Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb998655

Browse files
committed
Fix plan cache issue in PL/pgSQL CALL
If we are not going to save the plan, then we need to unset expr->planafter we are done, also in error cases. Otherwise, we get a danglingpointer next time around.This is not the ideal solution. It would be better if we could convinceSPI not to associate a cached plan with a resource owner, and then wecould just save the plan in all cases. But that would require biggersurgery.Reported-by: Pavel Stehule <pavel.stehule@gmail.com>
1 parent6a5f796 commitb998655

File tree

3 files changed

+40
-4
lines changed

3 files changed

+40
-4
lines changed

‎src/pl/plpgsql/src/expected/plpgsql_call.out

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,16 @@ SELECT * FROM test1;
5353
66
5454
(2 rows)
5555

56+
CALL test_proc4(66);
57+
SELECT * FROM test1;
58+
a
59+
----
60+
66
61+
66
62+
66
63+
66
64+
(4 rows)
65+
5666
-- output arguments
5767
CREATE PROCEDURE test_proc5(INOUT a text)
5868
LANGUAGE plpgsql

‎src/pl/plpgsql/src/pl_exec.c

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2060,6 +2060,7 @@ static int
20602060
exec_stmt_call(PLpgSQL_execstate*estate,PLpgSQL_stmt_call*stmt)
20612061
{
20622062
PLpgSQL_expr*expr=stmt->expr;
2063+
SPIPlanPtrplan;
20632064
ParamListInfoparamLI;
20642065
LocalTransactionIdbefore_lxid;
20652066
LocalTransactionIdafter_lxid;
@@ -2069,7 +2070,9 @@ exec_stmt_call(PLpgSQL_execstate *estate, PLpgSQL_stmt_call *stmt)
20692070
{
20702071
/*
20712072
* Don't save the plan if not in atomic context. Otherwise,
2072-
* transaction ends would cause warnings about plan leaks.
2073+
* transaction ends would cause errors about plancache leaks. XXX
2074+
* This would be fixable with some plancache/resowner surgery
2075+
* elsewhere, but for now we'll just work around this here.
20732076
*/
20742077
exec_prepare_plan(estate,expr,0,estate->atomic);
20752078

@@ -2084,8 +2087,27 @@ exec_stmt_call(PLpgSQL_execstate *estate, PLpgSQL_stmt_call *stmt)
20842087

20852088
before_lxid=MyProc->lxid;
20862089

2087-
rc=SPI_execute_plan_with_paramlist(expr->plan,paramLI,
2088-
estate->readonly_func,0);
2090+
PG_TRY();
2091+
{
2092+
rc=SPI_execute_plan_with_paramlist(expr->plan,paramLI,
2093+
estate->readonly_func,0);
2094+
}
2095+
PG_CATCH();
2096+
{
2097+
/*
2098+
* If we aren't saving the plan, unset the pointer. Note that it
2099+
* could have been unset already, in case of a recursive call.
2100+
*/
2101+
if (expr->plan&& !expr->plan->saved)
2102+
expr->plan=NULL;
2103+
PG_RE_THROW();
2104+
}
2105+
PG_END_TRY();
2106+
2107+
plan=expr->plan;
2108+
2109+
if (expr->plan&& !expr->plan->saved)
2110+
expr->plan=NULL;
20892111

20902112
after_lxid=MyProc->lxid;
20912113

@@ -2129,7 +2151,7 @@ exec_stmt_call(PLpgSQL_execstate *estate, PLpgSQL_stmt_call *stmt)
21292151
/*
21302152
* Get the original CallStmt
21312153
*/
2132-
node=linitial_node(Query, ((CachedPlanSource*)linitial(expr->plan->plancache_list))->query_list)->utilityStmt;
2154+
node=linitial_node(Query, ((CachedPlanSource*)linitial(plan->plancache_list))->query_list)->utilityStmt;
21332155
if (!IsA(node,CallStmt))
21342156
elog(ERROR,"returned row from not a CallStmt");
21352157

‎src/pl/plpgsql/src/sql/plpgsql_call.sql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ CALL test_proc4(66);
5454

5555
SELECT*FROM test1;
5656

57+
CALL test_proc4(66);
58+
59+
SELECT*FROM test1;
60+
5761

5862
-- output arguments
5963

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp