use crate::velesql::{CompareOp, Condition, Parser, Value};
#[test]
fn parse_join_condition_handles_quoted_identifiers_with_dots() {
let query = r#"SELECT * FROM users AS u JOIN orders AS o ON `tenant.users`.id = "order.items"."user""id""#;
let parsed = Parser::parse(query).expect("query with quoted JOIN identifiers should parse");
let join = parsed
.select
.joins
.first()
.expect("expected one JOIN clause");
let condition = join
.condition
.as_ref()
.expect("expected JOIN condition in ON clause");
assert_eq!(condition.left.table.as_deref(), Some("tenant.users"));
assert_eq!(condition.left.column, "id");
assert_eq!(condition.right.table.as_deref(), Some("order.items"));
assert_eq!(condition.right.column, "user\"id");
}
#[test]
fn parse_rejects_excessive_condition_nesting_depth() {
let depth = 257;
let mut query = String::from("SELECT * FROM t WHERE ");
for _ in 0..depth {
query.push_str("NOT (");
}
query.push_str("x = 1");
for _ in 0..depth {
query.push(')');
}
let err = Parser::parse(&query).expect_err("deeply nested condition should be rejected");
assert!(
err.to_string().contains("Query nesting too deep"),
"unexpected parser error: {err}"
);
}
#[test]
fn parse_rejects_deeply_nested_where_parens_without_overflow() {
let depth = 5000;
let query = format!(
"SELECT * FROM t WHERE {}x = 1{}",
"(".repeat(depth),
")".repeat(depth)
);
let err = Parser::parse(&query).expect_err("deeply nested WHERE parens must be rejected");
assert!(
err.to_string().contains("Query nesting too deep"),
"unexpected parser error: {err}"
);
}
#[test]
fn parse_rejects_deeply_nested_order_by_arithmetic_without_overflow() {
let depth = 5000;
let query = format!(
"SELECT * FROM t ORDER BY {}1{}",
"(".repeat(depth),
")".repeat(depth)
);
let err =
Parser::parse(&query).expect_err("deeply nested ORDER BY arithmetic must be rejected");
assert!(
err.to_string().contains("Query nesting too deep"),
"unexpected parser error: {err}"
);
}
#[test]
fn parse_rejects_deeply_nested_subqueries_without_overflow() {
let depth = 200;
let mut query = String::from("SELECT * FROM t WHERE x = ");
for _ in 0..depth {
query.push_str("(SELECT id FROM t WHERE y = ");
}
query.push('1');
query.push_str(&")".repeat(depth));
let err = Parser::parse(&query).expect_err("deeply nested subqueries must be rejected");
assert!(
err.to_string().contains("Query nesting too deep"),
"unexpected parser error: {err}"
);
}
#[test]
fn parse_does_not_count_parens_inside_string_literal() {
let payload = "(".repeat(5000);
let query = format!("SELECT * FROM t WHERE name = '{payload}'");
let parsed = Parser::parse(&query)
.expect("parens inside a string literal must not trip the depth guard");
let where_clause = parsed.select.where_clause.expect("WHERE clause present");
let Condition::Comparison(cmp) = where_clause else {
panic!("expected a Comparison, got {where_clause:?}");
};
assert_eq!(cmp.column, "name");
assert_eq!(cmp.operator, CompareOp::Eq);
assert!(
matches!(&cmp.value, Value::String(s) if s.len() == 5000 && s.bytes().all(|b| b == b'(')),
"the 5000 '(' string literal must be preserved intact, got {:?}",
cmp.value
);
}
#[test]
fn parse_accepts_moderately_nested_query() {
let query = "SELECT * FROM t WHERE ((a = 1 AND b = 2) OR (c = 3 AND (d = 4 OR e = 5)))";
let parsed = Parser::parse(query).expect("moderately nested query should parse");
let where_clause = parsed
.select
.where_clause
.expect("moderately nested query should parse");
let Condition::Group(inner) = where_clause else {
panic!("expected outer Group, got {where_clause:?}");
};
assert!(
matches!(*inner, Condition::Or(ref left, ref right)
if matches!(**left, Condition::Group(ref l) if matches!(**l, Condition::And(..)))
&& matches!(**right, Condition::Group(ref r) if matches!(**r, Condition::And(..)))),
"expected Group(Or(Group(And), Group(And))), got {inner:?}"
);
}
#[test]
fn parse_rejects_bracket_free_not_chain_without_overflow() {
let query = format!("SELECT * FROM t WHERE {}a = 1", "NOT ".repeat(4000));
let err = Parser::parse(&query).expect_err("bracket-free NOT chain must be rejected");
assert!(
err.to_string().contains("Query nesting too deep"),
"unexpected parser error: {err}"
);
}
#[test]
fn parse_rejects_deep_parens_after_comment_with_apostrophe() {
let query = format!(
"SELECT * FROM t -- it's deep\nWHERE {}a = 1{}",
"(".repeat(5000),
")".repeat(5000)
);
let err =
Parser::parse(&query).expect_err("deep parens after a poisoned comment must be rejected");
assert!(
err.to_string().contains("Query nesting too deep"),
"unexpected parser error: {err}"
);
}
#[test]
fn parse_does_not_count_brackets_inside_line_comment() {
let comment = "(".repeat(5000);
let query = format!("SELECT * FROM t -- {comment} it's fine\nWHERE a = 1");
let parsed =
Parser::parse(&query).expect("brackets inside a -- comment must not trip the depth guard");
let where_clause = parsed
.select
.where_clause
.expect("WHERE clause after the comment must be parsed");
let Condition::Comparison(cmp) = where_clause else {
panic!("expected a Comparison condition, got {where_clause:?}");
};
assert_eq!(cmp.column, "a");
assert_eq!(cmp.operator, CompareOp::Eq);
assert_eq!(cmp.value, Value::Integer(1));
}
#[test]
fn parse_accepts_small_not_nesting() {
let query = "SELECT * FROM t WHERE NOT NOT a = 1 AND NOT b = 2";
let parsed = Parser::parse(query).expect("small NOT nesting should parse");
match parsed.select.where_clause {
Some(Condition::And(left, right)) => {
match *left {
Condition::Not(inner1) => match *inner1 {
Condition::Not(inner2) => assert!(
matches!(*inner2, Condition::Comparison(_)),
"inner of double NOT should be `a = 1` comparison, got {inner2:?}"
),
other => panic!("expected double NOT on left, got Not({other:?})"),
},
other => panic!("expected double NOT on left, got {other:?}"),
}
match *right {
Condition::Not(inner) => assert!(
matches!(*inner, Condition::Comparison(_)),
"inner of single NOT should be `b = 2` comparison, got {inner:?}"
),
other => panic!("expected single NOT on right, got {other:?}"),
}
}
other => panic!("expected top-level And, got {other:?}"),
}
}