[MDEV-5368] Server crashes in Item_in_subselect::optimize on 2nd execution of PS with IN subqueries, materialization+semijoin Created: 2013-12-01  Updated: 2014-01-29  Resolved: 2014-01-23

Status: Closed
Project: MariaDB Server
Component/s: None
Affects Version/s: 5.3.12, 5.5.34, 10.0.6
Fix Version/s: 5.5.35, 10.0.8, 5.3.13

Type: Bug Priority: Major
Reporter: Elena Stepanova Assignee: Sergei Petrunia
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates

 Description   

#3  <signal handler called>
#4  0x00000000006349f3 in Item_in_subselect::optimize (this=0x2a83fe8, out_rows=0x7f6cd018e930, cost=0x7f6cd018e928) at item_subselect.cc:616
#5  0x000000000081916e in setup_jtbm_semi_joins (join=0x2a4cc60, join_list=0x2a81150, join_where=0x2a4d048) at opt_subselect.cc:5109
#6  0x000000000072826b in JOIN::optimize (this=0x2a4cc60) at sql_select.cc:1024
#7  0x000000000072f4b7 in mysql_select (thd=0x29c8bc8, rref_pointer_array=0x2a81238, tables=0x2a81d80, wild_num=0, fields=..., conds=0x2a4ca50, og_num=0, order=0x0, group=0x0, having=0x0, proc_param=0x0, select_options=2416200192, result=0x2a843b8, unit=0x2a80ad8, select_lex=0x2a80fe0) at sql_select.cc:2995
#8  0x0000000000725fad in handle_select (thd=0x29c8bc8, lex=0x2a80a38, result=0x2a843b8, setup_tables_done_option=0) at sql_select.cc:288
#9  0x00000000006b4ca8 in execute_sqlcom_select (thd=0x29c8bc8, all_tables=0x2a81d80) at sql_parse.cc:5172
#10 0x00000000006abe44 in mysql_execute_command (thd=0x29c8bc8) at sql_parse.cc:2305
#11 0x0000000000786fee in Prepared_statement::execute (this=0x2a80668, expanded_query=0x7f6cd018fcb0, open_cursor=false) at sql_prepare.cc:3764
#12 0x000000000078623b in Prepared_statement::execute_loop (this=0x2a80668, expanded_query=0x7f6cd018fcb0, open_cursor=false, packet=0x0, packet_end=0x0) at sql_prepare.cc:3445
#13 0x0000000000784692 in mysql_sql_stmt_execute (thd=0x29c8bc8) at sql_prepare.cc:2670
#14 0x00000000006abe72 in mysql_execute_command (thd=0x29c8bc8) at sql_parse.cc:2314
#15 0x00000000006b760f in mysql_parse (thd=0x29c8bc8, rawbuf=0x2a4c900 "EXECUTE stmt", length=12, found_semicolon=0x7f6cd0190cb8) at sql_parse.cc:6173
#16 0x00000000006a9624 in dispatch_command (command=COM_QUERY, thd=0x29c8bc8, packet=0x2a43499 "EXECUTE stmt", packet_length=12) at sql_parse.cc:1243
#17 0x00000000006a8910 in do_command (thd=0x29c8bc8) at sql_parse.cc:923
#18 0x00000000006a5799 in handle_one_connection (arg=0x29c8bc8) at sql_connect.cc:1231
#19 0x00007f6cd997fb50 in start_thread (arg=<optimized out>) at pthread_create.c:304
#20 0x00007f6cd8d22a7d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112

revision-id: psergey@askmonty.org-20131127134316-ljkto7w7f41oddrk
revno: 3728
branch-nick: 5.3
BUILD/compile-pentium-debug-max-no-ndb

SET optimizer_switch = 'materialization=on,semijoin=on';
 
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1),(3);
 
CREATE TABLE t2 (b INT) ENGINE=MyISAM;
CREATE ALGORITHM=MERGE VIEW v2 AS SELECT * FROM t2;
INSERT INTO t2 VALUES (8),(9);
 
PREPARE stmt FROM "
SELECT * FROM t1 WHERE 1 IN ( SELECT b FROM v2 WHERE 2 IN ( SELECT MAX(a) FROM t1 ) )
";
 
EXECUTE stmt;
EXECUTE stmt;



 Comments   
Comment by Sergei Petrunia [ 2014-01-22 ]

a VIEW is not necessary, the crash could be repeated when using a derived table, too:

prepare s from '
SELECT * FROM t1 WHERE 1 IN ( SELECT b FROM (SELECT * FROM t2) v2 WHERE 2 IN (
SELECT MAX(a) FROM t1 ) )';
execute s;
execute s;

Comment by Sergei Petrunia [ 2014-01-22 ]

The crash happens in - Item_in_subselect::optimize(). The cause is

this->unit->first_select()->join==NULL

that is, a JOIN object has not yet been constructed for the Item_in_subselect. The subselect is not a part of WHERE clause - it has been converted into a non-merged semijoin (see setup_jtbm_semi_joins in the stack trace) during the first EXECUTE call.

Comment by Sergei Petrunia [ 2014-01-22 ]

When a subquery is still an Item in a WHERE clause, it gets its JOIN here:

JOIN::JOIN
subselect_single_select_engine::prepare
Item_subselect::fix_fields
Item_in_subselect::fix_fields
setup_conds
setup_without_group
JOIN::prepare

Comment by Sergei Petrunia [ 2014-01-22 ]

In general, non-merged semi-joins work with PS.

If I run PREPARE, EXECUTE, EXECUTE for this query:

select * from t1a where a in (select max(a) from t1)

on second EXECUTE the join is created here:

JOIN::JOIN
subselect_single_select_engine::prepare
Item_subselect::fix_fields
Item_in_subselect::fix_fields
Item_in_optimizer::fix_fields
setup_tables
setup_tables_and_check_access
JOIN::prepare
mysql_select

setup_tables() has this piece:

if (table_list->jtbm_subselect)
{
Item *item= table_list->jtbm_subselect->optimizer;
if (table_list->jtbm_subselect->optimizer->fix_fields(thd, &item))

Comment by Sergei Petrunia [ 2014-01-22 ]

.. and it seems that piece of code is not hit.

I'm debugging the original query (the variant without the VIEW), second
EXECUTE. In setup_tables(), one sees:

if (select_lex->first_cond_optimization)

{ ... }

else

{ List_iterator_fast <TABLE_LIST> ti(select_lex->leaf_tables_exec); select_lex->leaf_tables.empty(); while ((table_list= ti++)) ... }

for (table_list= tables;
table_list;
table_list= table_list->next_local)
{
...

The while() loop enumerates all three tables: t1, t2, <subquery4>
The for() loop enumerates only two tables: t1, t2.

<subquery4> is never processed.

Comment by Sergei Petrunia [ 2014-01-22 ]

convert_subq_to_jtbm() has these lines:

/* Nests do not participate in those 'chains', so: */
/* jtbm->next_leaf= jtbm->next_local= jtbm->next_global == NULL*/

...

/* A theory: no need to re-connect the next_global chain */

Perhaps, they are the cause of this bug.

Comment by Sergei Petrunia [ 2014-01-23 ]

The code actually makes an attempt to connect the next_leaf chain. The problem is that something is connected in the wrong place.
Debugging, I see:

  • non-merged-semi-join table is connected to a list with 'v'.
  • top-level select initially has only "t1a" in the list.
    then "t2" is connected to it.

that way, second re-execution doesn't see the non-merged semi-join in TABLE_LIST::next_local chain

Comment by Sergei Petrunia [ 2014-01-23 ]

Had a discussion with Sanja. convert_subq_to_sj() has this code

tl->next_local= subq_lex->leaf_tables.head();

it attaches first of child's leaf_tables into the parent's TABLE_LIST:::next_local list. This is incorrect, we should attach child's next_local chain (and not the first table in child's leaf_tables list).

Comment by Daniel Bartholomew [ 2014-01-29 ]

http://bazaar.launchpad.net/~maria-captains/maria/5.5/revision/2502.567.185

Comment by Daniel Bartholomew [ 2014-01-29 ]

http://bazaar.launchpad.net/~maria-captains/maria/5.5/revision/4026

Generated at Thu Feb 08 07:03:44 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.