szehon-ho commented on code in PR #59036:
URL: https://github.com/apache/spark/pull/59036#discussion_r4150555028


##########
sql/catalyst/src/main/scala/org/apache/spark/sql/connector/catalog/CatalogV2Util.scala:
##########
@@ -677,6 +677,12 @@ private[sql] object CatalogV2Util {
     builder
   }
 
+  /** Returns non-reserved table properties with additional display-only 
metadata. */
+  def tablePropertiesForDisplay(table: Table): Map[String, String] = {
+    (table.displayProperties().asScala.toMap ++ table.properties().asScala)

Review Comment:
   Documented that SET/UNSET only changes `properties()` and cannot remove 
catalog-controlled display entries. Extended `ShowTblPropertiesSuite` to check 
unsetting a colliding stored key, unsetting a display-only key, and SET 
followed by UNSET. It also checks that `getTableProperties` returns the display 
value after UNSET while the key is absent from `getCreateTableString`.



##########
sql/catalyst/src/main/java/org/apache/spark/sql/connector/catalog/TableInfo.java:
##########
@@ -59,19 +62,40 @@ public Map<String, String> properties() {
     return properties;
   }
 
+  /**
+   * Returns the additional display-only properties described by {@link 
Table#displayProperties()}.
+   *
+   * @since 4.4.0
+   */
+  public Map<String, String> displayProperties() {

Review Comment:
   Clarified both Javadocs: display properties describe metadata returned by a 
catalog, and Spark leaves them empty when calling `createTable`, 
`createTableLike`, `stageCreate`, `stageReplace`, or `stageCreateOrReplace`. 
Removed the create-time display-property setters from the two in-memory 
catalogs; the preservation test now sets the entries on the live table returned 
by `createTable`.



##########
sql/core/src/test/scala/org/apache/spark/sql/execution/command/v2/DescribeTableSuite.scala:
##########
@@ -220,6 +222,38 @@ class DescribeTableSuite extends 
command.DescribeTableSuiteBase
     }
   }
 
+  gridTest("display properties preserve table type and reserved 
metadata")(Seq(false, true)) {
+      external =>
+    withNamespaceAndTable("ns", "table") { tbl =>
+      sql(s"CREATE TABLE $tbl (id bigint) $defaultUsing " +
+        "COMMENT 'table comment' LOCATION 'file:/tmp/display-properties' " +
+        "TBLPROPERTIES ('persisted' = 'stored')")
+      val table = loadTable(catalog, "ns", "table")
+      if (external) {
+        table.properties.put(TableCatalog.PROP_EXTERNAL, "true")
+      }
+      table.setDisplayProperties(Map(

Review Comment:
   Added a shared fixture in `CommandSuiteBase` that supplies every key in 
`TABLE_RESERVED_PROPERTIES`. Both DESCRIBE and SHOW TABLE EXTENDED now test 
managed/external tables with and without a stored LOCATION. The DESCRIBE 
assertion includes all reserved rows, and SHOW TABLE EXTENDED checks the 
complete output.



##########
sql/catalyst/src/main/java/org/apache/spark/sql/connector/catalog/DelegatingTable.java:
##########
@@ -74,6 +74,11 @@ public Map<String, String> properties() {
     return Collections.unmodifiableMap(info.properties());
   }
 
+  @Override
+  public Map<String, String> displayProperties() {

Review Comment:
   Added an end-to-end test in `DataSourceV2MetadataTableSuite`. Its catalog 
builds `TableInfo` with display properties in `loadTable` and returns a 
`DelegatingTable`. The test exercises DESCRIBE TABLE EXTENDED, SHOW 
TBLPROPERTIES, SHOW TABLE EXTENDED, and `getTableProperties`, and verifies that 
`getCreateTableString` excludes the display-only entry.



##########
sql/core/src/test/scala/org/apache/spark/sql/execution/command/v2/ShowTblPropertiesSuite.scala:
##########
@@ -17,10 +17,35 @@
 
 package org.apache.spark.sql.execution.command.v2
 
+import scala.jdk.CollectionConverters._
+
+import org.apache.spark.sql.Row
+import org.apache.spark.sql.connector.catalog.TableCatalog
 import org.apache.spark.sql.execution.command
 
 /**
  * The class contains tests for the `SHOW TBLPROPERTIES` command to check V2 
table catalogs.
  */
 class ShowTblPropertiesSuite extends command.ShowTblPropertiesSuiteBase with 
CommandSuiteBase {
+  test("display properties supplement current properties and exclude reserved 
keys") {

Review Comment:
   Added a display-only `password` to the shared fixture and asserted 
`*********(redacted)` in DESCRIBE TABLE EXTENDED, SHOW TBLPROPERTIES (including 
single-key lookup), and SHOW TABLE EXTENDED. The catalog API test also verifies 
redaction in `getTableProperties`.



##########
sql/api/src/main/scala/org/apache/spark/sql/catalog/Catalog.scala:
##########
@@ -846,6 +846,10 @@ abstract class Catalog {
   /**
    * Returns all table properties as a map (same as `SHOW TBLPROPERTIES`).
    *
+   * For V2 tables, this also includes the table's display-only properties. 
These entries may be

Review Comment:
   Added the same note to the Connect Scala override. The Scala and PySpark 
docs now state directly that display-only entries may be transient and are 
excluded from the DDL returned by `getCreateTableString`.



##########
sql/catalyst/src/main/java/org/apache/spark/sql/connector/catalog/Table.java:
##########
@@ -95,6 +95,24 @@ default Map<String, String> properties() {
     return Collections.emptyMap();
   }
 
+  /**
+   * Returns additional, display-only table properties.
+   *
+   * <p>Spark adds these entries to the non-reserved properties displayed by 
V2 table metadata

Review Comment:
   Added the specific limitation to `Table.displayProperties()`: for now, SHOW 
TABLE EXTENDED omits these entries for the built-in session catalog and its 
CatalogExtensions. Changing that routing needs separate compatibility work for 
mixed V1/V2 tables and existing V1 output.



##########
sql/catalyst/src/test/scala/org/apache/spark/sql/connector/catalog/InMemoryTableCatalog.scala:
##########
@@ -168,8 +168,11 @@ class BasicInMemoryTableCatalog extends TableCatalog {
   }
 
   override def createTable(ident: Identifier, tableInfo: TableInfo): Table = {
-    createTable(ident, tableInfo.columns(), tableInfo.partitions(), 
tableInfo.properties(),
+    val table = createTable(
+      ident, tableInfo.columns(), tableInfo.partitions(), 
tableInfo.properties(),
       Distributions.unspecified(), Array.empty, None, None, 
tableInfo.constraints())
+    
table.asInstanceOf[InMemoryBaseTable].setDisplayProperties(tableInfo.displayProperties())

Review Comment:
   Removed both create-time setters and the cast from 
`BasicInMemoryTableCatalog`. The Catalyst preservation test now sets display 
properties on the live table returned by `createTable`.



##########
sql/core/src/test/scala/org/apache/spark/sql/execution/command/v2/ShowTblPropertiesSuite.scala:
##########
@@ -17,10 +17,35 @@
 
 package org.apache.spark.sql.execution.command.v2
 
+import scala.jdk.CollectionConverters._
+
+import org.apache.spark.sql.Row
+import org.apache.spark.sql.connector.catalog.TableCatalog
 import org.apache.spark.sql.execution.command
 
 /**
  * The class contains tests for the `SHOW TBLPROPERTIES` command to check V2 
table catalogs.
  */
 class ShowTblPropertiesSuite extends command.ShowTblPropertiesSuiteBase with 
CommandSuiteBase {
+  test("display properties supplement current properties and exclude reserved 
keys") {
+    withNamespaceAndTable("ns", "table") { tbl =>
+      sql(s"CREATE TABLE $tbl (id bigint) $defaultUsing " +
+        "TBLPROPERTIES ('persisted' = 'stored')")
+      loadTable(catalog, "ns", "table").setDisplayProperties(Map(
+        "catalog-label" -> "catalog-value",
+        "persisted" -> "display-value",
+        TableCatalog.PROP_EXTERNAL -> "true",
+        TableCatalog.PROP_LOCATION -> "file:/display-location").asJava)
+
+      checkAnswer(sql(s"SHOW TBLPROPERTIES $tbl"),
+        Seq(Row("catalog-label", "catalog-value"), Row("persisted", "stored")))
+      checkAnswer(sql(s"SHOW TBLPROPERTIES $tbl ('persisted')"), 
Row("persisted", "stored"))
+      checkAnswer(sql(s"SHOW TBLPROPERTIES $tbl ('catalog-label')"),
+        Row("catalog-label", "catalog-value"))
+
+      sql(s"ALTER TABLE $tbl SET TBLPROPERTIES ('persisted' = 'updated')")

Review Comment:
   Added `setDisplayProperties(table.displayProperties())` when the 
session-catalog fixture reconstructs a table. A new regression test checks SHOW 
TBLPROPERTIES and DESCRIBE TABLE EXTENDED after SET, and that the display entry 
survives a subsequent UNSET.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to