Here is a patch for being able to rename constraints of domains. It goes on top of the previously committed patch for renaming table constraints.
diff --git a/doc/src/sgml/ref/alter_domain.sgml b/doc/src/sgml/ref/alter_domain.sgml index 2511a12..c59975a 100644 --- a/doc/src/sgml/ref/alter_domain.sgml +++ b/doc/src/sgml/ref/alter_domain.sgml @@ -32,6 +32,8 @@ ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable> ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable> DROP CONSTRAINT [ IF EXISTS ] <replaceable class="PARAMETER">constraint_name</replaceable> [ RESTRICT | CASCADE ] ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable> + RENAME CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> TO <replaceable class="PARAMETER">new_constraint_name</replaceable> +ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable> VALIDATE CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable> OWNER TO <replaceable class="PARAMETER">new_owner</replaceable> @@ -103,6 +105,15 @@ ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable> </varlistentry> <varlistentry> + <term>RENAME CONSTRAINT</term> + <listitem> + <para> + This form changes the name of a constraint on a domain. + </para> + </listitem> + </varlistentry> + + <varlistentry> <term>VALIDATE CONSTRAINT</term> <listitem> <para> @@ -182,7 +193,7 @@ ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable> <term><replaceable class="PARAMETER">constraint_name</replaceable></term> <listitem> <para> - Name of an existing constraint to drop. + Name of an existing constraint to drop or rename. </para> </listitem> </varlistentry> @@ -226,6 +237,15 @@ ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable> </varlistentry> <varlistentry> + <term><replaceable class="PARAMETER">new_constraint_name</replaceable></term> + <listitem> + <para> + The new name for the constraint. + </para> + </listitem> + </varlistentry> + + <varlistentry> <term><replaceable class="PARAMETER">new_owner</replaceable></term> <listitem> <para> @@ -289,6 +309,13 @@ ALTER DOMAIN zipcode DROP CONSTRAINT zipchk; </para> <para> + To rename a check constraint on a domain: +<programlisting> +ALTER DOMAIN zipcode RENAME CONSTRAINT zipchk TO zip_check; +</programlisting> + </para> + + <para> To move the domain into a different schema: <programlisting> ALTER DOMAIN zipcode SET SCHEMA customers; diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c index e6e0347..08de88b 100644 --- a/src/backend/catalog/objectaddress.c +++ b/src/backend/catalog/objectaddress.c @@ -753,7 +753,7 @@ get_object_address_relobject(ObjectType objtype, List *objname, case OBJECT_CONSTRAINT: address.classId = ConstraintRelationId; address.objectId = - get_constraint_oid(reloid, depname, missing_ok); + get_constraint_oid(reloid, InvalidOid, depname, missing_ok); address.objectSubId = 0; break; default: diff --git a/src/backend/catalog/pg_constraint.c b/src/backend/catalog/pg_constraint.c index 342cf75..4377207 100644 --- a/src/backend/catalog/pg_constraint.c +++ b/src/backend/catalog/pg_constraint.c @@ -737,17 +737,20 @@ AlterConstraintNamespaces(Oid ownerId, Oid oldNspId, /* * get_constraint_oid - * Find a constraint on the specified relation with the specified name. + * Find a constraint on the specified relation or domain with the specified name. * Returns constraint's OID. */ Oid -get_constraint_oid(Oid relid, const char *conname, bool missing_ok) +get_constraint_oid(Oid relid, Oid typid, const char *conname, bool missing_ok) { Relation pg_constraint; HeapTuple tuple; SysScanDesc scan; ScanKeyData skey[1]; Oid conOid = InvalidOid; + Oid indexId; + + AssertArg(!relid || !typid); /* * Fetch the constraint tuple from pg_constraint. There may be more than @@ -756,12 +759,24 @@ get_constraint_oid(Oid relid, const char *conname, bool missing_ok) */ pg_constraint = heap_open(ConstraintRelationId, AccessShareLock); - ScanKeyInit(&skey[0], - Anum_pg_constraint_conrelid, - BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(relid)); + if (relid) + { + ScanKeyInit(&skey[0], + Anum_pg_constraint_conrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(relid)); + indexId = ConstraintRelidIndexId; + } + else + { + ScanKeyInit(&skey[0], + Anum_pg_constraint_contypid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(typid)); + indexId = ConstraintTypidIndexId; + } - scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true, + scan = systable_beginscan(pg_constraint, indexId, true, SnapshotNow, 1, skey); while (HeapTupleIsValid(tuple = systable_getnext(scan))) @@ -771,10 +786,18 @@ get_constraint_oid(Oid relid, const char *conname, bool missing_ok) if (strcmp(NameStr(con->conname), conname) == 0) { if (OidIsValid(conOid)) - ereport(ERROR, - (errcode(ERRCODE_DUPLICATE_OBJECT), - errmsg("table \"%s\" has multiple constraints named \"%s\"", - get_rel_name(relid), conname))); + { + if (relid) + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_OBJECT), + errmsg("table \"%s\" has multiple constraints named \"%s\"", + get_rel_name(relid), conname))); + else + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_OBJECT), + errmsg("domain \"%s\" has multiple constraints named \"%s\"", + format_type_be(typid), conname))); + } conOid = HeapTupleGetOid(tuple); } } @@ -783,10 +806,18 @@ get_constraint_oid(Oid relid, const char *conname, bool missing_ok) /* If no such constraint exists, complain */ if (!OidIsValid(conOid) && !missing_ok) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("constraint \"%s\" for table \"%s\" does not exist", - conname, get_rel_name(relid)))); + { + if (relid) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("constraint \"%s\" for table \"%s\" does not exist", + conname, get_rel_name(relid)))); + else + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("constraint \"%s\" for domain \"%s\" does not exist", + conname, format_type_be(typid)))); + } heap_close(pg_constraint, AccessShareLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 9615380..a0a9270 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -2333,22 +2333,32 @@ renameatt(RenameStmt *stmt) */ static void rename_constraint_internal(Oid myrelid, + Oid mytypid, const char *oldconname, const char *newconname, bool recurse, bool recursing, int expected_parents) { - Relation targetrelation; + Relation targetrelation = NULL; Oid constraintOid; HeapTuple tuple; Form_pg_constraint con; - targetrelation = relation_open(myrelid, AccessExclusiveLock); - /* don't tell it whether we're recursing; we allow changing typed tables here */ - renameatt_check(myrelid, RelationGetForm(targetrelation), false); + AssertArg(!myrelid || !mytypid); + + if (mytypid) + { + constraintOid = get_constraint_oid(InvalidOid, mytypid, oldconname, false); + } + else + { + targetrelation = relation_open(myrelid, AccessExclusiveLock); + /* don't tell it whether we're recursing; we allow changing typed tables here */ + renameatt_check(myrelid, RelationGetForm(targetrelation), false); - constraintOid = get_constraint_oid(myrelid, oldconname, false); + constraintOid = get_constraint_oid(myrelid, InvalidOid, oldconname, false); + } tuple = SearchSysCache1(CONSTROID, ObjectIdGetDatum(constraintOid)); if (!HeapTupleIsValid(tuple)) @@ -2356,7 +2366,7 @@ rename_constraint_internal(Oid myrelid, constraintOid); con = (Form_pg_constraint) GETSTRUCT(tuple); - if (con->contype == CONSTRAINT_CHECK && !con->conisonly) + if (myrelid && con->contype == CONSTRAINT_CHECK && !con->conisonly) { if (recurse) { @@ -2376,7 +2386,7 @@ rename_constraint_internal(Oid myrelid, if (childrelid == myrelid) continue; - rename_constraint_internal(childrelid, oldconname, newconname, false, true, numparents); + rename_constraint_internal(childrelid, InvalidOid, oldconname, newconname, false, true, numparents); } } else @@ -2407,24 +2417,43 @@ rename_constraint_internal(Oid myrelid, ReleaseSysCache(tuple); - relation_close(targetrelation, NoLock); /* close rel but keep lock */ + if (targetrelation) + relation_close(targetrelation, NoLock); /* close rel but keep lock */ } void RenameConstraint(RenameStmt *stmt) { - Oid relid; + Oid relid = InvalidOid; + Oid typid = InvalidOid; - /* lock level taken here should match rename_constraint_internal */ - relid = RangeVarGetRelidExtended(stmt->relation, AccessExclusiveLock, - false, false, - RangeVarCallbackForRenameAttribute, - NULL); + if (stmt->relationType == OBJECT_DOMAIN) + { + Relation rel; + HeapTuple tup; + + typid = typenameTypeId(NULL, makeTypeNameFromNameList(stmt->object)); + rel = heap_open(TypeRelationId, RowExclusiveLock); + tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid)); + if (!HeapTupleIsValid(tup)) + elog(ERROR, "cache lookup failed for type %u", typid); + checkDomainOwner(tup); + ReleaseSysCache(tup); + heap_close(rel, NoLock); + } + else + { + /* lock level taken here should match rename_constraint_internal */ + relid = RangeVarGetRelidExtended(stmt->relation, AccessExclusiveLock, + false, false, + RangeVarCallbackForRenameAttribute, + NULL); + } - rename_constraint_internal(relid, + rename_constraint_internal(relid, typid, stmt->subname, stmt->newname, - interpretInhOption(stmt->relation->inhOpt), /* recursive? */ + stmt->relation ? interpretInhOption(stmt->relation->inhOpt) : false, /* recursive? */ false, /* recursing? */ 0 /* expected inhcount */); } diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index 37fe5e8..701a986 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -98,7 +98,6 @@ static Oid findRangeCanonicalFunction(List *procname, Oid typeOid); static Oid findRangeSubtypeDiffFunction(List *procname, Oid subtype); static void validateDomainConstraint(Oid domainoid, char *ccbin); static List *get_rels_with_domain(Oid domainOid, LOCKMODE lockmode); -static void checkDomainOwner(HeapTuple tup); static void checkEnumOwner(HeapTuple tup); static char *domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid, @@ -2794,7 +2793,7 @@ get_rels_with_domain(Oid domainOid, LOCKMODE lockmode) * Check that the type is actually a domain and that the current user * has permission to do ALTER DOMAIN on it. Throw an error if not. */ -static void +void checkDomainOwner(HeapTuple tup) { Form_pg_type typTup = (Form_pg_type) GETSTRUCT(tup); diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index feb28a4..bdfed84 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -6534,6 +6534,16 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name n->missing_ok = false; $$ = (Node *)n; } + | ALTER DOMAIN_P any_name RENAME CONSTRAINT name TO name + { + RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_CONSTRAINT; + n->relationType = OBJECT_DOMAIN; + n->object = $3; + n->subname = $6; + n->newname = $8; + $$ = (Node *)n; + } | ALTER FOREIGN DATA_P WRAPPER name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index 43f5634..f4370ee 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -802,7 +802,7 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla /* Copy comment on constraint */ if ((table_like_clause->options & CREATE_TABLE_LIKE_COMMENTS) && - (comment = GetComment(get_constraint_oid(RelationGetRelid(relation), + (comment = GetComment(get_constraint_oid(RelationGetRelid(relation), InvalidOid, n->conname, false), ConstraintRelationId, 0)) != NULL) diff --git a/src/include/catalog/pg_constraint.h b/src/include/catalog/pg_constraint.h index 77015ae..19281e5 100644 --- a/src/include/catalog/pg_constraint.h +++ b/src/include/catalog/pg_constraint.h @@ -244,7 +244,7 @@ extern char *ChooseConstraintName(const char *name1, const char *name2, extern void AlterConstraintNamespaces(Oid ownerId, Oid oldNspId, Oid newNspId, bool isType); -extern Oid get_constraint_oid(Oid relid, const char *conname, bool missing_ok); +extern Oid get_constraint_oid(Oid relid, Oid typid, const char *conname, bool missing_ok); extern bool check_functional_grouping(Oid relid, Index varno, Index varlevelsup, diff --git a/src/include/commands/typecmds.h b/src/include/commands/typecmds.h index 0c7e10d..bb4a7c3 100644 --- a/src/include/commands/typecmds.h +++ b/src/include/commands/typecmds.h @@ -14,6 +14,7 @@ #ifndef TYPECMDS_H #define TYPECMDS_H +#include "access/htup.h" #include "nodes/parsenodes.h" @@ -35,6 +36,8 @@ extern void AlterDomainValidateConstraint(List *names, char *constrName); extern void AlterDomainDropConstraint(List *names, const char *constrName, DropBehavior behavior, bool missing_ok); +extern void checkDomainOwner(HeapTuple tup); + extern List *GetDomainConstraints(Oid typeOid); extern void RenameType(RenameStmt *stmt); diff --git a/src/test/regress/expected/domain.out b/src/test/regress/expected/domain.out index e713b97..03204ff 100644 --- a/src/test/regress/expected/domain.out +++ b/src/test/regress/expected/domain.out @@ -659,3 +659,10 @@ create domain testdomain1 as int; alter domain testdomain1 rename to testdomain2; alter type testdomain2 rename to testdomain3; -- alter type also works drop domain testdomain3; +-- +-- Renaming domain constraints +-- +create domain testdomain1 as int constraint unsigned check (value > 0); +alter domain testdomain1 rename constraint unsigned to unsigned_foo; +alter domain testdomain1 drop constraint unsigned_foo; +drop domain testdomain1; diff --git a/src/test/regress/sql/domain.sql b/src/test/regress/sql/domain.sql index ad049b7..5af36af 100644 --- a/src/test/regress/sql/domain.sql +++ b/src/test/regress/sql/domain.sql @@ -496,3 +496,13 @@ create domain testdomain1 as int; alter domain testdomain1 rename to testdomain2; alter type testdomain2 rename to testdomain3; -- alter type also works drop domain testdomain3; + + +-- +-- Renaming domain constraints +-- + +create domain testdomain1 as int constraint unsigned check (value > 0); +alter domain testdomain1 rename constraint unsigned to unsigned_foo; +alter domain testdomain1 drop constraint unsigned_foo; +drop domain testdomain1;
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers