diff options
Diffstat (limited to 'sql/item.cc')
-rw-r--r-- | sql/item.cc | 448 |
1 files changed, 258 insertions, 190 deletions
diff --git a/sql/item.cc b/sql/item.cc index 26e99fe752e..52274380cd1 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -102,9 +102,7 @@ void item_init(void) void Item::raise_error_not_evaluable() { Item::Print tmp(this, QT_ORDINARY); - // TODO-10.5: add an error message to errmsg-utf8.txt - my_printf_error(ER_UNKNOWN_ERROR, - "'%s' is not allowed in this context", MYF(0), tmp.ptr()); + my_error(ER_NOT_ALLOWED_IN_THIS_CONTEXT, MYF(0), tmp.ptr()); } @@ -338,6 +336,7 @@ my_decimal *Item::val_decimal_from_real(my_decimal *decimal_value) my_decimal *Item::val_decimal_from_int(my_decimal *decimal_value) { + DBUG_ASSERT(is_fixed()); longlong nr= val_int(); if (null_value) return 0; @@ -411,7 +410,7 @@ int Item::save_str_value_in_field(Field *field, String *result) Item::Item(THD *thd): is_expensive_cache(-1), rsize(0), name(null_clex_str), orig_name(0), - is_autogenerated_name(TRUE) + common_flags(IS_AUTO_GENERATED_NAME) { DBUG_ASSERT(thd); marker= 0; @@ -457,7 +456,7 @@ const TABLE_SHARE *Item::field_table_or_null() tables. */ Item::Item(THD *thd, Item *item): - Type_all_attributes(item), + Type_all_attributes(*item), join_tab_idx(item->join_tab_idx), is_expensive_cache(-1), rsize(0), @@ -471,7 +470,7 @@ Item::Item(THD *thd, Item *item): with_param(item->with_param), with_window_func(item->with_window_func), with_field(item->with_field), - is_autogenerated_name(item->is_autogenerated_name) + common_flags(item->common_flags) { next= thd->free_list; // Put in free list thd->free_list= this; @@ -632,33 +631,34 @@ 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 LEX_CSTRING *field_name_arg) + const LEX_CSTRING &db_name_arg, + const LEX_CSTRING &table_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= *field_name_arg; + name= 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.str), - orig_field_name(*field_name_arg), + const LEX_CSTRING &field_name_arg) + :Item_result_field(thd), orig_db_name(null_clex_str), + orig_table_name(view_arg->table_name), + orig_field_name(field_name_arg), /* TODO: suspicious use of first_select_lex */ context(&view_arg->view->first_select_lex()->context), - db_name(NullS), table_name(view_arg->alias.str), - field_name(*field_name_arg), + db_name(null_clex_str), table_name(view_arg->alias), + 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= *field_name_arg; + name= field_name_arg; } @@ -764,6 +764,29 @@ bool Item_field::collect_item_field_processor(void *arg) } +void Item_ident::undeclared_spvar_error() const +{ + /* + We assume this is an unknown SP variable, possibly a ROW variable. + Print the leftmost name in the error: + SET var=a; -> a + SET var=a.b; -> a + SET var=a.b.c; -> a + */ + my_error(ER_SP_UNDECLARED_VAR, MYF(0), db_name.str ? db_name.str : + table_name.str ? table_name.str : + field_name.str); +} + +bool Item_field::unknown_splocal_processor(void *arg) +{ + DBUG_ENTER("Item_field::unknown_splocal_processor"); + DBUG_ASSERT(type() == FIELD_ITEM); + undeclared_spvar_error(); + DBUG_RETURN(true); +} + + bool Item_field::add_field_to_set_processor(void *arg) { DBUG_ENTER("Item_field::add_field_to_set_processor"); @@ -789,10 +812,10 @@ bool Item_field::rename_fields_processor(void *arg) while ((def=def_it++)) { if (def->change.str && - (!db_name || !db_name[0] || - !my_strcasecmp(table_alias_charset, db_name, rename->db_name.str)) && - (!table_name || !table_name[0] || - !my_strcasecmp(table_alias_charset, table_name, rename->table_name.str)) && + (!db_name.str || !db_name.str[0] || + !my_strcasecmp(table_alias_charset, db_name.str, rename->db_name.str)) && + (!table_name.str || !table_name.str[0] || + !my_strcasecmp(table_alias_charset, table_name.str, rename->table_name.str)) && !my_strcasecmp(system_charset_info, field_name.str, def->change.str)) { field_name= def->field_name; @@ -986,7 +1009,7 @@ bool Item::check_type_general_purpose_string(const char *opname) const bool Item::check_type_traditional_scalar(const char *opname) const { const Type_handler *handler= type_handler(); - if (handler->is_traditional_type() && handler->is_scalar_type()) + if (handler->is_traditional_scalar_type()) return false; my_error(ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION, MYF(0), handler->name().ptr(), opname); @@ -1107,9 +1130,9 @@ void Item::set_name(THD *thd, const char *str, size_t length, CHARSET_INFO *cs) } const char *str_start= str; - if (!cs->ctype || cs->mbminlen > 1) + if (!cs->m_ctype || cs->mbminlen > 1) { - str+= cs->cset->scan(cs, str, str + length, MY_SEQ_SPACES); + str+= cs->scan(str, str + length, MY_SEQ_SPACES); length-= (uint)(str - str_start); } else @@ -1124,7 +1147,7 @@ void Item::set_name(THD *thd, const char *str, size_t length, CHARSET_INFO *cs) str++; } } - if (str != str_start && !is_autogenerated_name) + if (str != str_start && !is_autogenerated_name()) { char buff[SAFE_NAME_LEN]; @@ -1300,7 +1323,7 @@ Item *Item::const_charset_converter(THD *thd, CHARSET_INFO *tocs, uint conv_errors; Item_string *conv= (func_name ? new (mem_root) - Item_static_string_func(thd, func_name, + Item_static_string_func(thd, Lex_cstring_strlen(func_name), s, tocs, &conv_errors, collation.derivation, collation.repertoire) : @@ -1371,7 +1394,7 @@ bool Item::get_date_from_real(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate bool Item::get_date_from_string(THD *thd, MYSQL_TIME *to, date_mode_t mode) { - StringBuffer<40> tmp; + StringBuffer<MAX_DATETIME_FULL_WIDTH+1> tmp; const TABLE_SHARE *s = field_table_or_null(); Temporal::Warn_push warn(thd, s ? s->db.str : nullptr, s ? s->table_name.str : nullptr, @@ -1421,7 +1444,7 @@ int Item::save_in_field_no_warnings(Field *field, bool no_conversions) THD *thd= table->in_use; enum_check_fields tmp= thd->count_cuted_fields; my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->write_set); - sql_mode_t sql_mode= thd->variables.sql_mode; + Sql_mode_save sms(thd); thd->variables.sql_mode&= ~(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE); thd->variables.sql_mode|= MODE_INVALID_DATES; thd->count_cuted_fields= CHECK_FIELD_IGNORE; @@ -1430,7 +1453,6 @@ int Item::save_in_field_no_warnings(Field *field, bool no_conversions) thd->count_cuted_fields= tmp; dbug_tmp_restore_column_map(table->write_set, old_map); - thd->variables.sql_mode= sql_mode; return res; } @@ -1473,6 +1495,37 @@ bool mark_unsupported_function(const char *w1, const char *w2, } +bool Item_field::check_vcol_func_processor(void *arg) +{ + context= 0; + vcol_func_processor_result *res= (vcol_func_processor_result *) arg; + if (res && res->alter_info) + { + for (Key &k: res->alter_info->key_list) + { + if (k.type != Key::FOREIGN_KEY) + continue; + Foreign_key *fk= (Foreign_key*) &k; + if (fk->update_opt != FK_OPTION_CASCADE) + continue; + for (Key_part_spec& kp: fk->columns) + { + if (!lex_string_cmp(system_charset_info, &kp.field_name, &field_name)) + { + return mark_unsupported_function(field_name.str, arg, VCOL_IMPOSSIBLE); + } + } + } + } + if (field && (field->unireg_check == Field::NEXT_NUMBER)) + { + // Auto increment fields are unsupported + return mark_unsupported_function(field_name.str, arg, VCOL_FIELD_REF | VCOL_AUTO_INC); + } + return mark_unsupported_function(field_name.str, arg, VCOL_FIELD_REF); +} + + Query_fragment::Query_fragment(THD *thd, sp_head *sphead, const char *start, const char *end) { @@ -2030,7 +2083,7 @@ Item_name_const::Item_name_const(THD *thd, Item *name_arg, Item *val): Item::maybe_null= TRUE; if (name_item->basic_const_item() && (name_str= name_item->val_str(&name_buffer))) // Can't have a NULL name - set_name(thd, name_str->ptr(), name_str->length(), name_str->charset()); + set_name(thd, name_str); } @@ -2075,7 +2128,7 @@ bool Item_name_const::fix_fields(THD *thd, Item **ref) return TRUE; } if (value_item->collation.derivation == DERIVATION_NUMERIC) - collation.set_numeric(); + collation= DTCollation_numeric(); else collation.set(value_item->collation.collation, DERIVATION_IMPLICIT); max_length= value_item->max_length; @@ -2105,18 +2158,18 @@ 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 LEX_CSTRING *field_name_arg): + Item **item, const LEX_CSTRING &table_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) + void print (String *str, enum_query_type query_type) override { if (ref) (*ref)->print(str, query_type); else Item_ident::print(str, query_type); } - virtual Ref_Type ref_type() { return AGGREGATE_REF; } + Ref_Type ref_type() override final { return AGGREGATE_REF; } }; @@ -2228,8 +2281,8 @@ void Item::split_sum_func2(THD *thd, Ref_ptr_array ref_pointer_array, if (!(item_ref= (new (thd->mem_root) Item_direct_ref(thd, &thd->lex->current_select->context, - &ref_pointer_array[el], 0, - &name)))) + &ref_pointer_array[el], + null_clex_str, name)))) return; // fatal_error is set } else @@ -2237,8 +2290,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], + null_clex_str, name)))) return; // fatal_error is set } if (type() == SUM_FUNC_ITEM) @@ -2384,7 +2437,7 @@ bool DTCollation::aggregate(const DTCollation &dt, uint flags) { if (derivation == DERIVATION_EXPLICIT) { - set(0, DERIVATION_NONE, 0); + set(0, DERIVATION_NONE, MY_REPERTOIRE_NONE); return 1; } if (collation->state & MY_CS_BINSORT && @@ -2767,7 +2820,8 @@ Item_sp::execute_impl(THD *thd, Item **args, uint arg_count) (m_sp->agg_type() == NOT_AGGREGATE && !func_ctx)); if (!func_ctx) { - init_sql_alloc(&sp_mem_root, "Item_sp", MEM_ROOT_BLOCK_SIZE, 0, MYF(0)); + init_sql_alloc(key_memory_sp_head_call_root, &sp_mem_root, + MEM_ROOT_BLOCK_SIZE, 0, MYF(0)); *sp_query_arena= Query_arena(&sp_mem_root, Query_arena::STMT_INITIALIZED_FOR_SP); } @@ -2885,9 +2939,10 @@ Item* Item_ref::build_clone(THD *thd) /**********************************************/ Item_field::Item_field(THD *thd, Field *f) - :Item_ident(thd, 0, NullS, *f->table_name, &f->field_name), + :Item_ident(thd, 0, null_clex_str, + Lex_cstring_strlen(*f->table_name), f->field_name), item_equal(0), - have_privileges(0), any_privileges(0) + have_privileges(NO_ACL), any_privileges(0) { set_field(f); /* @@ -2909,10 +2964,10 @@ 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, + Lex_cstring_strlen(*f->table_name), f->field_name), item_equal(0), - have_privileges(0), any_privileges(0) + have_privileges(NO_ACL), any_privileges(0) { /* We always need to provide Item_field with a fully qualified field @@ -2932,13 +2987,12 @@ Item_field::Item_field(THD *thd, Name_resolution_context *context_arg, procedures). */ { - if (db_name) - orig_db_name= thd->strdup(db_name); - if (table_name) - orig_table_name= thd->strdup(table_name); + if (db_name.str) + orig_db_name= thd->strmake_lex_cstring(db_name); + if (table_name.str) + orig_table_name= thd->strmake_lex_cstring(table_name); if (field_name.str) - thd->make_lex_string(&orig_field_name, field_name.str, - field_name.length); + orig_field_name= thd->strmake_lex_cstring(field_name); /* We don't restore 'name' in cleanup because it's not changed during execution. Still we need it to point to persistent @@ -2952,11 +3006,12 @@ 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 LEX_CSTRING *field_name_arg) + const LEX_CSTRING &db_arg, + const LEX_CSTRING &table_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) + have_privileges(NO_ACL), any_privileges(0) { SELECT_LEX *select= thd->lex->current_select; collation.set(DERIVATION_IMPLICIT); @@ -2981,14 +3036,25 @@ Item_field::Item_field(THD *thd, Item_field *item) } +bool Item_field::is_json_type() +{ + if (!field->check_constraint || + field->check_constraint->expr->type() != FUNC_ITEM) + return FALSE; + + Item_func *f= (Item_func *) field->check_constraint->expr; + return f->functype() == Item_func::JSON_VALID_FUNC; +} + + void Item_field::set_field(Field *field_par) { field=result_field=field_par; // for easy coding with fields maybe_null=field->maybe_null(); Type_std_attributes::set(field_par->type_std_attributes()); - table_name= *field_par->table_name; + table_name= Lex_cstring_strlen(*field_par->table_name); field_name= field_par->field_name; - db_name= field_par->table->s->db.str; + db_name= field_par->table->s->db; alias_name_used= field_par->table->alias_name_used; fixed= 1; @@ -3071,24 +3137,24 @@ bool Item_field::switch_to_nullable_fields_processor(void *arg) const char *Item_ident::full_name() const { char *tmp; - if (!table_name || !field_name.str) + if (!table_name.str || !field_name.str) return field_name.str ? field_name.str : name.str ? name.str : "tmp_field"; - if (db_name && db_name[0]) + if (db_name.str && db_name.str[0]) { THD *thd= current_thd; - tmp=(char*) thd->alloc((uint) strlen(db_name)+(uint) strlen(table_name)+ + tmp=(char*) thd->alloc((uint) db_name.length+ (uint) table_name.length + (uint) field_name.length+3); - strxmov(tmp,db_name,".",table_name,".",field_name.str,NullS); + strxmov(tmp,db_name.str,".",table_name.str,".",field_name.str,NullS); } else { - if (table_name[0]) + if (table_name.str[0]) { THD *thd= current_thd; - tmp= (char*) thd->alloc((uint) strlen(table_name) + + tmp= (char*) thd->alloc((uint) table_name.length + field_name.length + 2); - strxmov(tmp, table_name, ".", field_name.str, NullS); + strxmov(tmp, table_name.str, ".", field_name.str, NullS); } else return field_name.str; @@ -3100,12 +3166,14 @@ void Item_ident::print(String *str, enum_query_type query_type) { THD *thd= current_thd; char d_name_buff[MAX_ALIAS_NAME], t_name_buff[MAX_ALIAS_NAME]; - const char *d_name= db_name, *t_name= table_name; - bool use_table_name= table_name && table_name[0]; - bool use_db_name= use_table_name && db_name && db_name[0] && !alias_name_used; + LEX_CSTRING d_name= db_name; + LEX_CSTRING t_name= table_name; + bool use_table_name= table_name.str && table_name.str[0]; + bool use_db_name= use_table_name && db_name.str && db_name.str[0] && + !alias_name_used; if (use_db_name && (query_type & QT_ITEM_IDENT_SKIP_DB_NAMES)) - use_db_name= !thd->db.str || strcmp(thd->db.str, db_name); + use_db_name= !thd->db.str || strcmp(thd->db.str, db_name.str); if (use_db_name) use_db_name= !(cached_table && cached_table->belong_to_view && @@ -3128,6 +3196,12 @@ void Item_ident::print(String *str, enum_query_type query_type) use_db_name= use_table_name= false; } + if ((query_type & QT_ITEM_IDENT_DISABLE_DB_TABLE_NAMES)) + { + // Don't print db or table name irrespective of any other settings. + use_db_name= use_table_name= false; + } + if (!field_name.str || !field_name.str[0]) { append_identifier(thd, str, STRING_WITH_LEN("tmp_field")); @@ -3139,27 +3213,27 @@ void Item_ident::print(String *str, enum_query_type query_type) { if (use_table_name) { - strmov(t_name_buff, table_name); + strmov(t_name_buff, table_name.str); my_casedn_str(files_charset_info, t_name_buff); - t_name= t_name_buff; + t_name= Lex_cstring_strlen(t_name_buff); } if (use_db_name) { - strmov(d_name_buff, db_name); + strmov(d_name_buff, db_name.str); my_casedn_str(files_charset_info, d_name_buff); - d_name= d_name_buff; + d_name= Lex_cstring_strlen(d_name_buff); } } if (use_db_name) { - append_identifier(thd, str, d_name, (uint)strlen(d_name)); + append_identifier(thd, str, d_name.str, (uint) d_name.length); str->append('.'); DBUG_ASSERT(use_table_name); } if (use_table_name) { - append_identifier(thd, str, t_name, (uint) strlen(t_name)); + append_identifier(thd, str, t_name.str, (uint) t_name.length); str->append('.'); } append_identifier(thd, str, &field_name); @@ -3326,12 +3400,12 @@ bool Item_field::eq(const Item *item, bool binary_cmp) const */ return (!lex_string_cmp(system_charset_info, &item_field->name, &field_name) && - (!item_field->table_name || !table_name || - (!my_strcasecmp(table_alias_charset, item_field->table_name, - table_name) && - (!item_field->db_name || !db_name || - (item_field->db_name && !strcmp(item_field->db_name, - db_name)))))); + (!item_field->table_name.str || !table_name.str || + (!my_strcasecmp(table_alias_charset, item_field->table_name.str, + table_name.str) && + (!item_field->db_name.str || !db_name.str || + (item_field->db_name.str && !strcmp(item_field->db_name.str, + db_name.str)))))); } @@ -3348,6 +3422,16 @@ table_map Item_field::all_used_tables() const } +bool Item_field::find_not_null_fields(table_map allowed) +{ + if (field->table->const_table) + return false; + if (!get_depended_from() && field->real_maybe_null()) + bitmap_set_bit(&field->table->tmp_set, field->field_index); + return false; +} + + /* @Note thd->fatal_error can be set in case of OOM */ @@ -3550,9 +3634,10 @@ String *Item_int::val_str(String *str) void Item_int::print(String *str, enum_query_type query_type) { + StringBuffer<LONGLONG_BUFFER_SIZE> buf; // my_charset_bin is good enough for numbers - str_value.set_int(value, unsigned_flag, &my_charset_bin); - str->append(str_value); + buf.set_int(value, unsigned_flag, &my_charset_bin); + str->append(buf); } @@ -3578,21 +3663,6 @@ Item_uint::Item_uint(THD *thd, const char *str_arg, longlong i, uint length): } -String *Item_uint::val_str(String *str) -{ - str->set((ulonglong) value, collation.collation); - return str; -} - - -void Item_uint::print(String *str, enum_query_type query_type) -{ - // latin1 is good enough for numbers - str_value.set((ulonglong) value, default_charset()); - str->append(str_value); -} - - Item_decimal::Item_decimal(THD *thd, const char *str_arg, size_t length, CHARSET_INFO *charset): Item_num(thd) @@ -3835,7 +3905,7 @@ Item_null::make_string_literal_concat(THD *thd, const LEX_CSTRING *str) if (str->length) { CHARSET_INFO *cs= thd->variables.collation_connection; - uint repertoire= my_string_repertoire(cs, str->str, str->length); + my_repertoire_t repertoire= my_string_repertoire(cs, str->str, str->length); return new (thd->mem_root) Item_string(thd, str->str, (uint) str->length, cs, DERIVATION_COERCIBLE, repertoire); @@ -3916,7 +3986,6 @@ void Item_param::sync_clones() c->null_value= null_value; c->Type_std_attributes::operator=(*this); c->Type_handler_hybrid_field_type::operator=(*this); - c->Type_geometry_attributes::operator=(*this); c->state= state; c->m_empty_string_is_null= m_empty_string_is_null; @@ -3962,7 +4031,7 @@ void Item_param::set_int(longlong i, uint32 max_length_arg) DBUG_ASSERT(value.type_handler()->cmp_type() == INT_RESULT); value.integer= (longlong) i; state= SHORT_DATA_VALUE; - collation.set_numeric(); + collation= DTCollation_numeric(); max_length= max_length_arg; decimals= 0; maybe_null= 0; @@ -3976,7 +4045,7 @@ void Item_param::set_double(double d) DBUG_ASSERT(value.type_handler()->cmp_type() == REAL_RESULT); value.real= d; state= SHORT_DATA_VALUE; - collation.set_numeric(); + collation= DTCollation_numeric(); max_length= DBL_DIG + 8; decimals= NOT_FIXED_DEC; maybe_null= 0; @@ -4007,7 +4076,7 @@ void Item_param::set_decimal(const char *str, ulong length) str2my_decimal(E_DEC_FATAL_ERROR, str, &value.m_decimal, &end); state= SHORT_DATA_VALUE; decimals= value.m_decimal.frac; - collation.set_numeric(); + collation= DTCollation_numeric(); max_length= my_decimal_precision_to_length_no_truncation(value.m_decimal.precision(), decimals, unsigned_flag); @@ -4024,7 +4093,7 @@ void Item_param::set_decimal(const my_decimal *dv, bool unsigned_arg) my_decimal2decimal(dv, &value.m_decimal); decimals= (uint8) value.m_decimal.frac; - collation.set_numeric(); + collation= DTCollation_numeric(); unsigned_flag= unsigned_arg; max_length= my_decimal_precision_to_length(value.m_decimal.intg + decimals, decimals, unsigned_flag); @@ -4036,7 +4105,7 @@ void Item_param::set_decimal(const my_decimal *dv, bool unsigned_arg) void Item_param::fix_temporal(uint32 max_length_arg, uint decimals_arg) { state= SHORT_DATA_VALUE; - collation.set_numeric(); + collation= DTCollation_numeric(); max_length= max_length_arg; decimals= decimals_arg; maybe_null= 0; @@ -4143,12 +4212,12 @@ bool Item_param::set_longdata(const char *str, ulong length) (here), and first have to concatenate all pieces together, write query to the binary log and only then perform conversion. */ - if (value.m_string.length() + length > max_long_data_size) + if (value.m_string.length() + length > current_thd->variables.max_allowed_packet) { my_message(ER_UNKNOWN_ERROR, "Parameter of prepared statement which is set through " "mysql_send_long_data() is longer than " - "'max_long_data_size' bytes", + "'max_allowed_packet' bytes", MYF(0)); DBUG_RETURN(true); } @@ -4619,9 +4688,9 @@ Item *Item_param::value_clone_item(THD *thd) case DECIMAL_RESULT: return 0; // Should create Item_decimal. See MDEV-11361. case STRING_RESULT: - return new (mem_root) Item_string(thd, name.str, - value.m_string.c_ptr_quick(), - value.m_string.length(), + return new (mem_root) Item_string(thd, name, + Lex_cstring(value.m_string.c_ptr_quick(), + value.m_string.length()), value.m_string.charset(), collation.derivation, collation.repertoire); @@ -4857,16 +4926,16 @@ double Item_copy_string::val_real() int err_not_used; char *end_not_used; return (null_value ? 0.0 : - my_strntod(str_value.charset(), (char*) str_value.ptr(), - str_value.length(), &end_not_used, &err_not_used)); + str_value.charset()->strntod((char*) str_value.ptr(), str_value.length(), + &end_not_used, &err_not_used)); } longlong Item_copy_string::val_int() { int err; - return null_value ? 0 : my_strntoll(str_value.charset(),str_value.ptr(), - str_value.length(), 10, (char**) 0, - &err); + return null_value ? 0 : str_value.charset()->strntoll(str_value.ptr(), + str_value.length(), 10, (char**) 0, + &err); } @@ -5002,10 +5071,10 @@ static bool mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current, DBUG_RETURN(TRUE); if (thd->lex->describe & DESCRIBE_EXTENDED) { - const char *db_name= (resolved_item->db_name ? - resolved_item->db_name : ""); - const char *table_name= (resolved_item->table_name ? - resolved_item->table_name : ""); + const char *db_name= (resolved_item->db_name.str ? + resolved_item->db_name.str : ""); + const char *table_name= (resolved_item->table_name.str ? + resolved_item->table_name.str : ""); push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, ER_WARN_FIELD_RESOLVED, ER_THD(thd,ER_WARN_FIELD_RESOLVED), @@ -5038,8 +5107,7 @@ static bool mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current, resolved identifier. */ -void mark_select_range_as_dependent(THD *thd, - SELECT_LEX *last_select, +void mark_select_range_as_dependent(THD *thd, SELECT_LEX *last_select, SELECT_LEX *current_sel, Field *found_field, Item *found_item, Item_ident *resolved_item) @@ -5051,34 +5119,33 @@ void mark_select_range_as_dependent(THD *thd, resolving) */ SELECT_LEX *previous_select= current_sel; - for (; previous_select->outer_select() != last_select; - previous_select= previous_select->outer_select()) + for (; previous_select->context.outer_select() != last_select; + previous_select= previous_select->context.outer_select()) { Item_subselect *prev_subselect_item= previous_select->master_unit()->item; prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT; prev_subselect_item->const_item_cache= 0; } + + Item_subselect *prev_subselect_item= + previous_select->master_unit()->item; + Item_ident *dependent= resolved_item; + if (found_field == view_ref_found) { - Item_subselect *prev_subselect_item= - previous_select->master_unit()->item; - Item_ident *dependent= resolved_item; - if (found_field == view_ref_found) - { - Item::Type type= found_item->type(); - prev_subselect_item->used_tables_cache|= - found_item->used_tables(); - dependent= ((type == Item::REF_ITEM || type == Item::FIELD_ITEM) ? - (Item_ident*) found_item : - 0); - } - else - prev_subselect_item->used_tables_cache|= - found_field->table->map; - prev_subselect_item->const_item_cache= 0; - mark_as_dependent(thd, last_select, current_sel, resolved_item, - dependent); + Item::Type type= found_item->type(); + prev_subselect_item->used_tables_cache|= + found_item->used_tables(); + dependent= ((type == Item::REF_ITEM || type == Item::FIELD_ITEM) ? + (Item_ident*) found_item : + 0); } + else + prev_subselect_item->used_tables_cache|= + found_field->table->map; + prev_subselect_item->const_item_cache= 0; + mark_as_dependent(thd, last_select, current_sel, resolved_item, + dependent); } @@ -5099,9 +5166,9 @@ void mark_select_range_as_dependent(THD *thd, static Item** find_field_in_group_list(Item *find_item, ORDER *group_list) { - const char *db_name; - const char *table_name; - LEX_CSTRING *field_name; + LEX_CSTRING db_name; + LEX_CSTRING table_name; + LEX_CSTRING field_name; ORDER *found_group= NULL; int found_match_degree= 0; char name_buff[SAFE_NAME_LEN+1]; @@ -5111,30 +5178,30 @@ 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; - if (db_name && lower_case_table_names) + if (db_name.str && lower_case_table_names) { /* Convert database to lower case for comparison */ - strmake_buf(name_buff, db_name); + strmake_buf(name_buff, db_name.str); my_casedn_str(files_charset_info, name_buff); - db_name= name_buff; + db_name= Lex_cstring_strlen(name_buff); } - DBUG_ASSERT(field_name->str != 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.str && !table_name && - !(*(cur_group->item))->is_autogenerated_name && + if ((*(cur_group->item))->name.str && !table_name.str && + !(*(cur_group->item))->is_autogenerated_name() && !lex_string_cmp(system_charset_info, - &(*(cur_group->item))->name, field_name)) + &(*(cur_group->item))->name, &field_name)) { ++cur_match_degree; } @@ -5143,30 +5210,30 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list) (*(cur_group->item))->type() == Item::REF_ITEM ) { 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_db_name= cur_field->db_name.str; + const char *l_table_name= cur_field->table_name.str; LEX_CSTRING *l_field_name= &cur_field->field_name; DBUG_ASSERT(l_field_name->str != 0); if (!lex_string_cmp(system_charset_info, - l_field_name, field_name)) + l_field_name, &field_name)) ++cur_match_degree; else continue; - if (l_table_name && table_name) + if (l_table_name && table_name.str) { /* If field_name is qualified by a table name. */ - if (my_strcasecmp(table_alias_charset, l_table_name, table_name)) + if (my_strcasecmp(table_alias_charset, l_table_name, table_name.str)) /* Same field names, different tables. */ return NULL; ++cur_match_degree; - if (l_db_name && db_name) + if (l_db_name && db_name.str) { /* If field_name is also qualified by a database name. */ - if (strcmp(l_db_name, db_name)) + if (strcmp(l_db_name, db_name.str)) /* Same field names, different databases. */ return NULL; ++cur_match_degree; @@ -5635,14 +5702,14 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) rf= (place == IN_HAVING ? new (thd->mem_root) Item_ref(thd, context, ref, table_name, - &field_name, alias_name_used) : + field_name, alias_name_used) : (!select->group_list.elements ? new (thd->mem_root) Item_direct_ref(thd, context, ref, table_name, - &field_name, alias_name_used) : + field_name, alias_name_used) : new (thd->mem_root) Item_outer_ref(thd, context, ref, table_name, - &field_name, alias_name_used))); + field_name, alias_name_used))); *ref= save; if (!rf) return -1; @@ -5687,9 +5754,9 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) { Item_ref *rf; rf= new (thd->mem_root) Item_ref(thd, context, - (*from_field)->table->s->db.str, - (*from_field)->table->alias.c_ptr(), - &field_name); + (*from_field)->table->s->db, + Lex_cstring_strlen((*from_field)->table->alias.c_ptr()), + field_name); if (!rf) return -1; thd->change_item_tree(reference, rf); @@ -5837,7 +5904,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); @@ -6020,7 +6087,7 @@ bool Item_field::post_fix_fields_part_expr_processor(void *int_arg) /* Update table_name to be real table name, not the alias. Because alias is reallocated for every statement, and this item has a long life time */ - table_name= field->table->s->table_name.str; + table_name= field->table->s->table_name; return FALSE; } @@ -6217,10 +6284,10 @@ Item *Item_field::replace_equal_field(THD *thd, uchar *arg) void Item::init_make_send_field(Send_field *tmp_field, const Type_handler *h) { - tmp_field->db_name= ""; - tmp_field->org_table_name= ""; + tmp_field->db_name= empty_clex_str; + tmp_field->org_table_name= empty_clex_str; tmp_field->org_col_name= empty_clex_str; - tmp_field->table_name= ""; + tmp_field->table_name= empty_clex_str; tmp_field->col_name= name; tmp_field->flags= (maybe_null ? 0 : NOT_NULL_FLAG) | (my_binary_compare(charset_for_protocol()) ? @@ -6230,6 +6297,9 @@ void Item::init_make_send_field(Send_field *tmp_field, tmp_field->decimals=decimals; if (unsigned_flag) tmp_field->flags |= UNSIGNED_FLAG; + static_cast<Send_field_extended_metadata>(*tmp_field)= + Send_field_extended_metadata(); + h->Item_append_extended_type_info(tmp_field, this); } void Item::make_send_field(THD *thd, Send_field *tmp_field) @@ -6318,7 +6388,7 @@ String_copier_for_item::copy_with_warn(CHARSET_INFO *dstcs, String *dst, if (unlikely(pos= cannot_convert_error_pos())) { char buf[16]; - int mblen= my_charlen(srccs, pos, src + src_length); + int mblen= srccs->charlen(pos, src + src_length); DBUG_ASSERT(mblen > 0 && mblen * 2 + 1 <= (int) sizeof(buf)); octet2hex(buf, pos, mblen); push_warning_printf(m_thd, Sql_condition::WARN_LEVEL_WARN, @@ -6379,15 +6449,15 @@ bool Item::eq_by_collation(Item *item, bool binary_cmp, CHARSET_INFO *cs) void Item_field::make_send_field(THD *thd, Send_field *tmp_field) { field->make_send_field(tmp_field); - DBUG_ASSERT(tmp_field->table_name != 0); + DBUG_ASSERT(tmp_field->table_name.str != 0); if (name.str) { DBUG_ASSERT(name.length == strlen(name.str)); tmp_field->col_name= name; // Use user supplied name } - if (table_name) + if (table_name.str) tmp_field->table_name= table_name; - if (db_name) + if (db_name.str) tmp_field->db_name= db_name; } @@ -6612,9 +6682,9 @@ 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, str_value.ptr(), - str_value.length(), collation.collation); + LEX_CSTRING val; + str_value.get_value(&val); + return new (thd->mem_root) Item_string(thd, name, val, collation.collation); } @@ -6844,8 +6914,7 @@ Item_float::Item_float(THD *thd, const char *str_arg, size_t length): { int error; char *end_not_used; - value= my_strntod(&my_charset_bin, (char*) str_arg, length, &end_not_used, - &error); + value= my_charset_bin.strntod((char*) str_arg, length, &end_not_used, &error); if (unlikely(error)) { char tmp[NAME_LEN + 2]; @@ -7223,7 +7292,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; @@ -7449,8 +7518,7 @@ Item *get_field_item_for_having(THD *thd, Item *item, st_select_lex *sel) if (field_item) { Item_ref *ref= new (thd->mem_root) Item_ref(thd, &sel->context, - NullS, NullS, - &field_item->field_name); + field_item->field_name); return ref; } DBUG_ASSERT(0); @@ -7612,10 +7680,10 @@ 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 LEX_CSTRING *field_name_arg, + Item **item, const LEX_CSTRING &table_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), + Item_ident(thd, context_arg, null_clex_str, table_name_arg, field_name_arg), ref(item), reference_trough_name(0) { alias_name_used= alias_name_used_arg; @@ -7662,7 +7730,7 @@ public: }; Item_ref::Item_ref(THD *thd, TABLE_LIST *view_arg, Item **item, - const LEX_CSTRING *field_name_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) @@ -8096,7 +8164,7 @@ void Item_ref::print(String *str, enum_query_type query_type) if ((*ref)->type() != Item::CACHE_ITEM && (*ref)->type() != Item::WINDOW_FUNC_ITEM && ref_type() != VIEW_REF && - !table_name && name.str && alias_name_used) + !table_name.str && name.str && alias_name_used) { THD *thd= current_thd; append_identifier(thd, str, &(*ref)->real_item()->name); @@ -8330,13 +8398,13 @@ void Item_ref::make_send_field(THD *thd, Send_field *field) /* Non-zero in case of a view */ if (name.str) field->col_name= name; - if (table_name) + if (table_name.str) field->table_name= table_name; - if (db_name) + if (db_name.str) field->db_name= db_name; if (orig_field_name.str) field->org_col_name= orig_field_name; - if (orig_table_name) + if (orig_table_name.str) field->org_table_name= orig_table_name; } |