diff options
-rw-r--r-- | mysql-test/main/sp-row.result | 32 | ||||
-rw-r--r-- | mysql-test/main/type_int.result | 117 | ||||
-rw-r--r-- | mysql-test/main/type_int.test | 74 | ||||
-rw-r--r-- | mysql-test/suite/compat/oracle/r/sp-row.result | 32 | ||||
-rw-r--r-- | sql/field.h | 74 | ||||
-rw-r--r-- | sql/sql_type.cc | 22 | ||||
-rw-r--r-- | sql/sql_type.h | 162 |
7 files changed, 420 insertions, 93 deletions
diff --git a/mysql-test/main/sp-row.result b/mysql-test/main/sp-row.result index 295a881f9e4..ac09f7572c3 100644 --- a/mysql-test/main/sp-row.result +++ b/mysql-test/main/sp-row.result @@ -1286,8 +1286,8 @@ CALL p1(); SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `var` mediumint(9) DEFAULT NULL, - `rec.var` mediumint(9) DEFAULT NULL + `var` mediumint(8) DEFAULT NULL, + `rec.var` mediumint(8) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; DROP PROCEDURE p1; @@ -1296,8 +1296,8 @@ CALL p1(); SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `var` mediumint(9) DEFAULT NULL, - `rec.var` mediumint(9) DEFAULT NULL + `var` mediumint(8) DEFAULT NULL, + `rec.var` mediumint(8) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; DROP PROCEDURE p1; @@ -1306,8 +1306,8 @@ CALL p1(); SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `var` mediumint(9) DEFAULT NULL, - `rec.var` mediumint(9) DEFAULT NULL + `var` mediumint(8) DEFAULT NULL, + `rec.var` mediumint(8) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; DROP PROCEDURE p1; @@ -1316,8 +1316,8 @@ CALL p1(); SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `var` mediumint(9) DEFAULT NULL, - `rec.var` mediumint(9) DEFAULT NULL + `var` mediumint(8) DEFAULT NULL, + `rec.var` mediumint(8) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; DROP PROCEDURE p1; @@ -1326,8 +1326,8 @@ CALL p1(); SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `var` mediumint(9) DEFAULT NULL, - `rec.var` mediumint(9) DEFAULT NULL + `var` mediumint(8) DEFAULT NULL, + `rec.var` mediumint(8) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; DROP PROCEDURE p1; @@ -1336,8 +1336,8 @@ CALL p1(); SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `var` mediumint(9) DEFAULT NULL, - `rec.var` mediumint(9) DEFAULT NULL + `var` mediumint(8) DEFAULT NULL, + `rec.var` mediumint(8) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; DROP PROCEDURE p1; @@ -1346,8 +1346,8 @@ CALL p1(); SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `var` mediumint(9) DEFAULT NULL, - `rec.var` mediumint(9) DEFAULT NULL + `var` mediumint(8) DEFAULT NULL, + `rec.var` mediumint(8) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; DROP PROCEDURE p1; @@ -1356,8 +1356,8 @@ CALL p1(); SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `var` mediumint(9) DEFAULT NULL, - `rec.var` mediumint(9) DEFAULT NULL + `var` mediumint(8) DEFAULT NULL, + `rec.var` mediumint(8) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; DROP PROCEDURE p1; diff --git a/mysql-test/main/type_int.result b/mysql-test/main/type_int.result index bd24641fd65..47c859d3ffb 100644 --- a/mysql-test/main/type_int.result +++ b/mysql-test/main/type_int.result @@ -106,5 +106,122 @@ a 7 b 8 DROP TABLE t1; # +# MDEV-15946 MEDIUMINT(N<8) creates a wrong data type on conversion to string +# +CREATE TABLE t1 ( +uint8 TINYINT(2) UNSIGNED, sint8 TINYINT(2), +uint16 SMALLINT(2) UNSIGNED, sint16 SMALLINT(2), +uint24 MEDIUMINT(2) UNSIGNED, sint24 MEDIUMINT(2), +uint32 INT(2) UNSIGNED, sint32 INT(2), +uint64 BIGINT(2) UNSIGNED, sint64 BIGINT(2) +); +CREATE TABLE t2 AS SELECT +CONCAT(uint8),CONCAT(sint8), +CONCAT(uint16),CONCAT(sint16), +CONCAT(uint24),CONCAT(sint24), +CONCAT(uint32),CONCAT(sint32), +CONCAT(uint64),CONCAT(sint64) +FROM t1; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `CONCAT(uint8)` varchar(3) DEFAULT NULL, + `CONCAT(sint8)` varchar(4) DEFAULT NULL, + `CONCAT(uint16)` varchar(5) DEFAULT NULL, + `CONCAT(sint16)` varchar(6) DEFAULT NULL, + `CONCAT(uint24)` varchar(8) DEFAULT NULL, + `CONCAT(sint24)` varchar(8) DEFAULT NULL, + `CONCAT(uint32)` varchar(10) DEFAULT NULL, + `CONCAT(sint32)` varchar(11) DEFAULT NULL, + `CONCAT(uint64)` varchar(20) DEFAULT NULL, + `CONCAT(sint64)` varchar(20) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t2; +CREATE TABLE t2 AS SELECT +CONCAT(COALESCE(uint8)),CONCAT(COALESCE(sint8)), +CONCAT(COALESCE(uint16)),CONCAT(COALESCE(sint16)), +CONCAT(COALESCE(uint24)),CONCAT(COALESCE(sint24)), +CONCAT(COALESCE(uint32)),CONCAT(COALESCE(sint32)), +CONCAT(COALESCE(uint64)),CONCAT(COALESCE(sint64)) +FROM t1; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `CONCAT(COALESCE(uint8))` varchar(3) DEFAULT NULL, + `CONCAT(COALESCE(sint8))` varchar(4) DEFAULT NULL, + `CONCAT(COALESCE(uint16))` varchar(5) DEFAULT NULL, + `CONCAT(COALESCE(sint16))` varchar(6) DEFAULT NULL, + `CONCAT(COALESCE(uint24))` varchar(8) DEFAULT NULL, + `CONCAT(COALESCE(sint24))` varchar(8) DEFAULT NULL, + `CONCAT(COALESCE(uint32))` varchar(10) DEFAULT NULL, + `CONCAT(COALESCE(sint32))` varchar(11) DEFAULT NULL, + `CONCAT(COALESCE(uint64))` varchar(20) DEFAULT NULL, + `CONCAT(COALESCE(sint64))` varchar(20) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t2; +DROP TABLE t1; +CREATE FUNCTION uint8() RETURNS TINYINT(2) UNSIGNED RETURN 1; +CREATE FUNCTION sint8() RETURNS TINYINT(2) RETURN 1; +CREATE FUNCTION uint16() RETURNS SMALLINT(2) UNSIGNED RETURN 1; +CREATE FUNCTION sint16() RETURNS SMALLINT(2) RETURN 1; +CREATE FUNCTION uint24() RETURNS MEDIUMINT(2) UNSIGNED RETURN 1; +CREATE FUNCTION sint24() RETURNS MEDIUMINT(2) RETURN 1; +CREATE FUNCTION uint32() RETURNS INT(2) UNSIGNED RETURN 1; +CREATE FUNCTION sint32() RETURNS INT(2) RETURN 1; +CREATE FUNCTION uint64() RETURNS BIGINT(2) UNSIGNED RETURN 1; +CREATE FUNCTION sint64() RETURNS BIGINT(2) RETURN 1; +CREATE TABLE t1 AS SELECT +CONCAT(uint8()), CONCAT(sint8()), +CONCAT(uint16()),CONCAT(sint16()), +CONCAT(uint24()),CONCAT(sint24()), +CONCAT(uint32()),CONCAT(sint32()), +CONCAT(uint64()),CONCAT(sint64()); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `CONCAT(uint8())` varchar(3) DEFAULT NULL, + `CONCAT(sint8())` varchar(4) DEFAULT NULL, + `CONCAT(uint16())` varchar(5) DEFAULT NULL, + `CONCAT(sint16())` varchar(6) DEFAULT NULL, + `CONCAT(uint24())` varchar(8) DEFAULT NULL, + `CONCAT(sint24())` varchar(8) DEFAULT NULL, + `CONCAT(uint32())` varchar(10) DEFAULT NULL, + `CONCAT(sint32())` varchar(11) DEFAULT NULL, + `CONCAT(uint64())` varchar(20) DEFAULT NULL, + `CONCAT(sint64())` varchar(20) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT +CONCAT(COALESCE(uint8())),CONCAT(COALESCE(sint8())), +CONCAT(COALESCE(uint16())),CONCAT(COALESCE(sint16())), +CONCAT(COALESCE(uint24())),CONCAT(COALESCE(sint24())), +CONCAT(COALESCE(uint32())),CONCAT(COALESCE(sint32())), +CONCAT(COALESCE(uint64())),CONCAT(COALESCE(sint64())); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `CONCAT(COALESCE(uint8()))` varchar(3) DEFAULT NULL, + `CONCAT(COALESCE(sint8()))` varchar(4) DEFAULT NULL, + `CONCAT(COALESCE(uint16()))` varchar(5) DEFAULT NULL, + `CONCAT(COALESCE(sint16()))` varchar(6) DEFAULT NULL, + `CONCAT(COALESCE(uint24()))` varchar(8) DEFAULT NULL, + `CONCAT(COALESCE(sint24()))` varchar(8) DEFAULT NULL, + `CONCAT(COALESCE(uint32()))` varchar(10) DEFAULT NULL, + `CONCAT(COALESCE(sint32()))` varchar(11) DEFAULT NULL, + `CONCAT(COALESCE(uint64()))` varchar(20) DEFAULT NULL, + `CONCAT(COALESCE(sint64()))` varchar(20) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +DROP FUNCTION uint8; +DROP FUNCTION sint8; +DROP FUNCTION uint16; +DROP FUNCTION sint16; +DROP FUNCTION uint24; +DROP FUNCTION sint24; +DROP FUNCTION uint32; +DROP FUNCTION sint32; +DROP FUNCTION uint64; +DROP FUNCTION sint64; +# # End of 10.3 tests # diff --git a/mysql-test/main/type_int.test b/mysql-test/main/type_int.test index f0df08ffa2c..bcab2b20dc4 100644 --- a/mysql-test/main/type_int.test +++ b/mysql-test/main/type_int.test @@ -91,5 +91,79 @@ DROP TABLE t1; --echo # +--echo # MDEV-15946 MEDIUMINT(N<8) creates a wrong data type on conversion to string +--echo # + +CREATE TABLE t1 ( + uint8 TINYINT(2) UNSIGNED, sint8 TINYINT(2), + uint16 SMALLINT(2) UNSIGNED, sint16 SMALLINT(2), + uint24 MEDIUMINT(2) UNSIGNED, sint24 MEDIUMINT(2), + uint32 INT(2) UNSIGNED, sint32 INT(2), + uint64 BIGINT(2) UNSIGNED, sint64 BIGINT(2) +); + +CREATE TABLE t2 AS SELECT + CONCAT(uint8),CONCAT(sint8), + CONCAT(uint16),CONCAT(sint16), + CONCAT(uint24),CONCAT(sint24), + CONCAT(uint32),CONCAT(sint32), + CONCAT(uint64),CONCAT(sint64) +FROM t1; +SHOW CREATE TABLE t2; +DROP TABLE t2; + +CREATE TABLE t2 AS SELECT + CONCAT(COALESCE(uint8)),CONCAT(COALESCE(sint8)), + CONCAT(COALESCE(uint16)),CONCAT(COALESCE(sint16)), + CONCAT(COALESCE(uint24)),CONCAT(COALESCE(sint24)), + CONCAT(COALESCE(uint32)),CONCAT(COALESCE(sint32)), + CONCAT(COALESCE(uint64)),CONCAT(COALESCE(sint64)) +FROM t1; +SHOW CREATE TABLE t2; +DROP TABLE t2; + +DROP TABLE t1; + +CREATE FUNCTION uint8() RETURNS TINYINT(2) UNSIGNED RETURN 1; +CREATE FUNCTION sint8() RETURNS TINYINT(2) RETURN 1; +CREATE FUNCTION uint16() RETURNS SMALLINT(2) UNSIGNED RETURN 1; +CREATE FUNCTION sint16() RETURNS SMALLINT(2) RETURN 1; +CREATE FUNCTION uint24() RETURNS MEDIUMINT(2) UNSIGNED RETURN 1; +CREATE FUNCTION sint24() RETURNS MEDIUMINT(2) RETURN 1; +CREATE FUNCTION uint32() RETURNS INT(2) UNSIGNED RETURN 1; +CREATE FUNCTION sint32() RETURNS INT(2) RETURN 1; +CREATE FUNCTION uint64() RETURNS BIGINT(2) UNSIGNED RETURN 1; +CREATE FUNCTION sint64() RETURNS BIGINT(2) RETURN 1; + +CREATE TABLE t1 AS SELECT + CONCAT(uint8()), CONCAT(sint8()), + CONCAT(uint16()),CONCAT(sint16()), + CONCAT(uint24()),CONCAT(sint24()), + CONCAT(uint32()),CONCAT(sint32()), + CONCAT(uint64()),CONCAT(sint64()); +SHOW CREATE TABLE t1; +DROP TABLE t1; + +CREATE TABLE t1 AS SELECT + CONCAT(COALESCE(uint8())),CONCAT(COALESCE(sint8())), + CONCAT(COALESCE(uint16())),CONCAT(COALESCE(sint16())), + CONCAT(COALESCE(uint24())),CONCAT(COALESCE(sint24())), + CONCAT(COALESCE(uint32())),CONCAT(COALESCE(sint32())), + CONCAT(COALESCE(uint64())),CONCAT(COALESCE(sint64())); +SHOW CREATE TABLE t1; +DROP TABLE t1; + +DROP FUNCTION uint8; +DROP FUNCTION sint8; +DROP FUNCTION uint16; +DROP FUNCTION sint16; +DROP FUNCTION uint24; +DROP FUNCTION sint24; +DROP FUNCTION uint32; +DROP FUNCTION sint32; +DROP FUNCTION uint64; +DROP FUNCTION sint64; + +--echo # --echo # End of 10.3 tests --echo # diff --git a/mysql-test/suite/compat/oracle/r/sp-row.result b/mysql-test/suite/compat/oracle/r/sp-row.result index 4ca403431c3..72b33768864 100644 --- a/mysql-test/suite/compat/oracle/r/sp-row.result +++ b/mysql-test/suite/compat/oracle/r/sp-row.result @@ -1363,8 +1363,8 @@ CALL p1(); SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE "t1" ( - "var" mediumint(9) DEFAULT NULL, - "rec.var" mediumint(9) DEFAULT NULL + "var" mediumint(8) DEFAULT NULL, + "rec.var" mediumint(8) DEFAULT NULL ) DROP TABLE t1; DROP PROCEDURE p1; @@ -1373,8 +1373,8 @@ CALL p1(); SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE "t1" ( - "var" mediumint(9) DEFAULT NULL, - "rec.var" mediumint(9) DEFAULT NULL + "var" mediumint(8) DEFAULT NULL, + "rec.var" mediumint(8) DEFAULT NULL ) DROP TABLE t1; DROP PROCEDURE p1; @@ -1383,8 +1383,8 @@ CALL p1(); SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE "t1" ( - "var" mediumint(9) DEFAULT NULL, - "rec.var" mediumint(9) DEFAULT NULL + "var" mediumint(8) DEFAULT NULL, + "rec.var" mediumint(8) DEFAULT NULL ) DROP TABLE t1; DROP PROCEDURE p1; @@ -1393,8 +1393,8 @@ CALL p1(); SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE "t1" ( - "var" mediumint(9) DEFAULT NULL, - "rec.var" mediumint(9) DEFAULT NULL + "var" mediumint(8) DEFAULT NULL, + "rec.var" mediumint(8) DEFAULT NULL ) DROP TABLE t1; DROP PROCEDURE p1; @@ -1403,8 +1403,8 @@ CALL p1(); SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE "t1" ( - "var" mediumint(9) DEFAULT NULL, - "rec.var" mediumint(9) DEFAULT NULL + "var" mediumint(8) DEFAULT NULL, + "rec.var" mediumint(8) DEFAULT NULL ) DROP TABLE t1; DROP PROCEDURE p1; @@ -1413,8 +1413,8 @@ CALL p1(); SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE "t1" ( - "var" mediumint(9) DEFAULT NULL, - "rec.var" mediumint(9) DEFAULT NULL + "var" mediumint(8) DEFAULT NULL, + "rec.var" mediumint(8) DEFAULT NULL ) DROP TABLE t1; DROP PROCEDURE p1; @@ -1423,8 +1423,8 @@ CALL p1(); SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE "t1" ( - "var" mediumint(9) DEFAULT NULL, - "rec.var" mediumint(9) DEFAULT NULL + "var" mediumint(8) DEFAULT NULL, + "rec.var" mediumint(8) DEFAULT NULL ) DROP TABLE t1; DROP PROCEDURE p1; @@ -1433,8 +1433,8 @@ CALL p1(); SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE "t1" ( - "var" mediumint(9) DEFAULT NULL, - "rec.var" mediumint(9) DEFAULT NULL + "var" mediumint(8) DEFAULT NULL, + "rec.var" mediumint(8) DEFAULT NULL ) DROP TABLE t1; DROP PROCEDURE p1; diff --git a/sql/field.h b/sql/field.h index 6fb5c0c0f37..fd097e02074 100644 --- a/sql/field.h +++ b/sql/field.h @@ -777,6 +777,8 @@ public: dtcollation()); } + bool is_unsigned() const { return flags & UNSIGNED_FLAG; } + /** Convenience definition of a copy function returned by Field::get_copy_func() @@ -1983,7 +1985,6 @@ class Field_int :public Field_num protected: String *val_str_from_long(String *val_buffer, uint max_char_length, int radix, long nr); - uint32 sign_length() const { return (flags & UNSIGNED_FLAG) ? 0 : 1; } public: Field_int(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, @@ -1996,7 +1997,11 @@ public: bool val_bool() { return val_int() != 0; } int store_time_dec(const MYSQL_TIME *ltime, uint dec); bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate); - virtual uint numeric_precision() const= 0; + virtual const Type_limits_int *type_limits_int() const= 0; + uint32 max_display_length() const + { + return type_limits_int()->char_length(); + } Type_std_attributes type_std_attributes() const { /* @@ -2018,7 +2023,8 @@ public: Information_schema_numeric_attributes information_schema_numeric_attributes() const { - return Information_schema_numeric_attributes(numeric_precision(), 0); + uint32 prec= type_limits_int()->precision(); + return Information_schema_numeric_attributes(prec, 0); } }; @@ -2048,17 +2054,9 @@ public: void sort_string(uchar *buff,uint length); uint32 pack_length() const { return 1; } void sql_type(String &str) const; - /* - SIGNED: -128..127 digits=3 nchars=4 - UNDIGNED: 0..255 digits=3 nchars=3 - */ - uint numeric_precision() const - { - return MAX_TINYINT_WIDTH; - } - uint32 max_display_length() const + const Type_limits_int *type_limits_int() const { - return MAX_TINYINT_WIDTH + sign_length(); + return type_handler_tiny.type_limits_int_by_unsigned_flag(is_unsigned()); } virtual uchar *pack(uchar* to, const uchar *from, uint max_length) @@ -2109,19 +2107,10 @@ public: void sort_string(uchar *buff,uint length); uint32 pack_length() const { return 2; } void sql_type(String &str) const; - /* - SIGNED: -32768..32767 digits=5 nchars=6 - UNDIGNED: 0..65535 digits=5 nchars=5 - */ - uint numeric_precision() const - { - return MAX_SMALLINT_WIDTH; - } - uint32 max_display_length() const + const Type_limits_int *type_limits_int() const { - return MAX_SMALLINT_WIDTH + sign_length(); + return type_handler_short.type_limits_int_by_unsigned_flag(is_unsigned()); } - virtual uchar *pack(uchar* to, const uchar *from, uint max_length) { return pack_int16(to, from); } @@ -2155,22 +2144,10 @@ public: void sort_string(uchar *buff,uint length); uint32 pack_length() const { return 3; } void sql_type(String &str) const; - /* - MEDIUMINT has a different number of digits for signed and unsigned: - MEDIUMINT SIGNED: -8388608 .. 8388607 digits=7 char_length=8 - MEDIUMINT UNSIGNED 0 .. 16777215 digits=8 char_length=8 - */ - uint numeric_precision() const + const Type_limits_int *type_limits_int() const { - uint ndigits= MAX_MEDIUMINT_WIDTH - 1 + MY_TEST(flags & UNSIGNED_FLAG); - return ndigits; + return type_handler_int24.type_limits_int_by_unsigned_flag(is_unsigned()); } - uint32 max_display_length() const - { - // Looks too long for SIGNED: See MDEV-15946 - return MAX_MEDIUMINT_WIDTH + sign_length(); - } - virtual uchar *pack(uchar* to, const uchar *from, uint max_length) { return Field::pack(to, from, max_length); @@ -2209,17 +2186,9 @@ public: void sort_string(uchar *buff,uint length); uint32 pack_length() const { return 4; } void sql_type(String &str) const; - /* - SIGNED: -2147483648..2147483647 digits=10 nchars=11 - UNSIGNED: 0..4294967295 digits=10 nchars=10 - */ - uint numeric_precision() const + const Type_limits_int *type_limits_int() const { - return MAX_INT_WIDTH; - } - uint32 max_display_length() const - { - return MAX_INT_WIDTH + sign_length(); + return type_handler_long.type_limits_int_by_unsigned_flag(is_unsigned()); } virtual uchar *pack(uchar* to, const uchar *from, uint max_length __attribute__((unused))) @@ -2270,15 +2239,10 @@ public: void sort_string(uchar *buff,uint length); uint32 pack_length() const { return 8; } void sql_type(String &str) const; - /* - SIGNED: -9223372036854775808..9223372036854775807 digits=19 nchars=20 - UNSIGNED: 0..18446744073709551615 digits=20 nchars=20 - */ - uint numeric_precision() const + const Type_limits_int *type_limits_int() const { - return MAX_BIGINT_WIDTH - sign_length(); + return type_handler_longlong.type_limits_int_by_unsigned_flag(is_unsigned()); } - uint32 max_display_length() const { return MAX_BIGINT_WIDTH; } virtual uchar *pack(uchar* to, const uchar *from, uint max_length __attribute__((unused))) { diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 51c94ae8743..fe5ce3f8b9f 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -465,6 +465,20 @@ 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 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_handler *Type_handler_null::type_handler_for_comparison() const @@ -2488,6 +2502,14 @@ uint32 Type_handler_bit::max_display_length(const Item *item) const return item->max_length; } + +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(); +} + + /*************************************************************************/ int Type_handler_time_common::Item_save_in_field(Item *item, Field *field, diff --git a/sql/sql_type.h b/sql/sql_type.h index ad04c732982..16db421a4d3 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -1904,6 +1904,131 @@ public: }; +class Type_limits_int +{ +private: + uint32 m_precision; + uint32 m_char_length; +public: + Type_limits_int(uint32 prec, uint32 nchars) + :m_precision(prec), m_char_length(nchars) + { } + uint32 precision() const { return m_precision; } + uint32 char_length() const { return m_char_length; } +}; + + +/* + UNDIGNED TINYINT: 0..255 digits=3 nchars=3 + SIGNED TINYINT : -128..127 digits=3 nchars=4 +*/ +class Type_limits_uint8: public Type_limits_int +{ +public: + Type_limits_uint8() + :Type_limits_int(MAX_TINYINT_WIDTH, MAX_TINYINT_WIDTH) + { } +}; + + +class Type_limits_sint8: public Type_limits_int +{ +public: + Type_limits_sint8() + :Type_limits_int(MAX_TINYINT_WIDTH, MAX_TINYINT_WIDTH + 1) + { } +}; + + +/* + UNDIGNED SMALLINT: 0..65535 digits=5 nchars=5 + SIGNED SMALLINT: -32768..32767 digits=5 nchars=6 +*/ +class Type_limits_uint16: public Type_limits_int +{ +public: + Type_limits_uint16() + :Type_limits_int(MAX_SMALLINT_WIDTH, MAX_SMALLINT_WIDTH) + { } +}; + + +class Type_limits_sint16: public Type_limits_int +{ +public: + Type_limits_sint16() + :Type_limits_int(MAX_SMALLINT_WIDTH, MAX_SMALLINT_WIDTH + 1) + { } +}; + + +/* + MEDIUMINT UNSIGNED 0 .. 16777215 digits=8 char_length=8 + MEDIUMINT SIGNED: -8388608 .. 8388607 digits=7 char_length=8 +*/ +class Type_limits_uint24: public Type_limits_int +{ +public: + Type_limits_uint24() + :Type_limits_int(MAX_MEDIUMINT_WIDTH, MAX_MEDIUMINT_WIDTH) + { } +}; + + +class Type_limits_sint24: public Type_limits_int +{ +public: + Type_limits_sint24() + :Type_limits_int(MAX_MEDIUMINT_WIDTH - 1, MAX_MEDIUMINT_WIDTH) + { } +}; + + +/* + UNSIGNED INT: 0..4294967295 digits=10 nchars=10 + SIGNED INT: -2147483648..2147483647 digits=10 nchars=11 +*/ +class Type_limits_uint32: public Type_limits_int +{ +public: + Type_limits_uint32() + :Type_limits_int(MAX_INT_WIDTH, MAX_INT_WIDTH) + { } +}; + + + +class Type_limits_sint32: public Type_limits_int +{ +public: + Type_limits_sint32() + :Type_limits_int(MAX_INT_WIDTH, MAX_INT_WIDTH + 1) + { } +}; + + +/* + UNSIGNED BIGINT: 0..18446744073709551615 digits=20 nchars=20 + SIGNED BIGINT: -9223372036854775808..9223372036854775807 digits=19 nchars=20 +*/ +class Type_limits_uint64: public Type_limits_int +{ +public: + Type_limits_uint64(): Type_limits_int(MAX_BIGINT_WIDTH, MAX_BIGINT_WIDTH) + { } +}; + + +class Type_limits_sint64: public Type_limits_int +{ +public: + Type_limits_sint64() + :Type_limits_int(MAX_BIGINT_WIDTH - 1, MAX_BIGINT_WIDTH) + { } +}; + + + class Type_handler_int_result: public Type_handler_numeric { public: @@ -1977,6 +2102,9 @@ 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; }; @@ -2196,11 +2324,16 @@ 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 { return m_name_tiny; } enum_field_types field_type() const { return MYSQL_TYPE_TINY; } - uint32 max_display_length(const Item *item) const { return 4; } + const Type_limits_int *type_limits_int_by_unsigned_flag(bool unsigned_fl) const + { + return unsigned_fl ? &m_limits_uint8 : &m_limits_sint8; + } uint32 calc_pack_length(uint32 length) const { return 1; } bool Item_send(Item *item, Protocol *protocol, st_value *buf) const { @@ -2225,6 +2358,8 @@ public: 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 { return m_name_short; } @@ -2233,7 +2368,10 @@ public: { return Item_send_short(item, protocol, buf); } - uint32 max_display_length(const Item *item) const { return 6; } + const Type_limits_int *type_limits_int_by_unsigned_flag(bool unsigned_fl) const + { + return unsigned_fl ? &m_limits_uint16 : &m_limits_sint16; + } uint32 calc_pack_length(uint32 length) const { return 2; } Field *make_conversion_table_field(TABLE *TABLE, uint metadata, const Field *target) const; @@ -2254,13 +2392,15 @@ public: 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 { return m_name_int; } enum_field_types field_type() const { return MYSQL_TYPE_LONG; } - uint32 max_display_length(const Item *item) const + const Type_limits_int *type_limits_int_by_unsigned_flag(bool unsigned_fl) const { - return MY_INT32_NUM_DECIMAL_DIGITS; + return unsigned_fl ? &m_limits_uint32 : &m_limits_sint32; } uint32 calc_pack_length(uint32 length) const { return 4; } bool Item_send(Item *item, Protocol *protocol, st_value *buf) const @@ -2286,11 +2426,16 @@ 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 { return m_name_longlong; } enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; } - uint32 max_display_length(const Item *item) const { return 20; } + const Type_limits_int *type_limits_int_by_unsigned_flag(bool unsigned_fl) const + { + return unsigned_fl ? &m_limits_uint64 : &m_limits_sint64; + } uint32 calc_pack_length(uint32 length) const { return 8; } Item *create_typecast_item(THD *thd, Item *item, const Type_cast_attributes &attr) const; @@ -2330,6 +2475,8 @@ 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 { return m_name_mediumint; } @@ -2338,7 +2485,10 @@ public: { return Item_send_long(item, protocol, buf); } - uint32 max_display_length(const Item *item) const { return 8; } + const Type_limits_int *type_limits_int_by_unsigned_flag(bool unsigned_fl) const + { + return unsigned_fl ? &m_limits_uint24 : &m_limits_sint24; + } uint32 calc_pack_length(uint32 length) const { return 3; } Field *make_conversion_table_field(TABLE *, uint metadata, const Field *target) const; |