1
0
mirror of https://github.com/postgres/postgres.git synced 2025-10-16 17:07:43 +03:00

Make ALTER .. SET SCHEMA do nothing, instead of throwing an ERROR.

This was already true for CREATE EXTENSION, but historically has not
been true for other object types.  Therefore, this is a backward
incompatibility.  Per discussion on pgsql-hackers, everyone seems to
agree that the new behavior is better.

Marti Raudsepp, reviewed by Haribabu Kommi and myself
This commit is contained in:
Robert Haas
2015-11-19 10:49:25 -05:00
parent f11c557e92
commit bc4996e61b
10 changed files with 61 additions and 43 deletions

View File

@@ -592,8 +592,18 @@ AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid)
Assert(!isnull);
oldNspOid = DatumGetObjectId(namespace);
/*
* If the object is already in the correct namespace, we don't need
* to do anything except fire the object access hook.
*/
if (oldNspOid == nspOid)
{
InvokeObjectPostAlterHook(classId, objid, 0);
return oldNspOid;
}
/* Check basic namespace related issues */
CheckSetNamespace(oldNspOid, nspOid, classId, objid);
CheckSetNamespace(oldNspOid, nspOid);
/* Permission checks ... superusers can always do it */
if (!superuser())

View File

@@ -11350,7 +11350,7 @@ AlterTableNamespace(AlterObjectSchemaStmt *stmt, Oid *oldschema)
nspOid = RangeVarGetAndCheckCreationNamespace(newrv, NoLock, NULL);
/* common checks on switching namespaces */
CheckSetNamespace(oldNspOid, nspOid, RelationRelationId, relid);
CheckSetNamespace(oldNspOid, nspOid);
objsMoved = new_object_addresses();
AlterTableNamespaceInternal(rel, oldNspOid, nspOid, objsMoved);
@@ -11418,6 +11418,7 @@ AlterRelationNamespaceInternal(Relation classRel, Oid relOid,
HeapTuple classTup;
Form_pg_class classForm;
ObjectAddress thisobj;
bool already_done = false;
classTup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relOid));
if (!HeapTupleIsValid(classTup))
@@ -11431,9 +11432,12 @@ AlterRelationNamespaceInternal(Relation classRel, Oid relOid,
thisobj.objectSubId = 0;
/*
* Do nothing when there's nothing to do.
* If the object has already been moved, don't move it again. If it's
* already in the right place, don't move it, but still fire the object
* access hook.
*/
if (!object_address_present(&thisobj, objsMoved))
already_done = object_address_present(&thisobj, objsMoved);
if (!already_done && oldNspOid != newNspOid)
{
/* check for duplicate name (more friendly than unique-index failure) */
if (get_relname_relid(NameStr(classForm->relname),
@@ -11459,7 +11463,9 @@ AlterRelationNamespaceInternal(Relation classRel, Oid relOid,
newNspOid) != 1)
elog(ERROR, "failed to change schema dependency for relation \"%s\"",
NameStr(classForm->relname));
}
if (!already_done)
{
add_exact_object_address(&thisobj, objsMoved);
InvokeObjectPostAlterHook(RelationRelationId, relOid, 0);

View File

@@ -3520,18 +3520,22 @@ AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid,
oldNspOid = typform->typnamespace;
arrayOid = typform->typarray;
/* common checks on switching namespaces */
CheckSetNamespace(oldNspOid, nspOid, TypeRelationId, typeOid);
/* If the type is already there, we scan skip these next few checks. */
if (oldNspOid != nspOid)
{
/* common checks on switching namespaces */
CheckSetNamespace(oldNspOid, nspOid);
/* check for duplicate name (more friendly than unique-index failure) */
if (SearchSysCacheExists2(TYPENAMENSP,
CStringGetDatum(NameStr(typform->typname)),
ObjectIdGetDatum(nspOid)))
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("type \"%s\" already exists in schema \"%s\"",
NameStr(typform->typname),
get_namespace_name(nspOid))));
/* check for duplicate name (more friendly than unique-index failure) */
if (SearchSysCacheExists2(TYPENAMENSP,
CStringGetDatum(NameStr(typform->typname)),
ObjectIdGetDatum(nspOid)))
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("type \"%s\" already exists in schema \"%s\"",
NameStr(typform->typname),
get_namespace_name(nspOid))));
}
/* Detect whether type is a composite type (but not a table rowtype) */
isCompositeType =
@@ -3547,13 +3551,16 @@ AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid,
format_type_be(typeOid)),
errhint("Use ALTER TABLE instead.")));
/* OK, modify the pg_type row */
if (oldNspOid != nspOid)
{
/* OK, modify the pg_type row */
/* tup is a copy, so we can scribble directly on it */
typform->typnamespace = nspOid;
/* tup is a copy, so we can scribble directly on it */
typform->typnamespace = nspOid;
simple_heap_update(rel, &tup->t_self, tup);
CatalogUpdateIndexes(rel, tup);
simple_heap_update(rel, &tup->t_self, tup);
CatalogUpdateIndexes(rel, tup);
}
/*
* Composite types have pg_class entries.
@@ -3592,7 +3599,8 @@ AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid,
* Update dependency on schema, if any --- a table rowtype has not got
* one, and neither does an implicit array.
*/
if ((isCompositeType || typform->typtype != TYPTYPE_COMPOSITE) &&
if (oldNspOid != nspOid &&
(isCompositeType || typform->typtype != TYPTYPE_COMPOSITE) &&
!isImplicitArray)
if (changeDependencyFor(TypeRelationId, typeOid,
NamespaceRelationId, oldNspOid, nspOid) != 1)