[MDEV-4071] Valgrind warnings 'Invalid read' in subselect_engine::calc_const_tables with SELECT and IN subqueries, GROUP BY, HAVING, materialization+semijoin Created: 2013-01-21  Updated: 2013-05-04  Resolved: 2013-05-04

Status: Closed
Project: MariaDB Server
Component/s: None
Affects Version/s: 10.0.1, 5.5.29, 5.3.11
Fix Version/s: 10.0.3, 5.5.31, 5.3.13

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

Issue Links:
Relates
relates to MDEV-3404 LP:1002630 - Valgrind warnings 'Inval... Closed

 Description   

The bug and test case look very similar to MDEV-3404, except that the problem from MDEV-3404 was fixed some time ago, and the test case provided there does not cause valgrind errors any longer.

==29679== Thread 5:
==29679== Invalid read of size 1
==29679==    at 0x619C5B: subselect_engine::calc_const_tables(List<TABLE_LIST>&) (item_subselect.cc:3609)
==29679==    by 0x619CD4: subselect_single_select_engine::upper_select_const_tables() (item_subselect.cc:3618)
==29679==    by 0x611B19: Item_subselect::update_used_tables() (item_subselect.cc:801)
==29679==    by 0x5AFB0F: Item_func::update_used_tables() (item_func.cc:424)
==29679==    by 0x712097: JOIN::exec() (sql_select.cc:2532)
==29679==    by 0x713964: mysql_select(THD*, Item***, TABLE_LIST*, unsigned int, List<Item>&, Item*, unsigned int, st_order*, st_order*, Item*, st_order*, unsigned long long, select_result*, st_select_lex_unit*, st_select_lex*) (sql_select.cc:2985)
==29679==    by 0x70A31E: handle_select(THD*, st_lex*, select_result*, unsigned long) (sql_select.cc:286)
==29679==    by 0x69583E: execute_sqlcom_select(THD*, TABLE_LIST*) (sql_parse.cc:5157)
==29679==    by 0x68C5FD: mysql_execute_command(THD*) (sql_parse.cc:2290)
==29679==    by 0x698296: mysql_parse(THD*, char*, unsigned int, char const**) (sql_parse.cc:6158)
==29679==    by 0x689DA3: dispatch_command(enum_server_command, THD*, char*, unsigned int) (sql_parse.cc:1228)
==29679==    by 0x6890B7: do_command(THD*) (sql_parse.cc:923)
==29679==    by 0x685B12: handle_one_connection (sql_connect.cc:1231)
==29679==    by 0x548BEFB: start_thread (pthread_create.c:304)
==29679==    by 0x5F18F4C: clone (clone.S:112)
==29679==  Address 0xf7d48a7 is 2,103 bytes inside a block of size 4,120 free'd
==29679==    at 0x4C282E0: free (vg_replace_malloc.c:366)
==29679==    by 0xBAE901: my_no_flags_free (my_malloc.c:78)
==29679==    by 0xBB0323: free_root (my_alloc.c:366)
==29679==    by 0x731F8E: free_tmp_table(THD*, st_table*) (sql_select.cc:15218)
==29679==    by 0x61B812: subselect_hash_sj_engine::cleanup() (item_subselect.cc:4440)
==29679==    by 0x610127: Item_subselect::cleanup() (item_subselect.cc:130)
==29679==    by 0x610302: Item_in_subselect::cleanup() (item_subselect.cc:167)
==29679==    by 0x725781: st_join_table::cleanup() (sql_select.cc:10102)
==29679==    by 0x7261F1: JOIN::cleanup(bool) (sql_select.cc:10408)
==29679==    by 0x725EEE: JOIN::join_free() (sql_select.cc:10328)
==29679==    by 0x7117F6: JOIN::exec() (sql_select.cc:2402)
==29679==    by 0x713964: mysql_select(THD*, Item***, TABLE_LIST*, unsigned int, List<Item>&, Item*, unsigned int, st_order*, st_order*, Item*, st_order*, unsigned long long, select_result*, st_select_lex_unit*, st_select_lex*) (sql_select.cc:2985)
==29679==    by 0x70A31E: handle_select(THD*, st_lex*, select_result*, unsigned long) (sql_select.cc:286)
==29679==    by 0x69583E: execute_sqlcom_select(THD*, TABLE_LIST*) (sql_parse.cc:5157)
==29679==    by 0x68C5FD: mysql_execute_command(THD*) (sql_parse.cc:2290)
==29679==    by 0x698296: mysql_parse(THD*, char*, unsigned int, char const**) (sql_parse.cc:6158)

revision-id: timour@askmonty.org-20130117140805-4kyoq7azx4v2irhq
revno: 3615
branch-nick: 5.3

Also reproducible on 5.5 revno 3640 and 10.0-base revno 3472.

Minimal optimizer_switch: semijoin=on,materialization=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,engine_condition_pushdown=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,extended_keys=off

EXPLAIN (with the minimal optimizer_switch):

id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
1	PRIMARY	<subquery2>	const	distinct_key	distinct_key	8	const,const	1	100.00	Using temporary; Using filesort
1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	2	100.00	Using join buffer (flat, BNL join)
3	SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	2	100.00	
2	MATERIALIZED	t2	ALL	NULL	NULL	NULL	NULL	2	100.00	
Warnings:
Note	1003	select `test`.`t1`.`c` AS `c`,sum(distinct `test`.`t1`.`b`) AS `sm` from  <materialize> (select min(`test`.`t2`.`a`),max(`test`.`t2`.`a`) from `test`.`t2`) join `test`.`t1` where ((`<subquery2>`.`MAX(a)` = 108) and (`<subquery2>`.`MIN(a)` = 5)) group by `test`.`t1`.`b` having (`test`.`t1`.`c` <> (select max(`test`.`t1`.`c`) from `test`.`t1`)) order by sum(distinct `test`.`t1`.`b`)

Test case:

SET optimizer_switch = 'semijoin=on,materialization=on';
 
CREATE TABLE t1 (b INT, c VARCHAR(1)) ENGINE=MyISAM;
INSERT INTO t1 VALUES (7,'v'),(0,'s');
 
CREATE TABLE t2 (a INT) ENGINE=MyISAM;
INSERT INTO t2 VALUES (0),(8);
 
SELECT c, SUM( DISTINCT b ) AS sm FROM t1
WHERE ( 5, 108 ) IN ( SELECT MIN(a), MAX(a) FROM t2 )
GROUP BY b
HAVING c <> ( SELECT MAX( c ) FROM t1 )
ORDER BY sm;



 Comments   
Comment by Sergei Petrunia [ 2013-05-04 ]

In MDEV-3404, the problem was that update_used_tables() referred to the first table in the join order, which filesort() has replaced with temptable with sorted data, and then that temptable was freed before calc_const_tables() was called.

Here, the problem is similar - again we refer to a temptable that has already been freed. However, the temptable is of a different kind - this time it is SJ-Materialization temptable.

SJ-Materialization temptable is freed before the update_tmp_tables() is done for the HAVING clause. This is the cause for error.

Generated at Thu Feb 08 06:53:29 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.