@@ -8,7 +8,7 @@ use nom_sql::{
88} ;
99use readyset_errors:: { ReadySetError , ReadySetResult } ;
1010
11- use crate :: util :: { self , outermost_named_tables } ;
11+ use crate :: { outermost_table_exprs , util } ;
1212
1313pub trait StarExpansion : Sized {
1414 /// Expand all `*` column references in the query given a map from tables to the lists of
@@ -41,7 +41,7 @@ impl<'ast, 'schema> VisitorMut<'ast> for ExpandStarsVisitor<'schema> {
4141 & select_statement. join ,
4242 ) ;
4343
44- let expand_table = |table : Relation | -> ReadySetResult < _ > {
44+ let expand_table = |table : Relation , alias : Option < SqlIdentifier > | -> ReadySetResult < _ > {
4545 Ok ( if table. schema . is_none ( ) {
4646 // Can only reference subqueries with tables that don't have a schema
4747 subquery_schemas. get ( & table. name ) . cloned ( )
@@ -69,7 +69,12 @@ impl<'ast, 'schema> VisitorMut<'ast> for ExpandStarsVisitor<'schema> {
6969 . into_iter ( )
7070 . map ( move |f| FieldDefinitionExpr :: Expr {
7171 expr : Expr :: Column ( Column {
72- table : Some ( table. clone ( ) ) ,
72+ table : Some (
73+ alias
74+ . clone ( )
75+ . map ( Relation :: from)
76+ . unwrap_or_else ( || table. clone ( ) ) ,
77+ ) ,
7378 name : f. clone ( ) ,
7479 } ) ,
7580 alias : None ,
@@ -79,14 +84,46 @@ impl<'ast, 'schema> VisitorMut<'ast> for ExpandStarsVisitor<'schema> {
7984 for field in fields {
8085 match field {
8186 FieldDefinitionExpr :: All => {
82- for name in outermost_named_tables ( select_statement) . collect :: < Vec < _ > > ( ) {
83- for field in expand_table ( name) ? {
84- select_statement. fields . push ( field) ;
87+ for expr in outermost_table_exprs ( select_statement)
88+ . cloned ( )
89+ . collect :: < Vec < _ > > ( )
90+ {
91+ if let Some ( tbl) = expr
92+ . inner
93+ . as_table ( )
94+ . cloned ( )
95+ . or_else ( || expr. alias . clone ( ) . map ( Into :: into) )
96+ {
97+ for field in expand_table ( tbl, expr. alias . clone ( ) ) ? {
98+ select_statement. fields . push ( field) ;
99+ }
100+ continue ;
85101 }
86102 }
87103 }
88104 FieldDefinitionExpr :: AllInTable ( t) => {
89- for field in expand_table ( t) ? {
105+ let alias = if t. schema . is_none ( ) {
106+ Some ( t. name . clone ( ) )
107+ } else {
108+ None
109+ } ;
110+
111+ let tbl = t
112+ . schema
113+ . is_none ( )
114+ . then ( || {
115+ outermost_table_exprs ( select_statement) . find_map ( |expr| {
116+ if expr. alias . is_some ( ) && expr. alias == alias {
117+ expr. inner . as_table ( ) . cloned ( )
118+ } else {
119+ None
120+ }
121+ } )
122+ } )
123+ . flatten ( )
124+ . unwrap_or ( t) ;
125+
126+ for field in expand_table ( tbl, alias) ? {
90127 select_statement. fields . push ( field) ;
91128 }
92129 }
@@ -159,6 +196,24 @@ mod tests {
159196 ) ;
160197 }
161198
199+ #[ test]
200+ fn aliased ( ) {
201+ expands_stars (
202+ "SELECT * FROM PaperTag AS t" ,
203+ "SELECT t.paper_id, t.tag_id FROM PaperTag AS t" ,
204+ HashMap :: from ( [ ( "PaperTag" . into ( ) , vec ! [ "paper_id" . into( ) , "tag_id" . into( ) ] ) ] ) ,
205+ ) ;
206+ }
207+
208+ #[ test]
209+ fn referencing_alias ( ) {
210+ expands_stars (
211+ "SELECT t.* FROM PaperTag AS t" ,
212+ "SELECT t.paper_id, t.tag_id FROM PaperTag AS t" ,
213+ HashMap :: from ( [ ( "PaperTag" . into ( ) , vec ! [ "paper_id" . into( ) , "tag_id" . into( ) ] ) ] ) ,
214+ ) ;
215+ }
216+
162217 #[ test]
163218 fn multiple_tables ( ) {
164219 expands_stars (
@@ -236,6 +291,15 @@ mod tests {
236291 ) ;
237292 }
238293
294+ #[ test]
295+ fn star_with_subquery ( ) {
296+ expands_stars (
297+ "SELECT * FROM (SELECT t1.x FROM t1) sq" ,
298+ "SELECT sq.x FROM (SELECT t1.x FROM t1) sq" ,
299+ HashMap :: from ( [ ( "t1" . into ( ) , vec ! [ "x" . into( ) ] ) ] ) ,
300+ )
301+ }
302+
239303 #[ test]
240304 fn simple_join ( ) {
241305 expands_stars (
0 commit comments