You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hudi.apache.org by "voonhous (via GitHub)" <gi...@apache.org> on 2026/10/13 13:47:51 UTC

[I] Shredded variant COW upsert fails on DECIMAL leaf: Avro fixed/record name collision on typed_value [hudi]

voonhous opened a new issue, #20307:
URL: https://github.com/apache/hudi/issues/20307

   **Describe the problem you faced**
   
   A COW upsert fails when the base file holds a shredded variant column with at least one DECIMAL-typed shredded leaf. The bulk_insert that writes the shredded file succeeds and Spark reads it back correctly; the merge that rewrites the file group fails in the Avro read path with
   
   ```
   org.apache.hudi.exception.HoodieUpsertException: Failed to compact file group: 6213365d-...
     at org.apache.hudi.io.FileGroupReaderBasedMergeHandle.doMerge(FileGroupReaderBasedMergeHandle.java:337)
   Caused by: org.apache.hudi.exception.HoodieException: unable to read next record from parquet file
     at org.apache.hudi.common.util.ParquetReaderIterator.hasNext(ParquetReaderIterator.java:65)
     ...
     at org.apache.hudi.io.FileGroupReaderBasedMergeHandle.doMerge(FileGroupReaderBasedMergeHandle.java:297)
   Caused by: org.apache.hudi.exception.HoodieAvroSchemaException: Failed to parse schema: {"type":"record","name":"hudi_record",...
     at org.apache.hudi.common.schema.HoodieSchema$Parser.parse(HoodieSchema.java:1713)
     at org.apache.hudi.common.schema.HoodieSchema.parse(HoodieSchema.java:375)
     at org.apache.parquet.avro.HoodieAvroReadSupport.init(HoodieAvroReadSupport.java:90)
   Caused by: org.apache.avro.AvroTypeException: Undefined schema: k102.typed_value
     at org.apache.avro.util.SchemaResolver$ResolvingVisitor.visitNonTerminal(SchemaResolver.java:187)
     ...
     at org.apache.avro.Schema$Parser.parse(Schema.java:1516)
   ```
   
   Any JSON number with a fractional part is enough to hit this: `parse_json('{"a":1.5}')` stores the value as a decimal, and the inferred shredding schema writes it as `fixed_len_byte_array(8) typed_value (DECIMAL(18,12))`. Unshredded variant columns, and shredded columns whose leaves are all string/int/long/boolean/array, upsert fine.
   
   **Cause**
   
   `HoodieAvroParquetReader.getIndexedRecordIteratorInternal` reads a shredded base file in its shredded shape (`HoodieVariantReconstruction.intermediateSchema()`, from #18938). That schema is built by `VariantSchemaUtils.toShreddedReadSchema(requestedSchema, fileSchema)`, where `fileSchema` is the parquet footer converted by parquet-avro's `AvroSchemaConverter` (`NativeAvroSchemaConverter.java:41`).
   
   parquet-avro names the Avro `fixed` for a DECIMAL `fixed_len_byte_array` leaf after its parquet field, so the leaf becomes a `fixed` called `typed_value`. The enclosing shredded group also converts to a `record` called `typed_value`. Two named types now share the fullname `typed_value`.
   
   The reader then calls `AvroReadSupport.setRequestedProjection(conf, schema.toAvroSchema())` (`HoodieAvroParquetReader.java:199` and `:203`), which stores `schema.toString()`. Avro's `toString` writes each named type once and emits later occurrences as a bare name reference. `HoodieAvroReadSupport.init` re-parses that string (`HoodieAvroReadSupport.java:90`); the bare `"typed_value"` under key `k10` is resolved in that record's namespace (`k102`, from parquet-avro's duplicate-name suffixing), where nothing is defined.
   
   Where the enclosing namespace happens to be the empty one, the same reference resolves to the `typed_value` record instead of the fixed, so the non-throwing form of this is a silent wrong type rather than a failure.
   
   The dumped schema string shows the shape; the DECIMAL leaves are the only ones emitted as references:
   
   ```
   {"name":"k10","type":{"type":"record","name":"k10","namespace":"k102","fields":[
     {"name":"value","type":["null","bytes"],"default":null},
     {"name":"typed_value","type":["null","typed_value"],"default":null}]}}
   ```
   
   No `fixed` named `typed_value` is defined anywhere in the string.
   
   **To Reproduce**
   
   Verified on master `a41f6ea` with the `-Pspark4.1` bundle (Spark 4.1.1, Scala 2.13), COW, Spark datasource writes, default configs (`hoodie.parquet.variant.write.shredding.enabled=true`, inference on):
   
   1. bulk_insert a DataFrame with a `payload` column produced by `parse_json` over JSON documents that contain at least one number with a fractional part, e.g. `{"k3": 0.4375, "k7": "x"}`.
   2. upsert a batch that updates some of those keys.
   
   Step 2 fails every time with the trace above. The same input with `hoodie.parquet.variant.write.shredding.enabled=false` on both writes succeeds, and a Spark read of the table written by step 1 returns the correct rows and `variant_get` values.
   
   A one-row SQL form (`insert ... parse_json('{"a":1.5}')` then `update`) is expected to reproduce it as well; the verified run used a 20000-row generated workload.
   
   **Expected behavior**
   
   The upsert succeeds and the merged file keeps the shredded layout (or any layout, as long as the values round-trip).
   
   **Environment Description**
   
   * Hudi version : 1.3.0-SNAPSHOT (master `a41f6ea`)
   * Spark version : 4.1.1
   * Storage : local filesystem
   * Table type : COPY_ON_WRITE
   
   **Additional context**
   
   Existing shredded-variant coverage (`TestVariantShreddingMixedLayouts`, `TestVariantDataType`) only uses integer and string leaves, which is why the Avro-path merge never saw a `fixed` leaf. MOR compaction reads base files through the same reader and is probably affected too; not run.
   
   Fix options: give the DECIMAL `fixed` a path-unique name during footer conversion, or stop round-tripping the projection schema through `toString` in `HoodieAvroParquetReader`.
   
   Related: #18938 (shredded base files through the Avro reader), #18961 (per-file shredding inference on by default, which makes the DECIMAL leaf appear without a forced schema).
   


-- 
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: commits-unsubscribe@hudi.apache.org.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [I] Shredded variant COW upsert fails on DECIMAL leaf: Avro fixed/record name collision on typed_value [hudi]

Posted by "voonhous (via GitHub)" <gi...@apache.org>.
voonhous commented on issue #20307:
URL: https://github.com/apache/hudi/issues/20307#issuecomment-6148001844

   This is required for unblocking lake-loader benchmarking.
   
   I will first need to see why the avro format here is causing issues and if this issue has knock on effects elsewhere. 


-- 
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: commits-unsubscribe@hudi.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [I] Shredded variant COW upsert fails on DECIMAL leaf: Avro fixed/record name collision on typed_value [hudi]

Posted by "voonhous (via GitHub)" <gi...@apache.org>.
voonhous commented on issue #20307:
URL: https://github.com/apache/hudi/issues/20307#issuecomment-6165794582

   **TLDR:** root cause is a missing namespace: Hudi's Parquet-to-Avro converter (`AvroSchemaConverterWithTimestampNTZ`, copied from parquet-java 1.13.1) names every `fixed` after its field with no namespace, so the DECIMAL `typed_value` leaf collides with the enclosing `typed_value` record. Upstream already fixed this in PARQUET-2456 (apache/parquet-java#1304, 1.14.0); our copy predates it. Fix: #20324.
   


-- 
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: commits-unsubscribe@hudi.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [I] Shredded variant COW upsert fails on DECIMAL leaf: Avro fixed/record name collision on typed_value [hudi]

Posted by "voonhous (via GitHub)" <gi...@apache.org>.
voonhous closed issue #20307: Shredded variant COW upsert fails on DECIMAL leaf: Avro fixed/record name collision on typed_value
URL: https://github.com/apache/hudi/issues/20307


-- 
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: commits-unsubscribe@hudi.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org