diff options
-rw-r--r-- | mysql-test/r/func_time.result | 158 | ||||
-rw-r--r-- | mysql-test/r/grant.result | 29 | ||||
-rw-r--r-- | mysql-test/r/sp-security.result | 21 | ||||
-rw-r--r-- | mysql-test/r/type_float.result | 36 | ||||
-rw-r--r-- | mysql-test/suite/parts/r/update_and_cache.result | 7 | ||||
-rw-r--r-- | mysql-test/suite/parts/t/update_and_cache.test | 12 | ||||
-rw-r--r-- | mysql-test/t/func_time.test | 49 | ||||
-rw-r--r-- | mysql-test/t/grant.test | 22 | ||||
-rw-r--r-- | mysql-test/t/sp-security.test | 20 | ||||
-rw-r--r-- | mysql-test/t/type_float.test | 30 | ||||
-rw-r--r-- | sql/field.cc | 3 | ||||
-rw-r--r-- | sql/item.cc | 183 | ||||
-rw-r--r-- | sql/item.h | 90 | ||||
-rw-r--r-- | sql/item_func.cc | 5 | ||||
-rw-r--r-- | sql/item_func.h | 10 | ||||
-rw-r--r-- | sql/item_sum.cc | 6 | ||||
-rw-r--r-- | sql/item_sum.h | 19 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 29 | ||||
-rw-r--r-- | sql/sql_acl.cc | 5 | ||||
-rw-r--r-- | sql/sql_delete.cc | 1 | ||||
-rw-r--r-- | sql/sql_error.h | 7 | ||||
-rw-r--r-- | sql/sql_type_int.h | 40 | ||||
-rw-r--r-- | sql/sql_update.cc | 2 |
23 files changed, 479 insertions, 305 deletions
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index 6f81ffbd410..d4b289f1d80 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -2774,6 +2774,164 @@ SELECT PERIOD_DIFF(2018, AES_ENCRYPT('Rae Bareli', 'Rae Bareli')); PERIOD_DIFF(2018, AES_ENCRYPT('Rae Bareli', 'Rae Bareli')) 24257 # +# MDEV-17249 MAKETIME(-1e50,0,0) returns a wrong result +# +SELECT +MAKETIME(1e10,0,0), +MAKETIME(-1e10,0,0), +MAKETIME(1e50,0,0), +MAKETIME(-1e50,0,0), +MAKETIME(COALESCE(1e50),0,0), +MAKETIME(COALESCE(-1e50),0,0); +MAKETIME(1e10,0,0) 838:59:59 +MAKETIME(-1e10,0,0) -838:59:59 +MAKETIME(1e50,0,0) 838:59:59 +MAKETIME(-1e50,0,0) -838:59:59 +MAKETIME(COALESCE(1e50),0,0) 838:59:59 +MAKETIME(COALESCE(-1e50),0,0) -838:59:59 +Warnings: +Level Warning +Code 1292 +Message Truncated incorrect time value: '10000000000:00:00' +Level Warning +Code 1292 +Message Truncated incorrect time value: '-10000000000:00:00' +Level Warning +Code 1292 +Message Truncated incorrect time value: '9223372036854775807:00:00' +Level Warning +Code 1292 +Message Truncated incorrect time value: '-9223372036854775808:00:00' +Level Warning +Code 1292 +Message Truncated incorrect time value: '9223372036854775807:00:00' +Level Warning +Code 1292 +Message Truncated incorrect time value: '-9223372036854775808:00:00' +CREATE TABLE t1 (a FLOAT); +INSERT INTO t1 VALUES (1e30),(-1e30); +SELECT MAKETIME(a,0,0) FROM t1; +MAKETIME(a,0,0) +838:59:59 +-838:59:59 +Warnings: +Warning 1292 Truncated incorrect time value: '9223372036854775807:00:00' +Warning 1292 Truncated incorrect time value: '-9223372036854775808:00:00' +DROP TABLE t1; +# +# MDEV-17244 MAKETIME(900,0,0.111) returns a wrong result +# +SELECT MAKETIME(900,0,0); +MAKETIME(900,0,0) +838:59:59 +Warnings: +Warning 1292 Truncated incorrect time value: '900:00:00' +SELECT MAKETIME(900,0,0.1); +MAKETIME(900,0,0.1) +838:59:59.9 +Warnings: +Warning 1292 Truncated incorrect time value: '900:00:00' +SELECT MAKETIME(900,0,0.11); +MAKETIME(900,0,0.11) +838:59:59.99 +Warnings: +Warning 1292 Truncated incorrect time value: '900:00:00' +SELECT MAKETIME(900,0,0.111); +MAKETIME(900,0,0.111) +838:59:59.999 +Warnings: +Warning 1292 Truncated incorrect time value: '900:00:00' +SELECT MAKETIME(900,0,0.1111); +MAKETIME(900,0,0.1111) +838:59:59.9999 +Warnings: +Warning 1292 Truncated incorrect time value: '900:00:00' +SELECT MAKETIME(900,0,0.11111); +MAKETIME(900,0,0.11111) +838:59:59.99999 +Warnings: +Warning 1292 Truncated incorrect time value: '900:00:00' +SELECT MAKETIME(900,0,0.111111); +MAKETIME(900,0,0.111111) +838:59:59.999999 +Warnings: +Warning 1292 Truncated incorrect time value: '900:00:00' +SELECT MAKETIME(900,0,0.1111111); +MAKETIME(900,0,0.1111111) +838:59:59.999999 +Warnings: +Warning 1292 Truncated incorrect time value: '900:00:00' +SELECT MAKETIME(900,0,0.11111111); +MAKETIME(900,0,0.11111111) +838:59:59.999999 +Warnings: +Warning 1292 Truncated incorrect time value: '900:00:00' +SELECT MAKETIME(900,0,0.111111111); +MAKETIME(900,0,0.111111111) +838:59:59.999999 +Warnings: +Warning 1292 Truncated incorrect time value: '900:00:00' +SELECT MAKETIME(900,0,EXP(1)); +MAKETIME(900,0,EXP(1)) +838:59:59.999999 +Warnings: +Warning 1292 Truncated incorrect time value: '900:00:02' +SELECT MAKETIME(-900,0,0); +MAKETIME(-900,0,0) +-838:59:59 +Warnings: +Warning 1292 Truncated incorrect time value: '-900:00:00' +SELECT MAKETIME(-900,0,0.1); +MAKETIME(-900,0,0.1) +-838:59:59.9 +Warnings: +Warning 1292 Truncated incorrect time value: '-900:00:00' +SELECT MAKETIME(-900,0,0.11); +MAKETIME(-900,0,0.11) +-838:59:59.99 +Warnings: +Warning 1292 Truncated incorrect time value: '-900:00:00' +SELECT MAKETIME(-900,0,0.111); +MAKETIME(-900,0,0.111) +-838:59:59.999 +Warnings: +Warning 1292 Truncated incorrect time value: '-900:00:00' +SELECT MAKETIME(-900,0,0.1111); +MAKETIME(-900,0,0.1111) +-838:59:59.9999 +Warnings: +Warning 1292 Truncated incorrect time value: '-900:00:00' +SELECT MAKETIME(-900,0,0.11111); +MAKETIME(-900,0,0.11111) +-838:59:59.99999 +Warnings: +Warning 1292 Truncated incorrect time value: '-900:00:00' +SELECT MAKETIME(-900,0,0.111111); +MAKETIME(-900,0,0.111111) +-838:59:59.999999 +Warnings: +Warning 1292 Truncated incorrect time value: '-900:00:00' +SELECT MAKETIME(-900,0,0.1111111); +MAKETIME(-900,0,0.1111111) +-838:59:59.999999 +Warnings: +Warning 1292 Truncated incorrect time value: '-900:00:00' +SELECT MAKETIME(-900,0,0.11111111); +MAKETIME(-900,0,0.11111111) +-838:59:59.999999 +Warnings: +Warning 1292 Truncated incorrect time value: '-900:00:00' +SELECT MAKETIME(-900,0,0.111111111); +MAKETIME(-900,0,0.111111111) +-838:59:59.999999 +Warnings: +Warning 1292 Truncated incorrect time value: '-900:00:00' +SELECT MAKETIME(-900,0,EXP(1)); +MAKETIME(-900,0,EXP(1)) +-838:59:59.999999 +Warnings: +Warning 1292 Truncated incorrect time value: '-900:00:02' +# # End of 5.5 tests # # diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index c3a1db86c37..cfd442d58c8 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -2569,6 +2569,35 @@ foo@localhost foo@127.0.0.1 # Clean-up DROP USER foo@'127.0.0.1'; # End of Bug#12766319 +create user foo@localhost; +create database foodb; +grant create routine on foodb.* to foo@localhost; +create procedure fooproc() select 'i am fooproc'; +show grants; +Grants for foo@localhost +GRANT USAGE ON *.* TO 'foo'@'localhost' +GRANT CREATE ROUTINE ON `foodb`.* TO 'foo'@'localhost' +GRANT EXECUTE, ALTER ROUTINE ON PROCEDURE `test`.`fooproc` TO 'foo'@'localhost' +rename table mysql.procs_priv to mysql.procs_priv1; +flush privileges; +show grants for foo@localhost; +Grants for foo@localhost +GRANT USAGE ON *.* TO 'foo'@'localhost' +GRANT CREATE ROUTINE ON `foodb`.* TO 'foo'@'localhost' +rename table mysql.procs_priv1 to mysql.procs_priv; +show grants for foo@localhost; +Grants for foo@localhost +GRANT USAGE ON *.* TO 'foo'@'localhost' +GRANT CREATE ROUTINE ON `foodb`.* TO 'foo'@'localhost' +flush privileges; +show grants for foo@localhost; +Grants for foo@localhost +GRANT USAGE ON *.* TO 'foo'@'localhost' +GRANT CREATE ROUTINE ON `foodb`.* TO 'foo'@'localhost' +GRANT EXECUTE, ALTER ROUTINE ON PROCEDURE `test`.`fooproc` TO 'foo'@'localhost' +drop user foo@localhost; +drop procedure fooproc; +drop database foodb; # # Bug#11756966 - 48958: STORED PROCEDURES CAN BE LEVERAGED TO BYPASS # DATABASE SECURITY diff --git a/mysql-test/r/sp-security.result b/mysql-test/r/sp-security.result index e8c3fbff0e3..a4e3505cf0f 100644 --- a/mysql-test/r/sp-security.result +++ b/mysql-test/r/sp-security.result @@ -617,6 +617,27 @@ SELECT 1 latin1 latin1_swedish_ci latin1_swedish_ci # Connection default DROP USER user2@localhost; DROP DATABASE db1; +create user foo@local_ost; +create user foo@`local\_ost` identified by 'nevermore'; +create database foodb; +grant create routine on foodb.* to foo@local_ost; +select user(), current_user(); +user() current_user() +foo@localhost foo@local_ost +show grants; +Grants for foo@local_ost +GRANT USAGE ON *.* TO 'foo'@'local_ost' +GRANT CREATE ROUTINE ON `foodb`.* TO 'foo'@'local_ost' +create procedure fooproc() select 'i am fooproc'; +show grants; +Grants for foo@local_ost +GRANT USAGE ON *.* TO 'foo'@'local_ost' +GRANT CREATE ROUTINE ON `foodb`.* TO 'foo'@'local_ost' +GRANT EXECUTE, ALTER ROUTINE ON PROCEDURE `test`.`fooproc` TO 'foo'@'local_ost' +drop user foo@local_ost; +drop user foo@`local\_ost`; +drop procedure fooproc; +drop database foodb; # # Test for bug#12602983 - User without privilege on routine can discover # its existence by executing "select non_existing_func();" or by diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result index 57e2660750b..f71d4c13a0d 100644 --- a/mysql-test/r/type_float.result +++ b/mysql-test/r/type_float.result @@ -448,6 +448,42 @@ select format(truncate('1.7976931348623157E+308',-12),1,'fr_BE') as foo; foo 0 # +# MDEV-17249 MAKETIME(-1e50,0,0) returns a wrong result +# +SELECT LEFT('a',EXP(50)); +LEFT('a',EXP(50)) +a +SELECT LEFT('a', COALESCE(1e30)); +LEFT('a', COALESCE(1e30)) +a +CREATE TABLE t1 (a FLOAT); +INSERT INTO t1 VALUES (1e30); +SELECT LEFT('a',a), LEFT('a',1e30) FROM t1; +LEFT('a',a) LEFT('a',1e30) +a a +DROP TABLE t1; +PREPARE stmt FROM 'SELECT LEFT(111,?)'; +SET @a=1e30; +EXECUTE stmt USING @a; +LEFT(111,?) +111 +DEALLOCATE PREPARE stmt; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2),(3); +SELECT LEFT('a',(SELECT 1e30 FROM t1 LIMIT 1)); +LEFT('a',(SELECT 1e30 FROM t1 LIMIT 1)) +a +DROP TABLE t1; +CREATE TABLE t1 (a DOUBLE); +INSERT INTO t1 VALUES (1e30),(0); +SELECT LEFT('a', SUM(a)) FROM t1; +LEFT('a', SUM(a)) +a +SELECT LEFT('a', AVG(a)) FROM t1; +LEFT('a', AVG(a)) +a +DROP TABLE t1; +# # Bug #13500371 63704: CONVERSION OF '1.' TO A NUMBER GIVES ERROR 1265 # (WARN_DATA_TRUNCATED) # diff --git a/mysql-test/suite/parts/r/update_and_cache.result b/mysql-test/suite/parts/r/update_and_cache.result new file mode 100644 index 00000000000..52f13e66702 --- /dev/null +++ b/mysql-test/suite/parts/r/update_and_cache.result @@ -0,0 +1,7 @@ +CREATE TABLE t1 (pk INT PRIMARY KEY, a INT); +INSERT INTO t1 VALUES (1,10),(2,20); +CREATE TABLE t2 (b INT) PARTITION BY KEY (b) PARTITIONS 2; +INSERT INTO t2 VALUES (1),(2); +DELETE t2 FROM t2 WHERE b BETWEEN 5 AND 9; +UPDATE t2 JOIN t1 SET b = 5; +DROP TABLE t1, t2; diff --git a/mysql-test/suite/parts/t/update_and_cache.test b/mysql-test/suite/parts/t/update_and_cache.test new file mode 100644 index 00000000000..08ade807422 --- /dev/null +++ b/mysql-test/suite/parts/t/update_and_cache.test @@ -0,0 +1,12 @@ +--source include/have_partition.inc + +CREATE TABLE t1 (pk INT PRIMARY KEY, a INT); +INSERT INTO t1 VALUES (1,10),(2,20); + +CREATE TABLE t2 (b INT) PARTITION BY KEY (b) PARTITIONS 2; +INSERT INTO t2 VALUES (1),(2); + +DELETE t2 FROM t2 WHERE b BETWEEN 5 AND 9; +UPDATE t2 JOIN t1 SET b = 5; + +DROP TABLE t1, t2; diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index 949e5cada2a..cb8f35c3627 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -1702,6 +1702,55 @@ SELECT SEC_TO_TIME(MAKEDATE(0,RAND(~0))); # SELECT PERIOD_DIFF(2018, AES_ENCRYPT('Rae Bareli', 'Rae Bareli')); + +--echo # +--echo # MDEV-17249 MAKETIME(-1e50,0,0) returns a wrong result +--echo # + +--vertical_results +SELECT + MAKETIME(1e10,0,0), + MAKETIME(-1e10,0,0), + MAKETIME(1e50,0,0), + MAKETIME(-1e50,0,0), + MAKETIME(COALESCE(1e50),0,0), + MAKETIME(COALESCE(-1e50),0,0); +--horizontal_results + +CREATE TABLE t1 (a FLOAT); +INSERT INTO t1 VALUES (1e30),(-1e30); +SELECT MAKETIME(a,0,0) FROM t1; +DROP TABLE t1; + +--echo # +--echo # MDEV-17244 MAKETIME(900,0,0.111) returns a wrong result +--echo # + +SELECT MAKETIME(900,0,0); +SELECT MAKETIME(900,0,0.1); +SELECT MAKETIME(900,0,0.11); +SELECT MAKETIME(900,0,0.111); +SELECT MAKETIME(900,0,0.1111); +SELECT MAKETIME(900,0,0.11111); +SELECT MAKETIME(900,0,0.111111); +SELECT MAKETIME(900,0,0.1111111); +SELECT MAKETIME(900,0,0.11111111); +SELECT MAKETIME(900,0,0.111111111); +SELECT MAKETIME(900,0,EXP(1)); + +SELECT MAKETIME(-900,0,0); +SELECT MAKETIME(-900,0,0.1); +SELECT MAKETIME(-900,0,0.11); +SELECT MAKETIME(-900,0,0.111); +SELECT MAKETIME(-900,0,0.1111); +SELECT MAKETIME(-900,0,0.11111); +SELECT MAKETIME(-900,0,0.111111); +SELECT MAKETIME(-900,0,0.1111111); +SELECT MAKETIME(-900,0,0.11111111); +SELECT MAKETIME(-900,0,0.111111111); +SELECT MAKETIME(-900,0,EXP(1)); + + --echo # --echo # End of 5.5 tests --echo # diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index 156a55e0466..f2dfb01cc39 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -2232,6 +2232,28 @@ DROP USER foo@'127.0.0.1'; --echo # End of Bug#12766319 +# +# Bug#27230925: HANDLE_FATAL_SIGNAL (SIG=11) IN SHOW_ROUTINE_GRANTS +# +create user foo@localhost; +create database foodb; +grant create routine on foodb.* to foo@localhost; +connect con1,localhost,foo; +create procedure fooproc() select 'i am fooproc'; +show grants; +disconnect con1; +connection default; +rename table mysql.procs_priv to mysql.procs_priv1; +flush privileges; +show grants for foo@localhost; +rename table mysql.procs_priv1 to mysql.procs_priv; +show grants for foo@localhost; +flush privileges; +show grants for foo@localhost; +drop user foo@localhost; +drop procedure fooproc; +drop database foodb; + --echo # --echo # Bug#11756966 - 48958: STORED PROCEDURES CAN BE LEVERAGED TO BYPASS diff --git a/mysql-test/t/sp-security.test b/mysql-test/t/sp-security.test index a2079e91440..0f9243f30bb 100644 --- a/mysql-test/t/sp-security.test +++ b/mysql-test/t/sp-security.test @@ -995,6 +995,25 @@ disconnect con2; DROP USER user2@localhost; DROP DATABASE db1; +# +# Bug#27407480: AUTOMATIC_SP_PRIVILEGES REQUIRES NEED THE INSERT PRIVILEGES FOR MYSQL.USER TABLE +# +create user foo@local_ost; +create user foo@`local\_ost` identified by 'nevermore'; +create database foodb; +grant create routine on foodb.* to foo@local_ost; +connect con1,localhost,foo; +select user(), current_user(); +show grants; +create procedure fooproc() select 'i am fooproc'; +show grants; +disconnect con1; +connection default; +drop user foo@local_ost; +drop user foo@`local\_ost`; +drop procedure fooproc; +drop database foodb; + --echo # --echo # Test for bug#12602983 - User without privilege on routine can discover --echo # its existence by executing "select non_existing_func();" or by @@ -1039,4 +1058,3 @@ drop database mysqltest_db; # Wait till all disconnects are completed --source include/wait_until_count_sessions.inc - diff --git a/mysql-test/t/type_float.test b/mysql-test/t/type_float.test index bb7a784553e..5dfb4a75bb3 100644 --- a/mysql-test/t/type_float.test +++ b/mysql-test/t/type_float.test @@ -332,6 +332,36 @@ eval select concat((truncate((-1.7976931348623157E+307),(0x1e))), select format(truncate('1.7976931348623157E+308',-12),1,'fr_BE') as foo; + +--echo # +--echo # MDEV-17249 MAKETIME(-1e50,0,0) returns a wrong result +--echo # + +SELECT LEFT('a',EXP(50)); +SELECT LEFT('a', COALESCE(1e30)); + +CREATE TABLE t1 (a FLOAT); +INSERT INTO t1 VALUES (1e30); +SELECT LEFT('a',a), LEFT('a',1e30) FROM t1; +DROP TABLE t1; + +PREPARE stmt FROM 'SELECT LEFT(111,?)'; +SET @a=1e30; +EXECUTE stmt USING @a; +DEALLOCATE PREPARE stmt; + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2),(3); +SELECT LEFT('a',(SELECT 1e30 FROM t1 LIMIT 1)); +DROP TABLE t1; + +CREATE TABLE t1 (a DOUBLE); +INSERT INTO t1 VALUES (1e30),(0); +SELECT LEFT('a', SUM(a)) FROM t1; +SELECT LEFT('a', AVG(a)) FROM t1; +DROP TABLE t1; + + --echo # --echo # Bug #13500371 63704: CONVERSION OF '1.' TO A NUMBER GIVES ERROR 1265 --echo # (WARN_DATA_TRUNCATED) diff --git a/sql/field.cc b/sql/field.cc index 1427e055324..2a3394be411 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4083,7 +4083,8 @@ longlong Field_float::val_int(void) { float j; float4get(j,ptr); - return (longlong) rint(j); + bool error; + return double_to_longlong(j, false, &error); } diff --git a/sql/item.cc b/sql/item.cc index 7f1ec42b029..adf0335b844 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -3667,7 +3667,10 @@ longlong Item_param::val_int() { switch (state) { case REAL_VALUE: - return (longlong) rint(value.real); + { + bool error; + return double_to_longlong(value.real, unsigned_flag, &error); + } case INT_VALUE: return value.integer; case DECIMAL_VALUE: @@ -4128,31 +4131,6 @@ void Item_param::make_field(Send_field *field) field->type= m_out_param_info->type; } -/**************************************************************************** - Item_copy -****************************************************************************/ - -Item_copy *Item_copy::create (Item *item) -{ - switch (item->result_type()) - { - case STRING_RESULT: - return new Item_copy_string (item); - case REAL_RESULT: - return new Item_copy_float (item); - case INT_RESULT: - return item->unsigned_flag ? - new Item_copy_uint (item) : new Item_copy_int (item); - case DECIMAL_RESULT: - return new Item_copy_decimal (item); - case TIME_RESULT: - case ROW_RESULT: - case IMPOSSIBLE_RESULT: - DBUG_ASSERT (0); - } - /* should not happen */ - return NULL; -} /**************************************************************************** Item_copy_string @@ -4210,156 +4188,6 @@ my_decimal *Item_copy_string::val_decimal(my_decimal *decimal_value) } -/**************************************************************************** - Item_copy_int -****************************************************************************/ - -void Item_copy_int::copy() -{ - cached_value= item->val_int(); - null_value=item->null_value; -} - -static int save_int_value_in_field (Field *, longlong, bool, bool); - -int Item_copy_int::save_in_field(Field *field, bool no_conversions) -{ - return save_int_value_in_field(field, cached_value, - null_value, unsigned_flag); -} - - -String *Item_copy_int::val_str(String *str) -{ - if (null_value) - return (String *) 0; - - str->set(cached_value, &my_charset_bin); - return str; -} - - -my_decimal *Item_copy_int::val_decimal(my_decimal *decimal_value) -{ - if (null_value) - return (my_decimal *) 0; - - int2my_decimal(E_DEC_FATAL_ERROR, cached_value, unsigned_flag, decimal_value); - return decimal_value; -} - - -/**************************************************************************** - Item_copy_uint -****************************************************************************/ - -String *Item_copy_uint::val_str(String *str) -{ - if (null_value) - return (String *) 0; - - str->set((ulonglong) cached_value, &my_charset_bin); - return str; -} - - -/**************************************************************************** - Item_copy_float -****************************************************************************/ - -String *Item_copy_float::val_str(String *str) -{ - if (null_value) - return (String *) 0; - else - { - double nr= val_real(); - str->set_real(nr,decimals, &my_charset_bin); - return str; - } -} - - -my_decimal *Item_copy_float::val_decimal(my_decimal *decimal_value) -{ - if (null_value) - return (my_decimal *) 0; - else - { - double nr= val_real(); - double2my_decimal(E_DEC_FATAL_ERROR, nr, decimal_value); - return decimal_value; - } -} - - -int Item_copy_float::save_in_field(Field *field, bool no_conversions) -{ - if (null_value) - return set_field_to_null(field); - field->set_notnull(); - return field->store(cached_value); -} - - -/**************************************************************************** - Item_copy_decimal -****************************************************************************/ - -int Item_copy_decimal::save_in_field(Field *field, bool no_conversions) -{ - if (null_value) - return set_field_to_null(field); - field->set_notnull(); - return field->store_decimal(&cached_value); -} - - -String *Item_copy_decimal::val_str(String *result) -{ - if (null_value) - return (String *) 0; - result->set_charset(&my_charset_bin); - my_decimal2string(E_DEC_FATAL_ERROR, &cached_value, 0, 0, 0, result); - return result; -} - - -double Item_copy_decimal::val_real() -{ - if (null_value) - return 0.0; - else - { - double result; - my_decimal2double(E_DEC_FATAL_ERROR, &cached_value, &result); - return result; - } -} - - -longlong Item_copy_decimal::val_int() -{ - if (null_value) - return 0; - else - { - longlong result; - my_decimal2int(E_DEC_FATAL_ERROR, &cached_value, unsigned_flag, &result); - return result; - } -} - - -void Item_copy_decimal::copy() -{ - my_decimal *nr= item->val_decimal(&cached_value); - if (nr && nr != &cached_value) - my_decimal2decimal (nr, &cached_value); - null_value= item->null_value; -} - - /* Functions to convert item to field (for send_result_set_metadata) */ @@ -9222,7 +9050,8 @@ longlong Item_cache_real::val_int() DBUG_ASSERT(fixed == 1); if (!has_value()) return 0; - return (longlong) rint(value); + bool error; + return double_to_longlong(value, unsigned_flag, &error); } diff --git a/sql/item.h b/sql/item.h index 7c95239b242..1d580280196 100644 --- a/sql/item.h +++ b/sql/item.h @@ -4083,13 +4083,6 @@ protected: } public: - /** - Factory method to create the appropriate subclass dependent on the type of - the original item. - - @param item the original item. - */ - static Item_copy *create (Item *item); /** Update the cache with the value of the original item @@ -4151,89 +4144,6 @@ public: }; -class Item_copy_int : public Item_copy -{ -protected: - longlong cached_value; -public: - Item_copy_int (Item *i) : Item_copy(i) {} - int save_in_field(Field *field, bool no_conversions); - - virtual String *val_str(String*); - virtual my_decimal *val_decimal(my_decimal *); - virtual double val_real() - { - return null_value ? 0.0 : (double) cached_value; - } - virtual longlong val_int() - { - return null_value ? 0 : cached_value; - } - virtual void copy(); -}; - - -class Item_copy_uint : public Item_copy_int -{ -public: - Item_copy_uint (Item *item) : Item_copy_int(item) - { - unsigned_flag= 1; - } - - String *val_str(String*); - double val_real() - { - return null_value ? 0.0 : (double) (ulonglong) cached_value; - } -}; - - -class Item_copy_float : public Item_copy -{ -protected: - double cached_value; -public: - Item_copy_float (Item *i) : Item_copy(i) {} - int save_in_field(Field *field, bool no_conversions); - - String *val_str(String*); - my_decimal *val_decimal(my_decimal *); - double val_real() - { - return null_value ? 0.0 : cached_value; - } - longlong val_int() - { - return (longlong) rint(val_real()); - } - void copy() - { - cached_value= item->val_real(); - null_value= item->null_value; - } -}; - - -class Item_copy_decimal : public Item_copy -{ -protected: - my_decimal cached_value; -public: - Item_copy_decimal (Item *i) : Item_copy(i) {} - int save_in_field(Field *field, bool no_conversions); - - String *val_str(String*); - my_decimal *val_decimal(my_decimal *) - { - return null_value ? NULL: &cached_value; - } - double val_real(); - longlong val_int(); - void copy(); -}; - - /* Cached_item_XXX objects are not exactly caches. They do the following: diff --git a/sql/item_func.cc b/sql/item_func.cc index dac45cc0928..fd14eaad361 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -998,7 +998,10 @@ longlong Item_func_hybrid_result_type::val_int() case INT_RESULT: return int_op(); case REAL_RESULT: - return (longlong) rint(real_op()); + { + bool error; + return double_to_longlong(real_op(), unsigned_flag, &error); + } case STRING_RESULT: { if (is_temporal_type(field_type())) diff --git a/sql/item_func.h b/sql/item_func.h index 813bcf0d023..65c10c8bad5 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -418,7 +418,11 @@ public: String *val_str(String*str); my_decimal *val_decimal(my_decimal *decimal_value); longlong val_int() - { DBUG_ASSERT(fixed == 1); return (longlong) rint(val_real()); } + { + DBUG_ASSERT(fixed == 1); + bool error; + return double_to_longlong(val_real(), unsigned_flag, &error); + } enum Item_result result_type () const { return REAL_RESULT; } void fix_length_and_dec() { decimals= NOT_FIXED_DEC; max_length= float_length(decimals); } @@ -1477,7 +1481,9 @@ class Item_func_udf_float :public Item_udf_func longlong val_int() { DBUG_ASSERT(fixed == 1); - return (longlong) rint(Item_func_udf_float::val_real()); + bool error; + return double_to_longlong(Item_func_udf_float::val_real(), + unsigned_flag, &error); } my_decimal *val_decimal(my_decimal *dec_buf) { diff --git a/sql/item_sum.cc b/sql/item_sum.cc index fae3f2344df..1262f85c8c7 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1451,7 +1451,8 @@ longlong Item_sum_sum::val_int() &result); return result; } - return (longlong) rint(val_real()); + bool error; + return double_to_longlong(val_real(), unsigned_flag, &error); } @@ -2665,7 +2666,8 @@ double Item_avg_field::val_real() longlong Item_avg_field::val_int() { - return (longlong) rint(val_real()); + bool error; + return double_to_longlong(val_real(), unsigned_flag, &error); } diff --git a/sql/item_sum.h b/sql/item_sum.h index f4be2108e1b..47511910146 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -699,7 +699,9 @@ public: longlong val_int() { DBUG_ASSERT(fixed == 1); - return (longlong) rint(val_real()); /* Real as default */ + // Real as default + bool error; + return double_to_longlong(val_real(), unsigned_flag, &error); } String *val_str(String*str); my_decimal *val_decimal(my_decimal *); @@ -867,7 +869,11 @@ public: bool add(); double val_real(); // In SPs we might force the "wrong" type with select into a declare variable - longlong val_int() { return (longlong) rint(val_real()); } + longlong val_int() + { + bool error; + return double_to_longlong(val_real(), unsigned_flag, &error); + } my_decimal *val_decimal(my_decimal *); String *val_str(String *str); void reset_field(); @@ -904,7 +910,10 @@ public: enum Type type() const {return FIELD_VARIANCE_ITEM; } double val_real(); longlong val_int() - { /* can't be fix_fields()ed */ return (longlong) rint(val_real()); } + { /* can't be fix_fields()ed */ + bool error; + return double_to_longlong(val_real(), unsigned_flag, &error); + } String *val_str(String *str) { return val_string_from_real(str); } my_decimal *val_decimal(my_decimal *dec_buf) @@ -1215,7 +1224,9 @@ class Item_sum_udf_float :public Item_udf_sum longlong val_int() { DBUG_ASSERT(fixed == 1); - return (longlong) rint(Item_sum_udf_float::val_real()); + bool error; + return double_to_longlong(Item_sum_udf_float::val_real(), + unsigned_flag, &error); } double val_real(); String *val_str(String*str); diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index c7a14049f37..cc600c8252a 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -41,6 +41,7 @@ #include "set_var.h" #include "sql_locale.h" // MY_LOCALE my_locale_en_US #include "strfunc.h" // check_word +#include "sql_type_int.h" // Longlong_hybrid #include "sql_time.h" // make_truncated_value_warning, // get_date_from_daynr, // calc_weekday, calc_week, @@ -2801,8 +2802,7 @@ bool Item_func_timediff::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) bool Item_func_maketime::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) { DBUG_ASSERT(fixed == 1); - bool overflow= 0; - longlong hour= args[0]->val_int(); + Longlong_hybrid hour(args[0]->val_int(), args[0]->unsigned_flag); longlong minute= args[1]->val_int(); ulonglong second; ulong microsecond; @@ -2814,32 +2814,23 @@ bool Item_func_maketime::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) bzero(ltime, sizeof(*ltime)); ltime->time_type= MYSQL_TIMESTAMP_TIME; + ltime->neg= hour.neg(); - /* Check for integer overflows */ - if (hour < 0) + if (hour.abs() <= TIME_MAX_HOUR) { - if (args[0]->unsigned_flag) - overflow= 1; - else - ltime->neg= 1; - } - if (-hour > TIME_MAX_HOUR || hour > TIME_MAX_HOUR) - overflow= 1; - - if (!overflow) - { - ltime->hour= (uint) ((hour < 0 ? -hour : hour)); + ltime->hour= (uint) hour.abs(); ltime->minute= (uint) minute; ltime->second= (uint) second; ltime->second_part= microsecond; } else { - ltime->hour= TIME_MAX_HOUR; - ltime->minute= TIME_MAX_MINUTE; - ltime->second= TIME_MAX_SECOND; + // use check_time_range() to set ltime to the max value depending on dec + int unused; + ltime->hour= TIME_MAX_HOUR + 1; + check_time_range(ltime, decimals, &unused); char buf[28]; - char *ptr= longlong10_to_str(hour, buf, args[0]->unsigned_flag ? 10 : -10); + char *ptr= longlong10_to_str(hour.value(), buf, hour.is_unsigned() ? 10 : -10); int len = (int)(ptr - buf) + sprintf(ptr, ":%02u:%02u", (uint)minute, (uint)second); make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, buf, len, MYSQL_TIMESTAMP_TIME, diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index fa0f4ad1563..8eefddf57cc 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -9950,9 +9950,8 @@ bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name, combo->user.str= (char *) sctx->priv_user; mysql_mutex_lock(&acl_cache->lock); - - if ((au= find_user_wild(combo->host.str= (char *) sctx->priv_host, - combo->user.str))) + if ((au= find_user_exact(combo->host.str= (char *) sctx->priv_host, + combo->user.str))) goto found_acl; mysql_mutex_unlock(&acl_cache->lock); diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 609e5472ba6..bbea9815547 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -979,6 +979,7 @@ multi_delete::~multi_delete() { TABLE *table= table_being_deleted->table; table->no_keyread=0; + table->no_cache= 0; } for (uint counter= 0; counter < num_of_tables; counter++) diff --git a/sql/sql_error.h b/sql/sql_error.h index a993e9203c9..da077627c88 100644 --- a/sql/sql_error.h +++ b/sql/sql_error.h @@ -18,6 +18,7 @@ #include "sql_list.h" /* Sql_alloc, MEM_ROOT */ #include "m_string.h" /* LEX_STRING */ +#include "sql_type_int.h" // Longlong_hybrid #include "sql_string.h" /* String */ #include "sql_plist.h" /* I_P_List */ #include "mysql_com.h" /* MYSQL_ERRMSG_SIZE */ @@ -573,13 +574,11 @@ public: { return err_conv(err_buffer, sizeof(err_buffer), str, len, cs); } }; -class ErrConvInteger : public ErrConv +class ErrConvInteger : public ErrConv, public Longlong_hybrid { - longlong m_value; - bool m_unsigned; public: ErrConvInteger(longlong num_arg, bool unsigned_flag= false) : - ErrConv(), m_value(num_arg), m_unsigned(unsigned_flag) {} + ErrConv(), Longlong_hybrid(num_arg, unsigned_flag) {} const char *ptr() const { return m_unsigned ? ullstr(m_value, err_buffer) : diff --git a/sql/sql_type_int.h b/sql/sql_type_int.h new file mode 100644 index 00000000000..055790ba431 --- /dev/null +++ b/sql/sql_type_int.h @@ -0,0 +1,40 @@ +/* Copyright (c) 2006, 2010, Oracle and/or its affiliates. + Copyright (c) 2011, 2016, MariaDB + + 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 + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#ifndef SQL_TYPE_INT_INCLUDED +#define SQL_TYPE_INT_INCLUDED + + +// A longlong/ulonglong hybrid. Good to store results of val_int(). +class Longlong_hybrid +{ +protected: + longlong m_value; + bool m_unsigned; +public: + Longlong_hybrid(longlong nr, bool unsigned_flag) + :m_value(nr), m_unsigned(unsigned_flag) + { } + longlong value() const { return m_value; } + bool is_unsigned() const { return m_unsigned; } + bool neg() const { return m_value < 0 && !m_unsigned; } + ulonglong abs() const + { + return neg() ? (ulonglong) -m_value : (ulonglong) m_value; + } +}; + +#endif // SQL_TYPE_INT_INCLUDED diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 94fbe0924b6..592e8158c0d 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -2031,7 +2031,7 @@ multi_update::~multi_update() TABLE_LIST *table; for (table= update_tables ; table; table= table->next_local) { - table->table->no_keyread= table->table->no_cache= 0; + table->table->no_keyread= 0; if (ignore) table->table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); } |