mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-21 08:29:39 +08:00
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.
This commit is contained in:
parent
6122849416
commit
669ac03af6
@ -570,7 +570,8 @@ tuplestore_puttuple(Tuplestorestate *state, HeapTuple tuple)
|
||||
MemoryContext oldcxt = MemoryContextSwitchTo(state->context);
|
||||
|
||||
/*
|
||||
* Copy the tuple. (Must do this even in WRITEFILE case.)
|
||||
* Copy the tuple. (Must do this even in WRITEFILE case. Note that
|
||||
* COPYTUP includes USEMEM, so we needn't do that here.)
|
||||
*/
|
||||
tuple = COPYTUP(state, tuple);
|
||||
|
||||
@ -580,9 +581,8 @@ tuplestore_puttuple(Tuplestorestate *state, HeapTuple tuple)
|
||||
}
|
||||
|
||||
/*
|
||||
* Similar to tuplestore_puttuple(), but start from the values + nulls
|
||||
* array. This avoids requiring that the caller construct a HeapTuple,
|
||||
* saving a copy.
|
||||
* Similar to tuplestore_puttuple(), but work from values + nulls arrays.
|
||||
* This avoids an extra tuple-construction operation.
|
||||
*/
|
||||
void
|
||||
tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc,
|
||||
@ -592,6 +592,7 @@ tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc,
|
||||
MemoryContext oldcxt = MemoryContextSwitchTo(state->context);
|
||||
|
||||
tuple = heap_form_minimal_tuple(tdesc, values, isnull);
|
||||
USEMEM(state, GetMemoryChunkSpace(tuple));
|
||||
|
||||
tuplestore_puttuple_common(state, (void *) tuple);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user