v2.4.0 - Expression Index Support and Bug Fixes
Version 2.4.0 — Donut
New Features
-
Expression index support: Biscuit now correctly evaluates arbitrary index key expressions during index builds, enabling indexes such as:
CREATE INDEX idx ON table USING biscuit (lower(column_1), (column_2::text));
-
Multi-version build support (PG 16, 17, 18, 19beta1): Biscuit can now be compiled and installed against PostgreSQL 16 and 17, in addition to the already supported PG 18 and PG 19 Beta. All version-specific API differences are handled at compile time via
#if PG_VERSION_NUMguards.
Bug Fixes
-
Multi-column parallel scan returned duplicate rows: In the multi-column fallback scan path, every Gather participant was calling
biscuit_collect_sorted_tids_single()unconditionally, causing each worker to return the full TID set and the Gather node to assemble N× the expected rows. The call site now mirrors the single-column path by resolving the shared-memory parallel scan descriptor and dispatching throughbiscuit_collect_sorted_tids_parallel(), so each participant claims a disjoint slice of the pre-partitioned TID array. -
biscuit_operatorsview no longer breaks when additional operator classes are added: The view previously filtered on a hardcodedopfname = 'biscuit_text_ops'. It now joins throughpg_amand filters onam.amname = 'biscuit', staying correct without edits if new opclasses or opfamilies are later added. The view also surfaces the opfamily name per row.
Internal Changes
-
Parallel scan callbacks are conditionally compiled for PG 18+:
amcanparallel,amestimateparallelscan,aminitparallelscan, andamparallelrescanare only registered whenPG_VERSION_NUM >= 180000. On PG 16 and 17 the parallel fields are set tofalse/NULL. -
Cross-version compatibility macros added to
biscuit_common.h:BISCUIT_PARALLEL_AM_OFFSET(ps)abstracts the rename ofps_offset→ps_offset_amin PG 18.BISCUIT_COUNT_INDEX_SEARCH(scan)abstracts the index search counter, which moved fromxs_numIndexSearches(PG 17) toscan->instrument->nsearches(PG 18+) and did not exist in PG 16.biscuit_estimateparallelscanis declared with the correct signature for each major version (voidon PG 16,int nkeys, int norderbyson PG 17,Relation indexRelation, int nworkers, int nchunkson PG 18+).
-
Version string updated to
2.4.0 - Donut.
Notes
- CHAR(n) /
bpcharnative operator class is not yet available. PostgreSQL defines LIKE/ILIKE operators only over(text, text), so a dedicatedbiscuit_bpchar_opsoperating directly on paddedbpcharvalues would require new C-level operator implementations. As a supported workaround, CHAR(n) columns can be indexed today via an expression index on the text cast:This is documented inCREATE INDEX idx ON table USING biscuit ((char_col::text));
biscuit.sqland reflected in the updatedbiscuit_operatorsview comment.