Uploaded image for project: 'MariaDB ColumnStore'
  1. MariaDB ColumnStore
  2. MCOL-4651

SEC_TO_TIME(hugePositiveDecimal) returns a negative time

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed (View Workflow)
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 5.6.1, 6.1.1
    • Fix Version/s: 6.1.1
    • Component/s: PrimProc
    • Labels:
      None

      Description

      DROP TABLE IF EXISTS t1;
      CREATE TABLE t1 (a DECIMAL(30,1)) ENGINE=ColumnStore;
      INSERT INTO t1 VALUES (9223372036854775807.0);
      INSERT INTO t1 VALUES (9223372036854775807.5);
      INSERT INTO t1 VALUES (18446744073709551615.0);
      INSERT INTO t1 VALUES (18446744073709551615.5);
      SELECT a, SEC_TO_TIME(a) FROM t1 ORDER BY a;
      

      +------------------------+----------------+
      | a                      | SEC_TO_TIME(a) |
      +------------------------+----------------+
      |  9223372036854775807.0 | 838:59:59.0    |
      |  9223372036854775807.5 | -838:59:59.0   | -- bad
      | 18446744073709551615.0 | 838:59:59.0    |
      | 18446744073709551615.5 | -838:59:59.0   | -- bad
      +------------------------+----------------+
      

      Looks wrong. The correct result is:

      DROP TABLE IF EXISTS t1;
      CREATE TABLE t1 (a DECIMAL(30,1)) ENGINE=InnoDB;
      INSERT INTO t1 VALUES (9223372036854775807.0);
      INSERT INTO t1 VALUES (9223372036854775807.5);
      INSERT INTO t1 VALUES (18446744073709551615.0);
      INSERT INTO t1 VALUES (18446744073709551615.5);
      SELECT a, SEC_TO_TIME(a) FROM t1 ORDER BY a;
      

      +------------------------+----------------+
      | a                      | SEC_TO_TIME(a) |
      +------------------------+----------------+
      |  9223372036854775807.0 | 838:59:59.9    |
      |  9223372036854775807.5 | 838:59:59.9    |
      | 18446744073709551615.0 | 838:59:59.9    |
      | 18446744073709551615.5 | 838:59:59.9    |
      +------------------------+----------------+
      

      Note, the microsecond value is zero in MCS because of MCOL-4608.
      But at least the integer part should be fixed not to return negative values.

      The problem reside in Func_sec_to_time::getStrVal():

              case execplan::CalpontSystemCatalog::DECIMAL:
              case execplan::CalpontSystemCatalog::UDECIMAL:
              {
                  const string& valStr = parm[0]->data()->getStrVal(row, isNull);
       
                  val = parm[0]->data()->getIntVal(row, isNull);
                  size_t x = valStr.find(".");
       
                  if (x < string::npos)
                  {
                      string tmp = valStr.substr(x + 1, 1);
                      char* ptr = &tmp[0];
                      int i = atoi(ptr);
       
                      if (i >= 5)
                      {
                          if (val > 0)
                              val += 1;
                          else
                              val -= 1;
                      }
                  }
              }
              break;
      

      The above code performs rounding without checking the range properly. So a huge positive integer, e.g. 9223372036854775807 wraps around to a negative value.

        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:

                  Git Integration