0001-Lookup-the-correct-ordering-for-parallel-GIN-builds.patch

text/x-patch

Filename: 0001-Lookup-the-correct-ordering-for-parallel-GIN-builds.patch
Type: text/x-patch
Part: 1
Message: Re: Parallel CREATE INDEX for GIN indexes

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 0001
Subject: Lookup the correct ordering for parallel GIN builds
File+
src/backend/utils/sort/tuplesortvariants.c 22 5
From 90c7cda42bcf40fea5766e1e0928ec825857bda1 Mon Sep 17 00:00:00 2001
From: Tomas Vondra <tomas@vondra.me>
Date: Fri, 16 Jan 2026 15:25:35 +0100
Subject: [PATCH 1/2] 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 <hlinnaka@iki.fi>
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 e3e1142126e..2509ac3e3a4 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"
@@ -615,7 +617,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];
@@ -629,11 +631,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.52.0