Fixed bug #31471: decimal_bin_size: Assertion `scale >= 0 &&

                  precision > 0 && scale <= precision'.

A sign of a resulting item of the IFNULL function was not
updated and the maximal length of this result was calculated
improperly. Correct algorithm was copy&pasted from the IF
function implementation.
parent 20ec6605
...@@ -425,7 +425,7 @@ explain t2; ...@@ -425,7 +425,7 @@ 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 0 b bigint(11) NO 0
c bigint(11) NO 0 c bigint(11) unsigned NO 0
d date YES NULL d date YES NULL
e varchar(1) NO e varchar(1) NO
f datetime YES NULL f datetime YES NULL
......
drop table if exists t1; drop table if exists t1, t2;
select null,\N,isnull(null),isnull(1/0),isnull(1/0 = null),ifnull(null,1),ifnull(null,"TRUE"),ifnull("TRUE","ERROR"),1/0 is null,1 is not null; select null,\N,isnull(null),isnull(1/0),isnull(1/0 = null),ifnull(null,1),ifnull(null,"TRUE"),ifnull("TRUE","ERROR"),1/0 is null,1 is not null;
NULL NULL isnull(null) isnull(1/0) isnull(1/0 = null) ifnull(null,1) ifnull(null,"TRUE") ifnull("TRUE","ERROR") 1/0 is null 1 is not null NULL NULL isnull(null) isnull(1/0) isnull(1/0 = null) ifnull(null,1) ifnull(null,"TRUE") ifnull("TRUE","ERROR") 1/0 is null 1 is not null
NULL NULL 1 1 1 1 TRUE TRUE 1 1 NULL NULL 1 1 1 1 TRUE TRUE 1 1
...@@ -320,3 +320,26 @@ bug19145c CREATE TABLE `bug19145c` ( ...@@ -320,3 +320,26 @@ bug19145c CREATE TABLE `bug19145c` (
drop table bug19145a; drop table bug19145a;
drop table bug19145b; drop table bug19145b;
drop table bug19145c; drop table bug19145c;
# End of 4.1 tests
#
# Bug #31471: decimal_bin_size: Assertion `scale >= 0 &&
# precision > 0 && scale <= precision'
#
CREATE TABLE t1 (a DECIMAL (1, 0) ZEROFILL, b DECIMAL (1, 0) ZEROFILL);
INSERT INTO t1 (a, b) VALUES (0, 0);
CREATE TABLE t2 SELECT IFNULL(a, b) FROM t1;
DESCRIBE t2;
Field Type Null Key Default Extra
IFNULL(a, b) decimal(1,0) unsigned YES NULL
DROP TABLE t2;
CREATE TABLE t2 SELECT IFNULL(a, NULL) FROM t1;
DESCRIBE t2;
Field Type Null Key Default Extra
IFNULL(a, NULL) decimal(1,0) YES NULL
DROP TABLE t2;
CREATE TABLE t2 SELECT IFNULL(NULL, b) FROM t1;
DESCRIBE t2;
Field Type Null Key Default Extra
IFNULL(NULL, b) decimal(1,0) YES NULL
DROP TABLE t1, t2;
# End of 5.0 tests
# Initialise # Initialise
--disable_warnings --disable_warnings
drop table if exists t1; drop table if exists t1, t2;
--enable_warnings --enable_warnings
# #
...@@ -231,4 +231,27 @@ drop table bug19145a; ...@@ -231,4 +231,27 @@ drop table bug19145a;
drop table bug19145b; drop table bug19145b;
drop table bug19145c; drop table bug19145c;
# End of 4.1 tests --echo # End of 4.1 tests
--echo #
--echo # Bug #31471: decimal_bin_size: Assertion `scale >= 0 &&
--echo # precision > 0 && scale <= precision'
--echo #
CREATE TABLE t1 (a DECIMAL (1, 0) ZEROFILL, b DECIMAL (1, 0) ZEROFILL);
INSERT INTO t1 (a, b) VALUES (0, 0);
CREATE TABLE t2 SELECT IFNULL(a, b) FROM t1;
DESCRIBE t2;
DROP TABLE t2;
CREATE TABLE t2 SELECT IFNULL(a, NULL) FROM t1;
DESCRIBE t2;
DROP TABLE t2;
CREATE TABLE t2 SELECT IFNULL(NULL, b) FROM t1;
DESCRIBE t2;
DROP TABLE t1, t2;
--echo # End of 5.0 tests
...@@ -2020,10 +2020,20 @@ Item_func_ifnull::fix_length_and_dec() ...@@ -2020,10 +2020,20 @@ Item_func_ifnull::fix_length_and_dec()
agg_result_type(&hybrid_type, args, 2); agg_result_type(&hybrid_type, args, 2);
maybe_null=args[1]->maybe_null; maybe_null=args[1]->maybe_null;
decimals= max(args[0]->decimals, args[1]->decimals); decimals= max(args[0]->decimals, args[1]->decimals);
max_length= (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT) ? unsigned_flag= args[0]->unsigned_flag && args[1]->unsigned_flag;
(max(args[0]->max_length - args[0]->decimals,
args[1]->max_length - args[1]->decimals) + decimals) : if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT)
max(args[0]->max_length, args[1]->max_length); {
int len0= args[0]->max_length - args[0]->decimals
- (args[0]->unsigned_flag ? 0 : 1);
int len1= args[1]->max_length - args[1]->decimals
- (args[1]->unsigned_flag ? 0 : 1);
max_length= max(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
}
else
max_length= max(args[0]->max_length, args[1]->max_length);
switch (hybrid_type) { switch (hybrid_type) {
case STRING_RESULT: case STRING_RESULT:
......
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