summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/main/union.result85
-rw-r--r--mysql-test/main/union.test70
-rw-r--r--sql/item.h1
-rw-r--r--sql/item_subselect.cc44
-rw-r--r--sql/item_subselect.h1
-rw-r--r--sql/sql_lex.cc18
-rw-r--r--sql/sql_lex.h2
-rw-r--r--sql/sql_tvc.cc2
-rw-r--r--sql/sql_union.cc9
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);
- }
}