From a4e0ca13256e236004c55526b2daf71a1b0643df Mon Sep 17 00:00:00 2001 From: Andrey Borodin Date: Tue, 21 Jul 2026 14:52:16 +0500 Subject: [PATCH v2 5/5] Address Surya's feedback --- .../t/012_plpgsql_composite_replan_race.pl | 15 +++++++++++++++ src/test/regress/sql/alter_table.sql | 12 +++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/test/modules/test_misc/t/012_plpgsql_composite_replan_race.pl b/src/test/modules/test_misc/t/012_plpgsql_composite_replan_race.pl index 0c5f169000a..33a246e7470 100644 --- a/src/test/modules/test_misc/t/012_plpgsql_composite_replan_race.pl +++ b/src/test/modules/test_misc/t/012_plpgsql_composite_replan_race.pl @@ -80,6 +80,21 @@ COMMIT; \echo ddl_done ]); +# The concurrent DDL must now be blocked: the in-progress RETURN QUERY holds +# AccessShareLock on the composite type's relation, so ALTER TYPE waits for +# AccessExclusiveLock on the same relid. Verify the lock directly via the DDL +# backend pid, rather than only observing the row-shape symptom below. +$node->poll_query_until('postgres', qq[ +SELECT EXISTS ( + SELECT 1 + FROM pg_locks + WHERE pid = $ddl_pid + AND NOT granted + AND locktype = 'relation' + AND relation = (SELECT typrelid FROM pg_type WHERE typname = 'planinv_ct') +); +]) or die 'concurrent DDL is not waiting on the composite type lock'; + $node->safe_psql('postgres', "SELECT injection_points_wakeup('plpgsql-return-query-before-exec');"); diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f4216ceb2e1..f753cabc41a 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -2059,8 +2059,9 @@ DROP TYPE test_type_empty; -- Cached plans for queries that scan a set-returning function returning a -- named composite type must be invalidated when ALTER TYPE ADD ATTRIBUTE -- widens that type. The fix records the composite's underlying relation OID --- (pg_type.typrelid) in the plan's invalItems so the relcache invalidation --- broadcast by ALTER TYPE reaches the cached plan. +-- (pg_type.typrelid) in the plan's list of referenced relations +-- (glob->relationOids, checked by PlanCacheRelCallback) so the relcache +-- invalidation broadcast by ALTER TYPE reaches the cached plan. -- -- Without the fix the plan is never marked stale. A PL/pgSQL function whose -- RETURN QUERY calls such an SRF raises "structure of query does not match @@ -2068,9 +2069,10 @@ DROP TYPE test_type_empty; -- count while the SRF (independently replanned via table relcache) already -- returns the new one. -- --- SECURITY DEFINER prevents inlining; without inlining the outer plan holds --- only the proc OID in invalItems, so only the typrelid dependency added by --- the fix triggers its invalidation. +-- SECURITY DEFINER prevents inlining; without inlining the outer plan tracks +-- only the proc OID (in glob->invalItems, checked by PlanCacheObjectCallback), +-- so only the typrelid relation dependency added by the fix triggers its +-- invalidation. -- CREATE TYPE planinv_ct AS (a int, b int); CREATE TABLE planinv_tbl (a int, b int); -- 2.50.1 (Apple Git-155)