diff options
-rw-r--r-- | include/my_base.h | 2 | ||||
-rw-r--r-- | myisam/mi_delete.c | 2 | ||||
-rw-r--r-- | myisam/mi_key.c | 4 | ||||
-rw-r--r-- | myisam/mi_rnext_same.c | 4 | ||||
-rw-r--r-- | myisam/mi_unique.c | 3 | ||||
-rw-r--r-- | myisam/mi_update.c | 4 | ||||
-rw-r--r-- | myisam/mi_write.c | 4 | ||||
-rw-r--r-- | mysql-test/r/myisam.result | 18 | ||||
-rw-r--r-- | mysql-test/t/myisam.test | 19 |
9 files changed, 57 insertions, 3 deletions
diff --git a/include/my_base.h b/include/my_base.h index c82ecd06627..076eed9998f 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -399,7 +399,7 @@ enum ha_base_keytype { #define HA_STATE_BUFF_SAVED 512 /* If current keybuff is info->buff */ #define HA_STATE_ROW_CHANGED 1024 /* To invalide ROW cache */ #define HA_STATE_EXTEND_BLOCK 2048 -#define HA_STATE_RNEXT_SAME 4096 /* rnext_same was called */ +#define HA_STATE_RNEXT_SAME 4096 /* rnext_same occupied lastkey2 */ /* myisampack expects no more than 32 field types. */ enum en_fieldtype { diff --git a/myisam/mi_delete.c b/myisam/mi_delete.c index 2010b684300..2bc99d65dd2 100644 --- a/myisam/mi_delete.c +++ b/myisam/mi_delete.c @@ -88,6 +88,8 @@ int mi_delete(MI_INFO *info,const byte *record) _mi_make_key(info,i,old_key,record,info->lastpos))) goto err; } + /* The above changed info->lastkey2. Inform mi_rnext_same(). */ + info->update&= ~HA_STATE_RNEXT_SAME; } } diff --git a/myisam/mi_key.c b/myisam/mi_key.c index 4cabfc91197..5dcc99d41b4 100644 --- a/myisam/mi_key.c +++ b/myisam/mi_key.c @@ -444,6 +444,10 @@ static int _mi_put_key_in_record(register MI_INFO *info, uint keynr, (char*) &blob_ptr,sizeof(char*)); memcpy(blob_ptr,key,length); blob_ptr+=length; + + /* The above changed info->lastkey2. Inform mi_rnext_same(). */ + info->update&= ~HA_STATE_RNEXT_SAME; + _my_store_blob_length(record+keyseg->start, (uint) keyseg->bit_start,length); key+=length; diff --git a/myisam/mi_rnext_same.c b/myisam/mi_rnext_same.c index 92692d0517f..64d8d9b0baa 100644 --- a/myisam/mi_rnext_same.c +++ b/myisam/mi_rnext_same.c @@ -40,7 +40,7 @@ int mi_rnext_same(MI_INFO *info, byte *buf) if (info->s->concurrent_insert) rw_rdlock(&info->s->key_root_lock[inx]); - + switch (keyinfo->key_alg) { #ifdef HAVE_RTREE_KEYS @@ -102,4 +102,4 @@ int mi_rnext_same(MI_INFO *info, byte *buf) DBUG_RETURN(0); } DBUG_RETURN(my_errno); -} /* mi_rnext */ +} /* mi_rnext_same */ diff --git a/myisam/mi_unique.c b/myisam/mi_unique.c index 34f5f595f30..b698968127b 100644 --- a/myisam/mi_unique.c +++ b/myisam/mi_unique.c @@ -30,6 +30,9 @@ my_bool mi_check_unique(MI_INFO *info, MI_UNIQUEDEF *def, byte *record, mi_unique_store(record+key->seg->start, unique_hash); _mi_make_key(info,def->key,key_buff,record,0); + /* The above changed info->lastkey2. Inform mi_rnext_same(). */ + info->update&= ~HA_STATE_RNEXT_SAME; + if (_mi_search(info,info->s->keyinfo+def->key,key_buff,MI_UNIQUE_HASH_LENGTH, SEARCH_FIND,info->s->state.key_root[def->key])) { diff --git a/myisam/mi_update.c b/myisam/mi_update.c index 86652996afe..937c9983b45 100644 --- a/myisam/mi_update.c +++ b/myisam/mi_update.c @@ -111,6 +111,10 @@ int mi_update(register MI_INFO *info, const byte *oldrec, byte *newrec) { uint new_length=_mi_make_key(info,i,new_key,newrec,pos); uint old_length=_mi_make_key(info,i,old_key,oldrec,pos); + + /* The above changed info->lastkey2. Inform mi_rnext_same(). */ + info->update&= ~HA_STATE_RNEXT_SAME; + if (new_length != old_length || memcmp((byte*) old_key,(byte*) new_key,new_length)) { diff --git a/myisam/mi_write.c b/myisam/mi_write.c index 2dd84674bff..5e79b2937cc 100644 --- a/myisam/mi_write.c +++ b/myisam/mi_write.c @@ -132,6 +132,10 @@ int mi_write(MI_INFO *info, byte *record) goto err; } } + + /* The above changed info->lastkey2. Inform mi_rnext_same(). */ + info->update&= ~HA_STATE_RNEXT_SAME; + if (local_lock_tree) rw_unlock(&share->key_root_lock[i]); } diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 7d18c96bf5f..14195447b54 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -729,6 +729,24 @@ select * from t1 where bob is null and cip=1; cip time score bob 1 00:01:00 0 NULL drop table t1; +create table t1 ( +id1 int not null auto_increment, +id2 int not null default '0', +t text not null, +primary key (id1), +key x (id2, t(32)) +) engine=myisam; +insert into t1 (id2, t) values +(10, 'abc'), (10, 'abc'), (10, 'abc'), +(20, 'abc'), (20, 'abc'), (20, 'def'), +(10, 'abc'), (10, 'abc'); +select count(*) from t1 where id2 = 10; +count(*) +5 +select count(id1) from t1 where id2 = 10; +count(id1) +5 +drop table t1; set storage_engine=MyISAM; drop table if exists t1,t2,t3; --- Testing varchar --- diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index 4f07df4e4f2..15533ca00e6 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -678,6 +678,25 @@ select * from t1 where bob is null and cip=1; create index bug on t1 (bob(22), cip, time); select * from t1 where bob is null and cip=1; drop table t1; + +# +# Bug#14980 - COUNT(*) incorrect on MyISAM table with certain INDEX +# +create table t1 ( + id1 int not null auto_increment, + id2 int not null default '0', + t text not null, + primary key (id1), + key x (id2, t(32)) +) engine=myisam; +insert into t1 (id2, t) values +(10, 'abc'), (10, 'abc'), (10, 'abc'), +(20, 'abc'), (20, 'abc'), (20, 'def'), +(10, 'abc'), (10, 'abc'); +select count(*) from t1 where id2 = 10; +select count(id1) from t1 where id2 = 10; +drop table t1; + # End of 4.1 tests # |