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

Wrong query result with condition pushdown into derived table with ORDER BY ... LIMIT

Details

    • Bug
    • Status: Closed (View Workflow)
    • Major
    • Resolution: Fixed
    • 10.2(EOL)
    • 10.2.2
    • Optimizer
    • None

    Description

      Test dataset:

      create table ten(a int);
      insert into ten values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
      select a from ten order by a limit 5;
      +------+
      | a    |
      +------+
      |    0 |
      |    1 |
      |    2 |
      |    3 |
      |    4 |
      +------+
      

      Use the above query in a derived table, without condition_pushdown_for_derived:

      set optimizer_switch='condition_pushdown_for_derived=off';
      Query OK, 0 rows affected (0.00 sec)
       
      select * from (select a from ten order by a limit 5) TBL where TBL.a not in (1,2,3);
      +------+
      | a    |
      +------+
      |    0 |
      |    4 |
      +------+
      

      Enabling condition_pushdown_for_derived:

      set optimizer_switch='condition_pushdown_for_derived=on';
      Query OK, 0 rows affected (0.00 sec)
       
      select * from (select a from ten order by a limit 5) TBL where TBL.a not in (1,2,3);
      +------+
      | a    |
      +------+
      |    0 |
      |    4 |
      |    5 |
      |    6 |
      |    7 |
      +------+
      

      and see rows with id=5 and so forth. It looks like TBL.a not in (1,2,3) was pushed through ORDER BY ... LIMIT, which changes the query result.

      Attachments

        Issue Links

          Activity

            psergei Sergei Petrunia created issue -
            psergei Sergei Petrunia made changes -
            Field Original Value New Value
            Description {noformat}
            create table ten(a int);
            insert into ten values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
            {noformat}

            {noformat}
            set optimizer_switch='condition_pushdown_for_derived=off';
            Query OK, 0 rows affected (0.00 sec)

            select * from (select a from ten order by a limit 5) TBL where TBL.a not in (1,2,3);
            +------+
            | a |
            +------+
            | 0 |
            | 4 |
            +------+
            {noformat}

            {noformat}
            set optimizer_switch='condition_pushdown_for_derived=on';
            Query OK, 0 rows affected (0.00 sec)

            {noformat}
            select * from (select a from ten order by a limit 5) TBL where TBL.a not in (1,2,3);
            +------+
            | a |
            +------+
            | 0 |
            | 4 |
            | 5 |
            | 6 |
            | 7 |
            +------+
            {noformat}
            {noformat}
            create table ten(a int);
            insert into ten values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
            {noformat}

            {noformat}
            set optimizer_switch='condition_pushdown_for_derived=off';
            Query OK, 0 rows affected (0.00 sec)

            select * from (select a from ten order by a limit 5) TBL where TBL.a not in (1,2,3);
            +------+
            | a |
            +------+
            | 0 |
            | 4 |
            +------+
            {noformat}

            {noformat}
            set optimizer_switch='condition_pushdown_for_derived=on';
            Query OK, 0 rows affected (0.00 sec)

            select * from (select a from ten order by a limit 5) TBL where TBL.a not in (1,2,3);
            +------+
            | a |
            +------+
            | 0 |
            | 4 |
            | 5 |
            | 6 |
            | 7 |
            +------+
            {noformat}
            psergei Sergei Petrunia made changes -
            Description {noformat}
            create table ten(a int);
            insert into ten values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
            {noformat}

            {noformat}
            set optimizer_switch='condition_pushdown_for_derived=off';
            Query OK, 0 rows affected (0.00 sec)

            select * from (select a from ten order by a limit 5) TBL where TBL.a not in (1,2,3);
            +------+
            | a |
            +------+
            | 0 |
            | 4 |
            +------+
            {noformat}

            {noformat}
            set optimizer_switch='condition_pushdown_for_derived=on';
            Query OK, 0 rows affected (0.00 sec)

            select * from (select a from ten order by a limit 5) TBL where TBL.a not in (1,2,3);
            +------+
            | a |
            +------+
            | 0 |
            | 4 |
            | 5 |
            | 6 |
            | 7 |
            +------+
            {noformat}
            Test dataset:
            {noformat}
            create table ten(a int);
            insert into ten values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
            select a from ten order by a limit 5;
            +------+
            | a |
            +------+
            | 0 |
            | 1 |
            | 2 |
            | 3 |
            | 4 |
            +------+
            {noformat}

            Use the above query in a derived table, without condition_pushdown_for_derived:
            {noformat}
            set optimizer_switch='condition_pushdown_for_derived=off';
            Query OK, 0 rows affected (0.00 sec)

            select * from (select a from ten order by a limit 5) TBL where TBL.a not in (1,2,3);
            +------+
            | a |
            +------+
            | 0 |
            | 4 |
            +------+
            {noformat}

            Enabling condition_pushdown_for_derived:
            {noformat}
            set optimizer_switch='condition_pushdown_for_derived=on';
            Query OK, 0 rows affected (0.00 sec)

            select * from (select a from ten order by a limit 5) TBL where TBL.a not in (1,2,3);
            +------+
            | a |
            +------+
            | 0 |
            | 4 |
            | 5 |
            | 6 |
            | 7 |
            +------+
            {noformat}

            and se see rows with id=5 and so forth. It looks like {TBL.a not in (1,2,3)} was pushed through {{ORDER BY ... LIMIT}}.
            psergei Sergei Petrunia made changes -
            Description Test dataset:
            {noformat}
            create table ten(a int);
            insert into ten values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
            select a from ten order by a limit 5;
            +------+
            | a |
            +------+
            | 0 |
            | 1 |
            | 2 |
            | 3 |
            | 4 |
            +------+
            {noformat}

            Use the above query in a derived table, without condition_pushdown_for_derived:
            {noformat}
            set optimizer_switch='condition_pushdown_for_derived=off';
            Query OK, 0 rows affected (0.00 sec)

            select * from (select a from ten order by a limit 5) TBL where TBL.a not in (1,2,3);
            +------+
            | a |
            +------+
            | 0 |
            | 4 |
            +------+
            {noformat}

            Enabling condition_pushdown_for_derived:
            {noformat}
            set optimizer_switch='condition_pushdown_for_derived=on';
            Query OK, 0 rows affected (0.00 sec)

            select * from (select a from ten order by a limit 5) TBL where TBL.a not in (1,2,3);
            +------+
            | a |
            +------+
            | 0 |
            | 4 |
            | 5 |
            | 6 |
            | 7 |
            +------+
            {noformat}

            and se see rows with id=5 and so forth. It looks like {TBL.a not in (1,2,3)} was pushed through {{ORDER BY ... LIMIT}}.
            Test dataset:
            {noformat}
            create table ten(a int);
            insert into ten values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
            select a from ten order by a limit 5;
            +------+
            | a |
            +------+
            | 0 |
            | 1 |
            | 2 |
            | 3 |
            | 4 |
            +------+
            {noformat}

            Use the above query in a derived table, without condition_pushdown_for_derived:
            {noformat}
            set optimizer_switch='condition_pushdown_for_derived=off';
            Query OK, 0 rows affected (0.00 sec)

            select * from (select a from ten order by a limit 5) TBL where TBL.a not in (1,2,3);
            +------+
            | a |
            +------+
            | 0 |
            | 4 |
            +------+
            {noformat}

            Enabling condition_pushdown_for_derived:
            {noformat}
            set optimizer_switch='condition_pushdown_for_derived=on';
            Query OK, 0 rows affected (0.00 sec)

            select * from (select a from ten order by a limit 5) TBL where TBL.a not in (1,2,3);
            +------+
            | a |
            +------+
            | 0 |
            | 4 |
            | 5 |
            | 6 |
            | 7 |
            +------+
            {noformat}

            and see rows with id=5 and so forth. It looks like {{TBL.a not in (1,2,3) }} was pushed through {{ORDER BY ... LIMIT}}, which changes the query result.
            psergei Sergei Petrunia made changes -
            Description Test dataset:
            {noformat}
            create table ten(a int);
            insert into ten values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
            select a from ten order by a limit 5;
            +------+
            | a |
            +------+
            | 0 |
            | 1 |
            | 2 |
            | 3 |
            | 4 |
            +------+
            {noformat}

            Use the above query in a derived table, without condition_pushdown_for_derived:
            {noformat}
            set optimizer_switch='condition_pushdown_for_derived=off';
            Query OK, 0 rows affected (0.00 sec)

            select * from (select a from ten order by a limit 5) TBL where TBL.a not in (1,2,3);
            +------+
            | a |
            +------+
            | 0 |
            | 4 |
            +------+
            {noformat}

            Enabling condition_pushdown_for_derived:
            {noformat}
            set optimizer_switch='condition_pushdown_for_derived=on';
            Query OK, 0 rows affected (0.00 sec)

            select * from (select a from ten order by a limit 5) TBL where TBL.a not in (1,2,3);
            +------+
            | a |
            +------+
            | 0 |
            | 4 |
            | 5 |
            | 6 |
            | 7 |
            +------+
            {noformat}

            and see rows with id=5 and so forth. It looks like {{TBL.a not in (1,2,3) }} was pushed through {{ORDER BY ... LIMIT}}, which changes the query result.
            Test dataset:
            {noformat}
            create table ten(a int);
            insert into ten values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
            select a from ten order by a limit 5;
            +------+
            | a |
            +------+
            | 0 |
            | 1 |
            | 2 |
            | 3 |
            | 4 |
            +------+
            {noformat}

            Use the above query in a derived table, without condition_pushdown_for_derived:
            {noformat}
            set optimizer_switch='condition_pushdown_for_derived=off';
            Query OK, 0 rows affected (0.00 sec)

            select * from (select a from ten order by a limit 5) TBL where TBL.a not in (1,2,3);
            +------+
            | a |
            +------+
            | 0 |
            | 4 |
            +------+
            {noformat}

            Enabling condition_pushdown_for_derived:
            {noformat}
            set optimizer_switch='condition_pushdown_for_derived=on';
            Query OK, 0 rows affected (0.00 sec)

            select * from (select a from ten order by a limit 5) TBL where TBL.a not in (1,2,3);
            +------+
            | a |
            +------+
            | 0 |
            | 4 |
            | 5 |
            | 6 |
            | 7 |
            +------+
            {noformat}

            and see rows with id=5 and so forth. It looks like TBL.a not in (1,2,3) was pushed through ORDER BY ... LIMIT, which changes the query result.
            psergei Sergei Petrunia made changes -
            Assignee Sergei Petrunia [ psergey ]
            psergei Sergei Petrunia made changes -
            Assignee Sergei Petrunia [ psergey ] Igor Babaev [ igor ]
            psergei Sergei Petrunia made changes -
            psergei Sergei Petrunia made changes -
            Fix Version/s 10.2 [ 14601 ]
            igor Igor Babaev (Inactive) made changes -
            Status Open [ 1 ] In Progress [ 3 ]

            The condition should not have been pushed into SELECTs with ORDER BY ... LIMIT.

            Similarly they should not be pushed into SELECTs of a unit with global ORDER BY ... LIMIT.
            With condition pushdown into such units allowed we also can observe wrong result sets:

            ariaDB [test]> set statement optimizer_switch='condition_pushdown_for_derived=on' for 
            select * from  (select a from t1 where a < 4 union select a from t1 where a > 5  order by a limit 5) t where t.a not in (2,9);
            +------+
            | a    |
            +------+
            |    0 |
            |    1 |
            |    3 |
            |    6 |
            |    7 |
            +------+
             
            MariaDB [test]> set statement optimizer_switch='condition_pushdown_for_derived=off' for  select * from  (select a from t1 where a < 4 union select a from t1 where a > 5  order by a limit 5) t where t.a not in (2,9);
            +------+
            | a    |
            +------+
            |    0 |
            |    1 |
            |    3 |
            |    6 |
            +------+
            

            igor Igor Babaev (Inactive) added a comment - The condition should not have been pushed into SELECTs with ORDER BY ... LIMIT. Similarly they should not be pushed into SELECTs of a unit with global ORDER BY ... LIMIT. With condition pushdown into such units allowed we also can observe wrong result sets: ariaDB [test]> set statement optimizer_switch='condition_pushdown_for_derived=on' for select * from (select a from t1 where a < 4 union select a from t1 where a > 5 order by a limit 5) t where t.a not in (2,9); +------+ | a | +------+ | 0 | | 1 | | 3 | | 6 | | 7 | +------+   MariaDB [test]> set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from (select a from t1 where a < 4 union select a from t1 where a > 5 order by a limit 5) t where t.a not in (2,9); +------+ | a | +------+ | 0 | | 1 | | 3 | | 6 | +------+

            The fix for this bug was pushed into the 10.2 tree.

            igor Igor Babaev (Inactive) added a comment - The fix for this bug was pushed into the 10.2 tree.
            igor Igor Babaev (Inactive) made changes -
            Fix Version/s 10.2.2 [ 22013 ]
            Fix Version/s 10.2 [ 14601 ]
            Resolution Fixed [ 1 ]
            Status In Progress [ 3 ] Closed [ 6 ]
            serg Sergei Golubchik made changes -
            Workflow MariaDB v3 [ 77213 ] MariaDB v4 [ 150958 ]

            People

              igor Igor Babaev (Inactive)
              psergei Sergei Petrunia
              Votes:
              0 Vote for this issue
              Watchers:
              2 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.