diff options
author | Alvaro Herrera | 2015-03-03 17:10:50 +0000 |
---|---|---|
committer | Alvaro Herrera | 2015-03-03 17:10:50 +0000 |
commit | a2e35b53c39b2a27d3e332dc7c506539c306fd44 (patch) | |
tree | 1f4cd33208d33f4a8b3159b0d3757109c67d4b14 /src/backend/commands | |
parent | 6f9d79904748c26a58991942dc6719db558f77b0 (diff) |
Change many routines to return ObjectAddress rather than OID
The changed routines are mostly those that can be directly called by
ProcessUtilitySlow; the intention is to make the affected object
information more precise, in support for future event trigger changes.
Originally it was envisioned that the OID of the affected object would
be enough, and in most cases that is correct, but upon actually
implementing the event trigger changes it turned out that ObjectAddress
is more widely useful.
Additionally, some command execution routines grew an output argument
that's an object address which provides further info about the executed
command. To wit:
* for ALTER DOMAIN / ADD CONSTRAINT, it corresponds to the address of
the new constraint
* for ALTER OBJECT / SET SCHEMA, it corresponds to the address of the
schema that originally contained the object.
* for ALTER EXTENSION {ADD, DROP} OBJECT, it corresponds to the address
of the object added to or dropped from the extension.
There's no user-visible change in this commit, and no functional change
either.
Discussion: [email protected]
Reviewed-By: Stephen Frost, Andres Freund
Diffstat (limited to 'src/backend/commands')
28 files changed, 601 insertions, 401 deletions
diff --git a/src/backend/commands/aggregatecmds.c b/src/backend/commands/aggregatecmds.c index 70a5b8ad1bb..894c89df947 100644 --- a/src/backend/commands/aggregatecmds.c +++ b/src/backend/commands/aggregatecmds.c @@ -51,7 +51,7 @@ * isn't an ordered-set aggregate. * "parameters" is a list of DefElem representing the agg's definition clauses. */ -Oid +ObjectAddress DefineAggregate(List *name, List *args, bool oldstyle, List *parameters, const char *queryString) { diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c index 78b54b4a418..59aacef7ea9 100644 --- a/src/backend/commands/alter.c +++ b/src/backend/commands/alter.c @@ -299,8 +299,10 @@ AlterObjectRename_internal(Relation rel, Oid objectId, const char *new_name) /* * Executes an ALTER OBJECT / RENAME TO statement. Based on the object * type, the function appropriate to that type is executed. + * + * Return value is the address of the renamed object. */ -Oid +ObjectAddress ExecRenameStmt(RenameStmt *stmt) { switch (stmt->renameType) @@ -378,39 +380,54 @@ ExecRenameStmt(RenameStmt *stmt) stmt->newname); heap_close(catalog, RowExclusiveLock); - return address.objectId; + return address; } default: elog(ERROR, "unrecognized rename stmt type: %d", (int) stmt->renameType); - return InvalidOid; /* keep compiler happy */ + return InvalidObjectAddress; /* keep compiler happy */ } } /* * Executes an ALTER OBJECT / SET SCHEMA statement. Based on the object * type, the function appropriate to that type is executed. + * + * Return value is that of the altered object. + * + * oldSchemaAddr is an output argument which, if not NULL, is set to the object + * address of the original schema. */ -Oid -ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt) +ObjectAddress +ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt, + ObjectAddress *oldSchemaAddr) { + ObjectAddress address; + Oid oldNspOid; + switch (stmt->objectType) { case OBJECT_EXTENSION: - return AlterExtensionNamespace(stmt->object, stmt->newschema); + address = AlterExtensionNamespace(stmt->object, stmt->newschema, + oldSchemaAddr ? &oldNspOid : NULL); + break; case OBJECT_FOREIGN_TABLE: case OBJECT_SEQUENCE: case OBJECT_TABLE: case OBJECT_VIEW: case OBJECT_MATVIEW: - return AlterTableNamespace(stmt); + address = AlterTableNamespace(stmt, + oldSchemaAddr ? &oldNspOid : NULL); + break; case OBJECT_DOMAIN: case OBJECT_TYPE: - return AlterTypeNamespace(stmt->object, stmt->newschema, - stmt->objectType); + address = AlterTypeNamespace(stmt->object, stmt->newschema, + stmt->objectType, + oldSchemaAddr ? &oldNspOid : NULL); + break; /* generic code path */ case OBJECT_AGGREGATE: @@ -442,19 +459,22 @@ ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt) catalog = heap_open(classId, RowExclusiveLock); nspOid = LookupCreationNamespace(stmt->newschema); - AlterObjectNamespace_internal(catalog, address.objectId, - nspOid); + oldNspOid = AlterObjectNamespace_internal(catalog, address.objectId, + nspOid); heap_close(catalog, RowExclusiveLock); - - return address.objectId; } break; default: elog(ERROR, "unrecognized AlterObjectSchemaStmt type: %d", (int) stmt->objectType); - return InvalidOid; /* keep compiler happy */ + return InvalidObjectAddress; /* keep compiler happy */ } + + if (oldSchemaAddr) + ObjectAddressSet(*oldSchemaAddr, NamespaceRelationId, oldNspOid); + + return address; } /* @@ -676,7 +696,7 @@ AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid) * Executes an ALTER OBJECT / OWNER TO statement. Based on the object * type, the function appropriate to that type is executed. */ -Oid +ObjectAddress ExecAlterOwnerStmt(AlterOwnerStmt *stmt) { Oid newowner = get_role_oid(stmt->newowner, false); @@ -747,15 +767,14 @@ ExecAlterOwnerStmt(AlterOwnerStmt *stmt) AlterObjectOwner_internal(catalog, address.objectId, newowner); heap_close(catalog, RowExclusiveLock); - return address.objectId; + return address; } break; default: elog(ERROR, "unrecognized AlterOwnerStmt type: %d", (int) stmt->objectType); - - return InvalidOid; /* keep compiler happy */ + return InvalidObjectAddress; /* keep compiler happy */ } } diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c index dc1b37cb693..3febdd5cf44 100644 --- a/src/backend/commands/cluster.c +++ b/src/backend/commands/cluster.c @@ -677,7 +677,8 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, char relpersistence, reloptions, false, true, - true); + true, + NULL); Assert(OIDNewHeap != InvalidOid); ReleaseSysCache(tuple); diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c index 4334eb96832..df67e509420 100644 --- a/src/backend/commands/collationcmds.c +++ b/src/backend/commands/collationcmds.c @@ -37,7 +37,7 @@ /* * CREATE COLLATION */ -Oid +ObjectAddress DefineCollation(List *names, List *parameters) { char *collName; @@ -51,6 +51,7 @@ DefineCollation(List *names, List *parameters) char *collcollate = NULL; char *collctype = NULL; Oid newoid; + ObjectAddress address; collNamespace = QualifiedNameGetCreationNamespace(names, &collName); @@ -137,11 +138,13 @@ DefineCollation(List *names, List *parameters) collcollate, collctype); + ObjectAddressSet(address, CollationRelationId, newoid); + /* check that the locales can be loaded */ CommandCounterIncrement(); (void) pg_newlocale_from_collation(newoid); - return newoid; + return address; } /* diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c index ed1e46e73c1..6d8c0061bdc 100644 --- a/src/backend/commands/comment.c +++ b/src/backend/commands/comment.c @@ -36,11 +36,11 @@ * This routine is used to add the associated comment into * pg_description for the object specified by the given SQL command. */ -Oid +ObjectAddress CommentObject(CommentStmt *stmt) { - ObjectAddress address; Relation relation; + ObjectAddress address = InvalidObjectAddress; /* * When loading a dump, we may see a COMMENT ON DATABASE for the old name @@ -60,7 +60,7 @@ CommentObject(CommentStmt *stmt) ereport(WARNING, (errcode(ERRCODE_UNDEFINED_DATABASE), errmsg("database \"%s\" does not exist", database))); - return InvalidOid; + return address; } } @@ -126,7 +126,7 @@ CommentObject(CommentStmt *stmt) if (relation != NULL) relation_close(relation, NoLock); - return address.objectId; + return address; } /* diff --git a/src/backend/commands/conversioncmds.c b/src/backend/commands/conversioncmds.c index f58b0a9e9d2..9cd5ced5c7a 100644 --- a/src/backend/commands/conversioncmds.c +++ b/src/backend/commands/conversioncmds.c @@ -34,7 +34,7 @@ /* * CREATE CONVERSION */ -Oid +ObjectAddress CreateConversionCommand(CreateConversionStmt *stmt) { Oid namespaceId; diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index c961429a0f5..54b2f382ea0 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -58,8 +58,8 @@ typedef struct BulkInsertState bistate; /* bulk insert state */ } DR_intorel; -/* the OID of the created table, for ExecCreateTableAs consumption */ -static Oid CreateAsRelid = InvalidOid; +/* the address of the created table, for ExecCreateTableAs consumption */ +static ObjectAddress CreateAsReladdr = {InvalidOid, InvalidOid, 0}; static void intorel_startup(DestReceiver *self, int operation, TupleDesc typeinfo); static void intorel_receive(TupleTableSlot *slot, DestReceiver *self); @@ -70,7 +70,7 @@ static void intorel_destroy(DestReceiver *self); /* * ExecCreateTableAs -- execute a CREATE TABLE AS command */ -Oid +ObjectAddress ExecCreateTableAs(CreateTableAsStmt *stmt, const char *queryString, ParamListInfo params, char *completionTag) { @@ -81,7 +81,7 @@ ExecCreateTableAs(CreateTableAsStmt *stmt, const char *queryString, Oid save_userid = InvalidOid; int save_sec_context = 0; int save_nestlevel = 0; - Oid relOid; + ObjectAddress address; List *rewritten; PlannedStmt *plan; QueryDesc *queryDesc; @@ -99,7 +99,7 @@ ExecCreateTableAs(CreateTableAsStmt *stmt, const char *queryString, (errcode(ERRCODE_DUPLICATE_TABLE), errmsg("relation \"%s\" already exists, skipping", stmt->into->rel->relname))); - return InvalidOid; + return InvalidObjectAddress; } } @@ -121,9 +121,9 @@ ExecCreateTableAs(CreateTableAsStmt *stmt, const char *queryString, Assert(!is_matview); /* excluded by syntax */ ExecuteQuery(estmt, into, queryString, params, dest, completionTag); - relOid = CreateAsRelid; - CreateAsRelid = InvalidOid; - return relOid; + address = CreateAsReladdr; + CreateAsReladdr = InvalidObjectAddress; + return address; } Assert(query->commandType == CMD_SELECT); @@ -216,10 +216,10 @@ ExecCreateTableAs(CreateTableAsStmt *stmt, const char *queryString, SetUserIdAndSecContext(save_userid, save_sec_context); } - relOid = CreateAsRelid; - CreateAsRelid = InvalidOid; + address = CreateAsReladdr; + CreateAsReladdr = InvalidObjectAddress; - return relOid; + return address; } /* @@ -288,7 +288,7 @@ intorel_startup(DestReceiver *self, int operation, TupleDesc typeinfo) bool is_matview; char relkind; CreateStmt *create; - Oid intoRelationId; + ObjectAddress intoRelationAddr; Relation intoRelationDesc; RangeTblEntry *rte; Datum toast_options; @@ -385,7 +385,7 @@ intorel_startup(DestReceiver *self, int operation, TupleDesc typeinfo) /* * Actually create the target table */ - intoRelationId = DefineRelation(create, relkind, InvalidOid); + intoRelationAddr = DefineRelation(create, relkind, InvalidOid, NULL); /* * If necessary, create a TOAST table for the target table. Note that @@ -403,7 +403,7 @@ intorel_startup(DestReceiver *self, int operation, TupleDesc typeinfo) (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); - NewRelationCreateToastTable(intoRelationId, toast_options); + NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); /* Create the "view" part of a materialized view. */ if (is_matview) @@ -411,14 +411,14 @@ intorel_startup(DestReceiver *self, int operation, TupleDesc typeinfo) /* StoreViewQuery scribbles on tree, so make a copy */ Query *query = (Query *) copyObject(into->viewQuery); - StoreViewQuery(intoRelationId, query, false); + StoreViewQuery(intoRelationAddr.objectId, query, false); CommandCounterIncrement(); } /* * Finally we can open the target table */ - intoRelationDesc = heap_open(intoRelationId, AccessExclusiveLock); + intoRelationDesc = heap_open(intoRelationAddr.objectId, AccessExclusiveLock); /* * Check INSERT permission on the constructed table. @@ -428,7 +428,7 @@ intorel_startup(DestReceiver *self, int operation, TupleDesc typeinfo) */ rte = makeNode(RangeTblEntry); rte->rtekind = RTE_RELATION; - rte->relid = intoRelationId; + rte->relid = intoRelationAddr.objectId; rte->relkind = relkind; rte->requiredPerms = ACL_INSERT; @@ -446,7 +446,7 @@ intorel_startup(DestReceiver *self, int operation, TupleDesc typeinfo) * be enabled here. We don't actually support that currently, so throw * our own ereport(ERROR) if that happens. */ - if (check_enable_rls(intoRelationId, InvalidOid, false) == RLS_ENABLED) + if (check_enable_rls(intoRelationAddr.objectId, InvalidOid, false) == RLS_ENABLED) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errmsg("policies not yet implemented for this command")))); @@ -464,8 +464,8 @@ intorel_startup(DestReceiver *self, int operation, TupleDesc typeinfo) myState->rel = intoRelationDesc; myState->output_cid = GetCurrentCommandId(true); - /* and remember the new relation's OID for ExecCreateTableAs */ - CreateAsRelid = RelationGetRelid(myState->rel); + /* and remember the new relation's address for ExecCreateTableAs */ + CreateAsReladdr = intoRelationAddr; /* * We can skip WAL-logging the insertions, unless PITR or streaming diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index 5e669619bab..85791364205 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -938,7 +938,7 @@ dropdb(const char *dbname, bool missing_ok) /* * Rename database */ -Oid +ObjectAddress RenameDatabase(const char *oldname, const char *newname) { Oid db_id; @@ -946,6 +946,7 @@ RenameDatabase(const char *oldname, const char *newname) Relation rel; int notherbackends; int npreparedxacts; + ObjectAddress address; /* * Look up the target database's OID, and get exclusive lock on it. We @@ -1013,12 +1014,14 @@ RenameDatabase(const char *oldname, const char *newname) InvokeObjectPostAlterHook(DatabaseRelationId, db_id, 0); + ObjectAddressSet(address, DatabaseRelationId, db_id); + /* * Close pg_database, but keep lock till commit. */ heap_close(rel, NoLock); - return db_id; + return address; } @@ -1560,7 +1563,7 @@ AlterDatabaseSet(AlterDatabaseSetStmt *stmt) /* * ALTER DATABASE name OWNER TO newowner */ -Oid +ObjectAddress AlterDatabaseOwner(const char *dbname, Oid newOwnerId) { Oid db_id; @@ -1569,6 +1572,7 @@ AlterDatabaseOwner(const char *dbname, Oid newOwnerId) ScanKeyData scankey; SysScanDesc scan; Form_pg_database datForm; + ObjectAddress address; /* * Get the old tuple. We don't need a lock on the database per se, @@ -1663,12 +1667,14 @@ AlterDatabaseOwner(const char *dbname, Oid newOwnerId) InvokeObjectPostAlterHook(DatabaseRelationId, HeapTupleGetOid(tuple), 0); + ObjectAddressSet(address, DatabaseRelationId, db_id); + systable_endscan(scan); /* Close pg_database, but keep lock till commit */ heap_close(rel, NoLock); - return db_id; + return address; } diff --git a/src/backend/commands/event_trigger.c b/src/backend/commands/event_trigger.c index deeb8dcfaf1..f573c9ce706 100644 --- a/src/backend/commands/event_trigger.c +++ b/src/backend/commands/event_trigger.c @@ -518,12 +518,13 @@ AlterEventTrigger(AlterEventTrigStmt *stmt) /* * Change event trigger's owner -- by name */ -Oid +ObjectAddress AlterEventTriggerOwner(const char *name, Oid newOwnerId) { Oid evtOid; HeapTuple tup; Relation rel; + ObjectAddress address; rel = heap_open(EventTriggerRelationId, RowExclusiveLock); @@ -538,11 +539,13 @@ AlterEventTriggerOwner(const char *name, Oid newOwnerId) AlterEventTriggerOwner_internal(rel, tup, newOwnerId); + ObjectAddressSet(address, EventTriggerRelationId, evtOid); + heap_freetuple(tup); heap_close(rel, RowExclusiveLock); - return evtOid; + return address; } /* diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c index 3b95552a60f..aa733575e46 100644 --- a/src/backend/commands/extension.c +++ b/src/backend/commands/extension.c @@ -1170,7 +1170,7 @@ find_update_path(List *evi_list, /* * CREATE EXTENSION */ -Oid +ObjectAddress CreateExtension(CreateExtensionStmt *stmt) { DefElem *d_schema = NULL; @@ -1188,6 +1188,7 @@ CreateExtension(CreateExtensionStmt *stmt) List *requiredSchemas; Oid extensionOid; ListCell *lc; + ObjectAddress address; /* Check extension name validity before any filesystem access */ check_valid_extension_name(stmt->extname); @@ -1206,7 +1207,7 @@ CreateExtension(CreateExtensionStmt *stmt) (errcode(ERRCODE_DUPLICATE_OBJECT), errmsg("extension \"%s\" already exists, skipping", stmt->extname))); - return InvalidOid; + return InvalidObjectAddress; } else ereport(ERROR, @@ -1443,12 +1444,13 @@ CreateExtension(CreateExtensionStmt *stmt) /* * Insert new tuple into pg_extension, and create dependency entries. */ - extensionOid = InsertExtensionTuple(control->name, extowner, - schemaOid, control->relocatable, - versionName, - PointerGetDatum(NULL), - PointerGetDatum(NULL), - requiredExtensions); + address = InsertExtensionTuple(control->name, extowner, + schemaOid, control->relocatable, + versionName, + PointerGetDatum(NULL), + PointerGetDatum(NULL), + requiredExtensions); + extensionOid = address.objectId; /* * Apply any control-file comment on extension @@ -1471,7 +1473,7 @@ CreateExtension(CreateExtensionStmt *stmt) ApplyExtensionUpdates(extensionOid, pcontrol, versionName, updateVersions); - return extensionOid; + return address; } /* @@ -1487,7 +1489,7 @@ CreateExtension(CreateExtensionStmt *stmt) * extConfig and extCondition should be arrays or PointerGetDatum(NULL). * We declare them as plain Datum to avoid needing array.h in extension.h. */ -Oid +ObjectAddress InsertExtensionTuple(const char *extName, Oid extOwner, Oid schemaOid, bool relocatable, const char *extVersion, Datum extConfig, Datum extCondition, @@ -1564,7 +1566,7 @@ InsertExtensionTuple(const char *extName, Oid extOwner, /* Post creation hook for new extension */ InvokeObjectPostCreateHook(ExtensionRelationId, extensionOid, 0); - return extensionOid; + return myself; } /* @@ -2399,8 +2401,8 @@ extension_config_remove(Oid extensionoid, Oid tableoid) /* * Execute ALTER EXTENSION SET SCHEMA */ -Oid -AlterExtensionNamespace(List *names, const char *newschema) +ObjectAddress +AlterExtensionNamespace(List *names, const char *newschema, Oid *oldschema) { char *extensionName; Oid extensionOid; @@ -2416,6 +2418,7 @@ AlterExtensionNamespace(List *names, const char *newschema) SysScanDesc depScan; HeapTuple depTup; ObjectAddresses *objsMoved; + ObjectAddress extAddr; if (list_length(names) != 1) ereport(ERROR, @@ -2480,7 +2483,7 @@ AlterExtensionNamespace(List *names, const char *newschema) if (extForm->extnamespace == nspOid) { heap_close(extRel, RowExclusiveLock); - return InvalidOid; + return InvalidObjectAddress; } /* Check extension is supposed to be relocatable */ @@ -2557,6 +2560,10 @@ AlterExtensionNamespace(List *names, const char *newschema) get_namespace_name(oldNspOid)))); } + /* report old schema, if caller wants it */ + if (oldschema) + *oldschema = oldNspOid; + systable_endscan(depScan); relation_close(depRel, AccessShareLock); @@ -2575,13 +2582,15 @@ AlterExtensionNamespace(List *names, const char *newschema) InvokeObjectPostAlterHook(ExtensionRelationId, extensionOid, 0); - return extensionOid; + ObjectAddressSet(extAddr, ExtensionRelationId, extensionOid); + + return extAddr; } /* * Execute ALTER EXTENSION UPDATE */ -Oid +ObjectAddress ExecAlterExtensionStmt(AlterExtensionStmt *stmt) { DefElem *d_new_version = NULL; @@ -2597,6 +2606,7 @@ ExecAlterExtensionStmt(AlterExtensionStmt *stmt) Datum datum; bool isnull; ListCell *lc; + ObjectAddress address; /* * We use global variables to track the extension being created, so we can @@ -2698,7 +2708,7 @@ ExecAlterExtensionStmt(AlterExtensionStmt *stmt) ereport(NOTICE, (errmsg("version \"%s\" of extension \"%s\" is already installed", versionName, stmt->extname))); - return InvalidOid; + return InvalidObjectAddress; } /* @@ -2715,7 +2725,9 @@ ExecAlterExtensionStmt(AlterExtensionStmt *stmt) ApplyExtensionUpdates(extensionOid, control, oldVersionName, updateVersions); - return extensionOid; + ObjectAddressSet(address, ExtensionRelationId, extensionOid); + + return address; } /* @@ -2879,9 +2891,15 @@ ApplyExtensionUpdates(Oid extensionOid, /* * Execute ALTER EXTENSION ADD/DROP + * + * Return value is the address of the altered extension. + * + * objAddr is an output argument which, if not NULL, is set to the address of + * the added/dropped object. */ -Oid -ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt) +ObjectAddress +ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt, + ObjectAddress *objAddr) { ObjectAddress extension; ObjectAddress object; @@ -2906,6 +2924,10 @@ ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt) object = get_object_address(stmt->objtype, stmt->objname, stmt->objargs, &relation, ShareUpdateExclusiveLock, false); + Assert(object.objectSubId == 0); + if (objAddr) + *objAddr = object; + /* Permission check: must own target object, too */ check_object_ownership(GetUserId(), stmt->objtype, object, stmt->objname, stmt->objargs, relation); @@ -2984,5 +3006,5 @@ ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt) if (relation != NULL) relation_close(relation, NoLock); - return extension.objectId; + return extension; } diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c index 537e31c34ee..bd4839189e6 100644 --- a/src/backend/commands/foreigncmds.c +++ b/src/backend/commands/foreigncmds.c @@ -292,12 +292,13 @@ AlterForeignDataWrapperOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerI * * Note restrictions in the "_internal" function, above. */ -Oid +ObjectAddress AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId) { Oid fdwId; HeapTuple tup; Relation rel; + ObjectAddress address; rel = heap_open(ForeignDataWrapperRelationId, RowExclusiveLock); @@ -312,11 +313,13 @@ AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId) AlterForeignDataWrapperOwner_internal(rel, tup, newOwnerId); + ObjectAddressSet(address, ForeignDataWrapperRelationId, fdwId); + heap_freetuple(tup); heap_close(rel, RowExclusiveLock); - return fdwId; + return address; } /* @@ -427,12 +430,13 @@ AlterForeignServerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId) /* * Change foreign server owner -- by name */ -Oid +ObjectAddress AlterForeignServerOwner(const char *name, Oid newOwnerId) { Oid servOid; HeapTuple tup; Relation rel; + ObjectAddress address; rel = heap_open(ForeignServerRelationId, RowExclusiveLock); @@ -447,11 +451,13 @@ AlterForeignServerOwner(const char *name, Oid newOwnerId) AlterForeignServerOwner_internal(rel, tup, newOwnerId); + ObjectAddressSet(address, ForeignServerRelationId, servOid); + heap_freetuple(tup); heap_close(rel, RowExclusiveLock); - return servOid; + return address; } /* @@ -569,7 +575,7 @@ parse_func_options(List *func_options, /* * Create a foreign-data wrapper */ -Oid +ObjectAddress CreateForeignDataWrapper(CreateFdwStmt *stmt) { Relation rel; @@ -676,14 +682,14 @@ CreateForeignDataWrapper(CreateFdwStmt *stmt) heap_close(rel, RowExclusiveLock); - return fdwId; + return myself; } /* * Alter foreign-data wrapper */ -Oid +ObjectAddress AlterForeignDataWrapper(AlterFdwStmt *stmt) { Relation rel; @@ -699,6 +705,7 @@ AlterForeignDataWrapper(AlterFdwStmt *stmt) bool validator_given; Oid fdwhandler; Oid fdwvalidator; + ObjectAddress myself; rel = heap_open(ForeignDataWrapperRelationId, RowExclusiveLock); @@ -801,10 +808,11 @@ AlterForeignDataWrapper(AlterFdwStmt *stmt) heap_freetuple(tp); + ObjectAddressSet(myself, ForeignDataWrapperRelationId, fdwId); + /* Update function dependencies if we changed them */ if (handler_given || validator_given) { - ObjectAddress myself; ObjectAddress referenced; /* @@ -817,9 +825,6 @@ AlterForeignDataWrapper(AlterFdwStmt *stmt) DEPENDENCY_NORMAL); /* And build new ones. */ - myself.classId = ForeignDataWrapperRelationId; - myself.objectId = fdwId; - myself.objectSubId = 0; if (OidIsValid(fdwhandler)) { @@ -842,7 +847,7 @@ AlterForeignDataWrapper(AlterFdwStmt *stmt) heap_close(rel, RowExclusiveLock); - return fdwId; + return myself; } @@ -873,7 +878,7 @@ RemoveForeignDataWrapperById(Oid fdwId) /* * Create a foreign server */ -Oid +ObjectAddress CreateForeignServer(CreateForeignServerStmt *stmt) { Relation rel; @@ -979,14 +984,14 @@ CreateForeignServer(CreateForeignServerStmt *stmt) heap_close(rel, RowExclusiveLock); - return srvId; + return myself; } /* * Alter foreign server */ -Oid +ObjectAddress AlterForeignServer(AlterForeignServerStmt *stmt) { Relation rel; @@ -996,6 +1001,7 @@ AlterForeignServer(AlterForeignServerStmt *stmt) bool repl_repl[Natts_pg_foreign_server]; Oid srvId; Form_pg_foreign_server srvForm; + ObjectAddress address; rel = heap_open(ForeignServerRelationId, RowExclusiveLock); @@ -1072,11 +1078,13 @@ AlterForeignServer(AlterForeignServerStmt *stmt) InvokeObjectPostAlterHook(ForeignServerRelationId, srvId, 0); + ObjectAddressSet(address, ForeignServerRelationId, srvId); + heap_freetuple(tp); heap_close(rel, RowExclusiveLock); - return srvId; + return address; } @@ -1134,7 +1142,7 @@ user_mapping_ddl_aclcheck(Oid umuserid, Oid serverid, const char *servername) /* * Create user mapping */ -Oid +ObjectAddress CreateUserMapping(CreateUserMappingStmt *stmt) { Relation rel; @@ -1225,14 +1233,14 @@ CreateUserMapping(CreateUserMappingStmt *stmt) heap_close(rel, RowExclusiveLock); - return umId; + return myself; } /* * Alter user mapping */ -Oid +ObjectAddress AlterUserMapping(AlterUserMappingStmt *stmt) { Relation rel; @@ -1243,6 +1251,7 @@ AlterUserMapping(AlterUserMappingStmt *stmt) Oid useId; Oid umId; ForeignServer *srv; + ObjectAddress address; rel = heap_open(UserMappingRelationId, RowExclusiveLock); @@ -1309,11 +1318,13 @@ AlterUserMapping(AlterUserMappingStmt *stmt) simple_heap_update(rel, &tp->t_self, tp); CatalogUpdateIndexes(rel, tp); + ObjectAddressSet(address, UserMappingRelationId, umId); + heap_freetuple(tp); heap_close(rel, RowExclusiveLock); - return umId; + return address; } diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index b3a91fc681f..f4725056da0 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -112,6 +112,7 @@ compute_return_type(TypeName *returnType, Oid languageOid, Oid namespaceId; AclResult aclresult; char *typname; + ObjectAddress address; /* * Only C-coded functions can be I/O functions. We enforce this @@ -144,7 +145,8 @@ compute_return_type(TypeName *returnType, Oid languageOid, if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_NAMESPACE, get_namespace_name(namespaceId)); - rettype = TypeShellMake(typname, namespaceId, GetUserId()); + address = TypeShellMake(typname, namespaceId, GetUserId()); + rettype = address.objectId; Assert(OidIsValid(rettype)); } @@ -810,7 +812,7 @@ interpret_AS_clause(Oid languageOid, const char *languageName, * CreateFunction * Execute a CREATE FUNCTION utility statement. */ -Oid +ObjectAddress CreateFunction(CreateFunctionStmt *stmt, const char *queryString) { char *probin_str; @@ -1071,7 +1073,7 @@ RemoveFunctionById(Oid funcOid) * RENAME and OWNER clauses, which are handled as part of the generic * ALTER framework). */ -Oid +ObjectAddress AlterFunction(AlterFunctionStmt *stmt) { HeapTuple tup; @@ -1086,6 +1088,7 @@ AlterFunction(AlterFunctionStmt *stmt) List *set_items = NIL; DefElem *cost_item = NULL; DefElem *rows_item = NULL; + ObjectAddress address; rel = heap_open(ProcedureRelationId, RowExclusiveLock); @@ -1201,10 +1204,12 @@ AlterFunction(AlterFunctionStmt *stmt) InvokeObjectPostAlterHook(ProcedureRelationId, funcOid, 0); + ObjectAddressSet(address, ProcedureRelationId, funcOid); + heap_close(rel, NoLock); heap_freetuple(tup); - return funcOid; + return address; } /* @@ -1282,7 +1287,7 @@ SetFunctionArgType(Oid funcOid, int argIndex, Oid newArgType) /* * CREATE CAST */ -Oid +ObjectAddress CreateCast(CreateCastStmt *stmt) { Oid sourcetypeid; @@ -1596,7 +1601,7 @@ CreateCast(CreateCastStmt *stmt) heap_close(relation, RowExclusiveLock); - return castid; + return myself; } /* diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index e8596698970..6563f2bb5bf 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -291,9 +291,9 @@ CheckIndexCompatible(Oid oldId, * it will be filled later. * 'quiet': suppress the NOTICE chatter ordinarily provided for constraints. * - * Returns the OID of the created index. + * Returns the object address of the created index. */ -Oid +ObjectAddress DefineIndex(Oid relationId, IndexStmt *stmt, Oid indexRelationId, @@ -323,6 +323,7 @@ DefineIndex(Oid relationId, int numberOfAttributes; TransactionId limitXmin; VirtualTransactionId *old_snapshots; + ObjectAddress address; int n_old_snapshots; LockRelId heaprelid; LOCKTAG heaplocktag; @@ -613,10 +614,12 @@ DefineIndex(Oid relationId, stmt->concurrent, !check_rights, stmt->if_not_exists); + ObjectAddressSet(address, RelationRelationId, indexRelationId); + if (!OidIsValid(indexRelationId)) { heap_close(rel, NoLock); - return indexRelationId; + return address; } /* Add any requested comment */ @@ -628,7 +631,7 @@ DefineIndex(Oid relationId, { /* Close the heap and we're done, in the non-concurrent case */ heap_close(rel, NoLock); - return indexRelationId; + return address; } /* save lockrelid and locktag for below, then close rel */ @@ -873,7 +876,7 @@ DefineIndex(Oid relationId, */ UnlockRelationIdForSession(&heaprelid, ShareUpdateExclusiveLock); - return indexRelationId; + return address; } diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c index 92d90323284..eb16bb31ffc 100644 --- a/src/backend/commands/matview.c +++ b/src/backend/commands/matview.c @@ -134,7 +134,7 @@ SetMatViewPopulatedState(Relation relation, bool newstate) * The matview's "populated" state is changed based on whether the contents * reflect the result set of the materialized view's query. */ -Oid +ObjectAddress ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString, ParamListInfo params, char *completionTag) { @@ -153,6 +153,7 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString, Oid save_userid; int save_sec_context; int save_nestlevel; + ObjectAddress address; /* Determine strength of lock needed. */ concurrent = stmt->concurrent; @@ -311,7 +312,9 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString, /* Restore userid and security context */ SetUserIdAndSecContext(save_userid, save_sec_context); - return matviewOid; + ObjectAddressSet(address, RelationRelationId, matviewOid); + + return address; } /* diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c index 16f6f0503c9..c327cc0473e 100644 --- a/src/backend/commands/opclasscmds.c +++ b/src/backend/commands/opclasscmds.c @@ -246,7 +246,7 @@ get_opclass_oid(Oid amID, List *opclassname, bool missing_ok) * * Caller must have done permissions checks etc. already. */ -static Oid +static ObjectAddress CreateOpFamily(char *amname, char *opfname, Oid namespaceoid, Oid amoid) { Oid opfamilyoid; @@ -319,14 +319,14 @@ CreateOpFamily(char *amname, char *opfname, Oid namespaceoid, Oid amoid) heap_close(rel, RowExclusiveLock); - return opfamilyoid; + return myself; } /* * DefineOpClass * Define a new index operator class. */ -Oid +ObjectAddress DefineOpClass(CreateOpClassStmt *stmt) { char *opcname; /* name of opclass we're creating */ @@ -445,11 +445,14 @@ DefineOpClass(CreateOpClassStmt *stmt) } else { + ObjectAddress tmpAddr; + /* * Create it ... again no need for more permissions ... */ - opfamilyoid = CreateOpFamily(stmt->amname, opcname, - namespaceoid, amoid); + tmpAddr = CreateOpFamily(stmt->amname, opcname, + namespaceoid, amoid); + opfamilyoid = tmpAddr.objectId; } } @@ -719,7 +722,7 @@ DefineOpClass(CreateOpClassStmt *stmt) heap_close(rel, RowExclusiveLock); - return opclassoid; + return myself; } @@ -727,7 +730,7 @@ DefineOpClass(CreateOpClassStmt *stmt) * DefineOpFamily * Define a new index operator family. */ -Oid +ObjectAddress DefineOpFamily(CreateOpFamilyStmt *stmt) { char *opfname; /* name of opfamily we're creating */ diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c index 29960191c04..1efaacfd5e2 100644 --- a/src/backend/commands/operatorcmds.c +++ b/src/backend/commands/operatorcmds.c @@ -59,7 +59,7 @@ * * 'parameters' is a list of DefElem */ -Oid +ObjectAddress DefineOperator(List *names, List *parameters) { char *oprName; diff --git a/src/backend/commands/policy.c b/src/backend/commands/policy.c index d98da0dd506..e86299781f9 100644 --- a/src/backend/commands/policy.c +++ b/src/backend/commands/policy.c @@ -460,7 +460,7 @@ RemovePolicyById(Oid policy_id) * * stmt - the CreatePolicyStmt that describes the policy to create. */ -Oid +ObjectAddress CreatePolicy(CreatePolicyStmt *stmt) { Relation pg_policy_rel; @@ -626,7 +626,7 @@ CreatePolicy(CreatePolicyStmt *stmt) relation_close(target_table, NoLock); heap_close(pg_policy_rel, RowExclusiveLock); - return policy_id; + return myself; } /* @@ -635,7 +635,7 @@ CreatePolicy(CreatePolicyStmt *stmt) * * stmt - the AlterPolicyStmt that describes the policy and how to alter it. */ -Oid +ObjectAddress AlterPolicy(AlterPolicyStmt *stmt) { Relation pg_policy_rel; @@ -830,14 +830,14 @@ AlterPolicy(AlterPolicyStmt *stmt) relation_close(target_table, NoLock); heap_close(pg_policy_rel, RowExclusiveLock); - return policy_id; + return myself; } /* * rename_policy - * change the name of a policy on a relation */ -Oid +ObjectAddress rename_policy(RenameStmt *stmt) { Relation pg_policy_rel; @@ -847,6 +847,7 @@ rename_policy(RenameStmt *stmt) ScanKeyData skey[2]; SysScanDesc sscan; HeapTuple policy_tuple; + ObjectAddress address; /* Get id of table. Also handles permissions checks. */ table_id = RangeVarGetRelidExtended(stmt->relation, AccessExclusiveLock, @@ -925,6 +926,8 @@ rename_policy(RenameStmt *stmt) InvokeObjectPostAlterHook(PolicyRelationId, HeapTupleGetOid(policy_tuple), 0); + ObjectAddressSet(address, PolicyRelationId, opoloid); + /* * Invalidate relation's relcache entry so that other backends (and * this one too!) are sent SI message to make them rebuild relcache @@ -937,7 +940,7 @@ rename_policy(RenameStmt *stmt) heap_close(pg_policy_rel, RowExclusiveLock); relation_close(target_table, NoLock); - return opoloid; + return address; } /* diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c index 07224616145..11e6213e80f 100644 --- a/src/backend/commands/proclang.c +++ b/src/backend/commands/proclang.c @@ -51,7 +51,7 @@ typedef struct char *tmpllibrary; /* path of shared library */ } PLTemplate; -static Oid create_proc_lang(const char *languageName, bool replace, +static ObjectAddress create_proc_lang(const char *languageName, bool replace, Oid languageOwner, Oid handlerOid, Oid inlineOid, Oid valOid, bool trusted); static PLTemplate *find_language_template(const char *languageName); @@ -60,10 +60,11 @@ static PLTemplate *find_language_template(const char *languageName); * CREATE PROCEDURAL LANGUAGE * --------------------------------------------------------------------- */ -Oid +ObjectAddress CreateProceduralLanguage(CreatePLangStmt *stmt) { PLTemplate *pltemplate; + ObjectAddress tmpAddr; Oid handlerOid, inlineOid, valOid; @@ -118,30 +119,31 @@ CreateProceduralLanguage(CreatePLangStmt *stmt) } else { - handlerOid = ProcedureCreate(pltemplate->tmplhandler, - PG_CATALOG_NAMESPACE, - false, /* replace */ - false, /* returnsSet */ - LANGUAGE_HANDLEROID, - BOOTSTRAP_SUPERUSERID, - ClanguageId, - F_FMGR_C_VALIDATOR, - pltemplate->tmplhandler, - pltemplate->tmpllibrary, - false, /* isAgg */ - false, /* isWindowFunc */ - false, /* security_definer */ - false, /* isLeakProof */ - false, /* isStrict */ - PROVOLATILE_VOLATILE, - buildoidvector(funcargtypes, 0), - PointerGetDatum(NULL), - PointerGetDatum(NULL), - PointerGetDatum(NULL), - NIL, - PointerGetDatum(NULL), - 1, - 0); + tmpAddr = ProcedureCreate(pltemplate->tmplhandler, + PG_CATALOG_NAMESPACE, + false, /* replace */ + false, /* returnsSet */ + LANGUAGE_HANDLEROID, + BOOTSTRAP_SUPERUSERID, + ClanguageId, + F_FMGR_C_VALIDATOR, + pltemplate->tmplhandler, + pltemplate->tmpllibrary, + false, /* isAgg */ + false, /* isWindowFunc */ + false, /* security_definer */ + false, /* isLeakProof */ + false, /* isStrict */ + PROVOLATILE_VOLATILE, + buildoidvector(funcargtypes, 0), + PointerGetDatum(NULL), + PointerGetDatum(NULL), + PointerGetDatum(NULL), + NIL, + PointerGetDatum(NULL), + 1, + 0); + handlerOid = tmpAddr.objectId; } /* @@ -155,30 +157,31 @@ CreateProceduralLanguage(CreatePLangStmt *stmt) inlineOid = LookupFuncName(funcname, 1, funcargtypes, true); if (!OidIsValid(inlineOid)) { - inlineOid = ProcedureCreate(pltemplate->tmplinline, - PG_CATALOG_NAMESPACE, - false, /* replace */ - false, /* returnsSet */ - VOIDOID, - BOOTSTRAP_SUPERUSERID, - ClanguageId, - F_FMGR_C_VALIDATOR, - pltemplate->tmplinline, - pltemplate->tmpllibrary, - false, /* isAgg */ - false, /* isWindowFunc */ - false, /* security_definer */ - false, /* isLeakProof */ - true, /* isStrict */ - PROVOLATILE_VOLATILE, - buildoidvector(funcargtypes, 1), - PointerGetDatum(NULL), - PointerGetDatum(NULL), - PointerGetDatum(NULL), - NIL, - PointerGetDatum(NULL), - 1, - 0); + tmpAddr = ProcedureCreate(pltemplate->tmplinline, + PG_CATALOG_NAMESPACE, + false, /* replace */ + false, /* returnsSet */ + VOIDOID, + BOOTSTRAP_SUPERUSERID, + ClanguageId, + F_FMGR_C_VALIDATOR, + pltemplate->tmplinline, + pltemplate->tmpllibrary, + false, /* isAgg */ + false, /* isWindowFunc */ + false, /* security_definer */ + false, /* isLeakProof */ + true, /* isStrict */ + PROVOLATILE_VOLATILE, + buildoidvector(funcargtypes, 1), + PointerGetDatum(NULL), + PointerGetDatum(NULL), + PointerGetDatum(NULL), + NIL, + PointerGetDatum(NULL), + 1, + 0); + inlineOid = tmpAddr.objectId; } } else @@ -195,30 +198,31 @@ CreateProceduralLanguage(CreatePLangStmt *stmt) valOid = LookupFuncName(funcname, 1, funcargtypes, true); if (!OidIsValid(valOid)) { - valOid = ProcedureCreate(pltemplate->tmplvalidator, - PG_CATALOG_NAMESPACE, - false, /* replace */ - false, /* returnsSet */ - VOIDOID, - BOOTSTRAP_SUPERUSERID, - ClanguageId, - F_FMGR_C_VALIDATOR, - pltemplate->tmplvalidator, - pltemplate->tmpllibrary, - false, /* isAgg */ - false, /* isWindowFunc */ - false, /* security_definer */ - false, /* isLeakProof */ - true, /* isStrict */ - PROVOLATILE_VOLATILE, - buildoidvector(funcargtypes, 1), - PointerGetDatum(NULL), - PointerGetDatum(NULL), - PointerGetDatum(NULL), - NIL, - PointerGetDatum(NULL), - 1, - 0); + tmpAddr = ProcedureCreate(pltemplate->tmplvalidator, + PG_CATALOG_NAMESPACE, + false, /* replace */ + false, /* returnsSet */ + VOIDOID, + BOOTSTRAP_SUPERUSERID, + ClanguageId, + F_FMGR_C_VALIDATOR, + pltemplate->tmplvalidator, + pltemplate->tmpllibrary, + false, /* isAgg */ + false, /* isWindowFunc */ + false, /* security_definer */ + false, /* isLeakProof */ + true, /* isStrict */ + PROVOLATILE_VOLATILE, + buildoidvector(funcargtypes, 1), + PointerGetDatum(NULL), + PointerGetDatum(NULL), + PointerGetDatum(NULL), + NIL, + PointerGetDatum(NULL), + 1, + 0); + valOid = tmpAddr.objectId; } } else @@ -309,7 +313,7 @@ CreateProceduralLanguage(CreatePLangStmt *stmt) /* * Guts of language creation. */ -static Oid +static ObjectAddress create_proc_lang(const char *languageName, bool replace, Oid languageOwner, Oid handlerOid, Oid inlineOid, Oid valOid, bool trusted) @@ -433,7 +437,7 @@ create_proc_lang(const char *languageName, bool replace, heap_close(rel, RowExclusiveLock); - return myself.objectId; + return myself; } /* diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c index a44dbf453e4..722142e16ea 100644 --- a/src/backend/commands/schemacmds.c +++ b/src/backend/commands/schemacmds.c @@ -195,13 +195,14 @@ RemoveSchemaById(Oid schemaOid) /* * Rename schema */ -Oid +ObjectAddress RenameSchema(const char *oldname, const char *newname) { Oid nspOid; HeapTuple tup; Relation rel; AclResult aclresult; + ObjectAddress address; rel = heap_open(NamespaceRelationId, RowExclusiveLock); @@ -243,10 +244,12 @@ RenameSchema(const char *oldname, const char *newname) InvokeObjectPostAlterHook(NamespaceRelationId, HeapTupleGetOid(tup), 0); + ObjectAddressSet(address, NamespaceRelationId, nspOid); + heap_close(rel, NoLock); heap_freetuple(tup); - return nspOid; + return address; } void @@ -272,12 +275,13 @@ AlterSchemaOwner_oid(Oid oid, Oid newOwnerId) /* * Change schema owner */ -Oid +ObjectAddress AlterSchemaOwner(const char *name, Oid newOwnerId) { Oid nspOid; HeapTuple tup; Relation rel; + ObjectAddress address; rel = heap_open(NamespaceRelationId, RowExclusiveLock); @@ -291,11 +295,13 @@ AlterSchemaOwner(const char *name, Oid newOwnerId) AlterSchemaOwner_internal(tup, rel, newOwnerId); + ObjectAddressSet(address, NamespaceRelationId, nspOid); + ReleaseSysCache(tup); heap_close(rel, RowExclusiveLock); - return nspOid; + return address; } static void diff --git a/src/backend/commands/seclabel.c b/src/backend/commands/seclabel.c index 6e15bc8de7b..1ef98ce3532 100644 --- a/src/backend/commands/seclabel.c +++ b/src/backend/commands/seclabel.c @@ -37,8 +37,10 @@ static List *label_provider_list = NIL; * ExecSecLabelStmt -- * * Apply a security label to a database object. + * + * Returns the ObjectAddress of the object to which the policy was applied. */ -Oid +ObjectAddress ExecSecLabelStmt(SecLabelStmt *stmt) { LabelProvider *provider = NULL; @@ -133,7 +135,7 @@ ExecSecLabelStmt(SecLabelStmt *stmt) if (relation != NULL) relation_close(relation, NoLock); - return address.objectId; + return address; } /* diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index 0070c4f34ef..6d316d62b6c 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -104,13 +104,14 @@ static void process_owned_by(Relation seqrel, List *owned_by); * DefineSequence * Creates a new sequence relation */ -Oid +ObjectAddress DefineSequence(CreateSeqStmt *seq) { FormData_pg_sequence new; List *owned_by; CreateStmt *stmt = makeNode(CreateStmt); Oid seqoid; + ObjectAddress address; Relation rel; HeapTuple tuple; TupleDesc tupDesc; @@ -139,7 +140,7 @@ DefineSequence(CreateSeqStmt *seq) (errcode(ERRCODE_DUPLICATE_TABLE), errmsg("relation \"%s\" already exists, skipping", seq->sequence->relname))); - return InvalidOid; + return InvalidObjectAddress; } } @@ -233,7 +234,8 @@ DefineSequence(CreateSeqStmt *seq) stmt->tablespacename = NULL; stmt->if_not_exists = seq->if_not_exists; - seqoid = DefineRelation(stmt, RELKIND_SEQUENCE, seq->ownerId); + address = DefineRelation(stmt, RELKIND_SEQUENCE, seq->ownerId, NULL); + seqoid = address.objectId; Assert(seqoid != InvalidOid); rel = heap_open(seqoid, AccessExclusiveLock); @@ -249,7 +251,7 @@ DefineSequence(CreateSeqStmt *seq) heap_close(rel, NoLock); - return seqoid; + return address; } /* @@ -401,7 +403,7 @@ fill_seq_with_data(Relation rel, HeapTuple tuple) * * Modify the definition of a sequence relation */ -Oid +ObjectAddress AlterSequence(AlterSeqStmt *stmt) { Oid relid; @@ -412,6 +414,7 @@ AlterSequence(AlterSeqStmt *stmt) Form_pg_sequence seq; FormData_pg_sequence new; List *owned_by; + ObjectAddress address; /* Open and lock sequence. */ relid = RangeVarGetRelid(stmt->sequence, AccessShareLock, stmt->missing_ok); @@ -420,7 +423,7 @@ AlterSequence(AlterSeqStmt *stmt) ereport(NOTICE, (errmsg("relation \"%s\" does not exist, skipping", stmt->sequence->relname))); - return InvalidOid; + return InvalidObjectAddress; } init_sequence(relid, &elm, &seqrel); @@ -484,9 +487,11 @@ AlterSequence(AlterSeqStmt *stmt) InvokeObjectPostAlterHook(RelationRelationId, relid, 0); + ObjectAddressSet(address, RelationRelationId, relid); + relation_close(seqrel, NoLock); - return relid; + return address; } diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 745502072e6..653677892de 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -435,17 +435,19 @@ static void RangeVarCallbackForAlterRelation(const RangeVar *rv, Oid relid, * The other arguments are used to extend the behavior for other cases: * relkind: relkind to assign to the new relation * ownerId: if not InvalidOid, use this as the new relation's owner. + * typaddress: if not null, it's set to the pg_type entry's address. * * Note that permissions checks are done against current user regardless of * ownerId. A nonzero ownerId is used when someone is creating a relation * "on behalf of" someone else, so we still want to see that the current user * has permissions to do it. * - * If successful, returns the OID of the new relation. + * If successful, returns the address of the new relation. * ---------------------------------------------------------------- */ -Oid -DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId) +ObjectAddress +DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, + ObjectAddress *typaddress) { char relname[NAMEDATALEN]; Oid namespaceId; @@ -465,6 +467,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId) AttrNumber attnum; static char *validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; + ObjectAddress address; /* * Truncate relname to appropriate length (probably a waste of time, as @@ -657,7 +660,8 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId) reloptions, true, allowSystemTableMods, - false); + false, + typaddress); /* Store inheritance information for new rel. */ StoreCatalogInheritance(relationId, inheritOids); @@ -689,13 +693,15 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId) AddRelationNewConstraints(rel, rawDefaults, stmt->constraints, true, true, false); + ObjectAddressSet(address, RelationRelationId, relationId); + /* * Clean up. We keep lock on new relation (although it shouldn't be * visible to anyone else anyway, until commit). */ relation_close(rel, NoLock); - return relationId; + return address; } /* @@ -2158,8 +2164,10 @@ renameatt_check(Oid myrelid, Form_pg_class classform, bool recursing) /* * renameatt_internal - workhorse for renameatt + * + * Return value is the attribute number in the 'myrelid' relation. */ -static void +static AttrNumber renameatt_internal(Oid myrelid, const char *oldattname, const char *newattname, @@ -2172,7 +2180,7 @@ renameatt_internal(Oid myrelid, Relation attrelation; HeapTuple atttup; Form_pg_attribute attform; - int attnum; + AttrNumber attnum; /* * Grab an exclusive lock on the target table, which we will NOT release @@ -2300,6 +2308,8 @@ renameatt_internal(Oid myrelid, heap_close(attrelation, RowExclusiveLock); relation_close(targetrelation, NoLock); /* close rel but keep lock */ + + return attnum; } /* @@ -2322,11 +2332,15 @@ RangeVarCallbackForRenameAttribute(const RangeVar *rv, Oid relid, Oid oldrelid, /* * renameatt - changes the name of a attribute in a relation + * + * The returned ObjectAddress is that of the renamed column. */ -Oid +ObjectAddress renameatt(RenameStmt *stmt) { Oid relid; + AttrNumber attnum; + ObjectAddress address; /* lock level taken here should match renameatt_internal */ relid = RangeVarGetRelidExtended(stmt->relation, AccessExclusiveLock, @@ -2339,26 +2353,27 @@ renameatt(RenameStmt *stmt) ereport(NOTICE, (errmsg("relation \"%s\" does not exist, skipping", stmt->relation->relname))); - return InvalidOid; + return InvalidObjectAddress; } - renameatt_internal(relid, - stmt->subname, /* old att name */ - stmt->newname, /* new att name */ - interpretInhOption(stmt->relation->inhOpt), /* recursive? */ - false, /* recursing? */ - 0, /* expected inhcount */ - stmt->behavior); + attnum = + renameatt_internal(relid, + stmt->subname, /* old att name */ + stmt->newname, /* new att name */ + interpretInhOption(stmt->relation->inhOpt), /* recursive? */ + false, /* recursing? */ + 0, /* expected inhcount */ + stmt->behavior); - /* This is an ALTER TABLE command so it's about the relid */ - return relid; -} + ObjectAddressSubSet(address, RelationRelationId, relid, attnum); + return address; +} /* * same logic as renameatt_internal */ -static Oid +static ObjectAddress rename_constraint_internal(Oid myrelid, Oid mytypid, const char *oldconname, @@ -2371,6 +2386,7 @@ rename_constraint_internal(Oid myrelid, Oid constraintOid; HeapTuple tuple; Form_pg_constraint con; + ObjectAddress address; AssertArg(!myrelid || !mytypid); @@ -2446,15 +2462,17 @@ rename_constraint_internal(Oid myrelid, else RenameConstraintById(constraintOid, newconname); + ObjectAddressSet(address, ConstraintRelationId, constraintOid); + ReleaseSysCache(tuple); if (targetrelation) relation_close(targetrelation, NoLock); /* close rel but keep lock */ - return constraintOid; + return address; } -Oid +ObjectAddress RenameConstraint(RenameStmt *stmt) { Oid relid = InvalidOid; @@ -2497,10 +2515,11 @@ RenameConstraint(RenameStmt *stmt) * Execute ALTER TABLE/INDEX/SEQUENCE/VIEW/MATERIALIZED VIEW/FOREIGN TABLE * RENAME */ -Oid +ObjectAddress RenameRelation(RenameStmt *stmt) { Oid relid; + ObjectAddress address; /* * Grab an exclusive lock on the target table, index, sequence, view, @@ -2520,13 +2539,15 @@ RenameRelation(RenameStmt *stmt) ereport(NOTICE, (errmsg("relation \"%s\" does not exist, skipping", stmt->relation->relname))); - return InvalidOid; + return InvalidObjectAddress; } /* Do the work */ RenameRelationInternal(relid, stmt->newname, false); - return relid; + ObjectAddressSet(address, RelationRelationId, relid); + + return address; } /* @@ -5702,7 +5723,7 @@ ATExecAddIndex(AlteredTableInfo *tab, Relation rel, bool check_rights; bool skip_build; bool quiet; - Oid new_index; + ObjectAddress address; Assert(IsA(stmt, IndexStmt)); Assert(!stmt->concurrent); @@ -5717,13 +5738,13 @@ ATExecAddIndex(AlteredTableInfo *tab, Relation rel, /* suppress notices when rebuilding existing index */ quiet = is_rebuild; - new_index = DefineIndex(RelationGetRelid(rel), - stmt, - InvalidOid, /* no predefined OID */ - true, /* is_alter_table */ - check_rights, - skip_build, - quiet); + address = DefineIndex(RelationGetRelid(rel), + stmt, + InvalidOid, /* no predefined OID */ + true, /* is_alter_table */ + check_rights, + skip_build, + quiet); /* * If TryReuseIndex() stashed a relfilenode for us, we used it for the new @@ -5733,7 +5754,7 @@ ATExecAddIndex(AlteredTableInfo *tab, Relation rel, */ if (OidIsValid(stmt->oldNode)) { - Relation irel = index_open(new_index, NoLock); + Relation irel = index_open(address.objectId, NoLock); RelationPreserveStorage(irel->rd_node, true); index_close(irel, NoLock); @@ -10919,8 +10940,8 @@ ATPrepChangePersistence(Relation rel, bool toLogged) /* * Execute ALTER TABLE SET SCHEMA */ -Oid -AlterTableNamespace(AlterObjectSchemaStmt *stmt) +ObjectAddress +AlterTableNamespace(AlterObjectSchemaStmt *stmt, Oid *oldschema) { Relation rel; Oid relid; @@ -10928,6 +10949,7 @@ AlterTableNamespace(AlterObjectSchemaStmt *stmt) Oid nspOid; RangeVar *newrv; ObjectAddresses *objsMoved; + ObjectAddress myself; relid = RangeVarGetRelidExtended(stmt->relation, AccessExclusiveLock, stmt->missing_ok, false, @@ -10939,7 +10961,7 @@ AlterTableNamespace(AlterObjectSchemaStmt *stmt) ereport(NOTICE, (errmsg("relation \"%s\" does not exist, skipping", stmt->relation->relname))); - return InvalidOid; + return InvalidObjectAddress; } rel = relation_open(relid, NoLock); @@ -10972,10 +10994,15 @@ AlterTableNamespace(AlterObjectSchemaStmt *stmt) AlterTableNamespaceInternal(rel, oldNspOid, nspOid, objsMoved); free_object_addresses(objsMoved); + ObjectAddressSet(myself, RelationRelationId, relid); + + if (oldschema) + *oldschema = oldNspOid; + /* close rel, but keep lock until commit */ relation_close(rel, NoLock); - return relid; + return myself; } /* diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c index 03cc8fe8d80..68b6917df5d 100644 --- a/src/backend/commands/tablespace.c +++ b/src/backend/commands/tablespace.c @@ -846,7 +846,7 @@ directory_is_empty(const char *path) /* * Rename a tablespace */ -Oid +ObjectAddress RenameTableSpace(const char *oldname, const char *newname) { Oid tspId; @@ -856,6 +856,7 @@ RenameTableSpace(const char *oldname, const char *newname) HeapTuple tup; HeapTuple newtuple; Form_pg_tablespace newform; + ObjectAddress address; /* Search pg_tablespace */ rel = heap_open(TableSpaceRelationId, RowExclusiveLock); @@ -912,9 +913,11 @@ RenameTableSpace(const char *oldname, const char *newname) InvokeObjectPostAlterHook(TableSpaceRelationId, tspId, 0); + ObjectAddressSet(address, TableSpaceRelationId, tspId); + heap_close(rel, NoLock); - return tspId; + return address; } /* diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index a84e86ef805..e491c5ba772 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -100,7 +100,7 @@ static void AfterTriggerEnlargeQueryState(void); /* - * Create a trigger. Returns the OID of the created trigger. + * Create a trigger. Returns the address of the created trigger. * * queryString is the source text of the CREATE TRIGGER command. * This must be supplied if a whenClause is specified, else it can be NULL. @@ -129,10 +129,11 @@ static void AfterTriggerEnlargeQueryState(void); * relation, as well as ACL_EXECUTE on the trigger function. For internal * triggers the caller must apply any required permission checks. * - * Note: can return InvalidOid if we decided to not create a trigger at all, - * but a foreign-key constraint. This is a kluge for backwards compatibility. + * Note: can return InvalidObjectAddress if we decided to not create a trigger + * at all, but a foreign-key constraint. This is a kluge for backwards + * compatibility. */ -Oid +ObjectAddress CreateTrigger(CreateTrigStmt *stmt, const char *queryString, Oid relOid, Oid refRelOid, Oid constraintOid, Oid indexOid, bool isInternal) @@ -459,7 +460,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, ConvertTriggerToFK(stmt, funcoid); - return InvalidOid; + return InvalidObjectAddress; } /* @@ -799,7 +800,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, /* Keep lock on target rel until end of xact */ heap_close(rel, NoLock); - return trigoid; + return myself; } @@ -1249,7 +1250,7 @@ RangeVarCallbackForRenameTrigger(const RangeVar *rv, Oid relid, Oid oldrelid, * modify tgname in trigger tuple * update row in catalog */ -Oid +ObjectAddress renametrig(RenameStmt *stmt) { Oid tgoid; @@ -1259,6 +1260,7 @@ renametrig(RenameStmt *stmt) SysScanDesc tgscan; ScanKeyData key[2]; Oid relid; + ObjectAddress address; /* * Look up name, check permissions, and acquire lock (which we will NOT @@ -1351,6 +1353,8 @@ renametrig(RenameStmt *stmt) stmt->subname, RelationGetRelationName(targetrel)))); } + ObjectAddressSet(address, TriggerRelationId, tgoid); + systable_endscan(tgscan); heap_close(tgrel, RowExclusiveLock); @@ -1360,7 +1364,7 @@ renametrig(RenameStmt *stmt) */ relation_close(targetrel, NoLock); - return tgoid; + return address; } diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c index c6f89941e82..45bafd31707 100644 --- a/src/backend/commands/tsearchcmds.c +++ b/src/backend/commands/tsearchcmds.c @@ -120,8 +120,10 @@ get_ts_parser_func(DefElem *defel, int attnum) /* * make pg_depend entries for a new pg_ts_parser entry + * + * Return value is the address of said new entry. */ -static void +static ObjectAddress makeParserDependencies(HeapTuple tuple) { Form_pg_ts_parser prs = (Form_pg_ts_parser) GETSTRUCT(tuple); @@ -162,12 +164,14 @@ makeParserDependencies(HeapTuple tuple) referenced.objectId = prs->prsheadline; recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } + + return myself; } /* * CREATE TEXT SEARCH PARSER */ -Oid +ObjectAddress DefineTSParser(List *names, List *parameters) { char *prsname; @@ -179,6 +183,7 @@ DefineTSParser(List *names, List *parameters) NameData pname; Oid prsOid; Oid namespaceoid; + ObjectAddress address; if (!superuser()) ereport(ERROR, @@ -269,7 +274,7 @@ DefineTSParser(List *names, List *parameters) CatalogUpdateIndexes(prsRel, tup); - makeParserDependencies(tup); + address = makeParserDependencies(tup); /* Post creation hook for new text search parser */ InvokeObjectPostCreateHook(TSParserRelationId, prsOid, 0); @@ -278,7 +283,7 @@ DefineTSParser(List *names, List *parameters) heap_close(prsRel, RowExclusiveLock); - return prsOid; + return address; } /* @@ -308,8 +313,10 @@ RemoveTSParserById(Oid prsId) /* * make pg_depend entries for a new pg_ts_dict entry + * + * Return value is address of the new entry */ -static void +static ObjectAddress makeDictionaryDependencies(HeapTuple tuple) { Form_pg_ts_dict dict = (Form_pg_ts_dict) GETSTRUCT(tuple); @@ -337,6 +344,8 @@ makeDictionaryDependencies(HeapTuple tuple) referenced.objectId = dict->dicttemplate; referenced.objectSubId = 0; recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + + return myself; } /* @@ -397,7 +406,7 @@ verify_dictoptions(Oid tmplId, List *dictoptions) /* * CREATE TEXT SEARCH DICTIONARY */ -Oid +ObjectAddress DefineTSDictionary(List *names, List *parameters) { ListCell *pl; @@ -412,6 +421,7 @@ DefineTSDictionary(List *names, List *parameters) Oid namespaceoid; AclResult aclresult; char *dictname; + ObjectAddress address; /* Convert list of names to a name and namespace */ namespaceoid = QualifiedNameGetCreationNamespace(names, &dictname); @@ -475,7 +485,7 @@ DefineTSDictionary(List *names, List *parameters) CatalogUpdateIndexes(dictRel, tup); - makeDictionaryDependencies(tup); + address = makeDictionaryDependencies(tup); /* Post creation hook for new text search dictionary */ InvokeObjectPostCreateHook(TSDictionaryRelationId, dictOid, 0); @@ -484,7 +494,7 @@ DefineTSDictionary(List *names, List *parameters) heap_close(dictRel, RowExclusiveLock); - return dictOid; + return address; } /* @@ -514,7 +524,7 @@ RemoveTSDictionaryById(Oid dictId) /* * ALTER TEXT SEARCH DICTIONARY */ -Oid +ObjectAddress AlterTSDictionary(AlterTSDictionaryStmt *stmt) { HeapTuple tup, @@ -528,6 +538,7 @@ AlterTSDictionary(AlterTSDictionaryStmt *stmt) Datum repl_val[Natts_pg_ts_dict]; bool repl_null[Natts_pg_ts_dict]; bool repl_repl[Natts_pg_ts_dict]; + ObjectAddress address; dictId = get_ts_dict_oid(stmt->dictname, false); @@ -614,6 +625,8 @@ AlterTSDictionary(AlterTSDictionaryStmt *stmt) InvokeObjectPostAlterHook(TSDictionaryRelationId, dictId, 0); + ObjectAddressSet(address, TSDictionaryRelationId, dictId); + /* * NOTE: because we only support altering the options, not the template, * there is no need to update dependencies. This might have to change if @@ -625,7 +638,7 @@ AlterTSDictionary(AlterTSDictionaryStmt *stmt) heap_close(rel, RowExclusiveLock); - return dictId; + return address; } /* ---------------------- TS Template commands -----------------------*/ @@ -678,7 +691,7 @@ get_ts_template_func(DefElem *defel, int attnum) /* * make pg_depend entries for a new pg_ts_template entry */ -static void +static ObjectAddress makeTSTemplateDependencies(HeapTuple tuple) { Form_pg_ts_template tmpl = (Form_pg_ts_template) GETSTRUCT(tuple); @@ -710,12 +723,14 @@ makeTSTemplateDependencies(HeapTuple tuple) referenced.objectId = tmpl->tmplinit; recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } + + return myself; } /* * CREATE TEXT SEARCH TEMPLATE */ -Oid +ObjectAddress DefineTSTemplate(List *names, List *parameters) { ListCell *pl; @@ -728,6 +743,7 @@ DefineTSTemplate(List *names, List *parameters) Oid tmplOid; Oid namespaceoid; char *tmplname; + ObjectAddress address; if (!superuser()) ereport(ERROR, @@ -793,7 +809,7 @@ DefineTSTemplate(List *names, List *parameters) CatalogUpdateIndexes(tmplRel, tup); - makeTSTemplateDependencies(tup); + address = makeTSTemplateDependencies(tup); /* Post creation hook for new text search template */ InvokeObjectPostCreateHook(TSTemplateRelationId, tmplOid, 0); @@ -802,7 +818,7 @@ DefineTSTemplate(List *names, List *parameters) heap_close(tmplRel, RowExclusiveLock); - return tmplOid; + return address; } /* @@ -860,7 +876,7 @@ GetTSConfigTuple(List *names) * Pass opened pg_ts_config_map relation if there might be any config map * entries for the config. */ -static void +static ObjectAddress makeConfigurationDependencies(HeapTuple tuple, bool removeOld, Relation mapRel) { @@ -940,12 +956,14 @@ makeConfigurationDependencies(HeapTuple tuple, bool removeOld, record_object_address_dependencies(&myself, addrs, DEPENDENCY_NORMAL); free_object_addresses(addrs); + + return myself; } /* * CREATE TEXT SEARCH CONFIGURATION */ -Oid +ObjectAddress DefineTSConfiguration(List *names, List *parameters) { Relation cfgRel; @@ -961,6 +979,7 @@ DefineTSConfiguration(List *names, List *parameters) Oid prsOid = InvalidOid; Oid cfgOid; ListCell *pl; + ObjectAddress address; /* Convert list of names to a name and namespace */ namespaceoid = QualifiedNameGetCreationNamespace(names, &cfgname); @@ -1088,7 +1107,7 @@ DefineTSConfiguration(List *names, List *parameters) systable_endscan(scan); } - makeConfigurationDependencies(tup, false, mapRel); + address = makeConfigurationDependencies(tup, false, mapRel); /* Post creation hook for new text search configuration */ InvokeObjectPostCreateHook(TSConfigRelationId, cfgOid, 0); @@ -1099,7 +1118,7 @@ DefineTSConfiguration(List *names, List *parameters) heap_close(mapRel, RowExclusiveLock); heap_close(cfgRel, RowExclusiveLock); - return cfgOid; + return address; } /* @@ -1153,12 +1172,13 @@ RemoveTSConfigurationById(Oid cfgId) /* * ALTER TEXT SEARCH CONFIGURATION - main entry point */ -Oid +ObjectAddress AlterTSConfiguration(AlterTSConfigurationStmt *stmt) { HeapTuple tup; Oid cfgId; Relation relMap; + ObjectAddress address; /* Find the configuration */ tup = GetTSConfigTuple(stmt->cfgname); @@ -1189,11 +1209,13 @@ AlterTSConfiguration(AlterTSConfigurationStmt *stmt) InvokeObjectPostAlterHook(TSConfigMapRelationId, HeapTupleGetOid(tup), 0); + ObjectAddressSet(address, TSConfigMapRelationId, cfgId); + heap_close(relMap, RowExclusiveLock); ReleaseSysCache(tup); - return cfgId; + return address; } /* diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index 60ab3aaf12f..67e2ae22c68 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -101,14 +101,14 @@ static void checkEnumOwner(HeapTuple tup); static char *domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid, int typMod, Constraint *constr, - char *domainName); + char *domainName, ObjectAddress *constrAddr); /* * DefineType * Registers a new base type. */ -Oid +ObjectAddress DefineType(List *names, List *parameters) { char *typeName; @@ -160,6 +160,7 @@ DefineType(List *names, List *parameters) Oid typoid; Oid resulttype; ListCell *pl; + ObjectAddress address; /* * As of Postgres 8.4, we require superuser privilege to create a base @@ -213,7 +214,7 @@ DefineType(List *names, List *parameters) */ if (!OidIsValid(typoid)) { - typoid = TypeShellMake(typeName, typeNamespace, GetUserId()); + address = TypeShellMake(typeName, typeNamespace, GetUserId()); /* Make new shell type visible for modification below */ CommandCounterIncrement(); @@ -222,7 +223,7 @@ DefineType(List *names, List *parameters) * creating the shell type was all we're supposed to do. */ if (parameters == NIL) - return InvalidOid; + return address; } else { @@ -595,7 +596,7 @@ DefineType(List *names, List *parameters) * types) in ArrayType and in composite types in DatumTupleFields. This * oid must be preserved by binary upgrades. */ - typoid = + address = TypeCreate(InvalidOid, /* no predetermined type OID */ typeName, /* type name */ typeNamespace, /* namespace */ @@ -670,7 +671,7 @@ DefineType(List *names, List *parameters) pfree(array_type); - return typoid; + return address; } /* @@ -716,7 +717,7 @@ RemoveTypeById(Oid typeOid) * DefineDomain * Registers a new domain. */ -Oid +ObjectAddress DefineDomain(CreateDomainStmt *stmt) { char *domainName; @@ -746,12 +747,12 @@ DefineDomain(CreateDomainStmt *stmt) List *schema = stmt->constraints; ListCell *listptr; Oid basetypeoid; - Oid domainoid; Oid old_type_oid; Oid domaincoll; Form_pg_type baseType; int32 basetypeMod; Oid baseColl; + ObjectAddress address; /* Convert list of names to a name and namespace */ domainNamespace = QualifiedNameGetCreationNamespace(stmt->domainname, @@ -1021,7 +1022,7 @@ DefineDomain(CreateDomainStmt *stmt) /* * Have TypeCreate do all the real work. */ - domainoid = + address = TypeCreate(InvalidOid, /* no predetermined type OID */ domainName, /* type name */ domainNamespace, /* namespace */ @@ -1066,9 +1067,9 @@ DefineDomain(CreateDomainStmt *stmt) switch (constr->contype) { case CONSTR_CHECK: - domainAddConstraint(domainoid, domainNamespace, + domainAddConstraint(address.objectId, domainNamespace, basetypeoid, basetypeMod, - constr, domainName); + constr, domainName, NULL); break; /* Other constraint types were fully processed above */ @@ -1086,7 +1087,7 @@ DefineDomain(CreateDomainStmt *stmt) */ ReleaseSysCache(typeTup); - return domainoid; + return address; } @@ -1094,16 +1095,16 @@ DefineDomain(CreateDomainStmt *stmt) * DefineEnum * Registers a new enum. */ -Oid +ObjectAddress DefineEnum(CreateEnumStmt *stmt) { char *enumName; char *enumArrayName; Oid enumNamespace; - Oid enumTypeOid; AclResult aclresult; Oid old_type_oid; Oid enumArrayOid; + ObjectAddress enumTypeAddr; /* Convert list of names to a name and namespace */ enumNamespace = QualifiedNameGetCreationNamespace(stmt->typeName, @@ -1133,7 +1134,7 @@ DefineEnum(CreateEnumStmt *stmt) enumArrayOid = AssignTypeArrayOid(); /* Create the pg_type entry */ - enumTypeOid = + enumTypeAddr = TypeCreate(InvalidOid, /* no predetermined type OID */ enumName, /* type name */ enumNamespace, /* namespace */ @@ -1167,7 +1168,7 @@ DefineEnum(CreateEnumStmt *stmt) InvalidOid); /* type's collation */ /* Enter the enum's values into pg_enum */ - EnumValuesCreate(enumTypeOid, stmt->vals); + EnumValuesCreate(enumTypeAddr.objectId, stmt->vals); /* * Create the array type that goes with it. @@ -1192,7 +1193,7 @@ DefineEnum(CreateEnumStmt *stmt) InvalidOid, /* typmodin procedure - none */ InvalidOid, /* typmodout procedure - none */ F_ARRAY_TYPANALYZE, /* analyze procedure */ - enumTypeOid, /* element type ID */ + enumTypeAddr.objectId, /* element type ID */ true, /* yes this is an array type */ InvalidOid, /* no further array type */ InvalidOid, /* base type ID */ @@ -1208,19 +1209,20 @@ DefineEnum(CreateEnumStmt *stmt) pfree(enumArrayName); - return enumTypeOid; + return enumTypeAddr; } /* * AlterEnum * Adds a new label to an existing enum. */ -Oid +ObjectAddress AlterEnum(AlterEnumStmt *stmt, bool isTopLevel) { Oid enum_type_oid; TypeName *typename; HeapTuple tup; + ObjectAddress address; /* Make a TypeName so we can use standard type lookup machinery */ typename = makeTypeNameFromNameList(stmt->typeName); @@ -1259,9 +1261,11 @@ AlterEnum(AlterEnumStmt *stmt, bool isTopLevel) InvokeObjectPostAlterHook(TypeRelationId, enum_type_oid, 0); + ObjectAddressSet(address, TypeRelationId, enum_type_oid); + ReleaseSysCache(tup); - return enum_type_oid; + return address; } @@ -1293,7 +1297,7 @@ checkEnumOwner(HeapTuple tup) * DefineRange * Registers a new range type. */ -Oid +ObjectAddress DefineRange(CreateRangeStmt *stmt) { char *typeName; @@ -1316,6 +1320,7 @@ DefineRange(CreateRangeStmt *stmt) char alignment; AclResult aclresult; ListCell *lc; + ObjectAddress address; /* Convert list of names to a name and namespace */ typeNamespace = QualifiedNameGetCreationNamespace(stmt->typeName, @@ -1354,7 +1359,8 @@ DefineRange(CreateRangeStmt *stmt) */ if (!OidIsValid(typoid)) { - typoid = TypeShellMake(typeName, typeNamespace, GetUserId()); + address = TypeShellMake(typeName, typeNamespace, GetUserId()); + typoid = address.objectId; /* Make new shell type visible for modification below */ CommandCounterIncrement(); } @@ -1467,7 +1473,7 @@ DefineRange(CreateRangeStmt *stmt) rangeArrayOid = AssignTypeArrayOid(); /* Create the pg_type entry */ - typoid = + address = TypeCreate(InvalidOid, /* no predetermined type OID */ typeName, /* type name */ typeNamespace, /* namespace */ @@ -1499,6 +1505,7 @@ DefineRange(CreateRangeStmt *stmt) 0, /* Array dimensions of typbasetype */ false, /* Type NOT NULL */ InvalidOid); /* type's collation (ranges never have one) */ + typoid = address.objectId; /* Create the entry in pg_range */ RangeCreate(typoid, rangeSubtype, rangeCollation, rangeSubOpclass, @@ -1546,7 +1553,7 @@ DefineRange(CreateRangeStmt *stmt) /* And create the constructor functions for this range type */ makeRangeConstructors(typeName, typeNamespace, typoid, rangeSubtype); - return typoid; + return address; } /* @@ -1582,45 +1589,40 @@ makeRangeConstructors(const char *name, Oid namespace, for (i = 0; i < lengthof(prosrc); i++) { oidvector *constructorArgTypesVector; - Oid procOid; constructorArgTypesVector = buildoidvector(constructorArgTypes, pronargs[i]); - procOid = ProcedureCreate(name, /* name: same as range type */ - namespace, /* namespace */ - false, /* replace */ - false, /* returns set */ - rangeOid, /* return type */ - BOOTSTRAP_SUPERUSERID, /* proowner */ - INTERNALlanguageId, /* language */ - F_FMGR_INTERNAL_VALIDATOR, /* language validator */ - prosrc[i], /* prosrc */ - NULL, /* probin */ - false, /* isAgg */ - false, /* isWindowFunc */ - false, /* security_definer */ - false, /* leakproof */ - false, /* isStrict */ - PROVOLATILE_IMMUTABLE, /* volatility */ - constructorArgTypesVector, /* parameterTypes */ - PointerGetDatum(NULL), /* allParameterTypes */ - PointerGetDatum(NULL), /* parameterModes */ - PointerGetDatum(NULL), /* parameterNames */ - NIL, /* parameterDefaults */ - PointerGetDatum(NULL), /* proconfig */ - 1.0, /* procost */ - 0.0); /* prorows */ + myself = ProcedureCreate(name, /* name: same as range type */ + namespace, /* namespace */ + false, /* replace */ + false, /* returns set */ + rangeOid, /* return type */ + BOOTSTRAP_SUPERUSERID, /* proowner */ + INTERNALlanguageId, /* language */ + F_FMGR_INTERNAL_VALIDATOR, /* language validator */ + prosrc[i], /* prosrc */ + NULL, /* probin */ + false, /* isAgg */ + false, /* isWindowFunc */ + false, /* security_definer */ + false, /* leakproof */ + false, /* isStrict */ + PROVOLATILE_IMMUTABLE, /* volatility */ + constructorArgTypesVector, /* parameterTypes */ + PointerGetDatum(NULL), /* allParameterTypes */ + PointerGetDatum(NULL), /* parameterModes */ + PointerGetDatum(NULL), /* parameterNames */ + NIL, /* parameterDefaults */ + PointerGetDatum(NULL), /* proconfig */ + 1.0, /* procost */ + 0.0); /* prorows */ /* * Make the constructors internally-dependent on the range type so * that they go away silently when the type is dropped. Note that * pg_dump depends on this choice to avoid dumping the constructors. */ - myself.classId = ProcedureRelationId; - myself.objectId = procOid; - myself.objectSubId = 0; - recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL); } } @@ -2059,17 +2061,16 @@ AssignTypeArrayOid(void) * If the relation already exists, then 'DefineRelation' will abort * the xact... * - * DefineCompositeType returns relid for use when creating - * an implicit composite type during function creation + * Return type is the new type's object address. *------------------------------------------------------------------- */ -Oid +ObjectAddress DefineCompositeType(RangeVar *typevar, List *coldeflist) { CreateStmt *createStmt = makeNode(CreateStmt); Oid old_type_oid; Oid typeNamespace; - Oid relid; + ObjectAddress address; /* * now set the parameters for keys/inheritance etc. All of these are @@ -2108,17 +2109,19 @@ DefineCompositeType(RangeVar *typevar, List *coldeflist) /* * Finally create the relation. This also creates the type. */ - relid = DefineRelation(createStmt, RELKIND_COMPOSITE_TYPE, InvalidOid); - Assert(relid != InvalidOid); - return relid; + DefineRelation(createStmt, RELKIND_COMPOSITE_TYPE, InvalidOid, &address); + + return address; } /* * AlterDomainDefault * * Routine implementing ALTER DOMAIN SET/DROP DEFAULT statements. + * + * Returns ObjectAddress of the modified domain. */ -Oid +ObjectAddress AlterDomainDefault(List *names, Node *defaultRaw) { TypeName *typename; @@ -2133,6 +2136,7 @@ AlterDomainDefault(List *names, Node *defaultRaw) bool new_record_repl[Natts_pg_type]; HeapTuple newtuple; Form_pg_type typTup; + ObjectAddress address; /* Make a TypeName so we can use standard type lookup machinery */ typename = makeTypeNameFromNameList(names); @@ -2242,19 +2246,23 @@ AlterDomainDefault(List *names, Node *defaultRaw) InvokeObjectPostAlterHook(TypeRelationId, domainoid, 0); + ObjectAddressSet(address, TypeRelationId, domainoid); + /* Clean up */ heap_close(rel, NoLock); heap_freetuple(newtuple); - return domainoid; + return address; } /* * AlterDomainNotNull * * Routine implementing ALTER DOMAIN SET/DROP NOT NULL statements. + * + * Returns ObjectAddress of the modified domain. */ -Oid +ObjectAddress AlterDomainNotNull(List *names, bool notNull) { TypeName *typename; @@ -2262,6 +2270,7 @@ AlterDomainNotNull(List *names, bool notNull) Relation typrel; HeapTuple tup; Form_pg_type typTup; + ObjectAddress address = InvalidObjectAddress; /* Make a TypeName so we can use standard type lookup machinery */ typename = makeTypeNameFromNameList(names); @@ -2282,7 +2291,7 @@ AlterDomainNotNull(List *names, bool notNull) if (typTup->typnotnull == notNull) { heap_close(typrel, RowExclusiveLock); - return InvalidOid; + return address; } /* Adding a NOT NULL constraint requires checking existing columns */ @@ -2356,11 +2365,13 @@ AlterDomainNotNull(List *names, bool notNull) InvokeObjectPostAlterHook(TypeRelationId, domainoid, 0); + ObjectAddressSet(address, TypeRelationId, domainoid); + /* Clean up */ heap_freetuple(tup); heap_close(typrel, RowExclusiveLock); - return domainoid; + return address; } /* @@ -2368,7 +2379,7 @@ AlterDomainNotNull(List *names, bool notNull) * * Implements the ALTER DOMAIN DROP CONSTRAINT statement */ -Oid +ObjectAddress AlterDomainDropConstraint(List *names, const char *constrName, DropBehavior behavior, bool missing_ok) { @@ -2381,6 +2392,7 @@ AlterDomainDropConstraint(List *names, const char *constrName, ScanKeyData key[1]; HeapTuple contup; bool found = false; + ObjectAddress address = InvalidObjectAddress; /* Make a TypeName so we can use standard type lookup machinery */ typename = makeTypeNameFromNameList(names); @@ -2427,6 +2439,9 @@ AlterDomainDropConstraint(List *names, const char *constrName, found = true; } } + + ObjectAddressSet(address, TypeRelationId, domainoid); + /* Clean up after the scan */ systable_endscan(conscan); heap_close(conrel, RowExclusiveLock); @@ -2446,7 +2461,7 @@ AlterDomainDropConstraint(List *names, const char *constrName, constrName, TypeNameToString(typename)))); } - return domainoid; + return address; } /* @@ -2454,8 +2469,9 @@ AlterDomainDropConstraint(List *names, const char *constrName, * * Implements the ALTER DOMAIN .. ADD CONSTRAINT statement. */ -Oid -AlterDomainAddConstraint(List *names, Node *newConstraint) +ObjectAddress +AlterDomainAddConstraint(List *names, Node *newConstraint, + ObjectAddress *constrAddr) { TypeName *typename; Oid domainoid; @@ -2464,6 +2480,7 @@ AlterDomainAddConstraint(List *names, Node *newConstraint) Form_pg_type typTup; Constraint *constr; char *ccbin; + ObjectAddress address; /* Make a TypeName so we can use standard type lookup machinery */ typename = makeTypeNameFromNameList(names); @@ -2539,7 +2556,7 @@ AlterDomainAddConstraint(List *names, Node *newConstraint) ccbin = domainAddConstraint(domainoid, typTup->typnamespace, typTup->typbasetype, typTup->typtypmod, - constr, NameStr(typTup->typname)); + constr, NameStr(typTup->typname), constrAddr); /* * If requested to validate the constraint, test all values stored in the @@ -2548,10 +2565,12 @@ AlterDomainAddConstraint(List *names, Node *newConstraint) if (!constr->skip_validation) validateDomainConstraint(domainoid, ccbin); + ObjectAddressSet(address, TypeRelationId, domainoid); + /* Clean up */ heap_close(typrel, RowExclusiveLock); - return domainoid; + return address; } /* @@ -2559,7 +2578,7 @@ AlterDomainAddConstraint(List *names, Node *newConstraint) * * Implements the ALTER DOMAIN .. VALIDATE CONSTRAINT statement. */ -Oid +ObjectAddress AlterDomainValidateConstraint(List *names, char *constrName) { TypeName *typename; @@ -2577,6 +2596,7 @@ AlterDomainValidateConstraint(List *names, char *constrName) HeapTuple tuple; HeapTuple copyTuple; ScanKeyData key; + ObjectAddress address; /* Make a TypeName so we can use standard type lookup machinery */ typename = makeTypeNameFromNameList(names); @@ -2647,6 +2667,8 @@ AlterDomainValidateConstraint(List *names, char *constrName) InvokeObjectPostAlterHook(ConstraintRelationId, HeapTupleGetOid(copyTuple), 0); + ObjectAddressSet(address, TypeRelationId, domainoid); + heap_freetuple(copyTuple); systable_endscan(scan); @@ -2656,7 +2678,7 @@ AlterDomainValidateConstraint(List *names, char *constrName) ReleaseSysCache(tup); - return domainoid; + return address; } static void @@ -2953,13 +2975,14 @@ checkDomainOwner(HeapTuple tup) static char * domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid, int typMod, Constraint *constr, - char *domainName) + char *domainName, ObjectAddress *constrAddr) { Node *expr; char *ccsrc; char *ccbin; ParseState *pstate; CoerceToDomainValue *domVal; + Oid ccoid; /* * Assign or validate constraint name @@ -3038,34 +3061,37 @@ domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid, /* * Store the constraint in pg_constraint */ - CreateConstraintEntry(constr->conname, /* Constraint Name */ - domainNamespace, /* namespace */ - CONSTRAINT_CHECK, /* Constraint Type */ - false, /* Is Deferrable */ - false, /* Is Deferred */ - !constr->skip_validation, /* Is Validated */ - InvalidOid, /* not a relation constraint */ - NULL, - 0, - domainOid, /* domain constraint */ - InvalidOid, /* no associated index */ - InvalidOid, /* Foreign key fields */ - NULL, - NULL, - NULL, - NULL, - 0, - ' ', - ' ', - ' ', - NULL, /* not an exclusion constraint */ - expr, /* Tree form of check constraint */ - ccbin, /* Binary form of check constraint */ - ccsrc, /* Source form of check constraint */ - true, /* is local */ - 0, /* inhcount */ - false, /* connoinherit */ - false); /* is_internal */ + ccoid = + CreateConstraintEntry(constr->conname, /* Constraint Name */ + domainNamespace, /* namespace */ + CONSTRAINT_CHECK, /* Constraint Type */ + false, /* Is Deferrable */ + false, /* Is Deferred */ + !constr->skip_validation, /* Is Validated */ + InvalidOid, /* not a relation constraint */ + NULL, + 0, + domainOid, /* domain constraint */ + InvalidOid, /* no associated index */ + InvalidOid, /* Foreign key fields */ + NULL, + NULL, + NULL, + NULL, + 0, + ' ', + ' ', + ' ', + NULL, /* not an exclusion constraint */ + expr, /* Tree form of check constraint */ + ccbin, /* Binary form of check constraint */ + ccsrc, /* Source form of check constraint */ + true, /* is local */ + 0, /* inhcount */ + false, /* connoinherit */ + false); /* is_internal */ + if (constrAddr) + ObjectAddressSet(*constrAddr, ConstraintRelationId, ccoid); /* * Return the compiled constraint expression so the calling routine can @@ -3078,7 +3104,7 @@ domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid, /* * Execute ALTER TYPE RENAME */ -Oid +ObjectAddress RenameType(RenameStmt *stmt) { List *names = stmt->object; @@ -3088,6 +3114,7 @@ RenameType(RenameStmt *stmt) Relation rel; HeapTuple tup; Form_pg_type typTup; + ObjectAddress address; /* Make a TypeName so we can use standard type lookup machinery */ typename = makeTypeNameFromNameList(names); @@ -3145,16 +3172,17 @@ RenameType(RenameStmt *stmt) RenameTypeInternal(typeOid, newTypeName, typTup->typnamespace); + ObjectAddressSet(address, TypeRelationId, typeOid); /* Clean up */ heap_close(rel, RowExclusiveLock); - return typeOid; + return address; } /* * Change the owner of a type. */ -Oid +ObjectAddress AlterTypeOwner(List *names, Oid newOwnerId, ObjectType objecttype) { TypeName *typename; @@ -3164,6 +3192,7 @@ AlterTypeOwner(List *names, Oid newOwnerId, ObjectType objecttype) HeapTuple newtup; Form_pg_type typTup; AclResult aclresult; + ObjectAddress address; rel = heap_open(TypeRelationId, RowExclusiveLock); @@ -3293,10 +3322,12 @@ AlterTypeOwner(List *names, Oid newOwnerId, ObjectType objecttype) } } + ObjectAddressSet(address, TypeRelationId, typeOid); + /* Clean up */ heap_close(rel, RowExclusiveLock); - return typeOid; + return address; } /* @@ -3376,13 +3407,16 @@ AlterTypeOwnerInternal(Oid typeOid, Oid newOwnerId, /* * Execute ALTER TYPE SET SCHEMA */ -Oid -AlterTypeNamespace(List *names, const char *newschema, ObjectType objecttype) +ObjectAddress +AlterTypeNamespace(List *names, const char *newschema, ObjectType objecttype, + Oid *oldschema) { TypeName *typename; Oid typeOid; Oid nspOid; + Oid oldNspOid; ObjectAddresses *objsMoved; + ObjectAddress myself; /* Make a TypeName so we can use standard type lookup machinery */ typename = makeTypeNameFromNameList(names); @@ -3399,10 +3433,15 @@ AlterTypeNamespace(List *names, const char *newschema, ObjectType objecttype) nspOid = LookupCreationNamespace(newschema); objsMoved = new_object_addresses(); - AlterTypeNamespace_oid(typeOid, nspOid, objsMoved); + oldNspOid = AlterTypeNamespace_oid(typeOid, nspOid, objsMoved); free_object_addresses(objsMoved); - return typeOid; + if (oldschema) + *oldschema = oldNspOid; + + ObjectAddressSet(myself, TypeRelationId, typeOid); + + return myself; } Oid diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index 2210eedb99a..0d30838aeed 100644 --- a/src/backend/commands/user.c +++ b/src/backend/commands/user.c @@ -1114,7 +1114,7 @@ DropRole(DropRoleStmt *stmt) /* * Rename role */ -Oid +ObjectAddress RenameRole(const char *oldname, const char *newname) { HeapTuple oldtuple, @@ -1128,6 +1128,7 @@ RenameRole(const char *oldname, const char *newname) bool repl_repl[Natts_pg_authid]; int i; Oid roleid; + ObjectAddress address; rel = heap_open(AuthIdRelationId, RowExclusiveLock); dsc = RelationGetDescr(rel); @@ -1216,6 +1217,8 @@ RenameRole(const char *oldname, const char *newname) InvokeObjectPostAlterHook(AuthIdRelationId, roleid, 0); + ObjectAddressSet(address, AuthIdRelationId, roleid); + ReleaseSysCache(oldtuple); /* @@ -1223,7 +1226,7 @@ RenameRole(const char *oldname, const char *newname) */ heap_close(rel, NoLock); - return roleid; + return address; } /* diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c index 7358723bded..6f2a749756c 100644 --- a/src/backend/commands/view.c +++ b/src/backend/commands/view.c @@ -65,7 +65,7 @@ validateWithCheckOption(char *value) * work harder. *--------------------------------------------------------------------- */ -static Oid +static ObjectAddress DefineVirtualRelation(RangeVar *relation, List *tlist, bool replace, List *options) { @@ -143,6 +143,7 @@ DefineVirtualRelation(RangeVar *relation, List *tlist, bool replace, TupleDesc descriptor; List *atcmds = NIL; AlterTableCmd *atcmd; + ObjectAddress address; /* Relation is already locked, but we must build a relcache entry. */ rel = relation_open(viewOid, NoLock); @@ -208,16 +209,18 @@ DefineVirtualRelation(RangeVar *relation, List *tlist, bool replace, /* OK, let's do it. */ AlterTableInternal(viewOid, atcmds, true); + ObjectAddressSet(address, RelationRelationId, viewOid); + /* * Seems okay, so return the OID of the pre-existing view. */ relation_close(rel, NoLock); /* keep the lock! */ - return viewOid; + return address; } else { - Oid relid; + ObjectAddress address; /* * now set the parameters for keys/inheritance etc. All of these are @@ -237,9 +240,9 @@ DefineVirtualRelation(RangeVar *relation, List *tlist, bool replace, * existing view, so we don't need more code to complain if "replace" * is false). */ - relid = DefineRelation(createStmt, RELKIND_VIEW, InvalidOid); - Assert(relid != InvalidOid); - return relid; + address = DefineRelation(createStmt, RELKIND_VIEW, InvalidOid, NULL); + Assert(address.objectId != InvalidOid); + return address; } } @@ -388,14 +391,14 @@ UpdateRangeTableOfViewParse(Oid viewOid, Query *viewParse) * DefineView * Execute a CREATE VIEW command. */ -Oid +ObjectAddress DefineView(ViewStmt *stmt, const char *queryString) { Query *viewParse; - Oid viewOid; RangeVar *view; ListCell *cell; bool check_option; + ObjectAddress address; /* * Run parse analysis to convert the raw parse tree to a Query. Note this @@ -533,7 +536,7 @@ DefineView(ViewStmt *stmt, const char *queryString) * NOTE: if it already exists and replace is false, the xact will be * aborted. */ - viewOid = DefineVirtualRelation(view, viewParse->targetList, + address = DefineVirtualRelation(view, viewParse->targetList, stmt->replace, stmt->options); /* @@ -543,9 +546,9 @@ DefineView(ViewStmt *stmt, const char *queryString) */ CommandCounterIncrement(); - StoreViewQuery(viewOid, viewParse, stmt->replace); + StoreViewQuery(address.objectId, viewParse, stmt->replace); - return viewOid; + return address; } /* |