Hi — using the published community-extension build of lindel against DuckDB v1.5.2, several hilbert_encode / morton_encode calls trigger DuckDB internal-error assertions and poison the connection.
Versions
- DuckDB:
v1.5.2
- lindel:
332d151 (community-extensions, REPOSITORY install)
- Platform:
osx_arm64
The single repro that flagged this for us was the documented round-trip example SELECT hilbert_decode(hilbert_encode([10, 20]::INTEGER[2])). While narrowing it down I found the failure surface is broader and splits into two distinct shapes.
Bug 1 — 3D signed INTEGER[3] encode trips a UINT64-vs-UINT128 vector assertion
SELECT hilbert_encode([10, 20, 30]::INTEGER[3]);
-- INTERNAL Error: Expected vector of type UINT64, but found vector of type UINT128
SELECT morton_encode([10, 20, 30]::INTEGER[3]);
-- INTERNAL Error: Expected vector of type UINT64, but found vector of type UINT128
Specifically 3 dimensions; INTEGER[2] and INTEGER[4] both work:
arg::TYPE[N] |
result |
[10, 20]::INTEGER[2] |
OK → 884 |
[10, 20, 30]::INTEGER[3] |
INTERNAL Error UINT64 / UINT128 |
[10, 20, 30, 40]::INTEGER[4] |
OK → 7388876 |
Looks like the 3D code path picks an internal UINT128 accumulator but the function declares its return as UINT64, so ConstantVector::VerifyVectorType fails the assertion at flush time.
Bug 2 — every unsigned narrow-int element type fails the encoder
SELECT hilbert_encode([10, 20]::UINTEGER[2]);
-- INTERNAL Error: Expected vector of type INT32, but found vector of type UINT32
SELECT hilbert_encode([10, 20, 30]::UTINYINT[3]);
-- INTERNAL Error: Expected vector of type INT8, but found vector of type UINT8
SELECT hilbert_encode([10, 20, 30]::USMALLINT[3]);
-- INTERNAL Error: Expected vector of type INT16, but found vector of type UINT16
Same shape: implementation produces an unsigned-variant vector, declared signature expected the signed variant. Affects every UTINYINT[N] / USMALLINT[N] / UINTEGER[N] shape I tried, regardless of N.
UBIGINT[3] returns a clean Invalid Input Error: hilbert_encode()/morton_encode() only supports arrays of lengths of 1 or 2 for BIGINT/UBIGINT — that one's a documented constraint, not a crash. So the unsigned-encoder bug is specifically on the narrow unsigned types.
Why this matters
These are documented integer types in the README's Type Coverage section. They produce DuckDB internal-error stack traces (with the standard "this signals an assertion failure" footer) instead of either working or returning a normal SQL error. The error invalidates the connection, so subsequent queries on the same connection also fail.
Stack trace (representative — first repro above)
0 duckdb::Exception::Exception(...)
1 duckdb::InternalException::InternalException(...)
3 duckdb::ConstantVector::VerifyVectorType<unsigned long long>(duckdb::Vector const&)
4 duckdb::lindelEncodeArrayFunc(duckdb::DataChunk&, duckdb::ExpressionState&, duckdb::Vector&)
...
(Full stack available if useful — happy to attach.)
Repro script
import duckdb
db = duckdb.connect(":memory:")
db.execute("INSTALL 'lindel' FROM community")
db.execute("LOAD 'lindel'")
db.execute("SELECT hilbert_encode([10, 20, 30]::INTEGER[3])").fetchone()
Discovered via a SQL-validator pass over our docs site that exercises every published cookbook snippet against the live community-extensions build — so the recipes [hilbert_encode([x, y, z]::INTEGER[3])] we publish at https://query.farm/products/extensions/lindel were silently broken until the validator surfaced this. Filing here so users hitting the same patterns get a clean error or, ideally, a working result.
Happy to test patches.
Hi — using the published community-extension build of
lindelagainst DuckDB v1.5.2, severalhilbert_encode/morton_encodecalls trigger DuckDB internal-error assertions and poison the connection.Versions
v1.5.2332d151(community-extensions, REPOSITORY install)osx_arm64The single repro that flagged this for us was the documented round-trip example
SELECT hilbert_decode(hilbert_encode([10, 20]::INTEGER[2])). While narrowing it down I found the failure surface is broader and splits into two distinct shapes.Bug 1 — 3D signed
INTEGER[3]encode trips a UINT64-vs-UINT128 vector assertionSpecifically 3 dimensions;
INTEGER[2]andINTEGER[4]both work:arg::TYPE[N][10, 20]::INTEGER[2]884[10, 20, 30]::INTEGER[3][10, 20, 30, 40]::INTEGER[4]7388876Looks like the 3D code path picks an internal
UINT128accumulator but the function declares its return asUINT64, soConstantVector::VerifyVectorTypefails the assertion at flush time.Bug 2 — every unsigned narrow-int element type fails the encoder
Same shape: implementation produces an unsigned-variant vector, declared signature expected the signed variant. Affects every
UTINYINT[N]/USMALLINT[N]/UINTEGER[N]shape I tried, regardless of N.UBIGINT[3]returns a cleanInvalid Input Error: hilbert_encode()/morton_encode() only supports arrays of lengths of 1 or 2 for BIGINT/UBIGINT— that one's a documented constraint, not a crash. So the unsigned-encoder bug is specifically on the narrow unsigned types.Why this matters
These are documented integer types in the README's Type Coverage section. They produce DuckDB internal-error stack traces (with the standard "this signals an assertion failure" footer) instead of either working or returning a normal SQL error. The error invalidates the connection, so subsequent queries on the same connection also fail.
Stack trace (representative — first repro above)
(Full stack available if useful — happy to attach.)
Repro script
Discovered via a SQL-validator pass over our docs site that exercises every published cookbook snippet against the live community-extensions build — so the recipes
[hilbert_encode([x, y, z]::INTEGER[3])]we publish at https://query.farm/products/extensions/lindel were silently broken until the validator surfaced this. Filing here so users hitting the same patterns get a clean error or, ideally, a working result.Happy to test patches.