From 1754f128a445e261f06997bb64d1f6e911d32ac7 Mon Sep 17 00:00:00 2001
From: Richard Guo <guofenglinux@gmail.com>
Date: Tue, 1 Sep 2026 17:02:03 +0900
Subject: [PATCH v2] Fix OID-counter-sensitive row ordering in foreign_key test

Several queries in the foreign_key test sort pg_constraint rows with
"ORDER BY oid::regclass::text".  These OIDs are constraint OIDs, not
relation OIDs, so the regclass cast renders them as numeric strings,
and text comparison of numeric strings depends on digit count.  If the
OID counter crosses a power of ten while the test runs, the output
order flips, causing spurious test failures.  This cannot happen in a
fresh cluster, but installcheck against a long-lived cluster can hit
it.

To fix, sort by constraint name, which is unique within each of these
queries, and use COLLATE "C" so that the order does not depend on the
database's default collation either.
---
 src/test/regress/expected/foreign_key.out | 36 +++++++++++------------
 src/test/regress/sql/foreign_key.sql      | 18 ++++++------
 2 files changed, 27 insertions(+), 27 deletions(-)

diff --git a/src/test/regress/expected/foreign_key.out b/src/test/regress/expected/foreign_key.out
index ac044eb40fa..333994e6505 100644
--- a/src/test/regress/expected/foreign_key.out
+++ b/src/test/regress/expected/foreign_key.out
@@ -887,11 +887,11 @@ CREATE TABLE FKTABLE (
   -- this tests handling of duplicate entries in SET DEFAULT column list
   FOREIGN KEY (tid, fk_id_del_set_default) REFERENCES PKTABLE ON DELETE SET DEFAULT (fk_id_del_set_default, fk_id_del_set_default)
 );
-SELECT pg_get_constraintdef(oid) FROM pg_constraint WHERE conrelid = 'fktable'::regclass::oid ORDER BY oid;
+SELECT pg_get_constraintdef(oid) FROM pg_constraint WHERE conrelid = 'fktable'::regclass::oid ORDER BY conname COLLATE "C";
                                                 pg_get_constraintdef                                                
 --------------------------------------------------------------------------------------------------------------------
- FOREIGN KEY (tid, fk_id_del_set_null) REFERENCES pktable(tid, id) ON DELETE SET NULL (fk_id_del_set_null)
  FOREIGN KEY (tid, fk_id_del_set_default) REFERENCES pktable(tid, id) ON DELETE SET DEFAULT (fk_id_del_set_default)
+ FOREIGN KEY (tid, fk_id_del_set_null) REFERENCES pktable(tid, id) ON DELETE SET NULL (fk_id_del_set_null)
 (2 rows)
 
 INSERT INTO PKTABLE VALUES (1, 0), (1, 1), (1, 2);
@@ -1936,22 +1936,22 @@ ALTER TABLE fk_partitioned_fk_1 ADD FOREIGN KEY (a, b) REFERENCES fk_notpartitio
 ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_1 FOR VALUES FROM (0,0) TO (1000,1000);
 -- Child constraint will remain valid.
 SELECT conname, convalidated, conrelid::regclass FROM pg_constraint
-WHERE conrelid::regclass::text like 'fk_partitioned_fk%' ORDER BY oid::regclass::text;
+WHERE conrelid::regclass::text like 'fk_partitioned_fk%' ORDER BY conname COLLATE "C";
            conname            | convalidated |      conrelid       
 ------------------------------+--------------+---------------------
- fk_partitioned_fk_a_b_fkey   | f            | fk_partitioned_fk
  fk_partitioned_fk_1_a_b_fkey | t            | fk_partitioned_fk_1
+ fk_partitioned_fk_a_b_fkey   | f            | fk_partitioned_fk
 (2 rows)
 
 -- Validate the constraint
 ALTER TABLE fk_partitioned_fk VALIDATE CONSTRAINT fk_partitioned_fk_a_b_fkey;
 -- All constraints are now valid.
 SELECT conname, convalidated, conrelid::regclass FROM pg_constraint
-WHERE conrelid::regclass::text like 'fk_partitioned_fk%' ORDER BY oid::regclass::text;
+WHERE conrelid::regclass::text like 'fk_partitioned_fk%' ORDER BY conname COLLATE "C";
            conname            | convalidated |      conrelid       
 ------------------------------+--------------+---------------------
- fk_partitioned_fk_a_b_fkey   | t            | fk_partitioned_fk
  fk_partitioned_fk_1_a_b_fkey | t            | fk_partitioned_fk_1
+ fk_partitioned_fk_a_b_fkey   | t            | fk_partitioned_fk
 (2 rows)
 
 -- Attaching a child with a NOT VALID constraint.
@@ -1967,7 +1967,7 @@ TRUNCATE fk_partitioned_fk_2;
 ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 FOR VALUES FROM (1000,1000) TO (2000,2000);
 -- The child constraint will also be valid.
 SELECT conname, convalidated FROM pg_constraint
-WHERE conrelid = 'fk_partitioned_fk_2'::regclass ORDER BY oid::regclass::text;
+WHERE conrelid = 'fk_partitioned_fk_2'::regclass ORDER BY conname COLLATE "C";
            conname            | convalidated 
 ------------------------------+--------------
  fk_partitioned_fk_2_a_b_fkey | t
@@ -1984,14 +1984,14 @@ ALTER TABLE fk_partitioned_fk_3 ATTACH PARTITION fk_partitioned_fk_3_1 FOR VALUE
 ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_3 FOR VALUES FROM (2000,2000) TO (3000,3000);
 -- All constraints are now valid.
 SELECT conname, convalidated, conrelid::regclass FROM pg_constraint
-WHERE conrelid::regclass::text like 'fk_partitioned_fk%' ORDER BY oid::regclass::text;
+WHERE conrelid::regclass::text like 'fk_partitioned_fk%' ORDER BY conname COLLATE "C";
             conname             | convalidated |       conrelid        
 --------------------------------+--------------+-----------------------
- fk_partitioned_fk_a_b_fkey     | t            | fk_partitioned_fk
  fk_partitioned_fk_1_a_b_fkey   | t            | fk_partitioned_fk_1
  fk_partitioned_fk_2_a_b_fkey   | t            | fk_partitioned_fk_2
- fk_partitioned_fk_3_a_b_fkey   | t            | fk_partitioned_fk_3
  fk_partitioned_fk_3_1_a_b_fkey | t            | fk_partitioned_fk_3_1
+ fk_partitioned_fk_3_a_b_fkey   | t            | fk_partitioned_fk_3
+ fk_partitioned_fk_a_b_fkey     | t            | fk_partitioned_fk
 (5 rows)
 
 DROP TABLE fk_partitioned_fk, fk_notpartitioned_pk;
@@ -2009,30 +2009,30 @@ ALTER TABLE fk_notpartitioned_fk ADD CONSTRAINT fk_notpartitioned_fk_a_b_fkey2
 	FOREIGN KEY (a, b) REFERENCES fk_partitioned_pk NOT ENFORCED;
 -- All constraints will be invalid, and _fkey2 constraints will not be enforced.
 SELECT conname, conenforced, convalidated FROM pg_constraint
-WHERE conrelid = 'fk_notpartitioned_fk'::regclass ORDER BY oid::regclass::text;
+WHERE conrelid = 'fk_notpartitioned_fk'::regclass ORDER BY conname COLLATE "C";
              conname              | conenforced | convalidated 
 ----------------------------------+-------------+--------------
  fk_notpartitioned_fk_a_b_fkey    | t           | f
- fk_notpartitioned_fk_a_b_fkey_1  | t           | f
- fk_notpartitioned_fk_a_b_fkey_2  | t           | f
  fk_notpartitioned_fk_a_b_fkey2   | f           | f
  fk_notpartitioned_fk_a_b_fkey2_1 | f           | f
  fk_notpartitioned_fk_a_b_fkey2_2 | f           | f
+ fk_notpartitioned_fk_a_b_fkey_1  | t           | f
+ fk_notpartitioned_fk_a_b_fkey_2  | t           | f
 (6 rows)
 
 ALTER TABLE fk_notpartitioned_fk VALIDATE CONSTRAINT fk_notpartitioned_fk_a_b_fkey;
 ALTER TABLE fk_notpartitioned_fk ALTER CONSTRAINT fk_notpartitioned_fk_a_b_fkey2 ENFORCED;
 -- All constraints are now valid and enforced.
 SELECT conname, conenforced, convalidated FROM pg_constraint
-WHERE conrelid = 'fk_notpartitioned_fk'::regclass ORDER BY oid::regclass::text;
+WHERE conrelid = 'fk_notpartitioned_fk'::regclass ORDER BY conname COLLATE "C";
              conname              | conenforced | convalidated 
 ----------------------------------+-------------+--------------
  fk_notpartitioned_fk_a_b_fkey    | t           | t
- fk_notpartitioned_fk_a_b_fkey_1  | t           | t
- fk_notpartitioned_fk_a_b_fkey_2  | t           | t
  fk_notpartitioned_fk_a_b_fkey2   | t           | t
  fk_notpartitioned_fk_a_b_fkey2_1 | t           | t
  fk_notpartitioned_fk_a_b_fkey2_2 | t           | t
+ fk_notpartitioned_fk_a_b_fkey_1  | t           | t
+ fk_notpartitioned_fk_a_b_fkey_2  | t           | t
 (6 rows)
 
 -- test a self-referential FK
@@ -2042,7 +2042,7 @@ CREATE TABLE fk_partitioned_pk_3 PARTITION OF fk_partitioned_pk FOR VALUES FROM
 CREATE TABLE fk_partitioned_pk_3_1 PARTITION OF fk_partitioned_pk_3 FOR VALUES FROM (2000) TO (2100);
 SELECT conname, conenforced, convalidated FROM pg_constraint
 WHERE conrelid = 'fk_partitioned_pk'::regclass AND contype = 'f'
-ORDER BY oid::regclass::text;
+ORDER BY conname COLLATE "C";
   conname   | conenforced | convalidated 
 ------------+-------------+--------------
  selffk     | t           | f
@@ -2056,7 +2056,7 @@ ALTER TABLE fk_partitioned_pk_2 VALIDATE CONSTRAINT selffk;
 ALTER TABLE fk_partitioned_pk VALIDATE CONSTRAINT selffk;
 SELECT conname, conenforced, convalidated FROM pg_constraint
 WHERE conrelid = 'fk_partitioned_pk'::regclass AND contype = 'f'
-ORDER BY oid::regclass::text;
+ORDER BY conname COLLATE "C";
   conname   | conenforced | convalidated 
 ------------+-------------+--------------
  selffk     | t           | t
diff --git a/src/test/regress/sql/foreign_key.sql b/src/test/regress/sql/foreign_key.sql
index a93e81b42bc..21ef1931f31 100644
--- a/src/test/regress/sql/foreign_key.sql
+++ b/src/test/regress/sql/foreign_key.sql
@@ -585,7 +585,7 @@ CREATE TABLE FKTABLE (
   FOREIGN KEY (tid, fk_id_del_set_default) REFERENCES PKTABLE ON DELETE SET DEFAULT (fk_id_del_set_default, fk_id_del_set_default)
 );
 
-SELECT pg_get_constraintdef(oid) FROM pg_constraint WHERE conrelid = 'fktable'::regclass::oid ORDER BY oid;
+SELECT pg_get_constraintdef(oid) FROM pg_constraint WHERE conrelid = 'fktable'::regclass::oid ORDER BY conname COLLATE "C";
 
 INSERT INTO PKTABLE VALUES (1, 0), (1, 1), (1, 2);
 INSERT INTO FKTABLE VALUES
@@ -1449,14 +1449,14 @@ ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_1 FOR VALUES FR
 
 -- Child constraint will remain valid.
 SELECT conname, convalidated, conrelid::regclass FROM pg_constraint
-WHERE conrelid::regclass::text like 'fk_partitioned_fk%' ORDER BY oid::regclass::text;
+WHERE conrelid::regclass::text like 'fk_partitioned_fk%' ORDER BY conname COLLATE "C";
 
 -- Validate the constraint
 ALTER TABLE fk_partitioned_fk VALIDATE CONSTRAINT fk_partitioned_fk_a_b_fkey;
 
 -- All constraints are now valid.
 SELECT conname, convalidated, conrelid::regclass FROM pg_constraint
-WHERE conrelid::regclass::text like 'fk_partitioned_fk%' ORDER BY oid::regclass::text;
+WHERE conrelid::regclass::text like 'fk_partitioned_fk%' ORDER BY conname COLLATE "C";
 
 -- Attaching a child with a NOT VALID constraint.
 CREATE TABLE fk_partitioned_fk_2 (a int, b int);
@@ -1472,7 +1472,7 @@ ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 FOR VALUES FR
 
 -- The child constraint will also be valid.
 SELECT conname, convalidated FROM pg_constraint
-WHERE conrelid = 'fk_partitioned_fk_2'::regclass ORDER BY oid::regclass::text;
+WHERE conrelid = 'fk_partitioned_fk_2'::regclass ORDER BY conname COLLATE "C";
 
 -- Test case where the child constraint is invalid, the grandchild constraint
 -- is valid, and the validation for the grandchild should be skipped when a
@@ -1486,7 +1486,7 @@ ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_3 FOR VALUES FR
 
 -- All constraints are now valid.
 SELECT conname, convalidated, conrelid::regclass FROM pg_constraint
-WHERE conrelid::regclass::text like 'fk_partitioned_fk%' ORDER BY oid::regclass::text;
+WHERE conrelid::regclass::text like 'fk_partitioned_fk%' ORDER BY conname COLLATE "C";
 
 DROP TABLE fk_partitioned_fk, fk_notpartitioned_pk;
 
@@ -1505,14 +1505,14 @@ ALTER TABLE fk_notpartitioned_fk ADD CONSTRAINT fk_notpartitioned_fk_a_b_fkey2
 
 -- All constraints will be invalid, and _fkey2 constraints will not be enforced.
 SELECT conname, conenforced, convalidated FROM pg_constraint
-WHERE conrelid = 'fk_notpartitioned_fk'::regclass ORDER BY oid::regclass::text;
+WHERE conrelid = 'fk_notpartitioned_fk'::regclass ORDER BY conname COLLATE "C";
 
 ALTER TABLE fk_notpartitioned_fk VALIDATE CONSTRAINT fk_notpartitioned_fk_a_b_fkey;
 ALTER TABLE fk_notpartitioned_fk ALTER CONSTRAINT fk_notpartitioned_fk_a_b_fkey2 ENFORCED;
 
 -- All constraints are now valid and enforced.
 SELECT conname, conenforced, convalidated FROM pg_constraint
-WHERE conrelid = 'fk_notpartitioned_fk'::regclass ORDER BY oid::regclass::text;
+WHERE conrelid = 'fk_notpartitioned_fk'::regclass ORDER BY conname COLLATE "C";
 
 -- test a self-referential FK
 ALTER TABLE fk_partitioned_pk ADD CONSTRAINT selffk FOREIGN KEY (a, b) REFERENCES fk_partitioned_pk NOT VALID;
@@ -1521,12 +1521,12 @@ CREATE TABLE fk_partitioned_pk_3 PARTITION OF fk_partitioned_pk FOR VALUES FROM
 CREATE TABLE fk_partitioned_pk_3_1 PARTITION OF fk_partitioned_pk_3 FOR VALUES FROM (2000) TO (2100);
 SELECT conname, conenforced, convalidated FROM pg_constraint
 WHERE conrelid = 'fk_partitioned_pk'::regclass AND contype = 'f'
-ORDER BY oid::regclass::text;
+ORDER BY conname COLLATE "C";
 ALTER TABLE fk_partitioned_pk_2 VALIDATE CONSTRAINT selffk;
 ALTER TABLE fk_partitioned_pk VALIDATE CONSTRAINT selffk;
 SELECT conname, conenforced, convalidated FROM pg_constraint
 WHERE conrelid = 'fk_partitioned_pk'::regclass AND contype = 'f'
-ORDER BY oid::regclass::text;
+ORDER BY conname COLLATE "C";
 
 DROP TABLE fk_notpartitioned_fk, fk_partitioned_pk;
 
-- 
2.37.1 (Apple Git-137.1)

