]> granicus.if.org Git - postgresql/blob - src/backend/executor/execUtils.c
Renumber SnapshotNow and the other special snapshot codes so that
[postgresql] / src / backend / executor / execUtils.c
1 /*-------------------------------------------------------------------------
2  *
3  * execUtils.c
4  *        miscellaneous executor utility routines
5  *
6  * Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        $PostgreSQL: pgsql/src/backend/executor/execUtils.c,v 1.115 2004/09/11 18:28:34 tgl Exp $
12  *
13  *-------------------------------------------------------------------------
14  */
15 /*
16  * INTERFACE ROUTINES
17  *              CreateExecutorState             Create/delete executor working state
18  *              FreeExecutorState
19  *              CreateExprContext
20  *              FreeExprContext
21  *              ReScanExprContext
22  *
23  *              ExecAssignExprContext   Common code for plan node init routines.
24  *              ExecAssignResultType
25  *              etc
26  *
27  *              ExecOpenIndices                 \
28  *              ExecCloseIndices                 | referenced by InitPlan, EndPlan,
29  *              ExecInsertIndexTuples   /  ExecInsert, ExecUpdate
30  *
31  *              RegisterExprContextCallback    Register function shutdown callback
32  *              UnregisterExprContextCallback  Deregister function shutdown callback
33  *
34  *       NOTES
35  *              This file has traditionally been the place to stick misc.
36  *              executor support stuff that doesn't really go anyplace else.
37  */
38
39 #include "postgres.h"
40
41 #include "access/genam.h"
42 #include "access/heapam.h"
43 #include "catalog/catname.h"
44 #include "catalog/index.h"
45 #include "catalog/catalog.h"
46 #include "catalog/pg_index.h"
47 #include "executor/execdebug.h"
48 #include "miscadmin.h"
49 #include "utils/builtins.h"
50 #include "utils/fmgroids.h"
51 #include "utils/memutils.h"
52 #include "utils/relcache.h"
53 #include "utils/syscache.h"
54
55
56 /* ----------------------------------------------------------------
57  *              global counters for number of tuples processed, retrieved,
58  *              appended, replaced, deleted.
59  * ----------------------------------------------------------------
60  */
61 int                     NTupleProcessed;
62 int                     NTupleRetrieved;
63 int                     NTupleReplaced;
64 int                     NTupleAppended;
65 int                     NTupleDeleted;
66 int                     NIndexTupleInserted;
67 extern int      NIndexTupleProcessed;           /* have to be defined in the
68                                                                                  * access method level so that the
69                                                                                  * cinterface.a will link ok. */
70
71
72 static void ShutdownExprContext(ExprContext *econtext);
73
74
75 /* ----------------------------------------------------------------
76  *                                              statistic functions
77  * ----------------------------------------------------------------
78  */
79
80 /* ----------------------------------------------------------------
81  *              ResetTupleCount
82  * ----------------------------------------------------------------
83  */
84 #ifdef NOT_USED
85 void
86 ResetTupleCount(void)
87 {
88         NTupleProcessed = 0;
89         NTupleRetrieved = 0;
90         NTupleAppended = 0;
91         NTupleDeleted = 0;
92         NTupleReplaced = 0;
93         NIndexTupleProcessed = 0;
94 }
95 #endif
96
97 /* ----------------------------------------------------------------
98  *              PrintTupleCount
99  * ----------------------------------------------------------------
100  */
101 #ifdef NOT_USED
102 void
103 DisplayTupleCount(FILE *statfp)
104 {
105         if (NTupleProcessed > 0)
106                 fprintf(statfp, "!\t%d tuple%s processed, ", NTupleProcessed,
107                                 (NTupleProcessed == 1) ? "" : "s");
108         else
109         {
110                 fprintf(statfp, "!\tno tuples processed.\n");
111                 return;
112         }
113         if (NIndexTupleProcessed > 0)
114                 fprintf(statfp, "%d indextuple%s processed, ", NIndexTupleProcessed,
115                                 (NIndexTupleProcessed == 1) ? "" : "s");
116         if (NIndexTupleInserted > 0)
117                 fprintf(statfp, "%d indextuple%s inserted, ", NIndexTupleInserted,
118                                 (NIndexTupleInserted == 1) ? "" : "s");
119         if (NTupleRetrieved > 0)
120                 fprintf(statfp, "%d tuple%s retrieved. ", NTupleRetrieved,
121                                 (NTupleRetrieved == 1) ? "" : "s");
122         if (NTupleAppended > 0)
123                 fprintf(statfp, "%d tuple%s appended. ", NTupleAppended,
124                                 (NTupleAppended == 1) ? "" : "s");
125         if (NTupleDeleted > 0)
126                 fprintf(statfp, "%d tuple%s deleted. ", NTupleDeleted,
127                                 (NTupleDeleted == 1) ? "" : "s");
128         if (NTupleReplaced > 0)
129                 fprintf(statfp, "%d tuple%s replaced. ", NTupleReplaced,
130                                 (NTupleReplaced == 1) ? "" : "s");
131         fprintf(statfp, "\n");
132 }
133 #endif
134
135
136 /* ----------------------------------------------------------------
137  *                               Executor state and memory management functions
138  * ----------------------------------------------------------------
139  */
140
141 /* ----------------
142  *              CreateExecutorState
143  *
144  *              Create and initialize an EState node, which is the root of
145  *              working storage for an entire Executor invocation.
146  *
147  * Principally, this creates the per-query memory context that will be
148  * used to hold all working data that lives till the end of the query.
149  * Note that the per-query context will become a child of the caller's
150  * CurrentMemoryContext.
151  * ----------------
152  */
153 EState *
154 CreateExecutorState(void)
155 {
156         EState     *estate;
157         MemoryContext qcontext;
158         MemoryContext oldcontext;
159
160         /*
161          * Create the per-query context for this Executor run.
162          */
163         qcontext = AllocSetContextCreate(CurrentMemoryContext,
164                                                                          "ExecutorState",
165                                                                          ALLOCSET_DEFAULT_MINSIZE,
166                                                                          ALLOCSET_DEFAULT_INITSIZE,
167                                                                          ALLOCSET_DEFAULT_MAXSIZE);
168
169         /*
170          * Make the EState node within the per-query context.  This way, we
171          * don't need a separate pfree() operation for it at shutdown.
172          */
173         oldcontext = MemoryContextSwitchTo(qcontext);
174
175         estate = makeNode(EState);
176
177         /*
178          * Initialize all fields of the Executor State structure
179          */
180         estate->es_direction = ForwardScanDirection;
181         estate->es_snapshot = SnapshotNow;
182         estate->es_crosscheck_snapshot = InvalidSnapshot;       /* no crosscheck */
183         estate->es_range_table = NIL;
184
185         estate->es_result_relations = NULL;
186         estate->es_num_result_relations = 0;
187         estate->es_result_relation_info = NULL;
188
189         estate->es_junkFilter = NULL;
190         estate->es_into_relation_descriptor = NULL;
191
192         estate->es_param_list_info = NULL;
193         estate->es_param_exec_vals = NULL;
194
195         estate->es_query_cxt = qcontext;
196
197         estate->es_tupleTable = NULL;
198
199         estate->es_processed = 0;
200         estate->es_lastoid = InvalidOid;
201         estate->es_rowMark = NIL;
202
203         estate->es_instrument = false;
204         estate->es_select_into = false;
205         estate->es_into_oids = false;
206
207         estate->es_exprcontexts = NIL;
208
209         estate->es_per_tuple_exprcontext = NULL;
210
211         estate->es_topPlan = NULL;
212         estate->es_evalPlanQual = NULL;
213         estate->es_evTupleNull = NULL;
214         estate->es_evTuple = NULL;
215         estate->es_useEvalPlan = false;
216
217         /*
218          * Return the executor state structure
219          */
220         MemoryContextSwitchTo(oldcontext);
221
222         return estate;
223 }
224
225 /* ----------------
226  *              FreeExecutorState
227  *
228  *              Release an EState along with all remaining working storage.
229  *
230  * Note: this is not responsible for releasing non-memory resources,
231  * such as open relations or buffer pins.  But it will shut down any
232  * still-active ExprContexts within the EState.  That is sufficient
233  * cleanup for situations where the EState has only been used for expression
234  * evaluation, and not to run a complete Plan.
235  *
236  * This can be called in any memory context ... so long as it's not one
237  * of the ones to be freed.
238  * ----------------
239  */
240 void
241 FreeExecutorState(EState *estate)
242 {
243         /*
244          * Shut down and free any remaining ExprContexts.  We do this
245          * explicitly to ensure that any remaining shutdown callbacks get
246          * called (since they might need to release resources that aren't
247          * simply memory within the per-query memory context).
248          */
249         while (estate->es_exprcontexts)
250         {
251                 /*
252                  * XXX: seems there ought to be a faster way to implement this
253                  * than repeated list_delete(), no?
254                  */
255                 FreeExprContext((ExprContext *) linitial(estate->es_exprcontexts));
256                 /* FreeExprContext removed the list link for us */
257         }
258
259         /*
260          * Free the per-query memory context, thereby releasing all working
261          * memory, including the EState node itself.
262          */
263         MemoryContextDelete(estate->es_query_cxt);
264 }
265
266 /* ----------------
267  *              CreateExprContext
268  *
269  *              Create a context for expression evaluation within an EState.
270  *
271  * An executor run may require multiple ExprContexts (we usually make one
272  * for each Plan node, and a separate one for per-output-tuple processing
273  * such as constraint checking).  Each ExprContext has its own "per-tuple"
274  * memory context.
275  *
276  * Note we make no assumption about the caller's memory context.
277  * ----------------
278  */
279 ExprContext *
280 CreateExprContext(EState *estate)
281 {
282         ExprContext *econtext;
283         MemoryContext oldcontext;
284
285         /* Create the ExprContext node within the per-query memory context */
286         oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
287
288         econtext = makeNode(ExprContext);
289
290         /* Initialize fields of ExprContext */
291         econtext->ecxt_scantuple = NULL;
292         econtext->ecxt_innertuple = NULL;
293         econtext->ecxt_outertuple = NULL;
294
295         econtext->ecxt_per_query_memory = estate->es_query_cxt;
296
297         /*
298          * Create working memory for expression evaluation in this context.
299          */
300         econtext->ecxt_per_tuple_memory =
301                 AllocSetContextCreate(estate->es_query_cxt,
302                                                           "ExprContext",
303                                                           ALLOCSET_DEFAULT_MINSIZE,
304                                                           ALLOCSET_DEFAULT_INITSIZE,
305                                                           ALLOCSET_DEFAULT_MAXSIZE);
306
307         econtext->ecxt_param_exec_vals = estate->es_param_exec_vals;
308         econtext->ecxt_param_list_info = estate->es_param_list_info;
309
310         econtext->ecxt_aggvalues = NULL;
311         econtext->ecxt_aggnulls = NULL;
312
313         econtext->caseValue_datum = (Datum) 0;
314         econtext->caseValue_isNull = true;
315
316         econtext->domainValue_datum = (Datum) 0;
317         econtext->domainValue_isNull = true;
318
319         econtext->ecxt_estate = estate;
320
321         econtext->ecxt_callbacks = NULL;
322
323         /*
324          * Link the ExprContext into the EState to ensure it is shut down when
325          * the EState is freed.  Because we use lcons(), shutdowns will occur
326          * in reverse order of creation, which may not be essential but can't
327          * hurt.
328          */
329         estate->es_exprcontexts = lcons(econtext, estate->es_exprcontexts);
330
331         MemoryContextSwitchTo(oldcontext);
332
333         return econtext;
334 }
335
336 /* ----------------
337  *              FreeExprContext
338  *
339  *              Free an expression context, including calling any remaining
340  *              shutdown callbacks.
341  *
342  * Since we free the temporary context used for expression evaluation,
343  * any previously computed pass-by-reference expression result will go away!
344  *
345  * Note we make no assumption about the caller's memory context.
346  * ----------------
347  */
348 void
349 FreeExprContext(ExprContext *econtext)
350 {
351         EState     *estate;
352
353         /* Call any registered callbacks */
354         ShutdownExprContext(econtext);
355         /* And clean up the memory used */
356         MemoryContextDelete(econtext->ecxt_per_tuple_memory);
357         /* Unlink self from owning EState */
358         estate = econtext->ecxt_estate;
359         estate->es_exprcontexts = list_delete_ptr(estate->es_exprcontexts, econtext);
360         /* And delete the ExprContext node */
361         pfree(econtext);
362 }
363
364 /*
365  * ReScanExprContext
366  *
367  *              Reset an expression context in preparation for a rescan of its
368  *              plan node.      This requires calling any registered shutdown callbacks,
369  *              since any partially complete set-returning-functions must be canceled.
370  *
371  * Note we make no assumption about the caller's memory context.
372  */
373 void
374 ReScanExprContext(ExprContext *econtext)
375 {
376         /* Call any registered callbacks */
377         ShutdownExprContext(econtext);
378         /* And clean up the memory used */
379         MemoryContextReset(econtext->ecxt_per_tuple_memory);
380 }
381
382 /*
383  * Build a per-output-tuple ExprContext for an EState.
384  *
385  * This is normally invoked via GetPerTupleExprContext() macro,
386  * not directly.
387  */
388 ExprContext *
389 MakePerTupleExprContext(EState *estate)
390 {
391         if (estate->es_per_tuple_exprcontext == NULL)
392                 estate->es_per_tuple_exprcontext = CreateExprContext(estate);
393
394         return estate->es_per_tuple_exprcontext;
395 }
396
397
398 /* ----------------------------------------------------------------
399  *                               miscellaneous node-init support functions
400  *
401  * Note: all of these are expected to be called with CurrentMemoryContext
402  * equal to the per-query memory context.
403  * ----------------------------------------------------------------
404  */
405
406 /* ----------------
407  *              ExecAssignExprContext
408  *
409  *              This initializes the ps_ExprContext field.      It is only necessary
410  *              to do this for nodes which use ExecQual or ExecProject
411  *              because those routines require an econtext. Other nodes that
412  *              don't have to evaluate expressions don't need to do this.
413  * ----------------
414  */
415 void
416 ExecAssignExprContext(EState *estate, PlanState *planstate)
417 {
418         planstate->ps_ExprContext = CreateExprContext(estate);
419 }
420
421 /* ----------------
422  *              ExecAssignResultType
423  * ----------------
424  */
425 void
426 ExecAssignResultType(PlanState *planstate,
427                                          TupleDesc tupDesc, bool shouldFree)
428 {
429         TupleTableSlot *slot = planstate->ps_ResultTupleSlot;
430
431         ExecSetSlotDescriptor(slot, tupDesc, shouldFree);
432 }
433
434 /* ----------------
435  *              ExecAssignResultTypeFromOuterPlan
436  * ----------------
437  */
438 void
439 ExecAssignResultTypeFromOuterPlan(PlanState *planstate)
440 {
441         PlanState  *outerPlan;
442         TupleDesc       tupDesc;
443
444         outerPlan = outerPlanState(planstate);
445         tupDesc = ExecGetResultType(outerPlan);
446
447         ExecAssignResultType(planstate, tupDesc, false);
448 }
449
450 /* ----------------
451  *              ExecAssignResultTypeFromTL
452  * ----------------
453  */
454 void
455 ExecAssignResultTypeFromTL(PlanState *planstate)
456 {
457         bool            hasoid;
458         TupleDesc       tupDesc;
459
460         if (ExecContextForcesOids(planstate, &hasoid))
461         {
462                 /* context forces OID choice; hasoid is now set correctly */
463         }
464         else
465         {
466                 /* given free choice, don't leave space for OIDs in result tuples */
467                 hasoid = false;
468         }
469
470         /*
471          * ExecTypeFromTL needs the parse-time representation of the tlist,
472          * not a list of ExprStates.  This is good because some plan nodes
473          * don't bother to set up planstate->targetlist ...
474          */
475         tupDesc = ExecTypeFromTL(planstate->plan->targetlist, hasoid);
476         ExecAssignResultType(planstate, tupDesc, true);
477 }
478
479 /* ----------------
480  *              ExecGetResultType
481  * ----------------
482  */
483 TupleDesc
484 ExecGetResultType(PlanState *planstate)
485 {
486         TupleTableSlot *slot = planstate->ps_ResultTupleSlot;
487
488         return slot->ttc_tupleDescriptor;
489 }
490
491 /* ----------------
492  *              ExecBuildProjectionInfo
493  *
494  * Build a ProjectionInfo node for evaluating the given tlist in the given
495  * econtext, and storing the result into the tuple slot.  (Caller must have
496  * ensured that tuple slot has a descriptor matching the tlist!)  Note that
497  * the given tlist should be a list of ExprState nodes, not Expr nodes.
498  * ----------------
499  */
500 ProjectionInfo *
501 ExecBuildProjectionInfo(List *targetList,
502                                                 ExprContext *econtext,
503                                                 TupleTableSlot *slot)
504 {
505         ProjectionInfo *projInfo = makeNode(ProjectionInfo);
506         int                     len;
507
508         len = ExecTargetListLength(targetList);
509
510         projInfo->pi_targetlist = targetList;
511         projInfo->pi_exprContext = econtext;
512         projInfo->pi_slot = slot;
513         if (len > 0)
514         {
515                 projInfo->pi_tupValues = (Datum *) palloc(len * sizeof(Datum));
516                 projInfo->pi_tupNulls = (char *) palloc(len * sizeof(char));
517                 projInfo->pi_itemIsDone = (ExprDoneCond *) palloc(len * sizeof(ExprDoneCond));
518         }
519
520         return projInfo;
521 }
522
523 /* ----------------
524  *              ExecAssignProjectionInfo
525  *
526  * forms the projection information from the node's targetlist
527  * ----------------
528  */
529 void
530 ExecAssignProjectionInfo(PlanState *planstate)
531 {
532         planstate->ps_ProjInfo =
533                 ExecBuildProjectionInfo(planstate->targetlist,
534                                                                 planstate->ps_ExprContext,
535                                                                 planstate->ps_ResultTupleSlot);
536 }
537
538
539 /* ----------------
540  *              ExecFreeExprContext
541  *
542  * A plan node's ExprContext should be freed explicitly during ExecEndNode
543  * because there may be shutdown callbacks to call.  (Other resources made
544  * by the above routines, such as projection info, don't need to be freed
545  * explicitly because they're just memory in the per-query memory context.)
546  * ----------------
547  */
548 void
549 ExecFreeExprContext(PlanState *planstate)
550 {
551         ExprContext *econtext;
552
553         /*
554          * get expression context.      if NULL then this node has none so we just
555          * return.
556          */
557         econtext = planstate->ps_ExprContext;
558         if (econtext == NULL)
559                 return;
560
561         FreeExprContext(econtext);
562
563         planstate->ps_ExprContext = NULL;
564 }
565
566 /* ----------------------------------------------------------------
567  *              the following scan type support functions are for
568  *              those nodes which are stubborn and return tuples in
569  *              their Scan tuple slot instead of their Result tuple
570  *              slot..  luck fur us, these nodes do not do projections
571  *              so we don't have to worry about getting the ProjectionInfo
572  *              right for them...  -cim 6/3/91
573  * ----------------------------------------------------------------
574  */
575
576 /* ----------------
577  *              ExecGetScanType
578  * ----------------
579  */
580 TupleDesc
581 ExecGetScanType(ScanState *scanstate)
582 {
583         TupleTableSlot *slot = scanstate->ss_ScanTupleSlot;
584
585         return slot->ttc_tupleDescriptor;
586 }
587
588 /* ----------------
589  *              ExecAssignScanType
590  * ----------------
591  */
592 void
593 ExecAssignScanType(ScanState *scanstate,
594                                    TupleDesc tupDesc, bool shouldFree)
595 {
596         TupleTableSlot *slot = scanstate->ss_ScanTupleSlot;
597
598         ExecSetSlotDescriptor(slot, tupDesc, shouldFree);
599 }
600
601 /* ----------------
602  *              ExecAssignScanTypeFromOuterPlan
603  * ----------------
604  */
605 void
606 ExecAssignScanTypeFromOuterPlan(ScanState *scanstate)
607 {
608         PlanState  *outerPlan;
609         TupleDesc       tupDesc;
610
611         outerPlan = outerPlanState(scanstate);
612         tupDesc = ExecGetResultType(outerPlan);
613
614         ExecAssignScanType(scanstate, tupDesc, false);
615 }
616
617
618 /* ----------------------------------------------------------------
619  *                                ExecInsertIndexTuples support
620  * ----------------------------------------------------------------
621  */
622
623 /* ----------------------------------------------------------------
624  *              ExecOpenIndices
625  *
626  *              Find the indices associated with a result relation, open them,
627  *              and save information about them in the result ResultRelInfo.
628  *
629  *              At entry, caller has already opened and locked
630  *              resultRelInfo->ri_RelationDesc.
631  *
632  *              This used to be horribly ugly code, and slow too because it
633  *              did a sequential scan of pg_index.      Now we rely on the relcache
634  *              to cache a list of the OIDs of the indices associated with any
635  *              specific relation, and we use the pg_index syscache to get the
636  *              entries we need from pg_index.
637  * ----------------------------------------------------------------
638  */
639 void
640 ExecOpenIndices(ResultRelInfo *resultRelInfo)
641 {
642         Relation        resultRelation = resultRelInfo->ri_RelationDesc;
643         List       *indexoidlist;
644         ListCell   *l;
645         int                     len,
646                                 i;
647         RelationPtr relationDescs;
648         IndexInfo **indexInfoArray;
649
650         resultRelInfo->ri_NumIndices = 0;
651
652         /* fast path if no indexes */
653         if (!RelationGetForm(resultRelation)->relhasindex)
654                 return;
655
656         /*
657          * Get cached list of index OIDs
658          */
659         indexoidlist = RelationGetIndexList(resultRelation);
660         len = list_length(indexoidlist);
661         if (len == 0)
662                 return;
663
664         /*
665          * allocate space for result arrays
666          */
667         relationDescs = (RelationPtr) palloc(len * sizeof(Relation));
668         indexInfoArray = (IndexInfo **) palloc(len * sizeof(IndexInfo *));
669
670         resultRelInfo->ri_NumIndices = len;
671         resultRelInfo->ri_IndexRelationDescs = relationDescs;
672         resultRelInfo->ri_IndexRelationInfo = indexInfoArray;
673
674         /*
675          * For each index, open the index relation and save pg_index info.
676          */
677         i = 0;
678         foreach(l, indexoidlist)
679         {
680                 Oid                     indexOid = lfirst_oid(l);
681                 Relation        indexDesc;
682                 IndexInfo  *ii;
683
684                 /*
685                  * Open (and lock, if necessary) the index relation
686                  *
687                  * If the index AM is not safe for concurrent updates, obtain an
688                  * exclusive lock on the index to lock out other updaters as well
689                  * as readers (index_beginscan places AccessShareLock). We will
690                  * release this lock in ExecCloseIndices.
691                  *
692                  * If the index AM supports concurrent updates, we obtain no lock
693                  * here at all, which is a tad weird, but safe since any critical
694                  * operation on the index (like deleting it) will acquire
695                  * exclusive lock on the parent table.  Perhaps someday we should
696                  * acquire RowExclusiveLock on the index here?
697                  *
698                  * If there are multiple not-concurrent-safe indexes, all backends
699                  * must lock the indexes in the same order or we will get
700                  * deadlocks here during concurrent updates.  This is guaranteed
701                  * by RelationGetIndexList(), which promises to return the index
702                  * list in OID order.
703                  */
704                 indexDesc = index_open(indexOid);
705
706                 if (!indexDesc->rd_am->amconcurrent)
707                         LockRelation(indexDesc, AccessExclusiveLock);
708
709                 /* extract index key information from the index's pg_index info */
710                 ii = BuildIndexInfo(indexDesc);
711
712                 relationDescs[i] = indexDesc;
713                 indexInfoArray[i] = ii;
714                 i++;
715         }
716
717         list_free(indexoidlist);
718 }
719
720 /* ----------------------------------------------------------------
721  *              ExecCloseIndices
722  *
723  *              Close the index relations stored in resultRelInfo
724  * ----------------------------------------------------------------
725  */
726 void
727 ExecCloseIndices(ResultRelInfo *resultRelInfo)
728 {
729         int                     i;
730         int                     numIndices;
731         RelationPtr indexDescs;
732
733         numIndices = resultRelInfo->ri_NumIndices;
734         indexDescs = resultRelInfo->ri_IndexRelationDescs;
735
736         for (i = 0; i < numIndices; i++)
737         {
738                 if (indexDescs[i] == NULL)
739                         continue;
740
741                 /* Drop lock, if one was acquired by ExecOpenIndices */
742                 if (!indexDescs[i]->rd_am->amconcurrent)
743                         UnlockRelation(indexDescs[i], AccessExclusiveLock);
744
745                 index_close(indexDescs[i]);
746         }
747
748         /*
749          * XXX should free indexInfo array here too?  Currently we assume that
750          * such stuff will be cleaned up automatically in FreeExecutorState.
751          */
752 }
753
754 /* ----------------------------------------------------------------
755  *              ExecInsertIndexTuples
756  *
757  *              This routine takes care of inserting index tuples
758  *              into all the relations indexing the result relation
759  *              when a heap tuple is inserted into the result relation.
760  *              Much of this code should be moved into the genam
761  *              stuff as it only exists here because the genam stuff
762  *              doesn't provide the functionality needed by the
763  *              executor.. -cim 9/27/89
764  * ----------------------------------------------------------------
765  */
766 void
767 ExecInsertIndexTuples(TupleTableSlot *slot,
768                                           ItemPointer tupleid,
769                                           EState *estate,
770                                           bool is_vacuum)
771 {
772         HeapTuple       heapTuple;
773         ResultRelInfo *resultRelInfo;
774         int                     i;
775         int                     numIndices;
776         RelationPtr relationDescs;
777         Relation        heapRelation;
778         TupleDesc       heapDescriptor;
779         IndexInfo **indexInfoArray;
780         ExprContext *econtext;
781         Datum           datum[INDEX_MAX_KEYS];
782         char            nullv[INDEX_MAX_KEYS];
783
784         heapTuple = slot->val;
785
786         /*
787          * Get information from the result relation info structure.
788          */
789         resultRelInfo = estate->es_result_relation_info;
790         numIndices = resultRelInfo->ri_NumIndices;
791         relationDescs = resultRelInfo->ri_IndexRelationDescs;
792         indexInfoArray = resultRelInfo->ri_IndexRelationInfo;
793         heapRelation = resultRelInfo->ri_RelationDesc;
794         heapDescriptor = RelationGetDescr(heapRelation);
795
796         /*
797          * We will use the EState's per-tuple context for evaluating
798          * predicates and index expressions (creating it if it's not already
799          * there).
800          */
801         econtext = GetPerTupleExprContext(estate);
802
803         /* Arrange for econtext's scan tuple to be the tuple under test */
804         econtext->ecxt_scantuple = slot;
805
806         /*
807          * for each index, form and insert the index tuple
808          */
809         for (i = 0; i < numIndices; i++)
810         {
811                 IndexInfo  *indexInfo;
812                 InsertIndexResult result;
813
814                 if (relationDescs[i] == NULL)
815                         continue;
816
817                 indexInfo = indexInfoArray[i];
818
819                 /* Check for partial index */
820                 if (indexInfo->ii_Predicate != NIL)
821                 {
822                         List       *predicate;
823
824                         /*
825                          * If predicate state not set up yet, create it (in the
826                          * estate's per-query context)
827                          */
828                         predicate = indexInfo->ii_PredicateState;
829                         if (predicate == NIL)
830                         {
831                                 predicate = (List *)
832                                         ExecPrepareExpr((Expr *) indexInfo->ii_Predicate,
833                                                                         estate);
834                                 indexInfo->ii_PredicateState = predicate;
835                         }
836
837                         /* Skip this index-update if the predicate isn't satisfied */
838                         if (!ExecQual(predicate, econtext, false))
839                                 continue;
840                 }
841
842                 /*
843                  * FormIndexDatum fills in its datum and null parameters with
844                  * attribute information taken from the given heap tuple. It also
845                  * computes any expressions needed.
846                  */
847                 FormIndexDatum(indexInfo,
848                                            heapTuple,
849                                            heapDescriptor,
850                                            estate,
851                                            datum,
852                                            nullv);
853
854                 /*
855                  * The index AM does the rest.  Note we suppress unique-index
856                  * checks if we are being called from VACUUM, since VACUUM may
857                  * need to move dead tuples that have the same keys as live ones.
858                  */
859                 result = index_insert(relationDescs[i], /* index relation */
860                                                           datum,        /* array of heaptuple Datums */
861                                                           nullv,        /* info on nulls */
862                                                           &(heapTuple->t_self),         /* tid of heap tuple */
863                                                           heapRelation,
864                                   relationDescs[i]->rd_index->indisunique && !is_vacuum);
865
866                 /*
867                  * keep track of index inserts for debugging
868                  */
869                 IncrIndexInserted();
870
871                 if (result)
872                         pfree(result);
873         }
874 }
875
876 /*
877  * UpdateChangedParamSet
878  *              Add changed parameters to a plan node's chgParam set
879  */
880 void
881 UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
882 {
883         Bitmapset  *parmset;
884
885         /*
886          * The plan node only depends on params listed in its allParam set.
887          * Don't include anything else into its chgParam set.
888          */
889         parmset = bms_intersect(node->plan->allParam, newchg);
890
891         /*
892          * Keep node->chgParam == NULL if there's not actually any members;
893          * this allows the simplest possible tests in executor node files.
894          */
895         if (!bms_is_empty(parmset))
896                 node->chgParam = bms_join(node->chgParam, parmset);
897         else
898                 bms_free(parmset);
899 }
900
901 /*
902  * Register a shutdown callback in an ExprContext.
903  *
904  * Shutdown callbacks will be called (in reverse order of registration)
905  * when the ExprContext is deleted or rescanned.  This provides a hook
906  * for functions called in the context to do any cleanup needed --- it's
907  * particularly useful for functions returning sets.  Note that the
908  * callback will *not* be called in the event that execution is aborted
909  * by an error.
910  */
911 void
912 RegisterExprContextCallback(ExprContext *econtext,
913                                                         ExprContextCallbackFunction function,
914                                                         Datum arg)
915 {
916         ExprContext_CB *ecxt_callback;
917
918         /* Save the info in appropriate memory context */
919         ecxt_callback = (ExprContext_CB *)
920                 MemoryContextAlloc(econtext->ecxt_per_query_memory,
921                                                    sizeof(ExprContext_CB));
922
923         ecxt_callback->function = function;
924         ecxt_callback->arg = arg;
925
926         /* link to front of list for appropriate execution order */
927         ecxt_callback->next = econtext->ecxt_callbacks;
928         econtext->ecxt_callbacks = ecxt_callback;
929 }
930
931 /*
932  * Deregister a shutdown callback in an ExprContext.
933  *
934  * Any list entries matching the function and arg will be removed.
935  * This can be used if it's no longer necessary to call the callback.
936  */
937 void
938 UnregisterExprContextCallback(ExprContext *econtext,
939                                                           ExprContextCallbackFunction function,
940                                                           Datum arg)
941 {
942         ExprContext_CB **prev_callback;
943         ExprContext_CB *ecxt_callback;
944
945         prev_callback = &econtext->ecxt_callbacks;
946
947         while ((ecxt_callback = *prev_callback) != NULL)
948         {
949                 if (ecxt_callback->function == function && ecxt_callback->arg == arg)
950                 {
951                         *prev_callback = ecxt_callback->next;
952                         pfree(ecxt_callback);
953                 }
954                 else
955                         prev_callback = &ecxt_callback->next;
956         }
957 }
958
959 /*
960  * Call all the shutdown callbacks registered in an ExprContext.
961  *
962  * The callback list is emptied (important in case this is only a rescan
963  * reset, and not deletion of the ExprContext).
964  */
965 static void
966 ShutdownExprContext(ExprContext *econtext)
967 {
968         ExprContext_CB *ecxt_callback;
969         MemoryContext oldcontext;
970
971         /* Fast path in normal case where there's nothing to do. */
972         if (econtext->ecxt_callbacks == NULL)
973                 return;
974
975         /*
976          * Call the callbacks in econtext's per-tuple context.  This ensures
977          * that any memory they might leak will get cleaned up.
978          */
979         oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
980
981         /*
982          * Call each callback function in reverse registration order.
983          */
984         while ((ecxt_callback = econtext->ecxt_callbacks) != NULL)
985         {
986                 econtext->ecxt_callbacks = ecxt_callback->next;
987                 (*ecxt_callback->function) (ecxt_callback->arg);
988                 pfree(ecxt_callback);
989         }
990
991         MemoryContextSwitchTo(oldcontext);
992 }