Commit 67b0faa2 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-20495 Assertion `precision > 0' failed in decimal_bin_size upon CREATE .....

MDEV-20495 Assertion `precision > 0' failed in decimal_bin_size upon CREATE .. SELECT with zerofilled decimal

Also fixes:

MDEV-20560 Assertion `precision > 0' failed in decimal_bin_size upon SELECT with MOD short unsigned decimal

Changing the way how Item_func_mod calculates its max_length.
It now uses decimal_precision(), decimal_scale() and unsigned_flag
of its arguments, like all other Item_num_op descendants do.
parent fd3ad41e
......@@ -102,7 +102,7 @@ create table t1 as select concat(1 % 2) as c1;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` varbinary(1) DEFAULT NULL
`c1` varbinary(2) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
select hex(concat(-1));
......
......@@ -494,7 +494,7 @@ create table t1 as select concat(1 % 2) as c1;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` varchar(1) CHARACTER SET cp1251 DEFAULT NULL
`c1` varchar(2) CHARACTER SET cp1251 DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
select hex(concat(-1));
......
......@@ -676,7 +676,7 @@ create table t1 as select concat(1 % 2) as c1;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` varchar(1) DEFAULT NULL
`c1` varchar(2) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
select hex(concat(-1));
......
......@@ -1492,7 +1492,7 @@ create table t1 as select concat(1 % 2) as c1;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` varchar(1) CHARACTER SET ucs2 DEFAULT NULL
`c1` varchar(2) CHARACTER SET ucs2 DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
select hex(concat(-1));
......
......@@ -2313,7 +2313,7 @@ create table t1 as select concat(1 % 2) as c1;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` varchar(1) CHARACTER SET utf8 DEFAULT NULL
`c1` varchar(2) CHARACTER SET utf8 DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
select hex(concat(-1));
......
......@@ -771,5 +771,63 @@ STDDEV_SAMP(ROUND('0', 309))
0
DROP TABLE t1;
#
# MDEV-20495 Assertion `precision > 0' failed in decimal_bin_size upon CREATE .. SELECT with zerofilled decimal
#
# Testing that dyadic arithmetic operations are symmetric
# for (+1) and (-1) and produce the same length in CONCAT(),
# because (+1) and (-1) have the same data type: signed int.
CREATE TABLE t1 AS SELECT
CONCAT(+1%2.0),
CONCAT(-1%2.0),
CONCAT(+1/2.0),
CONCAT(-1/2.0),
CONCAT(+1*2.0),
CONCAT(-1*2.0),
CONCAT(+1+2.0),
CONCAT(-1+2.0),
CONCAT(+1-2.0),
CONCAT(-1-2.0);
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`CONCAT(+1%2.0)` varchar(4) DEFAULT NULL,
`CONCAT(-1%2.0)` varchar(4) DEFAULT NULL,
`CONCAT(+1/2.0)` varchar(8) DEFAULT NULL,
`CONCAT(-1/2.0)` varchar(8) DEFAULT NULL,
`CONCAT(+1*2.0)` varchar(5) NOT NULL DEFAULT '',
`CONCAT(-1*2.0)` varchar(5) NOT NULL DEFAULT '',
`CONCAT(+1+2.0)` varchar(5) NOT NULL DEFAULT '',
`CONCAT(-1+2.0)` varchar(5) NOT NULL DEFAULT '',
`CONCAT(+1-2.0)` varchar(5) NOT NULL DEFAULT '',
`CONCAT(-1-2.0)` varchar(5) NOT NULL DEFAULT ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
CREATE TABLE t1 AS SELECT
CONCAT(+1%2),
CONCAT(-1%2),
CONCAT(+1/2),
CONCAT(-1/2),
CONCAT(+1*2),
CONCAT(-1*2),
CONCAT(+1+2),
CONCAT(-1+2),
CONCAT(+1-2),
CONCAT(-1-2);
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`CONCAT(+1%2)` varchar(2) DEFAULT NULL,
`CONCAT(-1%2)` varchar(2) DEFAULT NULL,
`CONCAT(+1/2)` varchar(7) DEFAULT NULL,
`CONCAT(-1/2)` varchar(7) DEFAULT NULL,
`CONCAT(+1*2)` varchar(3) NOT NULL DEFAULT '',
`CONCAT(-1*2)` varchar(3) NOT NULL DEFAULT '',
`CONCAT(+1+2)` varchar(3) NOT NULL DEFAULT '',
`CONCAT(-1+2)` varchar(3) NOT NULL DEFAULT '',
`CONCAT(+1-2)` varchar(3) NOT NULL DEFAULT '',
`CONCAT(-1-2)` varchar(3) NOT NULL DEFAULT ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
#
# End of 5.5 tests
#
......@@ -2100,7 +2100,7 @@ CREATE TABLE t2 AS SELECT CONCAT(FROM_UNIXTIME(CONCAT(a,'10')) MOD FROM_UNIXTIME
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`f2` varchar(26) DEFAULT NULL
`f2` varchar(28) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SELECT * FROM t2;
f2
......
......@@ -2039,3 +2039,70 @@ t1 CREATE TABLE `t1` (
`1.0 * 2.000` decimal(6,4) NOT NULL DEFAULT '0.0000'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
#
# MDEV-20495 Assertion `precision > 0' failed in decimal_bin_size upon CREATE .. SELECT with zerofilled decimal
#
CREATE TABLE t1 (d DECIMAL(1,0) ZEROFILL);
CREATE TABLE t2 AS SELECT 0 MOD d AS f FROM t1;
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`f` decimal(1,0) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1, t2;
CREATE TABLE t1 (d DECIMAL(1,0) UNSIGNED);
CREATE TABLE t2 AS SELECT 0 MOD d AS f FROM t1;
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`f` decimal(1,0) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE IF EXISTS t1,t2;
CREATE TABLE t1 (d DECIMAL(1,0) ZEROFILL);
CREATE TABLE t2 AS SELECT CAST(0 AS UNSIGNED) MOD d AS f FROM t1;
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`f` decimal(1,0) unsigned DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1, t2;
CREATE TABLE t1 (d DECIMAL(1,0) UNSIGNED);
CREATE TABLE t2 AS SELECT CAST(0 AS UNSIGNED) MOD d AS f FROM t1;
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`f` decimal(1,0) unsigned DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1,t2;
#
# MDEV-20560 Assertion `precision > 0' failed in decimal_bin_size upon SELECT with MOD short unsigned decimal
#
CREATE TABLE t1 (a DECIMAL(1,0) UNSIGNED);
INSERT INTO t1 VALUES (1.0),(2.0);
SELECT DISTINCT 1 MOD a FROM t1;
1 MOD a
0
1
CREATE TABLE t2 AS SELECT DISTINCT 1 MOD a AS f FROM t1;
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`f` decimal(1,0) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1, t2;
CREATE TABLE t1 (a DECIMAL(1,0) UNSIGNED);
INSERT INTO t1 VALUES (1.0),(2.0);
SELECT DISTINCT 1 MOD a FROM t1;
1 MOD a
0
1
CREATE TABLE t2 AS SELECT DISTINCT CAST(1 AS UNSIGNED) MOD a AS f FROM t1;
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`f` decimal(1,0) unsigned DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1, t2;
#
# End of 5.5 tests
#
......@@ -576,6 +576,44 @@ INSERT INTO t1 VALUES (1),(2);
SELECT STDDEV_SAMP(ROUND('0', 309)) FROM t1;
DROP TABLE t1;
--echo #
--echo # MDEV-20495 Assertion `precision > 0' failed in decimal_bin_size upon CREATE .. SELECT with zerofilled decimal
--echo #
--echo # Testing that dyadic arithmetic operations are symmetric
--echo # for (+1) and (-1) and produce the same length in CONCAT(),
--echo # because (+1) and (-1) have the same data type: signed int.
CREATE TABLE t1 AS SELECT
CONCAT(+1%2.0),
CONCAT(-1%2.0),
CONCAT(+1/2.0),
CONCAT(-1/2.0),
CONCAT(+1*2.0),
CONCAT(-1*2.0),
CONCAT(+1+2.0),
CONCAT(-1+2.0),
CONCAT(+1-2.0),
CONCAT(-1-2.0);
SHOW CREATE TABLE t1;
DROP TABLE t1;
CREATE TABLE t1 AS SELECT
CONCAT(+1%2),
CONCAT(-1%2),
CONCAT(+1/2),
CONCAT(-1/2),
CONCAT(+1*2),
CONCAT(-1*2),
CONCAT(+1+2),
CONCAT(-1+2),
CONCAT(+1-2),
CONCAT(-1-2);
SHOW CREATE TABLE t1;
DROP TABLE t1;
--echo #
--echo # End of 5.5 tests
--echo #
......@@ -1625,3 +1625,48 @@ SHOW CREATE TABLE t1;
DROP TABLE t1;
--echo #
--echo # MDEV-20495 Assertion `precision > 0' failed in decimal_bin_size upon CREATE .. SELECT with zerofilled decimal
--echo #
CREATE TABLE t1 (d DECIMAL(1,0) ZEROFILL);
CREATE TABLE t2 AS SELECT 0 MOD d AS f FROM t1;
SHOW CREATE TABLE t2;
DROP TABLE t1, t2;
CREATE TABLE t1 (d DECIMAL(1,0) UNSIGNED);
CREATE TABLE t2 AS SELECT 0 MOD d AS f FROM t1;
SHOW CREATE TABLE t2;
DROP TABLE IF EXISTS t1,t2;
CREATE TABLE t1 (d DECIMAL(1,0) ZEROFILL);
CREATE TABLE t2 AS SELECT CAST(0 AS UNSIGNED) MOD d AS f FROM t1;
SHOW CREATE TABLE t2;
DROP TABLE t1, t2;
CREATE TABLE t1 (d DECIMAL(1,0) UNSIGNED);
CREATE TABLE t2 AS SELECT CAST(0 AS UNSIGNED) MOD d AS f FROM t1;
SHOW CREATE TABLE t2;
DROP TABLE t1,t2;
--echo #
--echo # MDEV-20560 Assertion `precision > 0' failed in decimal_bin_size upon SELECT with MOD short unsigned decimal
--echo #
CREATE TABLE t1 (a DECIMAL(1,0) UNSIGNED);
INSERT INTO t1 VALUES (1.0),(2.0);
SELECT DISTINCT 1 MOD a FROM t1;
CREATE TABLE t2 AS SELECT DISTINCT 1 MOD a AS f FROM t1;
SHOW CREATE TABLE t2;
DROP TABLE t1, t2;
CREATE TABLE t1 (a DECIMAL(1,0) UNSIGNED);
INSERT INTO t1 VALUES (1.0),(2.0);
SELECT DISTINCT 1 MOD a FROM t1;
CREATE TABLE t2 AS SELECT DISTINCT CAST(1 AS UNSIGNED) MOD a AS f FROM t1;
SHOW CREATE TABLE t2;
DROP TABLE t1, t2;
--echo #
--echo # End of 5.5 tests
--echo #
......@@ -2056,8 +2056,11 @@ my_decimal *Item_func_mod::decimal_op(my_decimal *decimal_value)
void Item_func_mod::result_precision()
{
unsigned_flag= args[0]->unsigned_flag;
decimals= max(args[0]->decimal_scale(), args[1]->decimal_scale());
max_length= max(args[0]->max_length, args[1]->max_length);
uint prec= max(args[0]->decimal_precision(), args[1]->decimal_precision());
fix_char_length(my_decimal_precision_to_length_no_truncation(prec, decimals,
unsigned_flag));
}
......@@ -2065,6 +2068,10 @@ void Item_func_mod::fix_length_and_dec()
{
Item_num_op::fix_length_and_dec();
maybe_null= 1;
/*
result_precision() sets unsigned_flag for INT_RESULT and DECIMAL_RESULT.
Here we need to set it in case of REAL_RESULT.
*/
unsigned_flag= args[0]->unsigned_flag;
}
......
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