diff options
Diffstat (limited to 'src/backend/executor/execProcnode.c')
| -rw-r--r-- | src/backend/executor/execProcnode.c | 82 |
1 files changed, 59 insertions, 23 deletions
diff --git a/src/backend/executor/execProcnode.c b/src/backend/executor/execProcnode.c index 3f2ebff173..b7ac08eead 100644 --- a/src/backend/executor/execProcnode.c +++ b/src/backend/executor/execProcnode.c @@ -77,6 +77,7 @@ */ #include "postgres.h" +#include "executor/execAsync.h" #include "executor/executor.h" #include "executor/nodeAgg.h" #include "executor/nodeAppend.h" @@ -368,24 +369,14 @@ ExecInitNode(Plan *node, EState *estate, PlanState *parent, int eflags) /* ---------------------------------------------------------------- - * ExecProcNode + * ExecDispatchNode * - * Execute the given node to return a(nother) tuple. + * Invoke the given node's dispatch function. * ---------------------------------------------------------------- */ -TupleTableSlot * -ExecProcNode(PlanState *node) +void +ExecDispatchNode(PlanState *node) { - TupleTableSlot *result; - - 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 */ - if (node->instrument) InstrStartNode(node->instrument); @@ -539,22 +530,67 @@ ExecProcNode(PlanState *node) default: elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node)); - result = NULL; break; } - /* We don't support asynchronous execution yet. */ - Assert(node->result_ready); + if (node->instrument) + { + double nTuples = 0.0; - /* Result should be a TupleTableSlot, unless it's NULL. */ - Assert(node->result == NULL || IsA(node->result, TupleTableSlot)); + if (node->result_ready && node->result != NULL && + IsA(node->result, TupleTableSlot)) + nTuples = 1.0; - result = (TupleTableSlot *) node->result; + InstrStopNode(node->instrument, nTuples); + } +} - if (node->instrument) - InstrStopNode(node->instrument, TupIsNull(result) ? 0.0 : 1.0); - return result; +/* ---------------------------------------------------------------- + * ExecExecuteNode + * + * Request the next tuple from the given node. Note that + * if the node supports asynchrony, result_ready may not be + * set on return (use ExecProcNode if you need that, or call + * ExecAsyncWaitForNode). + * ---------------------------------------------------------------- + */ +void +ExecExecuteNode(PlanState *node) +{ + node->result_ready = false; + ExecDispatchNode(node); +} + + +/* ---------------------------------------------------------------- + * ExecProcNode + * + * Get the next tuple from the given node. If the node is + * asynchronous, wait for a tuple to be ready before + * returning. + * ---------------------------------------------------------------- + */ +TupleTableSlot * +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 */ + + ExecDispatchNode(node); + + if (!node->result_ready) + ExecAsyncWaitForNode(node); + + /* Result should be a TupleTableSlot, unless it's NULL. */ + Assert(node->result == NULL || IsA(node->result, TupleTableSlot)); + + return (TupleTableSlot *) node->result; } |
