Skip to content

Commit 35b644b

Browse files
viiryacloud-fan
authored andcommitted
[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 <[email protected]> Closes #18141 from viirya/SPARK-20916.
1 parent 80fb24b commit 35b644b

File tree

5 files changed

+88
-3
lines changed

5 files changed

+88
-3
lines changed

sql/catalyst/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBase.g4

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,7 @@ identifierComment
473473

474474
relationPrimary
475475
: tableIdentifier sample? tableAlias #tableName
476-
| '(' queryNoWith ')' sample? (AS? strictIdentifier) #aliasedQuery
476+
| '(' queryNoWith ')' sample? (AS? strictIdentifier)? #aliasedQuery
477477
| '(' relation ')' sample? (AS? strictIdentifier)? #aliasedRelation
478478
| inlineTable #inlineTableDefault2
479479
| functionTable #tableValuedFunction

sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,13 @@ class AstBuilder(conf: SQLConf) extends SqlBaseBaseVisitor[AnyRef] with Logging
749749
* hooks.
750750
*/
751751
override def visitAliasedQuery(ctx: AliasedQueryContext): LogicalPlan = withOrigin(ctx) {
752+
// The unaliased subqueries in the FROM clause are disallowed. Instead of rejecting it in
753+
// parser rules, we handle it here in order to provide better error message.
754+
if (ctx.strictIdentifier == null) {
755+
throw new ParseException("The unaliased subqueries in the FROM clause are not supported.",
756+
ctx)
757+
}
758+
752759
aliasPlan(ctx.strictIdentifier,
753760
plan(ctx.queryNoWith).optionalMap(ctx.sample)(withSample))
754761
}

sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/PlanParserSuite.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -448,13 +448,15 @@ class PlanParserSuite extends PlanTest {
448448
}
449449

450450
test("aliased subquery") {
451+
val errMsg = "The unaliased subqueries in the FROM clause are not supported"
452+
451453
assertEqual("select a from (select id as a from t0) tt",
452454
table("t0").select('id.as("a")).as("tt").select('a))
453-
intercept("select a from (select id as a from t0)", "mismatched input")
455+
intercept("select a from (select id as a from t0)", errMsg)
454456

455457
assertEqual("from (select id as a from t0) tt select a",
456458
table("t0").select('id.as("a")).as("tt").select('a))
457-
intercept("from (select id as a from t0) select a", "extraneous input 'a'")
459+
intercept("from (select id as a from t0) select a", errMsg)
458460
}
459461

460462
test("scalar sub-query") {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
-- Aliased subqueries in FROM clause
2+
SELECT * FROM (SELECT * FROM testData) AS t WHERE key = 1;
3+
4+
FROM (SELECT * FROM testData WHERE key = 1) AS t SELECT *;
5+
6+
-- Optional `AS` keyword
7+
SELECT * FROM (SELECT * FROM testData) t WHERE key = 1;
8+
9+
FROM (SELECT * FROM testData WHERE key = 1) t SELECT *;
10+
11+
-- Disallow unaliased subqueries in FROM clause
12+
SELECT * FROM (SELECT * FROM testData) WHERE key = 1;
13+
14+
FROM (SELECT * FROM testData WHERE key = 1) SELECT *;
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
-- Automatically generated by SQLQueryTestSuite
2+
-- Number of queries: 6
3+
4+
5+
-- !query 0
6+
SELECT * FROM (SELECT * FROM testData) AS t WHERE key = 1
7+
-- !query 0 schema
8+
struct<key:int,value:string>
9+
-- !query 0 output
10+
1 1
11+
12+
13+
-- !query 1
14+
FROM (SELECT * FROM testData WHERE key = 1) AS t SELECT *
15+
-- !query 1 schema
16+
struct<key:int,value:string>
17+
-- !query 1 output
18+
1 1
19+
20+
21+
-- !query 2
22+
SELECT * FROM (SELECT * FROM testData) t WHERE key = 1
23+
-- !query 2 schema
24+
struct<key:int,value:string>
25+
-- !query 2 output
26+
1 1
27+
28+
29+
-- !query 3
30+
FROM (SELECT * FROM testData WHERE key = 1) t SELECT *
31+
-- !query 3 schema
32+
struct<key:int,value:string>
33+
-- !query 3 output
34+
1 1
35+
36+
37+
-- !query 4
38+
SELECT * FROM (SELECT * FROM testData) WHERE key = 1
39+
-- !query 4 schema
40+
struct<>
41+
-- !query 4 output
42+
org.apache.spark.sql.catalyst.parser.ParseException
43+
44+
The unaliased subqueries in the FROM clause are not supported.(line 1, pos 14)
45+
46+
== SQL ==
47+
SELECT * FROM (SELECT * FROM testData) WHERE key = 1
48+
--------------^^^
49+
50+
51+
-- !query 5
52+
FROM (SELECT * FROM testData WHERE key = 1) SELECT *
53+
-- !query 5 schema
54+
struct<>
55+
-- !query 5 output
56+
org.apache.spark.sql.catalyst.parser.ParseException
57+
58+
The unaliased subqueries in the FROM clause are not supported.(line 1, pos 5)
59+
60+
== SQL ==
61+
FROM (SELECT * FROM testData WHERE key = 1) SELECT *
62+
-----^^^

0 commit comments

Comments
 (0)