Skip to content

Commit 5a0e0ec

Browse files
committed
Simplify some tests by introducing verified_select_stmt and expr_from_projection
(The primary motivation was that it makes the tests more resilient to the upcoming changes to the SQLSelectStatement to support `AS` aliases and `UNION`.) Also start using `&'static str` literals consistently instead of String::from for the `let sql` test strings.
1 parent 2dec65f commit 5a0e0ec

File tree

1 file changed

+105
-118
lines changed

1 file changed

+105
-118
lines changed

tests/sqlparser_generic.rs

Lines changed: 105 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -104,36 +104,31 @@ fn parse_select_count_wildcard() {
104104

105105
#[test]
106106
fn parse_not() {
107-
let sql = String::from(
108-
"SELECT id FROM customer \
109-
WHERE NOT salary = ''",
110-
);
111-
let _ast = verified_stmt(&sql);
107+
let sql = "SELECT id FROM customer WHERE NOT salary = ''";
108+
let _ast = verified_only_select(sql);
112109
//TODO: add assertions
113110
}
114111

115112
#[test]
116113
fn parse_select_string_predicate() {
117-
let sql = String::from(
118-
"SELECT id, fname, lname FROM customer \
119-
WHERE salary != 'Not Provided' AND salary != ''",
120-
);
121-
let _ast = verified_stmt(&sql);
114+
let sql = "SELECT id, fname, lname FROM customer \
115+
WHERE salary != 'Not Provided' AND salary != ''";
116+
let _ast = verified_only_select(sql);
122117
//TODO: add assertions
123118
}
124119

125120
#[test]
126121
fn parse_projection_nested_type() {
127-
let sql = String::from("SELECT customer.address.state FROM foo");
128-
let _ast = verified_stmt(&sql);
122+
let sql = "SELECT customer.address.state FROM foo";
123+
let _ast = verified_only_select(sql);
129124
//TODO: add assertions
130125
}
131126

132127
#[test]
133128
fn parse_compound_expr_1() {
134129
use self::ASTNode::*;
135130
use self::SQLOperator::*;
136-
let sql = String::from("a + b * c");
131+
let sql = "a + b * c";
137132
assert_eq!(
138133
SQLBinaryExpr {
139134
left: Box::new(SQLIdentifier("a".to_string())),
@@ -144,15 +139,15 @@ fn parse_compound_expr_1() {
144139
right: Box::new(SQLIdentifier("c".to_string()))
145140
})
146141
},
147-
verified_expr(&sql)
142+
verified_expr(sql)
148143
);
149144
}
150145

151146
#[test]
152147
fn parse_compound_expr_2() {
153148
use self::ASTNode::*;
154149
use self::SQLOperator::*;
155-
let sql = String::from("a * b + c");
150+
let sql = "a * b + c";
156151
assert_eq!(
157152
SQLBinaryExpr {
158153
left: Box::new(SQLBinaryExpr {
@@ -163,27 +158,27 @@ fn parse_compound_expr_2() {
163158
op: Plus,
164159
right: Box::new(SQLIdentifier("c".to_string()))
165160
},
166-
verified_expr(&sql)
161+
verified_expr(sql)
167162
);
168163
}
169164

170165
#[test]
171166
fn parse_is_null() {
172167
use self::ASTNode::*;
173-
let sql = String::from("a IS NULL");
168+
let sql = "a IS NULL";
174169
assert_eq!(
175170
SQLIsNull(Box::new(SQLIdentifier("a".to_string()))),
176-
verified_expr(&sql)
171+
verified_expr(sql)
177172
);
178173
}
179174

180175
#[test]
181176
fn parse_is_not_null() {
182177
use self::ASTNode::*;
183-
let sql = String::from("a IS NOT NULL");
178+
let sql = "a IS NOT NULL";
184179
assert_eq!(
185180
SQLIsNotNull(Box::new(SQLIdentifier("a".to_string()))),
186-
verified_expr(&sql)
181+
verified_expr(sql)
187182
);
188183
}
189184

@@ -313,20 +308,15 @@ fn parse_limit_accepts_all() {
313308

314309
#[test]
315310
fn parse_cast() {
316-
let sql = String::from("SELECT CAST(id AS bigint) FROM customer");
317-
match verified_stmt(&sql) {
318-
SQLStatement::SQLSelect(SQLSelect { projection, .. }) => {
319-
assert_eq!(1, projection.len());
320-
assert_eq!(
321-
ASTNode::SQLCast {
322-
expr: Box::new(ASTNode::SQLIdentifier("id".to_string())),
323-
data_type: SQLType::BigInt
324-
},
325-
projection[0]
326-
);
327-
}
328-
_ => assert!(false),
329-
}
311+
let sql = "SELECT CAST(id AS bigint) FROM customer";
312+
let select = verified_only_select(sql);
313+
assert_eq!(
314+
&ASTNode::SQLCast {
315+
expr: Box::new(ASTNode::SQLIdentifier("id".to_string())),
316+
data_type: SQLType::BigInt
317+
},
318+
expr_from_projection(only(&select.projection))
319+
);
330320
one_statement_parses_to(
331321
"SELECT CAST(id AS BIGINT) FROM customer",
332322
"SELECT CAST(id AS bigint) FROM customer",
@@ -374,66 +364,55 @@ fn parse_create_table() {
374364

375365
#[test]
376366
fn parse_scalar_function_in_projection() {
377-
let sql = String::from("SELECT sqrt(id) FROM foo");
378-
match verified_stmt(&sql) {
379-
SQLStatement::SQLSelect(SQLSelect { projection, .. }) => {
380-
assert_eq!(
381-
vec![ASTNode::SQLFunction {
382-
id: String::from("sqrt"),
383-
args: vec![ASTNode::SQLIdentifier(String::from("id"))],
384-
}],
385-
projection
386-
);
387-
}
388-
_ => assert!(false),
389-
}
367+
let sql = "SELECT sqrt(id) FROM foo";
368+
let select = verified_only_select(sql);
369+
assert_eq!(
370+
&ASTNode::SQLFunction {
371+
id: String::from("sqrt"),
372+
args: vec![ASTNode::SQLIdentifier(String::from("id"))],
373+
},
374+
expr_from_projection(only(&select.projection))
375+
);
390376
}
391377

392378
#[test]
393379
fn parse_aggregate_with_group_by() {
394-
let sql = String::from("SELECT a, COUNT(1), MIN(b), MAX(b) FROM foo GROUP BY a");
395-
let _ast = verified_stmt(&sql);
380+
let sql = "SELECT a, COUNT(1), MIN(b), MAX(b) FROM foo GROUP BY a";
381+
let _ast = verified_only_select(sql);
396382
//TODO: assertions
397383
}
398384

399385
#[test]
400386
fn parse_literal_string() {
401387
let sql = "SELECT 'one'";
402-
match verified_stmt(&sql) {
403-
SQLStatement::SQLSelect(SQLSelect { ref projection, .. }) => {
404-
assert_eq!(
405-
projection[0],
406-
ASTNode::SQLValue(Value::SingleQuotedString("one".to_string()))
407-
);
408-
}
409-
_ => panic!(),
410-
}
388+
let select = verified_only_select(sql);
389+
assert_eq!(1, select.projection.len());
390+
assert_eq!(
391+
&ASTNode::SQLValue(Value::SingleQuotedString("one".to_string())),
392+
expr_from_projection(&select.projection[0])
393+
);
411394
}
412395

413396
#[test]
414397
fn parse_simple_math_expr_plus() {
415398
let sql = "SELECT a + b, 2 + a, 2.5 + a, a_f + b_f, 2 + a_f, 2.5 + a_f FROM c";
416-
verified_stmt(&sql);
399+
verified_only_select(sql);
417400
}
418401

419402
#[test]
420403
fn parse_simple_math_expr_minus() {
421404
let sql = "SELECT a - b, 2 - a, 2.5 - a, a_f - b_f, 2 - a_f, 2.5 - a_f FROM c";
422-
verified_stmt(&sql);
405+
verified_only_select(sql);
423406
}
424407

425408
#[test]
426409
fn parse_select_version() {
427410
let sql = "SELECT @@version";
428-
match verified_stmt(&sql) {
429-
SQLStatement::SQLSelect(SQLSelect { ref projection, .. }) => {
430-
assert_eq!(
431-
projection[0],
432-
ASTNode::SQLIdentifier("@@version".to_string())
433-
);
434-
}
435-
_ => panic!(),
436-
}
411+
let select = verified_only_select(sql);
412+
assert_eq!(
413+
&ASTNode::SQLIdentifier("@@version".to_string()),
414+
expr_from_projection(only(&select.projection)),
415+
);
437416
}
438417

439418
#[test]
@@ -465,38 +444,33 @@ fn parse_case_expression() {
465444
let sql = "SELECT CASE WHEN bar IS NULL THEN 'null' WHEN bar = 0 THEN '=0' WHEN bar >= 0 THEN '>=0' ELSE '<0' END FROM foo";
466445
use self::ASTNode::{SQLBinaryExpr, SQLCase, SQLIdentifier, SQLIsNull, SQLValue};
467446
use self::SQLOperator::*;
468-
match verified_stmt(&sql) {
469-
SQLStatement::SQLSelect(SQLSelect { projection, .. }) => {
470-
assert_eq!(1, projection.len());
471-
assert_eq!(
472-
SQLCase {
473-
conditions: vec![
474-
SQLIsNull(Box::new(SQLIdentifier("bar".to_string()))),
475-
SQLBinaryExpr {
476-
left: Box::new(SQLIdentifier("bar".to_string())),
477-
op: Eq,
478-
right: Box::new(SQLValue(Value::Long(0)))
479-
},
480-
SQLBinaryExpr {
481-
left: Box::new(SQLIdentifier("bar".to_string())),
482-
op: GtEq,
483-
right: Box::new(SQLValue(Value::Long(0)))
484-
}
485-
],
486-
results: vec![
487-
SQLValue(Value::SingleQuotedString("null".to_string())),
488-
SQLValue(Value::SingleQuotedString("=0".to_string())),
489-
SQLValue(Value::SingleQuotedString(">=0".to_string()))
490-
],
491-
else_result: Some(Box::new(SQLValue(Value::SingleQuotedString(
492-
"<0".to_string()
493-
))))
447+
let select = verified_only_select(sql);
448+
assert_eq!(
449+
&SQLCase {
450+
conditions: vec![
451+
SQLIsNull(Box::new(SQLIdentifier("bar".to_string()))),
452+
SQLBinaryExpr {
453+
left: Box::new(SQLIdentifier("bar".to_string())),
454+
op: Eq,
455+
right: Box::new(SQLValue(Value::Long(0)))
494456
},
495-
projection[0]
496-
);
497-
}
498-
_ => assert!(false),
499-
}
457+
SQLBinaryExpr {
458+
left: Box::new(SQLIdentifier("bar".to_string())),
459+
op: GtEq,
460+
right: Box::new(SQLValue(Value::Long(0)))
461+
}
462+
],
463+
results: vec![
464+
SQLValue(Value::SingleQuotedString("null".to_string())),
465+
SQLValue(Value::SingleQuotedString("=0".to_string())),
466+
SQLValue(Value::SingleQuotedString(">=0".to_string()))
467+
],
468+
else_result: Some(Box::new(SQLValue(Value::SingleQuotedString(
469+
"<0".to_string()
470+
))))
471+
},
472+
expr_from_projection(only(&select.projection)),
473+
);
500474
}
501475

502476
#[test]
@@ -592,7 +566,7 @@ fn parse_joins_on() {
592566
}
593567
// Test parsing of aliases
594568
assert_eq!(
595-
joins_from(verified_stmt("SELECT * FROM t1 JOIN t2 AS foo ON c1 = c2")),
569+
verified_only_select("SELECT * FROM t1 JOIN t2 AS foo ON c1 = c2").joins,
596570
vec![join_with_constraint(
597571
"t2",
598572
Some("foo".to_string()),
@@ -605,19 +579,19 @@ fn parse_joins_on() {
605579
);
606580
// Test parsing of different join operators
607581
assert_eq!(
608-
joins_from(verified_stmt("SELECT * FROM t1 JOIN t2 ON c1 = c2")),
582+
verified_only_select("SELECT * FROM t1 JOIN t2 ON c1 = c2").joins,
609583
vec![join_with_constraint("t2", None, JoinOperator::Inner)]
610584
);
611585
assert_eq!(
612-
joins_from(verified_stmt("SELECT * FROM t1 LEFT JOIN t2 ON c1 = c2")),
586+
verified_only_select("SELECT * FROM t1 LEFT JOIN t2 ON c1 = c2").joins,
613587
vec![join_with_constraint("t2", None, JoinOperator::LeftOuter)]
614588
);
615589
assert_eq!(
616-
joins_from(verified_stmt("SELECT * FROM t1 RIGHT JOIN t2 ON c1 = c2")),
590+
verified_only_select("SELECT * FROM t1 RIGHT JOIN t2 ON c1 = c2").joins,
617591
vec![join_with_constraint("t2", None, JoinOperator::RightOuter)]
618592
);
619593
assert_eq!(
620-
joins_from(verified_stmt("SELECT * FROM t1 FULL JOIN t2 ON c1 = c2")),
594+
verified_only_select("SELECT * FROM t1 FULL JOIN t2 ON c1 = c2").joins,
621595
vec![join_with_constraint("t2", None, JoinOperator::FullOuter)]
622596
);
623597
}
@@ -639,7 +613,7 @@ fn parse_joins_using() {
639613
}
640614
// Test parsing of aliases
641615
assert_eq!(
642-
joins_from(verified_stmt("SELECT * FROM t1 JOIN t2 AS foo USING(c1)")),
616+
verified_only_select("SELECT * FROM t1 JOIN t2 AS foo USING(c1)").joins,
643617
vec![join_with_constraint(
644618
"t2",
645619
Some("foo".to_string()),
@@ -652,27 +626,27 @@ fn parse_joins_using() {
652626
);
653627
// Test parsing of different join operators
654628
assert_eq!(
655-
joins_from(verified_stmt("SELECT * FROM t1 JOIN t2 USING(c1)")),
629+
verified_only_select("SELECT * FROM t1 JOIN t2 USING(c1)").joins,
656630
vec![join_with_constraint("t2", None, JoinOperator::Inner)]
657631
);
658632
assert_eq!(
659-
joins_from(verified_stmt("SELECT * FROM t1 LEFT JOIN t2 USING(c1)")),
633+
verified_only_select("SELECT * FROM t1 LEFT JOIN t2 USING(c1)").joins,
660634
vec![join_with_constraint("t2", None, JoinOperator::LeftOuter)]
661635
);
662636
assert_eq!(
663-
joins_from(verified_stmt("SELECT * FROM t1 RIGHT JOIN t2 USING(c1)")),
637+
verified_only_select("SELECT * FROM t1 RIGHT JOIN t2 USING(c1)").joins,
664638
vec![join_with_constraint("t2", None, JoinOperator::RightOuter)]
665639
);
666640
assert_eq!(
667-
joins_from(verified_stmt("SELECT * FROM t1 FULL JOIN t2 USING(c1)")),
641+
verified_only_select("SELECT * FROM t1 FULL JOIN t2 USING(c1)").joins,
668642
vec![join_with_constraint("t2", None, JoinOperator::FullOuter)]
669643
);
670644
}
671645

672646
#[test]
673647
fn parse_complex_join() {
674648
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";
675-
verified_stmt(sql);
649+
verified_only_select(sql);
676650
}
677651

678652
#[test]
@@ -695,6 +669,26 @@ fn parse_join_syntax_variants() {
695669
);
696670
}
697671

672+
fn only<'a, T>(v: &'a Vec<T>) -> &'a T {
673+
assert_eq!(1, v.len());
674+
v.first().unwrap()
675+
}
676+
677+
fn verified_query(query: &str) -> SQLSelect {
678+
match verified_stmt(query) {
679+
SQLStatement::SQLSelect(select) => select,
680+
_ => panic!("Expected SELECT"),
681+
}
682+
}
683+
684+
fn expr_from_projection(item: &ASTNode) -> &ASTNode {
685+
item // Will be changed later to extract expression from `expr AS alias` struct
686+
}
687+
688+
fn verified_only_select(query: &str) -> SQLSelect {
689+
verified_query(query)
690+
}
691+
698692
fn verified_stmt(query: &str) -> SQLStatement {
699693
one_statement_parses_to(query, query)
700694
}
@@ -705,13 +699,6 @@ fn verified_expr(query: &str) -> ASTNode {
705699
ast
706700
}
707701

708-
fn joins_from(ast: SQLStatement) -> Vec<Join> {
709-
match ast {
710-
SQLStatement::SQLSelect(SQLSelect { joins, .. }) => joins,
711-
_ => panic!("Expected SELECT"),
712-
}
713-
}
714-
715702
/// Ensures that `sql` parses as a statement, optionally checking that
716703
/// converting AST back to string equals to `canonical` (unless an empty string
717704
/// is provided).

0 commit comments

Comments
 (0)