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_strfunc.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_strfunc.cc')
-rw-r--r-- | sql/item_strfunc.cc | 112 |
1 files changed, 74 insertions, 38 deletions
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 183a628f8e4..86a892a9dcc 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -528,11 +528,11 @@ String *Item_func_des_encrypt::val_str(String *str) return &tmp_value; error: - push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN, code, ER(code), "des_encrypt"); #else - push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN, ER_FEATURE_DISABLED, ER(ER_FEATURE_DISABLED), "des_encrypt","--with-openssl"); #endif /* HAVE_OPENSSL */ @@ -605,12 +605,12 @@ String *Item_func_des_decrypt::val_str(String *str) return &tmp_value; error: - push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN, code, ER(code), "des_decrypt"); wrong_key: #else - push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN, ER_FEATURE_DISABLED, ER(ER_FEATURE_DISABLED), "des_decrypt","--with-openssl"); #endif /* HAVE_OPENSSL */ @@ -2041,9 +2041,22 @@ String *Item_func_soundex::val_str(String *str) const int FORMAT_MAX_DECIMALS= 30; -Item_func_format::Item_func_format(Item *org, Item *dec) -: Item_str_func(org, dec) + +MY_LOCALE *Item_func_format::get_locale(Item *item) { + DBUG_ASSERT(arg_count == 3); + String tmp, *locale_name= args[2]->val_str(&tmp); + MY_LOCALE *lc; + if (!locale_name || + !(lc= my_locale_by_name(locale_name->c_ptr_safe()))) + { + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_UNKNOWN_LOCALE, + ER(ER_UNKNOWN_LOCALE), + locale_name ? locale_name->c_ptr_safe() : "NULL"); + lc= &my_locale_en_US; + } + return lc; } void Item_func_format::fix_length_and_dec() @@ -2053,6 +2066,10 @@ void Item_func_format::fix_length_and_dec() collation.set(default_charset()); max_length= (char_length + max_sep_count + decimals) * collation.collation->mbmaxlen; + if (arg_count == 3) + locale= args[2]->basic_const_item() ? get_locale(args[2]) : NULL; + else + locale= &my_locale_en_US; /* Two arguments */ } @@ -2064,13 +2081,12 @@ void Item_func_format::fix_length_and_dec() String *Item_func_format::val_str(String *str) { - uint32 length; uint32 str_length; /* Number of decimal digits */ int dec; /* Number of characters used to represent the decimals, including '.' */ uint32 dec_length; - int diff; + MY_LOCALE *lc; DBUG_ASSERT(fixed == 1); dec= (int) args[1]->val_int(); @@ -2080,6 +2096,8 @@ String *Item_func_format::val_str(String *str) return NULL; } + lc= locale ? locale : get_locale(args[2]); + dec= set_zone(dec, 0, FORMAT_MAX_DECIMALS); dec_length= dec ? dec+1 : 0; null_value=0; @@ -2094,8 +2112,6 @@ String *Item_func_format::val_str(String *str) my_decimal_round(E_DEC_FATAL_ERROR, res, dec, false, &rnd_dec); my_decimal2string(E_DEC_FATAL_ERROR, &rnd_dec, 0, 0, 0, str); str_length= str->length(); - if (rnd_dec.sign()) - str_length--; } else { @@ -2108,31 +2124,51 @@ String *Item_func_format::val_str(String *str) if (isnan(nr)) return str; str_length=str->length(); - if (nr < 0) - str_length--; // Don't count sign - } - /* We need this test to handle 'nan' values */ - if (str_length >= dec_length+4) - { - char *tmp,*pos; - length= str->length()+(diff=((int)(str_length- dec_length-1))/3); - str= copy_if_not_alloced(&tmp_str,str,length); - str->length(length); - tmp= (char*) str->ptr()+length - dec_length-1; - for (pos= (char*) str->ptr()+length-1; pos != tmp; pos--) - pos[0]= pos[-diff]; - while (diff) + } + /* We need this test to handle 'nan' and short values */ + if (lc->grouping[0] > 0 && + str_length >= dec_length + 1 + lc->grouping[0]) + { + char buf[DECIMAL_MAX_STR_LENGTH * 2]; /* 2 - in the worst case when grouping=1 */ + int count; + const char *grouping= lc->grouping; + char sign_length= *str->ptr() == '-' ? 1 : 0; + const char *src= str->ptr() + str_length - dec_length - 1; + const char *src_begin= str->ptr() + sign_length; + char *dst= buf + sizeof(buf); + + /* Put the fractional part */ + if (dec) + { + dst-= (dec + 1); + *dst= lc->decimal_point; + memcpy(dst + 1, src + 2, dec); + } + + /* Put the integer part with grouping */ + for (count= *grouping; src >= src_begin; count--) { - *pos= *(pos - diff); - pos--; - *pos= *(pos - diff); - pos--; - *pos= *(pos - diff); - pos--; - pos[0]=','; - pos--; - diff--; + /* + When *grouping==0x80 (which means "end of grouping") + count will be initialized to -1 and + we'll never get into this "if" anymore. + */ + if (!count) + { + *--dst= lc->thousand_sep; + if (grouping[1]) + grouping++; + count= *grouping; + } + DBUG_ASSERT(dst > buf); + *--dst= *src--; } + + if (sign_length) /* Put '-' */ + *--dst= *str->ptr(); + + /* Put the rest of the integer part without grouping */ + str->copy(dst, buf + sizeof(buf) - dst, &my_charset_latin1); } return str; } @@ -3238,7 +3274,7 @@ longlong Item_func_uncompressed_length::val_int() */ if (res->length() <= 4) { - push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_ZLIB_Z_DATA_ERROR, ER(ER_ZLIB_Z_DATA_ERROR)); null_value= 1; @@ -3315,7 +3351,7 @@ String *Item_func_compress::val_str(String *str) (const Bytef*)res->ptr(), res->length())) != Z_OK) { code= err==Z_MEM_ERROR ? ER_ZLIB_Z_MEM_ERROR : ER_ZLIB_Z_BUF_ERROR; - push_warning(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR,code,ER(code)); + push_warning(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN,code,ER(code)); null_value= 1; return 0; } @@ -3353,7 +3389,7 @@ String *Item_func_uncompress::val_str(String *str) /* If length is less than 4 bytes, data is corrupt */ if (res->length() <= 4) { - push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN, ER_ZLIB_Z_DATA_ERROR, ER(ER_ZLIB_Z_DATA_ERROR)); goto err; @@ -3363,7 +3399,7 @@ String *Item_func_uncompress::val_str(String *str) new_size= uint4korr(res->ptr()) & 0x3FFFFFFF; if (new_size > current_thd->variables.max_allowed_packet) { - push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN, ER_TOO_BIG_FOR_UNCOMPRESS, ER(ER_TOO_BIG_FOR_UNCOMPRESS), current_thd->variables.max_allowed_packet); @@ -3381,7 +3417,7 @@ String *Item_func_uncompress::val_str(String *str) code= ((err == Z_BUF_ERROR) ? ER_ZLIB_Z_BUF_ERROR : ((err == Z_MEM_ERROR) ? ER_ZLIB_Z_MEM_ERROR : ER_ZLIB_Z_DATA_ERROR)); - push_warning(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR,code,ER(code)); + push_warning(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN,code,ER(code)); err: null_value= 1; |