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

Columnstore query returns incorrect value instead of expected out-of-range error

Details

    • 2023-11

    Description

      create schema coltest; use coltest;
      drop table if exists test_mult;
      create table test_mult (
      indemnity_paid int(11),
      n_clms tinyint(3) unsigned
      ) engine=columnstore;
      insert into test_mult (indemnity_paid, n_clms) values (-10, 1);
      select indemnity_paid, n_clms, indemnity_paid * n_clms from test_mult;
      +----------------+--------+-------------------------+
      | indemnity_paid | n_clms | indemnity_paid * n_clms |
      +----------------+--------+-------------------------+
      |            -10 |      1 |    18446744073709551606 |
      +----------------+--------+-------------------------+
      

      The multiplication produces an incorrect value.
      For the same table defined engine=innodb, the multiplication produces an expected out-of-range error:

      alter table test_mult engine=innodb;
      select indemnity_paid, n_clms, indemnity_paid * n_clms from test_mult;
      ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '`coltest`.`test_mult`.`indemnity_paid` * `coltest`.`test_mult`.`n_clms`'
      

      Attachments

        Activity

          drrtuy Roman added a comment -

          MDB promotes the mult type into UNSIGNED BIGINT however their mult processing checks if the signed column value is negative or not. If it is there is an error that is propagated upwards. MCS math processing lacks error propagation.

          drrtuy Roman added a comment - MDB promotes the mult type into UNSIGNED BIGINT however their mult processing checks if the signed column value is negative or not. If it is there is an error that is propagated upwards. MCS math processing lacks error propagation.

          BTW query can be rewritten
          <code>
          MariaDB [coltest]> select indemnity_paid, n_clms, indemnity_paid * cast(n_clms as signed) from test_mult;
          -------------------------------------------------------------

          indemnity_paid n_clms indemnity_paid * cast(n_clms as signed)

          -------------------------------------------------------------

          -10 1 -10

          -------------------------------------------------------------
          1 row in set (0.012 sec)
          <code>

          leonid.fedorov Leonid Fedorov added a comment - BTW query can be rewritten <code> MariaDB [coltest] > select indemnity_paid, n_clms, indemnity_paid * cast(n_clms as signed) from test_mult; --------------- ------ ---------------------------------------- indemnity_paid n_clms indemnity_paid * cast(n_clms as signed) --------------- ------ ---------------------------------------- -10 1 -10 --------------- ------ ---------------------------------------- 1 row in set (0.012 sec) <code>
          drrtuy Roman added a comment -

          Here are some comments on how does type coercion happens in MDB/MySQL:

          ```
          If both operands are integers and any of them are unsigned, the result is an unsigned integer. For subtraction, if the NO_UNSIGNED_SUBTRACTION SQL mode is enabled, the result is signed even if any operand is unsigned.
          ```
          There is another important aspect of this issue. There is a JIT patch almost ready to be merged. This patch is affected by the fact MCS doesn't do overflow or value domain checks like we see in this issue when negative int64 value is bit-casted into uint64. This upcoming change must be also taken into account.
          I suggest we search for similar issues filed previously by Bar. If not we should file an umbrella ticket to copy MDB behavior doing math with numerics.

          drrtuy Roman added a comment - Here are some comments on how does type coercion happens in MDB/MySQL: ``` If both operands are integers and any of them are unsigned, the result is an unsigned integer. For subtraction, if the NO_UNSIGNED_SUBTRACTION SQL mode is enabled, the result is signed even if any operand is unsigned. ``` There is another important aspect of this issue. There is a JIT patch almost ready to be merged. This patch is affected by the fact MCS doesn't do overflow or value domain checks like we see in this issue when negative int64 value is bit-casted into uint64. This upcoming change must be also taken into account. I suggest we search for similar issues filed previously by Bar. If not we should file an umbrella ticket to copy MDB behavior doing math with numerics.
          kirill.perov@mariadb.com Kirill Perov (Inactive) added a comment - - edited

          sergey.zefirov,drrtuy

          1.
          select indemnity_paid, n_clms, indemnity_paid / n_clms from test_mult;

          ---------------------------------------------

          indemnity_paid n_clms indemnity_paid / n_clms

          ---------------------------------------------

          -10 1 -10.0000

          ---------------------------------------------
          1 row in set (0.019 sec)

          I have expected it should give error according to: "If both operands are integers and any of them are unsigned, the result is an unsigned integer." But both MCS and MDB shows -10 as result here.

          2. In non strict mode if out-of-range value is inserted and truncated, MDB shows 1 warning:
          Warning (Code 1264): Out of range value for column 'n_clms' at row 1

          and MCS shows 2 warnings
          Warning (Code 1264): Out of range value for column 'n_clms' at row 1
          Warning (Code 1264): CAL0001: MCS-2025: Data truncated for column 'n_clms'

          3. For DECIMAL UNSIGNED, FLOAT UNSIGNED and DOUBLE UNSIGNED both MDB and MCS shows -10 as result, no error.

          kirill.perov@mariadb.com Kirill Perov (Inactive) added a comment - - edited sergey.zefirov , drrtuy 1. select indemnity_paid, n_clms, indemnity_paid / n_clms from test_mult; --------------- ------ ------------------------ indemnity_paid n_clms indemnity_paid / n_clms --------------- ------ ------------------------ -10 1 -10.0000 --------------- ------ ------------------------ 1 row in set (0.019 sec) I have expected it should give error according to: "If both operands are integers and any of them are unsigned, the result is an unsigned integer." But both MCS and MDB shows -10 as result here. 2. In non strict mode if out-of-range value is inserted and truncated, MDB shows 1 warning: Warning (Code 1264): Out of range value for column 'n_clms' at row 1 and MCS shows 2 warnings Warning (Code 1264): Out of range value for column 'n_clms' at row 1 Warning (Code 1264): CAL0001: MCS-2025: Data truncated for column 'n_clms' 3. For DECIMAL UNSIGNED, FLOAT UNSIGNED and DOUBLE UNSIGNED both MDB and MCS shows -10 as result, no error.
          drrtuy Roman added a comment - - edited

          Right, integer operands division produces float.

          Could you elaborate on whether integer division actually truncates for the 2nd scenario in your prev comment kirill.perov@mariadb.com?

          drrtuy Roman added a comment - - edited Right, integer operands division produces float. Could you elaborate on whether integer division actually truncates for the 2nd scenario in your prev comment kirill.perov@mariadb.com ?

          drrtuy Second scenario was about insertion of values > 256 into tinyint unsigned column.
          For division:

          MariaDB [coltest]> select indemnity_paid, n_clms, indemnity_paid / n_clms from test_mult;
          ---------------------------------------------

          indemnity_paid n_clms indemnity_paid / n_clms

          ---------------------------------------------

          -10 1 -10.0000
          -10 253 -0.0395

          ---------------------------------------------
          2 rows in set (0.009 sec)

          No errors or warnings there.

          kirill.perov@mariadb.com Kirill Perov (Inactive) added a comment - drrtuy Second scenario was about insertion of values > 256 into tinyint unsigned column. For division: MariaDB [coltest] > select indemnity_paid, n_clms, indemnity_paid / n_clms from test_mult; --------------- ------ ------------------------ indemnity_paid n_clms indemnity_paid / n_clms --------------- ------ ------------------------ -10 1 -10.0000 -10 253 -0.0395 --------------- ------ ------------------------ 2 rows in set (0.009 sec) No errors or warnings there.

          testing finished ok

          kirill.perov@mariadb.com Kirill Perov (Inactive) added a comment - testing finished ok

          People

            sergey.zefirov Sergey Zefirov
            edward Edward Stoever
            Roman Roman
            Kirill Perov Kirill Perov (Inactive)
            Votes:
            1 Vote for this issue
            Watchers:
            8 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Git Integration

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