diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 272c14f7635..3615d27a221 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -354,7 +354,7 @@ enum enum_commands { Q_INC, Q_DEC, Q_SOURCE, Q_DISCONNECT, Q_LET, Q_ECHO, - Q_WHILE, Q_END_BLOCK, + Q_WHILE, Q_END_BLOCK, Q_BREAK, Q_SYSTEM, Q_RESULT, Q_REQUIRE, Q_SAVE_MASTER_POS, Q_SYNC_WITH_MASTER, @@ -424,6 +424,7 @@ const char *command_names[]= "echo", "while", "end", + "break", "system", "result", "require", @@ -6306,6 +6307,33 @@ enum block_op find_operand(const char *start) return ILLEG_OP; } +/* + do_break + + DESCRIPTION + Instruction to stop execution of the current loop +*/ +void do_break(struct st_command* command) +{ + int depth= 0; + cur_block->ok= false; + + /* Disable every outer block until while found or block stack ends */ + while (cur_block->cmd != cmd_while && cur_block > block_stack) + { + cur_block--; + cur_block->ok= false; + depth++; + } + + /* Check if the top block is not 'while' */ + if (cur_block->cmd != cmd_while) + { + die("Stray break was found"); + } + /* Set current block back */ + cur_block+= depth; +} /* Process start of a "if" or "while" statement @@ -10059,6 +10087,7 @@ int main(int argc, char **argv) case Q_INC: do_modify_var(command, DO_INC); break; case Q_DEC: do_modify_var(command, DO_DEC); break; case Q_ECHO: do_echo(command); command_executed++; break; + case Q_BREAK: do_break(command); break; case Q_SYSTEM: do_system(command); break; case Q_REMOVE_FILE: do_remove_file(command); break; case Q_REMOVE_FILES_WILDCARD: do_remove_files_wildcard(command); break; diff --git a/mysql-test/main/mysqltest-break.result b/mysql-test/main/mysqltest-break.result new file mode 100644 index 00000000000..59091cbcbfe --- /dev/null +++ b/mysql-test/main/mysqltest-break.result @@ -0,0 +1,9 @@ +3 +2 +OK +OK +OK +1 +cnt=3 +cnt=2 +mysqltest: At line 1: Stray break was found diff --git a/mysql-test/main/mysqltest-break.test b/mysql-test/main/mysqltest-break.test new file mode 100644 index 00000000000..378309dd056 --- /dev/null +++ b/mysql-test/main/mysqltest-break.test @@ -0,0 +1,86 @@ +# +# MDEV-12130 improve mysqltest language +# +# test "break" statement +# + +# Break in a single loop + +let $cnt= 4; +while($cnt > 1) +{ + dec $cnt; + break; + --echo $cnt + --echo Break did not stop a single loop +} + +# Break stops inner loop + +let $outer= 4; +while($outer > 1) +{ + let $inner= 4; + while($inner > 1) + { + if($outer == 2) + { + --echo OK + } + if($inner == 2) + { + break; + } + dec $inner; + } + dec $outer; + --echo $outer +} + +# Break stops outer loop +let $inner= 4; +let $outer= 4; +while($outer > 1) +{ + break; + while($inner > 1) + { + dec $inner; + --echo Outer loop`s break did not stop inner loop + } + dec $outer; + --echo $outer +} + +# Break stops loop in if +let $cnt= 4; +if($cnt > 1) +{ + while($cnt) + { + break; + } + dec $cnt; +} + +--echo cnt=$cnt + +# Break in inner if + +let $cnt= 4; +while($cnt > 1) +{ + if($cnt == 2) + { + break; + --echo "if" is working after break + } + dec $cnt; +} + +--echo cnt=$cnt + +# Stray break + +--error 1 +--exec echo "break;" | $MYSQL_TEST 2>&1