Commit 47e96789 authored by Oleksandr Byelkin's avatar Oleksandr Byelkin

MDEV-29022 add_slave destroy child list and has dead code

Nowdays subquery in a UNION's ORDER BY placed correctly in fake select,
the only problem was incorrect Name_resolution_contect is fixed by this
patch in parsing, so we do not need scanning/reseting of ORDER BY of
a union.
parent 2b89598f
...@@ -2664,5 +2664,90 @@ ALTER TABLE t4 ADD INDEX (`NULL`); ...@@ -2664,5 +2664,90 @@ ALTER TABLE t4 ADD INDEX (`NULL`);
DROP TABLE t1, t2, t3, t4; DROP TABLE t1, t2, t3, t4;
set @@default_storage_engine=@save_default_storage_engine; 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 # End of 10.3 tests
# #
...@@ -1898,6 +1898,76 @@ DROP TABLE t1, t2, t3, t4; ...@@ -1898,6 +1898,76 @@ DROP TABLE t1, t2, t3, t4;
set @@default_storage_engine=@save_default_storage_engine; 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 #
--echo # End of 10.3 tests --echo # End of 10.3 tests
--echo # --echo #
...@@ -1758,7 +1758,6 @@ class Item: public Value_source, ...@@ -1758,7 +1758,6 @@ class Item: public Value_source,
virtual bool enumerate_field_refs_processor(void *arg) { return 0; } virtual bool enumerate_field_refs_processor(void *arg) { return 0; }
virtual bool mark_as_eliminated_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 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 view_used_tables_processor(void *arg) { return 0; }
virtual bool eval_not_null_tables(void *arg) { return 0; } virtual bool eval_not_null_tables(void *arg) { return 0; }
virtual bool is_subquery_processor(void *arg) { return 0; } virtual bool is_subquery_processor(void *arg) { return 0; }
......
...@@ -386,50 +386,6 @@ bool Item_subselect::eliminate_subselect_processor(void *arg) ...@@ -386,50 +386,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, bool Item_subselect::mark_as_dependent(THD *thd, st_select_lex *select,
Item *item) Item *item)
{ {
......
...@@ -238,7 +238,6 @@ class Item_subselect :public Item_result_field, ...@@ -238,7 +238,6 @@ class Item_subselect :public Item_result_field,
bool walk(Item_processor processor, bool walk_subquery, void *arg); bool walk(Item_processor processor, bool walk_subquery, void *arg);
bool mark_as_eliminated_processor(void *arg); bool mark_as_eliminated_processor(void *arg);
bool eliminate_subselect_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 enumerate_field_refs_processor(void *arg);
bool check_vcol_func_processor(void *arg) bool check_vcol_func_processor(void *arg)
{ {
......
...@@ -2434,23 +2434,9 @@ void st_select_lex_node::include_down(st_select_lex_node *upper) ...@@ -2434,23 +2434,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) DBUG_ASSERT(slave == 0);
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
{ {
slave= slave_arg; slave= slave_arg;
slave_arg->master= this; slave_arg->master= this;
......
...@@ -705,7 +705,7 @@ class st_select_lex_node { ...@@ -705,7 +705,7 @@ class st_select_lex_node {
inline st_select_lex_node* get_master() { return master; } inline st_select_lex_node* get_master() { return master; }
void include_down(st_select_lex_node *upper); 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 include_neighbour(st_select_lex_node *before);
void include_standalone(st_select_lex_node *sel, st_select_lex_node **ref); void include_standalone(st_select_lex_node *sel, st_select_lex_node **ref);
void include_global(st_select_lex_node **plink); void include_global(st_select_lex_node **plink);
......
...@@ -708,7 +708,7 @@ st_select_lex *wrap_tvc(THD *thd, st_select_lex *tvc_sl, ...@@ -708,7 +708,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 Attach the select used of TVC as the only slave to the unit for
the derived table tvc_x of the transformation the derived table tvc_x of the transformation
*/ */
derived_unit->add_slave(tvc_sl); derived_unit->attach_single(tvc_sl);
tvc_sl->linkage= DERIVED_TABLE_TYPE; tvc_sl->linkage= DERIVED_TABLE_TYPE;
/* /*
......
...@@ -633,15 +633,6 @@ st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg, ...@@ -633,15 +633,6 @@ st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg,
order= order->next) order= order->next)
order->item= &order->item_ptr; 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);
}
} }
......
...@@ -12910,11 +12910,16 @@ order_clause: ...@@ -12910,11 +12910,16 @@ order_clause:
*/ */
DBUG_ASSERT(sel->master_unit()->fake_select_lex); DBUG_ASSERT(sel->master_unit()->fake_select_lex);
lex->current_select= sel->master_unit()->fake_select_lex; lex->current_select= sel->master_unit()->fake_select_lex;
lex->push_context(&sel->master_unit()->fake_select_lex->context, thd->mem_root);
} }
} }
order_list order_list
{ {
if (Lex->current_select ==
Lex->current_select->master_unit()->fake_select_lex)
{
Lex->pop_context();
}
} }
; ;
......
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