Header And Logo

PostgreSQL
| The world's most advanced open source database.

execUtils.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * execUtils.c
00004  *    miscellaneous executor utility routines
00005  *
00006  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00007  * Portions Copyright (c) 1994, Regents of the University of California
00008  *
00009  *
00010  * IDENTIFICATION
00011  *    src/backend/executor/execUtils.c
00012  *
00013  *-------------------------------------------------------------------------
00014  */
00015 /*
00016  * INTERFACE ROUTINES
00017  *      CreateExecutorState     Create/delete executor working state
00018  *      FreeExecutorState
00019  *      CreateExprContext
00020  *      CreateStandaloneExprContext
00021  *      FreeExprContext
00022  *      ReScanExprContext
00023  *
00024  *      ExecAssignExprContext   Common code for plan node init routines.
00025  *      ExecAssignResultType
00026  *      etc
00027  *
00028  *      ExecOpenScanRelation    Common code for scan node init routines.
00029  *      ExecCloseScanRelation
00030  *
00031  *      ExecOpenIndices         \
00032  *      ExecCloseIndices         | referenced by InitPlan, EndPlan,
00033  *      ExecInsertIndexTuples   /  ExecInsert, ExecUpdate
00034  *
00035  *      RegisterExprContextCallback    Register function shutdown callback
00036  *      UnregisterExprContextCallback  Deregister function shutdown callback
00037  *
00038  *   NOTES
00039  *      This file has traditionally been the place to stick misc.
00040  *      executor support stuff that doesn't really go anyplace else.
00041  */
00042 
00043 #include "postgres.h"
00044 
00045 #include "access/relscan.h"
00046 #include "access/transam.h"
00047 #include "catalog/index.h"
00048 #include "executor/execdebug.h"
00049 #include "nodes/nodeFuncs.h"
00050 #include "parser/parsetree.h"
00051 #include "storage/lmgr.h"
00052 #include "utils/memutils.h"
00053 #include "utils/tqual.h"
00054 
00055 
00056 static bool get_last_attnums(Node *node, ProjectionInfo *projInfo);
00057 static bool index_recheck_constraint(Relation index, Oid *constr_procs,
00058                          Datum *existing_values, bool *existing_isnull,
00059                          Datum *new_values);
00060 static void ShutdownExprContext(ExprContext *econtext, bool isCommit);
00061 
00062 
00063 /* ----------------------------------------------------------------
00064  *               Executor state and memory management functions
00065  * ----------------------------------------------------------------
00066  */
00067 
00068 /* ----------------
00069  *      CreateExecutorState
00070  *
00071  *      Create and initialize an EState node, which is the root of
00072  *      working storage for an entire Executor invocation.
00073  *
00074  * Principally, this creates the per-query memory context that will be
00075  * used to hold all working data that lives till the end of the query.
00076  * Note that the per-query context will become a child of the caller's
00077  * CurrentMemoryContext.
00078  * ----------------
00079  */
00080 EState *
00081 CreateExecutorState(void)
00082 {
00083     EState     *estate;
00084     MemoryContext qcontext;
00085     MemoryContext oldcontext;
00086 
00087     /*
00088      * Create the per-query context for this Executor run.
00089      */
00090     qcontext = AllocSetContextCreate(CurrentMemoryContext,
00091                                      "ExecutorState",
00092                                      ALLOCSET_DEFAULT_MINSIZE,
00093                                      ALLOCSET_DEFAULT_INITSIZE,
00094                                      ALLOCSET_DEFAULT_MAXSIZE);
00095 
00096     /*
00097      * Make the EState node within the per-query context.  This way, we don't
00098      * need a separate pfree() operation for it at shutdown.
00099      */
00100     oldcontext = MemoryContextSwitchTo(qcontext);
00101 
00102     estate = makeNode(EState);
00103 
00104     /*
00105      * Initialize all fields of the Executor State structure
00106      */
00107     estate->es_direction = ForwardScanDirection;
00108     estate->es_snapshot = SnapshotNow;
00109     estate->es_crosscheck_snapshot = InvalidSnapshot;   /* no crosscheck */
00110     estate->es_range_table = NIL;
00111     estate->es_plannedstmt = NULL;
00112 
00113     estate->es_junkFilter = NULL;
00114 
00115     estate->es_output_cid = (CommandId) 0;
00116 
00117     estate->es_result_relations = NULL;
00118     estate->es_num_result_relations = 0;
00119     estate->es_result_relation_info = NULL;
00120 
00121     estate->es_trig_target_relations = NIL;
00122     estate->es_trig_tuple_slot = NULL;
00123     estate->es_trig_oldtup_slot = NULL;
00124     estate->es_trig_newtup_slot = NULL;
00125 
00126     estate->es_param_list_info = NULL;
00127     estate->es_param_exec_vals = NULL;
00128 
00129     estate->es_query_cxt = qcontext;
00130 
00131     estate->es_tupleTable = NIL;
00132 
00133     estate->es_rowMarks = NIL;
00134 
00135     estate->es_processed = 0;
00136     estate->es_lastoid = InvalidOid;
00137 
00138     estate->es_top_eflags = 0;
00139     estate->es_instrument = 0;
00140     estate->es_finished = false;
00141 
00142     estate->es_exprcontexts = NIL;
00143 
00144     estate->es_subplanstates = NIL;
00145 
00146     estate->es_auxmodifytables = NIL;
00147 
00148     estate->es_per_tuple_exprcontext = NULL;
00149 
00150     estate->es_epqTuple = NULL;
00151     estate->es_epqTupleSet = NULL;
00152     estate->es_epqScanDone = NULL;
00153 
00154     /*
00155      * Return the executor state structure
00156      */
00157     MemoryContextSwitchTo(oldcontext);
00158 
00159     return estate;
00160 }
00161 
00162 /* ----------------
00163  *      FreeExecutorState
00164  *
00165  *      Release an EState along with all remaining working storage.
00166  *
00167  * Note: this is not responsible for releasing non-memory resources,
00168  * such as open relations or buffer pins.  But it will shut down any
00169  * still-active ExprContexts within the EState.  That is sufficient
00170  * cleanup for situations where the EState has only been used for expression
00171  * evaluation, and not to run a complete Plan.
00172  *
00173  * This can be called in any memory context ... so long as it's not one
00174  * of the ones to be freed.
00175  * ----------------
00176  */
00177 void
00178 FreeExecutorState(EState *estate)
00179 {
00180     /*
00181      * Shut down and free any remaining ExprContexts.  We do this explicitly
00182      * to ensure that any remaining shutdown callbacks get called (since they
00183      * might need to release resources that aren't simply memory within the
00184      * per-query memory context).
00185      */
00186     while (estate->es_exprcontexts)
00187     {
00188         /*
00189          * XXX: seems there ought to be a faster way to implement this than
00190          * repeated list_delete(), no?
00191          */
00192         FreeExprContext((ExprContext *) linitial(estate->es_exprcontexts),
00193                         true);
00194         /* FreeExprContext removed the list link for us */
00195     }
00196 
00197     /*
00198      * Free the per-query memory context, thereby releasing all working
00199      * memory, including the EState node itself.
00200      */
00201     MemoryContextDelete(estate->es_query_cxt);
00202 }
00203 
00204 /* ----------------
00205  *      CreateExprContext
00206  *
00207  *      Create a context for expression evaluation within an EState.
00208  *
00209  * An executor run may require multiple ExprContexts (we usually make one
00210  * for each Plan node, and a separate one for per-output-tuple processing
00211  * such as constraint checking).  Each ExprContext has its own "per-tuple"
00212  * memory context.
00213  *
00214  * Note we make no assumption about the caller's memory context.
00215  * ----------------
00216  */
00217 ExprContext *
00218 CreateExprContext(EState *estate)
00219 {
00220     ExprContext *econtext;
00221     MemoryContext oldcontext;
00222 
00223     /* Create the ExprContext node within the per-query memory context */
00224     oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
00225 
00226     econtext = makeNode(ExprContext);
00227 
00228     /* Initialize fields of ExprContext */
00229     econtext->ecxt_scantuple = NULL;
00230     econtext->ecxt_innertuple = NULL;
00231     econtext->ecxt_outertuple = NULL;
00232 
00233     econtext->ecxt_per_query_memory = estate->es_query_cxt;
00234 
00235     /*
00236      * Create working memory for expression evaluation in this context.
00237      */
00238     econtext->ecxt_per_tuple_memory =
00239         AllocSetContextCreate(estate->es_query_cxt,
00240                               "ExprContext",
00241                               ALLOCSET_DEFAULT_MINSIZE,
00242                               ALLOCSET_DEFAULT_INITSIZE,
00243                               ALLOCSET_DEFAULT_MAXSIZE);
00244 
00245     econtext->ecxt_param_exec_vals = estate->es_param_exec_vals;
00246     econtext->ecxt_param_list_info = estate->es_param_list_info;
00247 
00248     econtext->ecxt_aggvalues = NULL;
00249     econtext->ecxt_aggnulls = NULL;
00250 
00251     econtext->caseValue_datum = (Datum) 0;
00252     econtext->caseValue_isNull = true;
00253 
00254     econtext->domainValue_datum = (Datum) 0;
00255     econtext->domainValue_isNull = true;
00256 
00257     econtext->ecxt_estate = estate;
00258 
00259     econtext->ecxt_callbacks = NULL;
00260 
00261     /*
00262      * Link the ExprContext into the EState to ensure it is shut down when the
00263      * EState is freed.  Because we use lcons(), shutdowns will occur in
00264      * reverse order of creation, which may not be essential but can't hurt.
00265      */
00266     estate->es_exprcontexts = lcons(econtext, estate->es_exprcontexts);
00267 
00268     MemoryContextSwitchTo(oldcontext);
00269 
00270     return econtext;
00271 }
00272 
00273 /* ----------------
00274  *      CreateStandaloneExprContext
00275  *
00276  *      Create a context for standalone expression evaluation.
00277  *
00278  * An ExprContext made this way can be used for evaluation of expressions
00279  * that contain no Params, subplans, or Var references (it might work to
00280  * put tuple references into the scantuple field, but it seems unwise).
00281  *
00282  * The ExprContext struct is allocated in the caller's current memory
00283  * context, which also becomes its "per query" context.
00284  *
00285  * It is caller's responsibility to free the ExprContext when done,
00286  * or at least ensure that any shutdown callbacks have been called
00287  * (ReScanExprContext() is suitable).  Otherwise, non-memory resources
00288  * might be leaked.
00289  * ----------------
00290  */
00291 ExprContext *
00292 CreateStandaloneExprContext(void)
00293 {
00294     ExprContext *econtext;
00295 
00296     /* Create the ExprContext node within the caller's memory context */
00297     econtext = makeNode(ExprContext);
00298 
00299     /* Initialize fields of ExprContext */
00300     econtext->ecxt_scantuple = NULL;
00301     econtext->ecxt_innertuple = NULL;
00302     econtext->ecxt_outertuple = NULL;
00303 
00304     econtext->ecxt_per_query_memory = CurrentMemoryContext;
00305 
00306     /*
00307      * Create working memory for expression evaluation in this context.
00308      */
00309     econtext->ecxt_per_tuple_memory =
00310         AllocSetContextCreate(CurrentMemoryContext,
00311                               "ExprContext",
00312                               ALLOCSET_DEFAULT_MINSIZE,
00313                               ALLOCSET_DEFAULT_INITSIZE,
00314                               ALLOCSET_DEFAULT_MAXSIZE);
00315 
00316     econtext->ecxt_param_exec_vals = NULL;
00317     econtext->ecxt_param_list_info = NULL;
00318 
00319     econtext->ecxt_aggvalues = NULL;
00320     econtext->ecxt_aggnulls = NULL;
00321 
00322     econtext->caseValue_datum = (Datum) 0;
00323     econtext->caseValue_isNull = true;
00324 
00325     econtext->domainValue_datum = (Datum) 0;
00326     econtext->domainValue_isNull = true;
00327 
00328     econtext->ecxt_estate = NULL;
00329 
00330     econtext->ecxt_callbacks = NULL;
00331 
00332     return econtext;
00333 }
00334 
00335 /* ----------------
00336  *      FreeExprContext
00337  *
00338  *      Free an expression context, including calling any remaining
00339  *      shutdown callbacks.
00340  *
00341  * Since we free the temporary context used for expression evaluation,
00342  * any previously computed pass-by-reference expression result will go away!
00343  *
00344  * If isCommit is false, we are being called in error cleanup, and should
00345  * not call callbacks but only release memory.  (It might be better to call
00346  * the callbacks and pass the isCommit flag to them, but that would require
00347  * more invasive code changes than currently seems justified.)
00348  *
00349  * Note we make no assumption about the caller's memory context.
00350  * ----------------
00351  */
00352 void
00353 FreeExprContext(ExprContext *econtext, bool isCommit)
00354 {
00355     EState     *estate;
00356 
00357     /* Call any registered callbacks */
00358     ShutdownExprContext(econtext, isCommit);
00359     /* And clean up the memory used */
00360     MemoryContextDelete(econtext->ecxt_per_tuple_memory);
00361     /* Unlink self from owning EState, if any */
00362     estate = econtext->ecxt_estate;
00363     if (estate)
00364         estate->es_exprcontexts = list_delete_ptr(estate->es_exprcontexts,
00365                                                   econtext);
00366     /* And delete the ExprContext node */
00367     pfree(econtext);
00368 }
00369 
00370 /*
00371  * ReScanExprContext
00372  *
00373  *      Reset an expression context in preparation for a rescan of its
00374  *      plan node.  This requires calling any registered shutdown callbacks,
00375  *      since any partially complete set-returning-functions must be canceled.
00376  *
00377  * Note we make no assumption about the caller's memory context.
00378  */
00379 void
00380 ReScanExprContext(ExprContext *econtext)
00381 {
00382     /* Call any registered callbacks */
00383     ShutdownExprContext(econtext, true);
00384     /* And clean up the memory used */
00385     MemoryContextReset(econtext->ecxt_per_tuple_memory);
00386 }
00387 
00388 /*
00389  * Build a per-output-tuple ExprContext for an EState.
00390  *
00391  * This is normally invoked via GetPerTupleExprContext() macro,
00392  * not directly.
00393  */
00394 ExprContext *
00395 MakePerTupleExprContext(EState *estate)
00396 {
00397     if (estate->es_per_tuple_exprcontext == NULL)
00398         estate->es_per_tuple_exprcontext = CreateExprContext(estate);
00399 
00400     return estate->es_per_tuple_exprcontext;
00401 }
00402 
00403 
00404 /* ----------------------------------------------------------------
00405  *               miscellaneous node-init support functions
00406  *
00407  * Note: all of these are expected to be called with CurrentMemoryContext
00408  * equal to the per-query memory context.
00409  * ----------------------------------------------------------------
00410  */
00411 
00412 /* ----------------
00413  *      ExecAssignExprContext
00414  *
00415  *      This initializes the ps_ExprContext field.  It is only necessary
00416  *      to do this for nodes which use ExecQual or ExecProject
00417  *      because those routines require an econtext. Other nodes that
00418  *      don't have to evaluate expressions don't need to do this.
00419  * ----------------
00420  */
00421 void
00422 ExecAssignExprContext(EState *estate, PlanState *planstate)
00423 {
00424     planstate->ps_ExprContext = CreateExprContext(estate);
00425 }
00426 
00427 /* ----------------
00428  *      ExecAssignResultType
00429  * ----------------
00430  */
00431 void
00432 ExecAssignResultType(PlanState *planstate, TupleDesc tupDesc)
00433 {
00434     TupleTableSlot *slot = planstate->ps_ResultTupleSlot;
00435 
00436     ExecSetSlotDescriptor(slot, tupDesc);
00437 }
00438 
00439 /* ----------------
00440  *      ExecAssignResultTypeFromTL
00441  * ----------------
00442  */
00443 void
00444 ExecAssignResultTypeFromTL(PlanState *planstate)
00445 {
00446     bool        hasoid;
00447     TupleDesc   tupDesc;
00448 
00449     if (ExecContextForcesOids(planstate, &hasoid))
00450     {
00451         /* context forces OID choice; hasoid is now set correctly */
00452     }
00453     else
00454     {
00455         /* given free choice, don't leave space for OIDs in result tuples */
00456         hasoid = false;
00457     }
00458 
00459     /*
00460      * ExecTypeFromTL needs the parse-time representation of the tlist, not a
00461      * list of ExprStates.  This is good because some plan nodes don't bother
00462      * to set up planstate->targetlist ...
00463      */
00464     tupDesc = ExecTypeFromTL(planstate->plan->targetlist, hasoid);
00465     ExecAssignResultType(planstate, tupDesc);
00466 }
00467 
00468 /* ----------------
00469  *      ExecGetResultType
00470  * ----------------
00471  */
00472 TupleDesc
00473 ExecGetResultType(PlanState *planstate)
00474 {
00475     TupleTableSlot *slot = planstate->ps_ResultTupleSlot;
00476 
00477     return slot->tts_tupleDescriptor;
00478 }
00479 
00480 /* ----------------
00481  *      ExecBuildProjectionInfo
00482  *
00483  * Build a ProjectionInfo node for evaluating the given tlist in the given
00484  * econtext, and storing the result into the tuple slot.  (Caller must have
00485  * ensured that tuple slot has a descriptor matching the tlist!)  Note that
00486  * the given tlist should be a list of ExprState nodes, not Expr nodes.
00487  *
00488  * inputDesc can be NULL, but if it is not, we check to see whether simple
00489  * Vars in the tlist match the descriptor.  It is important to provide
00490  * inputDesc for relation-scan plan nodes, as a cross check that the relation
00491  * hasn't been changed since the plan was made.  At higher levels of a plan,
00492  * there is no need to recheck.
00493  * ----------------
00494  */
00495 ProjectionInfo *
00496 ExecBuildProjectionInfo(List *targetList,
00497                         ExprContext *econtext,
00498                         TupleTableSlot *slot,
00499                         TupleDesc inputDesc)
00500 {
00501     ProjectionInfo *projInfo = makeNode(ProjectionInfo);
00502     int         len = ExecTargetListLength(targetList);
00503     int        *workspace;
00504     int        *varSlotOffsets;
00505     int        *varNumbers;
00506     int        *varOutputCols;
00507     List       *exprlist;
00508     int         numSimpleVars;
00509     bool        directMap;
00510     ListCell   *tl;
00511 
00512     projInfo->pi_exprContext = econtext;
00513     projInfo->pi_slot = slot;
00514     /* since these are all int arrays, we need do just one palloc */
00515     workspace = (int *) palloc(len * 3 * sizeof(int));
00516     projInfo->pi_varSlotOffsets = varSlotOffsets = workspace;
00517     projInfo->pi_varNumbers = varNumbers = workspace + len;
00518     projInfo->pi_varOutputCols = varOutputCols = workspace + len * 2;
00519     projInfo->pi_lastInnerVar = 0;
00520     projInfo->pi_lastOuterVar = 0;
00521     projInfo->pi_lastScanVar = 0;
00522 
00523     /*
00524      * We separate the target list elements into simple Var references and
00525      * expressions which require the full ExecTargetList machinery.  To be a
00526      * simple Var, a Var has to be a user attribute and not mismatch the
00527      * inputDesc.  (Note: if there is a type mismatch then ExecEvalScalarVar
00528      * will probably throw an error at runtime, but we leave that to it.)
00529      */
00530     exprlist = NIL;
00531     numSimpleVars = 0;
00532     directMap = true;
00533     foreach(tl, targetList)
00534     {
00535         GenericExprState *gstate = (GenericExprState *) lfirst(tl);
00536         Var        *variable = (Var *) gstate->arg->expr;
00537         bool        isSimpleVar = false;
00538 
00539         if (variable != NULL &&
00540             IsA(variable, Var) &&
00541             variable->varattno > 0)
00542         {
00543             if (!inputDesc)
00544                 isSimpleVar = true;     /* can't check type, assume OK */
00545             else if (variable->varattno <= inputDesc->natts)
00546             {
00547                 Form_pg_attribute attr;
00548 
00549                 attr = inputDesc->attrs[variable->varattno - 1];
00550                 if (!attr->attisdropped && variable->vartype == attr->atttypid)
00551                     isSimpleVar = true;
00552             }
00553         }
00554 
00555         if (isSimpleVar)
00556         {
00557             TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
00558             AttrNumber  attnum = variable->varattno;
00559 
00560             varNumbers[numSimpleVars] = attnum;
00561             varOutputCols[numSimpleVars] = tle->resno;
00562             if (tle->resno != numSimpleVars + 1)
00563                 directMap = false;
00564 
00565             switch (variable->varno)
00566             {
00567                 case INNER_VAR:
00568                     varSlotOffsets[numSimpleVars] = offsetof(ExprContext,
00569                                                              ecxt_innertuple);
00570                     if (projInfo->pi_lastInnerVar < attnum)
00571                         projInfo->pi_lastInnerVar = attnum;
00572                     break;
00573 
00574                 case OUTER_VAR:
00575                     varSlotOffsets[numSimpleVars] = offsetof(ExprContext,
00576                                                              ecxt_outertuple);
00577                     if (projInfo->pi_lastOuterVar < attnum)
00578                         projInfo->pi_lastOuterVar = attnum;
00579                     break;
00580 
00581                     /* INDEX_VAR is handled by default case */
00582 
00583                 default:
00584                     varSlotOffsets[numSimpleVars] = offsetof(ExprContext,
00585                                                              ecxt_scantuple);
00586                     if (projInfo->pi_lastScanVar < attnum)
00587                         projInfo->pi_lastScanVar = attnum;
00588                     break;
00589             }
00590             numSimpleVars++;
00591         }
00592         else
00593         {
00594             /* Not a simple variable, add it to generic targetlist */
00595             exprlist = lappend(exprlist, gstate);
00596             /* Examine expr to include contained Vars in lastXXXVar counts */
00597             get_last_attnums((Node *) variable, projInfo);
00598         }
00599     }
00600     projInfo->pi_targetlist = exprlist;
00601     projInfo->pi_numSimpleVars = numSimpleVars;
00602     projInfo->pi_directMap = directMap;
00603 
00604     if (exprlist == NIL)
00605         projInfo->pi_itemIsDone = NULL; /* not needed */
00606     else
00607         projInfo->pi_itemIsDone = (ExprDoneCond *)
00608             palloc(len * sizeof(ExprDoneCond));
00609 
00610     return projInfo;
00611 }
00612 
00613 /*
00614  * get_last_attnums: expression walker for ExecBuildProjectionInfo
00615  *
00616  *  Update the lastXXXVar counts to be at least as large as the largest
00617  *  attribute numbers found in the expression
00618  */
00619 static bool
00620 get_last_attnums(Node *node, ProjectionInfo *projInfo)
00621 {
00622     if (node == NULL)
00623         return false;
00624     if (IsA(node, Var))
00625     {
00626         Var        *variable = (Var *) node;
00627         AttrNumber  attnum = variable->varattno;
00628 
00629         switch (variable->varno)
00630         {
00631             case INNER_VAR:
00632                 if (projInfo->pi_lastInnerVar < attnum)
00633                     projInfo->pi_lastInnerVar = attnum;
00634                 break;
00635 
00636             case OUTER_VAR:
00637                 if (projInfo->pi_lastOuterVar < attnum)
00638                     projInfo->pi_lastOuterVar = attnum;
00639                 break;
00640 
00641                 /* INDEX_VAR is handled by default case */
00642 
00643             default:
00644                 if (projInfo->pi_lastScanVar < attnum)
00645                     projInfo->pi_lastScanVar = attnum;
00646                 break;
00647         }
00648         return false;
00649     }
00650 
00651     /*
00652      * Don't examine the arguments of Aggrefs or WindowFuncs, because those do
00653      * not represent expressions to be evaluated within the overall
00654      * targetlist's econtext.
00655      */
00656     if (IsA(node, Aggref))
00657         return false;
00658     if (IsA(node, WindowFunc))
00659         return false;
00660     return expression_tree_walker(node, get_last_attnums,
00661                                   (void *) projInfo);
00662 }
00663 
00664 /* ----------------
00665  *      ExecAssignProjectionInfo
00666  *
00667  * forms the projection information from the node's targetlist
00668  *
00669  * Notes for inputDesc are same as for ExecBuildProjectionInfo: supply it
00670  * for a relation-scan node, can pass NULL for upper-level nodes
00671  * ----------------
00672  */
00673 void
00674 ExecAssignProjectionInfo(PlanState *planstate,
00675                          TupleDesc inputDesc)
00676 {
00677     planstate->ps_ProjInfo =
00678         ExecBuildProjectionInfo(planstate->targetlist,
00679                                 planstate->ps_ExprContext,
00680                                 planstate->ps_ResultTupleSlot,
00681                                 inputDesc);
00682 }
00683 
00684 
00685 /* ----------------
00686  *      ExecFreeExprContext
00687  *
00688  * A plan node's ExprContext should be freed explicitly during executor
00689  * shutdown because there may be shutdown callbacks to call.  (Other resources
00690  * made by the above routines, such as projection info, don't need to be freed
00691  * explicitly because they're just memory in the per-query memory context.)
00692  *
00693  * However ... there is no particular need to do it during ExecEndNode,
00694  * because FreeExecutorState will free any remaining ExprContexts within
00695  * the EState.  Letting FreeExecutorState do it allows the ExprContexts to
00696  * be freed in reverse order of creation, rather than order of creation as
00697  * will happen if we delete them here, which saves O(N^2) work in the list
00698  * cleanup inside FreeExprContext.
00699  * ----------------
00700  */
00701 void
00702 ExecFreeExprContext(PlanState *planstate)
00703 {
00704     /*
00705      * Per above discussion, don't actually delete the ExprContext. We do
00706      * unlink it from the plan node, though.
00707      */
00708     planstate->ps_ExprContext = NULL;
00709 }
00710 
00711 /* ----------------------------------------------------------------
00712  *      the following scan type support functions are for
00713  *      those nodes which are stubborn and return tuples in
00714  *      their Scan tuple slot instead of their Result tuple
00715  *      slot..  luck fur us, these nodes do not do projections
00716  *      so we don't have to worry about getting the ProjectionInfo
00717  *      right for them...  -cim 6/3/91
00718  * ----------------------------------------------------------------
00719  */
00720 
00721 /* ----------------
00722  *      ExecGetScanType
00723  * ----------------
00724  */
00725 TupleDesc
00726 ExecGetScanType(ScanState *scanstate)
00727 {
00728     TupleTableSlot *slot = scanstate->ss_ScanTupleSlot;
00729 
00730     return slot->tts_tupleDescriptor;
00731 }
00732 
00733 /* ----------------
00734  *      ExecAssignScanType
00735  * ----------------
00736  */
00737 void
00738 ExecAssignScanType(ScanState *scanstate, TupleDesc tupDesc)
00739 {
00740     TupleTableSlot *slot = scanstate->ss_ScanTupleSlot;
00741 
00742     ExecSetSlotDescriptor(slot, tupDesc);
00743 }
00744 
00745 /* ----------------
00746  *      ExecAssignScanTypeFromOuterPlan
00747  * ----------------
00748  */
00749 void
00750 ExecAssignScanTypeFromOuterPlan(ScanState *scanstate)
00751 {
00752     PlanState  *outerPlan;
00753     TupleDesc   tupDesc;
00754 
00755     outerPlan = outerPlanState(scanstate);
00756     tupDesc = ExecGetResultType(outerPlan);
00757 
00758     ExecAssignScanType(scanstate, tupDesc);
00759 }
00760 
00761 
00762 /* ----------------------------------------------------------------
00763  *                Scan node support
00764  * ----------------------------------------------------------------
00765  */
00766 
00767 /* ----------------------------------------------------------------
00768  *      ExecRelationIsTargetRelation
00769  *
00770  *      Detect whether a relation (identified by rangetable index)
00771  *      is one of the target relations of the query.
00772  * ----------------------------------------------------------------
00773  */
00774 bool
00775 ExecRelationIsTargetRelation(EState *estate, Index scanrelid)
00776 {
00777     ResultRelInfo *resultRelInfos;
00778     int         i;
00779 
00780     resultRelInfos = estate->es_result_relations;
00781     for (i = 0; i < estate->es_num_result_relations; i++)
00782     {
00783         if (resultRelInfos[i].ri_RangeTableIndex == scanrelid)
00784             return true;
00785     }
00786     return false;
00787 }
00788 
00789 /* ----------------------------------------------------------------
00790  *      ExecOpenScanRelation
00791  *
00792  *      Open the heap relation to be scanned by a base-level scan plan node.
00793  *      This should be called during the node's ExecInit routine.
00794  *
00795  * By default, this acquires AccessShareLock on the relation.  However,
00796  * if the relation was already locked by InitPlan, we don't need to acquire
00797  * any additional lock.  This saves trips to the shared lock manager.
00798  * ----------------------------------------------------------------
00799  */
00800 Relation
00801 ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags)
00802 {
00803     Relation    rel;
00804     Oid         reloid;
00805     LOCKMODE    lockmode;
00806 
00807     /*
00808      * Determine the lock type we need.  First, scan to see if target relation
00809      * is a result relation.  If not, check if it's a FOR UPDATE/FOR SHARE
00810      * relation.  In either of those cases, we got the lock already.
00811      */
00812     lockmode = AccessShareLock;
00813     if (ExecRelationIsTargetRelation(estate, scanrelid))
00814         lockmode = NoLock;
00815     else
00816     {
00817         ListCell   *l;
00818 
00819         foreach(l, estate->es_rowMarks)
00820         {
00821             ExecRowMark *erm = lfirst(l);
00822 
00823             if (erm->rti == scanrelid)
00824             {
00825                 lockmode = NoLock;
00826                 break;
00827             }
00828         }
00829     }
00830 
00831     /* Open the relation and acquire lock as needed */
00832     reloid = getrelid(scanrelid, estate->es_range_table);
00833     rel = heap_open(reloid, lockmode);
00834 
00835     /*
00836      * Complain if we're attempting a scan of an unscannable relation, except
00837      * when the query won't actually be run.  This is a slightly klugy place
00838      * to do this, perhaps, but there is no better place.
00839      */
00840     if ((eflags & (EXEC_FLAG_EXPLAIN_ONLY | EXEC_FLAG_WITH_NO_DATA)) == 0 &&
00841         !RelationIsScannable(rel))
00842         ereport(ERROR,
00843                 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
00844                  errmsg("materialized view \"%s\" has not been populated",
00845                         RelationGetRelationName(rel)),
00846                  errhint("Use the REFRESH MATERIALIZED VIEW command.")));
00847 
00848     return rel;
00849 }
00850 
00851 /* ----------------------------------------------------------------
00852  *      ExecCloseScanRelation
00853  *
00854  *      Close the heap relation scanned by a base-level scan plan node.
00855  *      This should be called during the node's ExecEnd routine.
00856  *
00857  * Currently, we do not release the lock acquired by ExecOpenScanRelation.
00858  * This lock should be held till end of transaction.  (There is a faction
00859  * that considers this too much locking, however.)
00860  *
00861  * If we did want to release the lock, we'd have to repeat the logic in
00862  * ExecOpenScanRelation in order to figure out what to release.
00863  * ----------------------------------------------------------------
00864  */
00865 void
00866 ExecCloseScanRelation(Relation scanrel)
00867 {
00868     heap_close(scanrel, NoLock);
00869 }
00870 
00871 
00872 /* ----------------------------------------------------------------
00873  *                ExecInsertIndexTuples support
00874  * ----------------------------------------------------------------
00875  */
00876 
00877 /* ----------------------------------------------------------------
00878  *      ExecOpenIndices
00879  *
00880  *      Find the indices associated with a result relation, open them,
00881  *      and save information about them in the result ResultRelInfo.
00882  *
00883  *      At entry, caller has already opened and locked
00884  *      resultRelInfo->ri_RelationDesc.
00885  * ----------------------------------------------------------------
00886  */
00887 void
00888 ExecOpenIndices(ResultRelInfo *resultRelInfo)
00889 {
00890     Relation    resultRelation = resultRelInfo->ri_RelationDesc;
00891     List       *indexoidlist;
00892     ListCell   *l;
00893     int         len,
00894                 i;
00895     RelationPtr relationDescs;
00896     IndexInfo **indexInfoArray;
00897 
00898     resultRelInfo->ri_NumIndices = 0;
00899 
00900     /* fast path if no indexes */
00901     if (!RelationGetForm(resultRelation)->relhasindex)
00902         return;
00903 
00904     /*
00905      * Get cached list of index OIDs
00906      */
00907     indexoidlist = RelationGetIndexList(resultRelation);
00908     len = list_length(indexoidlist);
00909     if (len == 0)
00910         return;
00911 
00912     /*
00913      * allocate space for result arrays
00914      */
00915     relationDescs = (RelationPtr) palloc(len * sizeof(Relation));
00916     indexInfoArray = (IndexInfo **) palloc(len * sizeof(IndexInfo *));
00917 
00918     resultRelInfo->ri_NumIndices = len;
00919     resultRelInfo->ri_IndexRelationDescs = relationDescs;
00920     resultRelInfo->ri_IndexRelationInfo = indexInfoArray;
00921 
00922     /*
00923      * For each index, open the index relation and save pg_index info. We
00924      * acquire RowExclusiveLock, signifying we will update the index.
00925      *
00926      * Note: we do this even if the index is not IndexIsReady; it's not worth
00927      * the trouble to optimize for the case where it isn't.
00928      */
00929     i = 0;
00930     foreach(l, indexoidlist)
00931     {
00932         Oid         indexOid = lfirst_oid(l);
00933         Relation    indexDesc;
00934         IndexInfo  *ii;
00935 
00936         indexDesc = index_open(indexOid, RowExclusiveLock);
00937 
00938         /* extract index key information from the index's pg_index info */
00939         ii = BuildIndexInfo(indexDesc);
00940 
00941         relationDescs[i] = indexDesc;
00942         indexInfoArray[i] = ii;
00943         i++;
00944     }
00945 
00946     list_free(indexoidlist);
00947 }
00948 
00949 /* ----------------------------------------------------------------
00950  *      ExecCloseIndices
00951  *
00952  *      Close the index relations stored in resultRelInfo
00953  * ----------------------------------------------------------------
00954  */
00955 void
00956 ExecCloseIndices(ResultRelInfo *resultRelInfo)
00957 {
00958     int         i;
00959     int         numIndices;
00960     RelationPtr indexDescs;
00961 
00962     numIndices = resultRelInfo->ri_NumIndices;
00963     indexDescs = resultRelInfo->ri_IndexRelationDescs;
00964 
00965     for (i = 0; i < numIndices; i++)
00966     {
00967         if (indexDescs[i] == NULL)
00968             continue;           /* shouldn't happen? */
00969 
00970         /* Drop lock acquired by ExecOpenIndices */
00971         index_close(indexDescs[i], RowExclusiveLock);
00972     }
00973 
00974     /*
00975      * XXX should free indexInfo array here too?  Currently we assume that
00976      * such stuff will be cleaned up automatically in FreeExecutorState.
00977      */
00978 }
00979 
00980 /* ----------------------------------------------------------------
00981  *      ExecInsertIndexTuples
00982  *
00983  *      This routine takes care of inserting index tuples
00984  *      into all the relations indexing the result relation
00985  *      when a heap tuple is inserted into the result relation.
00986  *      Much of this code should be moved into the genam
00987  *      stuff as it only exists here because the genam stuff
00988  *      doesn't provide the functionality needed by the
00989  *      executor.. -cim 9/27/89
00990  *
00991  *      This returns a list of index OIDs for any unique or exclusion
00992  *      constraints that are deferred and that had
00993  *      potential (unconfirmed) conflicts.
00994  *
00995  *      CAUTION: this must not be called for a HOT update.
00996  *      We can't defend against that here for lack of info.
00997  *      Should we change the API to make it safer?
00998  * ----------------------------------------------------------------
00999  */
01000 List *
01001 ExecInsertIndexTuples(TupleTableSlot *slot,
01002                       ItemPointer tupleid,
01003                       EState *estate)
01004 {
01005     List       *result = NIL;
01006     ResultRelInfo *resultRelInfo;
01007     int         i;
01008     int         numIndices;
01009     RelationPtr relationDescs;
01010     Relation    heapRelation;
01011     IndexInfo **indexInfoArray;
01012     ExprContext *econtext;
01013     Datum       values[INDEX_MAX_KEYS];
01014     bool        isnull[INDEX_MAX_KEYS];
01015 
01016     /*
01017      * Get information from the result relation info structure.
01018      */
01019     resultRelInfo = estate->es_result_relation_info;
01020     numIndices = resultRelInfo->ri_NumIndices;
01021     relationDescs = resultRelInfo->ri_IndexRelationDescs;
01022     indexInfoArray = resultRelInfo->ri_IndexRelationInfo;
01023     heapRelation = resultRelInfo->ri_RelationDesc;
01024 
01025     /*
01026      * We will use the EState's per-tuple context for evaluating predicates
01027      * and index expressions (creating it if it's not already there).
01028      */
01029     econtext = GetPerTupleExprContext(estate);
01030 
01031     /* Arrange for econtext's scan tuple to be the tuple under test */
01032     econtext->ecxt_scantuple = slot;
01033 
01034     /*
01035      * for each index, form and insert the index tuple
01036      */
01037     for (i = 0; i < numIndices; i++)
01038     {
01039         Relation    indexRelation = relationDescs[i];
01040         IndexInfo  *indexInfo;
01041         IndexUniqueCheck checkUnique;
01042         bool        satisfiesConstraint;
01043 
01044         if (indexRelation == NULL)
01045             continue;
01046 
01047         indexInfo = indexInfoArray[i];
01048 
01049         /* If the index is marked as read-only, ignore it */
01050         if (!indexInfo->ii_ReadyForInserts)
01051             continue;
01052 
01053         /* Check for partial index */
01054         if (indexInfo->ii_Predicate != NIL)
01055         {
01056             List       *predicate;
01057 
01058             /*
01059              * If predicate state not set up yet, create it (in the estate's
01060              * per-query context)
01061              */
01062             predicate = indexInfo->ii_PredicateState;
01063             if (predicate == NIL)
01064             {
01065                 predicate = (List *)
01066                     ExecPrepareExpr((Expr *) indexInfo->ii_Predicate,
01067                                     estate);
01068                 indexInfo->ii_PredicateState = predicate;
01069             }
01070 
01071             /* Skip this index-update if the predicate isn't satisfied */
01072             if (!ExecQual(predicate, econtext, false))
01073                 continue;
01074         }
01075 
01076         /*
01077          * FormIndexDatum fills in its values and isnull parameters with the
01078          * appropriate values for the column(s) of the index.
01079          */
01080         FormIndexDatum(indexInfo,
01081                        slot,
01082                        estate,
01083                        values,
01084                        isnull);
01085 
01086         /*
01087          * The index AM does the actual insertion, plus uniqueness checking.
01088          *
01089          * For an immediate-mode unique index, we just tell the index AM to
01090          * throw error if not unique.
01091          *
01092          * For a deferrable unique index, we tell the index AM to just detect
01093          * possible non-uniqueness, and we add the index OID to the result
01094          * list if further checking is needed.
01095          */
01096         if (!indexRelation->rd_index->indisunique)
01097             checkUnique = UNIQUE_CHECK_NO;
01098         else if (indexRelation->rd_index->indimmediate)
01099             checkUnique = UNIQUE_CHECK_YES;
01100         else
01101             checkUnique = UNIQUE_CHECK_PARTIAL;
01102 
01103         satisfiesConstraint =
01104             index_insert(indexRelation, /* index relation */
01105                          values,    /* array of index Datums */
01106                          isnull,    /* null flags */
01107                          tupleid,       /* tid of heap tuple */
01108                          heapRelation,  /* heap relation */
01109                          checkUnique);  /* type of uniqueness check to do */
01110 
01111         /*
01112          * If the index has an associated exclusion constraint, check that.
01113          * This is simpler than the process for uniqueness checks since we
01114          * always insert first and then check.  If the constraint is deferred,
01115          * we check now anyway, but don't throw error on violation; instead
01116          * we'll queue a recheck event.
01117          *
01118          * An index for an exclusion constraint can't also be UNIQUE (not an
01119          * essential property, we just don't allow it in the grammar), so no
01120          * need to preserve the prior state of satisfiesConstraint.
01121          */
01122         if (indexInfo->ii_ExclusionOps != NULL)
01123         {
01124             bool        errorOK = !indexRelation->rd_index->indimmediate;
01125 
01126             satisfiesConstraint =
01127                 check_exclusion_constraint(heapRelation,
01128                                            indexRelation, indexInfo,
01129                                            tupleid, values, isnull,
01130                                            estate, false, errorOK);
01131         }
01132 
01133         if ((checkUnique == UNIQUE_CHECK_PARTIAL ||
01134              indexInfo->ii_ExclusionOps != NULL) &&
01135             !satisfiesConstraint)
01136         {
01137             /*
01138              * The tuple potentially violates the uniqueness or exclusion
01139              * constraint, so make a note of the index so that we can re-check
01140              * it later.
01141              */
01142             result = lappend_oid(result, RelationGetRelid(indexRelation));
01143         }
01144     }
01145 
01146     return result;
01147 }
01148 
01149 /*
01150  * Check for violation of an exclusion constraint
01151  *
01152  * heap: the table containing the new tuple
01153  * index: the index supporting the exclusion constraint
01154  * indexInfo: info about the index, including the exclusion properties
01155  * tupleid: heap TID of the new tuple we have just inserted
01156  * values, isnull: the *index* column values computed for the new tuple
01157  * estate: an EState we can do evaluation in
01158  * newIndex: if true, we are trying to build a new index (this affects
01159  *      only the wording of error messages)
01160  * errorOK: if true, don't throw error for violation
01161  *
01162  * Returns true if OK, false if actual or potential violation
01163  *
01164  * When errorOK is true, we report violation without waiting to see if any
01165  * concurrent transaction has committed or not; so the violation is only
01166  * potential, and the caller must recheck sometime later.  This behavior
01167  * is convenient for deferred exclusion checks; we need not bother queuing
01168  * a deferred event if there is definitely no conflict at insertion time.
01169  *
01170  * When errorOK is false, we'll throw error on violation, so a false result
01171  * is impossible.
01172  */
01173 bool
01174 check_exclusion_constraint(Relation heap, Relation index, IndexInfo *indexInfo,
01175                            ItemPointer tupleid, Datum *values, bool *isnull,
01176                            EState *estate, bool newIndex, bool errorOK)
01177 {
01178     Oid        *constr_procs = indexInfo->ii_ExclusionProcs;
01179     uint16     *constr_strats = indexInfo->ii_ExclusionStrats;
01180     Oid        *index_collations = index->rd_indcollation;
01181     int         index_natts = index->rd_index->indnatts;
01182     IndexScanDesc index_scan;
01183     HeapTuple   tup;
01184     ScanKeyData scankeys[INDEX_MAX_KEYS];
01185     SnapshotData DirtySnapshot;
01186     int         i;
01187     bool        conflict;
01188     bool        found_self;
01189     ExprContext *econtext;
01190     TupleTableSlot *existing_slot;
01191     TupleTableSlot *save_scantuple;
01192 
01193     /*
01194      * If any of the input values are NULL, the constraint check is assumed to
01195      * pass (i.e., we assume the operators are strict).
01196      */
01197     for (i = 0; i < index_natts; i++)
01198     {
01199         if (isnull[i])
01200             return true;
01201     }
01202 
01203     /*
01204      * Search the tuples that are in the index for any violations, including
01205      * tuples that aren't visible yet.
01206      */
01207     InitDirtySnapshot(DirtySnapshot);
01208 
01209     for (i = 0; i < index_natts; i++)
01210     {
01211         ScanKeyEntryInitialize(&scankeys[i],
01212                                0,
01213                                i + 1,
01214                                constr_strats[i],
01215                                InvalidOid,
01216                                index_collations[i],
01217                                constr_procs[i],
01218                                values[i]);
01219     }
01220 
01221     /*
01222      * Need a TupleTableSlot to put existing tuples in.
01223      *
01224      * To use FormIndexDatum, we have to make the econtext's scantuple point
01225      * to this slot.  Be sure to save and restore caller's value for
01226      * scantuple.
01227      */
01228     existing_slot = MakeSingleTupleTableSlot(RelationGetDescr(heap));
01229 
01230     econtext = GetPerTupleExprContext(estate);
01231     save_scantuple = econtext->ecxt_scantuple;
01232     econtext->ecxt_scantuple = existing_slot;
01233 
01234     /*
01235      * May have to restart scan from this point if a potential conflict is
01236      * found.
01237      */
01238 retry:
01239     conflict = false;
01240     found_self = false;
01241     index_scan = index_beginscan(heap, index, &DirtySnapshot, index_natts, 0);
01242     index_rescan(index_scan, scankeys, index_natts, NULL, 0);
01243 
01244     while ((tup = index_getnext(index_scan,
01245                                 ForwardScanDirection)) != NULL)
01246     {
01247         TransactionId xwait;
01248         Datum       existing_values[INDEX_MAX_KEYS];
01249         bool        existing_isnull[INDEX_MAX_KEYS];
01250         char       *error_new;
01251         char       *error_existing;
01252 
01253         /*
01254          * Ignore the entry for the tuple we're trying to check.
01255          */
01256         if (ItemPointerEquals(tupleid, &tup->t_self))
01257         {
01258             if (found_self)     /* should not happen */
01259                 elog(ERROR, "found self tuple multiple times in index \"%s\"",
01260                      RelationGetRelationName(index));
01261             found_self = true;
01262             continue;
01263         }
01264 
01265         /*
01266          * Extract the index column values and isnull flags from the existing
01267          * tuple.
01268          */
01269         ExecStoreTuple(tup, existing_slot, InvalidBuffer, false);
01270         FormIndexDatum(indexInfo, existing_slot, estate,
01271                        existing_values, existing_isnull);
01272 
01273         /* If lossy indexscan, must recheck the condition */
01274         if (index_scan->xs_recheck)
01275         {
01276             if (!index_recheck_constraint(index,
01277                                           constr_procs,
01278                                           existing_values,
01279                                           existing_isnull,
01280                                           values))
01281                 continue;       /* tuple doesn't actually match, so no
01282                                  * conflict */
01283         }
01284 
01285         /*
01286          * At this point we have either a conflict or a potential conflict. If
01287          * we're not supposed to raise error, just return the fact of the
01288          * potential conflict without waiting to see if it's real.
01289          */
01290         if (errorOK)
01291         {
01292             conflict = true;
01293             break;
01294         }
01295 
01296         /*
01297          * If an in-progress transaction is affecting the visibility of this
01298          * tuple, we need to wait for it to complete and then recheck.  For
01299          * simplicity we do rechecking by just restarting the whole scan ---
01300          * this case probably doesn't happen often enough to be worth trying
01301          * harder, and anyway we don't want to hold any index internal locks
01302          * while waiting.
01303          */
01304         xwait = TransactionIdIsValid(DirtySnapshot.xmin) ?
01305             DirtySnapshot.xmin : DirtySnapshot.xmax;
01306 
01307         if (TransactionIdIsValid(xwait))
01308         {
01309             index_endscan(index_scan);
01310             XactLockTableWait(xwait);
01311             goto retry;
01312         }
01313 
01314         /*
01315          * We have a definite conflict.  Report it.
01316          */
01317         error_new = BuildIndexValueDescription(index, values, isnull);
01318         error_existing = BuildIndexValueDescription(index, existing_values,
01319                                                     existing_isnull);
01320         if (newIndex)
01321             ereport(ERROR,
01322                     (errcode(ERRCODE_EXCLUSION_VIOLATION),
01323                      errmsg("could not create exclusion constraint \"%s\"",
01324                             RelationGetRelationName(index)),
01325                      errdetail("Key %s conflicts with key %s.",
01326                                error_new, error_existing),
01327                      errtableconstraint(heap,
01328                                         RelationGetRelationName(index))));
01329         else
01330             ereport(ERROR,
01331                     (errcode(ERRCODE_EXCLUSION_VIOLATION),
01332                      errmsg("conflicting key value violates exclusion constraint \"%s\"",
01333                             RelationGetRelationName(index)),
01334                      errdetail("Key %s conflicts with existing key %s.",
01335                                error_new, error_existing),
01336                      errtableconstraint(heap,
01337                                         RelationGetRelationName(index))));
01338     }
01339 
01340     index_endscan(index_scan);
01341 
01342     /*
01343      * Ordinarily, at this point the search should have found the originally
01344      * inserted tuple, unless we exited the loop early because of conflict.
01345      * However, it is possible to define exclusion constraints for which that
01346      * wouldn't be true --- for instance, if the operator is <>. So we no
01347      * longer complain if found_self is still false.
01348      */
01349 
01350     econtext->ecxt_scantuple = save_scantuple;
01351 
01352     ExecDropSingleTupleTableSlot(existing_slot);
01353 
01354     return !conflict;
01355 }
01356 
01357 /*
01358  * Check existing tuple's index values to see if it really matches the
01359  * exclusion condition against the new_values.  Returns true if conflict.
01360  */
01361 static bool
01362 index_recheck_constraint(Relation index, Oid *constr_procs,
01363                          Datum *existing_values, bool *existing_isnull,
01364                          Datum *new_values)
01365 {
01366     int         index_natts = index->rd_index->indnatts;
01367     int         i;
01368 
01369     for (i = 0; i < index_natts; i++)
01370     {
01371         /* Assume the exclusion operators are strict */
01372         if (existing_isnull[i])
01373             return false;
01374 
01375         if (!DatumGetBool(OidFunctionCall2Coll(constr_procs[i],
01376                                                index->rd_indcollation[i],
01377                                                existing_values[i],
01378                                                new_values[i])))
01379             return false;
01380     }
01381 
01382     return true;
01383 }
01384 
01385 /*
01386  * UpdateChangedParamSet
01387  *      Add changed parameters to a plan node's chgParam set
01388  */
01389 void
01390 UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
01391 {
01392     Bitmapset  *parmset;
01393 
01394     /*
01395      * The plan node only depends on params listed in its allParam set. Don't
01396      * include anything else into its chgParam set.
01397      */
01398     parmset = bms_intersect(node->plan->allParam, newchg);
01399 
01400     /*
01401      * Keep node->chgParam == NULL if there's not actually any members; this
01402      * allows the simplest possible tests in executor node files.
01403      */
01404     if (!bms_is_empty(parmset))
01405         node->chgParam = bms_join(node->chgParam, parmset);
01406     else
01407         bms_free(parmset);
01408 }
01409 
01410 /*
01411  * Register a shutdown callback in an ExprContext.
01412  *
01413  * Shutdown callbacks will be called (in reverse order of registration)
01414  * when the ExprContext is deleted or rescanned.  This provides a hook
01415  * for functions called in the context to do any cleanup needed --- it's
01416  * particularly useful for functions returning sets.  Note that the
01417  * callback will *not* be called in the event that execution is aborted
01418  * by an error.
01419  */
01420 void
01421 RegisterExprContextCallback(ExprContext *econtext,
01422                             ExprContextCallbackFunction function,
01423                             Datum arg)
01424 {
01425     ExprContext_CB *ecxt_callback;
01426 
01427     /* Save the info in appropriate memory context */
01428     ecxt_callback = (ExprContext_CB *)
01429         MemoryContextAlloc(econtext->ecxt_per_query_memory,
01430                            sizeof(ExprContext_CB));
01431 
01432     ecxt_callback->function = function;
01433     ecxt_callback->arg = arg;
01434 
01435     /* link to front of list for appropriate execution order */
01436     ecxt_callback->next = econtext->ecxt_callbacks;
01437     econtext->ecxt_callbacks = ecxt_callback;
01438 }
01439 
01440 /*
01441  * Deregister a shutdown callback in an ExprContext.
01442  *
01443  * Any list entries matching the function and arg will be removed.
01444  * This can be used if it's no longer necessary to call the callback.
01445  */
01446 void
01447 UnregisterExprContextCallback(ExprContext *econtext,
01448                               ExprContextCallbackFunction function,
01449                               Datum arg)
01450 {
01451     ExprContext_CB **prev_callback;
01452     ExprContext_CB *ecxt_callback;
01453 
01454     prev_callback = &econtext->ecxt_callbacks;
01455 
01456     while ((ecxt_callback = *prev_callback) != NULL)
01457     {
01458         if (ecxt_callback->function == function && ecxt_callback->arg == arg)
01459         {
01460             *prev_callback = ecxt_callback->next;
01461             pfree(ecxt_callback);
01462         }
01463         else
01464             prev_callback = &ecxt_callback->next;
01465     }
01466 }
01467 
01468 /*
01469  * Call all the shutdown callbacks registered in an ExprContext.
01470  *
01471  * The callback list is emptied (important in case this is only a rescan
01472  * reset, and not deletion of the ExprContext).
01473  *
01474  * If isCommit is false, just clean the callback list but don't call 'em.
01475  * (See comment for FreeExprContext.)
01476  */
01477 static void
01478 ShutdownExprContext(ExprContext *econtext, bool isCommit)
01479 {
01480     ExprContext_CB *ecxt_callback;
01481     MemoryContext oldcontext;
01482 
01483     /* Fast path in normal case where there's nothing to do. */
01484     if (econtext->ecxt_callbacks == NULL)
01485         return;
01486 
01487     /*
01488      * Call the callbacks in econtext's per-tuple context.  This ensures that
01489      * any memory they might leak will get cleaned up.
01490      */
01491     oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
01492 
01493     /*
01494      * Call each callback function in reverse registration order.
01495      */
01496     while ((ecxt_callback = econtext->ecxt_callbacks) != NULL)
01497     {
01498         econtext->ecxt_callbacks = ecxt_callback->next;
01499         if (isCommit)
01500             (*ecxt_callback->function) (ecxt_callback->arg);
01501         pfree(ecxt_callback);
01502     }
01503 
01504     MemoryContextSwitchTo(oldcontext);
01505 }