diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index e0dbcea0939f288be30029a97b1954277964236c..c518c50b21bfc7ae9e4109726ed9e345e16711d5 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -97,7 +97,7 @@ static ObjectAddress AddNewRelationType(const char *typeName, Oid new_row_type, Oid new_array_type); static void RelationRemoveInheritance(Oid relid); -static void StoreRelCheck(Relation rel, char *ccname, Node *expr, +static Oid StoreRelCheck(Relation rel, char *ccname, Node *expr, bool is_validated, bool is_local, int inhcount, bool is_no_inherit, bool is_internal); static void StoreConstraints(Relation rel, List *cooked_constraints, @@ -1852,8 +1852,10 @@ heap_drop_with_catalog(Oid relid) /* * Store a default expression for column attnum of relation rel. + * + * Returns the OID of the new pg_attrdef tuple. */ -void +Oid StoreAttrDefault(Relation rel, AttrNumber attnum, Node *expr, bool is_internal) { @@ -1958,6 +1960,8 @@ StoreAttrDefault(Relation rel, AttrNumber attnum, */ InvokeObjectPostCreateHookArg(AttrDefaultRelationId, RelationGetRelid(rel), attnum, is_internal); + + return attrdefOid; } /* @@ -1965,8 +1969,10 @@ StoreAttrDefault(Relation rel, AttrNumber attnum, * * Caller is responsible for updating the count of constraints * in the pg_class entry for the relation. + * + * The OID of the new constraint is returned. */ -static void +static Oid StoreRelCheck(Relation rel, char *ccname, Node *expr, bool is_validated, bool is_local, int inhcount, bool is_no_inherit, bool is_internal) @@ -1976,6 +1982,7 @@ StoreRelCheck(Relation rel, char *ccname, Node *expr, List *varList; int keycount; int16 *attNos; + Oid constrOid; /* * Flatten expression to string form for storage. @@ -2027,42 +2034,47 @@ StoreRelCheck(Relation rel, char *ccname, Node *expr, /* * Create the Check Constraint */ - CreateConstraintEntry(ccname, /* Constraint Name */ - RelationGetNamespace(rel), /* namespace */ - CONSTRAINT_CHECK, /* Constraint Type */ - false, /* Is Deferrable */ - false, /* Is Deferred */ - is_validated, - RelationGetRelid(rel), /* relation */ - attNos, /* attrs in the constraint */ - keycount, /* # attrs in the constraint */ - InvalidOid, /* not a 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 */ - is_local, /* conislocal */ - inhcount, /* coninhcount */ - is_no_inherit, /* connoinherit */ - is_internal); /* internally constructed? */ + constrOid = + CreateConstraintEntry(ccname, /* Constraint Name */ + RelationGetNamespace(rel), /* namespace */ + CONSTRAINT_CHECK, /* Constraint Type */ + false, /* Is Deferrable */ + false, /* Is Deferred */ + is_validated, + RelationGetRelid(rel), /* relation */ + attNos, /* attrs in the constraint */ + keycount, /* # attrs in the constraint */ + InvalidOid, /* not a 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 */ + is_local, /* conislocal */ + inhcount, /* coninhcount */ + is_no_inherit, /* connoinherit */ + is_internal); /* internally constructed? */ pfree(ccbin); pfree(ccsrc); + + return constrOid; } /* * Store defaults and constraints (passed as a list of CookedConstraint). * + * Each CookedConstraint struct is modified to store the new catalog tuple OID. + * * NOTE: only pre-cooked expressions will be passed this way, which is to * say expressions inherited from an existing relation. Newly parsed * expressions can be added later, by direct calls to StoreAttrDefault @@ -2074,7 +2086,7 @@ StoreConstraints(Relation rel, List *cooked_constraints, bool is_internal) int numchecks = 0; ListCell *lc; - if (!cooked_constraints) + if (cooked_constraints == NIL) return; /* nothing to do */ /* @@ -2091,12 +2103,15 @@ StoreConstraints(Relation rel, List *cooked_constraints, bool is_internal) switch (con->contype) { case CONSTR_DEFAULT: - StoreAttrDefault(rel, con->attnum, con->expr, is_internal); + con->conoid = StoreAttrDefault(rel, con->attnum, con->expr, + is_internal); break; case CONSTR_CHECK: - StoreRelCheck(rel, con->name, con->expr, !con->skip_validation, - con->is_local, con->inhcount, - con->is_no_inherit, is_internal); + con->conoid = + StoreRelCheck(rel, con->name, con->expr, + !con->skip_validation, con->is_local, + con->inhcount, con->is_no_inherit, + is_internal); numchecks++; break; default: @@ -2184,6 +2199,7 @@ AddRelationNewConstraints(Relation rel, { RawColumnDefault *colDef = (RawColumnDefault *) lfirst(cell); Form_pg_attribute atp = rel->rd_att->attrs[colDef->attnum - 1]; + Oid defOid; expr = cookDefault(pstate, colDef->raw_default, atp->atttypid, atp->atttypmod, @@ -2204,10 +2220,11 @@ AddRelationNewConstraints(Relation rel, (IsA(expr, Const) &&((Const *) expr)->constisnull)) continue; - StoreAttrDefault(rel, colDef->attnum, expr, is_internal); + defOid = StoreAttrDefault(rel, colDef->attnum, expr, is_internal); cooked = (CookedConstraint *) palloc(sizeof(CookedConstraint)); cooked->contype = CONSTR_DEFAULT; + cooked->conoid = defOid; cooked->name = NULL; cooked->attnum = colDef->attnum; cooked->expr = expr; @@ -2227,6 +2244,7 @@ AddRelationNewConstraints(Relation rel, { Constraint *cdef = (Constraint *) lfirst(cell); char *ccname; + Oid constrOid; if (cdef->contype != CONSTR_CHECK) continue; @@ -2329,13 +2347,15 @@ AddRelationNewConstraints(Relation rel, /* * OK, store it. */ - StoreRelCheck(rel, ccname, expr, !cdef->skip_validation, is_local, - is_local ? 0 : 1, cdef->is_no_inherit, is_internal); + constrOid = + StoreRelCheck(rel, ccname, expr, !cdef->skip_validation, is_local, + is_local ? 0 : 1, cdef->is_no_inherit, is_internal); numchecks++; cooked = (CookedConstraint *) palloc(sizeof(CookedConstraint)); cooked->contype = CONSTR_CHECK; + cooked->conoid = constrOid; cooked->name = ccname; cooked->attnum = 0; cooked->expr = expr; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index f85ed93e401153ab94b8164b000fd0c0eedf8d97..351dcb27847074569562f01ffed15e92651ca71d 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -675,7 +675,7 @@ UpdateIndexRelation(Oid indexoid, * to fix it up. * is_internal: if true, post creation hook for new index * if_not_exists: if true, do not throw an error if a relation with - * the same name already exists. + * the same name already exists. * * Returns the OID of the created index. */ @@ -1111,7 +1111,8 @@ index_create(Relation heapRelation, /* * index_constraint_create * - * Set up a constraint associated with an index + * Set up a constraint associated with an index. Return the new constraint's + * address. * * heapRelation: table owning the index (must be suitably locked by caller) * indexRelationId: OID of the index @@ -1128,7 +1129,7 @@ index_create(Relation heapRelation, * allow_system_table_mods: allow table to be a system catalog * is_internal: index is constructed due to internal process */ -void +ObjectAddress index_constraint_create(Relation heapRelation, Oid indexRelationId, IndexInfo *indexInfo, @@ -1316,6 +1317,8 @@ index_constraint_create(Relation heapRelation, heap_freetuple(indexTuple); heap_close(pg_index, RowExclusiveLock); } + + return referenced; } /* diff --git a/src/backend/catalog/pg_constraint.c b/src/backend/catalog/pg_constraint.c index 77fe91858da413a9a1f931d1e728f9285ab7b92b..3c756f82278abea7eaf94820ef2486e3bcf80d37 100644 --- a/src/backend/catalog/pg_constraint.c +++ b/src/backend/catalog/pg_constraint.c @@ -40,6 +40,8 @@ * Subsidiary records (such as triggers or indexes to implement the * constraint) are *not* created here. But we do make dependency links * from the constraint to the things it depends on. + * + * The new constraint's OID is returned. */ Oid CreateConstraintEntry(const char *constraintName, diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 32e19c5e4fc02010009fc99a24e168d4f6f65737..002319e8a02f1f79494713f3707adfa70c085741 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -282,9 +282,9 @@ static void AlterIndexNamespaces(Relation classRel, Relation rel, static void AlterSeqNamespaces(Relation classRel, Relation rel, Oid oldNspOid, Oid newNspOid, ObjectAddresses *objsMoved, LOCKMODE lockmode); -static void ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd, +static ObjectAddress ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd, bool recurse, bool recursing, LOCKMODE lockmode); -static void ATExecValidateConstraint(Relation rel, char *constrName, +static ObjectAddress ATExecValidateConstraint(Relation rel, char *constrName, bool recurse, bool recursing, LOCKMODE lockmode); static int transformColumnNameList(Oid relId, List *colList, int16 *attnums, Oid *atttypids); @@ -326,47 +326,47 @@ static List *find_typed_table_dependencies(Oid typeOid, const char *typeName, DropBehavior behavior); static void ATPrepAddColumn(List **wqueue, Relation rel, bool recurse, bool recursing, bool is_view, AlterTableCmd *cmd, LOCKMODE lockmode); -static void ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, - ColumnDef *colDef, bool isOid, +static ObjectAddress ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, + Relation rel, ColumnDef *colDef, bool isOid, bool recurse, bool recursing, LOCKMODE lockmode); static void check_for_column_name_collision(Relation rel, const char *colname); static void add_column_datatype_dependency(Oid relid, int32 attnum, Oid typid); static void add_column_collation_dependency(Oid relid, int32 attnum, Oid collid); static void ATPrepAddOids(List **wqueue, Relation rel, bool recurse, AlterTableCmd *cmd, LOCKMODE lockmode); -static void ATExecDropNotNull(Relation rel, const char *colName, LOCKMODE lockmode); -static void ATExecSetNotNull(AlteredTableInfo *tab, Relation rel, +static ObjectAddress ATExecDropNotNull(Relation rel, const char *colName, LOCKMODE lockmode); +static ObjectAddress ATExecSetNotNull(AlteredTableInfo *tab, Relation rel, const char *colName, LOCKMODE lockmode); -static void ATExecColumnDefault(Relation rel, const char *colName, +static ObjectAddress ATExecColumnDefault(Relation rel, const char *colName, Node *newDefault, LOCKMODE lockmode); static void ATPrepSetStatistics(Relation rel, const char *colName, Node *newValue, LOCKMODE lockmode); -static void ATExecSetStatistics(Relation rel, const char *colName, +static ObjectAddress ATExecSetStatistics(Relation rel, const char *colName, Node *newValue, LOCKMODE lockmode); -static void ATExecSetOptions(Relation rel, const char *colName, +static ObjectAddress ATExecSetOptions(Relation rel, const char *colName, Node *options, bool isReset, LOCKMODE lockmode); -static void ATExecSetStorage(Relation rel, const char *colName, +static ObjectAddress ATExecSetStorage(Relation rel, const char *colName, Node *newValue, LOCKMODE lockmode); static void ATPrepDropColumn(List **wqueue, Relation rel, bool recurse, bool recursing, AlterTableCmd *cmd, LOCKMODE lockmode); -static void ATExecDropColumn(List **wqueue, Relation rel, const char *colName, +static ObjectAddress ATExecDropColumn(List **wqueue, Relation rel, const char *colName, DropBehavior behavior, bool recurse, bool recursing, bool missing_ok, LOCKMODE lockmode); -static void ATExecAddIndex(AlteredTableInfo *tab, Relation rel, +static ObjectAddress ATExecAddIndex(AlteredTableInfo *tab, Relation rel, IndexStmt *stmt, bool is_rebuild, LOCKMODE lockmode); -static void ATExecAddConstraint(List **wqueue, +static ObjectAddress ATExecAddConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, Constraint *newConstraint, bool recurse, bool is_readd, LOCKMODE lockmode); -static void ATExecAddIndexConstraint(AlteredTableInfo *tab, Relation rel, +static ObjectAddress ATExecAddIndexConstraint(AlteredTableInfo *tab, Relation rel, IndexStmt *stmt, LOCKMODE lockmode); -static void ATAddCheckConstraint(List **wqueue, +static ObjectAddress ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, Constraint *constr, bool recurse, bool recursing, bool is_readd, LOCKMODE lockmode); -static void ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel, +static ObjectAddress ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel, Constraint *fkconstraint, LOCKMODE lockmode); static void ATExecDropConstraint(Relation rel, const char *constrName, DropBehavior behavior, @@ -377,9 +377,9 @@ static void ATPrepAlterColumnType(List **wqueue, bool recurse, bool recursing, AlterTableCmd *cmd, LOCKMODE lockmode); static bool ATColumnChangeRequiresRewrite(Node *expr, AttrNumber varattno); -static void ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, +static ObjectAddress ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, AlterTableCmd *cmd, LOCKMODE lockmode); -static void ATExecAlterColumnGenericOptions(Relation rel, const char *colName, +static ObjectAddress ATExecAlterColumnGenericOptions(Relation rel, const char *colName, List *options, LOCKMODE lockmode); static void ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode); @@ -392,7 +392,7 @@ static void change_owner_fix_column_acls(Oid relationOid, Oid oldOwnerId, Oid newOwnerId); static void change_owner_recurse_to_sequences(Oid relationOid, Oid newOwnerId, LOCKMODE lockmode); -static void ATExecClusterOn(Relation rel, const char *indexName, +static ObjectAddress ATExecClusterOn(Relation rel, const char *indexName, LOCKMODE lockmode); static void ATExecDropCluster(Relation rel, LOCKMODE lockmode); static bool ATPrepChangePersistence(Relation rel, bool toLogged); @@ -407,10 +407,10 @@ static void ATExecEnableDisableTrigger(Relation rel, char *trigname, static void ATExecEnableDisableRule(Relation rel, char *rulename, char fires_when, LOCKMODE lockmode); static void ATPrepAddInherit(Relation child_rel); -static void ATExecAddInherit(Relation child_rel, RangeVar *parent, LOCKMODE lockmode); -static void ATExecDropInherit(Relation rel, RangeVar *parent, LOCKMODE lockmode); +static ObjectAddress ATExecAddInherit(Relation child_rel, RangeVar *parent, LOCKMODE lockmode); +static ObjectAddress ATExecDropInherit(Relation rel, RangeVar *parent, LOCKMODE lockmode); static void drop_parent_dependency(Oid relid, Oid refclassid, Oid refobjid); -static void ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKMODE lockmode); +static ObjectAddress ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKMODE lockmode); static void ATExecDropOf(Relation rel, LOCKMODE lockmode); static void ATExecReplicaIdentity(Relation rel, ReplicaIdentityStmt *stmt, LOCKMODE lockmode); static void ATExecGenericOptions(Relation rel, List *options); @@ -623,6 +623,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, cooked = (CookedConstraint *) palloc(sizeof(CookedConstraint)); cooked->contype = CONSTR_DEFAULT; + cooked->conoid = InvalidOid; /* until created */ cooked->name = NULL; cooked->attnum = attnum; cooked->expr = colDef->cooked_default; @@ -1742,6 +1743,7 @@ MergeAttributes(List *schema, List *supers, char relpersistence, cooked = (CookedConstraint *) palloc(sizeof(CookedConstraint)); cooked->contype = CONSTR_CHECK; + cooked->conoid = InvalidOid; /* until created */ cooked->name = pstrdup(name); cooked->attnum = 0; /* not used for constraints */ cooked->expr = expr; @@ -3429,78 +3431,90 @@ static void ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel, AlterTableCmd *cmd, LOCKMODE lockmode) { + ObjectAddress address = InvalidObjectAddress; + switch (cmd->subtype) { case AT_AddColumn: /* ADD COLUMN */ case AT_AddColumnToView: /* add column via CREATE OR REPLACE * VIEW */ - ATExecAddColumn(wqueue, tab, rel, (ColumnDef *) cmd->def, - false, false, false, lockmode); + address = ATExecAddColumn(wqueue, tab, rel, (ColumnDef *) cmd->def, + false, false, false, lockmode); break; case AT_AddColumnRecurse: - ATExecAddColumn(wqueue, tab, rel, (ColumnDef *) cmd->def, - false, true, false, lockmode); + address = ATExecAddColumn(wqueue, tab, rel, (ColumnDef *) cmd->def, + false, true, false, lockmode); break; case AT_ColumnDefault: /* ALTER COLUMN DEFAULT */ - ATExecColumnDefault(rel, cmd->name, cmd->def, lockmode); + address = ATExecColumnDefault(rel, cmd->name, cmd->def, lockmode); break; case AT_DropNotNull: /* ALTER COLUMN DROP NOT NULL */ - ATExecDropNotNull(rel, cmd->name, lockmode); + address = ATExecDropNotNull(rel, cmd->name, lockmode); break; case AT_SetNotNull: /* ALTER COLUMN SET NOT NULL */ - ATExecSetNotNull(tab, rel, cmd->name, lockmode); + address = ATExecSetNotNull(tab, rel, cmd->name, lockmode); break; case AT_SetStatistics: /* ALTER COLUMN SET STATISTICS */ - ATExecSetStatistics(rel, cmd->name, cmd->def, lockmode); + address = ATExecSetStatistics(rel, cmd->name, cmd->def, lockmode); break; case AT_SetOptions: /* ALTER COLUMN SET ( options ) */ - ATExecSetOptions(rel, cmd->name, cmd->def, false, lockmode); + address = ATExecSetOptions(rel, cmd->name, cmd->def, false, lockmode); break; case AT_ResetOptions: /* ALTER COLUMN RESET ( options ) */ - ATExecSetOptions(rel, cmd->name, cmd->def, true, lockmode); + address = ATExecSetOptions(rel, cmd->name, cmd->def, true, lockmode); break; case AT_SetStorage: /* ALTER COLUMN SET STORAGE */ - ATExecSetStorage(rel, cmd->name, cmd->def, lockmode); + address = ATExecSetStorage(rel, cmd->name, cmd->def, lockmode); break; case AT_DropColumn: /* DROP COLUMN */ - ATExecDropColumn(wqueue, rel, cmd->name, - cmd->behavior, false, false, cmd->missing_ok, lockmode); + address = ATExecDropColumn(wqueue, rel, cmd->name, + cmd->behavior, false, false, + cmd->missing_ok, lockmode); break; case AT_DropColumnRecurse: /* DROP COLUMN with recursion */ - ATExecDropColumn(wqueue, rel, cmd->name, - cmd->behavior, true, false, cmd->missing_ok, lockmode); + address = ATExecDropColumn(wqueue, rel, cmd->name, + cmd->behavior, true, false, + cmd->missing_ok, lockmode); break; case AT_AddIndex: /* ADD INDEX */ - ATExecAddIndex(tab, rel, (IndexStmt *) cmd->def, false, lockmode); + address = ATExecAddIndex(tab, rel, (IndexStmt *) cmd->def, false, + lockmode); break; case AT_ReAddIndex: /* ADD INDEX */ - ATExecAddIndex(tab, rel, (IndexStmt *) cmd->def, true, lockmode); + address = ATExecAddIndex(tab, rel, (IndexStmt *) cmd->def, true, + lockmode); break; case AT_AddConstraint: /* ADD CONSTRAINT */ - ATExecAddConstraint(wqueue, tab, rel, (Constraint *) cmd->def, - false, false, lockmode); + address = + ATExecAddConstraint(wqueue, tab, rel, (Constraint *) cmd->def, + false, false, lockmode); break; case AT_AddConstraintRecurse: /* ADD CONSTRAINT with recursion */ - ATExecAddConstraint(wqueue, tab, rel, (Constraint *) cmd->def, - true, false, lockmode); + address = + ATExecAddConstraint(wqueue, tab, rel, (Constraint *) cmd->def, + true, false, lockmode); break; case AT_ReAddConstraint: /* Re-add pre-existing check * constraint */ - ATExecAddConstraint(wqueue, tab, rel, (Constraint *) cmd->def, - false, true, lockmode); + address = + ATExecAddConstraint(wqueue, tab, rel, (Constraint *) cmd->def, + false, true, lockmode); break; case AT_AddIndexConstraint: /* ADD CONSTRAINT USING INDEX */ - ATExecAddIndexConstraint(tab, rel, (IndexStmt *) cmd->def, lockmode); + address = ATExecAddIndexConstraint(tab, rel, (IndexStmt *) cmd->def, + lockmode); break; case AT_AlterConstraint: /* ALTER CONSTRAINT */ - ATExecAlterConstraint(rel, cmd, false, false, lockmode); + address = ATExecAlterConstraint(rel, cmd, false, false, lockmode); break; case AT_ValidateConstraint: /* VALIDATE CONSTRAINT */ - ATExecValidateConstraint(rel, cmd->name, false, false, lockmode); + address = ATExecValidateConstraint(rel, cmd->name, false, false, + lockmode); break; case AT_ValidateConstraintRecurse: /* VALIDATE CONSTRAINT with * recursion */ - ATExecValidateConstraint(rel, cmd->name, true, false, lockmode); + address = ATExecValidateConstraint(rel, cmd->name, true, false, + lockmode); break; case AT_DropConstraint: /* DROP CONSTRAINT */ ATExecDropConstraint(rel, cmd->name, cmd->behavior, @@ -3513,10 +3527,12 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel, cmd->missing_ok, lockmode); break; case AT_AlterColumnType: /* ALTER COLUMN TYPE */ - ATExecAlterColumnType(tab, rel, cmd, lockmode); + address = ATExecAlterColumnType(tab, rel, cmd, lockmode); break; case AT_AlterColumnGenericOptions: /* ALTER COLUMN OPTIONS */ - ATExecAlterColumnGenericOptions(rel, cmd->name, (List *) cmd->def, lockmode); + address = + ATExecAlterColumnGenericOptions(rel, cmd->name, + (List *) cmd->def, lockmode); break; case AT_ChangeOwner: /* ALTER OWNER */ ATExecChangeOwner(RelationGetRelid(rel), @@ -3524,7 +3540,7 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel, false, lockmode); break; case AT_ClusterOn: /* CLUSTER ON */ - ATExecClusterOn(rel, cmd->name, lockmode); + address = ATExecClusterOn(rel, cmd->name, lockmode); break; case AT_DropCluster: /* SET WITHOUT CLUSTER */ ATExecDropCluster(rel, lockmode); @@ -3535,14 +3551,16 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel, case AT_AddOids: /* SET WITH OIDS */ /* Use the ADD COLUMN code, unless prep decided to do nothing */ if (cmd->def != NULL) - ATExecAddColumn(wqueue, tab, rel, (ColumnDef *) cmd->def, - true, false, false, lockmode); + address = + ATExecAddColumn(wqueue, tab, rel, (ColumnDef *) cmd->def, + true, false, false, lockmode); break; case AT_AddOidsRecurse: /* SET WITH OIDS */ /* Use the ADD COLUMN code, unless prep decided to do nothing */ if (cmd->def != NULL) - ATExecAddColumn(wqueue, tab, rel, (ColumnDef *) cmd->def, - true, true, false, lockmode); + address = + ATExecAddColumn(wqueue, tab, rel, (ColumnDef *) cmd->def, + true, true, false, lockmode); break; case AT_DropOids: /* SET WITHOUT OIDS */ @@ -3613,13 +3631,13 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel, break; case AT_AddInherit: - ATExecAddInherit(rel, (RangeVar *) cmd->def, lockmode); + address = ATExecAddInherit(rel, (RangeVar *) cmd->def, lockmode); break; case AT_DropInherit: - ATExecDropInherit(rel, (RangeVar *) cmd->def, lockmode); + address = ATExecDropInherit(rel, (RangeVar *) cmd->def, lockmode); break; case AT_AddOf: - ATExecAddOf(rel, (TypeName *) cmd->def, lockmode); + address = ATExecAddOf(rel, (TypeName *) cmd->def, lockmode); break; case AT_DropOf: ATExecDropOf(rel, lockmode); @@ -3642,6 +3660,9 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel, break; } + /* supress compiler warning until we have some use for the address */ + (void) address; + /* * Bump the command counter to ensure the next subcommand in the sequence * can see the changes so far @@ -4626,7 +4647,11 @@ ATPrepAddColumn(List **wqueue, Relation rel, bool recurse, bool recursing, cmd->subtype = AT_AddColumnRecurse; } -static void +/* + * Add a column to a table; this handles the AT_AddOids cases as well. The + * return value is the address of the new column in the parent relation. + */ +static ObjectAddress ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, ColumnDef *colDef, bool isOid, bool recurse, bool recursing, LOCKMODE lockmode) @@ -4647,6 +4672,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, List *children; ListCell *child; AclResult aclresult; + ObjectAddress address; /* At top level, permission check was done in ATPrepCmd, else do it */ if (recursing) @@ -4711,7 +4737,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, colDef->colname, RelationGetRelationName(rel)))); heap_close(attrdesc, RowExclusiveLock); - return; + return InvalidObjectAddress; } } @@ -4951,12 +4977,15 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, /* Find or create work queue entry for this table */ childtab = ATGetQueueEntry(wqueue, childrel); - /* Recurse to child */ + /* Recurse to child; return value is ignored */ ATExecAddColumn(wqueue, childtab, childrel, colDef, isOid, recurse, true, lockmode); heap_close(childrel, NoLock); } + + ObjectAddressSubSet(address, RelationRelationId, myrelid, newattnum); + return address; } /* @@ -5070,8 +5099,11 @@ ATPrepAddOids(List **wqueue, Relation rel, bool recurse, AlterTableCmd *cmd, LOC /* * ALTER TABLE ALTER COLUMN DROP NOT NULL + * + * Return the address of the modified column. If the column was already + * nullable, InvalidObjectAddress is returned. */ -static void +static ObjectAddress ATExecDropNotNull(Relation rel, const char *colName, LOCKMODE lockmode) { HeapTuple tuple; @@ -5079,6 +5111,7 @@ ATExecDropNotNull(Relation rel, const char *colName, LOCKMODE lockmode) Relation attr_rel; List *indexoidlist; ListCell *indexoidscan; + ObjectAddress address; /* * lookup the attribute @@ -5156,24 +5189,35 @@ ATExecDropNotNull(Relation rel, const char *colName, LOCKMODE lockmode) /* keep the system catalog indexes current */ CatalogUpdateIndexes(attr_rel, tuple); + + ObjectAddressSubSet(address, RelationRelationId, + RelationGetRelid(rel), attnum); } + else + address = InvalidObjectAddress; InvokeObjectPostAlterHook(RelationRelationId, RelationGetRelid(rel), attnum); heap_close(attr_rel, RowExclusiveLock); + + return address; } /* * ALTER TABLE ALTER COLUMN SET NOT NULL + * + * Return the address of the modified column. If the column was already NOT + * NULL, InvalidObjectAddress is returned. */ -static void +static ObjectAddress ATExecSetNotNull(AlteredTableInfo *tab, Relation rel, const char *colName, LOCKMODE lockmode) { HeapTuple tuple; AttrNumber attnum; Relation attr_rel; + ObjectAddress address; /* * lookup the attribute @@ -5211,22 +5255,32 @@ ATExecSetNotNull(AlteredTableInfo *tab, Relation rel, /* Tell Phase 3 it needs to test the constraint */ tab->new_notnull = true; + + ObjectAddressSubSet(address, RelationRelationId, + RelationGetRelid(rel), attnum); } + else + address = InvalidObjectAddress; InvokeObjectPostAlterHook(RelationRelationId, RelationGetRelid(rel), attnum); heap_close(attr_rel, RowExclusiveLock); + + return address; } /* * ALTER TABLE ALTER COLUMN SET/DROP DEFAULT + * + * Return the address of the affected column. */ -static void +static ObjectAddress ATExecColumnDefault(Relation rel, const char *colName, Node *newDefault, LOCKMODE lockmode) { AttrNumber attnum; + ObjectAddress address; /* * get the number of the attribute @@ -5273,6 +5327,10 @@ ATExecColumnDefault(Relation rel, const char *colName, AddRelationNewConstraints(rel, list_make1(rawEnt), NIL, false, true, false); } + + ObjectAddressSubSet(address, RelationRelationId, + RelationGetRelid(rel), attnum); + return address; } /* @@ -5302,13 +5360,18 @@ ATPrepSetStatistics(Relation rel, const char *colName, Node *newValue, LOCKMODE RelationGetRelationName(rel)); } -static void +/* + * Return value is the address of the modified column + */ +static ObjectAddress ATExecSetStatistics(Relation rel, const char *colName, Node *newValue, LOCKMODE lockmode) { int newtarget; Relation attrelation; HeapTuple tuple; Form_pg_attribute attrtuple; + AttrNumber attnum; + ObjectAddress address; Assert(IsA(newValue, Integer)); newtarget = intVal(newValue); @@ -5343,7 +5406,8 @@ ATExecSetStatistics(Relation rel, const char *colName, Node *newValue, LOCKMODE colName, RelationGetRelationName(rel)))); attrtuple = (Form_pg_attribute) GETSTRUCT(tuple); - if (attrtuple->attnum <= 0) + attnum = attrtuple->attnum; + if (attnum <= 0) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot alter system column \"%s\"", @@ -5359,12 +5423,19 @@ ATExecSetStatistics(Relation rel, const char *colName, Node *newValue, LOCKMODE InvokeObjectPostAlterHook(RelationRelationId, RelationGetRelid(rel), attrtuple->attnum); + ObjectAddressSubSet(address, RelationRelationId, + RelationGetRelid(rel), attnum); heap_freetuple(tuple); heap_close(attrelation, RowExclusiveLock); + + return address; } -static void +/* + * Return value is the address of the modified column + */ +static ObjectAddress ATExecSetOptions(Relation rel, const char *colName, Node *options, bool isReset, LOCKMODE lockmode) { @@ -5372,9 +5443,11 @@ ATExecSetOptions(Relation rel, const char *colName, Node *options, HeapTuple tuple, newtuple; Form_pg_attribute attrtuple; + AttrNumber attnum; Datum datum, newOptions; bool isnull; + ObjectAddress address; Datum repl_val[Natts_pg_attribute]; bool repl_null[Natts_pg_attribute]; bool repl_repl[Natts_pg_attribute]; @@ -5390,7 +5463,8 @@ ATExecSetOptions(Relation rel, const char *colName, Node *options, colName, RelationGetRelationName(rel)))); attrtuple = (Form_pg_attribute) GETSTRUCT(tuple); - if (attrtuple->attnum <= 0) + attnum = attrtuple->attnum; + if (attnum <= 0) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot alter system column \"%s\"", @@ -5424,17 +5498,24 @@ ATExecSetOptions(Relation rel, const char *colName, Node *options, InvokeObjectPostAlterHook(RelationRelationId, RelationGetRelid(rel), attrtuple->attnum); + ObjectAddressSubSet(address, RelationRelationId, + RelationGetRelid(rel), attnum); + heap_freetuple(newtuple); ReleaseSysCache(tuple); heap_close(attrelation, RowExclusiveLock); + + return address; } /* * ALTER TABLE ALTER COLUMN SET STORAGE + * + * Return value is the address of the modified column */ -static void +static ObjectAddress ATExecSetStorage(Relation rel, const char *colName, Node *newValue, LOCKMODE lockmode) { char *storagemode; @@ -5442,6 +5523,8 @@ ATExecSetStorage(Relation rel, const char *colName, Node *newValue, LOCKMODE loc Relation attrelation; HeapTuple tuple; Form_pg_attribute attrtuple; + AttrNumber attnum; + ObjectAddress address; Assert(IsA(newValue, String)); storagemode = strVal(newValue); @@ -5474,7 +5557,8 @@ ATExecSetStorage(Relation rel, const char *colName, Node *newValue, LOCKMODE loc colName, RelationGetRelationName(rel)))); attrtuple = (Form_pg_attribute) GETSTRUCT(tuple); - if (attrtuple->attnum <= 0) + attnum = attrtuple->attnum; + if (attnum <= 0) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot alter system column \"%s\"", @@ -5504,6 +5588,10 @@ ATExecSetStorage(Relation rel, const char *colName, Node *newValue, LOCKMODE loc heap_freetuple(tuple); heap_close(attrelation, RowExclusiveLock); + + ObjectAddressSubSet(address, RelationRelationId, + RelationGetRelid(rel), attnum); + return address; } @@ -5532,7 +5620,10 @@ ATPrepDropColumn(List **wqueue, Relation rel, bool recurse, bool recursing, cmd->subtype = AT_DropColumnRecurse; } -static void +/* + * Return value is that of the dropped column. + */ +static ObjectAddress ATExecDropColumn(List **wqueue, Relation rel, const char *colName, DropBehavior behavior, bool recurse, bool recursing, @@ -5566,7 +5657,7 @@ ATExecDropColumn(List **wqueue, Relation rel, const char *colName, ereport(NOTICE, (errmsg("column \"%s\" of relation \"%s\" does not exist, skipping", colName, RelationGetRelationName(rel)))); - return; + return InvalidObjectAddress; } } targetatt = (Form_pg_attribute) GETSTRUCT(tuple); @@ -5720,6 +5811,8 @@ ATExecDropColumn(List **wqueue, Relation rel, const char *colName, /* Tell Phase 3 to physically remove the OID column */ tab->rewrite |= AT_REWRITE_ALTER_OID; } + + return object; } /* @@ -5728,8 +5821,10 @@ ATExecDropColumn(List **wqueue, Relation rel, const char *colName, * There is no such command in the grammar, but parse_utilcmd.c converts * UNIQUE and PRIMARY KEY constraints into AT_AddIndex subcommands. This lets * us schedule creation of the index at the appropriate time during ALTER. + * + * Return value is the address of the new index. */ -static void +static ObjectAddress ATExecAddIndex(AlteredTableInfo *tab, Relation rel, IndexStmt *stmt, bool is_rebuild, LOCKMODE lockmode) { @@ -5772,12 +5867,16 @@ ATExecAddIndex(AlteredTableInfo *tab, Relation rel, RelationPreserveStorage(irel->rd_node, true); index_close(irel, NoLock); } + + return address; } /* * ALTER TABLE ADD CONSTRAINT USING INDEX + * + * Returns the address of the new constraint. */ -static void +static ObjectAddress ATExecAddIndexConstraint(AlteredTableInfo *tab, Relation rel, IndexStmt *stmt, LOCKMODE lockmode) { @@ -5787,6 +5886,7 @@ ATExecAddIndexConstraint(AlteredTableInfo *tab, Relation rel, IndexInfo *indexInfo; char *constraintName; char constraintType; + ObjectAddress address; Assert(IsA(stmt, IndexStmt)); Assert(OidIsValid(index_oid)); @@ -5831,30 +5931,37 @@ ATExecAddIndexConstraint(AlteredTableInfo *tab, Relation rel, constraintType = CONSTRAINT_UNIQUE; /* Create the catalog entries for the constraint */ - index_constraint_create(rel, - index_oid, - indexInfo, - constraintName, - constraintType, - stmt->deferrable, - stmt->initdeferred, - stmt->primary, - true, /* update pg_index */ - true, /* remove old dependencies */ - allowSystemTableMods, - false); /* is_internal */ + address = index_constraint_create(rel, + index_oid, + indexInfo, + constraintName, + constraintType, + stmt->deferrable, + stmt->initdeferred, + stmt->primary, + true, /* update pg_index */ + true, /* remove old dependencies */ + allowSystemTableMods, + false); /* is_internal */ index_close(indexRel, NoLock); + + return address; } /* * ALTER TABLE ADD CONSTRAINT + * + * Return value is the address of the new constraint; if no constraint was + * added, InvalidObjectAddress is returned. */ -static void +static ObjectAddress ATExecAddConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, Constraint *newConstraint, bool recurse, bool is_readd, LOCKMODE lockmode) { + ObjectAddress address = InvalidObjectAddress; + Assert(IsA(newConstraint, Constraint)); /* @@ -5865,9 +5972,10 @@ ATExecAddConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, switch (newConstraint->contype) { case CONSTR_CHECK: - ATAddCheckConstraint(wqueue, tab, rel, - newConstraint, recurse, false, is_readd, - lockmode); + address = + ATAddCheckConstraint(wqueue, tab, rel, + newConstraint, recurse, false, is_readd, + lockmode); break; case CONSTR_FOREIGN: @@ -5898,17 +6006,22 @@ ATExecAddConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, RelationGetNamespace(rel), NIL); - ATAddForeignKeyConstraint(tab, rel, newConstraint, lockmode); + address = ATAddForeignKeyConstraint(tab, rel, newConstraint, + lockmode); break; default: elog(ERROR, "unrecognized constraint type: %d", (int) newConstraint->contype); } + + return address; } /* - * Add a check constraint to a single table and its children + * Add a check constraint to a single table and its children. Returns the + * address of the constraint added to the parent relation, if one gets added, + * or InvalidObjectAddress otherwise. * * Subroutine for ATExecAddConstraint. * @@ -5927,7 +6040,7 @@ ATExecAddConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, * "is_readd" flag for that; just setting recurse=false would result in an * error if there are child tables. */ -static void +static ObjectAddress ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, Constraint *constr, bool recurse, bool recursing, bool is_readd, LOCKMODE lockmode) @@ -5936,6 +6049,7 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, ListCell *lcon; List *children; ListCell *child; + ObjectAddress address = InvalidObjectAddress; /* At top level, permission check was done in ATPrepCmd, else do it */ if (recursing) @@ -5957,6 +6071,9 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, !recursing, /* is_local */ is_readd); /* is_internal */ + /* we don't expect more than one constraint here */ + Assert(list_length(newcons) <= 1); + /* Add each to-be-validated constraint to Phase 3's queue */ foreach(lcon, newcons) { @@ -5978,6 +6095,8 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, /* Save the actually assigned name if it was defaulted */ if (constr->conname == NULL) constr->conname = ccon->name; + + ObjectAddressSet(address, ConstraintRelationId, ccon->conoid); } /* At this point we must have a locked-down name to use */ @@ -5993,7 +6112,7 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, * incorrect value for coninhcount. */ if (newcons == NIL) - return; + return address; /* * If adding a NO INHERIT constraint, no need to find our children. @@ -6001,7 +6120,7 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, * handled at higher levels). */ if (constr->is_no_inherit || is_readd) - return; + return address; /* * Propagate to children as appropriate. Unlike most other ALTER @@ -6039,16 +6158,19 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, heap_close(childrel, NoLock); } + + return address; } /* - * Add a foreign-key constraint to a single table + * Add a foreign-key constraint to a single table; return the new constraint's + * address. * * Subroutine for ATExecAddConstraint. Must already hold exclusive * lock on the rel, and have done appropriate validity checks for it. * We do permissions checks here, however. */ -static void +static ObjectAddress ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel, Constraint *fkconstraint, LOCKMODE lockmode) { @@ -6067,6 +6189,7 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel, Oid indexOid; Oid constrOid; bool old_check_ok; + ObjectAddress address; ListCell *old_pfeqop_item = list_head(fkconstraint->old_conpfeqop); /* @@ -6414,6 +6537,7 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel, 0, /* inhcount */ true, /* isnoinherit */ false); /* is_internal */ + ObjectAddressSet(address, ConstraintRelationId, constrOid); /* * Create the triggers that will enforce the constraint. @@ -6447,6 +6571,8 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel, * Close pk table, but keep lock until we've committed. */ heap_close(pkrel, NoLock); + + return address; } /* @@ -6458,8 +6584,11 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel, * Foreign keys do not inherit, so we purposely ignore the * recursion bit here, but we keep the API the same for when * other constraint types are supported. + * + * If the constraint is modified, returns its address; otherwise, return + * InvalidObjectAddress. */ -static void +static ObjectAddress ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd, bool recurse, bool recursing, LOCKMODE lockmode) { @@ -6470,6 +6599,7 @@ ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd, Form_pg_constraint currcon = NULL; Constraint *cmdcon = NULL; bool found = false; + ObjectAddress address; Assert(IsA(cmd->def, Constraint)); cmdcon = (Constraint *) cmd->def; @@ -6571,11 +6701,18 @@ ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd, * Invalidate relcache so that others see the new attributes. */ CacheInvalidateRelcache(rel); + + ObjectAddressSet(address, ConstraintRelationId, + HeapTupleGetOid(contuple)); } + else + address = InvalidObjectAddress; systable_endscan(scan); heap_close(conrel, RowExclusiveLock); + + return address; } /* @@ -6585,8 +6722,11 @@ ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd, * there's no good way to skip recursing when handling foreign keys: there is * no need to lock children in that case, yet we wouldn't be able to avoid * doing so at that level. + * + * Return value is the address of the validated constraint. If the constraint + * was already validated, InvalidObjectAddress is returned. */ -static void +static ObjectAddress ATExecValidateConstraint(Relation rel, char *constrName, bool recurse, bool recursing, LOCKMODE lockmode) { @@ -6596,6 +6736,7 @@ ATExecValidateConstraint(Relation rel, char *constrName, bool recurse, HeapTuple tuple; Form_pg_constraint con = NULL; bool found = false; + ObjectAddress address; conrel = heap_open(ConstraintRelationId, RowExclusiveLock); @@ -6639,7 +6780,6 @@ ATExecValidateConstraint(Relation rel, char *constrName, bool recurse, if (con->contype == CONSTRAINT_FOREIGN) { - Oid conid = HeapTupleGetOid(tuple); Relation refrel; /* @@ -6654,7 +6794,7 @@ ATExecValidateConstraint(Relation rel, char *constrName, bool recurse, validateForeignKeyConstraint(constrName, rel, refrel, con->conindid, - conid); + HeapTupleGetOid(tuple)); heap_close(refrel, NoLock); /* @@ -6730,11 +6870,18 @@ ATExecValidateConstraint(Relation rel, char *constrName, bool recurse, HeapTupleGetOid(tuple), 0); heap_freetuple(copyTuple); + + ObjectAddressSet(address, ConstraintRelationId, + HeapTupleGetOid(tuple)); } + else + address = InvalidObjectAddress; /* already validated */ systable_endscan(scan); heap_close(conrel, RowExclusiveLock); + + return address; } @@ -7825,7 +7972,12 @@ ATColumnChangeRequiresRewrite(Node *expr, AttrNumber varattno) } } -static void +/* + * ALTER COLUMN .. SET DATA TYPE + * + * Return the address of the modified column. + */ +static ObjectAddress ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, AlterTableCmd *cmd, LOCKMODE lockmode) { @@ -7846,6 +7998,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, ScanKeyData key[3]; SysScanDesc scan; HeapTuple depTup; + ObjectAddress address; attrelation = heap_open(AttributeRelationId, RowExclusiveLock); @@ -8217,11 +8370,19 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, StoreAttrDefault(rel, attnum, defaultexpr, true); } + ObjectAddressSubSet(address, RelationRelationId, + RelationGetRelid(rel), attnum); + /* Cleanup */ heap_freetuple(heapTup); + + return address; } -static void +/* + * Returns the address of the modified column + */ +static ObjectAddress ATExecAlterColumnGenericOptions(Relation rel, const char *colName, List *options, @@ -8240,9 +8401,11 @@ ATExecAlterColumnGenericOptions(Relation rel, Datum datum; Form_pg_foreign_table fttableform; Form_pg_attribute atttableform; + AttrNumber attnum; + ObjectAddress address; if (options == NIL) - return; + return InvalidObjectAddress; /* First, determine FDW validator associated to the foreign table. */ ftrel = heap_open(ForeignTableRelationId, AccessShareLock); @@ -8269,7 +8432,8 @@ ATExecAlterColumnGenericOptions(Relation rel, /* Prevent them from altering a system attribute */ atttableform = (Form_pg_attribute) GETSTRUCT(tuple); - if (atttableform->attnum <= 0) + attnum = atttableform->attnum; + if (attnum <= 0) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot alter system column \"%s\"", colName))); @@ -8312,12 +8476,16 @@ ATExecAlterColumnGenericOptions(Relation rel, InvokeObjectPostAlterHook(RelationRelationId, RelationGetRelid(rel), atttableform->attnum); + ObjectAddressSubSet(address, RelationRelationId, + RelationGetRelid(rel), attnum); ReleaseSysCache(tuple); heap_close(attrel, RowExclusiveLock); heap_freetuple(newtuple); + + return address; } /* @@ -8958,11 +9126,14 @@ change_owner_recurse_to_sequences(Oid relationOid, Oid newOwnerId, LOCKMODE lock * ALTER TABLE CLUSTER ON * * The only thing we have to do is to change the indisclustered bits. + * + * Return the address of the new clustering index. */ -static void +static ObjectAddress ATExecClusterOn(Relation rel, const char *indexName, LOCKMODE lockmode) { Oid indexOid; + ObjectAddress address; indexOid = get_relname_relid(indexName, rel->rd_rel->relnamespace); @@ -8977,6 +9148,11 @@ ATExecClusterOn(Relation rel, const char *indexName, LOCKMODE lockmode) /* And do the work */ mark_index_clustered(rel, indexOid, false); + + ObjectAddressSet(address, + RelationRelationId, indexOid); + + return address; } /* @@ -9677,7 +9853,10 @@ ATPrepAddInherit(Relation child_rel) errmsg("cannot change inheritance of typed table"))); } -static void +/* + * Return the address of the new parent relation. + */ +static ObjectAddress ATExecAddInherit(Relation child_rel, RangeVar *parent, LOCKMODE lockmode) { Relation parent_rel, @@ -9687,6 +9866,7 @@ ATExecAddInherit(Relation child_rel, RangeVar *parent, LOCKMODE lockmode) HeapTuple inheritsTuple; int32 inhseqno; List *children; + ObjectAddress address; /* * A self-exclusive lock is needed here. See the similar case in @@ -9801,11 +9981,16 @@ ATExecAddInherit(Relation child_rel, RangeVar *parent, LOCKMODE lockmode) inhseqno + 1, catalogRelation); + ObjectAddressSet(address, RelationRelationId, + RelationGetRelid(parent_rel)); + /* Now we're done with pg_inherits */ heap_close(catalogRelation, RowExclusiveLock); /* keep our lock on the parent relation until commit */ heap_close(parent_rel, NoLock); + + return address; } /* @@ -10073,11 +10258,14 @@ MergeConstraintsIntoExisting(Relation child_rel, Relation parent_rel) * * coninhcount and conislocal for inherited constraints are adjusted in * exactly the same way. + * + * Return value is the OID of the relation that is no longer parent. */ -static void +static ObjectAddress ATExecDropInherit(Relation rel, RangeVar *parent, LOCKMODE lockmode) { Relation parent_rel; + Oid parent_oid; Relation catalogRelation; SysScanDesc scan; ScanKeyData key[3]; @@ -10086,6 +10274,7 @@ ATExecDropInherit(Relation rel, RangeVar *parent, LOCKMODE lockmode) constraintTuple; List *connames; bool found = false; + ObjectAddress address; /* * AccessShareLock on the parent is probably enough, seeing that DROP @@ -10246,6 +10435,8 @@ ATExecDropInherit(Relation rel, RangeVar *parent, LOCKMODE lockmode) } } + parent_oid = RelationGetRelid(parent_rel); + systable_endscan(scan); heap_close(catalogRelation, RowExclusiveLock); @@ -10264,6 +10455,10 @@ ATExecDropInherit(Relation rel, RangeVar *parent, LOCKMODE lockmode) /* keep our lock on the parent relation until commit */ heap_close(parent_rel, NoLock); + + ObjectAddressSet(address, RelationRelationId, parent_oid); + + return address; } /* @@ -10321,8 +10516,10 @@ drop_parent_dependency(Oid relid, Oid refclassid, Oid refobjid) * TABLE OF. All attname, atttypid, atttypmod and attcollation must match. The * subject table must not have inheritance parents. These restrictions ensure * that you cannot create a configuration impossible with CREATE TABLE OF alone. + * + * The address of the type is returned. */ -static void +static ObjectAddress ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKMODE lockmode) { Oid relid = RelationGetRelid(rel); @@ -10451,6 +10648,8 @@ ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKMODE lockmode) heap_close(relationRelation, RowExclusiveLock); ReleaseSysCache(typetuple); + + return typeobj; } /* diff --git a/src/include/catalog/heap.h b/src/include/catalog/heap.h index 573b2deb2d08434f6fe4b78d26193748762a1c54..e6ac3943fcb66e58614e1b825b4597d0a90761eb 100644 --- a/src/include/catalog/heap.h +++ b/src/include/catalog/heap.h @@ -28,6 +28,7 @@ typedef struct RawColumnDefault typedef struct CookedConstraint { ConstrType contype; /* CONSTR_DEFAULT or CONSTR_CHECK */ + Oid conoid; /* constr OID if created, otherwise Invalid */ char *name; /* name, or NULL if none */ AttrNumber attnum; /* which attr (only for DEFAULT) */ Node *expr; /* transformed default or check expr */ @@ -101,7 +102,7 @@ extern List *AddRelationNewConstraints(Relation rel, bool is_local, bool is_internal); -extern void StoreAttrDefault(Relation rel, AttrNumber attnum, +extern Oid StoreAttrDefault(Relation rel, AttrNumber attnum, Node *expr, bool is_internal); extern Node *cookDefault(ParseState *pstate, diff --git a/src/include/catalog/index.h b/src/include/catalog/index.h index e7cc7a0f7b1d6cb7af0e32673c877aa8de07c44d..a04def96e4cadd6cc569e59d74ee216ee1979ff7 100644 --- a/src/include/catalog/index.h +++ b/src/include/catalog/index.h @@ -14,6 +14,7 @@ #ifndef INDEX_H #define INDEX_H +#include "catalog/objectaddress.h" #include "nodes/execnodes.h" @@ -63,7 +64,7 @@ extern Oid index_create(Relation heapRelation, bool is_internal, bool if_not_exists); -extern void index_constraint_create(Relation heapRelation, +extern ObjectAddress index_constraint_create(Relation heapRelation, Oid indexRelationId, IndexInfo *indexInfo, const char *constraintName,