aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2011-06-15 14:05:22 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2011-06-15 14:05:22 -0400
commit10db3de66eb226e9aed32e789abd532c41f0f471 (patch)
tree0eb883bca9519286d1240170721bc12f338707f4 /src
parent31156ce8b95c5e9fa8cb01f08de008c3289c1086 (diff)
downloadpostgresql-10db3de66eb226e9aed32e789abd532c41f0f471.tar.gz
postgresql-10db3de66eb226e9aed32e789abd532c41f0f471.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/sort/tuplestore.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/src/backend/utils/sort/tuplestore.c b/src/backend/utils/sort/tuplestore.c
index b59587b73b3..4d6e3aa0e4b 100644
--- a/src/backend/utils/sort/tuplestore.c
+++ b/src/backend/utils/sort/tuplestore.c
@@ -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);