summaryrefslogtreecommitdiff
path: root/sql/item_subselect.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item_subselect.cc')
-rw-r--r--sql/item_subselect.cc167
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(')');
+}