From 6073049a3675363f7d7efe26f47525b528be9e2f Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Thu, 15 Aug 2019 13:16:00 +0400 Subject: MDEV-20353 Add separate type handlers for unsigned integer data types --- mysql-test/main/func_debug.result | 8 +- mysql-test/main/func_hybrid_type.result | 181 +++++++++++++++++++++ mysql-test/main/func_hybrid_type.test | 232 ++++++++++++++++++++++++++ mysql-test/main/gis.result | 4 +- sql/field.h | 59 +++++-- sql/handler.cc | 3 +- sql/item.h | 11 +- sql/item_cmpfunc.cc | 4 +- sql/item_cmpfunc.h | 2 +- sql/item_func.cc | 19 ++- sql/item_func.h | 35 ++-- sql/item_sum.h | 13 +- sql/item_timefunc.h | 10 +- sql/item_windowfunc.h | 11 +- sql/procedure.h | 6 +- sql/rpl_utility_server.cc | 10 +- sql/sql_i_s.h | 12 +- sql/sql_lex.cc | 17 +- sql/sql_prepare.cc | 2 + sql/sql_select.cc | 9 +- sql/sql_sequence.cc | 18 +-- sql/sql_table.cc | 6 +- sql/sql_type.cc | 277 ++++++++++++++++++++++++++------ sql/sql_type.h | 159 ++++++++++-------- sql/sql_yacc.yy | 60 ++++--- sql/sql_yacc_ora.yy | 60 ++++--- sql/structs.h | 2 + 27 files changed, 974 insertions(+), 256 deletions(-) diff --git a/mysql-test/main/func_debug.result b/mysql-test/main/func_debug.result index 47bbced730b..08650fdd3c3 100644 --- a/mysql-test/main/func_debug.result +++ b/mysql-test/main/func_debug.result @@ -1723,7 +1723,7 @@ a 2 3 Warnings: -Note 1105 bin_eq=0 a=(int)-1 b=(bigint)18446744073709551615 +Note 1105 bin_eq=0 a=(int)-1 b=(bigint unsigned)18446744073709551615 SELECT * FROM t1 WHERE a BETWEEN -1 AND 18446744073709551616; a 1 @@ -1746,7 +1746,7 @@ a 2 3 Warnings: -Note 1105 bin_eq=0 a=(int)-1 b=(bigint)18446744073709551615 +Note 1105 bin_eq=0 a=(int)-1 b=(bigint unsigned)18446744073709551615 EXECUTE IMMEDIATE 'SELECT * FROM t1 WHERE a BETWEEN -1 AND ?' USING 18446744073709551616; a 1 @@ -1863,8 +1863,8 @@ Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (row) Note 1105 DBUG: [1] arg=2 handler=0 (row) Note 1105 DBUG: ROW(3 args) level=0 -Note 1105 DBUG: [0,0] handler=bigint -Note 1105 DBUG: [0,1] handler=bigint +Note 1105 DBUG: [0,0] handler=bigint unsigned +Note 1105 DBUG: [0,1] handler=bigint unsigned Note 1105 DBUG: [0,2] handler=int Note 1105 DBUG: => handler=decimal Note 1105 DBUG: [1,0] handler=int diff --git a/mysql-test/main/func_hybrid_type.result b/mysql-test/main/func_hybrid_type.result index c7e1ceb5077..4be42cee523 100644 --- a/mysql-test/main/func_hybrid_type.result +++ b/mysql-test/main/func_hybrid_type.result @@ -4132,5 +4132,186 @@ def COALESCE(a,b) 253 19 0 Y 0 39 8 COALESCE(a,b) DROP TABLE t1; # +# MDEV-20353 Add separate type handlers for unsigned integer data types +# +# Constant +SELECT 1=ROW(1,1); +ERROR HY000: Illegal parameter data types int and row for operation '=' +SELECT -1=ROW(1,1); +ERROR HY000: Illegal parameter data types int and row for operation '=' +SELECT 9223372036854775807=ROW(1,1); +ERROR HY000: Illegal parameter data types bigint and row for operation '=' +SELECT 9223372036854775808=ROW(1,1); +ERROR HY000: Illegal parameter data types bigint unsigned and row for operation '=' +SELECT 18446744073709551615=ROW(1,1); +ERROR HY000: Illegal parameter data types bigint unsigned and row for operation '=' +# COALESCE +CREATE TABLE t1 (a TINYINT UNSIGNED, b TINYINT); +SELECT COALESCE(a,a)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types tiny unsigned and row for operation '=' +SELECT COALESCE(b,b)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types tinyint and row for operation '=' +DROP TABLE t1; +CREATE TABLE t1 (a SMALLINT UNSIGNED, b SMALLINT); +SELECT COALESCE(a,a)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types smallint unsigned and row for operation '=' +SELECT COALESCE(b,b)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types smallint and row for operation '=' +DROP TABLE t1; +CREATE TABLE t1 (a MEDIUMINT UNSIGNED, b MEDIUMINT); +SELECT COALESCE(a,a)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types mediumint unsigned and row for operation '=' +SELECT COALESCE(b,b)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types mediumint and row for operation '=' +DROP TABLE t1; +CREATE TABLE t1 (a INT UNSIGNED, b INT); +SELECT COALESCE(a,a)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types int unsigned and row for operation '=' +SELECT COALESCE(b,b)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types int and row for operation '=' +DROP TABLE t1; +CREATE TABLE t1 (a BIGINT UNSIGNED, b BIGINT); +SELECT COALESCE(a,a)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types bigint unsigned and row for operation '=' +SELECT COALESCE(b,b)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types bigint and row for operation '=' +DROP TABLE t1; +# COALESCE for different types integer types, with the UNSIGNED flag +CREATE TABLE t1 (a1 TINYINT UNSIGNED, a2 SMALLINT UNSIGNED); +SELECT COALESCE(a1,a2)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types smallint unsigned and row for operation '=' +DROP TABLE t1; +CREATE TABLE t1 (a1 SMALLINT UNSIGNED, a2 MEDIUMINT UNSIGNED); +SELECT COALESCE(a1,a2)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types mediumint unsigned and row for operation '=' +DROP TABLE t1; +CREATE TABLE t1 (a1 MEDIUMINT UNSIGNED, a2 INT UNSIGNED); +SELECT COALESCE(a1,a2)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types int unsigned and row for operation '=' +DROP TABLE t1; +CREATE TABLE t1 (a1 INT UNSIGNED, a2 BIGINT UNSIGNED); +SELECT COALESCE(a1,a2)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types bigint unsigned and row for operation '=' +DROP TABLE t1; +# COALESCE for different types integer types, without the UNSIGNED flag +CREATE TABLE t1 (a1 TINYINT, a2 SMALLINT); +SELECT COALESCE(a1,a2)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types smallint and row for operation '=' +DROP TABLE t1; +CREATE TABLE t1 (a1 SMALLINT, a2 MEDIUMINT); +SELECT COALESCE(a1,a2)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types mediumint and row for operation '=' +DROP TABLE t1; +CREATE TABLE t1 (a1 MEDIUMINT, a2 INT); +SELECT COALESCE(a1,a2)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types int and row for operation '=' +DROP TABLE t1; +CREATE TABLE t1 (a1 INT, a2 BIGINT); +SELECT COALESCE(a1,a2)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types bigint and row for operation '=' +DROP TABLE t1; +# Operator + +CREATE TABLE t1 (a TINYINT UNSIGNED, b TINYINT); +SELECT (a+a)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types int unsigned and row for operation '=' +SELECT (b+b)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types int and row for operation '=' +DROP TABLE t1; +CREATE TABLE t1 (a SMALLINT UNSIGNED, b SMALLINT); +SELECT (a+a)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types int unsigned and row for operation '=' +SELECT (b+b)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types int and row for operation '=' +DROP TABLE t1; +CREATE TABLE t1 (a MEDIUMINT UNSIGNED, b MEDIUMINT); +SELECT (a+a)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types int unsigned and row for operation '=' +SELECT (b+b)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types bigint and row for operation '=' +DROP TABLE t1; +CREATE TABLE t1 (a INT UNSIGNED, b INT); +SELECT (a+a)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types bigint unsigned and row for operation '=' +SELECT (b+b)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types bigint and row for operation '=' +DROP TABLE t1; +CREATE TABLE t1 (a BIGINT UNSIGNED, b BIGINT); +SELECT (a+a)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types bigint unsigned and row for operation '=' +SELECT (b+b)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types bigint and row for operation '=' +DROP TABLE t1; +# Opetator + for different types integer types, with the UNSIGNED flag +CREATE TABLE t1 (a1 TINYINT UNSIGNED, a2 SMALLINT UNSIGNED); +SELECT (a1+a2)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types int unsigned and row for operation '=' +DROP TABLE t1; +CREATE TABLE t1 (a1 SMALLINT UNSIGNED, a2 MEDIUMINT UNSIGNED); +SELECT (a1+a2)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types int unsigned and row for operation '=' +DROP TABLE t1; +CREATE TABLE t1 (a1 MEDIUMINT UNSIGNED, a2 INT UNSIGNED); +SELECT (a1+a2)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types bigint unsigned and row for operation '=' +DROP TABLE t1; +CREATE TABLE t1 (a1 INT UNSIGNED, a2 BIGINT UNSIGNED); +SELECT (a1+a2)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types bigint unsigned and row for operation '=' +DROP TABLE t1; +# Operator + for different types integer types, without the UNSIGNED flag +CREATE TABLE t1 (a1 TINYINT, a2 SMALLINT); +SELECT (a1+a2)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types int and row for operation '=' +DROP TABLE t1; +CREATE TABLE t1 (a1 SMALLINT, a2 MEDIUMINT); +SELECT (a1+a2)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types bigint and row for operation '=' +DROP TABLE t1; +CREATE TABLE t1 (a1 MEDIUMINT, a2 INT); +SELECT (a1+a2)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types bigint and row for operation '=' +DROP TABLE t1; +CREATE TABLE t1 (a1 INT, a2 BIGINT); +SELECT (a1+a2)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types bigint and row for operation '=' +DROP TABLE t1; +# SUM +CREATE TABLE t1 (a TINYINT UNSIGNED, b TINYINT); +SELECT MAX(a)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types tiny unsigned and row for operation '=' +SELECT MAX(b)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types tinyint and row for operation '=' +DROP TABLE t1; +CREATE TABLE t1 (a SMALLINT UNSIGNED, b SMALLINT); +SELECT MAX(a)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types smallint unsigned and row for operation '=' +SELECT MAX(b)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types smallint and row for operation '=' +DROP TABLE t1; +CREATE TABLE t1 (a MEDIUMINT UNSIGNED, b MEDIUMINT); +SELECT MAX(a)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types mediumint unsigned and row for operation '=' +SELECT MAX(b)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types mediumint and row for operation '=' +DROP TABLE t1; +CREATE TABLE t1 (a INT UNSIGNED, b INT); +SELECT MAX(a)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types int unsigned and row for operation '=' +SELECT MAX(b)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types int and row for operation '=' +DROP TABLE t1; +CREATE TABLE t1 (a BIGINT UNSIGNED, b BIGINT); +SELECT MAX(a)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types bigint unsigned and row for operation '=' +SELECT MAX(b)=ROW(1,1) FROM t1; +ERROR HY000: Illegal parameter data types bigint and row for operation '=' +DROP TABLE t1; +# HEX hybrid +SELECT 0x20+ROW(1,1); +ERROR HY000: Illegal parameter data types bigint unsigned and row for operation '+' +# System variables +SELECT @@max_allowed_packet=ROW(1,1); +ERROR HY000: Illegal parameter data types bigint unsigned and row for operation '=' +# # End of 10.5 tests # diff --git a/mysql-test/main/func_hybrid_type.test b/mysql-test/main/func_hybrid_type.test index df19e3c97ff..cf41d92b01f 100644 --- a/mysql-test/main/func_hybrid_type.test +++ b/mysql-test/main/func_hybrid_type.test @@ -843,6 +843,238 @@ SELECT COALESCE(a,b) FROM t1; --enable_ps_protocol DROP TABLE t1; +--echo # +--echo # MDEV-20353 Add separate type handlers for unsigned integer data types +--echo # + +--echo # Constant + +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT 1=ROW(1,1); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT -1=ROW(1,1); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT 9223372036854775807=ROW(1,1); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT 9223372036854775808=ROW(1,1); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT 18446744073709551615=ROW(1,1); + + +--echo # COALESCE + +CREATE TABLE t1 (a TINYINT UNSIGNED, b TINYINT); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT COALESCE(a,a)=ROW(1,1) FROM t1; +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT COALESCE(b,b)=ROW(1,1) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a SMALLINT UNSIGNED, b SMALLINT); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT COALESCE(a,a)=ROW(1,1) FROM t1; +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT COALESCE(b,b)=ROW(1,1) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a MEDIUMINT UNSIGNED, b MEDIUMINT); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT COALESCE(a,a)=ROW(1,1) FROM t1; +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT COALESCE(b,b)=ROW(1,1) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a INT UNSIGNED, b INT); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT COALESCE(a,a)=ROW(1,1) FROM t1; +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT COALESCE(b,b)=ROW(1,1) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a BIGINT UNSIGNED, b BIGINT); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT COALESCE(a,a)=ROW(1,1) FROM t1; +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT COALESCE(b,b)=ROW(1,1) FROM t1; +DROP TABLE t1; + + +--echo # COALESCE for different types integer types, with the UNSIGNED flag + +CREATE TABLE t1 (a1 TINYINT UNSIGNED, a2 SMALLINT UNSIGNED); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT COALESCE(a1,a2)=ROW(1,1) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a1 SMALLINT UNSIGNED, a2 MEDIUMINT UNSIGNED); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT COALESCE(a1,a2)=ROW(1,1) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a1 MEDIUMINT UNSIGNED, a2 INT UNSIGNED); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT COALESCE(a1,a2)=ROW(1,1) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a1 INT UNSIGNED, a2 BIGINT UNSIGNED); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT COALESCE(a1,a2)=ROW(1,1) FROM t1; +DROP TABLE t1; + + +--echo # COALESCE for different types integer types, without the UNSIGNED flag + +CREATE TABLE t1 (a1 TINYINT, a2 SMALLINT); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT COALESCE(a1,a2)=ROW(1,1) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a1 SMALLINT, a2 MEDIUMINT); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT COALESCE(a1,a2)=ROW(1,1) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a1 MEDIUMINT, a2 INT); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT COALESCE(a1,a2)=ROW(1,1) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a1 INT, a2 BIGINT); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT COALESCE(a1,a2)=ROW(1,1) FROM t1; +DROP TABLE t1; + + +--echo # Operator + + +CREATE TABLE t1 (a TINYINT UNSIGNED, b TINYINT); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT (a+a)=ROW(1,1) FROM t1; +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT (b+b)=ROW(1,1) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a SMALLINT UNSIGNED, b SMALLINT); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT (a+a)=ROW(1,1) FROM t1; +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT (b+b)=ROW(1,1) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a MEDIUMINT UNSIGNED, b MEDIUMINT); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT (a+a)=ROW(1,1) FROM t1; +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT (b+b)=ROW(1,1) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a INT UNSIGNED, b INT); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT (a+a)=ROW(1,1) FROM t1; +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT (b+b)=ROW(1,1) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a BIGINT UNSIGNED, b BIGINT); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT (a+a)=ROW(1,1) FROM t1; +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT (b+b)=ROW(1,1) FROM t1; +DROP TABLE t1; + + +--echo # Opetator + for different types integer types, with the UNSIGNED flag + +CREATE TABLE t1 (a1 TINYINT UNSIGNED, a2 SMALLINT UNSIGNED); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT (a1+a2)=ROW(1,1) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a1 SMALLINT UNSIGNED, a2 MEDIUMINT UNSIGNED); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT (a1+a2)=ROW(1,1) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a1 MEDIUMINT UNSIGNED, a2 INT UNSIGNED); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT (a1+a2)=ROW(1,1) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a1 INT UNSIGNED, a2 BIGINT UNSIGNED); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT (a1+a2)=ROW(1,1) FROM t1; +DROP TABLE t1; + + +--echo # Operator + for different types integer types, without the UNSIGNED flag + +CREATE TABLE t1 (a1 TINYINT, a2 SMALLINT); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT (a1+a2)=ROW(1,1) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a1 SMALLINT, a2 MEDIUMINT); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT (a1+a2)=ROW(1,1) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a1 MEDIUMINT, a2 INT); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT (a1+a2)=ROW(1,1) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a1 INT, a2 BIGINT); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT (a1+a2)=ROW(1,1) FROM t1; +DROP TABLE t1; + +--echo # SUM + +CREATE TABLE t1 (a TINYINT UNSIGNED, b TINYINT); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT MAX(a)=ROW(1,1) FROM t1; +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT MAX(b)=ROW(1,1) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a SMALLINT UNSIGNED, b SMALLINT); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT MAX(a)=ROW(1,1) FROM t1; +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT MAX(b)=ROW(1,1) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a MEDIUMINT UNSIGNED, b MEDIUMINT); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT MAX(a)=ROW(1,1) FROM t1; +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT MAX(b)=ROW(1,1) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a INT UNSIGNED, b INT); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT MAX(a)=ROW(1,1) FROM t1; +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT MAX(b)=ROW(1,1) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a BIGINT UNSIGNED, b BIGINT); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT MAX(a)=ROW(1,1) FROM t1; +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT MAX(b)=ROW(1,1) FROM t1; +DROP TABLE t1; + +--echo # HEX hybrid + +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT 0x20+ROW(1,1); + +--echo # System variables + +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT @@max_allowed_packet=ROW(1,1); + --echo # --echo # End of 10.5 tests --echo # diff --git a/mysql-test/main/gis.result b/mysql-test/main/gis.result index 5b198bb870d..936924ffe87 100644 --- a/mysql-test/main/gis.result +++ b/mysql-test/main/gis.result @@ -5012,9 +5012,9 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; SELECT 0x60+POINT(1,1); -ERROR HY000: Illegal parameter data types bigint and point for operation '+' +ERROR HY000: Illegal parameter data types bigint unsigned and point for operation '+' SELECT POINT(1,1)+0x60; -ERROR HY000: Illegal parameter data types point and bigint for operation '+' +ERROR HY000: Illegal parameter data types point and bigint unsigned for operation '+' # # MDEV-16454 Bad results for IN with ROW # diff --git a/sql/field.h b/sql/field.h index af659e18db7..58bac152ea2 100644 --- a/sql/field.h +++ b/sql/field.h @@ -449,7 +449,7 @@ public: { // Use this when an item is [a part of] a boolean expression public: Context_boolean() - :Context(ANY_SUBST, &type_handler_longlong, &my_charset_bin) { } + :Context(ANY_SUBST, &type_handler_slonglong, &my_charset_bin) { } }; }; @@ -2279,6 +2279,10 @@ public: class Field_tiny :public Field_int { + const Type_handler_general_purpose_int *type_handler_priv() const + { + return is_unsigned() ? &type_handler_utiny : &type_handler_stiny; + } public: Field_tiny(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, @@ -2287,7 +2291,7 @@ public: :Field_int(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg, zero_arg, unsigned_arg) {} - const Type_handler *type_handler() const { return &type_handler_tiny; } + const Type_handler *type_handler() const { return type_handler_priv(); } enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_BINARY : HA_KEYTYPE_INT8; } int store(const char *to,size_t length,CHARSET_INFO *charset); @@ -2304,7 +2308,7 @@ public: void sql_type(String &str) const; const Type_limits_int *type_limits_int() const { - return type_handler_tiny.type_limits_int_by_unsigned_flag(is_unsigned()); + return type_handler_priv()->type_limits_int(); } virtual uchar *pack(uchar* to, const uchar *from, uint max_length) @@ -2330,6 +2334,10 @@ public: class Field_short :public Field_int { + const Type_handler_general_purpose_int *type_handler_priv() const + { + return is_unsigned() ? &type_handler_ushort : &type_handler_sshort; + } public: Field_short(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, @@ -2344,7 +2352,7 @@ public: :Field_int((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0, NONE, field_name_arg, 0, unsigned_arg) {} - const Type_handler *type_handler() const { return &type_handler_short; } + const Type_handler *type_handler() const { return type_handler_priv(); } enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_USHORT_INT : HA_KEYTYPE_SHORT_INT;} int store(const char *to,size_t length,CHARSET_INFO *charset); @@ -2361,7 +2369,7 @@ public: void sql_type(String &str) const; const Type_limits_int *type_limits_int() const { - return type_handler_short.type_limits_int_by_unsigned_flag(is_unsigned()); + return type_handler_priv()->type_limits_int(); } virtual uchar *pack(uchar* to, const uchar *from, uint max_length) { return pack_int16(to, from); } @@ -2377,6 +2385,10 @@ public: class Field_medium :public Field_int { + const Type_handler_general_purpose_int *type_handler_priv() const + { + return is_unsigned() ? &type_handler_uint24 : &type_handler_sint24; + } public: Field_medium(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, @@ -2385,7 +2397,7 @@ public: :Field_int(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg, zero_arg, unsigned_arg) {} - const Type_handler *type_handler() const { return &type_handler_int24; } + const Type_handler *type_handler() const { return type_handler_priv(); } enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_UINT24 : HA_KEYTYPE_INT24; } int store(const char *to,size_t length,CHARSET_INFO *charset); @@ -2402,7 +2414,7 @@ public: void sql_type(String &str) const; const Type_limits_int *type_limits_int() const { - return type_handler_int24.type_limits_int_by_unsigned_flag(is_unsigned()); + return type_handler_priv()->type_limits_int(); } virtual uchar *pack(uchar* to, const uchar *from, uint max_length) { @@ -2417,6 +2429,10 @@ public: class Field_long :public Field_int { + const Type_handler_general_purpose_int *type_handler_priv() const + { + return is_unsigned() ? &type_handler_ulong : &type_handler_slong; + } public: Field_long(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, @@ -2431,7 +2447,7 @@ public: :Field_int((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0, NONE, field_name_arg, 0, unsigned_arg) {} - const Type_handler *type_handler() const { return &type_handler_long; } + const Type_handler *type_handler() const { return type_handler_priv(); } enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_ULONG_INT : HA_KEYTYPE_LONG_INT; } int store(const char *to,size_t length,CHARSET_INFO *charset); @@ -2448,7 +2464,7 @@ public: void sql_type(String &str) const; const Type_limits_int *type_limits_int() const { - return type_handler_long.type_limits_int_by_unsigned_flag(is_unsigned()); + return type_handler_priv()->type_limits_int(); } virtual uchar *pack(uchar* to, const uchar *from, uint max_length __attribute__((unused))) @@ -2470,6 +2486,10 @@ public: class Field_longlong :public Field_int { + const Type_handler_general_purpose_int *type_handler_priv() const + { + return is_unsigned() ? &type_handler_ulonglong : &type_handler_slonglong; + } public: Field_longlong(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, @@ -2484,7 +2504,7 @@ public: :Field_int((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0, NONE, field_name_arg, 0, unsigned_arg) {} - const Type_handler *type_handler() const { return &type_handler_longlong; } + const Type_handler *type_handler() const { return type_handler_priv(); } enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_ULONGLONG : HA_KEYTYPE_LONGLONG; } int store(const char *to,size_t length,CHARSET_INFO *charset); @@ -2505,7 +2525,7 @@ public: void sql_type(String &str) const; const Type_limits_int *type_limits_int() const { - return type_handler_longlong.type_limits_int_by_unsigned_flag(is_unsigned()); + return type_handler_priv()->type_limits_int(); } virtual uchar *pack(uchar* to, const uchar *from, uint max_length __attribute__((unused))) @@ -5209,12 +5229,27 @@ public: } // This should move to Type_handler eventually - bool is_sane() const + bool is_sane_float() const { return (decimals <= FLOATING_POINT_DECIMALS || (type_handler()->field_type() != MYSQL_TYPE_FLOAT && type_handler()->field_type() != MYSQL_TYPE_DOUBLE)); } + bool is_sane_signess() const + { + if (type_handler() == type_handler()->type_handler_signed() && + type_handler() == type_handler()->type_handler_unsigned()) + return true; // Any signess is allowed, e.g. DOUBLE, DECIMAL + /* + We are here e.g. in case of INT data type. + The UNSIGNED_FLAG bit must match in flags and in the type handler. + */ + return ((bool) (flags & UNSIGNED_FLAG)) == type_handler()->is_unsigned(); + } + bool is_sane() const + { + return is_sane_float() && is_sane_signess(); + } }; diff --git a/sql/handler.cc b/sql/handler.cc index 3e54d4a19d0..94cffd69b75 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -7637,7 +7637,8 @@ static bool is_versioning_timestamp(const Create_field *f) static bool is_some_bigint(const Create_field *f) { - return f->type_handler() == &type_handler_longlong || + return f->type_handler() == &type_handler_slonglong || + f->type_handler() == &type_handler_ulonglong || f->type_handler() == &type_handler_vers_trx_id; } diff --git a/sql/item.h b/sql/item.h index 5fb008b73f1..49852d38e1a 100644 --- a/sql/item.h +++ b/sql/item.h @@ -2076,7 +2076,8 @@ public: const Type_handler *type_handler_long_or_longlong() const { - return Type_handler::type_handler_long_or_longlong(max_char_length()); + return Type_handler::type_handler_long_or_longlong(max_char_length(), + unsigned_flag); } /** @@ -3897,7 +3898,7 @@ public: bool set_limit_clause_param(longlong nr) { - value.set_handler(&type_handler_longlong); + value.set_handler(&type_handler_slonglong); set_int(nr, MY_INT64_NUM_DECIMAL_DIGITS); return !unsigned_flag && value.integer < 0; } @@ -4476,7 +4477,9 @@ public: } const Type_handler *type_handler() const { - return Type_handler::get_handler_by_field_type(int_field_type); + const Type_handler *h= + Type_handler::get_handler_by_field_type(int_field_type); + return unsigned_flag ? h->type_handler_unsigned() : h; } }; @@ -6502,8 +6505,6 @@ class Item_cache_int: public Item_cache protected: longlong value; public: - Item_cache_int(THD *thd): Item_cache(thd, &type_handler_longlong), - value(0) {} Item_cache_int(THD *thd, const Type_handler *handler): Item_cache(thd, handler), value(0) {} diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 02fc7719fbc..24ffaeab98e 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2119,7 +2119,7 @@ bool Item_func_between::fix_length_and_dec_numeric(THD *thd) if (cvt_arg1 && cvt_arg2) { // Works for all types - m_comparator.set_handler(&type_handler_longlong); + m_comparator.set_handler(&type_handler_slonglong); } } } @@ -4461,7 +4461,7 @@ bool Item_func_in::value_list_convert_const_to_int(THD *thd) all_converted= false; } if (all_converted) - m_comparator.set_handler(&type_handler_longlong); + m_comparator.set_handler(&type_handler_slonglong); } } return thd->is_fatal_error; // Catch errrors in convert_const_to_int diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 34c957cba19..0e9b573f106 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -1421,7 +1421,7 @@ public: ((Item_int*) item)->unsigned_flag= (bool) ((packed_longlong*) base)[pos].unsigned_flag; } - const Type_handler *type_handler() const { return &type_handler_longlong; } + const Type_handler *type_handler() const { return &type_handler_slonglong; } friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b); }; diff --git a/sql/item_func.cc b/sql/item_func.cc index 089103e1047..913442ee22d 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1188,7 +1188,10 @@ void Item_func_minus::fix_unsigned_flag() { if (unsigned_flag && (current_thd->variables.sql_mode & MODE_NO_UNSIGNED_SUBTRACTION)) + { unsigned_flag=0; + set_handler(Item_func_minus::type_handler()->type_handler_signed()); + } } @@ -1807,7 +1810,7 @@ void Item_func_neg::fix_length_and_dec_int() Ensure that result is converted to DECIMAL, as longlong can't hold the negated number */ - set_handler_by_result_type(DECIMAL_RESULT); + set_handler(&type_handler_newdecimal); DBUG_PRINT("info", ("Type changed: DECIMAL_RESULT")); } } @@ -4391,7 +4394,8 @@ bool Item_func_set_user_var::fix_fields(THD *thd, Item **ref) set_handler(&type_handler_double); break; case INT_RESULT: - set_handler(Type_handler::type_handler_long_or_longlong(max_char_length())); + set_handler(Type_handler::type_handler_long_or_longlong(max_char_length(), + unsigned_flag)); break; case DECIMAL_RESULT: set_handler(&type_handler_newdecimal); @@ -5292,21 +5296,25 @@ bool Item_func_get_user_var::fix_length_and_dec() unsigned_flag= m_var_entry->unsigned_flag; max_length= (uint32)m_var_entry->length; collation.set(m_var_entry->charset(), DERIVATION_IMPLICIT); - set_handler_by_result_type(m_var_entry->type); - switch (result_type()) { + switch (m_var_entry->type) { case REAL_RESULT: fix_char_length(DBL_DIG + 8); + set_handler(&type_handler_double); break; case INT_RESULT: fix_char_length(MAX_BIGINT_WIDTH); decimals=0; + set_handler(unsigned_flag ? &type_handler_ulonglong : + &type_handler_slonglong); break; case STRING_RESULT: max_length= MAX_BLOB_WIDTH - 1; + set_handler(&type_handler_long_blob); break; case DECIMAL_RESULT: fix_char_length(DECIMAL_MAX_STR_LENGTH); decimals= DECIMAL_MAX_SCALE; + set_handler(&type_handler_newdecimal); break; case ROW_RESULT: // Keep compiler happy case TIME_RESULT: @@ -5589,11 +5597,12 @@ const Type_handler *Item_func_get_system_var::type_handler() const case SHOW_SINT: case SHOW_SLONG: case SHOW_SLONGLONG: + return &type_handler_slonglong; case SHOW_UINT: case SHOW_ULONG: case SHOW_ULONGLONG: case SHOW_HA_ROWS: - return &type_handler_longlong; + return &type_handler_ulonglong; case SHOW_CHAR: case SHOW_CHAR_PTR: case SHOW_LEX_STRING: diff --git a/sql/item_func.h b/sql/item_func.h index d59ba73b37d..c7b23a49114 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1023,7 +1023,12 @@ public: Item_long_func(THD *thd, Item *a, Item *b, Item *c): Item_int_func(thd, a, b, c) {} Item_long_func(THD *thd, List &list): Item_int_func(thd, list) { } Item_long_func(THD *thd, Item_long_func *item) :Item_int_func(thd, item) {} - const Type_handler *type_handler() const { return &type_handler_long; } + const Type_handler *type_handler() const + { + if (unsigned_flag) + return &type_handler_ulong; + return &type_handler_slong; + } bool fix_length_and_dec() { max_length= 11; return FALSE; } }; @@ -1035,7 +1040,7 @@ public: {} longlong val_int(); bool fix_length_and_dec(); - const Type_handler *type_handler() const { return &type_handler_long; } + const Type_handler *type_handler() const { return &type_handler_slong; } Item *get_copy(THD *thd) { return get_item_copy(thd, this); } const char *func_name() const { return ""; } @@ -1052,7 +1057,12 @@ public: Item_int_func(thd, a, b, c, d) {} Item_longlong_func(THD *thd, List &list): Item_int_func(thd, list) { } Item_longlong_func(THD *thd, Item_longlong_func *item) :Item_int_func(thd, item) {} - const Type_handler *type_handler() const { return &type_handler_longlong; } + const Type_handler *type_handler() const + { + if (unsigned_flag) + return &type_handler_ulonglong; + return &type_handler_slonglong; + } }; @@ -1120,7 +1130,10 @@ public: } const char *func_name() const { return "cast_as_signed"; } const Type_handler *type_handler() const - { return type_handler_long_or_longlong(); } + { + return Type_handler::type_handler_long_or_longlong(max_char_length(), + false); + } longlong val_int() { longlong value= args[0]->val_int_signed_typecast(); @@ -1179,8 +1192,8 @@ public: const Type_handler *type_handler() const { if (max_char_length() <= MY_INT32_NUM_DECIMAL_DIGITS - 1) - return &type_handler_long; - return &type_handler_longlong; + return &type_handler_ulong; + return &type_handler_ulonglong; } longlong val_int() { @@ -2431,7 +2444,11 @@ public: return val_decimal_from_int(decimal_value); } String *val_str(String *str); - const Type_handler *type_handler() const { return &type_handler_longlong; } + const Type_handler *type_handler() const + { + return unsigned_flag ? &type_handler_ulonglong : + &type_handler_slonglong; + } bool fix_length_and_dec() { decimals= 0; max_length= 21; return FALSE; } Item *get_copy(THD *thd) { return get_item_copy(thd, this); } @@ -2523,7 +2540,7 @@ public: Item_int_func(thd) {} Item_func_udf_int(THD *thd, udf_func *udf_arg, List &list): Item_int_func(thd, list) {} - const Type_handler *type_handler() const { return &type_handler_longlong; } + const Type_handler *type_handler() const { return &type_handler_slonglong; } longlong val_int() { DBUG_ASSERT(fixed == 1); return 0; } }; @@ -2535,7 +2552,7 @@ public: Item_int_func(thd) {} Item_func_udf_decimal(THD *thd, udf_func *udf_arg, List &list): Item_int_func(thd, list) {} - const Type_handler *type_handler() const { return &type_handler_longlong; } + const Type_handler *type_handler() const { return &type_handler_slonglong; } my_decimal *val_decimal(my_decimal *) { DBUG_ASSERT(fixed == 1); return 0; } }; diff --git a/sql/item_sum.h b/sql/item_sum.h index 4e3241d9594..16cc8d131b8 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -753,7 +753,6 @@ public: double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } String *val_str(String*str); my_decimal *val_decimal(my_decimal *); - const Type_handler *type_handler() const { return &type_handler_longlong; } bool fix_length_and_dec() { decimals=0; max_length=21; maybe_null=null_value=0; return FALSE; } }; @@ -869,6 +868,7 @@ public: count=count_arg; Item_sum::make_const(); } + const Type_handler *type_handler() const { return &type_handler_slonglong; } longlong val_int(); void reset_field(); void update_field(); @@ -1052,11 +1052,11 @@ class Item_sum_hybrid: public Item_sum, public: Item_sum_hybrid(THD *thd, Item *item_par): Item_sum(thd, item_par), - Type_handler_hybrid_field_type(&type_handler_longlong) + Type_handler_hybrid_field_type(&type_handler_slonglong) { collation.set(&my_charset_bin); } Item_sum_hybrid(THD *thd, Item *a, Item *b): Item_sum(thd, a, b), - Type_handler_hybrid_field_type(&type_handler_longlong) + Type_handler_hybrid_field_type(&type_handler_slonglong) { collation.set(&my_charset_bin); } Item_sum_hybrid(THD *thd, Item_sum_hybrid *item) :Item_sum(thd, item), @@ -1175,6 +1175,7 @@ public: longlong val_int(); void reset_field(); void update_field(); + const Type_handler *type_handler() const { return &type_handler_ulonglong; } bool fix_length_and_dec() { decimals= 0; max_length=21; unsigned_flag= 1; maybe_null= null_value= 0; @@ -1644,7 +1645,11 @@ public: { DBUG_ASSERT(fixed == 1); return (double) Item_sum_udf_int::val_int(); } String *val_str(String*str); my_decimal *val_decimal(my_decimal *); - const Type_handler *type_handler() const { return &type_handler_longlong; } + const Type_handler *type_handler() const + { + return unsigned_flag ? &type_handler_ulonglong : + &type_handler_slonglong; + } bool fix_length_and_dec() { decimals=0; max_length=21; return FALSE; } Item *copy_or_same(THD* thd); Item *get_copy(THD *thd) diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index de00c39acde..9896499e172 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -191,7 +191,7 @@ public: return get_date_from_int(thd, ltime, fuzzydate); } const char *func_name() const { return "month"; } - const Type_handler *type_handler() const { return &type_handler_long; } + const Type_handler *type_handler() const { return &type_handler_slong; } bool fix_length_and_dec() { decimals= 0; @@ -467,7 +467,7 @@ public: { return type_handler()->Item_get_date_with_warn(thd, this, ltime, fuzzydate); } - const Type_handler *type_handler() const { return &type_handler_long; } + const Type_handler *type_handler() const { return &type_handler_slong; } bool fix_length_and_dec() { decimals= 0; @@ -980,8 +980,8 @@ class Item_extract :public Item_int_func, uint32 threashold) { if (length >= threashold) - return &type_handler_longlong; - return &type_handler_long; + return &type_handler_slonglong; + return &type_handler_slong; } void set_date_length(uint32 length) { @@ -1012,7 +1012,7 @@ class Item_extract :public Item_int_func, const interval_type int_type; // keep it public Item_extract(THD *thd, interval_type type_arg, Item *a): Item_int_func(thd, a), - Type_handler_hybrid_field_type(&type_handler_longlong), + Type_handler_hybrid_field_type(&type_handler_slonglong), m_date_mode(date_mode_t(0)), int_type(type_arg) { } diff --git a/sql/item_windowfunc.h b/sql/item_windowfunc.h index ab0e914a4c4..8b53b2012e7 100644 --- a/sql/item_windowfunc.h +++ b/sql/item_windowfunc.h @@ -118,6 +118,8 @@ public: Item_sum_row_number(THD *thd) : Item_sum_int(thd), count(0) {} + const Type_handler *type_handler() const { return &type_handler_slonglong; } + void clear() { count= 0; @@ -179,6 +181,8 @@ public: Item_sum_rank(THD *thd) : Item_sum_int(thd), peer_tracker(NULL) {} + const Type_handler *type_handler() const { return &type_handler_slonglong; } + void clear() { /* This is called on partition start */ @@ -266,6 +270,7 @@ class Item_sum_dense_rank: public Item_sum_int Item_sum_dense_rank(THD *thd) : Item_sum_int(thd), dense_rank(0), first_add(true), peer_tracker(NULL) {} + const Type_handler *type_handler() const { return &type_handler_slonglong; } enum Sumfunctype sum_func () const { return DENSE_RANK_FUNC; @@ -690,7 +695,7 @@ class Item_sum_ntile : public Item_sum_window_with_row_count void update_field() {} - const Type_handler *type_handler() const { return &type_handler_longlong; } + const Type_handler *type_handler() const { return &type_handler_slonglong; } Item *get_copy(THD *thd) { return get_item_copy(thd, this); } @@ -705,7 +710,7 @@ class Item_sum_percentile_disc : public Item_sum_cume_dist, { public: Item_sum_percentile_disc(THD *thd, Item* arg) : Item_sum_cume_dist(thd, arg), - Type_handler_hybrid_field_type(&type_handler_longlong), + Type_handler_hybrid_field_type(&type_handler_slonglong), value(NULL), val_calculated(FALSE), first_call(TRUE), prev_value(0), order_item(NULL){} @@ -1294,7 +1299,7 @@ public: bool fix_length_and_dec() { - decimals = window_func()->decimals; + Type_std_attributes::set(window_func()); return FALSE; } diff --git a/sql/procedure.h b/sql/procedure.h index 008c5a8b294..b7e7b38a4d2 100644 --- a/sql/procedure.h +++ b/sql/procedure.h @@ -107,7 +107,11 @@ class Item_proc_int :public Item_proc public: Item_proc_int(THD *thd, const char *name_par): Item_proc(thd, name_par) { max_length=11; } - const Type_handler *type_handler() const { return &type_handler_longlong; } + const Type_handler *type_handler() const + { + return unsigned_flag ? &type_handler_ulonglong : + &type_handler_slonglong; + } void set(double nr) { value=(longlong) nr; } void set(longlong nr) { value=nr; } void set(const char *str,uint length, CHARSET_INFO *cs) diff --git a/sql/rpl_utility_server.cc b/sql/rpl_utility_server.cc index 4abcd9d6e1e..de088be6434 100644 --- a/sql/rpl_utility_server.cc +++ b/sql/rpl_utility_server.cc @@ -472,11 +472,11 @@ Field_int::rpl_conv_type_from(const Conv_source &source, The length comparison check will do the correct job of comparing the field lengths (in bytes) of two integer types. */ - if (source.type_handler() == &type_handler_tiny || - source.type_handler() == &type_handler_short || - source.type_handler() == &type_handler_int24 || - source.type_handler() == &type_handler_long || - source.type_handler() == &type_handler_longlong) + if (source.type_handler() == &type_handler_stiny || + source.type_handler() == &type_handler_sshort || + source.type_handler() == &type_handler_sint24 || + source.type_handler() == &type_handler_slong || + source.type_handler() == &type_handler_slonglong) { /* max_display_length_for_field() is not fully precise for the integer diff --git a/sql/sql_i_s.h b/sql/sql_i_s.h index a4c29b83826..4ca669a5610 100644 --- a/sql/sql_i_s.h +++ b/sql/sql_i_s.h @@ -218,7 +218,7 @@ public: class ULonglong: public Type { public: - ULonglong(uint length) :Type(&type_handler_longlong, length, true) { } + ULonglong(uint length) :Type(&type_handler_ulonglong, length, true) { } ULonglong() :ULonglong(MY_INT64_NUM_DECIMAL_DIGITS) { } }; @@ -226,7 +226,7 @@ public: class ULong: public Type { public: - ULong(uint length) :Type(&type_handler_long, length, true) { } + ULong(uint length) :Type(&type_handler_ulong, length, true) { } ULong() :ULong(MY_INT32_NUM_DECIMAL_DIGITS) { } }; @@ -234,7 +234,7 @@ public: class SLonglong: public Type { public: - SLonglong(uint length) :Type(&type_handler_longlong, length, false) { } + SLonglong(uint length) :Type(&type_handler_slonglong, length, false) { } SLonglong() :SLonglong(MY_INT64_NUM_DECIMAL_DIGITS) { } }; @@ -242,7 +242,7 @@ public: class SLong: public Type { public: - SLong(uint length) :Type(&type_handler_long, length, false) { } + SLong(uint length) :Type(&type_handler_slong, length, false) { } SLong() :SLong(MY_INT32_NUM_DECIMAL_DIGITS) { } }; @@ -250,14 +250,14 @@ public: class SShort: public Type { public: - SShort(uint length) :Type(&type_handler_short, length, false) { } + SShort(uint length) :Type(&type_handler_sshort, length, false) { } }; class STiny: public Type { public: - STiny(uint length) :Type(&type_handler_tiny, length, false) { } + STiny(uint length) :Type(&type_handler_stiny, length, false) { } }; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 15d83b15ac9..8f6e86fdb48 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -5979,9 +5979,9 @@ sp_variable *LEX::sp_add_for_loop_variable(THD *thd, const LEX_CSTRING *name, sp_variable *spvar= spcont->add_variable(thd, name); spcont->declare_var_boundary(1); spvar->field_def.field_name= spvar->name; - spvar->field_def.set_handler(&type_handler_longlong); - type_handler_longlong.Column_definition_prepare_stage2(&spvar->field_def, - NULL, HA_CAN_GEOMETRY); + spvar->field_def.set_handler(&type_handler_slonglong); + type_handler_slonglong.Column_definition_prepare_stage2(&spvar->field_def, + NULL, HA_CAN_GEOMETRY); if (!value && unlikely(!(value= new (thd->mem_root) Item_null(thd)))) return NULL; @@ -10496,3 +10496,14 @@ Lex_cast_type_st::create_typecast_item_or_error(THD *thd, Item *item, } return tmp; } + + +void Lex_field_type_st::set_handler_length_flags(const Type_handler *handler, + const char *length, + uint32 flags) +{ + DBUG_ASSERT(!handler->is_unsigned()); + if (flags & UNSIGNED_FLAG) + handler= handler->type_handler_unsigned(); + set(handler, length, NULL); +} diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index ab90e16d903..5a4e13603a1 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -739,6 +739,8 @@ void Item_param::setup_conversion(THD *thd, uchar param_type) */ if (!h) h= &type_handler_string; + else if (unsigned_flag) + h= h->type_handler_unsigned(); set_handler(h); h->Item_param_setup_conversion(thd, this); } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 3977dd9017b..a15fb860578 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -17507,9 +17507,11 @@ const_expression_in_where(COND *cond, Item *comp_item, Field *comp_field, Field *Item::create_tmp_field_int(MEM_ROOT *root, TABLE *table, uint convert_int_length) { - const Type_handler *h= &type_handler_long; + const Type_handler *h= &type_handler_slong; if (max_char_length() > convert_int_length) - h= &type_handler_longlong; + h= &type_handler_slonglong; + if (unsigned_flag) + h= h->type_handler_unsigned(); return h->make_and_init_table_field(root, &name, Record_addr(maybe_null), *this, table); } @@ -17601,7 +17603,8 @@ Item_field::create_tmp_field_from_item_field(MEM_ROOT *root, TABLE *new_table, else if (param->table_cant_handle_bit_fields() && field->type() == MYSQL_TYPE_BIT) { - const Type_handler *handler= type_handler_long_or_longlong(); + const Type_handler *handler= + Type_handler::type_handler_long_or_longlong(max_char_length(), true); result= handler->make_and_init_table_field(root, &name, Record_addr(maybe_null), *this, new_table); diff --git a/sql/sql_sequence.cc b/sql/sql_sequence.cc index 4e8624d6360..544c9b7f436 100644 --- a/sql/sql_sequence.cc +++ b/sql/sql_sequence.cc @@ -48,20 +48,20 @@ struct Field_definition static Field_definition sequence_structure[]= { - {"next_not_cached_value", 21, &type_handler_longlong, + {"next_not_cached_value", 21, &type_handler_slonglong, {STRING_WITH_LEN("")}, FL}, - {"minimum_value", 21, &type_handler_longlong, {STRING_WITH_LEN("")}, FL}, - {"maximum_value", 21, &type_handler_longlong, {STRING_WITH_LEN("")}, FL}, - {"start_value", 21, &type_handler_longlong, {STRING_WITH_LEN("start value when sequences is created or value if RESTART is used")}, FL}, - {"increment", 21, &type_handler_longlong, + {"minimum_value", 21, &type_handler_slonglong, {STRING_WITH_LEN("")}, FL}, + {"maximum_value", 21, &type_handler_slonglong, {STRING_WITH_LEN("")}, FL}, + {"start_value", 21, &type_handler_slonglong, {STRING_WITH_LEN("start value when sequences is created or value if RESTART is used")}, FL}, + {"increment", 21, &type_handler_slonglong, {STRING_WITH_LEN("increment value")}, FL}, - {"cache_size", 21, &type_handler_longlong, {STRING_WITH_LEN("")}, + {"cache_size", 21, &type_handler_ulonglong, {STRING_WITH_LEN("")}, FL | UNSIGNED_FLAG}, - {"cycle_option", 1, &type_handler_tiny, {STRING_WITH_LEN("0 if no cycles are allowed, 1 if the sequence should begin a new cycle when maximum_value is passed")}, + {"cycle_option", 1, &type_handler_utiny, {STRING_WITH_LEN("0 if no cycles are allowed, 1 if the sequence should begin a new cycle when maximum_value is passed")}, FL | UNSIGNED_FLAG }, - {"cycle_count", 21, &type_handler_longlong, + {"cycle_count", 21, &type_handler_slonglong, {STRING_WITH_LEN("How many cycles have been done")}, FL}, - {NULL, 0, &type_handler_longlong, {STRING_WITH_LEN("")}, 0} + {NULL, 0, &type_handler_slonglong, {STRING_WITH_LEN("")}, 0} }; #undef FL diff --git a/sql/sql_table.cc b/sql/sql_table.cc index bdf1d043e71..b7781d3389e 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3356,7 +3356,7 @@ static Create_field * add_hash_field(THD * thd, List *create_list, } } cf->field_name= field_name; - cf->set_handler(&type_handler_longlong); + cf->set_handler(&type_handler_slonglong); key_info->algorithm= HA_KEY_ALG_LONG_HASH; create_list->push_back(cf,thd->mem_root); return cf; @@ -3481,12 +3481,12 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, DBUG_EXECUTE_IF("test_pseudo_invisible",{ mysql_add_invisible_field(thd, &alter_info->create_list, - "invisible", &type_handler_long, INVISIBLE_SYSTEM, + "invisible", &type_handler_slong, INVISIBLE_SYSTEM, new (thd->mem_root)Item_int(thd, 9)); }); DBUG_EXECUTE_IF("test_completely_invisible",{ mysql_add_invisible_field(thd, &alter_info->create_list, - "invisible", &type_handler_long, INVISIBLE_FULL, + "invisible", &type_handler_slong, INVISIBLE_FULL, new (thd->mem_root)Item_int(thd, 9)); }); DBUG_EXECUTE_IF("test_invisible_index",{ diff --git a/sql/sql_type.cc b/sql/sql_type.cc index f9a16e72f0f..905676ee604 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -37,12 +37,16 @@ Type_handler_row type_handler_row; Type_handler_null type_handler_null; Type_handler_bool type_handler_bool; -Type_handler_tiny type_handler_tiny; -Type_handler_short type_handler_short; -Type_handler_long type_handler_long; -Type_handler_int24 type_handler_int24; -Type_handler_longlong type_handler_longlong; -Type_handler_longlong type_handler_ulonglong; // Only used for CAST() for now +Type_handler_tiny type_handler_stiny; +Type_handler_short type_handler_sshort; +Type_handler_long type_handler_slong; +Type_handler_int24 type_handler_sint24; +Type_handler_longlong type_handler_slonglong; +Type_handler_utiny type_handler_utiny; +Type_handler_ushort type_handler_ushort; +Type_handler_ulong type_handler_ulong; +Type_handler_uint24 type_handler_uint24; +Type_handler_ulonglong type_handler_ulonglong; Type_handler_vers_trx_id type_handler_vers_trx_id; Type_handler_float type_handler_float; Type_handler_double type_handler_double; @@ -1348,7 +1352,7 @@ Type_handler::get_handler_by_cmp_type(Item_result type) { switch (type) { case REAL_RESULT: return &type_handler_double; - case INT_RESULT: return &type_handler_longlong; + case INT_RESULT: return &type_handler_slonglong; case DECIMAL_RESULT: return &type_handler_newdecimal; case STRING_RESULT: return &type_handler_long_blob; case TIME_RESULT: return &type_handler_datetime; @@ -1422,25 +1426,174 @@ const Name Type_handler_datetime_common::m_name_datetime(STRING_WITH_LEN("datetime")), Type_handler_timestamp_common::m_name_timestamp(STRING_WITH_LEN("timestamp")); + +const Name Type_handler_utiny::name() const +{ + static Name tmp(STRING_WITH_LEN("tiny unsigned")); + return tmp; +} + + +const Name Type_handler_ushort::name() const +{ + static Name tmp(STRING_WITH_LEN("smallint unsigned")); + return tmp; +} + + +const Name Type_handler_uint24::name() const +{ + static Name tmp(STRING_WITH_LEN("mediumint unsigned")); + return tmp; +} + + +const Name Type_handler_ulong::name() const +{ + static Name tmp(STRING_WITH_LEN("int unsigned")); + return tmp; +} + + +const Name Type_handler_ulonglong::name() const +{ + static Name tmp(STRING_WITH_LEN("bigint unsigned")); + return tmp; +} + + +/***************************************************************************/ + const Name Type_handler::m_version_default(STRING_WITH_LEN("")), Type_handler::m_version_mariadb53(STRING_WITH_LEN("mariadb-5.3")), Type_handler::m_version_mysql56(STRING_WITH_LEN("mysql-5.6")); -const Type_limits_int - Type_handler_tiny::m_limits_sint8= Type_limits_sint8(), - Type_handler_tiny::m_limits_uint8= Type_limits_uint8(), - Type_handler_short::m_limits_sint16= Type_limits_sint16(), - Type_handler_short::m_limits_uint16= Type_limits_uint16(), - Type_handler_int24::m_limits_sint24= Type_limits_sint24(), - Type_handler_int24::m_limits_uint24= Type_limits_uint24(), - Type_handler_long::m_limits_sint32= Type_limits_sint32(), - Type_handler_long::m_limits_uint32= Type_limits_uint32(), - Type_handler_longlong::m_limits_sint64= Type_limits_sint64(), - Type_handler_longlong::m_limits_uint64= Type_limits_uint64(); +/***************************************************************************/ + +const Type_limits_int *Type_handler_tiny::type_limits_int() const +{ + static const Type_limits_sint8 limits_sint8; + return &limits_sint8; +} + +const Type_limits_int *Type_handler_utiny::type_limits_int() const +{ + static const Type_limits_uint8 limits_uint8; + return &limits_uint8; +} + +const Type_limits_int *Type_handler_short::type_limits_int() const +{ + static const Type_limits_sint16 limits_sint16; + return &limits_sint16; +} + +const Type_limits_int *Type_handler_ushort::type_limits_int() const +{ + static const Type_limits_uint16 limits_uint16; + return &limits_uint16; +} + +const Type_limits_int *Type_handler_int24::type_limits_int() const +{ + static const Type_limits_sint24 limits_sint24; + return &limits_sint24; +} + +const Type_limits_int *Type_handler_uint24::type_limits_int() const +{ + static const Type_limits_uint24 limits_uint24; + return &limits_uint24; +} + +const Type_limits_int *Type_handler_long::type_limits_int() const +{ + static const Type_limits_sint32 limits_sint32; + return &limits_sint32; +} + +const Type_limits_int *Type_handler_ulong::type_limits_int() const +{ + static const Type_limits_uint32 limits_uint32; + return &limits_uint32; +} + +const Type_limits_int *Type_handler_longlong::type_limits_int() const +{ + static const Type_limits_sint64 limits_sint64; + return &limits_sint64; +} + +const Type_limits_int *Type_handler_ulonglong::type_limits_int() const +{ + static const Type_limits_uint64 limits_uint64; + return &limits_uint64; +} +/***************************************************************************/ +const Type_handler *Type_handler_bool::type_handler_signed() const +{ + return &type_handler_bool; +} + +const Type_handler *Type_handler_bool::type_handler_unsigned() const +{ + return &type_handler_bool; +} + +const Type_handler *Type_handler_tiny::type_handler_signed() const +{ + return &type_handler_stiny; +} + +const Type_handler *Type_handler_tiny::type_handler_unsigned() const +{ + return &type_handler_utiny; +} + +const Type_handler *Type_handler_short::type_handler_signed() const +{ + return &type_handler_sshort; +} + +const Type_handler *Type_handler_short::type_handler_unsigned() const +{ + return &type_handler_ushort; +} + +const Type_handler *Type_handler_int24::type_handler_signed() const +{ + return &type_handler_sint24; +} + +const Type_handler *Type_handler_int24::type_handler_unsigned() const +{ + return &type_handler_uint24; +} + +const Type_handler *Type_handler_long::type_handler_signed() const +{ + return &type_handler_slong; +} + +const Type_handler *Type_handler_long::type_handler_unsigned() const +{ + return &type_handler_ulong; +} + +const Type_handler *Type_handler_longlong::type_handler_signed() const +{ + return &type_handler_slonglong; +} + +const Type_handler *Type_handler_longlong::type_handler_unsigned() const +{ + return &type_handler_ulonglong; +} + /***************************************************************************/ const Type_handler *Type_handler_null::type_handler_for_comparison() const @@ -1451,7 +1604,7 @@ const Type_handler *Type_handler_null::type_handler_for_comparison() const const Type_handler *Type_handler_int_result::type_handler_for_comparison() const { - return &type_handler_longlong; + return &type_handler_slonglong; } @@ -1520,7 +1673,7 @@ const Type_handler *Type_handler_typelib::type_handler_for_item_field() const const Type_handler *Type_handler_typelib::cast_to_int_type_handler() const { - return &type_handler_longlong; + return &type_handler_slonglong; } @@ -1543,13 +1696,21 @@ Type_handler_hybrid_field_type::aggregate_for_result(const Type_handler *other) const Type_handler * -Type_handler::type_handler_long_or_longlong(uint max_char_length) +Type_handler::type_handler_long_or_longlong(uint max_char_length, + bool unsigned_flag) { + if (unsigned_flag) + { + if (max_char_length <= MY_INT32_NUM_DECIMAL_DIGITS - 2) + return &type_handler_ulong; + return &type_handler_ulonglong; + } if (max_char_length <= MY_INT32_NUM_DECIMAL_DIGITS - 2) - return &type_handler_long; - return &type_handler_longlong; + return &type_handler_slong; + return &type_handler_slonglong; } + /* This method is called for CASE (and its abbreviations) and LEAST/GREATEST when data type aggregation returned LONGLONG and there were some BIT @@ -1560,8 +1721,8 @@ const Type_handler * Type_handler::bit_and_int_mixture_handler(uint max_char_length) { if (max_char_length <= MY_INT32_NUM_DECIMAL_DIGITS) - return &type_handler_long; - return &type_handler_longlong; + return &type_handler_slong; + return &type_handler_slonglong; } @@ -1623,9 +1784,9 @@ Type_handler_hybrid_field_type::aggregate_for_result(const char *funcname, { bit_and_non_bit_mixture_found= true; if (type_handler() == &type_handler_bit) - set_handler(&type_handler_longlong); // BIT + non-BIT + set_handler(&type_handler_slonglong); // BIT + non-BIT else - cur= &type_handler_longlong; // non-BIT + BIT + cur= &type_handler_slonglong; // non-BIT + BIT } if (aggregate_for_result(cur)) { @@ -1634,7 +1795,7 @@ Type_handler_hybrid_field_type::aggregate_for_result(const char *funcname, return true; } } - if (bit_and_non_bit_mixture_found && type_handler() == &type_handler_longlong) + if (bit_and_non_bit_mixture_found && type_handler() == &type_handler_slonglong) set_handler(Type_handler::bit_and_int_mixture_handler(max_display_length)); return false; } @@ -1676,7 +1837,7 @@ Type_collection_std::aggregate_for_comparison(const Type_handler *ha, if (a == STRING_RESULT && b == STRING_RESULT) return &type_handler_long_blob; if (a == INT_RESULT && b == INT_RESULT) - return &type_handler_longlong; + return &type_handler_slonglong; if (a == ROW_RESULT || b == ROW_RESULT) return &type_handler_row; if (a == TIME_RESULT || b == TIME_RESULT) @@ -1774,9 +1935,9 @@ Type_collection_std::aggregate_for_min_max(const Type_handler *ha, if (ha != hb) { if (ha == &type_handler_bit) - ha= &type_handler_longlong; + ha= &type_handler_slonglong; else if (hb == &type_handler_bit) - hb= &type_handler_longlong; + hb= &type_handler_slonglong; } return Type_collection_std::aggregate_for_result(ha, hb); } @@ -1839,7 +2000,7 @@ Type_handler_hybrid_field_type::aggregate_for_min_max(const char *funcname, return true; } } - if (bit_and_non_bit_mixture_found && type_handler() == &type_handler_longlong) + if (bit_and_non_bit_mixture_found && type_handler() == &type_handler_slonglong) { uint32 max_display_length= items[0]->max_display_length(); for (uint i= 1; i < nitems; i++) @@ -1868,7 +2029,7 @@ Type_collection_std::aggregate_for_num_op(const Type_handler *h0, return &type_handler_newdecimal; DBUG_ASSERT(r0 == INT_RESULT && r1 == INT_RESULT); - return &type_handler_longlong; + return &type_handler_slonglong; } @@ -1913,11 +2074,11 @@ Type_handler::get_handler_by_field_type(enum_field_types type) switch (type) { case MYSQL_TYPE_DECIMAL: return &type_handler_olddecimal; case MYSQL_TYPE_NEWDECIMAL: return &type_handler_newdecimal; - case MYSQL_TYPE_TINY: return &type_handler_tiny; - case MYSQL_TYPE_SHORT: return &type_handler_short; - case MYSQL_TYPE_LONG: return &type_handler_long; - case MYSQL_TYPE_LONGLONG: return &type_handler_longlong; - case MYSQL_TYPE_INT24: return &type_handler_int24; + case MYSQL_TYPE_TINY: return &type_handler_stiny; + case MYSQL_TYPE_SHORT: return &type_handler_sshort; + case MYSQL_TYPE_LONG: return &type_handler_slong; + case MYSQL_TYPE_LONGLONG: return &type_handler_slonglong; + case MYSQL_TYPE_INT24: return &type_handler_sint24; case MYSQL_TYPE_YEAR: return &type_handler_year; case MYSQL_TYPE_BIT: return &type_handler_bit; case MYSQL_TYPE_FLOAT: return &type_handler_float; @@ -1968,11 +2129,11 @@ Type_handler::get_handler_by_real_type(enum_field_types type) switch (type) { case MYSQL_TYPE_DECIMAL: return &type_handler_olddecimal; case MYSQL_TYPE_NEWDECIMAL: return &type_handler_newdecimal; - case MYSQL_TYPE_TINY: return &type_handler_tiny; - case MYSQL_TYPE_SHORT: return &type_handler_short; - case MYSQL_TYPE_LONG: return &type_handler_long; - case MYSQL_TYPE_LONGLONG: return &type_handler_longlong; - case MYSQL_TYPE_INT24: return &type_handler_int24; + case MYSQL_TYPE_TINY: return &type_handler_stiny; + case MYSQL_TYPE_SHORT: return &type_handler_sshort; + case MYSQL_TYPE_LONG: return &type_handler_slong; + case MYSQL_TYPE_LONGLONG: return &type_handler_slonglong; + case MYSQL_TYPE_INT24: return &type_handler_sint24; case MYSQL_TYPE_YEAR: return &type_handler_year; case MYSQL_TYPE_BIT: return &type_handler_bit; case MYSQL_TYPE_FLOAT: return &type_handler_float; @@ -3117,6 +3278,7 @@ Field *Type_handler_tiny::make_table_field(MEM_ROOT *root, const Type_all_attributes &attr, TABLE *table) const { + DBUG_ASSERT(is_unsigned() == attr.unsigned_flag); return new (root) Field_tiny(addr.ptr(), attr.max_char_length(), addr.null_ptr(), addr.null_bit(), @@ -3131,6 +3293,7 @@ Field *Type_handler_short::make_table_field(MEM_ROOT *root, TABLE *table) const { + DBUG_ASSERT(is_unsigned() == attr.unsigned_flag); return new (root) Field_short(addr.ptr(), attr.max_char_length(), addr.null_ptr(), addr.null_bit(), @@ -3144,6 +3307,7 @@ Field *Type_handler_int24::make_table_field(MEM_ROOT *root, const Type_all_attributes &attr, TABLE *table) const { + DBUG_ASSERT(is_unsigned() == attr.unsigned_flag); return new (root) Field_medium(addr.ptr(), attr.max_char_length(), addr.null_ptr(), addr.null_bit(), @@ -3158,6 +3322,7 @@ Field *Type_handler_long::make_table_field(MEM_ROOT *root, const Type_all_attributes &attr, TABLE *table) const { + DBUG_ASSERT(is_unsigned() == attr.unsigned_flag); return new (root) Field_long(addr.ptr(), attr.max_char_length(), addr.null_ptr(), addr.null_bit(), @@ -3171,6 +3336,7 @@ Field *Type_handler_longlong::make_table_field(MEM_ROOT *root, const Type_all_attributes &attr, TABLE *table) const { + DBUG_ASSERT(is_unsigned() == attr.unsigned_flag); return new (root) Field_longlong(addr.ptr(), attr.max_char_length(), addr.null_ptr(), addr.null_bit(), @@ -3185,6 +3351,7 @@ Field *Type_handler_vers_trx_id::make_table_field(MEM_ROOT *root, const Type_all_attributes &attr, TABLE *table) const { + DBUG_ASSERT(is_unsigned() == attr.unsigned_flag); return new (root) Field_vers_trx_id(addr.ptr(), attr.max_char_length(), addr.null_ptr(), addr.null_bit(), @@ -3825,13 +3992,6 @@ uint32 Type_handler_bit::max_display_length(const Item *item) const } -uint32 Type_handler_general_purpose_int::max_display_length(const Item *item) - const -{ - return type_limits_int_by_unsigned_flag(item->unsigned_flag)->char_length(); -} - - /*************************************************************************/ void Type_handler_row::Item_update_null_value(Item *item) const @@ -4189,6 +4349,9 @@ bool Type_handler_int_result:: } } func->aggregate_attributes_int(items, nitems); + handler->set_handler(func->unsigned_flag ? + handler->type_handler()->type_handler_unsigned() : + handler->type_handler()->type_handler_signed()); return false; } @@ -4461,7 +4624,15 @@ bool Type_handler_real_result:: bool Type_handler_int_result:: Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const { - return func->fix_length_and_dec_numeric(&type_handler_longlong); + /* + "this" is equal func->args[0]->type_handler() here, e.g. for MIN()/MAX(). + func->unsigned_flag is not reliably set yet. + It will be set by the call below (copied from args[0]). + */ + const Type_handler *h= is_unsigned() ? + &type_handler_ulonglong : + &type_handler_slonglong; + return func->fix_length_and_dec_numeric(h); } @@ -7960,14 +8131,14 @@ Type_handler_temporal_result::Item_const_eq(const Item_const *a, const Type_handler * Type_handler_hex_hybrid::cast_to_int_type_handler() const { - return &type_handler_longlong; + return &type_handler_ulonglong; } const Type_handler * Type_handler_hex_hybrid::type_handler_for_system_time() const { - return &type_handler_longlong; + return &type_handler_ulonglong; } diff --git a/sql/sql_type.h b/sql/sql_type.h index a696ada93df..07cc9db4760 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -3283,7 +3283,8 @@ public: static const Type_handler *blob_type_handler(uint max_octet_length); static const Type_handler *string_type_handler(uint max_octet_length); static const Type_handler *bit_and_int_mixture_handler(uint max_char_len); - static const Type_handler *type_handler_long_or_longlong(uint max_char_len); + static const Type_handler *type_handler_long_or_longlong(uint max_char_len, + bool unsigned_flag); /** Return a string type handler for Item If too_big_for_varchar() returns a BLOB variant, according to length. @@ -3296,15 +3297,6 @@ public: static const Type_handler *get_handler_by_field_type(enum_field_types type); static const Type_handler *get_handler_by_real_type(enum_field_types type); static const Type_handler *get_handler_by_cmp_type(Item_result type); - static const Type_handler *get_handler_by_result_type(Item_result type) - { - /* - As result_type() returns STRING_RESULT for temporal Items, - type should never be equal to TIME_RESULT here. - */ - DBUG_ASSERT(type != TIME_RESULT); - return get_handler_by_cmp_type(type); - } virtual const Type_collection *type_collection() const; static const Type_handler *aggregate_for_result_traditional(const Type_handler *h1, @@ -3313,6 +3305,8 @@ public: virtual const Name name() const= 0; virtual const Name version() const { return m_version_default; } virtual const Name &default_value() const= 0; + virtual uint32 flags() const { return 0; } + bool is_unsigned() const { return flags() & UNSIGNED_FLAG; } virtual enum_field_types field_type() const= 0; virtual enum_field_types real_field_type() const { return field_type(); } /** @@ -3420,6 +3414,14 @@ public: { return this; } + virtual const Type_handler *type_handler_unsigned() const + { + return this; + } + virtual const Type_handler *type_handler_signed() const + { + return this; + } virtual int stored_field_cmp_to_item(THD *thd, Field *field, Item *item) const= 0; virtual CHARSET_INFO *charset_for_protocol(const Item *item) const; @@ -4745,9 +4747,11 @@ class Type_handler_general_purpose_int: public Type_handler_int_result { public: bool type_can_have_auto_increment_attribute() const { return true; } - virtual const Type_limits_int * - type_limits_int_by_unsigned_flag(bool unsigned_flag) const= 0; - uint32 max_display_length(const Item *item) const; + virtual const Type_limits_int *type_limits_int() const= 0; + uint32 max_display_length(const Item *item) const + { + return type_limits_int()->char_length(); + } bool Vers_history_point_resolve_unit(THD *thd, Vers_history_point *p) const; }; @@ -5005,21 +5009,17 @@ public: class Type_handler_tiny: public Type_handler_general_purpose_int { static const Name m_name_tiny; - static const Type_limits_int m_limits_sint8; - static const Type_limits_int m_limits_uint8; public: virtual ~Type_handler_tiny() {} const Name name() const override { return m_name_tiny; } enum_field_types field_type() const override { return MYSQL_TYPE_TINY; } + const Type_handler *type_handler_unsigned() const override; + const Type_handler *type_handler_signed() const override; protocol_send_type_t protocol_send_type() const override { return PROTOCOL_SEND_TINY; } - const Type_limits_int *type_limits_int_by_unsigned_flag(bool unsigned_fl) - const override - { - return unsigned_fl ? &m_limits_uint8 : &m_limits_sint8; - } + const Type_limits_int *type_limits_int() const override; uint32 calc_pack_length(uint32 length) const override { return 1; } uint32 max_display_length_for_field(const Conv_source &src) const override { return 4; } @@ -5057,15 +5057,24 @@ public: }; +class Type_handler_utiny: public Type_handler_tiny +{ +public: + const Name name() const override; + uint flags() const override { return UNSIGNED_FLAG; } + const Type_limits_int *type_limits_int() const override; +}; + + class Type_handler_short: public Type_handler_general_purpose_int { static const Name m_name_short; - static const Type_limits_int m_limits_sint16; - static const Type_limits_int m_limits_uint16; public: virtual ~Type_handler_short() {} const Name name() const override { return m_name_short; } enum_field_types field_type() const override { return MYSQL_TYPE_SHORT; } + const Type_handler *type_handler_unsigned() const override; + const Type_handler *type_handler_signed() const override; protocol_send_type_t protocol_send_type() const override { return PROTOCOL_SEND_SHORT; @@ -5074,11 +5083,7 @@ public: { return Item_send_short(item, protocol, buf); } - const Type_limits_int *type_limits_int_by_unsigned_flag(bool unsigned_fl) - const override - { - return unsigned_fl ? &m_limits_uint16 : &m_limits_sint16; - } + const Type_limits_int *type_limits_int() const override; uint32 max_display_length_for_field(const Conv_source &src) const override { return 6; } uint32 calc_pack_length(uint32 length) const override{ return 2; } @@ -5112,24 +5117,29 @@ public: }; +class Type_handler_ushort: public Type_handler_short +{ +public: + const Name name() const override; + uint flags() const override { return UNSIGNED_FLAG; } + const Type_limits_int *type_limits_int() const override; +}; + + class Type_handler_long: public Type_handler_general_purpose_int { static const Name m_name_int; - static const Type_limits_int m_limits_sint32; - static const Type_limits_int m_limits_uint32; public: virtual ~Type_handler_long() {} const Name name() const override { return m_name_int; } enum_field_types field_type() const override { return MYSQL_TYPE_LONG; } + const Type_handler *type_handler_unsigned() const override; + const Type_handler *type_handler_signed() const override; protocol_send_type_t protocol_send_type() const override { return PROTOCOL_SEND_LONG; } - const Type_limits_int *type_limits_int_by_unsigned_flag(bool unsigned_fl) - const override - { - return unsigned_fl ? &m_limits_uint32 : &m_limits_sint32; - } + const Type_limits_int *type_limits_int() const override; uint32 max_display_length_for_field(const Conv_source &src) const override { return 11; } uint32 calc_pack_length(uint32 length) const override { return 4; } @@ -5167,12 +5177,23 @@ public: }; +class Type_handler_ulong: public Type_handler_long +{ +public: + const Name name() const override; + uint flags() const override { return UNSIGNED_FLAG; } + const Type_limits_int *type_limits_int() const override; +}; + + class Type_handler_bool: public Type_handler_long { static const Name m_name_bool; public: const Name name() const override { return m_name_bool; } bool is_bool_type() const override { return true; } + const Type_handler *type_handler_unsigned() const override; + const Type_handler *type_handler_signed() const override; void Item_update_null_value(Item *item) const override; bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *) const override; }; @@ -5181,21 +5202,17 @@ public: class Type_handler_longlong: public Type_handler_general_purpose_int { static const Name m_name_longlong; - static const Type_limits_int m_limits_sint64; - static const Type_limits_int m_limits_uint64; public: virtual ~Type_handler_longlong() {} const Name name() const override{ return m_name_longlong; } enum_field_types field_type() const override{ return MYSQL_TYPE_LONGLONG; } + const Type_handler *type_handler_unsigned() const override; + const Type_handler *type_handler_signed() const override; protocol_send_type_t protocol_send_type() const override { return PROTOCOL_SEND_LONGLONG; } - const Type_limits_int *type_limits_int_by_unsigned_flag(bool unsigned_fl) - const override - { - return unsigned_fl ? &m_limits_uint64 : &m_limits_sint64; - } + const Type_limits_int *type_limits_int() const override; uint32 max_display_length_for_field(const Conv_source &src) const override { return 20; } uint32 calc_pack_length(uint32 length) const override { return 8; } @@ -5237,7 +5254,16 @@ public: }; -class Type_handler_vers_trx_id: public Type_handler_longlong +class Type_handler_ulonglong: public Type_handler_longlong +{ +public: + const Name name() const override; + uint flags() const override { return UNSIGNED_FLAG; } + const Type_limits_int *type_limits_int() const override; +}; + + +class Type_handler_vers_trx_id: public Type_handler_ulonglong { public: virtual ~Type_handler_vers_trx_id() {} @@ -5252,12 +5278,12 @@ public: class Type_handler_int24: public Type_handler_general_purpose_int { static const Name m_name_mediumint; - static const Type_limits_int m_limits_sint24; - static const Type_limits_int m_limits_uint24; public: virtual ~Type_handler_int24() {} const Name name() const override { return m_name_mediumint; } enum_field_types field_type() const override { return MYSQL_TYPE_INT24; } + const Type_handler *type_handler_unsigned() const override; + const Type_handler *type_handler_signed() const override; protocol_send_type_t protocol_send_type() const override { return PROTOCOL_SEND_LONG; @@ -5266,11 +5292,7 @@ public: { return Item_send_long(item, protocol, buf); } - const Type_limits_int *type_limits_int_by_unsigned_flag(bool unsigned_fl) - const override - { - return unsigned_fl ? &m_limits_uint24 : &m_limits_sint24; - } + const Type_limits_int *type_limits_int() const override; uint32 max_display_length_for_field(const Conv_source &src) const override { return 9; } uint32 calc_pack_length(uint32 length) const override { return 3; } @@ -5297,6 +5319,15 @@ public: }; +class Type_handler_uint24: public Type_handler_int24 +{ +public: + const Name name() const override; + uint flags() const override { return UNSIGNED_FLAG; } + const Type_limits_int *type_limits_int() const override; +}; + + class Type_handler_year: public Type_handler_int_result { static const Name m_name_year; @@ -6803,19 +6834,6 @@ public: { m_type_handler= other; } - const Type_handler *set_handler_by_result_type(Item_result type) - { - return (m_type_handler= Type_handler::get_handler_by_result_type(type)); - } - const Type_handler *set_handler_by_result_type(Item_result type, - uint max_octet_length, - CHARSET_INFO *cs) - { - m_type_handler= Type_handler::get_handler_by_result_type(type); - return m_type_handler= - m_type_handler->type_handler_adjusted_to_max_octet_length(max_octet_length, - cs); - } const Type_handler *set_handler_by_field_type(enum_field_types type) { return (m_type_handler= Type_handler::get_handler_by_field_type(type)); @@ -6864,12 +6882,17 @@ extern MYSQL_PLUGIN_IMPORT Type_handler_blob_compressed type_handler_blob_compressed; extern MYSQL_PLUGIN_IMPORT Type_handler_bool type_handler_bool; -extern MYSQL_PLUGIN_IMPORT Type_handler_tiny type_handler_tiny; -extern MYSQL_PLUGIN_IMPORT Type_handler_short type_handler_short; -extern MYSQL_PLUGIN_IMPORT Type_handler_int24 type_handler_int24; -extern MYSQL_PLUGIN_IMPORT Type_handler_long type_handler_long; -extern MYSQL_PLUGIN_IMPORT Type_handler_longlong type_handler_longlong; -extern MYSQL_PLUGIN_IMPORT Type_handler_longlong type_handler_ulonglong; +extern MYSQL_PLUGIN_IMPORT Type_handler_tiny type_handler_stiny; +extern MYSQL_PLUGIN_IMPORT Type_handler_short type_handler_sshort; +extern MYSQL_PLUGIN_IMPORT Type_handler_int24 type_handler_sint24; +extern MYSQL_PLUGIN_IMPORT Type_handler_long type_handler_slong; +extern MYSQL_PLUGIN_IMPORT Type_handler_longlong type_handler_slonglong; + +extern MYSQL_PLUGIN_IMPORT Type_handler_utiny type_handler_utiny; +extern MYSQL_PLUGIN_IMPORT Type_handler_ushort type_handler_ushort; +extern MYSQL_PLUGIN_IMPORT Type_handler_uint24 type_handler_uint24; +extern MYSQL_PLUGIN_IMPORT Type_handler_ulong type_handler_ulong; +extern MYSQL_PLUGIN_IMPORT Type_handler_ulonglong type_handler_ulonglong; extern MYSQL_PLUGIN_IMPORT Type_handler_vers_trx_id type_handler_vers_trx_id; extern MYSQL_PLUGIN_IMPORT Type_handler_newdecimal type_handler_newdecimal; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 8fce24bfc3e..c518bf7fccc 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1864,6 +1864,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ws_level_flag_desc ws_level_flag_reverse ws_level_flags opt_ws_levels ws_level_list ws_level_list_item ws_level_number ws_level_range ws_level_list_or_range bool + field_options last_field_options %type ulonglong_num real_ulonglong_num size_number @@ -2059,7 +2060,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); procedure_list procedure_list2 procedure_item field_def handler opt_generated_always opt_ignore opt_column opt_restrict - grant revoke set lock unlock string_list field_options + grant revoke set lock unlock string_list opt_binary table_lock_list table_lock ref_list opt_match_clause opt_on_update_delete use opt_delete_options opt_delete_option varchar nchar nvarchar @@ -6660,7 +6661,7 @@ field_type_or_serial: field_def | SERIAL_SYM { - Lex->last_field->set_handler(&type_handler_longlong); + Lex->last_field->set_handler(&type_handler_ulonglong); Lex->last_field->flags|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNSIGNED_FLAG | UNIQUE_KEY_FLAG; } @@ -6842,9 +6843,12 @@ field_type: ; field_type_numeric: - int_type opt_field_length field_options { $$.set($1, $2); } - | real_type opt_precision field_options { $$.set($1, $2); } - | FLOAT_SYM float_options field_options + int_type opt_field_length last_field_options + { + $$.set_handler_length_flags($1, $2, (uint32) $3); + } + | real_type opt_precision last_field_options { $$.set($1, $2); } + | FLOAT_SYM float_options last_field_options { $$.set(&type_handler_float, $2); if ($2.length() && !$2.dec()) @@ -6866,24 +6870,24 @@ field_type_numeric: } | BOOL_SYM { - $$.set(&type_handler_tiny, "1"); + $$.set(&type_handler_stiny, "1"); } | BOOLEAN_SYM { - $$.set(&type_handler_tiny, "1"); + $$.set(&type_handler_stiny, "1"); } - | DECIMAL_SYM float_options field_options + | DECIMAL_SYM float_options last_field_options { $$.set(&type_handler_newdecimal, $2);} - | NUMBER_ORACLE_SYM float_options field_options + | NUMBER_ORACLE_SYM float_options last_field_options { if ($2.length() != 0) $$.set(&type_handler_newdecimal, $2); else $$.set(&type_handler_double); } - | NUMERIC_SYM float_options field_options + | NUMERIC_SYM float_options last_field_options { $$.set(&type_handler_newdecimal, $2);} - | FIXED_SYM float_options field_options + | FIXED_SYM float_options last_field_options { $$.set(&type_handler_newdecimal, $2);} ; @@ -6936,7 +6940,7 @@ field_type_string: ; field_type_temporal: - YEAR_SYM opt_field_length field_options + YEAR_SYM opt_field_length last_field_options { if ($2) { @@ -7080,11 +7084,11 @@ nvarchar: ; int_type: - INT_SYM { $$= &type_handler_long; } - | TINYINT { $$= &type_handler_tiny; } - | SMALLINT { $$= &type_handler_short; } - | MEDIUMINT { $$= &type_handler_int24; } - | BIGINT { $$= &type_handler_longlong; } + INT_SYM { $$= &type_handler_slong; } + | TINYINT { $$= &type_handler_stiny; } + | SMALLINT { $$= &type_handler_sshort; } + | MEDIUMINT { $$= &type_handler_sint24; } + | BIGINT { $$= &type_handler_slonglong; } ; real_type: @@ -7119,12 +7123,16 @@ precision: ; field_options: - /* empty */ {} - | SIGNED_SYM {} - | UNSIGNED { Lex->last_field->flags|= UNSIGNED_FLAG;} - | ZEROFILL { Lex->last_field->flags|= UNSIGNED_FLAG | ZEROFILL_FLAG; } - | UNSIGNED ZEROFILL { Lex->last_field->flags|= UNSIGNED_FLAG | ZEROFILL_FLAG; } - | ZEROFILL UNSIGNED { Lex->last_field->flags|= UNSIGNED_FLAG | ZEROFILL_FLAG; } + /* empty */ { $$= 0; } + | SIGNED_SYM { $$= 0; } + | UNSIGNED { $$= UNSIGNED_FLAG; } + | ZEROFILL { $$= UNSIGNED_FLAG | ZEROFILL_FLAG; } + | UNSIGNED ZEROFILL { $$= UNSIGNED_FLAG | ZEROFILL_FLAG; } + | ZEROFILL UNSIGNED { $$= UNSIGNED_FLAG | ZEROFILL_FLAG; } + ; + +last_field_options: + field_options { Lex->last_field->flags|= ($$= $1); } ; field_length: @@ -11717,9 +11725,9 @@ cast_type: ; cast_type_numeric: - INT_SYM { $$.set(&type_handler_longlong); } - | SIGNED_SYM { $$.set(&type_handler_longlong); } - | SIGNED_SYM INT_SYM { $$.set(&type_handler_longlong); } + INT_SYM { $$.set(&type_handler_slonglong); } + | SIGNED_SYM { $$.set(&type_handler_slonglong); } + | SIGNED_SYM INT_SYM { $$.set(&type_handler_slonglong); } | UNSIGNED { $$.set(&type_handler_ulonglong); } | UNSIGNED INT_SYM { $$.set(&type_handler_ulonglong); } | DECIMAL_SYM float_options { $$.set(&type_handler_newdecimal, $2); } diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy index 290e13e16a0..bdefb76ad81 100644 --- a/sql/sql_yacc_ora.yy +++ b/sql/sql_yacc_ora.yy @@ -1337,6 +1337,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ws_level_flag_desc ws_level_flag_reverse ws_level_flags opt_ws_levels ws_level_list ws_level_list_item ws_level_number ws_level_range ws_level_list_or_range bool + field_options last_field_options %type ulonglong_num real_ulonglong_num size_number @@ -1534,7 +1535,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); procedure_list procedure_list2 procedure_item field_def handler opt_generated_always opt_ignore opt_column opt_restrict - grant revoke set lock unlock string_list field_options + grant revoke set lock unlock string_list opt_binary table_lock_list table_lock ref_list opt_match_clause opt_on_update_delete use opt_delete_options opt_delete_option varchar nchar nvarchar @@ -6659,7 +6660,7 @@ field_type_or_serial: field_def | SERIAL_SYM { - Lex->last_field->set_handler(&type_handler_longlong); + Lex->last_field->set_handler(&type_handler_ulonglong); Lex->last_field->flags|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNSIGNED_FLAG | UNIQUE_KEY_FLAG; } @@ -6851,9 +6852,12 @@ sp_param_field_type: field_type_numeric: - int_type opt_field_length field_options { $$.set($1, $2); } - | real_type opt_precision field_options { $$.set($1, $2); } - | FLOAT_SYM float_options field_options + int_type opt_field_length last_field_options + { + $$.set_handler_length_flags($1, $2, (uint32) $3); + } + | real_type opt_precision last_field_options { $$.set($1, $2); } + | FLOAT_SYM float_options last_field_options { $$.set(&type_handler_float, $2); if ($2.length() && !$2.dec()) @@ -6875,24 +6879,24 @@ field_type_numeric: } | BOOL_SYM { - $$.set(&type_handler_tiny, "1"); + $$.set(&type_handler_stiny, "1"); } | BOOLEAN_SYM { - $$.set(&type_handler_tiny, "1"); + $$.set(&type_handler_stiny, "1"); } - | DECIMAL_SYM float_options field_options + | DECIMAL_SYM float_options last_field_options { $$.set(&type_handler_newdecimal, $2);} - | NUMBER_ORACLE_SYM float_options field_options + | NUMBER_ORACLE_SYM float_options last_field_options { if ($2.length() != 0) $$.set(&type_handler_newdecimal, $2); else $$.set(&type_handler_double); } - | NUMERIC_SYM float_options field_options + | NUMERIC_SYM float_options last_field_options { $$.set(&type_handler_newdecimal, $2);} - | FIXED_SYM float_options field_options + | FIXED_SYM float_options last_field_options { $$.set(&type_handler_newdecimal, $2);} ; @@ -6987,7 +6991,7 @@ sp_param_field_type_string: field_type_temporal: - YEAR_SYM opt_field_length field_options + YEAR_SYM opt_field_length last_field_options { if ($2) { @@ -7131,11 +7135,11 @@ nvarchar: ; int_type: - INT_SYM { $$= &type_handler_long; } - | TINYINT { $$= &type_handler_tiny; } - | SMALLINT { $$= &type_handler_short; } - | MEDIUMINT { $$= &type_handler_int24; } - | BIGINT { $$= &type_handler_longlong; } + INT_SYM { $$= &type_handler_slong; } + | TINYINT { $$= &type_handler_stiny; } + | SMALLINT { $$= &type_handler_sshort; } + | MEDIUMINT { $$= &type_handler_sint24; } + | BIGINT { $$= &type_handler_slonglong; } ; real_type: @@ -7170,12 +7174,16 @@ precision: ; field_options: - /* empty */ {} - | SIGNED_SYM {} - | UNSIGNED { Lex->last_field->flags|= UNSIGNED_FLAG;} - | ZEROFILL { Lex->last_field->flags|= UNSIGNED_FLAG | ZEROFILL_FLAG; } - | UNSIGNED ZEROFILL { Lex->last_field->flags|= UNSIGNED_FLAG | ZEROFILL_FLAG; } - | ZEROFILL UNSIGNED { Lex->last_field->flags|= UNSIGNED_FLAG | ZEROFILL_FLAG; } + /* empty */ { $$= 0; } + | SIGNED_SYM { $$= 0; } + | UNSIGNED { $$= UNSIGNED_FLAG; } + | ZEROFILL { $$= UNSIGNED_FLAG | ZEROFILL_FLAG; } + | UNSIGNED ZEROFILL { $$= UNSIGNED_FLAG | ZEROFILL_FLAG; } + | ZEROFILL UNSIGNED { $$= UNSIGNED_FLAG | ZEROFILL_FLAG; } + ; + +last_field_options: + field_options { Lex->last_field->flags|= ($$= $1); } ; field_length: @@ -11817,9 +11825,9 @@ cast_type: ; cast_type_numeric: - INT_SYM { $$.set(&type_handler_longlong); } - | SIGNED_SYM { $$.set(&type_handler_longlong); } - | SIGNED_SYM INT_SYM { $$.set(&type_handler_longlong); } + INT_SYM { $$.set(&type_handler_slonglong); } + | SIGNED_SYM { $$.set(&type_handler_slonglong); } + | SIGNED_SYM INT_SYM { $$.set(&type_handler_slonglong); } | UNSIGNED { $$.set(&type_handler_ulonglong); } | UNSIGNED INT_SYM { $$.set(&type_handler_ulonglong); } | DECIMAL_SYM float_options { $$.set(&type_handler_newdecimal, $2); } diff --git a/sql/structs.h b/sql/structs.h index 0c00aeec33a..f6d63051dfe 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -618,6 +618,8 @@ public: m_handler= handler; Lex_length_and_dec_st::operator=(length_and_dec); } + void set_handler_length_flags(const Type_handler *handler, const char *length, + uint32 flags); void set(const Type_handler *handler, const char *length) { set(handler, length, 0); -- cgit v1.2.1