git.postgresql.org Git - postgresql.git/commitdiff

git projects / postgresql.git / commitdiff
? search:
summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 123e65f)
Reduce lock level for ALTER DOMAIN ... VALIDATE CONSTRAINT
2025年8月22日 06:51:29 +0000 (08:51 +0200)
2025年8月22日 06:56:11 +0000 (08:56 +0200)
Reduce from ShareLock to ShareUpdateExclusivelock. Validation during
ALTER DOMAIN ... ADD CONSTRAINT keeps using ShareLock.

Example:

create domain d1 as int;
create table t (a d1);
alter domain d1 add constraint cc10 check (value > 10) not valid;

begin;
alter domain d1 validate constraint cc10;

-- another session
insert into t values (8);

Now we should still be able to perform DML operations on table t while
the domain constraint is being validated. The equivalent works
already on table constraints.

Author: jian he <jian.universality@gmail.com>
Reviewed-by: Dilip Kumar <dilipbalaut@gmail.com>
Reviewed-by: wenhui qiu <qiuwenhuifx@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/CACJufxHz92A88NLRTA2msgE2dpXpE-EoZ2QO61od76-6bfqurA%40mail.gmail.com


diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 26d985193aea42888c250b977cdc2f0d5e91fd75..c6de04819f1747aa987097ac52ea9515550cae75 100644 (file)
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -126,7 +126,7 @@ static Oid findTypeSubscriptingFunction(List *procname, Oid typeOid);
static Oid findRangeSubOpclass(List *opcname, Oid subtype);
static Oid findRangeCanonicalFunction(List *procname, Oid typeOid);
static Oid findRangeSubtypeDiffFunction(List *procname, Oid subtype);
-static void validateDomainCheckConstraint(Oid domainoid, const char *ccbin);
+static void validateDomainCheckConstraint(Oid domainoid, const char *ccbin, LOCKMODE lockmode);
static void validateDomainNotNullConstraint(Oid domainoid);
static List *get_rels_with_domain(Oid domainOid, LOCKMODE lockmode);
static void checkEnumOwner(HeapTuple tup);
@@ -2986,7 +2986,7 @@ AlterDomainAddConstraint(List *names, Node *newConstraint,
* to.
*/
if (!constr->skip_validation)
- validateDomainCheckConstraint(domainoid, ccbin);
+ validateDomainCheckConstraint(domainoid, ccbin, ShareLock);
/*
* We must send out an sinval message for the domain, to ensure that
@@ -3098,7 +3098,12 @@ AlterDomainValidateConstraint(List *names, const char *constrName)
val = SysCacheGetAttrNotNull(CONSTROID, tuple, Anum_pg_constraint_conbin);
conbin = TextDatumGetCString(val);
- validateDomainCheckConstraint(domainoid, conbin);
+ /*
+ * Locking related relations with ShareUpdateExclusiveLock is ok because
+ * not-yet-valid constraints are still enforced against concurrent inserts
+ * or updates.
+ */
+ validateDomainCheckConstraint(domainoid, conbin, ShareUpdateExclusiveLock);
/*
* Now update the catalog, while we have the door open.
@@ -3191,9 +3196,16 @@ validateDomainNotNullConstraint(Oid domainoid)
/*
* Verify that all columns currently using the domain satisfy the given check
* constraint expression.
+ *
+ * It is used to validate existing constraints and to add newly created check
+ * constraints to a domain.
+ *
+ * The lockmode is used for relations using the domain. It should be
+ * ShareLock when adding a new constraint to domain. It can be
+ * ShareUpdateExclusiveLock when validating an existing constraint.
*/
static void
-validateDomainCheckConstraint(Oid domainoid, const char *ccbin)
+validateDomainCheckConstraint(Oid domainoid, const char *ccbin, LOCKMODE lockmode)
{
Expr *expr = (Expr *) stringToNode(ccbin);
List *rels;
@@ -3210,9 +3222,7 @@ validateDomainCheckConstraint(Oid domainoid, const char *ccbin)
exprstate = ExecPrepareExpr(expr, estate);
/* Fetch relation list with attributes based on this domain */
- /* ShareLock is sufficient to prevent concurrent data changes */
-
- rels = get_rels_with_domain(domainoid, ShareLock);
+ rels = get_rels_with_domain(domainoid, lockmode);
foreach(rt, rels)
{
This is the main PostgreSQL git repository.
RSS Atom

AltStyle によって変換されたページ (->オリジナル) /