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