diff options
Diffstat (limited to 'sql/item_subselect.cc')
-rw-r--r-- | sql/item_subselect.cc | 61 |
1 files changed, 52 insertions, 9 deletions
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index b3744d6eb96..e42387c2237 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -143,6 +143,7 @@ Item_subselect::select_transformer(JOIN *join) bool Item_subselect::fix_fields(THD *thd_param, Item **ref) { char const *save_where= thd_param->where; + uint8 uncacheable; bool res; DBUG_ASSERT(fixed == 0); @@ -188,19 +189,61 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref) fix_length_and_dec(); } else - return 1; - uint8 uncacheable= engine->uncacheable(); - if (uncacheable) + goto err; + + if ((uncacheable= engine->uncacheable())) { const_item_cache= 0; if (uncacheable & UNCACHEABLE_RAND) used_tables_cache|= RAND_TABLE_BIT; } fixed= 1; + +err: thd->where= save_where; return res; } + +bool Item_subselect::walk(Item_processor processor, bool walk_subquery, + byte *argument) +{ + + if (walk_subquery) + { + for (SELECT_LEX *lex= unit->first_select(); lex; lex= lex->next_select()) + { + List_iterator<Item> li(lex->item_list); + Item *item; + ORDER *order; + + if (lex->where && (lex->where)->walk(processor, walk_subquery, argument)) + return 1; + if (lex->having && (lex->having)->walk(processor, walk_subquery, + argument)) + return 1; + + while ((item=li++)) + { + if (item->walk(processor, walk_subquery, argument)) + return 1; + } + for (order= (ORDER*) lex->order_list.first ; order; order= order->next) + { + if ((*order->item)->walk(processor, walk_subquery, argument)) + return 1; + } + for (order= (ORDER*) lex->group_list.first ; order; order= order->next) + { + if ((*order->item)->walk(processor, walk_subquery, argument)) + return 1; + } + } + } + return (this->*processor)(argument); +} + + bool Item_subselect::exec() { int res; @@ -405,7 +448,7 @@ Item_singlerow_subselect::select_transformer(JOIN *join) as far as we moved content to upper level, field which depend of 'upper' select is not really dependent => we remove this dependence */ - substitution->walk(&Item::remove_dependence_processor, + substitution->walk(&Item::remove_dependence_processor, 0, (byte *) select_lex->outer_select()); return RES_REDUCE; } @@ -1702,7 +1745,7 @@ void subselect_engine::set_row(List<Item> &item_list, Item_cache **row) Item *sel_item; List_iterator_fast<Item> li(item_list); res_type= STRING_RESULT; - res_field_type= FIELD_TYPE_VAR_STRING; + res_field_type= MYSQL_TYPE_VAR_STRING; for (uint i= 0; (sel_item= li++); i++) { item->max_length= sel_item->max_length; @@ -2000,7 +2043,7 @@ int subselect_uniquesubquery_engine::exec() DBUG_RETURN(scan_table()); if (!table->file->inited) - table->file->ha_index_init(tab->ref.key); + table->file->ha_index_init(tab->ref.key, 0); error= table->file->index_read(table->record[0], tab->ref.key_buff, tab->ref.key_length,HA_READ_KEY_EXACT); @@ -2109,7 +2152,7 @@ int subselect_indexsubquery_engine::exec() DBUG_RETURN(scan_table()); if (!table->file->inited) - table->file->ha_index_init(tab->ref.key); + table->file->ha_index_init(tab->ref.key, 1); error= table->file->index_read(table->record[0], tab->ref.key_buff, tab->ref.key_length,HA_READ_KEY_EXACT); @@ -2245,7 +2288,7 @@ void subselect_uniquesubquery_engine::print(String *str) str->append(STRING_WITH_LEN("<primary_index_lookup>(")); tab->ref.items[0]->print(str); str->append(STRING_WITH_LEN(" in ")); - str->append(tab->table->s->table_name); + str->append(tab->table->s->table_name.str, tab->table->s->table_name.length); KEY *key_info= tab->table->key_info+ tab->ref.key; str->append(STRING_WITH_LEN(" on ")); str->append(key_info->name); @@ -2263,7 +2306,7 @@ void subselect_indexsubquery_engine::print(String *str) str->append(STRING_WITH_LEN("<index_lookup>(")); tab->ref.items[0]->print(str); str->append(STRING_WITH_LEN(" in ")); - str->append(tab->table->s->table_name); + str->append(tab->table->s->table_name.str, tab->table->s->table_name.length); KEY *key_info= tab->table->key_info+ tab->ref.key; str->append(STRING_WITH_LEN(" on ")); str->append(key_info->name); |