mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-10-09 21:42:05 +00:00
More tests and some small bugfixes
This commit is contained in:
parent
7624095738
commit
72024661a9
5 changed files with 202 additions and 27 deletions
|
@ -11,22 +11,18 @@ fn parse_simple_select() {
|
|||
let sql = String::from("SELECT id, fname, lname FROM customer WHERE id = 1");
|
||||
let ast = parse_sql(&sql);
|
||||
match ast {
|
||||
ASTNode::SQLSelect {
|
||||
projection, ..
|
||||
} => {
|
||||
ASTNode::SQLSelect { projection, .. } => {
|
||||
assert_eq!(3, projection.len());
|
||||
}
|
||||
_ => assert!(false),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn parse_sql(sql: &str) -> ASTNode {
|
||||
let dialect = AnsiSqlDialect {};
|
||||
let mut tokenizer = Tokenizer::new(&dialect,&sql, );
|
||||
let mut tokenizer = Tokenizer::new(&dialect, &sql);
|
||||
let tokens = tokenizer.tokenize().unwrap();
|
||||
let mut parser = Parser::new(tokens);
|
||||
let ast = parser.parse().unwrap();
|
||||
ast
|
||||
}
|
||||
|
||||
|
|
|
@ -529,21 +529,20 @@ fn parse_joins_on() {
|
|||
})),
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
joins_from("SELECT * FROM t1 JOIN t2 ON c1 = c2"),
|
||||
joins_from(verified("SELECT * FROM t1 JOIN t2 ON c1 = c2")),
|
||||
vec![join_with_constraint("t2", JoinOperator::Inner)]
|
||||
);
|
||||
assert_eq!(
|
||||
joins_from("SELECT * FROM t1 LEFT JOIN t2 ON c1 = c2"),
|
||||
joins_from(verified("SELECT * FROM t1 LEFT JOIN t2 ON c1 = c2")),
|
||||
vec![join_with_constraint("t2", JoinOperator::LeftOuter)]
|
||||
);
|
||||
assert_eq!(
|
||||
joins_from("SELECT * FROM t1 RIGHT JOIN t2 ON c1 = c2"),
|
||||
joins_from(verified("SELECT * FROM t1 RIGHT JOIN t2 ON c1 = c2")),
|
||||
vec![join_with_constraint("t2", JoinOperator::RightOuter)]
|
||||
);
|
||||
assert_eq!(
|
||||
joins_from("SELECT * FROM t1 FULL OUTER JOIN t2 ON c1 = c2"),
|
||||
joins_from(verified("SELECT * FROM t1 FULL JOIN t2 ON c1 = c2")),
|
||||
vec![join_with_constraint("t2", JoinOperator::FullOuter)]
|
||||
);
|
||||
}
|
||||
|
@ -561,25 +560,61 @@ fn parse_joins_using() {
|
|||
}
|
||||
|
||||
assert_eq!(
|
||||
joins_from("SELECT * FROM t1 JOIN t2 USING(c1)"),
|
||||
joins_from(verified("SELECT * FROM t1 JOIN t2 USING(c1)")),
|
||||
vec![join_with_constraint("t2", JoinOperator::Inner)]
|
||||
);
|
||||
assert_eq!(
|
||||
joins_from("SELECT * FROM t1 LEFT JOIN t2 USING(c1)"),
|
||||
joins_from(verified("SELECT * FROM t1 LEFT JOIN t2 USING(c1)")),
|
||||
vec![join_with_constraint("t2", JoinOperator::LeftOuter)]
|
||||
);
|
||||
assert_eq!(
|
||||
joins_from("SELECT * FROM t1 RIGHT JOIN t2 USING(c1)"),
|
||||
joins_from(verified("SELECT * FROM t1 RIGHT JOIN t2 USING(c1)")),
|
||||
vec![join_with_constraint("t2", JoinOperator::RightOuter)]
|
||||
);
|
||||
assert_eq!(
|
||||
joins_from("SELECT * FROM t1 FULL OUTER JOIN t2 USING(c1)"),
|
||||
joins_from(verified("SELECT * FROM t1 FULL JOIN t2 USING(c1)")),
|
||||
vec![join_with_constraint("t2", JoinOperator::FullOuter)]
|
||||
);
|
||||
}
|
||||
|
||||
fn joins_from(sql: &str) -> Vec<Join> {
|
||||
match parse_sql(sql) {
|
||||
#[test]
|
||||
fn parse_complex_join() {
|
||||
let sql = "SELECT c1, c2 FROM t1, t4 JOIN t2 ON t2.c = t1.c LEFT JOIN t3 USING(q, c) WHERE t4.c = t1.c";
|
||||
assert_eq!(sql, parse_sql(sql).to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_join_syntax_variants() {
|
||||
fn parses_to(from: &str, to: &str) {
|
||||
assert_eq!(to, &parse_sql(from).to_string())
|
||||
}
|
||||
|
||||
parses_to(
|
||||
"SELECT c1 FROM t1 INNER JOIN t2 USING(c1)",
|
||||
"SELECT c1 FROM t1 JOIN t2 USING(c1)",
|
||||
);
|
||||
parses_to(
|
||||
"SELECT c1 FROM t1 LEFT OUTER JOIN t2 USING(c1)",
|
||||
"SELECT c1 FROM t1 LEFT JOIN t2 USING(c1)",
|
||||
);
|
||||
parses_to(
|
||||
"SELECT c1 FROM t1 RIGHT OUTER JOIN t2 USING(c1)",
|
||||
"SELECT c1 FROM t1 RIGHT JOIN t2 USING(c1)",
|
||||
);
|
||||
parses_to(
|
||||
"SELECT c1 FROM t1 FULL OUTER JOIN t2 USING(c1)",
|
||||
"SELECT c1 FROM t1 FULL JOIN t2 USING(c1)",
|
||||
);
|
||||
}
|
||||
|
||||
fn verified(query: &str) -> ASTNode {
|
||||
let ast = parse_sql(query);
|
||||
assert_eq!(query, &ast.to_string());
|
||||
ast
|
||||
}
|
||||
|
||||
fn joins_from(ast: ASTNode) -> Vec<Join> {
|
||||
match ast {
|
||||
ASTNode::SQLSelect { joins, .. } => joins,
|
||||
_ => panic!("Expected SELECT"),
|
||||
}
|
||||
|
|
|
@ -716,6 +716,150 @@ fn parse_function_now() {
|
|||
assert_eq!(sql, ast.to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_implicit_join() {
|
||||
let sql = "SELECT * FROM t1, t2";
|
||||
|
||||
match verified(sql) {
|
||||
ASTNode::SQLSelect { joins, .. } => {
|
||||
assert_eq!(joins.len(), 1);
|
||||
assert_eq!(
|
||||
joins[0],
|
||||
Join {
|
||||
relation: ASTNode::SQLIdentifier("t2".to_string()),
|
||||
join_operator: JoinOperator::Implicit
|
||||
}
|
||||
)
|
||||
}
|
||||
_ => assert!(false),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_cross_join() {
|
||||
let sql = "SELECT * FROM t1 CROSS JOIN t2";
|
||||
|
||||
match verified(sql) {
|
||||
ASTNode::SQLSelect { joins, .. } => {
|
||||
assert_eq!(joins.len(), 1);
|
||||
assert_eq!(
|
||||
joins[0],
|
||||
Join {
|
||||
relation: ASTNode::SQLIdentifier("t2".to_string()),
|
||||
join_operator: JoinOperator::Cross
|
||||
}
|
||||
)
|
||||
}
|
||||
_ => assert!(false),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_joins_on() {
|
||||
fn join_with_constraint(
|
||||
relation: impl Into<String>,
|
||||
f: impl Fn(JoinConstraint) -> JoinOperator,
|
||||
) -> Join {
|
||||
Join {
|
||||
relation: ASTNode::SQLIdentifier(relation.into()),
|
||||
join_operator: f(JoinConstraint::On(ASTNode::SQLBinaryExpr {
|
||||
left: Box::new(ASTNode::SQLIdentifier("c1".into())),
|
||||
op: SQLOperator::Eq,
|
||||
right: Box::new(ASTNode::SQLIdentifier("c2".into())),
|
||||
})),
|
||||
}
|
||||
}
|
||||
assert_eq!(
|
||||
joins_from(verified("SELECT * FROM t1 JOIN t2 ON c1 = c2")),
|
||||
vec![join_with_constraint("t2", JoinOperator::Inner)]
|
||||
);
|
||||
assert_eq!(
|
||||
joins_from(verified("SELECT * FROM t1 LEFT JOIN t2 ON c1 = c2")),
|
||||
vec![join_with_constraint("t2", JoinOperator::LeftOuter)]
|
||||
);
|
||||
assert_eq!(
|
||||
joins_from(verified("SELECT * FROM t1 RIGHT JOIN t2 ON c1 = c2")),
|
||||
vec![join_with_constraint("t2", JoinOperator::RightOuter)]
|
||||
);
|
||||
assert_eq!(
|
||||
joins_from(verified("SELECT * FROM t1 FULL JOIN t2 ON c1 = c2")),
|
||||
vec![join_with_constraint("t2", JoinOperator::FullOuter)]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_joins_using() {
|
||||
fn join_with_constraint(
|
||||
relation: impl Into<String>,
|
||||
f: impl Fn(JoinConstraint) -> JoinOperator,
|
||||
) -> Join {
|
||||
Join {
|
||||
relation: ASTNode::SQLIdentifier(relation.into()),
|
||||
join_operator: f(JoinConstraint::Using(vec!["c1".into()])),
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
joins_from(verified("SELECT * FROM t1 JOIN t2 USING(c1)")),
|
||||
vec![join_with_constraint("t2", JoinOperator::Inner)]
|
||||
);
|
||||
assert_eq!(
|
||||
joins_from(verified("SELECT * FROM t1 LEFT JOIN t2 USING(c1)")),
|
||||
vec![join_with_constraint("t2", JoinOperator::LeftOuter)]
|
||||
);
|
||||
assert_eq!(
|
||||
joins_from(verified("SELECT * FROM t1 RIGHT JOIN t2 USING(c1)")),
|
||||
vec![join_with_constraint("t2", JoinOperator::RightOuter)]
|
||||
);
|
||||
assert_eq!(
|
||||
joins_from(verified("SELECT * FROM t1 FULL JOIN t2 USING(c1)")),
|
||||
vec![join_with_constraint("t2", JoinOperator::FullOuter)]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_join_syntax_variants() {
|
||||
fn parses_to(from: &str, to: &str) {
|
||||
assert_eq!(to, &parse_sql(from).to_string())
|
||||
}
|
||||
|
||||
parses_to(
|
||||
"SELECT c1 FROM t1 INNER JOIN t2 USING(c1)",
|
||||
"SELECT c1 FROM t1 JOIN t2 USING(c1)",
|
||||
);
|
||||
parses_to(
|
||||
"SELECT c1 FROM t1 LEFT OUTER JOIN t2 USING(c1)",
|
||||
"SELECT c1 FROM t1 LEFT JOIN t2 USING(c1)",
|
||||
);
|
||||
parses_to(
|
||||
"SELECT c1 FROM t1 RIGHT OUTER JOIN t2 USING(c1)",
|
||||
"SELECT c1 FROM t1 RIGHT JOIN t2 USING(c1)",
|
||||
);
|
||||
parses_to(
|
||||
"SELECT c1 FROM t1 FULL OUTER JOIN t2 USING(c1)",
|
||||
"SELECT c1 FROM t1 FULL JOIN t2 USING(c1)",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_complex_join() {
|
||||
let sql = "SELECT c1, c2 FROM t1, t4 JOIN t2 ON t2.c = t1.c LEFT JOIN t3 USING(q, c) WHERE t4.c = t1.c";
|
||||
assert_eq!(sql, parse_sql(sql).to_string());
|
||||
}
|
||||
|
||||
fn verified(query: &str) -> ASTNode {
|
||||
let ast = parse_sql(query);
|
||||
assert_eq!(query, &ast.to_string());
|
||||
ast
|
||||
}
|
||||
|
||||
fn joins_from(ast: ASTNode) -> Vec<Join> {
|
||||
match ast {
|
||||
ASTNode::SQLSelect { joins, .. } => joins,
|
||||
_ => panic!("Expected SELECT"),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_sql(sql: &str) -> ASTNode {
|
||||
debug!("sql: {}", sql);
|
||||
let mut parser = parser(sql);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue