Skip to content

[SPARK-30282][SQL] Migrate SHOW TBLPROPERTIES to new framework #26921

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

Closed
wants to merge 15 commits into from
Closed
2 changes: 2 additions & 0 deletions docs/sql-migration-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,8 @@ license: |

- Since Spark 3.0, `ADD FILE` can be used to add file directories as well. Earlier only single files can be added using this command. To restore the behaviour of earlier versions, set `spark.sql.legacy.addDirectory.recursive` to false.

- Since Spark 3.0, `SHOW TBLPROPERTIES` on a temporary view will cause `AnalysisException`. In Spark version 2.4 and earlier, it returned an empty result.

## Upgrading from Spark SQL 2.4 to 2.4.1

- The value of `spark.executor.heartbeatInterval`, when specified without units like "30" rather than "30s", was
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -820,11 +820,6 @@ class Analyzer(
.map(rel => alter.copy(table = rel))
.getOrElse(alter)

case show @ ShowTableProperties(u: UnresolvedV2Relation, _) =>
CatalogV2Util.loadRelation(u.catalog, u.tableName)
.map(rel => show.copy(table = rel))
.getOrElse(show)

case u: UnresolvedV2Relation =>
CatalogV2Util.loadRelation(u.catalog, u.tableName).getOrElse(u)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,11 +191,6 @@ class ResolveCatalogs(val catalogManager: CatalogManager)

case ShowCurrentNamespaceStatement() =>
ShowCurrentNamespace(catalogManager)

case ShowTablePropertiesStatement(
nameParts @ NonSessionCatalogAndTable(catalog, tbl), propertyKey) =>
val r = UnresolvedV2Relation(nameParts, catalog.asTableCatalog, tbl.asIdentifier)
ShowTableProperties(r, propertyKey)
}

object NonSessionCatalogAndTable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3503,8 +3503,8 @@ class AstBuilder(conf: SQLConf) extends SqlBaseBaseVisitor[AnyRef] with Logging
*/
override def visitShowTblProperties(
ctx: ShowTblPropertiesContext): LogicalPlan = withOrigin(ctx) {
ShowTablePropertiesStatement(
visitMultipartIdentifier(ctx.table),
ShowTableProperties(
UnresolvedTable(visitMultipartIdentifier(ctx.table)),
Option(ctx.key).map(visitTablePropertyKey))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -438,13 +438,6 @@ case class ShowColumnsStatement(
*/
case class ShowCurrentNamespaceStatement() extends ParsedStatement

/**
* A SHOW TBLPROPERTIES statement, as parsed from SQL
*/
case class ShowTablePropertiesStatement(
tableName: Seq[String],
propertyKey: Option[String]) extends ParsedStatement

/**
* A DESCRIBE FUNCTION statement, as parsed from SQL
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -474,8 +474,10 @@ case class ShowCurrentNamespace(catalogManager: CatalogManager) extends Command
* The logical plan of the SHOW TBLPROPERTIES command that works for v2 catalogs.
*/
case class ShowTableProperties(
table: NamedRelation,
propertyKey: Option[String]) extends Command{
table: LogicalPlan,
propertyKey: Option[String]) extends Command {
override def children: Seq[LogicalPlan] = table :: Nil

override val output: Seq[Attribute] = Seq(
AttributeReference("key", StringType, nullable = false)(),
AttributeReference("value", StringType, nullable = false)())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1912,11 +1912,11 @@ class DDLParserSuite extends AnalysisTest {
test("SHOW TBLPROPERTIES table") {
comparePlans(
parsePlan("SHOW TBLPROPERTIES a.b.c"),
ShowTablePropertiesStatement(Seq("a", "b", "c"), None))
ShowTableProperties(UnresolvedTable(Seq("a", "b", "c")), None))

comparePlans(
parsePlan("SHOW TBLPROPERTIES a.b.c('propKey1')"),
ShowTablePropertiesStatement(Seq("a", "b", "c"), Some("propKey1")))
ShowTableProperties(UnresolvedTable(Seq("a", "b", "c")), Some("propKey1")))
}

test("DESCRIBE FUNCTION") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -485,10 +485,8 @@ class ResolveSessionCatalog(
replace,
viewType)

case ShowTablePropertiesStatement(SessionCatalogAndTable(_, tbl), propertyKey) =>
ShowTablePropertiesCommand(
tbl.asTableIdentifier,
propertyKey)
case ShowTableProperties(r: ResolvedTable, propertyKey) if isSessionCatalog(r.catalog) =>
ShowTablePropertiesCommand(r.identifier.asTableIdentifier, propertyKey)

case DescribeFunctionStatement(CatalogAndIdentifier(catalog, ident), extended) =>
val functionIdent =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -900,22 +900,15 @@ case class ShowTablePropertiesCommand(table: TableIdentifier, propertyKey: Optio
}

override def run(sparkSession: SparkSession): Seq[Row] = {
val catalog = sparkSession.sessionState.catalog

if (catalog.isTemporaryTable(table)) {
Seq.empty[Row]
Copy link
Member

@gatorsmile gatorsmile Apr 25, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We allow users to specify the table properties when creating temporary views.

CREATE TEMPORARY VIEW v1
TBLPROPERTIES(prop1 ="3")
AS SELECT 1 AS c1, 2 AS c2

Instead of disallowing it, I think we should support it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure I will create a PR for this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Upon looking at this further, properties specified in CREATE TEMP VIEW is not used in CreateViewCommand, so we can revert the behavior back to the original one where we showed empty properties. What do you think?

I will still create a PR to support a permanent view, which is a regression.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds good to me. please remove the item in the migration guide too.

Thanks!

} else {
val catalogTable = sparkSession.sessionState.catalog.getTableMetadata(table)

propertyKey match {
case Some(p) =>
val propValue = catalogTable
.properties
.getOrElse(p, s"Table ${catalogTable.qualifiedName} does not have property: $p")
Seq(Row(propValue))
case None =>
catalogTable.properties.map(p => Row(p._1, p._2)).toSeq
}
val catalogTable = sparkSession.sessionState.catalog.getTableMetadata(table)
propertyKey match {
case Some(p) =>
val propValue = catalogTable
.properties
.getOrElse(p, s"Table ${catalogTable.qualifiedName} does not have property: $p")
Seq(Row(propValue))
case None =>
catalogTable.properties.map(p => Row(p._1, p._2)).toSeq
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ object DataSourceV2Strategy extends Strategy with PredicateHelper {
case r: ShowCurrentNamespace =>
ShowCurrentNamespaceExec(r.output, r.catalogManager) :: Nil

case r @ ShowTableProperties(DataSourceV2Relation(table, _, _), propertyKey) =>
case r @ ShowTableProperties(ResolvedTable(_, _, table), propertyKey) =>
ShowTablePropertiesExec(r.output, table, propertyKey) :: Nil

case AlterNamespaceSetOwner(ResolvedNamespace(catalog, namespace), name, typ) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,10 @@ class HiveCommandSuite extends QueryTest with SQLTestUtils with TestHiveSingleto
}

test("show tblproperties for datasource table - errors") {
val message1 = intercept[NoSuchTableException] {
val message = intercept[AnalysisException] {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ur, this sounds like another behavior change from Apache Spark 2.4.4.
cc @gatorsmile

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for catching it! I will update the migration guide.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created a follow-up PR: #27276

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

sql("SHOW TBLPROPERTIES badtable")
}.getMessage
assert(message1.contains("Table or view 'badtable' not found in database 'default'"))
assert(message.contains("Table not found: badtable"))

// When key is not found, a row containing the error is returned.
checkAnswer(
Expand All @@ -147,16 +147,18 @@ class HiveCommandSuite extends QueryTest with SQLTestUtils with TestHiveSingleto
checkAnswer(sql("SHOW TBLPROPERTIES parquet_tab2('`prop2Key`')"), Row("prop2Val"))
}

test("show tblproperties for spark temporary table - empty row") {
test("show tblproperties for spark temporary table - AnalysisException is thrown") {
withTempView("parquet_temp") {
sql(
"""
|CREATE TEMPORARY VIEW parquet_temp (c1 INT, c2 STRING)
|USING org.apache.spark.sql.parquet.DefaultSource
""".stripMargin)

// An empty sequence of row is returned for session temporary table.
checkAnswer(sql("SHOW TBLPROPERTIES parquet_temp"), Nil)
val message = intercept[AnalysisException] {
sql("SHOW TBLPROPERTIES parquet_temp")
}.getMessage
assert(message.contains("parquet_temp is a temp view not table"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change LGTM, but can we add a note in the migration guide?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I will add it. Thanks!

}
}

Expand Down