]> granicus.if.org Git - postgresql/blob - src/backend/utils/cache/plancache.c
cbc7c498d0d533b149fe4395992d9910a2d6b5cd
[postgresql] / src / backend / utils / cache / plancache.c
1 /*-------------------------------------------------------------------------
2  *
3  * plancache.c
4  *        Plan cache management.
5  *
6  * The plan cache manager has two principal responsibilities: deciding when
7  * to use a generic plan versus a custom (parameter-value-specific) plan,
8  * and tracking whether cached plans need to be invalidated because of schema
9  * changes in the objects they depend on.
10  *
11  * The logic for choosing generic or custom plans is in choose_custom_plan,
12  * which see for comments.
13  *
14  * Cache invalidation is driven off sinval events.      Any CachedPlanSource
15  * that matches the event is marked invalid, as is its generic CachedPlan
16  * if it has one.  When (and if) the next demand for a cached plan occurs,
17  * parse analysis and rewrite is repeated to build a new valid query tree,
18  * and then planning is performed as normal.
19  *
20  * Note that if the sinval was a result of user DDL actions, parse analysis
21  * could throw an error, for example if a column referenced by the query is
22  * no longer present.  The creator of a cached plan can specify whether it
23  * is allowable for the query to change output tupdesc on replan (this
24  * could happen with "SELECT *" for example) --- if so, it's up to the
25  * caller to notice changes and cope with them.
26  *
27  * Currently, we track exactly the dependencies of plans on relations and
28  * user-defined functions.      On relcache invalidation events or pg_proc
29  * syscache invalidation events, we invalidate just those plans that depend
30  * on the particular object being modified.  (Note: this scheme assumes
31  * that any table modification that requires replanning will generate a
32  * relcache inval event.)  We also watch for inval events on certain other
33  * system catalogs, such as pg_namespace; but for them, our response is
34  * just to invalidate all plans.  We expect updates on those catalogs to
35  * be infrequent enough that more-detailed tracking is not worth the effort.
36  *
37  *
38  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
39  * Portions Copyright (c) 1994, Regents of the University of California
40  *
41  * IDENTIFICATION
42  *        src/backend/utils/cache/plancache.c
43  *
44  *-------------------------------------------------------------------------
45  */
46 #include "postgres.h"
47
48 #include <limits.h>
49
50 #include "access/transam.h"
51 #include "catalog/namespace.h"
52 #include "executor/executor.h"
53 #include "executor/spi.h"
54 #include "nodes/nodeFuncs.h"
55 #include "optimizer/planmain.h"
56 #include "optimizer/prep.h"
57 #include "parser/analyze.h"
58 #include "parser/parsetree.h"
59 #include "storage/lmgr.h"
60 #include "tcop/pquery.h"
61 #include "tcop/utility.h"
62 #include "utils/inval.h"
63 #include "utils/memutils.h"
64 #include "utils/resowner_private.h"
65 #include "utils/snapmgr.h"
66 #include "utils/syscache.h"
67
68
69 /*
70  * This is the head of the backend's list of "saved" CachedPlanSources (i.e.,
71  * those that are in long-lived storage and are examined for sinval events).
72  * We thread the structs manually instead of using List cells so that we can
73  * guarantee to save a CachedPlanSource without error.
74  */
75 static CachedPlanSource *first_saved_plan = NULL;
76
77 static void ReleaseGenericPlan(CachedPlanSource *plansource);
78 static List *RevalidateCachedQuery(CachedPlanSource *plansource);
79 static bool CheckCachedPlan(CachedPlanSource *plansource);
80 static CachedPlan *BuildCachedPlan(CachedPlanSource *plansource, List *qlist,
81                                 ParamListInfo boundParams);
82 static bool choose_custom_plan(CachedPlanSource *plansource,
83                                    ParamListInfo boundParams);
84 static double cached_plan_cost(CachedPlan *plan);
85 static void AcquireExecutorLocks(List *stmt_list, bool acquire);
86 static void AcquirePlannerLocks(List *stmt_list, bool acquire);
87 static void ScanQueryForLocks(Query *parsetree, bool acquire);
88 static bool ScanQueryWalker(Node *node, bool *acquire);
89 static bool plan_list_is_transient(List *stmt_list);
90 static TupleDesc PlanCacheComputeResultDesc(List *stmt_list);
91 static void PlanCacheRelCallback(Datum arg, Oid relid);
92 static void PlanCacheFuncCallback(Datum arg, int cacheid, uint32 hashvalue);
93 static void PlanCacheSysCallback(Datum arg, int cacheid, uint32 hashvalue);
94
95
96 /*
97  * InitPlanCache: initialize module during InitPostgres.
98  *
99  * All we need to do is hook into inval.c's callback lists.
100  */
101 void
102 InitPlanCache(void)
103 {
104         CacheRegisterRelcacheCallback(PlanCacheRelCallback, (Datum) 0);
105         CacheRegisterSyscacheCallback(PROCOID, PlanCacheFuncCallback, (Datum) 0);
106         CacheRegisterSyscacheCallback(NAMESPACEOID, PlanCacheSysCallback, (Datum) 0);
107         CacheRegisterSyscacheCallback(OPEROID, PlanCacheSysCallback, (Datum) 0);
108         CacheRegisterSyscacheCallback(AMOPOPID, PlanCacheSysCallback, (Datum) 0);
109 }
110
111 /*
112  * CreateCachedPlan: initially create a plan cache entry.
113  *
114  * Creation of a cached plan is divided into two steps, CreateCachedPlan and
115  * CompleteCachedPlan.  CreateCachedPlan should be called after running the
116  * query through raw_parser, but before doing parse analysis and rewrite;
117  * CompleteCachedPlan is called after that.  The reason for this arrangement
118  * is that it can save one round of copying of the raw parse tree, since
119  * the parser will normally scribble on the raw parse tree.  Callers would
120  * otherwise need to make an extra copy of the parse tree to ensure they
121  * still had a clean copy to present at plan cache creation time.
122  *
123  * All arguments presented to CreateCachedPlan are copied into a memory
124  * context created as a child of the call-time CurrentMemoryContext, which
125  * should be a reasonably short-lived working context that will go away in
126  * event of an error.  This ensures that the cached plan data structure will
127  * likewise disappear if an error occurs before we have fully constructed it.
128  * Once constructed, the cached plan can be made longer-lived, if needed,
129  * by calling SaveCachedPlan.
130  *
131  * raw_parse_tree: output of raw_parser()
132  * query_string: original query text
133  * commandTag: compile-time-constant tag for query, or NULL if empty query
134  */
135 CachedPlanSource *
136 CreateCachedPlan(Node *raw_parse_tree,
137                                  const char *query_string,
138                                  const char *commandTag)
139 {
140         CachedPlanSource *plansource;
141         MemoryContext source_context;
142         MemoryContext oldcxt;
143
144         Assert(query_string != NULL);           /* required as of 8.4 */
145
146         /*
147          * Make a dedicated memory context for the CachedPlanSource and its
148          * permanent subsidiary data.  It's probably not going to be large, but
149          * just in case, use the default maxsize parameter.  Initially it's a
150          * child of the caller's context (which we assume to be transient), so
151          * that it will be cleaned up on error.
152          */
153         source_context = AllocSetContextCreate(CurrentMemoryContext,
154                                                                                    "CachedPlanSource",
155                                                                                    ALLOCSET_SMALL_MINSIZE,
156                                                                                    ALLOCSET_SMALL_INITSIZE,
157                                                                                    ALLOCSET_DEFAULT_MAXSIZE);
158
159         /*
160          * Create and fill the CachedPlanSource struct within the new context.
161          * Most fields are just left empty for the moment.
162          */
163         oldcxt = MemoryContextSwitchTo(source_context);
164
165         plansource = (CachedPlanSource *) palloc0(sizeof(CachedPlanSource));
166         plansource->magic = CACHEDPLANSOURCE_MAGIC;
167         plansource->raw_parse_tree = copyObject(raw_parse_tree);
168         plansource->query_string = pstrdup(query_string);
169         plansource->commandTag = commandTag;
170         plansource->param_types = NULL;
171         plansource->num_params = 0;
172         plansource->parserSetup = NULL;
173         plansource->parserSetupArg = NULL;
174         plansource->cursor_options = 0;
175         plansource->fixed_result = false;
176         plansource->resultDesc = NULL;
177         plansource->search_path = NULL;
178         plansource->context = source_context;
179         plansource->query_list = NIL;
180         plansource->relationOids = NIL;
181         plansource->invalItems = NIL;
182         plansource->query_context = NULL;
183         plansource->gplan = NULL;
184         plansource->is_oneshot = false;
185         plansource->is_complete = false;
186         plansource->is_saved = false;
187         plansource->is_valid = false;
188         plansource->generation = 0;
189         plansource->next_saved = NULL;
190         plansource->generic_cost = -1;
191         plansource->total_custom_cost = 0;
192         plansource->num_custom_plans = 0;
193
194         MemoryContextSwitchTo(oldcxt);
195
196         return plansource;
197 }
198
199 /*
200  * CreateOneShotCachedPlan: initially create a one-shot plan cache entry.
201  *
202  * This variant of CreateCachedPlan creates a plan cache entry that is meant
203  * to be used only once.  No data copying occurs: all data structures remain
204  * in the caller's memory context (which typically should get cleared after
205  * completing execution).  The CachedPlanSource struct itself is also created
206  * in that context.
207  *
208  * A one-shot plan cannot be saved or copied, since we make no effort to
209  * preserve the raw parse tree unmodified.  There is also no support for
210  * invalidation, so plan use must be completed in the current transaction,
211  * and DDL that might invalidate the querytree_list must be avoided as well.
212  *
213  * raw_parse_tree: output of raw_parser()
214  * query_string: original query text
215  * commandTag: compile-time-constant tag for query, or NULL if empty query
216  */
217 CachedPlanSource *
218 CreateOneShotCachedPlan(Node *raw_parse_tree,
219                                                 const char *query_string,
220                                                 const char *commandTag)
221 {
222         CachedPlanSource *plansource;
223
224         Assert(query_string != NULL);           /* required as of 8.4 */
225
226         /*
227          * Create and fill the CachedPlanSource struct within the caller's memory
228          * context.  Most fields are just left empty for the moment.
229          */
230         plansource = (CachedPlanSource *) palloc0(sizeof(CachedPlanSource));
231         plansource->magic = CACHEDPLANSOURCE_MAGIC;
232         plansource->raw_parse_tree = raw_parse_tree;
233         plansource->query_string = query_string;
234         plansource->commandTag = commandTag;
235         plansource->param_types = NULL;
236         plansource->num_params = 0;
237         plansource->parserSetup = NULL;
238         plansource->parserSetupArg = NULL;
239         plansource->cursor_options = 0;
240         plansource->fixed_result = false;
241         plansource->resultDesc = NULL;
242         plansource->search_path = NULL;
243         plansource->context = CurrentMemoryContext;
244         plansource->query_list = NIL;
245         plansource->relationOids = NIL;
246         plansource->invalItems = NIL;
247         plansource->query_context = NULL;
248         plansource->gplan = NULL;
249         plansource->is_oneshot = true;
250         plansource->is_complete = false;
251         plansource->is_saved = false;
252         plansource->is_valid = false;
253         plansource->generation = 0;
254         plansource->next_saved = NULL;
255         plansource->generic_cost = -1;
256         plansource->total_custom_cost = 0;
257         plansource->num_custom_plans = 0;
258
259         return plansource;
260 }
261
262 /*
263  * CompleteCachedPlan: second step of creating a plan cache entry.
264  *
265  * Pass in the analyzed-and-rewritten form of the query, as well as the
266  * required subsidiary data about parameters and such.  All passed values will
267  * be copied into the CachedPlanSource's memory, except as specified below.
268  * After this is called, GetCachedPlan can be called to obtain a plan, and
269  * optionally the CachedPlanSource can be saved using SaveCachedPlan.
270  *
271  * If querytree_context is not NULL, the querytree_list must be stored in that
272  * context (but the other parameters need not be).      The querytree_list is not
273  * copied, rather the given context is kept as the initial query_context of
274  * the CachedPlanSource.  (It should have been created as a child of the
275  * caller's working memory context, but it will now be reparented to belong
276  * to the CachedPlanSource.)  The querytree_context is normally the context in
277  * which the caller did raw parsing and parse analysis.  This approach saves
278  * one tree copying step compared to passing NULL, but leaves lots of extra
279  * cruft in the query_context, namely whatever extraneous stuff parse analysis
280  * created, as well as whatever went unused from the raw parse tree.  Using
281  * this option is a space-for-time tradeoff that is appropriate if the
282  * CachedPlanSource is not expected to survive long.
283  *
284  * plancache.c cannot know how to copy the data referenced by parserSetupArg,
285  * and it would often be inappropriate to do so anyway.  When using that
286  * option, it is caller's responsibility that the referenced data remains
287  * valid for as long as the CachedPlanSource exists.
288  *
289  * If the CachedPlanSource is a "oneshot" plan, then no querytree copying
290  * occurs at all, and querytree_context is ignored; it is caller's
291  * responsibility that the passed querytree_list is sufficiently long-lived.
292  *
293  * plansource: structure returned by CreateCachedPlan
294  * querytree_list: analyzed-and-rewritten form of query (list of Query nodes)
295  * querytree_context: memory context containing querytree_list,
296  *                                        or NULL to copy querytree_list into a fresh context
297  * param_types: array of fixed parameter type OIDs, or NULL if none
298  * num_params: number of fixed parameters
299  * parserSetup: alternate method for handling query parameters
300  * parserSetupArg: data to pass to parserSetup
301  * cursor_options: options bitmask to pass to planner
302  * fixed_result: TRUE to disallow future changes in query's result tupdesc
303  */
304 void
305 CompleteCachedPlan(CachedPlanSource *plansource,
306                                    List *querytree_list,
307                                    MemoryContext querytree_context,
308                                    Oid *param_types,
309                                    int num_params,
310                                    ParserSetupHook parserSetup,
311                                    void *parserSetupArg,
312                                    int cursor_options,
313                                    bool fixed_result)
314 {
315         MemoryContext source_context = plansource->context;
316         MemoryContext oldcxt = CurrentMemoryContext;
317
318         /* Assert caller is doing things in a sane order */
319         Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
320         Assert(!plansource->is_complete);
321
322         /*
323          * If caller supplied a querytree_context, reparent it underneath the
324          * CachedPlanSource's context; otherwise, create a suitable context and
325          * copy the querytree_list into it.  But no data copying should be done
326          * for one-shot plans; for those, assume the passed querytree_list is
327          * sufficiently long-lived.
328          */
329         if (plansource->is_oneshot)
330         {
331                 querytree_context = CurrentMemoryContext;
332         }
333         else if (querytree_context != NULL)
334         {
335                 MemoryContextSetParent(querytree_context, source_context);
336                 MemoryContextSwitchTo(querytree_context);
337         }
338         else
339         {
340                 /* Again, it's a good bet the querytree_context can be small */
341                 querytree_context = AllocSetContextCreate(source_context,
342                                                                                                   "CachedPlanQuery",
343                                                                                                   ALLOCSET_SMALL_MINSIZE,
344                                                                                                   ALLOCSET_SMALL_INITSIZE,
345                                                                                                   ALLOCSET_DEFAULT_MAXSIZE);
346                 MemoryContextSwitchTo(querytree_context);
347                 querytree_list = (List *) copyObject(querytree_list);
348         }
349
350         plansource->query_context = querytree_context;
351         plansource->query_list = querytree_list;
352
353         /*
354          * Use the planner machinery to extract dependencies.  Data is saved in
355          * query_context.  (We assume that not a lot of extra cruft is created by
356          * this call.)  We can skip this for one-shot plans.
357          */
358         if (!plansource->is_oneshot)
359                 extract_query_dependencies((Node *) querytree_list,
360                                                                    &plansource->relationOids,
361                                                                    &plansource->invalItems);
362
363         /*
364          * Save the final parameter types (or other parameter specification data)
365          * into the source_context, as well as our other parameters.  Also save
366          * the result tuple descriptor.
367          */
368         MemoryContextSwitchTo(source_context);
369
370         if (num_params > 0)
371         {
372                 plansource->param_types = (Oid *) palloc(num_params * sizeof(Oid));
373                 memcpy(plansource->param_types, param_types, num_params * sizeof(Oid));
374         }
375         else
376                 plansource->param_types = NULL;
377         plansource->num_params = num_params;
378         plansource->parserSetup = parserSetup;
379         plansource->parserSetupArg = parserSetupArg;
380         plansource->cursor_options = cursor_options;
381         plansource->fixed_result = fixed_result;
382         plansource->resultDesc = PlanCacheComputeResultDesc(querytree_list);
383
384         MemoryContextSwitchTo(oldcxt);
385
386         /*
387          * Fetch current search_path into dedicated context, but do any
388          * recalculation work required in caller's context.
389          */
390         plansource->search_path = GetOverrideSearchPath(source_context);
391
392         plansource->is_complete = true;
393         plansource->is_valid = true;
394 }
395
396 /*
397  * SaveCachedPlan: save a cached plan permanently
398  *
399  * This function moves the cached plan underneath CacheMemoryContext (making
400  * it live for the life of the backend, unless explicitly dropped), and adds
401  * it to the list of cached plans that are checked for invalidation when an
402  * sinval event occurs.
403  *
404  * This is guaranteed not to throw error, except for the caller-error case
405  * of trying to save a one-shot plan.  Callers typically depend on that
406  * since this is called just before or just after adding a pointer to the
407  * CachedPlanSource to some permanent data structure of their own.      Up until
408  * this is done, a CachedPlanSource is just transient data that will go away
409  * automatically on transaction abort.
410  */
411 void
412 SaveCachedPlan(CachedPlanSource *plansource)
413 {
414         /* Assert caller is doing things in a sane order */
415         Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
416         Assert(plansource->is_complete);
417         Assert(!plansource->is_saved);
418
419         /* This seems worth a real test, though */
420         if (plansource->is_oneshot)
421                 elog(ERROR, "cannot save one-shot cached plan");
422
423         /*
424          * In typical use, this function would be called before generating any
425          * plans from the CachedPlanSource.  If there is a generic plan, moving it
426          * into CacheMemoryContext would be pretty risky since it's unclear
427          * whether the caller has taken suitable care with making references
428          * long-lived.  Best thing to do seems to be to discard the plan.
429          */
430         ReleaseGenericPlan(plansource);
431
432         /*
433          * Reparent the source memory context under CacheMemoryContext so that it
434          * will live indefinitely.      The query_context follows along since it's
435          * already a child of the other one.
436          */
437         MemoryContextSetParent(plansource->context, CacheMemoryContext);
438
439         /*
440          * Add the entry to the global list of cached plans.
441          */
442         plansource->next_saved = first_saved_plan;
443         first_saved_plan = plansource;
444
445         plansource->is_saved = true;
446 }
447
448 /*
449  * DropCachedPlan: destroy a cached plan.
450  *
451  * Actually this only destroys the CachedPlanSource: any referenced CachedPlan
452  * is released, but not destroyed until its refcount goes to zero.      That
453  * handles the situation where DropCachedPlan is called while the plan is
454  * still in use.
455  */
456 void
457 DropCachedPlan(CachedPlanSource *plansource)
458 {
459         Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
460
461         /* If it's been saved, remove it from the list */
462         if (plansource->is_saved)
463         {
464                 if (first_saved_plan == plansource)
465                         first_saved_plan = plansource->next_saved;
466                 else
467                 {
468                         CachedPlanSource *psrc;
469
470                         for (psrc = first_saved_plan; psrc; psrc = psrc->next_saved)
471                         {
472                                 if (psrc->next_saved == plansource)
473                                 {
474                                         psrc->next_saved = plansource->next_saved;
475                                         break;
476                                 }
477                         }
478                 }
479                 plansource->is_saved = false;
480         }
481
482         /* Decrement generic CachePlan's refcount and drop if no longer needed */
483         ReleaseGenericPlan(plansource);
484
485         /* Mark it no longer valid */
486         plansource->magic = 0;
487
488         /*
489          * Remove the CachedPlanSource and all subsidiary data (including the
490          * query_context if any).  But if it's a one-shot we can't free anything.
491          */
492         if (!plansource->is_oneshot)
493                 MemoryContextDelete(plansource->context);
494 }
495
496 /*
497  * ReleaseGenericPlan: release a CachedPlanSource's generic plan, if any.
498  */
499 static void
500 ReleaseGenericPlan(CachedPlanSource *plansource)
501 {
502         /* Be paranoid about the possibility that ReleaseCachedPlan fails */
503         if (plansource->gplan)
504         {
505                 CachedPlan *plan = plansource->gplan;
506
507                 Assert(plan->magic == CACHEDPLAN_MAGIC);
508                 plansource->gplan = NULL;
509                 ReleaseCachedPlan(plan, false);
510         }
511 }
512
513 /*
514  * RevalidateCachedQuery: ensure validity of analyzed-and-rewritten query tree.
515  *
516  * What we do here is re-acquire locks and redo parse analysis if necessary.
517  * On return, the query_list is valid and we have sufficient locks to begin
518  * planning.
519  *
520  * If any parse analysis activity is required, the caller's memory context is
521  * used for that work.
522  *
523  * The result value is the transient analyzed-and-rewritten query tree if we
524  * had to do re-analysis, and NIL otherwise.  (This is returned just to save
525  * a tree copying step in a subsequent BuildCachedPlan call.)
526  */
527 static List *
528 RevalidateCachedQuery(CachedPlanSource *plansource)
529 {
530         bool            snapshot_set;
531         Node       *rawtree;
532         List       *tlist;                      /* transient query-tree list */
533         List       *qlist;                      /* permanent query-tree list */
534         TupleDesc       resultDesc;
535         MemoryContext querytree_context;
536         MemoryContext oldcxt;
537
538         /*
539          * For one-shot plans, we do not support revalidation checking; it's
540          * assumed the query is parsed, planned, and executed in one transaction,
541          * so that no lock re-acquisition is necessary.
542          */
543         if (plansource->is_oneshot)
544         {
545                 Assert(plansource->is_valid);
546                 return NIL;
547         }
548
549         /*
550          * If the query is currently valid, acquire locks on the referenced
551          * objects; then check again.  We need to do it this way to cover the race
552          * condition that an invalidation message arrives before we get the locks.
553          */
554         if (plansource->is_valid)
555         {
556                 AcquirePlannerLocks(plansource->query_list, true);
557
558                 /*
559                  * By now, if any invalidation has happened, the inval callback
560                  * functions will have marked the query invalid.
561                  */
562                 if (plansource->is_valid)
563                 {
564                         /* Successfully revalidated and locked the query. */
565                         return NIL;
566                 }
567
568                 /* Ooops, the race case happened.  Release useless locks. */
569                 AcquirePlannerLocks(plansource->query_list, false);
570         }
571
572         /*
573          * Discard the no-longer-useful query tree.  (Note: we don't want to do
574          * this any earlier, else we'd not have been able to release locks
575          * correctly in the race condition case.)
576          */
577         plansource->is_valid = false;
578         plansource->query_list = NIL;
579         plansource->relationOids = NIL;
580         plansource->invalItems = NIL;
581
582         /*
583          * Free the query_context.      We don't really expect MemoryContextDelete to
584          * fail, but just in case, make sure the CachedPlanSource is left in a
585          * reasonably sane state.  (The generic plan won't get unlinked yet, but
586          * that's acceptable.)
587          */
588         if (plansource->query_context)
589         {
590                 MemoryContext qcxt = plansource->query_context;
591
592                 plansource->query_context = NULL;
593                 MemoryContextDelete(qcxt);
594         }
595
596         /* Drop the generic plan reference if any */
597         ReleaseGenericPlan(plansource);
598
599         /*
600          * Now re-do parse analysis and rewrite.  This not incidentally acquires
601          * the locks we need to do planning safely.
602          */
603         Assert(plansource->is_complete);
604
605         /*
606          * Restore the search_path that was in use when the plan was made. See
607          * comments for PushOverrideSearchPath about limitations of this.
608          *
609          * (XXX is there anything else we really need to restore?)
610          */
611         PushOverrideSearchPath(plansource->search_path);
612
613         /*
614          * If a snapshot is already set (the normal case), we can just use that
615          * for parsing/planning.  But if it isn't, install one.  Note: no point in
616          * checking whether parse analysis requires a snapshot; utility commands
617          * don't have invalidatable plans, so we'd not get here for such a
618          * command.
619          */
620         snapshot_set = false;
621         if (!ActiveSnapshotSet())
622         {
623                 PushActiveSnapshot(GetTransactionSnapshot());
624                 snapshot_set = true;
625         }
626
627         /*
628          * Run parse analysis and rule rewriting.  The parser tends to scribble on
629          * its input, so we must copy the raw parse tree to prevent corruption of
630          * the cache.
631          */
632         rawtree = copyObject(plansource->raw_parse_tree);
633         if (plansource->parserSetup != NULL)
634                 tlist = pg_analyze_and_rewrite_params(rawtree,
635                                                                                           plansource->query_string,
636                                                                                           plansource->parserSetup,
637                                                                                           plansource->parserSetupArg);
638         else
639                 tlist = pg_analyze_and_rewrite(rawtree,
640                                                                            plansource->query_string,
641                                                                            plansource->param_types,
642                                                                            plansource->num_params);
643
644         /* Release snapshot if we got one */
645         if (snapshot_set)
646                 PopActiveSnapshot();
647
648         /* Now we can restore current search path */
649         PopOverrideSearchPath();
650
651         /*
652          * Check or update the result tupdesc.  XXX should we use a weaker
653          * condition than equalTupleDescs() here?
654          *
655          * We assume the parameter types didn't change from the first time, so no
656          * need to update that.
657          */
658         resultDesc = PlanCacheComputeResultDesc(tlist);
659         if (resultDesc == NULL && plansource->resultDesc == NULL)
660         {
661                 /* OK, doesn't return tuples */
662         }
663         else if (resultDesc == NULL || plansource->resultDesc == NULL ||
664                          !equalTupleDescs(resultDesc, plansource->resultDesc))
665         {
666                 /* can we give a better error message? */
667                 if (plansource->fixed_result)
668                         ereport(ERROR,
669                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
670                                          errmsg("cached plan must not change result type")));
671                 oldcxt = MemoryContextSwitchTo(plansource->context);
672                 if (resultDesc)
673                         resultDesc = CreateTupleDescCopy(resultDesc);
674                 if (plansource->resultDesc)
675                         FreeTupleDesc(plansource->resultDesc);
676                 plansource->resultDesc = resultDesc;
677                 MemoryContextSwitchTo(oldcxt);
678         }
679
680         /*
681          * Allocate new query_context and copy the completed querytree into it.
682          * It's transient until we complete the copying and dependency extraction.
683          */
684         querytree_context = AllocSetContextCreate(CurrentMemoryContext,
685                                                                                           "CachedPlanQuery",
686                                                                                           ALLOCSET_SMALL_MINSIZE,
687                                                                                           ALLOCSET_SMALL_INITSIZE,
688                                                                                           ALLOCSET_DEFAULT_MAXSIZE);
689         oldcxt = MemoryContextSwitchTo(querytree_context);
690
691         qlist = (List *) copyObject(tlist);
692
693         /*
694          * Use the planner machinery to extract dependencies.  Data is saved in
695          * query_context.  (We assume that not a lot of extra cruft is created by
696          * this call.)
697          */
698         extract_query_dependencies((Node *) qlist,
699                                                            &plansource->relationOids,
700                                                            &plansource->invalItems);
701
702         MemoryContextSwitchTo(oldcxt);
703
704         /* Now reparent the finished query_context and save the links */
705         MemoryContextSetParent(querytree_context, plansource->context);
706
707         plansource->query_context = querytree_context;
708         plansource->query_list = qlist;
709
710         /*
711          * Note: we do not reset generic_cost or total_custom_cost, although we
712          * could choose to do so.  If the DDL or statistics change that prompted
713          * the invalidation meant a significant change in the cost estimates, it
714          * would be better to reset those variables and start fresh; but often it
715          * doesn't, and we're better retaining our hard-won knowledge about the
716          * relative costs.
717          */
718
719         plansource->is_valid = true;
720
721         /* Return transient copy of querytrees for possible use in planning */
722         return tlist;
723 }
724
725 /*
726  * CheckCachedPlan: see if the CachedPlanSource's generic plan is valid.
727  *
728  * Caller must have already called RevalidateCachedQuery to verify that the
729  * querytree is up to date.
730  *
731  * On a "true" return, we have acquired the locks needed to run the plan.
732  * (We must do this for the "true" result to be race-condition-free.)
733  */
734 static bool
735 CheckCachedPlan(CachedPlanSource *plansource)
736 {
737         CachedPlan *plan = plansource->gplan;
738
739         /* Assert that caller checked the querytree */
740         Assert(plansource->is_valid);
741
742         /* If there's no generic plan, just say "false" */
743         if (!plan)
744                 return false;
745
746         Assert(plan->magic == CACHEDPLAN_MAGIC);
747         /* Generic plans are never one-shot */
748         Assert(!plan->is_oneshot);
749
750         /*
751          * If it appears valid, acquire locks and recheck; this is much the same
752          * logic as in RevalidateCachedQuery, but for a plan.
753          */
754         if (plan->is_valid)
755         {
756                 /*
757                  * Plan must have positive refcount because it is referenced by
758                  * plansource; so no need to fear it disappears under us here.
759                  */
760                 Assert(plan->refcount > 0);
761
762                 AcquireExecutorLocks(plan->stmt_list, true);
763
764                 /*
765                  * If plan was transient, check to see if TransactionXmin has
766                  * advanced, and if so invalidate it.
767                  */
768                 if (plan->is_valid &&
769                         TransactionIdIsValid(plan->saved_xmin) &&
770                         !TransactionIdEquals(plan->saved_xmin, TransactionXmin))
771                         plan->is_valid = false;
772
773                 /*
774                  * By now, if any invalidation has happened, the inval callback
775                  * functions will have marked the plan invalid.
776                  */
777                 if (plan->is_valid)
778                 {
779                         /* Successfully revalidated and locked the query. */
780                         return true;
781                 }
782
783                 /* Ooops, the race case happened.  Release useless locks. */
784                 AcquireExecutorLocks(plan->stmt_list, false);
785         }
786
787         /*
788          * Plan has been invalidated, so unlink it from the parent and release it.
789          */
790         ReleaseGenericPlan(plansource);
791
792         return false;
793 }
794
795 /*
796  * BuildCachedPlan: construct a new CachedPlan from a CachedPlanSource.
797  *
798  * qlist should be the result value from a previous RevalidateCachedQuery,
799  * or it can be set to NIL if we need to re-copy the plansource's query_list.
800  *
801  * To build a generic, parameter-value-independent plan, pass NULL for
802  * boundParams.  To build a custom plan, pass the actual parameter values via
803  * boundParams.  For best effect, the PARAM_FLAG_CONST flag should be set on
804  * each parameter value; otherwise the planner will treat the value as a
805  * hint rather than a hard constant.
806  *
807  * Planning work is done in the caller's memory context.  The finished plan
808  * is in a child memory context, which typically should get reparented
809  * (unless this is a one-shot plan, in which case we don't copy the plan).
810  */
811 static CachedPlan *
812 BuildCachedPlan(CachedPlanSource *plansource, List *qlist,
813                                 ParamListInfo boundParams)
814 {
815         CachedPlan *plan;
816         List       *plist;
817         bool            snapshot_set;
818         bool            spi_pushed;
819         MemoryContext plan_context;
820         MemoryContext oldcxt = CurrentMemoryContext;
821
822         /*
823          * Normally the querytree should be valid already, but if it's not,
824          * rebuild it.
825          *
826          * NOTE: GetCachedPlan should have called RevalidateCachedQuery first, so
827          * we ought to be holding sufficient locks to prevent any invalidation.
828          * However, if we're building a custom plan after having built and
829          * rejected a generic plan, it's possible to reach here with is_valid
830          * false due to an invalidation while making the generic plan.  In theory
831          * the invalidation must be a false positive, perhaps a consequence of an
832          * sinval reset event or the CLOBBER_CACHE_ALWAYS debug code.  But for
833          * safety, let's treat it as real and redo the RevalidateCachedQuery call.
834          */
835         if (!plansource->is_valid)
836                 qlist = RevalidateCachedQuery(plansource);
837
838         /*
839          * If we don't already have a copy of the querytree list that can be
840          * scribbled on by the planner, make one.  For a one-shot plan, we assume
841          * it's okay to scribble on the original query_list.
842          */
843         if (qlist == NIL)
844         {
845                 if (!plansource->is_oneshot)
846                         qlist = (List *) copyObject(plansource->query_list);
847                 else
848                         qlist = plansource->query_list;
849         }
850
851         /*
852          * Restore the search_path that was in use when the plan was made. See
853          * comments for PushOverrideSearchPath about limitations of this.
854          *
855          * (XXX is there anything else we really need to restore?)
856          *
857          * Note: it's a bit annoying to do this and snapshot-setting twice in the
858          * case where we have to do both re-analysis and re-planning.  However,
859          * until there's some evidence that the cost is actually meaningful
860          * compared to parse analysis + planning, I'm not going to contort the
861          * code enough to avoid that.
862          */
863         PushOverrideSearchPath(plansource->search_path);
864
865         /*
866          * If a snapshot is already set (the normal case), we can just use that
867          * for planning.  But if it isn't, and we need one, install one.
868          */
869         snapshot_set = false;
870         if (!ActiveSnapshotSet() &&
871                 analyze_requires_snapshot(plansource->raw_parse_tree))
872         {
873                 PushActiveSnapshot(GetTransactionSnapshot());
874                 snapshot_set = true;
875         }
876
877         /*
878          * The planner may try to call SPI-using functions, which causes a problem
879          * if we're already inside one.  Rather than expect all SPI-using code to
880          * do SPI_push whenever a replan could happen, it seems best to take care
881          * of the case here.
882          */
883         spi_pushed = SPI_push_conditional();
884
885         /*
886          * Generate the plan.
887          */
888         plist = pg_plan_queries(qlist, plansource->cursor_options, boundParams);
889
890         /* Clean up SPI state */
891         SPI_pop_conditional(spi_pushed);
892
893         /* Release snapshot if we got one */
894         if (snapshot_set)
895                 PopActiveSnapshot();
896
897         /* Now we can restore current search path */
898         PopOverrideSearchPath();
899
900         /*
901          * Normally we make a dedicated memory context for the CachedPlan and its
902          * subsidiary data.  (It's probably not going to be large, but just in
903          * case, use the default maxsize parameter.  It's transient for the
904          * moment.)  But for a one-shot plan, we just leave it in the caller's
905          * memory context.
906          */
907         if (!plansource->is_oneshot)
908         {
909                 plan_context = AllocSetContextCreate(CurrentMemoryContext,
910                                                                                          "CachedPlan",
911                                                                                          ALLOCSET_SMALL_MINSIZE,
912                                                                                          ALLOCSET_SMALL_INITSIZE,
913                                                                                          ALLOCSET_DEFAULT_MAXSIZE);
914
915                 /*
916                  * Copy plan into the new context.
917                  */
918                 MemoryContextSwitchTo(plan_context);
919
920                 plist = (List *) copyObject(plist);
921         }
922         else
923                 plan_context = CurrentMemoryContext;
924
925         /*
926          * Create and fill the CachedPlan struct within the new context.
927          */
928         plan = (CachedPlan *) palloc(sizeof(CachedPlan));
929         plan->magic = CACHEDPLAN_MAGIC;
930         plan->stmt_list = plist;
931         if (plan_list_is_transient(plist))
932         {
933                 Assert(TransactionIdIsNormal(TransactionXmin));
934                 plan->saved_xmin = TransactionXmin;
935         }
936         else
937                 plan->saved_xmin = InvalidTransactionId;
938         plan->refcount = 0;
939         plan->context = plan_context;
940         plan->is_oneshot = plansource->is_oneshot;
941         plan->is_saved = false;
942         plan->is_valid = true;
943
944         /* assign generation number to new plan */
945         plan->generation = ++(plansource->generation);
946
947         MemoryContextSwitchTo(oldcxt);
948
949         return plan;
950 }
951
952 /*
953  * choose_custom_plan: choose whether to use custom or generic plan
954  *
955  * This defines the policy followed by GetCachedPlan.
956  */
957 static bool
958 choose_custom_plan(CachedPlanSource *plansource, ParamListInfo boundParams)
959 {
960         double          avg_custom_cost;
961
962         /* One-shot plans will always be considered custom */
963         if (plansource->is_oneshot)
964                 return true;
965
966         /* Otherwise, never any point in a custom plan if there's no parameters */
967         if (boundParams == NULL)
968                 return false;
969
970         /* See if caller wants to force the decision */
971         if (plansource->cursor_options & CURSOR_OPT_GENERIC_PLAN)
972                 return false;
973         if (plansource->cursor_options & CURSOR_OPT_CUSTOM_PLAN)
974                 return true;
975
976         /* Generate custom plans until we have done at least 5 (arbitrary) */
977         if (plansource->num_custom_plans < 5)
978                 return true;
979
980         avg_custom_cost = plansource->total_custom_cost / plansource->num_custom_plans;
981
982         /*
983          * Prefer generic plan if it's less than 10% more expensive than average
984          * custom plan.  This threshold is a bit arbitrary; it'd be better if we
985          * had some means of comparing planning time to the estimated runtime cost
986          * differential.
987          *
988          * Note that if generic_cost is -1 (indicating we've not yet determined
989          * the generic plan cost), we'll always prefer generic at this point.
990          */
991         if (plansource->generic_cost < avg_custom_cost * 1.1)
992                 return false;
993
994         return true;
995 }
996
997 /*
998  * cached_plan_cost: calculate estimated cost of a plan
999  */
1000 static double
1001 cached_plan_cost(CachedPlan *plan)
1002 {
1003         double          result = 0;
1004         ListCell   *lc;
1005
1006         foreach(lc, plan->stmt_list)
1007         {
1008                 PlannedStmt *plannedstmt = (PlannedStmt *) lfirst(lc);
1009
1010                 if (!IsA(plannedstmt, PlannedStmt))
1011                         continue;                       /* Ignore utility statements */
1012
1013                 result += plannedstmt->planTree->total_cost;
1014         }
1015
1016         return result;
1017 }
1018
1019 /*
1020  * GetCachedPlan: get a cached plan from a CachedPlanSource.
1021  *
1022  * This function hides the logic that decides whether to use a generic
1023  * plan or a custom plan for the given parameters: the caller does not know
1024  * which it will get.
1025  *
1026  * On return, the plan is valid and we have sufficient locks to begin
1027  * execution.
1028  *
1029  * On return, the refcount of the plan has been incremented; a later
1030  * ReleaseCachedPlan() call is expected.  The refcount has been reported
1031  * to the CurrentResourceOwner if useResOwner is true (note that that must
1032  * only be true if it's a "saved" CachedPlanSource).
1033  *
1034  * Note: if any replanning activity is required, the caller's memory context
1035  * is used for that work.
1036  */
1037 CachedPlan *
1038 GetCachedPlan(CachedPlanSource *plansource, ParamListInfo boundParams,
1039                           bool useResOwner)
1040 {
1041         CachedPlan *plan;
1042         List       *qlist;
1043         bool            customplan;
1044
1045         /* Assert caller is doing things in a sane order */
1046         Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1047         Assert(plansource->is_complete);
1048         /* This seems worth a real test, though */
1049         if (useResOwner && !plansource->is_saved)
1050                 elog(ERROR, "cannot apply ResourceOwner to non-saved cached plan");
1051
1052         /* Make sure the querytree list is valid and we have parse-time locks */
1053         qlist = RevalidateCachedQuery(plansource);
1054
1055         /* Decide whether to use a custom plan */
1056         customplan = choose_custom_plan(plansource, boundParams);
1057
1058         if (!customplan)
1059         {
1060                 if (CheckCachedPlan(plansource))
1061                 {
1062                         /* We want a generic plan, and we already have a valid one */
1063                         plan = plansource->gplan;
1064                         Assert(plan->magic == CACHEDPLAN_MAGIC);
1065                 }
1066                 else
1067                 {
1068                         /* Build a new generic plan */
1069                         plan = BuildCachedPlan(plansource, qlist, NULL);
1070                         /* Just make real sure plansource->gplan is clear */
1071                         ReleaseGenericPlan(plansource);
1072                         /* Link the new generic plan into the plansource */
1073                         plansource->gplan = plan;
1074                         plan->refcount++;
1075                         /* Immediately reparent into appropriate context */
1076                         if (plansource->is_saved)
1077                         {
1078                                 /* saved plans all live under CacheMemoryContext */
1079                                 MemoryContextSetParent(plan->context, CacheMemoryContext);
1080                                 plan->is_saved = true;
1081                         }
1082                         else
1083                         {
1084                                 /* otherwise, it should be a sibling of the plansource */
1085                                 MemoryContextSetParent(plan->context,
1086                                                                 MemoryContextGetParent(plansource->context));
1087                         }
1088                         /* Update generic_cost whenever we make a new generic plan */
1089                         plansource->generic_cost = cached_plan_cost(plan);
1090
1091                         /*
1092                          * If, based on the now-known value of generic_cost, we'd not have
1093                          * chosen to use a generic plan, then forget it and make a custom
1094                          * plan.  This is a bit of a wart but is necessary to avoid a
1095                          * glitch in behavior when the custom plans are consistently big
1096                          * winners; at some point we'll experiment with a generic plan and
1097                          * find it's a loser, but we don't want to actually execute that
1098                          * plan.
1099                          */
1100                         customplan = choose_custom_plan(plansource, boundParams);
1101
1102                         /*
1103                          * If we choose to plan again, we need to re-copy the query_list,
1104                          * since the planner probably scribbled on it.  We can force
1105                          * BuildCachedPlan to do that by passing NIL.
1106                          */
1107                         qlist = NIL;
1108                 }
1109         }
1110
1111         if (customplan)
1112         {
1113                 /* Build a custom plan */
1114                 plan = BuildCachedPlan(plansource, qlist, boundParams);
1115                 /* Accumulate total costs of custom plans, but 'ware overflow */
1116                 if (plansource->num_custom_plans < INT_MAX)
1117                 {
1118                         plansource->total_custom_cost += cached_plan_cost(plan);
1119                         plansource->num_custom_plans++;
1120                 }
1121         }
1122
1123         /* Flag the plan as in use by caller */
1124         if (useResOwner)
1125                 ResourceOwnerEnlargePlanCacheRefs(CurrentResourceOwner);
1126         plan->refcount++;
1127         if (useResOwner)
1128                 ResourceOwnerRememberPlanCacheRef(CurrentResourceOwner, plan);
1129
1130         /*
1131          * Saved plans should be under CacheMemoryContext so they will not go away
1132          * until their reference count goes to zero.  In the generic-plan cases we
1133          * already took care of that, but for a custom plan, do it as soon as we
1134          * have created a reference-counted link.
1135          */
1136         if (customplan && plansource->is_saved)
1137         {
1138                 MemoryContextSetParent(plan->context, CacheMemoryContext);
1139                 plan->is_saved = true;
1140         }
1141
1142         return plan;
1143 }
1144
1145 /*
1146  * ReleaseCachedPlan: release active use of a cached plan.
1147  *
1148  * This decrements the reference count, and frees the plan if the count
1149  * has thereby gone to zero.  If useResOwner is true, it is assumed that
1150  * the reference count is managed by the CurrentResourceOwner.
1151  *
1152  * Note: useResOwner = false is used for releasing references that are in
1153  * persistent data structures, such as the parent CachedPlanSource or a
1154  * Portal.      Transient references should be protected by a resource owner.
1155  */
1156 void
1157 ReleaseCachedPlan(CachedPlan *plan, bool useResOwner)
1158 {
1159         Assert(plan->magic == CACHEDPLAN_MAGIC);
1160         if (useResOwner)
1161         {
1162                 Assert(plan->is_saved);
1163                 ResourceOwnerForgetPlanCacheRef(CurrentResourceOwner, plan);
1164         }
1165         Assert(plan->refcount > 0);
1166         plan->refcount--;
1167         if (plan->refcount == 0)
1168         {
1169                 /* Mark it no longer valid */
1170                 plan->magic = 0;
1171
1172                 /* One-shot plans do not own their context, so we can't free them */
1173                 if (!plan->is_oneshot)
1174                         MemoryContextDelete(plan->context);
1175         }
1176 }
1177
1178 /*
1179  * CachedPlanSetParentContext: move a CachedPlanSource to a new memory context
1180  *
1181  * This can only be applied to unsaved plans; once saved, a plan always
1182  * lives underneath CacheMemoryContext.
1183  */
1184 void
1185 CachedPlanSetParentContext(CachedPlanSource *plansource,
1186                                                    MemoryContext newcontext)
1187 {
1188         /* Assert caller is doing things in a sane order */
1189         Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1190         Assert(plansource->is_complete);
1191
1192         /* These seem worth real tests, though */
1193         if (plansource->is_saved)
1194                 elog(ERROR, "cannot move a saved cached plan to another context");
1195         if (plansource->is_oneshot)
1196                 elog(ERROR, "cannot move a one-shot cached plan to another context");
1197
1198         /* OK, let the caller keep the plan where he wishes */
1199         MemoryContextSetParent(plansource->context, newcontext);
1200
1201         /*
1202          * The query_context needs no special handling, since it's a child of
1203          * plansource->context.  But if there's a generic plan, it should be
1204          * maintained as a sibling of plansource->context.
1205          */
1206         if (plansource->gplan)
1207         {
1208                 Assert(plansource->gplan->magic == CACHEDPLAN_MAGIC);
1209                 MemoryContextSetParent(plansource->gplan->context, newcontext);
1210         }
1211 }
1212
1213 /*
1214  * CopyCachedPlan: make a copy of a CachedPlanSource
1215  *
1216  * This is a convenience routine that does the equivalent of
1217  * CreateCachedPlan + CompleteCachedPlan, using the data stored in the
1218  * input CachedPlanSource.      The result is therefore "unsaved" (regardless
1219  * of the state of the source), and we don't copy any generic plan either.
1220  * The result will be currently valid, or not, the same as the source.
1221  */
1222 CachedPlanSource *
1223 CopyCachedPlan(CachedPlanSource *plansource)
1224 {
1225         CachedPlanSource *newsource;
1226         MemoryContext source_context;
1227         MemoryContext querytree_context;
1228         MemoryContext oldcxt;
1229
1230         Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1231         Assert(plansource->is_complete);
1232
1233         /*
1234          * One-shot plans can't be copied, because we haven't taken care that
1235          * parsing/planning didn't scribble on the raw parse tree or querytrees.
1236          */
1237         if (plansource->is_oneshot)
1238                 elog(ERROR, "cannot copy a one-shot cached plan");
1239
1240         source_context = AllocSetContextCreate(CurrentMemoryContext,
1241                                                                                    "CachedPlanSource",
1242                                                                                    ALLOCSET_SMALL_MINSIZE,
1243                                                                                    ALLOCSET_SMALL_INITSIZE,
1244                                                                                    ALLOCSET_DEFAULT_MAXSIZE);
1245
1246         oldcxt = MemoryContextSwitchTo(source_context);
1247
1248         newsource = (CachedPlanSource *) palloc0(sizeof(CachedPlanSource));
1249         newsource->magic = CACHEDPLANSOURCE_MAGIC;
1250         newsource->raw_parse_tree = copyObject(plansource->raw_parse_tree);
1251         newsource->query_string = pstrdup(plansource->query_string);
1252         newsource->commandTag = plansource->commandTag;
1253         if (plansource->num_params > 0)
1254         {
1255                 newsource->param_types = (Oid *)
1256                         palloc(plansource->num_params * sizeof(Oid));
1257                 memcpy(newsource->param_types, plansource->param_types,
1258                            plansource->num_params * sizeof(Oid));
1259         }
1260         else
1261                 newsource->param_types = NULL;
1262         newsource->num_params = plansource->num_params;
1263         newsource->parserSetup = plansource->parserSetup;
1264         newsource->parserSetupArg = plansource->parserSetupArg;
1265         newsource->cursor_options = plansource->cursor_options;
1266         newsource->fixed_result = plansource->fixed_result;
1267         if (plansource->resultDesc)
1268                 newsource->resultDesc = CreateTupleDescCopy(plansource->resultDesc);
1269         else
1270                 newsource->resultDesc = NULL;
1271         newsource->search_path = CopyOverrideSearchPath(plansource->search_path);
1272         newsource->context = source_context;
1273
1274         querytree_context = AllocSetContextCreate(source_context,
1275                                                                                           "CachedPlanQuery",
1276                                                                                           ALLOCSET_SMALL_MINSIZE,
1277                                                                                           ALLOCSET_SMALL_INITSIZE,
1278                                                                                           ALLOCSET_DEFAULT_MAXSIZE);
1279         MemoryContextSwitchTo(querytree_context);
1280         newsource->query_list = (List *) copyObject(plansource->query_list);
1281         newsource->relationOids = (List *) copyObject(plansource->relationOids);
1282         newsource->invalItems = (List *) copyObject(plansource->invalItems);
1283         newsource->query_context = querytree_context;
1284
1285         newsource->gplan = NULL;
1286
1287         newsource->is_oneshot = false;
1288         newsource->is_complete = true;
1289         newsource->is_saved = false;
1290         newsource->is_valid = plansource->is_valid;
1291         newsource->generation = plansource->generation;
1292         newsource->next_saved = NULL;
1293
1294         /* We may as well copy any acquired cost knowledge */
1295         newsource->generic_cost = plansource->generic_cost;
1296         newsource->total_custom_cost = plansource->total_custom_cost;
1297         newsource->num_custom_plans = plansource->num_custom_plans;
1298
1299         MemoryContextSwitchTo(oldcxt);
1300
1301         return newsource;
1302 }
1303
1304 /*
1305  * CachedPlanIsValid: test whether the rewritten querytree within a
1306  * CachedPlanSource is currently valid (that is, not marked as being in need
1307  * of revalidation).
1308  *
1309  * This result is only trustworthy (ie, free from race conditions) if
1310  * the caller has acquired locks on all the relations used in the plan.
1311  */
1312 bool
1313 CachedPlanIsValid(CachedPlanSource *plansource)
1314 {
1315         Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1316         return plansource->is_valid;
1317 }
1318
1319 /*
1320  * CachedPlanGetTargetList: return tlist, if any, describing plan's output
1321  *
1322  * The result is guaranteed up-to-date.  However, it is local storage
1323  * within the cached plan, and may disappear next time the plan is updated.
1324  */
1325 List *
1326 CachedPlanGetTargetList(CachedPlanSource *plansource)
1327 {
1328         Node       *pstmt;
1329
1330         /* Assert caller is doing things in a sane order */
1331         Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1332         Assert(plansource->is_complete);
1333
1334         /*
1335          * No work needed if statement doesn't return tuples (we assume this
1336          * feature cannot be changed by an invalidation)
1337          */
1338         if (plansource->resultDesc == NULL)
1339                 return NIL;
1340
1341         /* Make sure the querytree list is valid and we have parse-time locks */
1342         RevalidateCachedQuery(plansource);
1343
1344         /* Get the primary statement and find out what it returns */
1345         pstmt = PortalListGetPrimaryStmt(plansource->query_list);
1346
1347         return FetchStatementTargetList(pstmt);
1348 }
1349
1350 /*
1351  * AcquireExecutorLocks: acquire locks needed for execution of a cached plan;
1352  * or release them if acquire is false.
1353  */
1354 static void
1355 AcquireExecutorLocks(List *stmt_list, bool acquire)
1356 {
1357         ListCell   *lc1;
1358
1359         foreach(lc1, stmt_list)
1360         {
1361                 PlannedStmt *plannedstmt = (PlannedStmt *) lfirst(lc1);
1362                 int                     rt_index;
1363                 ListCell   *lc2;
1364
1365                 Assert(!IsA(plannedstmt, Query));
1366                 if (!IsA(plannedstmt, PlannedStmt))
1367                 {
1368                         /*
1369                          * Ignore utility statements, except those (such as EXPLAIN) that
1370                          * contain a parsed-but-not-planned query.      Note: it's okay to use
1371                          * ScanQueryForLocks, even though the query hasn't been through
1372                          * rule rewriting, because rewriting doesn't change the query
1373                          * representation.
1374                          */
1375                         Query      *query = UtilityContainsQuery((Node *) plannedstmt);
1376
1377                         if (query)
1378                                 ScanQueryForLocks(query, acquire);
1379                         continue;
1380                 }
1381
1382                 rt_index = 0;
1383                 foreach(lc2, plannedstmt->rtable)
1384                 {
1385                         RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc2);
1386                         LOCKMODE        lockmode;
1387                         PlanRowMark *rc;
1388
1389                         rt_index++;
1390
1391                         if (rte->rtekind != RTE_RELATION)
1392                                 continue;
1393
1394                         /*
1395                          * Acquire the appropriate type of lock on each relation OID. Note
1396                          * that we don't actually try to open the rel, and hence will not
1397                          * fail if it's been dropped entirely --- we'll just transiently
1398                          * acquire a non-conflicting lock.
1399                          */
1400                         if (list_member_int(plannedstmt->resultRelations, rt_index))
1401                                 lockmode = RowExclusiveLock;
1402                         else if ((rc = get_plan_rowmark(plannedstmt->rowMarks, rt_index)) != NULL &&
1403                                          RowMarkRequiresRowShareLock(rc->markType))
1404                                 lockmode = RowShareLock;
1405                         else
1406                                 lockmode = AccessShareLock;
1407
1408                         if (acquire)
1409                                 LockRelationOid(rte->relid, lockmode);
1410                         else
1411                                 UnlockRelationOid(rte->relid, lockmode);
1412                 }
1413         }
1414 }
1415
1416 /*
1417  * AcquirePlannerLocks: acquire locks needed for planning of a querytree list;
1418  * or release them if acquire is false.
1419  *
1420  * Note that we don't actually try to open the relations, and hence will not
1421  * fail if one has been dropped entirely --- we'll just transiently acquire
1422  * a non-conflicting lock.
1423  */
1424 static void
1425 AcquirePlannerLocks(List *stmt_list, bool acquire)
1426 {
1427         ListCell   *lc;
1428
1429         foreach(lc, stmt_list)
1430         {
1431                 Query      *query = (Query *) lfirst(lc);
1432
1433                 Assert(IsA(query, Query));
1434
1435                 if (query->commandType == CMD_UTILITY)
1436                 {
1437                         /* Ignore utility statements, unless they contain a Query */
1438                         query = UtilityContainsQuery(query->utilityStmt);
1439                         if (query)
1440                                 ScanQueryForLocks(query, acquire);
1441                         continue;
1442                 }
1443
1444                 ScanQueryForLocks(query, acquire);
1445         }
1446 }
1447
1448 /*
1449  * ScanQueryForLocks: recursively scan one Query for AcquirePlannerLocks.
1450  */
1451 static void
1452 ScanQueryForLocks(Query *parsetree, bool acquire)
1453 {
1454         ListCell   *lc;
1455         int                     rt_index;
1456
1457         /* Shouldn't get called on utility commands */
1458         Assert(parsetree->commandType != CMD_UTILITY);
1459
1460         /*
1461          * First, process RTEs of the current query level.
1462          */
1463         rt_index = 0;
1464         foreach(lc, parsetree->rtable)
1465         {
1466                 RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc);
1467                 LOCKMODE        lockmode;
1468
1469                 rt_index++;
1470                 switch (rte->rtekind)
1471                 {
1472                         case RTE_RELATION:
1473                                 /* Acquire or release the appropriate type of lock */
1474                                 if (rt_index == parsetree->resultRelation)
1475                                         lockmode = RowExclusiveLock;
1476                                 else if (get_parse_rowmark(parsetree, rt_index) != NULL)
1477                                         lockmode = RowShareLock;
1478                                 else
1479                                         lockmode = AccessShareLock;
1480                                 if (acquire)
1481                                         LockRelationOid(rte->relid, lockmode);
1482                                 else
1483                                         UnlockRelationOid(rte->relid, lockmode);
1484                                 break;
1485
1486                         case RTE_SUBQUERY:
1487                                 /* Recurse into subquery-in-FROM */
1488                                 ScanQueryForLocks(rte->subquery, acquire);
1489                                 break;
1490
1491                         default:
1492                                 /* ignore other types of RTEs */
1493                                 break;
1494                 }
1495         }
1496
1497         /* Recurse into subquery-in-WITH */
1498         foreach(lc, parsetree->cteList)
1499         {
1500                 CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
1501
1502                 ScanQueryForLocks((Query *) cte->ctequery, acquire);
1503         }
1504
1505         /*
1506          * Recurse into sublink subqueries, too.  But we already did the ones in
1507          * the rtable and cteList.
1508          */
1509         if (parsetree->hasSubLinks)
1510         {
1511                 query_tree_walker(parsetree, ScanQueryWalker,
1512                                                   (void *) &acquire,
1513                                                   QTW_IGNORE_RC_SUBQUERIES);
1514         }
1515 }
1516
1517 /*
1518  * Walker to find sublink subqueries for ScanQueryForLocks
1519  */
1520 static bool
1521 ScanQueryWalker(Node *node, bool *acquire)
1522 {
1523         if (node == NULL)
1524                 return false;
1525         if (IsA(node, SubLink))
1526         {
1527                 SubLink    *sub = (SubLink *) node;
1528
1529                 /* Do what we came for */
1530                 ScanQueryForLocks((Query *) sub->subselect, *acquire);
1531                 /* Fall through to process lefthand args of SubLink */
1532         }
1533
1534         /*
1535          * Do NOT recurse into Query nodes, because ScanQueryForLocks already
1536          * processed subselects of subselects for us.
1537          */
1538         return expression_tree_walker(node, ScanQueryWalker,
1539                                                                   (void *) acquire);
1540 }
1541
1542 /*
1543  * plan_list_is_transient: check if any of the plans in the list are transient.
1544  */
1545 static bool
1546 plan_list_is_transient(List *stmt_list)
1547 {
1548         ListCell   *lc;
1549
1550         foreach(lc, stmt_list)
1551         {
1552                 PlannedStmt *plannedstmt = (PlannedStmt *) lfirst(lc);
1553
1554                 if (!IsA(plannedstmt, PlannedStmt))
1555                         continue;                       /* Ignore utility statements */
1556
1557                 if (plannedstmt->transientPlan)
1558                         return true;
1559         }
1560
1561         return false;
1562 }
1563
1564 /*
1565  * PlanCacheComputeResultDesc: given a list of analyzed-and-rewritten Queries,
1566  * determine the result tupledesc it will produce.      Returns NULL if the
1567  * execution will not return tuples.
1568  *
1569  * Note: the result is created or copied into current memory context.
1570  */
1571 static TupleDesc
1572 PlanCacheComputeResultDesc(List *stmt_list)
1573 {
1574         Query      *query;
1575
1576         switch (ChoosePortalStrategy(stmt_list))
1577         {
1578                 case PORTAL_ONE_SELECT:
1579                 case PORTAL_ONE_MOD_WITH:
1580                         query = (Query *) linitial(stmt_list);
1581                         Assert(IsA(query, Query));
1582                         return ExecCleanTypeFromTL(query->targetList, false);
1583
1584                 case PORTAL_ONE_RETURNING:
1585                         query = (Query *) PortalListGetPrimaryStmt(stmt_list);
1586                         Assert(IsA(query, Query));
1587                         Assert(query->returningList);
1588                         return ExecCleanTypeFromTL(query->returningList, false);
1589
1590                 case PORTAL_UTIL_SELECT:
1591                         query = (Query *) linitial(stmt_list);
1592                         Assert(IsA(query, Query));
1593                         Assert(query->utilityStmt);
1594                         return UtilityTupleDescriptor(query->utilityStmt);
1595
1596                 case PORTAL_MULTI_QUERY:
1597                         /* will not return tuples */
1598                         break;
1599         }
1600         return NULL;
1601 }
1602
1603 /*
1604  * PlanCacheRelCallback
1605  *              Relcache inval callback function
1606  *
1607  * Invalidate all plans mentioning the given rel, or all plans mentioning
1608  * any rel at all if relid == InvalidOid.
1609  */
1610 static void
1611 PlanCacheRelCallback(Datum arg, Oid relid)
1612 {
1613         CachedPlanSource *plansource;
1614
1615         for (plansource = first_saved_plan; plansource; plansource = plansource->next_saved)
1616         {
1617                 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1618
1619                 /* No work if it's already invalidated */
1620                 if (!plansource->is_valid)
1621                         continue;
1622
1623                 /*
1624                  * Check the dependency list for the rewritten querytree.
1625                  */
1626                 if ((relid == InvalidOid) ? plansource->relationOids != NIL :
1627                         list_member_oid(plansource->relationOids, relid))
1628                 {
1629                         /* Invalidate the querytree and generic plan */
1630                         plansource->is_valid = false;
1631                         if (plansource->gplan)
1632                                 plansource->gplan->is_valid = false;
1633                 }
1634
1635                 /*
1636                  * The generic plan, if any, could have more dependencies than the
1637                  * querytree does, so we have to check it too.
1638                  */
1639                 if (plansource->gplan && plansource->gplan->is_valid)
1640                 {
1641                         ListCell   *lc;
1642
1643                         foreach(lc, plansource->gplan->stmt_list)
1644                         {
1645                                 PlannedStmt *plannedstmt = (PlannedStmt *) lfirst(lc);
1646
1647                                 Assert(!IsA(plannedstmt, Query));
1648                                 if (!IsA(plannedstmt, PlannedStmt))
1649                                         continue;       /* Ignore utility statements */
1650                                 if ((relid == InvalidOid) ? plannedstmt->relationOids != NIL :
1651                                         list_member_oid(plannedstmt->relationOids, relid))
1652                                 {
1653                                         /* Invalidate the generic plan only */
1654                                         plansource->gplan->is_valid = false;
1655                                         break;          /* out of stmt_list scan */
1656                                 }
1657                         }
1658                 }
1659         }
1660 }
1661
1662 /*
1663  * PlanCacheFuncCallback
1664  *              Syscache inval callback function for PROCOID cache
1665  *
1666  * Invalidate all plans mentioning the object with the specified hash value,
1667  * or all plans mentioning any member of this cache if hashvalue == 0.
1668  *
1669  * Note that the coding would support use for multiple caches, but right
1670  * now only user-defined functions are tracked this way.
1671  */
1672 static void
1673 PlanCacheFuncCallback(Datum arg, int cacheid, uint32 hashvalue)
1674 {
1675         CachedPlanSource *plansource;
1676
1677         for (plansource = first_saved_plan; plansource; plansource = plansource->next_saved)
1678         {
1679                 ListCell   *lc;
1680
1681                 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1682
1683                 /* No work if it's already invalidated */
1684                 if (!plansource->is_valid)
1685                         continue;
1686
1687                 /*
1688                  * Check the dependency list for the rewritten querytree.
1689                  */
1690                 foreach(lc, plansource->invalItems)
1691                 {
1692                         PlanInvalItem *item = (PlanInvalItem *) lfirst(lc);
1693
1694                         if (item->cacheId != cacheid)
1695                                 continue;
1696                         if (hashvalue == 0 ||
1697                                 item->hashValue == hashvalue)
1698                         {
1699                                 /* Invalidate the querytree and generic plan */
1700                                 plansource->is_valid = false;
1701                                 if (plansource->gplan)
1702                                         plansource->gplan->is_valid = false;
1703                                 break;
1704                         }
1705                 }
1706
1707                 /*
1708                  * The generic plan, if any, could have more dependencies than the
1709                  * querytree does, so we have to check it too.
1710                  */
1711                 if (plansource->gplan && plansource->gplan->is_valid)
1712                 {
1713                         foreach(lc, plansource->gplan->stmt_list)
1714                         {
1715                                 PlannedStmt *plannedstmt = (PlannedStmt *) lfirst(lc);
1716                                 ListCell   *lc3;
1717
1718                                 Assert(!IsA(plannedstmt, Query));
1719                                 if (!IsA(plannedstmt, PlannedStmt))
1720                                         continue;       /* Ignore utility statements */
1721                                 foreach(lc3, plannedstmt->invalItems)
1722                                 {
1723                                         PlanInvalItem *item = (PlanInvalItem *) lfirst(lc3);
1724
1725                                         if (item->cacheId != cacheid)
1726                                                 continue;
1727                                         if (hashvalue == 0 ||
1728                                                 item->hashValue == hashvalue)
1729                                         {
1730                                                 /* Invalidate the generic plan only */
1731                                                 plansource->gplan->is_valid = false;
1732                                                 break;  /* out of invalItems scan */
1733                                         }
1734                                 }
1735                                 if (!plansource->gplan->is_valid)
1736                                         break;          /* out of stmt_list scan */
1737                         }
1738                 }
1739         }
1740 }
1741
1742 /*
1743  * PlanCacheSysCallback
1744  *              Syscache inval callback function for other caches
1745  *
1746  * Just invalidate everything...
1747  */
1748 static void
1749 PlanCacheSysCallback(Datum arg, int cacheid, uint32 hashvalue)
1750 {
1751         ResetPlanCache();
1752 }
1753
1754 /*
1755  * ResetPlanCache: invalidate all cached plans.
1756  */
1757 void
1758 ResetPlanCache(void)
1759 {
1760         CachedPlanSource *plansource;
1761
1762         for (plansource = first_saved_plan; plansource; plansource = plansource->next_saved)
1763         {
1764                 ListCell   *lc;
1765
1766                 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1767
1768                 /* No work if it's already invalidated */
1769                 if (!plansource->is_valid)
1770                         continue;
1771
1772                 /*
1773                  * We *must not* mark transaction control statements as invalid,
1774                  * particularly not ROLLBACK, because they may need to be executed in
1775                  * aborted transactions when we can't revalidate them (cf bug #5269).
1776                  * In general there is no point in invalidating utility statements
1777                  * since they have no plans anyway.  So invalidate it only if it
1778                  * contains at least one non-utility statement, or contains a utility
1779                  * statement that contains a pre-analyzed query (which could have
1780                  * dependencies.)
1781                  */
1782                 foreach(lc, plansource->query_list)
1783                 {
1784                         Query      *query = (Query *) lfirst(lc);
1785
1786                         Assert(IsA(query, Query));
1787                         if (query->commandType != CMD_UTILITY ||
1788                                 UtilityContainsQuery(query->utilityStmt))
1789                         {
1790                                 /* non-utility statement, so invalidate */
1791                                 plansource->is_valid = false;
1792                                 if (plansource->gplan)
1793                                         plansource->gplan->is_valid = false;
1794                                 /* no need to look further */
1795                                 break;
1796                         }
1797                 }
1798         }
1799 }