use crate::velesql::Parser;
#[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");
assert!(parsed.select.where_clause.is_some());
}
#[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");
assert!(parsed.select.where_clause.is_some());
}
#[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");
assert!(parsed.select.where_clause.is_some());
}
#[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");
assert!(parsed.select.where_clause.is_some());
}