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