Commit 5819dfcd authored by Igor Babaev's avatar Igor Babaev

Fixed LP bug #809206.

The bitmap of used tables must be evaluated for the select list of every
materialized derived table / view and saved in a dedicated field.
This is also applied to materialized subqueries.
parent 419c20f1
......@@ -946,7 +946,7 @@ DROP TABLE t1,t2,t3;
# LP bug #806504: right join over a view/derived table
#
CREATE TABLE t1 (a int, b int) ;
INSERT IGNORE INTO t1 VALUES (0,0);
INSERT INTO t1 VALUES (0,0);
CREATE TABLE t2 (a int) ;
INSERT INTO t2 VALUES (0), (0);
CREATE VIEW v1 AS SELECT * FROM t1;
......@@ -978,3 +978,49 @@ Warnings:
Note 1003 select `test`.`t2`.`a` AS `a`,0 AS `a`,0 AS `b` from `test`.`t1` left join `test`.`t2` on((0 <> 0)) where <expr_cache><0>(<in_optimizer>(0,<exists>(select 0 from `test`.`t1` where (<cache>(0) = 0))))
DROP VIEW v1;
DROP TABLE t1,t2;
#
# LP bug #809206: DISTINCT in derived table / view
#
CREATE TABLE t1 (a int) ;
INSERT INTO t1 VALUES (0);
CREATE TABLE t2 (a varchar(32), b int, KEY (a)) ;
INSERT INTO t2 VALUES
('j',28), ('c',29), ('i',26), ('c',29), ('k',27),
('j',28), ('c',29), ('i',25), ('d',26), ('k',27);
CREATE TABLE t3 (a varchar(32));
INSERT INTO t3 VALUES ('j'), ('c');
CREATE VIEW v1 AS SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a;
SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a;
b
28
29
EXPLAIN
SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 system NULL NULL NULL NULL 1 Using temporary
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using where
1 SIMPLE t2 ref a a 35 test.t3.a 2
SELECT * FROM (SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a) t;
b
28
29
EXPLAIN
SELECT * FROM (SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a) t;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
2 DERIVED t1 system NULL NULL NULL NULL 1 Using temporary
2 DERIVED t3 ALL NULL NULL NULL NULL 2 Using where
2 DERIVED t2 ref a a 35 test.t3.a 2
SELECT * FROM v1;
b
28
29
EXPLAIN
SELECT * FROM v1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
2 DERIVED t1 system NULL NULL NULL NULL 1 Using temporary
2 DERIVED t3 ALL NULL NULL NULL NULL 2 Using where
2 DERIVED t2 ref a a 35 test.t3.a 2
DROP VIEW v1;
DROP TABLE t1,t2,t3;
......@@ -985,8 +985,8 @@ EXPLAIN EXTENDED SELECT 1 FROM
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 100.00 Using join buffer (flat, BNL join)
2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort; Distinct
2 DERIVED td ALL NULL NULL NULL NULL 2 100.00 Distinct; Using join buffer (flat, BNL join)
2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
2 DERIVED td ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
Warnings:
Note 1003 select 1 AS `1` from (select distinct group_concat(`test`.`td`.`f1` separator ',') AS `GROUP_CONCAT(td.f1)` from `test`.`t1` join `test`.`t1` `td` group by `test`.`td`.`f1`) `d` join `test`.`t1`
SELECT 1 FROM
......
......@@ -537,7 +537,7 @@ DROP TABLE t1,t2,t3;
--echo #
CREATE TABLE t1 (a int, b int) ;
INSERT IGNORE INTO t1 VALUES (0,0);
INSERT INTO t1 VALUES (0,0);
CREATE TABLE t2 (a int) ;
INSERT INTO t2 VALUES (0), (0);
......@@ -558,3 +558,35 @@ SELECT * FROM t2 RIGHT JOIN v1 AS t ON t.a != 0
DROP VIEW v1;
DROP TABLE t1,t2;
--echo #
--echo # LP bug #809206: DISTINCT in derived table / view
--echo #
CREATE TABLE t1 (a int) ;
INSERT INTO t1 VALUES (0);
CREATE TABLE t2 (a varchar(32), b int, KEY (a)) ;
INSERT INTO t2 VALUES
('j',28), ('c',29), ('i',26), ('c',29), ('k',27),
('j',28), ('c',29), ('i',25), ('d',26), ('k',27);
CREATE TABLE t3 (a varchar(32));
INSERT INTO t3 VALUES ('j'), ('c');
CREATE VIEW v1 AS SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a;
SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a;
EXPLAIN
SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a;
SELECT * FROM (SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a) t;
EXPLAIN
SELECT * FROM (SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a) t;
SELECT * FROM v1;
EXPLAIN
SELECT * FROM v1;
DROP VIEW v1;
DROP TABLE t1,t2,t3;
......@@ -3511,7 +3511,6 @@ void SELECT_LEX::update_used_tables()
while ((item= it++))
{
item->update_used_tables();
join->thd->used_tables|= item->used_tables();
}
Item_outer_ref *ref;
List_iterator_fast<Item_outer_ref> ref_it(inner_refs_list);
......@@ -3519,7 +3518,6 @@ void SELECT_LEX::update_used_tables()
{
item= ref->outer_ref;
item->update_used_tables();
join->thd->used_tables|= item->used_tables();
}
for (ORDER *order= group_list.first; order; order= order->next)
(*order->item)->update_used_tables();
......
......@@ -880,8 +880,6 @@ JOIN::optimize()
if (select_lex->first_cond_optimization)
{
if (!select_lex->outer_select())
thd->used_tables= 0;
//Do it only for the first execution
/* Merge all mergeable derived tables/views in this SELECT. */
if (select_lex->handle_derived(thd->lex, DT_MERGE))
......@@ -895,8 +893,6 @@ JOIN::optimize()
if (select_lex->first_cond_optimization)
{
if (!select_lex->outer_select())
thd->used_tables= 0;
/* dump_TABLE_LIST_graph(select_lex, select_lex->leaf_tables); */
if (convert_join_subqueries_to_semijoins(this))
DBUG_RETURN(1); /* purecov: inspected */
......@@ -906,6 +902,7 @@ JOIN::optimize()
/* Save this info for the next executions */
if (select_lex->save_leaf_tables(thd))
DBUG_RETURN(1);
eval_select_list_used_tables();
}
table_count= select_lex->leaf_tables.elements;
......@@ -1727,7 +1724,7 @@ int JOIN::init_execution()
if (exec_tmp_table1->distinct)
{
table_map used_tables= thd->used_tables;
table_map used_tables= select_list_used_tables;
JOIN_TAB *last_join_tab= join_tab + top_join_tab_count - 1;
do
{
......@@ -8464,6 +8461,30 @@ void JOIN::drop_unused_derived_keys()
}
}
/*
Evaluate the bitmap of used tables for items from the select list
*/
inline void JOIN::eval_select_list_used_tables()
{
select_list_used_tables= 0;
Item *item;
List_iterator_fast<Item> it(fields_list);
while ((item= it++))
{
select_list_used_tables|= item->used_tables();
}
Item_outer_ref *ref;
List_iterator_fast<Item_outer_ref> ref_it(select_lex->inner_refs_list);
while ((ref= ref_it++))
{
item= ref->outer_ref;
select_list_used_tables|= item->used_tables();
}
}
/*
Determine {after which table we'll produce ordered set}
......@@ -20845,7 +20866,8 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
need_order=0;
extra.append(STRING_WITH_LEN("; Using filesort"));
}
if (distinct & test_all_bits(used_tables,thd->used_tables))
if (distinct & test_all_bits(used_tables,
join->select_list_used_tables))
extra.append(STRING_WITH_LEN("; Distinct"));
if (tab->loosescan_match_tab)
{
......
......@@ -767,6 +767,8 @@ public:
make_join_statistics)
*/
table_map outer_join;
/* Bitmap of tables used in the select list items */
table_map select_list_used_tables;
ha_rows send_records,found_records,examined_rows,row_limit, select_limit;
/**
Used to fetch no more than given amount of rows per one
......@@ -1134,6 +1136,7 @@ public:
return (table_map(1) << table_count) - 1;
}
void drop_unused_derived_keys();
inline void eval_select_list_used_tables();
/*
Return the table for which an index scan can be used to satisfy
the sort order needed by the ORDER BY/(implicit) GROUP BY clause
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment