Commit 356007a8 authored by gshchepa/uchum@gleb.loc's avatar gshchepa/uchum@gleb.loc
Browse files

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
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -425,7 +425,7 @@ explain t2;
Field	Type	Null	Key	Default	Extra
a	int(11)	YES		NULL	
b	bigint(11)	NO		0	
c	bigint(11)	NO		0	
c	bigint(11) unsigned	NO		0	
d	date	YES		NULL	
e	varchar(1)	NO			
f	datetime	YES		NULL	
+24 −1
Original line number Diff line number Diff line
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;
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
@@ -320,3 +320,26 @@ bug19145c CREATE TABLE `bug19145c` (
drop table bug19145a;
drop table bug19145b;
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
+25 −2
Original line number Diff line number Diff line
# Initialise
--disable_warnings
drop table if exists t1;
drop table if exists t1, t2;
--enable_warnings

#
@@ -231,4 +231,27 @@ drop table bug19145a;
drop table bug19145b;
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
+14 −4
Original line number Diff line number Diff line
@@ -2020,10 +2020,20 @@ Item_func_ifnull::fix_length_and_dec()
  agg_result_type(&hybrid_type, args, 2);
  maybe_null=args[1]->maybe_null;
  decimals= max(args[0]->decimals, args[1]->decimals);
  max_length= (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT) ?
    (max(args[0]->max_length - args[0]->decimals,
         args[1]->max_length - args[1]->decimals) + decimals) :
    max(args[0]->max_length, args[1]->max_length);
  unsigned_flag= args[0]->unsigned_flag && args[1]->unsigned_flag;

  if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT) 
  {
    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) {
  case STRING_RESULT: