* Generic function to change the namespace of a given object, for simple * cases (won't work for tables, nor other cases where we need to do more * than change the namespace column of a single catalog entry). * * rel: catalog relation containing object (RowExclusiveLock'd by caller) * objid: OID of object to change the namespace of * nspOid: OID of new namespace * * Returns the OID of the
| 775 | * Returns the OID of the object's previous namespace. |
| 776 | */ |
| 777 | static Oid |
| 778 | AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid) |
| 779 | { |
| 780 | Oid classId = RelationGetRelid(rel); |
| 781 | int oidCacheId = get_object_catcache_oid(classId); |
| 782 | int nameCacheId = get_object_catcache_name(classId); |
| 783 | AttrNumber Anum_name = get_object_attnum_name(classId); |
| 784 | AttrNumber Anum_namespace = get_object_attnum_namespace(classId); |
| 785 | AttrNumber Anum_owner = get_object_attnum_owner(classId); |
| 786 | Oid oldNspOid; |
| 787 | Datum name, |
| 788 | namespace; |
| 789 | bool isnull; |
| 790 | HeapTuple tup, |
| 791 | newtup; |
| 792 | Datum *values; |
| 793 | bool *nulls; |
| 794 | bool *replaces; |
| 795 | |
| 796 | tup = SearchSysCacheCopy1(oidCacheId, ObjectIdGetDatum(objid)); |
| 797 | if (!HeapTupleIsValid(tup)) /* should not happen */ |
| 798 | elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"", |
| 799 | objid, RelationGetRelationName(rel)); |
| 800 | |
| 801 | name = heap_getattr(tup, Anum_name, RelationGetDescr(rel), &isnull); |
| 802 | Assert(!isnull); |
| 803 | namespace = heap_getattr(tup, Anum_namespace, RelationGetDescr(rel), |
| 804 | &isnull); |
| 805 | Assert(!isnull); |
| 806 | oldNspOid = DatumGetObjectId(namespace); |
| 807 | |
| 808 | /* |
| 809 | * If the object is already in the correct namespace, we don't need to do |
| 810 | * anything except fire the object access hook. |
| 811 | */ |
| 812 | if (oldNspOid == nspOid) |
| 813 | { |
| 814 | InvokeObjectPostAlterHook(classId, objid, 0); |
| 815 | return oldNspOid; |
| 816 | } |
| 817 | |
| 818 | /* Check basic namespace related issues */ |
| 819 | CheckSetNamespace(oldNspOid, nspOid); |
| 820 | |
| 821 | /* Permission checks ... superusers can always do it */ |
| 822 | if (!superuser()) |
| 823 | { |
| 824 | Datum owner; |
| 825 | Oid ownerId; |
| 826 | AclResult aclresult; |
| 827 | |
| 828 | /* Fail if object does not have an explicit owner */ |
| 829 | if (Anum_owner <= 0) |
| 830 | ereport(ERROR, |
| 831 | (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), |
| 832 | errmsg("must be superuser to set schema of %s", |
| 833 | getObjectDescriptionOids(classId, objid)))); |
| 834 |
no test coverage detected