]> granicus.if.org Git - postgresql/blob - src/backend/executor/execMain.c
More janitorial work: remove the explicit casting of NULL literals to a
[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-2003, 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.225 2004/01/07 18:56:26 neilc Exp $
30  *
31  *-------------------------------------------------------------------------
32  */
33 #include "postgres.h"
34
35 #include "access/heapam.h"
36 #include "catalog/heap.h"
37 #include "catalog/namespace.h"
38 #include "commands/tablecmds.h"
39 #include "commands/trigger.h"
40 #include "executor/execdebug.h"
41 #include "executor/execdefs.h"
42 #include "miscadmin.h"
43 #include "optimizer/clauses.h"
44 #include "optimizer/var.h"
45 #include "parser/parsetree.h"
46 #include "utils/acl.h"
47 #include "utils/guc.h"
48 #include "utils/lsyscache.h"
49
50
51 typedef struct execRowMark
52 {
53         Relation        relation;
54         Index           rti;
55         char            resname[32];
56 } execRowMark;
57
58 typedef struct evalPlanQual
59 {
60         Index           rti;
61         EState     *estate;
62         PlanState  *planstate;
63         struct evalPlanQual *next;      /* stack of active PlanQual plans */
64         struct evalPlanQual *free;      /* list of free PlanQual plans */
65 } evalPlanQual;
66
67 /* decls for local routines only used within this module */
68 static void InitPlan(QueryDesc *queryDesc, bool explainOnly);
69 static void initResultRelInfo(ResultRelInfo *resultRelInfo,
70                                   Index resultRelationIndex,
71                                   List *rangeTable,
72                                   CmdType operation);
73 static TupleTableSlot *ExecutePlan(EState *estate, PlanState *planstate,
74                         CmdType operation,
75                         long numberTuples,
76                         ScanDirection direction,
77                         DestReceiver *dest);
78 static void ExecSelect(TupleTableSlot *slot,
79                    DestReceiver *dest,
80                    EState *estate);
81 static void ExecInsert(TupleTableSlot *slot, ItemPointer tupleid,
82                    EState *estate);
83 static void ExecDelete(TupleTableSlot *slot, ItemPointer tupleid,
84                    EState *estate);
85 static void ExecUpdate(TupleTableSlot *slot, ItemPointer tupleid,
86                    EState *estate);
87 static TupleTableSlot *EvalPlanQualNext(EState *estate);
88 static void EndEvalPlanQual(EState *estate);
89 static void ExecCheckRTEPerms(RangeTblEntry *rte, CmdType operation);
90 static void ExecCheckXactReadOnly(Query *parsetree, CmdType operation);
91 static void EvalPlanQualStart(evalPlanQual *epq, EState *estate,
92                                   evalPlanQual *priorepq);
93 static void EvalPlanQualStop(evalPlanQual *epq);
94
95 /* end of local decls */
96
97
98 /* ----------------------------------------------------------------
99  *              ExecutorStart
100  *
101  *              This routine must be called at the beginning of any execution of any
102  *              query plan
103  *
104  * Takes a QueryDesc previously created by CreateQueryDesc (it's not real
105  * clear why we bother to separate the two functions, but...).  The tupDesc
106  * field of the QueryDesc is filled in to describe the tuples that will be
107  * returned, and the internal fields (estate and planstate) are set up.
108  *
109  * If useCurrentSnapshot is true, run the query with the latest available
110  * snapshot, instead of the normal QuerySnapshot.  Also, if it's an update
111  * or delete query, check that the rows to be updated or deleted would be
112  * visible to the normal QuerySnapshot.  (This is a special-case behavior
113  * needed for referential integrity updates in serializable transactions.
114  * We must check all currently-committed rows, but we want to throw a
115  * can't-serialize error if any rows that would need updates would not be
116  * visible under the normal serializable snapshot.)
117  *
118  * If explainOnly is true, we are not actually intending to run the plan,
119  * only to set up for EXPLAIN; so skip unwanted side-effects.
120  *
121  * NB: the CurrentMemoryContext when this is called will become the parent
122  * of the per-query context used for this Executor invocation.
123  * ----------------------------------------------------------------
124  */
125 void
126 ExecutorStart(QueryDesc *queryDesc, bool useCurrentSnapshot, bool explainOnly)
127 {
128         EState     *estate;
129         MemoryContext oldcontext;
130
131         /* sanity checks: queryDesc must not be started already */
132         Assert(queryDesc != NULL);
133         Assert(queryDesc->estate == NULL);
134
135         /*
136          * If the transaction is read-only, we need to check if any writes are
137          * planned to non-temporary tables.
138          */
139         if (!explainOnly)
140                 ExecCheckXactReadOnly(queryDesc->parsetree, queryDesc->operation);
141
142         /*
143          * Build EState, switch into per-query memory context for startup.
144          */
145         estate = CreateExecutorState();
146         queryDesc->estate = estate;
147
148         oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
149
150         /*
151          * Fill in parameters, if any, from queryDesc
152          */
153         estate->es_param_list_info = queryDesc->params;
154
155         if (queryDesc->plantree->nParamExec > 0)
156                 estate->es_param_exec_vals = (ParamExecData *)
157                         palloc0(queryDesc->plantree->nParamExec * sizeof(ParamExecData));
158
159         estate->es_instrument = queryDesc->doInstrument;
160
161         /*
162          * Make our own private copy of the current query snapshot data.
163          *
164          * This "freezes" our idea of which tuples are good and which are not for
165          * the life of this query, even if it outlives the current command and
166          * current snapshot.
167          */
168         if (useCurrentSnapshot)
169         {
170                 /* RI update/delete query --- must use an up-to-date snapshot */
171                 estate->es_snapshot = CopyCurrentSnapshot();
172                 /* crosscheck updates/deletes against transaction snapshot */
173                 estate->es_crosscheck_snapshot = CopyQuerySnapshot();
174         }
175         else
176         {
177                 /* normal query --- use query snapshot, no crosscheck */
178                 estate->es_snapshot = CopyQuerySnapshot();
179                 estate->es_crosscheck_snapshot = SnapshotAny;
180         }
181
182         /*
183          * Initialize the plan state tree
184          */
185         InitPlan(queryDesc, explainOnly);
186
187         MemoryContextSwitchTo(oldcontext);
188 }
189
190 /* ----------------------------------------------------------------
191  *              ExecutorRun
192  *
193  *              This is the main routine of the executor module. It accepts
194  *              the query descriptor from the traffic cop and executes the
195  *              query plan.
196  *
197  *              ExecutorStart must have been called already.
198  *
199  *              If direction is NoMovementScanDirection then nothing is done
200  *              except to start up/shut down the destination.  Otherwise,
201  *              we retrieve up to 'count' tuples in the specified direction.
202  *
203  *              Note: count = 0 is interpreted as no portal limit, i.e., run to
204  *              completion.
205  *
206  * ----------------------------------------------------------------
207  */
208 TupleTableSlot *
209 ExecutorRun(QueryDesc *queryDesc,
210                         ScanDirection direction, long count)
211 {
212         EState     *estate;
213         CmdType         operation;
214         DestReceiver *dest;
215         TupleTableSlot *result;
216         MemoryContext oldcontext;
217
218         /* sanity checks */
219         Assert(queryDesc != NULL);
220
221         estate = queryDesc->estate;
222
223         Assert(estate != NULL);
224
225         /*
226          * Switch into per-query memory context
227          */
228         oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
229
230         /*
231          * extract information from the query descriptor and the query
232          * feature.
233          */
234         operation = queryDesc->operation;
235         dest = queryDesc->dest;
236
237         /*
238          * startup tuple receiver
239          */
240         estate->es_processed = 0;
241         estate->es_lastoid = InvalidOid;
242
243         (*dest->rStartup) (dest, operation, queryDesc->tupDesc);
244
245         /*
246          * run plan
247          */
248         if (direction == NoMovementScanDirection)
249                 result = NULL;
250         else
251                 result = ExecutePlan(estate,
252                                                          queryDesc->planstate,
253                                                          operation,
254                                                          count,
255                                                          direction,
256                                                          dest);
257
258         /*
259          * shutdown receiver
260          */
261         (*dest->rShutdown) (dest);
262
263         MemoryContextSwitchTo(oldcontext);
264
265         return result;
266 }
267
268 /* ----------------------------------------------------------------
269  *              ExecutorEnd
270  *
271  *              This routine must be called at the end of execution of any
272  *              query plan
273  * ----------------------------------------------------------------
274  */
275 void
276 ExecutorEnd(QueryDesc *queryDesc)
277 {
278         EState     *estate;
279         MemoryContext oldcontext;
280
281         /* sanity checks */
282         Assert(queryDesc != NULL);
283
284         estate = queryDesc->estate;
285
286         Assert(estate != NULL);
287
288         /*
289          * Switch into per-query memory context to run ExecEndPlan
290          */
291         oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
292
293         ExecEndPlan(queryDesc->planstate, estate);
294
295         /*
296          * Must switch out of context before destroying it
297          */
298         MemoryContextSwitchTo(oldcontext);
299
300         /*
301          * Release EState and per-query memory context.  This should release
302          * everything the executor has allocated.
303          */
304         FreeExecutorState(estate);
305
306         /* Reset queryDesc fields that no longer point to anything */
307         queryDesc->tupDesc = NULL;
308         queryDesc->estate = NULL;
309         queryDesc->planstate = NULL;
310 }
311
312 /* ----------------------------------------------------------------
313  *              ExecutorRewind
314  *
315  *              This routine may be called on an open queryDesc to rewind it
316  *              to the start.
317  * ----------------------------------------------------------------
318  */
319 void
320 ExecutorRewind(QueryDesc *queryDesc)
321 {
322         EState     *estate;
323         MemoryContext oldcontext;
324
325         /* sanity checks */
326         Assert(queryDesc != NULL);
327
328         estate = queryDesc->estate;
329
330         Assert(estate != NULL);
331
332         /* It's probably not sensible to rescan updating queries */
333         Assert(queryDesc->operation == CMD_SELECT);
334
335         /*
336          * Switch into per-query memory context
337          */
338         oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
339
340         /*
341          * rescan plan
342          */
343         ExecReScan(queryDesc->planstate, NULL);
344
345         MemoryContextSwitchTo(oldcontext);
346 }
347
348
349 /*
350  * ExecCheckRTPerms
351  *              Check access permissions for all relations listed in a range table.
352  */
353 void
354 ExecCheckRTPerms(List *rangeTable, CmdType operation)
355 {
356         List       *lp;
357
358         foreach(lp, rangeTable)
359         {
360                 RangeTblEntry *rte = lfirst(lp);
361
362                 ExecCheckRTEPerms(rte, operation);
363         }
364 }
365
366 /*
367  * ExecCheckRTEPerms
368  *              Check access permissions for a single RTE.
369  */
370 static void
371 ExecCheckRTEPerms(RangeTblEntry *rte, CmdType operation)
372 {
373         Oid                     relOid;
374         AclId           userid;
375         AclResult       aclcheck_result;
376
377         /*
378          * If it's a subquery, recursively examine its rangetable.
379          */
380         if (rte->rtekind == RTE_SUBQUERY)
381         {
382                 ExecCheckRTPerms(rte->subquery->rtable, operation);
383                 return;
384         }
385
386         /*
387          * Otherwise, only plain-relation RTEs need to be checked here.
388          * Function RTEs are checked by init_fcache when the function is
389          * prepared for execution. Join and special RTEs need no checks.
390          */
391         if (rte->rtekind != RTE_RELATION)
392                 return;
393
394         relOid = rte->relid;
395
396         /*
397          * userid to check as: current user unless we have a setuid
398          * indication.
399          *
400          * Note: GetUserId() is presently fast enough that there's no harm in
401          * calling it separately for each RTE.  If that stops being true, we
402          * could call it once in ExecCheckRTPerms and pass the userid down
403          * from there.  But for now, no need for the extra clutter.
404          */
405         userid = rte->checkAsUser ? rte->checkAsUser : GetUserId();
406
407 #define CHECK(MODE)             pg_class_aclcheck(relOid, userid, MODE)
408
409         if (rte->checkForRead)
410         {
411                 aclcheck_result = CHECK(ACL_SELECT);
412                 if (aclcheck_result != ACLCHECK_OK)
413                         aclcheck_error(aclcheck_result, ACL_KIND_CLASS,
414                                                    get_rel_name(relOid));
415         }
416
417         if (rte->checkForWrite)
418         {
419                 /*
420                  * Note: write access in a SELECT context means SELECT FOR UPDATE.
421                  * Right now we don't distinguish that from true update as far as
422                  * permissions checks are concerned.
423                  */
424                 switch (operation)
425                 {
426                         case CMD_INSERT:
427                                 aclcheck_result = CHECK(ACL_INSERT);
428                                 break;
429                         case CMD_SELECT:
430                         case CMD_UPDATE:
431                                 aclcheck_result = CHECK(ACL_UPDATE);
432                                 break;
433                         case CMD_DELETE:
434                                 aclcheck_result = CHECK(ACL_DELETE);
435                                 break;
436                         default:
437                                 elog(ERROR, "unrecognized operation code: %d",
438                                          (int) operation);
439                                 aclcheck_result = ACLCHECK_OK;  /* keep compiler quiet */
440                                 break;
441                 }
442                 if (aclcheck_result != ACLCHECK_OK)
443                         aclcheck_error(aclcheck_result, ACL_KIND_CLASS,
444                                                    get_rel_name(relOid));
445         }
446 }
447
448 static void
449 ExecCheckXactReadOnly(Query *parsetree, CmdType operation)
450 {
451         if (!XactReadOnly)
452                 return;
453
454         /* CREATE TABLE AS or SELECT INTO */
455         if (operation == CMD_SELECT && parsetree->into != NULL)
456                 goto fail;
457
458         if (operation == CMD_DELETE || operation == CMD_INSERT
459                 || operation == CMD_UPDATE)
460         {
461                 List       *lp;
462
463                 foreach(lp, parsetree->rtable)
464                 {
465                         RangeTblEntry *rte = lfirst(lp);
466
467                         if (rte->rtekind != RTE_RELATION)
468                                 continue;
469
470                         if (!rte->checkForWrite)
471                                 continue;
472
473                         if (isTempNamespace(get_rel_namespace(rte->relid)))
474                                 continue;
475
476                         goto fail;
477                 }
478         }
479
480         return;
481
482 fail:
483         ereport(ERROR,
484                         (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
485                          errmsg("transaction is read-only")));
486 }
487
488
489 /* ----------------------------------------------------------------
490  *              InitPlan
491  *
492  *              Initializes the query plan: open files, allocate storage
493  *              and start up the rule manager
494  * ----------------------------------------------------------------
495  */
496 static void
497 InitPlan(QueryDesc *queryDesc, bool explainOnly)
498 {
499         CmdType         operation = queryDesc->operation;
500         Query      *parseTree = queryDesc->parsetree;
501         Plan       *plan = queryDesc->plantree;
502         EState     *estate = queryDesc->estate;
503         PlanState  *planstate;
504         List       *rangeTable;
505         Relation        intoRelationDesc;
506         bool            do_select_into;
507         TupleDesc       tupType;
508
509         /*
510          * Do permissions checks.  It's sufficient to examine the query's top
511          * rangetable here --- subplan RTEs will be checked during
512          * ExecInitSubPlan().
513          */
514         ExecCheckRTPerms(parseTree->rtable, operation);
515
516         /*
517          * get information from query descriptor
518          */
519         rangeTable = parseTree->rtable;
520
521         /*
522          * initialize the node's execution state
523          */
524         estate->es_range_table = rangeTable;
525
526         /*
527          * if there is a result relation, initialize result relation stuff
528          */
529         if (parseTree->resultRelation != 0 && operation != CMD_SELECT)
530         {
531                 List       *resultRelations = parseTree->resultRelations;
532                 int                     numResultRelations;
533                 ResultRelInfo *resultRelInfos;
534
535                 if (resultRelations != NIL)
536                 {
537                         /*
538                          * Multiple result relations (due to inheritance)
539                          * parseTree->resultRelations identifies them all
540                          */
541                         ResultRelInfo *resultRelInfo;
542
543                         numResultRelations = length(resultRelations);
544                         resultRelInfos = (ResultRelInfo *)
545                                 palloc(numResultRelations * sizeof(ResultRelInfo));
546                         resultRelInfo = resultRelInfos;
547                         while (resultRelations != NIL)
548                         {
549                                 initResultRelInfo(resultRelInfo,
550                                                                   lfirsti(resultRelations),
551                                                                   rangeTable,
552                                                                   operation);
553                                 resultRelInfo++;
554                                 resultRelations = lnext(resultRelations);
555                         }
556                 }
557                 else
558                 {
559                         /*
560                          * Single result relation identified by
561                          * parseTree->resultRelation
562                          */
563                         numResultRelations = 1;
564                         resultRelInfos = (ResultRelInfo *) palloc(sizeof(ResultRelInfo));
565                         initResultRelInfo(resultRelInfos,
566                                                           parseTree->resultRelation,
567                                                           rangeTable,
568                                                           operation);
569                 }
570
571                 estate->es_result_relations = resultRelInfos;
572                 estate->es_num_result_relations = numResultRelations;
573                 /* Initialize to first or only result rel */
574                 estate->es_result_relation_info = resultRelInfos;
575         }
576         else
577         {
578                 /*
579                  * if no result relation, then set state appropriately
580                  */
581                 estate->es_result_relations = NULL;
582                 estate->es_num_result_relations = 0;
583                 estate->es_result_relation_info = NULL;
584         }
585
586         /*
587          * Detect whether we're doing SELECT INTO.  If so, set the force_oids
588          * flag appropriately so that the plan tree will be initialized with
589          * the correct tuple descriptors.
590          */
591         do_select_into = false;
592
593         if (operation == CMD_SELECT && parseTree->into != NULL)
594         {
595                 do_select_into = true;
596
597                 /*
598                  * The presence of OIDs in the result set of SELECT INTO is
599                  * controlled by the default_with_oids GUC parameter. The
600                  * behavior in versions of PostgreSQL prior to 7.5 is to
601                  * always include OIDs.
602                  */
603                 estate->es_force_oids = default_with_oids;
604         }
605
606         /*
607          * Have to lock relations selected for update
608          */
609         estate->es_rowMark = NIL;
610         if (parseTree->rowMarks != NIL)
611         {
612                 List       *l;
613
614                 foreach(l, parseTree->rowMarks)
615                 {
616                         Index           rti = lfirsti(l);
617                         Oid                     relid = getrelid(rti, rangeTable);
618                         Relation        relation;
619                         execRowMark *erm;
620
621                         relation = heap_open(relid, RowShareLock);
622                         erm = (execRowMark *) palloc(sizeof(execRowMark));
623                         erm->relation = relation;
624                         erm->rti = rti;
625                         snprintf(erm->resname, sizeof(erm->resname), "ctid%u", rti);
626                         estate->es_rowMark = lappend(estate->es_rowMark, erm);
627                 }
628         }
629
630         /*
631          * initialize the executor "tuple" table.  We need slots for all the
632          * plan nodes, plus possibly output slots for the junkfilter(s). At
633          * this point we aren't sure if we need junkfilters, so just add slots
634          * for them unconditionally.
635          */
636         {
637                 int                     nSlots = ExecCountSlotsNode(plan);
638
639                 if (parseTree->resultRelations != NIL)
640                         nSlots += length(parseTree->resultRelations);
641                 else
642                         nSlots += 1;
643                 estate->es_tupleTable = ExecCreateTupleTable(nSlots);
644         }
645
646         /* mark EvalPlanQual not active */
647         estate->es_topPlan = plan;
648         estate->es_evalPlanQual = NULL;
649         estate->es_evTupleNull = NULL;
650         estate->es_evTuple = NULL;
651         estate->es_useEvalPlan = false;
652
653         /*
654          * initialize the private state information for all the nodes in the
655          * query tree.  This opens files, allocates storage and leaves us
656          * ready to start processing tuples.
657          */
658         planstate = ExecInitNode(plan, estate);
659
660         /*
661          * Get the tuple descriptor describing the type of tuples to return.
662          * (this is especially important if we are creating a relation with
663          * "SELECT INTO")
664          */
665         tupType = ExecGetResultType(planstate);
666
667         /*
668          * Initialize the junk filter if needed.  SELECT and INSERT queries
669          * need a filter if there are any junk attrs in the tlist.      INSERT and
670          * SELECT INTO also need a filter if the top plan node is a scan node
671          * that's not doing projection (else we'll be scribbling on the scan
672          * tuple!)      UPDATE and DELETE always need a filter, since there's
673          * always a junk 'ctid' attribute present --- no need to look first.
674          */
675         {
676                 bool            junk_filter_needed = false;
677                 List       *tlist;
678
679                 switch (operation)
680                 {
681                         case CMD_SELECT:
682                         case CMD_INSERT:
683                                 foreach(tlist, plan->targetlist)
684                                 {
685                                         TargetEntry *tle = (TargetEntry *) lfirst(tlist);
686
687                                         if (tle->resdom->resjunk)
688                                         {
689                                                 junk_filter_needed = true;
690                                                 break;
691                                         }
692                                 }
693                                 if (!junk_filter_needed &&
694                                         (operation == CMD_INSERT || do_select_into))
695                                 {
696                                         if (IsA(planstate, SeqScanState) ||
697                                                 IsA(planstate, IndexScanState) ||
698                                                 IsA(planstate, TidScanState) ||
699                                                 IsA(planstate, SubqueryScanState) ||
700                                                 IsA(planstate, FunctionScanState))
701                                         {
702                                                 if (planstate->ps_ProjInfo == NULL)
703                                                         junk_filter_needed = true;
704                                         }
705                                 }
706                                 break;
707                         case CMD_UPDATE:
708                         case CMD_DELETE:
709                                 junk_filter_needed = true;
710                                 break;
711                         default:
712                                 break;
713                 }
714
715                 if (junk_filter_needed)
716                 {
717                         /*
718                          * If there are multiple result relations, each one needs its
719                          * own junk filter.  Note this is only possible for
720                          * UPDATE/DELETE, so we can't be fooled by some needing a
721                          * filter and some not.
722                          */
723                         if (parseTree->resultRelations != NIL)
724                         {
725                                 PlanState **appendplans;
726                                 int                     as_nplans;
727                                 ResultRelInfo *resultRelInfo;
728                                 int                     i;
729
730                                 /* Top plan had better be an Append here. */
731                                 Assert(IsA(plan, Append));
732                                 Assert(((Append *) plan)->isTarget);
733                                 Assert(IsA(planstate, AppendState));
734                                 appendplans = ((AppendState *) planstate)->appendplans;
735                                 as_nplans = ((AppendState *) planstate)->as_nplans;
736                                 Assert(as_nplans == estate->es_num_result_relations);
737                                 resultRelInfo = estate->es_result_relations;
738                                 for (i = 0; i < as_nplans; i++)
739                                 {
740                                         PlanState  *subplan = appendplans[i];
741                                         JunkFilter *j;
742
743                                         j = ExecInitJunkFilter(subplan->plan->targetlist,
744                                                                                    ExecGetResultType(subplan),
745                                                           ExecAllocTableSlot(estate->es_tupleTable));
746                                         resultRelInfo->ri_junkFilter = j;
747                                         resultRelInfo++;
748                                 }
749
750                                 /*
751                                  * Set active junkfilter too; at this point ExecInitAppend
752                                  * has already selected an active result relation...
753                                  */
754                                 estate->es_junkFilter =
755                                         estate->es_result_relation_info->ri_junkFilter;
756                         }
757                         else
758                         {
759                                 /* Normal case with just one JunkFilter */
760                                 JunkFilter *j;
761
762                                 j = ExecInitJunkFilter(planstate->plan->targetlist,
763                                                                            tupType,
764                                                           ExecAllocTableSlot(estate->es_tupleTable));
765                                 estate->es_junkFilter = j;
766                                 if (estate->es_result_relation_info)
767                                         estate->es_result_relation_info->ri_junkFilter = j;
768
769                                 /* For SELECT, want to return the cleaned tuple type */
770                                 if (operation == CMD_SELECT)
771                                         tupType = j->jf_cleanTupType;
772                         }
773                 }
774                 else
775                         estate->es_junkFilter = NULL;
776         }
777
778         /*
779          * If doing SELECT INTO, initialize the "into" relation.  We must wait
780          * till now so we have the "clean" result tuple type to create the new
781          * table from.
782          *
783          * If EXPLAIN, skip creating the "into" relation.
784          */
785         intoRelationDesc = NULL;
786
787         if (do_select_into && !explainOnly)
788         {
789                 char       *intoName;
790                 Oid                     namespaceId;
791                 AclResult       aclresult;
792                 Oid                     intoRelationId;
793                 TupleDesc       tupdesc;
794
795                 /*
796                  * find namespace to create in, check permissions
797                  */
798                 intoName = parseTree->into->relname;
799                 namespaceId = RangeVarGetCreationNamespace(parseTree->into);
800
801                 aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(),
802                                                                                   ACL_CREATE);
803                 if (aclresult != ACLCHECK_OK)
804                         aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
805                                                    get_namespace_name(namespaceId));
806
807                 /*
808                  * have to copy tupType to get rid of constraints
809                  */
810                 tupdesc = CreateTupleDescCopy(tupType);
811
812                 intoRelationId = heap_create_with_catalog(intoName,
813                                                                                                   namespaceId,
814                                                                                                   tupdesc,
815                                                                                                   RELKIND_RELATION,
816                                                                                                   false,
817                                                                                                   ONCOMMIT_NOOP,
818                                                                                                   allowSystemTableMods);
819
820                 FreeTupleDesc(tupdesc);
821
822                 /*
823                  * Advance command counter so that the newly-created relation's
824                  * catalog tuples will be visible to heap_open.
825                  */
826                 CommandCounterIncrement();
827
828                 /*
829                  * If necessary, create a TOAST table for the into relation. Note
830                  * that AlterTableCreateToastTable ends with
831                  * CommandCounterIncrement(), so that the TOAST table will be
832                  * visible for insertion.
833                  */
834                 AlterTableCreateToastTable(intoRelationId, true);
835
836                 /*
837                  * And open the constructed table for writing.
838                  */
839                 intoRelationDesc = heap_open(intoRelationId, AccessExclusiveLock);
840         }
841
842         estate->es_into_relation_descriptor = intoRelationDesc;
843
844         queryDesc->tupDesc = tupType;
845         queryDesc->planstate = planstate;
846 }
847
848 /*
849  * Initialize ResultRelInfo data for one result relation
850  */
851 static void
852 initResultRelInfo(ResultRelInfo *resultRelInfo,
853                                   Index resultRelationIndex,
854                                   List *rangeTable,
855                                   CmdType operation)
856 {
857         Oid                     resultRelationOid;
858         Relation        resultRelationDesc;
859
860         resultRelationOid = getrelid(resultRelationIndex, rangeTable);
861         resultRelationDesc = heap_open(resultRelationOid, RowExclusiveLock);
862
863         switch (resultRelationDesc->rd_rel->relkind)
864         {
865                 case RELKIND_SEQUENCE:
866                         ereport(ERROR,
867                                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
868                                          errmsg("cannot change sequence \"%s\"",
869                                                   RelationGetRelationName(resultRelationDesc))));
870                         break;
871                 case RELKIND_TOASTVALUE:
872                         ereport(ERROR,
873                                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
874                                          errmsg("cannot change TOAST relation \"%s\"",
875                                                   RelationGetRelationName(resultRelationDesc))));
876                         break;
877                 case RELKIND_VIEW:
878                         ereport(ERROR,
879                                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
880                                          errmsg("cannot change view \"%s\"",
881                                                   RelationGetRelationName(resultRelationDesc))));
882                         break;
883         }
884
885         MemSet(resultRelInfo, 0, sizeof(ResultRelInfo));
886         resultRelInfo->type = T_ResultRelInfo;
887         resultRelInfo->ri_RangeTableIndex = resultRelationIndex;
888         resultRelInfo->ri_RelationDesc = resultRelationDesc;
889         resultRelInfo->ri_NumIndices = 0;
890         resultRelInfo->ri_IndexRelationDescs = NULL;
891         resultRelInfo->ri_IndexRelationInfo = NULL;
892         /* make a copy so as not to depend on relcache info not changing... */
893         resultRelInfo->ri_TrigDesc = CopyTriggerDesc(resultRelationDesc->trigdesc);
894         resultRelInfo->ri_TrigFunctions = NULL;
895         resultRelInfo->ri_ConstraintExprs = NULL;
896         resultRelInfo->ri_junkFilter = NULL;
897
898         /*
899          * If there are indices on the result relation, open them and save
900          * descriptors in the result relation info, so that we can add new
901          * index entries for the tuples we add/update.  We need not do this
902          * for a DELETE, however, since deletion doesn't affect indexes.
903          */
904         if (resultRelationDesc->rd_rel->relhasindex &&
905                 operation != CMD_DELETE)
906                 ExecOpenIndices(resultRelInfo);
907 }
908
909 /* ----------------------------------------------------------------
910  *              ExecEndPlan
911  *
912  *              Cleans up the query plan -- closes files and frees up storage
913  *
914  * NOTE: we are no longer very worried about freeing storage per se
915  * in this code; FreeExecutorState should be guaranteed to release all
916  * memory that needs to be released.  What we are worried about doing
917  * is closing relations and dropping buffer pins.  Thus, for example,
918  * tuple tables must be cleared or dropped to ensure pins are released.
919  * ----------------------------------------------------------------
920  */
921 void
922 ExecEndPlan(PlanState *planstate, EState *estate)
923 {
924         ResultRelInfo *resultRelInfo;
925         int                     i;
926         List       *l;
927
928         /*
929          * shut down any PlanQual processing we were doing
930          */
931         if (estate->es_evalPlanQual != NULL)
932                 EndEvalPlanQual(estate);
933
934         /*
935          * shut down the node-type-specific query processing
936          */
937         ExecEndNode(planstate);
938
939         /*
940          * destroy the executor "tuple" table.
941          */
942         ExecDropTupleTable(estate->es_tupleTable, true);
943         estate->es_tupleTable = NULL;
944
945         /*
946          * close the result relation(s) if any, but hold locks until xact
947          * commit.
948          */
949         resultRelInfo = estate->es_result_relations;
950         for (i = estate->es_num_result_relations; i > 0; i--)
951         {
952                 /* Close indices and then the relation itself */
953                 ExecCloseIndices(resultRelInfo);
954                 heap_close(resultRelInfo->ri_RelationDesc, NoLock);
955                 resultRelInfo++;
956         }
957
958         /*
959          * close the "into" relation if necessary, again keeping lock
960          */
961         if (estate->es_into_relation_descriptor != NULL)
962                 heap_close(estate->es_into_relation_descriptor, NoLock);
963
964         /*
965          * close any relations selected FOR UPDATE, again keeping locks
966          */
967         foreach(l, estate->es_rowMark)
968         {
969                 execRowMark *erm = lfirst(l);
970
971                 heap_close(erm->relation, NoLock);
972         }
973 }
974
975 /* ----------------------------------------------------------------
976  *              ExecutePlan
977  *
978  *              processes the query plan to retrieve 'numberTuples' tuples in the
979  *              direction specified.
980  *
981  *              Retrieves all tuples if numberTuples is 0
982  *
983  *              result is either a slot containing the last tuple in the case
984  *              of a SELECT or NULL otherwise.
985  *
986  * Note: the ctid attribute is a 'junk' attribute that is removed before the
987  * user can see it
988  * ----------------------------------------------------------------
989  */
990 static TupleTableSlot *
991 ExecutePlan(EState *estate,
992                         PlanState *planstate,
993                         CmdType operation,
994                         long numberTuples,
995                         ScanDirection direction,
996                         DestReceiver *dest)
997 {
998         JunkFilter *junkfilter;
999         TupleTableSlot *slot;
1000         ItemPointer tupleid = NULL;
1001         ItemPointerData tuple_ctid;
1002         long            current_tuple_count;
1003         TupleTableSlot *result;
1004
1005         /*
1006          * initialize local variables
1007          */
1008         slot = NULL;
1009         current_tuple_count = 0;
1010         result = NULL;
1011
1012         /*
1013          * Set the direction.
1014          */
1015         estate->es_direction = direction;
1016
1017         /*
1018          * Process BEFORE EACH STATEMENT triggers
1019          */
1020         switch (operation)
1021         {
1022                 case CMD_UPDATE:
1023                         ExecBSUpdateTriggers(estate, estate->es_result_relation_info);
1024                         break;
1025                 case CMD_DELETE:
1026                         ExecBSDeleteTriggers(estate, estate->es_result_relation_info);
1027                         break;
1028                 case CMD_INSERT:
1029                         ExecBSInsertTriggers(estate, estate->es_result_relation_info);
1030                         break;
1031                 default:
1032                         /* do nothing */
1033                         break;
1034         }
1035
1036         /*
1037          * Loop until we've processed the proper number of tuples from the
1038          * plan.
1039          */
1040
1041         for (;;)
1042         {
1043                 /* Reset the per-output-tuple exprcontext */
1044                 ResetPerTupleExprContext(estate);
1045
1046                 /*
1047                  * Execute the plan and obtain a tuple
1048                  */
1049 lnext:  ;
1050                 if (estate->es_useEvalPlan)
1051                 {
1052                         slot = EvalPlanQualNext(estate);
1053                         if (TupIsNull(slot))
1054                                 slot = ExecProcNode(planstate);
1055                 }
1056                 else
1057                         slot = ExecProcNode(planstate);
1058
1059                 /*
1060                  * if the tuple is null, then we assume there is nothing more to
1061                  * process so we just return null...
1062                  */
1063                 if (TupIsNull(slot))
1064                 {
1065                         result = NULL;
1066                         break;
1067                 }
1068
1069                 /*
1070                  * if we have a junk filter, then project a new tuple with the
1071                  * junk removed.
1072                  *
1073                  * Store this new "clean" tuple in the junkfilter's resultSlot.
1074                  * (Formerly, we stored it back over the "dirty" tuple, which is
1075                  * WRONG because that tuple slot has the wrong descriptor.)
1076                  *
1077                  * Also, extract all the junk information we need.
1078                  */
1079                 if ((junkfilter = estate->es_junkFilter) != NULL)
1080                 {
1081                         Datum           datum;
1082                         HeapTuple       newTuple;
1083                         bool            isNull;
1084
1085                         /*
1086                          * extract the 'ctid' junk attribute.
1087                          */
1088                         if (operation == CMD_UPDATE || operation == CMD_DELETE)
1089                         {
1090                                 if (!ExecGetJunkAttribute(junkfilter,
1091                                                                                   slot,
1092                                                                                   "ctid",
1093                                                                                   &datum,
1094                                                                                   &isNull))
1095                                         elog(ERROR, "could not find junk ctid column");
1096
1097                                 /* shouldn't ever get a null result... */
1098                                 if (isNull)
1099                                         elog(ERROR, "ctid is NULL");
1100
1101                                 tupleid = (ItemPointer) DatumGetPointer(datum);
1102                                 tuple_ctid = *tupleid;  /* make sure we don't free the
1103                                                                                  * ctid!! */
1104                                 tupleid = &tuple_ctid;
1105                         }
1106                         else if (estate->es_rowMark != NIL)
1107                         {
1108                                 List       *l;
1109
1110                 lmark:  ;
1111                                 foreach(l, estate->es_rowMark)
1112                                 {
1113                                         execRowMark *erm = lfirst(l);
1114                                         Buffer          buffer;
1115                                         HeapTupleData tuple;
1116                                         TupleTableSlot *newSlot;
1117                                         int                     test;
1118
1119                                         if (!ExecGetJunkAttribute(junkfilter,
1120                                                                                           slot,
1121                                                                                           erm->resname,
1122                                                                                           &datum,
1123                                                                                           &isNull))
1124                                                 elog(ERROR, "could not find junk \"%s\" column",
1125                                                          erm->resname);
1126
1127                                         /* shouldn't ever get a null result... */
1128                                         if (isNull)
1129                                                 elog(ERROR, "\"%s\" is NULL", erm->resname);
1130
1131                                         tuple.t_self = *((ItemPointer) DatumGetPointer(datum));
1132                                         test = heap_mark4update(erm->relation, &tuple, &buffer,
1133                                                                                         estate->es_snapshot->curcid);
1134                                         ReleaseBuffer(buffer);
1135                                         switch (test)
1136                                         {
1137                                                 case HeapTupleSelfUpdated:
1138                                                         /* treat it as deleted; do not process */
1139                                                         goto lnext;
1140
1141                                                 case HeapTupleMayBeUpdated:
1142                                                         break;
1143
1144                                                 case HeapTupleUpdated:
1145                                                         if (IsXactIsoLevelSerializable)
1146                                                                 ereport(ERROR,
1147                                                                                 (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
1148                                                                                  errmsg("could not serialize access due to concurrent update")));
1149                                                         if (!(ItemPointerEquals(&(tuple.t_self),
1150                                                                   (ItemPointer) DatumGetPointer(datum))))
1151                                                         {
1152                                                                 newSlot = EvalPlanQual(estate, erm->rti, &(tuple.t_self));
1153                                                                 if (!(TupIsNull(newSlot)))
1154                                                                 {
1155                                                                         slot = newSlot;
1156                                                                         estate->es_useEvalPlan = true;
1157                                                                         goto lmark;
1158                                                                 }
1159                                                         }
1160
1161                                                         /*
1162                                                          * if tuple was deleted or PlanQual failed for
1163                                                          * updated tuple - we must not return this
1164                                                          * tuple!
1165                                                          */
1166                                                         goto lnext;
1167
1168                                                 default:
1169                                                         elog(ERROR, "unrecognized heap_mark4update status: %u",
1170                                                                  test);
1171                                                         return (NULL);
1172                                         }
1173                                 }
1174                         }
1175
1176                         /*
1177                          * Finally create a new "clean" tuple with all junk attributes
1178                          * removed
1179                          */
1180                         newTuple = ExecRemoveJunk(junkfilter, slot);
1181
1182                         slot = ExecStoreTuple(newTuple,         /* tuple to store */
1183                                                                   junkfilter->jf_resultSlot,    /* dest slot */
1184                                                                   InvalidBuffer,                /* this tuple has no
1185                                                                                                                  * buffer */
1186                                                                   true);                /* tuple should be pfreed */
1187                 }
1188
1189                 /*
1190                  * now that we have a tuple, do the appropriate thing with it..
1191                  * either return it to the user, add it to a relation someplace,
1192                  * delete it from a relation, or modify some of its attributes.
1193                  */
1194                 switch (operation)
1195                 {
1196                         case CMD_SELECT:
1197                                 ExecSelect(slot,        /* slot containing tuple */
1198                                                    dest,        /* destination's tuple-receiver obj */
1199                                                    estate);
1200                                 result = slot;
1201                                 break;
1202
1203                         case CMD_INSERT:
1204                                 ExecInsert(slot, tupleid, estate);
1205                                 result = NULL;
1206                                 break;
1207
1208                         case CMD_DELETE:
1209                                 ExecDelete(slot, tupleid, estate);
1210                                 result = NULL;
1211                                 break;
1212
1213                         case CMD_UPDATE:
1214                                 ExecUpdate(slot, tupleid, estate);
1215                                 result = NULL;
1216                                 break;
1217
1218                         default:
1219                                 elog(ERROR, "unrecognized operation code: %d",
1220                                          (int) operation);
1221                                 result = NULL;
1222                                 break;
1223                 }
1224
1225                 /*
1226                  * check our tuple count.. if we've processed the proper number
1227                  * then quit, else loop again and process more tuples.  Zero
1228                  * numberTuples means no limit.
1229                  */
1230                 current_tuple_count++;
1231                 if (numberTuples && numberTuples == current_tuple_count)
1232                         break;
1233         }
1234
1235         /*
1236          * Process AFTER EACH STATEMENT triggers
1237          */
1238         switch (operation)
1239         {
1240                 case CMD_UPDATE:
1241                         ExecASUpdateTriggers(estate, estate->es_result_relation_info);
1242                         break;
1243                 case CMD_DELETE:
1244                         ExecASDeleteTriggers(estate, estate->es_result_relation_info);
1245                         break;
1246                 case CMD_INSERT:
1247                         ExecASInsertTriggers(estate, estate->es_result_relation_info);
1248                         break;
1249                 default:
1250                         /* do nothing */
1251                         break;
1252         }
1253
1254         /*
1255          * here, result is either a slot containing a tuple in the case of a
1256          * SELECT or NULL otherwise.
1257          */
1258         return result;
1259 }
1260
1261 /* ----------------------------------------------------------------
1262  *              ExecSelect
1263  *
1264  *              SELECTs are easy.. we just pass the tuple to the appropriate
1265  *              print function.  The only complexity is when we do a
1266  *              "SELECT INTO", in which case we insert the tuple into
1267  *              the appropriate relation (note: this is a newly created relation
1268  *              so we don't need to worry about indices or locks.)
1269  * ----------------------------------------------------------------
1270  */
1271 static void
1272 ExecSelect(TupleTableSlot *slot,
1273                    DestReceiver *dest,
1274                    EState *estate)
1275 {
1276         HeapTuple       tuple;
1277         TupleDesc       attrtype;
1278
1279         /*
1280          * get the heap tuple out of the tuple table slot
1281          */
1282         tuple = slot->val;
1283         attrtype = slot->ttc_tupleDescriptor;
1284
1285         /*
1286          * insert the tuple into the "into relation"
1287          *
1288          * XXX this probably ought to be replaced by a separate destination
1289          */
1290         if (estate->es_into_relation_descriptor != NULL)
1291         {
1292                 heap_insert(estate->es_into_relation_descriptor, tuple,
1293                                         estate->es_snapshot->curcid);
1294                 IncrAppended();
1295         }
1296
1297         /*
1298          * send the tuple to the destination
1299          */
1300         (*dest->receiveTuple) (tuple, attrtype, dest);
1301         IncrRetrieved();
1302         (estate->es_processed)++;
1303 }
1304
1305 /* ----------------------------------------------------------------
1306  *              ExecInsert
1307  *
1308  *              INSERTs are trickier.. we have to insert the tuple into
1309  *              the base relation and insert appropriate tuples into the
1310  *              index relations.
1311  * ----------------------------------------------------------------
1312  */
1313 static void
1314 ExecInsert(TupleTableSlot *slot,
1315                    ItemPointer tupleid,
1316                    EState *estate)
1317 {
1318         HeapTuple       tuple;
1319         ResultRelInfo *resultRelInfo;
1320         Relation        resultRelationDesc;
1321         int                     numIndices;
1322         Oid                     newId;
1323
1324         /*
1325          * get the heap tuple out of the tuple table slot
1326          */
1327         tuple = slot->val;
1328
1329         /*
1330          * get information on the (current) result relation
1331          */
1332         resultRelInfo = estate->es_result_relation_info;
1333         resultRelationDesc = resultRelInfo->ri_RelationDesc;
1334
1335         /* BEFORE ROW INSERT Triggers */
1336         if (resultRelInfo->ri_TrigDesc &&
1337           resultRelInfo->ri_TrigDesc->n_before_row[TRIGGER_EVENT_INSERT] > 0)
1338         {
1339                 HeapTuple       newtuple;
1340
1341                 newtuple = ExecBRInsertTriggers(estate, resultRelInfo, tuple);
1342
1343                 if (newtuple == NULL)   /* "do nothing" */
1344                         return;
1345
1346                 if (newtuple != tuple)  /* modified by Trigger(s) */
1347                 {
1348                         /*
1349                          * Insert modified tuple into tuple table slot, replacing the
1350                          * original.  We assume that it was allocated in per-tuple
1351                          * memory context, and therefore will go away by itself. The
1352                          * tuple table slot should not try to clear it.
1353                          */
1354                         ExecStoreTuple(newtuple, slot, InvalidBuffer, false);
1355                         tuple = newtuple;
1356                 }
1357         }
1358
1359         /*
1360          * Check the constraints of the tuple
1361          */
1362         if (resultRelationDesc->rd_att->constr)
1363                 ExecConstraints(resultRelInfo, slot, estate);
1364
1365         /*
1366          * insert the tuple
1367          */
1368         newId = heap_insert(resultRelationDesc, tuple,
1369                                                 estate->es_snapshot->curcid);
1370
1371         IncrAppended();
1372         (estate->es_processed)++;
1373         estate->es_lastoid = newId;
1374         setLastTid(&(tuple->t_self));
1375
1376         /*
1377          * process indices
1378          *
1379          * Note: heap_insert adds a new tuple to a relation.  As a side effect,
1380          * the tupleid of the new tuple is placed in the new tuple's t_ctid
1381          * field.
1382          */
1383         numIndices = resultRelInfo->ri_NumIndices;
1384         if (numIndices > 0)
1385                 ExecInsertIndexTuples(slot, &(tuple->t_self), estate, false);
1386
1387         /* AFTER ROW INSERT Triggers */
1388         ExecARInsertTriggers(estate, resultRelInfo, tuple);
1389 }
1390
1391 /* ----------------------------------------------------------------
1392  *              ExecDelete
1393  *
1394  *              DELETE is like UPDATE, we delete the tuple and its
1395  *              index tuples.
1396  * ----------------------------------------------------------------
1397  */
1398 static void
1399 ExecDelete(TupleTableSlot *slot,
1400                    ItemPointer tupleid,
1401                    EState *estate)
1402 {
1403         ResultRelInfo *resultRelInfo;
1404         Relation        resultRelationDesc;
1405         ItemPointerData ctid;
1406         int                     result;
1407
1408         /*
1409          * get information on the (current) result relation
1410          */
1411         resultRelInfo = estate->es_result_relation_info;
1412         resultRelationDesc = resultRelInfo->ri_RelationDesc;
1413
1414         /* BEFORE ROW DELETE Triggers */
1415         if (resultRelInfo->ri_TrigDesc &&
1416           resultRelInfo->ri_TrigDesc->n_before_row[TRIGGER_EVENT_DELETE] > 0)
1417         {
1418                 bool            dodelete;
1419
1420                 dodelete = ExecBRDeleteTriggers(estate, resultRelInfo, tupleid,
1421                                                                                 estate->es_snapshot->curcid);
1422
1423                 if (!dodelete)                  /* "do nothing" */
1424                         return;
1425         }
1426
1427         /*
1428          * delete the tuple
1429          */
1430 ldelete:;
1431         result = heap_delete(resultRelationDesc, tupleid,
1432                                                  &ctid,
1433                                                  estate->es_snapshot->curcid,
1434                                                  estate->es_crosscheck_snapshot,
1435                                                  true /* wait for commit */);
1436         switch (result)
1437         {
1438                 case HeapTupleSelfUpdated:
1439                         /* already deleted by self; nothing to do */
1440                         return;
1441
1442                 case HeapTupleMayBeUpdated:
1443                         break;
1444
1445                 case HeapTupleUpdated:
1446                         if (IsXactIsoLevelSerializable)
1447                                 ereport(ERROR,
1448                                                 (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
1449                                                  errmsg("could not serialize access due to concurrent update")));
1450                         else if (!(ItemPointerEquals(tupleid, &ctid)))
1451                         {
1452                                 TupleTableSlot *epqslot = EvalPlanQual(estate,
1453                                                            resultRelInfo->ri_RangeTableIndex, &ctid);
1454
1455                                 if (!TupIsNull(epqslot))
1456                                 {
1457                                         *tupleid = ctid;
1458                                         goto ldelete;
1459                                 }
1460                         }
1461                         /* tuple already deleted; nothing to do */
1462                         return;
1463
1464                 default:
1465                         elog(ERROR, "unrecognized heap_delete status: %u", result);
1466                         return;
1467         }
1468
1469         IncrDeleted();
1470         (estate->es_processed)++;
1471
1472         /*
1473          * Note: Normally one would think that we have to delete index tuples
1474          * associated with the heap tuple now..
1475          *
1476          * ... but in POSTGRES, we have no need to do this because the vacuum
1477          * daemon automatically opens an index scan and deletes index tuples
1478          * when it finds deleted heap tuples. -cim 9/27/89
1479          */
1480
1481         /* AFTER ROW DELETE Triggers */
1482         ExecARDeleteTriggers(estate, resultRelInfo, tupleid);
1483 }
1484
1485 /* ----------------------------------------------------------------
1486  *              ExecUpdate
1487  *
1488  *              note: we can't run UPDATE queries with transactions
1489  *              off because UPDATEs are actually INSERTs and our
1490  *              scan will mistakenly loop forever, updating the tuple
1491  *              it just inserted..      This should be fixed but until it
1492  *              is, we don't want to get stuck in an infinite loop
1493  *              which corrupts your database..
1494  * ----------------------------------------------------------------
1495  */
1496 static void
1497 ExecUpdate(TupleTableSlot *slot,
1498                    ItemPointer tupleid,
1499                    EState *estate)
1500 {
1501         HeapTuple       tuple;
1502         ResultRelInfo *resultRelInfo;
1503         Relation        resultRelationDesc;
1504         ItemPointerData ctid;
1505         int                     result;
1506         int                     numIndices;
1507
1508         /*
1509          * abort the operation if not running transactions
1510          */
1511         if (IsBootstrapProcessingMode())
1512                 elog(ERROR, "cannot UPDATE during bootstrap");
1513
1514         /*
1515          * get the heap tuple out of the tuple table slot
1516          */
1517         tuple = slot->val;
1518
1519         /*
1520          * get information on the (current) result relation
1521          */
1522         resultRelInfo = estate->es_result_relation_info;
1523         resultRelationDesc = resultRelInfo->ri_RelationDesc;
1524
1525         /* BEFORE ROW UPDATE Triggers */
1526         if (resultRelInfo->ri_TrigDesc &&
1527           resultRelInfo->ri_TrigDesc->n_before_row[TRIGGER_EVENT_UPDATE] > 0)
1528         {
1529                 HeapTuple       newtuple;
1530
1531                 newtuple = ExecBRUpdateTriggers(estate, resultRelInfo,
1532                                                                                 tupleid, tuple,
1533                                                                                 estate->es_snapshot->curcid);
1534
1535                 if (newtuple == NULL)   /* "do nothing" */
1536                         return;
1537
1538                 if (newtuple != tuple)  /* modified by Trigger(s) */
1539                 {
1540                         /*
1541                          * Insert modified tuple into tuple table slot, replacing the
1542                          * original.  We assume that it was allocated in per-tuple
1543                          * memory context, and therefore will go away by itself. The
1544                          * tuple table slot should not try to clear it.
1545                          */
1546                         ExecStoreTuple(newtuple, slot, InvalidBuffer, false);
1547                         tuple = newtuple;
1548                 }
1549         }
1550
1551         /*
1552          * Check the constraints of the tuple
1553          *
1554          * If we generate a new candidate tuple after EvalPlanQual testing, we
1555          * must loop back here and recheck constraints.  (We don't need to
1556          * redo triggers, however.      If there are any BEFORE triggers then
1557          * trigger.c will have done mark4update to lock the correct tuple, so
1558          * there's no need to do them again.)
1559          */
1560 lreplace:;
1561         if (resultRelationDesc->rd_att->constr)
1562                 ExecConstraints(resultRelInfo, slot, estate);
1563
1564         /*
1565          * replace the heap tuple
1566          */
1567         result = heap_update(resultRelationDesc, tupleid, tuple,
1568                                                  &ctid,
1569                                                  estate->es_snapshot->curcid,
1570                                                  estate->es_crosscheck_snapshot,
1571                                                  true /* wait for commit */);
1572         switch (result)
1573         {
1574                 case HeapTupleSelfUpdated:
1575                         /* already deleted by self; nothing to do */
1576                         return;
1577
1578                 case HeapTupleMayBeUpdated:
1579                         break;
1580
1581                 case HeapTupleUpdated:
1582                         if (IsXactIsoLevelSerializable)
1583                                 ereport(ERROR,
1584                                                 (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
1585                                                  errmsg("could not serialize access due to concurrent update")));
1586                         else if (!(ItemPointerEquals(tupleid, &ctid)))
1587                         {
1588                                 TupleTableSlot *epqslot = EvalPlanQual(estate,
1589                                                            resultRelInfo->ri_RangeTableIndex, &ctid);
1590
1591                                 if (!TupIsNull(epqslot))
1592                                 {
1593                                         *tupleid = ctid;
1594                                         tuple = ExecRemoveJunk(estate->es_junkFilter, epqslot);
1595                                         slot = ExecStoreTuple(tuple,
1596                                                                         estate->es_junkFilter->jf_resultSlot,
1597                                                                                   InvalidBuffer, true);
1598                                         goto lreplace;
1599                                 }
1600                         }
1601                         /* tuple already deleted; nothing to do */
1602                         return;
1603
1604                 default:
1605                         elog(ERROR, "unrecognized heap_update status: %u", result);
1606                         return;
1607         }
1608
1609         IncrReplaced();
1610         (estate->es_processed)++;
1611
1612         /*
1613          * Note: instead of having to update the old index tuples associated
1614          * with the heap tuple, all we do is form and insert new index tuples.
1615          * This is because UPDATEs are actually DELETEs and INSERTs and index
1616          * tuple deletion is done automagically by the vacuum daemon. All we
1617          * do is insert new index tuples.  -cim 9/27/89
1618          */
1619
1620         /*
1621          * process indices
1622          *
1623          * heap_update updates a tuple in the base relation by invalidating it
1624          * and then inserting a new tuple to the relation.      As a side effect,
1625          * the tupleid of the new tuple is placed in the new tuple's t_ctid
1626          * field.  So we now insert index tuples using the new tupleid stored
1627          * there.
1628          */
1629
1630         numIndices = resultRelInfo->ri_NumIndices;
1631         if (numIndices > 0)
1632                 ExecInsertIndexTuples(slot, &(tuple->t_self), estate, false);
1633
1634         /* AFTER ROW UPDATE Triggers */
1635         ExecARUpdateTriggers(estate, resultRelInfo, tupleid, tuple);
1636 }
1637
1638 static const char *
1639 ExecRelCheck(ResultRelInfo *resultRelInfo,
1640                          TupleTableSlot *slot, EState *estate)
1641 {
1642         Relation        rel = resultRelInfo->ri_RelationDesc;
1643         int                     ncheck = rel->rd_att->constr->num_check;
1644         ConstrCheck *check = rel->rd_att->constr->check;
1645         ExprContext *econtext;
1646         MemoryContext oldContext;
1647         List       *qual;
1648         int                     i;
1649
1650         /*
1651          * If first time through for this result relation, build expression
1652          * nodetrees for rel's constraint expressions.  Keep them in the
1653          * per-query memory context so they'll survive throughout the query.
1654          */
1655         if (resultRelInfo->ri_ConstraintExprs == NULL)
1656         {
1657                 oldContext = MemoryContextSwitchTo(estate->es_query_cxt);
1658                 resultRelInfo->ri_ConstraintExprs =
1659                         (List **) palloc(ncheck * sizeof(List *));
1660                 for (i = 0; i < ncheck; i++)
1661                 {
1662                         /* ExecQual wants implicit-AND form */
1663                         qual = make_ands_implicit(stringToNode(check[i].ccbin));
1664                         resultRelInfo->ri_ConstraintExprs[i] = (List *)
1665                                 ExecPrepareExpr((Expr *) qual, estate);
1666                 }
1667                 MemoryContextSwitchTo(oldContext);
1668         }
1669
1670         /*
1671          * We will use the EState's per-tuple context for evaluating
1672          * constraint expressions (creating it if it's not already there).
1673          */
1674         econtext = GetPerTupleExprContext(estate);
1675
1676         /* Arrange for econtext's scan tuple to be the tuple under test */
1677         econtext->ecxt_scantuple = slot;
1678
1679         /* And evaluate the constraints */
1680         for (i = 0; i < ncheck; i++)
1681         {
1682                 qual = resultRelInfo->ri_ConstraintExprs[i];
1683
1684                 /*
1685                  * NOTE: SQL92 specifies that a NULL result from a constraint
1686                  * expression is not to be treated as a failure.  Therefore, tell
1687                  * ExecQual to return TRUE for NULL.
1688                  */
1689                 if (!ExecQual(qual, econtext, true))
1690                         return check[i].ccname;
1691         }
1692
1693         /* NULL result means no error */
1694         return NULL;
1695 }
1696
1697 void
1698 ExecConstraints(ResultRelInfo *resultRelInfo,
1699                                 TupleTableSlot *slot, EState *estate)
1700 {
1701         Relation        rel = resultRelInfo->ri_RelationDesc;
1702         HeapTuple       tuple = slot->val;
1703         TupleConstr *constr = rel->rd_att->constr;
1704
1705         Assert(constr);
1706
1707         if (constr->has_not_null)
1708         {
1709                 int                     natts = rel->rd_att->natts;
1710                 int                     attrChk;
1711
1712                 for (attrChk = 1; attrChk <= natts; attrChk++)
1713                 {
1714                         if (rel->rd_att->attrs[attrChk - 1]->attnotnull &&
1715                                 heap_attisnull(tuple, attrChk))
1716                                 ereport(ERROR,
1717                                                 (errcode(ERRCODE_NOT_NULL_VIOLATION),
1718                                                  errmsg("null value in column \"%s\" violates not-null constraint",
1719                                         NameStr(rel->rd_att->attrs[attrChk - 1]->attname))));
1720                 }
1721         }
1722
1723         if (constr->num_check > 0)
1724         {
1725                 const char *failed;
1726
1727                 if ((failed = ExecRelCheck(resultRelInfo, slot, estate)) != NULL)
1728                         ereport(ERROR,
1729                                         (errcode(ERRCODE_CHECK_VIOLATION),
1730                                          errmsg("new row for relation \"%s\" violates check constraint \"%s\"",
1731                                                         RelationGetRelationName(rel), failed)));
1732         }
1733 }
1734
1735 /*
1736  * Check a modified tuple to see if we want to process its updated version
1737  * under READ COMMITTED rules.
1738  *
1739  * See backend/executor/README for some info about how this works.
1740  */
1741 TupleTableSlot *
1742 EvalPlanQual(EState *estate, Index rti, ItemPointer tid)
1743 {
1744         evalPlanQual *epq;
1745         EState     *epqstate;
1746         Relation        relation;
1747         HeapTupleData tuple;
1748         HeapTuple       copyTuple = NULL;
1749         bool            endNode;
1750
1751         Assert(rti != 0);
1752
1753         /*
1754          * find relation containing target tuple
1755          */
1756         if (estate->es_result_relation_info != NULL &&
1757                 estate->es_result_relation_info->ri_RangeTableIndex == rti)
1758                 relation = estate->es_result_relation_info->ri_RelationDesc;
1759         else
1760         {
1761                 List       *l;
1762
1763                 relation = NULL;
1764                 foreach(l, estate->es_rowMark)
1765                 {
1766                         if (((execRowMark *) lfirst(l))->rti == rti)
1767                         {
1768                                 relation = ((execRowMark *) lfirst(l))->relation;
1769                                 break;
1770                         }
1771                 }
1772                 if (relation == NULL)
1773                         elog(ERROR, "could not find RowMark for RT index %u", rti);
1774         }
1775
1776         /*
1777          * fetch tid tuple
1778          *
1779          * Loop here to deal with updated or busy tuples
1780          */
1781         tuple.t_self = *tid;
1782         for (;;)
1783         {
1784                 Buffer          buffer;
1785
1786                 if (heap_fetch(relation, SnapshotDirty, &tuple, &buffer, false, NULL))
1787                 {
1788                         TransactionId xwait = SnapshotDirty->xmax;
1789
1790                         /* xmin should not be dirty... */
1791                         if (TransactionIdIsValid(SnapshotDirty->xmin))
1792                                 elog(ERROR, "t_xmin is uncommitted in tuple to be updated");
1793
1794                         /*
1795                          * If tuple is being updated by other transaction then we have
1796                          * to wait for its commit/abort.
1797                          */
1798                         if (TransactionIdIsValid(xwait))
1799                         {
1800                                 ReleaseBuffer(buffer);
1801                                 XactLockTableWait(xwait);
1802                                 continue;
1803                         }
1804
1805                         /*
1806                          * We got tuple - now copy it for use by recheck query.
1807                          */
1808                         copyTuple = heap_copytuple(&tuple);
1809                         ReleaseBuffer(buffer);
1810                         break;
1811                 }
1812
1813                 /*
1814                  * Oops! Invalid tuple. Have to check is it updated or deleted.
1815                  * Note that it's possible to get invalid SnapshotDirty->tid if
1816                  * tuple updated by this transaction. Have we to check this ?
1817                  */
1818                 if (ItemPointerIsValid(&(SnapshotDirty->tid)) &&
1819                         !(ItemPointerEquals(&(tuple.t_self), &(SnapshotDirty->tid))))
1820                 {
1821                         /* updated, so look at the updated copy */
1822                         tuple.t_self = SnapshotDirty->tid;
1823                         continue;
1824                 }
1825
1826                 /*
1827                  * Deleted or updated by this transaction; forget it.
1828                  */
1829                 return NULL;
1830         }
1831
1832         /*
1833          * For UPDATE/DELETE we have to return tid of actual row we're
1834          * executing PQ for.
1835          */
1836         *tid = tuple.t_self;
1837
1838         /*
1839          * Need to run a recheck subquery.      Find or create a PQ stack entry.
1840          */
1841         epq = estate->es_evalPlanQual;
1842         endNode = true;
1843
1844         if (epq != NULL && epq->rti == 0)
1845         {
1846                 /* Top PQ stack entry is idle, so re-use it */
1847                 Assert(!(estate->es_useEvalPlan) && epq->next == NULL);
1848                 epq->rti = rti;
1849                 endNode = false;
1850         }
1851
1852         /*
1853          * If this is request for another RTE - Ra, - then we have to check
1854          * wasn't PlanQual requested for Ra already and if so then Ra' row was
1855          * updated again and we have to re-start old execution for Ra and
1856          * forget all what we done after Ra was suspended. Cool? -:))
1857          */
1858         if (epq != NULL && epq->rti != rti &&
1859                 epq->estate->es_evTuple[rti - 1] != NULL)
1860         {
1861                 do
1862                 {
1863                         evalPlanQual *oldepq;
1864
1865                         /* stop execution */
1866                         EvalPlanQualStop(epq);
1867                         /* pop previous PlanQual from the stack */
1868                         oldepq = epq->next;
1869                         Assert(oldepq && oldepq->rti != 0);
1870                         /* push current PQ to freePQ stack */
1871                         oldepq->free = epq;
1872                         epq = oldepq;
1873                         estate->es_evalPlanQual = epq;
1874                 } while (epq->rti != rti);
1875         }
1876
1877         /*
1878          * If we are requested for another RTE then we have to suspend
1879          * execution of current PlanQual and start execution for new one.
1880          */
1881         if (epq == NULL || epq->rti != rti)
1882         {
1883                 /* try to reuse plan used previously */
1884                 evalPlanQual *newepq = (epq != NULL) ? epq->free : NULL;
1885
1886                 if (newepq == NULL)             /* first call or freePQ stack is empty */
1887                 {
1888                         newepq = (evalPlanQual *) palloc0(sizeof(evalPlanQual));
1889                         newepq->free = NULL;
1890                         newepq->estate = NULL;
1891                         newepq->planstate = NULL;
1892                 }
1893                 else
1894                 {
1895                         /* recycle previously used PlanQual */
1896                         Assert(newepq->estate == NULL);
1897                         epq->free = NULL;
1898                 }
1899                 /* push current PQ to the stack */
1900                 newepq->next = epq;
1901                 epq = newepq;
1902                 estate->es_evalPlanQual = epq;
1903                 epq->rti = rti;
1904                 endNode = false;
1905         }
1906
1907         Assert(epq->rti == rti);
1908
1909         /*
1910          * Ok - we're requested for the same RTE.  Unfortunately we still have
1911          * to end and restart execution of the plan, because ExecReScan
1912          * wouldn't ensure that upper plan nodes would reset themselves.  We
1913          * could make that work if insertion of the target tuple were
1914          * integrated with the Param mechanism somehow, so that the upper plan
1915          * nodes know that their children's outputs have changed.
1916          *
1917          * Note that the stack of free evalPlanQual nodes is quite useless at the
1918          * moment, since it only saves us from pallocing/releasing the
1919          * evalPlanQual nodes themselves.  But it will be useful once we
1920          * implement ReScan instead of end/restart for re-using PlanQual
1921          * nodes.
1922          */
1923         if (endNode)
1924         {
1925                 /* stop execution */
1926                 EvalPlanQualStop(epq);
1927         }
1928
1929         /*
1930          * Initialize new recheck query.
1931          *
1932          * Note: if we were re-using PlanQual plans via ExecReScan, we'd need to
1933          * instead copy down changeable state from the top plan (including
1934          * es_result_relation_info, es_junkFilter) and reset locally
1935          * changeable state in the epq (including es_param_exec_vals,
1936          * es_evTupleNull).
1937          */
1938         EvalPlanQualStart(epq, estate, epq->next);
1939
1940         /*
1941          * free old RTE' tuple, if any, and store target tuple where
1942          * relation's scan node will see it
1943          */
1944         epqstate = epq->estate;
1945         if (epqstate->es_evTuple[rti - 1] != NULL)
1946                 heap_freetuple(epqstate->es_evTuple[rti - 1]);
1947         epqstate->es_evTuple[rti - 1] = copyTuple;
1948
1949         return EvalPlanQualNext(estate);
1950 }
1951
1952 static TupleTableSlot *
1953 EvalPlanQualNext(EState *estate)
1954 {
1955         evalPlanQual *epq = estate->es_evalPlanQual;
1956         MemoryContext oldcontext;
1957         TupleTableSlot *slot;
1958
1959         Assert(epq->rti != 0);
1960
1961 lpqnext:;
1962         oldcontext = MemoryContextSwitchTo(epq->estate->es_query_cxt);
1963         slot = ExecProcNode(epq->planstate);
1964         MemoryContextSwitchTo(oldcontext);
1965
1966         /*
1967          * No more tuples for this PQ. Continue previous one.
1968          */
1969         if (TupIsNull(slot))
1970         {
1971                 evalPlanQual *oldepq;
1972
1973                 /* stop execution */
1974                 EvalPlanQualStop(epq);
1975                 /* pop old PQ from the stack */
1976                 oldepq = epq->next;
1977                 if (oldepq == NULL)
1978                 {
1979                         /* this is the first (oldest) PQ - mark as free */
1980                         epq->rti = 0;
1981                         estate->es_useEvalPlan = false;
1982                         /* and continue Query execution */
1983                         return (NULL);
1984                 }
1985                 Assert(oldepq->rti != 0);
1986                 /* push current PQ to freePQ stack */
1987                 oldepq->free = epq;
1988                 epq = oldepq;
1989                 estate->es_evalPlanQual = epq;
1990                 goto lpqnext;
1991         }
1992
1993         return (slot);
1994 }
1995
1996 static void
1997 EndEvalPlanQual(EState *estate)
1998 {
1999         evalPlanQual *epq = estate->es_evalPlanQual;
2000
2001         if (epq->rti == 0)                      /* plans already shutdowned */
2002         {
2003                 Assert(epq->next == NULL);
2004                 return;
2005         }
2006
2007         for (;;)
2008         {
2009                 evalPlanQual *oldepq;
2010
2011                 /* stop execution */
2012                 EvalPlanQualStop(epq);
2013                 /* pop old PQ from the stack */
2014                 oldepq = epq->next;
2015                 if (oldepq == NULL)
2016                 {
2017                         /* this is the first (oldest) PQ - mark as free */
2018                         epq->rti = 0;
2019                         estate->es_useEvalPlan = false;
2020                         break;
2021                 }
2022                 Assert(oldepq->rti != 0);
2023                 /* push current PQ to freePQ stack */
2024                 oldepq->free = epq;
2025                 epq = oldepq;
2026                 estate->es_evalPlanQual = epq;
2027         }
2028 }
2029
2030 /*
2031  * Start execution of one level of PlanQual.
2032  *
2033  * This is a cut-down version of ExecutorStart(): we copy some state from
2034  * the top-level estate rather than initializing it fresh.
2035  */
2036 static void
2037 EvalPlanQualStart(evalPlanQual *epq, EState *estate, evalPlanQual *priorepq)
2038 {
2039         EState     *epqstate;
2040         int                     rtsize;
2041         MemoryContext oldcontext;
2042
2043         rtsize = length(estate->es_range_table);
2044
2045         epq->estate = epqstate = CreateExecutorState();
2046
2047         oldcontext = MemoryContextSwitchTo(epqstate->es_query_cxt);
2048
2049         /*
2050          * The epqstates share the top query's copy of unchanging state such
2051          * as the snapshot, rangetable, result-rel info, and external Param
2052          * info. They need their own copies of local state, including a tuple
2053          * table, es_param_exec_vals, etc.
2054          */
2055         epqstate->es_direction = ForwardScanDirection;
2056         epqstate->es_snapshot = estate->es_snapshot;
2057         epqstate->es_crosscheck_snapshot = estate->es_crosscheck_snapshot;
2058         epqstate->es_range_table = estate->es_range_table;
2059         epqstate->es_result_relations = estate->es_result_relations;
2060         epqstate->es_num_result_relations = estate->es_num_result_relations;
2061         epqstate->es_result_relation_info = estate->es_result_relation_info;
2062         epqstate->es_junkFilter = estate->es_junkFilter;
2063         epqstate->es_into_relation_descriptor = estate->es_into_relation_descriptor;
2064         epqstate->es_param_list_info = estate->es_param_list_info;
2065         if (estate->es_topPlan->nParamExec > 0)
2066                 epqstate->es_param_exec_vals = (ParamExecData *)
2067                         palloc0(estate->es_topPlan->nParamExec * sizeof(ParamExecData));
2068         epqstate->es_rowMark = estate->es_rowMark;
2069         epqstate->es_instrument = estate->es_instrument;
2070         epqstate->es_force_oids = estate->es_force_oids;
2071         epqstate->es_topPlan = estate->es_topPlan;
2072
2073         /*
2074          * Each epqstate must have its own es_evTupleNull state, but all the
2075          * stack entries share es_evTuple state.  This allows sub-rechecks to
2076          * inherit the value being examined by an outer recheck.
2077          */
2078         epqstate->es_evTupleNull = (bool *) palloc0(rtsize * sizeof(bool));
2079         if (priorepq == NULL)
2080                 /* first PQ stack entry */
2081                 epqstate->es_evTuple = (HeapTuple *)
2082                         palloc0(rtsize * sizeof(HeapTuple));
2083         else
2084                 /* later stack entries share the same storage */
2085                 epqstate->es_evTuple = priorepq->estate->es_evTuple;
2086
2087         epqstate->es_tupleTable =
2088                 ExecCreateTupleTable(estate->es_tupleTable->size);
2089
2090         epq->planstate = ExecInitNode(estate->es_topPlan, epqstate);
2091
2092         MemoryContextSwitchTo(oldcontext);
2093 }
2094
2095 /*
2096  * End execution of one level of PlanQual.
2097  *
2098  * This is a cut-down version of ExecutorEnd(); basically we want to do most
2099  * of the normal cleanup, but *not* close result relations (which we are
2100  * just sharing from the outer query).
2101  */
2102 static void
2103 EvalPlanQualStop(evalPlanQual *epq)
2104 {
2105         EState     *epqstate = epq->estate;
2106         MemoryContext oldcontext;
2107
2108         oldcontext = MemoryContextSwitchTo(epqstate->es_query_cxt);
2109
2110         ExecEndNode(epq->planstate);
2111
2112         ExecDropTupleTable(epqstate->es_tupleTable, true);
2113         epqstate->es_tupleTable = NULL;
2114
2115         if (epqstate->es_evTuple[epq->rti - 1] != NULL)
2116         {
2117                 heap_freetuple(epqstate->es_evTuple[epq->rti - 1]);
2118                 epqstate->es_evTuple[epq->rti - 1] = NULL;
2119         }
2120
2121         MemoryContextSwitchTo(oldcontext);
2122
2123         FreeExecutorState(epqstate);
2124
2125         epq->estate = NULL;
2126         epq->planstate = NULL;
2127 }