dongjoon-hyun commented on PR #58092:
URL: https://github.com/apache/spark/pull/58092#issuecomment-5348696891

   Thank you for working on this. The motivation is sound: 
`DescribeTableCommand.describePartitionInfo` calls 
`CatalogTable.partitionSchema`, whose `assert` (`interface.scala:475`) makes 
`DESCRIBE TABLE` itself fail on a corrupt table, which is exactly when users 
need to inspect the metadata. However, I think the current patch is broader 
than the actual bug, and it introduces a regression on the JSON path.
   
   ## 1. The JSON path was not broken, and this PR regresses it
   
   In `DescribeRelationJsonCommand`, the only `partitionSchema` call site is 
line 319, inside `describePartitionInfoJson` — the `DESC ... PARTITION AS JSON` 
path that this PR explicitly declares out of scope. `partition_columns` itself 
comes from `CatalogTable.toJsonLinkedHashMap` (`interface.scala:653`), which 
just emits `partitionColumnNames` and never touches the assertion.
   
   So `DESCRIBE TABLE EXTENDED ... AS JSON` already worked fine for corrupt 
partition metadata. This PR now drops `partition_columns` for those tables and 
replaces it with `invalid_partition_information`.
   
   More concretely, consider a legacy table with an empty stored schema. 
`DescribeRelationJsonCommand.run` already handles that case:
   
   ```scala
   val schema = if (metadata.schema.isEmpty) {
     // In older versions of Spark,
     // the table schema can be empty and should be inferred at runtime.
     sparkSession.table(metadata.identifier).schema
   } else { metadata.schema }
   describeColsJson(schema, jsonMap)
   ```
   
   but the new `describeInvalidPartitionInfoJson(metadata, jsonMap)` and the 
`describeFormattedTableInfoJson` filter both read `metadata.schema` (empty) 
rather than the resolved `schema`. `lastSchemaColumns` is then `Nil != 
partitionColumnNames`, so `isValid` is `false` and a perfectly healthy legacy 
table loses `partition_columns` and gains a bogus 
`invalid_partition_information`. That is a new user-facing regression, not a 
fix.
   
   The text path (`tables.scala:686`) has the same blind spot, but there it 
previously threw `AssertionError`, so it is only a misleading-message issue 
rather than a regression.
   
   Suggestion: pass the already-resolved schema into `describePartitionInfo` / 
`describeInvalidPartitionInfoJson` and base `isValid` on it. And since the JSON 
change fixes no bug, consider splitting it out — or at least keeping 
`partition_columns` and adding a flag alongside it, which is safer for JSON 
consumers than removing a documented field.
   
   ## 2. Design: a new output section plus a free-form "Recommendation" sentence
   
   `DESCRIBE` rows are `(col_name, data_type, comment)` tuples, and this puts 
an English sentence into the `data_type` column:
   
   ```scala
   Row("Recommendation", "Repair the catalog metadata so the declared partition 
columns match the last columns in the table schema.", "")
   ```
   
   That is the kind of text that belongs in an error condition, not in a result 
set. Two smaller alternatives worth considering:
   
   1. In `describePartitionInfo`, resolve partition columns by name instead of 
positionally (`takeRight`). Most real corruption cases are ordering mismatches 
and would then render correctly with no new section at all.
   2. Skip the section entirely when the metadata is inconsistent and let `DESC 
EXTENDED`'s existing `Partition Columns` row carry the information. For the 
strict paths (`DESC ... PARTITION`, `SHOW PARTITIONS`, `SHOW CREATE TABLE`), 
replacing the `assert` with a structured error (e.g. the existing 
`INTERNAL_ERROR_METADATA_CATALOG` family) can be a separate follow-up as you 
noted.
   
   If the current approach is kept, please extract the recommendation string 
into a single constant — it is currently duplicated as a literal in 
`tables.scala`, `DescribeRelationJsonCommand.scala`, and the test.
   
   ## 3. `PartitionMetadata` helper
   
   - It is inserted between the `DescribeCommandBase` trait and 
`DescribeTableCommand`'s scaladoc, splitting the two command definitions. 
Placing it next to `DescribeCommandBase` or at the bottom of the file would 
read better.
   - It does not need to be a `case class`; `equals`/`hashCode`/`unapply` are 
unused.
   - `DescribeRelationJsonCommand` constructs `PartitionMetadata(table)` twice 
(in `describeFormattedTableInfoJson` and `describeInvalidPartitionInfoJson`). 
Compute it once and pass it down.
   - The display helpers (`declaredPartitionColumnsDisplay`, `formatColumns`) 
are only used by the text path, so presentation logic is mixed into a shared 
helper.
   - In `describeInvalidPartitionInfoJson`, the 
`declaredPartitionColumns.nonEmpty &&` guard is redundant: when it is empty, 
`isValid` is already `true`.
   
   ## 4. Minor
   
   - `isValid` is an exact string comparison. A Hive catalog that lower-cases 
partition column names could flag a healthy table as invalid. Same semantics as 
the existing `assert`, so not a regression, but a `conf.resolver`-based 
comparison would be more accurate.
   - Docs: the JSON example shows `partition_columns` and 
`invalid_partition_information` side by side although they are mutually 
exclusive. Also, because of `addKeyValueToMap` ordering, 
`invalid_partition_information` actually lands after `schema` near the end of 
the object, not where the example places it.
   - `docs/sql-ref-syntax-aux-describe-table.md:141`: the trailing-whitespace 
removal is unrelated to this change.
   - Tests: the empty-stored-schema case from (1) is not covered; worth adding.
   - The PR description says the regression test was "expanded", but it is a 
newly added test. It also notes the test could not be run locally due to DNS 
failures — please confirm `build/sbt 'sql/testOnly *v1.DescribeTableSuite'` 
passes before merging.
   
   CI on `f4f2eb2` is still in progress (Linters, Precompile, Maven build, 
Docs), with no failures so far.
   
   ## Summary
   
   The core direction — not letting `DESCRIBE TABLE` die on corrupt metadata — 
is right. As written, though, it (a) regresses the JSON path that was never 
broken, and (b) adds a fair amount of new user-facing output surface for a 
corrupt-metadata edge case. I would fix (1) and reconsider the JSON change and 
the "Recommendation" row.
   


-- 
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