summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/func_str.result9
-rw-r--r--mysql-test/t/func_str.test3
-rw-r--r--sql/item_create.cc5
-rw-r--r--sql/item_create.h1
-rw-r--r--sql/item_strfunc.cc44
-rw-r--r--sql/item_strfunc.h35
-rw-r--r--sql/lex.h1
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)},