From a9998cf54fe3e4277ef7431213179d1b811132a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E6=8C=83?= Date: Fri, 24 Apr 2020 10:48:24 +0800 Subject: [PATCH v1] Add a Material Path for subplan and reused the previous result if the inputed params is not changed. PoC only --- src/backend/executor/nodeMaterial.c | 10 +++++++++- src/backend/executor/nodeSubplan.c | 2 +- src/backend/optimizer/plan/subselect.c | 4 ++++ src/backend/optimizer/util/pathnode.c | 2 +- src/backend/utils/sort/tuplestore.c | 2 +- 5 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/backend/executor/nodeMaterial.c b/src/backend/executor/nodeMaterial.c index dd077f4323..67066686b8 100644 --- a/src/backend/executor/nodeMaterial.c +++ b/src/backend/executor/nodeMaterial.c @@ -59,7 +59,7 @@ ExecMaterial(PlanState *pstate) /* * If first time through, and we need a tuplestore, initialize it. */ - if (tuplestorestate == NULL && node->eflags != 0) + if (tuplestorestate == NULL) { tuplestorestate = tuplestore_begin_heap(true, false, work_mem); tuplestore_set_eflags(tuplestorestate, node->eflags); @@ -321,6 +321,14 @@ ExecReScanMaterial(MaterialState *node) ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); + /* Param is not changed, and all the underlying rows is fetched, + * We reuses current data */ + if (outerPlan->chgParam == NULL && node->eof_underlying) + { + tuplestore_rescan(node->tuplestorestate); + return; + } + if (node->eflags != 0) { /* diff --git a/src/backend/executor/nodeSubplan.c b/src/backend/executor/nodeSubplan.c index 298b7757f5..35b9a3b2ce 100644 --- a/src/backend/executor/nodeSubplan.c +++ b/src/backend/executor/nodeSubplan.c @@ -288,7 +288,7 @@ ExecScanSubPlan(SubPlanState *node, prm->value = ExecEvalExprSwitchContext((ExprState *) lfirst(pvar), econtext, &(prm->isnull)); - planstate->chgParam = bms_add_member(planstate->chgParam, paramid); + // planstate->chgParam = bms_add_member(planstate->chgParam, paramid); } /* diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c index b02fcb9bfe..0b00de175e 100644 --- a/src/backend/optimizer/plan/subselect.c +++ b/src/backend/optimizer/plan/subselect.c @@ -23,6 +23,7 @@ #include "miscadmin.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" +#include "nodes/bitmapset.h" #include "optimizer/clauses.h" #include "optimizer/cost.h" #include "optimizer/optimizer.h" @@ -232,6 +233,9 @@ make_subplan(PlannerInfo *root, Query *orig_subquery, final_rel = fetch_upper_rel(subroot, UPPERREL_FINAL, NULL); best_path = get_cheapest_fractional_path(final_rel, tuple_fraction); + if (linitial_node(RangeTblEntry, root->parse->rtable)->relid == 25634) + best_path = (Path *) create_material_path(final_rel, best_path); + plan = create_plan(subroot, best_path); /* And convert to SubPlan or InitPlan format. */ diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c index e991385059..8d4946c45c 100644 --- a/src/backend/optimizer/util/pathnode.c +++ b/src/backend/optimizer/util/pathnode.c @@ -1496,7 +1496,7 @@ create_material_path(RelOptInfo *rel, Path *subpath) { MaterialPath *pathnode = makeNode(MaterialPath); - Assert(subpath->parent == rel); + // Assert(subpath->parent == rel); pathnode->path.pathtype = T_Material; pathnode->path.parent = rel; diff --git a/src/backend/utils/sort/tuplestore.c b/src/backend/utils/sort/tuplestore.c index ebb1da0746..df00b15aee 100644 --- a/src/backend/utils/sort/tuplestore.c +++ b/src/backend/utils/sort/tuplestore.c @@ -1234,7 +1234,7 @@ tuplestore_rescan(Tuplestorestate *state) { TSReadPointer *readptr = &state->readptrs[state->activeptr]; - Assert(readptr->eflags & EXEC_FLAG_REWIND); + // Assert(readptr->eflags & EXEC_FLAG_REWIND); Assert(!state->truncated); switch (state->status) -- 2.21.0