@@ -708,18 +708,6 @@ fn plan_table_factor<'a>(
708
708
if !with_hints. is_empty ( ) {
709
709
unsupported ! ( "WITH hints" ) ;
710
710
}
711
- let alias = if let Some ( TableAlias { name, columns } ) = alias {
712
- if !columns. is_empty ( ) {
713
- unsupported ! ( 3112 , "aliasing columns" ) ;
714
- }
715
- PartialName {
716
- database : None ,
717
- schema : None ,
718
- item : normalize:: ident ( name. clone ( ) ) ,
719
- }
720
- } else {
721
- normalize:: object_name ( name. clone ( ) ) ?
722
- } ;
723
711
if let Some ( args) = args {
724
712
let ecx = & ExprContext {
725
713
qcx,
@@ -729,19 +717,16 @@ fn plan_table_factor<'a>(
729
717
allow_aggregates : false ,
730
718
allow_subqueries : true ,
731
719
} ;
732
- plan_table_function ( ecx, left, & name, Some ( alias) , args)
720
+ plan_table_function ( ecx, left, & name, alias. as_ref ( ) , args)
733
721
} else {
734
722
let name = qcx. scx . resolve_item ( name. clone ( ) ) ?;
735
723
let item = qcx. scx . catalog . get_item ( & name) ;
736
724
let expr = RelationExpr :: Get {
737
725
id : Id :: Global ( item. id ( ) ) ,
738
726
typ : item. desc ( ) ?. typ ( ) . clone ( ) ,
739
727
} ;
740
- let scope = Scope :: from_source (
741
- Some ( alias) ,
742
- item. desc ( ) ?. iter_names ( ) ,
743
- Some ( qcx. outer_scope . clone ( ) ) ,
744
- ) ;
728
+ let column_names = item. desc ( ) ?. iter_names ( ) . map ( |n| n. cloned ( ) ) . collect ( ) ;
729
+ let scope = plan_table_alias ( qcx, alias. as_ref ( ) , Some ( name. into ( ) ) , column_names) ?;
745
730
plan_join_operator ( qcx, & join_operator, left, left_scope, expr, scope)
746
731
}
747
732
}
@@ -754,20 +739,9 @@ fn plan_table_factor<'a>(
754
739
unsupported ! ( 3111 , "LATERAL derived tables" ) ;
755
740
}
756
741
let ( expr, scope) = plan_subquery ( & qcx, & subquery) ?;
757
- let alias = if let Some ( TableAlias { name, columns } ) = alias {
758
- if !columns. is_empty ( ) {
759
- unsupported ! ( 3112 , "aliasing columns" ) ;
760
- }
761
- Some ( PartialName {
762
- database : None ,
763
- schema : None ,
764
- item : normalize:: ident ( name. clone ( ) ) ,
765
- } )
766
- } else {
767
- None
768
- } ;
769
- let scope =
770
- Scope :: from_source ( alias, scope. column_names ( ) , Some ( qcx. outer_scope . clone ( ) ) ) ;
742
+ let table_name = None ;
743
+ let column_names = scope. column_names ( ) . map ( |n| n. cloned ( ) ) . collect ( ) ;
744
+ let scope = plan_table_alias ( qcx, alias. as_ref ( ) , table_name, column_names) ?;
771
745
plan_join_operator ( qcx, & join_operator, left, left_scope, expr, scope)
772
746
}
773
747
TableFactor :: NestedJoin ( table_with_joins) => {
@@ -780,30 +754,71 @@ fn plan_table_function(
780
754
ecx : & ExprContext ,
781
755
left : RelationExpr ,
782
756
name : & ObjectName ,
783
- alias : Option < PartialName > ,
757
+ alias : Option < & TableAlias > ,
784
758
args : & FunctionArgs ,
785
759
) -> Result < ( RelationExpr , Scope ) , failure:: Error > {
786
- let ident = & * normalize:: function_name ( name. clone ( ) ) ?;
760
+ let ident = normalize:: function_name ( name. clone ( ) ) ?;
787
761
let args = match args {
788
762
FunctionArgs :: Star => bail ! ( "{} does not accept * as an argument" , ident) ,
789
763
FunctionArgs :: Args ( args) => args,
790
764
} ;
791
- let tf = func:: select_table_func ( ecx, ident, args) ?;
765
+ let tf = func:: select_table_func ( ecx, & * ident, args) ?;
792
766
let call = RelationExpr :: FlatMap {
793
767
input : Box :: new ( left) ,
794
768
func : tf. func ,
795
769
exprs : tf. exprs ,
796
770
} ;
797
- let scope = Scope :: from_source (
798
- alias,
799
- tf. column_names
800
- . iter ( )
801
- . map ( |name| Some ( ColumnName :: from ( & * * name) ) ) ,
802
- Some ( ecx. qcx . outer_scope . clone ( ) ) ,
803
- ) ;
771
+ let name = PartialName {
772
+ database : None ,
773
+ schema : None ,
774
+ item : ident,
775
+ } ;
776
+ let scope = plan_table_alias ( ecx. qcx , alias, Some ( name) , tf. column_names ) ?;
804
777
Ok ( ( call, ecx. scope . clone ( ) . product ( scope) ) )
805
778
}
806
779
780
+ fn plan_table_alias (
781
+ qcx : & QueryContext ,
782
+ alias : Option < & TableAlias > ,
783
+ inherent_table_name : Option < PartialName > ,
784
+ inherent_column_names : Vec < Option < ColumnName > > ,
785
+ ) -> Result < Scope , failure:: Error > {
786
+ let table_name = match alias {
787
+ None => inherent_table_name,
788
+ Some ( TableAlias { name, .. } ) => Some ( PartialName {
789
+ database : None ,
790
+ schema : None ,
791
+ item : normalize:: ident ( name. to_owned ( ) ) ,
792
+ } ) ,
793
+ } ;
794
+ let column_names = match alias {
795
+ None => inherent_column_names,
796
+ Some ( TableAlias { columns, .. } ) if columns. is_empty ( ) => inherent_column_names,
797
+ Some ( TableAlias { columns, .. } ) if columns. len ( ) > inherent_column_names. len ( ) => {
798
+ bail ! (
799
+ "{} has {} columns available but {} columns specified" ,
800
+ table_name
801
+ . map( |n| n. to_string( ) )
802
+ . as_deref( )
803
+ . unwrap_or( "subquery" ) ,
804
+ inherent_column_names. len( ) ,
805
+ columns. len( )
806
+ ) ;
807
+ }
808
+ Some ( TableAlias { columns, .. } ) => columns
809
+ . iter ( )
810
+ . cloned ( )
811
+ . map ( |n| Some ( normalize:: column_name ( n) ) )
812
+ . chain ( inherent_column_names. into_iter ( ) . skip ( columns. len ( ) ) )
813
+ . collect ( ) ,
814
+ } ;
815
+ Ok ( Scope :: from_source (
816
+ table_name,
817
+ column_names,
818
+ Some ( qcx. outer_scope . clone ( ) ) ,
819
+ ) )
820
+ }
821
+
807
822
fn plan_select_item < ' a > (
808
823
ecx : & ExprContext ,
809
824
s : & ' a SelectItem ,
0 commit comments