summaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorTom Lane2001-01-29 00:39:20 +0000
committerTom Lane2001-01-29 00:39:20 +0000
commit0d54d6ac44444c05f7c0f5058d3d3f32cc188b48 (patch)
treecccee5d61e1afc1982c363ed3e4876a09ed82b52 /src/include
parent51cd0377460839d25a5fc5f2a2499de43126a3b2 (diff)
Clean up handling of tuple descriptors so that result-tuple descriptors
allocated by plan nodes are not leaked at end of query. This doesn't really matter for normal queries, but it sure does for queries invoked repetitively inside SQL functions. Clean up some other grotty code associated with tupdescs, and fix a few other memory leaks exposed by tests with simple SQL functions.
Diffstat (limited to 'src/include')
-rw-r--r--src/include/executor/executor.h15
-rw-r--r--src/include/executor/tuptable.h26
-rw-r--r--src/include/nodes/execnodes.h15
3 files changed, 38 insertions, 18 deletions
diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h
index 0282e7e7140..091841a9c1c 100644
--- a/src/include/executor/executor.h
+++ b/src/include/executor/executor.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: executor.h,v 1.55 2001/01/24 19:43:23 momjian Exp $
+ * $Id: executor.h,v 1.56 2001/01/29 00:39:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -44,6 +44,7 @@ extern void ExecRestrPos(Plan *node);
* prototypes from functions in execJunk.c
*/
extern JunkFilter *ExecInitJunkFilter(List *targetList, TupleDesc tupType);
+extern void ExecFreeJunkFilter(JunkFilter *junkfilter);
extern bool ExecGetJunkAttribute(JunkFilter *junkfilter, TupleTableSlot *slot,
char *attrName, Datum *value, bool *isNull);
extern HeapTuple ExecRemoveJunk(JunkFilter *junkfilter, TupleTableSlot *slot);
@@ -68,6 +69,7 @@ extern bool ExecInitNode(Plan *node, EState *estate, Plan *parent);
extern TupleTableSlot *ExecProcNode(Plan *node, Plan *parent);
extern int ExecCountSlotsNode(Plan *node);
extern void ExecEndNode(Plan *node, Plan *parent);
+extern TupleDesc ExecGetTupType(Plan *node);
/*
* prototypes from functions in execQual.c
@@ -106,13 +108,14 @@ extern TupleTableSlot *ExecScan(Scan *node, ExecScanAccessMtd accessMtd);
extern TupleTable ExecCreateTupleTable(int initialSize);
extern void ExecDropTupleTable(TupleTable table, bool shouldFree);
extern TupleTableSlot *ExecAllocTableSlot(TupleTable table);
+extern TupleTableSlot *MakeTupleTableSlot(void);
extern TupleTableSlot *ExecStoreTuple(HeapTuple tuple,
TupleTableSlot *slot,
Buffer buffer,
bool shouldFree);
extern TupleTableSlot *ExecClearTuple(TupleTableSlot *slot);
-extern TupleDesc ExecSetSlotDescriptor(TupleTableSlot *slot,
- TupleDesc tupdesc);
+extern void ExecSetSlotDescriptor(TupleTableSlot *slot,
+ TupleDesc tupdesc, bool shouldFree);
extern void ExecSetSlotDescriptorIsNew(TupleTableSlot *slot, bool isNew);
extern void ExecInitResultTupleSlot(EState *estate, CommonState *commonstate);
extern void ExecInitScanTupleSlot(EState *estate,
@@ -120,8 +123,6 @@ extern void ExecInitScanTupleSlot(EState *estate,
extern TupleTableSlot *ExecInitExtraTupleSlot(EState *estate);
extern TupleTableSlot *ExecInitNullTupleSlot(EState *estate,
TupleDesc tupType);
-
-extern TupleDesc ExecGetTupType(Plan *node);
extern TupleDesc ExecTypeFromTL(List *targetList);
extern void SetChangedParamList(Plan *node, List *newchg);
@@ -131,7 +132,7 @@ extern void SetChangedParamList(Plan *node, List *newchg);
extern void ResetTupleCount(void);
extern void ExecAssignExprContext(EState *estate, CommonState *commonstate);
extern void ExecAssignResultType(CommonState *commonstate,
- TupleDesc tupDesc);
+ TupleDesc tupDesc, bool shouldFree);
extern void ExecAssignResultTypeFromOuterPlan(Plan *node,
CommonState *commonstate);
extern void ExecAssignResultTypeFromTL(Plan *node, CommonState *commonstate);
@@ -141,7 +142,7 @@ extern void ExecFreeProjectionInfo(CommonState *commonstate);
extern void ExecFreeExprContext(CommonState *commonstate);
extern TupleDesc ExecGetScanType(CommonScanState *csstate);
extern void ExecAssignScanType(CommonScanState *csstate,
- TupleDesc tupDesc);
+ TupleDesc tupDesc, bool shouldFree);
extern void ExecAssignScanTypeFromOuterPlan(Plan *node,
CommonScanState *csstate);
extern Form_pg_attribute ExecGetTypeInfo(Relation relDesc);
diff --git a/src/include/executor/tuptable.h b/src/include/executor/tuptable.h
index 47018666a78..7def0be4b69 100644
--- a/src/include/executor/tuptable.h
+++ b/src/include/executor/tuptable.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: tuptable.h,v 1.17 2001/01/24 19:43:23 momjian Exp $
+ * $Id: tuptable.h,v 1.18 2001/01/29 00:39:20 tgl Exp $
*
* NOTES
* The tuple table interface is getting pretty ugly.
@@ -22,27 +22,36 @@
/* ----------------
* The executor tuple table is managed and manipulated by special
- * code in executor/execTuples.c and tupTable.h
+ * code in executor/execTuples.c.
*
* TupleTableSlot information
*
- * shouldFree boolean - should we call pfree() on tuple
+ * val current tuple, or NULL if no tuple
+ * shouldFree boolean - should we pfree() tuple
* descIsNew boolean - true when tupleDescriptor changes
- * tupleDescriptor type information kept regarding the tuple data
+ * tupleDescriptor type information for the tuple data
+ * shouldFreeDesc boolean - should we free tupleDescriptor
* buffer the buffer for tuples pointing to disk pages
*
* The executor stores pointers to tuples in a ``tuple table''
- * which is composed of TupleTableSlot's. Some of the tuples
- * are pointers to buffer pages and others are pointers to
- * palloc'ed memory and the shouldFree variable tells us when
+ * which is composed of TupleTableSlots. Sometimes the tuples
+ * are pointers to buffer pages, while others are pointers to
+ * palloc'ed memory; the shouldFree variable tells us when
* we may call pfree() on a tuple. -cim 9/23/90
*
+ * If buffer is not InvalidBuffer, then the slot is holding a pin
+ * on the indicated buffer page; drop the pin when we release the
+ * slot's reference to that buffer.
+ *
* In the implementation of nested-dot queries such as
* "retrieve (EMP.hobbies.all)", a single scan may return tuples
* of many types, so now we return pointers to tuple descriptors
* along with tuples returned via the tuple table. -cim 1/18/90
*
- * Tuple table macros are all excised from the system now.
+ * shouldFreeDesc is similar to shouldFree: if it's true, then the
+ * tupleDescriptor is "owned" by the TupleTableSlot and should be
+ * freed when the slot's reference to the descriptor is dropped.
+ *
* See executor.h for decls of functions defined in execTuples.c
* -jolly
*
@@ -54,6 +63,7 @@ typedef struct TupleTableSlot
HeapTuple val;
bool ttc_shouldFree;
bool ttc_descIsNew;
+ bool ttc_shouldFreeDesc;
TupleDesc ttc_tupleDescriptor;
Buffer ttc_buffer;
} TupleTableSlot;
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 5552210de81..b9c10e6b310 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: execnodes.h,v 1.55 2001/01/24 19:43:25 momjian Exp $
+ * $Id: execnodes.h,v 1.56 2001/01/29 00:39:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -164,11 +164,19 @@ typedef struct ProjectionInfo
* (including the junk attributes).
* cleanTargetList: the "clean" target list (junk attributes removed).
* cleanLength: the length of 'cleanTargetList'
- * cleanTupTyp: the tuple descriptor of the "clean" tuple (with
+ * cleanTupType: the tuple descriptor of the "clean" tuple (with
* junk attributes removed).
- * cleanMap: A map with the correspondance between the non junk
+ * cleanMap: A map with the correspondance between the non-junk
* attributes of the "original" tuple and the
* attributes of the "clean" tuple.
+ * junkContext: memory context holding the JunkFilter node and all
+ * its subsidiary data structures.
+ *
+ * NOTE: the original targetList and tupType are passed to ExecInitJunkFilter
+ * and do not belong to the JunkFilter. All the other subsidiary structures
+ * are created during ExecInitJunkFilter, and all of them can be freed by
+ * deleting the memory context junkContext. This would not be needed if we
+ * had a cleaner approach to managing query-lifetime data structures...
* ----------------
*/
typedef struct JunkFilter
@@ -181,6 +189,7 @@ typedef struct JunkFilter
int jf_cleanLength;
TupleDesc jf_cleanTupType;
AttrNumber *jf_cleanMap;
+ MemoryContext jf_junkContext;
} JunkFilter;
/* ----------------