postgres.git / summary / log / commit / refs

commit    ec0dc2c596ff7c950ea3d47bf0994ef0e322ceb7
Author:   Tom Lane <tgl@sss.pgh.pa.us>
Date:     Sun Dec 15 19:14:15 2024 +0000
First released in: 18.0, 13.19, 14.16, 15.11, 16.7, 17.3

    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 6bccacaf86c..ed301e120c4 100644 --- a/src/bin/pgbench/pgbench.c +++ b/src/bin/pgbench/pgbench.c @@ -3133,8 +3133,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; @@ -3153,11 +3159,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 13fde757fd7..a4a7afd64f5 100644 --- a/src/bin/pgbench/t/001_pgbench_with_server.pl +++ b/src/bin/pgbench/t/001_pgbench_with_server.pl @@ -623,6 +623,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);' [parent: b6df2d6e5d83]