mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-08-31 09:27:24 +02:00
Fix plancache refcount leak after error in ExecuteQuery.
When stuffing a plan from the plancache into a Portal, one is
not supposed to risk throwing an error between GetCachedPlan and
PortalDefineQuery; if that happens, the plan refcount incremented
by GetCachedPlan will be leaked. I managed to break this rule
while refactoring code in 9dbf2b7d7
. There is no visible
consequence other than some memory leakage, and since nobody is
very likely to trigger the relevant error conditions many times
in a row, it's not surprising we haven't noticed. Nonetheless,
it's a bug, so rearrange the order of operations to remove the
hazard.
Noted on the way to looking for a better fix for bug #17053.
This mistake is pretty old, so back-patch to all supported
branches.
This commit is contained in:
parent
c0a7587807
commit
9cf1632660
@ -246,6 +246,17 @@ ExecuteQuery(ExecuteStmt *stmt, IntoClause *intoClause,
|
|||||||
cplan = GetCachedPlan(entry->plansource, paramLI, false, NULL);
|
cplan = GetCachedPlan(entry->plansource, paramLI, false, NULL);
|
||||||
plan_list = cplan->stmt_list;
|
plan_list = cplan->stmt_list;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DO NOT add any logic that could possibly throw an error between
|
||||||
|
* GetCachedPlan and PortalDefineQuery, or you'll leak the plan refcount.
|
||||||
|
*/
|
||||||
|
PortalDefineQuery(portal,
|
||||||
|
NULL,
|
||||||
|
query_string,
|
||||||
|
entry->plansource->commandTag,
|
||||||
|
plan_list,
|
||||||
|
cplan);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For CREATE TABLE ... AS EXECUTE, we must verify that the prepared
|
* For CREATE TABLE ... AS EXECUTE, we must verify that the prepared
|
||||||
* statement is one that produces tuples. Currently we insist that it be
|
* statement is one that produces tuples. Currently we insist that it be
|
||||||
@ -289,13 +300,6 @@ ExecuteQuery(ExecuteStmt *stmt, IntoClause *intoClause,
|
|||||||
count = FETCH_ALL;
|
count = FETCH_ALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PortalDefineQuery(portal,
|
|
||||||
NULL,
|
|
||||||
query_string,
|
|
||||||
entry->plansource->commandTag,
|
|
||||||
plan_list,
|
|
||||||
cplan);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Run the portal as appropriate.
|
* Run the portal as appropriate.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user