3286 Tor Didriksen 2011-07-21
Bug#12532830 - SIGFPE OR ASSERTION (PRECISION <= ((9 * 9) - 8*2)) && (DEC <= 30)
@ mysql-test/r/func_if.result
New test case.
@ mysql-test/suite/innodb/r/innodb_bug54044.result
If(xxxx, null, null) now returns binary(0) rater than null.
Add tests from bug#54044.
@ mysql-test/t/func_if.test
New test case.
@ sql/field.cc
Catch wrong value for decimals a bit earlier: when we create 'pack_flag'
rather than when we use it later to create Field_new_decimal.
@ sql/item_cmpfunc.cc
In Item_func_if::fix_length_and_dec(): save decimals (in addition to misc other properties) whenever one of the branches is a null_item.
Let other expressions (even if they evaluate to const-null) be handled
by the general mechanisms.
modified:
mysql-test/r/func_if.result
mysql-test/suite/innodb/r/innodb_bug54044.result
mysql-test/suite/innodb/t/innodb_bug54044.test
mysql-test/t/func_if.test
sql/field.cc
sql/item_cmpfunc.cc
sql/item_cmpfunc.h
3285 Bjorn Munch 2011-07-21
Followup to mysqltest/mtr option --opt-trace-protocol
Fixed some corner cases:
--send followed by stmt on separate line:
Drop doing optimizer trace in this case
--lowercase_result on a non-trivial statement
Turn off lower casing (as was done for sorting)
The first is fixed also for --explain-protocol
modified:
client/mysqltest.cc
=== modified file 'mysql-test/r/func_if.result'
--- a/mysql-test/r/func_if.result 2011-07-19 15:11:15 +0000
+++ b/mysql-test/r/func_if.result 2011-07-21 15:11:09 +0000
@@ -212,3 +212,17 @@ hello
SELECT if(1, NULL, (SELECT min('hello')));
if(1, NULL, (SELECT min('hello')))
NULL
+#
+# Bug#12532830
+# SIGFPE OR ASSERTION (PRECISION <= ((9 * 9) - 8*2)) && (DEC <= 30)
+#
+select
+sum(distinct(if('a',
+(select adddate(elt(convert(9999999999999999999999999999999999999,decimal(64,0)),count(*)),
+interval 1 day))
+, .1))) as foo;
+foo
+0.1
+Warnings:
+Warning 1292 Truncated incorrect DOUBLE value: 'a'
+Warning 1292 Truncated incorrect DOUBLE value: 'a'
=== modified file 'mysql-test/suite/innodb/r/innodb_bug54044.result'
--- a/mysql-test/suite/innodb/r/innodb_bug54044.result 2010-06-29 07:14:20 +0000
+++ b/mysql-test/suite/innodb/r/innodb_bug54044.result 2011-07-21 15:11:09 +0000
@@ -1,3 +1,12 @@
CREATE TEMPORARY TABLE table_54044 ENGINE = INNODB
AS SELECT IF(NULL IS NOT NULL, NULL, NULL);
-ERROR HY000: Can't create table 'test.table_54044' (errno: -1)
+SHOW CREATE TABLE table_54044;
+Table Create Table
+table_54044 CREATE TEMPORARY TABLE `table_54044` (
+ `IF(NULL IS NOT NULL, NULL, NULL)` binary(0) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+DROP TABLE table_54044;
+CREATE TABLE TMP ENGINE = INNODB AS SELECT COALESCE(NULL, NULL, NULL);
+ERROR HY000: Can't create table 'test.TMP' (errno: -1)
+CREATE TABLE TMP ENGINE = INNODB AS SELECT GREATEST(NULL, NULL);
+ERROR HY000: Can't create table 'test.TMP' (errno: -1)
=== modified file 'mysql-test/suite/innodb/t/innodb_bug54044.test'
--- a/mysql-test/suite/innodb/t/innodb_bug54044.test 2010-06-29 07:14:20 +0000
+++ b/mysql-test/suite/innodb/t/innodb_bug54044.test 2011-07-21 15:11:09 +0000
@@ -3,9 +3,17 @@
--source include/have_innodb.inc
-# This 'create table' operation should fail because of
-# using NULL datatype
---error ER_CANT_CREATE_TABLE
+# This 'create table' operation no longer uses the NULL datatype.
+
CREATE TEMPORARY TABLE table_54044 ENGINE = INNODB
AS SELECT IF(NULL IS NOT NULL, NULL, NULL);
+SHOW CREATE TABLE table_54044;
+DROP TABLE table_54044;
+# These 'create table' operations should fail because of
+# using NULL datatype
+
+--error ER_CANT_CREATE_TABLE
+CREATE TABLE TMP ENGINE = INNODB AS SELECT COALESCE(NULL, NULL, NULL);
+--error ER_CANT_CREATE_TABLE
+CREATE TABLE TMP ENGINE = INNODB AS SELECT GREATEST(NULL, NULL);
=== modified file 'mysql-test/t/func_if.test'
--- a/mysql-test/t/func_if.test 2011-06-30 12:57:20 +0000
+++ b/mysql-test/t/func_if.test 2011-07-21 15:11:09 +0000
@@ -187,3 +187,15 @@ SELECT if(0, (SELECT min('hello')), NULL
SELECT if(1, (SELECT min('hello')), NULL);
SELECT if(0, NULL, (SELECT min('hello')));
SELECT if(1, NULL, (SELECT min('hello')));
+
+--echo #
+--echo # Bug#12532830
+--echo # SIGFPE OR ASSERTION (PRECISION <= ((9 * 9) - 8*2)) && (DEC <= 30)
+--echo #
+
+let $nines= 9999999999999999999999999999999999999;
+eval select
+sum(distinct(if('a',
+ (select adddate(elt(convert($nines,decimal(64,0)),count(*)),
+ interval 1 day))
+ , .1))) as foo;
=== modified file 'sql/field.cc'
--- a/sql/field.cc 2011-07-04 00:25:46 +0000
+++ b/sql/field.cc 2011-07-21 15:11:09 +0000
@@ -9190,8 +9190,9 @@ void Create_field::init_for_tmp_table(en
pack_flag= FIELDFLAG_INTERVAL;
break;
- case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_NEWDECIMAL:
+ DBUG_ASSERT(decimals_arg <= DECIMAL_MAX_SCALE);
+ case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_FLOAT:
case MYSQL_TYPE_DOUBLE:
pack_flag= FIELDFLAG_NUMBER |
=== modified file 'sql/item_cmpfunc.cc'
--- a/sql/item_cmpfunc.cc 2011-07-19 15:11:15 +0000
+++ b/sql/item_cmpfunc.cc 2011-07-21 15:11:09 +0000
@@ -2720,37 +2720,43 @@ Item_func_if::fix_fields(THD *thd, Item
}
+void Item_func_if::cache_type_info(Item *source)
+{
+ collation.set(source->collation);
+ cached_field_type= source->field_type();
+ cached_result_type= source->result_type();
+ decimals= source->decimals;
+ max_length= source->max_length;
+ maybe_null= source->maybe_null;
+ unsigned_flag= source->unsigned_flag;
+}
+
+
void
Item_func_if::fix_length_and_dec()
{
- maybe_null=args[1]->maybe_null || args[2]->maybe_null;
- decimals= max(args[1]->decimals, args[2]->decimals);
- unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag;
-
- enum Item_result arg1_type=args[1]->result_type();
- enum Item_result arg2_type=args[2]->result_type();
- bool null1=args[1]->const_item() && args[1]->null_value;
- bool null2=args[2]->const_item() && args[2]->null_value;
-
- if (null1 && args[2]->type() != NULL_ITEM)
- {
- cached_result_type= arg2_type;
- collation.set(args[2]->collation);
- cached_field_type= args[2]->field_type();
- max_length= args[2]->max_length;
+ // Let IF(cond, expr, NULL) and IF(cond, NULL, expr) inherit type from expr.
+ if (args[1]->type() == NULL_ITEM)
+ {
+ cache_type_info(args[2]);
+ maybe_null= true;
+ // If both arguments are NULL, make resulting type BINARY(0).
+ if (args[2]->type() == NULL_ITEM)
+ cached_field_type= MYSQL_TYPE_STRING;
return;
}
-
- if (null2 && args[1]->type() != NULL_ITEM)
+ if (args[2]->type() == NULL_ITEM)
{
- cached_result_type= arg1_type;
- collation.set(args[1]->collation);
- cached_field_type= args[1]->field_type();
- max_length= args[1]->max_length;
+ cache_type_info(args[1]);
+ maybe_null= true;
return;
}
agg_result_type(&cached_result_type, args + 1, 2);
+ maybe_null= args[1]->maybe_null || args[2]->maybe_null;
+ decimals= max(args[1]->decimals, args[2]->decimals);
+ unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag;
+
if (cached_result_type == STRING_RESULT)
{
if (agg_arg_charsets_for_string_result(collation, args + 1, 2))
=== modified file 'sql/item_cmpfunc.h'
--- a/sql/item_cmpfunc.h 2011-07-19 15:11:15 +0000
+++ b/sql/item_cmpfunc.h 2011-07-21 15:11:09 +0000
@@ -818,6 +818,8 @@ public:
void fix_length_and_dec();
uint decimal_precision() const;
const char *func_name() const { return "if"; }
+private:
+ void cache_type_info(Item *source);
};
No bundle (reason: useless for push emails).
| Thread |
|---|
| • bzr push into mysql-trunk branch (tor.didriksen:3285 to 3286) Bug#12532830 | Tor Didriksen | 21 Jul |