]> granicus.if.org Git - postgresql/blob - src/backend/executor/execMain.c
Update EvalPlanQual() to work with new executor memory management method.
[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.195 2002/12/18 00:14:47 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, e.g. 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  *              Retrieves all tuples if numberTuples is 0
850  *
851  *              result is either a slot containing the last tuple in the case
852  *              of a SELECT or NULL otherwise.
853  *
854  * Note: the ctid attribute is a 'junk' attribute that is removed before the
855  * user can see it
856  * ----------------------------------------------------------------
857  */
858 static TupleTableSlot *
859 ExecutePlan(EState *estate,
860                         PlanState *planstate,
861                         CmdType operation,
862                         long numberTuples,
863                         ScanDirection direction,
864                         DestReceiver *destfunc)
865 {
866         JunkFilter                      *junkfilter;
867         TupleTableSlot          *slot;
868         ItemPointer                      tupleid = NULL;
869         ItemPointerData          tuple_ctid;
870         long                             current_tuple_count;
871         TupleTableSlot          *result;
872
873         /*
874          * initialize local variables
875          */
876         slot = NULL;
877         current_tuple_count = 0;
878         result = NULL;
879
880         /*
881          * Set the direction.
882          */
883         estate->es_direction = direction;
884
885         /*
886          * Process BEFORE EACH STATEMENT triggers
887          */
888         switch (operation)
889         {
890                 case CMD_UPDATE:
891                         ExecBSUpdateTriggers(estate, estate->es_result_relation_info);
892                         break;
893                 case CMD_DELETE:
894                         ExecBSDeleteTriggers(estate, estate->es_result_relation_info);
895                         break;
896                 case CMD_INSERT:
897                         ExecBSInsertTriggers(estate, estate->es_result_relation_info);
898                         break;
899                 default:
900                         /* do nothing */
901                         break;
902         }
903
904         /*
905          * Loop until we've processed the proper number of tuples from the
906          * plan.
907          */
908
909         for (;;)
910         {
911                 /* Reset the per-output-tuple exprcontext */
912                 ResetPerTupleExprContext(estate);
913
914                 /*
915                  * Execute the plan and obtain a tuple
916                  */
917 lnext:  ;
918                 if (estate->es_useEvalPlan)
919                 {
920                         slot = EvalPlanQualNext(estate);
921                         if (TupIsNull(slot))
922                                 slot = ExecProcNode(planstate);
923                 }
924                 else
925                         slot = ExecProcNode(planstate);
926
927                 /*
928                  * if the tuple is null, then we assume there is nothing more to
929                  * process so we just return null...
930                  */
931                 if (TupIsNull(slot))
932                 {
933                         result = NULL;
934                         break;
935                 }
936
937                 /*
938                  * if we have a junk filter, then project a new tuple with the
939                  * junk removed.
940                  *
941                  * Store this new "clean" tuple in the junkfilter's resultSlot.
942                  * (Formerly, we stored it back over the "dirty" tuple, which is
943                  * WRONG because that tuple slot has the wrong descriptor.)
944                  *
945                  * Also, extract all the junk information we need.
946                  */
947                 if ((junkfilter = estate->es_junkFilter) != (JunkFilter *) NULL)
948                 {
949                         Datum           datum;
950                         HeapTuple       newTuple;
951                         bool            isNull;
952
953                         /*
954                          * extract the 'ctid' junk attribute.
955                          */
956                         if (operation == CMD_UPDATE || operation == CMD_DELETE)
957                         {
958                                 if (!ExecGetJunkAttribute(junkfilter,
959                                                                                   slot,
960                                                                                   "ctid",
961                                                                                   &datum,
962                                                                                   &isNull))
963                                         elog(ERROR, "ExecutePlan: NO (junk) `ctid' was found!");
964
965                                 /* shouldn't ever get a null result... */
966                                 if (isNull)
967                                         elog(ERROR, "ExecutePlan: (junk) `ctid' is NULL!");
968
969                                 tupleid = (ItemPointer) DatumGetPointer(datum);
970                                 tuple_ctid = *tupleid;  /* make sure we don't free the
971                                                                                  * ctid!! */
972                                 tupleid = &tuple_ctid;
973                         }
974                         else if (estate->es_rowMark != NIL)
975                         {
976                                 List       *l;
977
978                 lmark:  ;
979                                 foreach(l, estate->es_rowMark)
980                                 {
981                                         execRowMark *erm = lfirst(l);
982                                         Buffer          buffer;
983                                         HeapTupleData tuple;
984                                         TupleTableSlot *newSlot;
985                                         int                     test;
986
987                                         if (!ExecGetJunkAttribute(junkfilter,
988                                                                                           slot,
989                                                                                           erm->resname,
990                                                                                           &datum,
991                                                                                           &isNull))
992                                                 elog(ERROR, "ExecutePlan: NO (junk) `%s' was found!",
993                                                          erm->resname);
994
995                                         /* shouldn't ever get a null result... */
996                                         if (isNull)
997                                                 elog(ERROR, "ExecutePlan: (junk) `%s' is NULL!",
998                                                          erm->resname);
999
1000                                         tuple.t_self = *((ItemPointer) DatumGetPointer(datum));
1001                                         test = heap_mark4update(erm->relation, &tuple, &buffer,
1002                                                                                         estate->es_snapshot->curcid);
1003                                         ReleaseBuffer(buffer);
1004                                         switch (test)
1005                                         {
1006                                                 case HeapTupleSelfUpdated:
1007                                                         /* treat it as deleted; do not process */
1008                                                         goto lnext;
1009
1010                                                 case HeapTupleMayBeUpdated:
1011                                                         break;
1012
1013                                                 case HeapTupleUpdated:
1014                                                         if (XactIsoLevel == XACT_SERIALIZABLE)
1015                                                                 elog(ERROR, "Can't serialize access due to concurrent update");
1016                                                         if (!(ItemPointerEquals(&(tuple.t_self),
1017                                                                   (ItemPointer) DatumGetPointer(datum))))
1018                                                         {
1019                                                                 newSlot = EvalPlanQual(estate, erm->rti, &(tuple.t_self));
1020                                                                 if (!(TupIsNull(newSlot)))
1021                                                                 {
1022                                                                         slot = newSlot;
1023                                                                         estate->es_useEvalPlan = true;
1024                                                                         goto lmark;
1025                                                                 }
1026                                                         }
1027
1028                                                         /*
1029                                                          * if tuple was deleted or PlanQual failed for
1030                                                          * updated tuple - we must not return this
1031                                                          * tuple!
1032                                                          */
1033                                                         goto lnext;
1034
1035                                                 default:
1036                                                         elog(ERROR, "Unknown status %u from heap_mark4update", test);
1037                                                         return (NULL);
1038                                         }
1039                                 }
1040                         }
1041
1042                         /*
1043                          * Finally create a new "clean" tuple with all junk attributes
1044                          * removed
1045                          */
1046                         newTuple = ExecRemoveJunk(junkfilter, slot);
1047
1048                         slot = ExecStoreTuple(newTuple,         /* tuple to store */
1049                                                                   junkfilter->jf_resultSlot,    /* dest slot */
1050                                                                   InvalidBuffer,                /* this tuple has no
1051                                                                                                                  * buffer */
1052                                                                   true);                /* tuple should be pfreed */
1053                 }
1054
1055                 /*
1056                  * now that we have a tuple, do the appropriate thing with it..
1057                  * either return it to the user, add it to a relation someplace,
1058                  * delete it from a relation, or modify some of its attributes.
1059                  */
1060                 switch (operation)
1061                 {
1062                         case CMD_SELECT:
1063                                 ExecSelect(slot,        /* slot containing tuple */
1064                                                    destfunc,    /* destination's tuple-receiver
1065                                                                                  * obj */
1066                                                    estate);
1067                                 result = slot;
1068                                 break;
1069
1070                         case CMD_INSERT:
1071                                 ExecInsert(slot, tupleid, estate);
1072                                 result = NULL;
1073                                 break;
1074
1075                         case CMD_DELETE:
1076                                 ExecDelete(slot, tupleid, estate);
1077                                 result = NULL;
1078                                 break;
1079
1080                         case CMD_UPDATE:
1081                                 ExecUpdate(slot, tupleid, estate);
1082                                 result = NULL;
1083                                 break;
1084
1085                         default:
1086                                 elog(LOG, "ExecutePlan: unknown operation in queryDesc");
1087                                 result = NULL;
1088                                 break;
1089                 }
1090
1091                 /*
1092                  * check our tuple count.. if we've processed the proper number
1093                  * then quit, else loop again and process more tuples.  Zero
1094                  * number_tuples means no limit.
1095                  */
1096                 current_tuple_count++;
1097                 if (numberTuples == current_tuple_count)
1098                         break;
1099         }
1100
1101         /*
1102          * Process AFTER EACH STATEMENT triggers
1103          */
1104         switch (operation)
1105         {
1106                 case CMD_UPDATE:
1107                         ExecASUpdateTriggers(estate, estate->es_result_relation_info);
1108                         break;
1109                 case CMD_DELETE:
1110                         ExecASDeleteTriggers(estate, estate->es_result_relation_info);
1111                         break;
1112                 case CMD_INSERT:
1113                         ExecASInsertTriggers(estate, estate->es_result_relation_info);
1114                         break;
1115                 default:
1116                         /* do nothing */
1117                         break;
1118         }
1119
1120         /*
1121          * here, result is either a slot containing a tuple in the case of a
1122          * SELECT or NULL otherwise.
1123          */
1124         return result;
1125 }
1126
1127 /* ----------------------------------------------------------------
1128  *              ExecSelect
1129  *
1130  *              SELECTs are easy.. we just pass the tuple to the appropriate
1131  *              print function.  The only complexity is when we do a
1132  *              "SELECT INTO", in which case we insert the tuple into
1133  *              the appropriate relation (note: this is a newly created relation
1134  *              so we don't need to worry about indices or locks.)
1135  * ----------------------------------------------------------------
1136  */
1137 static void
1138 ExecSelect(TupleTableSlot *slot,
1139                    DestReceiver *destfunc,
1140                    EState *estate)
1141 {
1142         HeapTuple       tuple;
1143         TupleDesc       attrtype;
1144
1145         /*
1146          * get the heap tuple out of the tuple table slot
1147          */
1148         tuple = slot->val;
1149         attrtype = slot->ttc_tupleDescriptor;
1150
1151         /*
1152          * insert the tuple into the "into relation"
1153          */
1154         if (estate->es_into_relation_descriptor != NULL)
1155         {
1156                 heap_insert(estate->es_into_relation_descriptor, tuple,
1157                                         estate->es_snapshot->curcid);
1158                 IncrAppended();
1159         }
1160
1161         /*
1162          * send the tuple to the front end (or the screen)
1163          */
1164         (*destfunc->receiveTuple) (tuple, attrtype, destfunc);
1165         IncrRetrieved();
1166         (estate->es_processed)++;
1167 }
1168
1169 /* ----------------------------------------------------------------
1170  *              ExecInsert
1171  *
1172  *              INSERTs are trickier.. we have to insert the tuple into
1173  *              the base relation and insert appropriate tuples into the
1174  *              index relations.
1175  * ----------------------------------------------------------------
1176  */
1177 static void
1178 ExecInsert(TupleTableSlot *slot,
1179                    ItemPointer tupleid,
1180                    EState *estate)
1181 {
1182         HeapTuple       tuple;
1183         ResultRelInfo *resultRelInfo;
1184         Relation        resultRelationDesc;
1185         int                     numIndices;
1186         Oid                     newId;
1187
1188         /*
1189          * get the heap tuple out of the tuple table slot
1190          */
1191         tuple = slot->val;
1192
1193         /*
1194          * get information on the (current) result relation
1195          */
1196         resultRelInfo = estate->es_result_relation_info;
1197         resultRelationDesc = resultRelInfo->ri_RelationDesc;
1198
1199         /* BEFORE ROW INSERT Triggers */
1200         if (resultRelInfo->ri_TrigDesc &&
1201                 resultRelInfo->ri_TrigDesc->n_before_row[TRIGGER_EVENT_INSERT] > 0)
1202         {
1203                 HeapTuple       newtuple;
1204
1205                 newtuple = ExecBRInsertTriggers(estate, resultRelInfo, tuple);
1206
1207                 if (newtuple == NULL)   /* "do nothing" */
1208                         return;
1209
1210                 if (newtuple != tuple)  /* modified by Trigger(s) */
1211                 {
1212                         /*
1213                          * Insert modified tuple into tuple table slot, replacing the
1214                          * original.  We assume that it was allocated in per-tuple
1215                          * memory context, and therefore will go away by itself. The
1216                          * tuple table slot should not try to clear it.
1217                          */
1218                         ExecStoreTuple(newtuple, slot, InvalidBuffer, false);
1219                         tuple = newtuple;
1220                 }
1221         }
1222
1223         /*
1224          * Check the constraints of the tuple
1225          */
1226         if (resultRelationDesc->rd_att->constr)
1227                 ExecConstraints("ExecInsert", resultRelInfo, slot, estate);
1228
1229         /*
1230          * insert the tuple
1231          */
1232         newId = heap_insert(resultRelationDesc, tuple,
1233                                                 estate->es_snapshot->curcid);
1234
1235         IncrAppended();
1236         (estate->es_processed)++;
1237         estate->es_lastoid = newId;
1238         setLastTid(&(tuple->t_self));
1239
1240         /*
1241          * process indices
1242          *
1243          * Note: heap_insert adds a new tuple to a relation.  As a side effect,
1244          * the tupleid of the new tuple is placed in the new tuple's t_ctid
1245          * field.
1246          */
1247         numIndices = resultRelInfo->ri_NumIndices;
1248         if (numIndices > 0)
1249                 ExecInsertIndexTuples(slot, &(tuple->t_self), estate, false);
1250
1251         /* AFTER ROW INSERT Triggers */
1252         ExecARInsertTriggers(estate, resultRelInfo, tuple);
1253 }
1254
1255 /* ----------------------------------------------------------------
1256  *              ExecDelete
1257  *
1258  *              DELETE is like UPDATE, we delete the tuple and its
1259  *              index tuples.
1260  * ----------------------------------------------------------------
1261  */
1262 static void
1263 ExecDelete(TupleTableSlot *slot,
1264                    ItemPointer tupleid,
1265                    EState *estate)
1266 {
1267         ResultRelInfo *resultRelInfo;
1268         Relation        resultRelationDesc;
1269         ItemPointerData ctid;
1270         int                     result;
1271
1272         /*
1273          * get information on the (current) result relation
1274          */
1275         resultRelInfo = estate->es_result_relation_info;
1276         resultRelationDesc = resultRelInfo->ri_RelationDesc;
1277
1278         /* BEFORE ROW DELETE Triggers */
1279         if (resultRelInfo->ri_TrigDesc &&
1280           resultRelInfo->ri_TrigDesc->n_before_row[TRIGGER_EVENT_DELETE] > 0)
1281         {
1282                 bool            dodelete;
1283
1284                 dodelete = ExecBRDeleteTriggers(estate, resultRelInfo, tupleid);
1285
1286                 if (!dodelete)                  /* "do nothing" */
1287                         return;
1288         }
1289
1290         /*
1291          * delete the tuple
1292          */
1293 ldelete:;
1294         result = heap_delete(resultRelationDesc, tupleid,
1295                                                  &ctid,
1296                                                  estate->es_snapshot->curcid);
1297         switch (result)
1298         {
1299                 case HeapTupleSelfUpdated:
1300                         /* already deleted by self; nothing to do */
1301                         return;
1302
1303                 case HeapTupleMayBeUpdated:
1304                         break;
1305
1306                 case HeapTupleUpdated:
1307                         if (XactIsoLevel == XACT_SERIALIZABLE)
1308                                 elog(ERROR, "Can't serialize access due to concurrent update");
1309                         else if (!(ItemPointerEquals(tupleid, &ctid)))
1310                         {
1311                                 TupleTableSlot *epqslot = EvalPlanQual(estate,
1312                                                            resultRelInfo->ri_RangeTableIndex, &ctid);
1313
1314                                 if (!TupIsNull(epqslot))
1315                                 {
1316                                         *tupleid = ctid;
1317                                         goto ldelete;
1318                                 }
1319                         }
1320                         /* tuple already deleted; nothing to do */
1321                         return;
1322
1323                 default:
1324                         elog(ERROR, "Unknown status %u from heap_delete", result);
1325                         return;
1326         }
1327
1328         IncrDeleted();
1329         (estate->es_processed)++;
1330
1331         /*
1332          * Note: Normally one would think that we have to delete index tuples
1333          * associated with the heap tuple now..
1334          *
1335          * ... but in POSTGRES, we have no need to do this because the vacuum
1336          * daemon automatically opens an index scan and deletes index tuples
1337          * when it finds deleted heap tuples. -cim 9/27/89
1338          */
1339
1340         /* AFTER ROW DELETE Triggers */
1341         ExecARDeleteTriggers(estate, resultRelInfo, tupleid);
1342 }
1343
1344 /* ----------------------------------------------------------------
1345  *              ExecUpdate
1346  *
1347  *              note: we can't run UPDATE queries with transactions
1348  *              off because UPDATEs are actually INSERTs and our
1349  *              scan will mistakenly loop forever, updating the tuple
1350  *              it just inserted..      This should be fixed but until it
1351  *              is, we don't want to get stuck in an infinite loop
1352  *              which corrupts your database..
1353  * ----------------------------------------------------------------
1354  */
1355 static void
1356 ExecUpdate(TupleTableSlot *slot,
1357                    ItemPointer tupleid,
1358                    EState *estate)
1359 {
1360         HeapTuple       tuple;
1361         ResultRelInfo *resultRelInfo;
1362         Relation        resultRelationDesc;
1363         ItemPointerData ctid;
1364         int                     result;
1365         int                     numIndices;
1366
1367         /*
1368          * abort the operation if not running transactions
1369          */
1370         if (IsBootstrapProcessingMode())
1371         {
1372                 elog(WARNING, "ExecUpdate: UPDATE can't run without transactions");
1373                 return;
1374         }
1375
1376         /*
1377          * get the heap tuple out of the tuple table slot
1378          */
1379         tuple = slot->val;
1380
1381         /*
1382          * get information on the (current) result relation
1383          */
1384         resultRelInfo = estate->es_result_relation_info;
1385         resultRelationDesc = resultRelInfo->ri_RelationDesc;
1386
1387         /* BEFORE ROW UPDATE Triggers */
1388         if (resultRelInfo->ri_TrigDesc &&
1389           resultRelInfo->ri_TrigDesc->n_before_row[TRIGGER_EVENT_UPDATE] > 0)
1390         {
1391                 HeapTuple       newtuple;
1392
1393                 newtuple = ExecBRUpdateTriggers(estate, resultRelInfo,
1394                                                                                 tupleid, tuple);
1395
1396                 if (newtuple == NULL)   /* "do nothing" */
1397                         return;
1398
1399                 if (newtuple != tuple)  /* modified by Trigger(s) */
1400                 {
1401                         /*
1402                          * Insert modified tuple into tuple table slot, replacing the
1403                          * original.  We assume that it was allocated in per-tuple
1404                          * memory context, and therefore will go away by itself. The
1405                          * tuple table slot should not try to clear it.
1406                          */
1407                         ExecStoreTuple(newtuple, slot, InvalidBuffer, false);
1408                         tuple = newtuple;
1409                 }
1410         }
1411
1412         /*
1413          * Check the constraints of the tuple
1414          *
1415          * If we generate a new candidate tuple after EvalPlanQual testing, we
1416          * must loop back here and recheck constraints.  (We don't need to
1417          * redo triggers, however.      If there are any BEFORE triggers then
1418          * trigger.c will have done mark4update to lock the correct tuple, so
1419          * there's no need to do them again.)
1420          */
1421 lreplace:;
1422         if (resultRelationDesc->rd_att->constr)
1423                 ExecConstraints("ExecUpdate", resultRelInfo, slot, estate);
1424
1425         /*
1426          * replace the heap tuple
1427          */
1428         result = heap_update(resultRelationDesc, tupleid, tuple,
1429                                                  &ctid,
1430                                                  estate->es_snapshot->curcid);
1431         switch (result)
1432         {
1433                 case HeapTupleSelfUpdated:
1434                         /* already deleted by self; nothing to do */
1435                         return;
1436
1437                 case HeapTupleMayBeUpdated:
1438                         break;
1439
1440                 case HeapTupleUpdated:
1441                         if (XactIsoLevel == XACT_SERIALIZABLE)
1442                                 elog(ERROR, "Can't serialize access due to concurrent update");
1443                         else if (!(ItemPointerEquals(tupleid, &ctid)))
1444                         {
1445                                 TupleTableSlot *epqslot = EvalPlanQual(estate,
1446                                                            resultRelInfo->ri_RangeTableIndex, &ctid);
1447
1448                                 if (!TupIsNull(epqslot))
1449                                 {
1450                                         *tupleid = ctid;
1451                                         tuple = ExecRemoveJunk(estate->es_junkFilter, epqslot);
1452                                         slot = ExecStoreTuple(tuple,
1453                                                                         estate->es_junkFilter->jf_resultSlot,
1454                                                                                   InvalidBuffer, true);
1455                                         goto lreplace;
1456                                 }
1457                         }
1458                         /* tuple already deleted; nothing to do */
1459                         return;
1460
1461                 default:
1462                         elog(ERROR, "Unknown status %u from heap_update", result);
1463                         return;
1464         }
1465
1466         IncrReplaced();
1467         (estate->es_processed)++;
1468
1469         /*
1470          * Note: instead of having to update the old index tuples associated
1471          * with the heap tuple, all we do is form and insert new index tuples.
1472          * This is because UPDATEs are actually DELETEs and INSERTs and index
1473          * tuple deletion is done automagically by the vacuum daemon. All we
1474          * do is insert new index tuples.  -cim 9/27/89
1475          */
1476
1477         /*
1478          * process indices
1479          *
1480          * heap_update updates a tuple in the base relation by invalidating it
1481          * and then inserting a new tuple to the relation.      As a side effect,
1482          * the tupleid of the new tuple is placed in the new tuple's t_ctid
1483          * field.  So we now insert index tuples using the new tupleid stored
1484          * there.
1485          */
1486
1487         numIndices = resultRelInfo->ri_NumIndices;
1488         if (numIndices > 0)
1489                 ExecInsertIndexTuples(slot, &(tuple->t_self), estate, false);
1490
1491         /* AFTER ROW UPDATE Triggers */
1492         ExecARUpdateTriggers(estate, resultRelInfo, tupleid, tuple);
1493 }
1494
1495 static char *
1496 ExecRelCheck(ResultRelInfo *resultRelInfo,
1497                          TupleTableSlot *slot, EState *estate)
1498 {
1499         Relation        rel = resultRelInfo->ri_RelationDesc;
1500         int                     ncheck = rel->rd_att->constr->num_check;
1501         ConstrCheck *check = rel->rd_att->constr->check;
1502         ExprContext *econtext;
1503         MemoryContext oldContext;
1504         List       *qual;
1505         int                     i;
1506
1507         /*
1508          * If first time through for this result relation, build expression
1509          * nodetrees for rel's constraint expressions.  Keep them in the
1510          * per-query memory context so they'll survive throughout the query.
1511          */
1512         if (resultRelInfo->ri_ConstraintExprs == NULL)
1513         {
1514                 oldContext = MemoryContextSwitchTo(estate->es_query_cxt);
1515                 resultRelInfo->ri_ConstraintExprs =
1516                         (List **) palloc(ncheck * sizeof(List *));
1517                 for (i = 0; i < ncheck; i++)
1518                 {
1519                         qual = (List *) stringToNode(check[i].ccbin);
1520                         resultRelInfo->ri_ConstraintExprs[i] = (List *)
1521                                 ExecPrepareExpr((Expr *) qual, estate);
1522                 }
1523                 MemoryContextSwitchTo(oldContext);
1524         }
1525
1526         /*
1527          * We will use the EState's per-tuple context for evaluating
1528          * constraint expressions (creating it if it's not already there).
1529          */
1530         econtext = GetPerTupleExprContext(estate);
1531
1532         /* Arrange for econtext's scan tuple to be the tuple under test */
1533         econtext->ecxt_scantuple = slot;
1534
1535         /* And evaluate the constraints */
1536         for (i = 0; i < ncheck; i++)
1537         {
1538                 qual = resultRelInfo->ri_ConstraintExprs[i];
1539
1540                 /*
1541                  * NOTE: SQL92 specifies that a NULL result from a constraint
1542                  * expression is not to be treated as a failure.  Therefore, tell
1543                  * ExecQual to return TRUE for NULL.
1544                  */
1545                 if (!ExecQual(qual, econtext, true))
1546                         return check[i].ccname;
1547         }
1548
1549         /* NULL result means no error */
1550         return (char *) NULL;
1551 }
1552
1553 void
1554 ExecConstraints(const char *caller, ResultRelInfo *resultRelInfo,
1555                                 TupleTableSlot *slot, EState *estate)
1556 {
1557         Relation        rel = resultRelInfo->ri_RelationDesc;
1558         HeapTuple       tuple = slot->val;
1559         TupleConstr *constr = rel->rd_att->constr;
1560
1561         Assert(constr);
1562
1563         if (constr->has_not_null)
1564         {
1565                 int                     natts = rel->rd_att->natts;
1566                 int                     attrChk;
1567
1568                 for (attrChk = 1; attrChk <= natts; attrChk++)
1569                 {
1570                         if (rel->rd_att->attrs[attrChk - 1]->attnotnull &&
1571                                 heap_attisnull(tuple, attrChk))
1572                                 elog(ERROR, "%s: Fail to add null value in not null attribute %s",
1573                                          caller, NameStr(rel->rd_att->attrs[attrChk - 1]->attname));
1574                 }
1575         }
1576
1577         if (constr->num_check > 0)
1578         {
1579                 char       *failed;
1580
1581                 if ((failed = ExecRelCheck(resultRelInfo, slot, estate)) != NULL)
1582                         elog(ERROR, "%s: rejected due to CHECK constraint \"%s\" on \"%s\"",
1583                                  caller, failed, RelationGetRelationName(rel));
1584         }
1585 }
1586
1587 /*
1588  * Check a modified tuple to see if we want to process its updated version
1589  * under READ COMMITTED rules.
1590  *
1591  * See backend/executor/README for some info about how this works.
1592  */
1593 TupleTableSlot *
1594 EvalPlanQual(EState *estate, Index rti, ItemPointer tid)
1595 {
1596         evalPlanQual *epq;
1597         EState     *epqstate;
1598         Relation        relation;
1599         HeapTupleData tuple;
1600         HeapTuple       copyTuple = NULL;
1601         bool            endNode;
1602
1603         Assert(rti != 0);
1604
1605         /*
1606          * find relation containing target tuple
1607          */
1608         if (estate->es_result_relation_info != NULL &&
1609                 estate->es_result_relation_info->ri_RangeTableIndex == rti)
1610                 relation = estate->es_result_relation_info->ri_RelationDesc;
1611         else
1612         {
1613                 List       *l;
1614
1615                 relation = NULL;
1616                 foreach(l, estate->es_rowMark)
1617                 {
1618                         if (((execRowMark *) lfirst(l))->rti == rti)
1619                         {
1620                                 relation = ((execRowMark *) lfirst(l))->relation;
1621                                 break;
1622                         }
1623                 }
1624                 if (relation == NULL)
1625                         elog(ERROR, "EvalPlanQual: can't find RTE %d", (int) rti);
1626         }
1627
1628         /*
1629          * fetch tid tuple
1630          *
1631          * Loop here to deal with updated or busy tuples
1632          */
1633         tuple.t_self = *tid;
1634         for (;;)
1635         {
1636                 Buffer          buffer;
1637
1638                 if (heap_fetch(relation, SnapshotDirty, &tuple, &buffer, false, NULL))
1639                 {
1640                         TransactionId xwait = SnapshotDirty->xmax;
1641
1642                         if (TransactionIdIsValid(SnapshotDirty->xmin))
1643                                 elog(ERROR, "EvalPlanQual: t_xmin is uncommitted ?!");
1644
1645                         /*
1646                          * If tuple is being updated by other transaction then we have
1647                          * to wait for its commit/abort.
1648                          */
1649                         if (TransactionIdIsValid(xwait))
1650                         {
1651                                 ReleaseBuffer(buffer);
1652                                 XactLockTableWait(xwait);
1653                                 continue;
1654                         }
1655
1656                         /*
1657                          * We got tuple - now copy it for use by recheck query.
1658                          */
1659                         copyTuple = heap_copytuple(&tuple);
1660                         ReleaseBuffer(buffer);
1661                         break;
1662                 }
1663
1664                 /*
1665                  * Oops! Invalid tuple. Have to check is it updated or deleted.
1666                  * Note that it's possible to get invalid SnapshotDirty->tid if
1667                  * tuple updated by this transaction. Have we to check this ?
1668                  */
1669                 if (ItemPointerIsValid(&(SnapshotDirty->tid)) &&
1670                         !(ItemPointerEquals(&(tuple.t_self), &(SnapshotDirty->tid))))
1671                 {
1672                         /* updated, so look at the updated copy */
1673                         tuple.t_self = SnapshotDirty->tid;
1674                         continue;
1675                 }
1676
1677                 /*
1678                  * Deleted or updated by this transaction; forget it.
1679                  */
1680                 return NULL;
1681         }
1682
1683         /*
1684          * For UPDATE/DELETE we have to return tid of actual row we're
1685          * executing PQ for.
1686          */
1687         *tid = tuple.t_self;
1688
1689         /*
1690          * Need to run a recheck subquery.      Find or create a PQ stack entry.
1691          */
1692         epq = estate->es_evalPlanQual;
1693         endNode = true;
1694
1695         if (epq != NULL && epq->rti == 0)
1696         {
1697                 /* Top PQ stack entry is idle, so re-use it */
1698                 Assert(!(estate->es_useEvalPlan) && epq->next == NULL);
1699                 epq->rti = rti;
1700                 endNode = false;
1701         }
1702
1703         /*
1704          * If this is request for another RTE - Ra, - then we have to check
1705          * wasn't PlanQual requested for Ra already and if so then Ra' row was
1706          * updated again and we have to re-start old execution for Ra and
1707          * forget all what we done after Ra was suspended. Cool? -:))
1708          */
1709         if (epq != NULL && epq->rti != rti &&
1710                 epq->estate->es_evTuple[rti - 1] != NULL)
1711         {
1712                 do
1713                 {
1714                         evalPlanQual *oldepq;
1715
1716                         /* stop execution */
1717                         EvalPlanQualStop(epq);
1718                         /* pop previous PlanQual from the stack */
1719                         oldepq = epq->next;
1720                         Assert(oldepq && oldepq->rti != 0);
1721                         /* push current PQ to freePQ stack */
1722                         oldepq->free = epq;
1723                         epq = oldepq;
1724                         estate->es_evalPlanQual = epq;
1725                 } while (epq->rti != rti);
1726         }
1727
1728         /*
1729          * If we are requested for another RTE then we have to suspend
1730          * execution of current PlanQual and start execution for new one.
1731          */
1732         if (epq == NULL || epq->rti != rti)
1733         {
1734                 /* try to reuse plan used previously */
1735                 evalPlanQual *newepq = (epq != NULL) ? epq->free : NULL;
1736
1737                 if (newepq == NULL)             /* first call or freePQ stack is empty */
1738                 {
1739                         newepq = (evalPlanQual *) palloc0(sizeof(evalPlanQual));
1740                         newepq->free = NULL;
1741                         newepq->estate = NULL;
1742                         newepq->planstate = NULL;
1743                 }
1744                 else
1745                 {
1746                         /* recycle previously used PlanQual */
1747                         Assert(newepq->estate == NULL);
1748                         epq->free = NULL;
1749                 }
1750                 /* push current PQ to the stack */
1751                 newepq->next = epq;
1752                 epq = newepq;
1753                 estate->es_evalPlanQual = epq;
1754                 epq->rti = rti;
1755                 endNode = false;
1756         }
1757
1758         Assert(epq->rti == rti);
1759
1760         /*
1761          * Ok - we're requested for the same RTE.  Unfortunately we still have
1762          * to end and restart execution of the plan, because ExecReScan
1763          * wouldn't ensure that upper plan nodes would reset themselves.  We
1764          * could make that work if insertion of the target tuple were
1765          * integrated with the Param mechanism somehow, so that the upper plan
1766          * nodes know that their children's outputs have changed.
1767          *
1768          * Note that the stack of free evalPlanQual nodes is quite useless at
1769          * the moment, since it only saves us from pallocing/releasing the
1770          * evalPlanQual nodes themselves.  But it will be useful once we
1771          * implement ReScan instead of end/restart for re-using PlanQual nodes.
1772          */
1773         if (endNode)
1774         {
1775                 /* stop execution */
1776                 EvalPlanQualStop(epq);
1777         }
1778
1779         /*
1780          * Initialize new recheck query.
1781          *
1782          * Note: if we were re-using PlanQual plans via ExecReScan, we'd need
1783          * to instead copy down changeable state from the top plan (including
1784          * es_result_relation_info, es_junkFilter) and reset locally changeable
1785          * state in the epq (including es_param_exec_vals, es_evTupleNull).
1786          */
1787         EvalPlanQualStart(epq, estate, epq->next);
1788
1789         /*
1790          * free old RTE' tuple, if any, and store target tuple where
1791          * relation's scan node will see it
1792          */
1793         epqstate = epq->estate;
1794         if (epqstate->es_evTuple[rti - 1] != NULL)
1795                 heap_freetuple(epqstate->es_evTuple[rti - 1]);
1796         epqstate->es_evTuple[rti - 1] = copyTuple;
1797
1798         return EvalPlanQualNext(estate);
1799 }
1800
1801 static TupleTableSlot *
1802 EvalPlanQualNext(EState *estate)
1803 {
1804         evalPlanQual *epq = estate->es_evalPlanQual;
1805         MemoryContext oldcontext;
1806         TupleTableSlot *slot;
1807
1808         Assert(epq->rti != 0);
1809
1810 lpqnext:;
1811         oldcontext = MemoryContextSwitchTo(epq->estate->es_query_cxt);
1812         slot = ExecProcNode(epq->planstate);
1813         MemoryContextSwitchTo(oldcontext);
1814
1815         /*
1816          * No more tuples for this PQ. Continue previous one.
1817          */
1818         if (TupIsNull(slot))
1819         {
1820                 evalPlanQual *oldepq;
1821
1822                 /* stop execution */
1823                 EvalPlanQualStop(epq);
1824                 /* pop old PQ from the stack */
1825                 oldepq = epq->next;
1826                 if (oldepq == NULL)
1827                 {
1828                         /* this is the first (oldest) PQ - mark as free */
1829                         epq->rti = 0;
1830                         estate->es_useEvalPlan = false;
1831                         /* and continue Query execution */
1832                         return (NULL);
1833                 }
1834                 Assert(oldepq->rti != 0);
1835                 /* push current PQ to freePQ stack */
1836                 oldepq->free = epq;
1837                 epq = oldepq;
1838                 estate->es_evalPlanQual = epq;
1839                 goto lpqnext;
1840         }
1841
1842         return (slot);
1843 }
1844
1845 static void
1846 EndEvalPlanQual(EState *estate)
1847 {
1848         evalPlanQual *epq = estate->es_evalPlanQual;
1849
1850         if (epq->rti == 0)                      /* plans already shutdowned */
1851         {
1852                 Assert(epq->next == NULL);
1853                 return;
1854         }
1855
1856         for (;;)
1857         {
1858                 evalPlanQual *oldepq;
1859
1860                 /* stop execution */
1861                 EvalPlanQualStop(epq);
1862                 /* pop old PQ from the stack */
1863                 oldepq = epq->next;
1864                 if (oldepq == NULL)
1865                 {
1866                         /* this is the first (oldest) PQ - mark as free */
1867                         epq->rti = 0;
1868                         estate->es_useEvalPlan = false;
1869                         break;
1870                 }
1871                 Assert(oldepq->rti != 0);
1872                 /* push current PQ to freePQ stack */
1873                 oldepq->free = epq;
1874                 epq = oldepq;
1875                 estate->es_evalPlanQual = epq;
1876         }
1877 }
1878
1879 /*
1880  * Start execution of one level of PlanQual.
1881  *
1882  * This is a cut-down version of ExecutorStart(): we copy some state from
1883  * the top-level estate rather than initializing it fresh.
1884  */
1885 static void
1886 EvalPlanQualStart(evalPlanQual *epq, EState *estate, evalPlanQual *priorepq)
1887 {
1888         EState     *epqstate;
1889         int                     rtsize;
1890         MemoryContext oldcontext;
1891
1892         rtsize = length(estate->es_range_table);
1893
1894         epq->estate = epqstate = CreateExecutorState();
1895
1896         oldcontext = MemoryContextSwitchTo(epqstate->es_query_cxt);
1897
1898         /*
1899          * The epqstates share the top query's copy of unchanging state such
1900          * as the snapshot, rangetable, result-rel info, and external Param info.
1901          * They need their own copies of local state, including a tuple table,
1902          * es_param_exec_vals, etc.
1903          */
1904         epqstate->es_direction = ForwardScanDirection;
1905         epqstate->es_snapshot = estate->es_snapshot;
1906         epqstate->es_range_table = estate->es_range_table;
1907         epqstate->es_result_relations = estate->es_result_relations;
1908         epqstate->es_num_result_relations = estate->es_num_result_relations;
1909         epqstate->es_result_relation_info = estate->es_result_relation_info;
1910         epqstate->es_junkFilter = estate->es_junkFilter;
1911         epqstate->es_into_relation_descriptor = estate->es_into_relation_descriptor;
1912         epqstate->es_param_list_info = estate->es_param_list_info;
1913         if (estate->es_topPlan->nParamExec > 0)
1914                 epqstate->es_param_exec_vals = (ParamExecData *)
1915                         palloc0(estate->es_topPlan->nParamExec * sizeof(ParamExecData));
1916         epqstate->es_rowMark = estate->es_rowMark;
1917         epqstate->es_instrument = estate->es_instrument;
1918         epqstate->es_topPlan = estate->es_topPlan;
1919         /*
1920          * Each epqstate must have its own es_evTupleNull state, but
1921          * all the stack entries share es_evTuple state.  This allows
1922          * sub-rechecks to inherit the value being examined by an
1923          * outer recheck.
1924          */
1925         epqstate->es_evTupleNull = (bool *) palloc0(rtsize * sizeof(bool));
1926         if (priorepq == NULL)
1927                 /* first PQ stack entry */
1928                 epqstate->es_evTuple = (HeapTuple *)
1929                         palloc0(rtsize * sizeof(HeapTuple));
1930         else
1931                 /* later stack entries share the same storage */
1932                 epqstate->es_evTuple = priorepq->estate->es_evTuple;
1933
1934         epqstate->es_tupleTable =
1935                 ExecCreateTupleTable(estate->es_tupleTable->size);
1936
1937         epq->planstate = ExecInitNode(estate->es_topPlan, epqstate);
1938
1939         MemoryContextSwitchTo(oldcontext);
1940 }
1941
1942 /*
1943  * End execution of one level of PlanQual.
1944  *
1945  * This is a cut-down version of ExecutorEnd(); basically we want to do most
1946  * of the normal cleanup, but *not* close result relations (which we are
1947  * just sharing from the outer query).
1948  */
1949 static void
1950 EvalPlanQualStop(evalPlanQual *epq)
1951 {
1952         EState     *epqstate = epq->estate;
1953         MemoryContext oldcontext;
1954
1955         oldcontext = MemoryContextSwitchTo(epqstate->es_query_cxt);
1956
1957         ExecEndNode(epq->planstate);
1958
1959         ExecDropTupleTable(epqstate->es_tupleTable, true);
1960         epqstate->es_tupleTable = NULL;
1961
1962         if (epqstate->es_evTuple[epq->rti - 1] != NULL)
1963         {
1964                 heap_freetuple(epqstate->es_evTuple[epq->rti - 1]);
1965                 epqstate->es_evTuple[epq->rti - 1] = NULL;
1966         }
1967
1968         MemoryContextSwitchTo(oldcontext);
1969
1970         FreeExecutorState(epqstate);
1971
1972         epq->estate = NULL;
1973         epq->planstate = NULL;
1974 }