mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03: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:
@@ -989,6 +989,12 @@ ADDTIME('916:40:00', '416:40:00')
|
|||||||
Warnings:
|
Warnings:
|
||||||
Warning 1292 Truncated incorrect time value: '916:40:00'
|
Warning 1292 Truncated incorrect time value: '916:40:00'
|
||||||
Warning 1292 Truncated incorrect time value: '1255:39:59.999999'
|
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');
|
SELECT SUBTIME('916:40:00', '416:40:00');
|
||||||
SUBTIME('916:40:00', '416:40:00')
|
SUBTIME('916:40:00', '416:40:00')
|
||||||
422:19:59.999999
|
422:19:59.999999
|
||||||
|
@@ -2456,5 +2456,29 @@ t1 CREATE TABLE `t1` (
|
|||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
drop table t1;
|
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
|
# 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('500:00:00', '416:40:00');
|
||||||
SELECT ADDTIME('916:40: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
|
# 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');
|
||||||
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;
|
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 #
|
||||||
--echo # End of 10.2 tests
|
--echo # End of 10.2 tests
|
||||||
--echo #
|
--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
|
** Field_new_decimal
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -3115,13 +3124,10 @@ Field_new_decimal::Field_new_decimal(uchar *ptr_arg,
|
|||||||
uint8 dec_arg,bool zero_arg,
|
uint8 dec_arg,bool zero_arg,
|
||||||
bool unsigned_arg)
|
bool unsigned_arg)
|
||||||
:Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_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_and_validate_prec(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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3132,13 +3138,11 @@ Field_new_decimal::Field_new_decimal(uint32 len_arg,
|
|||||||
bool unsigned_arg)
|
bool unsigned_arg)
|
||||||
:Field_num((uchar*) 0, len_arg,
|
:Field_num((uchar*) 0, len_arg,
|
||||||
maybe_null_arg ? (uchar*) "": 0, 0,
|
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);
|
DBUG_ASSERT(dec <= DECIMAL_MAX_SCALE);
|
||||||
set_if_smaller(precision, DECIMAL_MAX_PRECISION);
|
set_and_validate_prec(len_arg, dec_arg, unsigned_arg);
|
||||||
DBUG_ASSERT((precision <= DECIMAL_MAX_PRECISION) &&
|
|
||||||
(dec <= DECIMAL_MAX_SCALE));
|
|
||||||
bin_size= my_decimal_get_binary_size(precision, dec);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1913,6 +1913,8 @@ public:
|
|||||||
class Field_new_decimal :public Field_num {
|
class Field_new_decimal :public Field_num {
|
||||||
private:
|
private:
|
||||||
int do_save_field_metadata(uchar *first_byte);
|
int do_save_field_metadata(uchar *first_byte);
|
||||||
|
void set_and_validate_prec(uint32 len_arg,
|
||||||
|
uint8 dec_arg, bool unsigned_arg);
|
||||||
public:
|
public:
|
||||||
/* The maximum number of decimal digits can be stored */
|
/* The maximum number of decimal digits can be stored */
|
||||||
uint precision;
|
uint precision;
|
||||||
|
@@ -2453,14 +2453,16 @@ bool Item_func_round::fix_length_and_dec()
|
|||||||
if (!args[1]->const_item())
|
if (!args[1]->const_item())
|
||||||
{
|
{
|
||||||
decimals= args[0]->decimals;
|
decimals= args[0]->decimals;
|
||||||
max_length= float_length(decimals);
|
|
||||||
if (args[0]->result_type() == DECIMAL_RESULT)
|
if (args[0]->result_type() == DECIMAL_RESULT)
|
||||||
{
|
{
|
||||||
max_length++;
|
max_length= args[0]->max_length;
|
||||||
set_handler_by_result_type(DECIMAL_RESULT);
|
set_handler_by_result_type(DECIMAL_RESULT);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
max_length= float_length(decimals);
|
||||||
set_handler_by_result_type(REAL_RESULT);
|
set_handler_by_result_type(REAL_RESULT);
|
||||||
|
}
|
||||||
return FALSE;
|
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) */
|
/* 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;
|
||||||
|
decimals= MY_MIN(decimals, DECIMAL_MAX_SCALE);
|
||||||
|
precision= MY_MIN(precision, DECIMAL_MAX_PRECISION);
|
||||||
max_length= my_decimal_precision_to_length_no_truncation(precision,
|
max_length= my_decimal_precision_to_length_no_truncation(precision,
|
||||||
decimals,
|
decimals,
|
||||||
unsigned_flag);
|
unsigned_flag);
|
||||||
@@ -1673,12 +1675,12 @@ bool Item_sum_avg::fix_length_and_dec()
|
|||||||
if (Item_sum_avg::result_type() == DECIMAL_RESULT)
|
if (Item_sum_avg::result_type() == DECIMAL_RESULT)
|
||||||
{
|
{
|
||||||
int precision= args[0]->decimal_precision() + prec_increment;
|
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,
|
max_length= my_decimal_precision_to_length_no_truncation(precision,
|
||||||
decimals,
|
decimals,
|
||||||
unsigned_flag);
|
unsigned_flag);
|
||||||
f_precision= MY_MIN(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
|
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);
|
dec_bin_size= my_decimal_get_binary_size(f_precision, f_scale);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@@ -258,7 +258,6 @@ Type_handler_decimal_result::make_num_distinct_aggregator_field(
|
|||||||
const Item *item)
|
const Item *item)
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(item->decimals <= DECIMAL_MAX_SCALE);
|
|
||||||
return new (mem_root)
|
return new (mem_root)
|
||||||
Field_new_decimal(NULL, item->max_length,
|
Field_new_decimal(NULL, item->max_length,
|
||||||
(uchar *) (item->maybe_null ? "" : 0),
|
(uchar *) (item->maybe_null ? "" : 0),
|
||||||
|
Reference in New Issue
Block a user