Fixing a few problems with data type and metadata for INT result functions (MDEV-12852, MDEV-12853, MDEV-12869)
This is a joint patch for: MDEV-12852 Out-of-range errors when CAST(1-2 AS UNSIGNED MDEV-12853 Out-of-range errors when CAST('-1' AS UNSIGNED MDEV-12869 Wrong metadata for integer additive and multiplicative operators 1. Fixing all Item_func_numhybrid descendants to set the precise data type handler (type_handler_long or type_handler_longlong) at fix_fields() time. This fixes MDEV-12869. 2. Fixing Item_func_unsigned_typecast to set the precise data type handler at fix_fields() time. This fixes MDEV-12852 and MDEV-12853. This is done by: - fixing Type_handler::Item_func_unsigned_fix_length_and_dec() and Type_handler_string_result::Item_func_unsigned_fix_length_and_dec() to properly detect situations when a negative epxression is converted to UNSIGNED. In this case, length of the result is now always set to MAX_BIGINT_WIDTH without trying to use args[0]->max_length, as very short arguments can produce very long result in such conversion: CAST(-1 AS UNSIGNED) -> 18446744073709551614 - adding a new virtual method "longlong Item::val_int_max() const", to preserve the old behavior for expressions like this: CAST(1 AS UNSIGNED) to stay under the INT data type (instead of BIGINT) for small positive integer literals. Using Item::unsigned_flag would not help, because Item_int does not set unsigned_flag to "true" for positive numbers. 3. Adding helper methods: * Item::type_handler_long_or_longlong() * Type_handler::type_handler_long_or_longlong() and reusing them in a few places, to reduce code duplication. 4. Making reorganation in create_tmp_field() and create_field_for_create_select() for Item_hybrid_func and descendants, to reduce duplicate code. They all now have a similar behavior in respect of creating fields. Only Item_func_user_var descendants have a different behavior. So moving the default behvior to Item_hybrid_func, and overriding behavior on Item_func_user_var level.
This commit is contained in:
parent
9b79888df8
commit
d9304914be
@ -762,7 +762,7 @@ SHOW CREATE TABLE t1;
|
|||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`CONCAT(CAST(REPEAT('9', 1000) AS SIGNED))` varchar(21) NOT NULL,
|
`CONCAT(CAST(REPEAT('9', 1000) AS SIGNED))` varchar(21) NOT NULL,
|
||||||
`CONCAT(CAST(REPEAT('9', 1000) AS UNSIGNED))` varchar(21) NOT NULL
|
`CONCAT(CAST(REPEAT('9', 1000) AS UNSIGNED))` varchar(20) NOT NULL
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
# End of test for Bug#13581962, Bug#14096619
|
# End of test for Bug#13581962, Bug#14096619
|
||||||
@ -1130,3 +1130,41 @@ c LENGTH(c)
|
|||||||
|
|
||||||
DROP PROCEDURE p1;
|
DROP PROCEDURE p1;
|
||||||
SET sql_mode=DEFAULT;
|
SET sql_mode=DEFAULT;
|
||||||
|
#
|
||||||
|
# MDEV-12852 Out-of-range errors when CAST(1-2 AS UNSIGNED
|
||||||
|
#
|
||||||
|
SET sql_mode=STRICT_ALL_TABLES;
|
||||||
|
CREATE TABLE t1 AS SELECT
|
||||||
|
CAST(-1 AS UNSIGNED),
|
||||||
|
CAST(1-2 AS UNSIGNED);
|
||||||
|
Warnings:
|
||||||
|
Note 1105 Cast to unsigned converted negative integer to it's positive complement
|
||||||
|
Note 1105 Cast to unsigned converted negative integer to it's positive complement
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`CAST(-1 AS UNSIGNED)` bigint(20) unsigned NOT NULL,
|
||||||
|
`CAST(1-2 AS UNSIGNED)` bigint(20) unsigned NOT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
SELECT * FROM t1;
|
||||||
|
CAST(-1 AS UNSIGNED) CAST(1-2 AS UNSIGNED)
|
||||||
|
18446744073709551615 18446744073709551615
|
||||||
|
DROP TABLE t1;
|
||||||
|
SET sql_mode=DEFAULT;
|
||||||
|
#
|
||||||
|
# MDEV-12853 Out-of-range errors when CAST('-1' AS UNSIGNED
|
||||||
|
#
|
||||||
|
SET sql_mode=STRICT_ALL_TABLES;
|
||||||
|
CREATE TABLE t1 AS SELECT CAST('-1' AS UNSIGNED);
|
||||||
|
Warnings:
|
||||||
|
Note 1105 Cast to unsigned converted negative integer to it's positive complement
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`CAST('-1' AS UNSIGNED)` bigint(20) unsigned NOT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
SELECT * FROM t1;
|
||||||
|
CAST('-1' AS UNSIGNED)
|
||||||
|
18446744073709551615
|
||||||
|
DROP TABLE t1;
|
||||||
|
SET sql_mode=DEFAULT;
|
||||||
|
@ -482,8 +482,8 @@ from t1;
|
|||||||
explain t2;
|
explain t2;
|
||||||
Field Type Null Key Default Extra
|
Field Type Null Key Default Extra
|
||||||
a int(11) YES NULL
|
a int(11) YES NULL
|
||||||
b bigint(11) NO NULL
|
b int(11) NO NULL
|
||||||
c bigint(10) unsigned NO NULL
|
c int(10) unsigned NO NULL
|
||||||
d date YES NULL
|
d date YES NULL
|
||||||
e varchar(1) YES NULL
|
e varchar(1) YES NULL
|
||||||
f datetime YES NULL
|
f datetime YES NULL
|
||||||
|
@ -568,3 +568,207 @@ def test t1 t1 @:=1e0 @:=1e0 5 3 1 N 36865 31 63
|
|||||||
@:=1e0
|
@:=1e0
|
||||||
1
|
1
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# MDEV-12869 Wrong metadata for integer additive and multiplicative operators
|
||||||
|
#
|
||||||
|
SELECT
|
||||||
|
1+1,
|
||||||
|
11+1,
|
||||||
|
111+1,
|
||||||
|
1111+1,
|
||||||
|
11111+1,
|
||||||
|
111111+1,
|
||||||
|
1111111+1,
|
||||||
|
11111111+1,
|
||||||
|
111111111+1 LIMIT 0;
|
||||||
|
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||||
|
def 1+1 3 3 0 N 32897 0 63
|
||||||
|
def 11+1 3 4 0 N 32897 0 63
|
||||||
|
def 111+1 3 5 0 N 32897 0 63
|
||||||
|
def 1111+1 3 6 0 N 32897 0 63
|
||||||
|
def 11111+1 3 7 0 N 32897 0 63
|
||||||
|
def 111111+1 3 8 0 N 32897 0 63
|
||||||
|
def 1111111+1 3 9 0 N 32897 0 63
|
||||||
|
def 11111111+1 8 10 0 N 32897 0 63
|
||||||
|
def 111111111+1 8 11 0 N 32897 0 63
|
||||||
|
1+1 11+1 111+1 1111+1 11111+1 111111+1 1111111+1 11111111+1 111111111+1
|
||||||
|
SELECT
|
||||||
|
1-1,
|
||||||
|
11-1,
|
||||||
|
111-1,
|
||||||
|
1111-1,
|
||||||
|
11111-1,
|
||||||
|
111111-1,
|
||||||
|
1111111-1,
|
||||||
|
11111111-1,
|
||||||
|
111111111-1 LIMIT 0;
|
||||||
|
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||||
|
def 1-1 3 3 0 N 32897 0 63
|
||||||
|
def 11-1 3 4 0 N 32897 0 63
|
||||||
|
def 111-1 3 5 0 N 32897 0 63
|
||||||
|
def 1111-1 3 6 0 N 32897 0 63
|
||||||
|
def 11111-1 3 7 0 N 32897 0 63
|
||||||
|
def 111111-1 3 8 0 N 32897 0 63
|
||||||
|
def 1111111-1 3 9 0 N 32897 0 63
|
||||||
|
def 11111111-1 8 10 0 N 32897 0 63
|
||||||
|
def 111111111-1 8 11 0 N 32897 0 63
|
||||||
|
1-1 11-1 111-1 1111-1 11111-1 111111-1 1111111-1 11111111-1 111111111-1
|
||||||
|
SELECT
|
||||||
|
1*1,
|
||||||
|
11*1,
|
||||||
|
111*1,
|
||||||
|
1111*1,
|
||||||
|
11111*1,
|
||||||
|
111111*1,
|
||||||
|
1111111*1,
|
||||||
|
11111111*1,
|
||||||
|
111111111*1 LIMIT 0;
|
||||||
|
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||||
|
def 1*1 3 3 0 N 32897 0 63
|
||||||
|
def 11*1 3 4 0 N 32897 0 63
|
||||||
|
def 111*1 3 5 0 N 32897 0 63
|
||||||
|
def 1111*1 3 6 0 N 32897 0 63
|
||||||
|
def 11111*1 3 7 0 N 32897 0 63
|
||||||
|
def 111111*1 3 8 0 N 32897 0 63
|
||||||
|
def 1111111*1 3 9 0 N 32897 0 63
|
||||||
|
def 11111111*1 8 10 0 N 32897 0 63
|
||||||
|
def 111111111*1 8 11 0 N 32897 0 63
|
||||||
|
1*1 11*1 111*1 1111*1 11111*1 111111*1 1111111*1 11111111*1 111111111*1
|
||||||
|
SELECT
|
||||||
|
1 MOD 1,
|
||||||
|
11 MOD 1,
|
||||||
|
111 MOD 1,
|
||||||
|
1111 MOD 1,
|
||||||
|
11111 MOD 1,
|
||||||
|
111111 MOD 1,
|
||||||
|
1111111 MOD 1,
|
||||||
|
11111111 MOD 1,
|
||||||
|
111111111 MOD 1,
|
||||||
|
1111111111 MOD 1,
|
||||||
|
11111111111 MOD 1 LIMIT 0;
|
||||||
|
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||||
|
def 1 MOD 1 3 1 0 Y 32896 0 63
|
||||||
|
def 11 MOD 1 3 2 0 Y 32896 0 63
|
||||||
|
def 111 MOD 1 3 3 0 Y 32896 0 63
|
||||||
|
def 1111 MOD 1 3 4 0 Y 32896 0 63
|
||||||
|
def 11111 MOD 1 3 5 0 Y 32896 0 63
|
||||||
|
def 111111 MOD 1 3 6 0 Y 32896 0 63
|
||||||
|
def 1111111 MOD 1 3 7 0 Y 32896 0 63
|
||||||
|
def 11111111 MOD 1 3 8 0 Y 32896 0 63
|
||||||
|
def 111111111 MOD 1 3 9 0 Y 32896 0 63
|
||||||
|
def 1111111111 MOD 1 8 10 0 Y 32896 0 63
|
||||||
|
def 11111111111 MOD 1 8 11 0 Y 32896 0 63
|
||||||
|
1 MOD 1 11 MOD 1 111 MOD 1 1111 MOD 1 11111 MOD 1 111111 MOD 1 1111111 MOD 1 11111111 MOD 1 111111111 MOD 1 1111111111 MOD 1 11111111111 MOD 1
|
||||||
|
SELECT
|
||||||
|
-(1),
|
||||||
|
-(11),
|
||||||
|
-(111),
|
||||||
|
-(1111),
|
||||||
|
-(11111),
|
||||||
|
-(111111),
|
||||||
|
-(1111111),
|
||||||
|
-(11111111),
|
||||||
|
-(111111111) LIMIT 0;
|
||||||
|
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||||
|
def -(1) 3 2 0 N 32897 0 63
|
||||||
|
def -(11) 3 3 0 N 32897 0 63
|
||||||
|
def -(111) 3 4 0 N 32897 0 63
|
||||||
|
def -(1111) 3 5 0 N 32897 0 63
|
||||||
|
def -(11111) 3 6 0 N 32897 0 63
|
||||||
|
def -(111111) 3 7 0 N 32897 0 63
|
||||||
|
def -(1111111) 3 8 0 N 32897 0 63
|
||||||
|
def -(11111111) 3 9 0 N 32897 0 63
|
||||||
|
def -(111111111) 8 10 0 N 32897 0 63
|
||||||
|
-(1) -(11) -(111) -(1111) -(11111) -(111111) -(1111111) -(11111111) -(111111111)
|
||||||
|
SELECT
|
||||||
|
ABS(1),
|
||||||
|
ABS(11),
|
||||||
|
ABS(111),
|
||||||
|
ABS(1111),
|
||||||
|
ABS(11111),
|
||||||
|
ABS(111111),
|
||||||
|
ABS(1111111),
|
||||||
|
ABS(11111111),
|
||||||
|
ABS(111111111),
|
||||||
|
ABS(1111111111) LIMIT 0;
|
||||||
|
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||||
|
def ABS(1) 3 1 0 N 32897 0 63
|
||||||
|
def ABS(11) 3 2 0 N 32897 0 63
|
||||||
|
def ABS(111) 3 3 0 N 32897 0 63
|
||||||
|
def ABS(1111) 3 4 0 N 32897 0 63
|
||||||
|
def ABS(11111) 3 5 0 N 32897 0 63
|
||||||
|
def ABS(111111) 3 6 0 N 32897 0 63
|
||||||
|
def ABS(1111111) 3 7 0 N 32897 0 63
|
||||||
|
def ABS(11111111) 3 8 0 N 32897 0 63
|
||||||
|
def ABS(111111111) 3 9 0 N 32897 0 63
|
||||||
|
def ABS(1111111111) 8 10 0 N 32897 0 63
|
||||||
|
ABS(1) ABS(11) ABS(111) ABS(1111) ABS(11111) ABS(111111) ABS(1111111) ABS(11111111) ABS(111111111) ABS(1111111111)
|
||||||
|
SELECT
|
||||||
|
CEILING(1),
|
||||||
|
CEILING(11),
|
||||||
|
CEILING(111),
|
||||||
|
CEILING(1111),
|
||||||
|
CEILING(11111),
|
||||||
|
CEILING(111111),
|
||||||
|
CEILING(1111111),
|
||||||
|
CEILING(11111111),
|
||||||
|
CEILING(111111111),
|
||||||
|
CEILING(1111111111) LIMIT 0;
|
||||||
|
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||||
|
def CEILING(1) 3 3 0 N 32897 0 63
|
||||||
|
def CEILING(11) 3 4 0 N 32897 0 63
|
||||||
|
def CEILING(111) 3 5 0 N 32897 0 63
|
||||||
|
def CEILING(1111) 3 6 0 N 32897 0 63
|
||||||
|
def CEILING(11111) 3 7 0 N 32897 0 63
|
||||||
|
def CEILING(111111) 3 8 0 N 32897 0 63
|
||||||
|
def CEILING(1111111) 3 9 0 N 32897 0 63
|
||||||
|
def CEILING(11111111) 8 10 0 N 32897 0 63
|
||||||
|
def CEILING(111111111) 8 11 0 N 32897 0 63
|
||||||
|
def CEILING(1111111111) 8 12 0 N 32897 0 63
|
||||||
|
CEILING(1) CEILING(11) CEILING(111) CEILING(1111) CEILING(11111) CEILING(111111) CEILING(1111111) CEILING(11111111) CEILING(111111111) CEILING(1111111111)
|
||||||
|
SELECT
|
||||||
|
FLOOR(1),
|
||||||
|
FLOOR(11),
|
||||||
|
FLOOR(111),
|
||||||
|
FLOOR(1111),
|
||||||
|
FLOOR(11111),
|
||||||
|
FLOOR(111111),
|
||||||
|
FLOOR(1111111),
|
||||||
|
FLOOR(11111111),
|
||||||
|
FLOOR(111111111),
|
||||||
|
FLOOR(1111111111) LIMIT 0;
|
||||||
|
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||||
|
def FLOOR(1) 3 3 0 N 32897 0 63
|
||||||
|
def FLOOR(11) 3 4 0 N 32897 0 63
|
||||||
|
def FLOOR(111) 3 5 0 N 32897 0 63
|
||||||
|
def FLOOR(1111) 3 6 0 N 32897 0 63
|
||||||
|
def FLOOR(11111) 3 7 0 N 32897 0 63
|
||||||
|
def FLOOR(111111) 3 8 0 N 32897 0 63
|
||||||
|
def FLOOR(1111111) 3 9 0 N 32897 0 63
|
||||||
|
def FLOOR(11111111) 8 10 0 N 32897 0 63
|
||||||
|
def FLOOR(111111111) 8 11 0 N 32897 0 63
|
||||||
|
def FLOOR(1111111111) 8 12 0 N 32897 0 63
|
||||||
|
FLOOR(1) FLOOR(11) FLOOR(111) FLOOR(1111) FLOOR(11111) FLOOR(111111) FLOOR(1111111) FLOOR(11111111) FLOOR(111111111) FLOOR(1111111111)
|
||||||
|
SELECT
|
||||||
|
ROUND(1),
|
||||||
|
ROUND(11),
|
||||||
|
ROUND(111),
|
||||||
|
ROUND(1111),
|
||||||
|
ROUND(11111),
|
||||||
|
ROUND(111111),
|
||||||
|
ROUND(1111111),
|
||||||
|
ROUND(11111111),
|
||||||
|
ROUND(111111111),
|
||||||
|
ROUND(1111111111) LIMIT 0;
|
||||||
|
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||||
|
def ROUND(1) 3 1 0 N 32897 0 63
|
||||||
|
def ROUND(11) 3 2 0 N 32897 0 63
|
||||||
|
def ROUND(111) 3 3 0 N 32897 0 63
|
||||||
|
def ROUND(1111) 3 4 0 N 32897 0 63
|
||||||
|
def ROUND(11111) 3 5 0 N 32897 0 63
|
||||||
|
def ROUND(111111) 3 6 0 N 32897 0 63
|
||||||
|
def ROUND(1111111) 3 7 0 N 32897 0 63
|
||||||
|
def ROUND(11111111) 3 8 0 N 32897 0 63
|
||||||
|
def ROUND(111111111) 3 9 0 N 32897 0 63
|
||||||
|
def ROUND(1111111111) 8 10 0 N 32897 0 63
|
||||||
|
ROUND(1) ROUND(11) ROUND(111) ROUND(1111) ROUND(11111) ROUND(111111) ROUND(1111111) ROUND(11111111) ROUND(111111111) ROUND(1111111111)
|
||||||
|
@ -561,3 +561,29 @@ CALL p1('8FFFFFFFFFFFFFFF');
|
|||||||
|
|
||||||
DROP PROCEDURE p1;
|
DROP PROCEDURE p1;
|
||||||
SET sql_mode=DEFAULT;
|
SET sql_mode=DEFAULT;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-12852 Out-of-range errors when CAST(1-2 AS UNSIGNED
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SET sql_mode=STRICT_ALL_TABLES;
|
||||||
|
CREATE TABLE t1 AS SELECT
|
||||||
|
CAST(-1 AS UNSIGNED),
|
||||||
|
CAST(1-2 AS UNSIGNED);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
SET sql_mode=DEFAULT;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-12853 Out-of-range errors when CAST('-1' AS UNSIGNED
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SET sql_mode=STRICT_ALL_TABLES;
|
||||||
|
CREATE TABLE t1 AS SELECT CAST('-1' AS UNSIGNED);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
SET sql_mode=DEFAULT;
|
||||||
|
@ -353,3 +353,115 @@ CREATE TABLE t1 AS SELECT @:=1e0;
|
|||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
--disable_metadata
|
--disable_metadata
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-12869 Wrong metadata for integer additive and multiplicative operators
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--enable_metadata
|
||||||
|
SELECT
|
||||||
|
1+1,
|
||||||
|
11+1,
|
||||||
|
111+1,
|
||||||
|
1111+1,
|
||||||
|
11111+1,
|
||||||
|
111111+1,
|
||||||
|
1111111+1,
|
||||||
|
11111111+1,
|
||||||
|
111111111+1 LIMIT 0;
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
1-1,
|
||||||
|
11-1,
|
||||||
|
111-1,
|
||||||
|
1111-1,
|
||||||
|
11111-1,
|
||||||
|
111111-1,
|
||||||
|
1111111-1,
|
||||||
|
11111111-1,
|
||||||
|
111111111-1 LIMIT 0;
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
1*1,
|
||||||
|
11*1,
|
||||||
|
111*1,
|
||||||
|
1111*1,
|
||||||
|
11111*1,
|
||||||
|
111111*1,
|
||||||
|
1111111*1,
|
||||||
|
11111111*1,
|
||||||
|
111111111*1 LIMIT 0;
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
1 MOD 1,
|
||||||
|
11 MOD 1,
|
||||||
|
111 MOD 1,
|
||||||
|
1111 MOD 1,
|
||||||
|
11111 MOD 1,
|
||||||
|
111111 MOD 1,
|
||||||
|
1111111 MOD 1,
|
||||||
|
11111111 MOD 1,
|
||||||
|
111111111 MOD 1,
|
||||||
|
1111111111 MOD 1,
|
||||||
|
11111111111 MOD 1 LIMIT 0;
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
-(1),
|
||||||
|
-(11),
|
||||||
|
-(111),
|
||||||
|
-(1111),
|
||||||
|
-(11111),
|
||||||
|
-(111111),
|
||||||
|
-(1111111),
|
||||||
|
-(11111111),
|
||||||
|
-(111111111) LIMIT 0;
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
ABS(1),
|
||||||
|
ABS(11),
|
||||||
|
ABS(111),
|
||||||
|
ABS(1111),
|
||||||
|
ABS(11111),
|
||||||
|
ABS(111111),
|
||||||
|
ABS(1111111),
|
||||||
|
ABS(11111111),
|
||||||
|
ABS(111111111),
|
||||||
|
ABS(1111111111) LIMIT 0;
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
CEILING(1),
|
||||||
|
CEILING(11),
|
||||||
|
CEILING(111),
|
||||||
|
CEILING(1111),
|
||||||
|
CEILING(11111),
|
||||||
|
CEILING(111111),
|
||||||
|
CEILING(1111111),
|
||||||
|
CEILING(11111111),
|
||||||
|
CEILING(111111111),
|
||||||
|
CEILING(1111111111) LIMIT 0;
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
FLOOR(1),
|
||||||
|
FLOOR(11),
|
||||||
|
FLOOR(111),
|
||||||
|
FLOOR(1111),
|
||||||
|
FLOOR(11111),
|
||||||
|
FLOOR(111111),
|
||||||
|
FLOOR(1111111),
|
||||||
|
FLOOR(11111111),
|
||||||
|
FLOOR(111111111),
|
||||||
|
FLOOR(1111111111) LIMIT 0;
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
ROUND(1),
|
||||||
|
ROUND(11),
|
||||||
|
ROUND(111),
|
||||||
|
ROUND(1111),
|
||||||
|
ROUND(11111),
|
||||||
|
ROUND(111111),
|
||||||
|
ROUND(1111111),
|
||||||
|
ROUND(11111111),
|
||||||
|
ROUND(111111111),
|
||||||
|
ROUND(1111111111) LIMIT 0;
|
||||||
|
|
||||||
|
--disable_metadata
|
||||||
|
17
sql/item.h
17
sql/item.h
@ -627,6 +627,11 @@ protected:
|
|||||||
return (null_value= item->get_date_with_conversion(ltime, fuzzydate));
|
return (null_value= item->get_date_with_conversion(ltime, fuzzydate));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Type_handler *type_handler_long_or_longlong() const
|
||||||
|
{
|
||||||
|
return Type_handler::type_handler_long_or_longlong(max_char_length());
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*
|
/*
|
||||||
Cache val_str() into the own buffer, e.g. to evaluate constant
|
Cache val_str() into the own buffer, e.g. to evaluate constant
|
||||||
@ -1210,6 +1215,10 @@ public:
|
|||||||
return const_item() ? type_handler()->Item_datetime_precision(this) :
|
return const_item() ? type_handler()->Item_datetime_precision(this) :
|
||||||
MY_MIN(decimals, TIME_SECOND_PART_DIGITS);
|
MY_MIN(decimals, TIME_SECOND_PART_DIGITS);
|
||||||
}
|
}
|
||||||
|
virtual longlong val_int_min() const
|
||||||
|
{
|
||||||
|
return LONGLONG_MIN;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
Returns true if this is constant (during query execution, i.e. its value
|
Returns true if this is constant (during query execution, i.e. its value
|
||||||
will not change until next fix_fields) and its value is known.
|
will not change until next fix_fields) and its value is known.
|
||||||
@ -3234,17 +3243,13 @@ public:
|
|||||||
Item_int(THD *thd, const char *str_arg, uint length=64);
|
Item_int(THD *thd, const char *str_arg, uint length=64);
|
||||||
enum Type type() const { return INT_ITEM; }
|
enum Type type() const { return INT_ITEM; }
|
||||||
const Type_handler *type_handler() const
|
const Type_handler *type_handler() const
|
||||||
{
|
{ return type_handler_long_or_longlong(); }
|
||||||
// The same condition is repeated in Item::create_tmp_field()
|
|
||||||
if (max_length > MY_INT32_NUM_DECIMAL_DIGITS - 2)
|
|
||||||
return &type_handler_longlong;
|
|
||||||
return &type_handler_long;
|
|
||||||
}
|
|
||||||
Field *create_tmp_field(bool group, TABLE *table)
|
Field *create_tmp_field(bool group, TABLE *table)
|
||||||
{ return tmp_table_field_from_field_type(table); }
|
{ return tmp_table_field_from_field_type(table); }
|
||||||
Field *create_field_for_create_select(TABLE *table)
|
Field *create_field_for_create_select(TABLE *table)
|
||||||
{ return tmp_table_field_from_field_type(table); }
|
{ return tmp_table_field_from_field_type(table); }
|
||||||
longlong val_int() { DBUG_ASSERT(fixed == 1); return value; }
|
longlong val_int() { DBUG_ASSERT(fixed == 1); return value; }
|
||||||
|
longlong val_int_min() const { DBUG_ASSERT(fixed == 1); return value; }
|
||||||
double val_real() { DBUG_ASSERT(fixed == 1); return (double) value; }
|
double val_real() { DBUG_ASSERT(fixed == 1); return (double) value; }
|
||||||
my_decimal *val_decimal(my_decimal *);
|
my_decimal *val_decimal(my_decimal *);
|
||||||
String *val_str(String*);
|
String *val_str(String*);
|
||||||
|
@ -1740,8 +1740,8 @@ my_decimal *Item_func_neg::decimal_op(my_decimal *decimal_value)
|
|||||||
|
|
||||||
void Item_func_neg::fix_length_and_dec_int()
|
void Item_func_neg::fix_length_and_dec_int()
|
||||||
{
|
{
|
||||||
set_handler(&type_handler_longlong);
|
|
||||||
max_length= args[0]->max_length + 1;
|
max_length= args[0]->max_length + 1;
|
||||||
|
set_handler(type_handler_long_or_longlong());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If this is in integer context keep the context as integer if possible
|
If this is in integer context keep the context as integer if possible
|
||||||
@ -1834,9 +1834,9 @@ my_decimal *Item_func_abs::decimal_op(my_decimal *decimal_value)
|
|||||||
|
|
||||||
void Item_func_abs::fix_length_and_dec_int()
|
void Item_func_abs::fix_length_and_dec_int()
|
||||||
{
|
{
|
||||||
set_handler(&type_handler_longlong);
|
|
||||||
max_length= args[0]->max_length;
|
max_length= args[0]->max_length;
|
||||||
unsigned_flag= args[0]->unsigned_flag;
|
unsigned_flag= args[0]->unsigned_flag;
|
||||||
|
set_handler(type_handler_long_or_longlong());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2117,7 +2117,7 @@ void Item_func_int_val::fix_length_and_dec_int_or_decimal()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned_flag= args[0]->unsigned_flag;
|
unsigned_flag= args[0]->unsigned_flag;
|
||||||
set_handler(&type_handler_longlong);
|
set_handler(type_handler_long_or_longlong());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2308,9 +2308,9 @@ void Item_func_round::fix_arg_int()
|
|||||||
int length_can_increase= MY_TEST(!truncate && val1_is_negative);
|
int length_can_increase= MY_TEST(!truncate && val1_is_negative);
|
||||||
max_length= args[0]->max_length + length_can_increase;
|
max_length= args[0]->max_length + length_can_increase;
|
||||||
// Here we can keep INT_RESULT
|
// Here we can keep INT_RESULT
|
||||||
set_handler(&type_handler_longlong);
|
|
||||||
unsigned_flag= args[0]->unsigned_flag;
|
unsigned_flag= args[0]->unsigned_flag;
|
||||||
decimals= 0;
|
decimals= 0;
|
||||||
|
set_handler(type_handler_long_or_longlong());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
fix_length_and_dec_decimal(decimals_to_set);
|
fix_length_and_dec_decimal(decimals_to_set);
|
||||||
|
@ -396,6 +396,10 @@ public:
|
|||||||
:Item_func(thd, item), Type_handler_hybrid_field_type(item) { }
|
:Item_func(thd, item), Type_handler_hybrid_field_type(item) { }
|
||||||
const Type_handler *type_handler() const
|
const Type_handler *type_handler() const
|
||||||
{ return Type_handler_hybrid_field_type::type_handler(); }
|
{ return Type_handler_hybrid_field_type::type_handler(); }
|
||||||
|
Field *create_tmp_field(bool group, TABLE *table)
|
||||||
|
{ return tmp_table_field_from_field_type(table); }
|
||||||
|
Field *create_field_for_create_select(TABLE *table)
|
||||||
|
{ return tmp_table_field_from_field_type(table); }
|
||||||
Field::geometry_type get_geometry_type() const
|
Field::geometry_type get_geometry_type() const
|
||||||
{ return Type_geometry_attributes::get_geometry_type(); };
|
{ return Type_geometry_attributes::get_geometry_type(); };
|
||||||
void set_geometry_type(uint type)
|
void set_geometry_type(uint type)
|
||||||
@ -624,10 +628,6 @@ public:
|
|||||||
Item_func_case_expression(THD *thd, List<Item> &list):
|
Item_func_case_expression(THD *thd, List<Item> &list):
|
||||||
Item_func_hybrid_field_type(thd, list)
|
Item_func_hybrid_field_type(thd, list)
|
||||||
{ }
|
{ }
|
||||||
Field *create_tmp_field(bool group, TABLE *table)
|
|
||||||
{ return tmp_table_field_from_field_type(table); }
|
|
||||||
Field *create_field_for_create_select(TABLE *table)
|
|
||||||
{ return tmp_table_field_from_field_type(table); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -700,13 +700,14 @@ class Item_num_op :public Item_func_numhybrid
|
|||||||
unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;
|
unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;
|
||||||
result_precision();
|
result_precision();
|
||||||
decimals= 0;
|
decimals= 0;
|
||||||
|
set_handler(type_handler_long_or_longlong());
|
||||||
}
|
}
|
||||||
void fix_length_and_dec_temporal()
|
void fix_length_and_dec_temporal()
|
||||||
{
|
{
|
||||||
set_handler(&type_handler_newdecimal);
|
set_handler(&type_handler_newdecimal);
|
||||||
fix_length_and_dec_decimal();
|
fix_length_and_dec_decimal();
|
||||||
if (decimals == 0)
|
if (decimals == 0)
|
||||||
set_handler(&type_handler_longlong);
|
set_handler(type_handler_long_or_longlong());
|
||||||
}
|
}
|
||||||
bool need_parentheses_in_default() { return true; }
|
bool need_parentheses_in_default() { return true; }
|
||||||
};
|
};
|
||||||
@ -839,15 +840,8 @@ public:
|
|||||||
unsigned_flag= 0;
|
unsigned_flag= 0;
|
||||||
}
|
}
|
||||||
const char *func_name() const { return "cast_as_signed"; }
|
const char *func_name() const { return "cast_as_signed"; }
|
||||||
const Type_handler *type_handler() const { return &type_handler_longlong; }
|
const Type_handler *type_handler() const
|
||||||
Field *create_tmp_field(bool group, TABLE *table)
|
{ return type_handler_long_or_longlong(); }
|
||||||
{
|
|
||||||
return create_tmp_field_int(table,
|
|
||||||
MY_INT32_NUM_DECIMAL_DIGITS - 2 +
|
|
||||||
unsigned_flag);
|
|
||||||
}
|
|
||||||
Field *create_field_for_create_select(TABLE *table)
|
|
||||||
{ return Item_func_signed::create_tmp_field(false, table); }
|
|
||||||
longlong val_int()
|
longlong val_int()
|
||||||
{
|
{
|
||||||
longlong value= args[0]->val_int_signed_typecast();
|
longlong value= args[0]->val_int_signed_typecast();
|
||||||
@ -899,6 +893,12 @@ public:
|
|||||||
unsigned_flag= 1;
|
unsigned_flag= 1;
|
||||||
}
|
}
|
||||||
const char *func_name() const { return "cast_as_unsigned"; }
|
const char *func_name() const { return "cast_as_unsigned"; }
|
||||||
|
const Type_handler *type_handler() const
|
||||||
|
{
|
||||||
|
if (max_char_length() <= MY_INT32_NUM_DECIMAL_DIGITS - 1)
|
||||||
|
return &type_handler_long;
|
||||||
|
return &type_handler_longlong;
|
||||||
|
}
|
||||||
longlong val_int()
|
longlong val_int()
|
||||||
{
|
{
|
||||||
longlong value= args[0]->val_int_unsigned_typecast();
|
longlong value= args[0]->val_int_unsigned_typecast();
|
||||||
@ -909,6 +909,7 @@ public:
|
|||||||
{
|
{
|
||||||
args[0]->type_handler()->Item_func_unsigned_fix_length_and_dec(this);
|
args[0]->type_handler()->Item_func_unsigned_fix_length_and_dec(this);
|
||||||
}
|
}
|
||||||
|
uint decimal_precision() const { return max_length; }
|
||||||
virtual void print(String *str, enum_query_type query_type);
|
virtual void print(String *str, enum_query_type query_type);
|
||||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||||
{ return get_item_copy<Item_func_unsigned>(thd, mem_root, this); }
|
{ return get_item_copy<Item_func_unsigned>(thd, mem_root, this); }
|
||||||
@ -1072,12 +1073,7 @@ public:
|
|||||||
const char *func_name() const { return "DIV"; }
|
const char *func_name() const { return "DIV"; }
|
||||||
enum precedence precedence() const { return MUL_PRECEDENCE; }
|
enum precedence precedence() const { return MUL_PRECEDENCE; }
|
||||||
const Type_handler *type_handler() const
|
const Type_handler *type_handler() const
|
||||||
{
|
{ return type_handler_long_or_longlong(); }
|
||||||
// The same condition is repeated in Item::create_tmp_field()
|
|
||||||
if (max_length > MY_INT32_NUM_DECIMAL_DIGITS - 2)
|
|
||||||
return &type_handler_longlong;
|
|
||||||
return &type_handler_long;
|
|
||||||
}
|
|
||||||
void fix_length_and_dec();
|
void fix_length_and_dec();
|
||||||
void print(String *str, enum_query_type query_type)
|
void print(String *str, enum_query_type query_type)
|
||||||
{
|
{
|
||||||
@ -1118,6 +1114,7 @@ public:
|
|||||||
max_length= MY_MAX(args[0]->max_length, args[1]->max_length);
|
max_length= MY_MAX(args[0]->max_length, args[1]->max_length);
|
||||||
decimals= 0;
|
decimals= 0;
|
||||||
unsigned_flag= args[0]->unsigned_flag;
|
unsigned_flag= args[0]->unsigned_flag;
|
||||||
|
set_handler(type_handler_long_or_longlong());
|
||||||
}
|
}
|
||||||
bool check_partition_func_processor(void *int_arg) {return FALSE;}
|
bool check_partition_func_processor(void *int_arg) {return FALSE;}
|
||||||
bool check_vcol_func_processor(void *arg) { return FALSE;}
|
bool check_vcol_func_processor(void *arg) { return FALSE;}
|
||||||
@ -1469,10 +1466,6 @@ public:
|
|||||||
Item_func_min_max(THD *thd, List<Item> &list, int cmp_sign_arg):
|
Item_func_min_max(THD *thd, List<Item> &list, int cmp_sign_arg):
|
||||||
Item_hybrid_func(thd, list), cmp_sign(cmp_sign_arg)
|
Item_hybrid_func(thd, list), cmp_sign(cmp_sign_arg)
|
||||||
{}
|
{}
|
||||||
Field *create_tmp_field(bool group, TABLE *table)
|
|
||||||
{ return tmp_table_field_from_field_type(table); }
|
|
||||||
Field *create_field_for_create_select(TABLE *table)
|
|
||||||
{ return tmp_table_field_from_field_type(table); }
|
|
||||||
String *val_str_native(String *str);
|
String *val_str_native(String *str);
|
||||||
double val_real_native();
|
double val_real_native();
|
||||||
longlong val_int_native();
|
longlong val_int_native();
|
||||||
@ -2244,6 +2237,10 @@ public:
|
|||||||
Item_func_user_var(THD *thd, Item_func_user_var *item)
|
Item_func_user_var(THD *thd, Item_func_user_var *item)
|
||||||
:Item_hybrid_func(thd, item),
|
:Item_hybrid_func(thd, item),
|
||||||
m_var_entry(item->m_var_entry), name(item->name) { }
|
m_var_entry(item->m_var_entry), name(item->name) { }
|
||||||
|
Field *create_tmp_field(bool group, TABLE *table)
|
||||||
|
{ return Item::create_tmp_field(group, table); }
|
||||||
|
Field *create_field_for_create_select(TABLE *table)
|
||||||
|
{ return Item::create_field_for_create_select(table); }
|
||||||
bool check_vcol_func_processor(void *arg);
|
bool check_vcol_func_processor(void *arg);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ public:
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
const char *func_name() const { return "month"; }
|
const char *func_name() const { return "month"; }
|
||||||
const Type_handler *type_handler() const { return &type_handler_longlong; }
|
const Type_handler *type_handler() const { return &type_handler_long; }
|
||||||
void fix_length_and_dec()
|
void fix_length_and_dec()
|
||||||
{
|
{
|
||||||
decimals= 0;
|
decimals= 0;
|
||||||
@ -449,7 +449,10 @@ public:
|
|||||||
decimals= dec;
|
decimals= dec;
|
||||||
max_length=17 + (decimals ? decimals + 1 : 0);
|
max_length=17 + (decimals ? decimals + 1 : 0);
|
||||||
maybe_null= true;
|
maybe_null= true;
|
||||||
set_handler_by_result_type(decimals ? DECIMAL_RESULT : INT_RESULT);
|
if (decimals)
|
||||||
|
set_handler(&type_handler_newdecimal);
|
||||||
|
else
|
||||||
|
set_handler(type_handler_long_or_longlong());
|
||||||
}
|
}
|
||||||
double real_op() { DBUG_ASSERT(0); return 0; }
|
double real_op() { DBUG_ASSERT(0); return 0; }
|
||||||
String *str_op(String *str) { DBUG_ASSERT(0); return 0; }
|
String *str_op(String *str) { DBUG_ASSERT(0); return 0; }
|
||||||
|
@ -528,6 +528,14 @@ 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)
|
||||||
|
{
|
||||||
|
if (max_char_length <= MY_INT32_NUM_DECIMAL_DIGITS - 2)
|
||||||
|
return &type_handler_long;
|
||||||
|
return &type_handler_longlong;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This method is called for CASE (and its abbreviations) and LEAST/GREATEST
|
This method is called for CASE (and its abbreviations) and LEAST/GREATEST
|
||||||
when data type aggregation returned LONGLONG and there were some BIT
|
when data type aggregation returned LONGLONG and there were some BIT
|
||||||
@ -4168,6 +4176,16 @@ bool Type_handler::
|
|||||||
bool Type_handler::
|
bool Type_handler::
|
||||||
Item_func_unsigned_fix_length_and_dec(Item_func_unsigned *item) const
|
Item_func_unsigned_fix_length_and_dec(Item_func_unsigned *item) const
|
||||||
{
|
{
|
||||||
|
const Item *arg= item->arguments()[0];
|
||||||
|
if (!arg->unsigned_flag && arg->val_int_min() < 0)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Negative arguments produce long results:
|
||||||
|
CAST(1-2 AS UNSIGNED) -> 18446744073709551615
|
||||||
|
*/
|
||||||
|
item->max_length= MAX_BIGINT_WIDTH;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
item->fix_length_and_dec_generic();
|
item->fix_length_and_dec_generic();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -4184,6 +4202,14 @@ bool Type_handler_string_result::
|
|||||||
bool Type_handler_string_result::
|
bool Type_handler_string_result::
|
||||||
Item_func_unsigned_fix_length_and_dec(Item_func_unsigned *item) const
|
Item_func_unsigned_fix_length_and_dec(Item_func_unsigned *item) const
|
||||||
{
|
{
|
||||||
|
const Item *arg= item->arguments()[0];
|
||||||
|
if (!arg->unsigned_flag && // Not HEX hybrid
|
||||||
|
arg->max_char_length() > 1) // Can be negative
|
||||||
|
{
|
||||||
|
// String arguments can give long results: '-1' -> 18446744073709551614
|
||||||
|
item->max_length= MAX_BIGINT_WIDTH;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
item->fix_length_and_dec_string();
|
item->fix_length_and_dec_string();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -564,6 +564,7 @@ public:
|
|||||||
static const Type_handler *blob_type_handler(uint max_octet_length);
|
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 *string_type_handler(uint max_octet_length);
|
||||||
static const Type_handler *bit_and_int_mixture_handler(uint max_char_len);
|
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);
|
||||||
/**
|
/**
|
||||||
Return a string type handler for Item
|
Return a string type handler for Item
|
||||||
If too_big_for_varchar() returns a BLOB variant, according to length.
|
If too_big_for_varchar() returns a BLOB variant, according to length.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user