diff options
author | Jonathan Perkin <jonathan.perkin@oracle.com> | 2010-12-16 11:13:58 +0100 |
---|---|---|
committer | Jonathan Perkin <jonathan.perkin@oracle.com> | 2010-12-16 11:13:58 +0100 |
commit | 33827e7dbfc177ef52718f63eaf87e005ab3e8b5 (patch) | |
tree | 83c2beab0fb52424ab77dcb1449a3f394f0d0fe1 /sql/item.cc | |
parent | dec388d5beac2e9d0d32ce1610b871c3d1042544 (diff) | |
parent | cf175bf4b8fef9c054fa4779fbea011ad43432a0 (diff) | |
download | mariadb-git-33827e7dbfc177ef52718f63eaf87e005ab3e8b5.tar.gz |
Merge from mysql-5.5.8-release
Diffstat (limited to 'sql/item.cc')
-rw-r--r-- | sql/item.cc | 82 |
1 files changed, 57 insertions, 25 deletions
diff --git a/sql/item.cc b/sql/item.cc index b166f3e645f..8957e6e7133 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -226,8 +226,6 @@ bool Item::val_bool() */ String *Item::val_str_ascii(String *str) { - DBUG_ASSERT(fixed == 1); - if (!(collation.collation->state & MY_CS_NONASCII)) return val_str(str); @@ -1853,11 +1851,12 @@ bool agg_item_set_converter(DTCollation &coll, const char *fname, *arg= conv; else thd->change_item_tree(arg, conv); - /* - We do not check conv->fixed, because Item_func_conv_charset which can - be return by safe_charset_converter can't be fixed at creation - */ - conv->fix_fields(thd, arg); + + if (conv->fix_fields(thd, arg)) + { + res= TRUE; + break; // we cannot return here, we need to restore "arena". + } } if (arena) thd->restore_active_arena(arena, &backup); @@ -3458,19 +3457,16 @@ Item_param::set_value(THD *thd, sp_rcontext *ctx, Item **it) str_value.charset()); collation.set(str_value.charset(), DERIVATION_COERCIBLE); decimals= 0; - param_type= MYSQL_TYPE_STRING; break; } case REAL_RESULT: set_double(arg->val_real()); - param_type= MYSQL_TYPE_DOUBLE; break; case INT_RESULT: set_int(arg->val_int(), arg->max_length); - param_type= MYSQL_TYPE_LONG; break; case DECIMAL_RESULT: @@ -3482,8 +3478,6 @@ Item_param::set_value(THD *thd, sp_rcontext *ctx, Item **it) return TRUE; set_decimal(dv); - param_type= MYSQL_TYPE_NEWDECIMAL; - break; } @@ -3515,6 +3509,7 @@ void Item_param::set_out_param_info(Send_field *info) { m_out_param_info= info; + param_type= m_out_param_info->type; } @@ -3560,6 +3555,7 @@ void Item_param::make_field(Send_field *field) 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; @@ -5531,17 +5527,43 @@ static uint nr_of_decimals(const char *str, const char *end) break; } decimal_point= str; - for (; my_isdigit(system_charset_info, *str) ; str++) + for ( ; str < end && my_isdigit(system_charset_info, *str) ; str++) ; - if (*str == 'e' || *str == 'E') + if (str < end && (*str == 'e' || *str == 'E')) return NOT_FIXED_DEC; + /* + QQ: + The number of decimal digist in fact should be (str - decimal_point - 1). + But it seems the result of nr_of_decimals() is never used! + + In case of 'e' and 'E' nr_of_decimals returns NOT_FIXED_DEC. + In case if there is no 'e' or 'E' parser code in sql_yacc.yy + never calls Item_float::Item_float() - it creates Item_decimal instead. + + The only piece of code where we call Item_float::Item_float(str, len) + without having 'e' or 'E' is item_xmlfunc.cc, but this Item_float + never appears in metadata itself. Changing the code to return + (str - decimal_point - 1) does not make any changes in the test results. + + This should be addressed somehow. + Looks like a reminder from before real DECIMAL times. + */ return (uint) (str - decimal_point); } /** - This function is only called during parsing. We will signal an error if - value is not a true double value (overflow) + This function is only called during parsing: + - when parsing SQL query from sql_yacc.yy + - when parsing XPath query from item_xmlfunc.cc + We will signal an error if value is not a true double value (overflow): + eng: Illegal %s '%-.192s' value found during parsing + + Note: the string is NOT null terminated when called from item_xmlfunc.cc, + so this->name will contain some SQL query tail behind the "length" bytes. + This is Ok for now, as this Item is never seen in SHOW, + or EXPLAIN, or anywhere else in metadata. + Item->name should be fixed to use LEX_STRING eventually. */ Item_float::Item_float(const char *str_arg, uint length) @@ -5552,12 +5574,9 @@ Item_float::Item_float(const char *str_arg, uint length) &error); if (error) { - /* - Note that we depend on that str_arg is null terminated, which is true - when we are in the parser - */ - DBUG_ASSERT(str_arg[length] == 0); - my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "double", (char*) str_arg); + char tmp[NAME_LEN + 1]; + my_snprintf(tmp, sizeof(tmp), "%.*s", length, str_arg); + my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "double", tmp); } presentation= name=(char*) str_arg; decimals=(uint8) nr_of_decimals(str_arg, str_arg+length); @@ -7493,9 +7512,19 @@ void Item_cache_datetime::store(Item *item, longlong val_arg) } +void Item_cache_datetime::store(Item *item) +{ + Item_cache::store(item); + str_value_cached= FALSE; +} + String *Item_cache_datetime::val_str(String *str) { DBUG_ASSERT(fixed == 1); + + if ((value_cached || str_value_cached) && null_value) + return NULL; + if (!str_value_cached) { /* @@ -7509,6 +7538,8 @@ String *Item_cache_datetime::val_str(String *str) if (value_cached) { MYSQL_TIME ltime; + /* Return NULL in case of OOM/conversion error. */ + null_value= TRUE; if (str_value.alloc(MAX_DATE_STRING_REP_LENGTH)) return NULL; if (cached_field_type == MYSQL_TYPE_TIME) @@ -7531,13 +7562,14 @@ String *Item_cache_datetime::val_str(String *str) { int was_cut; longlong res; - res= number_to_datetime(val_int(), <ime, TIME_FUZZY_DATE, &was_cut); + res= number_to_datetime(int_value, <ime, TIME_FUZZY_DATE, &was_cut); if (res == -1) return NULL; } str_value.length(my_TIME_to_str(<ime, const_cast<char*>(str_value.ptr()))); str_value_cached= TRUE; + null_value= FALSE; } else if (!cache_value()) return NULL; @@ -7558,7 +7590,7 @@ my_decimal *Item_cache_datetime::val_decimal(my_decimal *decimal_val) double Item_cache_datetime::val_real() { DBUG_ASSERT(fixed == 1); - if (!value_cached && !cache_value_int()) + if ((!value_cached && !cache_value_int()) || null_value) return 0.0; return (double) int_value; } @@ -7566,7 +7598,7 @@ double Item_cache_datetime::val_real() longlong Item_cache_datetime::val_int() { DBUG_ASSERT(fixed == 1); - if (!value_cached && !cache_value_int()) + if ((!value_cached && !cache_value_int()) || null_value) return 0; return int_value; } |