PostgreSQL Source Code  git master
execMain.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * execMain.c
4  * top level executor interface routines
5  *
6  * INTERFACE ROUTINES
7  * ExecutorStart()
8  * ExecutorRun()
9  * ExecutorFinish()
10  * ExecutorEnd()
11  *
12  * These four procedures are the external interface to the executor.
13  * In each case, the query descriptor is required as an argument.
14  *
15  * ExecutorStart must be called at the beginning of execution of any
16  * query plan and ExecutorEnd must always be called at the end of
17  * execution of a plan (unless it is aborted due to error).
18  *
19  * ExecutorRun accepts direction and count arguments that specify whether
20  * the plan is to be executed forwards, backwards, and for how many tuples.
21  * In some cases ExecutorRun may be called multiple times to process all
22  * the tuples for a plan. It is also acceptable to stop short of executing
23  * the whole plan (but only if it is a SELECT).
24  *
25  * ExecutorFinish must be called after the final ExecutorRun call and
26  * before ExecutorEnd. This can be omitted only in case of EXPLAIN,
27  * which should also omit ExecutorRun.
28  *
29  * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
30  * Portions Copyright (c) 1994, Regents of the University of California
31  *
32  *
33  * IDENTIFICATION
34  * src/backend/executor/execMain.c
35  *
36  *-------------------------------------------------------------------------
37  */
38 #include "postgres.h"
39 
40 #include "access/heapam.h"
41 #include "access/htup_details.h"
42 #include "access/sysattr.h"
43 #include "access/tableam.h"
44 #include "access/transam.h"
45 #include "access/xact.h"
46 #include "catalog/namespace.h"
47 #include "catalog/pg_publication.h"
48 #include "commands/matview.h"
49 #include "commands/trigger.h"
50 #include "executor/execdebug.h"
51 #include "executor/nodeSubplan.h"
52 #include "foreign/fdwapi.h"
53 #include "jit/jit.h"
54 #include "mb/pg_wchar.h"
55 #include "miscadmin.h"
56 #include "parser/parsetree.h"
57 #include "storage/bufmgr.h"
58 #include "storage/lmgr.h"
59 #include "tcop/utility.h"
60 #include "utils/acl.h"
61 #include "utils/backend_status.h"
62 #include "utils/lsyscache.h"
63 #include "utils/memutils.h"
64 #include "utils/partcache.h"
65 #include "utils/rls.h"
66 #include "utils/ruleutils.h"
67 #include "utils/snapmgr.h"
68 
69 
70 /* Hooks for plugins to get control in ExecutorStart/Run/Finish/End */
75 
76 /* Hook for plugin to get control in ExecCheckRTPerms() */
78 
79 /* decls for local routines only used within this module */
80 static void InitPlan(QueryDesc *queryDesc, int eflags);
81 static void CheckValidRowMarkRel(Relation rel, RowMarkType markType);
82 static void ExecPostprocessPlan(EState *estate);
83 static void ExecEndPlan(PlanState *planstate, EState *estate);
84 static void ExecutePlan(EState *estate, PlanState *planstate,
85  bool use_parallel_mode,
86  CmdType operation,
87  bool sendTuples,
88  uint64 numberTuples,
89  ScanDirection direction,
91  bool execute_once);
92 static bool ExecCheckRTEPerms(RangeTblEntry *rte);
93 static bool ExecCheckRTEPermsModified(Oid relOid, Oid userid,
94  Bitmapset *modifiedCols,
95  AclMode requiredPerms);
96 static void ExecCheckXactReadOnly(PlannedStmt *plannedstmt);
97 static char *ExecBuildSlotValueDescription(Oid reloid,
98  TupleTableSlot *slot,
100  Bitmapset *modifiedCols,
101  int maxfieldlen);
102 static void EvalPlanQualStart(EPQState *epqstate, Plan *planTree);
103 
104 /* end of local decls */
105 
106 
107 /* ----------------------------------------------------------------
108  * ExecutorStart
109  *
110  * This routine must be called at the beginning of any execution of any
111  * query plan
112  *
113  * Takes a QueryDesc previously created by CreateQueryDesc (which is separate
114  * only because some places use QueryDescs for utility commands). The tupDesc
115  * field of the QueryDesc is filled in to describe the tuples that will be
116  * returned, and the internal fields (estate and planstate) are set up.
117  *
118  * eflags contains flag bits as described in executor.h.
119  *
120  * NB: the CurrentMemoryContext when this is called will become the parent
121  * of the per-query context used for this Executor invocation.
122  *
123  * We provide a function hook variable that lets loadable plugins
124  * get control when ExecutorStart is called. Such a plugin would
125  * normally call standard_ExecutorStart().
126  *
127  * ----------------------------------------------------------------
128  */
129 void
130 ExecutorStart(QueryDesc *queryDesc, int eflags)
131 {
132  /*
133  * In some cases (e.g. an EXECUTE statement) a query execution will skip
134  * parse analysis, which means that the query_id won't be reported. Note
135  * that it's harmless to report the query_id multiple time, as the call
136  * will be ignored if the top level query_id has already been reported.
137  */
138  pgstat_report_query_id(queryDesc->plannedstmt->queryId, false);
139 
140  if (ExecutorStart_hook)
141  (*ExecutorStart_hook) (queryDesc, eflags);
142  else
143  standard_ExecutorStart(queryDesc, eflags);
144 }
145 
146 void
147 standard_ExecutorStart(QueryDesc *queryDesc, int eflags)
148 {
149  EState *estate;
150  MemoryContext oldcontext;
151 
152  /* sanity checks: queryDesc must not be started already */
153  Assert(queryDesc != NULL);
154  Assert(queryDesc->estate == NULL);
155 
156  /*
157  * If the transaction is read-only, we need to check if any writes are
158  * planned to non-temporary tables. EXPLAIN is considered read-only.
159  *
160  * Don't allow writes in parallel mode. Supporting UPDATE and DELETE
161  * would require (a) storing the combo CID hash in shared memory, rather
162  * than synchronizing it just once at the start of parallelism, and (b) an
163  * alternative to heap_update()'s reliance on xmax for mutual exclusion.
164  * INSERT may have no such troubles, but we forbid it to simplify the
165  * checks.
166  *
167  * We have lower-level defenses in CommandCounterIncrement and elsewhere
168  * against performing unsafe operations in parallel mode, but this gives a
169  * more user-friendly error message.
170  */
171  if ((XactReadOnly || IsInParallelMode()) &&
172  !(eflags & EXEC_FLAG_EXPLAIN_ONLY))
174 
175  /*
176  * Build EState, switch into per-query memory context for startup.
177  */
178  estate = CreateExecutorState();
179  queryDesc->estate = estate;
180 
181  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
182 
183  /*
184  * Fill in external parameters, if any, from queryDesc; and allocate
185  * workspace for internal parameters
186  */
187  estate->es_param_list_info = queryDesc->params;
188 
189  if (queryDesc->plannedstmt->paramExecTypes != NIL)
190  {
191  int nParamExec;
192 
193  nParamExec = list_length(queryDesc->plannedstmt->paramExecTypes);
194  estate->es_param_exec_vals = (ParamExecData *)
195  palloc0(nParamExec * sizeof(ParamExecData));
196  }
197 
198  /* We now require all callers to provide sourceText */
199  Assert(queryDesc->sourceText != NULL);
200  estate->es_sourceText = queryDesc->sourceText;
201 
202  /*
203  * Fill in the query environment, if any, from queryDesc.
204  */
205  estate->es_queryEnv = queryDesc->queryEnv;
206 
207  /*
208  * If non-read-only query, set the command ID to mark output tuples with
209  */
210  switch (queryDesc->operation)
211  {
212  case CMD_SELECT:
213 
214  /*
215  * SELECT FOR [KEY] UPDATE/SHARE and modifying CTEs need to mark
216  * tuples
217  */
218  if (queryDesc->plannedstmt->rowMarks != NIL ||
219  queryDesc->plannedstmt->hasModifyingCTE)
220  estate->es_output_cid = GetCurrentCommandId(true);
221 
222  /*
223  * A SELECT without modifying CTEs can't possibly queue triggers,
224  * so force skip-triggers mode. This is just a marginal efficiency
225  * hack, since AfterTriggerBeginQuery/AfterTriggerEndQuery aren't
226  * all that expensive, but we might as well do it.
227  */
228  if (!queryDesc->plannedstmt->hasModifyingCTE)
229  eflags |= EXEC_FLAG_SKIP_TRIGGERS;
230  break;
231 
232  case CMD_INSERT:
233  case CMD_DELETE:
234  case CMD_UPDATE:
235  estate->es_output_cid = GetCurrentCommandId(true);
236  break;
237 
238  default:
239  elog(ERROR, "unrecognized operation code: %d",
240  (int) queryDesc->operation);
241  break;
242  }
243 
244  /*
245  * Copy other important information into the EState
246  */
247  estate->es_snapshot = RegisterSnapshot(queryDesc->snapshot);
249  estate->es_top_eflags = eflags;
250  estate->es_instrument = queryDesc->instrument_options;
251  estate->es_jit_flags = queryDesc->plannedstmt->jitFlags;
252 
253  /*
254  * Set up an AFTER-trigger statement context, unless told not to, or
255  * unless it's EXPLAIN-only mode (when ExecutorFinish won't be called).
256  */
257  if (!(eflags & (EXEC_FLAG_SKIP_TRIGGERS | EXEC_FLAG_EXPLAIN_ONLY)))
259 
260  /*
261  * Initialize the plan state tree
262  */
263  InitPlan(queryDesc, eflags);
264 
265  MemoryContextSwitchTo(oldcontext);
266 }
267 
268 /* ----------------------------------------------------------------
269  * ExecutorRun
270  *
271  * This is the main routine of the executor module. It accepts
272  * the query descriptor from the traffic cop and executes the
273  * query plan.
274  *
275  * ExecutorStart must have been called already.
276  *
277  * If direction is NoMovementScanDirection then nothing is done
278  * except to start up/shut down the destination. Otherwise,
279  * we retrieve up to 'count' tuples in the specified direction.
280  *
281  * Note: count = 0 is interpreted as no portal limit, i.e., run to
282  * completion. Also note that the count limit is only applied to
283  * retrieved tuples, not for instance to those inserted/updated/deleted
284  * by a ModifyTable plan node.
285  *
286  * There is no return value, but output tuples (if any) are sent to
287  * the destination receiver specified in the QueryDesc; and the number
288  * of tuples processed at the top level can be found in
289  * estate->es_processed.
290  *
291  * We provide a function hook variable that lets loadable plugins
292  * get control when ExecutorRun is called. Such a plugin would
293  * normally call standard_ExecutorRun().
294  *
295  * ----------------------------------------------------------------
296  */
297 void
299  ScanDirection direction, uint64 count,
300  bool execute_once)
301 {
302  if (ExecutorRun_hook)
303  (*ExecutorRun_hook) (queryDesc, direction, count, execute_once);
304  else
305  standard_ExecutorRun(queryDesc, direction, count, execute_once);
306 }
307 
308 void
310  ScanDirection direction, uint64 count, bool execute_once)
311 {
312  EState *estate;
313  CmdType operation;
315  bool sendTuples;
316  MemoryContext oldcontext;
317 
318  /* sanity checks */
319  Assert(queryDesc != NULL);
320 
321  estate = queryDesc->estate;
322 
323  Assert(estate != NULL);
325 
326  /*
327  * Switch into per-query memory context
328  */
329  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
330 
331  /* Allow instrumentation of Executor overall runtime */
332  if (queryDesc->totaltime)
333  InstrStartNode(queryDesc->totaltime);
334 
335  /*
336  * extract information from the query descriptor and the query feature.
337  */
338  operation = queryDesc->operation;
339  dest = queryDesc->dest;
340 
341  /*
342  * startup tuple receiver, if we will be emitting tuples
343  */
344  estate->es_processed = 0;
345 
346  sendTuples = (operation == CMD_SELECT ||
347  queryDesc->plannedstmt->hasReturning);
348 
349  if (sendTuples)
350  dest->rStartup(dest, operation, queryDesc->tupDesc);
351 
352  /*
353  * run plan
354  */
355  if (!ScanDirectionIsNoMovement(direction))
356  {
357  if (execute_once && queryDesc->already_executed)
358  elog(ERROR, "can't re-execute query flagged for single execution");
359  queryDesc->already_executed = true;
360 
361  ExecutePlan(estate,
362  queryDesc->planstate,
363  queryDesc->plannedstmt->parallelModeNeeded,
364  operation,
365  sendTuples,
366  count,
367  direction,
368  dest,
369  execute_once);
370  }
371 
372  /*
373  * shutdown tuple receiver, if we started it
374  */
375  if (sendTuples)
376  dest->rShutdown(dest);
377 
378  if (queryDesc->totaltime)
379  InstrStopNode(queryDesc->totaltime, estate->es_processed);
380 
381  MemoryContextSwitchTo(oldcontext);
382 }
383 
384 /* ----------------------------------------------------------------
385  * ExecutorFinish
386  *
387  * This routine must be called after the last ExecutorRun call.
388  * It performs cleanup such as firing AFTER triggers. It is
389  * separate from ExecutorEnd because EXPLAIN ANALYZE needs to
390  * include these actions in the total runtime.
391  *
392  * We provide a function hook variable that lets loadable plugins
393  * get control when ExecutorFinish is called. Such a plugin would
394  * normally call standard_ExecutorFinish().
395  *
396  * ----------------------------------------------------------------
397  */
398 void
400 {
402  (*ExecutorFinish_hook) (queryDesc);
403  else
404  standard_ExecutorFinish(queryDesc);
405 }
406 
407 void
409 {
410  EState *estate;
411  MemoryContext oldcontext;
412 
413  /* sanity checks */
414  Assert(queryDesc != NULL);
415 
416  estate = queryDesc->estate;
417 
418  Assert(estate != NULL);
420 
421  /* This should be run once and only once per Executor instance */
422  Assert(!estate->es_finished);
423 
424  /* Switch into per-query memory context */
425  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
426 
427  /* Allow instrumentation of Executor overall runtime */
428  if (queryDesc->totaltime)
429  InstrStartNode(queryDesc->totaltime);
430 
431  /* Run ModifyTable nodes to completion */
432  ExecPostprocessPlan(estate);
433 
434  /* Execute queued AFTER triggers, unless told not to */
435  if (!(estate->es_top_eflags & EXEC_FLAG_SKIP_TRIGGERS))
436  AfterTriggerEndQuery(estate);
437 
438  if (queryDesc->totaltime)
439  InstrStopNode(queryDesc->totaltime, 0);
440 
441  MemoryContextSwitchTo(oldcontext);
442 
443  estate->es_finished = true;
444 }
445 
446 /* ----------------------------------------------------------------
447  * ExecutorEnd
448  *
449  * This routine must be called at the end of execution of any
450  * query plan
451  *
452  * We provide a function hook variable that lets loadable plugins
453  * get control when ExecutorEnd is called. Such a plugin would
454  * normally call standard_ExecutorEnd().
455  *
456  * ----------------------------------------------------------------
457  */
458 void
460 {
461  if (ExecutorEnd_hook)
462  (*ExecutorEnd_hook) (queryDesc);
463  else
464  standard_ExecutorEnd(queryDesc);
465 }
466 
467 void
469 {
470  EState *estate;
471  MemoryContext oldcontext;
472 
473  /* sanity checks */
474  Assert(queryDesc != NULL);
475 
476  estate = queryDesc->estate;
477 
478  Assert(estate != NULL);
479 
480  /*
481  * Check that ExecutorFinish was called, unless in EXPLAIN-only mode. This
482  * Assert is needed because ExecutorFinish is new as of 9.1, and callers
483  * might forget to call it.
484  */
485  Assert(estate->es_finished ||
487 
488  /*
489  * Switch into per-query memory context to run ExecEndPlan
490  */
491  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
492 
493  ExecEndPlan(queryDesc->planstate, estate);
494 
495  /* do away with our snapshots */
498 
499  /*
500  * Must switch out of context before destroying it
501  */
502  MemoryContextSwitchTo(oldcontext);
503 
504  /*
505  * Release EState and per-query memory context. This should release
506  * everything the executor has allocated.
507  */
508  FreeExecutorState(estate);
509 
510  /* Reset queryDesc fields that no longer point to anything */
511  queryDesc->tupDesc = NULL;
512  queryDesc->estate = NULL;
513  queryDesc->planstate = NULL;
514  queryDesc->totaltime = NULL;
515 }
516 
517 /* ----------------------------------------------------------------
518  * ExecutorRewind
519  *
520  * This routine may be called on an open queryDesc to rewind it
521  * to the start.
522  * ----------------------------------------------------------------
523  */
524 void
526 {
527  EState *estate;
528  MemoryContext oldcontext;
529 
530  /* sanity checks */
531  Assert(queryDesc != NULL);
532 
533  estate = queryDesc->estate;
534 
535  Assert(estate != NULL);
536 
537  /* It's probably not sensible to rescan updating queries */
538  Assert(queryDesc->operation == CMD_SELECT);
539 
540  /*
541  * Switch into per-query memory context
542  */
543  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
544 
545  /*
546  * rescan plan
547  */
548  ExecReScan(queryDesc->planstate);
549 
550  MemoryContextSwitchTo(oldcontext);
551 }
552 
553 
554 /*
555  * ExecCheckRTPerms
556  * Check access permissions for all relations listed in a range table.
557  *
558  * Returns true if permissions are adequate. Otherwise, throws an appropriate
559  * error if ereport_on_violation is true, or simply returns false otherwise.
560  *
561  * Note that this does NOT address row-level security policies (aka: RLS). If
562  * rows will be returned to the user as a result of this permission check
563  * passing, then RLS also needs to be consulted (and check_enable_rls()).
564  *
565  * See rewrite/rowsecurity.c.
566  */
567 bool
568 ExecCheckRTPerms(List *rangeTable, bool ereport_on_violation)
569 {
570  ListCell *l;
571  bool result = true;
572 
573  foreach(l, rangeTable)
574  {
575  RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
576 
577  result = ExecCheckRTEPerms(rte);
578  if (!result)
579  {
580  Assert(rte->rtekind == RTE_RELATION);
581  if (ereport_on_violation)
583  get_rel_name(rte->relid));
584  return false;
585  }
586  }
587 
589  result = (*ExecutorCheckPerms_hook) (rangeTable,
590  ereport_on_violation);
591  return result;
592 }
593 
594 /*
595  * ExecCheckRTEPerms
596  * Check access permissions for a single RTE.
597  */
598 static bool
600 {
601  AclMode requiredPerms;
602  AclMode relPerms;
603  AclMode remainingPerms;
604  Oid relOid;
605  Oid userid;
606 
607  /*
608  * Only plain-relation RTEs need to be checked here. Function RTEs are
609  * checked when the function is prepared for execution. Join, subquery,
610  * and special RTEs need no checks.
611  */
612  if (rte->rtekind != RTE_RELATION)
613  return true;
614 
615  /*
616  * No work if requiredPerms is empty.
617  */
618  requiredPerms = rte->requiredPerms;
619  if (requiredPerms == 0)
620  return true;
621 
622  relOid = rte->relid;
623 
624  /*
625  * userid to check as: current user unless we have a setuid indication.
626  *
627  * Note: GetUserId() is presently fast enough that there's no harm in
628  * calling it separately for each RTE. If that stops being true, we could
629  * call it once in ExecCheckRTPerms and pass the userid down from there.
630  * But for now, no need for the extra clutter.
631  */
632  userid = rte->checkAsUser ? rte->checkAsUser : GetUserId();
633 
634  /*
635  * We must have *all* the requiredPerms bits, but some of the bits can be
636  * satisfied from column-level rather than relation-level permissions.
637  * First, remove any bits that are satisfied by relation permissions.
638  */
639  relPerms = pg_class_aclmask(relOid, userid, requiredPerms, ACLMASK_ALL);
640  remainingPerms = requiredPerms & ~relPerms;
641  if (remainingPerms != 0)
642  {
643  int col = -1;
644 
645  /*
646  * If we lack any permissions that exist only as relation permissions,
647  * we can fail straight away.
648  */
649  if (remainingPerms & ~(ACL_SELECT | ACL_INSERT | ACL_UPDATE))
650  return false;
651 
652  /*
653  * Check to see if we have the needed privileges at column level.
654  *
655  * Note: failures just report a table-level error; it would be nicer
656  * to report a column-level error if we have some but not all of the
657  * column privileges.
658  */
659  if (remainingPerms & ACL_SELECT)
660  {
661  /*
662  * When the query doesn't explicitly reference any columns (for
663  * example, SELECT COUNT(*) FROM table), allow the query if we
664  * have SELECT on any column of the rel, as per SQL spec.
665  */
666  if (bms_is_empty(rte->selectedCols))
667  {
668  if (pg_attribute_aclcheck_all(relOid, userid, ACL_SELECT,
670  return false;
671  }
672 
673  while ((col = bms_next_member(rte->selectedCols, col)) >= 0)
674  {
675  /* bit #s are offset by FirstLowInvalidHeapAttributeNumber */
677 
678  if (attno == InvalidAttrNumber)
679  {
680  /* Whole-row reference, must have priv on all cols */
681  if (pg_attribute_aclcheck_all(relOid, userid, ACL_SELECT,
683  return false;
684  }
685  else
686  {
687  if (pg_attribute_aclcheck(relOid, attno, userid,
688  ACL_SELECT) != ACLCHECK_OK)
689  return false;
690  }
691  }
692  }
693 
694  /*
695  * Basically the same for the mod columns, for both INSERT and UPDATE
696  * privilege as specified by remainingPerms.
697  */
698  if (remainingPerms & ACL_INSERT && !ExecCheckRTEPermsModified(relOid,
699  userid,
700  rte->insertedCols,
701  ACL_INSERT))
702  return false;
703 
704  if (remainingPerms & ACL_UPDATE && !ExecCheckRTEPermsModified(relOid,
705  userid,
706  rte->updatedCols,
707  ACL_UPDATE))
708  return false;
709  }
710  return true;
711 }
712 
713 /*
714  * ExecCheckRTEPermsModified
715  * Check INSERT or UPDATE access permissions for a single RTE (these
716  * are processed uniformly).
717  */
718 static bool
719 ExecCheckRTEPermsModified(Oid relOid, Oid userid, Bitmapset *modifiedCols,
720  AclMode requiredPerms)
721 {
722  int col = -1;
723 
724  /*
725  * When the query doesn't explicitly update any columns, allow the query
726  * if we have permission on any column of the rel. This is to handle
727  * SELECT FOR UPDATE as well as possible corner cases in UPDATE.
728  */
729  if (bms_is_empty(modifiedCols))
730  {
731  if (pg_attribute_aclcheck_all(relOid, userid, requiredPerms,
733  return false;
734  }
735 
736  while ((col = bms_next_member(modifiedCols, col)) >= 0)
737  {
738  /* bit #s are offset by FirstLowInvalidHeapAttributeNumber */
740 
741  if (attno == InvalidAttrNumber)
742  {
743  /* whole-row reference can't happen here */
744  elog(ERROR, "whole-row update is not implemented");
745  }
746  else
747  {
748  if (pg_attribute_aclcheck(relOid, attno, userid,
749  requiredPerms) != ACLCHECK_OK)
750  return false;
751  }
752  }
753  return true;
754 }
755 
756 /*
757  * Check that the query does not imply any writes to non-temp tables;
758  * unless we're in parallel mode, in which case don't even allow writes
759  * to temp tables.
760  *
761  * Note: in a Hot Standby this would need to reject writes to temp
762  * tables just as we do in parallel mode; but an HS standby can't have created
763  * any temp tables in the first place, so no need to check that.
764  */
765 static void
767 {
768  ListCell *l;
769 
770  /*
771  * Fail if write permissions are requested in parallel mode for table
772  * (temp or non-temp), otherwise fail for any non-temp table.
773  */
774  foreach(l, plannedstmt->rtable)
775  {
776  RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
777 
778  if (rte->rtekind != RTE_RELATION)
779  continue;
780 
781  if ((rte->requiredPerms & (~ACL_SELECT)) == 0)
782  continue;
783 
785  continue;
786 
788  }
789 
790  if (plannedstmt->commandType != CMD_SELECT || plannedstmt->hasModifyingCTE)
792 }
793 
794 
795 /* ----------------------------------------------------------------
796  * InitPlan
797  *
798  * Initializes the query plan: open files, allocate storage
799  * and start up the rule manager
800  * ----------------------------------------------------------------
801  */
802 static void
803 InitPlan(QueryDesc *queryDesc, int eflags)
804 {
805  CmdType operation = queryDesc->operation;
806  PlannedStmt *plannedstmt = queryDesc->plannedstmt;
807  Plan *plan = plannedstmt->planTree;
808  List *rangeTable = plannedstmt->rtable;
809  EState *estate = queryDesc->estate;
810  PlanState *planstate;
811  TupleDesc tupType;
812  ListCell *l;
813  int i;
814 
815  /*
816  * Do permissions checks
817  */
818  ExecCheckRTPerms(rangeTable, true);
819 
820  /*
821  * initialize the node's execution state
822  */
823  ExecInitRangeTable(estate, rangeTable);
824 
825  estate->es_plannedstmt = plannedstmt;
826 
827  /*
828  * Next, build the ExecRowMark array from the PlanRowMark(s), if any.
829  */
830  if (plannedstmt->rowMarks)
831  {
832  estate->es_rowmarks = (ExecRowMark **)
833  palloc0(estate->es_range_table_size * sizeof(ExecRowMark *));
834  foreach(l, plannedstmt->rowMarks)
835  {
836  PlanRowMark *rc = (PlanRowMark *) lfirst(l);
837  Oid relid;
838  Relation relation;
839  ExecRowMark *erm;
840 
841  /* ignore "parent" rowmarks; they are irrelevant at runtime */
842  if (rc->isParent)
843  continue;
844 
845  /* get relation's OID (will produce InvalidOid if subquery) */
846  relid = exec_rt_fetch(rc->rti, estate)->relid;
847 
848  /* open relation, if we need to access it for this mark type */
849  switch (rc->markType)
850  {
851  case ROW_MARK_EXCLUSIVE:
853  case ROW_MARK_SHARE:
854  case ROW_MARK_KEYSHARE:
855  case ROW_MARK_REFERENCE:
856  relation = ExecGetRangeTableRelation(estate, rc->rti);
857  break;
858  case ROW_MARK_COPY:
859  /* no physical table access is required */
860  relation = NULL;
861  break;
862  default:
863  elog(ERROR, "unrecognized markType: %d", rc->markType);
864  relation = NULL; /* keep compiler quiet */
865  break;
866  }
867 
868  /* Check that relation is a legal target for marking */
869  if (relation)
870  CheckValidRowMarkRel(relation, rc->markType);
871 
872  erm = (ExecRowMark *) palloc(sizeof(ExecRowMark));
873  erm->relation = relation;
874  erm->relid = relid;
875  erm->rti = rc->rti;
876  erm->prti = rc->prti;
877  erm->rowmarkId = rc->rowmarkId;
878  erm->markType = rc->markType;
879  erm->strength = rc->strength;
880  erm->waitPolicy = rc->waitPolicy;
881  erm->ermActive = false;
883  erm->ermExtra = NULL;
884 
885  Assert(erm->rti > 0 && erm->rti <= estate->es_range_table_size &&
886  estate->es_rowmarks[erm->rti - 1] == NULL);
887 
888  estate->es_rowmarks[erm->rti - 1] = erm;
889  }
890  }
891 
892  /*
893  * Initialize the executor's tuple table to empty.
894  */
895  estate->es_tupleTable = NIL;
896 
897  /* signal that this EState is not used for EPQ */
898  estate->es_epq_active = NULL;
899 
900  /*
901  * Initialize private state information for each SubPlan. We must do this
902  * before running ExecInitNode on the main query tree, since
903  * ExecInitSubPlan expects to be able to find these entries.
904  */
905  Assert(estate->es_subplanstates == NIL);
906  i = 1; /* subplan indices count from 1 */
907  foreach(l, plannedstmt->subplans)
908  {
909  Plan *subplan = (Plan *) lfirst(l);
910  PlanState *subplanstate;
911  int sp_eflags;
912 
913  /*
914  * A subplan will never need to do BACKWARD scan nor MARK/RESTORE. If
915  * it is a parameterless subplan (not initplan), we suggest that it be
916  * prepared to handle REWIND efficiently; otherwise there is no need.
917  */
918  sp_eflags = eflags
920  if (bms_is_member(i, plannedstmt->rewindPlanIDs))
921  sp_eflags |= EXEC_FLAG_REWIND;
922 
923  subplanstate = ExecInitNode(subplan, estate, sp_eflags);
924 
925  estate->es_subplanstates = lappend(estate->es_subplanstates,
926  subplanstate);
927 
928  i++;
929  }
930 
931  /*
932  * Initialize the private state information for all the nodes in the query
933  * tree. This opens files, allocates storage and leaves us ready to start
934  * processing tuples.
935  */
936  planstate = ExecInitNode(plan, estate, eflags);
937 
938  /*
939  * Get the tuple descriptor describing the type of tuples to return.
940  */
941  tupType = ExecGetResultType(planstate);
942 
943  /*
944  * Initialize the junk filter if needed. SELECT queries need a filter if
945  * there are any junk attrs in the top-level tlist.
946  */
947  if (operation == CMD_SELECT)
948  {
949  bool junk_filter_needed = false;
950  ListCell *tlist;
951 
952  foreach(tlist, plan->targetlist)
953  {
954  TargetEntry *tle = (TargetEntry *) lfirst(tlist);
955 
956  if (tle->resjunk)
957  {
958  junk_filter_needed = true;
959  break;
960  }
961  }
962 
963  if (junk_filter_needed)
964  {
965  JunkFilter *j;
966  TupleTableSlot *slot;
967 
968  slot = ExecInitExtraTupleSlot(estate, NULL, &TTSOpsVirtual);
969  j = ExecInitJunkFilter(planstate->plan->targetlist,
970  slot);
971  estate->es_junkFilter = j;
972 
973  /* Want to return the cleaned tuple type */
974  tupType = j->jf_cleanTupType;
975  }
976  }
977 
978  queryDesc->tupDesc = tupType;
979  queryDesc->planstate = planstate;
980 }
981 
982 /*
983  * Check that a proposed result relation is a legal target for the operation
984  *
985  * Generally the parser and/or planner should have noticed any such mistake
986  * already, but let's make sure.
987  *
988  * Note: when changing this function, you probably also need to look at
989  * CheckValidRowMarkRel.
990  */
991 void
992 CheckValidResultRel(ResultRelInfo *resultRelInfo, CmdType operation)
993 {
994  Relation resultRel = resultRelInfo->ri_RelationDesc;
995  TriggerDesc *trigDesc = resultRel->trigdesc;
996  FdwRoutine *fdwroutine;
997 
998  switch (resultRel->rd_rel->relkind)
999  {
1000  case RELKIND_RELATION:
1001  case RELKIND_PARTITIONED_TABLE:
1002  CheckCmdReplicaIdentity(resultRel, operation);
1003  break;
1004  case RELKIND_SEQUENCE:
1005  ereport(ERROR,
1006  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1007  errmsg("cannot change sequence \"%s\"",
1008  RelationGetRelationName(resultRel))));
1009  break;
1010  case RELKIND_TOASTVALUE:
1011  ereport(ERROR,
1012  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1013  errmsg("cannot change TOAST relation \"%s\"",
1014  RelationGetRelationName(resultRel))));
1015  break;
1016  case RELKIND_VIEW:
1017 
1018  /*
1019  * Okay only if there's a suitable INSTEAD OF trigger. Messages
1020  * here should match rewriteHandler.c's rewriteTargetView and
1021  * RewriteQuery, except that we omit errdetail because we haven't
1022  * got the information handy (and given that we really shouldn't
1023  * get here anyway, it's not worth great exertion to get).
1024  */
1025  switch (operation)
1026  {
1027  case CMD_INSERT:
1028  if (!trigDesc || !trigDesc->trig_insert_instead_row)
1029  ereport(ERROR,
1030  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1031  errmsg("cannot insert into view \"%s\"",
1032  RelationGetRelationName(resultRel)),
1033  errhint("To enable inserting into the view, provide an INSTEAD OF INSERT trigger or an unconditional ON INSERT DO INSTEAD rule.")));
1034  break;
1035  case CMD_UPDATE:
1036  if (!trigDesc || !trigDesc->trig_update_instead_row)
1037  ereport(ERROR,
1038  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1039  errmsg("cannot update view \"%s\"",
1040  RelationGetRelationName(resultRel)),
1041  errhint("To enable updating the view, provide an INSTEAD OF UPDATE trigger or an unconditional ON UPDATE DO INSTEAD rule.")));
1042  break;
1043  case CMD_DELETE:
1044  if (!trigDesc || !trigDesc->trig_delete_instead_row)
1045  ereport(ERROR,
1046  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1047  errmsg("cannot delete from view \"%s\"",
1048  RelationGetRelationName(resultRel)),
1049  errhint("To enable deleting from the view, provide an INSTEAD OF DELETE trigger or an unconditional ON DELETE DO INSTEAD rule.")));
1050  break;
1051  default:
1052  elog(ERROR, "unrecognized CmdType: %d", (int) operation);
1053  break;
1054  }
1055  break;
1056  case RELKIND_MATVIEW:
1058  ereport(ERROR,
1059  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1060  errmsg("cannot change materialized view \"%s\"",
1061  RelationGetRelationName(resultRel))));
1062  break;
1063  case RELKIND_FOREIGN_TABLE:
1064  /* Okay only if the FDW supports it */
1065  fdwroutine = resultRelInfo->ri_FdwRoutine;
1066  switch (operation)
1067  {
1068  case CMD_INSERT:
1069  if (fdwroutine->ExecForeignInsert == NULL)
1070  ereport(ERROR,
1071  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1072  errmsg("cannot insert into foreign table \"%s\"",
1073  RelationGetRelationName(resultRel))));
1074  if (fdwroutine->IsForeignRelUpdatable != NULL &&
1075  (fdwroutine->IsForeignRelUpdatable(resultRel) & (1 << CMD_INSERT)) == 0)
1076  ereport(ERROR,
1077  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1078  errmsg("foreign table \"%s\" does not allow inserts",
1079  RelationGetRelationName(resultRel))));
1080  break;
1081  case CMD_UPDATE:
1082  if (fdwroutine->ExecForeignUpdate == NULL)
1083  ereport(ERROR,
1084  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1085  errmsg("cannot update foreign table \"%s\"",
1086  RelationGetRelationName(resultRel))));
1087  if (fdwroutine->IsForeignRelUpdatable != NULL &&
1088  (fdwroutine->IsForeignRelUpdatable(resultRel) & (1 << CMD_UPDATE)) == 0)
1089  ereport(ERROR,
1090  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1091  errmsg("foreign table \"%s\" does not allow updates",
1092  RelationGetRelationName(resultRel))));
1093  break;
1094  case CMD_DELETE:
1095  if (fdwroutine->ExecForeignDelete == NULL)
1096  ereport(ERROR,
1097  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1098  errmsg("cannot delete from foreign table \"%s\"",
1099  RelationGetRelationName(resultRel))));
1100  if (fdwroutine->IsForeignRelUpdatable != NULL &&
1101  (fdwroutine->IsForeignRelUpdatable(resultRel) & (1 << CMD_DELETE)) == 0)
1102  ereport(ERROR,
1103  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1104  errmsg("foreign table \"%s\" does not allow deletes",
1105  RelationGetRelationName(resultRel))));
1106  break;
1107  default:
1108  elog(ERROR, "unrecognized CmdType: %d", (int) operation);
1109  break;
1110  }
1111  break;
1112  default:
1113  ereport(ERROR,
1114  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1115  errmsg("cannot change relation \"%s\"",
1116  RelationGetRelationName(resultRel))));
1117  break;
1118  }
1119 }
1120 
1121 /*
1122  * Check that a proposed rowmark target relation is a legal target
1123  *
1124  * In most cases parser and/or planner should have noticed this already, but
1125  * they don't cover all cases.
1126  */
1127 static void
1129 {
1130  FdwRoutine *fdwroutine;
1131 
1132  switch (rel->rd_rel->relkind)
1133  {
1134  case RELKIND_RELATION:
1135  case RELKIND_PARTITIONED_TABLE:
1136  /* OK */
1137  break;
1138  case RELKIND_SEQUENCE:
1139  /* Must disallow this because we don't vacuum sequences */
1140  ereport(ERROR,
1141  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1142  errmsg("cannot lock rows in sequence \"%s\"",
1143  RelationGetRelationName(rel))));
1144  break;
1145  case RELKIND_TOASTVALUE:
1146  /* We could allow this, but there seems no good reason to */
1147  ereport(ERROR,
1148  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1149  errmsg("cannot lock rows in TOAST relation \"%s\"",
1150  RelationGetRelationName(rel))));
1151  break;
1152  case RELKIND_VIEW:
1153  /* Should not get here; planner should have expanded the view */
1154  ereport(ERROR,
1155  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1156  errmsg("cannot lock rows in view \"%s\"",
1157  RelationGetRelationName(rel))));
1158  break;
1159  case RELKIND_MATVIEW:
1160  /* Allow referencing a matview, but not actual locking clauses */
1161  if (markType != ROW_MARK_REFERENCE)
1162  ereport(ERROR,
1163  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1164  errmsg("cannot lock rows in materialized view \"%s\"",
1165  RelationGetRelationName(rel))));
1166  break;
1167  case RELKIND_FOREIGN_TABLE:
1168  /* Okay only if the FDW supports it */
1169  fdwroutine = GetFdwRoutineForRelation(rel, false);
1170  if (fdwroutine->RefetchForeignRow == NULL)
1171  ereport(ERROR,
1172  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1173  errmsg("cannot lock rows in foreign table \"%s\"",
1174  RelationGetRelationName(rel))));
1175  break;
1176  default:
1177  ereport(ERROR,
1178  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1179  errmsg("cannot lock rows in relation \"%s\"",
1180  RelationGetRelationName(rel))));
1181  break;
1182  }
1183 }
1184 
1185 /*
1186  * Initialize ResultRelInfo data for one result relation
1187  *
1188  * Caution: before Postgres 9.1, this function included the relkind checking
1189  * that's now in CheckValidResultRel, and it also did ExecOpenIndices if
1190  * appropriate. Be sure callers cover those needs.
1191  */
1192 void
1194  Relation resultRelationDesc,
1195  Index resultRelationIndex,
1196  ResultRelInfo *partition_root_rri,
1197  int instrument_options)
1198 {
1199  MemSet(resultRelInfo, 0, sizeof(ResultRelInfo));
1200  resultRelInfo->type = T_ResultRelInfo;
1201  resultRelInfo->ri_RangeTableIndex = resultRelationIndex;
1202  resultRelInfo->ri_RelationDesc = resultRelationDesc;
1203  resultRelInfo->ri_NumIndices = 0;
1204  resultRelInfo->ri_IndexRelationDescs = NULL;
1205  resultRelInfo->ri_IndexRelationInfo = NULL;
1206  /* make a copy so as not to depend on relcache info not changing... */
1207  resultRelInfo->ri_TrigDesc = CopyTriggerDesc(resultRelationDesc->trigdesc);
1208  if (resultRelInfo->ri_TrigDesc)
1209  {
1210  int n = resultRelInfo->ri_TrigDesc->numtriggers;
1211 
1212  resultRelInfo->ri_TrigFunctions = (FmgrInfo *)
1213  palloc0(n * sizeof(FmgrInfo));
1214  resultRelInfo->ri_TrigWhenExprs = (ExprState **)
1215  palloc0(n * sizeof(ExprState *));
1216  if (instrument_options)
1217  resultRelInfo->ri_TrigInstrument = InstrAlloc(n, instrument_options, false);
1218  }
1219  else
1220  {
1221  resultRelInfo->ri_TrigFunctions = NULL;
1222  resultRelInfo->ri_TrigWhenExprs = NULL;
1223  resultRelInfo->ri_TrigInstrument = NULL;
1224  }
1225  if (resultRelationDesc->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
1226  resultRelInfo->ri_FdwRoutine = GetFdwRoutineForRelation(resultRelationDesc, true);
1227  else
1228  resultRelInfo->ri_FdwRoutine = NULL;
1229 
1230  /* The following fields are set later if needed */
1231  resultRelInfo->ri_RowIdAttNo = 0;
1232  resultRelInfo->ri_projectNew = NULL;
1233  resultRelInfo->ri_newTupleSlot = NULL;
1234  resultRelInfo->ri_oldTupleSlot = NULL;
1235  resultRelInfo->ri_projectNewInfoValid = false;
1236  resultRelInfo->ri_FdwState = NULL;
1237  resultRelInfo->ri_usesFdwDirectModify = false;
1238  resultRelInfo->ri_ConstraintExprs = NULL;
1239  resultRelInfo->ri_GeneratedExprs = NULL;
1240  resultRelInfo->ri_projectReturning = NULL;
1241  resultRelInfo->ri_onConflictArbiterIndexes = NIL;
1242  resultRelInfo->ri_onConflict = NULL;
1243  resultRelInfo->ri_ReturningSlot = NULL;
1244  resultRelInfo->ri_TrigOldSlot = NULL;
1245  resultRelInfo->ri_TrigNewSlot = NULL;
1246 
1247  /*
1248  * Only ExecInitPartitionInfo() and ExecInitPartitionDispatchInfo() pass
1249  * non-NULL partition_root_rri. For child relations that are part of the
1250  * initial query rather than being dynamically added by tuple routing,
1251  * this field is filled in ExecInitModifyTable().
1252  */
1253  resultRelInfo->ri_RootResultRelInfo = partition_root_rri;
1254  resultRelInfo->ri_RootToPartitionMap = NULL; /* set by
1255  * ExecInitRoutingInfo */
1256  resultRelInfo->ri_PartitionTupleSlot = NULL; /* ditto */
1257  resultRelInfo->ri_ChildToRootMap = NULL;
1258  resultRelInfo->ri_ChildToRootMapValid = false;
1259  resultRelInfo->ri_CopyMultiInsertBuffer = NULL;
1260 }
1261 
1262 /*
1263  * ExecGetTriggerResultRel
1264  * Get a ResultRelInfo for a trigger target relation.
1265  *
1266  * Most of the time, triggers are fired on one of the result relations of the
1267  * query, and so we can just return a member of the es_result_relations array,
1268  * or the es_tuple_routing_result_relations list (if any). (Note: in self-join
1269  * situations there might be multiple members with the same OID; if so it
1270  * doesn't matter which one we pick.)
1271  *
1272  * However, it is sometimes necessary to fire triggers on other relations;
1273  * this happens mainly when an RI update trigger queues additional triggers
1274  * on other relations, which will be processed in the context of the outer
1275  * query. For efficiency's sake, we want to have a ResultRelInfo for those
1276  * triggers too; that can avoid repeated re-opening of the relation. (It
1277  * also provides a way for EXPLAIN ANALYZE to report the runtimes of such
1278  * triggers.) So we make additional ResultRelInfo's as needed, and save them
1279  * in es_trig_target_relations.
1280  */
1281 ResultRelInfo *
1283 {
1284  ResultRelInfo *rInfo;
1285  ListCell *l;
1286  Relation rel;
1287  MemoryContext oldcontext;
1288 
1289  /* Search through the query result relations */
1290  foreach(l, estate->es_opened_result_relations)
1291  {
1292  rInfo = lfirst(l);
1293  if (RelationGetRelid(rInfo->ri_RelationDesc) == relid)
1294  return rInfo;
1295  }
1296 
1297  /*
1298  * Search through the result relations that were created during tuple
1299  * routing, if any.
1300  */
1301  foreach(l, estate->es_tuple_routing_result_relations)
1302  {
1303  rInfo = (ResultRelInfo *) lfirst(l);
1304  if (RelationGetRelid(rInfo->ri_RelationDesc) == relid)
1305  return rInfo;
1306  }
1307 
1308  /* Nope, but maybe we already made an extra ResultRelInfo for it */
1309  foreach(l, estate->es_trig_target_relations)
1310  {
1311  rInfo = (ResultRelInfo *) lfirst(l);
1312  if (RelationGetRelid(rInfo->ri_RelationDesc) == relid)
1313  return rInfo;
1314  }
1315  /* Nope, so we need a new one */
1316 
1317  /*
1318  * Open the target relation's relcache entry. We assume that an
1319  * appropriate lock is still held by the backend from whenever the trigger
1320  * event got queued, so we need take no new lock here. Also, we need not
1321  * recheck the relkind, so no need for CheckValidResultRel.
1322  */
1323  rel = table_open(relid, NoLock);
1324 
1325  /*
1326  * Make the new entry in the right context.
1327  */
1328  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1329  rInfo = makeNode(ResultRelInfo);
1330  InitResultRelInfo(rInfo,
1331  rel,
1332  0, /* dummy rangetable index */
1333  NULL,
1334  estate->es_instrument);
1335  estate->es_trig_target_relations =
1336  lappend(estate->es_trig_target_relations, rInfo);
1337  MemoryContextSwitchTo(oldcontext);
1338 
1339  /*
1340  * Currently, we don't need any index information in ResultRelInfos used
1341  * only for triggers, so no need to call ExecOpenIndices.
1342  */
1343 
1344  return rInfo;
1345 }
1346 
1347 /* ----------------------------------------------------------------
1348  * ExecPostprocessPlan
1349  *
1350  * Give plan nodes a final chance to execute before shutdown
1351  * ----------------------------------------------------------------
1352  */
1353 static void
1355 {
1356  ListCell *lc;
1357 
1358  /*
1359  * Make sure nodes run forward.
1360  */
1362 
1363  /*
1364  * Run any secondary ModifyTable nodes to completion, in case the main
1365  * query did not fetch all rows from them. (We do this to ensure that
1366  * such nodes have predictable results.)
1367  */
1368  foreach(lc, estate->es_auxmodifytables)
1369  {
1370  PlanState *ps = (PlanState *) lfirst(lc);
1371 
1372  for (;;)
1373  {
1374  TupleTableSlot *slot;
1375 
1376  /* Reset the per-output-tuple exprcontext each time */
1377  ResetPerTupleExprContext(estate);
1378 
1379  slot = ExecProcNode(ps);
1380 
1381  if (TupIsNull(slot))
1382  break;
1383  }
1384  }
1385 }
1386 
1387 /* ----------------------------------------------------------------
1388  * ExecEndPlan
1389  *
1390  * Cleans up the query plan -- closes files and frees up storage
1391  *
1392  * NOTE: we are no longer very worried about freeing storage per se
1393  * in this code; FreeExecutorState should be guaranteed to release all
1394  * memory that needs to be released. What we are worried about doing
1395  * is closing relations and dropping buffer pins. Thus, for example,
1396  * tuple tables must be cleared or dropped to ensure pins are released.
1397  * ----------------------------------------------------------------
1398  */
1399 static void
1400 ExecEndPlan(PlanState *planstate, EState *estate)
1401 {
1402  ListCell *l;
1403 
1404  /*
1405  * shut down the node-type-specific query processing
1406  */
1407  ExecEndNode(planstate);
1408 
1409  /*
1410  * for subplans too
1411  */
1412  foreach(l, estate->es_subplanstates)
1413  {
1414  PlanState *subplanstate = (PlanState *) lfirst(l);
1415 
1416  ExecEndNode(subplanstate);
1417  }
1418 
1419  /*
1420  * destroy the executor's tuple table. Actually we only care about
1421  * releasing buffer pins and tupdesc refcounts; there's no need to pfree
1422  * the TupleTableSlots, since the containing memory context is about to go
1423  * away anyway.
1424  */
1425  ExecResetTupleTable(estate->es_tupleTable, false);
1426 
1427  /*
1428  * Close any Relations that have been opened for range table entries or
1429  * result relations.
1430  */
1431  ExecCloseResultRelations(estate);
1433 }
1434 
1435 /*
1436  * Close any relations that have been opened for ResultRelInfos.
1437  */
1438 void
1440 {
1441  ListCell *l;
1442 
1443  /*
1444  * close indexes of result relation(s) if any. (Rels themselves are
1445  * closed in ExecCloseRangeTableRelations())
1446  */
1447  foreach(l, estate->es_opened_result_relations)
1448  {
1449  ResultRelInfo *resultRelInfo = lfirst(l);
1450 
1451  ExecCloseIndices(resultRelInfo);
1452  }
1453 
1454  /* Close any relations that have been opened by ExecGetTriggerResultRel(). */
1455  foreach(l, estate->es_trig_target_relations)
1456  {
1457  ResultRelInfo *resultRelInfo = (ResultRelInfo *) lfirst(l);
1458 
1459  /*
1460  * Assert this is a "dummy" ResultRelInfo, see above. Otherwise we
1461  * might be issuing a duplicate close against a Relation opened by
1462  * ExecGetRangeTableRelation.
1463  */
1464  Assert(resultRelInfo->ri_RangeTableIndex == 0);
1465 
1466  /*
1467  * Since ExecGetTriggerResultRel doesn't call ExecOpenIndices for
1468  * these rels, we needn't call ExecCloseIndices either.
1469  */
1470  Assert(resultRelInfo->ri_NumIndices == 0);
1471 
1472  table_close(resultRelInfo->ri_RelationDesc, NoLock);
1473  }
1474 }
1475 
1476 /*
1477  * Close all relations opened by ExecGetRangeTableRelation().
1478  *
1479  * We do not release any locks we might hold on those rels.
1480  */
1481 void
1483 {
1484  int i;
1485 
1486  for (i = 0; i < estate->es_range_table_size; i++)
1487  {
1488  if (estate->es_relations[i])
1489  table_close(estate->es_relations[i], NoLock);
1490  }
1491 }
1492 
1493 /* ----------------------------------------------------------------
1494  * ExecutePlan
1495  *
1496  * Processes the query plan until we have retrieved 'numberTuples' tuples,
1497  * moving in the specified direction.
1498  *
1499  * Runs to completion if numberTuples is 0
1500  *
1501  * Note: the ctid attribute is a 'junk' attribute that is removed before the
1502  * user can see it
1503  * ----------------------------------------------------------------
1504  */
1505 static void
1507  PlanState *planstate,
1508  bool use_parallel_mode,
1509  CmdType operation,
1510  bool sendTuples,
1511  uint64 numberTuples,
1512  ScanDirection direction,
1513  DestReceiver *dest,
1514  bool execute_once)
1515 {
1516  TupleTableSlot *slot;
1517  uint64 current_tuple_count;
1518 
1519  /*
1520  * initialize local variables
1521  */
1522  current_tuple_count = 0;
1523 
1524  /*
1525  * Set the direction.
1526  */
1527  estate->es_direction = direction;
1528 
1529  /*
1530  * If the plan might potentially be executed multiple times, we must force
1531  * it to run without parallelism, because we might exit early.
1532  */
1533  if (!execute_once)
1534  use_parallel_mode = false;
1535 
1536  estate->es_use_parallel_mode = use_parallel_mode;
1537  if (use_parallel_mode)
1539 
1540  /*
1541  * Loop until we've processed the proper number of tuples from the plan.
1542  */
1543  for (;;)
1544  {
1545  /* Reset the per-output-tuple exprcontext */
1546  ResetPerTupleExprContext(estate);
1547 
1548  /*
1549  * Execute the plan and obtain a tuple
1550  */
1551  slot = ExecProcNode(planstate);
1552 
1553  /*
1554  * if the tuple is null, then we assume there is nothing more to
1555  * process so we just end the loop...
1556  */
1557  if (TupIsNull(slot))
1558  break;
1559 
1560  /*
1561  * If we have a junk filter, then project a new tuple with the junk
1562  * removed.
1563  *
1564  * Store this new "clean" tuple in the junkfilter's resultSlot.
1565  * (Formerly, we stored it back over the "dirty" tuple, which is WRONG
1566  * because that tuple slot has the wrong descriptor.)
1567  */
1568  if (estate->es_junkFilter != NULL)
1569  slot = ExecFilterJunk(estate->es_junkFilter, slot);
1570 
1571  /*
1572  * If we are supposed to send the tuple somewhere, do so. (In
1573  * practice, this is probably always the case at this point.)
1574  */
1575  if (sendTuples)
1576  {
1577  /*
1578  * If we are not able to send the tuple, we assume the destination
1579  * has closed and no more tuples can be sent. If that's the case,
1580  * end the loop.
1581  */
1582  if (!dest->receiveSlot(slot, dest))
1583  break;
1584  }
1585 
1586  /*
1587  * Count tuples processed, if this is a SELECT. (For other operation
1588  * types, the ModifyTable plan node must count the appropriate
1589  * events.)
1590  */
1591  if (operation == CMD_SELECT)
1592  (estate->es_processed)++;
1593 
1594  /*
1595  * check our tuple count.. if we've processed the proper number then
1596  * quit, else loop again and process more tuples. Zero numberTuples
1597  * means no limit.
1598  */
1599  current_tuple_count++;
1600  if (numberTuples && numberTuples == current_tuple_count)
1601  break;
1602  }
1603 
1604  /*
1605  * If we know we won't need to back up, we can release resources at this
1606  * point.
1607  */
1608  if (!(estate->es_top_eflags & EXEC_FLAG_BACKWARD))
1609  (void) ExecShutdownNode(planstate);
1610 
1611  if (use_parallel_mode)
1612  ExitParallelMode();
1613 }
1614 
1615 
1616 /*
1617  * ExecRelCheck --- check that tuple meets constraints for result relation
1618  *
1619  * Returns NULL if OK, else name of failed check constraint
1620  */
1621 static const char *
1623  TupleTableSlot *slot, EState *estate)
1624 {
1625  Relation rel = resultRelInfo->ri_RelationDesc;
1626  int ncheck = rel->rd_att->constr->num_check;
1627  ConstrCheck *check = rel->rd_att->constr->check;
1628  ExprContext *econtext;
1629  MemoryContext oldContext;
1630  int i;
1631 
1632  /*
1633  * CheckConstraintFetch let this pass with only a warning, but now we
1634  * should fail rather than possibly failing to enforce an important
1635  * constraint.
1636  */
1637  if (ncheck != rel->rd_rel->relchecks)
1638  elog(ERROR, "%d pg_constraint record(s) missing for relation \"%s\"",
1639  rel->rd_rel->relchecks - ncheck, RelationGetRelationName(rel));
1640 
1641  /*
1642  * If first time through for this result relation, build expression
1643  * nodetrees for rel's constraint expressions. Keep them in the per-query
1644  * memory context so they'll survive throughout the query.
1645  */
1646  if (resultRelInfo->ri_ConstraintExprs == NULL)
1647  {
1648  oldContext = MemoryContextSwitchTo(estate->es_query_cxt);
1649  resultRelInfo->ri_ConstraintExprs =
1650  (ExprState **) palloc(ncheck * sizeof(ExprState *));
1651  for (i = 0; i < ncheck; i++)
1652  {
1653  Expr *checkconstr;
1654 
1655  checkconstr = stringToNode(check[i].ccbin);
1656  resultRelInfo->ri_ConstraintExprs[i] =
1657  ExecPrepareExpr(checkconstr, estate);
1658  }
1659  MemoryContextSwitchTo(oldContext);
1660  }
1661 
1662  /*
1663  * We will use the EState's per-tuple context for evaluating constraint
1664  * expressions (creating it if it's not already there).
1665  */
1666  econtext = GetPerTupleExprContext(estate);
1667 
1668  /* Arrange for econtext's scan tuple to be the tuple under test */
1669  econtext->ecxt_scantuple = slot;
1670 
1671  /* And evaluate the constraints */
1672  for (i = 0; i < ncheck; i++)
1673  {
1674  ExprState *checkconstr = resultRelInfo->ri_ConstraintExprs[i];
1675 
1676  /*
1677  * NOTE: SQL specifies that a NULL result from a constraint expression
1678  * is not to be treated as a failure. Therefore, use ExecCheck not
1679  * ExecQual.
1680  */
1681  if (!ExecCheck(checkconstr, econtext))
1682  return check[i].ccname;
1683  }
1684 
1685  /* NULL result means no error */
1686  return NULL;
1687 }
1688 
1689 /*
1690  * ExecPartitionCheck --- check that tuple meets the partition constraint.
1691  *
1692  * Returns true if it meets the partition constraint. If the constraint
1693  * fails and we're asked to emit an error, do so and don't return; otherwise
1694  * return false.
1695  */
1696 bool
1698  EState *estate, bool emitError)
1699 {
1700  ExprContext *econtext;
1701  bool success;
1702 
1703  /*
1704  * If first time through, build expression state tree for the partition
1705  * check expression. (In the corner case where the partition check
1706  * expression is empty, ie there's a default partition and nothing else,
1707  * we'll be fooled into executing this code each time through. But it's
1708  * pretty darn cheap in that case, so we don't worry about it.)
1709  */
1710  if (resultRelInfo->ri_PartitionCheckExpr == NULL)
1711  {
1712  /*
1713  * Ensure that the qual tree and prepared expression are in the
1714  * query-lifespan context.
1715  */
1717  List *qual = RelationGetPartitionQual(resultRelInfo->ri_RelationDesc);
1718 
1719  resultRelInfo->ri_PartitionCheckExpr = ExecPrepareCheck(qual, estate);
1720  MemoryContextSwitchTo(oldcxt);
1721  }
1722 
1723  /*
1724  * We will use the EState's per-tuple context for evaluating constraint
1725  * expressions (creating it if it's not already there).
1726  */
1727  econtext = GetPerTupleExprContext(estate);
1728 
1729  /* Arrange for econtext's scan tuple to be the tuple under test */
1730  econtext->ecxt_scantuple = slot;
1731 
1732  /*
1733  * As in case of the catalogued constraints, we treat a NULL result as
1734  * success here, not a failure.
1735  */
1736  success = ExecCheck(resultRelInfo->ri_PartitionCheckExpr, econtext);
1737 
1738  /* if asked to emit error, don't actually return on failure */
1739  if (!success && emitError)
1740  ExecPartitionCheckEmitError(resultRelInfo, slot, estate);
1741 
1742  return success;
1743 }
1744 
1745 /*
1746  * ExecPartitionCheckEmitError - Form and emit an error message after a failed
1747  * partition constraint check.
1748  */
1749 void
1751  TupleTableSlot *slot,
1752  EState *estate)
1753 {
1754  Oid root_relid;
1756  char *val_desc;
1757  Bitmapset *modifiedCols;
1758 
1759  /*
1760  * If the tuple has been routed, it's been converted to the partition's
1761  * rowtype, which might differ from the root table's. We must convert it
1762  * back to the root table's rowtype so that val_desc in the error message
1763  * matches the input tuple.
1764  */
1765  if (resultRelInfo->ri_RootResultRelInfo)
1766  {
1767  ResultRelInfo *rootrel = resultRelInfo->ri_RootResultRelInfo;
1768  TupleDesc old_tupdesc;
1769  AttrMap *map;
1770 
1771  root_relid = RelationGetRelid(rootrel->ri_RelationDesc);
1772  tupdesc = RelationGetDescr(rootrel->ri_RelationDesc);
1773 
1774  old_tupdesc = RelationGetDescr(resultRelInfo->ri_RelationDesc);
1775  /* a reverse map */
1776  map = build_attrmap_by_name_if_req(old_tupdesc, tupdesc);
1777 
1778  /*
1779  * Partition-specific slot's tupdesc can't be changed, so allocate a
1780  * new one.
1781  */
1782  if (map != NULL)
1783  slot = execute_attr_map_slot(map, slot,
1784  MakeTupleTableSlot(tupdesc, &TTSOpsVirtual));
1785  modifiedCols = bms_union(ExecGetInsertedCols(rootrel, estate),
1786  ExecGetUpdatedCols(rootrel, estate));
1787  }
1788  else
1789  {
1790  root_relid = RelationGetRelid(resultRelInfo->ri_RelationDesc);
1791  tupdesc = RelationGetDescr(resultRelInfo->ri_RelationDesc);
1792  modifiedCols = bms_union(ExecGetInsertedCols(resultRelInfo, estate),
1793  ExecGetUpdatedCols(resultRelInfo, estate));
1794  }
1795 
1796  val_desc = ExecBuildSlotValueDescription(root_relid,
1797  slot,
1798  tupdesc,
1799  modifiedCols,
1800  64);
1801  ereport(ERROR,
1802  (errcode(ERRCODE_CHECK_VIOLATION),
1803  errmsg("new row for relation \"%s\" violates partition constraint",
1804  RelationGetRelationName(resultRelInfo->ri_RelationDesc)),
1805  val_desc ? errdetail("Failing row contains %s.", val_desc) : 0,
1806  errtable(resultRelInfo->ri_RelationDesc)));
1807 }
1808 
1809 /*
1810  * ExecConstraints - check constraints of the tuple in 'slot'
1811  *
1812  * This checks the traditional NOT NULL and check constraints.
1813  *
1814  * The partition constraint is *NOT* checked.
1815  *
1816  * Note: 'slot' contains the tuple to check the constraints of, which may
1817  * have been converted from the original input tuple after tuple routing.
1818  * 'resultRelInfo' is the final result relation, after tuple routing.
1819  */
1820 void
1822  TupleTableSlot *slot, EState *estate)
1823 {
1824  Relation rel = resultRelInfo->ri_RelationDesc;
1826  TupleConstr *constr = tupdesc->constr;
1827  Bitmapset *modifiedCols;
1828 
1829  Assert(constr); /* we should not be called otherwise */
1830 
1831  if (constr->has_not_null)
1832  {
1833  int natts = tupdesc->natts;
1834  int attrChk;
1835 
1836  for (attrChk = 1; attrChk <= natts; attrChk++)
1837  {
1838  Form_pg_attribute att = TupleDescAttr(tupdesc, attrChk - 1);
1839 
1840  if (att->attnotnull && slot_attisnull(slot, attrChk))
1841  {
1842  char *val_desc;
1843  Relation orig_rel = rel;
1844  TupleDesc orig_tupdesc = RelationGetDescr(rel);
1845 
1846  /*
1847  * If the tuple has been routed, it's been converted to the
1848  * partition's rowtype, which might differ from the root
1849  * table's. We must convert it back to the root table's
1850  * rowtype so that val_desc shown error message matches the
1851  * input tuple.
1852  */
1853  if (resultRelInfo->ri_RootResultRelInfo)
1854  {
1855  ResultRelInfo *rootrel = resultRelInfo->ri_RootResultRelInfo;
1856  AttrMap *map;
1857 
1858  tupdesc = RelationGetDescr(rootrel->ri_RelationDesc);
1859  /* a reverse map */
1860  map = build_attrmap_by_name_if_req(orig_tupdesc,
1861  tupdesc);
1862 
1863  /*
1864  * Partition-specific slot's tupdesc can't be changed, so
1865  * allocate a new one.
1866  */
1867  if (map != NULL)
1868  slot = execute_attr_map_slot(map, slot,
1869  MakeTupleTableSlot(tupdesc, &TTSOpsVirtual));
1870  modifiedCols = bms_union(ExecGetInsertedCols(rootrel, estate),
1871  ExecGetUpdatedCols(rootrel, estate));
1872  rel = rootrel->ri_RelationDesc;
1873  }
1874  else
1875  modifiedCols = bms_union(ExecGetInsertedCols(resultRelInfo, estate),
1876  ExecGetUpdatedCols(resultRelInfo, estate));
1878  slot,
1879  tupdesc,
1880  modifiedCols,
1881  64);
1882 
1883  ereport(ERROR,
1884  (errcode(ERRCODE_NOT_NULL_VIOLATION),
1885  errmsg("null value in column \"%s\" of relation \"%s\" violates not-null constraint",
1886  NameStr(att->attname),
1887  RelationGetRelationName(orig_rel)),
1888  val_desc ? errdetail("Failing row contains %s.", val_desc) : 0,
1889  errtablecol(orig_rel, attrChk)));
1890  }
1891  }
1892  }
1893 
1894  if (rel->rd_rel->relchecks > 0)
1895  {
1896  const char *failed;
1897 
1898  if ((failed = ExecRelCheck(resultRelInfo, slot, estate)) != NULL)
1899  {
1900  char *val_desc;
1901  Relation orig_rel = rel;
1902 
1903  /* See the comment above. */
1904  if (resultRelInfo->ri_RootResultRelInfo)
1905  {
1906  ResultRelInfo *rootrel = resultRelInfo->ri_RootResultRelInfo;
1907  TupleDesc old_tupdesc = RelationGetDescr(rel);
1908  AttrMap *map;
1909 
1910  tupdesc = RelationGetDescr(rootrel->ri_RelationDesc);
1911  /* a reverse map */
1912  map = build_attrmap_by_name_if_req(old_tupdesc,
1913  tupdesc);
1914 
1915  /*
1916  * Partition-specific slot's tupdesc can't be changed, so
1917  * allocate a new one.
1918  */
1919  if (map != NULL)
1920  slot = execute_attr_map_slot(map, slot,
1921  MakeTupleTableSlot(tupdesc, &TTSOpsVirtual));
1922  modifiedCols = bms_union(ExecGetInsertedCols(rootrel, estate),
1923  ExecGetUpdatedCols(rootrel, estate));
1924  rel = rootrel->ri_RelationDesc;
1925  }
1926  else
1927  modifiedCols = bms_union(ExecGetInsertedCols(resultRelInfo, estate),
1928  ExecGetUpdatedCols(resultRelInfo, estate));
1930  slot,
1931  tupdesc,
1932  modifiedCols,
1933  64);
1934  ereport(ERROR,
1935  (errcode(ERRCODE_CHECK_VIOLATION),
1936  errmsg("new row for relation \"%s\" violates check constraint \"%s\"",
1937  RelationGetRelationName(orig_rel), failed),
1938  val_desc ? errdetail("Failing row contains %s.", val_desc) : 0,
1939  errtableconstraint(orig_rel, failed)));
1940  }
1941  }
1942 }
1943 
1944 /*
1945  * ExecWithCheckOptions -- check that tuple satisfies any WITH CHECK OPTIONs
1946  * of the specified kind.
1947  *
1948  * Note that this needs to be called multiple times to ensure that all kinds of
1949  * WITH CHECK OPTIONs are handled (both those from views which have the WITH
1950  * CHECK OPTION set and from row-level security policies). See ExecInsert()
1951  * and ExecUpdate().
1952  */
1953 void
1955  TupleTableSlot *slot, EState *estate)
1956 {
1957  Relation rel = resultRelInfo->ri_RelationDesc;
1959  ExprContext *econtext;
1960  ListCell *l1,
1961  *l2;
1962 
1963  /*
1964  * We will use the EState's per-tuple context for evaluating constraint
1965  * expressions (creating it if it's not already there).
1966  */
1967  econtext = GetPerTupleExprContext(estate);
1968 
1969  /* Arrange for econtext's scan tuple to be the tuple under test */
1970  econtext->ecxt_scantuple = slot;
1971 
1972  /* Check each of the constraints */
1973  forboth(l1, resultRelInfo->ri_WithCheckOptions,
1974  l2, resultRelInfo->ri_WithCheckOptionExprs)
1975  {
1976  WithCheckOption *wco = (WithCheckOption *) lfirst(l1);
1977  ExprState *wcoExpr = (ExprState *) lfirst(l2);
1978 
1979  /*
1980  * Skip any WCOs which are not the kind we are looking for at this
1981  * time.
1982  */
1983  if (wco->kind != kind)
1984  continue;
1985 
1986  /*
1987  * WITH CHECK OPTION checks are intended to ensure that the new tuple
1988  * is visible (in the case of a view) or that it passes the
1989  * 'with-check' policy (in the case of row security). If the qual
1990  * evaluates to NULL or FALSE, then the new tuple won't be included in
1991  * the view or doesn't pass the 'with-check' policy for the table.
1992  */
1993  if (!ExecQual(wcoExpr, econtext))
1994  {
1995  char *val_desc;
1996  Bitmapset *modifiedCols;
1997 
1998  switch (wco->kind)
1999  {
2000  /*
2001  * For WITH CHECK OPTIONs coming from views, we might be
2002  * able to provide the details on the row, depending on
2003  * the permissions on the relation (that is, if the user
2004  * could view it directly anyway). For RLS violations, we
2005  * don't include the data since we don't know if the user
2006  * should be able to view the tuple as that depends on the
2007  * USING policy.
2008  */
2009  case WCO_VIEW_CHECK:
2010  /* See the comment in ExecConstraints(). */
2011  if (resultRelInfo->ri_RootResultRelInfo)
2012  {
2013  ResultRelInfo *rootrel = resultRelInfo->ri_RootResultRelInfo;
2014  TupleDesc old_tupdesc = RelationGetDescr(rel);
2015  AttrMap *map;
2016 
2017  tupdesc = RelationGetDescr(rootrel->ri_RelationDesc);
2018  /* a reverse map */
2019  map = build_attrmap_by_name_if_req(old_tupdesc,
2020  tupdesc);
2021 
2022  /*
2023  * Partition-specific slot's tupdesc can't be changed,
2024  * so allocate a new one.
2025  */
2026  if (map != NULL)
2027  slot = execute_attr_map_slot(map, slot,
2028  MakeTupleTableSlot(tupdesc, &TTSOpsVirtual));
2029 
2030  modifiedCols = bms_union(ExecGetInsertedCols(rootrel, estate),
2031  ExecGetUpdatedCols(rootrel, estate));
2032  rel = rootrel->ri_RelationDesc;
2033  }
2034  else
2035  modifiedCols = bms_union(ExecGetInsertedCols(resultRelInfo, estate),
2036  ExecGetUpdatedCols(resultRelInfo, estate));
2038  slot,
2039  tupdesc,
2040  modifiedCols,
2041  64);
2042 
2043  ereport(ERROR,
2044  (errcode(ERRCODE_WITH_CHECK_OPTION_VIOLATION),
2045  errmsg("new row violates check option for view \"%s\"",
2046  wco->relname),
2047  val_desc ? errdetail("Failing row contains %s.",
2048  val_desc) : 0));
2049  break;
2050  case WCO_RLS_INSERT_CHECK:
2051  case WCO_RLS_UPDATE_CHECK:
2052  if (wco->polname != NULL)
2053  ereport(ERROR,
2054  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2055  errmsg("new row violates row-level security policy \"%s\" for table \"%s\"",
2056  wco->polname, wco->relname)));
2057  else
2058  ereport(ERROR,
2059  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2060  errmsg("new row violates row-level security policy for table \"%s\"",
2061  wco->relname)));
2062  break;
2064  if (wco->polname != NULL)
2065  ereport(ERROR,
2066  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2067  errmsg("new row violates row-level security policy \"%s\" (USING expression) for table \"%s\"",
2068  wco->polname, wco->relname)));
2069  else
2070  ereport(ERROR,
2071  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2072  errmsg("new row violates row-level security policy (USING expression) for table \"%s\"",
2073  wco->relname)));
2074  break;
2075  default:
2076  elog(ERROR, "unrecognized WCO kind: %u", wco->kind);
2077  break;
2078  }
2079  }
2080  }
2081 }
2082 
2083 /*
2084  * ExecBuildSlotValueDescription -- construct a string representing a tuple
2085  *
2086  * This is intentionally very similar to BuildIndexValueDescription, but
2087  * unlike that function, we truncate long field values (to at most maxfieldlen
2088  * bytes). That seems necessary here since heap field values could be very
2089  * long, whereas index entries typically aren't so wide.
2090  *
2091  * Also, unlike the case with index entries, we need to be prepared to ignore
2092  * dropped columns. We used to use the slot's tuple descriptor to decode the
2093  * data, but the slot's descriptor doesn't identify dropped columns, so we
2094  * now need to be passed the relation's descriptor.
2095  *
2096  * Note that, like BuildIndexValueDescription, if the user does not have
2097  * permission to view any of the columns involved, a NULL is returned. Unlike
2098  * BuildIndexValueDescription, if the user has access to view a subset of the
2099  * column involved, that subset will be returned with a key identifying which
2100  * columns they are.
2101  */
2102 static char *
2104  TupleTableSlot *slot,
2106  Bitmapset *modifiedCols,
2107  int maxfieldlen)
2108 {
2110  StringInfoData collist;
2111  bool write_comma = false;
2112  bool write_comma_collist = false;
2113  int i;
2114  AclResult aclresult;
2115  bool table_perm = false;
2116  bool any_perm = false;
2117 
2118  /*
2119  * Check if RLS is enabled and should be active for the relation; if so,
2120  * then don't return anything. Otherwise, go through normal permission
2121  * checks.
2122  */
2123  if (check_enable_rls(reloid, InvalidOid, true) == RLS_ENABLED)
2124  return NULL;
2125 
2126  initStringInfo(&buf);
2127 
2128  appendStringInfoChar(&buf, '(');
2129 
2130  /*
2131  * Check if the user has permissions to see the row. Table-level SELECT
2132  * allows access to all columns. If the user does not have table-level
2133  * SELECT then we check each column and include those the user has SELECT
2134  * rights on. Additionally, we always include columns the user provided
2135  * data for.
2136  */
2137  aclresult = pg_class_aclcheck(reloid, GetUserId(), ACL_SELECT);
2138  if (aclresult != ACLCHECK_OK)
2139  {
2140  /* Set up the buffer for the column list */
2141  initStringInfo(&collist);
2142  appendStringInfoChar(&collist, '(');
2143  }
2144  else
2145  table_perm = any_perm = true;
2146 
2147  /* Make sure the tuple is fully deconstructed */
2148  slot_getallattrs(slot);
2149 
2150  for (i = 0; i < tupdesc->natts; i++)
2151  {
2152  bool column_perm = false;
2153  char *val;
2154  int vallen;
2155  Form_pg_attribute att = TupleDescAttr(tupdesc, i);
2156 
2157  /* ignore dropped columns */
2158  if (att->attisdropped)
2159  continue;
2160 
2161  if (!table_perm)
2162  {
2163  /*
2164  * No table-level SELECT, so need to make sure they either have
2165  * SELECT rights on the column or that they have provided the data
2166  * for the column. If not, omit this column from the error
2167  * message.
2168  */
2169  aclresult = pg_attribute_aclcheck(reloid, att->attnum,
2170  GetUserId(), ACL_SELECT);
2172  modifiedCols) || aclresult == ACLCHECK_OK)
2173  {
2174  column_perm = any_perm = true;
2175 
2176  if (write_comma_collist)
2177  appendStringInfoString(&collist, ", ");
2178  else
2179  write_comma_collist = true;
2180 
2181  appendStringInfoString(&collist, NameStr(att->attname));
2182  }
2183  }
2184 
2185  if (table_perm || column_perm)
2186  {
2187  if (slot->tts_isnull[i])
2188  val = "null";
2189  else
2190  {
2191  Oid foutoid;
2192  bool typisvarlena;
2193 
2194  getTypeOutputInfo(att->atttypid,
2195  &foutoid, &typisvarlena);
2196  val = OidOutputFunctionCall(foutoid, slot->tts_values[i]);
2197  }
2198 
2199  if (write_comma)
2200  appendStringInfoString(&buf, ", ");
2201  else
2202  write_comma = true;
2203 
2204  /* truncate if needed */
2205  vallen = strlen(val);
2206  if (vallen <= maxfieldlen)
2207  appendBinaryStringInfo(&buf, val, vallen);
2208  else
2209  {
2210  vallen = pg_mbcliplen(val, vallen, maxfieldlen);
2211  appendBinaryStringInfo(&buf, val, vallen);
2212  appendStringInfoString(&buf, "...");
2213  }
2214  }
2215  }
2216 
2217  /* If we end up with zero columns being returned, then return NULL. */
2218  if (!any_perm)
2219  return NULL;
2220 
2221  appendStringInfoChar(&buf, ')');
2222 
2223  if (!table_perm)
2224  {
2225  appendStringInfoString(&collist, ") = ");
2226  appendBinaryStringInfo(&collist, buf.data, buf.len);
2227 
2228  return collist.data;
2229  }
2230 
2231  return buf.data;
2232 }
2233 
2234 
2235 /*
2236  * ExecUpdateLockMode -- find the appropriate UPDATE tuple lock mode for a
2237  * given ResultRelInfo
2238  */
2241 {
2242  Bitmapset *keyCols;
2243  Bitmapset *updatedCols;
2244 
2245  /*
2246  * Compute lock mode to use. If columns that are part of the key have not
2247  * been modified, then we can use a weaker lock, allowing for better
2248  * concurrency.
2249  */
2250  updatedCols = ExecGetAllUpdatedCols(relinfo, estate);
2251  keyCols = RelationGetIndexAttrBitmap(relinfo->ri_RelationDesc,
2253 
2254  if (bms_overlap(keyCols, updatedCols))
2255  return LockTupleExclusive;
2256 
2257  return LockTupleNoKeyExclusive;
2258 }
2259 
2260 /*
2261  * ExecFindRowMark -- find the ExecRowMark struct for given rangetable index
2262  *
2263  * If no such struct, either return NULL or throw error depending on missing_ok
2264  */
2265 ExecRowMark *
2266 ExecFindRowMark(EState *estate, Index rti, bool missing_ok)
2267 {
2268  if (rti > 0 && rti <= estate->es_range_table_size &&
2269  estate->es_rowmarks != NULL)
2270  {
2271  ExecRowMark *erm = estate->es_rowmarks[rti - 1];
2272 
2273  if (erm)
2274  return erm;
2275  }
2276  if (!missing_ok)
2277  elog(ERROR, "failed to find ExecRowMark for rangetable index %u", rti);
2278  return NULL;
2279 }
2280 
2281 /*
2282  * ExecBuildAuxRowMark -- create an ExecAuxRowMark struct
2283  *
2284  * Inputs are the underlying ExecRowMark struct and the targetlist of the
2285  * input plan node (not planstate node!). We need the latter to find out
2286  * the column numbers of the resjunk columns.
2287  */
2290 {
2291  ExecAuxRowMark *aerm = (ExecAuxRowMark *) palloc0(sizeof(ExecAuxRowMark));
2292  char resname[32];
2293 
2294  aerm->rowmark = erm;
2295 
2296  /* Look up the resjunk columns associated with this rowmark */
2297  if (erm->markType != ROW_MARK_COPY)
2298  {
2299  /* need ctid for all methods other than COPY */
2300  snprintf(resname, sizeof(resname), "ctid%u", erm->rowmarkId);
2301  aerm->ctidAttNo = ExecFindJunkAttributeInTlist(targetlist,
2302  resname);
2303  if (!AttributeNumberIsValid(aerm->ctidAttNo))
2304  elog(ERROR, "could not find junk %s column", resname);
2305  }
2306  else
2307  {
2308  /* need wholerow if COPY */
2309  snprintf(resname, sizeof(resname), "wholerow%u", erm->rowmarkId);
2310  aerm->wholeAttNo = ExecFindJunkAttributeInTlist(targetlist,
2311  resname);
2312  if (!AttributeNumberIsValid(aerm->wholeAttNo))
2313  elog(ERROR, "could not find junk %s column", resname);
2314  }
2315 
2316  /* if child rel, need tableoid */
2317  if (erm->rti != erm->prti)
2318  {
2319  snprintf(resname, sizeof(resname), "tableoid%u", erm->rowmarkId);
2320  aerm->toidAttNo = ExecFindJunkAttributeInTlist(targetlist,
2321  resname);
2322  if (!AttributeNumberIsValid(aerm->toidAttNo))
2323  elog(ERROR, "could not find junk %s column", resname);
2324  }
2325 
2326  return aerm;
2327 }
2328 
2329 
2330 /*
2331  * EvalPlanQual logic --- recheck modified tuple(s) to see if we want to
2332  * process the updated version under READ COMMITTED rules.
2333  *
2334  * See backend/executor/README for some info about how this works.
2335  */
2336 
2337 
2338 /*
2339  * Check the updated version of a tuple to see if we want to process it under
2340  * READ COMMITTED rules.
2341  *
2342  * epqstate - state for EvalPlanQual rechecking
2343  * relation - table containing tuple
2344  * rti - rangetable index of table containing tuple
2345  * inputslot - tuple for processing - this can be the slot from
2346  * EvalPlanQualSlot(), for the increased efficiency.
2347  *
2348  * This tests whether the tuple in inputslot still matches the relevant
2349  * quals. For that result to be useful, typically the input tuple has to be
2350  * last row version (otherwise the result isn't particularly useful) and
2351  * locked (otherwise the result might be out of date). That's typically
2352  * achieved by using table_tuple_lock() with the
2353  * TUPLE_LOCK_FLAG_FIND_LAST_VERSION flag.
2354  *
2355  * Returns a slot containing the new candidate update/delete tuple, or
2356  * NULL if we determine we shouldn't process the row.
2357  */
2359 EvalPlanQual(EPQState *epqstate, Relation relation,
2360  Index rti, TupleTableSlot *inputslot)
2361 {
2362  TupleTableSlot *slot;
2363  TupleTableSlot *testslot;
2364 
2365  Assert(rti > 0);
2366 
2367  /*
2368  * Need to run a recheck subquery. Initialize or reinitialize EPQ state.
2369  */
2370  EvalPlanQualBegin(epqstate);
2371 
2372  /*
2373  * Callers will often use the EvalPlanQualSlot to store the tuple to avoid
2374  * an unnecessary copy.
2375  */
2376  testslot = EvalPlanQualSlot(epqstate, relation, rti);
2377  if (testslot != inputslot)
2378  ExecCopySlot(testslot, inputslot);
2379 
2380  /*
2381  * Run the EPQ query. We assume it will return at most one tuple.
2382  */
2383  slot = EvalPlanQualNext(epqstate);
2384 
2385  /*
2386  * If we got a tuple, force the slot to materialize the tuple so that it
2387  * is not dependent on any local state in the EPQ query (in particular,
2388  * it's highly likely that the slot contains references to any pass-by-ref
2389  * datums that may be present in copyTuple). As with the next step, this
2390  * is to guard against early re-use of the EPQ query.
2391  */
2392  if (!TupIsNull(slot))
2393  ExecMaterializeSlot(slot);
2394 
2395  /*
2396  * Clear out the test tuple. This is needed in case the EPQ query is
2397  * re-used to test a tuple for a different relation. (Not clear that can
2398  * really happen, but let's be safe.)
2399  */
2400  ExecClearTuple(testslot);
2401 
2402  return slot;
2403 }
2404 
2405 /*
2406  * EvalPlanQualInit -- initialize during creation of a plan state node
2407  * that might need to invoke EPQ processing.
2408  *
2409  * Note: subplan/auxrowmarks can be NULL/NIL if they will be set later
2410  * with EvalPlanQualSetPlan.
2411  */
2412 void
2413 EvalPlanQualInit(EPQState *epqstate, EState *parentestate,
2414  Plan *subplan, List *auxrowmarks, int epqParam)
2415 {
2416  Index rtsize = parentestate->es_range_table_size;
2417 
2418  /* initialize data not changing over EPQState's lifetime */
2419  epqstate->parentestate = parentestate;
2420  epqstate->epqParam = epqParam;
2421 
2422  /*
2423  * Allocate space to reference a slot for each potential rti - do so now
2424  * rather than in EvalPlanQualBegin(), as done for other dynamically
2425  * allocated resources, so EvalPlanQualSlot() can be used to hold tuples
2426  * that *may* need EPQ later, without forcing the overhead of
2427  * EvalPlanQualBegin().
2428  */
2429  epqstate->tuple_table = NIL;
2430  epqstate->relsubs_slot = (TupleTableSlot **)
2431  palloc0(rtsize * sizeof(TupleTableSlot *));
2432 
2433  /* ... and remember data that EvalPlanQualBegin will need */
2434  epqstate->plan = subplan;
2435  epqstate->arowMarks = auxrowmarks;
2436 
2437  /* ... and mark the EPQ state inactive */
2438  epqstate->origslot = NULL;
2439  epqstate->recheckestate = NULL;
2440  epqstate->recheckplanstate = NULL;
2441  epqstate->relsubs_rowmark = NULL;
2442  epqstate->relsubs_done = NULL;
2443 }
2444 
2445 /*
2446  * EvalPlanQualSetPlan -- set or change subplan of an EPQState.
2447  *
2448  * We used to need this so that ModifyTable could deal with multiple subplans.
2449  * It could now be refactored out of existence.
2450  */
2451 void
2452 EvalPlanQualSetPlan(EPQState *epqstate, Plan *subplan, List *auxrowmarks)
2453 {
2454  /* If we have a live EPQ query, shut it down */
2455  EvalPlanQualEnd(epqstate);
2456  /* And set/change the plan pointer */
2457  epqstate->plan = subplan;
2458  /* The rowmarks depend on the plan, too */
2459  epqstate->arowMarks = auxrowmarks;
2460 }
2461 
2462 /*
2463  * Return, and create if necessary, a slot for an EPQ test tuple.
2464  *
2465  * Note this only requires EvalPlanQualInit() to have been called,
2466  * EvalPlanQualBegin() is not necessary.
2467  */
2470  Relation relation, Index rti)
2471 {
2472  TupleTableSlot **slot;
2473 
2474  Assert(relation);
2475  Assert(rti > 0 && rti <= epqstate->parentestate->es_range_table_size);
2476  slot = &epqstate->relsubs_slot[rti - 1];
2477 
2478  if (*slot == NULL)
2479  {
2480  MemoryContext oldcontext;
2481 
2482  oldcontext = MemoryContextSwitchTo(epqstate->parentestate->es_query_cxt);
2483  *slot = table_slot_create(relation, &epqstate->tuple_table);
2484  MemoryContextSwitchTo(oldcontext);
2485  }
2486 
2487  return *slot;
2488 }
2489 
2490 /*
2491  * Fetch the current row value for a non-locked relation, identified by rti,
2492  * that needs to be scanned by an EvalPlanQual operation. origslot must have
2493  * been set to contain the current result row (top-level row) that we need to
2494  * recheck. Returns true if a substitution tuple was found, false if not.
2495  */
2496 bool
2498 {
2499  ExecAuxRowMark *earm = epqstate->relsubs_rowmark[rti - 1];
2500  ExecRowMark *erm = earm->rowmark;
2501  Datum datum;
2502  bool isNull;
2503 
2504  Assert(earm != NULL);
2505  Assert(epqstate->origslot != NULL);
2506 
2508  elog(ERROR, "EvalPlanQual doesn't support locking rowmarks");
2509 
2510  /* if child rel, must check whether it produced this row */
2511  if (erm->rti != erm->prti)
2512  {
2513  Oid tableoid;
2514 
2515  datum = ExecGetJunkAttribute(epqstate->origslot,
2516  earm->toidAttNo,
2517  &isNull);
2518  /* non-locked rels could be on the inside of outer joins */
2519  if (isNull)
2520  return false;
2521 
2522  tableoid = DatumGetObjectId(datum);
2523 
2524  Assert(OidIsValid(erm->relid));
2525  if (tableoid != erm->relid)
2526  {
2527  /* this child is inactive right now */
2528  return false;
2529  }
2530  }
2531 
2532  if (erm->markType == ROW_MARK_REFERENCE)
2533  {
2534  Assert(erm->relation != NULL);
2535 
2536  /* fetch the tuple's ctid */
2537  datum = ExecGetJunkAttribute(epqstate->origslot,
2538  earm->ctidAttNo,
2539  &isNull);
2540  /* non-locked rels could be on the inside of outer joins */
2541  if (isNull)
2542  return false;
2543 
2544  /* fetch requests on foreign tables must be passed to their FDW */
2545  if (erm->relation->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
2546  {
2547  FdwRoutine *fdwroutine;
2548  bool updated = false;
2549 
2550  fdwroutine = GetFdwRoutineForRelation(erm->relation, false);
2551  /* this should have been checked already, but let's be safe */
2552  if (fdwroutine->RefetchForeignRow == NULL)
2553  ereport(ERROR,
2554  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2555  errmsg("cannot lock rows in foreign table \"%s\"",
2557 
2558  fdwroutine->RefetchForeignRow(epqstate->recheckestate,
2559  erm,
2560  datum,
2561  slot,
2562  &updated);
2563  if (TupIsNull(slot))
2564  elog(ERROR, "failed to fetch tuple for EvalPlanQual recheck");
2565 
2566  /*
2567  * Ideally we'd insist on updated == false here, but that assumes
2568  * that FDWs can track that exactly, which they might not be able
2569  * to. So just ignore the flag.
2570  */
2571  return true;
2572  }
2573  else
2574  {
2575  /* ordinary table, fetch the tuple */
2577  (ItemPointer) DatumGetPointer(datum),
2578  SnapshotAny, slot))
2579  elog(ERROR, "failed to fetch tuple for EvalPlanQual recheck");
2580  return true;
2581  }
2582  }
2583  else
2584  {
2585  Assert(erm->markType == ROW_MARK_COPY);
2586 
2587  /* fetch the whole-row Var for the relation */
2588  datum = ExecGetJunkAttribute(epqstate->origslot,
2589  earm->wholeAttNo,
2590  &isNull);
2591  /* non-locked rels could be on the inside of outer joins */
2592  if (isNull)
2593  return false;
2594 
2595  ExecStoreHeapTupleDatum(datum, slot);
2596  return true;
2597  }
2598 }
2599 
2600 /*
2601  * Fetch the next row (if any) from EvalPlanQual testing
2602  *
2603  * (In practice, there should never be more than one row...)
2604  */
2607 {
2608  MemoryContext oldcontext;
2609  TupleTableSlot *slot;
2610 
2611  oldcontext = MemoryContextSwitchTo(epqstate->recheckestate->es_query_cxt);
2612  slot = ExecProcNode(epqstate->recheckplanstate);
2613  MemoryContextSwitchTo(oldcontext);
2614 
2615  return slot;
2616 }
2617 
2618 /*
2619  * Initialize or reset an EvalPlanQual state tree
2620  */
2621 void
2623 {
2624  EState *parentestate = epqstate->parentestate;
2625  EState *recheckestate = epqstate->recheckestate;
2626 
2627  if (recheckestate == NULL)
2628  {
2629  /* First time through, so create a child EState */
2630  EvalPlanQualStart(epqstate, epqstate->plan);
2631  }
2632  else
2633  {
2634  /*
2635  * We already have a suitable child EPQ tree, so just reset it.
2636  */
2637  Index rtsize = parentestate->es_range_table_size;
2638  PlanState *rcplanstate = epqstate->recheckplanstate;
2639 
2640  MemSet(epqstate->relsubs_done, 0, rtsize * sizeof(bool));
2641 
2642  /* Recopy current values of parent parameters */
2643  if (parentestate->es_plannedstmt->paramExecTypes != NIL)
2644  {
2645  int i;
2646 
2647  /*
2648  * Force evaluation of any InitPlan outputs that could be needed
2649  * by the subplan, just in case they got reset since
2650  * EvalPlanQualStart (see comments therein).
2651  */
2652  ExecSetParamPlanMulti(rcplanstate->plan->extParam,
2653  GetPerTupleExprContext(parentestate));
2654 
2655  i = list_length(parentestate->es_plannedstmt->paramExecTypes);
2656 
2657  while (--i >= 0)
2658  {
2659  /* copy value if any, but not execPlan link */
2660  recheckestate->es_param_exec_vals[i].value =
2661  parentestate->es_param_exec_vals[i].value;
2662  recheckestate->es_param_exec_vals[i].isnull =
2663  parentestate->es_param_exec_vals[i].isnull;
2664  }
2665  }
2666 
2667  /*
2668  * Mark child plan tree as needing rescan at all scan nodes. The
2669  * first ExecProcNode will take care of actually doing the rescan.
2670  */
2671  rcplanstate->chgParam = bms_add_member(rcplanstate->chgParam,
2672  epqstate->epqParam);
2673  }
2674 }
2675 
2676 /*
2677  * Start execution of an EvalPlanQual plan tree.
2678  *
2679  * This is a cut-down version of ExecutorStart(): we copy some state from
2680  * the top-level estate rather than initializing it fresh.
2681  */
2682 static void
2683 EvalPlanQualStart(EPQState *epqstate, Plan *planTree)
2684 {
2685  EState *parentestate = epqstate->parentestate;
2686  Index rtsize = parentestate->es_range_table_size;
2687  EState *rcestate;
2688  MemoryContext oldcontext;
2689  ListCell *l;
2690 
2691  epqstate->recheckestate = rcestate = CreateExecutorState();
2692 
2693  oldcontext = MemoryContextSwitchTo(rcestate->es_query_cxt);
2694 
2695  /* signal that this is an EState for executing EPQ */
2696  rcestate->es_epq_active = epqstate;
2697 
2698  /*
2699  * Child EPQ EStates share the parent's copy of unchanging state such as
2700  * the snapshot, rangetable, and external Param info. They need their own
2701  * copies of local state, including a tuple table, es_param_exec_vals,
2702  * result-rel info, etc.
2703  */
2704  rcestate->es_direction = ForwardScanDirection;
2705  rcestate->es_snapshot = parentestate->es_snapshot;
2706  rcestate->es_crosscheck_snapshot = parentestate->es_crosscheck_snapshot;
2707  rcestate->es_range_table = parentestate->es_range_table;
2708  rcestate->es_range_table_size = parentestate->es_range_table_size;
2709  rcestate->es_relations = parentestate->es_relations;
2710  rcestate->es_queryEnv = parentestate->es_queryEnv;
2711  rcestate->es_rowmarks = parentestate->es_rowmarks;
2712  rcestate->es_plannedstmt = parentestate->es_plannedstmt;
2713  rcestate->es_junkFilter = parentestate->es_junkFilter;
2714  rcestate->es_output_cid = parentestate->es_output_cid;
2715 
2716  /*
2717  * ResultRelInfos needed by subplans are initialized from scratch when the
2718  * subplans themselves are initialized.
2719  */
2720  rcestate->es_result_relations = NULL;
2721  /* es_trig_target_relations must NOT be copied */
2722  rcestate->es_top_eflags = parentestate->es_top_eflags;
2723  rcestate->es_instrument = parentestate->es_instrument;
2724  /* es_auxmodifytables must NOT be copied */
2725 
2726  /*
2727  * The external param list is simply shared from parent. The internal
2728  * param workspace has to be local state, but we copy the initial values
2729  * from the parent, so as to have access to any param values that were
2730  * already set from other parts of the parent's plan tree.
2731  */
2732  rcestate->es_param_list_info = parentestate->es_param_list_info;
2733  if (parentestate->es_plannedstmt->paramExecTypes != NIL)
2734  {
2735  int i;
2736 
2737  /*
2738  * Force evaluation of any InitPlan outputs that could be needed by
2739  * the subplan. (With more complexity, maybe we could postpone this
2740  * till the subplan actually demands them, but it doesn't seem worth
2741  * the trouble; this is a corner case already, since usually the
2742  * InitPlans would have been evaluated before reaching EvalPlanQual.)
2743  *
2744  * This will not touch output params of InitPlans that occur somewhere
2745  * within the subplan tree, only those that are attached to the
2746  * ModifyTable node or above it and are referenced within the subplan.
2747  * That's OK though, because the planner would only attach such
2748  * InitPlans to a lower-level SubqueryScan node, and EPQ execution
2749  * will not descend into a SubqueryScan.
2750  *
2751  * The EState's per-output-tuple econtext is sufficiently short-lived
2752  * for this, since it should get reset before there is any chance of
2753  * doing EvalPlanQual again.
2754  */
2755  ExecSetParamPlanMulti(planTree->extParam,
2756  GetPerTupleExprContext(parentestate));
2757 
2758  /* now make the internal param workspace ... */
2759  i = list_length(parentestate->es_plannedstmt->paramExecTypes);
2760  rcestate->es_param_exec_vals = (ParamExecData *)
2761  palloc0(i * sizeof(ParamExecData));
2762  /* ... and copy down all values, whether really needed or not */
2763  while (--i >= 0)
2764  {
2765  /* copy value if any, but not execPlan link */
2766  rcestate->es_param_exec_vals[i].value =
2767  parentestate->es_param_exec_vals[i].value;
2768  rcestate->es_param_exec_vals[i].isnull =
2769  parentestate->es_param_exec_vals[i].isnull;
2770  }
2771  }
2772 
2773  /*
2774  * Initialize private state information for each SubPlan. We must do this
2775  * before running ExecInitNode on the main query tree, since
2776  * ExecInitSubPlan expects to be able to find these entries. Some of the
2777  * SubPlans might not be used in the part of the plan tree we intend to
2778  * run, but since it's not easy to tell which, we just initialize them
2779  * all.
2780  */
2781  Assert(rcestate->es_subplanstates == NIL);
2782  foreach(l, parentestate->es_plannedstmt->subplans)
2783  {
2784  Plan *subplan = (Plan *) lfirst(l);
2785  PlanState *subplanstate;
2786 
2787  subplanstate = ExecInitNode(subplan, rcestate, 0);
2788  rcestate->es_subplanstates = lappend(rcestate->es_subplanstates,
2789  subplanstate);
2790  }
2791 
2792  /*
2793  * Build an RTI indexed array of rowmarks, so that
2794  * EvalPlanQualFetchRowMark() can efficiently access the to be fetched
2795  * rowmark.
2796  */
2797  epqstate->relsubs_rowmark = (ExecAuxRowMark **)
2798  palloc0(rtsize * sizeof(ExecAuxRowMark *));
2799  foreach(l, epqstate->arowMarks)
2800  {
2801  ExecAuxRowMark *earm = (ExecAuxRowMark *) lfirst(l);
2802 
2803  epqstate->relsubs_rowmark[earm->rowmark->rti - 1] = earm;
2804  }
2805 
2806  /*
2807  * Initialize per-relation EPQ tuple states to not-fetched.
2808  */
2809  epqstate->relsubs_done = (bool *)
2810  palloc0(rtsize * sizeof(bool));
2811 
2812  /*
2813  * Initialize the private state information for all the nodes in the part
2814  * of the plan tree we need to run. This opens files, allocates storage
2815  * and leaves us ready to start processing tuples.
2816  */
2817  epqstate->recheckplanstate = ExecInitNode(planTree, rcestate, 0);
2818 
2819  MemoryContextSwitchTo(oldcontext);
2820 }
2821 
2822 /*
2823  * EvalPlanQualEnd -- shut down at termination of parent plan state node,
2824  * or if we are done with the current EPQ child.
2825  *
2826  * This is a cut-down version of ExecutorEnd(); basically we want to do most
2827  * of the normal cleanup, but *not* close result relations (which we are
2828  * just sharing from the outer query). We do, however, have to close any
2829  * result and trigger target relations that got opened, since those are not
2830  * shared. (There probably shouldn't be any of the latter, but just in
2831  * case...)
2832  */
2833 void
2835 {
2836  EState *estate = epqstate->recheckestate;
2837  Index rtsize;
2838  MemoryContext oldcontext;
2839  ListCell *l;
2840 
2841  rtsize = epqstate->parentestate->es_range_table_size;
2842 
2843  /*
2844  * We may have a tuple table, even if EPQ wasn't started, because we allow
2845  * use of EvalPlanQualSlot() without calling EvalPlanQualBegin().
2846  */
2847  if (epqstate->tuple_table != NIL)
2848  {
2849  memset(epqstate->relsubs_slot, 0,
2850  rtsize * sizeof(TupleTableSlot *));
2851  ExecResetTupleTable(epqstate->tuple_table, true);
2852  epqstate->tuple_table = NIL;
2853  }
2854 
2855  /* EPQ wasn't started, nothing further to do */
2856  if (estate == NULL)
2857  return;
2858 
2859  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
2860 
2861  ExecEndNode(epqstate->recheckplanstate);
2862 
2863  foreach(l, estate->es_subplanstates)
2864  {
2865  PlanState *subplanstate = (PlanState *) lfirst(l);
2866 
2867  ExecEndNode(subplanstate);
2868  }
2869 
2870  /* throw away the per-estate tuple table, some node may have used it */
2871  ExecResetTupleTable(estate->es_tupleTable, false);
2872 
2873  /* Close any result and trigger target relations attached to this EState */
2874  ExecCloseResultRelations(estate);
2875 
2876  MemoryContextSwitchTo(oldcontext);
2877 
2878  FreeExecutorState(estate);
2879 
2880  /* Mark EPQState idle */
2881  epqstate->origslot = NULL;
2882  epqstate->recheckestate = NULL;
2883  epqstate->recheckplanstate = NULL;
2884  epqstate->relsubs_rowmark = NULL;
2885  epqstate->relsubs_done = NULL;
2886 }
TupleTableSlot * table_slot_create(Relation relation, List **reglist)
Definition: tableam.c:91
bool(* receiveSlot)(TupleTableSlot *slot, DestReceiver *self)
Definition: dest.h:119
TupleTableSlot ** relsubs_slot
Definition: execnodes.h:1113
ExecForeignDelete_function ExecForeignDelete
Definition: fdwapi.h:236
int ri_NumIndices
Definition: execnodes.h:415
List * paramExecTypes
Definition: plannodes.h:84
struct ExprEvalStep::@49::@86 subplan
static TupleTableSlot * ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
Definition: tuptable.h:475
#define NIL
Definition: pg_list.h:65
void ExecInitRangeTable(EState *estate, List *rangeTable)
Definition: execUtils.c:751
void InstrStopNode(Instrumentation *instr, double nTuples)
Definition: instrument.c:84
void(* ExecutorRun_hook_type)(QueryDesc *queryDesc, ScanDirection direction, uint64 count, bool execute_once)
Definition: executor.h:69
TupleConversionMap * map
Definition: execExpr.h:555
Definition: fmgr.h:56
JunkFilter * es_junkFilter
Definition: execnodes.h:570
void standard_ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count, bool execute_once)
Definition: execMain.c:309
void ExecSetParamPlanMulti(const Bitmapset *params, ExprContext *econtext)
Definition: nodeSubplan.c:1253
Relation ri_RelationDesc
Definition: execnodes.h:412
LockTupleMode
Definition: lockoptions.h:49
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
int errhint(const char *fmt,...)
Definition: elog.c:1156
void ExecWithCheckOptions(WCOKind kind, ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate)
Definition: execMain.c:1954
#define forboth(cell1, list1, cell2, list2)
Definition: pg_list.h:446
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2854
RowMarkType markType
Definition: plannodes.h:1123
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1831
static void ExecPostprocessPlan(EState *estate)
Definition: execMain.c:1354
struct CopyMultiInsertBuffer * ri_CopyMultiInsertBuffer
Definition: execnodes.h:527
EState * estate
Definition: execdesc.h:48
CommandId es_output_cid
Definition: execnodes.h:573
void PreventCommandIfParallelMode(const char *cmdname)
Definition: utility.c:426
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:425
Snapshot RegisterSnapshot(Snapshot snapshot)
Definition: snapmgr.c:825
AclResult pg_attribute_aclcheck(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode)
Definition: aclchk.c:4551
#define ResetPerTupleExprContext(estate)
Definition: executor.h:542
AttrNumber ExecFindJunkAttributeInTlist(List *targetlist, const char *attrName)
Definition: execJunk.c:222
#define RelationGetDescr(relation)
Definition: rel.h:503
Oid GetUserId(void)
Definition: miscinit.c:495
bool EvalPlanQualFetchRowMark(EPQState *epqstate, Index rti, TupleTableSlot *slot)
Definition: execMain.c:2497
bool ExecShutdownNode(PlanState *node)
Definition: execProcnode.c:772
void ExecEndNode(PlanState *node)
Definition: execProcnode.c:556
Relation relation
Definition: execnodes.h:673
bool MatViewIncrementalMaintenanceIsEnabled(void)
Definition: matview.c:928
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
void ExecCloseResultRelations(EState *estate)
Definition: execMain.c:1439
static const char * CreateCommandName(Node *parsetree)
Definition: utility.h:103
ExecForeignInsert_function ExecForeignInsert
Definition: fdwapi.h:232
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1974
ExprState * ExecPrepareCheck(List *qual, EState *estate)
Definition: execExpr.c:797
#define DatumGetObjectId(X)
Definition: postgres.h:544
ProjectionInfo * ri_projectNew
Definition: execnodes.h:430
ExprState * ri_PartitionCheckExpr
Definition: execnodes.h:499
Bitmapset * ExecGetUpdatedCols(ResultRelInfo *relinfo, EState *estate)
Definition: execUtils.c:1295
const TupleTableSlotOps * kind
Definition: execExpr.h:294
void standard_ExecutorStart(QueryDesc *queryDesc, int eflags)
Definition: execMain.c:147
void ExecReScan(PlanState *node)
Definition: execAmi.c:78
int bms_next_member(const Bitmapset *a, int prevbit)
Definition: bitmapset.c:1043
const TupleTableSlotOps TTSOpsVirtual
Definition: execTuples.c:83
Bitmapset * ExecGetAllUpdatedCols(ResultRelInfo *relinfo, EState *estate)
Definition: execUtils.c:1347
Oid get_rel_namespace(Oid relid)
Definition: lsyscache.c:1923
void ExecutorStart(QueryDesc *queryDesc, int eflags)
Definition: execMain.c:130
void ExecConstraints(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate)
Definition: execMain.c:1821
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Instrumentation * InstrAlloc(int n, int instrument_options, bool async_mode)
Definition: instrument.c:31
Instrumentation * ri_TrigInstrument
Definition: execnodes.h:448
PlannedStmt * es_plannedstmt
Definition: execnodes.h:567
TupleConversionMap * ri_ChildToRootMap
Definition: execnodes.h:523
Definition: nodes.h:537
Snapshot es_crosscheck_snapshot
Definition: execnodes.h:560
int errcode(int sqlerrcode)
Definition: elog.c:698
void standard_ExecutorEnd(QueryDesc *queryDesc)
Definition: execMain.c:468
void * stringToNode(const char *str)
Definition: read.c:89
bool ermActive
Definition: execnodes.h:681
Index prti
Definition: plannodes.h:1121
LockWaitPolicy waitPolicy
Definition: execnodes.h:680
void(* ExecutorFinish_hook_type)(QueryDesc *queryDesc)
Definition: executor.h:76
#define MemSet(start, val, len)
Definition: c.h:1008
Snapshot es_snapshot
Definition: execnodes.h:559
Datum * tts_values
Definition: tuptable.h:126
#define EXEC_FLAG_WITH_NO_DATA
Definition: executor.h:61
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:27
void EvalPlanQualSetPlan(EPQState *epqstate, Plan *subplan, List *auxrowmarks)
Definition: execMain.c:2452
bool(* ExecutorCheckPerms_hook_type)(List *, bool)
Definition: executor.h:84
AclMode requiredPerms
Definition: parsenodes.h:1157
LockClauseStrength strength
Definition: execnodes.h:679
List * es_range_table
Definition: execnodes.h:561
Form_pg_class rd_rel
Definition: rel.h:109
unsigned int Oid
Definition: postgres_ext.h:31
static bool ExecQual(ExprState *state, ExprContext *econtext)
Definition: executor.h:396
EState * parentestate
Definition: execnodes.h:1104
TupleTableSlot * ri_TrigNewSlot
Definition: execnodes.h:453
Index rowmarkId
Definition: plannodes.h:1122
#define ScanDirectionIsNoMovement(direction)
Definition: sdir.h:48
LockWaitPolicy waitPolicy
Definition: plannodes.h:1126
bool ri_projectNewInfoValid
Definition: execnodes.h:436
static void CheckValidRowMarkRel(Relation rel, RowMarkType markType)
Definition: execMain.c:1128
AclMode pg_class_aclmask(Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how)
Definition: aclchk.c:3820
#define OidIsValid(objectId)
Definition: c.h:710
ExprState * ExecPrepareExpr(Expr *node, EState *estate)
Definition: execExpr.c:746
#define RowMarkRequiresRowShareLock(marktype)
Definition: plannodes.h:1077
ScanDirection es_direction
Definition: execnodes.h:558
struct EPQState * es_epq_active
Definition: execnodes.h:630
void standard_ExecutorFinish(QueryDesc *queryDesc)
Definition: execMain.c:408
Index ri_RangeTableIndex
Definition: execnodes.h:409
void ExecCloseRangeTableRelations(EState *estate)
Definition: execMain.c:1482
TupleTableSlot * EvalPlanQualNext(EPQState *epqstate)
Definition: execMain.c:2606
Definition: attmap.h:34
struct Plan * planTree
Definition: plannodes.h:64
TupleTableSlot * ri_newTupleSlot
Definition: execnodes.h:432
Snapshot snapshot
Definition: execdesc.h:39
int instrument_options
Definition: execdesc.h:44
void EvalPlanQualEnd(EPQState *epqstate)
Definition: execMain.c:2834
ExecRowMark * rowmark
Definition: execnodes.h:697
ItemPointerData curCtid
Definition: execnodes.h:682
ExecutorStart_hook_type ExecutorStart_hook
Definition: execMain.c:71
bool es_use_parallel_mode
Definition: execnodes.h:632
struct ExecRowMark ** es_rowmarks
Definition: execnodes.h:565
List * ri_WithCheckOptionExprs
Definition: execnodes.h:475
void ExecutorEnd(QueryDesc *queryDesc)
Definition: execMain.c:459
bool trig_insert_instead_row
Definition: reltrigger.h:58
void FreeExecutorState(EState *estate)
Definition: execUtils.c:186
#define GetPerTupleExprContext(estate)
Definition: executor.h:533
int errtableconstraint(Relation rel, const char *conname)
Definition: relcache.c:5793
uint32 AclMode
Definition: parsenodes.h:80
const char * es_sourceText
Definition: execnodes.h:568
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3308
Bitmapset * selectedCols
Definition: parsenodes.h:1159
ParamExecData * es_param_exec_vals
Definition: execnodes.h:596
QueryEnvironment * queryEnv
Definition: execdesc.h:43
MemoryContext es_query_cxt
Definition: execnodes.h:601
bool IsInParallelMode(void)
Definition: xact.c:1013
bool resjunk
Definition: primnodes.h:1462
AttrMap * build_attrmap_by_name_if_req(TupleDesc indesc, TupleDesc outdesc)
Definition: attmap.c:259
#define ERROR
Definition: elog.h:46
PlanState * planstate
Definition: execdesc.h:49
NodeTag type
Definition: execnodes.h:406
EState * recheckestate
Definition: execnodes.h:1134
ExecutorRun_hook_type ExecutorRun_hook
Definition: execMain.c:72
ExecutorEnd_hook_type ExecutorEnd_hook
Definition: execMain.c:74
TupleDesc tupdesc
Definition: execExpr.h:312
void ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count, bool execute_once)
Definition: execMain.c:298
bool isnull
Definition: params.h:150
void InstrStartNode(Instrumentation *instr)
Definition: instrument.c:68
bool ri_ChildToRootMapValid
Definition: execnodes.h:524
static char * ExecBuildSlotValueDescription(Oid reloid, TupleTableSlot *slot, TupleDesc tupdesc, Bitmapset *modifiedCols, int maxfieldlen)
Definition: execMain.c:2103
void(* rStartup)(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition: dest.h:122
TupleTableSlot * ri_PartitionTupleSlot
Definition: execnodes.h:515
int pg_mbcliplen(const char *mbstr, int len, int limit)
Definition: mbutils.c:1026
TupleTableSlot * EvalPlanQualSlot(EPQState *epqstate, Relation relation, Index rti)
Definition: execMain.c:2469
List * arowMarks
Definition: execnodes.h:1121
TriggerDesc * trigdesc
Definition: rel.h:115
static void slot_getallattrs(TupleTableSlot *slot)
Definition: tuptable.h:354
bool ri_usesFdwDirectModify
Definition: execnodes.h:462
void ExitParallelMode(void)
Definition: xact.c:993
struct ResultRelInfo * ri_RootResultRelInfo
Definition: execnodes.h:513
void CheckValidResultRel(ResultRelInfo *resultRelInfo, CmdType operation)
Definition: execMain.c:992
#define EXEC_FLAG_BACKWARD
Definition: executor.h:58
ExprState ** ri_TrigWhenExprs
Definition: execnodes.h:445
static void EvalPlanQualStart(EPQState *epqstate, Plan *planTree)
Definition: execMain.c:2683
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
Index rti
Definition: execnodes.h:675
#define NoLock
Definition: lockdefs.h:34
static char * buf
Definition: pg_test_fsync.c:68
void * ermExtra
Definition: execnodes.h:683
int es_jit_flags
Definition: execnodes.h:646
bool * tts_isnull
Definition: tuptable.h:128
TupleDesc jf_cleanTupType
Definition: execnodes.h:367
AttrNumber wholeAttNo
Definition: execnodes.h:700
TupleConstr * constr
Definition: tupdesc.h:85
bool hasReturning
Definition: plannodes.h:50
TupleTableSlot * ri_ReturningSlot
Definition: execnodes.h:451
List * es_opened_result_relations
Definition: execnodes.h:579
static bool ExecCheckRTEPermsModified(Oid relOid, Oid userid, Bitmapset *modifiedCols, AclMode requiredPerms)
Definition: execMain.c:719
Index prti
Definition: execnodes.h:676
List * tuple_table
Definition: execnodes.h:1112
int errdetail(const char *fmt,...)
Definition: elog.c:1042
char * ccname
Definition: tupdesc.h:30
ScanDirection
Definition: sdir.h:22
ParamListInfo params
Definition: execdesc.h:42
void ExecPartitionCheckEmitError(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate)
Definition: execMain.c:1750
ExprState ** ri_GeneratedExprs
Definition: execnodes.h:481
#define RelationGetRelationName(relation)
Definition: rel.h:511
static bool ExecCheckRTEPerms(RangeTblEntry *rte)
Definition: execMain.c:599
TupleTableSlot * EvalPlanQual(EPQState *epqstate, Relation relation, Index rti, TupleTableSlot *inputslot)
Definition: execMain.c:2359
ProjectionInfo * ri_projectReturning
Definition: execnodes.h:490
static RangeTblEntry * exec_rt_fetch(Index rti, EState *estate)
Definition: executor.h:571
#define TupIsNull(slot)
Definition: tuptable.h:292
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:207
struct FdwRoutine * ri_FdwRoutine
Definition: execnodes.h:456
bool isTempNamespace(Oid namespaceId)
Definition: namespace.c:3202
int jitFlags
Definition: plannodes.h:62
bool * relsubs_done
Definition: execnodes.h:1147
int es_instrument
Definition: execnodes.h:608
void CheckCmdReplicaIdentity(Relation rel, CmdType cmd)
WCOKind
Definition: parsenodes.h:1216
TupleTableSlot * origslot
Definition: execnodes.h:1129
#define EXEC_FLAG_REWIND
Definition: executor.h:57
ResultRelInfo ** es_result_relations
Definition: execnodes.h:576
ExprState ** ri_ConstraintExprs
Definition: execnodes.h:478
TriggerDesc * ri_TrigDesc
Definition: execnodes.h:439
Index rowmarkId
Definition: execnodes.h:677
void ExecutorFinish(QueryDesc *queryDesc)
Definition: execMain.c:399
ExecutorCheckPerms_hook_type ExecutorCheckPerms_hook
Definition: execMain.c:77
EState * CreateExecutorState(void)
Definition: execUtils.c:90
void ExecStoreHeapTupleDatum(Datum data, TupleTableSlot *slot)
Definition: execTuples.c:1606
Bitmapset * chgParam
Definition: execnodes.h:999
void UnregisterSnapshot(Snapshot snapshot)
Definition: snapmgr.c:867
static bool table_tuple_fetch_row_version(Relation rel, ItemPointer tid, Snapshot snapshot, TupleTableSlot *slot)
Definition: tableam.h:1257
List * lappend(List *list, void *datum)
Definition: list.c:336
QueryEnvironment * es_queryEnv
Definition: execnodes.h:598
bool trig_update_instead_row
Definition: reltrigger.h:63
ResultRelInfo * ExecGetTriggerResultRel(EState *estate, Oid relid)
Definition: execMain.c:1282
bool bms_is_empty(const Bitmapset *a)
Definition: bitmapset.c:701
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
TupleDesc tupDesc
Definition: execdesc.h:47
void EvalPlanQualInit(EPQState *epqstate, EState *parentestate, Plan *subplan, List *auxrowmarks, int epqParam)
Definition: execMain.c:2413
CmdType operation
Definition: execdesc.h:36
int numtriggers
Definition: reltrigger.h:50
OnConflictSetState * ri_onConflict
Definition: execnodes.h:496
static void ExecCheckXactReadOnly(PlannedStmt *plannedstmt)
Definition: execMain.c:766
#define AttributeNumberIsValid(attributeNumber)
Definition: attnum.h:34
#define ACL_UPDATE
Definition: parsenodes.h:84
void ExecutorRewind(QueryDesc *queryDesc)
Definition: execMain.c:525
List * es_trig_target_relations
Definition: execnodes.h:592
bool trig_delete_instead_row
Definition: reltrigger.h:68
Plan * plan
Definition: execnodes.h:1120
List * es_tupleTable
Definition: execnodes.h:603
void ExecResetTupleTable(List *tupleTable, bool shouldFree)
Definition: execTuples.c:1191
void * palloc0(Size size)
Definition: mcxt.c:1093
List * es_auxmodifytables
Definition: execnodes.h:615
AclResult
Definition: acl.h:177
static Datum ExecGetJunkAttribute(TupleTableSlot *slot, AttrNumber attno, bool *isNull)
Definition: executor.h:178
uintptr_t Datum
Definition: postgres.h:411
TupleTableSlot * ExecFilterJunk(JunkFilter *junkfilter, TupleTableSlot *slot)
Definition: execJunk.c:247
void InitResultRelInfo(ResultRelInfo *resultRelInfo, Relation resultRelationDesc, Index resultRelationIndex, ResultRelInfo *partition_root_rri, int instrument_options)
Definition: execMain.c:1193
CmdType commandType
Definition: plannodes.h:46
#define ACL_SELECT
Definition: parsenodes.h:83
static TupleTableSlot * ExecProcNode(PlanState *node)
Definition: executor.h:252
List * ri_WithCheckOptions
Definition: execnodes.h:472
bool already_executed
Definition: execdesc.h:52
Snapshot crosscheck_snapshot
Definition: execdesc.h:40
unsigned int Index
Definition: c.h:549
List * rowMarks
Definition: plannodes.h:78
TupleTableSlot * MakeTupleTableSlot(TupleDesc tupleDesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1112
TupleDesc rd_att
Definition: rel.h:110
uint16 num_check
Definition: tupdesc.h:43
static void ExecMaterializeSlot(TupleTableSlot *slot)
Definition: tuptable.h:443
Plan * plan
Definition: execnodes.h:967
static const char * ExecRelCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate)
Definition: execMain.c:1622
#define InvalidOid
Definition: postgres_ext.h:36
List * es_tuple_routing_result_relations
Definition: execnodes.h:589
bool es_finished
Definition: execnodes.h:609
#define ereport(elevel,...)
Definition: elog.h:157
void * ri_FdwState
Definition: execnodes.h:459
Bitmapset * updatedCols
Definition: parsenodes.h:1161
void pgstat_report_query_id(uint64 query_id, bool force)
bool XactReadOnly
Definition: xact.c:79
ExecForeignUpdate_function ExecForeignUpdate
Definition: fdwapi.h:235
void AfterTriggerBeginQuery(void)
Definition: trigger.c:4670
AttrNumber ri_RowIdAttNo
Definition: execnodes.h:427
int check_enable_rls(Oid relid, Oid checkAsUser, bool noError)
Definition: rls.c:52
Relation ExecGetRangeTableRelation(EState *estate, Index rti)
Definition: execUtils.c:782
struct Instrumentation * totaltime
Definition: execdesc.h:55
void(* ExecutorEnd_hook_type)(QueryDesc *queryDesc)
Definition: executor.h:80
#define makeNode(_type_)
Definition: nodes.h:585
List * subplans
Definition: plannodes.h:73
TupleTableSlot * ri_TrigOldSlot
Definition: execnodes.h:452
TupleTableSlot * execute_attr_map_slot(AttrMap *attrMap, TupleTableSlot *in_slot, TupleTableSlot *out_slot)
Definition: tupconvert.c:177
TriggerDesc * CopyTriggerDesc(TriggerDesc *trigdesc)
Definition: trigger.c:2014
#define Assert(condition)
Definition: c.h:804
#define lfirst(lc)
Definition: pg_list.h:169
Bitmapset * rewindPlanIDs
Definition: plannodes.h:76
int errtablecol(Relation rel, int attnum)
Definition: relcache.c:5756
LockTupleMode ExecUpdateLockMode(EState *estate, ResultRelInfo *relinfo)
Definition: execMain.c:2240
bool hasModifyingCTE
Definition: plannodes.h:52
static void ExecEndPlan(PlanState *planstate, EState *estate)
Definition: execMain.c:1400
Relation * es_relations
Definition: execnodes.h:563
#define ACL_INSERT
Definition: parsenodes.h:82
RowMarkType markType
Definition: execnodes.h:678
uint64 es_processed
Definition: execnodes.h:605
LockClauseStrength strength
Definition: plannodes.h:1125
AclResult pg_attribute_aclcheck_all(Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how)
Definition: aclchk.c:4595
Bitmapset * bms_union(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:225
static int list_length(const List *l)
Definition: pg_list.h:149
RowMarkType
Definition: plannodes.h:1067
Bitmapset * extParam
Definition: plannodes.h:159
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:227
Index es_range_table_size
Definition: execnodes.h:562
TupleTableSlot * ri_oldTupleSlot
Definition: execnodes.h:434
void EnterParallelMode(void)
Definition: xact.c:980
List * es_subplanstates
Definition: execnodes.h:613
Bitmapset * ExecGetInsertedCols(ResultRelInfo *relinfo, EState *estate)
Definition: execUtils.c:1256
AttrNumber toidAttNo
Definition: execnodes.h:699
List * rtable
Definition: plannodes.h:66
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:736
#define EXEC_FLAG_SKIP_TRIGGERS
Definition: executor.h:60
TupleDesc ExecGetResultType(PlanState *planstate)
Definition: execUtils.c:490
#define SnapshotAny
Definition: snapmgr.h:67
void PreventCommandIfReadOnly(const char *cmdname)
Definition: utility.c:408
#define InvalidAttrNumber
Definition: attnum.h:23
List * targetlist
Definition: plannodes.h:141
void(* rShutdown)(DestReceiver *self)
Definition: dest.h:125
AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4680
#define DatumGetPointer(X)
Definition: postgres.h:593
const char * sourceText
Definition: execdesc.h:38
RTEKind rtekind
Definition: parsenodes.h:1007
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:494
DestReceiver * dest
Definition: execdesc.h:41
#define ItemPointerSetInvalid(pointer)
Definition: itemptr.h:172
void AfterTriggerEndQuery(EState *estate)
Definition: trigger.c:4690
char * OidOutputFunctionCall(Oid functionId, Datum val)
Definition: fmgr.c:1653
void * palloc(Size size)
Definition: mcxt.c:1062
uint64 queryId
Definition: plannodes.h:48
TupleConversionMap * ri_RootToPartitionMap
Definition: execnodes.h:514
int errmsg(const char *fmt,...)
Definition: elog.c:909
FdwRoutine * GetFdwRoutineForRelation(Relation relation, bool makecopy)
Definition: foreign.c:427
int es_top_eflags
Definition: execnodes.h:607
void(* ExecutorStart_hook_type)(QueryDesc *queryDesc, int eflags)
Definition: executor.h:65
bool parallelModeNeeded
Definition: plannodes.h:60
#define elog(elevel,...)
Definition: elog.h:232
IndexInfo ** ri_IndexRelationInfo
Definition: execnodes.h:421
Bitmapset * insertedCols
Definition: parsenodes.h:1160
int i
ObjectType get_relkind_objtype(char relkind)
Bitmapset * RelationGetIndexAttrBitmap(Relation relation, IndexAttrBitmapKind attrKind)
Definition: relcache.c:5106
IsForeignRelUpdatable_function IsForeignRelUpdatable
Definition: fdwapi.h:240
bool ExecCheckRTPerms(List *rangeTable, bool ereport_on_violation)
Definition: execMain.c:568
#define NameStr(name)
Definition: c.h:681
List * RelationGetPartitionQual(Relation rel)
Definition: partcache.c:276
Datum value
Definition: params.h:149
bool ExecPartitionCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate, bool emitError)
Definition: execMain.c:1697
int epqParam
Definition: execnodes.h:1105
bool ExecCheck(ExprState *state, ExprContext *econtext)
Definition: execExpr.c:853
ParamListInfo es_param_list_info
Definition: execnodes.h:595
ExecutorFinish_hook_type ExecutorFinish_hook
Definition: execMain.c:73
ConstrCheck * check
Definition: tupdesc.h:40
bool isParent
Definition: plannodes.h:1127
CommandId GetCurrentCommandId(bool used)
Definition: xact.c:762
PlannedStmt * plannedstmt
Definition: execdesc.h:37
bool has_not_null
Definition: tupdesc.h:44
static bool slot_attisnull(TupleTableSlot *slot, int attnum)
Definition: tuptable.h:367
static bool success
Definition: initdb.c:165
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
Definition: execProcnode.c:141
ExecAuxRowMark ** relsubs_rowmark
Definition: execnodes.h:1141
Definition: pg_list.h:50
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1899
#define snprintf
Definition: port.h:217
int errtable(Relation rel)
Definition: relcache.c:5739
bool bms_is_member(int x, const Bitmapset *a)
Definition: bitmapset.c:427
#define EXEC_FLAG_EXPLAIN_ONLY
Definition: executor.h:56
int16 AttrNumber
Definition: attnum.h:21
#define RelationGetRelid(relation)
Definition: rel.h:477
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:227
JunkFilter * ExecInitJunkFilter(List *targetList, TupleTableSlot *slot)
Definition: execJunk.c:60
long val
Definition: informix.c:664
static void InitPlan(QueryDesc *queryDesc, int eflags)
Definition: execMain.c:803
void EvalPlanQualBegin(EPQState *epqstate)
Definition: execMain.c:2622
List * ri_onConflictArbiterIndexes
Definition: execnodes.h:493
CmdType
Definition: nodes.h:681
void ExecCloseIndices(ResultRelInfo *resultRelInfo)
Definition: execIndexing.c:231
AttrNumber ctidAttNo
Definition: execnodes.h:698
RelationPtr ri_IndexRelationDescs
Definition: execnodes.h:418
ExecAuxRowMark * ExecBuildAuxRowMark(ExecRowMark *erm, List *targetlist)
Definition: execMain.c:2289
FmgrInfo * ri_TrigFunctions
Definition: execnodes.h:442
PlanState * recheckplanstate
Definition: execnodes.h:1149
RefetchForeignRow_function RefetchForeignRow
Definition: fdwapi.h:248
ExecRowMark * ExecFindRowMark(EState *estate, Index rti, bool missing_ok)
Definition: execMain.c:2266
static void ExecutePlan(EState *estate, PlanState *planstate, bool use_parallel_mode, CmdType operation, bool sendTuples, uint64 numberTuples, ScanDirection direction, DestReceiver *dest, bool execute_once)
Definition: execMain.c:1506