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