From de5e96e443c2509a5750ef2c8569430fbdbb2722 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 20 Jun 2003 10:15:58 +0300 Subject: fixed BUG #679 outer resolved fields now do not marked as dependent if they is not really belong to outer SELECT one-letter variables name fixed mysql-test/r/subselect.result: test of bug 679 mysql-test/t/subselect.test: test of bug 679 sql/item.cc: outer resolved fields now do not marked as dependent if they is not really belong to outer SELECT one-letter variables name fixed --- sql/item.cc | 78 ++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 27 deletions(-) (limited to 'sql') diff --git a/sql/item.cc b/sql/item.cc index 868cf4466a6..0f16f07ed52 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -23,6 +23,10 @@ #include #include "my_dir.h" +static void mark_as_dependent(bool outer_resolving, + SELECT_LEX *last, SELECT_LEX_NODE *current, + Item_ident *item); + /***************************************************************************** ** Item functions *****************************************************************************/ @@ -769,6 +773,37 @@ bool Item_ref_null_helper::get_date(TIME *ltime, bool fuzzydate) return (owner->was_null|= null_value= (*ref)->get_date(ltime, fuzzydate)); } + +/* + Mark item and SELECT_LEXs as dependent if it is not outer resolving + + SYNOPSIS + mark_as_dependent() + outer_resolving - flag of outer resolving + last - select from which current item depend + current - current select + item - item which should be marked +*/ + +static void mark_as_dependent(bool outer_resolving, + SELECT_LEX *last, SELECT_LEX_NODE *current, + Item_ident *item) +{ + /* + only last check is need, i.e. + "last != current" + first check added for speed up (check boolean should be faster + then comparing pointers and this condition usually true) + */ + if (!outer_resolving || ((SELECT_LEX_NODE *)last) != current) + { + // store pointer on SELECT_LEX from wich item is dependent + item->depended_from= last; + current->mark_as_dependent(last); + } +} + + bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { if (!field) // If field is not checked @@ -833,29 +868,22 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) return -1; } - Item_ref *r; - *ref= r= new Item_ref(last->ref_pointer_array + counter - , (char *)table_name, - (char *)field_name); - if (!r) + Item_ref *rf; + *ref= rf= new Item_ref(last->ref_pointer_array + counter, + (char *)table_name, + (char *)field_name); + if (!rf) return 1; - if (r->fix_fields(thd, tables, ref) || r->check_cols(1)) + if (rf->fix_fields(thd, tables, ref) || rf->check_cols(1)) return 1; - // store pointer on SELECT_LEX from which item is dependent - r->depended_from= last; - cursel->mark_as_dependent(last); + + mark_as_dependent(outer_resolving, last, cursel, rf); return 0; } else { - // store pointer on SELECT_LEX from wich item is dependent - depended_from= last; - /* - Mark all selects from resolved to 1 before select where was - found table as depended (of select where was found table) - */ - thd->lex.current_select->mark_as_dependent(last); - if (depended_from->having_fix_field) + mark_as_dependent(outer_resolving, last, cursel, this); + if (last->having_fix_field) { Item_ref *rf; *ref= rf= new Item_ref((where->db[0]?where->db:0), @@ -1321,12 +1349,10 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) else if (tmp != not_found_field) { ref= 0; // To prevent "delete *ref;" on ~Item_erf() of this item - Item_field* f; - if (!((*reference)= f= new Item_field(tmp))) + Item_field* fld; + if (!((*reference)= fld= new Item_field(tmp))) return 1; - // store pointer on SELECT_LEX from wich item is dependent - f->depended_from= last; - thd->lex.current_select->mark_as_dependent(last); + mark_as_dependent(outer_resolving, last, thd->lex.current_select, fld); return 0; } else @@ -1337,11 +1363,9 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) "forward reference in item list"); return -1; } - /* - depended_from: pointer on SELECT_LEX from wich item is dependent - */ - ref= (depended_from= last)->ref_pointer_array + counter; - thd->lex.current_select->mark_as_dependent(last); + mark_as_dependent(outer_resolving, last, thd->lex.current_select, + this); + ref= last->ref_pointer_array + counter; } } else if (!ref) -- cgit v1.2.1