Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 10db3de

Browse files
committed
Fix failure to account for memory used by tuplestore_putvalues().
This oversight could result in a tuplestore using much more than the intended amount of memory. It would only happen in a code path that loaded a tuplestore via tuplestore_putvalues(), and many of those won't emit huge amounts of data; but cases such as holdable cursors and plpgsql's RETURN NEXT command could have the problem. The fix ensures that the tuplestore will switch to write-to-disk mode when it overruns work_mem. The potential overrun was finite, because we would still count the space used by the tuple pointer array, so the tuplestore code would eventually flip into write-to-disk mode anyway. When storing wide tuples we would go far past the expected work_mem usage before that happened; but this may account for the lack of prior reports. Back-patch to 8.4, where tuplestore_putvalues was introduced. Per bug #6061 from Yann Delorme.
1 parent 31156ce commit 10db3de

File tree

1 file changed

+5
-4
lines changed

1 file changed

+5
-4
lines changed

src/backend/utils/sort/tuplestore.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,8 @@ tuplestore_puttuple(Tuplestorestate *state, HeapTuple tuple)
570570
MemoryContext oldcxt = MemoryContextSwitchTo(state->context);
571571

572572
/*
573-
* Copy the tuple. (Must do this even in WRITEFILE case.)
573+
* Copy the tuple. (Must do this even in WRITEFILE case. Note that
574+
* COPYTUP includes USEMEM, so we needn't do that here.)
574575
*/
575576
tuple = COPYTUP(state, tuple);
576577

@@ -580,9 +581,8 @@ tuplestore_puttuple(Tuplestorestate *state, HeapTuple tuple)
580581
}
581582

582583
/*
583-
* Similar to tuplestore_puttuple(), but start from the values + nulls
584-
* array. This avoids requiring that the caller construct a HeapTuple,
585-
* saving a copy.
584+
* Similar to tuplestore_puttuple(), but work from values + nulls arrays.
585+
* This avoids an extra tuple-construction operation.
586586
*/
587587
void
588588
tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc,
@@ -592,6 +592,7 @@ tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc,
592592
MemoryContext oldcxt = MemoryContextSwitchTo(state->context);
593593

594594
tuple = heap_form_minimal_tuple(tdesc, values, isnull);
595+
USEMEM(state, GetMemoryChunkSpace(tuple));
595596

596597
tuplestore_puttuple_common(state, (void *) tuple);
597598

0 commit comments

Comments
 (0)