You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spark.apache.org by we...@apache.org on 2025/02/12 16:14:43 UTC

(spark) branch master updated: [SPARK-51113][SQL] Fix correctness with UNION/EXCEPT/INTERSECT inside a view or EXECUTE IMMEDIATE

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

wenchen 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 d0e07ac92473 [SPARK-51113][SQL] Fix correctness with UNION/EXCEPT/INTERSECT inside a view or EXECUTE IMMEDIATE
d0e07ac92473 is described below

commit d0e07ac924732d08a5213f425990990182bbf17a
Author: Vladimir Golubev <vl...@databricks.com>
AuthorDate: Thu Feb 13 00:14:27 2025 +0800

    [SPARK-51113][SQL] Fix correctness with UNION/EXCEPT/INTERSECT inside a view or EXECUTE IMMEDIATE
    
    ### What changes were proposed in this pull request?
    
    Fix correctness with UNION/EXCEPT/INTERSECT inside a view or `EXECUTE IMMEDIATE`.
    
    In the following examples the SQL Parser considers UNION/EXCEPT/INTERSECT keywords as aliases and drops the rest of the query:
    
    ```
    spark.sql("CREATE OR REPLACE VIEW v1 AS SELECT 1 AS col1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4")
    spark.sql("SELECT * FROM v1").show()
    spark.sql("SELECT * FROM v1").queryExecution.analyzed
    
    spark.sql("CREATE OR REPLACE VIEW v1 AS SELECT 1 AS col1 EXCEPT SELECT 2 EXCEPT SELECT 1 EXCEPT SELECT 2")
    spark.sql("SELECT * FROM v1").show()
    spark.sql("SELECT * FROM v1").queryExecution.analyzed
    
    spark.sql("CREATE OR REPLACE VIEW t1 AS SELECT 1 AS col1 INTERSECT SELECT 1 INTERSECT SELECT 2 INTERSECT SELECT 2")
    spark.sql("SELECT * FROM v1").show()
    spark.sql("SELECT * FROM v1").queryExecution.analyzed
    
    spark.sql("DECLARE v INT")
    spark.sql("EXECUTE IMMEDIATE 'SELECT 1 UNION SELECT 2 UNION SELECT 3' INTO v")
    spark.sql("EXECUTE IMMEDIATE 'SELECT 1 UNION SELECT 2 UNION SELECT 3' INTO v").queryExecution.analyzed
    spark.sql("SELECT v").show()
    ```
    
    ![image](https://github.com/user-attachments/assets/ef726178-2375-4ebc-a7e3-88f1991d1016)
    ![image](https://github.com/user-attachments/assets/50b4b7ba-bc7d-4fc1-a921-f4cbfcab79a3)
    ![image](https://github.com/user-attachments/assets/85b65325-5dd9-4d74-b46d-8ea203ce1039)
    ![image](https://github.com/user-attachments/assets/c53c5e02-18c6-4e30-b834-94af619190c5)
    
    There's no correctness issue associated with regular queries (without the `VIEW` or `EXECUTE IMMEDIATE`). Apparently that's because we use `ParserInterface.parsePlan` (`singleStatement` term in Spark SQL grammar) for [regular queries](https://github.com/apache/spark/blob/b968ce1d3ac1b72019b30bf3d4e11d9574ba1205/sql/core/src/main/scala/org/apache/spark/sql/classic/SparkSession.scala#L490) and `ParserInterface.parseQuery` (`query` term in Spark SQL grammar) for [view bodies](https://git [...]
    
    Not sure what's the actual root cause, because I don't know much about the SQL Parser.
    
    ### Why are the changes needed?
    
    Correctness issue fix.
    
    ### Does this PR introduce _any_ user-facing change?
    
    Yes, the results of queries on top of aforementioned views are gonna be correct.
    
    ### How was this patch tested?
    
    New `view-correctness` suite.
    
    ### Was this patch authored or co-authored using generative AI tooling?
    
    No.
    
    Closes #49835 from vladimirg-db/vladimirg-db/fix-views-with-trivial-unions.
    
    Authored-by: Vladimir Golubev <vl...@databricks.com>
    Signed-off-by: Wenchen Fan <we...@databricks.com>
---
 .../spark/sql/catalyst/parser/SqlBaseParser.g4     |    4 +
 .../sql/catalyst/parser/AbstractSqlParser.scala    |   16 +-
 .../spark/sql/catalyst/parser/AstBuilder.scala     |    4 +
 .../org/apache/spark/sql/internal/SQLConf.scala    |   12 +
 .../parse-query-correctness-old-behavior.sql.out   | 1150 +++++++++++++++++
 .../parse-query-correctness.sql.out                | 1352 ++++++++++++++++++++
 .../parse-query-correctness-old-behavior.sql       |    2 +
 .../sql-tests/inputs/parse-query-correctness.sql   |  284 ++++
 .../parse-query-correctness-old-behavior.sql.out   |  768 +++++++++++
 .../results/parse-query-correctness.sql.out        |  748 +++++++++++
 10 files changed, 4337 insertions(+), 3 deletions(-)

diff --git a/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 b/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4
index 6cc9ece451c0..a68a99ddb676 100644
--- a/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4
+++ b/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4
@@ -476,6 +476,10 @@ commentSpec
     : COMMENT stringLit
     ;
 
+singleQuery
+    : query EOF
+    ;
+
 query
     : ctes? queryTerm queryOrganization
     ;
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AbstractSqlParser.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AbstractSqlParser.scala
index 1928d4b23349..c17409a68c96 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AbstractSqlParser.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AbstractSqlParser.scala
@@ -24,6 +24,7 @@ import org.apache.spark.sql.catalyst.parser.ParserUtils.withOrigin
 import org.apache.spark.sql.catalyst.plans.logical.{CompoundPlanStatement, LogicalPlan}
 import org.apache.spark.sql.catalyst.trees.Origin
 import org.apache.spark.sql.errors.QueryParsingErrors
+import org.apache.spark.sql.internal.SQLConf
 
 /**
  * Base class for all ANTLR4 [[ParserInterface]] implementations.
@@ -72,9 +73,18 @@ abstract class AbstractSqlParser extends AbstractParser with ParserInterface {
   /** Creates LogicalPlan for a given SQL string of query. */
   override def parseQuery(sqlText: String): LogicalPlan =
     parse(sqlText) { parser =>
-      val ctx = parser.query()
-      withErrorHandling(ctx, Some(sqlText)) {
-        astBuilder.visitQuery(ctx)
+      if (!SQLConf.get.getConf(SQLConf.LEGACY_PARSE_QUERY_WITHOUT_EOF)) {
+        val ctx = parser.singleQuery()
+
+        withErrorHandling(ctx, Some(sqlText)) {
+          astBuilder.visitSingleQuery(ctx)
+        }
+      } else {
+        val ctx = parser.query()
+
+        withErrorHandling(ctx, Some(sqlText)) {
+          astBuilder.visitQuery(ctx)
+        }
       }
     }
 
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala
index 05b44f864369..9f54d3d830a3 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala
@@ -670,6 +670,10 @@ class AstBuilder extends DataTypeAstBuilder
    * ******************************************************************************************** */
   protected def plan(tree: ParserRuleContext): LogicalPlan = typedVisit(tree)
 
+  override def visitSingleQuery(ctx: SingleQueryContext): LogicalPlan = withOrigin(ctx) {
+    visitQuery(ctx.query())
+  }
+
   /**
    * Create a top-level plan with Common Table Expressions.
    */
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 41bee6ddf697..bf150633d13b 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
@@ -5554,6 +5554,18 @@ object SQLConf {
     .booleanConf
     .createWithDefault(true)
 
+  val LEGACY_PARSE_QUERY_WITHOUT_EOF = buildConf("spark.sql.legacy.parseQueryWithoutEof")
+    .internal()
+    .doc(
+      "When set to true, ParserInterface#parseQuery(...) is going to use base `query` grammar " +
+      "term without EOF resulting in some queries (like `SELECT 1 UNION SELECT 2`) to be parsed " +
+      "incorrectly - `UNION` will be treated as an alias, and the rest of SQL input will be " +
+      "thrown away."
+    )
+    .version("4.0.0")
+    .booleanConf
+    .createWithDefault(false)
+
   /**
    * Holds information about keys that have been deprecated.
    *
diff --git a/sql/core/src/test/resources/sql-tests/analyzer-results/parse-query-correctness-old-behavior.sql.out b/sql/core/src/test/resources/sql-tests/analyzer-results/parse-query-correctness-old-behavior.sql.out
new file mode 100644
index 000000000000..e92e49ec5e7f
--- /dev/null
+++ b/sql/core/src/test/resources/sql-tests/analyzer-results/parse-query-correctness-old-behavior.sql.out
@@ -0,0 +1,1150 @@
+-- Automatically generated by SQLQueryTestSuite
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num
+  UNION
+  SELECT 2
+  UNION
+  SELECT 3
+  UNION
+  SELECT 4
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1 AS num
+  UNION
+  SELECT 2
+  UNION
+  SELECT 3
+  UNION
+  SELECT 4, false, true, LocalTempView, UNSUPPORTED, true
+   +- Distinct
+      +- Union false, false
+         :- Distinct
+         :  +- Union false, false
+         :     :- Distinct
+         :     :  +- Union false, false
+         :     :     :- Project [1 AS num#x]
+         :     :     :  +- OneRowRelation
+         :     :     +- Project [2 AS 2#x]
+         :     :        +- OneRowRelation
+         :     +- Project [3 AS 3#x]
+         :        +- OneRowRelation
+         +- Project [4 AS 4#x]
+            +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [num#x]
++- SubqueryAlias v1
+   +- View (`v1`, [num#x])
+      +- Project [cast(num#x as int) AS num#x]
+         +- Distinct
+            +- Union false, false
+               :- Project [1 AS num#x]
+               :  +- OneRowRelation
+               +- Project [2 AS UNION#x]
+                  +- OneRowRelation
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1
+  UNION
+  SELECT 2
+  UNION
+  SELECT 3
+  UNION
+  SELECT 4
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1
+  UNION
+  SELECT 2
+  UNION
+  SELECT 3
+  UNION
+  SELECT 4, false, true, LocalTempView, UNSUPPORTED, true
+   +- Distinct
+      +- Union false, false
+         :- Distinct
+         :  +- Union false, false
+         :     :- Distinct
+         :     :  +- Union false, false
+         :     :     :- Project [1 AS 1#x]
+         :     :     :  +- OneRowRelation
+         :     :     +- Project [2 AS 2#x]
+         :     :        +- OneRowRelation
+         :     +- Project [3 AS 3#x]
+         :        +- OneRowRelation
+         +- Project [4 AS 4#x]
+            +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "INCOMPATIBLE_VIEW_SCHEMA_CHANGE",
+  "sqlState" : "51024",
+  "messageParameters" : {
+    "actualCols" : "[]",
+    "colName" : "1",
+    "expectedNum" : "1",
+    "suggestion" : "CREATE OR REPLACE TEMPORARY VIEW",
+    "viewName" : "`v1`"
+  }
+}
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1, 'a'
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1, 'a'
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd', false, true, LocalTempView, UNSUPPORTED, true
+   +- Distinct
+      +- Union false, false
+         :- Distinct
+         :  +- Union false, false
+         :     :- Distinct
+         :     :  +- Union false, false
+         :     :     :- Project [1 AS 1#x, a AS a#x]
+         :     :     :  +- OneRowRelation
+         :     :     +- Project [2 AS 2#x, b AS b#x]
+         :     :        +- OneRowRelation
+         :     +- Project [3 AS 3#x, c AS c#x]
+         :        +- OneRowRelation
+         +- Project [4 AS 4#x, d AS d#x]
+            +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "INCOMPATIBLE_VIEW_SCHEMA_CHANGE",
+  "sqlState" : "51024",
+  "messageParameters" : {
+    "actualCols" : "[]",
+    "colName" : "a",
+    "expectedNum" : "1",
+    "suggestion" : "CREATE OR REPLACE TEMPORARY VIEW",
+    "viewName" : "`v1`"
+  }
+}
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num, 'a'
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1 AS num, 'a'
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd', false, true, LocalTempView, UNSUPPORTED, true
+   +- Distinct
+      +- Union false, false
+         :- Distinct
+         :  +- Union false, false
+         :     :- Distinct
+         :     :  +- Union false, false
+         :     :     :- Project [1 AS num#x, a AS a#x]
+         :     :     :  +- OneRowRelation
+         :     :     +- Project [2 AS 2#x, b AS b#x]
+         :     :        +- OneRowRelation
+         :     +- Project [3 AS 3#x, c AS c#x]
+         :        +- OneRowRelation
+         +- Project [4 AS 4#x, d AS d#x]
+            +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "INCOMPATIBLE_VIEW_SCHEMA_CHANGE",
+  "sqlState" : "51024",
+  "messageParameters" : {
+    "actualCols" : "[]",
+    "colName" : "a",
+    "expectedNum" : "1",
+    "suggestion" : "CREATE OR REPLACE TEMPORARY VIEW",
+    "viewName" : "`v1`"
+  }
+}
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1, 'a' AS a
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1, 'a' AS a
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd', false, true, LocalTempView, UNSUPPORTED, true
+   +- Distinct
+      +- Union false, false
+         :- Distinct
+         :  +- Union false, false
+         :     :- Distinct
+         :     :  +- Union false, false
+         :     :     :- Project [1 AS 1#x, a AS a#x]
+         :     :     :  +- OneRowRelation
+         :     :     +- Project [2 AS 2#x, b AS b#x]
+         :     :        +- OneRowRelation
+         :     +- Project [3 AS 3#x, c AS c#x]
+         :        +- OneRowRelation
+         +- Project [4 AS 4#x, d AS d#x]
+            +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [1#x, a#x]
++- SubqueryAlias v1
+   +- View (`v1`, [1#x, a#x])
+      +- Project [cast(1#x as int) AS 1#x, cast(a#x as string) AS a#x]
+         +- Distinct
+            +- Union false, false
+               :- Project [1 AS 1#x, a AS a#x]
+               :  +- OneRowRelation
+               +- Project [2 AS 2#x, b AS UNION#x]
+                  +- OneRowRelation
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num, 'a' AS a
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1 AS num, 'a' AS a
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd', false, true, LocalTempView, UNSUPPORTED, true
+   +- Distinct
+      +- Union false, false
+         :- Distinct
+         :  +- Union false, false
+         :     :- Distinct
+         :     :  +- Union false, false
+         :     :     :- Project [1 AS num#x, a AS a#x]
+         :     :     :  +- OneRowRelation
+         :     :     +- Project [2 AS 2#x, b AS b#x]
+         :     :        +- OneRowRelation
+         :     +- Project [3 AS 3#x, c AS c#x]
+         :        +- OneRowRelation
+         +- Project [4 AS 4#x, d AS d#x]
+            +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [num#x, a#x]
++- SubqueryAlias v1
+   +- View (`v1`, [num#x, a#x])
+      +- Project [cast(num#x as int) AS num#x, cast(a#x as string) AS a#x]
+         +- Distinct
+            +- Union false, false
+               :- Project [1 AS num#x, a AS a#x]
+               :  +- OneRowRelation
+               +- Project [2 AS 2#x, b AS UNION#x]
+                  +- OneRowRelation
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num
+  EXCEPT
+  SELECT 2
+  EXCEPT
+  SELECT 1
+  EXCEPT
+  SELECT 2
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1 AS num
+  EXCEPT
+  SELECT 2
+  EXCEPT
+  SELECT 1
+  EXCEPT
+  SELECT 2, false, true, LocalTempView, UNSUPPORTED, true
+   +- Except false
+      :- Except false
+      :  :- Except false
+      :  :  :- Project [1 AS num#x]
+      :  :  :  +- OneRowRelation
+      :  :  +- Project [2 AS 2#x]
+      :  :     +- OneRowRelation
+      :  +- Project [1 AS 1#x]
+      :     +- OneRowRelation
+      +- Project [2 AS 2#x]
+         +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [num#x]
++- SubqueryAlias v1
+   +- View (`v1`, [num#x])
+      +- Project [cast(num#x as int) AS num#x]
+         +- Except false
+            :- Project [1 AS num#x]
+            :  +- OneRowRelation
+            +- Project [2 AS EXCEPT#x]
+               +- OneRowRelation
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1
+  EXCEPT
+  SELECT 2
+  EXCEPT
+  SELECT 1
+  EXCEPT
+  SELECT 2
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1
+  EXCEPT
+  SELECT 2
+  EXCEPT
+  SELECT 1
+  EXCEPT
+  SELECT 2, false, true, LocalTempView, UNSUPPORTED, true
+   +- Except false
+      :- Except false
+      :  :- Except false
+      :  :  :- Project [1 AS 1#x]
+      :  :  :  +- OneRowRelation
+      :  :  +- Project [2 AS 2#x]
+      :  :     +- OneRowRelation
+      :  +- Project [1 AS 1#x]
+      :     +- OneRowRelation
+      +- Project [2 AS 2#x]
+         +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "INCOMPATIBLE_VIEW_SCHEMA_CHANGE",
+  "sqlState" : "51024",
+  "messageParameters" : {
+    "actualCols" : "[]",
+    "colName" : "1",
+    "expectedNum" : "1",
+    "suggestion" : "CREATE OR REPLACE TEMPORARY VIEW",
+    "viewName" : "`v1`"
+  }
+}
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+  EXCEPT
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+  EXCEPT
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b', false, true, LocalTempView, UNSUPPORTED, true
+   +- Except false
+      :- Except false
+      :  :- Except false
+      :  :  :- Project [1 AS 1#x, a AS a#x]
+      :  :  :  +- OneRowRelation
+      :  :  +- Project [2 AS 2#x, b AS b#x]
+      :  :     +- OneRowRelation
+      :  +- Project [1 AS 1#x, a AS a#x]
+      :     +- OneRowRelation
+      +- Project [2 AS 2#x, b AS b#x]
+         +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "INCOMPATIBLE_VIEW_SCHEMA_CHANGE",
+  "sqlState" : "51024",
+  "messageParameters" : {
+    "actualCols" : "[]",
+    "colName" : "a",
+    "expectedNum" : "1",
+    "suggestion" : "CREATE OR REPLACE TEMPORARY VIEW",
+    "viewName" : "`v1`"
+  }
+}
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+  EXCEPT
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1 AS num, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+  EXCEPT
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b', false, true, LocalTempView, UNSUPPORTED, true
+   +- Except false
+      :- Except false
+      :  :- Except false
+      :  :  :- Project [1 AS num#x, a AS a#x]
+      :  :  :  +- OneRowRelation
+      :  :  +- Project [2 AS 2#x, b AS b#x]
+      :  :     +- OneRowRelation
+      :  +- Project [1 AS 1#x, a AS a#x]
+      :     +- OneRowRelation
+      +- Project [2 AS 2#x, b AS b#x]
+         +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "INCOMPATIBLE_VIEW_SCHEMA_CHANGE",
+  "sqlState" : "51024",
+  "messageParameters" : {
+    "actualCols" : "[]",
+    "colName" : "a",
+    "expectedNum" : "1",
+    "suggestion" : "CREATE OR REPLACE TEMPORARY VIEW",
+    "viewName" : "`v1`"
+  }
+}
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1, 'a' AS a
+  EXCEPT
+  SELECT 2, 'b'
+  EXCEPT
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1, 'a' AS a
+  EXCEPT
+  SELECT 2, 'b'
+  EXCEPT
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b', false, true, LocalTempView, UNSUPPORTED, true
+   +- Except false
+      :- Except false
+      :  :- Except false
+      :  :  :- Project [1 AS 1#x, a AS a#x]
+      :  :  :  +- OneRowRelation
+      :  :  +- Project [2 AS 2#x, b AS b#x]
+      :  :     +- OneRowRelation
+      :  +- Project [1 AS 1#x, a AS a#x]
+      :     +- OneRowRelation
+      +- Project [2 AS 2#x, b AS b#x]
+         +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [1#x, a#x]
++- SubqueryAlias v1
+   +- View (`v1`, [1#x, a#x])
+      +- Project [cast(1#x as int) AS 1#x, cast(a#x as string) AS a#x]
+         +- Except false
+            :- Project [1 AS 1#x, a AS a#x]
+            :  +- OneRowRelation
+            +- Project [2 AS 2#x, b AS EXCEPT#x]
+               +- OneRowRelation
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num, 'a' AS a
+  EXCEPT
+  SELECT 2, 'b'
+  EXCEPT
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1 AS num, 'a' AS a
+  EXCEPT
+  SELECT 2, 'b'
+  EXCEPT
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b', false, true, LocalTempView, UNSUPPORTED, true
+   +- Except false
+      :- Except false
+      :  :- Except false
+      :  :  :- Project [1 AS num#x, a AS a#x]
+      :  :  :  +- OneRowRelation
+      :  :  +- Project [2 AS 2#x, b AS b#x]
+      :  :     +- OneRowRelation
+      :  +- Project [1 AS 1#x, a AS a#x]
+      :     +- OneRowRelation
+      +- Project [2 AS 2#x, b AS b#x]
+         +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [num#x, a#x]
++- SubqueryAlias v1
+   +- View (`v1`, [num#x, a#x])
+      +- Project [cast(num#x as int) AS num#x, cast(a#x as string) AS a#x]
+         +- Except false
+            :- Project [1 AS num#x, a AS a#x]
+            :  +- OneRowRelation
+            +- Project [2 AS 2#x, b AS EXCEPT#x]
+               +- OneRowRelation
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num
+  INTERSECT
+  SELECT 1
+  INTERSECT
+  SELECT 2
+  INTERSECT
+  SELECT 2
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1 AS num
+  INTERSECT
+  SELECT 1
+  INTERSECT
+  SELECT 2
+  INTERSECT
+  SELECT 2, false, true, LocalTempView, UNSUPPORTED, true
+   +- Intersect false
+      :- Intersect false
+      :  :- Intersect false
+      :  :  :- Project [1 AS num#x]
+      :  :  :  +- OneRowRelation
+      :  :  +- Project [1 AS 1#x]
+      :  :     +- OneRowRelation
+      :  +- Project [2 AS 2#x]
+      :     +- OneRowRelation
+      +- Project [2 AS 2#x]
+         +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [num#x]
++- SubqueryAlias v1
+   +- View (`v1`, [num#x])
+      +- Project [cast(num#x as int) AS num#x]
+         +- Intersect false
+            :- Project [1 AS num#x]
+            :  +- OneRowRelation
+            +- Project [1 AS INTERSECT#x]
+               +- OneRowRelation
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1
+  INTERSECT
+  SELECT 1
+  INTERSECT
+  SELECT 2
+  INTERSECT
+  SELECT 2
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1
+  INTERSECT
+  SELECT 1
+  INTERSECT
+  SELECT 2
+  INTERSECT
+  SELECT 2, false, true, LocalTempView, UNSUPPORTED, true
+   +- Intersect false
+      :- Intersect false
+      :  :- Intersect false
+      :  :  :- Project [1 AS 1#x]
+      :  :  :  +- OneRowRelation
+      :  :  +- Project [1 AS 1#x]
+      :  :     +- OneRowRelation
+      :  +- Project [2 AS 2#x]
+      :     +- OneRowRelation
+      +- Project [2 AS 2#x]
+         +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "INCOMPATIBLE_VIEW_SCHEMA_CHANGE",
+  "sqlState" : "51024",
+  "messageParameters" : {
+    "actualCols" : "[]",
+    "colName" : "1",
+    "expectedNum" : "1",
+    "suggestion" : "CREATE OR REPLACE TEMPORARY VIEW",
+    "viewName" : "`v1`"
+  }
+}
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 2, 'b'
+  INTERSECT
+  SELECT 2, 'b'
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1, 'a'
+  INTERSECT
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 2, 'b'
+  INTERSECT
+  SELECT 2, 'b', false, true, LocalTempView, UNSUPPORTED, true
+   +- Intersect false
+      :- Intersect false
+      :  :- Intersect false
+      :  :  :- Project [1 AS 1#x, a AS a#x]
+      :  :  :  +- OneRowRelation
+      :  :  +- Project [1 AS 1#x, a AS a#x]
+      :  :     +- OneRowRelation
+      :  +- Project [2 AS 2#x, b AS b#x]
+      :     +- OneRowRelation
+      +- Project [2 AS 2#x, b AS b#x]
+         +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "INCOMPATIBLE_VIEW_SCHEMA_CHANGE",
+  "sqlState" : "51024",
+  "messageParameters" : {
+    "actualCols" : "[]",
+    "colName" : "a",
+    "expectedNum" : "1",
+    "suggestion" : "CREATE OR REPLACE TEMPORARY VIEW",
+    "viewName" : "`v1`"
+  }
+}
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num, 'a'
+  INTERSECT
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 2, 'b'
+  INTERSECT
+  SELECT 2, 'b'
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1 AS num, 'a'
+  INTERSECT
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 2, 'b'
+  INTERSECT
+  SELECT 2, 'b', false, true, LocalTempView, UNSUPPORTED, true
+   +- Intersect false
+      :- Intersect false
+      :  :- Intersect false
+      :  :  :- Project [1 AS num#x, a AS a#x]
+      :  :  :  +- OneRowRelation
+      :  :  +- Project [1 AS 1#x, a AS a#x]
+      :  :     +- OneRowRelation
+      :  +- Project [2 AS 2#x, b AS b#x]
+      :     +- OneRowRelation
+      +- Project [2 AS 2#x, b AS b#x]
+         +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "INCOMPATIBLE_VIEW_SCHEMA_CHANGE",
+  "sqlState" : "51024",
+  "messageParameters" : {
+    "actualCols" : "[]",
+    "colName" : "a",
+    "expectedNum" : "1",
+    "suggestion" : "CREATE OR REPLACE TEMPORARY VIEW",
+    "viewName" : "`v1`"
+  }
+}
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1, 'a' AS a
+  INTERSECT
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 2, 'b'
+  INTERSECT
+  SELECT 2, 'b'
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1, 'a' AS a
+  INTERSECT
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 2, 'b'
+  INTERSECT
+  SELECT 2, 'b', false, true, LocalTempView, UNSUPPORTED, true
+   +- Intersect false
+      :- Intersect false
+      :  :- Intersect false
+      :  :  :- Project [1 AS 1#x, a AS a#x]
+      :  :  :  +- OneRowRelation
+      :  :  +- Project [1 AS 1#x, a AS a#x]
+      :  :     +- OneRowRelation
+      :  +- Project [2 AS 2#x, b AS b#x]
+      :     +- OneRowRelation
+      +- Project [2 AS 2#x, b AS b#x]
+         +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [1#x, a#x]
++- SubqueryAlias v1
+   +- View (`v1`, [1#x, a#x])
+      +- Project [cast(1#x as int) AS 1#x, cast(a#x as string) AS a#x]
+         +- Intersect false
+            :- Project [1 AS 1#x, a AS a#x]
+            :  +- OneRowRelation
+            +- Project [1 AS 1#x, a AS INTERSECT#x]
+               +- OneRowRelation
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num, 'a' AS a
+  INTERSECT
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 2, 'b'
+  INTERSECT
+  SELECT 2, 'b'
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1 AS num, 'a' AS a
+  INTERSECT
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 2, 'b'
+  INTERSECT
+  SELECT 2, 'b', false, true, LocalTempView, UNSUPPORTED, true
+   +- Intersect false
+      :- Intersect false
+      :  :- Intersect false
+      :  :  :- Project [1 AS num#x, a AS a#x]
+      :  :  :  +- OneRowRelation
+      :  :  +- Project [1 AS 1#x, a AS a#x]
+      :  :     +- OneRowRelation
+      :  +- Project [2 AS 2#x, b AS b#x]
+      :     +- OneRowRelation
+      +- Project [2 AS 2#x, b AS b#x]
+         +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [num#x, a#x]
++- SubqueryAlias v1
+   +- View (`v1`, [num#x, a#x])
+      +- Project [cast(num#x as int) AS num#x, cast(a#x as string) AS a#x]
+         +- Intersect false
+            :- Project [1 AS num#x, a AS a#x]
+            :  +- OneRowRelation
+            +- Project [1 AS 1#x, a AS INTERSECT#x]
+               +- OneRowRelation
+
+
+-- !query
+CREATE OR REPLACE VIEW v1 WITH SCHEMA EVOLUTION AS
+  SELECT 1, 'a'
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+-- !query analysis
+CreateViewCommand `spark_catalog`.`default`.`v1`, SELECT 1, 'a'
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd', false, true, PersistedView, EVOLUTION, true
+   +- Distinct
+      +- Union false, false
+         :- Distinct
+         :  +- Union false, false
+         :     :- Distinct
+         :     :  +- Union false, false
+         :     :     :- Project [1 AS 1#x, a AS a#x]
+         :     :     :  +- OneRowRelation
+         :     :     +- Project [2 AS 2#x, b AS b#x]
+         :     :        +- OneRowRelation
+         :     +- Project [3 AS 3#x, c AS c#x]
+         :        +- OneRowRelation
+         +- Project [4 AS 4#x, d AS d#x]
+            +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [num#x, a#x]
++- SubqueryAlias v1
+   +- View (`v1`, [num#x, a#x])
+      +- Project [cast(num#x as int) AS num#x, cast(a#x as string) AS a#x]
+         +- Intersect false
+            :- Project [1 AS num#x, a AS a#x]
+            :  +- OneRowRelation
+            +- Project [1 AS 1#x, a AS INTERSECT#x]
+               +- OneRowRelation
+
+
+-- !query
+CREATE OR REPLACE VIEW v1 WITH SCHEMA EVOLUTION AS
+  SELECT 1 AS num, 'a'
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+-- !query analysis
+CreateViewCommand `spark_catalog`.`default`.`v1`, SELECT 1 AS num, 'a'
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd', false, true, PersistedView, EVOLUTION, true
+   +- Distinct
+      +- Union false, false
+         :- Distinct
+         :  +- Union false, false
+         :     :- Distinct
+         :     :  +- Union false, false
+         :     :     :- Project [1 AS num#x, a AS a#x]
+         :     :     :  +- OneRowRelation
+         :     :     +- Project [2 AS 2#x, b AS b#x]
+         :     :        +- OneRowRelation
+         :     +- Project [3 AS 3#x, c AS c#x]
+         :        +- OneRowRelation
+         +- Project [4 AS 4#x, d AS d#x]
+            +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [num#x, a#x]
++- SubqueryAlias v1
+   +- View (`v1`, [num#x, a#x])
+      +- Project [cast(num#x as int) AS num#x, cast(a#x as string) AS a#x]
+         +- Intersect false
+            :- Project [1 AS num#x, a AS a#x]
+            :  +- OneRowRelation
+            +- Project [1 AS 1#x, a AS INTERSECT#x]
+               +- OneRowRelation
+
+
+-- !query
+CREATE OR REPLACE VIEW v1 WITH SCHEMA EVOLUTION AS
+  SELECT 1 AS num, 'a' AS a
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+-- !query analysis
+CreateViewCommand `spark_catalog`.`default`.`v1`, SELECT 1 AS num, 'a' AS a
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd', false, true, PersistedView, EVOLUTION, true
+   +- Distinct
+      +- Union false, false
+         :- Distinct
+         :  +- Union false, false
+         :     :- Distinct
+         :     :  +- Union false, false
+         :     :     :- Project [1 AS num#x, a AS a#x]
+         :     :     :  +- OneRowRelation
+         :     :     +- Project [2 AS 2#x, b AS b#x]
+         :     :        +- OneRowRelation
+         :     +- Project [3 AS 3#x, c AS c#x]
+         :        +- OneRowRelation
+         +- Project [4 AS 4#x, d AS d#x]
+            +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [num#x, a#x]
++- SubqueryAlias v1
+   +- View (`v1`, [num#x, a#x])
+      +- Project [cast(num#x as int) AS num#x, cast(a#x as string) AS a#x]
+         +- Intersect false
+            :- Project [1 AS num#x, a AS a#x]
+            :  +- OneRowRelation
+            +- Project [1 AS 1#x, a AS INTERSECT#x]
+               +- OneRowRelation
+
+
+-- !query
+DROP VIEW v1
+-- !query analysis
+DropTempViewCommand v1
+
+
+-- !query
+DECLARE v1 INT
+-- !query analysis
+CreateVariable defaultvalueexpression(null, null), false
++- ResolvedIdentifier org.apache.spark.sql.catalyst.analysis.FakeSystemCatalog$@xxxxxxxx, session.v1
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 UNION SELECT 2 UNION SELECT 3' INTO v1
+-- !query analysis
+SetVariable [variablereference(system.session.v1=CAST(NULL AS INT))]
++- Project [1 AS UNION#x]
+   +- OneRowRelation
+
+
+-- !query
+SELECT v1
+-- !query analysis
+Project [variablereference(system.session.v1=1) AS v1#x]
++- OneRowRelation
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 UNION SELECT 1 UNION SELECT 1' INTO v1
+-- !query analysis
+SetVariable [variablereference(system.session.v1=1)]
++- Project [1 AS UNION#x]
+   +- OneRowRelation
+
+
+-- !query
+SELECT v1
+-- !query analysis
+Project [variablereference(system.session.v1=1) AS v1#x]
++- OneRowRelation
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 EXCEPT SELECT 2 EXCEPT SELECT 3' INTO v1
+-- !query analysis
+SetVariable [variablereference(system.session.v1=1)]
++- Project [1 AS EXCEPT#x]
+   +- OneRowRelation
+
+
+-- !query
+SELECT v1
+-- !query analysis
+Project [variablereference(system.session.v1=1) AS v1#x]
++- OneRowRelation
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 EXCEPT SELECT 1 EXCEPT SELECT 1' INTO v1
+-- !query analysis
+SetVariable [variablereference(system.session.v1=1)]
++- Project [1 AS EXCEPT#x]
+   +- OneRowRelation
+
+
+-- !query
+SELECT v1
+-- !query analysis
+Project [variablereference(system.session.v1=1) AS v1#x]
++- OneRowRelation
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 INTERSECT SELECT 2 INTERSECT SELECT 3' INTO v1
+-- !query analysis
+SetVariable [variablereference(system.session.v1=1)]
++- Project [1 AS INTERSECT#x]
+   +- OneRowRelation
+
+
+-- !query
+SELECT v1
+-- !query analysis
+Project [variablereference(system.session.v1=1) AS v1#x]
++- OneRowRelation
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 INTERSECT SELECT 1 INTERSECT SELECT 1' INTO v1
+-- !query analysis
+SetVariable [variablereference(system.session.v1=1)]
++- Project [1 AS INTERSECT#x]
+   +- OneRowRelation
+
+
+-- !query
+SELECT v1
+-- !query analysis
+Project [variablereference(system.session.v1=1) AS v1#x]
++- OneRowRelation
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 JOIN SELECT 2' INTO v1
+-- !query analysis
+SetVariable [variablereference(system.session.v1=1)]
++- Project [1 AS JOIN#x]
+   +- OneRowRelation
+
+
+-- !query
+SELECT v1
+-- !query analysis
+Project [variablereference(system.session.v1=1) AS v1#x]
++- OneRowRelation
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 VALUES (1)' INTO v1
+-- !query analysis
+SetVariable [variablereference(system.session.v1=1)]
++- Project [1 AS VALUES#x]
+   +- OneRowRelation
+
+
+-- !query
+SELECT v1
+-- !query analysis
+Project [variablereference(system.session.v1=1) AS v1#x]
++- OneRowRelation
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 alias garbage garbage garbage' INTO v1
+-- !query analysis
+SetVariable [variablereference(system.session.v1=1)]
++- Project [1 AS alias#x]
+   +- OneRowRelation
+
+
+-- !query
+SELECT v1
+-- !query analysis
+Project [variablereference(system.session.v1=1) AS v1#x]
++- OneRowRelation
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 WITH abc' INTO v1
+-- !query analysis
+SetVariable [variablereference(system.session.v1=1)]
++- Project [1 AS WITH#x]
+   +- OneRowRelation
+
+
+-- !query
+SELECT v1
+-- !query analysis
+Project [variablereference(system.session.v1=1) AS v1#x]
++- OneRowRelation
+
+
+-- !query
+DROP TEMPORARY VARIABLE v1
+-- !query analysis
+DropVariable false
++- ResolvedIdentifier org.apache.spark.sql.catalyst.analysis.FakeSystemCatalog$@xxxxxxxx, session.v1
diff --git a/sql/core/src/test/resources/sql-tests/analyzer-results/parse-query-correctness.sql.out b/sql/core/src/test/resources/sql-tests/analyzer-results/parse-query-correctness.sql.out
new file mode 100644
index 000000000000..e4b6f186562f
--- /dev/null
+++ b/sql/core/src/test/resources/sql-tests/analyzer-results/parse-query-correctness.sql.out
@@ -0,0 +1,1352 @@
+-- Automatically generated by SQLQueryTestSuite
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num
+  UNION
+  SELECT 2
+  UNION
+  SELECT 3
+  UNION
+  SELECT 4
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1 AS num
+  UNION
+  SELECT 2
+  UNION
+  SELECT 3
+  UNION
+  SELECT 4, false, true, LocalTempView, UNSUPPORTED, true
+   +- Distinct
+      +- Union false, false
+         :- Distinct
+         :  +- Union false, false
+         :     :- Distinct
+         :     :  +- Union false, false
+         :     :     :- Project [1 AS num#x]
+         :     :     :  +- OneRowRelation
+         :     :     +- Project [2 AS 2#x]
+         :     :        +- OneRowRelation
+         :     +- Project [3 AS 3#x]
+         :        +- OneRowRelation
+         +- Project [4 AS 4#x]
+            +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [num#x]
++- SubqueryAlias v1
+   +- View (`v1`, [num#x])
+      +- Project [cast(num#x as int) AS num#x]
+         +- Distinct
+            +- Union false, false
+               :- Distinct
+               :  +- Union false, false
+               :     :- Distinct
+               :     :  +- Union false, false
+               :     :     :- Project [1 AS num#x]
+               :     :     :  +- OneRowRelation
+               :     :     +- Project [2 AS 2#x]
+               :     :        +- OneRowRelation
+               :     +- Project [3 AS 3#x]
+               :        +- OneRowRelation
+               +- Project [4 AS 4#x]
+                  +- OneRowRelation
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1
+  UNION
+  SELECT 2
+  UNION
+  SELECT 3
+  UNION
+  SELECT 4
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1
+  UNION
+  SELECT 2
+  UNION
+  SELECT 3
+  UNION
+  SELECT 4, false, true, LocalTempView, UNSUPPORTED, true
+   +- Distinct
+      +- Union false, false
+         :- Distinct
+         :  +- Union false, false
+         :     :- Distinct
+         :     :  +- Union false, false
+         :     :     :- Project [1 AS 1#x]
+         :     :     :  +- OneRowRelation
+         :     :     +- Project [2 AS 2#x]
+         :     :        +- OneRowRelation
+         :     +- Project [3 AS 3#x]
+         :        +- OneRowRelation
+         +- Project [4 AS 4#x]
+            +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [1#x]
++- SubqueryAlias v1
+   +- View (`v1`, [1#x])
+      +- Project [cast(1#x as int) AS 1#x]
+         +- Distinct
+            +- Union false, false
+               :- Distinct
+               :  +- Union false, false
+               :     :- Distinct
+               :     :  +- Union false, false
+               :     :     :- Project [1 AS 1#x]
+               :     :     :  +- OneRowRelation
+               :     :     +- Project [2 AS 2#x]
+               :     :        +- OneRowRelation
+               :     +- Project [3 AS 3#x]
+               :        +- OneRowRelation
+               +- Project [4 AS 4#x]
+                  +- OneRowRelation
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1, 'a'
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1, 'a'
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd', false, true, LocalTempView, UNSUPPORTED, true
+   +- Distinct
+      +- Union false, false
+         :- Distinct
+         :  +- Union false, false
+         :     :- Distinct
+         :     :  +- Union false, false
+         :     :     :- Project [1 AS 1#x, a AS a#x]
+         :     :     :  +- OneRowRelation
+         :     :     +- Project [2 AS 2#x, b AS b#x]
+         :     :        +- OneRowRelation
+         :     +- Project [3 AS 3#x, c AS c#x]
+         :        +- OneRowRelation
+         +- Project [4 AS 4#x, d AS d#x]
+            +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [1#x, a#x]
++- SubqueryAlias v1
+   +- View (`v1`, [1#x, a#x])
+      +- Project [cast(1#x as int) AS 1#x, cast(a#x as string) AS a#x]
+         +- Distinct
+            +- Union false, false
+               :- Distinct
+               :  +- Union false, false
+               :     :- Distinct
+               :     :  +- Union false, false
+               :     :     :- Project [1 AS 1#x, a AS a#x]
+               :     :     :  +- OneRowRelation
+               :     :     +- Project [2 AS 2#x, b AS b#x]
+               :     :        +- OneRowRelation
+               :     +- Project [3 AS 3#x, c AS c#x]
+               :        +- OneRowRelation
+               +- Project [4 AS 4#x, d AS d#x]
+                  +- OneRowRelation
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num, 'a'
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1 AS num, 'a'
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd', false, true, LocalTempView, UNSUPPORTED, true
+   +- Distinct
+      +- Union false, false
+         :- Distinct
+         :  +- Union false, false
+         :     :- Distinct
+         :     :  +- Union false, false
+         :     :     :- Project [1 AS num#x, a AS a#x]
+         :     :     :  +- OneRowRelation
+         :     :     +- Project [2 AS 2#x, b AS b#x]
+         :     :        +- OneRowRelation
+         :     +- Project [3 AS 3#x, c AS c#x]
+         :        +- OneRowRelation
+         +- Project [4 AS 4#x, d AS d#x]
+            +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [num#x, a#x]
++- SubqueryAlias v1
+   +- View (`v1`, [num#x, a#x])
+      +- Project [cast(num#x as int) AS num#x, cast(a#x as string) AS a#x]
+         +- Distinct
+            +- Union false, false
+               :- Distinct
+               :  +- Union false, false
+               :     :- Distinct
+               :     :  +- Union false, false
+               :     :     :- Project [1 AS num#x, a AS a#x]
+               :     :     :  +- OneRowRelation
+               :     :     +- Project [2 AS 2#x, b AS b#x]
+               :     :        +- OneRowRelation
+               :     +- Project [3 AS 3#x, c AS c#x]
+               :        +- OneRowRelation
+               +- Project [4 AS 4#x, d AS d#x]
+                  +- OneRowRelation
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1, 'a' AS a
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1, 'a' AS a
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd', false, true, LocalTempView, UNSUPPORTED, true
+   +- Distinct
+      +- Union false, false
+         :- Distinct
+         :  +- Union false, false
+         :     :- Distinct
+         :     :  +- Union false, false
+         :     :     :- Project [1 AS 1#x, a AS a#x]
+         :     :     :  +- OneRowRelation
+         :     :     +- Project [2 AS 2#x, b AS b#x]
+         :     :        +- OneRowRelation
+         :     +- Project [3 AS 3#x, c AS c#x]
+         :        +- OneRowRelation
+         +- Project [4 AS 4#x, d AS d#x]
+            +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [1#x, a#x]
++- SubqueryAlias v1
+   +- View (`v1`, [1#x, a#x])
+      +- Project [cast(1#x as int) AS 1#x, cast(a#x as string) AS a#x]
+         +- Distinct
+            +- Union false, false
+               :- Distinct
+               :  +- Union false, false
+               :     :- Distinct
+               :     :  +- Union false, false
+               :     :     :- Project [1 AS 1#x, a AS a#x]
+               :     :     :  +- OneRowRelation
+               :     :     +- Project [2 AS 2#x, b AS b#x]
+               :     :        +- OneRowRelation
+               :     +- Project [3 AS 3#x, c AS c#x]
+               :        +- OneRowRelation
+               +- Project [4 AS 4#x, d AS d#x]
+                  +- OneRowRelation
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num, 'a' AS a
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1 AS num, 'a' AS a
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd', false, true, LocalTempView, UNSUPPORTED, true
+   +- Distinct
+      +- Union false, false
+         :- Distinct
+         :  +- Union false, false
+         :     :- Distinct
+         :     :  +- Union false, false
+         :     :     :- Project [1 AS num#x, a AS a#x]
+         :     :     :  +- OneRowRelation
+         :     :     +- Project [2 AS 2#x, b AS b#x]
+         :     :        +- OneRowRelation
+         :     +- Project [3 AS 3#x, c AS c#x]
+         :        +- OneRowRelation
+         +- Project [4 AS 4#x, d AS d#x]
+            +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [num#x, a#x]
++- SubqueryAlias v1
+   +- View (`v1`, [num#x, a#x])
+      +- Project [cast(num#x as int) AS num#x, cast(a#x as string) AS a#x]
+         +- Distinct
+            +- Union false, false
+               :- Distinct
+               :  +- Union false, false
+               :     :- Distinct
+               :     :  +- Union false, false
+               :     :     :- Project [1 AS num#x, a AS a#x]
+               :     :     :  +- OneRowRelation
+               :     :     +- Project [2 AS 2#x, b AS b#x]
+               :     :        +- OneRowRelation
+               :     +- Project [3 AS 3#x, c AS c#x]
+               :        +- OneRowRelation
+               +- Project [4 AS 4#x, d AS d#x]
+                  +- OneRowRelation
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num
+  EXCEPT
+  SELECT 2
+  EXCEPT
+  SELECT 1
+  EXCEPT
+  SELECT 2
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1 AS num
+  EXCEPT
+  SELECT 2
+  EXCEPT
+  SELECT 1
+  EXCEPT
+  SELECT 2, false, true, LocalTempView, UNSUPPORTED, true
+   +- Except false
+      :- Except false
+      :  :- Except false
+      :  :  :- Project [1 AS num#x]
+      :  :  :  +- OneRowRelation
+      :  :  +- Project [2 AS 2#x]
+      :  :     +- OneRowRelation
+      :  +- Project [1 AS 1#x]
+      :     +- OneRowRelation
+      +- Project [2 AS 2#x]
+         +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [num#x]
++- SubqueryAlias v1
+   +- View (`v1`, [num#x])
+      +- Project [cast(num#x as int) AS num#x]
+         +- Except false
+            :- Except false
+            :  :- Except false
+            :  :  :- Project [1 AS num#x]
+            :  :  :  +- OneRowRelation
+            :  :  +- Project [2 AS 2#x]
+            :  :     +- OneRowRelation
+            :  +- Project [1 AS 1#x]
+            :     +- OneRowRelation
+            +- Project [2 AS 2#x]
+               +- OneRowRelation
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1
+  EXCEPT
+  SELECT 2
+  EXCEPT
+  SELECT 1
+  EXCEPT
+  SELECT 2
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1
+  EXCEPT
+  SELECT 2
+  EXCEPT
+  SELECT 1
+  EXCEPT
+  SELECT 2, false, true, LocalTempView, UNSUPPORTED, true
+   +- Except false
+      :- Except false
+      :  :- Except false
+      :  :  :- Project [1 AS 1#x]
+      :  :  :  +- OneRowRelation
+      :  :  +- Project [2 AS 2#x]
+      :  :     +- OneRowRelation
+      :  +- Project [1 AS 1#x]
+      :     +- OneRowRelation
+      +- Project [2 AS 2#x]
+         +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [1#x]
++- SubqueryAlias v1
+   +- View (`v1`, [1#x])
+      +- Project [cast(1#x as int) AS 1#x]
+         +- Except false
+            :- Except false
+            :  :- Except false
+            :  :  :- Project [1 AS 1#x]
+            :  :  :  +- OneRowRelation
+            :  :  +- Project [2 AS 2#x]
+            :  :     +- OneRowRelation
+            :  +- Project [1 AS 1#x]
+            :     +- OneRowRelation
+            +- Project [2 AS 2#x]
+               +- OneRowRelation
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+  EXCEPT
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+  EXCEPT
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b', false, true, LocalTempView, UNSUPPORTED, true
+   +- Except false
+      :- Except false
+      :  :- Except false
+      :  :  :- Project [1 AS 1#x, a AS a#x]
+      :  :  :  +- OneRowRelation
+      :  :  +- Project [2 AS 2#x, b AS b#x]
+      :  :     +- OneRowRelation
+      :  +- Project [1 AS 1#x, a AS a#x]
+      :     +- OneRowRelation
+      +- Project [2 AS 2#x, b AS b#x]
+         +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [1#x, a#x]
++- SubqueryAlias v1
+   +- View (`v1`, [1#x, a#x])
+      +- Project [cast(1#x as int) AS 1#x, cast(a#x as string) AS a#x]
+         +- Except false
+            :- Except false
+            :  :- Except false
+            :  :  :- Project [1 AS 1#x, a AS a#x]
+            :  :  :  +- OneRowRelation
+            :  :  +- Project [2 AS 2#x, b AS b#x]
+            :  :     +- OneRowRelation
+            :  +- Project [1 AS 1#x, a AS a#x]
+            :     +- OneRowRelation
+            +- Project [2 AS 2#x, b AS b#x]
+               +- OneRowRelation
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+  EXCEPT
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1 AS num, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+  EXCEPT
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b', false, true, LocalTempView, UNSUPPORTED, true
+   +- Except false
+      :- Except false
+      :  :- Except false
+      :  :  :- Project [1 AS num#x, a AS a#x]
+      :  :  :  +- OneRowRelation
+      :  :  +- Project [2 AS 2#x, b AS b#x]
+      :  :     +- OneRowRelation
+      :  +- Project [1 AS 1#x, a AS a#x]
+      :     +- OneRowRelation
+      +- Project [2 AS 2#x, b AS b#x]
+         +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [num#x, a#x]
++- SubqueryAlias v1
+   +- View (`v1`, [num#x, a#x])
+      +- Project [cast(num#x as int) AS num#x, cast(a#x as string) AS a#x]
+         +- Except false
+            :- Except false
+            :  :- Except false
+            :  :  :- Project [1 AS num#x, a AS a#x]
+            :  :  :  +- OneRowRelation
+            :  :  +- Project [2 AS 2#x, b AS b#x]
+            :  :     +- OneRowRelation
+            :  +- Project [1 AS 1#x, a AS a#x]
+            :     +- OneRowRelation
+            +- Project [2 AS 2#x, b AS b#x]
+               +- OneRowRelation
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1, 'a' AS a
+  EXCEPT
+  SELECT 2, 'b'
+  EXCEPT
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1, 'a' AS a
+  EXCEPT
+  SELECT 2, 'b'
+  EXCEPT
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b', false, true, LocalTempView, UNSUPPORTED, true
+   +- Except false
+      :- Except false
+      :  :- Except false
+      :  :  :- Project [1 AS 1#x, a AS a#x]
+      :  :  :  +- OneRowRelation
+      :  :  +- Project [2 AS 2#x, b AS b#x]
+      :  :     +- OneRowRelation
+      :  +- Project [1 AS 1#x, a AS a#x]
+      :     +- OneRowRelation
+      +- Project [2 AS 2#x, b AS b#x]
+         +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [1#x, a#x]
++- SubqueryAlias v1
+   +- View (`v1`, [1#x, a#x])
+      +- Project [cast(1#x as int) AS 1#x, cast(a#x as string) AS a#x]
+         +- Except false
+            :- Except false
+            :  :- Except false
+            :  :  :- Project [1 AS 1#x, a AS a#x]
+            :  :  :  +- OneRowRelation
+            :  :  +- Project [2 AS 2#x, b AS b#x]
+            :  :     +- OneRowRelation
+            :  +- Project [1 AS 1#x, a AS a#x]
+            :     +- OneRowRelation
+            +- Project [2 AS 2#x, b AS b#x]
+               +- OneRowRelation
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num, 'a' AS a
+  EXCEPT
+  SELECT 2, 'b'
+  EXCEPT
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1 AS num, 'a' AS a
+  EXCEPT
+  SELECT 2, 'b'
+  EXCEPT
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b', false, true, LocalTempView, UNSUPPORTED, true
+   +- Except false
+      :- Except false
+      :  :- Except false
+      :  :  :- Project [1 AS num#x, a AS a#x]
+      :  :  :  +- OneRowRelation
+      :  :  +- Project [2 AS 2#x, b AS b#x]
+      :  :     +- OneRowRelation
+      :  +- Project [1 AS 1#x, a AS a#x]
+      :     +- OneRowRelation
+      +- Project [2 AS 2#x, b AS b#x]
+         +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [num#x, a#x]
++- SubqueryAlias v1
+   +- View (`v1`, [num#x, a#x])
+      +- Project [cast(num#x as int) AS num#x, cast(a#x as string) AS a#x]
+         +- Except false
+            :- Except false
+            :  :- Except false
+            :  :  :- Project [1 AS num#x, a AS a#x]
+            :  :  :  +- OneRowRelation
+            :  :  +- Project [2 AS 2#x, b AS b#x]
+            :  :     +- OneRowRelation
+            :  +- Project [1 AS 1#x, a AS a#x]
+            :     +- OneRowRelation
+            +- Project [2 AS 2#x, b AS b#x]
+               +- OneRowRelation
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num
+  INTERSECT
+  SELECT 1
+  INTERSECT
+  SELECT 2
+  INTERSECT
+  SELECT 2
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1 AS num
+  INTERSECT
+  SELECT 1
+  INTERSECT
+  SELECT 2
+  INTERSECT
+  SELECT 2, false, true, LocalTempView, UNSUPPORTED, true
+   +- Intersect false
+      :- Intersect false
+      :  :- Intersect false
+      :  :  :- Project [1 AS num#x]
+      :  :  :  +- OneRowRelation
+      :  :  +- Project [1 AS 1#x]
+      :  :     +- OneRowRelation
+      :  +- Project [2 AS 2#x]
+      :     +- OneRowRelation
+      +- Project [2 AS 2#x]
+         +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [num#x]
++- SubqueryAlias v1
+   +- View (`v1`, [num#x])
+      +- Project [cast(num#x as int) AS num#x]
+         +- Intersect false
+            :- Intersect false
+            :  :- Intersect false
+            :  :  :- Project [1 AS num#x]
+            :  :  :  +- OneRowRelation
+            :  :  +- Project [1 AS 1#x]
+            :  :     +- OneRowRelation
+            :  +- Project [2 AS 2#x]
+            :     +- OneRowRelation
+            +- Project [2 AS 2#x]
+               +- OneRowRelation
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1
+  INTERSECT
+  SELECT 1
+  INTERSECT
+  SELECT 2
+  INTERSECT
+  SELECT 2
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1
+  INTERSECT
+  SELECT 1
+  INTERSECT
+  SELECT 2
+  INTERSECT
+  SELECT 2, false, true, LocalTempView, UNSUPPORTED, true
+   +- Intersect false
+      :- Intersect false
+      :  :- Intersect false
+      :  :  :- Project [1 AS 1#x]
+      :  :  :  +- OneRowRelation
+      :  :  +- Project [1 AS 1#x]
+      :  :     +- OneRowRelation
+      :  +- Project [2 AS 2#x]
+      :     +- OneRowRelation
+      +- Project [2 AS 2#x]
+         +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [1#x]
++- SubqueryAlias v1
+   +- View (`v1`, [1#x])
+      +- Project [cast(1#x as int) AS 1#x]
+         +- Intersect false
+            :- Intersect false
+            :  :- Intersect false
+            :  :  :- Project [1 AS 1#x]
+            :  :  :  +- OneRowRelation
+            :  :  +- Project [1 AS 1#x]
+            :  :     +- OneRowRelation
+            :  +- Project [2 AS 2#x]
+            :     +- OneRowRelation
+            +- Project [2 AS 2#x]
+               +- OneRowRelation
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 2, 'b'
+  INTERSECT
+  SELECT 2, 'b'
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1, 'a'
+  INTERSECT
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 2, 'b'
+  INTERSECT
+  SELECT 2, 'b', false, true, LocalTempView, UNSUPPORTED, true
+   +- Intersect false
+      :- Intersect false
+      :  :- Intersect false
+      :  :  :- Project [1 AS 1#x, a AS a#x]
+      :  :  :  +- OneRowRelation
+      :  :  +- Project [1 AS 1#x, a AS a#x]
+      :  :     +- OneRowRelation
+      :  +- Project [2 AS 2#x, b AS b#x]
+      :     +- OneRowRelation
+      +- Project [2 AS 2#x, b AS b#x]
+         +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [1#x, a#x]
++- SubqueryAlias v1
+   +- View (`v1`, [1#x, a#x])
+      +- Project [cast(1#x as int) AS 1#x, cast(a#x as string) AS a#x]
+         +- Intersect false
+            :- Intersect false
+            :  :- Intersect false
+            :  :  :- Project [1 AS 1#x, a AS a#x]
+            :  :  :  +- OneRowRelation
+            :  :  +- Project [1 AS 1#x, a AS a#x]
+            :  :     +- OneRowRelation
+            :  +- Project [2 AS 2#x, b AS b#x]
+            :     +- OneRowRelation
+            +- Project [2 AS 2#x, b AS b#x]
+               +- OneRowRelation
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num, 'a'
+  INTERSECT
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 2, 'b'
+  INTERSECT
+  SELECT 2, 'b'
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1 AS num, 'a'
+  INTERSECT
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 2, 'b'
+  INTERSECT
+  SELECT 2, 'b', false, true, LocalTempView, UNSUPPORTED, true
+   +- Intersect false
+      :- Intersect false
+      :  :- Intersect false
+      :  :  :- Project [1 AS num#x, a AS a#x]
+      :  :  :  +- OneRowRelation
+      :  :  +- Project [1 AS 1#x, a AS a#x]
+      :  :     +- OneRowRelation
+      :  +- Project [2 AS 2#x, b AS b#x]
+      :     +- OneRowRelation
+      +- Project [2 AS 2#x, b AS b#x]
+         +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [num#x, a#x]
++- SubqueryAlias v1
+   +- View (`v1`, [num#x, a#x])
+      +- Project [cast(num#x as int) AS num#x, cast(a#x as string) AS a#x]
+         +- Intersect false
+            :- Intersect false
+            :  :- Intersect false
+            :  :  :- Project [1 AS num#x, a AS a#x]
+            :  :  :  +- OneRowRelation
+            :  :  +- Project [1 AS 1#x, a AS a#x]
+            :  :     +- OneRowRelation
+            :  +- Project [2 AS 2#x, b AS b#x]
+            :     +- OneRowRelation
+            +- Project [2 AS 2#x, b AS b#x]
+               +- OneRowRelation
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1, 'a' AS a
+  INTERSECT
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 2, 'b'
+  INTERSECT
+  SELECT 2, 'b'
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1, 'a' AS a
+  INTERSECT
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 2, 'b'
+  INTERSECT
+  SELECT 2, 'b', false, true, LocalTempView, UNSUPPORTED, true
+   +- Intersect false
+      :- Intersect false
+      :  :- Intersect false
+      :  :  :- Project [1 AS 1#x, a AS a#x]
+      :  :  :  +- OneRowRelation
+      :  :  +- Project [1 AS 1#x, a AS a#x]
+      :  :     +- OneRowRelation
+      :  +- Project [2 AS 2#x, b AS b#x]
+      :     +- OneRowRelation
+      +- Project [2 AS 2#x, b AS b#x]
+         +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [1#x, a#x]
++- SubqueryAlias v1
+   +- View (`v1`, [1#x, a#x])
+      +- Project [cast(1#x as int) AS 1#x, cast(a#x as string) AS a#x]
+         +- Intersect false
+            :- Intersect false
+            :  :- Intersect false
+            :  :  :- Project [1 AS 1#x, a AS a#x]
+            :  :  :  +- OneRowRelation
+            :  :  +- Project [1 AS 1#x, a AS a#x]
+            :  :     +- OneRowRelation
+            :  +- Project [2 AS 2#x, b AS b#x]
+            :     +- OneRowRelation
+            +- Project [2 AS 2#x, b AS b#x]
+               +- OneRowRelation
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num, 'a' AS a
+  INTERSECT
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 2, 'b'
+  INTERSECT
+  SELECT 2, 'b'
+-- !query analysis
+CreateViewCommand `v1`, SELECT 1 AS num, 'a' AS a
+  INTERSECT
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 2, 'b'
+  INTERSECT
+  SELECT 2, 'b', false, true, LocalTempView, UNSUPPORTED, true
+   +- Intersect false
+      :- Intersect false
+      :  :- Intersect false
+      :  :  :- Project [1 AS num#x, a AS a#x]
+      :  :  :  +- OneRowRelation
+      :  :  +- Project [1 AS 1#x, a AS a#x]
+      :  :     +- OneRowRelation
+      :  +- Project [2 AS 2#x, b AS b#x]
+      :     +- OneRowRelation
+      +- Project [2 AS 2#x, b AS b#x]
+         +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [num#x, a#x]
++- SubqueryAlias v1
+   +- View (`v1`, [num#x, a#x])
+      +- Project [cast(num#x as int) AS num#x, cast(a#x as string) AS a#x]
+         +- Intersect false
+            :- Intersect false
+            :  :- Intersect false
+            :  :  :- Project [1 AS num#x, a AS a#x]
+            :  :  :  +- OneRowRelation
+            :  :  +- Project [1 AS 1#x, a AS a#x]
+            :  :     +- OneRowRelation
+            :  +- Project [2 AS 2#x, b AS b#x]
+            :     +- OneRowRelation
+            +- Project [2 AS 2#x, b AS b#x]
+               +- OneRowRelation
+
+
+-- !query
+CREATE OR REPLACE VIEW v1 WITH SCHEMA EVOLUTION AS
+  SELECT 1, 'a'
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+-- !query analysis
+CreateViewCommand `spark_catalog`.`default`.`v1`, SELECT 1, 'a'
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd', false, true, PersistedView, EVOLUTION, true
+   +- Distinct
+      +- Union false, false
+         :- Distinct
+         :  +- Union false, false
+         :     :- Distinct
+         :     :  +- Union false, false
+         :     :     :- Project [1 AS 1#x, a AS a#x]
+         :     :     :  +- OneRowRelation
+         :     :     +- Project [2 AS 2#x, b AS b#x]
+         :     :        +- OneRowRelation
+         :     +- Project [3 AS 3#x, c AS c#x]
+         :        +- OneRowRelation
+         +- Project [4 AS 4#x, d AS d#x]
+            +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [num#x, a#x]
++- SubqueryAlias v1
+   +- View (`v1`, [num#x, a#x])
+      +- Project [cast(num#x as int) AS num#x, cast(a#x as string) AS a#x]
+         +- Intersect false
+            :- Intersect false
+            :  :- Intersect false
+            :  :  :- Project [1 AS num#x, a AS a#x]
+            :  :  :  +- OneRowRelation
+            :  :  +- Project [1 AS 1#x, a AS a#x]
+            :  :     +- OneRowRelation
+            :  +- Project [2 AS 2#x, b AS b#x]
+            :     +- OneRowRelation
+            +- Project [2 AS 2#x, b AS b#x]
+               +- OneRowRelation
+
+
+-- !query
+CREATE OR REPLACE VIEW v1 WITH SCHEMA EVOLUTION AS
+  SELECT 1 AS num, 'a'
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+-- !query analysis
+CreateViewCommand `spark_catalog`.`default`.`v1`, SELECT 1 AS num, 'a'
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd', false, true, PersistedView, EVOLUTION, true
+   +- Distinct
+      +- Union false, false
+         :- Distinct
+         :  +- Union false, false
+         :     :- Distinct
+         :     :  +- Union false, false
+         :     :     :- Project [1 AS num#x, a AS a#x]
+         :     :     :  +- OneRowRelation
+         :     :     +- Project [2 AS 2#x, b AS b#x]
+         :     :        +- OneRowRelation
+         :     +- Project [3 AS 3#x, c AS c#x]
+         :        +- OneRowRelation
+         +- Project [4 AS 4#x, d AS d#x]
+            +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [num#x, a#x]
++- SubqueryAlias v1
+   +- View (`v1`, [num#x, a#x])
+      +- Project [cast(num#x as int) AS num#x, cast(a#x as string) AS a#x]
+         +- Intersect false
+            :- Intersect false
+            :  :- Intersect false
+            :  :  :- Project [1 AS num#x, a AS a#x]
+            :  :  :  +- OneRowRelation
+            :  :  +- Project [1 AS 1#x, a AS a#x]
+            :  :     +- OneRowRelation
+            :  +- Project [2 AS 2#x, b AS b#x]
+            :     +- OneRowRelation
+            +- Project [2 AS 2#x, b AS b#x]
+               +- OneRowRelation
+
+
+-- !query
+CREATE OR REPLACE VIEW v1 WITH SCHEMA EVOLUTION AS
+  SELECT 1 AS num, 'a' AS a
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+-- !query analysis
+CreateViewCommand `spark_catalog`.`default`.`v1`, SELECT 1 AS num, 'a' AS a
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd', false, true, PersistedView, EVOLUTION, true
+   +- Distinct
+      +- Union false, false
+         :- Distinct
+         :  +- Union false, false
+         :     :- Distinct
+         :     :  +- Union false, false
+         :     :     :- Project [1 AS num#x, a AS a#x]
+         :     :     :  +- OneRowRelation
+         :     :     +- Project [2 AS 2#x, b AS b#x]
+         :     :        +- OneRowRelation
+         :     +- Project [3 AS 3#x, c AS c#x]
+         :        +- OneRowRelation
+         +- Project [4 AS 4#x, d AS d#x]
+            +- OneRowRelation
+
+
+-- !query
+SELECT * FROM v1
+-- !query analysis
+Project [num#x, a#x]
++- SubqueryAlias v1
+   +- View (`v1`, [num#x, a#x])
+      +- Project [cast(num#x as int) AS num#x, cast(a#x as string) AS a#x]
+         +- Intersect false
+            :- Intersect false
+            :  :- Intersect false
+            :  :  :- Project [1 AS num#x, a AS a#x]
+            :  :  :  +- OneRowRelation
+            :  :  +- Project [1 AS 1#x, a AS a#x]
+            :  :     +- OneRowRelation
+            :  +- Project [2 AS 2#x, b AS b#x]
+            :     +- OneRowRelation
+            +- Project [2 AS 2#x, b AS b#x]
+               +- OneRowRelation
+
+
+-- !query
+DROP VIEW v1
+-- !query analysis
+DropTempViewCommand v1
+
+
+-- !query
+DECLARE v1 INT
+-- !query analysis
+CreateVariable defaultvalueexpression(null, null), false
++- ResolvedIdentifier org.apache.spark.sql.catalyst.analysis.FakeSystemCatalog$@xxxxxxxx, session.v1
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 UNION SELECT 2 UNION SELECT 3' INTO v1
+-- !query analysis
+org.apache.spark.SparkException
+{
+  "errorClass" : "ROW_SUBQUERY_TOO_MANY_ROWS",
+  "sqlState" : "21000"
+}
+
+
+-- !query
+SELECT v1
+-- !query analysis
+Project [variablereference(system.session.v1=CAST(NULL AS INT)) AS v1#x]
++- OneRowRelation
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 UNION SELECT 1 UNION SELECT 1' INTO v1
+-- !query analysis
+SetVariable [variablereference(system.session.v1=CAST(NULL AS INT))]
++- GlobalLimit 2
+   +- LocalLimit 2
+      +- Distinct
+         +- Union false, false
+            :- Distinct
+            :  +- Union false, false
+            :     :- Project [1 AS 1#x]
+            :     :  +- OneRowRelation
+            :     +- Project [1 AS 1#x]
+            :        +- OneRowRelation
+            +- Project [1 AS 1#x]
+               +- OneRowRelation
+
+
+-- !query
+SELECT v1
+-- !query analysis
+Project [variablereference(system.session.v1=1) AS v1#x]
++- OneRowRelation
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 EXCEPT SELECT 2 EXCEPT SELECT 3' INTO v1
+-- !query analysis
+SetVariable [variablereference(system.session.v1=1)]
++- Except false
+   :- Except false
+   :  :- Project [1 AS 1#x]
+   :  :  +- OneRowRelation
+   :  +- Project [2 AS 2#x]
+   :     +- OneRowRelation
+   +- Project [3 AS 3#x]
+      +- OneRowRelation
+
+
+-- !query
+SELECT v1
+-- !query analysis
+Project [variablereference(system.session.v1=1) AS v1#x]
++- OneRowRelation
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 EXCEPT SELECT 1 EXCEPT SELECT 1' INTO v1
+-- !query analysis
+SetVariable [variablereference(system.session.v1=1)]
++- Except false
+   :- Except false
+   :  :- Project [1 AS 1#x]
+   :  :  +- OneRowRelation
+   :  +- Project [1 AS 1#x]
+   :     +- OneRowRelation
+   +- Project [1 AS 1#x]
+      +- OneRowRelation
+
+
+-- !query
+SELECT v1
+-- !query analysis
+Project [variablereference(system.session.v1=CAST(NULL AS INT)) AS v1#x]
++- OneRowRelation
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 INTERSECT SELECT 2 INTERSECT SELECT 3' INTO v1
+-- !query analysis
+SetVariable [variablereference(system.session.v1=CAST(NULL AS INT))]
++- Intersect false
+   :- Intersect false
+   :  :- Project [1 AS 1#x]
+   :  :  +- OneRowRelation
+   :  +- Project [2 AS 2#x]
+   :     +- OneRowRelation
+   +- Project [3 AS 3#x]
+      +- OneRowRelation
+
+
+-- !query
+SELECT v1
+-- !query analysis
+Project [variablereference(system.session.v1=CAST(NULL AS INT)) AS v1#x]
++- OneRowRelation
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 INTERSECT SELECT 1 INTERSECT SELECT 1' INTO v1
+-- !query analysis
+SetVariable [variablereference(system.session.v1=CAST(NULL AS INT))]
++- Intersect false
+   :- Intersect false
+   :  :- Project [1 AS 1#x]
+   :  :  +- OneRowRelation
+   :  +- Project [1 AS 1#x]
+   :     +- OneRowRelation
+   +- Project [1 AS 1#x]
+      +- OneRowRelation
+
+
+-- !query
+SELECT v1
+-- !query analysis
+Project [variablereference(system.session.v1=1) AS v1#x]
++- OneRowRelation
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 JOIN SELECT 2' INTO v1
+-- !query analysis
+org.apache.spark.sql.catalyst.parser.ParseException
+{
+  "errorClass" : "PARSE_SYNTAX_ERROR",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "error" : "'SELECT'",
+    "hint" : ""
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 1,
+    "stopIndex" : 50,
+    "fragment" : "EXECUTE IMMEDIATE 'SELECT 1 JOIN SELECT 2' INTO v1"
+  } ]
+}
+
+
+-- !query
+SELECT v1
+-- !query analysis
+Project [variablereference(system.session.v1=1) AS v1#x]
++- OneRowRelation
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 VALUES (1)' INTO v1
+-- !query analysis
+org.apache.spark.sql.catalyst.parser.ParseException
+{
+  "errorClass" : "PARSE_SYNTAX_ERROR",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "error" : "'('",
+    "hint" : ""
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 1,
+    "stopIndex" : 47,
+    "fragment" : "EXECUTE IMMEDIATE 'SELECT 1 VALUES (1)' INTO v1"
+  } ]
+}
+
+
+-- !query
+SELECT v1
+-- !query analysis
+Project [variablereference(system.session.v1=1) AS v1#x]
++- OneRowRelation
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 alias garbage garbage garbage' INTO v1
+-- !query analysis
+org.apache.spark.sql.catalyst.parser.ParseException
+{
+  "errorClass" : "PARSE_SYNTAX_ERROR",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "error" : "'garbage'",
+    "hint" : ""
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 1,
+    "stopIndex" : 66,
+    "fragment" : "EXECUTE IMMEDIATE 'SELECT 1 alias garbage garbage garbage' INTO v1"
+  } ]
+}
+
+
+-- !query
+SELECT v1
+-- !query analysis
+Project [variablereference(system.session.v1=1) AS v1#x]
++- OneRowRelation
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 WITH abc' INTO v1
+-- !query analysis
+org.apache.spark.sql.catalyst.parser.ParseException
+{
+  "errorClass" : "PARSE_SYNTAX_ERROR",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "error" : "'abc'",
+    "hint" : ": extra input 'abc'"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 1,
+    "stopIndex" : 45,
+    "fragment" : "EXECUTE IMMEDIATE 'SELECT 1 WITH abc' INTO v1"
+  } ]
+}
+
+
+-- !query
+SELECT v1
+-- !query analysis
+Project [variablereference(system.session.v1=1) AS v1#x]
++- OneRowRelation
+
+
+-- !query
+DROP TEMPORARY VARIABLE v1
+-- !query analysis
+DropVariable false
++- ResolvedIdentifier org.apache.spark.sql.catalyst.analysis.FakeSystemCatalog$@xxxxxxxx, session.v1
diff --git a/sql/core/src/test/resources/sql-tests/inputs/parse-query-correctness-old-behavior.sql b/sql/core/src/test/resources/sql-tests/inputs/parse-query-correctness-old-behavior.sql
new file mode 100644
index 000000000000..bece56f575cb
--- /dev/null
+++ b/sql/core/src/test/resources/sql-tests/inputs/parse-query-correctness-old-behavior.sql
@@ -0,0 +1,2 @@
+--SET spark.sql.legacy.parseQueryWithoutEof=true
+--IMPORT parse-query-correctness.sql
diff --git a/sql/core/src/test/resources/sql-tests/inputs/parse-query-correctness.sql b/sql/core/src/test/resources/sql-tests/inputs/parse-query-correctness.sql
new file mode 100644
index 000000000000..ec00e454fa76
--- /dev/null
+++ b/sql/core/src/test/resources/sql-tests/inputs/parse-query-correctness.sql
@@ -0,0 +1,284 @@
+-- This test suite checks the correctness of AbstractSqlParser.parseQuery
+
+-- SPARK-51113, view read path
+
+-- UNION
+
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num
+  UNION
+  SELECT 2
+  UNION
+  SELECT 3
+  UNION
+  SELECT 4
+;
+SELECT * FROM v1;
+
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1
+  UNION
+  SELECT 2
+  UNION
+  SELECT 3
+  UNION
+  SELECT 4
+;
+SELECT * FROM v1;
+
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1, 'a'
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+;
+SELECT * FROM v1;
+
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num, 'a'
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+;
+SELECT * FROM v1;
+
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1, 'a' AS a
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+;
+SELECT * FROM v1;
+
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num, 'a' AS a
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+;
+SELECT * FROM v1;
+
+-- EXCEPT
+
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num
+  EXCEPT
+  SELECT 2
+  EXCEPT
+  SELECT 1
+  EXCEPT
+  SELECT 2
+;
+SELECT * FROM v1;
+
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1
+  EXCEPT
+  SELECT 2
+  EXCEPT
+  SELECT 1
+  EXCEPT
+  SELECT 2
+;
+SELECT * FROM v1;
+
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+  EXCEPT
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+;
+SELECT * FROM v1;
+
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+  EXCEPT
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+;
+SELECT * FROM v1;
+
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1, 'a' AS a
+  EXCEPT
+  SELECT 2, 'b'
+  EXCEPT
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+;
+SELECT * FROM v1;
+
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num, 'a' AS a
+  EXCEPT
+  SELECT 2, 'b'
+  EXCEPT
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+;
+SELECT * FROM v1;
+
+-- INTERSECT
+
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num
+  INTERSECT
+  SELECT 1
+  INTERSECT
+  SELECT 2
+  INTERSECT
+  SELECT 2
+;
+SELECT * FROM v1;
+
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1
+  INTERSECT
+  SELECT 1
+  INTERSECT
+  SELECT 2
+  INTERSECT
+  SELECT 2
+;
+SELECT * FROM v1;
+
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 2, 'b'
+  INTERSECT
+  SELECT 2, 'b'
+;
+SELECT * FROM v1;
+
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num, 'a'
+  INTERSECT
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 2, 'b'
+  INTERSECT
+  SELECT 2, 'b'
+;
+SELECT * FROM v1;
+
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1, 'a' AS a
+  INTERSECT
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 2, 'b'
+  INTERSECT
+  SELECT 2, 'b'
+;
+SELECT * FROM v1;
+
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num, 'a' AS a
+  INTERSECT
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 2, 'b'
+  INTERSECT
+  SELECT 2, 'b'
+;
+SELECT * FROM v1;
+
+-- Views with schema evolution would give incorrect result.
+-- The last column would be named 'UNION' on read, but schema evolution
+-- would allow the 'a' -> 'UNION' rename on read.
+
+CREATE OR REPLACE VIEW v1 WITH SCHEMA EVOLUTION AS
+  SELECT 1, 'a'
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+;
+SELECT * FROM v1;
+
+CREATE OR REPLACE VIEW v1 WITH SCHEMA EVOLUTION AS
+  SELECT 1 AS num, 'a'
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+;
+SELECT * FROM v1;
+
+CREATE OR REPLACE VIEW v1 WITH SCHEMA EVOLUTION AS
+  SELECT 1 AS num, 'a' AS a
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+;
+SELECT * FROM v1;
+
+DROP VIEW v1;
+
+-- SPARK-51113, EXECUTE IMMEDIATE ... INTO
+
+DECLARE v1 INT;
+
+EXECUTE IMMEDIATE 'SELECT 1 UNION SELECT 2 UNION SELECT 3' INTO v1;
+SELECT v1;
+
+EXECUTE IMMEDIATE 'SELECT 1 UNION SELECT 1 UNION SELECT 1' INTO v1;
+SELECT v1;
+
+EXECUTE IMMEDIATE 'SELECT 1 EXCEPT SELECT 2 EXCEPT SELECT 3' INTO v1;
+SELECT v1;
+
+EXECUTE IMMEDIATE 'SELECT 1 EXCEPT SELECT 1 EXCEPT SELECT 1' INTO v1;
+SELECT v1;
+
+EXECUTE IMMEDIATE 'SELECT 1 INTERSECT SELECT 2 INTERSECT SELECT 3' INTO v1;
+SELECT v1;
+
+EXECUTE IMMEDIATE 'SELECT 1 INTERSECT SELECT 1 INTERSECT SELECT 1' INTO v1;
+SELECT v1;
+
+-- Garbage queries
+
+EXECUTE IMMEDIATE 'SELECT 1 JOIN SELECT 2' INTO v1;
+SELECT v1;
+
+EXECUTE IMMEDIATE 'SELECT 1 VALUES (1)' INTO v1;
+SELECT v1;
+
+EXECUTE IMMEDIATE 'SELECT 1 alias garbage garbage garbage' INTO v1;
+SELECT v1;
+
+EXECUTE IMMEDIATE 'SELECT 1 WITH abc' INTO v1;
+SELECT v1;
+
+DROP TEMPORARY VARIABLE v1;
diff --git a/sql/core/src/test/resources/sql-tests/results/parse-query-correctness-old-behavior.sql.out b/sql/core/src/test/resources/sql-tests/results/parse-query-correctness-old-behavior.sql.out
new file mode 100644
index 000000000000..81ce41f03fec
--- /dev/null
+++ b/sql/core/src/test/resources/sql-tests/results/parse-query-correctness-old-behavior.sql.out
@@ -0,0 +1,768 @@
+-- Automatically generated by SQLQueryTestSuite
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num
+  UNION
+  SELECT 2
+  UNION
+  SELECT 3
+  UNION
+  SELECT 4
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<num:int>
+-- !query output
+1
+2
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1
+  UNION
+  SELECT 2
+  UNION
+  SELECT 3
+  UNION
+  SELECT 4
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "INCOMPATIBLE_VIEW_SCHEMA_CHANGE",
+  "sqlState" : "51024",
+  "messageParameters" : {
+    "actualCols" : "[]",
+    "colName" : "1",
+    "expectedNum" : "1",
+    "suggestion" : "CREATE OR REPLACE TEMPORARY VIEW",
+    "viewName" : "`v1`"
+  }
+}
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1, 'a'
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "INCOMPATIBLE_VIEW_SCHEMA_CHANGE",
+  "sqlState" : "51024",
+  "messageParameters" : {
+    "actualCols" : "[]",
+    "colName" : "a",
+    "expectedNum" : "1",
+    "suggestion" : "CREATE OR REPLACE TEMPORARY VIEW",
+    "viewName" : "`v1`"
+  }
+}
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num, 'a'
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "INCOMPATIBLE_VIEW_SCHEMA_CHANGE",
+  "sqlState" : "51024",
+  "messageParameters" : {
+    "actualCols" : "[]",
+    "colName" : "a",
+    "expectedNum" : "1",
+    "suggestion" : "CREATE OR REPLACE TEMPORARY VIEW",
+    "viewName" : "`v1`"
+  }
+}
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1, 'a' AS a
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<1:int,a:string>
+-- !query output
+1	a
+2	b
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num, 'a' AS a
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<num:int,a:string>
+-- !query output
+1	a
+2	b
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num
+  EXCEPT
+  SELECT 2
+  EXCEPT
+  SELECT 1
+  EXCEPT
+  SELECT 2
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<num:int>
+-- !query output
+1
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1
+  EXCEPT
+  SELECT 2
+  EXCEPT
+  SELECT 1
+  EXCEPT
+  SELECT 2
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "INCOMPATIBLE_VIEW_SCHEMA_CHANGE",
+  "sqlState" : "51024",
+  "messageParameters" : {
+    "actualCols" : "[]",
+    "colName" : "1",
+    "expectedNum" : "1",
+    "suggestion" : "CREATE OR REPLACE TEMPORARY VIEW",
+    "viewName" : "`v1`"
+  }
+}
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+  EXCEPT
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "INCOMPATIBLE_VIEW_SCHEMA_CHANGE",
+  "sqlState" : "51024",
+  "messageParameters" : {
+    "actualCols" : "[]",
+    "colName" : "a",
+    "expectedNum" : "1",
+    "suggestion" : "CREATE OR REPLACE TEMPORARY VIEW",
+    "viewName" : "`v1`"
+  }
+}
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+  EXCEPT
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "INCOMPATIBLE_VIEW_SCHEMA_CHANGE",
+  "sqlState" : "51024",
+  "messageParameters" : {
+    "actualCols" : "[]",
+    "colName" : "a",
+    "expectedNum" : "1",
+    "suggestion" : "CREATE OR REPLACE TEMPORARY VIEW",
+    "viewName" : "`v1`"
+  }
+}
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1, 'a' AS a
+  EXCEPT
+  SELECT 2, 'b'
+  EXCEPT
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<1:int,a:string>
+-- !query output
+1	a
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num, 'a' AS a
+  EXCEPT
+  SELECT 2, 'b'
+  EXCEPT
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<num:int,a:string>
+-- !query output
+1	a
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num
+  INTERSECT
+  SELECT 1
+  INTERSECT
+  SELECT 2
+  INTERSECT
+  SELECT 2
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<num:int>
+-- !query output
+1
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1
+  INTERSECT
+  SELECT 1
+  INTERSECT
+  SELECT 2
+  INTERSECT
+  SELECT 2
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "INCOMPATIBLE_VIEW_SCHEMA_CHANGE",
+  "sqlState" : "51024",
+  "messageParameters" : {
+    "actualCols" : "[]",
+    "colName" : "1",
+    "expectedNum" : "1",
+    "suggestion" : "CREATE OR REPLACE TEMPORARY VIEW",
+    "viewName" : "`v1`"
+  }
+}
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 2, 'b'
+  INTERSECT
+  SELECT 2, 'b'
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "INCOMPATIBLE_VIEW_SCHEMA_CHANGE",
+  "sqlState" : "51024",
+  "messageParameters" : {
+    "actualCols" : "[]",
+    "colName" : "a",
+    "expectedNum" : "1",
+    "suggestion" : "CREATE OR REPLACE TEMPORARY VIEW",
+    "viewName" : "`v1`"
+  }
+}
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num, 'a'
+  INTERSECT
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 2, 'b'
+  INTERSECT
+  SELECT 2, 'b'
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "INCOMPATIBLE_VIEW_SCHEMA_CHANGE",
+  "sqlState" : "51024",
+  "messageParameters" : {
+    "actualCols" : "[]",
+    "colName" : "a",
+    "expectedNum" : "1",
+    "suggestion" : "CREATE OR REPLACE TEMPORARY VIEW",
+    "viewName" : "`v1`"
+  }
+}
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1, 'a' AS a
+  INTERSECT
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 2, 'b'
+  INTERSECT
+  SELECT 2, 'b'
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<1:int,a:string>
+-- !query output
+1	a
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num, 'a' AS a
+  INTERSECT
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 2, 'b'
+  INTERSECT
+  SELECT 2, 'b'
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<num:int,a:string>
+-- !query output
+1	a
+
+
+-- !query
+CREATE OR REPLACE VIEW v1 WITH SCHEMA EVOLUTION AS
+  SELECT 1, 'a'
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<num:int,a:string>
+-- !query output
+1	a
+
+
+-- !query
+CREATE OR REPLACE VIEW v1 WITH SCHEMA EVOLUTION AS
+  SELECT 1 AS num, 'a'
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<num:int,a:string>
+-- !query output
+1	a
+
+
+-- !query
+CREATE OR REPLACE VIEW v1 WITH SCHEMA EVOLUTION AS
+  SELECT 1 AS num, 'a' AS a
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<num:int,a:string>
+-- !query output
+1	a
+
+
+-- !query
+DROP VIEW v1
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+DECLARE v1 INT
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 UNION SELECT 2 UNION SELECT 3' INTO v1
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT v1
+-- !query schema
+struct<v1:int>
+-- !query output
+1
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 UNION SELECT 1 UNION SELECT 1' INTO v1
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT v1
+-- !query schema
+struct<v1:int>
+-- !query output
+1
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 EXCEPT SELECT 2 EXCEPT SELECT 3' INTO v1
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT v1
+-- !query schema
+struct<v1:int>
+-- !query output
+1
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 EXCEPT SELECT 1 EXCEPT SELECT 1' INTO v1
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT v1
+-- !query schema
+struct<v1:int>
+-- !query output
+1
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 INTERSECT SELECT 2 INTERSECT SELECT 3' INTO v1
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT v1
+-- !query schema
+struct<v1:int>
+-- !query output
+1
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 INTERSECT SELECT 1 INTERSECT SELECT 1' INTO v1
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT v1
+-- !query schema
+struct<v1:int>
+-- !query output
+1
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 JOIN SELECT 2' INTO v1
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT v1
+-- !query schema
+struct<v1:int>
+-- !query output
+1
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 VALUES (1)' INTO v1
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT v1
+-- !query schema
+struct<v1:int>
+-- !query output
+1
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 alias garbage garbage garbage' INTO v1
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT v1
+-- !query schema
+struct<v1:int>
+-- !query output
+1
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 WITH abc' INTO v1
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT v1
+-- !query schema
+struct<v1:int>
+-- !query output
+1
+
+
+-- !query
+DROP TEMPORARY VARIABLE v1
+-- !query schema
+struct<>
+-- !query output
+
diff --git a/sql/core/src/test/resources/sql-tests/results/parse-query-correctness.sql.out b/sql/core/src/test/resources/sql-tests/results/parse-query-correctness.sql.out
new file mode 100644
index 000000000000..a89ffdca7768
--- /dev/null
+++ b/sql/core/src/test/resources/sql-tests/results/parse-query-correctness.sql.out
@@ -0,0 +1,748 @@
+-- Automatically generated by SQLQueryTestSuite
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num
+  UNION
+  SELECT 2
+  UNION
+  SELECT 3
+  UNION
+  SELECT 4
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<num:int>
+-- !query output
+1
+2
+3
+4
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1
+  UNION
+  SELECT 2
+  UNION
+  SELECT 3
+  UNION
+  SELECT 4
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<1:int>
+-- !query output
+1
+2
+3
+4
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1, 'a'
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<1:int,a:string>
+-- !query output
+1	a
+2	b
+3	c
+4	d
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num, 'a'
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<num:int,a:string>
+-- !query output
+1	a
+2	b
+3	c
+4	d
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1, 'a' AS a
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<1:int,a:string>
+-- !query output
+1	a
+2	b
+3	c
+4	d
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num, 'a' AS a
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<num:int,a:string>
+-- !query output
+1	a
+2	b
+3	c
+4	d
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num
+  EXCEPT
+  SELECT 2
+  EXCEPT
+  SELECT 1
+  EXCEPT
+  SELECT 2
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<num:int>
+-- !query output
+
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1
+  EXCEPT
+  SELECT 2
+  EXCEPT
+  SELECT 1
+  EXCEPT
+  SELECT 2
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<1:int>
+-- !query output
+
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+  EXCEPT
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<1:int,a:string>
+-- !query output
+
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+  EXCEPT
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<num:int,a:string>
+-- !query output
+
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1, 'a' AS a
+  EXCEPT
+  SELECT 2, 'b'
+  EXCEPT
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<1:int,a:string>
+-- !query output
+
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num, 'a' AS a
+  EXCEPT
+  SELECT 2, 'b'
+  EXCEPT
+  SELECT 1, 'a'
+  EXCEPT
+  SELECT 2, 'b'
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<num:int,a:string>
+-- !query output
+
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num
+  INTERSECT
+  SELECT 1
+  INTERSECT
+  SELECT 2
+  INTERSECT
+  SELECT 2
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<num:int>
+-- !query output
+
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1
+  INTERSECT
+  SELECT 1
+  INTERSECT
+  SELECT 2
+  INTERSECT
+  SELECT 2
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<1:int>
+-- !query output
+
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 2, 'b'
+  INTERSECT
+  SELECT 2, 'b'
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<1:int,a:string>
+-- !query output
+
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num, 'a'
+  INTERSECT
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 2, 'b'
+  INTERSECT
+  SELECT 2, 'b'
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<num:int,a:string>
+-- !query output
+
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1, 'a' AS a
+  INTERSECT
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 2, 'b'
+  INTERSECT
+  SELECT 2, 'b'
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<1:int,a:string>
+-- !query output
+
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW v1 AS
+  SELECT 1 AS num, 'a' AS a
+  INTERSECT
+  SELECT 1, 'a'
+  INTERSECT
+  SELECT 2, 'b'
+  INTERSECT
+  SELECT 2, 'b'
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<num:int,a:string>
+-- !query output
+
+
+
+-- !query
+CREATE OR REPLACE VIEW v1 WITH SCHEMA EVOLUTION AS
+  SELECT 1, 'a'
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<num:int,a:string>
+-- !query output
+
+
+
+-- !query
+CREATE OR REPLACE VIEW v1 WITH SCHEMA EVOLUTION AS
+  SELECT 1 AS num, 'a'
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<num:int,a:string>
+-- !query output
+
+
+
+-- !query
+CREATE OR REPLACE VIEW v1 WITH SCHEMA EVOLUTION AS
+  SELECT 1 AS num, 'a' AS a
+  UNION
+  SELECT 2, 'b'
+  UNION
+  SELECT 3, 'c'
+  UNION
+  SELECT 4, 'd'
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT * FROM v1
+-- !query schema
+struct<num:int,a:string>
+-- !query output
+
+
+
+-- !query
+DROP VIEW v1
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+DECLARE v1 INT
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 UNION SELECT 2 UNION SELECT 3' INTO v1
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.SparkException
+{
+  "errorClass" : "ROW_SUBQUERY_TOO_MANY_ROWS",
+  "sqlState" : "21000"
+}
+
+
+-- !query
+SELECT v1
+-- !query schema
+struct<v1:int>
+-- !query output
+NULL
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 UNION SELECT 1 UNION SELECT 1' INTO v1
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT v1
+-- !query schema
+struct<v1:int>
+-- !query output
+1
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 EXCEPT SELECT 2 EXCEPT SELECT 3' INTO v1
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT v1
+-- !query schema
+struct<v1:int>
+-- !query output
+1
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 EXCEPT SELECT 1 EXCEPT SELECT 1' INTO v1
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT v1
+-- !query schema
+struct<v1:int>
+-- !query output
+NULL
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 INTERSECT SELECT 2 INTERSECT SELECT 3' INTO v1
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT v1
+-- !query schema
+struct<v1:int>
+-- !query output
+NULL
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 INTERSECT SELECT 1 INTERSECT SELECT 1' INTO v1
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT v1
+-- !query schema
+struct<v1:int>
+-- !query output
+1
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 JOIN SELECT 2' INTO v1
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.catalyst.parser.ParseException
+{
+  "errorClass" : "PARSE_SYNTAX_ERROR",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "error" : "'SELECT'",
+    "hint" : ""
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 1,
+    "stopIndex" : 50,
+    "fragment" : "EXECUTE IMMEDIATE 'SELECT 1 JOIN SELECT 2' INTO v1"
+  } ]
+}
+
+
+-- !query
+SELECT v1
+-- !query schema
+struct<v1:int>
+-- !query output
+1
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 VALUES (1)' INTO v1
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.catalyst.parser.ParseException
+{
+  "errorClass" : "PARSE_SYNTAX_ERROR",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "error" : "'('",
+    "hint" : ""
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 1,
+    "stopIndex" : 47,
+    "fragment" : "EXECUTE IMMEDIATE 'SELECT 1 VALUES (1)' INTO v1"
+  } ]
+}
+
+
+-- !query
+SELECT v1
+-- !query schema
+struct<v1:int>
+-- !query output
+1
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 alias garbage garbage garbage' INTO v1
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.catalyst.parser.ParseException
+{
+  "errorClass" : "PARSE_SYNTAX_ERROR",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "error" : "'garbage'",
+    "hint" : ""
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 1,
+    "stopIndex" : 66,
+    "fragment" : "EXECUTE IMMEDIATE 'SELECT 1 alias garbage garbage garbage' INTO v1"
+  } ]
+}
+
+
+-- !query
+SELECT v1
+-- !query schema
+struct<v1:int>
+-- !query output
+1
+
+
+-- !query
+EXECUTE IMMEDIATE 'SELECT 1 WITH abc' INTO v1
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.catalyst.parser.ParseException
+{
+  "errorClass" : "PARSE_SYNTAX_ERROR",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "error" : "'abc'",
+    "hint" : ": extra input 'abc'"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 1,
+    "stopIndex" : 45,
+    "fragment" : "EXECUTE IMMEDIATE 'SELECT 1 WITH abc' INTO v1"
+  } ]
+}
+
+
+-- !query
+SELECT v1
+-- !query schema
+struct<v1:int>
+-- !query output
+1
+
+
+-- !query
+DROP TEMPORARY VARIABLE v1
+-- !query schema
+struct<>
+-- !query output
+


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