summaryrefslogtreecommitdiff
path: root/sql/item.cc
diff options
context:
space:
mode:
authorAlexander Nozdrin <alik@sun.com>2009-12-11 12:39:38 +0300
committerAlexander Nozdrin <alik@sun.com>2009-12-11 12:39:38 +0300
commit567671368723c704d60902b4d0ccff951b414552 (patch)
tree965519a5b0af3f33624c7e16fd61b58d15f42372 /sql/item.cc
parentefee0608316e4cc034a3e62d05980eef8530843d (diff)
parentceefe7bb50b17b72e88851e3b98642e89a4cddae (diff)
downloadmariadb-git-567671368723c704d60902b4d0ccff951b414552.tar.gz
Manual merge from mysql-trunk.
Conflicts: - client/mysqltest.cc - mysql-test/collections/default.experimental - mysql-test/suite/rpl/t/disabled.def - sql/mysqld.cc - sql/opt_range.cc - sql/sp.cc - sql/sql_acl.cc - sql/sql_partition.cc - sql/sql_table.cc
Diffstat (limited to 'sql/item.cc')
-rw-r--r--sql/item.cc182
1 files changed, 173 insertions, 9 deletions
diff --git a/sql/item.cc b/sql/item.cc
index b35a6ae3d6e..ba920497ec1 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -264,10 +264,11 @@ my_decimal *Item::val_decimal_from_string(my_decimal *decimal_value)
res->ptr(), res->length(), res->charset(),
decimal_value) & E_DEC_BAD_NUM)
{
+ ErrConvString err(res);
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_TRUNCATED_WRONG_VALUE,
ER(ER_TRUNCATED_WRONG_VALUE), "DECIMAL",
- str_value.c_ptr());
+ err.ptr());
}
return decimal_value;
}
@@ -2447,6 +2448,7 @@ double_from_string_with_check (CHARSET_INFO *cs, const char *cptr, char *end)
tmp= my_strntod(cs, (char*) cptr, end - cptr, &end, &error);
if (error || (end != org_end && !check_if_only_end_space(cs, end, org_end)))
{
+ ErrConvString err(cptr, cs);
/*
We can use str_value.ptr() here as Item_string is gurantee to put an
end \0 here.
@@ -2454,7 +2456,7 @@ double_from_string_with_check (CHARSET_INFO *cs, const char *cptr, char *end)
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_TRUNCATED_WRONG_VALUE,
ER(ER_TRUNCATED_WRONG_VALUE), "DOUBLE",
- cptr);
+ err.ptr());
}
return tmp;
}
@@ -2484,10 +2486,11 @@ longlong_from_string_with_check (CHARSET_INFO *cs, const char *cptr, char *end)
(err > 0 ||
(end != org_end && !check_if_only_end_space(cs, end, org_end))))
{
+ ErrConvString err(cptr, cs);
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_TRUNCATED_WRONG_VALUE,
ER(ER_TRUNCATED_WRONG_VALUE), "INTEGER",
- cptr);
+ err.ptr());
}
return tmp;
}
@@ -2574,7 +2577,8 @@ Item_param::Item_param(uint pos_in_query_arg) :
param_type(MYSQL_TYPE_VARCHAR),
pos_in_query(pos_in_query_arg),
set_param_func(default_set_param_func),
- limit_clause_param(FALSE)
+ limit_clause_param(FALSE),
+ m_out_param_info(NULL)
{
name= (char*) "?";
/*
@@ -2656,6 +2660,17 @@ void Item_param::set_decimal(const char *str, ulong length)
DBUG_VOID_RETURN;
}
+void Item_param::set_decimal(const my_decimal *dv)
+{
+ state= DECIMAL_VALUE;
+
+ my_decimal2decimal(dv, &decimal_value);
+
+ decimals= (uint8) decimal_value.frac;
+ unsigned_flag= !decimal_value.sign();
+ max_length= my_decimal_precision_to_length(decimal_value.intg + decimals,
+ decimals, unsigned_flag);
+}
/**
Set parameter value from MYSQL_TIME value.
@@ -3278,6 +3293,158 @@ Item_param::set_param_type_and_swap_value(Item_param *src)
str_value_ptr.swap(src->str_value_ptr);
}
+
+/**
+ This operation is intended to store some item value in Item_param to be
+ used later.
+
+ @param thd thread context
+ @param ctx stored procedure runtime context
+ @param it a pointer to an item in the tree
+
+ @return Error status
+ @retval TRUE on error
+ @retval FALSE on success
+*/
+
+bool
+Item_param::set_value(THD *thd, sp_rcontext *ctx, Item **it)
+{
+ Item *value= *it;
+
+ if (value->is_null())
+ {
+ set_null();
+ return FALSE;
+ }
+
+ null_value= FALSE;
+
+ switch (value->result_type()) {
+ case STRING_RESULT:
+ {
+ char str_buffer[STRING_BUFFER_USUAL_SIZE];
+ String sv_buffer(str_buffer, sizeof(str_buffer), &my_charset_bin);
+ String *sv= value->val_str(&sv_buffer);
+
+ if (!sv)
+ return TRUE;
+
+ set_str(sv->c_ptr_safe(), sv->length());
+ str_value_ptr.set(str_value.ptr(),
+ str_value.length(),
+ str_value.charset());
+ collation.set(str_value.charset(), DERIVATION_COERCIBLE);
+ decimals= 0;
+ param_type= MYSQL_TYPE_STRING;
+
+ break;
+ }
+
+ case REAL_RESULT:
+ set_double(value->val_real());
+ param_type= MYSQL_TYPE_DOUBLE;
+ break;
+
+ case INT_RESULT:
+ set_int(value->val_int(), value->max_length);
+ param_type= MYSQL_TYPE_LONG;
+ break;
+
+ case DECIMAL_RESULT:
+ {
+ my_decimal dv_buf;
+ my_decimal *dv= value->val_decimal(&dv_buf);
+
+ if (!dv)
+ return TRUE;
+
+ set_decimal(dv);
+ param_type= MYSQL_TYPE_NEWDECIMAL;
+
+ break;
+ }
+
+ default:
+ /* That can not happen. */
+
+ DBUG_ASSERT(TRUE); // Abort in debug mode.
+
+ set_null(); // Set to NULL in release mode.
+ return FALSE;
+ }
+
+ item_result_type= value->result_type();
+ item_type= value->type();
+ return FALSE;
+}
+
+
+/**
+ Setter of Item_param::m_out_param_info.
+
+ m_out_param_info is used to store information about store routine
+ OUT-parameters, such as stored routine name, database, stored routine
+ variable name. It is supposed to be set in sp_head::execute() after
+ Item_param::set_value() is called.
+*/
+
+void
+Item_param::set_out_param_info(Send_field *info)
+{
+ m_out_param_info= info;
+}
+
+
+/**
+ Getter of Item_param::m_out_param_info.
+
+ m_out_param_info is used to store information about store routine
+ OUT-parameters, such as stored routine name, database, stored routine
+ variable name. It is supposed to be retrieved in
+ Protocol_binary::send_out_parameters() during creation of OUT-parameter
+ result set.
+*/
+
+const Send_field *
+Item_param::get_out_param_info() const
+{
+ return m_out_param_info;
+}
+
+
+/**
+ Fill meta-data information for the corresponding column in a result set.
+ If this is an OUT-parameter of a stored procedure, preserve meta-data of
+ stored-routine variable.
+
+ @param field container for meta-data to be filled
+*/
+
+void Item_param::make_field(Send_field *field)
+{
+ Item::make_field(field);
+
+ if (!m_out_param_info)
+ return;
+
+ /*
+ This is an OUT-parameter of stored procedure. We should use
+ OUT-parameter info to fill out the names.
+ */
+
+ field->db_name= m_out_param_info->db_name;
+ field->table_name= m_out_param_info->table_name;
+ field->org_table_name= m_out_param_info->org_table_name;
+ field->col_name= m_out_param_info->col_name;
+ field->org_col_name= m_out_param_info->org_col_name;
+ field->length= m_out_param_info->length;
+ field->charsetnr= m_out_param_info->charsetnr;
+ field->flags= m_out_param_info->flags;
+ field->decimals= m_out_param_info->decimals;
+ field->type= m_out_param_info->type;
+}
+
/****************************************************************************
Item_copy
****************************************************************************/
@@ -3509,7 +3676,7 @@ void Item_copy_decimal::copy()
/*
- Functions to convert item to field (for send_fields)
+ Functions to convert item to field (for send_result_set_metadata)
*/
/* ARGSUSED */
@@ -4773,7 +4940,6 @@ String *Item::check_well_formed_result(String *str, bool send_error)
{
THD *thd= current_thd;
char hexbuf[7];
- enum MYSQL_ERROR::enum_warning_level level;
uint diff= str->length() - wlen;
set_if_smaller(diff, 3);
octet2hex(hexbuf, str->ptr() + wlen, diff);
@@ -4786,16 +4952,14 @@ String *Item::check_well_formed_result(String *str, bool send_error)
if ((thd->variables.sql_mode &
(MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES)))
{
- level= MYSQL_ERROR::WARN_LEVEL_ERROR;
null_value= 1;
str= 0;
}
else
{
- level= MYSQL_ERROR::WARN_LEVEL_WARN;
str->length(wlen);
}
- push_warning_printf(thd, level, ER_INVALID_CHARACTER_STRING,
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_INVALID_CHARACTER_STRING,
ER(ER_INVALID_CHARACTER_STRING), cs->csname, hexbuf);
}
return str;