diff options
Diffstat (limited to 'src/backend/optimizer')
| -rw-r--r-- | src/backend/optimizer/path/indxpath.c | 30 | ||||
| -rw-r--r-- | src/backend/optimizer/util/clauses.c | 38 |
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. |
