Fix all findings from the table-format reader code review (fable) - #182
Open
schenksj wants to merge 2 commits into
Open
Fix all findings from the table-format reader code review (fable)#182schenksj wants to merge 2 commits into
schenksj wants to merge 2 commits into
Conversation
Addresses the 26 findings in docs/TABLE_FORMAT_READER_REVIEW.md (included with a resolution-status table). Highlights: High severity: - H1/H2: parquet getTableInfo prunes first-level partition dirs with new three-valued PartitionPredicate::evaluate_partial (unknown column -> keep), and discovers all partition levels by walking one directory chain - H3: delta get_snapshot_info scans all checkpoint parts for the metaData row - H4: read + validate the protocol action; reject unsupported readerFeatures (e.g. v2Checkpoint), minReaderVersion > 3, and columnMapping mode 'id' - H5: stale _last_checkpoint guard via one offset-bounded LIST; re-probe from the newest checkpoint, error on a broken commit chain - H6: compact serialization keeps has_deletion_vector (delta) and content_type (iceberg) - H7: abfss:// container parsed from URL username; account derived from host - H8: S3/Azure builders start from from_env() so env/IMDS credential chains work; explicit config still overrides Medium severity: - M1: percent-decode Url::path() before building object keys (shared decoder in common.rs) - M2: malformed non-empty commit lines fail loudly with file + line number - M3: translate catalog-style credential keys to FileIO keys for executor-side iceberg manifest reads - M4: capture sequence_number on iceberg entries (TANT, Arrow FFI col 8, Java getter) - M5: error instead of silent current_schema() fallback on unresolvable snapshot schema_id - M6: embed resolved_snapshot_id in every serialized iceberg entry; unify missing-snapshot-id fallback to -1 - M7: unify runtime creation to new_current_thread() - M8: render date/timestamp/decimal partition literals human-readably using each manifest's partition result types Low severity: L1-L6, L8-L10 fixed; L7 (exception taxonomy) deferred and documented. Tests: 152/152 Rust unit tests (incl. ~20 new); 107/107 Java tests across the 7 Delta/Iceberg/Parquet reader test classes. Note: IcebergTableReader.readManifestFileArrowFfi now exports 8 columns (sequence_number appended); callers must allocate 8 FFI addresses. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Claude encountered an error —— View job I'll analyze this and get back to you. |
Addresses 6 findings from an independent code review of PR #182 (fix all findings from the table-format reader review): - delta_reader: read_metadata_from_checkpoint no longer assumes metaData precedes protocol in the projected Arrow batch; ProjectionMask::roots() returns columns in physical schema order, which the Delta spec does not guarantee, so column identity is now derived from each field's sorted projection index instead. - delta_reader: the stale-_last_checkpoint guard (H5) now detects a second, deeper log gap beyond the newly-adopted checkpoint instead of silently discarding the already-known max_commit_version and returning a still-stale snapshot. - delta_reader: a missing protocol row in a checkpoint is now a hard error (like metaData) instead of a debug-only skip, since H4's reader-feature validation must not be silently bypassed. Updated the checkpoint test helper to include a protocol column so the enforcement path is covered. - parquet_reader: multi-level partition-column discovery now walks every first-level partition directory instead of only the first, so sibling partitions with a deeper structure (schema drift, partial backfill) are no longer under-reported. - iceberg_reader: threaded an inherited_snapshot_id parameter through read_iceberg_manifest / read_manifest_with_file_io / the Arrow FFI path and IcebergTableReader's Java API (additive overloads) so getChangesSince passes ManifestFileInfo's known added_snapshot_id, resolving the same fallback as listFiles() instead of always defaulting to -1. - parquet_reader: deduplicated the 4x-copied hidden-file filename check into a single is_hidden_parquet_file() helper. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Claude encountered an error —— View job I'll analyze this and get back to you. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Addresses all 26 findings from the table-format reader code review (
docs/TABLE_FORMAT_READER_REVIEW.md, included in this PR with a per-finding resolution-status table). Every finding was independently re-validated against the code before fixing — all 26 confirmed.High severity
getTableInfopredicate pruning evaluated the full predicate against first-level-only partition values, where missing-column semantics are "exclude" — a filter on a deeper column (e.g.month = '01'on ayear/monthtable) silently pruned everything. AddedPartitionPredicate::evaluate_partial()(Kleene three-valued logic, unknown → keep); executors re-apply the full predicate.partition_columnsnow discovers all levels by walking one directory chain (one LIST per level).get_snapshot_infonow scans all checkpoint parts for themetaDatarow instead of requiring it in part 1.protocolaction is read and validated; unsupported readerFeatures (v2Checkpoint, unknown future features),minReaderVersion > 3, and columnMapping modeidare rejected with clear errors._last_checkpoint: after the sequential commit probe, one offset-bounded LIST detects newer checkpoints; the reader re-probes from the newest checkpoint and errors loudly on a broken commit chain.has_deletion_vector(Delta) andcontent_type(Iceberg). The TANT format is name-keyed, so Java parsing is backward compatible.abfss://container@account.dfs...); account derived from host when not configured.from_env()(env vars, standard chains); explicit config still overrides.Medium severity
Url::path()before building object keys (paths with spaces/unicode). Deltaadd.pathvalues remain verbatim per spec; convention documented.aws_access_key_id,region_name, …) are translated to FileIO keys for executor-side Iceberg manifest reads; vended-credential catalogs documented as requiring the catalog path.sequence_numbercaptured on every Iceberg entry (TANT full mode, new 8th Arrow FFI column,IcebergFileEntry.getSequenceNumber()).schema_idis now an error instead of a silentcurrent_schema()fallback.resolved_snapshot_idembedded in every serialized entry; missing per-entry snapshot-id fallback unified to-1.new_current_thread()(shared-runtime/client caching left as a follow-up optimization).date = '2024-01-01'match.Low severity
L1–L6 and L8–L10 fixed (hidden-file filters,
-1sentinels, dead field removal, helper dedup intocommon.rs, serialization debug_assert + clearer 2 GiB error, throw on config-extraction failure, clear out-of-range version error,table_version = -1sentinel). L7 (exception taxonomy) deferred as a cross-layer API design change and documented.Breaking change note
IcebergTableReader.readManifestFileArrowFfinow exports 8 columns (sequence_numberappended); callers must allocate 8 FFI addresses. The column is appended last, so positional consumers of the first 7 stay aligned.Test plan
delta_reader,iceberg_reader,parquet_reader,parquet_schema_reader,common(~20 new tests: partial-predicate Kleene logic, protocol validation, percent-encoded log prefixes, typed literal rendering, compact-mode field presence)🤖 Generated with Claude Code