diff options
Diffstat (limited to 'sql/item.cc')
-rw-r--r-- | sql/item.cc | 27 |
1 files changed, 27 insertions, 0 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 |