From fcda5ac3acef50624a26bab1ba063b99d7d16b02 Mon Sep 17 00:00:00 2001
From: Hayato Kuroda <kuroda.hayato@fujitsu.com>
Date: Mon, 2 Nov 2026 17:24:15 +0900
Subject: [PATCH v1-nocfbot] Reproduce the cache lookup failure

---
 src/backend/catalog/pg_inherits.c             | 11 ++++
 src/test/modules/injection_points/Makefile    |  1 +
 .../expected/pub-concurrent-drop.out          | 27 +++++++++
 src/test/modules/injection_points/meson.build |  1 +
 .../specs/pub-concurrent-drop.spec            | 57 +++++++++++++++++++
 5 files changed, 97 insertions(+)
 create mode 100644 src/test/modules/injection_points/expected/pub-concurrent-drop.out
 create mode 100644 src/test/modules/injection_points/specs/pub-concurrent-drop.spec

diff --git a/src/backend/catalog/pg_inherits.c b/src/backend/catalog/pg_inherits.c
index 23fb7886cfb..0554bcc3f0d 100644
--- a/src/backend/catalog/pg_inherits.c
+++ b/src/backend/catalog/pg_inherits.c
@@ -29,6 +29,7 @@
 #include "utils/builtins.h"
 #include "utils/fmgroids.h"
 #include "utils/hsearch.h"
+#include "utils/injection_point.h"
 #include "utils/snapmgr.h"
 #include "utils/syscache.h"
 
@@ -289,6 +290,16 @@ find_all_inheritors(Oid parentrelId, LOCKMODE lockmode, List **numparents)
 		List	   *currentchildren;
 		ListCell   *lc;
 
+#ifdef USE_INJECTION_POINTS
+		if (IS_INJECTION_POINT_ATTACHED("find-all-inheritors-before-scan"))
+		{
+			char		currentrelstr[MAXINT8LEN + 1];
+
+			snprintf(currentrelstr, sizeof(currentrelstr), "%u", currentrel);
+			INJECTION_POINT("find-all-inheritors-before-scan", currentrelstr);
+		}
+#endif
+
 		/* Get the direct children of this rel */
 		currentchildren = find_inheritance_children(currentrel, lockmode);
 
diff --git a/src/test/modules/injection_points/Makefile b/src/test/modules/injection_points/Makefile
index 8e2dfaa2384..22044fecf77 100644
--- a/src/test/modules/injection_points/Makefile
+++ b/src/test/modules/injection_points/Makefile
@@ -36,6 +36,7 @@ ISOLATION = basic \
 	    syscache-update-pruned \
 	    $(WAIT_CLEANUP_TST) \
 	    heap_lock_update \
+	    pub-concurrent-drop \
 	    on_conflict_probe_window \
 	    multixact-aborted-updater
 
diff --git a/src/test/modules/injection_points/expected/pub-concurrent-drop.out b/src/test/modules/injection_points/expected/pub-concurrent-drop.out
new file mode 100644
index 00000000000..88f62ad330e
--- /dev/null
+++ b/src/test/modules/injection_points/expected/pub-concurrent-drop.out
@@ -0,0 +1,27 @@
+Parsed test spec with 2 sessions
+
+starting permutation: add_root drop_victim wakeup
+injection_points_attach
+-----------------------
+                       
+(1 row)
+
+step add_root: 
+	DO $$
+	BEGIN
+		ALTER PUBLICATION pub ADD TABLE root;
+	EXCEPTION WHEN others THEN
+		RAISE WARNING 'got: %', regexp_replace(sqlerrm, '[0-9]+', '*victim OID filtered*');
+	END
+	$$;
+ <waiting ...>
+step drop_victim: DROP TABLE victim;
+step wakeup: 
+	SELECT injection_points_wakeup('find-all-inheritors-before-scan');
+
+injection_points_wakeup
+-----------------------
+                       
+(1 row)
+
+step add_root: <... completed>
diff --git a/src/test/modules/injection_points/meson.build b/src/test/modules/injection_points/meson.build
index 97e7a736282..1a2237d3a22 100644
--- a/src/test/modules/injection_points/meson.build
+++ b/src/test/modules/injection_points/meson.build
@@ -43,6 +43,7 @@ injection_points_isolation = [
   'ri_fastpath_snapshot',
   'syscache-update-pruned',
   'heap_lock_update',
+  'pub-concurrent-drop',
   'on_conflict_probe_window',
   'multixact-aborted-updater',
 ]
diff --git a/src/test/modules/injection_points/specs/pub-concurrent-drop.spec b/src/test/modules/injection_points/specs/pub-concurrent-drop.spec
new file mode 100644
index 00000000000..4274ce5a768
--- /dev/null
+++ b/src/test/modules/injection_points/specs/pub-concurrent-drop.spec
@@ -0,0 +1,57 @@
+# Test concurrently dropping a partition while its publication relations are
+# being collected.
+
+setup
+{
+	CREATE EXTENSION injection_points;
+
+	CREATE TABLE root (a int, b int) PARTITION BY RANGE (a);
+	CREATE TABLE p1 PARTITION OF root FOR VALUES FROM (0) TO (10)
+		PARTITION BY RANGE (b);
+	CREATE TABLE p2 PARTITION OF root FOR VALUES FROM (10) TO (20)
+		PARTITION BY RANGE (b);
+	CREATE TABLE trigger PARTITION OF p1 FOR VALUES FROM (0) TO (10)
+		PARTITION BY HASH (a);
+	CREATE TABLE leaf PARTITION OF trigger
+		FOR VALUES WITH (MODULUS 1, REMAINDER 0);
+	CREATE TABLE victim PARTITION OF p2 FOR VALUES FROM (0) TO (10);
+
+	CREATE PUBLICATION pub;
+}
+
+teardown
+{
+	DROP PUBLICATION pub;
+	DROP TABLE root;
+	DROP EXTENSION injection_points;
+}
+
+session s1
+setup
+{
+	SELECT injection_points_set_local();
+	SELECT injection_points_attach(
+		'find-all-inheritors-before-scan',
+		'wait',
+		'trigger'::regclass::oid::text);
+}
+
+step add_root
+{
+	DO $$
+	BEGIN
+		ALTER PUBLICATION pub ADD TABLE root;
+	EXCEPTION WHEN others THEN
+		RAISE WARNING 'got: %', regexp_replace(sqlerrm, '[0-9]+', '*victim OID filtered*');
+	END
+	$$;
+}
+
+session s2
+step drop_victim { DROP TABLE victim; }
+step wakeup
+{
+	SELECT injection_points_wakeup('find-all-inheritors-before-scan');
+}
+
+permutation add_root drop_victim wakeup
-- 
2.52.0

