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

Commit73b06cf

Browse files
committed
Avoid taking a new snapshot for an immutable simple expression in plpgsql.
We already used this optimization if the plpgsql function is read-only.But it seems okay to do it even in a read-write function, if theexpression contains only immutable functions/operators. There wouldonly be a change of behavior if an "immutable" called function dependson seeing database updates made during the current plpgsql function.That's enough of a violation of the promise of immutability that anyonewho complains won't have much of a case.The benefits are significant --- for simple cases like while i < 10000000 loop i := i + 1; end loop;I see net performance improvements around 45%. Of course, real-worldcases won't get that much faster, but it ought to be noticeable.At the very least, this removes much of the performance penalty thatused to exist for forgetting to mark a plpgsql function non-volatile.Konstantin Knizhnik, reviewed by Pavel Stehule, cosmetic changes by meDiscussion:https://postgr.es/m/ed9da20e-01aa-d04b-d085-e6c16b14b9d7@postgrespro.ru
1 parentf67b173 commit73b06cf

File tree

2 files changed

+16
-5
lines changed

2 files changed

+16
-5
lines changed

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

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6079,6 +6079,7 @@ exec_eval_simple_expr(PLpgSQL_execstate *estate,
60796079
LocalTransactionIdcurlxid=MyProc->lxid;
60806080
CachedPlan*cplan;
60816081
void*save_setup_arg;
6082+
boolneed_snapshot;
60826083
MemoryContextoldcontext;
60836084

60846085
/*
@@ -6150,12 +6151,19 @@ exec_eval_simple_expr(PLpgSQL_execstate *estate,
61506151

61516152
/*
61526153
* We have to do some of the things SPI_execute_plan would do, in
6153-
* particular advance the snapshot if we are in a non-read-only function.
6154-
* Without this, stable functions within the expression would fail to see
6155-
* updates made so far by our own function.
6154+
* particular push a new snapshot so that stable functions within the
6155+
* expression can see updates made so far by our own function. However,
6156+
* we can skip doing that (and just invoke the expression with the same
6157+
* snapshot passed to our function) in some cases, which is useful because
6158+
* it's quite expensive relative to the cost of a simple expression. We
6159+
* can skip it if the expression contains no stable or volatile functions;
6160+
* immutable functions shouldn't need to see our updates. Also, if this
6161+
* is a read-only function, we haven't made any updates so again it's okay
6162+
* to skip.
61566163
*/
61576164
oldcontext=MemoryContextSwitchTo(get_eval_mcontext(estate));
6158-
if (!estate->readonly_func)
6165+
need_snapshot= (expr->expr_simple_mutable&& !estate->readonly_func);
6166+
if (need_snapshot)
61596167
{
61606168
CommandCounterIncrement();
61616169
PushActiveSnapshot(GetTransactionSnapshot());
@@ -6180,7 +6188,7 @@ exec_eval_simple_expr(PLpgSQL_execstate *estate,
61806188

61816189
estate->paramLI->parserSetupArg=save_setup_arg;
61826190

6183-
if (!estate->readonly_func)
6191+
if (need_snapshot)
61846192
PopActiveSnapshot();
61856193

61866194
MemoryContextSwitchTo(oldcontext);
@@ -8051,6 +8059,8 @@ exec_save_simple_expr(PLpgSQL_expr *expr, CachedPlan *cplan)
80518059
/* Also stash away the expression result type */
80528060
expr->expr_simple_type=exprType((Node*)tle_expr);
80538061
expr->expr_simple_typmod=exprTypmod((Node*)tle_expr);
8062+
/* We also want to remember if it is immutable or not */
8063+
expr->expr_simple_mutable=contain_mutable_functions((Node*)tle_expr);
80548064
}
80558065

80568066
/*

‎src/pl/plpgsql/src/plpgsql.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ typedef struct PLpgSQL_expr
234234
intexpr_simple_generation;/* plancache generation we checked */
235235
Oidexpr_simple_type;/* result type Oid, if simple */
236236
int32expr_simple_typmod;/* result typmod, if simple */
237+
boolexpr_simple_mutable;/* true if simple expr is mutable */
237238

238239
/*
239240
* if expr is simple AND prepared in current transaction,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp