summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/type_bit.result30
-rw-r--r--mysql-test/t/type_bit.test15
-rw-r--r--sql/item_strfunc.cc32
3 files changed, 69 insertions, 8 deletions
diff --git a/mysql-test/r/type_bit.result b/mysql-test/r/type_bit.result
index c66adbe871d..08a1b229491 100644
--- a/mysql-test/r/type_bit.result
+++ b/mysql-test/r/type_bit.result
@@ -572,4 +572,34 @@ def test t1 t1 a a 16 7 1 Y 0 0 63
a
`
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
diff --git a/mysql-test/t/type_bit.test b/mysql-test/t/type_bit.test
index e028dbc51d9..998f8f18fbe 100644
--- a/mysql-test/t/type_bit.test
+++ b/mysql-test/t/type_bit.test
@@ -238,4 +238,19 @@ select * from t1;
--disable_metadata
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
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index dee7f408733..2bfe7e8e81b 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -2359,17 +2359,33 @@ String *Item_func_conv::val_str(String *str)
abs(to_base) > 36 || abs(to_base) < 2 ||
abs(from_base) > 36 || abs(from_base) < 2 || !(res->length()))
{
- null_value=1;
- return 0;
+ null_value= 1;
+ return NULL;
}
- null_value=0;
+ null_value= 0;
unsigned_flag= !(from_base < 0);
- if (from_base < 0)
- dec= my_strntoll(res->charset(),res->ptr(),res->length(),-from_base,&endptr,&err);
+
+ 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
- dec= (longlong) my_strntoull(res->charset(),res->ptr(),res->length(),from_base,&endptr,&err);
- ptr= longlong2str(dec,ans,to_base);
- if (str->copy(ans,(uint32) (ptr-ans), default_charset()))
+ {
+ if (from_base < 0)
+ dec= my_strntoll(res->charset(), res->ptr(), res->length(),
+ -from_base, &endptr, &err);
+ else
+ dec= (longlong) my_strntoull(res->charset(), res->ptr(), res->length(),
+ from_base, &endptr, &err);
+ }
+
+ ptr= longlong2str(dec, ans, to_base);
+ if (str->copy(ans, (uint32) (ptr-ans), default_charset()))
return &my_empty_string;
return str;
}