1
0
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:
Tom Lane
2004-12-19 20:20:27 +00:00
parent 1553be4a0b
commit e184663b24
3 changed files with 134 additions and 7 deletions

View File

@@ -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();
/*