diff options
author | Teodor Sigaev <teodor@sigaev.ru> | 2009-11-13 11:17:04 +0000 |
---|---|---|
committer | Teodor Sigaev <teodor@sigaev.ru> | 2009-11-13 11:17:04 +0000 |
commit | 5e75f6790c6abc3bb5954ea380fb92e40f867d5e (patch) | |
tree | 6ec947c8fd4fb75c087a0624384dfdb51673d572 | |
parent | 0894c6b83862f1d091e3c37713e6e5db355248ef (diff) | |
download | postgresql-5e75f6790c6abc3bb5954ea380fb92e40f867d5e.tar.gz postgresql-5e75f6790c6abc3bb5954ea380fb92e40f867d5e.zip |
Fix multicolumn GIN's wrong results with fastupdate enabled.
User-defined consistent functions believes the check array
contains at least one true element which was not a true for
scanning pending list.
Per report from Yury Don <yura@vpcit.ru>
-rw-r--r-- | src/backend/access/gin/ginget.c | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/src/backend/access/gin/ginget.c b/src/backend/access/gin/ginget.c index f5e0f788d1c..db8fcc5633f 100644 --- a/src/backend/access/gin/ginget.c +++ b/src/backend/access/gin/ginget.c @@ -8,7 +8,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/gin/ginget.c,v 1.27 2009/06/11 14:48:53 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/access/gin/ginget.c,v 1.28 2009/11/13 11:17:04 teodor Exp $ *------------------------------------------------------------------------- */ @@ -25,10 +25,11 @@ typedef struct pendingPosition { - Buffer pendingBuffer; - OffsetNumber firstOffset; - OffsetNumber lastOffset; - ItemPointerData item; + Buffer pendingBuffer; + OffsetNumber firstOffset; + OffsetNumber lastOffset; + ItemPointerData item; + bool *hasMatchKey; } pendingPosition; @@ -873,6 +874,18 @@ matchPartialInPendingList(GinState *ginstate, Page page, return false; } +static bool +hasAllMatchingKeys(GinScanOpaque so, pendingPosition *pos) +{ + int i; + + for (i = 0; i < so->nkeys; i++) + if (pos->hasMatchKey[i] == false) + return false; + + return true; +} + /* * Sets entryRes array for each key by looking at * every entry per indexed value (heap's row) in pending list. @@ -889,7 +902,6 @@ collectDatumForItem(IndexScanDesc scan, pendingPosition *pos) IndexTuple itup; int i, j; - bool hasMatch = false; /* * Resets entryRes @@ -900,6 +912,7 @@ collectDatumForItem(IndexScanDesc scan, pendingPosition *pos) memset(key->entryRes, FALSE, key->nentries); } + memset(pos->hasMatchKey, FALSE, so->nkeys); for (;;) { @@ -1005,7 +1018,7 @@ collectDatumForItem(IndexScanDesc scan, pendingPosition *pos) entry->extra_data); } - hasMatch |= key->entryRes[j]; + pos->hasMatchKey[i] |= key->entryRes[j]; } } @@ -1017,7 +1030,7 @@ collectDatumForItem(IndexScanDesc scan, pendingPosition *pos) * We scan all values from one tuple, go to next one */ - return hasMatch; + return hasAllMatchingKeys(so, pos); } else { @@ -1034,7 +1047,7 @@ collectDatumForItem(IndexScanDesc scan, pendingPosition *pos) } } - return hasMatch; + return hasAllMatchingKeys(so, pos); } /* @@ -1073,6 +1086,7 @@ scanPendingInsert(IndexScanDesc scan, TIDBitmap *tbm, int64 *ntids) LockBuffer(pos.pendingBuffer, GIN_SHARE); pos.firstOffset = FirstOffsetNumber; UnlockReleaseBuffer(metabuffer); + pos.hasMatchKey = palloc(sizeof(bool) * so->nkeys); /* * loop for each heap row. scanGetCandidate returns full row or row's @@ -1126,6 +1140,8 @@ scanPendingInsert(IndexScanDesc scan, TIDBitmap *tbm, int64 *ntids) (*ntids)++; } } + + pfree(pos.hasMatchKey); } /* |