Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "postgres.h"
00017
00018 #include "executor/execdebug.h"
00019 #include "executor/nodeWorktablescan.h"
00020
00021 static TupleTableSlot *WorkTableScanNext(WorkTableScanState *node);
00022
00023
00024
00025
00026
00027
00028
00029 static TupleTableSlot *
00030 WorkTableScanNext(WorkTableScanState *node)
00031 {
00032 TupleTableSlot *slot;
00033 Tuplestorestate *tuplestorestate;
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 Assert(ScanDirectionIsForward(node->ss.ps.state->es_direction));
00051
00052 tuplestorestate = node->rustate->working_table;
00053
00054
00055
00056
00057 slot = node->ss.ss_ScanTupleSlot;
00058 (void) tuplestore_gettupleslot(tuplestorestate, true, false, slot);
00059 return slot;
00060 }
00061
00062
00063
00064
00065 static bool
00066 WorkTableScanRecheck(WorkTableScanState *node, TupleTableSlot *slot)
00067 {
00068
00069 return true;
00070 }
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 TupleTableSlot *
00081 ExecWorkTableScan(WorkTableScanState *node)
00082 {
00083
00084
00085
00086
00087
00088
00089 if (node->rustate == NULL)
00090 {
00091 WorkTableScan *plan = (WorkTableScan *) node->ss.ps.plan;
00092 EState *estate = node->ss.ps.state;
00093 ParamExecData *param;
00094
00095 param = &(estate->es_param_exec_vals[plan->wtParam]);
00096 Assert(param->execPlan == NULL);
00097 Assert(!param->isnull);
00098 node->rustate = (RecursiveUnionState *) DatumGetPointer(param->value);
00099 Assert(node->rustate && IsA(node->rustate, RecursiveUnionState));
00100
00101
00102
00103
00104
00105
00106
00107 ExecAssignScanType(&node->ss,
00108 ExecGetResultType(&node->rustate->ps));
00109
00110
00111
00112
00113
00114 ExecAssignScanProjectionInfo(&node->ss);
00115 }
00116
00117 return ExecScan(&node->ss,
00118 (ExecScanAccessMtd) WorkTableScanNext,
00119 (ExecScanRecheckMtd) WorkTableScanRecheck);
00120 }
00121
00122
00123
00124
00125
00126
00127 WorkTableScanState *
00128 ExecInitWorkTableScan(WorkTableScan *node, EState *estate, int eflags)
00129 {
00130 WorkTableScanState *scanstate;
00131
00132
00133 Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
00134
00135
00136
00137
00138 Assert(outerPlan(node) == NULL);
00139 Assert(innerPlan(node) == NULL);
00140
00141
00142
00143
00144 scanstate = makeNode(WorkTableScanState);
00145 scanstate->ss.ps.plan = (Plan *) node;
00146 scanstate->ss.ps.state = estate;
00147 scanstate->rustate = NULL;
00148
00149
00150
00151
00152
00153
00154 ExecAssignExprContext(estate, &scanstate->ss.ps);
00155
00156
00157
00158
00159 scanstate->ss.ps.targetlist = (List *)
00160 ExecInitExpr((Expr *) node->scan.plan.targetlist,
00161 (PlanState *) scanstate);
00162 scanstate->ss.ps.qual = (List *)
00163 ExecInitExpr((Expr *) node->scan.plan.qual,
00164 (PlanState *) scanstate);
00165
00166
00167
00168
00169 ExecInitResultTupleSlot(estate, &scanstate->ss.ps);
00170 ExecInitScanTupleSlot(estate, &scanstate->ss);
00171
00172
00173
00174
00175 ExecAssignResultTypeFromTL(&scanstate->ss.ps);
00176
00177 scanstate->ss.ps.ps_TupFromTlist = false;
00178
00179 return scanstate;
00180 }
00181
00182
00183
00184
00185
00186
00187
00188 void
00189 ExecEndWorkTableScan(WorkTableScanState *node)
00190 {
00191
00192
00193
00194 ExecFreeExprContext(&node->ss.ps);
00195
00196
00197
00198
00199 ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
00200 ExecClearTuple(node->ss.ss_ScanTupleSlot);
00201 }
00202
00203
00204
00205
00206
00207
00208
00209 void
00210 ExecReScanWorkTableScan(WorkTableScanState *node)
00211 {
00212 ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
00213
00214 ExecScanReScan(&node->ss);
00215
00216
00217 if (node->rustate)
00218 tuplestore_rescan(node->rustate->working_table);
00219 }