1818use crate :: planner:: { ContextProvider , PlannerContext , SqlToRel } ;
1919use datafusion_common:: { not_impl_err, Column , Result } ;
2020use datafusion_expr:: { JoinType , LogicalPlan , LogicalPlanBuilder } ;
21- use sqlparser:: ast:: { Join , JoinConstraint , JoinOperator , TableWithJoins } ;
21+ use sqlparser:: ast:: { Join , JoinConstraint , JoinOperator , TableFactor , TableWithJoins } ;
2222use std:: collections:: HashSet ;
2323
2424impl < ' a , S : ContextProvider > SqlToRel < ' a , S > {
@@ -27,10 +27,17 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
2727 t : TableWithJoins ,
2828 planner_context : & mut PlannerContext ,
2929 ) -> Result < LogicalPlan > {
30- let mut left = self . create_relation ( t. relation , planner_context) ?;
31- for join in t. joins . into_iter ( ) {
30+ let mut left = if is_lateral ( & t. relation ) {
31+ self . create_relation_subquery ( t. relation , planner_context) ?
32+ } else {
33+ self . create_relation ( t. relation , planner_context) ?
34+ } ;
35+ let old_outer_from_schema = planner_context. outer_from_schema ( ) ;
36+ for join in t. joins {
37+ planner_context. extend_outer_from_schema ( left. schema ( ) ) ?;
3238 left = self . parse_relation_join ( left, join, planner_context) ?;
3339 }
40+ planner_context. set_outer_from_schema ( old_outer_from_schema) ;
3441 Ok ( left)
3542 }
3643
@@ -40,7 +47,11 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
4047 join : Join ,
4148 planner_context : & mut PlannerContext ,
4249 ) -> Result < LogicalPlan > {
43- let right = self . create_relation ( join. relation , planner_context) ?;
50+ let right = if is_lateral_join ( & join) ? {
51+ self . create_relation_subquery ( join. relation , planner_context) ?
52+ } else {
53+ self . create_relation ( join. relation , planner_context) ?
54+ } ;
4455 match join. join_operator {
4556 JoinOperator :: LeftOuter ( constraint) => {
4657 self . parse_join ( left, right, constraint, JoinType :: Left , planner_context)
@@ -144,3 +155,30 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
144155 }
145156 }
146157}
158+
159+ /// Return `true` iff the given [`TableFactor`] is lateral.
160+ pub ( crate ) fn is_lateral ( factor : & TableFactor ) -> bool {
161+ match factor {
162+ TableFactor :: Derived { lateral, .. } => * lateral,
163+ TableFactor :: Function { lateral, .. } => * lateral,
164+ _ => false ,
165+ }
166+ }
167+
168+ /// Return `true` iff the given [`Join`] is lateral.
169+ pub ( crate ) fn is_lateral_join ( join : & Join ) -> Result < bool > {
170+ let is_lateral_syntax = is_lateral ( & join. relation ) ;
171+ let is_apply_syntax = match join. join_operator {
172+ JoinOperator :: FullOuter ( ..)
173+ | JoinOperator :: RightOuter ( ..)
174+ | JoinOperator :: RightAnti ( ..)
175+ | JoinOperator :: RightSemi ( ..)
176+ if is_lateral_syntax =>
177+ {
178+ return not_impl_err ! ( "NONE constraint is not supported" ) ;
179+ }
180+ JoinOperator :: CrossApply | JoinOperator :: OuterApply => true ,
181+ _ => false ,
182+ } ;
183+ Ok ( is_lateral_syntax || is_apply_syntax)
184+ }
0 commit comments