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

Wrong result for SELECT..WHERE CASE enum_field WHEN 1 THEN 1 ELSE 0 END AND a='5'

    Details

      Description

      In this script:

      DROP TABLE IF EXISTS t1;
      CREATE TABLE t1 (a ENUM('5','6') CHARACTER SET BINARY);
      INSERT INTO t1 VALUES ('5'),('6');
      SELECT * FROM t1 WHERE a='5';
      SELECT * FROM t1 WHERE a=1;
      SELECT * FROM t1 WHERE CASE a WHEN 1 THEN 1 ELSE 0 END;

      all SELECT queries return the same row:

      +------+
      | a    |
      +------+
      | 5    |
      +------+

      Now if I join the first and the third conditions into the same condition:

      SELECT * FROM t1 WHERE CASE a WHEN 1 THEN 1 ELSE 0 END AND a='5';

      it returns empty set. The expected result is to return the same row.

      Another example demonstrates that CASE does not propagate equal fields when it safely could:

      DROP TABLE IF EXISTS t1;
      CREATE TABLE t1 (a ENUM('a','b'));
      INSERT INTO t1 VALUES ('a'),('b');
      EXPLAIN EXTENDED SELECT * FROM t1 WHERE CASE a WHEN 'a' THEN 1 ELSE 0 END AND a='a';
      SHOW WARNINGS;

      The above script returns:

      +-------+------+--------------------------------------------------------------------------------------------------------------------------------------+
      | Level | Code | Message                                                                                                                              |
      +-------+------+--------------------------------------------------------------------------------------------------------------------------------------+
      | Note  | 1003 | select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = 'a') and (case `test`.`t1`.`a` when 'a' then 1 else 0 end)) |
      +-------+------+--------------------------------------------------------------------------------------------------------------------------------------+

      It could safely be rewritten as:

      SELECT * FROM t1 WHERE CASE 'a' WHEN 'a' THEN 1 ELSE 0 END AND a='a';

      and then remove the constant part:

      SELECT * FROM t1 WHERE a='a';

        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: