diff options
Diffstat (limited to 'src/backend/commands/opclasscmds.c')
-rw-r--r-- | src/backend/commands/opclasscmds.c | 171 |
1 files changed, 40 insertions, 131 deletions
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c index 4b57e3dbd60..2cfd89a7f9a 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)))); } /* |