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