From eee71a66cc860771837ed645a8dcf0ccffd735c6 Mon Sep 17 00:00:00 2001 From: Tomas Vondra Date: Mon, 26 Jan 2026 18:52:16 +0100 Subject: [PATCH] Lookup the correct ordering for parallel GIN builds 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 Backpatch-through: 18 --- src/backend/utils/sort/tuplesortvariants.c | 27 ++++++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/backend/utils/sort/tuplesortvariants.c b/src/backend/utils/sort/tuplesortvariants.c index 5f70e8dddac..82a712dc84b 100644 --- a/src/backend/utils/sort/tuplesortvariants.c +++ b/src/backend/utils/sort/tuplesortvariants.c @@ -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; -- 2.47.3