Commit 6795b264 authored by unknown's avatar unknown

fixed deleting derived table tree after using (BUG#1536)


mysql-test/r/subselect.result:
  fixed drop table statement
  test for BUG#1536
mysql-test/t/subselect.test:
  fixed drop table statement
  test for BUG#1536
sql/sql_derived.cc:
  all tree of derived table should be deleted
sql/sql_lex.cc:
  delete subtree method
sql/sql_lex.h:
  delete subtree method
parent d894f233
......@@ -1438,4 +1438,11 @@ explain select * from t3 where a > all (select max(b) from t2 group by a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 4 Using temporary; Using filesort
drop table if exists t2, t3;
drop table t2, t3;
create table t1 (E1 INTEGER UNSIGNED NOT NULL, E2 INTEGER UNSIGNED NOT NULL, E3 INTEGER UNSIGNED NOT NULL, PRIMARY KEY(E1)
);
insert into t1 VALUES(1,1,1), (2,2,1);
select count(*) from t1 INNER JOIN (SELECT A.E1, A.E2, A.E3 FROM t1 AS A WHERE A.E3 = (SELECT MAX(B.E3) FROM t1 AS B WHERE A.E2 = B.E2)) AS THEMAX ON t1.E1 = THEMAX.E2 AND t1.E1 = t1.E2;
count(*)
2
drop table t1;
......@@ -964,4 +964,13 @@ explain select * from t3 where a >= all (select b from t2);
insert into t2 values (2,2), (2,1), (3,3), (3,1);
select * from t3 where a > all (select max(b) from t2 group by a);
explain select * from t3 where a > all (select max(b) from t2 group by a);
drop table if exists t2, t3;
drop table t2, t3;
#
# deived tables with subquery inside all by one table
#
create table t1 (E1 INTEGER UNSIGNED NOT NULL, E2 INTEGER UNSIGNED NOT NULL, E3 INTEGER UNSIGNED NOT NULL, PRIMARY KEY(E1)
);
insert into t1 VALUES(1,1,1), (2,2,1);
select count(*) from t1 INNER JOIN (SELECT A.E1, A.E2, A.E3 FROM t1 AS A WHERE A.E3 = (SELECT MAX(B.E3) FROM t1 AS B WHERE A.E2 = B.E2)) AS THEMAX ON t1.E1 = THEMAX.E2 AND t1.E1 = t1.E2;
drop table t1;
......@@ -220,7 +220,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
}
}
else
unit->exclude_level();
unit->exclude_tree();
org_table_list->db= (char *)"";
#ifndef DBUG_OFF
/* Try to catch errors if this is accessed */
......
......@@ -1097,6 +1097,16 @@ void st_select_lex_node::exclude()
*/
}
/*
Exclude level of current unit from tree of SELECTs
SYNOPSYS
st_select_lex_unit::exclude_level()
NOTE: units which belong to current will be brought up on level of
currernt unit
*/
void st_select_lex_unit::exclude_level()
{
SELECT_LEX_UNIT *units= 0, **units_last= &units;
......@@ -1125,6 +1135,30 @@ void st_select_lex_unit::exclude_level()
(*prev)= next;
}
/*
Exclude subtree of current unit from tree of SELECTs
SYNOPSYS
st_select_lex_unit::exclude_tree()
*/
void st_select_lex_unit::exclude_tree()
{
SELECT_LEX_UNIT *units= 0, **units_last= &units;
for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
{
if (sl->link_prev && (*sl->link_prev= sl->link_next))
sl->link_next->link_prev= sl->link_prev;
for (SELECT_LEX_UNIT *u= sl->first_inner_unit(); u; u= u->next_unit())
{
u->exclude_level();
}
}
(*prev)= next;
}
/*
st_select_lex_node::mark_as_dependent mark all st_select_lex struct from
this to 'last' as dependent
......@@ -1135,7 +1169,6 @@ void st_select_lex_unit::exclude_level()
NOTE
'last' should be reachable from this st_select_lex_node
*/
void st_select_lex::mark_as_dependent(SELECT_LEX *last)
......
......@@ -321,6 +321,7 @@ class st_select_lex_unit: public st_select_lex_node {
st_select_lex_unit* next_unit() { return (st_select_lex_unit*) next; }
st_select_lex* return_after_parsing() { return return_to; }
void exclude_level();
void exclude_tree();
/* UNION methods */
int prepare(THD *thd, select_result *result, bool tables_and_fields_initied);
......
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