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

LP:878753 - Assertion `0' failed in replace_where_subcondition with derived_merge and first execution of prepared statement

    Details

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

      Description

      This query:

      SELECT *
      FROM (
      SELECT *
      FROM t3
      WHERE t3.b <= 'c'
      ) AS alias1
      RIGHT JOIN t1
      ON t1.a = alias1.b
      AND ( 6 ) IN (
      SELECT a
      FROM t2
      )

      crashes when executed with derived_merge=ON, semijoin=ON and prepared statement.

      explain:

      id select_type table type possible_keys key key_len ref rows Extra
      1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
      3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables

      optimizer switch: derived_merge=ON,semijoin=ON
      full switch: index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=on,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on

      test case:

      CREATE TABLE t1 ( a varchar(1)) ;

      CREATE TABLE t2 ( a int(11), b int(11)) ;

      CREATE TABLE t3 ( a int(11) NOT NULL , b varchar(1)) ;

      SET SESSION optimizer_switch = 'derived_merge=on';
      SET SESSION optimizer_switch = 'semijoin=on';

      PREPARE st1 from "
      SELECT *
      FROM (
      SELECT *
      FROM t3
      WHERE t3.b <= 0
      ) AS alias1
      RIGHT JOIN t1
      ON t1.a = alias1.b
      AND ( 6 ) IN (
      SELECT a
      FROM t2
      )";
      EXECUTE st1;

      bzr version-info
      revision-id: <email address hidden>
      date: 2011-10-19 21:01:42 +0200
      build-date: 2011-10-20 13:09:07 +0300
      revno: 3242
      branch-nick: maria-5.3

        Gliffy Diagrams

          Attachments

            Activity

            Hide
            philipstoev Philip Stoev added a comment -

            Re: Assertion `0' failed in replace_where_subcondition with derived_merge and first execution of prepared statement
            Also reproducible without a subquery in the ON clause. Let me know if you require such a testcase.

            Show
            philipstoev Philip Stoev added a comment - Re: Assertion `0' failed in replace_where_subcondition with derived_merge and first execution of prepared statement Also reproducible without a subquery in the ON clause. Let me know if you require such a testcase.
            Hide
            philipstoev Philip Stoev added a comment -

            Re: Assertion `0' failed in replace_where_subcondition with derived_merge and first execution of prepared statement
            Test case without subquery in the ON clause:

            CREATE TABLE t1 ( b int(11)) ;

            CREATE TABLE t2 (c int, b int, d varchar(52) NOT NULL ) ;

            CREATE TABLE t3 (b int(11)) ;

            SET SESSION optimizer_switch='semijoin=on,derived_merge=on';
            PREPARE st1 FROM '
            SELECT * FROM t1
            JOIN (
            SELECT t2.* FROM t2
            WHERE t2.d <> "a"
            AND t2.c IN (
            SELECT t3.b
            FROM t3
            )
            ) AS alias2
            ON ( alias2.b = t1.b );
            ';
            EXECUTE st1;

            Show
            philipstoev Philip Stoev added a comment - Re: Assertion `0' failed in replace_where_subcondition with derived_merge and first execution of prepared statement Test case without subquery in the ON clause: CREATE TABLE t1 ( b int(11)) ; CREATE TABLE t2 (c int, b int, d varchar(52) NOT NULL ) ; CREATE TABLE t3 (b int(11)) ; SET SESSION optimizer_switch='semijoin=on,derived_merge=on'; PREPARE st1 FROM ' SELECT * FROM t1 JOIN ( SELECT t2.* FROM t2 WHERE t2.d <> "a" AND t2.c IN ( SELECT t3.b FROM t3 ) ) AS alias2 ON ( alias2.b = t1.b ); '; EXECUTE st1;
            Hide
            psergey Sergei Petrunia added a comment -

            Re: Assertion `0' failed in replace_where_subcondition with derived_merge and first execution of prepared statement
            The crash happens inside convert_join_subqueries_to_semijoins(). replace_where_subcondition() throws an assert, because it was unable to locate the subquery item that it needs to replace.

            Show
            psergey Sergei Petrunia added a comment - Re: Assertion `0' failed in replace_where_subcondition with derived_merge and first execution of prepared statement The crash happens inside convert_join_subqueries_to_semijoins(). replace_where_subcondition() throws an assert, because it was unable to locate the subquery item that it needs to replace.
            Hide
            psergey Sergei Petrunia added a comment -

            Re: Assertion `0' failed in replace_where_subcondition with derived_merge and first execution of prepared statement
            The code goes like this:

            Item **tree= (in_subq->emb_on_expr_nest == NO_JOIN_NEST)?
            &join->conds : &(in_subq->emb_on_expr_nest->on_expr);
            Item *replace_me= in_subq->original_item();
            if (replace_where_subcondition(join, tree, replace_me, substitute,
            do_fix_fields))
            DBUG_RETURN(TRUE);

            ...

            if (!thd->stmt_arena->is_conventional())

            { tree= (in_subq->emb_on_expr_nest == NO_JOIN_NEST)? &join->select_lex->prep_where : &(in_subq->emb_on_expr_nest->prep_on_expr); if (*tree && replace_where_subcondition(join, tree, replace_me, substitute, FALSE)) DBUG_RETURN(TRUE); }

            the assert happens inside the second invocation. We fail to replace Item_in_subselect in prep_on_expr, because prep_on_expr shares the "sub-item" that contains Item_in_subselect with on_expr.

            First, we do [successfull] replace in on_expr, which also makes the replace in prep_on_expr.
            Second, we attempt to do the replace in prep_on_expr, and that fails.

            Show
            psergey Sergei Petrunia added a comment - Re: Assertion `0' failed in replace_where_subcondition with derived_merge and first execution of prepared statement The code goes like this: Item **tree= (in_subq->emb_on_expr_nest == NO_JOIN_NEST)? &join->conds : &(in_subq->emb_on_expr_nest->on_expr); Item *replace_me= in_subq->original_item(); if (replace_where_subcondition(join, tree, replace_me, substitute, do_fix_fields)) DBUG_RETURN(TRUE); ... if (!thd->stmt_arena->is_conventional()) { tree= (in_subq->emb_on_expr_nest == NO_JOIN_NEST)? &join->select_lex->prep_where : &(in_subq->emb_on_expr_nest->prep_on_expr); if (*tree && replace_where_subcondition(join, tree, replace_me, substitute, FALSE)) DBUG_RETURN(TRUE); } the assert happens inside the second invocation. We fail to replace Item_in_subselect in prep_on_expr, because prep_on_expr shares the "sub-item" that contains Item_in_subselect with on_expr. First, we do [successfull] replace in on_expr, which also makes the replace in prep_on_expr. Second, we attempt to do the replace in prep_on_expr, and that fails.
            Hide
            ratzpo Rasmus Johansson added a comment -

            Launchpad bug id: 878753

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

              People

              • Assignee:
                psergey Sergei Petrunia
                Reporter:
                philipstoev Philip Stoev
              • Votes:
                0 Vote for this issue
                Watchers:
                0 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: