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

Commitf26c06a

Browse files
committed
Fix error-cleanup mistakes in exec_stmt_call().
Commit15c7293 was a couple bricks shy of a load: we need toensure that expr->plan gets reset to NULL on any error exit,if it's not supposed to be saved. Also ensure that thestmt->target calculation gets redone if needed.The easy way to exhibit a problem is to set up code thatviolates the writable-argument restriction and then executeit twice. But error exits out of, eg, setup_param_list()could also break it. Make the existing PG_TRY block coverall of that code to be sure.Per report from Pavel Stehule.Discussion:https://postgr.es/m/CAFj8pRAeXNTO43W2Y0Cn0YOVFPv1WpYyOqQrrzUiN6s=dn7gCg@mail.gmail.com
1 parentfa2952d commitf26c06a

File tree

1 file changed

+45
-37
lines changed

1 file changed

+45
-37
lines changed

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

Lines changed: 45 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2072,39 +2072,50 @@ static int
20722072
exec_stmt_call(PLpgSQL_execstate*estate,PLpgSQL_stmt_call*stmt)
20732073
{
20742074
PLpgSQL_expr*expr=stmt->expr;
2075-
ParamListInfoparamLI;
2076-
LocalTransactionIdbefore_lxid;
2075+
volatileLocalTransactionIdbefore_lxid;
20772076
LocalTransactionIdafter_lxid;
2078-
boolpushed_active_snap= false;
2079-
intrc;
2077+
volatileboolpushed_active_snap= false;
2078+
volatileintrc;
20802079

2081-
if (expr->plan==NULL)
2080+
/* PG_TRY to ensure we clear the plan link, if needed, on failure */
2081+
PG_TRY();
20822082
{
2083-
SPIPlanPtrplan;
2083+
SPIPlanPtrplan=expr->plan;
2084+
ParamListInfoparamLI;
20842085

2085-
/*
2086-
* Don't save the plan if not in atomic context. Otherwise,
2087-
* transaction ends would cause errors about plancache leaks. XXX
2088-
* This would be fixable with some plancache/resowner surgery
2089-
* elsewhere, but for now we'll just work around this here.
2090-
*/
2091-
exec_prepare_plan(estate,expr,0,estate->atomic);
2086+
if (plan==NULL)
2087+
{
20922088

2093-
/*
2094-
* The procedure call could end transactions, which would upset the
2095-
* snapshot management in SPI_execute*, so don't let it do it.
2096-
* Instead, we set the snapshots ourselves below.
2097-
*/
2098-
plan=expr->plan;
2099-
plan->no_snapshots= true;
2089+
/*
2090+
* Don't save the plan if not in atomic context. Otherwise,
2091+
* transaction ends would cause errors about plancache leaks.
2092+
*
2093+
* XXX This would be fixable with some plancache/resowner surgery
2094+
* elsewhere, but for now we'll just work around this here.
2095+
*/
2096+
exec_prepare_plan(estate,expr,0,estate->atomic);
2097+
2098+
/*
2099+
* The procedure call could end transactions, which would upset
2100+
* the snapshot management in SPI_execute*, so don't let it do it.
2101+
* Instead, we set the snapshots ourselves below.
2102+
*/
2103+
plan=expr->plan;
2104+
plan->no_snapshots= true;
2105+
2106+
/*
2107+
* Force target to be recalculated whenever the plan changes, in
2108+
* case the procedure's argument list has changed.
2109+
*/
2110+
stmt->target=NULL;
2111+
}
21002112

21012113
/*
21022114
* We construct a DTYPE_ROW datum representing the plpgsql variables
21032115
* associated with the procedure's output arguments. Then we can use
2104-
* exec_move_row() to do the assignments. (We do this each time the
2105-
* plan changes, in case the procedure's argument list has changed.)
2116+
* exec_move_row() to do the assignments.
21062117
*/
2107-
if (stmt->is_call)
2118+
if (stmt->is_call&&stmt->target==NULL)
21082119
{
21092120
Node*node;
21102121
FuncExpr*funcexpr;
@@ -2206,24 +2217,21 @@ exec_stmt_call(PLpgSQL_execstate *estate, PLpgSQL_stmt_call *stmt)
22062217

22072218
stmt->target= (PLpgSQL_variable*)row;
22082219
}
2209-
}
22102220

2211-
paramLI=setup_param_list(estate,expr);
2221+
paramLI=setup_param_list(estate,expr);
22122222

2213-
before_lxid=MyProc->lxid;
2223+
before_lxid=MyProc->lxid;
22142224

2215-
/*
2216-
* Set snapshot only for non-read-only procedures, similar to SPI
2217-
* behavior.
2218-
*/
2219-
if (!estate->readonly_func)
2220-
{
2221-
PushActiveSnapshot(GetTransactionSnapshot());
2222-
pushed_active_snap= true;
2223-
}
2225+
/*
2226+
* Set snapshot only for non-read-only procedures, similar to SPI
2227+
* behavior.
2228+
*/
2229+
if (!estate->readonly_func)
2230+
{
2231+
PushActiveSnapshot(GetTransactionSnapshot());
2232+
pushed_active_snap= true;
2233+
}
22242234

2225-
PG_TRY();
2226-
{
22272235
rc=SPI_execute_plan_with_paramlist(expr->plan,paramLI,
22282236
estate->readonly_func,0);
22292237
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp