diff options
Diffstat (limited to 'sql/item_subselect.cc')
-rw-r--r-- | sql/item_subselect.cc | 167 |
1 files changed, 161 insertions, 6 deletions
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 5e0221ad6c7..3653823254e 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -141,17 +141,28 @@ Item::Type Item_subselect::type() const return SUBSELECT_ITEM; } + void Item_subselect::fix_length_and_dec() { engine->fix_length_and_dec(0); } + inline table_map Item_subselect::used_tables() const { return (table_map) (engine->dependent() ? 1L : (engine->uncacheable() ? RAND_TABLE_BIT : 0L)); } + +void Item_subselect::print(String *str) +{ + str->append('('); + engine->print(str); + str->append(')'); +} + + Item_singlerow_subselect::Item_singlerow_subselect(st_select_lex *select_lex) :Item_subselect(), value(0) { @@ -164,17 +175,24 @@ Item_singlerow_subselect::Item_singlerow_subselect(st_select_lex *select_lex) } Item_maxmin_subselect::Item_maxmin_subselect(st_select_lex *select_lex, - bool max) + bool max_arg) :Item_singlerow_subselect() { DBUG_ENTER("Item_maxmin_subselect::Item_maxmin_subselect"); - init(select_lex, new select_max_min_finder_subselect(this, max)); + max= max_arg; + init(select_lex, new select_max_min_finder_subselect(this, max_arg)); max_columns= 1; maybe_null= 1; max_columns= 1; DBUG_VOID_RETURN; } +void Item_maxmin_subselect::print(String *str) +{ + str->append(max?"<max>":"<min>"); + Item_singlerow_subselect::print(str); +} + void Item_singlerow_subselect::reset() { null_value= 1; @@ -217,7 +235,7 @@ Item_singlerow_subselect::select_transformer(JOIN *join) */ substitution->walk(&Item::remove_dependence_processor, (byte *) select_lex->outer_select()); - if (select_lex->where || select_lex->having) + if (join->conds || join->having) { Item *cond; if (!join->having) @@ -337,6 +355,7 @@ String *Item_singlerow_subselect::val_str (String *str) } } + Item_exists_subselect::Item_exists_subselect(st_select_lex *select_lex): Item_subselect() { @@ -351,6 +370,14 @@ Item_exists_subselect::Item_exists_subselect(st_select_lex *select_lex): DBUG_VOID_RETURN; } + +void Item_exists_subselect::print(String *str) +{ + str->append("exists"); + Item_subselect::print(str); +} + + bool Item_in_subselect::test_limit(SELECT_LEX_UNIT *unit) { if (unit->fake_select_lex && @@ -368,7 +395,7 @@ bool Item_in_subselect::test_limit(SELECT_LEX_UNIT *unit) Item_in_subselect::Item_in_subselect(Item * left_exp, st_select_lex *select_lex): - Item_exists_subselect(), upper_not(0) + Item_exists_subselect(), transformed(0), upper_not(0) { DBUG_ENTER("Item_in_subselect::Item_in_subselect"); left_expr= left_exp; @@ -384,8 +411,9 @@ Item_in_subselect::Item_in_subselect(Item * left_exp, Item_allany_subselect::Item_allany_subselect(Item * left_exp, compare_func_creator fn, - st_select_lex *select_lex) - :Item_in_subselect() + st_select_lex *select_lex, + bool all_arg) + :Item_in_subselect(), all(all_arg) { DBUG_ENTER("Item_in_subselect::Item_in_subselect"); left_expr= left_exp; @@ -758,6 +786,7 @@ Item_in_subselect::row_value_transformer(JOIN *join, Item_subselect::trans_res Item_in_subselect::select_transformer(JOIN *join) { + transformed= 1; if (left_expr->cols() == 1) return single_value_transformer(join, left_expr, &Item_bool_func2::eq_creator); @@ -765,12 +794,82 @@ Item_in_subselect::select_transformer(JOIN *join) } +void Item_in_subselect::print(String *str) +{ + if (transformed) + str->append("<exists>"); + else + { + left_expr->print(str); + str->append(" in "); + } + Item_subselect::print(str); +} + + Item_subselect::trans_res Item_allany_subselect::select_transformer(JOIN *join) { + transformed= 1; + if (upper_not) + upper_not->show= 1; return single_value_transformer(join, left_expr, func); } + +void Item_allany_subselect::print(String *str) +{ + if (transformed) + str->append("<exists>"); + else + { + left_expr->print(str); + str->append(' '); + if (all) + { + if (func == &Item_bool_func2::lt_creator) + str->append(">="); + else if (func == &Item_bool_func2::gt_creator) + str->append("<="); + else if (func == &Item_bool_func2::le_creator) + str->append('>'); + else if (func == &Item_bool_func2::ge_creator) + str->append('<'); + else if (func == &Item_bool_func2::eq_creator) + str->append("<>"); + else if (func == &Item_bool_func2::ne_creator) + str->append('='); + else + { + DBUG_ASSERT(0); // Impossible + } + str->append(" all "); + } + else + { + if (func == &Item_bool_func2::lt_creator) + str->append('<'); + else if (func == &Item_bool_func2::gt_creator) + str->append('>'); + else if (func == &Item_bool_func2::le_creator) + str->append("<="); + else if (func == &Item_bool_func2::ge_creator) + str->append(">="); + else if (func == &Item_bool_func2::eq_creator) + str->append('='); + else if (func == &Item_bool_func2::ne_creator) + str->append("<>"); + else + { + DBUG_ASSERT(0); // Impossible + } + str->append(" any "); + } + } + Item_subselect::print(str); +} + + subselect_single_select_engine:: subselect_single_select_engine(st_select_lex *select, select_subselect *result, @@ -1098,11 +1197,13 @@ uint subselect_single_select_engine::cols() return select_lex->item_list.elements; } + uint subselect_union_engine::cols() { return unit->first_select()->item_list.elements; } + bool subselect_single_select_engine::dependent() { return select_lex->dependent; @@ -1113,16 +1214,19 @@ bool subselect_union_engine::dependent() return unit->dependent; } + bool subselect_single_select_engine::uncacheable() { return select_lex->uncacheable; } + bool subselect_union_engine::uncacheable() { return unit->uncacheable; } + void subselect_single_select_engine::exclude() { select_lex->master_unit()->exclude_level(); @@ -1133,8 +1237,59 @@ void subselect_union_engine::exclude() unit->exclude_level(); } + void subselect_uniquesubquery_engine::exclude() { //this never should be called DBUG_ASSERT(0); } + + +void subselect_single_select_engine::print(String *str) +{ + select_lex->print(thd, str); +} + + +void subselect_union_engine::print(String *str) +{ + unit->print(str); +} + + +void subselect_uniquesubquery_engine::print(String *str) +{ + str->append("<primary_index_lookup>("); + tab->ref.items[0]->print(str); + str->append(" in "); + str->append(tab->table->real_name); + KEY *key_info= tab->table->key_info+ tab->ref.key; + str->append(" on "); + str->append(key_info->name); + if (cond) + { + str->append(" where "); + cond->print(str); + } + str->append(')'); +} + + +void subselect_indexsubquery_engine::print(String *str) +{ + str->append("<index_lookup>("); + tab->ref.items[0]->print(str); + str->append(" in "); + str->append(tab->table->real_name); + KEY *key_info= tab->table->key_info+ tab->ref.key; + str->append(" on "); + str->append(key_info->name); + if (check_null) + str->append(" chicking NULL"); + if (cond) + { + str->append(" where "); + cond->print(str); + } + str->append(')'); +} |