summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/create.result2
-rw-r--r--mysql-test/r/null.result25
-rw-r--r--mysql-test/t/null.test27
-rw-r--r--sql/item_cmpfunc.cc18
4 files changed, 64 insertions, 8 deletions
diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result
index ab5d23d6cea..3d7486b6ba2 100644
--- a/mysql-test/r/create.result
+++ b/mysql-test/r/create.result
@@ -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
diff --git a/mysql-test/r/null.result b/mysql-test/r/null.result
index c33adee76b2..090f41baec3 100644
--- a/mysql-test/r/null.result
+++ b/mysql-test/r/null.result
@@ -1,4 +1,4 @@
-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
diff --git a/mysql-test/t/null.test b/mysql-test/t/null.test
index 65e09b006ec..2878b54c357 100644
--- a/mysql-test/t/null.test
+++ b/mysql-test/t/null.test
@@ -1,6 +1,6 @@
# 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
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 1599bcc1571..789b0f7edc0 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -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: