mirror of
https://github.com/postgres/postgres.git
synced 2025-06-16 06:01:02 +03:00
Fix ALTER INDEX RENAME so that if the index belongs to a unique or primary key
constraint, the constraint is renamed as well. This avoids inconsistent situations that could confuse pg_dump (not to mention humans). We might at some point provide ALTER TABLE RENAME CONSTRAINT as a more general solution, but there seems no reason not to allow doing it this way too. Per bug #3854 and related discussions.
This commit is contained in:
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/catalog/pg_constraint.c,v 1.37 2008/01/01 19:45:48 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/catalog/pg_constraint.c,v 1.38 2008/01/17 18:56:54 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -25,6 +25,7 @@
|
|||||||
#include "utils/array.h"
|
#include "utils/array.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/fmgroids.h"
|
#include "utils/fmgroids.h"
|
||||||
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
|
|
||||||
@ -568,6 +569,67 @@ RemoveConstraintById(Oid conId)
|
|||||||
heap_close(conDesc, RowExclusiveLock);
|
heap_close(conDesc, RowExclusiveLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RenameConstraintById
|
||||||
|
* Rename a constraint.
|
||||||
|
*
|
||||||
|
* Note: this isn't intended to be a user-exposed function; it doesn't check
|
||||||
|
* permissions etc. Currently this is only invoked when renaming an index
|
||||||
|
* that is associated with a constraint, but it's made a little more general
|
||||||
|
* than that with the expectation of someday having ALTER TABLE RENAME
|
||||||
|
* CONSTRAINT.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
RenameConstraintById(Oid conId, const char *newname)
|
||||||
|
{
|
||||||
|
Relation conDesc;
|
||||||
|
HeapTuple tuple;
|
||||||
|
Form_pg_constraint con;
|
||||||
|
|
||||||
|
conDesc = heap_open(ConstraintRelationId, RowExclusiveLock);
|
||||||
|
|
||||||
|
tuple = SearchSysCacheCopy(CONSTROID,
|
||||||
|
ObjectIdGetDatum(conId),
|
||||||
|
0, 0, 0);
|
||||||
|
if (!HeapTupleIsValid(tuple))
|
||||||
|
elog(ERROR, "cache lookup failed for constraint %u", conId);
|
||||||
|
con = (Form_pg_constraint) GETSTRUCT(tuple);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We need to check whether the name is already in use --- note that
|
||||||
|
* there currently is not a unique index that would catch this.
|
||||||
|
*/
|
||||||
|
if (OidIsValid(con->conrelid) &&
|
||||||
|
ConstraintNameIsUsed(CONSTRAINT_RELATION,
|
||||||
|
con->conrelid,
|
||||||
|
con->connamespace,
|
||||||
|
newname))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_DUPLICATE_OBJECT),
|
||||||
|
errmsg("constraint \"%s\" for relation \"%s\" already exists",
|
||||||
|
newname, get_rel_name(con->conrelid))));
|
||||||
|
if (OidIsValid(con->contypid) &&
|
||||||
|
ConstraintNameIsUsed(CONSTRAINT_DOMAIN,
|
||||||
|
con->contypid,
|
||||||
|
con->connamespace,
|
||||||
|
newname))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_DUPLICATE_OBJECT),
|
||||||
|
errmsg("constraint \"%s\" for domain \"%s\" already exists",
|
||||||
|
newname, format_type_be(con->contypid))));
|
||||||
|
|
||||||
|
/* OK, do the rename --- tuple is a copy, so OK to scribble on it */
|
||||||
|
namestrcpy(&(con->conname), newname);
|
||||||
|
|
||||||
|
simple_heap_update(conDesc, &tuple->t_self, tuple);
|
||||||
|
|
||||||
|
/* update the system catalog indexes */
|
||||||
|
CatalogUpdateIndexes(conDesc, tuple);
|
||||||
|
|
||||||
|
heap_freetuple(tuple);
|
||||||
|
heap_close(conDesc, RowExclusiveLock);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AlterConstraintNamespaces
|
* AlterConstraintNamespaces
|
||||||
* Find any constraints belonging to the specified object,
|
* Find any constraints belonging to the specified object,
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.239 2008/01/02 23:34:42 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.240 2008/01/17 18:56:54 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1659,13 +1659,13 @@ renamerel(Oid myrelid, const char *newrelname, ObjectType reltype)
|
|||||||
* or ALTER INDEX is used to rename a sequence or view.
|
* or ALTER INDEX is used to rename a sequence or view.
|
||||||
*/
|
*/
|
||||||
relkind = targetrelation->rd_rel->relkind;
|
relkind = targetrelation->rd_rel->relkind;
|
||||||
if (reltype == OBJECT_SEQUENCE && relkind != 'S')
|
if (reltype == OBJECT_SEQUENCE && relkind != RELKIND_SEQUENCE)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
|
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
|
||||||
errmsg("\"%s\" is not a sequence",
|
errmsg("\"%s\" is not a sequence",
|
||||||
RelationGetRelationName(targetrelation))));
|
RelationGetRelationName(targetrelation))));
|
||||||
|
|
||||||
if (reltype == OBJECT_VIEW && relkind != 'v')
|
if (reltype == OBJECT_VIEW && relkind != RELKIND_VIEW)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
|
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
|
||||||
errmsg("\"%s\" is not a view",
|
errmsg("\"%s\" is not a view",
|
||||||
@ -1711,6 +1711,17 @@ renamerel(Oid myrelid, const char *newrelname, ObjectType reltype)
|
|||||||
if (OidIsValid(targetrelation->rd_rel->reltype))
|
if (OidIsValid(targetrelation->rd_rel->reltype))
|
||||||
TypeRename(targetrelation->rd_rel->reltype, newrelname, namespaceId);
|
TypeRename(targetrelation->rd_rel->reltype, newrelname, namespaceId);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Also rename the associated constraint, if any.
|
||||||
|
*/
|
||||||
|
if (relkind == RELKIND_INDEX)
|
||||||
|
{
|
||||||
|
Oid constraintId = get_index_constraint(myrelid);
|
||||||
|
|
||||||
|
if (OidIsValid(constraintId))
|
||||||
|
RenameConstraintById(constraintId, newrelname);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Close rel, but keep exclusive lock!
|
* Close rel, but keep exclusive lock!
|
||||||
*/
|
*/
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/catalog/pg_constraint.h,v 1.26 2008/01/01 19:45:56 momjian Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/pg_constraint.h,v 1.27 2008/01/17 18:56:54 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* the genbki.sh script reads this file and generates .bki
|
* the genbki.sh script reads this file and generates .bki
|
||||||
@ -201,6 +201,7 @@ extern Oid CreateConstraintEntry(const char *constraintName,
|
|||||||
const char *conSrc);
|
const char *conSrc);
|
||||||
|
|
||||||
extern void RemoveConstraintById(Oid conId);
|
extern void RemoveConstraintById(Oid conId);
|
||||||
|
extern void RenameConstraintById(Oid conId, const char *newname);
|
||||||
|
|
||||||
extern bool ConstraintNameIsUsed(ConstraintCategory conCat, Oid objId,
|
extern bool ConstraintNameIsUsed(ConstraintCategory conCat, Oid objId,
|
||||||
Oid objNamespace, const char *conname);
|
Oid objNamespace, const char *conname);
|
||||||
|
Reference in New Issue
Block a user