mirror of
https://github.com/postgres/postgres.git
synced 2025-08-27 07:42:10 +03:00
Change plan caching to honor, not resist, changes in search_path.
In the initial implementation of plan caching, we saved the active search_path when a plan was first cached, then reinstalled that path anytime we needed to reparse or replan. The idea of that was to try to reselect the same referenced objects, in somewhat the same way that views continue to refer to the same objects in the face of schema or name changes. Of course, that analogy doesn't bear close inspection, since holding the search_path fixed doesn't cope with object drops or renames. Moreover sticking with the old path seems to create more surprises than it avoids. So instead of doing that, consider that the cached plan depends on search_path, and force reparse/replan if the active search_path is different than it was when we last saved the plan. This gets us fairly close to having "transparency" of plan caching, in the sense that the cached statement acts the same as if you'd just resubmitted the original query text for another execution. There are still some corner cases where this fails though: a new object added in the search path schema(s) might capture a reference in the query text, but we'd not realize that and force a reparse. We might try to fix that in the future, but for the moment it looks too expensive and complicated.
This commit is contained in:
@@ -86,12 +86,13 @@ typedef struct CachedPlanSource
|
||||
int cursor_options; /* cursor options used for planning */
|
||||
bool fixed_result; /* disallow change in result tupdesc? */
|
||||
TupleDesc resultDesc; /* result type; NULL = doesn't return tuples */
|
||||
struct OverrideSearchPath *search_path; /* saved search_path */
|
||||
MemoryContext context; /* memory context holding all above */
|
||||
/* These fields describe the current analyzed-and-rewritten query tree: */
|
||||
List *query_list; /* list of Query nodes, or NIL if not valid */
|
||||
List *relationOids; /* OIDs of relations the queries depend on */
|
||||
List *invalItems; /* other dependencies, as PlanInvalItems */
|
||||
struct OverrideSearchPath *search_path; /* search_path used for
|
||||
* parsing and planning */
|
||||
MemoryContext query_context; /* context holding the above, or NULL */
|
||||
/* If we have a generic plan, this is a reference-counted link to it: */
|
||||
struct CachedPlan *gplan; /* generic plan, or NULL if not valid */
|
||||
|
Reference in New Issue
Block a user