Refactoring on DROP/ALTER SET SCHEMA/ALTER RENAME TO statement
The series of attached patches try to have refactoring on several ddl
statements; that consolidates distributed routines for each object
types into a common routine to minimize the number of upcoming hooks
for external security.
Please apply the series of patches in order of part-1, part-2, part-3
then part-4.
Part-1) DROP statement refactoring
It is a remaining portion of what I submitted in the last commit fest.
It allows object types that didn't used DropStmt in gram.y to go
through RemoveObjects(), instead of individual RemoveXXXX().
Part-2) Groundworks on objectaddress.c
This patch adds necessary groundworks for Part-3 and Part-4.
It adds ObjectPropertyType of objectaddress.c index-oid and cache-id
for name lookup and attribute number of object name; these field is
used to detect namespace conflict on object_exists_namespace() that
shall be called on refactored ALTER SET SCHEMA/RENAME TO.
It also reduce some arguments of check_object_ownership(), and allows
to call this function without knowledge of ObjectType and text
representation. It allows to check ownership using this function from
the code path of AlterObjectNamespace_oid() that does not have (or
need to look up catalog to obtain) ObjectType information.
In addition, it adds regression test cases for ALTER SET SCHEMA/RENAME TO.
Part-3) ALTER SET SCHEMA statement refactoring
This patch refactoring routines of ALTER SET SCHEMA implementations of
most object types; except for relations, types and extensions. This
portion was originally designed to use a common routine
(AlterObjectNamespace) via wrapper function that delivers
characteristic properties of object types, then this design was
replaced by facilities of objectaddress.c.
Part-4) ALTER RENAME TO statement refactoring
This patch refactoring routines of ALTER RENAME TO implementation of
most object types; except for databases, relations, columns, triggers
and roles.
Thanks,
--
KaiGai Kohei <kaigai@kaigai.gr.jp>
Attachments:
pgsql-v9.2-ddl-refactoring-part-4.v1.alter-rename-to.patchapplication/octet-stream; name=pgsql-v9.2-ddl-refactoring-part-4.v1.alter-rename-to.patchDownload
src/backend/catalog/objectaddress.c | 14 ++
src/backend/commands/aggregatecmds.c | 61 ------
src/backend/commands/alter.c | 315 +++++++++++++++++++---------
src/backend/commands/collationcmds.c | 66 ------
src/backend/commands/conversioncmds.c | 51 -----
src/backend/commands/functioncmds.c | 68 ------
src/backend/commands/opclasscmds.c | 148 -------------
src/backend/commands/proclang.c | 41 ----
src/backend/commands/schemacmds.c | 51 -----
src/backend/commands/tablespace.c | 69 ------
src/backend/commands/tsearchcmds.c | 188 -----------------
src/backend/parser/gram.y | 12 +-
src/include/catalog/objectaddress.h | 2 +-
src/include/commands/collationcmds.h | 1 -
src/include/commands/conversioncmds.h | 1 -
src/include/commands/defrem.h | 8 -
src/test/regress/expected/alter_rename.out | 14 +-
17 files changed, 249 insertions(+), 861 deletions(-)
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index 9162c26..e295fa3 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -1485,6 +1485,20 @@ get_object_tuple(ObjectAddress address)
}
/*
+ * get_object_name_attnum
+ *
+ * It returns attribute number of name of the given object type,
+ * or InvalidAttrNumber if it does not have name column.
+ */
+AttrNumber
+get_object_name_attnum(const ObjectAddress *address)
+{
+ ObjectPropertyType *property
+ = get_object_property_data(address->classId);
+ return property->attnum_name;
+}
+
+/*
* get_object_namespace_attnum
*
* It returns attribute number of namespace of the given object type,
diff --git a/src/backend/commands/aggregatecmds.c b/src/backend/commands/aggregatecmds.c
index 085a205..c50761f 100644
--- a/src/backend/commands/aggregatecmds.c
+++ b/src/backend/commands/aggregatecmds.c
@@ -206,67 +206,6 @@ DefineAggregate(List *name, List *args, bool oldstyle, List *parameters)
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
*/
diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c
index 2d60a99..9218edf 100644
--- a/src/backend/commands/alter.c
+++ b/src/backend/commands/alter.c
@@ -14,6 +14,7 @@
*/
#include "postgres.h"
+#include "catalog/catalog.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/namespace.h"
@@ -39,58 +40,216 @@
#include "utils/rel.h"
#include "utils/syscache.h"
+static void
+error_already_exist(ObjectType objtype,
+ const char *new_name, const char *nsp_name)
+{
+ const char *msg;
+ int code = ERRCODE_DUPLICATE_OBJECT;
+
+ switch (objtype)
+ {
+ case OBJECT_FUNCTION:
+ case OBJECT_AGGREGATE:
+ code = ERRCODE_DUPLICATE_FUNCTION;
+ msg = gettext_noop("function %s already exists in schema \"%s\"");
+ break;
+ case OBJECT_COLLATION:
+ msg = gettext_noop("collation \"%s\" already exists in schema \"%s\"");
+ break;
+ case OBJECT_CONVERSION:
+ msg = gettext_noop("conversion \"%s\" already exists in schema \"%s\"");
+ break;
+ case OBJECT_LANGUAGE:
+ msg = gettext_noop("language \"%s\" already exists");
+ break;
+ case OBJECT_OPCLASS:
+ msg = gettext_noop("operator class \"%s\" already exists in schema \"%s\"");
+ break;
+ case OBJECT_OPFAMILY:
+ msg = gettext_noop("operator family \"%s\" already exists in schema \"%s\"");
+ break;
+ case OBJECT_TSPARSER:
+ msg = gettext_noop("text search parser \"%s\" already exists in shcema \"%s\"");
+ break;
+ case OBJECT_TSDICTIONARY:
+ msg = gettext_noop("text search dictionary \"%s\" already exists in shema \"%s\"");
+ break;
+ case OBJECT_TSTEMPLATE:
+ msg = gettext_noop("text search template \"%s\" already exists in schema \"%s\"");
+ break;
+ case OBJECT_TSCONFIGURATION:
+ msg = gettext_noop("text search configuration \"%s\" already exists in schema \"%s\"");
+ break;
+ case OBJECT_SCHEMA:
+ msg = gettext_noop("schema \"%s\" already exists");
+ break;
+ case OBJECT_TABLESPACE:
+ msg = gettext_noop("tablespace \"%s\" already exists");
+ break;
+ default:
+ elog(ERROR, "unexpected object type (%d)", (int)objtype);
+ return;
+ }
+ if (nsp_name)
+ ereport(ERROR, (errcode(code), errmsg(msg, new_name, nsp_name)));
+ else
+ ereport(ERROR, (errcode(code), errmsg(msg, new_name)));
+}
/*
- * Executes an ALTER OBJECT / RENAME TO statement. Based on the object
- * type, the function appropriate to that type is executed.
+ * AltereObjectRenameInternal
+ *
+ * Generic function to change the name of a 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).
*/
-void
-ExecRenameStmt(RenameStmt *stmt)
+static void
+AltereObjectRenameInternal(ObjectType objtype, ObjectAddress address,
+ const char *new_name, Relation relation)
{
- switch (stmt->renameType)
+ Relation catalog;
+ AttrNumber Anum_name;
+ Oid namespaceId = InvalidOid;
+ HeapTuple oldtup;
+ HeapTuple newtup;
+ NameData namebuf;
+ AclResult aclresult;
+ Datum *values;
+ bool *nulls;
+ bool *replaces;
+
+ catalog = heap_open(address.classId, RowExclusiveLock);
+
+ Anum_name = get_object_name_attnum(&address);
+ namespaceId = get_object_namespace(&address);
+
+ /* must have ownership of the obejct being renamed */
+ check_object_ownership(GetUserId(), address, relation);
+
+ switch (objtype)
{
- case OBJECT_AGGREGATE:
- RenameAggregate(stmt->object, stmt->objarg, stmt->newname);
+ case OBJECT_LANGUAGE:
+ /* nothing to check more than ownership */
break;
- case OBJECT_COLLATION:
- RenameCollation(stmt->object, stmt->newname);
- break;
+ case OBJECT_SCHEMA:
+ /* must have CREATE privilege on database */
+ aclresult = pg_database_aclcheck(MyDatabaseId,
+ GetUserId(), ACL_CREATE);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, ACL_KIND_DATABASE,
+ get_database_name(MyDatabaseId));
- case OBJECT_CONVERSION:
- RenameConversion(stmt->object, stmt->newname);
+ if (!allowSystemTableMods && IsReservedName(new_name))
+ ereport(ERROR,
+ (errcode(ERRCODE_RESERVED_NAME),
+ errmsg("unacceptable schema name \"%s\"", new_name),
+ errdetail("The prefix \"pg_\" is reserved for system schemas.")));
break;
- case OBJECT_DATABASE:
- RenameDatabase(stmt->subname, stmt->newname);
+ case OBJECT_TABLESPACE:
+ if (!allowSystemTableMods && IsReservedName(new_name))
+ ereport(ERROR,
+ (errcode(ERRCODE_RESERVED_NAME),
+ errmsg("unacceptable tablespace name \"%s\"", new_name),
+ errdetail("The prefix \"pg_\" is reserved for system tablespaces.")));
break;
- case OBJECT_FUNCTION:
- RenameFunction(stmt->object, stmt->objarg, stmt->newname);
+ default:
+ /* must have CREATE privilege on namespace */
+ namespaceId = get_object_namespace(&address);
+ Assert(OidIsValid(namespaceId));
+ aclresult = pg_namespace_aclcheck(namespaceId,
+ GetUserId(), ACL_CREATE);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
+ get_namespace_name(namespaceId));
break;
+ }
- case OBJECT_LANGUAGE:
- RenameLanguage(stmt->subname, stmt->newname);
- break;
+ /*
+ * Check for duplicate names
+ */
+ if (object_exists_namespace(address, InvalidOid, new_name))
+ error_already_exist(objtype, new_name,
+ !OidIsValid(namespaceId) ? NULL
+ : get_namespace_name(namespaceId));
+
+ /*
+ * Build modified tuple
+ */
+ oldtup = get_object_tuple(address);
- case OBJECT_OPCLASS:
- RenameOpClass(stmt->object, stmt->subname, stmt->newname);
- break;
+ values = palloc0(RelationGetNumberOfAttributes(catalog) * sizeof(Datum));
+ nulls = palloc0(RelationGetNumberOfAttributes(catalog) * sizeof(bool));
+ replaces = palloc0(RelationGetNumberOfAttributes(catalog) * 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);
+
+ /* Release memory */
+ pfree(values);
+ pfree(nulls);
+ pfree(replaces);
+
+ heap_close(catalog, NoLock);
+}
+
+/*
+ * Executes an ALTER OBJECT / RENAME TO statement. Based on the object
+ * type, the function appropriate to that type is executed.
+ */
+void
+ExecRenameStmt(RenameStmt *stmt)
+{
+ ObjectAddress address;
+ Relation relation;
+ Oid relid;
+ switch (stmt->renameType)
+ {
+ case OBJECT_AGGREGATE:
+ case OBJECT_COLLATION:
+ case OBJECT_CONVERSION:
+ case OBJECT_FUNCTION:
+ case OBJECT_LANGUAGE:
+ case OBJECT_OPCLASS:
case OBJECT_OPFAMILY:
- RenameOpFamily(stmt->object, stmt->subname, stmt->newname);
+ case OBJECT_TSPARSER:
+ case OBJECT_TSDICTIONARY:
+ case OBJECT_TSTEMPLATE:
+ case OBJECT_TSCONFIGURATION:
+ case OBJECT_SCHEMA:
+ case OBJECT_TABLESPACE:
+ address = get_object_address(stmt->renameType,
+ stmt->object,
+ stmt->objarg,
+ &relation,
+ AccessExclusiveLock,
+ false);
+ AltereObjectRenameInternal(stmt->renameType, address,
+ stmt->newname, relation);
+ if (relation)
+ heap_close(relation, NoLock);
break;
+ case OBJECT_DATABASE:
+ RenameDatabase(stmt->subname, stmt->newname);
+ break;
case OBJECT_ROLE:
RenameRole(stmt->subname, stmt->newname);
break;
- case OBJECT_SCHEMA:
- RenameSchema(stmt->subname, stmt->newname);
- break;
-
- case OBJECT_TABLESPACE:
- RenameTableSpace(stmt->subname, stmt->newname);
+ case OBJECT_TYPE:
+ RenameType(stmt->object, stmt->newname);
break;
case OBJECT_TABLE:
@@ -101,77 +260,43 @@ ExecRenameStmt(RenameStmt *stmt)
case OBJECT_ATTRIBUTE:
case OBJECT_TRIGGER:
case OBJECT_FOREIGN_TABLE:
+ CheckRelationOwnership(stmt->relation, true);
+ /*
+ * Lock level used here should match what will be taken later,
+ * in RenameRelation, renameatt, or renametrig.
+ */
+ relid = RangeVarGetRelid(stmt->relation, AccessExclusiveLock,
+ false, false);
+ if (stmt->renameType == OBJECT_COLUMN ||
+ stmt->renameType == OBJECT_ATTRIBUTE)
+ {
+ renameatt(relid, stmt);
+ }
+ else if (stmt->renameType == OBJECT_TRIGGER)
+ {
+ renametrig(relid,
+ stmt->subname, /* old att name */
+ stmt->newname); /* new att name */
+ }
+ else
{
- Oid relid;
-
- CheckRelationOwnership(stmt->relation, true);
-
/*
- * Lock level used here should match what will be taken later,
- * in RenameRelation, renameatt, or renametrig.
+ * RENAME TABLE requires that we (still) hold
+ * CREATE rights on the containing namespace, as
+ * well as ownership of the table.
*/
- relid = RangeVarGetRelid(stmt->relation, AccessExclusiveLock,
- false, false);
-
- switch (stmt->renameType)
- {
- case OBJECT_TABLE:
- case OBJECT_SEQUENCE:
- case OBJECT_VIEW:
- case OBJECT_INDEX:
- case OBJECT_FOREIGN_TABLE:
- {
- /*
- * RENAME TABLE requires that we (still) hold
- * CREATE rights on the containing namespace, as
- * well as ownership of the table.
- */
- Oid namespaceId = get_rel_namespace(relid);
- AclResult aclresult;
-
- aclresult = pg_namespace_aclcheck(namespaceId,
- GetUserId(),
- ACL_CREATE);
- if (aclresult != ACLCHECK_OK)
- aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
- get_namespace_name(namespaceId));
-
- RenameRelation(relid, stmt->newname, stmt->renameType);
- break;
- }
- case OBJECT_COLUMN:
- case OBJECT_ATTRIBUTE:
- renameatt(relid, stmt);
- break;
- case OBJECT_TRIGGER:
- renametrig(relid,
- stmt->subname, /* old att name */
- stmt->newname); /* new att name */
- break;
- default:
- /* can't happen */ ;
- }
- break;
- }
-
- case OBJECT_TSPARSER:
- RenameTSParser(stmt->object, stmt->newname);
- break;
+ Oid namespaceId = get_rel_namespace(relid);
+ AclResult aclresult;
- case OBJECT_TSDICTIONARY:
- RenameTSDictionary(stmt->object, stmt->newname);
- break;
+ aclresult = pg_namespace_aclcheck(namespaceId,
+ GetUserId(),
+ ACL_CREATE);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
+ get_namespace_name(namespaceId));
- case OBJECT_TSTEMPLATE:
- RenameTSTemplate(stmt->object, stmt->newname);
- break;
-
- case OBJECT_TSCONFIGURATION:
- RenameTSConfiguration(stmt->object, stmt->newname);
- break;
-
- case OBJECT_TYPE:
- RenameType(stmt->object, stmt->newname);
+ RenameRelation(relid, stmt->newname, stmt->renameType);
+ }
break;
default:
diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c
index 09020d1..f219d6e 100644
--- a/src/backend/commands/collationcmds.c
+++ b/src/backend/commands/collationcmds.c
@@ -145,72 +145,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
diff --git a/src/backend/commands/conversioncmds.c b/src/backend/commands/conversioncmds.c
index 950f870..5b61cf0 100644
--- a/src/backend/commands/conversioncmds.c
+++ b/src/backend/commands/conversioncmds.c
@@ -118,57 +118,6 @@ CreateConversionCommand(CreateConversionStmt *stmt)
}
/*
- * 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
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 5102d87..1821c61 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -1013,74 +1013,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
*/
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index 7598561..1e16d32 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -1642,154 +1642,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
*/
diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c
index b7ed1a4..370b2a7 100644
--- a/src/backend/commands/proclang.c
+++ b/src/backend/commands/proclang.c
@@ -536,47 +536,6 @@ DropProceduralLanguageById(Oid langOid)
}
/*
- * Rename language
- */
-void
-RenameLanguage(const char *oldname, const char *newname)
-{
- HeapTuple tup;
- Relation rel;
-
- /* Translate both names for consistency with CREATE */
- oldname = case_translate_language_name(oldname);
- newname = case_translate_language_name(newname);
-
- 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
diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c
index 8daa9d0..a22fbcd 100644
--- a/src/backend/commands/schemacmds.c
+++ b/src/backend/commands/schemacmds.c
@@ -169,57 +169,6 @@ RemoveSchemaById(Oid schemaOid)
heap_close(relation, RowExclusiveLock);
}
-
-/*
- * Rename schema
- */
-void
-RenameSchema(const char *oldname, const char *newname)
-{
- HeapTuple tup;
- Relation rel;
- AclResult aclresult;
-
- rel = heap_open(NamespaceRelationId, RowExclusiveLock);
-
- tup = SearchSysCacheCopy1(NAMESPACENAME, CStringGetDatum(oldname));
- if (!HeapTupleIsValid(tup))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_SCHEMA),
- errmsg("schema \"%s\" does not exist", oldname)));
-
- /* make sure the new name doesn't exist */
- if (OidIsValid(get_namespace_oid(newname, true)))
- ereport(ERROR,
- (errcode(ERRCODE_DUPLICATE_SCHEMA),
- errmsg("schema \"%s\" already exists", newname)));
-
- /* must be owner */
- if (!pg_namespace_ownercheck(HeapTupleGetOid(tup), GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_NAMESPACE,
- oldname);
-
- /* must have CREATE privilege on database */
- aclresult = pg_database_aclcheck(MyDatabaseId, GetUserId(), ACL_CREATE);
- if (aclresult != ACLCHECK_OK)
- aclcheck_error(aclresult, ACL_KIND_DATABASE,
- get_database_name(MyDatabaseId));
-
- if (!allowSystemTableMods && IsReservedName(newname))
- ereport(ERROR,
- (errcode(ERRCODE_RESERVED_NAME),
- errmsg("unacceptable schema name \"%s\"", newname),
- errdetail("The prefix \"pg_\" is reserved for system schemas.")));
-
- /* rename */
- namestrcpy(&(((Form_pg_namespace) GETSTRUCT(tup))->nspname), newname);
- simple_heap_update(rel, &tup->t_self, tup);
- CatalogUpdateIndexes(rel, tup);
-
- heap_close(rel, NoLock);
- heap_freetuple(tup);
-}
-
void
AlterSchemaOwner_oid(Oid oid, Oid newOwnerId)
{
diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c
index d223f8c..37a6b5e 100644
--- a/src/backend/commands/tablespace.c
+++ b/src/backend/commands/tablespace.c
@@ -781,75 +781,6 @@ directory_is_empty(const char *path)
return true;
}
-
-/*
- * Rename a tablespace
- */
-void
-RenameTableSpace(const char *oldname, const char *newname)
-{
- Relation rel;
- ScanKeyData entry[1];
- HeapScanDesc scan;
- HeapTuple tup;
- HeapTuple newtuple;
- Form_pg_tablespace newform;
-
- /* Search pg_tablespace */
- rel = heap_open(TableSpaceRelationId, RowExclusiveLock);
-
- ScanKeyInit(&entry[0],
- Anum_pg_tablespace_spcname,
- BTEqualStrategyNumber, F_NAMEEQ,
- CStringGetDatum(oldname));
- scan = heap_beginscan(rel, SnapshotNow, 1, entry);
- tup = heap_getnext(scan, ForwardScanDirection);
- if (!HeapTupleIsValid(tup))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("tablespace \"%s\" does not exist",
- oldname)));
-
- newtuple = heap_copytuple(tup);
- newform = (Form_pg_tablespace) GETSTRUCT(newtuple);
-
- heap_endscan(scan);
-
- /* Must be owner */
- if (!pg_tablespace_ownercheck(HeapTupleGetOid(newtuple), GetUserId()))
- aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_TABLESPACE, oldname);
-
- /* Validate new name */
- if (!allowSystemTableMods && IsReservedName(newname))
- ereport(ERROR,
- (errcode(ERRCODE_RESERVED_NAME),
- errmsg("unacceptable tablespace name \"%s\"", newname),
- errdetail("The prefix \"pg_\" is reserved for system tablespaces.")));
-
- /* Make sure the new name doesn't exist */
- ScanKeyInit(&entry[0],
- Anum_pg_tablespace_spcname,
- BTEqualStrategyNumber, F_NAMEEQ,
- CStringGetDatum(newname));
- scan = heap_beginscan(rel, SnapshotNow, 1, entry);
- tup = heap_getnext(scan, ForwardScanDirection);
- if (HeapTupleIsValid(tup))
- ereport(ERROR,
- (errcode(ERRCODE_DUPLICATE_OBJECT),
- errmsg("tablespace \"%s\" already exists",
- newname)));
-
- heap_endscan(scan);
-
- /* OK, update the entry */
- namestrcpy(&(newform->spcname), newname);
-
- simple_heap_update(rel, &newtuple->t_self, newtuple);
- CatalogUpdateIndexes(rel, newtuple);
-
- heap_close(rel, NoLock);
-}
-
/*
* Change tablespace owner
*/
diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c
index 471d6d1..73b8c0d 100644
--- a/src/backend/commands/tsearchcmds.c
+++ b/src/backend/commands/tsearchcmds.c
@@ -301,49 +301,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);
-}
-
/* ---------------------- TS Dictionary commands -----------------------*/
/*
@@ -527,57 +484,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);
-}
-
-/*
* Guts of TS dictionary deletion.
*/
void
@@ -950,50 +856,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);
-}
-
-/*
* Guts of TS template deletion.
*/
void
@@ -1289,56 +1151,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);
-}
-
-/*
* Guts of TS configuration deletion.
*/
void
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 7940121..b79b654 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -6487,7 +6487,8 @@ 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->objarg = NIL;
n->newname = $7;
$$ = (Node *)n;
}
@@ -6496,7 +6497,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;
$$ = (Node *)n;
}
@@ -6505,7 +6506,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;
$$ = (Node *)n;
}
@@ -6513,7 +6514,8 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name
{
RenameStmt *n = makeNode(RenameStmt);
n->renameType = OBJECT_SCHEMA;
- n->subname = $3;
+ n->object = list_make1(makeString($3));
+ n->objarg = NIL;
n->newname = $6;
$$ = (Node *)n;
}
@@ -6611,7 +6613,7 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name
{
RenameStmt *n = makeNode(RenameStmt);
n->renameType = OBJECT_TABLESPACE;
- n->subname = $3;
+ n->object = list_make1(makeString($3));
n->newname = $6;
$$ = (Node *)n;
}
diff --git a/src/include/catalog/objectaddress.h b/src/include/catalog/objectaddress.h
index a5d3325..bc46a80 100644
--- a/src/include/catalog/objectaddress.h
+++ b/src/include/catalog/objectaddress.h
@@ -41,7 +41,7 @@ extern bool object_exists_namespace(ObjectAddress address,
const char *new_name);
extern HeapTuple get_object_tuple(ObjectAddress address);
-
+extern AttrNumber get_object_name_attnum(const ObjectAddress *address);
extern AttrNumber get_object_namespace_attnum(const ObjectAddress *address);
extern Oid get_object_namespace(const ObjectAddress *address);
diff --git a/src/include/commands/collationcmds.h b/src/include/commands/collationcmds.h
index d161d74..a2b7879 100644
--- a/src/include/commands/collationcmds.h
+++ b/src/include/commands/collationcmds.h
@@ -18,7 +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);
diff --git a/src/include/commands/conversioncmds.h b/src/include/commands/conversioncmds.h
index 6a8a02f..b592131 100644
--- a/src/include/commands/conversioncmds.h
+++ b/src/include/commands/conversioncmds.h
@@ -18,7 +18,6 @@
#include "nodes/parsenodes.h"
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);
diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h
index b4c0c91..6e38ebf 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);
@@ -83,7 +82,6 @@ extern void AlterOperatorOwner_oid(Oid operOid, Oid newOwnerId);
/* 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 */
@@ -94,8 +92,6 @@ 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 AlterOpFamilyOwner(List *name, const char *access_method, Oid newOwnerId);
@@ -106,21 +102,17 @@ 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 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 DefineTSTemplate(List *names, List *parameters);
-extern void RenameTSTemplate(List *oldname, const char *newname);
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);
diff --git a/src/test/regress/expected/alter_rename.out b/src/test/regress/expected/alter_rename.out
index 7248b49..38ba86f 100644
--- a/src/test/regress/expected/alter_rename.out
+++ b/src/test/regress/expected/alter_rename.out
@@ -124,7 +124,7 @@ CREATE FUNCTION testfunc_b(int)
RETURNS int LANGUAGE sql
AS 'SELECT $1 + $1';
ALTER FUNCTION testfunc_a(int) RENAME TO testfunc_b; -- fail
-ERROR: function testfunc_b(integer) already exists in schema "testschema_1"
+ERROR: function testfunc_b already exists in schema "testschema_1"
ALTER FUNCTION testfunc_b(int) SET SCHEMA testschema_2; -- OK
ALTER FUNCTION testfunc_a(int) RENAME TO testfunc_b; -- OK
ALTER FUNCTION testfunc_b(int) SET SCHEMA testschema_2; -- fail
@@ -138,7 +138,7 @@ CREATE AGGREGATE testagg_b(
initcond1 = '0'
);
ALTER AGGREGATE testagg_a(int) RENAME TO testagg_b; -- fail
-ERROR: function testagg_b(integer) already exists in schema "testschema_1"
+ERROR: function testagg_b already exists in schema "testschema_1"
ALTER AGGREGATE testagg_b(int) SET SCHEMA testschema_2; -- OK
ALTER AGGREGATE testagg_a(int) RENAME TO testagg_b; -- OK
ALTER AGGREGATE testagg_b(int) SET SCHEMA testschema_2; -- fail
@@ -177,7 +177,7 @@ ERROR: operator @#@(bigint,bigint) already exists in schema "testschema_2"
CREATE OPERATOR FAMILY testopfamily_a USING btree;
CREATE OPERATOR FAMILY testopfamily_b USING btree;
ALTER OPERATOR FAMILY testopfamily_a USING btree RENAME TO testopfamily_b; -- fail
-ERROR: operator family "testopfamily_b" for access method "btree" already exists in schema "testschema_1"
+ERROR: operator family "testopfamily_b" already exists in schema "testschema_1"
ALTER OPERATOR FAMILY testopfamily_b USING btree SET SCHEMA testschema_2; -- OK
ALTER OPERATOR FAMILY testopfamily_a USING btree RENAME TO testopfamily_b; -- OK
ALTER OPERATOR FAMILY testopfamily_b USING btree SET SCHEMA testschema_2; -- fail
@@ -187,7 +187,7 @@ CREATE OPERATOR CLASS testopclass_a
CREATE OPERATOR CLASS testopclass_b
FOR TYPE circle USING btree FAMILY testopfamily_b AS OPERATOR 1 =;
ALTER OPERATOR CLASS testopclass_a USING btree RENAME TO testopclass_b; -- fail
-ERROR: operator class "testopclass_b" for access method "btree" already exists in schema "testschema_1"
+ERROR: operator class "testopclass_b" already exists in schema "testschema_1"
ALTER OPERATOR CLASS testopclass_b USING btree SET SCHEMA testschema_2; -- OK
ALTER OPERATOR CLASS testopclass_a USING btree RENAME TO testopclass_b; -- OK
ALTER OPERATOR CLASS testopclass_b USING btree SET SCHEMA testschema_2; -- fail
@@ -206,7 +206,7 @@ CREATE TEXT SEARCH DICTIONARY testtsdict_b (
AffFile=ispell_sample
);
ALTER TEXT SEARCH DICTIONARY testtsdict_a RENAME TO testtsdict_b; -- fail
-ERROR: text search dictionary "testtsdict_b" already exists
+ERROR: text search dictionary "testtsdict_b" already exists in shema "testschema_1"
ALTER TEXT SEARCH DICTIONARY testtsdict_b SET SCHEMA testschema_2; -- OK
ALTER TEXT SEARCH DICTIONARY testtsdict_a RENAME TO testtsdict_b; -- OK
ALTER TEXT SEARCH DICTIONARY testtsdict_b SET SCHEMA testschema_2; -- fail
@@ -214,7 +214,7 @@ ERROR: text search dictionary testtsdict_b already exists in schema "testschema
CREATE TEXT SEARCH CONFIGURATION testtsconf_a (COPY=english);
CREATE TEXT SEARCH CONFIGURATION testtsconf_b (COPY=english);
ALTER TEXT SEARCH CONFIGURATION testtsconf_a RENAME TO testtsconf_b; -- fail
-ERROR: text search configuration "testtsconf_b" already exists
+ERROR: text search configuration "testtsconf_b" already exists in schema "testschema_1"
ALTER TEXT SEARCH CONFIGURATION testtsconf_b SET SCHEMA testschema_2; -- OK
ALTER TEXT SEARCH CONFIGURATION testtsconf_a RENAME TO testtsconf_b; -- OK
ALTER TEXT SEARCH CONFIGURATION testtsconf_b SET SCHEMA testschema_2; -- fail
@@ -225,7 +225,7 @@ ERROR: text search configuration testtsconf_b already exists in schema "testsch
CREATE COLLATION testcollation_a FROM "C";
CREATE COLLATION testcollation_b FROM "C";
ALTER COLLATION testcollation_a RENAME TO testcollation_b; -- fail
-ERROR: collation "testcollation_b" for encoding "UTF8" already exists in schema "testschema_1"
+ERROR: collation "testcollation_b" already exists in schema "testschema_1"
ALTER COLLATION testcollation_b SET SCHEMA testschema_2; -- OK
ALTER COLLATION testcollation_a RENAME TO testcollation_b; -- OK
ALTER COLLATION testcollation_b SET SCHEMA testschema_2; -- fail
pgsql-v9.2-ddl-refactoring-part-3.v1.alter-set-schema.patchapplication/octet-stream; name=pgsql-v9.2-ddl-refactoring-part-3.v1.alter-set-schema.patchDownload
src/backend/catalog/objectaddress.c | 14 ++
src/backend/commands/alter.c | 345 ++++++++++------------------
src/backend/commands/collationcmds.c | 73 ------
src/backend/commands/conversioncmds.c | 50 ----
src/backend/commands/functioncmds.c | 82 -------
src/backend/commands/opclasscmds.c | 104 ---------
src/backend/commands/operatorcmds.c | 53 -----
src/backend/commands/tsearchcmds.c | 188 ---------------
src/backend/nodes/copyfuncs.c | 1 -
src/backend/nodes/equalfuncs.c | 1 -
src/backend/parser/gram.y | 4 +-
src/include/catalog/objectaddress.h | 1 +
src/include/commands/alter.h | 4 -
src/include/commands/collationcmds.h | 2 -
src/include/commands/conversioncmds.h | 2 -
src/include/commands/defrem.h | 17 --
src/include/nodes/parsenodes.h | 1 -
src/test/regress/expected/alter_rename.out | 18 +-
src/test/regress/sql/alter_rename.sql | 9 +-
19 files changed, 155 insertions(+), 814 deletions(-)
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index bcf5259..9162c26 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -1485,6 +1485,20 @@ get_object_tuple(ObjectAddress address)
}
/*
+ * get_object_namespace_attnum
+ *
+ * It returns attribute number of namespace of the given object type,
+ * or InvalidAttrNumber if it is not an object under schema.
+ */
+AttrNumber
+get_object_namespace_attnum(const ObjectAddress *address)
+{
+ ObjectPropertyType *property
+ = get_object_property_data(address->classId);
+ return property->attnum_namespace;
+}
+
+/*
* get_object_namespace
*
* Find the schema containing the specified object. For non-schema objects,
diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c
index c321224..2d60a99 100644
--- a/src/backend/commands/alter.c
+++ b/src/backend/commands/alter.c
@@ -181,6 +181,84 @@ ExecRenameStmt(RenameStmt *stmt)
}
/*
+ * AlterObjectSchemaInternal
+ *
+ * Generic function to change the namespace of a given object, for simple
+ * cases (won't work for tables, nor other cases where we need to do more
+ * than change the namespace column of a single catalog entry).
+ *
+ * this routine assumes the caller checks CREATE permission on `new_schema'
+ * via LookupCreationNamespace().
+ */
+static Oid
+AlterObjectSchemaInternal(ObjectAddress address,
+ Oid new_schema, Relation relation)
+{
+ Relation catalog;
+ Oid old_schema;
+ HeapTuple oldtup;
+ HeapTuple newtup;
+ AttrNumber Anum_namespace;
+ Datum datum;
+ bool isnull;
+ Datum *values;
+ bool *nulls;
+ bool *replaces;
+
+ catalog = heap_open(address.classId, RowExclusiveLock);
+
+ /* Fetch a tuple to be updated from the catalog */
+ Anum_namespace = get_object_namespace_attnum(&address);
+ oldtup = get_object_tuple(address);
+ datum = heap_getattr(oldtup, Anum_namespace,
+ RelationGetDescr(catalog), &isnull);
+ Assert(!isnull);
+ old_schema = DatumGetObjectId(datum);
+
+ /* Check basic namespace related issues */
+ CheckSetNamespace(old_schema, new_schema,
+ address.classId, address.objectId);
+
+ /* Permission checks */
+ check_object_ownership(GetUserId(), address, relation);
+
+ /* Check for duplicate names */
+ if (object_exists_namespace(address, new_schema, NULL))
+ ereport(ERROR,
+ (errcode(ERRCODE_DUPLICATE_OBJECT),
+ errmsg("%s already exists in schema \"%s\"",
+ getObjectDescriptionOids(address.classId,
+ address.objectId),
+ get_namespace_name(new_schema))));
+
+ /* Build modified tuple */
+ values = palloc0(RelationGetNumberOfAttributes(catalog) * sizeof(Datum));
+ nulls = palloc0(RelationGetNumberOfAttributes(catalog) * sizeof(bool));
+ replaces = palloc0(RelationGetNumberOfAttributes(catalog) * sizeof(bool));
+ values[Anum_namespace - 1] = ObjectIdGetDatum(new_schema);
+ replaces[Anum_namespace - 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);
+
+ /* Release memory */
+ pfree(values);
+ pfree(nulls);
+ pfree(replaces);
+
+ /* update dependencies to point to the new schema */
+ changeDependencyFor(address.classId, address.objectId,
+ NamespaceRelationId, old_schema, new_schema);
+
+ heap_close(catalog, RowExclusiveLock);
+
+ return old_schema;
+}
+
+/*
* Executes an ALTER OBJECT / SET SCHEMA statement. Based on the object
* type, the function appropriate to that type is executed.
*/
@@ -189,73 +267,70 @@ ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt)
{
switch (stmt->objectType)
{
- case OBJECT_AGGREGATE:
- AlterFunctionNamespace(stmt->object, stmt->objarg, true,
- stmt->newschema);
- break;
-
- case OBJECT_COLLATION:
- AlterCollationNamespace(stmt->object, stmt->newschema);
- break;
-
- case OBJECT_CONVERSION:
- AlterConversionNamespace(stmt->object, stmt->newschema);
- break;
-
case OBJECT_EXTENSION:
+ /*
+ * ALTER EXTENSION tries to set schema on underlying objects,
+ * so it is unavailable to consolidate with common routine.
+ */
AlterExtensionNamespace(stmt->object, stmt->newschema);
break;
- case OBJECT_FUNCTION:
- AlterFunctionNamespace(stmt->object, stmt->objarg, false,
- 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:
case OBJECT_FOREIGN_TABLE:
+ /*
+ * ALTER "TABLE" is allowed to use for VIEW, SEQUENCE or FOREIGN
+ * TABLE, so it is unavailable to consolidate with common routine.
+ */
CheckRelationOwnership(stmt->relation, true);
AlterTableNamespace(stmt->relation, stmt->newschema,
stmt->objectType, AccessExclusiveLock);
break;
- case OBJECT_TSPARSER:
- AlterTSParserNamespace(stmt->object, stmt->newschema);
+ case OBJECT_TYPE:
+ case OBJECT_DOMAIN:
+ /*
+ * ALTER TYPE also alters namespace of the composite table's
+ * definition on pg_class, so it is unavailable to consolidate
+ * with common routine.
+ */
+ AlterTypeNamespace(stmt->object, stmt->newschema);
break;
+ case OBJECT_AGGREGATE:
+ case OBJECT_COLLATION:
+ case OBJECT_CONVERSION:
+ case OBJECT_FUNCTION:
+ 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;
+ {
+ ObjectAddress address;
+ Relation relation = NULL;
+ Oid new_schema;
- case OBJECT_TYPE:
- case OBJECT_DOMAIN:
- AlterTypeNamespace(stmt->object, stmt->newschema);
- break;
+ address = get_object_address(stmt->objectType,
+ stmt->object, stmt->objarg,
+ &relation,
+ AccessExclusiveLock, false);
+ new_schema = LookupCreationNamespace(stmt->newschema);
+
+ AlterObjectSchemaInternal(address, new_schema, relation);
+
+ if (relation)
+ heap_close(relation, NoLock);
+ }
+ break;
default:
elog(ERROR, "unrecognized AlterObjectSchemaStmt type: %d",
(int) stmt->objectType);
+ break;
}
}
@@ -277,6 +352,7 @@ Oid
AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid)
{
Oid oldNspOid = InvalidOid;
+ Relation relation = NULL;
ObjectAddress dep;
dep.classId = classId;
@@ -285,204 +361,35 @@ AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid)
switch (getObjectClass(&dep))
{
- case OCLASS_CLASS:
- {
- Relation rel;
- Relation classRel;
-
- rel = relation_open(objid, AccessExclusiveLock);
- oldNspOid = RelationGetNamespace(rel);
-
- classRel = heap_open(RelationRelationId, RowExclusiveLock);
-
- AlterRelationNamespaceInternal(classRel,
- objid,
- oldNspOid,
- nspOid,
- true);
-
- heap_close(classRel, RowExclusiveLock);
-
- relation_close(rel, NoLock);
- break;
- }
-
- case OCLASS_PROC:
- oldNspOid = AlterFunctionNamespace_oid(objid, nspOid);
- break;
-
case OCLASS_TYPE:
oldNspOid = AlterTypeNamespace_oid(objid, nspOid);
break;
+ case OCLASS_CLASS:
+ relation = relation_open(objid, AccessExclusiveLock);
+ case OCLASS_PROC:
case OCLASS_COLLATION:
- oldNspOid = AlterCollationNamespace_oid(objid, 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);
+ oldNspOid = AlterObjectSchemaInternal(dep, nspOid, relation);
break;
default:
break;
}
+ if (relation)
+ heap_close(relation, NoLock);
return oldNspOid;
}
/*
- * Generic function to change the namespace of a given object, for simple
- * cases (won't work for tables, nor other cases where we need to do more
- * than change the namespace column of a single catalog entry).
- *
- * The AlterFooNamespace() calls just above will call a function whose job
- * is to lookup the arguments for the generic function here.
- *
- * rel: catalog relation containing object (RowExclusiveLock'd by caller)
- * oidCacheId: syscache that indexes this catalog by OID
- * nameCacheId: syscache that indexes this catalog by name and namespace
- * (pass -1 if there is none)
- * objid: OID of object to change the namespace of
- * nspOid: OID of new namespace
- * Anum_name: column number of catalog's name column
- * Anum_namespace: column number of catalog's namespace column
- * Anum_owner: column number of catalog's owner column, or -1 if none
- * acl_kind: ACL type for object, or -1 if none assigned
- *
- * If the object does not have an owner or permissions, pass -1 for
- * Anum_owner and acl_kind. In this case the calling user must be superuser.
- *
- * Returns the OID of the object's previous namespace.
- */
-Oid
-AlterObjectNamespace(Relation rel, int oidCacheId, int nameCacheId,
- Oid objid, Oid nspOid,
- int Anum_name, int Anum_namespace, int Anum_owner,
- AclObjectKind acl_kind)
-{
- Oid classId = RelationGetRelid(rel);
- Oid oldNspOid;
- Datum name,
- namespace;
- bool isnull;
- HeapTuple tup,
- newtup;
- Datum *values;
- bool *nulls;
- bool *replaces;
-
- tup = SearchSysCacheCopy1(oidCacheId, ObjectIdGetDatum(objid));
- if (!HeapTupleIsValid(tup)) /* should not happen */
- elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"",
- objid, RelationGetRelationName(rel));
-
- name = heap_getattr(tup, Anum_name, RelationGetDescr(rel), &isnull);
- Assert(!isnull);
- namespace = heap_getattr(tup, Anum_namespace, RelationGetDescr(rel), &isnull);
- Assert(!isnull);
- oldNspOid = DatumGetObjectId(namespace);
-
- /* Check basic namespace related issues */
- CheckSetNamespace(oldNspOid, nspOid, classId, objid);
-
- /* Permission checks ... superusers can always do it */
- if (!superuser())
- {
- Datum owner;
- Oid ownerId;
- AclResult aclresult;
-
- /* Fail if object does not have an explicit owner */
- if (Anum_owner <= 0)
- ereport(ERROR,
- (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- (errmsg("must be superuser to set schema of %s",
- getObjectDescriptionOids(classId, objid)))));
-
- /* Otherwise, must be owner of the existing object */
- owner = heap_getattr(tup, Anum_owner, RelationGetDescr(rel), &isnull);
- Assert(!isnull);
- ownerId = DatumGetObjectId(owner);
-
- if (!has_privs_of_role(GetUserId(), ownerId))
- aclcheck_error(ACLCHECK_NOT_OWNER, acl_kind,
- NameStr(*(DatumGetName(name))));
-
- /* User must have CREATE privilege on new namespace */
- aclresult = pg_namespace_aclcheck(nspOid, GetUserId(), ACL_CREATE);
- if (aclresult != ACLCHECK_OK)
- aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
- get_namespace_name(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.
- */
- if (nameCacheId >= 0 &&
- SearchSysCacheExists2(nameCacheId, name, ObjectIdGetDatum(nspOid)))
- ereport(ERROR,
- (errcode(ERRCODE_DUPLICATE_OBJECT),
- errmsg("%s already exists in schema \"%s\"",
- getObjectDescriptionOids(classId, objid),
- get_namespace_name(nspOid))));
-
- /* Build modified tuple */
- values = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(Datum));
- nulls = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
- replaces = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
- values[Anum_namespace - 1] = ObjectIdGetDatum(nspOid);
- replaces[Anum_namespace - 1] = true;
- newtup = heap_modify_tuple(tup, RelationGetDescr(rel),
- values, nulls, replaces);
-
- /* Perform actual update */
- simple_heap_update(rel, &tup->t_self, newtup);
- CatalogUpdateIndexes(rel, newtup);
-
- /* Release memory */
- pfree(values);
- pfree(nulls);
- pfree(replaces);
-
- /* update dependencies to point to the new schema */
- changeDependencyFor(classId, objid,
- NamespaceRelationId, oldNspOid, nspOid);
-
- return oldNspOid;
-}
-
-
-/*
* Executes an ALTER OBJECT / OWNER TO statement. Based on the object
* type, the function appropriate to that type is executed.
*/
diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c
index 20aa204..09020d1 100644
--- a/src/backend/commands/collationcmds.c
+++ b/src/backend/commands/collationcmds.c
@@ -307,76 +307,3 @@ AlterCollationOwner_internal(Relation rel, Oid collationOid, Oid newOwnerId)
heap_freetuple(tup);
}
-
-/*
- * Execute ALTER COLLATION SET SCHEMA
- */
-void
-AlterCollationNamespace(List *name, const char *newschema)
-{
- Oid collOid,
- nspOid;
-
- collOid = get_collation_oid(name, false);
-
- nspOid = LookupCreationNamespace(newschema);
-
- AlterCollationNamespace_oid(collOid, nspOid);
-}
-
-/*
- * Change collation schema, by oid
- */
-Oid
-AlterCollationNamespace_oid(Oid collOid, Oid newNspOid)
-{
- Oid oldNspOid;
- Relation rel;
- char *collation_name;
-
- rel = heap_open(CollationRelationId, RowExclusiveLock);
-
- /*
- * We have to check for name collision ourselves, because
- * AlterObjectNamespace doesn't know how to deal with the encoding
- * considerations.
- */
- collation_name = get_collation_name(collOid);
- if (!collation_name)
- elog(ERROR, "cache lookup failed for collation %u", collOid);
-
- /* make sure the name doesn't already exist in new schema */
- if (SearchSysCacheExists3(COLLNAMEENCNSP,
- CStringGetDatum(collation_name),
- Int32GetDatum(GetDatabaseEncoding()),
- ObjectIdGetDatum(newNspOid)))
- ereport(ERROR,
- (errcode(ERRCODE_DUPLICATE_OBJECT),
- errmsg("collation \"%s\" for encoding \"%s\" already exists in schema \"%s\"",
- collation_name,
- GetDatabaseEncodingName(),
- get_namespace_name(newNspOid))));
-
- /* mustn't match an any-encoding entry, either */
- if (SearchSysCacheExists3(COLLNAMEENCNSP,
- CStringGetDatum(collation_name),
- Int32GetDatum(-1),
- ObjectIdGetDatum(newNspOid)))
- ereport(ERROR,
- (errcode(ERRCODE_DUPLICATE_OBJECT),
- errmsg("collation \"%s\" already exists in schema \"%s\"",
- collation_name,
- get_namespace_name(newNspOid))));
-
- /* OK, do the work */
- oldNspOid = AlterObjectNamespace(rel, COLLOID, -1,
- collOid, newNspOid,
- Anum_pg_collation_collname,
- Anum_pg_collation_collnamespace,
- Anum_pg_collation_collowner,
- ACL_KIND_COLLATION);
-
- heap_close(rel, RowExclusiveLock);
-
- return oldNspOid;
-}
diff --git a/src/backend/commands/conversioncmds.c b/src/backend/commands/conversioncmds.c
index 7d6063d..950f870 100644
--- a/src/backend/commands/conversioncmds.c
+++ b/src/backend/commands/conversioncmds.c
@@ -265,53 +265,3 @@ AlterConversionOwner_internal(Relation rel, Oid conversionOid, Oid 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/functioncmds.c b/src/backend/commands/functioncmds.c
index 09a975b..5102d87 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -1760,88 +1760,6 @@ DropCastById(Oid castOid)
}
/*
- * Execute ALTER FUNCTION/AGGREGATE SET SCHEMA
- *
- * These commands are identical except for the lookup procedure, so share code.
- */
-void
-AlterFunctionNamespace(List *name, List *argtypes, bool isagg,
- const char *newschema)
-{
- Oid procOid;
- Oid nspOid;
-
- /* get function OID */
- if (isagg)
- procOid = LookupAggNameTypeNames(name, argtypes, false);
- else
- procOid = LookupFuncNameTypeNames(name, argtypes, false);
-
- /* get schema OID and check its permissions */
- nspOid = LookupCreationNamespace(newschema);
-
- AlterFunctionNamespace_oid(procOid, nspOid);
-}
-
-Oid
-AlterFunctionNamespace_oid(Oid procOid, Oid nspOid)
-{
- Oid oldNspOid;
- HeapTuple tup;
- Relation procRel;
- Form_pg_proc proc;
-
- procRel = heap_open(ProcedureRelationId, RowExclusiveLock);
-
- tup = SearchSysCacheCopy1(PROCOID, ObjectIdGetDatum(procOid));
- if (!HeapTupleIsValid(tup))
- elog(ERROR, "cache lookup failed for function %u", procOid);
- proc = (Form_pg_proc) GETSTRUCT(tup);
-
- /* check permissions on function */
- if (!pg_proc_ownercheck(procOid, GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC,
- NameStr(proc->proname));
-
- oldNspOid = proc->pronamespace;
-
- /* common checks on switching namespaces */
- CheckSetNamespace(oldNspOid, nspOid, ProcedureRelationId, procOid);
-
- /* check for duplicate name (more friendly than unique-index failure) */
- if (SearchSysCacheExists3(PROCNAMEARGSNSP,
- CStringGetDatum(NameStr(proc->proname)),
- PointerGetDatum(&proc->proargtypes),
- ObjectIdGetDatum(nspOid)))
- ereport(ERROR,
- (errcode(ERRCODE_DUPLICATE_FUNCTION),
- errmsg("function \"%s\" already exists in schema \"%s\"",
- NameStr(proc->proname),
- get_namespace_name(nspOid))));
-
- /* OK, modify the pg_proc row */
-
- /* tup is a copy, so we can scribble directly on it */
- proc->pronamespace = nspOid;
-
- simple_heap_update(procRel, &tup->t_self, tup);
- CatalogUpdateIndexes(procRel, tup);
-
- /* Update dependency on schema */
- if (changeDependencyFor(ProcedureRelationId, procOid,
- NamespaceRelationId, oldNspOid, nspOid) != 1)
- elog(ERROR, "failed to change schema dependency for function \"%s\"",
- NameStr(proc->proname));
-
- heap_freetuple(tup);
-
- heap_close(procRel, RowExclusiveLock);
-
- return oldNspOid;
-}
-
-
-/*
* ExecuteDoStmt
* Execute inline procedural-language code
*/
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index 0ef3584..7598561 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -1896,58 +1896,6 @@ AlterOpClassOwner_internal(Relation rel, HeapTuple tup, Oid 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
@@ -2103,55 +2051,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 1e6c5ce..1037c45 100644
--- a/src/backend/commands/operatorcmds.c
+++ b/src/backend/commands/operatorcmds.c
@@ -401,56 +401,3 @@ AlterOperatorOwner_internal(Relation rel, Oid operOid, Oid 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/tsearchcmds.c b/src/backend/commands/tsearchcmds.c
index 5f206d8..471d6d1 100644
--- a/src/backend/commands/tsearchcmds.c
+++ b/src/backend/commands/tsearchcmds.c
@@ -344,52 +344,6 @@ RenameTSParser(List *oldname, const char *newname)
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 -----------------------*/
/*
@@ -624,54 +578,6 @@ RenameTSDictionary(List *oldname, const char *newname)
}
/*
- * 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
@@ -1088,52 +994,6 @@ RenameTSTemplate(List *oldname, const char *newname)
}
/*
- * 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
@@ -1479,54 +1339,6 @@ RenameTSConfiguration(List *oldname, const char *newname)
}
/*
- * 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
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index b8f047a..6fa5ec1 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -2914,7 +2914,6 @@ _copyAlterObjectSchemaStmt(AlterObjectSchemaStmt *from)
COPY_NODE_FIELD(relation);
COPY_NODE_FIELD(object);
COPY_NODE_FIELD(objarg);
- COPY_STRING_FIELD(addname);
COPY_STRING_FIELD(newschema);
return newnode;
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index d1af48a..9ae95b0 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -1319,7 +1319,6 @@ _equalAlterObjectSchemaStmt(AlterObjectSchemaStmt *a, AlterObjectSchemaStmt *b)
COMPARE_NODE_FIELD(relation);
COMPARE_NODE_FIELD(object);
COMPARE_NODE_FIELD(objarg);
- COMPARE_STRING_FIELD(addname);
COMPARE_STRING_FIELD(newschema);
return true;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 7ea38e4..7940121 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -6765,7 +6765,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;
$$ = (Node *)n;
}
@@ -6774,7 +6774,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;
$$ = (Node *)n;
}
diff --git a/src/include/catalog/objectaddress.h b/src/include/catalog/objectaddress.h
index ff7b957..a5d3325 100644
--- a/src/include/catalog/objectaddress.h
+++ b/src/include/catalog/objectaddress.h
@@ -42,6 +42,7 @@ extern bool object_exists_namespace(ObjectAddress address,
extern HeapTuple get_object_tuple(ObjectAddress address);
+extern AttrNumber get_object_namespace_attnum(const ObjectAddress *address);
extern Oid get_object_namespace(const ObjectAddress *address);
#endif /* PARSE_OBJECT_H */
diff --git a/src/include/commands/alter.h b/src/include/commands/alter.h
index 6cf9de1..0186a48 100644
--- a/src/include/commands/alter.h
+++ b/src/include/commands/alter.h
@@ -20,10 +20,6 @@
extern void ExecRenameStmt(RenameStmt *stmt);
extern void ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt);
extern Oid AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid);
-extern Oid AlterObjectNamespace(Relation rel, int oidCacheId, int nameCacheId,
- Oid objid, Oid nspOid,
- int Anum_name, int Anum_namespace, int Anum_owner,
- AclObjectKind acl_kind);
extern void ExecAlterOwnerStmt(AlterOwnerStmt *stmt);
#endif /* ALTER_H */
diff --git a/src/include/commands/collationcmds.h b/src/include/commands/collationcmds.h
index ce4727c..d161d74 100644
--- a/src/include/commands/collationcmds.h
+++ b/src/include/commands/collationcmds.h
@@ -21,7 +21,5 @@ 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);
#endif /* COLLATIONCMDS_H */
diff --git a/src/include/commands/conversioncmds.h b/src/include/commands/conversioncmds.h
index c0e7cd9..6a8a02f 100644
--- a/src/include/commands/conversioncmds.h
+++ b/src/include/commands/conversioncmds.h
@@ -21,7 +21,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 f0dcf76..b4c0c91 100644
--- a/src/include/commands/defrem.h
+++ b/src/include/commands/defrem.h
@@ -70,9 +70,6 @@ extern void AlterFunctionOwner_oid(Oid procOid, Oid newOwnerId);
extern void AlterFunction(AlterFunctionStmt *stmt);
extern void CreateCast(CreateCastStmt *stmt);
extern void DropCastById(Oid castOid);
-extern void AlterFunctionNamespace(List *name, List *argtypes, bool isagg,
- const char *newschema);
-extern Oid AlterFunctionNamespace_oid(Oid procOid, Oid nspOid);
extern void ExecuteDoStmt(DoStmt *stmt);
extern Oid get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok);
@@ -82,8 +79,6 @@ 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,
@@ -103,12 +98,8 @@ extern void RenameOpClass(List *name, const char *access_method, const char *new
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);
@@ -116,8 +107,6 @@ 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);
@@ -125,13 +114,9 @@ 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);
@@ -139,8 +124,6 @@ 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);
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 6449eca..77d4167 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -2125,7 +2125,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 */
} AlterObjectSchemaStmt;
diff --git a/src/test/regress/expected/alter_rename.out b/src/test/regress/expected/alter_rename.out
index 6688d50..7248b49 100644
--- a/src/test/regress/expected/alter_rename.out
+++ b/src/test/regress/expected/alter_rename.out
@@ -128,7 +128,7 @@ ERROR: function testfunc_b(integer) already exists in schema "testschema_1"
ALTER FUNCTION testfunc_b(int) SET SCHEMA testschema_2; -- OK
ALTER FUNCTION testfunc_a(int) RENAME TO testfunc_b; -- OK
ALTER FUNCTION testfunc_b(int) SET SCHEMA testschema_2; -- fail
-ERROR: function "testfunc_b" already exists in schema "testschema_2"
+ERROR: function testfunc_b(integer) already exists in schema "testschema_2"
CREATE AGGREGATE testagg_a(
sfunc1 = int4pl, basetype = int4, stype1 = int4,
initcond1 = '0'
@@ -142,7 +142,7 @@ ERROR: function testagg_b(integer) already exists in schema "testschema_1"
ALTER AGGREGATE testagg_b(int) SET SCHEMA testschema_2; -- OK
ALTER AGGREGATE testagg_a(int) RENAME TO testagg_b; -- OK
ALTER AGGREGATE testagg_b(int) SET SCHEMA testschema_2; -- fail
-ERROR: function "testagg_b" already exists in schema "testschema_2"
+ERROR: function testagg_b(integer) already exists in schema "testschema_2"
--
-- TYPE
--
@@ -172,16 +172,16 @@ CREATE OPERATOR @#@
ALTER OPERATOR @#@(int8,int8) SET SCHEMA testschema_2; -- OK
CREATE OPERATOR @#@
(leftarg = int8, rightarg = int8, procedure = int8xor);
--- XXX - comment out due to error message with oid determinded at runtime
--- ALTER OPERATOR @#@(int8,int8) SET SCHEMA testschema_2; -- fail
+ALTER OPERATOR @#@(int8,int8) SET SCHEMA testschema_2; -- fail
+ERROR: operator @#@(bigint,bigint) already exists in schema "testschema_2"
CREATE OPERATOR FAMILY testopfamily_a USING btree;
CREATE OPERATOR FAMILY testopfamily_b USING btree;
ALTER OPERATOR FAMILY testopfamily_a USING btree RENAME TO testopfamily_b; -- fail
ERROR: operator family "testopfamily_b" for access method "btree" already exists in schema "testschema_1"
ALTER OPERATOR FAMILY testopfamily_b USING btree SET SCHEMA testschema_2; -- OK
ALTER OPERATOR FAMILY testopfamily_a USING btree RENAME TO testopfamily_b; -- OK
--- XXX - comment out due to error message with oid determinded at runtime
--- ALTER OPERATOR FAMILY testopfamily_b USING btree SET SCHEMA testschema_2; -- fail
+ALTER OPERATOR FAMILY testopfamily_b USING btree SET SCHEMA testschema_2; -- fail
+ERROR: operator family testopfamily_b for access method btree already exists in schema "testschema_2"
CREATE OPERATOR CLASS testopclass_a
FOR TYPE box USING btree FAMILY testopfamily_b AS OPERATOR 1 =;
CREATE OPERATOR CLASS testopclass_b
@@ -190,8 +190,8 @@ ALTER OPERATOR CLASS testopclass_a USING btree RENAME TO testopclass_b; -- fail
ERROR: operator class "testopclass_b" for access method "btree" already exists in schema "testschema_1"
ALTER OPERATOR CLASS testopclass_b USING btree SET SCHEMA testschema_2; -- OK
ALTER OPERATOR CLASS testopclass_a USING btree RENAME TO testopclass_b; -- OK
--- XXX - comment out due to error message with oid determinded at runtime
--- ALTER OPERATOR CLASS testopclass_b USING btree SET SCHEMA testschema_2; -- fail
+ALTER OPERATOR CLASS testopclass_b USING btree SET SCHEMA testschema_2; -- fail
+ERROR: operator class testopclass_b for access method btree already exists in schema "testschema_2"
--
-- TEXT SEARCH
--
@@ -229,7 +229,7 @@ ERROR: collation "testcollation_b" for encoding "UTF8" already exists in schema
ALTER COLLATION testcollation_b SET SCHEMA testschema_2; -- OK
ALTER COLLATION testcollation_a RENAME TO testcollation_b; -- OK
ALTER COLLATION testcollation_b SET SCHEMA testschema_2; -- fail
-ERROR: collation "testcollation_b" for encoding "UTF8" already exists in schema "testschema_2"
+ERROR: collation testcollation_b already exists in schema "testschema_2"
--
-- CONVERSION
--
diff --git a/src/test/regress/sql/alter_rename.sql b/src/test/regress/sql/alter_rename.sql
index 9b2bdf1..4a33b12 100644
--- a/src/test/regress/sql/alter_rename.sql
+++ b/src/test/regress/sql/alter_rename.sql
@@ -162,16 +162,14 @@ CREATE OPERATOR @#@
ALTER OPERATOR @#@(int8,int8) SET SCHEMA testschema_2; -- OK
CREATE OPERATOR @#@
(leftarg = int8, rightarg = int8, procedure = int8xor);
--- XXX - comment out due to error message with oid determinded at runtime
--- ALTER OPERATOR @#@(int8,int8) SET SCHEMA testschema_2; -- fail
+ALTER OPERATOR @#@(int8,int8) SET SCHEMA testschema_2; -- fail
CREATE OPERATOR FAMILY testopfamily_a USING btree;
CREATE OPERATOR FAMILY testopfamily_b USING btree;
ALTER OPERATOR FAMILY testopfamily_a USING btree RENAME TO testopfamily_b; -- fail
ALTER OPERATOR FAMILY testopfamily_b USING btree SET SCHEMA testschema_2; -- OK
ALTER OPERATOR FAMILY testopfamily_a USING btree RENAME TO testopfamily_b; -- OK
--- XXX - comment out due to error message with oid determinded at runtime
--- ALTER OPERATOR FAMILY testopfamily_b USING btree SET SCHEMA testschema_2; -- fail
+ALTER OPERATOR FAMILY testopfamily_b USING btree SET SCHEMA testschema_2; -- fail
CREATE OPERATOR CLASS testopclass_a
@@ -181,8 +179,7 @@ CREATE OPERATOR CLASS testopclass_b
ALTER OPERATOR CLASS testopclass_a USING btree RENAME TO testopclass_b; -- fail
ALTER OPERATOR CLASS testopclass_b USING btree SET SCHEMA testschema_2; -- OK
ALTER OPERATOR CLASS testopclass_a USING btree RENAME TO testopclass_b; -- OK
--- XXX - comment out due to error message with oid determinded at runtime
--- ALTER OPERATOR CLASS testopclass_b USING btree SET SCHEMA testschema_2; -- fail
+ALTER OPERATOR CLASS testopclass_b USING btree SET SCHEMA testschema_2; -- fail
--
-- TEXT SEARCH
pgsql-v9.2-ddl-refactoring-part-2.v1.groundworks.patchapplication/octet-stream; name=pgsql-v9.2-ddl-refactoring-part-2.v1.groundworks.patchDownload
src/backend/catalog/objectaddress.c | 577 ++++++++++++++++++++++++----
src/backend/commands/comment.c | 3 +-
src/backend/commands/dropcmds.c | 3 +-
src/backend/commands/extension.c | 3 +-
src/backend/commands/seclabel.c | 3 +-
src/include/catalog/objectaddress.h | 11 +-
src/test/regress/expected/alter_rename.out | 282 ++++++++++++++
src/test/regress/expected/privileges.out | 2 +-
src/test/regress/parallel_schedule | 2 +-
src/test/regress/serial_schedule | 1 +
src/test/regress/sql/alter_rename.sql | 240 ++++++++++++
11 files changed, 1031 insertions(+), 96 deletions(-)
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index ec4c987..bcf5259 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -53,6 +53,7 @@
#include "foreign/foreign.h"
#include "libpq/be-fsstubs.h"
#include "miscadmin.h"
+#include "mb/pg_wchar.h"
#include "nodes/makefuncs.h"
#include "parser/parse_func.h"
#include "parser/parse_oper.h"
@@ -76,8 +77,11 @@ typedef struct
{
Oid class_oid; /* oid of catalog */
Oid oid_index_oid; /* oid of index on system oid column */
+ Oid name_index_oid; /* oid of index on name/schema column */
int oid_catcache_id; /* id of catcache on system oid column */
+ int name_catcache_id; /* id of catcache on name/schema column */
AttrNumber attnum_namespace; /* attnum of namespace field */
+ AttrNumber attnum_name; /* attnum of name field */
} ObjectPropertyType;
static ObjectPropertyType ObjectProperty[] =
@@ -85,152 +89,227 @@ static ObjectPropertyType ObjectProperty[] =
{
CastRelationId,
CastOidIndexId,
+ InvalidOid,
-1,
- InvalidAttrNumber
+ -1,
+ InvalidAttrNumber,
+ InvalidAttrNumber,
},
{
CollationRelationId,
CollationOidIndexId,
+ InvalidOid, /* No suitable index on pg_collation */
COLLOID,
- Anum_pg_collation_collnamespace
+ -1, /* COLLNAMEENCNSP also takes oid of encoding */
+ Anum_pg_collation_collnamespace,
+ Anum_pg_collation_collname,
},
{
ConstraintRelationId,
ConstraintOidIndexId,
+ ConstraintNameNspIndexId,
CONSTROID,
- Anum_pg_constraint_connamespace
+ -1,
+ Anum_pg_constraint_connamespace,
+ Anum_pg_constraint_conname,
},
{
ConversionRelationId,
ConversionOidIndexId,
+ ConversionNameNspIndexId,
CONVOID,
- Anum_pg_conversion_connamespace
+ -1,
+ Anum_pg_conversion_connamespace,
+ Anum_pg_conversion_conname,
},
{
DatabaseRelationId,
DatabaseOidIndexId,
+ DatabaseNameIndexId,
DATABASEOID,
- InvalidAttrNumber
+ -1,
+ InvalidAttrNumber,
+ Anum_pg_database_datname,
},
{
ExtensionRelationId,
ExtensionOidIndexId,
+ InvalidOid,
+ -1,
-1,
- InvalidAttrNumber /* extension doesn't belong to extnamespace */
+ InvalidAttrNumber, /* extension doesn't belong to extnamespace */
+ InvalidAttrNumber, /* extension name is unavailable to change */
},
{
ForeignDataWrapperRelationId,
ForeignDataWrapperOidIndexId,
+ ForeignDataWrapperNameIndexId,
FOREIGNDATAWRAPPEROID,
- InvalidAttrNumber
+ FOREIGNDATAWRAPPERNAME,
+ InvalidAttrNumber,
+ Anum_pg_foreign_data_wrapper_fdwname,
},
{
ForeignServerRelationId,
ForeignServerOidIndexId,
+ ForeignServerNameIndexId,
FOREIGNSERVEROID,
- InvalidAttrNumber
+ FOREIGNSERVERNAME,
+ InvalidAttrNumber,
+ Anum_pg_foreign_server_srvname,
},
{
ProcedureRelationId,
ProcedureOidIndexId,
+ InvalidOid, /* No suitable index on pg_proc */
PROCOID,
- Anum_pg_proc_pronamespace
+ -1, /* PROCNAMEARGSNSP takes argument types too */
+ Anum_pg_proc_pronamespace,
+ Anum_pg_proc_proname,
},
{
LanguageRelationId,
LanguageOidIndexId,
+ LanguageNameIndexId,
LANGOID,
+ LANGNAME,
InvalidAttrNumber,
+ Anum_pg_language_lanname,
},
{
LargeObjectMetadataRelationId,
LargeObjectMetadataOidIndexId,
+ InvalidOid,
+ -1,
-1,
- InvalidAttrNumber
+ InvalidAttrNumber,
+ InvalidAttrNumber,
},
{
OperatorClassRelationId,
OpclassOidIndexId,
+ InvalidOid, /* No suitable index on pg_opclass */
CLAOID,
+ -1, /* CLANAME takes oid of access method too */
Anum_pg_opclass_opcnamespace,
+ Anum_pg_opclass_opcname,
},
{
OperatorRelationId,
OperatorOidIndexId,
+ OperatorNameNspIndexId,
OPEROID,
- Anum_pg_operator_oprnamespace
+ -1, /* OPERNAMENSP takes oid of left/right types too */
+ Anum_pg_operator_oprnamespace,
+ Anum_pg_operator_oprname,
},
{
OperatorFamilyRelationId,
OpfamilyOidIndexId,
+ InvalidOid, /* No suitable index on op_opfamily */
OPFAMILYOID,
- Anum_pg_opfamily_opfnamespace
+ -1, /* OPFAMILYAMNAMENSP takes oid of access method too */
+ Anum_pg_opfamily_opfnamespace,
+ Anum_pg_opfamily_opfname,
},
{
AuthIdRelationId,
AuthIdOidIndexId,
+ AuthIdRolnameIndexId,
AUTHOID,
- InvalidAttrNumber
+ AUTHNAME,
+ InvalidAttrNumber,
+ AuthIdRelationId,
},
{
RewriteRelationId,
RewriteOidIndexId,
+ InvalidOid, /* No suitable index on pg_rewrite */
-1,
- InvalidAttrNumber
+ -1, /* RULERELNAME takes oid of relation too */
+ InvalidAttrNumber,
+ Anum_pg_rewrite_rulename,
},
{
NamespaceRelationId,
NamespaceOidIndexId,
+ NamespaceNameIndexId,
NAMESPACEOID,
- InvalidAttrNumber
+ NAMESPACENAME,
+ InvalidAttrNumber,
+ Anum_pg_namespace_nspname,
},
{
RelationRelationId,
ClassOidIndexId,
+ ClassNameNspIndexId,
RELOID,
- Anum_pg_class_relnamespace
+ RELNAMENSP,
+ Anum_pg_class_relnamespace,
+ Anum_pg_class_relname,
},
{
TableSpaceRelationId,
TablespaceOidIndexId,
+ TablespaceNameIndexId,
TABLESPACEOID,
- InvalidAttrNumber
+ -1,
+ InvalidAttrNumber,
+ Anum_pg_tablespace_spcname,
},
{
TriggerRelationId,
TriggerOidIndexId,
+ InvalidOid, /* No suitable index on pg_trigegr */
+ -1,
-1,
- InvalidAttrNumber
+ InvalidAttrNumber,
+ Anum_pg_trigger_tgname,
},
{
TSConfigRelationId,
TSConfigOidIndexId,
+ TSConfigNameNspIndexId,
TSCONFIGOID,
- Anum_pg_ts_config_cfgnamespace
+ TSCONFIGNAMENSP,
+ Anum_pg_ts_config_cfgnamespace,
+ Anum_pg_ts_config_cfgname,
},
{
TSDictionaryRelationId,
TSDictionaryOidIndexId,
+ TSDictionaryNameNspIndexId,
TSDICTOID,
- Anum_pg_ts_dict_dictnamespace
+ TSDICTNAMENSP,
+ Anum_pg_ts_dict_dictnamespace,
+ Anum_pg_ts_dict_dictname,
},
{
TSParserRelationId,
TSParserOidIndexId,
+ TSParserNameNspIndexId,
TSPARSEROID,
- Anum_pg_ts_parser_prsnamespace
+ TSPARSERNAMENSP,
+ Anum_pg_ts_parser_prsnamespace,
+ Anum_pg_ts_parser_prsname,
},
{
TSTemplateRelationId,
TSTemplateOidIndexId,
+ TSTemplateNameNspIndexId,
TSTEMPLATEOID,
+ TSTEMPLATENAMENSP,
Anum_pg_ts_template_tmplnamespace,
+ Anum_pg_ts_template_tmplname,
},
{
TypeRelationId,
TypeOidIndexId,
+ TypeNameNspIndexId,
TYPEOID,
- Anum_pg_type_typnamespace
+ TYPENAMENSP,
+ Anum_pg_type_typnamespace,
+ Anum_pg_type_typname,
}
};
@@ -914,93 +993,129 @@ object_exists(ObjectAddress address)
* Check ownership of an object previously identified by get_object_address.
*/
void
-check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address,
- List *objname, List *objargs, Relation relation)
+check_object_ownership(Oid roleid, ObjectAddress address, Relation relation)
{
- switch (objtype)
+ switch (address.classId)
{
- case OBJECT_INDEX:
- case OBJECT_SEQUENCE:
- case OBJECT_TABLE:
- case OBJECT_VIEW:
- case OBJECT_FOREIGN_TABLE:
- case OBJECT_COLUMN:
- case OBJECT_RULE:
- case OBJECT_TRIGGER:
- case OBJECT_CONSTRAINT:
+ case RelationRelationId:
+ case RewriteRelationId:
+ case TriggerRelationId:
+ case ConstraintRelationId:
if (!pg_class_ownercheck(RelationGetRelid(relation), roleid))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
RelationGetRelationName(relation));
break;
- case OBJECT_DATABASE:
+ case DatabaseRelationId:
if (!pg_database_ownercheck(address.objectId, roleid))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DATABASE,
- NameListToString(objname));
+ get_database_name(address.objectId));
break;
- case OBJECT_TYPE:
- case OBJECT_DOMAIN:
- case OBJECT_ATTRIBUTE:
+ case TypeRelationId:
if (!pg_type_ownercheck(address.objectId, roleid))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE,
format_type_be(address.objectId));
break;
- case OBJECT_AGGREGATE:
- case OBJECT_FUNCTION:
+ case ProcedureRelationId:
if (!pg_proc_ownercheck(address.objectId, roleid))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC,
- NameListToString(objname));
+ format_procedure(address.objectId));
break;
- case OBJECT_OPERATOR:
+ case OperatorRelationId:
if (!pg_oper_ownercheck(address.objectId, roleid))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPER,
- NameListToString(objname));
+ format_operator(address.objectId));
break;
- case OBJECT_SCHEMA:
+ case NamespaceRelationId:
if (!pg_namespace_ownercheck(address.objectId, roleid))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_NAMESPACE,
- NameListToString(objname));
+ get_namespace_name(address.objectId));
break;
- case OBJECT_COLLATION:
+ case CollationRelationId:
if (!pg_collation_ownercheck(address.objectId, roleid))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_COLLATION,
- NameListToString(objname));
+ get_collation_name(address.objectId));
break;
- case OBJECT_CONVERSION:
+ case ConversionRelationId:
if (!pg_conversion_ownercheck(address.objectId, roleid))
+ {
+ char *convname = NULL;
+ HeapTuple tup = SearchSysCache1(CONVOID,
+ ObjectIdGetDatum(address.objectId));
+ if (HeapTupleIsValid(tup))
+ {
+ Form_pg_conversion conversion
+ = (Form_pg_conversion) GETSTRUCT(tup);
+ convname = pstrdup(NameStr(conversion->conname));
+ ReleaseSysCache(tup);
+ }
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CONVERSION,
- NameListToString(objname));
+ convname);
+ }
break;
- case OBJECT_EXTENSION:
+ case ExtensionRelationId:
if (!pg_extension_ownercheck(address.objectId, roleid))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_EXTENSION,
- NameListToString(objname));
+ get_extension_name(address.objectId));
break;
- case OBJECT_FDW:
+ case ForeignDataWrapperRelationId:
if (!pg_foreign_data_wrapper_ownercheck(address.objectId, roleid))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_FDW,
- NameListToString(objname));
+ GetForeignDataWrapper(address.objectId)->fdwname);
break;
- case OBJECT_FOREIGN_SERVER:
+ case ForeignServerRelationId:
if (!pg_foreign_server_ownercheck(address.objectId, roleid))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_FOREIGN_SERVER,
- NameListToString(objname));
+ GetForeignServer(address.objectId)->servername);
break;
- case OBJECT_LANGUAGE:
+ case LanguageRelationId:
if (!pg_language_ownercheck(address.objectId, roleid))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_LANGUAGE,
- NameListToString(objname));
+ {
+ char *lanname = NULL;
+ HeapTuple tup = SearchSysCache1(LANGOID,
+ ObjectIdGetDatum(address.objectId));
+ if (HeapTupleIsValid(tup))
+ {
+ Form_pg_language lang
+ = (Form_pg_language) GETSTRUCT(tup);
+ lanname = pstrdup(NameStr(lang->lanname));
+ ReleaseSysCache(tup);
+ }
+ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_LANGUAGE, lanname);
+ }
break;
- case OBJECT_OPCLASS:
+ case OperatorClassRelationId:
if (!pg_opclass_ownercheck(address.objectId, roleid))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPCLASS,
- NameListToString(objname));
+ {
+ char *opcname = NULL;
+ HeapTuple tup = SearchSysCache1(CLAOID,
+ ObjectIdGetDatum(address.objectId));
+ if (HeapTupleIsValid(tup))
+ {
+ Form_pg_opclass opclass
+ = (Form_pg_opclass) GETSTRUCT(tup);
+ opcname = pstrdup(NameStr(opclass->opcname));
+ ReleaseSysCache(tup);
+ }
+ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPCLASS, opcname);
+ }
break;
- case OBJECT_OPFAMILY:
+ case OperatorFamilyRelationId:
if (!pg_opfamily_ownercheck(address.objectId, roleid))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPFAMILY,
- NameListToString(objname));
+ {
+ char *opfname = NULL;
+ HeapTuple tup = SearchSysCache1(OPFAMILYOID,
+ ObjectIdGetDatum(address.objectId));
+ if (HeapTupleIsValid(tup))
+ {
+ Form_pg_opfamily opfamily
+ = (Form_pg_opfamily) GETSTRUCT(tup);
+ opfname = pstrdup(NameStr(opfamily->opfname));
+ ReleaseSysCache(tup);
+ }
+ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPFAMILY, opfname);
+ }
break;
- case OBJECT_LARGEOBJECT:
+ case LargeObjectRelationId:
if (!lo_compat_privileges &&
!pg_largeobject_ownercheck(address.objectId, roleid))
ereport(ERROR,
@@ -1008,14 +1123,36 @@ check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address,
errmsg("must be owner of large object %u",
address.objectId)));
break;
- case OBJECT_CAST:
+ case CastRelationId:
{
- /* We can only check permissions on the source/target types */
- TypeName *sourcetype = (TypeName *) linitial(objname);
- TypeName *targettype = (TypeName *) linitial(objargs);
- Oid sourcetypeid = typenameTypeId(NULL, sourcetype);
- Oid targettypeid = typenameTypeId(NULL, targettype);
+ Relation catalog;
+ ScanKeyData skey[1];
+ SysScanDesc scan;
+ HeapTuple tup;
+ Oid sourcetypeid;
+ Oid targettypeid;
+
+ catalog = heap_open(CastRelationId, AccessShareLock);
+
+ ScanKeyInit(&skey[0],
+ ObjectIdAttributeNumber,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(address.objectId));
+
+ scan = systable_beginscan(catalog, CastOidIndexId, true,
+ SnapshotNow, 1, skey);
+ tup = systable_getnext(scan);
+ if (!HeapTupleIsValid(tup))
+ elog(ERROR, "could not find tuple for cast %u",
+ address.objectId);
+
+ sourcetypeid = ((Form_pg_cast) GETSTRUCT(tup))->castsource;
+ targettypeid = ((Form_pg_cast) GETSTRUCT(tup))->casttarget;
+
+ systable_endscan(scan);
+ heap_close(catalog, AccessShareLock);
+ /* We can only check permissions on the source/target types */
if (!pg_type_ownercheck(sourcetypeid, roleid)
&& !pg_type_ownercheck(targettypeid, roleid))
ereport(ERROR,
@@ -1025,23 +1162,46 @@ check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address,
format_type_be(targettypeid))));
}
break;
- case OBJECT_TABLESPACE:
+ case TableSpaceRelationId:
if (!pg_tablespace_ownercheck(address.objectId, roleid))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TABLESPACE,
- NameListToString(objname));
+ get_tablespace_name(address.objectId));
break;
- case OBJECT_TSDICTIONARY:
+ case TSDictionaryRelationId:
if (!pg_ts_dict_ownercheck(address.objectId, roleid))
+ {
+ char *dictname = NULL;
+ HeapTuple tup = SearchSysCache1(TSDICTOID,
+ ObjectIdGetDatum(address.objectId));
+ if (HeapTupleIsValid(tup))
+ {
+ Form_pg_ts_dict tsdict
+ = (Form_pg_ts_dict) GETSTRUCT(tup);
+ dictname = pstrdup(NameStr(tsdict->dictname));
+ ReleaseSysCache(tup);
+ }
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSDICTIONARY,
- NameListToString(objname));
+ dictname);
+ }
break;
- case OBJECT_TSCONFIGURATION:
+ case TSConfigRelationId:
if (!pg_ts_config_ownercheck(address.objectId, roleid))
+ {
+ char *confname = NULL;
+ HeapTuple tup = SearchSysCache1(TSCONFIGOID,
+ ObjectIdGetDatum(address.objectId));
+ if (HeapTupleIsValid(tup))
+ {
+ Form_pg_ts_config tsconf
+ = (Form_pg_ts_config) GETSTRUCT(tup);
+ confname = pstrdup(NameStr(tsconf->cfgname));
+ ReleaseSysCache(tup);
+ }
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSCONFIGURATION,
- NameListToString(objname));
+ confname);
+ }
break;
- case OBJECT_ROLE:
-
+ case AuthIdRelationId:
/*
* We treat roles as being "owned" by those with CREATEROLE priv,
* except that superusers are only owned by superusers.
@@ -1061,8 +1221,8 @@ check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address,
errmsg("must have CREATEROLE privilege")));
}
break;
- case OBJECT_TSPARSER:
- case OBJECT_TSTEMPLATE:
+ case TSParserRelationId:
+ case TSTemplateRelationId:
/* We treat these object types as being owned by superusers */
if (!superuser_arg(roleid))
ereport(ERROR,
@@ -1070,9 +1230,258 @@ check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address,
errmsg("must be superuser")));
break;
default:
- elog(ERROR, "unrecognized object type: %d",
- (int) objtype);
+ elog(ERROR, "unrecognized class-id of the object: %u",
+ address.classId);
+ }
+}
+
+/*
+ * check_exists_namespace
+ *
+ * check name or/and namespace conflict of the supplied object, if and
+ * when its name or namespace would be switched to.
+ */
+bool
+object_exists_namespace(ObjectAddress address,
+ Oid new_namespace, const char *new_name)
+{
+ ObjectPropertyType *property;
+ HeapTuple tuple;
+ Datum datum;
+ bool isnull;
+ bool found = false;
+
+ /*
+ * Right now, we have no code path to invoke this routine toward
+ * pg_attribute, pg_trigger or pg_rewrite; that takes special
+ * treatments.
+ */
+ Assert(address.objectSubId == 0);
+ Assert(address.classId != TriggerRelationId);
+ Assert(address.classId != RewriteRelationId);
+
+ /*
+ * Weird backward compatibility hack: ObjectAddress notation uses
+ * LargeObjectRelationId for large objects, but since PostgreSQL
+ * 9.0, the relevant catalog is actually LargeObjectMetadataRelationId.
+ */
+ if (address.classId == LargeObjectRelationId)
+ address.classId = LargeObjectMetadataRelationId;
+
+ property = get_object_property_data(address.classId);
+
+ /* This routine must be called towards object classes with its name. */
+ Assert(property->attnum_name != InvalidAttrNumber);
+
+ /* We have catcache by oid for named object types */
+ Assert(property->oid_catcache_id != -1);
+
+ tuple = SearchSysCache1(property->oid_catcache_id,
+ ObjectIdGetDatum(address.objectId));
+ if (!HeapTupleIsValid(tuple))
+ elog(ERROR, "cache lookup failed for class %u object %u subobj %d",
+ address.classId, address.objectId, address.objectSubId);
+
+ /*
+ * if namespace is preserved, the current one shall be used as
+ * a key to look up system catalog.
+ */
+ if (!OidIsValid(new_namespace) &&
+ property->attnum_namespace != InvalidAttrNumber)
+ {
+
+ datum = SysCacheGetAttr(property->oid_catcache_id,
+ tuple,
+ property->attnum_namespace,
+ &isnull);
+ Assert(!isnull);
+ new_namespace = DatumGetObjectId(datum);
+ }
+
+ /*
+ * if name is preserved, the current one shall be used as
+ * a key to look up system catalog.
+ */
+ if (!new_name)
+ {
+ datum = SysCacheGetAttr(property->oid_catcache_id,
+ tuple,
+ property->attnum_name,
+ &isnull);
+ Assert(!isnull);
+ new_name = pstrdup(NameStr(*(DatumGetName(datum))));
+ }
+ Assert(new_name != NULL);
+
+ /* COLLNAMEENCNSP cache takes encoding type, so special treatment too */
+ if (address.classId == CollationRelationId)
+ {
+ if (SearchSysCacheExists3(COLLNAMEENCNSP,
+ CStringGetDatum(new_name),
+ Int32GetDatum(GetDatabaseEncoding()),
+ ObjectIdGetDatum(new_namespace)))
+ found = true;
+ /* mustn't match an any-encoding entry, either */
+ if (SearchSysCacheExists3(COLLNAMEENCNSP,
+ CStringGetDatum(new_name),
+ Int32GetDatum(-1),
+ ObjectIdGetDatum(new_namespace)))
+ found = true;
}
+ /* PROCNAMEARGSNSP cache takes argument types too */
+ else if (address.classId == ProcedureRelationId)
+ {
+ Form_pg_proc procForm = (Form_pg_proc) GETSTRUCT(tuple);
+
+ if (SearchSysCacheExists3(PROCNAMEARGSNSP,
+ CStringGetDatum(new_name),
+ PointerGetDatum(&procForm->proargtypes),
+ ObjectIdGetDatum(new_namespace)))
+ found = true;
+ }
+ /* OPERNAMENSP cache takes oid of left/right types too */
+ else if (address.classId == OperatorRelationId)
+ {
+ Oid oprleft = ((Form_pg_operator) GETSTRUCT(tuple))->oprleft;
+ Oid oprright = ((Form_pg_operator) GETSTRUCT(tuple))->oprright;
+
+ if (SearchSysCacheExists4(OPERNAMENSP,
+ CStringGetDatum(new_name),
+ ObjectIdGetDatum(oprleft),
+ ObjectIdGetDatum(oprright),
+ ObjectIdGetDatum(new_namespace)))
+ found = true;
+ }
+ /* CLAAMNAMENSP cache takes oid of access method too */
+ else if (address.classId == OperatorClassRelationId)
+ {
+ Oid amoid = ((Form_pg_opclass) GETSTRUCT(tuple))->opcmethod;
+
+ if (SearchSysCacheExists3(CLAAMNAMENSP,
+ ObjectIdGetDatum(amoid),
+ CStringGetDatum(new_name),
+ ObjectIdGetDatum(new_namespace)))
+ found = true;
+ }
+ /* OPFAMILYAMNAMENSP cache takes oid of access method too */
+ else if (address.classId == OperatorFamilyRelationId)
+ {
+ Oid amoid = ((Form_pg_opfamily) GETSTRUCT(tuple))->opfmethod;
+
+ if (SearchSysCacheExists3(OPFAMILYAMNAMENSP,
+ ObjectIdGetDatum(amoid),
+ CStringGetDatum(new_name),
+ ObjectIdGetDatum(new_namespace)))
+ found = true;
+ }
+ else if (property->name_catcache_id != -1)
+ {
+ found = SearchSysCacheExists2(property->name_catcache_id,
+ CStringGetDatum(new_name),
+ ObjectIdGetDatum(new_namespace));
+ }
+ else
+ {
+ Relation rel;
+ ScanKeyData skey[2];
+ SysScanDesc scan;
+ int nkeys;
+
+ /* No syscache, so examine the table directly. */
+ Assert(OidIsValid(property->name_index_oid));
+
+ ScanKeyInit(&skey[0],
+ property->attnum_name,
+ BTEqualStrategyNumber, F_NAMEEQ,
+ CStringGetDatum(new_name));
+ if (property->attnum_namespace == InvalidAttrNumber)
+ nkeys = 1;
+ else
+ {
+ ScanKeyInit(&skey[1],
+ property->attnum_namespace,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(new_namespace));
+ nkeys = 2;
+ }
+
+ rel = heap_open(address.classId, AccessShareLock);
+ scan = systable_beginscan(rel, property->name_index_oid, true,
+ SnapshotNow, nkeys, skey);
+ found = HeapTupleIsValid(systable_getnext(scan));
+ systable_endscan(scan);
+ heap_close(rel, AccessShareLock);
+ }
+ ReleaseSysCache(tuple);
+
+ return found;
+}
+
+/*
+ * get_object_tuple
+ *
+ * It returns a copy of heaptuple data within system catalog.
+ */
+HeapTuple
+get_object_tuple(ObjectAddress address)
+{
+ int cache = -1;
+ Oid indexoid = InvalidOid;
+ Relation rel;
+ ScanKeyData skey[1];
+ SysScanDesc sd;
+ HeapTuple tuple = NULL;
+ ObjectPropertyType *property;
+
+ /* Sub-objects require special treatment. */
+ if (address.objectSubId != 0)
+ {
+ /* Currently, attributes are the only sub-objects. */
+ Assert(address.classId == RelationRelationId);
+ tuple = SearchSysCacheCopy2(ATTNUM,
+ ObjectIdGetDatum(address.objectId),
+ Int16GetDatum(address.objectSubId));
+ if (((Form_pg_attribute) GETSTRUCT(tuple))->attisdropped)
+ {
+ heap_freetuple(tuple);
+ return NULL;
+ }
+ return tuple;
+ }
+
+ /*
+ * Weird backward compatibility hack: ObjectAddress notation uses
+ * LargeObjectRelationId for large objects, but since PostgreSQL
+ * 9.0, the relevant catalog is actually LargeObjectMetadataRelationId.
+ */
+ if (address.classId == LargeObjectRelationId)
+ address.classId = LargeObjectMetadataRelationId;
+
+ /*
+ * For object types that have a relevant syscache, we use it; for
+ * everything else, we'll have to do an index-scan.
+ */
+ property = get_object_property_data(address.classId);
+ cache = property->oid_catcache_id;
+ indexoid = property->oid_index_oid;
+
+ /* Found a syscache? */
+ if (cache != -1)
+ return SearchSysCacheCopy1(cache, ObjectIdGetDatum(address.objectId));
+
+ /* No syscache, so examine the table directly. */
+ Assert(OidIsValid(indexoid));
+ ScanKeyInit(&skey[0],
+ ObjectIdAttributeNumber,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(address.objectId));
+ rel = heap_open(address.classId, AccessShareLock);
+ sd = systable_beginscan(rel, indexoid, true, SnapshotNow, 1, skey);
+ tuple = heap_copytuple(systable_getnext(sd));
+ systable_endscan(sd);
+ heap_close(rel, AccessShareLock);
+
+ return tuple;
}
/*
diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c
index 200b6a2..34705e5 100644
--- a/src/backend/commands/comment.c
+++ b/src/backend/commands/comment.c
@@ -73,8 +73,7 @@ CommentObject(CommentStmt *stmt)
&relation, ShareUpdateExclusiveLock, false);
/* Require ownership of the target object. */
- check_object_ownership(GetUserId(), stmt->objtype, address,
- stmt->objname, stmt->objargs, relation);
+ check_object_ownership(GetUserId(), address, relation);
/* Perform other integrity checks as needed. */
switch (stmt->objtype)
diff --git a/src/backend/commands/dropcmds.c b/src/backend/commands/dropcmds.c
index ef70168..2cd8232 100644
--- a/src/backend/commands/dropcmds.c
+++ b/src/backend/commands/dropcmds.c
@@ -98,8 +98,7 @@ RemoveObjects(DropStmt *stmt)
namespaceId = get_object_namespace(&address);
if (!OidIsValid(namespaceId) ||
!pg_namespace_ownercheck(namespaceId, GetUserId()))
- check_object_ownership(GetUserId(), stmt->removeType, address,
- objname, objargs, relation);
+ check_object_ownership(GetUserId(), address, relation);
}
/* Release any relcache reference count, but keep lock until commit. */
diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index c334ca9..5a2cc09 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -2652,8 +2652,7 @@ ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt)
&relation, ShareUpdateExclusiveLock, false);
/* Permission check: must own target object, too */
- check_object_ownership(GetUserId(), stmt->objtype, object,
- stmt->objname, stmt->objargs, relation);
+ check_object_ownership(GetUserId(), object, relation);
/*
* Check existing extension membership.
diff --git a/src/backend/commands/seclabel.c b/src/backend/commands/seclabel.c
index e0fd7ac..118f467 100644
--- a/src/backend/commands/seclabel.c
+++ b/src/backend/commands/seclabel.c
@@ -90,8 +90,7 @@ ExecSecLabelStmt(SecLabelStmt *stmt)
&relation, ShareUpdateExclusiveLock, false);
/* Require ownership of the target object. */
- check_object_ownership(GetUserId(), stmt->objtype, address,
- stmt->objname, stmt->objargs, relation);
+ check_object_ownership(GetUserId(), address, relation);
/* Perform other integrity checks as needed. */
switch (stmt->objtype)
diff --git a/src/include/catalog/objectaddress.h b/src/include/catalog/objectaddress.h
index eddccb8..ff7b957 100644
--- a/src/include/catalog/objectaddress.h
+++ b/src/include/catalog/objectaddress.h
@@ -13,6 +13,7 @@
#ifndef OBJECTADDRESS_H
#define OBJECTADDRESS_H
+#include "access/htup.h"
#include "nodes/parsenodes.h"
#include "storage/lock.h"
#include "utils/relcache.h"
@@ -32,8 +33,14 @@ extern ObjectAddress get_object_address(ObjectType objtype, List *objname,
LOCKMODE lockmode, bool missing_ok);
extern void check_object_ownership(Oid roleid,
- ObjectType objtype, ObjectAddress address,
- List *objname, List *objargs, Relation relation);
+ ObjectAddress address,
+ Relation relation);
+
+extern bool object_exists_namespace(ObjectAddress address,
+ Oid new_namespace,
+ const char *new_name);
+
+extern HeapTuple get_object_tuple(ObjectAddress address);
extern Oid get_object_namespace(const ObjectAddress *address);
diff --git a/src/test/regress/expected/alter_rename.out b/src/test/regress/expected/alter_rename.out
new file mode 100644
index 0000000..6688d50
--- /dev/null
+++ b/src/test/regress/expected/alter_rename.out
@@ -0,0 +1,282 @@
+--
+-- ALTER xxx RENAME TO/SET SCHEMA statement
+--
+CREATE SCHEMA testschema_1;
+CREATE SCHEMA testschema_2;
+SET search_path = testschema_1, public;
+--
+-- ROLE
+--
+CREATE ROLE testrole_1;
+CREATE ROLE testrole_2;
+ALTER ROLE testrole_1 RENAME TO testrole_2; -- fail
+ERROR: role "testrole_2" already exists
+ALTER ROLE testrole_1 RENAME TO testrole_3; -- OK
+DROP ROLE testrole_2, testrole_3;
+--
+-- LANGUAGE
+--
+CREATE LANGUAGE testlang_1 HANDLER plpgsql_call_handler;
+CREATE LANGUAGE testlang_2 HANDLER plpgsql_call_handler;
+ALTER LANGUAGE testlang_1 RENAME TO testlang_2; -- fail
+ERROR: language "testlang_2" already exists
+ALTER LANGUAGE testlang_1 RENAME TO testlang_3; -- OK
+DROP LANGUAGE testlang_2;
+DROP LANGUAGE testlang_3;
+--
+-- TABLE
+--
+CREATE TABLE testtable_a(a int, b int);
+CREATE TABLE testtable_b(x int, y int);
+ALTER TABLE testtable_a RENAME TO testtable_b; -- fail
+ERROR: relation "testtable_b" already exists
+ALTER TABLE testtable_b SET SCHEMA testschema_2; -- OK
+ALTER TABLE testtable_a RENAME TO testtable_b; -- OK
+ALTER TABLE testtable_b SET SCHEMA testschema_2; -- fail
+ERROR: relation "testtable_b" already exists in schema "testschema_2"
+--
+-- VIEW
+--
+CREATE VIEW testview_a AS SELECT * FROM pg_class WHERE relname like 'pg_%';
+CREATE VIEW testview_b AS SELECT * FROM pg_class WHERE relname like 'pg_%';
+ALTER VIEW testview_a RENAME TO testview_b; -- fail
+ERROR: relation "testview_b" already exists
+ALTER VIEW testview_b SET SCHEMA testschema_2; -- OK
+ALTER VIEW testview_a RENAME TO testview_b; -- OK
+ALTER VIEW testview_b SET SCHEMA testschema_2; -- fail
+ERROR: relation "testview_b" already exists in schema "testschema_2"
+ALTER VIEW testtable_b SET SCHEMA public; -- fail
+ERROR: "testtable_b" is not a view
+ALTER VIEW testtable_b RENAME TO testtable_c; -- fail
+ERROR: "testtable_b" is not a view
+--
+-- SEQUENCE
+--
+CREATE SEQUENCE testseq_a;
+CREATE SEQUENCE testseq_b;
+ALTER SEQUENCE testseq_a RENAME TO testseq_b; -- fail
+ERROR: relation "testseq_b" already exists
+ALTER SEQUENCE testseq_b SET SCHEMA testschema_2; -- OK
+ALTER SEQUENCE testseq_a RENAME TO testseq_b; -- OK
+ALTER SEQUENCE testseq_b SET SCHEMA testschema_2; -- fail
+ERROR: relation "testseq_b" already exists in schema "testschema_2"
+ALTER SEQUENCE testview_b SET SCHEMA public; -- fail
+ERROR: "testview_b" is not a sequence
+ALTER SEQUENCE testview_b RENAME TO testview_c; -- fail
+ERROR: "testview_b" is not a sequence
+--
+-- COMPOSITE TYPE
+--
+CREATE TYPE testcomptype_a AS (a int, b int);
+CREATE TYPE testcomptype_b AS (a int, b int);
+ALTER TYPE testcomptype_a RENAME TO testcomptype_b; -- fail
+ERROR: relation "testcomptype_b" already exists
+ALTER TYPE testcomptype_b SET SCHEMA testschema_2; -- OK
+ALTER TYPE testcomptype_a RENAME TO testcomptype_b; -- OK
+ALTER TYPE testcomptype_b SET SCHEMA testschema_2; -- fail
+ERROR: type "testcomptype_b" already exists in schema "testschema_2"
+ALTER TYPE testseq_b SET SCHEMA public; -- fail
+ERROR: testseq_b is a table's row type
+HINT: Use ALTER TABLE instead.
+ALTER TYPE testseq_b RENAME TO testseq_c; -- fail
+ERROR: testseq_b is a table's row type
+HINT: Use ALTER TABLE instead.
+--
+-- INDEX
+--
+CREATE INDEX testindex_a ON testtable_b (a);
+CREATE INDEX testindex_b ON testtable_b (b);
+ALTER INDEX testindex_a RENAME TO testindex_b; -- fail
+ERROR: relation "testindex_b" already exists
+ALTER INDEX testindex_a RENAME TO testindex_c; -- OK
+--
+-- COLUMN
+--
+ALTER TABLE testtable_b RENAME a TO b; -- fail
+ERROR: column "b" of relation "testtable_b" already exists
+ALTER TABLE testtable_b RENAME a TO x; -- OK
+CREATE TABLE testtable_c (z int) INHERITS (testtable_b);
+ALTER TABLE ONLY testtable_b RENAME b TO y; -- fail
+ERROR: inherited column "b" must be renamed in child tables too
+ALTER TABLE testtable_b RENAME b TO y; -- OK
+ALTER TABLE testtable_c RENAME z TO zz; -- OK
+ALTER TABLE testtable_c RENAME x TO xx; -- fail
+ERROR: cannot rename inherited column "x"
+--
+-- TRIGGER
+--
+CREATE TRIGGER testtrigger_a
+ BEFORE UPDATE ON testtable_b
+ FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger();
+CREATE TRIGGER testtrigger_b
+ BEFORE UPDATE ON testtable_b
+ FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger();
+ALTER TRIGGER testtrigger_a ON testtable_b RENAME TO testtrigger_b; -- fail
+ERROR: trigger "testtrigger_b" for relation "testtable_b" already exists
+ALTER TRIGGER testtrigger_a ON testtable_b RENAME TO testtrigger_c; -- OK
+--
+-- FUNCTION, AGGREGATE
+--
+CREATE FUNCTION testfunc_a(int)
+ RETURNS int LANGUAGE sql
+ AS 'SELECT $1 + $1';
+CREATE FUNCTION testfunc_b(int)
+ RETURNS int LANGUAGE sql
+ AS 'SELECT $1 + $1';
+ALTER FUNCTION testfunc_a(int) RENAME TO testfunc_b; -- fail
+ERROR: function testfunc_b(integer) already exists in schema "testschema_1"
+ALTER FUNCTION testfunc_b(int) SET SCHEMA testschema_2; -- OK
+ALTER FUNCTION testfunc_a(int) RENAME TO testfunc_b; -- OK
+ALTER FUNCTION testfunc_b(int) SET SCHEMA testschema_2; -- fail
+ERROR: function "testfunc_b" already exists in schema "testschema_2"
+CREATE AGGREGATE testagg_a(
+ sfunc1 = int4pl, basetype = int4, stype1 = int4,
+ initcond1 = '0'
+);
+CREATE AGGREGATE testagg_b(
+ sfunc1 = int4pl, basetype = int4, stype1 = int4,
+ initcond1 = '0'
+);
+ALTER AGGREGATE testagg_a(int) RENAME TO testagg_b; -- fail
+ERROR: function testagg_b(integer) already exists in schema "testschema_1"
+ALTER AGGREGATE testagg_b(int) SET SCHEMA testschema_2; -- OK
+ALTER AGGREGATE testagg_a(int) RENAME TO testagg_b; -- OK
+ALTER AGGREGATE testagg_b(int) SET SCHEMA testschema_2; -- fail
+ERROR: function "testagg_b" already exists in schema "testschema_2"
+--
+-- TYPE
+--
+CREATE TYPE testtype_a;
+CREATE TYPE testtype_b;
+CREATE FUNCTION testtype_a_in (cstring) RETURNS testtype_a LANGUAGE 'internal' AS 'int4in';
+NOTICE: return type testtype_a is only a shell
+CREATE FUNCTION testtype_b_in (cstring) RETURNS testtype_b LANGUAGE 'internal' AS 'int4in';
+NOTICE: return type testtype_b is only a shell
+CREATE FUNCTION testtype_a_out (testtype_a) RETURNS cstring LANGUAGE 'internal' AS 'int4out';
+NOTICE: argument type testtype_a is only a shell
+CREATE FUNCTION testtype_b_out (testtype_b) RETURNS cstring LANGUAGE 'internal' AS 'int4out';
+NOTICE: argument type testtype_b is only a shell
+CREATE TYPE testtype_a (internallength = 4, input = testtype_a_in, output = testtype_a_out);
+CREATE TYPE testtype_b (internallength = 4, input = testtype_b_in, output = testtype_b_out);
+ALTER TYPE testtype_a RENAME TO testtype_b; -- fail
+ERROR: type "testtype_b" already exists
+ALTER TYPE testtype_b SET SCHEMA testschema_2; -- OK
+ALTER TYPE testtype_a RENAME TO testtype_b; -- OK
+ALTER TYPE testtype_b SET SCHEMA testschema_2; -- fail
+ERROR: type "testtype_b" already exists in schema "testschema_2"
+--
+-- OPERATOR, OPERATOR FAMILY and OPERATOR CLASS
+--
+CREATE OPERATOR @#@
+ (leftarg = int8, rightarg = int8, procedure = int8xor);
+ALTER OPERATOR @#@(int8,int8) SET SCHEMA testschema_2; -- OK
+CREATE OPERATOR @#@
+ (leftarg = int8, rightarg = int8, procedure = int8xor);
+-- XXX - comment out due to error message with oid determinded at runtime
+-- ALTER OPERATOR @#@(int8,int8) SET SCHEMA testschema_2; -- fail
+CREATE OPERATOR FAMILY testopfamily_a USING btree;
+CREATE OPERATOR FAMILY testopfamily_b USING btree;
+ALTER OPERATOR FAMILY testopfamily_a USING btree RENAME TO testopfamily_b; -- fail
+ERROR: operator family "testopfamily_b" for access method "btree" already exists in schema "testschema_1"
+ALTER OPERATOR FAMILY testopfamily_b USING btree SET SCHEMA testschema_2; -- OK
+ALTER OPERATOR FAMILY testopfamily_a USING btree RENAME TO testopfamily_b; -- OK
+-- XXX - comment out due to error message with oid determinded at runtime
+-- ALTER OPERATOR FAMILY testopfamily_b USING btree SET SCHEMA testschema_2; -- fail
+CREATE OPERATOR CLASS testopclass_a
+ FOR TYPE box USING btree FAMILY testopfamily_b AS OPERATOR 1 =;
+CREATE OPERATOR CLASS testopclass_b
+ FOR TYPE circle USING btree FAMILY testopfamily_b AS OPERATOR 1 =;
+ALTER OPERATOR CLASS testopclass_a USING btree RENAME TO testopclass_b; -- fail
+ERROR: operator class "testopclass_b" for access method "btree" already exists in schema "testschema_1"
+ALTER OPERATOR CLASS testopclass_b USING btree SET SCHEMA testschema_2; -- OK
+ALTER OPERATOR CLASS testopclass_a USING btree RENAME TO testopclass_b; -- OK
+-- XXX - comment out due to error message with oid determinded at runtime
+-- ALTER OPERATOR CLASS testopclass_b USING btree SET SCHEMA testschema_2; -- fail
+--
+-- TEXT SEARCH
+--
+CREATE TEXT SEARCH DICTIONARY testtsdict_a (
+ Template=ispell,
+ DictFile=ispell_sample,
+ AffFile=ispell_sample
+);
+CREATE TEXT SEARCH DICTIONARY testtsdict_b (
+ Template=ispell,
+ DictFile=ispell_sample,
+ AffFile=ispell_sample
+);
+ALTER TEXT SEARCH DICTIONARY testtsdict_a RENAME TO testtsdict_b; -- fail
+ERROR: text search dictionary "testtsdict_b" already exists
+ALTER TEXT SEARCH DICTIONARY testtsdict_b SET SCHEMA testschema_2; -- OK
+ALTER TEXT SEARCH DICTIONARY testtsdict_a RENAME TO testtsdict_b; -- OK
+ALTER TEXT SEARCH DICTIONARY testtsdict_b SET SCHEMA testschema_2; -- fail
+ERROR: text search dictionary testtsdict_b already exists in schema "testschema_2"
+CREATE TEXT SEARCH CONFIGURATION testtsconf_a (COPY=english);
+CREATE TEXT SEARCH CONFIGURATION testtsconf_b (COPY=english);
+ALTER TEXT SEARCH CONFIGURATION testtsconf_a RENAME TO testtsconf_b; -- fail
+ERROR: text search configuration "testtsconf_b" already exists
+ALTER TEXT SEARCH CONFIGURATION testtsconf_b SET SCHEMA testschema_2; -- OK
+ALTER TEXT SEARCH CONFIGURATION testtsconf_a RENAME TO testtsconf_b; -- OK
+ALTER TEXT SEARCH CONFIGURATION testtsconf_b SET SCHEMA testschema_2; -- fail
+ERROR: text search configuration testtsconf_b already exists in schema "testschema_2"
+--
+-- COLLATION
+--
+CREATE COLLATION testcollation_a FROM "C";
+CREATE COLLATION testcollation_b FROM "C";
+ALTER COLLATION testcollation_a RENAME TO testcollation_b; -- fail
+ERROR: collation "testcollation_b" for encoding "UTF8" already exists in schema "testschema_1"
+ALTER COLLATION testcollation_b SET SCHEMA testschema_2; -- OK
+ALTER COLLATION testcollation_a RENAME TO testcollation_b; -- OK
+ALTER COLLATION testcollation_b SET SCHEMA testschema_2; -- fail
+ERROR: collation "testcollation_b" for encoding "UTF8" already exists in schema "testschema_2"
+--
+-- CONVERSION
+--
+CREATE CONVERSION testconv_a FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8;
+CREATE CONVERSION testconv_b FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8;
+ALTER CONVERSION testconv_a RENAME TO testconv_b; -- fail
+ERROR: conversion "testconv_b" already exists in schema "testschema_1"
+ALTER CONVERSION testconv_b SET SCHEMA testschema_2; -- OK
+ALTER CONVERSION testconv_a RENAME TO testconv_b; -- OK
+ALTER CONVERSION testconv_b SET SCHEMA testschema_2; -- fail
+ERROR: conversion testconv_b already exists in schema "testschema_2"
+--
+-- SCHEMA
+--
+ALTER SCHEMA testschema_1 RENAME TO testschema_2; -- fail
+ERROR: schema "testschema_2" already exists
+ALTER SCHEMA testschema_1 RENAME TO testschema_3; -- OK
+DROP SCHEMA testschema_2, testschema_3 CASCADE;
+NOTICE: drop cascades to 31 other objects
+DETAIL: drop cascades to table testschema_3.testtable_b
+drop cascades to view testschema_3.testview_b
+drop cascades to sequence testschema_3.testseq_b
+drop cascades to type testschema_3.testcomptype_b
+drop cascades to table testschema_3.testtable_c
+drop cascades to function testschema_3.testfunc_b(integer)
+drop cascades to function testschema_3.testagg_b(integer)
+drop cascades to type testschema_3.testtype_b
+drop cascades to function testschema_3.testtype_a_in(cstring)
+drop cascades to function testschema_3.testtype_a_out(testschema_3.testtype_b)
+drop cascades to operator testschema_3.@#@(bigint,bigint)
+drop cascades to operator family testschema_3.testopfamily_b for access method btree
+drop cascades to text search dictionary testtsdict_b
+drop cascades to text search configuration testtsconf_b
+drop cascades to collation testcollation_b
+drop cascades to conversion testconv_b
+drop cascades to table testschema_2.testtable_b
+drop cascades to view testschema_2.testview_b
+drop cascades to sequence testschema_2.testseq_b
+drop cascades to type testschema_2.testcomptype_b
+drop cascades to function testschema_2.testfunc_b(integer)
+drop cascades to function testschema_2.testagg_b(integer)
+drop cascades to type testschema_2.testtype_b
+drop cascades to function testschema_3.testtype_b_in(cstring)
+drop cascades to function testschema_3.testtype_b_out(testschema_2.testtype_b)
+drop cascades to operator testschema_2.@#@(bigint,bigint)
+drop cascades to operator family testschema_2.testopfamily_b for access method btree
+drop cascades to text search dictionary testtsdict_b
+drop cascades to text search configuration testtsconf_b
+drop cascades to collation testcollation_b
+drop cascades to conversion testconv_b
diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out
index 5cda230..8aec0a4 100644
--- a/src/test/regress/expected/privileges.out
+++ b/src/test/regress/expected/privileges.out
@@ -504,7 +504,7 @@ SELECT testfunc1(5); -- ok
(1 row)
DROP FUNCTION testfunc1(int); -- fail
-ERROR: must be owner of function testfunc1
+ERROR: must be owner of function testfunc1(integer)
\c -
DROP FUNCTION testfunc1(int); -- ok
-- restore to sanity
diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule
index b47b08b..7f590fc 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_rename alter_table 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 57806b5..78f63e3 100644
--- a/src/test/regress/serial_schedule
+++ b/src/test/regress/serial_schedule
@@ -119,6 +119,7 @@ test: prepare
test: without_oid
test: conversion
test: truncate
+test: alter_rename
test: alter_table
test: sequence
test: polymorphism
diff --git a/src/test/regress/sql/alter_rename.sql b/src/test/regress/sql/alter_rename.sql
new file mode 100644
index 0000000..9b2bdf1
--- /dev/null
+++ b/src/test/regress/sql/alter_rename.sql
@@ -0,0 +1,240 @@
+--
+-- ALTER xxx RENAME TO/SET SCHEMA statement
+--
+
+CREATE SCHEMA testschema_1;
+CREATE SCHEMA testschema_2;
+
+SET search_path = testschema_1, public;
+
+--
+-- ROLE
+--
+CREATE ROLE testrole_1;
+CREATE ROLE testrole_2;
+
+ALTER ROLE testrole_1 RENAME TO testrole_2; -- fail
+ALTER ROLE testrole_1 RENAME TO testrole_3; -- OK
+
+DROP ROLE testrole_2, testrole_3;
+
+--
+-- LANGUAGE
+--
+CREATE LANGUAGE testlang_1 HANDLER plpgsql_call_handler;
+CREATE LANGUAGE testlang_2 HANDLER plpgsql_call_handler;
+
+ALTER LANGUAGE testlang_1 RENAME TO testlang_2; -- fail
+ALTER LANGUAGE testlang_1 RENAME TO testlang_3; -- OK
+
+DROP LANGUAGE testlang_2;
+DROP LANGUAGE testlang_3;
+
+--
+-- TABLE
+--
+CREATE TABLE testtable_a(a int, b int);
+CREATE TABLE testtable_b(x int, y int);
+ALTER TABLE testtable_a RENAME TO testtable_b; -- fail
+ALTER TABLE testtable_b SET SCHEMA testschema_2; -- OK
+ALTER TABLE testtable_a RENAME TO testtable_b; -- OK
+ALTER TABLE testtable_b SET SCHEMA testschema_2; -- fail
+
+--
+-- VIEW
+--
+CREATE VIEW testview_a AS SELECT * FROM pg_class WHERE relname like 'pg_%';
+CREATE VIEW testview_b AS SELECT * FROM pg_class WHERE relname like 'pg_%';
+ALTER VIEW testview_a RENAME TO testview_b; -- fail
+ALTER VIEW testview_b SET SCHEMA testschema_2; -- OK
+ALTER VIEW testview_a RENAME TO testview_b; -- OK
+ALTER VIEW testview_b SET SCHEMA testschema_2; -- fail
+ALTER VIEW testtable_b SET SCHEMA public; -- fail
+ALTER VIEW testtable_b RENAME TO testtable_c; -- fail
+
+--
+-- SEQUENCE
+--
+CREATE SEQUENCE testseq_a;
+CREATE SEQUENCE testseq_b;
+ALTER SEQUENCE testseq_a RENAME TO testseq_b; -- fail
+ALTER SEQUENCE testseq_b SET SCHEMA testschema_2; -- OK
+ALTER SEQUENCE testseq_a RENAME TO testseq_b; -- OK
+ALTER SEQUENCE testseq_b SET SCHEMA testschema_2; -- fail
+ALTER SEQUENCE testview_b SET SCHEMA public; -- fail
+ALTER SEQUENCE testview_b RENAME TO testview_c; -- fail
+
+--
+-- COMPOSITE TYPE
+--
+CREATE TYPE testcomptype_a AS (a int, b int);
+CREATE TYPE testcomptype_b AS (a int, b int);
+ALTER TYPE testcomptype_a RENAME TO testcomptype_b; -- fail
+ALTER TYPE testcomptype_b SET SCHEMA testschema_2; -- OK
+ALTER TYPE testcomptype_a RENAME TO testcomptype_b; -- OK
+ALTER TYPE testcomptype_b SET SCHEMA testschema_2; -- fail
+ALTER TYPE testseq_b SET SCHEMA public; -- fail
+ALTER TYPE testseq_b RENAME TO testseq_c; -- fail
+
+--
+-- INDEX
+--
+CREATE INDEX testindex_a ON testtable_b (a);
+CREATE INDEX testindex_b ON testtable_b (b);
+ALTER INDEX testindex_a RENAME TO testindex_b; -- fail
+ALTER INDEX testindex_a RENAME TO testindex_c; -- OK
+
+--
+-- COLUMN
+--
+ALTER TABLE testtable_b RENAME a TO b; -- fail
+ALTER TABLE testtable_b RENAME a TO x; -- OK
+CREATE TABLE testtable_c (z int) INHERITS (testtable_b);
+ALTER TABLE ONLY testtable_b RENAME b TO y; -- fail
+ALTER TABLE testtable_b RENAME b TO y; -- OK
+ALTER TABLE testtable_c RENAME z TO zz; -- OK
+ALTER TABLE testtable_c RENAME x TO xx; -- fail
+
+--
+-- TRIGGER
+--
+CREATE TRIGGER testtrigger_a
+ BEFORE UPDATE ON testtable_b
+ FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger();
+CREATE TRIGGER testtrigger_b
+ BEFORE UPDATE ON testtable_b
+ FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger();
+ALTER TRIGGER testtrigger_a ON testtable_b RENAME TO testtrigger_b; -- fail
+ALTER TRIGGER testtrigger_a ON testtable_b RENAME TO testtrigger_c; -- OK
+
+
+--
+-- FUNCTION, AGGREGATE
+--
+CREATE FUNCTION testfunc_a(int)
+ RETURNS int LANGUAGE sql
+ AS 'SELECT $1 + $1';
+CREATE FUNCTION testfunc_b(int)
+ RETURNS int LANGUAGE sql
+ AS 'SELECT $1 + $1';
+ALTER FUNCTION testfunc_a(int) RENAME TO testfunc_b; -- fail
+ALTER FUNCTION testfunc_b(int) SET SCHEMA testschema_2; -- OK
+ALTER FUNCTION testfunc_a(int) RENAME TO testfunc_b; -- OK
+ALTER FUNCTION testfunc_b(int) SET SCHEMA testschema_2; -- fail
+
+
+CREATE AGGREGATE testagg_a(
+ sfunc1 = int4pl, basetype = int4, stype1 = int4,
+ initcond1 = '0'
+);
+CREATE AGGREGATE testagg_b(
+ sfunc1 = int4pl, basetype = int4, stype1 = int4,
+ initcond1 = '0'
+);
+ALTER AGGREGATE testagg_a(int) RENAME TO testagg_b; -- fail
+ALTER AGGREGATE testagg_b(int) SET SCHEMA testschema_2; -- OK
+ALTER AGGREGATE testagg_a(int) RENAME TO testagg_b; -- OK
+ALTER AGGREGATE testagg_b(int) SET SCHEMA testschema_2; -- fail
+
+--
+-- TYPE
+--
+CREATE TYPE testtype_a;
+CREATE TYPE testtype_b;
+CREATE FUNCTION testtype_a_in (cstring) RETURNS testtype_a LANGUAGE 'internal' AS 'int4in';
+CREATE FUNCTION testtype_b_in (cstring) RETURNS testtype_b LANGUAGE 'internal' AS 'int4in';
+CREATE FUNCTION testtype_a_out (testtype_a) RETURNS cstring LANGUAGE 'internal' AS 'int4out';
+CREATE FUNCTION testtype_b_out (testtype_b) RETURNS cstring LANGUAGE 'internal' AS 'int4out';
+CREATE TYPE testtype_a (internallength = 4, input = testtype_a_in, output = testtype_a_out);
+CREATE TYPE testtype_b (internallength = 4, input = testtype_b_in, output = testtype_b_out);
+
+ALTER TYPE testtype_a RENAME TO testtype_b; -- fail
+ALTER TYPE testtype_b SET SCHEMA testschema_2; -- OK
+ALTER TYPE testtype_a RENAME TO testtype_b; -- OK
+ALTER TYPE testtype_b SET SCHEMA testschema_2; -- fail
+
+--
+-- OPERATOR, OPERATOR FAMILY and OPERATOR CLASS
+--
+
+CREATE OPERATOR @#@
+ (leftarg = int8, rightarg = int8, procedure = int8xor);
+ALTER OPERATOR @#@(int8,int8) SET SCHEMA testschema_2; -- OK
+CREATE OPERATOR @#@
+ (leftarg = int8, rightarg = int8, procedure = int8xor);
+-- XXX - comment out due to error message with oid determinded at runtime
+-- ALTER OPERATOR @#@(int8,int8) SET SCHEMA testschema_2; -- fail
+
+CREATE OPERATOR FAMILY testopfamily_a USING btree;
+CREATE OPERATOR FAMILY testopfamily_b USING btree;
+ALTER OPERATOR FAMILY testopfamily_a USING btree RENAME TO testopfamily_b; -- fail
+ALTER OPERATOR FAMILY testopfamily_b USING btree SET SCHEMA testschema_2; -- OK
+ALTER OPERATOR FAMILY testopfamily_a USING btree RENAME TO testopfamily_b; -- OK
+-- XXX - comment out due to error message with oid determinded at runtime
+-- ALTER OPERATOR FAMILY testopfamily_b USING btree SET SCHEMA testschema_2; -- fail
+
+
+CREATE OPERATOR CLASS testopclass_a
+ FOR TYPE box USING btree FAMILY testopfamily_b AS OPERATOR 1 =;
+CREATE OPERATOR CLASS testopclass_b
+ FOR TYPE circle USING btree FAMILY testopfamily_b AS OPERATOR 1 =;
+ALTER OPERATOR CLASS testopclass_a USING btree RENAME TO testopclass_b; -- fail
+ALTER OPERATOR CLASS testopclass_b USING btree SET SCHEMA testschema_2; -- OK
+ALTER OPERATOR CLASS testopclass_a USING btree RENAME TO testopclass_b; -- OK
+-- XXX - comment out due to error message with oid determinded at runtime
+-- ALTER OPERATOR CLASS testopclass_b USING btree SET SCHEMA testschema_2; -- fail
+
+--
+-- TEXT SEARCH
+--
+CREATE TEXT SEARCH DICTIONARY testtsdict_a (
+ Template=ispell,
+ DictFile=ispell_sample,
+ AffFile=ispell_sample
+);
+CREATE TEXT SEARCH DICTIONARY testtsdict_b (
+ Template=ispell,
+ DictFile=ispell_sample,
+ AffFile=ispell_sample
+);
+ALTER TEXT SEARCH DICTIONARY testtsdict_a RENAME TO testtsdict_b; -- fail
+ALTER TEXT SEARCH DICTIONARY testtsdict_b SET SCHEMA testschema_2; -- OK
+ALTER TEXT SEARCH DICTIONARY testtsdict_a RENAME TO testtsdict_b; -- OK
+ALTER TEXT SEARCH DICTIONARY testtsdict_b SET SCHEMA testschema_2; -- fail
+
+CREATE TEXT SEARCH CONFIGURATION testtsconf_a (COPY=english);
+CREATE TEXT SEARCH CONFIGURATION testtsconf_b (COPY=english);
+ALTER TEXT SEARCH CONFIGURATION testtsconf_a RENAME TO testtsconf_b; -- fail
+ALTER TEXT SEARCH CONFIGURATION testtsconf_b SET SCHEMA testschema_2; -- OK
+ALTER TEXT SEARCH CONFIGURATION testtsconf_a RENAME TO testtsconf_b; -- OK
+ALTER TEXT SEARCH CONFIGURATION testtsconf_b SET SCHEMA testschema_2; -- fail
+
+--
+-- COLLATION
+--
+CREATE COLLATION testcollation_a FROM "C";
+CREATE COLLATION testcollation_b FROM "C";
+
+ALTER COLLATION testcollation_a RENAME TO testcollation_b; -- fail
+ALTER COLLATION testcollation_b SET SCHEMA testschema_2; -- OK
+ALTER COLLATION testcollation_a RENAME TO testcollation_b; -- OK
+ALTER COLLATION testcollation_b SET SCHEMA testschema_2; -- fail
+
+--
+-- CONVERSION
+--
+CREATE CONVERSION testconv_a FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8;
+CREATE CONVERSION testconv_b FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8;
+
+ALTER CONVERSION testconv_a RENAME TO testconv_b; -- fail
+ALTER CONVERSION testconv_b SET SCHEMA testschema_2; -- OK
+ALTER CONVERSION testconv_a RENAME TO testconv_b; -- OK
+ALTER CONVERSION testconv_b SET SCHEMA testschema_2; -- fail
+
+--
+-- SCHEMA
+--
+ALTER SCHEMA testschema_1 RENAME TO testschema_2; -- fail
+ALTER SCHEMA testschema_1 RENAME TO testschema_3; -- OK
+
+DROP SCHEMA testschema_2, testschema_3 CASCADE;
pgsql-v9.2-ddl-refactoring-part-1.v1.drop-stmt.patchapplication/octet-stream; name=pgsql-v9.2-ddl-refactoring-part-1.v1.drop-stmt.patchDownload
src/backend/commands/aggregatecmds.c | 53 +---------
src/backend/commands/dropcmds.c | 106 +++++++++++++++++--
src/backend/commands/foreigncmds.c | 83 ---------------
src/backend/commands/functioncmds.c | 111 -------------------
src/backend/commands/opclasscmds.c | 98 -----------------
src/backend/commands/operatorcmds.c | 50 ---------
src/backend/commands/proclang.c | 43 --------
src/backend/commands/trigger.c | 36 -------
src/backend/nodes/copyfuncs.c | 128 +----------------------
src/backend/nodes/equalfuncs.c | 112 +-------------------
src/backend/parser/gram.y | 170 ++++++++++++++++-------------
src/backend/rewrite/rewriteRemove.c | 65 ------------
src/backend/tcop/utility.c | 193 ++++++----------------------------
src/include/commands/defrem.h | 8 --
src/include/commands/proclang.h | 1 -
src/include/commands/trigger.h | 2 -
src/include/nodes/nodes.h | 8 --
src/include/nodes/parsenodes.h | 103 +-----------------
src/include/rewrite/rewriteRemove.h | 3 -
19 files changed, 231 insertions(+), 1142 deletions(-)
diff --git a/src/backend/commands/aggregatecmds.c b/src/backend/commands/aggregatecmds.c
index a2122c1..085a205 100644
--- a/src/backend/commands/aggregatecmds.c
+++ b/src/backend/commands/aggregatecmds.c
@@ -208,59 +208,10 @@ DefineAggregate(List *name, List *args, bool oldstyle, List *parameters)
/*
- * RemoveAggregate
- * Deletes an aggregate.
+ * RenameAggregate
+ * Rename an aggregate.
*/
void
-RemoveAggregate(RemoveFuncStmt *stmt)
-{
- List *aggName = stmt->name;
- List *aggArgs = stmt->args;
- Oid procOid;
- HeapTuple tup;
- ObjectAddress object;
-
- /* Look up function and make sure it's an aggregate */
- procOid = LookupAggNameTypeNames(aggName, aggArgs, stmt->missing_ok);
-
- if (!OidIsValid(procOid))
- {
- /* we only get here if stmt->missing_ok is true */
- ereport(NOTICE,
- (errmsg("aggregate %s(%s) does not exist, skipping",
- NameListToString(aggName),
- TypeNameListToString(aggArgs))));
- return;
- }
-
- /*
- * Find the function tuple, do permissions and validity checks
- */
- tup = SearchSysCache1(PROCOID, ObjectIdGetDatum(procOid));
- if (!HeapTupleIsValid(tup)) /* should not happen */
- elog(ERROR, "cache lookup failed for function %u", procOid);
-
- /* Permission check: must own agg or its namespace */
- if (!pg_proc_ownercheck(procOid, GetUserId()) &&
- !pg_namespace_ownercheck(((Form_pg_proc) GETSTRUCT(tup))->pronamespace,
- GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC,
- NameListToString(aggName));
-
- ReleaseSysCache(tup);
-
- /*
- * Do the deletion
- */
- object.classId = ProcedureRelationId;
- object.objectId = procOid;
- object.objectSubId = 0;
-
- performDeletion(&object, stmt->behavior);
-}
-
-
-void
RenameAggregate(List *name, List *args, const char *newname)
{
Oid procOid;
diff --git a/src/backend/commands/dropcmds.c b/src/backend/commands/dropcmds.c
index 8297730..ef70168 100644
--- a/src/backend/commands/dropcmds.c
+++ b/src/backend/commands/dropcmds.c
@@ -25,8 +25,10 @@
#include "nodes/makefuncs.h"
#include "parser/parse_type.h"
#include "utils/acl.h"
+#include "utils/builtins.h"
-static void does_not_exist_skipping(ObjectType objtype, List *objname);
+static void does_not_exist_skipping(ObjectType objtype,
+ List *objname, List *objargs);
/*
* Drop one or more objects.
@@ -44,6 +46,7 @@ RemoveObjects(DropStmt *stmt)
{
ObjectAddresses *objects;
ListCell *cell1;
+ ListCell *cell2 = NULL;
objects = new_object_addresses();
@@ -51,12 +54,19 @@ RemoveObjects(DropStmt *stmt)
{
ObjectAddress address;
List *objname = lfirst(cell1);
+ List *objargs = NIL;
Relation relation = NULL;
Oid namespaceId;
+ if (stmt->arguments)
+ {
+ cell2 = (!cell2 ? list_head(stmt->arguments) : lnext(cell2));
+ objargs = lfirst(cell2);
+ }
+
/* Get an ObjectAddress for the object. */
address = get_object_address(stmt->removeType,
- objname, NIL,
+ objname, objargs,
&relation,
AccessExclusiveLock,
stmt->missing_ok);
@@ -64,16 +74,33 @@ RemoveObjects(DropStmt *stmt)
/* Issue NOTICE if supplied object was not found. */
if (!OidIsValid(address.objectId))
{
- does_not_exist_skipping(stmt->removeType, objname);
+ does_not_exist_skipping(stmt->removeType, objname, objargs);
continue;
}
/* Check permissions. */
- namespaceId = get_object_namespace(&address);
- if (!OidIsValid(namespaceId) ||
- !pg_namespace_ownercheck(namespaceId, GetUserId()))
- check_object_ownership(GetUserId(), stmt->removeType, address,
- objname, NIL, relation);
+ if (stmt->removeType == OBJECT_FDW)
+ {
+ /*
+ * Foreign Data Wrapper is an exception of access control on
+ * deletion; it requires superuser privilege to drop it,
+ * instead of ownership on the target object.
+ */
+ if (!superuser())
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("permission denied to drop foreign-data wrapper \"%s\"",
+ NameListToString(objname)),
+ errhint("Must be superuser to drop a foreign-data wrapper.")));
+ }
+ else
+ {
+ namespaceId = get_object_namespace(&address);
+ if (!OidIsValid(namespaceId) ||
+ !pg_namespace_ownercheck(namespaceId, GetUserId()))
+ check_object_ownership(GetUserId(), stmt->removeType, address,
+ objname, objargs, relation);
+ }
/* Release any relcache reference count, but keep lock until commit. */
if (relation)
@@ -94,10 +121,11 @@ RemoveObjects(DropStmt *stmt)
* get_object_address() will throw an ERROR.
*/
static void
-does_not_exist_skipping(ObjectType objtype, List *objname)
+does_not_exist_skipping(ObjectType objtype, List *objname, List *objargs)
{
const char *msg = NULL;
char *name = NULL;
+ char *args = NULL;
switch (objtype)
{
@@ -138,10 +166,68 @@ does_not_exist_skipping(ObjectType objtype, List *objname)
msg = gettext_noop("extension \"%s\" does not exist, skipping");
name = NameListToString(objname);
break;
+ case OBJECT_FUNCTION:
+ msg = gettext_noop("function %s(%s) does not exist, skipping");
+ name = NameListToString(objname);
+ args = TypeNameListToString(objargs);
+ break;
+ case OBJECT_AGGREGATE:
+ msg = gettext_noop("aggregate %s(%s) does not exist, skipping");
+ name = NameListToString(objname);
+ args = TypeNameListToString(objargs);
+ break;
+ case OBJECT_OPERATOR:
+ msg = gettext_noop("operator %s does not exist, skipping");
+ name = NameListToString(objname);
+ break;
+ case OBJECT_LANGUAGE:
+ msg = gettext_noop("language \"%s\" does not exist, skipping");
+ name = NameListToString(objname);
+ break;
+ case OBJECT_CAST:
+ msg = gettext_noop("cast from type %s to type %s does not exist, skipping");
+ name = format_type_be(typenameTypeId(NULL,
+ (TypeName *) linitial(objname)));
+ args = format_type_be(typenameTypeId(NULL,
+ (TypeName *) linitial(objargs)));
+ break;
+ case OBJECT_TRIGGER:
+ msg = gettext_noop("trigger \"%s\" for table \"%s\" does not exist, skipping");
+ name = strVal(llast(objname));
+ args = NameListToString(list_truncate(objname,
+ list_length(objname) - 1));
+ break;
+ case OBJECT_RULE:
+ msg = gettext_noop("rule \"%s\" for relation \"%s\" does not exist, skipping");
+ name = strVal(llast(objname));
+ args = NameListToString(list_truncate(objname,
+ list_length(objname) - 1));
+ break;
+ case OBJECT_FDW:
+ msg = gettext_noop("foreign-data wrapper \"%s\" does not exist, skipping");
+ name = NameListToString(objname);
+ break;
+ case OBJECT_FOREIGN_SERVER:
+ msg = gettext_noop("server \"%s\" does not exist, skipping");
+ name = NameListToString(objname);
+ break;
+ case OBJECT_OPCLASS:
+ msg = gettext_noop("operator class \"%s\" does not exist for access method \"%s\", skipping");
+ name = NameListToString(objname);
+ args = strVal(linitial(objargs));
+ break;
+ case OBJECT_OPFAMILY:
+ msg= gettext_noop("operator family \"%s\" does not exist for access method \"%s\", skipping");
+ name = NameListToString(objname);
+ args = strVal(linitial(objargs));
+ break;
default:
elog(ERROR, "unexpected object type (%d)", (int)objtype);
break;
}
- ereport(NOTICE, (errmsg(msg, name)));
+ if (!args)
+ ereport(NOTICE, (errmsg(msg, name)));
+ else
+ ereport(NOTICE, (errmsg(msg, name, args)));
}
diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c
index d9c27d1..b30ff40 100644
--- a/src/backend/commands/foreigncmds.c
+++ b/src/backend/commands/foreigncmds.c
@@ -686,50 +686,6 @@ AlterForeignDataWrapper(AlterFdwStmt *stmt)
/*
- * Drop foreign-data wrapper
- */
-void
-RemoveForeignDataWrapper(DropFdwStmt *stmt)
-{
- Oid fdwId;
- ObjectAddress object;
-
- fdwId = get_foreign_data_wrapper_oid(stmt->fdwname, true);
-
- if (!superuser())
- ereport(ERROR,
- (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- errmsg("permission denied to drop foreign-data wrapper \"%s\"",
- stmt->fdwname),
- errhint("Must be superuser to drop a foreign-data wrapper.")));
-
- if (!OidIsValid(fdwId))
- {
- if (!stmt->missing_ok)
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("foreign-data wrapper \"%s\" does not exist",
- stmt->fdwname)));
-
- /* IF EXISTS specified, just note it */
- ereport(NOTICE,
- (errmsg("foreign-data wrapper \"%s\" does not exist, skipping",
- stmt->fdwname)));
- return;
- }
-
- /*
- * Do the deletion
- */
- object.classId = ForeignDataWrapperRelationId;
- object.objectId = fdwId;
- object.objectSubId = 0;
-
- performDeletion(&object, stmt->behavior);
-}
-
-
-/*
* Drop foreign-data wrapper by OID
*/
void
@@ -958,45 +914,6 @@ AlterForeignServer(AlterForeignServerStmt *stmt)
/*
- * Drop foreign server
- */
-void
-RemoveForeignServer(DropForeignServerStmt *stmt)
-{
- Oid srvId;
- ObjectAddress object;
-
- srvId = get_foreign_server_oid(stmt->servername, true);
-
- if (!OidIsValid(srvId))
- {
- /* Server not found, complain or notice */
- if (!stmt->missing_ok)
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("server \"%s\" does not exist", stmt->servername)));
-
- /* IF EXISTS specified, just note it */
- ereport(NOTICE,
- (errmsg("server \"%s\" does not exist, skipping",
- stmt->servername)));
- return;
- }
-
- /* Only allow DROP if the server is owned by the user. */
- if (!pg_foreign_server_ownercheck(srvId, GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_FOREIGN_SERVER,
- stmt->servername);
-
- object.classId = ForeignServerRelationId;
- object.objectId = srvId;
- object.objectSubId = 0;
-
- performDeletion(&object, stmt->behavior);
-}
-
-
-/*
* Drop foreign server by OID
*/
void
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 92abd44..09a975b 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -965,72 +965,6 @@ CreateFunction(CreateFunctionStmt *stmt, const char *queryString)
/*
- * RemoveFunction
- * Deletes a function.
- */
-void
-RemoveFunction(RemoveFuncStmt *stmt)
-{
- List *functionName = stmt->name;
- List *argTypes = stmt->args; /* list of TypeName nodes */
- Oid funcOid;
- HeapTuple tup;
- ObjectAddress object;
-
- /*
- * Find the function, do permissions and validity checks
- */
- funcOid = LookupFuncNameTypeNames(functionName, argTypes, stmt->missing_ok);
- if (!OidIsValid(funcOid))
- {
- /* can only get here if stmt->missing_ok */
- ereport(NOTICE,
- (errmsg("function %s(%s) does not exist, skipping",
- NameListToString(functionName),
- TypeNameListToString(argTypes))));
- return;
- }
-
- tup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcOid));
- if (!HeapTupleIsValid(tup)) /* should not happen */
- elog(ERROR, "cache lookup failed for function %u", funcOid);
-
- /* Permission check: must own func or its namespace */
- if (!pg_proc_ownercheck(funcOid, GetUserId()) &&
- !pg_namespace_ownercheck(((Form_pg_proc) GETSTRUCT(tup))->pronamespace,
- GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC,
- NameListToString(functionName));
-
- if (((Form_pg_proc) GETSTRUCT(tup))->proisagg)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is an aggregate function",
- NameListToString(functionName)),
- errhint("Use DROP AGGREGATE to drop aggregate functions.")));
-
- if (((Form_pg_proc) GETSTRUCT(tup))->prolang == INTERNALlanguageId)
- {
- /* "Helpful" NOTICE when removing a builtin function ... */
- ereport(NOTICE,
- (errcode(ERRCODE_WARNING),
- errmsg("removing built-in function \"%s\"",
- NameListToString(functionName))));
- }
-
- ReleaseSysCache(tup);
-
- /*
- * Do the deletion
- */
- object.classId = ProcedureRelationId;
- object.objectId = funcOid;
- object.objectSubId = 0;
-
- performDeletion(&object, stmt->behavior);
-}
-
-/*
* Guts of function deletion.
*
* Note: this is also used for aggregate deletion, since the OIDs of
@@ -1776,51 +1710,6 @@ CreateCast(CreateCastStmt *stmt)
heap_close(relation, RowExclusiveLock);
}
-
-
-/*
- * DROP CAST
- */
-void
-DropCast(DropCastStmt *stmt)
-{
- Oid sourcetypeid;
- Oid targettypeid;
- ObjectAddress object;
-
- /* when dropping a cast, the types must exist even if you use IF EXISTS */
- sourcetypeid = typenameTypeId(NULL, stmt->sourcetype);
- targettypeid = typenameTypeId(NULL, stmt->targettype);
-
- object.classId = CastRelationId;
- object.objectId = get_cast_oid(sourcetypeid, targettypeid,
- stmt->missing_ok);
- object.objectSubId = 0;
-
- if (!OidIsValid(object.objectId))
- {
- ereport(NOTICE,
- (errmsg("cast from type %s to type %s does not exist, skipping",
- format_type_be(sourcetypeid),
- format_type_be(targettypeid))));
- return;
- }
-
- /* Permission check */
- if (!pg_type_ownercheck(sourcetypeid, GetUserId())
- && !pg_type_ownercheck(targettypeid, GetUserId()))
- ereport(ERROR,
- (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- errmsg("must be owner of type %s or type %s",
- format_type_be(sourcetypeid),
- format_type_be(targettypeid))));
-
- /*
- * Do the deletion
- */
- performDeletion(&object, stmt->behavior);
-}
-
/*
* get_cast_oid - given two type OIDs, look up a cast OID
*
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index af0de05..0ef3584 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -1543,104 +1543,6 @@ dropProcedures(List *opfamilyname, Oid amoid, Oid opfamilyoid,
}
}
-
-/*
- * RemoveOpClass
- * Deletes an opclass.
- */
-void
-RemoveOpClass(RemoveOpClassStmt *stmt)
-{
- Oid amID,
- opcID;
- HeapTuple tuple;
- ObjectAddress object;
-
- /* Get the access method's OID. */
- amID = get_am_oid(stmt->amname, false);
-
- /* Look up the opclass. */
- tuple = OpClassCacheLookup(amID, stmt->opclassname, stmt->missing_ok);
- if (!HeapTupleIsValid(tuple))
- {
- ereport(NOTICE,
- (errmsg("operator class \"%s\" does not exist for access method \"%s\", skipping",
- NameListToString(stmt->opclassname), stmt->amname)));
- return;
- }
-
- opcID = HeapTupleGetOid(tuple);
-
- /* Permission check: must own opclass or its namespace */
- if (!pg_opclass_ownercheck(opcID, GetUserId()) &&
- !pg_namespace_ownercheck(((Form_pg_opclass) GETSTRUCT(tuple))->opcnamespace,
- GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPCLASS,
- NameListToString(stmt->opclassname));
-
- ReleaseSysCache(tuple);
-
- /*
- * Do the deletion
- */
- object.classId = OperatorClassRelationId;
- object.objectId = opcID;
- object.objectSubId = 0;
-
- performDeletion(&object, stmt->behavior);
-}
-
-/*
- * RemoveOpFamily
- * Deletes an opfamily.
- */
-void
-RemoveOpFamily(RemoveOpFamilyStmt *stmt)
-{
- Oid amID,
- opfID;
- HeapTuple tuple;
- ObjectAddress object;
-
- /*
- * Get the access method's OID.
- */
- amID = get_am_oid(stmt->amname, false);
-
- /*
- * Look up the opfamily.
- */
- tuple = OpFamilyCacheLookup(amID, stmt->opfamilyname, stmt->missing_ok);
- if (!HeapTupleIsValid(tuple))
- {
- ereport(NOTICE,
- (errmsg("operator family \"%s\" does not exist for access method \"%s\", skipping",
- NameListToString(stmt->opfamilyname), stmt->amname)));
- return;
- }
-
- opfID = HeapTupleGetOid(tuple);
-
- /* Permission check: must own opfamily or its namespace */
- if (!pg_opfamily_ownercheck(opfID, GetUserId()) &&
- !pg_namespace_ownercheck(((Form_pg_opfamily) GETSTRUCT(tuple))->opfnamespace,
- GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPFAMILY,
- NameListToString(stmt->opfamilyname));
-
- ReleaseSysCache(tuple);
-
- /*
- * Do the deletion
- */
- object.classId = OperatorFamilyRelationId;
- object.objectId = opfID;
- object.objectSubId = 0;
-
- performDeletion(&object, stmt->behavior);
-}
-
-
/*
* Deletion subroutines for use by dependency.c.
*/
diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c
index c5c18ee..1e6c5ce 100644
--- a/src/backend/commands/operatorcmds.c
+++ b/src/backend/commands/operatorcmds.c
@@ -291,56 +291,6 @@ DefineOperator(List *names, List *parameters)
/*
- * RemoveOperator
- * Deletes an operator.
- */
-void
-RemoveOperator(RemoveFuncStmt *stmt)
-{
- List *operatorName = stmt->name;
- TypeName *typeName1 = (TypeName *) linitial(stmt->args);
- TypeName *typeName2 = (TypeName *) lsecond(stmt->args);
- Oid operOid;
- HeapTuple tup;
- ObjectAddress object;
-
- Assert(list_length(stmt->args) == 2);
- operOid = LookupOperNameTypeNames(NULL, operatorName,
- typeName1, typeName2,
- stmt->missing_ok, -1);
-
- if (stmt->missing_ok && !OidIsValid(operOid))
- {
- ereport(NOTICE,
- (errmsg("operator %s does not exist, skipping",
- NameListToString(operatorName))));
- return;
- }
-
- tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid));
- if (!HeapTupleIsValid(tup)) /* should not happen */
- elog(ERROR, "cache lookup failed for operator %u", operOid);
-
- /* Permission check: must own operator or its namespace */
- if (!pg_oper_ownercheck(operOid, GetUserId()) &&
- !pg_namespace_ownercheck(((Form_pg_operator) GETSTRUCT(tup))->oprnamespace,
- GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPER,
- NameListToString(operatorName));
-
- ReleaseSysCache(tup);
-
- /*
- * Do the deletion
- */
- object.classId = OperatorRelationId;
- object.objectId = operOid;
- object.objectSubId = 0;
-
- performDeletion(&object, stmt->behavior);
-}
-
-/*
* Guts of operator deletion.
*/
void
diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c
index 98770c5..b7ed1a4 100644
--- a/src/backend/commands/proclang.c
+++ b/src/backend/commands/proclang.c
@@ -513,49 +513,6 @@ PLTemplateExists(const char *languageName)
return (find_language_template(languageName) != NULL);
}
-
-/* ---------------------------------------------------------------------
- * DROP PROCEDURAL LANGUAGE
- * ---------------------------------------------------------------------
- */
-void
-DropProceduralLanguage(DropPLangStmt *stmt)
-{
- char *languageName;
- Oid oid;
- ObjectAddress object;
-
- /*
- * Translate the language name, check that the language exists
- */
- languageName = case_translate_language_name(stmt->plname);
-
- oid = get_language_oid(languageName, stmt->missing_ok);
- if (!OidIsValid(oid))
- {
- ereport(NOTICE,
- (errmsg("language \"%s\" does not exist, skipping",
- languageName)));
- return;
- }
-
- /*
- * Check permission
- */
- if (!pg_language_ownercheck(oid, GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_LANGUAGE,
- languageName);
-
- object.classId = LanguageRelationId;
- object.objectId = oid;
- object.objectSubId = 0;
-
- /*
- * Do the deletion
- */
- performDeletion(&object, stmt->behavior);
-}
-
/*
* Guts of language dropping.
*/
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index a6e7268..5589528 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -1026,42 +1026,6 @@ ConvertTriggerToFK(CreateTrigStmt *stmt, Oid funcoid)
}
}
-
-/*
- * DropTrigger - drop an individual trigger by name
- */
-void
-DropTrigger(RangeVar *relation, const char *trigname, DropBehavior behavior,
- bool missing_ok)
-{
- Oid relid;
- ObjectAddress object;
-
- /* lock level should match RemoveTriggerById */
- relid = RangeVarGetRelid(relation, AccessExclusiveLock, false, false);
-
- object.classId = TriggerRelationId;
- object.objectId = get_trigger_oid(relid, trigname, missing_ok);
- object.objectSubId = 0;
-
- if (!OidIsValid(object.objectId))
- {
- ereport(NOTICE,
- (errmsg("trigger \"%s\" for table \"%s\" does not exist, skipping",
- trigname, get_rel_name(relid))));
- return;
- }
-
- if (!pg_class_ownercheck(relid, GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
- get_rel_name(relid));
-
- /*
- * Do the deletion
- */
- performDeletion(&object, behavior);
-}
-
/*
* Guts of trigger deletion.
*/
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 63958c3..b8f047a 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -2755,6 +2755,7 @@ _copyDropStmt(DropStmt *from)
DropStmt *newnode = makeNode(DropStmt);
COPY_NODE_FIELD(objects);
+ COPY_NODE_FIELD(arguments);
COPY_SCALAR_FIELD(removeType);
COPY_SCALAR_FIELD(behavior);
COPY_SCALAR_FIELD(missing_ok);
@@ -2878,20 +2879,6 @@ _copyAlterFunctionStmt(AlterFunctionStmt *from)
return newnode;
}
-static RemoveFuncStmt *
-_copyRemoveFuncStmt(RemoveFuncStmt *from)
-{
- RemoveFuncStmt *newnode = makeNode(RemoveFuncStmt);
-
- COPY_SCALAR_FIELD(kind);
- COPY_NODE_FIELD(name);
- COPY_NODE_FIELD(args);
- COPY_SCALAR_FIELD(behavior);
- COPY_SCALAR_FIELD(missing_ok);
-
- return newnode;
-}
-
static DoStmt *
_copyDoStmt(DoStmt *from)
{
@@ -2902,32 +2889,6 @@ _copyDoStmt(DoStmt *from)
return newnode;
}
-static RemoveOpClassStmt *
-_copyRemoveOpClassStmt(RemoveOpClassStmt *from)
-{
- RemoveOpClassStmt *newnode = makeNode(RemoveOpClassStmt);
-
- COPY_NODE_FIELD(opclassname);
- COPY_STRING_FIELD(amname);
- COPY_SCALAR_FIELD(behavior);
- COPY_SCALAR_FIELD(missing_ok);
-
- return newnode;
-}
-
-static RemoveOpFamilyStmt *
-_copyRemoveOpFamilyStmt(RemoveOpFamilyStmt *from)
-{
- RemoveOpFamilyStmt *newnode = makeNode(RemoveOpFamilyStmt);
-
- COPY_NODE_FIELD(opfamilyname);
- COPY_STRING_FIELD(amname);
- COPY_SCALAR_FIELD(behavior);
- COPY_SCALAR_FIELD(missing_ok);
-
- return newnode;
-}
-
static RenameStmt *
_copyRenameStmt(RenameStmt *from)
{
@@ -3391,18 +3352,6 @@ _copyAlterFdwStmt(AlterFdwStmt *from)
return newnode;
}
-static DropFdwStmt *
-_copyDropFdwStmt(DropFdwStmt *from)
-{
- DropFdwStmt *newnode = makeNode(DropFdwStmt);
-
- COPY_STRING_FIELD(fdwname);
- COPY_SCALAR_FIELD(missing_ok);
- COPY_SCALAR_FIELD(behavior);
-
- return newnode;
-}
-
static CreateForeignServerStmt *
_copyCreateForeignServerStmt(CreateForeignServerStmt *from)
{
@@ -3430,18 +3379,6 @@ _copyAlterForeignServerStmt(AlterForeignServerStmt *from)
return newnode;
}
-static DropForeignServerStmt *
-_copyDropForeignServerStmt(DropForeignServerStmt *from)
-{
- DropForeignServerStmt *newnode = makeNode(DropForeignServerStmt);
-
- COPY_STRING_FIELD(servername);
- COPY_SCALAR_FIELD(missing_ok);
- COPY_SCALAR_FIELD(behavior);
-
- return newnode;
-}
-
static CreateUserMappingStmt *
_copyCreateUserMappingStmt(CreateUserMappingStmt *from)
{
@@ -3513,20 +3450,6 @@ _copyCreateTrigStmt(CreateTrigStmt *from)
return newnode;
}
-static DropPropertyStmt *
-_copyDropPropertyStmt(DropPropertyStmt *from)
-{
- DropPropertyStmt *newnode = makeNode(DropPropertyStmt);
-
- COPY_NODE_FIELD(relation);
- COPY_STRING_FIELD(property);
- COPY_SCALAR_FIELD(removeType);
- COPY_SCALAR_FIELD(behavior);
- COPY_SCALAR_FIELD(missing_ok);
-
- return newnode;
-}
-
static CreatePLangStmt *
_copyCreatePLangStmt(CreatePLangStmt *from)
{
@@ -3542,18 +3465,6 @@ _copyCreatePLangStmt(CreatePLangStmt *from)
return newnode;
}
-static DropPLangStmt *
-_copyDropPLangStmt(DropPLangStmt *from)
-{
- DropPLangStmt *newnode = makeNode(DropPLangStmt);
-
- COPY_STRING_FIELD(plname);
- COPY_SCALAR_FIELD(behavior);
- COPY_SCALAR_FIELD(missing_ok);
-
- return newnode;
-}
-
static CreateRoleStmt *
_copyCreateRoleStmt(CreateRoleStmt *from)
{
@@ -3678,19 +3589,6 @@ _copyCreateCastStmt(CreateCastStmt *from)
return newnode;
}
-static DropCastStmt *
-_copyDropCastStmt(DropCastStmt *from)
-{
- DropCastStmt *newnode = makeNode(DropCastStmt);
-
- COPY_NODE_FIELD(sourcetype);
- COPY_NODE_FIELD(targettype);
- COPY_SCALAR_FIELD(behavior);
- COPY_SCALAR_FIELD(missing_ok);
-
- return newnode;
-}
-
static PrepareStmt *
_copyPrepareStmt(PrepareStmt *from)
{
@@ -4266,18 +4164,9 @@ copyObject(void *from)
case T_AlterFunctionStmt:
retval = _copyAlterFunctionStmt(from);
break;
- case T_RemoveFuncStmt:
- retval = _copyRemoveFuncStmt(from);
- break;
case T_DoStmt:
retval = _copyDoStmt(from);
break;
- case T_RemoveOpClassStmt:
- retval = _copyRemoveOpClassStmt(from);
- break;
- case T_RemoveOpFamilyStmt:
- retval = _copyRemoveOpFamilyStmt(from);
- break;
case T_RenameStmt:
retval = _copyRenameStmt(from);
break;
@@ -4392,18 +4281,12 @@ copyObject(void *from)
case T_AlterFdwStmt:
retval = _copyAlterFdwStmt(from);
break;
- case T_DropFdwStmt:
- retval = _copyDropFdwStmt(from);
- break;
case T_CreateForeignServerStmt:
retval = _copyCreateForeignServerStmt(from);
break;
case T_AlterForeignServerStmt:
retval = _copyAlterForeignServerStmt(from);
break;
- case T_DropForeignServerStmt:
- retval = _copyDropForeignServerStmt(from);
- break;
case T_CreateUserMappingStmt:
retval = _copyCreateUserMappingStmt(from);
break;
@@ -4419,15 +4302,9 @@ copyObject(void *from)
case T_CreateTrigStmt:
retval = _copyCreateTrigStmt(from);
break;
- case T_DropPropertyStmt:
- retval = _copyDropPropertyStmt(from);
- break;
case T_CreatePLangStmt:
retval = _copyCreatePLangStmt(from);
break;
- case T_DropPLangStmt:
- retval = _copyDropPLangStmt(from);
- break;
case T_CreateRoleStmt:
retval = _copyCreateRoleStmt(from);
break;
@@ -4461,9 +4338,6 @@ copyObject(void *from)
case T_CreateCastStmt:
retval = _copyCreateCastStmt(from);
break;
- case T_DropCastStmt:
- retval = _copyDropCastStmt(from);
- break;
case T_PrepareStmt:
retval = _copyPrepareStmt(from);
break;
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index f3a34a1..d1af48a 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -1182,6 +1182,7 @@ static bool
_equalDropStmt(DropStmt *a, DropStmt *b)
{
COMPARE_NODE_FIELD(objects);
+ COMPARE_NODE_FIELD(arguments);
COMPARE_SCALAR_FIELD(removeType);
COMPARE_SCALAR_FIELD(behavior);
COMPARE_SCALAR_FIELD(missing_ok);
@@ -1290,18 +1291,6 @@ _equalAlterFunctionStmt(AlterFunctionStmt *a, AlterFunctionStmt *b)
}
static bool
-_equalRemoveFuncStmt(RemoveFuncStmt *a, RemoveFuncStmt *b)
-{
- COMPARE_SCALAR_FIELD(kind);
- COMPARE_NODE_FIELD(name);
- COMPARE_NODE_FIELD(args);
- COMPARE_SCALAR_FIELD(behavior);
- COMPARE_SCALAR_FIELD(missing_ok);
-
- return true;
-}
-
-static bool
_equalDoStmt(DoStmt *a, DoStmt *b)
{
COMPARE_NODE_FIELD(args);
@@ -1310,28 +1299,6 @@ _equalDoStmt(DoStmt *a, DoStmt *b)
}
static bool
-_equalRemoveOpClassStmt(RemoveOpClassStmt *a, RemoveOpClassStmt *b)
-{
- COMPARE_NODE_FIELD(opclassname);
- COMPARE_STRING_FIELD(amname);
- COMPARE_SCALAR_FIELD(behavior);
- COMPARE_SCALAR_FIELD(missing_ok);
-
- return true;
-}
-
-static bool
-_equalRemoveOpFamilyStmt(RemoveOpFamilyStmt *a, RemoveOpFamilyStmt *b)
-{
- COMPARE_NODE_FIELD(opfamilyname);
- COMPARE_STRING_FIELD(amname);
- COMPARE_SCALAR_FIELD(behavior);
- COMPARE_SCALAR_FIELD(missing_ok);
-
- return true;
-}
-
-static bool
_equalRenameStmt(RenameStmt *a, RenameStmt *b)
{
COMPARE_SCALAR_FIELD(renameType);
@@ -1720,16 +1687,6 @@ _equalAlterFdwStmt(AlterFdwStmt *a, AlterFdwStmt *b)
}
static bool
-_equalDropFdwStmt(DropFdwStmt *a, DropFdwStmt *b)
-{
- COMPARE_STRING_FIELD(fdwname);
- COMPARE_SCALAR_FIELD(missing_ok);
- COMPARE_SCALAR_FIELD(behavior);
-
- return true;
-}
-
-static bool
_equalCreateForeignServerStmt(CreateForeignServerStmt *a, CreateForeignServerStmt *b)
{
COMPARE_STRING_FIELD(servername);
@@ -1753,16 +1710,6 @@ _equalAlterForeignServerStmt(AlterForeignServerStmt *a, AlterForeignServerStmt *
}
static bool
-_equalDropForeignServerStmt(DropForeignServerStmt *a, DropForeignServerStmt *b)
-{
- COMPARE_STRING_FIELD(servername);
- COMPARE_SCALAR_FIELD(missing_ok);
- COMPARE_SCALAR_FIELD(behavior);
-
- return true;
-}
-
-static bool
_equalCreateUserMappingStmt(CreateUserMappingStmt *a, CreateUserMappingStmt *b)
{
COMPARE_STRING_FIELD(username);
@@ -1825,18 +1772,6 @@ _equalCreateTrigStmt(CreateTrigStmt *a, CreateTrigStmt *b)
}
static bool
-_equalDropPropertyStmt(DropPropertyStmt *a, DropPropertyStmt *b)
-{
- COMPARE_NODE_FIELD(relation);
- COMPARE_STRING_FIELD(property);
- COMPARE_SCALAR_FIELD(removeType);
- COMPARE_SCALAR_FIELD(behavior);
- COMPARE_SCALAR_FIELD(missing_ok);
-
- return true;
-}
-
-static bool
_equalCreatePLangStmt(CreatePLangStmt *a, CreatePLangStmt *b)
{
COMPARE_SCALAR_FIELD(replace);
@@ -1850,16 +1785,6 @@ _equalCreatePLangStmt(CreatePLangStmt *a, CreatePLangStmt *b)
}
static bool
-_equalDropPLangStmt(DropPLangStmt *a, DropPLangStmt *b)
-{
- COMPARE_STRING_FIELD(plname);
- COMPARE_SCALAR_FIELD(behavior);
- COMPARE_SCALAR_FIELD(missing_ok);
-
- return true;
-}
-
-static bool
_equalCreateRoleStmt(CreateRoleStmt *a, CreateRoleStmt *b)
{
COMPARE_SCALAR_FIELD(stmt_type);
@@ -1964,17 +1889,6 @@ _equalCreateCastStmt(CreateCastStmt *a, CreateCastStmt *b)
}
static bool
-_equalDropCastStmt(DropCastStmt *a, DropCastStmt *b)
-{
- COMPARE_NODE_FIELD(sourcetype);
- COMPARE_NODE_FIELD(targettype);
- COMPARE_SCALAR_FIELD(behavior);
- COMPARE_SCALAR_FIELD(missing_ok);
-
- return true;
-}
-
-static bool
_equalPrepareStmt(PrepareStmt *a, PrepareStmt *b)
{
COMPARE_STRING_FIELD(name);
@@ -2793,18 +2707,9 @@ equal(void *a, void *b)
case T_AlterFunctionStmt:
retval = _equalAlterFunctionStmt(a, b);
break;
- case T_RemoveFuncStmt:
- retval = _equalRemoveFuncStmt(a, b);
- break;
case T_DoStmt:
retval = _equalDoStmt(a, b);
break;
- case T_RemoveOpClassStmt:
- retval = _equalRemoveOpClassStmt(a, b);
- break;
- case T_RemoveOpFamilyStmt:
- retval = _equalRemoveOpFamilyStmt(a, b);
- break;
case T_RenameStmt:
retval = _equalRenameStmt(a, b);
break;
@@ -2919,18 +2824,12 @@ equal(void *a, void *b)
case T_AlterFdwStmt:
retval = _equalAlterFdwStmt(a, b);
break;
- case T_DropFdwStmt:
- retval = _equalDropFdwStmt(a, b);
- break;
case T_CreateForeignServerStmt:
retval = _equalCreateForeignServerStmt(a, b);
break;
case T_AlterForeignServerStmt:
retval = _equalAlterForeignServerStmt(a, b);
break;
- case T_DropForeignServerStmt:
- retval = _equalDropForeignServerStmt(a, b);
- break;
case T_CreateUserMappingStmt:
retval = _equalCreateUserMappingStmt(a, b);
break;
@@ -2946,15 +2845,9 @@ equal(void *a, void *b)
case T_CreateTrigStmt:
retval = _equalCreateTrigStmt(a, b);
break;
- case T_DropPropertyStmt:
- retval = _equalDropPropertyStmt(a, b);
- break;
case T_CreatePLangStmt:
retval = _equalCreatePLangStmt(a, b);
break;
- case T_DropPLangStmt:
- retval = _equalDropPLangStmt(a, b);
- break;
case T_CreateRoleStmt:
retval = _equalCreateRoleStmt(a, b);
break;
@@ -2988,9 +2881,6 @@ equal(void *a, void *b)
case T_CreateCastStmt:
retval = _equalCreateCastStmt(a, b);
break;
- case T_DropCastStmt:
- retval = _equalDropCastStmt(a, b);
- break;
case T_PrepareStmt:
retval = _equalPrepareStmt(a, b);
break;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index c135465..7ea38e4 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -3255,16 +3255,19 @@ opt_validator:
DropPLangStmt:
DROP opt_procedural LANGUAGE ColId_or_Sconst opt_drop_behavior
{
- DropPLangStmt *n = makeNode(DropPLangStmt);
- n->plname = $4;
+ DropStmt *n = makeNode(DropStmt);
+ n->removeType = OBJECT_LANGUAGE;
+ n->objects = list_make1(list_make1(makeString($4)));
+ n->arguments = NIL;
n->behavior = $5;
n->missing_ok = false;
$$ = (Node *)n;
}
| DROP opt_procedural LANGUAGE IF_P EXISTS ColId_or_Sconst opt_drop_behavior
{
- DropPLangStmt *n = makeNode(DropPLangStmt);
- n->plname = $6;
+ DropStmt *n = makeNode(DropStmt);
+ n->removeType = OBJECT_LANGUAGE;
+ n->objects = list_make1(list_make1(makeString($6)));
n->behavior = $7;
n->missing_ok = true;
$$ = (Node *)n;
@@ -3656,16 +3659,20 @@ opt_fdw_options:
DropFdwStmt: DROP FOREIGN DATA_P WRAPPER name opt_drop_behavior
{
- DropFdwStmt *n = makeNode(DropFdwStmt);
- n->fdwname = $5;
+ DropStmt *n = makeNode(DropStmt);
+ n->removeType = OBJECT_FDW;
+ n->objects = list_make1(list_make1(makeString($5)));
+ n->arguments = NIL;
n->missing_ok = false;
n->behavior = $6;
$$ = (Node *) n;
}
| DROP FOREIGN DATA_P WRAPPER IF_P EXISTS name opt_drop_behavior
- {
- DropFdwStmt *n = makeNode(DropFdwStmt);
- n->fdwname = $7;
+ {
+ DropStmt *n = makeNode(DropStmt);
+ n->removeType = OBJECT_FDW;
+ n->objects = list_make1(list_make1(makeString($7)));
+ n->arguments = NIL;
n->missing_ok = true;
n->behavior = $8;
$$ = (Node *) n;
@@ -3812,16 +3819,20 @@ opt_foreign_server_version:
DropForeignServerStmt: DROP SERVER name opt_drop_behavior
{
- DropForeignServerStmt *n = makeNode(DropForeignServerStmt);
- n->servername = $3;
+ DropStmt *n = makeNode(DropStmt);
+ n->removeType = OBJECT_FOREIGN_SERVER;
+ n->objects = list_make1(list_make1(makeString($3)));
+ n->arguments = NIL;
n->missing_ok = false;
n->behavior = $4;
$$ = (Node *) n;
}
| DROP SERVER IF_P EXISTS name opt_drop_behavior
- {
- DropForeignServerStmt *n = makeNode(DropForeignServerStmt);
- n->servername = $5;
+ {
+ DropStmt *n = makeNode(DropStmt);
+ n->removeType = OBJECT_FOREIGN_SERVER;
+ n->objects = list_make1(list_make1(makeString($5)));
+ n->arguments = NIL;
n->missing_ok = true;
n->behavior = $6;
$$ = (Node *) n;
@@ -4193,23 +4204,23 @@ ConstraintAttributeElem:
DropTrigStmt:
- DROP TRIGGER name ON qualified_name opt_drop_behavior
+ DROP TRIGGER name ON any_name opt_drop_behavior
{
- DropPropertyStmt *n = makeNode(DropPropertyStmt);
- n->relation = $5;
- n->property = $3;
- n->behavior = $6;
+ DropStmt *n = makeNode(DropStmt);
n->removeType = OBJECT_TRIGGER;
+ n->objects = list_make1(lappend($5, makeString($3)));
+ n->arguments = NIL;
+ n->behavior = $6;
n->missing_ok = false;
$$ = (Node *) n;
}
- | DROP TRIGGER IF_P EXISTS name ON qualified_name opt_drop_behavior
+ | DROP TRIGGER IF_P EXISTS name ON any_name opt_drop_behavior
{
- DropPropertyStmt *n = makeNode(DropPropertyStmt);
- n->relation = $7;
- n->property = $5;
- n->behavior = $8;
+ DropStmt *n = makeNode(DropStmt);
n->removeType = OBJECT_TRIGGER;
+ n->objects = list_make1(lappend($7, makeString($5)));
+ n->arguments = NIL;
+ n->behavior = $8;
n->missing_ok = true;
$$ = (Node *) n;
}
@@ -4247,9 +4258,9 @@ CreateAssertStmt:
DropAssertStmt:
DROP ASSERTION name opt_drop_behavior
{
- DropPropertyStmt *n = makeNode(DropPropertyStmt);
- n->relation = NULL;
- n->property = $3;
+ DropStmt *n = makeNode(DropStmt);
+ n->objects = NIL;
+ n->arguments = NIL;
n->behavior = $4;
n->removeType = OBJECT_TRIGGER; /* XXX */
ereport(ERROR,
@@ -4665,18 +4676,20 @@ opclass_drop:
DropOpClassStmt:
DROP OPERATOR CLASS any_name USING access_method opt_drop_behavior
{
- RemoveOpClassStmt *n = makeNode(RemoveOpClassStmt);
- n->opclassname = $4;
- n->amname = $6;
+ DropStmt *n = makeNode(DropStmt);
+ n->objects = list_make1($4);
+ n->arguments = list_make1(list_make1(makeString($6)));
+ n->removeType = OBJECT_OPCLASS;
n->behavior = $7;
n->missing_ok = false;
$$ = (Node *) n;
}
| DROP OPERATOR CLASS IF_P EXISTS any_name USING access_method opt_drop_behavior
{
- RemoveOpClassStmt *n = makeNode(RemoveOpClassStmt);
- n->opclassname = $6;
- n->amname = $8;
+ DropStmt *n = makeNode(DropStmt);
+ n->objects = list_make1($6);
+ n->arguments = list_make1(list_make1(makeString($8)));
+ n->removeType = OBJECT_OPCLASS;
n->behavior = $9;
n->missing_ok = true;
$$ = (Node *) n;
@@ -4686,18 +4699,20 @@ DropOpClassStmt:
DropOpFamilyStmt:
DROP OPERATOR FAMILY any_name USING access_method opt_drop_behavior
{
- RemoveOpFamilyStmt *n = makeNode(RemoveOpFamilyStmt);
- n->opfamilyname = $4;
- n->amname = $6;
+ DropStmt *n = makeNode(DropStmt);
+ n->objects = list_make1($4);
+ n->arguments = list_make1(list_make1(makeString($6)));
+ n->removeType = OBJECT_OPFAMILY;
n->behavior = $7;
n->missing_ok = false;
$$ = (Node *) n;
}
| DROP OPERATOR FAMILY IF_P EXISTS any_name USING access_method opt_drop_behavior
{
- RemoveOpFamilyStmt *n = makeNode(RemoveOpFamilyStmt);
- n->opfamilyname = $6;
- n->amname = $8;
+ DropStmt *n = makeNode(DropStmt);
+ n->objects = list_make1($6);
+ n->arguments = list_make1(list_make1(makeString($8)));
+ n->removeType = OBJECT_OPFAMILY;
n->behavior = $9;
n->missing_ok = true;
$$ = (Node *) n;
@@ -4748,6 +4763,7 @@ DropStmt: DROP drop_type IF_P EXISTS any_name_list opt_drop_behavior
n->removeType = $2;
n->missing_ok = TRUE;
n->objects = $5;
+ n->arguments = NIL;
n->behavior = $6;
$$ = (Node *)n;
}
@@ -4757,6 +4773,7 @@ DropStmt: DROP drop_type IF_P EXISTS any_name_list opt_drop_behavior
n->removeType = $2;
n->missing_ok = FALSE;
n->objects = $3;
+ n->arguments = NIL;
n->behavior = $4;
$$ = (Node *)n;
}
@@ -6173,20 +6190,20 @@ opt_restrict:
RemoveFuncStmt:
DROP FUNCTION func_name func_args opt_drop_behavior
{
- RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
- n->kind = OBJECT_FUNCTION;
- n->name = $3;
- n->args = extractArgTypes($4);
+ DropStmt *n = makeNode(DropStmt);
+ n->removeType = OBJECT_FUNCTION;
+ n->objects = list_make1($3);
+ n->arguments = list_make1(extractArgTypes($4));
n->behavior = $5;
n->missing_ok = false;
$$ = (Node *)n;
}
| DROP FUNCTION IF_P EXISTS func_name func_args opt_drop_behavior
{
- RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
- n->kind = OBJECT_FUNCTION;
- n->name = $5;
- n->args = extractArgTypes($6);
+ DropStmt *n = makeNode(DropStmt);
+ n->removeType = OBJECT_FUNCTION;
+ n->objects = list_make1($5);
+ n->arguments = list_make1(extractArgTypes($6));
n->behavior = $7;
n->missing_ok = true;
$$ = (Node *)n;
@@ -6196,20 +6213,20 @@ RemoveFuncStmt:
RemoveAggrStmt:
DROP AGGREGATE func_name aggr_args opt_drop_behavior
{
- RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
- n->kind = OBJECT_AGGREGATE;
- n->name = $3;
- n->args = $4;
+ DropStmt *n = makeNode(DropStmt);
+ n->removeType = OBJECT_AGGREGATE;
+ n->objects = list_make1($3);
+ n->arguments = list_make1($4);
n->behavior = $5;
n->missing_ok = false;
$$ = (Node *)n;
}
| DROP AGGREGATE IF_P EXISTS func_name aggr_args opt_drop_behavior
{
- RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
- n->kind = OBJECT_AGGREGATE;
- n->name = $5;
- n->args = $6;
+ DropStmt *n = makeNode(DropStmt);
+ n->removeType = OBJECT_AGGREGATE;
+ n->objects = list_make1($5);
+ n->arguments = list_make1($6);
n->behavior = $7;
n->missing_ok = true;
$$ = (Node *)n;
@@ -6219,20 +6236,20 @@ RemoveAggrStmt:
RemoveOperStmt:
DROP OPERATOR any_operator oper_argtypes opt_drop_behavior
{
- RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
- n->kind = OBJECT_OPERATOR;
- n->name = $3;
- n->args = $4;
+ DropStmt *n = makeNode(DropStmt);
+ n->removeType = OBJECT_OPERATOR;
+ n->objects = list_make1($3);
+ n->arguments = list_make1($4);
n->behavior = $5;
n->missing_ok = false;
$$ = (Node *)n;
}
| DROP OPERATOR IF_P EXISTS any_operator oper_argtypes opt_drop_behavior
{
- RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
- n->kind = OBJECT_OPERATOR;
- n->name = $5;
- n->args = $6;
+ DropStmt *n = makeNode(DropStmt);
+ n->removeType = OBJECT_OPERATOR;
+ n->objects = list_make1($5);
+ n->arguments = list_make1($6);
n->behavior = $7;
n->missing_ok = true;
$$ = (Node *)n;
@@ -6345,9 +6362,10 @@ cast_context: AS IMPLICIT_P { $$ = COERCION_IMPLICIT; }
DropCastStmt: DROP CAST opt_if_exists '(' Typename AS Typename ')' opt_drop_behavior
{
- DropCastStmt *n = makeNode(DropCastStmt);
- n->sourcetype = $5;
- n->targettype = $7;
+ DropStmt *n = makeNode(DropStmt);
+ n->removeType = OBJECT_CAST;
+ n->objects = list_make1(list_make1($5));
+ n->arguments = list_make1(list_make1($7));
n->behavior = $9;
n->missing_ok = $3;
$$ = (Node *)n;
@@ -7063,23 +7081,23 @@ opt_instead:
DropRuleStmt:
- DROP RULE name ON qualified_name opt_drop_behavior
+ DROP RULE name ON any_name opt_drop_behavior
{
- DropPropertyStmt *n = makeNode(DropPropertyStmt);
- n->relation = $5;
- n->property = $3;
- n->behavior = $6;
+ DropStmt *n = makeNode(DropStmt);
n->removeType = OBJECT_RULE;
+ n->objects = list_make1(lappend($5, makeString($3)));
+ n->arguments = NIL;
+ n->behavior = $6;
n->missing_ok = false;
$$ = (Node *) n;
}
- | DROP RULE IF_P EXISTS name ON qualified_name opt_drop_behavior
+ | DROP RULE IF_P EXISTS name ON any_name opt_drop_behavior
{
- DropPropertyStmt *n = makeNode(DropPropertyStmt);
- n->relation = $7;
- n->property = $5;
- n->behavior = $8;
+ DropStmt *n = makeNode(DropStmt);
n->removeType = OBJECT_RULE;
+ n->objects = list_make1(lappend($7, makeString($5)));
+ n->arguments = NIL;
+ n->behavior = $8;
n->missing_ok = true;
$$ = (Node *) n;
}
diff --git a/src/backend/rewrite/rewriteRemove.c b/src/backend/rewrite/rewriteRemove.c
index b9b693c..3cc159a 100644
--- a/src/backend/rewrite/rewriteRemove.c
+++ b/src/backend/rewrite/rewriteRemove.c
@@ -30,71 +30,6 @@
#include "utils/syscache.h"
#include "utils/tqual.h"
-
-/*
- * RemoveRewriteRule
- *
- * Delete a rule given its name.
- */
-void
-RemoveRewriteRule(RangeVar *relation, const char *ruleName,
- DropBehavior behavior, bool missing_ok)
-{
- HeapTuple tuple;
- Oid eventRelationOid;
- Oid owningRel;
- ObjectAddress object;
-
- /* lock level should match RemoveRewriteRuleById */
- owningRel = RangeVarGetRelid(relation, AccessExclusiveLock,
- false, false);
-
- /*
- * Find the tuple for the target rule.
- */
- tuple = SearchSysCache2(RULERELNAME,
- ObjectIdGetDatum(owningRel),
- PointerGetDatum(ruleName));
-
- /*
- * complain if no rule with such name exists
- */
- if (!HeapTupleIsValid(tuple))
- {
- if (!missing_ok)
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("rule \"%s\" for relation \"%s\" does not exist",
- ruleName, get_rel_name(owningRel))));
- else
- ereport(NOTICE,
- (errmsg("rule \"%s\" for relation \"%s\" does not exist, skipping",
- ruleName, get_rel_name(owningRel))));
- return;
- }
-
- /*
- * Verify user has appropriate permissions.
- */
- eventRelationOid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class;
- Assert(eventRelationOid == owningRel);
- if (!pg_class_ownercheck(eventRelationOid, GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
- get_rel_name(eventRelationOid));
-
- /*
- * Do the deletion
- */
- object.classId = RewriteRelationId;
- object.objectId = HeapTupleGetOid(tuple);
- object.objectSubId = 0;
-
- ReleaseSysCache(tuple);
-
- performDeletion(&object, behavior);
-}
-
-
/*
* Guts of rule deletion.
*/
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 5b06333..cc8f32d 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -205,16 +205,10 @@ check_xact_readonly(Node *parsetree)
case T_CreateRangeStmt:
case T_AlterEnumStmt:
case T_ViewStmt:
- case T_DropCastStmt:
case T_DropStmt:
case T_DropdbStmt:
case T_DropTableSpaceStmt:
- case T_RemoveFuncStmt:
case T_DropRoleStmt:
- case T_DropPLangStmt:
- case T_RemoveOpClassStmt:
- case T_RemoveOpFamilyStmt:
- case T_DropPropertyStmt:
case T_GrantStmt:
case T_GrantRoleStmt:
case T_AlterDefaultPrivilegesStmt:
@@ -228,10 +222,8 @@ check_xact_readonly(Node *parsetree)
case T_AlterExtensionContentsStmt:
case T_CreateFdwStmt:
case T_AlterFdwStmt:
- case T_DropFdwStmt:
case T_CreateForeignServerStmt:
case T_AlterForeignServerStmt:
- case T_DropForeignServerStmt:
case T_CreateUserMappingStmt:
case T_AlterUserMappingStmt:
case T_DropUserMappingStmt:
@@ -616,10 +608,6 @@ standard_ProcessUtility(Node *parsetree,
AlterForeignDataWrapper((AlterFdwStmt *) parsetree);
break;
- case T_DropFdwStmt:
- RemoveForeignDataWrapper((DropFdwStmt *) parsetree);
- break;
-
case T_CreateForeignServerStmt:
CreateForeignServer((CreateForeignServerStmt *) parsetree);
break;
@@ -628,10 +616,6 @@ standard_ProcessUtility(Node *parsetree,
AlterForeignServer((AlterForeignServerStmt *) parsetree);
break;
- case T_DropForeignServerStmt:
- RemoveForeignServer((DropForeignServerStmt *) parsetree);
- break;
-
case T_CreateUserMappingStmt:
CreateUserMapping((CreateUserMappingStmt *) parsetree);
break;
@@ -947,29 +931,6 @@ standard_ProcessUtility(Node *parsetree,
AlterSequence((AlterSeqStmt *) parsetree);
break;
- case T_RemoveFuncStmt:
- {
- RemoveFuncStmt *stmt = (RemoveFuncStmt *) parsetree;
-
- switch (stmt->kind)
- {
- case OBJECT_FUNCTION:
- RemoveFunction(stmt);
- break;
- case OBJECT_AGGREGATE:
- RemoveAggregate(stmt);
- break;
- case OBJECT_OPERATOR:
- RemoveOperator(stmt);
- break;
- default:
- elog(ERROR, "unrecognized object type: %d",
- (int) stmt->kind);
- break;
- }
- }
- break;
-
case T_DoStmt:
ExecuteDoStmt((DoStmt *) parsetree);
break;
@@ -1079,38 +1040,10 @@ standard_ProcessUtility(Node *parsetree,
InvalidOid, InvalidOid, false);
break;
- case T_DropPropertyStmt:
- {
- DropPropertyStmt *stmt = (DropPropertyStmt *) parsetree;
-
- switch (stmt->removeType)
- {
- case OBJECT_RULE:
- /* RemoveRewriteRule checks permissions */
- RemoveRewriteRule(stmt->relation, stmt->property,
- stmt->behavior, stmt->missing_ok);
- break;
- case OBJECT_TRIGGER:
- /* DropTrigger checks permissions */
- DropTrigger(stmt->relation, stmt->property,
- stmt->behavior, stmt->missing_ok);
- break;
- default:
- elog(ERROR, "unrecognized object type: %d",
- (int) stmt->removeType);
- break;
- }
- }
- break;
-
case T_CreatePLangStmt:
CreateProceduralLanguage((CreatePLangStmt *) parsetree);
break;
- case T_DropPLangStmt:
- DropProceduralLanguage((DropPLangStmt *) parsetree);
- break;
-
/*
* ******************************** DOMAIN statements ****
*/
@@ -1220,10 +1153,6 @@ standard_ProcessUtility(Node *parsetree,
CreateCast((CreateCastStmt *) parsetree);
break;
- case T_DropCastStmt:
- DropCast((DropCastStmt *) parsetree);
- break;
-
case T_CreateOpClassStmt:
DefineOpClass((CreateOpClassStmt *) parsetree);
break;
@@ -1236,14 +1165,6 @@ standard_ProcessUtility(Node *parsetree,
AlterOpFamily((AlterOpFamilyStmt *) parsetree);
break;
- case T_RemoveOpClassStmt:
- RemoveOpClass((RemoveOpClassStmt *) parsetree);
- break;
-
- case T_RemoveOpFamilyStmt:
- RemoveOpFamily((RemoveOpFamilyStmt *) parsetree);
- break;
-
case T_AlterTSDictionaryStmt:
AlterTSDictionary((AlterTSDictionaryStmt *) parsetree);
break;
@@ -1674,10 +1595,6 @@ CreateCommandTag(Node *parsetree)
tag = "ALTER FOREIGN DATA WRAPPER";
break;
- case T_DropFdwStmt:
- tag = "DROP FOREIGN DATA WRAPPER";
- break;
-
case T_CreateForeignServerStmt:
tag = "CREATE SERVER";
break;
@@ -1686,10 +1603,6 @@ CreateCommandTag(Node *parsetree)
tag = "ALTER SERVER";
break;
- case T_DropForeignServerStmt:
- tag = "DROP SERVER";
- break;
-
case T_CreateUserMappingStmt:
tag = "CREATE USER MAPPING";
break;
@@ -1754,6 +1667,39 @@ CreateCommandTag(Node *parsetree)
case OBJECT_EXTENSION:
tag = "DROP EXTENSION";
break;
+ case OBJECT_FUNCTION:
+ tag = "DROP FUNCTION";
+ break;
+ case OBJECT_AGGREGATE:
+ tag = "DROP AGGREGATE";
+ break;
+ case OBJECT_OPERATOR:
+ tag = "DROP OPERATOR";
+ break;
+ case OBJECT_LANGUAGE:
+ tag = "DROP LANGUAGE";
+ break;
+ case OBJECT_CAST:
+ tag = "DROP CAST";
+ break;
+ case OBJECT_TRIGGER:
+ tag = "DROP TRIGGER";
+ break;
+ case OBJECT_RULE:
+ tag = "DROP RULE";
+ break;
+ case OBJECT_FDW:
+ tag = "DROP FOREIGN DATA WRAPPER";
+ break;
+ case OBJECT_FOREIGN_SERVER:
+ tag = "DROP SERVER";
+ break;
+ case OBJECT_OPCLASS:
+ tag = "DROP OPERATOR CLASS";
+ break;
+ case OBJECT_OPFAMILY:
+ tag = "DROP OPERATOR FAMILY";
+ break;
default:
tag = "???";
}
@@ -1891,23 +1837,6 @@ CreateCommandTag(Node *parsetree)
tag = "ALTER SEQUENCE";
break;
- case T_RemoveFuncStmt:
- switch (((RemoveFuncStmt *) parsetree)->kind)
- {
- case OBJECT_FUNCTION:
- tag = "DROP FUNCTION";
- break;
- case OBJECT_AGGREGATE:
- tag = "DROP AGGREGATE";
- break;
- case OBJECT_OPERATOR:
- tag = "DROP OPERATOR";
- break;
- default:
- tag = "???";
- }
- break;
-
case T_DoStmt:
tag = "DO";
break;
@@ -2002,28 +1931,10 @@ CreateCommandTag(Node *parsetree)
tag = "CREATE TRIGGER";
break;
- case T_DropPropertyStmt:
- switch (((DropPropertyStmt *) parsetree)->removeType)
- {
- case OBJECT_TRIGGER:
- tag = "DROP TRIGGER";
- break;
- case OBJECT_RULE:
- tag = "DROP RULE";
- break;
- default:
- tag = "???";
- }
- break;
-
case T_CreatePLangStmt:
tag = "CREATE LANGUAGE";
break;
- case T_DropPLangStmt:
- tag = "DROP LANGUAGE";
- break;
-
case T_CreateRoleStmt:
tag = "CREATE ROLE";
break;
@@ -2072,10 +1983,6 @@ CreateCommandTag(Node *parsetree)
tag = "CREATE CAST";
break;
- case T_DropCastStmt:
- tag = "DROP CAST";
- break;
-
case T_CreateOpClassStmt:
tag = "CREATE OPERATOR CLASS";
break;
@@ -2088,14 +1995,6 @@ CreateCommandTag(Node *parsetree)
tag = "ALTER OPERATOR FAMILY";
break;
- case T_RemoveOpClassStmt:
- tag = "DROP OPERATOR CLASS";
- break;
-
- case T_RemoveOpFamilyStmt:
- tag = "DROP OPERATOR FAMILY";
- break;
-
case T_AlterTSDictionaryStmt:
tag = "ALTER TEXT SEARCH DICTIONARY";
break;
@@ -2306,10 +2205,8 @@ GetCommandLogLevel(Node *parsetree)
case T_CreateFdwStmt:
case T_AlterFdwStmt:
- case T_DropFdwStmt:
case T_CreateForeignServerStmt:
case T_AlterForeignServerStmt:
- case T_DropForeignServerStmt:
case T_CreateUserMappingStmt:
case T_AlterUserMappingStmt:
case T_DropUserMappingStmt:
@@ -2446,10 +2343,6 @@ GetCommandLogLevel(Node *parsetree)
lev = LOGSTMT_DDL;
break;
- case T_RemoveFuncStmt:
- lev = LOGSTMT_DDL;
- break;
-
case T_DoStmt:
lev = LOGSTMT_ALL;
break;
@@ -2533,18 +2426,10 @@ GetCommandLogLevel(Node *parsetree)
lev = LOGSTMT_DDL;
break;
- case T_DropPropertyStmt:
- lev = LOGSTMT_DDL;
- break;
-
case T_CreatePLangStmt:
lev = LOGSTMT_DDL;
break;
- case T_DropPLangStmt:
- lev = LOGSTMT_DDL;
- break;
-
case T_CreateDomainStmt:
lev = LOGSTMT_DDL;
break;
@@ -2597,10 +2482,6 @@ GetCommandLogLevel(Node *parsetree)
lev = LOGSTMT_DDL;
break;
- case T_DropCastStmt:
- lev = LOGSTMT_DDL;
- break;
-
case T_CreateOpClassStmt:
lev = LOGSTMT_DDL;
break;
@@ -2613,14 +2494,6 @@ GetCommandLogLevel(Node *parsetree)
lev = LOGSTMT_DDL;
break;
- case T_RemoveOpClassStmt:
- lev = LOGSTMT_DDL;
- break;
-
- case T_RemoveOpFamilyStmt:
- lev = LOGSTMT_DDL;
- break;
-
case T_AlterTSDictionaryStmt:
lev = LOGSTMT_DDL;
break;
diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h
index 64eeb73..f0dcf76 100644
--- a/src/include/commands/defrem.h
+++ b/src/include/commands/defrem.h
@@ -61,7 +61,6 @@ extern Oid GetDefaultOpClass(Oid type_id, Oid am_id);
/* commands/functioncmds.c */
extern void CreateFunction(CreateFunctionStmt *stmt, const char *queryString);
-extern void RemoveFunction(RemoveFuncStmt *stmt);
extern void RemoveFunctionById(Oid funcOid);
extern void SetFunctionReturnType(Oid funcOid, Oid newRetType);
extern void SetFunctionArgType(Oid funcOid, int argIndex, Oid newArgType);
@@ -70,7 +69,6 @@ extern void AlterFunctionOwner(List *name, List *argtypes, Oid newOwnerId);
extern void AlterFunctionOwner_oid(Oid procOid, Oid newOwnerId);
extern void AlterFunction(AlterFunctionStmt *stmt);
extern void CreateCast(CreateCastStmt *stmt);
-extern void DropCast(DropCastStmt *stmt);
extern void DropCastById(Oid castOid);
extern void AlterFunctionNamespace(List *name, List *argtypes, bool isagg,
const char *newschema);
@@ -80,7 +78,6 @@ extern Oid get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok);
/* commands/operatorcmds.c */
extern void DefineOperator(List *names, List *parameters);
-extern void RemoveOperator(RemoveFuncStmt *stmt);
extern void RemoveOperatorById(Oid operOid);
extern void AlterOperatorOwner(List *name, TypeName *typeName1,
TypeName *typename2, Oid newOwnerId);
@@ -91,7 +88,6 @@ extern Oid AlterOperatorNamespace_oid(Oid operOid, Oid newNspOid);
/* commands/aggregatecmds.c */
extern void DefineAggregate(List *name, List *args, bool oldstyle,
List *parameters);
-extern void RemoveAggregate(RemoveFuncStmt *stmt);
extern void RenameAggregate(List *name, List *args, const char *newname);
extern void AlterAggregateOwner(List *name, List *args, Oid newOwnerId);
@@ -99,8 +95,6 @@ extern void AlterAggregateOwner(List *name, List *args, Oid newOwnerId);
extern void DefineOpClass(CreateOpClassStmt *stmt);
extern void DefineOpFamily(CreateOpFamilyStmt *stmt);
extern void AlterOpFamily(AlterOpFamilyStmt *stmt);
-extern void RemoveOpClass(RemoveOpClassStmt *stmt);
-extern void RemoveOpFamily(RemoveOpFamilyStmt *stmt);
extern void RemoveOpClassById(Oid opclassOid);
extern void RemoveOpFamilyById(Oid opfamilyOid);
extern void RemoveAmOpEntryById(Oid entryOid);
@@ -156,11 +150,9 @@ extern void AlterForeignServerOwner(const char *name, Oid newOwnerId);
extern void AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId);
extern void CreateForeignDataWrapper(CreateFdwStmt *stmt);
extern void AlterForeignDataWrapper(AlterFdwStmt *stmt);
-extern void RemoveForeignDataWrapper(DropFdwStmt *stmt);
extern void RemoveForeignDataWrapperById(Oid fdwId);
extern void CreateForeignServer(CreateForeignServerStmt *stmt);
extern void AlterForeignServer(AlterForeignServerStmt *stmt);
-extern void RemoveForeignServer(DropForeignServerStmt *stmt);
extern void RemoveForeignServerById(Oid srvId);
extern void CreateUserMapping(CreateUserMappingStmt *stmt);
extern void AlterUserMapping(AlterUserMappingStmt *stmt);
diff --git a/src/include/commands/proclang.h b/src/include/commands/proclang.h
index 644c371..17d0972 100644
--- a/src/include/commands/proclang.h
+++ b/src/include/commands/proclang.h
@@ -15,7 +15,6 @@
#include "nodes/parsenodes.h"
extern void CreateProceduralLanguage(CreatePLangStmt *stmt);
-extern void DropProceduralLanguage(DropPLangStmt *stmt);
extern void DropProceduralLanguageById(Oid langOid);
extern void RenameLanguage(const char *oldname, const char *newname);
extern void AlterLanguageOwner(const char *name, Oid newOwnerId);
diff --git a/src/include/commands/trigger.h b/src/include/commands/trigger.h
index fe21298..e7d28f7 100644
--- a/src/include/commands/trigger.h
+++ b/src/include/commands/trigger.h
@@ -112,8 +112,6 @@ extern Oid CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
Oid constraintOid, Oid indexOid,
bool isInternal);
-extern void DropTrigger(RangeVar *relation, const char *trigname,
- DropBehavior behavior, bool missing_ok);
extern void RemoveTriggerById(Oid trigOid);
extern Oid get_trigger_oid(Oid relid, const char *name, bool missing_ok);
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index 824d8b5..3a24089 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -291,7 +291,6 @@ typedef enum NodeTag
T_IndexStmt,
T_CreateFunctionStmt,
T_AlterFunctionStmt,
- T_RemoveFuncStmt,
T_DoStmt,
T_RenameStmt,
T_RuleStmt,
@@ -312,9 +311,7 @@ typedef enum NodeTag
T_VariableShowStmt,
T_DiscardStmt,
T_CreateTrigStmt,
- T_DropPropertyStmt,
T_CreatePLangStmt,
- T_DropPLangStmt,
T_CreateRoleStmt,
T_AlterRoleStmt,
T_DropRoleStmt,
@@ -328,12 +325,9 @@ typedef enum NodeTag
T_AlterRoleSetStmt,
T_CreateConversionStmt,
T_CreateCastStmt,
- T_DropCastStmt,
T_CreateOpClassStmt,
T_CreateOpFamilyStmt,
T_AlterOpFamilyStmt,
- T_RemoveOpClassStmt,
- T_RemoveOpFamilyStmt,
T_PrepareStmt,
T_ExecuteStmt,
T_DeallocateStmt,
@@ -352,10 +346,8 @@ typedef enum NodeTag
T_AlterTSConfigurationStmt,
T_CreateFdwStmt,
T_AlterFdwStmt,
- T_DropFdwStmt,
T_CreateForeignServerStmt,
T_AlterForeignServerStmt,
- T_DropForeignServerStmt,
T_CreateUserMappingStmt,
T_AlterUserMappingStmt,
T_DropUserMappingStmt,
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index af6565e..6449eca 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -1612,7 +1612,7 @@ typedef struct AlterExtensionContentsStmt
} AlterExtensionContentsStmt;
/* ----------------------
- * Create/Drop FOREIGN DATA WRAPPER Statements
+ * Create/Alter FOREIGN DATA WRAPPER Statements
* ----------------------
*/
@@ -1632,16 +1632,8 @@ typedef struct AlterFdwStmt
List *options; /* generic options to FDW */
} AlterFdwStmt;
-typedef struct DropFdwStmt
-{
- NodeTag type;
- char *fdwname; /* foreign-data wrapper name */
- bool missing_ok; /* don't complain if missing */
- DropBehavior behavior; /* drop behavior - cascade/restrict */
-} DropFdwStmt;
-
/* ----------------------
- * Create/Drop FOREIGN SERVER Statements
+ * Create/Alter FOREIGN SERVER Statements
* ----------------------
*/
@@ -1664,14 +1656,6 @@ typedef struct AlterForeignServerStmt
bool has_version; /* version specified */
} AlterForeignServerStmt;
-typedef struct DropForeignServerStmt
-{
- NodeTag type;
- char *servername; /* server name */
- bool missing_ok; /* ignore missing servers */
- DropBehavior behavior; /* drop behavior - cascade/restrict */
-} DropForeignServerStmt;
-
/* ----------------------
* Create FOREIGN TABLE Statements
* ----------------------
@@ -1739,7 +1723,7 @@ typedef struct CreateTrigStmt
} CreateTrigStmt;
/* ----------------------
- * Create/Drop PROCEDURAL LANGUAGE Statements
+ * Create PROCEDURAL LANGUAGE Statements
* ----------------------
*/
typedef struct CreatePLangStmt
@@ -1753,14 +1737,6 @@ typedef struct CreatePLangStmt
bool pltrusted; /* PL is trusted */
} CreatePLangStmt;
-typedef struct DropPLangStmt
-{
- NodeTag type;
- char *plname; /* PL name */
- DropBehavior behavior; /* RESTRICT or CASCADE behavior */
- bool missing_ok; /* skip error if missing? */
-} DropPLangStmt;
-
/* ----------------------
* Create/Alter/Drop Role Statements
*
@@ -1921,30 +1897,13 @@ typedef struct DropStmt
{
NodeTag type;
List *objects; /* list of sublists of names (as Values) */
+ List *arguments; /* list of sublists of arguments (as Values) */
ObjectType removeType; /* object type */
DropBehavior behavior; /* RESTRICT or CASCADE behavior */
bool missing_ok; /* skip error if object is missing? */
} DropStmt;
/* ----------------------
- * Drop Rule|Trigger Statement
- *
- * In general this may be used for dropping any property of a relation;
- * for example, someday soon we may have DROP ATTRIBUTE.
- * ----------------------
- */
-
-typedef struct DropPropertyStmt
-{
- NodeTag type;
- RangeVar *relation; /* owning relation */
- char *property; /* name of rule, trigger, etc */
- ObjectType removeType; /* OBJECT_RULE or OBJECT_TRIGGER */
- DropBehavior behavior; /* RESTRICT or CASCADE behavior */
- bool missing_ok; /* skip error if missing? */
-} DropPropertyStmt;
-
-/* ----------------------
* Truncate Table Statement
* ----------------------
*/
@@ -2118,20 +2077,6 @@ typedef struct AlterFunctionStmt
} AlterFunctionStmt;
/* ----------------------
- * Drop {Function|Aggregate|Operator} Statement
- * ----------------------
- */
-typedef struct RemoveFuncStmt
-{
- NodeTag type;
- ObjectType kind; /* function, aggregate, operator */
- List *name; /* qualified name of object to drop */
- List *args; /* types of the arguments */
- DropBehavior behavior; /* RESTRICT or CASCADE behavior */
- bool missing_ok; /* skip error if missing? */
-} RemoveFuncStmt;
-
-/* ----------------------
* DO Statement
*
* DoStmt is the raw parser output, InlineCodeBlock is the execution-time API
@@ -2152,32 +2097,6 @@ typedef struct InlineCodeBlock
} InlineCodeBlock;
/* ----------------------
- * Drop Operator Class Statement
- * ----------------------
- */
-typedef struct RemoveOpClassStmt
-{
- NodeTag type;
- List *opclassname; /* qualified name (list of Value strings) */
- char *amname; /* name of index AM opclass is for */
- DropBehavior behavior; /* RESTRICT or CASCADE behavior */
- bool missing_ok; /* skip error if missing? */
-} RemoveOpClassStmt;
-
-/* ----------------------
- * Drop Operator Family Statement
- * ----------------------
- */
-typedef struct RemoveOpFamilyStmt
-{
- NodeTag type;
- List *opfamilyname; /* qualified name (list of Value strings) */
- char *amname; /* name of index AM opfamily is for */
- DropBehavior behavior; /* RESTRICT or CASCADE behavior */
- bool missing_ok; /* skip error if missing? */
-} RemoveOpFamilyStmt;
-
-/* ----------------------
* Alter Object Rename Statement
* ----------------------
*/
@@ -2558,20 +2477,6 @@ typedef struct CreateCastStmt
} CreateCastStmt;
/* ----------------------
- * DROP CAST Statement
- * ----------------------
- */
-typedef struct DropCastStmt
-{
- NodeTag type;
- TypeName *sourcetype;
- TypeName *targettype;
- DropBehavior behavior;
- bool missing_ok; /* skip error if missing? */
-} DropCastStmt;
-
-
-/* ----------------------
* PREPARE Statement
* ----------------------
*/
diff --git a/src/include/rewrite/rewriteRemove.h b/src/include/rewrite/rewriteRemove.h
index b9a63ba..14f3c1d 100644
--- a/src/include/rewrite/rewriteRemove.h
+++ b/src/include/rewrite/rewriteRemove.h
@@ -16,9 +16,6 @@
#include "nodes/parsenodes.h"
-
-extern void RemoveRewriteRule(RangeVar *relation, const char *ruleName,
- DropBehavior behavior, bool missing_ok);
extern void RemoveRewriteRuleById(Oid ruleOid);
#endif /* REWRITEREMOVE_H */
On Tue, Nov 15, 2011 at 4:43 AM, Kohei KaiGai <kaigai@kaigai.gr.jp> wrote:
Part-1) DROP statement refactoring
It is a remaining portion of what I submitted in the last commit fest.
It allows object types that didn't used DropStmt in gram.y to go
through RemoveObjects(), instead of individual RemoveXXXX().
Review of just this part:
- I think we can remove the special case for foreign data wrappers
because (1) the only case in which there's any behavioral difference
at all is if a superuser creates a foreign data wrapper (or the
ownership of one is reassigned to him) and he is then made not a
superuser; non-superusers can't create foreign data wrappers, and
existing foreign data wrappers can't be given to non-superusers;
moreover, (2) removing the special case causes the behavior to match
the documentation, which it currently doesn't (but only in the
aforementioned, extremely minor way).
- On the other hand, this patch blithely nukes the prohibition on
using DROP FUNCTION to remove an aggregate. I'm not sure that's a
good idea. It also eliminates the NOTICE when removing a built-in
function, which I think is OK because you don't actually get that far:
rhaas=# drop function int4pl(integer, integer);
ERROR: cannot drop function int4pl(integer,integer) because it is
required by the database system
- For some reason, we have code that causes procedural language names
to be downcased before use. Given that unquoted identifiers are
downcased anyway, this seems a bit redundant. I'm inclined to think
we don't need to preserve that behavior for DROP, especially because
other parts of the code - such as COMMENT - don't know about it
anyway. But rather than just changing it for DROP, I think we should
go through and rip out case_translate_language_name() across the
board, probably as a a separate commit.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
Robert Haas <robertmhaas@gmail.com> writes:
It also eliminates the NOTICE when removing a built-in
function, which I think is OK because you don't actually get that far:
There are paths that can reach that notice --- I think what you have to
do is create a new function that references a built-in one. But why
we bother to warn for that isn't clear to me.
- For some reason, we have code that causes procedural language names
to be downcased before use.
I think this is a hangover from the fact that CREATE FUNCTION's LANGUAGE
clause used to insist on the language name being a string literal, and
of course the lexer didn't case-fold it then. That's been deprecated
for long enough that we probably don't need to have the extra case-fold
step anymore.
regards, tom lane
On Thu, Nov 17, 2011 at 1:00 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Robert Haas <robertmhaas@gmail.com> writes:
It also eliminates the NOTICE when removing a built-in
function, which I think is OK because you don't actually get that far:There are paths that can reach that notice --- I think what you have to
do is create a new function that references a built-in one. But why
we bother to warn for that isn't clear to me.- For some reason, we have code that causes procedural language names
to be downcased before use.I think this is a hangover from the fact that CREATE FUNCTION's LANGUAGE
clause used to insist on the language name being a string literal, and
of course the lexer didn't case-fold it then. That's been deprecated
for long enough that we probably don't need to have the extra case-fold
step anymore.
OK, great.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
Excerpts from Robert Haas's message of jue nov 17 16:25:03 -0300 2011:
On Thu, Nov 17, 2011 at 1:00 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Robert Haas <robertmhaas@gmail.com> writes:
- For some reason, we have code that causes procedural language names
to be downcased before use.I think this is a hangover from the fact that CREATE FUNCTION's LANGUAGE
clause used to insist on the language name being a string literal, and
of course the lexer didn't case-fold it then. That's been deprecated
for long enough that we probably don't need to have the extra case-fold
step anymore.OK, great.
So the buildfarm broke due to this change, because citext does
--
-- Aggregates.
--
CREATE FUNCTION citext_smaller(citext, citext)
RETURNS citext
AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT;
CREATE FUNCTION citext_larger(citext, citext)
RETURNS citext
AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT;
--
Álvaro Herrera <alvherre@commandprompt.com>
The PostgreSQL Company - Command Prompt, Inc.
PostgreSQL Replication, Consulting, Custom Development, 24x7 support
On Thu, Nov 17, 2011 at 4:26 PM, Alvaro Herrera
<alvherre@commandprompt.com> wrote:
So the buildfarm broke due to this change, because citext does
Thanks for fixing it. Should we revert the original change?
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
Robert Haas <robertmhaas@gmail.com> writes:
On Thu, Nov 17, 2011 at 4:26 PM, Alvaro Herrera
<alvherre@commandprompt.com> wrote:So the buildfarm broke due to this change, because citext does
Thanks for fixing it. Should we revert the original change?
I still think it's reasonable to remove the extra downcasing step,
but we'll have to document it as a change. For instance, spelling
C as either "C" or 'C' would work differently now. The fact that
the former is downcased seems quite surprising to me, so I don't
think anybody would say that this isn't a better definition, but
undoubtedly it could force people to change their source files.
regards, tom lane
On Thu, Nov 17, 2011 at 5:29 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Robert Haas <robertmhaas@gmail.com> writes:
On Thu, Nov 17, 2011 at 4:26 PM, Alvaro Herrera
<alvherre@commandprompt.com> wrote:So the buildfarm broke due to this change, because citext does
Thanks for fixing it. Should we revert the original change?
I still think it's reasonable to remove the extra downcasing step,
but we'll have to document it as a change. For instance, spelling
C as either "C" or 'C' would work differently now. The fact that
the former is downcased seems quite surprising to me, so I don't
think anybody would say that this isn't a better definition, but
undoubtedly it could force people to change their source files.
So, should we add a note to all the LANGUAGE command pages in the
manual? Or just include this in the release notes?
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
Robert Haas <robertmhaas@gmail.com> writes:
On Thu, Nov 17, 2011 at 5:29 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
I still think it's reasonable to remove the extra downcasing step,
but we'll have to document it as a change.
So, should we add a note to all the LANGUAGE command pages in the
manual? Or just include this in the release notes?
Release note seems sufficient. I looked at the text in CREATE FUNCTION
and it doesn't seem to need changing.
regards, tom lane
On Thu, Nov 17, 2011 at 11:21 AM, Robert Haas <robertmhaas@gmail.com> wrote:
On Tue, Nov 15, 2011 at 4:43 AM, Kohei KaiGai <kaigai@kaigai.gr.jp> wrote:
Part-1) DROP statement refactoring
It is a remaining portion of what I submitted in the last commit fest.
It allows object types that didn't used DropStmt in gram.y to go
through RemoveObjects(), instead of individual RemoveXXXX().Review of just this part:
- I think we can remove the special case for foreign data wrappers
because (1) the only case in which there's any behavioral difference
at all is if a superuser creates a foreign data wrapper (or the
ownership of one is reassigned to him) and he is then made not a
superuser; non-superusers can't create foreign data wrappers, and
existing foreign data wrappers can't be given to non-superusers;
moreover, (2) removing the special case causes the behavior to match
the documentation, which it currently doesn't (but only in the
aforementioned, extremely minor way).- On the other hand, this patch blithely nukes the prohibition on
using DROP FUNCTION to remove an aggregate. I'm not sure that's a
good idea. It also eliminates the NOTICE when removing a built-in
function, which I think is OK because you don't actually get that far:rhaas=# drop function int4pl(integer, integer);
ERROR: cannot drop function int4pl(integer,integer) because it is
required by the database system- For some reason, we have code that causes procedural language names
to be downcased before use. Given that unquoted identifiers are
downcased anyway, this seems a bit redundant. I'm inclined to think
we don't need to preserve that behavior for DROP, especially because
other parts of the code - such as COMMENT - don't know about it
anyway. But rather than just changing it for DROP, I think we should
go through and rip out case_translate_language_name() across the
board, probably as a a separate commit.
I've committed part 1 of this patch series after correcting the above items.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
On Tue, Nov 15, 2011 at 4:43 AM, Kohei KaiGai <kaigai@kaigai.gr.jp> wrote:
Part-2) Groundworks on objectaddress.c
This patch adds necessary groundworks for Part-3 and Part-4.
It adds ObjectPropertyType of objectaddress.c index-oid and cache-id
for name lookup and attribute number of object name; these field is
used to detect namespace conflict on object_exists_namespace() that
shall be called on refactored ALTER SET SCHEMA/RENAME TO.
It also reduce some arguments of check_object_ownership(), and allows
to call this function without knowledge of ObjectType and text
representation. It allows to check ownership using this function from
the code path of AlterObjectNamespace_oid() that does not have (or
need to look up catalog to obtain) ObjectType information.
In addition, it adds regression test cases for ALTER SET SCHEMA/RENAME TO.
This part adds a new regression test to a parallel group with the
following comments:
# NB: temp.sql does a reconnect which transiently uses 2 connections,
# so keep this parallel group to at most 19 tests
...and this would be test #20. So we either need to move it
elsewhere, or move something else elsewhere. I'm tempted to add it to
this rather scrawny-looking group, unless someone sees a reason to do
otherwise:
test: privileges security_label collate
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
On Tue, Nov 15, 2011 at 4:43 AM, Kohei KaiGai <kaigai@kaigai.gr.jp> wrote:
Part-2) Groundworks on objectaddress.c
This patch adds necessary groundworks for Part-3 and Part-4.
It adds ObjectPropertyType of objectaddress.c index-oid and cache-id
for name lookup and attribute number of object name; these field is
used to detect namespace conflict on object_exists_namespace() that
shall be called on refactored ALTER SET SCHEMA/RENAME TO.
It also reduce some arguments of check_object_ownership(), and allows
to call this function without knowledge of ObjectType and text
representation. It allows to check ownership using this function from
the code path of AlterObjectNamespace_oid() that does not have (or
need to look up catalog to obtain) ObjectType information.
I spent some time wading through the code for parts 2 through 4, and I
guess I'm not sure this is headed in the right direction. If we need
this much infrastructure in order to consolidate the handling of ALTER
BLAH .. SET SCHEMA, then maybe it's not worth doing.
But I'm not sure why we do. My thought here was that we should
extended the ObjectProperty array in objectaddress.c so that
AlterObjectNamespace can get by with fewer arguments - specifically,
it seems like the following ought to be things that can be looked up
via the ObjectProperty mechanism:
int oidCacheId, int nameCacheId, int Anum_name, int Anum_namespace,
int Anum_owner, AclObjectKind acl_kind
The advantage of that, or so it seems to me, is that all this
information is in a table in objectaddress.c where multiple clients
can get at it at need, as opposed to the current system where it's
passed as arguments to AlterObjectNamespace(), and all that would need
to be duplicated if we had another function that did something
similar.
Now, what you have here is a much broader reworking. And that's not
necessarily bad, but at the moment I'm not really seeing how it
benefits us.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
2011/11/18 Robert Haas <robertmhaas@gmail.com>:
On Tue, Nov 15, 2011 at 4:43 AM, Kohei KaiGai <kaigai@kaigai.gr.jp> wrote:
Part-2) Groundworks on objectaddress.c
This patch adds necessary groundworks for Part-3 and Part-4.
It adds ObjectPropertyType of objectaddress.c index-oid and cache-id
for name lookup and attribute number of object name; these field is
used to detect namespace conflict on object_exists_namespace() that
shall be called on refactored ALTER SET SCHEMA/RENAME TO.
It also reduce some arguments of check_object_ownership(), and allows
to call this function without knowledge of ObjectType and text
representation. It allows to check ownership using this function from
the code path of AlterObjectNamespace_oid() that does not have (or
need to look up catalog to obtain) ObjectType information.I spent some time wading through the code for parts 2 through 4, and I
guess I'm not sure this is headed in the right direction. If we need
this much infrastructure in order to consolidate the handling of ALTER
BLAH .. SET SCHEMA, then maybe it's not worth doing.But I'm not sure why we do. My thought here was that we should
extended the ObjectProperty array in objectaddress.c so that
AlterObjectNamespace can get by with fewer arguments - specifically,
it seems like the following ought to be things that can be looked up
via the ObjectProperty mechanism:int oidCacheId, int nameCacheId, int Anum_name, int Anum_namespace,
int Anum_owner, AclObjectKind acl_kind
Thanks for your reviewing, and sorry for not a timely response.
I tried to add these items into ObjectProperty and replace existing caller of
AlterObjectNamespace, however, it seemed to me these members (especially
AclObjectKind) were too specific with current implementation of the
AlterObjectNamespace.
I think, SET SCHEMA, RENAME TO and OWNER TO are candidate to
consolidate similar codes using facilities in objectaddress.c.
Even though SET SCHEMA is mostly consolidated with AlterObjectNamespace,
RENAME TO and OWNER TO are implemented individual routines for each
object types. So, I thought it is preferable way to provide groundwork to be
applied these routines also.
In the part-2 patch, I added object_exists_namespace() to check namespace
conflicts commonly used to SET SCHEMA and RENAME TO, although we
have individual routines for RENAME TO.
And, I also modified check_ownership() to eliminate objtype/object/objarg; that
allows to invoke this function from code paths without these
information, such as
shdepReassignOwned() or AlterObjectNamespace_oid().
The advantage of that, or so it seems to me, is that all this
information is in a table in objectaddress.c where multiple clients
can get at it at need, as opposed to the current system where it's
passed as arguments to AlterObjectNamespace(), and all that would need
to be duplicated if we had another function that did something
similar.
Yes, correct.
Now, what you have here is a much broader reworking. And that's not
necessarily bad, but at the moment I'm not really seeing how it
benefits us.
In my point, if individual object types need to have its own handler for
alter commands, points of the code to check permissions are also
distributed for each object types. It shall be a burden to maintain hooks
that allows modules (e.g sepgsql) to have permission checks.
Thanks,
--
KaiGai Kohei <kaigai@kaigai.gr.jp>
On Sat, Nov 19, 2011 at 1:49 PM, Kohei KaiGai <kaigai@kaigai.gr.jp> wrote:
But I'm not sure why we do. My thought here was that we should
extended the ObjectProperty array in objectaddress.c so that
AlterObjectNamespace can get by with fewer arguments - specifically,
it seems like the following ought to be things that can be looked up
via the ObjectProperty mechanism:int oidCacheId, int nameCacheId, int Anum_name, int Anum_namespace,
int Anum_owner, AclObjectKind acl_kindThanks for your reviewing, and sorry for not a timely response.
I tried to add these items into ObjectProperty and replace existing caller of
AlterObjectNamespace, however, it seemed to me these members (especially
AclObjectKind) were too specific with current implementation of the
AlterObjectNamespace.
Hmm, maybe so. But then we could still move over some things.
oidCacheId is pretty much already there already, isn't it?
And, I also modified check_ownership() to eliminate objtype/object/objarg; that
allows to invoke this function from code paths without these
information, such as
shdepReassignOwned() or AlterObjectNamespace_oid().
Yeah. I'm not sure I like that. It doesn't seem like a particularly
good idea to throw away the information we have about the name the
user entered and assume we'll be able to regenerate it from the system
catalogs after the fact.
Now, what you have here is a much broader reworking. And that's not
necessarily bad, but at the moment I'm not really seeing how it
benefits us.In my point, if individual object types need to have its own handler for
alter commands, points of the code to check permissions are also
distributed for each object types. It shall be a burden to maintain hooks
that allows modules (e.g sepgsql) to have permission checks.
Well, it's always nicer if you can just put a call to some hook in one
place instead of many. But it's not worth sacrificing everything to
make that happen. I think we need to compare the value of only
needing a hook in one place against the disruption of changing a lot
of code that is working fine as it is. In the case of the DROP
commands, it seems to me that the refactoring you did came out a huge
win, but this doesn't seem as clear to me. Note that DROP actually
does dispatch the actual work of dropping the object to a
type-specific function, unlike what you're trying to do here.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
2011/11/21 Robert Haas <robertmhaas@gmail.com>:
Now, what you have here is a much broader reworking. And that's not
necessarily bad, but at the moment I'm not really seeing how it
benefits us.In my point, if individual object types need to have its own handler for
alter commands, points of the code to check permissions are also
distributed for each object types. It shall be a burden to maintain hooks
that allows modules (e.g sepgsql) to have permission checks.Well, it's always nicer if you can just put a call to some hook in one
place instead of many. But it's not worth sacrificing everything to
make that happen. I think we need to compare the value of only
needing a hook in one place against the disruption of changing a lot
of code that is working fine as it is. In the case of the DROP
commands, it seems to me that the refactoring you did came out a huge
win, but this doesn't seem as clear to me. Note that DROP actually
does dispatch the actual work of dropping the object to a
type-specific function, unlike what you're trying to do here.
Yes, I agree with your opinion.
I'm also not sure whether my refactoring efforts on ALTER commands
will give us larger worth than its size of code changes, although we will
be able to consolidate the point of hooks around them.
If we add new properties that required by AlterObjectNamespace, as
you suggested, it will allow to reduce number of caller of this routine
mechanically with small changes.
Should I try this reworking with this way?
At least, AlterObjectNamespace already consolidate the point to check
permissions.
I initially thought it is too specific for AlterObjectNamespace, then I
reconsidered that we may be able to apply same properties to
ALTER RENAME TO/SET OWNER commands also, even though
these commands have completely branched routines for each object
types.
Thanks,
--
KaiGai Kohei <kaigai@kaigai.gr.jp>
On Sun, Nov 27, 2011 at 3:14 PM, Kohei KaiGai <kaigai@kaigai.gr.jp> wrote:
If we add new properties that required by AlterObjectNamespace, as
you suggested, it will allow to reduce number of caller of this routine
mechanically with small changes.
Should I try this reworking with this way?
Yeah, let's try that for starters, and then see if anything further
suggests itself.
At least, AlterObjectNamespace already consolidate the point to check
permissions.
Right.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
2011/11/30 Robert Haas <robertmhaas@gmail.com>:
On Sun, Nov 27, 2011 at 3:14 PM, Kohei KaiGai <kaigai@kaigai.gr.jp> wrote:
If we add new properties that required by AlterObjectNamespace, as
you suggested, it will allow to reduce number of caller of this routine
mechanically with small changes.
Should I try this reworking with this way?Yeah, let's try that for starters, and then see if anything further
suggests itself.
OK. I marked this patch as "Returned with Feedback".
I will try it again.
In the timeframe of this commit-fest, I'll focuse on remaining my
patches and reviewing pgsql-fdw.
Thanks,
--
KaiGai Kohei <kaigai@kaigai.gr.jp>