1 /*------------------------------------------------------------------------- 2 * 3 * execUtils.c 4 * miscellaneous executor utility routines 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/execUtils.c 12 * 13 *------------------------------------------------------------------------- 14 */ 15 /* 16 * INTERFACE ROUTINES 17 * CreateExecutorState Create/delete executor working state 18 * FreeExecutorState 19 * CreateExprContext 20 * CreateStandaloneExprContext 21 * FreeExprContext 22 * ReScanExprContext 23 * 24 * ExecAssignExprContext Common code for plan node init routines. 25 * etc 26 * 27 * ExecOpenScanRelation Common code for scan node init routines. 28 * 29 * ExecInitRangeTable Set up executor's range-table-related data. 30 * 31 * ExecGetRangeTableRelation Fetch Relation for a rangetable entry. 32 * 33 * executor_errposition Report syntactic position of an error. 34 * 35 * RegisterExprContextCallback Register function shutdown callback 36 * UnregisterExprContextCallback Deregister function shutdown callback 37 * 38 * GetAttributeByName Runtime extraction of columns from tuples. 39 * GetAttributeByNum 40 * 41 * NOTES 42 * This file has traditionally been the place to stick misc. 43 * executor support stuff that doesn't really go anyplace else. 44 */ 45 46 #include "postgres.h" 47 48 #include "access/parallel.h" 49 #include "access/relscan.h" 50 #include "access/table.h" 51 #include "access/tableam.h" 52 #include "access/transam.h" 53 #include "executor/executor.h" 54 #include "executor/execPartition.h" 55 #include "jit/jit.h" 56 #include "mb/pg_wchar.h" 57 #include "nodes/nodeFuncs.h" 58 #include "parser/parsetree.h" 59 #include "partitioning/partdesc.h" 60 #include "storage/lmgr.h" 61 #include "utils/builtins.h" 62 #include "utils/memutils.h" 63 #include "utils/rel.h" 64 #include "utils/typcache.h" 65 66 67 static bool tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc); 68 static void ShutdownExprContext(ExprContext *econtext, bool isCommit); 69 70 71 /* ---------------------------------------------------------------- 72 * Executor state and memory management functions 73 * ---------------------------------------------------------------- 74 */ 75 76 /* ---------------- 77 * CreateExecutorState 78 * 79 * Create and initialize an EState node, which is the root of 80 * working storage for an entire Executor invocation. 81 * 82 * Principally, this creates the per-query memory context that will be 83 * used to hold all working data that lives till the end of the query. 84 * Note that the per-query context will become a child of the caller's 85 * CurrentMemoryContext. 86 * ---------------- 87 */ 88 EState * 89 CreateExecutorState(void) 90 { 91 EState *estate; 92 MemoryContext qcontext; 93 MemoryContext oldcontext; 94 95 /* 96 * Create the per-query context for this Executor run. 97 */ 98 qcontext = AllocSetContextCreate(CurrentMemoryContext, 99 "ExecutorState", 100 ALLOCSET_DEFAULT_SIZES); 101 102 /* 103 * Make the EState node within the per-query context. This way, we don't 104 * need a separate pfree() operation for it at shutdown. 105 */ 106 oldcontext = MemoryContextSwitchTo(qcontext); 107 108 estate = makeNode(EState); 109 110 /* 111 * Initialize all fields of the Executor State structure 112 */ 113 estate->es_direction = ForwardScanDirection; 114 estate->es_snapshot = InvalidSnapshot; /* caller must initialize this */ 115 estate->es_crosscheck_snapshot = InvalidSnapshot; /* no crosscheck */ 116 estate->es_range_table = NIL; 117 estate->es_range_table_array = NULL; 118 estate->es_range_table_size = 0; 119 estate->es_relations = NULL; 120 estate->es_rowmarks = NULL; 121 estate->es_plannedstmt = NULL; 122 123 estate->es_junkFilter = NULL; 124 125 estate->es_output_cid = (CommandId) 0; 126 127 estate->es_result_relations = NULL; 128 estate->es_num_result_relations = 0; 129 estate->es_result_relation_info = NULL; 130 131 estate->es_root_result_relations = NULL; 132 estate->es_num_root_result_relations = 0; 133 134 estate->es_tuple_routing_result_relations = NIL; 135 136 estate->es_trig_target_relations = NIL; 137 138 estate->es_param_list_info = NULL; 139 estate->es_param_exec_vals = NULL; 140 141 estate->es_queryEnv = NULL; 142 143 estate->es_query_cxt = qcontext; 144 145 estate->es_tupleTable = NIL; 146 147 estate->es_processed = 0; 148 149 estate->es_top_eflags = 0; 150 estate->es_instrument = 0; 151 estate->es_finished = false; 152 153 estate->es_exprcontexts = NIL; 154 155 estate->es_subplanstates = NIL; 156 157 estate->es_auxmodifytables = NIL; 158 159 estate->es_per_tuple_exprcontext = NULL; 160 161 estate->es_sourceText = NULL; 162 163 estate->es_use_parallel_mode = false; 164 165 estate->es_jit_flags = 0; 166 estate->es_jit = NULL; 167 168 /* 169 * Return the executor state structure 170 */ 171 MemoryContextSwitchTo(oldcontext); 172 173 return estate; 174 } 175 176 /* ---------------- 177 * FreeExecutorState 178 * 179 * Release an EState along with all remaining working storage. 180 * 181 * Note: this is not responsible for releasing non-memory resources, such as 182 * open relations or buffer pins. But it will shut down any still-active 183 * ExprContexts within the EState and deallocate associated JITed expressions. 184 * That is sufficient cleanup for situations where the EState has only been 185 * used for expression evaluation, and not to run a complete Plan. 186 * 187 * This can be called in any memory context ... so long as it's not one 188 * of the ones to be freed. 189 * ---------------- 190 */ 191 void 192 FreeExecutorState(EState *estate) 193 { 194 /* 195 * Shut down and free any remaining ExprContexts. We do this explicitly 196 * to ensure that any remaining shutdown callbacks get called (since they 197 * might need to release resources that aren't simply memory within the 198 * per-query memory context). 199 */ 200 while (estate->es_exprcontexts) 201 { 202 /* 203 * XXX: seems there ought to be a faster way to implement this than 204 * repeated list_delete(), no? 205 */ 206 FreeExprContext((ExprContext *) linitial(estate->es_exprcontexts), 207 true); 208 /* FreeExprContext removed the list link for us */ 209 } 210 211 /* release JIT context, if allocated */ 212 if (estate->es_jit) 213 { 214 jit_release_context(estate->es_jit); 215 estate->es_jit = NULL; 216 } 217 218 /* release partition directory, if allocated */ 219 if (estate->es_partition_directory) 220 { 221 DestroyPartitionDirectory(estate->es_partition_directory); 222 estate->es_partition_directory = NULL; 223 } 224 225 /* 226 * Free the per-query memory context, thereby releasing all working 227 * memory, including the EState node itself. 228 */ 229 MemoryContextDelete(estate->es_query_cxt); 230 } 231 232 /* ---------------- 233 * CreateExprContext 234 * 235 * Create a context for expression evaluation within an EState. 236 * 237 * An executor run may require multiple ExprContexts (we usually make one 238 * for each Plan node, and a separate one for per-output-tuple processing 239 * such as constraint checking). Each ExprContext has its own "per-tuple" 240 * memory context. 241 * 242 * Note we make no assumption about the caller's memory context. 243 * ---------------- 244 */ 245 ExprContext * 246 CreateExprContext(EState *estate) 247 { 248 ExprContext *econtext; 249 MemoryContext oldcontext; 250 251 /* Create the ExprContext node within the per-query memory context */ 252 oldcontext = MemoryContextSwitchTo(estate->es_query_cxt); 253 254 econtext = makeNode(ExprContext); 255 256 /* Initialize fields of ExprContext */ 257 econtext->ecxt_scantuple = NULL; 258 econtext->ecxt_innertuple = NULL; 259 econtext->ecxt_outertuple = NULL; 260 261 econtext->ecxt_per_query_memory = estate->es_query_cxt; 262 263 /* 264 * Create working memory for expression evaluation in this context. 265 */ 266 econtext->ecxt_per_tuple_memory = 267 AllocSetContextCreate(estate->es_query_cxt, 268 "ExprContext", 269 ALLOCSET_DEFAULT_SIZES); 270 271 econtext->ecxt_param_exec_vals = estate->es_param_exec_vals; 272 econtext->ecxt_param_list_info = estate->es_param_list_info; 273 274 econtext->ecxt_aggvalues = NULL; 275 econtext->ecxt_aggnulls = NULL; 276 277 econtext->caseValue_datum = (Datum) 0; 278 econtext->caseValue_isNull = true; 279 280 econtext->domainValue_datum = (Datum) 0; 281 econtext->domainValue_isNull = true; 282 283 econtext->ecxt_estate = estate; 284 285 econtext->ecxt_callbacks = NULL; 286 287 /* 288 * Link the ExprContext into the EState to ensure it is shut down when the 289 * EState is freed. Because we use lcons(), shutdowns will occur in 290 * reverse order of creation, which may not be essential but can't hurt. 291 */ 292 estate->es_exprcontexts = lcons(econtext, estate->es_exprcontexts); 293 294 MemoryContextSwitchTo(oldcontext); 295 296 return econtext; 297 } 298 299 /* ---------------- 300 * CreateStandaloneExprContext 301 * 302 * Create a context for standalone expression evaluation. 303 * 304 * An ExprContext made this way can be used for evaluation of expressions 305 * that contain no Params, subplans, or Var references (it might work to 306 * put tuple references into the scantuple field, but it seems unwise). 307 * 308 * The ExprContext struct is allocated in the caller's current memory 309 * context, which also becomes its "per query" context. 310 * 311 * It is caller's responsibility to free the ExprContext when done, 312 * or at least ensure that any shutdown callbacks have been called 313 * (ReScanExprContext() is suitable). Otherwise, non-memory resources 314 * might be leaked. 315 * ---------------- 316 */ 317 ExprContext * 318 CreateStandaloneExprContext(void) 319 { 320 ExprContext *econtext; 321 322 /* Create the ExprContext node within the caller's memory context */ 323 econtext = makeNode(ExprContext); 324 325 /* Initialize fields of ExprContext */ 326 econtext->ecxt_scantuple = NULL; 327 econtext->ecxt_innertuple = NULL; 328 econtext->ecxt_outertuple = NULL; 329 330 econtext->ecxt_per_query_memory = CurrentMemoryContext; 331 332 /* 333 * Create working memory for expression evaluation in this context. 334 */ 335 econtext->ecxt_per_tuple_memory = 336 AllocSetContextCreate(CurrentMemoryContext, 337 "ExprContext", 338 ALLOCSET_DEFAULT_SIZES); 339 340 econtext->ecxt_param_exec_vals = NULL; 341 econtext->ecxt_param_list_info = NULL; 342 343 econtext->ecxt_aggvalues = NULL; 344 econtext->ecxt_aggnulls = NULL; 345 346 econtext->caseValue_datum = (Datum) 0; 347 econtext->caseValue_isNull = true; 348 349 econtext->domainValue_datum = (Datum) 0; 350 econtext->domainValue_isNull = true; 351 352 econtext->ecxt_estate = NULL; 353 354 econtext->ecxt_callbacks = NULL; 355 356 return econtext; 357 } 358 359 /* ---------------- 360 * FreeExprContext 361 * 362 * Free an expression context, including calling any remaining 363 * shutdown callbacks. 364 * 365 * Since we free the temporary context used for expression evaluation, 366 * any previously computed pass-by-reference expression result will go away! 367 * 368 * If isCommit is false, we are being called in error cleanup, and should 369 * not call callbacks but only release memory. (It might be better to call 370 * the callbacks and pass the isCommit flag to them, but that would require 371 * more invasive code changes than currently seems justified.) 372 * 373 * Note we make no assumption about the caller's memory context. 374 * ---------------- 375 */ 376 void 377 FreeExprContext(ExprContext *econtext, bool isCommit) 378 { 379 EState *estate; 380 381 /* Call any registered callbacks */ 382 ShutdownExprContext(econtext, isCommit); 383 /* And clean up the memory used */ 384 MemoryContextDelete(econtext->ecxt_per_tuple_memory); 385 /* Unlink self from owning EState, if any */ 386 estate = econtext->ecxt_estate; 387 if (estate) 388 estate->es_exprcontexts = list_delete_ptr(estate->es_exprcontexts, 389 econtext); 390 /* And delete the ExprContext node */ 391 pfree(econtext); 392 } 393 394 /* 395 * ReScanExprContext 396 * 397 * Reset an expression context in preparation for a rescan of its 398 * plan node. This requires calling any registered shutdown callbacks, 399 * since any partially complete set-returning-functions must be canceled. 400 * 401 * Note we make no assumption about the caller's memory context. 402 */ 403 void 404 ReScanExprContext(ExprContext *econtext) 405 { 406 /* Call any registered callbacks */ 407 ShutdownExprContext(econtext, true); 408 /* And clean up the memory used */ 409 MemoryContextReset(econtext->ecxt_per_tuple_memory); 410 } 411 412 /* 413 * Build a per-output-tuple ExprContext for an EState. 414 * 415 * This is normally invoked via GetPerTupleExprContext() macro, 416 * not directly. 417 */ 418 ExprContext * 419 MakePerTupleExprContext(EState *estate) 420 { 421 if (estate->es_per_tuple_exprcontext == NULL) 422 estate->es_per_tuple_exprcontext = CreateExprContext(estate); 423 424 return estate->es_per_tuple_exprcontext; 425 } 426 427 428 /* ---------------------------------------------------------------- 429 * miscellaneous node-init support functions 430 * 431 * Note: all of these are expected to be called with CurrentMemoryContext 432 * equal to the per-query memory context. 433 * ---------------------------------------------------------------- 434 */ 435 436 /* ---------------- 437 * ExecAssignExprContext 438 * 439 * This initializes the ps_ExprContext field. It is only necessary 440 * to do this for nodes which use ExecQual or ExecProject 441 * because those routines require an econtext. Other nodes that 442 * don't have to evaluate expressions don't need to do this. 443 * ---------------- 444 */ 445 void 446 ExecAssignExprContext(EState *estate, PlanState *planstate) 447 { 448 planstate->ps_ExprContext = CreateExprContext(estate); 449 } 450 451 /* ---------------- 452 * ExecGetResultType 453 * ---------------- 454 */ 455 TupleDesc 456 ExecGetResultType(PlanState *planstate) 457 { 458 return planstate->ps_ResultTupleDesc; 459 } 460 461 /* 462 * ExecGetResultSlotOps - information about node's type of result slot 463 */ 464 const TupleTableSlotOps * 465 ExecGetResultSlotOps(PlanState *planstate, bool *isfixed) 466 { 467 if (planstate->resultopsset && planstate->resultops) 468 { 469 if (isfixed) 470 *isfixed = planstate->resultopsfixed; 471 return planstate->resultops; 472 } 473 474 if (isfixed) 475 { 476 if (planstate->resultopsset) 477 *isfixed = planstate->resultopsfixed; 478 else if (planstate->ps_ResultTupleSlot) 479 *isfixed = TTS_FIXED(planstate->ps_ResultTupleSlot); 480 else 481 *isfixed = false; 482 } 483 484 if (!planstate->ps_ResultTupleSlot) 485 return &TTSOpsVirtual; 486 487 return planstate->ps_ResultTupleSlot->tts_ops; 488 } 489 490 491 /* ---------------- 492 * ExecAssignProjectionInfo 493 * 494 * forms the projection information from the node's targetlist 495 * 496 * Notes for inputDesc are same as for ExecBuildProjectionInfo: supply it 497 * for a relation-scan node, can pass NULL for upper-level nodes 498 * ---------------- 499 */ 500 void 501 ExecAssignProjectionInfo(PlanState *planstate, 502 TupleDesc inputDesc) 503 { 504 planstate->ps_ProjInfo = 505 ExecBuildProjectionInfo(planstate->plan->targetlist, 506 planstate->ps_ExprContext, 507 planstate->ps_ResultTupleSlot, 508 planstate, 509 inputDesc); 510 } 511 512 513 /* ---------------- 514 * ExecConditionalAssignProjectionInfo 515 * 516 * as ExecAssignProjectionInfo, but store NULL rather than building projection 517 * info if no projection is required 518 * ---------------- 519 */ 520 void 521 ExecConditionalAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc, 522 Index varno) 523 { 524 if (tlist_matches_tupdesc(planstate, 525 planstate->plan->targetlist, 526 varno, 527 inputDesc)) 528 { 529 planstate->ps_ProjInfo = NULL; 530 planstate->resultopsset = planstate->scanopsset; 531 planstate->resultopsfixed = planstate->scanopsfixed; 532 planstate->resultops = planstate->scanops; 533 } 534 else 535 { 536 if (!planstate->ps_ResultTupleSlot) 537 { 538 ExecInitResultSlot(planstate, &TTSOpsVirtual); 539 planstate->resultops = &TTSOpsVirtual; 540 planstate->resultopsfixed = true; 541 planstate->resultopsset = true; 542 } 543 ExecAssignProjectionInfo(planstate, inputDesc); 544 } 545 } 546 547 static bool 548 tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc) 549 { 550 int numattrs = tupdesc->natts; 551 int attrno; 552 ListCell *tlist_item = list_head(tlist); 553 554 /* Check the tlist attributes */ 555 for (attrno = 1; attrno <= numattrs; attrno++) 556 { 557 Form_pg_attribute att_tup = TupleDescAttr(tupdesc, attrno - 1); 558 Var *var; 559 560 if (tlist_item == NULL) 561 return false; /* tlist too short */ 562 var = (Var *) ((TargetEntry *) lfirst(tlist_item))->expr; 563 if (!var || !IsA(var, Var)) 564 return false; /* tlist item not a Var */ 565 /* if these Asserts fail, planner messed up */ 566 Assert(var->varno == varno); 567 Assert(var->varlevelsup == 0); 568 if (var->varattno != attrno) 569 return false; /* out of order */ 570 if (att_tup->attisdropped) 571 return false; /* table contains dropped columns */ 572 if (att_tup->atthasmissing) 573 return false; /* table contains cols with missing values */ 574 575 /* 576 * Note: usually the Var's type should match the tupdesc exactly, but 577 * in situations involving unions of columns that have different 578 * typmods, the Var may have come from above the union and hence have 579 * typmod -1. This is a legitimate situation since the Var still 580 * describes the column, just not as exactly as the tupdesc does. We 581 * could change the planner to prevent it, but it'd then insert 582 * projection steps just to convert from specific typmod to typmod -1, 583 * which is pretty silly. 584 */ 585 if (var->vartype != att_tup->atttypid || 586 (var->vartypmod != att_tup->atttypmod && 587 var->vartypmod != -1)) 588 return false; /* type mismatch */ 589 590 tlist_item = lnext(tlist_item); 591 } 592 593 if (tlist_item) 594 return false; /* tlist too long */ 595 596 return true; 597 } 598 599 /* ---------------- 600 * ExecFreeExprContext 601 * 602 * A plan node's ExprContext should be freed explicitly during executor 603 * shutdown because there may be shutdown callbacks to call. (Other resources 604 * made by the above routines, such as projection info, don't need to be freed 605 * explicitly because they're just memory in the per-query memory context.) 606 * 607 * However ... there is no particular need to do it during ExecEndNode, 608 * because FreeExecutorState will free any remaining ExprContexts within 609 * the EState. Letting FreeExecutorState do it allows the ExprContexts to 610 * be freed in reverse order of creation, rather than order of creation as 611 * will happen if we delete them here, which saves O(N^2) work in the list 612 * cleanup inside FreeExprContext. 613 * ---------------- 614 */ 615 void 616 ExecFreeExprContext(PlanState *planstate) 617 { 618 /* 619 * Per above discussion, don't actually delete the ExprContext. We do 620 * unlink it from the plan node, though. 621 */ 622 planstate->ps_ExprContext = NULL; 623 } 624 625 626 /* ---------------------------------------------------------------- 627 * Scan node support 628 * ---------------------------------------------------------------- 629 */ 630 631 /* ---------------- 632 * ExecAssignScanType 633 * ---------------- 634 */ 635 void 636 ExecAssignScanType(ScanState *scanstate, TupleDesc tupDesc) 637 { 638 TupleTableSlot *slot = scanstate->ss_ScanTupleSlot; 639 640 ExecSetSlotDescriptor(slot, tupDesc); 641 } 642 643 /* ---------------- 644 * ExecCreateScanSlotFromOuterPlan 645 * ---------------- 646 */ 647 void 648 ExecCreateScanSlotFromOuterPlan(EState *estate, 649 ScanState *scanstate, 650 const TupleTableSlotOps *tts_ops) 651 { 652 PlanState *outerPlan; 653 TupleDesc tupDesc; 654 655 outerPlan = outerPlanState(scanstate); 656 tupDesc = ExecGetResultType(outerPlan); 657 658 ExecInitScanTupleSlot(estate, scanstate, tupDesc, tts_ops); 659 } 660 661 /* ---------------------------------------------------------------- 662 * ExecRelationIsTargetRelation 663 * 664 * Detect whether a relation (identified by rangetable index) 665 * is one of the target relations of the query. 666 * 667 * Note: This is currently no longer used in core. We keep it around 668 * because FDWs may wish to use it to determine if their foreign table 669 * is a target relation. 670 * ---------------------------------------------------------------- 671 */ 672 bool 673 ExecRelationIsTargetRelation(EState *estate, Index scanrelid) 674 { 675 ResultRelInfo *resultRelInfos; 676 int i; 677 678 resultRelInfos = estate->es_result_relations; 679 for (i = 0; i < estate->es_num_result_relations; i++) 680 { 681 if (resultRelInfos[i].ri_RangeTableIndex == scanrelid) 682 return true; 683 } 684 return false; 685 } 686 687 /* ---------------------------------------------------------------- 688 * ExecOpenScanRelation 689 * 690 * Open the heap relation to be scanned by a base-level scan plan node. 691 * This should be called during the node's ExecInit routine. 692 * ---------------------------------------------------------------- 693 */ 694 Relation 695 ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags) 696 { 697 Relation rel; 698 699 /* Open the relation. */ 700 rel = ExecGetRangeTableRelation(estate, scanrelid); 701 702 /* 703 * Complain if we're attempting a scan of an unscannable relation, except 704 * when the query won't actually be run. This is a slightly klugy place 705 * to do this, perhaps, but there is no better place. 706 */ 707 if ((eflags & (EXEC_FLAG_EXPLAIN_ONLY | EXEC_FLAG_WITH_NO_DATA)) == 0 && 708 !RelationIsScannable(rel)) 709 ereport(ERROR, 710 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), 711 errmsg("materialized view \"%s\" has not been populated", 712 RelationGetRelationName(rel)), 713 errhint("Use the REFRESH MATERIALIZED VIEW command."))); 714 715 return rel; 716 } 717 718 /* 719 * ExecInitRangeTable 720 * Set up executor's range-table-related data 721 * 722 * We build an array from the range table list to allow faster lookup by RTI. 723 * (The es_range_table field is now somewhat redundant, but we keep it to 724 * avoid breaking external code unnecessarily.) 725 * This is also a convenient place to set up the parallel es_relations array. 726 */ 727 void 728 ExecInitRangeTable(EState *estate, List *rangeTable) 729 { 730 Index rti; 731 ListCell *lc; 732 733 /* Remember the range table List as-is */ 734 estate->es_range_table = rangeTable; 735 736 /* Set up the equivalent array representation */ 737 estate->es_range_table_size = list_length(rangeTable); 738 estate->es_range_table_array = (RangeTblEntry **) 739 palloc(estate->es_range_table_size * sizeof(RangeTblEntry *)); 740 rti = 0; 741 foreach(lc, rangeTable) 742 { 743 estate->es_range_table_array[rti++] = lfirst_node(RangeTblEntry, lc); 744 } 745 746 /* 747 * Allocate an array to store an open Relation corresponding to each 748 * rangetable entry, and initialize entries to NULL. Relations are opened 749 * and stored here as needed. 750 */ 751 estate->es_relations = (Relation *) 752 palloc0(estate->es_range_table_size * sizeof(Relation)); 753 754 /* 755 * es_rowmarks is also parallel to the es_range_table_array, but it's 756 * allocated only if needed. 757 */ 758 estate->es_rowmarks = NULL; 759 } 760 761 /* 762 * ExecGetRangeTableRelation 763 * Open the Relation for a range table entry, if not already done 764 * 765 * The Relations will be closed again in ExecEndPlan(). 766 */ 767 Relation 768 ExecGetRangeTableRelation(EState *estate, Index rti) 769 { 770 Relation rel; 771 772 Assert(rti > 0 && rti <= estate->es_range_table_size); 773 774 rel = estate->es_relations[rti - 1]; 775 if (rel == NULL) 776 { 777 /* First time through, so open the relation */ 778 RangeTblEntry *rte = exec_rt_fetch(rti, estate); 779 780 Assert(rte->rtekind == RTE_RELATION); 781 782 if (!IsParallelWorker()) 783 { 784 /* 785 * In a normal query, we should already have the appropriate lock, 786 * but verify that through an Assert. Since there's already an 787 * Assert inside table_open that insists on holding some lock, it 788 * seems sufficient to check this only when rellockmode is higher 789 * than the minimum. 790 */ 791 rel = table_open(rte->relid, NoLock); 792 Assert(rte->rellockmode == AccessShareLock || 793 CheckRelationLockedByMe(rel, rte->rellockmode, false)); 794 } 795 else 796 { 797 /* 798 * If we are a parallel worker, we need to obtain our own local 799 * lock on the relation. This ensures sane behavior in case the 800 * parent process exits before we do. 801 */ 802 rel = table_open(rte->relid, rte->rellockmode); 803 } 804 805 estate->es_relations[rti - 1] = rel; 806 } 807 808 return rel; 809 } 810 811 /* 812 * UpdateChangedParamSet 813 * Add changed parameters to a plan node's chgParam set 814 */ 815 void 816 UpdateChangedParamSet(PlanState *node, Bitmapset *newchg) 817 { 818 Bitmapset *parmset; 819 820 /* 821 * The plan node only depends on params listed in its allParam set. Don't 822 * include anything else into its chgParam set. 823 */ 824 parmset = bms_intersect(node->plan->allParam, newchg); 825 826 /* 827 * Keep node->chgParam == NULL if there's not actually any members; this 828 * allows the simplest possible tests in executor node files. 829 */ 830 if (!bms_is_empty(parmset)) 831 node->chgParam = bms_join(node->chgParam, parmset); 832 else 833 bms_free(parmset); 834 } 835 836 /* 837 * executor_errposition 838 * Report an execution-time cursor position, if possible. 839 * 840 * This is expected to be used within an ereport() call. The return value 841 * is a dummy (always 0, in fact). 842 * 843 * The locations stored in parsetrees are byte offsets into the source string. 844 * We have to convert them to 1-based character indexes for reporting to 845 * clients. (We do things this way to avoid unnecessary overhead in the 846 * normal non-error case: computing character indexes would be much more 847 * expensive than storing token offsets.) 848 */ 849 int 850 executor_errposition(EState *estate, int location) 851 { 852 int pos; 853 854 /* No-op if location was not provided */ 855 if (location < 0) 856 return 0; 857 /* Can't do anything if source text is not available */ 858 if (estate == NULL || estate->es_sourceText == NULL) 859 return 0; 860 /* Convert offset to character number */ 861 pos = pg_mbstrlen_with_len(estate->es_sourceText, location) + 1; 862 /* And pass it to the ereport mechanism */ 863 return errposition(pos); 864 } 865 866 /* 867 * Register a shutdown callback in an ExprContext. 868 * 869 * Shutdown callbacks will be called (in reverse order of registration) 870 * when the ExprContext is deleted or rescanned. This provides a hook 871 * for functions called in the context to do any cleanup needed --- it's 872 * particularly useful for functions returning sets. Note that the 873 * callback will *not* be called in the event that execution is aborted 874 * by an error. 875 */ 876 void 877 RegisterExprContextCallback(ExprContext *econtext, 878 ExprContextCallbackFunction function, 879 Datum arg) 880 { 881 ExprContext_CB *ecxt_callback; 882 883 /* Save the info in appropriate memory context */ 884 ecxt_callback = (ExprContext_CB *) 885 MemoryContextAlloc(econtext->ecxt_per_query_memory, 886 sizeof(ExprContext_CB)); 887 888 ecxt_callback->function = function; 889 ecxt_callback->arg = arg; 890 891 /* link to front of list for appropriate execution order */ 892 ecxt_callback->next = econtext->ecxt_callbacks; 893 econtext->ecxt_callbacks = ecxt_callback; 894 } 895 896 /* 897 * Deregister a shutdown callback in an ExprContext. 898 * 899 * Any list entries matching the function and arg will be removed. 900 * This can be used if it's no longer necessary to call the callback. 901 */ 902 void 903 UnregisterExprContextCallback(ExprContext *econtext, 904 ExprContextCallbackFunction function, 905 Datum arg) 906 { 907 ExprContext_CB **prev_callback; 908 ExprContext_CB *ecxt_callback; 909 910 prev_callback = &econtext->ecxt_callbacks; 911 912 while ((ecxt_callback = *prev_callback) != NULL) 913 { 914 if (ecxt_callback->function == function && ecxt_callback->arg == arg) 915 { 916 *prev_callback = ecxt_callback->next; 917 pfree(ecxt_callback); 918 } 919 else 920 prev_callback = &ecxt_callback->next; 921 } 922 } 923 924 /* 925 * Call all the shutdown callbacks registered in an ExprContext. 926 * 927 * The callback list is emptied (important in case this is only a rescan 928 * reset, and not deletion of the ExprContext). 929 * 930 * If isCommit is false, just clean the callback list but don't call 'em. 931 * (See comment for FreeExprContext.) 932 */ 933 static void 934 ShutdownExprContext(ExprContext *econtext, bool isCommit) 935 { 936 ExprContext_CB *ecxt_callback; 937 MemoryContext oldcontext; 938 939 /* Fast path in normal case where there's nothing to do. */ 940 if (econtext->ecxt_callbacks == NULL) 941 return; 942 943 /* 944 * Call the callbacks in econtext's per-tuple context. This ensures that 945 * any memory they might leak will get cleaned up. 946 */ 947 oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory); 948 949 /* 950 * Call each callback function in reverse registration order. 951 */ 952 while ((ecxt_callback = econtext->ecxt_callbacks) != NULL) 953 { 954 econtext->ecxt_callbacks = ecxt_callback->next; 955 if (isCommit) 956 ecxt_callback->function(ecxt_callback->arg); 957 pfree(ecxt_callback); 958 } 959 960 MemoryContextSwitchTo(oldcontext); 961 } 962 963 /* 964 * GetAttributeByName 965 * GetAttributeByNum 966 * 967 * These functions return the value of the requested attribute 968 * out of the given tuple Datum. 969 * C functions which take a tuple as an argument are expected 970 * to use these. Ex: overpaid(EMP) might call GetAttributeByNum(). 971 * Note: these are actually rather slow because they do a typcache 972 * lookup on each call. 973 */ 974 Datum 975 GetAttributeByName(HeapTupleHeader tuple, const char *attname, bool *isNull) 976 { 977 AttrNumber attrno; 978 Datum result; 979 Oid tupType; 980 int32 tupTypmod; 981 TupleDesc tupDesc; 982 HeapTupleData tmptup; 983 int i; 984 985 if (attname == NULL) 986 elog(ERROR, "invalid attribute name"); 987 988 if (isNull == NULL) 989 elog(ERROR, "a NULL isNull pointer was passed"); 990 991 if (tuple == NULL) 992 { 993 /* Kinda bogus but compatible with old behavior... */ 994 *isNull = true; 995 return (Datum) 0; 996 } 997 998 tupType = HeapTupleHeaderGetTypeId(tuple); 999 tupTypmod = HeapTupleHeaderGetTypMod(tuple); 1000 tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod); 1001 1002 attrno = InvalidAttrNumber; 1003 for (i = 0; i < tupDesc->natts; i++) 1004 { 1005 Form_pg_attribute att = TupleDescAttr(tupDesc, i); 1006 1007 if (namestrcmp(&(att->attname), attname) == 0) 1008 { 1009 attrno = att->attnum; 1010 break; 1011 } 1012 } 1013 1014 if (attrno == InvalidAttrNumber) 1015 elog(ERROR, "attribute \"%s\" does not exist", attname); 1016 1017 /* 1018 * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all 1019 * the fields in the struct just in case user tries to inspect system 1020 * columns. 1021 */ 1022 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple); 1023 ItemPointerSetInvalid(&(tmptup.t_self)); 1024 tmptup.t_tableOid = InvalidOid; 1025 tmptup.t_data = tuple; 1026 1027 result = heap_getattr(&tmptup, 1028 attrno, 1029 tupDesc, 1030 isNull); 1031 1032 ReleaseTupleDesc(tupDesc); 1033 1034 return result; 1035 } 1036 1037 Datum 1038 GetAttributeByNum(HeapTupleHeader tuple, 1039 AttrNumber attrno, 1040 bool *isNull) 1041 { 1042 Datum result; 1043 Oid tupType; 1044 int32 tupTypmod; 1045 TupleDesc tupDesc; 1046 HeapTupleData tmptup; 1047 1048 if (!AttributeNumberIsValid(attrno)) 1049 elog(ERROR, "invalid attribute number %d", attrno); 1050 1051 if (isNull == NULL) 1052 elog(ERROR, "a NULL isNull pointer was passed"); 1053 1054 if (tuple == NULL) 1055 { 1056 /* Kinda bogus but compatible with old behavior... */ 1057 *isNull = true; 1058 return (Datum) 0; 1059 } 1060 1061 tupType = HeapTupleHeaderGetTypeId(tuple); 1062 tupTypmod = HeapTupleHeaderGetTypMod(tuple); 1063 tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod); 1064 1065 /* 1066 * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all 1067 * the fields in the struct just in case user tries to inspect system 1068 * columns. 1069 */ 1070 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple); 1071 ItemPointerSetInvalid(&(tmptup.t_self)); 1072 tmptup.t_tableOid = InvalidOid; 1073 tmptup.t_data = tuple; 1074 1075 result = heap_getattr(&tmptup, 1076 attrno, 1077 tupDesc, 1078 isNull); 1079 1080 ReleaseTupleDesc(tupDesc); 1081 1082 return result; 1083 } 1084 1085 /* 1086 * Number of items in a tlist (including any resjunk items!) 1087 */ 1088 int 1089 ExecTargetListLength(List *targetlist) 1090 { 1091 /* This used to be more complex, but fjoins are dead */ 1092 return list_length(targetlist); 1093 } 1094 1095 /* 1096 * Number of items in a tlist, not including any resjunk items 1097 */ 1098 int 1099 ExecCleanTargetListLength(List *targetlist) 1100 { 1101 int len = 0; 1102 ListCell *tl; 1103 1104 foreach(tl, targetlist) 1105 { 1106 TargetEntry *curTle = lfirst_node(TargetEntry, tl); 1107 1108 if (!curTle->resjunk) 1109 len++; 1110 } 1111 return len; 1112 } 1113 1114 /* 1115 * Return a relInfo's tuple slot for a trigger's OLD tuples. 1116 */ 1117 TupleTableSlot * 1118 ExecGetTriggerOldSlot(EState *estate, ResultRelInfo *relInfo) 1119 { 1120 if (relInfo->ri_TrigOldSlot == NULL) 1121 { 1122 Relation rel = relInfo->ri_RelationDesc; 1123 MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt); 1124 1125 relInfo->ri_TrigOldSlot = 1126 ExecInitExtraTupleSlot(estate, 1127 RelationGetDescr(rel), 1128 table_slot_callbacks(rel)); 1129 1130 MemoryContextSwitchTo(oldcontext); 1131 } 1132 1133 return relInfo->ri_TrigOldSlot; 1134 } 1135 1136 /* 1137 * Return a relInfo's tuple slot for a trigger's NEW tuples. 1138 */ 1139 TupleTableSlot * 1140 ExecGetTriggerNewSlot(EState *estate, ResultRelInfo *relInfo) 1141 { 1142 if (relInfo->ri_TrigNewSlot == NULL) 1143 { 1144 Relation rel = relInfo->ri_RelationDesc; 1145 MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt); 1146 1147 relInfo->ri_TrigNewSlot = 1148 ExecInitExtraTupleSlot(estate, 1149 RelationGetDescr(rel), 1150 table_slot_callbacks(rel)); 1151 1152 MemoryContextSwitchTo(oldcontext); 1153 } 1154 1155 return relInfo->ri_TrigNewSlot; 1156 } 1157 1158 /* 1159 * Return a relInfo's tuple slot for processing returning tuples. 1160 */ 1161 TupleTableSlot * 1162 ExecGetReturningSlot(EState *estate, ResultRelInfo *relInfo) 1163 { 1164 if (relInfo->ri_ReturningSlot == NULL) 1165 { 1166 Relation rel = relInfo->ri_RelationDesc; 1167 MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt); 1168 1169 relInfo->ri_ReturningSlot = 1170 ExecInitExtraTupleSlot(estate, 1171 RelationGetDescr(rel), 1172 table_slot_callbacks(rel)); 1173 1174 MemoryContextSwitchTo(oldcontext); 1175 } 1176 1177 return relInfo->ri_ReturningSlot; 1178 } 1179 1180 /* Return a bitmap representing columns being inserted */ 1181 Bitmapset * 1182 ExecGetInsertedCols(ResultRelInfo *relinfo, EState *estate) 1183 { 1184 /* 1185 * The columns are stored in the range table entry. If this ResultRelInfo 1186 * represents a partition routing target, and doesn't have an entry of its 1187 * own in the range table, fetch the parent's RTE and map the columns to 1188 * the order they are in the partition. 1189 */ 1190 if (relinfo->ri_RangeTableIndex != 0) 1191 { 1192 RangeTblEntry *rte = exec_rt_fetch(relinfo->ri_RangeTableIndex, estate); 1193 1194 return rte->insertedCols; 1195 } 1196 else if (relinfo->ri_RootResultRelInfo) 1197 { 1198 ResultRelInfo *rootRelInfo = relinfo->ri_RootResultRelInfo; 1199 RangeTblEntry *rte = exec_rt_fetch(rootRelInfo->ri_RangeTableIndex, estate); 1200 PartitionRoutingInfo *partrouteinfo = relinfo->ri_PartitionInfo; 1201 1202 if (partrouteinfo->pi_RootToPartitionMap != NULL) 1203 return execute_attr_map_cols(rte->insertedCols, 1204 partrouteinfo->pi_RootToPartitionMap); 1205 else 1206 return rte->insertedCols; 1207 } 1208 else 1209 { 1210 /* 1211 * The relation isn't in the range table and it isn't a partition 1212 * routing target. This ResultRelInfo must've been created only for 1213 * firing triggers and the relation is not being inserted into. (See 1214 * ExecGetTriggerResultRel.) 1215 */ 1216 return NULL; 1217 } 1218 } 1219 1220 /* Return a bitmap representing columns being updated */ 1221 Bitmapset * 1222 ExecGetUpdatedCols(ResultRelInfo *relinfo, EState *estate) 1223 { 1224 /* see ExecGetInsertedCols() */ 1225 if (relinfo->ri_RangeTableIndex != 0) 1226 { 1227 RangeTblEntry *rte = exec_rt_fetch(relinfo->ri_RangeTableIndex, estate); 1228 1229 return rte->updatedCols; 1230 } 1231 else if (relinfo->ri_RootResultRelInfo) 1232 { 1233 ResultRelInfo *rootRelInfo = relinfo->ri_RootResultRelInfo; 1234 RangeTblEntry *rte = exec_rt_fetch(rootRelInfo->ri_RangeTableIndex, estate); 1235 PartitionRoutingInfo *partrouteinfo = relinfo->ri_PartitionInfo; 1236 1237 if (partrouteinfo->pi_RootToPartitionMap != NULL) 1238 return execute_attr_map_cols(rte->updatedCols, 1239 partrouteinfo->pi_RootToPartitionMap); 1240 else 1241 return rte->updatedCols; 1242 } 1243 else 1244 return NULL; 1245 } 1246 1247 /* Return a bitmap representing generated columns being updated */ 1248 Bitmapset * 1249 ExecGetExtraUpdatedCols(ResultRelInfo *relinfo, EState *estate) 1250 { 1251 /* see ExecGetInsertedCols() */ 1252 if (relinfo->ri_RangeTableIndex != 0) 1253 { 1254 RangeTblEntry *rte = exec_rt_fetch(relinfo->ri_RangeTableIndex, estate); 1255 1256 return rte->extraUpdatedCols; 1257 } 1258 else if (relinfo->ri_RootResultRelInfo) 1259 { 1260 ResultRelInfo *rootRelInfo = relinfo->ri_RootResultRelInfo; 1261 RangeTblEntry *rte = exec_rt_fetch(rootRelInfo->ri_RangeTableIndex, estate); 1262 PartitionRoutingInfo *partrouteinfo = relinfo->ri_PartitionInfo; 1263 1264 if (partrouteinfo->pi_RootToPartitionMap != NULL) 1265 return execute_attr_map_cols(rte->extraUpdatedCols, 1266 partrouteinfo->pi_RootToPartitionMap); 1267 else 1268 return rte->extraUpdatedCols; 1269 } 1270 else 1271 return NULL; 1272 } 1273 1274 /* Return columns being updated, including generated columns */ 1275 Bitmapset * 1276 ExecGetAllUpdatedCols(ResultRelInfo *relinfo, EState *estate) 1277 { 1278 return bms_union(ExecGetUpdatedCols(relinfo, estate), 1279 ExecGetExtraUpdatedCols(relinfo, estate)); 1280 } 1281