Skip to content

fix: Serialize VARINT/BIGNUM, GEOMETRY and VARIANT columns (#89)#93

Merged
jrosskopf merged 1 commit into
mainfrom
fix/gh-89-exotic-type-coverage
Jun 27, 2026
Merged

fix: Serialize VARINT/BIGNUM, GEOMETRY and VARIANT columns (#89)#93
jrosskopf merged 1 commit into
mainfrom
fix/gh-89-exotic-type-coverage

Conversation

@jrosskopf

Copy link
Copy Markdown
Contributor

Summary

Closes the last gap from the #89 type audit. VARINT/BIGNUM, GEOMETRY, and VARIANT previously fell through to the default case and serialized as null. They now produce real values.

Instead of hand-writing a decoder per type, this uses a universal C++-API fallback: a C-API duckdb_vector handle is just a reinterpret_cast of duckdb::Vector*, so we borrow the C++ Vector and let DuckDB's own Value stringification do the work.

Type Before After
VARINT / BIGNUM null exact decimal string (lossless arbitrary precision)
GEOMETRY null DuckDB text form, e.g. "POINT (1 2)" (spatial loaded)
VARIANT null nested JSON when its rendering is JSON, else its string form
any future/unknown type null best-effort string

The whole fallback is wrapped in try/catch, so an unconvertible extension value degrades to null rather than crashing.

Notes

  • 128-bit / arbitrary-precision integers are strings (consistent with the HUGEINT decision in fix: Correct REST JSON serialization of UUID/HUGEINT/BLOB/BIT (#89) #92) so values beyond 2⁵³ survive JSON consumers.
  • A struct-origin VARIANT stringifies as DuckDB's SQL-ish {'k': v} (not JSON), so it serializes as a string; JSON-derived VARIANTs embed as nested JSON. Documented in code + tests.

Test plan

  • New [query_executor][exotic_types] tests: VARINT (negative/large/multi-row/NULL), VARIANT (object embed, scalar, struct-origin, NULL).
  • GEOMETRY verified manually (POINT (1 2)); not in committed tests since it needs the spatial extension download.
  • Full C++ unit suite: 645/645 passing.
  • Reviewed with codex (LGTM — cast valid, no leaks, never emits invalid JSON).

Relates to #89

These types previously fell through to the default case and serialized
as null. Replace that with a universal C++-API fallback: a duckdb_vector
handle is a reinterpret_cast of duckdb::Vector*, so we borrow the C++
Vector and use DuckDB's own Value stringification.

- VARINT/BIGNUM -> exact decimal string (lossless arbitrary precision).
- GEOMETRY -> DuckDB's text form, e.g. 'POINT (1 2)' (spatial loaded).
- VARIANT -> embedded as nested JSON when its rendering is JSON,
  otherwise its string form.
- default/unknown/future types -> best-effort string instead of null.

Wrapped in try/catch so an unconvertible extension value degrades to
null rather than crashing. Adds [exotic_types] regression tests for
VARINT (incl. negative/large/multi-row) and VARIANT (object, scalar,
struct-origin, NULL).

Found via the type audit on #89.
@jrosskopf jrosskopf merged commit 60d8d56 into main Jun 27, 2026
21 checks passed
@jrosskopf jrosskopf deleted the fix/gh-89-exotic-type-coverage branch June 27, 2026 06:59
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.

1 participant