Skip to content

Commit 9606525

Browse files
committed
Simplified the code that fills recursive tables.
1 parent 0eec187 commit 9606525

File tree

7 files changed

+135
-205
lines changed

7 files changed

+135
-205
lines changed

sql/sql_cte.cc

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -248,22 +248,32 @@ bool With_clause::check_anchors()
248248
if (!with_elem->is_recursive)
249249
continue;
250250

251-
table_map with_elem_dep= with_elem->derived_dep_map;
252-
table_map with_elem_map= with_elem->get_elem_map();
253-
for (With_element *elem= with_elem;
254-
elem != NULL;
255-
elem= elem->next_elem)
251+
if (!with_elem->next_mutually_recursive)
256252
{
257-
if (!elem->is_recursive)
258-
continue;
259-
260-
if (elem == with_elem ||
261-
((elem->derived_dep_map & with_elem_map) &&
262-
(with_elem_dep & elem->get_elem_map())))
263-
{
253+
With_element *last_mutually_recursive= with_elem;
254+
table_map with_elem_dep= with_elem->derived_dep_map;
255+
table_map with_elem_map= with_elem->get_elem_map();
256+
for (With_element *elem= with_elem;
257+
elem != NULL;
258+
elem= elem->next_elem)
259+
{
260+
if (!elem->is_recursive)
261+
continue;
262+
263+
if (elem == with_elem ||
264+
((elem->derived_dep_map & with_elem_map) &&
265+
(with_elem_dep & elem->get_elem_map())))
266+
{
267+
elem->next_mutually_recursive= with_elem;
268+
last_mutually_recursive->next_mutually_recursive= elem;
269+
last_mutually_recursive= elem;
264270
with_elem->mutually_recursive|= elem->get_elem_map();
265-
elem->mutually_recursive|= with_elem_map;
266271
}
272+
}
273+
for (With_element *elem= with_elem->next_mutually_recursive;
274+
elem != with_elem;
275+
elem= elem->next_mutually_recursive)
276+
elem->mutually_recursive= with_elem->mutually_recursive;
267277
}
268278

269279
for (st_select_lex *sl= with_elem->spec->first_select();

sql/sql_cte.h

Lines changed: 12 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class With_element : public Sql_alloc
3939
table_map work_dep_map; // dependency map used for work
4040
/* Dependency map of with elements mutually recursive with this with element */
4141
table_map mutually_recursive;
42+
With_element *next_mutually_recursive;
4243
/*
4344
Total number of references to this element in the FROM lists of
4445
the queries that are in the scope of the element (including
@@ -87,17 +88,21 @@ class With_element : public Sql_alloc
8788
select_union_recursive *rec_result;
8889

8990
TABLE *result_table;
91+
92+
TABLE *first_rec_table_to_update;
9093

9194

9295
With_element(LEX_STRING *name,
9396
List <LEX_STRING> list,
9497
st_select_lex_unit *unit)
9598
: next_elem(NULL), base_dep_map(0), derived_dep_map(0),
96-
sq_dep_map(0), work_dep_map(0), mutually_recursive(0),
99+
sq_dep_map(0), work_dep_map(0), mutually_recursive(0),
100+
next_mutually_recursive(NULL),
97101
references(0), table(NULL),
98102
query_name(name), column_list(list), spec(unit),
99103
is_recursive(false), with_anchor(false),
100-
level(0), rec_result(NULL), result_table(NULL)
104+
level(0), rec_result(NULL), result_table(NULL),
105+
first_rec_table_to_update(NULL)
101106
{}
102107

103108
bool check_dependencies_in_spec(THD *thd);
@@ -146,6 +151,9 @@ class With_element : public Sql_alloc
146151

147152
table_map get_mutually_recursive() { return mutually_recursive; }
148153

154+
With_element *get_next_mutually_recursive()
155+
{ return next_mutually_recursive; }
156+
149157
void set_table(TABLE *tab) { table= tab; }
150158

151159
TABLE *get_table() { return table; }
@@ -166,22 +174,6 @@ class With_element : public Sql_alloc
166174

167175
void reset_for_exec();
168176

169-
bool no_driving_recursive_is_set();
170-
171-
void set_as_driving_recursive();
172-
173-
bool is_driving_recursive();
174-
175-
void cleanup_driving_recursive();
176-
177-
void cleanup_incr_ready();
178-
179-
void set_as_incr_ready();
180-
181-
bool is_incr_ready();
182-
183-
bool all_incr_are_ready();
184-
185177
void cleanup_stabilized();
186178

187179
void set_as_stabilized();
@@ -228,8 +220,6 @@ class With_clause : public Sql_alloc
228220
table_map unrestricted;
229221
table_map with_prepared_anchor;
230222
table_map cleaned;
231-
table_map driving_recursive;
232-
table_map incr_ready;
233223
table_map stabilized;
234224

235225
public:
@@ -241,7 +231,7 @@ class With_clause : public Sql_alloc
241231
embedding_with_clause(emb_with_clause), next_with_clause(NULL),
242232
dependencies_are_checked(false),
243233
unrestricted(0), with_prepared_anchor(0), cleaned(0),
244-
driving_recursive(0), incr_ready(0), stabilized(0),
234+
stabilized(0),
245235
with_recursive(recursive_fl)
246236
{ last_next= &first_elem; }
247237

@@ -331,68 +321,11 @@ void With_element::reset_for_exec()
331321
level= 0;
332322
owner->with_prepared_anchor&= ~mutually_recursive;
333323
owner->cleaned&= ~get_elem_map();
334-
owner->driving_recursive&= ~get_elem_map();
335-
cleanup_incr_ready();
324+
first_rec_table_to_update= NULL;
336325
cleanup_stabilized();
337326
}
338327

339328

340-
inline
341-
bool With_element::no_driving_recursive_is_set()
342-
{
343-
return !(owner->driving_recursive & mutually_recursive);
344-
}
345-
346-
347-
inline
348-
void With_element::set_as_driving_recursive()
349-
{
350-
owner->driving_recursive|= get_elem_map();
351-
}
352-
353-
354-
inline
355-
bool With_element::is_driving_recursive()
356-
{
357-
return owner->driving_recursive & get_elem_map();
358-
}
359-
360-
361-
inline
362-
void With_element::cleanup_driving_recursive()
363-
{
364-
owner->driving_recursive&= ~mutually_recursive;
365-
}
366-
367-
368-
inline
369-
void With_element::cleanup_incr_ready()
370-
{
371-
owner->incr_ready&= ~mutually_recursive;
372-
}
373-
374-
375-
inline
376-
void With_element::set_as_incr_ready()
377-
{
378-
owner->incr_ready|= get_elem_map();
379-
}
380-
381-
382-
inline
383-
bool With_element::is_incr_ready()
384-
{
385-
return owner->incr_ready & get_elem_map();
386-
}
387-
388-
389-
inline
390-
bool With_element::all_incr_are_ready()
391-
{
392-
return (owner->incr_ready & mutually_recursive) == mutually_recursive;
393-
}
394-
395-
396329
inline
397330
void With_element::cleanup_stabilized()
398331
{

sql/sql_derived.cc

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,6 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived)
663663
if (derived->is_with_table_recursive_reference())
664664
{
665665
unit->with_element->rec_result->rec_tables.push_back(derived->table);
666-
derived->table->is_rec_table= true;
667666
}
668667
}
669668
DBUG_ASSERT(derived->table || res);
@@ -921,6 +920,28 @@ bool mysql_derived_create(THD *thd, LEX *lex, TABLE_LIST *derived)
921920
}
922921

923922

923+
bool TABLE_LIST::fill_recursive(THD *thd)
924+
{
925+
bool rc= false;
926+
st_select_lex_unit *unit= get_unit();
927+
if (is_with_table_recursive_reference())
928+
rc= unit->exec_recursive(false);
929+
else
930+
{
931+
while(!with->all_are_stabilized() && !rc)
932+
{
933+
rc= unit->exec_recursive(true);
934+
}
935+
if (!rc)
936+
{
937+
TABLE *src= with->rec_result->table;
938+
rc =src->insert_all_rows_into(thd, table, true);
939+
}
940+
}
941+
return rc;
942+
}
943+
944+
924945
/*
925946
Execute subquery of a materialized derived table/view and fill the result
926947
table.
@@ -944,21 +965,14 @@ bool mysql_derived_create(THD *thd, LEX *lex, TABLE_LIST *derived)
944965
@return TRUE Error
945966
*/
946967

968+
947969
bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
948970
{
949971
DBUG_ENTER("mysql_derived_fill");
950972
SELECT_LEX_UNIT *unit= derived->get_unit();
951973
bool derived_is_recursive= derived->is_recursive_with_table();
952974
bool res= FALSE;
953975

954-
if (derived_is_recursive && derived->with->all_are_stabilized())
955-
{
956-
TABLE *src= unit->with_element->rec_result->table;
957-
TABLE *dest= derived->table;
958-
res= src->insert_all_rows_into(thd, dest, true);
959-
DBUG_RETURN(res);
960-
}
961-
962976
if (unit->executed && !unit->uncacheable && !unit->describe &&
963977
!derived_is_recursive)
964978
DBUG_RETURN(FALSE);
@@ -967,11 +981,14 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
967981
SELECT_LEX *first_select= unit->first_select();
968982
select_union *derived_result= derived->derived_result;
969983
SELECT_LEX *save_current_select= lex->current_select;
970-
if (unit->is_union() || derived_is_recursive)
984+
985+
if (derived_is_recursive)
986+
{
987+
res= derived->fill_recursive(thd);
988+
}
989+
else if (unit->is_union())
971990
{
972991
// execute union without clean up
973-
if (derived_is_recursive)
974-
unit->with_element->set_result_table(derived->table);
975992
res= unit->exec();
976993
}
977994
else
@@ -995,15 +1012,13 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
9951012
derived_result, unit, first_select);
9961013
}
9971014

998-
if (!res)
1015+
if (!res && !derived_is_recursive)
9991016
{
10001017
if (derived_result->flush())
10011018
res= TRUE;
10021019
unit->executed= TRUE;
10031020
}
1004-
if (res ||
1005-
(!lex->describe &&
1006-
!(unit->with_element && unit->with_element->is_recursive)))
1021+
if (res || (!lex->describe && !derived_is_recursive))
10071022
unit->cleanup();
10081023
lex->current_select= save_current_select;
10091024

sql/sql_lex.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -704,7 +704,7 @@ class st_select_lex_unit: public st_select_lex_node {
704704
bool prepare(THD *thd, select_result *result, ulong additional_options);
705705
bool optimize();
706706
bool exec();
707-
bool exec_recursive();
707+
bool exec_recursive(bool is_driving_recursive);
708708
bool cleanup();
709709
inline void unclean() { cleaned= 0; }
710710
void reinit_exec_mechanism();

sql/sql_select.cc

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11606,11 +11606,7 @@ bool JOIN_TAB::preread_init()
1160611606

1160711607
/* Materialize derived table/view. */
1160811608
if ((!derived->get_unit()->executed ||
11609-
(derived->is_recursive_with_table() &&
11610-
(!derived->is_with_table_recursive_reference() ||
11611-
(!derived->with->is_driving_recursive() &&
11612-
!derived->with->is_incr_ready()) &&
11613-
!derived->with->all_are_stabilized()))) &&
11609+
derived->is_recursive_with_table()) &&
1161411610
mysql_handle_single_derived(join->thd->lex,
1161511611
derived, DT_CREATE | DT_FILL))
1161611612
return TRUE;
@@ -18241,8 +18237,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
1824118237
flush_dups_table->sj_weedout_delete_rows();
1824218238
}
1824318239

18244-
if ((!join_tab->preread_init_done || join_tab->table->is_rec_table) &&
18245-
join_tab->preread_init())
18240+
if (!join_tab->preread_init_done && join_tab->preread_init())
1824618241
DBUG_RETURN(NESTED_LOOP_ERROR);
1824718242

1824818243
join->return_tab= join_tab;
@@ -19195,8 +19190,7 @@ int join_init_read_record(JOIN_TAB *tab)
1919519190
report_error(tab->table, error);
1919619191
return 1;
1919719192
}
19198-
if ((!tab->preread_init_done || tab->table->is_rec_table) &&
19199-
tab->preread_init())
19193+
if (!tab->preread_init_done && tab->preread_init())
1920019194
return 1;
1920119195
if (init_read_record(&tab->read_record, tab->join->thd, tab->table,
1920219196
tab->select, tab->filesort_result, 1,1, FALSE))
@@ -19429,8 +19423,6 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
1942919423

1943019424
if (!end_of_records)
1943119425
{
19432-
#if 0
19433-
#endif
1943419426
if (join->table_count &&
1943519427
join->join_tab->is_using_loose_index_scan())
1943619428
{

0 commit comments

Comments
 (0)