diff options
Diffstat (limited to 'sql/item.cc')
-rw-r--r-- | sql/item.cc | 425 |
1 files changed, 231 insertions, 194 deletions
diff --git a/sql/item.cc b/sql/item.cc index f5ef8f30dff..d5d8e39ea54 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -45,6 +45,15 @@ const String my_null_string("NULL", 4, default_charset_info); const String my_default_string("DEFAULT", 7, default_charset_info); +/* + item_empty_name is used when calling Item::set_name with NULL + pointer, to make it easier to use the name in printf. + item_used_name is used when calling Item::set_name with a 0 length + string. +*/ +const char *item_empty_name=""; +const char *item_used_name= "\0"; + static int save_field_in_field(Field *, bool *, Field *, bool); @@ -471,7 +480,7 @@ int Item::save_str_value_in_field(Field *field, String *result) Item::Item(THD *thd): - is_expensive_cache(-1), rsize(0), name(0), orig_name(0), name_length(0), + is_expensive_cache(-1), rsize(0), name(null_clex_str), orig_name(0), fixed(0), is_autogenerated_name(TRUE) { DBUG_ASSERT(thd); @@ -516,7 +525,6 @@ Item::Item(THD *thd, Item *item): str_value(item->str_value), name(item->name), orig_name(item->orig_name), - name_length(item->name_length), marker(item->marker), maybe_null(item->maybe_null), in_rollup(item->in_rollup), @@ -577,11 +585,12 @@ void Item::print_item_w_name(String *str, enum_query_type query_type) { print(str, query_type); - if (name) + if (name.str) { + DBUG_ASSERT(name.length == strlen(name.str)); THD *thd= current_thd; str->append(STRING_WITH_LEN(" AS ")); - append_identifier(thd, str, name, (uint) strlen(name)); + append_identifier(thd, str, name.str, name.length); } } @@ -620,7 +629,10 @@ void Item::cleanup() marker= 0; join_tab_idx= MAX_TABLES; if (orig_name) - name= orig_name; + { + name.str= orig_name; + name.length= strlen(orig_name); + } DBUG_VOID_RETURN; } @@ -640,24 +652,6 @@ bool Item::cleanup_processor(void *arg) /** - rename item (used for views, cleanup() return original name). - - @param new_name new name of item; -*/ - -void Item::rename(char *new_name) -{ - /* - we can compare pointers to names here, because if name was not changed, - pointer will be same - */ - if (!orig_name && new_name != name) - orig_name= name; - name= new_name; -} - - -/** Traverse item tree possibly transforming it (replacing items). This function is designed to ease transformation of Item trees. @@ -726,29 +720,31 @@ Item* Item::set_expr_cache(THD *thd) Item_ident::Item_ident(THD *thd, Name_resolution_context *context_arg, const char *db_name_arg,const char *table_name_arg, - const char *field_name_arg) + const LEX_CSTRING *field_name_arg) :Item_result_field(thd), orig_db_name(db_name_arg), orig_table_name(table_name_arg), - orig_field_name(field_name_arg), context(context_arg), + orig_field_name(*field_name_arg), context(context_arg), db_name(db_name_arg), table_name(table_name_arg), - field_name(field_name_arg), + field_name(*field_name_arg), alias_name_used(FALSE), cached_field_index(NO_CACHED_FIELD_INDEX), cached_table(0), depended_from(0), can_be_depended(TRUE) { - name = (char*) field_name_arg; + name= *field_name_arg; } -Item_ident::Item_ident(THD *thd, TABLE_LIST *view_arg, const char *field_name_arg) +Item_ident::Item_ident(THD *thd, TABLE_LIST *view_arg, + const LEX_CSTRING *field_name_arg) :Item_result_field(thd), orig_db_name(NullS), orig_table_name(view_arg->table_name), - orig_field_name(field_name_arg), context(&view_arg->view->select_lex.context), + orig_field_name(*field_name_arg), + context(&view_arg->view->select_lex.context), db_name(NullS), table_name(view_arg->alias), - field_name(field_name_arg), + field_name(*field_name_arg), alias_name_used(FALSE), cached_field_index(NO_CACHED_FIELD_INDEX), cached_table(NULL), depended_from(NULL), can_be_depended(TRUE) { - name = (char*) field_name_arg; + name= *field_name_arg; } @@ -839,7 +835,8 @@ bool Item_ident::collect_outer_ref_processor(void *param) bool Item_field::collect_item_field_processor(void *arg) { DBUG_ENTER("Item_field::collect_item_field_processor"); - DBUG_PRINT("info", ("%s", field->field_name ? field->field_name : "noname")); + DBUG_PRINT("info", ("%s", field->field_name.str ? + field->field_name.str : "noname")); List<Item_field> *item_list= (List<Item_field>*) arg; List_iterator<Item_field> item_list_it(*item_list); Item_field *curr_item; @@ -856,7 +853,8 @@ bool Item_field::collect_item_field_processor(void *arg) bool Item_field::add_field_to_set_processor(void *arg) { DBUG_ENTER("Item_field::add_field_to_set_processor"); - DBUG_PRINT("info", ("%s", field->field_name ? field->field_name : "noname")); + DBUG_PRINT("info", ("%s", field->field_name.str ? field->field_name.str : + "noname")); TABLE *table= (TABLE *) arg; if (field->table == table) bitmap_set_bit(&table->tmp_set, field->field_index); @@ -978,7 +976,7 @@ bool Item_field::check_field_expression_processor(void *arg) { my_error(ER_EXPRESSION_REFERS_TO_UNINIT_FIELD, MYF(0), - org_field->field_name, field->field_name); + org_field->field_name.str, field->field_name.str); return 1; } if ((field->default_value && field->default_value->flags) || field->vcol_info) @@ -991,7 +989,7 @@ bool Item_field::check_field_expression_processor(void *arg) { my_error(ER_EXPRESSION_REFERS_TO_UNINIT_FIELD, MYF(0), - org_field->field_name, field->field_name); + org_field->field_name.str, field->field_name.str); return 1; } } @@ -1021,14 +1019,18 @@ bool Item::check_cols(uint c) return 0; } - void Item::set_name(THD *thd, const char *str, uint length, CHARSET_INFO *cs) { if (!length) { - /* Empty string, used by AS or internal function like last_insert_id() */ - name= (char*) str; - name_length= 0; + /* + Null string are replaced by item_empty_name. This is used by AS or + internal function like last_insert_id() to detect if we need to + change the name later. + Used by sql_yacc.yy in select_alias handling + */ + name.str= str ? item_used_name : item_empty_name; + name.length= 0; return; } @@ -1070,13 +1072,13 @@ void Item::set_name(THD *thd, const char *str, uint length, CHARSET_INFO *cs) if (!my_charset_same(cs, system_charset_info)) { size_t res_length; - name= sql_strmake_with_convert(thd, str, length, cs, - MAX_ALIAS_NAME, system_charset_info, - &res_length); - name_length= res_length; + name.str= sql_strmake_with_convert(thd, str, length, cs, + MAX_ALIAS_NAME, system_charset_info, + &res_length); + name.length= res_length; } else - name= thd->strmake(str, (name_length= MY_MIN(length,MAX_ALIAS_NAME))); + name.str= thd->strmake(str, (name.length= MY_MIN(length,MAX_ALIAS_NAME))); } @@ -1086,13 +1088,13 @@ void Item::set_name_no_truncate(THD *thd, const char *str, uint length, if (!my_charset_same(cs, system_charset_info)) { size_t res_length; - name= sql_strmake_with_convert(thd, str, length, cs, - UINT_MAX, system_charset_info, - &res_length); - name_length= res_length; + name.str= sql_strmake_with_convert(thd, str, length, cs, + UINT_MAX, system_charset_info, + &res_length); + name.length= res_length; } else - name= thd->strmake(str, (name_length= length)); + name.str= thd->strmake(str, (name.length= length)); } @@ -1110,8 +1112,9 @@ bool Item::eq(const Item *item, bool binary_cmp) const for all basic constants we have special checks, and Item_param's type() can be only among basic constant types. */ - return type() == item->type() && name && item->name && - !my_strcasecmp(system_charset_info,name,item->name); + return type() == item->type() && name.str && item->name.str && + name.length == item->name.length && + !my_strcasecmp(system_charset_info, name.str, item->name.str); } @@ -1453,15 +1456,12 @@ bool mark_unsupported_function(const char *w1, const char *w2, Item_sp_variable methods *****************************************************************************/ -Item_sp_variable::Item_sp_variable(THD *thd, char *sp_var_name_str, - uint sp_var_name_length): - Item(thd), m_thd(0) +Item_sp_variable::Item_sp_variable(THD *thd, const LEX_CSTRING *sp_var_name) + :Item(thd), m_thd(0), m_name(*sp_var_name) #ifndef DBUG_OFF , m_sp(0) #endif { - m_name.str= sp_var_name_str; - m_name.length= sp_var_name_length; } @@ -1552,16 +1552,26 @@ bool Item_sp_variable::is_null() return this_item()->is_null(); } +void Item_sp_variable::make_field(THD *thd, Send_field *field) +{ + Item *it= this_item(); + + it->make_field(thd, field); + if (name.str) + field->col_name= name; + else + field->col_name= m_name; +} /***************************************************************************** Item_splocal methods *****************************************************************************/ -Item_splocal::Item_splocal(THD *thd, const LEX_STRING &sp_var_name, +Item_splocal::Item_splocal(THD *thd, const LEX_CSTRING *sp_var_name, uint sp_var_idx, enum_field_types sp_var_type, uint pos_in_q, uint len_in_q): - Item_sp_variable(thd, sp_var_name.str, sp_var_name.length), + Item_sp_variable(thd, sp_var_name), Rewritable_query_parameter(pos_in_q, len_in_q), m_var_idx(sp_var_idx) { @@ -1793,8 +1803,10 @@ bool Item_splocal_row_field_by_name::set_value(THD *thd, sp_rcontext *ctx, Item Item_case_expr methods *****************************************************************************/ +LEX_CSTRING str_case_expr= { STRING_WITH_LEN("case_expr") }; + Item_case_expr::Item_case_expr(THD *thd, uint case_expr_id): - Item_sp_variable(thd, C_STRING_WITH_LEN("case_expr")), + Item_sp_variable(thd, &str_case_expr), m_case_expr_id(case_expr_id) { } @@ -1974,7 +1986,7 @@ bool Item_name_const::fix_fields(THD *thd, Item **ref) } if (is_autogenerated_name) { - set_name(thd, item_name->ptr(), (uint) item_name->length(), + set_name(thd, item_name->c_ptr(), (uint) item_name->length(), system_charset_info); } collation.set(value_item->collation.collation, DERIVATION_IMPLICIT); @@ -2005,7 +2017,7 @@ class Item_aggregate_ref : public Item_ref public: Item_aggregate_ref(THD *thd, Name_resolution_context *context_arg, Item **item, const char *table_name_arg, - const char *field_name_arg): + const LEX_CSTRING *field_name_arg): Item_ref(thd, context_arg, item, table_name_arg, field_name_arg) {} virtual inline void print (String *str, enum_query_type query_type) @@ -2119,14 +2131,14 @@ void Item::split_sum_func2(THD *thd, Ref_ptr_array ref_pointer_array, already a reference. */ Item *real_itm= real_item(); - ref_pointer_array[el]= real_itm; if (type() == WINDOW_FUNC_ITEM) { if (!(item_ref= (new (thd->mem_root) Item_direct_ref(thd, - &thd->lex->current_select->context, - &ref_pointer_array[el], 0, name)))) + &thd->lex->current_select->context, + &ref_pointer_array[el], 0, + &name)))) return; // fatal_error is set } else if (type() == FUNC_ITEM && @@ -2137,7 +2149,8 @@ void Item::split_sum_func2(THD *thd, Ref_ptr_array ref_pointer_array, if (!(item_ref= (new (thd->mem_root) Item_aggregate_ref(thd, &thd->lex->current_select->context, - &ref_pointer_array[el], 0, name)))) + &ref_pointer_array[el], 0, + &name)))) return; // fatal_error is set } if (type() == SUM_FUNC_ITEM) @@ -2561,7 +2574,7 @@ void Item_ident_for_show::make_field(THD *thd, Send_field *tmp_field) /**********************************************/ Item_field::Item_field(THD *thd, Field *f) - :Item_ident(thd, 0, NullS, *f->table_name, f->field_name), + :Item_ident(thd, 0, NullS, *f->table_name, &f->field_name), item_equal(0), have_privileges(0), any_privileges(0) { @@ -2570,7 +2583,8 @@ Item_field::Item_field(THD *thd, Field *f) field_name and table_name should not point to garbage if this item is to be reused */ - orig_table_name= orig_field_name= ""; + orig_table_name= ""; + orig_field_name= null_clex_str; with_field= 1; } @@ -2584,7 +2598,8 @@ Item_field::Item_field(THD *thd, Field *f) Item_field::Item_field(THD *thd, Name_resolution_context *context_arg, Field *f) - :Item_ident(thd, context_arg, f->table->s->db.str, *f->table_name, f->field_name), + :Item_ident(thd, context_arg, f->table->s->db.str, *f->table_name, + &f->field_name), item_equal(0), have_privileges(0), any_privileges(0) { @@ -2610,14 +2625,15 @@ Item_field::Item_field(THD *thd, Name_resolution_context *context_arg, orig_db_name= thd->strdup(db_name); if (table_name) orig_table_name= thd->strdup(table_name); - if (field_name) - orig_field_name= thd->strdup(field_name); + if (field_name.str) + thd->make_lex_string(&orig_field_name, field_name.str, + field_name.length); /* We don't restore 'name' in cleanup because it's not changed during execution. Still we need it to point to persistent memory if this item is to be reused. */ - name= (char*) orig_field_name; + name= orig_field_name; } set_field(f); with_field= 1; @@ -2626,7 +2642,7 @@ Item_field::Item_field(THD *thd, Name_resolution_context *context_arg, Item_field::Item_field(THD *thd, Name_resolution_context *context_arg, const char *db_arg,const char *table_name_arg, - const char *field_name_arg) + const LEX_CSTRING *field_name_arg) :Item_ident(thd, context_arg, db_arg, table_name_arg, field_name_arg), field(0), item_equal(0), have_privileges(0), any_privileges(0) @@ -2736,7 +2752,7 @@ void Item_field::reset_field(Field *f) { set_field(f); /* 'name' is pointing at field->field_name of old field */ - name= (char*) f->field_name; + name= f->field_name; } @@ -2775,15 +2791,15 @@ bool Item_field::switch_to_nullable_fields_processor(void *arg) const char *Item_ident::full_name() const { char *tmp; - if (!table_name || !field_name) - return field_name ? field_name : name ? name : "tmp_field"; + if (!table_name || !field_name.str) + return field_name.str ? field_name.str : name.str ? name.str : "tmp_field"; if (db_name && db_name[0]) { THD *thd= current_thd; tmp=(char*) thd->alloc((uint) strlen(db_name)+(uint) strlen(table_name)+ - (uint) strlen(field_name)+3); - strxmov(tmp,db_name,".",table_name,".",field_name,NullS); + (uint) field_name.length+3); + strxmov(tmp,db_name,".",table_name,".",field_name.str,NullS); } else { @@ -2791,11 +2807,11 @@ const char *Item_ident::full_name() const { THD *thd= current_thd; tmp= (char*) thd->alloc((uint) strlen(table_name) + - (uint) strlen(field_name) + 2); - strxmov(tmp, table_name, ".", field_name, NullS); + field_name.length + 2); + strxmov(tmp, table_name, ".", field_name.str, NullS); } else - tmp= (char*) field_name; + return field_name.str; } return tmp; } @@ -2833,7 +2849,7 @@ void Item_ident::print(String *str, enum_query_type query_type) use_table_name= false; } - if (!field_name || !field_name[0]) + if (!field_name.str || !field_name.str[0]) { append_identifier(thd, str, STRING_WITH_LEN("tmp_field")); return; @@ -2867,7 +2883,7 @@ void Item_ident::print(String *str, enum_query_type query_type) append_identifier(thd, str, t_name, (uint) strlen(t_name)); str->append('.'); } - append_identifier(thd, str, field_name, (uint) strlen(field_name)); + append_identifier(thd, str, field_name.str, field_name.length); } /* ARGSUSED */ @@ -2998,8 +3014,8 @@ bool Item_field::eq(const Item *item, bool binary_cmp) const (In cases where we would choose wrong we would have to generate a ER_NON_UNIQ_ERROR). */ - return (!my_strcasecmp(system_charset_info, item_field->name, - field_name) && + return (!my_strcasecmp(system_charset_info, item_field->name.str, + field_name.str) && (!item_field->table_name || !table_name || (!my_strcasecmp(table_alias_charset, item_field->table_name, table_name) && @@ -3126,7 +3142,12 @@ Item_int::Item_int(THD *thd, const char *str_arg, uint length): int error; value= my_strtoll10(str_arg, &end_ptr, &error); max_length= (uint) (end_ptr - str_arg); - name= (char*) str_arg; + name.str= str_arg; + /* + We can't trust max_length as in show_routine_code we are using "Pos" as + the field name. + */ + name.length= !str_arg[max_length] ? max_length : strlen(str_arg); fixed= 1; } @@ -3156,7 +3177,7 @@ void Item_int::print(String *str, enum_query_type query_type) Item *Item_bool::neg_transformer(THD *thd) { value= !value; - name= 0; + name= null_clex_str; return this; } @@ -3197,7 +3218,8 @@ Item_decimal::Item_decimal(THD *thd, const char *str_arg, uint length, Item_num(thd) { str2my_decimal(E_DEC_FATAL_ERROR, str_arg, length, charset, &decimal_value); - name= (char*) str_arg; + name.str= str_arg; + name.length= safe_strlen(str_arg); decimals= (uint8) decimal_value.frac; fixed= 1; max_length= my_decimal_precision_to_length_no_truncation(decimal_value.intg + @@ -3237,7 +3259,8 @@ Item_decimal::Item_decimal(THD *thd, const char *str, const my_decimal *val_arg, Item_num(thd) { my_decimal2decimal(val_arg, &decimal_value); - name= (char*) str; + name.str= str; + name.length= safe_strlen(str); decimals= (uint8) decimal_par; max_length= length; fixed= 1; @@ -3329,7 +3352,7 @@ void Item_decimal::set_decimal_value(my_decimal *value_par) Item *Item_decimal::clone_item(THD *thd) { - return new (thd->mem_root) Item_decimal(thd, name, &decimal_value, decimals, + return new (thd->mem_root) Item_decimal(thd, name.str, &decimal_value, decimals, max_length); } @@ -3354,7 +3377,7 @@ my_decimal *Item_float::val_decimal(my_decimal *decimal_value) Item *Item_float::clone_item(THD *thd) { - return new (thd->mem_root) Item_float(thd, name, value, decimals, + return new (thd->mem_root) Item_float(thd, name.str, value, decimals, max_length); } @@ -3465,7 +3488,7 @@ Item *Item_null::safe_charset_converter(THD *thd, CHARSET_INFO *tocs) Item *Item_null::clone_item(THD *thd) { - return new (thd->mem_root) Item_null(thd, name); + return new (thd->mem_root) Item_null(thd, name.str); } /*********************** Item_param related ******************************/ @@ -3484,7 +3507,7 @@ default_set_param_func(Item_param *param, } -Item_param::Item_param(THD *thd, char *name_arg, +Item_param::Item_param(THD *thd, const LEX_CSTRING *name_arg, uint pos_in_query_arg, uint len_in_query_arg): Item_basic_value(thd), Rewritable_query_parameter(pos_in_query_arg, len_in_query_arg), @@ -3504,8 +3527,8 @@ Item_param::Item_param(THD *thd, char *name_arg, */ m_is_settable_routine_parameter(true) { - name= name_arg; - /* + name= *name_arg; + /* Since we can't say whenever this item can be NULL or cannot be NULL before mysql_stmt_execute(), so we assuming that it can be NULL until value is set. @@ -4196,19 +4219,19 @@ Item_param::clone_item(THD *thd) invalid_default_param(); // fall through case NULL_VALUE: - return new (mem_root) Item_null(thd, name); + return new (mem_root) Item_null(thd, name.str); case INT_VALUE: return (unsigned_flag ? - new (mem_root) Item_uint(thd, name, value.integer, max_length) : - new (mem_root) Item_int(thd, name, value.integer, max_length)); + new (mem_root) Item_uint(thd, name.str, value.integer, max_length) : + new (mem_root) Item_int(thd, name.str, value.integer, max_length)); case REAL_VALUE: - return new (mem_root) Item_float(thd, name, value.real, decimals, + return new (mem_root) Item_float(thd, name.str, value.real, decimals, max_length); case DECIMAL_VALUE: return 0; // Should create Item_decimal. See MDEV-11361. case STRING_VALUE: case LONG_DATA_VALUE: - return new (mem_root) Item_string(thd, name, str_value.c_ptr_quick(), + return new (mem_root) Item_string(thd, name.str, str_value.c_ptr_quick(), str_value.length(), str_value.charset(), collation.derivation, collation.repertoire); @@ -4841,7 +4864,7 @@ static bool mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current, ER_THD(thd,ER_WARN_FIELD_RESOLVED), db_name, (db_name[0] ? "." : ""), table_name, (table_name [0] ? "." : ""), - resolved_item->field_name, + resolved_item->field_name.str, current->select_number, last->select_number); } DBUG_RETURN(FALSE); @@ -4931,7 +4954,7 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list) { const char *db_name; const char *table_name; - const char *field_name; + LEX_CSTRING *field_name; ORDER *found_group= NULL; int found_match_degree= 0; char name_buff[SAFE_NAME_LEN+1]; @@ -4941,7 +4964,7 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list) { db_name= ((Item_ident*) find_item)->db_name; table_name= ((Item_ident*) find_item)->table_name; - field_name= ((Item_ident*) find_item)->field_name; + field_name= &((Item_ident*) find_item)->field_name; } else return NULL; @@ -4954,17 +4977,17 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list) db_name= name_buff; } - DBUG_ASSERT(field_name != 0); + DBUG_ASSERT(field_name->str != 0); for (ORDER *cur_group= group_list ; cur_group ; cur_group= cur_group->next) { int cur_match_degree= 0; /* SELECT list element with explicit alias */ - if ((*(cur_group->item))->name && + if ((*(cur_group->item))->name.str && !(*(cur_group->item))->is_autogenerated_name && !my_strcasecmp(system_charset_info, - (*(cur_group->item))->name, field_name)) + (*(cur_group->item))->name.str, field_name->str)) { ++cur_match_degree; } @@ -4975,12 +4998,12 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list) Item_ident *cur_field= (Item_ident*) *cur_group->item; const char *l_db_name= cur_field->db_name; const char *l_table_name= cur_field->table_name; - const char *l_field_name= cur_field->field_name; + LEX_CSTRING *l_field_name= &cur_field->field_name; - DBUG_ASSERT(l_field_name != 0); + DBUG_ASSERT(l_field_name->str != 0); if (!my_strcasecmp(system_charset_info, - l_field_name, field_name)) + l_field_name->str, field_name->str)) ++cur_match_degree; else continue; @@ -5116,7 +5139,7 @@ resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select) the strict mode is enabled. */ my_error(ER_NON_GROUPING_FIELD_USED, MYF(0), - ref->name, "HAVING"); + ref->name.str, "HAVING"); return NULL; } if (select_ref != not_found_item || group_by_ref) @@ -5127,7 +5150,7 @@ resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select) if (!select->ref_pointer_array[counter]) { my_error(ER_ILLEGAL_REFERENCE, MYF(0), - ref->name, "forward reference in item list"); + ref->name.str, "forward reference in item list"); return NULL; } DBUG_ASSERT((*select_ref)->fixed); @@ -5454,15 +5477,15 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) *ref= NULL; // Don't call set_properties() rf= (place == IN_HAVING ? new (thd->mem_root) - Item_ref(thd, context, ref, (char*) table_name, - (char*) field_name, alias_name_used) : + Item_ref(thd, context, ref, table_name, + &field_name, alias_name_used) : (!select->group_list.elements ? new (thd->mem_root) - Item_direct_ref(thd, context, ref, (char*) table_name, - (char*) field_name, alias_name_used) : + Item_direct_ref(thd, context, ref, table_name, + &field_name, alias_name_used) : new (thd->mem_root) - Item_outer_ref(thd, context, ref, (char*) table_name, - (char*) field_name, alias_name_used))); + Item_outer_ref(thd, context, ref, table_name, + &field_name, alias_name_used))); *ref= save; if (!rf) return -1; @@ -5506,9 +5529,10 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) if (last_checked_context->select_lex->having_fix_field) { Item_ref *rf; - rf= new (thd->mem_root) Item_ref(thd, context, (*from_field)->table->s->db.str, - (*from_field)->table->alias.c_ptr(), - (char*) field_name); + rf= new (thd->mem_root) Item_ref(thd, context, + (*from_field)->table->s->db.str, + (*from_field)->table->alias.c_ptr(), + &field_name); if (!rf) return -1; thd->change_item_tree(reference, rf); @@ -5626,7 +5650,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference) if (new_field == NULL) { /* The column to which we link isn't valid. */ - my_error(ER_BAD_FIELD_ERROR, MYF(0), (*res)->name, + my_error(ER_BAD_FIELD_ERROR, MYF(0), (*res)->name.str, thd->where); return(1); } @@ -5647,8 +5671,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference) Item_field created by the parser with the new Item_ref. */ Item_ref *rf= new (thd->mem_root) - Item_ref(thd, context, db_name, table_name, - field_name); + Item_ref(thd, context, db_name, table_name, &field_name); if (!rf) return 1; bool err= rf->fix_fields(thd, (Item **) &rf) || rf->check_cols(1); @@ -5746,16 +5769,16 @@ bool Item_field::fix_fields(THD *thd, Item **reference) #ifndef NO_EMBEDDED_ACCESS_CHECKS if (any_privileges) { - char *db, *tab; + const char *db, *tab; db= field->table->s->db.str; tab= field->table->s->table_name.str; if (!(have_privileges= (get_column_grant(thd, &field->table->grant, - db, tab, field_name) & + db, tab, field_name.str) & VIEW_ANY_ACL))) { my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0), "ANY", thd->security_ctx->priv_user, - thd->security_ctx->host_or_ip, field_name, tab); + thd->security_ctx->host_or_ip, field_name.str, tab); goto error; } } @@ -6043,12 +6066,11 @@ Item *Item_field::replace_equal_field(THD *thd, uchar *arg) void Item::init_make_field(Send_field *tmp_field, enum enum_field_types field_type_arg) { - char *empty_name= (char*) ""; - tmp_field->db_name= empty_name; - tmp_field->org_table_name= empty_name; - tmp_field->org_col_name= empty_name; - tmp_field->table_name= empty_name; - tmp_field->col_name= name; + tmp_field->db_name= ""; + tmp_field->org_table_name= ""; + tmp_field->org_col_name= empty_clex_str; + tmp_field->table_name= ""; + tmp_field->col_name= name; tmp_field->flags= (maybe_null ? 0 : NOT_NULL_FLAG) | (my_binary_compare(charset_for_protocol()) ? BINARY_FLAG : 0); @@ -6215,7 +6237,6 @@ Field *Item::make_string_field(TABLE *table) { Field *field; MEM_ROOT *mem_root= table->in_use->mem_root; - DBUG_ASSERT(collation.collation); /* Note: the following check is repeated in @@ -6223,17 +6244,17 @@ Field *Item::make_string_field(TABLE *table) */ if (too_big_for_varchar()) field= new (mem_root) - Field_blob(max_length, maybe_null, name, + Field_blob(max_length, maybe_null, &name, collation.collation, TRUE); /* Item_type_holder holds the exact type, do not change it */ else if (max_length > 0 && (type() != Item::TYPE_HOLDER || field_type() != MYSQL_TYPE_STRING)) field= new (mem_root) - Field_varstring(max_length, maybe_null, name, table->s, + Field_varstring(max_length, maybe_null, &name, table->s, collation.collation); else field= new (mem_root) - Field_string(max_length, maybe_null, name, collation.collation); + Field_string(max_length, maybe_null, &name, collation.collation); if (field) field->init(table); return field; @@ -6274,64 +6295,66 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table, case MYSQL_TYPE_TINY: field= new (mem_root) Field_tiny((uchar*) 0, max_length, null_ptr, 0, Field::NONE, - name, 0, unsigned_flag); + &name, 0, unsigned_flag); break; case MYSQL_TYPE_SHORT: field= new (mem_root) Field_short((uchar*) 0, max_length, null_ptr, 0, Field::NONE, - name, 0, unsigned_flag); + &name, 0, unsigned_flag); break; case MYSQL_TYPE_LONG: field= new (mem_root) Field_long((uchar*) 0, max_length, null_ptr, 0, Field::NONE, - name, 0, unsigned_flag); + &name, 0, unsigned_flag); break; #ifdef HAVE_LONG_LONG case MYSQL_TYPE_LONGLONG: field= new (mem_root) Field_longlong((uchar*) 0, max_length, null_ptr, 0, Field::NONE, - name, 0, unsigned_flag); + &name, 0, unsigned_flag); break; #endif case MYSQL_TYPE_FLOAT: field= new (mem_root) Field_float((uchar*) 0, max_length, null_ptr, 0, Field::NONE, - name, decimals, 0, unsigned_flag); + &name, decimals, 0, unsigned_flag); break; case MYSQL_TYPE_DOUBLE: field= new (mem_root) Field_double((uchar*) 0, max_length, null_ptr, 0, Field::NONE, - name, decimals, 0, unsigned_flag); + &name, decimals, 0, unsigned_flag); break; case MYSQL_TYPE_INT24: field= new (mem_root) Field_medium((uchar*) 0, max_length, null_ptr, 0, Field::NONE, - name, 0, unsigned_flag); + &name, 0, unsigned_flag); break; case MYSQL_TYPE_NEWDATE: case MYSQL_TYPE_DATE: field= new (mem_root) - Field_newdate(0, null_ptr, 0, Field::NONE, name); + Field_newdate(0, null_ptr, 0, Field::NONE, &name); break; case MYSQL_TYPE_TIME: - field= new_Field_time(mem_root, 0, null_ptr, 0, Field::NONE, name, + field= new_Field_time(mem_root, 0, null_ptr, 0, Field::NONE, &name, decimals); break; case MYSQL_TYPE_TIMESTAMP: field= new_Field_timestamp(mem_root, 0, null_ptr, 0, - Field::NONE, name, 0, decimals); + Field::NONE, &name, 0, decimals); break; case MYSQL_TYPE_DATETIME: - field= new_Field_datetime(mem_root, 0, null_ptr, 0, Field::NONE, name, - decimals); + field= new_Field_datetime(mem_root, 0, null_ptr, 0, Field::NONE, + &name, decimals); break; case MYSQL_TYPE_YEAR: field= new (mem_root) - Field_year((uchar*) 0, max_length, null_ptr, 0, Field::NONE, name); + Field_year((uchar*) 0, max_length, null_ptr, 0, Field::NONE, + &name); break; case MYSQL_TYPE_BIT: field= new (mem_root) - Field_bit_as_char(NULL, max_length, null_ptr, 0, Field::NONE, name); + Field_bit_as_char(NULL, max_length, null_ptr, 0, Field::NONE, + &name); break; default: /* This case should never be chosen */ @@ -6342,7 +6365,7 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table, if (fixed_length && !too_big_for_varchar()) { field= new (mem_root) - Field_string(max_length, maybe_null, name, collation.collation); + Field_string(max_length, maybe_null, &name, collation.collation); break; } /* Fall through to make_string_field() */ @@ -6356,13 +6379,14 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table, case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_BLOB: field= new (mem_root) - Field_blob(max_length, maybe_null, name, + Field_blob(max_length, maybe_null, &name, collation.collation, set_blob_packlength); break; // Blob handled outside of case #ifdef HAVE_SPATIAL case MYSQL_TYPE_GEOMETRY: field= new (mem_root) - Field_geom(max_length, maybe_null, name, table->s, get_geometry_type()); + Field_geom(max_length, maybe_null, &name, table->s, + get_geometry_type()); #endif /* HAVE_SPATIAL */ } if (field) @@ -6376,8 +6400,11 @@ void Item_field::make_field(THD *thd, Send_field *tmp_field) { field->make_field(tmp_field); DBUG_ASSERT(tmp_field->table_name != 0); - if (name) - tmp_field->col_name=name; // Use user supplied name + if (name.str) + { + DBUG_ASSERT(name.length == strlen(name.str)); + tmp_field->col_name= name; // Use user supplied name + } if (table_name) tmp_field->table_name= table_name; if (db_name) @@ -6602,7 +6629,7 @@ int Item_string::save_in_field(Field *field, bool no_conversions) Item *Item_string::clone_item(THD *thd) { return new (thd->mem_root) - Item_string(thd, name, str_value.ptr(), + Item_string(thd, name.str, str_value.ptr(), str_value.length(), collation.collation); } @@ -6625,7 +6652,7 @@ int Item_int::save_in_field(Field *field, bool no_conversions) Item *Item_int::clone_item(THD *thd) { - return new (thd->mem_root) Item_int(thd, name, value, max_length); + return new (thd->mem_root) Item_int(thd, name.str, value, max_length); } @@ -6661,9 +6688,9 @@ Item *Item_int_with_ref::clone_item(THD *thd) */ return (ref->unsigned_flag ? new (thd->mem_root) - Item_uint(thd, ref->name, ref->val_int(), ref->max_length) : + Item_uint(thd, ref->name.str, ref->val_int(), ref->max_length) : new (thd->mem_root) - Item_int(thd, ref->name, ref->val_int(), ref->max_length)); + Item_int(thd, ref->name.str, ref->val_int(), ref->max_length)); } @@ -6691,7 +6718,7 @@ Item *Item_int::neg(THD *thd) else if (value < 0 && max_length) max_length--; value= -value; - name= 0; + name= null_clex_str; return this; } @@ -6699,7 +6726,7 @@ Item *Item_decimal::neg(THD *thd) { my_decimal_neg(&decimal_value); unsigned_flag= 0; - name= 0; + name= null_clex_str; max_length= my_decimal_precision_to_length_no_truncation( decimal_value.intg + decimals, decimals, unsigned_flag); return this; @@ -6712,7 +6739,8 @@ Item *Item_float::neg(THD *thd) else if (value < 0 && max_length) max_length--; value= -value; - name= presentation= 0 ; + presentation= 0; + name= null_clex_str; return this; } @@ -6731,7 +6759,7 @@ Item *Item_uint::neg(THD *thd) Item *Item_uint::clone_item(THD *thd) { - return new (thd->mem_root) Item_uint(thd, name, value, max_length); + return new (thd->mem_root) Item_uint(thd, name.str, value, max_length); } static uint nr_of_decimals(const char *str, const char *end) @@ -6801,7 +6829,8 @@ Item_float::Item_float(THD *thd, const char *str_arg, uint length): my_snprintf(tmp, sizeof(tmp), "%.*s", length, str_arg); my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "double", tmp); } - presentation= name=(char*) str_arg; + presentation= name.str= str_arg; + name.length= strlen(str_arg); decimals=(uint8) nr_of_decimals(str_arg, str_arg+length); max_length=length; fixed= 1; @@ -7287,7 +7316,7 @@ Item *Item_field::update_value_transformer(THD *thd, uchar *select_arg) all_fields->push_front((Item*)this, thd->mem_root); ref= new (thd->mem_root) Item_ref(thd, &select->context, &ref_pointer_array[el], - table_name, field_name); + table_name, &field_name); return ref; } return this; @@ -7305,7 +7334,7 @@ Item *Item_field::derived_field_transformer_for_having(THD *thd, uchar *arg) Item_ref *rf= new (thd->mem_root) Item_ref(thd, &sl->context, NullS, NullS, - ((Item_field*) this)->field_name); + &((Item_field*) this)->field_name); if (!rf) return 0; return rf; @@ -7323,7 +7352,8 @@ Item *Item_field::derived_field_transformer_for_having(THD *thd, uchar *arg) Item_ref *rf= new (thd->mem_root) Item_ref(thd, &sl->context, NullS, NullS, - ((Item_field*) (item->real_item()))->field_name); + &((Item_field*) (item->real_item()))-> + field_name); if (!rf) return 0; return rf; @@ -7422,15 +7452,15 @@ void Item_field::print(String *str, enum_query_type query_type) bool Item_field_row::element_index_by_name(uint *idx, - const LEX_STRING &name) const + const LEX_CSTRING &name) const { Field *field; for (uint i= 0; (field= get_row_field(i)); i++) { // Use the same comparison style with sp_context::find_variable() if (!my_strnncoll(system_charset_info, - (const uchar *) field->field_name, - strlen(field->field_name), + (const uchar *) field->field_name.str, + field->field_name.length, (const uchar *) name.str, name.length)) { *idx= i; @@ -7453,7 +7483,7 @@ void Item_temptable_field::print(String *str, enum_query_type query_type) Item_ref::Item_ref(THD *thd, Name_resolution_context *context_arg, Item **item, const char *table_name_arg, - const char *field_name_arg, + const LEX_CSTRING *field_name_arg, bool alias_name_used_arg): Item_ident(thd, context_arg, NullS, table_name_arg, field_name_arg), ref(item), reference_trough_name(0) @@ -7498,7 +7528,8 @@ public: }; Item_ref::Item_ref(THD *thd, TABLE_LIST *view_arg, Item **item, - const char *field_name_arg, bool alias_name_used_arg): + const LEX_CSTRING *field_name_arg, + bool alias_name_used_arg): Item_ident(thd, view_arg, field_name_arg), ref(item), reference_trough_name(0) { @@ -7780,13 +7811,13 @@ bool Item_ref::fix_fields(THD *thd, Item **reference) */ if (!((*ref)->type() == REF_ITEM && ((Item_ref *)(*ref))->ref_type() == OUTER_REF) && - (((*ref)->with_sum_func && name && + (((*ref)->with_sum_func && name.str && !(current_sel->linkage != GLOBAL_OPTIONS_TYPE && current_sel->having_fix_field)) || !(*ref)->fixed)) { my_error(ER_ILLEGAL_REFERENCE, MYF(0), - name, ((*ref)->with_sum_func? + name.str, ((*ref)->with_sum_func? "reference to group function": "forward reference in item list")); goto error; @@ -7928,11 +7959,11 @@ void Item_ref::print(String *str, enum_query_type query_type) if (ref) { if ((*ref)->type() != Item::CACHE_ITEM && ref_type() != VIEW_REF && - !table_name && name && alias_name_used) + !table_name && name.str && alias_name_used) { THD *thd= current_thd; - append_identifier(thd, str, (*ref)->real_item()->name, - strlen((*ref)->real_item()->name)); + append_identifier(thd, str, (*ref)->real_item()->name.str, + (*ref)->real_item()->name.length); } else (*ref)->print(str, query_type); @@ -8129,13 +8160,13 @@ void Item_ref::make_field(THD *thd, Send_field *field) { (*ref)->make_field(thd, field); /* Non-zero in case of a view */ - if (name) + if (name.str) field->col_name= name; if (table_name) field->table_name= table_name; if (db_name) field->db_name= db_name; - if (orig_field_name) + if (orig_field_name.str) field->org_col_name= orig_field_name; if (orig_table_name) field->org_table_name= orig_table_name; @@ -8241,7 +8272,6 @@ Item_cache_wrapper::Item_cache_wrapper(THD *thd, Item *item_arg): with_sum_func= orig_item->with_sum_func; with_field= orig_item->with_field; name= item_arg->name; - name_length= item_arg->name_length; with_subselect= orig_item->with_subselect; if ((expr_value= orig_item->get_cache(thd))) @@ -8929,7 +8959,8 @@ bool Item_default_value::fix_fields(THD *thd, Item **items) field_arg= (Item_field *)real_arg; if ((field_arg->field->flags & NO_DEFAULT_VALUE_FLAG)) { - my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), field_arg->field->field_name); + my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), + field_arg->field->field_name.str); goto error; } if (!(def_field= (Field*) thd->alloc(field_arg->field->size_of()))) @@ -9170,7 +9201,7 @@ bool Item_insert_value::fix_fields(THD *thd, Item **items) { Field *tmp_field= field_arg->field; /* charset doesn't matter here, it's to avoid sigsegv only */ - tmp_field= new Field_null(0, 0, Field::NONE, field_arg->field->field_name, + tmp_field= new Field_null(0, 0, Field::NONE, &field_arg->field->field_name, &my_charset_bin); if (tmp_field) { @@ -9227,7 +9258,7 @@ void Item_trigger_field::setup_field(THD *thd, TABLE *table, Try to find field by its name and if it will be found set field_idx properly. */ - (void)find_field_in_table(thd, table, field_name, (uint) strlen(field_name), + (void)find_field_in_table(thd, table, field_name.str, field_name.length, 0, &field_idx); thd->mark_used_columns= save_mark_used_columns; triggers= table->triggers; @@ -9239,8 +9270,8 @@ bool Item_trigger_field::eq(const Item *item, bool binary_cmp) const { return item->type() == TRIGGER_FIELD_ITEM && row_version == ((Item_trigger_field *)item)->row_version && - !my_strcasecmp(system_charset_info, field_name, - ((Item_trigger_field *)item)->field_name); + !my_strcasecmp(system_charset_info, field_name.str, + ((Item_trigger_field *)item)->field_name.str); } @@ -9306,9 +9337,11 @@ bool Item_trigger_field::fix_fields(THD *thd, Item **items) { table_grants->want_privilege= want_privilege; - if (check_grant_column(thd, table_grants, triggers->trigger_table->s->db.str, - triggers->trigger_table->s->table_name.str, field_name, - strlen(field_name), thd->security_ctx)) + if (check_grant_column(thd, table_grants, + triggers->trigger_table->s->db.str, + triggers->trigger_table->s->table_name.str, + field_name.str, field_name.length, + thd->security_ctx)) return TRUE; } #endif // NO_EMBEDDED_ACCESS_CHECKS @@ -9320,7 +9353,7 @@ bool Item_trigger_field::fix_fields(THD *thd, Item **items) return FALSE; } - my_error(ER_BAD_FIELD_ERROR, MYF(0), field_name, + my_error(ER_BAD_FIELD_ERROR, MYF(0), field_name.str, (row_version == NEW_ROW) ? "NEW" : "OLD"); return TRUE; } @@ -9330,14 +9363,14 @@ void Item_trigger_field::print(String *str, enum_query_type query_type) { str->append((row_version == NEW_ROW) ? "NEW" : "OLD", 3); str->append('.'); - str->append(field_name); + str->append(&field_name); } bool Item_trigger_field::check_vcol_func_processor(void *arg) { const char *ver= row_version == NEW_ROW ? "NEW." : "OLD."; - return mark_unsupported_function(ver, field_name, arg, VCOL_IMPOSSIBLE); + return mark_unsupported_function(ver, field_name.str, arg, VCOL_IMPOSSIBLE); } @@ -9377,7 +9410,7 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item) Item *new_item= NULL; Item_result res_type= item_cmp_type(comp_item, item); - char *name= item->name; // Alloced on THD::mem_root + const char *name= item->name.str; // Alloced on THD::mem_root MEM_ROOT *mem_root= thd->mem_root; switch (res_type) { @@ -10222,7 +10255,7 @@ bool Item_type_holder::join_types(THD *thd, Item *item) DBUG_ENTER("Item_type_holder::join_types"); DBUG_PRINT("info:", ("was type %s len %d, dec %d name %s", real_type_handler()->name().ptr(), max_length, decimals, - (name ? name : "<NULL>"))); + (name.str ? name.str : "<NULL>"))); DBUG_PRINT("info:", ("in type %s len %d, dec %d", item->real_type_handler()->name().ptr(), item->max_length, item->decimals)); @@ -10368,23 +10401,27 @@ Field *Item_type_holder::make_field_by_type(TABLE *table) switch (Item_type_holder::real_type_handler()->real_field_type()) { case MYSQL_TYPE_ENUM: + { DBUG_ASSERT(enum_set_typelib); field= new Field_enum((uchar *) 0, max_length, null_ptr, 0, - Field::NONE, name, + Field::NONE, &name, get_enum_pack_length(enum_set_typelib->count), enum_set_typelib, collation.collation); if (field) field->init(table); return field; + } case MYSQL_TYPE_SET: + { DBUG_ASSERT(enum_set_typelib); field= new Field_set((uchar *) 0, max_length, null_ptr, 0, - Field::NONE, name, + Field::NONE, &name, get_set_pack_length(enum_set_typelib->count), enum_set_typelib, collation.collation); if (field) field->init(table); return field; + } case MYSQL_TYPE_NULL: return make_string_field(table); default: |