Skip to content

Commit 38b9693

Browse files
committed
Add support for renaming domain constraints
1 parent c2cc5c3 commit 38b9693

File tree

11 files changed

+168
-24
lines changed

11 files changed

+168
-24
lines changed

doc/src/sgml/ref/alter_domain.sgml

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
3131
ADD <replaceable class="PARAMETER">domain_constraint</replaceable> [ NOT VALID ]
3232
ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
3333
DROP CONSTRAINT [ IF EXISTS ] <replaceable class="PARAMETER">constraint_name</replaceable> [ RESTRICT | CASCADE ]
34+
ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
35+
RENAME CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> TO <replaceable class="PARAMETER">new_constraint_name</replaceable>
3436
ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
3537
VALIDATE CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable>
3638
ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
@@ -102,6 +104,15 @@ ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
102104
</listitem>
103105
</varlistentry>
104106

107+
<varlistentry>
108+
<term>RENAME CONSTRAINT</term>
109+
<listitem>
110+
<para>
111+
This form changes the name of a constraint on a domain.
112+
</para>
113+
</listitem>
114+
</varlistentry>
115+
105116
<varlistentry>
106117
<term>VALIDATE CONSTRAINT</term>
107118
<listitem>
@@ -182,7 +193,7 @@ ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
182193
<term><replaceable class="PARAMETER">constraint_name</replaceable></term>
183194
<listitem>
184195
<para>
185-
Name of an existing constraint to drop.
196+
Name of an existing constraint to drop or rename.
186197
</para>
187198
</listitem>
188199
</varlistentry>
@@ -225,6 +236,15 @@ ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
225236
</listitem>
226237
</varlistentry>
227238

239+
<varlistentry>
240+
<term><replaceable class="PARAMETER">new_constraint_name</replaceable></term>
241+
<listitem>
242+
<para>
243+
The new name for the constraint.
244+
</para>
245+
</listitem>
246+
</varlistentry>
247+
228248
<varlistentry>
229249
<term><replaceable class="PARAMETER">new_owner</replaceable></term>
230250
<listitem>
@@ -288,6 +308,13 @@ ALTER DOMAIN zipcode DROP CONSTRAINT zipchk;
288308
</programlisting>
289309
</para>
290310

311+
<para>
312+
To rename a check constraint on a domain:
313+
<programlisting>
314+
ALTER DOMAIN zipcode RENAME CONSTRAINT zipchk TO zip_check;
315+
</programlisting>
316+
</para>
317+
291318
<para>
292319
To move the domain into a different schema:
293320
<programlisting>

src/backend/catalog/objectaddress.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -753,7 +753,7 @@ get_object_address_relobject(ObjectType objtype, List *objname,
753753
case OBJECT_CONSTRAINT:
754754
address.classId = ConstraintRelationId;
755755
address.objectId =
756-
get_constraint_oid(reloid, depname, missing_ok);
756+
get_relation_constraint_oid(reloid, depname, missing_ok);
757757
address.objectSubId = 0;
758758
break;
759759
default:

src/backend/catalog/pg_constraint.c

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -736,12 +736,12 @@ AlterConstraintNamespaces(Oid ownerId, Oid oldNspId,
736736
}
737737

738738
/*
739-
* get_constraint_oid
739+
* get_relation_constraint_oid
740740
* Find a constraint on the specified relation with the specified name.
741741
* Returns constraint's OID.
742742
*/
743743
Oid
744-
get_constraint_oid(Oid relid, const char *conname, bool missing_ok)
744+
get_relation_constraint_oid(Oid relid, const char *conname, bool missing_ok)
745745
{
746746
Relation pg_constraint;
747747
HeapTuple tuple;
@@ -793,6 +793,64 @@ get_constraint_oid(Oid relid, const char *conname, bool missing_ok)
793793
return conOid;
794794
}
795795

796+
/*
797+
* get_domain_constraint_oid
798+
* Find a constraint on the specified domain with the specified name.
799+
* Returns constraint's OID.
800+
*/
801+
Oid
802+
get_domain_constraint_oid(Oid typid, const char *conname, bool missing_ok)
803+
{
804+
Relation pg_constraint;
805+
HeapTuple tuple;
806+
SysScanDesc scan;
807+
ScanKeyData skey[1];
808+
Oid conOid = InvalidOid;
809+
810+
/*
811+
* Fetch the constraint tuple from pg_constraint. There may be more than
812+
* one match, because constraints are not required to have unique names;
813+
* if so, error out.
814+
*/
815+
pg_constraint = heap_open(ConstraintRelationId, AccessShareLock);
816+
817+
ScanKeyInit(&skey[0],
818+
Anum_pg_constraint_contypid,
819+
BTEqualStrategyNumber, F_OIDEQ,
820+
ObjectIdGetDatum(typid));
821+
822+
scan = systable_beginscan(pg_constraint, ConstraintTypidIndexId, true,
823+
SnapshotNow, 1, skey);
824+
825+
while (HeapTupleIsValid(tuple = systable_getnext(scan)))
826+
{
827+
Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(tuple);
828+
829+
if (strcmp(NameStr(con->conname), conname) == 0)
830+
{
831+
if (OidIsValid(conOid))
832+
ereport(ERROR,
833+
(errcode(ERRCODE_DUPLICATE_OBJECT),
834+
errmsg("domain \"%s\" has multiple constraints named \"%s\"",
835+
format_type_be(typid), conname)));
836+
conOid = HeapTupleGetOid(tuple);
837+
}
838+
}
839+
840+
systable_endscan(scan);
841+
842+
/* If no such constraint exists, complain */
843+
if (!OidIsValid(conOid) && !missing_ok)
844+
ereport(ERROR,
845+
(errcode(ERRCODE_UNDEFINED_OBJECT),
846+
errmsg("constraint \"%s\" for domain \"%s\" does not exist",
847+
conname, format_type_be(typid))));
848+
849+
heap_close(pg_constraint, AccessShareLock);
850+
851+
return conOid;
852+
}
853+
796854
/*
797855
* Determine whether a relation can be proven functionally dependent on
798856
* a set of grouping columns. If so, return TRUE and add the pg_constraint

src/backend/commands/tablecmds.c

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2333,30 +2333,40 @@ renameatt(RenameStmt *stmt)
23332333
*/
23342334
static void
23352335
rename_constraint_internal(Oid myrelid,
2336+
Oid mytypid,
23362337
const char *oldconname,
23372338
const char *newconname,
23382339
bool recurse,
23392340
bool recursing,
23402341
int expected_parents)
23412342
{
2342-
Relation targetrelation;
2343+
Relation targetrelation = NULL;
23432344
Oid constraintOid;
23442345
HeapTuple tuple;
23452346
Form_pg_constraint con;
23462347

2347-
targetrelation = relation_open(myrelid, AccessExclusiveLock);
2348-
/* don't tell it whether we're recursing; we allow changing typed tables here */
2349-
renameatt_check(myrelid, RelationGetForm(targetrelation), false);
2348+
AssertArg(!myrelid || !mytypid);
2349+
2350+
if (mytypid)
2351+
{
2352+
constraintOid = get_domain_constraint_oid(mytypid, oldconname, false);
2353+
}
2354+
else
2355+
{
2356+
targetrelation = relation_open(myrelid, AccessExclusiveLock);
2357+
/* don't tell it whether we're recursing; we allow changing typed tables here */
2358+
renameatt_check(myrelid, RelationGetForm(targetrelation), false);
23502359

2351-
constraintOid = get_constraint_oid(myrelid, oldconname, false);
2360+
constraintOid = get_relation_constraint_oid(myrelid, oldconname, false);
2361+
}
23522362

23532363
tuple = SearchSysCache1(CONSTROID, ObjectIdGetDatum(constraintOid));
23542364
if (!HeapTupleIsValid(tuple))
23552365
elog(ERROR, "cache lookup failed for constraint %u",
23562366
constraintOid);
23572367
con = (Form_pg_constraint) GETSTRUCT(tuple);
23582368

2359-
if (con->contype == CONSTRAINT_CHECK && !con->conisonly)
2369+
if (myrelid && con->contype == CONSTRAINT_CHECK && !con->conisonly)
23602370
{
23612371
if (recurse)
23622372
{
@@ -2376,7 +2386,7 @@ rename_constraint_internal(Oid myrelid,
23762386
if (childrelid == myrelid)
23772387
continue;
23782388

2379-
rename_constraint_internal(childrelid, oldconname, newconname, false, true, numparents);
2389+
rename_constraint_internal(childrelid, InvalidOid, oldconname, newconname, false, true, numparents);
23802390
}
23812391
}
23822392
else
@@ -2407,24 +2417,43 @@ rename_constraint_internal(Oid myrelid,
24072417

24082418
ReleaseSysCache(tuple);
24092419

2410-
relation_close(targetrelation, NoLock); /* close rel but keep lock */
2420+
if (targetrelation)
2421+
relation_close(targetrelation, NoLock); /* close rel but keep lock */
24112422
}
24122423

24132424
void
24142425
RenameConstraint(RenameStmt *stmt)
24152426
{
2416-
Oid relid;
2427+
Oid relid = InvalidOid;
2428+
Oid typid = InvalidOid;
24172429

2418-
/* lock level taken here should match rename_constraint_internal */
2419-
relid = RangeVarGetRelidExtended(stmt->relation, AccessExclusiveLock,
2420-
false, false,
2421-
RangeVarCallbackForRenameAttribute,
2422-
NULL);
2430+
if (stmt->relationType == OBJECT_DOMAIN)
2431+
{
2432+
Relation rel;
2433+
HeapTuple tup;
2434+
2435+
typid = typenameTypeId(NULL, makeTypeNameFromNameList(stmt->object));
2436+
rel = heap_open(TypeRelationId, RowExclusiveLock);
2437+
tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2438+
if (!HeapTupleIsValid(tup))
2439+
elog(ERROR, "cache lookup failed for type %u", typid);
2440+
checkDomainOwner(tup);
2441+
ReleaseSysCache(tup);
2442+
heap_close(rel, NoLock);
2443+
}
2444+
else
2445+
{
2446+
/* lock level taken here should match rename_constraint_internal */
2447+
relid = RangeVarGetRelidExtended(stmt->relation, AccessExclusiveLock,
2448+
false, false,
2449+
RangeVarCallbackForRenameAttribute,
2450+
NULL);
2451+
}
24232452

2424-
rename_constraint_internal(relid,
2453+
rename_constraint_internal(relid, typid,
24252454
stmt->subname,
24262455
stmt->newname,
2427-
interpretInhOption(stmt->relation->inhOpt), /* recursive? */
2456+
stmt->relation ? interpretInhOption(stmt->relation->inhOpt) : false, /* recursive? */
24282457
false, /* recursing? */
24292458
0 /* expected inhcount */);
24302459
}

src/backend/commands/typecmds.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@ static Oid findRangeCanonicalFunction(List *procname, Oid typeOid);
9898
static Oid findRangeSubtypeDiffFunction(List *procname, Oid subtype);
9999
static void validateDomainConstraint(Oid domainoid, char *ccbin);
100100
static List *get_rels_with_domain(Oid domainOid, LOCKMODE lockmode);
101-
static void checkDomainOwner(HeapTuple tup);
102101
static void checkEnumOwner(HeapTuple tup);
103102
static char *domainAddConstraint(Oid domainOid, Oid domainNamespace,
104103
Oid baseTypeOid,
@@ -2794,7 +2793,7 @@ get_rels_with_domain(Oid domainOid, LOCKMODE lockmode)
27942793
* Check that the type is actually a domain and that the current user
27952794
* has permission to do ALTER DOMAIN on it. Throw an error if not.
27962795
*/
2797-
static void
2796+
void
27982797
checkDomainOwner(HeapTuple tup)
27992798
{
28002799
Form_pg_type typTup = (Form_pg_type) GETSTRUCT(tup);

src/backend/parser/gram.y

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6529,6 +6529,16 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name
65296529
n->missing_ok = false;
65306530
$$ = (Node *)n;
65316531
}
6532+
| ALTER DOMAIN_P any_name RENAME CONSTRAINT name TO name
6533+
{
6534+
RenameStmt *n = makeNode(RenameStmt);
6535+
n->renameType = OBJECT_CONSTRAINT;
6536+
n->relationType = OBJECT_DOMAIN;
6537+
n->object = $3;
6538+
n->subname = $6;
6539+
n->newname = $8;
6540+
$$ = (Node *)n;
6541+
}
65326542
| ALTER FOREIGN DATA_P WRAPPER name RENAME TO name
65336543
{
65346544
RenameStmt *n = makeNode(RenameStmt);

src/backend/parser/parse_utilcmd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -802,7 +802,7 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
802802

803803
/* Copy comment on constraint */
804804
if ((table_like_clause->options & CREATE_TABLE_LIKE_COMMENTS) &&
805-
(comment = GetComment(get_constraint_oid(RelationGetRelid(relation),
805+
(comment = GetComment(get_relation_constraint_oid(RelationGetRelid(relation),
806806
n->conname, false),
807807
ConstraintRelationId,
808808
0)) != NULL)

src/include/catalog/pg_constraint.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,8 @@ extern char *ChooseConstraintName(const char *name1, const char *name2,
244244

245245
extern void AlterConstraintNamespaces(Oid ownerId, Oid oldNspId,
246246
Oid newNspId, bool isType);
247-
extern Oid get_constraint_oid(Oid relid, const char *conname, bool missing_ok);
247+
extern Oid get_relation_constraint_oid(Oid relid, const char *conname, bool missing_ok);
248+
extern Oid get_domain_constraint_oid(Oid typid, const char *conname, bool missing_ok);
248249

249250
extern bool check_functional_grouping(Oid relid,
250251
Index varno, Index varlevelsup,

src/include/commands/typecmds.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#ifndef TYPECMDS_H
1515
#define TYPECMDS_H
1616

17+
#include "access/htup.h"
1718
#include "nodes/parsenodes.h"
1819

1920

@@ -35,6 +36,8 @@ extern void AlterDomainValidateConstraint(List *names, char *constrName);
3536
extern void AlterDomainDropConstraint(List *names, const char *constrName,
3637
DropBehavior behavior, bool missing_ok);
3738

39+
extern void checkDomainOwner(HeapTuple tup);
40+
3841
extern List *GetDomainConstraints(Oid typeOid);
3942

4043
extern void RenameType(RenameStmt *stmt);

src/test/regress/expected/domain.out

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,3 +659,10 @@ create domain testdomain1 as int;
659659
alter domain testdomain1 rename to testdomain2;
660660
alter type testdomain2 rename to testdomain3; -- alter type also works
661661
drop domain testdomain3;
662+
--
663+
-- Renaming domain constraints
664+
--
665+
create domain testdomain1 as int constraint unsigned check (value > 0);
666+
alter domain testdomain1 rename constraint unsigned to unsigned_foo;
667+
alter domain testdomain1 drop constraint unsigned_foo;
668+
drop domain testdomain1;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy