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/nodeCtescan.h"
00020 #include "miscadmin.h"
00021
00022 static TupleTableSlot *CteScanNext(CteScanState *node);
00023
00024
00025
00026
00027
00028
00029
00030 static TupleTableSlot *
00031 CteScanNext(CteScanState *node)
00032 {
00033 EState *estate;
00034 ScanDirection dir;
00035 bool forward;
00036 Tuplestorestate *tuplestorestate;
00037 bool eof_tuplestore;
00038 TupleTableSlot *slot;
00039
00040
00041
00042
00043 estate = node->ss.ps.state;
00044 dir = estate->es_direction;
00045 forward = ScanDirectionIsForward(dir);
00046 tuplestorestate = node->leader->cte_table;
00047 tuplestore_select_read_pointer(tuplestorestate, node->readptr);
00048 slot = node->ss.ss_ScanTupleSlot;
00049
00050
00051
00052
00053
00054 eof_tuplestore = tuplestore_ateof(tuplestorestate);
00055
00056 if (!forward && eof_tuplestore)
00057 {
00058 if (!node->leader->eof_cte)
00059 {
00060
00061
00062
00063
00064
00065
00066 if (!tuplestore_advance(tuplestorestate, forward))
00067 return NULL;
00068 }
00069 eof_tuplestore = false;
00070 }
00071
00072
00073
00074
00075
00076
00077
00078
00079 if (!eof_tuplestore)
00080 {
00081 if (tuplestore_gettupleslot(tuplestorestate, forward, true, slot))
00082 return slot;
00083 if (forward)
00084 eof_tuplestore = true;
00085 }
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 if (eof_tuplestore && !node->leader->eof_cte)
00096 {
00097 TupleTableSlot *cteslot;
00098
00099
00100
00101
00102
00103 cteslot = ExecProcNode(node->cteplanstate);
00104 if (TupIsNull(cteslot))
00105 {
00106 node->leader->eof_cte = true;
00107 return NULL;
00108 }
00109
00110
00111
00112
00113
00114
00115
00116
00117 tuplestore_puttupleslot(tuplestorestate, cteslot);
00118
00119
00120
00121
00122
00123
00124
00125 return ExecCopySlot(slot, cteslot);
00126 }
00127
00128
00129
00130
00131 return ExecClearTuple(slot);
00132 }
00133
00134
00135
00136
00137 static bool
00138 CteScanRecheck(CteScanState *node, TupleTableSlot *slot)
00139 {
00140
00141 return true;
00142 }
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 TupleTableSlot *
00153 ExecCteScan(CteScanState *node)
00154 {
00155 return ExecScan(&node->ss,
00156 (ExecScanAccessMtd) CteScanNext,
00157 (ExecScanRecheckMtd) CteScanRecheck);
00158 }
00159
00160
00161
00162
00163
00164
00165 CteScanState *
00166 ExecInitCteScan(CteScan *node, EState *estate, int eflags)
00167 {
00168 CteScanState *scanstate;
00169 ParamExecData *prmdata;
00170
00171
00172 Assert(!(eflags & EXEC_FLAG_MARK));
00173
00174
00175
00176
00177
00178
00179
00180 eflags |= EXEC_FLAG_REWIND;
00181
00182
00183
00184
00185 Assert(outerPlan(node) == NULL);
00186 Assert(innerPlan(node) == NULL);
00187
00188
00189
00190
00191 scanstate = makeNode(CteScanState);
00192 scanstate->ss.ps.plan = (Plan *) node;
00193 scanstate->ss.ps.state = estate;
00194 scanstate->eflags = eflags;
00195 scanstate->cte_table = NULL;
00196 scanstate->eof_cte = false;
00197
00198
00199
00200
00201 scanstate->cteplanstate = (PlanState *) list_nth(estate->es_subplanstates,
00202 node->ctePlanId - 1);
00203
00204
00205
00206
00207
00208
00209
00210 prmdata = &(estate->es_param_exec_vals[node->cteParam]);
00211 Assert(prmdata->execPlan == NULL);
00212 Assert(!prmdata->isnull);
00213 scanstate->leader = (CteScanState *) DatumGetPointer(prmdata->value);
00214 if (scanstate->leader == NULL)
00215 {
00216
00217 prmdata->value = PointerGetDatum(scanstate);
00218 scanstate->leader = scanstate;
00219 scanstate->cte_table = tuplestore_begin_heap(true, false, work_mem);
00220 tuplestore_set_eflags(scanstate->cte_table, scanstate->eflags);
00221 scanstate->readptr = 0;
00222 }
00223 else
00224 {
00225
00226 Assert(IsA(scanstate->leader, CteScanState));
00227 scanstate->readptr =
00228 tuplestore_alloc_read_pointer(scanstate->leader->cte_table,
00229 scanstate->eflags);
00230 }
00231
00232
00233
00234
00235
00236
00237 ExecAssignExprContext(estate, &scanstate->ss.ps);
00238
00239
00240
00241
00242 scanstate->ss.ps.targetlist = (List *)
00243 ExecInitExpr((Expr *) node->scan.plan.targetlist,
00244 (PlanState *) scanstate);
00245 scanstate->ss.ps.qual = (List *)
00246 ExecInitExpr((Expr *) node->scan.plan.qual,
00247 (PlanState *) scanstate);
00248
00249
00250
00251
00252 ExecInitResultTupleSlot(estate, &scanstate->ss.ps);
00253 ExecInitScanTupleSlot(estate, &scanstate->ss);
00254
00255
00256
00257
00258
00259 ExecAssignScanType(&scanstate->ss,
00260 ExecGetResultType(scanstate->cteplanstate));
00261
00262
00263
00264
00265 ExecAssignResultTypeFromTL(&scanstate->ss.ps);
00266 ExecAssignScanProjectionInfo(&scanstate->ss);
00267
00268 scanstate->ss.ps.ps_TupFromTlist = false;
00269
00270 return scanstate;
00271 }
00272
00273
00274
00275
00276
00277
00278
00279 void
00280 ExecEndCteScan(CteScanState *node)
00281 {
00282
00283
00284
00285 ExecFreeExprContext(&node->ss.ps);
00286
00287
00288
00289
00290 ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
00291 ExecClearTuple(node->ss.ss_ScanTupleSlot);
00292
00293
00294
00295
00296 if (node->leader == node)
00297 {
00298 tuplestore_end(node->cte_table);
00299 node->cte_table = NULL;
00300 }
00301 }
00302
00303
00304
00305
00306
00307
00308
00309 void
00310 ExecReScanCteScan(CteScanState *node)
00311 {
00312 Tuplestorestate *tuplestorestate = node->leader->cte_table;
00313
00314 ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
00315
00316 ExecScanReScan(&node->ss);
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 if (node->leader->cteplanstate->chgParam != NULL)
00327 {
00328 tuplestore_clear(tuplestorestate);
00329 node->leader->eof_cte = false;
00330 }
00331 else
00332 {
00333
00334
00335
00336
00337
00338 tuplestore_select_read_pointer(tuplestorestate, node->readptr);
00339 tuplestore_rescan(tuplestorestate);
00340 }
00341 }