MDEV-35250 Assertion `dec <= 6' failed in my_timestamp_binary_length

The TIMESTAMP related code did not handle AUTO_SEC_PART_DIGITS.
FROM_UNIXTIME() sets its member 'decimals' to AUTO_SEC_PART_DIGITS.
So some scripts involving FROM_UNIXTIME() crashed on assert in debug
builds and returned unexpected results in release builds.
This commit is contained in:
Alexander Barkov 2024-10-27 14:07:59 +04:00
parent a79f314f1b
commit 8c0a260a5b
4 changed files with 108 additions and 5 deletions

View file

@ -2336,3 +2336,64 @@ DROP TABLE t1;
#
# End of 11.3 tests
#
#
# Start of 11.7 tests
#
#
# MDEV-35250 Assertion `dec <= 6' failed in my_timestamp_binary_length
#
SET time_zone='+00:00';
SELECT FROM_UNIXTIME('1922-02-10'), BIT_AND(1);
FROM_UNIXTIME('1922-02-10') BIT_AND(1)
1970-01-01 00:32:02 1
Warnings:
Warning 1292 Truncated incorrect DECIMAL value: '1922-02-10'
SELECT FROM_UNIXTIME('1922'), BIT_AND(1);
FROM_UNIXTIME('1922') BIT_AND(1)
1970-01-01 00:32:02 1
SELECT FROM_UNIXTIME('1922.1'), BIT_AND(1);
FROM_UNIXTIME('1922.1') BIT_AND(1)
1970-01-01 00:32:02.100000 1
SELECT FROM_UNIXTIME('1922.1');
FROM_UNIXTIME('1922.1')
1970-01-01 00:32:02.100000
SELECT * FROM (SELECT FROM_UNIXTIME('1'), BIT_AND(1)) t;
FROM_UNIXTIME('1') BIT_AND(1)
1970-01-01 00:00:01.000000 1
SELECT * FROM (SELECT FROM_UNIXTIME('1.1'), BIT_AND(1)) t;
FROM_UNIXTIME('1.1') BIT_AND(1)
1970-01-01 00:00:01.100000 1
CREATE TABLE t1 (a TEXT, b TEXT);
INSERT INTO t1 SELECT FROM_UNIXTIME('1'), BIT_AND(1);
INSERT INTO t1 SELECT FROM_UNIXTIME('1.1'), BIT_AND(1);
SELECT * FROM t1;
a b
1970-01-01 00:00:01 1
1970-01-01 00:00:01.100000 1
DROP TABLE t1;
SELECT 1 FROM (values(1),(2)) dt GROUP BY from_unixtime('a') WITH ROLLUP;
1
1
1
Warnings:
Warning 1292 Truncated incorrect DECIMAL value: 'a'
Warning 1292 Truncated incorrect unixtime value: '0.0'
Warning 1292 Truncated incorrect DECIMAL value: 'a'
Warning 1292 Truncated incorrect unixtime value: '0.0'
Warning 1292 Truncated incorrect DECIMAL value: 'a'
Warning 1292 Truncated incorrect unixtime value: '0.0'
Warning 1292 Truncated incorrect DECIMAL value: 'a'
Warning 1292 Truncated incorrect unixtime value: '0.0'
Warning 1292 Truncated incorrect DECIMAL value: 'a'
Warning 1292 Truncated incorrect unixtime value: '0.0'
CREATE TABLE t1 (a TEXT);
INSERT INTO t1 VALUES (1),(2);
SELECT * FROM t1 ORDER BY from_unixtime(a);
a
1
2
DROP TABLE t1;
SET time_zone=DEFAULT;
#
# End of 11.7 tests
#

View file

@ -1368,3 +1368,40 @@ DROP TABLE t1;
--echo #
--echo # End of 11.3 tests
--echo #
--echo #
--echo # Start of 11.7 tests
--echo #
--echo #
--echo # MDEV-35250 Assertion `dec <= 6' failed in my_timestamp_binary_length
--echo #
SET time_zone='+00:00';
SELECT FROM_UNIXTIME('1922-02-10'), BIT_AND(1);
SELECT FROM_UNIXTIME('1922'), BIT_AND(1);
# Disable PS protocol to workaround CONC-739
--disable_ps_protocol
SELECT FROM_UNIXTIME('1922.1'), BIT_AND(1);
SELECT FROM_UNIXTIME('1922.1');
--enable_ps_protocol
SELECT * FROM (SELECT FROM_UNIXTIME('1'), BIT_AND(1)) t;
SELECT * FROM (SELECT FROM_UNIXTIME('1.1'), BIT_AND(1)) t;
CREATE TABLE t1 (a TEXT, b TEXT);
INSERT INTO t1 SELECT FROM_UNIXTIME('1'), BIT_AND(1);
INSERT INTO t1 SELECT FROM_UNIXTIME('1.1'), BIT_AND(1);
SELECT * FROM t1;
DROP TABLE t1;
SELECT 1 FROM (values(1),(2)) dt GROUP BY from_unixtime('a') WITH ROLLUP;
CREATE TABLE t1 (a TEXT);
INSERT INTO t1 VALUES (1),(2);
SELECT * FROM t1 ORDER BY from_unixtime(a);
DROP TABLE t1;
SET time_zone=DEFAULT;
--echo #
--echo # End of 11.7 tests
--echo #

View file

@ -1282,7 +1282,8 @@ Type_handler_timestamp_common::make_sort_key_part(uchar *to, Item *item,
String *tmp_buffer) const
{
THD *thd= current_thd;
uint binlen= my_timestamp_binary_length(item->decimals);
decimal_digits_t dec= MY_MIN(item->decimals, TIME_SECOND_PART_DIGITS);
uint binlen= my_timestamp_binary_length(dec);
Timestamp_or_zero_datetime_native_null native(thd, item);
if (native.is_null() || native.is_zero_datetime())
{
@ -2083,7 +2084,8 @@ Type_handler_timestamp_common::sort_length(THD *thd,
const Type_std_attributes *item,
SORT_FIELD_ATTR *sortorder) const
{
sortorder->length= my_timestamp_binary_length(item->decimals);
decimal_digits_t dec= MY_MIN(item->decimals, TIME_SECOND_PART_DIGITS);
sortorder->length= my_timestamp_binary_length(dec);
sortorder->original_length= sortorder->length;
}
@ -2619,7 +2621,8 @@ Type_handler_timestamp_common::make_packed_sort_key_part(uchar *to, Item *item,
String *tmp) const
{
THD *thd= current_thd;
uint binlen= my_timestamp_binary_length(item->decimals);
decimal_digits_t dec= MY_MIN(item->decimals, TIME_SECOND_PART_DIGITS);
uint binlen= my_timestamp_binary_length(dec);
Timestamp_or_zero_datetime_native_null native(thd, item);
if (native.is_null() || native.is_zero_datetime())
{

View file

@ -6789,7 +6789,8 @@ public:
DBUG_ASSERT(sane());
if (null_value)
return set_field_to_null(field);
Timestamp_or_zero_datetime_native native(m_value, decimals);
decimal_digits_t dec= MY_MIN(decimals, TIME_SECOND_PART_DIGITS);
Timestamp_or_zero_datetime_native native(m_value, dec);
return native.save_in_field(field, decimals);
}
longlong val_int() override
@ -6826,7 +6827,8 @@ public:
bool val_native(THD *thd, Native *to) override
{
DBUG_ASSERT(sane());
return null_value || m_value.to_native(to, decimals);
decimal_digits_t dec= MY_MIN(decimals, TIME_SECOND_PART_DIGITS);
return null_value || m_value.to_native(to, dec);
}
Item *do_get_copy(THD *thd) const override
{ return get_item_copy<Item_copy_timestamp>(thd, this); }