v3-0001-Add-check-for-compressed-posting-list-items-numbe.patch
text/x-patch
Filename: v3-0001-Add-check-for-compressed-posting-list-items-numbe.patch
Type: text/x-patch
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v3-0001
Subject: Add check for compressed posting list items number in GIN
| File | + | − |
|---|---|---|
| src/backend/access/gin/gininsert.c | 13 | 9 |
From d47dc9125cac3c83b6137783d1ec8c503711b65f Mon Sep 17 00:00:00 2001
From: Arseniy Mukhin <arseniy.mukhin.dev@gmail.com>
Date: Wed, 2 Jul 2025 22:00:31 +0300
Subject: [PATCH v3] Add check for compressed posting list items number in GIN
Current code doesn't check if compressed posting list contains all
items during index tuple creation which potentially can lead to
lost of data. It doesn't happen now because the size limit of compressed
posting list is the same as gin index tuple size limit, so when compressed
posting list reaches its limit, index tuple size with such a posting list
always too large. This commit adds check for compressed items number.
---
src/backend/access/gin/gininsert.c | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c
index e9d4b27427e..1d3ab22556d 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));
@@ -235,18 +236,19 @@ 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);
- pfree(newItems);
- if (compressedList)
+ compressedList = ginCompressPostingList(newItems, newNPosting, GinMaxItemSize, &nwritten);
+ if (nwritten == newNPosting)
{
res = GinFormTuple(ginstate, attnum, key, category,
(char *) compressedList,
SizeOfGinPostingList(compressedList),
newNPosting,
false);
- pfree(compressedList);
}
+
+ pfree(newItems);
+ 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 */
--
2.43.0