diff options
Diffstat (limited to 'sql/item.cc')
-rw-r--r-- | sql/item.cc | 156 |
1 files changed, 39 insertions, 117 deletions
diff --git a/sql/item.cc b/sql/item.cc index 17b0519b61c..86fa2d82c41 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -23,8 +23,7 @@ #include <m_ctype.h> #include "my_dir.h" -static void mark_as_dependent(bool outer_resolving, - SELECT_LEX *last, SELECT_LEX_NODE *current, +static void mark_as_dependent(SELECT_LEX *last, SELECT_LEX *current, Item_ident *item); /***************************************************************************** @@ -50,7 +49,7 @@ Item::Item(): next= thd->free_list; // Put in free list thd->free_list= this; /* - Item constructor can be called during execution other tnen SQL_COM + Item constructor can be called during execution other then SQL_COM command => we should check thd->lex.current_select on zero (thd->lex can be uninitialised) */ @@ -95,6 +94,15 @@ Item_ident::Item_ident(THD *thd, Item_ident &item): depended_from(item.depended_from) {} +bool Item_ident::remove_dependence_processor(byte * arg) +{ + DBUG_ENTER("Item_ident::remove_dependence_processor"); + if (depended_from == (st_select_lex *) arg) + depended_from= 0; + DBUG_RETURN(1); +} + + bool Item::check_cols(uint c) { if (c != 1) @@ -714,73 +722,6 @@ bool Item::fix_fields(THD *thd, return 0; } -bool Item_asterisk_remover::fix_fields(THD *thd, - struct st_table_list *list, - Item ** ref) -{ - DBUG_ENTER("Item_asterisk_remover::fix_fields"); - - bool res= 1; - if (item) - if (item->type() == Item::FIELD_ITEM && - ((Item_field*) item)->field_name[0] == '*') - { - Item_field *fitem= (Item_field*) item; - if (list) - if (!list->next || fitem->db_name || fitem->table_name) - { - TABLE_LIST *table= find_table_in_list(list, - fitem->db_name, - fitem->table_name); - if (table) - { - TABLE * tb= table->table; - if (find_table_in_list(table->next, fitem->db_name, - fitem->table_name) != 0 || - tb->fields == 1) - { - if ((item= new Item_field(tb->field[0]))) - { - res= 0; - tb->field[0]->query_id= thd->query_id; - tb->used_keys&= tb->field[0]->part_of_key; - tb->used_fields= tb->fields; - } - else - thd->fatal_error(); // can't create Item => out of memory - } - else - my_error(ER_CARDINALITY_COL, MYF(0), 1); - } - else - my_error(ER_BAD_TABLE_ERROR, MYF(0), fitem->table_name); - } - else - my_error(ER_CARDINALITY_COL, MYF(0), 1); - else - my_error(ER_NO_TABLES_USED, MYF(0)); - } - else - res= item->fix_fields(thd, list, &item); - else - thd->fatal_error(); // no item given => out of memory - DBUG_RETURN(res); -} - -bool Item_ref_on_list_position::fix_fields(THD *thd, - struct st_table_list *tables, - Item ** reference) -{ - if (select_lex->item_list.elements <= pos) - { - ref= 0; - my_error(ER_CARDINALITY_COL, MYF(0), pos); - return 1; - } - ref= select_lex->ref_pointer_array + pos; - return Item_ref_null_helper::fix_fields(thd, tables, reference); -} - double Item_ref_null_helper::val() { double tmp= (*ref)->val_result(); @@ -810,28 +751,17 @@ bool Item_ref_null_helper::get_date(TIME *ltime, bool fuzzydate) 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, +static void mark_as_dependent(SELECT_LEX *last, SELECT_LEX *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); - } + // store pointer on SELECT_LEX from wich item is dependent + item->depended_from= last; + current->mark_as_dependent(last); } @@ -841,8 +771,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { TABLE_LIST *where= 0; Field *tmp= (Field *)not_found_field; - if (outer_resolving || - (tmp= find_field_in_tables(thd, this, tables, &where, 0)) == + if ((tmp= find_field_in_tables(thd, this, tables, &where, 0)) == not_found_field) { /* @@ -863,9 +792,8 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) uint counter; // Prevent using outer fields in subselects, that is not supported now SELECT_LEX *cursel=(SELECT_LEX *) thd->lex.current_select; - if (outer_resolving || - cursel->master_unit()->first_select()->linkage != DERIVED_TABLE_TYPE) - for (SELECT_LEX *sl=(outer_resolving?cursel:cursel->outer_select()); + if (cursel->master_unit()->first_select()->linkage != DERIVED_TABLE_TYPE) + for (SELECT_LEX *sl= cursel->outer_select(); sl; sl= sl->outer_select()) { @@ -916,12 +844,12 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) if (rf->fix_fields(thd, tables, ref) || rf->check_cols(1)) return 1; - mark_as_dependent(outer_resolving, last, cursel, rf); + mark_as_dependent(last, cursel, rf); return 0; } else { - mark_as_dependent(outer_resolving, last, cursel, this); + mark_as_dependent(last, cursel, this); if (last->having_fix_field) { Item_ref *rf; @@ -930,7 +858,6 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) (char *)field_name); if (!rf) return 1; - (rf)->outer_resolving= outer_resolving; return rf->fix_fields(thd, tables, ref) || rf->check_cols(1); } } @@ -1325,16 +1252,13 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) if (!ref) { TABLE_LIST *where= 0, *table_list; - SELECT_LEX *sl= (outer_resolving? - thd->lex.current_select->select_lex(): - thd->lex.current_select->outer_select()); + SELECT_LEX *sl= thd->lex.current_select->outer_select(); /* Finding only in current select will be performed for selects that have not outer one and for derived tables (which not support using outer fields for now) */ - if (outer_resolving || - (ref= find_item_in_list(this, + if ((ref= find_item_in_list(this, *(thd->lex.current_select->get_item_list()), &counter, ((sl && @@ -1400,7 +1324,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) Item_field* fld; if (!((*reference)= fld= new Item_field(tmp))) return 1; - mark_as_dependent(outer_resolving, last, thd->lex.current_select, fld); + mark_as_dependent(last, thd->lex.current_select, fld); return 0; } else @@ -1411,7 +1335,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) "forward reference in item list"); return -1; } - mark_as_dependent(outer_resolving, last, thd->lex.current_select, + mark_as_dependent(last, thd->lex.current_select, this); ref= last->ref_pointer_array + counter; } @@ -1430,19 +1354,17 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) } } -/* - * The following conditional is changed as to correctly identify - * incorrect references in group functions or forward references - * with sub-select's / derived tables, while it prevents this - * check when Item_ref is created in an expression involving - * summing function, which is to be placed in the user variable. - * - */ - + /* + The following conditional is changed as to correctly identify + incorrect references in group functions or forward references + with sub-select's / derived tables, while it prevents this + check when Item_ref is created in an expression involving + summing function, which is to be placed in the user variable. + */ if (((*ref)->with_sum_func && name && - (depended_from || + (depended_from || !(thd->lex.current_select->linkage != GLOBAL_OPTIONS_TYPE && - thd->lex.current_select->select_lex()->having_fix_field))) || + thd->lex.current_select->having_fix_field))) || !(*ref)->fixed) { my_error(ER_ILLEGAL_REFERENCE, MYF(0), name, @@ -1687,11 +1609,11 @@ Item_cache* Item_cache::get_cache(Item_result type) void Item_cache_str::store(Item *item) { - str_value.set(buffer, sizeof(buffer), item->collation.collation); - value= item->str_result(&str_value); + value_buff.set(buffer, sizeof(buffer), item->collation.collation); + value= item->str_result(&value_buff); if ((null_value= item->null_value)) value= 0; - else if (value != &str_value) + else if (value != &value_buff) { /* We copy string value to avoid changing value if 'item' is table field @@ -1701,10 +1623,10 @@ void Item_cache_str::store(Item *item) (select c from t1 where a=t2.a) from t2; */ - str_value.copy(*value); - value= &str_value; + value_buff.copy(*value); + value= &value_buff; } - + collation.set(item->collation); } double Item_cache_str::val() { |