From e0496a4b98e4952a4a1a5118ab89438e857cc056 Mon Sep 17 00:00:00 2001 From: Narek Galstyan Date: Mon, 2 Nov 2026 20:30:41 -0500 Subject: [PATCH 2/2] Fix btree_gist unions of bit and varbit leaf keys btree_gist indexes on bit and VarBit types use an internal node structure that is different from leaf note structure. So gbt_var_union() has to always look for incoming leaf node and convert it to internal. Current implementation copied its first entry into the union as is, without checking if it is leaf. When the first entry is a leaf key, the corresponding internal bound after a union is essentially corrupted. Index scans can then return wrong results. The fix makes sure that every entry (including the first) passes through gbt_var_bin_union(), which already properly handles leaf2node conversion. Existing bit and varbit GiST indexes can return incomplete results and should be reindexed. --- contrib/btree_gist/btree_utils_var.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/contrib/btree_gist/btree_utils_var.c b/contrib/btree_gist/btree_utils_var.c index efa6e09aa53..bb88992028d 100644 --- a/contrib/btree_gist/btree_utils_var.c +++ b/contrib/btree_gist/btree_utils_var.c @@ -331,16 +331,12 @@ gbt_var_union(const GistEntryVector *entryvec, int32 *size, Oid collation, int i = 0, numranges = entryvec->n; GBT_VARKEY *cur; - Datum out; - GBT_VARKEY_R rk; + Datum out = PointerGetDatum(NULL); *size = sizeof(GBT_VARKEY); - cur = (GBT_VARKEY *) DatumGetPointer(entryvec->vector[0].key); - rk = gbt_var_key_readable(cur); - out = PointerGetDatum(gbt_var_key_copy(&rk)); - - for (i = 1; i < numranges; i++) + /* Entries may be leaf keys; gbt_var_bin_union converts those. */ + for (i = 0; i < numranges; i++) { cur = (GBT_VARKEY *) DatumGetPointer(entryvec->vector[i].key); gbt_var_bin_union(&out, cur, collation, tinfo, flinfo); -- 2.50.1 (Apple Git-155)