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