pgsql-v9.3-alter-reworks.v1.patch
application/octet-stream
Filename: pgsql-v9.3-alter-reworks.v1.patch
Type: application/octet-stream
Part: 0
Message:
ALTER command reworks
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
Series: patch v9
| File | + | − |
|---|---|---|
| src/backend/catalog/objectaddress.c | 223 | 22 |
| src/backend/catalog/pg_largeobject.c | 0 | 102 |
| src/backend/catalog/pg_shdepend.c | 26 | 33 |
| src/backend/commands/aggregatecmds.c | 0 | 76 |
| src/backend/commands/alter.c | 438 | 156 |
| src/backend/commands/collationcmds.c | 0 | 167 |
| src/backend/commands/conversioncmds.c | 0 | 202 |
| src/backend/commands/extension.c | 0 | 92 |
| src/backend/commands/foreigncmds.c | 0 | 77 |
| src/backend/commands/functioncmds.c | 0 | 205 |
| src/backend/commands/opclasscmds.c | 0 | 500 |
| src/backend/commands/operatorcmds.c | 0 | 146 |
| src/backend/commands/proclang.c | 0 | 154 |
| src/backend/commands/tablespace.c | 0 | 99 |
| src/backend/commands/tsearchcmds.c | 0 | 496 |
| src/backend/nodes/copyfuncs.c | 0 | 2 |
| src/backend/nodes/equalfuncs.c | 0 | 2 |
| src/backend/parser/gram.y | 9 | 9 |
| src/include/catalog/objectaddress.h | 10 | 0 |
| src/include/catalog/pg_largeobject.h | 0 | 1 |
| src/include/commands/alter.h | 6 | 1 |
| src/include/commands/collationcmds.h | 0 | 3 |
| src/include/commands/conversioncmds.h | 0 | 4 |
| src/include/commands/defrem.h | 0 | 33 |
| src/include/commands/proclang.h | 0 | 1 |
| src/include/nodes/parsenodes.h | 0 | 2 |
| src/test/regress/expected/alter_generic.out | 545 | 0 |
| src/test/regress/parallel_schedule | 1 | 1 |
| src/test/regress/serial_schedule | 1 | 0 |
| src/test/regress/sql/alter_generic.sql | 413 | 0 |
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index 19bde9f..3848af5 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -78,7 +78,13 @@ typedef struct
Oid class_oid; /* oid of catalog */
Oid oid_index_oid; /* oid of index on system oid column */
int oid_catcache_id; /* id of catcache on system oid column */
+ int name_catcache_id; /* id of catcache on a pair of name and
+ * namespace column */
+ AttrNumber attnum_name; /* attnum of name field */
AttrNumber attnum_namespace; /* attnum of namespace field */
+ AttrNumber attnum_owner; /* attnum of owner field */
+ AttrNumber attnum_acl; /* attnum of acl field */
+ AclObjectKind acl_kind; /* ACL_KIND_* of this object type */
} ObjectPropertyType;
static ObjectPropertyType ObjectProperty[] =
@@ -87,151 +93,276 @@ static ObjectPropertyType ObjectProperty[] =
CastRelationId,
CastOidIndexId,
-1,
- InvalidAttrNumber
+ -1,
+ InvalidAttrNumber,
+ InvalidAttrNumber,
+ InvalidAttrNumber,
+ InvalidAttrNumber,
+ -1
},
{
CollationRelationId,
CollationOidIndexId,
COLLOID,
- Anum_pg_collation_collnamespace
+ -1, /* COLLNAMEENCNSP also takes encoding */
+ Anum_pg_collation_collname,
+ Anum_pg_collation_collnamespace,
+ Anum_pg_collation_collowner,
+ InvalidAttrNumber,
+ ACL_KIND_COLLATION
},
{
ConstraintRelationId,
ConstraintOidIndexId,
CONSTROID,
- Anum_pg_constraint_connamespace
+ -1,
+ Anum_pg_constraint_conname,
+ Anum_pg_constraint_connamespace,
+ InvalidAttrNumber,
+ InvalidAttrNumber,
+ -1
},
{
ConversionRelationId,
ConversionOidIndexId,
CONVOID,
- Anum_pg_conversion_connamespace
+ CONNAMENSP,
+ Anum_pg_conversion_conname,
+ Anum_pg_conversion_connamespace,
+ Anum_pg_conversion_conowner,
+ InvalidAttrNumber,
+ ACL_KIND_CONVERSION
},
{
DatabaseRelationId,
DatabaseOidIndexId,
DATABASEOID,
- InvalidAttrNumber
+ -1,
+ Anum_pg_database_datname,
+ InvalidAttrNumber,
+ Anum_pg_database_datdba,
+ Anum_pg_database_datacl,
+ ACL_KIND_DATABASE
},
{
ExtensionRelationId,
ExtensionOidIndexId,
-1,
- InvalidAttrNumber /* extension doesn't belong to extnamespace */
+ -1,
+ Anum_pg_extension_extname,
+ InvalidAttrNumber, /* extension doesn't belong to extnamespace */
+ Anum_pg_extension_extowner,
+ InvalidAttrNumber,
+ ACL_KIND_EXTENSION
},
{
ForeignDataWrapperRelationId,
ForeignDataWrapperOidIndexId,
FOREIGNDATAWRAPPEROID,
- InvalidAttrNumber
+ FOREIGNDATAWRAPPERNAME,
+ Anum_pg_foreign_data_wrapper_fdwname,
+ InvalidAttrNumber,
+ Anum_pg_foreign_data_wrapper_fdwowner,
+ Anum_pg_foreign_data_wrapper_fdwacl,
+ ACL_KIND_FDW
},
{
ForeignServerRelationId,
ForeignServerOidIndexId,
FOREIGNSERVEROID,
- InvalidAttrNumber
+ FOREIGNSERVERNAME,
+ Anum_pg_foreign_server_srvname,
+ InvalidAttrNumber,
+ Anum_pg_foreign_server_srvowner,
+ Anum_pg_foreign_server_srvacl,
+ ACL_KIND_FOREIGN_SERVER
},
{
ProcedureRelationId,
ProcedureOidIndexId,
PROCOID,
- Anum_pg_proc_pronamespace
+ -1, /* PROCNAMEARGSNSP also takes argument types */
+ Anum_pg_proc_proname,
+ Anum_pg_proc_pronamespace,
+ Anum_pg_proc_proowner,
+ Anum_pg_proc_proacl,
+ ACL_KIND_PROC
},
{
LanguageRelationId,
LanguageOidIndexId,
LANGOID,
+ LANGNAME,
+ Anum_pg_language_lanname,
InvalidAttrNumber,
+ Anum_pg_language_lanowner,
+ Anum_pg_language_lanacl,
+ ACL_KIND_LANGUAGE
},
{
LargeObjectMetadataRelationId,
LargeObjectMetadataOidIndexId,
-1,
- InvalidAttrNumber
+ -1,
+ InvalidAttrNumber,
+ InvalidAttrNumber,
+ Anum_pg_largeobject_metadata_lomowner,
+ Anum_pg_largeobject_metadata_lomacl,
+ ACL_KIND_LARGEOBJECT
},
{
OperatorClassRelationId,
OpclassOidIndexId,
CLAOID,
+ -1, /* CLAAMNAMENSP also takes opcmethod */
+ Anum_pg_opclass_opcname,
Anum_pg_opclass_opcnamespace,
+ Anum_pg_opclass_opcowner,
+ InvalidAttrNumber,
+ ACL_KIND_OPCLASS
},
{
OperatorRelationId,
OperatorOidIndexId,
OPEROID,
- Anum_pg_operator_oprnamespace
+ -1, /* OPERNAMENSP also takes left and right type */
+ Anum_pg_operator_oprname,
+ Anum_pg_operator_oprnamespace,
+ Anum_pg_operator_oprowner,
+ InvalidAttrNumber,
+ ACL_KIND_OPER
},
{
OperatorFamilyRelationId,
OpfamilyOidIndexId,
OPFAMILYOID,
- Anum_pg_opfamily_opfnamespace
+ -1, /* OPFAMILYAMNAMENSP also takes opfmethod */
+ Anum_pg_opfamily_opfname,
+ Anum_pg_opfamily_opfnamespace,
+ Anum_pg_opfamily_opfowner,
+ InvalidAttrNumber,
+ ACL_KIND_OPFAMILY
},
{
AuthIdRelationId,
AuthIdOidIndexId,
AUTHOID,
- InvalidAttrNumber
+ AUTHNAME,
+ Anum_pg_authid_rolname,
+ InvalidAttrNumber,
+ InvalidAttrNumber,
+ InvalidAttrNumber,
+ -1
},
{
RewriteRelationId,
RewriteOidIndexId,
-1,
- InvalidAttrNumber
+ -1,
+ Anum_pg_rewrite_rulename,
+ InvalidAttrNumber,
+ InvalidAttrNumber,
+ InvalidAttrNumber,
+ -1
},
{
NamespaceRelationId,
NamespaceOidIndexId,
NAMESPACEOID,
- InvalidAttrNumber
+ NAMESPACENAME,
+ Anum_pg_namespace_nspname,
+ InvalidAttrNumber,
+ Anum_pg_namespace_nspowner,
+ Anum_pg_namespace_nspacl,
+ ACL_KIND_NAMESPACE
},
{
RelationRelationId,
ClassOidIndexId,
RELOID,
- Anum_pg_class_relnamespace
+ RELNAMENSP,
+ Anum_pg_class_relname,
+ Anum_pg_class_relnamespace,
+ Anum_pg_class_relowner,
+ Anum_pg_class_relacl,
+ ACL_KIND_CLASS
},
{
TableSpaceRelationId,
TablespaceOidIndexId,
TABLESPACEOID,
- InvalidAttrNumber
+ -1,
+ Anum_pg_tablespace_spcname,
+ InvalidAttrNumber,
+ Anum_pg_tablespace_spcowner,
+ Anum_pg_tablespace_spcacl,
+ ACL_KIND_TABLESPACE
},
{
TriggerRelationId,
TriggerOidIndexId,
-1,
- InvalidAttrNumber
+ -1,
+ Anum_pg_trigger_tgname,
+ InvalidAttrNumber,
+ InvalidAttrNumber,
+ InvalidAttrNumber,
+ -1,
},
{
TSConfigRelationId,
TSConfigOidIndexId,
TSCONFIGOID,
- Anum_pg_ts_config_cfgnamespace
+ TSCONFIGNAMENSP,
+ Anum_pg_ts_config_cfgname,
+ Anum_pg_ts_config_cfgnamespace,
+ Anum_pg_ts_config_cfgowner,
+ InvalidAttrNumber,
+ ACL_KIND_TSCONFIGURATION
},
{
TSDictionaryRelationId,
TSDictionaryOidIndexId,
TSDICTOID,
- Anum_pg_ts_dict_dictnamespace
+ TSDICTNAMENSP,
+ Anum_pg_ts_dict_dictname,
+ Anum_pg_ts_dict_dictnamespace,
+ Anum_pg_ts_dict_dictowner,
+ InvalidAttrNumber,
+ ACL_KIND_TSDICTIONARY
},
{
TSParserRelationId,
TSParserOidIndexId,
TSPARSEROID,
- Anum_pg_ts_parser_prsnamespace
+ TSPARSERNAMENSP,
+ Anum_pg_ts_parser_prsname,
+ Anum_pg_ts_parser_prsnamespace,
+ InvalidAttrNumber,
+ InvalidAttrNumber,
+ -1,
},
{
TSTemplateRelationId,
TSTemplateOidIndexId,
TSTEMPLATEOID,
+ TSTEMPLATENAMENSP,
+ Anum_pg_ts_template_tmplname,
Anum_pg_ts_template_tmplnamespace,
+ InvalidAttrNumber,
+ InvalidAttrNumber,
+ -1,
},
{
TypeRelationId,
TypeOidIndexId,
TYPEOID,
- Anum_pg_type_typnamespace
+ TYPENAMENSP,
+ Anum_pg_type_typname,
+ Anum_pg_type_typnamespace,
+ Anum_pg_type_typowner,
+ Anum_pg_type_typacl,
+ ACL_KIND_TYPE
}
};
@@ -1110,16 +1241,86 @@ get_object_namespace(const ObjectAddress *address)
}
/*
+ * Interfaces to reference fields of ObjectPropertyType
+ */
+Oid
+get_object_oid_index(Oid class_id)
+{
+ ObjectPropertyType *prop = get_object_property_data(class_id);
+ return prop->oid_index_oid;
+}
+
+int
+get_object_catcache_oid(Oid class_id)
+{
+ ObjectPropertyType *prop = get_object_property_data(class_id);
+ return prop->oid_catcache_id;
+}
+
+int
+get_object_catcache_name(Oid class_id)
+{
+ ObjectPropertyType *prop = get_object_property_data(class_id);
+ return prop->name_catcache_id;
+}
+
+AttrNumber
+get_object_attnum_name(Oid class_id)
+{
+ ObjectPropertyType *prop = get_object_property_data(class_id);
+ return prop->attnum_name;
+}
+
+AttrNumber
+get_object_attnum_namespace(Oid class_id)
+{
+ ObjectPropertyType *prop = get_object_property_data(class_id);
+ return prop->attnum_namespace;
+}
+
+AttrNumber
+get_object_attnum_owner(Oid class_id)
+{
+ ObjectPropertyType *prop = get_object_property_data(class_id);
+ return prop->attnum_owner;
+}
+
+AttrNumber
+get_object_attnum_acl(Oid class_id)
+{
+ ObjectPropertyType *prop = get_object_property_data(class_id);
+ return prop->attnum_acl;
+}
+
+AclObjectKind
+get_object_aclkind(Oid class_id)
+{
+ ObjectPropertyType *prop = get_object_property_data(class_id);
+ return prop->acl_kind;
+}
+
+/*
* Find ObjectProperty structure by class_id.
*/
static ObjectPropertyType *
get_object_property_data(Oid class_id)
{
+ static ObjectPropertyType *prop_last = NULL;
int index;
+ /*
+ * A shortcut when caller want to know multiple attribute number
+ * towards a particular object class.
+ */
+ if (prop_last && prop_last->class_oid == class_id)
+ return prop_last;
+
for (index = 0; index < lengthof(ObjectProperty); index++)
if (ObjectProperty[index].class_oid == class_id)
+ {
+ prop_last = &ObjectProperty[index];
return &ObjectProperty[index];
+ }
elog(ERROR, "unrecognized class id: %u", class_id);
return NULL; /* not reached */
diff --git a/src/backend/catalog/pg_largeobject.c b/src/backend/catalog/pg_largeobject.c
index 1e5de6a..1fe7e2e 100644
--- a/src/backend/catalog/pg_largeobject.c
+++ b/src/backend/catalog/pg_largeobject.c
@@ -139,108 +139,6 @@ LargeObjectDrop(Oid loid)
}
/*
- * LargeObjectAlterOwner
- *
- * Implementation of ALTER LARGE OBJECT statement
- */
-void
-LargeObjectAlterOwner(Oid loid, Oid newOwnerId)
-{
- Form_pg_largeobject_metadata form_lo_meta;
- Relation pg_lo_meta;
- ScanKeyData skey[1];
- SysScanDesc scan;
- HeapTuple oldtup;
- HeapTuple newtup;
-
- pg_lo_meta = heap_open(LargeObjectMetadataRelationId,
- RowExclusiveLock);
-
- ScanKeyInit(&skey[0],
- ObjectIdAttributeNumber,
- BTEqualStrategyNumber, F_OIDEQ,
- ObjectIdGetDatum(loid));
-
- scan = systable_beginscan(pg_lo_meta,
- LargeObjectMetadataOidIndexId, true,
- SnapshotNow, 1, skey);
-
- oldtup = systable_getnext(scan);
- if (!HeapTupleIsValid(oldtup))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("large object %u does not exist", loid)));
-
- form_lo_meta = (Form_pg_largeobject_metadata) GETSTRUCT(oldtup);
- if (form_lo_meta->lomowner != newOwnerId)
- {
- Datum values[Natts_pg_largeobject_metadata];
- bool nulls[Natts_pg_largeobject_metadata];
- bool replaces[Natts_pg_largeobject_metadata];
- Acl *newAcl;
- Datum aclDatum;
- bool isnull;
-
- /* Superusers can always do it */
- if (!superuser())
- {
- /*
- * lo_compat_privileges is not checked here, because ALTER LARGE
- * OBJECT ... OWNER did not exist at all prior to PostgreSQL 9.0.
- *
- * We must be the owner of the existing object.
- */
- if (!pg_largeobject_ownercheck(loid, GetUserId()))
- ereport(ERROR,
- (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- errmsg("must be owner of large object %u", loid)));
-
- /* Must be able to become new owner */
- check_is_member_of_role(GetUserId(), newOwnerId);
- }
-
- memset(values, 0, sizeof(values));
- memset(nulls, false, sizeof(nulls));
- memset(replaces, false, sizeof(nulls));
-
- values[Anum_pg_largeobject_metadata_lomowner - 1]
- = ObjectIdGetDatum(newOwnerId);
- replaces[Anum_pg_largeobject_metadata_lomowner - 1] = true;
-
- /*
- * Determine the modified ACL for the new owner. This is only
- * necessary when the ACL is non-null.
- */
- aclDatum = heap_getattr(oldtup,
- Anum_pg_largeobject_metadata_lomacl,
- RelationGetDescr(pg_lo_meta), &isnull);
- if (!isnull)
- {
- newAcl = aclnewowner(DatumGetAclP(aclDatum),
- form_lo_meta->lomowner, newOwnerId);
- values[Anum_pg_largeobject_metadata_lomacl - 1]
- = PointerGetDatum(newAcl);
- replaces[Anum_pg_largeobject_metadata_lomacl - 1] = true;
- }
-
- newtup = heap_modify_tuple(oldtup, RelationGetDescr(pg_lo_meta),
- values, nulls, replaces);
-
- simple_heap_update(pg_lo_meta, &newtup->t_self, newtup);
- CatalogUpdateIndexes(pg_lo_meta, newtup);
-
- heap_freetuple(newtup);
-
- /* Update owner dependency reference */
- changeDependencyOnOwner(LargeObjectRelationId,
- loid, newOwnerId);
- }
- systable_endscan(scan);
-
- heap_close(pg_lo_meta, RowExclusiveLock);
-}
-
-/*
* LargeObjectExists
*
* We don't use the system cache for large object metadata, for fear of
diff --git a/src/backend/catalog/pg_shdepend.c b/src/backend/catalog/pg_shdepend.c
index a2bb9f5..de82e4e 100644
--- a/src/backend/catalog/pg_shdepend.c
+++ b/src/backend/catalog/pg_shdepend.c
@@ -1328,22 +1328,10 @@ shdepReassignOwned(List *roleids, Oid newrole)
/* Issue the appropriate ALTER OWNER call */
switch (sdepForm->classid)
{
- case CollationRelationId:
- AlterCollationOwner_oid(sdepForm->objid, newrole);
- break;
-
- case ConversionRelationId:
- AlterConversionOwner_oid(sdepForm->objid, newrole);
- break;
-
case TypeRelationId:
AlterTypeOwnerInternal(sdepForm->objid, newrole, true);
break;
- case OperatorRelationId:
- AlterOperatorOwner_oid(sdepForm->objid, newrole);
- break;
-
case NamespaceRelationId:
AlterSchemaOwner_oid(sdepForm->objid, newrole);
break;
@@ -1358,18 +1346,6 @@ shdepReassignOwned(List *roleids, Oid newrole)
ATExecChangeOwner(sdepForm->objid, newrole, true, AccessExclusiveLock);
break;
- case ProcedureRelationId:
- AlterFunctionOwner_oid(sdepForm->objid, newrole);
- break;
-
- case LanguageRelationId:
- AlterLanguageOwner_oid(sdepForm->objid, newrole);
- break;
-
- case LargeObjectRelationId:
- LargeObjectAlterOwner(sdepForm->objid, newrole);
- break;
-
case DefaultAclRelationId:
/*
@@ -1378,14 +1354,6 @@ shdepReassignOwned(List *roleids, Oid newrole)
*/
break;
- case OperatorClassRelationId:
- AlterOpClassOwner_oid(sdepForm->objid, newrole);
- break;
-
- case OperatorFamilyRelationId:
- AlterOpFamilyOwner_oid(sdepForm->objid, newrole);
- break;
-
case ForeignServerRelationId:
AlterForeignServerOwner_oid(sdepForm->objid, newrole);
break;
@@ -1394,8 +1362,33 @@ shdepReassignOwned(List *roleids, Oid newrole)
AlterForeignDataWrapperOwner_oid(sdepForm->objid, newrole);
break;
+ /* Generic alter owner cases */
+ case CollationRelationId:
+ case ConversionRelationId:
+ case OperatorRelationId:
+ case ProcedureRelationId:
+ case LanguageRelationId:
+ case LargeObjectRelationId:
+ case OperatorFamilyRelationId:
+ case OperatorClassRelationId:
case ExtensionRelationId:
- AlterExtensionOwner_oid(sdepForm->objid, newrole);
+ {
+ Oid classId = sdepForm->classid;
+ Relation catalog;
+
+ catalog = heap_open(classId, RowExclusiveLock);
+
+ AlterObjectOwner(catalog,
+ get_object_oid_index(classId),
+ get_object_catcache_oid(classId),
+ sdepForm->objid, newrole,
+ get_object_attnum_owner(classId),
+ get_object_attnum_namespace(classId),
+ get_object_attnum_acl(classId),
+ get_object_aclkind(classId));
+
+ heap_close(catalog, NoLock);
+ }
break;
default:
diff --git a/src/backend/commands/aggregatecmds.c b/src/backend/commands/aggregatecmds.c
index c0dcdf7..ef10495 100644
--- a/src/backend/commands/aggregatecmds.c
+++ b/src/backend/commands/aggregatecmds.c
@@ -205,79 +205,3 @@ DefineAggregate(List *name, List *args, bool oldstyle, List *parameters)
transTypeId, /* transition data type */
initval); /* initial condition */
}
-
-
-/*
- * RenameAggregate
- * Rename an aggregate.
- */
-void
-RenameAggregate(List *name, List *args, const char *newname)
-{
- Oid procOid;
- Oid namespaceOid;
- HeapTuple tup;
- Form_pg_proc procForm;
- Relation rel;
- AclResult aclresult;
-
- rel = heap_open(ProcedureRelationId, RowExclusiveLock);
-
- /* Look up function and make sure it's an aggregate */
- procOid = LookupAggNameTypeNames(name, args, false);
-
- tup = SearchSysCacheCopy1(PROCOID, ObjectIdGetDatum(procOid));
- if (!HeapTupleIsValid(tup)) /* should not happen */
- elog(ERROR, "cache lookup failed for function %u", procOid);
- procForm = (Form_pg_proc) GETSTRUCT(tup);
-
- namespaceOid = procForm->pronamespace;
-
- /* make sure the new name doesn't exist */
- if (SearchSysCacheExists3(PROCNAMEARGSNSP,
- CStringGetDatum(newname),
- PointerGetDatum(&procForm->proargtypes),
- ObjectIdGetDatum(namespaceOid)))
- ereport(ERROR,
- (errcode(ERRCODE_DUPLICATE_FUNCTION),
- errmsg("function %s already exists in schema \"%s\"",
- funcname_signature_string(newname,
- procForm->pronargs,
- NIL,
- procForm->proargtypes.values),
- get_namespace_name(namespaceOid))));
-
- /* must be owner */
- if (!pg_proc_ownercheck(procOid, GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC,
- NameListToString(name));
-
- /* must have CREATE privilege on namespace */
- aclresult = pg_namespace_aclcheck(namespaceOid, GetUserId(), ACL_CREATE);
- if (aclresult != ACLCHECK_OK)
- aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
- get_namespace_name(namespaceOid));
-
- /* rename */
- namestrcpy(&(((Form_pg_proc) GETSTRUCT(tup))->proname), newname);
- simple_heap_update(rel, &tup->t_self, tup);
- CatalogUpdateIndexes(rel, tup);
-
- heap_close(rel, NoLock);
- heap_freetuple(tup);
-}
-
-/*
- * Change aggregate owner
- */
-void
-AlterAggregateOwner(List *name, List *args, Oid newOwnerId)
-{
- Oid procOid;
-
- /* Look up function and make sure it's an aggregate */
- procOid = LookupAggNameTypeNames(name, args, false);
-
- /* The rest is just like a function */
- AlterFunctionOwner_oid(procOid, newOwnerId);
-}
diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c
index 4dd9927..665a790 100644
--- a/src/backend/commands/alter.c
+++ b/src/backend/commands/alter.c
@@ -14,6 +14,7 @@
*/
#include "postgres.h"
+#include "access/sysattr.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/namespace.h"
@@ -35,10 +36,166 @@
#include "miscadmin.h"
#include "tcop/utility.h"
#include "utils/builtins.h"
+#include "utils/fmgroids.h"
#include "utils/lsyscache.h"
#include "utils/rel.h"
#include "utils/syscache.h"
+#include "utils/tqual.h"
+/*
+ * AlterObjectRename
+ *
+ * Generic function to change the name of given object, for simple
+ * cases (won't tables, nor other cases where we need to do more
+ * than change the name column of a single catalog entry).
+ */
+static void
+AlterObjectRename(ObjectType objtype, List *objname, List *objargs,
+ char *new_name)
+{
+ ObjectAddress address;
+ ObjectAddress address_new;
+ List *objname_new;
+ Relation catalog;
+ Relation relation;
+ Oid oidIndexId;
+ int oidCacheId;
+ AttrNumber Anum_name;
+ AttrNumber Anum_namespace;
+ HeapTuple oldtup;
+ HeapTuple newtup;
+ Datum datum;
+ bool isnull;
+ Oid namespaceId;
+ NameData namebuf;
+ AttrNumber nattrs;
+ Datum *values;
+ bool *nulls;
+ bool *replaces;
+
+ /* Lookup class-id and object-id */
+ address = get_object_address(objtype, objname, objargs,
+ &relation,
+ ShareUpdateExclusiveLock, false);
+
+ catalog = heap_open(address.classId, RowExclusiveLock);
+
+ oidIndexId = get_object_oid_index(address.classId);
+ oidCacheId = get_object_catcache_oid(address.classId);
+ Anum_name = get_object_attnum_name(address.classId);
+ Anum_namespace = get_object_attnum_namespace(address.classId);
+
+ /* Fetch a catalog entry to be altered */
+ if (oidCacheId > 0)
+ {
+ oldtup = SearchSysCacheCopy1(oidCacheId,
+ ObjectIdGetDatum(address.objectId));
+ if (!HeapTupleIsValid(oldtup)) /* should not happen */
+ elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"",
+ address.objectId, RelationGetRelationName(catalog));
+ }
+ else
+ {
+ SysScanDesc scan;
+ ScanKeyData skey;
+
+ Assert(OidIsValid(oidIndexId));
+
+ ScanKeyInit(&skey,
+ ObjectIdAttributeNumber,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(address.objectId));
+
+ scan = systable_beginscan(catalog, oidIndexId, true,
+ SnapshotNow, 1, &skey);
+ oldtup = systable_getnext(scan);
+ if (!HeapTupleIsValid(oldtup))
+ elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"",
+ address.objectId, RelationGetRelationName(catalog));
+ oldtup = heap_copytuple(oldtup);
+
+ systable_endscan(scan);
+ }
+
+ /* Fetch namespace if exists */
+ if (Anum_namespace != InvalidAttrNumber)
+ {
+ datum = heap_getattr(oldtup, Anum_namespace,
+ RelationGetDescr(catalog), &isnull);
+ Assert(!isnull);
+ namespaceId = DatumGetObjectId(datum);
+ }
+ else
+ namespaceId = InvalidOid;
+
+ /* Ensure the new name doesn't exist */
+ Assert(list_length(objname) > 0);
+ objname_new = list_truncate(list_copy(objname),
+ list_length(objname) - 1);
+ objname_new = lappend(objname_new, makeString(new_name));
+
+ address_new = get_object_address(objtype, objname_new, objargs,
+ &relation,
+ ShareUpdateExclusiveLock, true);
+ if (OidIsValid(address_new.objectId))
+ {
+ if (OidIsValid(namespaceId))
+ ereport(ERROR,
+ (errcode(ERRCODE_DUPLICATE_OBJECT),
+ errmsg("%s already exists in schema \"%s\"",
+ getObjectDescription(&address_new),
+ get_namespace_name(namespaceId))));
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_DUPLICATE_OBJECT),
+ errmsg("%s already exists",
+ getObjectDescription(&address_new))));
+ }
+
+ /*
+ * Must be owner of the target object
+ */
+ check_object_ownership(GetUserId(), objtype, address,
+ objname, objargs, relation);
+
+ /*
+ * Must have CREATE privilege on namespace
+ */
+ if (OidIsValid(namespaceId))
+ {
+ AclResult aclresult;
+
+ aclresult = pg_namespace_aclcheck(namespaceId,
+ GetUserId(), ACL_CREATE);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
+ get_namespace_name(namespaceId));
+ }
+
+ /*
+ * Construct an entry of catalog with new name
+ */
+ nattrs = RelationGetNumberOfAttributes(catalog);
+ values = palloc0(nattrs * sizeof(Datum));
+ nulls = palloc0(nattrs * sizeof(bool));
+ replaces = palloc0(nattrs * sizeof(bool));
+ namestrcpy(&namebuf, new_name);
+ values[Anum_name - 1] = NameGetDatum(&namebuf);
+ replaces[Anum_name - 1] = true;
+ newtup = heap_modify_tuple(oldtup, RelationGetDescr(catalog),
+ values, nulls, replaces);
+
+ /* Perform actual update */
+ simple_heap_update(catalog, &oldtup->t_self, newtup);
+ CatalogUpdateIndexes(catalog, newtup);
+
+ heap_close(catalog, NoLock);
+
+ /* Release memory */
+ pfree(values);
+ pfree(nulls);
+ pfree(replaces);
+}
/*
* Executes an ALTER OBJECT / RENAME TO statement. Based on the object
@@ -49,50 +206,14 @@ ExecRenameStmt(RenameStmt *stmt)
{
switch (stmt->renameType)
{
- case OBJECT_AGGREGATE:
- RenameAggregate(stmt->object, stmt->objarg, stmt->newname);
- break;
-
- case OBJECT_COLLATION:
- RenameCollation(stmt->object, stmt->newname);
- break;
-
case OBJECT_CONSTRAINT:
RenameConstraint(stmt);
break;
- case OBJECT_CONVERSION:
- RenameConversion(stmt->object, stmt->newname);
- break;
-
case OBJECT_DATABASE:
RenameDatabase(stmt->subname, stmt->newname);
break;
- case OBJECT_FDW:
- RenameForeignDataWrapper(stmt->subname, stmt->newname);
- break;
-
- case OBJECT_FOREIGN_SERVER:
- RenameForeignServer(stmt->subname, stmt->newname);
- break;
-
- case OBJECT_FUNCTION:
- RenameFunction(stmt->object, stmt->objarg, stmt->newname);
- break;
-
- case OBJECT_LANGUAGE:
- RenameLanguage(stmt->subname, stmt->newname);
- break;
-
- case OBJECT_OPCLASS:
- RenameOpClass(stmt->object, stmt->subname, stmt->newname);
- break;
-
- case OBJECT_OPFAMILY:
- RenameOpFamily(stmt->object, stmt->subname, stmt->newname);
- break;
-
case OBJECT_ROLE:
RenameRole(stmt->subname, stmt->newname);
break;
@@ -122,25 +243,28 @@ ExecRenameStmt(RenameStmt *stmt)
renametrig(stmt);
break;
- case OBJECT_TSPARSER:
- RenameTSParser(stmt->object, stmt->newname);
+ case OBJECT_DOMAIN:
+ case OBJECT_TYPE:
+ RenameType(stmt);
break;
+ case OBJECT_AGGREGATE:
+ case OBJECT_COLLATION:
+ case OBJECT_CONVERSION:
+ case OBJECT_FDW:
+ case OBJECT_FOREIGN_SERVER:
+ case OBJECT_FUNCTION:
+ case OBJECT_LANGUAGE:
+ case OBJECT_OPCLASS:
+ case OBJECT_OPFAMILY:
+ case OBJECT_TSCONFIGURATION:
case OBJECT_TSDICTIONARY:
- RenameTSDictionary(stmt->object, stmt->newname);
- break;
-
+ case OBJECT_TSPARSER:
case OBJECT_TSTEMPLATE:
- RenameTSTemplate(stmt->object, stmt->newname);
- break;
-
- case OBJECT_TSCONFIGURATION:
- RenameTSConfiguration(stmt->object, stmt->newname);
- break;
-
- case OBJECT_DOMAIN:
- case OBJECT_TYPE:
- RenameType(stmt);
+ AlterObjectRename(stmt->renameType,
+ stmt->object,
+ stmt->objarg,
+ stmt->newname);
break;
default:
@@ -167,10 +291,6 @@ ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt)
AlterCollationNamespace(stmt->object, stmt->newschema);
break;
- case OBJECT_CONVERSION:
- AlterConversionNamespace(stmt->object, stmt->newschema);
- break;
-
case OBJECT_EXTENSION:
AlterExtensionNamespace(stmt->object, stmt->newschema);
break;
@@ -180,18 +300,6 @@ ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt)
stmt->newschema);
break;
- case OBJECT_OPERATOR:
- AlterOperatorNamespace(stmt->object, stmt->objarg, stmt->newschema);
- break;
-
- case OBJECT_OPCLASS:
- AlterOpClassNamespace(stmt->object, stmt->addname, stmt->newschema);
- break;
-
- case OBJECT_OPFAMILY:
- AlterOpFamilyNamespace(stmt->object, stmt->addname, stmt->newschema);
- break;
-
case OBJECT_SEQUENCE:
case OBJECT_TABLE:
case OBJECT_VIEW:
@@ -199,27 +307,51 @@ ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt)
AlterTableNamespace(stmt);
break;
- case OBJECT_TSPARSER:
- AlterTSParserNamespace(stmt->object, stmt->newschema);
+ case OBJECT_TYPE:
+ case OBJECT_DOMAIN:
+ AlterTypeNamespace(stmt->object, stmt->newschema, stmt->objectType);
break;
+ /* generic code path */
+ case OBJECT_CONVERSION:
+ case OBJECT_OPERATOR:
+ case OBJECT_OPCLASS:
+ case OBJECT_OPFAMILY:
+ case OBJECT_TSPARSER:
case OBJECT_TSDICTIONARY:
- AlterTSDictionaryNamespace(stmt->object, stmt->newschema);
- break;
-
case OBJECT_TSTEMPLATE:
- AlterTSTemplateNamespace(stmt->object, stmt->newschema);
- break;
-
case OBJECT_TSCONFIGURATION:
- AlterTSConfigurationNamespace(stmt->object, stmt->newschema);
- break;
-
- case OBJECT_TYPE:
- case OBJECT_DOMAIN:
- AlterTypeNamespace(stmt->object, stmt->newschema, stmt->objectType);
+ {
+ Relation catalog;
+ Relation relation;
+ Oid classId;
+ Oid nspOid;
+ ObjectAddress address;
+
+ address = get_object_address(stmt->objectType,
+ stmt->object,
+ stmt->objarg,
+ &relation,
+ ShareUpdateExclusiveLock,
+ false);
+ classId = address.classId;
+
+ catalog = heap_open(classId, RowExclusiveLock);
+
+ nspOid = LookupCreationNamespace(stmt->newschema);
+
+ AlterObjectNamespace(catalog,
+ get_object_catcache_oid(classId),
+ get_object_catcache_name(classId),
+ address.objectId, nspOid,
+ get_object_attnum_name(classId),
+ get_object_attnum_namespace(classId),
+ get_object_attnum_owner(classId),
+ get_object_aclkind(classId));
+
+ heap_close(catalog, RowExclusiveLock);
+ }
break;
-
default:
elog(ERROR, "unrecognized AlterObjectSchemaStmt type: %d",
(int) stmt->objectType);
@@ -287,35 +419,28 @@ AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid)
break;
case OCLASS_CONVERSION:
- oldNspOid = AlterConversionNamespace_oid(objid, nspOid);
- break;
-
case OCLASS_OPERATOR:
- oldNspOid = AlterOperatorNamespace_oid(objid, nspOid);
- break;
-
case OCLASS_OPCLASS:
- oldNspOid = AlterOpClassNamespace_oid(objid, nspOid);
- break;
-
case OCLASS_OPFAMILY:
- oldNspOid = AlterOpFamilyNamespace_oid(objid, nspOid);
- break;
-
case OCLASS_TSPARSER:
- oldNspOid = AlterTSParserNamespace_oid(objid, nspOid);
- break;
-
case OCLASS_TSDICT:
- oldNspOid = AlterTSDictionaryNamespace_oid(objid, nspOid);
- break;
-
case OCLASS_TSTEMPLATE:
- oldNspOid = AlterTSTemplateNamespace_oid(objid, nspOid);
- break;
-
case OCLASS_TSCONFIG:
- oldNspOid = AlterTSConfigurationNamespace_oid(objid, nspOid);
+ {
+ Relation catalog;
+
+ catalog = heap_open(classId, RowExclusiveLock);
+
+ AlterObjectNamespace(catalog,
+ get_object_catcache_oid(classId),
+ get_object_catcache_name(classId),
+ objid, nspOid,
+ get_object_attnum_name(classId),
+ get_object_attnum_namespace(classId),
+ get_object_attnum_owner(classId),
+ get_object_aclkind(classId));
+ heap_close(catalog, RowExclusiveLock);
+ }
break;
default:
@@ -460,82 +585,239 @@ ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
switch (stmt->objectType)
{
- case OBJECT_AGGREGATE:
- AlterAggregateOwner(stmt->object, stmt->objarg, newowner);
- break;
-
- case OBJECT_COLLATION:
- AlterCollationOwner(stmt->object, newowner);
- break;
-
- case OBJECT_CONVERSION:
- AlterConversionOwner(stmt->object, newowner);
- break;
-
case OBJECT_DATABASE:
+ /* its special code due to have_createdb_privilege() check */
AlterDatabaseOwner(strVal(linitial(stmt->object)), newowner);
break;
- case OBJECT_FUNCTION:
- AlterFunctionOwner(stmt->object, stmt->objarg, newowner);
- break;
-
- case OBJECT_LANGUAGE:
- AlterLanguageOwner(strVal(linitial(stmt->object)), newowner);
- break;
-
- case OBJECT_LARGEOBJECT:
- LargeObjectAlterOwner(oidparse(linitial(stmt->object)), newowner);
- break;
-
- case OBJECT_OPERATOR:
- Assert(list_length(stmt->objarg) == 2);
- AlterOperatorOwner(stmt->object,
- (TypeName *) linitial(stmt->objarg),
- (TypeName *) lsecond(stmt->objarg),
- newowner);
- break;
-
- case OBJECT_OPCLASS:
- AlterOpClassOwner(stmt->object, stmt->addname, newowner);
- break;
-
- case OBJECT_OPFAMILY:
- AlterOpFamilyOwner(stmt->object, stmt->addname, newowner);
- break;
-
case OBJECT_SCHEMA:
+ /* its special code due to CREATE permission check on database */
AlterSchemaOwner(strVal(linitial(stmt->object)), newowner);
break;
- case OBJECT_TABLESPACE:
- AlterTableSpaceOwner(strVal(linitial(stmt->object)), newowner);
- break;
-
case OBJECT_TYPE:
case OBJECT_DOMAIN: /* same as TYPE */
AlterTypeOwner(stmt->object, newowner, stmt->objectType);
break;
- case OBJECT_TSDICTIONARY:
- AlterTSDictionaryOwner(stmt->object, newowner);
- break;
-
- case OBJECT_TSCONFIGURATION:
- AlterTSConfigurationOwner(stmt->object, newowner);
- break;
-
case OBJECT_FDW:
+ /* its special code due to USAGE permission check on FDW */
AlterForeignDataWrapperOwner(strVal(linitial(stmt->object)),
newowner);
break;
case OBJECT_FOREIGN_SERVER:
+ /* its special code due to USAGE permission check on FDW */
AlterForeignServerOwner(strVal(linitial(stmt->object)), newowner);
break;
+ /* Generic cases */
+ case OBJECT_AGGREGATE:
+ case OBJECT_COLLATION:
+ case OBJECT_CONVERSION:
+ case OBJECT_FUNCTION:
+ case OBJECT_LANGUAGE:
+ case OBJECT_LARGEOBJECT:
+ case OBJECT_OPERATOR:
+ case OBJECT_OPCLASS:
+ case OBJECT_OPFAMILY:
+ case OBJECT_TABLESPACE:
+ case OBJECT_TSDICTIONARY:
+ case OBJECT_TSCONFIGURATION:
+ {
+ Relation catalog;
+ Relation relation;
+ Oid classId;
+ ObjectAddress address;
+
+ address = get_object_address(stmt->objectType,
+ stmt->object,
+ stmt->objarg,
+ &relation,
+ ShareUpdateExclusiveLock,
+ false);
+ classId = address.classId;
+
+ catalog = heap_open(address.classId, RowExclusiveLock);
+
+ AlterObjectOwner(catalog,
+ get_object_oid_index(classId),
+ get_object_catcache_oid(classId),
+ address.objectId,
+ newowner,
+ get_object_attnum_owner(classId),
+ get_object_attnum_namespace(classId),
+ get_object_attnum_acl(classId),
+ get_object_aclkind(classId));
+
+ heap_close(catalog, NoLock);
+ }
+ break;
+
default:
elog(ERROR, "unrecognized AlterOwnerStmt type: %d",
(int) stmt->objectType);
}
}
+
+/*
+ * Generic function to change the ownership of a given object, for simple
+ * cases (won't tables, nor other cases where we need to do more than
+ * change the ownership column of a single catalog entry).
+ *
+ * catalog: catalog relation containing object (RowExclusiveLock'd by caller)
+ * oidCacheId: syscache that indexes this catalog by OID
+ * objectId: OID of object to change the ownership of
+ * new_ownerId: OID of new object owner
+ * Anum_owner: column number of catalog's owner column
+ * Anum_namespace: column number of catalog's namespace column,
+ * or InvalidAttrNumber if none.
+ * Anum_acl: column number of catalog's owner column,
+ * or InvalidAttrNumber if none.
+ * acl_kind: ACL type for object, or -1 if none assigned
+ *
+ * Returns the OID of the object's previous namespace
+ */
+Oid
+AlterObjectOwner(Relation catalog, Oid oidIndexId, int oidCacheId,
+ Oid objectId, Oid new_ownerId,
+ AttrNumber Anum_owner,
+ AttrNumber Anum_namespace,
+ AttrNumber Anum_acl,
+ AclObjectKind aclkind)
+{
+ HeapTuple oldtup;
+ HeapTuple newtup;
+ Datum datum;
+ bool isnull;
+ Oid old_ownerId;
+ Oid namespaceId = InvalidOid;
+
+ if (oidCacheId > 0)
+ {
+ oldtup = SearchSysCacheCopy1(oidCacheId, ObjectIdGetDatum(objectId));
+ if (!HeapTupleIsValid(oldtup)) /* should not happen */
+ elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"",
+ objectId, RelationGetRelationName(catalog));
+ }
+ else
+ {
+ SysScanDesc scan;
+ ScanKeyData skey;
+
+ Assert(OidIsValid(oidIndexId));
+
+ ScanKeyInit(&skey,
+ ObjectIdAttributeNumber,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(objectId));
+
+ scan = systable_beginscan(catalog, oidIndexId, true,
+ SnapshotNow, 1, &skey);
+
+ oldtup = systable_getnext(scan);
+ if (!HeapTupleIsValid(oldtup))
+ elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"",
+ objectId, RelationGetRelationName(catalog));
+ oldtup = heap_copytuple(oldtup);
+
+ systable_endscan(scan);
+ }
+
+ datum = heap_getattr(oldtup, Anum_owner,
+ RelationGetDescr(catalog), &isnull);
+ Assert(!isnull);
+ old_ownerId = DatumGetObjectId(datum);
+
+ if (Anum_namespace != InvalidAttrNumber)
+ {
+ datum = heap_getattr(oldtup, Anum_namespace,
+ RelationGetDescr(catalog), &isnull);
+ Assert(!isnull);
+ namespaceId = DatumGetObjectId(datum);
+ }
+
+ if (old_ownerId != new_ownerId)
+ {
+ AttrNumber nattrs;
+ Datum *values;
+ bool *nulls;
+ bool *replaces;
+
+ /* Superusers can bypass permission checks */
+ if (!superuser())
+ {
+ ObjectAddress address;
+
+ address.classId = RelationGetRelid(catalog);
+ address.objectId = objectId;
+ address.objectSubId = 0;
+
+ /* must be owner */
+ if (!has_privs_of_role(GetUserId(), old_ownerId))
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("must be owner of %s",
+ getObjectDescription(&address))));
+
+ /* Must be able to become new owner */
+ check_is_member_of_role(GetUserId(), new_ownerId);
+
+ /* New owner must have CREATE privilege on namespace */
+ if (OidIsValid(namespaceId))
+ {
+ AclResult aclresult;
+
+ aclresult = pg_namespace_aclcheck(namespaceId, new_ownerId,
+ ACL_CREATE);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, aclkind,
+ get_namespace_name(namespaceId));
+ }
+ }
+
+ /* Build a modified tuple */
+ nattrs = RelationGetNumberOfAttributes(catalog);
+ values = palloc0(nattrs * sizeof(Datum));
+ nulls = palloc0(nattrs * sizeof(bool));
+ replaces = palloc0(nattrs * sizeof(bool));
+ values[Anum_owner - 1] = ObjectIdGetDatum(new_ownerId);
+ replaces[Anum_owner - 1] = true;
+
+ /*
+ * Determine the modified ACL for the new owner. This is only
+ * necessary when the ACL is non-null.
+ */
+ if (Anum_acl != InvalidAttrNumber)
+ {
+ datum = heap_getattr(oldtup,
+ Anum_acl, RelationGetDescr(catalog), &isnull);
+ if (!isnull)
+ {
+ Acl *newAcl;
+
+ newAcl = aclnewowner(DatumGetAclP(datum),
+ old_ownerId, new_ownerId);
+ values[Anum_acl - 1] = PointerGetDatum(newAcl);
+ replaces[Anum_acl - 1] = true;
+ }
+ }
+
+ newtup = heap_modify_tuple(oldtup, RelationGetDescr(catalog),
+ values, nulls, replaces);
+
+ /* Perform actual update */
+ simple_heap_update(catalog, &newtup->t_self, newtup);
+ CatalogUpdateIndexes(catalog, newtup);
+
+ /* Update owner dependency reference */
+ changeDependencyOnOwner(RelationGetRelid(catalog),
+ HeapTupleGetOid(newtup), new_ownerId);
+
+ /* Release memory */
+ pfree(values);
+ pfree(nulls);
+ pfree(replaces);
+ }
+ return old_ownerId;
+}
diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c
index e574288..0655833 100644
--- a/src/backend/commands/collationcmds.c
+++ b/src/backend/commands/collationcmds.c
@@ -33,9 +33,6 @@
#include "utils/rel.h"
#include "utils/syscache.h"
-static void AlterCollationOwner_internal(Relation rel, Oid collationOid,
- Oid newOwnerId);
-
/*
* CREATE COLLATION
*/
@@ -145,170 +142,6 @@ DefineCollation(List *names, List *parameters)
}
/*
- * Rename collation
- */
-void
-RenameCollation(List *name, const char *newname)
-{
- Oid collationOid;
- Oid namespaceOid;
- HeapTuple tup;
- Relation rel;
- AclResult aclresult;
-
- rel = heap_open(CollationRelationId, RowExclusiveLock);
-
- collationOid = get_collation_oid(name, false);
-
- tup = SearchSysCacheCopy1(COLLOID, ObjectIdGetDatum(collationOid));
- if (!HeapTupleIsValid(tup)) /* should not happen */
- elog(ERROR, "cache lookup failed for collation %u", collationOid);
-
- namespaceOid = ((Form_pg_collation) GETSTRUCT(tup))->collnamespace;
-
- /* make sure the new name doesn't exist */
- if (SearchSysCacheExists3(COLLNAMEENCNSP,
- CStringGetDatum(newname),
- Int32GetDatum(GetDatabaseEncoding()),
- ObjectIdGetDatum(namespaceOid)))
- ereport(ERROR,
- (errcode(ERRCODE_DUPLICATE_OBJECT),
- errmsg("collation \"%s\" for encoding \"%s\" already exists in schema \"%s\"",
- newname,
- GetDatabaseEncodingName(),
- get_namespace_name(namespaceOid))));
-
- /* mustn't match an any-encoding entry, either */
- if (SearchSysCacheExists3(COLLNAMEENCNSP,
- CStringGetDatum(newname),
- Int32GetDatum(-1),
- ObjectIdGetDatum(namespaceOid)))
- ereport(ERROR,
- (errcode(ERRCODE_DUPLICATE_OBJECT),
- errmsg("collation \"%s\" already exists in schema \"%s\"",
- newname,
- get_namespace_name(namespaceOid))));
-
- /* must be owner */
- if (!pg_collation_ownercheck(collationOid, GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_COLLATION,
- NameListToString(name));
-
- /* must have CREATE privilege on namespace */
- aclresult = pg_namespace_aclcheck(namespaceOid, GetUserId(), ACL_CREATE);
- if (aclresult != ACLCHECK_OK)
- aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
- get_namespace_name(namespaceOid));
-
- /* rename */
- namestrcpy(&(((Form_pg_collation) GETSTRUCT(tup))->collname), newname);
- simple_heap_update(rel, &tup->t_self, tup);
- CatalogUpdateIndexes(rel, tup);
-
- heap_freetuple(tup);
-
- heap_close(rel, RowExclusiveLock);
-}
-
-/*
- * Change collation owner, by name
- */
-void
-AlterCollationOwner(List *name, Oid newOwnerId)
-{
- Oid collationOid;
- Relation rel;
-
- rel = heap_open(CollationRelationId, RowExclusiveLock);
-
- collationOid = get_collation_oid(name, false);
-
- AlterCollationOwner_internal(rel, collationOid, newOwnerId);
-
- heap_close(rel, RowExclusiveLock);
-}
-
-/*
- * Change collation owner, by oid
- */
-void
-AlterCollationOwner_oid(Oid collationOid, Oid newOwnerId)
-{
- Relation rel;
-
- rel = heap_open(CollationRelationId, RowExclusiveLock);
-
- AlterCollationOwner_internal(rel, collationOid, newOwnerId);
-
- heap_close(rel, RowExclusiveLock);
-}
-
-/*
- * AlterCollationOwner_internal
- *
- * Internal routine for changing the owner. rel must be pg_collation, already
- * open and suitably locked; it will not be closed.
- */
-static void
-AlterCollationOwner_internal(Relation rel, Oid collationOid, Oid newOwnerId)
-{
- Form_pg_collation collForm;
- HeapTuple tup;
-
- Assert(RelationGetRelid(rel) == CollationRelationId);
-
- tup = SearchSysCacheCopy1(COLLOID, ObjectIdGetDatum(collationOid));
- if (!HeapTupleIsValid(tup)) /* should not happen */
- elog(ERROR, "cache lookup failed for collation %u", collationOid);
-
- collForm = (Form_pg_collation) GETSTRUCT(tup);
-
- /*
- * If the new owner is the same as the existing owner, consider the
- * command to have succeeded. This is for dump restoration purposes.
- */
- if (collForm->collowner != newOwnerId)
- {
- AclResult aclresult;
-
- /* Superusers can always do it */
- if (!superuser())
- {
- /* Otherwise, must be owner of the existing object */
- if (!pg_collation_ownercheck(HeapTupleGetOid(tup), GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_COLLATION,
- NameStr(collForm->collname));
-
- /* Must be able to become new owner */
- check_is_member_of_role(GetUserId(), newOwnerId);
-
- /* New owner must have CREATE privilege on namespace */
- aclresult = pg_namespace_aclcheck(collForm->collnamespace,
- newOwnerId,
- ACL_CREATE);
- if (aclresult != ACLCHECK_OK)
- aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
- get_namespace_name(collForm->collnamespace));
- }
-
- /*
- * Modify the owner --- okay to scribble on tup because it's a copy
- */
- collForm->collowner = newOwnerId;
-
- simple_heap_update(rel, &tup->t_self, tup);
-
- CatalogUpdateIndexes(rel, tup);
-
- /* Update owner dependency reference */
- changeDependencyOnOwner(CollationRelationId, collationOid,
- newOwnerId);
- }
-
- heap_freetuple(tup);
-}
-
-/*
* Execute ALTER COLLATION SET SCHEMA
*/
void
diff --git a/src/backend/commands/conversioncmds.c b/src/backend/commands/conversioncmds.c
index aad7e46..e745bb8 100644
--- a/src/backend/commands/conversioncmds.c
+++ b/src/backend/commands/conversioncmds.c
@@ -30,9 +30,6 @@
#include "utils/rel.h"
#include "utils/syscache.h"
-static void AlterConversionOwner_internal(Relation rel, Oid conversionOid,
- Oid newOwnerId);
-
/*
* CREATE CONVERSION
*/
@@ -116,202 +113,3 @@ CreateConversionCommand(CreateConversionStmt *stmt)
ConversionCreate(conversion_name, namespaceId, GetUserId(),
from_encoding, to_encoding, funcoid, stmt->def);
}
-
-/*
- * Rename conversion
- */
-void
-RenameConversion(List *name, const char *newname)
-{
- Oid conversionOid;
- Oid namespaceOid;
- HeapTuple tup;
- Relation rel;
- AclResult aclresult;
-
- rel = heap_open(ConversionRelationId, RowExclusiveLock);
-
- conversionOid = get_conversion_oid(name, false);
-
- tup = SearchSysCacheCopy1(CONVOID, ObjectIdGetDatum(conversionOid));
- if (!HeapTupleIsValid(tup)) /* should not happen */
- elog(ERROR, "cache lookup failed for conversion %u", conversionOid);
-
- namespaceOid = ((Form_pg_conversion) GETSTRUCT(tup))->connamespace;
-
- /* make sure the new name doesn't exist */
- if (SearchSysCacheExists2(CONNAMENSP,
- CStringGetDatum(newname),
- ObjectIdGetDatum(namespaceOid)))
- ereport(ERROR,
- (errcode(ERRCODE_DUPLICATE_OBJECT),
- errmsg("conversion \"%s\" already exists in schema \"%s\"",
- newname, get_namespace_name(namespaceOid))));
-
- /* must be owner */
- if (!pg_conversion_ownercheck(conversionOid, GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CONVERSION,
- NameListToString(name));
-
- /* must have CREATE privilege on namespace */
- aclresult = pg_namespace_aclcheck(namespaceOid, GetUserId(), ACL_CREATE);
- if (aclresult != ACLCHECK_OK)
- aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
- get_namespace_name(namespaceOid));
-
- /* rename */
- namestrcpy(&(((Form_pg_conversion) GETSTRUCT(tup))->conname), newname);
- simple_heap_update(rel, &tup->t_self, tup);
- CatalogUpdateIndexes(rel, tup);
-
- heap_close(rel, NoLock);
- heap_freetuple(tup);
-}
-
-/*
- * Change conversion owner, by name
- */
-void
-AlterConversionOwner(List *name, Oid newOwnerId)
-{
- Oid conversionOid;
- Relation rel;
-
- rel = heap_open(ConversionRelationId, RowExclusiveLock);
-
- conversionOid = get_conversion_oid(name, false);
-
- AlterConversionOwner_internal(rel, conversionOid, newOwnerId);
-
- heap_close(rel, NoLock);
-}
-
-/*
- * Change conversion owner, by oid
- */
-void
-AlterConversionOwner_oid(Oid conversionOid, Oid newOwnerId)
-{
- Relation rel;
-
- rel = heap_open(ConversionRelationId, RowExclusiveLock);
-
- AlterConversionOwner_internal(rel, conversionOid, newOwnerId);
-
- heap_close(rel, NoLock);
-}
-
-/*
- * AlterConversionOwner_internal
- *
- * Internal routine for changing the owner. rel must be pg_conversion, already
- * open and suitably locked; it will not be closed.
- */
-static void
-AlterConversionOwner_internal(Relation rel, Oid conversionOid, Oid newOwnerId)
-{
- Form_pg_conversion convForm;
- HeapTuple tup;
-
- Assert(RelationGetRelid(rel) == ConversionRelationId);
-
- tup = SearchSysCacheCopy1(CONVOID, ObjectIdGetDatum(conversionOid));
- if (!HeapTupleIsValid(tup)) /* should not happen */
- elog(ERROR, "cache lookup failed for conversion %u", conversionOid);
-
- convForm = (Form_pg_conversion) GETSTRUCT(tup);
-
- /*
- * If the new owner is the same as the existing owner, consider the
- * command to have succeeded. This is for dump restoration purposes.
- */
- if (convForm->conowner != newOwnerId)
- {
- AclResult aclresult;
-
- /* Superusers can always do it */
- if (!superuser())
- {
- /* Otherwise, must be owner of the existing object */
- if (!pg_conversion_ownercheck(HeapTupleGetOid(tup), GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CONVERSION,
- NameStr(convForm->conname));
-
- /* Must be able to become new owner */
- check_is_member_of_role(GetUserId(), newOwnerId);
-
- /* New owner must have CREATE privilege on namespace */
- aclresult = pg_namespace_aclcheck(convForm->connamespace,
- newOwnerId,
- ACL_CREATE);
- if (aclresult != ACLCHECK_OK)
- aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
- get_namespace_name(convForm->connamespace));
- }
-
- /*
- * Modify the owner --- okay to scribble on tup because it's a copy
- */
- convForm->conowner = newOwnerId;
-
- simple_heap_update(rel, &tup->t_self, tup);
-
- CatalogUpdateIndexes(rel, tup);
-
- /* Update owner dependency reference */
- changeDependencyOnOwner(ConversionRelationId, conversionOid,
- newOwnerId);
- }
-
- heap_freetuple(tup);
-}
-
-/*
- * Execute ALTER CONVERSION SET SCHEMA
- */
-void
-AlterConversionNamespace(List *name, const char *newschema)
-{
- Oid convOid,
- nspOid;
- Relation rel;
-
- rel = heap_open(ConversionRelationId, RowExclusiveLock);
-
- convOid = get_conversion_oid(name, false);
-
- /* get schema OID */
- nspOid = LookupCreationNamespace(newschema);
-
- AlterObjectNamespace(rel, CONVOID, CONNAMENSP,
- convOid, nspOid,
- Anum_pg_conversion_conname,
- Anum_pg_conversion_connamespace,
- Anum_pg_conversion_conowner,
- ACL_KIND_CONVERSION);
-
- heap_close(rel, RowExclusiveLock);
-}
-
-/*
- * Change conversion schema, by oid
- */
-Oid
-AlterConversionNamespace_oid(Oid convOid, Oid newNspOid)
-{
- Oid oldNspOid;
- Relation rel;
-
- rel = heap_open(ConversionRelationId, RowExclusiveLock);
-
- oldNspOid = AlterObjectNamespace(rel, CONVOID, CONNAMENSP,
- convOid, newNspOid,
- Anum_pg_conversion_conname,
- Anum_pg_conversion_connamespace,
- Anum_pg_conversion_conowner,
- ACL_KIND_CONVERSION);
-
- heap_close(rel, RowExclusiveLock);
-
- return oldNspOid;
-}
diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index 5d6bc7a..cde3d60 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -2724,95 +2724,3 @@ ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt)
if (relation != NULL)
relation_close(relation, NoLock);
}
-
-/*
- * AlterExtensionOwner_internal
- *
- * Internal routine for changing the owner of an extension. rel must be
- * pg_extension, already open and suitably locked; it will not be closed.
- *
- * Note that this only changes ownership of the extension itself; it doesn't
- * change the ownership of objects it contains. Since this function is
- * currently only called from REASSIGN OWNED, this restriction is okay because
- * said objects would also be affected by our caller. But it's not enough for
- * a full-fledged ALTER OWNER implementation, so beware.
- */
-static void
-AlterExtensionOwner_internal(Relation rel, Oid extensionOid, Oid newOwnerId)
-{
- Form_pg_extension extForm;
- HeapTuple tup;
- SysScanDesc scandesc;
- ScanKeyData entry[1];
-
- Assert(RelationGetRelid(rel) == ExtensionRelationId);
-
- ScanKeyInit(&entry[0],
- ObjectIdAttributeNumber,
- BTEqualStrategyNumber, F_OIDEQ,
- ObjectIdGetDatum(extensionOid));
-
- scandesc = systable_beginscan(rel, ExtensionOidIndexId, true,
- SnapshotNow, 1, entry);
-
- /* We assume that there can be at most one matching tuple */
- tup = systable_getnext(scandesc);
- if (!HeapTupleIsValid(tup)) /* should not happen */
- elog(ERROR, "cache lookup failed for extension %u", extensionOid);
-
- tup = heap_copytuple(tup);
- systable_endscan(scandesc);
-
- extForm = (Form_pg_extension) GETSTRUCT(tup);
-
- /*
- * If the new owner is the same as the existing owner, consider the
- * command to have succeeded. This is for dump restoration purposes.
- */
- if (extForm->extowner != newOwnerId)
- {
- /* Superusers can always do it */
- if (!superuser())
- {
- /* Otherwise, must be owner of the existing object */
- if (!pg_extension_ownercheck(HeapTupleGetOid(tup), GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_EXTENSION,
- NameStr(extForm->extname));
-
- /* Must be able to become new owner */
- check_is_member_of_role(GetUserId(), newOwnerId);
-
- /* no privilege checks on namespace are required */
- }
-
- /*
- * Modify the owner --- okay to scribble on tup because it's a copy
- */
- extForm->extowner = newOwnerId;
-
- simple_heap_update(rel, &tup->t_self, tup);
-
- CatalogUpdateIndexes(rel, tup);
-
- /* Update owner dependency reference */
- changeDependencyOnOwner(ExtensionRelationId, extensionOid,
- newOwnerId);
- }
-
- heap_freetuple(tup);
-}
-
-/*
- * Change extension owner, by OID
- */
-void
-AlterExtensionOwner_oid(Oid extensionOid, Oid newOwnerId)
-{
- Relation rel;
-
- rel = heap_open(ExtensionRelationId, RowExclusiveLock);
-
- AlterExtensionOwner_internal(rel, extensionOid, newOwnerId);
-
- heap_close(rel, NoLock);
-}
diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c
index 342ecc2..d358b32 100644
--- a/src/backend/commands/foreigncmds.c
+++ b/src/backend/commands/foreigncmds.c
@@ -199,83 +199,6 @@ GetUserOidFromMapping(const char *username, bool missing_ok)
return get_role_oid(username, missing_ok);
}
-
-/*
- * Rename foreign-data wrapper
- */
-void
-RenameForeignDataWrapper(const char *oldname, const char *newname)
-{
- HeapTuple tup;
- Relation rel;
-
- rel = heap_open(ForeignDataWrapperRelationId, RowExclusiveLock);
-
- tup = SearchSysCacheCopy1(FOREIGNDATAWRAPPERNAME, CStringGetDatum(oldname));
- if (!HeapTupleIsValid(tup))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("foreign-data wrapper \"%s\" does not exist", oldname)));
-
- /* make sure the new name doesn't exist */
- if (SearchSysCacheExists1(FOREIGNDATAWRAPPERNAME, CStringGetDatum(newname)))
- ereport(ERROR,
- (errcode(ERRCODE_DUPLICATE_OBJECT),
- errmsg("foreign-data wrapper \"%s\" already exists", newname)));
-
- /* must be owner of FDW */
- if (!pg_foreign_data_wrapper_ownercheck(HeapTupleGetOid(tup), GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_FDW,
- oldname);
-
- /* rename */
- namestrcpy(&(((Form_pg_foreign_data_wrapper) GETSTRUCT(tup))->fdwname), newname);
- simple_heap_update(rel, &tup->t_self, tup);
- CatalogUpdateIndexes(rel, tup);
-
- heap_close(rel, NoLock);
- heap_freetuple(tup);
-}
-
-
-/*
- * Rename foreign server
- */
-void
-RenameForeignServer(const char *oldname, const char *newname)
-{
- HeapTuple tup;
- Relation rel;
-
- rel = heap_open(ForeignServerRelationId, RowExclusiveLock);
-
- tup = SearchSysCacheCopy1(FOREIGNSERVERNAME, CStringGetDatum(oldname));
- if (!HeapTupleIsValid(tup))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("server \"%s\" does not exist", oldname)));
-
- /* make sure the new name doesn't exist */
- if (SearchSysCacheExists1(FOREIGNSERVERNAME, CStringGetDatum(newname)))
- ereport(ERROR,
- (errcode(ERRCODE_DUPLICATE_OBJECT),
- errmsg("server \"%s\" already exists", newname)));
-
- /* must be owner of server */
- if (!pg_foreign_server_ownercheck(HeapTupleGetOid(tup), GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_FOREIGN_SERVER,
- oldname);
-
- /* rename */
- namestrcpy(&(((Form_pg_foreign_server) GETSTRUCT(tup))->srvname), newname);
- simple_heap_update(rel, &tup->t_self, tup);
- CatalogUpdateIndexes(rel, tup);
-
- heap_close(rel, NoLock);
- heap_freetuple(tup);
-}
-
-
/*
* Internal workhorse for changing a data wrapper's owner.
*
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 9ba6dd8..2f81d01 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -64,11 +64,6 @@
#include "utils/syscache.h"
#include "utils/tqual.h"
-
-static void AlterFunctionOwner_internal(Relation rel, HeapTuple tup,
- Oid newOwnerId);
-
-
/*
* Examine the RETURNS clause of the CREATE FUNCTION statement
* and return information about it as *prorettype_p and *returnsSet.
@@ -1047,206 +1042,6 @@ RemoveFunctionById(Oid funcOid)
}
}
-
-/*
- * Rename function
- */
-void
-RenameFunction(List *name, List *argtypes, const char *newname)
-{
- Oid procOid;
- Oid namespaceOid;
- HeapTuple tup;
- Form_pg_proc procForm;
- Relation rel;
- AclResult aclresult;
-
- rel = heap_open(ProcedureRelationId, RowExclusiveLock);
-
- procOid = LookupFuncNameTypeNames(name, argtypes, false);
-
- tup = SearchSysCacheCopy1(PROCOID, ObjectIdGetDatum(procOid));
- if (!HeapTupleIsValid(tup)) /* should not happen */
- elog(ERROR, "cache lookup failed for function %u", procOid);
- procForm = (Form_pg_proc) GETSTRUCT(tup);
-
- if (procForm->proisagg)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is an aggregate function",
- NameListToString(name)),
- errhint("Use ALTER AGGREGATE to rename aggregate functions.")));
-
- namespaceOid = procForm->pronamespace;
-
- /* make sure the new name doesn't exist */
- if (SearchSysCacheExists3(PROCNAMEARGSNSP,
- CStringGetDatum(newname),
- PointerGetDatum(&procForm->proargtypes),
- ObjectIdGetDatum(namespaceOid)))
- {
- ereport(ERROR,
- (errcode(ERRCODE_DUPLICATE_FUNCTION),
- errmsg("function %s already exists in schema \"%s\"",
- funcname_signature_string(newname,
- procForm->pronargs,
- NIL,
- procForm->proargtypes.values),
- get_namespace_name(namespaceOid))));
- }
-
- /* must be owner */
- if (!pg_proc_ownercheck(procOid, GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC,
- NameListToString(name));
-
- /* must have CREATE privilege on namespace */
- aclresult = pg_namespace_aclcheck(namespaceOid, GetUserId(), ACL_CREATE);
- if (aclresult != ACLCHECK_OK)
- aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
- get_namespace_name(namespaceOid));
-
- /* rename */
- namestrcpy(&(procForm->proname), newname);
- simple_heap_update(rel, &tup->t_self, tup);
- CatalogUpdateIndexes(rel, tup);
-
- heap_close(rel, NoLock);
- heap_freetuple(tup);
-}
-
-/*
- * Change function owner by name and args
- */
-void
-AlterFunctionOwner(List *name, List *argtypes, Oid newOwnerId)
-{
- Relation rel;
- Oid procOid;
- HeapTuple tup;
-
- rel = heap_open(ProcedureRelationId, RowExclusiveLock);
-
- procOid = LookupFuncNameTypeNames(name, argtypes, false);
-
- tup = SearchSysCache1(PROCOID, ObjectIdGetDatum(procOid));
- if (!HeapTupleIsValid(tup)) /* should not happen */
- elog(ERROR, "cache lookup failed for function %u", procOid);
-
- if (((Form_pg_proc) GETSTRUCT(tup))->proisagg)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is an aggregate function",
- NameListToString(name)),
- errhint("Use ALTER AGGREGATE to change owner of aggregate functions.")));
-
- AlterFunctionOwner_internal(rel, tup, newOwnerId);
-
- heap_close(rel, NoLock);
-}
-
-/*
- * Change function owner by Oid
- */
-void
-AlterFunctionOwner_oid(Oid procOid, Oid newOwnerId)
-{
- Relation rel;
- HeapTuple tup;
-
- rel = heap_open(ProcedureRelationId, RowExclusiveLock);
-
- tup = SearchSysCache1(PROCOID, ObjectIdGetDatum(procOid));
- if (!HeapTupleIsValid(tup)) /* should not happen */
- elog(ERROR, "cache lookup failed for function %u", procOid);
- AlterFunctionOwner_internal(rel, tup, newOwnerId);
-
- heap_close(rel, NoLock);
-}
-
-static void
-AlterFunctionOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
-{
- Form_pg_proc procForm;
- AclResult aclresult;
- Oid procOid;
-
- Assert(RelationGetRelid(rel) == ProcedureRelationId);
- Assert(tup->t_tableOid == ProcedureRelationId);
-
- procForm = (Form_pg_proc) GETSTRUCT(tup);
- procOid = HeapTupleGetOid(tup);
-
- /*
- * If the new owner is the same as the existing owner, consider the
- * command to have succeeded. This is for dump restoration purposes.
- */
- if (procForm->proowner != newOwnerId)
- {
- Datum repl_val[Natts_pg_proc];
- bool repl_null[Natts_pg_proc];
- bool repl_repl[Natts_pg_proc];
- Acl *newAcl;
- Datum aclDatum;
- bool isNull;
- HeapTuple newtuple;
-
- /* Superusers can always do it */
- if (!superuser())
- {
- /* Otherwise, must be owner of the existing object */
- if (!pg_proc_ownercheck(procOid, GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC,
- NameStr(procForm->proname));
-
- /* Must be able to become new owner */
- check_is_member_of_role(GetUserId(), newOwnerId);
-
- /* New owner must have CREATE privilege on namespace */
- aclresult = pg_namespace_aclcheck(procForm->pronamespace,
- newOwnerId,
- ACL_CREATE);
- if (aclresult != ACLCHECK_OK)
- aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
- get_namespace_name(procForm->pronamespace));
- }
-
- memset(repl_null, false, sizeof(repl_null));
- memset(repl_repl, false, sizeof(repl_repl));
-
- repl_repl[Anum_pg_proc_proowner - 1] = true;
- repl_val[Anum_pg_proc_proowner - 1] = ObjectIdGetDatum(newOwnerId);
-
- /*
- * Determine the modified ACL for the new owner. This is only
- * necessary when the ACL is non-null.
- */
- aclDatum = SysCacheGetAttr(PROCOID, tup,
- Anum_pg_proc_proacl,
- &isNull);
- if (!isNull)
- {
- newAcl = aclnewowner(DatumGetAclP(aclDatum),
- procForm->proowner, newOwnerId);
- repl_repl[Anum_pg_proc_proacl - 1] = true;
- repl_val[Anum_pg_proc_proacl - 1] = PointerGetDatum(newAcl);
- }
-
- newtuple = heap_modify_tuple(tup, RelationGetDescr(rel), repl_val,
- repl_null, repl_repl);
-
- simple_heap_update(rel, &newtuple->t_self, newtuple);
- CatalogUpdateIndexes(rel, newtuple);
-
- heap_freetuple(newtuple);
-
- /* Update owner dependency reference */
- changeDependencyOnOwner(ProcedureRelationId, procOid, newOwnerId);
- }
-
- ReleaseSysCache(tup);
-}
-
/*
* Implements the ALTER FUNCTION utility command (except for the
* RENAME and OWNER clauses, which are handled as part of the generic
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index f564244..4c9818e 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -80,11 +80,6 @@ static void dropOperators(List *opfamilyname, Oid amoid, Oid opfamilyoid,
List *operators);
static void dropProcedures(List *opfamilyname, Oid amoid, Oid opfamilyoid,
List *procedures);
-static void AlterOpClassOwner_internal(Relation rel, HeapTuple tuple,
- Oid newOwnerId);
-static void AlterOpFamilyOwner_internal(Relation rel, HeapTuple tuple,
- Oid newOwnerId);
-
/*
* OpFamilyCacheLookup
@@ -1660,449 +1655,6 @@ RemoveAmProcEntryById(Oid entryOid)
heap_close(rel, RowExclusiveLock);
}
-
-/*
- * Rename opclass
- */
-void
-RenameOpClass(List *name, const char *access_method, const char *newname)
-{
- Oid opcOid;
- Oid amOid;
- Oid namespaceOid;
- HeapTuple origtup;
- HeapTuple tup;
- Relation rel;
- AclResult aclresult;
-
- amOid = get_am_oid(access_method, false);
-
- rel = heap_open(OperatorClassRelationId, RowExclusiveLock);
-
- /* Look up the opclass. */
- origtup = OpClassCacheLookup(amOid, name, false);
- tup = heap_copytuple(origtup);
- ReleaseSysCache(origtup);
- opcOid = HeapTupleGetOid(tup);
- namespaceOid = ((Form_pg_opclass) GETSTRUCT(tup))->opcnamespace;
-
- /* make sure the new name doesn't exist */
- if (SearchSysCacheExists3(CLAAMNAMENSP,
- ObjectIdGetDatum(amOid),
- CStringGetDatum(newname),
- ObjectIdGetDatum(namespaceOid)))
- {
- ereport(ERROR,
- (errcode(ERRCODE_DUPLICATE_OBJECT),
- errmsg("operator class \"%s\" for access method \"%s\" already exists in schema \"%s\"",
- newname, access_method,
- get_namespace_name(namespaceOid))));
- }
-
- /* must be owner */
- if (!pg_opclass_ownercheck(opcOid, GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPCLASS,
- NameListToString(name));
-
- /* must have CREATE privilege on namespace */
- aclresult = pg_namespace_aclcheck(namespaceOid, GetUserId(), ACL_CREATE);
- if (aclresult != ACLCHECK_OK)
- aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
- get_namespace_name(namespaceOid));
-
- /* rename */
- namestrcpy(&(((Form_pg_opclass) GETSTRUCT(tup))->opcname), newname);
- simple_heap_update(rel, &tup->t_self, tup);
- CatalogUpdateIndexes(rel, tup);
-
- heap_close(rel, NoLock);
- heap_freetuple(tup);
-}
-
-/*
- * Rename opfamily
- */
-void
-RenameOpFamily(List *name, const char *access_method, const char *newname)
-{
- Oid opfOid;
- Oid amOid;
- Oid namespaceOid;
- char *schemaname;
- char *opfname;
- HeapTuple tup;
- Relation rel;
- AclResult aclresult;
-
- amOid = get_am_oid(access_method, false);
-
- rel = heap_open(OperatorFamilyRelationId, RowExclusiveLock);
-
- /*
- * Look up the opfamily
- */
- DeconstructQualifiedName(name, &schemaname, &opfname);
-
- if (schemaname)
- {
- namespaceOid = LookupExplicitNamespace(schemaname);
-
- tup = SearchSysCacheCopy3(OPFAMILYAMNAMENSP,
- ObjectIdGetDatum(amOid),
- PointerGetDatum(opfname),
- ObjectIdGetDatum(namespaceOid));
- if (!HeapTupleIsValid(tup))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("operator family \"%s\" does not exist for access method \"%s\"",
- opfname, access_method)));
-
- opfOid = HeapTupleGetOid(tup);
- }
- else
- {
- opfOid = OpfamilynameGetOpfid(amOid, opfname);
- if (!OidIsValid(opfOid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("operator family \"%s\" does not exist for access method \"%s\"",
- opfname, access_method)));
-
- tup = SearchSysCacheCopy1(OPFAMILYOID, ObjectIdGetDatum(opfOid));
- if (!HeapTupleIsValid(tup)) /* should not happen */
- elog(ERROR, "cache lookup failed for opfamily %u", opfOid);
-
- namespaceOid = ((Form_pg_opfamily) GETSTRUCT(tup))->opfnamespace;
- }
-
- /* make sure the new name doesn't exist */
- if (SearchSysCacheExists3(OPFAMILYAMNAMENSP,
- ObjectIdGetDatum(amOid),
- CStringGetDatum(newname),
- ObjectIdGetDatum(namespaceOid)))
- {
- ereport(ERROR,
- (errcode(ERRCODE_DUPLICATE_OBJECT),
- errmsg("operator family \"%s\" for access method \"%s\" already exists in schema \"%s\"",
- newname, access_method,
- get_namespace_name(namespaceOid))));
- }
-
- /* must be owner */
- if (!pg_opfamily_ownercheck(opfOid, GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPFAMILY,
- NameListToString(name));
-
- /* must have CREATE privilege on namespace */
- aclresult = pg_namespace_aclcheck(namespaceOid, GetUserId(), ACL_CREATE);
- if (aclresult != ACLCHECK_OK)
- aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
- get_namespace_name(namespaceOid));
-
- /* rename */
- namestrcpy(&(((Form_pg_opfamily) GETSTRUCT(tup))->opfname), newname);
- simple_heap_update(rel, &tup->t_self, tup);
- CatalogUpdateIndexes(rel, tup);
-
- heap_close(rel, NoLock);
- heap_freetuple(tup);
-}
-
-/*
- * Change opclass owner by name
- */
-void
-AlterOpClassOwner(List *name, const char *access_method, Oid newOwnerId)
-{
- Oid amOid;
- Relation rel;
- HeapTuple tup;
- HeapTuple origtup;
-
- amOid = get_am_oid(access_method, false);
-
- rel = heap_open(OperatorClassRelationId, RowExclusiveLock);
-
- /* Look up the opclass. */
- origtup = OpClassCacheLookup(amOid, name, false);
- tup = heap_copytuple(origtup);
- ReleaseSysCache(origtup);
-
- AlterOpClassOwner_internal(rel, tup, newOwnerId);
-
- heap_freetuple(tup);
- heap_close(rel, NoLock);
-}
-
-/*
- * Change operator class owner, specified by OID
- */
-void
-AlterOpClassOwner_oid(Oid opclassOid, Oid newOwnerId)
-{
- HeapTuple tup;
- Relation rel;
-
- rel = heap_open(OperatorClassRelationId, RowExclusiveLock);
-
- tup = SearchSysCacheCopy1(CLAOID, ObjectIdGetDatum(opclassOid));
- if (!HeapTupleIsValid(tup))
- elog(ERROR, "cache lookup failed for opclass %u", opclassOid);
-
- AlterOpClassOwner_internal(rel, tup, newOwnerId);
-
- heap_freetuple(tup);
- heap_close(rel, NoLock);
-}
-
-/*
- * The first parameter is pg_opclass, opened and suitably locked. The second
- * parameter is a copy of the tuple from pg_opclass we want to modify.
- */
-static void
-AlterOpClassOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
-{
- Oid namespaceOid;
- AclResult aclresult;
- Form_pg_opclass opcForm;
-
- Assert(tup->t_tableOid == OperatorClassRelationId);
- Assert(RelationGetRelid(rel) == OperatorClassRelationId);
-
- opcForm = (Form_pg_opclass) GETSTRUCT(tup);
-
- namespaceOid = opcForm->opcnamespace;
-
- /*
- * If the new owner is the same as the existing owner, consider the
- * command to have succeeded. This is for dump restoration purposes.
- */
- if (opcForm->opcowner != newOwnerId)
- {
- /* Superusers can always do it */
- if (!superuser())
- {
- /* Otherwise, must be owner of the existing object */
- if (!pg_opclass_ownercheck(HeapTupleGetOid(tup), GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPCLASS,
- NameStr(opcForm->opcname));
-
- /* Must be able to become new owner */
- check_is_member_of_role(GetUserId(), newOwnerId);
-
- /* New owner must have CREATE privilege on namespace */
- aclresult = pg_namespace_aclcheck(namespaceOid, newOwnerId,
- ACL_CREATE);
- if (aclresult != ACLCHECK_OK)
- aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
- get_namespace_name(namespaceOid));
- }
-
- /*
- * Modify the owner --- okay to scribble on tup because it's a copy
- */
- opcForm->opcowner = newOwnerId;
-
- simple_heap_update(rel, &tup->t_self, tup);
-
- CatalogUpdateIndexes(rel, tup);
-
- /* Update owner dependency reference */
- changeDependencyOnOwner(OperatorClassRelationId, HeapTupleGetOid(tup),
- newOwnerId);
- }
-}
-
-/*
- * ALTER OPERATOR CLASS any_name USING access_method SET SCHEMA name
- */
-void
-AlterOpClassNamespace(List *name, char *access_method, const char *newschema)
-{
- Oid amOid;
- Relation rel;
- Oid opclassOid;
- Oid nspOid;
-
- amOid = get_am_oid(access_method, false);
-
- rel = heap_open(OperatorClassRelationId, RowExclusiveLock);
-
- /* Look up the opclass */
- opclassOid = get_opclass_oid(amOid, name, false);
-
- /* get schema OID */
- nspOid = LookupCreationNamespace(newschema);
-
- AlterObjectNamespace(rel, CLAOID, -1,
- opclassOid, nspOid,
- Anum_pg_opclass_opcname,
- Anum_pg_opclass_opcnamespace,
- Anum_pg_opclass_opcowner,
- ACL_KIND_OPCLASS);
-
- heap_close(rel, RowExclusiveLock);
-}
-
-Oid
-AlterOpClassNamespace_oid(Oid opclassOid, Oid newNspOid)
-{
- Oid oldNspOid;
- Relation rel;
-
- rel = heap_open(OperatorClassRelationId, RowExclusiveLock);
-
- oldNspOid =
- AlterObjectNamespace(rel, CLAOID, -1,
- opclassOid, newNspOid,
- Anum_pg_opclass_opcname,
- Anum_pg_opclass_opcnamespace,
- Anum_pg_opclass_opcowner,
- ACL_KIND_OPCLASS);
-
- heap_close(rel, RowExclusiveLock);
-
- return oldNspOid;
-}
-
-/*
- * Change opfamily owner by name
- */
-void
-AlterOpFamilyOwner(List *name, const char *access_method, Oid newOwnerId)
-{
- Oid amOid;
- Relation rel;
- HeapTuple tup;
- char *opfname;
- char *schemaname;
-
- amOid = get_am_oid(access_method, false);
-
- rel = heap_open(OperatorFamilyRelationId, RowExclusiveLock);
-
- /*
- * Look up the opfamily
- */
- DeconstructQualifiedName(name, &schemaname, &opfname);
-
- if (schemaname)
- {
- Oid namespaceOid;
-
- namespaceOid = LookupExplicitNamespace(schemaname);
-
- tup = SearchSysCacheCopy3(OPFAMILYAMNAMENSP,
- ObjectIdGetDatum(amOid),
- PointerGetDatum(opfname),
- ObjectIdGetDatum(namespaceOid));
- if (!HeapTupleIsValid(tup))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("operator family \"%s\" does not exist for access method \"%s\"",
- opfname, access_method)));
- }
- else
- {
- Oid opfOid;
-
- opfOid = OpfamilynameGetOpfid(amOid, opfname);
- if (!OidIsValid(opfOid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("operator family \"%s\" does not exist for access method \"%s\"",
- opfname, access_method)));
-
- tup = SearchSysCacheCopy1(OPFAMILYOID, ObjectIdGetDatum(opfOid));
- if (!HeapTupleIsValid(tup)) /* should not happen */
- elog(ERROR, "cache lookup failed for opfamily %u", opfOid);
- }
-
- AlterOpFamilyOwner_internal(rel, tup, newOwnerId);
-
- heap_freetuple(tup);
- heap_close(rel, NoLock);
-}
-
-/*
- * Change operator family owner, specified by OID
- */
-void
-AlterOpFamilyOwner_oid(Oid opfamilyOid, Oid newOwnerId)
-{
- HeapTuple tup;
- Relation rel;
-
- rel = heap_open(OperatorFamilyRelationId, RowExclusiveLock);
-
- tup = SearchSysCacheCopy1(OPFAMILYOID, ObjectIdGetDatum(opfamilyOid));
- if (!HeapTupleIsValid(tup))
- elog(ERROR, "cache lookup failed for opfamily %u", opfamilyOid);
-
- AlterOpFamilyOwner_internal(rel, tup, newOwnerId);
-
- heap_freetuple(tup);
- heap_close(rel, NoLock);
-}
-
-/*
- * The first parameter is pg_opfamily, opened and suitably locked. The second
- * parameter is a copy of the tuple from pg_opfamily we want to modify.
- */
-static void
-AlterOpFamilyOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
-{
- Oid namespaceOid;
- AclResult aclresult;
- Form_pg_opfamily opfForm;
-
- Assert(tup->t_tableOid == OperatorFamilyRelationId);
- Assert(RelationGetRelid(rel) == OperatorFamilyRelationId);
-
- opfForm = (Form_pg_opfamily) GETSTRUCT(tup);
-
- namespaceOid = opfForm->opfnamespace;
-
- /*
- * If the new owner is the same as the existing owner, consider the
- * command to have succeeded. This is for dump restoration purposes.
- */
- if (opfForm->opfowner != newOwnerId)
- {
- /* Superusers can always do it */
- if (!superuser())
- {
- /* Otherwise, must be owner of the existing object */
- if (!pg_opfamily_ownercheck(HeapTupleGetOid(tup), GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPFAMILY,
- NameStr(opfForm->opfname));
-
- /* Must be able to become new owner */
- check_is_member_of_role(GetUserId(), newOwnerId);
-
- /* New owner must have CREATE privilege on namespace */
- aclresult = pg_namespace_aclcheck(namespaceOid, newOwnerId,
- ACL_CREATE);
- if (aclresult != ACLCHECK_OK)
- aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
- get_namespace_name(namespaceOid));
- }
-
- /*
- * Modify the owner --- okay to scribble on tup because it's a copy
- */
- opfForm->opfowner = newOwnerId;
-
- simple_heap_update(rel, &tup->t_self, tup);
-
- CatalogUpdateIndexes(rel, tup);
-
- /* Update owner dependency reference */
- changeDependencyOnOwner(OperatorFamilyRelationId, HeapTupleGetOid(tup),
- newOwnerId);
- }
-}
-
/*
* get_am_oid - given an access method name, look up the OID
*
@@ -2121,55 +1673,3 @@ get_am_oid(const char *amname, bool missing_ok)
errmsg("access method \"%s\" does not exist", amname)));
return oid;
}
-
-/*
- * ALTER OPERATOR FAMILY any_name USING access_method SET SCHEMA name
- */
-void
-AlterOpFamilyNamespace(List *name, char *access_method, const char *newschema)
-{
- Oid amOid;
- Relation rel;
- Oid opfamilyOid;
- Oid nspOid;
-
- amOid = get_am_oid(access_method, false);
-
- rel = heap_open(OperatorFamilyRelationId, RowExclusiveLock);
-
- /* Look up the opfamily */
- opfamilyOid = get_opfamily_oid(amOid, name, false);
-
- /* get schema OID */
- nspOid = LookupCreationNamespace(newschema);
-
- AlterObjectNamespace(rel, OPFAMILYOID, -1,
- opfamilyOid, nspOid,
- Anum_pg_opfamily_opfname,
- Anum_pg_opfamily_opfnamespace,
- Anum_pg_opfamily_opfowner,
- ACL_KIND_OPFAMILY);
-
- heap_close(rel, RowExclusiveLock);
-}
-
-Oid
-AlterOpFamilyNamespace_oid(Oid opfamilyOid, Oid newNspOid)
-{
- Oid oldNspOid;
- Relation rel;
-
- rel = heap_open(OperatorFamilyRelationId, RowExclusiveLock);
-
- oldNspOid =
- AlterObjectNamespace(rel, OPFAMILYOID, -1,
- opfamilyOid, newNspOid,
- Anum_pg_opfamily_opfname,
- Anum_pg_opfamily_opfnamespace,
- Anum_pg_opfamily_opfowner,
- ACL_KIND_OPFAMILY);
-
- heap_close(rel, RowExclusiveLock);
-
- return oldNspOid;
-}
diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c
index 410c708..16f66c4 100644
--- a/src/backend/commands/operatorcmds.c
+++ b/src/backend/commands/operatorcmds.c
@@ -50,9 +50,6 @@
#include "utils/rel.h"
#include "utils/syscache.h"
-
-static void AlterOperatorOwner_internal(Relation rel, Oid operOid, Oid newOwnerId);
-
/*
* DefineOperator
* this function extracts all the information from the
@@ -332,146 +329,3 @@ RemoveOperatorById(Oid operOid)
heap_close(relation, RowExclusiveLock);
}
-
-void
-AlterOperatorOwner_oid(Oid operOid, Oid newOwnerId)
-{
- Relation rel;
-
- rel = heap_open(OperatorRelationId, RowExclusiveLock);
-
- AlterOperatorOwner_internal(rel, operOid, newOwnerId);
-
- heap_close(rel, NoLock);
-}
-
-/*
- * change operator owner
- */
-void
-AlterOperatorOwner(List *name, TypeName *typeName1, TypeName *typeName2,
- Oid newOwnerId)
-{
- Oid operOid;
- Relation rel;
-
- rel = heap_open(OperatorRelationId, RowExclusiveLock);
-
- operOid = LookupOperNameTypeNames(NULL, name,
- typeName1, typeName2,
- false, -1);
-
- AlterOperatorOwner_internal(rel, operOid, newOwnerId);
-
- heap_close(rel, NoLock);
-}
-
-static void
-AlterOperatorOwner_internal(Relation rel, Oid operOid, Oid newOwnerId)
-{
- HeapTuple tup;
- AclResult aclresult;
- Form_pg_operator oprForm;
-
- Assert(RelationGetRelid(rel) == OperatorRelationId);
-
- tup = SearchSysCacheCopy1(OPEROID, ObjectIdGetDatum(operOid));
- if (!HeapTupleIsValid(tup)) /* should not happen */
- elog(ERROR, "cache lookup failed for operator %u", operOid);
-
- oprForm = (Form_pg_operator) GETSTRUCT(tup);
-
- /*
- * If the new owner is the same as the existing owner, consider the
- * command to have succeeded. This is for dump restoration purposes.
- */
- if (oprForm->oprowner != newOwnerId)
- {
- /* Superusers can always do it */
- if (!superuser())
- {
- /* Otherwise, must be owner of the existing object */
- if (!pg_oper_ownercheck(operOid, GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPER,
- NameStr(oprForm->oprname));
-
- /* Must be able to become new owner */
- check_is_member_of_role(GetUserId(), newOwnerId);
-
- /* New owner must have CREATE privilege on namespace */
- aclresult = pg_namespace_aclcheck(oprForm->oprnamespace,
- newOwnerId,
- ACL_CREATE);
- if (aclresult != ACLCHECK_OK)
- aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
- get_namespace_name(oprForm->oprnamespace));
- }
-
- /*
- * Modify the owner --- okay to scribble on tup because it's a copy
- */
- oprForm->oprowner = newOwnerId;
-
- simple_heap_update(rel, &tup->t_self, tup);
-
- CatalogUpdateIndexes(rel, tup);
-
- /* Update owner dependency reference */
- changeDependencyOnOwner(OperatorRelationId, operOid, newOwnerId);
- }
-
- heap_freetuple(tup);
-}
-
-/*
- * Execute ALTER OPERATOR SET SCHEMA
- */
-void
-AlterOperatorNamespace(List *names, List *argtypes, const char *newschema)
-{
- List *operatorName = names;
- TypeName *typeName1 = (TypeName *) linitial(argtypes);
- TypeName *typeName2 = (TypeName *) lsecond(argtypes);
- Oid operOid,
- nspOid;
- Relation rel;
-
- rel = heap_open(OperatorRelationId, RowExclusiveLock);
-
- Assert(list_length(argtypes) == 2);
- operOid = LookupOperNameTypeNames(NULL, operatorName,
- typeName1, typeName2,
- false, -1);
-
- /* get schema OID */
- nspOid = LookupCreationNamespace(newschema);
-
- AlterObjectNamespace(rel, OPEROID, -1,
- operOid, nspOid,
- Anum_pg_operator_oprname,
- Anum_pg_operator_oprnamespace,
- Anum_pg_operator_oprowner,
- ACL_KIND_OPER);
-
- heap_close(rel, RowExclusiveLock);
-}
-
-Oid
-AlterOperatorNamespace_oid(Oid operOid, Oid newNspOid)
-{
- Oid oldNspOid;
- Relation rel;
-
- rel = heap_open(OperatorRelationId, RowExclusiveLock);
-
- oldNspOid = AlterObjectNamespace(rel, OPEROID, -1,
- operOid, newNspOid,
- Anum_pg_operator_oprname,
- Anum_pg_operator_oprnamespace,
- Anum_pg_operator_oprowner,
- ACL_KIND_OPER);
-
- heap_close(rel, RowExclusiveLock);
-
- return oldNspOid;
-}
diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c
index 354389c..9d28588 100644
--- a/src/backend/commands/proclang.c
+++ b/src/backend/commands/proclang.c
@@ -54,9 +54,6 @@ static void create_proc_lang(const char *languageName, bool replace,
Oid languageOwner, Oid handlerOid, Oid inlineOid,
Oid valOid, bool trusted);
static PLTemplate *find_language_template(const char *languageName);
-static void AlterLanguageOwner_internal(HeapTuple tup, Relation rel,
- Oid newOwnerId);
-
/* ---------------------------------------------------------------------
* CREATE PROCEDURAL LANGUAGE
@@ -537,157 +534,6 @@ DropProceduralLanguageById(Oid langOid)
}
/*
- * Rename language
- */
-void
-RenameLanguage(const char *oldname, const char *newname)
-{
- HeapTuple tup;
- Relation rel;
-
- rel = heap_open(LanguageRelationId, RowExclusiveLock);
-
- tup = SearchSysCacheCopy1(LANGNAME, CStringGetDatum(oldname));
- if (!HeapTupleIsValid(tup))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("language \"%s\" does not exist", oldname)));
-
- /* make sure the new name doesn't exist */
- if (SearchSysCacheExists1(LANGNAME, CStringGetDatum(newname)))
- ereport(ERROR,
- (errcode(ERRCODE_DUPLICATE_OBJECT),
- errmsg("language \"%s\" already exists", newname)));
-
- /* must be owner of PL */
- if (!pg_language_ownercheck(HeapTupleGetOid(tup), GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_LANGUAGE,
- oldname);
-
- /* rename */
- namestrcpy(&(((Form_pg_language) GETSTRUCT(tup))->lanname), newname);
- simple_heap_update(rel, &tup->t_self, tup);
- CatalogUpdateIndexes(rel, tup);
-
- heap_close(rel, NoLock);
- heap_freetuple(tup);
-}
-
-/*
- * Change language owner
- */
-void
-AlterLanguageOwner(const char *name, Oid newOwnerId)
-{
- HeapTuple tup;
- Relation rel;
-
- rel = heap_open(LanguageRelationId, RowExclusiveLock);
-
- tup = SearchSysCache1(LANGNAME, CStringGetDatum(name));
- if (!HeapTupleIsValid(tup))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("language \"%s\" does not exist", name)));
-
- AlterLanguageOwner_internal(tup, rel, newOwnerId);
-
- ReleaseSysCache(tup);
-
- heap_close(rel, RowExclusiveLock);
-
-}
-
-/*
- * Change language owner, specified by OID
- */
-void
-AlterLanguageOwner_oid(Oid oid, Oid newOwnerId)
-{
- HeapTuple tup;
- Relation rel;
-
- rel = heap_open(LanguageRelationId, RowExclusiveLock);
-
- tup = SearchSysCache1(LANGOID, ObjectIdGetDatum(oid));
- if (!HeapTupleIsValid(tup))
- elog(ERROR, "cache lookup failed for language %u", oid);
-
- AlterLanguageOwner_internal(tup, rel, newOwnerId);
-
- ReleaseSysCache(tup);
-
- heap_close(rel, RowExclusiveLock);
-}
-
-/*
- * Workhorse for AlterLanguageOwner variants
- */
-static void
-AlterLanguageOwner_internal(HeapTuple tup, Relation rel, Oid newOwnerId)
-{
- Form_pg_language lanForm;
-
- lanForm = (Form_pg_language) GETSTRUCT(tup);
-
- /*
- * If the new owner is the same as the existing owner, consider the
- * command to have succeeded. This is for dump restoration purposes.
- */
- if (lanForm->lanowner != newOwnerId)
- {
- Datum repl_val[Natts_pg_language];
- bool repl_null[Natts_pg_language];
- bool repl_repl[Natts_pg_language];
- Acl *newAcl;
- Datum aclDatum;
- bool isNull;
- HeapTuple newtuple;
-
- /* Otherwise, must be owner of the existing object */
- if (!pg_language_ownercheck(HeapTupleGetOid(tup), GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_LANGUAGE,
- NameStr(lanForm->lanname));
-
- /* Must be able to become new owner */
- check_is_member_of_role(GetUserId(), newOwnerId);
-
- memset(repl_null, false, sizeof(repl_null));
- memset(repl_repl, false, sizeof(repl_repl));
-
- repl_repl[Anum_pg_language_lanowner - 1] = true;
- repl_val[Anum_pg_language_lanowner - 1] = ObjectIdGetDatum(newOwnerId);
-
- /*
- * Determine the modified ACL for the new owner. This is only
- * necessary when the ACL is non-null.
- */
- aclDatum = SysCacheGetAttr(LANGNAME, tup,
- Anum_pg_language_lanacl,
- &isNull);
- if (!isNull)
- {
- newAcl = aclnewowner(DatumGetAclP(aclDatum),
- lanForm->lanowner, newOwnerId);
- repl_repl[Anum_pg_language_lanacl - 1] = true;
- repl_val[Anum_pg_language_lanacl - 1] = PointerGetDatum(newAcl);
- }
-
- newtuple = heap_modify_tuple(tup, RelationGetDescr(rel),
- repl_val, repl_null, repl_repl);
-
- simple_heap_update(rel, &newtuple->t_self, newtuple);
- CatalogUpdateIndexes(rel, newtuple);
-
- heap_freetuple(newtuple);
-
- /* Update owner dependency reference */
- changeDependencyOnOwner(LanguageRelationId, HeapTupleGetOid(tup),
- newOwnerId);
- }
-}
-
-/*
* get_language_oid - given a language name, look up the OID
*
* If missing_ok is false, throw an error if language name not found. If
diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c
index da9cb2f..75ed118 100644
--- a/src/backend/commands/tablespace.c
+++ b/src/backend/commands/tablespace.c
@@ -883,105 +883,6 @@ RenameTableSpace(const char *oldname, const char *newname)
}
/*
- * Change tablespace owner
- */
-void
-AlterTableSpaceOwner(const char *name, Oid newOwnerId)
-{
- Relation rel;
- ScanKeyData entry[1];
- HeapScanDesc scandesc;
- Form_pg_tablespace spcForm;
- HeapTuple tup;
-
- /* Search pg_tablespace */
- rel = heap_open(TableSpaceRelationId, RowExclusiveLock);
-
- ScanKeyInit(&entry[0],
- Anum_pg_tablespace_spcname,
- BTEqualStrategyNumber, F_NAMEEQ,
- CStringGetDatum(name));
- scandesc = heap_beginscan(rel, SnapshotNow, 1, entry);
- tup = heap_getnext(scandesc, ForwardScanDirection);
- if (!HeapTupleIsValid(tup))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace \"%s\" does not exist", name)));
-
- spcForm = (Form_pg_tablespace) GETSTRUCT(tup);
-
- /*
- * If the new owner is the same as the existing owner, consider the
- * command to have succeeded. This is for dump restoration purposes.
- */
- if (spcForm->spcowner != newOwnerId)
- {
- Datum repl_val[Natts_pg_tablespace];
- bool repl_null[Natts_pg_tablespace];
- bool repl_repl[Natts_pg_tablespace];
- Acl *newAcl;
- Datum aclDatum;
- bool isNull;
- HeapTuple newtuple;
-
- /* Otherwise, must be owner of the existing object */
- if (!pg_tablespace_ownercheck(HeapTupleGetOid(tup), GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TABLESPACE,
- name);
-
- /* Must be able to become new owner */
- check_is_member_of_role(GetUserId(), newOwnerId);
-
- /*
- * Normally we would also check for create permissions here, but there
- * are none for tablespaces so we follow what rename tablespace does
- * and omit the create permissions check.
- *
- * NOTE: Only superusers may create tablespaces to begin with and so
- * initially only a superuser would be able to change its ownership
- * anyway.
- */
-
- memset(repl_null, false, sizeof(repl_null));
- memset(repl_repl, false, sizeof(repl_repl));
-
- repl_repl[Anum_pg_tablespace_spcowner - 1] = true;
- repl_val[Anum_pg_tablespace_spcowner - 1] = ObjectIdGetDatum(newOwnerId);
-
- /*
- * Determine the modified ACL for the new owner. This is only
- * necessary when the ACL is non-null.
- */
- aclDatum = heap_getattr(tup,
- Anum_pg_tablespace_spcacl,
- RelationGetDescr(rel),
- &isNull);
- if (!isNull)
- {
- newAcl = aclnewowner(DatumGetAclP(aclDatum),
- spcForm->spcowner, newOwnerId);
- repl_repl[Anum_pg_tablespace_spcacl - 1] = true;
- repl_val[Anum_pg_tablespace_spcacl - 1] = PointerGetDatum(newAcl);
- }
-
- newtuple = heap_modify_tuple(tup, RelationGetDescr(rel), repl_val, repl_null, repl_repl);
-
- simple_heap_update(rel, &newtuple->t_self, newtuple);
- CatalogUpdateIndexes(rel, newtuple);
-
- heap_freetuple(newtuple);
-
- /* Update owner dependency reference */
- changeDependencyOnOwner(TableSpaceRelationId, HeapTupleGetOid(tup),
- newOwnerId);
- }
-
- heap_endscan(scandesc);
- heap_close(rel, NoLock);
-}
-
-
-/*
* Alter table space options
*/
void
diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c
index 86cb870..2f3d7b5 100644
--- a/src/backend/commands/tsearchcmds.c
+++ b/src/backend/commands/tsearchcmds.c
@@ -302,95 +302,6 @@ RemoveTSParserById(Oid prsId)
heap_close(relation, RowExclusiveLock);
}
-/*
- * ALTER TEXT SEARCH PARSER RENAME
- */
-void
-RenameTSParser(List *oldname, const char *newname)
-{
- HeapTuple tup;
- Relation rel;
- Oid prsId;
- Oid namespaceOid;
-
- if (!superuser())
- ereport(ERROR,
- (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- errmsg("must be superuser to rename text search parsers")));
-
- rel = heap_open(TSParserRelationId, RowExclusiveLock);
-
- prsId = get_ts_parser_oid(oldname, false);
-
- tup = SearchSysCacheCopy1(TSPARSEROID, ObjectIdGetDatum(prsId));
-
- if (!HeapTupleIsValid(tup)) /* should not happen */
- elog(ERROR, "cache lookup failed for text search parser %u", prsId);
-
- namespaceOid = ((Form_pg_ts_parser) GETSTRUCT(tup))->prsnamespace;
-
- if (SearchSysCacheExists2(TSPARSERNAMENSP,
- PointerGetDatum(newname),
- ObjectIdGetDatum(namespaceOid)))
- ereport(ERROR,
- (errcode(ERRCODE_DUPLICATE_OBJECT),
- errmsg("text search parser \"%s\" already exists",
- newname)));
-
- namestrcpy(&(((Form_pg_ts_parser) GETSTRUCT(tup))->prsname), newname);
- simple_heap_update(rel, &tup->t_self, tup);
- CatalogUpdateIndexes(rel, tup);
-
- heap_close(rel, NoLock);
- heap_freetuple(tup);
-}
-
-/*
- * ALTER TEXT SEARCH PARSER any_name SET SCHEMA name
- */
-void
-AlterTSParserNamespace(List *name, const char *newschema)
-{
- Oid prsId,
- nspOid;
- Relation rel;
-
- rel = heap_open(TSParserRelationId, RowExclusiveLock);
-
- prsId = get_ts_parser_oid(name, false);
-
- /* get schema OID */
- nspOid = LookupCreationNamespace(newschema);
-
- AlterObjectNamespace(rel, TSPARSEROID, TSPARSERNAMENSP,
- prsId, nspOid,
- Anum_pg_ts_parser_prsname,
- Anum_pg_ts_parser_prsnamespace,
- -1, -1);
-
- heap_close(rel, RowExclusiveLock);
-}
-
-Oid
-AlterTSParserNamespace_oid(Oid prsId, Oid newNspOid)
-{
- Oid oldNspOid;
- Relation rel;
-
- rel = heap_open(TSParserRelationId, RowExclusiveLock);
-
- oldNspOid =
- AlterObjectNamespace(rel, TSPARSEROID, TSPARSERNAMENSP,
- prsId, newNspOid,
- Anum_pg_ts_parser_prsname,
- Anum_pg_ts_parser_prsnamespace,
- -1, -1);
-
- heap_close(rel, RowExclusiveLock);
-
- return oldNspOid;
-}
-
/* ---------------------- TS Dictionary commands -----------------------*/
/*
@@ -574,105 +485,6 @@ DefineTSDictionary(List *names, List *parameters)
}
/*
- * ALTER TEXT SEARCH DICTIONARY RENAME
- */
-void
-RenameTSDictionary(List *oldname, const char *newname)
-{
- HeapTuple tup;
- Relation rel;
- Oid dictId;
- Oid namespaceOid;
- AclResult aclresult;
-
- rel = heap_open(TSDictionaryRelationId, RowExclusiveLock);
-
- dictId = get_ts_dict_oid(oldname, false);
-
- tup = SearchSysCacheCopy1(TSDICTOID, ObjectIdGetDatum(dictId));
-
- if (!HeapTupleIsValid(tup)) /* should not happen */
- elog(ERROR, "cache lookup failed for text search dictionary %u",
- dictId);
-
- namespaceOid = ((Form_pg_ts_dict) GETSTRUCT(tup))->dictnamespace;
-
- if (SearchSysCacheExists2(TSDICTNAMENSP,
- PointerGetDatum(newname),
- ObjectIdGetDatum(namespaceOid)))
- ereport(ERROR,
- (errcode(ERRCODE_DUPLICATE_OBJECT),
- errmsg("text search dictionary \"%s\" already exists",
- newname)));
-
- /* must be owner */
- if (!pg_ts_dict_ownercheck(dictId, GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSDICTIONARY,
- NameListToString(oldname));
-
- /* must have CREATE privilege on namespace */
- aclresult = pg_namespace_aclcheck(namespaceOid, GetUserId(), ACL_CREATE);
- if (aclresult != ACLCHECK_OK)
- aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
- get_namespace_name(namespaceOid));
-
- namestrcpy(&(((Form_pg_ts_dict) GETSTRUCT(tup))->dictname), newname);
- simple_heap_update(rel, &tup->t_self, tup);
- CatalogUpdateIndexes(rel, tup);
-
- heap_close(rel, NoLock);
- heap_freetuple(tup);
-}
-
-/*
- * ALTER TEXT SEARCH DICTIONARY any_name SET SCHEMA name
- */
-void
-AlterTSDictionaryNamespace(List *name, const char *newschema)
-{
- Oid dictId,
- nspOid;
- Relation rel;
-
- rel = heap_open(TSDictionaryRelationId, RowExclusiveLock);
-
- dictId = get_ts_dict_oid(name, false);
-
- /* get schema OID */
- nspOid = LookupCreationNamespace(newschema);
-
- AlterObjectNamespace(rel, TSDICTOID, TSDICTNAMENSP,
- dictId, nspOid,
- Anum_pg_ts_dict_dictname,
- Anum_pg_ts_dict_dictnamespace,
- Anum_pg_ts_dict_dictowner,
- ACL_KIND_TSDICTIONARY);
-
- heap_close(rel, RowExclusiveLock);
-}
-
-Oid
-AlterTSDictionaryNamespace_oid(Oid dictId, Oid newNspOid)
-{
- Oid oldNspOid;
- Relation rel;
-
- rel = heap_open(TSDictionaryRelationId, RowExclusiveLock);
-
- oldNspOid =
- AlterObjectNamespace(rel, TSDICTOID, TSDICTNAMENSP,
- dictId, newNspOid,
- Anum_pg_ts_dict_dictname,
- Anum_pg_ts_dict_dictnamespace,
- Anum_pg_ts_dict_dictowner,
- ACL_KIND_TSDICTIONARY);
-
- heap_close(rel, RowExclusiveLock);
-
- return oldNspOid;
-}
-
-/*
* Guts of TS dictionary deletion.
*/
void
@@ -809,66 +621,6 @@ AlterTSDictionary(AlterTSDictionaryStmt *stmt)
heap_close(rel, RowExclusiveLock);
}
-/*
- * ALTER TEXT SEARCH DICTIONARY OWNER
- */
-void
-AlterTSDictionaryOwner(List *name, Oid newOwnerId)
-{
- HeapTuple tup;
- Relation rel;
- Oid dictId;
- Oid namespaceOid;
- AclResult aclresult;
- Form_pg_ts_dict form;
-
- rel = heap_open(TSDictionaryRelationId, RowExclusiveLock);
-
- dictId = get_ts_dict_oid(name, false);
-
- tup = SearchSysCacheCopy1(TSDICTOID, ObjectIdGetDatum(dictId));
-
- if (!HeapTupleIsValid(tup)) /* should not happen */
- elog(ERROR, "cache lookup failed for text search dictionary %u",
- dictId);
-
- form = (Form_pg_ts_dict) GETSTRUCT(tup);
- namespaceOid = form->dictnamespace;
-
- if (form->dictowner != newOwnerId)
- {
- /* Superusers can always do it */
- if (!superuser())
- {
- /* must be owner */
- if (!pg_ts_dict_ownercheck(dictId, GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSDICTIONARY,
- NameListToString(name));
-
- /* Must be able to become new owner */
- check_is_member_of_role(GetUserId(), newOwnerId);
-
- /* New owner must have CREATE privilege on namespace */
- aclresult = pg_namespace_aclcheck(namespaceOid, newOwnerId, ACL_CREATE);
- if (aclresult != ACLCHECK_OK)
- aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
- get_namespace_name(namespaceOid));
- }
-
- form->dictowner = newOwnerId;
-
- simple_heap_update(rel, &tup->t_self, tup);
- CatalogUpdateIndexes(rel, tup);
-
- /* Update owner dependency reference */
- changeDependencyOnOwner(TSDictionaryRelationId, HeapTupleGetOid(tup),
- newOwnerId);
- }
-
- heap_close(rel, NoLock);
- heap_freetuple(tup);
-}
-
/* ---------------------- TS Template commands -----------------------*/
/*
@@ -1046,96 +798,6 @@ DefineTSTemplate(List *names, List *parameters)
}
/*
- * ALTER TEXT SEARCH TEMPLATE RENAME
- */
-void
-RenameTSTemplate(List *oldname, const char *newname)
-{
- HeapTuple tup;
- Relation rel;
- Oid tmplId;
- Oid namespaceOid;
-
- if (!superuser())
- ereport(ERROR,
- (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- errmsg("must be superuser to rename text search templates")));
-
- rel = heap_open(TSTemplateRelationId, RowExclusiveLock);
-
- tmplId = get_ts_template_oid(oldname, false);
-
- tup = SearchSysCacheCopy1(TSTEMPLATEOID, ObjectIdGetDatum(tmplId));
-
- if (!HeapTupleIsValid(tup)) /* should not happen */
- elog(ERROR, "cache lookup failed for text search template %u",
- tmplId);
-
- namespaceOid = ((Form_pg_ts_template) GETSTRUCT(tup))->tmplnamespace;
-
- if (SearchSysCacheExists2(TSTEMPLATENAMENSP,
- PointerGetDatum(newname),
- ObjectIdGetDatum(namespaceOid)))
- ereport(ERROR,
- (errcode(ERRCODE_DUPLICATE_OBJECT),
- errmsg("text search template \"%s\" already exists",
- newname)));
-
- namestrcpy(&(((Form_pg_ts_template) GETSTRUCT(tup))->tmplname), newname);
- simple_heap_update(rel, &tup->t_self, tup);
- CatalogUpdateIndexes(rel, tup);
-
- heap_close(rel, NoLock);
- heap_freetuple(tup);
-}
-
-/*
- * ALTER TEXT SEARCH TEMPLATE any_name SET SCHEMA name
- */
-void
-AlterTSTemplateNamespace(List *name, const char *newschema)
-{
- Oid tmplId,
- nspOid;
- Relation rel;
-
- rel = heap_open(TSTemplateRelationId, RowExclusiveLock);
-
- tmplId = get_ts_template_oid(name, false);
-
- /* get schema OID */
- nspOid = LookupCreationNamespace(newschema);
-
- AlterObjectNamespace(rel, TSTEMPLATEOID, TSTEMPLATENAMENSP,
- tmplId, nspOid,
- Anum_pg_ts_template_tmplname,
- Anum_pg_ts_template_tmplnamespace,
- -1, -1);
-
- heap_close(rel, RowExclusiveLock);
-}
-
-Oid
-AlterTSTemplateNamespace_oid(Oid tmplId, Oid newNspOid)
-{
- Oid oldNspOid;
- Relation rel;
-
- rel = heap_open(TSTemplateRelationId, RowExclusiveLock);
-
- oldNspOid =
- AlterObjectNamespace(rel, TSTEMPLATEOID, TSTEMPLATENAMENSP,
- tmplId, newNspOid,
- Anum_pg_ts_template_tmplname,
- Anum_pg_ts_template_tmplnamespace,
- -1, -1);
-
- heap_close(rel, RowExclusiveLock);
-
- return oldNspOid;
-}
-
-/*
* Guts of TS template deletion.
*/
void
@@ -1432,104 +1094,6 @@ DefineTSConfiguration(List *names, List *parameters)
}
/*
- * ALTER TEXT SEARCH CONFIGURATION RENAME
- */
-void
-RenameTSConfiguration(List *oldname, const char *newname)
-{
- HeapTuple tup;
- Relation rel;
- Oid cfgId;
- AclResult aclresult;
- Oid namespaceOid;
-
- rel = heap_open(TSConfigRelationId, RowExclusiveLock);
-
- cfgId = get_ts_config_oid(oldname, false);
-
- tup = SearchSysCacheCopy1(TSCONFIGOID, ObjectIdGetDatum(cfgId));
-
- if (!HeapTupleIsValid(tup)) /* should not happen */
- elog(ERROR, "cache lookup failed for text search configuration %u",
- cfgId);
-
- namespaceOid = ((Form_pg_ts_config) GETSTRUCT(tup))->cfgnamespace;
-
- if (SearchSysCacheExists2(TSCONFIGNAMENSP,
- PointerGetDatum(newname),
- ObjectIdGetDatum(namespaceOid)))
- ereport(ERROR,
- (errcode(ERRCODE_DUPLICATE_OBJECT),
- errmsg("text search configuration \"%s\" already exists",
- newname)));
-
- /* must be owner */
- if (!pg_ts_config_ownercheck(cfgId, GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSCONFIGURATION,
- NameListToString(oldname));
-
- /* must have CREATE privilege on namespace */
- aclresult = pg_namespace_aclcheck(namespaceOid, GetUserId(), ACL_CREATE);
- aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
- get_namespace_name(namespaceOid));
-
- namestrcpy(&(((Form_pg_ts_config) GETSTRUCT(tup))->cfgname), newname);
- simple_heap_update(rel, &tup->t_self, tup);
- CatalogUpdateIndexes(rel, tup);
-
- heap_close(rel, NoLock);
- heap_freetuple(tup);
-}
-
-/*
- * ALTER TEXT SEARCH CONFIGURATION any_name SET SCHEMA name
- */
-void
-AlterTSConfigurationNamespace(List *name, const char *newschema)
-{
- Oid cfgId,
- nspOid;
- Relation rel;
-
- rel = heap_open(TSConfigRelationId, RowExclusiveLock);
-
- cfgId = get_ts_config_oid(name, false);
-
- /* get schema OID */
- nspOid = LookupCreationNamespace(newschema);
-
- AlterObjectNamespace(rel, TSCONFIGOID, TSCONFIGNAMENSP,
- cfgId, nspOid,
- Anum_pg_ts_config_cfgname,
- Anum_pg_ts_config_cfgnamespace,
- Anum_pg_ts_config_cfgowner,
- ACL_KIND_TSCONFIGURATION);
-
- heap_close(rel, RowExclusiveLock);
-}
-
-Oid
-AlterTSConfigurationNamespace_oid(Oid cfgId, Oid newNspOid)
-{
- Oid oldNspOid;
- Relation rel;
-
- rel = heap_open(TSConfigRelationId, RowExclusiveLock);
-
- oldNspOid =
- AlterObjectNamespace(rel, TSCONFIGOID, TSCONFIGNAMENSP,
- cfgId, newNspOid,
- Anum_pg_ts_config_cfgname,
- Anum_pg_ts_config_cfgnamespace,
- Anum_pg_ts_config_cfgowner,
- ACL_KIND_TSCONFIGURATION);
-
- heap_close(rel, RowExclusiveLock);
-
- return oldNspOid;
-}
-
-/*
* Guts of TS configuration deletion.
*/
void
@@ -1578,66 +1142,6 @@ RemoveTSConfigurationById(Oid cfgId)
}
/*
- * ALTER TEXT SEARCH CONFIGURATION OWNER
- */
-void
-AlterTSConfigurationOwner(List *name, Oid newOwnerId)
-{
- HeapTuple tup;
- Relation rel;
- Oid cfgId;
- AclResult aclresult;
- Oid namespaceOid;
- Form_pg_ts_config form;
-
- rel = heap_open(TSConfigRelationId, RowExclusiveLock);
-
- cfgId = get_ts_config_oid(name, false);
-
- tup = SearchSysCacheCopy1(TSCONFIGOID, ObjectIdGetDatum(cfgId));
-
- if (!HeapTupleIsValid(tup)) /* should not happen */
- elog(ERROR, "cache lookup failed for text search configuration %u",
- cfgId);
-
- form = (Form_pg_ts_config) GETSTRUCT(tup);
- namespaceOid = form->cfgnamespace;
-
- if (form->cfgowner != newOwnerId)
- {
- /* Superusers can always do it */
- if (!superuser())
- {
- /* must be owner */
- if (!pg_ts_config_ownercheck(cfgId, GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSCONFIGURATION,
- NameListToString(name));
-
- /* Must be able to become new owner */
- check_is_member_of_role(GetUserId(), newOwnerId);
-
- /* New owner must have CREATE privilege on namespace */
- aclresult = pg_namespace_aclcheck(namespaceOid, newOwnerId, ACL_CREATE);
- if (aclresult != ACLCHECK_OK)
- aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
- get_namespace_name(namespaceOid));
- }
-
- form->cfgowner = newOwnerId;
-
- simple_heap_update(rel, &tup->t_self, tup);
- CatalogUpdateIndexes(rel, tup);
-
- /* Update owner dependency reference */
- changeDependencyOnOwner(TSConfigRelationId, HeapTupleGetOid(tup),
- newOwnerId);
- }
-
- heap_close(rel, NoLock);
- heap_freetuple(tup);
-}
-
-/*
* ALTER TEXT SEARCH CONFIGURATION - main entry point
*/
void
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 1743b8f..22425b7 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -2914,7 +2914,6 @@ _copyAlterObjectSchemaStmt(const AlterObjectSchemaStmt *from)
COPY_NODE_FIELD(relation);
COPY_NODE_FIELD(object);
COPY_NODE_FIELD(objarg);
- COPY_STRING_FIELD(addname);
COPY_STRING_FIELD(newschema);
COPY_SCALAR_FIELD(missing_ok);
@@ -2930,7 +2929,6 @@ _copyAlterOwnerStmt(const AlterOwnerStmt *from)
COPY_NODE_FIELD(relation);
COPY_NODE_FIELD(object);
COPY_NODE_FIELD(objarg);
- COPY_STRING_FIELD(addname);
COPY_STRING_FIELD(newowner);
return newnode;
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index f19ad77..a3c8158 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -1326,7 +1326,6 @@ _equalAlterObjectSchemaStmt(const AlterObjectSchemaStmt *a, const AlterObjectSch
COMPARE_NODE_FIELD(relation);
COMPARE_NODE_FIELD(object);
COMPARE_NODE_FIELD(objarg);
- COMPARE_STRING_FIELD(addname);
COMPARE_STRING_FIELD(newschema);
COMPARE_SCALAR_FIELD(missing_ok);
@@ -1340,7 +1339,6 @@ _equalAlterOwnerStmt(const AlterOwnerStmt *a, const AlterOwnerStmt *b)
COMPARE_NODE_FIELD(relation);
COMPARE_NODE_FIELD(object);
COMPARE_NODE_FIELD(objarg);
- COMPARE_STRING_FIELD(addname);
COMPARE_STRING_FIELD(newowner);
return true;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 7e6ceed..89a40e8 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -6608,7 +6608,7 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name
{
RenameStmt *n = makeNode(RenameStmt);
n->renameType = OBJECT_FDW;
- n->subname = $5;
+ n->object = list_make1(makeString($5));
n->newname = $8;
n->missing_ok = false;
$$ = (Node *)n;
@@ -6636,7 +6636,7 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name
{
RenameStmt *n = makeNode(RenameStmt);
n->renameType = OBJECT_LANGUAGE;
- n->subname = $4;
+ n->object = list_make1(makeString($4));
n->newname = $7;
n->missing_ok = false;
$$ = (Node *)n;
@@ -6646,7 +6646,7 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name
RenameStmt *n = makeNode(RenameStmt);
n->renameType = OBJECT_OPCLASS;
n->object = $4;
- n->subname = $6;
+ n->objarg = list_make1(makeString($6));
n->newname = $9;
n->missing_ok = false;
$$ = (Node *)n;
@@ -6656,7 +6656,7 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name
RenameStmt *n = makeNode(RenameStmt);
n->renameType = OBJECT_OPFAMILY;
n->object = $4;
- n->subname = $6;
+ n->objarg = list_make1(makeString($6));
n->newname = $9;
n->missing_ok = false;
$$ = (Node *)n;
@@ -6674,7 +6674,7 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name
{
RenameStmt *n = makeNode(RenameStmt);
n->renameType = OBJECT_FOREIGN_SERVER;
- n->subname = $3;
+ n->object = list_make1(makeString($3));
n->newname = $6;
n->missing_ok = false;
$$ = (Node *)n;
@@ -7033,7 +7033,7 @@ AlterObjectSchemaStmt:
AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
n->objectType = OBJECT_OPCLASS;
n->object = $4;
- n->addname = $6;
+ n->objarg = list_make1(makeString($6));
n->newschema = $9;
n->missing_ok = false;
$$ = (Node *)n;
@@ -7043,7 +7043,7 @@ AlterObjectSchemaStmt:
AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
n->objectType = OBJECT_OPFAMILY;
n->object = $4;
- n->addname = $6;
+ n->objarg = list_make1(makeString($6));
n->newschema = $9;
n->missing_ok = false;
$$ = (Node *)n;
@@ -7253,7 +7253,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_OPCLASS;
n->object = $4;
- n->addname = $6;
+ n->objarg = list_make1(makeString($6));
n->newowner = $9;
$$ = (Node *)n;
}
@@ -7262,7 +7262,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_OPFAMILY;
n->object = $4;
- n->addname = $6;
+ n->objarg = list_make1(makeString($6));
n->newowner = $9;
$$ = (Node *)n;
}
diff --git a/src/include/catalog/objectaddress.h b/src/include/catalog/objectaddress.h
index 0af09c6..03514ac 100644
--- a/src/include/catalog/objectaddress.h
+++ b/src/include/catalog/objectaddress.h
@@ -15,6 +15,7 @@
#include "nodes/parsenodes.h"
#include "storage/lock.h"
+#include "utils/acl.h"
#include "utils/relcache.h"
/*
@@ -37,4 +38,13 @@ extern void check_object_ownership(Oid roleid,
extern Oid get_object_namespace(const ObjectAddress *address);
+extern Oid get_object_oid_index(Oid class_id);
+extern int get_object_catcache_oid(Oid class_id);
+extern int get_object_catcache_name(Oid class_id);
+extern AttrNumber get_object_attnum_name(Oid class_id);
+extern AttrNumber get_object_attnum_namespace(Oid class_id);
+extern AttrNumber get_object_attnum_owner(Oid class_id);
+extern AttrNumber get_object_attnum_acl(Oid class_id);
+extern AclObjectKind get_object_aclkind(Oid class_id);
+
#endif /* PARSE_OBJECT_H */
diff --git a/src/include/catalog/pg_largeobject.h b/src/include/catalog/pg_largeobject.h
index d0195ea..a5f0b00 100644
--- a/src/include/catalog/pg_largeobject.h
+++ b/src/include/catalog/pg_largeobject.h
@@ -55,7 +55,6 @@ typedef FormData_pg_largeobject *Form_pg_largeobject;
extern Oid LargeObjectCreate(Oid loid);
extern void LargeObjectDrop(Oid loid);
-extern void LargeObjectAlterOwner(Oid loid, Oid newOwnerId);
extern bool LargeObjectExists(Oid loid);
#endif /* PG_LARGEOBJECT_H */
diff --git a/src/include/commands/alter.h b/src/include/commands/alter.h
index 210cf4e..1a64d89 100644
--- a/src/include/commands/alter.h
+++ b/src/include/commands/alter.h
@@ -25,5 +25,10 @@ extern Oid AlterObjectNamespace(Relation rel, int oidCacheId, int nameCacheId,
int Anum_name, int Anum_namespace, int Anum_owner,
AclObjectKind acl_kind);
extern void ExecAlterOwnerStmt(AlterOwnerStmt *stmt);
-
+extern Oid AlterObjectOwner(Relation catalog, Oid oidIndexId, int oidCacheId,
+ Oid objectId, Oid new_ownerId,
+ AttrNumber Anum_owner,
+ AttrNumber Anum_namespace,
+ AttrNumber Anum_acl,
+ AclObjectKind aclkind);
#endif /* ALTER_H */
diff --git a/src/include/commands/collationcmds.h b/src/include/commands/collationcmds.h
index 0587c4f..597033a 100644
--- a/src/include/commands/collationcmds.h
+++ b/src/include/commands/collationcmds.h
@@ -18,9 +18,6 @@
#include "nodes/parsenodes.h"
extern void DefineCollation(List *names, List *parameters);
-extern void RenameCollation(List *name, const char *newname);
-extern void AlterCollationOwner(List *name, Oid newOwnerId);
-extern void AlterCollationOwner_oid(Oid collationOid, Oid newOwnerId);
extern void AlterCollationNamespace(List *name, const char *newschema);
extern Oid AlterCollationNamespace_oid(Oid collOid, Oid newNspOid);
diff --git a/src/include/commands/conversioncmds.h b/src/include/commands/conversioncmds.h
index 00f468f..2f9abad 100644
--- a/src/include/commands/conversioncmds.h
+++ b/src/include/commands/conversioncmds.h
@@ -19,9 +19,5 @@
extern void CreateConversionCommand(CreateConversionStmt *parsetree);
extern void RenameConversion(List *name, const char *newname);
-extern void AlterConversionOwner(List *name, Oid newOwnerId);
-extern void AlterConversionOwner_oid(Oid conversionOid, Oid newOwnerId);
-extern void AlterConversionNamespace(List *name, const char *newschema);
-extern Oid AlterConversionNamespace_oid(Oid convOid, Oid newNspOid);
#endif /* CONVERSIONCMDS_H */
diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h
index 8f3d2c3..7aecb1a 100644
--- a/src/include/commands/defrem.h
+++ b/src/include/commands/defrem.h
@@ -64,7 +64,6 @@ extern void CreateFunction(CreateFunctionStmt *stmt, const char *queryString);
extern void RemoveFunctionById(Oid funcOid);
extern void SetFunctionReturnType(Oid funcOid, Oid newRetType);
extern void SetFunctionArgType(Oid funcOid, int argIndex, Oid newArgType);
-extern void RenameFunction(List *name, List *argtypes, const char *newname);
extern void AlterFunctionOwner(List *name, List *argtypes, Oid newOwnerId);
extern void AlterFunctionOwner_oid(Oid procOid, Oid newOwnerId);
extern void AlterFunction(AlterFunctionStmt *stmt);
@@ -79,16 +78,10 @@ extern Oid get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok);
/* commands/operatorcmds.c */
extern void DefineOperator(List *names, List *parameters);
extern void RemoveOperatorById(Oid operOid);
-extern void AlterOperatorOwner(List *name, TypeName *typeName1,
- TypeName *typename2, Oid newOwnerId);
-extern void AlterOperatorOwner_oid(Oid operOid, Oid newOwnerId);
-extern void AlterOperatorNamespace(List *names, List *argtypes, const char *newschema);
-extern Oid AlterOperatorNamespace_oid(Oid operOid, Oid newNspOid);
/* commands/aggregatecmds.c */
extern void DefineAggregate(List *name, List *args, bool oldstyle,
List *parameters);
-extern void RenameAggregate(List *name, List *args, const char *newname);
extern void AlterAggregateOwner(List *name, List *args, Oid newOwnerId);
/* commands/opclasscmds.c */
@@ -99,55 +92,29 @@ extern void RemoveOpClassById(Oid opclassOid);
extern void RemoveOpFamilyById(Oid opfamilyOid);
extern void RemoveAmOpEntryById(Oid entryOid);
extern void RemoveAmProcEntryById(Oid entryOid);
-extern void RenameOpClass(List *name, const char *access_method, const char *newname);
-extern void RenameOpFamily(List *name, const char *access_method, const char *newname);
-extern void AlterOpClassOwner(List *name, const char *access_method, Oid newOwnerId);
-extern void AlterOpClassOwner_oid(Oid opclassOid, Oid newOwnerId);
-extern void AlterOpClassNamespace(List *name, char *access_method, const char *newschema);
-extern Oid AlterOpClassNamespace_oid(Oid opclassOid, Oid newNspOid);
-extern void AlterOpFamilyOwner(List *name, const char *access_method, Oid newOwnerId);
-extern void AlterOpFamilyOwner_oid(Oid opfamilyOid, Oid newOwnerId);
-extern void AlterOpFamilyNamespace(List *name, char *access_method, const char *newschema);
-extern Oid AlterOpFamilyNamespace_oid(Oid opfamilyOid, Oid newNspOid);
extern Oid get_am_oid(const char *amname, bool missing_ok);
extern Oid get_opclass_oid(Oid amID, List *opclassname, bool missing_ok);
extern Oid get_opfamily_oid(Oid amID, List *opfamilyname, bool missing_ok);
/* commands/tsearchcmds.c */
extern void DefineTSParser(List *names, List *parameters);
-extern void RenameTSParser(List *oldname, const char *newname);
-extern void AlterTSParserNamespace(List *name, const char *newschema);
-extern Oid AlterTSParserNamespace_oid(Oid prsId, Oid newNspOid);
extern void RemoveTSParserById(Oid prsId);
extern void DefineTSDictionary(List *names, List *parameters);
-extern void RenameTSDictionary(List *oldname, const char *newname);
extern void RemoveTSDictionaryById(Oid dictId);
extern void AlterTSDictionary(AlterTSDictionaryStmt *stmt);
-extern void AlterTSDictionaryOwner(List *name, Oid newOwnerId);
-extern void AlterTSDictionaryNamespace(List *name, const char *newschema);
-extern Oid AlterTSDictionaryNamespace_oid(Oid dictId, Oid newNspOid);
extern void DefineTSTemplate(List *names, List *parameters);
-extern void RenameTSTemplate(List *oldname, const char *newname);
-extern void AlterTSTemplateNamespace(List *name, const char *newschema);
-extern Oid AlterTSTemplateNamespace_oid(Oid tmplId, Oid newNspOid);
extern void RemoveTSTemplateById(Oid tmplId);
extern void DefineTSConfiguration(List *names, List *parameters);
-extern void RenameTSConfiguration(List *oldname, const char *newname);
extern void RemoveTSConfigurationById(Oid cfgId);
extern void AlterTSConfiguration(AlterTSConfigurationStmt *stmt);
-extern void AlterTSConfigurationOwner(List *name, Oid newOwnerId);
-extern void AlterTSConfigurationNamespace(List *name, const char *newschema);
-extern Oid AlterTSConfigurationNamespace_oid(Oid cfgId, Oid newNspOid);
extern text *serialize_deflist(List *deflist);
extern List *deserialize_deflist(Datum txt);
/* commands/foreigncmds.c */
-extern void RenameForeignServer(const char *oldname, const char *newname);
-extern void RenameForeignDataWrapper(const char *oldname, const char *newname);
extern void AlterForeignServerOwner(const char *name, Oid newOwnerId);
extern void AlterForeignServerOwner_oid(Oid, Oid newOwnerId);
extern void AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId);
diff --git a/src/include/commands/proclang.h b/src/include/commands/proclang.h
index 17d0972..11d7bf8 100644
--- a/src/include/commands/proclang.h
+++ b/src/include/commands/proclang.h
@@ -16,7 +16,6 @@
extern void CreateProceduralLanguage(CreatePLangStmt *stmt);
extern void DropProceduralLanguageById(Oid langOid);
-extern void RenameLanguage(const char *oldname, const char *newname);
extern void AlterLanguageOwner(const char *name, Oid newOwnerId);
extern void AlterLanguageOwner_oid(Oid oid, Oid newOwnerId);
extern bool PLTemplateExists(const char *languageName);
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 50111cb..fb71615 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -2136,7 +2136,6 @@ typedef struct AlterObjectSchemaStmt
RangeVar *relation; /* in case it's a table */
List *object; /* in case it's some other object */
List *objarg; /* argument types, if applicable */
- char *addname; /* additional name if needed */
char *newschema; /* the new schema */
bool missing_ok; /* skip error if missing? */
} AlterObjectSchemaStmt;
@@ -2152,7 +2151,6 @@ typedef struct AlterOwnerStmt
RangeVar *relation; /* in case it's a table */
List *object; /* in case it's some other object */
List *objarg; /* argument types, if applicable */
- char *addname; /* additional name if needed */
char *newowner; /* the new owner */
} AlterOwnerStmt;
diff --git a/src/test/regress/expected/alter_generic.out b/src/test/regress/expected/alter_generic.out
new file mode 100644
index 0000000..45e29c0
--- /dev/null
+++ b/src/test/regress/expected/alter_generic.out
@@ -0,0 +1,545 @@
+--
+-- Test for ALTER RENAME TO/OWNER TO/SET SCHEMA
+--
+-- Clean up in case a prior regression run failed
+SET client_min_messages TO 'warning';
+DROP ROLE IF EXISTS regtest_alter_user1;
+DROP ROLE IF EXISTS regtest_alter_user2;
+DROP ROLE IF EXISTS regtest_alter_user3;
+RESET client_min_messages;
+CREATE USER regtest_alter_user3;
+CREATE USER regtest_alter_user2;
+CREATE USER regtest_alter_user1 IN ROLE regtest_alter_user3;
+CREATE SCHEMA alt_nsp1;
+CREATE SCHEMA alt_nsp2;
+GRANT ALL ON SCHEMA alt_nsp1, alt_nsp2 TO public;
+SET search_path = alt_nsp1, public;
+--
+-- Function and Aggregate
+--
+SET SESSION AUTHORIZATION regtest_alter_user1;
+CREATE FUNCTION alt_func1(int) RETURNS int LANGUAGE sql
+ AS 'SELECT $1 + 1';
+CREATE FUNCTION alt_func2(int) RETURNS int LANGUAGE sql
+ AS 'SELECT $1 - 1';
+CREATE AGGREGATE alt_agg1 (
+ sfunc1 = int4pl, basetype = int4, stype1 = int4, initcond = 0
+);
+CREATE AGGREGATE alt_agg2 (
+ sfunc1 = int4mi, basetype = int4, stype1 = int4, initcond = 0
+);
+ALTER AGGREGATE alt_func1(int) RENAME TO alt_func3; -- failed (not aggregate)
+ERROR: function alt_func1(integer) is not an aggregate
+ALTER AGGREGATE alt_func1(int) OWNER TO regtest_alter_user3; -- failed (not aggregate)
+ERROR: function alt_func1(integer) is not an aggregate
+ALTER AGGREGATE alt_func1(int) SET SCHEMA alt_nsp2; -- failed (not aggregate)
+ERROR: function alt_func1(integer) is not an aggregate
+ALTER FUNCTION alt_func1(int) RENAME TO alt_func2; -- failed (name conflict)
+ERROR: function alt_func2(integer) already exists in schema "alt_nsp1"
+ALTER FUNCTION alt_func1(int) RENAME TO alt_func3; -- OK
+ALTER FUNCTION alt_func2(int) OWNER TO regtest_alter_user2; -- failed (no role membership)
+ERROR: must be member of role "regtest_alter_user2"
+ALTER FUNCTION alt_func2(int) OWNER TO regtest_alter_user3; -- OK
+ALTER FUNCTION alt_func2(int) SET SCHEMA alt_nsp2; -- OK
+ALTER AGGREGATE alt_agg1(int) RENAME TO alt_agg2; -- failed (name conflict)
+ERROR: function alt_agg2(integer) already exists in schema "alt_nsp1"
+ALTER AGGREGATE alt_agg1(int) RENAME TO alt_agg3; -- OK
+ALTER AGGREGATE alt_agg2(int) OWNER TO regtest_alter_user2; -- failed (no role membership)
+ERROR: must be member of role "regtest_alter_user2"
+ALTER AGGREGATE alt_agg2(int) OWNER TO regtest_alter_user3; -- OK
+ALTER AGGREGATE alt_agg2(int) SET SCHEMA alt_nsp2; -- OK
+SET SESSION AUTHORIZATION regtest_alter_user2;
+CREATE FUNCTION alt_func1(int) RETURNS int LANGUAGE sql
+ AS 'SELECT $1 + 2';
+CREATE FUNCTION alt_func2(int) RETURNS int LANGUAGE sql
+ AS 'SELECT $1 - 2';
+CREATE AGGREGATE alt_agg1 (
+ sfunc1 = int4pl, basetype = int4, stype1 = int4, initcond = 100
+);
+CREATE AGGREGATE alt_agg2 (
+ sfunc1 = int4mi, basetype = int4, stype1 = int4, initcond = -100
+);
+ALTER FUNCTION alt_func3(int) RENAME TO alt_func4; -- failed (not owner)
+ERROR: must be owner of function alt_func3
+ALTER FUNCTION alt_func1(int) RENAME TO alt_func4; -- OK
+ALTER FUNCTION alt_func3(int) OWNER TO regtest_alter_user2; -- failed (not owner)
+ERROR: must be owner of function alt_func3(integer)
+ALTER FUNCTION alt_func2(int) OWNER TO regtest_alter_user3; -- failed (no role membership)
+ERROR: must be member of role "regtest_alter_user3"
+ALTER FUNCTION alt_func3(int) SET SCHEMA alt_nsp2; -- failed (not owner)
+ERROR: must be owner of function alt_func3
+ALTER FUNCTION alt_func2(int) SET SCHEMA alt_nsp2; -- failed (name conflicts)
+ERROR: function "alt_func2" already exists in schema "alt_nsp2"
+ALTER AGGREGATE alt_agg3(int) RENAME TO alt_agg4; -- failed (not owner)
+ERROR: must be owner of function alt_agg3
+ALTER AGGREGATE alt_agg1(int) RENAME TO alt_agg4; -- OK
+ALTER AGGREGATE alt_agg3(int) OWNER TO regtest_alter_user2; -- failed (not owner)
+ERROR: must be owner of function alt_agg3(integer)
+ALTER AGGREGATE alt_agg2(int) OWNER TO regtest_alter_user3; -- failed (no role membership)
+ERROR: must be member of role "regtest_alter_user3"
+ALTER AGGREGATE alt_agg3(int) SET SCHEMA alt_nsp2; -- failed (not owner)
+ERROR: must be owner of function alt_agg3
+ALTER AGGREGATE alt_agg2(int) SET SCHEMA alt_nsp2; -- failed (name conflict)
+ERROR: function "alt_agg2" already exists in schema "alt_nsp2"
+RESET SESSION AUTHORIZATION;
+SELECT n.nspname, proname, prorettype::regtype, proisagg, a.rolname
+ FROM pg_proc p, pg_namespace n, pg_authid a
+ WHERE p.pronamespace = n.oid AND p.proowner = a.oid
+ AND n.nspname IN ('alt_nsp1', 'alt_nsp2')
+ ORDER BY nspname, proname;
+ nspname | proname | prorettype | proisagg | rolname
+----------+-----------+------------+----------+---------------------
+ alt_nsp1 | alt_agg2 | integer | t | regtest_alter_user2
+ alt_nsp1 | alt_agg3 | integer | t | regtest_alter_user1
+ alt_nsp1 | alt_agg4 | integer | t | regtest_alter_user2
+ alt_nsp1 | alt_func2 | integer | f | regtest_alter_user2
+ alt_nsp1 | alt_func3 | integer | f | regtest_alter_user1
+ alt_nsp1 | alt_func4 | integer | f | regtest_alter_user2
+ alt_nsp2 | alt_agg2 | integer | t | regtest_alter_user3
+ alt_nsp2 | alt_func2 | integer | f | regtest_alter_user3
+(8 rows)
+
+--
+-- Collation
+--
+SET SESSION AUTHORIZATION regtest_alter_user1;
+CREATE COLLATION alt_coll1 (locale = 'C');
+CREATE COLLATION alt_coll2 (locale = 'C');
+ALTER COLLATION alt_coll1 RENAME TO alt_coll2; -- failed (name conflict)
+ERROR: collation alt_coll2 already exists in schema "alt_nsp1"
+ALTER COLLATION alt_coll1 RENAME TO alt_coll3; -- OK
+ALTER COLLATION alt_coll2 OWNER TO regtest_alter_user2; -- failed (no role membership)
+ERROR: must be member of role "regtest_alter_user2"
+ALTER COLLATION alt_coll2 OWNER TO regtest_alter_user3; -- OK
+ALTER COLLATION alt_coll2 SET SCHEMA alt_nsp2; -- OK
+SET SESSION AUTHORIZATION regtest_alter_user2;
+CREATE COLLATION alt_coll1 (locale = 'C');
+CREATE COLLATION alt_coll2 (locale = 'C');
+ALTER COLLATION alt_coll3 RENAME TO alt_coll4; -- failed (not owner)
+ERROR: must be owner of collation alt_coll3
+ALTER COLLATION alt_coll1 RENAME TO alt_coll4; -- OK
+ALTER COLLATION alt_coll3 OWNER TO regtest_alter_user2; -- failed (not owner)
+ERROR: must be owner of collation alt_coll3
+ALTER COLLATION alt_coll2 OWNER TO regtest_alter_user3; -- failed (no role membership)
+ERROR: must be member of role "regtest_alter_user3"
+ALTER COLLATION alt_coll3 SET SCHEMA alt_nsp2; -- failed (not owner)
+ERROR: must be owner of collation alt_coll3
+ALTER COLLATION alt_coll2 SET SCHEMA alt_nsp2; -- failed (name conflict)
+ERROR: collation "alt_coll2" for encoding "SQL_ASCII" already exists in schema "alt_nsp2"
+RESET SESSION AUTHORIZATION;
+SELECT n.nspname, c.collname, a.rolname
+ FROM pg_collation c, pg_namespace n, pg_authid a
+ WHERE c.collnamespace = n.oid AND c.collowner = a.oid
+ AND n.nspname IN ('alt_nsp1', 'alt_nsp2')
+ ORDER BY n.nspname, c.collname;
+ nspname | collname | rolname
+----------+-----------+---------------------
+ alt_nsp1 | alt_coll2 | regtest_alter_user2
+ alt_nsp1 | alt_coll3 | regtest_alter_user1
+ alt_nsp1 | alt_coll4 | regtest_alter_user2
+ alt_nsp2 | alt_coll2 | regtest_alter_user3
+(4 rows)
+
+--
+-- Conversion
+--
+SET SESSION AUTHORIZATION regtest_alter_user1;
+CREATE CONVERSION alt_conv1 FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8;
+CREATE CONVERSION alt_conv2 FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8;
+ALTER CONVERSION alt_conv1 RENAME TO alt_conv2; -- failed (name conflict)
+ERROR: conversion alt_conv2 already exists in schema "alt_nsp1"
+ALTER CONVERSION alt_conv1 RENAME TO alt_conv3; -- OK
+ALTER CONVERSION alt_conv2 OWNER TO regtest_alter_user2; -- failed (no role membership)
+ERROR: must be member of role "regtest_alter_user2"
+ALTER CONVERSION alt_conv2 OWNER TO regtest_alter_user3; -- OK
+ALTER CONVERSION alt_conv2 SET SCHEMA alt_nsp2; -- OK
+SET SESSION AUTHORIZATION regtest_alter_user2;
+CREATE CONVERSION alt_conv1 FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8;
+CREATE CONVERSION alt_conv2 FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8;
+ALTER CONVERSION alt_conv3 RENAME TO alt_conv4; -- failed (not owner)
+ERROR: must be owner of conversion alt_conv3
+ALTER CONVERSION alt_conv1 RENAME TO alt_conv4; -- OK
+ALTER CONVERSION alt_conv3 OWNER TO regtest_alter_user2; -- failed (not owner)
+ERROR: must be owner of conversion alt_conv3
+ALTER CONVERSION alt_conv2 OWNER TO regtest_alter_user3; -- failed (no role membership)
+ERROR: must be member of role "regtest_alter_user3"
+ALTER CONVERSION alt_conv3 SET SCHEMA alt_nsp2; -- failed (not owner)
+ERROR: must be owner of conversion alt_conv3
+ALTER CONVERSION alt_conv2 SET SCHEMA alt_nsp2; -- failed (name conflict)
+ERROR: conversion alt_conv2 already exists in schema "alt_nsp2"
+RESET SESSION AUTHORIZATION;
+SELECT n.nspname, c.conname, a.rolname
+ FROM pg_conversion c, pg_namespace n, pg_authid a
+ WHERE c.connamespace = n.oid AND c.conowner = a.oid
+ AND n.nspname IN ('alt_nsp1', 'alt_nsp2')
+ ORDER BY nspname, conname;
+ nspname | conname | rolname
+----------+-----------+---------------------
+ alt_nsp1 | alt_conv2 | regtest_alter_user2
+ alt_nsp1 | alt_conv3 | regtest_alter_user1
+ alt_nsp1 | alt_conv4 | regtest_alter_user2
+ alt_nsp2 | alt_conv2 | regtest_alter_user3
+(4 rows)
+
+--
+-- Foreign Data Wrapper and Foreign Server
+--
+CREATE FOREIGN DATA WRAPPER alt_fdw1;
+CREATE FOREIGN DATA WRAPPER alt_fdw2;
+CREATE SERVER alt_fserv1 FOREIGN DATA WRAPPER alt_fdw1;
+CREATE SERVER alt_fserv2 FOREIGN DATA WRAPPER alt_fdw2;
+ALTER FOREIGN DATA WRAPPER alt_fdw1 RENAME TO alt_fdw2; -- failed (name conflict)
+ERROR: foreign-data wrapper alt_fdw2 already exists
+ALTER FOREIGN DATA WRAPPER alt_fdw1 RENAME TO alt_fdw3; -- OK
+ALTER SERVER alt_fserv1 RENAME TO alt_fserv2; -- failed (name conflict)
+ERROR: server alt_fserv2 already exists
+ALTER SERVER alt_fserv1 RENAME TO alt_fserv3; -- OK
+SELECT fdwname FROM pg_foreign_data_wrapper WHERE fdwname like 'alt_fdw%';
+ fdwname
+----------
+ alt_fdw2
+ alt_fdw3
+(2 rows)
+
+SELECT srvname FROM pg_foreign_server WHERE srvname like 'alt_fserv%';
+ srvname
+------------
+ alt_fserv2
+ alt_fserv3
+(2 rows)
+
+--
+-- Procedural Language
+--
+CREATE LANGUAGE alt_lang1 HANDLER plpgsql_call_handler;
+CREATE LANGUAGE alt_lang2 HANDLER plpgsql_call_handler;
+ALTER LANGUAGE alt_lang1 OWNER TO regtest_alter_user1; -- OK
+ALTER LANGUAGE alt_lang2 OWNER TO regtest_alter_user2; -- OK
+SET SESSION AUTHORIZATION regtest_alter_user1;
+ALTER LANGUAGE alt_lang1 RENAME TO alt_lang2; -- failed (name conflict)
+ERROR: language alt_lang2 already exists
+ALTER LANGUAGE alt_lang2 RENAME TO alt_lang3; -- failed (not owner)
+ERROR: must be owner of language alt_lang2
+ALTER LANGUAGE alt_lang1 RENAME TO alt_lang3; -- OK
+ALTER LANGUAGE alt_lang2 OWNER TO regtest_alter_user3; -- failed (not owner)
+ERROR: must be owner of language alt_lang2
+ALTER LANGUAGE alt_lang3 OWNER TO regtest_alter_user2; -- failed (no role membership)
+ERROR: must be member of role "regtest_alter_user2"
+ALTER LANGUAGE alt_lang3 OWNER TO regtest_alter_user3; -- OK
+RESET SESSION AUTHORIZATION;
+SELECT lanname, a.rolname
+ FROM pg_language l, pg_authid a
+ WHERE l.lanowner = a.oid AND l.lanname like 'alt_lang%'
+ ORDER BY lanname;
+ lanname | rolname
+-----------+---------------------
+ alt_lang2 | regtest_alter_user2
+ alt_lang3 | regtest_alter_user3
+(2 rows)
+
+--
+-- Operator
+--
+SET SESSION AUTHORIZATION regtest_alter_user1;
+CREATE OPERATOR @-@ ( leftarg = int4, rightarg = int4, procedure = int4mi );
+CREATE OPERATOR @+@ ( leftarg = int4, rightarg = int4, procedure = int4pl );
+ALTER OPERATOR @+@(int4, int4) OWNER TO regtest_alter_user2; -- failed (no role membership)
+ERROR: must be member of role "regtest_alter_user2"
+ALTER OPERATOR @+@(int4, int4) OWNER TO regtest_alter_user3; -- OK
+ALTER OPERATOR @-@(int4, int4) SET SCHEMA alt_nsp2; -- OK
+SET SESSION AUTHORIZATION regtest_alter_user2;
+CREATE OPERATOR @-@ ( leftarg = int4, rightarg = int4, procedure = int4mi );
+ALTER OPERATOR @+@(int4, int4) OWNER TO regtest_alter_user2; -- failed (not owner)
+ERROR: must be owner of operator @+@(integer,integer)
+ALTER OPERATOR @-@(int4, int4) OWNER TO regtest_alter_user3; -- failed (no role membership)
+ERROR: must be member of role "regtest_alter_user3"
+ALTER OPERATOR @+@(int4, int4) SET SCHEMA alt_nsp2; -- failed (not owner)
+ERROR: must be owner of operator @+@
+-- ALTER OPERATOR @-@(int4, int4) SET SCHEMA alt_nsp2; -- failed (name conflict)
+-- XXX it raises raw oid of namespace, it makes unneeded regression test fail...
+RESET SESSION AUTHORIZATION;
+SELECT n.nspname, oprname, a.rolname, oprleft::regtype, oprright::regtype, oprcode::regproc
+ FROM pg_operator o, pg_namespace n, pg_authid a
+ WHERE o.oprnamespace = n.oid AND o.oprowner = a.oid
+ AND n.nspname IN ('alt_nsp1', 'alt_nsp2')
+ ORDER BY nspname, oprname;
+ nspname | oprname | rolname | oprleft | oprright | oprcode
+----------+---------+---------------------+---------+----------+---------
+ alt_nsp1 | @+@ | regtest_alter_user3 | integer | integer | int4pl
+ alt_nsp1 | @-@ | regtest_alter_user2 | integer | integer | int4mi
+ alt_nsp2 | @-@ | regtest_alter_user1 | integer | integer | int4mi
+(3 rows)
+
+--
+-- OpFamily and OpClass
+--
+CREATE OPERATOR FAMILY alt_opf1 USING hash;
+CREATE OPERATOR FAMILY alt_opf2 USING hash;
+ALTER OPERATOR FAMILY alt_opf1 USING hash OWNER TO regtest_alter_user1;
+ALTER OPERATOR FAMILY alt_opf2 USING hash OWNER TO regtest_alter_user1;
+CREATE OPERATOR CLASS alt_opc1 FOR TYPE uuid USING hash AS STORAGE uuid;
+CREATE OPERATOR CLASS alt_opc2 FOR TYPE uuid USING hash AS STORAGE uuid;
+ALTER OPERATOR CLASS alt_opc1 USING hash OWNER TO regtest_alter_user1;
+ALTER OPERATOR CLASS alt_opc2 USING hash OWNER TO regtest_alter_user1;
+SET SESSION AUTHORIZATION regtest_alter_user1;
+ALTER OPERATOR FAMILY alt_opf1 USING hash RENAME TO alt_opf2; -- failed (name conflict)
+ERROR: operator family alt_opf2 for access method hash already exists in schema "alt_nsp1"
+ALTER OPERATOR FAMILY alt_opf1 USING hash RENAME TO alt_opf3; -- OK
+ALTER OPERATOR FAMILY alt_opf2 USING hash OWNER TO regtest_alter_user2; -- failed (no role membership)
+ERROR: must be member of role "regtest_alter_user2"
+ALTER OPERATOR FAMILY alt_opf2 USING hash OWNER TO regtest_alter_user3; -- OK
+ALTER OPERATOR FAMILY alt_opf2 USING hash SET SCHEMA alt_nsp2; -- OK
+ALTER OPERATOR CLASS alt_opc1 USING hash RENAME TO alt_opc2; -- failed (name conflict)
+ERROR: operator class alt_opc2 for access method hash already exists in schema "alt_nsp1"
+ALTER OPERATOR CLASS alt_opc1 USING hash RENAME TO alt_opc3; -- OK
+ALTER OPERATOR CLASS alt_opc2 USING hash OWNER TO regtest_alter_user2; -- failed (no role membership)
+ERROR: must be member of role "regtest_alter_user2"
+ALTER OPERATOR CLASS alt_opc2 USING hash OWNER TO regtest_alter_user3; -- OK
+ALTER OPERATOR CLASS alt_opc2 USING hash SET SCHEMA alt_nsp2; -- OK
+RESET SESSION AUTHORIZATION;
+CREATE OPERATOR FAMILY alt_opf1 USING hash;
+CREATE OPERATOR FAMILY alt_opf2 USING hash;
+ALTER OPERATOR FAMILY alt_opf1 USING hash OWNER TO regtest_alter_user2;
+ALTER OPERATOR FAMILY alt_opf2 USING hash OWNER TO regtest_alter_user2;
+CREATE OPERATOR CLASS alt_opc1 FOR TYPE macaddr USING hash AS STORAGE macaddr;
+CREATE OPERATOR CLASS alt_opc2 FOR TYPE macaddr USING hash AS STORAGE macaddr;
+ALTER OPERATOR CLASS alt_opc1 USING hash OWNER TO regtest_alter_user2;
+ALTER OPERATOR CLASS alt_opc2 USING hash OWNER TO regtest_alter_user2;
+SET SESSION AUTHORIZATION regtest_alter_user2;
+ALTER OPERATOR FAMILY alt_opf3 USING hash RENAME TO alt_opf4; -- failed (not owner)
+ERROR: must be owner of operator family alt_opf3
+ALTER OPERATOR FAMILY alt_opf1 USING hash RENAME TO alt_opf4; -- OK
+ALTER OPERATOR FAMILY alt_opf3 USING hash OWNER TO regtest_alter_user2; -- failed (not owner)
+ERROR: must be owner of operator family alt_opf3 for access method hash
+ALTER OPERATOR FAMILY alt_opf2 USING hash OWNER TO regtest_alter_user3; -- failed (no role membership)
+ERROR: must be member of role "regtest_alter_user3"
+ALTER OPERATOR FAMILY alt_opf3 USING hash SET SCHEMA alt_nsp2; -- failed (not owner)
+ERROR: must be owner of operator family alt_opf3
+-- ALTER OPERATOR FAMILY alt_opf2 USING hash SET SCHEMA alt_nsp2; -- failed (name conflict)
+ALTER OPERATOR CLASS alt_opc3 USING hash RENAME TO alt_opc4; -- failed (not owner)
+ERROR: must be owner of operator class alt_opc3
+ALTER OPERATOR CLASS alt_opc1 USING hash RENAME TO alt_opc4; -- OK
+ALTER OPERATOR CLASS alt_opc3 USING hash OWNER TO regtest_alter_user2; -- failed (not owner)
+ERROR: must be owner of operator class alt_opc3 for access method hash
+ALTER OPERATOR CLASS alt_opc2 USING hash OWNER TO regtest_alter_user3; -- failed (no role membership)
+ERROR: must be member of role "regtest_alter_user3"
+ALTER OPERATOR CLASS alt_opc3 USING hash SET SCHEMA alt_nsp2; -- failed (not owner)
+ERROR: must be owner of operator class alt_opc3
+-- ALTER OPERATOR CLASS alt_opc2 USING hash SET SCHEMA alt_nsp2; -- failed (name conflict)
+RESET SESSION AUTHORIZATION;
+SELECT nspname, opfname, amname, rolname
+ FROM pg_opfamily o, pg_am m, pg_namespace n, pg_authid a
+ WHERE o.opfmethod = m.oid AND o.opfnamespace = n.oid AND o.opfowner = a.oid
+ AND n.nspname IN ('alt_nsp1', 'alt_nsp2')
+ ORDER BY nspname, opfname;
+ nspname | opfname | amname | rolname
+----------+----------+--------+---------------------
+ alt_nsp1 | alt_opc1 | hash | kaigai
+ alt_nsp1 | alt_opc2 | hash | kaigai
+ alt_nsp1 | alt_opf2 | hash | regtest_alter_user2
+ alt_nsp1 | alt_opf3 | hash | regtest_alter_user1
+ alt_nsp1 | alt_opf4 | hash | regtest_alter_user2
+ alt_nsp2 | alt_opf2 | hash | regtest_alter_user3
+(6 rows)
+
+SELECT nspname, opcname, amname, rolname
+ FROM pg_opclass o, pg_am m, pg_namespace n, pg_authid a
+ WHERE o.opcmethod = m.oid AND o.opcnamespace = n.oid AND o.opcowner = a.oid
+ AND n.nspname IN ('alt_nsp1', 'alt_nsp2')
+ ORDER BY nspname, opcname;
+ nspname | opcname | amname | rolname
+----------+----------+--------+---------------------
+ alt_nsp1 | alt_opc2 | hash | regtest_alter_user2
+ alt_nsp1 | alt_opc3 | hash | regtest_alter_user1
+ alt_nsp1 | alt_opc4 | hash | regtest_alter_user2
+ alt_nsp2 | alt_opc2 | hash | regtest_alter_user3
+(4 rows)
+
+--
+-- Text Search Dictionary
+--
+SET SESSION AUTHORIZATION regtest_alter_user1;
+CREATE TEXT SEARCH DICTIONARY alt_ts_dict1 (template=simple);
+CREATE TEXT SEARCH DICTIONARY alt_ts_dict2 (template=simple);
+ALTER TEXT SEARCH DICTIONARY alt_ts_dict1 RENAME TO alt_ts_dict2; -- failed (name conflict)
+ERROR: text search dictionary alt_ts_dict2 already exists in schema "alt_nsp1"
+ALTER TEXT SEARCH DICTIONARY alt_ts_dict1 RENAME TO alt_ts_dict3; -- OK
+ALTER TEXT SEARCH DICTIONARY alt_ts_dict2 OWNER TO regtest_alter_user2; -- failed (no role membership)
+ERROR: must be member of role "regtest_alter_user2"
+ALTER TEXT SEARCH DICTIONARY alt_ts_dict2 OWNER TO regtest_alter_user3; -- OK
+ALTER TEXT SEARCH DICTIONARY alt_ts_dict2 SET SCHEMA alt_nsp2; -- OK
+SET SESSION AUTHORIZATION regtest_alter_user2;
+CREATE TEXT SEARCH DICTIONARY alt_ts_dict1 (template=simple);
+CREATE TEXT SEARCH DICTIONARY alt_ts_dict2 (template=simple);
+ALTER TEXT SEARCH DICTIONARY alt_ts_dict3 RENAME TO alt_ts_dict4; -- failed (not owner)
+ERROR: must be owner of text search dictionary alt_ts_dict3
+ALTER TEXT SEARCH DICTIONARY alt_ts_dict1 RENAME TO alt_ts_dict4; -- OK
+ALTER TEXT SEARCH DICTIONARY alt_ts_dict3 OWNER TO regtest_alter_user2; -- failed (not owner)
+ERROR: must be owner of text search dictionary alt_ts_dict3
+ALTER TEXT SEARCH DICTIONARY alt_ts_dict2 OWNER TO regtest_alter_user3; -- failed (no role membership)
+ERROR: must be member of role "regtest_alter_user3"
+ALTER TEXT SEARCH DICTIONARY alt_ts_dict3 SET SCHEMA alt_nsp2; -- failed (not owner)
+ERROR: must be owner of text search dictionary alt_ts_dict3
+ALTER TEXT SEARCH DICTIONARY alt_ts_dict2 SET SCHEMA alt_nsp2; -- failed (name conflict)
+ERROR: text search dictionary alt_ts_dict2 already exists in schema "alt_nsp2"
+RESET SESSION AUTHORIZATION;
+SELECT nspname, dictname, rolname
+ FROM pg_ts_dict t, pg_namespace n, pg_authid a
+ WHERE t.dictnamespace = n.oid AND t.dictowner = a.oid
+ AND n.nspname in ('alt_nsp1', 'alt_nsp2')
+ ORDER BY nspname, dictname;
+ nspname | dictname | rolname
+----------+--------------+---------------------
+ alt_nsp1 | alt_ts_dict2 | regtest_alter_user2
+ alt_nsp1 | alt_ts_dict3 | regtest_alter_user1
+ alt_nsp1 | alt_ts_dict4 | regtest_alter_user2
+ alt_nsp2 | alt_ts_dict2 | regtest_alter_user3
+(4 rows)
+
+--
+-- Text Search Configuration
+--
+SET SESSION AUTHORIZATION regtest_alter_user1;
+CREATE TEXT SEARCH CONFIGURATION alt_ts_conf1 (copy=english);
+CREATE TEXT SEARCH CONFIGURATION alt_ts_conf2 (copy=english);
+ALTER TEXT SEARCH CONFIGURATION alt_ts_conf1 RENAME TO alt_ts_conf2; -- failed (name conflict)
+ERROR: text search configuration alt_ts_conf2 already exists in schema "alt_nsp1"
+ALTER TEXT SEARCH CONFIGURATION alt_ts_conf1 RENAME TO alt_ts_conf3; -- OK
+ALTER TEXT SEARCH CONFIGURATION alt_ts_conf2 OWNER TO regtest_alter_user2; -- failed (no role membership)
+ERROR: must be member of role "regtest_alter_user2"
+ALTER TEXT SEARCH CONFIGURATION alt_ts_conf2 OWNER TO regtest_alter_user3; -- OK
+ALTER TEXT SEARCH CONFIGURATION alt_ts_conf2 SET SCHEMA alt_nsp2; -- OK
+SET SESSION AUTHORIZATION regtest_alter_user2;
+CREATE TEXT SEARCH CONFIGURATION alt_ts_conf1 (copy=english);
+CREATE TEXT SEARCH CONFIGURATION alt_ts_conf2 (copy=english);
+ALTER TEXT SEARCH CONFIGURATION alt_ts_conf3 RENAME TO alt_ts_conf4; -- failed (not owner)
+ERROR: must be owner of text search configuration alt_ts_conf3
+ALTER TEXT SEARCH CONFIGURATION alt_ts_conf1 RENAME TO alt_ts_conf4; -- OK
+ALTER TEXT SEARCH CONFIGURATION alt_ts_conf3 OWNER TO regtest_alter_user2; -- failed (not owner)
+ERROR: must be owner of text search configuration alt_ts_conf3
+ALTER TEXT SEARCH CONFIGURATION alt_ts_conf2 OWNER TO regtest_alter_user3; -- failed (no role membership)
+ERROR: must be member of role "regtest_alter_user3"
+ALTER TEXT SEARCH CONFIGURATION alt_ts_conf3 SET SCHEMA alt_nsp2; -- failed (not owner)
+ERROR: must be owner of text search configuration alt_ts_conf3
+ALTER TEXT SEARCH CONFIGURATION alt_ts_conf2 SET SCHEMA alt_nsp2; -- failed (name conflict)
+ERROR: text search configuration alt_ts_conf2 already exists in schema "alt_nsp2"
+RESET SESSION AUTHORIZATION;
+SELECT nspname, cfgname, rolname
+ FROM pg_ts_config t, pg_namespace n, pg_authid a
+ WHERE t.cfgnamespace = n.oid AND t.cfgowner = a.oid
+ AND n.nspname in ('alt_nsp1', 'alt_nsp2')
+ ORDER BY nspname, cfgname;
+ nspname | cfgname | rolname
+----------+--------------+---------------------
+ alt_nsp1 | alt_ts_conf2 | regtest_alter_user2
+ alt_nsp1 | alt_ts_conf3 | regtest_alter_user1
+ alt_nsp1 | alt_ts_conf4 | regtest_alter_user2
+ alt_nsp2 | alt_ts_conf2 | regtest_alter_user3
+(4 rows)
+
+--
+-- Text Search Template
+--
+CREATE TEXT SEARCH TEMPLATE alt_ts_temp1 (lexize=dsimple_lexize);
+CREATE TEXT SEARCH TEMPLATE alt_ts_temp2 (lexize=dsimple_lexize);
+ALTER TEXT SEARCH TEMPLATE alt_ts_temp1 RENAME TO alt_ts_temp2; -- failed (name conflict)
+ERROR: text search template alt_ts_temp2 already exists in schema "alt_nsp1"
+ALTER TEXT SEARCH TEMPLATE alt_ts_temp1 RENAME TO alt_ts_temp3; -- OK
+ALTER TEXT SEARCH TEMPLATE alt_ts_temp2 SET SCHEMA alt_nsp2; -- OK
+CREATE TEXT SEARCH TEMPLATE alt_ts_temp2 (lexize=dsimple_lexize);
+ALTER TEXT SEARCH TEMPLATE alt_ts_temp2 SET SCHEMA alt_nsp2; -- failed (name conflict)
+ERROR: text search template alt_ts_temp2 already exists in schema "alt_nsp2"
+SELECT nspname, tmplname
+ FROM pg_ts_template t, pg_namespace n
+ WHERE t.tmplnamespace = n.oid AND nspname like 'alt_nsp%'
+ ORDER BY nspname, tmplname;
+ nspname | tmplname
+----------+--------------
+ alt_nsp1 | alt_ts_temp2
+ alt_nsp1 | alt_ts_temp3
+ alt_nsp2 | alt_ts_temp2
+(3 rows)
+
+--
+-- Text Search Parser
+--
+CREATE TEXT SEARCH PARSER alt_ts_prs1
+ (start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype);
+CREATE TEXT SEARCH PARSER alt_ts_prs2
+ (start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype);
+ALTER TEXT SEARCH PARSER alt_ts_prs1 RENAME TO alt_ts_prs2; -- failed (name conflict)
+ERROR: text search parser alt_ts_prs2 already exists in schema "alt_nsp1"
+ALTER TEXT SEARCH PARSER alt_ts_prs1 RENAME TO alt_ts_prs3; -- OK
+ALTER TEXT SEARCH PARSER alt_ts_prs2 SET SCHEMA alt_nsp2; -- OK
+CREATE TEXT SEARCH PARSER alt_ts_prs2
+ (start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype);
+ALTER TEXT SEARCH PARSER alt_ts_prs2 SET SCHEMA alt_nsp2; -- failed (name conflict)
+ERROR: text search parser alt_ts_prs2 already exists in schema "alt_nsp2"
+SELECT nspname, prsname
+ FROM pg_ts_parser t, pg_namespace n
+ WHERE t.prsnamespace = n.oid AND nspname like 'alt_nsp%'
+ ORDER BY nspname, prsname;
+ nspname | prsname
+----------+-------------
+ alt_nsp1 | alt_ts_prs2
+ alt_nsp1 | alt_ts_prs3
+ alt_nsp2 | alt_ts_prs2
+(3 rows)
+
+---
+--- Cleanup resources
+---
+DROP FOREIGN DATA WRAPPER alt_fdw2 CASCADE;
+NOTICE: drop cascades to server alt_fserv2
+DROP FOREIGN DATA WRAPPER alt_fdw3 CASCADE;
+NOTICE: drop cascades to server alt_fserv3
+DROP LANGUAGE alt_lang2 CASCADE;
+DROP LANGUAGE alt_lang3 CASCADE;
+DROP LANGUAGE alt_lang4 CASCADE;
+ERROR: language "alt_lang4" does not exist
+DROP SCHEMA alt_nsp1 CASCADE;
+NOTICE: drop cascades to 29 other objects
+DETAIL: drop cascades to function alt_func3(integer)
+drop cascades to function alt_agg3(integer)
+drop cascades to function alt_func4(integer)
+drop cascades to function alt_func2(integer)
+drop cascades to function alt_agg4(integer)
+drop cascades to function alt_agg2(integer)
+drop cascades to collation alt_coll3
+drop cascades to collation alt_coll4
+drop cascades to collation alt_coll2
+drop cascades to conversion alt_conv3
+drop cascades to conversion alt_conv4
+drop cascades to conversion alt_conv2
+drop cascades to operator @+@(integer,integer)
+drop cascades to operator @-@(integer,integer)
+drop cascades to operator family alt_opf3 for access method hash
+drop cascades to operator family alt_opc1 for access method hash
+drop cascades to operator family alt_opc2 for access method hash
+drop cascades to operator family alt_opf4 for access method hash
+drop cascades to operator family alt_opf2 for access method hash
+drop cascades to text search dictionary alt_ts_dict3
+drop cascades to text search dictionary alt_ts_dict4
+drop cascades to text search dictionary alt_ts_dict2
+drop cascades to text search configuration alt_ts_conf3
+drop cascades to text search configuration alt_ts_conf4
+drop cascades to text search configuration alt_ts_conf2
+drop cascades to text search template alt_ts_temp3
+drop cascades to text search template alt_ts_temp2
+drop cascades to text search parser alt_ts_prs3
+drop cascades to text search parser alt_ts_prs2
+DROP SCHEMA alt_nsp2 CASCADE;
+NOTICE: drop cascades to 10 other objects
+DETAIL: drop cascades to function alt_nsp2.alt_func2(integer)
+drop cascades to function alt_nsp2.alt_agg2(integer)
+drop cascades to collation alt_coll2
+drop cascades to conversion alt_conv2
+drop cascades to operator alt_nsp2.@-@(integer,integer)
+drop cascades to operator family alt_nsp2.alt_opf2 for access method hash
+drop cascades to text search dictionary alt_ts_dict2
+drop cascades to text search configuration alt_ts_conf2
+drop cascades to text search template alt_ts_temp2
+drop cascades to text search parser alt_ts_prs2
+DROP USER regtest_alter_user1;
+DROP USER regtest_alter_user2;
+DROP USER regtest_alter_user3;
diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule
index 8852e0a..78be6f0 100644
--- a/src/test/regress/parallel_schedule
+++ b/src/test/regress/parallel_schedule
@@ -99,7 +99,7 @@ test: select_views portals_p2 foreign_key cluster dependency guc bitmapops combo
# NB: temp.sql does a reconnect which transiently uses 2 connections,
# so keep this parallel group to at most 19 tests
# ----------
-test: plancache limit plpgsql copy2 temp domain rangefuncs prepare without_oid conversion truncate alter_table sequence polymorphism rowtypes returning largeobject with xml
+test: plancache limit plpgsql copy2 temp domain rangefuncs prepare without_oid conversion truncate alter_table alter_generic sequence polymorphism rowtypes returning largeobject with xml
# run stats by itself because its delay may be insufficient under heavy load
test: stats
diff --git a/src/test/regress/serial_schedule b/src/test/regress/serial_schedule
index 0bc5df7..c12bb33 100644
--- a/src/test/regress/serial_schedule
+++ b/src/test/regress/serial_schedule
@@ -124,6 +124,7 @@ test: without_oid
test: conversion
test: truncate
test: alter_table
+test: alter_generic
test: sequence
test: polymorphism
test: rowtypes
diff --git a/src/test/regress/sql/alter_generic.sql b/src/test/regress/sql/alter_generic.sql
new file mode 100644
index 0000000..8a19949
--- /dev/null
+++ b/src/test/regress/sql/alter_generic.sql
@@ -0,0 +1,413 @@
+--
+-- Test for ALTER RENAME TO/OWNER TO/SET SCHEMA
+--
+
+-- Clean up in case a prior regression run failed
+SET client_min_messages TO 'warning';
+
+DROP ROLE IF EXISTS regtest_alter_user1;
+DROP ROLE IF EXISTS regtest_alter_user2;
+DROP ROLE IF EXISTS regtest_alter_user3;
+
+RESET client_min_messages;
+
+CREATE USER regtest_alter_user3;
+CREATE USER regtest_alter_user2;
+CREATE USER regtest_alter_user1 IN ROLE regtest_alter_user3;
+
+CREATE SCHEMA alt_nsp1;
+CREATE SCHEMA alt_nsp2;
+
+GRANT ALL ON SCHEMA alt_nsp1, alt_nsp2 TO public;
+
+SET search_path = alt_nsp1, public;
+
+--
+-- Function and Aggregate
+--
+SET SESSION AUTHORIZATION regtest_alter_user1;
+CREATE FUNCTION alt_func1(int) RETURNS int LANGUAGE sql
+ AS 'SELECT $1 + 1';
+CREATE FUNCTION alt_func2(int) RETURNS int LANGUAGE sql
+ AS 'SELECT $1 - 1';
+CREATE AGGREGATE alt_agg1 (
+ sfunc1 = int4pl, basetype = int4, stype1 = int4, initcond = 0
+);
+CREATE AGGREGATE alt_agg2 (
+ sfunc1 = int4mi, basetype = int4, stype1 = int4, initcond = 0
+);
+ALTER AGGREGATE alt_func1(int) RENAME TO alt_func3; -- failed (not aggregate)
+ALTER AGGREGATE alt_func1(int) OWNER TO regtest_alter_user3; -- failed (not aggregate)
+ALTER AGGREGATE alt_func1(int) SET SCHEMA alt_nsp2; -- failed (not aggregate)
+
+ALTER FUNCTION alt_func1(int) RENAME TO alt_func2; -- failed (name conflict)
+ALTER FUNCTION alt_func1(int) RENAME TO alt_func3; -- OK
+ALTER FUNCTION alt_func2(int) OWNER TO regtest_alter_user2; -- failed (no role membership)
+ALTER FUNCTION alt_func2(int) OWNER TO regtest_alter_user3; -- OK
+ALTER FUNCTION alt_func2(int) SET SCHEMA alt_nsp2; -- OK
+
+ALTER AGGREGATE alt_agg1(int) RENAME TO alt_agg2; -- failed (name conflict)
+ALTER AGGREGATE alt_agg1(int) RENAME TO alt_agg3; -- OK
+ALTER AGGREGATE alt_agg2(int) OWNER TO regtest_alter_user2; -- failed (no role membership)
+ALTER AGGREGATE alt_agg2(int) OWNER TO regtest_alter_user3; -- OK
+ALTER AGGREGATE alt_agg2(int) SET SCHEMA alt_nsp2; -- OK
+
+SET SESSION AUTHORIZATION regtest_alter_user2;
+CREATE FUNCTION alt_func1(int) RETURNS int LANGUAGE sql
+ AS 'SELECT $1 + 2';
+CREATE FUNCTION alt_func2(int) RETURNS int LANGUAGE sql
+ AS 'SELECT $1 - 2';
+CREATE AGGREGATE alt_agg1 (
+ sfunc1 = int4pl, basetype = int4, stype1 = int4, initcond = 100
+);
+CREATE AGGREGATE alt_agg2 (
+ sfunc1 = int4mi, basetype = int4, stype1 = int4, initcond = -100
+);
+
+ALTER FUNCTION alt_func3(int) RENAME TO alt_func4; -- failed (not owner)
+ALTER FUNCTION alt_func1(int) RENAME TO alt_func4; -- OK
+ALTER FUNCTION alt_func3(int) OWNER TO regtest_alter_user2; -- failed (not owner)
+ALTER FUNCTION alt_func2(int) OWNER TO regtest_alter_user3; -- failed (no role membership)
+ALTER FUNCTION alt_func3(int) SET SCHEMA alt_nsp2; -- failed (not owner)
+ALTER FUNCTION alt_func2(int) SET SCHEMA alt_nsp2; -- failed (name conflicts)
+
+ALTER AGGREGATE alt_agg3(int) RENAME TO alt_agg4; -- failed (not owner)
+ALTER AGGREGATE alt_agg1(int) RENAME TO alt_agg4; -- OK
+ALTER AGGREGATE alt_agg3(int) OWNER TO regtest_alter_user2; -- failed (not owner)
+ALTER AGGREGATE alt_agg2(int) OWNER TO regtest_alter_user3; -- failed (no role membership)
+ALTER AGGREGATE alt_agg3(int) SET SCHEMA alt_nsp2; -- failed (not owner)
+ALTER AGGREGATE alt_agg2(int) SET SCHEMA alt_nsp2; -- failed (name conflict)
+
+RESET SESSION AUTHORIZATION;
+
+SELECT n.nspname, proname, prorettype::regtype, proisagg, a.rolname
+ FROM pg_proc p, pg_namespace n, pg_authid a
+ WHERE p.pronamespace = n.oid AND p.proowner = a.oid
+ AND n.nspname IN ('alt_nsp1', 'alt_nsp2')
+ ORDER BY nspname, proname;
+
+--
+-- Collation
+--
+SET SESSION AUTHORIZATION regtest_alter_user1;
+CREATE COLLATION alt_coll1 (locale = 'C');
+CREATE COLLATION alt_coll2 (locale = 'C');
+
+ALTER COLLATION alt_coll1 RENAME TO alt_coll2; -- failed (name conflict)
+ALTER COLLATION alt_coll1 RENAME TO alt_coll3; -- OK
+ALTER COLLATION alt_coll2 OWNER TO regtest_alter_user2; -- failed (no role membership)
+ALTER COLLATION alt_coll2 OWNER TO regtest_alter_user3; -- OK
+ALTER COLLATION alt_coll2 SET SCHEMA alt_nsp2; -- OK
+
+SET SESSION AUTHORIZATION regtest_alter_user2;
+CREATE COLLATION alt_coll1 (locale = 'C');
+CREATE COLLATION alt_coll2 (locale = 'C');
+
+ALTER COLLATION alt_coll3 RENAME TO alt_coll4; -- failed (not owner)
+ALTER COLLATION alt_coll1 RENAME TO alt_coll4; -- OK
+ALTER COLLATION alt_coll3 OWNER TO regtest_alter_user2; -- failed (not owner)
+ALTER COLLATION alt_coll2 OWNER TO regtest_alter_user3; -- failed (no role membership)
+ALTER COLLATION alt_coll3 SET SCHEMA alt_nsp2; -- failed (not owner)
+ALTER COLLATION alt_coll2 SET SCHEMA alt_nsp2; -- failed (name conflict)
+
+RESET SESSION AUTHORIZATION;
+
+SELECT n.nspname, c.collname, a.rolname
+ FROM pg_collation c, pg_namespace n, pg_authid a
+ WHERE c.collnamespace = n.oid AND c.collowner = a.oid
+ AND n.nspname IN ('alt_nsp1', 'alt_nsp2')
+ ORDER BY n.nspname, c.collname;
+
+--
+-- Conversion
+--
+SET SESSION AUTHORIZATION regtest_alter_user1;
+CREATE CONVERSION alt_conv1 FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8;
+CREATE CONVERSION alt_conv2 FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8;
+
+ALTER CONVERSION alt_conv1 RENAME TO alt_conv2; -- failed (name conflict)
+ALTER CONVERSION alt_conv1 RENAME TO alt_conv3; -- OK
+ALTER CONVERSION alt_conv2 OWNER TO regtest_alter_user2; -- failed (no role membership)
+ALTER CONVERSION alt_conv2 OWNER TO regtest_alter_user3; -- OK
+ALTER CONVERSION alt_conv2 SET SCHEMA alt_nsp2; -- OK
+
+SET SESSION AUTHORIZATION regtest_alter_user2;
+CREATE CONVERSION alt_conv1 FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8;
+CREATE CONVERSION alt_conv2 FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8;
+
+ALTER CONVERSION alt_conv3 RENAME TO alt_conv4; -- failed (not owner)
+ALTER CONVERSION alt_conv1 RENAME TO alt_conv4; -- OK
+ALTER CONVERSION alt_conv3 OWNER TO regtest_alter_user2; -- failed (not owner)
+ALTER CONVERSION alt_conv2 OWNER TO regtest_alter_user3; -- failed (no role membership)
+ALTER CONVERSION alt_conv3 SET SCHEMA alt_nsp2; -- failed (not owner)
+ALTER CONVERSION alt_conv2 SET SCHEMA alt_nsp2; -- failed (name conflict)
+
+RESET SESSION AUTHORIZATION;
+
+SELECT n.nspname, c.conname, a.rolname
+ FROM pg_conversion c, pg_namespace n, pg_authid a
+ WHERE c.connamespace = n.oid AND c.conowner = a.oid
+ AND n.nspname IN ('alt_nsp1', 'alt_nsp2')
+ ORDER BY nspname, conname;
+
+--
+-- Foreign Data Wrapper and Foreign Server
+--
+CREATE FOREIGN DATA WRAPPER alt_fdw1;
+CREATE FOREIGN DATA WRAPPER alt_fdw2;
+
+CREATE SERVER alt_fserv1 FOREIGN DATA WRAPPER alt_fdw1;
+CREATE SERVER alt_fserv2 FOREIGN DATA WRAPPER alt_fdw2;
+
+ALTER FOREIGN DATA WRAPPER alt_fdw1 RENAME TO alt_fdw2; -- failed (name conflict)
+ALTER FOREIGN DATA WRAPPER alt_fdw1 RENAME TO alt_fdw3; -- OK
+
+ALTER SERVER alt_fserv1 RENAME TO alt_fserv2; -- failed (name conflict)
+ALTER SERVER alt_fserv1 RENAME TO alt_fserv3; -- OK
+
+SELECT fdwname FROM pg_foreign_data_wrapper WHERE fdwname like 'alt_fdw%';
+SELECT srvname FROM pg_foreign_server WHERE srvname like 'alt_fserv%';
+
+--
+-- Procedural Language
+--
+CREATE LANGUAGE alt_lang1 HANDLER plpgsql_call_handler;
+CREATE LANGUAGE alt_lang2 HANDLER plpgsql_call_handler;
+
+ALTER LANGUAGE alt_lang1 OWNER TO regtest_alter_user1; -- OK
+ALTER LANGUAGE alt_lang2 OWNER TO regtest_alter_user2; -- OK
+
+SET SESSION AUTHORIZATION regtest_alter_user1;
+ALTER LANGUAGE alt_lang1 RENAME TO alt_lang2; -- failed (name conflict)
+ALTER LANGUAGE alt_lang2 RENAME TO alt_lang3; -- failed (not owner)
+ALTER LANGUAGE alt_lang1 RENAME TO alt_lang3; -- OK
+
+ALTER LANGUAGE alt_lang2 OWNER TO regtest_alter_user3; -- failed (not owner)
+ALTER LANGUAGE alt_lang3 OWNER TO regtest_alter_user2; -- failed (no role membership)
+ALTER LANGUAGE alt_lang3 OWNER TO regtest_alter_user3; -- OK
+
+RESET SESSION AUTHORIZATION;
+SELECT lanname, a.rolname
+ FROM pg_language l, pg_authid a
+ WHERE l.lanowner = a.oid AND l.lanname like 'alt_lang%'
+ ORDER BY lanname;
+
+--
+-- Operator
+--
+SET SESSION AUTHORIZATION regtest_alter_user1;
+
+CREATE OPERATOR @-@ ( leftarg = int4, rightarg = int4, procedure = int4mi );
+CREATE OPERATOR @+@ ( leftarg = int4, rightarg = int4, procedure = int4pl );
+
+ALTER OPERATOR @+@(int4, int4) OWNER TO regtest_alter_user2; -- failed (no role membership)
+ALTER OPERATOR @+@(int4, int4) OWNER TO regtest_alter_user3; -- OK
+ALTER OPERATOR @-@(int4, int4) SET SCHEMA alt_nsp2; -- OK
+
+SET SESSION AUTHORIZATION regtest_alter_user2;
+
+CREATE OPERATOR @-@ ( leftarg = int4, rightarg = int4, procedure = int4mi );
+
+ALTER OPERATOR @+@(int4, int4) OWNER TO regtest_alter_user2; -- failed (not owner)
+ALTER OPERATOR @-@(int4, int4) OWNER TO regtest_alter_user3; -- failed (no role membership)
+ALTER OPERATOR @+@(int4, int4) SET SCHEMA alt_nsp2; -- failed (not owner)
+-- ALTER OPERATOR @-@(int4, int4) SET SCHEMA alt_nsp2; -- failed (name conflict)
+-- XXX it raises raw oid of namespace, it makes unneeded regression test fail...
+
+RESET SESSION AUTHORIZATION;
+
+SELECT n.nspname, oprname, a.rolname, oprleft::regtype, oprright::regtype, oprcode::regproc
+ FROM pg_operator o, pg_namespace n, pg_authid a
+ WHERE o.oprnamespace = n.oid AND o.oprowner = a.oid
+ AND n.nspname IN ('alt_nsp1', 'alt_nsp2')
+ ORDER BY nspname, oprname;
+
+--
+-- OpFamily and OpClass
+--
+CREATE OPERATOR FAMILY alt_opf1 USING hash;
+CREATE OPERATOR FAMILY alt_opf2 USING hash;
+ALTER OPERATOR FAMILY alt_opf1 USING hash OWNER TO regtest_alter_user1;
+ALTER OPERATOR FAMILY alt_opf2 USING hash OWNER TO regtest_alter_user1;
+
+CREATE OPERATOR CLASS alt_opc1 FOR TYPE uuid USING hash AS STORAGE uuid;
+CREATE OPERATOR CLASS alt_opc2 FOR TYPE uuid USING hash AS STORAGE uuid;
+ALTER OPERATOR CLASS alt_opc1 USING hash OWNER TO regtest_alter_user1;
+ALTER OPERATOR CLASS alt_opc2 USING hash OWNER TO regtest_alter_user1;
+
+SET SESSION AUTHORIZATION regtest_alter_user1;
+
+ALTER OPERATOR FAMILY alt_opf1 USING hash RENAME TO alt_opf2; -- failed (name conflict)
+ALTER OPERATOR FAMILY alt_opf1 USING hash RENAME TO alt_opf3; -- OK
+ALTER OPERATOR FAMILY alt_opf2 USING hash OWNER TO regtest_alter_user2; -- failed (no role membership)
+ALTER OPERATOR FAMILY alt_opf2 USING hash OWNER TO regtest_alter_user3; -- OK
+ALTER OPERATOR FAMILY alt_opf2 USING hash SET SCHEMA alt_nsp2; -- OK
+
+ALTER OPERATOR CLASS alt_opc1 USING hash RENAME TO alt_opc2; -- failed (name conflict)
+ALTER OPERATOR CLASS alt_opc1 USING hash RENAME TO alt_opc3; -- OK
+ALTER OPERATOR CLASS alt_opc2 USING hash OWNER TO regtest_alter_user2; -- failed (no role membership)
+ALTER OPERATOR CLASS alt_opc2 USING hash OWNER TO regtest_alter_user3; -- OK
+ALTER OPERATOR CLASS alt_opc2 USING hash SET SCHEMA alt_nsp2; -- OK
+
+RESET SESSION AUTHORIZATION;
+
+CREATE OPERATOR FAMILY alt_opf1 USING hash;
+CREATE OPERATOR FAMILY alt_opf2 USING hash;
+ALTER OPERATOR FAMILY alt_opf1 USING hash OWNER TO regtest_alter_user2;
+ALTER OPERATOR FAMILY alt_opf2 USING hash OWNER TO regtest_alter_user2;
+
+CREATE OPERATOR CLASS alt_opc1 FOR TYPE macaddr USING hash AS STORAGE macaddr;
+CREATE OPERATOR CLASS alt_opc2 FOR TYPE macaddr USING hash AS STORAGE macaddr;
+ALTER OPERATOR CLASS alt_opc1 USING hash OWNER TO regtest_alter_user2;
+ALTER OPERATOR CLASS alt_opc2 USING hash OWNER TO regtest_alter_user2;
+
+SET SESSION AUTHORIZATION regtest_alter_user2;
+
+ALTER OPERATOR FAMILY alt_opf3 USING hash RENAME TO alt_opf4; -- failed (not owner)
+ALTER OPERATOR FAMILY alt_opf1 USING hash RENAME TO alt_opf4; -- OK
+ALTER OPERATOR FAMILY alt_opf3 USING hash OWNER TO regtest_alter_user2; -- failed (not owner)
+ALTER OPERATOR FAMILY alt_opf2 USING hash OWNER TO regtest_alter_user3; -- failed (no role membership)
+ALTER OPERATOR FAMILY alt_opf3 USING hash SET SCHEMA alt_nsp2; -- failed (not owner)
+-- ALTER OPERATOR FAMILY alt_opf2 USING hash SET SCHEMA alt_nsp2; -- failed (name conflict)
+
+ALTER OPERATOR CLASS alt_opc3 USING hash RENAME TO alt_opc4; -- failed (not owner)
+ALTER OPERATOR CLASS alt_opc1 USING hash RENAME TO alt_opc4; -- OK
+ALTER OPERATOR CLASS alt_opc3 USING hash OWNER TO regtest_alter_user2; -- failed (not owner)
+ALTER OPERATOR CLASS alt_opc2 USING hash OWNER TO regtest_alter_user3; -- failed (no role membership)
+ALTER OPERATOR CLASS alt_opc3 USING hash SET SCHEMA alt_nsp2; -- failed (not owner)
+-- ALTER OPERATOR CLASS alt_opc2 USING hash SET SCHEMA alt_nsp2; -- failed (name conflict)
+
+RESET SESSION AUTHORIZATION;
+
+SELECT nspname, opfname, amname, rolname
+ FROM pg_opfamily o, pg_am m, pg_namespace n, pg_authid a
+ WHERE o.opfmethod = m.oid AND o.opfnamespace = n.oid AND o.opfowner = a.oid
+ AND n.nspname IN ('alt_nsp1', 'alt_nsp2')
+ ORDER BY nspname, opfname;
+
+SELECT nspname, opcname, amname, rolname
+ FROM pg_opclass o, pg_am m, pg_namespace n, pg_authid a
+ WHERE o.opcmethod = m.oid AND o.opcnamespace = n.oid AND o.opcowner = a.oid
+ AND n.nspname IN ('alt_nsp1', 'alt_nsp2')
+ ORDER BY nspname, opcname;
+
+--
+-- Text Search Dictionary
+--
+SET SESSION AUTHORIZATION regtest_alter_user1;
+CREATE TEXT SEARCH DICTIONARY alt_ts_dict1 (template=simple);
+CREATE TEXT SEARCH DICTIONARY alt_ts_dict2 (template=simple);
+
+ALTER TEXT SEARCH DICTIONARY alt_ts_dict1 RENAME TO alt_ts_dict2; -- failed (name conflict)
+ALTER TEXT SEARCH DICTIONARY alt_ts_dict1 RENAME TO alt_ts_dict3; -- OK
+ALTER TEXT SEARCH DICTIONARY alt_ts_dict2 OWNER TO regtest_alter_user2; -- failed (no role membership)
+ALTER TEXT SEARCH DICTIONARY alt_ts_dict2 OWNER TO regtest_alter_user3; -- OK
+ALTER TEXT SEARCH DICTIONARY alt_ts_dict2 SET SCHEMA alt_nsp2; -- OK
+
+SET SESSION AUTHORIZATION regtest_alter_user2;
+CREATE TEXT SEARCH DICTIONARY alt_ts_dict1 (template=simple);
+CREATE TEXT SEARCH DICTIONARY alt_ts_dict2 (template=simple);
+
+ALTER TEXT SEARCH DICTIONARY alt_ts_dict3 RENAME TO alt_ts_dict4; -- failed (not owner)
+ALTER TEXT SEARCH DICTIONARY alt_ts_dict1 RENAME TO alt_ts_dict4; -- OK
+ALTER TEXT SEARCH DICTIONARY alt_ts_dict3 OWNER TO regtest_alter_user2; -- failed (not owner)
+ALTER TEXT SEARCH DICTIONARY alt_ts_dict2 OWNER TO regtest_alter_user3; -- failed (no role membership)
+ALTER TEXT SEARCH DICTIONARY alt_ts_dict3 SET SCHEMA alt_nsp2; -- failed (not owner)
+ALTER TEXT SEARCH DICTIONARY alt_ts_dict2 SET SCHEMA alt_nsp2; -- failed (name conflict)
+
+RESET SESSION AUTHORIZATION;
+
+SELECT nspname, dictname, rolname
+ FROM pg_ts_dict t, pg_namespace n, pg_authid a
+ WHERE t.dictnamespace = n.oid AND t.dictowner = a.oid
+ AND n.nspname in ('alt_nsp1', 'alt_nsp2')
+ ORDER BY nspname, dictname;
+
+--
+-- Text Search Configuration
+--
+SET SESSION AUTHORIZATION regtest_alter_user1;
+CREATE TEXT SEARCH CONFIGURATION alt_ts_conf1 (copy=english);
+CREATE TEXT SEARCH CONFIGURATION alt_ts_conf2 (copy=english);
+
+ALTER TEXT SEARCH CONFIGURATION alt_ts_conf1 RENAME TO alt_ts_conf2; -- failed (name conflict)
+ALTER TEXT SEARCH CONFIGURATION alt_ts_conf1 RENAME TO alt_ts_conf3; -- OK
+ALTER TEXT SEARCH CONFIGURATION alt_ts_conf2 OWNER TO regtest_alter_user2; -- failed (no role membership)
+ALTER TEXT SEARCH CONFIGURATION alt_ts_conf2 OWNER TO regtest_alter_user3; -- OK
+ALTER TEXT SEARCH CONFIGURATION alt_ts_conf2 SET SCHEMA alt_nsp2; -- OK
+
+SET SESSION AUTHORIZATION regtest_alter_user2;
+CREATE TEXT SEARCH CONFIGURATION alt_ts_conf1 (copy=english);
+CREATE TEXT SEARCH CONFIGURATION alt_ts_conf2 (copy=english);
+
+ALTER TEXT SEARCH CONFIGURATION alt_ts_conf3 RENAME TO alt_ts_conf4; -- failed (not owner)
+ALTER TEXT SEARCH CONFIGURATION alt_ts_conf1 RENAME TO alt_ts_conf4; -- OK
+ALTER TEXT SEARCH CONFIGURATION alt_ts_conf3 OWNER TO regtest_alter_user2; -- failed (not owner)
+ALTER TEXT SEARCH CONFIGURATION alt_ts_conf2 OWNER TO regtest_alter_user3; -- failed (no role membership)
+ALTER TEXT SEARCH CONFIGURATION alt_ts_conf3 SET SCHEMA alt_nsp2; -- failed (not owner)
+ALTER TEXT SEARCH CONFIGURATION alt_ts_conf2 SET SCHEMA alt_nsp2; -- failed (name conflict)
+
+RESET SESSION AUTHORIZATION;
+
+SELECT nspname, cfgname, rolname
+ FROM pg_ts_config t, pg_namespace n, pg_authid a
+ WHERE t.cfgnamespace = n.oid AND t.cfgowner = a.oid
+ AND n.nspname in ('alt_nsp1', 'alt_nsp2')
+ ORDER BY nspname, cfgname;
+
+--
+-- Text Search Template
+--
+CREATE TEXT SEARCH TEMPLATE alt_ts_temp1 (lexize=dsimple_lexize);
+CREATE TEXT SEARCH TEMPLATE alt_ts_temp2 (lexize=dsimple_lexize);
+
+ALTER TEXT SEARCH TEMPLATE alt_ts_temp1 RENAME TO alt_ts_temp2; -- failed (name conflict)
+ALTER TEXT SEARCH TEMPLATE alt_ts_temp1 RENAME TO alt_ts_temp3; -- OK
+ALTER TEXT SEARCH TEMPLATE alt_ts_temp2 SET SCHEMA alt_nsp2; -- OK
+
+CREATE TEXT SEARCH TEMPLATE alt_ts_temp2 (lexize=dsimple_lexize);
+ALTER TEXT SEARCH TEMPLATE alt_ts_temp2 SET SCHEMA alt_nsp2; -- failed (name conflict)
+
+SELECT nspname, tmplname
+ FROM pg_ts_template t, pg_namespace n
+ WHERE t.tmplnamespace = n.oid AND nspname like 'alt_nsp%'
+ ORDER BY nspname, tmplname;
+
+--
+-- Text Search Parser
+--
+
+CREATE TEXT SEARCH PARSER alt_ts_prs1
+ (start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype);
+CREATE TEXT SEARCH PARSER alt_ts_prs2
+ (start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype);
+
+ALTER TEXT SEARCH PARSER alt_ts_prs1 RENAME TO alt_ts_prs2; -- failed (name conflict)
+ALTER TEXT SEARCH PARSER alt_ts_prs1 RENAME TO alt_ts_prs3; -- OK
+ALTER TEXT SEARCH PARSER alt_ts_prs2 SET SCHEMA alt_nsp2; -- OK
+
+CREATE TEXT SEARCH PARSER alt_ts_prs2
+ (start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype);
+ALTER TEXT SEARCH PARSER alt_ts_prs2 SET SCHEMA alt_nsp2; -- failed (name conflict)
+
+SELECT nspname, prsname
+ FROM pg_ts_parser t, pg_namespace n
+ WHERE t.prsnamespace = n.oid AND nspname like 'alt_nsp%'
+ ORDER BY nspname, prsname;
+
+---
+--- Cleanup resources
+---
+DROP FOREIGN DATA WRAPPER alt_fdw2 CASCADE;
+DROP FOREIGN DATA WRAPPER alt_fdw3 CASCADE;
+
+DROP LANGUAGE alt_lang2 CASCADE;
+DROP LANGUAGE alt_lang3 CASCADE;
+DROP LANGUAGE alt_lang4 CASCADE;
+
+DROP SCHEMA alt_nsp1 CASCADE;
+DROP SCHEMA alt_nsp2 CASCADE;
+
+DROP USER regtest_alter_user1;
+DROP USER regtest_alter_user2;
+DROP USER regtest_alter_user3;