Skip to content

fix(writer): give Fsst/VarBinView/Zstd a byte-safe Binary path - #361

Merged
dfa1 merged 1 commit into
mainfrom
fix/352-binary-cascade-encoders
Sep 1, 2026
Merged

fix(writer): give Fsst/VarBinView/Zstd a byte-safe Binary path#361
dfa1 merged 1 commit into
mainfrom
fix/352-binary-cascade-encoders

Conversation

@dfa1

@dfa1 dfa1 commented Sep 1, 2026

Copy link
Copy Markdown
Owner

Summary

  • FsstEncodingEncoder, VarBinViewEncodingEncoder, and ZstdEncodingEncoder cast data straight to String[], so a DType.Binary column threw ClassCastException if the cascade competition picked one of them (accepts() had been narrowed to Utf8-only as a stopgap). Added VarBinBytes, a shared helper normalizing Utf8/Binary input to byte[][], and gave all three encoders a real byte-safe path.
  • CascadingCompressor routed Binary through a first-match findPrimitiveEncoding instead of the real sample-and-measure competition Utf8 gets, so even with accepts() fixed there was no actual contest. Binary now joins Utf8 in competeAndEncode, with byte[][] support added to dataLength/stratifiedSample. MaskedEncodingEncoder's null-densification now covers byte[][] too.
  • Fixes an adjacent gap this surfaced: VortexWriter.arrayLength had no byte[][] case, so a non-nullable DType.Binary column could not be written at all (only nullable ones worked, since NullableData carries its own length).

Fixes #352

Test plan

  • ./mvnw -pl writer -am test — full writer suite green, including new Binary round-trip tests (byte-for-byte, non-UTF8 sequences, null entries) added to FsstEncodingEncoderTest, VarBinViewEncodingEncoderTest, ZstdEncodingEncoderTest, and new VortexWriterTest cases for non-nullable Binary and cascade competition over Binary.
  • ./mvnw verify — full reactor build green.

🤖 Generated with Claude Code

https://claude.ai/code/session_019NqSD9faDK9WHNektV8ZPH

FsstEncodingEncoder, VarBinViewEncodingEncoder, and ZstdEncodingEncoder
all cast data straight to String[], so a DType.Binary column (raw
bytes, e.g. an embedded audio/image blob) threw ClassCastException if
the cascade competition picked one of them. accepts() had been
narrowed to Utf8-only as a stopgap.

Add VarBinBytes, a small shared helper (mirroring
VarBinEncodingEncoder's existing byte[][]-or-String[] handling) that
normalizes both to byte[][] — UTF-8 encoding Utf8 rows, passing Binary
rows through untouched, with two null-handling variants (substitute
empty, or preserve for detect/strip). All three encoders now accept
Binary and round-trip byte-for-byte, including non-UTF8 sequences and
null entries (values child of a masked/nullable layout).

CascadingCompressor previously routed Binary through a first-match
findPrimitiveEncoding + spliceResult, not the real sample-and-measure
competition it gives Utf8 — so even with accepts() fixed, whichever
encoder happened to register first would always win. Binary now joins
Utf8 in the same competeAndEncode path, with a byte[][] case added to
dataLength/stratifiedSample. MaskedEncodingEncoder's denseValues
(substituting a placeholder for null values-child entries before the
cascade reads them) now handles byte[][] alongside String[].

Also fixes an adjacent gap this surfaced: VortexWriter's row-count
validation (arrayLength) had no byte[][] case, so a non-nullable
DType.Binary column could not be written at all — only nullable ones
worked, because NullableData carries its own length.

Fixes #352

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019NqSD9faDK9WHNektV8ZPH
@dfa1
dfa1 merged commit 6fba232 into main Sep 1, 2026
6 checks passed
@dfa1
dfa1 deleted the fix/352-binary-cascade-encoders branch September 1, 2026 05:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Binary-accepting encoders (Fsst/VarBinView/Zstd) assume String[] internally

1 participant