diff options
-rw-r--r-- | mysql-test/main/union.result | 85 | ||||
-rw-r--r-- | mysql-test/main/union.test | 70 | ||||
-rw-r--r-- | sql/item.h | 1 | ||||
-rw-r--r-- | sql/item_subselect.cc | 44 | ||||
-rw-r--r-- | sql/item_subselect.h | 1 | ||||
-rw-r--r-- | sql/sql_lex.cc | 18 | ||||
-rw-r--r-- | sql/sql_lex.h | 2 | ||||
-rw-r--r-- | sql/sql_tvc.cc | 2 | ||||
-rw-r--r-- | sql/sql_union.cc | 9 |
9 files changed, 159 insertions, 73 deletions
diff --git a/mysql-test/main/union.result b/mysql-test/main/union.result index 38d8eb3f722..39554b18a65 100644 --- a/mysql-test/main/union.result +++ b/mysql-test/main/union.result @@ -2679,5 +2679,90 @@ ALTER TABLE t4 ADD INDEX (`NULL`); DROP TABLE t1, t2, t3, t4; set @@default_storage_engine=@save_default_storage_engine; # +# MDEV-29022: add_slave destroy child list and has dead code +# (test added to be sure that ordering by several subqueries works) +# +create table t1 (aa int); +insert into t1 values (-1),(0),(1),(2),(3),(4),(5),(6),(98),(99),(100),(102); +create table t2 (a int, b int); +insert into t2 values (2,2),(2,3),(3,4),(3,5); +select a as a, b as b, +(select max(aa) from t1 where aa < t2.a) as c, +(select max(aa) from t1 where aa < t2.b) as d +from t2 +union select 0 as a, 100 as b, +(select max(aa) from t1 where aa < 0) as c, +(select max(aa) from t1 where aa < 100) as d +union select 0 as a, 99 as b, +(select max(aa) from t1 where aa < 0) as c, +(select max(aa) from t1 where aa < 99) as d +order by (select max(aa) from t1 where aa < a), +(select max(aa) from t1 where aa < b); +a b c d +0 99 -1 98 +0 100 -1 99 +2 2 1 1 +2 3 1 2 +3 4 2 3 +3 5 2 4 +select a as a, b as b, +(select max(aa) from t1 where aa < t2.a) as c, +(select 200 - max(aa) from t1 where aa < t2.b) as d +from t2 +union select 0 as a, 100 as b, +(select max(aa) from t1 where aa < 0) as c, +(select 200 - max(aa) from t1 where aa < 100) as d +union select 0 as a, 99 as b, +(select max(aa) from t1 where aa < 0) as c, +(select 200 - max(aa) from t1 where aa < 99) as d +order by (select max(aa) from t1 where aa < a), +(select 200 - max(aa) from t1 where aa < b); +a b c d +0 100 -1 101 +0 99 -1 102 +2 3 1 198 +2 2 1 199 +3 5 2 196 +3 4 2 197 +(select a as a, b as b, +(select max(aa) from t1 where aa < t2.a) as c, +(select max(aa) from t1 where aa < t2.b) as d +from t2) +union (select 0 as a, 100 as b, +(select max(aa) from t1 where aa < 0) as c, +(select max(aa) from t1 where aa < 100) as d) +union (select 0 as a, 99 as b, +(select max(aa) from t1 where aa < 0) as c, +(select max(aa) from t1 where aa < 99) as d) +order by (select max(aa) from t1 where aa < a), +(select max(aa) from t1 where aa < b); +a b c d +0 99 -1 98 +0 100 -1 99 +2 2 1 1 +2 3 1 2 +3 4 2 3 +3 5 2 4 +(select a as a, b as b, +(select max(aa) from t1 where aa < t2.a) as c, +(select 200 - max(aa) from t1 where aa < t2.b) as d +from t2) +union (select 0 as a, 100 as b, +(select max(aa) from t1 where aa < 0) as c, +(select 200 - max(aa) from t1 where aa < 100) as d) +union (select 0 as a, 99 as b, +(select max(aa) from t1 where aa < 0) as c, +(select 200 - max(aa) from t1 where aa < 99) as d) +order by (select max(aa) from t1 where aa < a), +(select 200 - max(aa) from t1 where aa < b); +a b c d +0 100 -1 101 +0 99 -1 102 +2 3 1 198 +2 2 1 199 +3 5 2 196 +3 4 2 197 +drop table t1,t2; +# # End of 10.3 tests # diff --git a/mysql-test/main/union.test b/mysql-test/main/union.test index a7adc347a53..9bc655c85f5 100644 --- a/mysql-test/main/union.test +++ b/mysql-test/main/union.test @@ -1909,5 +1909,75 @@ DROP TABLE t1, t2, t3, t4; set @@default_storage_engine=@save_default_storage_engine; --echo # +--echo # MDEV-29022: add_slave destroy child list and has dead code +--echo # (test added to be sure that ordering by several subqueries works) +--echo # + +create table t1 (aa int); + +insert into t1 values (-1),(0),(1),(2),(3),(4),(5),(6),(98),(99),(100),(102); + + +create table t2 (a int, b int); + +insert into t2 values (2,2),(2,3),(3,4),(3,5); + + +select a as a, b as b, + (select max(aa) from t1 where aa < t2.a) as c, + (select max(aa) from t1 where aa < t2.b) as d + from t2 +union select 0 as a, 100 as b, + (select max(aa) from t1 where aa < 0) as c, + (select max(aa) from t1 where aa < 100) as d +union select 0 as a, 99 as b, + (select max(aa) from t1 where aa < 0) as c, + (select max(aa) from t1 where aa < 99) as d + order by (select max(aa) from t1 where aa < a), + (select max(aa) from t1 where aa < b); + +select a as a, b as b, + (select max(aa) from t1 where aa < t2.a) as c, + (select 200 - max(aa) from t1 where aa < t2.b) as d + from t2 +union select 0 as a, 100 as b, + (select max(aa) from t1 where aa < 0) as c, + (select 200 - max(aa) from t1 where aa < 100) as d +union select 0 as a, 99 as b, + (select max(aa) from t1 where aa < 0) as c, + (select 200 - max(aa) from t1 where aa < 99) as d + order by (select max(aa) from t1 where aa < a), + (select 200 - max(aa) from t1 where aa < b); + + +(select a as a, b as b, + (select max(aa) from t1 where aa < t2.a) as c, + (select max(aa) from t1 where aa < t2.b) as d + from t2) +union (select 0 as a, 100 as b, + (select max(aa) from t1 where aa < 0) as c, + (select max(aa) from t1 where aa < 100) as d) +union (select 0 as a, 99 as b, + (select max(aa) from t1 where aa < 0) as c, + (select max(aa) from t1 where aa < 99) as d) + order by (select max(aa) from t1 where aa < a), + (select max(aa) from t1 where aa < b); + +(select a as a, b as b, + (select max(aa) from t1 where aa < t2.a) as c, + (select 200 - max(aa) from t1 where aa < t2.b) as d + from t2) +union (select 0 as a, 100 as b, + (select max(aa) from t1 where aa < 0) as c, + (select 200 - max(aa) from t1 where aa < 100) as d) +union (select 0 as a, 99 as b, + (select max(aa) from t1 where aa < 0) as c, + (select 200 - max(aa) from t1 where aa < 99) as d) + order by (select max(aa) from t1 where aa < a), + (select 200 - max(aa) from t1 where aa < b); + +drop table t1,t2; + +--echo # --echo # End of 10.3 tests --echo # diff --git a/sql/item.h b/sql/item.h index 52febaa3031..05bfc47a2b4 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1924,7 +1924,6 @@ public: virtual bool enumerate_field_refs_processor(void *arg) { return 0; } virtual bool mark_as_eliminated_processor(void *arg) { return 0; } virtual bool eliminate_subselect_processor(void *arg) { return 0; } - virtual bool set_fake_select_as_master_processor(void *arg) { return 0; } virtual bool view_used_tables_processor(void *arg) { return 0; } virtual bool eval_not_null_tables(void *arg) { return 0; } virtual bool is_subquery_processor(void *arg) { return 0; } diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 7a9b874c53b..461bd9fb144 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -393,50 +393,6 @@ bool Item_subselect::eliminate_subselect_processor(void *arg) } -/** - Adjust the master select of the subquery to be the fake_select which - represents the whole UNION right above the subquery, instead of the - last query of the UNION. - - @param arg pointer to the fake select - - @return - FALSE to force the evaluation of the processor for the subsequent items. -*/ - -bool Item_subselect::set_fake_select_as_master_processor(void *arg) -{ - SELECT_LEX *fake_select= (SELECT_LEX*) arg; - /* - Move the st_select_lex_unit of a subquery from a global ORDER BY clause to - become a direct child of the fake_select of a UNION. In this way the - ORDER BY that is applied to the temporary table that contains the result of - the whole UNION, and all columns in the subquery are resolved against this - table. The transformation is applied only for immediate child subqueries of - a UNION query. - */ - if (unit->outer_select()->master_unit()->fake_select_lex == fake_select) - { - /* - Set the master of the subquery to be the fake select (i.e. the whole - UNION), instead of the last query in the UNION. - */ - fake_select->add_slave(unit); - DBUG_ASSERT(unit->outer_select() == fake_select); - /* Adjust the name resolution context hierarchy accordingly. */ - for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select()) - sl->context.outer_context= &(fake_select->context); - /* - Undo Item_subselect::eliminate_subselect_processor because at that phase - we don't know yet that the ORDER clause will be moved to the fake select. - */ - unit->item= this; - eliminated= FALSE; - } - return FALSE; -} - - bool Item_subselect::mark_as_dependent(THD *thd, st_select_lex *select, Item *item) { diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 4816785fa13..d81991a087e 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -244,7 +244,6 @@ public: bool walk(Item_processor processor, bool walk_subquery, void *arg); bool mark_as_eliminated_processor(void *arg); bool eliminate_subselect_processor(void *arg); - bool set_fake_select_as_master_processor(void *arg); bool enumerate_field_refs_processor(void *arg); bool check_vcol_func_processor(void *arg) { diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 3d1837fe698..8922c6b541b 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -2506,23 +2506,9 @@ void st_select_lex_node::include_down(st_select_lex_node *upper) } -void st_select_lex_node::add_slave(st_select_lex_node *slave_arg) +void st_select_lex_node::attach_single(st_select_lex_node *slave_arg) { - for (; slave; slave= slave->next) - if (slave == slave_arg) - return; - - if (slave) - { - st_select_lex_node *slave_arg_slave= slave_arg->slave; - /* Insert in the front of list of slaves if any. */ - slave_arg->include_neighbour(slave); - /* include_neighbour() sets slave_arg->slave=0, restore it. */ - slave_arg->slave= slave_arg_slave; - /* Count on include_neighbour() setting the master. */ - DBUG_ASSERT(slave_arg->master == this); - } - else + DBUG_ASSERT(slave == 0); { slave= slave_arg; slave_arg->master= this; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 976d1b79cad..aae994c8721 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -740,7 +740,7 @@ public: inline st_select_lex_node* get_master() { return master; } void include_down(st_select_lex_node *upper); - void add_slave(st_select_lex_node *slave_arg); + void attach_single(st_select_lex_node *slave_arg); void include_neighbour(st_select_lex_node *before); void link_chain_down(st_select_lex_node *first); void link_neighbour(st_select_lex_node *neighbour) diff --git a/sql/sql_tvc.cc b/sql/sql_tvc.cc index 72d53b2307c..5a027decd43 100644 --- a/sql/sql_tvc.cc +++ b/sql/sql_tvc.cc @@ -709,7 +709,7 @@ st_select_lex *wrap_tvc(THD *thd, st_select_lex *tvc_sl, Attach the select used of TVC as the only slave to the unit for the derived table tvc_x of the transformation */ - derived_unit->add_slave(tvc_sl); + derived_unit->attach_single(tvc_sl); tvc_sl->set_linkage(DERIVED_TABLE_TYPE); /* diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 70a521696d2..b878294bfef 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -633,15 +633,6 @@ st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg, order= order->next) order->item= &order->item_ptr; } - for (ORDER *order= global_parameters()->order_list.first; - order; - order=order->next) - { - (*order->item)->walk(&Item::change_context_processor, 0, - &fake_select_lex->context); - (*order->item)->walk(&Item::set_fake_select_as_master_processor, 0, - fake_select_lex); - } } |