Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-41475

Partitioning by TO_SECONDS(), TO_DAYS() or UNIX_TIMESTAMP() changes the query result: a row with fractional seconds is not found

    XMLWordPrintable

Details

    Description

      --source include/have_partition.inc
       
      CREATE TABLE t1 (d DATETIME(6)) PARTITION BY RANGE (TO_SECONDS(d)) (PARTITION p0 VALUES LESS THAN (TO_SECONDS('2020-01-01 00:00:10')), PARTITION p1 VALUES LESS THAN (TO_SECONDS('2020-01-01 00:00:11')), PARTITION p2 VALUES LESS THAN MAXVALUE);
      INSERT INTO t1 VALUES ('2020-01-01 00:00:10.5');
      --let $c= query_get_value(SELECT COUNT(*) AS c FROM t1 WHERE d > '2020-01-01 00:00:10.4', c, 1)
      if ($c != 1)
      {
        --die The row 2020-01-01 00:00:10.5 is not found by d > '2020-01-01 00:00:10.4' on a table partitioned by TO_SECONDS(d)
      }
       
      CREATE TABLE t2 (d DATETIME(6)) PARTITION BY RANGE (TO_DAYS(d)) (PARTITION p0 VALUES LESS THAN (TO_DAYS('2020-01-01')), PARTITION p1 VALUES LESS THAN (TO_DAYS('2020-01-02')), PARTITION p2 VALUES LESS THAN MAXVALUE);
      INSERT INTO t2 VALUES ('2020-01-01 23:59:59.5');
      --let $c= query_get_value(SELECT COUNT(*) AS c FROM t2 WHERE d > '2020-01-01 23:59:59', c, 1)
      if ($c != 1)
      {
        --die The row 2020-01-01 23:59:59.5 is not found by d > '2020-01-01 23:59:59' on a table partitioned by TO_DAYS(d)
      }
       
      CREATE TABLE t3 (ts TIMESTAMP(6)) PARTITION BY RANGE (UNIX_TIMESTAMP(ts)) (PARTITION p0 VALUES LESS THAN (UNIX_TIMESTAMP('2020-01-01 00:00:10')), PARTITION p1 VALUES LESS THAN (UNIX_TIMESTAMP('2020-01-01 00:00:11')), PARTITION p2 VALUES LESS THAN MAXVALUE);
      INSERT INTO t3 VALUES ('2020-01-01 00:00:10.5');
      --let $c= query_get_value(SELECT COUNT(*) AS c FROM t3 WHERE ts > '2020-01-01 00:00:10.4', c, 1)
      if ($c != 1)
      {
        --die The row 2020-01-01 00:00:10.5 is not found by ts > '2020-01-01 00:00:10.4' on a table partitioned by UNIX_TIMESTAMP(ts)
      }
      DROP TABLE t1, t2, t3;

      Leads to:

      CS 13.1.0 da18481158c81ca94689702073c3e04aad85a6a3 (Debug, Clang 22.1.8-20260622) Build 18/08/2026

      mysqltest: At line 8: The row 2020-01-01 00:00:10.5 is not found by d > '2020-01-01 00:00:10.4' on a table partitioned by TO_SECONDS(d)

      Partitioning changes the query result. Without partitioning, each of the three queries finds the row. The TO_DAYS() and UNIX_TIMESTAMP() parts fail in the same way when run on their own. Optimized builds give the same result.

      From the code it seems that the pruning endpoints in sql/item_timefunc.cc do not allow for fractional seconds:

      • Item_func_to_seconds::val_int_endpoint() drops the fraction of '2020-01-01 00:00:10.4' and keeps > strict, so p1 is not read.
      • Item_func_to_days::val_int_endpoint() keeps d > '2020-01-01 23:59:59' strict as TO_DAYS(d) > TO_DAYS('2020-01-01'), but a DATETIME(6) value can lie between 23:59:59 and midnight.
      • Item_func_unix_timestamp::val_int_endpoint() drops the fraction in the same way as TO_SECONDS().

      Attachments

        Issue Links

          Activity

            People

              ycp Yuchen Pei
              Roel Roel Van de Paar
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:

                Time Tracking

                  Estimated:
                  Original Estimate - Not Specified
                  Not Specified
                  Remaining:
                  Remaining Estimate - Not Specified
                  Not Specified
                  Logged:
                  Time Spent - 1.5h
                  1.5h

                  Git Integration

                    Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.