Loading mysql-test/r/type_bit.result +9 −0 Original line number Diff line number Diff line Loading @@ -564,3 +564,12 @@ b1+0 sum(b1) sum(b2) 1 4 4 2 2 2 drop table t1, t2; create table t1 (a bit(7)); insert into t1 values (0x60); select * from t1; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr def test t1 t1 a a 16 7 1 Y 0 0 63 a ` drop table t1; End of 5.0 tests mysql-test/r/type_bit_innodb.result +9 −0 Original line number Diff line number Diff line Loading @@ -402,3 +402,12 @@ t1 CREATE TABLE `t1` ( `b` bit(10) default NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 drop table t1; create table t1 (a bit(7)) engine=innodb; insert into t1 values (0x60); select * from t1; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr def test t1 t1 a a 16 7 1 Y 0 0 63 a ` drop table t1; End of 5.0 tests mysql-test/t/type_bit.test +12 −0 Original line number Diff line number Diff line Loading @@ -227,3 +227,15 @@ select sum(a1), b1+0, b2+0 from t1 join t2 on b1 = b2 group by b1 order by 1; select 1 from t1 join t2 on b1 = b2 group by b1 order by 1; select b1+0,sum(b1), sum(b2) from t1 join t2 on b1 = b2 group by b1 order by 1; drop table t1, t2; # # Bug #13601: Wrong field length reported for BIT fields # create table t1 (a bit(7)); insert into t1 values (0x60); --enable_metadata select * from t1; --disable_metadata drop table t1; --echo End of 5.0 tests mysql-test/t/type_bit_innodb.test +12 −0 Original line number Diff line number Diff line Loading @@ -133,3 +133,15 @@ show create table t1; alter table t1 engine=innodb; show create table t1; drop table t1; # # Bug #13601: Wrong field length reported for BIT fields # create table t1 (a bit(7)) engine=innodb; insert into t1 values (0x60); --enable_metadata select * from t1; --disable_metadata drop table t1; --echo End of 5.0 tests sql/field.cc +24 −29 Original line number Diff line number Diff line Loading @@ -7942,9 +7942,10 @@ Field_bit::Field_bit(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(ptr_arg, len_arg >> 3, null_ptr_arg, null_bit_arg, : Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg, table_arg), bit_ptr(bit_ptr_arg), bit_ofs(bit_ofs_arg), bit_len(len_arg & 7) bit_ptr(bit_ptr_arg), bit_ofs(bit_ofs_arg), bit_len(len_arg & 7), bytes_in_rec(len_arg / 8) { /* Ensure that Field::eq() can distinguish between two different bit fields. Loading Loading @@ -7980,14 +7981,14 @@ int Field_bit::store(const char *from, uint length, CHARSET_INFO *cs) int delta; for (; length && !*from; from++, length--); // skip left 0's delta= field_length - length; delta= bytes_in_rec - length; if (delta < -1 || (delta == -1 && (uchar) *from > ((1 << bit_len) - 1)) || (!bit_len && delta < 0)) { set_rec_bits(0xff, bit_ptr, bit_ofs, bit_len); memset(ptr, 0xff, field_length); memset(ptr, 0xff, bytes_in_rec); if (table->in_use->really_abort_on_warning()) set_warning(MYSQL_ERROR::WARN_LEVEL_ERROR, ER_DATA_TOO_LONG, 1); else Loading Loading @@ -8015,7 +8016,7 @@ int Field_bit::store(const char *from, uint length, CHARSET_INFO *cs) set_rec_bits((uchar) *from, bit_ptr, bit_ofs, bit_len); from++; } memcpy(ptr, from, field_length); memcpy(ptr, from, bytes_in_rec); } return 0; } Loading Loading @@ -8056,10 +8057,10 @@ longlong Field_bit::val_int(void) if (bit_len) { bits= get_rec_bits(bit_ptr, bit_ofs, bit_len); bits<<= (field_length * 8); bits<<= (bytes_in_rec * 8); } switch (field_length) { switch (bytes_in_rec) { case 0: return bits; case 1: return bits | (ulonglong) (uchar) ptr[0]; case 2: return bits | mi_uint2korr(ptr); Loading @@ -8068,7 +8069,7 @@ longlong Field_bit::val_int(void) case 5: return bits | mi_uint5korr(ptr); case 6: return bits | mi_uint6korr(ptr); case 7: return bits | mi_uint7korr(ptr); default: return mi_uint8korr(ptr + field_length - sizeof(longlong)); default: return mi_uint8korr(ptr + bytes_in_rec - sizeof(longlong)); } } Loading Loading @@ -8121,7 +8122,7 @@ int Field_bit::cmp_offset(uint row_offset) if ((flag= (int) (bits_a - bits_b))) return flag; } return memcmp(ptr, ptr + row_offset, field_length); return memcmp(ptr, ptr + row_offset, bytes_in_rec); } Loading @@ -8133,7 +8134,7 @@ void Field_bit::get_key_image(char *buff, uint length, imagetype type) *buff++= bits; length--; } memcpy(buff, ptr, min(length, field_length)); memcpy(buff, ptr, min(length, bytes_in_rec)); } Loading @@ -8141,21 +8142,21 @@ void Field_bit::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) field_length * 8 + bit_len); "bit(%d)", (int) field_length); res.length((uint) length); } char *Field_bit::pack(char *to, const char *from, uint max_length) { uint length= min(field_length + (bit_len > 0), max_length); DBUG_ASSERT(max_length); uint length; if (bit_len) { uchar bits= get_rec_bits(bit_ptr, bit_ofs, bit_len); *to++= bits; length--; } length= min(bytes_in_rec, max_length - (bit_len > 0)); memcpy(to, from, length); return to + length; } Loading @@ -8168,8 +8169,8 @@ const char *Field_bit::unpack(char *to, const char *from) set_rec_bits(*from, bit_ptr, bit_ofs, bit_len); from++; } memcpy(to, from, field_length); return from + field_length; memcpy(to, from, bytes_in_rec); return from + bytes_in_rec; } Loading @@ -8183,26 +8184,25 @@ Field_bit_as_char::Field_bit_as_char(char *ptr_arg, uint32 len_arg, const char *field_name_arg, struct st_table *table_arg) : Field_bit(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, 0, 0, unireg_check_arg, field_name_arg, table_arg), create_length(len_arg) 0, unireg_check_arg, field_name_arg, table_arg) { bit_len= 0; field_length= ((len_arg + 7) & ~7) / 8; bytes_in_rec= (len_arg + 7) / 8; } int Field_bit_as_char::store(const char *from, uint length, CHARSET_INFO *cs) { int delta; uchar bits= create_length & 7; uchar bits= field_length & 7; for (; length && !*from; from++, length--); // skip left 0's delta= field_length - length; delta= bytes_in_rec - length; if (delta < 0 || (delta == 0 && bits && (uint) (uchar) *from >= (uint) (1 << bits))) { memset(ptr, 0xff, field_length); memset(ptr, 0xff, bytes_in_rec); if (bits) *ptr&= ((1 << bits) - 1); /* set first byte */ if (table->in_use->really_abort_on_warning()) Loading @@ -8221,7 +8221,7 @@ 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); "bit(%d)", (int) field_length); res.length((uint) length); } Loading Loading @@ -8947,11 +8947,6 @@ create_field::create_field(Field *old_field,Field *orig_field) geom_type= ((Field_geom*)old_field)->geom_type; break; #endif case FIELD_TYPE_BIT: length= (old_field->key_type() == HA_KEYTYPE_BIT) ? ((Field_bit *) old_field)->bit_len + length * 8 : ((Field_bit_as_char *) old_field)->create_length; break; default: break; } Loading Loading
mysql-test/r/type_bit.result +9 −0 Original line number Diff line number Diff line Loading @@ -564,3 +564,12 @@ b1+0 sum(b1) sum(b2) 1 4 4 2 2 2 drop table t1, t2; create table t1 (a bit(7)); insert into t1 values (0x60); select * from t1; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr def test t1 t1 a a 16 7 1 Y 0 0 63 a ` drop table t1; End of 5.0 tests
mysql-test/r/type_bit_innodb.result +9 −0 Original line number Diff line number Diff line Loading @@ -402,3 +402,12 @@ t1 CREATE TABLE `t1` ( `b` bit(10) default NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 drop table t1; create table t1 (a bit(7)) engine=innodb; insert into t1 values (0x60); select * from t1; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr def test t1 t1 a a 16 7 1 Y 0 0 63 a ` drop table t1; End of 5.0 tests
mysql-test/t/type_bit.test +12 −0 Original line number Diff line number Diff line Loading @@ -227,3 +227,15 @@ select sum(a1), b1+0, b2+0 from t1 join t2 on b1 = b2 group by b1 order by 1; select 1 from t1 join t2 on b1 = b2 group by b1 order by 1; select b1+0,sum(b1), sum(b2) from t1 join t2 on b1 = b2 group by b1 order by 1; drop table t1, t2; # # Bug #13601: Wrong field length reported for BIT fields # create table t1 (a bit(7)); insert into t1 values (0x60); --enable_metadata select * from t1; --disable_metadata drop table t1; --echo End of 5.0 tests
mysql-test/t/type_bit_innodb.test +12 −0 Original line number Diff line number Diff line Loading @@ -133,3 +133,15 @@ show create table t1; alter table t1 engine=innodb; show create table t1; drop table t1; # # Bug #13601: Wrong field length reported for BIT fields # create table t1 (a bit(7)) engine=innodb; insert into t1 values (0x60); --enable_metadata select * from t1; --disable_metadata drop table t1; --echo End of 5.0 tests
sql/field.cc +24 −29 Original line number Diff line number Diff line Loading @@ -7942,9 +7942,10 @@ Field_bit::Field_bit(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(ptr_arg, len_arg >> 3, null_ptr_arg, null_bit_arg, : Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg, table_arg), bit_ptr(bit_ptr_arg), bit_ofs(bit_ofs_arg), bit_len(len_arg & 7) bit_ptr(bit_ptr_arg), bit_ofs(bit_ofs_arg), bit_len(len_arg & 7), bytes_in_rec(len_arg / 8) { /* Ensure that Field::eq() can distinguish between two different bit fields. Loading Loading @@ -7980,14 +7981,14 @@ int Field_bit::store(const char *from, uint length, CHARSET_INFO *cs) int delta; for (; length && !*from; from++, length--); // skip left 0's delta= field_length - length; delta= bytes_in_rec - length; if (delta < -1 || (delta == -1 && (uchar) *from > ((1 << bit_len) - 1)) || (!bit_len && delta < 0)) { set_rec_bits(0xff, bit_ptr, bit_ofs, bit_len); memset(ptr, 0xff, field_length); memset(ptr, 0xff, bytes_in_rec); if (table->in_use->really_abort_on_warning()) set_warning(MYSQL_ERROR::WARN_LEVEL_ERROR, ER_DATA_TOO_LONG, 1); else Loading Loading @@ -8015,7 +8016,7 @@ int Field_bit::store(const char *from, uint length, CHARSET_INFO *cs) set_rec_bits((uchar) *from, bit_ptr, bit_ofs, bit_len); from++; } memcpy(ptr, from, field_length); memcpy(ptr, from, bytes_in_rec); } return 0; } Loading Loading @@ -8056,10 +8057,10 @@ longlong Field_bit::val_int(void) if (bit_len) { bits= get_rec_bits(bit_ptr, bit_ofs, bit_len); bits<<= (field_length * 8); bits<<= (bytes_in_rec * 8); } switch (field_length) { switch (bytes_in_rec) { case 0: return bits; case 1: return bits | (ulonglong) (uchar) ptr[0]; case 2: return bits | mi_uint2korr(ptr); Loading @@ -8068,7 +8069,7 @@ longlong Field_bit::val_int(void) case 5: return bits | mi_uint5korr(ptr); case 6: return bits | mi_uint6korr(ptr); case 7: return bits | mi_uint7korr(ptr); default: return mi_uint8korr(ptr + field_length - sizeof(longlong)); default: return mi_uint8korr(ptr + bytes_in_rec - sizeof(longlong)); } } Loading Loading @@ -8121,7 +8122,7 @@ int Field_bit::cmp_offset(uint row_offset) if ((flag= (int) (bits_a - bits_b))) return flag; } return memcmp(ptr, ptr + row_offset, field_length); return memcmp(ptr, ptr + row_offset, bytes_in_rec); } Loading @@ -8133,7 +8134,7 @@ void Field_bit::get_key_image(char *buff, uint length, imagetype type) *buff++= bits; length--; } memcpy(buff, ptr, min(length, field_length)); memcpy(buff, ptr, min(length, bytes_in_rec)); } Loading @@ -8141,21 +8142,21 @@ void Field_bit::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) field_length * 8 + bit_len); "bit(%d)", (int) field_length); res.length((uint) length); } char *Field_bit::pack(char *to, const char *from, uint max_length) { uint length= min(field_length + (bit_len > 0), max_length); DBUG_ASSERT(max_length); uint length; if (bit_len) { uchar bits= get_rec_bits(bit_ptr, bit_ofs, bit_len); *to++= bits; length--; } length= min(bytes_in_rec, max_length - (bit_len > 0)); memcpy(to, from, length); return to + length; } Loading @@ -8168,8 +8169,8 @@ const char *Field_bit::unpack(char *to, const char *from) set_rec_bits(*from, bit_ptr, bit_ofs, bit_len); from++; } memcpy(to, from, field_length); return from + field_length; memcpy(to, from, bytes_in_rec); return from + bytes_in_rec; } Loading @@ -8183,26 +8184,25 @@ Field_bit_as_char::Field_bit_as_char(char *ptr_arg, uint32 len_arg, const char *field_name_arg, struct st_table *table_arg) : Field_bit(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, 0, 0, unireg_check_arg, field_name_arg, table_arg), create_length(len_arg) 0, unireg_check_arg, field_name_arg, table_arg) { bit_len= 0; field_length= ((len_arg + 7) & ~7) / 8; bytes_in_rec= (len_arg + 7) / 8; } int Field_bit_as_char::store(const char *from, uint length, CHARSET_INFO *cs) { int delta; uchar bits= create_length & 7; uchar bits= field_length & 7; for (; length && !*from; from++, length--); // skip left 0's delta= field_length - length; delta= bytes_in_rec - length; if (delta < 0 || (delta == 0 && bits && (uint) (uchar) *from >= (uint) (1 << bits))) { memset(ptr, 0xff, field_length); memset(ptr, 0xff, bytes_in_rec); if (bits) *ptr&= ((1 << bits) - 1); /* set first byte */ if (table->in_use->really_abort_on_warning()) Loading @@ -8221,7 +8221,7 @@ 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); "bit(%d)", (int) field_length); res.length((uint) length); } Loading Loading @@ -8947,11 +8947,6 @@ create_field::create_field(Field *old_field,Field *orig_field) geom_type= ((Field_geom*)old_field)->geom_type; break; #endif case FIELD_TYPE_BIT: length= (old_field->key_type() == HA_KEYTYPE_BIT) ? ((Field_bit *) old_field)->bit_len + length * 8 : ((Field_bit_as_char *) old_field)->create_length; break; default: break; } Loading