diff options
author | unknown <jimw@mysql.com> | 2006-04-04 17:54:58 -0700 |
---|---|---|
committer | unknown <jimw@mysql.com> | 2006-04-04 17:54:58 -0700 |
commit | b3b626c31cb6f09cc89e633f500a066af6ef2fb5 (patch) | |
tree | 470f8546a50589e9c092da9005875129175816e0 /sql/field.cc | |
parent | bfa21dd1520b2f718a1f1aa8c6256f62c91cfff8 (diff) | |
download | mariadb-git-b3b626c31cb6f09cc89e633f500a066af6ef2fb5.tar.gz |
Bug #13601: Wrong int type for bit
The wrong value was being reported as the field_length for BIT
fields, resulting in confusion for at least Connector/J. The
field_length is now always the number of bits in the field, as
it should be.
mysql-test/r/type_bit.result:
Add new results
mysql-test/r/type_bit_innodb.result:
Add new results
mysql-test/t/type_bit.test:
Add new regression test
mysql-test/t/type_bit_innodb.test:
Add new regression test
sql/field.cc:
Fix Field_bit->field_length to actually report the display width, and
store the bytes stored in the rec in the new bytes_in_rec member.
sql/field.h:
Fix Field_bit::field_length to store the correct value, adding
Field_bit::bytes_in_rec to remember the number of bytes used for
storing the value. Remove Field_bit_as_char::create_length, as it
is now redundant.
sql/ha_ndbcluster.cc:
Handle field_length of Field_bit actually being the display width (# of bits).
sql/key.cc:
Fix inappropriate use of field->field_length for BIT field.
Diffstat (limited to 'sql/field.cc')
-rw-r--r-- | sql/field.cc | 53 |
1 files changed, 24 insertions, 29 deletions
diff --git a/sql/field.cc b/sql/field.cc index eab62cd1958..51efddb701c 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -7918,9 +7918,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. @@ -7956,14 +7957,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 @@ -7991,7 +7992,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; } @@ -8032,10 +8033,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); @@ -8044,7 +8045,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)); } } @@ -8097,7 +8098,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); } @@ -8109,7 +8110,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)); } @@ -8117,22 +8118,22 @@ 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--; } - memcpy(to, from, length); + length= min(bytes_in_rec, max_length - (bit_len > 0)); + memcpy(to, from, length); return to + length; } @@ -8144,8 +8145,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; } @@ -8159,26 +8160,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()) @@ -8197,7 +8197,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); } @@ -8923,11 +8923,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; } |