diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2009-03-27 18:30:21 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2009-03-27 18:30:21 +0000 |
commit | 25bf7f8b9b3ce0f04b498988bb98d9d5cf9bad67 (patch) | |
tree | 9d96a158b6c03def3242d5d4af85d843cd5490e0 /src/backend/executor/nodeWindowAgg.c | |
parent | a95307b639ad94fb94c898eb6b4a3c95c407bf44 (diff) | |
download | postgresql-25bf7f8b9b3ce0f04b498988bb98d9d5cf9bad67.tar.gz postgresql-25bf7f8b9b3ce0f04b498988bb98d9d5cf9bad67.zip |
Fix possible failures when a tuplestore switches from in-memory to on-disk
mode while callers hold pointers to in-memory tuples. I reported this for
the case of nodeWindowAgg's primary scan tuple, but inspection of the code
shows that all of the calls in nodeWindowAgg and nodeCtescan are at risk.
For the moment, fix it with a rather brute-force approach of copying
whenever one of the at-risk callers requests a tuple. Later we might
think of some sort of reference-count approach to reduce tuple copying.
Diffstat (limited to 'src/backend/executor/nodeWindowAgg.c')
-rw-r--r-- | src/backend/executor/nodeWindowAgg.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c index 7c3733a0553..263cb0a78c1 100644 --- a/src/backend/executor/nodeWindowAgg.c +++ b/src/backend/executor/nodeWindowAgg.c @@ -27,7 +27,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/nodeWindowAgg.c,v 1.3 2009/01/01 17:23:42 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/executor/nodeWindowAgg.c,v 1.4 2009/03/27 18:30:21 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -480,7 +480,8 @@ eval_windowaggregates(WindowAggState *winstate) spool_tuples(winstate, winstate->aggregatedupto); tuplestore_select_read_pointer(winstate->buffer, winstate->agg_ptr); - if (!tuplestore_gettupleslot(winstate->buffer, true, agg_row_slot)) + if (!tuplestore_gettupleslot(winstate->buffer, true, true, + agg_row_slot)) break; /* must be end of partition */ } @@ -1001,12 +1002,14 @@ restart: /* * Read the current row from the tuplestore, and save in ScanTupleSlot. * (We can't rely on the outerplan's output slot because we may have to - * read beyond the current row.) + * read beyond the current row. Also, we have to actually copy the row + * out of the tuplestore, since window function evaluation might cause + * the tuplestore to dump its state to disk.) * * Current row must be in the tuplestore, since we spooled it above. */ tuplestore_select_read_pointer(winstate->buffer, winstate->current_ptr); - if (!tuplestore_gettupleslot(winstate->buffer, true, + if (!tuplestore_gettupleslot(winstate->buffer, true, true, winstate->ss.ss_ScanTupleSlot)) elog(ERROR, "unexpected end of tuplestore"); @@ -1589,14 +1592,14 @@ window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot) while (winobj->seekpos > pos) { - if (!tuplestore_gettupleslot(winstate->buffer, false, slot)) + if (!tuplestore_gettupleslot(winstate->buffer, false, true, slot)) elog(ERROR, "unexpected end of tuplestore"); winobj->seekpos--; } while (winobj->seekpos < pos) { - if (!tuplestore_gettupleslot(winstate->buffer, true, slot)) + if (!tuplestore_gettupleslot(winstate->buffer, true, true, slot)) elog(ERROR, "unexpected end of tuplestore"); winobj->seekpos++; } |