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
00023
00024 #include "postgres.h"
00025
00026 #include "executor/executor.h"
00027 #include "executor/nodeValuesscan.h"
00028 #include "parser/parsetree.h"
00029
00030
00031 static TupleTableSlot *ValuesNext(ValuesScanState *node);
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 static TupleTableSlot *
00046 ValuesNext(ValuesScanState *node)
00047 {
00048 TupleTableSlot *slot;
00049 EState *estate;
00050 ExprContext *econtext;
00051 ScanDirection direction;
00052 List *exprlist;
00053
00054
00055
00056
00057 estate = node->ss.ps.state;
00058 direction = estate->es_direction;
00059 slot = node->ss.ss_ScanTupleSlot;
00060 econtext = node->rowcontext;
00061
00062
00063
00064
00065 if (ScanDirectionIsForward(direction))
00066 {
00067 if (node->curr_idx < node->array_len)
00068 node->curr_idx++;
00069 if (node->curr_idx < node->array_len)
00070 exprlist = node->exprlists[node->curr_idx];
00071 else
00072 exprlist = NIL;
00073 }
00074 else
00075 {
00076 if (node->curr_idx >= 0)
00077 node->curr_idx--;
00078 if (node->curr_idx >= 0)
00079 exprlist = node->exprlists[node->curr_idx];
00080 else
00081 exprlist = NIL;
00082 }
00083
00084
00085
00086
00087
00088
00089
00090 ExecClearTuple(slot);
00091
00092 if (exprlist)
00093 {
00094 MemoryContext oldContext;
00095 List *exprstatelist;
00096 Datum *values;
00097 bool *isnull;
00098 ListCell *lc;
00099 int resind;
00100
00101
00102
00103
00104
00105
00106 ReScanExprContext(econtext);
00107
00108
00109
00110
00111
00112
00113
00114 oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
00115
00116
00117
00118
00119
00120
00121
00122 exprstatelist = (List *) ExecInitExpr((Expr *) exprlist, NULL);
00123
00124
00125 Assert(list_length(exprstatelist) == slot->tts_tupleDescriptor->natts);
00126
00127
00128
00129
00130
00131 values = slot->tts_values;
00132 isnull = slot->tts_isnull;
00133
00134 resind = 0;
00135 foreach(lc, exprstatelist)
00136 {
00137 ExprState *estate = (ExprState *) lfirst(lc);
00138
00139 values[resind] = ExecEvalExpr(estate,
00140 econtext,
00141 &isnull[resind],
00142 NULL);
00143 resind++;
00144 }
00145
00146 MemoryContextSwitchTo(oldContext);
00147
00148
00149
00150
00151 ExecStoreVirtualTuple(slot);
00152 }
00153
00154 return slot;
00155 }
00156
00157
00158
00159
00160 static bool
00161 ValuesRecheck(ValuesScanState *node, TupleTableSlot *slot)
00162 {
00163
00164 return true;
00165 }
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 TupleTableSlot *
00177 ExecValuesScan(ValuesScanState *node)
00178 {
00179 return ExecScan(&node->ss,
00180 (ExecScanAccessMtd) ValuesNext,
00181 (ExecScanRecheckMtd) ValuesRecheck);
00182 }
00183
00184
00185
00186
00187
00188 ValuesScanState *
00189 ExecInitValuesScan(ValuesScan *node, EState *estate, int eflags)
00190 {
00191 ValuesScanState *scanstate;
00192 RangeTblEntry *rte = rt_fetch(node->scan.scanrelid,
00193 estate->es_range_table);
00194 TupleDesc tupdesc;
00195 ListCell *vtl;
00196 int i;
00197 PlanState *planstate;
00198
00199
00200
00201
00202 Assert(outerPlan(node) == NULL);
00203 Assert(innerPlan(node) == NULL);
00204
00205
00206
00207
00208 scanstate = makeNode(ValuesScanState);
00209 scanstate->ss.ps.plan = (Plan *) node;
00210 scanstate->ss.ps.state = estate;
00211
00212
00213
00214
00215 planstate = &scanstate->ss.ps;
00216
00217
00218
00219
00220
00221
00222 ExecAssignExprContext(estate, planstate);
00223 scanstate->rowcontext = planstate->ps_ExprContext;
00224 ExecAssignExprContext(estate, planstate);
00225
00226
00227
00228
00229 ExecInitResultTupleSlot(estate, &scanstate->ss.ps);
00230 ExecInitScanTupleSlot(estate, &scanstate->ss);
00231
00232
00233
00234
00235 scanstate->ss.ps.targetlist = (List *)
00236 ExecInitExpr((Expr *) node->scan.plan.targetlist,
00237 (PlanState *) scanstate);
00238 scanstate->ss.ps.qual = (List *)
00239 ExecInitExpr((Expr *) node->scan.plan.qual,
00240 (PlanState *) scanstate);
00241
00242
00243
00244
00245 tupdesc = ExecTypeFromExprList((List *) linitial(node->values_lists),
00246 rte->eref->colnames);
00247
00248 ExecAssignScanType(&scanstate->ss, tupdesc);
00249
00250
00251
00252
00253 scanstate->marked_idx = -1;
00254 scanstate->curr_idx = -1;
00255 scanstate->array_len = list_length(node->values_lists);
00256
00257
00258 scanstate->exprlists = (List **)
00259 palloc(scanstate->array_len * sizeof(List *));
00260 i = 0;
00261 foreach(vtl, node->values_lists)
00262 {
00263 scanstate->exprlists[i++] = (List *) lfirst(vtl);
00264 }
00265
00266 scanstate->ss.ps.ps_TupFromTlist = false;
00267
00268
00269
00270
00271 ExecAssignResultTypeFromTL(&scanstate->ss.ps);
00272 ExecAssignScanProjectionInfo(&scanstate->ss);
00273
00274 return scanstate;
00275 }
00276
00277
00278
00279
00280
00281
00282
00283 void
00284 ExecEndValuesScan(ValuesScanState *node)
00285 {
00286
00287
00288
00289 ExecFreeExprContext(&node->ss.ps);
00290 node->ss.ps.ps_ExprContext = node->rowcontext;
00291 ExecFreeExprContext(&node->ss.ps);
00292
00293
00294
00295
00296 ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
00297 ExecClearTuple(node->ss.ss_ScanTupleSlot);
00298 }
00299
00300
00301
00302
00303
00304
00305
00306 void
00307 ExecValuesMarkPos(ValuesScanState *node)
00308 {
00309 node->marked_idx = node->curr_idx;
00310 }
00311
00312
00313
00314
00315
00316
00317
00318 void
00319 ExecValuesRestrPos(ValuesScanState *node)
00320 {
00321 node->curr_idx = node->marked_idx;
00322 }
00323
00324
00325
00326
00327
00328
00329
00330 void
00331 ExecReScanValuesScan(ValuesScanState *node)
00332 {
00333 ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
00334
00335 ExecScanReScan(&node->ss);
00336
00337 node->curr_idx = -1;
00338 }