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. We also force re-analysis and 19 * re-planning if the active search_path is different from the previous time 20 * or, if RLS is involved, if the user changes or the RLS environment changes. 21 * 22 * Note that if the sinval was a result of user DDL actions, parse analysis 23 * could throw an error, for example if a column referenced by the query is 24 * no longer present. Another possibility is for the query's output tupdesc 25 * to change (for instance "SELECT *" might expand differently than before). 26 * The creator of a cached plan can specify whether it is allowable for the 27 * query to change output tupdesc on replan --- if so, it's up to the 28 * caller to notice changes and cope with them. 29 * 30 * Currently, we track exactly the dependencies of plans on relations, 31 * user-defined functions, and domains. On relcache invalidation events or 32 * pg_proc or pg_type syscache invalidation events, we invalidate just those 33 * plans that depend on the particular object being modified. (Note: this 34 * scheme assumes that any table modification that requires replanning will 35 * generate a relcache inval event.) We also watch for inval events on 36 * certain other system catalogs, such as pg_namespace; but for them, our 37 * response is just to invalidate all plans. We expect updates on those 38 * catalogs to be infrequent enough that more-detailed tracking is not worth 39 * the effort. 40 * 41 * In addition to full-fledged query plans, we provide a facility for 42 * detecting invalidations of simple scalar expressions. This is fairly 43 * bare-bones; it's the caller's responsibility to build a new expression 44 * if the old one gets invalidated. 45 * 46 * 47 * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group 48 * Portions Copyright (c) 1994, Regents of the University of California 49 * 50 * IDENTIFICATION 51 * src/backend/utils/cache/plancache.c 52 * 53 *------------------------------------------------------------------------- 54 */ 55 #include "postgres.h" 56 57 #include <limits.h> 58 59 #include "access/transam.h" 60 #include "catalog/namespace.h" 61 #include "executor/executor.h" 62 #include "miscadmin.h" 63 #include "nodes/nodeFuncs.h" 64 #include "optimizer/optimizer.h" 65 #include "parser/analyze.h" 66 #include "parser/parsetree.h" 67 #include "storage/lmgr.h" 68 #include "tcop/pquery.h" 69 #include "tcop/utility.h" 70 #include "utils/inval.h" 71 #include "utils/memutils.h" 72 #include "utils/resowner_private.h" 73 #include "utils/rls.h" 74 #include "utils/snapmgr.h" 75 #include "utils/syscache.h" 76 77 78 /* 79 * We must skip "overhead" operations that involve database access when the 80 * cached plan's subject statement is a transaction control command. 81 */ 82 #define IsTransactionStmtPlan(plansource) \ 83 ((plansource)->raw_parse_tree && \ 84 IsA((plansource)->raw_parse_tree->stmt, TransactionStmt)) 85 86 /* 87 * This is the head of the backend's list of "saved" CachedPlanSources (i.e., 88 * those that are in long-lived storage and are examined for sinval events). 89 * We use a dlist instead of separate List cells so that we can guarantee 90 * to save a CachedPlanSource without error. 91 */ 92 static dlist_head saved_plan_list = DLIST_STATIC_INIT(saved_plan_list); 93 94 /* 95 * This is the head of the backend's list of CachedExpressions. 96 */ 97 static dlist_head cached_expression_list = DLIST_STATIC_INIT(cached_expression_list); 98 99 static void ReleaseGenericPlan(CachedPlanSource *plansource); 100 static List *RevalidateCachedQuery(CachedPlanSource *plansource, 101 QueryEnvironment *queryEnv); 102 static bool CheckCachedPlan(CachedPlanSource *plansource); 103 static CachedPlan *BuildCachedPlan(CachedPlanSource *plansource, List *qlist, 104 ParamListInfo boundParams, QueryEnvironment *queryEnv); 105 static bool choose_custom_plan(CachedPlanSource *plansource, 106 ParamListInfo boundParams); 107 static double cached_plan_cost(CachedPlan *plan, bool include_planner); 108 static Query *QueryListGetPrimaryStmt(List *stmts); 109 static void AcquireExecutorLocks(List *stmt_list, bool acquire); 110 static void AcquirePlannerLocks(List *stmt_list, bool acquire); 111 static void ScanQueryForLocks(Query *parsetree, bool acquire); 112 static bool ScanQueryWalker(Node *node, bool *acquire); 113 static TupleDesc PlanCacheComputeResultDesc(List *stmt_list); 114 static void PlanCacheRelCallback(Datum arg, Oid relid); 115 static void PlanCacheObjectCallback(Datum arg, int cacheid, uint32 hashvalue); 116 static void PlanCacheSysCallback(Datum arg, int cacheid, uint32 hashvalue); 117 118 /* GUC parameter */ 119 int plan_cache_mode; 120 121 /* 122 * InitPlanCache: initialize module during InitPostgres. 123 * 124 * All we need to do is hook into inval.c's callback lists. 125 */ 126 void 127 InitPlanCache(void) 128 { 129 CacheRegisterRelcacheCallback(PlanCacheRelCallback, (Datum) 0); 130 CacheRegisterSyscacheCallback(PROCOID, PlanCacheObjectCallback, (Datum) 0); 131 CacheRegisterSyscacheCallback(TYPEOID, PlanCacheObjectCallback, (Datum) 0); 132 CacheRegisterSyscacheCallback(NAMESPACEOID, PlanCacheSysCallback, (Datum) 0); 133 CacheRegisterSyscacheCallback(OPEROID, PlanCacheSysCallback, (Datum) 0); 134 CacheRegisterSyscacheCallback(AMOPOPID, PlanCacheSysCallback, (Datum) 0); 135 CacheRegisterSyscacheCallback(FOREIGNSERVEROID, PlanCacheSysCallback, (Datum) 0); 136 CacheRegisterSyscacheCallback(FOREIGNDATAWRAPPEROID, PlanCacheSysCallback, (Datum) 0); 137 } 138 139 /* 140 * CreateCachedPlan: initially create a plan cache entry. 141 * 142 * Creation of a cached plan is divided into two steps, CreateCachedPlan and 143 * CompleteCachedPlan. CreateCachedPlan should be called after running the 144 * query through raw_parser, but before doing parse analysis and rewrite; 145 * CompleteCachedPlan is called after that. The reason for this arrangement 146 * is that it can save one round of copying of the raw parse tree, since 147 * the parser will normally scribble on the raw parse tree. Callers would 148 * otherwise need to make an extra copy of the parse tree to ensure they 149 * still had a clean copy to present at plan cache creation time. 150 * 151 * All arguments presented to CreateCachedPlan are copied into a memory 152 * context created as a child of the call-time CurrentMemoryContext, which 153 * should be a reasonably short-lived working context that will go away in 154 * event of an error. This ensures that the cached plan data structure will 155 * likewise disappear if an error occurs before we have fully constructed it. 156 * Once constructed, the cached plan can be made longer-lived, if needed, 157 * by calling SaveCachedPlan. 158 * 159 * raw_parse_tree: output of raw_parser(), or NULL if empty query 160 * query_string: original query text 161 * commandTag: command tag for query, or UNKNOWN if empty query 162 */ 163 CachedPlanSource * 164 CreateCachedPlan(RawStmt *raw_parse_tree, 165 const char *query_string, 166 CommandTag commandTag) 167 { 168 CachedPlanSource *plansource; 169 MemoryContext source_context; 170 MemoryContext oldcxt; 171 172 Assert(query_string != NULL); /* required as of 8.4 */ 173 174 /* 175 * Make a dedicated memory context for the CachedPlanSource and its 176 * permanent subsidiary data. It's probably not going to be large, but 177 * just in case, allow it to grow large. Initially it's a child of the 178 * caller's context (which we assume to be transient), so that it will be 179 * cleaned up on error. 180 */ 181 source_context = AllocSetContextCreate(CurrentMemoryContext, 182 "CachedPlanSource", 183 ALLOCSET_START_SMALL_SIZES); 184 185 /* 186 * Create and fill the CachedPlanSource struct within the new context. 187 * Most fields are just left empty for the moment. 188 */ 189 oldcxt = MemoryContextSwitchTo(source_context); 190 191 plansource = (CachedPlanSource *) palloc0(sizeof(CachedPlanSource)); 192 plansource->magic = CACHEDPLANSOURCE_MAGIC; 193 plansource->raw_parse_tree = copyObject(raw_parse_tree); 194 plansource->query_string = pstrdup(query_string); 195 MemoryContextSetIdentifier(source_context, plansource->query_string); 196 plansource->commandTag = commandTag; 197 plansource->param_types = NULL; 198 plansource->num_params = 0; 199 plansource->parserSetup = NULL; 200 plansource->parserSetupArg = NULL; 201 plansource->cursor_options = 0; 202 plansource->fixed_result = false; 203 plansource->resultDesc = NULL; 204 plansource->context = source_context; 205 plansource->query_list = NIL; 206 plansource->relationOids = NIL; 207 plansource->invalItems = NIL; 208 plansource->search_path = NULL; 209 plansource->query_context = NULL; 210 plansource->rewriteRoleId = InvalidOid; 211 plansource->rewriteRowSecurity = false; 212 plansource->dependsOnRLS = false; 213 plansource->gplan = NULL; 214 plansource->is_oneshot = false; 215 plansource->is_complete = false; 216 plansource->is_saved = false; 217 plansource->is_valid = false; 218 plansource->generation = 0; 219 plansource->generic_cost = -1; 220 plansource->total_custom_cost = 0; 221 plansource->num_generic_plans = 0; 222 plansource->num_custom_plans = 0; 223 224 MemoryContextSwitchTo(oldcxt); 225 226 return plansource; 227 } 228 229 /* 230 * CreateOneShotCachedPlan: initially create a one-shot plan cache entry. 231 * 232 * This variant of CreateCachedPlan creates a plan cache entry that is meant 233 * to be used only once. No data copying occurs: all data structures remain 234 * in the caller's memory context (which typically should get cleared after 235 * completing execution). The CachedPlanSource struct itself is also created 236 * in that context. 237 * 238 * A one-shot plan cannot be saved or copied, since we make no effort to 239 * preserve the raw parse tree unmodified. There is also no support for 240 * invalidation, so plan use must be completed in the current transaction, 241 * and DDL that might invalidate the querytree_list must be avoided as well. 242 * 243 * raw_parse_tree: output of raw_parser(), or NULL if empty query 244 * query_string: original query text 245 * commandTag: command tag for query, or NULL if empty query 246 */ 247 CachedPlanSource * 248 CreateOneShotCachedPlan(RawStmt *raw_parse_tree, 249 const char *query_string, 250 CommandTag commandTag) 251 { 252 CachedPlanSource *plansource; 253 254 Assert(query_string != NULL); /* required as of 8.4 */ 255 256 /* 257 * Create and fill the CachedPlanSource struct within the caller's memory 258 * context. Most fields are just left empty for the moment. 259 */ 260 plansource = (CachedPlanSource *) palloc0(sizeof(CachedPlanSource)); 261 plansource->magic = CACHEDPLANSOURCE_MAGIC; 262 plansource->raw_parse_tree = raw_parse_tree; 263 plansource->query_string = query_string; 264 plansource->commandTag = commandTag; 265 plansource->param_types = NULL; 266 plansource->num_params = 0; 267 plansource->parserSetup = NULL; 268 plansource->parserSetupArg = NULL; 269 plansource->cursor_options = 0; 270 plansource->fixed_result = false; 271 plansource->resultDesc = NULL; 272 plansource->context = CurrentMemoryContext; 273 plansource->query_list = NIL; 274 plansource->relationOids = NIL; 275 plansource->invalItems = NIL; 276 plansource->search_path = NULL; 277 plansource->query_context = NULL; 278 plansource->rewriteRoleId = InvalidOid; 279 plansource->rewriteRowSecurity = false; 280 plansource->dependsOnRLS = false; 281 plansource->gplan = NULL; 282 plansource->is_oneshot = true; 283 plansource->is_complete = false; 284 plansource->is_saved = false; 285 plansource->is_valid = false; 286 plansource->generation = 0; 287 plansource->generic_cost = -1; 288 plansource->total_custom_cost = 0; 289 plansource->num_generic_plans = 0; 290 plansource->num_custom_plans = 0; 291 292 return plansource; 293 } 294 295 /* 296 * CompleteCachedPlan: second step of creating a plan cache entry. 297 * 298 * Pass in the analyzed-and-rewritten form of the query, as well as the 299 * required subsidiary data about parameters and such. All passed values will 300 * be copied into the CachedPlanSource's memory, except as specified below. 301 * After this is called, GetCachedPlan can be called to obtain a plan, and 302 * optionally the CachedPlanSource can be saved using SaveCachedPlan. 303 * 304 * If querytree_context is not NULL, the querytree_list must be stored in that 305 * context (but the other parameters need not be). The querytree_list is not 306 * copied, rather the given context is kept as the initial query_context of 307 * the CachedPlanSource. (It should have been created as a child of the 308 * caller's working memory context, but it will now be reparented to belong 309 * to the CachedPlanSource.) The querytree_context is normally the context in 310 * which the caller did raw parsing and parse analysis. This approach saves 311 * one tree copying step compared to passing NULL, but leaves lots of extra 312 * cruft in the query_context, namely whatever extraneous stuff parse analysis 313 * created, as well as whatever went unused from the raw parse tree. Using 314 * this option is a space-for-time tradeoff that is appropriate if the 315 * CachedPlanSource is not expected to survive long. 316 * 317 * plancache.c cannot know how to copy the data referenced by parserSetupArg, 318 * and it would often be inappropriate to do so anyway. When using that 319 * option, it is caller's responsibility that the referenced data remains 320 * valid for as long as the CachedPlanSource exists. 321 * 322 * If the CachedPlanSource is a "oneshot" plan, then no querytree copying 323 * occurs at all, and querytree_context is ignored; it is caller's 324 * responsibility that the passed querytree_list is sufficiently long-lived. 325 * 326 * plansource: structure returned by CreateCachedPlan 327 * querytree_list: analyzed-and-rewritten form of query (list of Query nodes) 328 * querytree_context: memory context containing querytree_list, 329 * or NULL to copy querytree_list into a fresh context 330 * param_types: array of fixed parameter type OIDs, or NULL if none 331 * num_params: number of fixed parameters 332 * parserSetup: alternate method for handling query parameters 333 * parserSetupArg: data to pass to parserSetup 334 * cursor_options: options bitmask to pass to planner 335 * fixed_result: true to disallow future changes in query's result tupdesc 336 */ 337 void 338 CompleteCachedPlan(CachedPlanSource *plansource, 339 List *querytree_list, 340 MemoryContext querytree_context, 341 Oid *param_types, 342 int num_params, 343 ParserSetupHook parserSetup, 344 void *parserSetupArg, 345 int cursor_options, 346 bool fixed_result) 347 { 348 MemoryContext source_context = plansource->context; 349 MemoryContext oldcxt = CurrentMemoryContext; 350 351 /* Assert caller is doing things in a sane order */ 352 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC); 353 Assert(!plansource->is_complete); 354 355 /* 356 * If caller supplied a querytree_context, reparent it underneath the 357 * CachedPlanSource's context; otherwise, create a suitable context and 358 * copy the querytree_list into it. But no data copying should be done 359 * for one-shot plans; for those, assume the passed querytree_list is 360 * sufficiently long-lived. 361 */ 362 if (plansource->is_oneshot) 363 { 364 querytree_context = CurrentMemoryContext; 365 } 366 else if (querytree_context != NULL) 367 { 368 MemoryContextSetParent(querytree_context, source_context); 369 MemoryContextSwitchTo(querytree_context); 370 } 371 else 372 { 373 /* Again, it's a good bet the querytree_context can be small */ 374 querytree_context = AllocSetContextCreate(source_context, 375 "CachedPlanQuery", 376 ALLOCSET_START_SMALL_SIZES); 377 MemoryContextSwitchTo(querytree_context); 378 querytree_list = copyObject(querytree_list); 379 } 380 381 plansource->query_context = querytree_context; 382 plansource->query_list = querytree_list; 383 384 if (!plansource->is_oneshot && !IsTransactionStmtPlan(plansource)) 385 { 386 /* 387 * Use the planner machinery to extract dependencies. Data is saved 388 * in query_context. (We assume that not a lot of extra cruft is 389 * created by this call.) We can skip this for one-shot plans, and 390 * transaction control commands have no such dependencies anyway. 391 */ 392 extract_query_dependencies((Node *) querytree_list, 393 &plansource->relationOids, 394 &plansource->invalItems, 395 &plansource->dependsOnRLS); 396 397 /* Update RLS info as well. */ 398 plansource->rewriteRoleId = GetUserId(); 399 plansource->rewriteRowSecurity = row_security; 400 401 /* 402 * Also save the current search_path in the query_context. (This 403 * should not generate much extra cruft either, since almost certainly 404 * the path is already valid.) Again, we don't really need this for 405 * one-shot plans; and we *must* skip this for transaction control 406 * commands, because this could result in catalog accesses. 407 */ 408 plansource->search_path = GetOverrideSearchPath(querytree_context); 409 } 410 411 /* 412 * Save the final parameter types (or other parameter specification data) 413 * into the source_context, as well as our other parameters. Also save 414 * the result tuple descriptor. 415 */ 416 MemoryContextSwitchTo(source_context); 417 418 if (num_params > 0) 419 { 420 plansource->param_types = (Oid *) palloc(num_params * sizeof(Oid)); 421 memcpy(plansource->param_types, param_types, num_params * sizeof(Oid)); 422 } 423 else 424 plansource->param_types = NULL; 425 plansource->num_params = num_params; 426 plansource->parserSetup = parserSetup; 427 plansource->parserSetupArg = parserSetupArg; 428 plansource->cursor_options = cursor_options; 429 plansource->fixed_result = fixed_result; 430 plansource->resultDesc = PlanCacheComputeResultDesc(querytree_list); 431 432 MemoryContextSwitchTo(oldcxt); 433 434 plansource->is_complete = true; 435 plansource->is_valid = true; 436 } 437 438 /* 439 * SaveCachedPlan: save a cached plan permanently 440 * 441 * This function moves the cached plan underneath CacheMemoryContext (making 442 * it live for the life of the backend, unless explicitly dropped), and adds 443 * it to the list of cached plans that are checked for invalidation when an 444 * sinval event occurs. 445 * 446 * This is guaranteed not to throw error, except for the caller-error case 447 * of trying to save a one-shot plan. Callers typically depend on that 448 * since this is called just before or just after adding a pointer to the 449 * CachedPlanSource to some permanent data structure of their own. Up until 450 * this is done, a CachedPlanSource is just transient data that will go away 451 * automatically on transaction abort. 452 */ 453 void 454 SaveCachedPlan(CachedPlanSource *plansource) 455 { 456 /* Assert caller is doing things in a sane order */ 457 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC); 458 Assert(plansource->is_complete); 459 Assert(!plansource->is_saved); 460 461 /* This seems worth a real test, though */ 462 if (plansource->is_oneshot) 463 elog(ERROR, "cannot save one-shot cached plan"); 464 465 /* 466 * In typical use, this function would be called before generating any 467 * plans from the CachedPlanSource. If there is a generic plan, moving it 468 * into CacheMemoryContext would be pretty risky since it's unclear 469 * whether the caller has taken suitable care with making references 470 * long-lived. Best thing to do seems to be to discard the plan. 471 */ 472 ReleaseGenericPlan(plansource); 473 474 /* 475 * Reparent the source memory context under CacheMemoryContext so that it 476 * will live indefinitely. The query_context follows along since it's 477 * already a child of the other one. 478 */ 479 MemoryContextSetParent(plansource->context, CacheMemoryContext); 480 481 /* 482 * Add the entry to the global list of cached plans. 483 */ 484 dlist_push_tail(&saved_plan_list, &plansource->node); 485 486 plansource->is_saved = true; 487 } 488 489 /* 490 * DropCachedPlan: destroy a cached plan. 491 * 492 * Actually this only destroys the CachedPlanSource: any referenced CachedPlan 493 * is released, but not destroyed until its refcount goes to zero. That 494 * handles the situation where DropCachedPlan is called while the plan is 495 * still in use. 496 */ 497 void 498 DropCachedPlan(CachedPlanSource *plansource) 499 { 500 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC); 501 502 /* If it's been saved, remove it from the list */ 503 if (plansource->is_saved) 504 { 505 dlist_delete(&plansource->node); 506 plansource->is_saved = false; 507 } 508 509 /* Decrement generic CachedPlan's refcount and drop if no longer needed */ 510 ReleaseGenericPlan(plansource); 511 512 /* Mark it no longer valid */ 513 plansource->magic = 0; 514 515 /* 516 * Remove the CachedPlanSource and all subsidiary data (including the 517 * query_context if any). But if it's a one-shot we can't free anything. 518 */ 519 if (!plansource->is_oneshot) 520 MemoryContextDelete(plansource->context); 521 } 522 523 /* 524 * ReleaseGenericPlan: release a CachedPlanSource's generic plan, if any. 525 */ 526 static void 527 ReleaseGenericPlan(CachedPlanSource *plansource) 528 { 529 /* Be paranoid about the possibility that ReleaseCachedPlan fails */ 530 if (plansource->gplan) 531 { 532 CachedPlan *plan = plansource->gplan; 533 534 Assert(plan->magic == CACHEDPLAN_MAGIC); 535 plansource->gplan = NULL; 536 ReleaseCachedPlan(plan, NULL); 537 } 538 } 539 540 /* 541 * RevalidateCachedQuery: ensure validity of analyzed-and-rewritten query tree. 542 * 543 * What we do here is re-acquire locks and redo parse analysis if necessary. 544 * On return, the query_list is valid and we have sufficient locks to begin 545 * planning. 546 * 547 * If any parse analysis activity is required, the caller's memory context is 548 * used for that work. 549 * 550 * The result value is the transient analyzed-and-rewritten query tree if we 551 * had to do re-analysis, and NIL otherwise. (This is returned just to save 552 * a tree copying step in a subsequent BuildCachedPlan call.) 553 */ 554 static List * 555 RevalidateCachedQuery(CachedPlanSource *plansource, 556 QueryEnvironment *queryEnv) 557 { 558 bool snapshot_set; 559 RawStmt *rawtree; 560 List *tlist; /* transient query-tree list */ 561 List *qlist; /* permanent query-tree list */ 562 TupleDesc resultDesc; 563 MemoryContext querytree_context; 564 MemoryContext oldcxt; 565 566 /* 567 * For one-shot plans, we do not support revalidation checking; it's 568 * assumed the query is parsed, planned, and executed in one transaction, 569 * so that no lock re-acquisition is necessary. Also, there is never any 570 * need to revalidate plans for transaction control commands (and we 571 * mustn't risk any catalog accesses when handling those). 572 */ 573 if (plansource->is_oneshot || IsTransactionStmtPlan(plansource)) 574 { 575 Assert(plansource->is_valid); 576 return NIL; 577 } 578 579 /* 580 * If the query is currently valid, we should have a saved search_path --- 581 * check to see if that matches the current environment. If not, we want 582 * to force replan. 583 */ 584 if (plansource->is_valid) 585 { 586 Assert(plansource->search_path != NULL); 587 if (!OverrideSearchPathMatchesCurrent(plansource->search_path)) 588 { 589 /* Invalidate the querytree and generic plan */ 590 plansource->is_valid = false; 591 if (plansource->gplan) 592 plansource->gplan->is_valid = false; 593 } 594 } 595 596 /* 597 * If the query rewrite phase had a possible RLS dependency, we must redo 598 * it if either the role or the row_security setting has changed. 599 */ 600 if (plansource->is_valid && plansource->dependsOnRLS && 601 (plansource->rewriteRoleId != GetUserId() || 602 plansource->rewriteRowSecurity != row_security)) 603 plansource->is_valid = false; 604 605 /* 606 * If the query is currently valid, acquire locks on the referenced 607 * objects; then check again. We need to do it this way to cover the race 608 * condition that an invalidation message arrives before we get the locks. 609 */ 610 if (plansource->is_valid) 611 { 612 AcquirePlannerLocks(plansource->query_list, true); 613 614 /* 615 * By now, if any invalidation has happened, the inval callback 616 * functions will have marked the query invalid. 617 */ 618 if (plansource->is_valid) 619 { 620 /* Successfully revalidated and locked the query. */ 621 return NIL; 622 } 623 624 /* Oops, the race case happened. Release useless locks. */ 625 AcquirePlannerLocks(plansource->query_list, false); 626 } 627 628 /* 629 * Discard the no-longer-useful query tree. (Note: we don't want to do 630 * this any earlier, else we'd not have been able to release locks 631 * correctly in the race condition case.) 632 */ 633 plansource->is_valid = false; 634 plansource->query_list = NIL; 635 plansource->relationOids = NIL; 636 plansource->invalItems = NIL; 637 plansource->search_path = NULL; 638 639 /* 640 * Free the query_context. We don't really expect MemoryContextDelete to 641 * fail, but just in case, make sure the CachedPlanSource is left in a 642 * reasonably sane state. (The generic plan won't get unlinked yet, but 643 * that's acceptable.) 644 */ 645 if (plansource->query_context) 646 { 647 MemoryContext qcxt = plansource->query_context; 648 649 plansource->query_context = NULL; 650 MemoryContextDelete(qcxt); 651 } 652 653 /* Drop the generic plan reference if any */ 654 ReleaseGenericPlan(plansource); 655 656 /* 657 * Now re-do parse analysis and rewrite. This not incidentally acquires 658 * the locks we need to do planning safely. 659 */ 660 Assert(plansource->is_complete); 661 662 /* 663 * If a snapshot is already set (the normal case), we can just use that 664 * for parsing/planning. But if it isn't, install one. Note: no point in 665 * checking whether parse analysis requires a snapshot; utility commands 666 * don't have invalidatable plans, so we'd not get here for such a 667 * command. 668 */ 669 snapshot_set = false; 670 if (!ActiveSnapshotSet()) 671 { 672 PushActiveSnapshot(GetTransactionSnapshot()); 673 snapshot_set = true; 674 } 675 676 /* 677 * Run parse analysis and rule rewriting. The parser tends to scribble on 678 * its input, so we must copy the raw parse tree to prevent corruption of 679 * the cache. 680 */ 681 rawtree = copyObject(plansource->raw_parse_tree); 682 if (rawtree == NULL) 683 tlist = NIL; 684 else if (plansource->parserSetup != NULL) 685 tlist = pg_analyze_and_rewrite_params(rawtree, 686 plansource->query_string, 687 plansource->parserSetup, 688 plansource->parserSetupArg, 689 queryEnv); 690 else 691 tlist = pg_analyze_and_rewrite(rawtree, 692 plansource->query_string, 693 plansource->param_types, 694 plansource->num_params, 695 queryEnv); 696 697 /* Release snapshot if we got one */ 698 if (snapshot_set) 699 PopActiveSnapshot(); 700 701 /* 702 * Check or update the result tupdesc. XXX should we use a weaker 703 * condition than equalTupleDescs() here? 704 * 705 * We assume the parameter types didn't change from the first time, so no 706 * need to update that. 707 */ 708 resultDesc = PlanCacheComputeResultDesc(tlist); 709 if (resultDesc == NULL && plansource->resultDesc == NULL) 710 { 711 /* OK, doesn't return tuples */ 712 } 713 else if (resultDesc == NULL || plansource->resultDesc == NULL || 714 !equalTupleDescs(resultDesc, plansource->resultDesc)) 715 { 716 /* can we give a better error message? */ 717 if (plansource->fixed_result) 718 ereport(ERROR, 719 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), 720 errmsg("cached plan must not change result type"))); 721 oldcxt = MemoryContextSwitchTo(plansource->context); 722 if (resultDesc) 723 resultDesc = CreateTupleDescCopy(resultDesc); 724 if (plansource->resultDesc) 725 FreeTupleDesc(plansource->resultDesc); 726 plansource->resultDesc = resultDesc; 727 MemoryContextSwitchTo(oldcxt); 728 } 729 730 /* 731 * Allocate new query_context and copy the completed querytree into it. 732 * It's transient until we complete the copying and dependency extraction. 733 */ 734 querytree_context = AllocSetContextCreate(CurrentMemoryContext, 735 "CachedPlanQuery", 736 ALLOCSET_START_SMALL_SIZES); 737 oldcxt = MemoryContextSwitchTo(querytree_context); 738 739 qlist = copyObject(tlist); 740 741 /* 742 * Use the planner machinery to extract dependencies. Data is saved in 743 * query_context. (We assume that not a lot of extra cruft is created by 744 * this call.) 745 */ 746 extract_query_dependencies((Node *) qlist, 747 &plansource->relationOids, 748 &plansource->invalItems, 749 &plansource->dependsOnRLS); 750 751 /* Update RLS info as well. */ 752 plansource->rewriteRoleId = GetUserId(); 753 plansource->rewriteRowSecurity = row_security; 754 755 /* 756 * Also save the current search_path in the query_context. (This should 757 * not generate much extra cruft either, since almost certainly the path 758 * is already valid.) 759 */ 760 plansource->search_path = GetOverrideSearchPath(querytree_context); 761 762 MemoryContextSwitchTo(oldcxt); 763 764 /* Now reparent the finished query_context and save the links */ 765 MemoryContextSetParent(querytree_context, plansource->context); 766 767 plansource->query_context = querytree_context; 768 plansource->query_list = qlist; 769 770 /* 771 * Note: we do not reset generic_cost or total_custom_cost, although we 772 * could choose to do so. If the DDL or statistics change that prompted 773 * the invalidation meant a significant change in the cost estimates, it 774 * would be better to reset those variables and start fresh; but often it 775 * doesn't, and we're better retaining our hard-won knowledge about the 776 * relative costs. 777 */ 778 779 plansource->is_valid = true; 780 781 /* Return transient copy of querytrees for possible use in planning */ 782 return tlist; 783 } 784 785 /* 786 * CheckCachedPlan: see if the CachedPlanSource's generic plan is valid. 787 * 788 * Caller must have already called RevalidateCachedQuery to verify that the 789 * querytree is up to date. 790 * 791 * On a "true" return, we have acquired the locks needed to run the plan. 792 * (We must do this for the "true" result to be race-condition-free.) 793 */ 794 static bool 795 CheckCachedPlan(CachedPlanSource *plansource) 796 { 797 CachedPlan *plan = plansource->gplan; 798 799 /* Assert that caller checked the querytree */ 800 Assert(plansource->is_valid); 801 802 /* If there's no generic plan, just say "false" */ 803 if (!plan) 804 return false; 805 806 Assert(plan->magic == CACHEDPLAN_MAGIC); 807 /* Generic plans are never one-shot */ 808 Assert(!plan->is_oneshot); 809 810 /* 811 * If plan isn't valid for current role, we can't use it. 812 */ 813 if (plan->is_valid && plan->dependsOnRole && 814 plan->planRoleId != GetUserId()) 815 plan->is_valid = false; 816 817 /* 818 * If it appears valid, acquire locks and recheck; this is much the same 819 * logic as in RevalidateCachedQuery, but for a plan. 820 */ 821 if (plan->is_valid) 822 { 823 /* 824 * Plan must have positive refcount because it is referenced by 825 * plansource; so no need to fear it disappears under us here. 826 */ 827 Assert(plan->refcount > 0); 828 829 AcquireExecutorLocks(plan->stmt_list, true); 830 831 /* 832 * If plan was transient, check to see if TransactionXmin has 833 * advanced, and if so invalidate it. 834 */ 835 if (plan->is_valid && 836 TransactionIdIsValid(plan->saved_xmin) && 837 !TransactionIdEquals(plan->saved_xmin, TransactionXmin)) 838 plan->is_valid = false; 839 840 /* 841 * By now, if any invalidation has happened, the inval callback 842 * functions will have marked the plan invalid. 843 */ 844 if (plan->is_valid) 845 { 846 /* Successfully revalidated and locked the query. */ 847 return true; 848 } 849 850 /* Oops, the race case happened. Release useless locks. */ 851 AcquireExecutorLocks(plan->stmt_list, false); 852 } 853 854 /* 855 * Plan has been invalidated, so unlink it from the parent and release it. 856 */ 857 ReleaseGenericPlan(plansource); 858 859 return false; 860 } 861 862 /* 863 * BuildCachedPlan: construct a new CachedPlan from a CachedPlanSource. 864 * 865 * qlist should be the result value from a previous RevalidateCachedQuery, 866 * or it can be set to NIL if we need to re-copy the plansource's query_list. 867 * 868 * To build a generic, parameter-value-independent plan, pass NULL for 869 * boundParams. To build a custom plan, pass the actual parameter values via 870 * boundParams. For best effect, the PARAM_FLAG_CONST flag should be set on 871 * each parameter value; otherwise the planner will treat the value as a 872 * hint rather than a hard constant. 873 * 874 * Planning work is done in the caller's memory context. The finished plan 875 * is in a child memory context, which typically should get reparented 876 * (unless this is a one-shot plan, in which case we don't copy the plan). 877 */ 878 static CachedPlan * 879 BuildCachedPlan(CachedPlanSource *plansource, List *qlist, 880 ParamListInfo boundParams, QueryEnvironment *queryEnv) 881 { 882 CachedPlan *plan; 883 List *plist; 884 bool snapshot_set; 885 bool is_transient; 886 MemoryContext plan_context; 887 MemoryContext oldcxt = CurrentMemoryContext; 888 ListCell *lc; 889 890 /* 891 * Normally the querytree should be valid already, but if it's not, 892 * rebuild it. 893 * 894 * NOTE: GetCachedPlan should have called RevalidateCachedQuery first, so 895 * we ought to be holding sufficient locks to prevent any invalidation. 896 * However, if we're building a custom plan after having built and 897 * rejected a generic plan, it's possible to reach here with is_valid 898 * false due to an invalidation while making the generic plan. In theory 899 * the invalidation must be a false positive, perhaps a consequence of an 900 * sinval reset event or the debug_discard_caches code. But for safety, 901 * let's treat it as real and redo the RevalidateCachedQuery call. 902 */ 903 if (!plansource->is_valid) 904 qlist = RevalidateCachedQuery(plansource, queryEnv); 905 906 /* 907 * If we don't already have a copy of the querytree list that can be 908 * scribbled on by the planner, make one. For a one-shot plan, we assume 909 * it's okay to scribble on the original query_list. 910 */ 911 if (qlist == NIL) 912 { 913 if (!plansource->is_oneshot) 914 qlist = copyObject(plansource->query_list); 915 else 916 qlist = plansource->query_list; 917 } 918 919 /* 920 * If a snapshot is already set (the normal case), we can just use that 921 * for planning. But if it isn't, and we need one, install one. 922 */ 923 snapshot_set = false; 924 if (!ActiveSnapshotSet() && 925 plansource->raw_parse_tree && 926 analyze_requires_snapshot(plansource->raw_parse_tree)) 927 { 928 PushActiveSnapshot(GetTransactionSnapshot()); 929 snapshot_set = true; 930 } 931 932 /* 933 * Generate the plan. 934 */ 935 plist = pg_plan_queries(qlist, plansource->query_string, 936 plansource->cursor_options, boundParams); 937 938 /* Release snapshot if we got one */ 939 if (snapshot_set) 940 PopActiveSnapshot(); 941 942 /* 943 * Normally we make a dedicated memory context for the CachedPlan and its 944 * subsidiary data. (It's probably not going to be large, but just in 945 * case, allow it to grow large. It's transient for the moment.) But for 946 * a one-shot plan, we just leave it in the caller's memory context. 947 */ 948 if (!plansource->is_oneshot) 949 { 950 plan_context = AllocSetContextCreate(CurrentMemoryContext, 951 "CachedPlan", 952 ALLOCSET_START_SMALL_SIZES); 953 MemoryContextCopyAndSetIdentifier(plan_context, plansource->query_string); 954 955 /* 956 * Copy plan into the new context. 957 */ 958 MemoryContextSwitchTo(plan_context); 959 960 plist = copyObject(plist); 961 } 962 else 963 plan_context = CurrentMemoryContext; 964 965 /* 966 * Create and fill the CachedPlan struct within the new context. 967 */ 968 plan = (CachedPlan *) palloc(sizeof(CachedPlan)); 969 plan->magic = CACHEDPLAN_MAGIC; 970 plan->stmt_list = plist; 971 972 /* 973 * CachedPlan is dependent on role either if RLS affected the rewrite 974 * phase or if a role dependency was injected during planning. And it's 975 * transient if any plan is marked so. 976 */ 977 plan->planRoleId = GetUserId(); 978 plan->dependsOnRole = plansource->dependsOnRLS; 979 is_transient = false; 980 foreach(lc, plist) 981 { 982 PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc); 983 984 if (plannedstmt->commandType == CMD_UTILITY) 985 continue; /* Ignore utility statements */ 986 987 if (plannedstmt->transientPlan) 988 is_transient = true; 989 if (plannedstmt->dependsOnRole) 990 plan->dependsOnRole = true; 991 } 992 if (is_transient) 993 { 994 Assert(TransactionIdIsNormal(TransactionXmin)); 995 plan->saved_xmin = TransactionXmin; 996 } 997 else 998 plan->saved_xmin = InvalidTransactionId; 999 plan->refcount = 0; 1000 plan->context = plan_context; 1001 plan->is_oneshot = plansource->is_oneshot; 1002 plan->is_saved = false; 1003 plan->is_valid = true; 1004 1005 /* assign generation number to new plan */ 1006 plan->generation = ++(plansource->generation); 1007 1008 MemoryContextSwitchTo(oldcxt); 1009 1010 return plan; 1011 } 1012 1013 /* 1014 * choose_custom_plan: choose whether to use custom or generic plan 1015 * 1016 * This defines the policy followed by GetCachedPlan. 1017 */ 1018 static bool 1019 choose_custom_plan(CachedPlanSource *plansource, ParamListInfo boundParams) 1020 { 1021 double avg_custom_cost; 1022 1023 /* One-shot plans will always be considered custom */ 1024 if (plansource->is_oneshot) 1025 return true; 1026 1027 /* Otherwise, never any point in a custom plan if there's no parameters */ 1028 if (boundParams == NULL) 1029 return false; 1030 /* ... nor for transaction control statements */ 1031 if (IsTransactionStmtPlan(plansource)) 1032 return false; 1033 1034 /* Let settings force the decision */ 1035 if (plan_cache_mode == PLAN_CACHE_MODE_FORCE_GENERIC_PLAN) 1036 return false; 1037 if (plan_cache_mode == PLAN_CACHE_MODE_FORCE_CUSTOM_PLAN) 1038 return true; 1039 1040 /* See if caller wants to force the decision */ 1041 if (plansource->cursor_options & CURSOR_OPT_GENERIC_PLAN) 1042 return false; 1043 if (plansource->cursor_options & CURSOR_OPT_CUSTOM_PLAN) 1044 return true; 1045 1046 /* Generate custom plans until we have done at least 5 (arbitrary) */ 1047 if (plansource->num_custom_plans < 5) 1048 return true; 1049 1050 avg_custom_cost = plansource->total_custom_cost / plansource->num_custom_plans; 1051 1052 /* 1053 * Prefer generic plan if it's less expensive than the average custom 1054 * plan. (Because we include a charge for cost of planning in the 1055 * custom-plan costs, this means the generic plan only has to be less 1056 * expensive than the execution cost plus replan cost of the custom 1057 * plans.) 1058 * 1059 * Note that if generic_cost is -1 (indicating we've not yet determined 1060 * the generic plan cost), we'll always prefer generic at this point. 1061 */ 1062 if (plansource->generic_cost < avg_custom_cost) 1063 return false; 1064 1065 return true; 1066 } 1067 1068 /* 1069 * cached_plan_cost: calculate estimated cost of a plan 1070 * 1071 * If include_planner is true, also include the estimated cost of constructing 1072 * the plan. (We must factor that into the cost of using a custom plan, but 1073 * we don't count it for a generic plan.) 1074 */ 1075 static double 1076 cached_plan_cost(CachedPlan *plan, bool include_planner) 1077 { 1078 double result = 0; 1079 ListCell *lc; 1080 1081 foreach(lc, plan->stmt_list) 1082 { 1083 PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc); 1084 1085 if (plannedstmt->commandType == CMD_UTILITY) 1086 continue; /* Ignore utility statements */ 1087 1088 result += plannedstmt->planTree->total_cost; 1089 1090 if (include_planner) 1091 { 1092 /* 1093 * Currently we use a very crude estimate of planning effort based 1094 * on the number of relations in the finished plan's rangetable. 1095 * Join planning effort actually scales much worse than linearly 1096 * in the number of relations --- but only until the join collapse 1097 * limits kick in. Also, while inheritance child relations surely 1098 * add to planning effort, they don't make the join situation 1099 * worse. So the actual shape of the planning cost curve versus 1100 * number of relations isn't all that obvious. It will take 1101 * considerable work to arrive at a less crude estimate, and for 1102 * now it's not clear that's worth doing. 1103 * 1104 * The other big difficulty here is that we don't have any very 1105 * good model of how planning cost compares to execution costs. 1106 * The current multiplier of 1000 * cpu_operator_cost is probably 1107 * on the low side, but we'll try this for awhile before making a 1108 * more aggressive correction. 1109 * 1110 * If we ever do write a more complicated estimator, it should 1111 * probably live in src/backend/optimizer/ not here. 1112 */ 1113 int nrelations = list_length(plannedstmt->rtable); 1114 1115 result += 1000.0 * cpu_operator_cost * (nrelations + 1); 1116 } 1117 } 1118 1119 return result; 1120 } 1121 1122 /* 1123 * GetCachedPlan: get a cached plan from a CachedPlanSource. 1124 * 1125 * This function hides the logic that decides whether to use a generic 1126 * plan or a custom plan for the given parameters: the caller does not know 1127 * which it will get. 1128 * 1129 * On return, the plan is valid and we have sufficient locks to begin 1130 * execution. 1131 * 1132 * On return, the refcount of the plan has been incremented; a later 1133 * ReleaseCachedPlan() call is expected. If "owner" is not NULL then 1134 * the refcount has been reported to that ResourceOwner (note that this 1135 * is only supported for "saved" CachedPlanSources). 1136 * 1137 * Note: if any replanning activity is required, the caller's memory context 1138 * is used for that work. 1139 */ 1140 CachedPlan * 1141 GetCachedPlan(CachedPlanSource *plansource, ParamListInfo boundParams, 1142 ResourceOwner owner, QueryEnvironment *queryEnv) 1143 { 1144 CachedPlan *plan = NULL; 1145 List *qlist; 1146 bool customplan; 1147 1148 /* Assert caller is doing things in a sane order */ 1149 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC); 1150 Assert(plansource->is_complete); 1151 /* This seems worth a real test, though */ 1152 if (owner && !plansource->is_saved) 1153 elog(ERROR, "cannot apply ResourceOwner to non-saved cached plan"); 1154 1155 /* Make sure the querytree list is valid and we have parse-time locks */ 1156 qlist = RevalidateCachedQuery(plansource, queryEnv); 1157 1158 /* Decide whether to use a custom plan */ 1159 customplan = choose_custom_plan(plansource, boundParams); 1160 1161 if (!customplan) 1162 { 1163 if (CheckCachedPlan(plansource)) 1164 { 1165 /* We want a generic plan, and we already have a valid one */ 1166 plan = plansource->gplan; 1167 Assert(plan->magic == CACHEDPLAN_MAGIC); 1168 } 1169 else 1170 { 1171 /* Build a new generic plan */ 1172 plan = BuildCachedPlan(plansource, qlist, NULL, queryEnv); 1173 /* Just make real sure plansource->gplan is clear */ 1174 ReleaseGenericPlan(plansource); 1175 /* Link the new generic plan into the plansource */ 1176 plansource->gplan = plan; 1177 plan->refcount++; 1178 /* Immediately reparent into appropriate context */ 1179 if (plansource->is_saved) 1180 { 1181 /* saved plans all live under CacheMemoryContext */ 1182 MemoryContextSetParent(plan->context, CacheMemoryContext); 1183 plan->is_saved = true; 1184 } 1185 else 1186 { 1187 /* otherwise, it should be a sibling of the plansource */ 1188 MemoryContextSetParent(plan->context, 1189 MemoryContextGetParent(plansource->context)); 1190 } 1191 /* Update generic_cost whenever we make a new generic plan */ 1192 plansource->generic_cost = cached_plan_cost(plan, false); 1193 1194 /* 1195 * If, based on the now-known value of generic_cost, we'd not have 1196 * chosen to use a generic plan, then forget it and make a custom 1197 * plan. This is a bit of a wart but is necessary to avoid a 1198 * glitch in behavior when the custom plans are consistently big 1199 * winners; at some point we'll experiment with a generic plan and 1200 * find it's a loser, but we don't want to actually execute that 1201 * plan. 1202 */ 1203 customplan = choose_custom_plan(plansource, boundParams); 1204 1205 /* 1206 * If we choose to plan again, we need to re-copy the query_list, 1207 * since the planner probably scribbled on it. We can force 1208 * BuildCachedPlan to do that by passing NIL. 1209 */ 1210 qlist = NIL; 1211 } 1212 } 1213 1214 if (customplan) 1215 { 1216 /* Build a custom plan */ 1217 plan = BuildCachedPlan(plansource, qlist, boundParams, queryEnv); 1218 /* Accumulate total costs of custom plans */ 1219 plansource->total_custom_cost += cached_plan_cost(plan, true); 1220 1221 plansource->num_custom_plans++; 1222 } 1223 else 1224 { 1225 plansource->num_generic_plans++; 1226 } 1227 1228 Assert(plan != NULL); 1229 1230 /* Flag the plan as in use by caller */ 1231 if (owner) 1232 ResourceOwnerEnlargePlanCacheRefs(owner); 1233 plan->refcount++; 1234 if (owner) 1235 ResourceOwnerRememberPlanCacheRef(owner, plan); 1236 1237 /* 1238 * Saved plans should be under CacheMemoryContext so they will not go away 1239 * until their reference count goes to zero. In the generic-plan cases we 1240 * already took care of that, but for a custom plan, do it as soon as we 1241 * have created a reference-counted link. 1242 */ 1243 if (customplan && plansource->is_saved) 1244 { 1245 MemoryContextSetParent(plan->context, CacheMemoryContext); 1246 plan->is_saved = true; 1247 } 1248 1249 return plan; 1250 } 1251 1252 /* 1253 * ReleaseCachedPlan: release active use of a cached plan. 1254 * 1255 * This decrements the reference count, and frees the plan if the count 1256 * has thereby gone to zero. If "owner" is not NULL, it is assumed that 1257 * the reference count is managed by that ResourceOwner. 1258 * 1259 * Note: owner == NULL is used for releasing references that are in 1260 * persistent data structures, such as the parent CachedPlanSource or a 1261 * Portal. Transient references should be protected by a resource owner. 1262 */ 1263 void 1264 ReleaseCachedPlan(CachedPlan *plan, ResourceOwner owner) 1265 { 1266 Assert(plan->magic == CACHEDPLAN_MAGIC); 1267 if (owner) 1268 { 1269 Assert(plan->is_saved); 1270 ResourceOwnerForgetPlanCacheRef(owner, plan); 1271 } 1272 Assert(plan->refcount > 0); 1273 plan->refcount--; 1274 if (plan->refcount == 0) 1275 { 1276 /* Mark it no longer valid */ 1277 plan->magic = 0; 1278 1279 /* One-shot plans do not own their context, so we can't free them */ 1280 if (!plan->is_oneshot) 1281 MemoryContextDelete(plan->context); 1282 } 1283 } 1284 1285 /* 1286 * CachedPlanAllowsSimpleValidityCheck: can we use CachedPlanIsSimplyValid? 1287 * 1288 * This function, together with CachedPlanIsSimplyValid, provides a fast path 1289 * for revalidating "simple" generic plans. The core requirement to be simple 1290 * is that the plan must not require taking any locks, which translates to 1291 * not touching any tables; this happens to match up well with an important 1292 * use-case in PL/pgSQL. This function tests whether that's true, along 1293 * with checking some other corner cases that we'd rather not bother with 1294 * handling in the fast path. (Note that it's still possible for such a plan 1295 * to be invalidated, for example due to a change in a function that was 1296 * inlined into the plan.) 1297 * 1298 * If the plan is simply valid, and "owner" is not NULL, record a refcount on 1299 * the plan in that resowner before returning. It is caller's responsibility 1300 * to be sure that a refcount is held on any plan that's being actively used. 1301 * 1302 * This must only be called on known-valid generic plans (eg, ones just 1303 * returned by GetCachedPlan). If it returns true, the caller may re-use 1304 * the cached plan as long as CachedPlanIsSimplyValid returns true; that 1305 * check is much cheaper than the full revalidation done by GetCachedPlan. 1306 * Nonetheless, no required checks are omitted. 1307 */ 1308 bool 1309 CachedPlanAllowsSimpleValidityCheck(CachedPlanSource *plansource, 1310 CachedPlan *plan, ResourceOwner owner) 1311 { 1312 ListCell *lc; 1313 1314 /* 1315 * Sanity-check that the caller gave us a validated generic plan. Notice 1316 * that we *don't* assert plansource->is_valid as you might expect; that's 1317 * because it's possible that that's already false when GetCachedPlan 1318 * returns, e.g. because ResetPlanCache happened partway through. We 1319 * should accept the plan as long as plan->is_valid is true, and expect to 1320 * replan after the next CachedPlanIsSimplyValid call. 1321 */ 1322 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC); 1323 Assert(plan->magic == CACHEDPLAN_MAGIC); 1324 Assert(plan->is_valid); 1325 Assert(plan == plansource->gplan); 1326 Assert(plansource->search_path != NULL); 1327 Assert(OverrideSearchPathMatchesCurrent(plansource->search_path)); 1328 1329 /* We don't support oneshot plans here. */ 1330 if (plansource->is_oneshot) 1331 return false; 1332 Assert(!plan->is_oneshot); 1333 1334 /* 1335 * If the plan is dependent on RLS considerations, or it's transient, 1336 * reject. These things probably can't ever happen for table-free 1337 * queries, but for safety's sake let's check. 1338 */ 1339 if (plansource->dependsOnRLS) 1340 return false; 1341 if (plan->dependsOnRole) 1342 return false; 1343 if (TransactionIdIsValid(plan->saved_xmin)) 1344 return false; 1345 1346 /* 1347 * Reject if AcquirePlannerLocks would have anything to do. This is 1348 * simplistic, but there's no need to inquire any more carefully; indeed, 1349 * for current callers it shouldn't even be possible to hit any of these 1350 * checks. 1351 */ 1352 foreach(lc, plansource->query_list) 1353 { 1354 Query *query = lfirst_node(Query, lc); 1355 1356 if (query->commandType == CMD_UTILITY) 1357 return false; 1358 if (query->rtable || query->cteList || query->hasSubLinks) 1359 return false; 1360 } 1361 1362 /* 1363 * Reject if AcquireExecutorLocks would have anything to do. This is 1364 * probably unnecessary given the previous check, but let's be safe. 1365 */ 1366 foreach(lc, plan->stmt_list) 1367 { 1368 PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc); 1369 ListCell *lc2; 1370 1371 if (plannedstmt->commandType == CMD_UTILITY) 1372 return false; 1373 1374 /* 1375 * We have to grovel through the rtable because it's likely to contain 1376 * an RTE_RESULT relation, rather than being totally empty. 1377 */ 1378 foreach(lc2, plannedstmt->rtable) 1379 { 1380 RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc2); 1381 1382 if (rte->rtekind == RTE_RELATION) 1383 return false; 1384 } 1385 } 1386 1387 /* 1388 * Okay, it's simple. Note that what we've primarily established here is 1389 * that no locks need be taken before checking the plan's is_valid flag. 1390 */ 1391 1392 /* Bump refcount if requested. */ 1393 if (owner) 1394 { 1395 ResourceOwnerEnlargePlanCacheRefs(owner); 1396 plan->refcount++; 1397 ResourceOwnerRememberPlanCacheRef(owner, plan); 1398 } 1399 1400 return true; 1401 } 1402 1403 /* 1404 * CachedPlanIsSimplyValid: quick check for plan still being valid 1405 * 1406 * This function must not be used unless CachedPlanAllowsSimpleValidityCheck 1407 * previously said it was OK. 1408 * 1409 * If the plan is valid, and "owner" is not NULL, record a refcount on 1410 * the plan in that resowner before returning. It is caller's responsibility 1411 * to be sure that a refcount is held on any plan that's being actively used. 1412 * 1413 * The code here is unconditionally safe as long as the only use of this 1414 * CachedPlanSource is in connection with the particular CachedPlan pointer 1415 * that's passed in. If the plansource were being used for other purposes, 1416 * it's possible that its generic plan could be invalidated and regenerated 1417 * while the current caller wasn't looking, and then there could be a chance 1418 * collision of address between this caller's now-stale plan pointer and the 1419 * actual address of the new generic plan. For current uses, that scenario 1420 * can't happen; but with a plansource shared across multiple uses, it'd be 1421 * advisable to also save plan->generation and verify that that still matches. 1422 */ 1423 bool 1424 CachedPlanIsSimplyValid(CachedPlanSource *plansource, CachedPlan *plan, 1425 ResourceOwner owner) 1426 { 1427 /* 1428 * Careful here: since the caller doesn't necessarily hold a refcount on 1429 * the plan to start with, it's possible that "plan" is a dangling 1430 * pointer. Don't dereference it until we've verified that it still 1431 * matches the plansource's gplan (which is either valid or NULL). 1432 */ 1433 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC); 1434 1435 /* 1436 * Has cache invalidation fired on this plan? We can check this right 1437 * away since there are no locks that we'd need to acquire first. Note 1438 * that here we *do* check plansource->is_valid, so as to force plan 1439 * rebuild if that's become false. 1440 */ 1441 if (!plansource->is_valid || plan != plansource->gplan || !plan->is_valid) 1442 return false; 1443 1444 Assert(plan->magic == CACHEDPLAN_MAGIC); 1445 1446 /* Is the search_path still the same as when we made it? */ 1447 Assert(plansource->search_path != NULL); 1448 if (!OverrideSearchPathMatchesCurrent(plansource->search_path)) 1449 return false; 1450 1451 /* It's still good. Bump refcount if requested. */ 1452 if (owner) 1453 { 1454 ResourceOwnerEnlargePlanCacheRefs(owner); 1455 plan->refcount++; 1456 ResourceOwnerRememberPlanCacheRef(owner, plan); 1457 } 1458 1459 return true; 1460 } 1461 1462 /* 1463 * CachedPlanSetParentContext: move a CachedPlanSource to a new memory context 1464 * 1465 * This can only be applied to unsaved plans; once saved, a plan always 1466 * lives underneath CacheMemoryContext. 1467 */ 1468 void 1469 CachedPlanSetParentContext(CachedPlanSource *plansource, 1470 MemoryContext newcontext) 1471 { 1472 /* Assert caller is doing things in a sane order */ 1473 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC); 1474 Assert(plansource->is_complete); 1475 1476 /* These seem worth real tests, though */ 1477 if (plansource->is_saved) 1478 elog(ERROR, "cannot move a saved cached plan to another context"); 1479 if (plansource->is_oneshot) 1480 elog(ERROR, "cannot move a one-shot cached plan to another context"); 1481 1482 /* OK, let the caller keep the plan where he wishes */ 1483 MemoryContextSetParent(plansource->context, newcontext); 1484 1485 /* 1486 * The query_context needs no special handling, since it's a child of 1487 * plansource->context. But if there's a generic plan, it should be 1488 * maintained as a sibling of plansource->context. 1489 */ 1490 if (plansource->gplan) 1491 { 1492 Assert(plansource->gplan->magic == CACHEDPLAN_MAGIC); 1493 MemoryContextSetParent(plansource->gplan->context, newcontext); 1494 } 1495 } 1496 1497 /* 1498 * CopyCachedPlan: make a copy of a CachedPlanSource 1499 * 1500 * This is a convenience routine that does the equivalent of 1501 * CreateCachedPlan + CompleteCachedPlan, using the data stored in the 1502 * input CachedPlanSource. The result is therefore "unsaved" (regardless 1503 * of the state of the source), and we don't copy any generic plan either. 1504 * The result will be currently valid, or not, the same as the source. 1505 */ 1506 CachedPlanSource * 1507 CopyCachedPlan(CachedPlanSource *plansource) 1508 { 1509 CachedPlanSource *newsource; 1510 MemoryContext source_context; 1511 MemoryContext querytree_context; 1512 MemoryContext oldcxt; 1513 1514 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC); 1515 Assert(plansource->is_complete); 1516 1517 /* 1518 * One-shot plans can't be copied, because we haven't taken care that 1519 * parsing/planning didn't scribble on the raw parse tree or querytrees. 1520 */ 1521 if (plansource->is_oneshot) 1522 elog(ERROR, "cannot copy a one-shot cached plan"); 1523 1524 source_context = AllocSetContextCreate(CurrentMemoryContext, 1525 "CachedPlanSource", 1526 ALLOCSET_START_SMALL_SIZES); 1527 1528 oldcxt = MemoryContextSwitchTo(source_context); 1529 1530 newsource = (CachedPlanSource *) palloc0(sizeof(CachedPlanSource)); 1531 newsource->magic = CACHEDPLANSOURCE_MAGIC; 1532 newsource->raw_parse_tree = copyObject(plansource->raw_parse_tree); 1533 newsource->query_string = pstrdup(plansource->query_string); 1534 MemoryContextSetIdentifier(source_context, newsource->query_string); 1535 newsource->commandTag = plansource->commandTag; 1536 if (plansource->num_params > 0) 1537 { 1538 newsource->param_types = (Oid *) 1539 palloc(plansource->num_params * sizeof(Oid)); 1540 memcpy(newsource->param_types, plansource->param_types, 1541 plansource->num_params * sizeof(Oid)); 1542 } 1543 else 1544 newsource->param_types = NULL; 1545 newsource->num_params = plansource->num_params; 1546 newsource->parserSetup = plansource->parserSetup; 1547 newsource->parserSetupArg = plansource->parserSetupArg; 1548 newsource->cursor_options = plansource->cursor_options; 1549 newsource->fixed_result = plansource->fixed_result; 1550 if (plansource->resultDesc) 1551 newsource->resultDesc = CreateTupleDescCopy(plansource->resultDesc); 1552 else 1553 newsource->resultDesc = NULL; 1554 newsource->context = source_context; 1555 1556 querytree_context = AllocSetContextCreate(source_context, 1557 "CachedPlanQuery", 1558 ALLOCSET_START_SMALL_SIZES); 1559 MemoryContextSwitchTo(querytree_context); 1560 newsource->query_list = copyObject(plansource->query_list); 1561 newsource->relationOids = copyObject(plansource->relationOids); 1562 newsource->invalItems = copyObject(plansource->invalItems); 1563 if (plansource->search_path) 1564 newsource->search_path = CopyOverrideSearchPath(plansource->search_path); 1565 newsource->query_context = querytree_context; 1566 newsource->rewriteRoleId = plansource->rewriteRoleId; 1567 newsource->rewriteRowSecurity = plansource->rewriteRowSecurity; 1568 newsource->dependsOnRLS = plansource->dependsOnRLS; 1569 1570 newsource->gplan = NULL; 1571 1572 newsource->is_oneshot = false; 1573 newsource->is_complete = true; 1574 newsource->is_saved = false; 1575 newsource->is_valid = plansource->is_valid; 1576 newsource->generation = plansource->generation; 1577 1578 /* We may as well copy any acquired cost knowledge */ 1579 newsource->generic_cost = plansource->generic_cost; 1580 newsource->total_custom_cost = plansource->total_custom_cost; 1581 newsource->num_generic_plans = plansource->num_generic_plans; 1582 newsource->num_custom_plans = plansource->num_custom_plans; 1583 1584 MemoryContextSwitchTo(oldcxt); 1585 1586 return newsource; 1587 } 1588 1589 /* 1590 * CachedPlanIsValid: test whether the rewritten querytree within a 1591 * CachedPlanSource is currently valid (that is, not marked as being in need 1592 * of revalidation). 1593 * 1594 * This result is only trustworthy (ie, free from race conditions) if 1595 * the caller has acquired locks on all the relations used in the plan. 1596 */ 1597 bool 1598 CachedPlanIsValid(CachedPlanSource *plansource) 1599 { 1600 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC); 1601 return plansource->is_valid; 1602 } 1603 1604 /* 1605 * CachedPlanGetTargetList: return tlist, if any, describing plan's output 1606 * 1607 * The result is guaranteed up-to-date. However, it is local storage 1608 * within the cached plan, and may disappear next time the plan is updated. 1609 */ 1610 List * 1611 CachedPlanGetTargetList(CachedPlanSource *plansource, 1612 QueryEnvironment *queryEnv) 1613 { 1614 Query *pstmt; 1615 1616 /* Assert caller is doing things in a sane order */ 1617 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC); 1618 Assert(plansource->is_complete); 1619 1620 /* 1621 * No work needed if statement doesn't return tuples (we assume this 1622 * feature cannot be changed by an invalidation) 1623 */ 1624 if (plansource->resultDesc == NULL) 1625 return NIL; 1626 1627 /* Make sure the querytree list is valid and we have parse-time locks */ 1628 RevalidateCachedQuery(plansource, queryEnv); 1629 1630 /* Get the primary statement and find out what it returns */ 1631 pstmt = QueryListGetPrimaryStmt(plansource->query_list); 1632 1633 return FetchStatementTargetList((Node *) pstmt); 1634 } 1635 1636 /* 1637 * GetCachedExpression: construct a CachedExpression for an expression. 1638 * 1639 * This performs the same transformations on the expression as 1640 * expression_planner(), ie, convert an expression as emitted by parse 1641 * analysis to be ready to pass to the executor. 1642 * 1643 * The result is stashed in a private, long-lived memory context. 1644 * (Note that this might leak a good deal of memory in the caller's 1645 * context before that.) The passed-in expr tree is not modified. 1646 */ 1647 CachedExpression * 1648 GetCachedExpression(Node *expr) 1649 { 1650 CachedExpression *cexpr; 1651 List *relationOids; 1652 List *invalItems; 1653 MemoryContext cexpr_context; 1654 MemoryContext oldcxt; 1655 1656 /* 1657 * Pass the expression through the planner, and collect dependencies. 1658 * Everything built here is leaked in the caller's context; that's 1659 * intentional to minimize the size of the permanent data structure. 1660 */ 1661 expr = (Node *) expression_planner_with_deps((Expr *) expr, 1662 &relationOids, 1663 &invalItems); 1664 1665 /* 1666 * Make a private memory context, and copy what we need into that. To 1667 * avoid leaking a long-lived context if we fail while copying data, we 1668 * initially make the context under the caller's context. 1669 */ 1670 cexpr_context = AllocSetContextCreate(CurrentMemoryContext, 1671 "CachedExpression", 1672 ALLOCSET_SMALL_SIZES); 1673 1674 oldcxt = MemoryContextSwitchTo(cexpr_context); 1675 1676 cexpr = (CachedExpression *) palloc(sizeof(CachedExpression)); 1677 cexpr->magic = CACHEDEXPR_MAGIC; 1678 cexpr->expr = copyObject(expr); 1679 cexpr->is_valid = true; 1680 cexpr->relationOids = copyObject(relationOids); 1681 cexpr->invalItems = copyObject(invalItems); 1682 cexpr->context = cexpr_context; 1683 1684 MemoryContextSwitchTo(oldcxt); 1685 1686 /* 1687 * Reparent the expr's memory context under CacheMemoryContext so that it 1688 * will live indefinitely. 1689 */ 1690 MemoryContextSetParent(cexpr_context, CacheMemoryContext); 1691 1692 /* 1693 * Add the entry to the global list of cached expressions. 1694 */ 1695 dlist_push_tail(&cached_expression_list, &cexpr->node); 1696 1697 return cexpr; 1698 } 1699 1700 /* 1701 * FreeCachedExpression 1702 * Delete a CachedExpression. 1703 */ 1704 void 1705 FreeCachedExpression(CachedExpression *cexpr) 1706 { 1707 /* Sanity check */ 1708 Assert(cexpr->magic == CACHEDEXPR_MAGIC); 1709 /* Unlink from global list */ 1710 dlist_delete(&cexpr->node); 1711 /* Free all storage associated with CachedExpression */ 1712 MemoryContextDelete(cexpr->context); 1713 } 1714 1715 /* 1716 * QueryListGetPrimaryStmt 1717 * Get the "primary" stmt within a list, ie, the one marked canSetTag. 1718 * 1719 * Returns NULL if no such stmt. If multiple queries within the list are 1720 * marked canSetTag, returns the first one. Neither of these cases should 1721 * occur in present usages of this function. 1722 */ 1723 static Query * 1724 QueryListGetPrimaryStmt(List *stmts) 1725 { 1726 ListCell *lc; 1727 1728 foreach(lc, stmts) 1729 { 1730 Query *stmt = lfirst_node(Query, lc); 1731 1732 if (stmt->canSetTag) 1733 return stmt; 1734 } 1735 return NULL; 1736 } 1737 1738 /* 1739 * AcquireExecutorLocks: acquire locks needed for execution of a cached plan; 1740 * or release them if acquire is false. 1741 */ 1742 static void 1743 AcquireExecutorLocks(List *stmt_list, bool acquire) 1744 { 1745 ListCell *lc1; 1746 1747 foreach(lc1, stmt_list) 1748 { 1749 PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc1); 1750 ListCell *lc2; 1751 1752 if (plannedstmt->commandType == CMD_UTILITY) 1753 { 1754 /* 1755 * Ignore utility statements, except those (such as EXPLAIN) that 1756 * contain a parsed-but-not-planned query. Note: it's okay to use 1757 * ScanQueryForLocks, even though the query hasn't been through 1758 * rule rewriting, because rewriting doesn't change the query 1759 * representation. 1760 */ 1761 Query *query = UtilityContainsQuery(plannedstmt->utilityStmt); 1762 1763 if (query) 1764 ScanQueryForLocks(query, acquire); 1765 continue; 1766 } 1767 1768 foreach(lc2, plannedstmt->rtable) 1769 { 1770 RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc2); 1771 1772 if (rte->rtekind != RTE_RELATION) 1773 continue; 1774 1775 /* 1776 * Acquire the appropriate type of lock on each relation OID. Note 1777 * that we don't actually try to open the rel, and hence will not 1778 * fail if it's been dropped entirely --- we'll just transiently 1779 * acquire a non-conflicting lock. 1780 */ 1781 if (acquire) 1782 LockRelationOid(rte->relid, rte->rellockmode); 1783 else 1784 UnlockRelationOid(rte->relid, rte->rellockmode); 1785 } 1786 } 1787 } 1788 1789 /* 1790 * AcquirePlannerLocks: acquire locks needed for planning of a querytree list; 1791 * or release them if acquire is false. 1792 * 1793 * Note that we don't actually try to open the relations, and hence will not 1794 * fail if one has been dropped entirely --- we'll just transiently acquire 1795 * a non-conflicting lock. 1796 */ 1797 static void 1798 AcquirePlannerLocks(List *stmt_list, bool acquire) 1799 { 1800 ListCell *lc; 1801 1802 foreach(lc, stmt_list) 1803 { 1804 Query *query = lfirst_node(Query, lc); 1805 1806 if (query->commandType == CMD_UTILITY) 1807 { 1808 /* Ignore utility statements, unless they contain a Query */ 1809 query = UtilityContainsQuery(query->utilityStmt); 1810 if (query) 1811 ScanQueryForLocks(query, acquire); 1812 continue; 1813 } 1814 1815 ScanQueryForLocks(query, acquire); 1816 } 1817 } 1818 1819 /* 1820 * ScanQueryForLocks: recursively scan one Query for AcquirePlannerLocks. 1821 */ 1822 static void 1823 ScanQueryForLocks(Query *parsetree, bool acquire) 1824 { 1825 ListCell *lc; 1826 1827 /* Shouldn't get called on utility commands */ 1828 Assert(parsetree->commandType != CMD_UTILITY); 1829 1830 /* 1831 * First, process RTEs of the current query level. 1832 */ 1833 foreach(lc, parsetree->rtable) 1834 { 1835 RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc); 1836 1837 switch (rte->rtekind) 1838 { 1839 case RTE_RELATION: 1840 /* Acquire or release the appropriate type of lock */ 1841 if (acquire) 1842 LockRelationOid(rte->relid, rte->rellockmode); 1843 else 1844 UnlockRelationOid(rte->relid, rte->rellockmode); 1845 break; 1846 1847 case RTE_SUBQUERY: 1848 /* Recurse into subquery-in-FROM */ 1849 ScanQueryForLocks(rte->subquery, acquire); 1850 break; 1851 1852 default: 1853 /* ignore other types of RTEs */ 1854 break; 1855 } 1856 } 1857 1858 /* Recurse into subquery-in-WITH */ 1859 foreach(lc, parsetree->cteList) 1860 { 1861 CommonTableExpr *cte = lfirst_node(CommonTableExpr, lc); 1862 1863 ScanQueryForLocks(castNode(Query, cte->ctequery), acquire); 1864 } 1865 1866 /* 1867 * Recurse into sublink subqueries, too. But we already did the ones in 1868 * the rtable and cteList. 1869 */ 1870 if (parsetree->hasSubLinks) 1871 { 1872 query_tree_walker(parsetree, ScanQueryWalker, 1873 (void *) &acquire, 1874 QTW_IGNORE_RC_SUBQUERIES); 1875 } 1876 } 1877 1878 /* 1879 * Walker to find sublink subqueries for ScanQueryForLocks 1880 */ 1881 static bool 1882 ScanQueryWalker(Node *node, bool *acquire) 1883 { 1884 if (node == NULL) 1885 return false; 1886 if (IsA(node, SubLink)) 1887 { 1888 SubLink *sub = (SubLink *) node; 1889 1890 /* Do what we came for */ 1891 ScanQueryForLocks(castNode(Query, sub->subselect), *acquire); 1892 /* Fall through to process lefthand args of SubLink */ 1893 } 1894 1895 /* 1896 * Do NOT recurse into Query nodes, because ScanQueryForLocks already 1897 * processed subselects of subselects for us. 1898 */ 1899 return expression_tree_walker(node, ScanQueryWalker, 1900 (void *) acquire); 1901 } 1902 1903 /* 1904 * PlanCacheComputeResultDesc: given a list of analyzed-and-rewritten Queries, 1905 * determine the result tupledesc it will produce. Returns NULL if the 1906 * execution will not return tuples. 1907 * 1908 * Note: the result is created or copied into current memory context. 1909 */ 1910 static TupleDesc 1911 PlanCacheComputeResultDesc(List *stmt_list) 1912 { 1913 Query *query; 1914 1915 switch (ChoosePortalStrategy(stmt_list)) 1916 { 1917 case PORTAL_ONE_SELECT: 1918 case PORTAL_ONE_MOD_WITH: 1919 query = linitial_node(Query, stmt_list); 1920 return ExecCleanTypeFromTL(query->targetList); 1921 1922 case PORTAL_ONE_RETURNING: 1923 query = QueryListGetPrimaryStmt(stmt_list); 1924 Assert(query->returningList); 1925 return ExecCleanTypeFromTL(query->returningList); 1926 1927 case PORTAL_UTIL_SELECT: 1928 query = linitial_node(Query, stmt_list); 1929 Assert(query->utilityStmt); 1930 return UtilityTupleDescriptor(query->utilityStmt); 1931 1932 case PORTAL_MULTI_QUERY: 1933 /* will not return tuples */ 1934 break; 1935 } 1936 return NULL; 1937 } 1938 1939 /* 1940 * PlanCacheRelCallback 1941 * Relcache inval callback function 1942 * 1943 * Invalidate all plans mentioning the given rel, or all plans mentioning 1944 * any rel at all if relid == InvalidOid. 1945 */ 1946 static void 1947 PlanCacheRelCallback(Datum arg, Oid relid) 1948 { 1949 dlist_iter iter; 1950 1951 dlist_foreach(iter, &saved_plan_list) 1952 { 1953 CachedPlanSource *plansource = dlist_container(CachedPlanSource, 1954 node, iter.cur); 1955 1956 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC); 1957 1958 /* No work if it's already invalidated */ 1959 if (!plansource->is_valid) 1960 continue; 1961 1962 /* Never invalidate transaction control commands */ 1963 if (IsTransactionStmtPlan(plansource)) 1964 continue; 1965 1966 /* 1967 * Check the dependency list for the rewritten querytree. 1968 */ 1969 if ((relid == InvalidOid) ? plansource->relationOids != NIL : 1970 list_member_oid(plansource->relationOids, relid)) 1971 { 1972 /* Invalidate the querytree and generic plan */ 1973 plansource->is_valid = false; 1974 if (plansource->gplan) 1975 plansource->gplan->is_valid = false; 1976 } 1977 1978 /* 1979 * The generic plan, if any, could have more dependencies than the 1980 * querytree does, so we have to check it too. 1981 */ 1982 if (plansource->gplan && plansource->gplan->is_valid) 1983 { 1984 ListCell *lc; 1985 1986 foreach(lc, plansource->gplan->stmt_list) 1987 { 1988 PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc); 1989 1990 if (plannedstmt->commandType == CMD_UTILITY) 1991 continue; /* Ignore utility statements */ 1992 if ((relid == InvalidOid) ? plannedstmt->relationOids != NIL : 1993 list_member_oid(plannedstmt->relationOids, relid)) 1994 { 1995 /* Invalidate the generic plan only */ 1996 plansource->gplan->is_valid = false; 1997 break; /* out of stmt_list scan */ 1998 } 1999 } 2000 } 2001 } 2002 2003 /* Likewise check cached expressions */ 2004 dlist_foreach(iter, &cached_expression_list) 2005 { 2006 CachedExpression *cexpr = dlist_container(CachedExpression, 2007 node, iter.cur); 2008 2009 Assert(cexpr->magic == CACHEDEXPR_MAGIC); 2010 2011 /* No work if it's already invalidated */ 2012 if (!cexpr->is_valid) 2013 continue; 2014 2015 if ((relid == InvalidOid) ? cexpr->relationOids != NIL : 2016 list_member_oid(cexpr->relationOids, relid)) 2017 { 2018 cexpr->is_valid = false; 2019 } 2020 } 2021 } 2022 2023 /* 2024 * PlanCacheObjectCallback 2025 * Syscache inval callback function for PROCOID and TYPEOID caches 2026 * 2027 * Invalidate all plans mentioning the object with the specified hash value, 2028 * or all plans mentioning any member of this cache if hashvalue == 0. 2029 */ 2030 static void 2031 PlanCacheObjectCallback(Datum arg, int cacheid, uint32 hashvalue) 2032 { 2033 dlist_iter iter; 2034 2035 dlist_foreach(iter, &saved_plan_list) 2036 { 2037 CachedPlanSource *plansource = dlist_container(CachedPlanSource, 2038 node, iter.cur); 2039 ListCell *lc; 2040 2041 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC); 2042 2043 /* No work if it's already invalidated */ 2044 if (!plansource->is_valid) 2045 continue; 2046 2047 /* Never invalidate transaction control commands */ 2048 if (IsTransactionStmtPlan(plansource)) 2049 continue; 2050 2051 /* 2052 * Check the dependency list for the rewritten querytree. 2053 */ 2054 foreach(lc, plansource->invalItems) 2055 { 2056 PlanInvalItem *item = (PlanInvalItem *) lfirst(lc); 2057 2058 if (item->cacheId != cacheid) 2059 continue; 2060 if (hashvalue == 0 || 2061 item->hashValue == hashvalue) 2062 { 2063 /* Invalidate the querytree and generic plan */ 2064 plansource->is_valid = false; 2065 if (plansource->gplan) 2066 plansource->gplan->is_valid = false; 2067 break; 2068 } 2069 } 2070 2071 /* 2072 * The generic plan, if any, could have more dependencies than the 2073 * querytree does, so we have to check it too. 2074 */ 2075 if (plansource->gplan && plansource->gplan->is_valid) 2076 { 2077 foreach(lc, plansource->gplan->stmt_list) 2078 { 2079 PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc); 2080 ListCell *lc3; 2081 2082 if (plannedstmt->commandType == CMD_UTILITY) 2083 continue; /* Ignore utility statements */ 2084 foreach(lc3, plannedstmt->invalItems) 2085 { 2086 PlanInvalItem *item = (PlanInvalItem *) lfirst(lc3); 2087 2088 if (item->cacheId != cacheid) 2089 continue; 2090 if (hashvalue == 0 || 2091 item->hashValue == hashvalue) 2092 { 2093 /* Invalidate the generic plan only */ 2094 plansource->gplan->is_valid = false; 2095 break; /* out of invalItems scan */ 2096 } 2097 } 2098 if (!plansource->gplan->is_valid) 2099 break; /* out of stmt_list scan */ 2100 } 2101 } 2102 } 2103 2104 /* Likewise check cached expressions */ 2105 dlist_foreach(iter, &cached_expression_list) 2106 { 2107 CachedExpression *cexpr = dlist_container(CachedExpression, 2108 node, iter.cur); 2109 ListCell *lc; 2110 2111 Assert(cexpr->magic == CACHEDEXPR_MAGIC); 2112 2113 /* No work if it's already invalidated */ 2114 if (!cexpr->is_valid) 2115 continue; 2116 2117 foreach(lc, cexpr->invalItems) 2118 { 2119 PlanInvalItem *item = (PlanInvalItem *) lfirst(lc); 2120 2121 if (item->cacheId != cacheid) 2122 continue; 2123 if (hashvalue == 0 || 2124 item->hashValue == hashvalue) 2125 { 2126 cexpr->is_valid = false; 2127 break; 2128 } 2129 } 2130 } 2131 } 2132 2133 /* 2134 * PlanCacheSysCallback 2135 * Syscache inval callback function for other caches 2136 * 2137 * Just invalidate everything... 2138 */ 2139 static void 2140 PlanCacheSysCallback(Datum arg, int cacheid, uint32 hashvalue) 2141 { 2142 ResetPlanCache(); 2143 } 2144 2145 /* 2146 * ResetPlanCache: invalidate all cached plans. 2147 */ 2148 void 2149 ResetPlanCache(void) 2150 { 2151 dlist_iter iter; 2152 2153 dlist_foreach(iter, &saved_plan_list) 2154 { 2155 CachedPlanSource *plansource = dlist_container(CachedPlanSource, 2156 node, iter.cur); 2157 ListCell *lc; 2158 2159 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC); 2160 2161 /* No work if it's already invalidated */ 2162 if (!plansource->is_valid) 2163 continue; 2164 2165 /* 2166 * We *must not* mark transaction control statements as invalid, 2167 * particularly not ROLLBACK, because they may need to be executed in 2168 * aborted transactions when we can't revalidate them (cf bug #5269). 2169 */ 2170 if (IsTransactionStmtPlan(plansource)) 2171 continue; 2172 2173 /* 2174 * In general there is no point in invalidating utility statements 2175 * since they have no plans anyway. So invalidate it only if it 2176 * contains at least one non-utility statement, or contains a utility 2177 * statement that contains a pre-analyzed query (which could have 2178 * dependencies.) 2179 */ 2180 foreach(lc, plansource->query_list) 2181 { 2182 Query *query = lfirst_node(Query, lc); 2183 2184 if (query->commandType != CMD_UTILITY || 2185 UtilityContainsQuery(query->utilityStmt)) 2186 { 2187 /* non-utility statement, so invalidate */ 2188 plansource->is_valid = false; 2189 if (plansource->gplan) 2190 plansource->gplan->is_valid = false; 2191 /* no need to look further */ 2192 break; 2193 } 2194 } 2195 } 2196 2197 /* Likewise invalidate cached expressions */ 2198 dlist_foreach(iter, &cached_expression_list) 2199 { 2200 CachedExpression *cexpr = dlist_container(CachedExpression, 2201 node, iter.cur); 2202 2203 Assert(cexpr->magic == CACHEDEXPR_MAGIC); 2204 2205 cexpr->is_valid = false; 2206 } 2207 } 2208