Skip to content

Commit d79cd55

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 f7642cf commit d79cd55

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
@@ -2494,8 +2494,15 @@ rename_constraint_internal(Oid myrelid,
24942494
ReleaseSysCache(tuple);
24952495

24962496
if (targetrelation)
2497+
{
24972498
relation_close(targetrelation, NoLock); /* close rel but keep lock */
24982499

2500+
/*
2501+
* Invalidate relcache so as others can see the new constraint name.
2502+
*/
2503+
CacheInvalidateRelcache(targetrelation);
2504+
}
2505+
24992506
return address;
25002507
}
25012508

src/test/regress/expected/alter_table.out

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,28 @@ ALTER TABLE IF EXISTS constraint_not_exist RENAME CONSTRAINT con3 TO con3foo; --
342342
NOTICE: relation "constraint_not_exist" does not exist, skipping
343343
ALTER TABLE IF EXISTS constraint_rename_test ADD CONSTRAINT con4 UNIQUE (a);
344344
NOTICE: relation "constraint_rename_test" does not exist, skipping
345+
-- renaming constraints with cache reset of target relation
346+
CREATE TABLE constraint_rename_cache (a int,
347+
CONSTRAINT chk_a CHECK (a > 0),
348+
PRIMARY KEY (a));
349+
ALTER TABLE constraint_rename_cache
350+
RENAME CONSTRAINT chk_a TO chk_a_new;
351+
ALTER TABLE constraint_rename_cache
352+
RENAME CONSTRAINT constraint_rename_cache_pkey TO chk_a_gt_zero;
353+
CREATE TABLE like_constraint_rename_cache
354+
(LIKE constraint_rename_cache INCLUDING ALL);
355+
\d like_constraint_rename_cache
356+
Table "public.like_constraint_rename_cache"
357+
Column | Type | Modifiers
358+
--------+---------+-----------
359+
a | integer | not null
360+
Indexes:
361+
"like_constraint_rename_cache_pkey" PRIMARY KEY, btree (a)
362+
Check constraints:
363+
"chk_a_new" CHECK (a > 0)
364+
365+
DROP TABLE constraint_rename_cache;
366+
DROP TABLE like_constraint_rename_cache;
345367
-- FOREIGN KEY CONSTRAINT adding TEST
346368
CREATE TABLE tmp2 (a int primary key);
347369
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
@@ -251,6 +251,20 @@ DROP TABLE constraint_rename_test;
251251
ALTER TABLE IF EXISTS constraint_not_exist RENAME CONSTRAINT con3 TO con3foo; -- ok
252252
ALTER TABLE IF EXISTS constraint_rename_test ADD CONSTRAINT con4 UNIQUE (a);
253253

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

256270
CREATE TABLE tmp2 (a int primary key);

0 commit comments

Comments
 (0)