Skip to content

Commit 003ab44

Browse files
committed
[SPARK-29539][SQL] SHOW PARTITIONS should look up catalog/table like v2 commands
1 parent f4d5aa4 commit 003ab44

File tree

8 files changed

+71
-40
lines changed

8 files changed

+71
-40
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
@@ -194,7 +194,7 @@ statement
194194
('(' key=tablePropertyKey ')')? #showTblProperties
195195
| SHOW COLUMNS (FROM | IN) tableIdentifier
196196
((FROM | IN) db=errorCapturingIdentifier)? #showColumns
197-
| SHOW PARTITIONS tableIdentifier partitionSpec? #showPartitions
197+
| SHOW PARTITIONS multipartIdentifier partitionSpec? #showPartitions
198198
| SHOW identifier? FUNCTIONS
199199
(LIKE? (qualifiedName | pattern=STRING))? #showFunctions
200200
| SHOW CREATE TABLE tableIdentifier #showCreateTable

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2728,4 +2728,21 @@ class AstBuilder(conf: SQLConf) extends SqlBaseBaseVisitor[AnyRef] with Logging
27282728
override def visitRepairTable(ctx: RepairTableContext): LogicalPlan = withOrigin(ctx) {
27292729
RepairTableStatement(visitMultipartIdentifier(ctx.multipartIdentifier()))
27302730
}
2731+
2732+
/**
2733+
* A command for users to list the partition names of a table. If partition spec is specified,
2734+
* partitions that match the spec are returned. Otherwise an empty result set is returned.
2735+
*
2736+
* This function creates a [[ShowPartitionsStatement]] logical plan
2737+
*
2738+
* The syntax of using this command in SQL is:
2739+
* {{{
2740+
* SHOW PARTITIONS multi_part_name [partition_spec];
2741+
* }}}
2742+
*/
2743+
override def visitShowPartitions(ctx: ShowPartitionsContext): LogicalPlan = withOrigin(ctx) {
2744+
val table = visitMultipartIdentifier(ctx.multipartIdentifier)
2745+
val partitionKeys = Option(ctx.partitionSpec).map(visitNonOptionalPartitionSpec)
2746+
ShowPartitionsStatement(table, partitionKeys)
2747+
}
27312748
}

sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/plans/logical/statements.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,3 +316,9 @@ case class AnalyzeColumnStatement(
316316
* A REPAIR TABLE statement, as parsed from SQL
317317
*/
318318
case class RepairTableStatement(tableName: Seq[String]) extends ParsedStatement
319+
320+
/**
321+
* A SHOW PARTITIONS statement, as parsed from SQL
322+
*/
323+
case class ShowPartitionsStatement(tableName: Seq[String],
324+
partitionSpec: Option[TablePartitionSpec]) extends ParsedStatement

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -961,6 +961,24 @@ class DDLParserSuite extends AnalysisTest {
961961
RepairTableStatement(Seq("a", "b", "c")))
962962
}
963963

964+
test("SHOW PARTITIONS") {
965+
val sql1 = "SHOW PARTITIONS t1"
966+
val sql2 = "SHOW PARTITIONS db1.t1"
967+
val sql3 = "SHOW PARTITIONS t1 PARTITION(partcol1='partvalue', partcol2='partvalue')"
968+
969+
val parsed1 = parsePlan(sql1)
970+
val expected1 = ShowPartitionsStatement(Seq("t1"), None)
971+
val parsed2 = parsePlan(sql2)
972+
val expected2 = ShowPartitionsStatement(Seq("db1", "t1"), None)
973+
val parsed3 = parsePlan(sql3)
974+
val expected3 = ShowPartitionsStatement(Seq("t1"),
975+
Some(Map("partcol1" -> "partvalue", "partcol2" -> "partvalue")))
976+
977+
comparePlans(parsed1, expected1)
978+
comparePlans(parsed2, expected2)
979+
comparePlans(parsed3, expected3)
980+
}
981+
964982
private case class TableSpec(
965983
name: Seq[String],
966984
schema: Option[StructType],

sql/core/src/main/scala/org/apache/spark/sql/catalyst/analysis/ResolveSessionCatalog.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import org.apache.spark.sql.catalyst.plans.logical._
2424
import org.apache.spark.sql.catalyst.rules.Rule
2525
import org.apache.spark.sql.connector.catalog.{CatalogManager, CatalogPlugin, LookupCatalog, TableChange, V1Table}
2626
import org.apache.spark.sql.connector.expressions.Transform
27-
import org.apache.spark.sql.execution.command.{AlterTableAddColumnsCommand, AlterTableRecoverPartitionsCommand, AlterTableSetLocationCommand, AlterTableSetPropertiesCommand, AlterTableUnsetPropertiesCommand, AnalyzeColumnCommand, AnalyzePartitionCommand, AnalyzeTableCommand, DescribeColumnCommand, DescribeTableCommand, DropTableCommand, ShowTablesCommand}
27+
import org.apache.spark.sql.execution.command.{AlterTableAddColumnsCommand, AlterTableRecoverPartitionsCommand, AlterTableSetLocationCommand, AlterTableSetPropertiesCommand, AlterTableUnsetPropertiesCommand, AnalyzeColumnCommand, AnalyzePartitionCommand, AnalyzeTableCommand, DescribeColumnCommand, DescribeTableCommand, DropTableCommand, ShowPartitionsCommand, ShowTablesCommand}
2828
import org.apache.spark.sql.execution.datasources.{CreateTable, DataSource}
2929
import org.apache.spark.sql.execution.datasources.v2.FileDataSourceV2
3030
import org.apache.spark.sql.internal.SQLConf
@@ -282,6 +282,12 @@ class ResolveSessionCatalog(
282282
AlterTableRecoverPartitionsCommand(
283283
v1TableName.asTableIdentifier,
284284
"MSCK REPAIR TABLE")
285+
286+
case ShowPartitionsStatement(tableName, partitionSpec) =>
287+
val v1TableName = parseV1Table(tableName, "SHOW PARTITIONS")
288+
ShowPartitionsCommand(
289+
v1TableName.asTableIdentifier,
290+
partitionSpec)
285291
}
286292

287293
private def parseV1Table(tableName: Seq[String], sql: String): Seq[String] = {

sql/core/src/main/scala/org/apache/spark/sql/execution/SparkSqlParser.scala

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -135,23 +135,6 @@ class SparkSqlAstBuilder(conf: SQLConf) extends AstBuilder(conf) {
135135
ShowColumnsCommand(Option(ctx.db).map(_.getText), visitTableIdentifier(ctx.tableIdentifier))
136136
}
137137

138-
/**
139-
* A command for users to list the partition names of a table. If partition spec is specified,
140-
* partitions that match the spec are returned. Otherwise an empty result set is returned.
141-
*
142-
* This function creates a [[ShowPartitionsCommand]] logical plan
143-
*
144-
* The syntax of using this command in SQL is:
145-
* {{{
146-
* SHOW PARTITIONS table_identifier [partition_spec];
147-
* }}}
148-
*/
149-
override def visitShowPartitions(ctx: ShowPartitionsContext): LogicalPlan = withOrigin(ctx) {
150-
val table = visitTableIdentifier(ctx.tableIdentifier)
151-
val partitionKeys = Option(ctx.partitionSpec).map(visitNonOptionalPartitionSpec)
152-
ShowPartitionsCommand(table, partitionKeys)
153-
}
154-
155138
/**
156139
* Creates a [[ShowCreateTableCommand]]
157140
*/

sql/core/src/test/scala/org/apache/spark/sql/connector/DataSourceV2SQLSuite.scala

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,6 +1210,28 @@ class DataSourceV2SQLSuite
12101210
}
12111211
}
12121212

1213+
test("SHOW PARTITIONS") {
1214+
val t = "testcat.ns1.ns2.tbl"
1215+
withTable(t) {
1216+
sql(
1217+
s"""
1218+
|CREATE TABLE $t (id bigint, data string)
1219+
|USING foo
1220+
|PARTITIONED BY (id)
1221+
""".stripMargin)
1222+
1223+
val e1 = intercept[AnalysisException] {
1224+
val partition = sql(s"SHOW PARTITIONS $t")
1225+
}
1226+
assert(e1.message.contains("SHOW PARTITIONS is only supported with v1 tables"))
1227+
1228+
val e2 = intercept[AnalysisException] {
1229+
val partition2 = sql(s"SHOW PARTITIONS $t PARTITION(id='1')")
1230+
}
1231+
assert(e2.message.contains("SHOW PARTITIONS is only supported with v1 tables"))
1232+
}
1233+
}
1234+
12131235
private def assertAnalysisError(sqlStatement: String, expectedError: String): Unit = {
12141236
val errMsg = intercept[AnalysisException] {
12151237
sql(sqlStatement)

sql/core/src/test/scala/org/apache/spark/sql/execution/command/DDLParserSuite.scala

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -870,27 +870,6 @@ class DDLParserSuite extends AnalysisTest with SharedSparkSession {
870870
comparePlans(parsed4, expected4)
871871
}
872872

873-
874-
test("show partitions") {
875-
val sql1 = "SHOW PARTITIONS t1"
876-
val sql2 = "SHOW PARTITIONS db1.t1"
877-
val sql3 = "SHOW PARTITIONS t1 PARTITION(partcol1='partvalue', partcol2='partvalue')"
878-
879-
val parsed1 = parser.parsePlan(sql1)
880-
val expected1 =
881-
ShowPartitionsCommand(TableIdentifier("t1", None), None)
882-
val parsed2 = parser.parsePlan(sql2)
883-
val expected2 =
884-
ShowPartitionsCommand(TableIdentifier("t1", Some("db1")), None)
885-
val expected3 =
886-
ShowPartitionsCommand(TableIdentifier("t1", None),
887-
Some(Map("partcol1" -> "partvalue", "partcol2" -> "partvalue")))
888-
val parsed3 = parser.parsePlan(sql3)
889-
comparePlans(parsed1, expected1)
890-
comparePlans(parsed2, expected2)
891-
comparePlans(parsed3, expected3)
892-
}
893-
894873
test("support for other types in DBPROPERTIES") {
895874
val sql =
896875
"""

0 commit comments

Comments
 (0)