]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Avoid unnecessary GinFormTuple() calls for incompressible posting lists.
authorMasahiko Sawada <msawada@postgresql.org>
Mon, 6 Oct 2025 21:02:01 +0000 (14:02 -0700)
committerMasahiko Sawada <msawada@postgresql.org>
Mon, 6 Oct 2025 21:02:01 +0000 (14:02 -0700)
Previously, we attempted to form a posting list tuple even when
ginCompressPostingList() failed to compress the posting list due to
its size. While there was no functional failure, it always wasted one
GinFormTuple() call when item pointers didn't fit in a posting list
tuple.

This commit ensures that a GIN index tuple is formed only when all
item pointers in the posting list are successfully compressed.

Author: Arseniy Mukhin <arseniy.mukhin.dev@gmail.com>
Reviewed-by: Masahiko Sawada <sawada.mshk@gmail.com>
Discussion: https://postgr.es/m/CAE7r3M+C=jcpTD93f_RBHrQp3C+=TAXFs+k4tTuZuuxboK8AvA@mail.gmail.com

src/backend/access/gin/gininsert.c

index e9d4b27427e59637eb6a8b443286ae0952687845..1d3ab22556d89506bc614f780a9235da8dd437ef 100644 (file)
@@ -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 */