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 07086d1a45aa..893afc8984e9 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 @@ -3301,10 +3301,14 @@ class AstBuilder(conf: SQLConf) extends SqlBaseBaseVisitor[AnyRef] with Logging } /** - * Creates a [[ShowCreateTableStatement]] + * Creates a [[ShowCreateTable]] */ override def visitShowCreateTable(ctx: ShowCreateTableContext): LogicalPlan = withOrigin(ctx) { - ShowCreateTableStatement(visitMultipartIdentifier(ctx.multipartIdentifier()), ctx.SERDE != null) + ShowCreateTable( + UnresolvedTableOrView( + visitMultipartIdentifier(ctx.multipartIdentifier()), + allowTempView = false), + ctx.SERDE != null) } /** diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/plans/logical/statements.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/plans/logical/statements.scala index 246e7f3bcb95..2fc56891cd15 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/plans/logical/statements.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/plans/logical/statements.scala @@ -347,13 +347,6 @@ case class UseStatement(isNamespaceSet: Boolean, nameParts: Seq[String]) extends */ case class RepairTableStatement(tableName: Seq[String]) extends ParsedStatement -/** - * A SHOW CREATE TABLE statement, as parsed from SQL. - */ -case class ShowCreateTableStatement( - tableName: Seq[String], - asSerde: Boolean = false) extends ParsedStatement - /** * A CACHE TABLE statement, as parsed from SQL */ diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/plans/logical/v2Commands.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/plans/logical/v2Commands.scala index b5386f504445..c1fc0b69354c 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/plans/logical/v2Commands.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/plans/logical/v2Commands.scala @@ -622,3 +622,10 @@ case class LoadData( partition: Option[TablePartitionSpec]) extends Command { override def children: Seq[LogicalPlan] = child :: Nil } + +/** + * The logical plan of the SHOW CREATE TABLE command. + */ +case class ShowCreateTable(child: LogicalPlan, asSerde: Boolean = false) extends Command { + override def children: Seq[LogicalPlan] = child :: Nil +} diff --git a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/DDLParserSuite.scala b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/DDLParserSuite.scala index 085aaf148c8c..649337a31553 100644 --- a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/DDLParserSuite.scala +++ b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/DDLParserSuite.scala @@ -1632,7 +1632,13 @@ class DDLParserSuite extends AnalysisTest { test("SHOW CREATE table") { comparePlans( parsePlan("SHOW CREATE TABLE a.b.c"), - ShowCreateTableStatement(Seq("a", "b", "c"))) + ShowCreateTable(UnresolvedTableOrView(Seq("a", "b", "c"), allowTempView = false))) + + comparePlans( + parsePlan("SHOW CREATE TABLE a.b.c AS SERDE"), + ShowCreateTable( + UnresolvedTableOrView(Seq("a", "b", "c"), allowTempView = false), + asSerde = true)) } test("CACHE TABLE") { diff --git a/sql/core/src/main/scala/org/apache/spark/sql/catalyst/analysis/ResolveSessionCatalog.scala b/sql/core/src/main/scala/org/apache/spark/sql/catalyst/analysis/ResolveSessionCatalog.scala index 59652229a2b2..ff25272aebb5 100644 --- a/sql/core/src/main/scala/org/apache/spark/sql/catalyst/analysis/ResolveSessionCatalog.scala +++ b/sql/core/src/main/scala/org/apache/spark/sql/catalyst/analysis/ResolveSessionCatalog.scala @@ -434,13 +434,12 @@ class ResolveSessionCatalog( isOverwrite, partition) - case ShowCreateTableStatement(tbl, asSerde) if !asSerde => - val name = parseTempViewOrV1Table(tbl, "SHOW CREATE TABLE") - ShowCreateTableCommand(name.asTableIdentifier) - - case ShowCreateTableStatement(tbl, asSerde) if asSerde => - val v1TableName = parseV1Table(tbl, "SHOW CREATE TABLE AS SERDE") - ShowCreateTableAsSerdeCommand(v1TableName.asTableIdentifier) + case ShowCreateTable(ResolvedV1TableOrViewIdentifier(ident), asSerde) => + if (asSerde) { + ShowCreateTableAsSerdeCommand(ident.asTableIdentifier) + } else { + ShowCreateTableCommand(ident.asTableIdentifier) + } case CacheTableStatement(tbl, plan, isLazy, options) => val name = if (plan.isDefined) { diff --git a/sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/v2/DataSourceV2Strategy.scala b/sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/v2/DataSourceV2Strategy.scala index 5695d232fae5..48fa88ed550b 100644 --- a/sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/v2/DataSourceV2Strategy.scala +++ b/sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/v2/DataSourceV2Strategy.scala @@ -286,6 +286,9 @@ class DataSourceV2Strategy(session: SparkSession) extends Strategy with Predicat case LoadData(_: ResolvedTable, _, _, _, _) => throw new AnalysisException("LOAD DATA is not supported for v2 tables.") + case ShowCreateTable(_: ResolvedTable, _) => + throw new AnalysisException("SHOW CREATE TABLE is not supported for v2 tables.") + case _ => Nil } } diff --git a/sql/core/src/test/scala/org/apache/spark/sql/ShowCreateTableSuite.scala b/sql/core/src/test/scala/org/apache/spark/sql/ShowCreateTableSuite.scala index 1106a787cc9a..7b4c8d1cc71d 100644 --- a/sql/core/src/test/scala/org/apache/spark/sql/ShowCreateTableSuite.scala +++ b/sql/core/src/test/scala/org/apache/spark/sql/ShowCreateTableSuite.scala @@ -155,16 +155,17 @@ abstract class ShowCreateTableSuite extends QueryTest with SQLTestUtils { val ex = intercept[AnalysisException] { sql(s"SHOW CREATE TABLE $viewName") } - assert(ex.getMessage.contains("SHOW CREATE TABLE is not supported on a temporary view")) + assert(ex.getMessage.contains(s"$viewName is a temp view not table or permanent view")) } withGlobalTempView(viewName) { sql(s"CREATE GLOBAL TEMPORARY VIEW $viewName AS SELECT 1 AS a") + val globalTempViewDb = spark.sessionState.catalog.globalTempViewManager.database val ex = intercept[AnalysisException] { - val globalTempViewDb = spark.sessionState.catalog.globalTempViewManager.database sql(s"SHOW CREATE TABLE $globalTempViewDb.$viewName") } - assert(ex.getMessage.contains("SHOW CREATE TABLE is not supported on a temporary view")) + assert(ex.getMessage.contains( + s"$globalTempViewDb.$viewName is a temp view not table or permanent view")) } } diff --git a/sql/core/src/test/scala/org/apache/spark/sql/connector/DataSourceV2SQLSuite.scala b/sql/core/src/test/scala/org/apache/spark/sql/connector/DataSourceV2SQLSuite.scala index dfa32b9ac802..cd318c9335be 100644 --- a/sql/core/src/test/scala/org/apache/spark/sql/connector/DataSourceV2SQLSuite.scala +++ b/sql/core/src/test/scala/org/apache/spark/sql/connector/DataSourceV2SQLSuite.scala @@ -2102,7 +2102,8 @@ class DataSourceV2SQLSuite val t = "testcat.ns1.ns2.tbl" withTable(t) { spark.sql(s"CREATE TABLE $t (id bigint, data string) USING foo") - testV1CommandSupportingTempView("SHOW CREATE TABLE", t) + testNotSupportedV2Command("SHOW CREATE TABLE", t) + testNotSupportedV2Command("SHOW CREATE TABLE", s"$t AS SERDE") } } diff --git a/sql/core/src/test/scala/org/apache/spark/sql/execution/SQLViewSuite.scala b/sql/core/src/test/scala/org/apache/spark/sql/execution/SQLViewSuite.scala index 8889ea177720..f5d6ea929a9a 100644 --- a/sql/core/src/test/scala/org/apache/spark/sql/execution/SQLViewSuite.scala +++ b/sql/core/src/test/scala/org/apache/spark/sql/execution/SQLViewSuite.scala @@ -176,7 +176,7 @@ abstract class SQLViewSuite extends QueryTest with SQLTestUtils { val e3 = intercept[AnalysisException] { sql(s"SHOW CREATE TABLE $viewName") }.getMessage - assert(e3.contains("SHOW CREATE TABLE is not supported on a temporary view")) + assert(e3.contains(s"$viewName is a temp view not table or permanent view")) assertNoSuchTable(s"SHOW PARTITIONS $viewName") val e4 = intercept[AnalysisException] { sql(s"ANALYZE TABLE $viewName COMPUTE STATISTICS")