]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Lookup the correct ordering for parallel GIN builds
authorTomas Vondra <tomas.vondra@postgresql.org>
Mon, 26 Jan 2026 17:52:16 +0000 (18:52 +0100)
committerTomas Vondra <tomas.vondra@postgresql.org>
Mon, 26 Jan 2026 19:05:00 +0000 (20:05 +0100)
When building a tuplesort during parallel GIN builds, the function
incorrectly looked up the default B-Tree operator, not the function
associated with the GIN opclass (through GIN_COMPARE_PROC).

Fixed by using the same logic as initGinState(), and the other place
in parallel GIN builds.

This could cause two types of issues. First, a data type might not have
a B-Tree opclass, in which case the PrepareSortSupportFromOrderingOp()
fails with an ERROR. Second, a data type might have both B-Tree and GIN
opclasses, defining order/equality in different ways. This could lead to
logical corruption in the index.

Backpatch to 18, where parallel GIN builds were introduced.

Discussion: https://postgr.es/m/73a28b94-43d5-4f77-b26e-0d642f6de777@iki.fi
Reported-by: Heikki Linnakangas <hlinnaka@iki.fi>
Backpatch-through: 18

src/backend/utils/sort/tuplesortvariants.c

index 5f70e8dddac571bb435782906417162eeb5a01b5..82a712dc84bb4db7eb57234342f8ca6bcdfc058f 100644 (file)
@@ -20,6 +20,7 @@
 #include "postgres.h"
 
 #include "access/brin_tuple.h"
+#include "access/gin.h"
 #include "access/gin_tuple.h"
 #include "access/hash.h"
 #include "access/htup_details.h"
@@ -28,6 +29,7 @@
 #include "catalog/pg_collation.h"
 #include "executor/executor.h"
 #include "pg_trace.h"
+#include "utils/builtins.h"
 #include "utils/datum.h"
 #include "utils/guc.h"
 #include "utils/lsyscache.h"
@@ -614,7 +616,7 @@ tuplesort_begin_index_gin(Relation heapRel,
        {
                SortSupport sortKey = base->sortKeys + i;
                Form_pg_attribute att = TupleDescAttr(desc, i);
-               TypeCacheEntry *typentry;
+               Oid                     cmpFunc;
 
                sortKey->ssup_cxt = CurrentMemoryContext;
                sortKey->ssup_collation = indexRel->rd_indcollation[i];
@@ -628,11 +630,26 @@ tuplesort_begin_index_gin(Relation heapRel,
                        sortKey->ssup_collation = DEFAULT_COLLATION_OID;
 
                /*
-                * Look for a ordering for the index key data type, and then the sort
-                * support function.
+                * If the compare proc isn't specified in the opclass definition, look
+                * up the index key type's default btree comparator.
                 */
-               typentry = lookup_type_cache(att->atttypid, TYPECACHE_LT_OPR);
-               PrepareSortSupportFromOrderingOp(typentry->lt_opr, sortKey);
+               cmpFunc = index_getprocid(indexRel, i + 1, GIN_COMPARE_PROC);
+               if (cmpFunc == InvalidOid)
+               {
+                       TypeCacheEntry *typentry;
+
+                       typentry = lookup_type_cache(att->atttypid,
+                                                                                TYPECACHE_CMP_PROC_FINFO);
+                       if (!OidIsValid(typentry->cmp_proc_finfo.fn_oid))
+                               ereport(ERROR,
+                                               (errcode(ERRCODE_UNDEFINED_FUNCTION),
+                                                errmsg("could not identify a comparison function for type %s",
+                                                               format_type_be(att->atttypid))));
+
+                       cmpFunc = typentry->cmp_proc_finfo.fn_oid;
+               }
+
+               PrepareSortSupportComparisonShim(cmpFunc, sortKey);
        }
 
        base->removeabbrev = removeabbrev_index_gin;