mirror of
https://github.com/MariaDB/server.git
synced 2025-01-28 01:34:17 +01:00
MDEV-25317 Assertion scale <= precision' failed in decimal_bin_size And Assertion
scale >= 0 && precision > 0 && scale <= precision' failed in decimal_bin_size_inline/decimal_bin_size.
Precision should be kept below DECIMAL_MAX_SCALE for computations. It can be bigger in Item_decimal. I'd fix this too but it changes the existing behaviour so problemmatic to ix.
This commit is contained in:
parent
945245aea4
commit
eca207c462
9 changed files with 79 additions and 17 deletions
|
@ -989,6 +989,12 @@ ADDTIME('916:40:00', '416:40:00')
|
|||
Warnings:
|
||||
Warning 1292 Truncated incorrect time value: '916:40:00'
|
||||
Warning 1292 Truncated incorrect time value: '1255:39:59.999999'
|
||||
SELECT ADDTIME(20010101,1e0), ADDTIME(20010101,1.1e0);
|
||||
ADDTIME(20010101,1e0) ADDTIME(20010101,1.1e0)
|
||||
2001-01-01 00:00:01 2001-01-01 00:00:01.100000
|
||||
SELECT ADDTIME(ADDTIME(20010101,1e0), 0);
|
||||
ADDTIME(ADDTIME(20010101,1e0), 0)
|
||||
2001-01-01 00:00:01
|
||||
SELECT SUBTIME('916:40:00', '416:40:00');
|
||||
SUBTIME('916:40:00', '416:40:00')
|
||||
422:19:59.999999
|
||||
|
|
|
@ -2456,5 +2456,29 @@ t1 CREATE TABLE `t1` (
|
|||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
#
|
||||
# MDEV-25317 Assertion `scale <= precision' failed in
|
||||
# decimal_bin_size And Assertion `scale >= 0 && precision > 0 && scale <= precision'
|
||||
# failed in decimal_bin_size_inline/decimal_bin_size.
|
||||
#
|
||||
SELECT AVG(DISTINCT 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001);
|
||||
AVG(DISTINCT 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
0.00000000000000000000000000000000000000
|
||||
CREATE TABLE t1 AS SELECT NULL AS v1;
|
||||
SELECT 1 FROM t1 GROUP BY v1 ORDER BY AVG ( from_unixtime ( '' ) ) ;
|
||||
1
|
||||
1
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect DECIMAL value: ''
|
||||
DROP TABLE t1;
|
||||
SELECT SUM(DISTINCT 0.000000000000000000000000000000000000001);
|
||||
SUM(DISTINCT 0.000000000000000000000000000000000000001)
|
||||
0.00000000000000000000000000000000000000
|
||||
CREATE TABLE t1 AS SELECT 1.000000000000000000000000000000000 AS a;
|
||||
ALTER TABLE t1 ADD COLUMN b INT;
|
||||
SELECT ROUND (a,b) AS c FROM t1 ORDER BY c;
|
||||
c
|
||||
NULL
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# End of 10.2 tests
|
||||
#
|
||||
|
|
|
@ -513,6 +513,10 @@ SELECT TIME_TO_SEC('916:40:00');
|
|||
SELECT ADDTIME('500:00:00', '416:40:00');
|
||||
SELECT ADDTIME('916:40:00', '416:40:00');
|
||||
|
||||
# check if ADDTIME() handles NOT_FIXED_DEC correctly
|
||||
SELECT ADDTIME(20010101,1e0), ADDTIME(20010101,1.1e0);
|
||||
SELECT ADDTIME(ADDTIME(20010101,1e0), 0);
|
||||
|
||||
# check if SUBTIME() handles out-of-range values correctly
|
||||
SELECT SUBTIME('916:40:00', '416:40:00');
|
||||
SELECT SUBTIME('-916:40:00', '416:40:00');
|
||||
|
|
|
@ -1894,6 +1894,25 @@ show create table t1;
|
|||
|
||||
drop table t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-25317 Assertion `scale <= precision' failed in
|
||||
--echo # decimal_bin_size And Assertion `scale >= 0 && precision > 0 && scale <= precision'
|
||||
--echo # failed in decimal_bin_size_inline/decimal_bin_size.
|
||||
--echo #
|
||||
|
||||
SELECT AVG(DISTINCT 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001);
|
||||
|
||||
CREATE TABLE t1 AS SELECT NULL AS v1;
|
||||
SELECT 1 FROM t1 GROUP BY v1 ORDER BY AVG ( from_unixtime ( '' ) ) ;
|
||||
DROP TABLE t1;
|
||||
|
||||
SELECT SUM(DISTINCT 0.000000000000000000000000000000000000001);
|
||||
|
||||
CREATE TABLE t1 AS SELECT 1.000000000000000000000000000000000 AS a;
|
||||
ALTER TABLE t1 ADD COLUMN b INT;
|
||||
SELECT ROUND (a,b) AS c FROM t1 ORDER BY c;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # End of 10.2 tests
|
||||
--echo #
|
||||
|
|
28
sql/field.cc
28
sql/field.cc
|
@ -3103,6 +3103,15 @@ Field *Field_decimal::make_new_field(MEM_ROOT *root, TABLE *new_table,
|
|||
}
|
||||
|
||||
|
||||
void Field_new_decimal::set_and_validate_prec(uint32 len_arg,
|
||||
uint8 dec_arg, bool unsigned_arg)
|
||||
{
|
||||
precision= my_decimal_length_to_precision(len_arg, dec_arg, unsigned_arg);
|
||||
set_if_smaller(precision, DECIMAL_MAX_PRECISION);
|
||||
bin_size= my_decimal_get_binary_size(precision, dec);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
** Field_new_decimal
|
||||
****************************************************************************/
|
||||
|
@ -3115,13 +3124,10 @@ Field_new_decimal::Field_new_decimal(uchar *ptr_arg,
|
|||
uint8 dec_arg,bool zero_arg,
|
||||
bool unsigned_arg)
|
||||
:Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
|
||||
unireg_check_arg, field_name_arg, dec_arg, zero_arg, unsigned_arg)
|
||||
unireg_check_arg, field_name_arg,
|
||||
MY_MIN(dec_arg, DECIMAL_MAX_SCALE), zero_arg, unsigned_arg)
|
||||
{
|
||||
precision= my_decimal_length_to_precision(len_arg, dec_arg, unsigned_arg);
|
||||
set_if_smaller(precision, DECIMAL_MAX_PRECISION);
|
||||
DBUG_ASSERT((precision <= DECIMAL_MAX_PRECISION) &&
|
||||
(dec <= DECIMAL_MAX_SCALE));
|
||||
bin_size= my_decimal_get_binary_size(precision, dec);
|
||||
set_and_validate_prec(len_arg, dec_arg, unsigned_arg);
|
||||
}
|
||||
|
||||
|
||||
|
@ -3132,13 +3138,11 @@ Field_new_decimal::Field_new_decimal(uint32 len_arg,
|
|||
bool unsigned_arg)
|
||||
:Field_num((uchar*) 0, len_arg,
|
||||
maybe_null_arg ? (uchar*) "": 0, 0,
|
||||
NONE, name, dec_arg, 0, unsigned_arg)
|
||||
NONE, name,
|
||||
MY_MIN(dec_arg, DECIMAL_MAX_SCALE), 0, unsigned_arg)
|
||||
{
|
||||
precision= my_decimal_length_to_precision(len_arg, dec_arg, unsigned_arg);
|
||||
set_if_smaller(precision, DECIMAL_MAX_PRECISION);
|
||||
DBUG_ASSERT((precision <= DECIMAL_MAX_PRECISION) &&
|
||||
(dec <= DECIMAL_MAX_SCALE));
|
||||
bin_size= my_decimal_get_binary_size(precision, dec);
|
||||
DBUG_ASSERT(dec <= DECIMAL_MAX_SCALE);
|
||||
set_and_validate_prec(len_arg, dec_arg, unsigned_arg);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1913,6 +1913,8 @@ public:
|
|||
class Field_new_decimal :public Field_num {
|
||||
private:
|
||||
int do_save_field_metadata(uchar *first_byte);
|
||||
void set_and_validate_prec(uint32 len_arg,
|
||||
uint8 dec_arg, bool unsigned_arg);
|
||||
public:
|
||||
/* The maximum number of decimal digits can be stored */
|
||||
uint precision;
|
||||
|
|
|
@ -2453,14 +2453,16 @@ bool Item_func_round::fix_length_and_dec()
|
|||
if (!args[1]->const_item())
|
||||
{
|
||||
decimals= args[0]->decimals;
|
||||
max_length= float_length(decimals);
|
||||
if (args[0]->result_type() == DECIMAL_RESULT)
|
||||
{
|
||||
max_length++;
|
||||
max_length= args[0]->max_length;
|
||||
set_handler_by_result_type(DECIMAL_RESULT);
|
||||
}
|
||||
else
|
||||
{
|
||||
max_length= float_length(decimals);
|
||||
set_handler_by_result_type(REAL_RESULT);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -1346,6 +1346,8 @@ bool Item_sum_sum::fix_length_and_dec()
|
|||
{
|
||||
/* SUM result can't be longer than length(arg) + length(MAX_ROWS) */
|
||||
int precision= args[0]->decimal_precision() + DECIMAL_LONGLONG_DIGITS;
|
||||
decimals= MY_MIN(decimals, DECIMAL_MAX_SCALE);
|
||||
precision= MY_MIN(precision, DECIMAL_MAX_PRECISION);
|
||||
max_length= my_decimal_precision_to_length_no_truncation(precision,
|
||||
decimals,
|
||||
unsigned_flag);
|
||||
|
@ -1673,12 +1675,12 @@ bool Item_sum_avg::fix_length_and_dec()
|
|||
if (Item_sum_avg::result_type() == DECIMAL_RESULT)
|
||||
{
|
||||
int precision= args[0]->decimal_precision() + prec_increment;
|
||||
decimals= MY_MIN(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
|
||||
decimals= MY_MIN(args[0]->decimal_scale() + prec_increment, DECIMAL_MAX_SCALE);
|
||||
max_length= my_decimal_precision_to_length_no_truncation(precision,
|
||||
decimals,
|
||||
unsigned_flag);
|
||||
f_precision= MY_MIN(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
|
||||
f_scale= args[0]->decimals;
|
||||
f_scale= args[0]->decimal_scale();
|
||||
dec_bin_size= my_decimal_get_binary_size(f_precision, f_scale);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -258,7 +258,6 @@ Type_handler_decimal_result::make_num_distinct_aggregator_field(
|
|||
const Item *item)
|
||||
const
|
||||
{
|
||||
DBUG_ASSERT(item->decimals <= DECIMAL_MAX_SCALE);
|
||||
return new (mem_root)
|
||||
Field_new_decimal(NULL, item->max_length,
|
||||
(uchar *) (item->maybe_null ? "" : 0),
|
||||
|
|
Loading…
Add table
Reference in a new issue