From 1957f8dabf8daa29c78d05f971dd665c9680a754 Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Tue, 24 Apr 2018 14:03:10 -0300 Subject: Initialize ExprStates once in run-time partition pruning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of doing ExecInitExpr every time a Param needs to be evaluated in run-time partition pruning, do it once during run-time pruning set-up and cache the exprstate in PartitionPruneContext, saving a lot of work. Author: David Rowley Reviewed-by: Amit Langote, Álvaro Herrera Discussion: https://postgr.es/m/CAKJS1f8-x+q-90QAPDu_okhQBV4DPEtPz8CJ=m0940GyT4DA4w@mail.gmail.com --- src/backend/executor/execPartition.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'src/backend/executor/execPartition.c') diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c index f7bbb804aae..f7418f64b18 100644 --- a/src/backend/executor/execPartition.c +++ b/src/backend/executor/execPartition.c @@ -1442,7 +1442,9 @@ ExecSetupPartitionPruneState(PlanState *planstate, List *partitionpruneinfo) PartitionDesc partdesc; Relation rel; PartitionKey partkey; + ListCell *lc2; int partnatts; + int n_steps; pprune->present_parts = bms_copy(pinfo->present_parts); pprune->subnode_map = palloc(sizeof(int) * pinfo->nparts); @@ -1465,6 +1467,7 @@ ExecSetupPartitionPruneState(PlanState *planstate, List *partitionpruneinfo) partkey = RelationGetPartitionKey(rel); partdesc = RelationGetPartitionDesc(rel); + n_steps = list_length(pinfo->pruning_steps); context->strategy = partkey->strategy; context->partnatts = partnatts = partkey->partnatts; @@ -1476,6 +1479,38 @@ ExecSetupPartitionPruneState(PlanState *planstate, List *partitionpruneinfo) context->boundinfo = partition_bounds_copy(partdesc->boundinfo, partkey); context->planstate = planstate; context->safeparams = NULL; /* empty for now */ + context->exprstates = palloc0(sizeof(ExprState *) * n_steps * partnatts); + + /* Initialize expression states for each expression */ + foreach(lc2, pinfo->pruning_steps) + { + PartitionPruneStepOp *step = (PartitionPruneStepOp *) lfirst(lc2); + ListCell *lc3; + int keyno; + + /* not needed for other step kinds */ + if (!IsA(step, PartitionPruneStepOp)) + continue; + + Assert(list_length(step->exprs) <= partnatts); + + keyno = 0; + foreach(lc3, step->exprs) + { + Expr *expr = (Expr *) lfirst(lc3); + int stateidx; + + /* not needed for Consts */ + if (!IsA(expr, Const)) + { + stateidx = PruneCxtStateIdx(partnatts, + step->step.step_id, keyno); + context->exprstates[stateidx] = + ExecInitExpr(expr, context->planstate); + } + keyno++; + } + } pprune->pruning_steps = pinfo->pruning_steps; pprune->extparams = bms_copy(pinfo->extparams); -- cgit v1.2.3