Assertion `0' failed in QUICK_INDEX_SORT_SELECT::need_sorted_output() with index_merge+index_merge_sort_union+loosescan+semijoin, IN subquery, InnoDB

Bug #962667 reported by Elena Stepanova on 2012-03-22
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
MariaDB
Fix Released
High
Sergey Petrunia

Bug Description

Query:
SELECT * FROM t1 WHERE b IN (
  SELECT d FROM t2, t1
  WHERE a = d AND ( pk < 2 OR d = 'z' )
);

mysqld: opt_range.h:584: virtual void QUICK_INDEX_SORT_SELECT::need_sorted_output(): Assertion `0' failed.
120323 3:32:15 [ERROR] mysqld got signal 6 ;

#8 0xb748e014 in __assert_fail () from /lib/libc.so.6
#9 0x0841bb69 in QUICK_INDEX_SORT_SELECT::need_sorted_output (this=0x9ee6f38) at opt_range.h:584
#10 0x084261f4 in setup_semijoin_dups_elimination (join=0x9eebfc8, options=0, no_jbuf_after=3)
    at opt_subselect.cc:4110
#11 0x0836856a in make_join_readinfo (join=0x9eebfc8, options=0, no_jbuf_after=3)
    at sql_select.cc:9494
#12 0x0835487a in JOIN::optimize (this=0x9eebfc8) at sql_select.cc:1536
#13 0x083591c8 in mysql_select (thd=0x9e687f0, rref_pointer_array=0x9e6a38c, tables=0x9ed6e48,
    wild_num=1, fields=..., conds=0x9ed8380, og_num=0, order=0x0, group=0x0, having=0x0,
    proc_param=0x0, select_options=2147764736, result=0x9ed8528, unit=0x9e69f70,
    select_lex=0x9e6a250) at sql_select.cc:2938
#14 0x08350ecb in handle_select (thd=0x9e687f0, lex=0x9e69f14, result=0x9ed8528,
    setup_tables_done_option=0) at sql_select.cc:285
#15 0x082ebf4d in execute_sqlcom_select (thd=0x9e687f0, all_tables=0x9ed6e48) at sql_parse.cc:5151
#16 0x082e3329 in mysql_execute_command (thd=0x9e687f0) at sql_parse.cc:2284
#17 0x082ee588 in mysql_parse (thd=0x9e687f0,
    rawbuf=0x9ed6c70 "SELECT * FROM t1 WHERE b IN ( \nSELECT d FROM t2, t1 \nWHERE a = d AND ( pk < 2 OR d = 'z' )\n)", length=92, found_semicolon=0x9d744234) at sql_parse.cc:6152
#18 0x082e0f69 in dispatch_command (command=COM_QUERY, thd=0x9e687f0,
    packet=0x9f06131 "SELECT * FROM t1 WHERE b IN ( \nSELECT d FROM t2, t1 \nWHERE a = d AND ( pk < 2 OR d = 'z' )\n)", packet_length=92) at sql_parse.cc:1228
#19 0x082e0413 in do_command (thd=0x9e687f0) at sql_parse.cc:923
#20 0x082dd399 in handle_one_connection (arg=0x9e687f0) at sql_connect.cc:1193
#21 0xb771cb25 in start_thread () from /lib/libpthread.so.0

bzr version-info
revision-id: <email address hidden>
date: 2012-03-22 13:23:55 +0100
build-date: 2012-03-23 03:35:16 +0400
revno: 3466

This particular test case passes on MariaDB 5.5 (revno 3345), but I have a bigger one which fails with the same assertion.

Minimal optimizer_switch: index_merge=on,index_merge_sort_union=on,loosescan=on,semijoin=on
Full optimizer_switch (default): index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=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=off,table_elimination=on

EXPLAIN also fails.

Test case:

--source include/have_innodb.inc
SET optimizer_switch = 'index_merge=on,index_merge_sort_union=on,loosescan=on,semijoin=on';

CREATE TABLE t1 (
  a INT, b VARCHAR(1), c INT,
  KEY(a), KEY(b)
) ENGINE=InnoDB;

INSERT INTO t1 VALUES
(1,'v',9),(2,'v',8),(3,'c',7),(4,'m',6),(5,'x',5),
(6,'i',4),(7,'e',3),(8,'p',2),(9,'s',1),(10,'j',9),
(11,'z',8),(12,'c',7),(13,'a',6),(14,'q',5),(15,'y',4),
(16,'n',3),(17,'r',2),(18,'v',1),(19,'p',0);

CREATE TABLE t2 (
  pk INT, d VARCHAR(1), e INT,
  PRIMARY KEY(pk), KEY(d,e)
) ENGINE=InnoDB;

INSERT INTO t2 VALUES
(1,'x',1),(2,'d',2),(3,'r',3),(4,'f',4),(5,'y',5),
(6,'u',6),(7,'m',7),(8,'k',8),(9,'o',9),(10,'w',1),
(11,'m',2),(12,'q',3),(13,'m',4),(14,'d',5),
(15,'g',6),(16,'x',7),(17,'f',8);

SELECT * FROM t1 WHERE b IN (
  SELECT d FROM t2, t1
  WHERE a = d AND ( pk < 2 OR d = 'z' )
);

# End of test case

Sergey Petrunia (sergefp) wrote :

The failure scenario is as follows:

> best_access_path(idx=0, table=t2)

 > considers ref access
  - start considering ref access and LooseScan
  - ref access is not possible (cost=DBL_MAX)
  - LooseScan (as full index scan) is possible (cost=1.025)

 > then consider full scan/range accesses
  - find that quick access is possible
  - however it's not applicable for loose scan.
  - still, quick select is chosen.
< best_access_path
...

> advance_sj_state
  (choses the above loose scan over full index scan)
<

The problem is that subsequent code assumes that tab->type==JT_ALL &&
tab->quick!=NULL => use quick select for retrieval.

And eventually we crash with an assert because QUICK_SORT_INTERSECT_SELECT is
unable to produce records in order (that's true).

Changed in maria:
assignee: Oleksandr "Sanja" Byelkin (sanja-byelkin) → Sergey Petrunia (sergefp)
status: New → Confirmed
status: Confirmed → In Progress
Sergey Petrunia (sergefp) wrote :

Have a patch, need review.

Changed in maria:
status: In Progress → Fix Committed
Elena Stepanova (elenst) on 2012-03-29
tags: added: assertion optimizer
Changed in maria:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers