summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-03-20 15:37:08 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2020-03-20 15:51:30 +0200
commitc9ec1cc751df936d3359e0705f4341a814b2b4fa (patch)
treee1ed643823118af2d254a23878932c8f1e9965b8
parenta66eebf57c212363f9f430a4c8c9a4f3ddf57cfb (diff)
parent328edf8560dbf1941ce314fa112e0db05d9f97f1 (diff)
downloadmariadb-git-c9ec1cc751df936d3359e0705f4341a814b2b4fa.tar.gz
Merge 10.1 into 10.2
-rwxr-xr-xmysql-test/mysql-test-run.pl5
-rw-r--r--mysql-test/r/func_math.result48
-rw-r--r--mysql-test/t/func_math.test29
-rw-r--r--sql/item_func.cc33
-rw-r--r--sql/mysqld.cc6
-rw-r--r--sql/sql_class.h6
-rw-r--r--sql/sql_type_int.h20
7 files changed, 116 insertions, 31 deletions
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index ec6af7c1171..5cf41b65461 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -2,7 +2,7 @@
# -*- cperl -*-
# Copyright (c) 2004, 2014, Oracle and/or its affiliates.
-# Copyright (c) 2009, 2018, MariaDB Corporation
+# Copyright (c) 2009, 2020, MariaDB Corporation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -614,7 +614,8 @@ sub main {
else
{
my $sys_info= My::SysInfo->new();
- $opt_parallel= $sys_info->num_cpus();
+ $opt_parallel= $sys_info->num_cpus() +
+ int($sys_info->min_bogomips()/500) - 4;
for my $limit (2000, 1500, 1000, 500){
$opt_parallel-- if ($sys_info->min_bogomips() < $limit);
}
diff --git a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result
index 66ee73de88e..22c68ad7309 100644
--- a/mysql-test/r/func_math.result
+++ b/mysql-test/r/func_math.result
@@ -967,6 +967,54 @@ 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 04fee6fb66b..0a406d56a9d 100644
--- a/mysql-test/t/func_math.test
+++ b/mysql-test/t/func_math.test
@@ -689,6 +689,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 825af76ef15..5a4c7aeab3e 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -1817,11 +1817,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)
@@ -1830,12 +1828,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)
@@ -1864,11 +1858,8 @@ bool 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 */
@@ -1883,13 +1874,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/mysqld.cc b/sql/mysqld.cc
index 128dd19cbfc..83e93110ad1 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -8525,9 +8525,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 b35f9a93238..111c407f117 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -811,9 +811,9 @@ typedef struct system_status_var
ulong feature_window_functions; /* +1 when window functions are 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;
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