summaryrefslogtreecommitdiff
path: root/myisam
diff options
context:
space:
mode:
authorunknown <svoj@mysql.com/april.(none)>2007-04-11 01:40:35 +0500
committerunknown <svoj@mysql.com/april.(none)>2007-04-11 01:40:35 +0500
commit6866ca008c941d2cc7afa106607257d9aaace519 (patch)
tree2482931c9bb45377c1054fe895e884386ccba920 /myisam
parentf6eca60afb461fddfe7ccd0096a48a4631489c75 (diff)
downloadmariadb-git-6866ca008c941d2cc7afa106607257d9aaace519.tar.gz
BUG#24342 - Incorrect results with query over MERGE table
MERGE engine may return incorrect values when several representations of equal keys are present in the index. For example "groß" and "gross" or "gross" and "gross " (trailing space), which are considered equal, but have different lengths. The problem was that key length was not recalculated after key lookup. Only MERGE engine is affected. myisam/mi_rkey.c: info->lastkey gets rewritten by mi_search. Later we recalculate found lastkey length. This is done to make sure that mi_rnext_same gets true, found (not searched) lastkey length. Searched and found key lengths may be different, for example in case searched key is "groß" and found is "gross" or in case a key has trailing spaces. Unfortunately we recalculate found lastkey length only for first underlying table. To recalculate found key length for non-first underlying table we need to know how much key segments were used to create this key. When mi_rkey is called for first underlying table of a merge table, store offset to last used key segment. Restore last_used_keyseg variable when mi_rkey is called for non-first underlying table. myisam/myisamdef.h: Added last_used_keyseg variable to MI_INFO. It is used by merge engine to calculate key length. myisammrg/myrg_rkey.c: Pass last used key segment returned by first table key read to other table key reads. mysql-test/r/merge.result: A test case for bug#24342. mysql-test/t/merge.test: A test case for bug#24342.
Diffstat (limited to 'myisam')
-rw-r--r--myisam/mi_rkey.c3
-rw-r--r--myisam/myisamdef.h1
2 files changed, 3 insertions, 1 deletions
diff --git a/myisam/mi_rkey.c b/myisam/mi_rkey.c
index b2d40288645..2933d694318 100644
--- a/myisam/mi_rkey.c
+++ b/myisam/mi_rkey.c
@@ -50,7 +50,7 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
key_buff=info->lastkey+info->s->base.max_key_length;
pack_key_length= key_len;
bmove(key_buff,key,key_len);
- last_used_keyseg= 0;
+ last_used_keyseg= info->s->keyinfo[inx].seg + info->last_used_keyseg;
}
else
{
@@ -62,6 +62,7 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
key_len, &last_used_keyseg);
/* Save packed_key_length for use by the MERGE engine. */
info->pack_key_length= pack_key_length;
+ info->last_used_keyseg= last_used_keyseg - info->s->keyinfo[inx].seg;
DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE, keyinfo->seg,
key_buff, pack_key_length););
}
diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h
index 6365f0e1b0c..6ed041e8b9d 100644
--- a/myisam/myisamdef.h
+++ b/myisam/myisamdef.h
@@ -263,6 +263,7 @@ struct st_myisam_info {
enum ha_rkey_function last_key_func; /* CONTAIN, OVERLAP, etc */
uint save_lastkey_length;
uint pack_key_length; /* For MYISAMMRG */
+ uint16 last_used_keyseg; /* For MyISAMMRG */
int errkey; /* Got last error on this key */
int lock_type; /* How database was locked */
int tmp_lock_type; /* When locked by readinfo */