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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy