Commit 07fca603 authored by Heikki Linnakangas's avatar Heikki Linnakangas

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.
parent aa04b323
...@@ -623,10 +623,10 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems, ...@@ -623,10 +623,10 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems,
BlockNumber blkno; BlockNumber blkno;
Buffer buffer; Buffer buffer;
Page page; Page page;
int itemsCount; int nrootitems;
/* Calculate how many TIDs will fit on first page. */ /* Calculate how many TIDs will fit on first page. */
itemsCount = Min(nitems, GinMaxLeafDataItems); nrootitems = Min(nitems, GinMaxLeafDataItems);
/* /*
* Create the root page. * Create the root page.
...@@ -638,8 +638,8 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems, ...@@ -638,8 +638,8 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems,
START_CRIT_SECTION(); START_CRIT_SECTION();
GinInitBuffer(buffer, GIN_DATA | GIN_LEAF); GinInitBuffer(buffer, GIN_DATA | GIN_LEAF);
memcpy(GinDataPageGetData(page), items, sizeof(ItemPointerData) * nitems); memcpy(GinDataPageGetData(page), items, sizeof(ItemPointerData) * nrootitems);
GinPageGetOpaque(page)->maxoff = nitems; GinPageGetOpaque(page)->maxoff = nrootitems;
MarkBufferDirty(buffer); MarkBufferDirty(buffer);
...@@ -651,7 +651,7 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems, ...@@ -651,7 +651,7 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems,
data.node = index->rd_node; data.node = index->rd_node;
data.blkno = blkno; data.blkno = blkno;
data.nitem = nitems; data.nitem = nrootitems;
rdata[0].buffer = InvalidBuffer; rdata[0].buffer = InvalidBuffer;
rdata[0].data = (char *) &data; rdata[0].data = (char *) &data;
...@@ -660,7 +660,7 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems, ...@@ -660,7 +660,7 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems,
rdata[1].buffer = InvalidBuffer; rdata[1].buffer = InvalidBuffer;
rdata[1].data = (char *) items; rdata[1].data = (char *) items;
rdata[1].len = sizeof(ItemPointerData) * itemsCount; rdata[1].len = sizeof(ItemPointerData) * nrootitems;
rdata[1].next = NULL; rdata[1].next = NULL;
recptr = XLogInsert(RM_GIN_ID, XLOG_GIN_CREATE_PTREE, rdata); recptr = XLogInsert(RM_GIN_ID, XLOG_GIN_CREATE_PTREE, rdata);
...@@ -678,7 +678,7 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems, ...@@ -678,7 +678,7 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems,
/* /*
* Add any remaining TIDs to the newly-created posting tree. * Add any remaining TIDs to the newly-created posting tree.
*/ */
if (itemsCount < nitems) if (nitems > nrootitems)
{ {
GinPostingTreeScan *gdi; GinPostingTreeScan *gdi;
...@@ -686,8 +686,8 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems, ...@@ -686,8 +686,8 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems,
gdi->btree.isBuild = (buildStats != NULL); gdi->btree.isBuild = (buildStats != NULL);
ginInsertItemPointers(gdi, ginInsertItemPointers(gdi,
items + itemsCount, items + nrootitems,
nitems - itemsCount, nitems - nrootitems,
buildStats); buildStats);
pfree(gdi); pfree(gdi);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment