aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Paquier <michael@paquier.xyz>2018-12-17 10:34:44 +0900
committerMichael Paquier <michael@paquier.xyz>2018-12-17 10:34:44 +0900
commitb13fd344c5fce6a2f95b758e97b79eb00adf2731 (patch)
tree2dd60ace2ee6313cc28cb22193ae9b5b1e09c8fc
parenta73d08319537d807a520a72bc5bd17279672c3de (diff)
downloadpostgresql-b13fd344c5fce6a2f95b758e97b79eb00adf2731.tar.gz
postgresql-b13fd344c5fce6a2f95b758e97b79eb00adf2731.zip
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
-rw-r--r--src/backend/commands/tablecmds.c7
-rw-r--r--src/test/regress/expected/alter_table.out22
-rw-r--r--src/test/regress/sql/alter_table.sql14
3 files changed, 43 insertions, 0 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index d6d0de1b01b..fe75f9e80bb 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -3019,8 +3019,15 @@ rename_constraint_internal(Oid myrelid,
ReleaseSysCache(tuple);
if (targetrelation)
+ {
relation_close(targetrelation, NoLock); /* close rel but keep lock */
+ /*
+ * Invalidate relcache so as others can see the new constraint name.
+ */
+ CacheInvalidateRelcache(targetrelation);
+ }
+
return address;
}
diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out
index 38ede0a4730..3fed5812bce 100644
--- a/src/test/regress/expected/alter_table.out
+++ b/src/test/regress/expected/alter_table.out
@@ -393,6 +393,28 @@ ALTER TABLE IF EXISTS constraint_not_exist RENAME CONSTRAINT con3 TO con3foo; --
NOTICE: relation "constraint_not_exist" does not exist, skipping
ALTER TABLE IF EXISTS constraint_rename_test ADD CONSTRAINT con4 UNIQUE (a);
NOTICE: relation "constraint_rename_test" does not exist, skipping
+-- renaming constraints with cache reset of target relation
+CREATE TABLE constraint_rename_cache (a int,
+ CONSTRAINT chk_a CHECK (a > 0),
+ PRIMARY KEY (a));
+ALTER TABLE constraint_rename_cache
+ RENAME CONSTRAINT chk_a TO chk_a_new;
+ALTER TABLE constraint_rename_cache
+ RENAME CONSTRAINT constraint_rename_cache_pkey TO chk_a_gt_zero;
+CREATE TABLE like_constraint_rename_cache
+ (LIKE constraint_rename_cache INCLUDING ALL);
+\d like_constraint_rename_cache
+ Table "public.like_constraint_rename_cache"
+ Column | Type | Collation | Nullable | Default
+--------+---------+-----------+----------+---------
+ a | integer | | not null |
+Indexes:
+ "like_constraint_rename_cache_pkey" PRIMARY KEY, btree (a)
+Check constraints:
+ "chk_a_new" CHECK (a > 0)
+
+DROP TABLE constraint_rename_cache;
+DROP TABLE like_constraint_rename_cache;
-- FOREIGN KEY CONSTRAINT adding TEST
CREATE TABLE attmp2 (a int primary key);
CREATE TABLE attmp3 (a int, b int);
diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql
index 137f2d8ed03..e5a85c238b5 100644
--- a/src/test/regress/sql/alter_table.sql
+++ b/src/test/regress/sql/alter_table.sql
@@ -289,6 +289,20 @@ DROP TABLE constraint_rename_test;
ALTER TABLE IF EXISTS constraint_not_exist RENAME CONSTRAINT con3 TO con3foo; -- ok
ALTER TABLE IF EXISTS constraint_rename_test ADD CONSTRAINT con4 UNIQUE (a);
+-- renaming constraints with cache reset of target relation
+CREATE TABLE constraint_rename_cache (a int,
+ CONSTRAINT chk_a CHECK (a > 0),
+ PRIMARY KEY (a));
+ALTER TABLE constraint_rename_cache
+ RENAME CONSTRAINT chk_a TO chk_a_new;
+ALTER TABLE constraint_rename_cache
+ RENAME CONSTRAINT constraint_rename_cache_pkey TO chk_a_gt_zero;
+CREATE TABLE like_constraint_rename_cache
+ (LIKE constraint_rename_cache INCLUDING ALL);
+\d like_constraint_rename_cache
+DROP TABLE constraint_rename_cache;
+DROP TABLE like_constraint_rename_cache;
+
-- FOREIGN KEY CONSTRAINT adding TEST
CREATE TABLE attmp2 (a int primary key);