#At file:///home/kgeorge/mysql/work/B49141-5.1-bugteam/ based on revid:satya.bn@stripped
3237 Georgi Kodinov 2009-12-02
Bug #49141: Encode function is significantly slower in 5.1 compared to 5.0
The fix for bug 22684 moved all the calculations to run time.
For some special cases (e.g. a constant password) it's greatly beneficial
to initialize the random structures at compile time and only calculate
the outcome of the operation at run time.
Implemented such caching of the random structures initialization.
Fixed both ENCODE() and DECODE() functions.
modified:
sql/item_strfunc.cc
sql/item_strfunc.h
sql/sql_crypt.cc
sql/sql_crypt.h
=== modified file 'sql/item_strfunc.cc'
--- a/sql/item_strfunc.cc 2009-11-18 14:50:31 +0000
+++ b/sql/item_strfunc.cc 2009-12-02 15:08:44 +0000
@@ -1722,16 +1722,27 @@ String *Item_func_encrypt::val_str(Strin
void Item_func_encode::fix_length_and_dec()
{
+ Item *password_item= args[1];
+
max_length=args[0]->max_length;
maybe_null=args[0]->maybe_null || args[1]->maybe_null;
collation.set(&my_charset_bin);
+
+ if (password_item->const_item() && password_item->result_type() == STRING_RESULT)
+ {
+ char pw_buff[80];
+ String tmp_pw_value(pw_buff, sizeof(pw_buff), system_charset_info);
+ String *str, *res;
+
+ if (!(str= password_item->val_str(&tmp_pw_value)))
+ return;
+ sql_crypt.crypt_password_hash (str->ptr(), str->length());
+ }
}
String *Item_func_encode::val_str(String *str)
{
String *res;
- char pw_buff[80];
- String tmp_pw_value(pw_buff, sizeof(pw_buff), system_charset_info);
String *password;
DBUG_ASSERT(fixed == 1);
@@ -1741,45 +1752,33 @@ String *Item_func_encode::val_str(String
return 0; /* purecov: inspected */
}
- if (!(password=args[1]->val_str(& tmp_pw_value)))
+ if (!sql_crypt.is_initialized())
{
- null_value=1;
- return 0;
+ char pw_buff[80];
+ String tmp_pw_value(pw_buff, sizeof(pw_buff), system_charset_info);
+ if (!(password=args[1]->val_str(& tmp_pw_value)))
+ {
+ null_value=1;
+ return 0;
+ }
+ sql_crypt.crypt_password_hash (password->ptr(), password->length());
}
null_value=0;
res=copy_if_not_alloced(str,res,res->length());
- SQL_CRYPT sql_crypt(password->ptr(), password->length());
sql_crypt.init();
+ return calculate(res);
+}
+
+String *Item_func_encode::calculate(String *res)
+{
sql_crypt.encode((char*) res->ptr(),res->length());
res->set_charset(&my_charset_bin);
return res;
}
-String *Item_func_decode::val_str(String *str)
+String *Item_func_decode::calculate(String *res)
{
- 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(), password->length());
- sql_crypt.init();
sql_crypt.decode((char*) res->ptr(),res->length());
return res;
}
=== modified file 'sql/item_strfunc.h'
--- a/sql/item_strfunc.h 2009-06-01 12:00:38 +0000
+++ b/sql/item_strfunc.h 2009-12-02 15:08:44 +0000
@@ -351,12 +351,16 @@ public:
class Item_func_encode :public Item_str_func
{
+protected:
+ SQL_CRYPT sql_crypt;
public:
Item_func_encode(Item *a, Item *seed):
- Item_str_func(a, seed) {}
+ Item_str_func(a, seed), sql_crypt() {}
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "encode"; }
+protected:
+ virtual String *calculate (String *argument);
};
@@ -364,8 +368,9 @@ class Item_func_decode :public Item_func
{
public:
Item_func_decode(Item *a, Item *seed): Item_func_encode(a, seed) {}
- String *val_str(String *);
const char *func_name() const { return "decode"; }
+protected:
+ String *calculate (String *argument);
};
=== modified file 'sql/sql_crypt.cc'
--- a/sql/sql_crypt.cc 2009-04-23 07:43:42 +0000
+++ b/sql/sql_crypt.cc 2009-12-02 15:08:44 +0000
@@ -28,7 +28,7 @@
#include "mysql_priv.h"
-SQL_CRYPT::SQL_CRYPT(const char *password, uint length)
+void SQL_CRYPT::crypt_password_hash(const char *password, uint length)
{
ulong rand_nr[2];
hash_password(rand_nr,password, length);
@@ -54,6 +54,7 @@ void SQL_CRYPT::crypt_init(ulong *rand_n
encode_buff[(uchar) decode_buff[i]]=i;
org_rand=rand;
shift=0;
+ initialized= TRUE;
}
=== modified file 'sql/sql_crypt.h'
--- a/sql/sql_crypt.h 2009-04-23 07:43:42 +0000
+++ b/sql/sql_crypt.h 2009-12-02 15:08:44 +0000
@@ -24,9 +24,14 @@ class SQL_CRYPT :public Sql_alloc
char decode_buff[256],encode_buff[256];
uint shift;
void crypt_init(ulong *seed);
+ bool initialized;
public:
- SQL_CRYPT(const char *seed, uint length);
- SQL_CRYPT(ulong *seed)
+ SQL_CRYPT() : initialized (FALSE) {}
+ SQL_CRYPT(const char *seed, uint length) : initialized(FALSE)
+ {
+ crypt_password_hash(seed, length);
+ }
+ SQL_CRYPT(ulong *seed) : initialized(FALSE)
{
crypt_init(seed);
}
@@ -34,4 +39,6 @@ class SQL_CRYPT :public Sql_alloc
void init() { shift=0; rand=org_rand; }
void encode(char *str, uint length);
void decode(char *str, uint length);
+ void crypt_password_hash (const char *password, uint length);
+ bool is_initialized() { return initialized; };
};
Attachment: [text/bzr-bundle] bzr/joro@sun.com-20091202150844-lkstj65b8usxtjew.bundle