voonhous commented on code in PR #19808:
URL: https://github.com/apache/hudi/pull/19808#discussion_r3911181843


##########
hudi-spark-datasource/hudi-spark-common/src/test/scala/org/apache/spark/sql/execution/datasources/parquet/TestParquetSchemaEvolutionUtils.scala:
##########
@@ -199,6 +201,71 @@ class TestParquetSchemaEvolutionUtils {
   private def footerOf(column: Type): FileMetaData =
     new FileMetaData(Types.buildMessage().addField(column).named("test"), new 
HashMap[String, String](), "test")
 
+  /**
+   * The Spark 3.x shape: no VariantType there, so a variant column is 
declared as
+   * struct<value: binary, metadata: binary> (the shape Hive sync also 
writes). Either member
+   * order is the same column, and the unshredded twin of the same file must 
still read.
+   */
+  @Test
+  def testValidateNoShreddedVariantStructsRejectsTopLevelShreddedVariant(): 
Unit = {

Review Comment:
   Added `Test Backward Compatibility: Shredded Variant Table Read Fails Fast 
in Spark 3.x` to `TestVariantDataType`: the compat struct DDL pointed at 
`variant_shredded_mixed_cow.zip`, asserting the guard's own message rather than 
any failure naming the column, for both `select id, v` and the pruned `select 
id, v.value`.
   



##########
hudi-spark-datasource/hudi-spark3.5.x/src/main/scala/org/apache/spark/sql/execution/datasources/parquet/Spark35ParquetReader.scala:
##########
@@ -117,6 +117,11 @@ class Spark35ParquetReader(enableVectorizedReader: Boolean,
     }
 
     val footerFileMetaData = fileFooter.getFileMetaData
+    // A variant column is declared as its unshredded struct shape on Spark 
3.x (no VariantType);
+    // reject a file that shreds it here, before the reader is built, so the 
read fails naming the
+    // column instead of projecting the group by name and returning a null 
value for every
+    // shredded row.
+    
ParquetSchemaEvolutionUtils.validateNoShreddedVariantStructs(requiredSchema, 
footerFileMetaData)

Review Comment:
   Confirmed - `HoodieSparkParquetReader.getUnsafeRowIterator` builds its 
reader on whatever `SparkAdapter.createParquetReadSupport` returns, and Spark 
3.x got the plain one, so a shredded variant in a log block met no guard.
   
   Took the adapter route: `BaseSpark3Adapter` now returns 
`Spark3HoodieParquetReadSupport`, whose `init` runs the guard against 
`context.getFileSchema` and the catalyst request from 
`SPARK_ROW_REQUESTED_SCHEMA`. The file schema rather than the requested one, 
because a Spark 3.x request asks for the binary members alone, so typed_value 
has already been clipped from the requested schema by that point. 
`validateNoShreddedVariantStructs` now takes a `MessageType` so the reader call 
sites and this one share the same walk.
   



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

Reply via email to