Skip to content

Commit 848bdfa

Browse files
planga82dongjoon-hyun
authored andcommitted
[SPARK-29829][SQL] SHOW TABLE EXTENDED should do multi-catalog resolution
### What changes were proposed in this pull request? Add ShowTableStatement and make SHOW TABLE EXTENDED go through the same catalog/table resolution framework of v2 commands. We don’t have this methods in the catalog to implement an V2 command - catalog.getPartition - catalog.getTempViewOrPermanentTableMetadata ### Why are the changes needed? It's important to make all the commands have the same table resolution behavior, to avoid confusing ```sql USE my_catalog DESC t // success and describe the table t from my_catalog SHOW TABLE EXTENDED FROM LIKE 't' // report table not found as there is no table t in the session catalog ``` ### Does this PR introduce any user-facing change? Yes. When running SHOW TABLE EXTENDED Spark fails the command if the current catalog is set to a v2 catalog, or the table name specified a v2 catalog. ### How was this patch tested? Unit tests. Closes apache#26540 from planga82/feature/SPARK-29481_ShowTableExtended. Authored-by: Pablo Langa <[email protected]> Signed-off-by: Dongjoon Hyun <[email protected]>
1 parent 1521889 commit 848bdfa

File tree

7 files changed

+98
-18
lines changed

7 files changed

+98
-18
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
@@ -187,7 +187,7 @@ statement
187187
statement #explain
188188
| SHOW TABLES ((FROM | IN) multipartIdentifier)?
189189
(LIKE? pattern=STRING)? #showTables
190-
| SHOW TABLE EXTENDED ((FROM | IN) db=errorCapturingIdentifier)?
190+
| SHOW TABLE EXTENDED ((FROM | IN) namespace=multipartIdentifier)?
191191
LIKE pattern=STRING partitionSpec? #showTable
192192
| SHOW TBLPROPERTIES table=multipartIdentifier
193193
('(' key=tablePropertyKey ')')? #showTblProperties

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2719,6 +2719,16 @@ class AstBuilder(conf: SQLConf) extends SqlBaseBaseVisitor[AnyRef] with Logging
27192719
Option(ctx.pattern).map(string))
27202720
}
27212721

2722+
/**
2723+
* Create a [[ShowTableStatement]] command.
2724+
*/
2725+
override def visitShowTable(ctx: ShowTableContext): LogicalPlan = withOrigin(ctx) {
2726+
ShowTableStatement(
2727+
Option(ctx.namespace).map(visitMultipartIdentifier),
2728+
string(ctx.pattern),
2729+
Option(ctx.partitionSpec).map(visitNonOptionalPartitionSpec))
2730+
}
2731+
27222732
/**
27232733
* Parse new column info from ADD COLUMN into a QualifiedColType.
27242734
*/

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,15 @@ case class InsertIntoStatement(
313313
case class ShowTablesStatement(namespace: Option[Seq[String]], pattern: Option[String])
314314
extends ParsedStatement
315315

316+
/**
317+
* A SHOW TABLE EXTENDED statement, as parsed from SQL.
318+
*/
319+
case class ShowTableStatement(
320+
namespace: Option[Seq[String]],
321+
pattern: String,
322+
partitionSpec: Option[TablePartitionSpec])
323+
extends ParsedStatement
324+
316325
/**
317326
* A CREATE NAMESPACE statement, as parsed from SQL.
318327
*/

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,6 +1022,31 @@ class DDLParserSuite extends AnalysisTest {
10221022
ShowTablesStatement(Some(Seq("tbl")), Some("*dog*")))
10231023
}
10241024

1025+
test("show table extended") {
1026+
comparePlans(
1027+
parsePlan("SHOW TABLE EXTENDED LIKE '*test*'"),
1028+
ShowTableStatement(None, "*test*", None))
1029+
comparePlans(
1030+
parsePlan("SHOW TABLE EXTENDED FROM testcat.ns1.ns2 LIKE '*test*'"),
1031+
ShowTableStatement(Some(Seq("testcat", "ns1", "ns2")), "*test*", None))
1032+
comparePlans(
1033+
parsePlan("SHOW TABLE EXTENDED IN testcat.ns1.ns2 LIKE '*test*'"),
1034+
ShowTableStatement(Some(Seq("testcat", "ns1", "ns2")), "*test*", None))
1035+
comparePlans(
1036+
parsePlan("SHOW TABLE EXTENDED LIKE '*test*' PARTITION(ds='2008-04-09', hr=11)"),
1037+
ShowTableStatement(None, "*test*", Some(Map("ds" -> "2008-04-09", "hr" -> "11"))))
1038+
comparePlans(
1039+
parsePlan("SHOW TABLE EXTENDED FROM testcat.ns1.ns2 LIKE '*test*' " +
1040+
"PARTITION(ds='2008-04-09')"),
1041+
ShowTableStatement(Some(Seq("testcat", "ns1", "ns2")), "*test*",
1042+
Some(Map("ds" -> "2008-04-09"))))
1043+
comparePlans(
1044+
parsePlan("SHOW TABLE EXTENDED IN testcat.ns1.ns2 LIKE '*test*' " +
1045+
"PARTITION(ds='2008-04-09')"),
1046+
ShowTableStatement(Some(Seq("testcat", "ns1", "ns2")), "*test*",
1047+
Some(Map("ds" -> "2008-04-09"))))
1048+
}
1049+
10251050
test("create namespace -- backward compatibility with DATABASE/DBPROPERTIES") {
10261051
val expected = CreateNamespaceStatement(
10271052
Seq("a", "b", "c"),

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,15 @@ class ResolveSessionCatalog(
301301
case ShowTablesStatement(None, pattern) if isSessionCatalog(currentCatalog) =>
302302
ShowTablesCommand(None, pattern)
303303

304+
case ShowTableStatement(namespace, pattern, partitionsSpec) =>
305+
val db = namespace match {
306+
case Some(namespace) if namespace.length != 1 =>
307+
throw new AnalysisException(
308+
s"The database name is not valid: ${namespace.quoted}")
309+
case _ => namespace.map(_.head)
310+
}
311+
ShowTablesCommand(db, Some(pattern), true, partitionsSpec)
312+
304313
case AnalyzeTableStatement(tableName, partitionSpec, noScan) =>
305314
val v1TableName = parseV1Table(tableName, "ANALYZE TABLE")
306315
if (partitionSpec.isEmpty) {

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
@@ -89,23 +89,6 @@ class SparkSqlAstBuilder(conf: SQLConf) extends AstBuilder(conf) {
8989
ResetCommand
9090
}
9191

92-
/**
93-
* Create a [[ShowTablesCommand]] logical plan.
94-
* Example SQL :
95-
* {{{
96-
* SHOW TABLE EXTENDED [(IN|FROM) database_name] LIKE 'identifier_with_wildcards'
97-
* [PARTITION(partition_spec)];
98-
* }}}
99-
*/
100-
override def visitShowTable(ctx: ShowTableContext): LogicalPlan = withOrigin(ctx) {
101-
val partitionSpec = Option(ctx.partitionSpec).map(visitNonOptionalPartitionSpec)
102-
ShowTablesCommand(
103-
Option(ctx.db).map(_.getText),
104-
Option(ctx.pattern).map(string),
105-
isExtended = true,
106-
partitionSpec = partitionSpec)
107-
}
108-
10992
/**
11093
* Create a [[RefreshResource]] logical plan.
11194
*/

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

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,50 @@ class DataSourceV2SQLSuite
766766
assert(expected === df.collect())
767767
}
768768

769+
test("SHOW TABLE EXTENDED not valid v1 database") {
770+
def testV1CommandNamespace(sqlCommand: String, namespace: String): Unit = {
771+
val e = intercept[AnalysisException] {
772+
sql(sqlCommand)
773+
}
774+
assert(e.message.contains(s"The database name is not valid: ${namespace}"))
775+
}
776+
777+
val namespace = "testcat.ns1.ns2"
778+
val table = "tbl"
779+
withTable(s"$namespace.$table") {
780+
sql(s"CREATE TABLE $namespace.$table (id bigint, data string) " +
781+
s"USING foo PARTITIONED BY (id)")
782+
783+
testV1CommandNamespace(s"SHOW TABLE EXTENDED FROM $namespace LIKE 'tb*'",
784+
namespace)
785+
testV1CommandNamespace(s"SHOW TABLE EXTENDED IN $namespace LIKE 'tb*'",
786+
namespace)
787+
testV1CommandNamespace("SHOW TABLE EXTENDED " +
788+
s"FROM $namespace LIKE 'tb*' PARTITION(id=1)",
789+
namespace)
790+
testV1CommandNamespace("SHOW TABLE EXTENDED " +
791+
s"IN $namespace LIKE 'tb*' PARTITION(id=1)",
792+
namespace)
793+
}
794+
}
795+
796+
test("SHOW TABLE EXTENDED valid v1") {
797+
val expected = Seq(Row("", "source", true), Row("", "source2", true))
798+
val schema = new StructType()
799+
.add("database", StringType, nullable = false)
800+
.add("tableName", StringType, nullable = false)
801+
.add("isTemporary", BooleanType, nullable = false)
802+
.add("information", StringType, nullable = false)
803+
804+
val df = sql("SHOW TABLE EXTENDED FROM default LIKE '*source*'")
805+
val result = df.collect()
806+
val resultWithoutInfo = result.map{ case Row(db, table, temp, _) => Row(db, table, temp)}
807+
808+
assert(df.schema === schema)
809+
assert(resultWithoutInfo === expected)
810+
result.foreach{ case Row(_, _, _, info: String) => assert(info.nonEmpty)}
811+
}
812+
769813
test("CreateNameSpace: basic tests") {
770814
// Session catalog is used.
771815
withNamespace("ns") {

0 commit comments

Comments
 (0)