From 979f27ee4ab978d6f634f444b8e377cf45dc7a59 Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Thu, 14 Nov 2002 09:43:24 +0200 Subject: [PATCH] fixed bug in cyclic reference refinition --- mysql-test/r/subselect.result | 2 ++ mysql-test/t/subselect.test | 2 ++ sql/item.cc | 6 +----- sql/sql_class.cc | 9 +++++++++ sql/sql_class.h | 2 ++ sql/sql_parse.cc | 4 +++- sql/sql_select.cc | 17 +++++++++++++++++ 7 files changed, 36 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 1b799a6cb63..d1a3056d8e9 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -10,6 +10,8 @@ SELECT (SELECT (SELECT 0 UNION SELECT 0)); 0 SELECT (SELECT 1 FROM (SELECT 1) HAVING a=1) as a; 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; create table t1 (a int); create table t2 (a int, b int); diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index f690a823f85..63f689d2608 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -3,6 +3,8 @@ SELECT (SELECT 1) UNION SELECT (SELECT 2); SELECT (SELECT (SELECT 0 UNION SELECT 0)); -- error 1243 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; create table t1 (a int); create table t2 (a int, b int); diff --git a/sql/item.cc b/sql/item.cc index f317759553b..48ec11d02c2 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -876,11 +876,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) { depended_from= last; thd->lex.current_select->mark_as_dependent(last); - if (check_loop(thd->check_loops_counter++)) - { - my_message(ER_CYCLIC_REFERENCE, ER(ER_CYCLIC_REFERENCE), MYF(0)); - return 1; - } + thd->add_possible_loop(this); } } else if (!ref) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index f33d0f2ca28..e6acab6a244 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -434,6 +434,15 @@ void THD::close_active_vio() } #endif +void THD::add_possible_loop (Item *item) +{ + if (!possible_loops) + { + possible_loops= new List; + } + possible_loops->push_back(item); +} + /***************************************************************************** ** Functions to provide a interface to select results *****************************************************************************/ diff --git a/sql/sql_class.h b/sql/sql_class.h index 6f6547a358c..a619e8e3aff 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -482,6 +482,7 @@ public: USER_CONN *user_connect; CHARSET_INFO *db_charset; CHARSET_INFO *thd_charset; + List *possible_loops; // Items that may cause loops in subselects List warn_list; uint warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_END]; uint total_warn_count, old_total_warn_count; @@ -632,6 +633,7 @@ public: net.last_errno= 0; net.report_error= 0; } + void add_possible_loop(Item *); }; /* diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1586469de42..8df74f332eb 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2862,7 +2862,8 @@ mysql_init_query(THD *thd) lex->select_lex.init_query(); lex->value_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.prev= &lex->unit.slave; lex->olap=lex->describe=0; @@ -2875,6 +2876,7 @@ mysql_init_query(THD *thd) thd->sent_row_count= thd->examined_row_count= 0; thd->fatal_error= thd->rand_used=0; thd->safe_to_cache_query= 1; + thd->possible_loops= 0; DBUG_VOID_RETURN; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index dd84b2a46c8..b3838628d35 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1087,6 +1087,23 @@ mysql_select(THD *thd, TABLE_LIST *tables, List &fields, COND *conds, { 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())