diff options
author | Alexander Nozdrin <alik@sun.com> | 2009-12-11 12:39:38 +0300 |
---|---|---|
committer | Alexander Nozdrin <alik@sun.com> | 2009-12-11 12:39:38 +0300 |
commit | 567671368723c704d60902b4d0ccff951b414552 (patch) | |
tree | 965519a5b0af3f33624c7e16fd61b58d15f42372 /sql/item.cc | |
parent | efee0608316e4cc034a3e62d05980eef8530843d (diff) | |
parent | ceefe7bb50b17b72e88851e3b98642e89a4cddae (diff) | |
download | mariadb-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.cc | 182 |
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; |