]> granicus.if.org Git - postgresql/blob - src/backend/executor/execMain.c
f63ea4e9ebad1030aab932700f9f72e8c68679a8
[postgresql] / src / backend / executor / execMain.c
1 /*-------------------------------------------------------------------------
2  *
3  * execMain.c
4  *        top level executor interface routines
5  *
6  * INTERFACE ROUTINES
7  *      ExecutorStart()
8  *      ExecutorRun()
9  *      ExecutorEnd()
10  *
11  *      The old ExecutorMain() has been replaced by ExecutorStart(),
12  *      ExecutorRun() and ExecutorEnd()
13  *
14  *      These three procedures are the external interfaces to the executor.
15  *      In each case, the query descriptor is required as an argument.
16  *
17  *      ExecutorStart() must be called at the beginning of execution of any
18  *      query plan and ExecutorEnd() should always be called at the end of
19  *      execution of a plan.
20  *
21  *      ExecutorRun accepts direction and count arguments that specify whether
22  *      the plan is to be executed forwards, backwards, and for how many tuples.
23  *
24  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
25  * Portions Copyright (c) 1994, Regents of the University of California
26  *
27  *
28  * IDENTIFICATION
29  *        $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.318 2008/11/19 01:10:23 tgl Exp $
30  *
31  *-------------------------------------------------------------------------
32  */
33 #include "postgres.h"
34
35 #include "access/heapam.h"
36 #include "access/reloptions.h"
37 #include "access/transam.h"
38 #include "access/xact.h"
39 #include "catalog/heap.h"
40 #include "catalog/namespace.h"
41 #include "catalog/toasting.h"
42 #include "commands/tablespace.h"
43 #include "commands/trigger.h"
44 #include "executor/execdebug.h"
45 #include "executor/instrument.h"
46 #include "executor/nodeSubplan.h"
47 #include "miscadmin.h"
48 #include "nodes/nodeFuncs.h"
49 #include "optimizer/clauses.h"
50 #include "parser/parse_clause.h"
51 #include "parser/parsetree.h"
52 #include "storage/bufmgr.h"
53 #include "storage/lmgr.h"
54 #include "storage/smgr.h"
55 #include "utils/acl.h"
56 #include "utils/builtins.h"
57 #include "utils/lsyscache.h"
58 #include "utils/memutils.h"
59 #include "utils/snapmgr.h"
60 #include "utils/tqual.h"
61
62
63 /* Hooks for plugins to get control in ExecutorStart/Run/End() */
64 ExecutorStart_hook_type ExecutorStart_hook = NULL;
65 ExecutorRun_hook_type   ExecutorRun_hook = NULL;
66 ExecutorEnd_hook_type   ExecutorEnd_hook = NULL;
67
68 typedef struct evalPlanQual
69 {
70         Index           rti;
71         EState     *estate;
72         PlanState  *planstate;
73         struct evalPlanQual *next;      /* stack of active PlanQual plans */
74         struct evalPlanQual *free;      /* list of free PlanQual plans */
75 } evalPlanQual;
76
77 /* decls for local routines only used within this module */
78 static void InitPlan(QueryDesc *queryDesc, int eflags);
79 static void ExecCheckPlanOutput(Relation resultRel, List *targetList);
80 static void ExecEndPlan(PlanState *planstate, EState *estate);
81 static void ExecutePlan(EState *estate, PlanState *planstate,
82                         CmdType operation,
83                         long numberTuples,
84                         ScanDirection direction,
85                         DestReceiver *dest);
86 static void ExecSelect(TupleTableSlot *slot,
87                    DestReceiver *dest, EState *estate);
88 static void ExecInsert(TupleTableSlot *slot, ItemPointer tupleid,
89                    TupleTableSlot *planSlot,
90                    DestReceiver *dest, EState *estate);
91 static void ExecDelete(ItemPointer tupleid,
92                    TupleTableSlot *planSlot,
93                    DestReceiver *dest, EState *estate);
94 static void ExecUpdate(TupleTableSlot *slot, ItemPointer tupleid,
95                    TupleTableSlot *planSlot,
96                    DestReceiver *dest, EState *estate);
97 static void ExecProcessReturning(ProjectionInfo *projectReturning,
98                                          TupleTableSlot *tupleSlot,
99                                          TupleTableSlot *planSlot,
100                                          DestReceiver *dest);
101 static TupleTableSlot *EvalPlanQualNext(EState *estate);
102 static void EndEvalPlanQual(EState *estate);
103 static void ExecCheckRTPerms(List *rangeTable);
104 static void ExecCheckRTEPerms(RangeTblEntry *rte);
105 static void ExecCheckXactReadOnly(PlannedStmt *plannedstmt);
106 static void EvalPlanQualStart(evalPlanQual *epq, EState *estate,
107                                   evalPlanQual *priorepq);
108 static void EvalPlanQualStop(evalPlanQual *epq);
109 static void OpenIntoRel(QueryDesc *queryDesc);
110 static void CloseIntoRel(QueryDesc *queryDesc);
111 static void intorel_startup(DestReceiver *self, int operation, TupleDesc typeinfo);
112 static void intorel_receive(TupleTableSlot *slot, DestReceiver *self);
113 static void intorel_shutdown(DestReceiver *self);
114 static void intorel_destroy(DestReceiver *self);
115
116 /* end of local decls */
117
118
119 /* ----------------------------------------------------------------
120  *              ExecutorStart
121  *
122  *              This routine must be called at the beginning of any execution of any
123  *              query plan
124  *
125  * Takes a QueryDesc previously created by CreateQueryDesc (it's not real
126  * clear why we bother to separate the two functions, but...).  The tupDesc
127  * field of the QueryDesc is filled in to describe the tuples that will be
128  * returned, and the internal fields (estate and planstate) are set up.
129  *
130  * eflags contains flag bits as described in executor.h.
131  *
132  * NB: the CurrentMemoryContext when this is called will become the parent
133  * of the per-query context used for this Executor invocation.
134  *
135  * We provide a function hook variable that lets loadable plugins
136  * get control when ExecutorStart is called.  Such a plugin would
137  * normally call standard_ExecutorStart().
138  *
139  * ----------------------------------------------------------------
140  */
141 void
142 ExecutorStart(QueryDesc *queryDesc, int eflags)
143 {
144         if (ExecutorStart_hook)
145                 (*ExecutorStart_hook) (queryDesc, eflags);
146         else
147                 standard_ExecutorStart(queryDesc, eflags);
148 }
149
150 void
151 standard_ExecutorStart(QueryDesc *queryDesc, int eflags)
152 {
153         EState     *estate;
154         MemoryContext oldcontext;
155
156         /* sanity checks: queryDesc must not be started already */
157         Assert(queryDesc != NULL);
158         Assert(queryDesc->estate == NULL);
159
160         /*
161          * If the transaction is read-only, we need to check if any writes are
162          * planned to non-temporary tables.  EXPLAIN is considered read-only.
163          */
164         if (XactReadOnly && !(eflags & EXEC_FLAG_EXPLAIN_ONLY))
165                 ExecCheckXactReadOnly(queryDesc->plannedstmt);
166
167         /*
168          * Build EState, switch into per-query memory context for startup.
169          */
170         estate = CreateExecutorState();
171         queryDesc->estate = estate;
172
173         oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
174
175         /*
176          * Fill in parameters, if any, from queryDesc
177          */
178         estate->es_param_list_info = queryDesc->params;
179
180         if (queryDesc->plannedstmt->nParamExec > 0)
181                 estate->es_param_exec_vals = (ParamExecData *)
182                         palloc0(queryDesc->plannedstmt->nParamExec * sizeof(ParamExecData));
183
184         /*
185          * If non-read-only query, set the command ID to mark output tuples with
186          */
187         switch (queryDesc->operation)
188         {
189                 case CMD_SELECT:
190                         /* SELECT INTO and SELECT FOR UPDATE/SHARE need to mark tuples */
191                         if (queryDesc->plannedstmt->intoClause != NULL ||
192                                 queryDesc->plannedstmt->rowMarks != NIL)
193                                 estate->es_output_cid = GetCurrentCommandId(true);
194                         break;
195
196                 case CMD_INSERT:
197                 case CMD_DELETE:
198                 case CMD_UPDATE:
199                         estate->es_output_cid = GetCurrentCommandId(true);
200                         break;
201
202                 default:
203                         elog(ERROR, "unrecognized operation code: %d",
204                                  (int) queryDesc->operation);
205                         break;
206         }
207
208         /*
209          * Copy other important information into the EState
210          */
211         estate->es_snapshot = RegisterSnapshot(queryDesc->snapshot);
212         estate->es_crosscheck_snapshot = RegisterSnapshot(queryDesc->crosscheck_snapshot);
213         estate->es_instrument = queryDesc->doInstrument;
214
215         /*
216          * Initialize the plan state tree
217          */
218         InitPlan(queryDesc, eflags);
219
220         MemoryContextSwitchTo(oldcontext);
221 }
222
223 /* ----------------------------------------------------------------
224  *              ExecutorRun
225  *
226  *              This is the main routine of the executor module. It accepts
227  *              the query descriptor from the traffic cop and executes the
228  *              query plan.
229  *
230  *              ExecutorStart must have been called already.
231  *
232  *              If direction is NoMovementScanDirection then nothing is done
233  *              except to start up/shut down the destination.  Otherwise,
234  *              we retrieve up to 'count' tuples in the specified direction.
235  *
236  *              Note: count = 0 is interpreted as no portal limit, i.e., run to
237  *              completion.
238  *
239  *              There is no return value, but output tuples (if any) are sent to
240  *              the destination receiver specified in the QueryDesc; and the number
241  *              of tuples processed at the top level can be found in
242  *              estate->es_processed.
243  *
244  *              We provide a function hook variable that lets loadable plugins
245  *              get control when ExecutorRun is called.  Such a plugin would
246  *              normally call standard_ExecutorRun().
247  *
248  * ----------------------------------------------------------------
249  */
250 void
251 ExecutorRun(QueryDesc *queryDesc,
252                         ScanDirection direction, long count)
253 {
254         if (ExecutorRun_hook)
255                 (*ExecutorRun_hook) (queryDesc, direction, count);
256         else
257                 standard_ExecutorRun(queryDesc, direction, count);
258 }
259
260 void
261 standard_ExecutorRun(QueryDesc *queryDesc,
262                                          ScanDirection direction, long count)
263 {
264         EState     *estate;
265         CmdType         operation;
266         DestReceiver *dest;
267         bool            sendTuples;
268         MemoryContext oldcontext;
269
270         /* sanity checks */
271         Assert(queryDesc != NULL);
272
273         estate = queryDesc->estate;
274
275         Assert(estate != NULL);
276
277         /*
278          * Switch into per-query memory context
279          */
280         oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
281
282         /* Allow instrumentation of ExecutorRun overall runtime */
283         if (queryDesc->totaltime)
284                 InstrStartNode(queryDesc->totaltime);
285
286         /*
287          * extract information from the query descriptor and the query feature.
288          */
289         operation = queryDesc->operation;
290         dest = queryDesc->dest;
291
292         /*
293          * startup tuple receiver, if we will be emitting tuples
294          */
295         estate->es_processed = 0;
296         estate->es_lastoid = InvalidOid;
297
298         sendTuples = (operation == CMD_SELECT ||
299                                   queryDesc->plannedstmt->returningLists);
300
301         if (sendTuples)
302                 (*dest->rStartup) (dest, operation, queryDesc->tupDesc);
303
304         /*
305          * run plan
306          */
307         if (!ScanDirectionIsNoMovement(direction))
308                 ExecutePlan(estate,
309                                         queryDesc->planstate,
310                                         operation,
311                                         count,
312                                         direction,
313                                         dest);
314
315         /*
316          * shutdown tuple receiver, if we started it
317          */
318         if (sendTuples)
319                 (*dest->rShutdown) (dest);
320
321         if (queryDesc->totaltime)
322                 InstrStopNode(queryDesc->totaltime, estate->es_processed);
323
324         MemoryContextSwitchTo(oldcontext);
325 }
326
327 /* ----------------------------------------------------------------
328  *              ExecutorEnd
329  *
330  *              This routine must be called at the end of execution of any
331  *              query plan
332  *
333  *              We provide a function hook variable that lets loadable plugins
334  *              get control when ExecutorEnd is called.  Such a plugin would
335  *              normally call standard_ExecutorEnd().
336  *
337  * ----------------------------------------------------------------
338  */
339 void
340 ExecutorEnd(QueryDesc *queryDesc)
341 {
342         if (ExecutorEnd_hook)
343                 (*ExecutorEnd_hook) (queryDesc);
344         else
345                 standard_ExecutorEnd(queryDesc);
346 }
347
348 void
349 standard_ExecutorEnd(QueryDesc *queryDesc)
350 {
351         EState     *estate;
352         MemoryContext oldcontext;
353
354         /* sanity checks */
355         Assert(queryDesc != NULL);
356
357         estate = queryDesc->estate;
358
359         Assert(estate != NULL);
360
361         /*
362          * Switch into per-query memory context to run ExecEndPlan
363          */
364         oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
365
366         ExecEndPlan(queryDesc->planstate, estate);
367
368         /*
369          * Close the SELECT INTO relation if any
370          */
371         if (estate->es_select_into)
372                 CloseIntoRel(queryDesc);
373
374         /* do away with our snapshots */
375         UnregisterSnapshot(estate->es_snapshot);
376         UnregisterSnapshot(estate->es_crosscheck_snapshot);
377
378         /*
379          * Must switch out of context before destroying it
380          */
381         MemoryContextSwitchTo(oldcontext);
382
383         /*
384          * Release EState and per-query memory context.  This should release
385          * everything the executor has allocated.
386          */
387         FreeExecutorState(estate);
388
389         /* Reset queryDesc fields that no longer point to anything */
390         queryDesc->tupDesc = NULL;
391         queryDesc->estate = NULL;
392         queryDesc->planstate = NULL;
393         queryDesc->totaltime = NULL;
394 }
395
396 /* ----------------------------------------------------------------
397  *              ExecutorRewind
398  *
399  *              This routine may be called on an open queryDesc to rewind it
400  *              to the start.
401  * ----------------------------------------------------------------
402  */
403 void
404 ExecutorRewind(QueryDesc *queryDesc)
405 {
406         EState     *estate;
407         MemoryContext oldcontext;
408
409         /* sanity checks */
410         Assert(queryDesc != NULL);
411
412         estate = queryDesc->estate;
413
414         Assert(estate != NULL);
415
416         /* It's probably not sensible to rescan updating queries */
417         Assert(queryDesc->operation == CMD_SELECT);
418
419         /*
420          * Switch into per-query memory context
421          */
422         oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
423
424         /*
425          * rescan plan
426          */
427         ExecReScan(queryDesc->planstate, NULL);
428
429         MemoryContextSwitchTo(oldcontext);
430 }
431
432
433 /*
434  * ExecCheckRTPerms
435  *              Check access permissions for all relations listed in a range table.
436  */
437 static void
438 ExecCheckRTPerms(List *rangeTable)
439 {
440         ListCell   *l;
441
442         foreach(l, rangeTable)
443         {
444                 ExecCheckRTEPerms((RangeTblEntry *) lfirst(l));
445         }
446 }
447
448 /*
449  * ExecCheckRTEPerms
450  *              Check access permissions for a single RTE.
451  */
452 static void
453 ExecCheckRTEPerms(RangeTblEntry *rte)
454 {
455         AclMode         requiredPerms;
456         Oid                     relOid;
457         Oid                     userid;
458
459         /*
460          * Only plain-relation RTEs need to be checked here.  Function RTEs are
461          * checked by init_fcache when the function is prepared for execution.
462          * Join, subquery, and special RTEs need no checks.
463          */
464         if (rte->rtekind != RTE_RELATION)
465                 return;
466
467         /*
468          * No work if requiredPerms is empty.
469          */
470         requiredPerms = rte->requiredPerms;
471         if (requiredPerms == 0)
472                 return;
473
474         relOid = rte->relid;
475
476         /*
477          * userid to check as: current user unless we have a setuid indication.
478          *
479          * Note: GetUserId() is presently fast enough that there's no harm in
480          * calling it separately for each RTE.  If that stops being true, we could
481          * call it once in ExecCheckRTPerms and pass the userid down from there.
482          * But for now, no need for the extra clutter.
483          */
484         userid = rte->checkAsUser ? rte->checkAsUser : GetUserId();
485
486         /*
487          * We must have *all* the requiredPerms bits, so use aclmask not aclcheck.
488          */
489         if (pg_class_aclmask(relOid, userid, requiredPerms, ACLMASK_ALL)
490                 != requiredPerms)
491                 aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_CLASS,
492                                            get_rel_name(relOid));
493 }
494
495 /*
496  * Check that the query does not imply any writes to non-temp tables.
497  */
498 static void
499 ExecCheckXactReadOnly(PlannedStmt *plannedstmt)
500 {
501         ListCell   *l;
502
503         /*
504          * CREATE TABLE AS or SELECT INTO?
505          *
506          * XXX should we allow this if the destination is temp?
507          */
508         if (plannedstmt->intoClause != NULL)
509                 goto fail;
510
511         /* Fail if write permissions are requested on any non-temp table */
512         foreach(l, plannedstmt->rtable)
513         {
514                 RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
515
516                 if (rte->rtekind != RTE_RELATION)
517                         continue;
518
519                 if ((rte->requiredPerms & (~ACL_SELECT)) == 0)
520                         continue;
521
522                 if (isTempNamespace(get_rel_namespace(rte->relid)))
523                         continue;
524
525                 goto fail;
526         }
527
528         return;
529
530 fail:
531         ereport(ERROR,
532                         (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
533                          errmsg("transaction is read-only")));
534 }
535
536
537 /* ----------------------------------------------------------------
538  *              InitPlan
539  *
540  *              Initializes the query plan: open files, allocate storage
541  *              and start up the rule manager
542  * ----------------------------------------------------------------
543  */
544 static void
545 InitPlan(QueryDesc *queryDesc, int eflags)
546 {
547         CmdType         operation = queryDesc->operation;
548         PlannedStmt *plannedstmt = queryDesc->plannedstmt;
549         Plan       *plan = plannedstmt->planTree;
550         List       *rangeTable = plannedstmt->rtable;
551         EState     *estate = queryDesc->estate;
552         PlanState  *planstate;
553         TupleDesc       tupType;
554         ListCell   *l;
555         int                     i;
556
557         /*
558          * Do permissions checks
559          */
560         ExecCheckRTPerms(rangeTable);
561
562         /*
563          * initialize the node's execution state
564          */
565         estate->es_range_table = rangeTable;
566
567         /*
568          * initialize result relation stuff
569          */
570         if (plannedstmt->resultRelations)
571         {
572                 List       *resultRelations = plannedstmt->resultRelations;
573                 int                     numResultRelations = list_length(resultRelations);
574                 ResultRelInfo *resultRelInfos;
575                 ResultRelInfo *resultRelInfo;
576
577                 resultRelInfos = (ResultRelInfo *)
578                         palloc(numResultRelations * sizeof(ResultRelInfo));
579                 resultRelInfo = resultRelInfos;
580                 foreach(l, resultRelations)
581                 {
582                         Index           resultRelationIndex = lfirst_int(l);
583                         Oid                     resultRelationOid;
584                         Relation        resultRelation;
585
586                         resultRelationOid = getrelid(resultRelationIndex, rangeTable);
587                         resultRelation = heap_open(resultRelationOid, RowExclusiveLock);
588                         InitResultRelInfo(resultRelInfo,
589                                                           resultRelation,
590                                                           resultRelationIndex,
591                                                           operation,
592                                                           estate->es_instrument);
593                         resultRelInfo++;
594                 }
595                 estate->es_result_relations = resultRelInfos;
596                 estate->es_num_result_relations = numResultRelations;
597                 /* Initialize to first or only result rel */
598                 estate->es_result_relation_info = resultRelInfos;
599         }
600         else
601         {
602                 /*
603                  * if no result relation, then set state appropriately
604                  */
605                 estate->es_result_relations = NULL;
606                 estate->es_num_result_relations = 0;
607                 estate->es_result_relation_info = NULL;
608         }
609
610         /*
611          * Detect whether we're doing SELECT INTO.  If so, set the es_into_oids
612          * flag appropriately so that the plan tree will be initialized with the
613          * correct tuple descriptors.  (Other SELECT INTO stuff comes later.)
614          */
615         estate->es_select_into = false;
616         if (operation == CMD_SELECT && plannedstmt->intoClause != NULL)
617         {
618                 estate->es_select_into = true;
619                 estate->es_into_oids = interpretOidsOption(plannedstmt->intoClause->options);
620         }
621
622         /*
623          * Have to lock relations selected FOR UPDATE/FOR SHARE before we
624          * initialize the plan tree, else we'd be doing a lock upgrade. While we
625          * are at it, build the ExecRowMark list.
626          */
627         estate->es_rowMarks = NIL;
628         foreach(l, plannedstmt->rowMarks)
629         {
630                 RowMarkClause *rc = (RowMarkClause *) lfirst(l);
631                 Oid                     relid;
632                 Relation        relation;
633                 ExecRowMark *erm;
634
635                 /* ignore "parent" rowmarks; they are irrelevant at runtime */
636                 if (rc->isParent)
637                         continue;
638
639                 relid = getrelid(rc->rti, rangeTable);
640                 relation = heap_open(relid, RowShareLock);
641                 erm = (ExecRowMark *) palloc(sizeof(ExecRowMark));
642                 erm->relation = relation;
643                 erm->rti = rc->rti;
644                 erm->prti = rc->prti;
645                 erm->forUpdate = rc->forUpdate;
646                 erm->noWait = rc->noWait;
647                 /* We'll locate the junk attrs below */
648                 erm->ctidAttNo = InvalidAttrNumber;
649                 erm->toidAttNo = InvalidAttrNumber;
650                 ItemPointerSetInvalid(&(erm->curCtid));
651                 estate->es_rowMarks = lappend(estate->es_rowMarks, erm);
652         }
653
654         /*
655          * Initialize the executor "tuple" table.  We need slots for all the plan
656          * nodes, plus possibly output slots for the junkfilter(s). At this point
657          * we aren't sure if we need junkfilters, so just add slots for them
658          * unconditionally.  Also, if it's not a SELECT, set up a slot for use for
659          * trigger output tuples.  Also, one for RETURNING-list evaluation.
660          */
661         {
662                 int                     nSlots;
663
664                 /* Slots for the main plan tree */
665                 nSlots = ExecCountSlotsNode(plan);
666                 /* Add slots for subplans and initplans */
667                 foreach(l, plannedstmt->subplans)
668                 {
669                         Plan       *subplan = (Plan *) lfirst(l);
670
671                         nSlots += ExecCountSlotsNode(subplan);
672                 }
673                 /* Add slots for junkfilter(s) */
674                 if (plannedstmt->resultRelations != NIL)
675                         nSlots += list_length(plannedstmt->resultRelations);
676                 else
677                         nSlots += 1;
678                 if (operation != CMD_SELECT)
679                         nSlots++;                       /* for es_trig_tuple_slot */
680                 if (plannedstmt->returningLists)
681                         nSlots++;                       /* for RETURNING projection */
682
683                 estate->es_tupleTable = ExecCreateTupleTable(nSlots);
684
685                 if (operation != CMD_SELECT)
686                         estate->es_trig_tuple_slot =
687                                 ExecAllocTableSlot(estate->es_tupleTable);
688         }
689
690         /* mark EvalPlanQual not active */
691         estate->es_plannedstmt = plannedstmt;
692         estate->es_evalPlanQual = NULL;
693         estate->es_evTupleNull = NULL;
694         estate->es_evTuple = NULL;
695         estate->es_useEvalPlan = false;
696
697         /*
698          * Initialize private state information for each SubPlan.  We must do this
699          * before running ExecInitNode on the main query tree, since
700          * ExecInitSubPlan expects to be able to find these entries.
701          */
702         Assert(estate->es_subplanstates == NIL);
703         i = 1;                                          /* subplan indices count from 1 */
704         foreach(l, plannedstmt->subplans)
705         {
706                 Plan       *subplan = (Plan *) lfirst(l);
707                 PlanState  *subplanstate;
708                 int                     sp_eflags;
709
710                 /*
711                  * A subplan will never need to do BACKWARD scan nor MARK/RESTORE. If
712                  * it is a parameterless subplan (not initplan), we suggest that it be
713                  * prepared to handle REWIND efficiently; otherwise there is no need.
714                  */
715                 sp_eflags = eflags & EXEC_FLAG_EXPLAIN_ONLY;
716                 if (bms_is_member(i, plannedstmt->rewindPlanIDs))
717                         sp_eflags |= EXEC_FLAG_REWIND;
718
719                 subplanstate = ExecInitNode(subplan, estate, sp_eflags);
720
721                 estate->es_subplanstates = lappend(estate->es_subplanstates,
722                                                                                    subplanstate);
723
724                 i++;
725         }
726
727         /*
728          * Initialize the private state information for all the nodes in the query
729          * tree.  This opens files, allocates storage and leaves us ready to start
730          * processing tuples.
731          */
732         planstate = ExecInitNode(plan, estate, eflags);
733
734         /*
735          * Get the tuple descriptor describing the type of tuples to return. (this
736          * is especially important if we are creating a relation with "SELECT
737          * INTO")
738          */
739         tupType = ExecGetResultType(planstate);
740
741         /*
742          * Initialize the junk filter if needed.  SELECT and INSERT queries need a
743          * filter if there are any junk attrs in the tlist.  UPDATE and
744          * DELETE always need a filter, since there's always a junk 'ctid'
745          * attribute present --- no need to look first.
746          *
747          * This section of code is also a convenient place to verify that the
748          * output of an INSERT or UPDATE matches the target table(s).
749          */
750         {
751                 bool            junk_filter_needed = false;
752                 ListCell   *tlist;
753
754                 switch (operation)
755                 {
756                         case CMD_SELECT:
757                         case CMD_INSERT:
758                                 foreach(tlist, plan->targetlist)
759                                 {
760                                         TargetEntry *tle = (TargetEntry *) lfirst(tlist);
761
762                                         if (tle->resjunk)
763                                         {
764                                                 junk_filter_needed = true;
765                                                 break;
766                                         }
767                                 }
768                                 break;
769                         case CMD_UPDATE:
770                         case CMD_DELETE:
771                                 junk_filter_needed = true;
772                                 break;
773                         default:
774                                 break;
775                 }
776
777                 if (junk_filter_needed)
778                 {
779                         /*
780                          * If there are multiple result relations, each one needs its own
781                          * junk filter.  Note this is only possible for UPDATE/DELETE, so
782                          * we can't be fooled by some needing a filter and some not.
783                          */
784                         if (list_length(plannedstmt->resultRelations) > 1)
785                         {
786                                 PlanState **appendplans;
787                                 int                     as_nplans;
788                                 ResultRelInfo *resultRelInfo;
789
790                                 /* Top plan had better be an Append here. */
791                                 Assert(IsA(plan, Append));
792                                 Assert(((Append *) plan)->isTarget);
793                                 Assert(IsA(planstate, AppendState));
794                                 appendplans = ((AppendState *) planstate)->appendplans;
795                                 as_nplans = ((AppendState *) planstate)->as_nplans;
796                                 Assert(as_nplans == estate->es_num_result_relations);
797                                 resultRelInfo = estate->es_result_relations;
798                                 for (i = 0; i < as_nplans; i++)
799                                 {
800                                         PlanState  *subplan = appendplans[i];
801                                         JunkFilter *j;
802
803                                         if (operation == CMD_UPDATE)
804                                                 ExecCheckPlanOutput(resultRelInfo->ri_RelationDesc,
805                                                                                         subplan->plan->targetlist);
806
807                                         j = ExecInitJunkFilter(subplan->plan->targetlist,
808                                                         resultRelInfo->ri_RelationDesc->rd_att->tdhasoid,
809                                                                   ExecAllocTableSlot(estate->es_tupleTable));
810
811                                         /*
812                                          * Since it must be UPDATE/DELETE, there had better be a
813                                          * "ctid" junk attribute in the tlist ... but ctid could
814                                          * be at a different resno for each result relation. We
815                                          * look up the ctid resnos now and save them in the
816                                          * junkfilters.
817                                          */
818                                         j->jf_junkAttNo = ExecFindJunkAttribute(j, "ctid");
819                                         if (!AttributeNumberIsValid(j->jf_junkAttNo))
820                                                 elog(ERROR, "could not find junk ctid column");
821                                         resultRelInfo->ri_junkFilter = j;
822                                         resultRelInfo++;
823                                 }
824
825                                 /*
826                                  * Set active junkfilter too; at this point ExecInitAppend has
827                                  * already selected an active result relation...
828                                  */
829                                 estate->es_junkFilter =
830                                         estate->es_result_relation_info->ri_junkFilter;
831
832                                 /*
833                                  * We currently can't support rowmarks in this case, because
834                                  * the associated junk CTIDs might have different resnos in
835                                  * different subplans.
836                                  */
837                                 if (estate->es_rowMarks)
838                                         ereport(ERROR,
839                                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
840                                                          errmsg("SELECT FOR UPDATE/SHARE is not supported within a query with multiple result relations")));
841                         }
842                         else
843                         {
844                                 /* Normal case with just one JunkFilter */
845                                 JunkFilter *j;
846
847                                 if (operation == CMD_INSERT || operation == CMD_UPDATE)
848                                         ExecCheckPlanOutput(estate->es_result_relation_info->ri_RelationDesc,
849                                                                                 planstate->plan->targetlist);
850
851                                 j = ExecInitJunkFilter(planstate->plan->targetlist,
852                                                                            tupType->tdhasoid,
853                                                                   ExecAllocTableSlot(estate->es_tupleTable));
854                                 estate->es_junkFilter = j;
855                                 if (estate->es_result_relation_info)
856                                         estate->es_result_relation_info->ri_junkFilter = j;
857
858                                 if (operation == CMD_SELECT)
859                                 {
860                                         /* For SELECT, want to return the cleaned tuple type */
861                                         tupType = j->jf_cleanTupType;
862                                 }
863                                 else if (operation == CMD_UPDATE || operation == CMD_DELETE)
864                                 {
865                                         /* For UPDATE/DELETE, find the ctid junk attr now */
866                                         j->jf_junkAttNo = ExecFindJunkAttribute(j, "ctid");
867                                         if (!AttributeNumberIsValid(j->jf_junkAttNo))
868                                                 elog(ERROR, "could not find junk ctid column");
869                                 }
870
871                                 /* For SELECT FOR UPDATE/SHARE, find the junk attrs now */
872                                 foreach(l, estate->es_rowMarks)
873                                 {
874                                         ExecRowMark *erm = (ExecRowMark *) lfirst(l);
875                                         char            resname[32];
876
877                                         /* always need the ctid */
878                                         snprintf(resname, sizeof(resname), "ctid%u",
879                                                          erm->prti);
880                                         erm->ctidAttNo = ExecFindJunkAttribute(j, resname);
881                                         if (!AttributeNumberIsValid(erm->ctidAttNo))
882                                                 elog(ERROR, "could not find junk \"%s\" column",
883                                                          resname);
884                                         /* if child relation, need tableoid too */
885                                         if (erm->rti != erm->prti)
886                                         {
887                                                 snprintf(resname, sizeof(resname), "tableoid%u",
888                                                                  erm->prti);
889                                                 erm->toidAttNo = ExecFindJunkAttribute(j, resname);
890                                                 if (!AttributeNumberIsValid(erm->toidAttNo))
891                                                         elog(ERROR, "could not find junk \"%s\" column",
892                                                                  resname);
893                                         }
894                                 }
895                         }
896                 }
897                 else
898                 {
899                         if (operation == CMD_INSERT)
900                                 ExecCheckPlanOutput(estate->es_result_relation_info->ri_RelationDesc,
901                                                                         planstate->plan->targetlist);
902
903                         estate->es_junkFilter = NULL;
904                         if (estate->es_rowMarks)
905                                 elog(ERROR, "SELECT FOR UPDATE/SHARE, but no junk columns");
906                 }
907         }
908
909         /*
910          * Initialize RETURNING projections if needed.
911          */
912         if (plannedstmt->returningLists)
913         {
914                 TupleTableSlot *slot;
915                 ExprContext *econtext;
916                 ResultRelInfo *resultRelInfo;
917
918                 /*
919                  * We set QueryDesc.tupDesc to be the RETURNING rowtype in this case.
920                  * We assume all the sublists will generate the same output tupdesc.
921                  */
922                 tupType = ExecTypeFromTL((List *) linitial(plannedstmt->returningLists),
923                                                                  false);
924
925                 /* Set up a slot for the output of the RETURNING projection(s) */
926                 slot = ExecAllocTableSlot(estate->es_tupleTable);
927                 ExecSetSlotDescriptor(slot, tupType);
928                 /* Need an econtext too */
929                 econtext = CreateExprContext(estate);
930
931                 /*
932                  * Build a projection for each result rel.      Note that any SubPlans in
933                  * the RETURNING lists get attached to the topmost plan node.
934                  */
935                 Assert(list_length(plannedstmt->returningLists) == estate->es_num_result_relations);
936                 resultRelInfo = estate->es_result_relations;
937                 foreach(l, plannedstmt->returningLists)
938                 {
939                         List       *rlist = (List *) lfirst(l);
940                         List       *rliststate;
941
942                         rliststate = (List *) ExecInitExpr((Expr *) rlist, planstate);
943                         resultRelInfo->ri_projectReturning =
944                                 ExecBuildProjectionInfo(rliststate, econtext, slot,
945                                                                          resultRelInfo->ri_RelationDesc->rd_att);
946                         resultRelInfo++;
947                 }
948         }
949
950         queryDesc->tupDesc = tupType;
951         queryDesc->planstate = planstate;
952
953         /*
954          * If doing SELECT INTO, initialize the "into" relation.  We must wait
955          * till now so we have the "clean" result tuple type to create the new
956          * table from.
957          *
958          * If EXPLAIN, skip creating the "into" relation.
959          */
960         if (estate->es_select_into && !(eflags & EXEC_FLAG_EXPLAIN_ONLY))
961                 OpenIntoRel(queryDesc);
962 }
963
964 /*
965  * Initialize ResultRelInfo data for one result relation
966  */
967 void
968 InitResultRelInfo(ResultRelInfo *resultRelInfo,
969                                   Relation resultRelationDesc,
970                                   Index resultRelationIndex,
971                                   CmdType operation,
972                                   bool doInstrument)
973 {
974         /*
975          * Check valid relkind ... parser and/or planner should have noticed this
976          * already, but let's make sure.
977          */
978         switch (resultRelationDesc->rd_rel->relkind)
979         {
980                 case RELKIND_RELATION:
981                         /* OK */
982                         break;
983                 case RELKIND_SEQUENCE:
984                         ereport(ERROR,
985                                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
986                                          errmsg("cannot change sequence \"%s\"",
987                                                         RelationGetRelationName(resultRelationDesc))));
988                         break;
989                 case RELKIND_TOASTVALUE:
990                         ereport(ERROR,
991                                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
992                                          errmsg("cannot change TOAST relation \"%s\"",
993                                                         RelationGetRelationName(resultRelationDesc))));
994                         break;
995                 case RELKIND_VIEW:
996                         ereport(ERROR,
997                                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
998                                          errmsg("cannot change view \"%s\"",
999                                                         RelationGetRelationName(resultRelationDesc))));
1000                         break;
1001                 default:
1002                         ereport(ERROR,
1003                                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1004                                          errmsg("cannot change relation \"%s\"",
1005                                                         RelationGetRelationName(resultRelationDesc))));
1006                         break;
1007         }
1008
1009         /* OK, fill in the node */
1010         MemSet(resultRelInfo, 0, sizeof(ResultRelInfo));
1011         resultRelInfo->type = T_ResultRelInfo;
1012         resultRelInfo->ri_RangeTableIndex = resultRelationIndex;
1013         resultRelInfo->ri_RelationDesc = resultRelationDesc;
1014         resultRelInfo->ri_NumIndices = 0;
1015         resultRelInfo->ri_IndexRelationDescs = NULL;
1016         resultRelInfo->ri_IndexRelationInfo = NULL;
1017         /* make a copy so as not to depend on relcache info not changing... */
1018         resultRelInfo->ri_TrigDesc = CopyTriggerDesc(resultRelationDesc->trigdesc);
1019         if (resultRelInfo->ri_TrigDesc)
1020         {
1021                 int                     n = resultRelInfo->ri_TrigDesc->numtriggers;
1022
1023                 resultRelInfo->ri_TrigFunctions = (FmgrInfo *)
1024                         palloc0(n * sizeof(FmgrInfo));
1025                 if (doInstrument)
1026                         resultRelInfo->ri_TrigInstrument = InstrAlloc(n);
1027                 else
1028                         resultRelInfo->ri_TrigInstrument = NULL;
1029         }
1030         else
1031         {
1032                 resultRelInfo->ri_TrigFunctions = NULL;
1033                 resultRelInfo->ri_TrigInstrument = NULL;
1034         }
1035         resultRelInfo->ri_ConstraintExprs = NULL;
1036         resultRelInfo->ri_junkFilter = NULL;
1037         resultRelInfo->ri_projectReturning = NULL;
1038
1039         /*
1040          * If there are indices on the result relation, open them and save
1041          * descriptors in the result relation info, so that we can add new index
1042          * entries for the tuples we add/update.  We need not do this for a
1043          * DELETE, however, since deletion doesn't affect indexes.
1044          */
1045         if (resultRelationDesc->rd_rel->relhasindex &&
1046                 operation != CMD_DELETE)
1047                 ExecOpenIndices(resultRelInfo);
1048 }
1049
1050 /*
1051  * Verify that the tuples to be produced by INSERT or UPDATE match the
1052  * target relation's rowtype
1053  *
1054  * We do this to guard against stale plans.  If plan invalidation is
1055  * functioning properly then we should never get a failure here, but better
1056  * safe than sorry.  Note that this is called after we have obtained lock
1057  * on the target rel, so the rowtype can't change underneath us.
1058  *
1059  * The plan output is represented by its targetlist, because that makes
1060  * handling the dropped-column case easier.
1061  */
1062 static void
1063 ExecCheckPlanOutput(Relation resultRel, List *targetList)
1064 {
1065         TupleDesc       resultDesc = RelationGetDescr(resultRel);
1066         int                     attno = 0;
1067         ListCell   *lc;
1068
1069         foreach(lc, targetList)
1070         {
1071                 TargetEntry *tle = (TargetEntry *) lfirst(lc);
1072                 Form_pg_attribute attr;
1073
1074                 if (tle->resjunk)
1075                         continue;                       /* ignore junk tlist items */
1076
1077                 if (attno >= resultDesc->natts)
1078                         ereport(ERROR,
1079                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
1080                                          errmsg("table row type and query-specified row type do not match"),
1081                                          errdetail("Query has too many columns.")));
1082                 attr = resultDesc->attrs[attno++];
1083
1084                 if (!attr->attisdropped)
1085                 {
1086                         /* Normal case: demand type match */
1087                         if (exprType((Node *) tle->expr) != attr->atttypid)
1088                                 ereport(ERROR,
1089                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
1090                                                  errmsg("table row type and query-specified row type do not match"),
1091                                                  errdetail("Table has type %s at ordinal position %d, but query expects %s.",
1092                                                                    format_type_be(attr->atttypid),
1093                                                                    attno,
1094                                                                    format_type_be(exprType((Node *) tle->expr)))));
1095                 }
1096                 else
1097                 {
1098                         /*
1099                          * For a dropped column, we can't check atttypid (it's likely 0).
1100                          * In any case the planner has most likely inserted an INT4 null.
1101                          * What we insist on is just *some* NULL constant.
1102                          */
1103                         if (!IsA(tle->expr, Const) ||
1104                                 !((Const *) tle->expr)->constisnull)
1105                                 ereport(ERROR,
1106                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
1107                                                  errmsg("table row type and query-specified row type do not match"),
1108                                                  errdetail("Query provides a value for a dropped column at ordinal position %d.",
1109                                                                    attno)));
1110                 }
1111         }
1112         if (attno != resultDesc->natts)
1113                 ereport(ERROR,
1114                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
1115                                  errmsg("table row type and query-specified row type do not match"),
1116                                  errdetail("Query has too few columns.")));
1117 }
1118
1119 /*
1120  *              ExecGetTriggerResultRel
1121  *
1122  * Get a ResultRelInfo for a trigger target relation.  Most of the time,
1123  * triggers are fired on one of the result relations of the query, and so
1124  * we can just return a member of the es_result_relations array.  (Note: in
1125  * self-join situations there might be multiple members with the same OID;
1126  * if so it doesn't matter which one we pick.)  However, it is sometimes
1127  * necessary to fire triggers on other relations; this happens mainly when an
1128  * RI update trigger queues additional triggers on other relations, which will
1129  * be processed in the context of the outer query.      For efficiency's sake,
1130  * we want to have a ResultRelInfo for those triggers too; that can avoid
1131  * repeated re-opening of the relation.  (It also provides a way for EXPLAIN
1132  * ANALYZE to report the runtimes of such triggers.)  So we make additional
1133  * ResultRelInfo's as needed, and save them in es_trig_target_relations.
1134  */
1135 ResultRelInfo *
1136 ExecGetTriggerResultRel(EState *estate, Oid relid)
1137 {
1138         ResultRelInfo *rInfo;
1139         int                     nr;
1140         ListCell   *l;
1141         Relation        rel;
1142         MemoryContext oldcontext;
1143
1144         /* First, search through the query result relations */
1145         rInfo = estate->es_result_relations;
1146         nr = estate->es_num_result_relations;
1147         while (nr > 0)
1148         {
1149                 if (RelationGetRelid(rInfo->ri_RelationDesc) == relid)
1150                         return rInfo;
1151                 rInfo++;
1152                 nr--;
1153         }
1154         /* Nope, but maybe we already made an extra ResultRelInfo for it */
1155         foreach(l, estate->es_trig_target_relations)
1156         {
1157                 rInfo = (ResultRelInfo *) lfirst(l);
1158                 if (RelationGetRelid(rInfo->ri_RelationDesc) == relid)
1159                         return rInfo;
1160         }
1161         /* Nope, so we need a new one */
1162
1163         /*
1164          * Open the target relation's relcache entry.  We assume that an
1165          * appropriate lock is still held by the backend from whenever the trigger
1166          * event got queued, so we need take no new lock here.
1167          */
1168         rel = heap_open(relid, NoLock);
1169
1170         /*
1171          * Make the new entry in the right context.  Currently, we don't need any
1172          * index information in ResultRelInfos used only for triggers, so tell
1173          * InitResultRelInfo it's a DELETE.
1174          */
1175         oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1176         rInfo = makeNode(ResultRelInfo);
1177         InitResultRelInfo(rInfo,
1178                                           rel,
1179                                           0,            /* dummy rangetable index */
1180                                           CMD_DELETE,
1181                                           estate->es_instrument);
1182         estate->es_trig_target_relations =
1183                 lappend(estate->es_trig_target_relations, rInfo);
1184         MemoryContextSwitchTo(oldcontext);
1185
1186         return rInfo;
1187 }
1188
1189 /*
1190  *              ExecContextForcesOids
1191  *
1192  * This is pretty grotty: when doing INSERT, UPDATE, or SELECT INTO,
1193  * we need to ensure that result tuples have space for an OID iff they are
1194  * going to be stored into a relation that has OIDs.  In other contexts
1195  * we are free to choose whether to leave space for OIDs in result tuples
1196  * (we generally don't want to, but we do if a physical-tlist optimization
1197  * is possible).  This routine checks the plan context and returns TRUE if the
1198  * choice is forced, FALSE if the choice is not forced.  In the TRUE case,
1199  * *hasoids is set to the required value.
1200  *
1201  * One reason this is ugly is that all plan nodes in the plan tree will emit
1202  * tuples with space for an OID, though we really only need the topmost node
1203  * to do so.  However, node types like Sort don't project new tuples but just
1204  * return their inputs, and in those cases the requirement propagates down
1205  * to the input node.  Eventually we might make this code smart enough to
1206  * recognize how far down the requirement really goes, but for now we just
1207  * make all plan nodes do the same thing if the top level forces the choice.
1208  *
1209  * We assume that estate->es_result_relation_info is already set up to
1210  * describe the target relation.  Note that in an UPDATE that spans an
1211  * inheritance tree, some of the target relations may have OIDs and some not.
1212  * We have to make the decisions on a per-relation basis as we initialize
1213  * each of the child plans of the topmost Append plan.
1214  *
1215  * SELECT INTO is even uglier, because we don't have the INTO relation's
1216  * descriptor available when this code runs; we have to look aside at a
1217  * flag set by InitPlan().
1218  */
1219 bool
1220 ExecContextForcesOids(PlanState *planstate, bool *hasoids)
1221 {
1222         if (planstate->state->es_select_into)
1223         {
1224                 *hasoids = planstate->state->es_into_oids;
1225                 return true;
1226         }
1227         else
1228         {
1229                 ResultRelInfo *ri = planstate->state->es_result_relation_info;
1230
1231                 if (ri != NULL)
1232                 {
1233                         Relation        rel = ri->ri_RelationDesc;
1234
1235                         if (rel != NULL)
1236                         {
1237                                 *hasoids = rel->rd_rel->relhasoids;
1238                                 return true;
1239                         }
1240                 }
1241         }
1242
1243         return false;
1244 }
1245
1246 /* ----------------------------------------------------------------
1247  *              ExecEndPlan
1248  *
1249  *              Cleans up the query plan -- closes files and frees up storage
1250  *
1251  * NOTE: we are no longer very worried about freeing storage per se
1252  * in this code; FreeExecutorState should be guaranteed to release all
1253  * memory that needs to be released.  What we are worried about doing
1254  * is closing relations and dropping buffer pins.  Thus, for example,
1255  * tuple tables must be cleared or dropped to ensure pins are released.
1256  * ----------------------------------------------------------------
1257  */
1258 static void
1259 ExecEndPlan(PlanState *planstate, EState *estate)
1260 {
1261         ResultRelInfo *resultRelInfo;
1262         int                     i;
1263         ListCell   *l;
1264
1265         /*
1266          * shut down any PlanQual processing we were doing
1267          */
1268         if (estate->es_evalPlanQual != NULL)
1269                 EndEvalPlanQual(estate);
1270
1271         /*
1272          * shut down the node-type-specific query processing
1273          */
1274         ExecEndNode(planstate);
1275
1276         /*
1277          * for subplans too
1278          */
1279         foreach(l, estate->es_subplanstates)
1280         {
1281                 PlanState  *subplanstate = (PlanState *) lfirst(l);
1282
1283                 ExecEndNode(subplanstate);
1284         }
1285
1286         /*
1287          * destroy the executor "tuple" table.
1288          */
1289         ExecDropTupleTable(estate->es_tupleTable, true);
1290         estate->es_tupleTable = NULL;
1291
1292         /*
1293          * close the result relation(s) if any, but hold locks until xact commit.
1294          */
1295         resultRelInfo = estate->es_result_relations;
1296         for (i = estate->es_num_result_relations; i > 0; i--)
1297         {
1298                 /* Close indices and then the relation itself */
1299                 ExecCloseIndices(resultRelInfo);
1300                 heap_close(resultRelInfo->ri_RelationDesc, NoLock);
1301                 resultRelInfo++;
1302         }
1303
1304         /*
1305          * likewise close any trigger target relations
1306          */
1307         foreach(l, estate->es_trig_target_relations)
1308         {
1309                 resultRelInfo = (ResultRelInfo *) lfirst(l);
1310                 /* Close indices and then the relation itself */
1311                 ExecCloseIndices(resultRelInfo);
1312                 heap_close(resultRelInfo->ri_RelationDesc, NoLock);
1313         }
1314
1315         /*
1316          * close any relations selected FOR UPDATE/FOR SHARE, again keeping locks
1317          */
1318         foreach(l, estate->es_rowMarks)
1319         {
1320                 ExecRowMark *erm = lfirst(l);
1321
1322                 heap_close(erm->relation, NoLock);
1323         }
1324 }
1325
1326 /* ----------------------------------------------------------------
1327  *              ExecutePlan
1328  *
1329  *              Processes the query plan until we have processed 'numberTuples' tuples,
1330  *              moving in the specified direction.
1331  *
1332  *              Runs to completion if numberTuples is 0
1333  *
1334  * Note: the ctid attribute is a 'junk' attribute that is removed before the
1335  * user can see it
1336  * ----------------------------------------------------------------
1337  */
1338 static void
1339 ExecutePlan(EState *estate,
1340                         PlanState *planstate,
1341                         CmdType operation,
1342                         long numberTuples,
1343                         ScanDirection direction,
1344                         DestReceiver *dest)
1345 {
1346         JunkFilter *junkfilter;
1347         TupleTableSlot *planSlot;
1348         TupleTableSlot *slot;
1349         ItemPointer tupleid = NULL;
1350         ItemPointerData tuple_ctid;
1351         long            current_tuple_count;
1352
1353         /*
1354          * initialize local variables
1355          */
1356         current_tuple_count = 0;
1357
1358         /*
1359          * Set the direction.
1360          */
1361         estate->es_direction = direction;
1362
1363         /*
1364          * Process BEFORE EACH STATEMENT triggers
1365          */
1366         switch (operation)
1367         {
1368                 case CMD_UPDATE:
1369                         ExecBSUpdateTriggers(estate, estate->es_result_relation_info);
1370                         break;
1371                 case CMD_DELETE:
1372                         ExecBSDeleteTriggers(estate, estate->es_result_relation_info);
1373                         break;
1374                 case CMD_INSERT:
1375                         ExecBSInsertTriggers(estate, estate->es_result_relation_info);
1376                         break;
1377                 default:
1378                         /* do nothing */
1379                         break;
1380         }
1381
1382         /*
1383          * Loop until we've processed the proper number of tuples from the plan.
1384          */
1385         for (;;)
1386         {
1387                 /* Reset the per-output-tuple exprcontext */
1388                 ResetPerTupleExprContext(estate);
1389
1390                 /*
1391                  * Execute the plan and obtain a tuple
1392                  */
1393 lnext:  ;
1394                 if (estate->es_useEvalPlan)
1395                 {
1396                         planSlot = EvalPlanQualNext(estate);
1397                         if (TupIsNull(planSlot))
1398                                 planSlot = ExecProcNode(planstate);
1399                 }
1400                 else
1401                         planSlot = ExecProcNode(planstate);
1402
1403                 /*
1404                  * if the tuple is null, then we assume there is nothing more to
1405                  * process so we just end the loop...
1406                  */
1407                 if (TupIsNull(planSlot))
1408                         break;
1409                 slot = planSlot;
1410
1411                 /*
1412                  * If we have a junk filter, then project a new tuple with the junk
1413                  * removed.
1414                  *
1415                  * Store this new "clean" tuple in the junkfilter's resultSlot.
1416                  * (Formerly, we stored it back over the "dirty" tuple, which is WRONG
1417                  * because that tuple slot has the wrong descriptor.)
1418                  *
1419                  * But first, extract all the junk information we need.
1420                  */
1421                 if ((junkfilter = estate->es_junkFilter) != NULL)
1422                 {
1423                         /*
1424                          * Process any FOR UPDATE or FOR SHARE locking requested.
1425                          */
1426                         if (estate->es_rowMarks != NIL)
1427                         {
1428                                 ListCell   *l;
1429
1430                 lmark:  ;
1431                                 foreach(l, estate->es_rowMarks)
1432                                 {
1433                                         ExecRowMark *erm = lfirst(l);
1434                                         Datum           datum;
1435                                         bool            isNull;
1436                                         HeapTupleData tuple;
1437                                         Buffer          buffer;
1438                                         ItemPointerData update_ctid;
1439                                         TransactionId update_xmax;
1440                                         TupleTableSlot *newSlot;
1441                                         LockTupleMode lockmode;
1442                                         HTSU_Result test;
1443
1444                                         /* if child rel, must check whether it produced this row */
1445                                         if (erm->rti != erm->prti)
1446                                         {
1447                                                 Oid             tableoid;
1448
1449                                                 datum = ExecGetJunkAttribute(slot,
1450                                                                                                          erm->toidAttNo,
1451                                                                                                          &isNull);
1452                                                 /* shouldn't ever get a null result... */
1453                                                 if (isNull)
1454                                                         elog(ERROR, "tableoid is NULL");
1455                                                 tableoid = DatumGetObjectId(datum);
1456
1457                                                 if (tableoid != RelationGetRelid(erm->relation))
1458                                                 {
1459                                                         /* this child is inactive right now */
1460                                                         ItemPointerSetInvalid(&(erm->curCtid));
1461                                                         continue;
1462                                                 }
1463                                         }
1464
1465                                         /* okay, fetch the tuple by ctid */
1466                                         datum = ExecGetJunkAttribute(slot,
1467                                                                                                  erm->ctidAttNo,
1468                                                                                                  &isNull);
1469                                         /* shouldn't ever get a null result... */
1470                                         if (isNull)
1471                                                 elog(ERROR, "ctid is NULL");
1472                                         tuple.t_self = *((ItemPointer) DatumGetPointer(datum));
1473
1474                                         if (erm->forUpdate)
1475                                                 lockmode = LockTupleExclusive;
1476                                         else
1477                                                 lockmode = LockTupleShared;
1478
1479                                         test = heap_lock_tuple(erm->relation, &tuple, &buffer,
1480                                                                                    &update_ctid, &update_xmax,
1481                                                                                    estate->es_output_cid,
1482                                                                                    lockmode, erm->noWait);
1483                                         ReleaseBuffer(buffer);
1484                                         switch (test)
1485                                         {
1486                                                 case HeapTupleSelfUpdated:
1487                                                         /* treat it as deleted; do not process */
1488                                                         goto lnext;
1489
1490                                                 case HeapTupleMayBeUpdated:
1491                                                         break;
1492
1493                                                 case HeapTupleUpdated:
1494                                                         if (IsXactIsoLevelSerializable)
1495                                                                 ereport(ERROR,
1496                                                                  (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
1497                                                                   errmsg("could not serialize access due to concurrent update")));
1498                                                         if (!ItemPointerEquals(&update_ctid,
1499                                                                                                    &tuple.t_self))
1500                                                         {
1501                                                                 /* updated, so look at updated version */
1502                                                                 newSlot = EvalPlanQual(estate,
1503                                                                                                            erm->rti,
1504                                                                                                            &update_ctid,
1505                                                                                                            update_xmax);
1506                                                                 if (!TupIsNull(newSlot))
1507                                                                 {
1508                                                                         slot = planSlot = newSlot;
1509                                                                         estate->es_useEvalPlan = true;
1510                                                                         goto lmark;
1511                                                                 }
1512                                                         }
1513
1514                                                         /*
1515                                                          * if tuple was deleted or PlanQual failed for
1516                                                          * updated tuple - we must not return this tuple!
1517                                                          */
1518                                                         goto lnext;
1519
1520                                                 default:
1521                                                         elog(ERROR, "unrecognized heap_lock_tuple status: %u",
1522                                                                  test);
1523                                         }
1524
1525                                         /* Remember tuple TID for WHERE CURRENT OF */
1526                                         erm->curCtid = tuple.t_self;
1527                                 }
1528                         }
1529
1530                         /*
1531                          * extract the 'ctid' junk attribute.
1532                          */
1533                         if (operation == CMD_UPDATE || operation == CMD_DELETE)
1534                         {
1535                                 Datum           datum;
1536                                 bool            isNull;
1537
1538                                 datum = ExecGetJunkAttribute(slot, junkfilter->jf_junkAttNo,
1539                                                                                          &isNull);
1540                                 /* shouldn't ever get a null result... */
1541                                 if (isNull)
1542                                         elog(ERROR, "ctid is NULL");
1543
1544                                 tupleid = (ItemPointer) DatumGetPointer(datum);
1545                                 tuple_ctid = *tupleid;  /* make sure we don't free the ctid!! */
1546                                 tupleid = &tuple_ctid;
1547                         }
1548
1549                         /*
1550                          * Create a new "clean" tuple with all junk attributes removed. We
1551                          * don't need to do this for DELETE, however (there will in fact
1552                          * be no non-junk attributes in a DELETE!)
1553                          */
1554                         if (operation != CMD_DELETE)
1555                                 slot = ExecFilterJunk(junkfilter, slot);
1556                 }
1557
1558                 /*
1559                  * now that we have a tuple, do the appropriate thing with it.. either
1560                  * send it to the output destination, add it to a relation someplace,
1561                  * delete it from a relation, or modify some of its attributes.
1562                  */
1563                 switch (operation)
1564                 {
1565                         case CMD_SELECT:
1566                                 ExecSelect(slot, dest, estate);
1567                                 break;
1568
1569                         case CMD_INSERT:
1570                                 ExecInsert(slot, tupleid, planSlot, dest, estate);
1571                                 break;
1572
1573                         case CMD_DELETE:
1574                                 ExecDelete(tupleid, planSlot, dest, estate);
1575                                 break;
1576
1577                         case CMD_UPDATE:
1578                                 ExecUpdate(slot, tupleid, planSlot, dest, estate);
1579                                 break;
1580
1581                         default:
1582                                 elog(ERROR, "unrecognized operation code: %d",
1583                                          (int) operation);
1584                                 break;
1585                 }
1586
1587                 /*
1588                  * check our tuple count.. if we've processed the proper number then
1589                  * quit, else loop again and process more tuples.  Zero numberTuples
1590                  * means no limit.
1591                  */
1592                 current_tuple_count++;
1593                 if (numberTuples && numberTuples == current_tuple_count)
1594                         break;
1595         }
1596
1597         /*
1598          * Process AFTER EACH STATEMENT triggers
1599          */
1600         switch (operation)
1601         {
1602                 case CMD_UPDATE:
1603                         ExecASUpdateTriggers(estate, estate->es_result_relation_info);
1604                         break;
1605                 case CMD_DELETE:
1606                         ExecASDeleteTriggers(estate, estate->es_result_relation_info);
1607                         break;
1608                 case CMD_INSERT:
1609                         ExecASInsertTriggers(estate, estate->es_result_relation_info);
1610                         break;
1611                 default:
1612                         /* do nothing */
1613                         break;
1614         }
1615 }
1616
1617 /* ----------------------------------------------------------------
1618  *              ExecSelect
1619  *
1620  *              SELECTs are easy.. we just pass the tuple to the appropriate
1621  *              output function.
1622  * ----------------------------------------------------------------
1623  */
1624 static void
1625 ExecSelect(TupleTableSlot *slot,
1626                    DestReceiver *dest,
1627                    EState *estate)
1628 {
1629         (*dest->receiveSlot) (slot, dest);
1630         IncrRetrieved();
1631         (estate->es_processed)++;
1632 }
1633
1634 /* ----------------------------------------------------------------
1635  *              ExecInsert
1636  *
1637  *              INSERTs are trickier.. we have to insert the tuple into
1638  *              the base relation and insert appropriate tuples into the
1639  *              index relations.
1640  * ----------------------------------------------------------------
1641  */
1642 static void
1643 ExecInsert(TupleTableSlot *slot,
1644                    ItemPointer tupleid,
1645                    TupleTableSlot *planSlot,
1646                    DestReceiver *dest,
1647                    EState *estate)
1648 {
1649         HeapTuple       tuple;
1650         ResultRelInfo *resultRelInfo;
1651         Relation        resultRelationDesc;
1652         Oid                     newId;
1653
1654         /*
1655          * get the heap tuple out of the tuple table slot, making sure we have a
1656          * writable copy
1657          */
1658         tuple = ExecMaterializeSlot(slot);
1659
1660         /*
1661          * get information on the (current) result relation
1662          */
1663         resultRelInfo = estate->es_result_relation_info;
1664         resultRelationDesc = resultRelInfo->ri_RelationDesc;
1665
1666         /* BEFORE ROW INSERT Triggers */
1667         if (resultRelInfo->ri_TrigDesc &&
1668                 resultRelInfo->ri_TrigDesc->n_before_row[TRIGGER_EVENT_INSERT] > 0)
1669         {
1670                 HeapTuple       newtuple;
1671
1672                 newtuple = ExecBRInsertTriggers(estate, resultRelInfo, tuple);
1673
1674                 if (newtuple == NULL)   /* "do nothing" */
1675                         return;
1676
1677                 if (newtuple != tuple)  /* modified by Trigger(s) */
1678                 {
1679                         /*
1680                          * Put the modified tuple into a slot for convenience of routines
1681                          * below.  We assume the tuple was allocated in per-tuple memory
1682                          * context, and therefore will go away by itself. The tuple table
1683                          * slot should not try to clear it.
1684                          */
1685                         TupleTableSlot *newslot = estate->es_trig_tuple_slot;
1686
1687                         if (newslot->tts_tupleDescriptor != slot->tts_tupleDescriptor)
1688                                 ExecSetSlotDescriptor(newslot, slot->tts_tupleDescriptor);
1689                         ExecStoreTuple(newtuple, newslot, InvalidBuffer, false);
1690                         slot = newslot;
1691                         tuple = newtuple;
1692                 }
1693         }
1694
1695         /*
1696          * Check the constraints of the tuple
1697          */
1698         if (resultRelationDesc->rd_att->constr)
1699                 ExecConstraints(resultRelInfo, slot, estate);
1700
1701         /*
1702          * insert the tuple
1703          *
1704          * Note: heap_insert returns the tid (location) of the new tuple in the
1705          * t_self field.
1706          */
1707         newId = heap_insert(resultRelationDesc, tuple,
1708                                                 estate->es_output_cid, 0, NULL);
1709
1710         IncrAppended();
1711         (estate->es_processed)++;
1712         estate->es_lastoid = newId;
1713         setLastTid(&(tuple->t_self));
1714
1715         /*
1716          * insert index entries for tuple
1717          */
1718         if (resultRelInfo->ri_NumIndices > 0)
1719                 ExecInsertIndexTuples(slot, &(tuple->t_self), estate, false);
1720
1721         /* AFTER ROW INSERT Triggers */
1722         ExecARInsertTriggers(estate, resultRelInfo, tuple);
1723
1724         /* Process RETURNING if present */
1725         if (resultRelInfo->ri_projectReturning)
1726                 ExecProcessReturning(resultRelInfo->ri_projectReturning,
1727                                                          slot, planSlot, dest);
1728 }
1729
1730 /* ----------------------------------------------------------------
1731  *              ExecDelete
1732  *
1733  *              DELETE is like UPDATE, except that we delete the tuple and no
1734  *              index modifications are needed
1735  * ----------------------------------------------------------------
1736  */
1737 static void
1738 ExecDelete(ItemPointer tupleid,
1739                    TupleTableSlot *planSlot,
1740                    DestReceiver *dest,
1741                    EState *estate)
1742 {
1743         ResultRelInfo *resultRelInfo;
1744         Relation        resultRelationDesc;
1745         HTSU_Result result;
1746         ItemPointerData update_ctid;
1747         TransactionId update_xmax;
1748
1749         /*
1750          * get information on the (current) result relation
1751          */
1752         resultRelInfo = estate->es_result_relation_info;
1753         resultRelationDesc = resultRelInfo->ri_RelationDesc;
1754
1755         /* BEFORE ROW DELETE Triggers */
1756         if (resultRelInfo->ri_TrigDesc &&
1757                 resultRelInfo->ri_TrigDesc->n_before_row[TRIGGER_EVENT_DELETE] > 0)
1758         {
1759                 bool            dodelete;
1760
1761                 dodelete = ExecBRDeleteTriggers(estate, resultRelInfo, tupleid);
1762
1763                 if (!dodelete)                  /* "do nothing" */
1764                         return;
1765         }
1766
1767         /*
1768          * delete the tuple
1769          *
1770          * Note: if es_crosscheck_snapshot isn't InvalidSnapshot, we check that
1771          * the row to be deleted is visible to that snapshot, and throw a can't-
1772          * serialize error if not.      This is a special-case behavior needed for
1773          * referential integrity updates in serializable transactions.
1774          */
1775 ldelete:;
1776         result = heap_delete(resultRelationDesc, tupleid,
1777                                                  &update_ctid, &update_xmax,
1778                                                  estate->es_output_cid,
1779                                                  estate->es_crosscheck_snapshot,
1780                                                  true /* wait for commit */ );
1781         switch (result)
1782         {
1783                 case HeapTupleSelfUpdated:
1784                         /* already deleted by self; nothing to do */
1785                         return;
1786
1787                 case HeapTupleMayBeUpdated:
1788                         break;
1789
1790                 case HeapTupleUpdated:
1791                         if (IsXactIsoLevelSerializable)
1792                                 ereport(ERROR,
1793                                                 (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
1794                                                  errmsg("could not serialize access due to concurrent update")));
1795                         else if (!ItemPointerEquals(tupleid, &update_ctid))
1796                         {
1797                                 TupleTableSlot *epqslot;
1798
1799                                 epqslot = EvalPlanQual(estate,
1800                                                                            resultRelInfo->ri_RangeTableIndex,
1801                                                                            &update_ctid,
1802                                                                            update_xmax);
1803                                 if (!TupIsNull(epqslot))
1804                                 {
1805                                         *tupleid = update_ctid;
1806                                         goto ldelete;
1807                                 }
1808                         }
1809                         /* tuple already deleted; nothing to do */
1810                         return;
1811
1812                 default:
1813                         elog(ERROR, "unrecognized heap_delete status: %u", result);
1814                         return;
1815         }
1816
1817         IncrDeleted();
1818         (estate->es_processed)++;
1819
1820         /*
1821          * Note: Normally one would think that we have to delete index tuples
1822          * associated with the heap tuple now...
1823          *
1824          * ... but in POSTGRES, we have no need to do this because VACUUM will
1825          * take care of it later.  We can't delete index tuples immediately
1826          * anyway, since the tuple is still visible to other transactions.
1827          */
1828
1829         /* AFTER ROW DELETE Triggers */
1830         ExecARDeleteTriggers(estate, resultRelInfo, tupleid);
1831
1832         /* Process RETURNING if present */
1833         if (resultRelInfo->ri_projectReturning)
1834         {
1835                 /*
1836                  * We have to put the target tuple into a slot, which means first we
1837                  * gotta fetch it.      We can use the trigger tuple slot.
1838                  */
1839                 TupleTableSlot *slot = estate->es_trig_tuple_slot;
1840                 HeapTupleData deltuple;
1841                 Buffer          delbuffer;
1842
1843                 deltuple.t_self = *tupleid;
1844                 if (!heap_fetch(resultRelationDesc, SnapshotAny,
1845                                                 &deltuple, &delbuffer, false, NULL))
1846                         elog(ERROR, "failed to fetch deleted tuple for DELETE RETURNING");
1847
1848                 if (slot->tts_tupleDescriptor != RelationGetDescr(resultRelationDesc))
1849                         ExecSetSlotDescriptor(slot, RelationGetDescr(resultRelationDesc));
1850                 ExecStoreTuple(&deltuple, slot, InvalidBuffer, false);
1851
1852                 ExecProcessReturning(resultRelInfo->ri_projectReturning,
1853                                                          slot, planSlot, dest);
1854
1855                 ExecClearTuple(slot);
1856                 ReleaseBuffer(delbuffer);
1857         }
1858 }
1859
1860 /* ----------------------------------------------------------------
1861  *              ExecUpdate
1862  *
1863  *              note: we can't run UPDATE queries with transactions
1864  *              off because UPDATEs are actually INSERTs and our
1865  *              scan will mistakenly loop forever, updating the tuple
1866  *              it just inserted..      This should be fixed but until it
1867  *              is, we don't want to get stuck in an infinite loop
1868  *              which corrupts your database..
1869  * ----------------------------------------------------------------
1870  */
1871 static void
1872 ExecUpdate(TupleTableSlot *slot,
1873                    ItemPointer tupleid,
1874                    TupleTableSlot *planSlot,
1875                    DestReceiver *dest,
1876                    EState *estate)
1877 {
1878         HeapTuple       tuple;
1879         ResultRelInfo *resultRelInfo;
1880         Relation        resultRelationDesc;
1881         HTSU_Result result;
1882         ItemPointerData update_ctid;
1883         TransactionId update_xmax;
1884
1885         /*
1886          * abort the operation if not running transactions
1887          */
1888         if (IsBootstrapProcessingMode())
1889                 elog(ERROR, "cannot UPDATE during bootstrap");
1890
1891         /*
1892          * get the heap tuple out of the tuple table slot, making sure we have a
1893          * writable copy
1894          */
1895         tuple = ExecMaterializeSlot(slot);
1896
1897         /*
1898          * get information on the (current) result relation
1899          */
1900         resultRelInfo = estate->es_result_relation_info;
1901         resultRelationDesc = resultRelInfo->ri_RelationDesc;
1902
1903         /* BEFORE ROW UPDATE Triggers */
1904         if (resultRelInfo->ri_TrigDesc &&
1905                 resultRelInfo->ri_TrigDesc->n_before_row[TRIGGER_EVENT_UPDATE] > 0)
1906         {
1907                 HeapTuple       newtuple;
1908
1909                 newtuple = ExecBRUpdateTriggers(estate, resultRelInfo,
1910                                                                                 tupleid, tuple);
1911
1912                 if (newtuple == NULL)   /* "do nothing" */
1913                         return;
1914
1915                 if (newtuple != tuple)  /* modified by Trigger(s) */
1916                 {
1917                         /*
1918                          * Put the modified tuple into a slot for convenience of routines
1919                          * below.  We assume the tuple was allocated in per-tuple memory
1920                          * context, and therefore will go away by itself. The tuple table
1921                          * slot should not try to clear it.
1922                          */
1923                         TupleTableSlot *newslot = estate->es_trig_tuple_slot;
1924
1925                         if (newslot->tts_tupleDescriptor != slot->tts_tupleDescriptor)
1926                                 ExecSetSlotDescriptor(newslot, slot->tts_tupleDescriptor);
1927                         ExecStoreTuple(newtuple, newslot, InvalidBuffer, false);
1928                         slot = newslot;
1929                         tuple = newtuple;
1930                 }
1931         }
1932
1933         /*
1934          * Check the constraints of the tuple
1935          *
1936          * If we generate a new candidate tuple after EvalPlanQual testing, we
1937          * must loop back here and recheck constraints.  (We don't need to redo
1938          * triggers, however.  If there are any BEFORE triggers then trigger.c
1939          * will have done heap_lock_tuple to lock the correct tuple, so there's no
1940          * need to do them again.)
1941          */
1942 lreplace:;
1943         if (resultRelationDesc->rd_att->constr)
1944                 ExecConstraints(resultRelInfo, slot, estate);
1945
1946         /*
1947          * replace the heap tuple
1948          *
1949          * Note: if es_crosscheck_snapshot isn't InvalidSnapshot, we check that
1950          * the row to be updated is visible to that snapshot, and throw a can't-
1951          * serialize error if not.      This is a special-case behavior needed for
1952          * referential integrity updates in serializable transactions.
1953          */
1954         result = heap_update(resultRelationDesc, tupleid, tuple,
1955                                                  &update_ctid, &update_xmax,
1956                                                  estate->es_output_cid,
1957                                                  estate->es_crosscheck_snapshot,
1958                                                  true /* wait for commit */ );
1959         switch (result)
1960         {
1961                 case HeapTupleSelfUpdated:
1962                         /* already deleted by self; nothing to do */
1963                         return;
1964
1965                 case HeapTupleMayBeUpdated:
1966                         break;
1967
1968                 case HeapTupleUpdated:
1969                         if (IsXactIsoLevelSerializable)
1970                                 ereport(ERROR,
1971                                                 (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
1972                                                  errmsg("could not serialize access due to concurrent update")));
1973                         else if (!ItemPointerEquals(tupleid, &update_ctid))
1974                         {
1975                                 TupleTableSlot *epqslot;
1976
1977                                 epqslot = EvalPlanQual(estate,
1978                                                                            resultRelInfo->ri_RangeTableIndex,
1979                                                                            &update_ctid,
1980                                                                            update_xmax);
1981                                 if (!TupIsNull(epqslot))
1982                                 {
1983                                         *tupleid = update_ctid;
1984                                         slot = ExecFilterJunk(estate->es_junkFilter, epqslot);
1985                                         tuple = ExecMaterializeSlot(slot);
1986                                         goto lreplace;
1987                                 }
1988                         }
1989                         /* tuple already deleted; nothing to do */
1990                         return;
1991
1992                 default:
1993                         elog(ERROR, "unrecognized heap_update status: %u", result);
1994                         return;
1995         }
1996
1997         IncrReplaced();
1998         (estate->es_processed)++;
1999
2000         /*
2001          * Note: instead of having to update the old index tuples associated with
2002          * the heap tuple, all we do is form and insert new index tuples. This is
2003          * because UPDATEs are actually DELETEs and INSERTs, and index tuple
2004          * deletion is done later by VACUUM (see notes in ExecDelete).  All we do
2005          * here is insert new index tuples.  -cim 9/27/89
2006          */
2007
2008         /*
2009          * insert index entries for tuple
2010          *
2011          * Note: heap_update returns the tid (location) of the new tuple in the
2012          * t_self field.
2013          *
2014          * If it's a HOT update, we mustn't insert new index entries.
2015          */
2016         if (resultRelInfo->ri_NumIndices > 0 && !HeapTupleIsHeapOnly(tuple))
2017                 ExecInsertIndexTuples(slot, &(tuple->t_self), estate, false);
2018
2019         /* AFTER ROW UPDATE Triggers */
2020         ExecARUpdateTriggers(estate, resultRelInfo, tupleid, tuple);
2021
2022         /* Process RETURNING if present */
2023         if (resultRelInfo->ri_projectReturning)
2024                 ExecProcessReturning(resultRelInfo->ri_projectReturning,
2025                                                          slot, planSlot, dest);
2026 }
2027
2028 /*
2029  * ExecRelCheck --- check that tuple meets constraints for result relation
2030  */
2031 static const char *
2032 ExecRelCheck(ResultRelInfo *resultRelInfo,
2033                          TupleTableSlot *slot, EState *estate)
2034 {
2035         Relation        rel = resultRelInfo->ri_RelationDesc;
2036         int                     ncheck = rel->rd_att->constr->num_check;
2037         ConstrCheck *check = rel->rd_att->constr->check;
2038         ExprContext *econtext;
2039         MemoryContext oldContext;
2040         List       *qual;
2041         int                     i;
2042
2043         /*
2044          * If first time through for this result relation, build expression
2045          * nodetrees for rel's constraint expressions.  Keep them in the per-query
2046          * memory context so they'll survive throughout the query.
2047          */
2048         if (resultRelInfo->ri_ConstraintExprs == NULL)
2049         {
2050                 oldContext = MemoryContextSwitchTo(estate->es_query_cxt);
2051                 resultRelInfo->ri_ConstraintExprs =
2052                         (List **) palloc(ncheck * sizeof(List *));
2053                 for (i = 0; i < ncheck; i++)
2054                 {
2055                         /* ExecQual wants implicit-AND form */
2056                         qual = make_ands_implicit(stringToNode(check[i].ccbin));
2057                         resultRelInfo->ri_ConstraintExprs[i] = (List *)
2058                                 ExecPrepareExpr((Expr *) qual, estate);
2059                 }
2060                 MemoryContextSwitchTo(oldContext);
2061         }
2062
2063         /*
2064          * We will use the EState's per-tuple context for evaluating constraint
2065          * expressions (creating it if it's not already there).
2066          */
2067         econtext = GetPerTupleExprContext(estate);
2068
2069         /* Arrange for econtext's scan tuple to be the tuple under test */
2070         econtext->ecxt_scantuple = slot;
2071
2072         /* And evaluate the constraints */
2073         for (i = 0; i < ncheck; i++)
2074         {
2075                 qual = resultRelInfo->ri_ConstraintExprs[i];
2076
2077                 /*
2078                  * NOTE: SQL92 specifies that a NULL result from a constraint
2079                  * expression is not to be treated as a failure.  Therefore, tell
2080                  * ExecQual to return TRUE for NULL.
2081                  */
2082                 if (!ExecQual(qual, econtext, true))
2083                         return check[i].ccname;
2084         }
2085
2086         /* NULL result means no error */
2087         return NULL;
2088 }
2089
2090 void
2091 ExecConstraints(ResultRelInfo *resultRelInfo,
2092                                 TupleTableSlot *slot, EState *estate)
2093 {
2094         Relation        rel = resultRelInfo->ri_RelationDesc;
2095         TupleConstr *constr = rel->rd_att->constr;
2096
2097         Assert(constr);
2098
2099         if (constr->has_not_null)
2100         {
2101                 int                     natts = rel->rd_att->natts;
2102                 int                     attrChk;
2103
2104                 for (attrChk = 1; attrChk <= natts; attrChk++)
2105                 {
2106                         if (rel->rd_att->attrs[attrChk - 1]->attnotnull &&
2107                                 slot_attisnull(slot, attrChk))
2108                                 ereport(ERROR,
2109                                                 (errcode(ERRCODE_NOT_NULL_VIOLATION),
2110                                                  errmsg("null value in column \"%s\" violates not-null constraint",
2111                                                 NameStr(rel->rd_att->attrs[attrChk - 1]->attname))));
2112                 }
2113         }
2114
2115         if (constr->num_check > 0)
2116         {
2117                 const char *failed;
2118
2119                 if ((failed = ExecRelCheck(resultRelInfo, slot, estate)) != NULL)
2120                         ereport(ERROR,
2121                                         (errcode(ERRCODE_CHECK_VIOLATION),
2122                                          errmsg("new row for relation \"%s\" violates check constraint \"%s\"",
2123                                                         RelationGetRelationName(rel), failed)));
2124         }
2125 }
2126
2127 /*
2128  * ExecProcessReturning --- evaluate a RETURNING list and send to dest
2129  *
2130  * projectReturning: RETURNING projection info for current result rel
2131  * tupleSlot: slot holding tuple actually inserted/updated/deleted
2132  * planSlot: slot holding tuple returned by top plan node
2133  * dest: where to send the output
2134  */
2135 static void
2136 ExecProcessReturning(ProjectionInfo *projectReturning,
2137                                          TupleTableSlot *tupleSlot,
2138                                          TupleTableSlot *planSlot,
2139                                          DestReceiver *dest)
2140 {
2141         ExprContext *econtext = projectReturning->pi_exprContext;
2142         TupleTableSlot *retSlot;
2143
2144         /*
2145          * Reset per-tuple memory context to free any expression evaluation
2146          * storage allocated in the previous cycle.
2147          */
2148         ResetExprContext(econtext);
2149
2150         /* Make tuple and any needed join variables available to ExecProject */
2151         econtext->ecxt_scantuple = tupleSlot;
2152         econtext->ecxt_outertuple = planSlot;
2153
2154         /* Compute the RETURNING expressions */
2155         retSlot = ExecProject(projectReturning, NULL);
2156
2157         /* Send to dest */
2158         (*dest->receiveSlot) (retSlot, dest);
2159
2160         ExecClearTuple(retSlot);
2161 }
2162
2163 /*
2164  * Check a modified tuple to see if we want to process its updated version
2165  * under READ COMMITTED rules.
2166  *
2167  * See backend/executor/README for some info about how this works.
2168  *
2169  *      estate - executor state data
2170  *      rti - rangetable index of table containing tuple
2171  *      *tid - t_ctid from the outdated tuple (ie, next updated version)
2172  *      priorXmax - t_xmax from the outdated tuple
2173  *
2174  * *tid is also an output parameter: it's modified to hold the TID of the
2175  * latest version of the tuple (note this may be changed even on failure)
2176  *
2177  * Returns a slot containing the new candidate update/delete tuple, or
2178  * NULL if we determine we shouldn't process the row.
2179  */
2180 TupleTableSlot *
2181 EvalPlanQual(EState *estate, Index rti,
2182                          ItemPointer tid, TransactionId priorXmax)
2183 {
2184         evalPlanQual *epq;
2185         EState     *epqstate;
2186         Relation        relation;
2187         HeapTupleData tuple;
2188         HeapTuple       copyTuple = NULL;
2189         SnapshotData SnapshotDirty;
2190         bool            endNode;
2191
2192         Assert(rti != 0);
2193
2194         /*
2195          * find relation containing target tuple
2196          */
2197         if (estate->es_result_relation_info != NULL &&
2198                 estate->es_result_relation_info->ri_RangeTableIndex == rti)
2199                 relation = estate->es_result_relation_info->ri_RelationDesc;
2200         else
2201         {
2202                 ListCell   *l;
2203
2204                 relation = NULL;
2205                 foreach(l, estate->es_rowMarks)
2206                 {
2207                         ExecRowMark *erm = lfirst(l);
2208
2209                         if (erm->rti == rti)
2210                         {
2211                                 relation = erm->relation;
2212                                 break;
2213                         }
2214                 }
2215                 if (relation == NULL)
2216                         elog(ERROR, "could not find RowMark for RT index %u", rti);
2217         }
2218
2219         /*
2220          * fetch tid tuple
2221          *
2222          * Loop here to deal with updated or busy tuples
2223          */
2224         InitDirtySnapshot(SnapshotDirty);
2225         tuple.t_self = *tid;
2226         for (;;)
2227         {
2228                 Buffer          buffer;
2229
2230                 if (heap_fetch(relation, &SnapshotDirty, &tuple, &buffer, true, NULL))
2231                 {
2232                         /*
2233                          * If xmin isn't what we're expecting, the slot must have been
2234                          * recycled and reused for an unrelated tuple.  This implies that
2235                          * the latest version of the row was deleted, so we need do
2236                          * nothing.  (Should be safe to examine xmin without getting
2237                          * buffer's content lock, since xmin never changes in an existing
2238                          * tuple.)
2239                          */
2240                         if (!TransactionIdEquals(HeapTupleHeaderGetXmin(tuple.t_data),
2241                                                                          priorXmax))
2242                         {
2243                                 ReleaseBuffer(buffer);
2244                                 return NULL;
2245                         }
2246
2247                         /* otherwise xmin should not be dirty... */
2248                         if (TransactionIdIsValid(SnapshotDirty.xmin))
2249                                 elog(ERROR, "t_xmin is uncommitted in tuple to be updated");
2250
2251                         /*
2252                          * If tuple is being updated by other transaction then we have to
2253                          * wait for its commit/abort.
2254                          */
2255                         if (TransactionIdIsValid(SnapshotDirty.xmax))
2256                         {
2257                                 ReleaseBuffer(buffer);
2258                                 XactLockTableWait(SnapshotDirty.xmax);
2259                                 continue;               /* loop back to repeat heap_fetch */
2260                         }
2261
2262                         /*
2263                          * If tuple was inserted by our own transaction, we have to check
2264                          * cmin against es_output_cid: cmin >= current CID means our
2265                          * command cannot see the tuple, so we should ignore it.  Without
2266                          * this we are open to the "Halloween problem" of indefinitely
2267                          * re-updating the same tuple. (We need not check cmax because
2268                          * HeapTupleSatisfiesDirty will consider a tuple deleted by our
2269                          * transaction dead, regardless of cmax.)  We just checked that
2270                          * priorXmax == xmin, so we can test that variable instead of
2271                          * doing HeapTupleHeaderGetXmin again.
2272                          */
2273                         if (TransactionIdIsCurrentTransactionId(priorXmax) &&
2274                                 HeapTupleHeaderGetCmin(tuple.t_data) >= estate->es_output_cid)
2275                         {
2276                                 ReleaseBuffer(buffer);
2277                                 return NULL;
2278                         }
2279
2280                         /*
2281                          * We got tuple - now copy it for use by recheck query.
2282                          */
2283                         copyTuple = heap_copytuple(&tuple);
2284                         ReleaseBuffer(buffer);
2285                         break;
2286                 }
2287
2288                 /*
2289                  * If the referenced slot was actually empty, the latest version of
2290                  * the row must have been deleted, so we need do nothing.
2291                  */
2292                 if (tuple.t_data == NULL)
2293                 {
2294                         ReleaseBuffer(buffer);
2295                         return NULL;
2296                 }
2297
2298                 /*
2299                  * As above, if xmin isn't what we're expecting, do nothing.
2300                  */
2301                 if (!TransactionIdEquals(HeapTupleHeaderGetXmin(tuple.t_data),
2302                                                                  priorXmax))
2303                 {
2304                         ReleaseBuffer(buffer);
2305                         return NULL;
2306                 }
2307
2308                 /*
2309                  * If we get here, the tuple was found but failed SnapshotDirty.
2310                  * Assuming the xmin is either a committed xact or our own xact (as it
2311                  * certainly should be if we're trying to modify the tuple), this must
2312                  * mean that the row was updated or deleted by either a committed xact
2313                  * or our own xact.  If it was deleted, we can ignore it; if it was
2314                  * updated then chain up to the next version and repeat the whole
2315                  * test.
2316                  *
2317                  * As above, it should be safe to examine xmax and t_ctid without the
2318                  * buffer content lock, because they can't be changing.
2319                  */
2320                 if (ItemPointerEquals(&tuple.t_self, &tuple.t_data->t_ctid))
2321                 {
2322                         /* deleted, so forget about it */
2323                         ReleaseBuffer(buffer);
2324                         return NULL;
2325                 }
2326
2327                 /* updated, so look at the updated row */
2328                 tuple.t_self = tuple.t_data->t_ctid;
2329                 /* updated row should have xmin matching this xmax */
2330                 priorXmax = HeapTupleHeaderGetXmax(tuple.t_data);
2331                 ReleaseBuffer(buffer);
2332                 /* loop back to fetch next in chain */
2333         }
2334
2335         /*
2336          * For UPDATE/DELETE we have to return tid of actual row we're executing
2337          * PQ for.
2338          */
2339         *tid = tuple.t_self;
2340
2341         /*
2342          * Need to run a recheck subquery.      Find or create a PQ stack entry.
2343          */
2344         epq = estate->es_evalPlanQual;
2345         endNode = true;
2346
2347         if (epq != NULL && epq->rti == 0)
2348         {
2349                 /* Top PQ stack entry is idle, so re-use it */
2350                 Assert(!(estate->es_useEvalPlan) && epq->next == NULL);
2351                 epq->rti = rti;
2352                 endNode = false;
2353         }
2354
2355         /*
2356          * If this is request for another RTE - Ra, - then we have to check wasn't
2357          * PlanQual requested for Ra already and if so then Ra' row was updated
2358          * again and we have to re-start old execution for Ra and forget all what
2359          * we done after Ra was suspended. Cool? -:))
2360          */
2361         if (epq != NULL && epq->rti != rti &&
2362                 epq->estate->es_evTuple[rti - 1] != NULL)
2363         {
2364                 do
2365                 {
2366                         evalPlanQual *oldepq;
2367
2368                         /* stop execution */
2369                         EvalPlanQualStop(epq);
2370                         /* pop previous PlanQual from the stack */
2371                         oldepq = epq->next;
2372                         Assert(oldepq && oldepq->rti != 0);
2373                         /* push current PQ to freePQ stack */
2374                         oldepq->free = epq;
2375                         epq = oldepq;
2376                         estate->es_evalPlanQual = epq;
2377                 } while (epq->rti != rti);
2378         }
2379
2380         /*
2381          * If we are requested for another RTE then we have to suspend execution
2382          * of current PlanQual and start execution for new one.
2383          */
2384         if (epq == NULL || epq->rti != rti)
2385         {
2386                 /* try to reuse plan used previously */
2387                 evalPlanQual *newepq = (epq != NULL) ? epq->free : NULL;
2388
2389                 if (newepq == NULL)             /* first call or freePQ stack is empty */
2390                 {
2391                         newepq = (evalPlanQual *) palloc0(sizeof(evalPlanQual));
2392                         newepq->free = NULL;
2393                         newepq->estate = NULL;
2394                         newepq->planstate = NULL;
2395                 }
2396                 else
2397                 {
2398                         /* recycle previously used PlanQual */
2399                         Assert(newepq->estate == NULL);
2400                         epq->free = NULL;
2401                 }
2402                 /* push current PQ to the stack */
2403                 newepq->next = epq;
2404                 epq = newepq;
2405                 estate->es_evalPlanQual = epq;
2406                 epq->rti = rti;
2407                 endNode = false;
2408         }
2409
2410         Assert(epq->rti == rti);
2411
2412         /*
2413          * Ok - we're requested for the same RTE.  Unfortunately we still have to
2414          * end and restart execution of the plan, because ExecReScan wouldn't
2415          * ensure that upper plan nodes would reset themselves.  We could make
2416          * that work if insertion of the target tuple were integrated with the
2417          * Param mechanism somehow, so that the upper plan nodes know that their
2418          * children's outputs have changed.
2419          *
2420          * Note that the stack of free evalPlanQual nodes is quite useless at the
2421          * moment, since it only saves us from pallocing/releasing the
2422          * evalPlanQual nodes themselves.  But it will be useful once we implement
2423          * ReScan instead of end/restart for re-using PlanQual nodes.
2424          */
2425         if (endNode)
2426         {
2427                 /* stop execution */
2428                 EvalPlanQualStop(epq);
2429         }
2430
2431         /*
2432          * Initialize new recheck query.
2433          *
2434          * Note: if we were re-using PlanQual plans via ExecReScan, we'd need to
2435          * instead copy down changeable state from the top plan (including
2436          * es_result_relation_info, es_junkFilter) and reset locally changeable
2437          * state in the epq (including es_param_exec_vals, es_evTupleNull).
2438          */
2439         EvalPlanQualStart(epq, estate, epq->next);
2440
2441         /*
2442          * free old RTE' tuple, if any, and store target tuple where relation's
2443          * scan node will see it
2444          */
2445         epqstate = epq->estate;
2446         if (epqstate->es_evTuple[rti - 1] != NULL)
2447                 heap_freetuple(epqstate->es_evTuple[rti - 1]);
2448         epqstate->es_evTuple[rti - 1] = copyTuple;
2449
2450         return EvalPlanQualNext(estate);
2451 }
2452
2453 static TupleTableSlot *
2454 EvalPlanQualNext(EState *estate)
2455 {
2456         evalPlanQual *epq = estate->es_evalPlanQual;
2457         MemoryContext oldcontext;
2458         TupleTableSlot *slot;
2459
2460         Assert(epq->rti != 0);
2461
2462 lpqnext:;
2463         oldcontext = MemoryContextSwitchTo(epq->estate->es_query_cxt);
2464         slot = ExecProcNode(epq->planstate);
2465         MemoryContextSwitchTo(oldcontext);
2466
2467         /*
2468          * No more tuples for this PQ. Continue previous one.
2469          */
2470         if (TupIsNull(slot))
2471         {
2472                 evalPlanQual *oldepq;
2473
2474                 /* stop execution */
2475                 EvalPlanQualStop(epq);
2476                 /* pop old PQ from the stack */
2477                 oldepq = epq->next;
2478                 if (oldepq == NULL)
2479                 {
2480                         /* this is the first (oldest) PQ - mark as free */
2481                         epq->rti = 0;
2482                         estate->es_useEvalPlan = false;
2483                         /* and continue Query execution */
2484                         return NULL;
2485                 }
2486                 Assert(oldepq->rti != 0);
2487                 /* push current PQ to freePQ stack */
2488                 oldepq->free = epq;
2489                 epq = oldepq;
2490                 estate->es_evalPlanQual = epq;
2491                 goto lpqnext;
2492         }
2493
2494         return slot;
2495 }
2496
2497 static void
2498 EndEvalPlanQual(EState *estate)
2499 {
2500         evalPlanQual *epq = estate->es_evalPlanQual;
2501
2502         if (epq->rti == 0)                      /* plans already shutdowned */
2503         {
2504                 Assert(epq->next == NULL);
2505                 return;
2506         }
2507
2508         for (;;)
2509         {
2510                 evalPlanQual *oldepq;
2511
2512                 /* stop execution */
2513                 EvalPlanQualStop(epq);
2514                 /* pop old PQ from the stack */
2515                 oldepq = epq->next;
2516                 if (oldepq == NULL)
2517                 {
2518                         /* this is the first (oldest) PQ - mark as free */
2519                         epq->rti = 0;
2520                         estate->es_useEvalPlan = false;
2521                         break;
2522                 }
2523                 Assert(oldepq->rti != 0);
2524                 /* push current PQ to freePQ stack */
2525                 oldepq->free = epq;
2526                 epq = oldepq;
2527                 estate->es_evalPlanQual = epq;
2528         }
2529 }
2530
2531 /*
2532  * Start execution of one level of PlanQual.
2533  *
2534  * This is a cut-down version of ExecutorStart(): we copy some state from
2535  * the top-level estate rather than initializing it fresh.
2536  */
2537 static void
2538 EvalPlanQualStart(evalPlanQual *epq, EState *estate, evalPlanQual *priorepq)
2539 {
2540         EState     *epqstate;
2541         int                     rtsize;
2542         MemoryContext oldcontext;
2543         ListCell   *l;
2544
2545         rtsize = list_length(estate->es_range_table);
2546
2547         epq->estate = epqstate = CreateExecutorState();
2548
2549         oldcontext = MemoryContextSwitchTo(epqstate->es_query_cxt);
2550
2551         /*
2552          * The epqstates share the top query's copy of unchanging state such as
2553          * the snapshot, rangetable, result-rel info, and external Param info.
2554          * They need their own copies of local state, including a tuple table,
2555          * es_param_exec_vals, etc.
2556          */
2557         epqstate->es_direction = ForwardScanDirection;
2558         epqstate->es_snapshot = estate->es_snapshot;
2559         epqstate->es_crosscheck_snapshot = estate->es_crosscheck_snapshot;
2560         epqstate->es_range_table = estate->es_range_table;
2561         epqstate->es_output_cid = estate->es_output_cid;
2562         epqstate->es_result_relations = estate->es_result_relations;
2563         epqstate->es_num_result_relations = estate->es_num_result_relations;
2564         epqstate->es_result_relation_info = estate->es_result_relation_info;
2565         epqstate->es_junkFilter = estate->es_junkFilter;
2566         /* es_trig_target_relations must NOT be copied */
2567         epqstate->es_param_list_info = estate->es_param_list_info;
2568         if (estate->es_plannedstmt->nParamExec > 0)
2569                 epqstate->es_param_exec_vals = (ParamExecData *)
2570                         palloc0(estate->es_plannedstmt->nParamExec * sizeof(ParamExecData));
2571         epqstate->es_rowMarks = estate->es_rowMarks;
2572         epqstate->es_instrument = estate->es_instrument;
2573         epqstate->es_select_into = estate->es_select_into;
2574         epqstate->es_into_oids = estate->es_into_oids;
2575         epqstate->es_plannedstmt = estate->es_plannedstmt;
2576
2577         /*
2578          * Each epqstate must have its own es_evTupleNull state, but all the stack
2579          * entries share es_evTuple state.      This allows sub-rechecks to inherit
2580          * the value being examined by an outer recheck.
2581          */
2582         epqstate->es_evTupleNull = (bool *) palloc0(rtsize * sizeof(bool));
2583         if (priorepq == NULL)
2584                 /* first PQ stack entry */
2585                 epqstate->es_evTuple = (HeapTuple *)
2586                         palloc0(rtsize * sizeof(HeapTuple));
2587         else
2588                 /* later stack entries share the same storage */
2589                 epqstate->es_evTuple = priorepq->estate->es_evTuple;
2590
2591         /*
2592          * Create sub-tuple-table; we needn't redo the CountSlots work though.
2593          */
2594         epqstate->es_tupleTable =
2595                 ExecCreateTupleTable(estate->es_tupleTable->size);
2596
2597         /*
2598          * Initialize private state information for each SubPlan.  We must do this
2599          * before running ExecInitNode on the main query tree, since
2600          * ExecInitSubPlan expects to be able to find these entries.
2601          */
2602         Assert(epqstate->es_subplanstates == NIL);
2603         foreach(l, estate->es_plannedstmt->subplans)
2604         {
2605                 Plan       *subplan = (Plan *) lfirst(l);
2606                 PlanState  *subplanstate;
2607
2608                 subplanstate = ExecInitNode(subplan, epqstate, 0);
2609
2610                 epqstate->es_subplanstates = lappend(epqstate->es_subplanstates,
2611                                                                                          subplanstate);
2612         }
2613
2614         /*
2615          * Initialize the private state information for all the nodes in the query
2616          * tree.  This opens files, allocates storage and leaves us ready to start
2617          * processing tuples.
2618          */
2619         epq->planstate = ExecInitNode(estate->es_plannedstmt->planTree, epqstate, 0);
2620
2621         MemoryContextSwitchTo(oldcontext);
2622 }
2623
2624 /*
2625  * End execution of one level of PlanQual.
2626  *
2627  * This is a cut-down version of ExecutorEnd(); basically we want to do most
2628  * of the normal cleanup, but *not* close result relations (which we are
2629  * just sharing from the outer query).  We do, however, have to close any
2630  * trigger target relations that got opened, since those are not shared.
2631  */
2632 static void
2633 EvalPlanQualStop(evalPlanQual *epq)
2634 {
2635         EState     *epqstate = epq->estate;
2636         MemoryContext oldcontext;
2637         ListCell   *l;
2638
2639         oldcontext = MemoryContextSwitchTo(epqstate->es_query_cxt);
2640
2641         ExecEndNode(epq->planstate);
2642
2643         foreach(l, epqstate->es_subplanstates)
2644         {
2645                 PlanState  *subplanstate = (PlanState *) lfirst(l);
2646
2647                 ExecEndNode(subplanstate);
2648         }
2649
2650         ExecDropTupleTable(epqstate->es_tupleTable, true);
2651         epqstate->es_tupleTable = NULL;
2652
2653         if (epqstate->es_evTuple[epq->rti - 1] != NULL)
2654         {
2655                 heap_freetuple(epqstate->es_evTuple[epq->rti - 1]);
2656                 epqstate->es_evTuple[epq->rti - 1] = NULL;
2657         }
2658
2659         foreach(l, epqstate->es_trig_target_relations)
2660         {
2661                 ResultRelInfo *resultRelInfo = (ResultRelInfo *) lfirst(l);
2662
2663                 /* Close indices and then the relation itself */
2664                 ExecCloseIndices(resultRelInfo);
2665                 heap_close(resultRelInfo->ri_RelationDesc, NoLock);
2666         }
2667
2668         MemoryContextSwitchTo(oldcontext);
2669
2670         FreeExecutorState(epqstate);
2671
2672         epq->estate = NULL;
2673         epq->planstate = NULL;
2674 }
2675
2676 /*
2677  * ExecGetActivePlanTree --- get the active PlanState tree from a QueryDesc
2678  *
2679  * Ordinarily this is just the one mentioned in the QueryDesc, but if we
2680  * are looking at a row returned by the EvalPlanQual machinery, we need
2681  * to look at the subsidiary state instead.
2682  */
2683 PlanState *
2684 ExecGetActivePlanTree(QueryDesc *queryDesc)
2685 {
2686         EState     *estate = queryDesc->estate;
2687
2688         if (estate && estate->es_useEvalPlan && estate->es_evalPlanQual != NULL)
2689                 return estate->es_evalPlanQual->planstate;
2690         else
2691                 return queryDesc->planstate;
2692 }
2693
2694
2695 /*
2696  * Support for SELECT INTO (a/k/a CREATE TABLE AS)
2697  *
2698  * We implement SELECT INTO by diverting SELECT's normal output with
2699  * a specialized DestReceiver type.
2700  */
2701
2702 typedef struct
2703 {
2704         DestReceiver pub;                       /* publicly-known function pointers */
2705         EState     *estate;                     /* EState we are working with */
2706         Relation        rel;                    /* Relation to write to */
2707         int                     hi_options;             /* heap_insert performance options */
2708         BulkInsertState bistate;        /* bulk insert state */
2709 } DR_intorel;
2710
2711 /*
2712  * OpenIntoRel --- actually create the SELECT INTO target relation
2713  *
2714  * This also replaces QueryDesc->dest with the special DestReceiver for
2715  * SELECT INTO.  We assume that the correct result tuple type has already
2716  * been placed in queryDesc->tupDesc.
2717  */
2718 static void
2719 OpenIntoRel(QueryDesc *queryDesc)
2720 {
2721         IntoClause *into = queryDesc->plannedstmt->intoClause;
2722         EState     *estate = queryDesc->estate;
2723         Relation        intoRelationDesc;
2724         char       *intoName;
2725         Oid                     namespaceId;
2726         Oid                     tablespaceId;
2727         Datum           reloptions;
2728         AclResult       aclresult;
2729         Oid                     intoRelationId;
2730         TupleDesc       tupdesc;
2731         DR_intorel *myState;
2732
2733         Assert(into);
2734
2735         /*
2736          * Check consistency of arguments
2737          */
2738         if (into->onCommit != ONCOMMIT_NOOP && !into->rel->istemp)
2739                 ereport(ERROR,
2740                                 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
2741                                  errmsg("ON COMMIT can only be used on temporary tables")));
2742
2743         /*
2744          * Find namespace to create in, check its permissions
2745          */
2746         intoName = into->rel->relname;
2747         namespaceId = RangeVarGetCreationNamespace(into->rel);
2748
2749         aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(),
2750                                                                           ACL_CREATE);
2751         if (aclresult != ACLCHECK_OK)
2752                 aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
2753                                            get_namespace_name(namespaceId));
2754
2755         /*
2756          * Select tablespace to use.  If not specified, use default tablespace
2757          * (which may in turn default to database's default).
2758          */
2759         if (into->tableSpaceName)
2760         {
2761                 tablespaceId = get_tablespace_oid(into->tableSpaceName);
2762                 if (!OidIsValid(tablespaceId))
2763                         ereport(ERROR,
2764                                         (errcode(ERRCODE_UNDEFINED_OBJECT),
2765                                          errmsg("tablespace \"%s\" does not exist",
2766                                                         into->tableSpaceName)));
2767         }
2768         else
2769         {
2770                 tablespaceId = GetDefaultTablespace(into->rel->istemp);
2771                 /* note InvalidOid is OK in this case */
2772         }
2773
2774         /* Check permissions except when using the database's default space */
2775         if (OidIsValid(tablespaceId) && tablespaceId != MyDatabaseTableSpace)
2776         {
2777                 AclResult       aclresult;
2778
2779                 aclresult = pg_tablespace_aclcheck(tablespaceId, GetUserId(),
2780                                                                                    ACL_CREATE);
2781
2782                 if (aclresult != ACLCHECK_OK)
2783                         aclcheck_error(aclresult, ACL_KIND_TABLESPACE,
2784                                                    get_tablespace_name(tablespaceId));
2785         }
2786
2787         /* Parse and validate any reloptions */
2788         reloptions = transformRelOptions((Datum) 0,
2789                                                                          into->options,
2790                                                                          true,
2791                                                                          false);
2792         (void) heap_reloptions(RELKIND_RELATION, reloptions, true);
2793
2794         /* Copy the tupdesc because heap_create_with_catalog modifies it */
2795         tupdesc = CreateTupleDescCopy(queryDesc->tupDesc);
2796
2797         /* Now we can actually create the new relation */
2798         intoRelationId = heap_create_with_catalog(intoName,
2799                                                                                           namespaceId,
2800                                                                                           tablespaceId,
2801                                                                                           InvalidOid,
2802                                                                                           GetUserId(),
2803                                                                                           tupdesc,
2804                                                                                           NIL,
2805                                                                                           RELKIND_RELATION,
2806                                                                                           false,
2807                                                                                           true,
2808                                                                                           0,
2809                                                                                           into->onCommit,
2810                                                                                           reloptions,
2811                                                                                           allowSystemTableMods);
2812
2813         FreeTupleDesc(tupdesc);
2814
2815         /*
2816          * Advance command counter so that the newly-created relation's catalog
2817          * tuples will be visible to heap_open.
2818          */
2819         CommandCounterIncrement();
2820
2821         /*
2822          * If necessary, create a TOAST table for the INTO relation. Note that
2823          * AlterTableCreateToastTable ends with CommandCounterIncrement(), so that
2824          * the TOAST table will be visible for insertion.
2825          */
2826         AlterTableCreateToastTable(intoRelationId);
2827
2828         /*
2829          * And open the constructed table for writing.
2830          */
2831         intoRelationDesc = heap_open(intoRelationId, AccessExclusiveLock);
2832
2833         /*
2834          * Now replace the query's DestReceiver with one for SELECT INTO
2835          */
2836         queryDesc->dest = CreateDestReceiver(DestIntoRel, NULL);
2837         myState = (DR_intorel *) queryDesc->dest;
2838         Assert(myState->pub.mydest == DestIntoRel);
2839         myState->estate = estate;
2840         myState->rel = intoRelationDesc;
2841
2842         /*
2843          * We can skip WAL-logging the insertions, unless PITR is in use.  We
2844          * can skip the FSM in any case.
2845          */
2846         myState->hi_options = HEAP_INSERT_SKIP_FSM |
2847                 (XLogArchivingActive() ? 0 : HEAP_INSERT_SKIP_WAL);
2848         myState->bistate = GetBulkInsertState();
2849
2850         /* Not using WAL requires rd_targblock be initially invalid */
2851         Assert(intoRelationDesc->rd_targblock == InvalidBlockNumber);
2852 }
2853
2854 /*
2855  * CloseIntoRel --- clean up SELECT INTO at ExecutorEnd time
2856  */
2857 static void
2858 CloseIntoRel(QueryDesc *queryDesc)
2859 {
2860         DR_intorel *myState = (DR_intorel *) queryDesc->dest;
2861
2862         /* OpenIntoRel might never have gotten called */
2863         if (myState && myState->pub.mydest == DestIntoRel && myState->rel)
2864         {
2865                 FreeBulkInsertState(myState->bistate);
2866
2867                 /* If we skipped using WAL, must heap_sync before commit */
2868                 if (myState->hi_options & HEAP_INSERT_SKIP_WAL)
2869                         heap_sync(myState->rel);
2870
2871                 /* close rel, but keep lock until commit */
2872                 heap_close(myState->rel, NoLock);
2873
2874                 myState->rel = NULL;
2875         }
2876 }
2877
2878 /*
2879  * CreateIntoRelDestReceiver -- create a suitable DestReceiver object
2880  *
2881  * Since CreateDestReceiver doesn't accept the parameters we'd need,
2882  * we just leave the private fields zeroed here.  OpenIntoRel will
2883  * fill them in.
2884  */
2885 DestReceiver *
2886 CreateIntoRelDestReceiver(void)
2887 {
2888         DR_intorel *self = (DR_intorel *) palloc0(sizeof(DR_intorel));
2889
2890         self->pub.receiveSlot = intorel_receive;
2891         self->pub.rStartup = intorel_startup;
2892         self->pub.rShutdown = intorel_shutdown;
2893         self->pub.rDestroy = intorel_destroy;
2894         self->pub.mydest = DestIntoRel;
2895
2896         return (DestReceiver *) self;
2897 }
2898
2899 /*
2900  * intorel_startup --- executor startup
2901  */
2902 static void
2903 intorel_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
2904 {
2905         /* no-op */
2906 }
2907
2908 /*
2909  * intorel_receive --- receive one tuple
2910  */
2911 static void
2912 intorel_receive(TupleTableSlot *slot, DestReceiver *self)
2913 {
2914         DR_intorel *myState = (DR_intorel *) self;
2915         HeapTuple       tuple;
2916
2917         /*
2918          * get the heap tuple out of the tuple table slot, making sure we have a
2919          * writable copy
2920          */
2921         tuple = ExecMaterializeSlot(slot);
2922
2923         heap_insert(myState->rel,
2924                                 tuple,
2925                                 myState->estate->es_output_cid,
2926                                 myState->hi_options,
2927                                 myState->bistate);
2928
2929         /* We know this is a newly created relation, so there are no indexes */
2930
2931         IncrAppended();
2932 }
2933
2934 /*
2935  * intorel_shutdown --- executor end
2936  */
2937 static void
2938 intorel_shutdown(DestReceiver *self)
2939 {
2940         /* no-op */
2941 }
2942
2943 /*
2944  * intorel_destroy --- release DestReceiver object
2945  */
2946 static void
2947 intorel_destroy(DestReceiver *self)
2948 {
2949         pfree(self);
2950 }