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

LP:813418 - Wrong result with aggregate + NOT BETWEEN + key

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: None
    • Labels:

      Description

      Repeatable in mysql-5.1,5.5, maria 5.1, 5.2, 5.5. The following query:

      SELECT MAX(a) FROM t1 WHERE a NOT BETWEEN 3 AND 9;

      returns NULL even though there are obviously rows that match the WHERE predicate.

      explain:

      id select_type table type possible_keys key key_len ref rows Extra
      1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No matching min/max row

      test case:

      CREATE TABLE t1 (a int, KEY (a));
      INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
      SELECT MAX(a) FROM t1 WHERE a NOT BETWEEN 3 AND 9;

        Gliffy Diagrams

          Attachments

            Activity

            Hide
            timour Timour Katchaounov added a comment -

            Re: Wrong result with aggregate + NOT BETWEEN + key
            Assigning to Sanja, because he already dealt with some MIN/MAX
            optimization bug recently.

            Show
            timour Timour Katchaounov added a comment - Re: Wrong result with aggregate + NOT BETWEEN + key Assigning to Sanja, because he already dealt with some MIN/MAX optimization bug recently.
            Hide
            sanja Oleksandr Byelkin added a comment -

            Re: Wrong result with aggregate + NOT BETWEEN + key
            The problem is that when optimizer trying to calculate maximum by the index (opt_sum_query) it gets 9 (right value is 10).

            The problem is not engine related (myisam/aria/innodb return the same result).

            Show
            sanja Oleksandr Byelkin added a comment - Re: Wrong result with aggregate + NOT BETWEEN + key The problem is that when optimizer trying to calculate maximum by the index (opt_sum_query) it gets 9 (right value is 10). The problem is not engine related (myisam/aria/innodb return the same result).
            Hide
            sanja Oleksandr Byelkin added a comment -

            Re: Wrong result with aggregate + NOT BETWEEN + key
            The problem is that get_index_max_value has ref->key_length set and its looks not for maximum of the all index but for maximum with some prefix...

            Show
            sanja Oleksandr Byelkin added a comment - Re: Wrong result with aggregate + NOT BETWEEN + key The problem is that get_index_max_value has ref->key_length set and its looks not for maximum of the all index but for maximum with some prefix...
            Hide
            sanja Oleksandr Byelkin added a comment -

            Re: Wrong result with aggregate + NOT BETWEEN + key
            The problem is in matching_cond, the code

            /* Update endpoints for MAX/MIN, see function comment. */
            Item *value= args[between && max_fl ? 2 : 1];

            does not takes into account that BETWEEN could be negated (Item_func_between inherited from Item_func_opt_neg).

            Show
            sanja Oleksandr Byelkin added a comment - Re: Wrong result with aggregate + NOT BETWEEN + key The problem is in matching_cond, the code /* Update endpoints for MAX/MIN, see function comment. */ Item *value= args [between && max_fl ? 2 : 1] ; does not takes into account that BETWEEN could be negated (Item_func_between inherited from Item_func_opt_neg).
            Hide
            sanja Oleksandr Byelkin added a comment -

            Re: Wrong result with aggregate + NOT BETWEEN + key
            It is possible just switch off optimization for negated BETWEEN:

            === modified file 'sql/opt_sum.cc'
            — sql/opt_sum.cc 2011-05-03 16:10:10 +0000
            +++ sql/opt_sum.cc 2011-09-08 00:47:11 +0000
            @@ -657,6 +657,8 @@ static bool matching_cond(bool max_fl, T
            case Item_func::GE_FUNC:
            break;
            case Item_func::BETWEEN:
            + if (((Item_func_between*) cond)->negated)
            + DBUG_RETURN(FALSE);
            between= 1;
            break;
            case Item_func::MULT_EQUAL_FUNC:

            Show
            sanja Oleksandr Byelkin added a comment - Re: Wrong result with aggregate + NOT BETWEEN + key It is possible just switch off optimization for negated BETWEEN: === modified file 'sql/opt_sum.cc' — sql/opt_sum.cc 2011-05-03 16:10:10 +0000 +++ sql/opt_sum.cc 2011-09-08 00:47:11 +0000 @@ -657,6 +657,8 @@ static bool matching_cond(bool max_fl, T case Item_func::GE_FUNC: break; case Item_func::BETWEEN: + if (((Item_func_between*) cond)->negated) + DBUG_RETURN(FALSE); between= 1; break; case Item_func::MULT_EQUAL_FUNC:
            Hide
            ratzpo Rasmus Johansson added a comment -

            Launchpad bug id: 813418

            Show
            ratzpo Rasmus Johansson added a comment - Launchpad bug id: 813418

              People

              • Assignee:
                sanja Oleksandr Byelkin
                Reporter:
                philipstoev Philip Stoev
              • Votes:
                0 Vote for this issue
                Watchers:
                0 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: