summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2019-08-15 13:16:00 +0400
committerAlexander Barkov <bar@mariadb.com>2019-08-15 21:53:24 +0400
commit6073049a3675363f7d7efe26f47525b528be9e2f (patch)
treed7151b02c0f1a291e1bad7b994b2dc3982eb783c
parentae4b9b7689c49b8b8bf61d1762f452e0f14cad22 (diff)
downloadmariadb-git-6073049a3675363f7d7efe26f47525b528be9e2f.tar.gz
MDEV-20353 Add separate type handlers for unsigned integer data types
-rw-r--r--mysql-test/main/func_debug.result8
-rw-r--r--mysql-test/main/func_hybrid_type.result181
-rw-r--r--mysql-test/main/func_hybrid_type.test232
-rw-r--r--mysql-test/main/gis.result4
-rw-r--r--sql/field.h59
-rw-r--r--sql/handler.cc3
-rw-r--r--sql/item.h11
-rw-r--r--sql/item_cmpfunc.cc4
-rw-r--r--sql/item_cmpfunc.h2
-rw-r--r--sql/item_func.cc19
-rw-r--r--sql/item_func.h35
-rw-r--r--sql/item_sum.h13
-rw-r--r--sql/item_timefunc.h10
-rw-r--r--sql/item_windowfunc.h11
-rw-r--r--sql/procedure.h6
-rw-r--r--sql/rpl_utility_server.cc10
-rw-r--r--sql/sql_i_s.h12
-rw-r--r--sql/sql_lex.cc17
-rw-r--r--sql/sql_prepare.cc2
-rw-r--r--sql/sql_select.cc9
-rw-r--r--sql/sql_sequence.cc18
-rw-r--r--sql/sql_table.cc6
-rw-r--r--sql/sql_type.cc277
-rw-r--r--sql/sql_type.h159
-rw-r--r--sql/sql_yacc.yy60
-rw-r--r--sql/sql_yacc_ora.yy60
-rw-r--r--sql/structs.h2
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
@@ -844,5 +844,237 @@ SELECT COALESCE(a,b) FROM t1;
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<Item> &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<Item_func_hash>(thd, this); }
const char *func_name() const { return "<hash>"; }
@@ -1052,7 +1057,12 @@ public:
Item_int_func(thd, a, b, c, d) {}
Item_longlong_func(THD *thd, List<Item> &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<Item_func_udf_int>(thd, this); }
@@ -2523,7 +2540,7 @@ public:
Item_int_func(thd) {}
Item_func_udf_int(THD *thd, udf_func *udf_arg, List<Item> &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<Item> &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<Item_sum_ntile>(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_field> *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,26 +1426,175 @@ 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_number>
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_number>
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);