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)
This commit is contained in:
parent
8b20a878cc
commit
dd377bfba6
@ -25,7 +25,7 @@ CFG=libmysql - Win32 Debug
|
|||||||
# PROP AllowPerConfigDependencies 0
|
# PROP AllowPerConfigDependencies 0
|
||||||
# PROP Scc_ProjName ""
|
# PROP Scc_ProjName ""
|
||||||
# PROP Scc_LocalPath ""
|
# PROP Scc_LocalPath ""
|
||||||
CPP=cl.exe
|
CPP=xicl6.exe
|
||||||
MTL=midl.exe
|
MTL=midl.exe
|
||||||
RSC=rc.exe
|
RSC=rc.exe
|
||||||
|
|
||||||
@ -52,14 +52,14 @@ RSC=rc.exe
|
|||||||
BSC32=bscmake.exe
|
BSC32=bscmake.exe
|
||||||
# ADD BASE BSC32 /nologo
|
# ADD BASE BSC32 /nologo
|
||||||
# ADD BSC32 /nologo
|
# ADD BSC32 /nologo
|
||||||
LINK32=link.exe
|
LINK32=xilink6.exe
|
||||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
|
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
|
||||||
# ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 /def:"libmysql.def" /out:"..\lib_release\libmysql.dll" /libpath:"." /libpath:"..\lib_release"
|
# ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 /def:"libmysql.def" /out:"..\lib_release\libmysql.dll" /libpath:"." /libpath:"..\lib_release"
|
||||||
# SUBTRACT LINK32 /pdb:none
|
# SUBTRACT LINK32 /pdb:none
|
||||||
# Begin Special Build Tool
|
# Begin Special Build Tool
|
||||||
SOURCE="$(InputPath)"
|
SOURCE="$(InputPath)"
|
||||||
PostBuild_Desc=Copy .lib file
|
PostBuild_Desc=Move DLL export lib
|
||||||
PostBuild_Cmds=xcopy release\libmysql.lib ..\lib_release\
|
PostBuild_Cmds=xcopy release\libmysql.lib ..\lib_release /y
|
||||||
# End Special Build Tool
|
# End Special Build Tool
|
||||||
|
|
||||||
!ELSEIF "$(CFG)" == "libmysql - Win32 Debug"
|
!ELSEIF "$(CFG)" == "libmysql - Win32 Debug"
|
||||||
@ -85,14 +85,14 @@ PostBuild_Cmds=xcopy release\libmysql.lib ..\lib_release\
|
|||||||
BSC32=bscmake.exe
|
BSC32=bscmake.exe
|
||||||
# ADD BASE BSC32 /nologo
|
# ADD BASE BSC32 /nologo
|
||||||
# ADD BSC32 /nologo
|
# ADD BSC32 /nologo
|
||||||
LINK32=link.exe
|
LINK32=xilink6.exe
|
||||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
|
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
|
||||||
# ADD LINK32 zlib.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /incremental:no /map /debug /machine:I386 /def:"libmysql.def" /out:"..\lib_debug\libmysql.dll" /pdbtype:sept /libpath:"." /libpath:"..\lib_debug"
|
# ADD LINK32 zlib.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /incremental:no /map /debug /machine:I386 /def:"libmysql.def" /out:"..\lib_debug\libmysql.dll" /pdbtype:sept /libpath:"." /libpath:"..\lib_debug"
|
||||||
# SUBTRACT LINK32 /pdb:none
|
# SUBTRACT LINK32 /pdb:none
|
||||||
# Begin Special Build Tool
|
# Begin Special Build Tool
|
||||||
SOURCE="$(InputPath)"
|
SOURCE="$(InputPath)"
|
||||||
PostBuild_Desc=Copy .lib file
|
PostBuild_Desc=Move DLL export lib
|
||||||
PostBuild_Cmds=xcopy ..\lib_debug\libmysql.dll C:\winnt\system32\ xcopy debug\libmysql.lib ..\lib_debug\
|
PostBuild_Cmds=xcopy ..\lib_debug\libmysql.dll C:\winnt\system32\ /y xcopy debug\libmysql.lib ..\lib_debug\ /y
|
||||||
# End Special Build Tool
|
# End Special Build Tool
|
||||||
|
|
||||||
!ENDIF
|
!ENDIF
|
||||||
@ -239,6 +239,10 @@ SOURCE=..\mysys\mf_pack.c
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\mysys\mf_path.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\mysys\mf_unixpath.c
|
SOURCE=..\mysys\mf_unixpath.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
@ -395,6 +399,10 @@ SOURCE=..\client\select_test.c
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\mysys\sha1.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\client\sql_string.cpp
|
SOURCE=..\client\sql_string.cpp
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
@ -136,11 +136,26 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
|
|||||||
} /* _mi_make_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 _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;
|
uint length;
|
||||||
uchar *pos,*end,*start_key=key;
|
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;
|
key+= length;
|
||||||
k_length-=length;
|
k_length-=length;
|
||||||
}
|
}
|
||||||
|
if (last_used_keyseg)
|
||||||
|
*last_used_keyseg= keyseg;
|
||||||
|
|
||||||
#ifdef NOT_USED
|
#ifdef NOT_USED
|
||||||
if (keyseg->type)
|
if (keyseg->type)
|
||||||
|
@ -83,7 +83,8 @@ static ha_rows _mi_record_pos(MI_INFO *info, const byte *key, uint key_len,
|
|||||||
if (key_len == 0)
|
if (key_len == 0)
|
||||||
key_len=USE_WHOLE_KEY;
|
key_len=USE_WHOLE_KEY;
|
||||||
key_buff=info->lastkey+info->s->base.max_key_length;
|
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,
|
DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,keyinfo->seg,
|
||||||
(uchar*) key_buff,key_len););
|
(uchar*) key_buff,key_len););
|
||||||
nextflag=myisam_read_vec[search_flag];
|
nextflag=myisam_read_vec[search_flag];
|
||||||
|
@ -23,10 +23,12 @@
|
|||||||
/* Ordinary search_flag is 0 ; Give error if no record with key */
|
/* 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,
|
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;
|
uchar *key_buff;
|
||||||
MYISAM_SHARE *share=info->s;
|
MYISAM_SHARE *share=info->s;
|
||||||
|
MI_KEYDEF *keyinfo;
|
||||||
|
MI_KEYSEG *last_used_keyseg;
|
||||||
uint pack_key_length, use_key_length, nextflag;
|
uint pack_key_length, use_key_length, nextflag;
|
||||||
DBUG_ENTER("mi_rkey");
|
DBUG_ENTER("mi_rkey");
|
||||||
DBUG_PRINT("enter",("base: %lx inx: %d search_flag: %d",
|
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);
|
DBUG_RETURN(my_errno);
|
||||||
|
|
||||||
info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
|
info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
|
||||||
|
keyinfo= share->keyinfo + inx;
|
||||||
|
|
||||||
if (!info->use_packed_key)
|
if (!info->use_packed_key)
|
||||||
{
|
{
|
||||||
if (key_len == 0)
|
if (key_len == 0)
|
||||||
key_len=USE_WHOLE_KEY;
|
key_len=USE_WHOLE_KEY;
|
||||||
key_buff=info->lastkey+info->s->base.max_key_length;
|
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);
|
pack_key_length=_mi_pack_key(info, (uint) inx, key_buff, (uchar*) key,
|
||||||
info->last_rkey_length=pack_key_length;
|
key_len, &last_used_keyseg);
|
||||||
DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,share->keyinfo[inx].seg,
|
DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE, keyinfo->seg,
|
||||||
key_buff,pack_key_length););
|
key_buff, pack_key_length););
|
||||||
}
|
}
|
||||||
else
|
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;
|
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);
|
bmove(key_buff,key,key_len);
|
||||||
|
last_used_keyseg= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fast_mi_readinfo(info))
|
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)))
|
if (!(nextflag & (SEARCH_FIND | SEARCH_NO_FIND | SEARCH_LAST)))
|
||||||
use_key_length=USE_WHOLE_KEY;
|
use_key_length=USE_WHOLE_KEY;
|
||||||
|
|
||||||
if (!_mi_search(info,info->s->keyinfo+inx,key_buff,use_key_length,
|
if (!_mi_search(info,keyinfo, key_buff, use_key_length,
|
||||||
myisam_read_vec[search_flag],info->s->state.key_root[inx]))
|
myisam_read_vec[search_flag], info->s->state.key_root[inx]))
|
||||||
{
|
{
|
||||||
while (info->lastpos >= info->state->data_file_length)
|
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
|
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,
|
info->lastkey_length,
|
||||||
myisam_readnext_vec[search_flag],
|
myisam_readnext_vec[search_flag],
|
||||||
info->s->state.key_root[inx]))
|
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)
|
if (share->concurrent_insert)
|
||||||
rw_unlock(&share->key_root_lock[inx]);
|
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)
|
if (!buf)
|
||||||
DBUG_RETURN(info->lastpos==HA_OFFSET_ERROR ? my_errno : 0);
|
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 */
|
/* Store key for read next */
|
||||||
memcpy(info->lastkey,key_buff,pack_key_length);
|
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);
|
bzero((char*) info->lastkey+pack_key_length,info->s->base.rec_reflength);
|
||||||
info->lastkey_length=pack_key_length+info->s->base.rec_reflength;
|
info->lastkey_length=pack_key_length+info->s->base.rec_reflength;
|
||||||
|
|
||||||
|
@ -1441,6 +1441,37 @@ uint _mi_keylength(MI_KEYDEF *keyinfo, register uchar *key)
|
|||||||
} /* _mi_keylength */
|
} /* _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 */
|
/* Move a key */
|
||||||
|
|
||||||
uchar *_mi_move_key(MI_KEYDEF *keyinfo, uchar *to, uchar *from)
|
uchar *_mi_move_key(MI_KEYDEF *keyinfo, uchar *to, uchar *from)
|
||||||
|
@ -639,14 +639,14 @@ int main(int argc, char *argv[])
|
|||||||
if ((long) range_records < (long) records*7/10-2 ||
|
if ((long) range_records < (long) records*7/10-2 ||
|
||||||
(long) range_records > (long) records*14/10+2)
|
(long) range_records > (long) records*14/10+2)
|
||||||
{
|
{
|
||||||
printf("mi_records_range for key: %d returned %ld; Should be about %ld\n",
|
printf("mi_records_range for key: %d returned %lu; Should be about %lu\n",
|
||||||
i, range_records, records);
|
i, (ulong) range_records, (ulong) records);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
if (verbose && records)
|
if (verbose && records)
|
||||||
{
|
{
|
||||||
printf("mi_records_range returned %ld; Exact is %ld (diff: %4.2g %%)\n",
|
printf("mi_records_range returned %lu; Exact is %lu (diff: %4.2g %%)\n",
|
||||||
range_records,records,
|
(ulong) range_records, (ulong) records,
|
||||||
labs((long) range_records-(long) records)*100.0/records);
|
labs((long) range_records-(long) records)*100.0/records);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -660,8 +660,8 @@ int main(int argc, char *argv[])
|
|||||||
|| info.keys != keys)
|
|| info.keys != keys)
|
||||||
{
|
{
|
||||||
puts("Wrong info from mi_info");
|
puts("Wrong info from mi_info");
|
||||||
printf("Got: records: %ld delete: %ld i_keys: %d\n",
|
printf("Got: records: %lu delete: %lu i_keys: %d\n",
|
||||||
info.records,info.deleted,info.keys);
|
(ulong) info.records, (ulong) info.deleted, info.keys);
|
||||||
}
|
}
|
||||||
if (verbose)
|
if (verbose)
|
||||||
{
|
{
|
||||||
|
@ -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,
|
extern uchar *_mi_get_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
|
||||||
uchar *key, uchar *keypos, uint *return_key_length);
|
uchar *key, uchar *keypos, uint *return_key_length);
|
||||||
extern uint _mi_keylength(MI_KEYDEF *keyinfo,uchar *key);
|
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 uchar *_mi_move_key(MI_KEYDEF *keyinfo,uchar *to,uchar *from);
|
||||||
extern int _mi_search_next(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *key,
|
extern int _mi_search_next(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *key,
|
||||||
uint key_length,uint nextflag,my_off_t pos);
|
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,
|
extern uint _mi_make_key(MI_INFO *info,uint keynr,uchar *key,
|
||||||
const byte *record,my_off_t filepos);
|
const byte *record,my_off_t filepos);
|
||||||
extern uint _mi_pack_key(MI_INFO *info,uint keynr,uchar *key,uchar *old,
|
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_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,
|
extern int _mi_read_cache(IO_CACHE *info,byte *buff,my_off_t pos,
|
||||||
uint length,int re_read_if_possibly);
|
uint length,int re_read_if_possibly);
|
||||||
|
@ -163,8 +163,8 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
|
|||||||
if (maxbuffer == 0)
|
if (maxbuffer == 0)
|
||||||
{
|
{
|
||||||
if (!no_messages)
|
if (!no_messages)
|
||||||
printf(" - Dumping %lu keys\n",records);
|
printf(" - Dumping %lu keys\n", (ulong) records);
|
||||||
if (write_index(info,sort_keys,(uint) records))
|
if (write_index(info,sort_keys, (uint) records))
|
||||||
goto err; /* purecov: inspected */
|
goto err; /* purecov: inspected */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -173,7 +173,7 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
|
|||||||
if (maxbuffer >= MERGEBUFF2)
|
if (maxbuffer >= MERGEBUFF2)
|
||||||
{
|
{
|
||||||
if (!no_messages)
|
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,
|
if (merge_many_buff(info,keys,sort_keys,
|
||||||
dynamic_element(&buffpek,0,BUFFPEK *),&maxbuffer,&tempfile))
|
dynamic_element(&buffpek,0,BUFFPEK *),&maxbuffer,&tempfile))
|
||||||
goto err; /* purecov: inspected */
|
goto err; /* purecov: inspected */
|
||||||
|
@ -212,3 +212,55 @@ select * from t1 where match a against ("te*" in boolean mode)+0;
|
|||||||
a
|
a
|
||||||
test
|
test
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1 (word varchar(255) not null, word2 varchar(255) not null, index(word));
|
||||||
|
insert into t1 (word) values ('ss'),(0xDF),(0xE4),('ae');
|
||||||
|
update t1 set word2=word;
|
||||||
|
select word, word=0xdf as t from t1 having t > 0;
|
||||||
|
word t
|
||||||
|
ß 1
|
||||||
|
select word, word=cast(0xdf AS CHAR) as t from t1 having t > 0;
|
||||||
|
word t
|
||||||
|
ss 1
|
||||||
|
ß 1
|
||||||
|
select * from t1 where word=0xDF;
|
||||||
|
word word2
|
||||||
|
ß ß
|
||||||
|
select * from t1 where word=CAST(0xDF as CHAR);
|
||||||
|
word word2
|
||||||
|
ss ss
|
||||||
|
ß ß
|
||||||
|
select * from t1 where word2=0xDF;
|
||||||
|
word word2
|
||||||
|
ß ß
|
||||||
|
select * from t1 where word2=CAST(0xDF as CHAR);
|
||||||
|
word word2
|
||||||
|
ss ss
|
||||||
|
ß ß
|
||||||
|
select * from t1 where word='ae';
|
||||||
|
word word2
|
||||||
|
ä ä
|
||||||
|
ae ae
|
||||||
|
select * from t1 where word= 0xe4 or word=CAST(0xe4 as CHAR);
|
||||||
|
word word2
|
||||||
|
ä ä
|
||||||
|
ae ae
|
||||||
|
select * from t1 where word between 0xDF and 0xDF;
|
||||||
|
word word2
|
||||||
|
ß ß
|
||||||
|
select * from t1 where word between CAST(0xDF AS CHAR) and CAST(0xDF AS CHAR);
|
||||||
|
word word2
|
||||||
|
ss ss
|
||||||
|
ß ß
|
||||||
|
select * from t1 where word like 'ae';
|
||||||
|
word word2
|
||||||
|
ae ae
|
||||||
|
select * from t1 where word like 'AE';
|
||||||
|
word word2
|
||||||
|
ae ae
|
||||||
|
select * from t1 where word like 0xDF;
|
||||||
|
word word2
|
||||||
|
ß ß
|
||||||
|
select * from t1 where word like CAST(0xDF as CHAR);
|
||||||
|
word word2
|
||||||
|
ß ß
|
||||||
|
drop table t1;
|
||||||
|
@ -273,8 +273,16 @@ cust 20
|
|||||||
SELECT emp.rate_code, lr.base_rate FROM t1 AS emp LEFT JOIN t2 AS lr USING (siteid, rate_code) WHERE lr.siteid = 'rivercats' AND emp.emp_id = 'psmith';
|
SELECT emp.rate_code, lr.base_rate FROM t1 AS emp LEFT JOIN t2 AS lr USING (siteid, rate_code) WHERE lr.siteid = 'rivercats' AND emp.emp_id = 'psmith';
|
||||||
rate_code base_rate
|
rate_code base_rate
|
||||||
cust 20
|
cust 20
|
||||||
|
drop table t1,t2;
|
||||||
|
CREATE TABLE t1 (ID INTEGER NOT NULL PRIMARY KEY, Value1 VARCHAR(255));
|
||||||
|
CREATE TABLE t2 (ID INTEGER NOT NULL PRIMARY KEY, Value2 VARCHAR(255));
|
||||||
|
INSERT INTO t1 VALUES (1, 'A');
|
||||||
|
INSERT INTO t2 VALUES (1, 'B');
|
||||||
|
SELECT * FROM t1 NATURAL JOIN t2 WHERE 1 AND (Value1 = 'A' AND Value2 <> 'B');
|
||||||
ID Value1 ID Value2
|
ID Value1 ID Value2
|
||||||
|
SELECT * FROM t1 NATURAL JOIN t2 WHERE 1 AND Value1 = 'A' AND Value2 <> 'B';
|
||||||
ID Value1 ID Value2
|
ID Value1 ID Value2
|
||||||
|
SELECT * FROM t1 NATURAL JOIN t2 WHERE (Value1 = 'A' AND Value2 <> 'B') AND 1;
|
||||||
ID Value1 ID Value2
|
ID Value1 ID Value2
|
||||||
drop table t1,t2;
|
drop table t1,t2;
|
||||||
create table t1 (i int);
|
create table t1 (i int);
|
||||||
|
@ -4,4 +4,8 @@ repair table t1 use_frm;
|
|||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
test.t1 repair warning Number of rows changed from 0 to 1
|
test.t1 repair warning Number of rows changed from 0 to 1
|
||||||
test.t1 repair status OK
|
test.t1 repair status OK
|
||||||
drop table if exists t1;
|
alter table t1 TYPE=HEAP;
|
||||||
|
repair table t1 use_frm;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 repair error The handler for the table doesn't support repair
|
||||||
|
drop table t1;
|
||||||
|
@ -4,18 +4,18 @@ reset master;
|
|||||||
reset slave;
|
reset slave;
|
||||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||||
slave start;
|
slave start;
|
||||||
drop database if exists d1;
|
drop database if exists test_$1;
|
||||||
create database d1;
|
create database test_$1;
|
||||||
create table d1.t1 ( n int);
|
create table test_$1.t1 ( n int);
|
||||||
alter table d1.t1 add m int;
|
alter table test_$1.t1 add m int;
|
||||||
insert into d1.t1 values (1,2);
|
insert into test_$1.t1 values (1,2);
|
||||||
create table d1.t2 (n int);
|
create table test_$1.t2 (n int);
|
||||||
insert into d1.t2 values (45);
|
insert into test_$1.t2 values (45);
|
||||||
rename table d1.t2 to d1.t3, d1.t1 to d1.t2;
|
rename table test_$1.t2 to test_$1.t3, test_$1.t1 to test_$1.t2;
|
||||||
select * from d1.t2;
|
select * from test_$1.t2;
|
||||||
n m
|
n m
|
||||||
1 2
|
1 2
|
||||||
select * from d1.t3;
|
select * from test_$1.t3;
|
||||||
n
|
n
|
||||||
45
|
45
|
||||||
drop database d1;
|
drop database test_$1;
|
||||||
|
@ -1 +1,2 @@
|
|||||||
--default-character-set=latin1_de
|
--default-character-set=latin1_de --new
|
||||||
|
|
||||||
|
@ -45,3 +45,26 @@ select * from t1 where a like "test%";
|
|||||||
select * from t1 where a like "te_t";
|
select * from t1 where a like "te_t";
|
||||||
select * from t1 where match a against ("te*" in boolean mode)+0;
|
select * from t1 where match a against ("te*" in boolean mode)+0;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test bug report #152 (problem with index on latin1_de)
|
||||||
|
#
|
||||||
|
|
||||||
|
create table t1 (word varchar(255) not null, word2 varchar(255) not null, index(word));
|
||||||
|
insert into t1 (word) values ('ss'),(0xDF),(0xE4),('ae');
|
||||||
|
update t1 set word2=word;
|
||||||
|
select word, word=0xdf as t from t1 having t > 0;
|
||||||
|
select word, word=cast(0xdf AS CHAR) as t from t1 having t > 0;
|
||||||
|
select * from t1 where word=0xDF;
|
||||||
|
select * from t1 where word=CAST(0xDF as CHAR);
|
||||||
|
select * from t1 where word2=0xDF;
|
||||||
|
select * from t1 where word2=CAST(0xDF as CHAR);
|
||||||
|
select * from t1 where word='ae';
|
||||||
|
select * from t1 where word= 0xe4 or word=CAST(0xe4 as CHAR);
|
||||||
|
select * from t1 where word between 0xDF and 0xDF;
|
||||||
|
select * from t1 where word between CAST(0xDF AS CHAR) and CAST(0xDF AS CHAR);
|
||||||
|
select * from t1 where word like 'ae';
|
||||||
|
select * from t1 where word like 'AE';
|
||||||
|
select * from t1 where word like 0xDF;
|
||||||
|
select * from t1 where word like CAST(0xDF as CHAR);
|
||||||
|
drop table t1;
|
||||||
|
@ -5,4 +5,6 @@
|
|||||||
drop table if exists t1;
|
drop table if exists t1;
|
||||||
create table t1 SELECT 1,"table 1";
|
create table t1 SELECT 1,"table 1";
|
||||||
repair table t1 use_frm;
|
repair table t1 use_frm;
|
||||||
drop table if exists t1;
|
alter table t1 TYPE=HEAP;
|
||||||
|
repair table t1 use_frm;
|
||||||
|
drop table t1;
|
||||||
|
25
sql/field.cc
25
sql/field.cc
@ -162,6 +162,14 @@ static bool test_if_real(const char *str,int length)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline uint field_length_without_space(const char *ptr, uint length)
|
||||||
|
{
|
||||||
|
const char *end= ptr+length;
|
||||||
|
while (end > ptr && end[-1] == ' ')
|
||||||
|
end--;
|
||||||
|
return (uint) (end-ptr);
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
** Functions for the base classes
|
** Functions for the base classes
|
||||||
** This is an unpacked number.
|
** This is an unpacked number.
|
||||||
@ -3673,8 +3681,21 @@ int Field_string::cmp(const char *a_ptr, const char *b_ptr)
|
|||||||
{
|
{
|
||||||
if (binary_flag)
|
if (binary_flag)
|
||||||
return memcmp(a_ptr,b_ptr,field_length);
|
return memcmp(a_ptr,b_ptr,field_length);
|
||||||
else
|
#ifdef USE_STRCOLL
|
||||||
return my_sortcmp(a_ptr,b_ptr,field_length);
|
if (use_strcoll(default_charset_info))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
We have to remove end space to be able to compare multi-byte-characters
|
||||||
|
like in latin_de 'ae' and 0xe4
|
||||||
|
*/
|
||||||
|
uint a_length= field_length_without_space(a_ptr, field_length);
|
||||||
|
uint b_length= field_length_without_space(b_ptr, field_length);
|
||||||
|
return my_strnncoll(default_charset_info,
|
||||||
|
(const uchar*) a_ptr, a_length,
|
||||||
|
(const uchar*) b_ptr, b_length);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return my_sortcmp(a_ptr,b_ptr,field_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Field_string::sort_string(char *to,uint length)
|
void Field_string::sort_string(char *to,uint length)
|
||||||
|
@ -576,6 +576,14 @@ inline uint char_val(char X)
|
|||||||
X-'a'+10);
|
X-'a'+10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* In MySQL 4.1 this will always return STRING_RESULT */
|
||||||
|
|
||||||
|
enum Item_result Item_varbinary::result_type () const
|
||||||
|
{
|
||||||
|
return (current_thd->variables.new_mode) ? STRING_RESULT : INT_RESULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Item_varbinary::Item_varbinary(const char *str, uint str_length)
|
Item_varbinary::Item_varbinary(const char *str, uint str_length)
|
||||||
{
|
{
|
||||||
name=(char*) str-2; // Lex makes this start with 0x
|
name=(char*) str-2; // Lex makes this start with 0x
|
||||||
|
@ -353,7 +353,7 @@ public:
|
|||||||
String *val_str(String*) { return &str_value; }
|
String *val_str(String*) { return &str_value; }
|
||||||
bool save_in_field(Field *field, bool no_conversions);
|
bool save_in_field(Field *field, bool no_conversions);
|
||||||
void make_field(Send_field *field);
|
void make_field(Send_field *field);
|
||||||
enum Item_result result_type () const { return INT_RESULT; }
|
enum Item_result result_type () const;
|
||||||
unsigned int size_of() { return sizeof(*this);}
|
unsigned int size_of() { return sizeof(*this);}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -204,12 +204,12 @@ static char **opt_argv;
|
|||||||
#ifdef __WIN__
|
#ifdef __WIN__
|
||||||
#undef MYSQL_SERVER_SUFFIX
|
#undef MYSQL_SERVER_SUFFIX
|
||||||
#ifdef __NT__
|
#ifdef __NT__
|
||||||
#if defined(HAVE_INNOBASE_DB) || defined(HAVE_BERKELEY_DB)
|
#if defined(HAVE_BERKELEY_DB)
|
||||||
#define MYSQL_SERVER_SUFFIX "-max-nt"
|
#define MYSQL_SERVER_SUFFIX "-max-nt"
|
||||||
#else
|
#else
|
||||||
#define MYSQL_SERVER_SUFFIX "-nt"
|
#define MYSQL_SERVER_SUFFIX "-nt"
|
||||||
#endif /* ...DB */
|
#endif /* ...DB */
|
||||||
#elif defined(HAVE_INNOBASE_DB) || defined(HAVE_BERKELEY_DB)
|
#elif defined(HAVE_BERKELEY_DB)
|
||||||
#define MYSQL_SERVER_SUFFIX "-max"
|
#define MYSQL_SERVER_SUFFIX "-max"
|
||||||
#else
|
#else
|
||||||
#define MYSQL_SERVER_SUFFIX ""
|
#define MYSQL_SERVER_SUFFIX ""
|
||||||
|
@ -284,7 +284,6 @@ void field_str::add()
|
|||||||
char buff[MAX_FIELD_WIDTH], *ptr;
|
char buff[MAX_FIELD_WIDTH], *ptr;
|
||||||
String s(buff, sizeof(buff)), *res;
|
String s(buff, sizeof(buff)), *res;
|
||||||
ulong length;
|
ulong length;
|
||||||
TREE_ELEMENT *element;
|
|
||||||
|
|
||||||
if (!(res = item->val_str(&s)))
|
if (!(res = item->val_str(&s)))
|
||||||
{
|
{
|
||||||
|
@ -1029,7 +1029,7 @@ extern "C" pthread_handler_decl(handle_delayed_insert,arg)
|
|||||||
#else
|
#else
|
||||||
error=pthread_cond_timedwait(&di->cond,&di->mutex,&abstime);
|
error=pthread_cond_timedwait(&di->cond,&di->mutex,&abstime);
|
||||||
#ifdef EXTRA_DEBUG
|
#ifdef EXTRA_DEBUG
|
||||||
if (error && error != EINTR)
|
if (error && error != EINTR && error != ETIMEDOUT)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Got error %d from pthread_cond_timedwait\n",error);
|
fprintf(stderr, "Got error %d from pthread_cond_timedwait\n",error);
|
||||||
DBUG_PRINT("error",("Got error %d from pthread_cond_timedwait",
|
DBUG_PRINT("error",("Got error %d from pthread_cond_timedwait",
|
||||||
|
@ -1042,6 +1042,9 @@ err:
|
|||||||
}
|
}
|
||||||
|
|
||||||
send_eof(&thd->net);
|
send_eof(&thd->net);
|
||||||
|
pthread_mutex_lock(&LOCK_thread_count);
|
||||||
|
thd->current_linfo = 0;
|
||||||
|
pthread_mutex_unlock(&LOCK_thread_count);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2631,6 +2631,9 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
|
|||||||
join->thd->select_limit)) < 0)
|
join->thd->select_limit)) < 0)
|
||||||
DBUG_RETURN(1); // Impossible range
|
DBUG_RETURN(1); // Impossible range
|
||||||
sel->cond=orig_cond;
|
sel->cond=orig_cond;
|
||||||
|
/* Fix for EXPLAIN */
|
||||||
|
if (sel->quick)
|
||||||
|
join->best_positions[i].records_read= sel->quick->records;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <hash.h>
|
#include <hash.h>
|
||||||
#include <myisam.h>
|
#include <myisam.h>
|
||||||
|
#include <my_dir.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#ifdef __WIN__
|
#ifdef __WIN__
|
||||||
@ -1046,12 +1047,31 @@ static int prepare_for_repair(THD* thd, TABLE_LIST* table,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
User gave us USE_FRM which means that the header in the index file is
|
||||||
|
trashed.
|
||||||
|
In this case we will try to fix the table the following way:
|
||||||
|
- Rename the data file to a temporary name
|
||||||
|
- Truncate the table
|
||||||
|
- Replace the new data file with the old one
|
||||||
|
- Run a normal repair using the new index file and the old data file
|
||||||
|
*/
|
||||||
|
|
||||||
char from[FN_REFLEN],tmp[FN_REFLEN];
|
char from[FN_REFLEN],tmp[FN_REFLEN+32];
|
||||||
char* db = thd->db ? thd->db : table->db;
|
const char **ext= table->table->file->bas_ext();
|
||||||
|
MY_STAT stat_info;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Check if this is a table type that stores index and data separately,
|
||||||
|
like ISAM or MyISAM
|
||||||
|
*/
|
||||||
|
if (!ext[0] || !ext[1])
|
||||||
|
DBUG_RETURN(0); // No data file
|
||||||
|
|
||||||
|
strxmov(from, table->table->path, ext[1], NullS); // Name of data file
|
||||||
|
if (!my_stat(from, &stat_info, MYF(0)))
|
||||||
|
DBUG_RETURN(0); // Can't use USE_FRM flag
|
||||||
|
|
||||||
sprintf(from, "%s/%s/%s", mysql_real_data_home, db, table->real_name);
|
|
||||||
fn_format(from, from, "", MI_NAME_DEXT, 4);
|
|
||||||
sprintf(tmp,"%s-%lx_%lx", from, current_pid, thd->thread_id);
|
sprintf(tmp,"%s-%lx_%lx", from, current_pid, thd->thread_id);
|
||||||
|
|
||||||
pthread_mutex_lock(&LOCK_open);
|
pthread_mutex_lock(&LOCK_open);
|
||||||
@ -1067,7 +1087,7 @@ static int prepare_for_repair(THD* thd, TABLE_LIST* table,
|
|||||||
unlock_table_name(thd, table);
|
unlock_table_name(thd, table);
|
||||||
pthread_mutex_unlock(&LOCK_open);
|
pthread_mutex_unlock(&LOCK_open);
|
||||||
DBUG_RETURN(send_check_errmsg(thd, table, "repair",
|
DBUG_RETURN(send_check_errmsg(thd, table, "repair",
|
||||||
"Failed renaming .MYD file"));
|
"Failed renaming data file"));
|
||||||
}
|
}
|
||||||
if (mysql_truncate(thd, table, 1))
|
if (mysql_truncate(thd, table, 1))
|
||||||
{
|
{
|
||||||
|
@ -2310,16 +2310,12 @@ olap_opt:
|
|||||||
| WITH CUBE_SYM
|
| WITH CUBE_SYM
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->olap = true;
|
|
||||||
lex->select->olap= CUBE_TYPE;
|
|
||||||
net_printf(&lex->thd->net, ER_NOT_SUPPORTED_YET, "CUBE");
|
net_printf(&lex->thd->net, ER_NOT_SUPPORTED_YET, "CUBE");
|
||||||
YYABORT; /* To be deleted in 4.1 */
|
YYABORT; /* To be deleted in 4.1 */
|
||||||
}
|
}
|
||||||
| WITH ROLLUP_SYM
|
| WITH ROLLUP_SYM
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->olap = true;
|
|
||||||
lex->select->olap= ROLLUP_TYPE;
|
|
||||||
net_printf(&lex->thd->net, ER_NOT_SUPPORTED_YET, "ROLLUP");
|
net_printf(&lex->thd->net, ER_NOT_SUPPORTED_YET, "ROLLUP");
|
||||||
YYABORT; /* To be deleted in 4.1 */
|
YYABORT; /* To be deleted in 4.1 */
|
||||||
}
|
}
|
||||||
@ -2407,7 +2403,7 @@ delete_limit_clause:
|
|||||||
|
|
||||||
ULONG_NUM:
|
ULONG_NUM:
|
||||||
NUM { $$= strtoul($1.str,NULL,10); }
|
NUM { $$= strtoul($1.str,NULL,10); }
|
||||||
| LONG_NUM { $$= (ulonglong) strtoll($1.str,NULL,10); }
|
| LONG_NUM { $$= (ulong) strtoll($1.str,NULL,10); }
|
||||||
| ULONGLONG_NUM { $$= (ulong) strtoull($1.str,NULL,10); }
|
| ULONGLONG_NUM { $$= (ulong) strtoull($1.str,NULL,10); }
|
||||||
| REAL_NUM { $$= strtoul($1.str,NULL,10); }
|
| REAL_NUM { $$= strtoul($1.str,NULL,10); }
|
||||||
| FLOAT_NUM { $$= strtoul($1.str,NULL,10); };
|
| FLOAT_NUM { $$= strtoul($1.str,NULL,10); };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user