On 2019/04/19 2:25, Tom Lane wrote: > Amit Langote <langote_amit...@lab.ntt.co.jp> writes: >> Another idea is to teach explain.c about this special case of run-time >> pruning having pruned all child subplans even though appendplans contains >> one element to cater for targetlist accesses. That is, Append will be >> displayed with "Subplans Removed: All" and no child subplans listed below >> it, even though appendplans[] has one. David already said he didn't do in >> the first place to avoid PartitionPruneInfo details creeping into other >> modules, but maybe there's no other way? > > I tried simply removing the hack in nodeAppend.c (per quick-hack patch > below), and it gets through the core regression tests without a crash, > and with output diffs that seem fine to me. However, that just shows that > we lack enough test coverage; we evidently have no regression cases where > an upper node needs to print Vars that are coming from a fully-pruned > Append. Given the test case mentioned in this thread, I get > > regression=# explain verbose select * from t1 where dt = current_date + 400; > QUERY PLAN > --------------------------------------------- > Append (cost=0.00..198.42 rows=44 width=8) > Subplans Removed: 4 > (2 rows) > > which seems fine, but > > regression=# explain verbose select * from t1 where dt = current_date + 400 > order by id; > psql: server closed the connection unexpectedly > > It's dying trying to resolve Vars in the Sort node, of course.
Another approach, as I mentioned above, is to extend the hack that begins in nodeAppend.c (and nodeMergeAppend.c) into explain.c, as in the attached. Then: explain verbose select * from t1 where dt = current_date + 400 order by id; QUERY PLAN ─────────────────────────────────────────────────── Sort (cost=199.62..199.73 rows=44 width=8) Output: t1_1.id, t1_1.dt Sort Key: t1_1.id -> Append (cost=0.00..198.42 rows=44 width=8) Subplans Removed: 4 (5 rows) It's pretty confusing to see t1_1 which has been pruned away, but you didn't seem very interested in the idea of teaching explain.c to use the original target list of plans like Append, MergeAppend, etc. that have child subplans. Just a note: runtime pruning for MergeAppend is new in PG 12. Thanks, Amit
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index a6c6de78f1..5a494fd4b6 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -1981,16 +1981,27 @@ ExplainNode(PlanState *planstate, List *ancestors, ancestors, es); break; case T_Append: - ExplainMemberNodes(((AppendState *) planstate)->appendplans, - ((AppendState *) planstate)->as_nplans, - list_length(((Append *) plan)->appendplans), - ancestors, es); + { + AppendState *astate = (AppendState *) planstate; + /* Runtime pruning may have pruned all partitions. */ + int nsubnodes = astate->as_whichplan == NO_MATCHING_SUBPLANS ? + 0 : astate->as_nplans; + + ExplainMemberNodes(astate->appendplans, nsubnodes, + list_length(((Append *) plan)->appendplans), + ancestors, es); + } break; case T_MergeAppend: - ExplainMemberNodes(((MergeAppendState *) planstate)->mergeplans, - ((MergeAppendState *) planstate)->ms_nplans, - list_length(((MergeAppend *) plan)->mergeplans), - ancestors, es); + { + MergeAppendState *mastate = (MergeAppendState *) planstate; + /* Runtime pruning may have pruned all partitions. */ + int nsubnodes = mastate->ms_noopscan ? 0 : mastate->ms_nplans; + + ExplainMemberNodes(mastate->mergeplans, nsubnodes, + list_length(((MergeAppend *) plan)->mergeplans), + ancestors, es); + } break; case T_BitmapAnd: ExplainMemberNodes(((BitmapAndState *) planstate)->bitmapplans, diff --git a/src/backend/executor/nodeAppend.c b/src/backend/executor/nodeAppend.c index f3be2429db..c12f5161e7 100644 --- a/src/backend/executor/nodeAppend.c +++ b/src/backend/executor/nodeAppend.c @@ -78,7 +78,6 @@ struct ParallelAppendState }; #define INVALID_SUBPLAN_INDEX -1 -#define NO_MATCHING_SUBPLANS -2 static TupleTableSlot *ExecAppend(PlanState *pstate); static bool choose_next_subplan_locally(AppendState *node); diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index a5e4b7ef2e..40e019b395 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -1155,6 +1155,9 @@ typedef struct ModifyTableState * ---------------- */ +/* Exported for explain.c to use. */ +#define NO_MATCHING_SUBPLANS -2 + struct AppendState; typedef struct AppendState AppendState; struct ParallelAppendState;