summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2024-12-15 19:14:14 +0000
committerTom Lane2024-12-15 19:14:14 +0000
commit530f89e648da3a5505920322dcd4e00e15559f66 (patch)
treebdd4d7a6389ace6e38be7478b024a07e084d62b1
parent56499315a74f97d220373e396903c389d85c8933 (diff)
pgbench: fix misprocessing of some nested \if constructs.
An \if command appearing within a false (not-to-be-executed) \if branch was incorrectly treated the same as \elif. This could allow statements within the inner \if to be executed when they should not be. Also the missing inner \if stack entry would result in an assertion failure (in assert-enabled builds) when the final \endif is reached. Report and patch by Michail Nikolaev. Back-patch to all supported branches. Discussion: https://postgr.es/m/CANtu0oiA1ke=SP6tauhNqkUdv5QFsJtS1p=aOOf_iU+EhyKkjQ@mail.gmail.com
-rw-r--r--src/bin/pgbench/pgbench.c16
-rw-r--r--src/bin/pgbench/t/001_pgbench_with_server.pl50
2 files changed, 59 insertions, 7 deletions
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index c4c38099c5b..3b2f708ebe7 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -3880,8 +3880,14 @@ advanceConnectionState(TState *thread, CState *st, StatsData *agg)
switch (conditional_stack_peek(st->cstack))
{
case IFSTATE_FALSE:
- if (command->meta == META_IF ||
- command->meta == META_ELIF)
+ if (command->meta == META_IF)
+ {
+ /* nested if in skipped branch - ignore */
+ conditional_stack_push(st->cstack,
+ IFSTATE_IGNORED);
+ st->command++;
+ }
+ else if (command->meta == META_ELIF)
{
/* we must evaluate the condition */
st->state = CSTATE_START_COMMAND;
@@ -3900,11 +3906,7 @@ advanceConnectionState(TState *thread, CState *st, StatsData *agg)
conditional_stack_pop(st->cstack);
if (conditional_active(st->cstack))
st->state = CSTATE_START_COMMAND;
-
- /*
- * else state remains in
- * CSTATE_SKIP_COMMAND
- */
+ /* else state remains CSTATE_SKIP_COMMAND */
st->command++;
}
break;
diff --git a/src/bin/pgbench/t/001_pgbench_with_server.pl b/src/bin/pgbench/t/001_pgbench_with_server.pl
index 0bc5c0042eb..4484b132ef3 100644
--- a/src/bin/pgbench/t/001_pgbench_with_server.pl
+++ b/src/bin/pgbench/t/001_pgbench_with_server.pl
@@ -668,6 +668,56 @@ SELECT :v0, :v1, :v2, :v3;
}
});
+# test nested \if constructs
+$node->pgbench(
+ '--no-vacuum --client=1 --exit-on-abort --transactions=1',
+ 0,
+ [qr{actually processed}],
+ [qr{^$}],
+ 'nested ifs',
+ {
+ 'pgbench_nested_if' => q(
+ \if false
+ SELECT 1 / 0;
+ \if true
+ SELECT 1 / 0;
+ \elif true
+ SELECT 1 / 0;
+ \else
+ SELECT 1 / 0;
+ \endif
+ SELECT 1 / 0;
+ \elif false
+ \if true
+ SELECT 1 / 0;
+ \elif true
+ SELECT 1 / 0;
+ \else
+ SELECT 1 / 0;
+ \endif
+ \else
+ \if false
+ SELECT 1 / 0;
+ \elif false
+ SELECT 1 / 0;
+ \else
+ SELECT 'correct';
+ \endif
+ \endif
+ \if true
+ SELECT 'correct';
+ \else
+ \if true
+ SELECT 1 / 0;
+ \elif true
+ SELECT 1 / 0;
+ \else
+ SELECT 1 / 0;
+ \endif
+ \endif
+ )
+ });
+
# random determinism when seeded
$node->safe_psql('postgres',
'CREATE UNLOGGED TABLE seeded_random(seed INT8 NOT NULL, rand TEXT NOT NULL, val INTEGER NOT NULL);'