From a56616f3014942e2671bc9d7384313fa3e097909 Mon Sep 17 00:00:00 2001 From: Geng Tian Date: Wed, 28 Jan 2026 20:06:23 +0000 Subject: [PATCH] MDEV-38454 CHANGE MASTER TO master_heartbeat_period does not accept numbers with `+` sign Fixed parser inconsistency where CHANGE MASTER TO master_heartbeat_period rejected numeric values with an explicit '+' sign, while other parameters like master_connect_retry accepted them. The issue was in sql/sql_yacc.yy where master_heartbeat_period used NUM_literal (which doesn't accept '+'), while other parameters used ulong_num (which includes opt_plus). Solution: Added opt_plus before NUM_literal in the master_heartbeat_period grammar rule, making it consistent with other numeric parameters. Added test case to verify: - master_heartbeat_period=+60 now works (was broken) - master_heartbeat_period=60 still works (backward compatible) All new code of the whole pull request, including one or several files that are either new files or modified ones, are contributed under the BSD-new license. I am contributing on behalf of my employer Amazon Web Services, Inc. --- .../suite/rpl/r/rpl_heartbeat_basic.result | 12 ++++++++++++ mysql-test/suite/rpl/t/rpl_heartbeat_basic.test | 16 ++++++++++++++++ sql/sql_yacc.yy | 4 ++-- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_heartbeat_basic.result b/mysql-test/suite/rpl/r/rpl_heartbeat_basic.result index a9bd16cc85ad2..ee4cfd4129071 100644 --- a/mysql-test/suite/rpl/r/rpl_heartbeat_basic.result +++ b/mysql-test/suite/rpl/r/rpl_heartbeat_basic.result @@ -182,6 +182,18 @@ CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER=' ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '''' at line 1 RESET SLAVE; +*** MDEV-38454: MASTER_HEARTBEAT_PERIOD should accept + sign *** +CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_CONNECT_RETRY=20, MASTER_HEARTBEAT_PERIOD=+60; +SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period'; +Variable_name Value +Slave_heartbeat_period 60.000 +RESET SLAVE; +CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_CONNECT_RETRY=20, MASTER_HEARTBEAT_PERIOD=60; +SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period'; +Variable_name Value +Slave_heartbeat_period 60.000 +RESET SLAVE; + *** Running slave *** CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_CONNECT_RETRY=20, MASTER_HEARTBEAT_PERIOD=0.1; include/start_slave.inc diff --git a/mysql-test/suite/rpl/t/rpl_heartbeat_basic.test b/mysql-test/suite/rpl/t/rpl_heartbeat_basic.test index fb67ad770d57a..3cfcbf5ed2864 100644 --- a/mysql-test/suite/rpl/t/rpl_heartbeat_basic.test +++ b/mysql-test/suite/rpl/t/rpl_heartbeat_basic.test @@ -238,6 +238,22 @@ eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTE RESET SLAVE; --echo +# +# MDEV-38454: MASTER_HEARTBEAT_PERIOD should accept values with + sign +# +--echo *** MDEV-38454: MASTER_HEARTBEAT_PERIOD should accept + sign *** +# Test with + sign (was broken before fix) +--replace_result $MASTER_MYPORT MASTER_PORT +eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=+60; +SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period'; +RESET SLAVE; +# Test without + sign (should still work) +--replace_result $MASTER_MYPORT MASTER_PORT +eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=60; +SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period'; +RESET SLAVE; +--echo + # # Testing heartbeat # diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 9d2d6a8f4a395..67eaa221b8ac2 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2265,9 +2265,9 @@ master_def: Lex->mi.ssl_crlpath= $3.str; } - | MASTER_HEARTBEAT_PERIOD_SYM '=' NUM_literal + | MASTER_HEARTBEAT_PERIOD_SYM '=' opt_plus NUM_literal { - Lex->mi.heartbeat_period= (float) $3->val_real(); + Lex->mi.heartbeat_period= (float) $4->val_real(); if (unlikely(Lex->mi.heartbeat_period > SLAVE_MAX_HEARTBEAT_PERIOD) || unlikely(Lex->mi.heartbeat_period < 0.0))