aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/gin/gininsert.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2009-06-06 02:39:40 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2009-06-06 02:39:40 +0000
commit356eea24ce6f5e0875b85e938230cfd01ed75ae3 (patch)
tree36d3e14da16b0ef91998fda4587b750308251149 /src/backend/access/gin/gininsert.c
parent1978d7f13fc2c46c74bf60ee84a5a8557391e53b (diff)
downloadpostgresql-356eea24ce6f5e0875b85e938230cfd01ed75ae3.tar.gz
postgresql-356eea24ce6f5e0875b85e938230cfd01ed75ae3.zip
Fix a serious bug introduced into GIN in 8.4: now that MergeItemPointers()
is supposed to remove duplicate heap TIDs, we have to be sure to reduce the tuple size and posting-item count accordingly in addItemPointersToTuple(). Failing to do so resulted in the effective injection of garbage TIDs into the index contents, ie, whatever happened to be in the memory palloc'd for the new tuple. I'm not sure that this fully explains the index corruption reported by Tatsuo Ishii, but the test case I'm using no longer fails.
Diffstat (limited to 'src/backend/access/gin/gininsert.c')
-rw-r--r--src/backend/access/gin/gininsert.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c
index f6a348eb85d..ef3d4bbb032 100644
--- a/src/backend/access/gin/gininsert.c
+++ b/src/backend/access/gin/gininsert.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/gin/gininsert.c,v 1.20 2009/03/24 22:06:03 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/gin/gininsert.c,v 1.21 2009/06/06 02:39:40 tgl Exp $
*-------------------------------------------------------------------------
*/
@@ -102,17 +102,19 @@ addItemPointersToTuple(Relation index, GinState *ginstate, GinBtreeStack *stack,
{
Datum key = gin_index_getattr(ginstate, old);
OffsetNumber attnum = gintuple_get_attrnum(ginstate, old);
- IndexTuple res = GinFormTuple(ginstate, attnum, key, NULL, nitem + GinGetNPosting(old));
+ IndexTuple res = GinFormTuple(ginstate, attnum, key,
+ NULL, nitem + GinGetNPosting(old));
if (res)
{
/* good, small enough */
- MergeItemPointers(GinGetPosting(res),
- GinGetPosting(old), GinGetNPosting(old),
- items, nitem
- );
+ uint32 newnitem;
- GinSetNPosting(res, nitem + GinGetNPosting(old));
+ newnitem = MergeItemPointers(GinGetPosting(res),
+ GinGetPosting(old), GinGetNPosting(old),
+ items, nitem);
+ /* merge might have eliminated some duplicate items */
+ GinShortenTuple(res, newnitem);
}
else
{