I've set the CF entry to "Waiting on Author" pending a new patch that does it like that.
With contain_mutable_functions the patch becomes trivial. -- Konstantin Knizhnik Postgres Professional: http://www.postgrespro.com The Russian Postgres Company
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index a4697dc..55ed878 100644 --- a/src/pl/plpgsql/src/pl_exec.c +++ b/src/pl/plpgsql/src/pl_exec.c @@ -30,6 +30,7 @@ #include "funcapi.h" #include "miscadmin.h" #include "nodes/nodeFuncs.h" +#include "optimizer/clauses.h" #include "optimizer/optimizer.h" #include "parser/parse_coerce.h" #include "parser/parse_type.h" @@ -6157,7 +6158,7 @@ exec_eval_simple_expr(PLpgSQL_execstate *estate, * updates made so far by our own function. */ oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate)); - if (!estate->readonly_func) + if (!estate->readonly_func && expr->expr_needs_snapshot) { CommandCounterIncrement(); PushActiveSnapshot(GetTransactionSnapshot()); @@ -6182,7 +6183,7 @@ exec_eval_simple_expr(PLpgSQL_execstate *estate, estate->paramLI->parserSetupArg = save_setup_arg; - if (!estate->readonly_func) + if (!estate->readonly_func && expr->expr_needs_snapshot) PopActiveSnapshot(); MemoryContextSwitchTo(oldcontext); @@ -8046,6 +8047,7 @@ exec_save_simple_expr(PLpgSQL_expr *expr, CachedPlan *cplan) * current transaction". */ expr->expr_simple_expr = tle_expr; + expr->expr_needs_snapshot = contain_mutable_functions((Node*)tle_expr); expr->expr_simple_generation = cplan->generation; expr->expr_simple_state = NULL; expr->expr_simple_in_use = false; diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h index f66b2ba..454131f 100644 --- a/src/pl/plpgsql/src/plpgsql.h +++ b/src/pl/plpgsql/src/plpgsql.h @@ -243,6 +243,7 @@ typedef struct PLpgSQL_expr */ ExprState *expr_simple_state; /* eval tree for expr_simple_expr */ bool expr_simple_in_use; /* true if eval tree is active */ + bool expr_needs_snapshot; /* true if simple expression calls non-immutable functions or performs subqueries */ LocalTransactionId expr_simple_lxid; } PLpgSQL_expr;