@@ -26,12 +26,18 @@ use common_ast::ast::Query;
26
26
use common_ast:: ast:: SelectStmt ;
27
27
use common_ast:: ast:: SelectTarget ;
28
28
use common_ast:: ast:: SetExpr ;
29
+ use common_ast:: ast:: TableAlias ;
29
30
use common_ast:: ast:: TableReference ;
31
+ use common_ast:: ast:: With ;
32
+ use common_ast:: ast:: CTE ;
33
+ use common_expression:: infer_schema_type;
30
34
use common_expression:: types:: DataType ;
31
35
use common_expression:: types:: NumberDataType ;
32
36
use common_expression:: TableDataType ;
33
37
use common_expression:: TableField ;
38
+ use common_expression:: TableSchemaRef ;
34
39
use common_expression:: TableSchemaRefExt ;
40
+ use rand:: distributions:: Alphanumeric ;
35
41
use rand:: Rng ;
36
42
37
43
use crate :: sql_gen:: Column ;
@@ -40,19 +46,20 @@ use crate::sql_gen::Table;
40
46
41
47
impl < ' a , R : Rng > SqlGenerator < ' a , R > {
42
48
pub ( crate ) fn gen_query ( & mut self ) -> Query {
43
- self . bound_columns . clear ( ) ;
49
+ self . cte_tables . clear ( ) ;
44
50
self . bound_tables . clear ( ) ;
51
+ self . bound_columns . clear ( ) ;
45
52
self . is_join = false ;
46
53
54
+ let with = self . gen_with ( ) ;
47
55
let body = self . gen_set_expr ( ) ;
48
56
let limit = self . gen_limit ( ) ;
49
57
let offset = self . gen_offset ( limit. len ( ) ) ;
50
58
let order_by = self . gen_order_by ( self . group_by . clone ( ) ) ;
51
59
52
60
Query {
53
61
span : None ,
54
- // TODO
55
- with : None ,
62
+ with,
56
63
body,
57
64
order_by,
58
65
limit,
@@ -61,7 +68,10 @@ impl<'a, R: Rng> SqlGenerator<'a, R> {
61
68
}
62
69
}
63
70
64
- pub ( crate ) fn gen_subquery ( & mut self ) -> Query {
71
+ // Scalar, IN / NOT IN, ANY / SOME / ALL Subquery must return only one column
72
+ // EXISTS / NOT EXISTS Subquery can return any columns
73
+ pub ( crate ) fn gen_subquery ( & mut self , one_column : bool ) -> ( Query , TableSchemaRef ) {
74
+ let current_cte_tables = mem:: take ( & mut self . cte_tables ) ;
65
75
let current_bound_tables = mem:: take ( & mut self . bound_tables ) ;
66
76
let current_bound_columns = mem:: take ( & mut self . bound_columns ) ;
67
77
let current_is_join = self . is_join ;
@@ -70,13 +80,101 @@ impl<'a, R: Rng> SqlGenerator<'a, R> {
70
80
self . bound_columns = vec ! [ ] ;
71
81
self . is_join = false ;
72
82
73
- let query = self . gen_query ( ) ;
83
+ // Only generate simple subquery
84
+ // TODO: complex subquery
85
+ let from = self . gen_from ( ) ;
86
+
87
+ let len = if one_column {
88
+ 1
89
+ } else {
90
+ self . rng . gen_range ( 1 ..=5 )
91
+ } ;
92
+
93
+ let name: String = ( 0 ..3 )
94
+ . map ( |_| self . rng . sample ( Alphanumeric ) as char )
95
+ . collect ( ) ;
96
+ let mut fields = Vec :: with_capacity ( len) ;
97
+ let mut select_list = Vec :: with_capacity ( len) ;
98
+ for i in 0 ..len {
99
+ let ty = self . gen_simple_data_type ( ) ;
100
+ let expr = self . gen_simple_expr ( & ty) ;
101
+ let col_name = format ! ( "c{}{}" , name, i) ;
102
+ let table_type = infer_schema_type ( & ty) . unwrap ( ) ;
103
+ let field = TableField :: new ( & col_name, table_type) ;
104
+ fields. push ( field) ;
105
+ let alias = Identifier :: from_name ( col_name) ;
106
+ let target = SelectTarget :: AliasedExpr {
107
+ expr : Box :: new ( expr) ,
108
+ alias : Some ( alias) ,
109
+ } ;
110
+ select_list. push ( target) ;
111
+ }
112
+ let schema = TableSchemaRefExt :: create ( fields) ;
74
113
114
+ let select = SelectStmt {
115
+ span : None ,
116
+ hints : None ,
117
+ distinct : false ,
118
+ select_list,
119
+ from,
120
+ selection : None ,
121
+ group_by : None ,
122
+ having : None ,
123
+ window_list : None ,
124
+ } ;
125
+ let body = SetExpr :: Select ( Box :: new ( select) ) ;
126
+
127
+ let query = Query {
128
+ span : None ,
129
+ with : None ,
130
+ body,
131
+ order_by : vec ! [ ] ,
132
+ limit : vec ! [ ] ,
133
+ offset : None ,
134
+ ignore_result : false ,
135
+ } ;
136
+
137
+ self . cte_tables = current_cte_tables;
75
138
self . bound_tables = current_bound_tables;
76
139
self . bound_columns = current_bound_columns;
77
140
self . is_join = current_is_join;
78
141
79
- query
142
+ ( query, schema)
143
+ }
144
+
145
+ fn gen_with ( & mut self ) -> Option < With > {
146
+ if self . rng . gen_bool ( 0.8 ) {
147
+ return None ;
148
+ }
149
+
150
+ let len = self . rng . gen_range ( 1 ..=3 ) ;
151
+ let mut ctes = Vec :: with_capacity ( len) ;
152
+ for _ in 0 ..len {
153
+ let cte = self . gen_cte ( ) ;
154
+ ctes. push ( cte) ;
155
+ }
156
+
157
+ Some ( With {
158
+ span : None ,
159
+ recursive : false ,
160
+ ctes,
161
+ } )
162
+ }
163
+
164
+ fn gen_cte ( & mut self ) -> CTE {
165
+ let ( subquery, schema) = self . gen_subquery ( false ) ;
166
+
167
+ let ( table, alias) = self . gen_subquery_table ( schema) ;
168
+ self . cte_tables . push ( table) ;
169
+
170
+ let materialized = self . rng . gen_bool ( 0.5 ) ;
171
+
172
+ CTE {
173
+ span : None ,
174
+ alias,
175
+ materialized,
176
+ query : Box :: new ( subquery) ,
177
+ }
80
178
}
81
179
82
180
fn gen_set_expr ( & mut self ) -> SetExpr {
@@ -304,17 +402,21 @@ impl<'a, R: Rng> SqlGenerator<'a, R> {
304
402
// TODO: generate more table reference
305
403
// let table_ref_num = self.rng.gen_range(1..=3);
306
404
match self . rng . gen_range ( 0 ..=10 ) {
307
- 0 ..=7 => {
308
- let i = self . rng . gen_range ( 0 ..self . tables . len ( ) ) ;
309
- let table_ref = self . gen_table_ref ( self . tables [ i] . clone ( ) ) ;
405
+ 0 ..=6 => {
406
+ let ( table_ref, _) = self . gen_table_ref ( ) ;
310
407
table_refs. push ( table_ref) ;
311
408
}
312
409
// join
313
- 8 ..=9 => {
410
+ 7 ..=8 => {
314
411
self . is_join = true ;
315
412
let join = self . gen_join_table_ref ( ) ;
316
413
table_refs. push ( join) ;
317
414
}
415
+ // subquery
416
+ 9 => {
417
+ let subquery = self . gen_subquery_table_ref ( ) ;
418
+ table_refs. push ( subquery) ;
419
+ }
318
420
10 => {
319
421
let table_func = self . gen_table_func ( ) ;
320
422
table_refs. push ( table_func) ;
@@ -325,12 +427,21 @@ impl<'a, R: Rng> SqlGenerator<'a, R> {
325
427
table_refs
326
428
}
327
429
328
- fn gen_table_ref ( & mut self , table : Table ) -> TableReference {
430
+ fn gen_table_ref ( & mut self ) -> ( TableReference , TableSchemaRef ) {
431
+ let len = self . tables . len ( ) + self . cte_tables . len ( ) ;
432
+ let i = self . rng . gen_range ( 0 ..len) ;
433
+
434
+ let table = if i < self . tables . len ( ) {
435
+ self . tables [ i] . clone ( )
436
+ } else {
437
+ self . cte_tables [ len - i - 1 ] . clone ( )
438
+ } ;
439
+ let schema = table. schema . clone ( ) ;
329
440
let table_name = Identifier :: from_name ( table. name . clone ( ) ) ;
330
441
331
442
self . bound_table ( table) ;
332
443
333
- TableReference :: Table {
444
+ let table_ref = TableReference :: Table {
334
445
span : None ,
335
446
// TODO
336
447
catalog : None ,
@@ -345,7 +456,8 @@ impl<'a, R: Rng> SqlGenerator<'a, R> {
345
456
pivot : None ,
346
457
// TODO
347
458
unpivot : None ,
348
- }
459
+ } ;
460
+ ( table_ref, schema)
349
461
}
350
462
351
463
// Only test:
@@ -453,11 +565,10 @@ impl<'a, R: Rng> SqlGenerator<'a, R> {
453
565
_ => unreachable ! ( ) ,
454
566
}
455
567
}
568
+
456
569
fn gen_join_table_ref ( & mut self ) -> TableReference {
457
- let i = self . rng . gen_range ( 0 ..self . tables . len ( ) ) ;
458
- let j = if i == self . tables . len ( ) - 1 { 0 } else { i + 1 } ;
459
- let left_table = self . gen_table_ref ( self . tables [ i] . clone ( ) ) ;
460
- let right_table = self . gen_table_ref ( self . tables [ j] . clone ( ) ) ;
570
+ let ( left_table, left_schema) = self . gen_table_ref ( ) ;
571
+ let ( right_table, right_schema) = self . gen_table_ref ( ) ;
461
572
462
573
let op = match self . rng . gen_range ( 0 ..=8 ) {
463
574
0 => JoinOperator :: Inner ,
@@ -479,8 +590,8 @@ impl<'a, R: Rng> SqlGenerator<'a, R> {
479
590
JoinCondition :: On ( Box :: new ( expr) )
480
591
}
481
592
1 => {
482
- let left_fields = self . tables [ i ] . schema . fields ( ) ;
483
- let right_fields = self . tables [ j ] . schema . fields ( ) ;
593
+ let left_fields = left_schema . fields ( ) ;
594
+ let right_fields = right_schema . fields ( ) ;
484
595
485
596
let mut names = Vec :: new ( ) ;
486
597
for left_field in left_fields {
@@ -534,6 +645,19 @@ impl<'a, R: Rng> SqlGenerator<'a, R> {
534
645
TableReference :: Join { span : None , join }
535
646
}
536
647
648
+ fn gen_subquery_table_ref ( & mut self ) -> TableReference {
649
+ let ( subquery, schema) = self . gen_subquery ( false ) ;
650
+
651
+ let ( table, alias) = self . gen_subquery_table ( schema) ;
652
+ self . bound_table ( table) ;
653
+
654
+ TableReference :: Subquery {
655
+ span : None ,
656
+ subquery : Box :: new ( subquery) ,
657
+ alias : Some ( alias) ,
658
+ }
659
+ }
660
+
537
661
fn gen_selection ( & mut self ) -> Option < Expr > {
538
662
match self . rng . gen_range ( 0 ..=9 ) {
539
663
0 ..=5 => Some ( self . gen_expr ( & DataType :: Boolean ) ) ,
@@ -545,6 +669,25 @@ impl<'a, R: Rng> SqlGenerator<'a, R> {
545
669
}
546
670
}
547
671
672
+ fn gen_subquery_table ( & mut self , schema : TableSchemaRef ) -> ( Table , TableAlias ) {
673
+ let name: String = ( 0 ..4 )
674
+ . map ( |_| self . rng . sample ( Alphanumeric ) as char )
675
+ . collect ( ) ;
676
+ let table_name = format ! ( "t{}" , name) ;
677
+ let mut columns = Vec :: with_capacity ( schema. num_fields ( ) ) ;
678
+ for field in schema. fields ( ) {
679
+ let column = Identifier :: from_name ( field. name . clone ( ) ) ;
680
+ columns. push ( column) ;
681
+ }
682
+ let alias = TableAlias {
683
+ name : Identifier :: from_name ( table_name. clone ( ) ) ,
684
+ columns,
685
+ } ;
686
+ let table = Table :: new ( table_name, schema) ;
687
+
688
+ ( table, alias)
689
+ }
690
+
548
691
fn bound_table ( & mut self , table : Table ) {
549
692
for ( i, field) in table. schema . fields ( ) . iter ( ) . enumerate ( ) {
550
693
let column = Column {
0 commit comments