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