Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 07fca60

Browse files
committed
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.
1 parent aa04b32 commit 07fca60

File tree

1 file changed

+9
-9
lines changed

1 file changed

+9
-9
lines changed

src/backend/access/gin/gindatapage.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -623,10 +623,10 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems,
623623
BlockNumber blkno;
624624
Buffer buffer;
625625
Page page;
626-
int itemsCount;
626+
int nrootitems;
627627

628628
/* Calculate how many TIDs will fit on first page. */
629-
itemsCount = Min(nitems, GinMaxLeafDataItems);
629+
nrootitems = Min(nitems, GinMaxLeafDataItems);
630630

631631
/*
632632
* Create the root page.
@@ -638,8 +638,8 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems,
638638
START_CRIT_SECTION();
639639

640640
GinInitBuffer(buffer, GIN_DATA | GIN_LEAF);
641-
memcpy(GinDataPageGetData(page), items, sizeof(ItemPointerData) * nitems);
642-
GinPageGetOpaque(page)->maxoff = nitems;
641+
memcpy(GinDataPageGetData(page), items, sizeof(ItemPointerData) * nrootitems);
642+
GinPageGetOpaque(page)->maxoff = nrootitems;
643643

644644
MarkBufferDirty(buffer);
645645

@@ -651,7 +651,7 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems,
651651

652652
data.node = index->rd_node;
653653
data.blkno = blkno;
654-
data.nitem = nitems;
654+
data.nitem = nrootitems;
655655

656656
rdata[0].buffer = InvalidBuffer;
657657
rdata[0].data = (char *) &data;
@@ -660,7 +660,7 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems,
660660

661661
rdata[1].buffer = InvalidBuffer;
662662
rdata[1].data = (char *) items;
663-
rdata[1].len = sizeof(ItemPointerData) * itemsCount;
663+
rdata[1].len = sizeof(ItemPointerData) * nrootitems;
664664
rdata[1].next = NULL;
665665

666666
recptr = XLogInsert(RM_GIN_ID, XLOG_GIN_CREATE_PTREE, rdata);
@@ -678,16 +678,16 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems,
678678
/*
679679
* Add any remaining TIDs to the newly-created posting tree.
680680
*/
681-
if (itemsCount < nitems)
681+
if (nitems > nrootitems)
682682
{
683683
GinPostingTreeScan *gdi;
684684

685685
gdi = ginPrepareScanPostingTree(index, blkno, FALSE);
686686
gdi->btree.isBuild = (buildStats != NULL);
687687

688688
ginInsertItemPointers(gdi,
689-
items + itemsCount,
690-
nitems - itemsCount,
689+
items + nrootitems,
690+
nitems - nrootitems,
691691
buildStats);
692692

693693
pfree(gdi);

0 commit comments

Comments
 (0)