From 936c84989e9fb4307983ce6fa94e23d5cf29dab9 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 May 2005 17:17:55 +0500 Subject: [PATCH] A fix (bug #10179: error in default value setting). include/my_handler.h: A fix (bug #10179: error in default value setting). Proper masks added: we should not touch extra bits. sql/key.cc: A fix (bug #10179: error in default value setting). Unnecessary code removed. sql/unireg.cc: A fix (bug #10179: error in default value setting). 1. we should take into account uneven bits (for bit fields) stored among NULL bits. 2. changed code which sets NULL bits for fields. 3. changed code which sets unused bits after NULL bits. 4. unused variables removed. BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- BitKeeper/etc/logging_ok | 1 + include/my_handler.h | 5 +++-- mysql-test/r/type_bit.result | 21 +++++++++++++++++++++ mysql-test/t/type_bit.test | 22 ++++++++++++++++++++++ sql/key.cc | 6 ------ sql/unireg.cc | 21 ++++++++++++--------- 6 files changed, 59 insertions(+), 17 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 346dcae3cfd..0ddc8b2d996 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -217,6 +217,7 @@ ram@deer.(none) ram@gw.mysql.r18.ru ram@gw.udmsearch.izhnet.ru ram@mysql.r18.ru +ram@ram-book.(none) ram@ram.(none) ramil@mysql.com ranger@regul.home.lan diff --git a/include/my_handler.h b/include/my_handler.h index cad15d5471f..c076ba0c2c9 100644 --- a/include/my_handler.h +++ b/include/my_handler.h @@ -72,10 +72,11 @@ typedef struct st_HA_KEYSEG /* Key-portion */ #define set_rec_bits(bits, bit_ptr, bit_ofs, bit_len) \ { \ - (bit_ptr)[0]= ((bit_ptr)[0] & ((1 << (bit_ofs)) - 1)) | \ + (bit_ptr)[0]= ((bit_ptr)[0] & ~(((1 << (bit_len)) - 1) << (bit_ofs))) | \ ((bits) << (bit_ofs)); \ if ((bit_ofs) + (bit_len) > 8) \ - (bit_ptr)[1]= ((bits) & ((1 << (bit_len)) - 1)) >> (8 - (bit_ofs)); \ + (bit_ptr)[1]= ((bit_ptr)[1] & ~((1 << ((bit_len) - 8 + (bit_ofs))) - 1)) | \ + ((bits) >> (8 - (bit_ofs))); \ } #define clr_rec_bits(bit_ptr, bit_ofs, bit_len) \ diff --git a/mysql-test/r/type_bit.result b/mysql-test/r/type_bit.result index b0cd4150c9d..64c9a11b3cd 100644 --- a/mysql-test/r/type_bit.result +++ b/mysql-test/r/type_bit.result @@ -437,3 +437,24 @@ a+0 b+0 2303 2 12345 4 drop table t1, t2; +create table t1 (a int, b time, c tinyint, d bool, e char(10), f bit(1), +g bit(1) NOT NULL default 1, h char(1) default 'a'); +insert into t1 set a=1; +select hex(g), h from t1; +hex(g) h +1 a +drop table t1; +create table t1 (a int, b time, c tinyint, d bool, e char(10), f bit(1), +g bit(1) NOT NULL default 1); +insert into t1 set a=1; +select hex(g) from t1; +hex(g) +1 +drop table t1; +create table t1 (a int, b time, c tinyint, d bool, e char(10), f bit(1), +h char(1) default 'a') engine=myisam; +insert into t1 set a=1; +select h from t1; +h +a +drop table t1; diff --git a/mysql-test/t/type_bit.test b/mysql-test/t/type_bit.test index 1fbcf01d5a6..19d16f95990 100644 --- a/mysql-test/t/type_bit.test +++ b/mysql-test/t/type_bit.test @@ -140,3 +140,25 @@ drop table t1; create table t1 select * from t2; select a+0, b+0 from t1; drop table t1, t2; + +# +# Bug #10179: problem with NULLs and default values +# + +create table t1 (a int, b time, c tinyint, d bool, e char(10), f bit(1), + g bit(1) NOT NULL default 1, h char(1) default 'a'); +insert into t1 set a=1; +select hex(g), h from t1; +drop table t1; + +create table t1 (a int, b time, c tinyint, d bool, e char(10), f bit(1), + g bit(1) NOT NULL default 1); +insert into t1 set a=1; +select hex(g) from t1; +drop table t1; + +create table t1 (a int, b time, c tinyint, d bool, e char(10), f bit(1), + h char(1) default 'a') engine=myisam; +insert into t1 set a=1; +select h from t1; +drop table t1; diff --git a/sql/key.cc b/sql/key.cc index 3299c3db8f8..4bd71d2fa47 100644 --- a/sql/key.cc +++ b/sql/key.cc @@ -197,12 +197,6 @@ void key_restore(byte *to_record, byte *from_key, KEY *key_info, (key_part->null_bit == 128), field->bit_ofs, field->bit_len); } - else - { - clr_rec_bits(to_record + key_part->null_offset + - (key_part->null_bit == 128), - field->bit_ofs, field->bit_len); - } } if (key_part->key_part_flag & HA_BLOB_PART) { diff --git a/sql/unireg.cc b/sql/unireg.cc index 95a383e0f01..e29b97a3f03 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -647,7 +647,7 @@ static bool make_empty_rec(THD *thd, File file,enum db_type table_type, { int error; Field::utype type; - uint firstpos,null_count,null_length; + uint null_count; uchar *buff,*null_pos; TABLE table; create_field *field; @@ -671,15 +671,14 @@ static bool make_empty_rec(THD *thd, File file,enum db_type table_type, table.s->db_low_byte_first= handler->low_byte_first(); table.s->blob_ptr_size= portable_sizeof_char_ptr; - firstpos=reclength; null_count=0; if (!(table_options & HA_OPTION_PACK_RECORD)) { null_fields++; // Need one bit for delete mark null_count++; + *buff|= 1; } - bfill(buff,(null_length=(null_fields+7)/8),255); - null_pos= buff + null_count / 8; + null_pos= buff; List_iterator it(create_fields); thd->count_cuted_fields= CHECK_FIELD_WARN; // To find wrong default values @@ -689,7 +688,7 @@ static bool make_empty_rec(THD *thd, File file,enum db_type table_type, regfield don't have to be deleted as it's allocated with sql_alloc() */ Field *regfield=make_field((char*) buff+field->offset,field->length, - null_pos, + null_pos + null_count / 8, null_count & 7, field->pack_flag, field->sql_type, @@ -703,11 +702,13 @@ static bool make_empty_rec(THD *thd, File file,enum db_type table_type, goto err; // End of memory if (!(field->flags & NOT_NULL_FLAG)) + { + *regfield->null_ptr|= regfield->null_bit; null_count++; + } - if ((uint) field->offset < firstpos && - regfield->type() != FIELD_TYPE_NULL) - firstpos= field->offset; + if (field->sql_type == FIELD_TYPE_BIT && !f_bit_as_char(field->pack_flag)) + null_count+= field->length & 7; type= (Field::utype) MTYP_TYPENR(field->unireg_check); @@ -737,7 +738,9 @@ static bool make_empty_rec(THD *thd, File file,enum db_type table_type, } /* Fill not used startpos */ - bfill((byte*) buff+null_length,firstpos-null_length,255); + if (null_count) + *(null_pos + null_count / 8)|= ~(((uchar) 1 << (null_count & 7)) - 1); + error=(int) my_write(file,(byte*) buff,(uint) reclength,MYF_RW); err: