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 ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers