OSDN Git Service

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