Skip to content

Commit 500889a

Browse files
committed
Fix erroneous range-union logic for varlena types in contrib/btree_gist.
gbt_var_bin_union() failed to do the right thing when the existing range needed to be widened at both ends rather than just one end. This could result in an invalid index in which keys that are present would not be found by searches, because the searches would not think they need to descend to the relevant leaf pages. This error affected all the varlena datatypes supported by btree_gist (text, bytea, bit, numeric). Per investigation of a trouble report from Tomas Vondra. (There is also an issue in gbt_var_penalty(), but that should only result in inefficiency not wrong answers. I'm committing this separately so that we have a git state in which it can be tested that bad penalty results don't produce invalid indexes.) Back-patch to all supported branches.
1 parent bb5e312 commit 500889a

File tree

1 file changed

+11
-10
lines changed

1 file changed

+11
-10
lines changed

contrib/btree_gist/btree_utils_var.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -223,39 +223,40 @@ void
223223
gbt_var_bin_union(Datum *u, GBT_VARKEY *e, Oid collation,
224224
const gbtree_vinfo *tinfo)
225225
{
226-
GBT_VARKEY *nk = NULL;
227-
GBT_VARKEY *tmp = NULL;
228-
GBT_VARKEY_R nr;
229226
GBT_VARKEY_R eo = gbt_var_key_readable(e);
227+
GBT_VARKEY_R nr;
230228

231229
if (eo.lower == eo.upper) /* leaf */
232230
{
231+
GBT_VARKEY *tmp;
232+
233233
tmp = gbt_var_leaf2node(e, tinfo);
234234
if (tmp != e)
235235
eo = gbt_var_key_readable(tmp);
236236
}
237237

238238
if (DatumGetPointer(*u))
239239
{
240-
241240
GBT_VARKEY_R ro = gbt_var_key_readable((GBT_VARKEY *) DatumGetPointer(*u));
241+
bool update = false;
242+
243+
nr.lower = ro.lower;
244+
nr.upper = ro.upper;
242245

243246
if ((*tinfo->f_cmp) (ro.lower, eo.lower, collation) > 0)
244247
{
245248
nr.lower = eo.lower;
246-
nr.upper = ro.upper;
247-
nk = gbt_var_key_copy(&nr, TRUE);
249+
update = true;
248250
}
249251

250252
if ((*tinfo->f_cmp) (ro.upper, eo.upper, collation) < 0)
251253
{
252254
nr.upper = eo.upper;
253-
nr.lower = ro.lower;
254-
nk = gbt_var_key_copy(&nr, TRUE);
255+
update = true;
255256
}
256257

257-
if (nk)
258-
*u = PointerGetDatum(nk);
258+
if (update)
259+
*u = PointerGetDatum(gbt_var_key_copy(&nr, TRUE));
259260
}
260261
else
261262
{

0 commit comments

Comments
 (0)