1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-03 20:02:46 +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:
Tom Lane
2000-07-12 02:37:39 +00:00
parent 46fb9c29e2
commit badce86a2c
53 changed files with 1536 additions and 1584 deletions

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Id: nodeHash.c,v 1.48 2000/06/28 03:31:34 tgl Exp $
* $Id: nodeHash.c,v 1.49 2000/07/12 02:37:03 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -28,7 +28,8 @@
#include "executor/nodeHash.h"
#include "executor/nodeHashjoin.h"
#include "miscadmin.h"
#include "parser/parse_expr.h"
#include "parser/parse_type.h"
static int hashFunc(Datum key, int len, bool byVal);
@ -45,7 +46,7 @@ ExecHash(Hash *node)
EState *estate;
HashState *hashstate;
Plan *outerNode;
Var *hashkey;
Node *hashkey;
HashJoinTable hashtable;
TupleTableSlot *slot;
ExprContext *econtext;
@ -139,12 +140,9 @@ ExecInitHash(Hash *node, EState *estate, Plan *parent)
/* ----------------
* Miscellaneous initialization
*
* + assign node's base_id
* + assign debugging hooks and
* + create expression context for node
* ----------------
*/
ExecAssignNodeBaseInfo(estate, &hashstate->cstate, parent);
ExecAssignExprContext(estate, &hashstate->cstate);
/* ----------------
@ -204,6 +202,7 @@ ExecEndHash(Hash *node)
* ----------------
*/
ExecFreeProjectionInfo(&hashstate->cstate);
ExecFreeExprContext(&hashstate->cstate);
/* ----------------
* shut down the subplan
@ -236,6 +235,7 @@ ExecHashTableCreate(Hash *node)
int totalbuckets;
int bucketsize;
int i;
Type typeInfo;
MemoryContext oldcxt;
/* ----------------
@ -346,6 +346,14 @@ ExecHashTableCreate(Hash *node)
hashtable->innerBatchSize = NULL;
hashtable->outerBatchSize = NULL;
/* ----------------
* Get info about the datatype of the hash key.
* ----------------
*/
typeInfo = typeidType(exprType(node->hashkey));
hashtable->typByVal = typeByVal(typeInfo);
hashtable->typLen = typeLen(typeInfo);
/* ----------------
* Create temporary memory contexts in which to keep the hashtable
* working storage. See notes in executor/hashjoin.h.
@ -448,7 +456,7 @@ ExecHashTableDestroy(HashJoinTable hashtable)
void
ExecHashTableInsert(HashJoinTable hashtable,
ExprContext *econtext,
Var *hashkey)
Node *hashkey)
{
int bucketno = ExecHashGetBucket(hashtable, econtext, hashkey);
TupleTableSlot *slot = econtext->ecxt_innertuple;
@ -508,43 +516,44 @@ ExecHashTableInsert(HashJoinTable hashtable,
int
ExecHashGetBucket(HashJoinTable hashtable,
ExprContext *econtext,
Var *hashkey)
Node *hashkey)
{
int bucketno;
Datum keyval;
bool isNull;
bool isDone;
/* ----------------
* Get the join attribute value of the tuple
*
* ...It's quick hack - use ExecEvalExpr instead of ExecEvalVar:
* hashkey may be T_ArrayRef, not just T_Var. - vadim 04/22/97
* We reset the eval context each time to avoid any possibility
* of memory leaks in the hash function.
* ----------------
*/
keyval = ExecEvalExpr((Node *) hashkey, econtext, &isNull, NULL);
ResetExprContext(econtext);
/*
* keyval could be null, so we better point it to something valid
* before trying to run hashFunc on it. --djm 8/17/96
*/
if (isNull)
{
execConstByVal = 0;
execConstLen = 0;
keyval = (Datum) "";
}
keyval = ExecEvalExprSwitchContext(hashkey, econtext,
&isNull, &isDone);
/* ------------------
* compute the hash function
* ------------------
*/
bucketno = hashFunc(keyval, execConstLen, execConstByVal) % hashtable->totalbuckets;
if (isNull)
{
bucketno = 0;
}
else
{
bucketno = hashFunc(keyval, hashtable->typLen, hashtable->typByVal)
% hashtable->totalbuckets;
}
#ifdef HJDEBUG
if (bucketno >= hashtable->nbuckets)
printf("hash(%d) = %d SAVED\n", keyval, bucketno);
printf("hash(%ld) = %d SAVED\n", (long) keyval, bucketno);
else
printf("hash(%d) = %d\n", keyval, bucketno);
printf("hash(%ld) = %d\n", (long) keyval, bucketno);
#endif
return bucketno;
@ -585,6 +594,9 @@ ExecScanHashBucket(HashJoinState *hjstate,
false); /* do not pfree this tuple */
econtext->ecxt_innertuple = inntuple;
/* reset temp memory each time to avoid leaks from qual expression */
ResetExprContext(econtext);
if (ExecQual(hjclauses, econtext, false))
{
hjstate->hj_CurTuple = hashTuple;