Repository: spark
Updated Branches:
  refs/heads/master 80fb24b85 -> 35b644bd0


[SPARK-20916][SQL] Improve error message for unaliased subqueries in FROM clause

## What changes were proposed in this pull request?

We changed the parser to reject unaliased subqueries in the FROM clause in 
SPARK-20690. However, the error message that we now give isn't very helpful:

    scala> sql("""SELECT x FROM (SELECT 1 AS x)""")
    org.apache.spark.sql.catalyst.parser.ParseException:
    mismatched input 'FROM' expecting {<EOF>, 'WHERE', 'GROUP', 'ORDER', 
'HAVING', 'LIMIT', 'LATERAL', 'WINDOW', 'UNION', 'EXCEPT', 'MINUS', 
'INTERSECT', 'SORT', 'CLUSTER', 'DISTRIBUTE'}(line 1, pos 9)

We should modify the parser to throw a more clear error for such queries:

    scala> sql("""SELECT x FROM (SELECT 1 AS x)""")
    org.apache.spark.sql.catalyst.parser.ParseException:
    The unaliased subqueries in the FROM clause are not supported.(line 1, pos 
14)

## How was this patch tested?

Modified existing tests to reflect this change.

Author: Liang-Chi Hsieh <vii...@gmail.com>

Closes #18141 from viirya/SPARK-20916.


Project: http://git-wip-us.apache.org/repos/asf/spark/repo
Commit: http://git-wip-us.apache.org/repos/asf/spark/commit/35b644bd
Tree: http://git-wip-us.apache.org/repos/asf/spark/tree/35b644bd
Diff: http://git-wip-us.apache.org/repos/asf/spark/diff/35b644bd

Branch: refs/heads/master
Commit: 35b644bd03da74ee9cafd2d1626e4694d473236d
Parents: 80fb24b
Author: Liang-Chi Hsieh <vii...@gmail.com>
Authored: Tue May 30 06:28:43 2017 -0700
Committer: Wenchen Fan <wenc...@databricks.com>
Committed: Tue May 30 06:28:43 2017 -0700

----------------------------------------------------------------------
 .../apache/spark/sql/catalyst/parser/SqlBase.g4 |  2 +-
 .../spark/sql/catalyst/parser/AstBuilder.scala  |  7 +++
 .../sql/catalyst/parser/PlanParserSuite.scala   |  6 +-
 .../inputs/subquery/subquery-in-from.sql        | 14 +++++
 .../results/subquery/subquery-in-from.sql.out   | 62 ++++++++++++++++++++
 5 files changed, 88 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/spark/blob/35b644bd/sql/catalyst/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBase.g4
----------------------------------------------------------------------
diff --git 
a/sql/catalyst/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBase.g4 
b/sql/catalyst/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBase.g4
index 547013c..4584aea 100644
--- 
a/sql/catalyst/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBase.g4
+++ 
b/sql/catalyst/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBase.g4
@@ -473,7 +473,7 @@ identifierComment
 
 relationPrimary
     : tableIdentifier sample? tableAlias                   #tableName
-    | '(' queryNoWith ')' sample? (AS? strictIdentifier)   #aliasedQuery
+    | '(' queryNoWith ')' sample? (AS? strictIdentifier)?  #aliasedQuery
     | '(' relation ')' sample? (AS? strictIdentifier)?     #aliasedRelation
     | inlineTable                                          #inlineTableDefault2
     | functionTable                                        #tableValuedFunction

http://git-wip-us.apache.org/repos/asf/spark/blob/35b644bd/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala
----------------------------------------------------------------------
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 5f34d07..4eb5560 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
@@ -749,6 +749,13 @@ class AstBuilder(conf: SQLConf) extends 
SqlBaseBaseVisitor[AnyRef] with Logging
    * hooks.
    */
   override def visitAliasedQuery(ctx: AliasedQueryContext): LogicalPlan = 
withOrigin(ctx) {
+    // The unaliased subqueries in the FROM clause are disallowed. Instead of 
rejecting it in
+    // parser rules, we handle it here in order to provide better error 
message.
+    if (ctx.strictIdentifier == null) {
+      throw new ParseException("The unaliased subqueries in the FROM clause 
are not supported.",
+        ctx)
+    }
+
     aliasPlan(ctx.strictIdentifier,
       plan(ctx.queryNoWith).optionalMap(ctx.sample)(withSample))
   }

http://git-wip-us.apache.org/repos/asf/spark/blob/35b644bd/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/PlanParserSuite.scala
----------------------------------------------------------------------
diff --git 
a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/PlanParserSuite.scala
 
b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/PlanParserSuite.scala
index 7a5357e..3a26ada 100644
--- 
a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/PlanParserSuite.scala
+++ 
b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/PlanParserSuite.scala
@@ -448,13 +448,15 @@ class PlanParserSuite extends PlanTest {
   }
 
   test("aliased subquery") {
+    val errMsg = "The unaliased subqueries in the FROM clause are not 
supported"
+
     assertEqual("select a from (select id as a from t0) tt",
       table("t0").select('id.as("a")).as("tt").select('a))
-    intercept("select a from (select id as a from t0)", "mismatched input")
+    intercept("select a from (select id as a from t0)", errMsg)
 
     assertEqual("from (select id as a from t0) tt select a",
       table("t0").select('id.as("a")).as("tt").select('a))
-    intercept("from (select id as a from t0) select a", "extraneous input 'a'")
+    intercept("from (select id as a from t0) select a", errMsg)
   }
 
   test("scalar sub-query") {

http://git-wip-us.apache.org/repos/asf/spark/blob/35b644bd/sql/core/src/test/resources/sql-tests/inputs/subquery/subquery-in-from.sql
----------------------------------------------------------------------
diff --git 
a/sql/core/src/test/resources/sql-tests/inputs/subquery/subquery-in-from.sql 
b/sql/core/src/test/resources/sql-tests/inputs/subquery/subquery-in-from.sql
new file mode 100644
index 0000000..1273b56
--- /dev/null
+++ b/sql/core/src/test/resources/sql-tests/inputs/subquery/subquery-in-from.sql
@@ -0,0 +1,14 @@
+-- Aliased subqueries in FROM clause
+SELECT * FROM (SELECT * FROM testData) AS t WHERE key = 1;
+
+FROM (SELECT * FROM testData WHERE key = 1) AS t SELECT *;
+
+-- Optional `AS` keyword
+SELECT * FROM (SELECT * FROM testData) t WHERE key = 1;
+
+FROM (SELECT * FROM testData WHERE key = 1) t SELECT *;
+
+-- Disallow unaliased subqueries in FROM clause
+SELECT * FROM (SELECT * FROM testData) WHERE key = 1;
+
+FROM (SELECT * FROM testData WHERE key = 1) SELECT *;

http://git-wip-us.apache.org/repos/asf/spark/blob/35b644bd/sql/core/src/test/resources/sql-tests/results/subquery/subquery-in-from.sql.out
----------------------------------------------------------------------
diff --git 
a/sql/core/src/test/resources/sql-tests/results/subquery/subquery-in-from.sql.out
 
b/sql/core/src/test/resources/sql-tests/results/subquery/subquery-in-from.sql.out
new file mode 100644
index 0000000..1455355
--- /dev/null
+++ 
b/sql/core/src/test/resources/sql-tests/results/subquery/subquery-in-from.sql.out
@@ -0,0 +1,62 @@
+-- Automatically generated by SQLQueryTestSuite
+-- Number of queries: 6
+
+
+-- !query 0
+SELECT * FROM (SELECT * FROM testData) AS t WHERE key = 1
+-- !query 0 schema
+struct<key:int,value:string>
+-- !query 0 output
+1      1
+
+
+-- !query 1
+FROM (SELECT * FROM testData WHERE key = 1) AS t SELECT *
+-- !query 1 schema
+struct<key:int,value:string>
+-- !query 1 output
+1      1
+
+
+-- !query 2
+SELECT * FROM (SELECT * FROM testData) t WHERE key = 1
+-- !query 2 schema
+struct<key:int,value:string>
+-- !query 2 output
+1      1
+
+
+-- !query 3
+FROM (SELECT * FROM testData WHERE key = 1) t SELECT *
+-- !query 3 schema
+struct<key:int,value:string>
+-- !query 3 output
+1      1
+
+
+-- !query 4
+SELECT * FROM (SELECT * FROM testData) WHERE key = 1
+-- !query 4 schema
+struct<>
+-- !query 4 output
+org.apache.spark.sql.catalyst.parser.ParseException
+
+The unaliased subqueries in the FROM clause are not supported.(line 1, pos 14)
+
+== SQL ==
+SELECT * FROM (SELECT * FROM testData) WHERE key = 1
+--------------^^^
+
+
+-- !query 5
+FROM (SELECT * FROM testData WHERE key = 1) SELECT *
+-- !query 5 schema
+struct<>
+-- !query 5 output
+org.apache.spark.sql.catalyst.parser.ParseException
+
+The unaliased subqueries in the FROM clause are not supported.(line 1, pos 5)
+
+== SQL ==
+FROM (SELECT * FROM testData WHERE key = 1) SELECT *
+-----^^^


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

Reply via email to