From 076b09123078033ebef609c91a9a276ee6e1bcb3 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 15 Dec 2024 14:14:15 -0500 Subject: [PATCH] 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 --- src/bin/pgbench/pgbench.c | 16 ++++--- src/bin/pgbench/t/001_pgbench_with_server.pl | 50 ++++++++++++++++++++ 2 files changed, 59 insertions(+), 7 deletions(-) diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c index fd2c8f42c50..1aa6661f142 100644 --- a/src/bin/pgbench/pgbench.c +++ b/src/bin/pgbench/pgbench.c @@ -3865,8 +3865,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; @@ -3885,11 +3891,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 afc9ecfaf77..d746987b530 100644 --- a/src/bin/pgbench/t/001_pgbench_with_server.pl +++ b/src/bin/pgbench/t/001_pgbench_with_server.pl @@ -633,6 +633,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);' -- 2.39.5