summaryrefslogtreecommitdiff
path: root/sql/item_func.cc
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2017-04-24 09:54:12 +0400
committerAlexander Barkov <bar@mariadb.org>2017-04-24 09:54:12 +0400
commit79ecd75afd1d6f0adc5bb6c840b9d3c66f014239 (patch)
tree71cc3b35dd38106f22c78577ba5fcd63bb92776b /sql/item_func.cc
parent530396cef0fff2a67faf42f9683bdc5ccb893217 (diff)
parent5a759d31f766087d5e135e1d3d3d987693bc9b88 (diff)
downloadmariadb-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.cc189
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;
}