]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
pgbench: fix misprocessing of some nested \if constructs.
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 15 Dec 2024 19:14:15 +0000 (14:14 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 15 Dec 2024 19:14:15 +0000 (14:14 -0500)
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
src/bin/pgbench/t/001_pgbench_with_server.pl

index c0825ae6790b5b52c1dffafc31fd91ebfd6c62a4..8b2e61d27e01862628f3922b87180793d6a3eff1 100644 (file)
@@ -3889,8 +3889,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;
@@ -3909,11 +3915,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;
index f9690c649574155fc7566fe62ed16e22ef084062..28b23cdc6783888b1e1b1c28dbb455de4aabb3de 100644 (file)
@@ -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);'