summaryrefslogtreecommitdiff
path: root/myisam
diff options
context:
space:
mode:
authorunknown <monty@mashka.mysql.fi>2003-04-27 22:12:08 +0300
committerunknown <monty@mashka.mysql.fi>2003-04-27 22:12:08 +0300
commitf22be777341f53b4deb58851828c0733ab5380bf (patch)
tree9cf8ed6360561508fc24e4f8cc90f56282626854 /myisam
parent3e90ec6a582ec6a39209c00329ed93a7cc639ded (diff)
downloadmariadb-git-f22be777341f53b4deb58851828c0733ab5380bf.tar.gz
Fixed problem when comparing a key for a multi-byte-character set. (bug 152)
Use 0x.... as strings if 'new' mode. (bug 152) Don't report -max on windows when InnoDB is enabled. (bug 332) Reset current_linfo; This could cause a hang when doing PURGE LOGS. Fix for row numbers in EXPLAIN (bug 322) Fix that USE_FRM works for all table types (bug 97) VC++Files/libmysql/libmysql.dsp: Added new source files myisam/mi_key.c: Fixed problem when comparing a key for a multi-byte-character set. myisam/mi_range.c: Fixed problem when comparing a key for a multi-byte-character set. myisam/mi_rkey.c: Fixed problem when comparing a key for a multi-byte-character set. myisam/mi_search.c: Fixed problem when comparing a key for a multi-byte-character set. myisam/mi_test2.c: Fixed printf statements myisam/myisamdef.h: Fixed problem when comparing a key for a multi-byte-character set. myisam/sort.c: Fixed printf statements mysql-test/r/ctype_latin1_de.result: New test results mysql-test/r/join.result: New test results mysql-test/r/repair.result: New test results mysql-test/r/rpl_alter.result: New test results mysql-test/t/ctype_latin1_de-master.opt: --new is needed to get 0x... strings to work properly mysql-test/t/ctype_latin1_de.test: New test for latin1_de mysql-test/t/repair.test: Test of USE_FRM and HEAP tables sql/field.cc: Fixed problem when comparing a key for a multi-byte-character set. sql/item.cc: Use 0x.... as strings if 'new' mode sql/item.h: Use 0x.... as strings if 'new' mode sql/mysqld.cc: Don't report -max on windows when InnoDB is enabled. sql/sql_analyse.cc: Removed unused variable sql/sql_insert.cc: Removed debug message sql/sql_repl.cc: Reset current_linfo; This could cause a hang when doing PURGE LOGS. sql/sql_select.cc: Fix for row numbers in EXPLAIN sql/sql_table.cc: Fix that USE_FRM works for all table types (without strange errors) sql/sql_yacc.yy: Removed compiler warnings.
Diffstat (limited to 'myisam')
-rw-r--r--myisam/mi_key.c23
-rw-r--r--myisam/mi_range.c3
-rw-r--r--myisam/mi_rkey.c33
-rw-r--r--myisam/mi_search.c31
-rw-r--r--myisam/mi_test2.c12
-rw-r--r--myisam/myisamdef.h4
-rw-r--r--myisam/sort.c6
7 files changed, 88 insertions, 24 deletions
diff --git a/myisam/mi_key.c b/myisam/mi_key.c
index 9ec1ca99e0e..5b167cc9ab0 100644
--- a/myisam/mi_key.c
+++ b/myisam/mi_key.c
@@ -136,11 +136,26 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
} /* _mi_make_key */
- /* Pack a key to intern format from given format (c_rkey) */
- /* returns length of packed key */
+/*
+ Pack a key to intern format from given format (c_rkey)
+
+ SYNOPSIS
+ _mi_pack_key()
+ info MyISAM handler
+ uint keynr key number
+ key Store packed key here
+ old Not packed key
+ k_length Length of 'old' to use
+ last_used_keyseg out parameter. May be NULL
+
+ RETURN
+ length of packed key
+
+ last_use_keyseg Store pointer to the keyseg after the last used one
+*/
uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old,
- uint k_length)
+ uint k_length, MI_KEYSEG **last_used_keyseg)
{
uint length;
uchar *pos,*end,*start_key=key;
@@ -211,6 +226,8 @@ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old,
key+= length;
k_length-=length;
}
+ if (last_used_keyseg)
+ *last_used_keyseg= keyseg;
#ifdef NOT_USED
if (keyseg->type)
diff --git a/myisam/mi_range.c b/myisam/mi_range.c
index 70694bf4620..8e85afc5f80 100644
--- a/myisam/mi_range.c
+++ b/myisam/mi_range.c
@@ -83,7 +83,8 @@ static ha_rows _mi_record_pos(MI_INFO *info, const byte *key, uint key_len,
if (key_len == 0)
key_len=USE_WHOLE_KEY;
key_buff=info->lastkey+info->s->base.max_key_length;
- key_len=_mi_pack_key(info,inx,key_buff,(uchar*) key,key_len);
+ key_len=_mi_pack_key(info,inx,key_buff,(uchar*) key,key_len,
+ (MI_KEYSEG**) 0);
DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,keyinfo->seg,
(uchar*) key_buff,key_len););
nextflag=myisam_read_vec[search_flag];
diff --git a/myisam/mi_rkey.c b/myisam/mi_rkey.c
index 86547d3ef04..60dec0449a0 100644
--- a/myisam/mi_rkey.c
+++ b/myisam/mi_rkey.c
@@ -23,10 +23,12 @@
/* Ordinary search_flag is 0 ; Give error if no record with key */
int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
- enum ha_rkey_function search_flag)
+ enum ha_rkey_function search_flag)
{
uchar *key_buff;
MYISAM_SHARE *share=info->s;
+ MI_KEYDEF *keyinfo;
+ MI_KEYSEG *last_used_keyseg;
uint pack_key_length, use_key_length, nextflag;
DBUG_ENTER("mi_rkey");
DBUG_PRINT("enter",("base: %lx inx: %d search_flag: %d",
@@ -36,23 +38,27 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
DBUG_RETURN(my_errno);
info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
+ keyinfo= share->keyinfo + inx;
if (!info->use_packed_key)
{
if (key_len == 0)
key_len=USE_WHOLE_KEY;
key_buff=info->lastkey+info->s->base.max_key_length;
- pack_key_length=_mi_pack_key(info,(uint) inx,key_buff,(uchar*) key,key_len);
- info->last_rkey_length=pack_key_length;
- DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,share->keyinfo[inx].seg,
- key_buff,pack_key_length););
+ pack_key_length=_mi_pack_key(info, (uint) inx, key_buff, (uchar*) key,
+ key_len, &last_used_keyseg);
+ DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE, keyinfo->seg,
+ key_buff, pack_key_length););
}
else
{
- /* key is already packed! */
+ /*
+ key is already packed!; This happens when we are using a MERGE TABLE
+ */
key_buff=info->lastkey+info->s->base.max_key_length;
- info->last_rkey_length=pack_key_length=key_len;
+ pack_key_length= key_len;
bmove(key_buff,key,key_len);
+ last_used_keyseg= 0;
}
if (fast_mi_readinfo(info))
@@ -65,8 +71,8 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
if (!(nextflag & (SEARCH_FIND | SEARCH_NO_FIND | SEARCH_LAST)))
use_key_length=USE_WHOLE_KEY;
- if (!_mi_search(info,info->s->keyinfo+inx,key_buff,use_key_length,
- myisam_read_vec[search_flag],info->s->state.key_root[inx]))
+ if (!_mi_search(info,keyinfo, key_buff, use_key_length,
+ myisam_read_vec[search_flag], info->s->state.key_root[inx]))
{
while (info->lastpos >= info->state->data_file_length)
{
@@ -76,7 +82,7 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
exact key, because the keys are sorted according to position
*/
- if (_mi_search_next(info,info->s->keyinfo+inx,info->lastkey,
+ if (_mi_search_next(info, keyinfo, info->lastkey,
info->lastkey_length,
myisam_readnext_vec[search_flag],
info->s->state.key_root[inx]))
@@ -86,6 +92,12 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
if (share->concurrent_insert)
rw_unlock(&share->key_root_lock[inx]);
+ /* Calculate length of the found key; Used by mi_rnext_same */
+ if ((keyinfo->flag & HA_VAR_LENGTH_KEY) && last_used_keyseg)
+ info->last_rkey_length= _mi_keylength_part(keyinfo, info->lastkey,
+ last_used_keyseg);
+ else
+ info->last_rkey_length= pack_key_length;
if (!buf)
DBUG_RETURN(info->lastpos==HA_OFFSET_ERROR ? my_errno : 0);
@@ -99,6 +111,7 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
/* Store key for read next */
memcpy(info->lastkey,key_buff,pack_key_length);
+ info->last_rkey_length= pack_key_length;
bzero((char*) info->lastkey+pack_key_length,info->s->base.rec_reflength);
info->lastkey_length=pack_key_length+info->s->base.rec_reflength;
diff --git a/myisam/mi_search.c b/myisam/mi_search.c
index 41d53e76241..32db69144d8 100644
--- a/myisam/mi_search.c
+++ b/myisam/mi_search.c
@@ -1441,6 +1441,37 @@ uint _mi_keylength(MI_KEYDEF *keyinfo, register uchar *key)
} /* _mi_keylength */
+/*
+ Calculate length of part key.
+
+ Used in mi_rkey() to find the key found for the key-part that was used.
+ This is needed in case of multi-byte character sets where we may search
+ after '0xDF' but find 'ss'
+*/
+
+uint _mi_keylength_part(MI_KEYDEF *keyinfo, register uchar *key,
+ MI_KEYSEG *end)
+{
+ reg1 MI_KEYSEG *keyseg;
+ uchar *start= key;
+
+ for (keyseg=keyinfo->seg ; keyseg != end ; keyseg++)
+ {
+ if (keyseg->flag & HA_NULL_PART)
+ if (!*key++)
+ continue;
+ if (keyseg->flag & (HA_SPACE_PACK | HA_BLOB_PART | HA_VAR_LENGTH))
+ {
+ uint length;
+ get_key_length(length,key);
+ key+=length;
+ }
+ else
+ key+= keyseg->length;
+ }
+ return (uint) (key-start);
+}
+
/* Move a key */
uchar *_mi_move_key(MI_KEYDEF *keyinfo, uchar *to, uchar *from)
diff --git a/myisam/mi_test2.c b/myisam/mi_test2.c
index 93538e3ead7..e3a2ecfbb1f 100644
--- a/myisam/mi_test2.c
+++ b/myisam/mi_test2.c
@@ -639,14 +639,14 @@ int main(int argc, char *argv[])
if ((long) range_records < (long) records*7/10-2 ||
(long) range_records > (long) records*14/10+2)
{
- printf("mi_records_range for key: %d returned %ld; Should be about %ld\n",
- i, range_records, records);
+ printf("mi_records_range for key: %d returned %lu; Should be about %lu\n",
+ i, (ulong) range_records, (ulong) records);
goto end;
}
if (verbose && records)
{
- printf("mi_records_range returned %ld; Exact is %ld (diff: %4.2g %%)\n",
- range_records,records,
+ printf("mi_records_range returned %lu; Exact is %lu (diff: %4.2g %%)\n",
+ (ulong) range_records, (ulong) records,
labs((long) range_records-(long) records)*100.0/records);
}
@@ -660,8 +660,8 @@ int main(int argc, char *argv[])
|| info.keys != keys)
{
puts("Wrong info from mi_info");
- printf("Got: records: %ld delete: %ld i_keys: %d\n",
- info.records,info.deleted,info.keys);
+ printf("Got: records: %lu delete: %lu i_keys: %d\n",
+ (ulong) info.records, (ulong) info.deleted, info.keys);
}
if (verbose)
{
diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h
index 7c035bc6097..7631b245b9b 100644
--- a/myisam/myisamdef.h
+++ b/myisam/myisamdef.h
@@ -505,6 +505,8 @@ extern uchar *_mi_get_last_key(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *keypos,
extern uchar *_mi_get_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
uchar *key, uchar *keypos, uint *return_key_length);
extern uint _mi_keylength(MI_KEYDEF *keyinfo,uchar *key);
+extern uint _mi_keylength_part(MI_KEYDEF *keyinfo, register uchar *key,
+ MI_KEYSEG *end);
extern uchar *_mi_move_key(MI_KEYDEF *keyinfo,uchar *to,uchar *from);
extern int _mi_search_next(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *key,
uint key_length,uint nextflag,my_off_t pos);
@@ -519,7 +521,7 @@ extern my_off_t _mi_new(MI_INFO *info,MI_KEYDEF *keyinfo);
extern uint _mi_make_key(MI_INFO *info,uint keynr,uchar *key,
const byte *record,my_off_t filepos);
extern uint _mi_pack_key(MI_INFO *info,uint keynr,uchar *key,uchar *old,
- uint key_length);
+ uint key_length, MI_KEYSEG **last_used_keyseg);
extern int _mi_read_key_record(MI_INFO *info,my_off_t filepos,byte *buf);
extern int _mi_read_cache(IO_CACHE *info,byte *buff,my_off_t pos,
uint length,int re_read_if_possibly);
diff --git a/myisam/sort.c b/myisam/sort.c
index ddf565d5092..224b4ad8420 100644
--- a/myisam/sort.c
+++ b/myisam/sort.c
@@ -163,8 +163,8 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
if (maxbuffer == 0)
{
if (!no_messages)
- printf(" - Dumping %lu keys\n",records);
- if (write_index(info,sort_keys,(uint) records))
+ printf(" - Dumping %lu keys\n", (ulong) records);
+ if (write_index(info,sort_keys, (uint) records))
goto err; /* purecov: inspected */
}
else
@@ -173,7 +173,7 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
if (maxbuffer >= MERGEBUFF2)
{
if (!no_messages)
- printf(" - Merging %lu keys\n",records); /* purecov: tested */
+ printf(" - Merging %lu keys\n", (ulong) records); /* purecov: tested */
if (merge_many_buff(info,keys,sort_keys,
dynamic_element(&buffpek,0,BUFFPEK *),&maxbuffer,&tempfile))
goto err; /* purecov: inspected */