aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/Analyzer.scala13
-rw-r--r--sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/AnalysisErrorSuite.scala17
-rw-r--r--sql/core/src/test/scala/org/apache/spark/sql/SubquerySuite.scala29
3 files changed, 59 insertions, 0 deletions
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 660f523698..25202b521a 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
@@ -1021,6 +1021,19 @@ class Analyzer(
case e: Expand =>
failOnOuterReferenceInSubTree(e, "an EXPAND")
e
+ case l : LocalLimit =>
+ failOnOuterReferenceInSubTree(l, "a LIMIT")
+ l
+ // Since LIMIT <n> is represented as GlobalLimit(<n>, (LocalLimit (<n>, child))
+ // and we are walking bottom up, we will fail on LocalLimit before
+ // reaching GlobalLimit.
+ // The code below is just a safety net.
+ case g : GlobalLimit =>
+ failOnOuterReferenceInSubTree(g, "a LIMIT")
+ g
+ case s : Sample =>
+ failOnOuterReferenceInSubTree(s, "a TABLESAMPLE")
+ s
case p =>
failOnOuterReference(p)
p
diff --git a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/AnalysisErrorSuite.scala b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/AnalysisErrorSuite.scala
index 8363a1b1cd..13bf034f83 100644
--- a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/AnalysisErrorSuite.scala
+++ b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/AnalysisErrorSuite.scala
@@ -548,5 +548,22 @@ class AnalysisErrorSuite extends AnalysisTest {
Exists(Union(LocalRelation(b), Filter(EqualTo(OuterReference(a), c), LocalRelation(c)))),
LocalRelation(a))
assertAnalysisError(plan3, "Accessing outer query column is not allowed in" :: Nil)
+
+ val plan4 = Filter(
+ Exists(
+ Limit(1,
+ Filter(EqualTo(OuterReference(a), b), LocalRelation(b)))
+ ),
+ LocalRelation(a))
+ assertAnalysisError(plan4, "Accessing outer query column is not allowed in a LIMIT" :: Nil)
+
+ val plan5 = Filter(
+ Exists(
+ Sample(0.0, 0.5, false, 1L,
+ Filter(EqualTo(OuterReference(a), b), LocalRelation(b)))().select('b)
+ ),
+ LocalRelation(a))
+ assertAnalysisError(plan5,
+ "Accessing outer query column is not allowed in a TABLESAMPLE" :: Nil)
}
}
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 afed342ff8..52387b4b72 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
@@ -571,4 +571,33 @@ class SubquerySuite extends QueryTest with SharedSQLContext {
Row(1.0, false) :: Row(1.0, false) :: Row(2.0, true) :: Row(2.0, true) ::
Row(3.0, false) :: Row(5.0, true) :: Row(null, false) :: Row(null, true) :: Nil)
}
+
+ test("SPARK-16804: Correlated subqueries containing LIMIT - 1") {
+ withTempView("onerow") {
+ Seq(1).toDF("c1").createOrReplaceTempView("onerow")
+
+ checkAnswer(
+ sql(
+ """
+ | select c1 from onerow t1
+ | where exists (select 1 from onerow t2 where t1.c1=t2.c1)
+ | and exists (select 1 from onerow LIMIT 1)""".stripMargin),
+ Row(1) :: Nil)
+ }
+ }
+
+ test("SPARK-16804: Correlated subqueries containing LIMIT - 2") {
+ withTempView("onerow") {
+ Seq(1).toDF("c1").createOrReplaceTempView("onerow")
+
+ checkAnswer(
+ sql(
+ """
+ | select c1 from onerow t1
+ | where exists (select 1
+ | from (select 1 from onerow t2 LIMIT 1)
+ | where t1.c1=t2.c1)""".stripMargin),
+ Row(1) :: Nil)
+ }
+ }
}