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