Repository navigation
Overview
7.1.0 adds native decimal and double-array column APIs and a non-blocking
completion poll, and fixes several QWP/WebSocket correctness and performance
issues. It also changes how UUID bytes and Arrow FixedSizeBinary columns are
interpreted: read "Breaking changes" before upgrading if you send or read
UUIDs as raw bytes or ingest Arrow, Polars, or NumPy data.
The C and C++ clients are distributed as source. No pre-built native binaries
are attached; use the tag's source archive.
Compatibility
- QWP over WebSocket requires QuestDB 10.0 or newer. HTTP Basic auth and
single-endpoint reconnect work with Open Source and Enterprise; bearer-token
and OIDC auth, multi-host failover, and durable acknowledgement require
QuestDB Enterprise. - Rust MSRV is 1.91.0, relaxed from 1.91.1 (#211).
- The published
questdb-rscrate supports Arrow>=58, <60and Polars
>=0.52, <0.55. The native (FFI) library pins Arrow=59.0.0(#195).
See doc/COMPATIBILITY.md
for the full matrix.
Breaking changes
- UUID byte order (#186). Raw UUID bytes are now in standard RFC-4122
order, matching Python'suuid.bytesand Rust'sUuid::as_bytes(). This
affectscolumn_uuid()with a byte array, NumPyS16(qwp_numpy_s16),
bind_uuid, Arrow UUID columns, and every reader getter. Code that swapped
bytes to match the previous order must stop doing so. Thelo/hiinteger
UUID API is unchanged. - Arrow
FixedSizeBinarycolumns ingest asBINARYunless tagged (#186).
A UUID column needs thearrow.uuidorquestdb.column_type=uuidfield tag
(16 bytes), orArrowColumnOverride::Uuidat flush time; LONG256 needs
questdb.column_type=long256(32 bytes) orArrowColumnOverride::Long256.
A tag whose width doesn't match the column is an error. - Invalid Arrow column metadata is an error rather than being ignored
(#186). - Arrow field metadata is capped at 64 MiB per batch through the C, C++,
and Python APIs (#195). Larger batches are rejected and nothing is sent.
PolarsEnumcolumns with millions of categories should be cast to
pl.Categorical. Rustflush_polars_dataframeis not affected. - A failed columnar batch can publish a prefix (#219). A batch of up to
eight rows that contains an oversized row, other than the first, now sends
the rows before it instead of being rejected whole. A store-and-forward
sender commits those rows and reports the error as in doubt; a direct sender
closes its connection, discarding its other uncommitted chunks, so the
following commit fails withFailoverRetry. CheckError::in_doubt()before
retrying the whole input.
New
- Native
Chunkcolumn APIs forDecimal64,Decimal128,Decimal256, and
fixed-shapeDOUBLEarrays, in Rust, C, and C++ (#206). Buffers are borrowed
through flush, with validation of scales, shapes, lengths, and validity
bitmaps. Sender::completed_fsn(AckLevel): a non-blocking poll of the completion
watermark, the polling counterpart toSender::wait(#190).- QWP row buffers accept symbols after other columns (#203), over both UDP and
WebSocket. ILP still requires symbols before fields. - Polars
Objectcolumns fail with a clear error instead of ingesting
meaningless bytes (#186).
Fixes
- Columnar batches whose rows each fit
max_buf_sizeare no longer rejected;
splitting continues down to single rows (#219). Error::in_doubt()on a failedQuestDb::flush_polars_dataframe()covers
the whole DataFrame (#195): if any earlier batch was published, replaying the
DataFrame could duplicate that prefix.- Byte-aligned GEOHASH maximum values are no longer encoded as
NULL(#195). - Arrow C Data Interface inputs are validated before import: schema/array
agreement, child counts, buffer layouts, offsets, and slice lengths (#195).
On failure, inspectarray->releaseto determine ownership; the error code
alone does not. - Closing a connection pool (
questdb_db_close) could block forever on a
lost wakeup in the rejection-event dispatcher (#189). - In store-and-forward memory mode, a split chunk commits once at its last
frame instead of once per frame, with a bounded deferred window (#178). The
memory-mode default store-and-forward budget is at least five segments. Buffer::bookmark()on a QWP/WebSocket buffer records lengths instead of
cloning the buffered data, so bookmarking per row is no longer quadratic
(#191).QwpWsSizeHint::len()reuses its scratch allocation (#190).
Other changes
- The
InvalidApiCallmessage returned bywaitforAckLevel::Durable
withoutrequest_durable_ack=onhas new text (#190). The error code is
unchanged.
Full changelog: 7.0.0...7.1.0