Repository navigation
Antalya-26.6: iceberg v3 multi-arg transforms ,added logic to read source_ids and not throw an error - #2318
Antalya-26.6: iceberg v3 multi-arg transforms ,added logic to read source_ids and not throw an error#2318subkanthi wants to merge 9 commits into
Conversation
CI triage for #2318Verdict: none of the red checks are caused by this PR. This PR changes only 8 Iceberg data-lake C++ files ( Breakdown: 2 integration failures — pre-existing & tracked · 1 stateless — flaky · 1 stateless — pre-existing (cas storage) · Regression TestFlows — pre-existing branch state. Integration tests (amd_asan_ubsan, db disk, old analyzer, 4/8) — 12/1102 ❌ NOT this PR (pre-existing, tracked)All 12 are This is issue #2216 — a signed-integer overflow parsing Iceberg Integration tests (amd_asan_ubsan, db disk, old analyzer, 7/8) — 1/635 ❌ NOT this PR (pre-existing, tracked)
Stateless tests (amd_binary, cas storage / cas s3 storage) —
|
CI triage for this PRVerdict: 0 failures caused by this PR. All red checks are pre-existing base-branch failures, known-flaky tests, or CI-infra problems (OOM / S3 connectivity / server-start). The build is green on all amd targets, so the change compiles cleanly. Re-running will not turn CI green until the base-branch issues below are resolved. Head SHA analyzed: 1.
|
Audit update for PR #2318 (Iceberg v3 multi-argument transforms: reading
|
Audit Report: PR #2318 — Iceberg V3 Multi-Arg TransformsAI audit note: This review comment was generated by AI (claude-opus-4.6). Audit update for PR #2318 (iceberg v3 multi-arg transforms: read Call GraphTransition Matrix
Confirmed DefectsMedium:
|
|
Here is the audit report for PR #2318: AI audit note: This review comment was generated by AI (Claude Opus 4.6).
Audit update for PR #2318 (Iceberg V3 multi-argument partition/sort transform support):
Confirmed defects:
Medium: Pruner `partition_key_spec_positions` is not populated when `hasPartitionKey` is true
Impact: When the pruner is constructed, it reads `partition_key` and
`partition_key_spec_positions` from the manifest file iterator. However,
the new `partition_key_spec_positions` field is set via assignment
(`partition_key_spec_positions = manifest_file.getPartitionKeySpecPositions()`)
only inside the `if (manifest_file.hasPartitionKey())` block — which is
correct. But the field is a `std::vector<size_t>` member with default
empty construction. If by some code path `partition_key_condition` is set
but `partition_key_spec_positions` is empty (should not happen in current
code since both are guarded by the same `if`), `canBePruned` would produce
an empty `index_value` and call `mayBeTrueInRange(0, ...)`, which
returns true (not pruned). This is fail-closed (safe) so NOT a correctness
bug — downgraded to observation. No defect.
Status: NOT CONFIRMED — fail-closed by design.
Low: `PartitionSpecsEntry` comparison operator (`<=>`) uses lexicographic
vector comparison on `source_ids`
Impact: The `<=>` operator on `PartitionSpecsEntry` now compares
`std::vector<Int32> source_ids` lexicographically. This is used for
sorting `ProcessedManifestFileEntry` objects (via the `<=>` on
`ProcessedManifestFileEntryPtr` which includes
`common_partition_specification`). Changing from `Int32 source_id` to
`std::vector<Int32> source_ids` changes the sort order of entries.
For existing V1/V2 tables, `source_ids` always has exactly one element,
so `vector<Int32>{x} <=> vector<Int32>{y}` produces the same ordering
as `x <=> y`. For V3 tables with multi-arg fields, the new ordering is
well-defined and consistent. No correctness break.
Anchor: ManifestFile.cpp / `operator<=>`
Status: NOT CONFIRMED — ordering is consistent and correct for both single and
multi-element vectors.
No confirmed defects in reviewed scope.
Coverage summary:
Scope reviewed:
- ManifestFileIterator.cpp: multi-arg parsing, partition_key_spec_positions construction,
skip-multi-arg-in-key logic
- ManifestFilesPruning.cpp: projection of partition_value via partition_key_spec_positions,
bounds-check fail-closed, mayBeTrueInRange size fix
- ManifestFile.h/cpp: PartitionSpecsEntry struct change, comparison operator, dump formatting
- Utils.cpp: getSortingKeyDescriptionFromMetadata prefix-break on multi-arg/missing source-id,
getPartitionKeyStringFromMetadata multi-arg display,
getSortingKeyDisplayStringFromMetadata multi-arg display,
formatPartitionFieldDisplayMultiArg helper
- IcebergMetadata.cpp: sort_order_id guarded by non-empty key check
- ChunkPartitioner.cpp: early rejection of multi-arg writes
- MetadataGenerator.cpp: drop-column rejection for multi-arg partition/sort fields
- Constant.h: f_source_ids alias
- Unit tests: 2 new test files + extensions to existing test
Categories passed:
- Input validation (source-id/source-ids mutual exclusivity, empty array, missing both)
- Partition pruning projection correctness (positions mapping, bounds check, size argument fix)
- Sort key prefix truncation (break at first multi-arg, prefix-only guarantee)
- Drop-column guard for multi-arg references
- Write-path rejection for multi-arg transforms
- Display/formatting for multi-arg transforms (bucket, truncate, fallback)
- Comparison operator consistency (single-element vector backward compat)
- sort_order_id stale-pairing prevention (empty key → no id)
Categories not applicable:
- Concurrency/thread-safety: all changes are in single-threaded parsing/construction paths
- Memory lifetime: no new ownership patterns; vectors moved into const members
- Iterator invalidation: no container mutation during iteration
Assumptions/limits:
Static analysis only; not executed at runtime. Avro deserialization of multi-arg
partition tuples assumed to produce one Field per spec field (confirmed by reading
AvroForIcebergDeserializer.cpp). No V3 multi-arg Iceberg table was available for
end-to-end testing. |
xieandrew
left a comment
There was a problem hiding this comment.
Please check the issue related to OPTIMIZE table leaving leftover files.
| /// Iceberg V3: multi-argument transforms use `source-ids` instead of `source-id`. | ||
| /// Writing with multi-arg transforms is not supported yet (hash semantics not finalized upstream). | ||
| if (partition_specification_field->has(Iceberg::f_source_ids)) | ||
| throw Exception( |
There was a problem hiding this comment.
It looks like this could lead to leftover data files when compaction (OPTIMIZE table) is run on a table with source-ids. Compaction.cpp:1385-1395 writes data files before metadata files. writeMetadataFiles at Compaction.cpp:1121 calls the ChunkPartitioner constructor which would throw this exception. So the data files would have already been written but the metadata wouldn't update, leaving those files orphaned.
…ner rejection can no longer leave orphaned files
|
AI audit note: This review comment was generated by AI (Claude Opus 5.5). Audit update for PR #2318 (Iceberg v3 multi-argument transforms: read Confirmed defects: Coverage summary: |

#2316
implementation similar to apache/iceberg-python#3630
Changelog category (leave one):
Changelog entry (a user-readable short description of the changes that goes to CHANGELOG.md):
Implement iceberg v3 feature when the transformations are created in multiple columns,
source-idsdata is stored in the manifest.This PR will read iceberg tables created with
source-idsand not throw an error.CI/CD Options
Exclude tests:
Regression jobs to run: