|
33 | 33 | * Portions Copyright (c) 1994, Regents of the University of California |
34 | 34 | * |
35 | 35 | * IDENTIFICATION |
36 | | - * $PostgreSQL: pgsql/src/backend/utils/cache/plancache.c,v 1.8 2007/04/16 18:21:07 tgl Exp $ |
| 36 | + * $PostgreSQL: pgsql/src/backend/utils/cache/plancache.c,v 1.9 2007/05/14 18:13:21 tgl Exp $ |
37 | 37 | * |
38 | 38 | *------------------------------------------------------------------------- |
39 | 39 | */ |
@@ -69,6 +69,7 @@ static List *cached_plans_list = NIL; |
69 | 69 |
|
70 | 70 | staticvoidStoreCachedPlan(CachedPlanSource*plansource,List*stmt_list, |
71 | 71 | MemoryContextplan_context); |
| 72 | +staticList*do_planning(List*querytrees,intcursorOptions); |
72 | 73 | staticvoidAcquireExecutorLocks(List*stmt_list,boolacquire); |
73 | 74 | staticvoidAcquirePlannerLocks(List*stmt_list,boolacquire); |
74 | 75 | staticvoidLockRelid(Oidrelid,LOCKMODElockmode,void*arg); |
@@ -462,12 +463,8 @@ RevalidateCachedPlan(CachedPlanSource *plansource, bool useResOwner) |
462 | 463 |
|
463 | 464 | if (plansource->fully_planned) |
464 | 465 | { |
465 | | -/* |
466 | | - * Generate plans for queries.Assume snapshot is not set yet |
467 | | - * (XXX this may be wasteful, won't all callers have done that?) |
468 | | - */ |
469 | | -slist=pg_plan_queries(slist,plansource->cursor_options,NULL, |
470 | | -true); |
| 466 | +/* Generate plans for queries */ |
| 467 | +slist=do_planning(slist,plansource->cursor_options); |
471 | 468 | } |
472 | 469 |
|
473 | 470 | /* |
@@ -522,6 +519,49 @@ RevalidateCachedPlan(CachedPlanSource *plansource, bool useResOwner) |
522 | 519 | returnplan; |
523 | 520 | } |
524 | 521 |
|
| 522 | +/* |
| 523 | + * Invoke the planner on some rewritten queries. This is broken out of |
| 524 | + * RevalidateCachedPlan just to avoid plastering "volatile" all over that |
| 525 | + * function's variables. |
| 526 | + */ |
| 527 | +staticList* |
| 528 | +do_planning(List*querytrees,intcursorOptions) |
| 529 | +{ |
| 530 | +List*stmt_list; |
| 531 | + |
| 532 | +/* |
| 533 | + * If a snapshot is already set (the normal case), we can just use that |
| 534 | + * for planning. But if it isn't, we have to tell pg_plan_queries to make |
| 535 | + * a snap if it needs one. In that case we should arrange to reset |
| 536 | + * ActiveSnapshot afterward, to ensure that RevalidateCachedPlan has no |
| 537 | + * caller-visible effects on the snapshot. Having to replan is an unusual |
| 538 | + * case, and it seems a really bad idea for RevalidateCachedPlan to affect |
| 539 | + * the snapshot only in unusual cases. (Besides, the snap might have |
| 540 | + * been created in a short-lived context.) |
| 541 | + */ |
| 542 | +if (ActiveSnapshot!=NULL) |
| 543 | +stmt_list=pg_plan_queries(querytrees,cursorOptions,NULL, false); |
| 544 | +else |
| 545 | +{ |
| 546 | +PG_TRY(); |
| 547 | +{ |
| 548 | +stmt_list=pg_plan_queries(querytrees,cursorOptions,NULL, true); |
| 549 | +} |
| 550 | +PG_CATCH(); |
| 551 | +{ |
| 552 | +/* Restore global vars and propagate error */ |
| 553 | +ActiveSnapshot=NULL; |
| 554 | +PG_RE_THROW(); |
| 555 | +} |
| 556 | +PG_END_TRY(); |
| 557 | + |
| 558 | +ActiveSnapshot=NULL; |
| 559 | +} |
| 560 | + |
| 561 | +returnstmt_list; |
| 562 | +} |
| 563 | + |
| 564 | + |
525 | 565 | /* |
526 | 566 | * ReleaseCachedPlan: release active use of a cached plan. |
527 | 567 | * |
|