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