You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by xu...@apache.org on 2022/12/03 14:39:50 UTC

[arrow-datafusion] branch master updated: Fix `Cte` in `from` clause with duplicated cte name (#4461)

This is an automated email from the ASF dual-hosted git repository.

xudong963 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow-datafusion.git


The following commit(s) were added to refs/heads/master by this push:
     new 156a594e0 Fix `Cte` in `from` clause with duplicated cte name (#4461)
156a594e0 is described below

commit 156a594e0ba3108c96f04a765ae112adc1182da5
Author: xudong.w <wx...@gmail.com>
AuthorDate: Sat Dec 3 22:39:44 2022 +0800

    Fix `Cte` in `from` clause with duplicated cte name (#4461)
    
    * Fix CTE in from clause with duplicated cte name
    
    * add logictest
    
    * remove clone
    
    * add more annotations
---
 .../core/tests/sqllogictests/test_files/cte.slt     | 21 +++++++++++++++++++++
 datafusion/sql/src/planner.rs                       | 14 +++++++++++++-
 2 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/datafusion/core/tests/sqllogictests/test_files/cte.slt b/datafusion/core/tests/sqllogictests/test_files/cte.slt
new file mode 100644
index 000000000..c62b56584
--- /dev/null
+++ b/datafusion/core/tests/sqllogictests/test_files/cte.slt
@@ -0,0 +1,21 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+
+#   http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+query II
+select * from (WITH source AS (select 1 as e) SELECT * FROM source) t1,   (WITH source AS (select 1 as e) SELECT * FROM source) t2
+----
+1 1
diff --git a/datafusion/sql/src/planner.rs b/datafusion/sql/src/planner.rs
index 154e36f48..c2ea7001b 100644
--- a/datafusion/sql/src/planner.rs
+++ b/datafusion/sql/src/planner.rs
@@ -662,11 +662,21 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
         ctes: &mut HashMap<String, LogicalPlan>,
         outer_query_schema: Option<&DFSchema>,
     ) -> Result<LogicalPlan> {
+        // From clause may exist CTEs, we should separate them from global CTEs.
+        // CTEs in from clause are allowed to be duplicated.
+        // Such as `select * from (WITH source AS (select 1 as e) SELECT * FROM source) t1, (WITH source AS (select 1 as e) SELECT * FROM source) t2;` which is valid.
+        // So always use original global CTEs to plan CTEs in from clause.
+        // Btw, don't need to add CTEs in from to global CTEs.
+        let origin_ctes = ctes.clone();
         let left = self.create_relation(t.relation, ctes, outer_query_schema)?;
         match t.joins.len() {
-            0 => Ok(left),
+            0 => {
+                *ctes = origin_ctes;
+                Ok(left)
+            }
             _ => {
                 let mut joins = t.joins.into_iter();
+                *ctes = origin_ctes.clone();
                 let mut left = self.parse_relation_join(
                     left,
                     joins.next().unwrap(), // length of joins > 0
@@ -674,9 +684,11 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
                     outer_query_schema,
                 )?;
                 for join in joins {
+                    *ctes = origin_ctes.clone();
                     left =
                         self.parse_relation_join(left, join, ctes, outer_query_schema)?;
                 }
+                *ctes = origin_ctes;
                 Ok(left)
             }
         }