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

CONCAT Function Returns Unexpected Empty Set in Query

Details

    Description

      CREATE TABLE IF NOT EXISTS t0 (
          c0_1 VARCHAR(200),
          c0_2 TEXT
      );
       
      INSERT INTO t0 VALUES ('0.67882431850', '97966');
      MariaDB [test]> select * from t0;
      +---------------+-------+
      | c0_1          | c0_2  |
      +---------------+-------+
      | 0.67882431850 | 97966 |
      +---------------+-------+
      1 row in set (0.002 sec)
      

      Execute the query:

      SELECT (CONCAT(t0.c0_1, t0.c0_2)) AS ref0 FROM t0 WHERE (CONCAT(t0.c0_1, t0.c0_2));
      

      Expected Result:
      The query should return a single row with the value 0.6788243185097966 in the ref0 column.

      Actual Result:
      The query returns an empty set.

      Attachments

        Issue Links

          Activity

            In case of the column, normalize_cond() rewrites this statement:

            SELECT * FROM t1 WHERE c;
            

            as:

            SELECT * FROM t1 WHERE c<>0;
            

            The rewritten condition is evaluated as DECIMAL:

            • The string '0.6' gets converted to 0.6
            • Decimal '0.6 <> 0' evaluates as TRUE

            In case of functions, the condition does not get replaced, the conditions is evaluated as is:

            evaluate_join_record() calls Item_func_xxx::val_int(), which is :

            longlong Item_str_func::val_int()
            {
              DBUG_ASSERT(fixed());
              StringBuffer<22> tmp;
              String *res= val_str(&tmp);
              return res ? longlong_from_string_with_check(res) : 0;
            }
            

            longlong_from_string_with_check() converts '0.6' to 0 (without rounding).

            bar Alexander Barkov added a comment - In case of the column, normalize_cond() rewrites this statement: SELECT * FROM t1 WHERE c; as: SELECT * FROM t1 WHERE c<>0; The rewritten condition is evaluated as DECIMAL: The string '0.6' gets converted to 0.6 Decimal '0.6 <> 0' evaluates as TRUE In case of functions, the condition does not get replaced, the conditions is evaluated as is: evaluate_join_record() calls Item_func_xxx::val_int(), which is : longlong Item_str_func::val_int() { DBUG_ASSERT(fixed()); StringBuffer<22> tmp; String *res= val_str(&tmp); return res ? longlong_from_string_with_check(res) : 0; } longlong_from_string_with_check() converts '0.6' to 0 (without rounding).
            bar Alexander Barkov added a comment - - edited

            The problem is repeatable with the DECIMAL data type:

            CREATE OR REPLACE TABLE t1 (a DECIMAL(10,1));
            INSERT INTO t1 VALUES (0.1);
            SELECT * FROM t1 WHERE a; -- this correctly returns one row
            SELECT * FROM t1 WHERE COALESCE(a); -- this incorrectly returns empty set
            

            The problem is repeatable with the DOUBLE data type:

            CREATE OR REPLACE TABLE t1 (a DOUBLE);
            INSERT INTO t1 VALUES (0.1);
            SELECT * FROM t1 WHERE a; -- this correctly returns one row
            SELECT * FROM t1 WHERE COALESCE(a); -- this incorrectly returns empty set
            

            bar Alexander Barkov added a comment - - edited The problem is repeatable with the DECIMAL data type: CREATE OR REPLACE TABLE t1 (a DECIMAL (10,1)); INSERT INTO t1 VALUES (0.1); SELECT * FROM t1 WHERE a; -- this correctly returns one row SELECT * FROM t1 WHERE COALESCE (a); -- this incorrectly returns empty set The problem is repeatable with the DOUBLE data type: CREATE OR REPLACE TABLE t1 (a DOUBLE ); INSERT INTO t1 VALUES (0.1); SELECT * FROM t1 WHERE a; -- this correctly returns one row SELECT * FROM t1 WHERE COALESCE (a); -- this incorrectly returns empty set

            The problem is also repeatable with DATETIME:

            CREATE OR REPLACE TABLE t1 (a DATETIME(1));
            INSERT INTO t1 VALUES ('0000-00-00 00:00:00.1');
            SELECT * FROM t1 WHERE a; -- Correctly returns one row
            SELECT * FROM t1 WHERE COALESCE(a); -- Incorrectly returns empty set
            

            The problem is also repeatable with TIME:

            CREATE OR REPLACE TABLE t1 (a TIME(1));
            INSERT INTO t1 VALUES ('00:00:00.1');
            SELECT * FROM t1 WHERE a; -- Correctly returns one row
            SELECT * FROM t1 WHERE COALESCE(a); -- Incorrectly returns empty set
            

            bar Alexander Barkov added a comment - The problem is also repeatable with DATETIME: CREATE OR REPLACE TABLE t1 (a DATETIME(1)); INSERT INTO t1 VALUES ( '0000-00-00 00:00:00.1' ); SELECT * FROM t1 WHERE a; -- Correctly returns one row SELECT * FROM t1 WHERE COALESCE (a); -- Incorrectly returns empty set The problem is also repeatable with TIME: CREATE OR REPLACE TABLE t1 (a TIME (1)); INSERT INTO t1 VALUES ( '00:00:00.1' ); SELECT * FROM t1 WHERE a; -- Correctly returns one row SELECT * FROM t1 WHERE COALESCE (a); -- Incorrectly returns empty set

            I reviewed, rebased and pushed it.

            sanja Oleksandr Byelkin added a comment - I reviewed, rebased and pushed it.
            ralf.gebhardt Ralf Gebhardt added a comment -

            bar explained to me that the real issue and description for this case is "In some contexts text strings containing numbers with the integer part equal to zero and the fractional part not equal to zero where erroneously evaluated as FALSE in WHERE condition."

            ralf.gebhardt Ralf Gebhardt added a comment - bar explained to me that the real issue and description for this case is "In some contexts text strings containing numbers with the integer part equal to zero and the fractional part not equal to zero where erroneously evaluated as FALSE in WHERE condition."

            People

              bar Alexander Barkov
              dwenking chaos
              Votes:
              0 Vote for this issue
              Watchers:
              6 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.