Commit f982d107 authored by Igor Babaev's avatar Igor Babaev

Fixed the following problem:

Temporary tables created for recursive CTE
were instantiated at the prepare phase. As
a result these temporary tables missed
indexes for look-ups and optimizer could not
use them.
parent 8c6a9aa3
...@@ -113,7 +113,7 @@ select t2.a from t1,t2 where t1.a+1=t2.a ...@@ -113,7 +113,7 @@ select t2.a from t1,t2 where t1.a+1=t2.a
) )
select * from t1; select * from t1;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 30 1 PRIMARY <derived2> ALL NULL NULL NULL NULL 5
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where 2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
3 UNCACHEABLE UNION <derived2> ALL NULL NULL NULL NULL 5 3 UNCACHEABLE UNION <derived2> ALL NULL NULL NULL NULL 5
3 UNCACHEABLE UNION t2 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join) 3 UNCACHEABLE UNION t2 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
...@@ -595,18 +595,18 @@ select h.name, h.dob, w.name, w.dob ...@@ -595,18 +595,18 @@ select h.name, h.dob, w.name, w.dob
from ancestor_couple_ids c, coupled_ancestors h, coupled_ancestors w from ancestor_couple_ids c, coupled_ancestors h, coupled_ancestors w
where c.h_id = h.id and c.w_id= w.id; where c.h_id = h.id and c.w_id= w.id;
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 36 100.00 1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00 Using where
1 PRIMARY <derived3> ALL NULL NULL NULL NULL 468 100.00 Using where; Using join buffer (flat, BNL join) 1 PRIMARY <derived3> ref key0 key0 5 c.h_id 2 100.00
1 PRIMARY <derived3> ALL NULL NULL NULL NULL 468 100.00 Using where; Using join buffer (incremental, BNL join) 1 PRIMARY <derived3> ref key0 key0 5 c.w_id 2 100.00
3 SUBQUERY folks ALL NULL NULL NULL NULL 12 100.00 Using where 3 SUBQUERY folks ALL NULL NULL NULL NULL 12 100.00 Using where
4 UNCACHEABLE UNION p ALL NULL NULL NULL NULL 12 100.00 4 UNCACHEABLE UNION <derived2> ALL NULL NULL NULL NULL 2 100.00
4 UNCACHEABLE UNION <derived2> ALL NULL NULL NULL NULL 36 100.00 Using where; Using join buffer (flat, BNL join) 4 UNCACHEABLE UNION p ALL NULL NULL NULL NULL 12 100.00 Using where; Using join buffer (flat, BNL join)
5 UNCACHEABLE UNION <derived2> ALL NULL NULL NULL NULL 2 100.00 5 UNCACHEABLE UNION <derived2> ALL NULL NULL NULL NULL 2 100.00
5 UNCACHEABLE UNION p ALL NULL NULL NULL NULL 12 100.00 Using where; Using join buffer (flat, BNL join) 5 UNCACHEABLE UNION p ALL NULL NULL NULL NULL 12 100.00 Using where; Using join buffer (flat, BNL join)
NULL UNION RESULT <union3,4,5> ALL NULL NULL NULL NULL NULL NULL NULL UNION RESULT <union3,4,5> ALL NULL NULL NULL NULL NULL NULL
2 UNCACHEABLE SUBQUERY <derived3> ALL NULL NULL NULL NULL 36 100.00 Using where 2 UNCACHEABLE SUBQUERY <derived3> ALL NULL NULL NULL NULL 12 100.00 Using where
Warnings: Warnings:
Note 1003 with recursive ancestor_couple_ids as (select `a`.`father` AS `h_id`,`a`.`mother` AS `w_id` from `coupled_ancestors` `a` where ((`a`.`father` is not null) and (`a`.`mother` is not null)))coupled_ancestors as (select `test`.`folks`.`id` AS `id`,`test`.`folks`.`name` AS `name`,`test`.`folks`.`dob` AS `dob`,`test`.`folks`.`father` AS `father`,`test`.`folks`.`mother` AS `mother` from `test`.`folks` where (`test`.`folks`.`name` = 'Me') union all select `test`.`p`.`id` AS `id`,`test`.`p`.`name` AS `name`,`test`.`p`.`dob` AS `dob`,`test`.`p`.`father` AS `father`,`test`.`p`.`mother` AS `mother` from `test`.`folks` `p` join `ancestor_couple_ids` `fa` where (`fa`.`h_id` = `test`.`p`.`id`) union all select `test`.`p`.`id` AS `id`,`test`.`p`.`name` AS `name`,`test`.`p`.`dob` AS `dob`,`test`.`p`.`father` AS `father`,`test`.`p`.`mother` AS `mother` from `test`.`folks` `p` join `ancestor_couple_ids` `ma` where (`test`.`p`.`id` = `ma`.`w_id`)), select `h`.`name` AS `name`,`h`.`dob` AS `dob`,`w`.`name` AS `name`,`w`.`dob` AS `dob` from `ancestor_couple_ids` `c` join `coupled_ancestors` `h` join `coupled_ancestors` `w` where ((`h`.`id` = `c`.`h_id`) and (`w`.`id` = `c`.`w_id`)) Note 1003 with recursive ancestor_couple_ids as (select `a`.`father` AS `h_id`,`a`.`mother` AS `w_id` from `coupled_ancestors` `a` where ((`a`.`father` is not null) and (`a`.`mother` is not null)))coupled_ancestors as (select `test`.`folks`.`id` AS `id`,`test`.`folks`.`name` AS `name`,`test`.`folks`.`dob` AS `dob`,`test`.`folks`.`father` AS `father`,`test`.`folks`.`mother` AS `mother` from `test`.`folks` where (`test`.`folks`.`name` = 'Me') union all select `test`.`p`.`id` AS `id`,`test`.`p`.`name` AS `name`,`test`.`p`.`dob` AS `dob`,`test`.`p`.`father` AS `father`,`test`.`p`.`mother` AS `mother` from `test`.`folks` `p` join `ancestor_couple_ids` `fa` where (`test`.`p`.`id` = `fa`.`h_id`) union all select `test`.`p`.`id` AS `id`,`test`.`p`.`name` AS `name`,`test`.`p`.`dob` AS `dob`,`test`.`p`.`father` AS `father`,`test`.`p`.`mother` AS `mother` from `test`.`folks` `p` join `ancestor_couple_ids` `ma` where (`test`.`p`.`id` = `ma`.`w_id`)), select `h`.`name` AS `name`,`h`.`dob` AS `dob`,`w`.`name` AS `name`,`w`.`dob` AS `dob` from `ancestor_couple_ids` `c` join `coupled_ancestors` `h` join `coupled_ancestors` `w` where ((`h`.`id` = `c`.`h_id`) and (`w`.`id` = `c`.`w_id`))
with recursive with recursive
ancestor_couple_ids(h_id, w_id) ancestor_couple_ids(h_id, w_id)
as as
...@@ -779,7 +779,7 @@ where p.id = a.father or p.id = a.mother ...@@ -779,7 +779,7 @@ where p.id = a.father or p.id = a.mother
) )
select * from ancestors; select * from ancestors;
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 156 100.00 1 PRIMARY <derived2> ALL NULL NULL NULL NULL 12 100.00
2 SUBQUERY folks ALL NULL NULL NULL NULL 12 100.00 Using where 2 SUBQUERY folks ALL NULL NULL NULL NULL 12 100.00 Using where
3 UNCACHEABLE UNION p ALL NULL NULL NULL NULL 12 100.00 3 UNCACHEABLE UNION p ALL NULL NULL NULL NULL 12 100.00
3 UNCACHEABLE UNION <derived2> ALL NULL NULL NULL NULL 12 100.00 Using where; Using join buffer (flat, BNL join) 3 UNCACHEABLE UNION <derived2> ALL NULL NULL NULL NULL 12 100.00 Using where; Using join buffer (flat, BNL join)
...@@ -809,9 +809,9 @@ id name dob father mother ...@@ -809,9 +809,9 @@ id name dob father mother
20 Dad 1970-02-02 10 9 20 Dad 1970-02-02 10 9
30 Mom 1975-03-03 8 7 30 Mom 1975-03-03 8 7
10 Grandpa Bill 1940-04-05 NULL NULL 10 Grandpa Bill 1940-04-05 NULL NULL
8 Grandpa Ben 1940-10-21 NULL NULL
9 Grandma Ann 1941-10-15 NULL NULL 9 Grandma Ann 1941-10-15 NULL NULL
7 Grandma Sally 1943-08-23 NULL 6 7 Grandma Sally 1943-08-23 NULL 6
8 Grandpa Ben 1940-10-21 NULL NULL
6 Grandgrandma Martha 1923-05-17 NULL NULL 6 Grandgrandma Martha 1923-05-17 NULL NULL
with recursive with recursive
ancestors ancestors
...@@ -896,9 +896,9 @@ generation name ...@@ -896,9 +896,9 @@ generation name
1 Dad 1 Dad
1 Mom 1 Mom
2 Grandpa Bill 2 Grandpa Bill
2 Grandpa Ben
2 Grandma Ann 2 Grandma Ann
2 Grandma Sally 2 Grandma Sally
2 Grandpa Ben
3 Grandgrandma Martha 3 Grandgrandma Martha
set standards_compliant_cte=1; set standards_compliant_cte=1;
with recursive with recursive
...@@ -951,9 +951,9 @@ id name dob father mother ...@@ -951,9 +951,9 @@ id name dob father mother
20 Dad 1970-02-02 10 9 20 Dad 1970-02-02 10 9
30 Mom 1975-03-03 8 7 30 Mom 1975-03-03 8 7
10 Grandpa Bill 1940-04-05 NULL NULL 10 Grandpa Bill 1940-04-05 NULL NULL
8 Grandpa Ben 1940-10-21 NULL NULL
9 Grandma Ann 1941-10-15 NULL NULL 9 Grandma Ann 1941-10-15 NULL NULL
7 Grandma Sally 1943-08-23 NULL 6 7 Grandma Sally 1943-08-23 NULL 6
8 Grandpa Ben 1940-10-21 NULL NULL
with recursive with recursive
ancestor_ids (id) ancestor_ids (id)
as as
...@@ -998,10 +998,10 @@ id name dob father mother ...@@ -998,10 +998,10 @@ id name dob father mother
20 Dad 1970-02-02 10 9 20 Dad 1970-02-02 10 9
30 Mom 1975-03-03 8 7 30 Mom 1975-03-03 8 7
10 Grandpa Bill 1940-04-05 NULL NULL 10 Grandpa Bill 1940-04-05 NULL NULL
8 Grandpa Ben 1940-10-21 NULL NULL
25 Uncle Jim 1968-11-18 8 7
9 Grandma Ann 1941-10-15 NULL NULL 9 Grandma Ann 1941-10-15 NULL NULL
25 Uncle Jim 1968-11-18 8 7
7 Grandma Sally 1943-08-23 NULL 6 7 Grandma Sally 1943-08-23 NULL 6
8 Grandpa Ben 1940-10-21 NULL NULL
6 Grandgrandma Martha 1923-05-17 NULL NULL 6 Grandgrandma Martha 1923-05-17 NULL NULL
27 Auntie Melinda 1971-03-29 NULL NULL 27 Auntie Melinda 1971-03-29 NULL NULL
with recursive with recursive
...@@ -1029,9 +1029,9 @@ generation name ...@@ -1029,9 +1029,9 @@ generation name
1 Dad 1 Dad
1 Mom 1 Mom
2 Grandpa Bill 2 Grandpa Bill
2 Grandpa Ben
2 Grandma Ann 2 Grandma Ann
2 Grandma Sally 2 Grandma Sally
2 Grandpa Ben
3 Grandgrandma Martha 3 Grandgrandma Martha
with recursive with recursive
ancestor_ids (id, generation) ancestor_ids (id, generation)
...@@ -1112,7 +1112,60 @@ generation name ...@@ -1112,7 +1112,60 @@ generation name
1 Dad 1 Dad
1 Mom 1 Mom
2 Grandpa Bill 2 Grandpa Bill
2 Grandpa Ben
2 Grandma Ann 2 Grandma Ann
2 Grandma Sally 2 Grandma Sally
2 Grandpa Ben
alter table folks add primary key (id);
explain
with recursive
ancestors
as
(
select *
from folks
where name = 'Me'
union
select p.*
from folks as p, ancestors as fa
where p.id = fa.father
union
select p.*
from folks as p, ancestors as ma
where p.id = ma.mother
)
select * from ancestors;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 12
2 SUBQUERY folks ALL NULL NULL NULL NULL 12 Using where
3 UNCACHEABLE UNION p ALL PRIMARY NULL NULL NULL 12
3 UNCACHEABLE UNION <derived2> ref key0 key0 5 test.p.id 2
4 UNCACHEABLE UNION p ALL PRIMARY NULL NULL NULL 12
4 UNCACHEABLE UNION <derived2> ref key0 key0 5 test.p.id 2
NULL UNION RESULT <union2,3,4> ALL NULL NULL NULL NULL NULL
with recursive
ancestors
as
(
select *
from folks
where name = 'Me'
union
select p.*
from folks as p, ancestors as fa
where p.id = fa.father
union
select p.*
from folks as p, ancestors as ma
where p.id = ma.mother
)
select * from ancestors;
id name dob father mother
100 Me 2000-01-01 20 30
20 Dad 1970-02-02 10 9
30 Mom 1975-03-03 8 7
10 Grandpa Bill 1940-04-05 NULL NULL
8 Grandpa Ben 1940-10-21 NULL NULL
9 Grandma Ann 1941-10-15 NULL NULL
7 Grandma Sally 1943-08-23 NULL 6
6 Grandgrandma Martha 1923-05-17 NULL NULL
drop table folks; drop table folks;
...@@ -937,5 +937,45 @@ as ...@@ -937,5 +937,45 @@ as
) )
select * from ancestors; select * from ancestors;
alter table folks add primary key (id);
explain
with recursive
ancestors
as
(
select *
from folks
where name = 'Me'
union
select p.*
from folks as p, ancestors as fa
where p.id = fa.father
union
select p.*
from folks as p, ancestors as ma
where p.id = ma.mother
)
select * from ancestors;
with recursive
ancestors
as
(
select *
from folks
where name = 'Me'
union
select p.*
from folks as p, ancestors as fa
where p.id = fa.father
union
select p.*
from folks as p, ancestors as ma
where p.id = ma.mother
)
select * from ancestors;
drop table folks; drop table folks;
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include "sql_cte.h" #include "sql_cte.h"
#include "sql_view.h" // for make_valid_column_names #include "sql_view.h" // for make_valid_column_names
#include "sql_parse.h" #include "sql_parse.h"
#include "sql_select.h"
/** /**
...@@ -956,3 +957,20 @@ void With_element::print(String *str, enum_query_type query_type) ...@@ -956,3 +957,20 @@ void With_element::print(String *str, enum_query_type query_type)
} }
bool With_element::instantiate_tmp_tables()
{
List_iterator_fast<TABLE> li(rec_result->rec_tables);
TABLE *rec_table;
while ((rec_table= li++))
{
if (!rec_table->is_created() &&
instantiate_tmp_table(rec_table,
rec_result->tmp_table_param.keyinfo,
rec_result->tmp_table_param.start_recinfo,
&rec_result->tmp_table_param.recinfo,
0))
return true;
}
return false;
}
...@@ -6,14 +6,14 @@ ...@@ -6,14 +6,14 @@
class select_union; class select_union;
struct st_unit_ctxt_elem; struct st_unit_ctxt_elem;
/** /**
@class With_clause @class With_element
@brief Set of with_elements @brief Definition of a CTE table
It has a reference to the first with element from this with clause. It contains a reference to the name of the table introduced by this with element,
This reference allows to navigate through all the elements of the with clause. and a reference to the unit that specificies this table. Also it contains
It contains a reference to the unit to which this with clause is attached. a reference to the with clause to which this element belongs to.
It also contains a flag saying whether this with clause was specified as recursive.
*/ */
class With_element : public Sql_alloc class With_element : public Sql_alloc
...@@ -184,17 +184,19 @@ class With_element : public Sql_alloc ...@@ -184,17 +184,19 @@ class With_element : public Sql_alloc
void set_result_table(TABLE *tab) { result_table= tab; } void set_result_table(TABLE *tab) { result_table= tab; }
bool instantiate_tmp_tables();
friend class With_clause; friend class With_clause;
}; };
/** /**
@class With_element @class With_clause
@brief Definition of a CTE table @brief Set of with_elements
It contains a reference to the name of the table introduced by this with element, It has a reference to the first with element from this with clause.
and a reference to the unit that specificies this table. Also it contains This reference allows to navigate through all the elements of the with clause.
a reference to the with clause to which this element belongs to. It contains a reference to the unit to which this with clause is attached.
It also contains a flag saying whether this with clause was specified as recursive.
*/ */
class With_clause : public Sql_alloc class With_clause : public Sql_alloc
......
...@@ -653,7 +653,7 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived) ...@@ -653,7 +653,7 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived)
(first_select->options | (first_select->options |
thd->variables.option_bits | thd->variables.option_bits |
TMP_TABLE_ALL_COLUMNS), TMP_TABLE_ALL_COLUMNS),
derived->alias, FALSE, TRUE); derived->alias, FALSE, FALSE);
thd->create_tmp_table_for_derived= FALSE; thd->create_tmp_table_for_derived= FALSE;
if (!res && !derived->table) if (!res && !derived->table)
...@@ -681,7 +681,9 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived) ...@@ -681,7 +681,9 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived)
for (SELECT_LEX *sl= first_select; sl; sl= sl->next_select()) for (SELECT_LEX *sl= first_select; sl; sl= sl->next_select())
{ {
sl->context.outer_context= 0; sl->context.outer_context= 0;
if (!derived->is_with_table_recursive_reference()) if (!derived->is_with_table_recursive_reference() ||
(!derived->with->with_anchor &&
!derived->with->is_with_prepared_anchor()))
{ {
// Prepare underlying views/DT first. // Prepare underlying views/DT first.
if ((res= sl->handle_derived(lex, DT_PREPARE))) if ((res= sl->handle_derived(lex, DT_PREPARE)))
...@@ -928,7 +930,8 @@ bool TABLE_LIST::fill_recursive(THD *thd) ...@@ -928,7 +930,8 @@ bool TABLE_LIST::fill_recursive(THD *thd)
rc= unit->exec_recursive(false); rc= unit->exec_recursive(false);
else else
{ {
while(!with->all_are_stabilized() && !rc) rc= with->instantiate_tmp_tables();
while(!rc && !with->all_are_stabilized())
{ {
rc= unit->exec_recursive(true); rc= unit->exec_recursive(true);
} }
......
...@@ -2065,6 +2065,7 @@ void st_select_lex_unit::init_query() ...@@ -2065,6 +2065,7 @@ void st_select_lex_unit::init_query()
offset_limit_cnt= 0; offset_limit_cnt= 0;
union_distinct= 0; union_distinct= 0;
prepared= optimized= executed= 0; prepared= optimized= executed= 0;
optimize_started= 0;
item= 0; item= 0;
union_result= 0; union_result= 0;
table= 0; table= 0;
...@@ -4393,6 +4394,19 @@ void SELECT_LEX::increase_derived_records(ha_rows records) ...@@ -4393,6 +4394,19 @@ void SELECT_LEX::increase_derived_records(ha_rows records)
SELECT_LEX_UNIT *unit= master_unit(); SELECT_LEX_UNIT *unit= master_unit();
DBUG_ASSERT(unit->derived); DBUG_ASSERT(unit->derived);
if (unit->with_element && unit->with_element->is_recursive)
{
st_select_lex *first_recursive= unit->with_element->first_recursive;
st_select_lex *sl= unit->first_select();
for ( ; sl != first_recursive; sl= sl->next_select())
{
if (sl == this)
break;
}
if (sl == first_recursive)
return;
}
select_union *result= (select_union*)unit->result; select_union *result= (select_union*)unit->result;
result->records+= records; result->records+= records;
} }
......
...@@ -611,6 +611,8 @@ class st_select_lex_unit: public st_select_lex_node { ...@@ -611,6 +611,8 @@ class st_select_lex_unit: public st_select_lex_node {
executed, // already executed executed, // already executed
cleaned; cleaned;
bool optimize_started;
// list of fields which points to temporary table for union // list of fields which points to temporary table for union
List<Item> item_list; List<Item> item_list;
/* /*
......
...@@ -165,10 +165,6 @@ static COND *optimize_cond(JOIN *join, COND *conds, ...@@ -165,10 +165,6 @@ static COND *optimize_cond(JOIN *join, COND *conds,
int flags= 0); int flags= 0);
bool const_expression_in_where(COND *conds,Item *item, Item **comp_item); bool const_expression_in_where(COND *conds,Item *item, Item **comp_item);
static int do_select(JOIN *join, Procedure *procedure); static int do_select(JOIN *join, Procedure *procedure);
static bool instantiate_tmp_table(TABLE *table, KEY *keyinfo,
MARIA_COLUMNDEF *start_recinfo,
MARIA_COLUMNDEF **recinfo,
ulonglong options);
static enum_nested_loop_state evaluate_join_record(JOIN *, JOIN_TAB *, int); static enum_nested_loop_state evaluate_join_record(JOIN *, JOIN_TAB *, int);
static enum_nested_loop_state static enum_nested_loop_state
...@@ -17915,7 +17911,6 @@ int rr_sequential_and_unpack(READ_RECORD *info) ...@@ -17915,7 +17911,6 @@ int rr_sequential_and_unpack(READ_RECORD *info)
TRUE - Error TRUE - Error
*/ */
static
bool instantiate_tmp_table(TABLE *table, KEY *keyinfo, bool instantiate_tmp_table(TABLE *table, KEY *keyinfo,
MARIA_COLUMNDEF *start_recinfo, MARIA_COLUMNDEF *start_recinfo,
MARIA_COLUMNDEF **recinfo, MARIA_COLUMNDEF **recinfo,
......
...@@ -2235,6 +2235,10 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo, ...@@ -2235,6 +2235,10 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
TMP_ENGINE_COLUMNDEF *start_recinfo, TMP_ENGINE_COLUMNDEF *start_recinfo,
TMP_ENGINE_COLUMNDEF **recinfo, TMP_ENGINE_COLUMNDEF **recinfo,
ulonglong options); ulonglong options);
bool instantiate_tmp_table(TABLE *table, KEY *keyinfo,
MARIA_COLUMNDEF *start_recinfo,
MARIA_COLUMNDEF **recinfo,
ulonglong options);
bool open_tmp_table(TABLE *table); bool open_tmp_table(TABLE *table);
void setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps); void setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps);
double prev_record_reads(POSITION *positions, uint idx, table_map found_ref); double prev_record_reads(POSITION *positions, uint idx, table_map found_ref);
......
...@@ -229,7 +229,7 @@ select_union_recursive::create_result_table(THD *thd_arg, ...@@ -229,7 +229,7 @@ select_union_recursive::create_result_table(THD *thd_arg,
if (! (rec_table= create_tmp_table(thd_arg, &tmp_table_param, *column_types, if (! (rec_table= create_tmp_table(thd_arg, &tmp_table_param, *column_types,
(ORDER*) 0, false, 1, (ORDER*) 0, false, 1,
options, HA_POS_ERROR, alias, options, HA_POS_ERROR, alias,
!create_table, keep_row_order))) true, keep_row_order)))
return true; return true;
rec_table->keys_in_use_for_query.clear_all(); rec_table->keys_in_use_for_query.clear_all();
...@@ -282,9 +282,12 @@ void select_union_recursive::cleanup() ...@@ -282,9 +282,12 @@ void select_union_recursive::cleanup()
List_iterator<TABLE> it(rec_tables); List_iterator<TABLE> it(rec_tables);
TABLE *tab; TABLE *tab;
while ((tab= it++)) while ((tab= it++))
{
if (tab->is_created())
{ {
tab->file->extra(HA_EXTRA_RESET_STATE); tab->file->extra(HA_EXTRA_RESET_STATE);
tab->file->ha_delete_all_rows(); tab->file->ha_delete_all_rows();
}
free_tmp_table(thd, tab); free_tmp_table(thd, tab);
} }
} }
...@@ -840,6 +843,10 @@ bool st_select_lex_unit::optimize() ...@@ -840,6 +843,10 @@ bool st_select_lex_unit::optimize()
if (optimized && !uncacheable && !describe) if (optimized && !uncacheable && !describe)
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
if (with_element && with_element->is_recursive && optimize_started)
DBUG_RETURN(FALSE);
optimize_started= true;
if (uncacheable || !item || !item->assigned() || describe) if (uncacheable || !item || !item->assigned() || describe)
{ {
if (item) if (item)
...@@ -1315,6 +1322,7 @@ bool st_select_lex_unit::cleanup() ...@@ -1315,6 +1322,7 @@ bool st_select_lex_unit::cleanup()
void st_select_lex_unit::reinit_exec_mechanism() void st_select_lex_unit::reinit_exec_mechanism()
{ {
prepared= optimized= executed= 0; prepared= optimized= executed= 0;
optimize_started= 0;
#ifndef DBUG_OFF #ifndef DBUG_OFF
if (is_union()) if (is_union())
{ {
......
...@@ -7198,24 +7198,14 @@ bool TABLE_LIST::handle_derived(LEX *lex, uint phases) ...@@ -7198,24 +7198,14 @@ bool TABLE_LIST::handle_derived(LEX *lex, uint phases)
DBUG_ENTER("handle_derived"); DBUG_ENTER("handle_derived");
DBUG_PRINT("enter", ("phases: 0x%x", phases)); DBUG_PRINT("enter", ("phases: 0x%x", phases));
if (is_with_table_recursive_reference()) if (unit)
{ {
if (!(with->with_anchor || with->is_with_prepared_anchor())) if (!is_with_table_recursive_reference())
{ {
for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select()) for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
if (sl->handle_derived(lex, phases)) if (sl->handle_derived(lex, phases))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
else if (mysql_handle_single_derived(lex, this, phases))
DBUG_RETURN(TRUE);
DBUG_RETURN(FALSE);
}
if (unit)
{
for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
if (sl->handle_derived(lex, phases))
DBUG_RETURN(TRUE);
if (mysql_handle_single_derived(lex, this, phases)) if (mysql_handle_single_derived(lex, this, phases))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
......
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