diff --git a/mysql-test/r/heap_btree.result b/mysql-test/r/heap_btree.result index 7ad0f212d99..fb26f98cdaf 100644 --- a/mysql-test/r/heap_btree.result +++ b/mysql-test/r/heap_btree.result @@ -344,3 +344,38 @@ INSERT INTO t1 VALUES(1),(1); DELETE a1 FROM t1 AS a1, t1 AS a2 WHERE a1.a=a2.a; DROP TABLE t1; End of 5.0 tests +# bit index in heap tables +create table t1 (a bit(63) not null) engine=heap; +insert into t1 values (869751),(736494),(226312),(802616),(728912); +alter table t1 add unique uniq_id using BTREE (a); +select 0+a from t1 where a > 736494; +0+a +802616 +869751 +explain select 0+a from t1 where a > 736494; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range uniq_id uniq_id 8 NULL 3 Using where +select 0+a from t1 where a = 736494; +0+a +736494 +explain select 0+a from t1 where a = 736494; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const uniq_id uniq_id 8 const 1 +select 0+a from t1 where a=869751 or a=736494; +0+a +736494 +869751 +explain select 0+a from t1 where a=869751 or a=736494; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range uniq_id uniq_id 8 NULL 2 Using where +select 0+a from t1 where a in (869751,736494,226312,802616); +0+a +226312 +736494 +802616 +869751 +explain select 0+a from t1 where a in (869751,736494,226312,802616); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range uniq_id uniq_id 8 NULL 4 Using where +drop table t1; +End of 5.3 tests diff --git a/mysql-test/r/heap_hash.result b/mysql-test/r/heap_hash.result index bae49af462f..ba7d79e491a 100644 --- a/mysql-test/r/heap_hash.result +++ b/mysql-test/r/heap_hash.result @@ -382,3 +382,38 @@ INSERT INTO t1 VALUES('A ', 'A '); ERROR 23000: Duplicate entry 'A -A ' for key 'key1' DROP TABLE t1; End of 5.0 tests +# bit index in heap tables +create table t1 (a bit(63) not null) engine=heap; +insert into t1 values (869751),(736494),(226312),(802616),(728912); +alter table t1 add unique uniq_id using HASH (a); +select 0+a from t1 where a > 736494; +0+a +869751 +802616 +explain select 0+a from t1 where a > 736494; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL uniq_id NULL NULL NULL 5 Using where +select 0+a from t1 where a = 736494; +0+a +736494 +explain select 0+a from t1 where a = 736494; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const uniq_id uniq_id 8 const 1 +select 0+a from t1 where a=869751 or a=736494; +0+a +736494 +869751 +explain select 0+a from t1 where a=869751 or a=736494; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range uniq_id uniq_id 8 NULL 2 Using where +select 0+a from t1 where a in (869751,736494,226312,802616); +0+a +226312 +736494 +802616 +869751 +explain select 0+a from t1 where a in (869751,736494,226312,802616); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range uniq_id uniq_id 8 NULL 4 Using where +drop table t1; +End of 5.3 tests diff --git a/mysql-test/t/heap_btree.test b/mysql-test/t/heap_btree.test index 637c6ba1c81..02c09f52263 100644 --- a/mysql-test/t/heap_btree.test +++ b/mysql-test/t/heap_btree.test @@ -263,3 +263,19 @@ DELETE a1 FROM t1 AS a1, t1 AS a2 WHERE a1.a=a2.a; DROP TABLE t1; --echo End of 5.0 tests +-- echo # bit index in heap tables + +create table t1 (a bit(63) not null) engine=heap; +insert into t1 values (869751),(736494),(226312),(802616),(728912); +alter table t1 add unique uniq_id using BTREE (a); +select 0+a from t1 where a > 736494; +explain select 0+a from t1 where a > 736494; +select 0+a from t1 where a = 736494; +explain select 0+a from t1 where a = 736494; +select 0+a from t1 where a=869751 or a=736494; +explain select 0+a from t1 where a=869751 or a=736494; +select 0+a from t1 where a in (869751,736494,226312,802616); +explain select 0+a from t1 where a in (869751,736494,226312,802616); +drop table t1; + +--echo End of 5.3 tests diff --git a/mysql-test/t/heap_hash.test b/mysql-test/t/heap_hash.test index 1e3491f89a9..a2960560e57 100644 --- a/mysql-test/t/heap_hash.test +++ b/mysql-test/t/heap_hash.test @@ -284,3 +284,20 @@ INSERT INTO t1 VALUES('A ', 'A '); DROP TABLE t1; --echo End of 5.0 tests + +-- echo # bit index in heap tables + +create table t1 (a bit(63) not null) engine=heap; +insert into t1 values (869751),(736494),(226312),(802616),(728912); +alter table t1 add unique uniq_id using HASH (a); +select 0+a from t1 where a > 736494; +explain select 0+a from t1 where a > 736494; +select 0+a from t1 where a = 736494; +explain select 0+a from t1 where a = 736494; +select 0+a from t1 where a=869751 or a=736494; +explain select 0+a from t1 where a=869751 or a=736494; +select 0+a from t1 where a in (869751,736494,226312,802616); +explain select 0+a from t1 where a in (869751,736494,226312,802616); +drop table t1; + +--echo End of 5.3 tests diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc index 42437a22614..20d01c62b31 100644 --- a/storage/heap/ha_heap.cc +++ b/storage/heap/ha_heap.cc @@ -654,7 +654,8 @@ int ha_heap::create(const char *name, TABLE *table_arg, seg->type != HA_KEYTYPE_VARTEXT1 && seg->type != HA_KEYTYPE_VARTEXT2 && seg->type != HA_KEYTYPE_VARBINARY1 && - seg->type != HA_KEYTYPE_VARBINARY2) + seg->type != HA_KEYTYPE_VARBINARY2 && + seg->type != HA_KEYTYPE_BIT) seg->type= HA_KEYTYPE_BINARY; } seg->start= (uint) key_part->offset; @@ -686,6 +687,15 @@ int ha_heap::create(const char *name, TABLE *table_arg, auto_key= key+ 1; auto_key_type= field->key_type(); } + if (seg->type == HA_KEYTYPE_BIT) + { + seg->bit_length= ((Field_bit *) field)->bit_len; + seg->bit_start= ((Field_bit *) field)->bit_ofs; + seg->bit_pos= (uint) (((Field_bit *) field)->bit_ptr - + (uchar*) table_arg->record[0]); + } + else + seg->bit_length= seg->bit_start= seg->bit_pos= 0; } } mem_per_row+= MY_ALIGN(share->reclength + 1, sizeof(char*)); diff --git a/storage/heap/hp_create.c b/storage/heap/hp_create.c index bc8183bf777..2036bd7166f 100644 --- a/storage/heap/hp_create.c +++ b/storage/heap/hp_create.c @@ -104,6 +104,14 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, */ keyinfo->seg[j].type= HA_KEYTYPE_VARTEXT1; break; + case HA_KEYTYPE_BIT: + /* + The odd bits which stored separately (if they are present + (bit_pos, bit_length)) are already present in seg[j].length as + additional byte. + See field.h, function key_length() + */ + break; default: break; } diff --git a/storage/heap/hp_hash.c b/storage/heap/hp_hash.c index aaaa0fe833f..fb9ea44a424 100644 --- a/storage/heap/hp_hash.c +++ b/storage/heap/hp_hash.c @@ -349,6 +349,15 @@ ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const uchar *rec) } else { + if (seg->type == HA_KEYTYPE_BIT && seg->bit_length) + { + uchar bits= get_rec_bits(rec + seg->bit_pos, + seg->bit_start, seg->bit_length); + nr^=(ulong) ((((uint) nr & 63)+nr2)*((uint) bits))+ (nr << 8); + nr2+=3; + end--; + } + for (; pos < end ; pos++) { nr^=(ulong) ((((uint) nr & 63)+nr2)*((uint) *pos))+ (nr << 8); @@ -465,6 +474,14 @@ ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const uchar *rec) else { uchar *end= pos+seg->length; + if (seg->type == HA_KEYTYPE_BIT && seg->bit_length) + { + uchar bits= get_rec_bits(rec + seg->bit_pos, + seg->bit_start, seg->bit_length); + nr *=16777619; + nr ^=(uint) bits; + end--; + } for ( ; pos < end ; pos++) { nr *=16777619; @@ -577,7 +594,18 @@ int hp_rec_key_cmp(HP_KEYDEF *keydef, const uchar *rec1, const uchar *rec2, } else { - if (bcmp(rec1+seg->start,rec2+seg->start,seg->length)) + uint dec= 0; + if (seg->type == HA_KEYTYPE_BIT && seg->bit_length) + { + uchar bits1= get_rec_bits(rec1 + seg->bit_pos, + seg->bit_start, seg->bit_length); + uchar bits2= get_rec_bits(rec2 + seg->bit_pos, + seg->bit_start, seg->bit_length); + if (bits1 != bits2) + return 1; + dec= 1; + } + if (bcmp(rec1 + seg->start, rec2 + seg->start, seg->length - dec)) return 1; } } @@ -660,7 +688,18 @@ int hp_key_cmp(HP_KEYDEF *keydef, const uchar *rec, const uchar *key) } else { - if (bcmp(rec+seg->start,key,seg->length)) + uint dec= 0; + if (seg->type == HA_KEYTYPE_BIT && seg->bit_length) + { + uchar bits= get_rec_bits(rec + seg->bit_pos, + seg->bit_start, seg->bit_length); + if (bits != (*key)) + return 1; + dec= 1; + key++; + } + + if (bcmp(rec + seg->start, key, seg->length - dec)) return 1; } } @@ -689,6 +728,12 @@ void hp_make_key(HP_KEYDEF *keydef, uchar *key, const uchar *rec) } if (seg->type == HA_KEYTYPE_VARTEXT1) char_length+= seg->bit_start; /* Copy also length */ + else if (seg->type == HA_KEYTYPE_BIT && seg->bit_length) + { + *key++= get_rec_bits(rec + seg->bit_pos, + seg->bit_start, seg->bit_length); + char_length--; + } memcpy(key,rec+seg->start,(size_t) char_length); key+= char_length; } @@ -720,7 +765,8 @@ uint hp_rb_make_key(HP_KEYDEF *keydef, uchar *key, { uint length= seg->length; uchar *pos= (uchar*) rec + seg->start; - + DBUG_ASSERT(seg->type != HA_KEYTYPE_BIT); + #ifdef HAVE_ISNAN if (seg->type == HA_KEYTYPE_FLOAT) { @@ -784,6 +830,12 @@ uint hp_rb_make_key(HP_KEYDEF *keydef, uchar *key, seg->charset->cset->fill(seg->charset, (char*) key + char_length, seg->length - char_length, ' '); } + if (seg->type == HA_KEYTYPE_BIT && seg->bit_length) + { + *key++= get_rec_bits(rec + seg->bit_pos, + seg->bit_start, seg->bit_length); + char_length--; + } memcpy(key, rec + seg->start, (size_t) char_length); key+= seg->length; }