aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeMaterial.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2008-10-01 19:51:50 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2008-10-01 19:51:50 +0000
commitdad4cb6258382e99409c3e0673f1a5ec5b8bf03f (patch)
treefc13e11ae4ec12a824befec58c61fe8e5b398197 /src/backend/executor/nodeMaterial.c
parent233f135144ffc02512490eaffdb2575284a3af9d (diff)
downloadpostgresql-dad4cb6258382e99409c3e0673f1a5ec5b8bf03f.tar.gz
postgresql-dad4cb6258382e99409c3e0673f1a5ec5b8bf03f.zip
Improve tuplestore.c to support multiple concurrent read positions.
This facility replaces the former mark/restore support but is otherwise upward-compatible with previous uses. It's expected to be needed for single evaluation of CTEs and also for window functions, so I'm committing it separately instead of waiting for either one of those patches to be finished. Per discussion with Greg Stark and Hitoshi Harada. Note: I removed nodeFunctionscan's mark/restore support, instead of bothering to update it for this change, because it was dead code anyway.
Diffstat (limited to 'src/backend/executor/nodeMaterial.c')
-rw-r--r--src/backend/executor/nodeMaterial.c33
1 files changed, 24 insertions, 9 deletions
diff --git a/src/backend/executor/nodeMaterial.c b/src/backend/executor/nodeMaterial.c
index 3c096356a37..494560d0f46 100644
--- a/src/backend/executor/nodeMaterial.c
+++ b/src/backend/executor/nodeMaterial.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/nodeMaterial.c,v 1.62 2008/03/23 00:54:04 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/nodeMaterial.c,v 1.63 2008/10/01 19:51:49 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -51,7 +51,7 @@ ExecMaterial(MaterialState *node)
estate = node->ss.ps.state;
dir = estate->es_direction;
forward = ScanDirectionIsForward(dir);
- tuplestorestate = (Tuplestorestate *) node->tuplestorestate;
+ tuplestorestate = node->tuplestorestate;
/*
* If first time through, and we need a tuplestore, initialize it.
@@ -60,7 +60,19 @@ ExecMaterial(MaterialState *node)
{
tuplestorestate = tuplestore_begin_heap(true, false, work_mem);
tuplestore_set_eflags(tuplestorestate, node->eflags);
- node->tuplestorestate = (void *) tuplestorestate;
+ if (node->eflags & EXEC_FLAG_MARK)
+ {
+ /*
+ * Allocate a second read pointer to serve as the mark.
+ * We know it must have index 1, so needn't store that.
+ */
+ int ptrn;
+
+ ptrn = tuplestore_alloc_read_pointer(tuplestorestate,
+ node->eflags);
+ Assert(ptrn == 1);
+ }
+ node->tuplestorestate = tuplestorestate;
}
/*
@@ -236,7 +248,7 @@ ExecEndMaterial(MaterialState *node)
* Release tuplestore resources
*/
if (node->tuplestorestate != NULL)
- tuplestore_end((Tuplestorestate *) node->tuplestorestate);
+ tuplestore_end(node->tuplestorestate);
node->tuplestorestate = NULL;
/*
@@ -262,7 +274,10 @@ ExecMaterialMarkPos(MaterialState *node)
if (!node->tuplestorestate)
return;
- tuplestore_markpos((Tuplestorestate *) node->tuplestorestate);
+ /*
+ * copy the active read pointer to the mark.
+ */
+ tuplestore_copy_read_pointer(node->tuplestorestate, 0, 1);
}
/* ----------------------------------------------------------------
@@ -283,9 +298,9 @@ ExecMaterialRestrPos(MaterialState *node)
return;
/*
- * restore the scan to the previously marked position
+ * copy the mark to the active read pointer.
*/
- tuplestore_restorepos((Tuplestorestate *) node->tuplestorestate);
+ tuplestore_copy_read_pointer(node->tuplestorestate, 1, 0);
}
/* ----------------------------------------------------------------
@@ -322,14 +337,14 @@ ExecMaterialReScan(MaterialState *node, ExprContext *exprCtxt)
if (((PlanState *) node)->lefttree->chgParam != NULL ||
(node->eflags & EXEC_FLAG_REWIND) == 0)
{
- tuplestore_end((Tuplestorestate *) node->tuplestorestate);
+ tuplestore_end(node->tuplestorestate);
node->tuplestorestate = NULL;
if (((PlanState *) node)->lefttree->chgParam == NULL)
ExecReScan(((PlanState *) node)->lefttree, exprCtxt);
node->eof_underlying = false;
}
else
- tuplestore_rescan((Tuplestorestate *) node->tuplestorestate);
+ tuplestore_rescan(node->tuplestorestate);
}
else
{