Commit 979f27ee authored by bell@sanja.is.com.ua's avatar bell@sanja.is.com.ua

fixed bug in cyclic reference refinition

parent b724f02c
...@@ -10,6 +10,8 @@ SELECT (SELECT (SELECT 0 UNION SELECT 0)); ...@@ -10,6 +10,8 @@ SELECT (SELECT (SELECT 0 UNION SELECT 0));
0 0
SELECT (SELECT 1 FROM (SELECT 1) HAVING a=1) as a; SELECT (SELECT 1 FROM (SELECT 1) HAVING a=1) as a;
Cyclic reference on subqueries Cyclic reference on subqueries
SELECT (SELECT 1 FROM (SELECT 1) HAVING b=1) as a,(SELECT 1 FROM (SELECT 1) HAVING a=1) as b;
Cyclic reference on subqueries
drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit; drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit;
create table t1 (a int); create table t1 (a int);
create table t2 (a int, b int); create table t2 (a int, b int);
......
...@@ -3,6 +3,8 @@ SELECT (SELECT 1) UNION SELECT (SELECT 2); ...@@ -3,6 +3,8 @@ SELECT (SELECT 1) UNION SELECT (SELECT 2);
SELECT (SELECT (SELECT 0 UNION SELECT 0)); SELECT (SELECT (SELECT 0 UNION SELECT 0));
-- error 1243 -- error 1243
SELECT (SELECT 1 FROM (SELECT 1) HAVING a=1) as a; SELECT (SELECT 1 FROM (SELECT 1) HAVING a=1) as a;
-- error 1243
SELECT (SELECT 1 FROM (SELECT 1) HAVING b=1) as a,(SELECT 1 FROM (SELECT 1) HAVING a=1) as b;
drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit; drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit;
create table t1 (a int); create table t1 (a int);
create table t2 (a int, b int); create table t2 (a int, b int);
......
...@@ -876,11 +876,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) ...@@ -876,11 +876,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
{ {
depended_from= last; depended_from= last;
thd->lex.current_select->mark_as_dependent(last); thd->lex.current_select->mark_as_dependent(last);
if (check_loop(thd->check_loops_counter++)) thd->add_possible_loop(this);
{
my_message(ER_CYCLIC_REFERENCE, ER(ER_CYCLIC_REFERENCE), MYF(0));
return 1;
}
} }
} }
else if (!ref) else if (!ref)
......
...@@ -434,6 +434,15 @@ void THD::close_active_vio() ...@@ -434,6 +434,15 @@ void THD::close_active_vio()
} }
#endif #endif
void THD::add_possible_loop (Item *item)
{
if (!possible_loops)
{
possible_loops= new List<Item>;
}
possible_loops->push_back(item);
}
/***************************************************************************** /*****************************************************************************
** Functions to provide a interface to select results ** Functions to provide a interface to select results
*****************************************************************************/ *****************************************************************************/
......
...@@ -482,6 +482,7 @@ class THD :public ilink { ...@@ -482,6 +482,7 @@ class THD :public ilink {
USER_CONN *user_connect; USER_CONN *user_connect;
CHARSET_INFO *db_charset; CHARSET_INFO *db_charset;
CHARSET_INFO *thd_charset; CHARSET_INFO *thd_charset;
List<Item> *possible_loops; // Items that may cause loops in subselects
List <MYSQL_ERROR> warn_list; List <MYSQL_ERROR> warn_list;
uint warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_END]; uint warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_END];
uint total_warn_count, old_total_warn_count; uint total_warn_count, old_total_warn_count;
...@@ -632,6 +633,7 @@ class THD :public ilink { ...@@ -632,6 +633,7 @@ class THD :public ilink {
net.last_errno= 0; net.last_errno= 0;
net.report_error= 0; net.report_error= 0;
} }
void add_possible_loop(Item *);
}; };
/* /*
......
...@@ -2862,7 +2862,8 @@ mysql_init_query(THD *thd) ...@@ -2862,7 +2862,8 @@ mysql_init_query(THD *thd)
lex->select_lex.init_query(); lex->select_lex.init_query();
lex->value_list.empty(); lex->value_list.empty();
lex->param_list.empty(); lex->param_list.empty();
lex->unit.global_parameters= lex->unit.slave= lex->current_select= &lex->select_lex; lex->unit.global_parameters= lex->unit.slave= lex->current_select=
&lex->select_lex;
lex->select_lex.master= &lex->unit; lex->select_lex.master= &lex->unit;
lex->select_lex.prev= &lex->unit.slave; lex->select_lex.prev= &lex->unit.slave;
lex->olap=lex->describe=0; lex->olap=lex->describe=0;
...@@ -2875,6 +2876,7 @@ mysql_init_query(THD *thd) ...@@ -2875,6 +2876,7 @@ mysql_init_query(THD *thd)
thd->sent_row_count= thd->examined_row_count= 0; thd->sent_row_count= thd->examined_row_count= 0;
thd->fatal_error= thd->rand_used=0; thd->fatal_error= thd->rand_used=0;
thd->safe_to_cache_query= 1; thd->safe_to_cache_query= 1;
thd->possible_loops= 0;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
......
...@@ -1087,6 +1087,23 @@ mysql_select(THD *thd, TABLE_LIST *tables, List<Item> &fields, COND *conds, ...@@ -1087,6 +1087,23 @@ mysql_select(THD *thd, TABLE_LIST *tables, List<Item> &fields, COND *conds,
{ {
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
if (thd->possible_loops)
{
Item *item;
while(thd->possible_loops->elements)
{
item= thd->possible_loops->pop();
if (item->check_loop(thd->check_loops_counter++))
{
delete thd->possible_loops;
thd->possible_loops= 0;
my_message(ER_CYCLIC_REFERENCE, ER(ER_CYCLIC_REFERENCE), MYF(0));
return 1;
}
}
delete thd->possible_loops;
thd->possible_loops= 0;
}
} }
switch (join->optimize()) switch (join->optimize())
......
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