PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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-2026, 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/sysattr.h"
41#include "access/table.h"
42#include "access/tableam.h"
43#include "access/tupconvert.h"
44#include "access/xact.h"
45#include "catalog/namespace.h"
46#include "catalog/partition.h"
47#include "commands/matview.h"
48#include "commands/trigger.h"
49#include "executor/executor.h"
51#include "executor/instrument.h"
53#include "foreign/fdwapi.h"
54#include "mb/pg_wchar.h"
55#include "miscadmin.h"
56#include "nodes/queryjumble.h"
58#include "pgstat.h"
60#include "tcop/utility.h"
61#include "utils/acl.h"
63#include "utils/lsyscache.h"
64#include "utils/partcache.h"
65#include "utils/rls.h"
66#include "utils/snapmgr.h"
67
68
69/* Hooks for plugins to get control in ExecutorStart/Run/Finish/End */
74
75/* Hook for plugin to get control in ExecCheckPermissions() */
77
78/* decls for local routines only used within this module */
79static void InitPlan(QueryDesc *queryDesc, int eflags);
80static void CheckValidRowMarkRel(Relation rel, RowMarkType markType);
81static void ExecPostprocessPlan(EState *estate);
82static void ExecEndPlan(PlanState *planstate, EState *estate);
83static void ExecutePlan(QueryDesc *queryDesc,
85 bool sendTuples,
87 ScanDirection direction,
88 DestReceiver *dest);
89static bool ExecCheckPermissionsModified(Oid relOid, Oid userid,
91 AclMode requiredPerms);
92static void ExecCheckXactReadOnly(PlannedStmt *plannedstmt);
93static void EvalPlanQualStart(EPQState *epqstate, Plan *planTree);
94static void ReportNotNullViolationError(ResultRelInfo *resultRelInfo,
95 TupleTableSlot *slot,
96 EState *estate, int attnum);
97
98/* end of local decls */
99
100
101/* ----------------------------------------------------------------
102 * ExecutorStart
103 *
104 * This routine must be called at the beginning of any execution of any
105 * query plan
106 *
107 * Takes a QueryDesc previously created by CreateQueryDesc (which is separate
108 * only because some places use QueryDescs for utility commands). The tupDesc
109 * field of the QueryDesc is filled in to describe the tuples that will be
110 * returned, and the internal fields (estate and planstate) are set up.
111 *
112 * eflags contains flag bits as described in executor.h.
113 *
114 * NB: the CurrentMemoryContext when this is called will become the parent
115 * of the per-query context used for this Executor invocation.
116 *
117 * We provide a function hook variable that lets loadable plugins
118 * get control when ExecutorStart is called. Such a plugin would
119 * normally call standard_ExecutorStart().
120 *
121 * ----------------------------------------------------------------
122 */
123void
124ExecutorStart(QueryDesc *queryDesc, int eflags)
125{
126 /*
127 * In some cases (e.g. an EXECUTE statement or an execute message with the
128 * extended query protocol) the query_id won't be reported, so do it now.
129 *
130 * Note that it's harmless to report the query_id multiple times, as the
131 * call will be ignored if the top level query_id has already been
132 * reported.
133 */
134 pgstat_report_query_id(queryDesc->plannedstmt->queryId, false);
135
137 (*ExecutorStart_hook) (queryDesc, eflags);
138 else
139 standard_ExecutorStart(queryDesc, eflags);
140}
141
142void
143standard_ExecutorStart(QueryDesc *queryDesc, int eflags)
144{
145 EState *estate;
146 MemoryContext oldcontext;
147
148 /* sanity checks: queryDesc must not be started already */
149 Assert(queryDesc != NULL);
150 Assert(queryDesc->estate == NULL);
151
152 /* caller must ensure the query's snapshot is active */
153 Assert(GetActiveSnapshot() == queryDesc->snapshot);
154
155 /*
156 * If the transaction is read-only, we need to check if any writes are
157 * planned to non-temporary tables. EXPLAIN is considered read-only.
158 *
159 * Don't allow writes in parallel mode. Supporting UPDATE and DELETE
160 * would require (a) storing the combo CID hash in shared memory, rather
161 * than synchronizing it just once at the start of parallelism, and (b) an
162 * alternative to heap_update()'s reliance on xmax for mutual exclusion.
163 * INSERT may have no such troubles, but we forbid it to simplify the
164 * checks.
165 *
166 * We have lower-level defenses in CommandCounterIncrement and elsewhere
167 * against performing unsafe operations in parallel mode, but this gives a
168 * more user-friendly error message.
169 */
170 if ((XactReadOnly || IsInParallelMode()) &&
171 !(eflags & EXEC_FLAG_EXPLAIN_ONLY))
173
174 /*
175 * Build EState, switch into per-query memory context for startup.
176 */
177 estate = CreateExecutorState();
178 queryDesc->estate = estate;
179
180 oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
181
182 /*
183 * Fill in external parameters, if any, from queryDesc; and allocate
184 * workspace for internal parameters
185 */
186 estate->es_param_list_info = queryDesc->params;
187
188 if (queryDesc->plannedstmt->paramExecTypes != NIL)
189 {
190 int nParamExec;
191
195 }
196
197 /* We now require all callers to provide sourceText */
198 Assert(queryDesc->sourceText != NULL);
199 estate->es_sourceText = queryDesc->sourceText;
200
201 /*
202 * Fill in the query environment, if any, from queryDesc.
203 */
204 estate->es_queryEnv = queryDesc->queryEnv;
205
206 /*
207 * If non-read-only query, set the command ID to mark output tuples with
208 */
209 switch (queryDesc->operation)
210 {
211 case CMD_SELECT:
212
213 /*
214 * SELECT FOR [KEY] UPDATE/SHARE and modifying CTEs need to mark
215 * tuples
216 */
217 if (queryDesc->plannedstmt->rowMarks != NIL ||
218 queryDesc->plannedstmt->hasModifyingCTE)
219 estate->es_output_cid = GetCurrentCommandId(true);
220
221 /*
222 * A SELECT without modifying CTEs can't possibly queue triggers,
223 * so force skip-triggers mode. This is just a marginal efficiency
224 * hack, since AfterTriggerBeginQuery/AfterTriggerEndQuery aren't
225 * all that expensive, but we might as well do it.
226 */
227 if (!queryDesc->plannedstmt->hasModifyingCTE)
228 eflags |= EXEC_FLAG_SKIP_TRIGGERS;
229 break;
230
231 case CMD_INSERT:
232 case CMD_DELETE:
233 case CMD_UPDATE:
234 case CMD_MERGE:
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 query-level instrumentation if extensions have requested it via
255 * query_instr_options. Ensure an extension has not allocated query_instr
256 * itself.
257 */
258 Assert(queryDesc->query_instr == NULL);
259 if (queryDesc->query_instr_options)
260 queryDesc->query_instr = InstrAlloc(queryDesc->query_instr_options);
261
262 /*
263 * Set up an AFTER-trigger statement context, unless told not to, or
264 * unless it's EXPLAIN-only mode (when ExecutorFinish won't be called).
265 */
268
269 /*
270 * Initialize the plan state tree
271 */
272 InitPlan(queryDesc, eflags);
273
274 MemoryContextSwitchTo(oldcontext);
275}
276
277/* ----------------------------------------------------------------
278 * ExecutorRun
279 *
280 * This is the main routine of the executor module. It accepts
281 * the query descriptor from the traffic cop and executes the
282 * query plan.
283 *
284 * ExecutorStart must have been called already.
285 *
286 * If direction is NoMovementScanDirection then nothing is done
287 * except to start up/shut down the destination. Otherwise,
288 * we retrieve up to 'count' tuples in the specified direction.
289 *
290 * Note: count = 0 is interpreted as no portal limit, i.e., run to
291 * completion. Also note that the count limit is only applied to
292 * retrieved tuples, not for instance to those inserted/updated/deleted
293 * by a ModifyTable plan node.
294 *
295 * There is no return value, but output tuples (if any) are sent to
296 * the destination receiver specified in the QueryDesc; and the number
297 * of tuples processed at the top level can be found in
298 * estate->es_processed. The total number of tuples processed in all
299 * the ExecutorRun calls can be found in estate->es_total_processed.
300 *
301 * We provide a function hook variable that lets loadable plugins
302 * get control when ExecutorRun is called. Such a plugin would
303 * normally call standard_ExecutorRun().
304 *
305 * ----------------------------------------------------------------
306 */
307void
309 ScanDirection direction, uint64 count)
310{
312 (*ExecutorRun_hook) (queryDesc, direction, count);
313 else
314 standard_ExecutorRun(queryDesc, direction, count);
315}
316
317void
319 ScanDirection direction, uint64 count)
320{
321 EState *estate;
323 DestReceiver *dest;
324 bool sendTuples;
325 MemoryContext oldcontext;
326
327 /* sanity checks */
328 Assert(queryDesc != NULL);
329
330 estate = queryDesc->estate;
331
332 Assert(estate != NULL);
334
335 /* caller must ensure the query's snapshot is active */
337
338 /*
339 * Switch into per-query memory context
340 */
341 oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
342
343 /* Allow instrumentation of Executor overall runtime */
344 if (queryDesc->query_instr)
345 InstrStart(queryDesc->query_instr);
346
347 /*
348 * extract information from the query descriptor and the query feature.
349 */
350 operation = queryDesc->operation;
351 dest = queryDesc->dest;
352
353 /*
354 * startup tuple receiver, if we will be emitting tuples
355 */
356 estate->es_processed = 0;
357
359 queryDesc->plannedstmt->hasReturning);
360
361 if (sendTuples)
362 dest->rStartup(dest, operation, queryDesc->tupDesc);
363
364 /*
365 * Run plan, unless direction is NoMovement.
366 *
367 * Note: pquery.c selects NoMovement if a prior call already reached
368 * end-of-data in the user-specified fetch direction. This is important
369 * because various parts of the executor can misbehave if called again
370 * after reporting EOF. For example, heapam.c would actually restart a
371 * heapscan and return all its data afresh. There is also some doubt
372 * about whether a parallel plan would operate properly if an additional,
373 * necessarily non-parallel execution request occurs after completing a
374 * parallel execution. (That case should work, but it's untested.)
375 */
376 if (!ScanDirectionIsNoMovement(direction))
377 ExecutePlan(queryDesc,
378 operation,
380 count,
381 direction,
382 dest);
383
384 /*
385 * Update es_total_processed to keep track of the number of tuples
386 * processed across multiple ExecutorRun() calls.
387 */
388 estate->es_total_processed += estate->es_processed;
389
390 /*
391 * shutdown tuple receiver, if we started it
392 */
393 if (sendTuples)
394 dest->rShutdown(dest);
395
396 if (queryDesc->query_instr)
397 InstrStop(queryDesc->query_instr);
398
399 MemoryContextSwitchTo(oldcontext);
400}
401
402/* ----------------------------------------------------------------
403 * ExecutorFinish
404 *
405 * This routine must be called after the last ExecutorRun call.
406 * It performs cleanup such as firing AFTER triggers. It is
407 * separate from ExecutorEnd because EXPLAIN ANALYZE needs to
408 * include these actions in the total runtime.
409 *
410 * We provide a function hook variable that lets loadable plugins
411 * get control when ExecutorFinish is called. Such a plugin would
412 * normally call standard_ExecutorFinish().
413 *
414 * ----------------------------------------------------------------
415 */
416void
418{
420 (*ExecutorFinish_hook) (queryDesc);
421 else
422 standard_ExecutorFinish(queryDesc);
423}
424
425void
427{
428 EState *estate;
429 MemoryContext oldcontext;
430
431 /* sanity checks */
432 Assert(queryDesc != NULL);
433
434 estate = queryDesc->estate;
435
436 Assert(estate != NULL);
438
439 /* This should be run once and only once per Executor instance */
440 Assert(!estate->es_finished);
441
442 /* Switch into per-query memory context */
443 oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
444
445 /* Allow instrumentation of Executor overall runtime */
446 if (queryDesc->query_instr)
447 InstrStart(queryDesc->query_instr);
448
449 /* Run ModifyTable nodes to completion */
450 ExecPostprocessPlan(estate);
451
452 /* Execute queued AFTER triggers, unless told not to */
453 if (!(estate->es_top_eflags & EXEC_FLAG_SKIP_TRIGGERS))
454 AfterTriggerEndQuery(estate);
455
456 if (queryDesc->query_instr)
457 InstrStop(queryDesc->query_instr);
458
459 MemoryContextSwitchTo(oldcontext);
460
461 estate->es_finished = true;
462}
463
464/* ----------------------------------------------------------------
465 * ExecutorEnd
466 *
467 * This routine must be called at the end of execution of any
468 * query plan
469 *
470 * We provide a function hook variable that lets loadable plugins
471 * get control when ExecutorEnd is called. Such a plugin would
472 * normally call standard_ExecutorEnd().
473 *
474 * ----------------------------------------------------------------
475 */
476void
478{
480 (*ExecutorEnd_hook) (queryDesc);
481 else
482 standard_ExecutorEnd(queryDesc);
483}
484
485void
487{
488 EState *estate;
489 MemoryContext oldcontext;
490
491 /* sanity checks */
492 Assert(queryDesc != NULL);
493
494 estate = queryDesc->estate;
495
496 Assert(estate != NULL);
497
498 if (estate->es_parallel_workers_to_launch > 0)
501
502 /*
503 * Check that ExecutorFinish was called, unless in EXPLAIN-only mode. This
504 * Assert is needed because ExecutorFinish is new as of 9.1, and callers
505 * might forget to call it.
506 */
507 Assert(estate->es_finished ||
509
510 /*
511 * Switch into per-query memory context to run ExecEndPlan
512 */
513 oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
514
515 ExecEndPlan(queryDesc->planstate, estate);
516
517 /* do away with our snapshots */
520
521 /*
522 * Must switch out of context before destroying it
523 */
524 MemoryContextSwitchTo(oldcontext);
525
526 /*
527 * Release EState and per-query memory context. This should release
528 * everything the executor has allocated.
529 */
530 FreeExecutorState(estate);
531
532 /* Reset queryDesc fields that no longer point to anything */
533 queryDesc->tupDesc = NULL;
534 queryDesc->estate = NULL;
535 queryDesc->planstate = NULL;
536 queryDesc->query_instr = NULL;
537}
538
539/* ----------------------------------------------------------------
540 * ExecutorRewind
541 *
542 * This routine may be called on an open queryDesc to rewind it
543 * to the start.
544 * ----------------------------------------------------------------
545 */
546void
548{
549 EState *estate;
550 MemoryContext oldcontext;
551
552 /* sanity checks */
553 Assert(queryDesc != NULL);
554
555 estate = queryDesc->estate;
556
557 Assert(estate != NULL);
558
559 /* It's probably not sensible to rescan updating queries */
560 Assert(queryDesc->operation == CMD_SELECT);
561
562 /*
563 * Switch into per-query memory context
564 */
565 oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
566
567 /*
568 * rescan plan
569 */
570 ExecReScan(queryDesc->planstate);
571
572 MemoryContextSwitchTo(oldcontext);
573}
574
575
576/*
577 * ExecCheckPermissions
578 * Check access permissions of relations mentioned in a query
579 *
580 * Returns true if permissions are adequate. Otherwise, throws an appropriate
581 * error if ereport_on_violation is true, or simply returns false otherwise.
582 *
583 * Note that this does NOT address row-level security policies (aka: RLS). If
584 * rows will be returned to the user as a result of this permission check
585 * passing, then RLS also needs to be consulted (and check_enable_rls()).
586 *
587 * See rewrite/rowsecurity.c.
588 *
589 * NB: rangeTable is no longer used by us, but kept around for the hooks that
590 * might still want to look at the RTEs.
591 */
592bool
594 bool ereport_on_violation)
595{
596 ListCell *l;
597 bool result = true;
598
599#ifdef USE_ASSERT_CHECKING
601
602 /* Check that rteperminfos is consistent with rangeTable */
603 foreach(l, rangeTable)
604 {
606
607 if (rte->perminfoindex != 0)
608 {
609 /* Sanity checks */
610
611 /*
612 * Only relation RTEs and subquery RTEs that were once relation
613 * RTEs (views, property graphs) have their perminfoindex set.
614 */
615 Assert(rte->rtekind == RTE_RELATION ||
616 (rte->rtekind == RTE_SUBQUERY &&
617 (rte->relkind == RELKIND_VIEW || rte->relkind == RELKIND_PROPGRAPH)));
618
619 (void) getRTEPermissionInfo(rteperminfos, rte);
620 /* Many-to-one mapping not allowed */
621 Assert(!bms_is_member(rte->perminfoindex, indexset));
622 indexset = bms_add_member(indexset, rte->perminfoindex);
623 }
624 }
625
626 /* All rteperminfos are referenced */
627 Assert(bms_num_members(indexset) == list_length(rteperminfos));
628#endif
629
630 foreach(l, rteperminfos)
631 {
633
634 Assert(OidIsValid(perminfo->relid));
636 if (!result)
637 {
638 if (ereport_on_violation)
641 get_rel_name(perminfo->relid));
642 return false;
643 }
644 }
645
647 result = (*ExecutorCheckPerms_hook) (rangeTable, rteperminfos,
648 ereport_on_violation);
649 return result;
650}
651
652/*
653 * ExecCheckOneRelPerms
654 * Check access permissions for a single relation.
655 */
656bool
658{
659 AclMode requiredPerms;
662 Oid userid;
663 Oid relOid = perminfo->relid;
664
665 requiredPerms = perminfo->requiredPerms;
666 Assert(requiredPerms != 0);
667
668 /*
669 * userid to check as: current user unless we have a setuid indication.
670 *
671 * Note: GetUserId() is presently fast enough that there's no harm in
672 * calling it separately for each relation. If that stops being true, we
673 * could call it once in ExecCheckPermissions and pass the userid down
674 * from there. But for now, no need for the extra clutter.
675 */
676 userid = OidIsValid(perminfo->checkAsUser) ?
677 perminfo->checkAsUser : GetUserId();
678
679 /*
680 * We must have *all* the requiredPerms bits, but some of the bits can be
681 * satisfied from column-level rather than relation-level permissions.
682 * First, remove any bits that are satisfied by relation permissions.
683 */
684 relPerms = pg_class_aclmask(relOid, userid, requiredPerms, ACLMASK_ALL);
685 remainingPerms = requiredPerms & ~relPerms;
686 if (remainingPerms != 0)
687 {
688 int col = -1;
689
690 /*
691 * If we lack any permissions that exist only as relation permissions,
692 * we can fail straight away.
693 */
695 return false;
696
697 /*
698 * Check to see if we have the needed privileges at column level.
699 *
700 * Note: failures just report a table-level error; it would be nicer
701 * to report a column-level error if we have some but not all of the
702 * column privileges.
703 */
705 {
706 /*
707 * When the query doesn't explicitly reference any columns (for
708 * example, SELECT COUNT(*) FROM table), allow the query if we
709 * have SELECT on any column of the rel, as per SQL spec.
710 */
711 if (bms_is_empty(perminfo->selectedCols))
712 {
713 if (pg_attribute_aclcheck_all(relOid, userid, ACL_SELECT,
715 return false;
716 }
717
718 while ((col = bms_next_member(perminfo->selectedCols, col)) >= 0)
719 {
720 /* bit #s are offset by FirstLowInvalidHeapAttributeNumber */
722
723 if (attno == InvalidAttrNumber)
724 {
725 /* Whole-row reference, must have priv on all cols */
726 if (pg_attribute_aclcheck_all(relOid, userid, ACL_SELECT,
728 return false;
729 }
730 else
731 {
732 if (pg_attribute_aclcheck(relOid, attno, userid,
734 return false;
735 }
736 }
737 }
738
739 /*
740 * Basically the same for the mod columns, for both INSERT and UPDATE
741 * privilege as specified by remainingPerms.
742 */
745 userid,
746 perminfo->insertedCols,
747 ACL_INSERT))
748 return false;
749
752 userid,
753 perminfo->updatedCols,
754 ACL_UPDATE))
755 return false;
756 }
757 return true;
758}
759
760/*
761 * ExecCheckPermissionsModified
762 * Check INSERT or UPDATE access permissions for a single relation (these
763 * are processed uniformly).
764 */
765static bool
767 AclMode requiredPerms)
768{
769 int col = -1;
770
771 /*
772 * When the query doesn't explicitly update any columns, allow the query
773 * if we have permission on any column of the rel. This is to handle
774 * SELECT FOR UPDATE as well as possible corner cases in UPDATE.
775 */
777 {
778 if (pg_attribute_aclcheck_all(relOid, userid, requiredPerms,
780 return false;
781 }
782
783 while ((col = bms_next_member(modifiedCols, col)) >= 0)
784 {
785 /* bit #s are offset by FirstLowInvalidHeapAttributeNumber */
787
788 if (attno == InvalidAttrNumber)
789 {
790 /* whole-row reference can't happen here */
791 elog(ERROR, "whole-row update is not implemented");
792 }
793 else
794 {
795 if (pg_attribute_aclcheck(relOid, attno, userid,
796 requiredPerms) != ACLCHECK_OK)
797 return false;
798 }
799 }
800 return true;
801}
802
803/*
804 * Check that the query does not imply any writes to non-temp tables;
805 * unless we're in parallel mode, in which case don't even allow writes
806 * to temp tables.
807 *
808 * Note: in a Hot Standby this would need to reject writes to temp
809 * tables just as we do in parallel mode; but an HS standby can't have created
810 * any temp tables in the first place, so no need to check that.
811 */
812static void
814{
815 ListCell *l;
816
817 /*
818 * Fail if write permissions are requested in parallel mode for table
819 * (temp or non-temp), otherwise fail for any non-temp table.
820 */
821 foreach(l, plannedstmt->permInfos)
822 {
824
825 if ((perminfo->requiredPerms & (~ACL_SELECT)) == 0)
826 continue;
827
829 continue;
830
832 }
833
834 if (plannedstmt->commandType != CMD_SELECT || plannedstmt->hasModifyingCTE)
836}
837
838
839/* ----------------------------------------------------------------
840 * InitPlan
841 *
842 * Initializes the query plan: open files, allocate storage
843 * and start up the rule manager
844 * ----------------------------------------------------------------
845 */
846static void
847InitPlan(QueryDesc *queryDesc, int eflags)
848{
849 CmdType operation = queryDesc->operation;
850 PlannedStmt *plannedstmt = queryDesc->plannedstmt;
851 Plan *plan = plannedstmt->planTree;
852 List *rangeTable = plannedstmt->rtable;
853 EState *estate = queryDesc->estate;
854 PlanState *planstate;
856 ListCell *l;
857 int i;
858
859 /*
860 * Do permissions checks
861 */
862 ExecCheckPermissions(rangeTable, plannedstmt->permInfos, true);
863
864 /*
865 * initialize the node's execution state
866 */
867 ExecInitRangeTable(estate, rangeTable, plannedstmt->permInfos,
868 bms_copy(plannedstmt->unprunableRelids));
869
870 estate->es_plannedstmt = plannedstmt;
871 estate->es_part_prune_infos = plannedstmt->partPruneInfos;
872
873 /*
874 * Perform runtime "initial" pruning to identify which child subplans,
875 * corresponding to the children of plan nodes that contain
876 * PartitionPruneInfo such as Append, will not be executed. The results,
877 * which are bitmapsets of indexes of the child subplans that will be
878 * executed, are saved in es_part_prune_results. These results correspond
879 * to each PartitionPruneInfo entry, and the es_part_prune_results list is
880 * parallel to es_part_prune_infos.
881 */
882 ExecDoInitialPruning(estate);
883
884 /*
885 * Next, build the ExecRowMark array from the PlanRowMark(s), if any.
886 */
887 if (plannedstmt->rowMarks)
888 {
889 estate->es_rowmarks = (ExecRowMark **)
891 foreach(l, plannedstmt->rowMarks)
892 {
893 PlanRowMark *rc = (PlanRowMark *) lfirst(l);
894 RangeTblEntry *rte = exec_rt_fetch(rc->rti, estate);
895 Oid relid;
896 Relation relation;
898
899 /* ignore "parent" rowmarks; they are irrelevant at runtime */
900 if (rc->isParent)
901 continue;
902
903 /*
904 * Also ignore rowmarks belonging to child tables that have been
905 * pruned in ExecDoInitialPruning().
906 */
907 if (rte->rtekind == RTE_RELATION &&
908 !bms_is_member(rc->rti, estate->es_unpruned_relids))
909 continue;
910
911 /* get relation's OID (will produce InvalidOid if subquery) */
912 relid = rte->relid;
913
914 /* open relation, if we need to access it for this mark type */
915 switch (rc->markType)
916 {
919 case ROW_MARK_SHARE:
922 relation = ExecGetRangeTableRelation(estate, rc->rti, false);
923 break;
924 case ROW_MARK_COPY:
925 /* no physical table access is required */
926 relation = NULL;
927 break;
928 default:
929 elog(ERROR, "unrecognized markType: %d", rc->markType);
930 relation = NULL; /* keep compiler quiet */
931 break;
932 }
933
934 /* Check that relation is a legal target for marking */
935 if (relation)
936 CheckValidRowMarkRel(relation, rc->markType);
937
939 erm->relation = relation;
940 erm->relid = relid;
941 erm->rti = rc->rti;
942 erm->prti = rc->prti;
943 erm->rowmarkId = rc->rowmarkId;
944 erm->markType = rc->markType;
945 erm->strength = rc->strength;
946 erm->waitPolicy = rc->waitPolicy;
947 erm->ermActive = false;
948 ItemPointerSetInvalid(&(erm->curCtid));
949 erm->ermExtra = NULL;
950
951 Assert(erm->rti > 0 && erm->rti <= estate->es_range_table_size &&
952 estate->es_rowmarks[erm->rti - 1] == NULL);
953
954 estate->es_rowmarks[erm->rti - 1] = erm;
955 }
956 }
957
958 /*
959 * Initialize the executor's tuple table to empty.
960 */
961 estate->es_tupleTable = NIL;
962
963 /* signal that this EState is not used for EPQ */
964 estate->es_epq_active = NULL;
965
966 /*
967 * Initialize private state information for each SubPlan. We must do this
968 * before running ExecInitNode on the main query tree, since
969 * ExecInitSubPlan expects to be able to find these entries.
970 */
971 Assert(estate->es_subplanstates == NIL);
972 i = 1; /* subplan indices count from 1 */
973 foreach(l, plannedstmt->subplans)
974 {
975 Plan *subplan = (Plan *) lfirst(l);
977 int sp_eflags;
978
979 /*
980 * A subplan will never need to do BACKWARD scan nor MARK/RESTORE. If
981 * it is a parameterless subplan (not initplan), we suggest that it be
982 * prepared to handle REWIND efficiently; otherwise there is no need.
983 */
984 sp_eflags = eflags
986 if (bms_is_member(i, plannedstmt->rewindPlanIDs))
988
989 subplanstate = ExecInitNode(subplan, estate, sp_eflags);
990
991 estate->es_subplanstates = lappend(estate->es_subplanstates,
993
994 i++;
995 }
996
997 /*
998 * Initialize the private state information for all the nodes in the query
999 * tree. This opens files, allocates storage and leaves us ready to start
1000 * processing tuples.
1001 */
1002 planstate = ExecInitNode(plan, estate, eflags);
1003
1004 /*
1005 * Get the tuple descriptor describing the type of tuples to return.
1006 */
1007 tupType = ExecGetResultType(planstate);
1008
1009 /*
1010 * Initialize the junk filter if needed. SELECT queries need a filter if
1011 * there are any junk attrs in the top-level tlist.
1012 */
1013 if (operation == CMD_SELECT)
1014 {
1015 bool junk_filter_needed = false;
1016 ListCell *tlist;
1017
1018 foreach(tlist, plan->targetlist)
1019 {
1020 TargetEntry *tle = (TargetEntry *) lfirst(tlist);
1021
1022 if (tle->resjunk)
1023 {
1024 junk_filter_needed = true;
1025 break;
1026 }
1027 }
1028
1030 {
1031 JunkFilter *j;
1032 TupleTableSlot *slot;
1033
1034 slot = ExecInitExtraTupleSlot(estate, NULL, &TTSOpsVirtual);
1035 j = ExecInitJunkFilter(planstate->plan->targetlist,
1036 slot);
1037 estate->es_junkFilter = j;
1038
1039 /* Want to return the cleaned tuple type */
1041 }
1042 }
1043
1044 queryDesc->tupDesc = tupType;
1045 queryDesc->planstate = planstate;
1046}
1047
1048/*
1049 * Check that a proposed result relation is a legal target for the operation
1050 *
1051 * Generally the parser and/or planner should have noticed any such mistake
1052 * already, but let's make sure.
1053 *
1054 * For INSERT ON CONFLICT, the result relation is required to support the
1055 * onConflictAction, regardless of whether a conflict actually occurs.
1056 *
1057 * For MERGE, mergeActions is the list of actions that may be performed. The
1058 * result relation is required to support every action, regardless of whether
1059 * or not they are all executed.
1060 *
1061 * Note: when changing this function, you probably also need to look at
1062 * CheckValidRowMarkRel.
1063 */
1064void
1066 OnConflictAction onConflictAction, List *mergeActions,
1068{
1069 Relation resultRel = resultRelInfo->ri_RelationDesc;
1070 FdwRoutine *fdwroutine;
1071
1072 /* Expect a fully-formed ResultRelInfo from InitResultRelInfo(). */
1073 Assert(resultRelInfo->ri_needLockTagTuple ==
1074 IsInplaceUpdateRelation(resultRel));
1075
1076 switch (resultRel->rd_rel->relkind)
1077 {
1078 case RELKIND_RELATION:
1080
1081 /*
1082 * For MERGE, check that the target relation supports each action.
1083 * For other operations, just check the operation itself.
1084 */
1085 if (operation == CMD_MERGE)
1087 CheckCmdReplicaIdentity(resultRel, action->commandType);
1088 else
1090
1091 /*
1092 * For INSERT ON CONFLICT DO UPDATE, additionally check that the
1093 * target relation supports UPDATE.
1094 */
1095 if (onConflictAction == ONCONFLICT_UPDATE)
1097 break;
1098 case RELKIND_SEQUENCE:
1099 ereport(ERROR,
1101 errmsg("cannot change sequence \"%s\"",
1102 RelationGetRelationName(resultRel))));
1103 break;
1104 case RELKIND_TOASTVALUE:
1105 ereport(ERROR,
1107 errmsg("cannot change TOAST relation \"%s\"",
1108 RelationGetRelationName(resultRel))));
1109 break;
1110 case RELKIND_VIEW:
1111
1112 /*
1113 * Okay only if there's a suitable INSTEAD OF trigger. Otherwise,
1114 * complain, but omit errdetail because we haven't got the
1115 * information handy (and given that it really shouldn't happen,
1116 * it's not worth great exertion to get).
1117 */
1120 NULL);
1121 break;
1122 case RELKIND_MATVIEW:
1124 ereport(ERROR,
1126 errmsg("cannot change materialized view \"%s\"",
1127 RelationGetRelationName(resultRel))));
1128 break;
1130 /* We don't support FOR PORTION OF FDW queries. */
1131 if (mtnode && mtnode->forPortionOf)
1132 ereport(ERROR,
1134 errmsg("foreign tables don't support FOR PORTION OF"),
1135 errdetail("\"%s\" is a foreign table.",
1136 RelationGetRelationName(resultRel)));
1137
1138 /* Okay only if the FDW supports it */
1139 fdwroutine = resultRelInfo->ri_FdwRoutine;
1140 switch (operation)
1141 {
1142 case CMD_INSERT:
1143 if (fdwroutine->ExecForeignInsert == NULL)
1144 ereport(ERROR,
1146 errmsg("cannot insert into foreign table \"%s\"",
1147 RelationGetRelationName(resultRel))));
1148 if (fdwroutine->IsForeignRelUpdatable != NULL &&
1149 (fdwroutine->IsForeignRelUpdatable(resultRel) & (1 << CMD_INSERT)) == 0)
1150 ereport(ERROR,
1152 errmsg("foreign table \"%s\" does not allow inserts",
1153 RelationGetRelationName(resultRel))));
1154 break;
1155 case CMD_UPDATE:
1156 if (fdwroutine->ExecForeignUpdate == NULL)
1157 ereport(ERROR,
1159 errmsg("cannot update foreign table \"%s\"",
1160 RelationGetRelationName(resultRel))));
1161 if (fdwroutine->IsForeignRelUpdatable != NULL &&
1162 (fdwroutine->IsForeignRelUpdatable(resultRel) & (1 << CMD_UPDATE)) == 0)
1163 ereport(ERROR,
1165 errmsg("foreign table \"%s\" does not allow updates",
1166 RelationGetRelationName(resultRel))));
1167 break;
1168 case CMD_DELETE:
1169 if (fdwroutine->ExecForeignDelete == NULL)
1170 ereport(ERROR,
1172 errmsg("cannot delete from foreign table \"%s\"",
1173 RelationGetRelationName(resultRel))));
1174 if (fdwroutine->IsForeignRelUpdatable != NULL &&
1175 (fdwroutine->IsForeignRelUpdatable(resultRel) & (1 << CMD_DELETE)) == 0)
1176 ereport(ERROR,
1178 errmsg("foreign table \"%s\" does not allow deletes",
1179 RelationGetRelationName(resultRel))));
1180 break;
1181 default:
1182 elog(ERROR, "unrecognized CmdType: %d", (int) operation);
1183 break;
1184 }
1185 break;
1186 case RELKIND_PROPGRAPH:
1187 ereport(ERROR,
1189 errmsg("cannot change property graph \"%s\"",
1190 RelationGetRelationName(resultRel))));
1191 break;
1192 default:
1193 ereport(ERROR,
1195 errmsg("cannot change relation \"%s\"",
1196 RelationGetRelationName(resultRel))));
1197 break;
1198 }
1199}
1200
1201/*
1202 * Check that a proposed rowmark target relation is a legal target
1203 *
1204 * In most cases parser and/or planner should have noticed this already, but
1205 * they don't cover all cases.
1206 */
1207static void
1209{
1210 FdwRoutine *fdwroutine;
1211
1212 switch (rel->rd_rel->relkind)
1213 {
1214 case RELKIND_RELATION:
1216 /* OK */
1217 break;
1218 case RELKIND_SEQUENCE:
1219 /* Must disallow this because we don't vacuum sequences */
1220 ereport(ERROR,
1222 errmsg("cannot lock rows in sequence \"%s\"",
1224 break;
1225 case RELKIND_TOASTVALUE:
1226 /* We could allow this, but there seems no good reason to */
1227 ereport(ERROR,
1229 errmsg("cannot lock rows in TOAST relation \"%s\"",
1231 break;
1232 case RELKIND_VIEW:
1233 /* Should not get here; planner should have expanded the view */
1234 ereport(ERROR,
1236 errmsg("cannot lock rows in view \"%s\"",
1238 break;
1239 case RELKIND_MATVIEW:
1240 /* Allow referencing a matview, but not actual locking clauses */
1241 if (markType != ROW_MARK_REFERENCE)
1242 ereport(ERROR,
1244 errmsg("cannot lock rows in materialized view \"%s\"",
1246 break;
1248 /* Okay only if the FDW supports it */
1249 fdwroutine = GetFdwRoutineForRelation(rel, false);
1250 if (fdwroutine->RefetchForeignRow == NULL)
1251 ereport(ERROR,
1253 errmsg("cannot lock rows in foreign table \"%s\"",
1255 break;
1256 case RELKIND_PROPGRAPH:
1257 /* Should not get here; rewriter should have expanded the graph */
1258 ereport(ERROR,
1260 errmsg_internal("cannot lock rows in property graph \"%s\"",
1262 break;
1263 default:
1264 ereport(ERROR,
1266 errmsg("cannot lock rows in relation \"%s\"",
1268 break;
1269 }
1270}
1271
1272/*
1273 * Initialize ResultRelInfo data for one result relation
1274 *
1275 * Caution: before Postgres 9.1, this function included the relkind checking
1276 * that's now in CheckValidResultRel, and it also did ExecOpenIndices if
1277 * appropriate. Be sure callers cover those needs.
1278 */
1279void
1284 int instrument_options)
1285{
1286 MemSet(resultRelInfo, 0, sizeof(ResultRelInfo));
1287 resultRelInfo->type = T_ResultRelInfo;
1288 resultRelInfo->ri_RangeTableIndex = resultRelationIndex;
1289 resultRelInfo->ri_RelationDesc = resultRelationDesc;
1290 resultRelInfo->ri_NumIndices = 0;
1291 resultRelInfo->ri_IndexRelationDescs = NULL;
1292 resultRelInfo->ri_IndexRelationInfo = NULL;
1293 resultRelInfo->ri_needLockTagTuple =
1295 /* make a copy so as not to depend on relcache info not changing... */
1296 resultRelInfo->ri_TrigDesc = CopyTriggerDesc(resultRelationDesc->trigdesc);
1297 if (resultRelInfo->ri_TrigDesc)
1298 {
1299 int n = resultRelInfo->ri_TrigDesc->numtriggers;
1300
1301 resultRelInfo->ri_TrigFunctions = (FmgrInfo *)
1303 resultRelInfo->ri_TrigWhenExprs = (ExprState **)
1305 if (instrument_options)
1306 resultRelInfo->ri_TrigInstrument = InstrAllocTrigger(n, instrument_options);
1307 }
1308 else
1309 {
1310 resultRelInfo->ri_TrigFunctions = NULL;
1311 resultRelInfo->ri_TrigWhenExprs = NULL;
1312 resultRelInfo->ri_TrigInstrument = NULL;
1313 }
1314 if (resultRelationDesc->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
1316 else
1317 resultRelInfo->ri_FdwRoutine = NULL;
1318
1319 /* The following fields are set later if needed */
1320 resultRelInfo->ri_RowIdAttNo = 0;
1321 resultRelInfo->ri_extraUpdatedCols = NULL;
1322 resultRelInfo->ri_projectNew = NULL;
1323 resultRelInfo->ri_newTupleSlot = NULL;
1324 resultRelInfo->ri_oldTupleSlot = NULL;
1325 resultRelInfo->ri_projectNewInfoValid = false;
1326 resultRelInfo->ri_FdwState = NULL;
1327 resultRelInfo->ri_usesFdwDirectModify = false;
1328 resultRelInfo->ri_CheckConstraintExprs = NULL;
1330 resultRelInfo->ri_GeneratedExprsI = NULL;
1331 resultRelInfo->ri_GeneratedExprsU = NULL;
1332 resultRelInfo->ri_projectReturning = NULL;
1333 resultRelInfo->ri_onConflictArbiterIndexes = NIL;
1334 resultRelInfo->ri_onConflict = NULL;
1335 resultRelInfo->ri_forPortionOf = NULL;
1336 resultRelInfo->ri_ReturningSlot = NULL;
1337 resultRelInfo->ri_TrigOldSlot = NULL;
1338 resultRelInfo->ri_TrigNewSlot = NULL;
1339 resultRelInfo->ri_AllNullSlot = NULL;
1340 resultRelInfo->ri_MergeActions[MERGE_WHEN_MATCHED] = NIL;
1343 resultRelInfo->ri_MergeJoinCondition = NULL;
1344
1345 /*
1346 * Only ExecInitPartitionInfo() and ExecInitPartitionDispatchInfo() pass
1347 * non-NULL partition_root_rri. For child relations that are part of the
1348 * initial query rather than being dynamically added by tuple routing,
1349 * this field is filled in ExecInitModifyTable().
1350 */
1352 /* Set by ExecGetRootToChildMap */
1353 resultRelInfo->ri_RootToChildMap = NULL;
1354 resultRelInfo->ri_RootToChildMapValid = false;
1355 /* Set by ExecInitRoutingInfo */
1356 resultRelInfo->ri_PartitionTupleSlot = NULL;
1357 resultRelInfo->ri_ChildToRootMap = NULL;
1358 resultRelInfo->ri_ChildToRootMapValid = false;
1359 resultRelInfo->ri_CopyMultiInsertBuffer = NULL;
1360}
1361
1362/*
1363 * ExecGetTriggerResultRel
1364 * Get a ResultRelInfo for a trigger target relation.
1365 *
1366 * Most of the time, triggers are fired on one of the result relations of the
1367 * query, and so we can just return a suitable one we already made and stored
1368 * in the es_opened_result_relations or es_tuple_routing_result_relations
1369 * Lists.
1370 *
1371 * However, it is sometimes necessary to fire triggers on other relations;
1372 * this happens mainly when an RI update trigger queues additional triggers
1373 * on other relations, which will be processed in the context of the outer
1374 * query. For efficiency's sake, we want to have a ResultRelInfo for those
1375 * triggers too; that can avoid repeated re-opening of the relation. (It
1376 * also provides a way for EXPLAIN ANALYZE to report the runtimes of such
1377 * triggers.) So we make additional ResultRelInfo's as needed, and save them
1378 * in es_trig_target_relations.
1379 */
1383{
1385 ListCell *l;
1386 Relation rel;
1387 MemoryContext oldcontext;
1388
1389 /*
1390 * Before creating a new ResultRelInfo, check if we've already made and
1391 * cached one for this relation. We must ensure that the given
1392 * 'rootRelInfo' matches the one stored in the cached ResultRelInfo as
1393 * trigger handling for partitions can result in mixed requirements for
1394 * what ri_RootResultRelInfo is set to.
1395 */
1396
1397 /* Search through the query result relations */
1398 foreach(l, estate->es_opened_result_relations)
1399 {
1400 rInfo = lfirst(l);
1401 if (RelationGetRelid(rInfo->ri_RelationDesc) == relid &&
1402 rInfo->ri_RootResultRelInfo == rootRelInfo)
1403 return rInfo;
1404 }
1405
1406 /*
1407 * Search through the result relations that were created during tuple
1408 * routing, if any.
1409 */
1410 foreach(l, estate->es_tuple_routing_result_relations)
1411 {
1412 rInfo = (ResultRelInfo *) lfirst(l);
1413 if (RelationGetRelid(rInfo->ri_RelationDesc) == relid &&
1414 rInfo->ri_RootResultRelInfo == rootRelInfo)
1415 return rInfo;
1416 }
1417
1418 /* Nope, but maybe we already made an extra ResultRelInfo for it */
1419 foreach(l, estate->es_trig_target_relations)
1420 {
1421 rInfo = (ResultRelInfo *) lfirst(l);
1422 if (RelationGetRelid(rInfo->ri_RelationDesc) == relid &&
1423 rInfo->ri_RootResultRelInfo == rootRelInfo)
1424 return rInfo;
1425 }
1426 /* Nope, so we need a new one */
1427
1428 /*
1429 * Open the target relation's relcache entry. We assume that an
1430 * appropriate lock is still held by the backend from whenever the trigger
1431 * event got queued, so we need take no new lock here. Also, we need not
1432 * recheck the relkind, so no need for CheckValidResultRel.
1433 */
1434 rel = table_open(relid, NoLock);
1435
1436 /*
1437 * Make the new entry in the right context.
1438 */
1439 oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1442 rel,
1443 0, /* dummy rangetable index */
1445 estate->es_instrument);
1446 estate->es_trig_target_relations =
1448 MemoryContextSwitchTo(oldcontext);
1449
1450 /*
1451 * Currently, we don't need any index information in ResultRelInfos used
1452 * only for triggers, so no need to call ExecOpenIndices.
1453 */
1454
1455 return rInfo;
1456}
1457
1458/*
1459 * Return the ancestor relations of a given leaf partition result relation
1460 * up to and including the query's root target relation.
1461 *
1462 * These work much like the ones opened by ExecGetTriggerResultRel, except
1463 * that we need to keep them in a separate list.
1464 *
1465 * These are closed by ExecCloseResultRelations.
1466 */
1467List *
1469{
1471 Relation partRel = resultRelInfo->ri_RelationDesc;
1473
1474 if (!partRel->rd_rel->relispartition)
1475 elog(ERROR, "cannot find ancestors of a non-partition result relation");
1477 rootRelOid = RelationGetRelid(rootRelInfo->ri_RelationDesc);
1478 if (resultRelInfo->ri_ancestorResultRels == NIL)
1479 {
1480 ListCell *lc;
1483
1484 foreach(lc, oids)
1485 {
1489
1490 /*
1491 * Ignore the root ancestor here, and use ri_RootResultRelInfo
1492 * (below) for it instead. Also, we stop climbing up the
1493 * hierarchy when we find the table that was mentioned in the
1494 * query.
1495 */
1496 if (ancOid == rootRelOid)
1497 break;
1498
1499 /*
1500 * All ancestors up to the root target relation must have been
1501 * locked by the planner or AcquireExecutorLocks().
1502 */
1505
1506 /* dummy rangetable index */
1508 estate->es_instrument);
1510 }
1512 resultRelInfo->ri_ancestorResultRels = ancResultRels;
1513 }
1514
1515 /* We must have found some ancestor */
1516 Assert(resultRelInfo->ri_ancestorResultRels != NIL);
1517
1518 return resultRelInfo->ri_ancestorResultRels;
1519}
1520
1521/* ----------------------------------------------------------------
1522 * ExecPostprocessPlan
1523 *
1524 * Give plan nodes a final chance to execute before shutdown
1525 * ----------------------------------------------------------------
1526 */
1527static void
1529{
1530 ListCell *lc;
1531
1532 /*
1533 * Make sure nodes run forward.
1534 */
1536
1537 /*
1538 * Run any secondary ModifyTable nodes to completion, in case the main
1539 * query did not fetch all rows from them. (We do this to ensure that
1540 * such nodes have predictable results.)
1541 */
1542 foreach(lc, estate->es_auxmodifytables)
1543 {
1544 PlanState *ps = (PlanState *) lfirst(lc);
1545
1546 for (;;)
1547 {
1548 TupleTableSlot *slot;
1549
1550 /* Reset the per-output-tuple exprcontext each time */
1552
1553 slot = ExecProcNode(ps);
1554
1555 if (TupIsNull(slot))
1556 break;
1557 }
1558 }
1559}
1560
1561/* ----------------------------------------------------------------
1562 * ExecEndPlan
1563 *
1564 * Cleans up the query plan -- closes files and frees up storage
1565 *
1566 * NOTE: we are no longer very worried about freeing storage per se
1567 * in this code; FreeExecutorState should be guaranteed to release all
1568 * memory that needs to be released. What we are worried about doing
1569 * is closing relations and dropping buffer pins. Thus, for example,
1570 * tuple tables must be cleared or dropped to ensure pins are released.
1571 * ----------------------------------------------------------------
1572 */
1573static void
1574ExecEndPlan(PlanState *planstate, EState *estate)
1575{
1576 ListCell *l;
1577
1578 /*
1579 * shut down the node-type-specific query processing
1580 */
1581 ExecEndNode(planstate);
1582
1583 /*
1584 * for subplans too
1585 */
1586 foreach(l, estate->es_subplanstates)
1587 {
1589
1591 }
1592
1593 /*
1594 * destroy the executor's tuple table. Actually we only care about
1595 * releasing buffer pins and tupdesc refcounts; there's no need to pfree
1596 * the TupleTableSlots, since the containing memory context is about to go
1597 * away anyway.
1598 */
1599 ExecResetTupleTable(estate->es_tupleTable, false);
1600
1601 /*
1602 * Close any Relations that have been opened for range table entries or
1603 * result relations.
1604 */
1607}
1608
1609/*
1610 * Close any relations that have been opened for ResultRelInfos.
1611 */
1612void
1614{
1615 ListCell *l;
1616
1617 /*
1618 * close indexes of result relation(s) if any. (Rels themselves are
1619 * closed in ExecCloseRangeTableRelations())
1620 *
1621 * In addition, close the stub RTs that may be in each resultrel's
1622 * ri_ancestorResultRels.
1623 */
1624 foreach(l, estate->es_opened_result_relations)
1625 {
1626 ResultRelInfo *resultRelInfo = lfirst(l);
1627 ListCell *lc;
1628
1629 ExecCloseIndices(resultRelInfo);
1630 foreach(lc, resultRelInfo->ri_ancestorResultRels)
1631 {
1633
1634 /*
1635 * Ancestors with RTI > 0 (should only be the root ancestor) are
1636 * closed by ExecCloseRangeTableRelations.
1637 */
1638 if (rInfo->ri_RangeTableIndex > 0)
1639 continue;
1640
1641 table_close(rInfo->ri_RelationDesc, NoLock);
1642 }
1643 }
1644
1645 /* Close any relations that have been opened by ExecGetTriggerResultRel(). */
1646 foreach(l, estate->es_trig_target_relations)
1647 {
1648 ResultRelInfo *resultRelInfo = (ResultRelInfo *) lfirst(l);
1649
1650 /*
1651 * Assert this is a "dummy" ResultRelInfo, see above. Otherwise we
1652 * might be issuing a duplicate close against a Relation opened by
1653 * ExecGetRangeTableRelation.
1654 */
1655 Assert(resultRelInfo->ri_RangeTableIndex == 0);
1656
1657 /*
1658 * Since ExecGetTriggerResultRel doesn't call ExecOpenIndices for
1659 * these rels, we needn't call ExecCloseIndices either.
1660 */
1661 Assert(resultRelInfo->ri_NumIndices == 0);
1662
1663 table_close(resultRelInfo->ri_RelationDesc, NoLock);
1664 }
1665}
1666
1667/*
1668 * Close all relations opened by ExecGetRangeTableRelation().
1669 *
1670 * We do not release any locks we might hold on those rels.
1671 */
1672void
1674{
1675 int i;
1676
1677 for (i = 0; i < estate->es_range_table_size; i++)
1678 {
1679 if (estate->es_relations[i])
1680 table_close(estate->es_relations[i], NoLock);
1681 }
1682}
1683
1684/* ----------------------------------------------------------------
1685 * ExecutePlan
1686 *
1687 * Processes the query plan until we have retrieved 'numberTuples' tuples,
1688 * moving in the specified direction.
1689 *
1690 * Runs to completion if numberTuples is 0
1691 * ----------------------------------------------------------------
1692 */
1693static void
1696 bool sendTuples,
1698 ScanDirection direction,
1699 DestReceiver *dest)
1700{
1701 EState *estate = queryDesc->estate;
1702 PlanState *planstate = queryDesc->planstate;
1703 bool use_parallel_mode;
1704 TupleTableSlot *slot;
1706
1707 /*
1708 * initialize local variables
1709 */
1711
1712 /*
1713 * Set the direction.
1714 */
1715 estate->es_direction = direction;
1716
1717 /*
1718 * Set up parallel mode if appropriate.
1719 *
1720 * Parallel mode only supports complete execution of a plan. If we've
1721 * already partially executed it, or if the caller asks us to exit early,
1722 * we must force the plan to run without parallelism.
1723 */
1724 if (queryDesc->already_executed || numberTuples != 0)
1725 use_parallel_mode = false;
1726 else
1728 queryDesc->already_executed = true;
1729
1733
1734 /*
1735 * Loop until we've processed the proper number of tuples from the plan.
1736 */
1737 for (;;)
1738 {
1739 /* Reset the per-output-tuple exprcontext */
1741
1742 /*
1743 * Execute the plan and obtain a tuple
1744 */
1745 slot = ExecProcNode(planstate);
1746
1747 /*
1748 * if the tuple is null, then we assume there is nothing more to
1749 * process so we just end the loop...
1750 */
1751 if (TupIsNull(slot))
1752 break;
1753
1754 /*
1755 * If we have a junk filter, then project a new tuple with the junk
1756 * removed.
1757 *
1758 * Store this new "clean" tuple in the junkfilter's resultSlot.
1759 * (Formerly, we stored it back over the "dirty" tuple, which is WRONG
1760 * because that tuple slot has the wrong descriptor.)
1761 */
1762 if (estate->es_junkFilter != NULL)
1763 slot = ExecFilterJunk(estate->es_junkFilter, slot);
1764
1765 /*
1766 * If we are supposed to send the tuple somewhere, do so. (In
1767 * practice, this is probably always the case at this point.)
1768 */
1769 if (sendTuples)
1770 {
1771 /*
1772 * If we are not able to send the tuple, we assume the destination
1773 * has closed and no more tuples can be sent. If that's the case,
1774 * end the loop.
1775 */
1776 if (!dest->receiveSlot(slot, dest))
1777 break;
1778 }
1779
1780 /*
1781 * Count tuples processed, if this is a SELECT. (For other operation
1782 * types, the ModifyTable plan node must count the appropriate
1783 * events.)
1784 */
1785 if (operation == CMD_SELECT)
1786 (estate->es_processed)++;
1787
1788 /*
1789 * check our tuple count.. if we've processed the proper number then
1790 * quit, else loop again and process more tuples. Zero numberTuples
1791 * means no limit.
1792 */
1795 break;
1796 }
1797
1798 /*
1799 * If we know we won't need to back up, we can release resources at this
1800 * point.
1801 */
1802 if (!(estate->es_top_eflags & EXEC_FLAG_BACKWARD))
1803 ExecShutdownNode(planstate);
1804
1807}
1808
1809
1810/*
1811 * ExecRelCheck --- check that tuple meets check constraints for result relation
1812 *
1813 * Returns NULL if OK, else name of failed check constraint
1814 */
1815static const char *
1817 TupleTableSlot *slot, EState *estate)
1818{
1819 Relation rel = resultRelInfo->ri_RelationDesc;
1820 int ncheck = rel->rd_att->constr->num_check;
1821 ConstrCheck *check = rel->rd_att->constr->check;
1822 ExprContext *econtext;
1824
1825 /*
1826 * CheckNNConstraintFetch let this pass with only a warning, but now we
1827 * should fail rather than possibly failing to enforce an important
1828 * constraint.
1829 */
1830 if (ncheck != rel->rd_rel->relchecks)
1831 elog(ERROR, "%d pg_constraint record(s) missing for relation \"%s\"",
1832 rel->rd_rel->relchecks - ncheck, RelationGetRelationName(rel));
1833
1834 /*
1835 * If first time through for this result relation, build expression
1836 * nodetrees for rel's constraint expressions. Keep them in the per-query
1837 * memory context so they'll survive throughout the query.
1838 */
1839 if (resultRelInfo->ri_CheckConstraintExprs == NULL)
1840 {
1842 resultRelInfo->ri_CheckConstraintExprs = palloc0_array(ExprState *, ncheck);
1843 for (int i = 0; i < ncheck; i++)
1844 {
1846
1847 /* Skip not enforced constraint */
1848 if (!check[i].ccenforced)
1849 continue;
1850
1851 checkconstr = stringToNode(check[i].ccbin);
1853 resultRelInfo->ri_CheckConstraintExprs[i] =
1855 }
1857 }
1858
1859 /*
1860 * We will use the EState's per-tuple context for evaluating constraint
1861 * expressions (creating it if it's not already there).
1862 */
1863 econtext = GetPerTupleExprContext(estate);
1864
1865 /* Arrange for econtext's scan tuple to be the tuple under test */
1866 econtext->ecxt_scantuple = slot;
1867
1868 /* And evaluate the constraints */
1869 for (int i = 0; i < ncheck; i++)
1870 {
1872
1873 /*
1874 * NOTE: SQL specifies that a NULL result from a constraint expression
1875 * is not to be treated as a failure. Therefore, use ExecCheck not
1876 * ExecQual.
1877 */
1878 if (checkconstr && !ExecCheck(checkconstr, econtext))
1879 return check[i].ccname;
1880 }
1881
1882 /* NULL result means no error */
1883 return NULL;
1884}
1885
1886/*
1887 * ExecPartitionCheck --- check that tuple meets the partition constraint.
1888 *
1889 * Returns true if it meets the partition constraint. If the constraint
1890 * fails and we're asked to emit an error, do so and don't return; otherwise
1891 * return false.
1892 */
1893bool
1895 EState *estate, bool emitError)
1896{
1897 ExprContext *econtext;
1898 bool success;
1899
1900 /*
1901 * If first time through, build expression state tree for the partition
1902 * check expression. (In the corner case where the partition check
1903 * expression is empty, ie there's a default partition and nothing else,
1904 * we'll be fooled into executing this code each time through. But it's
1905 * pretty darn cheap in that case, so we don't worry about it.)
1906 */
1907 if (resultRelInfo->ri_PartitionCheckExpr == NULL)
1908 {
1909 /*
1910 * Ensure that the qual tree and prepared expression are in the
1911 * query-lifespan context.
1912 */
1914 List *qual = RelationGetPartitionQual(resultRelInfo->ri_RelationDesc);
1915
1916 resultRelInfo->ri_PartitionCheckExpr = ExecPrepareCheck(qual, estate);
1918 }
1919
1920 /*
1921 * We will use the EState's per-tuple context for evaluating constraint
1922 * expressions (creating it if it's not already there).
1923 */
1924 econtext = GetPerTupleExprContext(estate);
1925
1926 /* Arrange for econtext's scan tuple to be the tuple under test */
1927 econtext->ecxt_scantuple = slot;
1928
1929 /*
1930 * As in case of the cataloged constraints, we treat a NULL result as
1931 * success here, not a failure.
1932 */
1933 success = ExecCheck(resultRelInfo->ri_PartitionCheckExpr, econtext);
1934
1935 /* if asked to emit error, don't actually return on failure */
1936 if (!success && emitError)
1937 ExecPartitionCheckEmitError(resultRelInfo, slot, estate);
1938
1939 return success;
1940}
1941
1942/*
1943 * ExecPartitionCheckEmitError - Form and emit an error message after a failed
1944 * partition constraint check.
1945 */
1946void
1948 TupleTableSlot *slot,
1949 EState *estate)
1950{
1952 TupleDesc tupdesc;
1953 char *val_desc;
1955
1956 /*
1957 * If the tuple has been routed, it's been converted to the partition's
1958 * rowtype, which might differ from the root table's. We must convert it
1959 * back to the root table's rowtype so that val_desc in the error message
1960 * matches the input tuple.
1961 */
1962 if (resultRelInfo->ri_RootResultRelInfo)
1963 {
1964 ResultRelInfo *rootrel = resultRelInfo->ri_RootResultRelInfo;
1966 AttrMap *map;
1967
1968 root_relid = RelationGetRelid(rootrel->ri_RelationDesc);
1969 tupdesc = RelationGetDescr(rootrel->ri_RelationDesc);
1970
1972 /* a reverse map */
1973 map = build_attrmap_by_name_if_req(old_tupdesc, tupdesc, false);
1974
1975 /*
1976 * Partition-specific slot's tupdesc can't be changed, so allocate a
1977 * new one.
1978 */
1979 if (map != NULL)
1980 slot = execute_attr_map_slot(map, slot,
1981 MakeTupleTableSlot(tupdesc, &TTSOpsVirtual, 0));
1983 ExecGetUpdatedCols(rootrel, estate));
1984 }
1985 else
1986 {
1988 tupdesc = RelationGetDescr(resultRelInfo->ri_RelationDesc);
1989 modifiedCols = bms_union(ExecGetInsertedCols(resultRelInfo, estate),
1990 ExecGetUpdatedCols(resultRelInfo, estate));
1991 }
1992
1994 slot,
1995 tupdesc,
1997 64);
1998 ereport(ERROR,
2000 errmsg("new row for relation \"%s\" violates partition constraint",
2002 val_desc ? errdetail("Failing row contains %s.", val_desc) : 0,
2003 errtable(resultRelInfo->ri_RelationDesc)));
2004}
2005
2006/*
2007 * ExecConstraints - check constraints of the tuple in 'slot'
2008 *
2009 * This checks the traditional NOT NULL and check constraints.
2010 *
2011 * The partition constraint is *NOT* checked.
2012 *
2013 * Note: 'slot' contains the tuple to check the constraints of, which may
2014 * have been converted from the original input tuple after tuple routing.
2015 * 'resultRelInfo' is the final result relation, after tuple routing.
2016 */
2017void
2019 TupleTableSlot *slot, EState *estate)
2020{
2021 Relation rel = resultRelInfo->ri_RelationDesc;
2022 TupleDesc tupdesc = RelationGetDescr(rel);
2023 TupleConstr *constr = tupdesc->constr;
2026
2027 Assert(constr); /* we should not be called otherwise */
2028
2029 /*
2030 * Verify not-null constraints.
2031 *
2032 * Not-null constraints on virtual generated columns are collected and
2033 * checked separately below.
2034 */
2035 if (constr->has_not_null)
2036 {
2037 for (AttrNumber attnum = 1; attnum <= tupdesc->natts; attnum++)
2038 {
2039 Form_pg_attribute att = TupleDescAttr(tupdesc, attnum - 1);
2040
2041 if (att->attnotnull && att->attgenerated == ATTRIBUTE_GENERATED_VIRTUAL)
2043 else if (att->attnotnull && slot_attisnull(slot, attnum))
2044 ReportNotNullViolationError(resultRelInfo, slot, estate, attnum);
2045 }
2046 }
2047
2048 /*
2049 * Verify not-null constraints on virtual generated column, if any.
2050 */
2052 {
2054
2055 attnum = ExecRelGenVirtualNotNull(resultRelInfo, slot, estate,
2058 ReportNotNullViolationError(resultRelInfo, slot, estate, attnum);
2059 }
2060
2061 /*
2062 * Verify check constraints.
2063 */
2064 if (rel->rd_rel->relchecks > 0)
2065 {
2066 const char *failed;
2067
2068 if ((failed = ExecRelCheck(resultRelInfo, slot, estate)) != NULL)
2069 {
2070 char *val_desc;
2071 Relation orig_rel = rel;
2072
2073 /*
2074 * If the tuple has been routed, it's been converted to the
2075 * partition's rowtype, which might differ from the root table's.
2076 * We must convert it back to the root table's rowtype so that
2077 * val_desc shown error message matches the input tuple.
2078 */
2079 if (resultRelInfo->ri_RootResultRelInfo)
2080 {
2081 ResultRelInfo *rootrel = resultRelInfo->ri_RootResultRelInfo;
2083 AttrMap *map;
2084
2085 tupdesc = RelationGetDescr(rootrel->ri_RelationDesc);
2086 /* a reverse map */
2088 tupdesc,
2089 false);
2090
2091 /*
2092 * Partition-specific slot's tupdesc can't be changed, so
2093 * allocate a new one.
2094 */
2095 if (map != NULL)
2096 slot = execute_attr_map_slot(map, slot,
2097 MakeTupleTableSlot(tupdesc, &TTSOpsVirtual, 0));
2099 ExecGetUpdatedCols(rootrel, estate));
2100 rel = rootrel->ri_RelationDesc;
2101 }
2102 else
2103 modifiedCols = bms_union(ExecGetInsertedCols(resultRelInfo, estate),
2104 ExecGetUpdatedCols(resultRelInfo, estate));
2106 slot,
2107 tupdesc,
2109 64);
2110 ereport(ERROR,
2112 errmsg("new row for relation \"%s\" violates check constraint \"%s\"",
2114 val_desc ? errdetail("Failing row contains %s.", val_desc) : 0,
2115 errtableconstraint(orig_rel, failed)));
2116 }
2117 }
2118}
2119
2120/*
2121 * Verify not-null constraints on virtual generated columns of the given
2122 * tuple slot.
2123 *
2124 * Return value of InvalidAttrNumber means all not-null constraints on virtual
2125 * generated columns are satisfied. A return value > 0 means a not-null
2126 * violation happened for that attribute.
2127 *
2128 * notnull_virtual_attrs is the list of the attnums of virtual generated column with
2129 * not-null constraints.
2130 */
2134{
2135 Relation rel = resultRelInfo->ri_RelationDesc;
2136 ExprContext *econtext;
2138
2139 /*
2140 * We implement this by building a NullTest node for each virtual
2141 * generated column, which we cache in resultRelInfo, and running those
2142 * through ExecCheck().
2143 */
2144 if (resultRelInfo->ri_GenVirtualNotNullConstraintExprs == NULL)
2145 {
2149
2151 {
2154
2155 /* "generated_expression IS NOT NULL" check. */
2158 nnulltest->nulltesttype = IS_NOT_NULL;
2159 nnulltest->argisrow = false;
2160 nnulltest->location = -1;
2161
2162 resultRelInfo->ri_GenVirtualNotNullConstraintExprs[i] =
2163 ExecPrepareExpr((Expr *) nnulltest, estate);
2164 }
2166 }
2167
2168 /*
2169 * We will use the EState's per-tuple context for evaluating virtual
2170 * generated column not null constraint expressions (creating it if it's
2171 * not already there).
2172 */
2173 econtext = GetPerTupleExprContext(estate);
2174
2175 /* Arrange for econtext's scan tuple to be the tuple under test */
2176 econtext->ecxt_scantuple = slot;
2177
2178 /* And evaluate the check constraints for virtual generated column */
2180 {
2182 ExprState *exprstate = resultRelInfo->ri_GenVirtualNotNullConstraintExprs[i];
2183
2184 Assert(exprstate != NULL);
2185 if (!ExecCheck(exprstate, econtext))
2186 return attnum;
2187 }
2188
2189 /* InvalidAttrNumber result means no error */
2190 return InvalidAttrNumber;
2191}
2192
2193/*
2194 * Report a violation of a not-null constraint that was already detected.
2195 */
2196static void
2198 EState *estate, int attnum)
2199{
2201 char *val_desc;
2202 Relation rel = resultRelInfo->ri_RelationDesc;
2203 Relation orig_rel = rel;
2204 TupleDesc tupdesc = RelationGetDescr(rel);
2206 Form_pg_attribute att = TupleDescAttr(tupdesc, attnum - 1);
2207
2208 Assert(attnum > 0);
2209
2210 /*
2211 * If the tuple has been routed, it's been converted to the partition's
2212 * rowtype, which might differ from the root table's. We must convert it
2213 * back to the root table's rowtype so that val_desc shown error message
2214 * matches the input tuple.
2215 */
2216 if (resultRelInfo->ri_RootResultRelInfo)
2217 {
2218 ResultRelInfo *rootrel = resultRelInfo->ri_RootResultRelInfo;
2219 AttrMap *map;
2220
2221 tupdesc = RelationGetDescr(rootrel->ri_RelationDesc);
2222 /* a reverse map */
2224 tupdesc,
2225 false);
2226
2227 /*
2228 * Partition-specific slot's tupdesc can't be changed, so allocate a
2229 * new one.
2230 */
2231 if (map != NULL)
2232 slot = execute_attr_map_slot(map, slot,
2233 MakeTupleTableSlot(tupdesc, &TTSOpsVirtual, 0));
2235 ExecGetUpdatedCols(rootrel, estate));
2236 rel = rootrel->ri_RelationDesc;
2237 }
2238 else
2239 modifiedCols = bms_union(ExecGetInsertedCols(resultRelInfo, estate),
2240 ExecGetUpdatedCols(resultRelInfo, estate));
2241
2243 slot,
2244 tupdesc,
2246 64);
2247 ereport(ERROR,
2249 errmsg("null value in column \"%s\" of relation \"%s\" violates not-null constraint",
2250 NameStr(att->attname),
2252 val_desc ? errdetail("Failing row contains %s.", val_desc) : 0,
2254}
2255
2256/*
2257 * ExecWithCheckOptions -- check that tuple satisfies any WITH CHECK OPTIONs
2258 * of the specified kind.
2259 *
2260 * Note that this needs to be called multiple times to ensure that all kinds of
2261 * WITH CHECK OPTIONs are handled (both those from views which have the WITH
2262 * CHECK OPTION set and from row-level security policies). See ExecInsert()
2263 * and ExecUpdate().
2264 */
2265void
2267 TupleTableSlot *slot, EState *estate)
2268{
2269 Relation rel = resultRelInfo->ri_RelationDesc;
2270 TupleDesc tupdesc = RelationGetDescr(rel);
2271 ExprContext *econtext;
2272 ListCell *l1,
2273 *l2;
2274
2275 /*
2276 * We will use the EState's per-tuple context for evaluating constraint
2277 * expressions (creating it if it's not already there).
2278 */
2279 econtext = GetPerTupleExprContext(estate);
2280
2281 /* Arrange for econtext's scan tuple to be the tuple under test */
2282 econtext->ecxt_scantuple = slot;
2283
2284 /* Check each of the constraints */
2285 forboth(l1, resultRelInfo->ri_WithCheckOptions,
2286 l2, resultRelInfo->ri_WithCheckOptionExprs)
2287 {
2289 ExprState *wcoExpr = (ExprState *) lfirst(l2);
2290
2291 /*
2292 * Skip any WCOs which are not the kind we are looking for at this
2293 * time.
2294 */
2295 if (wco->kind != kind)
2296 continue;
2297
2298 /*
2299 * WITH CHECK OPTION checks are intended to ensure that the new tuple
2300 * is visible (in the case of a view) or that it passes the
2301 * 'with-check' policy (in the case of row security). If the qual
2302 * evaluates to NULL or FALSE, then the new tuple won't be included in
2303 * the view or doesn't pass the 'with-check' policy for the table.
2304 */
2305 if (!ExecQual(wcoExpr, econtext))
2306 {
2307 char *val_desc;
2309
2310 switch (wco->kind)
2311 {
2312 /*
2313 * For WITH CHECK OPTIONs coming from views, we might be
2314 * able to provide the details on the row, depending on
2315 * the permissions on the relation (that is, if the user
2316 * could view it directly anyway). For RLS violations, we
2317 * don't include the data since we don't know if the user
2318 * should be able to view the tuple as that depends on the
2319 * USING policy.
2320 */
2321 case WCO_VIEW_CHECK:
2322 /* See the comment in ExecConstraints(). */
2323 if (resultRelInfo->ri_RootResultRelInfo)
2324 {
2325 ResultRelInfo *rootrel = resultRelInfo->ri_RootResultRelInfo;
2327 AttrMap *map;
2328
2329 tupdesc = RelationGetDescr(rootrel->ri_RelationDesc);
2330 /* a reverse map */
2332 tupdesc,
2333 false);
2334
2335 /*
2336 * Partition-specific slot's tupdesc can't be changed,
2337 * so allocate a new one.
2338 */
2339 if (map != NULL)
2340 slot = execute_attr_map_slot(map, slot,
2341 MakeTupleTableSlot(tupdesc, &TTSOpsVirtual, 0));
2342
2344 ExecGetUpdatedCols(rootrel, estate));
2345 rel = rootrel->ri_RelationDesc;
2346 }
2347 else
2348 modifiedCols = bms_union(ExecGetInsertedCols(resultRelInfo, estate),
2349 ExecGetUpdatedCols(resultRelInfo, estate));
2351 slot,
2352 tupdesc,
2354 64);
2355
2356 ereport(ERROR,
2358 errmsg("new row violates check option for view \"%s\"",
2359 wco->relname),
2360 val_desc ? errdetail("Failing row contains %s.",
2361 val_desc) : 0));
2362 break;
2365 if (wco->polname != NULL)
2366 ereport(ERROR,
2368 errmsg("new row violates row-level security policy \"%s\" for table \"%s\"",
2369 wco->polname, wco->relname)));
2370 else
2371 ereport(ERROR,
2373 errmsg("new row violates row-level security policy for table \"%s\"",
2374 wco->relname)));
2375 break;
2378 if (wco->polname != NULL)
2379 ereport(ERROR,
2381 errmsg("target row violates row-level security policy \"%s\" (USING expression) for table \"%s\"",
2382 wco->polname, wco->relname)));
2383 else
2384 ereport(ERROR,
2386 errmsg("target row violates row-level security policy (USING expression) for table \"%s\"",
2387 wco->relname)));
2388 break;
2390 if (wco->polname != NULL)
2391 ereport(ERROR,
2393 errmsg("new row violates row-level security policy \"%s\" (USING expression) for table \"%s\"",
2394 wco->polname, wco->relname)));
2395 else
2396 ereport(ERROR,
2398 errmsg("new row violates row-level security policy (USING expression) for table \"%s\"",
2399 wco->relname)));
2400 break;
2401 default:
2402 elog(ERROR, "unrecognized WCO kind: %u", wco->kind);
2403 break;
2404 }
2405 }
2406 }
2407}
2408
2409/*
2410 * ExecBuildSlotValueDescription -- construct a string representing a tuple
2411 *
2412 * This is intentionally very similar to BuildIndexValueDescription, but
2413 * unlike that function, we truncate long field values (to at most maxfieldlen
2414 * bytes). That seems necessary here since heap field values could be very
2415 * long, whereas index entries typically aren't so wide.
2416 *
2417 * Also, unlike the case with index entries, we need to be prepared to ignore
2418 * dropped columns. We used to use the slot's tuple descriptor to decode the
2419 * data, but the slot's descriptor doesn't identify dropped columns, so we
2420 * now need to be passed the relation's descriptor.
2421 *
2422 * Note that, like BuildIndexValueDescription, if the user does not have
2423 * permission to view any of the columns involved, a NULL is returned. Unlike
2424 * BuildIndexValueDescription, if the user has access to view a subset of the
2425 * column involved, that subset will be returned with a key identifying which
2426 * columns they are.
2427 */
2428char *
2430 TupleTableSlot *slot,
2431 TupleDesc tupdesc,
2433 int maxfieldlen)
2434{
2437 bool write_comma = false;
2438 bool write_comma_collist = false;
2439 int i;
2441 bool table_perm = false;
2442 bool any_perm = false;
2443
2444 /*
2445 * Check if RLS is enabled and should be active for the relation; if so,
2446 * then don't return anything. Otherwise, go through normal permission
2447 * checks.
2448 */
2449 if (check_enable_rls(reloid, InvalidOid, true) == RLS_ENABLED)
2450 return NULL;
2451
2453
2455
2456 /*
2457 * Check if the user has permissions to see the row. Table-level SELECT
2458 * allows access to all columns. If the user does not have table-level
2459 * SELECT then we check each column and include those the user has SELECT
2460 * rights on. Additionally, we always include columns the user provided
2461 * data for.
2462 */
2464 if (aclresult != ACLCHECK_OK)
2465 {
2466 /* Set up the buffer for the column list */
2469 }
2470 else
2471 table_perm = any_perm = true;
2472
2473 /* Make sure the tuple is fully deconstructed */
2474 slot_getallattrs(slot);
2475
2476 for (i = 0; i < tupdesc->natts; i++)
2477 {
2478 bool column_perm = false;
2479 char *val;
2480 int vallen;
2481 Form_pg_attribute att = TupleDescAttr(tupdesc, i);
2482
2483 /* ignore dropped columns */
2484 if (att->attisdropped)
2485 continue;
2486
2487 if (!table_perm)
2488 {
2489 /*
2490 * No table-level SELECT, so need to make sure they either have
2491 * SELECT rights on the column or that they have provided the data
2492 * for the column. If not, omit this column from the error
2493 * message.
2494 */
2495 aclresult = pg_attribute_aclcheck(reloid, att->attnum,
2499 {
2500 column_perm = any_perm = true;
2501
2504 else
2505 write_comma_collist = true;
2506
2507 appendStringInfoString(&collist, NameStr(att->attname));
2508 }
2509 }
2510
2511 if (table_perm || column_perm)
2512 {
2513 if (att->attgenerated == ATTRIBUTE_GENERATED_VIRTUAL)
2514 val = "virtual";
2515 else if (slot->tts_isnull[i])
2516 val = "null";
2517 else
2518 {
2519 Oid foutoid;
2520 bool typisvarlena;
2521
2522 getTypeOutputInfo(att->atttypid,
2523 &foutoid, &typisvarlena);
2525 }
2526
2527 if (write_comma)
2529 else
2530 write_comma = true;
2531
2532 /* truncate if needed */
2533 vallen = strlen(val);
2534 if (vallen <= maxfieldlen)
2535 appendBinaryStringInfo(&buf, val, vallen);
2536 else
2537 {
2538 vallen = pg_mbcliplen(val, vallen, maxfieldlen);
2539 appendBinaryStringInfo(&buf, val, vallen);
2540 appendStringInfoString(&buf, "...");
2541 }
2542 }
2543 }
2544
2545 /* If we end up with zero columns being returned, then return NULL. */
2546 if (!any_perm)
2547 return NULL;
2548
2550
2551 if (!table_perm)
2552 {
2555
2556 return collist.data;
2557 }
2558
2559 return buf.data;
2560}
2561
2562
2563/*
2564 * ExecUpdateLockMode -- find the appropriate UPDATE tuple lock mode for a
2565 * given ResultRelInfo
2566 */
2569{
2571 Bitmapset *updatedCols;
2572
2573 /*
2574 * Compute lock mode to use. If columns that are part of the key have not
2575 * been modified, then we can use a weaker lock, allowing for better
2576 * concurrency.
2577 */
2578 updatedCols = ExecGetAllUpdatedCols(relinfo, estate);
2579 keyCols = RelationGetIndexAttrBitmap(relinfo->ri_RelationDesc,
2581
2582 if (bms_overlap(keyCols, updatedCols))
2583 return LockTupleExclusive;
2584
2586}
2587
2588/*
2589 * ExecFindRowMark -- find the ExecRowMark struct for given rangetable index
2590 *
2591 * If no such struct, either return NULL or throw error depending on missing_ok
2592 */
2594ExecFindRowMark(EState *estate, Index rti, bool missing_ok)
2595{
2596 if (rti > 0 && rti <= estate->es_range_table_size &&
2597 estate->es_rowmarks != NULL)
2598 {
2599 ExecRowMark *erm = estate->es_rowmarks[rti - 1];
2600
2601 if (erm)
2602 return erm;
2603 }
2604 if (!missing_ok)
2605 elog(ERROR, "failed to find ExecRowMark for rangetable index %u", rti);
2606 return NULL;
2607}
2608
2609/*
2610 * ExecBuildAuxRowMark -- create an ExecAuxRowMark struct
2611 *
2612 * Inputs are the underlying ExecRowMark struct and the targetlist of the
2613 * input plan node (not planstate node!). We need the latter to find out
2614 * the column numbers of the resjunk columns.
2615 */
2618{
2620 char resname[32];
2621
2622 aerm->rowmark = erm;
2623
2624 /* Look up the resjunk columns associated with this rowmark */
2625 if (erm->markType != ROW_MARK_COPY)
2626 {
2627 /* need ctid for all methods other than COPY */
2628 snprintf(resname, sizeof(resname), "ctid%u", erm->rowmarkId);
2629 aerm->ctidAttNo = ExecFindJunkAttributeInTlist(targetlist,
2630 resname);
2631 if (!AttributeNumberIsValid(aerm->ctidAttNo))
2632 elog(ERROR, "could not find junk %s column", resname);
2633 }
2634 else
2635 {
2636 /* need wholerow if COPY */
2637 snprintf(resname, sizeof(resname), "wholerow%u", erm->rowmarkId);
2638 aerm->wholeAttNo = ExecFindJunkAttributeInTlist(targetlist,
2639 resname);
2640 if (!AttributeNumberIsValid(aerm->wholeAttNo))
2641 elog(ERROR, "could not find junk %s column", resname);
2642 }
2643
2644 /* if child rel, need tableoid */
2645 if (erm->rti != erm->prti)
2646 {
2647 snprintf(resname, sizeof(resname), "tableoid%u", erm->rowmarkId);
2648 aerm->toidAttNo = ExecFindJunkAttributeInTlist(targetlist,
2649 resname);
2650 if (!AttributeNumberIsValid(aerm->toidAttNo))
2651 elog(ERROR, "could not find junk %s column", resname);
2652 }
2653
2654 return aerm;
2655}
2656
2657
2658/*
2659 * EvalPlanQual logic --- recheck modified tuple(s) to see if we want to
2660 * process the updated version under READ COMMITTED rules.
2661 *
2662 * See backend/executor/README for some info about how this works.
2663 */
2664
2665
2666/*
2667 * Check the updated version of a tuple to see if we want to process it under
2668 * READ COMMITTED rules.
2669 *
2670 * epqstate - state for EvalPlanQual rechecking
2671 * relation - table containing tuple
2672 * rti - rangetable index of table containing tuple
2673 * inputslot - tuple for processing - this can be the slot from
2674 * EvalPlanQualSlot() for this rel, for increased efficiency.
2675 *
2676 * This tests whether the tuple in inputslot still matches the relevant
2677 * quals. For that result to be useful, typically the input tuple has to be
2678 * last row version (otherwise the result isn't particularly useful) and
2679 * locked (otherwise the result might be out of date). That's typically
2680 * achieved by using table_tuple_lock() with the
2681 * TUPLE_LOCK_FLAG_FIND_LAST_VERSION flag.
2682 *
2683 * Returns a slot containing the new candidate update/delete tuple, or
2684 * NULL if we determine we shouldn't process the row.
2685 */
2687EvalPlanQual(EPQState *epqstate, Relation relation,
2688 Index rti, TupleTableSlot *inputslot)
2689{
2690 TupleTableSlot *slot;
2692
2693 Assert(rti > 0);
2694
2695 /*
2696 * Need to run a recheck subquery. Initialize or reinitialize EPQ state.
2697 */
2698 EvalPlanQualBegin(epqstate);
2699
2700 /*
2701 * Callers will often use the EvalPlanQualSlot to store the tuple to avoid
2702 * an unnecessary copy.
2703 */
2704 testslot = EvalPlanQualSlot(epqstate, relation, rti);
2705 if (testslot != inputslot)
2706 ExecCopySlot(testslot, inputslot);
2707
2708 /*
2709 * Mark that an EPQ tuple is available for this relation. (If there is
2710 * more than one result relation, the others remain marked as having no
2711 * tuple available.)
2712 */
2713 epqstate->relsubs_done[rti - 1] = false;
2714 epqstate->relsubs_blocked[rti - 1] = false;
2715
2716 /*
2717 * Run the EPQ query. We assume it will return at most one tuple.
2718 */
2719 slot = EvalPlanQualNext(epqstate);
2720
2721 /*
2722 * If we got a tuple, force the slot to materialize the tuple so that it
2723 * is not dependent on any local state in the EPQ query (in particular,
2724 * it's highly likely that the slot contains references to any pass-by-ref
2725 * datums that may be present in copyTuple). As with the next step, this
2726 * is to guard against early re-use of the EPQ query.
2727 */
2728 if (!TupIsNull(slot))
2729 ExecMaterializeSlot(slot);
2730
2731 /*
2732 * Clear out the test tuple, and mark that no tuple is available here.
2733 * This is needed in case the EPQ state is re-used to test a tuple for a
2734 * different target relation.
2735 */
2737 epqstate->relsubs_blocked[rti - 1] = true;
2738
2739 return slot;
2740}
2741
2742/*
2743 * EvalPlanQualInit -- initialize during creation of a plan state node
2744 * that might need to invoke EPQ processing.
2745 *
2746 * If the caller intends to use EvalPlanQual(), resultRelations should be
2747 * a list of RT indexes of potential target relations for EvalPlanQual(),
2748 * and we will arrange that the other listed relations don't return any
2749 * tuple during an EvalPlanQual() call. Otherwise resultRelations
2750 * should be NIL.
2751 *
2752 * Note: subplan/auxrowmarks can be NULL/NIL if they will be set later
2753 * with EvalPlanQualSetPlan.
2754 */
2755void
2756EvalPlanQualInit(EPQState *epqstate, EState *parentestate,
2757 Plan *subplan, List *auxrowmarks,
2758 int epqParam, List *resultRelations)
2759{
2760 Index rtsize = parentestate->es_range_table_size;
2761
2762 /* initialize data not changing over EPQState's lifetime */
2763 epqstate->parentestate = parentestate;
2764 epqstate->epqParam = epqParam;
2765 epqstate->resultRelations = resultRelations;
2766
2767 /*
2768 * Allocate space to reference a slot for each potential rti - do so now
2769 * rather than in EvalPlanQualBegin(), as done for other dynamically
2770 * allocated resources, so EvalPlanQualSlot() can be used to hold tuples
2771 * that *may* need EPQ later, without forcing the overhead of
2772 * EvalPlanQualBegin().
2773 */
2774 epqstate->tuple_table = NIL;
2776
2777 /* ... and remember data that EvalPlanQualBegin will need */
2778 epqstate->plan = subplan;
2779 epqstate->arowMarks = auxrowmarks;
2780
2781 /* ... and mark the EPQ state inactive */
2782 epqstate->origslot = NULL;
2783 epqstate->recheckestate = NULL;
2784 epqstate->recheckplanstate = NULL;
2785 epqstate->relsubs_rowmark = NULL;
2786 epqstate->relsubs_done = NULL;
2787 epqstate->relsubs_blocked = NULL;
2788}
2789
2790/*
2791 * EvalPlanQualSetPlan -- set or change subplan of an EPQState.
2792 *
2793 * We used to need this so that ModifyTable could deal with multiple subplans.
2794 * It could now be refactored out of existence.
2795 */
2796void
2798{
2799 /* If we have a live EPQ query, shut it down */
2800 EvalPlanQualEnd(epqstate);
2801 /* And set/change the plan pointer */
2802 epqstate->plan = subplan;
2803 /* The rowmarks depend on the plan, too */
2804 epqstate->arowMarks = auxrowmarks;
2805}
2806
2807/*
2808 * Return, and create if necessary, a slot for an EPQ test tuple.
2809 *
2810 * Note this only requires EvalPlanQualInit() to have been called,
2811 * EvalPlanQualBegin() is not necessary.
2812 */
2815 Relation relation, Index rti)
2816{
2817 TupleTableSlot **slot;
2818
2819 Assert(relation);
2820 Assert(rti > 0 && rti <= epqstate->parentestate->es_range_table_size);
2821 slot = &epqstate->relsubs_slot[rti - 1];
2822
2823 if (*slot == NULL)
2824 {
2825 MemoryContext oldcontext;
2826
2827 oldcontext = MemoryContextSwitchTo(epqstate->parentestate->es_query_cxt);
2828 *slot = table_slot_create(relation, &epqstate->tuple_table);
2829 MemoryContextSwitchTo(oldcontext);
2830 }
2831
2832 return *slot;
2833}
2834
2835/*
2836 * Fetch the current row value for a non-locked relation, identified by rti,
2837 * that needs to be scanned by an EvalPlanQual operation. origslot must have
2838 * been set to contain the current result row (top-level row) that we need to
2839 * recheck. Returns true if a substitution tuple was found, false if not.
2840 */
2841bool
2843{
2844 ExecAuxRowMark *earm = epqstate->relsubs_rowmark[rti - 1];
2846 Datum datum;
2847 bool isNull;
2848
2849 Assert(earm != NULL);
2850 Assert(epqstate->origslot != NULL);
2851
2852 erm = earm->rowmark;
2853
2854 if (RowMarkRequiresRowShareLock(erm->markType))
2855 elog(ERROR, "EvalPlanQual doesn't support locking rowmarks");
2856
2857 /* if child rel, must check whether it produced this row */
2858 if (erm->rti != erm->prti)
2859 {
2860 Oid tableoid;
2861
2862 datum = ExecGetJunkAttribute(epqstate->origslot,
2863 earm->toidAttNo,
2864 &isNull);
2865 /* non-locked rels could be on the inside of outer joins */
2866 if (isNull)
2867 return false;
2868
2869 tableoid = DatumGetObjectId(datum);
2870
2871 Assert(OidIsValid(erm->relid));
2872 if (tableoid != erm->relid)
2873 {
2874 /* this child is inactive right now */
2875 return false;
2876 }
2877 }
2878
2879 if (erm->markType == ROW_MARK_REFERENCE)
2880 {
2881 Assert(erm->relation != NULL);
2882
2883 /* fetch the tuple's ctid */
2884 datum = ExecGetJunkAttribute(epqstate->origslot,
2885 earm->ctidAttNo,
2886 &isNull);
2887 /* non-locked rels could be on the inside of outer joins */
2888 if (isNull)
2889 return false;
2890
2891 /* fetch requests on foreign tables must be passed to their FDW */
2892 if (erm->relation->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
2893 {
2894 FdwRoutine *fdwroutine;
2895 bool updated = false;
2896
2897 fdwroutine = GetFdwRoutineForRelation(erm->relation, false);
2898 /* this should have been checked already, but let's be safe */
2899 if (fdwroutine->RefetchForeignRow == NULL)
2900 ereport(ERROR,
2902 errmsg("cannot lock rows in foreign table \"%s\"",
2903 RelationGetRelationName(erm->relation))));
2904
2905 fdwroutine->RefetchForeignRow(epqstate->recheckestate,
2906 erm,
2907 datum,
2908 slot,
2909 &updated);
2910 if (TupIsNull(slot))
2911 elog(ERROR, "failed to fetch tuple for EvalPlanQual recheck");
2912
2913 /*
2914 * Ideally we'd insist on updated == false here, but that assumes
2915 * that FDWs can track that exactly, which they might not be able
2916 * to. So just ignore the flag.
2917 */
2918 return true;
2919 }
2920 else
2921 {
2922 /* ordinary table, fetch the tuple */
2923 if (!table_tuple_fetch_row_version(erm->relation,
2925 SnapshotAny, slot))
2926 elog(ERROR, "failed to fetch tuple for EvalPlanQual recheck");
2927 return true;
2928 }
2929 }
2930 else
2931 {
2932 Assert(erm->markType == ROW_MARK_COPY);
2933
2934 /* fetch the whole-row Var for the relation */
2935 datum = ExecGetJunkAttribute(epqstate->origslot,
2936 earm->wholeAttNo,
2937 &isNull);
2938 /* non-locked rels could be on the inside of outer joins */
2939 if (isNull)
2940 return false;
2941
2942 ExecStoreHeapTupleDatum(datum, slot);
2943 return true;
2944 }
2945}
2946
2947/*
2948 * Fetch the next row (if any) from EvalPlanQual testing
2949 *
2950 * (In practice, there should never be more than one row...)
2951 */
2954{
2955 MemoryContext oldcontext;
2956 TupleTableSlot *slot;
2957
2958 oldcontext = MemoryContextSwitchTo(epqstate->recheckestate->es_query_cxt);
2959 slot = ExecProcNode(epqstate->recheckplanstate);
2960 MemoryContextSwitchTo(oldcontext);
2961
2962 return slot;
2963}
2964
2965/*
2966 * Initialize or reset an EvalPlanQual state tree
2967 */
2968void
2970{
2971 EState *parentestate = epqstate->parentestate;
2972 EState *recheckestate = epqstate->recheckestate;
2973
2974 if (recheckestate == NULL)
2975 {
2976 /* First time through, so create a child EState */
2977 EvalPlanQualStart(epqstate, epqstate->plan);
2978 }
2979 else
2980 {
2981 /*
2982 * We already have a suitable child EPQ tree, so just reset it.
2983 */
2984 Index rtsize = parentestate->es_range_table_size;
2986
2987 /*
2988 * Reset the relsubs_done[] flags to equal relsubs_blocked[], so that
2989 * the EPQ run will never attempt to fetch tuples from blocked target
2990 * relations.
2991 */
2992 memcpy(epqstate->relsubs_done, epqstate->relsubs_blocked,
2993 rtsize * sizeof(bool));
2994
2995 /* Recopy current values of parent parameters */
2996 if (parentestate->es_plannedstmt->paramExecTypes != NIL)
2997 {
2998 int i;
2999
3000 /*
3001 * Force evaluation of any InitPlan outputs that could be needed
3002 * by the subplan, just in case they got reset since
3003 * EvalPlanQualStart (see comments therein).
3004 */
3005 ExecSetParamPlanMulti(rcplanstate->plan->extParam,
3006 GetPerTupleExprContext(parentestate));
3007
3008 i = list_length(parentestate->es_plannedstmt->paramExecTypes);
3009
3010 while (--i >= 0)
3011 {
3012 /* copy value if any, but not execPlan link */
3013 recheckestate->es_param_exec_vals[i].value =
3014 parentestate->es_param_exec_vals[i].value;
3015 recheckestate->es_param_exec_vals[i].isnull =
3016 parentestate->es_param_exec_vals[i].isnull;
3017 }
3018 }
3019
3020 /*
3021 * Mark child plan tree as needing rescan at all scan nodes. The
3022 * first ExecProcNode will take care of actually doing the rescan.
3023 */
3024 rcplanstate->chgParam = bms_add_member(rcplanstate->chgParam,
3025 epqstate->epqParam);
3026 }
3027}
3028
3029/*
3030 * Start execution of an EvalPlanQual plan tree.
3031 *
3032 * This is a cut-down version of ExecutorStart(): we copy some state from
3033 * the top-level estate rather than initializing it fresh.
3034 */
3035static void
3036EvalPlanQualStart(EPQState *epqstate, Plan *planTree)
3037{
3038 EState *parentestate = epqstate->parentestate;
3039 Index rtsize = parentestate->es_range_table_size;
3041 MemoryContext oldcontext;
3042 ListCell *l;
3043
3045
3046 oldcontext = MemoryContextSwitchTo(rcestate->es_query_cxt);
3047
3048 /* signal that this is an EState for executing EPQ */
3049 rcestate->es_epq_active = epqstate;
3050
3051 /*
3052 * Child EPQ EStates share the parent's copy of unchanging state such as
3053 * the snapshot, rangetable, and external Param info. They need their own
3054 * copies of local state, including a tuple table, es_param_exec_vals,
3055 * result-rel info, etc.
3056 */
3057 rcestate->es_direction = ForwardScanDirection;
3058 rcestate->es_snapshot = parentestate->es_snapshot;
3059 rcestate->es_crosscheck_snapshot = parentestate->es_crosscheck_snapshot;
3060 rcestate->es_range_table = parentestate->es_range_table;
3061 rcestate->es_range_table_size = parentestate->es_range_table_size;
3062 rcestate->es_relations = parentestate->es_relations;
3063 rcestate->es_rowmarks = parentestate->es_rowmarks;
3064 rcestate->es_rteperminfos = parentestate->es_rteperminfos;
3065 rcestate->es_plannedstmt = parentestate->es_plannedstmt;
3066 rcestate->es_junkFilter = parentestate->es_junkFilter;
3067 rcestate->es_output_cid = parentestate->es_output_cid;
3068 rcestate->es_queryEnv = parentestate->es_queryEnv;
3069
3070 /*
3071 * ResultRelInfos needed by subplans are initialized from scratch when the
3072 * subplans themselves are initialized.
3073 */
3074 rcestate->es_result_relations = NULL;
3075 /* es_trig_target_relations must NOT be copied */
3076 rcestate->es_top_eflags = parentestate->es_top_eflags;
3077 rcestate->es_instrument = parentestate->es_instrument;
3078 /* es_auxmodifytables must NOT be copied */
3079
3080 /*
3081 * The external param list is simply shared from parent. The internal
3082 * param workspace has to be local state, but we copy the initial values
3083 * from the parent, so as to have access to any param values that were
3084 * already set from other parts of the parent's plan tree.
3085 */
3086 rcestate->es_param_list_info = parentestate->es_param_list_info;
3087 if (parentestate->es_plannedstmt->paramExecTypes != NIL)
3088 {
3089 int i;
3090
3091 /*
3092 * Force evaluation of any InitPlan outputs that could be needed by
3093 * the subplan. (With more complexity, maybe we could postpone this
3094 * till the subplan actually demands them, but it doesn't seem worth
3095 * the trouble; this is a corner case already, since usually the
3096 * InitPlans would have been evaluated before reaching EvalPlanQual.)
3097 *
3098 * This will not touch output params of InitPlans that occur somewhere
3099 * within the subplan tree, only those that are attached to the
3100 * ModifyTable node or above it and are referenced within the subplan.
3101 * That's OK though, because the planner would only attach such
3102 * InitPlans to a lower-level SubqueryScan node, and EPQ execution
3103 * will not descend into a SubqueryScan.
3104 *
3105 * The EState's per-output-tuple econtext is sufficiently short-lived
3106 * for this, since it should get reset before there is any chance of
3107 * doing EvalPlanQual again.
3108 */
3110 GetPerTupleExprContext(parentestate));
3111
3112 /* now make the internal param workspace ... */
3113 i = list_length(parentestate->es_plannedstmt->paramExecTypes);
3114 rcestate->es_param_exec_vals = palloc0_array(ParamExecData, i);
3115 /* ... and copy down all values, whether really needed or not */
3116 while (--i >= 0)
3117 {
3118 /* copy value if any, but not execPlan link */
3119 rcestate->es_param_exec_vals[i].value =
3120 parentestate->es_param_exec_vals[i].value;
3121 rcestate->es_param_exec_vals[i].isnull =
3122 parentestate->es_param_exec_vals[i].isnull;
3123 }
3124 }
3125
3126 /*
3127 * Copy es_unpruned_relids so that pruned relations are ignored by
3128 * ExecInitLockRows() and ExecInitModifyTable() when initializing the plan
3129 * trees below.
3130 */
3131 rcestate->es_unpruned_relids = parentestate->es_unpruned_relids;
3132
3133 /*
3134 * Also make the PartitionPruneInfo and the results of pruning available.
3135 * These need to match exactly so that we initialize all the same Append
3136 * and MergeAppend subplans as the parent did.
3137 */
3138 rcestate->es_part_prune_infos = parentestate->es_part_prune_infos;
3139 rcestate->es_part_prune_states = parentestate->es_part_prune_states;
3140 rcestate->es_part_prune_results = parentestate->es_part_prune_results;
3141
3142 /* We'll also borrow the es_partition_directory from the parent state */
3143 rcestate->es_partition_directory = parentestate->es_partition_directory;
3144
3145 /*
3146 * Initialize private state information for each SubPlan. We must do this
3147 * before running ExecInitNode on the main query tree, since
3148 * ExecInitSubPlan expects to be able to find these entries. Some of the
3149 * SubPlans might not be used in the part of the plan tree we intend to
3150 * run, but since it's not easy to tell which, we just initialize them
3151 * all.
3152 */
3153 Assert(rcestate->es_subplanstates == NIL);
3154 foreach(l, parentestate->es_plannedstmt->subplans)
3155 {
3156 Plan *subplan = (Plan *) lfirst(l);
3158
3159 subplanstate = ExecInitNode(subplan, rcestate, 0);
3160 rcestate->es_subplanstates = lappend(rcestate->es_subplanstates,
3161 subplanstate);
3162 }
3163
3164 /*
3165 * Build an RTI indexed array of rowmarks, so that
3166 * EvalPlanQualFetchRowMark() can efficiently access the to be fetched
3167 * rowmark.
3168 */
3170 foreach(l, epqstate->arowMarks)
3171 {
3173
3174 epqstate->relsubs_rowmark[earm->rowmark->rti - 1] = earm;
3175 }
3176
3177 /*
3178 * Initialize per-relation EPQ tuple states. Result relations, if any,
3179 * get marked as blocked; others as not-fetched.
3180 */
3181 epqstate->relsubs_done = palloc_array(bool, rtsize);
3182 epqstate->relsubs_blocked = palloc0_array(bool, rtsize);
3183
3184 foreach(l, epqstate->resultRelations)
3185 {
3186 int rtindex = lfirst_int(l);
3187
3188 Assert(rtindex > 0 && rtindex <= rtsize);
3189 epqstate->relsubs_blocked[rtindex - 1] = true;
3190 }
3191
3192 memcpy(epqstate->relsubs_done, epqstate->relsubs_blocked,
3193 rtsize * sizeof(bool));
3194
3195 /*
3196 * Initialize the private state information for all the nodes in the part
3197 * of the plan tree we need to run. This opens files, allocates storage
3198 * and leaves us ready to start processing tuples.
3199 */
3200 epqstate->recheckplanstate = ExecInitNode(planTree, rcestate, 0);
3201
3202 MemoryContextSwitchTo(oldcontext);
3203}
3204
3205/*
3206 * EvalPlanQualEnd -- shut down at termination of parent plan state node,
3207 * or if we are done with the current EPQ child.
3208 *
3209 * This is a cut-down version of ExecutorEnd(); basically we want to do most
3210 * of the normal cleanup, but *not* close result relations (which we are
3211 * just sharing from the outer query). We do, however, have to close any
3212 * result and trigger target relations that got opened, since those are not
3213 * shared. (There probably shouldn't be any of the latter, but just in
3214 * case...)
3215 */
3216void
3218{
3219 EState *estate = epqstate->recheckestate;
3220 Index rtsize;
3221 MemoryContext oldcontext;
3222 ListCell *l;
3223
3225
3226 /*
3227 * We may have a tuple table, even if EPQ wasn't started, because we allow
3228 * use of EvalPlanQualSlot() without calling EvalPlanQualBegin().
3229 */
3230 if (epqstate->tuple_table != NIL)
3231 {
3232 memset(epqstate->relsubs_slot, 0,
3233 rtsize * sizeof(TupleTableSlot *));
3234 ExecResetTupleTable(epqstate->tuple_table, true);
3235 epqstate->tuple_table = NIL;
3236 }
3237
3238 /* EPQ wasn't started, nothing further to do */
3239 if (estate == NULL)
3240 return;
3241
3242 oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
3243
3244 ExecEndNode(epqstate->recheckplanstate);
3245
3246 foreach(l, estate->es_subplanstates)
3247 {
3249
3251 }
3252
3253 /* throw away the per-estate tuple table, some node may have used it */
3254 ExecResetTupleTable(estate->es_tupleTable, false);
3255
3256 /* Close any result and trigger target relations attached to this EState */
3258
3259 MemoryContextSwitchTo(oldcontext);
3260
3261 /*
3262 * NULLify the partition directory before freeing the executor state.
3263 * Since EvalPlanQualStart() just borrowed the parent EState's directory,
3264 * we'd better leave it up to the parent to delete it.
3265 */
3266 estate->es_partition_directory = NULL;
3267
3268 FreeExecutorState(estate);
3269
3270 /* Mark EPQState idle */
3271 epqstate->origslot = NULL;
3272 epqstate->recheckestate = NULL;
3273 epqstate->recheckplanstate = NULL;
3274 epqstate->relsubs_rowmark = NULL;
3275 epqstate->relsubs_done = NULL;
3276 epqstate->relsubs_blocked = NULL;
3277}
AclResult
Definition acl.h:183
@ ACLCHECK_NO_PRIV
Definition acl.h:185
@ ACLCHECK_OK
Definition acl.h:184
@ ACLMASK_ANY
Definition acl.h:178
@ ACLMASK_ALL
Definition acl.h:177
AclResult pg_attribute_aclcheck_all(Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how)
Definition aclchk.c:3954
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition aclchk.c:2672
AclResult pg_attribute_aclcheck(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode)
Definition aclchk.c:3912
AclMode pg_class_aclmask(Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how)
Definition aclchk.c:3298
AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode)
Definition aclchk.c:4083
AttrMap * build_attrmap_by_name_if_req(TupleDesc indesc, TupleDesc outdesc, bool missing_ok)
Definition attmap.c:261
int16 AttrNumber
Definition attnum.h:21
#define AttributeNumberIsValid(attributeNumber)
Definition attnum.h:34
#define InvalidAttrNumber
Definition attnum.h:23
void pgstat_report_query_id(int64 query_id, bool force)
int bms_next_member(const Bitmapset *a, int prevbit)
Definition bitmapset.c:1290
int bms_num_members(const Bitmapset *a)
Definition bitmapset.c:744
bool bms_is_member(int x, const Bitmapset *a)
Definition bitmapset.c:510
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition bitmapset.c:799
Bitmapset * bms_union(const Bitmapset *a, const Bitmapset *b)
Definition bitmapset.c:251
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
Definition bitmapset.c:575
Bitmapset * bms_copy(const Bitmapset *a)
Definition bitmapset.c:122
#define bms_is_empty(a)
Definition bitmapset.h:118
#define NameStr(name)
Definition c.h:891
#define Assert(condition)
Definition c.h:999
uint64_t uint64
Definition c.h:681
unsigned int Index
Definition c.h:754
#define MemSet(start, val, len)
Definition c.h:1163
#define OidIsValid(objectId)
Definition c.h:914
bool IsInplaceUpdateRelation(Relation relation)
Definition catalog.c:183
uint32 result
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))
static DataChecksumsWorkerOperation operation
int errcode(int sqlerrcode)
Definition elog.c:875
int errdetail(const char *fmt,...) pg_attribute_printf(1
int int errmsg_internal(const char *fmt,...) pg_attribute_printf(1
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
#define ereport(elevel,...)
Definition elog.h:152
void ExecReScan(PlanState *node)
Definition execAmi.c:78
ExprState * ExecPrepareExpr(Expr *node, EState *estate)
Definition execExpr.c:765
bool ExecCheck(ExprState *state, ExprContext *econtext)
Definition execExpr.c:872
ExprState * ExecPrepareCheck(List *qual, EState *estate)
Definition execExpr.c:816
void ExecCloseIndices(ResultRelInfo *resultRelInfo)
TupleTableSlot * ExecFilterJunk(JunkFilter *junkfilter, TupleTableSlot *slot)
Definition execJunk.c:247
AttrNumber ExecFindJunkAttributeInTlist(List *targetlist, const char *attrName)
Definition execJunk.c:222
JunkFilter * ExecInitJunkFilter(List *targetList, TupleTableSlot *slot)
Definition execJunk.c:60
static void EvalPlanQualStart(EPQState *epqstate, Plan *planTree)
Definition execMain.c:3036
static void ReportNotNullViolationError(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate, int attnum)
Definition execMain.c:2197
LockTupleMode ExecUpdateLockMode(EState *estate, ResultRelInfo *relinfo)
Definition execMain.c:2568
ExecRowMark * ExecFindRowMark(EState *estate, Index rti, bool missing_ok)
Definition execMain.c:2594
ExecAuxRowMark * ExecBuildAuxRowMark(ExecRowMark *erm, List *targetlist)
Definition execMain.c:2617
ExecutorEnd_hook_type ExecutorEnd_hook
Definition execMain.c:73
ResultRelInfo * ExecGetTriggerResultRel(EState *estate, Oid relid, ResultRelInfo *rootRelInfo)
Definition execMain.c:1381
TupleTableSlot * EvalPlanQualSlot(EPQState *epqstate, Relation relation, Index rti)
Definition execMain.c:2814
void EvalPlanQualBegin(EPQState *epqstate)
Definition execMain.c:2969
ExecutorFinish_hook_type ExecutorFinish_hook
Definition execMain.c:72
char * ExecBuildSlotValueDescription(Oid reloid, TupleTableSlot *slot, TupleDesc tupdesc, Bitmapset *modifiedCols, int maxfieldlen)
Definition execMain.c:2429
bool ExecPartitionCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate, bool emitError)
Definition execMain.c:1894
static void ExecEndPlan(PlanState *planstate, EState *estate)
Definition execMain.c:1574
ExecutorStart_hook_type ExecutorStart_hook
Definition execMain.c:70
void CheckValidResultRel(ResultRelInfo *resultRelInfo, CmdType operation, OnConflictAction onConflictAction, List *mergeActions, ModifyTable *mtnode)
Definition execMain.c:1065
void ExecutorEnd(QueryDesc *queryDesc)
Definition execMain.c:477
void EvalPlanQualInit(EPQState *epqstate, EState *parentestate, Plan *subplan, List *auxrowmarks, int epqParam, List *resultRelations)
Definition execMain.c:2756
void ExecWithCheckOptions(WCOKind kind, ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate)
Definition execMain.c:2266
ExecutorCheckPerms_hook_type ExecutorCheckPerms_hook
Definition execMain.c:76
void InitResultRelInfo(ResultRelInfo *resultRelInfo, Relation resultRelationDesc, Index resultRelationIndex, ResultRelInfo *partition_root_rri, int instrument_options)
Definition execMain.c:1280
void standard_ExecutorStart(QueryDesc *queryDesc, int eflags)
Definition execMain.c:143
void ExecutorFinish(QueryDesc *queryDesc)
Definition execMain.c:417
static void CheckValidRowMarkRel(Relation rel, RowMarkType markType)
Definition execMain.c:1208
void EvalPlanQualEnd(EPQState *epqstate)
Definition execMain.c:3217
static void ExecCheckXactReadOnly(PlannedStmt *plannedstmt)
Definition execMain.c:813
void EvalPlanQualSetPlan(EPQState *epqstate, Plan *subplan, List *auxrowmarks)
Definition execMain.c:2797
void ExecutorRewind(QueryDesc *queryDesc)
Definition execMain.c:547
void ExecutorStart(QueryDesc *queryDesc, int eflags)
Definition execMain.c:124
AttrNumber ExecRelGenVirtualNotNull(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate, List *notnull_virtual_attrs)
Definition execMain.c:2132
TupleTableSlot * EvalPlanQual(EPQState *epqstate, Relation relation, Index rti, TupleTableSlot *inputslot)
Definition execMain.c:2687
bool ExecCheckOneRelPerms(RTEPermissionInfo *perminfo)
Definition execMain.c:657
bool EvalPlanQualFetchRowMark(EPQState *epqstate, Index rti, TupleTableSlot *slot)
Definition execMain.c:2842
static bool ExecCheckPermissionsModified(Oid relOid, Oid userid, Bitmapset *modifiedCols, AclMode requiredPerms)
Definition execMain.c:766
ExecutorRun_hook_type ExecutorRun_hook
Definition execMain.c:71
static void ExecPostprocessPlan(EState *estate)
Definition execMain.c:1528
static const char * ExecRelCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate)
Definition execMain.c:1816
static void ExecutePlan(QueryDesc *queryDesc, CmdType operation, bool sendTuples, uint64 numberTuples, ScanDirection direction, DestReceiver *dest)
Definition execMain.c:1694
void ExecCloseResultRelations(EState *estate)
Definition execMain.c:1613
void standard_ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count)
Definition execMain.c:318
void standard_ExecutorEnd(QueryDesc *queryDesc)
Definition execMain.c:486
void ExecCloseRangeTableRelations(EState *estate)
Definition execMain.c:1673
void ExecPartitionCheckEmitError(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate)
Definition execMain.c:1947
void ExecConstraints(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate)
Definition execMain.c:2018
static void InitPlan(QueryDesc *queryDesc, int eflags)
Definition execMain.c:847
bool ExecCheckPermissions(List *rangeTable, List *rteperminfos, bool ereport_on_violation)
Definition execMain.c:593
void ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count)
Definition execMain.c:308
List * ExecGetAncestorResultRels(EState *estate, ResultRelInfo *resultRelInfo)
Definition execMain.c:1468
TupleTableSlot * EvalPlanQualNext(EPQState *epqstate)
Definition execMain.c:2953
void standard_ExecutorFinish(QueryDesc *queryDesc)
Definition execMain.c:426
void ExecDoInitialPruning(EState *estate)
void ExecEndNode(PlanState *node)
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
void ExecShutdownNode(PlanState *node)
void CheckCmdReplicaIdentity(Relation rel, CmdType cmd)
void ExecResetTupleTable(List *tupleTable, bool shouldFree)
const TupleTableSlotOps TTSOpsVirtual
Definition execTuples.c:84
TupleTableSlot * MakeTupleTableSlot(TupleDesc tupleDesc, const TupleTableSlotOps *tts_ops, uint16 flags)
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
void ExecStoreHeapTupleDatum(Datum data, TupleTableSlot *slot)
TupleDesc ExecGetResultType(PlanState *planstate)
Definition execUtils.c:500
Relation ExecGetRangeTableRelation(EState *estate, Index rti, bool isResultRel)
Definition execUtils.c:851
Bitmapset * ExecGetInsertedCols(ResultRelInfo *relinfo, EState *estate)
Definition execUtils.c:1387
void ExecInitRangeTable(EState *estate, List *rangeTable, List *permInfos, Bitmapset *unpruned_relids)
Definition execUtils.c:799
Bitmapset * ExecGetUpdatedCols(ResultRelInfo *relinfo, EState *estate)
Definition execUtils.c:1408
void FreeExecutorState(EState *estate)
Definition execUtils.c:197
Bitmapset * ExecGetAllUpdatedCols(ResultRelInfo *relinfo, EState *estate)
Definition execUtils.c:1444
EState * CreateExecutorState(void)
Definition execUtils.c:90
#define EXEC_FLAG_BACKWARD
Definition executor.h:70
#define EXEC_FLAG_REWIND
Definition executor.h:69
#define ResetPerTupleExprContext(estate)
Definition executor.h:674
#define GetPerTupleExprContext(estate)
Definition executor.h:665
void(* ExecutorFinish_hook_type)(QueryDesc *queryDesc)
Definition executor.h:87
static RangeTblEntry * exec_rt_fetch(Index rti, EState *estate)
Definition executor.h:708
void(* ExecutorRun_hook_type)(QueryDesc *queryDesc, ScanDirection direction, uint64 count)
Definition executor.h:81
void(* ExecutorStart_hook_type)(QueryDesc *queryDesc, int eflags)
Definition executor.h:77
static bool ExecQual(ExprState *state, ExprContext *econtext)
Definition executor.h:527
bool(* ExecutorCheckPerms_hook_type)(List *rangeTable, List *rtePermInfos, bool ereport_on_violation)
Definition executor.h:95
void(* ExecutorEnd_hook_type)(QueryDesc *queryDesc)
Definition executor.h:91
static TupleTableSlot * ExecProcNode(PlanState *node)
Definition executor.h:322
#define EXEC_FLAG_SKIP_TRIGGERS
Definition executor.h:72
#define EXEC_FLAG_EXPLAIN_ONLY
Definition executor.h:67
static Datum ExecGetJunkAttribute(TupleTableSlot *slot, AttrNumber attno, bool *isNull)
Definition executor.h:226
#define EXEC_FLAG_MARK
Definition executor.h:71
#define palloc_object(type)
Definition fe_memutils.h:89
#define palloc_array(type, count)
Definition fe_memutils.h:91
#define palloc0_array(type, count)
Definition fe_memutils.h:92
#define palloc0_object(type)
Definition fe_memutils.h:90
char * OidOutputFunctionCall(Oid functionId, Datum val)
Definition fmgr.c:1764
FdwRoutine * GetFdwRoutineForRelation(Relation relation, bool makecopy)
Definition foreign.c:474
struct parser_state ps
long val
Definition informix.c:689
static bool success
Definition initdb.c:188
void InstrStart(Instrumentation *instr)
Definition instrument.c:53
void InstrStop(Instrumentation *instr)
Definition instrument.c:103
Instrumentation * InstrAlloc(int instrument_options)
Definition instrument.c:36
TriggerInstrumentation * InstrAllocTrigger(int n, int instrument_options)
Definition instrument.c:253
int j
Definition isn.c:78
int i
Definition isn.c:77
static void ItemPointerSetInvalid(ItemPointerData *pointer)
Definition itemptr.h:184
List * lappend(List *list, void *datum)
Definition list.c:339
List * lappend_int(List *list, int datum)
Definition list.c:357
#define NoLock
Definition lockdefs.h:34
LockTupleMode
Definition lockoptions.h:51
@ LockTupleExclusive
Definition lockoptions.h:59
@ LockTupleNoKeyExclusive
Definition lockoptions.h:57
char * get_rel_name(Oid relid)
Definition lsyscache.c:2234
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition lsyscache.c:3215
char get_rel_relkind(Oid relid)
Definition lsyscache.c:2309
Oid get_rel_namespace(Oid relid)
Definition lsyscache.c:2258
bool MatViewIncrementalMaintenanceIsEnabled(void)
Definition matview.c:953
int pg_mbcliplen(const char *mbstr, int len, int limit)
Definition mbutils.c:1212
Oid GetUserId(void)
Definition miscinit.c:470
bool isTempNamespace(Oid namespaceId)
Definition namespace.c:3721
void ExecSetParamPlanMulti(const Bitmapset *params, ExprContext *econtext)
OnConflictAction
Definition nodes.h:425
@ ONCONFLICT_UPDATE
Definition nodes.h:428
CmdType
Definition nodes.h:271
@ CMD_MERGE
Definition nodes.h:277
@ CMD_INSERT
Definition nodes.h:275
@ CMD_DELETE
Definition nodes.h:276
@ CMD_UPDATE
Definition nodes.h:274
@ CMD_SELECT
Definition nodes.h:273
#define makeNode(_type_)
Definition nodes.h:159
static char * errmsg
ObjectType get_relkind_objtype(char relkind)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:138
RTEPermissionInfo * getRTEPermissionInfo(List *rteperminfos, RangeTblEntry *rte)
WCOKind
@ WCO_RLS_MERGE_UPDATE_CHECK
@ WCO_RLS_CONFLICT_CHECK
@ WCO_RLS_INSERT_CHECK
@ WCO_VIEW_CHECK
@ WCO_RLS_UPDATE_CHECK
@ WCO_RLS_MERGE_DELETE_CHECK
uint64 AclMode
Definition parsenodes.h:74
#define ACL_INSERT
Definition parsenodes.h:76
#define ACL_UPDATE
Definition parsenodes.h:78
@ RTE_SUBQUERY
@ RTE_RELATION
#define ACL_SELECT
Definition parsenodes.h:77
List * RelationGetPartitionQual(Relation rel)
Definition partcache.c:277
List * get_partition_ancestors(Oid relid)
Definition partition.c:134
int16 attnum
FormData_pg_attribute * Form_pg_attribute
#define lfirst(lc)
Definition pg_list.h:172
#define lfirst_node(type, lc)
Definition pg_list.h:176
static int list_length(const List *l)
Definition pg_list.h:152
#define NIL
Definition pg_list.h:68
#define forboth(cell1, list1, cell2, list2)
Definition pg_list.h:550
#define foreach_current_index(var_or_cell)
Definition pg_list.h:435
#define lfirst_int(lc)
Definition pg_list.h:173
#define foreach_node(type, var, lst)
Definition pg_list.h:528
#define lfirst_oid(lc)
Definition pg_list.h:174
#define foreach_int(var, lst)
Definition pg_list.h:502
#define plan(x)
Definition pg_regress.c:164
static char buf[DEFAULT_XLOG_SEG_SIZE]
int64 PgStat_Counter
Definition pgstat.h:71
void pgstat_update_parallel_workers_stats(PgStat_Counter workers_to_launch, PgStat_Counter workers_launched)
#define RowMarkRequiresRowShareLock(marktype)
Definition plannodes.h:1565
RowMarkType
Definition plannodes.h:1556
@ ROW_MARK_COPY
Definition plannodes.h:1562
@ ROW_MARK_REFERENCE
Definition plannodes.h:1561
@ ROW_MARK_SHARE
Definition plannodes.h:1559
@ ROW_MARK_EXCLUSIVE
Definition plannodes.h:1557
@ ROW_MARK_NOKEYEXCLUSIVE
Definition plannodes.h:1558
@ ROW_MARK_KEYSHARE
Definition plannodes.h:1560
#define snprintf
Definition port.h:261
static Oid DatumGetObjectId(Datum X)
Definition postgres.h:242
uint64_t Datum
Definition postgres.h:70
static Pointer DatumGetPointer(Datum X)
Definition postgres.h:332
#define InvalidOid
unsigned int Oid
static int fb(int x)
@ IS_NOT_NULL
Definition primnodes.h:1973
@ MERGE_WHEN_NOT_MATCHED_BY_TARGET
Definition primnodes.h:2019
@ MERGE_WHEN_NOT_MATCHED_BY_SOURCE
Definition primnodes.h:2018
@ MERGE_WHEN_MATCHED
Definition primnodes.h:2017
void * stringToNode(const char *str)
Definition read.c:90
#define RelationGetRelid(relation)
Definition rel.h:516
#define RelationGetDescr(relation)
Definition rel.h:542
#define RelationGetRelationName(relation)
Definition rel.h:550
int errtableconstraint(Relation rel, const char *conname)
Definition relcache.c:6136
int errtablecol(Relation rel, int attnum)
Definition relcache.c:6099
Bitmapset * RelationGetIndexAttrBitmap(Relation relation, IndexAttrBitmapKind attrKind)
Definition relcache.c:5313
int errtable(Relation rel)
Definition relcache.c:6082
@ INDEX_ATTR_BITMAP_KEY
Definition relcache.h:70
bool view_has_instead_trigger(Relation view, CmdType event, List *mergeActionList)
Node * build_generation_expression(Relation rel, int attrno)
void error_view_not_updatable(Relation view, CmdType command, List *mergeActionList, const char *detail)
Node * expand_generated_columns_in_expr(Node *node, Relation rel, int rt_index)
int check_enable_rls(Oid relid, Oid checkAsUser, bool noError)
Definition rls.c:52
@ RLS_ENABLED
Definition rls.h:45
#define ScanDirectionIsNoMovement(direction)
Definition sdir.h:57
ScanDirection
Definition sdir.h:25
@ ForwardScanDirection
Definition sdir.h:28
void UnregisterSnapshot(Snapshot snapshot)
Definition snapmgr.c:866
Snapshot RegisterSnapshot(Snapshot snapshot)
Definition snapmgr.c:824
Snapshot GetActiveSnapshot(void)
Definition snapmgr.c:800
#define SnapshotAny
Definition snapmgr.h:33
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
Definition stringinfo.c:281
void appendStringInfoString(StringInfo str, const char *s)
Definition stringinfo.c:230
void appendStringInfoChar(StringInfo str, char ch)
Definition stringinfo.c:242
void initStringInfo(StringInfo str)
Definition stringinfo.c:97
char * ccname
Definition tupdesc.h:30
ExecAuxRowMark ** relsubs_rowmark
Definition execnodes.h:1379
TupleTableSlot * origslot
Definition execnodes.h:1367
TupleTableSlot ** relsubs_slot
Definition execnodes.h:1351
Plan * plan
Definition execnodes.h:1358
int epqParam
Definition execnodes.h:1341
bool * relsubs_blocked
Definition execnodes.h:1395
EState * parentestate
Definition execnodes.h:1340
EState * recheckestate
Definition execnodes.h:1372
PlanState * recheckplanstate
Definition execnodes.h:1397
List * resultRelations
Definition execnodes.h:1342
List * arowMarks
Definition execnodes.h:1359
List * tuple_table
Definition execnodes.h:1350
bool * relsubs_done
Definition execnodes.h:1386
uint64 es_processed
Definition execnodes.h:751
List * es_part_prune_infos
Definition execnodes.h:707
int es_parallel_workers_to_launch
Definition execnodes.h:783
List * es_tuple_routing_result_relations
Definition execnodes.h:735
int es_top_eflags
Definition execnodes.h:756
int es_instrument
Definition execnodes.h:757
PlannedStmt * es_plannedstmt
Definition execnodes.h:706
QueryEnvironment * es_queryEnv
Definition execnodes.h:744
ParamExecData * es_param_exec_vals
Definition execnodes.h:742
uint64 es_total_processed
Definition execnodes.h:753
List * es_range_table
Definition execnodes.h:699
List * es_rteperminfos
Definition execnodes.h:705
Bitmapset * es_unpruned_relids
Definition execnodes.h:710
List * es_part_prune_states
Definition execnodes.h:708
ParamListInfo es_param_list_info
Definition execnodes.h:741
ExecRowMark ** es_rowmarks
Definition execnodes.h:703
bool es_finished
Definition execnodes.h:758
MemoryContext es_query_cxt
Definition execnodes.h:747
List * es_tupleTable
Definition execnodes.h:749
ScanDirection es_direction
Definition execnodes.h:696
struct EPQState * es_epq_active
Definition execnodes.h:779
PartitionDirectory es_partition_directory
Definition execnodes.h:729
List * es_trig_target_relations
Definition execnodes.h:738
int es_jit_flags
Definition execnodes.h:800
List * es_opened_result_relations
Definition execnodes.h:725
bool es_use_parallel_mode
Definition execnodes.h:781
Relation * es_relations
Definition execnodes.h:701
List * es_subplanstates
Definition execnodes.h:762
int es_parallel_workers_launched
Definition execnodes.h:785
CommandId es_output_cid
Definition execnodes.h:719
Index es_range_table_size
Definition execnodes.h:700
const char * es_sourceText
Definition execnodes.h:714
Snapshot es_snapshot
Definition execnodes.h:697
List * es_auxmodifytables
Definition execnodes.h:764
JunkFilter * es_junkFilter
Definition execnodes.h:716
List * es_part_prune_results
Definition execnodes.h:709
Snapshot es_crosscheck_snapshot
Definition execnodes.h:698
TupleTableSlot * ecxt_scantuple
Definition execnodes.h:287
ExecForeignInsert_function ExecForeignInsert
Definition fdwapi.h:236
ExecForeignUpdate_function ExecForeignUpdate
Definition fdwapi.h:239
RefetchForeignRow_function RefetchForeignRow
Definition fdwapi.h:252
ExecForeignDelete_function ExecForeignDelete
Definition fdwapi.h:240
IsForeignRelUpdatable_function IsForeignRelUpdatable
Definition fdwapi.h:244
TupleDesc jf_cleanTupType
Definition execnodes.h:433
Definition pg_list.h:54
Definition nodes.h:133
bool isnull
Definition params.h:149
Datum value
Definition params.h:148
LockClauseStrength strength
Definition plannodes.h:1621
RowMarkType markType
Definition plannodes.h:1617
LockWaitPolicy waitPolicy
Definition plannodes.h:1623
Index rowmarkId
Definition plannodes.h:1615
Plan * plan
Definition execnodes.h:1202
Bitmapset * extParam
Definition plannodes.h:255
List * targetlist
Definition plannodes.h:235
struct Plan * planTree
Definition plannodes.h:99
bool hasModifyingCTE
Definition plannodes.h:81
List * permInfos
Definition plannodes.h:118
List * rowMarks
Definition plannodes.h:138
Bitmapset * rewindPlanIDs
Definition plannodes.h:135
int64 queryId
Definition plannodes.h:69
bool hasReturning
Definition plannodes.h:78
List * subplans
Definition plannodes.h:129
Bitmapset * unprunableRelids
Definition plannodes.h:113
CmdType commandType
Definition plannodes.h:66
List * rtable
Definition plannodes.h:107
List * partPruneInfos
Definition plannodes.h:104
List * paramExecTypes
Definition plannodes.h:150
bool parallelModeNeeded
Definition plannodes.h:93
const char * sourceText
Definition execdesc.h:38
ParamListInfo params
Definition execdesc.h:42
DestReceiver * dest
Definition execdesc.h:41
int instrument_options
Definition execdesc.h:44
EState * estate
Definition execdesc.h:50
CmdType operation
Definition execdesc.h:36
Snapshot snapshot
Definition execdesc.h:39
bool already_executed
Definition execdesc.h:54
PlannedStmt * plannedstmt
Definition execdesc.h:37
int query_instr_options
Definition execdesc.h:45
QueryEnvironment * queryEnv
Definition execdesc.h:43
struct Instrumentation * query_instr
Definition execdesc.h:57
TupleDesc tupDesc
Definition execdesc.h:49
Snapshot crosscheck_snapshot
Definition execdesc.h:40
PlanState * planstate
Definition execdesc.h:51
TupleDesc rd_att
Definition rel.h:112
Form_pg_class rd_rel
Definition rel.h:111
TupleConversionMap * ri_RootToChildMap
Definition execnodes.h:643
OnConflictActionState * ri_onConflict
Definition execnodes.h:617
ExprState ** ri_CheckConstraintExprs
Definition execnodes.h:589
TupleTableSlot * ri_PartitionTupleSlot
Definition execnodes.h:656
bool ri_projectNewInfoValid
Definition execnodes.h:543
List * ri_onConflictArbiterIndexes
Definition execnodes.h:614
struct ResultRelInfo * ri_RootResultRelInfo
Definition execnodes.h:655
ExprState * ri_PartitionCheckExpr
Definition execnodes.h:629
ExprState * ri_MergeJoinCondition
Definition execnodes.h:623
bool ri_needLockTagTuple
Definition execnodes.h:546
Relation ri_RelationDesc
Definition execnodes.h:514
RelationPtr ri_IndexRelationDescs
Definition execnodes.h:520
TupleTableSlot * ri_ReturningSlot
Definition execnodes.h:561
List * ri_WithCheckOptions
Definition execnodes.h:583
TupleTableSlot * ri_oldTupleSlot
Definition execnodes.h:541
bool ri_RootToChildMapValid
Definition execnodes.h:644
struct CopyMultiInsertBuffer * ri_CopyMultiInsertBuffer
Definition execnodes.h:659
TriggerDesc * ri_TrigDesc
Definition execnodes.h:549
TupleTableSlot * ri_AllNullSlot
Definition execnodes.h:564
ForPortionOfState * ri_forPortionOf
Definition execnodes.h:626
ExprState ** ri_GenVirtualNotNullConstraintExprs
Definition execnodes.h:595
Bitmapset * ri_extraUpdatedCols
Definition execnodes.h:532
Index ri_RangeTableIndex
Definition execnodes.h:511
ExprState ** ri_GeneratedExprsI
Definition execnodes.h:600
TupleConversionMap * ri_ChildToRootMap
Definition execnodes.h:637
void * ri_FdwState
Definition execnodes.h:570
bool ri_ChildToRootMapValid
Definition execnodes.h:638
List * ri_MergeActions[NUM_MERGE_MATCH_KINDS]
Definition execnodes.h:620
List * ri_ancestorResultRels
Definition execnodes.h:665
TupleTableSlot * ri_newTupleSlot
Definition execnodes.h:539
List * ri_WithCheckOptionExprs
Definition execnodes.h:586
ProjectionInfo * ri_projectNew
Definition execnodes.h:537
NodeTag type
Definition execnodes.h:508
ProjectionInfo * ri_projectReturning
Definition execnodes.h:611
ExprState ** ri_GeneratedExprsU
Definition execnodes.h:601
struct FdwRoutine * ri_FdwRoutine
Definition execnodes.h:567
ExprState ** ri_TrigWhenExprs
Definition execnodes.h:555
FmgrInfo * ri_TrigFunctions
Definition execnodes.h:552
bool ri_usesFdwDirectModify
Definition execnodes.h:573
AttrNumber ri_RowIdAttNo
Definition execnodes.h:529
IndexInfo ** ri_IndexRelationInfo
Definition execnodes.h:523
TupleTableSlot * ri_TrigNewSlot
Definition execnodes.h:563
TriggerInstrumentation * ri_TrigInstrument
Definition execnodes.h:558
TupleTableSlot * ri_TrigOldSlot
Definition execnodes.h:562
int numtriggers
Definition reltrigger.h:50
bool has_not_null
Definition tupdesc.h:45
ConstrCheck * check
Definition tupdesc.h:41
uint16 num_check
Definition tupdesc.h:44
TupleConstr * constr
Definition tupdesc.h:159
bool * tts_isnull
Definition tuptable.h:133
Datum * tts_values
Definition tuptable.h:131
#define FirstLowInvalidHeapAttributeNumber
Definition sysattr.h:27
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition table.c:40
TupleTableSlot * table_slot_create(Relation relation, List **reglist)
Definition tableam.c:92
static bool table_tuple_fetch_row_version(Relation rel, ItemPointer tid, Snapshot snapshot, TupleTableSlot *slot)
Definition tableam.h:1344
TriggerDesc * CopyTriggerDesc(TriggerDesc *trigdesc)
Definition trigger.c:2092
void AfterTriggerEndQuery(EState *estate)
Definition trigger.c:5161
void AfterTriggerBeginQuery(void)
Definition trigger.c:5141
TupleTableSlot * execute_attr_map_slot(AttrMap *attrMap, TupleTableSlot *in_slot, TupleTableSlot *out_slot)
Definition tupconvert.c:193
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition tupdesc.h:178
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition tuptable.h:476
#define TupIsNull(slot)
Definition tuptable.h:325
static void slot_getallattrs(TupleTableSlot *slot)
Definition tuptable.h:390
static TupleTableSlot * ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
Definition tuptable.h:544
static void ExecMaterializeSlot(TupleTableSlot *slot)
Definition tuptable.h:495
static bool slot_attisnull(TupleTableSlot *slot, int attnum)
Definition tuptable.h:403
void PreventCommandIfReadOnly(const char *cmdname)
Definition utility.c:409
void PreventCommandIfParallelMode(const char *cmdname)
Definition utility.c:427
static const char * CreateCommandName(Node *parsetree)
Definition utility.h:103
void ExitParallelMode(void)
Definition xact.c:1094
void EnterParallelMode(void)
Definition xact.c:1081
bool XactReadOnly
Definition xact.c:84
bool IsInParallelMode(void)
Definition xact.c:1119
CommandId GetCurrentCommandId(bool used)
Definition xact.c:831