diff options
author | Alexander Barkov <bar@mariadb.org> | 2017-04-24 09:54:12 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2017-04-24 09:54:12 +0400 |
commit | 79ecd75afd1d6f0adc5bb6c840b9d3c66f014239 (patch) | |
tree | 71cc3b35dd38106f22c78577ba5fcd63bb92776b /sql/item_func.cc | |
parent | 530396cef0fff2a67faf42f9683bdc5ccb893217 (diff) | |
parent | 5a759d31f766087d5e135e1d3d3d987693bc9b88 (diff) | |
download | mariadb-git-79ecd75afd1d6f0adc5bb6c840b9d3c66f014239.tar.gz |
Merge remote-tracking branch 'origin/bb-10.2-ext' into 10.3
Diffstat (limited to 'sql/item_func.cc')
-rw-r--r-- | sql/item_func.cc | 189 |
1 files changed, 42 insertions, 147 deletions
diff --git a/sql/item_func.cc b/sql/item_func.cc index f25ba12b83c..ab2f354f371 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -59,7 +59,7 @@ #define sp_restore_security_context(A,B) while (0) {} #endif -bool check_reserved_words(LEX_STRING *name) +bool check_reserved_words(const LEX_CSTRING *name) { if (!my_strcasecmp(system_charset_info, name->str, "GLOBAL") || !my_strcasecmp(system_charset_info, name->str, "LOCAL") || @@ -1107,7 +1107,7 @@ err: push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, ER_THD(thd, ER_WARN_DATA_OUT_OF_RANGE), - name, 1L); + name.str, 1L); return dec; } @@ -1150,7 +1150,7 @@ double Item_double_typecast::val_real() Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, ER_THD(thd, ER_WARN_DATA_OUT_OF_RANGE), - name, 1); + name.str, (ulong) 1); if (error < 0) { null_value= 1; // Illegal value @@ -2698,119 +2698,12 @@ double Item_func_units::val_real() } -void Item_func_min_max::fix_length_and_dec() +bool Item_func_min_max::fix_attributes(Item **items, uint nitems) { - uint unsigned_count= 0; - int max_int_part=0; - decimals=0; - max_length=0; - maybe_null=0; - Item_result tmp_cmp_type= args[0]->cmp_type(); - uint string_type_count= 0; - uint temporal_type_count= 0; - enum_field_types temporal_field_type= MYSQL_TYPE_DATETIME; - - for (uint i=0 ; i < arg_count ; i++) - { - set_if_bigger(max_length, args[i]->max_length); - set_if_bigger(decimals, args[i]->decimals); - set_if_bigger(max_int_part, args[i]->decimal_int_part()); - unsigned_count+= args[i]->unsigned_flag; - if (args[i]->maybe_null) - maybe_null= 1; - tmp_cmp_type= item_cmp_type(tmp_cmp_type, args[i]->cmp_type()); - string_type_count+= args[i]->cmp_type() == STRING_RESULT; - if (args[i]->cmp_type() == TIME_RESULT) - { - if (!temporal_type_count) - temporal_field_type= args[i]->field_type(); - else - temporal_field_type= Field::field_type_merge(temporal_field_type, - args[i]->field_type()); - temporal_type_count++; - } - } - unsigned_flag= unsigned_count == arg_count; // if all args are unsigned - - switch (tmp_cmp_type) { - case TIME_RESULT: - // At least one temporal argument was found. - collation.set_numeric(); - set_handler_by_field_type(temporal_field_type); - if (is_temporal_type_with_time(temporal_field_type)) - set_if_smaller(decimals, TIME_SECOND_PART_DIGITS); - else - decimals= 0; - break; - - case STRING_RESULT: - if (aggregate_for_result(func_name(), args, arg_count, false)) - return; - /* - All arguments are of string-alike types: - CHAR, VARCHAR, TEXT, BINARY, VARBINARY, BLOB, SET, ENUM - No numeric and no temporal types were found. - */ - agg_arg_charsets_for_string_result_with_comparison(collation, - args, arg_count); - break; - - case INT_RESULT: - /* - All arguments have INT-alike types: - TINY, SHORT, LONG, LONGLONG, INT24, YEAR, BIT. - */ - collation.set_numeric(); - fix_char_length(my_decimal_precision_to_length_no_truncation(max_int_part + - decimals, - decimals, - unsigned_flag)); - if (unsigned_count != 0 && unsigned_count != arg_count) - { - /* - If all args are of INT-alike type, but have different unsigned_flag, - then change type to DECIMAL. - */ - set_handler_by_field_type(MYSQL_TYPE_NEWDECIMAL); - } - else - { - /* - There are only INT-alike arguments with equal unsigned_flag. - Aggregate types to get the best covering type. - Treat BIT as LONGLONG when aggregating to non-BIT types. - Possible final type: TINY, SHORT, LONG, LONGLONG, INT24, YEAR, BIT. - */ - if (aggregate_for_result(func_name(), args, arg_count, true)) - return; - } - break; - - case DECIMAL_RESULT: - // All arguments are of DECIMAL type - collation.set_numeric(); - fix_char_length(my_decimal_precision_to_length_no_truncation(max_int_part + - decimals, - decimals, - unsigned_flag)); - set_handler_by_field_type(MYSQL_TYPE_NEWDECIMAL); - break; - - case ROW_RESULT: - DBUG_ASSERT(0); - // Pass through - case REAL_RESULT: - collation.set_numeric(); - fix_char_length(float_length(decimals)); - /* - Set type to DOUBLE, as Item_func::create_tmp_field() does not - distinguish between DOUBLE and FLOAT and always creates Field_double. - Perhaps we should eventually change this to use aggregate_for_result() - and fix Item_func::create_tmp_field() to create Field_float when possible. - */ - set_handler_by_field_type(MYSQL_TYPE_DOUBLE); - break; - } + bool rc= Item_func_min_max::type_handler()-> + Item_func_min_max_fix_attributes(current_thd, this, items, nitems); + DBUG_ASSERT(!rc || current_thd->is_error()); + return rc; } @@ -3399,7 +3292,7 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func, !(f_args.maybe_null= (char*) thd->alloc(arg_count * sizeof(char))) || !(num_buffer= (char*) thd->alloc(arg_count * ALIGN_SIZE(sizeof(double)))) || - !(f_args.attributes= (char**) thd->alloc(arg_count * + !(f_args.attributes= (const char**) thd->alloc(arg_count * sizeof(char *))) || !(f_args.attribute_lengths= (ulong*) thd->alloc(arg_count * sizeof(long)))) @@ -3429,8 +3322,8 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func, f_args.lengths[i]= arguments[i]->max_length; f_args.maybe_null[i]= (char) arguments[i]->maybe_null; - f_args.attributes[i]= arguments[i]->name; - f_args.attribute_lengths[i]= arguments[i]->name_length; + f_args.attributes[i]= arguments[i]->name.str; + f_args.attribute_lengths[i]= arguments[i]->name.length; if (arguments[i]->const_item()) { @@ -3798,7 +3691,7 @@ longlong Item_master_pos_wait::val_int() longlong pos = (ulong)args[1]->val_int(); longlong timeout = (arg_count>=3) ? args[2]->val_int() : 0 ; String connection_name_buff; - LEX_STRING connection_name; + LEX_CSTRING connection_name; Master_info *mi= NULL; if (arg_count >= 4) { @@ -3806,7 +3699,7 @@ longlong Item_master_pos_wait::val_int() if (!(con= args[3]->val_str(&connection_name_buff))) goto err; - connection_name.str= (char*) con->ptr(); + connection_name.str= con->ptr(); connection_name.length= con->length(); if (check_master_connection_name(&connection_name)) { @@ -4506,16 +4399,16 @@ bool Item_func_user_var::check_vcol_func_processor(void *arg) #define extra_size sizeof(double) -user_var_entry *get_variable(HASH *hash, LEX_STRING &name, - bool create_if_not_exists) +user_var_entry *get_variable(HASH *hash, LEX_CSTRING *name, + bool create_if_not_exists) { user_var_entry *entry; - if (!(entry = (user_var_entry*) my_hash_search(hash, (uchar*) name.str, - name.length)) && + if (!(entry = (user_var_entry*) my_hash_search(hash, (uchar*) name->str, + name->length)) && create_if_not_exists) { - uint size=ALIGN_SIZE(sizeof(user_var_entry))+name.length+1+extra_size; + uint size=ALIGN_SIZE(sizeof(user_var_entry))+name->length+1+extra_size; if (!my_hash_inited(hash)) return 0; if (!(entry = (user_var_entry*) my_malloc(size, @@ -4524,7 +4417,7 @@ user_var_entry *get_variable(HASH *hash, LEX_STRING &name, return 0; entry->name.str=(char*) entry+ ALIGN_SIZE(sizeof(user_var_entry))+ extra_size; - entry->name.length=name.length; + entry->name.length=name->length; entry->value=0; entry->length=0; entry->update_query_id=0; @@ -4542,7 +4435,7 @@ user_var_entry *get_variable(HASH *hash, LEX_STRING &name, */ entry->used_query_id=current_thd->query_id; entry->type=STRING_RESULT; - memcpy(entry->name.str, name.str, name.length+1); + memcpy((char*) entry->name.str, name->str, name->length+1); if (my_hash_insert(hash,(uchar*) entry)) { my_free(entry); @@ -4564,7 +4457,7 @@ bool Item_func_set_user_var::set_entry(THD *thd, bool create_if_not_exists) { if (m_var_entry && thd->thread_id == entry_thread_id) goto end; // update entry->update_query_id for PS - if (!(m_var_entry= get_variable(&thd->user_vars, name, create_if_not_exists))) + if (!(m_var_entry= get_variable(&thd->user_vars, &name, create_if_not_exists))) { entry_thread_id= 0; return TRUE; @@ -5198,8 +5091,8 @@ void Item_func_set_user_var::make_field(THD *thd, Send_field *tmp_field) { result_field->make_field(tmp_field); DBUG_ASSERT(tmp_field->table_name != 0); - if (Item::name) - tmp_field->col_name=Item::name; // Use user supplied name + if (Item::name.str) + tmp_field->col_name= Item::name; // Use user supplied name } else Item::make_field(thd, tmp_field); @@ -5367,7 +5260,7 @@ longlong Item_func_get_user_var::val_int() static int get_var_with_binlog(THD *thd, enum_sql_command sql_command, - LEX_STRING &name, user_var_entry **out_entry) + LEX_CSTRING *name, user_var_entry **out_entry) { BINLOG_USER_VAR_EVENT *user_var_event; user_var_entry *var_entry; @@ -5493,7 +5386,7 @@ void Item_func_get_user_var::fix_length_and_dec() decimals=NOT_FIXED_DEC; max_length=MAX_BLOB_WIDTH; - error= get_var_with_binlog(thd, thd->lex->sql_command, name, &m_var_entry); + error= get_var_with_binlog(thd, thd->lex->sql_command, &name, &m_var_entry); /* If the variable didn't exist it has been created as a STRING-type. @@ -5570,7 +5463,8 @@ bool Item_func_get_user_var::eq(const Item *item, bool binary_cmp) const bool Item_func_get_user_var::set_value(THD *thd, sp_rcontext * /*ctx*/, Item **it) { - Item_func_set_user_var *suv= new (thd->mem_root) Item_func_set_user_var(thd, get_name(), *it); + LEX_CSTRING tmp_name= get_name(); + Item_func_set_user_var *suv= new (thd->mem_root) Item_func_set_user_var(thd, &tmp_name, *it); /* Item_func_set_user_var is not fixed after construction, call fix_fields(). @@ -5584,7 +5478,7 @@ bool Item_user_var_as_out_param::fix_fields(THD *thd, Item **ref) DBUG_ASSERT(fixed == 0); DBUG_ASSERT(thd->lex->exchange); if (Item::fix_fields(thd, ref) || - !(entry= get_variable(&thd->user_vars, name, 1))) + !(entry= get_variable(&thd->user_vars, &name, 1))) return TRUE; entry->type= STRING_RESULT; /* @@ -5651,7 +5545,7 @@ void Item_user_var_as_out_param::print_for_load(THD *thd, String *str) Item_func_get_system_var:: Item_func_get_system_var(THD *thd, sys_var *var_arg, enum_var_type var_type_arg, - LEX_STRING *component_arg, const char *name_arg, + LEX_CSTRING *component_arg, const char *name_arg, size_t name_len_arg): Item_func(thd), var(var_arg), var_type(var_type_arg), orig_var_type(var_type_arg), component(*component_arg), cache_present(0) @@ -5758,8 +5652,8 @@ void Item_func_get_system_var::fix_length_and_dec() void Item_func_get_system_var::print(String *str, enum_query_type query_type) { - if (name_length) - str->append(name, name_length); + if (name.length) + str->append(name.str, name.length); else { str->append(STRING_WITH_LEN("@@")); @@ -6319,11 +6213,11 @@ longlong Item_func_bit_xor::val_int() */ -Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name, - LEX_STRING component) +Item *get_system_var(THD *thd, enum_var_type var_type, LEX_CSTRING name, + LEX_CSTRING component) { sys_var *var; - LEX_STRING *base_name, *component_name; + LEX_CSTRING *base_name, *component_name; if (component.str) { @@ -6426,7 +6320,7 @@ Item_func_sp::func_name() const } -void my_missing_function_error(const LEX_STRING &token, const char *func_name) +void my_missing_function_error(const LEX_CSTRING &token, const char *func_name) { if (token.length && is_lex_native_function (&token)) my_error(ER_FUNC_INEXISTENT_NAME_COLLISION, MYF(0), func_name); @@ -6456,7 +6350,6 @@ void my_missing_function_error(const LEX_STRING &token, const char *func_name) bool Item_func_sp::init_result_field(THD *thd) { - LEX_STRING empty_name= { C_STRING_WITH_LEN("") }; TABLE_SHARE *share; DBUG_ENTER("Item_func_sp::init_result_field"); @@ -6482,11 +6375,10 @@ Item_func_sp::init_result_field(THD *thd) dummy_table->maybe_null = maybe_null; dummy_table->in_use= thd; dummy_table->copy_blobs= TRUE; - share->table_cache_key = empty_name; - share->table_name = empty_name; + share->table_cache_key= empty_clex_str; + share->table_name= empty_clex_str; - if (!(sp_result_field= m_sp->create_result_field(max_length, name, - dummy_table))) + if (!(sp_result_field= m_sp->create_result_field(max_length, &name, dummy_table))) { DBUG_RETURN(TRUE); } @@ -6639,8 +6531,11 @@ Item_func_sp::make_field(THD *thd, Send_field *tmp_field) DBUG_ENTER("Item_func_sp::make_field"); DBUG_ASSERT(sp_result_field); sp_result_field->make_field(tmp_field); - if (name) + if (name.str) + { + DBUG_ASSERT(name.length == strlen(name.str)); tmp_field->col_name= name; + } DBUG_VOID_RETURN; } |