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

Server crashes at TABLE::add_tmp_key

Details

    • Bug
    • Status: Closed (View Workflow)
    • Major
    • Resolution: Fixed
    • 11.1.2, 11.2.1, 10.4(EOL), 10.5, 10.6, 10.9(EOL), 10.10(EOL), 10.11, 11.0(EOL), 11.1(EOL), 11.2(EOL)
    • Optimizer
    • None
    • Ubuntu 20.04 x86-64, docker image mariadb:11.1.2

    Description

      PoC:

      SELECT 
        EXISTS ( 
          WITH x ( x ) AS ( SELECT 1 ) 
          SELECT NULL 
          WHERE ( 1 , 1 ) = 
               ( SELECT 
                 1 , ( ( x , 1.000000 ) , 1 ) 
                 IN 
                 (SELECT 'x' , 'x' 
                  WHERE ( ( 'x' ) ) 
                  UNION 
                  SELECT 1 , x 
                  HAVING 1 != 1 
                 )
                 FROM x 
                ) 
        );
      

      docker log:

      mariadbd(my_print_stacktrace+0x32)[0x55ab626be7c2]
      mariadbd(handle_fatal_signal+0x488)[0x55ab62197cf8]
      /lib/x86_64-linux-gnu/libc.so.6(+0x42520)[0x7fe667658520]
      mariadbd(_ZN5TABLE11add_tmp_keyEjjPFjPhES0_b+0x1bc)[0x55ab620253ec]
      mariadbd(_ZN25Expression_cache_tmptable4initEv+0x1d3)[0x55ab620a3a73]
      mariadbd(_ZN18Item_cache_wrapper11check_cacheEv+0x21)[0x55ab621c4aa1]
      mariadbd(_ZN18Item_cache_wrapper7val_intEv+0x21)[0x55ab621c4c31]
      mariadbd(_ZN14Item_cache_int11cache_valueEv+0x29)[0x55ab621ad149]
      mariadbd(_ZN26select_singlerow_subselect9send_dataER4ListI4ItemE+0x3f)[0x55ab61ec193f]
      mariadbd(+0x89bf74)[0x55ab61f8df74]
      mariadbd(_ZN4JOIN10exec_innerEv+0x1222)[0x55ab61fa6e12]
      mariadbd(_ZN4JOIN4execEv+0x3f)[0x55ab61fa6fff]
      mariadbd(_ZN30subselect_single_select_engine4execEv+0x146)[0x55ab622777f6]
      mariadbd(_ZN14Item_subselect4execEv+0x4c)[0x55ab6227673c]
      mariadbd(_ZN24Item_singlerow_subselect11bring_valueEv+0x17)[0x55ab62277ec7]
      mariadbd(_ZN14Arg_comparator11compare_rowEv+0x37)[0x55ab621d1377]
      mariadbd(_ZN12Item_func_eq7val_intEv+0x2f)[0x55ab621d164f]
      mariadbd(_ZN4JOIN10exec_innerEv+0x432)[0x55ab61fa6022]
      mariadbd(_ZN4JOIN4execEv+0x3f)[0x55ab61fa6fff]
      mariadbd(_ZN30subselect_single_select_engine4execEv+0x146)[0x55ab622777f6]
      mariadbd(_ZN14Item_subselect4execEv+0x4c)[0x55ab6227673c]
      mariadbd(_ZN21Item_exists_subselect7val_intEv+0x23)[0x55ab622764a3]
      mariadbd(_ZNK12Type_handler14Item_send_longEP4ItemP8ProtocolP8st_value+0x1d)[0x55ab620ee89d]
      mariadbd(_ZN8Protocol19send_result_set_rowEP4ListI4ItemE+0xea)[0x55ab61e4ccfa]
      mariadbd(_ZN11select_send9send_dataER4ListI4ItemE+0x37)[0x55ab61ecb6a7]
      mariadbd(_ZN4JOIN10exec_innerEv+0xc90)[0x55ab61fa6880]
      mariadbd(_ZN4JOIN4execEv+0x3f)[0x55ab61fa6fff]
      mariadbd(_Z12mysql_selectP3THDP10TABLE_LISTR4ListI4ItemEPS4_jP8st_orderS9_S7_S9_yP13select_resultP18st_select_lex_unitP13st_select_lex+0x12c)[0x55ab61fa4f7c]
      mariadbd(_Z13handle_selectP3THDP3LEXP13select_resulty+0x154)[0x55ab61fa5774]
      mariadbd(+0x826f55)[0x55ab61f18f55]
      mariadbd(_Z21mysql_execute_commandP3THDb+0x419e)[0x55ab61f27f0e]
      mariadbd(_Z11mysql_parseP3THDPcjP12Parser_state+0x1e7)[0x55ab61f29237]
      mariadbd(_Z16dispatch_command19enum_server_commandP3THDPcjb+0x14bd)[0x55ab61f2ba1d]
      mariadbd(_Z10do_commandP3THDb+0x138)[0x55ab61f2d818]
      mariadbd(_Z24do_handle_one_connectionP7CONNECTb+0x3bf)[0x55ab620553af]
      mariadbd(handle_one_connection+0x5d)[0x55ab620556fd]
      mariadbd(+0xcd1906)[0x55ab623c3906]
      /lib/x86_64-linux-gnu/libc.so.6(+0x94b43)[0x7fe6676aab43]
      /lib/x86_64-linux-gnu/libc.so.6(clone+0x44)[0x7fe66773bbb4]
       
      Trying to get some variables.
      Some pointers may be invalid and cause the dump to abort.
      Query (0x7fe5f80130d8): SELECT EXISTS ( WITH x ( x ) AS ( SELECT 1 ) SELECT NULL WHERE ( 1 , 1 ) = ( SELECT 1 , ( ( x , 1.000000 ) , 1 ) IN ( SELECT 'x' , 'x' WHERE ( ( 'x' ) ) UNION SELECT 1 , x HAVING 1 != 1 ) 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

        Activity

          alice Alice Sherepa added a comment -

          Thanks! I repeated on 10.4-11.2:

          SELECT  ( ( x , 1 ) , 1 ) IN ( SELECT 'x' , 'x'  WHERE 0 UNION SELECT 1 , x HAVING 0) FROM  ( SELECT 1 x ) x ;
          

          Version: '10.4.32-MariaDB-debug-log'  
          231009 15:22:32 [ERROR] mysqld got signal 11 ;
           
          Server version: 10.4.32-MariaDB-debug-log source revision: 0c7af6a2a19343cb9d4fedbd7165b8f73bc4cf96
           
          sigaction.c:0(__restore_rt)[0x7f0ec71dc420]
          sql/sql_bitmap.h:118(Bitmap<64u>::set_bit(unsigned int))[0x55de76e6efa3]
          sql/table.cc:7984(TABLE::add_tmp_key(unsigned int, unsigned int, unsigned int (*)(unsigned char*), unsigned char*, bool))[0x55de77317475]
          sql/sql_expression_cache.cc:143(Expression_cache_tmptable::init())[0x55de774e68c2]
          sql/item.cc:8638(Item_cache_wrapper::init_on_demand())[0x55de77825e89]
          sql/item.cc:8761(Item_cache_wrapper::check_cache())[0x55de77826cc0]
          sql/item.cc:8824(Item_cache_wrapper::val_int())[0x55de778277e6]
          sql/sql_type.cc:7106(Type_handler::Item_send_long(Item*, Protocol*, st_value*) const)[0x55de7755a330]
          sql/sql_type.h:5192(Type_handler_long::Item_send(Item*, Protocol*, st_value*) const)[0x55de77574a3c]
          sql/item.h:1045(Item::send(Protocol*, st_value*))[0x55de76d0c5e4]
          sql/item.cc:8682(Item_cache_wrapper::send(Protocol*, st_value*))[0x55de77826484]
          sql/protocol.cc:1038(Protocol::send_result_set_row(List<Item>*))[0x55de76cfdf63]
          sql/sql_class.cc:3138(select_send::send_data(List<Item>&))[0x55de76eb0d83]
          sql/sql_select.cc:22098(end_send(JOIN*, st_join_table*, bool))[0x55de7712150b]
          sql/sql_select.cc:20363(do_select(JOIN*, Procedure*))[0x55de77115869]
          sql/sql_select.cc:4605(JOIN::exec_inner())[0x55de770a3adc]
          sql/sql_select.cc:4388(JOIN::exec())[0x55de770a110c]
          sql/sql_select.cc:4828(mysql_select(THD*, TABLE_LIST*, unsigned int, List<Item>&, Item*, unsigned int, st_order*, st_order*, Item*, st_order*, unsigned long long, select_result*, st_select_lex_unit*, st_select_lex*))[0x55de770a52e8]
          sql/sql_select.cc:442(handle_select(THD*, LEX*, select_result*, unsigned long))[0x55de77075de0]
          sql/sql_parse.cc:6475(execute_sqlcom_select(THD*, TABLE_LIST*))[0x55de76fe1be4]
          sql/sql_parse.cc:3978(mysql_execute_command(THD*))[0x55de76fcf35b]
          sql/sql_parse.cc:8012(mysql_parse(THD*, char*, unsigned int, Parser_state*, bool, bool))[0x55de76feb0bf]
          sql/sql_parse.cc:1860(dispatch_command(enum_server_command, THD*, char*, unsigned int, bool, bool))[0x55de76fc14e5]
          sql/sql_parse.cc:1378(do_command(THD*))[0x55de76fbe010]
          sql/sql_connect.cc:1420(do_handle_one_connection(CONNECT*))[0x55de773cbdeb]
          sql/sql_connect.cc:1325(handle_one_connection)[0x55de773cb68f]
          perfschema/pfs.cc:1871(pfs_spawn_thread)[0x55de78076274]
          nptl/pthread_create.c:478(start_thread)[0x7f0ec71d0609]
           
          Query (0x62b0000a1420): SELECT  ( ( x , 1 ) , 1 ) IN ( SELECT 'x' , 'x'  WHERE 0 UNION SELECT 1 , x HAVING 0) FROM  ( SELECT 1 x ) x
          

          alice Alice Sherepa added a comment - Thanks! I repeated on 10.4-11.2: SELECT ( ( x , 1 ) , 1 ) IN ( SELECT 'x' , 'x' WHERE 0 UNION SELECT 1 , x HAVING 0) FROM ( SELECT 1 x ) x ; Version: '10.4.32-MariaDB-debug-log' 231009 15:22:32 [ERROR] mysqld got signal 11 ;   Server version: 10.4.32-MariaDB-debug-log source revision: 0c7af6a2a19343cb9d4fedbd7165b8f73bc4cf96   sigaction.c:0(__restore_rt)[0x7f0ec71dc420] sql/sql_bitmap.h:118(Bitmap<64u>::set_bit(unsigned int))[0x55de76e6efa3] sql/table.cc:7984(TABLE::add_tmp_key(unsigned int, unsigned int, unsigned int (*)(unsigned char*), unsigned char*, bool))[0x55de77317475] sql/sql_expression_cache.cc:143(Expression_cache_tmptable::init())[0x55de774e68c2] sql/item.cc:8638(Item_cache_wrapper::init_on_demand())[0x55de77825e89] sql/item.cc:8761(Item_cache_wrapper::check_cache())[0x55de77826cc0] sql/item.cc:8824(Item_cache_wrapper::val_int())[0x55de778277e6] sql/sql_type.cc:7106(Type_handler::Item_send_long(Item*, Protocol*, st_value*) const)[0x55de7755a330] sql/sql_type.h:5192(Type_handler_long::Item_send(Item*, Protocol*, st_value*) const)[0x55de77574a3c] sql/item.h:1045(Item::send(Protocol*, st_value*))[0x55de76d0c5e4] sql/item.cc:8682(Item_cache_wrapper::send(Protocol*, st_value*))[0x55de77826484] sql/protocol.cc:1038(Protocol::send_result_set_row(List<Item>*))[0x55de76cfdf63] sql/sql_class.cc:3138(select_send::send_data(List<Item>&))[0x55de76eb0d83] sql/sql_select.cc:22098(end_send(JOIN*, st_join_table*, bool))[0x55de7712150b] sql/sql_select.cc:20363(do_select(JOIN*, Procedure*))[0x55de77115869] sql/sql_select.cc:4605(JOIN::exec_inner())[0x55de770a3adc] sql/sql_select.cc:4388(JOIN::exec())[0x55de770a110c] sql/sql_select.cc:4828(mysql_select(THD*, TABLE_LIST*, unsigned int, List<Item>&, Item*, unsigned int, st_order*, st_order*, Item*, st_order*, unsigned long long, select_result*, st_select_lex_unit*, st_select_lex*))[0x55de770a52e8] sql/sql_select.cc:442(handle_select(THD*, LEX*, select_result*, unsigned long))[0x55de77075de0] sql/sql_parse.cc:6475(execute_sqlcom_select(THD*, TABLE_LIST*))[0x55de76fe1be4] sql/sql_parse.cc:3978(mysql_execute_command(THD*))[0x55de76fcf35b] sql/sql_parse.cc:8012(mysql_parse(THD*, char*, unsigned int, Parser_state*, bool, bool))[0x55de76feb0bf] sql/sql_parse.cc:1860(dispatch_command(enum_server_command, THD*, char*, unsigned int, bool, bool))[0x55de76fc14e5] sql/sql_parse.cc:1378(do_command(THD*))[0x55de76fbe010] sql/sql_connect.cc:1420(do_handle_one_connection(CONNECT*))[0x55de773cbdeb] sql/sql_connect.cc:1325(handle_one_connection)[0x55de773cb68f] perfschema/pfs.cc:1871(pfs_spawn_thread)[0x55de78076274] nptl/pthread_create.c:478(start_thread)[0x7f0ec71d0609] Query (0x62b0000a1420): SELECT ( ( x , 1 ) , 1 ) IN ( SELECT 'x' , 'x' WHERE 0 UNION SELECT 1 , x HAVING 0) FROM ( SELECT 1 x ) x
          psergei Sergei Petrunia added a comment - - edited

          Execution eventually reaches

            #0  Expression_cache_tmptable::init (this=0x7fff78093b10) at /home/psergey/dev-git2/10.4-fix1/sql/sql_expression_cache.cc:121
          

          The list of items passed to create_tmp_table is:

          (gdb) p dbug_print_item(items.elem(0))
            $125 = 0x5555577d6c80 <dbug_item_print_buf> "<cache>(<in_optimizer>(((1,1.000000),1),<exists>(subquery#5)))"
          (gdb) p dbug_print_item(items.elem(1))
            $126 = 0x5555577d6c80 <dbug_item_print_buf> "(1,1.000000)"
          (gdb) p dbug_print_item(items.elem(2))
            $127 = 0x5555577d6c80 <dbug_item_print_buf> "1"
          (gdb) p dbug_print_item(items.elem(3))
            $128 = 0x5555577d6c80 <dbug_item_print_buf> "1"
          (gdb) p items.elements
            $129 = 4
          

          create_tmp_field() returns NULL for Item_row, the "(1,1.000000)" .

          This means, the temptable is created with 3 fields, not 4.

          Then add_tmp_key() crashes when it tries to add an index on fields with indexes 1,2,and 3. (field with index 0 is subquery's result).

          psergei Sergei Petrunia added a comment - - edited Execution eventually reaches #0 Expression_cache_tmptable::init (this=0x7fff78093b10) at /home/psergey/dev-git2/10.4-fix1/sql/sql_expression_cache.cc:121 The list of items passed to create_tmp_table is: (gdb) p dbug_print_item(items.elem(0)) $125 = 0x5555577d6c80 <dbug_item_print_buf> "<cache>(<in_optimizer>(((1,1.000000),1),<exists>(subquery#5)))" (gdb) p dbug_print_item(items.elem(1)) $126 = 0x5555577d6c80 <dbug_item_print_buf> "(1,1.000000)" (gdb) p dbug_print_item(items.elem(2)) $127 = 0x5555577d6c80 <dbug_item_print_buf> "1" (gdb) p dbug_print_item(items.elem(3)) $128 = 0x5555577d6c80 <dbug_item_print_buf> "1" (gdb) p items.elements $129 = 4 create_tmp_field() returns NULL for Item_row , the "(1,1.000000)" . This means, the temptable is created with 3 fields, not 4. Then add_tmp_key() crashes when it tries to add an index on fields with indexes 1,2,and 3. (field with index 0 is subquery's result).
          psergei Sergei Petrunia added a comment - - edited

          ( ( x , 1.000000 ) , 1 ) 
          IN 
          (SELECT 
             'x' , 'x' 
           WHERE ( ( 'x' ) ) 
           UNION 
           SELECT 1 , x 
           HAVING 1 != 1 
          )
          

          ( x , 1.000000 ) is not a scalar here ... should this have produced an error on name resolution phase?

          psergei Sergei Petrunia added a comment - - edited ( ( x , 1.000000 ) , 1 ) IN ( SELECT 'x' , 'x' WHERE ( ( 'x' ) ) UNION SELECT 1 , x HAVING 1 != 1 ) ( x , 1.000000 ) is not a scalar here ... should this have produced an error on name resolution phase?

          A smaller testcase:

          select
            ( ( 'x' , 1.000000 ) , 1 ) 
          IN 
          (SELECT 
             'x' , 'x' 
           WHERE ( 'x' ) 
           UNION 
           SELECT 1 , 'x' 
           HAVING 1 != 1 
          ) as T;
          

          Doesn't produce an error. It produces:

          +------+
          | T    |
          +------+
          |    0 |
          +------+
          1 row in set, 1 warning (0.000 sec)
          

          MariaDB [test]> show warnings;
          +---------+------+---------------------------------------+
          | Level   | Code | Message                               |
          +---------+------+---------------------------------------+
          | Warning | 1292 | Truncated incorrect DOUBLE value: 'x' |
          +---------+------+---------------------------------------+
          1 row in set (0.000 sec)
          

          psergei Sergei Petrunia added a comment - A smaller testcase: select ( ( 'x' , 1.000000 ) , 1 ) IN ( SELECT 'x' , 'x' WHERE ( 'x' ) UNION SELECT 1 , 'x' HAVING 1 != 1 ) as T; Doesn't produce an error. It produces: +------+ | T | +------+ | 0 | +------+ 1 row in set, 1 warning (0.000 sec) MariaDB [test]> show warnings; +---------+------+---------------------------------------+ | Level | Code | Message | +---------+------+---------------------------------------+ | Warning | 1292 | Truncated incorrect DOUBLE value: 'x' | +---------+------+---------------------------------------+ 1 row in set (0.000 sec)

          If I change the query in any way, e.g.

            WHERE ( 'x' ) 
          

          to WHERE 1, I get the correct result:

          ERROR 1241 (21000): Operand should contain 2 column(s)
          

          psergei Sergei Petrunia added a comment - If I change the query in any way, e.g. WHERE ( 'x' ) to WHERE 1 , I get the correct result: ERROR 1241 (21000): Operand should contain 2 column(s)
          psergei Sergei Petrunia added a comment - - edited

          In the failing query:

          JOIN::choose_tableless_subquery_plan() is called with select_number=2.
          It reaches this point:

                    /*
                      Both group by queries and non-group by queries without aggregate
                      functions produce empty subquery result. There is no need to further
                      rewrite the subquery because it will not be executed at all.
                    */
                    exec_const_cond= 0;
          =>        return FALSE;
          

          It does NOT reach these lines:

                  if (in_subs->create_in_to_exists_cond(this) ||
                      in_subs->inject_in_to_exists_cond(this))
          

          While for the subquery with WHERE 1 is does reach them, and we get here:

                  if (select_lex->ref_pointer_array[i]->
          =>          check_cols(left_expr->element_index(i)->cols()))
          

          in here:

            #0  my_error (nr=1241, MyFlags=0) at /home/psergey/dev-git2/10.4-fix1/mysys/my_error.c:109
            #1  0x00005555560fe14e in Item::check_cols (this=0x7fff74016498, c=2) at /home/psergey/dev-git2/10.4-fix1/sql/item.cc:953
            #2  0x00005555561ca1ac in Item_in_subselect::create_row_in_to_exists_cond (this=0x7fff74017d00, join=0x7fff74019468, where_item=0x7fff74019968, having_item=0x7ff
            #3  0x00005555561cb8ad in Item_in_subselect::create_in_to_exists_cond (this=0x7fff74017d00, join_arg=0x7fff74019468) at /home/psergey/dev-git2/10.4-fix1/sql/item
            #4  0x0000555555f9aa11 in JOIN::choose_tableless_subquery_plan (this=0x7fff74019468) at /home/psergey/dev-git2/10.4-fix1/sql/opt_subselect.cc:6763
          

          psergei Sergei Petrunia added a comment - - edited In the failing query: JOIN::choose_tableless_subquery_plan() is called with select_number=2. It reaches this point: /* Both group by queries and non-group by queries without aggregate functions produce empty subquery result. There is no need to further rewrite the subquery because it will not be executed at all. */ exec_const_cond= 0; => return FALSE; It does NOT reach these lines: if (in_subs->create_in_to_exists_cond(this) || in_subs->inject_in_to_exists_cond(this)) While for the subquery with WHERE 1 is does reach them, and we get here: if (select_lex->ref_pointer_array[i]-> => check_cols(left_expr->element_index(i)->cols())) in here: #0 my_error (nr=1241, MyFlags=0) at /home/psergey/dev-git2/10.4-fix1/mysys/my_error.c:109 #1 0x00005555560fe14e in Item::check_cols (this=0x7fff74016498, c=2) at /home/psergey/dev-git2/10.4-fix1/sql/item.cc:953 #2 0x00005555561ca1ac in Item_in_subselect::create_row_in_to_exists_cond (this=0x7fff74017d00, join=0x7fff74019468, where_item=0x7fff74019968, having_item=0x7ff #3 0x00005555561cb8ad in Item_in_subselect::create_in_to_exists_cond (this=0x7fff74017d00, join_arg=0x7fff74019468) at /home/psergey/dev-git2/10.4-fix1/sql/item #4 0x0000555555f9aa11 in JOIN::choose_tableless_subquery_plan (this=0x7fff74019468) at /home/psergey/dev-git2/10.4-fix1/sql/opt_subselect.cc:6763

          bb-10.4-MDEV-32320. sanja_byelkin, please review.

          psergei Sergei Petrunia added a comment - bb-10.4- MDEV-32320 . sanja_byelkin , please review.

          OK to push

          sanja Oleksandr Byelkin added a comment - OK to push

          People

            psergei Sergei Petrunia
            fuboat Jingzhou Fu
            Votes:
            0 Vote for this issue
            Watchers:
            6 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.