Details
-
Task
-
Status: Closed (View Workflow)
-
Major
-
Resolution: Fixed
-
None
-
None
Description
Attachments
Issue Links
- relates to
-
MDEV-334 [backport] Implement UNION ALL without usage of a temporary table (MWL#44)
-
- Closed
-
Activity
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;
|
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:
#0 select_result::prepare (this=0x7ffebc848768, 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=0x7ffebc848e28, 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=0x7ffebc848768, 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=0x7ffebc848768) at /home/psergey/dev2/10.1-union-all-look/sql/sql_select.cc:23776
#4 0x000000000065f37e in execute_sqlcom_select (thd=0x7ffeb9e62070, all_tables=0x7ffebc8472b0) 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=0x7ffebc847088 "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
The reason for this is:
(gdb) p this
$51 = (select_union_direct *) 0x7ffebc848e28
(gdb) p this->unit
$53 = (SELECT_LEX_UNIT *) 0xa5a5a5a5a5a5a5a5
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