@@ -104,36 +104,31 @@ fn parse_select_count_wildcard() {
104
104
105
105
#[ test]
106
106
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) ;
112
109
//TODO: add assertions
113
110
}
114
111
115
112
#[ test]
116
113
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) ;
122
117
//TODO: add assertions
123
118
}
124
119
125
120
#[ test]
126
121
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) ;
129
124
//TODO: add assertions
130
125
}
131
126
132
127
#[ test]
133
128
fn parse_compound_expr_1 ( ) {
134
129
use self :: ASTNode :: * ;
135
130
use self :: SQLOperator :: * ;
136
- let sql = String :: from ( "a + b * c" ) ;
131
+ let sql = "a + b * c" ;
137
132
assert_eq ! (
138
133
SQLBinaryExpr {
139
134
left: Box :: new( SQLIdentifier ( "a" . to_string( ) ) ) ,
@@ -144,15 +139,15 @@ fn parse_compound_expr_1() {
144
139
right: Box :: new( SQLIdentifier ( "c" . to_string( ) ) )
145
140
} )
146
141
} ,
147
- verified_expr( & sql)
142
+ verified_expr( sql)
148
143
) ;
149
144
}
150
145
151
146
#[ test]
152
147
fn parse_compound_expr_2 ( ) {
153
148
use self :: ASTNode :: * ;
154
149
use self :: SQLOperator :: * ;
155
- let sql = String :: from ( "a * b + c" ) ;
150
+ let sql = "a * b + c" ;
156
151
assert_eq ! (
157
152
SQLBinaryExpr {
158
153
left: Box :: new( SQLBinaryExpr {
@@ -163,27 +158,27 @@ fn parse_compound_expr_2() {
163
158
op: Plus ,
164
159
right: Box :: new( SQLIdentifier ( "c" . to_string( ) ) )
165
160
} ,
166
- verified_expr( & sql)
161
+ verified_expr( sql)
167
162
) ;
168
163
}
169
164
170
165
#[ test]
171
166
fn parse_is_null ( ) {
172
167
use self :: ASTNode :: * ;
173
- let sql = String :: from ( "a IS NULL" ) ;
168
+ let sql = "a IS NULL" ;
174
169
assert_eq ! (
175
170
SQLIsNull ( Box :: new( SQLIdentifier ( "a" . to_string( ) ) ) ) ,
176
- verified_expr( & sql)
171
+ verified_expr( sql)
177
172
) ;
178
173
}
179
174
180
175
#[ test]
181
176
fn parse_is_not_null ( ) {
182
177
use self :: ASTNode :: * ;
183
- let sql = String :: from ( "a IS NOT NULL" ) ;
178
+ let sql = "a IS NOT NULL" ;
184
179
assert_eq ! (
185
180
SQLIsNotNull ( Box :: new( SQLIdentifier ( "a" . to_string( ) ) ) ) ,
186
- verified_expr( & sql)
181
+ verified_expr( sql)
187
182
) ;
188
183
}
189
184
@@ -313,20 +308,15 @@ fn parse_limit_accepts_all() {
313
308
314
309
#[ test]
315
310
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
+ ) ;
330
320
one_statement_parses_to (
331
321
"SELECT CAST(id AS BIGINT) FROM customer" ,
332
322
"SELECT CAST(id AS bigint) FROM customer" ,
@@ -374,66 +364,55 @@ fn parse_create_table() {
374
364
375
365
#[ test]
376
366
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
+ ) ;
390
376
}
391
377
392
378
#[ test]
393
379
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) ;
396
382
//TODO: assertions
397
383
}
398
384
399
385
#[ test]
400
386
fn parse_literal_string ( ) {
401
387
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
+ ) ;
411
394
}
412
395
413
396
#[ test]
414
397
fn parse_simple_math_expr_plus ( ) {
415
398
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) ;
417
400
}
418
401
419
402
#[ test]
420
403
fn parse_simple_math_expr_minus ( ) {
421
404
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) ;
423
406
}
424
407
425
408
#[ test]
426
409
fn parse_select_version ( ) {
427
410
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
+ ) ;
437
416
}
438
417
439
418
#[ test]
@@ -465,38 +444,33 @@ fn parse_case_expression() {
465
444
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" ;
466
445
use self :: ASTNode :: { SQLBinaryExpr , SQLCase , SQLIdentifier , SQLIsNull , SQLValue } ;
467
446
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 ) ) )
494
456
} ,
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
+ ) ;
500
474
}
501
475
502
476
#[ test]
@@ -592,7 +566,7 @@ fn parse_joins_on() {
592
566
}
593
567
// Test parsing of aliases
594
568
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 ,
596
570
vec![ join_with_constraint(
597
571
"t2" ,
598
572
Some ( "foo" . to_string( ) ) ,
@@ -605,19 +579,19 @@ fn parse_joins_on() {
605
579
) ;
606
580
// Test parsing of different join operators
607
581
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 ,
609
583
vec![ join_with_constraint( "t2" , None , JoinOperator :: Inner ) ]
610
584
) ;
611
585
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 ,
613
587
vec![ join_with_constraint( "t2" , None , JoinOperator :: LeftOuter ) ]
614
588
) ;
615
589
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 ,
617
591
vec![ join_with_constraint( "t2" , None , JoinOperator :: RightOuter ) ]
618
592
) ;
619
593
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 ,
621
595
vec![ join_with_constraint( "t2" , None , JoinOperator :: FullOuter ) ]
622
596
) ;
623
597
}
@@ -639,7 +613,7 @@ fn parse_joins_using() {
639
613
}
640
614
// Test parsing of aliases
641
615
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 ,
643
617
vec![ join_with_constraint(
644
618
"t2" ,
645
619
Some ( "foo" . to_string( ) ) ,
@@ -652,27 +626,27 @@ fn parse_joins_using() {
652
626
) ;
653
627
// Test parsing of different join operators
654
628
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 ,
656
630
vec![ join_with_constraint( "t2" , None , JoinOperator :: Inner ) ]
657
631
) ;
658
632
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 ,
660
634
vec![ join_with_constraint( "t2" , None , JoinOperator :: LeftOuter ) ]
661
635
) ;
662
636
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 ,
664
638
vec![ join_with_constraint( "t2" , None , JoinOperator :: RightOuter ) ]
665
639
) ;
666
640
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 ,
668
642
vec![ join_with_constraint( "t2" , None , JoinOperator :: FullOuter ) ]
669
643
) ;
670
644
}
671
645
672
646
#[ test]
673
647
fn parse_complex_join ( ) {
674
648
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) ;
676
650
}
677
651
678
652
#[ test]
@@ -695,6 +669,26 @@ fn parse_join_syntax_variants() {
695
669
) ;
696
670
}
697
671
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
+
698
692
fn verified_stmt ( query : & str ) -> SQLStatement {
699
693
one_statement_parses_to ( query, query)
700
694
}
@@ -705,13 +699,6 @@ fn verified_expr(query: &str) -> ASTNode {
705
699
ast
706
700
}
707
701
708
- fn joins_from ( ast : SQLStatement ) -> Vec < Join > {
709
- match ast {
710
- SQLStatement :: SQLSelect ( SQLSelect { joins, .. } ) => joins,
711
- _ => panic ! ( "Expected SELECT" ) ,
712
- }
713
- }
714
-
715
702
/// Ensures that `sql` parses as a statement, optionally checking that
716
703
/// converting AST back to string equals to `canonical` (unless an empty string
717
704
/// is provided).
0 commit comments