From 873028c217b4353f482d8c43a3eddd3521bfe370 Mon Sep 17 00:00:00 2001 From: nkey Date: Sun, 15 Dec 2024 14:04:26 +0100 Subject: [PATCH v1] pgbench: Fix nested if/elif/else handling in scripts Add support for properly handling nested conditional blocks in pgbench scripts by correctly tracking the state of inner conditional blocks when they appear inside skipped (false) branches. Previously, the evaluation of conditions in nested blocks could lead to incorrect behavior. Add a regression test to verify nested if/elif/else statements work as expected. --- src/bin/pgbench/meson.build | 1 + src/bin/pgbench/pgbench.c | 10 +++- src/bin/pgbench/t/003_pgbench_nested_ifs.pl | 57 +++++++++++++++++++++ 3 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 src/bin/pgbench/t/003_pgbench_nested_ifs.pl diff --git a/src/bin/pgbench/meson.build b/src/bin/pgbench/meson.build index d330bb5eb0d..ac45cad4015 100644 --- a/src/bin/pgbench/meson.build +++ b/src/bin/pgbench/meson.build @@ -43,6 +43,7 @@ tests += { 'tests': [ 't/001_pgbench_with_server.pl', 't/002_pgbench_no_server.pl', + 't/003_pgbench_nested_ifs.pl', ], }, } diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c index c4c38099c5b..5181629133e 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; diff --git a/src/bin/pgbench/t/003_pgbench_nested_ifs.pl b/src/bin/pgbench/t/003_pgbench_nested_ifs.pl new file mode 100644 index 00000000000..52bc1734e06 --- /dev/null +++ b/src/bin/pgbench/t/003_pgbench_nested_ifs.pl @@ -0,0 +1,57 @@ +# Copyright (c) 2021-2024, PostgreSQL Global Development Group + +# Test nested if/elif/else working correctly in pgbench +use strict; +use warnings FATAL => 'all'; + +use PostgreSQL::Test::Cluster; +use PostgreSQL::Test::Utils; + +use Test::More; + +my ($node, $result); + +$node = PostgreSQL::Test::Cluster->new('pgbench_nested_ifs'); +$node->init; +$node->start; + +$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 + ) + }); + +$node->stop; +done_testing(); -- 2.43.0