diff options
-rw-r--r-- | mysql-test/r/func_str.result | 9 | ||||
-rw-r--r-- | mysql-test/t/func_str.test | 3 | ||||
-rw-r--r-- | sql/item_create.cc | 5 | ||||
-rw-r--r-- | sql/item_create.h | 1 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 44 | ||||
-rw-r--r-- | sql/item_strfunc.h | 35 | ||||
-rw-r--r-- | sql/lex.h | 1 |
7 files changed, 87 insertions, 11 deletions
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index c9eba2f2505..d213883df76 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -192,6 +192,15 @@ length(quote(concat(char(0),"test"))) select hex(quote(concat(char(224),char(227),char(230),char(231),char(232),char(234),char(235)))); hex(quote(concat(char(224),char(227),char(230),char(231),char(232),char(234),char(235)))) 27E0E3E6E7E8EAEB27 +select unhex(hex("foobar")), hex(unhex("1234567890ABCDEF")), unhex("345678"); +unhex(hex("foobar")) hex(unhex("1234567890ABCDEF")) unhex("345678") +foobar 1234567890ABCDEF 4Vx +select hex(unhex("1")), hex(unhex("12")), hex(unhex("123")), hex(unhex("1234")), hex(unhex("12345")), hex(unhex("123456")); +hex(unhex("1")) hex(unhex("12")) hex(unhex("123")) hex(unhex("1234")) hex(unhex("12345")) hex(unhex("123456")) +01 12 0123 1234 012345 123456 +select length(unhex(md5("abrakadabra"))); +length(unhex(md5("abrakadabra"))) +16 select reverse(""); reverse("") diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index a9c2895206d..6e4fc21f4b0 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -78,6 +78,9 @@ select quote(concat('abc\'', '\\cba')); select quote(1/0), quote('\0\Z'); select length(quote(concat(char(0),"test"))); select hex(quote(concat(char(224),char(227),char(230),char(231),char(232),char(234),char(235)))); +select unhex(hex("foobar")), hex(unhex("1234567890ABCDEF")), unhex("345678"); +select hex(unhex("1")), hex(unhex("12")), hex(unhex("123")), hex(unhex("1234")), hex(unhex("12345")), hex(unhex("123456")); +select length(unhex(md5("abrakadabra"))); # # Wrong usage of functions diff --git a/sql/item_create.cc b/sql/item_create.cc index eda3d43afdc..c6c5fd77b79 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -426,6 +426,11 @@ Item *create_func_ucase(Item* a) return new Item_func_ucase(a); } +Item *create_func_unhex(Item* a) +{ + return new Item_func_unhex(a); +} + Item *create_func_uuid(void) { return new Item_func_uuid(); diff --git a/sql/item_create.h b/sql/item_create.h index a6a3c9e1841..7577627ef04 100644 --- a/sql/item_create.h +++ b/sql/item_create.h @@ -92,6 +92,7 @@ Item *create_func_time_format(Item *a, Item *b); Item *create_func_time_to_sec(Item* a); Item *create_func_to_days(Item* a); Item *create_func_ucase(Item* a); +Item *create_func_unhex(Item* a); Item *create_func_uuid(void); Item *create_func_version(void); Item *create_func_weekday(Item* a); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index fdf65a1f834..b9604cf900b 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2231,7 +2231,7 @@ String *Item_func_hex::val_str(String *str) null_value=0; tmp_value.length(res->length()*2); for (from=res->ptr(), end=from+res->length(), to= (char*) tmp_value.ptr(); - from != end ; + from < end ; from++, to+=2) { uint tmp=(uint) (uchar) *from; @@ -2241,6 +2241,48 @@ String *Item_func_hex::val_str(String *str) return &tmp_value; } +int inline hexchar_to_int(char c) +{ + if (c <= '9' && c >= '0') + return c-'0'; + c|=32; + if (c <= 'f' && c >= 'a') + return c-'a'+10; + return -1; +} + +String *Item_func_unhex::val_str(String *str) +{ + /* Convert given hex string to a binary string */ + String *res= args[0]->val_str(str); + const char *from=res->ptr(), *end; + char *to; + int r; + if (!res || tmp_value.alloc((1+res->length())/2)) + { + null_value=1; + return 0; + } + null_value=0; + tmp_value.length((1+res->length())/2); + to= (char*) tmp_value.ptr(); + if (res->length() % 2) + { + *to++= r= hexchar_to_int(*from++); + if ((null_value= (r == -1))) + return 0; + } + for (end=res->ptr()+res->length(); from < end ; from+=2, to++) + { + *to= (r= hexchar_to_int(from[0])) << 4; + if ((null_value= (r == -1))) + return 0; + *to|= r= hexchar_to_int(from[1]); + if ((null_value= (r == -1))) + return 0; + } + return &tmp_value; +} void Item_func_binary::print(String *str) { diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 7eb0750711f..5b9c442b5db 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -500,10 +500,10 @@ public: Item_func_conv(Item *a,Item *b,Item *c) :Item_str_func(a,b,c) {} const char *func_name() const { return "conv"; } String *val_str(String *); - void fix_length_and_dec() - { + void fix_length_and_dec() + { collation.set(default_charset()); - decimals=0; max_length=64; + decimals=0; max_length=64; } }; @@ -515,14 +515,29 @@ public: Item_func_hex(Item *a) :Item_str_func(a) {} const char *func_name() const { return "hex"; } String *val_str(String *); - void fix_length_and_dec() - { + void fix_length_and_dec() + { collation.set(default_charset()); decimals=0; max_length=args[0]->max_length*2*collation.collation->mbmaxlen; } }; +class Item_func_unhex :public Item_str_func +{ + String tmp_value; +public: + Item_func_unhex(Item *a) :Item_str_func(a) {} + const char *func_name() const { return "unhex"; } + String *val_str(String *); + void fix_length_and_dec() + { + collation.set(&my_charset_bin); + decimals=0; + max_length=(1+args[0]->max_length)/2; + } +}; + class Item_func_binary :public Item_str_func { @@ -536,10 +551,10 @@ public: tmp->set_charset(&my_charset_bin); return tmp; } - void fix_length_and_dec() - { - collation.set(&my_charset_bin); - max_length=args[0]->max_length; + void fix_length_and_dec() + { + collation.set(&my_charset_bin); + max_length=args[0]->max_length; } void print(String *str); }; @@ -553,7 +568,7 @@ public: String *val_str(String *); const char *func_name() const { return "load_file"; } void fix_length_and_dec() - { + { collation.set(&my_charset_bin, DERIVATION_COERCIBLE); maybe_null=1; max_length=MAX_BLOB_WIDTH; diff --git a/sql/lex.h b/sql/lex.h index 9cdb1067d91..3b32d2bcd3b 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -671,6 +671,7 @@ static SYMBOL sql_functions[] = { { "UCASE", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ucase)}, { "UNCOMPRESS", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_uncompress)}, { "UNCOMPRESSED_LENGTH", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_uncompressed_length)}, + { "UNHEX", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_unhex)}, { "UNIQUE_USERS", SYM(UNIQUE_USERS)}, { "UNIX_TIMESTAMP", SYM(UNIX_TIMESTAMP)}, { "UPPER", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ucase)}, |