Hi, In the functions addItemPointersToLeafTuple and buildFreshLeafTuple (in gininsert.c), the result of ginCompressPostingList() is passed to GinFormTuple without checking whether ginCompressPostingList() successfully packed all items. These GinFormTuple calls consistently fail because the resulting tuples always exceed the maximum size. While this doesn’t result in data corruption, it might still be worth addressing. Additionally, the condition if (compressedList) is unnecessary, since ginCompressPostingList() never returns NULL.
Please find the attached patch fixing it. Best regards, Arseniy Mukhin
diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c index a7b7b5996e3..5643c423627 100644 --- a/src/backend/access/gin/gininsert.c +++ b/src/backend/access/gin/gininsert.c @@ -218,7 +218,8 @@ addItemPointersToLeafTuple(GinState *ginstate, ItemPointerData *newItems, *oldItems; int oldNPosting, - newNPosting; + newNPosting, + nwritten; GinPostingList *compressedList; Assert(!GinIsPostingTree(old)); @@ -236,17 +237,18 @@ addItemPointersToLeafTuple(GinState *ginstate, /* Compress the posting list, and try to a build tuple with room for it */ res = NULL; compressedList = ginCompressPostingList(newItems, newNPosting, GinMaxItemSize, - NULL); + &nwritten); pfree(newItems); - if (compressedList) + if (nwritten == newNPosting) { res = GinFormTuple(ginstate, attnum, key, category, (char *) compressedList, SizeOfGinPostingList(compressedList), newNPosting, false); - pfree(compressedList); } + pfree(compressedList); + if (!res) { /* posting list would be too big, convert to posting tree */ @@ -293,17 +295,19 @@ buildFreshLeafTuple(GinState *ginstate, { IndexTuple res = NULL; GinPostingList *compressedList; + int nwritten; /* try to build a posting list tuple with all the items */ - compressedList = ginCompressPostingList(items, nitem, GinMaxItemSize, NULL); - if (compressedList) + compressedList = ginCompressPostingList(items, nitem, GinMaxItemSize, &nwritten); + if (nwritten == nitem) { res = GinFormTuple(ginstate, attnum, key, category, (char *) compressedList, SizeOfGinPostingList(compressedList), nitem, false); - pfree(compressedList); } + pfree(compressedList); + if (!res) { /* posting list would be too big, build posting tree */