summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/main/sp-row.result32
-rw-r--r--mysql-test/main/type_int.result117
-rw-r--r--mysql-test/main/type_int.test74
-rw-r--r--mysql-test/suite/compat/oracle/r/sp-row.result32
-rw-r--r--sql/field.h74
-rw-r--r--sql/sql_type.cc22
-rw-r--r--sql/sql_type.h162
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;