mbutrovich opened a new pull request, #4982:
URL: https://github.com/apache/datafusion-comet/pull/4982

   ## Which issue does this PR close?
   
   Relates to #4944.
   
   ## Rationale for this change
   
   `CometIcebergNativeScanExec` serializes an Iceberg scan's shared data into a 
single `IcebergScanCommon` protobuf message that is broadcast to executors. On 
a large merge-on-read pipeline this was reported to crash on the driver:
   
   ```
   java.lang.NegativeArraySizeException: -954238687
        at 
org.apache.comet.shaded.protobuf.AbstractMessageLite.toByteArray(AbstractMessageLite.java:46)
        at 
org.apache.comet.serde.operator.CometIcebergNativeScan$.serializePartitions(CometIcebergNativeScan.scala:1025)
   ```
   
   `AbstractMessageLite.toByteArray` allocates `new byte[getSerializedSize()]`, 
and `getSerializedSize()` returns `int`. The reported value implies the common 
message serialized to ~3.11 GiB (`-954238687 + 2^32 = 3340728609`), so the size 
wrapped negative and the array allocation threw. protobuf cannot represent a 
single message larger than 2 GiB.
   
   A likely contributor is `delete_files_pool`. Delete files were pooled by 
whole set: each `DeleteFileList` held full copies of every `IcebergDeleteFile` 
in a `FileScanTask`'s delete set. Under Iceberg's default partition delete 
granularity, one position-delete file applies to every data file in the 
partition with a compatible sequence number (`DeleteFileIndex.forDataFile`). 
Interleaving inserts and deletes staggers data-file sequence numbers, so each 
task sees a different subset of the same delete files. Set-level pooling then 
re-serialized a shared delete file once per distinct set, which grows 
quadratically with the number of delete commits. Iceberg's own 
`DeleteFileIndex` stores each `DeleteFile` once and references it many times; 
the serde did not preserve that sharing.
   
   This PR removes that duplication. It should reduce the common message size 
substantially on merge-on-read tables with shared delete files, which is 
expected to resolve the overflow, though the original reporter's workload has 
not yet been confirmed against this change.
   
   ## What changes are included in this PR?
   
   Normalize the wire format to intern each delete file once and reference it 
by index, mirroring Iceberg's in-memory model:
   
   - **proto** (`operator.proto`): add `repeated IcebergDeleteFile 
delete_file_pool` to `IcebergScanCommon`; change `DeleteFileList` to hold 
`repeated uint32 delete_file_indices` into that flat pool.
   - **Scala serde** (`CometIcebergNativeScan.scala`): intern each delete file 
into the flat pool (keyed by path, its identity), then dedup per-task sets as 
lists of pool indices. The set-level pool is retained so tasks sharing a delete 
set still share one `DeleteFileList`.
   - **Rust decode** (`planner.rs`): build the flat `delete_file_pool` once, 
then resolve each `DeleteFileList`'s indices against it. An out-of-range index 
is a hard error rather than a silent drop, consistent with the existing 
invalid-content-type and invalid-`schema_idx` handling.
   
   Error-handling semantics are unchanged: delete extraction and serialization 
failures at execution time remain fatal; the Rust decode fails loudly on a bad 
index.
   
   ## How are these changes tested?
   
   New regression test in `CometIcebergNativeSuite`: `"delete file pool does 
not duplicate shared delete files (serde size)"`. It builds a merge-on-read 
table with default partition delete granularity, interleaves 5 insert/delete 
rounds to stagger sequence numbers, then parses the serialized 
`IcebergScanCommon` and asserts each delete-file path appears exactly once in 
the raw message bytes (a format-agnostic check). It also guards against a 
vacuous pass by requiring that delete files are actually shared across tasks 
(`totalReferences > distinctPaths.size`).
   
   This test fails on the pre-change serde (a shared delete file appears 2-5 
times in the common message for the 5-round setup: 5 distinct files, 15 
references) and passes after the fix. `checkSparkAnswer` in the same test 
confirms the deletes are still applied correctly through the new index-based 
decode path. The existing positional-delete, equality-delete, dropped-column 
equality-delete, `bytes_scanned`, and compaction delete tests in the suite 
exercise the decode path end to end.
   


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