From 8c42a8dcab7e2f835eff5c001d9be2829301429d Mon Sep 17 00:00:00 2001 From: amit Date: Tue, 24 Jul 2018 15:11:25 +0900 Subject: [PATCH v1] Use per-tuple memory in ExecFindPartition --- src/backend/executor/execPartition.c | 38 ++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c index 7a4665cc4e..f5d9b1755a 100644 --- a/src/backend/executor/execPartition.c +++ b/src/backend/executor/execPartition.c @@ -196,6 +196,15 @@ ExecFindPartition(ResultRelInfo *resultRelInfo, PartitionDispatch *pd, PartitionDispatch parent; ExprContext *ecxt = GetPerTupleExprContext(estate); TupleTableSlot *ecxt_scantuple_old = ecxt->ecxt_scantuple; + TupleTableSlot *myslot = NULL; + MemoryContext oldcontext; + HeapTuple tuple = ExecFetchSlotTuple(slot); + + /* + * Anything below that needs to allocate memory should use per-tuple + * memory. + */ + oldcontext = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate)); /* * First check the root table's partition constraint, if any. No point in @@ -209,7 +218,6 @@ ExecFindPartition(ResultRelInfo *resultRelInfo, PartitionDispatch *pd, while (true) { PartitionDesc partdesc; - TupleTableSlot *myslot = parent->tupslot; TupleConversionMap *map = parent->tupmap; int cur_index = -1; @@ -220,11 +228,9 @@ ExecFindPartition(ResultRelInfo *resultRelInfo, PartitionDispatch *pd, * Convert the tuple to this parent's layout so that we can do certain * things we do below. */ + myslot = parent->tupslot; if (myslot != NULL && map != NULL) { - HeapTuple tuple = ExecFetchSlotTuple(slot); - - ExecClearTuple(myslot); tuple = do_convert_tuple(tuple, map); ExecStoreTuple(tuple, myslot, InvalidBuffer, true); slot = myslot; @@ -269,9 +275,32 @@ ExecFindPartition(ResultRelInfo *resultRelInfo, PartitionDispatch *pd, break; } else + { parent = pd[-parent->indexes[cur_index]]; + + /* + * If we used the dedicated slot, must call ExecClearTuple now + * to release the tuple contained in it and set its + * tts_shouldFree to false so that nobody attempts to release it + * later. We have to do that because the tuple uses per-tuple + * memory. + */ + if (slot == myslot) + { + /* + * Copy the tuple to be used for further routing before + * clearing the slot itself. + */ + tuple = ExecCopySlotTuple(myslot); + ExecClearTuple(myslot); + } + } } + /* Release the tuple in the lowest parent's dedicated slot. */ + if (slot == myslot) + ExecClearTuple(myslot); + /* A partition was not found. */ if (result < 0) { @@ -287,6 +316,7 @@ ExecFindPartition(ResultRelInfo *resultRelInfo, PartitionDispatch *pd, val_desc ? errdetail("Partition key of the failing row contains %s.", val_desc) : 0)); } + MemoryContextSwitchTo(oldcontext); ecxt->ecxt_scantuple = ecxt_scantuple_old; return result; } -- 2.11.0