You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spark.apache.org by do...@apache.org on 2019/07/12 14:18:10 UTC

[spark] branch master updated: [SPARK-28228][SQL] Fix substitution order of nested WITH clauses

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

dongjoon pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/spark.git


The following commit(s) were added to refs/heads/master by this push:
     new 1a26126  [SPARK-28228][SQL] Fix substitution order of nested WITH clauses
1a26126 is described below

commit 1a26126d8c5e9bb647f858db236c370685f2f2da
Author: Peter Toth <pe...@gmail.com>
AuthorDate: Fri Jul 12 07:17:33 2019 -0700

    [SPARK-28228][SQL] Fix substitution order of nested WITH clauses
    
    ## What changes were proposed in this pull request?
    
    This PR adds compatibility of handling a `WITH` clause within another `WITH` cause. Before this PR these queries retuned `1` while after this PR they return `2` as PostgreSQL does:
    ```
    WITH
      t AS (SELECT 1),
      t2 AS (
        WITH t AS (SELECT 2)
        SELECT * FROM t
      )
    SELECT * FROM t2
    ```
    ```
    WITH t AS (SELECT 1)
    SELECT (
      WITH t AS (SELECT 2)
      SELECT * FROM t
    )
    ```
    As this is an incompatible change, the PR introduces the `spark.sql.legacy.cte.substitution.enabled` flag as an option to restore old behaviour.
    
    ## How was this patch tested?
    
    Added new UTs.
    
    Closes #25029 from peter-toth/SPARK-28228.
    
    Authored-by: Peter Toth <pe...@gmail.com>
    Signed-off-by: Dongjoon Hyun <dh...@apple.com>
---
 docs/sql-migration-guide-upgrade.md                |   2 +
 .../spark/sql/catalyst/analysis/Analyzer.scala     |  32 ---
 .../sql/catalyst/analysis/CTESubstitution.scala    | 136 +++++++++++++
 .../org/apache/spark/sql/internal/SQLConf.scala    |   6 +
 .../test/resources/sql-tests/inputs/cte-legacy.sql | 115 +++++++++++
 .../results/{cte.sql.out => cte-legacy.sql.out}    | 225 +++++----------------
 .../test/resources/sql-tests/results/cte.sql.out   |  16 +-
 7 files changed, 312 insertions(+), 220 deletions(-)

diff --git a/docs/sql-migration-guide-upgrade.md b/docs/sql-migration-guide-upgrade.md
index d39bd93..b592ddc 100644
--- a/docs/sql-migration-guide-upgrade.md
+++ b/docs/sql-migration-guide-upgrade.md
@@ -149,6 +149,8 @@ license: |
 
   - Since Spark 3.0, if files or subdirectories disappear during recursive directory listing (i.e. they appear in an intermediate listing but then cannot be read or listed during later phases of the recursive directory listing, due to either concurrent file deletions or object store consistency issues) then the listing will fail with an exception unless `spark.sql.files.ignoreMissingFiles` is `true` (default `false`). In previous versions, these missing files or subdirectories would be i [...]
 
+  - Since Spark 3.0, substitution order of nested WITH clauses is changed and an inner CTE definition takes precedence over an outer. In version 2.4 and earlier, `WITH t AS (SELECT 1), t2 AS (WITH t AS (SELECT 2) SELECT * FROM t) SELECT * FROM t2` returns `1` while in version 3.0 it returns `2`. The previous behaviour can be restored by setting `spark.sql.legacy.ctePrecedence.enabled` to `true`.
+
 ## Upgrading from Spark SQL 2.4 to 2.4.1
 
   - The value of `spark.executor.heartbeatInterval`, when specified without units like "30" rather than "30s", was
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/Analyzer.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/Analyzer.scala
index e3b4177..e55cdfe 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/Analyzer.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/Analyzer.scala
@@ -214,38 +214,6 @@ class Analyzer(
   )
 
   /**
-   * Analyze cte definitions and substitute child plan with analyzed cte definitions.
-   */
-  object CTESubstitution extends Rule[LogicalPlan] {
-    def apply(plan: LogicalPlan): LogicalPlan = plan.resolveOperatorsUp {
-      case With(child, relations) =>
-        // substitute CTE expressions right-to-left to resolve references to previous CTEs:
-        // with a as (select * from t), b as (select * from a) select * from b
-        relations.foldRight(child) {
-          case ((cteName, ctePlan), currentPlan) =>
-            substituteCTE(currentPlan, cteName, ctePlan)
-        }
-      case other => other
-    }
-
-    private def substituteCTE(
-        plan: LogicalPlan,
-        cteName: String,
-        ctePlan: LogicalPlan): LogicalPlan = {
-      plan resolveOperatorsUp {
-        case UnresolvedRelation(Seq(table)) if resolver(cteName, table) =>
-          ctePlan
-        case other =>
-          // This cannot be done in ResolveSubquery because ResolveSubquery does not know the CTE.
-          other transformExpressions {
-            case e: SubqueryExpression =>
-              e.withNewPlan(substituteCTE(e.plan, cteName, ctePlan))
-          }
-      }
-    }
-  }
-
-  /**
    * Substitute child plan with WindowSpecDefinitions.
    */
   object WindowsSubstitution extends Rule[LogicalPlan] {
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/CTESubstitution.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/CTESubstitution.scala
new file mode 100644
index 0000000..60e6bf8
--- /dev/null
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/CTESubstitution.scala
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ */
+
+package org.apache.spark.sql.catalyst.analysis
+
+import org.apache.spark.sql.catalyst.expressions.SubqueryExpression
+import org.apache.spark.sql.catalyst.plans.logical.{LogicalPlan, With}
+import org.apache.spark.sql.catalyst.rules.Rule
+import org.apache.spark.sql.internal.SQLConf
+import org.apache.spark.sql.internal.SQLConf.LEGACY_CTE_PRECEDENCE_ENABLED
+
+/**
+ * Analyze WITH nodes and substitute child plan with CTE definitions.
+ */
+object CTESubstitution extends Rule[LogicalPlan] {
+  def apply(plan: LogicalPlan): LogicalPlan = {
+    if (SQLConf.get.getConf(LEGACY_CTE_PRECEDENCE_ENABLED)) {
+      legacyTraverseAndSubstituteCTE(plan)
+    } else {
+      traverseAndSubstituteCTE(plan, false)
+    }
+  }
+
+  private def legacyTraverseAndSubstituteCTE(plan: LogicalPlan): LogicalPlan = {
+    plan.resolveOperatorsUp {
+      case With(child, relations) =>
+        // substitute CTE expressions right-to-left to resolve references to previous CTEs:
+        // with a as (select * from t), b as (select * from a) select * from b
+        relations.foldRight(child) {
+          case ((cteName, ctePlan), currentPlan) => substituteCTE(currentPlan, cteName, ctePlan)
+        }
+    }
+  }
+
+  /**
+   * Traverse the plan and expression nodes as a tree and replace matching references to CTE
+   * definitions.
+   * - If the rule encounters a WITH node then it substitutes the child of the node with CTE
+   *   definitions of the node right-to-left order as a definition can reference to a previous
+   *   one.
+   *   For example the following query is valid:
+   *   WITH
+   *     t AS (SELECT 1),
+   *     t2 AS (SELECT * FROM t)
+   *   SELECT * FROM t2
+   * - If a CTE definition contains an inner WITH node then substitution of inner should take
+   *   precedence because it can shadow an outer CTE definition.
+   *   For example the following query should return 2:
+   *   WITH
+   *     t AS (SELECT 1),
+   *     t2 AS (
+   *       WITH t AS (SELECT 2)
+   *       SELECT * FROM t
+   *     )
+   *   SELECT * FROM t2
+   * - If a CTE definition contains a subquery that contains an inner WITH node then substitution
+   *   of inner should take precedence because it can shadow an outer CTE definition.
+   *   For example the following query should return 2:
+   *   WITH t AS (SELECT 1 AS c)
+   *   SELECT max(c) FROM (
+   *     WITH t AS (SELECT 2 AS c)
+   *     SELECT * FROM t
+   *   )
+   * - If a CTE definition contains a subquery expression that contains an inner WITH node then
+   *   substitution of inner should take precedence because it can shadow an outer CTE
+   *   definition.
+   *   For example the following query should return 2:
+   *   WITH t AS (SELECT 1)
+   *   SELECT (
+   *     WITH t AS (SELECT 2)
+   *     SELECT * FROM t
+   *   )
+   * @param plan the plan to be traversed
+   * @param inTraverse whether the current traverse is called from another traverse, only in this
+   *                   case name collision can occur
+   * @return the plan where CTE substitution is applied
+   */
+  private def traverseAndSubstituteCTE(plan: LogicalPlan, inTraverse: Boolean): LogicalPlan = {
+    plan.resolveOperatorsUp {
+      case With(child: LogicalPlan, relations) =>
+        // child might contain an inner CTE that has priority so traverse and substitute inner CTEs
+        // in child first
+        val traversedChild: LogicalPlan = child transformExpressions {
+          case e: SubqueryExpression => e.withNewPlan(traverseAndSubstituteCTE(e.plan, true))
+        }
+
+        // Substitute CTE definitions from last to first as a CTE definition can reference a
+        // previous one
+        relations.foldRight(traversedChild) {
+          case ((cteName, ctePlan), currentPlan) =>
+            // A CTE definition might contain an inner CTE that has priority, so traverse and
+            // substitute CTE defined in ctePlan.
+            // A CTE definition might not be used at all or might be used multiple times. To avoid
+            // computation if it is not used and to avoid multiple recomputation if it is used
+            // multiple times we use a lazy construct with call-by-name parameter passing.
+            lazy val substitutedCTEPlan = traverseAndSubstituteCTE(ctePlan, true)
+            substituteCTE(currentPlan, cteName, substitutedCTEPlan)
+        }
+
+      // CTE name collision can occur only when inTraverse is true, it helps to avoid eager CTE
+      // substitution in a subquery expression.
+      case other if inTraverse =>
+        other.transformExpressions {
+          case e: SubqueryExpression => e.withNewPlan(traverseAndSubstituteCTE(e.plan, true))
+        }
+    }
+  }
+
+  private def substituteCTE(
+      plan: LogicalPlan,
+      cteName: String,
+      ctePlan: => LogicalPlan): LogicalPlan =
+    plan resolveOperatorsUp {
+      case UnresolvedRelation(Seq(table)) if plan.conf.resolver(cteName, table) => ctePlan
+
+      case other =>
+        // This cannot be done in ResolveSubquery because ResolveSubquery does not know the CTE.
+        other transformExpressions {
+          case e: SubqueryExpression => e.withNewPlan(substituteCTE(e.plan, cteName, ctePlan))
+        }
+    }
+}
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/internal/SQLConf.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/internal/SQLConf.scala
index 94d197b..f76103e 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/internal/SQLConf.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/internal/SQLConf.scala
@@ -1851,6 +1851,12 @@ object SQLConf {
     .booleanConf
     .createWithDefault(false)
 
+  val LEGACY_CTE_PRECEDENCE_ENABLED = buildConf("spark.sql.legacy.ctePrecedence.enabled")
+    .internal()
+    .doc("When true, outer CTE definitions takes precedence over inner definitions.")
+    .booleanConf
+    .createWithDefault(false)
+
   val LEGACY_ARRAY_EXISTS_FOLLOWS_THREE_VALUED_LOGIC =
     buildConf("spark.sql.legacy.arrayExistsFollowsThreeValuedLogic")
       .doc("When true, the ArrayExists will follow the three-valued boolean logic.")
diff --git a/sql/core/src/test/resources/sql-tests/inputs/cte-legacy.sql b/sql/core/src/test/resources/sql-tests/inputs/cte-legacy.sql
new file mode 100644
index 0000000..2f2606d
--- /dev/null
+++ b/sql/core/src/test/resources/sql-tests/inputs/cte-legacy.sql
@@ -0,0 +1,115 @@
+create temporary view t as select * from values 0, 1, 2 as t(id);
+create temporary view t2 as select * from values 0, 1 as t(id);
+
+-- CTE legacy substitution
+SET spark.sql.legacy.ctePrecedence.enabled=true;
+
+-- CTE in CTE definition
+WITH t as (
+  WITH t2 AS (SELECT 1)
+  SELECT * FROM t2
+)
+SELECT * FROM t;
+
+-- CTE in subquery
+SELECT max(c) FROM (
+  WITH t(c) AS (SELECT 1)
+  SELECT * FROM t
+);
+
+-- CTE in subquery expression
+SELECT (
+  WITH t AS (SELECT 1)
+  SELECT * FROM t
+);
+
+-- CTE in CTE definition shadows outer
+WITH
+  t AS (SELECT 1),
+  t2 AS (
+    WITH t AS (SELECT 2)
+    SELECT * FROM t
+  )
+SELECT * FROM t2;
+
+-- CTE in CTE definition shadows outer 2
+WITH
+  t(c) AS (SELECT 1),
+  t2 AS (
+    SELECT (
+      SELECT max(c) FROM (
+        WITH t(c) AS (SELECT 2)
+        SELECT * FROM t
+      )
+    )
+  )
+SELECT * FROM t2;
+
+-- CTE in CTE definition shadows outer 3
+WITH
+  t AS (SELECT 1),
+  t2 AS (
+    WITH t AS (SELECT 2),
+    t2 AS (
+      WITH t AS (SELECT 3)
+      SELECT * FROM t
+    )
+    SELECT * FROM t2
+  )
+SELECT * FROM t2;
+
+-- CTE in subquery shadows outer
+WITH t(c) AS (SELECT 1)
+SELECT max(c) FROM (
+  WITH t(c) AS (SELECT 2)
+  SELECT * FROM t
+);
+
+-- CTE in subquery shadows outer 2
+WITH t(c) AS (SELECT 1)
+SELECT sum(c) FROM (
+  SELECT max(c) AS c FROM (
+    WITH t(c) AS (SELECT 2)
+    SELECT * FROM t
+  )
+);
+
+-- CTE in subquery shadows outer 3
+WITH t(c) AS (SELECT 1)
+SELECT sum(c) FROM (
+  WITH t(c) AS (SELECT 2)
+  SELECT max(c) AS c FROM (
+    WITH t(c) AS (SELECT 3)
+    SELECT * FROM t
+  )
+);
+
+-- CTE in subquery expression shadows outer
+WITH t AS (SELECT 1)
+SELECT (
+  WITH t AS (SELECT 2)
+  SELECT * FROM t
+);
+
+-- CTE in subquery expression shadows outer 2
+WITH t AS (SELECT 1)
+SELECT (
+  SELECT (
+    WITH t AS (SELECT 2)
+    SELECT * FROM t
+  )
+);
+
+-- CTE in subquery expression shadows outer 3
+WITH t AS (SELECT 1)
+SELECT (
+  WITH t AS (SELECT 2)
+  SELECT (
+    WITH t AS (SELECT 3)
+    SELECT * FROM t
+  )
+);
+
+-- Clean up
+DROP VIEW IF EXISTS t;
+DROP VIEW IF EXISTS t2;
diff --git a/sql/core/src/test/resources/sql-tests/results/cte.sql.out b/sql/core/src/test/resources/sql-tests/results/cte-legacy.sql.out
similarity index 55%
copy from sql/core/src/test/resources/sql-tests/results/cte.sql.out
copy to sql/core/src/test/resources/sql-tests/results/cte-legacy.sql.out
index 9e90908..5193e25 100644
--- a/sql/core/src/test/resources/sql-tests/results/cte.sql.out
+++ b/sql/core/src/test/resources/sql-tests/results/cte-legacy.sql.out
@@ -1,5 +1,5 @@
 -- Automatically generated by SQLQueryTestSuite
--- Number of queries: 27
+-- Number of queries: 17
 
 
 -- !query 0
@@ -19,183 +19,48 @@ struct<>
 
 
 -- !query 2
-WITH s AS (SELECT 1 FROM s) SELECT * FROM s
+SET spark.sql.legacy.ctePrecedence.enabled=true
 -- !query 2 schema
-struct<>
+struct<key:string,value:string>
 -- !query 2 output
-org.apache.spark.sql.AnalysisException
-Table or view not found: s; line 1 pos 25
+spark.sql.legacy.ctePrecedence.enabled	true
 
 
 -- !query 3
-WITH r AS (SELECT (SELECT * FROM r))
-SELECT * FROM r
--- !query 3 schema
-struct<>
--- !query 3 output
-org.apache.spark.sql.AnalysisException
-Table or view not found: r; line 1 pos 33
-
-
--- !query 4
-WITH t AS (SELECT 1 FROM t) SELECT * FROM t
--- !query 4 schema
-struct<1:int>
--- !query 4 output
-1
-1
-1
-
-
--- !query 5
-WITH s1 AS (SELECT 1 FROM s2), s2 AS (SELECT 1 FROM s1) SELECT * FROM s1, s2
--- !query 5 schema
-struct<>
--- !query 5 output
-org.apache.spark.sql.AnalysisException
-Table or view not found: s2; line 1 pos 26
-
-
--- !query 6
-WITH t1 AS (SELECT * FROM t2), t2 AS (SELECT 2 FROM t1) SELECT * FROM t1 cross join t2
--- !query 6 schema
-struct<id:int,2:int>
--- !query 6 output
-0	2
-0	2
-1	2
-1	2
-
-
--- !query 7
-WITH CTE1 AS (
-  SELECT b.id AS id
-  FROM   T2 a
-         CROSS JOIN (SELECT id AS id FROM T2) b
-)
-SELECT t1.id AS c1,
-       t2.id AS c2
-FROM   CTE1 t1
-       CROSS JOIN CTE1 t2
--- !query 7 schema
-struct<c1:int,c2:int>
--- !query 7 output
-0	0
-0	0
-0	0
-0	0
-0	1
-0	1
-0	1
-0	1
-1	0
-1	0
-1	0
-1	0
-1	1
-1	1
-1	1
-1	1
-
-
--- !query 8
-WITH t(x) AS (SELECT 1)
-SELECT * FROM t WHERE x = 1
--- !query 8 schema
-struct<x:int>
--- !query 8 output
-1
-
-
--- !query 9
-WITH t(x, y) AS (SELECT 1, 2)
-SELECT * FROM t WHERE x = 1 AND y = 2
--- !query 9 schema
-struct<x:int,y:int>
--- !query 9 output
-1	2
-
-
--- !query 10
-WITH t(x, x) AS (SELECT 1, 2)
-SELECT * FROM t
--- !query 10 schema
-struct<x:int,x:int>
--- !query 10 output
-1	2
-
-
--- !query 11
-WITH t() AS (SELECT 1)
-SELECT * FROM t
--- !query 11 schema
-struct<>
--- !query 11 output
-org.apache.spark.sql.catalyst.parser.ParseException
-
-no viable alternative at input 'WITH t()'(line 1, pos 7)
-
-== SQL ==
-WITH t() AS (SELECT 1)
--------^^^
-SELECT * FROM t
-
-
--- !query 12
-WITH
-  t(x) AS (SELECT 1),
-  t(x) AS (SELECT 2)
-SELECT * FROM t
--- !query 12 schema
-struct<>
--- !query 12 output
-org.apache.spark.sql.catalyst.parser.ParseException
-
-CTE definition can't have duplicate names: 't'.(line 1, pos 0)
-
-== SQL ==
-WITH
-^^^
-  t(x) AS (SELECT 1),
-  t(x) AS (SELECT 2)
-SELECT * FROM t
-
-
--- !query 13
 WITH t as (
   WITH t2 AS (SELECT 1)
   SELECT * FROM t2
 )
 SELECT * FROM t
--- !query 13 schema
+-- !query 3 schema
 struct<1:int>
--- !query 13 output
+-- !query 3 output
 1
 
 
--- !query 14
+-- !query 4
 SELECT max(c) FROM (
   WITH t(c) AS (SELECT 1)
   SELECT * FROM t
 )
--- !query 14 schema
+-- !query 4 schema
 struct<max(c):int>
--- !query 14 output
+-- !query 4 output
 1
 
 
--- !query 15
+-- !query 5
 SELECT (
   WITH t AS (SELECT 1)
   SELECT * FROM t
 )
--- !query 15 schema
+-- !query 5 schema
 struct<scalarsubquery():int>
--- !query 15 output
+-- !query 5 output
 1
 
 
--- !query 16
+-- !query 6
 WITH
   t AS (SELECT 1),
   t2 AS (
@@ -203,13 +68,13 @@ WITH
     SELECT * FROM t
   )
 SELECT * FROM t2
--- !query 16 schema
+-- !query 6 schema
 struct<1:int>
--- !query 16 output
+-- !query 6 output
 1
 
 
--- !query 17
+-- !query 7
 WITH
   t(c) AS (SELECT 1),
   t2 AS (
@@ -221,13 +86,13 @@ WITH
     )
   )
 SELECT * FROM t2
--- !query 17 schema
+-- !query 7 schema
 struct<scalarsubquery():int>
--- !query 17 output
+-- !query 7 output
 1
 
 
--- !query 18
+-- !query 8
 WITH
   t AS (SELECT 1),
   t2 AS (
@@ -239,25 +104,25 @@ WITH
     SELECT * FROM t2
   )
 SELECT * FROM t2
--- !query 18 schema
+-- !query 8 schema
 struct<2:int>
--- !query 18 output
+-- !query 8 output
 2
 
 
--- !query 19
+-- !query 9
 WITH t(c) AS (SELECT 1)
 SELECT max(c) FROM (
   WITH t(c) AS (SELECT 2)
   SELECT * FROM t
 )
--- !query 19 schema
+-- !query 9 schema
 struct<max(c):int>
--- !query 19 output
+-- !query 9 output
 2
 
 
--- !query 20
+-- !query 10
 WITH t(c) AS (SELECT 1)
 SELECT sum(c) FROM (
   SELECT max(c) AS c FROM (
@@ -265,13 +130,13 @@ SELECT sum(c) FROM (
     SELECT * FROM t
   )
 )
--- !query 20 schema
+-- !query 10 schema
 struct<sum(c):bigint>
--- !query 20 output
+-- !query 10 output
 2
 
 
--- !query 21
+-- !query 11
 WITH t(c) AS (SELECT 1)
 SELECT sum(c) FROM (
   WITH t(c) AS (SELECT 2)
@@ -280,25 +145,25 @@ SELECT sum(c) FROM (
     SELECT * FROM t
   )
 )
--- !query 21 schema
+-- !query 11 schema
 struct<sum(c):bigint>
--- !query 21 output
+-- !query 11 output
 3
 
 
--- !query 22
+-- !query 12
 WITH t AS (SELECT 1)
 SELECT (
   WITH t AS (SELECT 2)
   SELECT * FROM t
 )
--- !query 22 schema
+-- !query 12 schema
 struct<scalarsubquery():int>
--- !query 22 output
+-- !query 12 output
 1
 
 
--- !query 23
+-- !query 13
 WITH t AS (SELECT 1)
 SELECT (
   SELECT (
@@ -306,13 +171,13 @@ SELECT (
     SELECT * FROM t
   )
 )
--- !query 23 schema
+-- !query 13 schema
 struct<scalarsubquery():int>
--- !query 23 output
+-- !query 13 output
 1
 
 
--- !query 24
+-- !query 14
 WITH t AS (SELECT 1)
 SELECT (
   WITH t AS (SELECT 2)
@@ -321,23 +186,23 @@ SELECT (
     SELECT * FROM t
   )
 )
--- !query 24 schema
+-- !query 14 schema
 struct<scalarsubquery():int>
--- !query 24 output
+-- !query 14 output
 1
 
 
--- !query 25
+-- !query 15
 DROP VIEW IF EXISTS t
--- !query 25 schema
+-- !query 15 schema
 struct<>
--- !query 25 output
+-- !query 15 output
 
 
 
--- !query 26
+-- !query 16
 DROP VIEW IF EXISTS t2
--- !query 26 schema
+-- !query 16 schema
 struct<>
--- !query 26 output
+-- !query 16 output
 
diff --git a/sql/core/src/test/resources/sql-tests/results/cte.sql.out b/sql/core/src/test/resources/sql-tests/results/cte.sql.out
index 9e90908..b7dd76c 100644
--- a/sql/core/src/test/resources/sql-tests/results/cte.sql.out
+++ b/sql/core/src/test/resources/sql-tests/results/cte.sql.out
@@ -204,9 +204,9 @@ WITH
   )
 SELECT * FROM t2
 -- !query 16 schema
-struct<1:int>
+struct<2:int>
 -- !query 16 output
-1
+2
 
 
 -- !query 17
@@ -224,7 +224,7 @@ SELECT * FROM t2
 -- !query 17 schema
 struct<scalarsubquery():int>
 -- !query 17 output
-1
+2
 
 
 -- !query 18
@@ -240,9 +240,9 @@ WITH
   )
 SELECT * FROM t2
 -- !query 18 schema
-struct<2:int>
+struct<3:int>
 -- !query 18 output
-2
+3
 
 
 -- !query 19
@@ -295,7 +295,7 @@ SELECT (
 -- !query 22 schema
 struct<scalarsubquery():int>
 -- !query 22 output
-1
+2
 
 
 -- !query 23
@@ -309,7 +309,7 @@ SELECT (
 -- !query 23 schema
 struct<scalarsubquery():int>
 -- !query 23 output
-1
+2
 
 
 -- !query 24
@@ -324,7 +324,7 @@ SELECT (
 -- !query 24 schema
 struct<scalarsubquery():int>
 -- !query 24 output
-1
+3
 
 
 -- !query 25


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@spark.apache.org
For additional commands, e-mail: commits-help@spark.apache.org