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