mirror of
https://github.com/postgres/postgres.git
synced 2025-10-21 02:52:47 +03:00
Reduce lock level for ALTER DOMAIN ... VALIDATE CONSTRAINT
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
This commit is contained in:
@@ -126,7 +126,7 @@ static Oid findTypeSubscriptingFunction(List *procname, Oid typeOid);
|
|||||||
static Oid findRangeSubOpclass(List *opcname, Oid subtype);
|
static Oid findRangeSubOpclass(List *opcname, Oid subtype);
|
||||||
static Oid findRangeCanonicalFunction(List *procname, Oid typeOid);
|
static Oid findRangeCanonicalFunction(List *procname, Oid typeOid);
|
||||||
static Oid findRangeSubtypeDiffFunction(List *procname, Oid subtype);
|
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 void validateDomainNotNullConstraint(Oid domainoid);
|
||||||
static List *get_rels_with_domain(Oid domainOid, LOCKMODE lockmode);
|
static List *get_rels_with_domain(Oid domainOid, LOCKMODE lockmode);
|
||||||
static void checkEnumOwner(HeapTuple tup);
|
static void checkEnumOwner(HeapTuple tup);
|
||||||
@@ -2986,7 +2986,7 @@ AlterDomainAddConstraint(List *names, Node *newConstraint,
|
|||||||
* to.
|
* to.
|
||||||
*/
|
*/
|
||||||
if (!constr->skip_validation)
|
if (!constr->skip_validation)
|
||||||
validateDomainCheckConstraint(domainoid, ccbin);
|
validateDomainCheckConstraint(domainoid, ccbin, ShareLock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We must send out an sinval message for the domain, to ensure that
|
* 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);
|
val = SysCacheGetAttrNotNull(CONSTROID, tuple, Anum_pg_constraint_conbin);
|
||||||
conbin = TextDatumGetCString(val);
|
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.
|
* 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
|
* Verify that all columns currently using the domain satisfy the given check
|
||||||
* constraint expression.
|
* 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
|
static void
|
||||||
validateDomainCheckConstraint(Oid domainoid, const char *ccbin)
|
validateDomainCheckConstraint(Oid domainoid, const char *ccbin, LOCKMODE lockmode)
|
||||||
{
|
{
|
||||||
Expr *expr = (Expr *) stringToNode(ccbin);
|
Expr *expr = (Expr *) stringToNode(ccbin);
|
||||||
List *rels;
|
List *rels;
|
||||||
@@ -3210,9 +3222,7 @@ validateDomainCheckConstraint(Oid domainoid, const char *ccbin)
|
|||||||
exprstate = ExecPrepareExpr(expr, estate);
|
exprstate = ExecPrepareExpr(expr, estate);
|
||||||
|
|
||||||
/* Fetch relation list with attributes based on this domain */
|
/* Fetch relation list with attributes based on this domain */
|
||||||
/* ShareLock is sufficient to prevent concurrent data changes */
|
rels = get_rels_with_domain(domainoid, lockmode);
|
||||||
|
|
||||||
rels = get_rels_with_domain(domainoid, ShareLock);
|
|
||||||
|
|
||||||
foreach(rt, rels)
|
foreach(rt, rels)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user