diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 3f9962144ff..ccd8601ace0 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -2382,5 +2382,3 @@ drop table t1; set storage_engine=MyISAM; create table t1 (v varchar(16384)) engine=innodb; drop table t1; -create table t1 (a bit, key(a)) engine=innodb; -ERROR 42000: The storage engine for the table doesn't support BIT FIELD diff --git a/mysql-test/r/type_bit.result b/mysql-test/r/type_bit.result index 04179a46285..b0cd4150c9d 100644 --- a/mysql-test/r/type_bit.result +++ b/mysql-test/r/type_bit.result @@ -380,3 +380,60 @@ drop table t1; create table t1(a int, b bit not null); alter table t1 add primary key (a); drop table t1; +create table t1 (a bit(19), b bit(5)); +insert into t1 values (1000, 10), (3, 8), (200, 6), (2303, 2), (12345, 4), (1, 0); +select a+0, b+0 from t1; +a+0 b+0 +1000 10 +3 8 +200 6 +2303 2 +12345 4 +1 0 +alter table t1 engine=heap; +select a+0, b+0 from t1; +a+0 b+0 +1000 10 +3 8 +200 6 +2303 2 +12345 4 +1 0 +alter table t1 add key(a, b); +select a+0, b+0 from t1; +a+0 b+0 +1000 10 +3 8 +200 6 +2303 2 +12345 4 +1 0 +alter table t1 engine=myisam; +select a+0, b+0 from t1; +a+0 b+0 +1 0 +3 8 +200 6 +1000 10 +2303 2 +12345 4 +create table t2 engine=heap select * from t1; +select a+0, b+0 from t2; +a+0 b+0 +1 0 +3 8 +200 6 +1000 10 +2303 2 +12345 4 +drop table t1; +create table t1 select * from t2; +select a+0, b+0 from t1; +a+0 b+0 +1 0 +3 8 +200 6 +1000 10 +2303 2 +12345 4 +drop table t1, t2; diff --git a/mysql-test/r/type_bit_innodb.result b/mysql-test/r/type_bit_innodb.result new file mode 100644 index 00000000000..57068f6502a --- /dev/null +++ b/mysql-test/r/type_bit_innodb.result @@ -0,0 +1,382 @@ +select 0 + b'1'; +0 + b'1' +1 +select 0 + b'0'; +0 + b'0' +0 +select 0 + b'000001'; +0 + b'000001' +1 +select 0 + b'000011'; +0 + b'000011' +3 +select 0 + b'000101'; +0 + b'000101' +5 +select 0 + b'000000'; +0 + b'000000' +0 +select 0 + b'10000000'; +0 + b'10000000' +128 +select 0 + b'11111111'; +0 + b'11111111' +255 +select 0 + b'10000001'; +0 + b'10000001' +129 +select 0 + b'1000000000000000'; +0 + b'1000000000000000' +32768 +select 0 + b'1111111111111111'; +0 + b'1111111111111111' +65535 +select 0 + b'1000000000000001'; +0 + b'1000000000000001' +32769 +drop table if exists t1; +create table t1 (a bit(65)) engine=innodb; +ERROR 42000: Column length too big for column 'a' (max = 64); use BLOB or TEXT instead +create table t1 (a bit(0)) engine=innodb; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` bit(1) default NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +drop table t1; +create table t1 (a bit(64)) engine=innodb; +insert into t1 values +(b'1111111111111111111111111111111111111111111111111111111111111111'), +(b'1000000000000000000000000000000000000000000000000000000000000000'), +(b'0000000000000000000000000000000000000000000000000000000000000001'), +(b'1010101010101010101010101010101010101010101010101010101010101010'), +(b'0101010101010101010101010101010101010101010101010101010101010101'); +select hex(a) from t1; +hex(a) +FFFFFFFFFFFFFFFF +8000000000000000 +1 +AAAAAAAAAAAAAAAA +5555555555555555 +drop table t1; +create table t1 (a bit) engine=innodb; +insert into t1 values (b'0'), (b'1'), (b'000'), (b'100'), (b'001'); +Warnings: +Warning 1264 Out of range value adjusted for column 'a' at row 4 +select hex(a) from t1; +hex(a) +0 +1 +0 +1 +1 +alter table t1 add unique (a); +ERROR 23000: Duplicate entry '' for key 1 +drop table t1; +create table t1 (a bit(2)) engine=innodb; +insert into t1 values (b'00'), (b'01'), (b'10'), (b'100'); +Warnings: +Warning 1264 Out of range value adjusted for column 'a' at row 4 +select a+0 from t1; +a+0 +0 +1 +2 +3 +alter table t1 add key (a); +explain select a+0 from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL a 2 NULL 4 Using index +select a+0 from t1; +a+0 +0 +1 +2 +3 +drop table t1; +create table t1 (a bit(7), b bit(9), key(a, b)) engine=innodb; +insert into t1 values +(94, 46), (31, 438), (61, 152), (78, 123), (88, 411), (122, 118), (0, 177), +(75, 42), (108, 67), (79, 349), (59, 188), (68, 206), (49, 345), (118, 380), +(111, 368), (94, 468), (56, 379), (77, 133), (29, 399), (9, 363), (23, 36), +(116, 390), (119, 368), (87, 351), (123, 411), (24, 398), (34, 202), (28, 499), +(30, 83), (5, 178), (60, 343), (4, 245), (104, 280), (106, 446), (127, 403), +(44, 307), (68, 454), (57, 135); +explain select a+0 from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL a 5 NULL 38 Using index +select a+0 from t1; +a+0 +0 +4 +5 +9 +23 +24 +28 +29 +30 +31 +34 +44 +49 +56 +57 +59 +60 +61 +68 +68 +75 +77 +78 +79 +87 +88 +94 +94 +104 +106 +108 +111 +116 +118 +119 +122 +123 +127 +explain select b+0 from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL a 5 NULL 38 Using index +select b+0 from t1; +b+0 +177 +245 +178 +363 +36 +398 +499 +399 +83 +438 +202 +307 +345 +379 +135 +188 +343 +152 +206 +454 +42 +133 +123 +349 +351 +411 +46 +468 +280 +446 +67 +368 +390 +380 +368 +118 +411 +403 +explain select a+0, b+0 from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL a 5 NULL 38 Using index +select a+0, b+0 from t1; +a+0 b+0 +0 177 +4 245 +5 178 +9 363 +23 36 +24 398 +28 499 +29 399 +30 83 +31 438 +34 202 +44 307 +49 345 +56 379 +57 135 +59 188 +60 343 +61 152 +68 206 +68 454 +75 42 +77 133 +78 123 +79 349 +87 351 +88 411 +94 46 +94 468 +104 280 +106 446 +108 67 +111 368 +116 390 +118 380 +119 368 +122 118 +123 411 +127 403 +explain select a+0, b+0 from t1 where a > 40 and b > 200 order by 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 2 NULL 19 Using where; Using index; Using filesort +select a+0, b+0 from t1 where a > 40 and b > 200 order by 1; +a+0 b+0 +44 307 +49 345 +56 379 +60 343 +68 206 +68 454 +79 349 +87 351 +88 411 +94 468 +104 280 +106 446 +111 368 +116 390 +118 380 +119 368 +123 411 +127 403 +explain select a+0, b+0 from t1 where a > 40 and a < 70 order by 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 2 NULL 8 Using where; Using index; Using filesort +select a+0, b+0 from t1 where a > 40 and a < 70 order by 2; +a+0 b+0 +57 135 +61 152 +59 188 +68 206 +44 307 +60 343 +49 345 +56 379 +68 454 +set @@max_length_for_sort_data=0; +select a+0, b+0 from t1 where a > 40 and a < 70 order by 2; +a+0 b+0 +57 135 +61 152 +59 188 +68 206 +44 307 +60 343 +49 345 +56 379 +68 454 +select hex(min(a)) from t1; +hex(min(a)) +0 +select hex(min(b)) from t1; +hex(min(b)) +24 +select hex(min(a)), hex(max(a)), hex(min(b)), hex(max(b)) from t1; +hex(min(a)) hex(max(a)) hex(min(b)) hex(max(b)) +0 7F 24 1F3 +drop table t1; +create table t1 (a int not null, b bit, c bit(9), key(a, b, c)) engine=innodb; +insert into t1 values +(4, NULL, 1), (4, 0, 3), (2, 1, 4), (1, 1, 100), (4, 0, 23), (4, 0, 54), +(56, 0, 22), (4, 1, 100), (23, 0, 1), (4, 0, 34); +select a+0, b+0, c+0 from t1; +a+0 b+0 c+0 +1 1 100 +2 1 4 +4 NULL 1 +4 0 3 +4 0 23 +4 0 34 +4 0 54 +4 1 100 +23 0 1 +56 0 22 +select hex(min(b)) from t1 where a = 4; +hex(min(b)) +0 +select hex(min(c)) from t1 where a = 4 and b = 0; +hex(min(c)) +3 +select hex(max(b)) from t1; +hex(max(b)) +1 +select a+0, b+0, c+0 from t1 where a = 4 and b = 0 limit 2; +a+0 b+0 c+0 +4 0 3 +4 0 23 +select a+0, b+0, c+0 from t1 where a = 4 and b = 1; +a+0 b+0 c+0 +4 1 100 +select a+0, b+0, c+0 from t1 where a = 4 and b = 1 and c=100; +a+0 b+0 c+0 +4 1 100 +select a+0, b+0, c+0 from t1 order by b desc; +a+0 b+0 c+0 +2 1 4 +1 1 100 +4 1 100 +4 0 3 +4 0 23 +4 0 54 +56 0 22 +23 0 1 +4 0 34 +4 NULL 1 +select a+0, b+0, c+0 from t1 order by c; +a+0 b+0 c+0 +4 NULL 1 +23 0 1 +4 0 3 +2 1 4 +56 0 22 +4 0 23 +4 0 34 +4 0 54 +1 1 100 +4 1 100 +drop table t1; +create table t1(a bit(2), b bit(2)) engine=innodb; +insert into t1 (a) values (0x01), (0x03), (0x02); +update t1 set b= concat(a); +select a+0, b+0 from t1; +a+0 b+0 +1 1 +3 3 +2 2 +drop table t1; +create table t1 (a bit(7), key(a)) engine=innodb; +insert into t1 values (44), (57); +select a+0 from t1; +a+0 +44 +57 +drop table t1; +create table t1 (a bit(3), b bit(12)) engine=innodb; +insert into t1 values (7,(1<<12)-2), (0x01,0x01ff); +select hex(a),hex(b) from t1; +hex(a) hex(b) +7 FFE +1 1FF +select hex(concat(a)),hex(concat(b)) from t1; +hex(concat(a)) hex(concat(b)) +07 0FFE +01 01FF +drop table t1; +create table t1(a int, b bit not null) engine=innodb; +alter table t1 add primary key (a); +drop table t1; diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index cca3e7ed3ad..bd07d2220d2 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -1300,8 +1300,3 @@ eval set storage_engine=$default; # InnoDB specific varchar tests create table t1 (v varchar(16384)) engine=innodb; drop table t1; - -# The following should be moved to type_bit.test when innodb will support it ---error 1178 -create table t1 (a bit, key(a)) engine=innodb; - diff --git a/mysql-test/t/type_bit.test b/mysql-test/t/type_bit.test index 5303a55fb25..1fbcf01d5a6 100644 --- a/mysql-test/t/type_bit.test +++ b/mysql-test/t/type_bit.test @@ -120,3 +120,23 @@ drop table t1; create table t1(a int, b bit not null); alter table t1 add primary key (a); drop table t1; + +# +# myisam <-> heap +# + +create table t1 (a bit(19), b bit(5)); +insert into t1 values (1000, 10), (3, 8), (200, 6), (2303, 2), (12345, 4), (1, 0); +select a+0, b+0 from t1; +alter table t1 engine=heap; +select a+0, b+0 from t1; +alter table t1 add key(a, b); +select a+0, b+0 from t1; +alter table t1 engine=myisam; +select a+0, b+0 from t1; +create table t2 engine=heap select * from t1; +select a+0, b+0 from t2; +drop table t1; +create table t1 select * from t2; +select a+0, b+0 from t1; +drop table t1, t2; diff --git a/mysql-test/t/type_bit_innodb.test b/mysql-test/t/type_bit_innodb.test new file mode 100644 index 00000000000..6410b98fcd0 --- /dev/null +++ b/mysql-test/t/type_bit_innodb.test @@ -0,0 +1,123 @@ +--source include/have_innodb.inc +# +# testing of the BIT column type +# + +select 0 + b'1'; +select 0 + b'0'; +select 0 + b'000001'; +select 0 + b'000011'; +select 0 + b'000101'; +select 0 + b'000000'; +select 0 + b'10000000'; +select 0 + b'11111111'; +select 0 + b'10000001'; +select 0 + b'1000000000000000'; +select 0 + b'1111111111111111'; +select 0 + b'1000000000000001'; + +--disable_warnings +drop table if exists t1; +--enable_warnings + +--error 1074 +create table t1 (a bit(65)) engine=innodb; + +create table t1 (a bit(0)) engine=innodb; +show create table t1; +drop table t1; + +create table t1 (a bit(64)) engine=innodb; +insert into t1 values +(b'1111111111111111111111111111111111111111111111111111111111111111'), +(b'1000000000000000000000000000000000000000000000000000000000000000'), +(b'0000000000000000000000000000000000000000000000000000000000000001'), +(b'1010101010101010101010101010101010101010101010101010101010101010'), +(b'0101010101010101010101010101010101010101010101010101010101010101'); +select hex(a) from t1; +drop table t1; + +create table t1 (a bit) engine=innodb; +insert into t1 values (b'0'), (b'1'), (b'000'), (b'100'), (b'001'); +select hex(a) from t1; +--error 1062 +alter table t1 add unique (a); +drop table t1; + +create table t1 (a bit(2)) engine=innodb; +insert into t1 values (b'00'), (b'01'), (b'10'), (b'100'); +select a+0 from t1; +alter table t1 add key (a); +explain select a+0 from t1; +select a+0 from t1; +drop table t1; + +create table t1 (a bit(7), b bit(9), key(a, b)) engine=innodb; +insert into t1 values +(94, 46), (31, 438), (61, 152), (78, 123), (88, 411), (122, 118), (0, 177), +(75, 42), (108, 67), (79, 349), (59, 188), (68, 206), (49, 345), (118, 380), +(111, 368), (94, 468), (56, 379), (77, 133), (29, 399), (9, 363), (23, 36), +(116, 390), (119, 368), (87, 351), (123, 411), (24, 398), (34, 202), (28, 499), +(30, 83), (5, 178), (60, 343), (4, 245), (104, 280), (106, 446), (127, 403), +(44, 307), (68, 454), (57, 135); +explain select a+0 from t1; +select a+0 from t1; +explain select b+0 from t1; +select b+0 from t1; +explain select a+0, b+0 from t1; +select a+0, b+0 from t1; +explain select a+0, b+0 from t1 where a > 40 and b > 200 order by 1; +select a+0, b+0 from t1 where a > 40 and b > 200 order by 1; +explain select a+0, b+0 from t1 where a > 40 and a < 70 order by 2; +select a+0, b+0 from t1 where a > 40 and a < 70 order by 2; +set @@max_length_for_sort_data=0; +select a+0, b+0 from t1 where a > 40 and a < 70 order by 2; +select hex(min(a)) from t1; +select hex(min(b)) from t1; +select hex(min(a)), hex(max(a)), hex(min(b)), hex(max(b)) from t1; +drop table t1; + +create table t1 (a int not null, b bit, c bit(9), key(a, b, c)) engine=innodb; +insert into t1 values +(4, NULL, 1), (4, 0, 3), (2, 1, 4), (1, 1, 100), (4, 0, 23), (4, 0, 54), +(56, 0, 22), (4, 1, 100), (23, 0, 1), (4, 0, 34); +select a+0, b+0, c+0 from t1; +select hex(min(b)) from t1 where a = 4; +select hex(min(c)) from t1 where a = 4 and b = 0; +select hex(max(b)) from t1; +select a+0, b+0, c+0 from t1 where a = 4 and b = 0 limit 2; +select a+0, b+0, c+0 from t1 where a = 4 and b = 1; +select a+0, b+0, c+0 from t1 where a = 4 and b = 1 and c=100; +select a+0, b+0, c+0 from t1 order by b desc; +select a+0, b+0, c+0 from t1 order by c; +drop table t1; + +create table t1(a bit(2), b bit(2)) engine=innodb; +insert into t1 (a) values (0x01), (0x03), (0x02); +update t1 set b= concat(a); +select a+0, b+0 from t1; +drop table t1; + +# Some magic numbers + +create table t1 (a bit(7), key(a)) engine=innodb; +insert into t1 values (44), (57); +select a+0 from t1; +drop table t1; + +# +# Test conversion to and from strings +# +create table t1 (a bit(3), b bit(12)) engine=innodb; +insert into t1 values (7,(1<<12)-2), (0x01,0x01ff); +select hex(a),hex(b) from t1; +select hex(concat(a)),hex(concat(b)) from t1; +drop table t1; + +# +# Bug #9571: problem with primary key creation +# + +create table t1(a int, b bit not null) engine=innodb; +alter table t1 add primary key (a); +drop table t1; diff --git a/sql/field.cc b/sql/field.cc index 3afc8a2eb12..05dbfc8271d 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -7945,6 +7945,58 @@ const char *Field_bit::unpack(char *to, const char *from) } +/* + Bit field support for non-MyISAM tables. +*/ + +Field_bit_as_char::Field_bit_as_char(char *ptr_arg, uint32 len_arg, + uchar *null_ptr_arg, uchar null_bit_arg, + uchar *bit_ptr_arg, uchar bit_ofs_arg, + enum utype unireg_check_arg, + const char *field_name_arg, + struct st_table *table_arg) + : Field_bit(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, bit_ptr_arg, + bit_ofs_arg, unireg_check_arg, field_name_arg, table_arg), + create_length(len_arg) +{ + bit_ptr= 0; + bit_ofs= 0; + bit_len= 0; + field_length= ((len_arg + 7) & ~7) / 8; +} + + +int Field_bit_as_char::store(const char *from, uint length, CHARSET_INFO *cs) +{ + int delta; + uchar bits= create_length & 7; + + for (; !*from && length; from++, length--); // skip left 0's + delta= field_length - length; + + if (delta < 0 || + (delta == 0 && bits && (uint) (uchar) *from >= (uint) (1 << bits))) + { + memset(ptr, 0xff, field_length); + *ptr&= ((1 << bits) - 1); /* set first byte */ + set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); + return 1; + } + bzero(ptr, delta); + memcpy(ptr + delta, from, length); + return 0; +} + + +void Field_bit_as_char::sql_type(String &res) const +{ + CHARSET_INFO *cs= res.charset(); + ulong length= cs->cset->snprintf(cs, (char*) res.ptr(), res.alloced_length(), + "bit(%d)", (int) create_length); + res.length((uint) length); +} + + /***************************************************************************** Handling of field and create_field *****************************************************************************/ @@ -7970,9 +8022,16 @@ void create_field::create_length_to_internal_length(void) key_length= pack_length; break; case MYSQL_TYPE_BIT: - pack_length= calc_pack_length(sql_type, length); - /* We need one extra byte to store the bits we save among the null bits */ - key_length= pack_length+ test(length & 7); + if (f_bit_as_char(pack_flag)) + { + key_length= pack_length= ((length + 7) & ~7) / 8; + } + else + { + pack_length= length / 8; + /* We need one extra byte to store the bits we save among the null bits */ + key_length= pack_length + test(length & 7); + } break; case MYSQL_TYPE_NEWDECIMAL: key_length= pack_length= my_decimal_get_binary_size(length, decimals); @@ -8086,7 +8145,7 @@ Field *make_field(char *ptr, uint32 field_length, uchar bit_offset; LINT_INIT(bit_ptr); LINT_INIT(bit_offset); - if (field_type == FIELD_TYPE_BIT) + if (field_type == FIELD_TYPE_BIT && !f_bit_as_char(pack_flag)) { bit_ptr= null_pos; bit_offset= null_bit; @@ -8236,7 +8295,10 @@ Field *make_field(char *ptr, uint32 field_length, case FIELD_TYPE_NULL: return new Field_null(ptr,field_length,unireg_check,field_name,table, field_charset); case FIELD_TYPE_BIT: - return new Field_bit(ptr, field_length, null_pos, null_bit, bit_ptr, + return f_bit_as_char(pack_flag) ? + new Field_bit_as_char(ptr, field_length, null_pos, null_bit, bit_ptr, + bit_offset, unireg_check, field_name, table) : + new Field_bit(ptr, field_length, null_pos, null_bit, bit_ptr, bit_offset, unireg_check, field_name, table); default: // Impossible (Wrong version) break; diff --git a/sql/field.h b/sql/field.h index 365f2c323b9..fd0937b2f4c 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1312,6 +1312,22 @@ public: }; +class Field_bit_as_char: public Field_bit { +protected: + uchar create_length; +public: + Field_bit_as_char(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, + uchar null_bit_arg, uchar *bit_ptr_arg, uchar bit_ofs_arg, + enum utype unireg_check_arg, const char *field_name_arg, + struct st_table *table_arg); + enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; } + int store(const char *to, uint length, CHARSET_INFO *charset); + int store(double nr) { return Field_bit::store(nr); } + int store(longlong nr) { return Field_bit::store(nr); } + void sql_type(String &str) const; +}; + + /* Create field class for CREATE TABLE */ @@ -1415,6 +1431,8 @@ int set_field_to_null_with_conversions(Field *field, bool no_conversions); #define FIELDFLAG_BLOB 1024 // mangled with decimals! #define FIELDFLAG_GEOM 2048 // mangled with decimals! +#define FIELDFLAG_TREAT_BIT_AS_CHAR 4096 /* use Field_bit_as_char */ + #define FIELDFLAG_LEFT_FULLSCREEN 8192 #define FIELDFLAG_RIGHT_FULLSCREEN 16384 #define FIELDFLAG_FORMAT_NUMBER 16384 // predit: ###,,## in output @@ -1445,3 +1463,4 @@ int set_field_to_null_with_conversions(Field *field, bool no_conversions); #define f_settype(x) (((int) x) << FIELDFLAG_PACK_SHIFT) #define f_maybe_null(x) (x & FIELDFLAG_MAYBE_NULL) #define f_no_default(x) (x & FIELDFLAG_NO_DEFAULT) +#define f_bit_as_char(x) ((x) & FIELDFLAG_TREAT_BIT_AS_CHAR) diff --git a/sql/field_conv.cc b/sql/field_conv.cc index bbdd6619bf3..ae784ae0293 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -511,7 +511,7 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*) /* If we are copying date or datetime's we have to check the dates if we don't allow 'all' dates. -p */ + */ if (to->real_type() != from->real_type() || !compatible_db_low_byte_first || ((to->table->in_use->variables.sql_mode & @@ -594,6 +594,7 @@ void field_conv(Field *to,Field *from) !(to->flags & UNSIGNED_FLAG && !(from->flags & UNSIGNED_FLAG)) && to->real_type() != FIELD_TYPE_ENUM && to->real_type() != FIELD_TYPE_SET && + to->real_type() != FIELD_TYPE_BIT && (to->real_type() != FIELD_TYPE_NEWDECIMAL || (to->field_length == from->field_length && (((Field_num*)to)->dec == ((Field_num*)from)->dec))) && diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index cfc649a5963..9de76abbb18 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -2233,6 +2233,7 @@ innobase_mysql_cmp( switch (mysql_tp) { + case MYSQL_TYPE_BIT: case MYSQL_TYPE_STRING: case MYSQL_TYPE_VAR_STRING: case FIELD_TYPE_TINY_BLOB: @@ -2342,6 +2343,7 @@ get_innobase_type_from_mysql_type( } else { return(DATA_VARMYSQL); } + case MYSQL_TYPE_BIT: case MYSQL_TYPE_STRING: if (field->binary()) { return(DATA_FIXBINARY); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 4b40ff7638c..686e38104ab 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -563,12 +563,7 @@ int prepare_create_field(create_field *sql_field, sql_field->pack_flag=f_settype((uint) sql_field->sql_type); break; case FIELD_TYPE_BIT: - if (!(table_flags & HA_CAN_BIT_FIELD)) - { - my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "BIT FIELD"); - DBUG_RETURN(1); - } - sql_field->pack_flag= FIELDFLAG_NUMBER; + sql_field->pack_flag|= FIELDFLAG_NUMBER; break; case FIELD_TYPE_NEWDECIMAL: sql_field->pack_flag=(FIELDFLAG_NUMBER | @@ -774,6 +769,14 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, set_if_smaller(sql_field->length, MAX_FIELD_WIDTH-1); } + if (sql_field->sql_type == FIELD_TYPE_BIT) + { + if (file->table_flags() & HA_CAN_BIT_FIELD) + total_uneven_bit_length+= sql_field->length & 7; + else + sql_field->pack_flag|= FIELDFLAG_TREAT_BIT_AS_CHAR; + } + sql_field->create_length_to_internal_length(); if (sql_field->length > MAX_FIELD_VARCHARLENGTH && !(sql_field->flags & BLOB_FLAG)) @@ -810,9 +813,6 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if (!(sql_field->flags & NOT_NULL_FLAG)) null_fields++; - if (sql_field->sql_type == FIELD_TYPE_BIT) - total_uneven_bit_length+= sql_field->length & 7; - if (check_column_name(sql_field->field_name)) { my_error(ER_WRONG_COLUMN_NAME, MYF(0), sql_field->field_name); diff --git a/sql/table.cc b/sql/table.cc index e1f15926c03..8e0f52e1910 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -568,7 +568,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, goto err; /* purecov: inspected */ } reg_field->comment=comment; - if (field_type == FIELD_TYPE_BIT) + if (field_type == FIELD_TYPE_BIT && !f_bit_as_char(pack_flag)) { if ((null_bit_pos+= field_length & 7) > 7) {