@@ -31,7 +31,7 @@ use itertools::Itertools;
3131use sqlparser:: ast;
3232use sqlparser:: ast:: {
3333 Distinct , Expr , Ident , Join , JoinConstraint , JoinOperator , Offset , OrderByExpr , Query , Select ,
34- SelectItem , SetExpr , TableFactor , TableWithJoins ,
34+ SelectItem , SetExpr , TableAlias , TableFactor , TableWithJoins ,
3535} ;
3636
3737impl < ' a , T : Transaction > Binder < ' a , T > {
@@ -128,18 +128,25 @@ impl<'a, T: Transaction> Binder<'a, T> {
128128 let ( left_name, mut plan) = self . bind_single_table_ref ( relation, None ) ?;
129129
130130 if !joins. is_empty ( ) {
131+ let left_name = Self :: unpack_name ( left_name, true ) ;
132+
131133 for join in joins {
132- plan = self . bind_join ( left_name. clone ( ) , plan, join) ?;
134+ plan = self . bind_join ( & left_name, plan, join) ?;
133135 }
134136 }
135137 Ok ( plan)
136138 }
137139
140+ fn unpack_name ( table_name : Option < TableName > , is_left : bool ) -> TableName {
141+ let title = if is_left { "Left" } else { "Right" } ;
142+ table_name. expect ( & format ! ( "{}: Table is not named" , title) )
143+ }
144+
138145 fn bind_single_table_ref (
139146 & mut self ,
140147 table : & TableFactor ,
141148 joint_type : Option < JoinType > ,
142- ) -> Result < ( TableName , LogicalPlan ) , BindError > {
149+ ) -> Result < ( Option < TableName > , LogicalPlan ) , BindError > {
143150 let plan_with_name = match table {
144151 TableFactor :: Table { name, alias, .. } => {
145152 let obj_name = name
@@ -148,45 +155,69 @@ impl<'a, T: Transaction> Binder<'a, T> {
148155 . map ( |ident| Ident :: new ( ident. value . to_lowercase ( ) ) )
149156 . collect_vec ( ) ;
150157
151- let ( _database, _schema, mut table) : ( & str , & str , & str ) = match obj_name. as_slice ( )
152- {
158+ let ( _database, _schema, table) : ( & str , & str , & str ) = match obj_name. as_slice ( ) {
153159 [ table] => ( DEFAULT_DATABASE_NAME , DEFAULT_SCHEMA_NAME , & table. value ) ,
154160 [ schema, table] => ( DEFAULT_DATABASE_NAME , & schema. value , & table. value ) ,
155161 [ database, schema, table] => ( & database. value , & schema. value , & table. value ) ,
156162 _ => return Err ( BindError :: InvalidTableName ( obj_name) ) ,
157163 } ;
158- if let Some ( alias) = alias {
159- table = & alias. name . value ;
160- }
161164
162- self . _bind_single_table_ref ( joint_type, table) ?
165+ let ( table, plan) =
166+ self . _bind_single_table_ref ( joint_type, table, Self :: trans_alias ( alias) ) ?;
167+ ( Some ( table) , plan)
168+ }
169+ TableFactor :: Derived {
170+ subquery, alias, ..
171+ } => {
172+ let plan = self . bind_query ( subquery) ?;
173+ let mut tables = plan. referenced_table ( ) ;
174+
175+ if let Some ( alias) = Self :: trans_alias ( alias) {
176+ let alias = Arc :: new ( alias. clone ( ) ) ;
177+
178+ if tables. len ( ) > 1 {
179+ todo ! ( "Implement virtual tables for multiple table aliases" ) ;
180+ }
181+ // FIXME
182+ self . context
183+ . add_table_alias ( alias. to_string ( ) , tables. remove ( 0 ) ) ?;
184+
185+ ( Some ( alias) , plan)
186+ } else {
187+ ( ( tables. len ( ) > 1 ) . then ( || tables. pop ( ) ) . flatten ( ) , plan)
188+ }
163189 }
164190 _ => unimplemented ! ( ) ,
165191 } ;
166192
167193 Ok ( plan_with_name)
168194 }
169195
196+ pub ( crate ) fn trans_alias ( alias : & Option < TableAlias > ) -> Option < & String > {
197+ alias. as_ref ( ) . map ( |alias| & alias. name . value )
198+ }
199+
170200 pub ( crate ) fn _bind_single_table_ref (
171201 & mut self ,
172- joint_type : Option < JoinType > ,
202+ join_type : Option < JoinType > ,
173203 table : & str ,
204+ alias : Option < & String > ,
174205 ) -> Result < ( Arc < String > , LogicalPlan ) , BindError > {
175206 let table_name = Arc :: new ( table. to_string ( ) ) ;
176207
177- if self . context . bind_table . contains_key ( & table_name) {
178- return Err ( BindError :: InvalidTable ( format ! ( "{} duplicated" , table) ) ) ;
179- }
180-
181208 let table_catalog = self
182209 . context
183- . transaction
184210 . table ( & table_name)
211+ . cloned ( )
185212 . ok_or_else ( || BindError :: InvalidTable ( format ! ( "bind table {}" , table) ) ) ?;
186213
187214 self . context
188- . bind_table
189- . insert ( table_name. clone ( ) , ( table_catalog. clone ( ) , joint_type) ) ;
215+ . add_bind_table ( table_name. clone ( ) , table_catalog. clone ( ) , join_type) ?;
216+
217+ if let Some ( alias) = alias {
218+ self . context
219+ . add_table_alias ( alias. to_string ( ) , table_name. clone ( ) ) ?;
220+ }
190221
191222 Ok ( (
192223 table_name. clone ( ) ,
@@ -213,7 +244,7 @@ impl<'a, T: Transaction> Binder<'a, T> {
213244 let expr = self . bind_expr ( expr) ?;
214245 let alias_name = alias. to_string ( ) ;
215246
216- self . context . add_alias ( alias_name. clone ( ) , expr. clone ( ) ) ;
247+ self . context . add_alias ( alias_name. clone ( ) , expr. clone ( ) ) ? ;
217248
218249 select_items. push ( ScalarExpression :: Alias {
219250 expr : Box :: new ( expr) ,
@@ -236,7 +267,6 @@ impl<'a, T: Transaction> Binder<'a, T> {
236267 for table_name in self . context . bind_table . keys ( ) . cloned ( ) {
237268 let table = self
238269 . context
239- . transaction
240270 . table ( & table_name)
241271 . ok_or_else ( || BindError :: InvalidTable ( table_name. to_string ( ) ) ) ?;
242272 for col in table. all_columns ( ) {
@@ -249,7 +279,7 @@ impl<'a, T: Transaction> Binder<'a, T> {
249279
250280 fn bind_join (
251281 & mut self ,
252- left_table : TableName ,
282+ left_table : & String ,
253283 left : LogicalPlan ,
254284 join : & Join ,
255285 ) -> Result < LogicalPlan , BindError > {
@@ -266,21 +296,17 @@ impl<'a, T: Transaction> Binder<'a, T> {
266296 JoinOperator :: CrossJoin => ( JoinType :: Cross , None ) ,
267297 _ => unimplemented ! ( ) ,
268298 } ;
269-
270299 let ( right_table, right) = self . bind_single_table_ref ( relation, Some ( join_type) ) ?;
271-
272- let left_table = self
273- . context
274- . transaction
275- . table ( & left_table)
276- . cloned ( )
277- . ok_or_else ( || BindError :: InvalidTable ( format ! ( "Left: {} not found" , left_table) ) ) ?;
278- let right_table = self
279- . context
280- . transaction
281- . table ( & right_table)
282- . cloned ( )
283- . ok_or_else ( || BindError :: InvalidTable ( format ! ( "Right: {} not found" , right_table) ) ) ?;
300+ let right_table = Self :: unpack_name ( right_table, false ) ;
301+
302+ let left_table =
303+ self . context . table ( left_table) . cloned ( ) . ok_or_else ( || {
304+ BindError :: InvalidTable ( format ! ( "Left: {} not found" , left_table) )
305+ } ) ?;
306+ let right_table =
307+ self . context . table ( & right_table) . cloned ( ) . ok_or_else ( || {
308+ BindError :: InvalidTable ( format ! ( "Right: {} not found" , right_table) )
309+ } ) ?;
284310
285311 let on = match joint_condition {
286312 Some ( constraint) => self . bind_join_constraint ( & left_table, & right_table, constraint) ?,
0 commit comments