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>
This commit is contained in:
Teodor Sigaev 2009-11-13 11:17:04 +00:00
parent 0894c6b838
commit 5e75f6790c

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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 typedef struct pendingPosition
{ {
Buffer pendingBuffer; Buffer pendingBuffer;
OffsetNumber firstOffset; OffsetNumber firstOffset;
OffsetNumber lastOffset; OffsetNumber lastOffset;
ItemPointerData item; ItemPointerData item;
bool *hasMatchKey;
} pendingPosition; } pendingPosition;
@ -873,6 +874,18 @@ matchPartialInPendingList(GinState *ginstate, Page page,
return false; 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 * Sets entryRes array for each key by looking at
* every entry per indexed value (heap's row) in pending list. * every entry per indexed value (heap's row) in pending list.
@ -889,7 +902,6 @@ collectDatumForItem(IndexScanDesc scan, pendingPosition *pos)
IndexTuple itup; IndexTuple itup;
int i, int i,
j; j;
bool hasMatch = false;
/* /*
* Resets entryRes * Resets entryRes
@ -900,6 +912,7 @@ collectDatumForItem(IndexScanDesc scan, pendingPosition *pos)
memset(key->entryRes, FALSE, key->nentries); memset(key->entryRes, FALSE, key->nentries);
} }
memset(pos->hasMatchKey, FALSE, so->nkeys);
for (;;) for (;;)
{ {
@ -1005,7 +1018,7 @@ collectDatumForItem(IndexScanDesc scan, pendingPosition *pos)
entry->extra_data); 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 * We scan all values from one tuple, go to next one
*/ */
return hasMatch; return hasAllMatchingKeys(so, pos);
} }
else 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); LockBuffer(pos.pendingBuffer, GIN_SHARE);
pos.firstOffset = FirstOffsetNumber; pos.firstOffset = FirstOffsetNumber;
UnlockReleaseBuffer(metabuffer); UnlockReleaseBuffer(metabuffer);
pos.hasMatchKey = palloc(sizeof(bool) * so->nkeys);
/* /*
* loop for each heap row. scanGetCandidate returns full row or row's * loop for each heap row. scanGetCandidate returns full row or row's
@ -1126,6 +1140,8 @@ scanPendingInsert(IndexScanDesc scan, TIDBitmap *tbm, int64 *ntids)
(*ntids)++; (*ntids)++;
} }
} }
pfree(pos.hasMatchKey);
} }
/* /*