From f8a61f9c1ac1850d67823cdefab9368199e84d33 Mon Sep 17 00:00:00 2001
From: John Naylor <john.naylor@postgresql.org>
Date: Thu, 23 Jul 2026 16:19:57 -0400
Subject: [PATCH v1] Revert using ssup_datum_unsigned_cmp for comparing oids

---
 src/backend/access/nbtree/nbtcompare.c  | 20 +++++++++++++++++++-
 src/test/regress/expected/tuplesort.out | 11 +++++++++++
 src/test/regress/sql/tuplesort.sql      |  5 +++++
 3 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/src/backend/access/nbtree/nbtcompare.c b/src/backend/access/nbtree/nbtcompare.c
index 795fded49d3..a797912ff81 100644
--- a/src/backend/access/nbtree/nbtcompare.c
+++ b/src/backend/access/nbtree/nbtcompare.c
@@ -422,12 +422,30 @@ btoidcmp(PG_FUNCTION_ARGS)
 		PG_RETURN_INT32(A_LESS_THAN_B);
 }
 
+static int
+btoidfastcmp(Datum x, Datum y, SortSupport ssup)
+{
+	Oid			a = DatumGetObjectId(x);
+	Oid			b = DatumGetObjectId(y);
+
+	if (a > b)
+		return A_GREATER_THAN_B;
+	else if (a == b)
+		return 0;
+	else
+		return A_LESS_THAN_B;
+}
+
 Datum
 btoidsortsupport(PG_FUNCTION_ARGS)
 {
 	SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
 
-	ssup->comparator = ssup_datum_unsigned_cmp;
+	/*
+	 * We cannot use ssup_datum_unsigned_cmp here, since we cannot count on
+	 * Datums being zero-extended.
+	 */
+	ssup->comparator = btoidfastcmp;
 	PG_RETURN_VOID();
 }
 
diff --git a/src/test/regress/expected/tuplesort.out b/src/test/regress/expected/tuplesort.out
index fc1321bf443..9851e8a6a57 100644
--- a/src/test/regress/expected/tuplesort.out
+++ b/src/test/regress/expected/tuplesort.out
@@ -703,3 +703,14 @@ EXPLAIN (COSTS OFF) :qry;
 (10 rows)
 
 COMMIT;
+-- Test sorting oids with the high bit set, mixing sources
+CREATE TEMP TABLE test_oid_sort (o oid);
+INSERT INTO test_oid_sort VALUES ('2147483648'), ('2147483647');
+SELECT o FROM test_oid_sort UNION ALL SELECT '3000000000'::oid ORDER BY 1;
+     o      
+------------
+ 2147483647
+ 2147483648
+ 3000000000
+(3 rows)
+
diff --git a/src/test/regress/sql/tuplesort.sql b/src/test/regress/sql/tuplesort.sql
index 8476e594e6c..31cd28c6116 100644
--- a/src/test/regress/sql/tuplesort.sql
+++ b/src/test/regress/sql/tuplesort.sql
@@ -305,3 +305,8 @@ EXPLAIN (COSTS OFF) :qry;
 :qry;
 
 COMMIT;
+
+-- Test sorting oids with the high bit set, mixing sources
+CREATE TEMP TABLE test_oid_sort (o oid);
+INSERT INTO test_oid_sort VALUES ('2147483648'), ('2147483647');
+SELECT o FROM test_oid_sort UNION ALL SELECT '3000000000'::oid ORDER BY 1;
-- 
2.55.0

