Fix bug in GIN posting tree root creation.
The root page is filled with as many items as fit, and the rest are inserted using normal insertions. However, I fumbled the variable names, and the code actually memcpy'd all the items on the page, overflowing the buffer. While at it, rename the variable to make the distinction more clear. Reported by Teodor Sigaev. This bug was introduced by my recent refactorings, so no backpatching required.
This commit is contained in:
parent
aa04b323c3
commit
07fca603b5
@ -623,10 +623,10 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems,
|
||||
BlockNumber blkno;
|
||||
Buffer buffer;
|
||||
Page page;
|
||||
int itemsCount;
|
||||
int nrootitems;
|
||||
|
||||
/* Calculate how many TIDs will fit on first page. */
|
||||
itemsCount = Min(nitems, GinMaxLeafDataItems);
|
||||
nrootitems = Min(nitems, GinMaxLeafDataItems);
|
||||
|
||||
/*
|
||||
* Create the root page.
|
||||
@ -638,8 +638,8 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems,
|
||||
START_CRIT_SECTION();
|
||||
|
||||
GinInitBuffer(buffer, GIN_DATA | GIN_LEAF);
|
||||
memcpy(GinDataPageGetData(page), items, sizeof(ItemPointerData) * nitems);
|
||||
GinPageGetOpaque(page)->maxoff = nitems;
|
||||
memcpy(GinDataPageGetData(page), items, sizeof(ItemPointerData) * nrootitems);
|
||||
GinPageGetOpaque(page)->maxoff = nrootitems;
|
||||
|
||||
MarkBufferDirty(buffer);
|
||||
|
||||
@ -651,7 +651,7 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems,
|
||||
|
||||
data.node = index->rd_node;
|
||||
data.blkno = blkno;
|
||||
data.nitem = nitems;
|
||||
data.nitem = nrootitems;
|
||||
|
||||
rdata[0].buffer = InvalidBuffer;
|
||||
rdata[0].data = (char *) &data;
|
||||
@ -660,7 +660,7 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems,
|
||||
|
||||
rdata[1].buffer = InvalidBuffer;
|
||||
rdata[1].data = (char *) items;
|
||||
rdata[1].len = sizeof(ItemPointerData) * itemsCount;
|
||||
rdata[1].len = sizeof(ItemPointerData) * nrootitems;
|
||||
rdata[1].next = NULL;
|
||||
|
||||
recptr = XLogInsert(RM_GIN_ID, XLOG_GIN_CREATE_PTREE, rdata);
|
||||
@ -678,7 +678,7 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems,
|
||||
/*
|
||||
* Add any remaining TIDs to the newly-created posting tree.
|
||||
*/
|
||||
if (itemsCount < nitems)
|
||||
if (nitems > nrootitems)
|
||||
{
|
||||
GinPostingTreeScan *gdi;
|
||||
|
||||
@ -686,8 +686,8 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems,
|
||||
gdi->btree.isBuild = (buildStats != NULL);
|
||||
|
||||
ginInsertItemPointers(gdi,
|
||||
items + itemsCount,
|
||||
nitems - itemsCount,
|
||||
items + nrootitems,
|
||||
nitems - nrootitems,
|
||||
buildStats);
|
||||
|
||||
pfree(gdi);
|
||||
|
Loading…
x
Reference in New Issue
Block a user