]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Make ALTER DOMAIN VALIDATE CONSTRAINT no-op when constraint is already validated
authorPeter Eisentraut <peter@eisentraut.org>
Tue, 24 Feb 2026 09:56:17 +0000 (10:56 +0100)
committerPeter Eisentraut <peter@eisentraut.org>
Tue, 24 Feb 2026 09:58:36 +0000 (10:58 +0100)
Currently, AlterDomainValidateConstraint will re-validate a constraint
that has already been validated, which would just waste cycles.  This
operation should be a no-op when the constraint is already validated.
This also aligns with ATExecValidateConstraint.

Author: jian he <jian.universality@gmail.com>
Discussion: https://postgr.es/m/CACJufxG=-Dv9fPJHqkA9c-wGZ2dDOWOXSp-X-0K_G7r-DgaASw@mail.gmail.com

src/backend/commands/typecmds.c

index 288edb25f2f4166b97d10d921f5e35bb4b374a9d..3dab6bb5a797340410aa50ae2215b1f4b7377aa6 100644 (file)
@@ -3052,6 +3052,9 @@ AlterDomainAddConstraint(List *names, Node *newConstraint,
  * AlterDomainValidateConstraint
  *
  * Implements the ALTER DOMAIN .. VALIDATE CONSTRAINT statement.
+ *
+ * Return value is the address of the validated constraint.  If the constraint
+ * was already validated, InvalidObjectAddress is returned.
  */
 ObjectAddress
 AlterDomainValidateConstraint(List *names, const char *constrName)
@@ -3069,7 +3072,7 @@ AlterDomainValidateConstraint(List *names, const char *constrName)
        HeapTuple       tuple;
        HeapTuple       copyTuple;
        ScanKeyData skey[3];
-       ObjectAddress address;
+       ObjectAddress address = InvalidObjectAddress;
 
        /* Make a TypeName so we can use standard type lookup machinery */
        typename = makeTypeNameFromNameList(names);
@@ -3120,29 +3123,32 @@ AlterDomainValidateConstraint(List *names, const char *constrName)
                                 errmsg("constraint \"%s\" of domain \"%s\" is not a check constraint",
                                                constrName, TypeNameToString(typename))));
 
-       val = SysCacheGetAttrNotNull(CONSTROID, tuple, Anum_pg_constraint_conbin);
-       conbin = TextDatumGetCString(val);
+       if (!con->convalidated)
+       {
+               val = SysCacheGetAttrNotNull(CONSTROID, tuple, Anum_pg_constraint_conbin);
+               conbin = TextDatumGetCString(val);
 
-       /*
-        * Locking related relations with ShareUpdateExclusiveLock is ok because
-        * not-yet-valid constraints are still enforced against concurrent inserts
-        * or updates.
-        */
-       validateDomainCheckConstraint(domainoid, conbin, ShareUpdateExclusiveLock);
+               /*
+                * 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.
-        */
-       copyTuple = heap_copytuple(tuple);
-       copy_con = (Form_pg_constraint) GETSTRUCT(copyTuple);
-       copy_con->convalidated = true;
-       CatalogTupleUpdate(conrel, &copyTuple->t_self, copyTuple);
+               /*
+                * Now update the catalog, while we have the door open.
+                */
+               copyTuple = heap_copytuple(tuple);
+               copy_con = (Form_pg_constraint) GETSTRUCT(copyTuple);
+               copy_con->convalidated = true;
+               CatalogTupleUpdate(conrel, &copyTuple->t_self, copyTuple);
 
-       InvokeObjectPostAlterHook(ConstraintRelationId, con->oid, 0);
+               InvokeObjectPostAlterHook(ConstraintRelationId, con->oid, 0);
 
-       ObjectAddressSet(address, TypeRelationId, domainoid);
+               ObjectAddressSet(address, TypeRelationId, domainoid);
 
-       heap_freetuple(copyTuple);
+               heap_freetuple(copyTuple);
+       }
 
        systable_endscan(scan);