diff options
Diffstat (limited to 'src/backend/commands')
-rw-r--r-- | src/backend/commands/alter.c | 12 | ||||
-rw-r--r-- | src/backend/commands/tablecmds.c | 14 | ||||
-rw-r--r-- | src/backend/commands/typecmds.c | 42 |
3 files changed, 46 insertions, 22 deletions
diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c index d28758cf8b2..535741e9236 100644 --- a/src/backend/commands/alter.c +++ b/src/backend/commands/alter.c @@ -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()) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 44ea7311639..b5d3708a6c1 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -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); diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index d2b3f2297b2..a126e666d88 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -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) |