PgFdwModifyState *fmstate;
ModifyTable *plan = castNode(ModifyTable, mtstate->ps.plan);
EState *estate = mtstate->ps.state;
- Index resultRelation = resultRelInfo->ri_RangeTableIndex;
+ Index resultRelation;
Relation rel = resultRelInfo->ri_RelationDesc;
RangeTblEntry *rte;
TupleDesc tupdesc = RelationGetDescr(rel);
}
/*
- * If the foreign table is a partition, we need to create a new RTE
+ * If the foreign table is a partition that doesn't have a corresponding
+ * RTE entry, we need to create a new RTE
* describing the foreign table for use by deparseInsertSql and
* create_foreign_modify() below, after first copying the parent's RTE and
* modifying some fields to describe the foreign partition to work on.
* correspond to this partition if it is one of the UPDATE subplan target
* rels; in that case, we can just use the existing RTE as-is.
*/
- rte = exec_rt_fetch(resultRelation, estate);
- if (rte->relid != RelationGetRelid(rel))
+ if (resultRelInfo->ri_RangeTableIndex == 0)
{
+ ResultRelInfo *rootResultRelInfo = resultRelInfo->ri_RootResultRelInfo;
+
+ rte = exec_rt_fetch(rootResultRelInfo->ri_RangeTableIndex, estate);
rte = copyObject(rte);
rte->relid = RelationGetRelid(rel);
rte->relkind = RELKIND_FOREIGN_TABLE;
* Vars contained in those expressions.
*/
if (plan && plan->operation == CMD_UPDATE &&
- resultRelation == plan->rootRelation)
+ rootResultRelInfo->ri_RangeTableIndex == plan->rootRelation)
resultRelation = mtstate->resultRelInfo[0].ri_RangeTableIndex;
+ else
+ resultRelation = rootResultRelInfo->ri_RangeTableIndex;
+ }
+ else
+ {
+ resultRelation = resultRelInfo->ri_RangeTableIndex;
+ rte = exec_rt_fetch(resultRelation, estate);
}
/* Construct the SQL command string. */
/* How many levels deep into trigger execution are we? */
static int MyTriggerDepth = 0;
-/*
- * Note that similar macros also exist in executor/execMain.c. There does not
- * appear to be any good header to put them into, given the structures that
- * they use, so we let them be duplicated. Be sure to update all if one needs
- * to be changed, however.
- */
-#define GetAllUpdatedColumns(relinfo, estate) \
- (bms_union(exec_rt_fetch((relinfo)->ri_RangeTableIndex, estate)->updatedCols, \
- exec_rt_fetch((relinfo)->ri_RangeTableIndex, estate)->extraUpdatedCols))
-
/* Local function prototypes */
static void ConvertTriggerToFK(CreateTrigStmt *stmt, Oid funcoid);
static void SetTriggerFlags(TriggerDesc *trigdesc, Trigger *trigger);
CMD_UPDATE))
return;
- updatedCols = GetAllUpdatedColumns(relinfo, estate);
+ /* statement-level triggers operate on the parent table */
+ Assert(relinfo->ri_RootResultRelInfo == NULL);
+
+ updatedCols = ExecGetAllUpdatedCols(relinfo, estate);
LocTriggerData.type = T_TriggerData;
LocTriggerData.tg_event = TRIGGER_EVENT_UPDATE |
{
TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
+ /* statement-level triggers operate on the parent table */
+ Assert(relinfo->ri_RootResultRelInfo == NULL);
+
if (trigdesc && trigdesc->trig_update_after_statement)
AfterTriggerSaveEvent(estate, relinfo, TRIGGER_EVENT_UPDATE,
false, NULL, NULL, NIL,
- GetAllUpdatedColumns(relinfo, estate),
+ ExecGetAllUpdatedCols(relinfo, estate),
transition_capture);
}
LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
LocTriggerData.tg_oldtable = NULL;
LocTriggerData.tg_newtable = NULL;
- updatedCols = GetAllUpdatedColumns(relinfo, estate);
+ updatedCols = ExecGetAllUpdatedCols(relinfo, estate);
for (i = 0; i < trigdesc->numtriggers; i++)
{
Trigger *trigger = &trigdesc->triggers[i];
AfterTriggerSaveEvent(estate, relinfo, TRIGGER_EVENT_UPDATE,
true, oldslot, newslot, recheckIndexes,
- GetAllUpdatedColumns(relinfo, estate),
+ ExecGetAllUpdatedCols(relinfo, estate),
transition_capture);
}
}
int maxfieldlen);
static void EvalPlanQualStart(EPQState *epqstate, Plan *planTree);
-/*
- * Note that GetAllUpdatedColumns() also exists in commands/trigger.c. There does
- * not appear to be any good header to put it into, given the structures that
- * it uses, so we let them be duplicated. Be sure to update both if one needs
- * to be changed, however.
- */
-#define GetInsertedColumns(relinfo, estate) \
- (exec_rt_fetch((relinfo)->ri_RangeTableIndex, estate)->insertedCols)
-#define GetUpdatedColumns(relinfo, estate) \
- (exec_rt_fetch((relinfo)->ri_RangeTableIndex, estate)->updatedCols)
-#define GetAllUpdatedColumns(relinfo, estate) \
- (bms_union(exec_rt_fetch((relinfo)->ri_RangeTableIndex, estate)->updatedCols, \
- exec_rt_fetch((relinfo)->ri_RangeTableIndex, estate)->extraUpdatedCols))
-
/* end of local decls */
InitResultRelInfo(ResultRelInfo *resultRelInfo,
Relation resultRelationDesc,
Index resultRelationIndex,
- Relation partition_root,
+ ResultRelInfo *partition_root_rri,
int instrument_options)
{
List *partition_check = NIL;
partition_check = RelationGetPartitionQual(resultRelationDesc);
resultRelInfo->ri_PartitionCheck = partition_check;
- resultRelInfo->ri_PartitionRoot = partition_root;
+ resultRelInfo->ri_RootResultRelInfo = partition_root_rri;
resultRelInfo->ri_PartitionInfo = NULL; /* may be set later */
resultRelInfo->ri_CopyMultiInsertBuffer = NULL;
}
* back to the root table's rowtype so that val_desc in the error message
* matches the input tuple.
*/
- if (resultRelInfo->ri_PartitionRoot)
+ if (resultRelInfo->ri_RootResultRelInfo)
{
+ ResultRelInfo *rootrel = resultRelInfo->ri_RootResultRelInfo;
TupleDesc old_tupdesc;
AttrNumber *map;
- root_relid = RelationGetRelid(resultRelInfo->ri_PartitionRoot);
- tupdesc = RelationGetDescr(resultRelInfo->ri_PartitionRoot);
+ root_relid = RelationGetRelid(rootrel->ri_RelationDesc);
+ tupdesc = RelationGetDescr(rootrel->ri_RelationDesc);
old_tupdesc = RelationGetDescr(resultRelInfo->ri_RelationDesc);
/* a reverse map */
if (map != NULL)
slot = execute_attr_map_slot(map, slot,
MakeTupleTableSlot(tupdesc, &TTSOpsVirtual));
+ modifiedCols = bms_union(ExecGetInsertedCols(rootrel, estate),
+ ExecGetUpdatedCols(rootrel, estate));
}
else
{
root_relid = RelationGetRelid(resultRelInfo->ri_RelationDesc);
tupdesc = RelationGetDescr(resultRelInfo->ri_RelationDesc);
+ modifiedCols = bms_union(ExecGetInsertedCols(resultRelInfo, estate),
+ ExecGetUpdatedCols(resultRelInfo, estate));
}
- modifiedCols = bms_union(GetInsertedColumns(resultRelInfo, estate),
- GetUpdatedColumns(resultRelInfo, estate));
-
val_desc = ExecBuildSlotValueDescription(root_relid,
slot,
tupdesc,
TupleDesc tupdesc = RelationGetDescr(rel);
TupleConstr *constr = tupdesc->constr;
Bitmapset *modifiedCols;
- Bitmapset *insertedCols;
- Bitmapset *updatedCols;
Assert(constr || resultRelInfo->ri_PartitionCheck);
* rowtype so that val_desc shown error message matches the
* input tuple.
*/
- if (resultRelInfo->ri_PartitionRoot)
+ if (resultRelInfo->ri_RootResultRelInfo)
{
+ ResultRelInfo *rootrel = resultRelInfo->ri_RootResultRelInfo;
AttrNumber *map;
- rel = resultRelInfo->ri_PartitionRoot;
- tupdesc = RelationGetDescr(rel);
+ tupdesc = RelationGetDescr(rootrel->ri_RelationDesc);
/* a reverse map */
map = convert_tuples_by_name_map_if_req(orig_tupdesc,
tupdesc,
if (map != NULL)
slot = execute_attr_map_slot(map, slot,
MakeTupleTableSlot(tupdesc, &TTSOpsVirtual));
+ modifiedCols = bms_union(ExecGetInsertedCols(rootrel, estate),
+ ExecGetUpdatedCols(rootrel, estate));
+ rel = rootrel->ri_RelationDesc;
}
-
- insertedCols = GetInsertedColumns(resultRelInfo, estate);
- updatedCols = GetUpdatedColumns(resultRelInfo, estate);
- modifiedCols = bms_union(insertedCols, updatedCols);
+ else
+ modifiedCols = bms_union(ExecGetInsertedCols(resultRelInfo, estate),
+ ExecGetUpdatedCols(resultRelInfo, estate));
val_desc = ExecBuildSlotValueDescription(RelationGetRelid(rel),
slot,
tupdesc,
Relation orig_rel = rel;
/* See the comment above. */
- if (resultRelInfo->ri_PartitionRoot)
+ if (resultRelInfo->ri_RootResultRelInfo)
{
+ ResultRelInfo *rootrel = resultRelInfo->ri_RootResultRelInfo;
TupleDesc old_tupdesc = RelationGetDescr(rel);
AttrNumber *map;
- rel = resultRelInfo->ri_PartitionRoot;
- tupdesc = RelationGetDescr(rel);
+ tupdesc = RelationGetDescr(rootrel->ri_RelationDesc);
/* a reverse map */
map = convert_tuples_by_name_map_if_req(old_tupdesc,
tupdesc,
if (map != NULL)
slot = execute_attr_map_slot(map, slot,
MakeTupleTableSlot(tupdesc, &TTSOpsVirtual));
+ modifiedCols = bms_union(ExecGetInsertedCols(rootrel, estate),
+ ExecGetUpdatedCols(rootrel, estate));
+ rel = rootrel->ri_RelationDesc;
}
-
- insertedCols = GetInsertedColumns(resultRelInfo, estate);
- updatedCols = GetUpdatedColumns(resultRelInfo, estate);
- modifiedCols = bms_union(insertedCols, updatedCols);
+ else
+ modifiedCols = bms_union(ExecGetInsertedCols(resultRelInfo, estate),
+ ExecGetUpdatedCols(resultRelInfo, estate));
val_desc = ExecBuildSlotValueDescription(RelationGetRelid(rel),
slot,
tupdesc,
{
char *val_desc;
Bitmapset *modifiedCols;
- Bitmapset *insertedCols;
- Bitmapset *updatedCols;
switch (wco->kind)
{
*/
case WCO_VIEW_CHECK:
/* See the comment in ExecConstraints(). */
- if (resultRelInfo->ri_PartitionRoot)
+ if (resultRelInfo->ri_RootResultRelInfo)
{
+ ResultRelInfo *rootrel = resultRelInfo->ri_RootResultRelInfo;
TupleDesc old_tupdesc = RelationGetDescr(rel);
AttrNumber *map;
- rel = resultRelInfo->ri_PartitionRoot;
- tupdesc = RelationGetDescr(rel);
+ tupdesc = RelationGetDescr(rootrel->ri_RelationDesc);
/* a reverse map */
map = convert_tuples_by_name_map_if_req(old_tupdesc,
tupdesc,
if (map != NULL)
slot = execute_attr_map_slot(map, slot,
MakeTupleTableSlot(tupdesc, &TTSOpsVirtual));
- }
- insertedCols = GetInsertedColumns(resultRelInfo, estate);
- updatedCols = GetUpdatedColumns(resultRelInfo, estate);
- modifiedCols = bms_union(insertedCols, updatedCols);
+ modifiedCols = bms_union(ExecGetInsertedCols(rootrel, estate),
+ ExecGetUpdatedCols(rootrel, estate));
+ rel = rootrel->ri_RelationDesc;
+ }
+ else
+ modifiedCols = bms_union(ExecGetInsertedCols(resultRelInfo, estate),
+ ExecGetUpdatedCols(resultRelInfo, estate));
val_desc = ExecBuildSlotValueDescription(RelationGetRelid(rel),
slot,
tupdesc,
* been modified, then we can use a weaker lock, allowing for better
* concurrency.
*/
- updatedCols = GetAllUpdatedColumns(relinfo, estate);
+ updatedCols = ExecGetAllUpdatedCols(relinfo, estate);
keyCols = RelationGetIndexAttrBitmap(relinfo->ri_RelationDesc,
INDEX_ATTR_BITMAP_KEY);