Repository navigation
Description
This Epic is for hardening Vortex's type system, ensuring it is sound, consistent, and robust.
Status
Active. Canonical decimal foundations and integer Widen have merged. Recent extension fixes cover temporal validation, nullability, scalar read errors, matching comparison dtypes, and DataFusion literals. The broader extension model and the decimal reader/writer stack remain in progress.
The current design is in #10633 and #11237, especially the extension type decisions and the Decimal decisions. Both PRs are for research and discussion and are not intended to merge.
Goal
We want to ensure that users of Vortex do not run into any issues with Vortex's type system. In an ideal world, all of these are true:
- Using provided types do not cause any issues (types are sound and consistent)
- Logical / physical boundary is always consistent
- Provided types are sufficient for most use cases (no missing provided types)
- Users (and us as well) can easily add their types via extension types
- Working with extension types is easy
Motivation
A robust type system means less bugs and easier abstractions. By ensuring this, users can interact with Vortex more confidently.
Examples that motivated this work include the multiple canonical decimal forms behind the fuzzer crashes in #5820 (#10701), and extension operations that leaked storage semantics or disagreed between execution paths (#7683).
Workstreams
- Tracking Issue: Fix Canonical Decimal #10701: one canonical decimal width per dtype. The width mapping, imports, compatibility fixtures and faster widening copy have merged. Decimal
Widen, DecimalByteParts decoding, old-node conversion and constructor enforcement remain open. CD5 and CD6 wait for the fixtures in 0.91.0, which is still a draft as of 2026-11-02. - Tracking Issue: Add
Widenencoding for integers and decimals #10733:Widenfor integers and decimals. Integer encoding and compute kernels have merged. Structural lifting, internal-child migration, decimal support, the wire format and editions remain open. - Epic: Extension Types #7683: extension types. The updated plan makes types opaque by default, with explicit
EqandOrdclaims, function declarations that govern storage use and result wrapping, and rewrite rules owned by each type. Storage is declared from metadata, top-level nullability follows storage, and nested nullability belongs to the type. The dedicated tracking issue for this implementation will follow separately. - Epic: Logical
Uniontype #7705: logicalUnionsupport. - First class FixedSizeBinary support #9902: first-class
FixedSizeBinary. The plan makes it a core type. - Wide primitive integers: add
I128,I256,U128andU256. A dedicated tracking issue follows when the work is scheduled. This andFixedSizeBinaryare outside the canonical decimal fix.
The design permits casts only through explicit rules for each dtype pair. The extension plan uses exact casts, with named functions for lossy unit changes. Existing lossy primitive casts and broader decimal arithmetic changes remain separate work.
Recent merged extension foundations and fixes
- Preserve extension metadata on Arrow dictionary import #10645 (2026-10-20): preserve extension metadata when importing Arrow dictionaries
- Honour NaN options in min/max over float-backed extension types #10851 (2026-10-27): honor NaN options in min/max over float-backed extension types
- Return errors for invalid temporal types and values #11015 (2026-10-30): return errors for invalid temporal types and values
- Add execution path consistency assertions #11013 (2026-10-30): compare batch, row and constant execution against an explicit expected result
- Change extension dtype nullability without validating again #11012 (2026-11-02): change top-level extension nullability without revalidating, and fix erased dtype debug output
- Require matching dtypes for extension comparisons #11016 (2026-11-02): require matching logical dtypes for extension comparisons, ignoring nullability
- Preserve extension literals in DataFusion comparisons #11067 (2026-11-02): preserve extension literals in DataFusion comparisons and
INlists, and reject bare scalar export that would discard the type - Validate extension storage and return scalar read errors #11014 (2026-11-02): validate scalar storage before the extension validator and return validation errors from scalar reads and aggregate results
#10953 remains open. It makes Timestamp accept every i64 count, keeps jiff limits at conversion and display boundaries, and widens DateTimeParts days when needed. #11099 contains documentation split from the comparison PR. The full extension phase plan stays in the research notes until the dedicated tracking issue is written.
Unresolved questions
-
Do the planned 128-bit and 256-bit integer types and(yes)FixedSizeBinary(First class FixedSizeBinary support #9902) belong to this Epic?
Activity
Uniontype #7705Widenencoding for integers and decimals #10733