Details
-
Type:
Task
-
Status: Closed
-
Priority:
Major
-
Resolution: Fixed
-
Fix Version/s: N/A
-
Component/s: None
-
Labels:None
Description
Gliffy Diagrams
Attachments
Issue Links
- relates to
-
MDEV-334 [backport] Implement UNION ALL without usage of a temporary table (MWL#44)
-
- Closed
-
Activity
- All
- Comments
- Work Log
- History
- Activity
- Transitions
Comparing with MySQL-5.7:
When we're here in MySQL:
(gdb) wher #0 select_result::prepare (this=0x7fffa80119e8, list=..., u=0x7fffa800fdd8) at /home/psergey/dev2/mysql-server/sql/sql_class.h:3925 #1 0x000000000096c723 in select_union_direct::postponed_prepare (this=0x7fffa8023b18, types=...) at /home/psergey/dev2/mysql-server/sql/sql_union.cc:329 #2 0x000000000096d585 in st_select_lex_unit::prepare (this=0x7fffa800fdd8, thd_arg=0x7fffa8000c50, sel_result=0x7fffa80119e8, additional_options=268435460) at /home/psergey/dev2/mysql-server/sql/sql_union.cc:626 #3 0x000000000096be18 in mysql_union_prepare_and_optimize (thd=0x7fffa8000c50, lex=0x7fffa8003038, result=0x7fffa80119e8, unit=0x7fffa800fdd8, union_options=4) at /home/psergey/dev2/mysql-server/sql/sql_union.cc:92 #4 0x0000000000a38231 in explain_query (ethd=0x7fffa8000c50, unit=0x7fffa800fdd8, result=0x7fffa80119e8) at /home/psergey/dev2/mysql-server/sql/opt_explain.cc:2142 #5 0x00000000008d3783 in execute_sqlcom_select (thd=0x7fffa8000c50, all_tables=0x7fffa8010748) at /home/psergey/dev2/mysql-server/sql/sql_parse.cc:4835 #6 0x00000000008cc600 in mysql_execute_command (thd=0x7fffa8000c50) at /home/psergey/dev2/mysql-server/sql/sql_parse.cc:2421 #7 0x00000000008d4632 in mysql_parse (thd=0x7fffa8000c50, parser_state=0x7fffec59b110) at /home/psergey/dev2/mysql-server/sql/sql_parse.cc:5242 #8 0x00000000008c991e in dispatch_command (command=COM_QUERY, thd=0x7fffa8000c50, packet=0x7fffa8006941 "", packet_length=51) at /home/psergey/dev2/mysql-server/sql/sql_parse.cc:1247 #9 0x00000000008c86f4 in do_command (thd=0x7fffa8000c50) at /home/psergey/dev2/mysql-server/sql/sql_parse.cc:834 #10 0x00000000009d3a68 in handle_connection (arg=0x2671130) at /home/psergey/dev2/mysql-server/sql/conn_handler/connection_handler_per_thread.cc:288 #11 0x0000000000b65811 in pfs_spawn_thread (arg=0x25fbed0) at /home/psergey/dev2/mysql-server/storage/perfschema/pfs.cc:2072 #12 0x00007ffff737de9a in start_thread (arg=0x7fffec59c700) at pthread_create.c:308 #13 0x00007ffff68983fd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112 #14 0x0000000000000000 in ?? ()
And here in MariaDB:
(gdb) wher #0 select_result::prepare (this=0x7ffebc448768, list=..., u=0xa5a5a5a5a5a5a5a5) at /home/psergey/dev2/10.1-union-all-look/sql/sql_class.h:3851 #1 0x000000000071fce7 in select_union_direct::postponed_prepare (this=0x7ffebc448e28, types=...) at /home/psergey/dev2/10.1-union-all-look/sql/sql_union.cc:210 #2 0x0000000000720cd8 in st_select_lex_unit::prepare (this=0x7ffeb9e65d78, thd_arg=0x7ffeb9e62070, sel_result=0x7ffebc448768, additional_options=268435460) at /home/psergey/dev2/10.1-union-all-look/sql/sql_union.cc:510 #3 0x00000000006c7f91 in mysql_explain_union (thd=0x7ffeb9e62070, unit=0x7ffeb9e65d78, result=0x7ffebc448768) at /home/psergey/dev2/10.1-union-all-look/sql/sql_select.cc:23776 #4 0x000000000065f37e in execute_sqlcom_select (thd=0x7ffeb9e62070, all_tables=0x7ffebc4472b0) at /home/psergey/dev2/10.1-union-all-look/sql/sql_parse.cc:5227 #5 0x0000000000657600 in mysql_execute_command (thd=0x7ffeb9e62070) at /home/psergey/dev2/10.1-union-all-look/sql/sql_parse.cc:2554 #6 0x0000000000661df6 in mysql_parse (thd=0x7ffeb9e62070, rawbuf=0x7ffebc447088 "explain select * from t1 union all select * from t2", length=51, parser_state=0x7ffeb2fa64b0) at /home/psergey/dev2/10.1-union-all-look/sql/sql_parse.cc:6409 #7 0x00000000006547b8 in dispatch_command (command=COM_QUERY, thd=0x7ffeb9e62070, packet=0x7ffebef02071 "", packet_length=51) at /home/psergey/dev2/10.1-union-all-look/sql/sql_parse.cc:1309 #8 0x0000000000653b06 in do_command (thd=0x7ffeb9e62070) at /home/psergey/dev2/10.1-union-all-look/sql/sql_parse.cc:1006 #9 0x000000000077779a in do_handle_one_connection (thd_arg=0x7ffeb9e62070) at /home/psergey/dev2/10.1-union-all-look/sql/sql_connect.cc:1379 #10 0x00000000007774ed in handle_one_connection (arg=0x7ffeb9e62070) at /home/psergey/dev2/10.1-union-all-look/sql/sql_connect.cc:1293 #11 0x0000000000aebfdf in pfs_spawn_thread (arg=0x7ffeb9f1f350) at /home/psergey/dev2/10.1-union-all-look/storage/perfschema/pfs.cc:1853 #12 0x00007ffff7166e9a in start_thread (arg=0x7ffeb2fa7700) at pthread_create.c:308 #13 0x00007ffff66813fd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112 #14 0x0000000000000000 in ?? () (gdb)
note that 'u' parameter is valid in MySQL and not valid in MariaDB.
In other words, need to check where select_union_direct is set in MySQL.
Debugging mysql-5.7. select_union_direct::unit is NULL after ctor; it is set to a non-NULL value here:
#0 select_union::prepare (this=0x7fffa8023b18, list=..., u=0x7fffa800fdd8) at /home/psergey/dev2/mysql-server/sql/sql_union.cc:187 #1 0x000000000090ea67 in st_select_lex::prepare (this=0x7fffa800fb10, join=0x7fffa8023c08) at /home/psergey/dev2/mysql-server/sql/sql_resolver.cc:362 #2 0x000000000096d28e in st_select_lex_unit::prepare (this=0x7fffa800fdd8, thd_arg=0x7fffa8000c50, sel_result=0x7fffa80119e8, additional_options=268435460) at /home/psergey/dev2/mysql-server/sql/sql_union.cc:578 #3 0x000000000096be18 in mysql_union_prepare_and_optimize (thd=0x7fffa8000c50, lex=0x7fffa8003038, result=0x7fffa80119e8, unit=0x7fffa800fdd8, union_options=4) at /home/psergey/dev2/mysql-server/sql/sql_union.cc:92 #4 0x0000000000a38231 in explain_query (ethd=0x7fffa8000c50, unit=0x7fffa800fdd8, result=0x7fffa80119e8) at /home/psergey/dev2/mysql-server/sql/opt_explain.cc:2142 #5 0x00000000008d3783 in execute_sqlcom_select (thd=0x7fffa8000c50, all_tables=0x7fffa8010748) at /home/psergey/dev2/mysql-server/sql/sql_parse.cc:4835 #6 0x00000000008cc600 in mysql_execute_command (thd=0x7fffa8000c50) at /home/psergey/dev2/mysql-server/sql/sql_parse.cc:2421 #7 0x00000000008d4632 in mysql_parse (thd=0x7fffa8000c50, parser_state=0x7fffec59b110) at /home/psergey/dev2/mysql-server/sql/sql_parse.cc:5242 #8 0x00000000008c991e in dispatch_command (command=COM_QUERY, thd=0x7fffa8000c50, packet=0x7fffa8006941 "", packet_length=51) at /home/psergey/dev2/mysql-server/sql/sql_parse.cc:1247 #9 0x00000000008c86f4 in do_command (thd=0x7fffa8000c50) at /home/psergey/dev2/mysql-server/sql/sql_parse.cc:834 #10 0x00000000009d3a68 in handle_connection (arg=0x2671130) at /home/psergey/dev2/mysql-server/sql/conn_handler/connection_handler_per_thread.cc:288 #11 0x0000000000b65811 in pfs_spawn_thread (arg=0x25fbed0) at /home/psergey/dev2/mysql-server/storage/perfschema/pfs.cc:2072 #12 0x00007ffff737de9a in start_thread (arg=0x7fffec59c700) at pthread_create.c:308 #13 0x00007ffff68983fd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112 #14 0x0000000000000000 in ?? ()
The code at #1 is:
if (join->result && join->result->prepare(join->fields_list, unit))
DBUG_RETURN(-1); /* purecov: inspected */
st_select_lex::prepare is 5.7's analog of JOIN::prepare.
(gdb) p join->select_lex->select_number $80 = 1 (gdb) p join->result $82 = (select_union_direct *) 0x7fffa8023b18
That is, the first join has select_union_direct as it's JOIN::result.
MariaDB has similar code in JOIN::prepare:
if (!procedure && result && result->prepare(fields_list, unit_arg))
goto err; /* purecov: inspected */
However, when we reach it, join->result points to select_send:
(gdb) p select_lex->select_number $171 = 1 (gdb) p result $172 = (select_send *) 0x7ffebb900768
stack trace:
(gdb) wher #0 JOIN::prepare (this=0x7ffebb9d1088, rref_pointer_array=0x7ffeb9e666d8, tables_init=0x7ffebb8ff2b0, wild_num=1, conds_init=0x0, og_num=0, order_init=0x0, skip_order_by=true, group_init=0x0, having_init=0x0, proc_param_init=0x0, select_lex_arg=0x7ffeb9e66460, unit_arg=0x7ffeb9e65d78) at /home/psergey/dev2/10.1-union-all-look/sql/sql_select.cc:957 #1 0x00000000007209b0 in st_select_lex_unit::prepare (this=0x7ffeb9e65d78, thd_arg=0x7ffeb9e62070, sel_result=0x7ffebb900768, additional_options=268435460) at /home/psergey/dev2/10.1-union-all-look/sql/sql_union.cc:460 #2 0x00000000006c7f91 in mysql_explain_union (thd=0x7ffeb9e62070, unit=0x7ffeb9e65d78, result=0x7ffebb900768) at /home/psergey/dev2/10.1-union-all-look/sql/sql_select.cc:23776 #3 0x000000000065f37e in execute_sqlcom_select (thd=0x7ffeb9e62070, all_tables=0x7ffebb8ff2b0) at /home/psergey/dev2/10.1-union-all-look/sql/sql_parse.cc:5227 #4 0x0000000000657600 in mysql_execute_command (thd=0x7ffeb9e62070) at /home/psergey/dev2/10.1-union-all-look/sql/sql_parse.cc:2554 #5 0x0000000000661df6 in mysql_parse (thd=0x7ffeb9e62070, rawbuf=0x7ffebb8ff088 "explain select * from t1 union all select * from t2", length=51, parser_state=0x7ffeb2fa64b0) at /home/psergey/dev2/10.1-union-all-look/sql/sql_parse.cc:6409 #6 0x00000000006547b8 in dispatch_command (command=COM_QUERY, thd=0x7ffeb9e62070, packet=0x7ffebef02071 "", packet_length=51) at /home/psergey/dev2/10.1-union-all-look/sql/sql_parse.cc:1309
We set the 'unit' in select_send object, but never set it in the select_union_direct object.
I am looking at the code in st_select_lex_unit::prepare(), in both 10.1 and 5.7. I see that JOIN::JOIN() constructor is called with a select_union_direct object in 5.7, but not in 10.1
The reason it's called with select_send in 10.1 is this piece
if (describe)
tmp_result= sel_result;
which bzr history shows is a very old code.
It's no longer necessary to run JOIN::optimize() with output set to select_send.
If I remove that code, the crash goes away.
The fix
diff '--exclude=.*' -urp 10.1-union-all-look2/sql/sql_union.cc 10.1-union-all-look/sql/sql_union.cc
--- 10.1-union-all-look2/sql/sql_union.cc 2014-08-25 16:09:36.424369391 +0400
+++ 10.1-union-all-look/sql/sql_union.cc 2014-08-25 16:06:56.820363242 +0400
@@ -402,8 +402,6 @@ bool st_select_lex_unit::prepare(THD *th
goto err; /* purecov: inspected */
instantiate_tmp_table= true;
}
- if (describe)
- tmp_result= sel_result;
}
else
tmp_result= sel_result;
Fix was provided to Igor Babaev
Investigation results:
EXPLAIN seems to be saved correclty. Explain_union data structure is actually
created, which would allow to print out the EXPLAIN output (provided that
Explain_union has a flag which says whether it's using the tem. table).
The problems start here:
The reason for this is:
select_union_direct::unit was never set.
Conceptually, it does not have a UNIT? OTOH, looking at the above stack trace: we are in
select_lex_unit::prepare(), which means there is a select_lex_unit