Skip to content

Commit 9b8ed7d

Browse files
jianhe-funCommitfest Bot
authored andcommitted
fix concurrent issue in ALTER DOMAIN
we should ensure that two backends can not ALTER DOMAIN at the same time discussion: https://postgr.es/m/
1 parent f047814 commit 9b8ed7d

File tree

4 files changed

+126
-0
lines changed

4 files changed

+126
-0
lines changed

src/backend/commands/typecmds.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2631,6 +2631,13 @@ AlterDomainDefault(List *names, Node *defaultRaw)
26312631
typename = makeTypeNameFromNameList(names);
26322632
domainoid = typenameTypeId(NULL, typename);
26332633

2634+
/*
2635+
* Acquire a lock on the domain type, which we won't release until commit.
2636+
* This ensures that two backends aren't concurrently modifying the same
2637+
* domain type.
2638+
*/
2639+
LockDatabaseObject(TypeRelationId, domainoid, 0, AccessExclusiveLock);
2640+
26342641
/* Look up the domain in the type table */
26352642
rel = table_open(TypeRelationId, RowExclusiveLock);
26362643

@@ -2753,6 +2760,13 @@ AlterDomainNotNull(List *names, bool notNull)
27532760
typename = makeTypeNameFromNameList(names);
27542761
domainoid = typenameTypeId(NULL, typename);
27552762

2763+
/*
2764+
* Acquire a lock on the domain type, which we won't release until commit.
2765+
* This ensures that two backends aren't concurrently modifying the same
2766+
* domain type.
2767+
*/
2768+
LockDatabaseObject(TypeRelationId, domainoid, 0, AccessExclusiveLock);
2769+
27562770
/* Look up the domain in the type table */
27572771
typrel = table_open(TypeRelationId, RowExclusiveLock);
27582772

@@ -2844,6 +2858,13 @@ AlterDomainDropConstraint(List *names, const char *constrName,
28442858
typename = makeTypeNameFromNameList(names);
28452859
domainoid = typenameTypeId(NULL, typename);
28462860

2861+
/*
2862+
* Acquire a lock on the domain type, which we won't release until commit.
2863+
* This ensures that two backends aren't concurrently modifying the same
2864+
* domain type.
2865+
*/
2866+
LockDatabaseObject(TypeRelationId, domainoid, 0, AccessExclusiveLock);
2867+
28472868
/* Look up the domain in the type table */
28482869
rel = table_open(TypeRelationId, RowExclusiveLock);
28492870

@@ -2948,6 +2969,13 @@ AlterDomainAddConstraint(List *names, Node *newConstraint,
29482969
typename = makeTypeNameFromNameList(names);
29492970
domainoid = typenameTypeId(NULL, typename);
29502971

2972+
/*
2973+
* Acquire a lock on the domain type, which we won't release until commit.
2974+
* This ensures that two backends aren't concurrently modifying the same
2975+
* domain type.
2976+
*/
2977+
LockDatabaseObject(TypeRelationId, domainoid, 0, AccessExclusiveLock);
2978+
29512979
/* Look up the domain in the type table */
29522980
typrel = table_open(TypeRelationId, RowExclusiveLock);
29532981

@@ -3050,6 +3078,13 @@ AlterDomainValidateConstraint(List *names, const char *constrName)
30503078
typename = makeTypeNameFromNameList(names);
30513079
domainoid = typenameTypeId(NULL, typename);
30523080

3081+
/*
3082+
* Acquire a lock on the domain type, which we won't release until commit.
3083+
* This ensures that two backends aren't concurrently modifying the same
3084+
* domain type.
3085+
*/
3086+
LockDatabaseObject(TypeRelationId, domainoid, 0, AccessExclusiveLock);
3087+
30533088
/* Look up the domain in the type table */
30543089
typrel = table_open(TypeRelationId, AccessShareLock);
30553090

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
Parsed test spec with 2 sessions
2+
3+
starting permutation: b1 b2 s_add s2_drop c1 c2
4+
step b1: BEGIN;
5+
step b2: BEGIN;
6+
step s_add: ALTER DOMAIN dd ADD CONSTRAINT dd_check1 CHECK(VALUE > 0);
7+
step s2_drop: DROP DOMAIN dd; <waiting ...>
8+
step c1: COMMIT;
9+
step s2_drop: <... completed>
10+
step c2: COMMIT;
11+
12+
starting permutation: b1 b2 s_add s2_set c1 c2
13+
step b1: BEGIN;
14+
step b2: BEGIN;
15+
step s_add: ALTER DOMAIN dd ADD CONSTRAINT dd_check1 CHECK(VALUE > 0);
16+
step s2_set: ALTER DOMAIN dd SET DEFAULT 3; <waiting ...>
17+
step c1: COMMIT;
18+
step s2_set: <... completed>
19+
step c2: COMMIT;
20+
21+
starting permutation: b1 b2 s1_set s1_drop s2_set c1 c2
22+
step b1: BEGIN;
23+
step b2: BEGIN;
24+
step s1_set: ALTER DOMAIN dd SET NOT NULL;
25+
step s1_drop: ALTER DOMAIN dd DROP DEFAULT;
26+
step s2_set: ALTER DOMAIN dd SET DEFAULT 3; <waiting ...>
27+
step c1: COMMIT;
28+
step s2_set: <... completed>
29+
step c2: COMMIT;
30+
31+
starting permutation: b1 b2 s1_drop s2_set c1 c2
32+
step b1: BEGIN;
33+
step b2: BEGIN;
34+
step s1_drop: ALTER DOMAIN dd DROP DEFAULT;
35+
step s2_set: ALTER DOMAIN dd SET DEFAULT 3; <waiting ...>
36+
step c1: COMMIT;
37+
step s2_set: <... completed>
38+
step c2: COMMIT;
39+
40+
starting permutation: b1 b2 s1_set s1_drop2 v2 c1 c2
41+
step b1: BEGIN;
42+
step b2: BEGIN;
43+
step s1_set: ALTER DOMAIN dd SET NOT NULL;
44+
step s1_drop2: ALTER DOMAIN dd DROP CONSTRAINT cc;
45+
step v2: ALTER DOMAIN dd VALIDATE CONSTRAINT cc; <waiting ...>
46+
step c1: COMMIT;
47+
step v2: <... completed>
48+
ERROR: constraint "cc" of domain "dd" does not exist
49+
step c2: COMMIT;
50+
51+
starting permutation: b1 b2 v2 s1_drop2 c2 c1
52+
step b1: BEGIN;
53+
step b2: BEGIN;
54+
step v2: ALTER DOMAIN dd VALIDATE CONSTRAINT cc;
55+
step s1_drop2: ALTER DOMAIN dd DROP CONSTRAINT cc; <waiting ...>
56+
step c2: COMMIT;
57+
step s1_drop2: <... completed>
58+
step c1: COMMIT;

src/test/isolation/isolation_schedule

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,3 +118,4 @@ test: serializable-parallel-2
118118
test: serializable-parallel-3
119119
test: matview-write-skew
120120
test: lock-nowait
121+
test: domains

src/test/isolation/specs/domains.spec

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
setup
2+
{
3+
CREATE DOMAIN dd AS INT;
4+
ALTER DOMAIN dd ADD CONSTRAINT cc CHECK(VALUE > 1) NOT VALID;
5+
}
6+
7+
teardown
8+
{
9+
DROP DOMAIN IF EXISTS dd CASCADE;
10+
}
11+
12+
session s1
13+
step b1 { BEGIN; }
14+
step s_add { ALTER DOMAIN dd ADD CONSTRAINT dd_check1 CHECK(VALUE > 0); }
15+
step s1_drop { ALTER DOMAIN dd DROP DEFAULT; }
16+
step s1_set { ALTER DOMAIN dd SET NOT NULL; }
17+
step s1_drop2 { ALTER DOMAIN dd DROP CONSTRAINT cc;}
18+
step c1 { COMMIT; }
19+
20+
session s2
21+
step b2 { BEGIN; }
22+
step s2_set { ALTER DOMAIN dd SET DEFAULT 3; }
23+
step s2_drop { DROP DOMAIN dd; }
24+
step v2 { ALTER DOMAIN dd VALIDATE CONSTRAINT cc; }
25+
step c2 { COMMIT; }
26+
27+
permutation b1 b2 s_add s2_drop c1 c2
28+
permutation b1 b2 s_add s2_set c1 c2
29+
permutation b1 b2 s1_set s1_drop s2_set c1 c2
30+
permutation b1 b2 s1_drop s2_set c1 c2
31+
permutation b1 b2 s1_set s1_drop2 v2 c1 c2
32+
permutation b1 b2 v2 s1_drop2 c2 c1

0 commit comments

Comments
 (0)