diff options
Diffstat (limited to 'sql/item_strfunc.cc')
-rw-r--r-- | sql/item_strfunc.cc | 116 |
1 files changed, 73 insertions, 43 deletions
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 20a4b64640a..d54b9961562 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -25,12 +25,10 @@ #include "mysql_priv.h" #include <m_ctype.h> -#ifdef HAVE_OPENSSL -#include <openssl/des.h> -#endif /* HAVE_OPENSSL */ #include "my_md5.h" #include "sha1.h" #include "my_aes.h" +#include <zlib.h> C_MODE_START #include "../mysys/my_static.h" // For soundex_map C_MODE_END @@ -132,11 +130,11 @@ String *Item_func_md5::val_str(String *str) if (sptr) { my_MD5_CTX context; - unsigned char digest[16]; + uchar digest[16]; null_value=0; my_MD5Init (&context); - my_MD5Update (&context,(unsigned char *) sptr->ptr(), sptr->length()); + my_MD5Update (&context,(uchar *) sptr->ptr(), sptr->length()); my_MD5Final (digest, &context); if (str->alloc(32)) // Ensure that memory is free { @@ -184,7 +182,7 @@ String *Item_func_sha::val_str(String *str) mysql_sha1_reset(&context); /* We do not have to check for error here */ /* No need to check error as the only case would be too long message */ mysql_sha1_input(&context, - (const unsigned char *) sptr->ptr(), sptr->length()); + (const uchar *) sptr->ptr(), sptr->length()); /* Ensure that memory is free and we got result */ if (!( str->alloc(SHA1_HASH_SIZE*2) || (mysql_sha1_result(&context,digest)))) @@ -973,8 +971,8 @@ String *Item_func_insert::val_str(String *str) length= res->length(); /* start and length are now sufficiently valid to pass to charpos function */ - start= res->charpos((int) start); - length= res->charpos((int) length, (uint32) start); + start= res->charpos((int) start); + length= res->charpos((int) length, (uint32) start); /* Re-testing with corrected params */ if (start > res->length()) @@ -1664,51 +1662,62 @@ String *Item_func_encrypt::val_str(String *str) void Item_func_encode::fix_length_and_dec() { max_length=args[0]->max_length; - maybe_null=args[0]->maybe_null; + maybe_null=args[0]->maybe_null || args[1]->maybe_null; collation.set(&my_charset_bin); } String *Item_func_encode::val_str(String *str) { - DBUG_ASSERT(fixed == 1); String *res; + char pw_buff[80]; + String tmp_pw_value(pw_buff, sizeof(pw_buff), system_charset_info); + String *password; + DBUG_ASSERT(fixed == 1); + if (!(res=args[0]->val_str(str))) { null_value=1; /* purecov: inspected */ return 0; /* purecov: inspected */ } + + if (!(password=args[1]->val_str(& tmp_pw_value))) + { + null_value=1; + return 0; + } + null_value=0; res=copy_if_not_alloced(str,res,res->length()); + SQL_CRYPT sql_crypt(password->ptr()); sql_crypt.init(); sql_crypt.encode((char*) res->ptr(),res->length()); res->set_charset(&my_charset_bin); return res; } -void Item_func_encode::print(String *str) -{ - str->append(func_name()); - str->append('('); - args[0]->print(str); - str->append(','); - str->append('\''); - str->append(seed); - str->append('\''); - str->append(')'); -} - - String *Item_func_decode::val_str(String *str) { - DBUG_ASSERT(fixed == 1); String *res; + char pw_buff[80]; + String tmp_pw_value(pw_buff, sizeof(pw_buff), system_charset_info); + String *password; + DBUG_ASSERT(fixed == 1); + if (!(res=args[0]->val_str(str))) { null_value=1; /* purecov: inspected */ return 0; /* purecov: inspected */ } + + if (!(password=args[1]->val_str(& tmp_pw_value))) + { + null_value=1; + return 0; + } + null_value=0; res=copy_if_not_alloced(str,res,res->length()); + SQL_CRYPT sql_crypt(password->ptr()); sql_crypt.init(); sql_crypt.decode((char*) res->ptr(),res->length()); return res; @@ -1960,9 +1969,19 @@ String *Item_func_soundex::val_str(String *str) ** This should be 'internationalized' sometimes. */ -Item_func_format::Item_func_format(Item *org,int dec) :Item_str_func(org) +const int FORMAT_MAX_DECIMALS= 30; + +Item_func_format::Item_func_format(Item *org, Item *dec) +: Item_str_func(org, dec) +{ +} + +void Item_func_format::fix_length_and_dec() { - decimals=(uint) set_zone(dec,0,30); + collation.set(default_charset()); + uint char_length= args[0]->max_length/args[0]->collation.collation->mbmaxlen; + max_length= ((char_length + (char_length-args[0]->decimals)/3) * + collation.collation->mbmaxlen); } @@ -1973,10 +1992,25 @@ Item_func_format::Item_func_format(Item *org,int dec) :Item_str_func(org) String *Item_func_format::val_str(String *str) { - uint32 length, str_length ,dec; + 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; DBUG_ASSERT(fixed == 1); - dec= decimals ? decimals+1 : 0; + + dec= (int) args[1]->val_int(); + if (args[1]->null_value) + { + null_value=1; + return NULL; + } + + dec= set_zone(dec, 0, FORMAT_MAX_DECIMALS); + dec_length= dec ? dec+1 : 0; + null_value=0; if (args[0]->result_type() == DECIMAL_RESULT || args[0]->result_type() == INT_RESULT) @@ -1985,7 +2019,7 @@ String *Item_func_format::val_str(String *str) res= args[0]->val_decimal(&dec_val); if ((null_value=args[0]->null_value)) return 0; /* purecov: inspected */ - my_decimal_round(E_DEC_FATAL_ERROR, res, decimals, false, &rnd_dec); + 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()) @@ -1996,9 +2030,9 @@ String *Item_func_format::val_str(String *str) double nr= args[0]->val_real(); if ((null_value=args[0]->null_value)) return 0; /* purecov: inspected */ - nr= my_double_round(nr, (longlong) decimals, FALSE, FALSE); + nr= my_double_round(nr, (longlong) dec, FALSE, FALSE); /* Here default_charset() is right as this is not an automatic conversion */ - str->set(nr,decimals, default_charset()); + str->set_real(nr, dec, default_charset()); if (isnan(nr)) return str; str_length=str->length(); @@ -2006,13 +2040,13 @@ String *Item_func_format::val_str(String *str) str_length--; // Don't count sign } /* We need this test to handle 'nan' values */ - if (str_length >= dec+4) + if (str_length >= dec_length+4) { char *tmp,*pos; - length= str->length()+(diff=((int)(str_length- dec-1))/3); + 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-1; + tmp= (char*) str->ptr()+length - dec_length-1; for (pos= (char*) str->ptr()+length-1; pos != tmp; pos--) pos[0]= pos[-diff]; while (diff) @@ -2036,12 +2070,8 @@ void Item_func_format::print(String *str) { str->append(STRING_WITH_LEN("format(")); args[0]->print(str); - str->append(','); - // my_charset_bin is good enough for numbers - char buffer[20]; - String st(buffer, sizeof(buffer), &my_charset_bin); - st.set((ulonglong)decimals, &my_charset_bin); - str->append(st); + str->append(','); + args[1]->print(str); str->append(')'); } @@ -2192,7 +2222,7 @@ String *Item_func_make_set::val_str(String *str) } -Item *Item_func_make_set::transform(Item_transformer transformer, byte *arg) +Item *Item_func_make_set::transform(Item_transformer transformer, uchar *arg) { DBUG_ASSERT(!current_thd->is_stmt_prepare()); @@ -2415,7 +2445,7 @@ String *Item_func_rpad::val_str(String *str) count= INT_MAX32; if (count <= (res_char_length= res->numchars())) { // String to pad is big enough - res->length(res->charpos((int) count)); // Shorten result if longer + res->length(res->charpos((int) count)); // Shorten result if longer return (res); } pad_char_length= rpad->numchars(); @@ -2875,7 +2905,7 @@ String *Item_load_file::val_str(String *str) goto err; if ((file = my_open(file_name->c_ptr(), O_RDONLY, MYF(0))) < 0) goto err; - if (my_read(file, (byte*) tmp_value.ptr(), stat_info.st_size, MYF(MY_NABP))) + if (my_read(file, (uchar*) tmp_value.ptr(), stat_info.st_size, MYF(MY_NABP))) { my_close(file, MYF(0)); goto err; |