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

The result of TIME('42949672965959-01') depends on architecture

    Details

      Description

      The code in str_to_time() in sql-common/my_time.c is not portable.
      It can return different results on different architectures.

      Platforms with sizeof(ulong)==4 (e.g. Linux 32bit, Windows)

      SELECT TIME('42949672955959-01'), TIME('42949672965959-01');
      

      +---------------------------+---------------------------+
      | TIME('42949672955959-01') | TIME('42949672965959-01') |
      +---------------------------+---------------------------+
      | 838:59:59                 | 00:59:59                  |
      +---------------------------+---------------------------+
      1 row in set, 2 warnings (0.001 sec)
      

      The result for the second column is wrong.

      Platforms with sizeof(ulong)==8 (e.g. Linux 64bit)

      SELECT TIME('42949672955959-01'), TIME('42949672965959-01');
      

      +---------------------------+---------------------------+
      | TIME('42949672955959-01') | TIME('42949672965959-01') |
      +---------------------------+---------------------------+
      | 838:59:59                 | NULL                      |
      +---------------------------+---------------------------+
      1 row in set, 2 warnings (0.00 sec)
      

      The result for the second column is correct.

      The underlying code description

        else
        {
          /* String given as one number; assume HHMMSS format */
          date[0]= 0;
          date[1]= (ulong) (value/10000);     //This line is not portable
          date[2]= (ulong) (value/100 % 100);
          date[3]= (ulong) (value % 100);
          state=4;
          goto fractional;
        }
      

      The difference happens in the line assigning date[1]. For TIME('42949672965959-01'), "value" is 4294967296595.

      Assigning (4294967296595/10000) to data[1]:

      • makes 4294967296 on platforms with sizeof(ulong)=8
      • overflows to 0 on platforms with sizeof(ulong)=4

      On 64bit platforms a similar problem is repeatable with TIME('18446744073709551616-01')

      SELECT TIME('18446744073709551615-01'),  TIME('18446744073709551616-01');
      

      +---------------------------------+---------------------------------+
      | TIME('18446744073709551615-01') | TIME('18446744073709551616-01') |
      +---------------------------------+---------------------------------+
      | NULL                            | 00:00:00                        |
      +---------------------------------+---------------------------------+
      

      Notice, the value for the second column is wrong. The expected value is NULL.

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                bar Alexander Barkov
                Reporter:
                bar Alexander Barkov
              • Votes:
                0 Vote for this issue
                Watchers:
                1 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: