Commit d046b13e authored by Alexander Barkov's avatar Alexander Barkov

MDEV-20548 Unexpected error on CREATE..SELECT HEX(num)

Item_func_hex::fix_length_and_dec() evaluated a too short data type
for signed numeric arguments, which resulted in a 'Data too long for column'
error on CREATE..SELECT.

Fixing the code to take into account that a short negative
numer can produce a long HEX value: -1  -> 'FFFFFFFFFFFFFFFF'

Also fixing Item_func_hex::val_str_ascii_from_val_real().
Without this change, MTR test with HEX with negative float point arguments
failed on some platforms (aarch64, ppc64le, s390-x).
parent e7b76f87
......@@ -748,7 +748,7 @@ t1 CREATE TABLE `t1` (
`bin(130)` varchar(64) DEFAULT NULL,
`oct(130)` varchar(64) DEFAULT NULL,
`conv(130,16,10)` varchar(64) DEFAULT NULL,
`hex(130)` varchar(6) DEFAULT NULL,
`hex(130)` varchar(16) DEFAULT NULL,
`char(130)` varbinary(4) DEFAULT NULL,
`format(130,10)` varchar(25) DEFAULT NULL,
`left(_latin2'a',1)` varchar(1) CHARACTER SET latin2 COLLATE latin2_general_ci DEFAULT NULL,
......
......@@ -1206,3 +1206,82 @@ DROP VIEW v1;
#
# End of 10.4 tests
#
#
# Start of 10.5 tests
#
#
# MDEV-20548 Unexpected error on CREATE..SELECT HEX(num)
#
SET sql_mode=STRICT_ALL_TABLES;
CREATE TABLE t1 AS SELECT HEX(-2e0) AS h;
SELECT * FROM t1;
h
FFFFFFFFFFFFFFFE
SHOW COLUMNS IN t1;
Field Type Null Key Default Extra
h varchar(16) YES NULL
DROP TABLE t1;
CREATE TABLE t1 AS SELECT HEX(-1e0) AS h;
SELECT * FROM t1;
h
FFFFFFFFFFFFFFFF
SHOW COLUMNS IN t1;
Field Type Null Key Default Extra
h varchar(16) YES NULL
DROP TABLE t1;
CREATE TABLE t1 AS SELECT HEX(1e0) AS h;
SELECT * FROM t1;
h
1
SHOW COLUMNS IN t1;
Field Type Null Key Default Extra
h varchar(16) YES NULL
DROP TABLE t1;
CREATE TABLE t1 AS SELECT HEX(2e0) AS h;
SELECT * FROM t1;
h
2
SHOW COLUMNS IN t1;
Field Type Null Key Default Extra
h varchar(16) YES NULL
DROP TABLE t1;
CREATE TABLE t1 (a FLOAT);
INSERT INTO t1 VALUES (-1e38),(-255),(-2),(-1),(+1),(+2),(255),(1e38);
CREATE TABLE t2 AS SELECT a, HEX(a) AS h FROM t1;
SELECT * FROM t2 ORDER BY a;
a h
-1e38 FFFFFFFFFFFFFFFF
-255 FFFFFFFFFFFFFF01
-2 FFFFFFFFFFFFFFFE
-1 FFFFFFFFFFFFFFFF
1 1
2 2
255 FF
1e38 FFFFFFFFFFFFFFFF
SHOW COLUMNS IN t2;
Field Type Null Key Default Extra
a float YES NULL
h varchar(16) YES NULL
DROP TABLE t1, t2;
CREATE TABLE t1 (a DOUBLE);
INSERT INTO t1 VALUES (-1e308),(-255),(-2),(-1),(+1),(+2),(255),(1e308);
CREATE TABLE t2 AS SELECT a, HEX(a) AS h FROM t1;
SELECT * FROM t2 ORDER BY a;
a h
-1e308 FFFFFFFFFFFFFFFF
-255 FFFFFFFFFFFFFF01
-2 FFFFFFFFFFFFFFFE
-1 FFFFFFFFFFFFFFFF
1 1
2 2
255 FF
1e308 FFFFFFFFFFFFFFFF
SHOW COLUMNS IN t2;
Field Type Null Key Default Extra
a double YES NULL
h varchar(16) YES NULL
DROP TABLE t1, t2;
SET sql_mode=DEFAULT;
#
# End of 10.5 tests
#
......@@ -745,3 +745,54 @@ DROP VIEW v1;
--echo #
--echo # End of 10.4 tests
--echo #
--echo #
--echo # Start of 10.5 tests
--echo #
--echo #
--echo # MDEV-20548 Unexpected error on CREATE..SELECT HEX(num)
--echo #
SET sql_mode=STRICT_ALL_TABLES;
CREATE TABLE t1 AS SELECT HEX(-2e0) AS h;
SELECT * FROM t1;
SHOW COLUMNS IN t1;
DROP TABLE t1;
CREATE TABLE t1 AS SELECT HEX(-1e0) AS h;
SELECT * FROM t1;
SHOW COLUMNS IN t1;
DROP TABLE t1;
CREATE TABLE t1 AS SELECT HEX(1e0) AS h;
SELECT * FROM t1;
SHOW COLUMNS IN t1;
DROP TABLE t1;
CREATE TABLE t1 AS SELECT HEX(2e0) AS h;
SELECT * FROM t1;
SHOW COLUMNS IN t1;
DROP TABLE t1;
CREATE TABLE t1 (a FLOAT);
INSERT INTO t1 VALUES (-1e38),(-255),(-2),(-1),(+1),(+2),(255),(1e38);
CREATE TABLE t2 AS SELECT a, HEX(a) AS h FROM t1;
SELECT * FROM t2 ORDER BY a;
SHOW COLUMNS IN t2;
DROP TABLE t1, t2;
CREATE TABLE t1 (a DOUBLE);
INSERT INTO t1 VALUES (-1e308),(-255),(-2),(-1),(+1),(+2),(255),(1e308);
CREATE TABLE t2 AS SELECT a, HEX(a) AS h FROM t1;
SELECT * FROM t2 ORDER BY a;
SHOW COLUMNS IN t2;
DROP TABLE t1, t2;
SET sql_mode=DEFAULT;
--echo #
--echo # End of 10.5 tests
--echo #
......@@ -1686,5 +1686,166 @@ c0
127
drop table t1;
#
# MDEV-20548 Unexpected error on CREATE..SELECT HEX(num)
#
SET sql_mode=STRICT_ALL_TABLES;
CREATE TABLE t1 AS SELECT HEX(-2) AS h;
SELECT * FROM t1;
h
FFFFFFFFFFFFFFFE
SHOW COLUMNS IN t1;
Field Type Null Key Default Extra
h varchar(16) YES NULL
DROP TABLE t1;
CREATE TABLE t1 AS SELECT HEX(-1) AS h;
SELECT * FROM t1;
h
FFFFFFFFFFFFFFFF
SHOW COLUMNS IN t1;
Field Type Null Key Default Extra
h varchar(16) YES NULL
DROP TABLE t1;
CREATE TABLE t1 AS SELECT HEX(1) AS h;
SELECT * FROM t1;
h
1
SHOW COLUMNS IN t1;
Field Type Null Key Default Extra
h varchar(16) YES NULL
DROP TABLE t1;
CREATE TABLE t1 AS SELECT HEX(2) AS h;
SELECT * FROM t1;
h
2
SHOW COLUMNS IN t1;
Field Type Null Key Default Extra
h varchar(16) YES NULL
DROP TABLE t1;
CREATE TABLE t1 (a TINYINT);
INSERT INTO t1 VALUES (-0x80),(-2),(-1),(1),(2),(0x7f);
CREATE TABLE t2 AS SELECT a, HEX(a) AS h FROM t1;
SELECT * FROM t2;
a h
-128 FFFFFFFFFFFFFF80
-2 FFFFFFFFFFFFFFFE
-1 FFFFFFFFFFFFFFFF
1 1
2 2
127 7F
SHOW COLUMNS IN t2;
Field Type Null Key Default Extra
a tinyint(4) YES NULL
h varchar(16) YES NULL
DROP TABLE t1, t2;
CREATE TABLE t1 (a SMALLINT);
INSERT INTO t1 VALUES (-0x8000),(-0x80),(-2),(-1),(1),(2),(0x7f),(0x7fff);
CREATE TABLE t2 AS SELECT a, HEX(a) AS h FROM t1;
SELECT * FROM t2;
a h
-32768 FFFFFFFFFFFF8000
-128 FFFFFFFFFFFFFF80
-2 FFFFFFFFFFFFFFFE
-1 FFFFFFFFFFFFFFFF
1 1
2 2
127 7F
32767 7FFF
SHOW COLUMNS IN t2;
Field Type Null Key Default Extra
a smallint(6) YES NULL
h varchar(16) YES NULL
DROP TABLE t1, t2;
CREATE TABLE t1 (a MEDIUMINT);
INSERT INTO t1 VALUES (-0x800000);
INSERT INTO t1 VALUES (-0x8000),(-0x80),(-2),(-1),(1),(2),(0x7f),(0x7fff);
INSERT INTO t1 VALUES (0x7fffff);
CREATE TABLE t2 AS SELECT a, HEX(a) AS h FROM t1;
SELECT * FROM t2;
a h
-8388608 FFFFFFFFFF800000
-32768 FFFFFFFFFFFF8000
-128 FFFFFFFFFFFFFF80
-2 FFFFFFFFFFFFFFFE
-1 FFFFFFFFFFFFFFFF
1 1
2 2
127 7F
32767 7FFF
8388607 7FFFFF
SHOW COLUMNS IN t2;
Field Type Null Key Default Extra
a mediumint(9) YES NULL
h varchar(16) YES NULL
DROP TABLE t1, t2;
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (-0x80000000);
INSERT INTO t1 VALUES (-0x800000);
INSERT INTO t1 VALUES (-0x8000),(-0x80),(-2),(-1),(1),(2),(0x7f),(0x7fff);
INSERT INTO t1 VALUES (0x7fffff);
INSERT INTO t1 VALUES (0x7fffffff);
CREATE TABLE t2 AS SELECT a, HEX(a) AS h FROM t1;
SELECT * FROM t2;
a h
-2147483648 FFFFFFFF80000000
-8388608 FFFFFFFFFF800000
-32768 FFFFFFFFFFFF8000
-128 FFFFFFFFFFFFFF80
-2 FFFFFFFFFFFFFFFE
-1 FFFFFFFFFFFFFFFF
1 1
2 2
127 7F
32767 7FFF
8388607 7FFFFF
2147483647 7FFFFFFF
SHOW COLUMNS IN t2;
Field Type Null Key Default Extra
a int(11) YES NULL
h varchar(16) YES NULL
DROP TABLE t1, t2;
CREATE TABLE t1 (a BIGINT);
INSERT INTO t1 VALUES (-0x8000000000000000);
INSERT INTO t1 VALUES (-0x80000000000000);
INSERT INTO t1 VALUES (-0x800000000000);
INSERT INTO t1 VALUES (-0x8000000000);
INSERT INTO t1 VALUES (-0x80000000);
INSERT INTO t1 VALUES (-0x800000);
INSERT INTO t1 VALUES (-0x8000),(-0x80),(-2),(-1),(1),(2),(0x7f),(0x7fff);
INSERT INTO t1 VALUES (0x7fffff);
INSERT INTO t1 VALUES (0x7fffffff);
INSERT INTO t1 VALUES (0x7fffffffff);
INSERT INTO t1 VALUES (0x7fffffffffff);
INSERT INTO t1 VALUES (0x7fffffffffffff);
INSERT INTO t1 VALUES (0x7fffffffffffffff);
CREATE TABLE t2 AS SELECT a, HEX(a) AS h FROM t1;
SELECT * FROM t2;
a h
-9223372036854775808 8000000000000000
-36028797018963968 FF80000000000000
-140737488355328 FFFF800000000000
-549755813888 FFFFFF8000000000
-2147483648 FFFFFFFF80000000
-8388608 FFFFFFFFFF800000
-32768 FFFFFFFFFFFF8000
-128 FFFFFFFFFFFFFF80
-2 FFFFFFFFFFFFFFFE
-1 FFFFFFFFFFFFFFFF
1 1
2 2
127 7F
32767 7FFF
8388607 7FFFFF
2147483647 7FFFFFFF
549755813887 7FFFFFFFFF
140737488355327 7FFFFFFFFFFF
36028797018963967 7FFFFFFFFFFFFF
9223372036854775807 7FFFFFFFFFFFFFFF
SHOW COLUMNS IN t2;
Field Type Null Key Default Extra
a bigint(20) YES NULL
h varchar(16) YES NULL
DROP TABLE t1, t2;
SET sql_mode=DEFAULT;
#
# End of 10.5 tests
#
......@@ -564,6 +564,88 @@ insert into t1 values (-128);
select * from t1 where 18446744073700599371 > c0;
drop table t1;
--echo #
--echo # MDEV-20548 Unexpected error on CREATE..SELECT HEX(num)
--echo #
SET sql_mode=STRICT_ALL_TABLES;
CREATE TABLE t1 AS SELECT HEX(-2) AS h;
SELECT * FROM t1;
SHOW COLUMNS IN t1;
DROP TABLE t1;
CREATE TABLE t1 AS SELECT HEX(-1) AS h;
SELECT * FROM t1;
SHOW COLUMNS IN t1;
DROP TABLE t1;
CREATE TABLE t1 AS SELECT HEX(1) AS h;
SELECT * FROM t1;
SHOW COLUMNS IN t1;
DROP TABLE t1;
CREATE TABLE t1 AS SELECT HEX(2) AS h;
SELECT * FROM t1;
SHOW COLUMNS IN t1;
DROP TABLE t1;
CREATE TABLE t1 (a TINYINT);
INSERT INTO t1 VALUES (-0x80),(-2),(-1),(1),(2),(0x7f);
CREATE TABLE t2 AS SELECT a, HEX(a) AS h FROM t1;
SELECT * FROM t2;
SHOW COLUMNS IN t2;
DROP TABLE t1, t2;
CREATE TABLE t1 (a SMALLINT);
INSERT INTO t1 VALUES (-0x8000),(-0x80),(-2),(-1),(1),(2),(0x7f),(0x7fff);
CREATE TABLE t2 AS SELECT a, HEX(a) AS h FROM t1;
SELECT * FROM t2;
SHOW COLUMNS IN t2;
DROP TABLE t1, t2;
CREATE TABLE t1 (a MEDIUMINT);
INSERT INTO t1 VALUES (-0x800000);
INSERT INTO t1 VALUES (-0x8000),(-0x80),(-2),(-1),(1),(2),(0x7f),(0x7fff);
INSERT INTO t1 VALUES (0x7fffff);
CREATE TABLE t2 AS SELECT a, HEX(a) AS h FROM t1;
SELECT * FROM t2;
SHOW COLUMNS IN t2;
DROP TABLE t1, t2;
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (-0x80000000);
INSERT INTO t1 VALUES (-0x800000);
INSERT INTO t1 VALUES (-0x8000),(-0x80),(-2),(-1),(1),(2),(0x7f),(0x7fff);
INSERT INTO t1 VALUES (0x7fffff);
INSERT INTO t1 VALUES (0x7fffffff);
CREATE TABLE t2 AS SELECT a, HEX(a) AS h FROM t1;
SELECT * FROM t2;
SHOW COLUMNS IN t2;
DROP TABLE t1, t2;
CREATE TABLE t1 (a BIGINT);
INSERT INTO t1 VALUES (-0x8000000000000000);
INSERT INTO t1 VALUES (-0x80000000000000);
INSERT INTO t1 VALUES (-0x800000000000);
INSERT INTO t1 VALUES (-0x8000000000);
INSERT INTO t1 VALUES (-0x80000000);
INSERT INTO t1 VALUES (-0x800000);
INSERT INTO t1 VALUES (-0x8000),(-0x80),(-2),(-1),(1),(2),(0x7f),(0x7fff);
INSERT INTO t1 VALUES (0x7fffff);
INSERT INTO t1 VALUES (0x7fffffff);
INSERT INTO t1 VALUES (0x7fffffffff);
INSERT INTO t1 VALUES (0x7fffffffffff);
INSERT INTO t1 VALUES (0x7fffffffffffff);
INSERT INTO t1 VALUES (0x7fffffffffffffff);
CREATE TABLE t2 AS SELECT a, HEX(a) AS h FROM t1;
SELECT * FROM t2;
SHOW COLUMNS IN t2;
DROP TABLE t1, t2;
SET sql_mode=DEFAULT;
--echo #
--echo # End of 10.5 tests
--echo #
......@@ -2801,3 +2801,77 @@ DROP TABLE t2,t1;
#
# End of 10.4 tests
#
#
# Start of 10.5 tests
#
#
# MDEV-20548 Unexpected error on CREATE..SELECT HEX(num)
#
SET sql_mode=STRICT_ALL_TABLES;
CREATE TABLE t1 AS SELECT HEX(-2) AS h;
SELECT * FROM t1;
h
FFFFFFFFFFFFFFFE
SHOW COLUMNS IN t1;
Field Type Null Key Default Extra
h varchar(16) YES NULL
DROP TABLE t1;
CREATE TABLE t1 AS SELECT HEX(-1) AS h;
SELECT * FROM t1;
h
FFFFFFFFFFFFFFFF
SHOW COLUMNS IN t1;
Field Type Null Key Default Extra
h varchar(16) YES NULL
DROP TABLE t1;
CREATE TABLE t1 AS SELECT HEX(+1) AS h;
SELECT * FROM t1;
h
1
SHOW COLUMNS IN t1;
Field Type Null Key Default Extra
h varchar(16) YES NULL
DROP TABLE t1;
CREATE TABLE t1 AS SELECT HEX(+2) AS h;
SELECT * FROM t1;
h
2
SHOW COLUMNS IN t1;
Field Type Null Key Default Extra
h varchar(16) YES NULL
DROP TABLE t1;
CREATE TABLE t1 (a DECIMAL(41,1));
INSERT INTO t1 VALUES (-1000000000000000000000000000000000000000);
INSERT INTO t1 VALUES (-0x8000000000);
INSERT INTO t1 VALUES (-0x80000000),(-0x800000),(-0x8000),(-0x80),(-2),(-1);
INSERT INTO t1 VALUES (1),(2),(128),(0x7fff),(0x7fffff),(0x7fffffff);
INSERT INTO t1 VALUES (+0x7fffffffff);
INSERT INTO t1 VALUES (+1000000000000000000000000000000000000000);
CREATE TABLE t2 AS SELECT a, HEX(a) AS h FROM t1;
SELECT * FROM t2 ORDER BY a;
a h
-1000000000000000000000000000000000000000.0 FFFFFFFFFFFFFFFF
-549755813888.0 FFFFFF8000000000
-2147483648.0 FFFFFFFF80000000
-8388608.0 FFFFFFFFFF800000
-32768.0 FFFFFFFFFFFF8000
-128.0 FFFFFFFFFFFFFF80
-2.0 FFFFFFFFFFFFFFFE
-1.0 FFFFFFFFFFFFFFFF
1.0 1
2.0 2
128.0 80
32767.0 7FFF
8388607.0 7FFFFF
2147483647.0 7FFFFFFF
549755813887.0 7FFFFFFFFF
1000000000000000000000000000000000000000.0 FFFFFFFFFFFFFFFF
SHOW COLUMNS IN t2;
Field Type Null Key Default Extra
a decimal(41,1) YES NULL
h varchar(16) YES NULL
DROP TABLE t1, t2;
SET sql_mode=DEFAULT;
#
# End of 10.5 tests
#
......@@ -2000,3 +2000,51 @@ DROP TABLE t2,t1;
--echo #
--echo # End of 10.4 tests
--echo #
--echo #
--echo # Start of 10.5 tests
--echo #
--echo #
--echo # MDEV-20548 Unexpected error on CREATE..SELECT HEX(num)
--echo #
SET sql_mode=STRICT_ALL_TABLES;
CREATE TABLE t1 AS SELECT HEX(-2) AS h;
SELECT * FROM t1;
SHOW COLUMNS IN t1;
DROP TABLE t1;
CREATE TABLE t1 AS SELECT HEX(-1) AS h;
SELECT * FROM t1;
SHOW COLUMNS IN t1;
DROP TABLE t1;
CREATE TABLE t1 AS SELECT HEX(+1) AS h;
SELECT * FROM t1;
SHOW COLUMNS IN t1;
DROP TABLE t1;
CREATE TABLE t1 AS SELECT HEX(+2) AS h;
SELECT * FROM t1;
SHOW COLUMNS IN t1;
DROP TABLE t1;
CREATE TABLE t1 (a DECIMAL(41,1));
INSERT INTO t1 VALUES (-1000000000000000000000000000000000000000);
INSERT INTO t1 VALUES (-0x8000000000);
INSERT INTO t1 VALUES (-0x80000000),(-0x800000),(-0x8000),(-0x80),(-2),(-1);
INSERT INTO t1 VALUES (1),(2),(128),(0x7fff),(0x7fffff),(0x7fffffff);
INSERT INTO t1 VALUES (+0x7fffffffff);
INSERT INTO t1 VALUES (+1000000000000000000000000000000000000000);
CREATE TABLE t2 AS SELECT a, HEX(a) AS h FROM t1;
SELECT * FROM t2 ORDER BY a;
SHOW COLUMNS IN t2;
DROP TABLE t1, t2;
SET sql_mode=DEFAULT;
--echo #
--echo # End of 10.5 tests
--echo #
......@@ -83,7 +83,7 @@ SELECT HEX(a), a;
END;
$$
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def HEX(a) 253 44 3 Y 0 0 8
def HEX(a) 253 16 3 Y 0 0 8
def a a 5 22 3 Y 32768 31 63
HEX(a) a
100 256
......
......@@ -62,7 +62,7 @@ SELECT HEX(a), a;
END;
$$
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def HEX(a) 253 40 3 Y 0 0 8
def HEX(a) 253 16 3 Y 0 0 8
def a a 8 20 3 Y 32768 0 63
HEX(a) a
100 256
......
......@@ -3770,9 +3770,11 @@ String *Item_func_hex::val_str_ascii_from_val_real(String *str)
return 0;
if ((val <= (double) LONGLONG_MIN) ||
(val >= (double) (ulonglong) ULONGLONG_MAX))
dec= ~(longlong) 0;
dec= ULONGLONG_MAX;
else if (val < 0)
dec= (ulonglong) (longlong) (val - 0.5);
else
dec= (ulonglong) (val + (val > 0 ? 0.5 : -0.5));
dec= (ulonglong) (val + 0.5);
return str->set_hex(dec) ? make_empty_result(str) : str;
}
......
......@@ -1379,10 +1379,20 @@ class Item_func_hex :public Item_str_ascii_checksum_func
}
bool fix_length_and_dec() override
{
m_arg0_type_handler= args[0]->type_handler();
collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
decimals=0;
fix_char_length(args[0]->max_length * 2);
m_arg0_type_handler= args[0]->type_handler();
/*
Reserve space for 16 characters for signed numeric data types:
hex(-1) -> 'FFFFFFFFFFFFFFFF'.
For unsigned numeric types, HEX() can create too large columns.
This should be eventually fixed to create minimum possible columns.
*/
const Type_handler_numeric *tn=
dynamic_cast<const Type_handler_numeric*>(m_arg0_type_handler);
size_t char_length= (tn && !(tn->flags() & UNSIGNED_FLAG)) ?
(size_t) 16 : (size_t) args[0]->max_length * 2;
fix_char_length(char_length);
return FALSE;
}
Item *get_copy(THD *thd) override
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment