Modify PlanState to have result/result_ready fields.
authorRobert Haas <rhaas@postgresql.org>
Fri, 6 May 2016 17:01:48 +0000 (13:01 -0400)
committerRobert Haas <rhaas@postgresql.org>
Tue, 20 Sep 2016 16:39:56 +0000 (12:39 -0400)
Modify executor to use them instead of returning tuples directly.

68 files changed:
src/backend/executor/execProcnode.c
src/backend/executor/execScan.c
src/backend/executor/nodeAgg.c
src/backend/executor/nodeAppend.c
src/backend/executor/nodeBitmapHeapscan.c
src/backend/executor/nodeCtescan.c
src/backend/executor/nodeCustom.c
src/backend/executor/nodeForeignscan.c
src/backend/executor/nodeFunctionscan.c
src/backend/executor/nodeGather.c
src/backend/executor/nodeGroup.c
src/backend/executor/nodeHash.c
src/backend/executor/nodeHashjoin.c
src/backend/executor/nodeIndexonlyscan.c
src/backend/executor/nodeIndexscan.c
src/backend/executor/nodeLimit.c
src/backend/executor/nodeLockRows.c
src/backend/executor/nodeMaterial.c
src/backend/executor/nodeMergeAppend.c
src/backend/executor/nodeMergejoin.c
src/backend/executor/nodeModifyTable.c
src/backend/executor/nodeNestloop.c
src/backend/executor/nodeRecursiveunion.c
src/backend/executor/nodeResult.c
src/backend/executor/nodeSamplescan.c
src/backend/executor/nodeSeqscan.c
src/backend/executor/nodeSetOp.c
src/backend/executor/nodeSort.c
src/backend/executor/nodeSubqueryscan.c
src/backend/executor/nodeTidscan.c
src/backend/executor/nodeUnique.c
src/backend/executor/nodeValuesscan.c
src/backend/executor/nodeWindowAgg.c
src/backend/executor/nodeWorktablescan.c
src/include/executor/executor.h
src/include/executor/nodeAgg.h
src/include/executor/nodeAppend.h
src/include/executor/nodeBitmapHeapscan.h
src/include/executor/nodeCtescan.h
src/include/executor/nodeCustom.h
src/include/executor/nodeForeignscan.h
src/include/executor/nodeFunctionscan.h
src/include/executor/nodeGather.h
src/include/executor/nodeGroup.h
src/include/executor/nodeHash.h
src/include/executor/nodeHashjoin.h
src/include/executor/nodeIndexonlyscan.h
src/include/executor/nodeIndexscan.h
src/include/executor/nodeLimit.h
src/include/executor/nodeLockRows.h
src/include/executor/nodeMaterial.h
src/include/executor/nodeMergeAppend.h
src/include/executor/nodeMergejoin.h
src/include/executor/nodeModifyTable.h
src/include/executor/nodeNestloop.h
src/include/executor/nodeRecursiveunion.h
src/include/executor/nodeResult.h
src/include/executor/nodeSamplescan.h
src/include/executor/nodeSeqscan.h
src/include/executor/nodeSetOp.h
src/include/executor/nodeSort.h
src/include/executor/nodeSubqueryscan.h
src/include/executor/nodeTidscan.h
src/include/executor/nodeUnique.h
src/include/executor/nodeValuesscan.h
src/include/executor/nodeWindowAgg.h
src/include/executor/nodeWorktablescan.h
src/include/nodes/execnodes.h

index 680ca4b4ed6b2cc8bc42600568d74d61c50b0671..3f2ebff1733911cb1daa48fcd12ff2d8c9ae7682 100644 (file)
@@ -380,6 +380,9 @@ ExecProcNode(PlanState *node)
 
        CHECK_FOR_INTERRUPTS();
 
+       /* mark any previous result as having been consumed */
+       node->result_ready = false;
+
        if (node->chgParam != NULL) /* something changed */
                ExecReScan(node);               /* let ReScan handle this */
 
@@ -392,23 +395,23 @@ ExecProcNode(PlanState *node)
                         * control nodes
                         */
                case T_ResultState:
-                       result = ExecResult((ResultState *) node);
+                       ExecResult((ResultState *) node);
                        break;
 
                case T_ModifyTableState:
-                       result = ExecModifyTable((ModifyTableState *) node);
+                       ExecModifyTable((ModifyTableState *) node);
                        break;
 
                case T_AppendState:
-                       result = ExecAppend((AppendState *) node);
+                       ExecAppend((AppendState *) node);
                        break;
 
                case T_MergeAppendState:
-                       result = ExecMergeAppend((MergeAppendState *) node);
+                       ExecMergeAppend((MergeAppendState *) node);
                        break;
 
                case T_RecursiveUnionState:
-                       result = ExecRecursiveUnion((RecursiveUnionState *) node);
+                       ExecRecursiveUnion((RecursiveUnionState *) node);
                        break;
 
                        /* BitmapAndState does not yield tuples */
@@ -419,119 +422,119 @@ ExecProcNode(PlanState *node)
                         * scan nodes
                         */
                case T_SeqScanState:
-                       result = ExecSeqScan((SeqScanState *) node);
+                       ExecSeqScan((SeqScanState *) node);
                        break;
 
                case T_SampleScanState:
-                       result = ExecSampleScan((SampleScanState *) node);
+                       ExecSampleScan((SampleScanState *) node);
                        break;
 
                case T_IndexScanState:
-                       result = ExecIndexScan((IndexScanState *) node);
+                       ExecIndexScan((IndexScanState *) node);
                        break;
 
                case T_IndexOnlyScanState:
-                       result = ExecIndexOnlyScan((IndexOnlyScanState *) node);
+                       ExecIndexOnlyScan((IndexOnlyScanState *) node);
                        break;
 
                        /* BitmapIndexScanState does not yield tuples */
 
                case T_BitmapHeapScanState:
-                       result = ExecBitmapHeapScan((BitmapHeapScanState *) node);
+                       ExecBitmapHeapScan((BitmapHeapScanState *) node);
                        break;
 
                case T_TidScanState:
-                       result = ExecTidScan((TidScanState *) node);
+                       ExecTidScan((TidScanState *) node);
                        break;
 
                case T_SubqueryScanState:
-                       result = ExecSubqueryScan((SubqueryScanState *) node);
+                       ExecSubqueryScan((SubqueryScanState *) node);
                        break;
 
                case T_FunctionScanState:
-                       result = ExecFunctionScan((FunctionScanState *) node);
+                       ExecFunctionScan((FunctionScanState *) node);
                        break;
 
                case T_ValuesScanState:
-                       result = ExecValuesScan((ValuesScanState *) node);
+                       ExecValuesScan((ValuesScanState *) node);
                        break;
 
                case T_CteScanState:
-                       result = ExecCteScan((CteScanState *) node);
+                       ExecCteScan((CteScanState *) node);
                        break;
 
                case T_WorkTableScanState:
-                       result = ExecWorkTableScan((WorkTableScanState *) node);
+                       ExecWorkTableScan((WorkTableScanState *) node);
                        break;
 
                case T_ForeignScanState:
-                       result = ExecForeignScan((ForeignScanState *) node);
+                       ExecForeignScan((ForeignScanState *) node);
                        break;
 
                case T_CustomScanState:
-                       result = ExecCustomScan((CustomScanState *) node);
+                       ExecCustomScan((CustomScanState *) node);
                        break;
 
                        /*
                         * join nodes
                         */
                case T_NestLoopState:
-                       result = ExecNestLoop((NestLoopState *) node);
+                       ExecNestLoop((NestLoopState *) node);
                        break;
 
                case T_MergeJoinState:
-                       result = ExecMergeJoin((MergeJoinState *) node);
+                       ExecMergeJoin((MergeJoinState *) node);
                        break;
 
                case T_HashJoinState:
-                       result = ExecHashJoin((HashJoinState *) node);
+                       ExecHashJoin((HashJoinState *) node);
                        break;
 
                        /*
                         * materialization nodes
                         */
                case T_MaterialState:
-                       result = ExecMaterial((MaterialState *) node);
+                       ExecMaterial((MaterialState *) node);
                        break;
 
                case T_SortState:
-                       result = ExecSort((SortState *) node);
+                       ExecSort((SortState *) node);
                        break;
 
                case T_GroupState:
-                       result = ExecGroup((GroupState *) node);
+                       ExecGroup((GroupState *) node);
                        break;
 
                case T_AggState:
-                       result = ExecAgg((AggState *) node);
+                       ExecAgg((AggState *) node);
                        break;
 
                case T_WindowAggState:
-                       result = ExecWindowAgg((WindowAggState *) node);
+                       ExecWindowAgg((WindowAggState *) node);
                        break;
 
                case T_UniqueState:
-                       result = ExecUnique((UniqueState *) node);
+                       ExecUnique((UniqueState *) node);
                        break;
 
                case T_GatherState:
-                       result = ExecGather((GatherState *) node);
+                       ExecGather((GatherState *) node);
                        break;
 
                case T_HashState:
-                       result = ExecHash((HashState *) node);
+                       ExecHash((HashState *) node);
                        break;
 
                case T_SetOpState:
-                       result = ExecSetOp((SetOpState *) node);
+                       ExecSetOp((SetOpState *) node);
                        break;
 
                case T_LockRowsState:
-                       result = ExecLockRows((LockRowsState *) node);
+                       ExecLockRows((LockRowsState *) node);
                        break;
 
                case T_LimitState:
-                       result = ExecLimit((LimitState *) node);
+                       ExecLimit((LimitState *) node);
                        break;
 
                default:
@@ -540,6 +543,14 @@ ExecProcNode(PlanState *node)
                        break;
        }
 
+       /* We don't support asynchronous execution yet. */
+       Assert(node->result_ready);
+
+       /* Result should be a TupleTableSlot, unless it's NULL. */
+       Assert(node->result == NULL || IsA(node->result, TupleTableSlot));
+
+       result = (TupleTableSlot *) node->result;
+
        if (node->instrument)
                InstrStopNode(node->instrument, TupIsNull(result) ? 0.0 : 1.0);
 
index fb0013dc534c5599cb628a8a0dd1f81339d40634..095d40bcdc852d5c4e18c4bf965f23caca4a6cc8 100644 (file)
@@ -99,7 +99,7 @@ ExecScanFetch(ScanState *node,
  *             ExecScan
  *
  *             Scans the relation using the 'access method' indicated and
- *             returns the next qualifying tuple in the direction specified
+ *             produces the next qualifying tuple in the direction specified
  *             in the global variable ExecDirection.
  *             The access method returns the next tuple and ExecScan() is
  *             responsible for checking the tuple returned against the qual-clause.
@@ -117,7 +117,7 @@ ExecScanFetch(ScanState *node,
  *                      "cursor" is positioned before the first qualifying tuple.
  * ----------------------------------------------------------------
  */
-TupleTableSlot *
+void
 ExecScan(ScanState *node,
                 ExecScanAccessMtd accessMtd,   /* function returning a tuple */
                 ExecScanRecheckMtd recheckMtd)
@@ -137,12 +137,14 @@ ExecScan(ScanState *node,
 
        /*
         * If we have neither a qual to check nor a projection to do, just skip
-        * all the overhead and return the raw scan tuple.
+        * all the overhead and produce the raw scan tuple.
         */
        if (!qual && !projInfo)
        {
                ResetExprContext(econtext);
-               return ExecScanFetch(node, accessMtd, recheckMtd);
+               ExecReturnTuple(&node->ps,
+                                               ExecScanFetch(node, accessMtd, recheckMtd));
+               return;
        }
 
        /*
@@ -155,7 +157,10 @@ ExecScan(ScanState *node,
                Assert(projInfo);               /* can't get here if not projecting */
                resultSlot = ExecProject(projInfo, &isDone);
                if (isDone == ExprMultipleResult)
-                       return resultSlot;
+               {
+                       ExecReturnTuple(&node->ps, resultSlot);
+                       return;
+               }
                /* Done with that source tuple... */
                node->ps.ps_TupFromTlist = false;
        }
@@ -188,9 +193,10 @@ ExecScan(ScanState *node,
                if (TupIsNull(slot))
                {
                        if (projInfo)
-                               return ExecClearTuple(projInfo->pi_slot);
+                               ExecReturnTuple(&node->ps, ExecClearTuple(projInfo->pi_slot));
                        else
-                               return slot;
+                               ExecReturnTuple(&node->ps, slot);
+                       return;
                }
 
                /*
@@ -221,7 +227,8 @@ ExecScan(ScanState *node,
                                if (isDone != ExprEndResult)
                                {
                                        node->ps.ps_TupFromTlist = (isDone == ExprMultipleResult);
-                                       return resultSlot;
+                                       ExecReturnTuple(&node->ps, resultSlot);
+                                       return;
                                }
                        }
                        else
@@ -229,7 +236,8 @@ ExecScan(ScanState *node,
                                /*
                                 * Here, we aren't projecting, so just return scan tuple.
                                 */
-                               return slot;
+                               ExecReturnTuple(&node->ps, slot);
+                               return;
                        }
                }
                else
index d6aa99c76cadb16d7a071d93ccb6dbe69c21bc3b..e17d76c9e6227f0b2e248290b0d5f1c8b0d068c9 100644 (file)
@@ -1797,7 +1797,7 @@ lookup_hash_entry(AggState *aggstate, TupleTableSlot *inputslot)
  *       stored in the expression context to be used when ExecProject evaluates
  *       the result tuple.
  */
-TupleTableSlot *
+void
 ExecAgg(AggState *node)
 {
        TupleTableSlot *result;
@@ -1813,7 +1813,10 @@ ExecAgg(AggState *node)
 
                result = ExecProject(node->ss.ps.ps_ProjInfo, &isDone);
                if (isDone == ExprMultipleResult)
-                       return result;
+               {
+                       ExecReturnTuple(&node->ss.ps, result);
+                       return;
+               }
                /* Done with that source tuple... */
                node->ss.ps.ps_TupFromTlist = false;
        }
@@ -1823,6 +1826,7 @@ ExecAgg(AggState *node)
         * agg_done gets set before we emit the final aggregate tuple, and we have
         * to finish running SRFs for it.)
         */
+       result = NULL;
        if (!node->agg_done)
        {
                /* Dispatch based on strategy */
@@ -1837,12 +1841,9 @@ ExecAgg(AggState *node)
                                result = agg_retrieve_direct(node);
                                break;
                }
-
-               if (!TupIsNull(result))
-                       return result;
        }
 
-       return NULL;
+       ExecReturnTuple(&node->ss.ps, result);
 }
 
 /*
index beb4ab883de1ff79d8d215be6f972f1d2b7e67fd..e0ce8c6dc719865f904b25880eeb6e8f654c84fe 100644 (file)
@@ -191,7 +191,7 @@ ExecInitAppend(Append *node, EState *estate, int eflags)
  *             Handles iteration over multiple subplans.
  * ----------------------------------------------------------------
  */
-TupleTableSlot *
+void
 ExecAppend(AppendState *node)
 {
        for (;;)
@@ -216,7 +216,8 @@ ExecAppend(AppendState *node)
                         * NOT make use of the result slot that was set up in
                         * ExecInitAppend; there's no need for it.
                         */
-                       return result;
+                       ExecReturnTuple(&node->ps, result);
+                       return;
                }
 
                /*
@@ -229,7 +230,11 @@ ExecAppend(AppendState *node)
                else
                        node->as_whichplan--;
                if (!exec_append_initialize_next(node))
-                       return ExecClearTuple(node->ps.ps_ResultTupleSlot);
+               {
+                       ExecReturnTuple(&node->ps,
+                                                       ExecClearTuple(node->ps.ps_ResultTupleSlot));
+                       return;
+               }
 
                /* Else loop back and try to get a tuple from the new subplan */
        }
index 2ba5cd0514afe3d538a05b8445134632d9805d30..31133ffbf3421834743c4b2ede26bf6cd0123bf6 100644 (file)
@@ -434,7 +434,7 @@ BitmapHeapRecheck(BitmapHeapScanState *node, TupleTableSlot *slot)
  *             ExecBitmapHeapScan(node)
  * ----------------------------------------------------------------
  */
-TupleTableSlot *
+void
 ExecBitmapHeapScan(BitmapHeapScanState *node)
 {
        return ExecScan(&node->ss,
index 3c2f684a062d577f5eb0c66e9b5e6cfc5a6f8289..1f1fdf574fe7beaaf140d1d40bdaf7bcf31a0dd8 100644 (file)
@@ -149,7 +149,7 @@ CteScanRecheck(CteScanState *node, TupleTableSlot *slot)
  *             access method functions.
  * ----------------------------------------------------------------
  */
-TupleTableSlot *
+void
 ExecCteScan(CteScanState *node)
 {
        return ExecScan(&node->ss,
index 322abca282acfad4af0fafcdc1744aa3600746da..716234823eb1d2fda1552af2f501826ba699d678 100644 (file)
@@ -107,11 +107,11 @@ ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags)
        return css;
 }
 
-TupleTableSlot *
+void
 ExecCustomScan(CustomScanState *node)
 {
        Assert(node->methods->ExecCustomScan != NULL);
-       return node->methods->ExecCustomScan(node);
+       ExecReturnTuple(&node->ss.ps, node->methods->ExecCustomScan(node));
 }
 
 void
index 7d9160df95ba96bb334f3eb938c3c93fb0eee96b..1f3e0729519da3a110fd0f03def5a83560ad22b5 100644 (file)
@@ -113,7 +113,7 @@ ForeignRecheck(ForeignScanState *node, TupleTableSlot *slot)
  *             access method functions.
  * ----------------------------------------------------------------
  */
-TupleTableSlot *
+void
 ExecForeignScan(ForeignScanState *node)
 {
        return ExecScan((ScanState *) node,
index 5a0f324de0aaa824fc76f33fcb27dc8c2db41574..5038801054b379fc5bf37e491336718d61abd846 100644 (file)
@@ -262,7 +262,7 @@ FunctionRecheck(FunctionScanState *node, TupleTableSlot *slot)
  *             access method functions.
  * ----------------------------------------------------------------
  */
-TupleTableSlot *
+void
 ExecFunctionScan(FunctionScanState *node)
 {
        return ExecScan(&node->ss,
index 1bf5a31dc59fa93a33ea8a18049743f1e87294b9..e4cfc44016bc5debf3e74c22278648dd321c66d2 100644 (file)
@@ -126,7 +126,7 @@ ExecInitGather(Gather *node, EState *estate, int eflags)
  *             the next qualifying tuple.
  * ----------------------------------------------------------------
  */
-TupleTableSlot *
+void
 ExecGather(GatherState *node)
 {
        TupleTableSlot *fslot = node->funnel_slot;
@@ -207,7 +207,10 @@ ExecGather(GatherState *node)
        {
                resultSlot = ExecProject(node->ps.ps_ProjInfo, &isDone);
                if (isDone == ExprMultipleResult)
-                       return resultSlot;
+               {
+                       ExecReturnTuple(&node->ps, resultSlot);
+                       return;
+               }
                /* Done with that source tuple... */
                node->ps.ps_TupFromTlist = false;
        }
@@ -232,7 +235,10 @@ ExecGather(GatherState *node)
                 */
                slot = gather_getnext(node);
                if (TupIsNull(slot))
-                       return NULL;
+               {
+                       ExecReturnTuple(&node->ps, NULL);
+                       return;
+               }
 
                /*
                 * form the result tuple using ExecProject(), and return it --- unless
@@ -245,11 +251,12 @@ ExecGather(GatherState *node)
                if (isDone != ExprEndResult)
                {
                        node->ps.ps_TupFromTlist = (isDone == ExprMultipleResult);
-                       return resultSlot;
+                       ExecReturnTuple(&node->ps, resultSlot);
+                       return;
                }
        }
 
-       return slot;
+       ExecReturnTuple(&node->ps, slot);
 }
 
 /* ----------------------------------------------------------------
index 3c066fc55e8b72067bd56212123fac7aea0baf25..f33a3162830221e48a770bf5dd1519a09297f9a8 100644 (file)
@@ -31,7 +31,7 @@
  *
  *             Return one tuple for each group of matching input tuples.
  */
-TupleTableSlot *
+void
 ExecGroup(GroupState *node)
 {
        ExprContext *econtext;
@@ -44,7 +44,10 @@ ExecGroup(GroupState *node)
         * get state info from node
         */
        if (node->grp_done)
-               return NULL;
+       {
+               ExecReturnTuple(&node->ss.ps, NULL);
+               return;
+       }
        econtext = node->ss.ps.ps_ExprContext;
        numCols = ((Group *) node->ss.ps.plan)->numCols;
        grpColIdx = ((Group *) node->ss.ps.plan)->grpColIdx;
@@ -61,7 +64,10 @@ ExecGroup(GroupState *node)
 
                result = ExecProject(node->ss.ps.ps_ProjInfo, &isDone);
                if (isDone == ExprMultipleResult)
-                       return result;
+               {
+                       ExecReturnTuple(&node->ss.ps, result);
+                       return;
+               }
                /* Done with that source tuple... */
                node->ss.ps.ps_TupFromTlist = false;
        }
@@ -87,7 +93,8 @@ ExecGroup(GroupState *node)
                {
                        /* empty input, so return nothing */
                        node->grp_done = TRUE;
-                       return NULL;
+                       ExecReturnTuple(&node->ss.ps, NULL);
+                       return;
                }
                /* Copy tuple into firsttupleslot */
                ExecCopySlot(firsttupleslot, outerslot);
@@ -115,7 +122,8 @@ ExecGroup(GroupState *node)
                        if (isDone != ExprEndResult)
                        {
                                node->ss.ps.ps_TupFromTlist = (isDone == ExprMultipleResult);
-                               return result;
+                               ExecReturnTuple(&node->ss.ps, result);
+                               return;
                        }
                }
                else
@@ -139,7 +147,8 @@ ExecGroup(GroupState *node)
                        {
                                /* no more groups, so we're done */
                                node->grp_done = TRUE;
-                               return NULL;
+                               ExecReturnTuple(&node->ss.ps, NULL);
+                               return;
                        }
 
                        /*
@@ -178,7 +187,8 @@ ExecGroup(GroupState *node)
                        if (isDone != ExprEndResult)
                        {
                                node->ss.ps.ps_TupFromTlist = (isDone == ExprMultipleResult);
-                               return result;
+                               ExecReturnTuple(&node->ss.ps, result);
+                               return;
                        }
                }
                else
index 8333e5c861adc880bba8b90fd0b54629fe2bb673..5bc93e07496a3ba718e2acc4e316f20c059114e7 100644 (file)
@@ -56,11 +56,10 @@ static void *dense_alloc(HashJoinTable hashtable, Size size);
  *             stub for pro forma compliance
  * ----------------------------------------------------------------
  */
-TupleTableSlot *
+void
 ExecHash(HashState *node)
 {
        elog(ERROR, "Hash node does not support ExecProcNode call convention");
-       return NULL;
 }
 
 /* ----------------------------------------------------------------
index a7a908a903dc5cb77e1c369207d7c4c144f90654..cc92fc32a82da08143e6d512a6ffd6d4de4314b2 100644 (file)
@@ -58,7 +58,7 @@ static bool ExecHashJoinNewBatch(HashJoinState *hjstate);
  *                       the other one is "outer".
  * ----------------------------------------------------------------
  */
-TupleTableSlot *                               /* return: a tuple or NULL */
+void
 ExecHashJoin(HashJoinState *node)
 {
        PlanState  *outerNode;
@@ -93,7 +93,10 @@ ExecHashJoin(HashJoinState *node)
 
                result = ExecProject(node->js.ps.ps_ProjInfo, &isDone);
                if (isDone == ExprMultipleResult)
-                       return result;
+               {
+                       ExecReturnTuple(&node->js.ps, result);
+                       return;
+               }
                /* Done with that source tuple... */
                node->js.ps.ps_TupFromTlist = false;
        }
@@ -155,7 +158,8 @@ ExecHashJoin(HashJoinState *node)
                                        if (TupIsNull(node->hj_FirstOuterTupleSlot))
                                        {
                                                node->hj_OuterNotEmpty = false;
-                                               return NULL;
+                                               ExecReturnTuple(&node->js.ps, NULL);
+                                               return;
                                        }
                                        else
                                                node->hj_OuterNotEmpty = true;
@@ -183,7 +187,10 @@ ExecHashJoin(HashJoinState *node)
                                 * outer relation.
                                 */
                                if (hashtable->totalTuples == 0 && !HJ_FILL_OUTER(node))
-                                       return NULL;
+                               {
+                                       ExecReturnTuple(&node->js.ps, NULL);
+                                       return;
+                               }
 
                                /*
                                 * need to remember whether nbatch has increased since we
@@ -323,7 +330,8 @@ ExecHashJoin(HashJoinState *node)
                                                {
                                                        node->js.ps.ps_TupFromTlist =
                                                                (isDone == ExprMultipleResult);
-                                                       return result;
+                                                       ExecReturnTuple(&node->js.ps, result);
+                                                       return;
                                                }
                                        }
                                        else
@@ -362,7 +370,8 @@ ExecHashJoin(HashJoinState *node)
                                                {
                                                        node->js.ps.ps_TupFromTlist =
                                                                (isDone == ExprMultipleResult);
-                                                       return result;
+                                                       ExecReturnTuple(&node->js.ps, result);
+                                                       return;
                                                }
                                        }
                                        else
@@ -401,7 +410,8 @@ ExecHashJoin(HashJoinState *node)
                                        {
                                                node->js.ps.ps_TupFromTlist =
                                                        (isDone == ExprMultipleResult);
-                                               return result;
+                                               ExecReturnTuple(&node->js.ps, result);
+                                               return;
                                        }
                                }
                                else
@@ -414,7 +424,10 @@ ExecHashJoin(HashJoinState *node)
                                 * Try to advance to next batch.  Done if there are no more.
                                 */
                                if (!ExecHashJoinNewBatch(node))
-                                       return NULL;    /* end of join */
+                               {
+                                       ExecReturnTuple(&node->js.ps, NULL); /* end of join */
+                                       return;
+                               }
                                node->hj_JoinState = HJ_NEED_NEW_OUTER;
                                break;
 
index 4f6f91c8dbac11b912b1280536802da0109fedf8..47285a13f0965321fce3e3b567a354be4df17073 100644 (file)
@@ -249,7 +249,7 @@ IndexOnlyRecheck(IndexOnlyScanState *node, TupleTableSlot *slot)
  *             ExecIndexOnlyScan(node)
  * ----------------------------------------------------------------
  */
-TupleTableSlot *
+void
 ExecIndexOnlyScan(IndexOnlyScanState *node)
 {
        /*
index 3143bd94ec4499fba94b41693538b785c4b32e6c..6bf35d35d33acc7ec2c758eda54cb8fb5e8cb1c7 100644 (file)
@@ -482,7 +482,7 @@ reorderqueue_pop(IndexScanState *node)
  *             ExecIndexScan(node)
  * ----------------------------------------------------------------
  */
-TupleTableSlot *
+void
 ExecIndexScan(IndexScanState *node)
 {
        /*
index 97267c587c6caebf57ef806212ba5fccd96ac87a..4e701830bb49266f7bdc340b7f7ff8d3cbc693ba 100644 (file)
@@ -36,7 +36,7 @@ static void pass_down_bound(LimitState *node, PlanState *child_node);
  *             filtering on the stream of tuples returned by a subplan.
  * ----------------------------------------------------------------
  */
-TupleTableSlot *                               /* return: a tuple or NULL */
+void
 ExecLimit(LimitState *node)
 {
        ScanDirection direction;
@@ -72,7 +72,10 @@ ExecLimit(LimitState *node)
                         * If backwards scan, just return NULL without changing state.
                         */
                        if (!ScanDirectionIsForward(direction))
-                               return NULL;
+                       {
+                               ExecReturnTuple(&node->ps, NULL);
+                               return;
+                       }
 
                        /*
                         * Check for empty window; if so, treat like empty subplan.
@@ -80,7 +83,8 @@ ExecLimit(LimitState *node)
                        if (node->count <= 0 && !node->noCount)
                        {
                                node->lstate = LIMIT_EMPTY;
-                               return NULL;
+                               ExecReturnTuple(&node->ps, NULL);
+                               return;
                        }
 
                        /*
@@ -96,7 +100,8 @@ ExecLimit(LimitState *node)
                                         * any output at all.
                                         */
                                        node->lstate = LIMIT_EMPTY;
-                                       return NULL;
+                                       ExecReturnTuple(&node->ps, NULL);
+                                       return;
                                }
                                node->subSlot = slot;
                                if (++node->position > node->offset)
@@ -115,7 +120,8 @@ ExecLimit(LimitState *node)
                         * The subplan is known to return no tuples (or not more than
                         * OFFSET tuples, in general).  So we return no tuples.
                         */
-                       return NULL;
+                       ExecReturnTuple(&node->ps, NULL);
+                       return;
 
                case LIMIT_INWINDOW:
                        if (ScanDirectionIsForward(direction))
@@ -130,7 +136,8 @@ ExecLimit(LimitState *node)
                                        node->position - node->offset >= node->count)
                                {
                                        node->lstate = LIMIT_WINDOWEND;
-                                       return NULL;
+                                       ExecReturnTuple(&node->ps, NULL);
+                                       return;
                                }
 
                                /*
@@ -140,7 +147,8 @@ ExecLimit(LimitState *node)
                                if (TupIsNull(slot))
                                {
                                        node->lstate = LIMIT_SUBPLANEOF;
-                                       return NULL;
+                                       ExecReturnTuple(&node->ps, NULL);
+                                       return;
                                }
                                node->subSlot = slot;
                                node->position++;
@@ -154,7 +162,8 @@ ExecLimit(LimitState *node)
                                if (node->position <= node->offset + 1)
                                {
                                        node->lstate = LIMIT_WINDOWSTART;
-                                       return NULL;
+                                       ExecReturnTuple(&node->ps, NULL);
+                                       return;
                                }
 
                                /*
@@ -170,7 +179,10 @@ ExecLimit(LimitState *node)
 
                case LIMIT_SUBPLANEOF:
                        if (ScanDirectionIsForward(direction))
-                               return NULL;
+                       {
+                               ExecReturnTuple(&node->ps, NULL);
+                               return;
+                       }
 
                        /*
                         * Backing up from subplan EOF, so re-fetch previous tuple; there
@@ -186,7 +198,10 @@ ExecLimit(LimitState *node)
 
                case LIMIT_WINDOWEND:
                        if (ScanDirectionIsForward(direction))
-                               return NULL;
+                       {
+                               ExecReturnTuple(&node->ps, NULL);
+                               return;
+                       }
 
                        /*
                         * Backing up from window end: simply re-return the last tuple
@@ -199,7 +214,10 @@ ExecLimit(LimitState *node)
 
                case LIMIT_WINDOWSTART:
                        if (!ScanDirectionIsForward(direction))
-                               return NULL;
+                       {
+                               ExecReturnTuple(&node->ps, NULL);
+                               return;
+                       }
 
                        /*
                         * Advancing after having backed off window start: simply
@@ -220,7 +238,7 @@ ExecLimit(LimitState *node)
        /* Return the current tuple */
        Assert(!TupIsNull(slot));
 
-       return slot;
+       ExecReturnTuple(&node->ps, slot);
 }
 
 /*
index c4b533354b998d9f44aed3d0bb94cb6e2f826570..8daa2035764bab6cdb5bcb97de3493db9f54818d 100644 (file)
@@ -35,7 +35,7 @@
  *             ExecLockRows
  * ----------------------------------------------------------------
  */
-TupleTableSlot *                               /* return: a tuple or NULL */
+void
 ExecLockRows(LockRowsState *node)
 {
        TupleTableSlot *slot;
@@ -57,7 +57,10 @@ lnext:
        slot = ExecProcNode(outerPlan);
 
        if (TupIsNull(slot))
-               return NULL;
+       {
+               ExecReturnTuple(&node->ps, NULL);
+               return;
+       }
 
        /* We don't need EvalPlanQual unless we get updated tuple version(s) */
        epq_needed = false;
@@ -334,7 +337,7 @@ lnext:
        }
 
        /* Got all locks, so return the current tuple */
-       return slot;
+       ExecReturnTuple(&node->ps, slot);
 }
 
 /* ----------------------------------------------------------------
index 82e31c123d2f2e233563815dd2c3a4b669685047..fd3b013e006e1d789242ef64ea2edb05a9510440 100644 (file)
@@ -35,7 +35,7 @@
  *
  * ----------------------------------------------------------------
  */
-TupleTableSlot *                               /* result tuple from subplan */
+void
 ExecMaterial(MaterialState *node)
 {
        EState     *estate;
@@ -93,7 +93,11 @@ ExecMaterial(MaterialState *node)
                         * fetch.
                         */
                        if (!tuplestore_advance(tuplestorestate, forward))
-                               return NULL;    /* the tuplestore must be empty */
+                       {
+                               /* the tuplestore must be empty */
+                               ExecReturnTuple(&node->ss.ps, NULL);
+                               return;
+                       }
                }
                eof_tuplestore = false;
        }
@@ -105,7 +109,10 @@ ExecMaterial(MaterialState *node)
        if (!eof_tuplestore)
        {
                if (tuplestore_gettupleslot(tuplestorestate, forward, false, slot))
-                       return slot;
+               {
+                       ExecReturnTuple(&node->ss.ps, slot);
+                       return;
+               }
                if (forward)
                        eof_tuplestore = true;
        }
@@ -132,7 +139,8 @@ ExecMaterial(MaterialState *node)
                if (TupIsNull(outerslot))
                {
                        node->eof_underlying = true;
-                       return NULL;
+                       ExecReturnTuple(&node->ss.ps, NULL);
+                       return;
                }
 
                /*
@@ -146,13 +154,14 @@ ExecMaterial(MaterialState *node)
                /*
                 * We can just return the subplan's returned tuple, without copying.
                 */
-               return outerslot;
+               ExecReturnTuple(&node->ss.ps, outerslot);
+               return;
        }
 
        /*
         * Nothing left ...
         */
-       return ExecClearTuple(slot);
+       ExecReturnTuple(&node->ss.ps, ExecClearTuple(slot));
 }
 
 /* ----------------------------------------------------------------
index ae0e8dce68609599d3fe86405a55a9c0ee187ee2..3ef81205e2100ba6890cfedd79264463cc0ca474 100644 (file)
@@ -164,7 +164,7 @@ ExecInitMergeAppend(MergeAppend *node, EState *estate, int eflags)
  *             Handles iteration over multiple subplans.
  * ----------------------------------------------------------------
  */
-TupleTableSlot *
+void
 ExecMergeAppend(MergeAppendState *node)
 {
        TupleTableSlot *result;
@@ -214,7 +214,7 @@ ExecMergeAppend(MergeAppendState *node)
                result = node->ms_slots[i];
        }
 
-       return result;
+       ExecReturnTuple(&node->ps, result);
 }
 
 /*
index cd8d6c68c1d2a5374c085c476c6514423b95f06e..d73d9f4735afdbaa75baf1f630adc9aa46bd5d03 100644 (file)
@@ -615,7 +615,7 @@ ExecMergeTupleDump(MergeJoinState *mergestate)
  *             ExecMergeJoin
  * ----------------------------------------------------------------
  */
-TupleTableSlot *
+void
 ExecMergeJoin(MergeJoinState *node)
 {
        List       *joinqual;
@@ -653,7 +653,10 @@ ExecMergeJoin(MergeJoinState *node)
 
                result = ExecProject(node->js.ps.ps_ProjInfo, &isDone);
                if (isDone == ExprMultipleResult)
-                       return result;
+               {
+                       ExecReturnTuple(&node->js.ps, result);
+                       return;
+               }
                /* Done with that source tuple... */
                node->js.ps.ps_TupFromTlist = false;
        }
@@ -710,7 +713,10 @@ ExecMergeJoin(MergeJoinState *node)
 
                                                        result = MJFillOuter(node);
                                                        if (result)
-                                                               return result;
+                                                       {
+                                                               ExecReturnTuple(&node->js.ps, result);
+                                                               return;
+                                                       }
                                                }
                                                break;
                                        case MJEVAL_ENDOFJOIN:
@@ -728,7 +734,8 @@ ExecMergeJoin(MergeJoinState *node)
                                                        break;
                                                }
                                                /* Otherwise we're done. */
-                                               return NULL;
+                                               ExecReturnTuple(&node->js.ps, NULL);
+                                               return;
                                }
                                break;
 
@@ -765,7 +772,10 @@ ExecMergeJoin(MergeJoinState *node)
 
                                                        result = MJFillInner(node);
                                                        if (result)
-                                                               return result;
+                                                       {
+                                                               ExecReturnTuple(&node->js.ps, result);
+                                                               return;
+                                                       }
                                                }
                                                break;
                                        case MJEVAL_ENDOFJOIN:
@@ -785,7 +795,8 @@ ExecMergeJoin(MergeJoinState *node)
                                                        break;
                                                }
                                                /* Otherwise we're done. */
-                                               return NULL;
+                                               ExecReturnTuple(&node->js.ps, NULL);
+                                               return;
                                }
                                break;
 
@@ -868,7 +879,8 @@ ExecMergeJoin(MergeJoinState *node)
                                                {
                                                        node->js.ps.ps_TupFromTlist =
                                                                (isDone == ExprMultipleResult);
-                                                       return result;
+                                                       ExecReturnTuple(&node->js.ps, result);
+                                                       return;
                                                }
                                        }
                                        else
@@ -901,7 +913,10 @@ ExecMergeJoin(MergeJoinState *node)
 
                                        result = MJFillInner(node);
                                        if (result)
-                                               return result;
+                                       {
+                                               ExecReturnTuple(&node->js.ps, result);
+                                               return;
+                                       }
                                }
 
                                /*
@@ -1003,7 +1018,10 @@ ExecMergeJoin(MergeJoinState *node)
 
                                        result = MJFillOuter(node);
                                        if (result)
-                                               return result;
+                                       {
+                                               ExecReturnTuple(&node->js.ps, result);
+                                               return;
+                                       }
                                }
 
                                /*
@@ -1039,7 +1057,8 @@ ExecMergeJoin(MergeJoinState *node)
                                                        break;
                                                }
                                                /* Otherwise we're done. */
-                                               return NULL;
+                                               ExecReturnTuple(&node->js.ps, NULL);
+                                               return;
                                }
                                break;
 
@@ -1174,7 +1193,8 @@ ExecMergeJoin(MergeJoinState *node)
                                                                break;
                                                        }
                                                        /* Otherwise we're done. */
-                                                       return NULL;
+                                                       ExecReturnTuple(&node->js.ps, NULL);
+                                                       return;
                                        }
                                }
                                break;
@@ -1256,7 +1276,10 @@ ExecMergeJoin(MergeJoinState *node)
 
                                        result = MJFillOuter(node);
                                        if (result)
-                                               return result;
+                                       {
+                                               ExecReturnTuple(&node->js.ps, result);
+                                               return;
+                                       }
                                }
 
                                /*
@@ -1292,7 +1315,8 @@ ExecMergeJoin(MergeJoinState *node)
                                                        break;
                                                }
                                                /* Otherwise we're done. */
-                                               return NULL;
+                                               ExecReturnTuple(&node->js.ps, NULL);
+                                               return;
                                }
                                break;
 
@@ -1318,7 +1342,10 @@ ExecMergeJoin(MergeJoinState *node)
 
                                        result = MJFillInner(node);
                                        if (result)
-                                               return result;
+                                       {
+                                               ExecReturnTuple(&node->js.ps, result);
+                                               return;
+                                       }
                                }
 
                                /* Mark before advancing, if wanted */
@@ -1362,7 +1389,8 @@ ExecMergeJoin(MergeJoinState *node)
                                                        break;
                                                }
                                                /* Otherwise we're done. */
-                                               return NULL;
+                                               ExecReturnTuple(&node->js.ps, NULL);
+                                               return;
                                }
                                break;
 
@@ -1388,7 +1416,10 @@ ExecMergeJoin(MergeJoinState *node)
 
                                        result = MJFillInner(node);
                                        if (result)
-                                               return result;
+                                       {
+                                               ExecReturnTuple(&node->js.ps, result);
+                                               return;
+                                       }
                                }
 
                                /* Mark before advancing, if wanted */
@@ -1406,7 +1437,8 @@ ExecMergeJoin(MergeJoinState *node)
                                if (TupIsNull(innerTupleSlot))
                                {
                                        MJ_printf("ExecMergeJoin: end of inner subplan\n");
-                                       return NULL;
+                                       ExecReturnTuple(&node->js.ps, NULL);
+                                       return;
                                }
 
                                /* Else remain in ENDOUTER state and process next tuple. */
@@ -1434,7 +1466,10 @@ ExecMergeJoin(MergeJoinState *node)
 
                                        result = MJFillOuter(node);
                                        if (result)
-                                               return result;
+                                       {
+                                               ExecReturnTuple(&node->js.ps, result);
+                                               return;
+                                       }
                                }
 
                                /*
@@ -1448,7 +1483,8 @@ ExecMergeJoin(MergeJoinState *node)
                                if (TupIsNull(outerTupleSlot))
                                {
                                        MJ_printf("ExecMergeJoin: end of outer subplan\n");
-                                       return NULL;
+                                       ExecReturnTuple(&node->js.ps, NULL);
+                                       return;
                                }
 
                                /* Else remain in ENDINNER state and process next tuple. */
index 95cc2c63a56bc87d2eecd70d8cd4130b77146963..0e05d4d0648b4999815bc735dae07185c9c5e645 100644 (file)
@@ -1298,7 +1298,7 @@ fireASTriggers(ModifyTableState *node)
  *             if needed.
  * ----------------------------------------------------------------
  */
-TupleTableSlot *
+void
 ExecModifyTable(ModifyTableState *node)
 {
        EState     *estate = node->ps.state;
@@ -1333,7 +1333,10 @@ ExecModifyTable(ModifyTableState *node)
         * extra times.
         */
        if (node->mt_done)
-               return NULL;
+       {
+               ExecReturnTuple(&node->ps, NULL);
+               return;
+       }
 
        /*
         * On first call, fire BEFORE STATEMENT triggers before proceeding.
@@ -1411,7 +1414,8 @@ ExecModifyTable(ModifyTableState *node)
                        slot = ExecProcessReturning(resultRelInfo, NULL, planSlot);
 
                        estate->es_result_relation_info = saved_resultRelInfo;
-                       return slot;
+                       ExecReturnTuple(&node->ps, slot);
+                       return;
                }
 
                EvalPlanQualSetSlot(&node->mt_epqstate, planSlot);
@@ -1517,7 +1521,8 @@ ExecModifyTable(ModifyTableState *node)
                if (slot)
                {
                        estate->es_result_relation_info = saved_resultRelInfo;
-                       return slot;
+                       ExecReturnTuple(&node->ps, slot);
+                       return;
                }
        }
 
@@ -1531,7 +1536,7 @@ ExecModifyTable(ModifyTableState *node)
 
        node->mt_done = true;
 
-       return NULL;
+       ExecReturnTuple(&node->ps, NULL);
 }
 
 /* ----------------------------------------------------------------
index 1895b60459d13c0bb5d9e297d35d2b006b609ba5..54eff56c8c20f0b82cee8acf43ee4e88c3c9bb7d 100644 (file)
@@ -56,7 +56,7 @@
  *                        are prepared to return the first tuple.
  * ----------------------------------------------------------------
  */
-TupleTableSlot *
+void
 ExecNestLoop(NestLoopState *node)
 {
        NestLoop   *nl;
@@ -93,7 +93,10 @@ ExecNestLoop(NestLoopState *node)
 
                result = ExecProject(node->js.ps.ps_ProjInfo, &isDone);
                if (isDone == ExprMultipleResult)
-                       return result;
+               {
+                       ExecReturnTuple(&node->js.ps, result);
+                       return;
+               }
                /* Done with that source tuple... */
                node->js.ps.ps_TupFromTlist = false;
        }
@@ -128,7 +131,8 @@ ExecNestLoop(NestLoopState *node)
                        if (TupIsNull(outerTupleSlot))
                        {
                                ENL1_printf("no outer tuple, ending join");
-                               return NULL;
+                               ExecReturnTuple(&node->js.ps, NULL);
+                               return;
                        }
 
                        ENL1_printf("saving new outer tuple information");
@@ -212,7 +216,8 @@ ExecNestLoop(NestLoopState *node)
                                        {
                                                node->js.ps.ps_TupFromTlist =
                                                        (isDone == ExprMultipleResult);
-                                               return result;
+                                               ExecReturnTuple(&node->js.ps, result);
+                                               return;
                                        }
                                }
                                else
@@ -270,7 +275,8 @@ ExecNestLoop(NestLoopState *node)
                                {
                                        node->js.ps.ps_TupFromTlist =
                                                (isDone == ExprMultipleResult);
-                                       return result;
+                                       ExecReturnTuple(&node->js.ps, result);
+                                       return;
                                }
                        }
                        else
index 627370f56c54ebc99c1c056b167344168335db53..8a29df8cedb7a7f429c23f8870a08b74412c8118 100644 (file)
@@ -72,7 +72,7 @@ build_hash_table(RecursiveUnionState *rustate)
  * 2.6 go back to 2.2
  * ----------------------------------------------------------------
  */
-TupleTableSlot *
+void
 ExecRecursiveUnion(RecursiveUnionState *node)
 {
        PlanState  *outerPlan = outerPlanState(node);
@@ -102,7 +102,8 @@ ExecRecursiveUnion(RecursiveUnionState *node)
                        /* Each non-duplicate tuple goes to the working table ... */
                        tuplestore_puttupleslot(node->working_table, slot);
                        /* ... and to the caller */
-                       return slot;
+                       ExecReturnTuple(&node->ps, slot);
+                       return;
                }
                node->recursing = true;
        }
@@ -151,10 +152,11 @@ ExecRecursiveUnion(RecursiveUnionState *node)
                node->intermediate_empty = false;
                tuplestore_puttupleslot(node->intermediate_table, slot);
                /* ... and return it */
-               return slot;
+               ExecReturnTuple(&node->ps, slot);
+               return;
        }
 
-       return NULL;
+       ExecReturnTuple(&node->ps, NULL);
 }
 
 /* ----------------------------------------------------------------
index 0d2de14f87459d57545717d35ed6f43360a200ad..a830ffdce9b30fe9f01742a2534bce4888b6cf7c 100644 (file)
@@ -63,7 +63,7 @@
  *             'nil' if the constant qualification is not satisfied.
  * ----------------------------------------------------------------
  */
-TupleTableSlot *
+void
 ExecResult(ResultState *node)
 {
        TupleTableSlot *outerTupleSlot;
@@ -87,7 +87,8 @@ ExecResult(ResultState *node)
                if (!qualResult)
                {
                        node->rs_done = true;
-                       return NULL;
+                       ExecReturnTuple(&node->ps, NULL);
+                       return;
                }
        }
 
@@ -100,7 +101,10 @@ ExecResult(ResultState *node)
        {
                resultSlot = ExecProject(node->ps.ps_ProjInfo, &isDone);
                if (isDone == ExprMultipleResult)
-                       return resultSlot;
+               {
+                       ExecReturnTuple(&node->ps, resultSlot);
+                       return;
+               }
                /* Done with that source tuple... */
                node->ps.ps_TupFromTlist = false;
        }
@@ -130,7 +134,10 @@ ExecResult(ResultState *node)
                        outerTupleSlot = ExecProcNode(outerPlan);
 
                        if (TupIsNull(outerTupleSlot))
-                               return NULL;
+                       {
+                               ExecReturnTuple(&node->ps, NULL);
+                               return;
+                       }
 
                        /*
                         * prepare to compute projection expressions, which will expect to
@@ -157,11 +164,12 @@ ExecResult(ResultState *node)
                if (isDone != ExprEndResult)
                {
                        node->ps.ps_TupFromTlist = (isDone == ExprMultipleResult);
-                       return resultSlot;
+                       ExecReturnTuple(&node->ps, resultSlot);
+                       return;
                }
        }
 
-       return NULL;
+       ExecReturnTuple(&node->ps, NULL);
 }
 
 /* ----------------------------------------------------------------
index 9ce7c02aff415c2239f42f48e55e1735ee75519c..89cce0e4a9b2d706b103fe63fb72078ffea18637 100644 (file)
@@ -95,7 +95,7 @@ SampleRecheck(SampleScanState *node, TupleTableSlot *slot)
  *             access method functions.
  * ----------------------------------------------------------------
  */
-TupleTableSlot *
+void
 ExecSampleScan(SampleScanState *node)
 {
        return ExecScan((ScanState *) node,
index 00bf3a58b1ab42b1f1ecca40f15b01816b4a1c88..0ca86d92b994c36ba6194dab208d4f5030a6cf20 100644 (file)
@@ -121,7 +121,7 @@ SeqRecheck(SeqScanState *node, TupleTableSlot *slot)
  *             access method functions.
  * ----------------------------------------------------------------
  */
-TupleTableSlot *
+void
 ExecSeqScan(SeqScanState *node)
 {
        return ExecScan((ScanState *) node,
index 8b05795dfd6727967ccf6d41571b88cb15c823bd..fe12631529fd897607ca31191a4f22b7419f06cf 100644 (file)
@@ -191,7 +191,7 @@ set_output_count(SetOpState *setopstate, SetOpStatePerGroup pergroup)
  *             ExecSetOp
  * ----------------------------------------------------------------
  */
-TupleTableSlot *                               /* return: a tuple or NULL */
+void
 ExecSetOp(SetOpState *node)
 {
        SetOp      *plannode = (SetOp *) node->ps.plan;
@@ -204,22 +204,26 @@ ExecSetOp(SetOpState *node)
        if (node->numOutput > 0)
        {
                node->numOutput--;
-               return resultTupleSlot;
+               ExecReturnTuple(&node->ps, resultTupleSlot);
+               return;
        }
 
        /* Otherwise, we're done if we are out of groups */
        if (node->setop_done)
-               return NULL;
+       {
+               ExecReturnTuple(&node->ps, NULL);
+               return;
+       }
 
        /* Fetch the next tuple group according to the correct strategy */
        if (plannode->strategy == SETOP_HASHED)
        {
                if (!node->table_filled)
                        setop_fill_hash_table(node);
-               return setop_retrieve_hash_table(node);
+               ExecReturnTuple(&node->ps, setop_retrieve_hash_table(node));
        }
        else
-               return setop_retrieve_direct(node);
+               ExecReturnTuple(&node->ps, setop_retrieve_direct(node));
 }
 
 /*
index 0286a7fdf37fe322995267c31da6f3c9b91a3a01..13f721abfca5f72092df932902ef27db43766fff 100644 (file)
@@ -35,7 +35,7 @@
  *               -- the outer child is prepared to return the first tuple.
  * ----------------------------------------------------------------
  */
-TupleTableSlot *
+void
 ExecSort(SortState *node)
 {
        EState     *estate;
@@ -138,7 +138,7 @@ ExecSort(SortState *node)
        (void) tuplesort_gettupleslot(tuplesortstate,
                                                                  ScanDirectionIsForward(dir),
                                                                  slot, NULL);
-       return slot;
+       ExecReturnTuple(&node->ss.ps, slot);
 }
 
 /* ----------------------------------------------------------------
index cb007a578cba023e1fde9a170fc7b8d9acb15e2b..0562926f8a8079ffc9151df985f73c31bf82c50d 100644 (file)
@@ -79,7 +79,7 @@ SubqueryRecheck(SubqueryScanState *node, TupleTableSlot *slot)
  *             access method functions.
  * ----------------------------------------------------------------
  */
-TupleTableSlot *
+void
 ExecSubqueryScan(SubqueryScanState *node)
 {
        return ExecScan(&node->ss,
index 2604103352949ff9c96860a0f3872255264091d6..e2a0479045aa4e675bb1176238fe47bffb99223f 100644 (file)
@@ -387,7 +387,7 @@ TidRecheck(TidScanState *node, TupleTableSlot *slot)
  *               -- tidPtr is -1.
  * ----------------------------------------------------------------
  */
-TupleTableSlot *
+void
 ExecTidScan(TidScanState *node)
 {
        return ExecScan(&node->ss,
index 3b89e846672cda9084c1d4d650a0a27f039643e6..ac8932303aaccd1e56d9ae5084a3d3000d6fb314 100644 (file)
@@ -42,7 +42,7 @@
  *             ExecUnique
  * ----------------------------------------------------------------
  */
-TupleTableSlot *                               /* return: a tuple or NULL */
+void
 ExecUnique(UniqueState *node)
 {
        Unique     *plannode = (Unique *) node->ps.plan;
@@ -70,8 +70,8 @@ ExecUnique(UniqueState *node)
                if (TupIsNull(slot))
                {
                        /* end of subplan, so we're done */
-                       ExecClearTuple(resultTupleSlot);
-                       return NULL;
+                       ExecReturnTuple(&node->ps, ExecClearTuple(resultTupleSlot));
+                       return;
                }
 
                /*
@@ -98,7 +98,7 @@ ExecUnique(UniqueState *node)
         * won't guarantee that this source tuple is still accessible after
         * fetching the next source tuple.
         */
-       return ExecCopySlot(resultTupleSlot, slot);
+       ExecReturnTuple(&node->ps, ExecCopySlot(resultTupleSlot, slot));
 }
 
 /* ----------------------------------------------------------------
index 9c03f8ae16680b57fa76e46f956093b032d40295..3e6c321d12fdf111b9330b793ebbff324da6fee1 100644 (file)
@@ -186,7 +186,7 @@ ValuesRecheck(ValuesScanState *node, TupleTableSlot *slot)
  *             access method functions.
  * ----------------------------------------------------------------
  */
-TupleTableSlot *
+void
 ExecValuesScan(ValuesScanState *node)
 {
        return ExecScan(&node->ss,
index f12fe2689242a1a6a50175950b1a780cc87a2b2e..16c02f8259cade0678c95bc2276c2d4da559f58b 100644 (file)
@@ -1555,7 +1555,7 @@ update_frametailpos(WindowObject winobj, TupleTableSlot *slot)
  *     (ignoring the case of SRFs in the targetlist, that is).
  * -----------------
  */
-TupleTableSlot *
+void
 ExecWindowAgg(WindowAggState *winstate)
 {
        TupleTableSlot *result;
@@ -1565,7 +1565,10 @@ ExecWindowAgg(WindowAggState *winstate)
        int                     numfuncs;
 
        if (winstate->all_done)
-               return NULL;
+       {
+               ExecReturnTuple(&winstate->ss.ps, NULL);
+               return;
+       }
 
        /*
         * Check to see if we're still projecting out tuples from a previous
@@ -1579,7 +1582,10 @@ ExecWindowAgg(WindowAggState *winstate)
 
                result = ExecProject(winstate->ss.ps.ps_ProjInfo, &isDone);
                if (isDone == ExprMultipleResult)
-                       return result;
+               {
+                       ExecReturnTuple(&winstate->ss.ps, result);
+                       return;
+               }
                /* Done with that source tuple... */
                winstate->ss.ps.ps_TupFromTlist = false;
        }
@@ -1687,7 +1693,8 @@ restart:
                else
                {
                        winstate->all_done = true;
-                       return NULL;
+                       ExecReturnTuple(&winstate->ss.ps, NULL);
+                       return;
                }
        }
 
@@ -1753,7 +1760,7 @@ restart:
 
        winstate->ss.ps.ps_TupFromTlist =
                (isDone == ExprMultipleResult);
-       return result;
+       ExecReturnTuple(&winstate->ss.ps, result);
 }
 
 /* -----------------
index cfed6e6329087a49ef3a74e6199ffc8cc10f94b4..c3615b2f57503ae17bdc9fa7a80341bf7ad3f9c6 100644 (file)
@@ -77,7 +77,7 @@ WorkTableScanRecheck(WorkTableScanState *node, TupleTableSlot *slot)
  *             access method functions.
  * ----------------------------------------------------------------
  */
-TupleTableSlot *
+void
 ExecWorkTableScan(WorkTableScanState *node)
 {
        /*
index 28c0c2e1bb1dc5bf06f47e3ffd9e40acf42c27a6..1eb09d80a0fdd94739d9cc62cf2940349d4397b9 100644 (file)
@@ -228,6 +228,15 @@ extern Node *MultiExecProcNode(PlanState *node);
 extern void ExecEndNode(PlanState *node);
 extern bool ExecShutdownNode(PlanState *node);
 
+/* Convenience function to set a node's result to a TupleTableSlot. */
+static inline void
+ExecReturnTuple(PlanState *node, TupleTableSlot *slot)
+{
+       Assert(!node->result_ready);
+       node->result = (Node *) slot;
+       node->result_ready = true;
+}
+
 /*
  * prototypes from functions in execQual.c
  */
@@ -256,7 +265,7 @@ extern TupleTableSlot *ExecProject(ProjectionInfo *projInfo,
 typedef TupleTableSlot *(*ExecScanAccessMtd) (ScanState *node);
 typedef bool (*ExecScanRecheckMtd) (ScanState *node, TupleTableSlot *slot);
 
-extern TupleTableSlot *ExecScan(ScanState *node, ExecScanAccessMtd accessMtd,
+extern void ExecScan(ScanState *node, ExecScanAccessMtd accessMtd,
                 ExecScanRecheckMtd recheckMtd);
 extern void ExecAssignScanProjectionInfo(ScanState *node);
 extern void ExecAssignScanProjectionInfoWithVarno(ScanState *node, Index varno);
index 54c75e8f31d660979a1f13e0a228d1df3d345b3c..b86ec6ac6e0aa11008ab67562a4ba0ebcf8b4514 100644 (file)
@@ -17,7 +17,7 @@
 #include "nodes/execnodes.h"
 
 extern AggState *ExecInitAgg(Agg *node, EState *estate, int eflags);
-extern TupleTableSlot *ExecAgg(AggState *node);
+extern void ExecAgg(AggState *node);
 extern void ExecEndAgg(AggState *node);
 extern void ExecReScanAgg(AggState *node);
 
index 51c381ee88b884ea7727c0a2a3650610ed2e716b..70a6b62f4a5f4f49cce65881a4ff3a4b40aa490a 100644 (file)
@@ -17,7 +17,7 @@
 #include "nodes/execnodes.h"
 
 extern AppendState *ExecInitAppend(Append *node, EState *estate, int eflags);
-extern TupleTableSlot *ExecAppend(AppendState *node);
+extern void ExecAppend(AppendState *node);
 extern void ExecEndAppend(AppendState *node);
 extern void ExecReScanAppend(AppendState *node);
 
index 0ed9c7888aaa9befcc62ba0bf8c82bf7f9da1990..069dbc7bc4930f37db66b94c22670abcd1b10a8b 100644 (file)
@@ -17,7 +17,7 @@
 #include "nodes/execnodes.h"
 
 extern BitmapHeapScanState *ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags);
-extern TupleTableSlot *ExecBitmapHeapScan(BitmapHeapScanState *node);
+extern void ExecBitmapHeapScan(BitmapHeapScanState *node);
 extern void ExecEndBitmapHeapScan(BitmapHeapScanState *node);
 extern void ExecReScanBitmapHeapScan(BitmapHeapScanState *node);
 
index ef5c2bc8b7266f8cb610401c12745c2bbab2668d..8411fa1dc82fa4aaa217d6bd7a985bac9fb66f44 100644 (file)
@@ -17,7 +17,7 @@
 #include "nodes/execnodes.h"
 
 extern CteScanState *ExecInitCteScan(CteScan *node, EState *estate, int eflags);
-extern TupleTableSlot *ExecCteScan(CteScanState *node);
+extern void ExecCteScan(CteScanState *node);
 extern void ExecEndCteScan(CteScanState *node);
 extern void ExecReScanCteScan(CteScanState *node);
 
index 7d16c2b1faddeaf76d85e502f0e2378c42a3243e..5df2ebb816646254211e945bf61be65285b67281 100644 (file)
@@ -21,7 +21,7 @@
  */
 extern CustomScanState *ExecInitCustomScan(CustomScan *custom_scan,
                                   EState *estate, int eflags);
-extern TupleTableSlot *ExecCustomScan(CustomScanState *node);
+extern void ExecCustomScan(CustomScanState *node);
 extern void ExecEndCustomScan(CustomScanState *node);
 
 extern void ExecReScanCustomScan(CustomScanState *node);
index 0cdec4e843e87eea83c0ef4ca19957a19a84ed16..3d0f7bd8223100e0cef364fb5a737023d3b79e05 100644 (file)
@@ -18,7 +18,7 @@
 #include "nodes/execnodes.h"
 
 extern ForeignScanState *ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags);
-extern TupleTableSlot *ExecForeignScan(ForeignScanState *node);
+extern void ExecForeignScan(ForeignScanState *node);
 extern void ExecEndForeignScan(ForeignScanState *node);
 extern void ExecReScanForeignScan(ForeignScanState *node);
 
index d6e7a617304c886b6cebbcb0ac3cc5a7a36e8a0e..15beb13a8f4ff2c47ee839f0909053a322ca6f78 100644 (file)
@@ -17,7 +17,7 @@
 #include "nodes/execnodes.h"
 
 extern FunctionScanState *ExecInitFunctionScan(FunctionScan *node, EState *estate, int eflags);
-extern TupleTableSlot *ExecFunctionScan(FunctionScanState *node);
+extern void ExecFunctionScan(FunctionScanState *node);
 extern void ExecEndFunctionScan(FunctionScanState *node);
 extern void ExecReScanFunctionScan(FunctionScanState *node);
 
index f76d9be5123f9d5e04ffbff5533b5ea033e41669..100a82725c83bbe1d0560d377bfd9d29698253aa 100644 (file)
@@ -17,7 +17,7 @@
 #include "nodes/execnodes.h"
 
 extern GatherState *ExecInitGather(Gather *node, EState *estate, int eflags);
-extern TupleTableSlot *ExecGather(GatherState *node);
+extern void ExecGather(GatherState *node);
 extern void ExecEndGather(GatherState *node);
 extern void ExecShutdownGather(GatherState *node);
 extern void ExecReScanGather(GatherState *node);
index 92639f5c638c12b003a6d16446cab4d22b345ac8..446ded5dd52511d678734ce4db9485307fc84c04 100644 (file)
@@ -17,7 +17,7 @@
 #include "nodes/execnodes.h"
 
 extern GroupState *ExecInitGroup(Group *node, EState *estate, int eflags);
-extern TupleTableSlot *ExecGroup(GroupState *node);
+extern void ExecGroup(GroupState *node);
 extern void ExecEndGroup(GroupState *node);
 extern void ExecReScanGroup(GroupState *node);
 
index 8cf6d15c1f1d9efaaa4f203b729e7ba6e86c7884..b395fd960f8059a4168b8761ca0459ab49f84c4b 100644 (file)
@@ -17,7 +17,7 @@
 #include "nodes/execnodes.h"
 
 extern HashState *ExecInitHash(Hash *node, EState *estate, int eflags);
-extern TupleTableSlot *ExecHash(HashState *node);
+extern void ExecHash(HashState *node);
 extern Node *MultiExecHash(HashState *node);
 extern void ExecEndHash(HashState *node);
 extern void ExecReScanHash(HashState *node);
index f24127acac4a6dff3b58af32cf64e71a3beac69a..072c6105ff0d30693b88807152830ae4139abe9e 100644 (file)
@@ -18,7 +18,7 @@
 #include "storage/buffile.h"
 
 extern HashJoinState *ExecInitHashJoin(HashJoin *node, EState *estate, int eflags);
-extern TupleTableSlot *ExecHashJoin(HashJoinState *node);
+extern void ExecHashJoin(HashJoinState *node);
 extern void ExecEndHashJoin(HashJoinState *node);
 extern void ExecReScanHashJoin(HashJoinState *node);
 
index d63d194a8fd0d2aef2a875ab2e1efc13862fd68d..0fbcf8033df26f975c9059cba06609d381e1e0d7 100644 (file)
@@ -17,7 +17,7 @@
 #include "nodes/execnodes.h"
 
 extern IndexOnlyScanState *ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags);
-extern TupleTableSlot *ExecIndexOnlyScan(IndexOnlyScanState *node);
+extern void ExecIndexOnlyScan(IndexOnlyScanState *node);
 extern void ExecEndIndexOnlyScan(IndexOnlyScanState *node);
 extern void ExecIndexOnlyMarkPos(IndexOnlyScanState *node);
 extern void ExecIndexOnlyRestrPos(IndexOnlyScanState *node);
index 194fadb386b01d96c9f7470a6f6b0e49fe511b67..341dab3da4d9b9149adc59de26c51e4cf705e3ef 100644 (file)
@@ -17,7 +17,7 @@
 #include "nodes/execnodes.h"
 
 extern IndexScanState *ExecInitIndexScan(IndexScan *node, EState *estate, int eflags);
-extern TupleTableSlot *ExecIndexScan(IndexScanState *node);
+extern void ExecIndexScan(IndexScanState *node);
 extern void ExecEndIndexScan(IndexScanState *node);
 extern void ExecIndexMarkPos(IndexScanState *node);
 extern void ExecIndexRestrPos(IndexScanState *node);
index 96166b44f26b9fb83c3688e8c626ad1ef7254233..03dde30cb3632398ad1874a629b9847127e73913 100644 (file)
@@ -17,7 +17,7 @@
 #include "nodes/execnodes.h"
 
 extern LimitState *ExecInitLimit(Limit *node, EState *estate, int eflags);
-extern TupleTableSlot *ExecLimit(LimitState *node);
+extern void ExecLimit(LimitState *node);
 extern void ExecEndLimit(LimitState *node);
 extern void ExecReScanLimit(LimitState *node);
 
index e828e9c6ec543dbc121f821c6da54b2ebbb25204..eda3cbec54a7351722b1330b27c72e11a3530d79 100644 (file)
@@ -17,7 +17,7 @@
 #include "nodes/execnodes.h"
 
 extern LockRowsState *ExecInitLockRows(LockRows *node, EState *estate, int eflags);
-extern TupleTableSlot *ExecLockRows(LockRowsState *node);
+extern void ExecLockRows(LockRowsState *node);
 extern void ExecEndLockRows(LockRowsState *node);
 extern void ExecReScanLockRows(LockRowsState *node);
 
index 2b8cae197dc70fc79631c47b3ebe290acc92ac01..20bc7f61cf4ff69d7e7cc47dbe925ebcb351f2d7 100644 (file)
@@ -17,7 +17,7 @@
 #include "nodes/execnodes.h"
 
 extern MaterialState *ExecInitMaterial(Material *node, EState *estate, int eflags);
-extern TupleTableSlot *ExecMaterial(MaterialState *node);
+extern void ExecMaterial(MaterialState *node);
 extern void ExecEndMaterial(MaterialState *node);
 extern void ExecMaterialMarkPos(MaterialState *node);
 extern void ExecMaterialRestrPos(MaterialState *node);
index 0efc48979470283ba285e6bb39c7acc3174c0734..e43b5e6966bb814155da61e66946c10e211fe015 100644 (file)
@@ -17,7 +17,7 @@
 #include "nodes/execnodes.h"
 
 extern MergeAppendState *ExecInitMergeAppend(MergeAppend *node, EState *estate, int eflags);
-extern TupleTableSlot *ExecMergeAppend(MergeAppendState *node);
+extern void ExecMergeAppend(MergeAppendState *node);
 extern void ExecEndMergeAppend(MergeAppendState *node);
 extern void ExecReScanMergeAppend(MergeAppendState *node);
 
index 74d691ce2c0229215fb2bfb50db81007b94a35d9..dfdbc1b699a78edd5ae8f69b4b85368316f3d20f 100644 (file)
@@ -17,7 +17,7 @@
 #include "nodes/execnodes.h"
 
 extern MergeJoinState *ExecInitMergeJoin(MergeJoin *node, EState *estate, int eflags);
-extern TupleTableSlot *ExecMergeJoin(MergeJoinState *node);
+extern void ExecMergeJoin(MergeJoinState *node);
 extern void ExecEndMergeJoin(MergeJoinState *node);
 extern void ExecReScanMergeJoin(MergeJoinState *node);
 
index 6b663537a57be251d055b6a82d3c490d22ebabf9..fe6724851dffef10ab2a902e0360a0e2532910ec 100644 (file)
@@ -16,7 +16,7 @@
 #include "nodes/execnodes.h"
 
 extern ModifyTableState *ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags);
-extern TupleTableSlot *ExecModifyTable(ModifyTableState *node);
+extern void ExecModifyTable(ModifyTableState *node);
 extern void ExecEndModifyTable(ModifyTableState *node);
 extern void ExecReScanModifyTable(ModifyTableState *node);
 
index eeb42d6ceacf8f1a5cad17001683946805c91b55..cab18859db0763c5ca7301a5edb5bd3801bd21f5 100644 (file)
@@ -17,7 +17,7 @@
 #include "nodes/execnodes.h"
 
 extern NestLoopState *ExecInitNestLoop(NestLoop *node, EState *estate, int eflags);
-extern TupleTableSlot *ExecNestLoop(NestLoopState *node);
+extern void ExecNestLoop(NestLoopState *node);
 extern void ExecEndNestLoop(NestLoopState *node);
 extern void ExecReScanNestLoop(NestLoopState *node);
 
index 1c087907c24e2a08a8647c2b3a434036c5dede59..fb11ecacbbcebcba6f193e730beb9a9f2f33479f 100644 (file)
@@ -17,7 +17,7 @@
 #include "nodes/execnodes.h"
 
 extern RecursiveUnionState *ExecInitRecursiveUnion(RecursiveUnion *node, EState *estate, int eflags);
-extern TupleTableSlot *ExecRecursiveUnion(RecursiveUnionState *node);
+extern void ExecRecursiveUnion(RecursiveUnionState *node);
 extern void ExecEndRecursiveUnion(RecursiveUnionState *node);
 extern void ExecReScanRecursiveUnion(RecursiveUnionState *node);
 
index 356027f8cf970c05bf1a2f52206cc815a0d70afa..951fae6c16294d5e4290d300c080494d8332d5d0 100644 (file)
@@ -17,7 +17,7 @@
 #include "nodes/execnodes.h"
 
 extern ResultState *ExecInitResult(Result *node, EState *estate, int eflags);
-extern TupleTableSlot *ExecResult(ResultState *node);
+extern void ExecResult(ResultState *node);
 extern void ExecEndResult(ResultState *node);
 extern void ExecResultMarkPos(ResultState *node);
 extern void ExecResultRestrPos(ResultState *node);
index c8f03d8b18bde0f49aea425c3c15d975c5caf332..4ab6e5a28b2fd172c7d0cd03ee4d825be69ef5eb 100644 (file)
@@ -17,7 +17,7 @@
 #include "nodes/execnodes.h"
 
 extern SampleScanState *ExecInitSampleScan(SampleScan *node, EState *estate, int eflags);
-extern TupleTableSlot *ExecSampleScan(SampleScanState *node);
+extern void ExecSampleScan(SampleScanState *node);
 extern void ExecEndSampleScan(SampleScanState *node);
 extern void ExecReScanSampleScan(SampleScanState *node);
 
index f2e61ffdb3f5110fb5f3e4b25dc558edd48702a4..816d1a52f5b6e9113b9147e4a25edc049a9cfea9 100644 (file)
@@ -18,7 +18,7 @@
 #include "nodes/execnodes.h"
 
 extern SeqScanState *ExecInitSeqScan(SeqScan *node, EState *estate, int eflags);
-extern TupleTableSlot *ExecSeqScan(SeqScanState *node);
+extern void ExecSeqScan(SeqScanState *node);
 extern void ExecEndSeqScan(SeqScanState *node);
 extern void ExecReScanSeqScan(SeqScanState *node);
 
index c6e9603204eb01fc64956693864eb528c287c7f8..dd88afb4fed1ae57ce16a669d17d85d69904fc02 100644 (file)
@@ -17,7 +17,7 @@
 #include "nodes/execnodes.h"
 
 extern SetOpState *ExecInitSetOp(SetOp *node, EState *estate, int eflags);
-extern TupleTableSlot *ExecSetOp(SetOpState *node);
+extern void ExecSetOp(SetOpState *node);
 extern void ExecEndSetOp(SetOpState *node);
 extern void ExecReScanSetOp(SetOpState *node);
 
index 481065fdbe3edb5b11822e31d343b073bdc85575..f65037dff2e47ab3df4b30c47472b06a99bdbf06 100644 (file)
@@ -17,7 +17,7 @@
 #include "nodes/execnodes.h"
 
 extern SortState *ExecInitSort(Sort *node, EState *estate, int eflags);
-extern TupleTableSlot *ExecSort(SortState *node);
+extern void ExecSort(SortState *node);
 extern void ExecEndSort(SortState *node);
 extern void ExecSortMarkPos(SortState *node);
 extern void ExecSortRestrPos(SortState *node);
index 427699be0b65c3016c9866872990259217d9c50f..a3962c78092fdf5c822a11298748f0208cf09c76 100644 (file)
@@ -17,7 +17,7 @@
 #include "nodes/execnodes.h"
 
 extern SubqueryScanState *ExecInitSubqueryScan(SubqueryScan *node, EState *estate, int eflags);
-extern TupleTableSlot *ExecSubqueryScan(SubqueryScanState *node);
+extern void ExecSubqueryScan(SubqueryScanState *node);
 extern void ExecEndSubqueryScan(SubqueryScanState *node);
 extern void ExecReScanSubqueryScan(SubqueryScanState *node);
 
index 76c2a9f297b7e51bae23b9ee291e3f713af52fc3..5b7bbfd810863c955fbd80d00023aa957e1bfa90 100644 (file)
@@ -17,7 +17,7 @@
 #include "nodes/execnodes.h"
 
 extern TidScanState *ExecInitTidScan(TidScan *node, EState *estate, int eflags);
-extern TupleTableSlot *ExecTidScan(TidScanState *node);
+extern void ExecTidScan(TidScanState *node);
 extern void ExecEndTidScan(TidScanState *node);
 extern void ExecReScanTidScan(TidScanState *node);
 
index aa8491dd3c21cc9de72fb66906e0fa77eb7256cc..b53a5539741dc21d8b5d4a18cea1b758b9a2b41e 100644 (file)
@@ -17,7 +17,7 @@
 #include "nodes/execnodes.h"
 
 extern UniqueState *ExecInitUnique(Unique *node, EState *estate, int eflags);
-extern TupleTableSlot *ExecUnique(UniqueState *node);
+extern void ExecUnique(UniqueState *node);
 extern void ExecEndUnique(UniqueState *node);
 extern void ExecReScanUnique(UniqueState *node);
 
index 026f261c513d6d8407c280434401a5ed22b2a98f..90288fcc5583f94bd5d6d069e9ef3225677f1443 100644 (file)
@@ -17,7 +17,7 @@
 #include "nodes/execnodes.h"
 
 extern ValuesScanState *ExecInitValuesScan(ValuesScan *node, EState *estate, int eflags);
-extern TupleTableSlot *ExecValuesScan(ValuesScanState *node);
+extern void ExecValuesScan(ValuesScanState *node);
 extern void ExecEndValuesScan(ValuesScanState *node);
 extern void ExecReScanValuesScan(ValuesScanState *node);
 
index 94ed0372e629a1c8257c9f9bf0f4813e874cbdf8..f5e2c9858c0f654e67f26e0ddd5edcc9f719ca1f 100644 (file)
@@ -17,7 +17,7 @@
 #include "nodes/execnodes.h"
 
 extern WindowAggState *ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags);
-extern TupleTableSlot *ExecWindowAgg(WindowAggState *node);
+extern void ExecWindowAgg(WindowAggState *node);
 extern void ExecEndWindowAgg(WindowAggState *node);
 extern void ExecReScanWindowAgg(WindowAggState *node);
 
index 217208a1127fc2f4c60b778262bffb453737f052..7b1eecbc107cdd3e668f5a4b17cae9167c13e171 100644 (file)
@@ -17,7 +17,7 @@
 #include "nodes/execnodes.h"
 
 extern WorkTableScanState *ExecInitWorkTableScan(WorkTableScan *node, EState *estate, int eflags);
-extern TupleTableSlot *ExecWorkTableScan(WorkTableScanState *node);
+extern void ExecWorkTableScan(WorkTableScanState *node);
 extern void ExecEndWorkTableScan(WorkTableScanState *node);
 extern void ExecReScanWorkTableScan(WorkTableScanState *node);
 
index e8bebef5df049abeb17469b58b497e165d96e169..b14aa7a3068f6304b1f0c0f7fdf11867ec74697c 100644 (file)
@@ -1032,6 +1032,8 @@ typedef struct PlanState
                                                                 * top-level plan */
 
        struct PlanState *parent;       /* node which will receive tuples from us */
+       bool            result_ready;   /* true if result is ready */
+       Node       *result;                     /* result, most often TupleTableSlot */
 
        Instrumentation *instrument;    /* Optional runtime stats for this node */
        WorkerInstrumentation *worker_instrument;       /* per-worker instrumentation */