From 4274826e2acb791cdf9fe31be6b416c5f2ca3b33 Mon Sep 17 00:00:00 2001 From: Alexander Alexandrov Date: Sun, 14 Jul 2024 19:50:40 +0300 Subject: [PATCH] Planner: use `DFSchema::merge` in `create_relation_subquery` In order to compute the `set_outer_from_schema` argument we currently use `DFSchema::join`. When we combine the current outer FROM schema with the current outer query schema columns from the latter should override columns from the first, so the correct way is to use `DFSchema::merge`. To witness the fix, note that the query in the fixed test case isn't planned as expected without the accompanying changes. --- datafusion/sql/src/relation/mod.rs | 10 ++++++++-- datafusion/sql/tests/sql_integration.rs | 15 ++++++++++++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/datafusion/sql/src/relation/mod.rs b/datafusion/sql/src/relation/mod.rs index 9e05bd835a2d..86e49780724b 100644 --- a/datafusion/sql/src/relation/mod.rs +++ b/datafusion/sql/src/relation/mod.rs @@ -169,9 +169,15 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> { // factors, and those can never be the first factor in a FROM list. This // means we arrived here through the `for` loop in `plan_from_tables` or // the `for` loop in `plan_table_with_joins`. - let old_from_schema = planner_context.set_outer_from_schema(None).unwrap(); + let old_from_schema = planner_context + .set_outer_from_schema(None) + .unwrap_or_else(|| Arc::new(DFSchema::empty())); let new_query_schema = match planner_context.outer_query_schema() { - Some(lhs) => Some(Arc::new(lhs.join(&old_from_schema)?)), + Some(old_query_schema) => { + let mut new_query_schema = old_from_schema.as_ref().clone(); + new_query_schema.merge(old_query_schema); + Some(Arc::new(new_query_schema)) + } None => Some(Arc::clone(&old_from_schema)), }; let old_query_schema = planner_context.set_outer_query_schema(new_query_schema); diff --git a/datafusion/sql/tests/sql_integration.rs b/datafusion/sql/tests/sql_integration.rs index f7c0f68a9b10..b936a51dbefc 100644 --- a/datafusion/sql/tests/sql_integration.rs +++ b/datafusion/sql/tests/sql_integration.rs @@ -3103,6 +3103,19 @@ fn join_on_complex_condition() { quick_test(sql, expected); } +#[test] +fn lateral_constant() { + let sql = "SELECT * FROM j1, LATERAL (SELECT 1) AS j2"; + let expected = "Projection: j1.j1_id, j1.j1_string, j2.Int64(1)\ + \n CrossJoin:\ + \n TableScan: j1\ + \n SubqueryAlias: j2\ + \n Subquery:\ + \n Projection: Int64(1)\ + \n EmptyRelation"; + quick_test(sql, expected); +} + #[test] fn lateral_comma_join() { let sql = "SELECT j1_string, j2_string FROM @@ -3145,7 +3158,7 @@ fn lateral_comma_join_with_shadowing() { let sql = "\ SELECT * FROM j1, LATERAL (\ SELECT * FROM j1, LATERAL (\ - SELECT * FROM j2 WHERE j1.j1_id = j2_id\ + SELECT * FROM j2 WHERE j1_id = j2_id\ ) as j2\ ) as j2;"; let expected = "Projection: j1.j1_id, j1.j1_string, j2.j1_id, j2.j1_string, j2.j2_id, j2.j2_string\