aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2024-12-15 14:14:15 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2024-12-15 14:14:15 -0500
commit2a23dbcf35946b844699c65fdf2ee440251eab12 (patch)
treef78d0a8ec2f0d64cc9dfbcbe5dbb481fb5d452f7
parentc7f3c414fdedbb9a48d597a309c53fdf1ac3652a (diff)
downloadpostgresql-2a23dbcf35946b844699c65fdf2ee440251eab12.tar.gz
postgresql-2a23dbcf35946b844699c65fdf2ee440251eab12.zip
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 c7f8431841a..1f6cb0e6038 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -3446,8 +3446,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;
@@ -3466,11 +3472,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 4f716c6c073..fbd45c766cc 100644
--- a/src/bin/pgbench/t/001_pgbench_with_server.pl
+++ b/src/bin/pgbench/t/001_pgbench_with_server.pl
@@ -622,6 +622,56 @@ SELECT :v0, :v1, :v2, :v3;
}
});
+# test nested \if constructs
+$node->pgbench(
+ '--no-vacuum --client=1 --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);'