Add support for user-defined I/O conversion casts.
[PostgreSQL.git] / src / backend / executor / execUtils.c
blobfc67da5ea0d28043517123ccfb8d3ebb8de1da71
1 /*-------------------------------------------------------------------------
3 * execUtils.c
4 * miscellaneous executor utility routines
6 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
10 * IDENTIFICATION
11 * $PostgreSQL$
13 *-------------------------------------------------------------------------
16 * INTERFACE ROUTINES
17 * CreateExecutorState Create/delete executor working state
18 * FreeExecutorState
19 * CreateExprContext
20 * CreateStandaloneExprContext
21 * FreeExprContext
22 * ReScanExprContext
24 * ExecAssignExprContext Common code for plan node init routines.
25 * ExecAssignResultType
26 * etc
28 * ExecOpenScanRelation Common code for scan node init routines.
29 * ExecCloseScanRelation
31 * ExecOpenIndices \
32 * ExecCloseIndices | referenced by InitPlan, EndPlan,
33 * ExecInsertIndexTuples / ExecInsert, ExecUpdate
35 * RegisterExprContextCallback Register function shutdown callback
36 * UnregisterExprContextCallback Deregister function shutdown callback
38 * NOTES
39 * This file has traditionally been the place to stick misc.
40 * executor support stuff that doesn't really go anyplace else.
43 #include "postgres.h"
45 #include "access/genam.h"
46 #include "access/heapam.h"
47 #include "catalog/index.h"
48 #include "executor/execdebug.h"
49 #include "parser/parsetree.h"
50 #include "utils/memutils.h"
51 #include "utils/relcache.h"
52 #include "utils/tqual.h"
55 /* ----------------------------------------------------------------
56 * global counters for number of tuples processed, retrieved,
57 * appended, replaced, deleted.
58 * ----------------------------------------------------------------
60 int NTupleProcessed;
61 int NTupleRetrieved;
62 int NTupleReplaced;
63 int NTupleAppended;
64 int NTupleDeleted;
65 int NIndexTupleInserted;
66 int NIndexTupleProcessed;
69 static void ShutdownExprContext(ExprContext *econtext);
72 /* ----------------------------------------------------------------
73 * statistic functions
74 * ----------------------------------------------------------------
77 /* ----------------------------------------------------------------
78 * ResetTupleCount
79 * ----------------------------------------------------------------
81 #ifdef NOT_USED
82 void
83 ResetTupleCount(void)
85 NTupleProcessed = 0;
86 NTupleRetrieved = 0;
87 NTupleAppended = 0;
88 NTupleDeleted = 0;
89 NTupleReplaced = 0;
90 NIndexTupleProcessed = 0;
92 #endif
94 /* ----------------------------------------------------------------
95 * PrintTupleCount
96 * ----------------------------------------------------------------
98 #ifdef NOT_USED
99 void
100 DisplayTupleCount(FILE *statfp)
102 if (NTupleProcessed > 0)
103 fprintf(statfp, "!\t%d tuple%s processed, ", NTupleProcessed,
104 (NTupleProcessed == 1) ? "" : "s");
105 else
107 fprintf(statfp, "!\tno tuples processed.\n");
108 return;
110 if (NIndexTupleProcessed > 0)
111 fprintf(statfp, "%d indextuple%s processed, ", NIndexTupleProcessed,
112 (NIndexTupleProcessed == 1) ? "" : "s");
113 if (NIndexTupleInserted > 0)
114 fprintf(statfp, "%d indextuple%s inserted, ", NIndexTupleInserted,
115 (NIndexTupleInserted == 1) ? "" : "s");
116 if (NTupleRetrieved > 0)
117 fprintf(statfp, "%d tuple%s retrieved. ", NTupleRetrieved,
118 (NTupleRetrieved == 1) ? "" : "s");
119 if (NTupleAppended > 0)
120 fprintf(statfp, "%d tuple%s appended. ", NTupleAppended,
121 (NTupleAppended == 1) ? "" : "s");
122 if (NTupleDeleted > 0)
123 fprintf(statfp, "%d tuple%s deleted. ", NTupleDeleted,
124 (NTupleDeleted == 1) ? "" : "s");
125 if (NTupleReplaced > 0)
126 fprintf(statfp, "%d tuple%s replaced. ", NTupleReplaced,
127 (NTupleReplaced == 1) ? "" : "s");
128 fprintf(statfp, "\n");
130 #endif
133 /* ----------------------------------------------------------------
134 * Executor state and memory management functions
135 * ----------------------------------------------------------------
138 /* ----------------
139 * CreateExecutorState
141 * Create and initialize an EState node, which is the root of
142 * working storage for an entire Executor invocation.
144 * Principally, this creates the per-query memory context that will be
145 * used to hold all working data that lives till the end of the query.
146 * Note that the per-query context will become a child of the caller's
147 * CurrentMemoryContext.
148 * ----------------
150 EState *
151 CreateExecutorState(void)
153 EState *estate;
154 MemoryContext qcontext;
155 MemoryContext oldcontext;
158 * Create the per-query context for this Executor run.
160 qcontext = AllocSetContextCreate(CurrentMemoryContext,
161 "ExecutorState",
162 ALLOCSET_DEFAULT_MINSIZE,
163 ALLOCSET_DEFAULT_INITSIZE,
164 ALLOCSET_DEFAULT_MAXSIZE);
167 * Make the EState node within the per-query context. This way, we don't
168 * need a separate pfree() operation for it at shutdown.
170 oldcontext = MemoryContextSwitchTo(qcontext);
172 estate = makeNode(EState);
175 * Initialize all fields of the Executor State structure
177 estate->es_direction = ForwardScanDirection;
178 estate->es_snapshot = SnapshotNow;
179 estate->es_crosscheck_snapshot = InvalidSnapshot; /* no crosscheck */
180 estate->es_range_table = NIL;
182 estate->es_output_cid = (CommandId) 0;
184 estate->es_result_relations = NULL;
185 estate->es_num_result_relations = 0;
186 estate->es_result_relation_info = NULL;
188 estate->es_junkFilter = NULL;
190 estate->es_trig_target_relations = NIL;
191 estate->es_trig_tuple_slot = NULL;
193 estate->es_param_list_info = NULL;
194 estate->es_param_exec_vals = NULL;
196 estate->es_query_cxt = qcontext;
198 estate->es_tupleTable = NULL;
200 estate->es_processed = 0;
201 estate->es_lastoid = InvalidOid;
202 estate->es_rowMarks = NIL;
204 estate->es_instrument = false;
205 estate->es_select_into = false;
206 estate->es_into_oids = false;
208 estate->es_exprcontexts = NIL;
210 estate->es_subplanstates = NIL;
212 estate->es_per_tuple_exprcontext = NULL;
214 estate->es_plannedstmt = NULL;
215 estate->es_evalPlanQual = NULL;
216 estate->es_evTupleNull = NULL;
217 estate->es_evTuple = NULL;
218 estate->es_useEvalPlan = false;
221 * Return the executor state structure
223 MemoryContextSwitchTo(oldcontext);
225 return estate;
228 /* ----------------
229 * FreeExecutorState
231 * Release an EState along with all remaining working storage.
233 * Note: this is not responsible for releasing non-memory resources,
234 * such as open relations or buffer pins. But it will shut down any
235 * still-active ExprContexts within the EState. That is sufficient
236 * cleanup for situations where the EState has only been used for expression
237 * evaluation, and not to run a complete Plan.
239 * This can be called in any memory context ... so long as it's not one
240 * of the ones to be freed.
241 * ----------------
243 void
244 FreeExecutorState(EState *estate)
247 * Shut down and free any remaining ExprContexts. We do this explicitly
248 * to ensure that any remaining shutdown callbacks get called (since they
249 * might need to release resources that aren't simply memory within the
250 * per-query memory context).
252 while (estate->es_exprcontexts)
255 * XXX: seems there ought to be a faster way to implement this than
256 * repeated list_delete(), no?
258 FreeExprContext((ExprContext *) linitial(estate->es_exprcontexts));
259 /* FreeExprContext removed the list link for us */
263 * Free the per-query memory context, thereby releasing all working
264 * memory, including the EState node itself.
266 MemoryContextDelete(estate->es_query_cxt);
269 /* ----------------
270 * CreateExprContext
272 * Create a context for expression evaluation within an EState.
274 * An executor run may require multiple ExprContexts (we usually make one
275 * for each Plan node, and a separate one for per-output-tuple processing
276 * such as constraint checking). Each ExprContext has its own "per-tuple"
277 * memory context.
279 * Note we make no assumption about the caller's memory context.
280 * ----------------
282 ExprContext *
283 CreateExprContext(EState *estate)
285 ExprContext *econtext;
286 MemoryContext oldcontext;
288 /* Create the ExprContext node within the per-query memory context */
289 oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
291 econtext = makeNode(ExprContext);
293 /* Initialize fields of ExprContext */
294 econtext->ecxt_scantuple = NULL;
295 econtext->ecxt_innertuple = NULL;
296 econtext->ecxt_outertuple = NULL;
298 econtext->ecxt_per_query_memory = estate->es_query_cxt;
301 * Create working memory for expression evaluation in this context.
303 econtext->ecxt_per_tuple_memory =
304 AllocSetContextCreate(estate->es_query_cxt,
305 "ExprContext",
306 ALLOCSET_DEFAULT_MINSIZE,
307 ALLOCSET_DEFAULT_INITSIZE,
308 ALLOCSET_DEFAULT_MAXSIZE);
310 econtext->ecxt_param_exec_vals = estate->es_param_exec_vals;
311 econtext->ecxt_param_list_info = estate->es_param_list_info;
313 econtext->ecxt_aggvalues = NULL;
314 econtext->ecxt_aggnulls = NULL;
316 econtext->caseValue_datum = (Datum) 0;
317 econtext->caseValue_isNull = true;
319 econtext->domainValue_datum = (Datum) 0;
320 econtext->domainValue_isNull = true;
322 econtext->ecxt_estate = estate;
324 econtext->ecxt_callbacks = NULL;
327 * Link the ExprContext into the EState to ensure it is shut down when the
328 * EState is freed. Because we use lcons(), shutdowns will occur in
329 * reverse order of creation, which may not be essential but can't hurt.
331 estate->es_exprcontexts = lcons(econtext, estate->es_exprcontexts);
333 MemoryContextSwitchTo(oldcontext);
335 return econtext;
338 /* ----------------
339 * CreateStandaloneExprContext
341 * Create a context for standalone expression evaluation.
343 * An ExprContext made this way can be used for evaluation of expressions
344 * that contain no Params, subplans, or Var references (it might work to
345 * put tuple references into the scantuple field, but it seems unwise).
347 * The ExprContext struct is allocated in the caller's current memory
348 * context, which also becomes its "per query" context.
350 * It is caller's responsibility to free the ExprContext when done,
351 * or at least ensure that any shutdown callbacks have been called
352 * (ReScanExprContext() is suitable). Otherwise, non-memory resources
353 * might be leaked.
354 * ----------------
356 ExprContext *
357 CreateStandaloneExprContext(void)
359 ExprContext *econtext;
361 /* Create the ExprContext node within the caller's memory context */
362 econtext = makeNode(ExprContext);
364 /* Initialize fields of ExprContext */
365 econtext->ecxt_scantuple = NULL;
366 econtext->ecxt_innertuple = NULL;
367 econtext->ecxt_outertuple = NULL;
369 econtext->ecxt_per_query_memory = CurrentMemoryContext;
372 * Create working memory for expression evaluation in this context.
374 econtext->ecxt_per_tuple_memory =
375 AllocSetContextCreate(CurrentMemoryContext,
376 "ExprContext",
377 ALLOCSET_DEFAULT_MINSIZE,
378 ALLOCSET_DEFAULT_INITSIZE,
379 ALLOCSET_DEFAULT_MAXSIZE);
381 econtext->ecxt_param_exec_vals = NULL;
382 econtext->ecxt_param_list_info = NULL;
384 econtext->ecxt_aggvalues = NULL;
385 econtext->ecxt_aggnulls = NULL;
387 econtext->caseValue_datum = (Datum) 0;
388 econtext->caseValue_isNull = true;
390 econtext->domainValue_datum = (Datum) 0;
391 econtext->domainValue_isNull = true;
393 econtext->ecxt_estate = NULL;
395 econtext->ecxt_callbacks = NULL;
397 return econtext;
400 /* ----------------
401 * FreeExprContext
403 * Free an expression context, including calling any remaining
404 * shutdown callbacks.
406 * Since we free the temporary context used for expression evaluation,
407 * any previously computed pass-by-reference expression result will go away!
409 * Note we make no assumption about the caller's memory context.
410 * ----------------
412 void
413 FreeExprContext(ExprContext *econtext)
415 EState *estate;
417 /* Call any registered callbacks */
418 ShutdownExprContext(econtext);
419 /* And clean up the memory used */
420 MemoryContextDelete(econtext->ecxt_per_tuple_memory);
421 /* Unlink self from owning EState, if any */
422 estate = econtext->ecxt_estate;
423 if (estate)
424 estate->es_exprcontexts = list_delete_ptr(estate->es_exprcontexts,
425 econtext);
426 /* And delete the ExprContext node */
427 pfree(econtext);
431 * ReScanExprContext
433 * Reset an expression context in preparation for a rescan of its
434 * plan node. This requires calling any registered shutdown callbacks,
435 * since any partially complete set-returning-functions must be canceled.
437 * Note we make no assumption about the caller's memory context.
439 void
440 ReScanExprContext(ExprContext *econtext)
442 /* Call any registered callbacks */
443 ShutdownExprContext(econtext);
444 /* And clean up the memory used */
445 MemoryContextReset(econtext->ecxt_per_tuple_memory);
449 * Build a per-output-tuple ExprContext for an EState.
451 * This is normally invoked via GetPerTupleExprContext() macro,
452 * not directly.
454 ExprContext *
455 MakePerTupleExprContext(EState *estate)
457 if (estate->es_per_tuple_exprcontext == NULL)
458 estate->es_per_tuple_exprcontext = CreateExprContext(estate);
460 return estate->es_per_tuple_exprcontext;
464 /* ----------------------------------------------------------------
465 * miscellaneous node-init support functions
467 * Note: all of these are expected to be called with CurrentMemoryContext
468 * equal to the per-query memory context.
469 * ----------------------------------------------------------------
472 /* ----------------
473 * ExecAssignExprContext
475 * This initializes the ps_ExprContext field. It is only necessary
476 * to do this for nodes which use ExecQual or ExecProject
477 * because those routines require an econtext. Other nodes that
478 * don't have to evaluate expressions don't need to do this.
479 * ----------------
481 void
482 ExecAssignExprContext(EState *estate, PlanState *planstate)
484 planstate->ps_ExprContext = CreateExprContext(estate);
487 /* ----------------
488 * ExecAssignResultType
489 * ----------------
491 void
492 ExecAssignResultType(PlanState *planstate, TupleDesc tupDesc)
494 TupleTableSlot *slot = planstate->ps_ResultTupleSlot;
496 ExecSetSlotDescriptor(slot, tupDesc);
499 /* ----------------
500 * ExecAssignResultTypeFromTL
501 * ----------------
503 void
504 ExecAssignResultTypeFromTL(PlanState *planstate)
506 bool hasoid;
507 TupleDesc tupDesc;
509 if (ExecContextForcesOids(planstate, &hasoid))
511 /* context forces OID choice; hasoid is now set correctly */
513 else
515 /* given free choice, don't leave space for OIDs in result tuples */
516 hasoid = false;
520 * ExecTypeFromTL needs the parse-time representation of the tlist, not a
521 * list of ExprStates. This is good because some plan nodes don't bother
522 * to set up planstate->targetlist ...
524 tupDesc = ExecTypeFromTL(planstate->plan->targetlist, hasoid);
525 ExecAssignResultType(planstate, tupDesc);
528 /* ----------------
529 * ExecGetResultType
530 * ----------------
532 TupleDesc
533 ExecGetResultType(PlanState *planstate)
535 TupleTableSlot *slot = planstate->ps_ResultTupleSlot;
537 return slot->tts_tupleDescriptor;
540 /* ----------------
541 * ExecBuildProjectionInfo
543 * Build a ProjectionInfo node for evaluating the given tlist in the given
544 * econtext, and storing the result into the tuple slot. (Caller must have
545 * ensured that tuple slot has a descriptor matching the tlist!) Note that
546 * the given tlist should be a list of ExprState nodes, not Expr nodes.
548 * inputDesc can be NULL, but if it is not, we check to see whether simple
549 * Vars in the tlist match the descriptor. It is important to provide
550 * inputDesc for relation-scan plan nodes, as a cross check that the relation
551 * hasn't been changed since the plan was made. At higher levels of a plan,
552 * there is no need to recheck.
553 * ----------------
555 ProjectionInfo *
556 ExecBuildProjectionInfo(List *targetList,
557 ExprContext *econtext,
558 TupleTableSlot *slot,
559 TupleDesc inputDesc)
561 ProjectionInfo *projInfo = makeNode(ProjectionInfo);
562 int len;
563 bool isVarList;
564 ListCell *tl;
566 len = ExecTargetListLength(targetList);
568 projInfo->pi_targetlist = targetList;
569 projInfo->pi_exprContext = econtext;
570 projInfo->pi_slot = slot;
573 * Determine whether the target list consists entirely of simple Var
574 * references (ie, references to non-system attributes) that match the
575 * input. If so, we can use the simpler ExecVariableList instead of
576 * ExecTargetList. (Note: if there is a type mismatch then ExecEvalVar
577 * will probably throw an error at runtime, but we leave that to it.)
579 isVarList = true;
580 foreach(tl, targetList)
582 GenericExprState *gstate = (GenericExprState *) lfirst(tl);
583 Var *variable = (Var *) gstate->arg->expr;
584 Form_pg_attribute attr;
586 if (variable == NULL ||
587 !IsA(variable, Var) ||
588 variable->varattno <= 0)
590 isVarList = false;
591 break;
593 if (!inputDesc)
594 continue; /* can't check type, assume OK */
595 if (variable->varattno > inputDesc->natts)
597 isVarList = false;
598 break;
600 attr = inputDesc->attrs[variable->varattno - 1];
601 if (attr->attisdropped || variable->vartype != attr->atttypid)
603 isVarList = false;
604 break;
607 projInfo->pi_isVarList = isVarList;
609 if (isVarList)
611 int *varSlotOffsets;
612 int *varNumbers;
613 AttrNumber lastInnerVar = 0;
614 AttrNumber lastOuterVar = 0;
615 AttrNumber lastScanVar = 0;
617 projInfo->pi_itemIsDone = NULL; /* not needed */
618 projInfo->pi_varSlotOffsets = varSlotOffsets = (int *)
619 palloc0(len * sizeof(int));
620 projInfo->pi_varNumbers = varNumbers = (int *)
621 palloc0(len * sizeof(int));
624 * Set up the data needed by ExecVariableList. The slots in which the
625 * variables can be found at runtime are denoted by the offsets of
626 * their slot pointers within the econtext. This rather grotty
627 * representation is needed because the caller may not have given us
628 * the real econtext yet (see hacks in nodeSubplan.c).
630 foreach(tl, targetList)
632 GenericExprState *gstate = (GenericExprState *) lfirst(tl);
633 Var *variable = (Var *) gstate->arg->expr;
634 AttrNumber attnum = variable->varattno;
635 TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
636 AttrNumber resind = tle->resno - 1;
638 Assert(resind >= 0 && resind < len);
639 varNumbers[resind] = attnum;
641 switch (variable->varno)
643 case INNER:
644 varSlotOffsets[resind] = offsetof(ExprContext,
645 ecxt_innertuple);
646 lastInnerVar = Max(lastInnerVar, attnum);
647 break;
649 case OUTER:
650 varSlotOffsets[resind] = offsetof(ExprContext,
651 ecxt_outertuple);
652 lastOuterVar = Max(lastOuterVar, attnum);
653 break;
655 default:
656 varSlotOffsets[resind] = offsetof(ExprContext,
657 ecxt_scantuple);
658 lastScanVar = Max(lastScanVar, attnum);
659 break;
662 projInfo->pi_lastInnerVar = lastInnerVar;
663 projInfo->pi_lastOuterVar = lastOuterVar;
664 projInfo->pi_lastScanVar = lastScanVar;
666 else
668 projInfo->pi_itemIsDone = (ExprDoneCond *)
669 palloc(len * sizeof(ExprDoneCond));
670 projInfo->pi_varSlotOffsets = NULL;
671 projInfo->pi_varNumbers = NULL;
674 return projInfo;
677 /* ----------------
678 * ExecAssignProjectionInfo
680 * forms the projection information from the node's targetlist
682 * Notes for inputDesc are same as for ExecBuildProjectionInfo: supply it
683 * for a relation-scan node, can pass NULL for upper-level nodes
684 * ----------------
686 void
687 ExecAssignProjectionInfo(PlanState *planstate,
688 TupleDesc inputDesc)
690 planstate->ps_ProjInfo =
691 ExecBuildProjectionInfo(planstate->targetlist,
692 planstate->ps_ExprContext,
693 planstate->ps_ResultTupleSlot,
694 inputDesc);
698 /* ----------------
699 * ExecFreeExprContext
701 * A plan node's ExprContext should be freed explicitly during executor
702 * shutdown because there may be shutdown callbacks to call. (Other resources
703 * made by the above routines, such as projection info, don't need to be freed
704 * explicitly because they're just memory in the per-query memory context.)
706 * However ... there is no particular need to do it during ExecEndNode,
707 * because FreeExecutorState will free any remaining ExprContexts within
708 * the EState. Letting FreeExecutorState do it allows the ExprContexts to
709 * be freed in reverse order of creation, rather than order of creation as
710 * will happen if we delete them here, which saves O(N^2) work in the list
711 * cleanup inside FreeExprContext.
712 * ----------------
714 void
715 ExecFreeExprContext(PlanState *planstate)
718 * Per above discussion, don't actually delete the ExprContext. We do
719 * unlink it from the plan node, though.
721 planstate->ps_ExprContext = NULL;
724 /* ----------------------------------------------------------------
725 * the following scan type support functions are for
726 * those nodes which are stubborn and return tuples in
727 * their Scan tuple slot instead of their Result tuple
728 * slot.. luck fur us, these nodes do not do projections
729 * so we don't have to worry about getting the ProjectionInfo
730 * right for them... -cim 6/3/91
731 * ----------------------------------------------------------------
734 /* ----------------
735 * ExecGetScanType
736 * ----------------
738 TupleDesc
739 ExecGetScanType(ScanState *scanstate)
741 TupleTableSlot *slot = scanstate->ss_ScanTupleSlot;
743 return slot->tts_tupleDescriptor;
746 /* ----------------
747 * ExecAssignScanType
748 * ----------------
750 void
751 ExecAssignScanType(ScanState *scanstate, TupleDesc tupDesc)
753 TupleTableSlot *slot = scanstate->ss_ScanTupleSlot;
755 ExecSetSlotDescriptor(slot, tupDesc);
758 /* ----------------
759 * ExecAssignScanTypeFromOuterPlan
760 * ----------------
762 void
763 ExecAssignScanTypeFromOuterPlan(ScanState *scanstate)
765 PlanState *outerPlan;
766 TupleDesc tupDesc;
768 outerPlan = outerPlanState(scanstate);
769 tupDesc = ExecGetResultType(outerPlan);
771 ExecAssignScanType(scanstate, tupDesc);
775 /* ----------------------------------------------------------------
776 * Scan node support
777 * ----------------------------------------------------------------
780 /* ----------------------------------------------------------------
781 * ExecRelationIsTargetRelation
783 * Detect whether a relation (identified by rangetable index)
784 * is one of the target relations of the query.
785 * ----------------------------------------------------------------
787 bool
788 ExecRelationIsTargetRelation(EState *estate, Index scanrelid)
790 ResultRelInfo *resultRelInfos;
791 int i;
793 resultRelInfos = estate->es_result_relations;
794 for (i = 0; i < estate->es_num_result_relations; i++)
796 if (resultRelInfos[i].ri_RangeTableIndex == scanrelid)
797 return true;
799 return false;
802 /* ----------------------------------------------------------------
803 * ExecOpenScanRelation
805 * Open the heap relation to be scanned by a base-level scan plan node.
806 * This should be called during the node's ExecInit routine.
808 * By default, this acquires AccessShareLock on the relation. However,
809 * if the relation was already locked by InitPlan, we don't need to acquire
810 * any additional lock. This saves trips to the shared lock manager.
811 * ----------------------------------------------------------------
813 Relation
814 ExecOpenScanRelation(EState *estate, Index scanrelid)
816 Oid reloid;
817 LOCKMODE lockmode;
820 * Determine the lock type we need. First, scan to see if target relation
821 * is a result relation. If not, check if it's a FOR UPDATE/FOR SHARE
822 * relation. In either of those cases, we got the lock already.
824 lockmode = AccessShareLock;
825 if (ExecRelationIsTargetRelation(estate, scanrelid))
826 lockmode = NoLock;
827 else
829 ListCell *l;
831 foreach(l, estate->es_rowMarks)
833 ExecRowMark *erm = lfirst(l);
835 if (erm->rti == scanrelid)
837 lockmode = NoLock;
838 break;
843 /* OK, open the relation and acquire lock as needed */
844 reloid = getrelid(scanrelid, estate->es_range_table);
845 return heap_open(reloid, lockmode);
848 /* ----------------------------------------------------------------
849 * ExecCloseScanRelation
851 * Close the heap relation scanned by a base-level scan plan node.
852 * This should be called during the node's ExecEnd routine.
854 * Currently, we do not release the lock acquired by ExecOpenScanRelation.
855 * This lock should be held till end of transaction. (There is a faction
856 * that considers this too much locking, however.)
858 * If we did want to release the lock, we'd have to repeat the logic in
859 * ExecOpenScanRelation in order to figure out what to release.
860 * ----------------------------------------------------------------
862 void
863 ExecCloseScanRelation(Relation scanrel)
865 heap_close(scanrel, NoLock);
869 /* ----------------------------------------------------------------
870 * ExecInsertIndexTuples support
871 * ----------------------------------------------------------------
874 /* ----------------------------------------------------------------
875 * ExecOpenIndices
877 * Find the indices associated with a result relation, open them,
878 * and save information about them in the result ResultRelInfo.
880 * At entry, caller has already opened and locked
881 * resultRelInfo->ri_RelationDesc.
882 * ----------------------------------------------------------------
884 void
885 ExecOpenIndices(ResultRelInfo *resultRelInfo)
887 Relation resultRelation = resultRelInfo->ri_RelationDesc;
888 List *indexoidlist;
889 ListCell *l;
890 int len,
892 RelationPtr relationDescs;
893 IndexInfo **indexInfoArray;
895 resultRelInfo->ri_NumIndices = 0;
897 /* fast path if no indexes */
898 if (!RelationGetForm(resultRelation)->relhasindex)
899 return;
902 * Get cached list of index OIDs
904 indexoidlist = RelationGetIndexList(resultRelation);
905 len = list_length(indexoidlist);
906 if (len == 0)
907 return;
910 * allocate space for result arrays
912 relationDescs = (RelationPtr) palloc(len * sizeof(Relation));
913 indexInfoArray = (IndexInfo **) palloc(len * sizeof(IndexInfo *));
915 resultRelInfo->ri_NumIndices = len;
916 resultRelInfo->ri_IndexRelationDescs = relationDescs;
917 resultRelInfo->ri_IndexRelationInfo = indexInfoArray;
920 * For each index, open the index relation and save pg_index info. We
921 * acquire RowExclusiveLock, signifying we will update the index.
923 i = 0;
924 foreach(l, indexoidlist)
926 Oid indexOid = lfirst_oid(l);
927 Relation indexDesc;
928 IndexInfo *ii;
930 indexDesc = index_open(indexOid, RowExclusiveLock);
932 /* extract index key information from the index's pg_index info */
933 ii = BuildIndexInfo(indexDesc);
935 relationDescs[i] = indexDesc;
936 indexInfoArray[i] = ii;
937 i++;
940 list_free(indexoidlist);
943 /* ----------------------------------------------------------------
944 * ExecCloseIndices
946 * Close the index relations stored in resultRelInfo
947 * ----------------------------------------------------------------
949 void
950 ExecCloseIndices(ResultRelInfo *resultRelInfo)
952 int i;
953 int numIndices;
954 RelationPtr indexDescs;
956 numIndices = resultRelInfo->ri_NumIndices;
957 indexDescs = resultRelInfo->ri_IndexRelationDescs;
959 for (i = 0; i < numIndices; i++)
961 if (indexDescs[i] == NULL)
962 continue; /* shouldn't happen? */
964 /* Drop lock acquired by ExecOpenIndices */
965 index_close(indexDescs[i], RowExclusiveLock);
969 * XXX should free indexInfo array here too? Currently we assume that
970 * such stuff will be cleaned up automatically in FreeExecutorState.
974 /* ----------------------------------------------------------------
975 * ExecInsertIndexTuples
977 * This routine takes care of inserting index tuples
978 * into all the relations indexing the result relation
979 * when a heap tuple is inserted into the result relation.
980 * Much of this code should be moved into the genam
981 * stuff as it only exists here because the genam stuff
982 * doesn't provide the functionality needed by the
983 * executor.. -cim 9/27/89
985 * CAUTION: this must not be called for a HOT update.
986 * We can't defend against that here for lack of info.
987 * Should we change the API to make it safer?
988 * ----------------------------------------------------------------
990 void
991 ExecInsertIndexTuples(TupleTableSlot *slot,
992 ItemPointer tupleid,
993 EState *estate,
994 bool is_vacuum)
996 ResultRelInfo *resultRelInfo;
997 int i;
998 int numIndices;
999 RelationPtr relationDescs;
1000 Relation heapRelation;
1001 IndexInfo **indexInfoArray;
1002 ExprContext *econtext;
1003 Datum values[INDEX_MAX_KEYS];
1004 bool isnull[INDEX_MAX_KEYS];
1007 * Get information from the result relation info structure.
1009 resultRelInfo = estate->es_result_relation_info;
1010 numIndices = resultRelInfo->ri_NumIndices;
1011 relationDescs = resultRelInfo->ri_IndexRelationDescs;
1012 indexInfoArray = resultRelInfo->ri_IndexRelationInfo;
1013 heapRelation = resultRelInfo->ri_RelationDesc;
1016 * We will use the EState's per-tuple context for evaluating predicates
1017 * and index expressions (creating it if it's not already there).
1019 econtext = GetPerTupleExprContext(estate);
1021 /* Arrange for econtext's scan tuple to be the tuple under test */
1022 econtext->ecxt_scantuple = slot;
1025 * for each index, form and insert the index tuple
1027 for (i = 0; i < numIndices; i++)
1029 IndexInfo *indexInfo;
1031 if (relationDescs[i] == NULL)
1032 continue;
1034 indexInfo = indexInfoArray[i];
1036 /* If the index is marked as read-only, ignore it */
1037 if (!indexInfo->ii_ReadyForInserts)
1038 continue;
1040 /* Check for partial index */
1041 if (indexInfo->ii_Predicate != NIL)
1043 List *predicate;
1046 * If predicate state not set up yet, create it (in the estate's
1047 * per-query context)
1049 predicate = indexInfo->ii_PredicateState;
1050 if (predicate == NIL)
1052 predicate = (List *)
1053 ExecPrepareExpr((Expr *) indexInfo->ii_Predicate,
1054 estate);
1055 indexInfo->ii_PredicateState = predicate;
1058 /* Skip this index-update if the predicate isn't satisfied */
1059 if (!ExecQual(predicate, econtext, false))
1060 continue;
1064 * FormIndexDatum fills in its values and isnull parameters with the
1065 * appropriate values for the column(s) of the index.
1067 FormIndexDatum(indexInfo,
1068 slot,
1069 estate,
1070 values,
1071 isnull);
1074 * The index AM does the rest. Note we suppress unique-index checks
1075 * if we are being called from VACUUM, since VACUUM may need to move
1076 * dead tuples that have the same keys as live ones.
1078 index_insert(relationDescs[i], /* index relation */
1079 values, /* array of index Datums */
1080 isnull, /* null flags */
1081 tupleid, /* tid of heap tuple */
1082 heapRelation,
1083 relationDescs[i]->rd_index->indisunique && !is_vacuum);
1086 * keep track of index inserts for debugging
1088 IncrIndexInserted();
1093 * UpdateChangedParamSet
1094 * Add changed parameters to a plan node's chgParam set
1096 void
1097 UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
1099 Bitmapset *parmset;
1102 * The plan node only depends on params listed in its allParam set. Don't
1103 * include anything else into its chgParam set.
1105 parmset = bms_intersect(node->plan->allParam, newchg);
1108 * Keep node->chgParam == NULL if there's not actually any members; this
1109 * allows the simplest possible tests in executor node files.
1111 if (!bms_is_empty(parmset))
1112 node->chgParam = bms_join(node->chgParam, parmset);
1113 else
1114 bms_free(parmset);
1118 * Register a shutdown callback in an ExprContext.
1120 * Shutdown callbacks will be called (in reverse order of registration)
1121 * when the ExprContext is deleted or rescanned. This provides a hook
1122 * for functions called in the context to do any cleanup needed --- it's
1123 * particularly useful for functions returning sets. Note that the
1124 * callback will *not* be called in the event that execution is aborted
1125 * by an error.
1127 void
1128 RegisterExprContextCallback(ExprContext *econtext,
1129 ExprContextCallbackFunction function,
1130 Datum arg)
1132 ExprContext_CB *ecxt_callback;
1134 /* Save the info in appropriate memory context */
1135 ecxt_callback = (ExprContext_CB *)
1136 MemoryContextAlloc(econtext->ecxt_per_query_memory,
1137 sizeof(ExprContext_CB));
1139 ecxt_callback->function = function;
1140 ecxt_callback->arg = arg;
1142 /* link to front of list for appropriate execution order */
1143 ecxt_callback->next = econtext->ecxt_callbacks;
1144 econtext->ecxt_callbacks = ecxt_callback;
1148 * Deregister a shutdown callback in an ExprContext.
1150 * Any list entries matching the function and arg will be removed.
1151 * This can be used if it's no longer necessary to call the callback.
1153 void
1154 UnregisterExprContextCallback(ExprContext *econtext,
1155 ExprContextCallbackFunction function,
1156 Datum arg)
1158 ExprContext_CB **prev_callback;
1159 ExprContext_CB *ecxt_callback;
1161 prev_callback = &econtext->ecxt_callbacks;
1163 while ((ecxt_callback = *prev_callback) != NULL)
1165 if (ecxt_callback->function == function && ecxt_callback->arg == arg)
1167 *prev_callback = ecxt_callback->next;
1168 pfree(ecxt_callback);
1170 else
1171 prev_callback = &ecxt_callback->next;
1176 * Call all the shutdown callbacks registered in an ExprContext.
1178 * The callback list is emptied (important in case this is only a rescan
1179 * reset, and not deletion of the ExprContext).
1181 static void
1182 ShutdownExprContext(ExprContext *econtext)
1184 ExprContext_CB *ecxt_callback;
1185 MemoryContext oldcontext;
1187 /* Fast path in normal case where there's nothing to do. */
1188 if (econtext->ecxt_callbacks == NULL)
1189 return;
1192 * Call the callbacks in econtext's per-tuple context. This ensures that
1193 * any memory they might leak will get cleaned up.
1195 oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
1198 * Call each callback function in reverse registration order.
1200 while ((ecxt_callback = econtext->ecxt_callbacks) != NULL)
1202 econtext->ecxt_callbacks = ecxt_callback->next;
1203 (*ecxt_callback->function) (ecxt_callback->arg);
1204 pfree(ecxt_callback);
1207 MemoryContextSwitchTo(oldcontext);