aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/execUtils.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor/execUtils.c')
-rw-r--r--src/backend/executor/execUtils.c125
1 files changed, 87 insertions, 38 deletions
diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c
index a023405a275..daa40dccf75 100644
--- a/src/backend/executor/execUtils.c
+++ b/src/backend/executor/execUtils.c
@@ -1,22 +1,20 @@
/*-------------------------------------------------------------------------
*
* execUtils.c
- * miscellanious executor utility routines
+ * miscellaneous executor utility routines
*
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.62 2000/07/05 23:11:14 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.63 2000/07/12 02:37:03 tgl Exp $
*
*-------------------------------------------------------------------------
*/
/*
* INTERFACE ROUTINES
- * ExecAssignNodeBaseInfo \
- * ExecAssignDebugHooks > preforms misc work done in all the
- * ExecAssignExprContext / init node routines.
+ * ExecAssignExprContext Common code for plan node init routines.
*
* ExecGetTypeInfo | old execCStructs interface
* ExecMakeTypeInfo | code from the version 1
@@ -53,6 +51,7 @@
#include "miscadmin.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
+#include "utils/memutils.h"
#include "utils/relcache.h"
#include "utils/syscache.h"
@@ -137,57 +136,104 @@ DisplayTupleCount(FILE *statfp)
#endif
/* ----------------------------------------------------------------
- * miscellanious init node support functions
+ * miscellaneous node-init support functions
*
- * ExecAssignNodeBaseInfo - assigns the baseid field of the node
- * ExecAssignDebugHooks - assigns the node's debugging hooks
* ExecAssignExprContext - assigns the node's expression context
* ----------------------------------------------------------------
*/
/* ----------------
- * ExecAssignNodeBaseInfo
+ * ExecAssignExprContext
+ *
+ * This initializes the ExprContext field. It is only necessary
+ * to do this for nodes which use ExecQual or ExecProject
+ * because those routines depend on econtext. Other nodes that
+ * don't have to evaluate expressions don't need to do this.
*
- * as it says, this assigns the baseid field of the node and
- * increments the counter in the estate. In addition, it initializes
- * the base_parent field of the basenode.
+ * Note: we assume CurrentMemoryContext is the correct per-query context.
+ * This should be true during plan node initialization.
* ----------------
*/
void
-ExecAssignNodeBaseInfo(EState *estate, CommonState *cstate, Plan *parent)
+ExecAssignExprContext(EState *estate, CommonState *commonstate)
{
- int baseId;
+ ExprContext *econtext = makeNode(ExprContext);
- baseId = estate->es_BaseId;
- cstate->cs_base_id = baseId;
- estate->es_BaseId = baseId + 1;
+ econtext->ecxt_scantuple = NULL;
+ econtext->ecxt_innertuple = NULL;
+ econtext->ecxt_outertuple = NULL;
+ econtext->ecxt_per_query_memory = CurrentMemoryContext;
+ /*
+ * Create working memory for expression evaluation in this context.
+ */
+ econtext->ecxt_per_tuple_memory =
+ AllocSetContextCreate(CurrentMemoryContext,
+ "PlanExprContext",
+ ALLOCSET_DEFAULT_MINSIZE,
+ ALLOCSET_DEFAULT_INITSIZE,
+ ALLOCSET_DEFAULT_MAXSIZE);
+ econtext->ecxt_param_exec_vals = estate->es_param_exec_vals;
+ econtext->ecxt_param_list_info = estate->es_param_list_info;
+ econtext->ecxt_aggvalues = NULL;
+ econtext->ecxt_aggnulls = NULL;
+ econtext->ecxt_range_table = estate->es_range_table;
+
+ commonstate->cs_ExprContext = econtext;
}
/* ----------------
- * ExecAssignExprContext
+ * MakeExprContext
*
- * This initializes the ExprContext field. It is only necessary
- * to do this for nodes which use ExecQual or ExecTargetList
- * because those routines depend on econtext. Other nodes which
- * dont have to evaluate expressions don't need to do this.
+ * Build an expression context for use outside normal plan-node cases.
+ * A fake scan-tuple slot can be supplied (pass NULL if not needed).
+ * A memory context sufficiently long-lived to use as fcache context
+ * must be supplied as well.
* ----------------
*/
-void
-ExecAssignExprContext(EState *estate, CommonState *commonstate)
+ExprContext *
+MakeExprContext(TupleTableSlot *slot,
+ MemoryContext queryContext)
{
- ExprContext *econtext;
+ ExprContext *econtext = makeNode(ExprContext);
- econtext = makeNode(ExprContext);
- econtext->ecxt_scantuple = NULL; /* scan tuple slot */
- econtext->ecxt_innertuple = NULL; /* inner tuple slot */
- econtext->ecxt_outertuple = NULL; /* outer tuple slot */
- econtext->ecxt_relation = NULL; /* relation */
- econtext->ecxt_relid = 0; /* relid */
- econtext->ecxt_param_list_info = estate->es_param_list_info;
- econtext->ecxt_param_exec_vals = estate->es_param_exec_vals;
- econtext->ecxt_range_table = estate->es_range_table; /* range table */
+ econtext->ecxt_scantuple = slot;
+ econtext->ecxt_innertuple = NULL;
+ econtext->ecxt_outertuple = NULL;
+ econtext->ecxt_per_query_memory = queryContext;
+ /*
+ * We make the temporary context a child of current working context,
+ * not of the specified queryContext. This seems reasonable but I'm
+ * not totally sure about it...
+ *
+ * Expression contexts made via this routine typically don't live long
+ * enough to get reset, so specify a minsize of 0. That avoids alloc'ing
+ * any memory in the common case where expr eval doesn't use any.
+ */
+ econtext->ecxt_per_tuple_memory =
+ AllocSetContextCreate(CurrentMemoryContext,
+ "TempExprContext",
+ 0,
+ ALLOCSET_DEFAULT_INITSIZE,
+ ALLOCSET_DEFAULT_MAXSIZE);
+ econtext->ecxt_param_exec_vals = NULL;
+ econtext->ecxt_param_list_info = NULL;
+ econtext->ecxt_aggvalues = NULL;
+ econtext->ecxt_aggnulls = NULL;
+ econtext->ecxt_range_table = NIL;
+
+ return econtext;
+}
- commonstate->cs_ExprContext = econtext;
+/*
+ * Free an ExprContext made by MakeExprContext, including the temporary
+ * context used for expression evaluation. Note this will cause any
+ * pass-by-reference expression result to go away!
+ */
+void
+FreeExprContext(ExprContext *econtext)
+{
+ MemoryContextDelete(econtext->ecxt_per_tuple_memory);
+ pfree(econtext);
}
/* ----------------------------------------------------------------
@@ -390,6 +436,7 @@ ExecFreeExprContext(CommonState *commonstate)
* clean up memory used.
* ----------------
*/
+ MemoryContextDelete(econtext->ecxt_per_tuple_memory);
pfree(econtext);
commonstate->cs_ExprContext = NULL;
}
@@ -398,6 +445,7 @@ ExecFreeExprContext(CommonState *commonstate)
* ExecFreeTypeInfo
* ----------------
*/
+#ifdef NOT_USED
void
ExecFreeTypeInfo(CommonState *commonstate)
{
@@ -414,6 +462,7 @@ ExecFreeTypeInfo(CommonState *commonstate)
FreeTupleDesc(tupDesc);
commonstate->cs_ResultTupleSlot->ttc_tupleDescriptor = NULL;
}
+#endif
/* ----------------------------------------------------------------
* the following scan type support functions are for
@@ -974,8 +1023,8 @@ ExecInsertIndexTuples(TupleTableSlot *slot,
if (predicate != NULL)
{
if (econtext == NULL)
- econtext = makeNode(ExprContext);
- econtext->ecxt_scantuple = slot;
+ econtext = MakeExprContext(slot,
+ TransactionCommandContext);
/* Skip this index-update if the predicate isn't satisfied */
if (!ExecQual((List *) predicate, econtext, false))
@@ -1023,7 +1072,7 @@ ExecInsertIndexTuples(TupleTableSlot *slot,
pfree(result);
}
if (econtext != NULL)
- pfree(econtext);
+ FreeExprContext(econtext);
}
void