|
61 | 61 | #include "utils/syscache.h"
|
62 | 62 |
|
63 | 63 |
|
| 64 | +/* |
| 65 | + * We must skip "overhead" operations that involve database access when the |
| 66 | + * cached plan's subject statement is a transaction control command. |
| 67 | + */ |
| 68 | +#define IsTransactionStmtPlan(plansource) \ |
| 69 | + ((plansource)->raw_parse_tree && \ |
| 70 | + IsA((plansource)->raw_parse_tree, TransactionStmt)) |
| 71 | + |
64 | 72 | static List *cached_plans_list = NIL;
|
65 | 73 |
|
66 | 74 | static void StoreCachedPlan(CachedPlanSource *plansource, List *stmt_list,
|
@@ -136,9 +144,13 @@ CreateCachedPlan(Node *raw_parse_tree,
|
136 | 144 |
|
137 | 145 | /*
|
138 | 146 | * Fetch current search_path into new context, but do any recalculation
|
139 |
| - * work required in caller's context. |
| 147 | + * work required in caller's context. Skip this for a transaction control |
| 148 | + * command, since we won't need it and can't risk catalog access. |
140 | 149 | */
|
141 |
| - search_path = GetOverrideSearchPath(source_context); |
| 150 | + if (raw_parse_tree && IsA(raw_parse_tree, TransactionStmt)) |
| 151 | + search_path = NULL; |
| 152 | + else |
| 153 | + search_path = GetOverrideSearchPath(source_context); |
142 | 154 |
|
143 | 155 | /*
|
144 | 156 | * Create and fill the CachedPlanSource struct within the new context.
|
@@ -229,9 +241,13 @@ FastCreateCachedPlan(Node *raw_parse_tree,
|
229 | 241 |
|
230 | 242 | /*
|
231 | 243 | * Fetch current search_path into given context, but do any recalculation
|
232 |
| - * work required in caller's context. |
| 244 | + * work required in caller's context. Skip this for a transaction control |
| 245 | + * command, since we won't need it and can't risk catalog access. |
233 | 246 | */
|
234 |
| - search_path = GetOverrideSearchPath(context); |
| 247 | + if (raw_parse_tree && IsA(raw_parse_tree, TransactionStmt)) |
| 248 | + search_path = NULL; |
| 249 | + else |
| 250 | + search_path = GetOverrideSearchPath(context); |
235 | 251 |
|
236 | 252 | /*
|
237 | 253 | * Create and fill the CachedPlanSource struct within the given context.
|
@@ -517,7 +533,8 @@ RevalidateCachedPlan(CachedPlanSource *plansource, bool useResOwner)
|
517 | 533 | *
|
518 | 534 | * (XXX is there anything else we really need to restore?)
|
519 | 535 | */
|
520 |
| - PushOverrideSearchPath(plansource->search_path); |
| 536 | + if (plansource->search_path) |
| 537 | + PushOverrideSearchPath(plansource->search_path); |
521 | 538 |
|
522 | 539 | /*
|
523 | 540 | * If a snapshot is already set (the normal case), we can just use
|
@@ -601,7 +618,8 @@ RevalidateCachedPlan(CachedPlanSource *plansource, bool useResOwner)
|
601 | 618 | PopActiveSnapshot();
|
602 | 619 |
|
603 | 620 | /* Now we can restore current search path */
|
604 |
| - PopOverrideSearchPath(); |
| 621 | + if (plansource->search_path) |
| 622 | + PopOverrideSearchPath(); |
605 | 623 |
|
606 | 624 | /*
|
607 | 625 | * Store the plans into the plancache entry, advancing the generation
|
|
0 commit comments