mirror of
https://github.com/postgres/postgres.git
synced 2025-07-14 08:21:07 +03:00
First stage of reclaiming memory in executor by resetting short-term
memory contexts. Currently, only leaks in expressions executed as quals or projections are handled. Clean up some old dead cruft in executor while at it --- unused fields in state nodes, that sort of thing.
This commit is contained in:
@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.93 2000/06/18 22:44:07 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.94 2000/07/12 02:37:08 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -66,7 +66,7 @@ static NestLoop *make_nestloop(List *qptlist, List *qpqual, Plan *lefttree,
|
||||
Plan *righttree);
|
||||
static HashJoin *make_hashjoin(List *tlist, List *qpqual,
|
||||
List *hashclauses, Plan *lefttree, Plan *righttree);
|
||||
static Hash *make_hash(List *tlist, Var *hashkey, Plan *lefttree);
|
||||
static Hash *make_hash(List *tlist, Node *hashkey, Plan *lefttree);
|
||||
static MergeJoin *make_mergejoin(List *tlist, List *qpqual,
|
||||
List *mergeclauses, Plan *righttree, Plan *lefttree);
|
||||
static void copy_path_costsize(Plan *dest, Path *src);
|
||||
@ -664,7 +664,7 @@ create_hashjoin_node(HashPath *best_path,
|
||||
List *hashclauses;
|
||||
HashJoin *join_node;
|
||||
Hash *hash_node;
|
||||
Var *innerhashkey;
|
||||
Node *innerhashkey;
|
||||
|
||||
/*
|
||||
* NOTE: there will always be exactly one hashclause in the list
|
||||
@ -694,7 +694,7 @@ create_hashjoin_node(HashPath *best_path,
|
||||
(Index) 0));
|
||||
|
||||
/* Now the righthand op of the sole hashclause is the inner hash key. */
|
||||
innerhashkey = get_rightop(lfirst(hashclauses));
|
||||
innerhashkey = (Node *) get_rightop(lfirst(hashclauses));
|
||||
|
||||
/*
|
||||
* Build the hash node and hash join node.
|
||||
@ -1103,7 +1103,7 @@ make_hashjoin(List *tlist,
|
||||
}
|
||||
|
||||
static Hash *
|
||||
make_hash(List *tlist, Var *hashkey, Plan *lefttree)
|
||||
make_hash(List *tlist, Node *hashkey, Plan *lefttree)
|
||||
{
|
||||
Hash *node = makeNode(Hash);
|
||||
Plan *plan = &node->plan;
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.38 2000/06/18 22:44:09 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.39 2000/07/12 02:37:09 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -649,7 +649,7 @@ SS_finalize_plan(Plan *plan)
|
||||
break;
|
||||
|
||||
case T_Hash:
|
||||
finalize_primnode((Node *) ((Hash *) plan)->hashkey,
|
||||
finalize_primnode(((Hash *) plan)->hashkey,
|
||||
&results);
|
||||
break;
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.68 2000/05/30 00:49:49 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.69 2000/07/12 02:37:11 tgl Exp $
|
||||
*
|
||||
* HISTORY
|
||||
* AUTHOR DATE MAJOR EVENT
|
||||
@ -30,6 +30,7 @@
|
||||
#include "optimizer/var.h"
|
||||
#include "parser/parse_type.h"
|
||||
#include "parser/parsetree.h"
|
||||
#include "utils/datum.h"
|
||||
#include "utils/lsyscache.h"
|
||||
#include "utils/syscache.h"
|
||||
|
||||
@ -1317,7 +1318,10 @@ simplify_op_or_func(Expr *expr, List *args)
|
||||
HeapTuple func_tuple;
|
||||
Form_pg_proc funcform;
|
||||
Type resultType;
|
||||
bool resultTypByVal;
|
||||
int resultTypLen;
|
||||
Expr *newexpr;
|
||||
ExprContext *econtext;
|
||||
Datum const_val;
|
||||
bool has_nonconst_input = false;
|
||||
bool has_null_input = false;
|
||||
@ -1424,25 +1428,35 @@ simplify_op_or_func(Expr *expr, List *args)
|
||||
newexpr->oper = expr->oper;
|
||||
newexpr->args = args;
|
||||
|
||||
/* Get info needed about result datatype */
|
||||
resultType = typeidType(result_typeid);
|
||||
resultTypByVal = typeByVal(resultType);
|
||||
resultTypLen = typeLen(resultType);
|
||||
|
||||
/*
|
||||
* It is OK to pass econtext = NULL because none of the ExecEvalExpr()
|
||||
* It is OK to pass a dummy 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?
|
||||
*/
|
||||
const_val = ExecEvalExpr((Node *) newexpr, NULL,
|
||||
&const_is_null, &isDone);
|
||||
econtext = MakeExprContext(NULL, CurrentMemoryContext);
|
||||
|
||||
const_val = ExecEvalExprSwitchContext((Node *) newexpr, econtext,
|
||||
&const_is_null, &isDone);
|
||||
Assert(isDone); /* if this isn't set, we blew it... */
|
||||
|
||||
/* Must copy result out of sub-context used by expression eval */
|
||||
const_val = datumCopy(const_val, resultTypByVal, resultTypLen);
|
||||
|
||||
FreeExprContext(econtext);
|
||||
pfree(newexpr);
|
||||
|
||||
/*
|
||||
* Make the constant result node.
|
||||
*/
|
||||
resultType = typeidType(result_typeid);
|
||||
return (Expr *) makeConst(result_typeid, typeLen(resultType),
|
||||
return (Expr *) makeConst(result_typeid, resultTypLen,
|
||||
const_val, const_is_null,
|
||||
typeByVal(resultType),
|
||||
false, false);
|
||||
resultTypByVal, false, false);
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user