[MDEV-19961] MIN(timestamp_column) returns a wrong result in a GROUP BY query Created: 2019-07-05  Updated: 2020-06-08  Resolved: 2019-08-19

Status: Closed
Project: MariaDB Server
Component/s: Data types, Temporal Types
Affects Version/s: 10.0, 10.1, 10.2, 10.3, 10.4, 10.5
Fix Version/s: 10.4.8

Type: Bug Priority: Major
Reporter: Alexander Barkov Assignee: Alexander Barkov
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Blocks
is blocked by MDEV-17857 Assertion `tmp != ((long long) 0x8000... Closed
Relates
relates to MDEV-13995 MAX(timestamp) returns a wrong result... Closed
relates to MDEV-22828 Bad results near DST change: UNIX_TIM... Open

 Description   

I run this script using two timestamp values near DST change:

SET time_zone='Europe/Moscow';
CREATE OR REPLACE TABLE t1 (i INT, d TIMESTAMP);
SET timestamp=1288477526  /* this is summer time */ ;
INSERT INTO t1 VALUES (3,NULL);
SET timestamp=1288477526+3599 /* this is winter time*/ ;
INSERT INTO t1 VALUES (3,NULL);
SELECT i, d, UNIX_TIMESTAMP(d) FROM t1 ORDER BY d;

+------+---------------------+-------------------+
| i    | d                   | UNIX_TIMESTAMP(d) |
+------+---------------------+-------------------+
|    3 | 2010-10-31 02:25:26 |        1288477526 |
|    3 | 2010-10-31 02:25:25 |        1288481125 |
+------+---------------------+-------------------+

The record with Unix timestamp value of 1288477526 returned first, because it is smaller.

Now I run a GROUP BY query with MIN:

SELECT i, MIN(d) FROM t1 GROUP BY i;

+------+---------------------+
| i    | MIN(d)              |
+------+---------------------+
|    3 | 2010-10-31 02:25:25 |
+------+---------------------+

It erroneously chose a wrong record.
This happens because TIMESTAMP in this piece of code is handled in striing format (which uses DATETIME rather than TIMESTAMP representation):

void Item_sum_hybrid::update_field()
{
  DBUG_ENTER("Item_sum_hybrid::update_field");
  Item *UNINIT_VAR(tmp_item);
  if (unlikely(direct_added))
  {
    tmp_item= args[0];
    args[0]= direct_item;
  }
  switch (result_type()) {
  case STRING_RESULT:
    min_max_update_str_field();
    break;
  case INT_RESULT:
    min_max_update_int_field();
    break;
  case DECIMAL_RESULT:
    min_max_update_decimal_field();
    break;
  default:
    min_max_update_real_field();
  }
  if (unlikely(direct_added))
  {
    direct_added= FALSE;
    args[0]= tmp_item;
  }
  DBUG_VOID_RETURN;
}


Generated at Thu Feb 08 08:55:40 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.