diff options
Diffstat (limited to 'sql/item_subselect.cc')
-rw-r--r-- | sql/item_subselect.cc | 112 |
1 files changed, 48 insertions, 64 deletions
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 96d3bea6685..8e4c5dcbbf1 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -45,7 +45,7 @@ double get_post_group_estimate(JOIN* join, double join_op_rows); -const char *exists_outer_expr_name= "<exists outer expr>"; +LEX_CSTRING exists_outer_expr_name= { STRING_WITH_LEN("<exists outer expr>") }; int check_and_do_in_subquery_rewrites(JOIN *join); @@ -64,7 +64,6 @@ Item_subselect::Item_subselect(THD *thd_arg): #ifndef DBUG_OFF exec_counter= 0; #endif - with_subselect= 1; reset(); /* Item value is NULL if select_result_interceptor didn't change this value @@ -118,7 +117,7 @@ void Item_subselect::init(st_select_lex *select_lex, */ parsing_place= (outer_select->in_sum_expr ? NO_MATTER : outer_select->parsing_place); - if (unit->is_union()) + if (unit->is_unit_op()) engine= new subselect_union_engine(unit, result, this); else engine= new subselect_single_select_engine(select_lex, result, this); @@ -290,7 +289,6 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref) (*ref)= substitution; substitution->name= name; - substitution->name_length= name_length; if (have_to_be_excluded) engine->exclude(); substitution= 0; @@ -1067,7 +1065,7 @@ void Item_maxmin_subselect::no_rows_in_result() */ if (parsing_place != SELECT_LIST || const_item()) return; - value= Item_cache::get_cache(thd, new (thd->mem_root) Item_null(thd)); + value= (new (thd->mem_root) Item_null(thd))->get_cache(thd); null_value= 0; was_values= 0; make_const(); @@ -1085,7 +1083,7 @@ void Item_singlerow_subselect::no_rows_in_result() */ if (parsing_place != SELECT_LIST || const_item()) return; - value= Item_cache::get_cache(thd, new (thd->mem_root) Item_null(thd)); + value= (new (thd->mem_root) Item_null(thd))->get_cache(thd); reset(); make_const(); } @@ -1127,7 +1125,7 @@ Item_singlerow_subselect::select_transformer(JOIN *join) SELECT_LEX *select_lex= join->select_lex; Query_arena *arena= thd->stmt_arena; - if (!select_lex->master_unit()->is_union() && + if (!select_lex->master_unit()->is_unit_op() && !select_lex->table_list.elements && select_lex->item_list.elements == 1 && !select_lex->item_list.head()->with_sum_func && @@ -1175,23 +1173,9 @@ void Item_singlerow_subselect::store(uint i, Item *item) row[i]->cache_value(); } -enum Item_result Item_singlerow_subselect::result_type() const +const Type_handler *Item_singlerow_subselect::type_handler() const { - return engine->type(); -} - -enum Item_result Item_singlerow_subselect::cmp_type() const -{ - return engine->cmptype(); -} - -/* - Don't rely on the result type to calculate field type. - Ask the engine instead. -*/ -enum_field_types Item_singlerow_subselect::field_type() const -{ - return engine->field_type(); + return engine->type_handler(); } void Item_singlerow_subselect::fix_length_and_dec() @@ -1262,7 +1246,7 @@ Item* Item_singlerow_subselect::expr_cache_insert_transformer(THD *tmp_thd, } -uint Item_singlerow_subselect::cols() +uint Item_singlerow_subselect::cols() const { return engine->cols(); } @@ -1828,7 +1812,7 @@ Item_in_subselect::single_value_transformer(JOIN *join) if (!(join_having || select_lex->with_sum_func || select_lex->group_list.elements) && select_lex->table_list.elements == 0 && - !select_lex->master_unit()->is_union()) + !select_lex->master_unit()->is_unit_op()) { Item *where_item= (Item*) select_lex->item_list.head(); /* @@ -1888,8 +1872,8 @@ Item_in_subselect::single_value_transformer(JOIN *join) */ expr= new (thd->mem_root) Item_direct_ref(thd, &select_lex->context, (Item**)optimizer->get_cache(), - (char *)"<no matter>", - (char *)in_left_expr_name); + "<no matter>", + &in_left_expr_name); } DBUG_RETURN(false); @@ -2112,6 +2096,8 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join, if (join_having || select_lex->with_sum_func || select_lex->group_list.elements) { + const char *tmp= this->full_name(); + LEX_CSTRING field_name= {tmp, safe_strlen(tmp)}; Item *item= func->create(thd, expr, new (thd->mem_root) Item_ref_null_helper( thd, @@ -2120,7 +2106,7 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join, &select_lex-> ref_pointer_array[0], (char *)"<ref>", - this->full_name())); + &field_name)); if (!abort_on_null && left_expr->maybe_null) { /* @@ -2132,7 +2118,7 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join, } if (!join_having) - item->name= (char*) in_having_cond; + item->name= in_having_cond; if (fix_having(item, select_lex)) DBUG_RETURN(true); *having_item= item; @@ -2157,7 +2143,7 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join, get_cond_guard(0)))) DBUG_RETURN(true); } - having->name= (char*) in_having_cond; + having->name= in_having_cond; if (fix_having(having, select_lex)) DBUG_RETURN(true); *having_item= having; @@ -2182,15 +2168,16 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join, single_value_transformer but there is no corresponding action in row_value_transformer? */ - item->name= (char *) in_additional_cond; + item->name= in_additional_cond; if (!item->fixed && item->fix_fields(thd, 0)) DBUG_RETURN(true); *where_item= item; } else { - if (select_lex->master_unit()->is_union()) + if (select_lex->master_unit()->is_unit_op()) { + LEX_CSTRING field_name= {STRING_WITH_LEN("<result>") }; Item *new_having= func->create(thd, expr, new (thd->mem_root) Item_ref_null_helper(thd, @@ -2198,7 +2185,7 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join, this, &select_lex->ref_pointer_array[0], (char *)"<no matter>", - (char *)"<result>")); + &field_name)); if (!abort_on_null && left_expr->maybe_null) { disable_cond_guard_for_const_null_left_expr(0); @@ -2207,7 +2194,7 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join, DBUG_RETURN(true); } - new_having->name= (char*) in_having_cond; + new_having->name= in_having_cond; if (fix_having(new_having, select_lex)) DBUG_RETURN(true); *having_item= new_having; @@ -2354,7 +2341,7 @@ Item_in_subselect::create_row_in_to_exists_cond(JOIN * join, bool is_having_used= (join_having || select_lex->with_sum_func || select_lex->group_list.first || !select_lex->table_list.elements); - + LEX_CSTRING list_ref= { STRING_WITH_LEN("<list ref>")}; DBUG_ENTER("Item_in_subselect::create_row_in_to_exists_cond"); DBUG_ASSERT(thd == join->thd); @@ -2376,6 +2363,7 @@ Item_in_subselect::create_row_in_to_exists_cond(JOIN * join, if (select_lex->ref_pointer_array[i]-> check_cols(left_expr->element_index(i)->cols())) DBUG_RETURN(true); + Item *item_eq= new (thd->mem_root) Item_func_eq(thd, new (thd->mem_root) @@ -2383,12 +2371,12 @@ Item_in_subselect::create_row_in_to_exists_cond(JOIN * join, (*optimizer->get_cache())-> addr(i), (char *)"<no matter>", - (char *)in_left_expr_name), + &in_left_expr_name), new (thd->mem_root) Item_ref(thd, &select_lex->context, &select_lex->ref_pointer_array[i], (char *)"<no matter>", - (char *)"<list ref>")); + &list_ref)); Item *item_isnull= new (thd->mem_root) Item_func_isnull(thd, @@ -2396,7 +2384,7 @@ Item_in_subselect::create_row_in_to_exists_cond(JOIN * join, Item_ref(thd, &select_lex->context, &select_lex->ref_pointer_array[i], (char *)"<no matter>", - (char *)"<list ref>")); + &list_ref)); Item *col_item= new (thd->mem_root) Item_cond_or(thd, item_eq, item_isnull); if (!abort_on_null && left_expr->element_index(i)->maybe_null && @@ -2417,7 +2405,7 @@ Item_in_subselect::create_row_in_to_exists_cond(JOIN * join, &select_lex-> ref_pointer_array[i], (char *)"<no matter>", - (char *)"<list ref>")); + &list_ref)); if (!abort_on_null && left_expr->element_index(i)->maybe_null && get_cond_guard(i) ) { @@ -2452,13 +2440,13 @@ Item_in_subselect::create_row_in_to_exists_cond(JOIN * join, (*optimizer->get_cache())-> addr(i), (char *)"<no matter>", - (char *)in_left_expr_name), + &in_left_expr_name), new (thd->mem_root) Item_direct_ref(thd, &select_lex->context, &select_lex-> ref_pointer_array[i], (char *)"<no matter>", - (char *)"<list ref>")); + &list_ref)); if (!abort_on_null && select_lex->ref_pointer_array[i]->maybe_null) { Item *having_col_item= @@ -2468,8 +2456,7 @@ Item_in_subselect::create_row_in_to_exists_cond(JOIN * join, Item_ref(thd, &select_lex->context, &select_lex->ref_pointer_array[i], (char *)"<no matter>", - (char *)"<list ref>")); - + &list_ref)); item_isnull= new (thd->mem_root) Item_func_isnull(thd, @@ -2478,7 +2465,7 @@ Item_in_subselect::create_row_in_to_exists_cond(JOIN * join, &select_lex-> ref_pointer_array[i], (char *)"<no matter>", - (char *)"<list ref>")); + &list_ref)); item= new (thd->mem_root) Item_cond_or(thd, item, item_isnull); if (left_expr->element_index(i)->maybe_null && get_cond_guard(i)) { @@ -2513,7 +2500,7 @@ Item_in_subselect::create_row_in_to_exists_cond(JOIN * join, if (*having_item) { if (!join_having) - (*having_item)->name= (char*) in_having_cond; + (*having_item)->name= in_having_cond; if (fix_having(*having_item, select_lex)) DBUG_RETURN(true); (*having_item)->top_level_item(); @@ -3010,7 +2997,7 @@ bool Item_exists_subselect::exists2in_processor(void *opt_arg) Item_direct_ref(thd, &first_select->context, (Item**)optimizer->get_cache(), (char *)"<no matter>", - (char *)in_left_expr_name); + &in_left_expr_name); if (in_subs->fix_fields(thd, optimizer->arguments() + 1)) { res= TRUE; @@ -3081,7 +3068,7 @@ bool Item_exists_subselect::exists2in_processor(void *opt_arg) &unit->outer_select()->context, optimizer->arguments(), (char *)"<no matter>", - (char *)exists_outer_expr_name)), + &exists_outer_expr_name)), optimizer) : (Item *)optimizer); } @@ -3105,7 +3092,7 @@ bool Item_exists_subselect::exists2in_processor(void *opt_arg) &unit->outer_select()->context, optimizer->arguments()[0]->addr(i), (char *)"<no matter>", - (char *)exists_outer_expr_name)), + &exists_outer_expr_name)), thd->mem_root); } } @@ -3294,7 +3281,7 @@ bool Item_in_subselect::fix_fields(THD *thd_arg, Item **ref) { outer_cols_num= left_expr->cols(); - if (unit->is_union()) + if (unit->is_unit_op()) inner_cols= &(unit->types); else inner_cols= &(unit->first_select()->item_list); @@ -3716,24 +3703,21 @@ void subselect_engine::set_row(List<Item> &item_list, Item_cache **row) { Item *sel_item; List_iterator_fast<Item> li(item_list); - cmp_type= res_type= STRING_RESULT; - res_field_type= MYSQL_TYPE_VAR_STRING; + set_handler(&type_handler_varchar); for (uint i= 0; (sel_item= li++); i++) { item->max_length= sel_item->max_length; - res_type= sel_item->result_type(); - cmp_type= sel_item->cmp_type(); - res_field_type= sel_item->field_type(); + set_handler(sel_item->type_handler()); item->decimals= sel_item->decimals; item->unsigned_flag= sel_item->unsigned_flag; maybe_null= sel_item->maybe_null; - if (!(row[i]= Item_cache::get_cache(thd, sel_item, sel_item->cmp_type()))) + if (!(row[i]= sel_item->get_cache(thd))) return; row[i]->setup(thd, sel_item); //psergey-backport-timours: row[i]->store(sel_item); } if (item_list.elements > 1) - cmp_type= res_type= ROW_RESULT; + set_handler(&type_handler_row); } void subselect_single_select_engine::fix_length_and_dec(Item_cache **row) @@ -4296,7 +4280,7 @@ int subselect_indexsubquery_engine::exec() } -uint subselect_single_select_engine::cols() +uint subselect_single_select_engine::cols() const { //psergey-sj-backport: the following assert was gone in 6.0: //DBUG_ASSERT(select_lex->join != 0); // should be called after fix_fields() @@ -4305,7 +4289,7 @@ uint subselect_single_select_engine::cols() } -uint subselect_union_engine::cols() +uint subselect_union_engine::cols() const { DBUG_ASSERT(unit->is_prepared()); // should be called after fix_fields() return unit->types.elements; @@ -4386,7 +4370,7 @@ void subselect_union_engine::print(String *str, enum_query_type query_type) void subselect_uniquesubquery_engine::print(String *str, enum_query_type query_type) { - char *table_name= tab->table->s->table_name.str; + const char *table_name= tab->table->s->table_name.str; str->append(STRING_WITH_LEN("<primary_index_lookup>(")); tab->ref.items[0]->print(str, query_type); str->append(STRING_WITH_LEN(" in ")); @@ -4905,7 +4889,7 @@ my_bitmap_init_memroot(MY_BITMAP *map, uint n_bits, MEM_ROOT *mem_root) bool subselect_hash_sj_engine::init(List<Item> *tmp_columns, uint subquery_id) { THD *thd= get_thd(); - select_union *result_sink; + select_unit *result_sink; /* Options to create_tmp_table. */ ulonglong tmp_create_options= thd->variables.option_bits | TMP_TABLE_ALL_COLUMNS; /* | TMP_TABLE_FORCE_MYISAM; TIMOUR: force MYISAM */ @@ -4943,7 +4927,7 @@ bool subselect_hash_sj_engine::init(List<Item> *tmp_columns, uint subquery_id) DBUG_RETURN(TRUE); char buf[32]; - uint len= my_snprintf(buf, sizeof(buf), "<subquery%d>", subquery_id); + uint len= my_snprintf(buf, sizeof(buf), "<subquery%u>", subquery_id); char *name; if (!(name= (char*)thd->alloc(len + 1))) DBUG_RETURN(TRUE); @@ -4957,7 +4941,7 @@ bool subselect_hash_sj_engine::init(List<Item> *tmp_columns, uint subquery_id) } if (result_sink->create_result_table(thd, tmp_columns, TRUE, tmp_create_options, - name, TRUE, TRUE)) + name, TRUE, TRUE, FALSE, 0)) DBUG_RETURN(TRUE); tmp_table= result_sink->table; @@ -5986,10 +5970,10 @@ void Ordered_key::print(String *str) str->append(", ("); for (i= 0; i < key_column_count - 1; i++) { - str->append(key_columns[i]->field->field_name); + str->append(&key_columns[i]->field->field_name); str->append(", "); } - str->append(key_columns[i]->field->field_name); + str->append(&key_columns[i]->field->field_name); str->append("), "); str->append("null_bitmap: (bits="); |