From 765cbfdc9263bf7c90b9d1f1044c6950b8b7088c Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Mon, 21 Jan 2013 12:06:41 -0300 Subject: [PATCH] Refactor ALTER some-obj RENAME implementation MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Remove duplicate implementations of catalog munging and miscellaneous privilege checks. Instead rely on already existing data in objectaddress.c to do the work. Author: KaiGai Kohei, changes by me Reviewed by: Robert Haas, Álvaro Herrera, Dimitri Fontaine --- src/backend/catalog/objectaddress.c | 4 +- src/backend/commands/aggregatecmds.c | 63 ---- src/backend/commands/alter.c | 374 +++++++++++++++----- src/backend/commands/collationcmds.c | 48 --- src/backend/commands/conversioncmds.c | 53 --- src/backend/commands/event_trigger.c | 46 --- src/backend/commands/foreigncmds.c | 87 ----- src/backend/commands/functioncmds.c | 61 +--- src/backend/commands/opclasscmds.c | 171 +++------ src/backend/commands/proclang.c | 42 --- src/backend/commands/tsearchcmds.c | 196 ---------- src/backend/parser/gram.y | 12 +- src/include/commands/collationcmds.h | 3 +- src/include/commands/conversioncmds.h | 1 - src/include/commands/defrem.h | 14 +- src/include/commands/event_trigger.h | 1 - src/include/commands/proclang.h | 1 - src/test/regress/expected/alter_generic.out | 16 +- src/test/regress/sql/alter_generic.sql | 6 +- 19 files changed, 348 insertions(+), 851 deletions(-) diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c index 01aba15f35..d902f9d6ba 100644 --- a/src/backend/catalog/objectaddress.c +++ b/src/backend/catalog/objectaddress.c @@ -80,7 +80,9 @@ 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 (name,namespace) */ + int name_catcache_id; /* id of catcache on (name,namespace), + * or (name) if the object does not + * live in a namespace */ AttrNumber attnum_name; /* attnum of name field */ AttrNumber attnum_namespace; /* attnum of namespace field */ AttrNumber attnum_owner; /* attnum of owner field */ diff --git a/src/backend/commands/aggregatecmds.c b/src/backend/commands/aggregatecmds.c index 144768303a..e25108192e 100644 --- a/src/backend/commands/aggregatecmds.c +++ b/src/backend/commands/aggregatecmds.c @@ -226,66 +226,3 @@ DefineAggregate(List *name, List *args, bool oldstyle, List *parameters) transTypeId, /* transition data type */ initval); /* initial condition */ } - - -/* - * RenameAggregate - * Rename an aggregate. - */ -Oid -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); - - return procOid; -} diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c index b565e9b2c3..c2d4bb3ed4 100644 --- a/src/backend/commands/alter.c +++ b/src/backend/commands/alter.c @@ -21,9 +21,15 @@ #include "catalog/namespace.h" #include "catalog/pg_collation.h" #include "catalog/pg_conversion.h" +#include "catalog/pg_event_trigger.h" +#include "catalog/pg_foreign_data_wrapper.h" +#include "catalog/pg_foreign_server.h" +#include "catalog/pg_language.h" #include "catalog/pg_largeobject.h" #include "catalog/pg_largeobject_metadata.h" #include "catalog/pg_namespace.h" +#include "catalog/pg_opclass.h" +#include "catalog/pg_opfamily.h" #include "catalog/pg_proc.h" #include "catalog/pg_ts_config.h" #include "catalog/pg_ts_dict.h" @@ -43,6 +49,7 @@ #include "commands/trigger.h" #include "commands/typecmds.h" #include "commands/user.h" +#include "parser/parse_func.h" #include "miscadmin.h" #include "tcop/utility.h" #include "utils/builtins.h" @@ -56,49 +63,246 @@ static Oid AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid); /* - * Executes an ALTER OBJECT / RENAME TO statement. Based on the object - * type, the function appropriate to that type is executed. + * Raise an error to the effect that an object of the given name is already + * present in the given namespace. */ -Oid -ExecRenameStmt(RenameStmt *stmt) +static void +report_name_conflict(Oid classId, const char *name) { - switch (stmt->renameType) + char *msgfmt; + + switch (classId) { - case OBJECT_AGGREGATE: - return RenameAggregate(stmt->object, stmt->objarg, stmt->newname); + case EventTriggerRelationId: + msgfmt = gettext_noop("event trigger \"%s\" already exists"); + break; + case ForeignDataWrapperRelationId: + msgfmt = gettext_noop("foreign-data wrapper \"%s\" already exists"); + break; + case ForeignServerRelationId: + msgfmt = gettext_noop("server \"%s\" already exists"); + break; + case LanguageRelationId: + msgfmt = gettext_noop("language \"%s\" already exists"); + break; + default: + elog(ERROR, "unsupported object class %u", classId); + break; + } - case OBJECT_COLLATION: - return RenameCollation(stmt->object, stmt->newname); + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_OBJECT), + errmsg(msgfmt, name))); +} - case OBJECT_CONSTRAINT: - return RenameConstraint(stmt); +static void +report_namespace_conflict(Oid classId, const char *name, Oid nspOid) +{ + char *msgfmt; - case OBJECT_CONVERSION: - return RenameConversion(stmt->object, stmt->newname); + Assert(OidIsValid(nspOid)); - case OBJECT_DATABASE: - return RenameDatabase(stmt->subname, stmt->newname); + switch (classId) + { + case ConversionRelationId: + Assert(OidIsValid(nspOid)); + msgfmt = gettext_noop("conversion \"%s\" already exists in schema \"%s\""); + break; + case TSParserRelationId: + Assert(OidIsValid(nspOid)); + msgfmt = gettext_noop("text search parser \"%s\" already exists in schema \"%s\""); + break; + case TSDictionaryRelationId: + Assert(OidIsValid(nspOid)); + msgfmt = gettext_noop("text search dictionary \"%s\" already exists in schema \"%s\""); + break; + case TSTemplateRelationId: + Assert(OidIsValid(nspOid)); + msgfmt = gettext_noop("text search template \"%s\" already exists in schema \"%s\""); + break; + case TSConfigRelationId: + Assert(OidIsValid(nspOid)); + msgfmt = gettext_noop("text search configuration \"%s\" already exists in schema \"%s\""); + break; + default: + elog(ERROR, "unsupported object class %u", classId); + break; + } - case OBJECT_FDW: - return RenameForeignDataWrapper(stmt->subname, stmt->newname); + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_OBJECT), + errmsg(msgfmt, name, get_namespace_name(nspOid)))); +} - case OBJECT_FOREIGN_SERVER: - return RenameForeignServer(stmt->subname, stmt->newname); +/* + * AlterObjectRename_internal + * + * Generic function to rename the given object, for simple cases (won't + * work for tables, nor other cases where we need to do more than change + * the name column of a single catalog entry). + * + * rel: catalog relation containing object (RowExclusiveLock'd by caller) + * objectId: OID of object to be renamed + * new_name: CString representation of new name + */ +static void +AlterObjectRename_internal(Relation rel, Oid objectId, const char *new_name) +{ + Oid classId = RelationGetRelid(rel); + int oidCacheId = get_object_catcache_oid(classId); + int nameCacheId = get_object_catcache_name(classId); + AttrNumber Anum_name = get_object_attnum_name(classId); + AttrNumber Anum_namespace = get_object_attnum_namespace(classId); + AttrNumber Anum_owner = get_object_attnum_owner(classId); + AclObjectKind acl_kind = get_object_aclkind(classId); + HeapTuple oldtup; + HeapTuple newtup; + Datum datum; + bool isnull; + Oid namespaceId; + Oid ownerId; + char *old_name; + AclResult aclresult; + Datum *values; + bool *nulls; + bool *replaces; - case OBJECT_EVENT_TRIGGER: - return RenameEventTrigger(stmt->subname, stmt->newname); + oldtup = SearchSysCache1(oidCacheId, ObjectIdGetDatum(objectId)); + if (!HeapTupleIsValid(oldtup)) + elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"", + objectId, RelationGetRelationName(rel)); - case OBJECT_FUNCTION: - return RenameFunction(stmt->object, stmt->objarg, stmt->newname); + datum = heap_getattr(oldtup, Anum_name, + RelationGetDescr(rel), &isnull); + Assert(!isnull); + old_name = NameStr(*(DatumGetName(datum))); - case OBJECT_LANGUAGE: - return RenameLanguage(stmt->subname, stmt->newname); + /* Get OID of namespace */ + if (Anum_namespace > 0) + { + datum = heap_getattr(oldtup, Anum_namespace, + RelationGetDescr(rel), &isnull); + Assert(!isnull); + namespaceId = DatumGetObjectId(datum); + } + else + namespaceId = InvalidOid; - case OBJECT_OPCLASS: - return RenameOpClass(stmt->object, stmt->subname, stmt->newname); + /* Permission checks ... superusers can always do it */ + if (!superuser()) + { + /* Fail if object does not have an explicit owner */ + if (Anum_owner <= 0) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + (errmsg("must be superuser to rename %s", + getObjectDescriptionOids(classId, objectId))))); - case OBJECT_OPFAMILY: - return RenameOpFamily(stmt->object, stmt->subname, stmt->newname); + /* Otherwise, must be owner of the existing object */ + datum = heap_getattr(oldtup, Anum_owner, + RelationGetDescr(rel), &isnull); + Assert(!isnull); + ownerId = DatumGetObjectId(datum); + + if (!has_privs_of_role(GetUserId(), DatumGetObjectId(ownerId))) + aclcheck_error(ACLCHECK_NOT_OWNER, acl_kind, old_name); + + /* User must have CREATE privilege on the namespace */ + if (OidIsValid(namespaceId)) + { + aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), + ACL_CREATE); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, ACL_KIND_NAMESPACE, + get_namespace_name(namespaceId)); + } + } + + /* + * Check for duplicate name (more friendly than unique-index failure). + * Since this is just a friendliness check, we can just skip it in cases + * where there isn't suitable support. + */ + if (classId == ProcedureRelationId) + { + Form_pg_proc proc = (Form_pg_proc) GETSTRUCT(oldtup); + + IsThereFunctionInNamespace(new_name, proc->pronargs, + proc->proargtypes, proc->pronamespace); + } + else if (classId == CollationRelationId) + { + Form_pg_collation coll = (Form_pg_collation) GETSTRUCT(oldtup); + + IsThereCollationInNamespace(new_name, coll->collnamespace); + } + else if (classId == OperatorClassRelationId) + { + Form_pg_opclass opc = (Form_pg_opclass) GETSTRUCT(oldtup); + + IsThereOpClassInNamespace(new_name, opc->opcmethod, + opc->opcnamespace); + } + else if (classId == OperatorFamilyRelationId) + { + Form_pg_opfamily opf = (Form_pg_opfamily) GETSTRUCT(oldtup); + + IsThereOpFamilyInNamespace(new_name, opf->opfmethod, + opf->opfnamespace); + } + else if (nameCacheId >= 0) + { + if (OidIsValid(namespaceId)) + { + if (SearchSysCacheExists2(nameCacheId, + CStringGetDatum(new_name), + ObjectIdGetDatum(namespaceId))) + report_namespace_conflict(classId, new_name, namespaceId); + } + else + { + if (SearchSysCacheExists1(nameCacheId, + CStringGetDatum(new_name))) + report_name_conflict(classId, new_name); + } + } + + /* Build modified tuple */ + values = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(Datum)); + nulls = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool)); + replaces = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool)); + values[Anum_name - 1] = PointerGetDatum(new_name); + replaces[Anum_name - 1] = true; + newtup = heap_modify_tuple(oldtup, RelationGetDescr(rel), + values, nulls, replaces); + + /* Perform actual update */ + simple_heap_update(rel, &oldtup->t_self, newtup); + CatalogUpdateIndexes(rel, newtup); + + /* Release memory */ + pfree(values); + pfree(nulls); + pfree(replaces); + heap_freetuple(newtup); + + ReleaseSysCache(oldtup); +} + +/* + * Executes an ALTER OBJECT / RENAME TO statement. Based on the object + * type, the function appropriate to that type is executed. + */ +Oid +ExecRenameStmt(RenameStmt *stmt) +{ + switch (stmt->renameType) + { + case OBJECT_CONSTRAINT: + return RenameConstraint(stmt); + + case OBJECT_DATABASE: + return RenameDatabase(stmt->subname, stmt->newname); case OBJECT_ROLE: return RenameRole(stmt->subname, stmt->newname); @@ -123,21 +327,43 @@ ExecRenameStmt(RenameStmt *stmt) case OBJECT_TRIGGER: return renametrig(stmt); - case OBJECT_TSPARSER: - return RenameTSParser(stmt->object, stmt->newname); + case OBJECT_DOMAIN: + case OBJECT_TYPE: + return RenameType(stmt); + case OBJECT_AGGREGATE: + case OBJECT_COLLATION: + case OBJECT_CONVERSION: + case OBJECT_EVENT_TRIGGER: + case OBJECT_FDW: + case OBJECT_FOREIGN_SERVER: + case OBJECT_FUNCTION: + case OBJECT_OPCLASS: + case OBJECT_OPFAMILY: + case OBJECT_LANGUAGE: + case OBJECT_TSCONFIGURATION: case OBJECT_TSDICTIONARY: - return RenameTSDictionary(stmt->object, stmt->newname); - + case OBJECT_TSPARSER: case OBJECT_TSTEMPLATE: - return RenameTSTemplate(stmt->object, stmt->newname); + { + ObjectAddress address; + Relation catalog; + Relation relation; - case OBJECT_TSCONFIGURATION: - return RenameTSConfiguration(stmt->object, stmt->newname); + address = get_object_address(stmt->renameType, + stmt->object, stmt->objarg, + &relation, + AccessExclusiveLock, false); + Assert(relation == NULL); - case OBJECT_DOMAIN: - case OBJECT_TYPE: - return RenameType(stmt); + catalog = heap_open(address.classId, RowExclusiveLock); + AlterObjectRename_internal(catalog, + address.objectId, + stmt->newname); + heap_close(catalog, RowExclusiveLock); + + return address.objectId; + } default: elog(ERROR, "unrecognized rename stmt type: %d", @@ -287,43 +513,6 @@ AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid, return oldNspOid; } -/* - * Raise an error to the effect that an object of the given name is already - * present in the given namespace. - */ -static void -report_namespace_conflict(Oid classId, const char *name, Oid nspOid) -{ - char *msgfmt; - - Assert(OidIsValid(nspOid)); - switch (classId) - { - case ConversionRelationId: - msgfmt = gettext_noop("conversion \"%s\" already exists in schema \"%s\""); - break; - case TSParserRelationId: - msgfmt = gettext_noop("text search parser \"%s\" already exists in schema \"%s\""); - break; - case TSDictionaryRelationId: - msgfmt = gettext_noop("text search dictionary \"%s\" already exists in schema \"%s\""); - break; - case TSTemplateRelationId: - msgfmt = gettext_noop("text search template \"%s\" already exists in schema \"%s\""); - break; - case TSConfigRelationId: - msgfmt = gettext_noop("text search configuration \"%s\" already exists in schema \"%s\""); - break; - default: - elog(ERROR, "unsupported object class %u", classId); - break; - } - - ereport(ERROR, - (errcode(ERRCODE_DUPLICATE_OBJECT), - errmsg(msgfmt, name, get_namespace_name(nspOid)))); -} - /* * Generic function to change the namespace of a given object, for simple * cases (won't work for tables, nor other cases where we need to do more @@ -403,31 +592,34 @@ AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid) /* * Check for duplicate name (more friendly than unique-index failure). * Since this is just a friendliness check, we can just skip it in cases - * where there isn't a suitable syscache available. + * where there isn't suitable support. */ if (classId == ProcedureRelationId) { - HeapTuple tup; - Form_pg_proc proc; - - tup = SearchSysCacheCopy1(PROCOID, ObjectIdGetDatum(objid)); - if (!HeapTupleIsValid(tup)) - elog(ERROR, "cache lookup failed for function %u", objid); - proc = (Form_pg_proc) GETSTRUCT(tup); + Form_pg_proc proc = (Form_pg_proc) GETSTRUCT(tup); IsThereFunctionInNamespace(NameStr(proc->proname), proc->pronargs, proc->proargtypes, nspOid); - heap_freetuple(tup); } else if (classId == CollationRelationId) { - char *collname; + Form_pg_collation coll = (Form_pg_collation) GETSTRUCT(tup); + + IsThereCollationInNamespace(NameStr(coll->collname), nspOid); + } + else if (classId == OperatorClassRelationId) + { + Form_pg_opclass opc = (Form_pg_opclass) GETSTRUCT(tup); + + IsThereOpClassInNamespace(NameStr(opc->opcname), + opc->opcmethod, nspOid); + } + else if (classId == OperatorFamilyRelationId) + { + Form_pg_opfamily opf = (Form_pg_opfamily) GETSTRUCT(tup); - collname = get_collation_name(objid); - if (!collname) - elog(ERROR, "cache lookup failed for collation %u", objid); - IsThereCollationInNamespace(collname, nspOid); - pfree(collname); + IsThereOpFamilyInNamespace(NameStr(opf->opfname), + opf->opfmethod, nspOid); } else if (nameCacheId >= 0 && SearchSysCacheExists2(nameCacheId, name, diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c index 67200f87ba..8326cd0469 100644 --- a/src/backend/commands/collationcmds.c +++ b/src/backend/commands/collationcmds.c @@ -144,54 +144,6 @@ DefineCollation(List *names, List *parameters) return newoid; } -/* - * Rename collation - */ -Oid -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 */ - IsThereCollationInNamespace(newname, 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); - - return collationOid; -} - /* * Subroutine for ALTER COLLATION SET SCHEMA and RENAME * diff --git a/src/backend/commands/conversioncmds.c b/src/backend/commands/conversioncmds.c index 35d4d08680..84ab434fd7 100644 --- a/src/backend/commands/conversioncmds.c +++ b/src/backend/commands/conversioncmds.c @@ -114,56 +114,3 @@ CreateConversionCommand(CreateConversionStmt *stmt) return ConversionCreate(conversion_name, namespaceId, GetUserId(), from_encoding, to_encoding, funcoid, stmt->def); } - -/* - * Rename conversion - */ -Oid -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); - - return conversionOid; -} diff --git a/src/backend/commands/event_trigger.c b/src/backend/commands/event_trigger.c index 99b17a03ef..9063187f5f 100644 --- a/src/backend/commands/event_trigger.c +++ b/src/backend/commands/event_trigger.c @@ -417,52 +417,6 @@ AlterEventTrigger(AlterEventTrigStmt *stmt) return trigoid; } - -/* - * Rename event trigger - */ -Oid -RenameEventTrigger(const char *trigname, const char *newname) -{ - Oid evtId; - HeapTuple tup; - Relation rel; - Form_pg_event_trigger evtForm; - - rel = heap_open(EventTriggerRelationId, RowExclusiveLock); - - /* newname must be available */ - if (SearchSysCacheExists1(EVENTTRIGGERNAME, CStringGetDatum(newname))) - ereport(ERROR, - (errcode(ERRCODE_DUPLICATE_OBJECT), - errmsg("event trigger \"%s\" already exists", newname))); - - /* trigname must exists */ - tup = SearchSysCacheCopy1(EVENTTRIGGERNAME, CStringGetDatum(trigname)); - if (!HeapTupleIsValid(tup)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("event trigger \"%s\" does not exist", trigname))); - if (!pg_event_trigger_ownercheck(HeapTupleGetOid(tup), GetUserId())) - aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_EVENT_TRIGGER, - trigname); - - evtId = HeapTupleGetOid(tup); - - evtForm = (Form_pg_event_trigger) GETSTRUCT(tup); - - /* tuple is a copy, so we can rename it now */ - namestrcpy(&(evtForm->evtname), newname); - simple_heap_update(rel, &tup->t_self, tup); - CatalogUpdateIndexes(rel, tup); - - heap_freetuple(tup); - heap_close(rel, RowExclusiveLock); - - return evtId; -} - - /* * Change event trigger's owner -- by name */ diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c index d3af8dc22a..7700e91c82 100644 --- a/src/backend/commands/foreigncmds.c +++ b/src/backend/commands/foreigncmds.c @@ -200,93 +200,6 @@ GetUserOidFromMapping(const char *username, bool missing_ok) return get_role_oid(username, missing_ok); } - -/* - * Rename foreign-data wrapper - */ -Oid -RenameForeignDataWrapper(const char *oldname, const char *newname) -{ - Oid fdwId; - 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))); - - fdwId = HeapTupleGetOid(tup); - - /* 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); - - return fdwId; -} - - -/* - * Rename foreign server - */ -Oid -RenameForeignServer(const char *oldname, const char *newname) -{ - Oid srvId; - 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))); - - srvId = HeapTupleGetOid(tup); - - /* 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); - - return srvId; -} - - /* * Internal workhorse for changing a data wrapper's owner. * diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index 4f8e82a8e6..7b912332fe 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -1036,65 +1036,6 @@ RemoveFunctionById(Oid funcOid) } } - -/* - * Rename function - */ -Oid -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 */ - IsThereFunctionInNamespace(newname, procForm->pronargs, - procForm->proargtypes, - 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); - - return procOid; -} - /* * Implements the ALTER FUNCTION utility command (except for the * RENAME and OWNER clauses, which are handled as part of the generic @@ -1677,7 +1618,7 @@ DropCastById(Oid castOid) } /* - * Subroutine for ALTER FUNCTION/AGGREGATE SET SCHEMA + * Subroutine for ALTER FUNCTION/AGGREGATE SET SCHEMA/RENAME * * Is there a function with the given name and signature already in the given * namespace? If so, raise an appropriate error message. diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c index 4b57e3dbd6..2cfd89a7f9 100644 --- a/src/backend/commands/opclasscmds.c +++ b/src/backend/commands/opclasscmds.c @@ -1660,156 +1660,65 @@ RemoveAmProcEntryById(Oid entryOid) heap_close(rel, RowExclusiveLock); } - -/* - * Rename opclass - */ -Oid -RenameOpClass(List *name, const char *access_method, const char *newname) +static char * +get_am_name(Oid amOid) { - 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); + char *result = NULL; - /* 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; + tup = SearchSysCache1(AMOID, ObjectIdGetDatum(amOid)); + if (HeapTupleIsValid(tup)) + { + result = pstrdup(NameStr(((Form_pg_am) GETSTRUCT(tup))->amname)); + ReleaseSysCache(tup); + } + return result; +} +/* + * Subroutine for ALTER OPERATOR CLASS SET SCHEMA/RENAME + * + * Is there an operator class with the given name and signature already + * in the given namespace? If so, raise an appropriate error message. + */ +void +IsThereOpClassInNamespace(const char *opcname, Oid opcmethod, + Oid opcnamespace) +{ /* make sure the new name doesn't exist */ if (SearchSysCacheExists3(CLAAMNAMENSP, - ObjectIdGetDatum(amOid), - CStringGetDatum(newname), - ObjectIdGetDatum(namespaceOid))) - { + ObjectIdGetDatum(opcmethod), + CStringGetDatum(opcname), + ObjectIdGetDatum(opcnamespace))) 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); - - return opcOid; + opcname, + get_am_name(opcmethod), + get_namespace_name(opcnamespace)))); } /* - * Rename opfamily + * Subroutine for ALTER OPERATOR FAMILY SET SCHEMA/RENAME + * + * Is there an operator family with the given name and signature already + * in the given namespace? If so, raise an appropriate error message. */ -Oid -RenameOpFamily(List *name, const char *access_method, const char *newname) +void +IsThereOpFamilyInNamespace(const char *opfname, Oid opfmethod, + Oid opfnamespace) { - 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))) - { + ObjectIdGetDatum(opfmethod), + CStringGetDatum(opfname), + ObjectIdGetDatum(opfnamespace))) 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); - - return opfOid; + opfname, + get_am_name(opfmethod), + get_namespace_name(opfnamespace)))); } /* diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c index 718b71185f..e6c6d4e5e9 100644 --- a/src/backend/commands/proclang.c +++ b/src/backend/commands/proclang.c @@ -536,48 +536,6 @@ DropProceduralLanguageById(Oid langOid) heap_close(rel, RowExclusiveLock); } -/* - * Rename language - */ -Oid -RenameLanguage(const char *oldname, const char *newname) -{ - Oid lanId; - 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))); - - lanId = HeapTupleGetOid(tup); - - /* 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); - - return lanId; -} - /* * get_language_oid - given a language name, look up the OID * diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c index aea9fd1fac..95377ac492 100644 --- a/src/backend/commands/tsearchcmds.c +++ b/src/backend/commands/tsearchcmds.c @@ -305,51 +305,6 @@ RemoveTSParserById(Oid prsId) heap_close(relation, RowExclusiveLock); } -/* - * ALTER TEXT SEARCH PARSER RENAME - */ -Oid -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); - - return prsId; -} - /* ---------------------- TS Dictionary commands -----------------------*/ /* @@ -534,59 +489,6 @@ DefineTSDictionary(List *names, List *parameters) return dictOid; } -/* - * ALTER TEXT SEARCH DICTIONARY RENAME - */ -Oid -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); - - return dictId; -} - /* * Guts of TS dictionary deletion. */ @@ -904,52 +806,6 @@ DefineTSTemplate(List *names, List *parameters) return tmplOid; } -/* - * ALTER TEXT SEARCH TEMPLATE RENAME - */ -Oid -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); - - return tmplId; -} - /* * Guts of TS template deletion. */ @@ -1248,58 +1104,6 @@ DefineTSConfiguration(List *names, List *parameters) return cfgOid; } -/* - * ALTER TEXT SEARCH CONFIGURATION RENAME - */ -Oid -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); - - return cfgId; -} - /* * Guts of TS configuration deletion. */ diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 76ef11e049..b19afa88e7 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -6776,7 +6776,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; @@ -6804,7 +6804,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; @@ -6814,7 +6814,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; @@ -6824,7 +6824,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; @@ -6842,7 +6842,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; @@ -7015,7 +7015,7 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name { RenameStmt *n = makeNode(RenameStmt); n->renameType = OBJECT_EVENT_TRIGGER; - n->subname = $4; + n->object = list_make1(makeString($4)); n->newname = $7; $$ = (Node *)n; } diff --git a/src/include/commands/collationcmds.h b/src/include/commands/collationcmds.h index 5aaa178172..178f704842 100644 --- a/src/include/commands/collationcmds.h +++ b/src/include/commands/collationcmds.h @@ -18,7 +18,6 @@ #include "nodes/parsenodes.h" extern Oid DefineCollation(List *names, List *parameters); -extern Oid RenameCollation(List *name, const char *newname); -extern void IsThereCollationInNamespace(const char *collname, Oid newNspOid); +extern void IsThereCollationInNamespace(const char *collname, Oid nspOid); #endif /* COLLATIONCMDS_H */ diff --git a/src/include/commands/conversioncmds.h b/src/include/commands/conversioncmds.h index 3995628974..75e42f5d17 100644 --- a/src/include/commands/conversioncmds.h +++ b/src/include/commands/conversioncmds.h @@ -18,6 +18,5 @@ #include "nodes/parsenodes.h" extern Oid CreateConversionCommand(CreateConversionStmt *parsetree); -extern Oid RenameConversion(List *name, const char *newname); #endif /* CONVERSIONCMDS_H */ diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h index 7de6d5de97..62515b217e 100644 --- a/src/include/commands/defrem.h +++ b/src/include/commands/defrem.h @@ -46,7 +46,6 @@ extern Oid 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 Oid RenameFunction(List *name, List *argtypes, const char *newname); extern Oid AlterFunction(AlterFunctionStmt *stmt); extern Oid CreateCast(CreateCastStmt *stmt); extern void DropCastById(Oid castOid); @@ -62,7 +61,6 @@ extern void RemoveOperatorById(Oid operOid); /* commands/aggregatecmds.c */ extern Oid DefineAggregate(List *name, List *args, bool oldstyle, List *parameters); -extern Oid RenameAggregate(List *name, List *args, const char *newname); /* commands/opclasscmds.c */ extern Oid DefineOpClass(CreateOpClassStmt *stmt); @@ -72,28 +70,26 @@ extern void RemoveOpClassById(Oid opclassOid); extern void RemoveOpFamilyById(Oid opfamilyOid); extern void RemoveAmOpEntryById(Oid entryOid); extern void RemoveAmProcEntryById(Oid entryOid); -extern Oid RenameOpClass(List *name, const char *access_method, const char *newname); -extern Oid RenameOpFamily(List *name, const char *access_method, const char *newname); +extern void IsThereOpClassInNamespace(const char *opcname, Oid opcmethod, + Oid opcnamespace); +extern void IsThereOpFamilyInNamespace(const char *opfname, Oid opfmethod, + Oid opfnamespace); 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 Oid DefineTSParser(List *names, List *parameters); -extern Oid RenameTSParser(List *oldname, const char *newname); extern void RemoveTSParserById(Oid prsId); extern Oid DefineTSDictionary(List *names, List *parameters); -extern Oid RenameTSDictionary(List *oldname, const char *newname); extern void RemoveTSDictionaryById(Oid dictId); extern Oid AlterTSDictionary(AlterTSDictionaryStmt *stmt); extern Oid DefineTSTemplate(List *names, List *parameters); -extern Oid RenameTSTemplate(List *oldname, const char *newname); extern void RemoveTSTemplateById(Oid tmplId); extern Oid DefineTSConfiguration(List *names, List *parameters); -extern Oid RenameTSConfiguration(List *oldname, const char *newname); extern void RemoveTSConfigurationById(Oid cfgId); extern Oid AlterTSConfiguration(AlterTSConfigurationStmt *stmt); @@ -101,8 +97,6 @@ extern text *serialize_deflist(List *deflist); extern List *deserialize_deflist(Datum txt); /* commands/foreigncmds.c */ -extern Oid RenameForeignServer(const char *oldname, const char *newname); -extern Oid RenameForeignDataWrapper(const char *oldname, const char *newname); extern Oid AlterForeignServerOwner(const char *name, Oid newOwnerId); extern void AlterForeignServerOwner_oid(Oid, Oid newOwnerId); extern Oid AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId); diff --git a/src/include/commands/event_trigger.h b/src/include/commands/event_trigger.h index 8b86b7005a..6d84b15b08 100644 --- a/src/include/commands/event_trigger.h +++ b/src/include/commands/event_trigger.h @@ -36,7 +36,6 @@ extern void RemoveEventTriggerById(Oid ctrigOid); extern Oid get_event_trigger_oid(const char *trigname, bool missing_ok); extern Oid AlterEventTrigger(AlterEventTrigStmt *stmt); -extern Oid RenameEventTrigger(const char* trigname, const char *newname); extern Oid AlterEventTriggerOwner(const char *name, Oid newOwnerId); extern void AlterEventTriggerOwner_oid(Oid, Oid newOwnerId); diff --git a/src/include/commands/proclang.h b/src/include/commands/proclang.h index 1f17ae4d3d..f93b62cdb5 100644 --- a/src/include/commands/proclang.h +++ b/src/include/commands/proclang.h @@ -16,7 +16,6 @@ extern Oid CreateProceduralLanguage(CreatePLangStmt *stmt); extern void DropProceduralLanguageById(Oid langOid); -extern Oid RenameLanguage(const char *oldname, const char *newname); extern bool PLTemplateExists(const char *languageName); extern Oid get_language_oid(const char *langname, bool missing_ok); diff --git a/src/test/regress/expected/alter_generic.out b/src/test/regress/expected/alter_generic.out index f27d21787e..1d7e52412f 100644 --- a/src/test/regress/expected/alter_generic.out +++ b/src/test/regress/expected/alter_generic.out @@ -279,8 +279,8 @@ ALTER OPERATOR FAMILY alt_opf2 USING hash OWNER TO regtest_alter_user3; -- fail 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 --- can't test this: the error message includes the raw oid of namespace --- ALTER OPERATOR FAMILY alt_opf2 USING hash SET SCHEMA alt_nsp2; -- failed (name conflict) +ALTER OPERATOR FAMILY alt_opf2 USING hash SET SCHEMA alt_nsp2; -- failed (name conflict) +ERROR: operator family "alt_opf2" for access method "hash" already exists in schema "alt_nsp2" 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 @@ -290,8 +290,8 @@ ALTER OPERATOR CLASS alt_opc2 USING hash OWNER TO regtest_alter_user3; -- faile 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 --- can't test this: the error message includes the raw oid of namespace --- ALTER OPERATOR CLASS alt_opc2 USING hash SET SCHEMA alt_nsp2; -- failed (name conflict) +ALTER OPERATOR CLASS alt_opc2 USING hash SET SCHEMA alt_nsp2; -- failed (name conflict) +ERROR: operator class "alt_opc2" for access method "hash" already exists in schema "alt_nsp2" RESET SESSION AUTHORIZATION; SELECT nspname, opfname, amname, rolname FROM pg_opfamily o, pg_am m, pg_namespace n, pg_authid a @@ -327,7 +327,7 @@ 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 +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" @@ -368,7 +368,7 @@ 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 +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" @@ -408,7 +408,7 @@ SELECT nspname, cfgname, rolname 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 +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); @@ -433,7 +433,7 @@ CREATE TEXT SEARCH PARSER alt_ts_prs1 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 +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 diff --git a/src/test/regress/sql/alter_generic.sql b/src/test/regress/sql/alter_generic.sql index 6313ed9415..04c5cc15e6 100644 --- a/src/test/regress/sql/alter_generic.sql +++ b/src/test/regress/sql/alter_generic.sql @@ -242,16 +242,14 @@ 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) --- can't test this: the error message includes the raw oid of namespace --- ALTER OPERATOR FAMILY alt_opf2 USING hash SET SCHEMA alt_nsp2; -- failed (name conflict) +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) --- can't test this: the error message includes the raw oid of namespace --- ALTER OPERATOR CLASS alt_opc2 USING hash SET SCHEMA alt_nsp2; -- failed (name conflict) +ALTER OPERATOR CLASS alt_opc2 USING hash SET SCHEMA alt_nsp2; -- failed (name conflict) RESET SESSION AUTHORIZATION; -- 2.40.0