Commit 2f9555c4 authored by Igor Babaev's avatar Igor Babaev

Removed the parameter from st_select_lex_unit::exec_recursive.

Moved checking whether the limit set for the number of iterations
when executing a recursive query has been reached from
st_select_lex_unit::exec_recursive to TABLE_LIST::fill_recursive.
Changed the name of the system variable max_recursion_level for
max_recursive_iterations.
Adjusted test cases.
parent e20e28bd
...@@ -1086,7 +1086,7 @@ generation name ...@@ -1086,7 +1086,7 @@ generation name
1 Mom 1 Mom
2 Grandpa Bill 2 Grandpa Bill
2 Grandma Ann 2 Grandma Ann
set statement max_recursion_level=2 for set statement max_recursive_iterations=1 for
with recursive with recursive
ancestor_ids (id, generation) ancestor_ids (id, generation)
as as
...@@ -1463,8 +1463,8 @@ drop table folks; ...@@ -1463,8 +1463,8 @@ drop table folks;
create table t1(a int); create table t1(a int);
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
explain format=json explain format=json
with recursive T as (select a from t1 union select a+10 from T where a < 1000) with recursive t as (select a from t1 union select a+10 from t where a < 1000)
select * from T; select * from t;
EXPLAIN EXPLAIN
{ {
"query_block": { "query_block": {
...@@ -1499,7 +1499,7 @@ EXPLAIN ...@@ -1499,7 +1499,7 @@ EXPLAIN
"access_type": "ALL", "access_type": "ALL",
"rows": 10, "rows": 10,
"filtered": 100, "filtered": 100,
"attached_condition": "(T.a < 1000)" "attached_condition": "(t.a < 1000)"
} }
} }
} }
......
...@@ -450,7 +450,7 @@ The following options may be given as the first argument: ...@@ -450,7 +450,7 @@ The following options may be given as the first argument:
max_allowed_packet instead. max_allowed_packet instead.
--max-prepared-stmt-count=# --max-prepared-stmt-count=#
Maximum number of prepared statements in the server Maximum number of prepared statements in the server
--max-recursion-level[=#] --max-recursive-iterations[=#]
Maximum number of iterations when executing recursive Maximum number of iterations when executing recursive
queries queries
--max-relay-log-size=# --max-relay-log-size=#
...@@ -1273,7 +1273,7 @@ max-join-size 18446744073709551615 ...@@ -1273,7 +1273,7 @@ max-join-size 18446744073709551615
max-length-for-sort-data 1024 max-length-for-sort-data 1024
max-long-data-size 4194304 max-long-data-size 4194304
max-prepared-stmt-count 16382 max-prepared-stmt-count 16382
max-recursion-level 18446744073709551615 max-recursive-iterations 18446744073709551615
max-relay-log-size 1073741824 max-relay-log-size 1073741824
max-seeks-for-key 18446744073709551615 max-seeks-for-key 18446744073709551615
max-sort-length 1024 max-sort-length 1024
......
...@@ -2165,7 +2165,7 @@ NUMERIC_BLOCK_SIZE 1 ...@@ -2165,7 +2165,7 @@ NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL ENUM_VALUE_LIST NULL
READ_ONLY NO READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME MAX_RECURSION_LEVEL VARIABLE_NAME MAX_RECURSIVE_ITERATIONS
SESSION_VALUE 4294967295 SESSION_VALUE 4294967295
GLOBAL_VALUE 4294967295 GLOBAL_VALUE 4294967295
GLOBAL_VALUE_ORIGIN COMPILE-TIME GLOBAL_VALUE_ORIGIN COMPILE-TIME
......
...@@ -914,7 +914,7 @@ as ...@@ -914,7 +914,7 @@ as
) )
select * from ancestors; select * from ancestors;
set statement max_recursion_level=2 for set statement max_recursive_iterations=1 for
with recursive with recursive
ancestor_ids (id, generation) ancestor_ids (id, generation)
as as
...@@ -1074,8 +1074,8 @@ create table t1(a int); ...@@ -1074,8 +1074,8 @@ create table t1(a int);
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
explain format=json explain format=json
with recursive T as (select a from t1 union select a+10 from T where a < 1000) with recursive t as (select a from t1 union select a+10 from t where a < 1000)
select * from T; select * from t;
drop table t1; drop table t1;
......
...@@ -558,7 +558,7 @@ typedef struct system_variables ...@@ -558,7 +558,7 @@ typedef struct system_variables
ulong max_allowed_packet; ulong max_allowed_packet;
ulong max_error_count; ulong max_error_count;
ulong max_length_for_sort_data; ulong max_length_for_sort_data;
ulong max_recursion_level; ulong max_recursive_iterations;
ulong max_sort_length; ulong max_sort_length;
ulong max_tmp_tables; ulong max_tmp_tables;
ulong max_insert_delayed_threads; ulong max_insert_delayed_threads;
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#define SQL_CTE_INCLUDED #define SQL_CTE_INCLUDED
#include "sql_list.h" #include "sql_list.h"
#include "sql_lex.h" #include "sql_lex.h"
#include "sql_select.h"
class select_union; class select_union;
struct st_unit_ctxt_elem; struct st_unit_ctxt_elem;
...@@ -186,6 +187,8 @@ class With_element : public Sql_alloc ...@@ -186,6 +187,8 @@ class With_element : public Sql_alloc
bool instantiate_tmp_tables(); bool instantiate_tmp_tables();
void prepare_for_next_iteration();
friend class With_clause; friend class With_clause;
}; };
...@@ -356,6 +359,19 @@ bool With_element::all_are_stabilized() ...@@ -356,6 +359,19 @@ bool With_element::all_are_stabilized()
} }
inline
void With_element::prepare_for_next_iteration()
{
With_element *with_elem= this;
while ((with_elem= with_elem->get_next_mutually_recursive()) != this)
{
TABLE *rec_table= with_elem->first_rec_table_to_update;
if (rec_table)
rec_table->reginfo.join_tab->preread_init_done= false;
}
}
inline inline
void st_select_lex_unit::set_with_clause(With_clause *with_cl) void st_select_lex_unit::set_with_clause(With_clause *with_cl)
{ {
......
...@@ -927,13 +927,18 @@ bool TABLE_LIST::fill_recursive(THD *thd) ...@@ -927,13 +927,18 @@ bool TABLE_LIST::fill_recursive(THD *thd)
bool rc= false; bool rc= false;
st_select_lex_unit *unit= get_unit(); st_select_lex_unit *unit= get_unit();
if (is_with_table_recursive_reference()) if (is_with_table_recursive_reference())
rc= unit->exec_recursive(false); {
rc= unit->exec_recursive();
}
else else
{ {
rc= with->instantiate_tmp_tables(); rc= with->instantiate_tmp_tables();
while(!rc && !with->all_are_stabilized()) while (!rc && !with->all_are_stabilized())
{ {
rc= unit->exec_recursive(true); if (with->level > thd->variables.max_recursive_iterations)
break;
with->prepare_for_next_iteration();
rc= unit->exec_recursive();
} }
if (!rc) if (!rc)
{ {
......
...@@ -706,7 +706,7 @@ class st_select_lex_unit: public st_select_lex_node { ...@@ -706,7 +706,7 @@ class st_select_lex_unit: public st_select_lex_node {
bool prepare(THD *thd, select_result *result, ulong additional_options); bool prepare(THD *thd, select_result *result, ulong additional_options);
bool optimize(); bool optimize();
bool exec(); bool exec();
bool exec_recursive(bool is_driving_recursive); bool exec_recursive();
bool cleanup(); bool cleanup();
inline void unclean() { cleaned= 0; } inline void unclean() { cleaned= 0; }
void reinit_exec_mechanism(); void reinit_exec_mechanism();
......
...@@ -1167,7 +1167,7 @@ bool st_select_lex_unit::exec() ...@@ -1167,7 +1167,7 @@ bool st_select_lex_unit::exec()
// One step of recursive execution // One step of recursive execution
bool st_select_lex_unit::exec_recursive(bool is_driving_recursive) bool st_select_lex_unit::exec_recursive()
{ {
st_select_lex *lex_select_save= thd->lex->current_select; st_select_lex *lex_select_save= thd->lex->current_select;
st_select_lex *start= with_element->first_recursive; st_select_lex *start= with_element->first_recursive;
...@@ -1189,18 +1189,6 @@ bool st_select_lex_unit::exec_recursive(bool is_driving_recursive) ...@@ -1189,18 +1189,6 @@ bool st_select_lex_unit::exec_recursive(bool is_driving_recursive)
if ((saved_error= incr_table->file->ha_delete_all_rows())) if ((saved_error= incr_table->file->ha_delete_all_rows()))
goto err; goto err;
if (is_driving_recursive)
{
With_element *with_elem= with_element;
while ((with_elem= with_elem->get_next_mutually_recursive()) !=
with_element)
{
rec_table= with_elem->first_rec_table_to_update;
if (rec_table)
rec_table->reginfo.join_tab->preread_init_done= false;
}
}
if (with_element->level == 0) if (with_element->level == 0)
{ {
start= first_select(); start= first_select();
...@@ -1248,9 +1236,6 @@ bool st_select_lex_unit::exec_recursive(bool is_driving_recursive) ...@@ -1248,9 +1236,6 @@ bool st_select_lex_unit::exec_recursive(bool is_driving_recursive)
if (with_element->level == 1) if (with_element->level == 1)
rec_table->reginfo.join_tab->preread_init_done= true; rec_table->reginfo.join_tab->preread_init_done= true;
} }
if (with_element->level == thd->variables.max_recursion_level)
with_element->set_as_stabilized();
thd->lex->current_select= lex_select_save; thd->lex->current_select= lex_select_save;
err: err:
......
...@@ -2145,10 +2145,10 @@ static Sys_var_ulong Sys_max_prepared_stmt_count( ...@@ -2145,10 +2145,10 @@ static Sys_var_ulong Sys_max_prepared_stmt_count(
VALID_RANGE(0, 1024*1024), DEFAULT(16382), BLOCK_SIZE(1), VALID_RANGE(0, 1024*1024), DEFAULT(16382), BLOCK_SIZE(1),
&PLock_prepared_stmt_count); &PLock_prepared_stmt_count);
static Sys_var_ulong Sys_max_recursion_level( static Sys_var_ulong Sys_max_recursive_iterations(
"max_recursion_level", "max_recursive_iterations",
"Maximum number of iterations when executing recursive queries", "Maximum number of iterations when executing recursive queries",
SESSION_VAR(max_recursion_level), CMD_LINE(OPT_ARG), SESSION_VAR(max_recursive_iterations), CMD_LINE(OPT_ARG),
VALID_RANGE(0, UINT_MAX), DEFAULT(UINT_MAX), BLOCK_SIZE(1)); VALID_RANGE(0, UINT_MAX), DEFAULT(UINT_MAX), BLOCK_SIZE(1));
static Sys_var_ulong Sys_max_sort_length( static Sys_var_ulong Sys_max_sort_length(
......
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