Backport from trunk of:
Bug#12532830 - SIGFPE OR ASSERTION (PRECISION <= ((9 * 9) - 8*2)) && (DEC <= 30)
This commit is contained in:
parent
0b78d56412
commit
af6f0876ad
@ -196,3 +196,17 @@ c
|
|||||||
NULL
|
NULL
|
||||||
0
|
0
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# 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'
|
||||||
|
@ -1,3 +1,12 @@
|
|||||||
CREATE TEMPORARY TABLE table_54044 ENGINE = INNODB
|
CREATE TEMPORARY TABLE table_54044 ENGINE = INNODB
|
||||||
AS SELECT IF(NULL IS NOT NULL, NULL, NULL);
|
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)
|
||||||
|
@ -3,9 +3,17 @@
|
|||||||
|
|
||||||
--source include/have_innodb.inc
|
--source include/have_innodb.inc
|
||||||
|
|
||||||
# This 'create table' operation should fail because of
|
# This 'create table' operation no longer uses the NULL datatype.
|
||||||
# using NULL datatype
|
|
||||||
--error ER_CANT_CREATE_TABLE
|
|
||||||
CREATE TEMPORARY TABLE table_54044 ENGINE = INNODB
|
CREATE TEMPORARY TABLE table_54044 ENGINE = INNODB
|
||||||
AS SELECT IF(NULL IS NOT NULL, NULL, NULL);
|
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);
|
||||||
|
@ -177,3 +177,15 @@ INSERT INTO t1 VALUES (NULL, 0), (NULL, 1);
|
|||||||
SELECT IF(b, (SELECT a FROM t1 LIMIT 1), b) c FROM t1 GROUP BY c;
|
SELECT IF(b, (SELECT a FROM t1 LIMIT 1), b) c FROM t1 GROUP BY c;
|
||||||
|
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--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;
|
||||||
|
@ -9159,8 +9159,9 @@ void Create_field::init_for_tmp_table(enum_field_types sql_type_arg,
|
|||||||
pack_flag= FIELDFLAG_INTERVAL;
|
pack_flag= FIELDFLAG_INTERVAL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MYSQL_TYPE_DECIMAL:
|
|
||||||
case MYSQL_TYPE_NEWDECIMAL:
|
case MYSQL_TYPE_NEWDECIMAL:
|
||||||
|
DBUG_ASSERT(decimals_arg <= DECIMAL_MAX_SCALE);
|
||||||
|
case MYSQL_TYPE_DECIMAL:
|
||||||
case MYSQL_TYPE_FLOAT:
|
case MYSQL_TYPE_FLOAT:
|
||||||
case MYSQL_TYPE_DOUBLE:
|
case MYSQL_TYPE_DOUBLE:
|
||||||
pack_flag= FIELDFLAG_NUMBER |
|
pack_flag= FIELDFLAG_NUMBER |
|
||||||
|
@ -2625,37 +2625,43 @@ Item_func_if::fix_fields(THD *thd, Item **ref)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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
|
void
|
||||||
Item_func_if::fix_length_and_dec()
|
Item_func_if::fix_length_and_dec()
|
||||||
{
|
{
|
||||||
maybe_null=args[1]->maybe_null || args[2]->maybe_null;
|
// Let IF(cond, expr, NULL) and IF(cond, NULL, expr) inherit type from expr.
|
||||||
decimals= max(args[1]->decimals, args[2]->decimals);
|
if (args[1]->type() == NULL_ITEM)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
cached_result_type= arg2_type;
|
cache_type_info(args[2]);
|
||||||
collation.set(args[2]->collation);
|
maybe_null= true;
|
||||||
cached_field_type= args[2]->field_type();
|
// If both arguments are NULL, make resulting type BINARY(0).
|
||||||
max_length= args[2]->max_length;
|
if (args[2]->type() == NULL_ITEM)
|
||||||
|
cached_field_type= MYSQL_TYPE_STRING;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (args[2]->type() == NULL_ITEM)
|
||||||
if (null2)
|
|
||||||
{
|
{
|
||||||
cached_result_type= arg1_type;
|
cache_type_info(args[1]);
|
||||||
collation.set(args[1]->collation);
|
maybe_null= true;
|
||||||
cached_field_type= args[1]->field_type();
|
|
||||||
max_length= args[1]->max_length;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
agg_result_type(&cached_result_type, args + 1, 2);
|
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 (cached_result_type == STRING_RESULT)
|
||||||
{
|
{
|
||||||
if (agg_arg_charsets_for_string_result(collation, args + 1, 2))
|
if (agg_arg_charsets_for_string_result(collation, args + 1, 2))
|
||||||
|
@ -750,6 +750,8 @@ public:
|
|||||||
void fix_length_and_dec();
|
void fix_length_and_dec();
|
||||||
uint decimal_precision() const;
|
uint decimal_precision() const;
|
||||||
const char *func_name() const { return "if"; }
|
const char *func_name() const { return "if"; }
|
||||||
|
private:
|
||||||
|
void cache_type_info(Item *source);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user