mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-12 18:34:36 +08:00
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:
parent
0894c6b838
commit
5e75f6790c
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user