mirror of
https://github.com/postgres/postgres.git
synced 2025-04-24 10:47:04 +03:00
Revert patch becaues of locking concerns:
Allow ALTER TABLE ... ALTER CONSTRAINT ... RENAME Joachim Wieland
This commit is contained in:
parent
92a26489ac
commit
04a2b54c09
@ -1,4 +1,4 @@
|
|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/ddl.sgml,v 1.53 2006/02/11 22:17:18 momjian Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/ddl.sgml,v 1.54 2006/02/12 19:11:00 momjian Exp $ -->
|
||||||
|
|
||||||
<chapter id="ddl">
|
<chapter id="ddl">
|
||||||
<title>Data Definition</title>
|
<title>Data Definition</title>
|
||||||
@ -543,10 +543,6 @@ CREATE TABLE products (
|
|||||||
price numeric
|
price numeric
|
||||||
);
|
);
|
||||||
</programlisting>
|
</programlisting>
|
||||||
Since <productname>PostgreSQL</productname> implements a UNIQUE constraint by
|
|
||||||
means of an index, the above command will also create an index with the same
|
|
||||||
name as the constraint. If you later on change the name of one of those, the
|
|
||||||
name of the corresponding object will be changed automatically as well.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<indexterm>
|
<indexterm>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_index.sgml,v 1.7 2006/02/11 22:17:18 momjian Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_index.sgml,v 1.8 2006/02/12 19:11:00 momjian Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -107,15 +107,6 @@ ALTER INDEX <replaceable class="PARAMETER">name</replaceable> SET TABLESPACE <re
|
|||||||
of <command>ALTER TABLE</> that apply to indexes.
|
of <command>ALTER TABLE</> that apply to indexes.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
|
||||||
Indexes are also used internally by constraints, namely by UNIQUE and
|
|
||||||
PRIMARY KEY constraints. If you rename an index that is used internally by
|
|
||||||
a constraint of that type, this constraint will implicitly be renamed as
|
|
||||||
well. On the other hand, if you rename such a constraint, it will
|
|
||||||
implicitly rename its corresponding index such that both objects always
|
|
||||||
have the same name.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
There was formerly an <command>ALTER INDEX OWNER</> variant, but
|
There was formerly an <command>ALTER INDEX OWNER</> variant, but
|
||||||
this is now ignored (with a warning). An index cannot have an owner
|
this is now ignored (with a warning). An index cannot have an owner
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_table.sgml,v 1.83 2006/02/11 22:17:18 momjian Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_table.sgml,v 1.84 2006/02/12 19:11:00 momjian Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -24,8 +24,6 @@ ALTER TABLE [ ONLY ] <replaceable class="PARAMETER">name</replaceable> [ * ]
|
|||||||
<replaceable class="PARAMETER">action</replaceable> [, ... ]
|
<replaceable class="PARAMETER">action</replaceable> [, ... ]
|
||||||
ALTER TABLE [ ONLY ] <replaceable class="PARAMETER">name</replaceable> [ * ]
|
ALTER TABLE [ ONLY ] <replaceable class="PARAMETER">name</replaceable> [ * ]
|
||||||
RENAME [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> TO <replaceable class="PARAMETER">new_column</replaceable>
|
RENAME [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> TO <replaceable class="PARAMETER">new_column</replaceable>
|
||||||
ALTER TABLE [ ONLY ] <replaceable class="PARAMETER">name</replaceable> [ * ]
|
|
||||||
ALTER CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> RENAME TO <replaceable class="PARAMETER">new_constraint_name</replaceable>
|
|
||||||
ALTER TABLE <replaceable class="PARAMETER">name</replaceable>
|
ALTER TABLE <replaceable class="PARAMETER">name</replaceable>
|
||||||
RENAME TO <replaceable class="PARAMETER">new_name</replaceable>
|
RENAME TO <replaceable class="PARAMETER">new_name</replaceable>
|
||||||
ALTER TABLE <replaceable class="PARAMETER">name</replaceable>
|
ALTER TABLE <replaceable class="PARAMETER">name</replaceable>
|
||||||
@ -171,18 +169,6 @@ where <replaceable class="PARAMETER">action</replaceable> is one of:
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term><literal>ALTER CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> RENAME TO <replaceable class="PARAMETER">new_constraint_name</replaceable></literal></term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
This form renames a constraint that is defined on the table. Note that if
|
|
||||||
a constraint is using an index internally (<literal>UNIQUE</> or
|
|
||||||
<literal>PRIMARY KEY</> constraints), the corresponding index will be
|
|
||||||
renamed as well.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><literal>ADD <replaceable class="PARAMETER">table_constraint</replaceable></literal></term>
|
<term><literal>ADD <replaceable class="PARAMETER">table_constraint</replaceable></literal></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/catalog/pg_constraint.c,v 1.29 2006/02/11 22:17:18 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/catalog/pg_constraint.c,v 1.30 2006/02/12 19:11:01 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -664,191 +664,3 @@ AlterConstraintNamespaces(Oid ownerId, Oid oldNspId,
|
|||||||
|
|
||||||
heap_close(conRel, RowExclusiveLock);
|
heap_close(conRel, RowExclusiveLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* RenameConstraint
|
|
||||||
* Rename a single constraint record
|
|
||||||
* conId: The OID of the constraint to rename
|
|
||||||
* newName: The new name of the constraint
|
|
||||||
* implicitRename: is this an implicit rename? If so, we will issue
|
|
||||||
* a notice about the implicit rename
|
|
||||||
* cmdName: the command that triggered the rename for the "implicitly
|
|
||||||
* renames" notice message
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
RenameConstraint(Oid conId, const char* newName,
|
|
||||||
bool implicitRename, const char* cmdName)
|
|
||||||
{
|
|
||||||
Relation conRel;
|
|
||||||
ScanKeyData key[1];
|
|
||||||
SysScanDesc scan;
|
|
||||||
HeapTuple tup;
|
|
||||||
NameData newNameData;
|
|
||||||
Relation rel;
|
|
||||||
Oid relId;
|
|
||||||
Oid nspOid;
|
|
||||||
Form_pg_constraint conform;
|
|
||||||
|
|
||||||
/* before reading the tuple, lock the table it constraints in
|
|
||||||
* AccessExclusiveLock mode. Otherwise, if we read it before locking this
|
|
||||||
* table, the tuple might be changed by another transaction and our copy
|
|
||||||
* would be out of date
|
|
||||||
*/
|
|
||||||
relId = GetConstraintRelationId(conId);
|
|
||||||
if (!OidIsValid(relId))
|
|
||||||
{
|
|
||||||
ereport(ERROR,
|
|
||||||
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
|
||||||
errmsg("constraint with OID %d does not exist", conId)));
|
|
||||||
}
|
|
||||||
|
|
||||||
rel = relation_open(relId, AccessExclusiveLock);
|
|
||||||
nspOid = get_rel_namespace(relId);
|
|
||||||
|
|
||||||
conRel = heap_open(ConstraintRelationId, RowExclusiveLock);
|
|
||||||
|
|
||||||
ScanKeyInit(&key[0],
|
|
||||||
ObjectIdAttributeNumber,
|
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
|
||||||
ObjectIdGetDatum(conId));
|
|
||||||
|
|
||||||
scan = systable_beginscan(conRel, ConstraintOidIndexId, true,
|
|
||||||
SnapshotNow, 1, key);
|
|
||||||
if (!HeapTupleIsValid((tup = systable_getnext(scan))))
|
|
||||||
{
|
|
||||||
ereport(ERROR,
|
|
||||||
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
|
||||||
errmsg("constraint with OID %d does not exist", conId)));
|
|
||||||
}
|
|
||||||
|
|
||||||
conform = (Form_pg_constraint) GETSTRUCT(tup);
|
|
||||||
|
|
||||||
if (ConstraintNameIsUsed(CONSTRAINT_RELATION,
|
|
||||||
conform->conrelid,
|
|
||||||
get_rel_namespace(conform->conrelid),
|
|
||||||
newName))
|
|
||||||
{
|
|
||||||
ereport(ERROR,
|
|
||||||
(errcode(ERRCODE_DUPLICATE_OBJECT),
|
|
||||||
errmsg("constraint \"%s\" for relation \"%s\" already exists",
|
|
||||||
newName,
|
|
||||||
RelationGetRelationName(rel))));
|
|
||||||
}
|
|
||||||
tup = heap_copytuple(tup);
|
|
||||||
conform = (Form_pg_constraint) GETSTRUCT(tup);
|
|
||||||
|
|
||||||
if (implicitRename && cmdName)
|
|
||||||
{
|
|
||||||
ereport(NOTICE,
|
|
||||||
(errmsg("%s will implicitly rename constraint "
|
|
||||||
"\"%s\" to \"%s\" on table \"%s.%s\"",
|
|
||||||
cmdName,
|
|
||||||
NameStr(conform->conname),
|
|
||||||
newName,
|
|
||||||
get_namespace_name(nspOid),
|
|
||||||
RelationGetRelationName(rel))));
|
|
||||||
}
|
|
||||||
|
|
||||||
namestrcpy(&newNameData, newName);
|
|
||||||
conform->conname = newNameData;
|
|
||||||
|
|
||||||
simple_heap_update(conRel, &tup->t_self, tup);
|
|
||||||
CatalogUpdateIndexes(conRel, tup);
|
|
||||||
heap_freetuple(tup);
|
|
||||||
|
|
||||||
systable_endscan(scan);
|
|
||||||
heap_close(conRel, RowExclusiveLock);
|
|
||||||
|
|
||||||
/* close relation but hold lock until end of transaction */
|
|
||||||
relation_close(rel, NoLock);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* GetRelationConstraintOid
|
|
||||||
*
|
|
||||||
* Get the contraint OID by the relation Id of the relation it constraints and
|
|
||||||
* this relations' name. We need this function in order to rename a constraint.
|
|
||||||
* This is done via "ALTER TABLE ... ALTER CONSTRAINT name" and the parser
|
|
||||||
* gives us the relation this constraint is defined on as well as the
|
|
||||||
* constraint's name.
|
|
||||||
*
|
|
||||||
* The function returns:
|
|
||||||
*
|
|
||||||
* - the unique OID of the constraint if the constraint could be found
|
|
||||||
* - the invalid OID if the constraint was not found
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
Oid GetRelationConstraintOid(Oid relId, const char* name)
|
|
||||||
{
|
|
||||||
Relation conRel;
|
|
||||||
ScanKeyData key[1];
|
|
||||||
SysScanDesc scan;
|
|
||||||
HeapTuple tup;
|
|
||||||
Oid conId = InvalidOid;
|
|
||||||
|
|
||||||
/* we don't change data, so an AccessShareLock is enough */
|
|
||||||
conRel = heap_open(ConstraintRelationId, AccessShareLock);
|
|
||||||
|
|
||||||
ScanKeyInit(&key[0],
|
|
||||||
Anum_pg_constraint_conrelid,
|
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
|
||||||
ObjectIdGetDatum(relId));
|
|
||||||
|
|
||||||
scan = systable_beginscan(conRel, ConstraintRelidIndexId, true,
|
|
||||||
SnapshotNow, 1, key);
|
|
||||||
|
|
||||||
while (HeapTupleIsValid((tup = systable_getnext(scan))))
|
|
||||||
{
|
|
||||||
Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(tup);
|
|
||||||
if (pg_strcasecmp(name, NameStr(con->conname)) == 0)
|
|
||||||
{
|
|
||||||
conId = HeapTupleGetOid(tup);
|
|
||||||
Assert(OidIsValid(conId));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
systable_endscan(scan);
|
|
||||||
heap_close(conRel, AccessShareLock);
|
|
||||||
|
|
||||||
return conId;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* GetConstraintRelationId
|
|
||||||
*
|
|
||||||
* Gets the OID of the relation where the constraint is defined on or the
|
|
||||||
* invalid OID if the constraint cannot be found.
|
|
||||||
*/
|
|
||||||
Oid GetConstraintRelationId(Oid conId)
|
|
||||||
{
|
|
||||||
Relation conRel;
|
|
||||||
ScanKeyData key[1];
|
|
||||||
SysScanDesc scan;
|
|
||||||
HeapTuple tup;
|
|
||||||
Oid relId = InvalidOid;
|
|
||||||
|
|
||||||
/* we don't change data, so an AccessShareLock is enough */
|
|
||||||
conRel = heap_open(ConstraintRelationId, AccessShareLock);
|
|
||||||
|
|
||||||
ScanKeyInit(&key[0],
|
|
||||||
ObjectIdAttributeNumber,
|
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
|
||||||
ObjectIdGetDatum(conId));
|
|
||||||
|
|
||||||
scan = systable_beginscan(conRel, ConstraintOidIndexId, true,
|
|
||||||
SnapshotNow, 1, key);
|
|
||||||
|
|
||||||
if (HeapTupleIsValid((tup = systable_getnext(scan))))
|
|
||||||
{
|
|
||||||
Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(tup);
|
|
||||||
relId = con->conrelid;
|
|
||||||
Assert(OidIsValid(relId));
|
|
||||||
}
|
|
||||||
|
|
||||||
systable_endscan(scan);
|
|
||||||
heap_close(conRel, AccessShareLock);
|
|
||||||
|
|
||||||
return relId;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/catalog/pg_depend.c,v 1.18 2006/02/11 22:17:18 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/catalog/pg_depend.c,v 1.19 2006/02/12 19:11:01 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -361,102 +361,3 @@ isObjectPinned(const ObjectAddress *object, Relation rel)
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
List* getReferencingOids(Oid refClassId, Oid refObjId, Oid refObjSubId,
|
|
||||||
Oid classId, DependencyType deptype)
|
|
||||||
{
|
|
||||||
ScanKeyData key[3];
|
|
||||||
SysScanDesc scan;
|
|
||||||
HeapTuple tup;
|
|
||||||
Relation depRel;
|
|
||||||
List *list = NIL;
|
|
||||||
|
|
||||||
depRel = heap_open(DependRelationId, AccessShareLock);
|
|
||||||
|
|
||||||
ScanKeyInit(&key[0],
|
|
||||||
Anum_pg_depend_refclassid,
|
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
|
||||||
ObjectIdGetDatum(refClassId));
|
|
||||||
|
|
||||||
ScanKeyInit(&key[1],
|
|
||||||
Anum_pg_depend_refobjid,
|
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
|
||||||
ObjectIdGetDatum(refObjId));
|
|
||||||
|
|
||||||
ScanKeyInit(&key[2],
|
|
||||||
Anum_pg_depend_refobjsubid,
|
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
|
||||||
ObjectIdGetDatum(refObjSubId));
|
|
||||||
|
|
||||||
scan = systable_beginscan(depRel, DependReferenceIndexId, true,
|
|
||||||
SnapshotNow, 3, key);
|
|
||||||
|
|
||||||
while (HeapTupleIsValid(tup = systable_getnext(scan)))
|
|
||||||
{
|
|
||||||
Form_pg_depend depForm = (Form_pg_depend) GETSTRUCT(tup);
|
|
||||||
|
|
||||||
/* check if the class id is what we want */
|
|
||||||
if (depForm->classid != classId)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* check if the DependencyType is what we want */
|
|
||||||
if (depForm->deptype != deptype)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* if we are still here, we have found a match */
|
|
||||||
list = lcons_oid(depForm->objid, list);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
systable_endscan(scan);
|
|
||||||
|
|
||||||
heap_close(depRel, AccessShareLock);
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
List* getDependentOids(Oid classId, Oid objId,
|
|
||||||
Oid refClassId, DependencyType deptype)
|
|
||||||
{
|
|
||||||
ScanKeyData key[2];
|
|
||||||
SysScanDesc scan;
|
|
||||||
HeapTuple tup;
|
|
||||||
Relation depRel;
|
|
||||||
List *list = NIL;
|
|
||||||
|
|
||||||
depRel = heap_open(DependRelationId, AccessShareLock);
|
|
||||||
|
|
||||||
ScanKeyInit(&key[0],
|
|
||||||
Anum_pg_depend_classid,
|
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
|
||||||
ObjectIdGetDatum(classId));
|
|
||||||
|
|
||||||
ScanKeyInit(&key[1],
|
|
||||||
Anum_pg_depend_objid,
|
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
|
||||||
ObjectIdGetDatum(objId));
|
|
||||||
|
|
||||||
scan = systable_beginscan(depRel, DependDependerIndexId, true,
|
|
||||||
SnapshotNow, 2, key);
|
|
||||||
|
|
||||||
while (HeapTupleIsValid(tup = systable_getnext(scan)))
|
|
||||||
{
|
|
||||||
Form_pg_depend depForm = (Form_pg_depend) GETSTRUCT(tup);
|
|
||||||
|
|
||||||
/* check if the DependencyType is what we want */
|
|
||||||
if (depForm->deptype != deptype)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* check if the referenced class id is what we want */
|
|
||||||
if (depForm->refclassid != refClassId)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* if we are still here, we have found a match */
|
|
||||||
list = lcons_oid(depForm->refobjid, list);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
systable_endscan(scan);
|
|
||||||
|
|
||||||
heap_close(depRel, AccessShareLock);
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/alter.c,v 1.16 2006/02/11 22:17:18 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/alter.c,v 1.17 2006/02/12 19:11:01 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -16,10 +16,8 @@
|
|||||||
|
|
||||||
#include "access/htup.h"
|
#include "access/htup.h"
|
||||||
#include "catalog/catalog.h"
|
#include "catalog/catalog.h"
|
||||||
#include "catalog/dependency.h"
|
|
||||||
#include "catalog/namespace.h"
|
#include "catalog/namespace.h"
|
||||||
#include "catalog/pg_class.h"
|
#include "catalog/pg_class.h"
|
||||||
#include "catalog/pg_constraint.h"
|
|
||||||
#include "commands/alter.h"
|
#include "commands/alter.h"
|
||||||
#include "commands/conversioncmds.h"
|
#include "commands/conversioncmds.h"
|
||||||
#include "commands/dbcommands.h"
|
#include "commands/dbcommands.h"
|
||||||
@ -90,7 +88,6 @@ ExecRenameStmt(RenameStmt *stmt)
|
|||||||
case OBJECT_INDEX:
|
case OBJECT_INDEX:
|
||||||
case OBJECT_COLUMN:
|
case OBJECT_COLUMN:
|
||||||
case OBJECT_TRIGGER:
|
case OBJECT_TRIGGER:
|
||||||
case OBJECT_CONSTRAINT:
|
|
||||||
{
|
{
|
||||||
Oid relid;
|
Oid relid;
|
||||||
|
|
||||||
@ -112,38 +109,12 @@ ExecRenameStmt(RenameStmt *stmt)
|
|||||||
AclResult aclresult;
|
AclResult aclresult;
|
||||||
|
|
||||||
aclresult = pg_namespace_aclcheck(namespaceId,
|
aclresult = pg_namespace_aclcheck(namespaceId,
|
||||||
GetUserId(), ACL_CREATE);
|
GetUserId(),
|
||||||
|
ACL_CREATE);
|
||||||
if (aclresult != ACLCHECK_OK)
|
if (aclresult != ACLCHECK_OK)
|
||||||
aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
|
aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
|
||||||
get_namespace_name(namespaceId));
|
get_namespace_name(namespaceId));
|
||||||
|
|
||||||
/*
|
|
||||||
* Do NOT refer to stmt->renameType here because
|
|
||||||
* you can also rename an index with ALTER TABLE
|
|
||||||
*/
|
|
||||||
if (get_rel_relkind(relid) == RELKIND_INDEX)
|
|
||||||
{
|
|
||||||
/* see if we depend on a constraint */
|
|
||||||
List* depOids = getDependentOids(
|
|
||||||
RelationRelationId, relid,
|
|
||||||
ConstraintRelationId,
|
|
||||||
DEPENDENCY_INTERNAL);
|
|
||||||
|
|
||||||
/* there should only be one constraint */
|
|
||||||
Assert(list_length(depOids) <= 1);
|
|
||||||
if (list_length(depOids) == 1)
|
|
||||||
{
|
|
||||||
Oid conRelId = linitial_oid(depOids);
|
|
||||||
/*
|
|
||||||
* Apply the same name to the
|
|
||||||
* constraint and tell it that this
|
|
||||||
* is an implicit rename triggered
|
|
||||||
* by an "ALTER INDEX" command.
|
|
||||||
*/
|
|
||||||
RenameConstraint(conRelId,
|
|
||||||
stmt->newname, true, "ALTER INDEX");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
renamerel(relid, stmt->newname);
|
renamerel(relid, stmt->newname);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -159,52 +130,6 @@ ExecRenameStmt(RenameStmt *stmt)
|
|||||||
stmt->subname, /* old att name */
|
stmt->subname, /* old att name */
|
||||||
stmt->newname); /* new att name */
|
stmt->newname); /* new att name */
|
||||||
break;
|
break;
|
||||||
case OBJECT_CONSTRAINT:
|
|
||||||
/* XXX could do extra function renameconstr() - but I
|
|
||||||
* don't know where it should go */
|
|
||||||
/* renameconstr(relid,
|
|
||||||
stmt->subname,
|
|
||||||
stmt->newname); */
|
|
||||||
{
|
|
||||||
List *depRelOids;
|
|
||||||
ListCell *l;
|
|
||||||
Oid conId =
|
|
||||||
GetRelationConstraintOid(relid,
|
|
||||||
stmt->subname);
|
|
||||||
if (!OidIsValid(conId)) {
|
|
||||||
ereport(ERROR,
|
|
||||||
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
|
||||||
errmsg("constraint with name \"%s\" "
|
|
||||||
"does not exist",
|
|
||||||
stmt->subname)));
|
|
||||||
}
|
|
||||||
RenameConstraint(conId, stmt->newname,
|
|
||||||
false, NULL);
|
|
||||||
depRelOids = getReferencingOids(
|
|
||||||
ConstraintRelationId, conId, 0,
|
|
||||||
RelationRelationId,
|
|
||||||
DEPENDENCY_INTERNAL);
|
|
||||||
foreach(l, depRelOids)
|
|
||||||
{
|
|
||||||
Oid depRelOid;
|
|
||||||
Oid nspOid;
|
|
||||||
depRelOid = lfirst_oid(l);
|
|
||||||
nspOid = get_rel_namespace(depRelOid);
|
|
||||||
if (get_rel_relkind(depRelOid) == RELKIND_INDEX)
|
|
||||||
{
|
|
||||||
ereport(NOTICE,
|
|
||||||
(errmsg("ALTER TABLE / CONSTRAINT will implicitly rename index "
|
|
||||||
"\"%s\" to \"%s\" on table \"%s.%s\"",
|
|
||||||
get_rel_name(depRelOid),
|
|
||||||
stmt->newname,
|
|
||||||
get_namespace_name(nspOid),
|
|
||||||
get_rel_name(relid))));
|
|
||||||
renamerel(depRelOid, stmt->newname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* can't happen */ ;
|
/* can't happen */ ;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.528 2006/02/12 03:22:17 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.529 2006/02/12 19:11:01 momjian Exp $
|
||||||
*
|
*
|
||||||
* HISTORY
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* AUTHOR DATE MAJOR EVENT
|
||||||
@ -4099,15 +4099,6 @@ RenameStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' RENAME TO name
|
|||||||
n->newname = $8;
|
n->newname = $8;
|
||||||
$$ = (Node *)n;
|
$$ = (Node *)n;
|
||||||
}
|
}
|
||||||
| ALTER TABLE relation_expr ALTER CONSTRAINT name RENAME TO name
|
|
||||||
{
|
|
||||||
RenameStmt *n = makeNode(RenameStmt);
|
|
||||||
n->renameType = OBJECT_CONSTRAINT;
|
|
||||||
n->relation = $3;
|
|
||||||
n->subname = $6;
|
|
||||||
n->newname = $9;
|
|
||||||
$$ = (Node *)n;
|
|
||||||
}
|
|
||||||
| ALTER TRIGGER name ON relation_expr RENAME TO name
|
| ALTER TRIGGER name ON relation_expr RENAME TO name
|
||||||
{
|
{
|
||||||
RenameStmt *n = makeNode(RenameStmt);
|
RenameStmt *n = makeNode(RenameStmt);
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.251 2006/02/11 22:17:19 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.252 2006/02/12 19:11:01 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1406,7 +1406,6 @@ CreateCommandTag(Node *parsetree)
|
|||||||
case OBJECT_SCHEMA:
|
case OBJECT_SCHEMA:
|
||||||
tag = "ALTER SCHEMA";
|
tag = "ALTER SCHEMA";
|
||||||
break;
|
break;
|
||||||
case OBJECT_CONSTRAINT:
|
|
||||||
case OBJECT_COLUMN:
|
case OBJECT_COLUMN:
|
||||||
case OBJECT_TABLE:
|
case OBJECT_TABLE:
|
||||||
tag = "ALTER TABLE";
|
tag = "ALTER TABLE";
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, 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/dependency.h,v 1.19 2006/02/11 22:17:19 momjian Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/dependency.h,v 1.20 2006/02/12 19:11:01 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -179,12 +179,6 @@ extern long changeDependencyFor(Oid classId, Oid objectId,
|
|||||||
|
|
||||||
extern bool objectIsInternalDependency(Oid classId, Oid objectId);
|
extern bool objectIsInternalDependency(Oid classId, Oid objectId);
|
||||||
|
|
||||||
extern List* getDependentOids(Oid classId, Oid objId,
|
|
||||||
Oid refClassId, DependencyType deptype);
|
|
||||||
|
|
||||||
extern List* getReferencingOids(Oid refClassId, Oid refObjId, Oid refObjSubId,
|
|
||||||
Oid classId, DependencyType deptype);
|
|
||||||
|
|
||||||
/* in pg_shdepend.c */
|
/* in pg_shdepend.c */
|
||||||
|
|
||||||
extern void recordSharedDependencyOn(ObjectAddress *depender,
|
extern void recordSharedDependencyOn(ObjectAddress *depender,
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, 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.20 2006/02/11 22:17:19 momjian Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/pg_constraint.h,v 1.21 2006/02/12 19:11:01 momjian Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* the genbki.sh script reads this file and generates .bki
|
* the genbki.sh script reads this file and generates .bki
|
||||||
@ -187,10 +187,4 @@ extern char *GetConstraintNameForTrigger(Oid triggerId);
|
|||||||
extern void AlterConstraintNamespaces(Oid ownerId, Oid oldNspId,
|
extern void AlterConstraintNamespaces(Oid ownerId, Oid oldNspId,
|
||||||
Oid newNspId, bool isType);
|
Oid newNspId, bool isType);
|
||||||
|
|
||||||
extern void RenameConstraint(Oid conId, const char* newName,
|
|
||||||
bool implicitRename, const char* cmdName);
|
|
||||||
|
|
||||||
extern Oid GetRelationConstraintOid(Oid relId, const char* name);
|
|
||||||
extern Oid GetConstraintRelationId(Oid conId);
|
|
||||||
|
|
||||||
#endif /* PG_CONSTRAINT_H */
|
#endif /* PG_CONSTRAINT_H */
|
||||||
|
@ -159,10 +159,6 @@ CREATE TABLE tmp3 (a int, b int);
|
|||||||
CREATE TABLE tmp4 (a int, b int, unique(a,b));
|
CREATE TABLE tmp4 (a int, b int, unique(a,b));
|
||||||
NOTICE: CREATE TABLE / UNIQUE will create implicit index "tmp4_a_key" for table "tmp4"
|
NOTICE: CREATE TABLE / UNIQUE will create implicit index "tmp4_a_key" for table "tmp4"
|
||||||
CREATE TABLE tmp5 (a int, b int);
|
CREATE TABLE tmp5 (a int, b int);
|
||||||
-- creates implicit index tmp6_a_key
|
|
||||||
CREATE TABLE tmp6 (a int, b int, unique(a));
|
|
||||||
NOTICE: CREATE TABLE / UNIQUE will create implicit index "tmp6_a_key" for table "tmp6"
|
|
||||||
CREATE INDEX tmp6_b_key ON tmp6(b);
|
|
||||||
-- Insert rows into tmp2 (pktable)
|
-- Insert rows into tmp2 (pktable)
|
||||||
INSERT INTO tmp2 values (1);
|
INSERT INTO tmp2 values (1);
|
||||||
INSERT INTO tmp2 values (2);
|
INSERT INTO tmp2 values (2);
|
||||||
@ -190,22 +186,6 @@ ALTER TABLE tmp3 add constraint tmpconstr foreign key (a) references tmp2 match
|
|||||||
-- tmp4 is a,b
|
-- tmp4 is a,b
|
||||||
ALTER TABLE tmp5 add constraint tmpconstr foreign key(a) references tmp4(a) match full;
|
ALTER TABLE tmp5 add constraint tmpconstr foreign key(a) references tmp4(a) match full;
|
||||||
ERROR: there is no unique constraint matching given keys for referenced table "tmp4"
|
ERROR: there is no unique constraint matching given keys for referenced table "tmp4"
|
||||||
-- check if constraint and index name stay in sync if we rename one or the other
|
|
||||||
-- fail here
|
|
||||||
ALTER TABLE tmp6 ALTER CONSTRAINT tmp6_a_key RENAME TO tmp6_b_key;
|
|
||||||
NOTICE: ALTER TABLE / CONSTRAINT will implicitly rename index "tmp6_a_key" to "tmp6_b_key" on table "public.tmp6"
|
|
||||||
ERROR: relation "tmp6_b_key" already exists
|
|
||||||
-- succeed
|
|
||||||
ALTER TABLE tmp6 ALTER CONSTRAINT tmp6_a_key RENAME TO tmp6_c_key;
|
|
||||||
NOTICE: ALTER TABLE / CONSTRAINT will implicitly rename index "tmp6_a_key" to "tmp6_c_key" on table "public.tmp6"
|
|
||||||
-- Now rename the index (this fails)
|
|
||||||
ALTER INDEX tmp6_c_key RENAME TO tmp6_b_key;
|
|
||||||
NOTICE: ALTER INDEX will implicitly rename constraint "tmp6_c_key" to "tmp6_b_key" on table "public.tmp6"
|
|
||||||
ERROR: relation "tmp6_b_key" already exists
|
|
||||||
-- this succeeds and uses ALTER TABLE syntax to rename an INDEX
|
|
||||||
ALTER TABLE tmp6_c_key RENAME TO tmp6_a_key;
|
|
||||||
NOTICE: ALTER INDEX will implicitly rename constraint "tmp6_c_key" to "tmp6_a_key" on table "public.tmp6"
|
|
||||||
DROP TABLE tmp6;
|
|
||||||
DROP TABLE tmp5;
|
DROP TABLE tmp5;
|
||||||
DROP TABLE tmp4;
|
DROP TABLE tmp4;
|
||||||
DROP TABLE tmp3;
|
DROP TABLE tmp3;
|
||||||
|
@ -196,10 +196,6 @@ CREATE TABLE tmp4 (a int, b int, unique(a,b));
|
|||||||
|
|
||||||
CREATE TABLE tmp5 (a int, b int);
|
CREATE TABLE tmp5 (a int, b int);
|
||||||
|
|
||||||
-- creates implicit index tmp6_a_key
|
|
||||||
CREATE TABLE tmp6 (a int, b int, unique(a));
|
|
||||||
CREATE INDEX tmp6_b_key ON tmp6(b);
|
|
||||||
|
|
||||||
-- Insert rows into tmp2 (pktable)
|
-- Insert rows into tmp2 (pktable)
|
||||||
INSERT INTO tmp2 values (1);
|
INSERT INTO tmp2 values (1);
|
||||||
INSERT INTO tmp2 values (2);
|
INSERT INTO tmp2 values (2);
|
||||||
@ -231,21 +227,6 @@ ALTER TABLE tmp3 add constraint tmpconstr foreign key (a) references tmp2 match
|
|||||||
|
|
||||||
ALTER TABLE tmp5 add constraint tmpconstr foreign key(a) references tmp4(a) match full;
|
ALTER TABLE tmp5 add constraint tmpconstr foreign key(a) references tmp4(a) match full;
|
||||||
|
|
||||||
-- check if constraint and index name stay in sync if we rename one or the other
|
|
||||||
-- fail here
|
|
||||||
ALTER TABLE tmp6 ALTER CONSTRAINT tmp6_a_key RENAME TO tmp6_b_key;
|
|
||||||
|
|
||||||
-- succeed
|
|
||||||
ALTER TABLE tmp6 ALTER CONSTRAINT tmp6_a_key RENAME TO tmp6_c_key;
|
|
||||||
|
|
||||||
-- Now rename the index (this fails)
|
|
||||||
ALTER INDEX tmp6_c_key RENAME TO tmp6_b_key;
|
|
||||||
|
|
||||||
-- this succeeds and uses ALTER TABLE syntax to rename an INDEX
|
|
||||||
ALTER TABLE tmp6_c_key RENAME TO tmp6_a_key;
|
|
||||||
|
|
||||||
DROP TABLE tmp6;
|
|
||||||
|
|
||||||
DROP TABLE tmp5;
|
DROP TABLE tmp5;
|
||||||
|
|
||||||
DROP TABLE tmp4;
|
DROP TABLE tmp4;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user