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

Pushdown: server crashes at check_simple_equality()

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)
    • 10.5.26, 10.6.19, 10.11.9, 11.1.6, 11.2.5, 11.4.3
    • Optimizer
    • None
    • Ubuntu 20.04 x86-64, docker image mariadb:11.1.2

    Description

      PoC:

      SELECT * FROM ( SELECT -128 x ) ss GROUP BY x HAVING x = 'x' AND x = ( ( ( x ) IS NULL ) ) ;
      

      docker log:

      mariadbd(my_print_stacktrace+0x32)[0x5645fde287c2]
      mariadbd(handle_fatal_signal+0x488)[0x5645fd901cf8]
      /lib/x86_64-linux-gnu/libc.so.6(+0x42520)[0x7fb7d73c3520]
      mariadbd(_Z21check_simple_equalityP3THDRKN12Value_source7ContextEP4ItemS6_P10COND_EQUAL+0x282)[0x5645fd6ddfc2]
      mariadbd(_Z36and_new_conditions_to_optimized_condP3THDP4ItemPP10COND_EQUALR4ListIS1_EPNS1_11cond_resultE+0x188)[0x5645fd808328]
      mariadbd(_ZN4JOIN14optimize_innerEv+0x152b)[0x5645fd70e9eb]
      mariadbd(_ZN4JOIN8optimizeEv+0xda)[0x5645fd70ee2a]
      mariadbd(_Z12mysql_selectP3THDP10TABLE_LISTR4ListI4ItemEPS4_jP8st_orderS9_S7_S9_yP13select_resultP18st_select_lex_unitP13st_select_lex+0xd1)[0x5645fd70ef21]
      mariadbd(_Z13handle_selectP3THDP3LEXP13select_resulty+0x154)[0x5645fd70f774]
      mariadbd(+0x826f55)[0x5645fd682f55]
      mariadbd(_Z21mysql_execute_commandP3THDb+0x419e)[0x5645fd691f0e]
      mariadbd(_Z11mysql_parseP3THDPcjP12Parser_state+0x1e7)[0x5645fd693237]
      mariadbd(_Z16dispatch_command19enum_server_commandP3THDPcjb+0x14bd)[0x5645fd695a1d]
      mariadbd(_Z10do_commandP3THDb+0x138)[0x5645fd697818]
      mariadbd(_Z24do_handle_one_connectionP7CONNECTb+0x3bf)[0x5645fd7bf3af]
      mariadbd(handle_one_connection+0x5d)[0x5645fd7bf6fd]
      mariadbd(+0xcd1906)[0x5645fdb2d906]
      /lib/x86_64-linux-gnu/libc.so.6(+0x94b43)[0x7fb7d7415b43]
      /lib/x86_64-linux-gnu/libc.so.6(clone+0x44)[0x7fb7d74a6bb4]
       
      Trying to get some variables.
      Some pointers may be invalid and cause the dump to abort.
      Query (0x7fb7840130d8): SELECT * FROM ( SELECT -128 x ) ss GROUP BY x HAVING x = 'x' AND x = ( ( ( x ) IS NULL ) )
       
      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

            alice Alice Sherepa added a comment -

            Thank you for the report!
            I repeated on 10.4-11.2:

            Version: '10.4.32-MariaDB-debug-log'  
            231009 17:58:37 [ERROR] mysqld got signal 11 ;
             
            Server version: 10.4.32-MariaDB-debug-log source revision: 0c7af6a2a19343cb9d4fedbd7165b8f73bc4cf96
             
            sql/signal_handler.cc:238(handle_fatal_signal)[0x55c834b6ff8d]
            sigaction.c:0(__restore_rt)[0x7f03cf269420]
            sql/sql_select.cc:15122(check_simple_equality(THD*, Value_source::Context const&, Item*, Item*, COND_EQUAL*))[0x55c8344d3f37]
            sql/opt_subselect.cc:5872(and_new_conditions_to_optimized_cond(THD*, Item*, COND_EQUAL**, List<Item>&, Item::cond_result*))[0x55c8348b58dc]
            sql/sql_select.cc:2143(JOIN::optimize_inner())[0x55c83446ddec]
            sql/sql_select.cc:1711(JOIN::optimize())[0x55c83446910d]
            sql/sql_select.cc:4812(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*))[0x55c83448a0f7]
            sql/sql_select.cc:442(handle_select(THD*, LEX*, select_result*, unsigned long))[0x55c83445ade0]
            sql/sql_parse.cc:6475(execute_sqlcom_select(THD*, TABLE_LIST*))[0x55c8343c6be4]
            sql/sql_parse.cc:3978(mysql_execute_command(THD*))[0x55c8343b435b]
            sql/sql_parse.cc:8012(mysql_parse(THD*, char*, unsigned int, Parser_state*, bool, bool))[0x55c8343d00bf]
            sql/sql_parse.cc:1860(dispatch_command(enum_server_command, THD*, char*, unsigned int, bool, bool))[0x55c8343a64e5]
            sql/sql_parse.cc:1378(do_command(THD*))[0x55c8343a3010]
            sql/sql_connect.cc:1420(do_handle_one_connection(CONNECT*))[0x55c8347b0deb]
            sql/sql_connect.cc:1325(handle_one_connection)[0x55c8347b068f]
            perfschema/pfs.cc:1871(pfs_spawn_thread)[0x55c83545b274]
            nptl/pthread_create.c:478(start_thread)[0x7f03cf25d609]
             
            Query (0x62b0000a1420): SELECT * FROM ( SELECT 1 x ) ss GROUP BY x HAVING x = 'x' AND x = ( x IS NULL )
            
            

            alice Alice Sherepa added a comment - Thank you for the report! I repeated on 10.4-11.2: Version: '10.4.32-MariaDB-debug-log' 231009 17:58:37 [ERROR] mysqld got signal 11 ;   Server version: 10.4.32-MariaDB-debug-log source revision: 0c7af6a2a19343cb9d4fedbd7165b8f73bc4cf96   sql/signal_handler.cc:238(handle_fatal_signal)[0x55c834b6ff8d] sigaction.c:0(__restore_rt)[0x7f03cf269420] sql/sql_select.cc:15122(check_simple_equality(THD*, Value_source::Context const&, Item*, Item*, COND_EQUAL*))[0x55c8344d3f37] sql/opt_subselect.cc:5872(and_new_conditions_to_optimized_cond(THD*, Item*, COND_EQUAL**, List<Item>&, Item::cond_result*))[0x55c8348b58dc] sql/sql_select.cc:2143(JOIN::optimize_inner())[0x55c83446ddec] sql/sql_select.cc:1711(JOIN::optimize())[0x55c83446910d] sql/sql_select.cc:4812(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*))[0x55c83448a0f7] sql/sql_select.cc:442(handle_select(THD*, LEX*, select_result*, unsigned long))[0x55c83445ade0] sql/sql_parse.cc:6475(execute_sqlcom_select(THD*, TABLE_LIST*))[0x55c8343c6be4] sql/sql_parse.cc:3978(mysql_execute_command(THD*))[0x55c8343b435b] sql/sql_parse.cc:8012(mysql_parse(THD*, char*, unsigned int, Parser_state*, bool, bool))[0x55c8343d00bf] sql/sql_parse.cc:1860(dispatch_command(enum_server_command, THD*, char*, unsigned int, bool, bool))[0x55c8343a64e5] sql/sql_parse.cc:1378(do_command(THD*))[0x55c8343a3010] sql/sql_connect.cc:1420(do_handle_one_connection(CONNECT*))[0x55c8347b0deb] sql/sql_connect.cc:1325(handle_one_connection)[0x55c8347b068f] perfschema/pfs.cc:1871(pfs_spawn_thread)[0x55c83545b274] nptl/pthread_create.c:478(start_thread)[0x7f03cf25d609] Query (0x62b0000a1420): SELECT * FROM ( SELECT 1 x ) ss GROUP BY x HAVING x = 'x' AND x = ( x IS NULL )

            The testcase can be shortened to:

            CREATE VIEW v1 AS SELECT 1 a;
            SELECT * FROM v1 GROUP BY a HAVING a = 'b' AND a = (a IS NULL);
            

            With switched off pushdown from HAVING into WHERE optimization the query doesn't crash:

            MariaDB [test]> set statement optimizer_switch='condition_pushdown_from_having=off' for
                -> SELECT * FROM v1 GROUP BY a HAVING a = 'b' AND a = (a IS NULL);
            Empty set (0,002 sec)
            

            The condition that will be pushed into WHERE is looking this way:

            v1.a = 'b' and v1.a = (/*always not null*/ 1 is null)
            

            where /*always not null*/ is v1.a.

            In debugger it can be seen that v1.a from (v1.a = 'b') equality and /*always not null*/ are references to the same object.

            During the optimization (/*always not null*/ 1 is null) is considered as a constant object and is marked with IMMUTABLE_FL. It will prevent this expression from being fixed and cleaned up on the last stage of the optimization.
            When the cleanup process is entered, v1.a from (v1.a = 'b') has IMMUTABLE_FL as it is a reference
            to the same object as /*always not null*/. It is not cleaned up or fixed, and IMMUTABLE_FL is removed from this object. Later, when /*always not null*/ is processed, it already doesn't have IMMUTABLE_FL, so it is cleaned up.
            Later, when fix fields is made and (/*always not null*/ 1 is null) is processed, no fixing is made on this expression as it has IMMUTABLE_FL. However, /*always not null*/ that was cleaned up on the previous step remains unfixed. That causes a crash.

            This bug is similar to MDEV-32304 and will be fixed with MDEV-29363 fix.

            shagalla Galina Shalygina (Inactive) added a comment - The testcase can be shortened to: CREATE VIEW v1 AS SELECT 1 a; SELECT * FROM v1 GROUP BY a HAVING a = 'b' AND a = (a IS NULL ); With switched off pushdown from HAVING into WHERE optimization the query doesn't crash: MariaDB [test]> set statement optimizer_switch= 'condition_pushdown_from_having=off' for -> SELECT * FROM v1 GROUP BY a HAVING a = 'b' AND a = (a IS NULL ); Empty set (0,002 sec) The condition that will be pushed into WHERE is looking this way: v1.a = 'b' and v1.a = (/*always not null*/ 1 is null) where /*always not null*/ is v1.a . In debugger it can be seen that v1.a from (v1.a = 'b') equality and /*always not null*/ are references to the same object. During the optimization (/*always not null*/ 1 is null) is considered as a constant object and is marked with IMMUTABLE_FL. It will prevent this expression from being fixed and cleaned up on the last stage of the optimization. When the cleanup process is entered, v1.a from (v1.a = 'b') has IMMUTABLE_FL as it is a reference to the same object as /*always not null*/ . It is not cleaned up or fixed, and IMMUTABLE_FL is removed from this object. Later, when /*always not null*/ is processed, it already doesn't have IMMUTABLE_FL , so it is cleaned up. Later, when fix fields is made and (/*always not null*/ 1 is null) is processed, no fixing is made on this expression as it has IMMUTABLE_FL . However, /*always not null*/ that was cleaned up on the previous step remains unfixed. That causes a crash. This bug is similar to MDEV-32304 and will be fixed with MDEV-29363 fix.

            Fixed in 10.5. Pushed with MDEV-29363 commit.
            The testcase for this MDEV is included in the patch (find it here).

            The initial query doesn't crash anymore:

            MariaDB [t]> SELECT * FROM ( SELECT -128 x ) ss GROUP BY x HAVING x = 'x' AND x = ( ( ( x ) IS NULL ) ) ;
            Empty set, 1 warning (0,001 sec)
            

            shagalla Galina Shalygina (Inactive) added a comment - - edited Fixed in 10.5. Pushed with MDEV-29363 commit . The testcase for this MDEV is included in the patch (find it here ). The initial query doesn't crash anymore: MariaDB [t]> SELECT * FROM ( SELECT -128 x ) ss GROUP BY x HAVING x = 'x' AND x = ( ( ( x ) IS NULL ) ) ; Empty set , 1 warning (0,001 sec)

            People

              shagalla Galina Shalygina (Inactive)
              fuboat Jingzhou Fu
              Votes:
              0 Vote for this issue
              Watchers:
              5 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.