mirror of
https://github.com/postgres/postgres.git
synced 2025-07-14 08:21:07 +03:00
Improve ALTER DOMAIN / DROP CONSTRAINT with nonexistent constraint
ALTER DOMAIN / DROP CONSTRAINT on a nonexistent constraint name did not report any error. Now it reports an error. The IF EXISTS option was added to get the usual behavior of ignoring nonexistent objects to drop.
This commit is contained in:
@ -30,7 +30,7 @@ ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
|
|||||||
ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
|
ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
|
||||||
ADD <replaceable class="PARAMETER">domain_constraint</replaceable> [ NOT VALID ]
|
ADD <replaceable class="PARAMETER">domain_constraint</replaceable> [ NOT VALID ]
|
||||||
ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
|
ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
|
||||||
DROP CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> [ RESTRICT | CASCADE ]
|
DROP CONSTRAINT [ IF EXISTS ] <replaceable class="PARAMETER">constraint_name</replaceable> [ RESTRICT | CASCADE ]
|
||||||
ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
|
ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
|
||||||
VALIDATE CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable>
|
VALIDATE CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable>
|
||||||
ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
|
ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
|
||||||
@ -92,10 +92,12 @@ ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
|
|||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>DROP CONSTRAINT</term>
|
<term>DROP CONSTRAINT [ IF EXISTS ]</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
This form drops constraints on a domain.
|
This form drops constraints on a domain.
|
||||||
|
If <literal>IF EXISTS</literal> is specified and the constraint
|
||||||
|
does not exist, no error is thrown. In this case a notice is issued instead.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@ -2264,7 +2264,7 @@ AlterDomainNotNull(List *names, bool notNull)
|
|||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
AlterDomainDropConstraint(List *names, const char *constrName,
|
AlterDomainDropConstraint(List *names, const char *constrName,
|
||||||
DropBehavior behavior)
|
DropBehavior behavior, bool missing_ok)
|
||||||
{
|
{
|
||||||
TypeName *typename;
|
TypeName *typename;
|
||||||
Oid domainoid;
|
Oid domainoid;
|
||||||
@ -2274,6 +2274,7 @@ AlterDomainDropConstraint(List *names, const char *constrName,
|
|||||||
SysScanDesc conscan;
|
SysScanDesc conscan;
|
||||||
ScanKeyData key[1];
|
ScanKeyData key[1];
|
||||||
HeapTuple contup;
|
HeapTuple contup;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
/* Make a TypeName so we can use standard type lookup machinery */
|
/* Make a TypeName so we can use standard type lookup machinery */
|
||||||
typename = makeTypeNameFromNameList(names);
|
typename = makeTypeNameFromNameList(names);
|
||||||
@ -2317,6 +2318,7 @@ AlterDomainDropConstraint(List *names, const char *constrName,
|
|||||||
conobj.objectSubId = 0;
|
conobj.objectSubId = 0;
|
||||||
|
|
||||||
performDeletion(&conobj, behavior);
|
performDeletion(&conobj, behavior);
|
||||||
|
found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Clean up after the scan */
|
/* Clean up after the scan */
|
||||||
@ -2324,6 +2326,19 @@ AlterDomainDropConstraint(List *names, const char *constrName,
|
|||||||
heap_close(conrel, RowExclusiveLock);
|
heap_close(conrel, RowExclusiveLock);
|
||||||
|
|
||||||
heap_close(rel, NoLock);
|
heap_close(rel, NoLock);
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
if (!missing_ok)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||||
|
errmsg("constraint \"%s\" of domain \"%s\" does not exist",
|
||||||
|
constrName, TypeNameToString(typename))));
|
||||||
|
else
|
||||||
|
ereport(NOTICE,
|
||||||
|
(errmsg("constraint \"%s\" of domain \"%s\" does not exist, skipping",
|
||||||
|
constrName, TypeNameToString(typename))));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2568,6 +2568,7 @@ _copyAlterDomainStmt(const AlterDomainStmt *from)
|
|||||||
COPY_STRING_FIELD(name);
|
COPY_STRING_FIELD(name);
|
||||||
COPY_NODE_FIELD(def);
|
COPY_NODE_FIELD(def);
|
||||||
COPY_SCALAR_FIELD(behavior);
|
COPY_SCALAR_FIELD(behavior);
|
||||||
|
COPY_SCALAR_FIELD(missing_ok);
|
||||||
|
|
||||||
return newnode;
|
return newnode;
|
||||||
}
|
}
|
||||||
|
@ -1034,6 +1034,7 @@ _equalAlterDomainStmt(const AlterDomainStmt *a, const AlterDomainStmt *b)
|
|||||||
COMPARE_STRING_FIELD(name);
|
COMPARE_STRING_FIELD(name);
|
||||||
COMPARE_NODE_FIELD(def);
|
COMPARE_NODE_FIELD(def);
|
||||||
COMPARE_SCALAR_FIELD(behavior);
|
COMPARE_SCALAR_FIELD(behavior);
|
||||||
|
COMPARE_SCALAR_FIELD(missing_ok);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -7616,6 +7616,18 @@ AlterDomainStmt:
|
|||||||
n->typeName = $3;
|
n->typeName = $3;
|
||||||
n->name = $6;
|
n->name = $6;
|
||||||
n->behavior = $7;
|
n->behavior = $7;
|
||||||
|
n->missing_ok = false;
|
||||||
|
$$ = (Node *)n;
|
||||||
|
}
|
||||||
|
/* ALTER DOMAIN <domain> DROP CONSTRAINT IF EXISTS <name> [RESTRICT|CASCADE] */
|
||||||
|
| ALTER DOMAIN_P any_name DROP CONSTRAINT IF_P EXISTS name opt_drop_behavior
|
||||||
|
{
|
||||||
|
AlterDomainStmt *n = makeNode(AlterDomainStmt);
|
||||||
|
n->subtype = 'X';
|
||||||
|
n->typeName = $3;
|
||||||
|
n->name = $8;
|
||||||
|
n->behavior = $9;
|
||||||
|
n->missing_ok = true;
|
||||||
$$ = (Node *)n;
|
$$ = (Node *)n;
|
||||||
}
|
}
|
||||||
/* ALTER DOMAIN <domain> VALIDATE CONSTRAINT <name> */
|
/* ALTER DOMAIN <domain> VALIDATE CONSTRAINT <name> */
|
||||||
|
@ -768,7 +768,8 @@ standard_ProcessUtility(Node *parsetree,
|
|||||||
case 'X': /* DROP CONSTRAINT */
|
case 'X': /* DROP CONSTRAINT */
|
||||||
AlterDomainDropConstraint(stmt->typeName,
|
AlterDomainDropConstraint(stmt->typeName,
|
||||||
stmt->name,
|
stmt->name,
|
||||||
stmt->behavior);
|
stmt->behavior,
|
||||||
|
stmt->missing_ok);
|
||||||
break;
|
break;
|
||||||
case 'V': /* VALIDATE CONSTRAINT */
|
case 'V': /* VALIDATE CONSTRAINT */
|
||||||
AlterDomainValidateConstraint(stmt->typeName,
|
AlterDomainValidateConstraint(stmt->typeName,
|
||||||
|
@ -33,7 +33,7 @@ extern void AlterDomainNotNull(List *names, bool notNull);
|
|||||||
extern void AlterDomainAddConstraint(List *names, Node *constr);
|
extern void AlterDomainAddConstraint(List *names, Node *constr);
|
||||||
extern void AlterDomainValidateConstraint(List *names, char *constrName);
|
extern void AlterDomainValidateConstraint(List *names, char *constrName);
|
||||||
extern void AlterDomainDropConstraint(List *names, const char *constrName,
|
extern void AlterDomainDropConstraint(List *names, const char *constrName,
|
||||||
DropBehavior behavior);
|
DropBehavior behavior, bool missing_ok);
|
||||||
|
|
||||||
extern List *GetDomainConstraints(Oid typeOid);
|
extern List *GetDomainConstraints(Oid typeOid);
|
||||||
|
|
||||||
|
@ -1264,6 +1264,7 @@ typedef struct AlterDomainStmt
|
|||||||
char *name; /* column or constraint name to act on */
|
char *name; /* column or constraint name to act on */
|
||||||
Node *def; /* definition of default or constraint */
|
Node *def; /* definition of default or constraint */
|
||||||
DropBehavior behavior; /* RESTRICT or CASCADE for DROP cases */
|
DropBehavior behavior; /* RESTRICT or CASCADE for DROP cases */
|
||||||
|
bool missing_ok; /* skip error if missing? */
|
||||||
} AlterDomainStmt;
|
} AlterDomainStmt;
|
||||||
|
|
||||||
|
|
||||||
|
@ -358,6 +358,10 @@ alter domain con drop constraint t;
|
|||||||
insert into domcontest values (-5); --fails
|
insert into domcontest values (-5); --fails
|
||||||
ERROR: value for domain con violates check constraint "con_check"
|
ERROR: value for domain con violates check constraint "con_check"
|
||||||
insert into domcontest values (42);
|
insert into domcontest values (42);
|
||||||
|
alter domain con drop constraint nonexistent;
|
||||||
|
ERROR: constraint "nonexistent" of domain "con" does not exist
|
||||||
|
alter domain con drop constraint if exists nonexistent;
|
||||||
|
NOTICE: constraint "nonexistent" of domain "con" does not exist, skipping
|
||||||
-- Test ALTER DOMAIN .. CONSTRAINT .. NOT VALID
|
-- Test ALTER DOMAIN .. CONSTRAINT .. NOT VALID
|
||||||
create domain things AS INT;
|
create domain things AS INT;
|
||||||
CREATE TABLE thethings (stuff things);
|
CREATE TABLE thethings (stuff things);
|
||||||
|
@ -259,6 +259,9 @@ alter domain con drop constraint t;
|
|||||||
insert into domcontest values (-5); --fails
|
insert into domcontest values (-5); --fails
|
||||||
insert into domcontest values (42);
|
insert into domcontest values (42);
|
||||||
|
|
||||||
|
alter domain con drop constraint nonexistent;
|
||||||
|
alter domain con drop constraint if exists nonexistent;
|
||||||
|
|
||||||
-- Test ALTER DOMAIN .. CONSTRAINT .. NOT VALID
|
-- Test ALTER DOMAIN .. CONSTRAINT .. NOT VALID
|
||||||
create domain things AS INT;
|
create domain things AS INT;
|
||||||
CREATE TABLE thethings (stuff things);
|
CREATE TABLE thethings (stuff things);
|
||||||
|
Reference in New Issue
Block a user