mirror of
https://github.com/postgres/postgres.git
synced 2025-09-02 04:21:28 +03:00
plpgsql's exec_eval_simple_expr() now has to take responsibility for
advancing ActiveSnapshot when we are inside a volatile function. Per example from Gaetano Mendola. Add a regression test to catch similar problems in future.
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
* procedural language
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.124 2004/12/11 23:26:51 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.125 2004/12/19 20:20:17 tgl Exp $
|
||||
*
|
||||
* This software is copyrighted by Jan Wieck - Hamburg.
|
||||
*
|
||||
@@ -3548,9 +3548,10 @@ exec_eval_simple_expr(PLpgSQL_execstate *estate,
|
||||
Oid *rettype)
|
||||
{
|
||||
Datum retval;
|
||||
ExprContext *econtext;
|
||||
ExprContext * volatile econtext;
|
||||
ParamListInfo paramLI;
|
||||
int i;
|
||||
Snapshot saveActiveSnapshot;
|
||||
|
||||
/*
|
||||
* Pass back previously-determined result type.
|
||||
@@ -3629,13 +3630,39 @@ exec_eval_simple_expr(PLpgSQL_execstate *estate,
|
||||
econtext->ecxt_param_list_info = paramLI;
|
||||
|
||||
/*
|
||||
* Now call the executor to evaluate the expression
|
||||
* We have to do some of the things SPI_execute_plan would do,
|
||||
* in particular adjust ActiveSnapshot if we are in a non-read-only
|
||||
* function. Without this, stable functions within the expression
|
||||
* would fail to see updates made so far by our own function.
|
||||
*/
|
||||
SPI_push();
|
||||
retval = ExecEvalExprSwitchContext(expr->expr_simple_state,
|
||||
econtext,
|
||||
isNull,
|
||||
NULL);
|
||||
saveActiveSnapshot = ActiveSnapshot;
|
||||
|
||||
PG_TRY();
|
||||
{
|
||||
MemoryContext oldcontext;
|
||||
|
||||
oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
|
||||
if (!estate->readonly_func)
|
||||
ActiveSnapshot = CopySnapshot(GetTransactionSnapshot());
|
||||
/*
|
||||
* Finally we can call the executor to evaluate the expression
|
||||
*/
|
||||
retval = ExecEvalExpr(expr->expr_simple_state,
|
||||
econtext,
|
||||
isNull,
|
||||
NULL);
|
||||
MemoryContextSwitchTo(oldcontext);
|
||||
}
|
||||
PG_CATCH();
|
||||
{
|
||||
/* Restore global vars and propagate error */
|
||||
ActiveSnapshot = saveActiveSnapshot;
|
||||
PG_RE_THROW();
|
||||
}
|
||||
PG_END_TRY();
|
||||
|
||||
ActiveSnapshot = saveActiveSnapshot;
|
||||
SPI_pop();
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user