diff options
author | unknown <bell@sanja.is.com.ua> | 2002-11-14 00:26:18 +0200 |
---|---|---|
committer | unknown <bell@sanja.is.com.ua> | 2002-11-14 00:26:18 +0200 |
commit | 81a5afb925e9c41f7f43e58e8f36d93b5befd364 (patch) | |
tree | d888a4517004a1a442146f5d6b8c8ca5fa2515dc /sql | |
parent | e0ad88a2ff751d62853fa4f81d007d1b55fc71f4 (diff) | |
download | mariadb-git-81a5afb925e9c41f7f43e58e8f36d93b5befd364.tar.gz |
fixed cyclic reference bug
mysql-test/r/subselect.result:
test of cyclic reference
mysql-test/t/subselect.test:
test of cyclic reference
sql/share/czech/errmsg.txt:
new error message
sql/share/danish/errmsg.txt:
new error message
sql/share/dutch/errmsg.txt:
new error message
sql/share/english/errmsg.txt:
new error message
sql/share/estonian/errmsg.txt:
new error message
sql/share/french/errmsg.txt:
new error message
sql/share/german/errmsg.txt:
new error message
sql/share/greek/errmsg.txt:
new error message
sql/share/hungarian/errmsg.txt:
new error message
sql/share/italian/errmsg.txt:
new error message
sql/share/japanese/errmsg.txt:
new error message
sql/share/korean/errmsg.txt:
new error message
sql/share/norwegian-ny/errmsg.txt:
new error message
sql/share/norwegian/errmsg.txt:
new error message
sql/share/polish/errmsg.txt:
new error message
sql/share/portuguese/errmsg.txt:
new error message
sql/share/romanian/errmsg.txt:
new error message
sql/share/russian/errmsg.txt:
new error message
sql/share/serbian/errmsg.txt:
new error message
sql/share/slovak/errmsg.txt:
new error message
sql/share/spanish/errmsg.txt:
new error message
sql/share/swedish/errmsg.txt:
new error message
sql/share/ukrainian/errmsg.txt:
new error message
Diffstat (limited to 'sql')
36 files changed, 242 insertions, 37 deletions
diff --git a/sql/item.cc b/sql/item.cc index ea797679957..f317759553b 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -42,6 +42,20 @@ Item::Item() decimals=0; max_length=0; next=current_thd->free_list; // Put in free list current_thd->free_list=this; + loop_id= 0; +} + +bool Item::check_loop(uint id) +{ + DBUG_ENTER("Item::check_loop"); + DBUG_PRINT("info", ("id %u, name %s", id, name)); + if (loop_id == id) + { + DBUG_PRINT("info", ("id match")); + DBUG_RETURN(1); + } + loop_id= id; + DBUG_RETURN(0); } void Item::set_name(const char *str,uint length) @@ -862,6 +876,11 @@ 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; + } } } else if (!ref) @@ -873,6 +892,14 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) return 0; } +bool Item_ref::check_loop(uint id) +{ + DBUG_ENTER("Item_ref::check_loop"); + if (Item_ident::check_loop(id)) + DBUG_RETURN(1); + DBUG_RETURN((*ref)->check_loop(id)); +} + /* ** If item is a const function, calculate it and return a const item ** The original item is freed if not returned diff --git a/sql/item.h b/sql/item.h index fb6bed75d51..c67c16c50ad 100644 --- a/sql/item.h +++ b/sql/item.h @@ -20,10 +20,11 @@ #endif struct st_table_list; -void item_init(void); /* Init item functions */ +void item_init(void); /* Init item functions */ class Item { - Item(const Item &); /* Prevent use of these */ + uint loop_id; /* Used to find selfrefering loops */ + Item(const Item &); /* Prevent use of these */ void operator=(Item &); public: static void *operator new(size_t size) {return (void*) sql_alloc((uint) size); } @@ -88,6 +89,8 @@ public: virtual CHARSET_INFO *charset() const { return str_value.charset(); }; virtual bool binary() const { return str_value.charset()->state & MY_CS_BINSORT ? 1 : 0 ; } virtual void set_charset(CHARSET_INFO *cs) { str_value.set_charset(cs); } + + virtual bool check_loop(uint id); }; @@ -434,6 +437,7 @@ public: void save_org_in_field(Field *field) { (*ref)->save_org_in_field(field); } enum Item_result result_type () const { return (*ref)->result_type(); } table_map used_tables() const { return (*ref)->used_tables(); } + bool check_loop(uint id); }; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index b6ea4beb339..744ed1bceca 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -344,6 +344,14 @@ void Item_func_interval::update_used_tables() const_item_cache&=item->const_item(); } +bool Item_func_interval::check_loop(uint id) +{ + DBUG_ENTER("Item_func_interval::check_loop"); + if (Item_func::check_loop(id)) + DBUG_RETURN(1); + DBUG_RETURN(item->check_loop(id)); +} + void Item_func_between::fix_length_and_dec() { max_length=1; @@ -776,6 +784,16 @@ Item_func_case::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) return 0; } +bool Item_func_case::check_loop(uint id) +{ + DBUG_ENTER("Item_func_case::check_loop"); + if (Item_func::check_loop(id)) + DBUG_RETURN(1); + + DBUG_RETURN((first_expr && first_expr->check_loop(id)) || + (else_expr && else_expr->check_loop(id))); +} + void Item_func_case::update_used_tables() { Item_func::update_used_tables(); @@ -1137,6 +1155,20 @@ Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) return 0; } +bool Item_cond::check_loop(uint id) +{ + DBUG_ENTER("Item_cond::check_loop"); + if (Item_func::check_loop(id)) + DBUG_RETURN(1); + List_iterator<Item> li(list); + Item *item; + while ((item= li++)) + { + if (item->check_loop(id)) + DBUG_RETURN(1); + } + DBUG_RETURN(0); +} void Item_cond::split_sum_func(List<Item> &fields) { diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index c0dcc2bba8f..489d54ae786 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -186,6 +186,7 @@ public: ~Item_func_interval() { delete item; } const char *func_name() const { return "interval"; } void update_used_tables(); + bool check_loop(uint id); }; @@ -262,6 +263,7 @@ public: void print(String *str); bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref); Item *find_item(String *str); + bool check_loop(uint id); }; @@ -424,6 +426,13 @@ class Item_func_in :public Item_int_func enum Functype functype() const { return IN_FUNC; } const char *func_name() const { return " IN "; } void update_used_tables(); + bool check_loop(uint id) + { + DBUG_ENTER("Item_func_in::check_loop"); + if (Item_func::check_loop(id)) + DBUG_RETURN(1); + DBUG_RETURN(item->check_loop(id)); + } }; @@ -563,6 +572,7 @@ public: void print(String *str); void split_sum_func(List<Item> &fields); friend int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds); + bool check_loop(uint id); }; diff --git a/sql/item_func.cc b/sql/item_func.cc index 543a96107dc..aa39b3cc857 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -126,6 +126,22 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) return 0; } +bool Item_func::check_loop(uint id) +{ + DBUG_ENTER("Item_func::check_loop"); + if (Item_result_field::check_loop(id)) + DBUG_RETURN(1); + if (arg_count) + { + Item **arg,**arg_end; + for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++) + { + if ((*arg)->check_loop(id)) + DBUG_RETURN(1); + } + } + DBUG_RETURN(0); +} void Item_func::split_sum_func(List<Item> &fields) { @@ -2264,6 +2280,19 @@ bool Item_func_match::fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) return 0; } +bool Item_func_match::check_loop(uint id) +{ + DBUG_ENTER("Item_func_match::check_loop"); + if (Item_real_func::check_loop(id)) + DBUG_RETURN(1); + + List_iterator<Item> li(fields); + Item *item; + while ((item= li++)) + if (item->check_loop(id)) + DBUG_RETURN(1); + DBUG_RETURN(0); +} bool Item_func_match::fix_index() { diff --git a/sql/item_func.h b/sql/item_func.h index 1e1f2ba39fc..581809fc9cb 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -128,6 +128,7 @@ public: bool is_null() { (void) val_int(); return null_value; } friend class udf_handler; Field *tmp_table_field(TABLE *t_arg); + bool check_loop(uint id); }; @@ -606,6 +607,13 @@ public: const_item_cache&= item->const_item(); with_sum_func= with_sum_func || item->with_sum_func; } + bool check_loop(uint id) + { + DBUG_ENTER("Item_func_field::check_loop"); + if (Item_int_func::check_loop(id)) + DBUG_RETURN(1); + DBUG_RETURN(item->check_loop(id)); + } }; @@ -971,6 +979,7 @@ public: bool fix_index(); void init_search(bool no_order); + bool check_loop(uint id); }; diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 1a3193318b6..2b308630b48 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -105,6 +105,13 @@ public: || Item_func::fix_fields(thd, tlist, ref)); } const char *func_name() const { return "concat_ws"; } + bool check_loop(uint id) + { + DBUG_ENTER("Item_func_concat_ws::check_loop"); + if (Item_str_func::check_loop(id)) + DBUG_RETURN(1); + DBUG_RETURN(separator->check_loop(id)); + } }; class Item_func_reverse :public Item_str_func @@ -361,6 +368,13 @@ public: void fix_length_and_dec(); void update_used_tables(); const char *func_name() const { return "elt"; } + bool check_loop(uint id) + { + DBUG_ENTER("Item_func_elt::check_loop"); + if (Item_str_func::check_loop(id)) + DBUG_RETURN(1); + DBUG_RETURN(item->check_loop(id)); + } }; @@ -381,6 +395,13 @@ public: void fix_length_and_dec(); void update_used_tables(); const char *func_name() const { return "make_set"; } + bool check_loop(uint id) + { + DBUG_ENTER("Item_func_make_set::check_loop"); + if (Item_str_func::check_loop(id)) + DBUG_RETURN(1); + DBUG_RETURN(item->check_loop(id)); + } }; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 37c85501b06..1f1944026ef 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -95,6 +95,15 @@ bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) return res; } +bool Item_subselect::check_loop(uint id) +{ + DBUG_ENTER("Item_subselect::check_loop"); + if (Item_result_field::check_loop(id)) + DBUG_RETURN(1); + + DBUG_RETURN(engine->check_loop(id)); +} + void Item_subselect::fix_length_and_dec() { engine->fix_length_and_dec(); @@ -228,6 +237,7 @@ subselect_single_select_engine::subselect_single_select_engine(THD *thd, thd->fatal_error= 1; my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); } + unit->item= item; this->select_lex= select_lex; } @@ -353,3 +363,18 @@ bool subselect_union_engine::depended() { return unit->dependent; } + +bool subselect_single_select_engine::check_loop(uint id) +{ + DBUG_ENTER("subselect_single_select_engine::check_loop"); + DBUG_RETURN(join->check_loop(id)); +} + +bool subselect_union_engine::check_loop(uint id) +{ + DBUG_ENTER("subselect_union_engine::check_loop"); + for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select()) + if (sl->join && sl->join->check_loop(id)) + DBUG_RETURN(1); + DBUG_RETURN(0); +} diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 58726f16ba9..3ad6c68a6ba 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -70,6 +70,7 @@ public: bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref); virtual void fix_length_and_dec(); table_map used_tables() const; + bool check_loop(uint id); friend class select_subselect; }; @@ -176,6 +177,7 @@ public: virtual uint cols()= 0; /* return number of columnss in select */ virtual bool depended()= 0; /* depended from outer select */ enum Item_result type() { return res_type; } + virtual bool check_loop(uint id)= 0; }; class subselect_single_select_engine: public subselect_engine @@ -189,11 +191,12 @@ public: subselect_single_select_engine(THD *thd, st_select_lex *select, select_subselect *result, Item_subselect *item); - virtual int prepare(); - virtual void fix_length_and_dec(); - virtual int exec(); - virtual uint cols(); - virtual bool depended(); + int prepare(); + void fix_length_and_dec(); + int exec(); + uint cols(); + bool depended(); + bool check_loop(uint id); }; class subselect_union_engine: public subselect_engine @@ -204,9 +207,10 @@ public: st_select_lex_unit *u, select_subselect *result, Item_subselect *item); - virtual int prepare(); - virtual void fix_length_and_dec(); - virtual int exec(); - virtual uint cols(); - virtual bool depended(); + int prepare(); + void fix_length_and_dec(); + int exec(); + uint cols(); + bool depended(); + bool check_loop(uint id); }; diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index c8ac594f00b..d43a433da06 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -252,4 +252,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist",
\ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 5638260277e..3a947bcbe38 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -246,4 +246,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist",
\ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index acbda2829d0..1cb81849be1 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -254,4 +254,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist",
\ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 36d8831fd39..6e96fdb393e 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -243,4 +243,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist",
\ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 96bd758cc6a..394c40c5778 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -248,4 +248,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist",
\ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 932182a2c94..b18d3f8fb38 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -243,4 +243,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist",
\ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index febd723df89..49ea31dd05b 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -246,4 +246,5 @@ "Subselect return more than 1 field", "Subselect return more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist",
\ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 9d9aa07af8d..b203c63949b 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -243,4 +243,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist",
\ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index d596c8f3433..07081e689ad 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -245,4 +245,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist",
\ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index d9ccf54d7ea..0a380e2b48f 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -243,4 +243,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist",
\ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 22a53801efd..2e0a083ca06 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -245,4 +245,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist",
\ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 27a8fdde027..19fcf98e3c7 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -243,4 +243,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist",
\ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 8e8b5aa7e61..810aaf38f74 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -245,4 +245,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist",
\ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 0f4650c186c..a74a0a910b8 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -245,4 +245,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist",
\ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 758e96e5ca3..efde31ff4c9 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -247,4 +247,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist",
\ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 21ebe5c39dc..e90d5844b9b 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -243,4 +243,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist",
\ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index c84049d6192..18f0bf7f79d 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -247,4 +247,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist",
\ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 0ee79ce5811..790d738031c 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -246,4 +246,5 @@ "Подзапрос возвращает более одного поля", "Подзапрос возвращает более одной записи", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist",
\ No newline at end of file +"Help database is corrupt or does not exist", +"Циклическая ссылка на подзапрос", diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index d120630b636..e8186d38a5b 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -239,4 +239,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist",
\ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index eb9e2a240a0..216d46fcd3a 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -251,4 +251,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist",
\ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 0b7de283481..5076b1b6679 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -244,4 +244,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist",
\ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 052cd1506d3..a3bb40fb4f5 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -243,4 +243,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist",
\ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 5cfad494a32..426c2a14e3b 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -248,4 +248,5 @@ "Пiдзапит поверта╓ бiльш нiж 1 стовбець", "Пiдзапит поверта╓ бiльш нiж 1 запис", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist",
\ No newline at end of file +"Help database is corrupt or does not exist", +"Циклiчне посилання на пiдзапит", diff --git a/sql/sql_class.h b/sql/sql_class.h index 08066e83ee7..6f6547a358c 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -494,6 +494,7 @@ public: uint32 query_length; uint32 db_length; uint select_number; //number of select (used for EXPLAIN) + uint check_loops_counter; //last id used to check loops /* variables.transaction_isolation is reset to this after each commit */ enum_tx_isolation session_tx_isolation; char scramble[9]; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 6a2c8e17185..1586469de42 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2867,7 +2867,8 @@ mysql_init_query(THD *thd) lex->select_lex.prev= &lex->unit.slave; lex->olap=lex->describe=0; lex->derived_tables= false; - thd->select_number= lex->select_lex.select_number= 1; + thd->check_loops_counter= thd->select_number= + lex->select_lex.select_number= 1; thd->free_list= 0; thd->total_warn_count=0; // Warnings for this query thd->last_insert_id_used= thd->query_start_used= thd->insert_id_used=0; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 5f4bfc5462a..dd84b2a46c8 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1035,6 +1035,24 @@ JOIN::cleanup(THD *thd) DBUG_RETURN(error); } +bool JOIN::check_loop(uint id) +{ + DBUG_ENTER("JOIN::check_loop"); + Item *item; + List_iterator<Item> it(all_fields); + DBUG_PRINT("info", ("all_fields:")); + while ((item= it++)) + if (item->check_loop(id)) + DBUG_RETURN(1); + DBUG_PRINT("info", ("where:")); + if (select_lex->where && select_lex->where->check_loop(id)) + DBUG_RETURN(1); + DBUG_PRINT("info", ("having:")); + if (select_lex->having && select_lex->having->check_loop(id)) + DBUG_RETURN(1); + DBUG_RETURN(0); +} + int mysql_select(THD *thd, TABLE_LIST *tables, List<Item> &fields, COND *conds, ORDER *order, ORDER *group,Item *having, ORDER *proc_param, diff --git a/sql/sql_select.h b/sql/sql_select.h index c5b5357be50..3b89c1ce0d3 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -244,7 +244,8 @@ class JOIN :public Sql_alloc int global_optimize(); int reinit(); void exec(); - int cleanup(THD *thd); + int cleanup(THD *thd); + bool check_loop(uint id); }; |