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