From 0fe3d6d56371b2b8ae5e92e80270a112d9bf4910 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 26 Feb 2020 12:33:16 +0100 Subject: [PATCH 1/3] all status variables above `questions` MUST be ulong see e.g. `add_to_status()` --- sql/mysqld.cc | 6 +++--- sql/sql_class.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 9a6aa2676d7..4580da89f16 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -8415,9 +8415,9 @@ SHOW_VAR status_vars[]= { {"Key", (char*) &show_default_keycache, SHOW_FUNC}, {"Last_query_cost", (char*) offsetof(STATUS_VAR, last_query_cost), SHOW_DOUBLE_STATUS}, {"Max_statement_time_exceeded", (char*) offsetof(STATUS_VAR, max_statement_time_exceeded), SHOW_LONG_STATUS}, - {"Master_gtid_wait_count", (char*) offsetof(STATUS_VAR, master_gtid_wait_count), SHOW_LONGLONG_STATUS}, - {"Master_gtid_wait_timeouts", (char*) offsetof(STATUS_VAR, master_gtid_wait_timeouts), SHOW_LONGLONG_STATUS}, - {"Master_gtid_wait_time", (char*) offsetof(STATUS_VAR, master_gtid_wait_time), SHOW_LONGLONG_STATUS}, + {"Master_gtid_wait_count", (char*) offsetof(STATUS_VAR, master_gtid_wait_count), SHOW_LONG_STATUS}, + {"Master_gtid_wait_timeouts", (char*) offsetof(STATUS_VAR, master_gtid_wait_timeouts), SHOW_LONG_STATUS}, + {"Master_gtid_wait_time", (char*) offsetof(STATUS_VAR, master_gtid_wait_time), SHOW_LONG_STATUS}, {"Max_used_connections", (char*) &max_used_connections, SHOW_LONG}, {"Memory_used", (char*) &show_memory_used, SHOW_SIMPLE_FUNC}, {"Not_flushed_delayed_rows", (char*) &delayed_rows_in_use, SHOW_LONG_NOFLUSH}, diff --git a/sql/sql_class.h b/sql/sql_class.h index edd02c9c932..9071a2db516 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -781,9 +781,9 @@ typedef struct system_status_var ulong feature_xml; /* +1 when XPATH is used */ /* From MASTER_GTID_WAIT usage */ - ulonglong master_gtid_wait_timeouts; /* Number of timeouts */ - ulonglong master_gtid_wait_time; /* Time in microseconds */ - ulonglong master_gtid_wait_count; + ulong master_gtid_wait_timeouts; /* Number of timeouts */ + ulong master_gtid_wait_time; /* Time in microseconds */ + ulong master_gtid_wait_count; ulong empty_queries; ulong access_denied_errors; From 5c1ed707a3d03a081fde2b2c960998d797757adf Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 26 Feb 2020 19:39:26 +0100 Subject: [PATCH 2/3] mtr: update heuristics for --parallel=auto to work better for CPUs with more than 2000 bogomips. old behavior is preserved if less than 2500 bogomips. --- mysql-test/mysql-test-run.pl | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 07cd4fa5392..cb7e6666800 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -441,11 +441,8 @@ sub main { if ( $opt_parallel eq "auto" ) { # Try to find a suitable value for number of workers my $sys_info= My::SysInfo->new(); + $opt_parallel= $sys_info->num_cpus() + int($sys_info->min_bogomips()/500)-4; - $opt_parallel= $sys_info->num_cpus(); - for my $limit (2000, 1500, 1000, 500){ - $opt_parallel-- if ($sys_info->min_bogomips() < $limit); - } my $max_par= $ENV{MTR_MAX_PARALLEL} || 8; $opt_parallel= $max_par if ($opt_parallel > $max_par); $opt_parallel= $num_tests if ($opt_parallel > $num_tests); From 328edf8560dbf1941ce314fa112e0db05d9f97f1 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Fri, 20 Mar 2020 15:24:06 +0400 Subject: [PATCH 3/3] MDEV-21977 main.func_math fails due to undefined behaviour The problem happened in these line: uval0= (ulonglong) (val0_negative ? -val0 : val0); uval1= (ulonglong) (val1_negative ? -val1 : val1); return check_integer_overflow(val0_negative ? -(longlong) res : res, !val0_negative); when unary minus was performed on -9223372036854775808. This behavior is undefined in C/C++. --- mysql-test/r/func_math.result | 48 +++++++++++++++++++++++++++++++++++ mysql-test/t/func_math.test | 29 +++++++++++++++++++++ sql/item_func.cc | 33 ++++++++---------------- sql/sql_type_int.h | 20 +++++++++++++++ 4 files changed, 107 insertions(+), 23 deletions(-) diff --git a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result index 008590aa5d8..c92549ae45e 100644 --- a/mysql-test/r/func_math.result +++ b/mysql-test/r/func_math.result @@ -946,5 +946,53 @@ STDDEV_SAMP(a) NULL DROP TABLE t1; # +# MDEV-21977 main.func_math fails due to undefined behaviour +# +SELECT 9223372036854775808 DIV 1; +9223372036854775808 DIV 1 +9223372036854775808 +SELECT 9223372036854775808 DIV -1; +ERROR 22003: BIGINT UNSIGNED value is out of range in '(9223372036854775808 DIV -(1))' +SELECT -9223372036854775808 DIV 1; +ERROR 22003: BIGINT value is out of range in '(-(9223372036854775808) DIV 1)' +SELECT -9223372036854775808 DIV -1; +ERROR 22003: BIGINT value is out of range in '(-(9223372036854775808) DIV -(1))' +SELECT 9223372036854775808 MOD 1; +9223372036854775808 MOD 1 +0 +SELECT 9223372036854775808 MOD -1; +9223372036854775808 MOD -1 +0 +SELECT -9223372036854775808 MOD 1; +-9223372036854775808 MOD 1 +0 +SELECT -9223372036854775808 MOD -1; +-9223372036854775808 MOD -1 +0 +SELECT 1 MOD 9223372036854775808; +1 MOD 9223372036854775808 +1 +SELECT -1 MOD 9223372036854775808; +-1 MOD 9223372036854775808 +-1 +SELECT 1 MOD -9223372036854775808; +1 MOD -9223372036854775808 +1 +SELECT -1 MOD -9223372036854775808; +-1 MOD -9223372036854775808 +-1 +SELECT 9223372036854775808 MOD 9223372036854775808; +9223372036854775808 MOD 9223372036854775808 +0 +SELECT 9223372036854775808 MOD -9223372036854775808; +9223372036854775808 MOD -9223372036854775808 +0 +SELECT -9223372036854775808 MOD 9223372036854775808; +-9223372036854775808 MOD 9223372036854775808 +0 +SELECT -9223372036854775808 MOD -9223372036854775808; +-9223372036854775808 MOD -9223372036854775808 +0 +# # End of 10.1 tests # diff --git a/mysql-test/t/func_math.test b/mysql-test/t/func_math.test index ebce8a8480c..89e9c4f4d49 100644 --- a/mysql-test/t/func_math.test +++ b/mysql-test/t/func_math.test @@ -692,6 +692,35 @@ SELECT STDDEV_SAMP(a) FROM t1; DROP TABLE t1; +--echo # +--echo # MDEV-21977 main.func_math fails due to undefined behaviour +--echo # + +SELECT 9223372036854775808 DIV 1; +--error ER_DATA_OUT_OF_RANGE +SELECT 9223372036854775808 DIV -1; +--error ER_DATA_OUT_OF_RANGE +SELECT -9223372036854775808 DIV 1; +--error ER_DATA_OUT_OF_RANGE +SELECT -9223372036854775808 DIV -1; + +SELECT 9223372036854775808 MOD 1; +SELECT 9223372036854775808 MOD -1; +SELECT -9223372036854775808 MOD 1; +SELECT -9223372036854775808 MOD -1; + +SELECT 1 MOD 9223372036854775808; +SELECT -1 MOD 9223372036854775808; +SELECT 1 MOD -9223372036854775808; +SELECT -1 MOD -9223372036854775808; + +SELECT 9223372036854775808 MOD 9223372036854775808; +SELECT 9223372036854775808 MOD -9223372036854775808; +SELECT -9223372036854775808 MOD 9223372036854775808; +SELECT -9223372036854775808 MOD -9223372036854775808; + + + --echo # --echo # End of 10.1 tests --echo # diff --git a/sql/item_func.cc b/sql/item_func.cc index ffd2b462431..302ec58a708 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1834,11 +1834,9 @@ longlong Item_func_int_div::val_int() raise_integer_overflow(); return res; } - - longlong val0=args[0]->val_int(); - longlong val1=args[1]->val_int(); - bool val0_negative, val1_negative, res_negative; - ulonglong uval0, uval1, res; + + Longlong_hybrid val0= args[0]->to_longlong_hybrid(); + Longlong_hybrid val1= args[1]->to_longlong_hybrid(); if ((null_value= (args[0]->null_value || args[1]->null_value))) return 0; if (val1 == 0) @@ -1847,12 +1845,8 @@ longlong Item_func_int_div::val_int() return 0; } - val0_negative= !args[0]->unsigned_flag && val0 < 0; - val1_negative= !args[1]->unsigned_flag && val1 < 0; - res_negative= val0_negative != val1_negative; - uval0= (ulonglong) (val0_negative ? -val0 : val0); - uval1= (ulonglong) (val1_negative ? -val1 : val1); - res= uval0 / uval1; + bool res_negative= val0.neg() != val1.neg(); + ulonglong res= val0.abs() / val1.abs(); if (res_negative) { if (res > (ulonglong) LONGLONG_MAX) @@ -1880,11 +1874,8 @@ void Item_func_int_div::fix_length_and_dec() longlong Item_func_mod::int_op() { DBUG_ASSERT(fixed == 1); - longlong val0= args[0]->val_int(); - longlong val1= args[1]->val_int(); - bool val0_negative, val1_negative; - ulonglong uval0, uval1; - ulonglong res; + Longlong_hybrid val0= args[0]->to_longlong_hybrid(); + Longlong_hybrid val1= args[1]->to_longlong_hybrid(); if ((null_value= args[0]->null_value || args[1]->null_value)) return 0; /* purecov: inspected */ @@ -1899,13 +1890,9 @@ longlong Item_func_mod::int_op() LONGLONG_MIN by -1 generates SIGFPE, we calculate using unsigned values and then adjust the sign appropriately. */ - val0_negative= !args[0]->unsigned_flag && val0 < 0; - val1_negative= !args[1]->unsigned_flag && val1 < 0; - uval0= (ulonglong) (val0_negative ? -val0 : val0); - uval1= (ulonglong) (val1_negative ? -val1 : val1); - res= uval0 % uval1; - return check_integer_overflow(val0_negative ? -(longlong) res : res, - !val0_negative); + ulonglong res= val0.abs() % val1.abs(); + return check_integer_overflow(val0.neg() ? -(longlong) res : res, + !val0.neg()); } double Item_func_mod::real_op() diff --git a/sql/sql_type_int.h b/sql/sql_type_int.h index 74e59b08385..5988a985a2d 100644 --- a/sql/sql_type_int.h +++ b/sql/sql_type_int.h @@ -67,6 +67,26 @@ public: */ return cmp_signed(other); } + bool operator==(const Longlong_hybrid &nr) const + { + return cmp(nr) == 0; + } + bool operator==(ulonglong nr) const + { + return cmp(Longlong_hybrid((longlong) nr, true)) == 0; + } + bool operator==(uint nr) const + { + return cmp(Longlong_hybrid((longlong) nr, true)) == 0; + } + bool operator==(longlong nr) const + { + return cmp(Longlong_hybrid(nr, false)) == 0; + } + bool operator==(int nr) const + { + return cmp(Longlong_hybrid(nr, false)) == 0; + } }; #endif // SQL_TYPE_INT_INCLUDED