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.
This commit is contained in:
parent
2b89598fe0
commit
47e9678982
@ -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;
|
|||||||
|
|
||||||
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 @@ public:
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
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 @@ public:
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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 @@ public:
|
|||||||
|
|
||||||
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,
|
|||||||
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,
|
|||||||
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:
|
|||||||
*/
|
*/
|
||||||
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user