((Scan *) plan)->scanrelid);
break;
case T_ModifyTable:
- /* cf ExplainModifyTarget */
*rels_used = bms_add_member(*rels_used,
- linitial_int(((ModifyTable *) plan)->resultRelations));
+ ((ModifyTable *) plan)->nominalRelation);
break;
default:
break;
static void
ExplainModifyTarget(ModifyTable *plan, ExplainState *es)
{
- Index rti;
-
- /*
- * We show the name of the first target relation. In multi-target-table
- * cases this should always be the parent of the inheritance tree.
- */
- Assert(plan->resultRelations != NIL);
- rti = linitial_int(plan->resultRelations);
-
- ExplainTargetRel((Plan *) plan, rti, es);
+ ExplainTargetRel((Plan *) plan, plan->nominalRelation, es);
}
/*
*/
COPY_SCALAR_FIELD(operation);
COPY_SCALAR_FIELD(canSetTag);
+ COPY_SCALAR_FIELD(nominalRelation);
COPY_NODE_FIELD(resultRelations);
COPY_SCALAR_FIELD(resultRelIndex);
COPY_NODE_FIELD(plans);
WRITE_ENUM_FIELD(operation, CmdType);
WRITE_BOOL_FIELD(canSetTag);
+ WRITE_UINT_FIELD(nominalRelation);
WRITE_NODE_FIELD(resultRelations);
WRITE_INT_FIELD(resultRelIndex);
WRITE_NODE_FIELD(plans);
ModifyTable *
make_modifytable(PlannerInfo *root,
CmdType operation, bool canSetTag,
+ Index nominalRelation,
List *resultRelations, List *subplans,
List *withCheckOptionLists, List *returningLists,
List *rowMarks, int epqParam)
node->operation = operation;
node->canSetTag = canSetTag;
+ node->nominalRelation = nominalRelation;
node->resultRelations = resultRelations;
node->resultRelIndex = -1; /* will be set correctly in setrefs.c */
node->plans = subplans;
plan = (Plan *) make_modifytable(root,
parse->commandType,
parse->canSetTag,
+ parse->resultRelation,
list_make1_int(parse->resultRelation),
list_make1(plan),
withCheckOptionLists,
{
Query *parse = root->parse;
int parentRTindex = parse->resultRelation;
+ int nominalRelation = -1;
List *final_rtable = NIL;
int save_rel_array_size = 0;
RelOptInfo **save_rel_array = NULL;
*/
appinfo->child_relid = subroot.parse->resultRelation;
+ /*
+ * We'll use the first child relation (even if it's excluded) as the
+ * nominal target relation of the ModifyTable node. Because of the
+ * way expand_inherited_rtentry works, this should always be the RTE
+ * representing the parent table in its role as a simple member of the
+ * inheritance set. (It would be logically cleaner to use the
+ * inheritance parent RTE as the nominal target; but since that RTE
+ * will not be otherwise referenced in the plan, doing so would give
+ * rise to confusing use of multiple aliases in EXPLAIN output for
+ * what the user will think is the "same" table.)
+ */
+ if (nominalRelation < 0)
+ nominalRelation = appinfo->child_relid;
+
/*
* If this child rel was excluded by constraint exclusion, exclude it
* from the result plan.
return (Plan *) make_modifytable(root,
parse->commandType,
parse->canSetTag,
+ nominalRelation,
resultRelations,
subplans,
withCheckOptionLists,
newrc->markType = ROW_MARK_REFERENCE;
else
newrc->markType = ROW_MARK_COPY;
- newrc->waitPolicy = LockWaitBlock; /* doesn't matter */
+ newrc->waitPolicy = LockWaitBlock; /* doesn't matter */
newrc->isParent = false;
prowmarks = lappend(prowmarks, newrc);
splan->plan.targetlist = copyObject(linitial(newRL));
}
+ splan->nominalRelation += rtoffset;
+
foreach(l, splan->resultRelations)
{
lfirst_int(l) += rtoffset;
int nParamExec; /* number of PARAM_EXEC Params used */
- bool hasRowSecurity; /* row security applied? */
+ bool hasRowSecurity; /* row security applied? */
} PlannedStmt;
Plan plan;
CmdType operation; /* INSERT, UPDATE, or DELETE */
bool canSetTag; /* do we set the command tag/es_processed? */
+ Index nominalRelation; /* Parent RT index for use of EXPLAIN */
List *resultRelations; /* integer list of RT indexes */
int resultRelIndex; /* index of first resultRel in plan's list */
List *plans; /* plan(s) producing source data */
Node *resconstantqual, Plan *subplan);
extern ModifyTable *make_modifytable(PlannerInfo *root,
CmdType operation, bool canSetTag,
+ Index nominalRelation,
List *resultRelations, List *subplans,
List *withCheckOptionLists, List *returningLists,
List *rowMarks, int epqParam);