summaryrefslogtreecommitdiff
path: root/src/backend/commands
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands')
-rw-r--r--src/backend/commands/tablecmds.c419
1 files changed, 309 insertions, 110 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 32e19c5e4fc..002319e8a02 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;
}
/*