diff options
author | unknown <ingo@mysql.com> | 2006-03-10 15:03:04 +0100 |
---|---|---|
committer | unknown <ingo@mysql.com> | 2006-03-10 15:03:04 +0100 |
commit | fbe17c2a36dcaa99c5a6570f7096745126113301 (patch) | |
tree | 801bfa5ba08dc20436d5731d021e7d7e7cf2f4e5 /myisam | |
parent | a7abbd918ba952e2f387cec28ed0f74997b14975 (diff) | |
download | mariadb-git-fbe17c2a36dcaa99c5a6570f7096745126113301.tar.gz |
Bug#14980 - COUNT(*) incorrect on MyISAM table with certain INDEX
For "count(*) while index_column = value" an index read
is done. It consists of an index scan and retrieval of
each key.
For efficiency reasons the index scan stores the key in
the special buffer 'lastkey2' once only. At the first
iteration it notes this fact with the flag
HA_STATE_RNEXT_SAME in 'info->update'.
For efficiency reasons, the key retrieval for blobs
does not allocate a new buffer, but uses 'lastkey2'...
Now I clear the HA_STATE_RNEXT_SAME flag whenever the
buffer has been polluted. In this case, the index scan
copies the key value again (and sets the flag again).
include/my_base.h:
Bug#14980 - COUNT(*) incorrect on MyISAM table with certain INDEX
Changed the comment for HA_STATE_RNEXT_SAME as a warning
for future uses.
myisam/mi_delete.c:
Bug#14980 - COUNT(*) incorrect on MyISAM table with certain INDEX
Removing the flag HA_STATE_RNEXT_SAME from info->update
if info->lastkey2 was reused for another purpose than
index scanning.
myisam/mi_key.c:
Bug#14980 - COUNT(*) incorrect on MyISAM table with certain INDEX
Removing the flag HA_STATE_RNEXT_SAME from info->update
if info->lastkey2 was reused for another purpose than
index scanning.
myisam/mi_rnext_same.c:
Bug#14980 - COUNT(*) incorrect on MyISAM table with certain INDEX
Removed trailing space and fixed a comment.
myisam/mi_unique.c:
Bug#14980 - COUNT(*) incorrect on MyISAM table with certain INDEX
Removing the flag HA_STATE_RNEXT_SAME from info->update
if info->lastkey2 was reused for another purpose than
index scanning.
myisam/mi_update.c:
Bug#14980 - COUNT(*) incorrect on MyISAM table with certain INDEX
Removing the flag HA_STATE_RNEXT_SAME from info->update
if info->lastkey2 was reused for another purpose than
index scanning.
myisam/mi_write.c:
Bug#14980 - COUNT(*) incorrect on MyISAM table with certain INDEX
Removing the flag HA_STATE_RNEXT_SAME from info->update
if info->lastkey2 was reused for another purpose than
index scanning.
mysql-test/r/myisam.result:
Bug#14980 - COUNT(*) incorrect on MyISAM table with certain INDEX
Added test result.
mysql-test/t/myisam.test:
Bug#14980 - COUNT(*) incorrect on MyISAM table with certain INDEX
Added test.
Diffstat (limited to 'myisam')
-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 |
6 files changed, 19 insertions, 2 deletions
diff --git a/myisam/mi_delete.c b/myisam/mi_delete.c index 6c302aecea1..00699e8b089 100644 --- a/myisam/mi_delete.c +++ b/myisam/mi_delete.c @@ -82,6 +82,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 f4b92f969db..cb85febd869 100644 --- a/myisam/mi_key.c +++ b/myisam/mi_key.c @@ -393,6 +393,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 ad685f4cbdc..b5baa448609 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 f62be133ed9..672c8407353 100644 --- a/myisam/mi_update.c +++ b/myisam/mi_update.c @@ -108,6 +108,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 52455320515..720c96b2d38 100644 --- a/myisam/mi_write.c +++ b/myisam/mi_write.c @@ -128,6 +128,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]); } |