summaryrefslogtreecommitdiff
path: root/src/backend/optimizer
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer')
-rw-r--r--src/backend/optimizer/path/indxpath.c30
-rw-r--r--src/backend/optimizer/util/clauses.c38
2 files changed, 49 insertions, 19 deletions
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index e4eedd1179..984c930e3a 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.128 2002/12/13 19:45:56 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.129 2002/12/15 16:17:49 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1132,7 +1132,8 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
HeapTuple tuple;
ScanKeyData entry[1];
Form_pg_amop aform;
- ExprContext *econtext;
+ EState *estate;
+ MemoryContext oldcontext;
/* First try the equal() test */
if (equal((Node *) predicate, clause))
@@ -1267,20 +1268,33 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
ReleaseSysCache(tuple);
/*
- * 5. Evaluate the test
+ * 5. Evaluate the test. For this we need an EState.
*/
+ estate = CreateExecutorState();
+
+ /* We can use the estate's working context to avoid memory leaks. */
+ oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
+
+ /* Build expression tree */
test_expr = make_opclause(test_op,
BOOLOID,
false,
(Expr *) clause_const,
(Expr *) pred_const);
- set_opfuncid((OpExpr *) test_expr);
- test_exprstate = ExecInitExpr(test_expr, NULL);
- econtext = MakeExprContext(NULL, CurrentMemoryContext);
- test_result = ExecEvalExprSwitchContext(test_exprstate, econtext,
+ /* Prepare it for execution */
+ test_exprstate = ExecPrepareExpr(test_expr, estate);
+
+ /* And execute it. */
+ test_result = ExecEvalExprSwitchContext(test_exprstate,
+ GetPerTupleExprContext(estate),
&isNull, NULL);
- FreeExprContext(econtext);
+
+ /* Get back to outer memory context */
+ MemoryContextSwitchTo(oldcontext);
+
+ /* Release all the junk we just created */
+ FreeExecutorState(estate);
if (isNull)
{
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 1d87afdc42..4c87a95c3b 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.119 2002/12/14 00:17:59 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.120 2002/12/15 16:17:50 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -1684,7 +1684,8 @@ evaluate_function(Oid funcid, List *args, HeapTuple func_tuple)
bool has_null_input = false;
FuncExpr *newexpr;
ExprState *newexprstate;
- ExprContext *econtext;
+ EState *estate;
+ MemoryContext oldcontext;
Datum const_val;
bool const_is_null;
List *arg;
@@ -1729,7 +1730,14 @@ evaluate_function(Oid funcid, List *args, HeapTuple func_tuple)
*
* We use the executor's routine ExecEvalExpr() to avoid duplication of
* code and ensure we get the same result as the executor would get.
- *
+ * To use the executor, we need an EState.
+ */
+ estate = CreateExecutorState();
+
+ /* We can use the estate's working context to avoid memory leaks. */
+ oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
+
+ /*
* Build a new FuncExpr node containing the already-simplified arguments.
*/
newexpr = makeNode(FuncExpr);
@@ -1739,27 +1747,35 @@ evaluate_function(Oid funcid, List *args, HeapTuple func_tuple)
newexpr->funcformat = COERCE_EXPLICIT_CALL; /* doesn't matter */
newexpr->args = args;
- /* Get info needed about result datatype */
- get_typlenbyval(result_typeid, &resultTypLen, &resultTypByVal);
+ /*
+ * Prepare it for execution.
+ */
+ newexprstate = ExecPrepareExpr((Expr *) newexpr, estate);
/*
- * It is OK to use a dummy econtext because none of the
+ * And evaluate it.
+ *
+ * It is OK to use a default econtext because none of the
* ExecEvalExpr() code used in this situation will use econtext. That
* might seem fortuitous, but it's not so unreasonable --- a constant
* expression does not depend on context, by definition, n'est ce pas?
*/
- econtext = MakeExprContext(NULL, CurrentMemoryContext);
+ const_val = ExecEvalExprSwitchContext(newexprstate,
+ GetPerTupleExprContext(estate),
+ &const_is_null, NULL);
- newexprstate = ExecInitExpr((Expr *) newexpr, NULL);
+ /* Get info needed about result datatype */
+ get_typlenbyval(result_typeid, &resultTypLen, &resultTypByVal);
- const_val = ExecEvalExprSwitchContext(newexprstate, econtext,
- &const_is_null, NULL);
+ /* Get back to outer memory context */
+ MemoryContextSwitchTo(oldcontext);
/* Must copy result out of sub-context used by expression eval */
if (!const_is_null)
const_val = datumCopy(const_val, resultTypByVal, resultTypLen);
- FreeExprContext(econtext);
+ /* Release all the junk we just created */
+ FreeExecutorState(estate);
/*
* Make the constant result node.