Bug#15583: BIN()/OCT()/CONV() do not work with BIT values

Converting BIT to a string (an intermediate step in conversion) does 
not yield an ASCII numeric string, so we skip that step for BIT and
get the integer value directly from the item.

This site in sql/item_strfunc.cc may be ripe for refactoring for
other types as well, where converting to a string is a waste of time.
parent 83896aa8
...@@ -572,4 +572,34 @@ def test t1 t1 a a 16 7 1 Y 0 0 63 ...@@ -572,4 +572,34 @@ def test t1 t1 a a 16 7 1 Y 0 0 63
a a
` `
drop table t1; drop table t1;
create table bug15583(b BIT(8), n INT);
insert into bug15583 values(128, 128);
insert into bug15583 values(null, null);
insert into bug15583 values(0, 0);
insert into bug15583 values(255, 255);
select hex(b), bin(b), oct(b), hex(n), bin(n), oct(n) from bug15583;
hex(b) bin(b) oct(b) hex(n) bin(n) oct(n)
80 10000000 200 80 10000000 200
NULL NULL NULL NULL NULL NULL
0 0 0 0 0 0
FF 11111111 377 FF 11111111 377
select hex(b)=hex(n) as should_be_onetrue, bin(b)=bin(n) as should_be_onetrue, oct(b)=oct(n) as should_be_onetrue from bug15583;
should_be_onetrue should_be_onetrue should_be_onetrue
1 1 1
NULL NULL NULL
1 1 1
1 1 1
select hex(b + 0), bin(b + 0), oct(b + 0), hex(n), bin(n), oct(n) from bug15583;
hex(b + 0) bin(b + 0) oct(b + 0) hex(n) bin(n) oct(n)
80 10000000 200 80 10000000 200
NULL NULL NULL NULL NULL NULL
0 0 0 0 0 0
FF 11111111 377 FF 11111111 377
select conv(b, 10, 2), conv(b + 0, 10, 2) from bug15583;
conv(b, 10, 2) conv(b + 0, 10, 2)
10000000 10000000
NULL NULL
0 0
11111111 11111111
drop table bug15583;
End of 5.0 tests End of 5.0 tests
...@@ -238,4 +238,19 @@ select * from t1; ...@@ -238,4 +238,19 @@ select * from t1;
--disable_metadata --disable_metadata
drop table t1; drop table t1;
#
# Bug#15583: BIN()/OCT()/CONV() do not work with BIT values
#
create table bug15583(b BIT(8), n INT);
insert into bug15583 values(128, 128);
insert into bug15583 values(null, null);
insert into bug15583 values(0, 0);
insert into bug15583 values(255, 255);
select hex(b), bin(b), oct(b), hex(n), bin(n), oct(n) from bug15583;
select hex(b)=hex(n) as should_be_onetrue, bin(b)=bin(n) as should_be_onetrue, oct(b)=oct(n) as should_be_onetrue from bug15583;
select hex(b + 0), bin(b + 0), oct(b + 0), hex(n), bin(n), oct(n) from bug15583;
select conv(b, 10, 2), conv(b + 0, 10, 2) from bug15583;
drop table bug15583;
--echo End of 5.0 tests --echo End of 5.0 tests
...@@ -2359,17 +2359,33 @@ String *Item_func_conv::val_str(String *str) ...@@ -2359,17 +2359,33 @@ String *Item_func_conv::val_str(String *str)
abs(to_base) > 36 || abs(to_base) < 2 || abs(to_base) > 36 || abs(to_base) < 2 ||
abs(from_base) > 36 || abs(from_base) < 2 || !(res->length())) abs(from_base) > 36 || abs(from_base) < 2 || !(res->length()))
{ {
null_value=1; null_value= 1;
return 0; return NULL;
} }
null_value=0; null_value= 0;
unsigned_flag= !(from_base < 0); unsigned_flag= !(from_base < 0);
if (args[0]->field_type() == MYSQL_TYPE_BIT)
{
/*
Special case: The string representation of BIT doesn't resemble the
decimal representation, so we shouldn't change it to string and then to
decimal.
*/
dec= args[0]->val_int();
}
else
{
if (from_base < 0) if (from_base < 0)
dec= my_strntoll(res->charset(),res->ptr(),res->length(),-from_base,&endptr,&err); dec= my_strntoll(res->charset(), res->ptr(), res->length(),
-from_base, &endptr, &err);
else else
dec= (longlong) my_strntoull(res->charset(),res->ptr(),res->length(),from_base,&endptr,&err); dec= (longlong) my_strntoull(res->charset(), res->ptr(), res->length(),
ptr= longlong2str(dec,ans,to_base); from_base, &endptr, &err);
if (str->copy(ans,(uint32) (ptr-ans), default_charset())) }
ptr= longlong2str(dec, ans, to_base);
if (str->copy(ans, (uint32) (ptr-ans), default_charset()))
return &my_empty_string; return &my_empty_string;
return str; return str;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment