Commit 8f607aae authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-4283 Assertion `scale <= precision' fails in strings/decimal.c

  
with decimals=NOT_FIXED_DEC it is possible to have 'decimals' larger
than 'max_length', it's not an error for temporal functions.
  
But when Item_func_numhybrid converts the value to DECIMAL_RESULT,
it must limit 'decimals' to be a valid scale of a decimal number.
parent 3827d70a
create table t1 (a int);
insert into t1 values (4),(8);
select distinct 100 mod timestampadd( week, a, '2002-05-20' ) from t1;
100 mod timestampadd( week, a, '2002-05-20' )
100
drop table t1;
create table t1 (i int);
insert into t1 values (2),(4);
select distinct convert_tz( '2001-03-21', 'utc', 'met' ) mod i from t1;
convert_tz( '2001-03-21', 'utc', 'met' ) mod i
0
drop table t1;
#
# MDEV-4283 Assertion `scale <= precision' fails in strings/decimal.c
#
create table t1 (a int);
insert into t1 values (4),(8);
select distinct 100 mod timestampadd( week, a, '2002-05-20' ) from t1;
drop table t1;
create table t1 (i int);
insert into t1 values (2),(4);
select distinct convert_tz( '2001-03-21', 'utc', 'met' ) mod i from t1;
drop table t1;
...@@ -742,13 +742,14 @@ void Item_num_op::find_num_type(void) ...@@ -742,13 +742,14 @@ void Item_num_op::find_num_type(void)
{ {
hybrid_type= DECIMAL_RESULT; hybrid_type= DECIMAL_RESULT;
result_precision(); result_precision();
fix_decimals();
} }
else else
{ {
DBUG_ASSERT(r0 == INT_RESULT && r1 == INT_RESULT); DBUG_ASSERT(r0 == INT_RESULT && r1 == INT_RESULT);
decimals= 0;
hybrid_type=INT_RESULT; hybrid_type=INT_RESULT;
result_precision(); result_precision();
decimals= 0;
} }
DBUG_PRINT("info", ("Type: %s", DBUG_PRINT("info", ("Type: %s",
(hybrid_type == REAL_RESULT ? "REAL_RESULT" : (hybrid_type == REAL_RESULT ? "REAL_RESULT" :
...@@ -1492,6 +1493,7 @@ void Item_func_div::fix_length_and_dec() ...@@ -1492,6 +1493,7 @@ void Item_func_div::fix_length_and_dec()
break; break;
case DECIMAL_RESULT: case DECIMAL_RESULT:
result_precision(); result_precision();
fix_decimals();
break; break;
case STRING_RESULT: case STRING_RESULT:
case ROW_RESULT: case ROW_RESULT:
......
...@@ -348,6 +348,13 @@ class Item_func_numhybrid: public Item_func ...@@ -348,6 +348,13 @@ class Item_func_numhybrid: public Item_func
void fix_num_length_and_dec(); void fix_num_length_and_dec();
virtual void find_num_type()= 0; /* To be called from fix_length_and_dec */ virtual void find_num_type()= 0; /* To be called from fix_length_and_dec */
inline void fix_decimals()
{
DBUG_ASSERT(result_type() == DECIMAL_RESULT);
if (decimals == NOT_FIXED_DEC)
set_if_smaller(decimals, max_length - 1);
}
double val_real(); double val_real();
longlong val_int(); longlong val_int();
my_decimal *val_decimal(my_decimal *); my_decimal *val_decimal(my_decimal *);
......
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