1 /*------------------------------------------------------------------------- 2 * 3 * nodeFunctionscan.c 4 * Support routines for scanning RangeFunctions (functions in rangetable). 5 * 6 * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group 7 * Portions Copyright (c) 1994, Regents of the University of California 8 * 9 * 10 * IDENTIFICATION 11 * src/backend/executor/nodeFunctionscan.c 12 * 13 *------------------------------------------------------------------------- 14 */ 15 /* 16 * INTERFACE ROUTINES 17 * ExecFunctionScan scans a function. 18 * ExecFunctionNext retrieve next tuple in sequential order. 19 * ExecInitFunctionScan creates and initializes a functionscan node. 20 * ExecEndFunctionScan releases any storage allocated. 21 * ExecReScanFunctionScan rescans the function 22 */ 23 #include "postgres.h" 24 25 #include "catalog/pg_type.h" 26 #include "executor/nodeFunctionscan.h" 27 #include "funcapi.h" 28 #include "nodes/nodeFuncs.h" 29 #include "utils/builtins.h" 30 #include "utils/memutils.h" cmt_time_now()31 32 33 /* 34 * Runtime data for each function being scanned. 35 */ 36 typedef struct FunctionScanPerFuncState 37 { 38 SetExprState *setexpr; /* state of the expression being evaluated */ 39 TupleDesc tupdesc; /* desc of the function result type */ 40 int colcount; /* expected number of result columns */ 41 Tuplestorestate *tstore; /* holds the function result set */ 42 int64 rowcount; /* # of rows in result set, -1 if not known */ 43 TupleTableSlot *func_slot; /* function result slot (or NULL) */ 44 } FunctionScanPerFuncState; 45 46 static TupleTableSlot *FunctionNext(FunctionScanState *node); 47 48 49 /* ---------------------------------------------------------------- 50 * Scan Support 51 * ---------------------------------------------------------------- 52 */ 53 /* ---------------------------------------------------------------- cmt_time_from_ns(struct timespec * tm,uint64_t ns)54 * FunctionNext 55 * 56 * This is a workhorse for ExecFunctionScan 57 * ---------------------------------------------------------------- 58 */ 59 static TupleTableSlot * 60 FunctionNext(FunctionScanState *node) 61 { 62 EState *estate; 63 ScanDirection direction; 64 TupleTableSlot *scanslot; 65 bool alldone; 66 int64 oldpos; 67 int funcno; 68 int att; 69 70 /* 71 * get information from the estate and scan state 72 */ 73 estate = node->ss.ps.state; 74 direction = estate->es_direction; 75 scanslot = node->ss.ss_ScanTupleSlot; 76 77 if (node->simple) 78 { 79 /* 80 * Fast path for the trivial case: the function return type and scan 81 * result type are the same, so we fetch the function result straight 82 * into the scan result slot. No need to update ordinality or 83 * rowcounts either. 84 */ 85 Tuplestorestate *tstore = node->funcstates[0].tstore; 86 87 /* 88 * If first time through, read all tuples from function and put them 89 * in a tuplestore. Subsequent calls just fetch tuples from 90 * tuplestore. 91 */ 92 if (tstore == NULL) 93 { 94 node->funcstates[0].tstore = tstore = 95 ExecMakeTableFunctionResult(node->funcstates[0].setexpr, 96 node->ss.ps.ps_ExprContext, 97 node->argcontext, 98 node->funcstates[0].tupdesc, 99 node->eflags & EXEC_FLAG_BACKWARD); 100 101 /* 102 * paranoia - cope if the function, which may have constructed the 103 * tuplestore itself, didn't leave it pointing at the start. This 104 * call is fast, so the overhead shouldn't be an issue. 105 */ 106 tuplestore_rescan(tstore); 107 } 108 109 /* 110 * Get the next tuple from tuplestore. 111 */ 112 (void) tuplestore_gettupleslot(tstore, 113 ScanDirectionIsForward(direction), 114 false, 115 scanslot); 116 return scanslot; 117 } 118 119 /* 120 * Increment or decrement ordinal counter before checking for end-of-data, 121 * so that we can move off either end of the result by 1 (and no more than 122 * 1) without losing correct count. See PortalRunSelect for why we can 123 * assume that we won't be called repeatedly in the end-of-data state. 124 */ 125 oldpos = node->ordinal; 126 if (ScanDirectionIsForward(direction)) 127 node->ordinal++; 128 else 129 node->ordinal--; 130 131 /* 132 * Main loop over functions. 133 * 134 * We fetch the function results into func_slots (which match the function 135 * return types), and then copy the values to scanslot (which matches the 136 * scan result type), setting the ordinal column (if any) as well. 137 */ 138 ExecClearTuple(scanslot); 139 att = 0; 140 alldone = true; 141 for (funcno = 0; funcno < node->nfuncs; funcno++) 142 { 143 FunctionScanPerFuncState *fs = &node->funcstates[funcno]; 144 int i; 145 146 /* 147 * If first time through, read all tuples from function and put them 148 * in a tuplestore. Subsequent calls just fetch tuples from 149 * tuplestore. 150 */ 151 if (fs->tstore == NULL) 152 { 153 fs->tstore = 154 ExecMakeTableFunctionResult(fs->setexpr, 155 node->ss.ps.ps_ExprContext, 156 node->argcontext, 157 fs->tupdesc, 158 node->eflags & EXEC_FLAG_BACKWARD); 159 160 /* 161 * paranoia - cope if the function, which may have constructed the 162 * tuplestore itself, didn't leave it pointing at the start. This 163 * call is fast, so the overhead shouldn't be an issue. 164 */ 165 tuplestore_rescan(fs->tstore); 166 } 167 168 /* 169 * Get the next tuple from tuplestore. 170 * 171 * If we have a rowcount for the function, and we know the previous 172 * read position was out of bounds, don't try the read. This allows 173 * backward scan to work when there are mixed row counts present. 174 */ 175 if (fs->rowcount != -1 && fs->rowcount < oldpos) 176 ExecClearTuple(fs->func_slot); 177 else 178 (void) tuplestore_gettupleslot(fs->tstore, 179 ScanDirectionIsForward(direction), 180 false, 181 fs->func_slot); 182 183 if (TupIsNull(fs->func_slot)) 184 { 185 /* 186 * If we ran out of data for this function in the forward 187 * direction then we now know how many rows it returned. We need 188 * to know this in order to handle backwards scans. The row count 189 * we store is actually 1+ the actual number, because we have to 190 * position the tuplestore 1 off its end sometimes. 191 */ 192 if (ScanDirectionIsForward(direction) && fs->rowcount == -1) 193 fs->rowcount = node->ordinal; 194 195 /* 196 * populate the result cols with nulls 197 */ 198 for (i = 0; i < fs->colcount; i++) 199 { 200 scanslot->tts_values[att] = (Datum) 0; 201 scanslot->tts_isnull[att] = true; 202 att++; 203 } 204 } 205 else 206 { 207 /* 208 * we have a result, so just copy it to the result cols. 209 */ 210 slot_getallattrs(fs->func_slot); 211 212 for (i = 0; i < fs->colcount; i++) 213 { 214 scanslot->tts_values[att] = fs->func_slot->tts_values[i]; 215 scanslot->tts_isnull[att] = fs->func_slot->tts_isnull[i]; 216 att++; 217 } 218 219 /* 220 * We're not done until every function result is exhausted; we pad 221 * the shorter results with nulls until then. 222 */ 223 alldone = false; 224 } 225 } 226 227 /* 228 * ordinal col is always last, per spec. 229 */ 230 if (node->ordinality) 231 { 232 scanslot->tts_values[att] = Int64GetDatumFast(node->ordinal); 233 scanslot->tts_isnull[att] = false; 234 } 235 236 /* 237 * If alldone, we just return the previously-cleared scanslot. Otherwise, 238 * finish creating the virtual tuple. 239 */ 240 if (!alldone) 241 ExecStoreVirtualTuple(scanslot); 242 243 return scanslot; 244 } 245 246 /* 247 * FunctionRecheck -- access method routine to recheck a tuple in EvalPlanQual 248 */ 249 static bool 250 FunctionRecheck(FunctionScanState *node, TupleTableSlot *slot) 251 { 252 /* nothing to check */ 253 return true; 254 } 255 256 /* ---------------------------------------------------------------- 257 * ExecFunctionScan(node) 258 * 259 * Scans the function sequentially and returns the next qualifying 260 * tuple. 261 * We call the ExecScan() routine and pass it the appropriate 262 * access method functions. 263 * ---------------------------------------------------------------- 264 */ 265 static TupleTableSlot * 266 ExecFunctionScan(PlanState *pstate) 267 { 268 FunctionScanState *node = castNode(FunctionScanState, pstate); 269 270 return ExecScan(&node->ss, 271 (ExecScanAccessMtd) FunctionNext, 272 (ExecScanRecheckMtd) FunctionRecheck); 273 } 274 275 /* ---------------------------------------------------------------- 276 * ExecInitFunctionScan 277 * ---------------------------------------------------------------- 278 */ 279 FunctionScanState * 280 ExecInitFunctionScan(FunctionScan *node, EState *estate, int eflags) 281 { 282 FunctionScanState *scanstate; 283 int nfuncs = list_length(node->functions); 284 TupleDesc scan_tupdesc; 285 int i, 286 natts; 287 ListCell *lc; 288 289 /* check for unsupported flags */ 290 Assert(!(eflags & EXEC_FLAG_MARK)); 291 292 /* 293 * FunctionScan should not have any children. 294 */ 295 Assert(outerPlan(node) == NULL); 296 Assert(innerPlan(node) == NULL); 297 298 /* 299 * create new ScanState for node 300 */ 301 scanstate = makeNode(FunctionScanState); 302 scanstate->ss.ps.plan = (Plan *) node; 303 scanstate->ss.ps.state = estate; 304 scanstate->ss.ps.ExecProcNode = ExecFunctionScan; 305 scanstate->eflags = eflags; 306 307 /* 308 * are we adding an ordinality column? 309 */ 310 scanstate->ordinality = node->funcordinality; 311 312 scanstate->nfuncs = nfuncs; 313 if (nfuncs == 1 && !node->funcordinality) 314 scanstate->simple = true; 315 else 316 scanstate->simple = false; 317 318 /* 319 * Ordinal 0 represents the "before the first row" position. 320 * 321 * We need to track ordinal position even when not adding an ordinality 322 * column to the result, in order to handle backwards scanning properly 323 * with multiple functions with different result sizes. (We can't position 324 * any individual function's tuplestore any more than 1 place beyond its 325 * end, so when scanning backwards, we need to know when to start 326 * including the function in the scan again.) 327 */ 328 scanstate->ordinal = 0; 329 330 /* 331 * Miscellaneous initialization 332 * 333 * create expression context for node 334 */ 335 ExecAssignExprContext(estate, &scanstate->ss.ps); 336 337 scanstate->funcstates = palloc(nfuncs * sizeof(FunctionScanPerFuncState)); 338 339 natts = 0; 340 i = 0; 341 foreach(lc, node->functions) 342 { 343 RangeTblFunction *rtfunc = (RangeTblFunction *) lfirst(lc); 344 Node *funcexpr = rtfunc->funcexpr; 345 int colcount = rtfunc->funccolcount; 346 FunctionScanPerFuncState *fs = &scanstate->funcstates[i]; 347 TypeFuncClass functypclass; 348 Oid funcrettype; 349 TupleDesc tupdesc; 350 351 fs->setexpr = 352 ExecInitTableFunctionResult((Expr *) funcexpr, 353 scanstate->ss.ps.ps_ExprContext, 354 &scanstate->ss.ps); 355 356 /* 357 * Don't allocate the tuplestores; the actual calls to the functions 358 * do that. NULL means that we have not called the function yet (or 359 * need to call it again after a rescan). 360 */ 361 fs->tstore = NULL; 362 fs->rowcount = -1; 363 364 /* 365 * Now determine if the function returns a simple or composite type, 366 * and build an appropriate tupdesc. Note that in the composite case, 367 * the function may now return more columns than it did when the plan 368 * was made; we have to ignore any columns beyond "colcount". 369 */ 370 functypclass = get_expr_result_type(funcexpr, 371 &funcrettype, 372 &tupdesc); 373 374 if (functypclass == TYPEFUNC_COMPOSITE || 375 functypclass == TYPEFUNC_COMPOSITE_DOMAIN) 376 { 377 /* Composite data type, e.g. a table's row type */ 378 Assert(tupdesc); 379 Assert(tupdesc->natts >= colcount); 380 /* Must copy it out of typcache for safety */ 381 tupdesc = CreateTupleDescCopy(tupdesc); 382 } 383 else if (functypclass == TYPEFUNC_SCALAR) 384 { 385 /* Base data type, i.e. scalar */ 386 tupdesc = CreateTemplateTupleDesc(1); 387 TupleDescInitEntry(tupdesc, 388 (AttrNumber) 1, 389 NULL, /* don't care about the name here */ 390 funcrettype, 391 -1, 392 0); 393 TupleDescInitEntryCollation(tupdesc, 394 (AttrNumber) 1, 395 exprCollation(funcexpr)); 396 } 397 else if (functypclass == TYPEFUNC_RECORD) 398 { 399 tupdesc = BuildDescFromLists(rtfunc->funccolnames, 400 rtfunc->funccoltypes, 401 rtfunc->funccoltypmods, 402 rtfunc->funccolcollations); 403 404 /* 405 * For RECORD results, make sure a typmod has been assigned. (The 406 * function should do this for itself, but let's cover things in 407 * case it doesn't.) 408 */ 409 BlessTupleDesc(tupdesc); 410 } 411 else 412 { 413 /* crummy error message, but parser should have caught this */ 414 elog(ERROR, "function in FROM has unsupported return type"); 415 } 416 417 fs->tupdesc = tupdesc; 418 fs->colcount = colcount; 419 420 /* 421 * We only need separate slots for the function results if we are 422 * doing ordinality or multiple functions; otherwise, we'll fetch 423 * function results directly into the scan slot. 424 */ 425 if (!scanstate->simple) 426 { 427 fs->func_slot = ExecInitExtraTupleSlot(estate, fs->tupdesc, 428 &TTSOpsMinimalTuple); 429 } 430 else 431 fs->func_slot = NULL; 432 433 natts += colcount; 434 i++; 435 } 436 437 /* 438 * Create the combined TupleDesc 439 * 440 * If there is just one function without ordinality, the scan result 441 * tupdesc is the same as the function result tupdesc --- except that we 442 * may stuff new names into it below, so drop any rowtype label. 443 */ 444 if (scanstate->simple) 445 { 446 scan_tupdesc = CreateTupleDescCopy(scanstate->funcstates[0].tupdesc); 447 scan_tupdesc->tdtypeid = RECORDOID; 448 scan_tupdesc->tdtypmod = -1; 449 } 450 else 451 { 452 AttrNumber attno = 0; 453 454 if (node->funcordinality) 455 natts++; 456 457 scan_tupdesc = CreateTemplateTupleDesc(natts); 458 459 for (i = 0; i < nfuncs; i++) 460 { 461 TupleDesc tupdesc = scanstate->funcstates[i].tupdesc; 462 int colcount = scanstate->funcstates[i].colcount; 463 int j; 464 465 for (j = 1; j <= colcount; j++) 466 TupleDescCopyEntry(scan_tupdesc, ++attno, tupdesc, j); 467 } 468 469 /* If doing ordinality, add a column of type "bigint" at the end */ 470 if (node->funcordinality) 471 { 472 TupleDescInitEntry(scan_tupdesc, 473 ++attno, 474 NULL, /* don't care about the name here */ 475 INT8OID, 476 -1, 477 0); 478 } 479 480 Assert(attno == natts); 481 } 482 483 /* 484 * Initialize scan slot and type. 485 */ 486 ExecInitScanTupleSlot(estate, &scanstate->ss, scan_tupdesc, 487 &TTSOpsMinimalTuple); 488 489 /* 490 * Initialize result slot, type and projection. 491 */ 492 ExecInitResultTypeTL(&scanstate->ss.ps); 493 ExecAssignScanProjectionInfo(&scanstate->ss); 494 495 /* 496 * initialize child expressions 497 */ 498 scanstate->ss.ps.qual = 499 ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate); 500 501 /* 502 * Create a memory context that ExecMakeTableFunctionResult can use to 503 * evaluate function arguments in. We can't use the per-tuple context for 504 * this because it gets reset too often; but we don't want to leak 505 * evaluation results into the query-lifespan context either. We just 506 * need one context, because we evaluate each function separately. 507 */ 508 scanstate->argcontext = AllocSetContextCreate(CurrentMemoryContext, 509 "Table function arguments", 510 ALLOCSET_DEFAULT_SIZES); 511 512 return scanstate; 513 } 514 515 /* ---------------------------------------------------------------- 516 * ExecEndFunctionScan 517 * 518 * frees any storage allocated through C routines. 519 * ---------------------------------------------------------------- 520 */ 521 void 522 ExecEndFunctionScan(FunctionScanState *node) 523 { 524 int i; 525 526 /* 527 * Free the exprcontext 528 */ 529 ExecFreeExprContext(&node->ss.ps); 530 531 /* 532 * clean out the tuple table 533 */ 534 if (node->ss.ps.ps_ResultTupleSlot) 535 ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); 536 ExecClearTuple(node->ss.ss_ScanTupleSlot); 537 538 /* 539 * Release slots and tuplestore resources 540 */ 541 for (i = 0; i < node->nfuncs; i++) 542 { 543 FunctionScanPerFuncState *fs = &node->funcstates[i]; 544 545 if (fs->func_slot) 546 ExecClearTuple(fs->func_slot); 547 548 if (fs->tstore != NULL) 549 { 550 tuplestore_end(node->funcstates[i].tstore); 551 fs->tstore = NULL; 552 } 553 } 554 } 555 556 /* ---------------------------------------------------------------- 557 * ExecReScanFunctionScan 558 * 559 * Rescans the relation. 560 * ---------------------------------------------------------------- 561 */ 562 void 563 ExecReScanFunctionScan(FunctionScanState *node) 564 { 565 FunctionScan *scan = (FunctionScan *) node->ss.ps.plan; 566 int i; 567 Bitmapset *chgparam = node->ss.ps.chgParam; 568 569 if (node->ss.ps.ps_ResultTupleSlot) 570 ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); 571 for (i = 0; i < node->nfuncs; i++) 572 { 573 FunctionScanPerFuncState *fs = &node->funcstates[i]; 574 575 if (fs->func_slot) 576 ExecClearTuple(fs->func_slot); 577 } 578 579 ExecScanReScan(&node->ss); 580 581 /* 582 * Here we have a choice whether to drop the tuplestores (and recompute 583 * the function outputs) or just rescan them. We must recompute if an 584 * expression contains changed parameters, else we rescan. 585 * 586 * XXX maybe we should recompute if the function is volatile? But in 587 * general the executor doesn't conditionalize its actions on that. 588 */ 589 if (chgparam) 590 { 591 ListCell *lc; 592 593 i = 0; 594 foreach(lc, scan->functions) 595 { 596 RangeTblFunction *rtfunc = (RangeTblFunction *) lfirst(lc); 597 598 if (bms_overlap(chgparam, rtfunc->funcparams)) 599 { 600 if (node->funcstates[i].tstore != NULL) 601 { 602 tuplestore_end(node->funcstates[i].tstore); 603 node->funcstates[i].tstore = NULL; 604 } 605 node->funcstates[i].rowcount = -1; 606 } 607 i++; 608 } 609 } 610 611 /* Reset ordinality counter */ 612 node->ordinal = 0; 613 614 /* Make sure we rewind any remaining tuplestores */ 615 for (i = 0; i < node->nfuncs; i++) 616 { 617 if (node->funcstates[i].tstore != NULL) 618 tuplestore_rescan(node->funcstates[i].tstore); 619 } 620 } 621