-
Notifications
You must be signed in to change notification settings - Fork 29.2k
[SPARK-20690][SQL] Subqueries in FROM should have alias names #17935
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
c079946
51aafde
c19cbbb
a904214
1e25926
307ca1d
1e595b2
9ec0414
9b117f4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -798,14 +798,26 @@ case class LocalLimit(limitExpr: Expression, child: LogicalPlan) extends UnaryNo | |
| } | ||
| } | ||
|
|
||
| object SubqueryAlias { | ||
| def apply(alias: String, child: LogicalPlan): SubqueryAlias = SubqueryAlias(Some(alias), child) | ||
| def apply(child: LogicalPlan): SubqueryAlias = SubqueryAlias(None, child) | ||
| } | ||
|
|
||
| /** | ||
| * Aliased subquery. | ||
| * | ||
| * @param alias the alias name for this subquery. If `None` is given, the `output` will have | ||
| * empty qualifier. | ||
| * @param child the LogicalPlan | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: |
||
| */ | ||
| case class SubqueryAlias( | ||
| alias: String, | ||
| alias: Option[String], | ||
| child: LogicalPlan) | ||
| extends UnaryNode { | ||
|
|
||
| override lazy val canonicalized: LogicalPlan = child.canonicalized | ||
|
|
||
| override def output: Seq[Attribute] = child.output.map(_.withQualifier(Some(alias))) | ||
| override def output: Seq[Attribute] = child.output.map(_.withQualifier(alias)) | ||
| } | ||
|
|
||
| /** | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -655,7 +655,7 @@ class SubquerySuite extends QueryTest with SharedSQLContext { | |
| """ | ||
| | select c1 from onerow t1 | ||
| | where exists (select 1 | ||
| | from (select 1 from onerow t2 LIMIT 1) | ||
| | from (select 1 as c1 from onerow t2 LIMIT 1) t2 | ||
| | where t1.c1=t2.c1)""".stripMargin), | ||
| Row(1) :: Nil) | ||
| } | ||
|
|
@@ -868,6 +868,29 @@ class SubquerySuite extends QueryTest with SharedSQLContext { | |
| Row(3, 3.0, 2, 3.0) :: Row(3, 3.0, 2, 3.0) :: Nil) | ||
| } | ||
|
|
||
| test("SPARK-20690: Do not add missing attributes through subqueries") { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do we still need this test? I think it's all covered by the parser test
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. We can remove this. |
||
| withTempView("onerow") { | ||
| Seq(1).toDF("c1").createOrReplaceTempView("onerow") | ||
|
|
||
| val e = intercept[AnalysisException] { | ||
| sql( | ||
| """ | ||
| | select 1 | ||
| | from (select 1 from onerow t1 LIMIT 1) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm surprised we support this syntax, I think the FROM clause must have an alias. I checked with postgres, it will throw exception
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. mysql:
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. https://cwiki.apache.org/confluence/display/Hive/LanguageManual+SubQueries
Hive also requires an alias name.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. https://docs.oracle.com/cd/E17952_01/mysql-5.1-en/from-clause-subqueries.html
Oracle also requires it.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cc @hvanhovell shall we change the parser? I think it's hard to reason about the semantic of an anonymous subquery
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, in this change I remove qualifier after an anonymous subquery. Not sure if it is what we always want.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should change the parser and require alias for subquery.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, this seems confusing. Subqueries should be have an alias. Let's try to add that. |
||
| | where t1.c1=1""".stripMargin) | ||
| } | ||
| assert(e.message.contains("cannot resolve '`t1.c1`'")) | ||
|
|
||
| checkAnswer( | ||
| sql( | ||
| """ | ||
| | select 1 | ||
| | from (select 1 as c1 from onerow t1 LIMIT 1) t2 | ||
| | where t2.c1=1""".stripMargin), | ||
| Row(1) :: Nil) | ||
| } | ||
| } | ||
|
|
||
| test("SPARK-20688: correctly check analysis for scalar sub-queries") { | ||
| withTempView("t") { | ||
| Seq(1 -> "a").toDF("i", "j").createTempView("t") | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only added for
Filter? How aboutSortin the same rule?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure.