Repair bug #2839: the various ExecReScan functions need to reset
authorTom Lane <[email protected]>
Tue, 26 Dec 2006 19:27:26 +0000 (19:27 +0000)
committerTom Lane <[email protected]>
Tue, 26 Dec 2006 19:27:26 +0000 (19:27 +0000)
ps_TupFromTlist in plan nodes that make use of it.  This was being done
correctly in join nodes and Result nodes but not in any relation-scan nodes.
Bug would lead to bogus results if a set-returning function appeared in the
targetlist of a subquery that could be rescanned after partial execution,
for example a subquery within EXISTS().  Bug has been around forever :-(
... surprising it wasn't reported before.

src/backend/executor/nodeFunctionscan.c
src/backend/executor/nodeIndexscan.c
src/backend/executor/nodeResult.c
src/backend/executor/nodeSeqscan.c
src/backend/executor/nodeSubqueryscan.c
src/backend/executor/nodeTidscan.c

index 8aa7eb44e24f21fb019395f09e552cae103fa72f..ff37ecfb6bfb1e30d10c8f47669742d58cb22248 100644 (file)
@@ -361,6 +361,7 @@ ExecFunctionReScan(FunctionScan *node, ExprContext *exprCtxt, Plan *parent)
        scanstate = (FunctionScanState *) node->scan.scanstate;
 
        ExecClearTuple(scanstate->csstate.cstate.cs_ResultTupleSlot);
+       scanstate->csstate.cstate.cs_TupFromTlist = false;
 
        /*
         * If we haven't materialized yet, just return.
index c1918d9df6f85a43b534e25cfd23c95fa87806dd..dfc4188f86da3a44abce4e03ad6fc6c5a40e6e14 100644 (file)
@@ -303,6 +303,8 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan *parent)
        runtimeKeyInfo = indexstate->iss_RuntimeKeyInfo;
        numScanKeys = indexstate->iss_NumScanKeys;
 
+       node->scan.scanstate->cstate.cs_TupFromTlist = false;
+
        if (econtext)
        {
                /*
@@ -639,6 +641,8 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
         */
        ExecAssignExprContext(estate, &scanstate->cstate);
 
+       scanstate->cstate.cs_TupFromTlist = false;
+
 #define INDEXSCAN_NSLOTS 2
 
        /*
index 1cc11a89f34b14ba8160198d29bcff3dcde41005..d292164904f445357acaaae6cb9cee1651aa1dd3 100644 (file)
@@ -202,6 +202,8 @@ ExecInitResult(Result *node, EState *estate, Plan *parent)
         */
        ExecAssignExprContext(estate, &resstate->cstate);
 
+       resstate->cstate.cs_TupFromTlist = false;
+
 #define RESULT_NSLOTS 1
 
        /*
index 0e930bb343d24c2fff6a33373af190c7041c793a..ce34d91f4b67f6b0ef6cc4569acd83bbebf62006 100644 (file)
@@ -318,6 +318,8 @@ ExecSeqReScan(SeqScan *node, ExprContext *exprCtxt, Plan *parent)
        scanstate = node->scanstate;
        estate = node->plan.state;
 
+       scanstate->cstate.cs_TupFromTlist = false;
+
        /* If this is re-scanning of PlanQual ... */
        if (estate->es_evTuple != NULL &&
                estate->es_evTuple[node->scanrelid - 1] != NULL)
index 45c3252f78481ef42828fb5b50abf0cfb81df9a0..56626009a66f5f457e8df1176ac8dea73c64bbd4 100644 (file)
@@ -259,4 +259,5 @@ ExecSubqueryReScan(SubqueryScan *node, ExprContext *exprCtxt, Plan *parent)
                ExecReScan(node->subplan, NULL, (Plan *) node);
 
        subquerystate->csstate.css_ScanTupleSlot = NULL;
+       subquerystate->csstate.cstate.cs_TupFromTlist = false;
 }
index 8bc3b613e08414c77312111fe0d2ed97a27ef05c..f7e74218eb0f63fde033c4758b5d991ce4840804 100644 (file)
@@ -254,6 +254,8 @@ ExecTidReScan(TidScan *node, ExprContext *exprCtxt, Plan *parent)
        tidstate = node->tidstate;
        tidList = tidstate->tss_TidList;
 
+       node->scan.scanstate->cstate.cs_TupFromTlist = false;
+
        /* If we are being passed an outer tuple, save it for runtime key calc */
        if (exprCtxt != NULL)
                node->scan.scanstate->cstate.cs_ExprContext->ecxt_outertuple =
@@ -411,6 +413,8 @@ ExecInitTidScan(TidScan *node, EState *estate, Plan *parent)
         */
        ExecAssignExprContext(estate, &scanstate->cstate);
 
+       scanstate->cstate.cs_TupFromTlist = false;
+
 #define TIDSCAN_NSLOTS 2
 
        /*