diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2002-12-15 16:17:59 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2002-12-15 16:17:59 +0000 |
commit | 5bab36e9f6c3f3a9e14a89e1124179a339d2c3a1 (patch) | |
tree | a05154b129808efc7882599d96a1132051c2403b /src/backend/executor/execQual.c | |
parent | 90b3a0b6fd3bc74804c01156491635e5d95091d9 (diff) | |
download | postgresql-5bab36e9f6c3f3a9e14a89e1124179a339d2c3a1.tar.gz postgresql-5bab36e9f6c3f3a9e14a89e1124179a339d2c3a1.zip |
Revise executor APIs so that all per-query state structure is built in
a per-query memory context created by CreateExecutorState --- and destroyed
by FreeExecutorState. This provides a final solution to the longstanding
problem of memory leaked by various ExecEndNode calls.
Diffstat (limited to 'src/backend/executor/execQual.c')
-rw-r--r-- | src/backend/executor/execQual.c | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c index a3f79c3ac80..971773b1212 100644 --- a/src/backend/executor/execQual.c +++ b/src/backend/executor/execQual.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.120 2002/12/14 00:17:50 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.121 2002/12/15 16:17:45 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -40,6 +40,7 @@ #include "executor/functions.h" #include "executor/nodeSubplan.h" #include "miscadmin.h" +#include "optimizer/planmain.h" #include "parser/parse_expr.h" #include "utils/acl.h" #include "utils/array.h" @@ -1896,9 +1897,11 @@ ExecEvalExprSwitchContext(ExprState *expression, * cleanup work can register a shutdown callback in the ExprContext. * * 'node' is the root of the expression tree to examine - * 'parent' is the PlanState node that owns the expression, - * or NULL if we are preparing an expression that is not associated - * with a plan. (If so, it can't have aggs or subplans.) + * 'parent' is the PlanState node that owns the expression. + * + * 'parent' may be NULL if we are preparing an expression that is not + * associated with a plan tree. (If so, it can't have aggs or subplans.) + * This case should usually come through ExecPrepareExpr, not directly here. */ ExprState * ExecInitExpr(Expr *node, PlanState *parent) @@ -2017,6 +2020,7 @@ ExecInitExpr(Expr *node, PlanState *parent) * parent->subPlan. The subplans will be initialized later. */ parent->subPlan = lcons(sstate, parent->subPlan); + sstate->sub_estate = NULL; sstate->planstate = NULL; sstate->oper = (List *) @@ -2149,6 +2153,7 @@ ExecInitExprInitPlan(SubPlan *node, PlanState *parent) elog(ERROR, "ExecInitExpr: SubPlan not expected here"); /* The subplan's state will be initialized later */ + sstate->sub_estate = NULL; sstate->planstate = NULL; sstate->oper = (List *) ExecInitExpr((Expr *) node->oper, parent); @@ -2159,6 +2164,33 @@ ExecInitExprInitPlan(SubPlan *node, PlanState *parent) return sstate; } +/* + * ExecPrepareExpr --- initialize for expression execution outside a normal + * Plan tree context. + * + * This differs from ExecInitExpr in that we don't assume the caller is + * already running in the EState's per-query context. Also, we apply + * fix_opfuncids() to the passed expression tree to be sure it is ready + * to run. (In ordinary Plan trees the planner will have fixed opfuncids, + * but callers outside the executor will not have done this.) + */ +ExprState * +ExecPrepareExpr(Expr *node, EState *estate) +{ + ExprState *result; + MemoryContext oldcontext; + + fix_opfuncids((Node *) node); + + oldcontext = MemoryContextSwitchTo(estate->es_query_cxt); + + result = ExecInitExpr(node, NULL); + + MemoryContextSwitchTo(oldcontext); + + return result; +} + /* ---------------------------------------------------------------- * ExecQual / ExecTargetList / ExecProject |