Hi,
I think ExplainModifyTarget should show the parent of the inheritance
tree in multi-target-table cases, as described there, but noticed that
it doesn't always work like that. Here is an example.
postgres=# create table parent (a int check (a < 0) no inherit);
CREATE TABLE
postgres=# create table child (a int check (a >= 0));
CREATE TABLE
postgres=# alter table child inherit parent;
ALTER TABLE
postgres=# explain update parent set a = a * 2 where a >= 0;
QUERY PLAN
---------------------------------------------------------------
Update on child (cost=0.00..42.00 rows=800 width=10)
-> Seq Scan on child (cost=0.00..42.00 rows=800 width=10)
Filter: (a >= 0)
(3 rows)
IIUC, I think this is because ExplainModifyTarget doesn't take into
account that the parent *can* be excluded by constraint exclusion. So,
I added a field to ModifyTable to record the parent, apart from
resultRelations. (More precisely, the parent in its role as a simple
member of the inheritance tree is recorded so that appending digits to
refname in select_rtable_names_for_explain works as before.) Attached
is a proposed patch for that.
Thanks,
Best regards,
Etsuro Fujita
*** a/src/backend/commands/explain.c
--- b/src/backend/commands/explain.c
***************
*** 728,736 **** ExplainPreScanNode(PlanState *planstate, Bitmapset **rels_used)
((Scan *) plan)->scanrelid);
break;
case T_ModifyTable:
- /* cf ExplainModifyTarget */
*rels_used = bms_add_member(*rels_used,
! linitial_int(((ModifyTable *) plan)->resultRelations));
break;
default:
break;
--- 728,735 ----
((Scan *) plan)->scanrelid);
break;
case T_ModifyTable:
*rels_used = bms_add_member(*rels_used,
! ((ModifyTable *) plan)->resultRelation);
break;
default:
break;
***************
*** 2109,2122 **** ExplainScanTarget(Scan *plan, ExplainState *es)
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);
}
--- 2108,2114 ----
static void
ExplainModifyTarget(ModifyTable *plan, ExplainState *es)
{
! Index rti = plan->resultRelation;
ExplainTargetRel((Plan *) plan, rti, es);
}
*** a/src/backend/nodes/copyfuncs.c
--- b/src/backend/nodes/copyfuncs.c
***************
*** 175,180 **** _copyModifyTable(const ModifyTable *from)
--- 175,181 ----
*/
COPY_SCALAR_FIELD(operation);
COPY_SCALAR_FIELD(canSetTag);
+ COPY_SCALAR_FIELD(resultRelation);
COPY_NODE_FIELD(resultRelations);
COPY_SCALAR_FIELD(resultRelIndex);
COPY_NODE_FIELD(plans);
*** a/src/backend/nodes/outfuncs.c
--- b/src/backend/nodes/outfuncs.c
***************
*** 327,332 **** _outModifyTable(StringInfo str, const ModifyTable *node)
--- 327,333 ----
WRITE_ENUM_FIELD(operation, CmdType);
WRITE_BOOL_FIELD(canSetTag);
+ WRITE_UINT_FIELD(resultRelation);
WRITE_NODE_FIELD(resultRelations);
WRITE_INT_FIELD(resultRelIndex);
WRITE_NODE_FIELD(plans);
*** a/src/backend/optimizer/plan/createplan.c
--- b/src/backend/optimizer/plan/createplan.c
***************
*** 4809,4814 **** make_result(PlannerInfo *root,
--- 4809,4815 ----
ModifyTable *
make_modifytable(PlannerInfo *root,
CmdType operation, bool canSetTag,
+ Index resultRelation,
List *resultRelations, List *subplans,
List *withCheckOptionLists, List *returningLists,
List *rowMarks, int epqParam)
***************
*** 4857,4862 **** make_modifytable(PlannerInfo *root,
--- 4858,4864 ----
node->operation = operation;
node->canSetTag = canSetTag;
+ node->resultRelation = resultRelation;
node->resultRelations = resultRelations;
node->resultRelIndex = -1; /* will be set correctly in setrefs.c */
node->plans = subplans;
*** a/src/backend/optimizer/plan/planner.c
--- b/src/backend/optimizer/plan/planner.c
***************
*** 607,612 **** subquery_planner(PlannerGlobal *glob, Query *parse,
--- 607,613 ----
plan = (Plan *) make_modifytable(root,
parse->commandType,
parse->canSetTag,
+ parse->resultRelation,
list_make1_int(parse->resultRelation),
list_make1(plan),
withCheckOptionLists,
***************
*** 790,795 **** inheritance_planner(PlannerInfo *root)
--- 791,797 ----
{
Query *parse = root->parse;
int parentRTindex = parse->resultRelation;
+ int pseudoParentRTindex = -1;
List *final_rtable = NIL;
int save_rel_array_size = 0;
RelOptInfo **save_rel_array = NULL;
***************
*** 925,930 **** inheritance_planner(PlannerInfo *root)
--- 927,940 ----
appinfo->child_relid = subroot.parse->resultRelation;
/*
+ * If this child rel was the first target relation, it should always be
+ * the parent rel in its role as a simple member of the inheritance set.
+ * Get it for use of EXPLAIN.
+ */
+ if (pseudoParentRTindex == -1)
+ pseudoParentRTindex = appinfo->child_relid;
+
+ /*
* If this child rel was excluded by constraint exclusion, exclude it
* from the result plan.
*/
***************
*** 1051,1056 **** inheritance_planner(PlannerInfo *root)
--- 1061,1067 ----
return (Plan *) make_modifytable(root,
parse->commandType,
parse->canSetTag,
+ pseudoParentRTindex,
resultRelations,
subplans,
withCheckOptionLists,
*** a/src/backend/optimizer/plan/setrefs.c
--- b/src/backend/optimizer/plan/setrefs.c
***************
*** 754,759 **** set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset)
--- 754,761 ----
splan->plan.targetlist = copyObject(linitial(newRL));
}
+ splan->resultRelation += rtoffset;
+
foreach(l, splan->resultRelations)
{
lfirst_int(l) += rtoffset;
*** a/src/include/nodes/plannodes.h
--- b/src/include/nodes/plannodes.h
***************
*** 174,179 **** typedef struct ModifyTable
--- 174,180 ----
Plan plan;
CmdType operation; /* INSERT, UPDATE, or DELETE */
bool canSetTag; /* do we set the command tag/es_processed? */
+ Index resultRelation; /* 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 */
*** a/src/include/optimizer/planmain.h
--- b/src/include/optimizer/planmain.h
***************
*** 82,87 **** extern Result *make_result(PlannerInfo *root, List *tlist,
--- 82,88 ----
Node *resconstantqual, Plan *subplan);
extern ModifyTable *make_modifytable(PlannerInfo *root,
CmdType operation, bool canSetTag,
+ Index resultRelation,
List *resultRelations, List *subplans,
List *withCheckOptionLists, List *returningLists,
List *rowMarks, int epqParam);
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers