Commit fbf6ab44 authored by monty@hundin.mysql.fi's avatar monty@hundin.mysql.fi

merge with 4.0.5

parents 26b1bbdb b1f99ce4
...@@ -51,6 +51,8 @@ Docs/manual.ky ...@@ -51,6 +51,8 @@ Docs/manual.ky
Docs/manual.log Docs/manual.log
Docs/manual.pdf Docs/manual.pdf
Docs/manual.pg Docs/manual.pg
Docs/manual.texi.orig
Docs/manual.texi.rej
Docs/manual.toc Docs/manual.toc
Docs/manual.tp Docs/manual.tp
Docs/manual.txt Docs/manual.txt
...@@ -247,6 +249,7 @@ libmysqld/field.cc ...@@ -247,6 +249,7 @@ libmysqld/field.cc
libmysqld/field_conv.cc libmysqld/field_conv.cc
libmysqld/filesort.cc libmysqld/filesort.cc
libmysqld/get_password.c libmysqld/get_password.c
libmysqld/gstream.cc
libmysqld/ha_berkeley.cc libmysqld/ha_berkeley.cc
libmysqld/ha_heap.cc libmysqld/ha_heap.cc
libmysqld/ha_innobase.cc libmysqld/ha_innobase.cc
...@@ -287,6 +290,7 @@ libmysqld/repl_failsafe.cc ...@@ -287,6 +290,7 @@ libmysqld/repl_failsafe.cc
libmysqld/set_var.cc libmysqld/set_var.cc
libmysqld/simple-test libmysqld/simple-test
libmysqld/slave.cc libmysqld/slave.cc
libmysqld/spatial.cc
libmysqld/sql_acl.cc libmysqld/sql_acl.cc
libmysqld/sql_analyse.cc libmysqld/sql_analyse.cc
libmysqld/sql_base.cc libmysqld/sql_base.cc
...@@ -356,6 +360,8 @@ myisam/myisam.log ...@@ -356,6 +360,8 @@ myisam/myisam.log
myisam/myisamchk myisam/myisamchk
myisam/myisamlog myisam/myisamlog
myisam/myisampack myisam/myisampack
myisam/rt_test
myisam/sp_test
myisam/test1.MYD myisam/test1.MYD
myisam/test1.MYI myisam/test1.MYI
myisam/test2.MYD myisam/test2.MYD
...@@ -382,6 +388,7 @@ mysql.proj ...@@ -382,6 +388,7 @@ mysql.proj
mysqld.S mysqld.S
mysqld.sym mysqld.sym
mysys/#mf_iocache.c# mysys/#mf_iocache.c#
mysys/charset2html
mysys/getopt.c mysys/getopt.c
mysys/getopt1.c mysys/getopt1.c
mysys/ste5KbMa mysys/ste5KbMa
...@@ -466,6 +473,7 @@ sql/share/norwegian/errmsg.sys ...@@ -466,6 +473,7 @@ sql/share/norwegian/errmsg.sys
sql/sql_select.cc.orig sql/sql_select.cc.orig
sql/sql_yacc.cc sql/sql_yacc.cc
sql/sql_yacc.h sql/sql_yacc.h
sql/sql_yacc.yy.orig
stamp-h stamp-h
stamp-h.in stamp-h.in
strings/conf_to_src strings/conf_to_src
...@@ -485,6 +493,7 @@ support-files/mysql-log-rotate ...@@ -485,6 +493,7 @@ support-files/mysql-log-rotate
support-files/mysql.server support-files/mysql.server
support-files/mysql.spec support-files/mysql.spec
tags tags
tests/client_test
tmp/* tmp/*
tools/my_vsnprintf.c tools/my_vsnprintf.c
tools/mysqlmanager tools/mysqlmanager
...@@ -494,3 +503,5 @@ vio/test-ssl ...@@ -494,3 +503,5 @@ vio/test-ssl
vio/test-sslclient vio/test-sslclient
vio/test-sslserver vio/test-sslserver
vio/viotest-ssl vio/viotest-ssl
sql_error.cc
sql_prepare.cc
...@@ -14,7 +14,8 @@ $make -k clean || true ...@@ -14,7 +14,8 @@ $make -k clean || true
/bin/rm -f */.deps/*.P config.cache innobase/config.cache bdb/build_unix/config.cache /bin/rm -f */.deps/*.P config.cache innobase/config.cache bdb/build_unix/config.cache
aclocal && autoheader && aclocal && automake && autoconf aclocal && autoheader && aclocal && automake && autoconf
(cd bdb/dist && sh s_all) # TODO: remove when DBD will be OK
#(cd bdb/dist && sh s_all)
(cd innobase && aclocal && autoheader && aclocal && automake && autoconf) (cd innobase && aclocal && autoheader && aclocal && automake && autoconf)
if [ -d gemini ] if [ -d gemini ]
then then
......
...@@ -6,8 +6,8 @@ path=`dirname $0` ...@@ -6,8 +6,8 @@ path=`dirname $0`
extra_flags="$pentium_cflags $debug_cflags" extra_flags="$pentium_cflags $debug_cflags"
c_warnings="$c_warnings $debug_extra_warnings" c_warnings="$c_warnings $debug_extra_warnings"
cxx_warnings="$cxx_warnings $debug_extra_warnings" cxx_warnings="$cxx_warnings $debug_extra_warnings"
extra_configs="$pentium_configs $debug_configs $static_link" extra_configs="$pentium_configs $debug_configs "
extra_configs="$extra_configs " extra_configs="$extra_configs"
. "$path/FINISH.sh" . "$path/FINISH.sh"
...@@ -4,6 +4,7 @@ Administrator@co3064164-a.rochd1.qld.optushome.com.au ...@@ -4,6 +4,7 @@ Administrator@co3064164-a.rochd1.qld.optushome.com.au
Administrator@fred. Administrator@fred.
Miguel@light.local Miguel@light.local
Sinisa@sinisa.nasamreza.org Sinisa@sinisa.nasamreza.org
WAX@sergbook.mysql.com
ahlentz@co3064164-a.rochd1.qld.optusnet.com.au ahlentz@co3064164-a.rochd1.qld.optusnet.com.au
akishkin@work.mysql.com akishkin@work.mysql.com
arjen@co3064164-a.bitbike.com arjen@co3064164-a.bitbike.com
...@@ -11,6 +12,7 @@ arjen@fred.bitbike.com ...@@ -11,6 +12,7 @@ arjen@fred.bitbike.com
arjen@george.bitbike.com arjen@george.bitbike.com
bar@bar.mysql.r18.ru bar@bar.mysql.r18.ru
bar@bar.udmsearch.izhnet.ru bar@bar.udmsearch.izhnet.ru
bar@gw.udmsearch.izhnet.ru
bell@sanja.is.com.ua bell@sanja.is.com.ua
davida@isil.mysql.com davida@isil.mysql.com
heikki@donna.mysql.fi heikki@donna.mysql.fi
...@@ -57,6 +59,8 @@ paul@teton.kitebird.com ...@@ -57,6 +59,8 @@ paul@teton.kitebird.com
pem@mysql.com pem@mysql.com
peter@linux.local peter@linux.local
peter@mysql.com peter@mysql.com
ram@gw.udmsearch.izhnet.ru
ram@mysql.r18.ru
ram@ram.(none) ram@ram.(none)
root@x3.internalnet root@x3.internalnet
salle@geopard.(none) salle@geopard.(none)
...@@ -80,6 +84,7 @@ tonu@hundin.mysql.fi ...@@ -80,6 +84,7 @@ tonu@hundin.mysql.fi
tonu@volk.internalnet tonu@volk.internalnet
tonu@x153.internalnet tonu@x153.internalnet
tonu@x3.internalnet tonu@x3.internalnet
venu@myvenu.com
venu@work.mysql.com venu@work.mysql.com
vva@genie.(none) vva@genie.(none)
walrus@mysql.com walrus@mysql.com
......
...@@ -25,10 +25,10 @@ then ...@@ -25,10 +25,10 @@ then
echo "Commit successful, notifying developers at $TO" echo "Commit successful, notifying developers at $TO"
( (
cat <<EOF cat <<EOF
List-ID: <bk.mysql-4.0> List-ID: <bk.mysql-4.1>
From: $FROM From: $FROM
To: $TO To: $TO
Subject: bk commit - 4.0 tree Subject: bk commit - 4.1 tree
EOF EOF
bk changes -v -r+ bk changes -v -r+
...@@ -41,13 +41,13 @@ EOF ...@@ -41,13 +41,13 @@ EOF
echo "Notifying internals list at $INTERNALS" echo "Notifying internals list at $INTERNALS"
( (
cat <<EOF cat <<EOF
List-ID: <bk.mysql-4.0> List-ID: <bk.mysql-4.1>
From: $FROM From: $FROM
To: $INTERNALS To: $INTERNALS
Subject: bk commit into 4.0 tree Subject: bk commit into 4.1 tree
Below is the list of changes that have just been committed into a local Below is the list of changes that have just been committed into a local
4.0 repository of $USER. When $USER does a push these changes will 4.1 repository of $USER. When $USER does a push these changes will
be propagated to the main repository and, within 24 hours after the be propagated to the main repository and, within 24 hours after the
push, to the public repository. push, to the public repository.
For information on how to access the public repository For information on how to access the public repository
...@@ -68,10 +68,10 @@ EOF ...@@ -68,10 +68,10 @@ EOF
echo "Notifying docs list at $DOCS" echo "Notifying docs list at $DOCS"
( (
cat <<EOF cat <<EOF
List-ID: <bk.mysql-4.0> List-ID: <bk.mysql-4.1>
From: $FROM From: $FROM
To: $DOCS To: $DOCS
Subject: bk commit - 4.0 tree (Manual) Subject: bk commit - 4.1 tree (Manual)
EOF EOF
bk changes -v -r+ bk changes -v -r+
......
...@@ -136,6 +136,10 @@ SOURCE="..\strings\ctype-latin1_de.c" ...@@ -136,6 +136,10 @@ SOURCE="..\strings\ctype-latin1_de.c"
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE="..\strings\ctype-simple.c"
# End Source File
# Begin Source File
SOURCE="..\strings\ctype-sjis.c" SOURCE="..\strings\ctype-sjis.c"
# End Source File # End Source File
# Begin Source File # Begin Source File
......
#!/bin/sh
#
# Change linefeed -> return+linefeed for all VC++ project files
#
find . \( -name "*.dsp" -o -name "*.dsw" \) -print | grep -v "SCCS" | xargs replace '\r\$' ' ' '\$' ' ' --
...@@ -147,6 +147,10 @@ SOURCE="..\strings\ctype-latin1_de.c" ...@@ -147,6 +147,10 @@ SOURCE="..\strings\ctype-latin1_de.c"
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE="..\strings\ctype-simple.c"
# End Source File
# Begin Source File
SOURCE="..\strings\ctype-sjis.c" SOURCE="..\strings\ctype-sjis.c"
# End Source File # End Source File
# Begin Source File # Begin Source File
...@@ -256,6 +260,7 @@ SOURCE=..\mysys\my_alloc.c ...@@ -256,6 +260,7 @@ SOURCE=..\mysys\my_alloc.c
# Begin Source File # Begin Source File
SOURCE=..\mysys\my_compress.c SOURCE=..\mysys\my_compress.c
# ADD CPP /I "../zlib"
# End Source File # End Source File
# Begin Source File # Begin Source File
......
...@@ -43,8 +43,7 @@ RSC=rc.exe ...@@ -43,8 +43,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBMYSQLD_EXPORTS" /YX /FD /c # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBMYSQLD_EXPORTS" /YX /FD /c
# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../regex" /I "../sql" /I "../bdb/build_win32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "USE_SYMDIR" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /D "EMBEDDED_LIBRARY" /D "HAVE_INNOBASE_DB" /D "DBUG_OFF" /D "USE_TLS" /D "__WIN__" /FR /FD /c # ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../regex" /I "../sql" /I "../bdb/build_win32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "USE_SYMDIR" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /D "EMBEDDED_LIBRARY" /D "HAVE_INNOBASE_DB" /D "DBUG_OFF" /D "USE_TLS" /D "__WIN__" /FR /FD /mktyplib203 /win32 # ADD BASE MTL /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x416 /d "NDEBUG" # ADD BASE RSC /l 0x416 /d "NDEBUG"
# ADD RSC /l 0x416 /d "NDEBUG" # ADD RSC /l 0x416 /d "NDEBUG"
...@@ -53,8 +52,7 @@ BSC32=bscmake.exe ...@@ -53,8 +52,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo # ADD BSC32 /nologo
LINK32=link.exe LINK32=link.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 /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 /dll /machine:I386
# ADD 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 Wsock32.lib ..\lib_release\myisam.lib ..\lib_release\myisammrg.lib ..\lib_release\mysys.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap.lib ..\lib_release\innodb.lib ..\lib_release\bdb.lib ..\lib_release\zlib.lib /nologo /dll /machine:I386 /out:"../lib_release/libmysqld.dll" /implib:"../lib_release/libmysqld.lib" # ADD 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 Wsock32.lib ..\lib_release\myisam.lib ..\lib_release\myisammrg.lib ..\lib_release\mysys.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap.lib ..\lib_release\innodb.lib ..\lib_release\bdb.lib ..\lib_release\zlib.lib # SUBTRACT LINK32 /nologo /dll /pdb:none /machine:I386 /out:"../lib_release/libmysqld.dll" /implib:"../lib_release/libmysqld.lib"
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "libmysqld - Win32 Debug" !ELSEIF "$(CFG)" == "libmysqld - Win32 Debug"
...@@ -70,8 +68,7 @@ LINK32=link.exe ...@@ -70,8 +68,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBMYSQLD_EXPORTS" /YX /FD /GZ /c # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBMYSQLD_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MT /W3 /Gm /Zi /Od /I "../include" /I "../sql" /I "../regex" /I "../bdb/build_win32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "HAVE_BERKELEY_DB" /D "USE_SYMDIR" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /D "EMBEDDED_LIBRARY" /D "HAVE_INNOBASE_DB" /D "USE_TLS" /D "__WIN__" /FD /GZ /c # ADD CPP /nologo /MT /W3 /Gm /Zi /Od /I "../include" /I "../sql" /I "../regex" /I "../bdb/build_win32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "HAVE_BERKELEY_DB" /D "USE_SYMDIR" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /D "EMBEDDED_LIBRARY" /D "HAVE_INNOBASE_DB" /D "USE_TLS" /D "__WIN__" /FD /GZ /mktyplib203 /win32 # ADD BASE MTL /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x416 /d "_DEBUG" # ADD BASE RSC /l 0x416 /d "_DEBUG"
# ADD RSC /l 0x416 /d "_DEBUG" # ADD RSC /l 0x416 /d "_DEBUG"
...@@ -80,8 +77,7 @@ BSC32=bscmake.exe ...@@ -80,8 +77,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo # ADD BSC32 /nologo
LINK32=link.exe LINK32=link.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 /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 /dll /debug /machine:I386 /pdbtype:sept
# ADD 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 Wsock32.lib ..\lib_debug\dbug.lib ..\lib_debug\mysys.lib ..\lib_debug\strings.lib ..\lib_debug\regex.lib ..\lib_debug\heap.lib ..\lib_debug\innodb.lib /nologo /dll /incremental:no /debug /machine:I386 /nodefaultlib:"LIBCMTD" /out:"../lib_debug/libmysqld.dll" /implib:"../lib_debug/libmysqld.lib" /pdbtype:sept # ADD 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 Wsock32.lib ..\lib_debug\dbug.lib ..\lib_debug\mysys.lib ..\lib_debug\strings.lib ..\lib_debug\regex.lib ..\lib_debug\heap.lib ..\lib_debug\innodb.lib # SUBTRACT LINK32 /nologo /dll /pdb:none /debug /machine:I386 /nodefaultlib:"LIBCMTD" /out:"../lib_debug/libmysqld.dll" /implib:"../lib_debug/libmysqld.lib"
# SUBTRACT LINK32 /pdb:none
!ENDIF !ENDIF
...@@ -119,6 +115,10 @@ SOURCE=..\libmysql\get_password.c ...@@ -119,6 +115,10 @@ SOURCE=..\libmysql\get_password.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\sql\gstream.cpp
# End Source File
# Begin Source File
SOURCE=..\sql\ha_berkeley.cpp SOURCE=..\sql\ha_berkeley.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
...@@ -176,6 +176,7 @@ SOURCE=..\sql\item_create.cpp ...@@ -176,6 +176,7 @@ SOURCE=..\sql\item_create.cpp
# Begin Source File # Begin Source File
SOURCE=..\sql\item_func.cpp SOURCE=..\sql\item_func.cpp
# ADD CPP /I "../zlib"
# End Source File # End Source File
# Begin Source File # Begin Source File
...@@ -183,6 +184,10 @@ SOURCE=..\sql\item_strfunc.cpp ...@@ -183,6 +184,10 @@ SOURCE=..\sql\item_strfunc.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\sql\item_subselect.cpp
# End Source File
# Begin Source File
SOURCE=..\sql\item_sum.cpp SOURCE=..\sql\item_sum.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
...@@ -271,7 +276,7 @@ SOURCE=..\sql\set_var.cpp ...@@ -271,7 +276,7 @@ SOURCE=..\sql\set_var.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\sql\slave.cpp SOURCE=..\sql\spatial.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
...@@ -307,10 +312,18 @@ SOURCE=..\sql\sql_delete.cpp ...@@ -307,10 +312,18 @@ SOURCE=..\sql\sql_delete.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\sql\sql_derived.cpp
# End Source File
# Begin Source File
SOURCE=..\sql\sql_do.cpp SOURCE=..\sql\sql_do.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\sql\sql_error.cpp
# End Source File
# Begin Source File
SOURCE=..\sql\sql_handler.cpp SOURCE=..\sql\sql_handler.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
...@@ -327,10 +340,6 @@ SOURCE=..\sql\sql_list.cpp ...@@ -327,10 +340,6 @@ SOURCE=..\sql\sql_list.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\sql\sql_load.cpp
# End Source File
# Begin Source File
SOURCE=..\sql\sql_manager.cpp SOURCE=..\sql\sql_manager.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
...@@ -340,6 +349,10 @@ SOURCE=..\sql\sql_map.cpp ...@@ -340,6 +349,10 @@ SOURCE=..\sql\sql_map.cpp
# Begin Source File # Begin Source File
SOURCE=..\sql\sql_parse.cpp SOURCE=..\sql\sql_parse.cpp
# End Source File
# Begin Source File
SOURCE=..\sql\sql_prepare.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
......
...@@ -265,8 +265,28 @@ SOURCE=.\mi_write.c ...@@ -265,8 +265,28 @@ SOURCE=.\mi_write.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\rt_index.c
# End Source File
# Begin Source File
SOURCE=.\rt_key.c
# End Source File
# Begin Source File
SOURCE=.\rt_mbr.c
# End Source File
# Begin Source File
SOURCE=.\rt_split.c
# End Source File
# Begin Source File
SOURCE=.\sort.c SOURCE=.\sort.c
# End Source File # End Source File
# Begin Source File
SOURCE=.\sp_key.c
# End Source File
# End Group # End Group
# Begin Group "Header Files" # Begin Group "Header Files"
...@@ -279,6 +299,10 @@ SOURCE=.\ft_eval.h ...@@ -279,6 +299,10 @@ SOURCE=.\ft_eval.h
SOURCE=.\myisamdef.h SOURCE=.\myisamdef.h
# End Source File # End Source File
# Begin Source File
SOURCE=.\rt_index.h
# End Source File
# End Group # End Group
# End Target # End Target
# End Project # End Project
...@@ -326,6 +326,10 @@ SOURCE=.\my_getwd.c ...@@ -326,6 +326,10 @@ SOURCE=.\my_getwd.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\my_handler.c
# End Source File
# Begin Source File
SOURCE=.\my_init.c SOURCE=.\my_init.c
# End Source File # End Source File
# Begin Source File # Begin Source File
......
...@@ -282,6 +282,10 @@ SOURCE=.\filesort.cpp ...@@ -282,6 +282,10 @@ SOURCE=.\filesort.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\gstream.cpp
# End Source File
# Begin Source File
SOURCE=.\ha_berkeley.cpp SOURCE=.\ha_berkeley.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
...@@ -460,17 +464,25 @@ SOURCE=.\item_func.cpp ...@@ -460,17 +464,25 @@ SOURCE=.\item_func.cpp
!IF "$(CFG)" == "mysqld - Win32 Release" !IF "$(CFG)" == "mysqld - Win32 Release"
# ADD CPP /I "../zlib"
!ELSEIF "$(CFG)" == "mysqld - Win32 Debug" !ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
# ADD CPP /G5 # ADD CPP /G5 /I "../zlib"
# SUBTRACT CPP /YX /Yc /Yu # SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "mysqld - Win32 nt" !ELSEIF "$(CFG)" == "mysqld - Win32 nt"
# ADD CPP /I "../zlib"
!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt" !ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
# ADD CPP /I "../zlib"
!ELSEIF "$(CFG)" == "mysqld - Win32 Max" !ELSEIF "$(CFG)" == "mysqld - Win32 Max"
# ADD CPP /I "../zlib"
!ENDIF !ENDIF
# End Source File # End Source File
...@@ -496,6 +508,10 @@ SOURCE=.\item_strfunc.cpp ...@@ -496,6 +508,10 @@ SOURCE=.\item_strfunc.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\item_subselect.cpp
# End Source File
# Begin Source File
SOURCE=.\item_sum.cpp SOURCE=.\item_sum.cpp
!IF "$(CFG)" == "mysqld - Win32 Release" !IF "$(CFG)" == "mysqld - Win32 Release"
...@@ -811,6 +827,10 @@ SOURCE=.\slave.cpp ...@@ -811,6 +827,10 @@ SOURCE=.\slave.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\spatial.cpp
# End Source File
# Begin Source File
SOURCE=.\sql_acl.cpp SOURCE=.\sql_acl.cpp
!IF "$(CFG)" == "mysqld - Win32 Release" !IF "$(CFG)" == "mysqld - Win32 Release"
...@@ -927,10 +947,18 @@ SOURCE=.\sql_delete.cpp ...@@ -927,10 +947,18 @@ SOURCE=.\sql_delete.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\sql_derived.cpp
# End Source File
# Begin Source File
SOURCE=.\sql_do.cpp SOURCE=.\sql_do.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\sql_error.cpp
# End Source File
# Begin Source File
SOURCE=.\sql_handler.cpp SOURCE=.\sql_handler.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
...@@ -1059,6 +1087,10 @@ SOURCE=.\sql_parse.cpp ...@@ -1059,6 +1087,10 @@ SOURCE=.\sql_parse.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\sql_prepare.cpp
# End Source File
# Begin Source File
SOURCE=.\sql_rename.cpp SOURCE=.\sql_rename.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
......
...@@ -128,6 +128,10 @@ SOURCE=".\ctype-latin1_de.c" ...@@ -128,6 +128,10 @@ SOURCE=".\ctype-latin1_de.c"
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=".\ctype-simple.c"
# End Source File
# Begin Source File
SOURCE=".\ctype-sjis.c" SOURCE=".\ctype-sjis.c"
# End Source File # End Source File
# Begin Source File # Begin Source File
......
...@@ -18,6 +18,9 @@ ...@@ -18,6 +18,9 @@
#undef CRAY_STACKSEG_END #undef CRAY_STACKSEG_END
/* Define the default charset name */
#undef DEFAULT_CHARSET_NAME
/* Version of .frm files */ /* Version of .frm files */
#undef DOT_FRM_VERSION #undef DOT_FRM_VERSION
...@@ -63,6 +66,43 @@ ...@@ -63,6 +66,43 @@
/* READLINE: */ /* READLINE: */
#undef HAVE_BSD_SIGNALS #undef HAVE_BSD_SIGNALS
/* Define charsets you want */
#undef HAVE_CHARSET_armscii8
#undef HAVE_CHARSET_big5
#undef HAVE_CHARSET_cp1251
#undef HAVE_CHARSET_cp1257
#undef HAVE_CHARSET_croat
#undef HAVE_CHARSET_czech
#undef HAVE_CHARSET_danish
#undef HAVE_CHARSET_dec8
#undef HAVE_CHARSET_dos
#undef HAVE_CHARSET_estonia
#undef HAVE_CHARSET_euc_kr
#undef HAVE_CHARSET_gb2312
#undef HAVE_CHARSET_gbk
#undef HAVE_CHARSET_german1
#undef HAVE_CHARSET_greek
#undef HAVE_CHARSET_hebrew
#undef HAVE_CHARSET_hp8
#undef HAVE_CHARSET_hungarian
#undef HAVE_CHARSET_koi8_ru
#undef HAVE_CHARSET_koi8_ukr
#undef HAVE_CHARSET_latin1
#undef HAVE_CHARSET_latin1_de
#undef HAVE_CHARSET_latin2
#undef HAVE_CHARSET_latin5
#undef HAVE_CHARSET_sjis
#undef HAVE_CHARSET_swe7
#undef HAVE_CHARSET_tis620
#undef HAVE_CHARSET_ucs2
#undef HAVE_CHARSET_ujis
#undef HAVE_CHARSET_usa7
#undef HAVE_CHARSET_utf8
#undef HAVE_CHARSET_win1250
#undef HAVE_CHARSET_win1250ch
#undef HAVE_CHARSET_win1251ukr
#undef HAVE_CHARSET_win1251
/* ZLIB and compress: */ /* ZLIB and compress: */
#undef HAVE_COMPRESS #undef HAVE_COMPRESS
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
#include <signal.h> #include <signal.h>
#include <violite.h> #include <violite.h>
const char *VER= "12.16"; const char *VER= "13.0";
/* Don't try to make a nice table if the data is too big */ /* Don't try to make a nice table if the data is too big */
#define MAX_COLUMN_LENGTH 1024 #define MAX_COLUMN_LENGTH 1024
...@@ -91,8 +91,8 @@ extern "C" { ...@@ -91,8 +91,8 @@ extern "C" {
#define vidattr(A) {} // Can't get this to work #define vidattr(A) {} // Can't get this to work
#endif #endif
#ifdef __WIN__ #ifdef FN_NO_CASE_SENCE
#define cmp_database(A,B) my_strcasecmp((A),(B)) #define cmp_database(A,B) my_strcasecmp(system_charset_info, (A), (B))
#else #else
#define cmp_database(A,B) strcmp((A),(B)) #define cmp_database(A,B) strcmp((A),(B))
#endif #endif
...@@ -346,6 +346,7 @@ int main(int argc,char *argv[]) ...@@ -346,6 +346,7 @@ int main(int argc,char *argv[])
if (!status.batch) if (!status.batch)
ignore_errors=1; // Don't abort monitor ignore_errors=1; // Don't abort monitor
signal(SIGINT, mysql_end); // Catch SIGINT to clean up signal(SIGINT, mysql_end); // Catch SIGINT to clean up
signal(SIGQUIT, mysql_end); // Catch SIGQUIT to clean up
/* /*
Run in interactive mode like the ingres/postgres monitor Run in interactive mode like the ingres/postgres monitor
...@@ -877,14 +878,14 @@ static COMMANDS *find_command (char *name,char cmd_char) ...@@ -877,14 +878,14 @@ static COMMANDS *find_command (char *name,char cmd_char)
} }
else else
{ {
while (isspace(*name)) while (my_isspace(system_charset_info,*name))
name++; name++;
if (strchr(name,';') || strstr(name,"\\g")) if (strchr(name,';') || strstr(name,"\\g"))
return ((COMMANDS *) 0); return ((COMMANDS *) 0);
if ((end=strcont(name," \t"))) if ((end=strcont(name," \t")))
{ {
len=(uint) (end - name); len=(uint) (end - name);
while (isspace(*end)) while (my_isspace(system_charset_info,*end))
end++; end++;
if (!*end) if (!*end)
end=0; // no arguments to function end=0; // no arguments to function
...@@ -896,7 +897,8 @@ static COMMANDS *find_command (char *name,char cmd_char) ...@@ -896,7 +897,8 @@ static COMMANDS *find_command (char *name,char cmd_char)
for (uint i= 0; commands[i].name; i++) for (uint i= 0; commands[i].name; i++)
{ {
if (commands[i].func && if (commands[i].func &&
((name && !my_casecmp(name,commands[i].name,len) && ((name &&
!my_strncasecmp(system_charset_info,name,commands[i].name,len) &&
!commands[i].name[len] && !commands[i].name[len] &&
(!end || (end && commands[i].takes_params))) || (!end || (end && commands[i].takes_params))) ||
!name && commands[i].cmd_char == cmd_char)) !name && commands[i].cmd_char == cmd_char))
...@@ -924,12 +926,13 @@ static bool add_line(String &buffer,char *line,char *in_string) ...@@ -924,12 +926,13 @@ static bool add_line(String &buffer,char *line,char *in_string)
for (pos=out=line ; (inchar= (uchar) *pos) ; pos++) for (pos=out=line ; (inchar= (uchar) *pos) ; pos++)
{ {
if (isspace(inchar) && out == line && buffer.is_empty()) if (my_isspace(system_charset_info,inchar) && out == line &&
buffer.is_empty())
continue; continue;
#ifdef USE_MB #ifdef USE_MB
int l; int l;
if (use_mb(default_charset_info) && if (use_mb(system_charset_info) &&
(l = my_ismbchar(default_charset_info, pos, strend))) { (l = my_ismbchar(system_charset_info, pos, strend))) {
while (l--) while (l--)
*out++ = *pos++; *out++ = *pos++;
pos--; pos--;
...@@ -992,7 +995,7 @@ static bool add_line(String &buffer,char *line,char *in_string) ...@@ -992,7 +995,7 @@ static bool add_line(String &buffer,char *line,char *in_string)
} }
else if (!*in_string && (inchar == '#' || else if (!*in_string && (inchar == '#' ||
inchar == '-' && pos[1] == '-' && inchar == '-' && pos[1] == '-' &&
isspace(pos[2]))) my_isspace(system_charset_info,pos[2])))
break; // comment to end of line break; // comment to end of line
else else
{ // Add found char to buffer { // Add found char to buffer
...@@ -1368,9 +1371,9 @@ com_clear(String *buffer,char *line __attribute__((unused))) ...@@ -1368,9 +1371,9 @@ com_clear(String *buffer,char *line __attribute__((unused)))
static int static int
com_go(String *buffer,char *line __attribute__((unused))) com_go(String *buffer,char *line __attribute__((unused)))
{ {
char buff[160],time_buff[32]; char buff[200], time_buff[32], *pos;
MYSQL_RES *result; MYSQL_RES *result;
ulong timer; ulong timer, warnings;
uint error=0; uint error=0;
if (!status.batch) if (!status.batch)
...@@ -1399,7 +1402,9 @@ com_go(String *buffer,char *line __attribute__((unused))) ...@@ -1399,7 +1402,9 @@ com_go(String *buffer,char *line __attribute__((unused)))
(void) com_print(buffer,0); (void) com_print(buffer,0);
if (skip_updates && if (skip_updates &&
(buffer->length() < 4 || my_sortcmp(buffer->ptr(),"SET ",4))) (buffer->length() < 4 || my_strnncoll(system_charset_info,
(const uchar*)buffer->ptr(),4,
(const uchar*)"SET ",4)))
{ {
(void) put_info("Ignoring query to other database",INFO_INFO); (void) put_info("Ignoring query to other database",INFO_INFO);
return 0; return 0;
...@@ -1452,7 +1457,7 @@ com_go(String *buffer,char *line __attribute__((unused))) ...@@ -1452,7 +1457,7 @@ com_go(String *buffer,char *line __attribute__((unused)))
{ {
if (!mysql_num_rows(result) && ! quick) if (!mysql_num_rows(result) && ! quick)
{ {
sprintf(buff,"Empty set%s",time_buff); strmov(buff, "Empty set");
} }
else else
{ {
...@@ -1467,20 +1472,30 @@ com_go(String *buffer,char *line __attribute__((unused))) ...@@ -1467,20 +1472,30 @@ com_go(String *buffer,char *line __attribute__((unused)))
print_tab_data(result); print_tab_data(result);
else else
print_table_data(result); print_table_data(result);
sprintf(buff,"%ld %s in set%s", sprintf(buff,"%ld %s in set",
(long) mysql_num_rows(result), (long) mysql_num_rows(result),
(long) mysql_num_rows(result) == 1 ? "row" : "rows", (long) mysql_num_rows(result) == 1 ? "row" : "rows");
time_buff);
end_pager(); end_pager();
} }
} }
else if (mysql_affected_rows(&mysql) == ~(ulonglong) 0) else if (mysql_affected_rows(&mysql) == ~(ulonglong) 0)
sprintf(buff,"Query OK%s",time_buff); strmov(buff,"Query OK");
else else
sprintf(buff,"Query OK, %ld %s affected%s", sprintf(buff,"Query OK, %ld %s affected",
(long) mysql_affected_rows(&mysql), (long) mysql_affected_rows(&mysql),
(long) mysql_affected_rows(&mysql) == 1 ? "row" : "rows", (long) mysql_affected_rows(&mysql) == 1 ? "row" : "rows");
time_buff);
pos=strend(buff);
if ((warnings= mysql_warning_count(&mysql)))
{
*pos++= ',';
*pos++= ' ';
pos=int2str(warnings, pos, 10);
pos=strmov(pos, " warning");
if (warnings != 1)
*pos++= 's';
}
strmov(pos, time_buff);
put_info(buff,INFO_RESULT); put_info(buff,INFO_RESULT);
if (mysql_info(&mysql)) if (mysql_info(&mysql))
put_info(mysql_info(&mysql),INFO_RESULT); put_info(mysql_info(&mysql),INFO_RESULT);
...@@ -1777,8 +1792,9 @@ safe_put_field(const char *pos,ulong length) ...@@ -1777,8 +1792,9 @@ safe_put_field(const char *pos,ulong length)
{ {
#ifdef USE_MB #ifdef USE_MB
int l; int l;
if (use_mb(default_charset_info) && if (use_mb(system_charset_info) &&
(l = my_ismbchar(default_charset_info, pos, end))) { (l = my_ismbchar(system_charset_info, pos, end)))
{
while (l--) while (l--)
tee_putc(*pos++, PAGER); tee_putc(*pos++, PAGER);
pos--; pos--;
...@@ -1838,7 +1854,7 @@ com_tee(String *buffer, char *line __attribute__((unused))) ...@@ -1838,7 +1854,7 @@ com_tee(String *buffer, char *line __attribute__((unused)))
if (status.batch) if (status.batch)
return 0; return 0;
while (isspace(*line)) while (my_isspace(system_charset_info,*line))
line++; line++;
if (!(param = strchr(line, ' '))) // if outfile wasn't given, use the default if (!(param = strchr(line, ' '))) // if outfile wasn't given, use the default
{ {
...@@ -1857,11 +1873,12 @@ com_tee(String *buffer, char *line __attribute__((unused))) ...@@ -1857,11 +1873,12 @@ com_tee(String *buffer, char *line __attribute__((unused)))
} }
/* eliminate the spaces before the parameters */ /* eliminate the spaces before the parameters */
while (isspace(*param)) while (my_isspace(system_charset_info,*param))
param++; param++;
end= strmake(file_name, param, sizeof(file_name) - 1); end= strmake(file_name, param, sizeof(file_name) - 1);
/* remove end space from command line */ /* remove end space from command line */
while (end > file_name && (isspace(end[-1]) || iscntrl(end[-1]))) while (end > file_name && (my_isspace(system_charset_info,end[-1]) ||
my_iscntrl(system_charset_info,end[-1])))
end--; end--;
end[0]= 0; end[0]= 0;
if (end == file_name) if (end == file_name)
...@@ -1901,7 +1918,7 @@ com_pager(String *buffer, char *line __attribute__((unused))) ...@@ -1901,7 +1918,7 @@ com_pager(String *buffer, char *line __attribute__((unused)))
if (status.batch) if (status.batch)
return 0; return 0;
/* Skip space from file name */ /* Skip space from file name */
while (isspace(*line)) while (my_isspace(system_charset_info,*line))
line++; line++;
if (!(param = strchr(line, ' '))) // if pager was not given, use the default if (!(param = strchr(line, ' '))) // if pager was not given, use the default
{ {
...@@ -1917,10 +1934,11 @@ com_pager(String *buffer, char *line __attribute__((unused))) ...@@ -1917,10 +1934,11 @@ com_pager(String *buffer, char *line __attribute__((unused)))
} }
else else
{ {
while (isspace(*param)) while (my_isspace(system_charset_info,*param))
param++; param++;
end=strmake(pager_name, param, sizeof(pager_name)-1); end=strmake(pager_name, param, sizeof(pager_name)-1);
while (end > pager_name && (isspace(end[-1]) || iscntrl(end[-1]))) while (end > pager_name && (my_isspace(system_charset_info,end[-1]) ||
my_iscntrl(system_charset_info,end[-1])))
end--; end--;
end[0]=0; end[0]=0;
strmov(pager, pager_name); strmov(pager, pager_name);
...@@ -2056,7 +2074,7 @@ com_connect(String *buffer, char *line) ...@@ -2056,7 +2074,7 @@ com_connect(String *buffer, char *line)
if (buffer) if (buffer)
{ {
while (isspace(*line)) while (my_isspace(system_charset_info,*line))
line++; line++;
strnmov(buff,line,sizeof(buff)-1); // Don't destroy history strnmov(buff,line,sizeof(buff)-1); // Don't destroy history
if (buff[0] == '\\') // Short command if (buff[0] == '\\') // Short command
...@@ -2102,15 +2120,16 @@ static int com_source(String *buffer, char *line) ...@@ -2102,15 +2120,16 @@ static int com_source(String *buffer, char *line)
FILE *sql_file; FILE *sql_file;
/* Skip space from file name */ /* Skip space from file name */
while (isspace(*line)) while (my_isspace(system_charset_info,*line))
line++; line++;
if (!(param = strchr(line, ' '))) // Skip command name if (!(param = strchr(line, ' '))) // Skip command name
return put_info("Usage: \\. <filename> | source <filename>", return put_info("Usage: \\. <filename> | source <filename>",
INFO_ERROR, 0); INFO_ERROR, 0);
while (isspace(*param)) while (my_isspace(system_charset_info,*param))
param++; param++;
end=strmake(source_name,param,sizeof(source_name)-1); end=strmake(source_name,param,sizeof(source_name)-1);
while (end > source_name && (isspace(end[-1]) || iscntrl(end[-1]))) while (end > source_name && (my_isspace(system_charset_info,end[-1]) ||
my_iscntrl(system_charset_info,end[-1])))
end--; end--;
end[0]=0; end[0]=0;
unpack_filename(source_name,source_name); unpack_filename(source_name,source_name);
...@@ -2151,7 +2170,7 @@ com_use(String *buffer __attribute__((unused)), char *line) ...@@ -2151,7 +2170,7 @@ com_use(String *buffer __attribute__((unused)), char *line)
char *tmp; char *tmp;
char buff[256]; char buff[256];
while (isspace(*line)) while (my_isspace(system_charset_info,*line))
line++; line++;
strnmov(buff,line,sizeof(buff)-1); // Don't destroy history strnmov(buff,line,sizeof(buff)-1); // Don't destroy history
if (buff[0] == '\\') // Short command if (buff[0] == '\\') // Short command
...@@ -2335,7 +2354,7 @@ com_status(String *buffer __attribute__((unused)), ...@@ -2335,7 +2354,7 @@ com_status(String *buffer __attribute__((unused)),
tee_fprintf(stdout, "Protocol version:\t%d\n", mysql_get_proto_info(&mysql)); tee_fprintf(stdout, "Protocol version:\t%d\n", mysql_get_proto_info(&mysql));
tee_fprintf(stdout, "Connection:\t\t%s\n", mysql_get_host_info(&mysql)); tee_fprintf(stdout, "Connection:\t\t%s\n", mysql_get_host_info(&mysql));
tee_fprintf(stdout, "Client characterset:\t%s\n", tee_fprintf(stdout, "Client characterset:\t%s\n",
default_charset_info->name); system_charset_info->name);
tee_fprintf(stdout, "Server characterset:\t%s\n", mysql.charset->name); tee_fprintf(stdout, "Server characterset:\t%s\n", mysql.charset->name);
if (strstr(mysql_get_host_info(&mysql),"TCP/IP") || ! mysql.unix_socket) if (strstr(mysql_get_host_info(&mysql),"TCP/IP") || ! mysql.unix_socket)
tee_fprintf(stdout, "TCP port:\t\t%d\n", mysql.port); tee_fprintf(stdout, "TCP port:\t\t%d\n", mysql.port);
...@@ -2444,7 +2463,7 @@ static void remove_cntrl(String &buffer) ...@@ -2444,7 +2463,7 @@ static void remove_cntrl(String &buffer)
{ {
char *start,*end; char *start,*end;
end=(start=(char*) buffer.ptr())+buffer.length(); end=(start=(char*) buffer.ptr())+buffer.length();
while (start < end && !isgraph(end[-1])) while (start < end && !my_isgraph(system_charset_info,end[-1]))
end--; end--;
buffer.length((uint) (end-start)); buffer.length((uint) (end-start));
} }
......
...@@ -518,7 +518,7 @@ static my_bool test_if_special_chars(const char *str) ...@@ -518,7 +518,7 @@ static my_bool test_if_special_chars(const char *str)
{ {
#if MYSQL_VERSION_ID >= 32300 #if MYSQL_VERSION_ID >= 32300
for ( ; *str ; str++) for ( ; *str ; str++)
if (!isvar(*str) && *str != '$') if (!my_isvar(system_charset_info,*str) && *str != '$')
return 1; return 1;
#endif #endif
return 0; return 0;
...@@ -1036,7 +1036,8 @@ static void dumpTable(uint numFields, char *table) ...@@ -1036,7 +1036,8 @@ static void dumpTable(uint numFields, char *table)
/* change any strings ("inf","nan",..) into NULL */ /* change any strings ("inf","nan",..) into NULL */
char *ptr = row[i]; char *ptr = row[i];
dynstr_append(&extended_row, dynstr_append(&extended_row,
(!isalpha(*ptr)) ? ptr : "NULL"); (!my_isalpha(system_charset_info,*ptr)) ?
ptr : "NULL");
} }
} }
else else
...@@ -1068,9 +1069,11 @@ static void dumpTable(uint numFields, char *table) ...@@ -1068,9 +1069,11 @@ static void dumpTable(uint numFields, char *table)
char *ptr = row[i]; char *ptr = row[i];
if (opt_xml) if (opt_xml)
fprintf(md_result_file, "\t\t<%s>%s</%s>\n", fprintf(md_result_file, "\t\t<%s>%s</%s>\n",
field->name,!isalpha(*ptr) ?ptr: "NULL",field->name); field->name,
!my_isalpha(system_charset_info,*ptr) ?ptr: "NULL",field->name);
else else
fputs((!isalpha(*ptr)) ? ptr : "NULL", md_result_file); fputs((!my_isalpha(system_charset_info,*ptr)) ?
ptr : "NULL", md_result_file);
} }
} }
else else
......
...@@ -311,7 +311,7 @@ static int eval_result = 0; ...@@ -311,7 +311,7 @@ static int eval_result = 0;
void mysql_enable_rpl_parse(MYSQL* mysql __attribute__((unused))) {} void mysql_enable_rpl_parse(MYSQL* mysql __attribute__((unused))) {}
void mysql_disable_rpl_parse(MYSQL* mysql __attribute__((unused))) {} void mysql_disable_rpl_parse(MYSQL* mysql __attribute__((unused))) {}
int mysql_rpl_parse_enabled(MYSQL* mysql __attribute__((unused))) { return 1; } int mysql_rpl_parse_enabled(MYSQL* mysql __attribute__((unused))) { return 1; }
int mysql_rpl_probe(MYSQL *mysql __attribute__((unused))) { return 1; } my_bool mysql_rpl_probe(MYSQL *mysql __attribute__((unused))) { return 1; }
#endif #endif
#define MAX_SERVER_ARGS 20 #define MAX_SERVER_ARGS 20
...@@ -482,9 +482,9 @@ void init_parser() ...@@ -482,9 +482,9 @@ void init_parser()
int hex_val(int c) int hex_val(int c)
{ {
if (isdigit(c)) if (my_isdigit(system_charset_info,c))
return c - '0'; return c - '0';
else if ((c = tolower(c)) >= 'a' && c <= 'f') else if ((c = my_tolower(system_charset_info,c)) >= 'a' && c <= 'f')
return c - 'a' + 10; return c - 'a' + 10;
else else
return -1; return -1;
...@@ -594,7 +594,7 @@ VAR* var_get(const char* var_name, const char** var_name_end, my_bool raw, ...@@ -594,7 +594,7 @@ VAR* var_get(const char* var_name, const char** var_name_end, my_bool raw,
{ {
const char* save_var_name = var_name, *end; const char* save_var_name = var_name, *end;
end = (var_name_end) ? *var_name_end : 0; end = (var_name_end) ? *var_name_end : 0;
while (isvar(*var_name) && var_name != end) while (my_isvar(system_charset_info,*var_name) && var_name != end)
++var_name; ++var_name;
if (var_name == save_var_name) if (var_name == save_var_name)
{ {
...@@ -757,7 +757,7 @@ int do_server_op(struct st_query* q,const char* op) ...@@ -757,7 +757,7 @@ int do_server_op(struct st_query* q,const char* op)
com_p=strmov(com_p,"_exec "); com_p=strmov(com_p,"_exec ");
if (!*p) if (!*p)
die("Missing server name in server_%s\n",op); die("Missing server name in server_%s\n",op);
while (*p && !isspace(*p)) while (*p && !my_isspace(system_charset_info,*p))
{ {
*com_p++=*p++; *com_p++=*p++;
} }
...@@ -790,7 +790,7 @@ int do_require_version(struct st_query* q) ...@@ -790,7 +790,7 @@ int do_require_version(struct st_query* q)
if (!*p) if (!*p)
die("Missing version argument in require_version\n"); die("Missing version argument in require_version\n");
ver_arg = p; ver_arg = p;
while (*p && !isspace(*p)) while (*p && !my_isspace(system_charset_info,*p))
p++; p++;
*p = 0; *p = 0;
ver_arg_len = p - ver_arg; ver_arg_len = p - ver_arg;
...@@ -820,7 +820,7 @@ int do_source(struct st_query* q) ...@@ -820,7 +820,7 @@ int do_source(struct st_query* q)
if (!*p) if (!*p)
die("Missing file name in source\n"); die("Missing file name in source\n");
name = p; name = p;
while (*p && !isspace(*p)) while (*p && !my_isspace(system_charset_info,*p))
p++; p++;
*p = 0; *p = 0;
...@@ -1057,11 +1057,11 @@ int do_let(struct st_query* q) ...@@ -1057,11 +1057,11 @@ int do_let(struct st_query* q)
if (!*p) if (!*p)
die("Missing variable name in let\n"); die("Missing variable name in let\n");
var_name = p; var_name = p;
while (*p && (*p != '=' || isspace(*p))) while (*p && (*p != '=' || my_isspace(system_charset_info,*p)))
p++; p++;
var_name_end = p; var_name_end = p;
if (*p == '=') p++; if (*p == '=') p++;
while (*p && isspace(*p)) while (*p && my_isspace(system_charset_info,*p))
p++; p++;
var_val_start = p; var_val_start = p;
return var_set(var_name, var_name_end, var_val_start, q->end); return var_set(var_name, var_name_end, var_val_start, q->end);
...@@ -1090,8 +1090,8 @@ int do_disable_rpl_parse(struct st_query* q __attribute__((unused))) ...@@ -1090,8 +1090,8 @@ int do_disable_rpl_parse(struct st_query* q __attribute__((unused)))
int do_sleep(struct st_query* q, my_bool real_sleep) int do_sleep(struct st_query* q, my_bool real_sleep)
{ {
char* p=q->first_argument; char *p=q->first_argument;
while (*p && isspace(*p)) while (*p && my_isspace(system_charset_info,*p))
p++; p++;
if (!*p) if (!*p)
die("Missing argument in sleep\n"); die("Missing argument in sleep\n");
...@@ -1107,7 +1107,7 @@ static void get_file_name(char *filename, struct st_query* q) ...@@ -1107,7 +1107,7 @@ static void get_file_name(char *filename, struct st_query* q)
char* p=q->first_argument; char* p=q->first_argument;
strnmov(filename, p, FN_REFLEN); strnmov(filename, p, FN_REFLEN);
/* Remove end space */ /* Remove end space */
while (p > filename && isspace(p[-1])) while (p > filename && my_isspace(system_charset_info,p[-1]))
p--; p--;
p[0]=0; p[0]=0;
} }
...@@ -1193,7 +1193,7 @@ static char *get_string(char **to_ptr, char **from_ptr, ...@@ -1193,7 +1193,7 @@ static char *get_string(char **to_ptr, char **from_ptr,
if (*from != ' ' && *from) if (*from != ' ' && *from)
die("Wrong string argument in %s\n", q->query); die("Wrong string argument in %s\n", q->query);
while (isspace(*from)) /* Point to next string */ while (my_isspace(system_charset_info,*from)) /* Point to next string */
from++; from++;
*to =0; /* End of string marker */ *to =0; /* End of string marker */
...@@ -1250,8 +1250,8 @@ static void get_replace(struct st_query *q) ...@@ -1250,8 +1250,8 @@ static void get_replace(struct st_query *q)
insert_pointer_name(&to_array,to); insert_pointer_name(&to_array,to);
} }
for (i=1,pos=word_end_chars ; i < 256 ; i++) for (i=1,pos=word_end_chars ; i < 256 ; i++)
if (isspace(i)) if (my_isspace(system_charset_info,i))
*pos++=i; *pos++= i;
*pos=0; /* End pointer */ *pos=0; /* End pointer */
if (!(glob_replace=init_replace((char**) from_array.typelib.type_names, if (!(glob_replace=init_replace((char**) from_array.typelib.type_names,
(char**) to_array.typelib.type_names, (char**) to_array.typelib.type_names,
...@@ -1287,7 +1287,7 @@ int select_connection(char *p) ...@@ -1287,7 +1287,7 @@ int select_connection(char *p)
if (!*p) if (!*p)
die("Missing connection name in connect\n"); die("Missing connection name in connect\n");
name = p; name = p;
while (*p && !isspace(*p)) while (*p && !my_isspace(system_charset_info,*p))
p++; p++;
*p = 0; *p = 0;
...@@ -1313,7 +1313,7 @@ int close_connection(struct st_query* q) ...@@ -1313,7 +1313,7 @@ int close_connection(struct st_query* q)
if (!*p) if (!*p)
die("Missing connection name in connect\n"); die("Missing connection name in connect\n");
name = p; name = p;
while (*p && !isspace(*p)) while (*p && !my_isspace(system_charset_info,*p))
p++; p++;
*p = 0; *p = 0;
...@@ -1349,11 +1349,13 @@ int close_connection(struct st_query* q) ...@@ -1349,11 +1349,13 @@ int close_connection(struct st_query* q)
char* safe_get_param(char* str, char** arg, const char* msg) char* safe_get_param(char* str, char** arg, const char* msg)
{ {
DBUG_ENTER("safe_get_param"); DBUG_ENTER("safe_get_param");
while (*str && isspace(*str)) str++; while (*str && my_isspace(system_charset_info,*str))
str++;
*arg = str; *arg = str;
for (; *str && *str != ',' && *str != ')' ; str++) for (; *str && *str != ',' && *str != ')' ; str++)
{ {
if (isspace(*str)) *str = 0; if (my_isspace(system_charset_info,*str))
*str = 0;
} }
if (!*str) if (!*str)
die(msg); die(msg);
...@@ -1635,7 +1637,7 @@ int read_line(char* buf, int size) ...@@ -1635,7 +1637,7 @@ int read_line(char* buf, int size)
{ {
state = R_COMMENT; state = R_COMMENT;
} }
else if (isspace(c)) else if (my_isspace(system_charset_info,c))
{ {
if (c == '\n') if (c == '\n')
start_lineno= ++*lineno; /* Query hasn't started yet */ start_lineno= ++*lineno; /* Query hasn't started yet */
...@@ -1761,7 +1763,7 @@ int read_query(struct st_query** q_ptr) ...@@ -1761,7 +1763,7 @@ int read_query(struct st_query** q_ptr)
{ {
expected_errno = 0; expected_errno = 0;
p++; p++;
for (;isdigit(*p);p++) for (;my_isdigit(system_charset_info,*p);p++)
expected_errno = expected_errno * 10 + *p - '0'; expected_errno = expected_errno * 10 + *p - '0';
q->expected_errno[0] = expected_errno; q->expected_errno[0] = expected_errno;
q->expected_errno[1] = 0; q->expected_errno[1] = 0;
...@@ -1769,25 +1771,28 @@ int read_query(struct st_query** q_ptr) ...@@ -1769,25 +1771,28 @@ int read_query(struct st_query** q_ptr)
} }
} }
while (*p && isspace(*p)) p++ ; while (*p && my_isspace(system_charset_info,*p))
p++ ;
if (*p == '@') if (*p == '@')
{ {
p++; p++;
p1 = q->record_file; p1 = q->record_file;
while (!isspace(*p) && while (!my_isspace(system_charset_info,*p) &&
p1 < q->record_file + sizeof(q->record_file) - 1) p1 < q->record_file + sizeof(q->record_file) - 1)
*p1++ = *p++; *p1++ = *p++;
*p1 = 0; *p1 = 0;
} }
} }
while (*p && isspace(*p)) p++; while (*p && my_isspace(system_charset_info,*p))
p++;
if (!(q->query_buf=q->query=my_strdup(p,MYF(MY_WME)))) if (!(q->query_buf=q->query=my_strdup(p,MYF(MY_WME))))
die(NullS); die(NullS);
/* Calculate first word and first argument */ /* Calculate first word and first argument */
for (p=q->query; *p && !isspace(*p) ; p++) ; for (p=q->query; *p && !my_isspace(system_charset_info,*p) ; p++) ;
q->first_word_len = (uint) (p - q->query); q->first_word_len = (uint) (p - q->query);
while (*p && isspace(*p)) p++; while (*p && my_isspace(system_charset_info,*p))
p++;
q->first_argument=p; q->first_argument=p;
q->end = strend(q->query); q->end = strend(q->query);
parser.read_lines++; parser.read_lines++;
...@@ -2028,6 +2033,36 @@ static void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val, ...@@ -2028,6 +2033,36 @@ static void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val,
dynstr_append_mem(ds, val, len); dynstr_append_mem(ds, val, len);
} }
/*
Append all results to the dynamic string separated with '\t'
*/
static void append_result(DYNAMIC_STRING *ds, MYSQL_RES *res)
{
MYSQL_ROW row;
int num_fields= mysql_num_fields(res);
unsigned long *lengths;
while ((row = mysql_fetch_row(res)))
{
int i;
lengths = mysql_fetch_lengths(res);
for (i = 0; i < num_fields; i++)
{
const char *val= row[i];
ulonglong len= lengths[i];
if (!val)
{
val = "NULL";
len = 4;
}
if (i)
dynstr_append_mem(ds, "\t", 1);
replace_dynstr_append_mem(ds, val, len);
}
dynstr_append_mem(ds, "\n", 1);
}
}
/* /*
* flags control the phased/stages of query execution to be performed * flags control the phased/stages of query execution to be performed
...@@ -2038,12 +2073,7 @@ static void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val, ...@@ -2038,12 +2073,7 @@ static void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val,
int run_query(MYSQL* mysql, struct st_query* q, int flags) int run_query(MYSQL* mysql, struct st_query* q, int flags)
{ {
MYSQL_RES* res = 0; MYSQL_RES* res = 0;
MYSQL_FIELD* fields; int i, error = 0;
MYSQL_ROW row;
int num_fields,i, error = 0;
unsigned long* lengths;
char* val;
int len;
DYNAMIC_STRING *ds; DYNAMIC_STRING *ds;
DYNAMIC_STRING ds_tmp; DYNAMIC_STRING ds_tmp;
DYNAMIC_STRING eval_query; DYNAMIC_STRING eval_query;
...@@ -2152,45 +2182,37 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags) ...@@ -2152,45 +2182,37 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags)
goto end; goto end;
} }
if (!res) if (!disable_result_log && res)
goto end;
if (!disable_result_log)
{ {
fields = mysql_fetch_fields(res); int num_fields= mysql_num_fields(res);
num_fields = mysql_num_fields(res); MYSQL_FIELD *fields= mysql_fetch_fields(res);
for (i = 0; i < num_fields; i++) for (i = 0; i < num_fields; i++)
{ {
if (i) if (i)
dynstr_append_mem(ds, "\t", 1); dynstr_append_mem(ds, "\t", 1);
dynstr_append(ds, fields[i].name); dynstr_append(ds, fields[i].name);
} }
dynstr_append_mem(ds, "\n", 1); dynstr_append_mem(ds, "\n", 1);
append_result(ds, res);
}
while ((row = mysql_fetch_row(res))) /* Add all warnings to the result */
if (!disable_result_log && mysql_warning_count(mysql))
{
MYSQL_RES *warn_res= mysql_warnings(mysql);
if (!warn_res)
verbose_msg("Warning count is %d but didn't get any warnings\n",
mysql_warning_count(mysql));
else
{ {
lengths = mysql_fetch_lengths(res); dynstr_append_mem(ds, "Warnings:\n", 10);
for (i = 0; i < num_fields; i++) append_result(ds, warn_res);
{ mysql_free_result(warn_res);
val = (char*)row[i];
len = lengths[i];
if (!val)
{
val = (char*)"NULL";
len = 4;
}
if (i)
dynstr_append_mem(ds, "\t", 1);
replace_dynstr_append_mem(ds, val, len);
}
dynstr_append_mem(ds, "\n", 1);
} }
if (glob_replace)
free_replace();
} }
if (glob_replace)
free_replace();
if (record) if (record)
{ {
if (!q->record_file[0] && !result_file) if (!q->record_file[0] && !result_file)
...@@ -2301,7 +2323,8 @@ static void var_from_env(const char* name, const char* def_val) ...@@ -2301,7 +2323,8 @@ static void var_from_env(const char* name, const char* def_val)
static void init_var_hash() static void init_var_hash()
{ {
VAR* v; VAR* v;
if (hash_init(&var_hash, 1024, 0, 0, get_var_key, var_free, MYF(0))) if (hash_init(&var_hash, system_charset_info,
1024, 0, 0, get_var_key, var_free, MYF(0)))
die("Variable hash initialization failed"); die("Variable hash initialization failed");
var_from_env("MASTER_MYPORT", "9306"); var_from_env("MASTER_MYPORT", "9306");
var_from_env("SLAVE_MYPORT", "9307"); var_from_env("SLAVE_MYPORT", "9307");
......
This diff is collapsed.
...@@ -24,31 +24,57 @@ ...@@ -24,31 +24,57 @@
#define NOT_FIXED_DEC 31 #define NOT_FIXED_DEC 31
#endif #endif
class String;
int sortcmp(const String *a,const String *b);
int stringcmp(const String *a,const String *b);
String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
int wild_case_compare(String &match,String &wild,char escape);
int wild_compare(String &match,String &wild,char escape);
class String class String
{ {
char *Ptr; char *Ptr;
uint32 str_length,Alloced_length; uint32 str_length,Alloced_length;
bool alloced; bool alloced;
CHARSET_INFO *str_charset;
public: public:
String() String()
{ Ptr=0; str_length=Alloced_length=0; alloced=0; } {
Ptr=0; str_length=Alloced_length=0; alloced=0;
str_charset=default_charset_info;
}
String(uint32 length_arg) String(uint32 length_arg)
{ alloced=0; Alloced_length=0; (void) real_alloc(length_arg); } {
alloced=0; Alloced_length=0; (void) real_alloc(length_arg);
str_charset=default_charset_info;
}
String(const char *str) String(const char *str)
{ Ptr=(char*) str; str_length=(uint) strlen(str); Alloced_length=0; alloced=0;} {
Ptr=(char*) str; str_length=(uint) strlen(str); Alloced_length=0; alloced=0;
str_charset=default_charset_info;
}
String(const char *str,uint32 len) String(const char *str,uint32 len)
{ Ptr=(char*) str; str_length=len; Alloced_length=0; alloced=0;} {
Ptr=(char*) str; str_length=len; Alloced_length=0; alloced=0;
str_charset=default_charset_info;
}
String(char *str,uint32 len) String(char *str,uint32 len)
{ Ptr=(char*) str; Alloced_length=str_length=len; alloced=0;} {
Ptr=(char*) str; Alloced_length=str_length=len; alloced=0;
str_charset=default_charset_info;
}
String(const String &str) String(const String &str)
{ Ptr=str.Ptr ; str_length=str.str_length ; {
Alloced_length=str.Alloced_length; alloced=0; } Ptr=str.Ptr ; str_length=str.str_length ;
Alloced_length=str.Alloced_length; alloced=0;
str_charset=str.str_charset;
}
static void *operator new(size_t size) { return (void*) sql_alloc((uint) size); } static void *operator new(size_t size) { return (void*) sql_alloc((uint) size); }
static void operator delete(void *ptr_arg,size_t size) /*lint -e715 */ static void operator delete(void *ptr_arg,size_t size) /*lint -e715 */
{ sql_element_free(ptr_arg); } { sql_element_free(ptr_arg); }
~String() { free(); } ~String() { free(); }
inline CHARSET_INFO *charset() const { return str_charset; }
inline uint32 length() const { return str_length;} inline uint32 length() const { return str_length;}
inline uint32 alloced_length() const { return Alloced_length;} inline uint32 alloced_length() const { return Alloced_length;}
inline char& operator [] (uint32 i) const { return Ptr[i]; } inline char& operator [] (uint32 i) const { return Ptr[i]; }
...@@ -124,7 +150,7 @@ class String ...@@ -124,7 +150,7 @@ class String
char *new_ptr; char *new_ptr;
if (!(new_ptr=(char*) my_realloc(Ptr,arg_length,MYF(0)))) if (!(new_ptr=(char*) my_realloc(Ptr,arg_length,MYF(0))))
{ {
(void) my_free(Ptr,MYF(0)); Alloced_length = 0;
real_alloc(arg_length); real_alloc(arg_length);
} }
else else
...@@ -153,6 +179,7 @@ class String ...@@ -153,6 +179,7 @@ class String
bool append(const char *s,uint32 arg_length=0); bool append(const char *s,uint32 arg_length=0);
bool append(IO_CACHE* file, uint32 arg_length); bool append(IO_CACHE* file, uint32 arg_length);
int strstr(const String &search,uint32 offset=0); // Returns offset to substring or -1 int strstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
int strstr_case(const String &s,uint32 offset=0);
int strrstr(const String &search,uint32 offset=0); // Returns offset to substring or -1 int strrstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
bool replace(uint32 offset,uint32 arg_length,const String &to); bool replace(uint32 offset,uint32 arg_length,const String &to);
inline bool append(char chr) inline bool append(char chr)
...@@ -171,8 +198,8 @@ class String ...@@ -171,8 +198,8 @@ class String
} }
bool fill(uint32 max_length,char fill); bool fill(uint32 max_length,char fill);
void strip_sp(); void strip_sp();
inline void caseup() { ::caseup(Ptr,str_length); } inline void caseup() { my_caseup(str_charset,Ptr,str_length); }
inline void casedn() { ::casedn(Ptr,str_length); } inline void casedn() { my_casedn(str_charset,Ptr,str_length); }
friend int sortcmp(const String *a,const String *b); friend int sortcmp(const String *a,const String *b);
friend int stringcmp(const String *a,const String *b); friend int stringcmp(const String *a,const String *b);
friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length); friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
...@@ -180,4 +207,49 @@ class String ...@@ -180,4 +207,49 @@ class String
friend int wild_compare(String &match,String &wild,char escape); friend int wild_compare(String &match,String &wild,char escape);
uint32 numchars(); uint32 numchars();
int charpos(int i,uint32 offset=0); int charpos(int i,uint32 offset=0);
// added by Holyfoot for "geometry" needs
int reserve(uint32 space_needed)
{
return realloc(str_length + space_needed);
}
int reserve(uint32 space_needed, uint32 grow_by);
// these append operations do NOT check alloced memory
// q_*** methods writes values of parameters itself
// qs_*** methods writes string representation of value
void q_append(const char &c)
{
Ptr[str_length++] = c;
}
void q_append(const uint32 &n)
{
int4store(Ptr + str_length, n);
str_length += 4;
}
void q_append(double d)
{
float8store(Ptr + str_length, d);
str_length += 8;
}
void q_append(double *d)
{
float8store(Ptr + str_length, *d);
str_length += 8;
}
void q_append(const char *data, uint32 data_len)
{
memcpy(Ptr + str_length, data, data_len);
str_length += data_len;
}
void WriteAtPosition(int position, uint32 value)
{
int4store(Ptr + position,value);
}
void qs_append(const char *str);
void qs_append(double d);
void qs_append(double *d);
void qs_append(const char &c);
}; };
This diff is collapsed.
...@@ -157,7 +157,7 @@ static int get_answer(QUESTION_WIDGET* w) ...@@ -157,7 +157,7 @@ static int get_answer(QUESTION_WIDGET* w)
char c; char c;
if (!fgets(buf,sizeof(buf),w->in)) if (!fgets(buf,sizeof(buf),w->in))
die("Failed fgets on input stream"); die("Failed fgets on input stream");
switch ((c=tolower(*buf))) switch ((c=my_tolower(system_charset_info,*buf)))
{ {
case '\n': case '\n':
return w->default_ind; return w->default_ind;
......
...@@ -113,7 +113,7 @@ char *argv[]; ...@@ -113,7 +113,7 @@ char *argv[];
exit(1); exit(1);
for (i=1,pos=word_end_chars ; i < 256 ; i++) for (i=1,pos=word_end_chars ; i < 256 ; i++)
if (isspace(i)) if (my_isspace(system_charset_info,i))
*pos++=i; *pos++=i;
*pos=0; *pos=0;
if (!(replace=init_replace((char**) from.typelib.type_names, if (!(replace=init_replace((char**) from.typelib.type_names,
......
...@@ -175,9 +175,9 @@ trace dump and specify the path to it with -s or --symbols-file"); ...@@ -175,9 +175,9 @@ trace dump and specify the path to it with -s or --symbols-file");
static uchar hex_val(char c) static uchar hex_val(char c)
{ {
uchar l; uchar l;
if (isdigit(c)) if (my_isdigit(system_charset_info,c))
return c - '0'; return c - '0';
l = tolower(c); l = my_tolower(system_charset_info,c);
if (l < 'a' || l > 'f') if (l < 'a' || l > 'f')
return HEX_INVALID; return HEX_INVALID;
return (uchar)10 + ((uchar)c - (uchar)'a'); return (uchar)10 + ((uchar)c - (uchar)'a');
...@@ -203,9 +203,11 @@ static int init_sym_entry(SYM_ENTRY* se, char* buf) ...@@ -203,9 +203,11 @@ static int init_sym_entry(SYM_ENTRY* se, char* buf)
if (!se->addr) if (!se->addr)
return -1; return -1;
while (isspace(*buf++)) ; while (my_isspace(system_charset_info,*buf++))
/* empty */;
while (isspace(*buf++)) ; /* skip more space */ while (my_isspace(system_charset_info,*buf++))
/* empty - skip more space */;
--buf; --buf;
/* now we are on the symbol */ /* now we are on the symbol */
for (p = se->symbol, p_end = se->symbol + sizeof(se->symbol) - 1; for (p = se->symbol, p_end = se->symbol + sizeof(se->symbol) - 1;
...@@ -285,7 +287,8 @@ static void do_resolve() ...@@ -285,7 +287,8 @@ static void do_resolve()
while (fgets(buf, sizeof(buf), fp_dump)) while (fgets(buf, sizeof(buf), fp_dump))
{ {
p = buf; p = buf;
while(isspace(*p)) /* skip space */
while (my_isspace(system_charset_info,*p))
++p; ++p;
if (*p++ == '0' && *p++ == 'x') if (*p++ == '0' && *p++ == 'x')
......
...@@ -122,7 +122,7 @@ int main(int argc, char **argv) ...@@ -122,7 +122,7 @@ int main(int argc, char **argv)
{ {
ip = *argv++; ip = *argv++;
if (isdigit(ip[0])) if (my_isdigit(system_charset_info,ip[0]))
{ {
taddr = inet_addr(ip); taddr = inet_addr(ip);
if (taddr == htonl(INADDR_BROADCAST)) if (taddr == htonl(INADDR_BROADCAST))
......
...@@ -20,10 +20,12 @@ ...@@ -20,10 +20,12 @@
static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records, static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records,
ulong blength, my_bool print_status); ulong blength, my_bool print_status);
static int check_one_rb_key(HP_INFO *info, uint keynr, ulong records,
my_bool print_status);
/* Returns 0 if the HEAP is ok */ /* Returns 0 if the HEAP is ok */
int heap_check_heap(HP_INFO *info,my_bool print_status) int heap_check_heap(HP_INFO *info, my_bool print_status)
{ {
int error; int error;
uint key; uint key;
...@@ -31,8 +33,13 @@ int heap_check_heap(HP_INFO *info,my_bool print_status) ...@@ -31,8 +33,13 @@ int heap_check_heap(HP_INFO *info,my_bool print_status)
DBUG_ENTER("heap_check_keys"); DBUG_ENTER("heap_check_keys");
for (error=key=0 ; key < share->keys ; key++) for (error=key=0 ; key < share->keys ; key++)
error|=check_one_key(share->keydef+key,key, share->records,share->blength, {
print_status); if (share->keydef[key].algorithm == HA_KEY_ALG_BTREE)
error|= check_one_rb_key(info, key, share->records, print_status);
else
error|= check_one_key(share->keydef + key, key, share->records,
share->blength, print_status);
}
DBUG_RETURN(error); DBUG_RETURN(error);
} }
...@@ -50,8 +57,8 @@ static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records, ...@@ -50,8 +57,8 @@ static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records,
for (i=found=max_links=seek=0 ; i < records ; i++) for (i=found=max_links=seek=0 ; i < records ; i++)
{ {
hash_info=hp_find_hash(&keydef->block,i); hash_info=hp_find_hash(&keydef->block,i);
if (_hp_mask(_hp_rec_hashnr(keydef,hash_info->ptr_to_rec), if (hp_mask(hp_rec_hashnr(keydef, hash_info->ptr_to_rec),
blength,records) == i) blength,records) == i)
{ {
found++; found++;
seek++; seek++;
...@@ -59,8 +66,8 @@ static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records, ...@@ -59,8 +66,8 @@ static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records,
while ((hash_info=hash_info->next_key) && found < records + 1) while ((hash_info=hash_info->next_key) && found < records + 1)
{ {
seek+= ++links; seek+= ++links;
if ((rec_link=_hp_mask(_hp_rec_hashnr(keydef,hash_info->ptr_to_rec), if ((rec_link = hp_mask(hp_rec_hashnr(keydef, hash_info->ptr_to_rec),
blength,records)) blength, records))
!= i) != i)
{ {
DBUG_PRINT("error",("Record in wrong link: Link %d Record: %lx Record-link %d", i,hash_info->ptr_to_rec,rec_link)); DBUG_PRINT("error",("Record in wrong link: Link %d Record: %lx Record-link %d", i,hash_info->ptr_to_rec,rec_link));
...@@ -87,3 +94,44 @@ static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records, ...@@ -87,3 +94,44 @@ static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records,
(float) seek / (float) (records ? records : 1)); (float) seek / (float) (records ? records : 1));
return error; return error;
} }
static int check_one_rb_key(HP_INFO *info, uint keynr, ulong records,
my_bool print_status)
{
HP_KEYDEF *keydef= info->s->keydef + keynr;
int error= 0;
ulong found= 0;
byte *key, *recpos;
uint key_length;
uint not_used;
if ((key= tree_search_edge(&keydef->rb_tree, info->parents,
&info->last_pos, offsetof(TREE_ELEMENT, left))))
{
do
{
memcpy(&recpos, key + (*keydef->get_key_length)(keydef,key), sizeof(byte*));
key_length= hp_rb_make_key(keydef, info->recbuf, recpos, 0);
if (ha_key_cmp(keydef->seg, info->recbuf, key, key_length,
SEARCH_FIND | SEARCH_SAME, &not_used))
{
error= 1;
DBUG_PRINT("error",("Record in wrong link: key: %d Record: %lx\n",
keynr, recpos));
}
else
found++;
key= tree_search_next(&keydef->rb_tree, &info->last_pos,
offsetof(TREE_ELEMENT, left),
offsetof(TREE_ELEMENT, right));
} while (key);
}
if (found != records)
{
DBUG_PRINT("error",("Found %lu of %lu records", found, records));
error= 1;
}
if (print_status)
printf("Key: %d records: %ld\n", keynr, records);
return error;
}
...@@ -19,9 +19,9 @@ ...@@ -19,9 +19,9 @@
#include "heapdef.h" #include "heapdef.h"
int _hp_rectest(register HP_INFO *info, register const byte *old) int hp_rectest(register HP_INFO *info, register const byte *old)
{ {
DBUG_ENTER("_hp_rectest"); DBUG_ENTER("hp_rectest");
if (memcmp(info->current_ptr,old,(size_t) info->s->reclength)) if (memcmp(info->current_ptr,old,(size_t) info->s->reclength))
{ {
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <my_pthread.h> #include <my_pthread.h>
#endif #endif
#include "heap.h" /* Structs & some defines */ #include "heap.h" /* Structs & some defines */
#include "my_tree.h"
/* /*
When allocating keys /rows in the internal block structure, do it When allocating keys /rows in the internal block structure, do it
...@@ -40,10 +41,10 @@ extern LIST *heap_open_list,*heap_share_list; ...@@ -40,10 +41,10 @@ extern LIST *heap_open_list,*heap_share_list;
#define test_active(info) \ #define test_active(info) \
if (!(info->update & HA_STATE_AKTIV))\ if (!(info->update & HA_STATE_AKTIV))\
{ my_errno=HA_ERR_NO_ACTIVE_RECORD; DBUG_RETURN(-1); } { my_errno=HA_ERR_NO_ACTIVE_RECORD; DBUG_RETURN(-1); }
#define hp_find_hash(A,B) ((HASH_INFO*) _hp_find_block((A),(B))) #define hp_find_hash(A,B) ((HASH_INFO*) hp_find_block((A),(B)))
/* Find pos for record and update it in info->current_ptr */ /* Find pos for record and update it in info->current_ptr */
#define _hp_find_record(info,pos) (info)->current_ptr= _hp_find_block(&(info)->s->block,pos) #define hp_find_record(info,pos) (info)->current_ptr= hp_find_block(&(info)->s->block,pos)
typedef struct st_hp_hash_info typedef struct st_hp_hash_info
{ {
...@@ -51,40 +52,52 @@ typedef struct st_hp_hash_info ...@@ -51,40 +52,52 @@ typedef struct st_hp_hash_info
byte *ptr_to_rec; byte *ptr_to_rec;
} HASH_INFO; } HASH_INFO;
typedef struct {
HA_KEYSEG *keyseg;
uint key_length;
uint search_flag;
} heap_rb_param;
/* Prototypes for intern functions */ /* Prototypes for intern functions */
extern HP_SHARE *_hp_find_named_heap(const char *name); extern HP_SHARE *hp_find_named_heap(const char *name);
extern int _hp_rectest(HP_INFO *info,const byte *old); extern int hp_rectest(HP_INFO *info,const byte *old);
extern void _hp_delete_file_from_open_list(HP_INFO *info); extern byte *hp_find_block(HP_BLOCK *info,ulong pos);
extern byte *_hp_find_block(HP_BLOCK *info,ulong pos); extern int hp_get_new_block(HP_BLOCK *info, ulong* alloc_length);
extern int _hp_get_new_block(HP_BLOCK *info, ulong* alloc_length); extern void hp_free(HP_SHARE *info);
extern void _hp_free(HP_SHARE *info); extern byte *hp_free_level(HP_BLOCK *block,uint level,HP_PTRS *pos,
extern byte *_hp_free_level(HP_BLOCK *block,uint level,HP_PTRS *pos, byte *last_pos);
byte *last_pos); extern int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
extern int _hp_write_key(HP_SHARE *info,HP_KEYDEF *keyinfo, const byte *record, byte *recpos);
const byte *record,byte *recpos); extern int hp_rb_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
extern int _hp_delete_key(HP_INFO *info,HP_KEYDEF *keyinfo, const byte *record, byte *recpos);
const byte *record,byte *recpos,int flag); extern int hp_rb_delete_key(HP_INFO *info,HP_KEYDEF *keyinfo,
const byte *record,byte *recpos,int flag);
extern int hp_delete_key(HP_INFO *info,HP_KEYDEF *keyinfo,
const byte *record,byte *recpos,int flag);
extern HASH_INFO *_heap_find_hash(HP_BLOCK *block,ulong pos); extern HASH_INFO *_heap_find_hash(HP_BLOCK *block,ulong pos);
extern byte *_hp_search(HP_INFO *info,HP_KEYDEF *keyinfo,const byte *key, extern byte *hp_search(HP_INFO *info,HP_KEYDEF *keyinfo,const byte *key,
uint nextflag); uint nextflag);
extern byte *_hp_search_next(HP_INFO *info, HP_KEYDEF *keyinfo, extern byte *hp_search_next(HP_INFO *info, HP_KEYDEF *keyinfo,
const byte *key, const byte *key, HASH_INFO *pos);
HASH_INFO *pos); extern ulong hp_hashnr(HP_KEYDEF *keyinfo,const byte *key);
extern ulong _hp_hashnr(HP_KEYDEF *keyinfo,const byte *key); extern ulong hp_rec_hashnr(HP_KEYDEF *keyinfo,const byte *rec);
extern ulong _hp_rec_hashnr(HP_KEYDEF *keyinfo,const byte *rec); extern ulong hp_mask(ulong hashnr,ulong buffmax,ulong maxlength);
extern ulong _hp_mask(ulong hashnr,ulong buffmax,ulong maxlength); extern void hp_movelink(HASH_INFO *pos,HASH_INFO *next_link,
extern void _hp_movelink(HASH_INFO *pos,HASH_INFO *next_link,
HASH_INFO *newlink); HASH_INFO *newlink);
extern int _hp_rec_key_cmp(HP_KEYDEF *keydef,const byte *rec1, extern int hp_rec_key_cmp(HP_KEYDEF *keydef,const byte *rec1,
const byte *rec2); const byte *rec2);
extern int _hp_key_cmp(HP_KEYDEF *keydef,const byte *rec, extern int hp_key_cmp(HP_KEYDEF *keydef,const byte *rec,
const byte *key); const byte *key);
extern void _hp_make_key(HP_KEYDEF *keydef,byte *key,const byte *rec); extern void hp_make_key(HP_KEYDEF *keydef,byte *key,const byte *rec);
extern uint hp_rb_make_key(HP_KEYDEF *keydef, byte *key,
const byte *rec, byte *recpos);
extern uint hp_rb_key_length(HP_KEYDEF *keydef, const byte *key);
extern uint hp_rb_null_key_length(HP_KEYDEF *keydef, const byte *key);
extern my_bool hp_if_null_in_key(HP_KEYDEF *keyinfo, const byte *record); extern my_bool hp_if_null_in_key(HP_KEYDEF *keyinfo, const byte *record);
extern int _hp_close(register HP_INFO *info); extern int hp_close(register HP_INFO *info);
extern void _hp_clear(HP_SHARE *info); extern void hp_clear(HP_SHARE *info);
extern uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old);
#ifdef THREAD #ifdef THREAD
extern pthread_mutex_t THR_LOCK_heap; extern pthread_mutex_t THR_LOCK_heap;
#else #else
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
/* Find record according to record-position */ /* Find record according to record-position */
byte *_hp_find_block(HP_BLOCK *block, ulong pos) byte *hp_find_block(HP_BLOCK *block, ulong pos)
{ {
reg1 int i; reg1 int i;
reg3 HP_PTRS *ptr; reg3 HP_PTRS *ptr;
...@@ -37,7 +37,7 @@ byte *_hp_find_block(HP_BLOCK *block, ulong pos) ...@@ -37,7 +37,7 @@ byte *_hp_find_block(HP_BLOCK *block, ulong pos)
/* get one new block-of-records. Alloc ptr to block if neaded */ /* get one new block-of-records. Alloc ptr to block if neaded */
/* Interrupts are stopped to allow ha_panic in interrupts */ /* Interrupts are stopped to allow ha_panic in interrupts */
int _hp_get_new_block(HP_BLOCK *block, ulong *alloc_length) int hp_get_new_block(HP_BLOCK *block, ulong *alloc_length)
{ {
reg1 uint i,j; reg1 uint i,j;
HP_PTRS *root; HP_PTRS *root;
...@@ -84,7 +84,7 @@ int _hp_get_new_block(HP_BLOCK *block, ulong *alloc_length) ...@@ -84,7 +84,7 @@ int _hp_get_new_block(HP_BLOCK *block, ulong *alloc_length)
/* free all blocks under level */ /* free all blocks under level */
byte *_hp_free_level(HP_BLOCK *block, uint level, HP_PTRS *pos, byte *last_pos) byte *hp_free_level(HP_BLOCK *block, uint level, HP_PTRS *pos, byte *last_pos)
{ {
int i,max_pos; int i,max_pos;
byte *next_ptr; byte *next_ptr;
...@@ -99,7 +99,7 @@ byte *_hp_free_level(HP_BLOCK *block, uint level, HP_PTRS *pos, byte *last_pos) ...@@ -99,7 +99,7 @@ byte *_hp_free_level(HP_BLOCK *block, uint level, HP_PTRS *pos, byte *last_pos)
next_ptr=(byte*) (pos+1); next_ptr=(byte*) (pos+1);
for (i=0 ; i < max_pos ; i++) for (i=0 ; i < max_pos ; i++)
next_ptr=_hp_free_level(block,level-1, next_ptr=hp_free_level(block,level-1,
(HP_PTRS*) pos->blocks[i],next_ptr); (HP_PTRS*) pos->blocks[i],next_ptr);
} }
if ((byte*) pos != last_pos) if ((byte*) pos != last_pos)
......
...@@ -24,25 +24,33 @@ ...@@ -24,25 +24,33 @@
void heap_clear(HP_INFO *info) void heap_clear(HP_INFO *info)
{ {
_hp_clear(info->s); hp_clear(info->s);
} }
void _hp_clear(HP_SHARE *info) void hp_clear(HP_SHARE *info)
{ {
uint key; uint key;
DBUG_ENTER("_hp_clear"); DBUG_ENTER("hp_clear");
if (info->block.levels) if (info->block.levels)
VOID(_hp_free_level(&info->block,info->block.levels,info->block.root, VOID(hp_free_level(&info->block,info->block.levels,info->block.root,
(byte*) 0)); (byte*) 0));
info->block.levels=0; info->block.levels=0;
for (key=0 ; key < info->keys ; key++) for (key=0 ; key < info->keys ; key++)
{ {
HP_BLOCK *block= &info->keydef[key].block; HP_KEYDEF *keyinfo = info->keydef + key;
if (block->levels) if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
VOID(_hp_free_level(block,block->levels,block->root,(byte*) 0)); {
block->levels=0; delete_tree(&keyinfo->rb_tree);
block->last_allocated=0; }
else
{
HP_BLOCK *block= &keyinfo->block;
if (block->levels)
VOID(hp_free_level(block,block->levels,block->root,(byte*) 0));
block->levels=0;
block->last_allocated=0;
}
} }
info->records=info->deleted=info->data_length=info->index_length=0; info->records=info->deleted=info->data_length=info->index_length=0;
info->blength=1; info->blength=1;
......
...@@ -26,16 +26,16 @@ int heap_close(HP_INFO *info) ...@@ -26,16 +26,16 @@ int heap_close(HP_INFO *info)
int tmp; int tmp;
DBUG_ENTER("heap_close"); DBUG_ENTER("heap_close");
pthread_mutex_lock(&THR_LOCK_heap); pthread_mutex_lock(&THR_LOCK_heap);
tmp= _hp_close(info); tmp= hp_close(info);
pthread_mutex_unlock(&THR_LOCK_heap); pthread_mutex_unlock(&THR_LOCK_heap);
DBUG_RETURN(tmp); DBUG_RETURN(tmp);
} }
int _hp_close(register HP_INFO *info) int hp_close(register HP_INFO *info)
{ {
int error=0; int error=0;
DBUG_ENTER("_hp_close"); DBUG_ENTER("hp_close");
#ifndef DBUG_OFF #ifndef DBUG_OFF
if (info->s->changed && heap_check_heap(info,0)) if (info->s->changed && heap_check_heap(info,0))
{ {
...@@ -45,7 +45,7 @@ int _hp_close(register HP_INFO *info) ...@@ -45,7 +45,7 @@ int _hp_close(register HP_INFO *info)
info->s->changed=0; info->s->changed=0;
heap_open_list=list_delete(heap_open_list,&info->open_list); heap_open_list=list_delete(heap_open_list,&info->open_list);
if (!--info->s->open_count && info->s->delete_on_close) if (!--info->s->open_count && info->s->delete_on_close)
_hp_free(info->s); /* Table was deleted */ hp_free(info->s); /* Table was deleted */
my_free((gptr) info,MYF(0)); my_free((gptr) info,MYF(0));
DBUG_RETURN(error); DBUG_RETURN(error);
} }
...@@ -14,30 +14,164 @@ ...@@ -14,30 +14,164 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Create is done by simply remove the database from memory if it exists.
Open creates the database when neaded
*/
#include "heapdef.h" #include "heapdef.h"
static int keys_compare(heap_rb_param *param, uchar *key1, uchar *key2);
static void init_block(HP_BLOCK *block,uint reclength,ulong min_records,
ulong max_records);
int heap_create(const char *name) int heap_create(const char *name, uint keys, HP_KEYDEF *keydef,
uint reclength, ulong max_records, ulong min_records,
HP_CREATE_INFO *create_info)
{ {
reg1 HP_SHARE *share; uint i, j, key_segs, max_length, length;
HP_SHARE *share;
HA_KEYSEG *keyseg;
DBUG_ENTER("heap_create"); DBUG_ENTER("heap_create");
pthread_mutex_lock(&THR_LOCK_heap); pthread_mutex_lock(&THR_LOCK_heap);
if ((share=_hp_find_named_heap(name)))
if ((share= hp_find_named_heap(name)) && share->open_count == 0)
{ {
if (share->open_count == 0) hp_free(share);
_hp_free(share); share= NULL;
} }
else
if (!share)
{ {
my_errno=ENOENT; HP_KEYDEF *keyinfo;
DBUG_PRINT("info",("Initializing new table"));
for (i= key_segs= max_length= 0, keyinfo= keydef; i < keys; i++, keyinfo++)
{
bzero((char*) &keyinfo->block,sizeof(keyinfo->block));
bzero((char*) &keyinfo->rb_tree ,sizeof(keyinfo->rb_tree));
for (j= length= 0; j < keyinfo->keysegs; j++)
{
length+= keyinfo->seg[j].length;
if (keyinfo->seg[j].null_bit)
{
if (!(keyinfo->flag & HA_NULL_ARE_EQUAL))
keyinfo->flag|= HA_NULL_PART_KEY;
if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
keyinfo->rb_tree.size_of_element++;
}
}
keyinfo->length= length;
length+= keyinfo->rb_tree.size_of_element +
((keyinfo->algorithm == HA_KEY_ALG_BTREE) ? sizeof(byte*) : 0);
if (length > max_length)
max_length= length;
key_segs+= keyinfo->keysegs;
if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
{
key_segs++; /* additional HA_KEYTYPE_END segment */
if (keyinfo->flag & HA_NULL_PART_KEY)
keyinfo->get_key_length= hp_rb_null_key_length;
else
keyinfo->get_key_length= hp_rb_key_length;
}
}
if (!(share= (HP_SHARE*) my_malloc((uint) sizeof(HP_SHARE)+
keys*sizeof(HP_KEYDEF)+
key_segs*sizeof(HA_KEYSEG),
MYF(MY_ZEROFILL))))
{
pthread_mutex_unlock(&THR_LOCK_heap);
DBUG_RETURN(1);
}
share->keydef= (HP_KEYDEF*) (share + 1);
keyseg= (HA_KEYSEG*) (share->keydef + keys);
init_block(&share->block, reclength + 1, min_records, max_records);
/* Fix keys */
memcpy(share->keydef, keydef, (size_t) (sizeof(keydef[0]) * keys));
for (i= 0, keyinfo= share->keydef; i < keys; i++, keyinfo++)
{
keyinfo->seg= keyseg;
memcpy(keyseg, keydef[i].seg,
(size_t) (sizeof(keyseg[0]) * keydef[i].keysegs));
keyseg+= keydef[i].keysegs;
if (keydef[i].algorithm == HA_KEY_ALG_BTREE)
{
/* additional HA_KEYTYPE_END keyseg */
keyseg->type= HA_KEYTYPE_END;
keyseg->length= sizeof(byte*);
keyseg->flag= 0;
keyseg->null_bit= 0;
keyseg++;
init_tree(&keyinfo->rb_tree, 0, 0, sizeof(byte*),
(qsort_cmp2)keys_compare, 1, NULL, NULL);
keyinfo->delete_key= hp_rb_delete_key;
keyinfo->write_key= hp_rb_write_key;
}
else
{
init_block(&keyinfo->block, sizeof(HASH_INFO), min_records,
max_records);
keyinfo->delete_key= hp_delete_key;
keyinfo->write_key= hp_write_key;
}
}
share->min_records= min_records;
share->max_records= max_records;
share->data_length= share->index_length= 0;
share->reclength= reclength;
share->blength= 1;
share->keys= keys;
share->max_key_length= max_length;
share->changed= 0;
share->auto_key= create_info->auto_key;
share->auto_key_type= create_info->auto_key_type;
share->auto_increment= create_info->auto_increment;
if (!(share->name= my_strdup(name,MYF(0))))
{
my_free((gptr) share,MYF(0));
pthread_mutex_unlock(&THR_LOCK_heap);
DBUG_RETURN(1);
}
#ifdef THREAD
thr_lock_init(&share->lock);
VOID(pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST));
#endif
share->open_list.data= (void*) share;
heap_share_list= list_add(heap_share_list,&share->open_list);
} }
pthread_mutex_unlock(&THR_LOCK_heap); pthread_mutex_unlock(&THR_LOCK_heap);
DBUG_RETURN(0); DBUG_RETURN(0);
} /* heap_create */
static int keys_compare(heap_rb_param *param, uchar *key1, uchar *key2)
{
uint not_used;
return ha_key_cmp(param->keyseg, key1, key2, param->key_length,
param->search_flag, &not_used);
}
static void init_block(HP_BLOCK *block, uint reclength, ulong min_records,
ulong max_records)
{
uint i,recbuffer,records_in_block;
max_records= max(min_records,max_records);
if (!max_records)
max_records= 1000; /* As good as quess as anything */
recbuffer= (uint) (reclength + sizeof(byte**) - 1) & ~(sizeof(byte**) - 1);
records_in_block= max_records / 10;
if (records_in_block < 10 && max_records)
records_in_block= 10;
if (!records_in_block || records_in_block*recbuffer >
(my_default_record_cache_size-sizeof(HP_PTRS)*HP_MAX_LEVELS))
records_in_block= (my_default_record_cache_size - sizeof(HP_PTRS) *
HP_MAX_LEVELS) / recbuffer + 1;
block->records_in_block= records_in_block;
block->recbuffer= recbuffer;
block->last_allocated= 0L;
for (i= 0; i <= HP_MAX_LEVELS; i++)
block->level_info[i].records_under_level=
(!i ? 1 : i == 1 ? records_in_block :
HP_PTRS_IN_NOD * block->level_info[i - 1].records_under_level);
} }
int heap_delete_table(const char *name) int heap_delete_table(const char *name)
...@@ -47,32 +181,31 @@ int heap_delete_table(const char *name) ...@@ -47,32 +181,31 @@ int heap_delete_table(const char *name)
DBUG_ENTER("heap_delete_table"); DBUG_ENTER("heap_delete_table");
pthread_mutex_lock(&THR_LOCK_heap); pthread_mutex_lock(&THR_LOCK_heap);
if ((share=_hp_find_named_heap(name))) if ((share= hp_find_named_heap(name)))
{ {
if (share->open_count == 0) if (share->open_count == 0)
_hp_free(share); hp_free(share);
else else
share->delete_on_close=1; share->delete_on_close= 1;
result=0; result= 0;
} }
else else
{ {
result=my_errno=ENOENT; result= my_errno=ENOENT;
} }
pthread_mutex_unlock(&THR_LOCK_heap); pthread_mutex_unlock(&THR_LOCK_heap);
DBUG_RETURN(result); DBUG_RETURN(result);
} }
void hp_free(HP_SHARE *share)
void _hp_free(HP_SHARE *share)
{ {
heap_share_list=list_delete(heap_share_list,&share->open_list); heap_share_list= list_delete(heap_share_list, &share->open_list);
_hp_clear(share); /* Remove blocks from memory */ hp_clear(share); /* Remove blocks from memory */
#ifdef THREAD #ifdef THREAD
thr_lock_delete(&share->lock); thr_lock_delete(&share->lock);
VOID(pthread_mutex_destroy(&share->intern_lock)); VOID(pthread_mutex_destroy(&share->intern_lock));
#endif #endif
my_free((gptr) share->name,MYF(0)); my_free((gptr) share->name, MYF(0));
my_free((gptr) share,MYF(0)); my_free((gptr) share, MYF(0));
return; return;
} }
...@@ -20,25 +20,26 @@ ...@@ -20,25 +20,26 @@
int heap_delete(HP_INFO *info, const byte *record) int heap_delete(HP_INFO *info, const byte *record)
{ {
uint key;
byte *pos; byte *pos;
HP_SHARE *share=info->s; HP_SHARE *share=info->s;
HP_KEYDEF *keydef, *end, *p_lastinx;
DBUG_ENTER("heap_delete"); DBUG_ENTER("heap_delete");
DBUG_PRINT("enter",("info: %lx record: %lx",info,record)); DBUG_PRINT("enter",("info: %lx record: %lx",info,record));
test_active(info); test_active(info);
if (info->opt_flag & READ_CHECK_USED && _hp_rectest(info,record)) if (info->opt_flag & READ_CHECK_USED && hp_rectest(info,record))
DBUG_RETURN(my_errno); /* Record changed */ DBUG_RETURN(my_errno); /* Record changed */
share->changed=1; share->changed=1;
if ( --(share->records) < share->blength >> 1) share->blength>>=1; if ( --(share->records) < share->blength >> 1) share->blength>>=1;
pos=info->current_ptr; pos=info->current_ptr;
for (key=0 ; key < share->keys ; key++) p_lastinx = share->keydef + info->lastinx;
for (keydef = share->keydef, end = keydef + share->keys; keydef < end;
keydef++)
{ {
if (_hp_delete_key(info,share->keydef+key,record,pos, if ((*keydef->delete_key)(info, keydef, record, pos, keydef == p_lastinx))
key == (uint) info->lastinx))
goto err; goto err;
} }
...@@ -49,22 +50,39 @@ int heap_delete(HP_INFO *info, const byte *record) ...@@ -49,22 +50,39 @@ int heap_delete(HP_INFO *info, const byte *record)
share->deleted++; share->deleted++;
info->current_hash_ptr=0; info->current_hash_ptr=0;
DBUG_RETURN(0); DBUG_RETURN(0);
err: err:
if (++(share->records) == share->blength) if (++(share->records) == share->blength)
share->blength+= share->blength; share->blength+= share->blength;
DBUG_RETURN(my_errno); DBUG_RETURN(my_errno);
} }
/*
Remove one key from rb-tree
*/
int hp_rb_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
const byte *record, byte *recpos, int flag)
{
heap_rb_param custom_arg;
if (flag)
info->last_pos= NULL; /* For heap_rnext/heap_rprev */
custom_arg.keyseg= keyinfo->seg;
custom_arg.key_length= hp_rb_make_key(keyinfo, info->recbuf, record, recpos);
custom_arg.search_flag= SEARCH_SAME;
return tree_delete(&keyinfo->rb_tree, info->recbuf, &custom_arg);
}
/* Remove one key from hash-table */ /* Remove one key from hash-table */
/* Flag is set if we want's to correct info->current_ptr */ /* Flag is set if we want's to correct info->current_ptr */
int _hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo, int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
const byte *record, byte *recpos, int flag) const byte *record, byte *recpos, int flag)
{ {
ulong blength,pos2,pos_hashnr,lastpos_hashnr; ulong blength,pos2,pos_hashnr,lastpos_hashnr;
HASH_INFO *lastpos,*gpos,*pos,*pos3,*empty,*last_ptr; HASH_INFO *lastpos,*gpos,*pos,*pos3,*empty,*last_ptr;
HP_SHARE *share=info->s; HP_SHARE *share=info->s;
DBUG_ENTER("_hp_delete_key"); DBUG_ENTER("hp_delete_key");
blength=share->blength; blength=share->blength;
if (share->records+1 == blength) if (share->records+1 == blength)
...@@ -74,13 +92,13 @@ int _hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo, ...@@ -74,13 +92,13 @@ int _hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
/* Search after record with key */ /* Search after record with key */
pos= hp_find_hash(&keyinfo->block, pos= hp_find_hash(&keyinfo->block,
_hp_mask(_hp_rec_hashnr(keyinfo,record),blength, hp_mask(hp_rec_hashnr(keyinfo, record), blength,
share->records+1)); share->records + 1));
gpos = pos3 = 0; gpos = pos3 = 0;
while (pos->ptr_to_rec != recpos) while (pos->ptr_to_rec != recpos)
{ {
if (flag && !_hp_rec_key_cmp(keyinfo,record,pos->ptr_to_rec)) if (flag && !hp_rec_key_cmp(keyinfo, record, pos->ptr_to_rec))
last_ptr=pos; /* Previous same key */ last_ptr=pos; /* Previous same key */
gpos=pos; gpos=pos;
if (!(pos=pos->next_key)) if (!(pos=pos->next_key))
...@@ -113,33 +131,33 @@ int _hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo, ...@@ -113,33 +131,33 @@ int _hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
DBUG_RETURN (0); DBUG_RETURN (0);
/* Move the last key (lastpos) */ /* Move the last key (lastpos) */
lastpos_hashnr=_hp_rec_hashnr(keyinfo,lastpos->ptr_to_rec); lastpos_hashnr = hp_rec_hashnr(keyinfo, lastpos->ptr_to_rec);
/* pos is where lastpos should be */ /* pos is where lastpos should be */
pos=hp_find_hash(&keyinfo->block,_hp_mask(lastpos_hashnr,share->blength, pos=hp_find_hash(&keyinfo->block, hp_mask(lastpos_hashnr, share->blength,
share->records)); share->records));
if (pos == empty) /* Move to empty position. */ if (pos == empty) /* Move to empty position. */
{ {
empty[0]=lastpos[0]; empty[0]=lastpos[0];
DBUG_RETURN(0); DBUG_RETURN(0);
} }
pos_hashnr=_hp_rec_hashnr(keyinfo,pos->ptr_to_rec); pos_hashnr = hp_rec_hashnr(keyinfo, pos->ptr_to_rec);
/* pos3 is where the pos should be */ /* pos3 is where the pos should be */
pos3= hp_find_hash(&keyinfo->block, pos3= hp_find_hash(&keyinfo->block,
_hp_mask(pos_hashnr,share->blength,share->records)); hp_mask(pos_hashnr, share->blength, share->records));
if (pos != pos3) if (pos != pos3)
{ /* pos is on wrong posit */ { /* pos is on wrong posit */
empty[0]=pos[0]; /* Save it here */ empty[0]=pos[0]; /* Save it here */
pos[0]=lastpos[0]; /* This shold be here */ pos[0]=lastpos[0]; /* This shold be here */
_hp_movelink(pos,pos3,empty); /* Fix link to pos */ hp_movelink(pos, pos3, empty); /* Fix link to pos */
DBUG_RETURN(0); DBUG_RETURN(0);
} }
pos2= _hp_mask(lastpos_hashnr,blength,share->records+1); pos2= hp_mask(lastpos_hashnr, blength, share->records + 1);
if (pos2 == _hp_mask(pos_hashnr,blength,share->records+1)) if (pos2 == hp_mask(pos_hashnr, blength, share->records + 1))
{ /* Identical key-positions */ { /* Identical key-positions */
if (pos2 != share->records) if (pos2 != share->records)
{ {
empty[0]=lastpos[0]; empty[0]=lastpos[0];
_hp_movelink(lastpos,pos,empty); hp_movelink(lastpos, pos, empty);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
pos3= pos; /* Link pos->next after lastpos */ pos3= pos; /* Link pos->next after lastpos */
...@@ -147,7 +165,7 @@ int _hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo, ...@@ -147,7 +165,7 @@ int _hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
else pos3= 0; /* Different positions merge */ else pos3= 0; /* Different positions merge */
empty[0]=lastpos[0]; empty[0]=lastpos[0];
_hp_movelink(pos3,empty,pos->next_key); hp_movelink(pos3, empty, pos->next_key);
pos->next_key=empty; pos->next_key=empty;
DBUG_RETURN(0); DBUG_RETURN(0);
} }
This diff is collapsed.
...@@ -55,5 +55,7 @@ int heap_info(reg1 HP_INFO *info,reg2 HEAPINFO *x, ...@@ -55,5 +55,7 @@ int heap_info(reg1 HP_INFO *info,reg2 HEAPINFO *x,
x->index_length= info->s->index_length; x->index_length= info->s->index_length;
x->max_records = info->s->max_records; x->max_records = info->s->max_records;
x->errkey = info->errkey; x->errkey = info->errkey;
if (flag & HA_STATUS_AUTO)
x->auto_increment= info->s->auto_increment + 1;
DBUG_RETURN(0); DBUG_RETURN(0);
} /* heap_info */ } /* heap_info */
...@@ -21,165 +21,72 @@ ...@@ -21,165 +21,72 @@
#include "hp_static.c" /* Stupid vms-linker */ #include "hp_static.c" /* Stupid vms-linker */
#endif #endif
static void init_block(HP_BLOCK *block,uint reclength,ulong min_records, #include "my_sys.h"
ulong max_records);
/* open a heap database. */ HP_INFO *heap_open(const char *name, int mode)
HP_INFO *heap_open(const char *name, int mode, uint keys, HP_KEYDEF *keydef,
uint reclength, ulong max_records, ulong min_records)
{ {
uint i,j,key_segs,max_length,length;
HP_INFO *info; HP_INFO *info;
HP_SHARE *share; HP_SHARE *share;
HP_KEYSEG *keyseg;
DBUG_ENTER("heap_open");
DBUG_ENTER("heap_open");
pthread_mutex_lock(&THR_LOCK_heap); pthread_mutex_lock(&THR_LOCK_heap);
if (!(share=_hp_find_named_heap(name))) if (!(share= hp_find_named_heap(name)))
{ {
DBUG_PRINT("info",("Initializing new table")); my_errno= ENOENT;
for (i=key_segs=max_length=0 ; i < keys ; i++) pthread_mutex_unlock(&THR_LOCK_heap);
{ DBUG_RETURN(0);
key_segs+= keydef[i].keysegs;
bzero((char*) &keydef[i].block,sizeof(keydef[i].block));
for (j=length=0 ; j < keydef[i].keysegs; j++)
{
length+=keydef[i].seg[j].length;
if (keydef[i].seg[j].null_bit &&
!(keydef[i].flag & HA_NULL_ARE_EQUAL))
keydef[i].flag |= HA_NULL_PART_KEY;
}
keydef[i].length=length;
if (length > max_length)
max_length=length;
}
if (!(share = (HP_SHARE*) my_malloc((uint) sizeof(HP_SHARE)+
keys*sizeof(HP_KEYDEF)+
key_segs*sizeof(HP_KEYSEG),
MYF(MY_ZEROFILL))))
{
pthread_mutex_unlock(&THR_LOCK_heap);
DBUG_RETURN(0);
}
share->keydef=(HP_KEYDEF*) (share+1);
keyseg=(HP_KEYSEG*) (share->keydef+keys);
init_block(&share->block,reclength+1,min_records,max_records);
/* Fix keys */
memcpy(share->keydef,keydef,(size_t) (sizeof(keydef[0])*keys));
for (i=0 ; i < keys ; i++)
{
share->keydef[i].seg=keyseg;
memcpy(keyseg,keydef[i].seg,
(size_t) (sizeof(keyseg[0])*keydef[i].keysegs));
keyseg+=keydef[i].keysegs;
init_block(&share->keydef[i].block,sizeof(HASH_INFO),min_records,
max_records);
}
share->min_records=min_records;
share->max_records=max_records;
share->data_length=share->index_length=0;
share->reclength=reclength;
share->blength=1;
share->keys=keys;
share->max_key_length=max_length;
share->changed=0;
if (!(share->name=my_strdup(name,MYF(0))))
{
my_free((gptr) share,MYF(0));
pthread_mutex_unlock(&THR_LOCK_heap);
DBUG_RETURN(0);
}
#ifdef THREAD
thr_lock_init(&share->lock);
VOID(pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST));
#endif
share->open_list.data=(void*) share;
heap_share_list=list_add(heap_share_list,&share->open_list);
} }
if (!(info= (HP_INFO*) my_malloc((uint) sizeof(HP_INFO)+ if (!(info= (HP_INFO*) my_malloc((uint) sizeof(HP_INFO) +
share->max_key_length, 2 * share->max_key_length,
MYF(MY_ZEROFILL)))) MYF(MY_ZEROFILL))))
{ {
pthread_mutex_unlock(&THR_LOCK_heap); pthread_mutex_unlock(&THR_LOCK_heap);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
share->open_count++; share->open_count++;
#ifdef THREAD #ifdef THREAD
thr_lock_data_init(&share->lock,&info->lock,NULL); thr_lock_data_init(&share->lock,&info->lock,NULL);
#endif #endif
info->open_list.data=(void*) info; info->open_list.data= (void*) info;
heap_open_list=list_add(heap_open_list,&info->open_list); heap_open_list= list_add(heap_open_list,&info->open_list);
pthread_mutex_unlock(&THR_LOCK_heap); pthread_mutex_unlock(&THR_LOCK_heap);
info->s=share; info->s= share;
info->lastkey=(byte*) (info+1); info->lastkey= (byte*) (info + 1);
info->mode=mode; info->recbuf= (byte*) (info->lastkey + share->max_key_length);
info->mode= mode;
info->current_record= (ulong) ~0L; /* No current record */ info->current_record= (ulong) ~0L; /* No current record */
info->current_ptr=0; info->current_ptr= 0;
info->current_hash_ptr=0; info->current_hash_ptr= 0;
info->lastinx= info->errkey= -1; info->lastinx= info->errkey= -1;
info->update=0; info->update= 0;
#ifndef DBUG_OFF #ifndef DBUG_OFF
info->opt_flag=READ_CHECK_USED; /* Check when changing */ info->opt_flag= READ_CHECK_USED; /* Check when changing */
#endif #endif
DBUG_PRINT("exit",("heap: %lx reclength: %d records_in_block: %d", DBUG_PRINT("exit",("heap: %lx reclength: %d records_in_block: %d",
info,share->reclength,share->block.records_in_block)); info,share->reclength,share->block.records_in_block));
DBUG_RETURN(info); DBUG_RETURN(info);
} /* heap_open */ }
/* map name to a heap-nr. If name isn't found return 0 */ /* map name to a heap-nr. If name isn't found return 0 */
HP_SHARE *_hp_find_named_heap(const char *name) HP_SHARE *hp_find_named_heap(const char *name)
{ {
LIST *pos; LIST *pos;
HP_SHARE *info; HP_SHARE *info;
DBUG_ENTER("heap_find"); DBUG_ENTER("heap_find");
DBUG_PRINT("enter",("name: %s",name)); DBUG_PRINT("enter",("name: %s",name));
for (pos=heap_share_list ; pos ; pos=pos->next) for (pos= heap_share_list; pos; pos= pos->next)
{ {
info=(HP_SHARE*) pos->data; info= (HP_SHARE*) pos->data;
if (!strcmp(name,info->name)) if (!strcmp(name, info->name))
{ {
DBUG_PRINT("exit",("Old heap_database: %lx",info)); DBUG_PRINT("exit", ("Old heap_database: %lx",info));
DBUG_RETURN(info); DBUG_RETURN(info);
} }
} }
DBUG_RETURN((HP_SHARE *)0); DBUG_RETURN((HP_SHARE *) 0);
} }
static void init_block(HP_BLOCK *block, uint reclength, ulong min_records,
ulong max_records)
{
uint i,recbuffer,records_in_block;
max_records=max(min_records,max_records);
if (!max_records)
max_records=1000; /* As good as quess as anything */
recbuffer=(uint) (reclength+sizeof(byte**)-1) & ~(sizeof(byte**)-1);
records_in_block=max_records/10;
if (records_in_block < HP_MIN_RECORDS_IN_BLOCK && max_records)
records_in_block= HP_MIN_RECORDS_IN_BLOCK;
/*
Don't allocate too many rows at one time too keep memory consumption
done when we don't need it.
*/
if (records_in_block > HP_MAX_RECORDS_IN_BLOCK)
records_in_block= HP_MAX_RECORDS_IN_BLOCK;
if (!records_in_block || records_in_block*recbuffer >
(my_default_record_cache_size-sizeof(HP_PTRS)*HP_MAX_LEVELS))
records_in_block=(my_default_record_cache_size-sizeof(HP_PTRS)*
HP_MAX_LEVELS)/recbuffer+1;
block->records_in_block=records_in_block;
block->recbuffer=recbuffer;
block->last_allocated= 0L;
for (i=0 ; i <= HP_MAX_LEVELS ; i++)
block->level_info[i].records_under_level=
(!i ? 1 : i == 1 ? records_in_block :
HP_PTRS_IN_NOD * block->level_info[i-1].records_under_level);
}
...@@ -31,7 +31,7 @@ int heap_panic(enum ha_panic_function flag) ...@@ -31,7 +31,7 @@ int heap_panic(enum ha_panic_function flag)
next_open=element->next; /* Save if close */ next_open=element->next; /* Save if close */
switch (flag) { switch (flag) {
case HA_PANIC_CLOSE: case HA_PANIC_CLOSE:
_hp_close(info); hp_close(info);
break; break;
default: default:
break; break;
...@@ -45,7 +45,7 @@ int heap_panic(enum ha_panic_function flag) ...@@ -45,7 +45,7 @@ int heap_panic(enum ha_panic_function flag)
case HA_PANIC_CLOSE: case HA_PANIC_CLOSE:
{ {
if (!share->open_count) if (!share->open_count)
_hp_free(share); hp_free(share);
break; break;
} }
default: default:
......
...@@ -27,7 +27,7 @@ int heap_rename(const char *old_name, const char *new_name) ...@@ -27,7 +27,7 @@ int heap_rename(const char *old_name, const char *new_name)
DBUG_ENTER("heap_rename"); DBUG_ENTER("heap_rename");
pthread_mutex_lock(&THR_LOCK_heap); pthread_mutex_lock(&THR_LOCK_heap);
if ((info=_hp_find_named_heap(old_name))) if ((info = hp_find_named_heap(old_name)))
{ {
if (!(name_buff=(char*) my_strdup(new_name,MYF(MY_WME)))) if (!(name_buff=(char*) my_strdup(new_name,MYF(MY_WME))))
{ {
......
...@@ -18,11 +18,43 @@ ...@@ -18,11 +18,43 @@
/* Read first record with the current key */ /* Read first record with the current key */
int heap_rfirst(HP_INFO *info, byte *record) int heap_rfirst(HP_INFO *info, byte *record, int inx)
{ {
HP_SHARE *share = info->s;
HP_KEYDEF *keyinfo = share->keydef + inx;
DBUG_ENTER("heap_rfirst"); DBUG_ENTER("heap_rfirst");
info->current_record=0; info->lastinx= inx;
info->current_hash_ptr=0; if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
info->update=HA_STATE_PREV_FOUND; {
DBUG_RETURN(heap_rnext(info,record)); byte *pos;
if ((pos = tree_search_edge(&keyinfo->rb_tree, info->parents,
&info->last_pos, offsetof(TREE_ELEMENT, left))))
{
memcpy(&pos, pos + (*keyinfo->get_key_length)(keyinfo, pos),
sizeof(byte*));
info->current_ptr = pos;
memcpy(record, pos, (size_t)share->reclength);
info->update = HA_STATE_AKTIV;
}
else
{
my_errno = HA_ERR_END_OF_FILE;
DBUG_RETURN(my_errno);
}
DBUG_RETURN(0);
}
else
{
if (!(info->s->records))
{
my_errno=HA_ERR_END_OF_FILE;
DBUG_RETURN(my_errno);
}
info->current_record=0;
info->current_hash_ptr=0;
info->update=HA_STATE_PREV_FOUND;
DBUG_RETURN(heap_rnext(info,record));
}
} }
...@@ -16,29 +16,60 @@ ...@@ -16,29 +16,60 @@
#include "heapdef.h" #include "heapdef.h"
int heap_rkey(HP_INFO *info, byte *record, int inx, const byte *key) int heap_rkey(HP_INFO *info, byte *record, int inx, const byte *key,
uint key_len, enum ha_rkey_function find_flag)
{ {
byte *pos; byte *pos;
HP_SHARE *share=info->s; HP_SHARE *share= info->s;
HP_KEYDEF *keyinfo= share->keydef + inx;
DBUG_ENTER("heap_rkey"); DBUG_ENTER("heap_rkey");
DBUG_PRINT("enter",("base: %lx inx: %d",info,inx)); DBUG_PRINT("enter",("base: %lx inx: %d",info,inx));
if ((uint) inx >= share->keys) if ((uint) inx >= share->keys)
{ {
DBUG_RETURN(my_errno=HA_ERR_WRONG_INDEX); DBUG_RETURN(my_errno= HA_ERR_WRONG_INDEX);
} }
info->lastinx=inx; info->lastinx= inx;
info->current_record = (ulong) ~0L; /* For heap_rrnd() */ info->current_record= (ulong) ~0L; /* For heap_rrnd() */
if (!(pos=_hp_search(info,share->keydef+inx,key,0))) if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
{ {
info->update=0; heap_rb_param custom_arg;
DBUG_RETURN(my_errno);
hp_rb_pack_key(keyinfo, info->recbuf, key);
custom_arg.keyseg= info->s->keydef[inx].seg;
custom_arg.key_length= key_len;
custom_arg.search_flag= SEARCH_FIND | SEARCH_SAME;
/* for next rkey() after deletion */
if (find_flag == HA_READ_AFTER_KEY)
info->last_find_flag= HA_READ_KEY_OR_NEXT;
else if (find_flag == HA_READ_BEFORE_KEY)
info->last_find_flag= HA_READ_KEY_OR_PREV;
else
info->last_find_flag= find_flag;
info->lastkey_len= key_len;
if (!(pos= tree_search_key(&keyinfo->rb_tree, info->recbuf, info->parents,
&info->last_pos, find_flag, &custom_arg)))
{
info->update= 0;
DBUG_RETURN(my_errno= HA_ERR_KEY_NOT_FOUND);
}
memcpy(&pos, pos + (*keyinfo->get_key_length)(keyinfo, pos), sizeof(byte*));
info->current_ptr= pos;
}
else
{
if (!(pos= hp_search(info, share->keydef + inx, key, 0)))
{
info->update= 0;
DBUG_RETURN(my_errno);
}
if (!(keyinfo->flag & HA_NOSAME))
memcpy(info->lastkey, key, (size_t) keyinfo->length);
} }
memcpy(record,pos,(size_t) share->reclength); memcpy(record, pos, (size_t) share->reclength);
info->update=HA_STATE_AKTIV; info->update= HA_STATE_AKTIV;
if (!(share->keydef[inx].flag & HA_NOSAME))
memcpy(info->lastkey,key,(size_t) share->keydef[inx].length);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -47,5 +78,5 @@ int heap_rkey(HP_INFO *info, byte *record, int inx, const byte *key) ...@@ -47,5 +78,5 @@ int heap_rkey(HP_INFO *info, byte *record, int inx, const byte *key)
gptr heap_find(HP_INFO *info, int inx, const byte *key) gptr heap_find(HP_INFO *info, int inx, const byte *key)
{ {
return _hp_search(info,info->s->keydef+inx,key,0); return hp_search(info, info->s->keydef + inx, key, 0);
} }
...@@ -19,11 +19,38 @@ ...@@ -19,11 +19,38 @@
/* Read first record with the current key */ /* Read first record with the current key */
int heap_rlast(HP_INFO *info, byte *record) int heap_rlast(HP_INFO *info, byte *record, int inx)
{ {
HP_SHARE *share= info->s;
HP_KEYDEF *keyinfo= share->keydef + inx;
DBUG_ENTER("heap_rlast"); DBUG_ENTER("heap_rlast");
info->current_ptr=0; info->lastinx= inx;
info->current_hash_ptr=0; if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
info->update=HA_STATE_NEXT_FOUND; {
DBUG_RETURN(heap_rprev(info,record)); byte *pos;
if ((pos = tree_search_edge(&keyinfo->rb_tree, info->parents,
&info->last_pos, offsetof(TREE_ELEMENT, right))))
{
memcpy(&pos, pos + (*keyinfo->get_key_length)(keyinfo, pos),
sizeof(byte*));
info->current_ptr = pos;
memcpy(record, pos, (size_t)share->reclength);
info->update = HA_STATE_AKTIV;
}
else
{
my_errno = HA_ERR_END_OF_FILE;
DBUG_RETURN(my_errno);
}
DBUG_RETURN(0);
}
else
{
info->current_ptr=0;
info->current_hash_ptr=0;
info->update=HA_STATE_NEXT_FOUND;
DBUG_RETURN(heap_rprev(info,record));
}
} }
...@@ -22,27 +22,58 @@ int heap_rnext(HP_INFO *info, byte *record) ...@@ -22,27 +22,58 @@ int heap_rnext(HP_INFO *info, byte *record)
{ {
byte *pos; byte *pos;
HP_SHARE *share=info->s; HP_SHARE *share=info->s;
HP_KEYDEF *keyinfo;
DBUG_ENTER("heap_rnext"); DBUG_ENTER("heap_rnext");
if (info->lastinx < 0) if (info->lastinx < 0)
DBUG_RETURN(my_errno=HA_ERR_WRONG_INDEX); DBUG_RETURN(my_errno=HA_ERR_WRONG_INDEX);
if (info->current_hash_ptr) keyinfo = share->keydef + info->lastinx;
pos= _hp_search_next(info,share->keydef+info->lastinx, info->lastkey, if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
info->current_hash_ptr);
else
{ {
if (!info->current_ptr && (info->update & HA_STATE_NEXT_FOUND)) heap_rb_param custom_arg;
if (info->last_pos)
pos = tree_search_next(&keyinfo->rb_tree, &info->last_pos,
offsetof(TREE_ELEMENT, left),
offsetof(TREE_ELEMENT, right));
else
{
custom_arg.keyseg = keyinfo->seg;
custom_arg.key_length = info->lastkey_len;
custom_arg.search_flag = SEARCH_SAME | SEARCH_FIND;
pos = tree_search_key(&keyinfo->rb_tree, info->lastkey, info->parents,
&info->last_pos, info->last_find_flag, &custom_arg);
}
if (pos)
{
memcpy(&pos, pos + (*keyinfo->get_key_length)(keyinfo, pos),
sizeof(byte*));
info->current_ptr = pos;
}
else
{ {
pos=0; /* Read next after last */ my_errno = HA_ERR_KEY_NOT_FOUND;
my_errno=HA_ERR_KEY_NOT_FOUND;
} }
else if (!info->current_ptr) /* Deleted or first call */ }
pos= _hp_search(info,share->keydef+info->lastinx, info->lastkey, 0); else
{
if (info->current_hash_ptr)
pos= hp_search_next(info, keyinfo, info->lastkey,
info->current_hash_ptr);
else else
pos= _hp_search(info,share->keydef+info->lastinx, info->lastkey, 1); {
if (!info->current_ptr && (info->update & HA_STATE_NEXT_FOUND))
{
pos=0; /* Read next after last */
my_errno=HA_ERR_KEY_NOT_FOUND;
}
else if (!info->current_ptr) /* Deleted or first call */
pos= hp_search(info, keyinfo, info->lastkey, 0);
else
pos= hp_search(info, keyinfo, info->lastkey, 1);
}
} }
if (!pos) if (!pos)
{ {
info->update=HA_STATE_NEXT_FOUND; /* For heap_rprev */ info->update=HA_STATE_NEXT_FOUND; /* For heap_rprev */
......
...@@ -23,22 +23,53 @@ int heap_rprev(HP_INFO *info, byte *record) ...@@ -23,22 +23,53 @@ int heap_rprev(HP_INFO *info, byte *record)
{ {
byte *pos; byte *pos;
HP_SHARE *share=info->s; HP_SHARE *share=info->s;
HP_KEYDEF *keyinfo;
DBUG_ENTER("heap_rprev"); DBUG_ENTER("heap_rprev");
if (info->lastinx < 0) if (info->lastinx < 0)
DBUG_RETURN(my_errno=HA_ERR_WRONG_INDEX); DBUG_RETURN(my_errno=HA_ERR_WRONG_INDEX);
keyinfo = share->keydef + info->lastinx;
if (info->current_ptr || (info->update & HA_STATE_NEXT_FOUND)) if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
{ {
if ((info->update & HA_STATE_DELETED)) heap_rb_param custom_arg;
pos= _hp_search(info,share->keydef+info->lastinx, info->lastkey, 3);
if (info->last_pos)
pos = tree_search_next(&keyinfo->rb_tree, &info->last_pos,
offsetof(TREE_ELEMENT, right),
offsetof(TREE_ELEMENT, left));
else else
pos= _hp_search(info,share->keydef+info->lastinx, info->lastkey, 2); {
custom_arg.keyseg = keyinfo->seg;
custom_arg.key_length = keyinfo->length;
custom_arg.search_flag = SEARCH_SAME;
pos = tree_search_key(&keyinfo->rb_tree, info->lastkey, info->parents,
&info->last_pos, info->last_find_flag, &custom_arg);
}
if (pos)
{
memcpy(&pos, pos + (*keyinfo->get_key_length)(keyinfo, pos),
sizeof(byte*));
info->current_ptr = pos;
}
else
{
my_errno = HA_ERR_KEY_NOT_FOUND;
}
} }
else else
{ {
pos=0; /* Read next after last */ if (info->current_ptr || (info->update & HA_STATE_NEXT_FOUND))
my_errno=HA_ERR_KEY_NOT_FOUND; {
if ((info->update & HA_STATE_DELETED))
pos= hp_search(info, share->keydef + info->lastinx, info->lastkey, 3);
else
pos= hp_search(info, share->keydef + info->lastinx, info->lastkey, 2);
}
else
{
pos=0; /* Read next after last */
my_errno=HA_ERR_KEY_NOT_FOUND;
}
} }
if (!pos) if (!pos)
{ {
......
...@@ -88,7 +88,7 @@ int heap_rrnd_old(register HP_INFO *info, byte *record, ulong pos) ...@@ -88,7 +88,7 @@ int heap_rrnd_old(register HP_INFO *info, byte *record, ulong pos)
} }
/* Find record number pos */ /* Find record number pos */
_hp_find_record(info,pos); hp_find_record(info, pos);
end: end:
if (!info->current_ptr[share->reclength]) if (!info->current_ptr[share->reclength])
......
...@@ -41,8 +41,8 @@ int heap_rsame(register HP_INFO *info, byte *record, int inx) ...@@ -41,8 +41,8 @@ int heap_rsame(register HP_INFO *info, byte *record, int inx)
else if (inx != -1) else if (inx != -1)
{ {
info->lastinx=inx; info->lastinx=inx;
_hp_make_key(share->keydef+inx,info->lastkey,record); hp_make_key(share->keydef + inx, info->lastkey, record);
if (!_hp_search(info,share->keydef+inx,info->lastkey,3)) if (!hp_search(info, share->keydef + inx, info->lastkey, 3))
{ {
info->update=0; info->update=0;
DBUG_RETURN(my_errno); DBUG_RETURN(my_errno);
......
...@@ -58,7 +58,7 @@ int heap_scan(register HP_INFO *info, byte *record) ...@@ -58,7 +58,7 @@ int heap_scan(register HP_INFO *info, byte *record)
DBUG_RETURN(my_errno= HA_ERR_END_OF_FILE); DBUG_RETURN(my_errno= HA_ERR_END_OF_FILE);
} }
} }
_hp_find_record(info,pos); hp_find_record(info, pos);
} }
if (!info->current_ptr[share->reclength]) if (!info->current_ptr[share->reclength])
{ {
......
...@@ -36,25 +36,31 @@ int main(int argc, char **argv) ...@@ -36,25 +36,31 @@ int main(int argc, char **argv)
char record[128],key[32]; char record[128],key[32];
const char *filename; const char *filename;
HP_KEYDEF keyinfo[10]; HP_KEYDEF keyinfo[10];
HP_KEYSEG keyseg[4]; HA_KEYSEG keyseg[4];
HP_CREATE_INFO hp_create_info;
MY_INIT(argv[0]); MY_INIT(argv[0]);
filename= "test1"; filename= "test1";
get_options(argc,argv); get_options(argc,argv);
bzero(&hp_create_info, sizeof(hp_create_info));
keyinfo[0].keysegs=1; keyinfo[0].keysegs=1;
keyinfo[0].seg=keyseg; keyinfo[0].seg=keyseg;
keyinfo[0].algorithm= HA_KEY_ALG_HASH;
keyinfo[0].seg[0].type=HA_KEYTYPE_BINARY; keyinfo[0].seg[0].type=HA_KEYTYPE_BINARY;
keyinfo[0].seg[0].start=1; keyinfo[0].seg[0].start=1;
keyinfo[0].seg[0].length=6; keyinfo[0].seg[0].length=6;
keyinfo[0].seg[0].charset=default_charset_info;
keyinfo[0].flag = HA_NOSAME; keyinfo[0].flag = HA_NOSAME;
deleted=0; deleted=0;
bzero((gptr) flags,sizeof(flags)); bzero((gptr) flags,sizeof(flags));
printf("- Creating heap-file\n"); printf("- Creating heap-file\n");
heap_create(filename); if (heap_create(filename,1,keyinfo,30,(ulong) flag*100000l,10l,
if (!(file=heap_open(filename,2,1,keyinfo,30,(ulong) flag*100000l,10l))) &hp_create_info) ||
!(file= heap_open(filename, 2)))
goto err; goto err;
printf("- Writing records:s\n"); printf("- Writing records:s\n");
strmov(record," ..... key "); strmov(record," ..... key ");
...@@ -77,7 +83,7 @@ int main(int argc, char **argv) ...@@ -77,7 +83,7 @@ int main(int argc, char **argv)
if (heap_close(file)) if (heap_close(file))
goto err; goto err;
printf("- Reopening file\n"); printf("- Reopening file\n");
if (!(file=heap_open(filename,2,1,keyinfo,30,(ulong) flag*100000l,10l))) if (!(file=heap_open(filename, 2)))
goto err; goto err;
printf("- Removing records\n"); printf("- Removing records\n");
...@@ -85,7 +91,7 @@ int main(int argc, char **argv) ...@@ -85,7 +91,7 @@ int main(int argc, char **argv)
{ {
if (i == remove_ant) { VOID(heap_close(file)) ; return (0) ; } if (i == remove_ant) { VOID(heap_close(file)) ; return (0) ; }
sprintf(key,"%6d",(j=(int) ((rand() & 32767)/32767.*25))); sprintf(key,"%6d",(j=(int) ((rand() & 32767)/32767.*25)));
if ((error = heap_rkey(file,record,0,key))) if ((error = heap_rkey(file,record,0,key,0,6)))
{ {
if (verbose || (flags[j] == 1 || if (verbose || (flags[j] == 1 ||
(error && my_errno != HA_ERR_KEY_NOT_FOUND))) (error && my_errno != HA_ERR_KEY_NOT_FOUND)))
...@@ -113,7 +119,7 @@ int main(int argc, char **argv) ...@@ -113,7 +119,7 @@ int main(int argc, char **argv)
sprintf(key,"%6d",i); sprintf(key,"%6d",i);
bmove(record+1,key,6); bmove(record+1,key,6);
my_errno=0; my_errno=0;
error=heap_rkey(file,record,0,key); error=heap_rkey(file,record,0,key,0,6);
if (verbose || if (verbose ||
(error == 0 && flags[i] != 1) || (error == 0 && flags[i] != 1) ||
(error && (flags[i] != 0 || my_errno != HA_ERR_KEY_NOT_FOUND))) (error && (flags[i] != 0 || my_errno != HA_ERR_KEY_NOT_FOUND)))
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#define SAFEMALLOC #define SAFEMALLOC
#endif #endif
#include "heapdef.h" /* Because of _hp_find_block */ #include "heapdef.h" /* Because of hp_find_block */
#include <signal.h> #include <signal.h>
#define MAX_RECORDS 100000 #define MAX_RECORDS 100000
...@@ -61,8 +61,9 @@ int main(int argc, char *argv[]) ...@@ -61,8 +61,9 @@ int main(int argc, char *argv[])
const char *filename,*filename2; const char *filename,*filename2;
HP_INFO *file,*file2; HP_INFO *file,*file2;
HP_KEYDEF keyinfo[MAX_KEYS]; HP_KEYDEF keyinfo[MAX_KEYS];
HP_KEYSEG keyseg[MAX_KEYS*5]; HA_KEYSEG keyseg[MAX_KEYS*5];
HEAP_PTR position; HEAP_PTR position;
HP_CREATE_INFO hp_create_info;
MY_INIT(argv[0]); /* init my_sys library & pthreads */ MY_INIT(argv[0]); /* init my_sys library & pthreads */
LINT_INIT(position); LINT_INIT(position);
...@@ -70,6 +71,8 @@ int main(int argc, char *argv[]) ...@@ -70,6 +71,8 @@ int main(int argc, char *argv[])
filename2= "test2_2"; filename2= "test2_2";
file=file2=0; file=file2=0;
get_options(argc,argv); get_options(argc,argv);
bzero(&hp_create_info, sizeof(hp_create_info));
write_count=update=opt_delete=0; write_count=update=opt_delete=0;
key_check=0; key_check=0;
...@@ -77,45 +80,53 @@ int main(int argc, char *argv[]) ...@@ -77,45 +80,53 @@ int main(int argc, char *argv[])
keyinfo[0].seg=keyseg; keyinfo[0].seg=keyseg;
keyinfo[0].keysegs=1; keyinfo[0].keysegs=1;
keyinfo[0].flag= 0; keyinfo[0].flag= 0;
keyinfo[0].algorithm= HA_KEY_ALG_HASH;
keyinfo[0].seg[0].type=HA_KEYTYPE_BINARY; keyinfo[0].seg[0].type=HA_KEYTYPE_BINARY;
keyinfo[0].seg[0].start=0; keyinfo[0].seg[0].start=0;
keyinfo[0].seg[0].length=6; keyinfo[0].seg[0].length=6;
keyinfo[0].seg[0].null_bit=0; keyinfo[0].seg[0].null_bit=0;
keyinfo[0].seg[0].charset=default_charset_info;
keyinfo[1].seg=keyseg+1; keyinfo[1].seg=keyseg+1;
keyinfo[1].keysegs=2; keyinfo[1].keysegs=2;
keyinfo[1].flag=0; keyinfo[1].flag=0;
keyinfo[1].algorithm= HA_KEY_ALG_HASH;
keyinfo[1].seg[0].type=HA_KEYTYPE_BINARY; keyinfo[1].seg[0].type=HA_KEYTYPE_BINARY;
keyinfo[1].seg[0].start=7; keyinfo[1].seg[0].start=7;
keyinfo[1].seg[0].length=6; keyinfo[1].seg[0].length=6;
keyinfo[1].seg[0].null_bit=0; keyinfo[1].seg[0].null_bit=0;
keyinfo[1].seg[0].charset=default_charset_info;
keyinfo[1].seg[1].type=HA_KEYTYPE_TEXT; keyinfo[1].seg[1].type=HA_KEYTYPE_TEXT;
keyinfo[1].seg[1].start=0; /* key in two parts */ keyinfo[1].seg[1].start=0; /* key in two parts */
keyinfo[1].seg[1].length=6; keyinfo[1].seg[1].length=6;
keyinfo[1].seg[1].null_bit=0; keyinfo[1].seg[1].null_bit=0;
keyinfo[1].seg[1].charset=default_charset_info;
keyinfo[2].seg=keyseg+3; keyinfo[2].seg=keyseg+3;
keyinfo[2].keysegs=1; keyinfo[2].keysegs=1;
keyinfo[2].flag=HA_NOSAME; keyinfo[2].flag=HA_NOSAME;
keyinfo[2].algorithm= HA_KEY_ALG_HASH;
keyinfo[2].seg[0].type=HA_KEYTYPE_BINARY; keyinfo[2].seg[0].type=HA_KEYTYPE_BINARY;
keyinfo[2].seg[0].start=12; keyinfo[2].seg[0].start=12;
keyinfo[2].seg[0].length=8; keyinfo[2].seg[0].length=8;
keyinfo[2].seg[0].null_bit=0; keyinfo[2].seg[0].null_bit=0;
keyinfo[2].seg[0].charset=default_charset_info;
keyinfo[3].seg=keyseg+4;
keyinfo[3].keysegs=1; keyinfo[3].keysegs=1;
keyinfo[3].flag=HA_NOSAME; keyinfo[3].flag=HA_NOSAME;
keyinfo[3].seg=keyseg+4; keyinfo[3].algorithm= HA_KEY_ALG_HASH;
keyinfo[3].seg[0].type=HA_KEYTYPE_BINARY; keyinfo[3].seg[0].type=HA_KEYTYPE_BINARY;
keyinfo[3].seg[0].start=37; keyinfo[3].seg[0].start=37;
keyinfo[3].seg[0].length=1; keyinfo[3].seg[0].length=1;
keyinfo[3].seg[0].null_bit=1; keyinfo[3].seg[0].null_bit=1;
keyinfo[3].seg[0].null_pos=38; keyinfo[3].seg[0].null_pos=38;
keyinfo[3].seg[0].charset=default_charset_info;
bzero((char*) key1,sizeof(key1)); bzero((char*) key1,sizeof(key1));
bzero((char*) key3,sizeof(key3)); bzero((char*) key3,sizeof(key3));
printf("- Creating heap-file\n"); printf("- Creating heap-file\n");
if (heap_create(filename)) if (heap_create(filename,keys,keyinfo,reclength,(ulong) flag*100000L,
goto err; (ulong) recant/2, &hp_create_info) ||
if (!(file=heap_open(filename,2,keys,keyinfo,reclength,(ulong) flag*100000L, !(file= heap_open(filename, 2)))
(ulong) recant/2)))
goto err; goto err;
signal(SIGINT,endprog); signal(SIGINT,endprog);
...@@ -167,14 +178,14 @@ int main(int argc, char *argv[]) ...@@ -167,14 +178,14 @@ int main(int argc, char *argv[])
if (j != 0) if (j != 0)
{ {
sprintf(key,"%6d",j); sprintf(key,"%6d",j);
if (heap_rkey(file,record,0,key)) if (heap_rkey(file,record,0,key,6,0))
{ {
printf("can't find key1: \"%s\"\n",key); printf("can't find key1: \"%s\"\n",key);
goto err; goto err;
} }
#ifdef NOT_USED #ifdef NOT_USED
if (file->current_ptr == _hp_find_block(&file->s->block,0) || if (file->current_ptr == hp_find_block(&file->s->block,0) ||
file->current_ptr == _hp_find_block(&file->s->block,1)) file->current_ptr == hp_find_block(&file->s->block,1))
continue; /* Don't remove 2 first records */ continue; /* Don't remove 2 first records */
#endif #endif
if (heap_delete(file,record)) if (heap_delete(file,record))
...@@ -227,7 +238,7 @@ int main(int argc, char *argv[]) ...@@ -227,7 +238,7 @@ int main(int argc, char *argv[])
if (!key1[j]) if (!key1[j])
continue; continue;
sprintf(key,"%6d",j); sprintf(key,"%6d",j);
if (heap_rkey(file,record,0,key)) if (heap_rkey(file,record,0,key,6,0))
{ {
printf("can't find key1: \"%s\"\n",key); printf("can't find key1: \"%s\"\n",key);
goto err; goto err;
...@@ -277,7 +288,7 @@ int main(int argc, char *argv[]) ...@@ -277,7 +288,7 @@ int main(int argc, char *argv[])
printf("- Read first key - next - delete - next -> last\n"); printf("- Read first key - next - delete - next -> last\n");
DBUG_PRINT("progpos",("first - next - delete - next -> last")); DBUG_PRINT("progpos",("first - next - delete - next -> last"));
if (heap_rkey(file,record,0,key)) if (heap_rkey(file,record,0,key,6,0))
goto err; goto err;
if (heap_rnext(file,record3)) goto err; if (heap_rnext(file,record3)) goto err;
if (heap_delete(file,record3)) goto err; if (heap_delete(file,record3)) goto err;
...@@ -306,7 +317,7 @@ int main(int argc, char *argv[]) ...@@ -306,7 +317,7 @@ int main(int argc, char *argv[])
if (!silent) if (!silent)
printf("- Read last key - delete - prev - prev - opt_delete - prev -> first\n"); printf("- Read last key - delete - prev - prev - opt_delete - prev -> first\n");
if (heap_rlast(file,record3)) goto err; if (heap_rlast(file,record3,0)) goto err;
if (heap_delete(file,record3)) goto err; if (heap_delete(file,record3)) goto err;
key_check-=atoi(record3); key_check-=atoi(record3);
key1[atoi(record+keyinfo[0].seg[0].start)]--; key1[atoi(record+keyinfo[0].seg[0].start)]--;
...@@ -501,7 +512,7 @@ int main(int argc, char *argv[]) ...@@ -501,7 +512,7 @@ int main(int argc, char *argv[])
} }
printf("- Read through all keys with first-next-last-prev\n"); printf("- Read through all keys with first-next-last-prev\n");
ant=0; ant=0;
for (error=heap_rkey(file,record,0,key) ; for (error=heap_rkey(file,record,0,key,6,0);
! error ; ! error ;
error=heap_rnext(file,record)) error=heap_rnext(file,record))
ant++; ant++;
...@@ -513,7 +524,7 @@ int main(int argc, char *argv[]) ...@@ -513,7 +524,7 @@ int main(int argc, char *argv[])
} }
ant=0; ant=0;
for (error=heap_rlast(file,record) ; for (error=heap_rlast(file,record,0) ;
! error ; ! error ;
error=heap_rprev(file,record)) error=heap_rprev(file,record))
{ {
...@@ -530,7 +541,7 @@ int main(int argc, char *argv[]) ...@@ -530,7 +541,7 @@ int main(int argc, char *argv[])
if (testflag == 4) goto end; if (testflag == 4) goto end;
printf("- Reading through all rows through keys\n"); printf("- Reading through all rows through keys\n");
if (!(file2=heap_open(filename,2,0,0,0,0,0))) if (!(file2=heap_open(filename, 2)))
goto err; goto err;
if (heap_scan_init(file)) if (heap_scan_init(file))
goto err; goto err;
...@@ -538,7 +549,7 @@ int main(int argc, char *argv[]) ...@@ -538,7 +549,7 @@ int main(int argc, char *argv[])
{ {
if (error == 0) if (error == 0)
{ {
if (heap_rkey(file2,record2,2,record+keyinfo[2].seg[0].start)) if (heap_rkey(file2,record2,2,record+keyinfo[2].seg[0].start,8,0))
{ {
printf("can't find key3: \"%.8s\"\n", printf("can't find key3: \"%.8s\"\n",
record+keyinfo[2].seg[0].start); record+keyinfo[2].seg[0].start);
...@@ -549,7 +560,8 @@ int main(int argc, char *argv[]) ...@@ -549,7 +560,8 @@ int main(int argc, char *argv[])
heap_close(file2); heap_close(file2);
printf("- Creating output heap-file 2\n"); printf("- Creating output heap-file 2\n");
if (!(file2=heap_open(filename2,2,1,keyinfo,reclength,0L,0L))) if (heap_create(filename2,1,keyinfo,reclength,0L,0L,&hp_create_info) ||
!(file2= heap_open(filename2, 2)))
goto err; goto err;
printf("- Copying and removing records\n"); printf("- Copying and removing records\n");
......
...@@ -20,47 +20,63 @@ ...@@ -20,47 +20,63 @@
int heap_update(HP_INFO *info, const byte *old, const byte *heap_new) int heap_update(HP_INFO *info, const byte *old, const byte *heap_new)
{ {
uint key; HP_KEYDEF *keydef, *end, *p_lastinx;
byte *pos; byte *pos;
HP_SHARE *share=info->s; bool auto_key_changed= 0;
HP_SHARE *share= info->s;
DBUG_ENTER("heap_update"); DBUG_ENTER("heap_update");
test_active(info); test_active(info);
pos=info->current_ptr; pos=info->current_ptr;
if (info->opt_flag & READ_CHECK_USED && _hp_rectest(info,old)) if (info->opt_flag & READ_CHECK_USED && hp_rectest(info,old))
DBUG_RETURN(my_errno); /* Record changed */ DBUG_RETURN(my_errno); /* Record changed */
if (--(share->records) < share->blength >> 1) share->blength>>= 1; if (--(share->records) < share->blength >> 1) share->blength>>= 1;
share->changed=1; share->changed=1;
for (key=0 ; key < share->keys ; key++) p_lastinx= share->keydef + info->lastinx;
for (keydef= share->keydef, end= keydef + share->keys; keydef < end; keydef++)
{ {
if (_hp_rec_key_cmp(share->keydef+key,old,heap_new)) if (hp_rec_key_cmp(keydef, old, heap_new))
{ {
if (_hp_delete_key(info,share->keydef+key,old,pos,key == if ((*keydef->delete_key)(info, keydef, old, pos, keydef == p_lastinx) ||
(uint) info->lastinx) || (*keydef->write_key)(info, keydef, heap_new, pos))
_hp_write_key(share,share->keydef+key,heap_new,pos)) goto err;
goto err; if (share->auto_key == (uint) (keydef - share->keydef + 1))
auto_key_changed= 1;
} }
} }
memcpy(pos,heap_new,(size_t) share->reclength); memcpy(pos,heap_new,(size_t) share->reclength);
if (++(share->records) == share->blength) share->blength+= share->blength; if (++(share->records) == share->blength) share->blength+= share->blength;
if (auto_key_changed)
heap_update_auto_increment(info, heap_new);
DBUG_RETURN(0); DBUG_RETURN(0);
err: err:
if (my_errno == HA_ERR_FOUND_DUPP_KEY) if (my_errno == HA_ERR_FOUND_DUPP_KEY)
{ {
info->errkey=key; info->errkey = keydef - share->keydef;
do if (keydef->algorithm == HA_KEY_ALG_BTREE)
{ {
if (_hp_rec_key_cmp(share->keydef+key,old,heap_new)) /* we don't need to delete non-inserted key from rb-tree */
if ((*keydef->write_key)(info, keydef, old, pos))
{ {
if (_hp_delete_key(info,share->keydef+key,heap_new,pos,0) || if (++(share->records) == share->blength) share->blength+= share->blength;
_hp_write_key(share,share->keydef+key,old,pos)) DBUG_RETURN(my_errno);
}
keydef--;
}
while (keydef >= share->keydef)
{
if (hp_rec_key_cmp(keydef, old, heap_new))
{
if ((*keydef->delete_key)(info, keydef, heap_new, pos, 0) ||
(*keydef->write_key)(info, keydef, old, pos))
break; break;
} }
} while (key-- > 0); keydef--;
}
} }
if (++(share->records) == share->blength) share->blength+= share->blength; if (++(share->records) == share->blength) share->blength+= share->blength;
DBUG_RETURN(my_errno); DBUG_RETURN(my_errno);
......
...@@ -27,12 +27,12 @@ ...@@ -27,12 +27,12 @@
#define HIGHUSED 8 #define HIGHUSED 8
static byte *next_free_record_pos(HP_SHARE *info); static byte *next_free_record_pos(HP_SHARE *info);
static HASH_INFO *_hp_find_free_hash(HP_SHARE *info, HP_BLOCK *block, static HASH_INFO *hp_find_free_hash(HP_SHARE *info, HP_BLOCK *block,
ulong records); ulong records);
int heap_write(HP_INFO *info, const byte *record) int heap_write(HP_INFO *info, const byte *record)
{ {
uint key; HP_KEYDEF *keydef, *end;
byte *pos; byte *pos;
HP_SHARE *share=info->s; HP_SHARE *share=info->s;
DBUG_ENTER("heap_write"); DBUG_ENTER("heap_write");
...@@ -47,9 +47,10 @@ int heap_write(HP_INFO *info, const byte *record) ...@@ -47,9 +47,10 @@ int heap_write(HP_INFO *info, const byte *record)
DBUG_RETURN(my_errno); DBUG_RETURN(my_errno);
share->changed=1; share->changed=1;
for (key=0 ; key < share->keys ; key++) for (keydef = share->keydef, end = keydef + share->keys; keydef < end;
keydef++)
{ {
if (_hp_write_key(share,share->keydef+key,record,pos)) if ((*keydef->write_key)(info, keydef, record, pos))
goto err; goto err;
} }
...@@ -60,15 +61,23 @@ int heap_write(HP_INFO *info, const byte *record) ...@@ -60,15 +61,23 @@ int heap_write(HP_INFO *info, const byte *record)
info->current_ptr=pos; info->current_ptr=pos;
info->current_hash_ptr=0; info->current_hash_ptr=0;
info->update|=HA_STATE_AKTIV; info->update|=HA_STATE_AKTIV;
if (share->auto_key)
heap_update_auto_increment(info, record);
DBUG_RETURN(0); DBUG_RETURN(0);
err: err:
DBUG_PRINT("info",("Duplicate key: %d",key)); DBUG_PRINT("info",("Duplicate key: %d", keydef - share->keydef));
info->errkey= key; info->errkey= keydef - share->keydef;
do if (keydef->algorithm == HA_KEY_ALG_BTREE)
{ {
if (_hp_delete_key(info,share->keydef+key,record,pos,0)) /* we don't need to delete non-inserted key from rb-tree */
keydef--;
}
while (keydef >= share->keydef)
{
if ((*keydef->delete_key)(info, keydef, record, pos, 0))
break; break;
} while (key-- > 0); keydef--;
}
share->deleted++; share->deleted++;
*((byte**) pos)=share->del_link; *((byte**) pos)=share->del_link;
...@@ -77,6 +86,36 @@ int heap_write(HP_INFO *info, const byte *record) ...@@ -77,6 +86,36 @@ int heap_write(HP_INFO *info, const byte *record)
DBUG_RETURN(my_errno); DBUG_RETURN(my_errno);
} /* heap_write */ } /* heap_write */
/*
Write a key to rb_tree-index
*/
int hp_rb_write_key(HP_INFO *info, HP_KEYDEF *keyinfo, const byte *record,
byte *recpos)
{
heap_rb_param custom_arg;
info->last_pos= NULL; /* For heap_rnext/heap_rprev */
custom_arg.keyseg= keyinfo->seg;
custom_arg.key_length= hp_rb_make_key(keyinfo, info->recbuf, record, recpos);
if (keyinfo->flag & HA_NOSAME)
{
custom_arg.search_flag= SEARCH_FIND | SEARCH_SAME;
keyinfo->rb_tree.flag= TREE_NO_DUPS;
}
else
{
custom_arg.search_flag= SEARCH_SAME;
keyinfo->rb_tree.flag= 0;
}
if (!tree_insert(&keyinfo->rb_tree, (void*)info->recbuf,
custom_arg.key_length, &custom_arg))
{
my_errno= HA_ERR_FOUND_DUPP_KEY;
return 1;
}
return 0;
}
/* Find where to place new record */ /* Find where to place new record */
...@@ -102,7 +141,7 @@ static byte *next_free_record_pos(HP_SHARE *info) ...@@ -102,7 +141,7 @@ static byte *next_free_record_pos(HP_SHARE *info)
my_errno=HA_ERR_RECORD_FILE_FULL; my_errno=HA_ERR_RECORD_FILE_FULL;
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
} }
if (_hp_get_new_block(&info->block,&length)) if (hp_get_new_block(&info->block,&length))
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
info->data_length+=length; info->data_length+=length;
} }
...@@ -113,12 +152,12 @@ static byte *next_free_record_pos(HP_SHARE *info) ...@@ -113,12 +152,12 @@ static byte *next_free_record_pos(HP_SHARE *info)
block_pos*info->block.recbuffer); block_pos*info->block.recbuffer);
} }
/* Write a hash-key to the hash-index */ /* Write a hash-key to the hash-index */
int _hp_write_key(register HP_SHARE *info, HP_KEYDEF *keyinfo, int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
const byte *record, byte *recpos) const byte *record, byte *recpos)
{ {
HP_SHARE *share = info->s;
int flag; int flag;
ulong halfbuff,hashnr,first_index; ulong halfbuff,hashnr,first_index;
byte *ptr_to_rec,*ptr_to_rec2; byte *ptr_to_rec,*ptr_to_rec2;
...@@ -129,18 +168,18 @@ int _hp_write_key(register HP_SHARE *info, HP_KEYDEF *keyinfo, ...@@ -129,18 +168,18 @@ int _hp_write_key(register HP_SHARE *info, HP_KEYDEF *keyinfo,
LINT_INIT(ptr_to_rec); LINT_INIT(ptr_to_rec2); LINT_INIT(ptr_to_rec); LINT_INIT(ptr_to_rec2);
flag=0; flag=0;
if (!(empty= _hp_find_free_hash(info,&keyinfo->block,info->records))) if (!(empty= hp_find_free_hash(share,&keyinfo->block,share->records)))
DBUG_RETURN(-1); /* No more memory */ DBUG_RETURN(-1); /* No more memory */
halfbuff= (long) info->blength >> 1; halfbuff= (long) share->blength >> 1;
pos= hp_find_hash(&keyinfo->block,(first_index=info->records-halfbuff)); pos= hp_find_hash(&keyinfo->block,(first_index=share->records-halfbuff));
if (pos != empty) /* If some records */ if (pos != empty) /* If some records */
{ {
do do
{ {
hashnr=_hp_rec_hashnr(keyinfo,pos->ptr_to_rec); hashnr = hp_rec_hashnr(keyinfo, pos->ptr_to_rec);
if (flag == 0) /* First loop; Check if ok */ if (flag == 0) /* First loop; Check if ok */
if (_hp_mask(hashnr,info->blength,info->records) != first_index) if (hp_mask(hashnr, share->blength, share->records) != first_index)
break; break;
if (!(hashnr & halfbuff)) if (!(hashnr & halfbuff))
{ /* Key will not move */ { /* Key will not move */
...@@ -212,8 +251,8 @@ int _hp_write_key(register HP_SHARE *info, HP_KEYDEF *keyinfo, ...@@ -212,8 +251,8 @@ int _hp_write_key(register HP_SHARE *info, HP_KEYDEF *keyinfo,
} }
/* Check if we are at the empty position */ /* Check if we are at the empty position */
pos=hp_find_hash(&keyinfo->block,_hp_mask(_hp_rec_hashnr(keyinfo,record), pos=hp_find_hash(&keyinfo->block, hp_mask(hp_rec_hashnr(keyinfo, record),
info->blength,info->records+1)); share->blength, share->records + 1));
if (pos == empty) if (pos == empty)
{ {
pos->ptr_to_rec=recpos; pos->ptr_to_rec=recpos;
...@@ -224,8 +263,8 @@ int _hp_write_key(register HP_SHARE *info, HP_KEYDEF *keyinfo, ...@@ -224,8 +263,8 @@ int _hp_write_key(register HP_SHARE *info, HP_KEYDEF *keyinfo,
/* Check if more records in same hash-nr family */ /* Check if more records in same hash-nr family */
empty[0]=pos[0]; empty[0]=pos[0];
gpos=hp_find_hash(&keyinfo->block, gpos=hp_find_hash(&keyinfo->block,
_hp_mask(_hp_rec_hashnr(keyinfo,pos->ptr_to_rec), hp_mask(hp_rec_hashnr(keyinfo, pos->ptr_to_rec),
info->blength,info->records+1)); share->blength, share->records + 1));
if (pos == gpos) if (pos == gpos)
{ {
pos->ptr_to_rec=recpos; pos->ptr_to_rec=recpos;
...@@ -235,7 +274,7 @@ int _hp_write_key(register HP_SHARE *info, HP_KEYDEF *keyinfo, ...@@ -235,7 +274,7 @@ int _hp_write_key(register HP_SHARE *info, HP_KEYDEF *keyinfo,
{ {
pos->ptr_to_rec=recpos; pos->ptr_to_rec=recpos;
pos->next_key=0; pos->next_key=0;
_hp_movelink(pos,gpos,empty); hp_movelink(pos, gpos, empty);
} }
/* Check if duplicated keys */ /* Check if duplicated keys */
...@@ -246,7 +285,7 @@ int _hp_write_key(register HP_SHARE *info, HP_KEYDEF *keyinfo, ...@@ -246,7 +285,7 @@ int _hp_write_key(register HP_SHARE *info, HP_KEYDEF *keyinfo,
pos=empty; pos=empty;
do do
{ {
if (! _hp_rec_key_cmp(keyinfo,record,pos->ptr_to_rec)) if (! hp_rec_key_cmp(keyinfo, record, pos->ptr_to_rec))
{ {
DBUG_RETURN(my_errno=HA_ERR_FOUND_DUPP_KEY); DBUG_RETURN(my_errno=HA_ERR_FOUND_DUPP_KEY);
} }
...@@ -258,7 +297,7 @@ int _hp_write_key(register HP_SHARE *info, HP_KEYDEF *keyinfo, ...@@ -258,7 +297,7 @@ int _hp_write_key(register HP_SHARE *info, HP_KEYDEF *keyinfo,
/* Returns ptr to block, and allocates block if neaded */ /* Returns ptr to block, and allocates block if neaded */
static HASH_INFO *_hp_find_free_hash(HP_SHARE *info, static HASH_INFO *hp_find_free_hash(HP_SHARE *info,
HP_BLOCK *block, ulong records) HP_BLOCK *block, ulong records)
{ {
uint block_pos; uint block_pos;
...@@ -268,7 +307,7 @@ static HASH_INFO *_hp_find_free_hash(HP_SHARE *info, ...@@ -268,7 +307,7 @@ static HASH_INFO *_hp_find_free_hash(HP_SHARE *info,
return hp_find_hash(block,records); return hp_find_hash(block,records);
if (!(block_pos=(records % block->records_in_block))) if (!(block_pos=(records % block->records_in_block)))
{ {
if (_hp_get_new_block(block,&length)) if (hp_get_new_block(block,&length))
return(NULL); return(NULL);
info->index_length+=length; info->index_length+=length;
} }
......
...@@ -28,7 +28,8 @@ noinst_HEADERS = config-win.h config-os2.h \ ...@@ -28,7 +28,8 @@ noinst_HEADERS = config-win.h config-os2.h \
my_dir.h mysys_err.h my_base.h \ my_dir.h mysys_err.h my_base.h \
my_nosys.h my_alarm.h queues.h rijndael.h sha1.h \ my_nosys.h my_alarm.h queues.h rijndael.h sha1.h \
my_aes.h my_tree.h hash.h thr_alarm.h \ my_aes.h my_tree.h hash.h thr_alarm.h \
thr_lock.h t_ctype.h violite.h md5.h mysql_version.h.in thr_lock.h t_ctype.h violite.h md5.h \
mysql_version.h.in my_handler.h
# mysql_version.h are generated # mysql_version.h are generated
SUPERCLEANFILES = mysql_version.h my_config.h SUPERCLEANFILES = mysql_version.h my_config.h
......
...@@ -61,3 +61,14 @@ extern const char *client_errors[]; /* Error messages */ ...@@ -61,3 +61,14 @@ extern const char *client_errors[]; /* Error messages */
#define CR_PROBE_SLAVE_HOSTS 2023 #define CR_PROBE_SLAVE_HOSTS 2023
#define CR_PROBE_SLAVE_CONNECT 2024 #define CR_PROBE_SLAVE_CONNECT 2024
#define CR_PROBE_MASTER_CONNECT 2025 #define CR_PROBE_MASTER_CONNECT 2025
/* new 4.1 error codes */
#define CR_INVALID_CONN_HANDLE 2026
#define CR_NULL_POINTER 2027
#define CR_NO_PREPARE_STMT 2028
#define CR_NOT_ALL_PARAMS_BOUND 2029
#define CR_DATA_TRUNCATED 2030
#define CR_NO_PARAMETERS_EXISTS 2031
#define CR_INVALID_PARAMETER_NO 2032
#define CR_INVALID_BUFFER_USE 2033
#define CR_UNSUPPORTED_PARAM_TYPE 2034
...@@ -40,13 +40,15 @@ typedef struct st_hash { ...@@ -40,13 +40,15 @@ typedef struct st_hash {
DYNAMIC_ARRAY array; /* Place for hash_keys */ DYNAMIC_ARRAY array; /* Place for hash_keys */
hash_get_key get_key; hash_get_key get_key;
void (*free)(void *); void (*free)(void *);
uint (*calc_hashnr)(const byte *key,uint length); uint (*calc_hashnr)(CHARSET_INFO *cs, const byte *key,uint length);
CHARSET_INFO *charset;
} HASH; } HASH;
#define hash_init(A,B,C,D,E,F,G) _hash_init(A,B,C,D,E,F,G CALLER_INFO) #define hash_init(A,B,C,D,E,F,G,H) _hash_init(A,B,C,D,E,F,G, H CALLER_INFO)
my_bool _hash_init(HASH *hash,uint default_array_elements, uint key_offset, my_bool _hash_init(HASH *hash, CHARSET_INFO *charset,
uint key_length, hash_get_key get_key, uint default_array_elements, uint key_offset,
void (*free_element)(void*), uint flags CALLER_INFO_PROTO); uint key_length, hash_get_key get_key,
void (*free_element)(void*), uint flags CALLER_INFO_PROTO);
void hash_free(HASH *tree); void hash_free(HASH *tree);
byte *hash_element(HASH *hash,uint idx); byte *hash_element(HASH *hash,uint idx);
gptr hash_search(HASH *info,const byte *key,uint length); gptr hash_search(HASH *info,const byte *key,uint length);
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file should be included when using heap_database_funktions */ /* This file should be included when using heap_database_functions */
/* Author: Michael Widenius */ /* Author: Michael Widenius */
#ifndef _heap_h #ifndef _heap_h
...@@ -31,6 +31,9 @@ extern "C" { ...@@ -31,6 +31,9 @@ extern "C" {
#include <thr_lock.h> #include <thr_lock.h>
#endif #endif
#include "my_handler.h"
#include "my_tree.h"
/* defines used by heap-funktions */ /* defines used by heap-funktions */
#define HP_MAX_LEVELS 4 /* 128^5 records is enough */ #define HP_MAX_LEVELS 4 /* 128^5 records is enough */
...@@ -47,6 +50,7 @@ typedef struct st_heapinfo /* Struct from heap_info */ ...@@ -47,6 +50,7 @@ typedef struct st_heapinfo /* Struct from heap_info */
ulong index_length; ulong index_length;
uint reclength; /* Length of one record */ uint reclength; /* Length of one record */
int errkey; int errkey;
ulonglong auto_increment;
} HEAPINFO; } HEAPINFO;
...@@ -73,22 +77,22 @@ typedef struct st_heap_block /* The data is saved in blocks */ ...@@ -73,22 +77,22 @@ typedef struct st_heap_block /* The data is saved in blocks */
ulong last_allocated; /* Blocks allocated, used by keys */ ulong last_allocated; /* Blocks allocated, used by keys */
} HP_BLOCK; } HP_BLOCK;
typedef struct st_hp_keyseg /* Key-portion */ struct st_heap_info; /* For referense */
{
uint start; /* Start of key in record (from 0) */
uint length; /* Keylength */
uint type;
uint null_bit; /* bit set in row+null_pos */
uint null_pos;
} HP_KEYSEG;
typedef struct st_hp_keydef /* Key definition with open */ typedef struct st_hp_keydef /* Key definition with open */
{ {
uint flag; /* HA_NOSAME |HA_NULL_PART_KEY */ uint flag; /* HA_NOSAME |HA_NULL_PART_KEY */
uint keysegs; /* Number of key-segment */ uint keysegs; /* Number of key-segment */
uint length; /* Length of key (automatic) */ uint length; /* Length of key (automatic) */
HP_KEYSEG *seg; uint8 algorithm; /* HASH / BTREE */
HA_KEYSEG *seg;
HP_BLOCK block; /* Where keys are saved */ HP_BLOCK block; /* Where keys are saved */
TREE rb_tree;
int (*write_key)(struct st_heap_info *info, struct st_hp_keydef *keyinfo,
const byte *record, byte *recpos);
int (*delete_key)(struct st_heap_info *info, struct st_hp_keydef *keyinfo,
const byte *record, byte *recpos, int flag);
uint (*get_key_length)(struct st_hp_keydef *keydef, const byte *key);
} HP_KEYDEF; } HP_KEYDEF;
typedef struct st_heap_share typedef struct st_heap_share
...@@ -112,6 +116,9 @@ typedef struct st_heap_share ...@@ -112,6 +116,9 @@ typedef struct st_heap_share
#endif #endif
my_bool delete_on_close; my_bool delete_on_close;
LIST open_list; LIST open_list;
uint auto_key;
uint auto_key_type; /* real type of the auto key segment */
ulonglong auto_increment;
} HP_SHARE; } HP_SHARE;
struct st_hp_hash_info; struct st_hp_hash_info;
...@@ -126,17 +133,27 @@ typedef struct st_heap_info ...@@ -126,17 +133,27 @@ typedef struct st_heap_info
int mode; /* Mode of file (READONLY..) */ int mode; /* Mode of file (READONLY..) */
uint opt_flag,update; uint opt_flag,update;
byte *lastkey; /* Last used key with rkey */ byte *lastkey; /* Last used key with rkey */
byte *recbuf; /* Record buffer for rb-tree keys */
enum ha_rkey_function last_find_flag;
TREE_ELEMENT *parents[MAX_TREE_HEIGHT+1];
TREE_ELEMENT **last_pos;
uint lastkey_len;
#ifdef THREAD #ifdef THREAD
THR_LOCK_DATA lock; THR_LOCK_DATA lock;
#endif #endif
LIST open_list; LIST open_list;
} HP_INFO; } HP_INFO;
typedef struct st_heap_create_info
{
uint auto_key;
uint auto_key_type;
ulonglong auto_increment;
} HP_CREATE_INFO;
/* Prototypes for heap-functions */ /* Prototypes for heap-functions */
extern HP_INFO* heap_open(const char *name,int mode,uint keys, extern HP_INFO *heap_open(const char *name, int mode);
HP_KEYDEF *keydef,uint reclength,
ulong max_records,ulong min_reloc);
extern int heap_close(HP_INFO *info); extern int heap_close(HP_INFO *info);
extern int heap_write(HP_INFO *info,const byte *buff); extern int heap_write(HP_INFO *info,const byte *buff);
extern int heap_update(HP_INFO *info,const byte *old,const byte *newdata); extern int heap_update(HP_INFO *info,const byte *old,const byte *newdata);
...@@ -145,7 +162,9 @@ extern int heap_scan_init(HP_INFO *info); ...@@ -145,7 +162,9 @@ extern int heap_scan_init(HP_INFO *info);
extern int heap_scan(register HP_INFO *info, byte *record); extern int heap_scan(register HP_INFO *info, byte *record);
extern int heap_delete(HP_INFO *info,const byte *buff); extern int heap_delete(HP_INFO *info,const byte *buff);
extern int heap_info(HP_INFO *info,HEAPINFO *x,int flag); extern int heap_info(HP_INFO *info,HEAPINFO *x,int flag);
extern int heap_create(const char *name); extern int heap_create(const char *name, uint keys, HP_KEYDEF *keydef,
uint reclength, ulong max_records, ulong min_records,
HP_CREATE_INFO *create_info);
extern int heap_delete_table(const char *name); extern int heap_delete_table(const char *name);
extern int heap_extra(HP_INFO *info,enum ha_extra_function function); extern int heap_extra(HP_INFO *info,enum ha_extra_function function);
extern int heap_rename(const char *old_name,const char *new_name); extern int heap_rename(const char *old_name,const char *new_name);
...@@ -153,10 +172,17 @@ extern int heap_panic(enum ha_panic_function flag); ...@@ -153,10 +172,17 @@ extern int heap_panic(enum ha_panic_function flag);
extern int heap_rsame(HP_INFO *info,byte *record,int inx); extern int heap_rsame(HP_INFO *info,byte *record,int inx);
extern int heap_rnext(HP_INFO *info,byte *record); extern int heap_rnext(HP_INFO *info,byte *record);
extern int heap_rprev(HP_INFO *info,byte *record); extern int heap_rprev(HP_INFO *info,byte *record);
extern int heap_rfirst(HP_INFO *info,byte *record); extern int heap_rfirst(HP_INFO *info,byte *record,int inx);
extern int heap_rlast(HP_INFO *info,byte *record); extern int heap_rlast(HP_INFO *info,byte *record,int inx);
extern void heap_clear(HP_INFO *info); extern void heap_clear(HP_INFO *info);
extern int heap_rkey(HP_INFO *info,byte *record,int inx,const byte *key); extern void heap_update_auto_increment(HP_INFO *info, const byte *record);
ha_rows hp_rb_records_in_range(HP_INFO *info, int inx, const byte *start_key,
uint start_key_len,
enum ha_rkey_function start_search_flag,
const byte *end_key, uint end_key_len,
enum ha_rkey_function end_search_flag);
int heap_rkey(HP_INFO *info, byte *record, int inx, const byte *key,
uint key_len, enum ha_rkey_function find_flag);
extern gptr heap_find(HP_INFO *info,int inx,const byte *key); extern gptr heap_find(HP_INFO *info,int inx,const byte *key);
extern int heap_check_heap(HP_INFO *info, my_bool print_status); extern int heap_check_heap(HP_INFO *info, my_bool print_status);
extern byte *heap_position(HP_INFO *info); extern byte *heap_position(HP_INFO *info);
......
This diff is collapsed.
...@@ -150,9 +150,9 @@ enum ha_base_keytype { ...@@ -150,9 +150,9 @@ enum ha_base_keytype {
#define HA_PACK_KEY 2 /* Pack string key to previous key */ #define HA_PACK_KEY 2 /* Pack string key to previous key */
#define HA_AUTO_KEY 16 #define HA_AUTO_KEY 16
#define HA_BINARY_PACK_KEY 32 /* Packing of all keys to prev key */ #define HA_BINARY_PACK_KEY 32 /* Packing of all keys to prev key */
#define HA_FULLTEXT 128 /* SerG: for full-text search */ #define HA_FULLTEXT 128 /* For full-text search */
#define HA_UNIQUE_CHECK 256 /* Check the key for uniqueness */ #define HA_UNIQUE_CHECK 256 /* Check the key for uniqueness */
#define HA_SPATIAL 1024 /* Alex Barkov: for spatial search */ #define HA_SPATIAL 1024 /* For spatial search */
#define HA_NULL_ARE_EQUAL 2048 /* NULL in key are cmp as equal */ #define HA_NULL_ARE_EQUAL 2048 /* NULL in key are cmp as equal */
......
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA */
#ifndef _my_handler_h
#define _my_handler_h
#include "my_global.h"
#include "my_base.h"
#include "m_ctype.h"
#include "myisampack.h"
typedef struct st_HA_KEYSEG /* Key-portion */
{
uint8 type; /* Type of key (for sort) */
uint8 language;
uint8 null_bit; /* bitmask to test for NULL */
uint8 bit_start,bit_end; /* if bit field */
uint16 flag;
uint16 length; /* Keylength */
uint32 start; /* Start of key in record */
uint32 null_pos; /* position to NULL indicator */
CHARSET_INFO *charset;
} HA_KEYSEG;
#define get_key_length(length,key) \
{ if ((uchar) *(key) != 255) \
length= (uint) (uchar) *((key)++); \
else \
{ length=mi_uint2korr((key)+1); (key)+=3; } \
}
#define get_key_pack_length(length,length_pack,key) \
{ if ((uchar) *(key) != 255) \
{ length= (uint) (uchar) *((key)++); length_pack=1; }\
else \
{ length=mi_uint2korr((key)+1); (key)+=3; length_pack=3; } \
}
extern int mi_compare_text(CHARSET_INFO *, uchar *, uint, uchar *, uint ,
my_bool);
extern int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
register uchar *b, uint key_length, uint nextflag,
uint *diff_pos);
#endif /* _my_handler_h */
...@@ -105,13 +105,6 @@ extern int NEAR my_errno; /* Last error in mysys */ ...@@ -105,13 +105,6 @@ extern int NEAR my_errno; /* Last error in mysys */
#define MY_SEEK_CUR 1 #define MY_SEEK_CUR 1
#define MY_SEEK_END 2 #define MY_SEEK_END 2
/* My charsets_list flags */
#define MY_NO_SETS 0
#define MY_COMPILED_SETS 1 /* show compiled-in sets */
#define MY_CONFIG_SETS 2 /* sets that have a *.conf file */
#define MY_INDEX_SETS 4 /* all sets listed in the Index file */
#define MY_LOADED_SETS 8 /* the sets that are currently loaded */
/* Some constants */ /* Some constants */
#define MY_WAIT_FOR_USER_TO_FIX_PANIC 60 /* in seconds */ #define MY_WAIT_FOR_USER_TO_FIX_PANIC 60 /* in seconds */
#define MY_WAIT_GIVE_USER_A_MESSAGE 10 /* Every 10 times of prev */ #define MY_WAIT_GIVE_USER_A_MESSAGE 10 /* Every 10 times of prev */
...@@ -300,6 +293,14 @@ extern struct my_file_info ...@@ -300,6 +293,14 @@ extern struct my_file_info
#endif #endif
} my_file_info[MY_NFILE]; } my_file_info[MY_NFILE];
typedef struct st_my_tmpdir
{
char **list;
uint cur, max;
#ifdef THREAD
pthread_mutex_t mutex;
#endif
} MY_TMPDIR;
typedef struct st_dynamic_array typedef struct st_dynamic_array
{ {
...@@ -589,12 +590,11 @@ extern void allow_break(void); ...@@ -589,12 +590,11 @@ extern void allow_break(void);
#define allow_break() #define allow_break()
#endif #endif
extern my_bool init_tmpdir(MY_TMPDIR *tmpdir, const char *pathlist);
extern char *my_tmpdir(MY_TMPDIR *tmpdir);
extern void free_tmpdir(MY_TMPDIR *tmpdir);
extern void my_remember_signal(int signal_number,sig_handler (*func)(int)); extern void my_remember_signal(int signal_number,sig_handler (*func)(int));
extern void caseup(my_string str,uint length);
extern void casedn(my_string str,uint length);
extern void caseup_str(my_string str);
extern void casedn_str(my_string str);
extern void case_sort(my_string str,uint length);
extern uint dirname_part(my_string to,const char *name); extern uint dirname_part(my_string to,const char *name);
extern uint dirname_length(const char *name); extern uint dirname_length(const char *name);
#define base_name(A) (A+dirname_length(A)) #define base_name(A) (A+dirname_length(A))
...@@ -619,18 +619,12 @@ extern my_string my_path(my_string to,const char *progname, ...@@ -619,18 +619,12 @@ extern my_string my_path(my_string to,const char *progname,
extern my_string my_load_path(my_string to, const char *path, extern my_string my_load_path(my_string to, const char *path,
const char *own_path_prefix); const char *own_path_prefix);
extern int wild_compare(const char *str,const char *wildstr); extern int wild_compare(const char *str,const char *wildstr);
extern my_string my_strcasestr(const char *src,const char *suffix);
extern int my_strcasecmp(const char *s,const char *t);
extern int my_strsortcmp(const char *s,const char *t);
extern int my_casecmp(const char *s,const char *t,uint length);
extern int my_sortcmp(const char *s,const char *t,uint length);
extern int my_sortncmp(const char *s,uint s_len, const char *t,uint t_len);
extern WF_PACK *wf_comp(my_string str); extern WF_PACK *wf_comp(my_string str);
extern int wf_test(struct wild_file_pack *wf_pack,const char *name); extern int wf_test(struct wild_file_pack *wf_pack,const char *name);
extern void wf_end(struct wild_file_pack *buffer); extern void wf_end(struct wild_file_pack *buffer);
extern size_s strip_sp(my_string str); extern size_s strip_sp(my_string str);
extern void get_date(my_string to,int timeflag,time_t use_time); extern void get_date(my_string to,int timeflag,time_t use_time);
extern void soundex(my_string out_pntr, my_string in_pntr,pbool remove_garbage); extern void soundex(CHARSET_INFO *, my_string out_pntr, my_string in_pntr,pbool remove_garbage);
extern int init_record_cache(RECORD_CACHE *info,uint cachesize,File file, extern int init_record_cache(RECORD_CACHE *info,uint cachesize,File file,
uint reclength,enum cache_type type, uint reclength,enum cache_type type,
pbool use_async_io); pbool use_async_io);
......
...@@ -20,13 +20,17 @@ ...@@ -20,13 +20,17 @@
extern "C" { extern "C" {
#endif #endif
#define MAX_TREE_HIGHT 40 /* = max 1048576 leafs in tree */ #include "my_base.h" /* get 'enum ha_rkey_function' */
#define MAX_TREE_HEIGHT 40 /* = max 1048576 leafs in tree */
#define ELEMENT_KEY(tree,element)\ #define ELEMENT_KEY(tree,element)\
(tree->offset_to_key ? (void*)((byte*) element+tree->offset_to_key) :\ (tree->offset_to_key ? (void*)((byte*) element+tree->offset_to_key) :\
*((void**) (element+1))) *((void**) (element+1)))
#define tree_set_pointer(element,ptr) *((byte **) (element+1))=((byte*) (ptr)) #define tree_set_pointer(element,ptr) *((byte **) (element+1))=((byte*) (ptr))
#define TREE_NO_DUPS 1
typedef enum { left_root_right, right_root_left } TREE_WALK; typedef enum { left_root_right, right_root_left } TREE_WALK;
typedef uint32 element_count; typedef uint32 element_count;
typedef int (*tree_walk_action)(void *,element_count,void *); typedef int (*tree_walk_action)(void *,element_count,void *);
...@@ -48,15 +52,18 @@ typedef struct st_tree_element { ...@@ -48,15 +52,18 @@ typedef struct st_tree_element {
} TREE_ELEMENT; } TREE_ELEMENT;
#endif /* MSDOS */ #endif /* MSDOS */
#define ELEMENT_CHILD(element, offs) (*(TREE_ELEMENT**)((char*)element + offs))
typedef struct st_tree { typedef struct st_tree {
TREE_ELEMENT *root,null_element; TREE_ELEMENT *root,null_element;
TREE_ELEMENT **parents[MAX_TREE_HIGHT]; TREE_ELEMENT **parents[MAX_TREE_HEIGHT];
uint offset_to_key,elements_in_tree,size_of_element,memory_limit,allocated; uint offset_to_key,elements_in_tree,size_of_element,memory_limit,allocated;
qsort_cmp2 compare; qsort_cmp2 compare;
void* custom_arg; void *custom_arg;
MEM_ROOT mem_root; MEM_ROOT mem_root;
my_bool with_delete; my_bool with_delete;
tree_element_free free; tree_element_free free;
uint flag;
} TREE; } TREE;
/* Functions on whole tree */ /* Functions on whole tree */
...@@ -70,12 +77,22 @@ void reset_tree(TREE*); ...@@ -70,12 +77,22 @@ void reset_tree(TREE*);
#define is_tree_inited(tree) ((tree)->root != 0) #define is_tree_inited(tree) ((tree)->root != 0)
/* Functions on leafs */ /* Functions on leafs */
TREE_ELEMENT *tree_insert(TREE *tree,void *key,uint key_size); TREE_ELEMENT *tree_insert(TREE *tree,void *key, uint key_size,
void *tree_search(TREE *tree,void *key); void *custom_arg);
void *tree_search(TREE *tree, void *key, void *custom_arg);
int tree_walk(TREE *tree,tree_walk_action action, int tree_walk(TREE *tree,tree_walk_action action,
void *argument, TREE_WALK visit); void *argument, TREE_WALK visit);
int tree_delete(TREE *tree,void *key); int tree_delete(TREE *tree, void *key, void *custom_arg);
void *tree_search_key(TREE *tree, const void *key,
TREE_ELEMENT **parents, TREE_ELEMENT ***last_pos,
enum ha_rkey_function flag, void *custom_arg);
void *tree_search_edge(TREE *tree, TREE_ELEMENT **parents,
TREE_ELEMENT ***last_pos, int child_offs);
void *tree_search_next(TREE *tree, TREE_ELEMENT ***last_pos, int l_offs,
int r_offs);
uint tree_record_pos(TREE *tree, const void *key,
enum ha_rkey_function search_flag, void *custom_arg);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
......
...@@ -28,6 +28,7 @@ extern "C" { ...@@ -28,6 +28,7 @@ extern "C" {
#ifndef _m_ctype_h #ifndef _m_ctype_h
#include <m_ctype.h> #include <m_ctype.h>
#endif #endif
#include "my_handler.h"
/* defines used by myisam-funktions */ /* defines used by myisam-funktions */
...@@ -105,20 +106,6 @@ typedef struct st_mi_create_info ...@@ -105,20 +106,6 @@ typedef struct st_mi_create_info
struct st_myisam_info; /* For referense */ struct st_myisam_info; /* For referense */
typedef struct st_myisam_info MI_INFO; typedef struct st_myisam_info MI_INFO;
typedef struct st_mi_keyseg /* Key-portion */
{
uint8 type; /* Type of key (for sort) */
uint8 language;
uint8 null_bit; /* bitmask to test for NULL */
uint8 bit_start,bit_end; /* if bit field */
uint16 flag;
uint16 length; /* Keylength */
uint32 start; /* Start of key in record */
uint32 null_pos; /* position to NULL indicator */
CHARSET_INFO *charset;
} MI_KEYSEG;
struct st_mi_s_param; struct st_mi_s_param;
typedef struct st_mi_keydef /* Key definition with open & info */ typedef struct st_mi_keydef /* Key definition with open & info */
...@@ -135,7 +122,7 @@ typedef struct st_mi_keydef /* Key definition with open & info */ ...@@ -135,7 +122,7 @@ typedef struct st_mi_keydef /* Key definition with open & info */
uint16 block_size; /* block_size (auto) */ uint16 block_size; /* block_size (auto) */
uint32 version; /* For concurrent read/write */ uint32 version; /* For concurrent read/write */
MI_KEYSEG *seg,*end; HA_KEYSEG *seg,*end;
int (*bin_search)(struct st_myisam_info *info,struct st_mi_keydef *keyinfo, int (*bin_search)(struct st_myisam_info *info,struct st_mi_keydef *keyinfo,
uchar *page,uchar *key, uchar *page,uchar *key,
uint key_len,uint comp_flag,uchar * *ret_pos, uint key_len,uint comp_flag,uchar * *ret_pos,
...@@ -147,6 +134,8 @@ typedef struct st_mi_keydef /* Key definition with open & info */ ...@@ -147,6 +134,8 @@ typedef struct st_mi_keydef /* Key definition with open & info */
struct st_mi_s_param *s_temp); struct st_mi_s_param *s_temp);
void (*store_key)(struct st_mi_keydef *keyinfo, uchar *key_pos, void (*store_key)(struct st_mi_keydef *keyinfo, uchar *key_pos,
struct st_mi_s_param *s_temp); struct st_mi_s_param *s_temp);
int (*ck_insert)(struct st_myisam_info *inf, uint k_nr, uchar *k, uint klen);
int (*ck_delete)(struct st_myisam_info *inf, uint k_nr, uchar *k, uint klen);
} MI_KEYDEF; } MI_KEYDEF;
...@@ -157,7 +146,7 @@ typedef struct st_unique_def /* Segment definition of unique */ ...@@ -157,7 +146,7 @@ typedef struct st_unique_def /* Segment definition of unique */
uint16 keysegs; /* Number of key-segment */ uint16 keysegs; /* Number of key-segment */
uchar key; /* Mapped to which key */ uchar key; /* Mapped to which key */
uint8 null_are_equal; uint8 null_are_equal;
MI_KEYSEG *seg,*end; HA_KEYSEG *seg,*end;
} MI_UNIQUEDEF; } MI_UNIQUEDEF;
typedef struct st_mi_decode_tree /* Decode huff-table */ typedef struct st_mi_decode_tree /* Decode huff-table */
...@@ -321,6 +310,7 @@ typedef struct st_sort_key_blocks /* Used when sorting */ ...@@ -321,6 +310,7 @@ typedef struct st_sort_key_blocks /* Used when sorting */
int inited; int inited;
} SORT_KEY_BLOCKS; } SORT_KEY_BLOCKS;
typedef struct st_mi_check_param typedef struct st_mi_check_param
{ {
ulonglong auto_increment_value; ulonglong auto_increment_value;
...@@ -339,7 +329,8 @@ typedef struct st_mi_check_param ...@@ -339,7 +329,8 @@ typedef struct st_mi_check_param
uint8 language; uint8 language;
my_bool using_global_keycache, opt_lock_memory, opt_follow_links; my_bool using_global_keycache, opt_lock_memory, opt_follow_links;
my_bool retry_repair, force_sort, calc_checksum; my_bool retry_repair, force_sort, calc_checksum;
char temp_filename[FN_REFLEN],*isam_file_name,*tmpdir; char temp_filename[FN_REFLEN],*isam_file_name;
MY_TMPDIR *tmpdir;
int tmpfile_createflag; int tmpfile_createflag;
myf myf_rw; myf myf_rw;
IO_CACHE read_cache; IO_CACHE read_cache;
...@@ -386,7 +377,7 @@ typedef struct st_mi_sort_param ...@@ -386,7 +377,7 @@ typedef struct st_mi_sort_param
byte *rec_buff; byte *rec_buff;
void *wordlist, *wordptr; void *wordlist, *wordptr;
char *record; char *record;
char *tmpdir; MY_TMPDIR *tmpdir;
int (*key_cmp)(struct st_mi_sort_param *, const void *, const void *); int (*key_cmp)(struct st_mi_sort_param *, const void *, const void *);
int (*key_read)(struct st_mi_sort_param *,void *); int (*key_read)(struct st_mi_sort_param *,void *);
int (*key_write)(struct st_mi_sort_param *, const void *); int (*key_write)(struct st_mi_sort_param *, const void *);
......
This diff is collapsed.
This diff is collapsed.
...@@ -253,4 +253,9 @@ ...@@ -253,4 +253,9 @@
#define ER_CANT_USE_OPTION_HERE 1234 #define ER_CANT_USE_OPTION_HERE 1234
#define ER_NOT_SUPPORTED_YET 1235 #define ER_NOT_SUPPORTED_YET 1235
#define ER_MASTER_FATAL_ERROR_READING_BINLOG 1236 #define ER_MASTER_FATAL_ERROR_READING_BINLOG 1236
#define ER_ERROR_MESSAGES 237 #define ER_WRONG_FK_DEF 1237
#define ER_KEY_REF_DO_NOT_MATCH_TABLE_REF 1238
#define ER_SUBSELECT_NO_1_COL 1239
#define ER_SUBSELECT_NO_1_ROW 1240
#define ER_UNKNOWN_STMT_HANDLER 1241
#define ER_ERROR_MESSAGES 242
...@@ -54,11 +54,11 @@ uint _nisam_make_key(register N_INFO *info, uint keynr, uchar *key, const char * ...@@ -54,11 +54,11 @@ uint _nisam_make_key(register N_INFO *info, uint keynr, uchar *key, const char *
*key++= (uchar) (length=(uint) (end-pos)); *key++= (uchar) (length=(uint) (end-pos));
memcpy((byte*) key,(byte*) pos,(size_t) length); memcpy((byte*) key,(byte*) pos,(size_t) length);
#ifdef USE_STRCOLL #ifdef USE_STRCOLL
if (!use_strcoll(default_charset_info)) if (!use_strnxfrm(default_charset_info))
#endif #endif
{ {
if (type == HA_KEYTYPE_TEXT) if (type == HA_KEYTYPE_TEXT)
case_sort((byte*) key,length); my_tosort(default_charset_info,(byte*) key,length);
} }
key+=length; key+=length;
} }
...@@ -67,11 +67,11 @@ uint _nisam_make_key(register N_INFO *info, uint keynr, uchar *key, const char * ...@@ -67,11 +67,11 @@ uint _nisam_make_key(register N_INFO *info, uint keynr, uchar *key, const char *
memcpy((byte*) key,(byte*) record+keyseg->base.start, memcpy((byte*) key,(byte*) record+keyseg->base.start,
(size_t) keyseg->base.length); (size_t) keyseg->base.length);
#ifdef USE_STRCOLL #ifdef USE_STRCOLL
if (!use_strcoll(default_charset_info)) if (!use_strnxfrm(default_charset_info))
#endif #endif
{ {
if (type == HA_KEYTYPE_TEXT) if (type == HA_KEYTYPE_TEXT)
case_sort((byte*) key,(uint) keyseg->base.length); my_tosort(default_charset_info,(byte*) key,(uint) keyseg->base.length);
} }
#ifdef NAN_TEST #ifdef NAN_TEST
else if (type == HA_KEYTYPE_FLOAT) else if (type == HA_KEYTYPE_FLOAT)
...@@ -150,11 +150,11 @@ uint _nisam_pack_key(register N_INFO *info, uint keynr, uchar *key, uchar *old, ...@@ -150,11 +150,11 @@ uint _nisam_pack_key(register N_INFO *info, uint keynr, uchar *key, uchar *old,
else else
memcpy((byte*) key,old,(size_t) length); memcpy((byte*) key,old,(size_t) length);
#ifdef USE_STRCOLL #ifdef USE_STRCOLL
if (!use_strcoll(default_charset_info)) if (!use_strnxfrm(default_charset_info))
#endif #endif
{ {
if (type == HA_KEYTYPE_TEXT) if (type == HA_KEYTYPE_TEXT)
case_sort((byte*) key,length); my_tosort(default_charset_info,(byte*) key,length);
} }
key+= length; key+= length;
} }
......
...@@ -332,7 +332,7 @@ int _nisam_key_cmp(register N_KEYSEG *keyseg, register uchar *a, register uchar ...@@ -332,7 +332,7 @@ int _nisam_key_cmp(register N_KEYSEG *keyseg, register uchar *a, register uchar
end= a+ min(key_length,(uint) length); end= a+ min(key_length,(uint) length);
#ifdef USE_STRCOLL #ifdef USE_STRCOLL
if (use_strcoll(default_charset_info)) { if (use_strnxfrm(default_charset_info)) {
if (((enum ha_base_keytype) keyseg->base.type) == HA_KEYTYPE_BINARY) if (((enum ha_base_keytype) keyseg->base.type) == HA_KEYTYPE_BINARY)
{ {
while (a < end) while (a < end)
...@@ -383,7 +383,7 @@ int _nisam_key_cmp(register N_KEYSEG *keyseg, register uchar *a, register uchar ...@@ -383,7 +383,7 @@ int _nisam_key_cmp(register N_KEYSEG *keyseg, register uchar *a, register uchar
else else
{ {
#ifdef USE_STRCOLL #ifdef USE_STRCOLL
if (use_strcoll(default_charset_info)) { if (use_strnxfrm(default_charset_info)) {
if (((enum ha_base_keytype) keyseg->base.type) == HA_KEYTYPE_BINARY) if (((enum ha_base_keytype) keyseg->base.type) == HA_KEYTYPE_BINARY)
{ {
while (a < end) while (a < end)
...@@ -515,11 +515,13 @@ int _nisam_key_cmp(register N_KEYSEG *keyseg, register uchar *a, register uchar ...@@ -515,11 +515,13 @@ int _nisam_key_cmp(register N_KEYSEG *keyseg, register uchar *a, register uchar
if (*a++ != *b++) if (*a++ != *b++)
{ {
a--; b--; a--; b--;
if (isdigit((char) *a) && isdigit((char) *b)) if (my_isdigit(default_charset_info, (char) *a) &&
my_isdigit(default_charset_info, (char) *b))
return ((int) *a - (int) *b); return ((int) *a - (int) *b);
if (*a == '-' || isdigit((char) *b)) if (*a == '-' || my_isdigit(default_charset_info,(char) *b))
return (-1); return (-1);
if (*b == '-' || *b++ == ' ' || isdigit((char) *a)) if (*b == '-' || *b++ == ' ' ||
my_isdigit(default_charset_info,(char) *a))
return (1); return (1);
if (*a++ == ' ') if (*a++ == ' ')
return (-1); return (-1);
...@@ -539,11 +541,13 @@ int _nisam_key_cmp(register N_KEYSEG *keyseg, register uchar *a, register uchar ...@@ -539,11 +541,13 @@ int _nisam_key_cmp(register N_KEYSEG *keyseg, register uchar *a, register uchar
if (*a++ != *b++) if (*a++ != *b++)
{ {
a--; b--; a--; b--;
if (isdigit((char) *a) && isdigit((char) *b)) if (my_isdigit(default_charset_info,(char) *a) &&
my_isdigit(default_charset_info,(char) *b))
return ((int) *a - (int) *b); return ((int) *a - (int) *b);
if (*a == '-' || isdigit((char) *b)) if (*a == '-' || my_isdigit(default_charset_info,(char) *b))
return (-1); return (-1);
if (*b == '-' || *b++ == ' ' || isdigit((char) *a)) if (*b == '-' || *b++ == ' ' ||
my_isdigit(default_charset_info,(char) *a))
return (1); return (1);
if (*a++ == ' ') if (*a++ == ' ')
return -1; return -1;
......
...@@ -342,7 +342,7 @@ static int examine_log(my_string file_name, char **table_names) ...@@ -342,7 +342,7 @@ static int examine_log(my_string file_name, char **table_names)
file_info.process=0; file_info.process=0;
result=uint2korr(head+7); result=uint2korr(head+7);
if ((curr_file_info=(struct isamlog_file_info*) if ((curr_file_info=(struct isamlog_file_info*)
tree_search(&tree,&file_info))) tree_search(&tree, &file_info, tree.custom_arg)))
{ {
curr_file_info->accessed=access_time; curr_file_info->accessed=access_time;
if (update && curr_file_info->used && curr_file_info->closed) if (update && curr_file_info->used && curr_file_info->closed)
...@@ -444,7 +444,7 @@ static int examine_log(my_string file_name, char **table_names) ...@@ -444,7 +444,7 @@ static int examine_log(my_string file_name, char **table_names)
files_open++; files_open++;
file_info.closed=0; file_info.closed=0;
} }
VOID(tree_insert(&tree,(gptr) &file_info,0)); VOID(tree_insert(&tree, (gptr) &file_info, 0, tree.custom_arg));
if (file_info.used) if (file_info.used)
{ {
if (verbose && !record_pos_file) if (verbose && !record_pos_file)
...@@ -463,7 +463,7 @@ static int examine_log(my_string file_name, char **table_names) ...@@ -463,7 +463,7 @@ static int examine_log(my_string file_name, char **table_names)
{ {
if (!curr_file_info->closed) if (!curr_file_info->closed)
files_open--; files_open--;
VOID(tree_delete(&tree,(gptr) curr_file_info)); VOID(tree_delete(&tree, (gptr) curr_file_info, tree.custom_arg));
} }
break; break;
case LOG_EXTRA: case LOG_EXTRA:
......
This diff is collapsed.
...@@ -49,10 +49,6 @@ link_sources: ...@@ -49,10 +49,6 @@ link_sources:
rm -f $(srcdir)/$$f; \ rm -f $(srcdir)/$$f; \
@LN_CP_F@ $(srcdir)/../strings/$$f $(srcdir)/$$f; \ @LN_CP_F@ $(srcdir)/../strings/$$f $(srcdir)/$$f; \
done; \ done; \
for f in $(mystringsgen); do \
rm -f $(srcdir)/$$f; \
@LN_CP_F@ ../strings/$$f $(srcdir)/$$f; \
done; \
for f in $$qs; do \ for f in $$qs; do \
rm -f $(srcdir)/$$f; \ rm -f $(srcdir)/$$f; \
@LN_CP_F@ $(srcdir)/../sql/$$f $(srcdir)/$$f; \ @LN_CP_F@ $(srcdir)/../sql/$$f $(srcdir)/$$f; \
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment