aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/catalyst/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBase.g42
-rw-r--r--sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/Analyzer.scala5
-rw-r--r--sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala2
-rw-r--r--sql/core/src/test/scala/org/apache/spark/sql/SubquerySuite.scala25
4 files changed, 29 insertions, 5 deletions
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 7023c0c8c4..de2f9ee6bc 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
@@ -262,7 +262,7 @@ ctes
;
namedQuery
- : name=identifier AS? '(' queryNoWith ')'
+ : name=identifier AS? '(' query ')'
;
tableProvider
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/Analyzer.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/Analyzer.scala
index cc62d5e7c8..ae8869ff25 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/Analyzer.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/Analyzer.scala
@@ -116,15 +116,14 @@ class Analyzer(
)
/**
- * Substitute child plan with cte definitions
+ * Analyze cte definitions and substitute child plan with analyzed cte definitions.
*/
object CTESubstitution extends Rule[LogicalPlan] {
- // TODO allow subquery to define CTE
def apply(plan: LogicalPlan): LogicalPlan = plan resolveOperators {
case With(child, relations) =>
substituteCTE(child, relations.foldLeft(Seq.empty[(String, LogicalPlan)]) {
case (resolved, (name, relation)) =>
- resolved :+ name -> ResolveRelations(substituteCTE(relation, resolved))
+ resolved :+ name -> execute(substituteCTE(relation, resolved))
})
case other => other
}
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 69d68fa6f9..12a70b7769 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
@@ -108,7 +108,7 @@ class AstBuilder extends SqlBaseBaseVisitor[AnyRef] with Logging {
* This is only used for Common Table Expressions.
*/
override def visitNamedQuery(ctx: NamedQueryContext): SubqueryAlias = withOrigin(ctx) {
- SubqueryAlias(ctx.name.getText, plan(ctx.queryNoWith), None)
+ SubqueryAlias(ctx.name.getText, plan(ctx.query), None)
}
/**
diff --git a/sql/core/src/test/scala/org/apache/spark/sql/SubquerySuite.scala b/sql/core/src/test/scala/org/apache/spark/sql/SubquerySuite.scala
index 52387b4b72..eab45050f7 100644
--- a/sql/core/src/test/scala/org/apache/spark/sql/SubquerySuite.scala
+++ b/sql/core/src/test/scala/org/apache/spark/sql/SubquerySuite.scala
@@ -76,6 +76,31 @@ class SubquerySuite extends QueryTest with SharedSQLContext {
)
}
+ test("define CTE in CTE subquery") {
+ checkAnswer(
+ sql(
+ """
+ | with t2 as (with t1 as (select 1 as b, 2 as c) select b, c from t1)
+ | select a from (select 1 as a union all select 2 as a) t
+ | where a = (select max(b) from t2)
+ """.stripMargin),
+ Array(Row(1))
+ )
+ checkAnswer(
+ sql(
+ """
+ | with t2 as (with t1 as (select 1 as b, 2 as c) select b, c from t1),
+ | t3 as (
+ | with t4 as (select 1 as d, 3 as e)
+ | select * from t4 cross join t2 where t2.b = t4.d
+ | )
+ | select a from (select 1 as a union all select 2 as a)
+ | where a = (select max(d) from t3)
+ """.stripMargin),
+ Array(Row(1))
+ )
+ }
+
test("uncorrelated scalar subquery in CTE") {
checkAnswer(
sql("with t2 as (select 1 as b, 2 as c) " +