@@ -33,12 +33,14 @@ use itertools::Itertools;
33
33
use super :: prune_by_children;
34
34
use super :: ExprContext ;
35
35
use super :: Finder ;
36
+ use crate :: binder:: project_set:: SetReturningRewriter ;
36
37
use crate :: binder:: scalar:: ScalarBinder ;
37
38
use crate :: binder:: select:: SelectList ;
38
39
use crate :: binder:: Binder ;
39
40
use crate :: binder:: ColumnBinding ;
40
41
use crate :: binder:: ColumnBindingBuilder ;
41
42
use crate :: binder:: Visibility ;
43
+ use crate :: normalize_identifier;
42
44
use crate :: optimizer:: SExpr ;
43
45
use crate :: plans:: walk_expr_mut;
44
46
use crate :: plans:: Aggregate ;
@@ -347,6 +349,13 @@ impl Binder {
347
349
bind_context : & mut BindContext ,
348
350
select_list : & mut SelectList ,
349
351
) -> Result < ( ) > {
352
+ if !bind_context. srf_info . srfs . is_empty ( ) {
353
+ // Rewrite the Set-returning functions in Aggregate function as columns.
354
+ let mut srf_rewriter = SetReturningRewriter :: new ( bind_context, true ) ;
355
+ for item in select_list. items . iter_mut ( ) {
356
+ srf_rewriter. visit ( & mut item. scalar ) ?;
357
+ }
358
+ }
350
359
let mut rewriter = AggregateRewriter :: new ( bind_context, self . metadata . clone ( ) ) ;
351
360
for item in select_list. items . iter_mut ( ) {
352
361
rewriter. visit ( & mut item. scalar ) ?;
@@ -373,22 +382,16 @@ impl Binder {
373
382
374
383
// Extract available aliases from `SELECT` clause,
375
384
for item in select_list. items . iter ( ) {
376
- if let SelectTarget :: AliasedExpr { alias : Some ( _) , .. } = item. select_target {
377
- let column = if let ScalarExpr :: BoundColumnRef ( column_ref) = & item. scalar {
378
- let mut column = column_ref. column . clone ( ) ;
379
- column. column_name = item. alias . clone ( ) ;
380
- column
381
- } else {
382
- self . create_derived_column_binding (
383
- item. alias . clone ( ) ,
384
- item. scalar . data_type ( ) ?,
385
- Some ( item. scalar . clone ( ) ) ,
386
- )
387
- } ;
388
- available_aliases. push ( ( column, item. scalar . clone ( ) ) ) ;
385
+ if let SelectTarget :: AliasedExpr {
386
+ alias : Some ( alias) , ..
387
+ } = item. select_target
388
+ {
389
+ let column = normalize_identifier ( alias, & self . name_resolution_ctx ) ;
390
+ available_aliases. push ( ( column. name , item. scalar . clone ( ) ) ) ;
389
391
}
390
392
}
391
393
394
+ let original_context = bind_context. expr_context . clone ( ) ;
392
395
bind_context. set_expr_context ( ExprContext :: GroupClaue ) ;
393
396
match group_by {
394
397
GroupBy :: Normal ( exprs) => self . resolve_group_items (
@@ -398,7 +401,7 @@ impl Binder {
398
401
& available_aliases,
399
402
false ,
400
403
& mut vec ! [ ] ,
401
- ) ,
404
+ ) ? ,
402
405
GroupBy :: All => {
403
406
let groups = self . resolve_group_all ( select_list) ?;
404
407
self . resolve_group_items (
@@ -408,10 +411,10 @@ impl Binder {
408
411
& available_aliases,
409
412
false ,
410
413
& mut vec ! [ ] ,
411
- )
414
+ ) ? ;
412
415
}
413
416
GroupBy :: GroupingSets ( sets) => {
414
- self . resolve_grouping_sets ( bind_context, select_list, sets, & available_aliases)
417
+ self . resolve_grouping_sets ( bind_context, select_list, sets, & available_aliases) ? ;
415
418
}
416
419
// TODO: avoid too many clones.
417
420
GroupBy :: Rollup ( exprs) => {
@@ -420,16 +423,18 @@ impl Binder {
420
423
for i in ( 0 ..=exprs. len ( ) ) . rev ( ) {
421
424
sets. push ( exprs[ 0 ..i] . to_vec ( ) ) ;
422
425
}
423
- self . resolve_grouping_sets ( bind_context, select_list, & sets, & available_aliases)
426
+ self . resolve_grouping_sets ( bind_context, select_list, & sets, & available_aliases) ? ;
424
427
}
425
428
GroupBy :: Cube ( exprs) => {
426
429
// CUBE (a,b) => GROUPING SETS ((a,b),(a),(b),()) // All subsets
427
430
let sets = ( 0 ..=exprs. len ( ) )
428
431
. flat_map ( |count| exprs. clone ( ) . into_iter ( ) . combinations ( count) )
429
432
. collect :: < Vec < _ > > ( ) ;
430
- self . resolve_grouping_sets ( bind_context, select_list, & sets, & available_aliases)
433
+ self . resolve_grouping_sets ( bind_context, select_list, & sets, & available_aliases) ? ;
431
434
}
432
435
}
436
+ bind_context. set_expr_context ( original_context) ;
437
+ Ok ( ( ) )
433
438
}
434
439
435
440
pub fn bind_aggregate (
@@ -490,7 +495,7 @@ impl Binder {
490
495
bind_context : & mut BindContext ,
491
496
select_list : & SelectList < ' _ > ,
492
497
sets : & [ Vec < Expr > ] ,
493
- available_aliases : & [ ( ColumnBinding , ScalarExpr ) ] ,
498
+ available_aliases : & [ ( String , ScalarExpr ) ] ,
494
499
) -> Result < ( ) > {
495
500
let mut grouping_sets = Vec :: with_capacity ( sets. len ( ) ) ;
496
501
for set in sets {
@@ -587,7 +592,7 @@ impl Binder {
587
592
bind_context : & mut BindContext ,
588
593
select_list : & SelectList < ' _ > ,
589
594
group_by : & [ Expr ] ,
590
- available_aliases : & [ ( ColumnBinding , ScalarExpr ) ] ,
595
+ available_aliases : & [ ( String , ScalarExpr ) ] ,
591
596
collect_grouping_sets : bool ,
592
597
grouping_sets : & mut Vec < Vec < ScalarExpr > > ,
593
598
) -> Result < ( ) > {
@@ -640,9 +645,9 @@ impl Binder {
640
645
self . metadata . clone ( ) ,
641
646
& [ ] ,
642
647
) ;
643
- let ( scalar_expr, _) = scalar_binder
648
+ let ( mut scalar_expr, _) = scalar_binder
644
649
. bind ( expr)
645
- . or_else ( |e| Self :: resolve_alias_item ( bind_context, expr, available_aliases, e) ) ?;
650
+ . or_else ( |e| self . resolve_alias_item ( bind_context, expr, available_aliases, e) ) ?;
646
651
647
652
if collect_grouping_sets && !grouping_sets. last ( ) . unwrap ( ) . contains ( & scalar_expr) {
648
653
grouping_sets. last_mut ( ) . unwrap ( ) . push ( scalar_expr. clone ( ) ) ;
@@ -657,6 +662,11 @@ impl Binder {
657
662
continue ;
658
663
}
659
664
665
+ if !bind_context. srf_info . srfs . is_empty ( ) {
666
+ let mut srf_rewriter = SetReturningRewriter :: new ( bind_context, false ) ;
667
+ srf_rewriter. visit ( & mut scalar_expr) ?;
668
+ }
669
+
660
670
let group_item_name = format ! ( "{:#}" , expr) ;
661
671
let index = if let ScalarExpr :: BoundColumnRef ( BoundColumnRef {
662
672
column : ColumnBinding { index, .. } ,
@@ -766,17 +776,18 @@ impl Binder {
766
776
767
777
Ok ( ( scalar, alias) )
768
778
}
779
+
769
780
fn resolve_alias_item (
781
+ & mut self ,
770
782
bind_context : & mut BindContext ,
771
783
expr : & Expr ,
772
- available_aliases : & [ ( ColumnBinding , ScalarExpr ) ] ,
784
+ available_aliases : & [ ( String , ScalarExpr ) ] ,
773
785
original_error : ErrorCode ,
774
786
) -> Result < ( ScalarExpr , DataType ) > {
775
787
let mut result: Vec < usize > = vec ! [ ] ;
776
788
// If cannot resolve group item, then try to find an available alias
777
- for ( i, ( column_binding , _) ) in available_aliases. iter ( ) . enumerate ( ) {
789
+ for ( i, ( alias , _) ) in available_aliases. iter ( ) . enumerate ( ) {
778
790
// Alias of the select item
779
- let col_name = column_binding. column_name . as_str ( ) ;
780
791
if let Expr :: ColumnRef {
781
792
column :
782
793
ColumnRef {
@@ -787,7 +798,7 @@ impl Binder {
787
798
..
788
799
} = expr
789
800
{
790
- if col_name . eq_ignore_ascii_case ( column. name ( ) ) {
801
+ if alias . eq_ignore_ascii_case ( column. name ( ) ) {
791
802
result. push ( i) ;
792
803
}
793
804
}
@@ -801,31 +812,75 @@ impl Binder {
801
812
. set_span ( expr. span ( ) ) ,
802
813
)
803
814
} else {
804
- let ( column_binding, scalar) = available_aliases[ result[ 0 ] ] . clone ( ) ;
805
- // We will add the alias to BindContext, so we can reference it
806
- // in `HAVING` and `ORDER BY` clause.
807
- bind_context. add_column_binding ( column_binding. clone ( ) ) ;
815
+ let ( alias, mut scalar) = available_aliases[ result[ 0 ] ] . clone ( ) ;
808
816
809
- let index = column_binding. index ;
810
- bind_context. aggregate_info . group_items . push ( ScalarItem {
811
- scalar : scalar. clone ( ) ,
812
- index,
813
- } ) ;
814
- bind_context. aggregate_info . group_items_map . insert (
815
- scalar. clone ( ) ,
816
- bind_context. aggregate_info . group_items . len ( ) - 1 ,
817
- ) ;
817
+ if !bind_context. srf_info . srfs . is_empty ( ) {
818
+ let mut srf_rewriter = SetReturningRewriter :: new ( bind_context, false ) ;
819
+ srf_rewriter. visit ( & mut scalar) ?;
820
+ }
821
+
822
+ // check scalar first, avoid duplicate create column.
823
+ let mut scalar_column_index = None ;
824
+ let column_binding = if let Some ( column_index) =
825
+ bind_context. aggregate_info . group_items_map . get ( & scalar)
826
+ {
827
+ scalar_column_index = Some ( * column_index) ;
828
+
829
+ let group_item = & bind_context. aggregate_info . group_items [ * column_index] ;
830
+ ColumnBindingBuilder :: new (
831
+ alias. clone ( ) ,
832
+ group_item. index ,
833
+ Box :: new ( group_item. scalar . data_type ( ) ?) ,
834
+ Visibility :: Visible ,
835
+ )
836
+ . build ( )
837
+ } else if let ScalarExpr :: BoundColumnRef ( column_ref) = & scalar {
838
+ let mut column = column_ref. column . clone ( ) ;
839
+ column. column_name = alias. clone ( ) ;
840
+ column
841
+ } else {
842
+ self . create_derived_column_binding (
843
+ alias. clone ( ) ,
844
+ scalar. data_type ( ) ?,
845
+ Some ( scalar. clone ( ) ) ,
846
+ )
847
+ } ;
848
+
849
+ if scalar_column_index. is_none ( ) {
850
+ let index = column_binding. index ;
851
+ bind_context. aggregate_info . group_items . push ( ScalarItem {
852
+ scalar : scalar. clone ( ) ,
853
+ index,
854
+ } ) ;
855
+ bind_context. aggregate_info . group_items_map . insert (
856
+ scalar. clone ( ) ,
857
+ bind_context. aggregate_info . group_items . len ( ) - 1 ,
858
+ ) ;
859
+ scalar_column_index = Some ( bind_context. aggregate_info . group_items . len ( ) - 1 ) ;
860
+ }
861
+
862
+ let scalar_column_index = scalar_column_index. unwrap ( ) ;
818
863
819
- // Add a mapping (alias -> scalar), so we can resolve the alias later
820
864
let column_ref: ScalarExpr = BoundColumnRef {
821
865
span : scalar. span ( ) ,
822
- column : column_binding,
866
+ column : column_binding. clone ( ) ,
823
867
}
824
868
. into ( ) ;
825
- bind_context. aggregate_info . group_items_map . insert (
826
- column_ref,
827
- bind_context. aggregate_info . group_items . len ( ) - 1 ,
828
- ) ;
869
+ let has_column = bind_context
870
+ . aggregate_info
871
+ . group_items_map
872
+ . contains_key ( & column_ref) ;
873
+ if !has_column {
874
+ // We will add the alias to BindContext, so we can reference it
875
+ // in `HAVING` and `ORDER BY` clause.
876
+ bind_context. add_column_binding ( column_binding. clone ( ) ) ;
877
+
878
+ // Add a mapping (alias -> scalar), so we can resolve the alias later
879
+ bind_context
880
+ . aggregate_info
881
+ . group_items_map
882
+ . insert ( column_ref, scalar_column_index) ;
883
+ }
829
884
830
885
Ok ( ( scalar. clone ( ) , scalar. data_type ( ) ?) )
831
886
}
0 commit comments