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

Server crashes in Explain_union::print_explain with explain in slow log, tis620 charset

Details

    Description

      #2  0x0000000000864189 in handle_fatal_signal (sig=11) at 10.0/sql/signal_handler.cc:262
      #3  <signal handler called>
      #4  0x00000000007c4f24 in Explain_union::print_explain (this=0x7fee28b77b68, query=0x7fee28b77aa8, output=0x7fee325b4d10, explain_flags=0 '\000') at 10.0/sql/sql_explain.cc:228
      #5  0x00000000007c53cc in Explain_node::print_explain_for_children (this=0x7fee28b78ff0, query=0x7fee28b77aa8, output=0x7fee325b4d10, explain_flags=0 '\000') at 10.0/sql/sql_explain.cc:327
      #6  0x00000000007c57a7 in Explain_select::print_explain (this=0x7fee28b78ff0, query=0x7fee28b77aa8, output=0x7fee325b4d10, explain_flags=0 '\000') at 10.0/sql/sql_explain.cc:390
      #7  0x00000000007c4c9c in Explain_query::print_explain (this=0x7fee28b77aa8, output=0x7fee325b4d10, explain_flags=0 '\000') at 10.0/sql/sql_explain.cc:175
      #8  0x00000000007c4d63 in Explain_query::print_explain_str (this=0x7fee28b77aa8, thd=0x7fee2b32f070, out_str=0x7fee325b4e70) at 10.0/sql/sql_explain.cc:197
      #9  0x00000000007c4cd0 in print_explain_query (lex=0x7fee2b332cc0, thd=0x7fee2b32f070, str=0x7fee325b4e70) at 10.0/sql/sql_explain.cc:182
      #10 0x000000000093552b in MYSQL_QUERY_LOG::write (this=0x7fee2c3d6150, thd=0x7fee2b32f070, current_time=1405123297, user_host=0x7fee325b52a0 "root[root] @ localhost []", user_host_len=25, query_utime=1563, lock_utime=733, is_command=false, sql_text=0x7fee28819088 "SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo' UNION SELECT 'bar' )", sql_text_len=67) at 10.0/sql/log.cc:2926
      #11 0x000000000093088b in Log_to_file_event_handler::log_slow (this=0x7fee2c3d5c00, thd=0x7fee2b32f070, current_time=..., user_host=0x7fee325b52a0 "root[root] @ localhost []", user_host_len=25, query_utime=1563, lock_utime=733, is_command=false, sql_text=0x7fee28819088 "SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo' UNION SELECT 'bar' )", sql_text_len=67) at 10.0/sql/log.cc:1018
      #12 0x000000000093129e in LOGGER::slow_log_print (this=0x18a1600, thd=0x7fee2b32f070, query=0x7fee28819088 "SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo' UNION SELECT 'bar' )", query_length=67, current_utime=52081142100) at 10.0/sql/log.cc:1309
      #13 0x000000000093d254 in slow_log_print (thd=0x7fee2b32f070, query=0x7fee28819088 "SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo' UNION SELECT 'bar' )", query_length=67, current_utime=52081142100) at 10.0/sql/log.cc:6020
      #14 0x000000000067708c in log_slow_statement (thd=0x7fee2b32f070) at 10.0/sql/sql_parse.cc:1823
      #15 0x0000000000676d62 in dispatch_command (command=COM_QUERY, thd=0x7fee2b32f070, packet=0x7fee2c3f6071 "", packet_length=67) at 10.0/sql/sql_parse.cc:1743
      #16 0x0000000000674be2 in do_command (thd=0x7fee2b32f070) at 10.0/sql/sql_parse.cc:1006
      #17 0x0000000000790ab5 in do_handle_one_connection (thd_arg=0x7fee2b32f070) at 10.0/sql/sql_connect.cc:1379
      #18 0x0000000000790808 in handle_one_connection (arg=0x7fee2b32f070) at 10.0/sql/sql_connect.cc:1293
      #19 0x0000000000cc22f6 in pfs_spawn_thread (arg=0x7fee2a6a0970) at 10.0/storage/perfschema/pfs.cc:1860
      #20 0x00007fee321a0b50 in start_thread (arg=<optimized out>) at pthread_create.c:304
      #21 0x00007fee30698a7d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112

      Stack trace from:

      revision-id: knielsen@knielsen-hq.org-20140711100647-nf3rdaf5ep26pgty
      revno: 4290
      branch-nick: 10.0

      Test case:

      SET NAMES tis620;
      SET GLOBAL slow_query_log = 1;
      SET long_query_time = 0.000001;
      SET log_slow_verbosity = 'explain';
       
      CREATE TABLE t1 (a VARCHAR(3)) ENGINE=MyISAM;
      SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo' UNION SELECT 'bar' );

      Attachments

        Issue Links

          Activity

            Discussed the issue with bar. It is ok if we produce an error like in the testcase for the query.

            psergei Sergei Petrunia added a comment - Discussed the issue with bar . It is ok if we produce an error like in the testcase for the query.

            Again, the failure scenario:

            SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo' UNION SELECT 'bar' );

            • Query optimization starts
            • We enter JOIN::optimize() for the "SELECT 'foo'" (select_number=2)
            • JOIN::optimize discovers this is a degenerate select and sets tables_list=NULL.
            • Then it calls JOIN::transform_max_min_subquery
              • the subquery is a UNION, so MIN/MAX rewrite is not applicable
              • instead, the subquery is converted into Item_maxmin_subselect
              • the rewrite constructs a comparison, 'a < ALL (SELECT ...)'
              • Then it calls fix_fields() for the comparison
                • which sees that one part of the comparison is a constant and inexpensive,
                  and tries to compute it.

            TADA, we are trying to execute a JOIN that we are currently optimizing.

            JOIN::exec() will be able to finish just fine in this example.

            The problem is that we still have JOIN::have_query_plan==QEP_NOT_PRESENT_YET. and since the SELECT is not correlated, we will call JOIN::cleanup(full=true), which will destroy the query plan before we had a chance to save its EXPLAIN (this is done in two places: at the end of JOIN::optimize and the end of JOIN::exec() . When we reach either of them, we will already have JOIN::have_query_plan==QEP_DELETED).

            Trying to execute a JOIN while we are still inside JOIN::optimize() for that join is not expected and can potentially cause all kinds of harm, so it's
            better to disable it.

            Note that the second part of the UNION is not yet optimized when we are at point.
            So if we make Item_subselect::is_expensive() return TRUE for this case,we will prevent the problematic scenario from happening.

            (One may ask won't we get into the same problem after we have optimized the second part of the UNION? No, we would not, because the subquery rewrite only happens when we are optimizing the first part of the UNION. Which is not a good place to do it but that's where it is done)

            So, the fix is ugly but it works.

            We would be better off if this rewrite wasn't so convoluted but fixing that is outside of scope of this bugfix and would be a too big change for 10.0.

            psergei Sergei Petrunia added a comment - Again, the failure scenario: SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo' UNION SELECT 'bar' ); Query optimization starts We enter JOIN::optimize() for the "SELECT 'foo'" (select_number=2) JOIN::optimize discovers this is a degenerate select and sets tables_list=NULL. Then it calls JOIN::transform_max_min_subquery the subquery is a UNION, so MIN/MAX rewrite is not applicable instead, the subquery is converted into Item_maxmin_subselect the rewrite constructs a comparison, 'a < ALL (SELECT ...)' Then it calls fix_fields() for the comparison which sees that one part of the comparison is a constant and inexpensive, and tries to compute it. TADA, we are trying to execute a JOIN that we are currently optimizing. JOIN::exec() will be able to finish just fine in this example. The problem is that we still have JOIN::have_query_plan==QEP_NOT_PRESENT_YET . and since the SELECT is not correlated, we will call JOIN::cleanup(full=true), which will destroy the query plan before we had a chance to save its EXPLAIN (this is done in two places: at the end of JOIN::optimize and the end of JOIN::exec() . When we reach either of them, we will already have JOIN::have_query_plan==QEP_DELETED ). Trying to execute a JOIN while we are still inside JOIN::optimize() for that join is not expected and can potentially cause all kinds of harm, so it's better to disable it. Note that the second part of the UNION is not yet optimized when we are at point . So if we make Item_subselect::is_expensive() return TRUE for this case,we will prevent the problematic scenario from happening. (One may ask won't we get into the same problem after we have optimized the second part of the UNION? No, we would not, because the subquery rewrite only happens when we are optimizing the first part of the UNION. Which is not a good place to do it but that's where it is done) So, the fix is ugly but it works. We would be better off if this rewrite wasn't so convoluted but fixing that is outside of scope of this bugfix and would be a too big change for 10.0.

            sanja, please review

            psergei Sergei Petrunia added a comment - sanja , please review

            Somehow, the patch wasn't sent to the commits@. Now, sent it: http://lists.askmonty.org/pipermail/commits/2018-August/012797.html

            psergei Sergei Petrunia added a comment - Somehow, the patch wasn't sent to the commits@. Now, sent it: http://lists.askmonty.org/pipermail/commits/2018-August/012797.html

            OK to push after removing spaces at the end of line.

            sanja Oleksandr Byelkin added a comment - OK to push after removing spaces at the end of line.

            People

              psergei Sergei Petrunia
              elenst Elena Stepanova
              Votes:
              2 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.