Skip to content

Commit d5d86e2

Browse files
committed
Make constraint rename issue relcache invalidation on target relation
When a constraint gets renamed, it may have associated with it a target relation (for example domain constraints don't have one). Not invalidating the target relation cache when issuing the renaming can result in issues with subsequent commands that refer to the old constraint name using the relation cache, causing various failures. One pattern spotted was using CREATE TABLE LIKE after a constraint renaming. Reported-by: Stuart <sfbarbee@gmail.com> Author: Amit Langote Reviewed-by: Michael Paquier Discussion: https://postgr.es/m/2047094.V130LYfLq4@station53.ousa.org
1 parent b10d225 commit d5d86e2

File tree

3 files changed

+43
-0
lines changed

3 files changed

+43
-0
lines changed

src/backend/commands/tablecmds.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2428,8 +2428,15 @@ rename_constraint_internal(Oid myrelid,
24282428
ReleaseSysCache(tuple);
24292429

24302430
if (targetrelation)
2431+
{
24312432
relation_close(targetrelation, NoLock); /* close rel but keep lock */
24322433

2434+
/*
2435+
* Invalidate relcache so as others can see the new constraint name.
2436+
*/
2437+
CacheInvalidateRelcache(targetrelation);
2438+
}
2439+
24332440
return constraintOid;
24342441
}
24352442

src/test/regress/expected/alter_table.out

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,28 @@ DROP TABLE constraint_rename_test2;
340340
DROP TABLE constraint_rename_test;
341341
ALTER TABLE IF EXISTS constraint_rename_test ADD CONSTRAINT con4 UNIQUE (a);
342342
NOTICE: relation "constraint_rename_test" does not exist, skipping
343+
-- renaming constraints with cache reset of target relation
344+
CREATE TABLE constraint_rename_cache (a int,
345+
CONSTRAINT chk_a CHECK (a > 0),
346+
PRIMARY KEY (a));
347+
ALTER TABLE constraint_rename_cache
348+
RENAME CONSTRAINT chk_a TO chk_a_new;
349+
ALTER TABLE constraint_rename_cache
350+
RENAME CONSTRAINT constraint_rename_cache_pkey TO chk_a_gt_zero;
351+
CREATE TABLE like_constraint_rename_cache
352+
(LIKE constraint_rename_cache INCLUDING ALL);
353+
\d like_constraint_rename_cache
354+
Table "public.like_constraint_rename_cache"
355+
Column | Type | Modifiers
356+
--------+---------+-----------
357+
a | integer | not null
358+
Indexes:
359+
"like_constraint_rename_cache_pkey" PRIMARY KEY, btree (a)
360+
Check constraints:
361+
"chk_a_new" CHECK (a > 0)
362+
363+
DROP TABLE constraint_rename_cache;
364+
DROP TABLE like_constraint_rename_cache;
343365
-- FOREIGN KEY CONSTRAINT adding TEST
344366
CREATE TABLE tmp2 (a int primary key);
345367
CREATE TABLE tmp3 (a int, b int);

src/test/regress/sql/alter_table.sql

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,20 @@ DROP TABLE constraint_rename_test2;
250250
DROP TABLE constraint_rename_test;
251251
ALTER TABLE IF EXISTS constraint_rename_test ADD CONSTRAINT con4 UNIQUE (a);
252252

253+
-- renaming constraints with cache reset of target relation
254+
CREATE TABLE constraint_rename_cache (a int,
255+
CONSTRAINT chk_a CHECK (a > 0),
256+
PRIMARY KEY (a));
257+
ALTER TABLE constraint_rename_cache
258+
RENAME CONSTRAINT chk_a TO chk_a_new;
259+
ALTER TABLE constraint_rename_cache
260+
RENAME CONSTRAINT constraint_rename_cache_pkey TO chk_a_gt_zero;
261+
CREATE TABLE like_constraint_rename_cache
262+
(LIKE constraint_rename_cache INCLUDING ALL);
263+
\d like_constraint_rename_cache
264+
DROP TABLE constraint_rename_cache;
265+
DROP TABLE like_constraint_rename_cache;
266+
253267
-- FOREIGN KEY CONSTRAINT adding TEST
254268

255269
CREATE TABLE tmp2 (a int primary key);

0 commit comments

Comments
 (0)