diff --git a/src/backend/access/gist/gistutil.c b/src/backend/access/gist/gistutil.c index 8b60774..af4d4ea 100644 --- a/src/backend/access/gist/gistutil.c +++ b/src/backend/access/gist/gistutil.c @@ -375,6 +375,7 @@ gistchoose(Relation r, Page p, IndexTuple it, /* it has compressed entry */ OffsetNumber result; OffsetNumber maxoff; OffsetNumber i; + OffsetNumber offsets[MaxOffsetNumber]; float best_penalty[INDEX_MAX_KEYS]; GISTENTRY entry, identry[INDEX_MAX_KEYS]; @@ -407,11 +408,43 @@ gistchoose(Relation r, Page p, IndexTuple it, /* it has compressed entry */ maxoff = PageGetMaxOffsetNumber(p); Assert(maxoff >= FirstOffsetNumber); - for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) + if (true) { - IndexTuple itup = (IndexTuple) PageGetItem(p, PageGetItemId(p, i)); - bool zero_penalty; - int j; + /* + * If randomization is required then prepare array of offset numbers + * in order to remember which offset numbers were already exanimed. + */ + for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) + offsets[i - FirstOffsetNumber] = i; + } + + for (i = 0; i < maxoff; i++) + { + IndexTuple itup; + bool zero_penalty; + int j; + OffsetNumber offset; + + if (true) + { + /* + * Randomization: select random offset number from those which + * aren't previously selected. + */ + OffsetNumber rnd_i, tmp; + rnd_i = random() % (maxoff - i) + i; + tmp = offsets[rnd_i]; + offsets[rnd_i] = offsets[i]; + offsets[i] = tmp; + offset = offsets[i]; + } + else + { + /* No randomization: select next offset number */ + offset = i + FirstOffsetNumber; + } + + itup = (IndexTuple) PageGetItem(p, PageGetItemId(p, offset)); zero_penalty = true; @@ -424,7 +457,7 @@ gistchoose(Relation r, Page p, IndexTuple it, /* it has compressed entry */ /* Compute penalty for this column. */ datum = index_getattr(itup, j + 1, giststate->tupdesc, &IsNull); - gistdentryinit(giststate, j, &entry, datum, r, p, i, + gistdentryinit(giststate, j, &entry, datum, r, p, offset, FALSE, IsNull); usize = gistpenalty(giststate, j, &entry, IsNull, &identry[j], isnull[j]); @@ -441,7 +474,7 @@ gistchoose(Relation r, Page p, IndexTuple it, /* it has compressed entry */ * adopt this tuple's penalty values as the best for all the * remaining columns during subsequent loop iterations. */ - result = i; + result = offset; best_penalty[j] = usize; if (j < r->rd_att->natts - 1)