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

Failing queries with outer references to views in degenerated selects

Details

    • Bug
    • Status: Stalled (View Workflow)
    • Critical
    • Resolution: Unresolved
    • 11.1.2, 10.5.27, 11.2.1, 10.6, 10.9(EOL), 10.10(EOL), 10.11, 11.0(EOL), 11.1(EOL), 11.4
    • 10.5, 10.6, 10.11, 11.4
    • Optimizer
    • None
    • Ubuntu 20.04 x86-64, docker image mariadb:11.1.2

    Description

      PoC:

      SELECT ( ( ( WITH x AS ( WITH x AS ( SELECT x FROM ( SELECT * FROM ( SELECT 'x' ) x ) x WHERE ( SELECT x * x ORDER BY ( SELECT 1 GROUP BY 1 IN ( SELECT x ) ) ) ) SELECT x FROM x WHERE x ) SELECT * FROM x ) ) ) ;
      

      docker log:

      mariadbd(my_print_stacktrace+0x32)[0x556678eaa7c2]
      mariadbd(handle_fatal_signal+0x488)[0x556678983cf8]
      /lib/x86_64-linux-gnu/libc.so.6(+0x42520)[0x7f8dd27eb520]
      mariadbd(_ZN10Item_field15fix_outer_fieldEP3THDPP5FieldPP4Item+0x31b)[0x5566789ae8ab]
      mariadbd(_ZN10Item_field10fix_fieldsEP3THDPP4Item+0x415)[0x5566789af675]
      mariadbd(_ZN20Item_direct_view_ref10fix_fieldsEP3THDPP4Item+0x11b)[0x5566789b04ab]
      mariadbd(_ZN9Item_func10fix_fieldsEP3THDPP4Item+0x8c)[0x5566789f4fec]
      mariadbd(_ZN9Item_cond10fix_fieldsEP3THDPP4Item+0x139)[0x5566789ce5c9]
      mariadbd(_ZN4JOIN14optimize_innerEv+0x69b)[0x55667878fb5b]
      mariadbd(_ZN4JOIN8optimizeEv+0xda)[0x556678790e2a]
      mariadbd(+0x7ec60c)[0x5566786ca60c]
      mariadbd(_Z27mysql_handle_single_derivedP3LEXP10TABLE_LISTj+0x95)[0x5566786c9e35]
      mariadbd(_ZN4JOIN14optimize_innerEv+0xb27)[0x55667878ffe7]
      mariadbd(_ZN4JOIN8optimizeEv+0xda)[0x556678790e2a]
      mariadbd(_ZN13st_select_lex31optimize_unflattened_subqueriesEb+0x115)[0x5566786eaa55]
      mariadbd(_ZN4JOIN28optimize_constant_subqueriesEv+0x35)[0x556678889d55]
      mariadbd(_ZN4JOIN14optimize_innerEv+0x503)[0x55667878f9c3]
      mariadbd(_ZN4JOIN8optimizeEv+0xda)[0x556678790e2a]
      mariadbd(_Z12mysql_selectP3THDP10TABLE_LISTR4ListI4ItemEPS4_jP8st_orderS9_S7_S9_yP13select_resultP18st_select_lex_unitP13st_select_lex+0xd1)[0x556678790f21]
      mariadbd(_Z13handle_selectP3THDP3LEXP13select_resulty+0x154)[0x556678791774]
      mariadbd(+0x826f55)[0x556678704f55]
      mariadbd(_Z21mysql_execute_commandP3THDb+0x419e)[0x556678713f0e]
      mariadbd(_Z11mysql_parseP3THDPcjP12Parser_state+0x1e7)[0x556678715237]
      mariadbd(_Z16dispatch_command19enum_server_commandP3THDPcjb+0x14bd)[0x556678717a1d]
      mariadbd(_Z10do_commandP3THDb+0x138)[0x556678719818]
      mariadbd(_Z24do_handle_one_connectionP7CONNECTb+0x3bf)[0x5566788413af]
      mariadbd(handle_one_connection+0x5d)[0x5566788416fd]
      mariadbd(+0xcd1906)[0x556678baf906]
      /lib/x86_64-linux-gnu/libc.so.6(+0x94b43)[0x7f8dd283db43]
      /lib/x86_64-linux-gnu/libc.so.6(clone+0x44)[0x7f8dd28cebb4]
       
      Trying to get some variables.
      Some pointers may be invalid and cause the dump to abort.
      Query (0x7f8d700130d8): SELECT ( ( ( WITH x AS ( WITH x AS ( SELECT x FROM ( SELECT * FROM ( SELECT 'x' ) x ) x WHERE ( SELECT x * x ORDER BY ( SELECT 1 GROUP BY 1 IN ( SELECT x ) ) ) ) SELECT x FROM x WHERE x ) SELECT * FROM x ) ) )
       
      Connection ID (thread ID): 4
      Status: NOT_KILLED
       
      Optimizer switch: index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,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=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off,hash_join_cardinality=on
      

      Attachments

        Issue Links

          Activity

            igor Igor Babaev (Inactive) added a comment - - edited

            Let's investigate why we have a problem when fixing dt2.x from the expression dt2.x >=1 pushed into the derived table dt. This dt2.x is a full copy of dt2.x from the item list of the select that we get after having merged dt1. Due to this merge this occurrence of dt2.x is wrapped into an Item_direct_view_ref reference item. Another occurrence of
            dt2.x appears after the merge in (SELECT dt1.x). It's also wrapped into an Item_direct_view_ref reference item. Bear in mind that both wrapper reference item points to the same dt2.x in the translation table created for dt1. We see that by the time when the first item Item_direct_view_ref(dt2.x) is used to create a copy of it to replace dt1.x from the expression dt1.x>= 1 to be pushed into dt the context structure of dt2.x from the translation table is already incorrect. Let's check when the pointer to this structure is changed. It's changed in the function:

            bool Item_ident::remove_dependence_processor(void * arg)
            {
              DBUG_ENTER("Item_ident::remove_dependence_processor");
              if (get_depended_from() == (st_select_lex *) arg)
                depended_from= 0;
              context= &((st_select_lex *) arg)->context;
              DBUG_RETURN(0);
            }
            

            when we execute the following code:

                /*
                  it is single select without tables => possible optimization
                  remove the dependence mark since the item is moved to upper
                  select and is not outer anymore.
                */
                where_item->walk(&Item::remove_dependence_processor, 0,
                                 select_lex->outer_select());
            

            Here we have:

            (gdb) p dbug_print_select(select_lex)
            $8 = 0x555557b87600 <dbug_item_print_buf> "select dt2.x"
            (gdb) p dbug_print_item(where_item)
            $9 = 0x555557b87600 <dbug_item_print_buf> "dt2.x"
            (gdb) p where_item->type()
            $10 = Item::REF_ITEM
            (gdb) p ((Item_ref*)where_item)->ref_type()
            $11 = Item_ref::VIEW_REF
            (gdb) p ((Item_direct_view_ref*)where_item)->view->alias
            $12 = {str = 0x7fff74019b30 "dt1", length = 3}
            (gdb) p (*(((Item_direct_view_ref*)where_item)->ref))->type()
            $14 = Item::FIELD_ITEM
            (gdb) p dbug_print_item(*(((Item_direct_view_ref*)where_item)->ref))
            $15 = 0x555557b87600 <dbug_item_print_buf> "dt2.x"
            

            We see that the statement:

            context= &((st_select_lex *) arg)->context;
            

            effectively sets the new context of the occurrence dt2.x in the select list. After this change we have the context with:

            (gdb) p dbug_print_select(((st_select_lex *) arg)->context.select_lex)
            $38 = 0x555557b87600 <dbug_item_print_buf> "select t2.a from t2 where 1 in (subquery#6) and t2.a < 2"
            gdb) p ((st_select_lex *) arg)->context.first_name_resolution_table->alias
            $39 = {str = 0x7fff7801a8e0 "t2", length = 2}
            

            dt2.x cannot be resolved a a field of t2.
            The context of Item_direct_view_ref wrapper around dt2.x is also changed and in the same way.

            Note that only the occurrence of dt2.x in the IN predicate is an outer reference. And
            get_depended_from() != NULL only for this occurrence.

            The following implementation of Item_ident::remove_dependence_processor could fix this problem:

            bool Item_ident::remove_dependence_processor(void * arg)
            {
              DBUG_ENTER("Item_ident::remove_dependence_processor");
              if (get_depended_from() == (st_select_lex *) arg)
              {
                depended_from= 0;
                context= &((st_select_lex *) arg)->context;
              }
              DBUG_RETURN(0);
            }
            

            And indeed with this change we have:

            MariaDB [test]> SELECT dt.x
                -> FROM 
                -> ( 
                ->   SELECT dt1.x
                ->   FROM
                ->   (
                ->     SELECT dt2.x
                ->     FROM
                ->     (
                ->       SELECT t1.x FROM t1 WHERE t1.x < 2 GROUP BY t1.x  
                ->     ) dt2
                ->   ) dt1 
                ->   WHERE (SELECT t2.a FROM t2 WHERE (1 IN (SELECT dt1.x)) AND t2.a < 2) != 0
                ->   GROUP BY dt1.x
                -> ) dt
                -> WHERE dt.x>=1;
            +------+
            | x    |
            +------+
            |    1 |
            +------+
            

            and all tests from the main test suite pass, and with --ps-protocol and --view-protocol as well.
            Yet the query itself returns the empty set when executed in prepared mode.

            MariaDB [test]> PREPARE stmt FROM "
                "> SELECT dt.x
                "> FROM 
                "> ( 
                ">   SELECT dt1.x
                ">   FROM
                ">   (
                ">     SELECT dt2.x
                ">     FROM
                ">     (
                ">       SELECT t1.x FROM t1 WHERE t1.x < 2 GROUP BY t1.x  
                ">     ) dt2
                ">   ) dt1 
                ">   WHERE (SELECT t2.a FROM t2 WHERE (1 IN (SELECT dt1.x)) AND t2.a < 2) != 0
                ">   GROUP BY dt1.x
                "> ) dt
                "> WHERE dt.x>=1;
                "> ";
            Query OK, 0 rows affected (0.002 sec)
            Statement prepared
             
            MariaDB [test]> EXECUTE stmt;
            Empty set ( 0.003 sec)
            

            igor Igor Babaev (Inactive) added a comment - - edited Let's investigate why we have a problem when fixing dt2.x from the expression dt2.x >=1 pushed into the derived table dt. This dt2.x is a full copy of dt2.x from the item list of the select that we get after having merged dt1. Due to this merge this occurrence of dt2.x is wrapped into an Item_direct_view_ref reference item. Another occurrence of dt2.x appears after the merge in (SELECT dt1.x). It's also wrapped into an Item_direct_view_ref reference item. Bear in mind that both wrapper reference item points to the same dt2.x in the translation table created for dt1. We see that by the time when the first item Item_direct_view_ref(dt2.x) is used to create a copy of it to replace dt1.x from the expression dt1.x>= 1 to be pushed into dt the context structure of dt2.x from the translation table is already incorrect. Let's check when the pointer to this structure is changed. It's changed in the function: bool Item_ident::remove_dependence_processor(void * arg) { DBUG_ENTER("Item_ident::remove_dependence_processor"); if (get_depended_from() == (st_select_lex *) arg) depended_from= 0; context= &((st_select_lex *) arg)->context; DBUG_RETURN(0); } when we execute the following code: /* it is single select without tables => possible optimization remove the dependence mark since the item is moved to upper select and is not outer anymore. */ where_item->walk(&Item::remove_dependence_processor, 0, select_lex->outer_select()); Here we have: (gdb) p dbug_print_select(select_lex) $8 = 0x555557b87600 <dbug_item_print_buf> "select dt2.x" (gdb) p dbug_print_item(where_item) $9 = 0x555557b87600 <dbug_item_print_buf> "dt2.x" (gdb) p where_item->type() $10 = Item::REF_ITEM (gdb) p ((Item_ref*)where_item)->ref_type() $11 = Item_ref::VIEW_REF (gdb) p ((Item_direct_view_ref*)where_item)->view->alias $12 = {str = 0x7fff74019b30 "dt1", length = 3} (gdb) p (*(((Item_direct_view_ref*)where_item)->ref))->type() $14 = Item::FIELD_ITEM (gdb) p dbug_print_item(*(((Item_direct_view_ref*)where_item)->ref)) $15 = 0x555557b87600 <dbug_item_print_buf> "dt2.x" We see that the statement: context= &((st_select_lex *) arg)->context; effectively sets the new context of the occurrence dt2.x in the select list. After this change we have the context with: (gdb) p dbug_print_select(((st_select_lex *) arg)->context.select_lex) $38 = 0x555557b87600 <dbug_item_print_buf> "select t2.a from t2 where 1 in (subquery#6) and t2.a < 2" gdb) p ((st_select_lex *) arg)->context.first_name_resolution_table->alias $39 = {str = 0x7fff7801a8e0 "t2", length = 2} dt2.x cannot be resolved a a field of t2. The context of Item_direct_view_ref wrapper around dt2.x is also changed and in the same way. Note that only the occurrence of dt2.x in the IN predicate is an outer reference. And get_depended_from() != NULL only for this occurrence. The following implementation of Item_ident::remove_dependence_processor could fix this problem: bool Item_ident::remove_dependence_processor(void * arg) { DBUG_ENTER("Item_ident::remove_dependence_processor"); if (get_depended_from() == (st_select_lex *) arg) { depended_from= 0; context= &((st_select_lex *) arg)->context; } DBUG_RETURN(0); } And indeed with this change we have: MariaDB [test]> SELECT dt.x -> FROM -> ( -> SELECT dt1.x -> FROM -> ( -> SELECT dt2.x -> FROM -> ( -> SELECT t1.x FROM t1 WHERE t1.x < 2 GROUP BY t1.x -> ) dt2 -> ) dt1 -> WHERE (SELECT t2.a FROM t2 WHERE (1 IN (SELECT dt1.x)) AND t2.a < 2) != 0 -> GROUP BY dt1.x -> ) dt -> WHERE dt.x>=1; +------+ | x | +------+ | 1 | +------+ and all tests from the main test suite pass, and with --ps-protocol and --view-protocol as well. Yet the query itself returns the empty set when executed in prepared mode. MariaDB [test]> PREPARE stmt FROM " "> SELECT dt.x "> FROM "> ( "> SELECT dt1.x "> FROM "> ( "> SELECT dt2.x "> FROM "> ( "> SELECT t1.x FROM t1 WHERE t1.x < 2 GROUP BY t1.x "> ) dt2 "> ) dt1 "> WHERE (SELECT t2.a FROM t2 WHERE (1 IN (SELECT dt1.x)) AND t2.a < 2) != 0 "> GROUP BY dt1.x "> ) dt "> WHERE dt.x>=1; "> "; Query OK, 0 rows affected (0.002 sec) Statement prepared   MariaDB [test]> EXECUTE stmt; Empty set ( 0.003 sec)
            igor Igor Babaev (Inactive) added a comment - - edited

            Moreover, even for the query to which no pushdown into derived can be applied:

            SELECT dt.x
            FROM 
            ( 
              SELECT dt1.x
              FROM
              (
                SELECT dt2.x
                FROM
                (
                  SELECT t1.x FROM t1 WHERE t1.x < 2 GROUP BY t1.x  
                ) dt2
              ) dt1 
              WHERE (SELECT t2.a FROM t2 WHERE (1 IN (SELECT dt1.x)) AND t2.a < 2) != 0
              GROUP BY dt1.x
            ) dt;
            

            we see the same wrong result when executing the query in prepared mode:

            MariaDB [test]> PREPARE stmt FROM "
                "> SELECT dt.x
                "> FROM 
                "> ( 
                ">   SELECT dt1.x
                ">   FROM
                ">   (
                ">     SELECT dt2.x
                ">     FROM
                ">     (
                ">       SELECT t1.x FROM t1 WHERE t1.x < 2 GROUP BY t1.x  
                ">     ) dt2
                ">   ) dt1 
                ">   WHERE (SELECT t2.a FROM t2 WHERE (1 IN (SELECT dt1.x)) AND t2.a < 2) != 0
                ">   GROUP BY dt1.x
                "> ) dt;
                "> ";
            Query OK, 0 rows affected (0.002 sec)
            Statement prepared
             
            MariaDB [test]> EXECUTE stmt;
            Empty set (0.003 sec)
            

            Let's investigate why it happens.
            When processing the EXECUTE command at the call of JOIN::prepare for the query we see:

            (gdb) p dbug_print_select(select_lex)
            $40 = 0x555557b87600 <dbug_item_print_buf> "select dt.x AS x from (select dt1.x AS x from (select dt2.x AS x from (select t1.x AS x from t1 where t1.x < 2 group by t1.x) dt2) dt1 where (subquery#5) <> 0 group by dt1.x) dt"
            

            and subquery#5 here looks like this:

            (gdb) p dbug_print_select(select_lex)
            $44 = 0x555557b87600 <dbug_item_print_buf> "select t2.a from t2 where 1 = dt2.x and t2.a < 2"
            

            Here dt2.x in the expression "1 = dt2.x" is actually wrapped into an Item_direct_view_ref object. When fix_fields is called for the where condition of subquery#5 it calls fix_fields for the expression. The latter calls fix_fields for Item_direct_view_ref around dt2.x. Note that dt2.x is the item from the translation table created for the mergeable derived table dt1. Because dt2.x is also used in the item list of select containing subquery#5 it has already been fixed and no new fix_fields is called for the occurrence of dt2.x from subquery#5. As a result no Item_field::fix_outer_field is called for this occurrence of dt2.x and the list upper_refs remains empty for the subquery#5. It leads to a wrong re-calculation of used_tables_cache for the subquery in the call of st_select_lex::update_used_tables() at the optimization stage after which the subquery mistakenly is treated as non-correlated.
            Opposed to the occurrence of dt2.x from the item list of the select that uses subquery#5 the occurrence of dt2.x in this subquery preserves an Item_direct_view_ref wrapper while such wrapper for the first occurrence is rolled back at the end of processing the PREPARE command. The wrapper around the second occurrence has not been rolled back due to the conversion of the predicate 1 IN (SELECT dt1.x) into the expression 1 = dt1.x done when the PREPARE command was executed.

            igor Igor Babaev (Inactive) added a comment - - edited Moreover, even for the query to which no pushdown into derived can be applied: SELECT dt.x FROM ( SELECT dt1.x FROM ( SELECT dt2.x FROM ( SELECT t1.x FROM t1 WHERE t1.x < 2 GROUP BY t1.x ) dt2 ) dt1 WHERE (SELECT t2.a FROM t2 WHERE (1 IN (SELECT dt1.x)) AND t2.a < 2) != 0 GROUP BY dt1.x ) dt; we see the same wrong result when executing the query in prepared mode: MariaDB [test]> PREPARE stmt FROM " "> SELECT dt.x "> FROM "> ( "> SELECT dt1.x "> FROM "> ( "> SELECT dt2.x "> FROM "> ( "> SELECT t1.x FROM t1 WHERE t1.x < 2 GROUP BY t1.x "> ) dt2 "> ) dt1 "> WHERE (SELECT t2.a FROM t2 WHERE (1 IN (SELECT dt1.x)) AND t2.a < 2) != 0 "> GROUP BY dt1.x "> ) dt; "> "; Query OK, 0 rows affected (0.002 sec) Statement prepared   MariaDB [test]> EXECUTE stmt; Empty set (0.003 sec) Let's investigate why it happens. When processing the EXECUTE command at the call of JOIN::prepare for the query we see: (gdb) p dbug_print_select(select_lex) $40 = 0x555557b87600 <dbug_item_print_buf> "select dt.x AS x from (select dt1.x AS x from (select dt2.x AS x from (select t1.x AS x from t1 where t1.x < 2 group by t1.x) dt2) dt1 where (subquery#5) <> 0 group by dt1.x) dt" and subquery#5 here looks like this: (gdb) p dbug_print_select(select_lex) $44 = 0x555557b87600 <dbug_item_print_buf> "select t2.a from t2 where 1 = dt2.x and t2.a < 2" Here dt2.x in the expression "1 = dt2.x" is actually wrapped into an Item_direct_view_ref object. When fix_fields is called for the where condition of subquery#5 it calls fix_fields for the expression. The latter calls fix_fields for Item_direct_view_ref around dt2.x. Note that dt2.x is the item from the translation table created for the mergeable derived table dt1. Because dt2.x is also used in the item list of select containing subquery#5 it has already been fixed and no new fix_fields is called for the occurrence of dt2.x from subquery#5. As a result no Item_field::fix_outer_field is called for this occurrence of dt2.x and the list upper_refs remains empty for the subquery#5. It leads to a wrong re-calculation of used_tables_cache for the subquery in the call of st_select_lex::update_used_tables() at the optimization stage after which the subquery mistakenly is treated as non-correlated. Opposed to the occurrence of dt2.x from the item list of the select that uses subquery#5 the occurrence of dt2.x in this subquery preserves an Item_direct_view_ref wrapper while such wrapper for the first occurrence is rolled back at the end of processing the PREPARE command. The wrapper around the second occurrence has not been rolled back due to the conversion of the predicate 1 IN (SELECT dt1.x) into the expression 1 = dt1.x done when the PREPARE command was executed.

            If we do the conversion of the predicate 1 IN (SELECT dt1.x) into the expression 1 = dt1.x at the first execution of the prepared statement rather than when processing the PREPARE command we'll get an empty result set at the second execution. After having the following results for the procedure:

            CREATE PROCEDURE p()
            SELECT dt.x
            FROM 
            ( 
              SELECT dt1.x
              FROM
              (
                SELECT dt2.x
                FROM
                (
                  SELECT t1.x FROM t1 WHERE t1.x < 2 GROUP BY t1.x  
                ) dt2
              ) dt1 
              WHERE (SELECT t2.a FROM t2 WHERE (1 IN (SELECT dt1.x)) AND t2.a < 2) != 0
              GROUP BY dt1.x
            ) dt;
            

            MariaDB [test]> CALL p();
            +------+
            | x    |
            +------+
            |    1 |
            +------+
            1 row in set (0.003 sec)
             
            Query OK, 0 rows affected (0.003 sec)
             
            MariaDB [test]> CALL p();
            Empty set (0.003 sec)
            

            we easily can predict it.

            igor Igor Babaev (Inactive) added a comment - If we do the conversion of the predicate 1 IN (SELECT dt1.x) into the expression 1 = dt1.x at the first execution of the prepared statement rather than when processing the PREPARE command we'll get an empty result set at the second execution. After having the following results for the procedure: CREATE PROCEDURE p() SELECT dt.x FROM ( SELECT dt1.x FROM ( SELECT dt2.x FROM ( SELECT t1.x FROM t1 WHERE t1.x < 2 GROUP BY t1.x ) dt2 ) dt1 WHERE ( SELECT t2.a FROM t2 WHERE (1 IN ( SELECT dt1.x)) AND t2.a < 2) != 0 GROUP BY dt1.x ) dt; MariaDB [test]> CALL p(); +------+ | x | +------+ | 1 | +------+ 1 row in set (0.003 sec)   Query OK, 0 rows affected (0.003 sec)   MariaDB [test]> CALL p(); Empty set (0.003 sec) we easily can predict it.

            Summing up a full solution for this bug requires a resolution of the problem of wrong re-calculation of used_tables_cache for subqueries with outer references. Such re-calculation has to be done after any permanent transformation. The problem is reported in MDEV-32294.

            igor Igor Babaev (Inactive) added a comment - Summing up a full solution for this bug requires a resolution of the problem of wrong re-calculation of used_tables_cache for subqueries with outer references. Such re-calculation has to be done after any permanent transformation. The problem is reported in MDEV-32294.
            Johnston Rex Johnston added a comment -

            With the latest patch from https://github.com/MariaDB/server/tree/MDEV-32294-Work_In_Progress
            https://github.com/MariaDB/server/commit/f8e2caaa4036cece9368831d15670594a7e2e1d1

            We have this

            MariaDB [test]> CREATE PROCEDURE p()
                -> SELECT dt.x
                -> FROM 
                -> ( 
                ->   SELECT dt1.x
                ->   FROM
                ->   (
                ->     SELECT dt2.x
                ->     FROM
                ->     (
                ->       SELECT t1.x FROM t1 WHERE t1.x < 2 GROUP BY t1.x  
                ->     ) dt2
                ->   ) dt1 
                ->   WHERE (SELECT t2.a FROM t2 WHERE (1 IN (SELECT dt1.x)) AND t2.a < 2) != 0
                ->   GROUP BY dt1.x
                -> ) dt;
            Query OK, 0 rows affected (0.031 sec)
             
            MariaDB [test]> call p();
            +------+
            | x    |
            +------+
            |    1 |
            +------+
            1 row in set (0.012 sec)
             
            Query OK, 0 rows affected (0.013 sec)
             
            MariaDB [test]> call p();
            +------+
            | x    |
            +------+
            |    1 |
            +------+
            1 row in set (0.009 sec)
            

            I'm still investigating some wrong results from queries i've detailed in MDEV-35859

            Johnston Rex Johnston added a comment - With the latest patch from https://github.com/MariaDB/server/tree/MDEV-32294-Work_In_Progress https://github.com/MariaDB/server/commit/f8e2caaa4036cece9368831d15670594a7e2e1d1 We have this MariaDB [test]> CREATE PROCEDURE p() -> SELECT dt.x -> FROM -> ( -> SELECT dt1.x -> FROM -> ( -> SELECT dt2.x -> FROM -> ( -> SELECT t1.x FROM t1 WHERE t1.x < 2 GROUP BY t1.x -> ) dt2 -> ) dt1 -> WHERE (SELECT t2.a FROM t2 WHERE (1 IN (SELECT dt1.x)) AND t2.a < 2) != 0 -> GROUP BY dt1.x -> ) dt; Query OK, 0 rows affected (0.031 sec)   MariaDB [test]> call p(); +------+ | x | +------+ | 1 | +------+ 1 row in set (0.012 sec)   Query OK, 0 rows affected (0.013 sec)   MariaDB [test]> call p(); +------+ | x | +------+ | 1 | +------+ 1 row in set (0.009 sec) I'm still investigating some wrong results from queries i've detailed in MDEV-35859

            People

              Johnston Rex Johnston
              fuboat Jingzhou Fu
              Votes:
              0 Vote for this issue
              Watchers:
              8 Start watching this issue

              Dates

                Created:
                Updated:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.