summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2015-01-29 19:35:55 +0200
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2015-01-29 19:37:27 +0200
commit1c2774f3771353cac002ffcb4325331a20613305 (patch)
tree0e8bb4e7af1caecbeb54d5a4d454e08c87a08ea4
parentd5d46e626ab3107908bce887b55f75d3bc13db94 (diff)
Fix bug where GIN scan keys were not initialized with gin_fuzzy_search_limit.
When gin_fuzzy_search_limit was used, we could jump out of startScan() without calling startScanKey(). That was harmless in 9.3 and below, because startScanKey()() didn't do anything interesting, but in 9.4 it initializes information needed for skipping entries (aka GIN fast scans), and you readily get a segfault if it's not done. Nevertheless, it was clearly wrong all along, so backpatch all the way to 9.1 where the early return was introduced. (AFAICS startScanKey() did nothing useful in 9.3 and below, because the fields it initialized were already initialized in ginFillScanKey(), but I don't dare to change that in a minor release. ginFillScanKey() is always called in gingetbitmap() even though there's a check there to see if the scan keys have already been initialized, because they never are; ginrescan() free's them.) In the passing, remove unnecessary if-check from the second inner loop in startScan(). We already check in the first loop that the condition is true for all entries. Reported by Olaf Gawenda, bug #12694, Backpatch to 9.1 and above, although AFAICS it causes a live bug only in 9.4.
-rw-r--r--src/backend/access/gin/ginget.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/src/backend/access/gin/ginget.c b/src/backend/access/gin/ginget.c
index d1462d091ac..bc16d24b7c2 100644
--- a/src/backend/access/gin/ginget.c
+++ b/src/backend/access/gin/ginget.c
@@ -507,17 +507,24 @@ startScan(IndexScanDesc scan)
* supposition isn't true), that total result will not more than
* minimal predictNumberResult.
*/
+ bool reduce = true;
for (i = 0; i < so->totalentries; i++)
+ {
if (so->entries[i]->predictNumberResult <= so->totalentries * GinFuzzySearchLimit)
- return;
-
- for (i = 0; i < so->totalentries; i++)
- if (so->entries[i]->predictNumberResult > so->totalentries * GinFuzzySearchLimit)
+ {
+ reduce = false;
+ break;
+ }
+ }
+ if (reduce)
+ {
+ for (i = 0; i < so->totalentries; i++)
{
so->entries[i]->predictNumberResult /= so->totalentries;
so->entries[i]->reduceResult = TRUE;
}
+ }
}
for (i = 0; i < so->nkeys; i++)