Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "postgres.h"
00023
00024 #include "executor/executor.h"
00025 #include "executor/nodeMaterial.h"
00026 #include "miscadmin.h"
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 TupleTableSlot *
00039 ExecMaterial(MaterialState *node)
00040 {
00041 EState *estate;
00042 ScanDirection dir;
00043 bool forward;
00044 Tuplestorestate *tuplestorestate;
00045 bool eof_tuplestore;
00046 TupleTableSlot *slot;
00047
00048
00049
00050
00051 estate = node->ss.ps.state;
00052 dir = estate->es_direction;
00053 forward = ScanDirectionIsForward(dir);
00054 tuplestorestate = node->tuplestorestate;
00055
00056
00057
00058
00059 if (tuplestorestate == NULL && node->eflags != 0)
00060 {
00061 tuplestorestate = tuplestore_begin_heap(true, false, work_mem);
00062 tuplestore_set_eflags(tuplestorestate, node->eflags);
00063 if (node->eflags & EXEC_FLAG_MARK)
00064 {
00065
00066
00067
00068
00069 int ptrno PG_USED_FOR_ASSERTS_ONLY;
00070
00071 ptrno = tuplestore_alloc_read_pointer(tuplestorestate,
00072 node->eflags);
00073 Assert(ptrno == 1);
00074 }
00075 node->tuplestorestate = tuplestorestate;
00076 }
00077
00078
00079
00080
00081
00082 eof_tuplestore = (tuplestorestate == NULL) ||
00083 tuplestore_ateof(tuplestorestate);
00084
00085 if (!forward && eof_tuplestore)
00086 {
00087 if (!node->eof_underlying)
00088 {
00089
00090
00091
00092
00093
00094
00095 if (!tuplestore_advance(tuplestorestate, forward))
00096 return NULL;
00097 }
00098 eof_tuplestore = false;
00099 }
00100
00101
00102
00103
00104 slot = node->ss.ps.ps_ResultTupleSlot;
00105 if (!eof_tuplestore)
00106 {
00107 if (tuplestore_gettupleslot(tuplestorestate, forward, false, slot))
00108 return slot;
00109 if (forward)
00110 eof_tuplestore = true;
00111 }
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 if (eof_tuplestore && !node->eof_underlying)
00122 {
00123 PlanState *outerNode;
00124 TupleTableSlot *outerslot;
00125
00126
00127
00128
00129
00130 outerNode = outerPlanState(node);
00131 outerslot = ExecProcNode(outerNode);
00132 if (TupIsNull(outerslot))
00133 {
00134 node->eof_underlying = true;
00135 return NULL;
00136 }
00137
00138
00139
00140
00141
00142
00143 if (tuplestorestate)
00144 tuplestore_puttupleslot(tuplestorestate, outerslot);
00145
00146
00147
00148
00149 return outerslot;
00150 }
00151
00152
00153
00154
00155 return ExecClearTuple(slot);
00156 }
00157
00158
00159
00160
00161
00162 MaterialState *
00163 ExecInitMaterial(Material *node, EState *estate, int eflags)
00164 {
00165 MaterialState *matstate;
00166 Plan *outerPlan;
00167
00168
00169
00170
00171 matstate = makeNode(MaterialState);
00172 matstate->ss.ps.plan = (Plan *) node;
00173 matstate->ss.ps.state = estate;
00174
00175
00176
00177
00178
00179
00180
00181 matstate->eflags = (eflags & (EXEC_FLAG_REWIND |
00182 EXEC_FLAG_BACKWARD |
00183 EXEC_FLAG_MARK));
00184
00185
00186
00187
00188
00189
00190
00191
00192 if (eflags & EXEC_FLAG_BACKWARD)
00193 matstate->eflags |= EXEC_FLAG_REWIND;
00194
00195 matstate->eof_underlying = false;
00196 matstate->tuplestorestate = NULL;
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 ExecInitResultTupleSlot(estate, &matstate->ss.ps);
00211 ExecInitScanTupleSlot(estate, &matstate->ss);
00212
00213
00214
00215
00216
00217
00218
00219 eflags &= ~(EXEC_FLAG_REWIND | EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK);
00220
00221 outerPlan = outerPlan(node);
00222 outerPlanState(matstate) = ExecInitNode(outerPlan, estate, eflags);
00223
00224
00225
00226
00227
00228 ExecAssignResultTypeFromTL(&matstate->ss.ps);
00229 ExecAssignScanTypeFromOuterPlan(&matstate->ss);
00230 matstate->ss.ps.ps_ProjInfo = NULL;
00231
00232 return matstate;
00233 }
00234
00235
00236
00237
00238
00239 void
00240 ExecEndMaterial(MaterialState *node)
00241 {
00242
00243
00244
00245 ExecClearTuple(node->ss.ss_ScanTupleSlot);
00246
00247
00248
00249
00250 if (node->tuplestorestate != NULL)
00251 tuplestore_end(node->tuplestorestate);
00252 node->tuplestorestate = NULL;
00253
00254
00255
00256
00257 ExecEndNode(outerPlanState(node));
00258 }
00259
00260
00261
00262
00263
00264
00265
00266 void
00267 ExecMaterialMarkPos(MaterialState *node)
00268 {
00269 Assert(node->eflags & EXEC_FLAG_MARK);
00270
00271
00272
00273
00274 if (!node->tuplestorestate)
00275 return;
00276
00277
00278
00279
00280 tuplestore_copy_read_pointer(node->tuplestorestate, 0, 1);
00281
00282
00283
00284
00285 tuplestore_trim(node->tuplestorestate);
00286 }
00287
00288
00289
00290
00291
00292
00293
00294 void
00295 ExecMaterialRestrPos(MaterialState *node)
00296 {
00297 Assert(node->eflags & EXEC_FLAG_MARK);
00298
00299
00300
00301
00302 if (!node->tuplestorestate)
00303 return;
00304
00305
00306
00307
00308 tuplestore_copy_read_pointer(node->tuplestorestate, 1, 0);
00309 }
00310
00311
00312
00313
00314
00315
00316
00317 void
00318 ExecReScanMaterial(MaterialState *node)
00319 {
00320 ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
00321
00322 if (node->eflags != 0)
00323 {
00324
00325
00326
00327
00328
00329 if (!node->tuplestorestate)
00330 return;
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342 if (node->ss.ps.lefttree->chgParam != NULL ||
00343 (node->eflags & EXEC_FLAG_REWIND) == 0)
00344 {
00345 tuplestore_end(node->tuplestorestate);
00346 node->tuplestorestate = NULL;
00347 if (node->ss.ps.lefttree->chgParam == NULL)
00348 ExecReScan(node->ss.ps.lefttree);
00349 node->eof_underlying = false;
00350 }
00351 else
00352 tuplestore_rescan(node->tuplestorestate);
00353 }
00354 else
00355 {
00356
00357
00358
00359
00360
00361
00362 if (node->ss.ps.lefttree->chgParam == NULL)
00363 ExecReScan(node->ss.ps.lefttree);
00364 node->eof_underlying = false;
00365 }
00366 }