From c0a65a4e29bd811526e8a6ff8a3dc55cd3b74068 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 | 6 +++++- datafusion/sql/tests/sql_integration.rs | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/datafusion/sql/src/relation/mod.rs b/datafusion/sql/src/relation/mod.rs index 8279e8def60d..77addfe43bcc 100644 --- a/datafusion/sql/src/relation/mod.rs +++ b/datafusion/sql/src/relation/mod.rs @@ -161,7 +161,11 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> { // the `for` loop in `plan_table_with_joins`. let old_from_schema = planner_context.set_outer_from_schema(None).unwrap(); 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 6976b9d69c14..383bc591c391 100644 --- a/datafusion/sql/tests/sql_integration.rs +++ b/datafusion/sql/tests/sql_integration.rs @@ -3219,7 +3219,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\