diff --git a/mysql-test/r/derived_view.result b/mysql-test/r/derived_view.result index 9434cccec0d..5e9eeb99732 100644 --- a/mysql-test/r/derived_view.result +++ b/mysql-test/r/derived_view.result @@ -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 <0>((0,(select 0 from `test`.`t1` where ((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 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 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; diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index a45701b5f9b..4af2a4c3a66 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -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 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 diff --git a/mysql-test/t/derived_view.test b/mysql-test/t/derived_view.test index dcad590676c..240eaf480a6 100644 --- a/mysql-test/t/derived_view.test +++ b/mysql-test/t/derived_view.test @@ -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; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 8fef7ef2f9d..80a80363cc0 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -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 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(); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index d42a4b869b3..fdee99b88f4 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -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 it(fields_list); + while ((item= it++)) + { + select_list_used_tables|= item->used_tables(); + } + Item_outer_ref *ref; + List_iterator_fast 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) { diff --git a/sql/sql_select.h b/sql/sql_select.h index ae21db849ff..07872cffa3e 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -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