You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(reader): resolve non-offset dict values pools lazily, not by expansion
DictLayoutDecoder fell through to an eager per-row string expansion for
any dict values pool that wasn't already a flat VarBinOffsetArray (a
vortex.constant pool, a StringView pool, or a VarBin-backed extension
dtype), and blindly cast to VarBinArray for pool shapes that aren't
VarBin at all (e.g. a dict-encoded vortex.uuid), raising a raw
ClassCastException instead of VortexException.
Non-offset pools now normalize into the existing lazy VarBinDictArray
path instead. The normalization walk is bounded by validating codes
against the pool first, since a pool's declared length is untrusted
and some shapes (vortex.constant) report an arbitrary length in a
tiny file; a vortex.constant pool resolves in O(1) without a walk at
all. The same fallback was also dropping pool/codes validity for any
pool it reached, silently un-nulling rows — fixed as part of the same
merge, since both bugs shared the one code path.
Closes#341
Copy file name to clipboardExpand all lines: CHANGELOG.md
+3Lines changed: 3 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -14,6 +14,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
14
14
### Fixed
15
15
16
16
- A malformed `fastlanes.rle` column now fails as `VortexException` where an absurd declared length, an empty or undersized child segment, or an out-of-range chunk offset previously escaped as `OutOfMemoryError`, `NegativeArraySizeException`, `ArithmeticException`, or `IndexOutOfBoundsException`. ([#342](https://github.com/dfa1/vortex-java/issues/342))
17
+
- A `vortex.dict` layout over a StringView or `vortex.constant` values pool no longer expands every row into a fresh buffer, and no longer silently drops that pool's validity. ([#341](https://github.com/dfa1/vortex-java/issues/341))
18
+
- A `vortex.dict` layout whose values pool declares more entries than it stores — a `vortex.constant` pool can claim any length in a few hundred bytes — no longer allocates against that claim; codes are bounded against the pool first, and an out-of-pool code fails as `VortexException`. ([#341](https://github.com/dfa1/vortex-java/issues/341))
19
+
- A `vortex.dict` layout over a values pool that is neither VarBin- nor primitive-shaped (e.g. a dict-encoded `vortex.uuid`) now fails as `VortexException` instead of `ClassCastException`. ([#341](https://github.com/dfa1/vortex-java/issues/341))
Copy file name to clipboardExpand all lines: docs/compatibility.md
+2-1Lines changed: 2 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -40,6 +40,7 @@ only the built-in decoders in `reader`; no encoder class is loaded.
40
40
|`vortex.onpair` experimental string encoding | Rust 0.74.0 | ❌ Not registered. Files using it fail to decode unless `ReadRegistry.builder().allowUnknown()` is enabled. |
41
41
|`vortex.variant` arbitrary nested objects | Rust (`vortex.parquet.variant`) | ⚠️ Java encodes/decodes variant columns of **typed scalar** values (constant / chunked-of-constants core, optional shredded child); Java↔Rust round-trip verified. Arbitrary nested JSON objects and real path-based shredding need the `vortex.parquet.variant` physical encoding — deferred ([ADR 0014](../adr/0014-variant-encoding-strategy.md)). |
|`vortex.dict`**layout** over a values pool that is neither VarBin- nor primitive-shaped (e.g. a dict-encoded `vortex.uuid`, whose storage is `FixedSizeList(U8, 16)`) | Rust's dict layout accepts any dtype | ❌ No lazy dict carrier exists for that pool shape, so decode throws `VortexException("unsupported dict values shape: …")`. The `vortex.dict`*encoding* is unaffected. |
43
44
| Duplicate struct field names | Rust writer rejects ("StructLayout must have unique field names"); Rust reader tolerates foreign files (first-match access) | ⚠️ Deliberate divergence on read: Java rejects such files with `VortexException("duplicate field name in file schema")` instead of tolerating them — the name-keyed `Chunk` API cannot represent both columns, and silent column loss is worse than a loud failure on a file the reference writer refuses to produce. Java's writer mirrors the Rust writer's rejection. |
44
45
| Blank / control-character field names | Wire-legal; the Rust writer produces `""` and whitespace-only names. NUL (`U+0000`) additionally aborts the Rust toolchain: Arrow FFI schema export hits a panic-cannot-unwind in `arrow-rs` (`ffi_stream::get_schema`) and SIGABRTs the process (measured against vortex-jni 0.75.0) | ⚠️ Deliberate strictness BOTH ways: vortex-java's writer refuses blank and control-character field names (`IllegalArgumentException`), and its reader rejects files carrying them (`VortexException` naming the producing pipeline as the likely bug) — the JSON-`""`-key principle: wire-legal is a floor, not a policy. Printable names of any shape (`$`-runs, spaces inside, emoji) are legal and round-trip intact both directions (measured; pinned by `ColumnNameEdgeCasesIntegrationTest`). |
45
46
@@ -143,7 +144,7 @@ decoder falls into one of three shapes:
143
144
|`vortex.varbinview`| Lazy | Lazy |`VarBinViewArray` — keeps views + data buffers as mmap slices |
|`vortex.dict`| Lazy | Lazy |`DictXxxArray` (numeric) + `VarBinDictArray` (string), ADR 0012. The `vortex.dict`**layout** resolves the same way for any VarBin-shaped values pool — a StringView pool, or any VarBin-backed extension dtype — normalizing only the pool entries the codes reach, never the rows; a `vortex.constant` pool collapses to `VarBinConstantArray`|
147
148
|`vortex.sparse`| Lazy | Lazy |`LazySparseXxxArray` (primitive + bool) + `VarBinSparseArray` (Utf8/Binary); fill broadcast, patch resolved per access; patch-free range → `VarBinConstantArray`, ADR 0015 |
148
149
|`vortex.sequence`| Lazy | Lazy |`LazySequenceXxxArray`; `base + i * multiplier` per access, no buffer, ADR 0015 |
0 commit comments