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