Header And Logo

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

plancache.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * plancache.c
00004  *    Plan cache management.
00005  *
00006  * The plan cache manager has two principal responsibilities: deciding when
00007  * to use a generic plan versus a custom (parameter-value-specific) plan,
00008  * and tracking whether cached plans need to be invalidated because of schema
00009  * changes in the objects they depend on.
00010  *
00011  * The logic for choosing generic or custom plans is in choose_custom_plan,
00012  * which see for comments.
00013  *
00014  * Cache invalidation is driven off sinval events.  Any CachedPlanSource
00015  * that matches the event is marked invalid, as is its generic CachedPlan
00016  * if it has one.  When (and if) the next demand for a cached plan occurs,
00017  * parse analysis and rewrite is repeated to build a new valid query tree,
00018  * and then planning is performed as normal.  We also force re-analysis and
00019  * re-planning if the active search_path is different from the previous time.
00020  *
00021  * Note that if the sinval was a result of user DDL actions, parse analysis
00022  * could throw an error, for example if a column referenced by the query is
00023  * no longer present.  Another possibility is for the query's output tupdesc
00024  * to change (for instance "SELECT *" might expand differently than before).
00025  * The creator of a cached plan can specify whether it is allowable for the
00026  * query to change output tupdesc on replan --- if so, it's up to the
00027  * caller to notice changes and cope with them.
00028  *
00029  * Currently, we track exactly the dependencies of plans on relations and
00030  * user-defined functions.  On relcache invalidation events or pg_proc
00031  * syscache invalidation events, we invalidate just those plans that depend
00032  * on the particular object being modified.  (Note: this scheme assumes
00033  * that any table modification that requires replanning will generate a
00034  * relcache inval event.)  We also watch for inval events on certain other
00035  * system catalogs, such as pg_namespace; but for them, our response is
00036  * just to invalidate all plans.  We expect updates on those catalogs to
00037  * be infrequent enough that more-detailed tracking is not worth the effort.
00038  *
00039  *
00040  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00041  * Portions Copyright (c) 1994, Regents of the University of California
00042  *
00043  * IDENTIFICATION
00044  *    src/backend/utils/cache/plancache.c
00045  *
00046  *-------------------------------------------------------------------------
00047  */
00048 #include "postgres.h"
00049 
00050 #include <limits.h>
00051 
00052 #include "access/transam.h"
00053 #include "catalog/namespace.h"
00054 #include "executor/executor.h"
00055 #include "executor/spi.h"
00056 #include "nodes/nodeFuncs.h"
00057 #include "optimizer/planmain.h"
00058 #include "optimizer/prep.h"
00059 #include "parser/analyze.h"
00060 #include "parser/parsetree.h"
00061 #include "storage/lmgr.h"
00062 #include "tcop/pquery.h"
00063 #include "tcop/utility.h"
00064 #include "utils/inval.h"
00065 #include "utils/memutils.h"
00066 #include "utils/resowner_private.h"
00067 #include "utils/snapmgr.h"
00068 #include "utils/syscache.h"
00069 
00070 
00071 /*
00072  * We must skip "overhead" operations that involve database access when the
00073  * cached plan's subject statement is a transaction control command.
00074  */
00075 #define IsTransactionStmtPlan(plansource)  \
00076     ((plansource)->raw_parse_tree && \
00077      IsA((plansource)->raw_parse_tree, TransactionStmt))
00078 
00079 /*
00080  * This is the head of the backend's list of "saved" CachedPlanSources (i.e.,
00081  * those that are in long-lived storage and are examined for sinval events).
00082  * We thread the structs manually instead of using List cells so that we can
00083  * guarantee to save a CachedPlanSource without error.
00084  */
00085 static CachedPlanSource *first_saved_plan = NULL;
00086 
00087 static void ReleaseGenericPlan(CachedPlanSource *plansource);
00088 static List *RevalidateCachedQuery(CachedPlanSource *plansource);
00089 static bool CheckCachedPlan(CachedPlanSource *plansource);
00090 static CachedPlan *BuildCachedPlan(CachedPlanSource *plansource, List *qlist,
00091                 ParamListInfo boundParams);
00092 static bool choose_custom_plan(CachedPlanSource *plansource,
00093                    ParamListInfo boundParams);
00094 static double cached_plan_cost(CachedPlan *plan);
00095 static void AcquireExecutorLocks(List *stmt_list, bool acquire);
00096 static void AcquirePlannerLocks(List *stmt_list, bool acquire);
00097 static void ScanQueryForLocks(Query *parsetree, bool acquire);
00098 static bool ScanQueryWalker(Node *node, bool *acquire);
00099 static bool plan_list_is_transient(List *stmt_list);
00100 static TupleDesc PlanCacheComputeResultDesc(List *stmt_list);
00101 static void PlanCacheRelCallback(Datum arg, Oid relid);
00102 static void PlanCacheFuncCallback(Datum arg, int cacheid, uint32 hashvalue);
00103 static void PlanCacheSysCallback(Datum arg, int cacheid, uint32 hashvalue);
00104 
00105 
00106 /*
00107  * InitPlanCache: initialize module during InitPostgres.
00108  *
00109  * All we need to do is hook into inval.c's callback lists.
00110  */
00111 void
00112 InitPlanCache(void)
00113 {
00114     CacheRegisterRelcacheCallback(PlanCacheRelCallback, (Datum) 0);
00115     CacheRegisterSyscacheCallback(PROCOID, PlanCacheFuncCallback, (Datum) 0);
00116     CacheRegisterSyscacheCallback(NAMESPACEOID, PlanCacheSysCallback, (Datum) 0);
00117     CacheRegisterSyscacheCallback(OPEROID, PlanCacheSysCallback, (Datum) 0);
00118     CacheRegisterSyscacheCallback(AMOPOPID, PlanCacheSysCallback, (Datum) 0);
00119 }
00120 
00121 /*
00122  * CreateCachedPlan: initially create a plan cache entry.
00123  *
00124  * Creation of a cached plan is divided into two steps, CreateCachedPlan and
00125  * CompleteCachedPlan.  CreateCachedPlan should be called after running the
00126  * query through raw_parser, but before doing parse analysis and rewrite;
00127  * CompleteCachedPlan is called after that.  The reason for this arrangement
00128  * is that it can save one round of copying of the raw parse tree, since
00129  * the parser will normally scribble on the raw parse tree.  Callers would
00130  * otherwise need to make an extra copy of the parse tree to ensure they
00131  * still had a clean copy to present at plan cache creation time.
00132  *
00133  * All arguments presented to CreateCachedPlan are copied into a memory
00134  * context created as a child of the call-time CurrentMemoryContext, which
00135  * should be a reasonably short-lived working context that will go away in
00136  * event of an error.  This ensures that the cached plan data structure will
00137  * likewise disappear if an error occurs before we have fully constructed it.
00138  * Once constructed, the cached plan can be made longer-lived, if needed,
00139  * by calling SaveCachedPlan.
00140  *
00141  * raw_parse_tree: output of raw_parser()
00142  * query_string: original query text
00143  * commandTag: compile-time-constant tag for query, or NULL if empty query
00144  */
00145 CachedPlanSource *
00146 CreateCachedPlan(Node *raw_parse_tree,
00147                  const char *query_string,
00148                  const char *commandTag)
00149 {
00150     CachedPlanSource *plansource;
00151     MemoryContext source_context;
00152     MemoryContext oldcxt;
00153 
00154     Assert(query_string != NULL);       /* required as of 8.4 */
00155 
00156     /*
00157      * Make a dedicated memory context for the CachedPlanSource and its
00158      * permanent subsidiary data.  It's probably not going to be large, but
00159      * just in case, use the default maxsize parameter.  Initially it's a
00160      * child of the caller's context (which we assume to be transient), so
00161      * that it will be cleaned up on error.
00162      */
00163     source_context = AllocSetContextCreate(CurrentMemoryContext,
00164                                            "CachedPlanSource",
00165                                            ALLOCSET_SMALL_MINSIZE,
00166                                            ALLOCSET_SMALL_INITSIZE,
00167                                            ALLOCSET_DEFAULT_MAXSIZE);
00168 
00169     /*
00170      * Create and fill the CachedPlanSource struct within the new context.
00171      * Most fields are just left empty for the moment.
00172      */
00173     oldcxt = MemoryContextSwitchTo(source_context);
00174 
00175     plansource = (CachedPlanSource *) palloc0(sizeof(CachedPlanSource));
00176     plansource->magic = CACHEDPLANSOURCE_MAGIC;
00177     plansource->raw_parse_tree = copyObject(raw_parse_tree);
00178     plansource->query_string = pstrdup(query_string);
00179     plansource->commandTag = commandTag;
00180     plansource->param_types = NULL;
00181     plansource->num_params = 0;
00182     plansource->parserSetup = NULL;
00183     plansource->parserSetupArg = NULL;
00184     plansource->cursor_options = 0;
00185     plansource->fixed_result = false;
00186     plansource->resultDesc = NULL;
00187     plansource->context = source_context;
00188     plansource->query_list = NIL;
00189     plansource->relationOids = NIL;
00190     plansource->invalItems = NIL;
00191     plansource->search_path = NULL;
00192     plansource->query_context = NULL;
00193     plansource->gplan = NULL;
00194     plansource->is_oneshot = false;
00195     plansource->is_complete = false;
00196     plansource->is_saved = false;
00197     plansource->is_valid = false;
00198     plansource->generation = 0;
00199     plansource->next_saved = NULL;
00200     plansource->generic_cost = -1;
00201     plansource->total_custom_cost = 0;
00202     plansource->num_custom_plans = 0;
00203 
00204     MemoryContextSwitchTo(oldcxt);
00205 
00206     return plansource;
00207 }
00208 
00209 /*
00210  * CreateOneShotCachedPlan: initially create a one-shot plan cache entry.
00211  *
00212  * This variant of CreateCachedPlan creates a plan cache entry that is meant
00213  * to be used only once.  No data copying occurs: all data structures remain
00214  * in the caller's memory context (which typically should get cleared after
00215  * completing execution).  The CachedPlanSource struct itself is also created
00216  * in that context.
00217  *
00218  * A one-shot plan cannot be saved or copied, since we make no effort to
00219  * preserve the raw parse tree unmodified.  There is also no support for
00220  * invalidation, so plan use must be completed in the current transaction,
00221  * and DDL that might invalidate the querytree_list must be avoided as well.
00222  *
00223  * raw_parse_tree: output of raw_parser()
00224  * query_string: original query text
00225  * commandTag: compile-time-constant tag for query, or NULL if empty query
00226  */
00227 CachedPlanSource *
00228 CreateOneShotCachedPlan(Node *raw_parse_tree,
00229                         const char *query_string,
00230                         const char *commandTag)
00231 {
00232     CachedPlanSource *plansource;
00233 
00234     Assert(query_string != NULL);       /* required as of 8.4 */
00235 
00236     /*
00237      * Create and fill the CachedPlanSource struct within the caller's memory
00238      * context.  Most fields are just left empty for the moment.
00239      */
00240     plansource = (CachedPlanSource *) palloc0(sizeof(CachedPlanSource));
00241     plansource->magic = CACHEDPLANSOURCE_MAGIC;
00242     plansource->raw_parse_tree = raw_parse_tree;
00243     plansource->query_string = query_string;
00244     plansource->commandTag = commandTag;
00245     plansource->param_types = NULL;
00246     plansource->num_params = 0;
00247     plansource->parserSetup = NULL;
00248     plansource->parserSetupArg = NULL;
00249     plansource->cursor_options = 0;
00250     plansource->fixed_result = false;
00251     plansource->resultDesc = NULL;
00252     plansource->context = CurrentMemoryContext;
00253     plansource->query_list = NIL;
00254     plansource->relationOids = NIL;
00255     plansource->invalItems = NIL;
00256     plansource->search_path = NULL;
00257     plansource->query_context = NULL;
00258     plansource->gplan = NULL;
00259     plansource->is_oneshot = true;
00260     plansource->is_complete = false;
00261     plansource->is_saved = false;
00262     plansource->is_valid = false;
00263     plansource->generation = 0;
00264     plansource->next_saved = NULL;
00265     plansource->generic_cost = -1;
00266     plansource->total_custom_cost = 0;
00267     plansource->num_custom_plans = 0;
00268 
00269     return plansource;
00270 }
00271 
00272 /*
00273  * CompleteCachedPlan: second step of creating a plan cache entry.
00274  *
00275  * Pass in the analyzed-and-rewritten form of the query, as well as the
00276  * required subsidiary data about parameters and such.  All passed values will
00277  * be copied into the CachedPlanSource's memory, except as specified below.
00278  * After this is called, GetCachedPlan can be called to obtain a plan, and
00279  * optionally the CachedPlanSource can be saved using SaveCachedPlan.
00280  *
00281  * If querytree_context is not NULL, the querytree_list must be stored in that
00282  * context (but the other parameters need not be).  The querytree_list is not
00283  * copied, rather the given context is kept as the initial query_context of
00284  * the CachedPlanSource.  (It should have been created as a child of the
00285  * caller's working memory context, but it will now be reparented to belong
00286  * to the CachedPlanSource.)  The querytree_context is normally the context in
00287  * which the caller did raw parsing and parse analysis.  This approach saves
00288  * one tree copying step compared to passing NULL, but leaves lots of extra
00289  * cruft in the query_context, namely whatever extraneous stuff parse analysis
00290  * created, as well as whatever went unused from the raw parse tree.  Using
00291  * this option is a space-for-time tradeoff that is appropriate if the
00292  * CachedPlanSource is not expected to survive long.
00293  *
00294  * plancache.c cannot know how to copy the data referenced by parserSetupArg,
00295  * and it would often be inappropriate to do so anyway.  When using that
00296  * option, it is caller's responsibility that the referenced data remains
00297  * valid for as long as the CachedPlanSource exists.
00298  *
00299  * If the CachedPlanSource is a "oneshot" plan, then no querytree copying
00300  * occurs at all, and querytree_context is ignored; it is caller's
00301  * responsibility that the passed querytree_list is sufficiently long-lived.
00302  *
00303  * plansource: structure returned by CreateCachedPlan
00304  * querytree_list: analyzed-and-rewritten form of query (list of Query nodes)
00305  * querytree_context: memory context containing querytree_list,
00306  *                    or NULL to copy querytree_list into a fresh context
00307  * param_types: array of fixed parameter type OIDs, or NULL if none
00308  * num_params: number of fixed parameters
00309  * parserSetup: alternate method for handling query parameters
00310  * parserSetupArg: data to pass to parserSetup
00311  * cursor_options: options bitmask to pass to planner
00312  * fixed_result: TRUE to disallow future changes in query's result tupdesc
00313  */
00314 void
00315 CompleteCachedPlan(CachedPlanSource *plansource,
00316                    List *querytree_list,
00317                    MemoryContext querytree_context,
00318                    Oid *param_types,
00319                    int num_params,
00320                    ParserSetupHook parserSetup,
00321                    void *parserSetupArg,
00322                    int cursor_options,
00323                    bool fixed_result)
00324 {
00325     MemoryContext source_context = plansource->context;
00326     MemoryContext oldcxt = CurrentMemoryContext;
00327 
00328     /* Assert caller is doing things in a sane order */
00329     Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
00330     Assert(!plansource->is_complete);
00331 
00332     /*
00333      * If caller supplied a querytree_context, reparent it underneath the
00334      * CachedPlanSource's context; otherwise, create a suitable context and
00335      * copy the querytree_list into it.  But no data copying should be done
00336      * for one-shot plans; for those, assume the passed querytree_list is
00337      * sufficiently long-lived.
00338      */
00339     if (plansource->is_oneshot)
00340     {
00341         querytree_context = CurrentMemoryContext;
00342     }
00343     else if (querytree_context != NULL)
00344     {
00345         MemoryContextSetParent(querytree_context, source_context);
00346         MemoryContextSwitchTo(querytree_context);
00347     }
00348     else
00349     {
00350         /* Again, it's a good bet the querytree_context can be small */
00351         querytree_context = AllocSetContextCreate(source_context,
00352                                                   "CachedPlanQuery",
00353                                                   ALLOCSET_SMALL_MINSIZE,
00354                                                   ALLOCSET_SMALL_INITSIZE,
00355                                                   ALLOCSET_DEFAULT_MAXSIZE);
00356         MemoryContextSwitchTo(querytree_context);
00357         querytree_list = (List *) copyObject(querytree_list);
00358     }
00359 
00360     plansource->query_context = querytree_context;
00361     plansource->query_list = querytree_list;
00362 
00363     if (!plansource->is_oneshot && !IsTransactionStmtPlan(plansource))
00364     {
00365         /*
00366          * Use the planner machinery to extract dependencies.  Data is saved
00367          * in query_context.  (We assume that not a lot of extra cruft is
00368          * created by this call.)  We can skip this for one-shot plans, and
00369          * transaction control commands have no such dependencies anyway.
00370          */
00371         extract_query_dependencies((Node *) querytree_list,
00372                                    &plansource->relationOids,
00373                                    &plansource->invalItems);
00374 
00375         /*
00376          * Also save the current search_path in the query_context.  (This
00377          * should not generate much extra cruft either, since almost certainly
00378          * the path is already valid.)  Again, we don't really need this for
00379          * one-shot plans; and we *must* skip this for transaction control
00380          * commands, because this could result in catalog accesses.
00381          */
00382         plansource->search_path = GetOverrideSearchPath(querytree_context);
00383     }
00384 
00385     /*
00386      * Save the final parameter types (or other parameter specification data)
00387      * into the source_context, as well as our other parameters.  Also save
00388      * the result tuple descriptor.
00389      */
00390     MemoryContextSwitchTo(source_context);
00391 
00392     if (num_params > 0)
00393     {
00394         plansource->param_types = (Oid *) palloc(num_params * sizeof(Oid));
00395         memcpy(plansource->param_types, param_types, num_params * sizeof(Oid));
00396     }
00397     else
00398         plansource->param_types = NULL;
00399     plansource->num_params = num_params;
00400     plansource->parserSetup = parserSetup;
00401     plansource->parserSetupArg = parserSetupArg;
00402     plansource->cursor_options = cursor_options;
00403     plansource->fixed_result = fixed_result;
00404     plansource->resultDesc = PlanCacheComputeResultDesc(querytree_list);
00405 
00406     MemoryContextSwitchTo(oldcxt);
00407 
00408     plansource->is_complete = true;
00409     plansource->is_valid = true;
00410 }
00411 
00412 /*
00413  * SaveCachedPlan: save a cached plan permanently
00414  *
00415  * This function moves the cached plan underneath CacheMemoryContext (making
00416  * it live for the life of the backend, unless explicitly dropped), and adds
00417  * it to the list of cached plans that are checked for invalidation when an
00418  * sinval event occurs.
00419  *
00420  * This is guaranteed not to throw error, except for the caller-error case
00421  * of trying to save a one-shot plan.  Callers typically depend on that
00422  * since this is called just before or just after adding a pointer to the
00423  * CachedPlanSource to some permanent data structure of their own.  Up until
00424  * this is done, a CachedPlanSource is just transient data that will go away
00425  * automatically on transaction abort.
00426  */
00427 void
00428 SaveCachedPlan(CachedPlanSource *plansource)
00429 {
00430     /* Assert caller is doing things in a sane order */
00431     Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
00432     Assert(plansource->is_complete);
00433     Assert(!plansource->is_saved);
00434 
00435     /* This seems worth a real test, though */
00436     if (plansource->is_oneshot)
00437         elog(ERROR, "cannot save one-shot cached plan");
00438 
00439     /*
00440      * In typical use, this function would be called before generating any
00441      * plans from the CachedPlanSource.  If there is a generic plan, moving it
00442      * into CacheMemoryContext would be pretty risky since it's unclear
00443      * whether the caller has taken suitable care with making references
00444      * long-lived.  Best thing to do seems to be to discard the plan.
00445      */
00446     ReleaseGenericPlan(plansource);
00447 
00448     /*
00449      * Reparent the source memory context under CacheMemoryContext so that it
00450      * will live indefinitely.  The query_context follows along since it's
00451      * already a child of the other one.
00452      */
00453     MemoryContextSetParent(plansource->context, CacheMemoryContext);
00454 
00455     /*
00456      * Add the entry to the global list of cached plans.
00457      */
00458     plansource->next_saved = first_saved_plan;
00459     first_saved_plan = plansource;
00460 
00461     plansource->is_saved = true;
00462 }
00463 
00464 /*
00465  * DropCachedPlan: destroy a cached plan.
00466  *
00467  * Actually this only destroys the CachedPlanSource: any referenced CachedPlan
00468  * is released, but not destroyed until its refcount goes to zero.  That
00469  * handles the situation where DropCachedPlan is called while the plan is
00470  * still in use.
00471  */
00472 void
00473 DropCachedPlan(CachedPlanSource *plansource)
00474 {
00475     Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
00476 
00477     /* If it's been saved, remove it from the list */
00478     if (plansource->is_saved)
00479     {
00480         if (first_saved_plan == plansource)
00481             first_saved_plan = plansource->next_saved;
00482         else
00483         {
00484             CachedPlanSource *psrc;
00485 
00486             for (psrc = first_saved_plan; psrc; psrc = psrc->next_saved)
00487             {
00488                 if (psrc->next_saved == plansource)
00489                 {
00490                     psrc->next_saved = plansource->next_saved;
00491                     break;
00492                 }
00493             }
00494         }
00495         plansource->is_saved = false;
00496     }
00497 
00498     /* Decrement generic CachePlan's refcount and drop if no longer needed */
00499     ReleaseGenericPlan(plansource);
00500 
00501     /* Mark it no longer valid */
00502     plansource->magic = 0;
00503 
00504     /*
00505      * Remove the CachedPlanSource and all subsidiary data (including the
00506      * query_context if any).  But if it's a one-shot we can't free anything.
00507      */
00508     if (!plansource->is_oneshot)
00509         MemoryContextDelete(plansource->context);
00510 }
00511 
00512 /*
00513  * ReleaseGenericPlan: release a CachedPlanSource's generic plan, if any.
00514  */
00515 static void
00516 ReleaseGenericPlan(CachedPlanSource *plansource)
00517 {
00518     /* Be paranoid about the possibility that ReleaseCachedPlan fails */
00519     if (plansource->gplan)
00520     {
00521         CachedPlan *plan = plansource->gplan;
00522 
00523         Assert(plan->magic == CACHEDPLAN_MAGIC);
00524         plansource->gplan = NULL;
00525         ReleaseCachedPlan(plan, false);
00526     }
00527 }
00528 
00529 /*
00530  * RevalidateCachedQuery: ensure validity of analyzed-and-rewritten query tree.
00531  *
00532  * What we do here is re-acquire locks and redo parse analysis if necessary.
00533  * On return, the query_list is valid and we have sufficient locks to begin
00534  * planning.
00535  *
00536  * If any parse analysis activity is required, the caller's memory context is
00537  * used for that work.
00538  *
00539  * The result value is the transient analyzed-and-rewritten query tree if we
00540  * had to do re-analysis, and NIL otherwise.  (This is returned just to save
00541  * a tree copying step in a subsequent BuildCachedPlan call.)
00542  */
00543 static List *
00544 RevalidateCachedQuery(CachedPlanSource *plansource)
00545 {
00546     bool        snapshot_set;
00547     Node       *rawtree;
00548     List       *tlist;          /* transient query-tree list */
00549     List       *qlist;          /* permanent query-tree list */
00550     TupleDesc   resultDesc;
00551     MemoryContext querytree_context;
00552     MemoryContext oldcxt;
00553 
00554     /*
00555      * For one-shot plans, we do not support revalidation checking; it's
00556      * assumed the query is parsed, planned, and executed in one transaction,
00557      * so that no lock re-acquisition is necessary.  Also, there is never
00558      * any need to revalidate plans for transaction control commands (and
00559      * we mustn't risk any catalog accesses when handling those).
00560      */
00561     if (plansource->is_oneshot || IsTransactionStmtPlan(plansource))
00562     {
00563         Assert(plansource->is_valid);
00564         return NIL;
00565     }
00566 
00567     /*
00568      * If the query is currently valid, we should have a saved search_path ---
00569      * check to see if that matches the current environment.  If not, we want
00570      * to force replan.
00571      */
00572     if (plansource->is_valid)
00573     {
00574         Assert(plansource->search_path != NULL);
00575         if (!OverrideSearchPathMatchesCurrent(plansource->search_path))
00576         {
00577             /* Invalidate the querytree and generic plan */
00578             plansource->is_valid = false;
00579             if (plansource->gplan)
00580                 plansource->gplan->is_valid = false;
00581         }
00582     }
00583 
00584     /*
00585      * If the query is currently valid, acquire locks on the referenced
00586      * objects; then check again.  We need to do it this way to cover the race
00587      * condition that an invalidation message arrives before we get the locks.
00588      */
00589     if (plansource->is_valid)
00590     {
00591         AcquirePlannerLocks(plansource->query_list, true);
00592 
00593         /*
00594          * By now, if any invalidation has happened, the inval callback
00595          * functions will have marked the query invalid.
00596          */
00597         if (plansource->is_valid)
00598         {
00599             /* Successfully revalidated and locked the query. */
00600             return NIL;
00601         }
00602 
00603         /* Ooops, the race case happened.  Release useless locks. */
00604         AcquirePlannerLocks(plansource->query_list, false);
00605     }
00606 
00607     /*
00608      * Discard the no-longer-useful query tree.  (Note: we don't want to do
00609      * this any earlier, else we'd not have been able to release locks
00610      * correctly in the race condition case.)
00611      */
00612     plansource->is_valid = false;
00613     plansource->query_list = NIL;
00614     plansource->relationOids = NIL;
00615     plansource->invalItems = NIL;
00616     plansource->search_path = NULL;
00617 
00618     /*
00619      * Free the query_context.  We don't really expect MemoryContextDelete to
00620      * fail, but just in case, make sure the CachedPlanSource is left in a
00621      * reasonably sane state.  (The generic plan won't get unlinked yet, but
00622      * that's acceptable.)
00623      */
00624     if (plansource->query_context)
00625     {
00626         MemoryContext qcxt = plansource->query_context;
00627 
00628         plansource->query_context = NULL;
00629         MemoryContextDelete(qcxt);
00630     }
00631 
00632     /* Drop the generic plan reference if any */
00633     ReleaseGenericPlan(plansource);
00634 
00635     /*
00636      * Now re-do parse analysis and rewrite.  This not incidentally acquires
00637      * the locks we need to do planning safely.
00638      */
00639     Assert(plansource->is_complete);
00640 
00641     /*
00642      * If a snapshot is already set (the normal case), we can just use that
00643      * for parsing/planning.  But if it isn't, install one.  Note: no point in
00644      * checking whether parse analysis requires a snapshot; utility commands
00645      * don't have invalidatable plans, so we'd not get here for such a
00646      * command.
00647      */
00648     snapshot_set = false;
00649     if (!ActiveSnapshotSet())
00650     {
00651         PushActiveSnapshot(GetTransactionSnapshot());
00652         snapshot_set = true;
00653     }
00654 
00655     /*
00656      * Run parse analysis and rule rewriting.  The parser tends to scribble on
00657      * its input, so we must copy the raw parse tree to prevent corruption of
00658      * the cache.
00659      */
00660     rawtree = copyObject(plansource->raw_parse_tree);
00661     if (plansource->parserSetup != NULL)
00662         tlist = pg_analyze_and_rewrite_params(rawtree,
00663                                               plansource->query_string,
00664                                               plansource->parserSetup,
00665                                               plansource->parserSetupArg);
00666     else
00667         tlist = pg_analyze_and_rewrite(rawtree,
00668                                        plansource->query_string,
00669                                        plansource->param_types,
00670                                        plansource->num_params);
00671 
00672     /* Release snapshot if we got one */
00673     if (snapshot_set)
00674         PopActiveSnapshot();
00675 
00676     /*
00677      * Check or update the result tupdesc.  XXX should we use a weaker
00678      * condition than equalTupleDescs() here?
00679      *
00680      * We assume the parameter types didn't change from the first time, so no
00681      * need to update that.
00682      */
00683     resultDesc = PlanCacheComputeResultDesc(tlist);
00684     if (resultDesc == NULL && plansource->resultDesc == NULL)
00685     {
00686         /* OK, doesn't return tuples */
00687     }
00688     else if (resultDesc == NULL || plansource->resultDesc == NULL ||
00689              !equalTupleDescs(resultDesc, plansource->resultDesc))
00690     {
00691         /* can we give a better error message? */
00692         if (plansource->fixed_result)
00693             ereport(ERROR,
00694                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
00695                      errmsg("cached plan must not change result type")));
00696         oldcxt = MemoryContextSwitchTo(plansource->context);
00697         if (resultDesc)
00698             resultDesc = CreateTupleDescCopy(resultDesc);
00699         if (plansource->resultDesc)
00700             FreeTupleDesc(plansource->resultDesc);
00701         plansource->resultDesc = resultDesc;
00702         MemoryContextSwitchTo(oldcxt);
00703     }
00704 
00705     /*
00706      * Allocate new query_context and copy the completed querytree into it.
00707      * It's transient until we complete the copying and dependency extraction.
00708      */
00709     querytree_context = AllocSetContextCreate(CurrentMemoryContext,
00710                                               "CachedPlanQuery",
00711                                               ALLOCSET_SMALL_MINSIZE,
00712                                               ALLOCSET_SMALL_INITSIZE,
00713                                               ALLOCSET_DEFAULT_MAXSIZE);
00714     oldcxt = MemoryContextSwitchTo(querytree_context);
00715 
00716     qlist = (List *) copyObject(tlist);
00717 
00718     /*
00719      * Use the planner machinery to extract dependencies.  Data is saved in
00720      * query_context.  (We assume that not a lot of extra cruft is created by
00721      * this call.)
00722      */
00723     extract_query_dependencies((Node *) qlist,
00724                                &plansource->relationOids,
00725                                &plansource->invalItems);
00726 
00727     /*
00728      * Also save the current search_path in the query_context.  (This should
00729      * not generate much extra cruft either, since almost certainly the path
00730      * is already valid.)
00731      */
00732     plansource->search_path = GetOverrideSearchPath(querytree_context);
00733 
00734     MemoryContextSwitchTo(oldcxt);
00735 
00736     /* Now reparent the finished query_context and save the links */
00737     MemoryContextSetParent(querytree_context, plansource->context);
00738 
00739     plansource->query_context = querytree_context;
00740     plansource->query_list = qlist;
00741 
00742     /*
00743      * Note: we do not reset generic_cost or total_custom_cost, although we
00744      * could choose to do so.  If the DDL or statistics change that prompted
00745      * the invalidation meant a significant change in the cost estimates, it
00746      * would be better to reset those variables and start fresh; but often it
00747      * doesn't, and we're better retaining our hard-won knowledge about the
00748      * relative costs.
00749      */
00750 
00751     plansource->is_valid = true;
00752 
00753     /* Return transient copy of querytrees for possible use in planning */
00754     return tlist;
00755 }
00756 
00757 /*
00758  * CheckCachedPlan: see if the CachedPlanSource's generic plan is valid.
00759  *
00760  * Caller must have already called RevalidateCachedQuery to verify that the
00761  * querytree is up to date.
00762  *
00763  * On a "true" return, we have acquired the locks needed to run the plan.
00764  * (We must do this for the "true" result to be race-condition-free.)
00765  */
00766 static bool
00767 CheckCachedPlan(CachedPlanSource *plansource)
00768 {
00769     CachedPlan *plan = plansource->gplan;
00770 
00771     /* Assert that caller checked the querytree */
00772     Assert(plansource->is_valid);
00773 
00774     /* If there's no generic plan, just say "false" */
00775     if (!plan)
00776         return false;
00777 
00778     Assert(plan->magic == CACHEDPLAN_MAGIC);
00779     /* Generic plans are never one-shot */
00780     Assert(!plan->is_oneshot);
00781 
00782     /*
00783      * If it appears valid, acquire locks and recheck; this is much the same
00784      * logic as in RevalidateCachedQuery, but for a plan.
00785      */
00786     if (plan->is_valid)
00787     {
00788         /*
00789          * Plan must have positive refcount because it is referenced by
00790          * plansource; so no need to fear it disappears under us here.
00791          */
00792         Assert(plan->refcount > 0);
00793 
00794         AcquireExecutorLocks(plan->stmt_list, true);
00795 
00796         /*
00797          * If plan was transient, check to see if TransactionXmin has
00798          * advanced, and if so invalidate it.
00799          */
00800         if (plan->is_valid &&
00801             TransactionIdIsValid(plan->saved_xmin) &&
00802             !TransactionIdEquals(plan->saved_xmin, TransactionXmin))
00803             plan->is_valid = false;
00804 
00805         /*
00806          * By now, if any invalidation has happened, the inval callback
00807          * functions will have marked the plan invalid.
00808          */
00809         if (plan->is_valid)
00810         {
00811             /* Successfully revalidated and locked the query. */
00812             return true;
00813         }
00814 
00815         /* Ooops, the race case happened.  Release useless locks. */
00816         AcquireExecutorLocks(plan->stmt_list, false);
00817     }
00818 
00819     /*
00820      * Plan has been invalidated, so unlink it from the parent and release it.
00821      */
00822     ReleaseGenericPlan(plansource);
00823 
00824     return false;
00825 }
00826 
00827 /*
00828  * BuildCachedPlan: construct a new CachedPlan from a CachedPlanSource.
00829  *
00830  * qlist should be the result value from a previous RevalidateCachedQuery,
00831  * or it can be set to NIL if we need to re-copy the plansource's query_list.
00832  *
00833  * To build a generic, parameter-value-independent plan, pass NULL for
00834  * boundParams.  To build a custom plan, pass the actual parameter values via
00835  * boundParams.  For best effect, the PARAM_FLAG_CONST flag should be set on
00836  * each parameter value; otherwise the planner will treat the value as a
00837  * hint rather than a hard constant.
00838  *
00839  * Planning work is done in the caller's memory context.  The finished plan
00840  * is in a child memory context, which typically should get reparented
00841  * (unless this is a one-shot plan, in which case we don't copy the plan).
00842  */
00843 static CachedPlan *
00844 BuildCachedPlan(CachedPlanSource *plansource, List *qlist,
00845                 ParamListInfo boundParams)
00846 {
00847     CachedPlan *plan;
00848     List       *plist;
00849     bool        snapshot_set;
00850     bool        spi_pushed;
00851     MemoryContext plan_context;
00852     MemoryContext oldcxt = CurrentMemoryContext;
00853 
00854     /*
00855      * Normally the querytree should be valid already, but if it's not,
00856      * rebuild it.
00857      *
00858      * NOTE: GetCachedPlan should have called RevalidateCachedQuery first, so
00859      * we ought to be holding sufficient locks to prevent any invalidation.
00860      * However, if we're building a custom plan after having built and
00861      * rejected a generic plan, it's possible to reach here with is_valid
00862      * false due to an invalidation while making the generic plan.  In theory
00863      * the invalidation must be a false positive, perhaps a consequence of an
00864      * sinval reset event or the CLOBBER_CACHE_ALWAYS debug code.  But for
00865      * safety, let's treat it as real and redo the RevalidateCachedQuery call.
00866      */
00867     if (!plansource->is_valid)
00868         qlist = RevalidateCachedQuery(plansource);
00869 
00870     /*
00871      * If we don't already have a copy of the querytree list that can be
00872      * scribbled on by the planner, make one.  For a one-shot plan, we assume
00873      * it's okay to scribble on the original query_list.
00874      */
00875     if (qlist == NIL)
00876     {
00877         if (!plansource->is_oneshot)
00878             qlist = (List *) copyObject(plansource->query_list);
00879         else
00880             qlist = plansource->query_list;
00881     }
00882 
00883     /*
00884      * If a snapshot is already set (the normal case), we can just use that
00885      * for planning.  But if it isn't, and we need one, install one.
00886      */
00887     snapshot_set = false;
00888     if (!ActiveSnapshotSet() &&
00889         analyze_requires_snapshot(plansource->raw_parse_tree))
00890     {
00891         PushActiveSnapshot(GetTransactionSnapshot());
00892         snapshot_set = true;
00893     }
00894 
00895     /*
00896      * The planner may try to call SPI-using functions, which causes a problem
00897      * if we're already inside one.  Rather than expect all SPI-using code to
00898      * do SPI_push whenever a replan could happen, it seems best to take care
00899      * of the case here.
00900      */
00901     spi_pushed = SPI_push_conditional();
00902 
00903     /*
00904      * Generate the plan.
00905      */
00906     plist = pg_plan_queries(qlist, plansource->cursor_options, boundParams);
00907 
00908     /* Clean up SPI state */
00909     SPI_pop_conditional(spi_pushed);
00910 
00911     /* Release snapshot if we got one */
00912     if (snapshot_set)
00913         PopActiveSnapshot();
00914 
00915     /*
00916      * Normally we make a dedicated memory context for the CachedPlan and its
00917      * subsidiary data.  (It's probably not going to be large, but just in
00918      * case, use the default maxsize parameter.  It's transient for the
00919      * moment.)  But for a one-shot plan, we just leave it in the caller's
00920      * memory context.
00921      */
00922     if (!plansource->is_oneshot)
00923     {
00924         plan_context = AllocSetContextCreate(CurrentMemoryContext,
00925                                              "CachedPlan",
00926                                              ALLOCSET_SMALL_MINSIZE,
00927                                              ALLOCSET_SMALL_INITSIZE,
00928                                              ALLOCSET_DEFAULT_MAXSIZE);
00929 
00930         /*
00931          * Copy plan into the new context.
00932          */
00933         MemoryContextSwitchTo(plan_context);
00934 
00935         plist = (List *) copyObject(plist);
00936     }
00937     else
00938         plan_context = CurrentMemoryContext;
00939 
00940     /*
00941      * Create and fill the CachedPlan struct within the new context.
00942      */
00943     plan = (CachedPlan *) palloc(sizeof(CachedPlan));
00944     plan->magic = CACHEDPLAN_MAGIC;
00945     plan->stmt_list = plist;
00946     if (plan_list_is_transient(plist))
00947     {
00948         Assert(TransactionIdIsNormal(TransactionXmin));
00949         plan->saved_xmin = TransactionXmin;
00950     }
00951     else
00952         plan->saved_xmin = InvalidTransactionId;
00953     plan->refcount = 0;
00954     plan->context = plan_context;
00955     plan->is_oneshot = plansource->is_oneshot;
00956     plan->is_saved = false;
00957     plan->is_valid = true;
00958 
00959     /* assign generation number to new plan */
00960     plan->generation = ++(plansource->generation);
00961 
00962     MemoryContextSwitchTo(oldcxt);
00963 
00964     return plan;
00965 }
00966 
00967 /*
00968  * choose_custom_plan: choose whether to use custom or generic plan
00969  *
00970  * This defines the policy followed by GetCachedPlan.
00971  */
00972 static bool
00973 choose_custom_plan(CachedPlanSource *plansource, ParamListInfo boundParams)
00974 {
00975     double      avg_custom_cost;
00976 
00977     /* One-shot plans will always be considered custom */
00978     if (plansource->is_oneshot)
00979         return true;
00980 
00981     /* Otherwise, never any point in a custom plan if there's no parameters */
00982     if (boundParams == NULL)
00983         return false;
00984     /* ... nor for transaction control statements */
00985     if (IsTransactionStmtPlan(plansource))
00986         return false;
00987 
00988     /* See if caller wants to force the decision */
00989     if (plansource->cursor_options & CURSOR_OPT_GENERIC_PLAN)
00990         return false;
00991     if (plansource->cursor_options & CURSOR_OPT_CUSTOM_PLAN)
00992         return true;
00993 
00994     /* Generate custom plans until we have done at least 5 (arbitrary) */
00995     if (plansource->num_custom_plans < 5)
00996         return true;
00997 
00998     avg_custom_cost = plansource->total_custom_cost / plansource->num_custom_plans;
00999 
01000     /*
01001      * Prefer generic plan if it's less than 10% more expensive than average
01002      * custom plan.  This threshold is a bit arbitrary; it'd be better if we
01003      * had some means of comparing planning time to the estimated runtime cost
01004      * differential.
01005      *
01006      * Note that if generic_cost is -1 (indicating we've not yet determined
01007      * the generic plan cost), we'll always prefer generic at this point.
01008      */
01009     if (plansource->generic_cost < avg_custom_cost * 1.1)
01010         return false;
01011 
01012     return true;
01013 }
01014 
01015 /*
01016  * cached_plan_cost: calculate estimated cost of a plan
01017  */
01018 static double
01019 cached_plan_cost(CachedPlan *plan)
01020 {
01021     double      result = 0;
01022     ListCell   *lc;
01023 
01024     foreach(lc, plan->stmt_list)
01025     {
01026         PlannedStmt *plannedstmt = (PlannedStmt *) lfirst(lc);
01027 
01028         if (!IsA(plannedstmt, PlannedStmt))
01029             continue;           /* Ignore utility statements */
01030 
01031         result += plannedstmt->planTree->total_cost;
01032     }
01033 
01034     return result;
01035 }
01036 
01037 /*
01038  * GetCachedPlan: get a cached plan from a CachedPlanSource.
01039  *
01040  * This function hides the logic that decides whether to use a generic
01041  * plan or a custom plan for the given parameters: the caller does not know
01042  * which it will get.
01043  *
01044  * On return, the plan is valid and we have sufficient locks to begin
01045  * execution.
01046  *
01047  * On return, the refcount of the plan has been incremented; a later
01048  * ReleaseCachedPlan() call is expected.  The refcount has been reported
01049  * to the CurrentResourceOwner if useResOwner is true (note that that must
01050  * only be true if it's a "saved" CachedPlanSource).
01051  *
01052  * Note: if any replanning activity is required, the caller's memory context
01053  * is used for that work.
01054  */
01055 CachedPlan *
01056 GetCachedPlan(CachedPlanSource *plansource, ParamListInfo boundParams,
01057               bool useResOwner)
01058 {
01059     CachedPlan *plan;
01060     List       *qlist;
01061     bool        customplan;
01062 
01063     /* Assert caller is doing things in a sane order */
01064     Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
01065     Assert(plansource->is_complete);
01066     /* This seems worth a real test, though */
01067     if (useResOwner && !plansource->is_saved)
01068         elog(ERROR, "cannot apply ResourceOwner to non-saved cached plan");
01069 
01070     /* Make sure the querytree list is valid and we have parse-time locks */
01071     qlist = RevalidateCachedQuery(plansource);
01072 
01073     /* Decide whether to use a custom plan */
01074     customplan = choose_custom_plan(plansource, boundParams);
01075 
01076     if (!customplan)
01077     {
01078         if (CheckCachedPlan(plansource))
01079         {
01080             /* We want a generic plan, and we already have a valid one */
01081             plan = plansource->gplan;
01082             Assert(plan->magic == CACHEDPLAN_MAGIC);
01083         }
01084         else
01085         {
01086             /* Build a new generic plan */
01087             plan = BuildCachedPlan(plansource, qlist, NULL);
01088             /* Just make real sure plansource->gplan is clear */
01089             ReleaseGenericPlan(plansource);
01090             /* Link the new generic plan into the plansource */
01091             plansource->gplan = plan;
01092             plan->refcount++;
01093             /* Immediately reparent into appropriate context */
01094             if (plansource->is_saved)
01095             {
01096                 /* saved plans all live under CacheMemoryContext */
01097                 MemoryContextSetParent(plan->context, CacheMemoryContext);
01098                 plan->is_saved = true;
01099             }
01100             else
01101             {
01102                 /* otherwise, it should be a sibling of the plansource */
01103                 MemoryContextSetParent(plan->context,
01104                                 MemoryContextGetParent(plansource->context));
01105             }
01106             /* Update generic_cost whenever we make a new generic plan */
01107             plansource->generic_cost = cached_plan_cost(plan);
01108 
01109             /*
01110              * If, based on the now-known value of generic_cost, we'd not have
01111              * chosen to use a generic plan, then forget it and make a custom
01112              * plan.  This is a bit of a wart but is necessary to avoid a
01113              * glitch in behavior when the custom plans are consistently big
01114              * winners; at some point we'll experiment with a generic plan and
01115              * find it's a loser, but we don't want to actually execute that
01116              * plan.
01117              */
01118             customplan = choose_custom_plan(plansource, boundParams);
01119 
01120             /*
01121              * If we choose to plan again, we need to re-copy the query_list,
01122              * since the planner probably scribbled on it.  We can force
01123              * BuildCachedPlan to do that by passing NIL.
01124              */
01125             qlist = NIL;
01126         }
01127     }
01128 
01129     if (customplan)
01130     {
01131         /* Build a custom plan */
01132         plan = BuildCachedPlan(plansource, qlist, boundParams);
01133         /* Accumulate total costs of custom plans, but 'ware overflow */
01134         if (plansource->num_custom_plans < INT_MAX)
01135         {
01136             plansource->total_custom_cost += cached_plan_cost(plan);
01137             plansource->num_custom_plans++;
01138         }
01139     }
01140 
01141     /* Flag the plan as in use by caller */
01142     if (useResOwner)
01143         ResourceOwnerEnlargePlanCacheRefs(CurrentResourceOwner);
01144     plan->refcount++;
01145     if (useResOwner)
01146         ResourceOwnerRememberPlanCacheRef(CurrentResourceOwner, plan);
01147 
01148     /*
01149      * Saved plans should be under CacheMemoryContext so they will not go away
01150      * until their reference count goes to zero.  In the generic-plan cases we
01151      * already took care of that, but for a custom plan, do it as soon as we
01152      * have created a reference-counted link.
01153      */
01154     if (customplan && plansource->is_saved)
01155     {
01156         MemoryContextSetParent(plan->context, CacheMemoryContext);
01157         plan->is_saved = true;
01158     }
01159 
01160     return plan;
01161 }
01162 
01163 /*
01164  * ReleaseCachedPlan: release active use of a cached plan.
01165  *
01166  * This decrements the reference count, and frees the plan if the count
01167  * has thereby gone to zero.  If useResOwner is true, it is assumed that
01168  * the reference count is managed by the CurrentResourceOwner.
01169  *
01170  * Note: useResOwner = false is used for releasing references that are in
01171  * persistent data structures, such as the parent CachedPlanSource or a
01172  * Portal.  Transient references should be protected by a resource owner.
01173  */
01174 void
01175 ReleaseCachedPlan(CachedPlan *plan, bool useResOwner)
01176 {
01177     Assert(plan->magic == CACHEDPLAN_MAGIC);
01178     if (useResOwner)
01179     {
01180         Assert(plan->is_saved);
01181         ResourceOwnerForgetPlanCacheRef(CurrentResourceOwner, plan);
01182     }
01183     Assert(plan->refcount > 0);
01184     plan->refcount--;
01185     if (plan->refcount == 0)
01186     {
01187         /* Mark it no longer valid */
01188         plan->magic = 0;
01189 
01190         /* One-shot plans do not own their context, so we can't free them */
01191         if (!plan->is_oneshot)
01192             MemoryContextDelete(plan->context);
01193     }
01194 }
01195 
01196 /*
01197  * CachedPlanSetParentContext: move a CachedPlanSource to a new memory context
01198  *
01199  * This can only be applied to unsaved plans; once saved, a plan always
01200  * lives underneath CacheMemoryContext.
01201  */
01202 void
01203 CachedPlanSetParentContext(CachedPlanSource *plansource,
01204                            MemoryContext newcontext)
01205 {
01206     /* Assert caller is doing things in a sane order */
01207     Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
01208     Assert(plansource->is_complete);
01209 
01210     /* These seem worth real tests, though */
01211     if (plansource->is_saved)
01212         elog(ERROR, "cannot move a saved cached plan to another context");
01213     if (plansource->is_oneshot)
01214         elog(ERROR, "cannot move a one-shot cached plan to another context");
01215 
01216     /* OK, let the caller keep the plan where he wishes */
01217     MemoryContextSetParent(plansource->context, newcontext);
01218 
01219     /*
01220      * The query_context needs no special handling, since it's a child of
01221      * plansource->context.  But if there's a generic plan, it should be
01222      * maintained as a sibling of plansource->context.
01223      */
01224     if (plansource->gplan)
01225     {
01226         Assert(plansource->gplan->magic == CACHEDPLAN_MAGIC);
01227         MemoryContextSetParent(plansource->gplan->context, newcontext);
01228     }
01229 }
01230 
01231 /*
01232  * CopyCachedPlan: make a copy of a CachedPlanSource
01233  *
01234  * This is a convenience routine that does the equivalent of
01235  * CreateCachedPlan + CompleteCachedPlan, using the data stored in the
01236  * input CachedPlanSource.  The result is therefore "unsaved" (regardless
01237  * of the state of the source), and we don't copy any generic plan either.
01238  * The result will be currently valid, or not, the same as the source.
01239  */
01240 CachedPlanSource *
01241 CopyCachedPlan(CachedPlanSource *plansource)
01242 {
01243     CachedPlanSource *newsource;
01244     MemoryContext source_context;
01245     MemoryContext querytree_context;
01246     MemoryContext oldcxt;
01247 
01248     Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
01249     Assert(plansource->is_complete);
01250 
01251     /*
01252      * One-shot plans can't be copied, because we haven't taken care that
01253      * parsing/planning didn't scribble on the raw parse tree or querytrees.
01254      */
01255     if (plansource->is_oneshot)
01256         elog(ERROR, "cannot copy a one-shot cached plan");
01257 
01258     source_context = AllocSetContextCreate(CurrentMemoryContext,
01259                                            "CachedPlanSource",
01260                                            ALLOCSET_SMALL_MINSIZE,
01261                                            ALLOCSET_SMALL_INITSIZE,
01262                                            ALLOCSET_DEFAULT_MAXSIZE);
01263 
01264     oldcxt = MemoryContextSwitchTo(source_context);
01265 
01266     newsource = (CachedPlanSource *) palloc0(sizeof(CachedPlanSource));
01267     newsource->magic = CACHEDPLANSOURCE_MAGIC;
01268     newsource->raw_parse_tree = copyObject(plansource->raw_parse_tree);
01269     newsource->query_string = pstrdup(plansource->query_string);
01270     newsource->commandTag = plansource->commandTag;
01271     if (plansource->num_params > 0)
01272     {
01273         newsource->param_types = (Oid *)
01274             palloc(plansource->num_params * sizeof(Oid));
01275         memcpy(newsource->param_types, plansource->param_types,
01276                plansource->num_params * sizeof(Oid));
01277     }
01278     else
01279         newsource->param_types = NULL;
01280     newsource->num_params = plansource->num_params;
01281     newsource->parserSetup = plansource->parserSetup;
01282     newsource->parserSetupArg = plansource->parserSetupArg;
01283     newsource->cursor_options = plansource->cursor_options;
01284     newsource->fixed_result = plansource->fixed_result;
01285     if (plansource->resultDesc)
01286         newsource->resultDesc = CreateTupleDescCopy(plansource->resultDesc);
01287     else
01288         newsource->resultDesc = NULL;
01289     newsource->context = source_context;
01290 
01291     querytree_context = AllocSetContextCreate(source_context,
01292                                               "CachedPlanQuery",
01293                                               ALLOCSET_SMALL_MINSIZE,
01294                                               ALLOCSET_SMALL_INITSIZE,
01295                                               ALLOCSET_DEFAULT_MAXSIZE);
01296     MemoryContextSwitchTo(querytree_context);
01297     newsource->query_list = (List *) copyObject(plansource->query_list);
01298     newsource->relationOids = (List *) copyObject(plansource->relationOids);
01299     newsource->invalItems = (List *) copyObject(plansource->invalItems);
01300     if (plansource->search_path)
01301         newsource->search_path = CopyOverrideSearchPath(plansource->search_path);
01302     newsource->query_context = querytree_context;
01303 
01304     newsource->gplan = NULL;
01305 
01306     newsource->is_oneshot = false;
01307     newsource->is_complete = true;
01308     newsource->is_saved = false;
01309     newsource->is_valid = plansource->is_valid;
01310     newsource->generation = plansource->generation;
01311     newsource->next_saved = NULL;
01312 
01313     /* We may as well copy any acquired cost knowledge */
01314     newsource->generic_cost = plansource->generic_cost;
01315     newsource->total_custom_cost = plansource->total_custom_cost;
01316     newsource->num_custom_plans = plansource->num_custom_plans;
01317 
01318     MemoryContextSwitchTo(oldcxt);
01319 
01320     return newsource;
01321 }
01322 
01323 /*
01324  * CachedPlanIsValid: test whether the rewritten querytree within a
01325  * CachedPlanSource is currently valid (that is, not marked as being in need
01326  * of revalidation).
01327  *
01328  * This result is only trustworthy (ie, free from race conditions) if
01329  * the caller has acquired locks on all the relations used in the plan.
01330  */
01331 bool
01332 CachedPlanIsValid(CachedPlanSource *plansource)
01333 {
01334     Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
01335     return plansource->is_valid;
01336 }
01337 
01338 /*
01339  * CachedPlanGetTargetList: return tlist, if any, describing plan's output
01340  *
01341  * The result is guaranteed up-to-date.  However, it is local storage
01342  * within the cached plan, and may disappear next time the plan is updated.
01343  */
01344 List *
01345 CachedPlanGetTargetList(CachedPlanSource *plansource)
01346 {
01347     Node       *pstmt;
01348 
01349     /* Assert caller is doing things in a sane order */
01350     Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
01351     Assert(plansource->is_complete);
01352 
01353     /*
01354      * No work needed if statement doesn't return tuples (we assume this
01355      * feature cannot be changed by an invalidation)
01356      */
01357     if (plansource->resultDesc == NULL)
01358         return NIL;
01359 
01360     /* Make sure the querytree list is valid and we have parse-time locks */
01361     RevalidateCachedQuery(plansource);
01362 
01363     /* Get the primary statement and find out what it returns */
01364     pstmt = PortalListGetPrimaryStmt(plansource->query_list);
01365 
01366     return FetchStatementTargetList(pstmt);
01367 }
01368 
01369 /*
01370  * AcquireExecutorLocks: acquire locks needed for execution of a cached plan;
01371  * or release them if acquire is false.
01372  */
01373 static void
01374 AcquireExecutorLocks(List *stmt_list, bool acquire)
01375 {
01376     ListCell   *lc1;
01377 
01378     foreach(lc1, stmt_list)
01379     {
01380         PlannedStmt *plannedstmt = (PlannedStmt *) lfirst(lc1);
01381         int         rt_index;
01382         ListCell   *lc2;
01383 
01384         Assert(!IsA(plannedstmt, Query));
01385         if (!IsA(plannedstmt, PlannedStmt))
01386         {
01387             /*
01388              * Ignore utility statements, except those (such as EXPLAIN) that
01389              * contain a parsed-but-not-planned query.  Note: it's okay to use
01390              * ScanQueryForLocks, even though the query hasn't been through
01391              * rule rewriting, because rewriting doesn't change the query
01392              * representation.
01393              */
01394             Query      *query = UtilityContainsQuery((Node *) plannedstmt);
01395 
01396             if (query)
01397                 ScanQueryForLocks(query, acquire);
01398             continue;
01399         }
01400 
01401         rt_index = 0;
01402         foreach(lc2, plannedstmt->rtable)
01403         {
01404             RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc2);
01405             LOCKMODE    lockmode;
01406             PlanRowMark *rc;
01407 
01408             rt_index++;
01409 
01410             if (rte->rtekind != RTE_RELATION)
01411                 continue;
01412 
01413             /*
01414              * Acquire the appropriate type of lock on each relation OID. Note
01415              * that we don't actually try to open the rel, and hence will not
01416              * fail if it's been dropped entirely --- we'll just transiently
01417              * acquire a non-conflicting lock.
01418              */
01419             if (list_member_int(plannedstmt->resultRelations, rt_index))
01420                 lockmode = RowExclusiveLock;
01421             else if ((rc = get_plan_rowmark(plannedstmt->rowMarks, rt_index)) != NULL &&
01422                      RowMarkRequiresRowShareLock(rc->markType))
01423                 lockmode = RowShareLock;
01424             else
01425                 lockmode = AccessShareLock;
01426 
01427             if (acquire)
01428                 LockRelationOid(rte->relid, lockmode);
01429             else
01430                 UnlockRelationOid(rte->relid, lockmode);
01431         }
01432     }
01433 }
01434 
01435 /*
01436  * AcquirePlannerLocks: acquire locks needed for planning of a querytree list;
01437  * or release them if acquire is false.
01438  *
01439  * Note that we don't actually try to open the relations, and hence will not
01440  * fail if one has been dropped entirely --- we'll just transiently acquire
01441  * a non-conflicting lock.
01442  */
01443 static void
01444 AcquirePlannerLocks(List *stmt_list, bool acquire)
01445 {
01446     ListCell   *lc;
01447 
01448     foreach(lc, stmt_list)
01449     {
01450         Query      *query = (Query *) lfirst(lc);
01451 
01452         Assert(IsA(query, Query));
01453 
01454         if (query->commandType == CMD_UTILITY)
01455         {
01456             /* Ignore utility statements, unless they contain a Query */
01457             query = UtilityContainsQuery(query->utilityStmt);
01458             if (query)
01459                 ScanQueryForLocks(query, acquire);
01460             continue;
01461         }
01462 
01463         ScanQueryForLocks(query, acquire);
01464     }
01465 }
01466 
01467 /*
01468  * ScanQueryForLocks: recursively scan one Query for AcquirePlannerLocks.
01469  */
01470 static void
01471 ScanQueryForLocks(Query *parsetree, bool acquire)
01472 {
01473     ListCell   *lc;
01474     int         rt_index;
01475 
01476     /* Shouldn't get called on utility commands */
01477     Assert(parsetree->commandType != CMD_UTILITY);
01478 
01479     /*
01480      * First, process RTEs of the current query level.
01481      */
01482     rt_index = 0;
01483     foreach(lc, parsetree->rtable)
01484     {
01485         RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc);
01486         LOCKMODE    lockmode;
01487 
01488         rt_index++;
01489         switch (rte->rtekind)
01490         {
01491             case RTE_RELATION:
01492                 /* Acquire or release the appropriate type of lock */
01493                 if (rt_index == parsetree->resultRelation)
01494                     lockmode = RowExclusiveLock;
01495                 else if (get_parse_rowmark(parsetree, rt_index) != NULL)
01496                     lockmode = RowShareLock;
01497                 else
01498                     lockmode = AccessShareLock;
01499                 if (acquire)
01500                     LockRelationOid(rte->relid, lockmode);
01501                 else
01502                     UnlockRelationOid(rte->relid, lockmode);
01503                 break;
01504 
01505             case RTE_SUBQUERY:
01506                 /* Recurse into subquery-in-FROM */
01507                 ScanQueryForLocks(rte->subquery, acquire);
01508                 break;
01509 
01510             default:
01511                 /* ignore other types of RTEs */
01512                 break;
01513         }
01514     }
01515 
01516     /* Recurse into subquery-in-WITH */
01517     foreach(lc, parsetree->cteList)
01518     {
01519         CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
01520 
01521         ScanQueryForLocks((Query *) cte->ctequery, acquire);
01522     }
01523 
01524     /*
01525      * Recurse into sublink subqueries, too.  But we already did the ones in
01526      * the rtable and cteList.
01527      */
01528     if (parsetree->hasSubLinks)
01529     {
01530         query_tree_walker(parsetree, ScanQueryWalker,
01531                           (void *) &acquire,
01532                           QTW_IGNORE_RC_SUBQUERIES);
01533     }
01534 }
01535 
01536 /*
01537  * Walker to find sublink subqueries for ScanQueryForLocks
01538  */
01539 static bool
01540 ScanQueryWalker(Node *node, bool *acquire)
01541 {
01542     if (node == NULL)
01543         return false;
01544     if (IsA(node, SubLink))
01545     {
01546         SubLink    *sub = (SubLink *) node;
01547 
01548         /* Do what we came for */
01549         ScanQueryForLocks((Query *) sub->subselect, *acquire);
01550         /* Fall through to process lefthand args of SubLink */
01551     }
01552 
01553     /*
01554      * Do NOT recurse into Query nodes, because ScanQueryForLocks already
01555      * processed subselects of subselects for us.
01556      */
01557     return expression_tree_walker(node, ScanQueryWalker,
01558                                   (void *) acquire);
01559 }
01560 
01561 /*
01562  * plan_list_is_transient: check if any of the plans in the list are transient.
01563  */
01564 static bool
01565 plan_list_is_transient(List *stmt_list)
01566 {
01567     ListCell   *lc;
01568 
01569     foreach(lc, stmt_list)
01570     {
01571         PlannedStmt *plannedstmt = (PlannedStmt *) lfirst(lc);
01572 
01573         if (!IsA(plannedstmt, PlannedStmt))
01574             continue;           /* Ignore utility statements */
01575 
01576         if (plannedstmt->transientPlan)
01577             return true;
01578     }
01579 
01580     return false;
01581 }
01582 
01583 /*
01584  * PlanCacheComputeResultDesc: given a list of analyzed-and-rewritten Queries,
01585  * determine the result tupledesc it will produce.  Returns NULL if the
01586  * execution will not return tuples.
01587  *
01588  * Note: the result is created or copied into current memory context.
01589  */
01590 static TupleDesc
01591 PlanCacheComputeResultDesc(List *stmt_list)
01592 {
01593     Query      *query;
01594 
01595     switch (ChoosePortalStrategy(stmt_list))
01596     {
01597         case PORTAL_ONE_SELECT:
01598         case PORTAL_ONE_MOD_WITH:
01599             query = (Query *) linitial(stmt_list);
01600             Assert(IsA(query, Query));
01601             return ExecCleanTypeFromTL(query->targetList, false);
01602 
01603         case PORTAL_ONE_RETURNING:
01604             query = (Query *) PortalListGetPrimaryStmt(stmt_list);
01605             Assert(IsA(query, Query));
01606             Assert(query->returningList);
01607             return ExecCleanTypeFromTL(query->returningList, false);
01608 
01609         case PORTAL_UTIL_SELECT:
01610             query = (Query *) linitial(stmt_list);
01611             Assert(IsA(query, Query));
01612             Assert(query->utilityStmt);
01613             return UtilityTupleDescriptor(query->utilityStmt);
01614 
01615         case PORTAL_MULTI_QUERY:
01616             /* will not return tuples */
01617             break;
01618     }
01619     return NULL;
01620 }
01621 
01622 /*
01623  * PlanCacheRelCallback
01624  *      Relcache inval callback function
01625  *
01626  * Invalidate all plans mentioning the given rel, or all plans mentioning
01627  * any rel at all if relid == InvalidOid.
01628  */
01629 static void
01630 PlanCacheRelCallback(Datum arg, Oid relid)
01631 {
01632     CachedPlanSource *plansource;
01633 
01634     for (plansource = first_saved_plan; plansource; plansource = plansource->next_saved)
01635     {
01636         Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
01637 
01638         /* No work if it's already invalidated */
01639         if (!plansource->is_valid)
01640             continue;
01641 
01642         /* Never invalidate transaction control commands */
01643         if (IsTransactionStmtPlan(plansource))
01644             continue;
01645 
01646         /*
01647          * Check the dependency list for the rewritten querytree.
01648          */
01649         if ((relid == InvalidOid) ? plansource->relationOids != NIL :
01650             list_member_oid(plansource->relationOids, relid))
01651         {
01652             /* Invalidate the querytree and generic plan */
01653             plansource->is_valid = false;
01654             if (plansource->gplan)
01655                 plansource->gplan->is_valid = false;
01656         }
01657 
01658         /*
01659          * The generic plan, if any, could have more dependencies than the
01660          * querytree does, so we have to check it too.
01661          */
01662         if (plansource->gplan && plansource->gplan->is_valid)
01663         {
01664             ListCell   *lc;
01665 
01666             foreach(lc, plansource->gplan->stmt_list)
01667             {
01668                 PlannedStmt *plannedstmt = (PlannedStmt *) lfirst(lc);
01669 
01670                 Assert(!IsA(plannedstmt, Query));
01671                 if (!IsA(plannedstmt, PlannedStmt))
01672                     continue;   /* Ignore utility statements */
01673                 if ((relid == InvalidOid) ? plannedstmt->relationOids != NIL :
01674                     list_member_oid(plannedstmt->relationOids, relid))
01675                 {
01676                     /* Invalidate the generic plan only */
01677                     plansource->gplan->is_valid = false;
01678                     break;      /* out of stmt_list scan */
01679                 }
01680             }
01681         }
01682     }
01683 }
01684 
01685 /*
01686  * PlanCacheFuncCallback
01687  *      Syscache inval callback function for PROCOID cache
01688  *
01689  * Invalidate all plans mentioning the object with the specified hash value,
01690  * or all plans mentioning any member of this cache if hashvalue == 0.
01691  *
01692  * Note that the coding would support use for multiple caches, but right
01693  * now only user-defined functions are tracked this way.
01694  */
01695 static void
01696 PlanCacheFuncCallback(Datum arg, int cacheid, uint32 hashvalue)
01697 {
01698     CachedPlanSource *plansource;
01699 
01700     for (plansource = first_saved_plan; plansource; plansource = plansource->next_saved)
01701     {
01702         ListCell   *lc;
01703 
01704         Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
01705 
01706         /* No work if it's already invalidated */
01707         if (!plansource->is_valid)
01708             continue;
01709 
01710         /* Never invalidate transaction control commands */
01711         if (IsTransactionStmtPlan(plansource))
01712             continue;
01713 
01714         /*
01715          * Check the dependency list for the rewritten querytree.
01716          */
01717         foreach(lc, plansource->invalItems)
01718         {
01719             PlanInvalItem *item = (PlanInvalItem *) lfirst(lc);
01720 
01721             if (item->cacheId != cacheid)
01722                 continue;
01723             if (hashvalue == 0 ||
01724                 item->hashValue == hashvalue)
01725             {
01726                 /* Invalidate the querytree and generic plan */
01727                 plansource->is_valid = false;
01728                 if (plansource->gplan)
01729                     plansource->gplan->is_valid = false;
01730                 break;
01731             }
01732         }
01733 
01734         /*
01735          * The generic plan, if any, could have more dependencies than the
01736          * querytree does, so we have to check it too.
01737          */
01738         if (plansource->gplan && plansource->gplan->is_valid)
01739         {
01740             foreach(lc, plansource->gplan->stmt_list)
01741             {
01742                 PlannedStmt *plannedstmt = (PlannedStmt *) lfirst(lc);
01743                 ListCell   *lc3;
01744 
01745                 Assert(!IsA(plannedstmt, Query));
01746                 if (!IsA(plannedstmt, PlannedStmt))
01747                     continue;   /* Ignore utility statements */
01748                 foreach(lc3, plannedstmt->invalItems)
01749                 {
01750                     PlanInvalItem *item = (PlanInvalItem *) lfirst(lc3);
01751 
01752                     if (item->cacheId != cacheid)
01753                         continue;
01754                     if (hashvalue == 0 ||
01755                         item->hashValue == hashvalue)
01756                     {
01757                         /* Invalidate the generic plan only */
01758                         plansource->gplan->is_valid = false;
01759                         break;  /* out of invalItems scan */
01760                     }
01761                 }
01762                 if (!plansource->gplan->is_valid)
01763                     break;      /* out of stmt_list scan */
01764             }
01765         }
01766     }
01767 }
01768 
01769 /*
01770  * PlanCacheSysCallback
01771  *      Syscache inval callback function for other caches
01772  *
01773  * Just invalidate everything...
01774  */
01775 static void
01776 PlanCacheSysCallback(Datum arg, int cacheid, uint32 hashvalue)
01777 {
01778     ResetPlanCache();
01779 }
01780 
01781 /*
01782  * ResetPlanCache: invalidate all cached plans.
01783  */
01784 void
01785 ResetPlanCache(void)
01786 {
01787     CachedPlanSource *plansource;
01788 
01789     for (plansource = first_saved_plan; plansource; plansource = plansource->next_saved)
01790     {
01791         ListCell   *lc;
01792 
01793         Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
01794 
01795         /* No work if it's already invalidated */
01796         if (!plansource->is_valid)
01797             continue;
01798 
01799         /*
01800          * We *must not* mark transaction control statements as invalid,
01801          * particularly not ROLLBACK, because they may need to be executed in
01802          * aborted transactions when we can't revalidate them (cf bug #5269).
01803          */
01804         if (IsTransactionStmtPlan(plansource))
01805             continue;
01806 
01807         /*
01808          * In general there is no point in invalidating utility statements
01809          * since they have no plans anyway.  So invalidate it only if it
01810          * contains at least one non-utility statement, or contains a utility
01811          * statement that contains a pre-analyzed query (which could have
01812          * dependencies.)
01813          */
01814         foreach(lc, plansource->query_list)
01815         {
01816             Query      *query = (Query *) lfirst(lc);
01817 
01818             Assert(IsA(query, Query));
01819             if (query->commandType != CMD_UTILITY ||
01820                 UtilityContainsQuery(query->utilityStmt))
01821             {
01822                 /* non-utility statement, so invalidate */
01823                 plansource->is_valid = false;
01824                 if (plansource->gplan)
01825                     plansource->gplan->is_valid = false;
01826                 /* no need to look further */
01827                 break;
01828             }
01829         }
01830     }
01831 }