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 #include "postgres.h"
00024
00025 #include "executor/nodeFunctionscan.h"
00026 #include "funcapi.h"
00027 #include "nodes/nodeFuncs.h"
00028
00029
00030 static TupleTableSlot *FunctionNext(FunctionScanState *node);
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 static TupleTableSlot *
00043 FunctionNext(FunctionScanState *node)
00044 {
00045 TupleTableSlot *slot;
00046 EState *estate;
00047 ScanDirection direction;
00048 Tuplestorestate *tuplestorestate;
00049
00050
00051
00052
00053 estate = node->ss.ps.state;
00054 direction = estate->es_direction;
00055
00056 tuplestorestate = node->tuplestorestate;
00057
00058
00059
00060
00061
00062 if (tuplestorestate == NULL)
00063 {
00064 node->tuplestorestate = tuplestorestate =
00065 ExecMakeTableFunctionResult(node->funcexpr,
00066 node->ss.ps.ps_ExprContext,
00067 node->tupdesc,
00068 node->eflags & EXEC_FLAG_BACKWARD);
00069 }
00070
00071
00072
00073
00074 slot = node->ss.ss_ScanTupleSlot;
00075 (void) tuplestore_gettupleslot(tuplestorestate,
00076 ScanDirectionIsForward(direction),
00077 false,
00078 slot);
00079 return slot;
00080 }
00081
00082
00083
00084
00085 static bool
00086 FunctionRecheck(FunctionScanState *node, TupleTableSlot *slot)
00087 {
00088
00089 return true;
00090 }
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 TupleTableSlot *
00102 ExecFunctionScan(FunctionScanState *node)
00103 {
00104 return ExecScan(&node->ss,
00105 (ExecScanAccessMtd) FunctionNext,
00106 (ExecScanRecheckMtd) FunctionRecheck);
00107 }
00108
00109
00110
00111
00112
00113 FunctionScanState *
00114 ExecInitFunctionScan(FunctionScan *node, EState *estate, int eflags)
00115 {
00116 FunctionScanState *scanstate;
00117 Oid funcrettype;
00118 TypeFuncClass functypclass;
00119 TupleDesc tupdesc = NULL;
00120
00121
00122 Assert(!(eflags & EXEC_FLAG_MARK));
00123
00124
00125
00126
00127 Assert(outerPlan(node) == NULL);
00128 Assert(innerPlan(node) == NULL);
00129
00130
00131
00132
00133 scanstate = makeNode(FunctionScanState);
00134 scanstate->ss.ps.plan = (Plan *) node;
00135 scanstate->ss.ps.state = estate;
00136 scanstate->eflags = eflags;
00137
00138
00139
00140
00141
00142
00143 ExecAssignExprContext(estate, &scanstate->ss.ps);
00144
00145
00146
00147
00148 ExecInitResultTupleSlot(estate, &scanstate->ss.ps);
00149 ExecInitScanTupleSlot(estate, &scanstate->ss);
00150
00151
00152
00153
00154 scanstate->ss.ps.targetlist = (List *)
00155 ExecInitExpr((Expr *) node->scan.plan.targetlist,
00156 (PlanState *) scanstate);
00157 scanstate->ss.ps.qual = (List *)
00158 ExecInitExpr((Expr *) node->scan.plan.qual,
00159 (PlanState *) scanstate);
00160
00161
00162
00163
00164
00165 functypclass = get_expr_result_type(node->funcexpr,
00166 &funcrettype,
00167 &tupdesc);
00168
00169 if (functypclass == TYPEFUNC_COMPOSITE)
00170 {
00171
00172 Assert(tupdesc);
00173
00174 tupdesc = CreateTupleDescCopy(tupdesc);
00175 }
00176 else if (functypclass == TYPEFUNC_SCALAR)
00177 {
00178
00179 char *attname = strVal(linitial(node->funccolnames));
00180
00181 tupdesc = CreateTemplateTupleDesc(1, false);
00182 TupleDescInitEntry(tupdesc,
00183 (AttrNumber) 1,
00184 attname,
00185 funcrettype,
00186 -1,
00187 0);
00188 TupleDescInitEntryCollation(tupdesc,
00189 (AttrNumber) 1,
00190 exprCollation(node->funcexpr));
00191 }
00192 else if (functypclass == TYPEFUNC_RECORD)
00193 {
00194 tupdesc = BuildDescFromLists(node->funccolnames,
00195 node->funccoltypes,
00196 node->funccoltypmods,
00197 node->funccolcollations);
00198 }
00199 else
00200 {
00201
00202 elog(ERROR, "function in FROM has unsupported return type");
00203 }
00204
00205
00206
00207
00208
00209
00210 BlessTupleDesc(tupdesc);
00211
00212 scanstate->tupdesc = tupdesc;
00213 ExecAssignScanType(&scanstate->ss, tupdesc);
00214
00215
00216
00217
00218 scanstate->tuplestorestate = NULL;
00219 scanstate->funcexpr = ExecInitExpr((Expr *) node->funcexpr,
00220 (PlanState *) scanstate);
00221
00222 scanstate->ss.ps.ps_TupFromTlist = false;
00223
00224
00225
00226
00227 ExecAssignResultTypeFromTL(&scanstate->ss.ps);
00228 ExecAssignScanProjectionInfo(&scanstate->ss);
00229
00230 return scanstate;
00231 }
00232
00233
00234
00235
00236
00237
00238
00239 void
00240 ExecEndFunctionScan(FunctionScanState *node)
00241 {
00242
00243
00244
00245 ExecFreeExprContext(&node->ss.ps);
00246
00247
00248
00249
00250 ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
00251 ExecClearTuple(node->ss.ss_ScanTupleSlot);
00252
00253
00254
00255
00256 if (node->tuplestorestate != NULL)
00257 tuplestore_end(node->tuplestorestate);
00258 node->tuplestorestate = NULL;
00259 }
00260
00261
00262
00263
00264
00265
00266
00267 void
00268 ExecReScanFunctionScan(FunctionScanState *node)
00269 {
00270 ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
00271
00272 ExecScanReScan(&node->ss);
00273
00274
00275
00276
00277 if (!node->tuplestorestate)
00278 return;
00279
00280
00281
00282
00283
00284
00285
00286 if (node->ss.ps.chgParam != NULL)
00287 {
00288 tuplestore_end(node->tuplestorestate);
00289 node->tuplestorestate = NULL;
00290 }
00291 else
00292 tuplestore_rescan(node->tuplestorestate);
00293 }