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

Data loss on DOUBLE and DECIMAL conversion to INT

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed (View Workflow)
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 5.5, 10.1, 10.2, 10.3, 10.4, 10.5, 10.0
    • Fix Version/s: 10.5.4
    • Component/s: Data types
    • Labels:
      None

      Description

      CREATE OR REPLACE TABLE t1 (a BIGINT UNSIGNED, b DOUBLE, c DECIMAL(30,0));
      INSERT INTO t1 VALUES(18446744073709551615,18446744073709551615,18446744073709551615);
      SELECT a, b, c, a << 0, b << 0, c << 0 FROM t1\G
      

      MariaDB [test]> SELECT a, b, c, a << 0, b << 0, c << 0 FROM t1\G
      *************************** 1. row ***************************
           a: 18446744073709551615
           b: 1.8446744073709552e19
           c: 18446744073709551615
      a << 0: 18446744073709551615
      b << 0: 9223372036854775807
      c << 0: 9223372036854775807
      

      Notice, the result for `b << 0` and `c << 0` is wrong. It should be 18446744073709551615.

      The problem happens because Field_double::val_int() and Field_new_decimal::val_int() truncate to max signed bigint value.

      It's not easy to fix this in the current code base.
      It seems we need to change this Field and Item method:

      virtual longlong val_int();
      

      to:

      virtual Longlong_hybrid to_longlong_hybrid();
      

      so the underlying Field or Item can return the entire range -9223372036854775808 .. 18446744073709551615, i.e. from the minimum possible SIGNED value to maximum possible UNSIGNED value.

        Attachments

          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: