Manual merge.
This commit is contained in:
commit
2d4df13ef2
@ -1524,10 +1524,10 @@ Warnings:
|
|||||||
Warning 1264 Out of range value for column 'f1' at row 1
|
Warning 1264 Out of range value for column 'f1' at row 1
|
||||||
DESC t1;
|
DESC t1;
|
||||||
Field Type Null Key Default Extra
|
Field Type Null Key Default Extra
|
||||||
f1 decimal(59,30) NO 0.000000000000000000000000000000
|
f1 decimal(65,30) NO 0.000000000000000000000000000000
|
||||||
SELECT f1 FROM t1;
|
SELECT f1 FROM t1;
|
||||||
f1
|
f1
|
||||||
99999999999999999999999999999.999999999999999999999999999999
|
99999999999999999999999999999999999.999999999999999999999999999999
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
select (1.20396873 * 0.89550000 * 0.68000000 * 1.08721696 * 0.99500000 *
|
select (1.20396873 * 0.89550000 * 0.68000000 * 1.08721696 * 0.99500000 *
|
||||||
1.01500000 * 1.01500000 * 0.99500000);
|
1.01500000 * 1.01500000 * 0.99500000);
|
||||||
@ -1577,3 +1577,56 @@ Error 1264 Out of range value for column 'cast(-13.4 as decimal(2,1))' at row 1
|
|||||||
select cast(98.6 as decimal(2,0));
|
select cast(98.6 as decimal(2,0));
|
||||||
cast(98.6 as decimal(2,0))
|
cast(98.6 as decimal(2,0))
|
||||||
99
|
99
|
||||||
|
#
|
||||||
|
# Bug #45262: Bad effects with CREATE TABLE and DECIMAL
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 SELECT .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col;
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'my_col' at row 1
|
||||||
|
DESCRIBE t1;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
my_col decimal(30,30) NO 0.000000000000000000000000000000
|
||||||
|
SELECT my_col FROM t1;
|
||||||
|
my_col
|
||||||
|
0.123456789123456789123456789123
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 SELECT 1 + .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col;
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'my_col' at row 1
|
||||||
|
DESCRIBE t1;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
my_col decimal(65,30) NO 0.000000000000000000000000000000
|
||||||
|
SELECT my_col FROM t1;
|
||||||
|
my_col
|
||||||
|
1.123456789123456789123456789123
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 SELECT 1 * .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col;
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'my_col' at row 1
|
||||||
|
DESCRIBE t1;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
my_col decimal(65,30) NO 0.000000000000000000000000000000
|
||||||
|
SELECT my_col FROM t1;
|
||||||
|
my_col
|
||||||
|
0.123456789123456789123456789123
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 SELECT 1 / .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col;
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'my_col' at row 1
|
||||||
|
DESCRIBE t1;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
my_col decimal(65,4) YES NULL
|
||||||
|
SELECT my_col FROM t1;
|
||||||
|
my_col
|
||||||
|
8.1000
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 SELECT 1 % .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col;
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'my_col' at row 1
|
||||||
|
DESCRIBE t1;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
my_col decimal(65,30) YES NULL
|
||||||
|
SELECT my_col FROM t1;
|
||||||
|
my_col
|
||||||
|
0.012345687012345687012345687012
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -1257,3 +1257,32 @@ select cast(-3.4 as decimal(2,1));
|
|||||||
select cast(99.6 as decimal(2,0));
|
select cast(99.6 as decimal(2,0));
|
||||||
select cast(-13.4 as decimal(2,1));
|
select cast(-13.4 as decimal(2,1));
|
||||||
select cast(98.6 as decimal(2,0));
|
select cast(98.6 as decimal(2,0));
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug #45262: Bad effects with CREATE TABLE and DECIMAL
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 SELECT .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col;
|
||||||
|
DESCRIBE t1;
|
||||||
|
SELECT my_col FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 SELECT 1 + .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col;
|
||||||
|
DESCRIBE t1;
|
||||||
|
SELECT my_col FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 SELECT 1 * .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col;
|
||||||
|
DESCRIBE t1;
|
||||||
|
SELECT my_col FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 SELECT 1 / .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col;
|
||||||
|
DESCRIBE t1;
|
||||||
|
SELECT my_col FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 SELECT 1 % .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col;
|
||||||
|
DESCRIBE t1;
|
||||||
|
SELECT my_col FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
49
sql/item.cc
49
sql/item.cc
@ -2260,8 +2260,10 @@ Item_decimal::Item_decimal(const char *str_arg, uint length,
|
|||||||
name= (char*) str_arg;
|
name= (char*) str_arg;
|
||||||
decimals= (uint8) decimal_value.frac;
|
decimals= (uint8) decimal_value.frac;
|
||||||
fixed= 1;
|
fixed= 1;
|
||||||
max_length= my_decimal_precision_to_length(decimal_value.intg + decimals,
|
max_length= my_decimal_precision_to_length_no_truncation(decimal_value.intg +
|
||||||
decimals, unsigned_flag);
|
decimals,
|
||||||
|
decimals,
|
||||||
|
unsigned_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
Item_decimal::Item_decimal(longlong val, bool unsig)
|
Item_decimal::Item_decimal(longlong val, bool unsig)
|
||||||
@ -2269,8 +2271,10 @@ Item_decimal::Item_decimal(longlong val, bool unsig)
|
|||||||
int2my_decimal(E_DEC_FATAL_ERROR, val, unsig, &decimal_value);
|
int2my_decimal(E_DEC_FATAL_ERROR, val, unsig, &decimal_value);
|
||||||
decimals= (uint8) decimal_value.frac;
|
decimals= (uint8) decimal_value.frac;
|
||||||
fixed= 1;
|
fixed= 1;
|
||||||
max_length= my_decimal_precision_to_length(decimal_value.intg + decimals,
|
max_length= my_decimal_precision_to_length_no_truncation(decimal_value.intg +
|
||||||
decimals, unsigned_flag);
|
decimals,
|
||||||
|
decimals,
|
||||||
|
unsigned_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2279,8 +2283,10 @@ Item_decimal::Item_decimal(double val, int precision, int scale)
|
|||||||
double2my_decimal(E_DEC_FATAL_ERROR, val, &decimal_value);
|
double2my_decimal(E_DEC_FATAL_ERROR, val, &decimal_value);
|
||||||
decimals= (uint8) decimal_value.frac;
|
decimals= (uint8) decimal_value.frac;
|
||||||
fixed= 1;
|
fixed= 1;
|
||||||
max_length= my_decimal_precision_to_length(decimal_value.intg + decimals,
|
max_length= my_decimal_precision_to_length_no_truncation(decimal_value.intg +
|
||||||
decimals, unsigned_flag);
|
decimals,
|
||||||
|
decimals,
|
||||||
|
unsigned_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2300,8 +2306,10 @@ Item_decimal::Item_decimal(my_decimal *value_par)
|
|||||||
my_decimal2decimal(value_par, &decimal_value);
|
my_decimal2decimal(value_par, &decimal_value);
|
||||||
decimals= (uint8) decimal_value.frac;
|
decimals= (uint8) decimal_value.frac;
|
||||||
fixed= 1;
|
fixed= 1;
|
||||||
max_length= my_decimal_precision_to_length(decimal_value.intg + decimals,
|
max_length= my_decimal_precision_to_length_no_truncation(decimal_value.intg +
|
||||||
decimals, unsigned_flag);
|
decimals,
|
||||||
|
decimals,
|
||||||
|
unsigned_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2311,8 +2319,8 @@ Item_decimal::Item_decimal(const uchar *bin, int precision, int scale)
|
|||||||
&decimal_value, precision, scale);
|
&decimal_value, precision, scale);
|
||||||
decimals= (uint8) decimal_value.frac;
|
decimals= (uint8) decimal_value.frac;
|
||||||
fixed= 1;
|
fixed= 1;
|
||||||
max_length= my_decimal_precision_to_length(precision, decimals,
|
max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
|
||||||
unsigned_flag);
|
unsigned_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2367,8 +2375,10 @@ void Item_decimal::set_decimal_value(my_decimal *value_par)
|
|||||||
my_decimal2decimal(value_par, &decimal_value);
|
my_decimal2decimal(value_par, &decimal_value);
|
||||||
decimals= (uint8) decimal_value.frac;
|
decimals= (uint8) decimal_value.frac;
|
||||||
unsigned_flag= !decimal_value.sign();
|
unsigned_flag= !decimal_value.sign();
|
||||||
max_length= my_decimal_precision_to_length(decimal_value.intg + decimals,
|
max_length= my_decimal_precision_to_length_no_truncation(decimal_value.intg +
|
||||||
decimals, unsigned_flag);
|
decimals,
|
||||||
|
decimals,
|
||||||
|
unsigned_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2640,8 +2650,9 @@ void Item_param::set_decimal(const char *str, ulong length)
|
|||||||
str2my_decimal(E_DEC_FATAL_ERROR, str, &decimal_value, &end);
|
str2my_decimal(E_DEC_FATAL_ERROR, str, &decimal_value, &end);
|
||||||
state= DECIMAL_VALUE;
|
state= DECIMAL_VALUE;
|
||||||
decimals= decimal_value.frac;
|
decimals= decimal_value.frac;
|
||||||
max_length= my_decimal_precision_to_length(decimal_value.precision(),
|
max_length=
|
||||||
decimals, unsigned_flag);
|
my_decimal_precision_to_length_no_truncation(decimal_value.precision(),
|
||||||
|
decimals, unsigned_flag);
|
||||||
maybe_null= 0;
|
maybe_null= 0;
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
@ -2797,8 +2808,9 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry)
|
|||||||
my_decimal2decimal(ent_value, &decimal_value);
|
my_decimal2decimal(ent_value, &decimal_value);
|
||||||
state= DECIMAL_VALUE;
|
state= DECIMAL_VALUE;
|
||||||
decimals= ent_value->frac;
|
decimals= ent_value->frac;
|
||||||
max_length= my_decimal_precision_to_length(ent_value->precision(),
|
max_length=
|
||||||
decimals, unsigned_flag);
|
my_decimal_precision_to_length_no_truncation(ent_value->precision(),
|
||||||
|
decimals, unsigned_flag);
|
||||||
item_type= Item::DECIMAL_ITEM;
|
item_type= Item::DECIMAL_ITEM;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -7290,8 +7302,9 @@ bool Item_type_holder::join_types(THD *thd, Item *item)
|
|||||||
int item_prec = max(prev_decimal_int_part, item_int_part) + decimals;
|
int item_prec = max(prev_decimal_int_part, item_int_part) + decimals;
|
||||||
int precision= min(item_prec, DECIMAL_MAX_PRECISION);
|
int precision= min(item_prec, DECIMAL_MAX_PRECISION);
|
||||||
unsigned_flag&= item->unsigned_flag;
|
unsigned_flag&= item->unsigned_flag;
|
||||||
max_length= my_decimal_precision_to_length(precision, decimals,
|
max_length= my_decimal_precision_to_length_no_truncation(precision,
|
||||||
unsigned_flag);
|
decimals,
|
||||||
|
unsigned_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (Field::result_merge_type(fld_type))
|
switch (Field::result_merge_type(fld_type))
|
||||||
|
@ -2760,8 +2760,9 @@ void Item_func_case::fix_length_and_dec()
|
|||||||
agg_num_lengths(args[i + 1]);
|
agg_num_lengths(args[i + 1]);
|
||||||
if (else_expr_num != -1)
|
if (else_expr_num != -1)
|
||||||
agg_num_lengths(args[else_expr_num]);
|
agg_num_lengths(args[else_expr_num]);
|
||||||
max_length= my_decimal_precision_to_length(max_length + decimals, decimals,
|
max_length= my_decimal_precision_to_length_no_truncation(max_length +
|
||||||
unsigned_flag);
|
decimals, decimals,
|
||||||
|
unsigned_flag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,11 +452,45 @@ Field *Item_func::tmp_table_field(TABLE *table)
|
|||||||
return make_string_field(table);
|
return make_string_field(table);
|
||||||
break;
|
break;
|
||||||
case DECIMAL_RESULT:
|
case DECIMAL_RESULT:
|
||||||
field= new Field_new_decimal(my_decimal_precision_to_length(decimal_precision(),
|
{
|
||||||
decimals,
|
uint8 dec= decimals;
|
||||||
unsigned_flag),
|
uint8 intg= decimal_precision() - dec;
|
||||||
maybe_null, name, decimals, unsigned_flag);
|
uint32 len= max_length;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Trying to put too many digits overall in a DECIMAL(prec,dec)
|
||||||
|
will always throw a warning. We must limit dec to
|
||||||
|
DECIMAL_MAX_SCALE however to prevent an assert() later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (dec > 0)
|
||||||
|
{
|
||||||
|
int overflow;
|
||||||
|
|
||||||
|
dec= min(dec, DECIMAL_MAX_SCALE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
If the value still overflows the field with the corrected dec,
|
||||||
|
we'll throw out decimals rather than integers. This is still
|
||||||
|
bad and of course throws a truncation warning.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const int required_length=
|
||||||
|
my_decimal_precision_to_length(intg + dec, dec,
|
||||||
|
unsigned_flag);
|
||||||
|
|
||||||
|
overflow= required_length - len;
|
||||||
|
|
||||||
|
if (overflow > 0)
|
||||||
|
dec= max(0, dec - overflow); // too long, discard fract
|
||||||
|
else
|
||||||
|
/* Corrected value fits. */
|
||||||
|
len= required_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
field= new Field_new_decimal(len, maybe_null, name, dec, unsigned_flag);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case ROW_RESULT:
|
case ROW_RESULT:
|
||||||
default:
|
default:
|
||||||
// This case should never be chosen
|
// This case should never be chosen
|
||||||
@ -545,8 +579,8 @@ void Item_func::count_decimal_length()
|
|||||||
set_if_smaller(unsigned_flag, args[i]->unsigned_flag);
|
set_if_smaller(unsigned_flag, args[i]->unsigned_flag);
|
||||||
}
|
}
|
||||||
int precision= min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
|
int precision= min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
|
||||||
max_length= my_decimal_precision_to_length(precision, decimals,
|
max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
|
||||||
unsigned_flag);
|
unsigned_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1141,16 +1175,15 @@ void Item_func_additive_op::result_precision()
|
|||||||
decimals= max(args[0]->decimals, args[1]->decimals);
|
decimals= max(args[0]->decimals, args[1]->decimals);
|
||||||
int arg1_int= args[0]->decimal_precision() - args[0]->decimals;
|
int arg1_int= args[0]->decimal_precision() - args[0]->decimals;
|
||||||
int arg2_int= args[1]->decimal_precision() - args[1]->decimals;
|
int arg2_int= args[1]->decimal_precision() - args[1]->decimals;
|
||||||
int est_prec= max(arg1_int, arg2_int) + 1 + decimals;
|
int precision= max(arg1_int, arg2_int) + 1 + decimals;
|
||||||
int precision= min(est_prec, DECIMAL_MAX_PRECISION);
|
|
||||||
|
|
||||||
/* Integer operations keep unsigned_flag if one of arguments is unsigned */
|
/* Integer operations keep unsigned_flag if one of arguments is unsigned */
|
||||||
if (result_type() == INT_RESULT)
|
if (result_type() == INT_RESULT)
|
||||||
unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;
|
unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;
|
||||||
else
|
else
|
||||||
unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag;
|
unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag;
|
||||||
max_length= my_decimal_precision_to_length(precision, decimals,
|
max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
|
||||||
unsigned_flag);
|
unsigned_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1255,7 +1288,8 @@ void Item_func_mul::result_precision()
|
|||||||
decimals= min(args[0]->decimals + args[1]->decimals, DECIMAL_MAX_SCALE);
|
decimals= min(args[0]->decimals + args[1]->decimals, DECIMAL_MAX_SCALE);
|
||||||
uint est_prec = args[0]->decimal_precision() + args[1]->decimal_precision();
|
uint est_prec = args[0]->decimal_precision() + args[1]->decimal_precision();
|
||||||
uint precision= min(est_prec, DECIMAL_MAX_PRECISION);
|
uint precision= min(est_prec, DECIMAL_MAX_PRECISION);
|
||||||
max_length= my_decimal_precision_to_length(precision, decimals,unsigned_flag);
|
max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
|
||||||
|
unsigned_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1311,8 +1345,8 @@ void Item_func_div::result_precision()
|
|||||||
else
|
else
|
||||||
unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag;
|
unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag;
|
||||||
decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
|
decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
|
||||||
max_length= my_decimal_precision_to_length(precision, decimals,
|
max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
|
||||||
unsigned_flag);
|
unsigned_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1999,8 +2033,9 @@ void Item_func_round::fix_length_and_dec()
|
|||||||
|
|
||||||
precision-= decimals_delta - length_increase;
|
precision-= decimals_delta - length_increase;
|
||||||
decimals= min(decimals_to_set, DECIMAL_MAX_SCALE);
|
decimals= min(decimals_to_set, DECIMAL_MAX_SCALE);
|
||||||
max_length= my_decimal_precision_to_length(precision, decimals,
|
max_length= my_decimal_precision_to_length_no_truncation(precision,
|
||||||
unsigned_flag);
|
decimals,
|
||||||
|
unsigned_flag);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -2243,8 +2278,9 @@ void Item_func_min_max::fix_length_and_dec()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((cmp_type == DECIMAL_RESULT) || (cmp_type == INT_RESULT))
|
else if ((cmp_type == DECIMAL_RESULT) || (cmp_type == INT_RESULT))
|
||||||
max_length= my_decimal_precision_to_length(max_int_part+decimals, decimals,
|
max_length= my_decimal_precision_to_length_no_truncation(max_int_part +
|
||||||
unsigned_flag);
|
decimals, decimals,
|
||||||
|
unsigned_flag);
|
||||||
cached_field_type= agg_field_type(args, arg_count);
|
cached_field_type= agg_field_type(args, arg_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,7 +378,8 @@ public:
|
|||||||
Item_decimal_typecast(Item *a, int len, int dec) :Item_func(a)
|
Item_decimal_typecast(Item *a, int len, int dec) :Item_func(a)
|
||||||
{
|
{
|
||||||
decimals= dec;
|
decimals= dec;
|
||||||
max_length= my_decimal_precision_to_length(len, dec, unsigned_flag);
|
max_length= my_decimal_precision_to_length_no_truncation(len, dec,
|
||||||
|
unsigned_flag);
|
||||||
}
|
}
|
||||||
String *val_str(String *str);
|
String *val_str(String *str);
|
||||||
double val_real();
|
double val_real();
|
||||||
|
@ -798,8 +798,9 @@ void Item_sum_sum::fix_length_and_dec()
|
|||||||
{
|
{
|
||||||
/* SUM result can't be longer than length(arg) + length(MAX_ROWS) */
|
/* SUM result can't be longer than length(arg) + length(MAX_ROWS) */
|
||||||
int precision= args[0]->decimal_precision() + DECIMAL_LONGLONG_DIGITS;
|
int precision= args[0]->decimal_precision() + DECIMAL_LONGLONG_DIGITS;
|
||||||
max_length= my_decimal_precision_to_length(precision, decimals,
|
max_length= my_decimal_precision_to_length_no_truncation(precision,
|
||||||
unsigned_flag);
|
decimals,
|
||||||
|
unsigned_flag);
|
||||||
curr_dec_buff= 0;
|
curr_dec_buff= 0;
|
||||||
hybrid_type= DECIMAL_RESULT;
|
hybrid_type= DECIMAL_RESULT;
|
||||||
my_decimal_set_zero(dec_buffs);
|
my_decimal_set_zero(dec_buffs);
|
||||||
@ -1233,8 +1234,9 @@ void Item_sum_avg::fix_length_and_dec()
|
|||||||
{
|
{
|
||||||
int precision= args[0]->decimal_precision() + prec_increment;
|
int precision= args[0]->decimal_precision() + prec_increment;
|
||||||
decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
|
decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
|
||||||
max_length= my_decimal_precision_to_length(precision, decimals,
|
max_length= my_decimal_precision_to_length_no_truncation(precision,
|
||||||
unsigned_flag);
|
decimals,
|
||||||
|
unsigned_flag);
|
||||||
f_precision= min(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
|
f_precision= min(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
|
||||||
f_scale= args[0]->decimals;
|
f_scale= args[0]->decimals;
|
||||||
dec_bin_size= my_decimal_get_binary_size(f_precision, f_scale);
|
dec_bin_size= my_decimal_get_binary_size(f_precision, f_scale);
|
||||||
@ -1439,8 +1441,9 @@ void Item_sum_variance::fix_length_and_dec()
|
|||||||
{
|
{
|
||||||
int precision= args[0]->decimal_precision()*2 + prec_increment;
|
int precision= args[0]->decimal_precision()*2 + prec_increment;
|
||||||
decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
|
decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
|
||||||
max_length= my_decimal_precision_to_length(precision, decimals,
|
max_length= my_decimal_precision_to_length_no_truncation(precision,
|
||||||
unsigned_flag);
|
decimals,
|
||||||
|
unsigned_flag);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -183,6 +183,19 @@ inline uint my_decimal_length_to_precision(uint length, uint scale,
|
|||||||
(unsigned_flag || !length ? 0:1));
|
(unsigned_flag || !length ? 0:1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline uint32 my_decimal_precision_to_length_no_truncation(uint precision,
|
||||||
|
uint8 scale,
|
||||||
|
bool unsigned_flag)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
When precision is 0 it means that original length was also 0. Thus
|
||||||
|
unsigned_flag is ignored in this case.
|
||||||
|
*/
|
||||||
|
DBUG_ASSERT(precision || !scale);
|
||||||
|
return (uint32)(precision + (scale > 0 ? 1 : 0) +
|
||||||
|
(unsigned_flag || !precision ? 0 : 1));
|
||||||
|
}
|
||||||
|
|
||||||
inline uint32 my_decimal_precision_to_length(uint precision, uint8 scale,
|
inline uint32 my_decimal_precision_to_length(uint precision, uint8 scale,
|
||||||
bool unsigned_flag)
|
bool unsigned_flag)
|
||||||
{
|
{
|
||||||
@ -192,8 +205,8 @@ inline uint32 my_decimal_precision_to_length(uint precision, uint8 scale,
|
|||||||
*/
|
*/
|
||||||
DBUG_ASSERT(precision || !scale);
|
DBUG_ASSERT(precision || !scale);
|
||||||
set_if_smaller(precision, DECIMAL_MAX_PRECISION);
|
set_if_smaller(precision, DECIMAL_MAX_PRECISION);
|
||||||
return (uint32)(precision + (scale>0 ? 1:0) +
|
return my_decimal_precision_to_length_no_truncation(precision, scale,
|
||||||
(unsigned_flag || !precision ? 0:1));
|
unsigned_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
|
@ -9392,13 +9392,17 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
|
|||||||
+1: for decimal point
|
+1: for decimal point
|
||||||
*/
|
*/
|
||||||
|
|
||||||
overflow= my_decimal_precision_to_length(intg + dec, dec,
|
const int required_length=
|
||||||
item->unsigned_flag) - len;
|
my_decimal_precision_to_length(intg + dec, dec,
|
||||||
|
item->unsigned_flag);
|
||||||
|
|
||||||
|
overflow= required_length - len;
|
||||||
|
|
||||||
if (overflow > 0)
|
if (overflow > 0)
|
||||||
dec= max(0, dec - overflow); // too long, discard fract
|
dec= max(0, dec - overflow); // too long, discard fract
|
||||||
else
|
else
|
||||||
len -= item->decimals - dec; // corrected value fits
|
/* Corrected value fits. */
|
||||||
|
len= required_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
new_field= new Field_new_decimal(len, maybe_null, item->name,
|
new_field= new Field_new_decimal(len, maybe_null, item->name,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user