merge with 4.0.5
BitKeeper/etc/logging_ok: auto-union configure.in: Auto merged Docs/manual.texi: Auto merged myisam/mi_open.c: Auto merged mysql-test/r/null_key.result: Auto merged mysql-test/r/select.result: Auto merged sql/field.h: Auto merged sql/field_conv.cc: Auto merged sql/ha_innodb.cc: Auto merged sql/log.cc: Auto merged sql/sql_parse.cc: Auto merged sql/table.cc: Auto merged
This commit is contained in:
commit
b3cb7b7f77
11
.bzrignore
11
.bzrignore
@ -51,6 +51,8 @@ Docs/manual.ky
|
||||
Docs/manual.log
|
||||
Docs/manual.pdf
|
||||
Docs/manual.pg
|
||||
Docs/manual.texi.orig
|
||||
Docs/manual.texi.rej
|
||||
Docs/manual.toc
|
||||
Docs/manual.tp
|
||||
Docs/manual.txt
|
||||
@ -247,6 +249,7 @@ libmysqld/field.cc
|
||||
libmysqld/field_conv.cc
|
||||
libmysqld/filesort.cc
|
||||
libmysqld/get_password.c
|
||||
libmysqld/gstream.cc
|
||||
libmysqld/ha_berkeley.cc
|
||||
libmysqld/ha_heap.cc
|
||||
libmysqld/ha_innobase.cc
|
||||
@ -287,6 +290,7 @@ libmysqld/repl_failsafe.cc
|
||||
libmysqld/set_var.cc
|
||||
libmysqld/simple-test
|
||||
libmysqld/slave.cc
|
||||
libmysqld/spatial.cc
|
||||
libmysqld/sql_acl.cc
|
||||
libmysqld/sql_analyse.cc
|
||||
libmysqld/sql_base.cc
|
||||
@ -356,6 +360,8 @@ myisam/myisam.log
|
||||
myisam/myisamchk
|
||||
myisam/myisamlog
|
||||
myisam/myisampack
|
||||
myisam/rt_test
|
||||
myisam/sp_test
|
||||
myisam/test1.MYD
|
||||
myisam/test1.MYI
|
||||
myisam/test2.MYD
|
||||
@ -382,6 +388,7 @@ mysql.proj
|
||||
mysqld.S
|
||||
mysqld.sym
|
||||
mysys/#mf_iocache.c#
|
||||
mysys/charset2html
|
||||
mysys/getopt.c
|
||||
mysys/getopt1.c
|
||||
mysys/ste5KbMa
|
||||
@ -466,6 +473,7 @@ sql/share/norwegian/errmsg.sys
|
||||
sql/sql_select.cc.orig
|
||||
sql/sql_yacc.cc
|
||||
sql/sql_yacc.h
|
||||
sql/sql_yacc.yy.orig
|
||||
stamp-h
|
||||
stamp-h.in
|
||||
strings/conf_to_src
|
||||
@ -485,6 +493,7 @@ support-files/mysql-log-rotate
|
||||
support-files/mysql.server
|
||||
support-files/mysql.spec
|
||||
tags
|
||||
tests/client_test
|
||||
tmp/*
|
||||
tools/my_vsnprintf.c
|
||||
tools/mysqlmanager
|
||||
@ -494,3 +503,5 @@ vio/test-ssl
|
||||
vio/test-sslclient
|
||||
vio/test-sslserver
|
||||
vio/viotest-ssl
|
||||
sql_error.cc
|
||||
sql_prepare.cc
|
||||
|
@ -14,7 +14,8 @@ $make -k clean || true
|
||||
/bin/rm -f */.deps/*.P config.cache innobase/config.cache bdb/build_unix/config.cache
|
||||
|
||||
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)
|
||||
if [ -d gemini ]
|
||||
then
|
||||
|
@ -6,8 +6,8 @@ path=`dirname $0`
|
||||
extra_flags="$pentium_cflags $debug_cflags"
|
||||
c_warnings="$c_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"
|
||||
|
@ -4,6 +4,7 @@ Administrator@co3064164-a.rochd1.qld.optushome.com.au
|
||||
Administrator@fred.
|
||||
Miguel@light.local
|
||||
Sinisa@sinisa.nasamreza.org
|
||||
WAX@sergbook.mysql.com
|
||||
ahlentz@co3064164-a.rochd1.qld.optusnet.com.au
|
||||
akishkin@work.mysql.com
|
||||
arjen@co3064164-a.bitbike.com
|
||||
@ -11,6 +12,7 @@ arjen@fred.bitbike.com
|
||||
arjen@george.bitbike.com
|
||||
bar@bar.mysql.r18.ru
|
||||
bar@bar.udmsearch.izhnet.ru
|
||||
bar@gw.udmsearch.izhnet.ru
|
||||
bell@sanja.is.com.ua
|
||||
davida@isil.mysql.com
|
||||
heikki@donna.mysql.fi
|
||||
@ -57,6 +59,8 @@ paul@teton.kitebird.com
|
||||
pem@mysql.com
|
||||
peter@linux.local
|
||||
peter@mysql.com
|
||||
ram@gw.udmsearch.izhnet.ru
|
||||
ram@mysql.r18.ru
|
||||
ram@ram.(none)
|
||||
root@x3.internalnet
|
||||
salle@geopard.(none)
|
||||
@ -80,6 +84,7 @@ tonu@hundin.mysql.fi
|
||||
tonu@volk.internalnet
|
||||
tonu@x153.internalnet
|
||||
tonu@x3.internalnet
|
||||
venu@myvenu.com
|
||||
venu@work.mysql.com
|
||||
vva@genie.(none)
|
||||
walrus@mysql.com
|
||||
|
@ -25,10 +25,10 @@ then
|
||||
echo "Commit successful, notifying developers at $TO"
|
||||
(
|
||||
cat <<EOF
|
||||
List-ID: <bk.mysql-4.0>
|
||||
List-ID: <bk.mysql-4.1>
|
||||
From: $FROM
|
||||
To: $TO
|
||||
Subject: bk commit - 4.0 tree
|
||||
Subject: bk commit - 4.1 tree
|
||||
|
||||
EOF
|
||||
bk changes -v -r+
|
||||
@ -41,13 +41,13 @@ EOF
|
||||
echo "Notifying internals list at $INTERNALS"
|
||||
(
|
||||
cat <<EOF
|
||||
List-ID: <bk.mysql-4.0>
|
||||
List-ID: <bk.mysql-4.1>
|
||||
From: $FROM
|
||||
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
|
||||
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
|
||||
push, to the public repository.
|
||||
For information on how to access the public repository
|
||||
@ -68,10 +68,10 @@ EOF
|
||||
echo "Notifying docs list at $DOCS"
|
||||
(
|
||||
cat <<EOF
|
||||
List-ID: <bk.mysql-4.0>
|
||||
List-ID: <bk.mysql-4.1>
|
||||
From: $FROM
|
||||
To: $DOCS
|
||||
Subject: bk commit - 4.0 tree (Manual)
|
||||
Subject: bk commit - 4.1 tree (Manual)
|
||||
|
||||
EOF
|
||||
bk changes -v -r+
|
||||
|
@ -136,6 +136,10 @@ SOURCE="..\strings\ctype-latin1_de.c"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE="..\strings\ctype-simple.c"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE="..\strings\ctype-sjis.c"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
7
VC++Files/fix-project-files
Executable file
7
VC++Files/fix-project-files
Executable file
@ -0,0 +1,7 @@
|
||||
#!/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"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE="..\strings\ctype-simple.c"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE="..\strings\ctype-sjis.c"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@ -256,6 +260,7 @@ SOURCE=..\mysys\my_alloc.c
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\mysys\my_compress.c
|
||||
# ADD CPP /I "../zlib"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
|
@ -43,8 +43,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# 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 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 BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# 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 MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x416 /d "NDEBUG"
|
||||
# ADD RSC /l 0x416 /d "NDEBUG"
|
||||
@ -53,8 +52,7 @@ BSC32=bscmake.exe
|
||||
# ADD BSC32 /nologo
|
||||
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 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"
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
# 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"
|
||||
|
||||
!ELSEIF "$(CFG)" == "libmysqld - Win32 Debug"
|
||||
|
||||
@ -70,8 +68,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# 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 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 BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# 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 MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x416 /d "_DEBUG"
|
||||
# ADD RSC /l 0x416 /d "_DEBUG"
|
||||
@ -80,8 +77,7 @@ BSC32=bscmake.exe
|
||||
# ADD BSC32 /nologo
|
||||
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 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
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
# 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"
|
||||
|
||||
!ENDIF
|
||||
|
||||
@ -119,6 +115,10 @@ SOURCE=..\libmysql\get_password.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sql\gstream.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sql\ha_berkeley.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@ -176,6 +176,7 @@ SOURCE=..\sql\item_create.cpp
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sql\item_func.cpp
|
||||
# ADD CPP /I "../zlib"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@ -183,6 +184,10 @@ SOURCE=..\sql\item_strfunc.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sql\item_subselect.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sql\item_sum.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@ -271,7 +276,7 @@ SOURCE=..\sql\set_var.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sql\slave.cpp
|
||||
SOURCE=..\sql\spatial.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@ -307,10 +312,18 @@ SOURCE=..\sql\sql_delete.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sql\sql_derived.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sql\sql_do.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sql\sql_error.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sql\sql_handler.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@ -327,10 +340,6 @@ SOURCE=..\sql\sql_list.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sql\sql_load.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sql\sql_manager.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@ -343,6 +352,10 @@ SOURCE=..\sql\sql_parse.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sql\sql_prepare.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sql\sql_rename.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -265,8 +265,28 @@ SOURCE=.\mi_write.c
|
||||
# End 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
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\sp_key.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
@ -279,6 +299,10 @@ SOURCE=.\ft_eval.h
|
||||
|
||||
SOURCE=.\myisamdef.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\rt_index.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
|
@ -326,6 +326,10 @@ SOURCE=.\my_getwd.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\my_handler.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\my_init.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -282,6 +282,10 @@ SOURCE=.\filesort.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\gstream.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ha_berkeley.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@ -460,17 +464,25 @@ SOURCE=.\item_func.cpp
|
||||
|
||||
!IF "$(CFG)" == "mysqld - Win32 Release"
|
||||
|
||||
# ADD CPP /I "../zlib"
|
||||
|
||||
!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
|
||||
|
||||
# ADD CPP /G5
|
||||
# ADD CPP /G5 /I "../zlib"
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
|
||||
|
||||
# ADD CPP /I "../zlib"
|
||||
|
||||
!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
|
||||
|
||||
# ADD CPP /I "../zlib"
|
||||
|
||||
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
|
||||
|
||||
# ADD CPP /I "../zlib"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
@ -496,6 +508,10 @@ SOURCE=.\item_strfunc.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\item_subselect.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\item_sum.cpp
|
||||
|
||||
!IF "$(CFG)" == "mysqld - Win32 Release"
|
||||
@ -811,6 +827,10 @@ SOURCE=.\slave.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\spatial.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\sql_acl.cpp
|
||||
|
||||
!IF "$(CFG)" == "mysqld - Win32 Release"
|
||||
@ -927,10 +947,18 @@ SOURCE=.\sql_delete.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\sql_derived.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\sql_do.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\sql_error.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\sql_handler.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@ -1059,6 +1087,10 @@ SOURCE=.\sql_parse.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\sql_prepare.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\sql_rename.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -128,6 +128,10 @@ SOURCE=".\ctype-latin1_de.c"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\ctype-simple.c"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\ctype-sjis.c"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
40
acconfig.h
40
acconfig.h
@ -18,6 +18,9 @@
|
||||
|
||||
#undef CRAY_STACKSEG_END
|
||||
|
||||
/* Define the default charset name */
|
||||
#undef DEFAULT_CHARSET_NAME
|
||||
|
||||
/* Version of .frm files */
|
||||
#undef DOT_FRM_VERSION
|
||||
|
||||
@ -63,6 +66,43 @@
|
||||
/* READLINE: */
|
||||
#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: */
|
||||
#undef HAVE_COMPRESS
|
||||
|
||||
|
@ -40,7 +40,7 @@
|
||||
#include <signal.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 */
|
||||
#define MAX_COLUMN_LENGTH 1024
|
||||
@ -91,8 +91,8 @@ extern "C" {
|
||||
#define vidattr(A) {} // Can't get this to work
|
||||
#endif
|
||||
|
||||
#ifdef __WIN__
|
||||
#define cmp_database(A,B) my_strcasecmp((A),(B))
|
||||
#ifdef FN_NO_CASE_SENCE
|
||||
#define cmp_database(A,B) my_strcasecmp(system_charset_info, (A), (B))
|
||||
#else
|
||||
#define cmp_database(A,B) strcmp((A),(B))
|
||||
#endif
|
||||
@ -346,6 +346,7 @@ int main(int argc,char *argv[])
|
||||
if (!status.batch)
|
||||
ignore_errors=1; // Don't abort monitor
|
||||
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
|
||||
@ -877,14 +878,14 @@ static COMMANDS *find_command (char *name,char cmd_char)
|
||||
}
|
||||
else
|
||||
{
|
||||
while (isspace(*name))
|
||||
while (my_isspace(system_charset_info,*name))
|
||||
name++;
|
||||
if (strchr(name,';') || strstr(name,"\\g"))
|
||||
return ((COMMANDS *) 0);
|
||||
if ((end=strcont(name," \t")))
|
||||
{
|
||||
len=(uint) (end - name);
|
||||
while (isspace(*end))
|
||||
while (my_isspace(system_charset_info,*end))
|
||||
end++;
|
||||
if (!*end)
|
||||
end=0; // no arguments to function
|
||||
@ -896,7 +897,8 @@ static COMMANDS *find_command (char *name,char cmd_char)
|
||||
for (uint i= 0; commands[i].name; i++)
|
||||
{
|
||||
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] &&
|
||||
(!end || (end && commands[i].takes_params))) ||
|
||||
!name && commands[i].cmd_char == cmd_char))
|
||||
@ -924,12 +926,13 @@ static bool add_line(String &buffer,char *line,char *in_string)
|
||||
|
||||
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;
|
||||
#ifdef USE_MB
|
||||
int l;
|
||||
if (use_mb(default_charset_info) &&
|
||||
(l = my_ismbchar(default_charset_info, pos, strend))) {
|
||||
if (use_mb(system_charset_info) &&
|
||||
(l = my_ismbchar(system_charset_info, pos, strend))) {
|
||||
while (l--)
|
||||
*out++ = *pos++;
|
||||
pos--;
|
||||
@ -992,7 +995,7 @@ static bool add_line(String &buffer,char *line,char *in_string)
|
||||
}
|
||||
else if (!*in_string && (inchar == '#' ||
|
||||
inchar == '-' && pos[1] == '-' &&
|
||||
isspace(pos[2])))
|
||||
my_isspace(system_charset_info,pos[2])))
|
||||
break; // comment to end of line
|
||||
else
|
||||
{ // Add found char to buffer
|
||||
@ -1368,9 +1371,9 @@ com_clear(String *buffer,char *line __attribute__((unused)))
|
||||
static int
|
||||
com_go(String *buffer,char *line __attribute__((unused)))
|
||||
{
|
||||
char buff[160],time_buff[32];
|
||||
char buff[200], time_buff[32], *pos;
|
||||
MYSQL_RES *result;
|
||||
ulong timer;
|
||||
ulong timer, warnings;
|
||||
uint error=0;
|
||||
|
||||
if (!status.batch)
|
||||
@ -1399,7 +1402,9 @@ com_go(String *buffer,char *line __attribute__((unused)))
|
||||
(void) com_print(buffer,0);
|
||||
|
||||
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);
|
||||
return 0;
|
||||
@ -1452,7 +1457,7 @@ com_go(String *buffer,char *line __attribute__((unused)))
|
||||
{
|
||||
if (!mysql_num_rows(result) && ! quick)
|
||||
{
|
||||
sprintf(buff,"Empty set%s",time_buff);
|
||||
strmov(buff, "Empty set");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1467,20 +1472,30 @@ com_go(String *buffer,char *line __attribute__((unused)))
|
||||
print_tab_data(result);
|
||||
else
|
||||
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) == 1 ? "row" : "rows",
|
||||
time_buff);
|
||||
(long) mysql_num_rows(result) == 1 ? "row" : "rows");
|
||||
end_pager();
|
||||
}
|
||||
}
|
||||
else if (mysql_affected_rows(&mysql) == ~(ulonglong) 0)
|
||||
sprintf(buff,"Query OK%s",time_buff);
|
||||
strmov(buff,"Query OK");
|
||||
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) == 1 ? "row" : "rows",
|
||||
time_buff);
|
||||
(long) mysql_affected_rows(&mysql) == 1 ? "row" : "rows");
|
||||
|
||||
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);
|
||||
if (mysql_info(&mysql))
|
||||
put_info(mysql_info(&mysql),INFO_RESULT);
|
||||
@ -1777,8 +1792,9 @@ safe_put_field(const char *pos,ulong length)
|
||||
{
|
||||
#ifdef USE_MB
|
||||
int l;
|
||||
if (use_mb(default_charset_info) &&
|
||||
(l = my_ismbchar(default_charset_info, pos, end))) {
|
||||
if (use_mb(system_charset_info) &&
|
||||
(l = my_ismbchar(system_charset_info, pos, end)))
|
||||
{
|
||||
while (l--)
|
||||
tee_putc(*pos++, PAGER);
|
||||
pos--;
|
||||
@ -1838,7 +1854,7 @@ com_tee(String *buffer, char *line __attribute__((unused)))
|
||||
|
||||
if (status.batch)
|
||||
return 0;
|
||||
while (isspace(*line))
|
||||
while (my_isspace(system_charset_info,*line))
|
||||
line++;
|
||||
if (!(param = strchr(line, ' '))) // if outfile wasn't given, use the default
|
||||
{
|
||||
@ -1857,11 +1873,12 @@ com_tee(String *buffer, char *line __attribute__((unused)))
|
||||
}
|
||||
|
||||
/* eliminate the spaces before the parameters */
|
||||
while (isspace(*param))
|
||||
while (my_isspace(system_charset_info,*param))
|
||||
param++;
|
||||
end= strmake(file_name, param, sizeof(file_name) - 1);
|
||||
/* 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[0]= 0;
|
||||
if (end == file_name)
|
||||
@ -1901,7 +1918,7 @@ com_pager(String *buffer, char *line __attribute__((unused)))
|
||||
if (status.batch)
|
||||
return 0;
|
||||
/* Skip space from file name */
|
||||
while (isspace(*line))
|
||||
while (my_isspace(system_charset_info,*line))
|
||||
line++;
|
||||
if (!(param = strchr(line, ' '))) // if pager was not given, use the default
|
||||
{
|
||||
@ -1917,10 +1934,11 @@ com_pager(String *buffer, char *line __attribute__((unused)))
|
||||
}
|
||||
else
|
||||
{
|
||||
while (isspace(*param))
|
||||
while (my_isspace(system_charset_info,*param))
|
||||
param++;
|
||||
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[0]=0;
|
||||
strmov(pager, pager_name);
|
||||
@ -2056,7 +2074,7 @@ com_connect(String *buffer, char *line)
|
||||
|
||||
if (buffer)
|
||||
{
|
||||
while (isspace(*line))
|
||||
while (my_isspace(system_charset_info,*line))
|
||||
line++;
|
||||
strnmov(buff,line,sizeof(buff)-1); // Don't destroy history
|
||||
if (buff[0] == '\\') // Short command
|
||||
@ -2102,15 +2120,16 @@ static int com_source(String *buffer, char *line)
|
||||
FILE *sql_file;
|
||||
|
||||
/* Skip space from file name */
|
||||
while (isspace(*line))
|
||||
while (my_isspace(system_charset_info,*line))
|
||||
line++;
|
||||
if (!(param = strchr(line, ' '))) // Skip command name
|
||||
return put_info("Usage: \\. <filename> | source <filename>",
|
||||
INFO_ERROR, 0);
|
||||
while (isspace(*param))
|
||||
while (my_isspace(system_charset_info,*param))
|
||||
param++;
|
||||
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[0]=0;
|
||||
unpack_filename(source_name,source_name);
|
||||
@ -2151,7 +2170,7 @@ com_use(String *buffer __attribute__((unused)), char *line)
|
||||
char *tmp;
|
||||
char buff[256];
|
||||
|
||||
while (isspace(*line))
|
||||
while (my_isspace(system_charset_info,*line))
|
||||
line++;
|
||||
strnmov(buff,line,sizeof(buff)-1); // Don't destroy history
|
||||
if (buff[0] == '\\') // Short command
|
||||
@ -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, "Connection:\t\t%s\n", mysql_get_host_info(&mysql));
|
||||
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);
|
||||
if (strstr(mysql_get_host_info(&mysql),"TCP/IP") || ! mysql.unix_socket)
|
||||
tee_fprintf(stdout, "TCP port:\t\t%d\n", mysql.port);
|
||||
@ -2444,7 +2463,7 @@ static void remove_cntrl(String &buffer)
|
||||
{
|
||||
char *start,*end;
|
||||
end=(start=(char*) buffer.ptr())+buffer.length();
|
||||
while (start < end && !isgraph(end[-1]))
|
||||
while (start < end && !my_isgraph(system_charset_info,end[-1]))
|
||||
end--;
|
||||
buffer.length((uint) (end-start));
|
||||
}
|
||||
|
@ -518,7 +518,7 @@ static my_bool test_if_special_chars(const char *str)
|
||||
{
|
||||
#if MYSQL_VERSION_ID >= 32300
|
||||
for ( ; *str ; str++)
|
||||
if (!isvar(*str) && *str != '$')
|
||||
if (!my_isvar(system_charset_info,*str) && *str != '$')
|
||||
return 1;
|
||||
#endif
|
||||
return 0;
|
||||
@ -1036,7 +1036,8 @@ static void dumpTable(uint numFields, char *table)
|
||||
/* change any strings ("inf","nan",..) into NULL */
|
||||
char *ptr = row[i];
|
||||
dynstr_append(&extended_row,
|
||||
(!isalpha(*ptr)) ? ptr : "NULL");
|
||||
(!my_isalpha(system_charset_info,*ptr)) ?
|
||||
ptr : "NULL");
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1068,9 +1069,11 @@ static void dumpTable(uint numFields, char *table)
|
||||
char *ptr = row[i];
|
||||
if (opt_xml)
|
||||
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
|
||||
fputs((!isalpha(*ptr)) ? ptr : "NULL", md_result_file);
|
||||
fputs((!my_isalpha(system_charset_info,*ptr)) ?
|
||||
ptr : "NULL", md_result_file);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -311,7 +311,7 @@ static int eval_result = 0;
|
||||
void mysql_enable_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_probe(MYSQL *mysql __attribute__((unused))) { return 1; }
|
||||
my_bool mysql_rpl_probe(MYSQL *mysql __attribute__((unused))) { return 1; }
|
||||
#endif
|
||||
|
||||
#define MAX_SERVER_ARGS 20
|
||||
@ -482,9 +482,9 @@ void init_parser()
|
||||
|
||||
int hex_val(int c)
|
||||
{
|
||||
if (isdigit(c))
|
||||
if (my_isdigit(system_charset_info,c))
|
||||
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;
|
||||
else
|
||||
return -1;
|
||||
@ -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;
|
||||
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;
|
||||
if (var_name == save_var_name)
|
||||
{
|
||||
@ -757,7 +757,7 @@ int do_server_op(struct st_query* q,const char* op)
|
||||
com_p=strmov(com_p,"_exec ");
|
||||
if (!*p)
|
||||
die("Missing server name in server_%s\n",op);
|
||||
while (*p && !isspace(*p))
|
||||
while (*p && !my_isspace(system_charset_info,*p))
|
||||
{
|
||||
*com_p++=*p++;
|
||||
}
|
||||
@ -790,7 +790,7 @@ int do_require_version(struct st_query* q)
|
||||
if (!*p)
|
||||
die("Missing version argument in require_version\n");
|
||||
ver_arg = p;
|
||||
while (*p && !isspace(*p))
|
||||
while (*p && !my_isspace(system_charset_info,*p))
|
||||
p++;
|
||||
*p = 0;
|
||||
ver_arg_len = p - ver_arg;
|
||||
@ -820,7 +820,7 @@ int do_source(struct st_query* q)
|
||||
if (!*p)
|
||||
die("Missing file name in source\n");
|
||||
name = p;
|
||||
while (*p && !isspace(*p))
|
||||
while (*p && !my_isspace(system_charset_info,*p))
|
||||
p++;
|
||||
*p = 0;
|
||||
|
||||
@ -1057,11 +1057,11 @@ int do_let(struct st_query* q)
|
||||
if (!*p)
|
||||
die("Missing variable name in let\n");
|
||||
var_name = p;
|
||||
while (*p && (*p != '=' || isspace(*p)))
|
||||
while (*p && (*p != '=' || my_isspace(system_charset_info,*p)))
|
||||
p++;
|
||||
var_name_end = p;
|
||||
if (*p == '=') p++;
|
||||
while (*p && isspace(*p))
|
||||
while (*p && my_isspace(system_charset_info,*p))
|
||||
p++;
|
||||
var_val_start = p;
|
||||
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)))
|
||||
|
||||
int do_sleep(struct st_query* q, my_bool real_sleep)
|
||||
{
|
||||
char* p=q->first_argument;
|
||||
while (*p && isspace(*p))
|
||||
char *p=q->first_argument;
|
||||
while (*p && my_isspace(system_charset_info,*p))
|
||||
p++;
|
||||
if (!*p)
|
||||
die("Missing argument in sleep\n");
|
||||
@ -1107,7 +1107,7 @@ static void get_file_name(char *filename, struct st_query* q)
|
||||
char* p=q->first_argument;
|
||||
strnmov(filename, p, FN_REFLEN);
|
||||
/* Remove end space */
|
||||
while (p > filename && isspace(p[-1]))
|
||||
while (p > filename && my_isspace(system_charset_info,p[-1]))
|
||||
p--;
|
||||
p[0]=0;
|
||||
}
|
||||
@ -1193,7 +1193,7 @@ static char *get_string(char **to_ptr, char **from_ptr,
|
||||
if (*from != ' ' && *from)
|
||||
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++;
|
||||
|
||||
*to =0; /* End of string marker */
|
||||
@ -1250,8 +1250,8 @@ static void get_replace(struct st_query *q)
|
||||
insert_pointer_name(&to_array,to);
|
||||
}
|
||||
for (i=1,pos=word_end_chars ; i < 256 ; i++)
|
||||
if (isspace(i))
|
||||
*pos++=i;
|
||||
if (my_isspace(system_charset_info,i))
|
||||
*pos++= i;
|
||||
*pos=0; /* End pointer */
|
||||
if (!(glob_replace=init_replace((char**) from_array.typelib.type_names,
|
||||
(char**) to_array.typelib.type_names,
|
||||
@ -1287,7 +1287,7 @@ int select_connection(char *p)
|
||||
if (!*p)
|
||||
die("Missing connection name in connect\n");
|
||||
name = p;
|
||||
while (*p && !isspace(*p))
|
||||
while (*p && !my_isspace(system_charset_info,*p))
|
||||
p++;
|
||||
*p = 0;
|
||||
|
||||
@ -1313,7 +1313,7 @@ int close_connection(struct st_query* q)
|
||||
if (!*p)
|
||||
die("Missing connection name in connect\n");
|
||||
name = p;
|
||||
while (*p && !isspace(*p))
|
||||
while (*p && !my_isspace(system_charset_info,*p))
|
||||
p++;
|
||||
*p = 0;
|
||||
|
||||
@ -1349,11 +1349,13 @@ int close_connection(struct st_query* q)
|
||||
char* safe_get_param(char* str, char** arg, const char* msg)
|
||||
{
|
||||
DBUG_ENTER("safe_get_param");
|
||||
while (*str && isspace(*str)) str++;
|
||||
while (*str && my_isspace(system_charset_info,*str))
|
||||
str++;
|
||||
*arg = str;
|
||||
for (; *str && *str != ',' && *str != ')' ; str++)
|
||||
{
|
||||
if (isspace(*str)) *str = 0;
|
||||
if (my_isspace(system_charset_info,*str))
|
||||
*str = 0;
|
||||
}
|
||||
if (!*str)
|
||||
die(msg);
|
||||
@ -1635,7 +1637,7 @@ int read_line(char* buf, int size)
|
||||
{
|
||||
state = R_COMMENT;
|
||||
}
|
||||
else if (isspace(c))
|
||||
else if (my_isspace(system_charset_info,c))
|
||||
{
|
||||
if (c == '\n')
|
||||
start_lineno= ++*lineno; /* Query hasn't started yet */
|
||||
@ -1761,7 +1763,7 @@ int read_query(struct st_query** q_ptr)
|
||||
{
|
||||
expected_errno = 0;
|
||||
p++;
|
||||
for (;isdigit(*p);p++)
|
||||
for (;my_isdigit(system_charset_info,*p);p++)
|
||||
expected_errno = expected_errno * 10 + *p - '0';
|
||||
q->expected_errno[0] = expected_errno;
|
||||
q->expected_errno[1] = 0;
|
||||
@ -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 == '@')
|
||||
{
|
||||
p++;
|
||||
p1 = q->record_file;
|
||||
while (!isspace(*p) &&
|
||||
while (!my_isspace(system_charset_info,*p) &&
|
||||
p1 < q->record_file + sizeof(q->record_file) - 1)
|
||||
*p1++ = *p++;
|
||||
*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))))
|
||||
die(NullS);
|
||||
|
||||
/* 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);
|
||||
while (*p && isspace(*p)) p++;
|
||||
while (*p && my_isspace(system_charset_info,*p))
|
||||
p++;
|
||||
q->first_argument=p;
|
||||
q->end = strend(q->query);
|
||||
parser.read_lines++;
|
||||
@ -2028,6 +2033,36 @@ static void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val,
|
||||
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
|
||||
@ -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)
|
||||
{
|
||||
MYSQL_RES* res = 0;
|
||||
MYSQL_FIELD* fields;
|
||||
MYSQL_ROW row;
|
||||
int num_fields,i, error = 0;
|
||||
unsigned long* lengths;
|
||||
char* val;
|
||||
int len;
|
||||
int i, error = 0;
|
||||
DYNAMIC_STRING *ds;
|
||||
DYNAMIC_STRING ds_tmp;
|
||||
DYNAMIC_STRING eval_query;
|
||||
@ -2152,45 +2182,37 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags)
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!res)
|
||||
goto end;
|
||||
|
||||
if (!disable_result_log)
|
||||
if (!disable_result_log && res)
|
||||
{
|
||||
fields = mysql_fetch_fields(res);
|
||||
num_fields = mysql_num_fields(res);
|
||||
int num_fields= mysql_num_fields(res);
|
||||
MYSQL_FIELD *fields= mysql_fetch_fields(res);
|
||||
for (i = 0; i < num_fields; i++)
|
||||
{
|
||||
if (i)
|
||||
dynstr_append_mem(ds, "\t", 1);
|
||||
dynstr_append(ds, fields[i].name);
|
||||
}
|
||||
|
||||
dynstr_append_mem(ds, "\n", 1);
|
||||
|
||||
while ((row = mysql_fetch_row(res)))
|
||||
{
|
||||
lengths = mysql_fetch_lengths(res);
|
||||
for (i = 0; i < num_fields; i++)
|
||||
{
|
||||
val = (char*)row[i];
|
||||
len = lengths[i];
|
||||
|
||||
if (!val)
|
||||
{
|
||||
val = (char*)"NULL";
|
||||
len = 4;
|
||||
append_result(ds, res);
|
||||
}
|
||||
|
||||
if (i)
|
||||
dynstr_append_mem(ds, "\t", 1);
|
||||
replace_dynstr_append_mem(ds, val, len);
|
||||
/* 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
|
||||
{
|
||||
dynstr_append_mem(ds, "Warnings:\n", 10);
|
||||
append_result(ds, warn_res);
|
||||
mysql_free_result(warn_res);
|
||||
}
|
||||
dynstr_append_mem(ds, "\n", 1);
|
||||
}
|
||||
if (glob_replace)
|
||||
free_replace();
|
||||
}
|
||||
|
||||
if (record)
|
||||
{
|
||||
if (!q->record_file[0] && !result_file)
|
||||
@ -2301,7 +2323,8 @@ static void var_from_env(const char* name, const char* def_val)
|
||||
static void init_var_hash()
|
||||
{
|
||||
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");
|
||||
var_from_env("MASTER_MYPORT", "9306");
|
||||
var_from_env("SLAVE_MYPORT", "9307");
|
||||
|
@ -234,7 +234,7 @@ bool String::fill(uint32 max_length,char fill_char)
|
||||
|
||||
void String::strip_sp()
|
||||
{
|
||||
while (str_length && isspace(Ptr[str_length-1]))
|
||||
while (str_length && my_isspace(str_charset,Ptr[str_length-1]))
|
||||
str_length--;
|
||||
}
|
||||
|
||||
@ -296,10 +296,10 @@ uint32 String::numchars()
|
||||
register uint32 n=0,mblen;
|
||||
register const char *mbstr=Ptr;
|
||||
register const char *end=mbstr+str_length;
|
||||
if (use_mb(default_charset_info))
|
||||
if (use_mb(str_charset))
|
||||
{
|
||||
while (mbstr < end) {
|
||||
if ((mblen=my_ismbchar(default_charset_info, mbstr,end))) mbstr+=mblen;
|
||||
if ((mblen=my_ismbchar(str_charset, mbstr,end))) mbstr+=mblen;
|
||||
else ++mbstr;
|
||||
++n;
|
||||
}
|
||||
@ -316,11 +316,11 @@ int String::charpos(int i,uint32 offset)
|
||||
register uint32 mblen;
|
||||
register const char *mbstr=Ptr+offset;
|
||||
register const char *end=Ptr+str_length;
|
||||
if (use_mb(default_charset_info))
|
||||
if (use_mb(str_charset))
|
||||
{
|
||||
if (i<=0) return i;
|
||||
while (i && mbstr < end) {
|
||||
if ((mblen=my_ismbchar(default_charset_info, mbstr,end))) mbstr+=mblen;
|
||||
if ((mblen=my_ismbchar(str_charset, mbstr,end))) mbstr+=mblen;
|
||||
else ++mbstr;
|
||||
--i;
|
||||
}
|
||||
@ -361,6 +361,39 @@ skipp:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
Search after a string without regarding to case
|
||||
This needs to be replaced when we have character sets per string
|
||||
*/
|
||||
|
||||
int String::strstr_case(const String &s,uint32 offset)
|
||||
{
|
||||
if (s.length()+offset <= str_length)
|
||||
{
|
||||
if (!s.length())
|
||||
return ((int) offset); // Empty string is always found
|
||||
|
||||
register const char *str = Ptr+offset;
|
||||
register const char *search=s.ptr();
|
||||
const char *end=Ptr+str_length-s.length()+1;
|
||||
const char *search_end=s.ptr()+s.length();
|
||||
skipp:
|
||||
while (str != end)
|
||||
{
|
||||
if (str_charset->sort_order[*str++] == str_charset->sort_order[*search])
|
||||
{
|
||||
register char *i,*j;
|
||||
i=(char*) str; j=(char*) search+1;
|
||||
while (j != search_end)
|
||||
if (str_charset->sort_order[*i++] !=
|
||||
str_charset->sort_order[*j++])
|
||||
goto skipp;
|
||||
return (int) (str-Ptr) -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
** Search string from end. Offset is offset to the end of string
|
||||
@ -428,6 +461,44 @@ bool String::replace(uint32 offset,uint32 arg_length,const String &to)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// added by Holyfoot for "geometry" needs
|
||||
int String::reserve(uint32 space_needed, uint32 grow_by)
|
||||
{
|
||||
if (Alloced_length < str_length + space_needed)
|
||||
{
|
||||
if (realloc(Alloced_length + max(space_needed, grow_by) - 1))
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void String::qs_append(const char *str)
|
||||
{
|
||||
int len = strlen(str);
|
||||
memcpy(Ptr + str_length, str, len + 1);
|
||||
str_length += len;
|
||||
}
|
||||
|
||||
void String::qs_append(double d)
|
||||
{
|
||||
char *buff = Ptr + str_length;
|
||||
sprintf(buff,"%.14g", d);
|
||||
str_length += strlen(buff);
|
||||
}
|
||||
|
||||
void String::qs_append(double *d)
|
||||
{
|
||||
double ld;
|
||||
float8get(ld, d);
|
||||
qs_append(ld);
|
||||
}
|
||||
|
||||
void String::qs_append(const char &c)
|
||||
{
|
||||
Ptr[str_length] = c;
|
||||
str_length += sizeof(c);
|
||||
}
|
||||
|
||||
|
||||
int sortcmp(const String *x,const String *y)
|
||||
{
|
||||
@ -436,15 +507,15 @@ int sortcmp(const String *x,const String *y)
|
||||
uint32 x_len=x->length(),y_len=y->length(),len=min(x_len,y_len);
|
||||
|
||||
#ifdef USE_STRCOLL
|
||||
if (use_strcoll(default_charset_info))
|
||||
if (use_strnxfrm(x->str_charset))
|
||||
{
|
||||
#ifndef CMP_ENDSPACE
|
||||
while (x_len && isspace(s[x_len-1]))
|
||||
while (x_len && my_isspace(x->str_charset,s[x_len-1]))
|
||||
x_len--;
|
||||
while (y_len && isspace(t[y_len-1]))
|
||||
while (y_len && my_isspace(x->str_charset,t[y_len-1]))
|
||||
y_len--;
|
||||
#endif
|
||||
return my_strnncoll(default_charset_info,
|
||||
return my_strnncoll(x->str_charset,
|
||||
(unsigned char *)s,x_len,(unsigned char *)t,y_len);
|
||||
}
|
||||
else
|
||||
@ -454,9 +525,10 @@ int sortcmp(const String *x,const String *y)
|
||||
y_len-=len;
|
||||
while (len--)
|
||||
{
|
||||
if (my_sort_order[(uchar) *s++] != my_sort_order[(uchar) *t++])
|
||||
return ((int) my_sort_order[(uchar) s[-1]] -
|
||||
(int) my_sort_order[(uchar) t[-1]]);
|
||||
if (x->str_charset->sort_order[(uchar) *s++] !=
|
||||
x->str_charset->sort_order[(uchar) *t++])
|
||||
return ((int) x->str_charset->sort_order[(uchar) s[-1]] -
|
||||
(int) x->str_charset->sort_order[(uchar) t[-1]]);
|
||||
}
|
||||
#ifndef CMP_ENDSPACE
|
||||
/* Don't compare end space in strings */
|
||||
@ -465,14 +537,14 @@ int sortcmp(const String *x,const String *y)
|
||||
{
|
||||
const char *end=t+y_len;
|
||||
for (; t != end ; t++)
|
||||
if (!isspace(*t))
|
||||
if (!my_isspace(x->str_charset,*t))
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *end=s+x_len;
|
||||
for (; s != end ; s++)
|
||||
if (!isspace(*s))
|
||||
if (!my_isspace(x->str_charset,*s))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@ -520,11 +592,10 @@ String *copy_if_not_alloced(String *to,String *from,uint32 from_length)
|
||||
/* Make it easier to handle different charactersets */
|
||||
|
||||
#ifdef USE_MB
|
||||
#define INC_PTR(A,B) A+=((use_mb_flag && \
|
||||
my_ismbchar(default_charset_info,A,B)) ? \
|
||||
my_ismbchar(default_charset_info,A,B) : 1)
|
||||
#define INC_PTR(cs,A,B) A+=((use_mb_flag && \
|
||||
my_ismbchar(cs,A,B)) ? my_ismbchar(cs,A,B) : 1)
|
||||
#else
|
||||
#define INC_PTR(A,B) A++
|
||||
#define INC_PTR(cs,A,B) A++
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -535,18 +606,18 @@ String *copy_if_not_alloced(String *to,String *from,uint32 from_length)
|
||||
*/
|
||||
|
||||
#ifdef LIKE_CMP_TOUPPER
|
||||
#define likeconv(A) (uchar) toupper(A)
|
||||
#define likeconv(s,A) (uchar) my_toupper(s,A)
|
||||
#else
|
||||
#define likeconv(A) (uchar) my_sort_order[(uchar) (A)]
|
||||
#define likeconv(s,A) (uchar) (s)->sort_order[(uchar) (A)]
|
||||
#endif
|
||||
|
||||
static int wild_case_compare(const char *str,const char *str_end,
|
||||
int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *str_end,
|
||||
const char *wildstr,const char *wildend,
|
||||
char escape)
|
||||
{
|
||||
int result= -1; // Not found, using wildcards
|
||||
#ifdef USE_MB
|
||||
bool use_mb_flag=use_mb(default_charset_info);
|
||||
bool use_mb_flag=use_mb(cs);
|
||||
#endif
|
||||
while (wildstr != wildend)
|
||||
{
|
||||
@ -557,7 +628,7 @@ static int wild_case_compare(const char *str,const char *str_end,
|
||||
#ifdef USE_MB
|
||||
int l;
|
||||
if (use_mb_flag &&
|
||||
(l = my_ismbchar(default_charset_info, wildstr, wildend)))
|
||||
(l = my_ismbchar(cs, wildstr, wildend)))
|
||||
{
|
||||
if (str+l > str_end || memcmp(str, wildstr, l) != 0)
|
||||
return 1;
|
||||
@ -566,7 +637,7 @@ static int wild_case_compare(const char *str,const char *str_end,
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (str == str_end || likeconv(*wildstr++) != likeconv(*str++))
|
||||
if (str == str_end || likeconv(cs,*wildstr++) != likeconv(cs,*str++))
|
||||
return(1); // No match
|
||||
if (wildstr == wildend)
|
||||
return (str != str_end); // Match if both are at end
|
||||
@ -576,9 +647,9 @@ static int wild_case_compare(const char *str,const char *str_end,
|
||||
{
|
||||
do
|
||||
{
|
||||
if (str == str_end) // Skipp one char if possible
|
||||
if (str == str_end) // Skip one char if possible
|
||||
return (result);
|
||||
INC_PTR(str,str_end);
|
||||
INC_PTR(cs,str,str_end);
|
||||
} while (++wildstr < wildend && *wildstr == wild_one);
|
||||
if (wildstr == wildend)
|
||||
break;
|
||||
@ -595,7 +666,7 @@ static int wild_case_compare(const char *str,const char *str_end,
|
||||
{
|
||||
if (str == str_end)
|
||||
return (-1);
|
||||
INC_PTR(str,str_end);
|
||||
INC_PTR(cs,str,str_end);
|
||||
continue;
|
||||
}
|
||||
break; // Not a wild character
|
||||
@ -613,10 +684,10 @@ static int wild_case_compare(const char *str,const char *str_end,
|
||||
int mblen;
|
||||
LINT_INIT(mblen);
|
||||
if (use_mb_flag)
|
||||
mblen = my_ismbchar(default_charset_info, wildstr, wildend);
|
||||
mblen = my_ismbchar(cs, wildstr, wildend);
|
||||
#endif
|
||||
INC_PTR(wildstr,wildend); // This is compared trough cmp
|
||||
cmp=likeconv(cmp);
|
||||
INC_PTR(cs,wildstr,wildend); // This is compared trough cmp
|
||||
cmp=likeconv(cs,cmp);
|
||||
do
|
||||
{
|
||||
#ifdef USE_MB
|
||||
@ -634,26 +705,26 @@ static int wild_case_compare(const char *str,const char *str_end,
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (!my_ismbchar(default_charset_info, str, str_end) &&
|
||||
likeconv(*str) == cmp)
|
||||
else if (!my_ismbchar(cs, str, str_end) &&
|
||||
likeconv(cs,*str) == cmp)
|
||||
{
|
||||
str++;
|
||||
break;
|
||||
}
|
||||
INC_PTR(str, str_end);
|
||||
INC_PTR(cs,str, str_end);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif /* USE_MB */
|
||||
while (str != str_end && likeconv(*str) != cmp)
|
||||
while (str != str_end && likeconv(cs,*str) != cmp)
|
||||
str++;
|
||||
if (str++ == str_end) return (-1);
|
||||
#ifdef USE_MB
|
||||
}
|
||||
#endif
|
||||
{
|
||||
int tmp=wild_case_compare(str,str_end,wildstr,wildend,escape);
|
||||
int tmp=wild_case_compare(cs,str,str_end,wildstr,wildend,escape);
|
||||
if (tmp <= 0)
|
||||
return (tmp);
|
||||
}
|
||||
@ -667,17 +738,23 @@ static int wild_case_compare(const char *str,const char *str_end,
|
||||
|
||||
int wild_case_compare(String &match,String &wild, char escape)
|
||||
{
|
||||
return wild_case_compare(match.ptr(),match.ptr()+match.length(),
|
||||
wild.ptr(), wild.ptr()+wild.length(),escape);
|
||||
DBUG_ENTER("wild_case_compare");
|
||||
DBUG_PRINT("enter",("match='%s', wild='%s', escape='%c'"
|
||||
,match.ptr(),wild.ptr(),escape));
|
||||
DBUG_RETURN(wild_case_compare(match.str_charset,match.ptr(),match.ptr()+match.length(),
|
||||
wild.ptr(), wild.ptr()+wild.length(),escape));
|
||||
}
|
||||
|
||||
/*
|
||||
** The following is used when using LIKE on binary strings
|
||||
*/
|
||||
|
||||
static int wild_compare(const char *str,const char *str_end,
|
||||
int wild_compare(const char *str,const char *str_end,
|
||||
const char *wildstr,const char *wildend,char escape)
|
||||
{
|
||||
DBUG_ENTER("wild_compare");
|
||||
DBUG_PRINT("enter",("str='%s', str_end='%s', wildstr='%s', wildend='%s', escape='%c'"
|
||||
,str,str_end,wildstr,wildend,escape));
|
||||
int result= -1; // Not found, using wildcards
|
||||
while (wildstr != wildend)
|
||||
{
|
||||
@ -686,17 +763,21 @@ static int wild_compare(const char *str,const char *str_end,
|
||||
if (*wildstr == escape && wildstr+1 != wildend)
|
||||
wildstr++;
|
||||
if (str == str_end || *wildstr++ != *str++)
|
||||
return(1);
|
||||
{
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (wildstr == wildend)
|
||||
return (str != str_end); // Match if both are at end
|
||||
{
|
||||
DBUG_RETURN(str != str_end); // Match if both are at end
|
||||
}
|
||||
result=1; // Found an anchor char
|
||||
}
|
||||
if (*wildstr == wild_one)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (str == str_end) // Skipp one char if possible
|
||||
return (result);
|
||||
if (str == str_end) // Skip one char if possible
|
||||
DBUG_RETURN(result);
|
||||
str++;
|
||||
} while (*++wildstr == wild_one && wildstr != wildend);
|
||||
if (wildstr == wildend)
|
||||
@ -713,17 +794,22 @@ static int wild_compare(const char *str,const char *str_end,
|
||||
if (*wildstr == wild_one)
|
||||
{
|
||||
if (str == str_end)
|
||||
return (-1);
|
||||
{
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
str++;
|
||||
continue;
|
||||
}
|
||||
break; // Not a wild character
|
||||
}
|
||||
if (wildstr == wildend)
|
||||
return(0); // Ok if wild_many is last
|
||||
{
|
||||
DBUG_RETURN(0); // Ok if wild_many is last
|
||||
}
|
||||
if (str == str_end)
|
||||
return -1;
|
||||
|
||||
{
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
char cmp;
|
||||
if ((cmp= *wildstr) == escape && wildstr+1 != wildend)
|
||||
cmp= *++wildstr;
|
||||
@ -732,22 +818,32 @@ static int wild_compare(const char *str,const char *str_end,
|
||||
{
|
||||
while (str != str_end && *str != cmp)
|
||||
str++;
|
||||
if (str++ == str_end) return (-1);
|
||||
if (str++ == str_end)
|
||||
{
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
{
|
||||
int tmp=wild_compare(str,str_end,wildstr,wildend,escape);
|
||||
if (tmp <= 0)
|
||||
return (tmp);
|
||||
{
|
||||
DBUG_RETURN(tmp);
|
||||
}
|
||||
}
|
||||
} while (str != str_end && wildstr[0] != wild_many);
|
||||
return(-1);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
}
|
||||
return (str != str_end ? 1 : 0);
|
||||
DBUG_RETURN(str != str_end ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
int wild_compare(String &match,String &wild, char escape)
|
||||
{
|
||||
return wild_compare(match.ptr(),match.ptr()+match.length(),
|
||||
wild.ptr(), wild.ptr()+wild.length(),escape);
|
||||
DBUG_ENTER("wild_compare");
|
||||
DBUG_PRINT("enter",("match='%s', wild='%s', escape='%c'"
|
||||
,match.ptr(),wild.ptr(),escape));
|
||||
DBUG_RETURN(wild_compare(match.ptr(),match.ptr()+match.length(),
|
||||
wild.ptr(), wild.ptr()+wild.length(),escape));
|
||||
}
|
||||
|
||||
|
||||
|
@ -24,31 +24,57 @@
|
||||
#define NOT_FIXED_DEC 31
|
||||
#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
|
||||
{
|
||||
char *Ptr;
|
||||
uint32 str_length,Alloced_length;
|
||||
bool alloced;
|
||||
CHARSET_INFO *str_charset;
|
||||
public:
|
||||
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)
|
||||
{ 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)
|
||||
{ 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)
|
||||
{ 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)
|
||||
{ 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)
|
||||
{ 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 delete(void *ptr_arg,size_t size) /*lint -e715 */
|
||||
{ sql_element_free(ptr_arg); }
|
||||
~String() { free(); }
|
||||
|
||||
inline CHARSET_INFO *charset() const { return str_charset; }
|
||||
inline uint32 length() const { return str_length;}
|
||||
inline uint32 alloced_length() const { return Alloced_length;}
|
||||
inline char& operator [] (uint32 i) const { return Ptr[i]; }
|
||||
@ -124,7 +150,7 @@ public:
|
||||
char *new_ptr;
|
||||
if (!(new_ptr=(char*) my_realloc(Ptr,arg_length,MYF(0))))
|
||||
{
|
||||
(void) my_free(Ptr,MYF(0));
|
||||
Alloced_length = 0;
|
||||
real_alloc(arg_length);
|
||||
}
|
||||
else
|
||||
@ -153,6 +179,7 @@ public:
|
||||
bool append(const char *s,uint32 arg_length=0);
|
||||
bool append(IO_CACHE* file, uint32 arg_length);
|
||||
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
|
||||
bool replace(uint32 offset,uint32 arg_length,const String &to);
|
||||
inline bool append(char chr)
|
||||
@ -171,8 +198,8 @@ public:
|
||||
}
|
||||
bool fill(uint32 max_length,char fill);
|
||||
void strip_sp();
|
||||
inline void caseup() { ::caseup(Ptr,str_length); }
|
||||
inline void casedn() { ::casedn(Ptr,str_length); }
|
||||
inline void caseup() { my_caseup(str_charset,Ptr,str_length); }
|
||||
inline void casedn() { my_casedn(str_charset,Ptr,str_length); }
|
||||
friend int sortcmp(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);
|
||||
@ -180,4 +207,49 @@ public:
|
||||
friend int wild_compare(String &match,String &wild,char escape);
|
||||
uint32 numchars();
|
||||
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);
|
||||
};
|
||||
|
337
configure.in
337
configure.in
@ -4,13 +4,13 @@ dnl Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(sql/mysqld.cc)
|
||||
AC_CANONICAL_SYSTEM
|
||||
# The Docs Makefile.am parses this line!
|
||||
AM_INIT_AUTOMAKE(mysql, 4.0.5-beta)
|
||||
AM_INIT_AUTOMAKE(mysql, 4.1.0-alpha)
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
|
||||
PROTOCOL_VERSION=10
|
||||
DOT_FRM_VERSION=6
|
||||
# See the libtool docs for information on how to do shared lib versions.
|
||||
SHARED_LIB_VERSION=11:0:0
|
||||
SHARED_LIB_VERSION=12:0:0
|
||||
|
||||
# Set all version vars based on $VERSION. How do we do this more elegant ?
|
||||
# Remember that regexps needs to quote [ and ] since this is run through m4
|
||||
@ -657,10 +657,13 @@ AC_ARG_WITH(mysqld-user,
|
||||
AC_SUBST(MYSQLD_USER)
|
||||
|
||||
# If we should allow LOAD DATA LOCAL
|
||||
AC_MSG_CHECKING(if we should should enable LOAD DATA LOCAL by default)
|
||||
AC_MSG_CHECKING(If we should should enable LOAD DATA LOCAL by default)
|
||||
AC_ARG_ENABLE(local-infile,
|
||||
[ --enable-local-infile Enable LOAD DATA LOCAL INFILE (default: disabled)],
|
||||
[ ENABLED_LOCAL_INFILE=$enableval ],
|
||||
Enable LOAD DATA LOCAL INFILE (default: disabled)],
|
||||
[
|
||||
ENABLED_LOCAL_INFILE=$enableval
|
||||
AC_DEFINE(ENABLED_LOCAL_INFILE)
|
||||
],
|
||||
[ ENABLED_LOCAL_INFILE=no ]
|
||||
)
|
||||
if test "$ENABLED_LOCAL_INFILE" = "yes"
|
||||
@ -1981,18 +1984,20 @@ fi
|
||||
AC_SUBST(readline_dir)
|
||||
AC_SUBST(readline_link)
|
||||
|
||||
|
||||
dnl In order to add new charset, you must add charset name to
|
||||
dnl this CHARSETS_AVAILABLE list and sql/share/charsets/Index.
|
||||
dnl If the character set uses strcoll or other special handling,
|
||||
dnl you must also create strings/ctype-$charset_name.c
|
||||
|
||||
AC_DIVERT_PUSH(0)
|
||||
CHARSETS_AVAILABLE="big5 cp1251 cp1257
|
||||
CHARSETS_AVAILABLE="armscii8 big5 cp1251 cp1257
|
||||
croat czech danish dec8 dos estonia euc_kr gb2312 gbk
|
||||
german1 greek hebrew hp8 hungarian koi8_ru koi8_ukr
|
||||
latin1 latin1_de latin2 latin5 sjis swe7 tis620 ujis
|
||||
usa7 win1250 win1251ukr"
|
||||
latin1 latin1_de latin2 latin5 sjis swe7 tis620 ucs2 ujis
|
||||
usa7 utf8 win1250 win1250ch win1251ukr"
|
||||
CHARSETS_DEPRECATED="win1251"
|
||||
CHARSETS_COMPLEX="big5 czech euc_kr gb2312 gbk latin1_de sjis tis620 ucs2 ujis utf8 win1250ch"
|
||||
DEFAULT_CHARSET=latin1
|
||||
AC_DIVERT_POP
|
||||
|
||||
@ -2016,208 +2021,154 @@ AC_MSG_CHECKING("character sets")
|
||||
if test "$extra_charsets" = none; then
|
||||
CHARSETS=""
|
||||
elif test "$extra_charsets" = complex; then
|
||||
CHARSETS=`/bin/ls -1 $srcdir/strings/ctype-*.c | \
|
||||
sed -e 's;^.*/ctype-;;' -e 's;.c$;;'`
|
||||
CHARSETS=`echo $CHARSETS` # get rid of line breaks
|
||||
else
|
||||
if test "$extra_charsets" = all; then
|
||||
CHARSETS="$CHARSETS_COMPLEX"
|
||||
elif test "$extra_charsets" = all; then
|
||||
CHARSETS="$CHARSETS_AVAILABLE $CHARSETS_DEPRECATED"
|
||||
else
|
||||
else
|
||||
CHARSETS=`echo $extra_charsets | sed -e 's/,/ /g'`
|
||||
fi
|
||||
fi
|
||||
|
||||
# Ensure that the default_charset is first in CHARSETS
|
||||
TMP_CHARSETS="$default_charset "
|
||||
for i in $CHARSETS
|
||||
do
|
||||
if test $i != $default_charset
|
||||
then
|
||||
TMP_CHARSETS="$TMP_CHARSETS $i"
|
||||
fi
|
||||
done
|
||||
CHARSETS=$TMP_CHARSETS
|
||||
CHARSETS="$DEFAULT_CHARSET $CHARSETS"
|
||||
|
||||
use_mb="no"
|
||||
|
||||
# Check if charsets are all good
|
||||
for cs in $CHARSETS
|
||||
do
|
||||
charset_okay=0
|
||||
for charset in $CHARSETS_AVAILABLE $CHARSETS_DEPRECATED
|
||||
do
|
||||
if test $cs = $charset; then charset_okay=1; fi
|
||||
done
|
||||
if test $charset_okay = 0;
|
||||
then
|
||||
case $cs in
|
||||
armscii8)
|
||||
AC_DEFINE(HAVE_CHARSET_armscii8)
|
||||
use_mb="yes"
|
||||
;;
|
||||
big5)
|
||||
AC_DEFINE(HAVE_CHARSET_big5)
|
||||
use_mb="yes"
|
||||
;;
|
||||
cp1251)
|
||||
AC_DEFINE(HAVE_CHARSET_cp1251)
|
||||
;;
|
||||
cp1257)
|
||||
AC_DEFINE(HAVE_CHARSET_cp1257)
|
||||
;;
|
||||
croat)
|
||||
AC_DEFINE(HAVE_CHARSET_croat)
|
||||
;;
|
||||
czech)
|
||||
AC_DEFINE(HAVE_CHARSET_czech)
|
||||
;;
|
||||
danish)
|
||||
AC_DEFINE(HAVE_CHARSET_danish)
|
||||
;;
|
||||
dec8)
|
||||
AC_DEFINE(HAVE_CHARSET_dec8)
|
||||
;;
|
||||
dos)
|
||||
AC_DEFINE(HAVE_CHARSET_dos)
|
||||
;;
|
||||
estonia)
|
||||
AC_DEFINE(HAVE_CHARSET_estonia)
|
||||
;;
|
||||
euc_kr)
|
||||
AC_DEFINE(HAVE_CHARSET_euc_kr)
|
||||
use_mb="yes"
|
||||
;;
|
||||
gb2312)
|
||||
AC_DEFINE(HAVE_CHARSET_gb2312)
|
||||
use_mb="yes"
|
||||
;;
|
||||
gbk)
|
||||
AC_DEFINE(HAVE_CHARSET_gbk)
|
||||
use_mb="yes"
|
||||
;;
|
||||
german1)
|
||||
AC_DEFINE(HAVE_CHARSET_german1)
|
||||
;;
|
||||
greek)
|
||||
AC_DEFINE(HAVE_CHARSET_greek)
|
||||
;;
|
||||
hebrew)
|
||||
AC_DEFINE(HAVE_CHARSET_hebrew)
|
||||
;;
|
||||
hp8)
|
||||
AC_DEFINE(HAVE_CHARSET_hp8)
|
||||
;;
|
||||
hungarian)
|
||||
AC_DEFINE(HAVE_CHARSET_hungarian)
|
||||
;;
|
||||
koi8_ru)
|
||||
AC_DEFINE(HAVE_CHARSET_koi8_ru)
|
||||
;;
|
||||
koi8_ukr)
|
||||
AC_DEFINE(HAVE_CHARSET_koi8_ukr)
|
||||
;;
|
||||
latin1)
|
||||
AC_DEFINE(HAVE_CHARSET_latin1)
|
||||
;;
|
||||
latin1_de)
|
||||
AC_DEFINE(HAVE_CHARSET_latin1_de)
|
||||
;;
|
||||
latin2)
|
||||
AC_DEFINE(HAVE_CHARSET_latin2)
|
||||
;;
|
||||
latin5)
|
||||
AC_DEFINE(HAVE_CHARSET_latin5)
|
||||
;;
|
||||
sjis)
|
||||
AC_DEFINE(HAVE_CHARSET_sjis)
|
||||
use_mb="yes"
|
||||
;;
|
||||
swe7)
|
||||
AC_DEFINE(HAVE_CHARSET_swe7)
|
||||
;;
|
||||
tis620)
|
||||
AC_DEFINE(HAVE_CHARSET_tis620)
|
||||
;;
|
||||
ucs2)
|
||||
AC_DEFINE(HAVE_CHARSET_ucs2)
|
||||
use_mb="yes"
|
||||
;;
|
||||
ujis)
|
||||
AC_DEFINE(HAVE_CHARSET_ujis)
|
||||
use_mb="yes"
|
||||
;;
|
||||
usa7)
|
||||
AC_DEFINE(HAVE_CHARSET_usa7)
|
||||
;;
|
||||
utf8)
|
||||
AC_DEFINE(HAVE_CHARSET_utf8)
|
||||
use_mb="yes"
|
||||
;;
|
||||
win1250)
|
||||
AC_DEFINE(HAVE_CHARSET_win1250)
|
||||
;;
|
||||
win1250ch)
|
||||
AC_DEFINE(HAVE_CHARSET_win1250ch)
|
||||
;;
|
||||
win1251)
|
||||
AC_DEFINE(HAVE_CHARSET_win1251)
|
||||
;;
|
||||
win1251ukr)
|
||||
AC_DEFINE(HAVE_CHARSET_win1251ukr)
|
||||
;;
|
||||
*)
|
||||
AC_MSG_ERROR([Charset $cs not available. (Available $CHARSETS_AVAILABLE).
|
||||
See the Installation chapter in the Reference Manual.]);
|
||||
fi
|
||||
esac
|
||||
done
|
||||
|
||||
CHARSET_SRCS=""
|
||||
CHARSETS_NEED_SOURCE=""
|
||||
CHARSET_DECLARATIONS=""
|
||||
CHARSET_COMP_CS_INIT="CHARSET_INFO compiled_charsets[[]] = {"
|
||||
dnl Always compile latin1
|
||||
AC_DEFINE(HAVE_CHARSET_latin1)
|
||||
|
||||
want_use_strcoll=0
|
||||
want_use_mb=0
|
||||
|
||||
index_file="$srcdir/sql/share/charsets/Index"
|
||||
|
||||
for c in $CHARSETS
|
||||
do
|
||||
# get the charset number from $index_file
|
||||
changequote(,)dnl
|
||||
subpat='^'"${c}"'[ ][ ]*\([0-9][0-9]*\)[^0-9]*$'
|
||||
number=`sed -e "/$subpat/!d" -e 's//\1/' $index_file`
|
||||
changequote([,])dnl
|
||||
# some sanity checking....
|
||||
if test X"$number" = X
|
||||
then
|
||||
AC_MSG_ERROR([No number was found in $index_file for the $c character set. This is a bug in the MySQL distribution. Please report this message to bugs@lists.mysql.com.])
|
||||
fi
|
||||
|
||||
cs_file="$srcdir/strings/ctype-$c.c"
|
||||
if test -f $cs_file
|
||||
then
|
||||
CHARSET_SRCS="${CHARSET_SRCS}ctype-$c.c "
|
||||
# get the strxfrm multiplier and max mb len from files
|
||||
subpat='^.*\\.configure\\. strxfrm_multiply_'"${c}"'='
|
||||
strx=`$AWK 'sub("'"$subpat"'", "") { print }' $cs_file`
|
||||
subpat='^.*\\.configure\\. mbmaxlen_'"${c}"'='
|
||||
maxl=`$AWK 'sub("'"$subpat"'", "") { print }' $cs_file`
|
||||
|
||||
CHARSET_DECLARATIONS="$CHARSET_DECLARATIONS
|
||||
|
||||
/* declarations for the ${c} character set, filled in by configure */
|
||||
extern uchar ctype_${c}[[]], to_lower_${c}[[]], to_upper_${c}[[]], sort_order_${c}[[]];"
|
||||
else
|
||||
CHARSETS_NEED_SOURCE="$CHARSETS_NEED_SOURCE $c"
|
||||
strx=''
|
||||
maxl=''
|
||||
fi
|
||||
|
||||
CHARSET_COMP_CS_INIT="$CHARSET_COMP_CS_INIT
|
||||
|
||||
/* this information is filled in by configure */
|
||||
{
|
||||
$number, /* number */
|
||||
\"$c\", /* name */
|
||||
ctype_${c},
|
||||
to_lower_${c},
|
||||
to_upper_${c},
|
||||
sort_order_${c},"
|
||||
|
||||
if test -n "$strx"
|
||||
then
|
||||
want_use_strcoll=1
|
||||
|
||||
CHARSET_DECLARATIONS="$CHARSET_DECLARATIONS
|
||||
extern int my_strcoll_${c}(const uchar *, const uchar *);
|
||||
extern int my_strxfrm_${c}(uchar *, const uchar *, int);
|
||||
extern int my_strnncoll_${c}(const uchar *, int, const uchar *, int);
|
||||
extern int my_strnxfrm_${c}(uchar *, const uchar *, int, int);
|
||||
extern my_bool my_like_range_${c}(const char *, uint, pchar, uint,
|
||||
char *, char *, uint *, uint *);"
|
||||
|
||||
CHARSET_COMP_CS_INIT="$CHARSET_COMP_CS_INIT
|
||||
$strx, /* strxfrm_multiply */
|
||||
my_strcoll_${c},
|
||||
my_strxfrm_${c},
|
||||
my_strnncoll_${c},
|
||||
my_strnxfrm_${c},
|
||||
my_like_range_${c},"
|
||||
else
|
||||
CHARSET_COMP_CS_INIT="$CHARSET_COMP_CS_INIT
|
||||
0, /* strxfrm_multiply */
|
||||
NULL, /* strcoll */
|
||||
NULL, /* strxfrm */
|
||||
NULL, /* strnncoll */
|
||||
NULL, /* strnxfrm */
|
||||
NULL, /* like_range */"
|
||||
fi
|
||||
|
||||
if test -n "$maxl"
|
||||
then
|
||||
want_use_mb=1
|
||||
|
||||
CHARSET_DECLARATIONS="$CHARSET_DECLARATIONS
|
||||
extern int ismbchar_${c}(const char *, const char *);
|
||||
extern my_bool ismbhead_${c}(uint);
|
||||
extern int mbcharlen_${c}(uint);"
|
||||
|
||||
|
||||
CHARSET_COMP_CS_INIT="$CHARSET_COMP_CS_INIT
|
||||
$maxl, /* mbmaxlen */
|
||||
ismbchar_${c},
|
||||
ismbhead_${c},
|
||||
mbcharlen_${c}"
|
||||
else
|
||||
CHARSET_COMP_CS_INIT="$CHARSET_COMP_CS_INIT
|
||||
0, /* mbmaxlen */
|
||||
NULL, /* ismbchar */
|
||||
NULL, /* ismbhead */
|
||||
NULL /* mbcharlen */"
|
||||
fi
|
||||
CHARSET_COMP_CS_INIT="$CHARSET_COMP_CS_INIT
|
||||
},"
|
||||
done
|
||||
|
||||
CHARSET_COMP_CS_INIT="$CHARSET_COMP_CS_INIT
|
||||
|
||||
/* this information is filled in by configure */
|
||||
{
|
||||
0, /* end-of-list marker */
|
||||
NullS,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
}
|
||||
};"
|
||||
|
||||
|
||||
if test $want_use_strcoll = 1
|
||||
then
|
||||
AC_DEFINE(USE_STRCOLL)
|
||||
fi
|
||||
|
||||
if test $want_use_mb = 1
|
||||
if test "$use_mb" = "yes"
|
||||
then
|
||||
AC_DEFINE(USE_MB)
|
||||
AC_DEFINE(USE_MB_IDENT)
|
||||
fi
|
||||
|
||||
# Temporary hack for USE_STRCOLL
|
||||
AC_DEFINE(USE_STRCOLL)
|
||||
|
||||
AC_SUBST(default_charset)
|
||||
AC_SUBST(CHARSET_SRCS)
|
||||
CHARSET_OBJS="`echo "$CHARSET_SRCS" | sed -e 's/\.c /.o /g'`"
|
||||
AC_SUBST(CHARSET_OBJS)
|
||||
AC_SUBST(CHARSETS_NEED_SOURCE)
|
||||
|
||||
dnl We can't use AC_SUBST because these substitutions are too long.
|
||||
dnl I don't want to use sed, either, because there's a reason why
|
||||
dnl autoconf breaks up the substitution commands. So we'll just
|
||||
dnl write to a file and #include it.
|
||||
dnl AC_SUBST(CHARSET_DECLARATIONS)
|
||||
dnl AC_SUBST(CHARSET_COMP_CS_INIT)
|
||||
dnl sed -e "s%@CHARSET_DECLARATIONS@%$CHARSET_DECLARATIONS%g" \
|
||||
dnl -e "s%@CHARSET_COMP_CS_INIT@%$CHARSET_COMP_CS_INIT%g" \
|
||||
dnl $srcdir/strings/ctype.c.in > $srcdir/strings/ctype.c
|
||||
|
||||
cat <<EOF > $srcdir/strings/ctype_autoconf.c
|
||||
/* This file is generated automatically by configure. */$CHARSET_DECLARATIONS
|
||||
|
||||
$CHARSET_COMP_CS_INIT
|
||||
EOF
|
||||
AC_DEFINE_UNQUOTED(DEFAULT_CHARSET_NAME,"$default_charset")
|
||||
|
||||
AC_MSG_RESULT([default: $default_charset; compiled in: $CHARSETS])
|
||||
|
||||
@ -2417,7 +2368,7 @@ AC_OUTPUT(Makefile extra/Makefile mysys/Makefile isam/Makefile \
|
||||
os2/Makefile os2/include/Makefile os2/include/sys/Makefile \
|
||||
man/Makefile BUILD/Makefile readline/Makefile vio/Makefile \
|
||||
libmysql_r/Makefile libmysqld/Makefile libmysqld/examples/Makefile \
|
||||
libmysql/Makefile client/Makefile os2/Makefile \
|
||||
libmysql/Makefile client/Makefile \
|
||||
pstack/Makefile pstack/aout/Makefile sql/Makefile sql/share/Makefile \
|
||||
merge/Makefile dbug/Makefile scripts/Makefile \
|
||||
include/Makefile sql-bench/Makefile tools/Makefile \
|
||||
|
@ -157,7 +157,7 @@ static int get_answer(QUESTION_WIDGET* w)
|
||||
char c;
|
||||
if (!fgets(buf,sizeof(buf),w->in))
|
||||
die("Failed fgets on input stream");
|
||||
switch ((c=tolower(*buf)))
|
||||
switch ((c=my_tolower(system_charset_info,*buf)))
|
||||
{
|
||||
case '\n':
|
||||
return w->default_ind;
|
||||
|
@ -113,7 +113,7 @@ char *argv[];
|
||||
exit(1);
|
||||
|
||||
for (i=1,pos=word_end_chars ; i < 256 ; i++)
|
||||
if (isspace(i))
|
||||
if (my_isspace(system_charset_info,i))
|
||||
*pos++=i;
|
||||
*pos=0;
|
||||
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");
|
||||
static uchar hex_val(char c)
|
||||
{
|
||||
uchar l;
|
||||
if (isdigit(c))
|
||||
if (my_isdigit(system_charset_info,c))
|
||||
return c - '0';
|
||||
l = tolower(c);
|
||||
l = my_tolower(system_charset_info,c);
|
||||
if (l < 'a' || l > 'f')
|
||||
return HEX_INVALID;
|
||||
return (uchar)10 + ((uchar)c - (uchar)'a');
|
||||
@ -203,9 +203,11 @@ static int init_sym_entry(SYM_ENTRY* se, char* buf)
|
||||
|
||||
if (!se->addr)
|
||||
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;
|
||||
/* now we are on the symbol */
|
||||
for (p = se->symbol, p_end = se->symbol + sizeof(se->symbol) - 1;
|
||||
@ -285,7 +287,8 @@ static void do_resolve()
|
||||
while (fgets(buf, sizeof(buf), fp_dump))
|
||||
{
|
||||
p = buf;
|
||||
while(isspace(*p))
|
||||
/* skip space */
|
||||
while (my_isspace(system_charset_info,*p))
|
||||
++p;
|
||||
|
||||
if (*p++ == '0' && *p++ == 'x')
|
||||
|
@ -122,7 +122,7 @@ int main(int argc, char **argv)
|
||||
{
|
||||
ip = *argv++;
|
||||
|
||||
if (isdigit(ip[0]))
|
||||
if (my_isdigit(system_charset_info,ip[0]))
|
||||
{
|
||||
taddr = inet_addr(ip);
|
||||
if (taddr == htonl(INADDR_BROADCAST))
|
||||
|
@ -20,10 +20,12 @@
|
||||
|
||||
static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records,
|
||||
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 */
|
||||
|
||||
int heap_check_heap(HP_INFO *info,my_bool print_status)
|
||||
int heap_check_heap(HP_INFO *info, my_bool print_status)
|
||||
{
|
||||
int error;
|
||||
uint key;
|
||||
@ -31,8 +33,13 @@ int heap_check_heap(HP_INFO *info,my_bool print_status)
|
||||
DBUG_ENTER("heap_check_keys");
|
||||
|
||||
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);
|
||||
}
|
||||
@ -50,7 +57,7 @@ static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records,
|
||||
for (i=found=max_links=seek=0 ; i < records ; 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)
|
||||
{
|
||||
found++;
|
||||
@ -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)
|
||||
{
|
||||
seek+= ++links;
|
||||
if ((rec_link=_hp_mask(_hp_rec_hashnr(keydef,hash_info->ptr_to_rec),
|
||||
blength,records))
|
||||
if ((rec_link = hp_mask(hp_rec_hashnr(keydef, hash_info->ptr_to_rec),
|
||||
blength, records))
|
||||
!= i)
|
||||
{
|
||||
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,
|
||||
(float) seek / (float) (records ? records : 1));
|
||||
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, ¬_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 @@
|
||||
|
||||
#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))
|
||||
{
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <my_pthread.h>
|
||||
#endif
|
||||
#include "heap.h" /* Structs & some defines */
|
||||
#include "my_tree.h"
|
||||
|
||||
/*
|
||||
When allocating keys /rows in the internal block structure, do it
|
||||
@ -40,10 +41,10 @@ extern LIST *heap_open_list,*heap_share_list;
|
||||
#define test_active(info) \
|
||||
if (!(info->update & HA_STATE_AKTIV))\
|
||||
{ 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 */
|
||||
#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
|
||||
{
|
||||
@ -51,40 +52,52 @@ typedef struct st_hp_hash_info
|
||||
byte *ptr_to_rec;
|
||||
} HASH_INFO;
|
||||
|
||||
typedef struct {
|
||||
HA_KEYSEG *keyseg;
|
||||
uint key_length;
|
||||
uint search_flag;
|
||||
} heap_rb_param;
|
||||
|
||||
/* Prototypes for intern functions */
|
||||
|
||||
extern HP_SHARE *_hp_find_named_heap(const char *name);
|
||||
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 int _hp_get_new_block(HP_BLOCK *info, ulong* alloc_length);
|
||||
extern void _hp_free(HP_SHARE *info);
|
||||
extern byte *_hp_free_level(HP_BLOCK *block,uint level,HP_PTRS *pos,
|
||||
extern HP_SHARE *hp_find_named_heap(const char *name);
|
||||
extern int hp_rectest(HP_INFO *info,const byte *old);
|
||||
extern byte *hp_find_block(HP_BLOCK *info,ulong pos);
|
||||
extern int hp_get_new_block(HP_BLOCK *info, ulong* alloc_length);
|
||||
extern void hp_free(HP_SHARE *info);
|
||||
extern byte *hp_free_level(HP_BLOCK *block,uint level,HP_PTRS *pos,
|
||||
byte *last_pos);
|
||||
extern int _hp_write_key(HP_SHARE *info,HP_KEYDEF *keyinfo,
|
||||
const byte *record,byte *recpos);
|
||||
extern int _hp_delete_key(HP_INFO *info,HP_KEYDEF *keyinfo,
|
||||
extern int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
|
||||
const byte *record, byte *recpos);
|
||||
extern int hp_rb_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
|
||||
const byte *record, byte *recpos);
|
||||
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 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);
|
||||
extern byte *_hp_search_next(HP_INFO *info, HP_KEYDEF *keyinfo,
|
||||
const byte *key,
|
||||
HASH_INFO *pos);
|
||||
extern ulong _hp_hashnr(HP_KEYDEF *keyinfo,const byte *key);
|
||||
extern ulong _hp_rec_hashnr(HP_KEYDEF *keyinfo,const byte *rec);
|
||||
extern ulong _hp_mask(ulong hashnr,ulong buffmax,ulong maxlength);
|
||||
extern void _hp_movelink(HASH_INFO *pos,HASH_INFO *next_link,
|
||||
extern byte *hp_search_next(HP_INFO *info, HP_KEYDEF *keyinfo,
|
||||
const byte *key, HASH_INFO *pos);
|
||||
extern ulong hp_hashnr(HP_KEYDEF *keyinfo,const byte *key);
|
||||
extern ulong hp_rec_hashnr(HP_KEYDEF *keyinfo,const byte *rec);
|
||||
extern ulong hp_mask(ulong hashnr,ulong buffmax,ulong maxlength);
|
||||
extern void hp_movelink(HASH_INFO *pos,HASH_INFO *next_link,
|
||||
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);
|
||||
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);
|
||||
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 int _hp_close(register HP_INFO *info);
|
||||
extern void _hp_clear(HP_SHARE *info);
|
||||
|
||||
extern int hp_close(register HP_INFO *info);
|
||||
extern void hp_clear(HP_SHARE *info);
|
||||
extern uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old);
|
||||
#ifdef THREAD
|
||||
extern pthread_mutex_t THR_LOCK_heap;
|
||||
#else
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
/* 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;
|
||||
reg3 HP_PTRS *ptr;
|
||||
@ -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 */
|
||||
/* 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;
|
||||
HP_PTRS *root;
|
||||
@ -84,7 +84,7 @@ int _hp_get_new_block(HP_BLOCK *block, ulong *alloc_length)
|
||||
|
||||
/* 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;
|
||||
byte *next_ptr;
|
||||
@ -99,7 +99,7 @@ byte *_hp_free_level(HP_BLOCK *block, uint level, HP_PTRS *pos, byte *last_pos)
|
||||
|
||||
next_ptr=(byte*) (pos+1);
|
||||
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);
|
||||
}
|
||||
if ((byte*) pos != last_pos)
|
||||
|
@ -24,26 +24,34 @@
|
||||
|
||||
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;
|
||||
DBUG_ENTER("_hp_clear");
|
||||
DBUG_ENTER("hp_clear");
|
||||
|
||||
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));
|
||||
info->block.levels=0;
|
||||
for (key=0 ; key < info->keys ; key++)
|
||||
{
|
||||
HP_BLOCK *block= &info->keydef[key].block;
|
||||
HP_KEYDEF *keyinfo = info->keydef + key;
|
||||
if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
|
||||
{
|
||||
delete_tree(&keyinfo->rb_tree);
|
||||
}
|
||||
else
|
||||
{
|
||||
HP_BLOCK *block= &keyinfo->block;
|
||||
if (block->levels)
|
||||
VOID(_hp_free_level(block,block->levels,block->root,(byte*) 0));
|
||||
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->blength=1;
|
||||
info->changed=0;
|
||||
|
@ -26,16 +26,16 @@ int heap_close(HP_INFO *info)
|
||||
int tmp;
|
||||
DBUG_ENTER("heap_close");
|
||||
pthread_mutex_lock(&THR_LOCK_heap);
|
||||
tmp= _hp_close(info);
|
||||
tmp= hp_close(info);
|
||||
pthread_mutex_unlock(&THR_LOCK_heap);
|
||||
DBUG_RETURN(tmp);
|
||||
}
|
||||
|
||||
|
||||
int _hp_close(register HP_INFO *info)
|
||||
int hp_close(register HP_INFO *info)
|
||||
{
|
||||
int error=0;
|
||||
DBUG_ENTER("_hp_close");
|
||||
DBUG_ENTER("hp_close");
|
||||
#ifndef DBUG_OFF
|
||||
if (info->s->changed && heap_check_heap(info,0))
|
||||
{
|
||||
@ -45,7 +45,7 @@ int _hp_close(register HP_INFO *info)
|
||||
info->s->changed=0;
|
||||
heap_open_list=list_delete(heap_open_list,&info->open_list);
|
||||
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));
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
177
heap/hp_create.c
177
heap/hp_create.c
@ -14,30 +14,164 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
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"
|
||||
|
||||
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");
|
||||
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;
|
||||
}
|
||||
|
||||
if (!share)
|
||||
{
|
||||
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
|
||||
{
|
||||
my_errno=ENOENT;
|
||||
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);
|
||||
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, ¬_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)
|
||||
@ -47,32 +181,31 @@ int heap_delete_table(const char *name)
|
||||
DBUG_ENTER("heap_delete_table");
|
||||
|
||||
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)
|
||||
_hp_free(share);
|
||||
hp_free(share);
|
||||
else
|
||||
share->delete_on_close=1;
|
||||
result=0;
|
||||
share->delete_on_close= 1;
|
||||
result= 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
result=my_errno=ENOENT;
|
||||
result= my_errno=ENOENT;
|
||||
}
|
||||
pthread_mutex_unlock(&THR_LOCK_heap);
|
||||
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);
|
||||
_hp_clear(share); /* Remove blocks from memory */
|
||||
heap_share_list= list_delete(heap_share_list, &share->open_list);
|
||||
hp_clear(share); /* Remove blocks from memory */
|
||||
#ifdef THREAD
|
||||
thr_lock_delete(&share->lock);
|
||||
VOID(pthread_mutex_destroy(&share->intern_lock));
|
||||
#endif
|
||||
my_free((gptr) share->name,MYF(0));
|
||||
my_free((gptr) share,MYF(0));
|
||||
my_free((gptr) share->name, MYF(0));
|
||||
my_free((gptr) share, MYF(0));
|
||||
return;
|
||||
}
|
||||
|
@ -20,25 +20,26 @@
|
||||
|
||||
int heap_delete(HP_INFO *info, const byte *record)
|
||||
{
|
||||
uint key;
|
||||
byte *pos;
|
||||
HP_SHARE *share=info->s;
|
||||
HP_KEYDEF *keydef, *end, *p_lastinx;
|
||||
DBUG_ENTER("heap_delete");
|
||||
DBUG_PRINT("enter",("info: %lx record: %lx",info,record));
|
||||
|
||||
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 */
|
||||
share->changed=1;
|
||||
|
||||
if ( --(share->records) < share->blength >> 1) share->blength>>=1;
|
||||
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,
|
||||
key == (uint) info->lastinx))
|
||||
if ((*keydef->delete_key)(info, keydef, record, pos, keydef == p_lastinx))
|
||||
goto err;
|
||||
}
|
||||
|
||||
@ -49,22 +50,39 @@ int heap_delete(HP_INFO *info, const byte *record)
|
||||
share->deleted++;
|
||||
info->current_hash_ptr=0;
|
||||
DBUG_RETURN(0);
|
||||
err:
|
||||
err:
|
||||
if (++(share->records) == share->blength)
|
||||
share->blength+= share->blength;
|
||||
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 */
|
||||
/* 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)
|
||||
{
|
||||
ulong blength,pos2,pos_hashnr,lastpos_hashnr;
|
||||
HASH_INFO *lastpos,*gpos,*pos,*pos3,*empty,*last_ptr;
|
||||
HP_SHARE *share=info->s;
|
||||
DBUG_ENTER("_hp_delete_key");
|
||||
DBUG_ENTER("hp_delete_key");
|
||||
|
||||
blength=share->blength;
|
||||
if (share->records+1 == blength)
|
||||
@ -74,13 +92,13 @@ int _hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
|
||||
|
||||
/* Search after record with key */
|
||||
pos= hp_find_hash(&keyinfo->block,
|
||||
_hp_mask(_hp_rec_hashnr(keyinfo,record),blength,
|
||||
share->records+1));
|
||||
hp_mask(hp_rec_hashnr(keyinfo, record), blength,
|
||||
share->records + 1));
|
||||
gpos = pos3 = 0;
|
||||
|
||||
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 */
|
||||
gpos=pos;
|
||||
if (!(pos=pos->next_key))
|
||||
@ -113,33 +131,33 @@ int _hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
|
||||
DBUG_RETURN (0);
|
||||
|
||||
/* 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=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));
|
||||
if (pos == empty) /* Move to empty position. */
|
||||
{
|
||||
empty[0]=lastpos[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= hp_find_hash(&keyinfo->block,
|
||||
_hp_mask(pos_hashnr,share->blength,share->records));
|
||||
hp_mask(pos_hashnr, share->blength, share->records));
|
||||
if (pos != pos3)
|
||||
{ /* pos is on wrong posit */
|
||||
empty[0]=pos[0]; /* Save it 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);
|
||||
}
|
||||
pos2= _hp_mask(lastpos_hashnr,blength,share->records+1);
|
||||
if (pos2 == _hp_mask(pos_hashnr,blength,share->records+1))
|
||||
pos2= hp_mask(lastpos_hashnr, blength, share->records + 1);
|
||||
if (pos2 == hp_mask(pos_hashnr, blength, share->records + 1))
|
||||
{ /* Identical key-positions */
|
||||
if (pos2 != share->records)
|
||||
{
|
||||
empty[0]=lastpos[0];
|
||||
_hp_movelink(lastpos,pos,empty);
|
||||
hp_movelink(lastpos, pos, empty);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
pos3= pos; /* Link pos->next after lastpos */
|
||||
@ -147,7 +165,7 @@ int _hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
|
||||
else pos3= 0; /* Different positions merge */
|
||||
|
||||
empty[0]=lastpos[0];
|
||||
_hp_movelink(pos3,empty,pos->next_key);
|
||||
hp_movelink(pos3, empty, pos->next_key);
|
||||
pos->next_key=empty;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
241
heap/hp_hash.c
241
heap/hp_hash.c
@ -19,30 +19,73 @@
|
||||
#include "heapdef.h"
|
||||
#include <m_ctype.h>
|
||||
|
||||
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)
|
||||
{
|
||||
ha_rows start_pos, end_pos;
|
||||
HP_KEYDEF *keyinfo= info->s->keydef + inx;
|
||||
TREE *rb_tree = &keyinfo->rb_tree;
|
||||
heap_rb_param custom_arg;
|
||||
|
||||
info->lastinx = inx;
|
||||
custom_arg.keyseg = keyinfo->seg;
|
||||
custom_arg.search_flag = SEARCH_FIND | SEARCH_SAME;
|
||||
custom_arg.key_length = start_key_len;
|
||||
if (start_key)
|
||||
{
|
||||
hp_rb_pack_key(keyinfo, info->recbuf, start_key);
|
||||
start_pos= tree_record_pos(rb_tree, info->recbuf, start_search_flag,
|
||||
&custom_arg);
|
||||
}
|
||||
else
|
||||
{
|
||||
start_pos= 0;
|
||||
}
|
||||
|
||||
custom_arg.key_length = end_key_len;
|
||||
if (end_key)
|
||||
{
|
||||
hp_rb_pack_key(keyinfo, info->recbuf, end_key);
|
||||
end_pos= tree_record_pos(rb_tree, info->recbuf, end_search_flag,
|
||||
&custom_arg);
|
||||
}
|
||||
else
|
||||
{
|
||||
end_pos= rb_tree->elements_in_tree + (ha_rows)1;
|
||||
}
|
||||
|
||||
if (start_pos == HA_POS_ERROR || end_pos == HA_POS_ERROR)
|
||||
return HA_POS_ERROR;
|
||||
return end_pos < start_pos ? (ha_rows) 0 :
|
||||
(end_pos == start_pos ? (ha_rows) 1 : end_pos - start_pos);
|
||||
}
|
||||
|
||||
/* Search after a record based on a key */
|
||||
/* Sets info->current_ptr to found record */
|
||||
/* next_flag: Search=0, next=1, prev =2, same =3 */
|
||||
|
||||
byte *_hp_search(HP_INFO *info, HP_KEYDEF *keyinfo, const byte *key,
|
||||
byte *hp_search(HP_INFO *info, HP_KEYDEF *keyinfo, const byte *key,
|
||||
uint nextflag)
|
||||
{
|
||||
reg1 HASH_INFO *pos,*prev_ptr;
|
||||
int flag;
|
||||
uint old_nextflag;
|
||||
HP_SHARE *share=info->s;
|
||||
DBUG_ENTER("_hp_search");
|
||||
|
||||
DBUG_ENTER("hp_search");
|
||||
old_nextflag=nextflag;
|
||||
flag=1;
|
||||
prev_ptr=0;
|
||||
|
||||
if (share->records)
|
||||
{
|
||||
pos=hp_find_hash(&keyinfo->block,_hp_mask(_hp_hashnr(keyinfo,key),
|
||||
share->blength,share->records));
|
||||
pos=hp_find_hash(&keyinfo->block, hp_mask(hp_hashnr(keyinfo, key),
|
||||
share->blength, share->records));
|
||||
do
|
||||
{
|
||||
if (!_hp_key_cmp(keyinfo,pos->ptr_to_rec,key))
|
||||
if (!hp_key_cmp(keyinfo, pos->ptr_to_rec, key))
|
||||
{
|
||||
switch (nextflag) {
|
||||
case 0: /* Search after key */
|
||||
@ -74,8 +117,8 @@ byte *_hp_search(HP_INFO *info, HP_KEYDEF *keyinfo, const byte *key,
|
||||
{
|
||||
flag=0; /* Reset flag */
|
||||
if (hp_find_hash(&keyinfo->block,
|
||||
_hp_mask(_hp_rec_hashnr(keyinfo,pos->ptr_to_rec),
|
||||
share->blength,share->records)) != pos)
|
||||
hp_mask(hp_rec_hashnr(keyinfo, pos->ptr_to_rec),
|
||||
share->blength, share->records)) != pos)
|
||||
break; /* Wrong link */
|
||||
}
|
||||
}
|
||||
@ -102,14 +145,14 @@ byte *_hp_search(HP_INFO *info, HP_KEYDEF *keyinfo, const byte *key,
|
||||
since last read !
|
||||
*/
|
||||
|
||||
byte *_hp_search_next(HP_INFO *info, HP_KEYDEF *keyinfo, const byte *key,
|
||||
byte *hp_search_next(HP_INFO *info, HP_KEYDEF *keyinfo, const byte *key,
|
||||
HASH_INFO *pos)
|
||||
{
|
||||
DBUG_ENTER("_hp_search_next");
|
||||
DBUG_ENTER("hp_search_next");
|
||||
|
||||
while ((pos= pos->next_key))
|
||||
{
|
||||
if (!_hp_key_cmp(keyinfo,pos->ptr_to_rec,key))
|
||||
if (! hp_key_cmp(keyinfo, pos->ptr_to_rec, key))
|
||||
{
|
||||
info->current_hash_ptr=pos;
|
||||
DBUG_RETURN (info->current_ptr= pos->ptr_to_rec);
|
||||
@ -124,7 +167,7 @@ byte *_hp_search_next(HP_INFO *info, HP_KEYDEF *keyinfo, const byte *key,
|
||||
|
||||
/* Calculate pos according to keys */
|
||||
|
||||
ulong _hp_mask(ulong hashnr, ulong buffmax, ulong maxlength)
|
||||
ulong hp_mask(ulong hashnr, ulong buffmax, ulong maxlength)
|
||||
{
|
||||
if ((hashnr & (buffmax-1)) < maxlength) return (hashnr & (buffmax-1));
|
||||
return (hashnr & ((buffmax >> 1) -1));
|
||||
@ -133,7 +176,7 @@ ulong _hp_mask(ulong hashnr, ulong buffmax, ulong maxlength)
|
||||
|
||||
/* Change link from pos to new_link */
|
||||
|
||||
void _hp_movelink(HASH_INFO *pos, HASH_INFO *next_link, HASH_INFO *newlink)
|
||||
void hp_movelink(HASH_INFO *pos, HASH_INFO *next_link, HASH_INFO *newlink)
|
||||
{
|
||||
HASH_INFO *old_link;
|
||||
do
|
||||
@ -149,10 +192,11 @@ void _hp_movelink(HASH_INFO *pos, HASH_INFO *next_link, HASH_INFO *newlink)
|
||||
|
||||
/* Calc hashvalue for a key */
|
||||
|
||||
ulong _hp_hashnr(register HP_KEYDEF *keydef, register const byte *key)
|
||||
ulong hp_hashnr(register HP_KEYDEF *keydef, register const byte *key)
|
||||
{
|
||||
register ulong nr=1, nr2=4;
|
||||
HP_KEYSEG *seg,*endseg;
|
||||
/*register*/
|
||||
ulong nr=1, nr2=4;
|
||||
HA_KEYSEG *seg,*endseg;
|
||||
|
||||
for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
|
||||
{
|
||||
@ -170,12 +214,7 @@ ulong _hp_hashnr(register HP_KEYDEF *keydef, register const byte *key)
|
||||
}
|
||||
if (seg->type == HA_KEYTYPE_TEXT)
|
||||
{
|
||||
for (; pos < (uchar*) key ; pos++)
|
||||
{
|
||||
nr^=(ulong) ((((uint) nr & 63)+nr2) *
|
||||
((uint) my_sort_order[(uint) *pos])) + (nr << 8);
|
||||
nr2+=3;
|
||||
}
|
||||
seg->charset->hash_sort(seg->charset,pos,((uchar*)key)-pos,&nr,&nr2);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -191,10 +230,11 @@ ulong _hp_hashnr(register HP_KEYDEF *keydef, register const byte *key)
|
||||
|
||||
/* Calc hashvalue for a key in a record */
|
||||
|
||||
ulong _hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec)
|
||||
ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec)
|
||||
{
|
||||
register ulong nr=1, nr2=4;
|
||||
HP_KEYSEG *seg,*endseg;
|
||||
/*register*/
|
||||
ulong nr=1, nr2=4;
|
||||
HA_KEYSEG *seg,*endseg;
|
||||
|
||||
for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
|
||||
{
|
||||
@ -209,12 +249,7 @@ ulong _hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec)
|
||||
}
|
||||
if (seg->type == HA_KEYTYPE_TEXT)
|
||||
{
|
||||
for (; pos < end ; pos++)
|
||||
{
|
||||
nr^=(ulong) ((((uint) nr & 63)+nr2)*
|
||||
((uint) my_sort_order[(uint) *pos]))+ (nr << 8);
|
||||
nr2+=3;
|
||||
}
|
||||
seg->charset->hash_sort(seg->charset,pos,end-pos,&nr,&nr2);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -245,10 +280,10 @@ ulong _hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec)
|
||||
* far, and works well on both numbers and strings.
|
||||
*/
|
||||
|
||||
ulong _hp_hashnr(register HP_KEYDEF *keydef, register const byte *key)
|
||||
ulong hp_hashnr(register HP_KEYDEF *keydef, register const byte *key)
|
||||
{
|
||||
register ulong nr=0;
|
||||
HP_KEYSEG *seg,*endseg;
|
||||
HA_KEYSEG *seg,*endseg;
|
||||
|
||||
for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
|
||||
{
|
||||
@ -266,11 +301,7 @@ ulong _hp_hashnr(register HP_KEYDEF *keydef, register const byte *key)
|
||||
}
|
||||
if (seg->type == HA_KEYTYPE_TEXT)
|
||||
{
|
||||
for (; pos < (uchar*) key ; pos++)
|
||||
{
|
||||
nr *=16777619;
|
||||
nr ^=((uint) my_sort_order[(uint) *pos]);
|
||||
}
|
||||
seg->charset->hash_sort(seg->charset,pos,((uchar*)key)-pos,&nr,NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -286,10 +317,10 @@ ulong _hp_hashnr(register HP_KEYDEF *keydef, register const byte *key)
|
||||
|
||||
/* Calc hashvalue for a key in a record */
|
||||
|
||||
ulong _hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec)
|
||||
ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec)
|
||||
{
|
||||
register ulong nr=0;
|
||||
HP_KEYSEG *seg,*endseg;
|
||||
HA_KEYSEG *seg,*endseg;
|
||||
|
||||
for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
|
||||
{
|
||||
@ -304,11 +335,7 @@ ulong _hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec)
|
||||
}
|
||||
if (seg->type == HA_KEYTYPE_TEXT)
|
||||
{
|
||||
for ( ; pos < end ; pos++)
|
||||
{
|
||||
nr *=16777619;
|
||||
nr ^=(uint) my_sort_order[(uint) *pos];
|
||||
}
|
||||
seg->charset->hash_sort(seg->charset,pos,((uchar*)key)-pos,&nr,NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -327,9 +354,9 @@ ulong _hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec)
|
||||
|
||||
/* Compare keys for two records. Returns 0 if they are identical */
|
||||
|
||||
int _hp_rec_key_cmp(HP_KEYDEF *keydef, const byte *rec1, const byte *rec2)
|
||||
int hp_rec_key_cmp(HP_KEYDEF *keydef, const byte *rec1, const byte *rec2)
|
||||
{
|
||||
HP_KEYSEG *seg,*endseg;
|
||||
HA_KEYSEG *seg,*endseg;
|
||||
|
||||
for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
|
||||
{
|
||||
@ -343,7 +370,7 @@ int _hp_rec_key_cmp(HP_KEYDEF *keydef, const byte *rec1, const byte *rec2)
|
||||
}
|
||||
if (seg->type == HA_KEYTYPE_TEXT)
|
||||
{
|
||||
if (my_sortcmp(rec1+seg->start,rec2+seg->start,seg->length))
|
||||
if (my_strnncoll(seg->charset,rec1+seg->start,seg->length,rec2+seg->start,seg->length))
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
@ -357,9 +384,9 @@ int _hp_rec_key_cmp(HP_KEYDEF *keydef, const byte *rec1, const byte *rec2)
|
||||
|
||||
/* Compare a key in a record to a whole key */
|
||||
|
||||
int _hp_key_cmp(HP_KEYDEF *keydef, const byte *rec, const byte *key)
|
||||
int hp_key_cmp(HP_KEYDEF *keydef, const byte *rec, const byte *key)
|
||||
{
|
||||
HP_KEYSEG *seg,*endseg;
|
||||
HA_KEYSEG *seg,*endseg;
|
||||
|
||||
for (seg=keydef->seg,endseg=seg+keydef->keysegs ;
|
||||
seg < endseg ;
|
||||
@ -375,7 +402,7 @@ int _hp_key_cmp(HP_KEYDEF *keydef, const byte *rec, const byte *key)
|
||||
}
|
||||
if (seg->type == HA_KEYTYPE_TEXT)
|
||||
{
|
||||
if (my_sortcmp(rec+seg->start,key,seg->length))
|
||||
if (my_strnncoll(seg->charset,rec+seg->start,seg->length,key,seg->length))
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
@ -390,9 +417,9 @@ int _hp_key_cmp(HP_KEYDEF *keydef, const byte *rec, const byte *key)
|
||||
|
||||
/* Copy a key from a record to a keybuffer */
|
||||
|
||||
void _hp_make_key(HP_KEYDEF *keydef, byte *key, const byte *rec)
|
||||
void hp_make_key(HP_KEYDEF *keydef, byte *key, const byte *rec)
|
||||
{
|
||||
HP_KEYSEG *seg,*endseg;
|
||||
HA_KEYSEG *seg,*endseg;
|
||||
|
||||
for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
|
||||
{
|
||||
@ -403,6 +430,64 @@ void _hp_make_key(HP_KEYDEF *keydef, byte *key, const byte *rec)
|
||||
}
|
||||
}
|
||||
|
||||
uint hp_rb_make_key(HP_KEYDEF *keydef, byte *key,
|
||||
const byte *rec, byte *recpos)
|
||||
{
|
||||
byte *start_key= key;
|
||||
HA_KEYSEG *seg, *endseg;
|
||||
|
||||
for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; seg++)
|
||||
{
|
||||
if (seg->null_bit)
|
||||
{
|
||||
if (!(*key++= 1 - test(rec[seg->null_pos] & seg->null_bit)))
|
||||
continue;
|
||||
}
|
||||
memcpy(key, rec + seg->start, (size_t) seg->length);
|
||||
key+= seg->length;
|
||||
}
|
||||
memcpy(key, &recpos, sizeof(byte*));
|
||||
return key - start_key;
|
||||
}
|
||||
|
||||
uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old)
|
||||
{
|
||||
HA_KEYSEG *seg, *endseg;
|
||||
uchar *start_key= key;
|
||||
|
||||
for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg;
|
||||
old+= seg->length, seg++)
|
||||
{
|
||||
if (seg->null_bit)
|
||||
{
|
||||
if (!(*key++= (char) 1 - *old++))
|
||||
continue;
|
||||
}
|
||||
memcpy((byte*) key, old, seg->length);
|
||||
key+= seg->length;
|
||||
}
|
||||
return key - start_key;
|
||||
}
|
||||
|
||||
uint hp_rb_key_length(HP_KEYDEF *keydef,
|
||||
const byte *key __attribute__((unused)))
|
||||
{
|
||||
return keydef->length;
|
||||
}
|
||||
|
||||
uint hp_rb_null_key_length(HP_KEYDEF *keydef, const byte *key)
|
||||
{
|
||||
const byte *start_key= key;
|
||||
HA_KEYSEG *seg, *endseg;
|
||||
|
||||
for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; seg++)
|
||||
{
|
||||
if (seg->null_bit && !*key++)
|
||||
continue;
|
||||
key+= seg->length;
|
||||
}
|
||||
return key - start_key;
|
||||
}
|
||||
|
||||
/*
|
||||
Test if any of the key parts are NULL.
|
||||
@ -413,7 +498,7 @@ void _hp_make_key(HP_KEYDEF *keydef, byte *key, const byte *rec)
|
||||
|
||||
my_bool hp_if_null_in_key(HP_KEYDEF *keydef, const byte *record)
|
||||
{
|
||||
HP_KEYSEG *seg,*endseg;
|
||||
HA_KEYSEG *seg,*endseg;
|
||||
for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
|
||||
{
|
||||
if (seg->null_bit && (record[seg->null_pos] & seg->null_bit))
|
||||
@ -421,3 +506,51 @@ my_bool hp_if_null_in_key(HP_KEYDEF *keydef, const byte *record)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void heap_update_auto_increment(HP_INFO *info, const byte *record)
|
||||
{
|
||||
ulonglong value;
|
||||
HA_KEYSEG *keyseg= info->s->keydef[info->s->auto_key - 1].seg;
|
||||
const uchar *key= (uchar*) record + keyseg->start;
|
||||
|
||||
switch (info->s->auto_key_type) {
|
||||
case HA_KEYTYPE_INT8:
|
||||
case HA_KEYTYPE_BINARY:
|
||||
value= (ulonglong) *(uchar*) key;
|
||||
break;
|
||||
case HA_KEYTYPE_SHORT_INT:
|
||||
case HA_KEYTYPE_USHORT_INT:
|
||||
value= (ulonglong) uint2korr(key);
|
||||
break;
|
||||
case HA_KEYTYPE_LONG_INT:
|
||||
case HA_KEYTYPE_ULONG_INT:
|
||||
value= (ulonglong) uint4korr(key);
|
||||
break;
|
||||
case HA_KEYTYPE_INT24:
|
||||
case HA_KEYTYPE_UINT24:
|
||||
value= (ulonglong) uint3korr(key);
|
||||
break;
|
||||
case HA_KEYTYPE_FLOAT: /* This shouldn't be used */
|
||||
{
|
||||
float f_1;
|
||||
float4get(f_1, key);
|
||||
value= (ulonglong) f_1;
|
||||
break;
|
||||
}
|
||||
case HA_KEYTYPE_DOUBLE: /* This shouldn't be used */
|
||||
{
|
||||
double f_1;
|
||||
float8get(f_1, key);
|
||||
value= (ulonglong) f_1;
|
||||
break;
|
||||
}
|
||||
case HA_KEYTYPE_LONGLONG:
|
||||
case HA_KEYTYPE_ULONGLONG:
|
||||
value= uint8korr(key);
|
||||
break;
|
||||
default:
|
||||
value= 0; /* Error */
|
||||
break;
|
||||
}
|
||||
set_if_bigger(info->s->auto_increment, value);
|
||||
}
|
||||
|
@ -55,5 +55,7 @@ int heap_info(reg1 HP_INFO *info,reg2 HEAPINFO *x,
|
||||
x->index_length= info->s->index_length;
|
||||
x->max_records = info->s->max_records;
|
||||
x->errkey = info->errkey;
|
||||
if (flag & HA_STATUS_AUTO)
|
||||
x->auto_increment= info->s->auto_increment + 1;
|
||||
DBUG_RETURN(0);
|
||||
} /* heap_info */
|
||||
|
141
heap/hp_open.c
141
heap/hp_open.c
@ -21,85 +21,23 @@
|
||||
#include "hp_static.c" /* Stupid vms-linker */
|
||||
#endif
|
||||
|
||||
static void init_block(HP_BLOCK *block,uint reclength,ulong min_records,
|
||||
ulong max_records);
|
||||
#include "my_sys.h"
|
||||
|
||||
/* open a heap database. */
|
||||
|
||||
HP_INFO *heap_open(const char *name, int mode, uint keys, HP_KEYDEF *keydef,
|
||||
uint reclength, ulong max_records, ulong min_records)
|
||||
HP_INFO *heap_open(const char *name, int mode)
|
||||
{
|
||||
uint i,j,key_segs,max_length,length;
|
||||
HP_INFO *info;
|
||||
HP_SHARE *share;
|
||||
HP_KEYSEG *keyseg;
|
||||
|
||||
DBUG_ENTER("heap_open");
|
||||
|
||||
pthread_mutex_lock(&THR_LOCK_heap);
|
||||
if (!(share=_hp_find_named_heap(name)))
|
||||
{
|
||||
DBUG_PRINT("info",("Initializing new table"));
|
||||
for (i=key_segs=max_length=0 ; i < keys ; i++)
|
||||
{
|
||||
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))))
|
||||
if (!(share= hp_find_named_heap(name)))
|
||||
{
|
||||
my_errno= ENOENT;
|
||||
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)+
|
||||
share->max_key_length,
|
||||
if (!(info= (HP_INFO*) my_malloc((uint) sizeof(HP_INFO) +
|
||||
2 * share->max_key_length,
|
||||
MYF(MY_ZEROFILL))))
|
||||
{
|
||||
pthread_mutex_unlock(&THR_LOCK_heap);
|
||||
@ -109,77 +47,46 @@ HP_INFO *heap_open(const char *name, int mode, uint keys, HP_KEYDEF *keydef,
|
||||
#ifdef THREAD
|
||||
thr_lock_data_init(&share->lock,&info->lock,NULL);
|
||||
#endif
|
||||
info->open_list.data=(void*) info;
|
||||
heap_open_list=list_add(heap_open_list,&info->open_list);
|
||||
info->open_list.data= (void*) info;
|
||||
heap_open_list= list_add(heap_open_list,&info->open_list);
|
||||
pthread_mutex_unlock(&THR_LOCK_heap);
|
||||
|
||||
info->s=share;
|
||||
info->lastkey=(byte*) (info+1);
|
||||
info->mode=mode;
|
||||
info->s= share;
|
||||
info->lastkey= (byte*) (info + 1);
|
||||
info->recbuf= (byte*) (info->lastkey + share->max_key_length);
|
||||
info->mode= mode;
|
||||
info->current_record= (ulong) ~0L; /* No current record */
|
||||
info->current_ptr=0;
|
||||
info->current_hash_ptr=0;
|
||||
info->current_ptr= 0;
|
||||
info->current_hash_ptr= 0;
|
||||
info->lastinx= info->errkey= -1;
|
||||
info->update=0;
|
||||
info->update= 0;
|
||||
#ifndef DBUG_OFF
|
||||
info->opt_flag=READ_CHECK_USED; /* Check when changing */
|
||||
info->opt_flag= READ_CHECK_USED; /* Check when changing */
|
||||
#endif
|
||||
DBUG_PRINT("exit",("heap: %lx reclength: %d records_in_block: %d",
|
||||
info,share->reclength,share->block.records_in_block));
|
||||
DBUG_RETURN(info);
|
||||
} /* heap_open */
|
||||
|
||||
}
|
||||
|
||||
/* 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;
|
||||
HP_SHARE *info;
|
||||
DBUG_ENTER("heap_find");
|
||||
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;
|
||||
if (!strcmp(name,info->name))
|
||||
info= (HP_SHARE*) pos->data;
|
||||
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((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)
|
||||
next_open=element->next; /* Save if close */
|
||||
switch (flag) {
|
||||
case HA_PANIC_CLOSE:
|
||||
_hp_close(info);
|
||||
hp_close(info);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -45,7 +45,7 @@ int heap_panic(enum ha_panic_function flag)
|
||||
case HA_PANIC_CLOSE:
|
||||
{
|
||||
if (!share->open_count)
|
||||
_hp_free(share);
|
||||
hp_free(share);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -27,7 +27,7 @@ int heap_rename(const char *old_name, const char *new_name)
|
||||
DBUG_ENTER("heap_rename");
|
||||
|
||||
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))))
|
||||
{
|
||||
|
@ -18,11 +18,43 @@
|
||||
|
||||
/* 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");
|
||||
info->lastinx= inx;
|
||||
if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
|
||||
{
|
||||
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 @@
|
||||
|
||||
#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;
|
||||
HP_SHARE *share=info->s;
|
||||
HP_SHARE *share= info->s;
|
||||
HP_KEYDEF *keyinfo= share->keydef + inx;
|
||||
DBUG_ENTER("heap_rkey");
|
||||
DBUG_PRINT("enter",("base: %lx inx: %d",info,inx));
|
||||
|
||||
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->current_record = (ulong) ~0L; /* For heap_rrnd() */
|
||||
info->lastinx= inx;
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
memcpy(record,pos,(size_t) share->reclength);
|
||||
info->update=HA_STATE_AKTIV;
|
||||
if (!(share->keydef[inx].flag & HA_NOSAME))
|
||||
memcpy(info->lastkey,key,(size_t) share->keydef[inx].length);
|
||||
if (!(keyinfo->flag & HA_NOSAME))
|
||||
memcpy(info->lastkey, key, (size_t) keyinfo->length);
|
||||
}
|
||||
memcpy(record, pos, (size_t) share->reclength);
|
||||
info->update= HA_STATE_AKTIV;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
@ -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)
|
||||
{
|
||||
return _hp_search(info,info->s->keydef+inx,key,0);
|
||||
return hp_search(info, info->s->keydef + inx, key, 0);
|
||||
}
|
||||
|
@ -19,11 +19,38 @@
|
||||
/* 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");
|
||||
info->lastinx= inx;
|
||||
if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
|
||||
{
|
||||
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,13 +22,44 @@ int heap_rnext(HP_INFO *info, byte *record)
|
||||
{
|
||||
byte *pos;
|
||||
HP_SHARE *share=info->s;
|
||||
HP_KEYDEF *keyinfo;
|
||||
DBUG_ENTER("heap_rnext");
|
||||
|
||||
if (info->lastinx < 0)
|
||||
DBUG_RETURN(my_errno=HA_ERR_WRONG_INDEX);
|
||||
|
||||
keyinfo = share->keydef + info->lastinx;
|
||||
if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
|
||||
{
|
||||
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
|
||||
{
|
||||
my_errno = HA_ERR_KEY_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (info->current_hash_ptr)
|
||||
pos= _hp_search_next(info,share->keydef+info->lastinx, info->lastkey,
|
||||
pos= hp_search_next(info, keyinfo, info->lastkey,
|
||||
info->current_hash_ptr);
|
||||
else
|
||||
{
|
||||
@ -38,11 +69,11 @@ int heap_rnext(HP_INFO *info, byte *record)
|
||||
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);
|
||||
pos= hp_search(info, keyinfo, info->lastkey, 0);
|
||||
else
|
||||
pos= _hp_search(info,share->keydef+info->lastinx, info->lastkey, 1);
|
||||
pos= hp_search(info, keyinfo, info->lastkey, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!pos)
|
||||
{
|
||||
info->update=HA_STATE_NEXT_FOUND; /* For heap_rprev */
|
||||
|
@ -23,23 +23,54 @@ int heap_rprev(HP_INFO *info, byte *record)
|
||||
{
|
||||
byte *pos;
|
||||
HP_SHARE *share=info->s;
|
||||
HP_KEYDEF *keyinfo;
|
||||
DBUG_ENTER("heap_rprev");
|
||||
|
||||
if (info->lastinx < 0)
|
||||
DBUG_RETURN(my_errno=HA_ERR_WRONG_INDEX);
|
||||
keyinfo = share->keydef + info->lastinx;
|
||||
if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
|
||||
{
|
||||
heap_rb_param custom_arg;
|
||||
|
||||
if (info->last_pos)
|
||||
pos = tree_search_next(&keyinfo->rb_tree, &info->last_pos,
|
||||
offsetof(TREE_ELEMENT, right),
|
||||
offsetof(TREE_ELEMENT, left));
|
||||
else
|
||||
{
|
||||
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
|
||||
{
|
||||
if (info->current_ptr || (info->update & HA_STATE_NEXT_FOUND))
|
||||
{
|
||||
if ((info->update & HA_STATE_DELETED))
|
||||
pos= _hp_search(info,share->keydef+info->lastinx, info->lastkey, 3);
|
||||
pos= hp_search(info, share->keydef + info->lastinx, info->lastkey, 3);
|
||||
else
|
||||
pos= _hp_search(info,share->keydef+info->lastinx, info->lastkey, 2);
|
||||
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)
|
||||
{
|
||||
info->update=HA_STATE_PREV_FOUND; /* For heap_rprev */
|
||||
|
@ -88,7 +88,7 @@ int heap_rrnd_old(register HP_INFO *info, byte *record, ulong pos)
|
||||
}
|
||||
|
||||
/* Find record number pos */
|
||||
_hp_find_record(info,pos);
|
||||
hp_find_record(info, pos);
|
||||
|
||||
end:
|
||||
if (!info->current_ptr[share->reclength])
|
||||
|
@ -41,8 +41,8 @@ int heap_rsame(register HP_INFO *info, byte *record, int inx)
|
||||
else if (inx != -1)
|
||||
{
|
||||
info->lastinx=inx;
|
||||
_hp_make_key(share->keydef+inx,info->lastkey,record);
|
||||
if (!_hp_search(info,share->keydef+inx,info->lastkey,3))
|
||||
hp_make_key(share->keydef + inx, info->lastkey, record);
|
||||
if (!hp_search(info, share->keydef + inx, info->lastkey, 3))
|
||||
{
|
||||
info->update=0;
|
||||
DBUG_RETURN(my_errno);
|
||||
|
@ -58,7 +58,7 @@ int heap_scan(register HP_INFO *info, byte *record)
|
||||
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])
|
||||
{
|
||||
|
@ -36,25 +36,31 @@ int main(int argc, char **argv)
|
||||
char record[128],key[32];
|
||||
const char *filename;
|
||||
HP_KEYDEF keyinfo[10];
|
||||
HP_KEYSEG keyseg[4];
|
||||
HA_KEYSEG keyseg[4];
|
||||
HP_CREATE_INFO hp_create_info;
|
||||
MY_INIT(argv[0]);
|
||||
|
||||
filename= "test1";
|
||||
get_options(argc,argv);
|
||||
|
||||
bzero(&hp_create_info, sizeof(hp_create_info));
|
||||
|
||||
keyinfo[0].keysegs=1;
|
||||
keyinfo[0].seg=keyseg;
|
||||
keyinfo[0].algorithm= HA_KEY_ALG_HASH;
|
||||
keyinfo[0].seg[0].type=HA_KEYTYPE_BINARY;
|
||||
keyinfo[0].seg[0].start=1;
|
||||
keyinfo[0].seg[0].length=6;
|
||||
keyinfo[0].seg[0].charset=default_charset_info;
|
||||
keyinfo[0].flag = HA_NOSAME;
|
||||
|
||||
deleted=0;
|
||||
bzero((gptr) flags,sizeof(flags));
|
||||
|
||||
printf("- Creating heap-file\n");
|
||||
heap_create(filename);
|
||||
if (!(file=heap_open(filename,2,1,keyinfo,30,(ulong) flag*100000l,10l)))
|
||||
if (heap_create(filename,1,keyinfo,30,(ulong) flag*100000l,10l,
|
||||
&hp_create_info) ||
|
||||
!(file= heap_open(filename, 2)))
|
||||
goto err;
|
||||
printf("- Writing records:s\n");
|
||||
strmov(record," ..... key ");
|
||||
@ -77,7 +83,7 @@ int main(int argc, char **argv)
|
||||
if (heap_close(file))
|
||||
goto err;
|
||||
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;
|
||||
|
||||
printf("- Removing records\n");
|
||||
@ -85,7 +91,7 @@ int main(int argc, char **argv)
|
||||
{
|
||||
if (i == remove_ant) { VOID(heap_close(file)) ; return (0) ; }
|
||||
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 ||
|
||||
(error && my_errno != HA_ERR_KEY_NOT_FOUND)))
|
||||
@ -113,7 +119,7 @@ int main(int argc, char **argv)
|
||||
sprintf(key,"%6d",i);
|
||||
bmove(record+1,key,6);
|
||||
my_errno=0;
|
||||
error=heap_rkey(file,record,0,key);
|
||||
error=heap_rkey(file,record,0,key,0,6);
|
||||
if (verbose ||
|
||||
(error == 0 && flags[i] != 1) ||
|
||||
(error && (flags[i] != 0 || my_errno != HA_ERR_KEY_NOT_FOUND)))
|
||||
|
@ -26,7 +26,7 @@
|
||||
#define SAFEMALLOC
|
||||
#endif
|
||||
|
||||
#include "heapdef.h" /* Because of _hp_find_block */
|
||||
#include "heapdef.h" /* Because of hp_find_block */
|
||||
#include <signal.h>
|
||||
|
||||
#define MAX_RECORDS 100000
|
||||
@ -61,8 +61,9 @@ int main(int argc, char *argv[])
|
||||
const char *filename,*filename2;
|
||||
HP_INFO *file,*file2;
|
||||
HP_KEYDEF keyinfo[MAX_KEYS];
|
||||
HP_KEYSEG keyseg[MAX_KEYS*5];
|
||||
HA_KEYSEG keyseg[MAX_KEYS*5];
|
||||
HEAP_PTR position;
|
||||
HP_CREATE_INFO hp_create_info;
|
||||
MY_INIT(argv[0]); /* init my_sys library & pthreads */
|
||||
LINT_INIT(position);
|
||||
|
||||
@ -71,51 +72,61 @@ int main(int argc, char *argv[])
|
||||
file=file2=0;
|
||||
get_options(argc,argv);
|
||||
|
||||
bzero(&hp_create_info, sizeof(hp_create_info));
|
||||
|
||||
write_count=update=opt_delete=0;
|
||||
key_check=0;
|
||||
|
||||
keyinfo[0].seg=keyseg;
|
||||
keyinfo[0].keysegs=1;
|
||||
keyinfo[0].flag= 0;
|
||||
keyinfo[0].algorithm= HA_KEY_ALG_HASH;
|
||||
keyinfo[0].seg[0].type=HA_KEYTYPE_BINARY;
|
||||
keyinfo[0].seg[0].start=0;
|
||||
keyinfo[0].seg[0].length=6;
|
||||
keyinfo[0].seg[0].null_bit=0;
|
||||
keyinfo[0].seg[0].charset=default_charset_info;
|
||||
keyinfo[1].seg=keyseg+1;
|
||||
keyinfo[1].keysegs=2;
|
||||
keyinfo[1].flag=0;
|
||||
keyinfo[1].algorithm= HA_KEY_ALG_HASH;
|
||||
keyinfo[1].seg[0].type=HA_KEYTYPE_BINARY;
|
||||
keyinfo[1].seg[0].start=7;
|
||||
keyinfo[1].seg[0].length=6;
|
||||
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].start=0; /* key in two parts */
|
||||
keyinfo[1].seg[1].length=6;
|
||||
keyinfo[1].seg[1].null_bit=0;
|
||||
keyinfo[1].seg[1].charset=default_charset_info;
|
||||
keyinfo[2].seg=keyseg+3;
|
||||
keyinfo[2].keysegs=1;
|
||||
keyinfo[2].flag=HA_NOSAME;
|
||||
keyinfo[2].algorithm= HA_KEY_ALG_HASH;
|
||||
keyinfo[2].seg[0].type=HA_KEYTYPE_BINARY;
|
||||
keyinfo[2].seg[0].start=12;
|
||||
keyinfo[2].seg[0].length=8;
|
||||
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].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].start=37;
|
||||
keyinfo[3].seg[0].length=1;
|
||||
keyinfo[3].seg[0].null_bit=1;
|
||||
keyinfo[3].seg[0].null_pos=38;
|
||||
keyinfo[3].seg[0].charset=default_charset_info;
|
||||
|
||||
bzero((char*) key1,sizeof(key1));
|
||||
bzero((char*) key3,sizeof(key3));
|
||||
|
||||
printf("- Creating heap-file\n");
|
||||
if (heap_create(filename))
|
||||
goto err;
|
||||
if (!(file=heap_open(filename,2,keys,keyinfo,reclength,(ulong) flag*100000L,
|
||||
(ulong) recant/2)))
|
||||
if (heap_create(filename,keys,keyinfo,reclength,(ulong) flag*100000L,
|
||||
(ulong) recant/2, &hp_create_info) ||
|
||||
!(file= heap_open(filename, 2)))
|
||||
goto err;
|
||||
signal(SIGINT,endprog);
|
||||
|
||||
@ -167,14 +178,14 @@ int main(int argc, char *argv[])
|
||||
if (j != 0)
|
||||
{
|
||||
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);
|
||||
goto err;
|
||||
}
|
||||
#ifdef NOT_USED
|
||||
if (file->current_ptr == _hp_find_block(&file->s->block,0) ||
|
||||
file->current_ptr == _hp_find_block(&file->s->block,1))
|
||||
if (file->current_ptr == hp_find_block(&file->s->block,0) ||
|
||||
file->current_ptr == hp_find_block(&file->s->block,1))
|
||||
continue; /* Don't remove 2 first records */
|
||||
#endif
|
||||
if (heap_delete(file,record))
|
||||
@ -227,7 +238,7 @@ int main(int argc, char *argv[])
|
||||
if (!key1[j])
|
||||
continue;
|
||||
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);
|
||||
goto err;
|
||||
@ -277,7 +288,7 @@ int main(int argc, char *argv[])
|
||||
printf("- Read first key - next - delete - next -> last\n");
|
||||
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;
|
||||
if (heap_rnext(file,record3)) goto err;
|
||||
if (heap_delete(file,record3)) goto err;
|
||||
@ -306,7 +317,7 @@ int main(int argc, char *argv[])
|
||||
if (!silent)
|
||||
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;
|
||||
key_check-=atoi(record3);
|
||||
key1[atoi(record+keyinfo[0].seg[0].start)]--;
|
||||
@ -501,7 +512,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
printf("- Read through all keys with first-next-last-prev\n");
|
||||
ant=0;
|
||||
for (error=heap_rkey(file,record,0,key) ;
|
||||
for (error=heap_rkey(file,record,0,key,6,0);
|
||||
! error ;
|
||||
error=heap_rnext(file,record))
|
||||
ant++;
|
||||
@ -513,7 +524,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
ant=0;
|
||||
for (error=heap_rlast(file,record) ;
|
||||
for (error=heap_rlast(file,record,0) ;
|
||||
! error ;
|
||||
error=heap_rprev(file,record))
|
||||
{
|
||||
@ -530,7 +541,7 @@ int main(int argc, char *argv[])
|
||||
if (testflag == 4) goto end;
|
||||
|
||||
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;
|
||||
if (heap_scan_init(file))
|
||||
goto err;
|
||||
@ -538,7 +549,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
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",
|
||||
record+keyinfo[2].seg[0].start);
|
||||
@ -549,7 +560,8 @@ int main(int argc, char *argv[])
|
||||
heap_close(file2);
|
||||
|
||||
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;
|
||||
|
||||
printf("- Copying and removing records\n");
|
||||
|
@ -20,47 +20,63 @@
|
||||
|
||||
int heap_update(HP_INFO *info, const byte *old, const byte *heap_new)
|
||||
{
|
||||
uint key;
|
||||
HP_KEYDEF *keydef, *end, *p_lastinx;
|
||||
byte *pos;
|
||||
HP_SHARE *share=info->s;
|
||||
bool auto_key_changed= 0;
|
||||
HP_SHARE *share= info->s;
|
||||
DBUG_ENTER("heap_update");
|
||||
|
||||
test_active(info);
|
||||
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 */
|
||||
if (--(share->records) < share->blength >> 1) share->blength>>= 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 ==
|
||||
(uint) info->lastinx) ||
|
||||
_hp_write_key(share,share->keydef+key,heap_new,pos))
|
||||
if ((*keydef->delete_key)(info, keydef, old, pos, keydef == p_lastinx) ||
|
||||
(*keydef->write_key)(info, keydef, heap_new, pos))
|
||||
goto err;
|
||||
if (share->auto_key == (uint) (keydef - share->keydef + 1))
|
||||
auto_key_changed= 1;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(pos,heap_new,(size_t) share->reclength);
|
||||
if (++(share->records) == share->blength) share->blength+= share->blength;
|
||||
if (auto_key_changed)
|
||||
heap_update_auto_increment(info, heap_new);
|
||||
DBUG_RETURN(0);
|
||||
|
||||
err:
|
||||
if (my_errno == HA_ERR_FOUND_DUPP_KEY)
|
||||
{
|
||||
info->errkey=key;
|
||||
do
|
||||
info->errkey = keydef - share->keydef;
|
||||
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) ||
|
||||
_hp_write_key(share,share->keydef+key,old,pos))
|
||||
if (++(share->records) == share->blength) share->blength+= share->blength;
|
||||
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;
|
||||
}
|
||||
} while (key-- > 0);
|
||||
keydef--;
|
||||
}
|
||||
}
|
||||
if (++(share->records) == share->blength) share->blength+= share->blength;
|
||||
DBUG_RETURN(my_errno);
|
||||
|
@ -27,12 +27,12 @@
|
||||
#define HIGHUSED 8
|
||||
|
||||
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);
|
||||
|
||||
int heap_write(HP_INFO *info, const byte *record)
|
||||
{
|
||||
uint key;
|
||||
HP_KEYDEF *keydef, *end;
|
||||
byte *pos;
|
||||
HP_SHARE *share=info->s;
|
||||
DBUG_ENTER("heap_write");
|
||||
@ -47,9 +47,10 @@ int heap_write(HP_INFO *info, const byte *record)
|
||||
DBUG_RETURN(my_errno);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -60,15 +61,23 @@ int heap_write(HP_INFO *info, const byte *record)
|
||||
info->current_ptr=pos;
|
||||
info->current_hash_ptr=0;
|
||||
info->update|=HA_STATE_AKTIV;
|
||||
if (share->auto_key)
|
||||
heap_update_auto_increment(info, record);
|
||||
DBUG_RETURN(0);
|
||||
err:
|
||||
DBUG_PRINT("info",("Duplicate key: %d",key));
|
||||
info->errkey= key;
|
||||
do
|
||||
DBUG_PRINT("info",("Duplicate key: %d", keydef - share->keydef));
|
||||
info->errkey= keydef - share->keydef;
|
||||
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;
|
||||
} while (key-- > 0);
|
||||
keydef--;
|
||||
}
|
||||
|
||||
share->deleted++;
|
||||
*((byte**) pos)=share->del_link;
|
||||
@ -77,6 +86,36 @@ err:
|
||||
DBUG_RETURN(my_errno);
|
||||
} /* 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 */
|
||||
|
||||
@ -102,7 +141,7 @@ static byte *next_free_record_pos(HP_SHARE *info)
|
||||
my_errno=HA_ERR_RECORD_FILE_FULL;
|
||||
DBUG_RETURN(NULL);
|
||||
}
|
||||
if (_hp_get_new_block(&info->block,&length))
|
||||
if (hp_get_new_block(&info->block,&length))
|
||||
DBUG_RETURN(NULL);
|
||||
info->data_length+=length;
|
||||
}
|
||||
@ -113,12 +152,12 @@ static byte *next_free_record_pos(HP_SHARE *info)
|
||||
block_pos*info->block.recbuffer);
|
||||
}
|
||||
|
||||
|
||||
/* 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)
|
||||
{
|
||||
HP_SHARE *share = info->s;
|
||||
int flag;
|
||||
ulong halfbuff,hashnr,first_index;
|
||||
byte *ptr_to_rec,*ptr_to_rec2;
|
||||
@ -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);
|
||||
|
||||
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 */
|
||||
halfbuff= (long) info->blength >> 1;
|
||||
pos= hp_find_hash(&keyinfo->block,(first_index=info->records-halfbuff));
|
||||
halfbuff= (long) share->blength >> 1;
|
||||
pos= hp_find_hash(&keyinfo->block,(first_index=share->records-halfbuff));
|
||||
|
||||
if (pos != empty) /* If some records */
|
||||
{
|
||||
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 (_hp_mask(hashnr,info->blength,info->records) != first_index)
|
||||
if (hp_mask(hashnr, share->blength, share->records) != first_index)
|
||||
break;
|
||||
if (!(hashnr & halfbuff))
|
||||
{ /* Key will not move */
|
||||
@ -212,8 +251,8 @@ int _hp_write_key(register HP_SHARE *info, HP_KEYDEF *keyinfo,
|
||||
}
|
||||
/* Check if we are at the empty position */
|
||||
|
||||
pos=hp_find_hash(&keyinfo->block,_hp_mask(_hp_rec_hashnr(keyinfo,record),
|
||||
info->blength,info->records+1));
|
||||
pos=hp_find_hash(&keyinfo->block, hp_mask(hp_rec_hashnr(keyinfo, record),
|
||||
share->blength, share->records + 1));
|
||||
if (pos == empty)
|
||||
{
|
||||
pos->ptr_to_rec=recpos;
|
||||
@ -224,8 +263,8 @@ int _hp_write_key(register HP_SHARE *info, HP_KEYDEF *keyinfo,
|
||||
/* Check if more records in same hash-nr family */
|
||||
empty[0]=pos[0];
|
||||
gpos=hp_find_hash(&keyinfo->block,
|
||||
_hp_mask(_hp_rec_hashnr(keyinfo,pos->ptr_to_rec),
|
||||
info->blength,info->records+1));
|
||||
hp_mask(hp_rec_hashnr(keyinfo, pos->ptr_to_rec),
|
||||
share->blength, share->records + 1));
|
||||
if (pos == gpos)
|
||||
{
|
||||
pos->ptr_to_rec=recpos;
|
||||
@ -235,7 +274,7 @@ int _hp_write_key(register HP_SHARE *info, HP_KEYDEF *keyinfo,
|
||||
{
|
||||
pos->ptr_to_rec=recpos;
|
||||
pos->next_key=0;
|
||||
_hp_movelink(pos,gpos,empty);
|
||||
hp_movelink(pos, gpos, empty);
|
||||
}
|
||||
|
||||
/* Check if duplicated keys */
|
||||
@ -246,7 +285,7 @@ int _hp_write_key(register HP_SHARE *info, HP_KEYDEF *keyinfo,
|
||||
pos=empty;
|
||||
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);
|
||||
}
|
||||
@ -258,7 +297,7 @@ int _hp_write_key(register HP_SHARE *info, HP_KEYDEF *keyinfo,
|
||||
|
||||
/* 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)
|
||||
{
|
||||
uint block_pos;
|
||||
@ -268,7 +307,7 @@ static HASH_INFO *_hp_find_free_hash(HP_SHARE *info,
|
||||
return hp_find_hash(block,records);
|
||||
if (!(block_pos=(records % block->records_in_block)))
|
||||
{
|
||||
if (_hp_get_new_block(block,&length))
|
||||
if (hp_get_new_block(block,&length))
|
||||
return(NULL);
|
||||
info->index_length+=length;
|
||||
}
|
||||
|
@ -28,7 +28,8 @@ noinst_HEADERS = config-win.h config-os2.h \
|
||||
my_dir.h mysys_err.h my_base.h \
|
||||
my_nosys.h my_alarm.h queues.h rijndael.h sha1.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
|
||||
SUPERCLEANFILES = mysql_version.h my_config.h
|
||||
|
@ -61,3 +61,14 @@ extern const char *client_errors[]; /* Error messages */
|
||||
#define CR_PROBE_SLAVE_HOSTS 2023
|
||||
#define CR_PROBE_SLAVE_CONNECT 2024
|
||||
#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,11 +40,13 @@ typedef struct st_hash {
|
||||
DYNAMIC_ARRAY array; /* Place for hash_keys */
|
||||
hash_get_key get_key;
|
||||
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;
|
||||
|
||||
#define hash_init(A,B,C,D,E,F,G) _hash_init(A,B,C,D,E,F,G CALLER_INFO)
|
||||
my_bool _hash_init(HASH *hash,uint default_array_elements, uint key_offset,
|
||||
#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, CHARSET_INFO *charset,
|
||||
uint default_array_elements, uint key_offset,
|
||||
uint key_length, hash_get_key get_key,
|
||||
void (*free_element)(void*), uint flags CALLER_INFO_PROTO);
|
||||
void hash_free(HASH *tree);
|
||||
|
@ -14,7 +14,7 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
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 */
|
||||
|
||||
#ifndef _heap_h
|
||||
@ -31,6 +31,9 @@ extern "C" {
|
||||
#include <thr_lock.h>
|
||||
#endif
|
||||
|
||||
#include "my_handler.h"
|
||||
#include "my_tree.h"
|
||||
|
||||
/* defines used by heap-funktions */
|
||||
|
||||
#define HP_MAX_LEVELS 4 /* 128^5 records is enough */
|
||||
@ -47,6 +50,7 @@ typedef struct st_heapinfo /* Struct from heap_info */
|
||||
ulong index_length;
|
||||
uint reclength; /* Length of one record */
|
||||
int errkey;
|
||||
ulonglong auto_increment;
|
||||
} HEAPINFO;
|
||||
|
||||
|
||||
@ -73,22 +77,22 @@ typedef struct st_heap_block /* The data is saved in blocks */
|
||||
ulong last_allocated; /* Blocks allocated, used by keys */
|
||||
} HP_BLOCK;
|
||||
|
||||
typedef struct st_hp_keyseg /* Key-portion */
|
||||
{
|
||||
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;
|
||||
struct st_heap_info; /* For referense */
|
||||
|
||||
typedef struct st_hp_keydef /* Key definition with open */
|
||||
{
|
||||
uint flag; /* HA_NOSAME | HA_NULL_PART_KEY */
|
||||
uint keysegs; /* Number of key-segment */
|
||||
uint length; /* Length of key (automatic) */
|
||||
HP_KEYSEG *seg;
|
||||
uint8 algorithm; /* HASH / BTREE */
|
||||
HA_KEYSEG *seg;
|
||||
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;
|
||||
|
||||
typedef struct st_heap_share
|
||||
@ -112,6 +116,9 @@ typedef struct st_heap_share
|
||||
#endif
|
||||
my_bool delete_on_close;
|
||||
LIST open_list;
|
||||
uint auto_key;
|
||||
uint auto_key_type; /* real type of the auto key segment */
|
||||
ulonglong auto_increment;
|
||||
} HP_SHARE;
|
||||
|
||||
struct st_hp_hash_info;
|
||||
@ -126,17 +133,27 @@ typedef struct st_heap_info
|
||||
int mode; /* Mode of file (READONLY..) */
|
||||
uint opt_flag,update;
|
||||
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
|
||||
THR_LOCK_DATA lock;
|
||||
#endif
|
||||
LIST open_list;
|
||||
} 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 */
|
||||
|
||||
extern HP_INFO* heap_open(const char *name,int mode,uint keys,
|
||||
HP_KEYDEF *keydef,uint reclength,
|
||||
ulong max_records,ulong min_reloc);
|
||||
extern HP_INFO *heap_open(const char *name, int mode);
|
||||
extern int heap_close(HP_INFO *info);
|
||||
extern int heap_write(HP_INFO *info,const byte *buff);
|
||||
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);
|
||||
extern int heap_scan(register HP_INFO *info, byte *record);
|
||||
extern int heap_delete(HP_INFO *info,const byte *buff);
|
||||
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_extra(HP_INFO *info,enum ha_extra_function function);
|
||||
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);
|
||||
extern int heap_rsame(HP_INFO *info,byte *record,int inx);
|
||||
extern int heap_rnext(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_rlast(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,int inx);
|
||||
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 int heap_check_heap(HP_INFO *info, my_bool print_status);
|
||||
extern byte *heap_position(HP_INFO *info);
|
||||
|
@ -26,68 +26,139 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define CHARSET_DIR "charsets/"
|
||||
|
||||
typedef struct charset_info_st
|
||||
{
|
||||
uint number;
|
||||
const char *name;
|
||||
uchar *ctype;
|
||||
uchar *to_lower;
|
||||
uchar *to_upper;
|
||||
uchar *sort_order;
|
||||
#define my_wc_t ulong
|
||||
|
||||
uint strxfrm_multiply;
|
||||
int (*strcoll)(const uchar *, const uchar *);
|
||||
int (*strxfrm)(uchar *, const uchar *, int);
|
||||
int (*strnncoll)(const uchar *, int, const uchar *, int);
|
||||
int (*strnxfrm)(uchar *, const uchar *, int, int);
|
||||
my_bool (*like_range)(const char *, uint, pchar, uint,
|
||||
char *, char *, uint *, uint *);
|
||||
typedef struct unicase_info_st {
|
||||
uint16 toupper;
|
||||
uint16 tolower;
|
||||
uint16 sort;
|
||||
} MY_UNICASE_INFO;
|
||||
|
||||
uint mbmaxlen;
|
||||
int (*ismbchar)(const char *, const char *);
|
||||
my_bool (*ismbhead)(uint);
|
||||
int (*mbcharlen)(uint);
|
||||
} CHARSET_INFO;
|
||||
#define MY_CS_ILSEQ 0
|
||||
#define MY_CS_ILUNI 0
|
||||
#define MY_CS_TOOSMALL -1
|
||||
#define MY_CS_TOOFEW(n) (-1-(n))
|
||||
|
||||
/* strings/ctype.c */
|
||||
extern CHARSET_INFO *default_charset_info;
|
||||
extern CHARSET_INFO *find_compiled_charset(uint cs_number);
|
||||
extern CHARSET_INFO *find_compiled_charset_by_name(const char *name);
|
||||
extern CHARSET_INFO compiled_charsets[];
|
||||
extern uint compiled_charset_number(const char *name);
|
||||
extern const char *compiled_charset_name(uint charset_number);
|
||||
/* My charsets_list flags */
|
||||
#define MY_NO_SETS 0
|
||||
#define MY_CS_COMPILED 1 /* compiled-in sets */
|
||||
#define MY_CS_CONFIG 2 /* sets that have a *.conf file */
|
||||
#define MY_CS_INDEX 4 /* sets listed in the Index file */
|
||||
#define MY_CS_LOADED 8 /* sets that are currently loaded */
|
||||
|
||||
#define MY_CHARSET_UNDEFINED 0
|
||||
#define MY_CHARSET_CURRENT (default_charset_info->number)
|
||||
|
||||
/* Don't include std ctype.h when this is included */
|
||||
#define _CTYPE_H
|
||||
#define _CTYPE_H_
|
||||
#define _CTYPE_INCLUDED
|
||||
#define __CTYPE_INCLUDED
|
||||
#define _CTYPE_USING /* Don't put names in global namespace. */
|
||||
|
||||
/* Fix things, if ctype.h would have been included before */
|
||||
#undef toupper
|
||||
#undef _toupper
|
||||
#undef _tolower
|
||||
#undef toupper
|
||||
#undef tolower
|
||||
#undef isalpha
|
||||
#undef isupper
|
||||
#undef islower
|
||||
#undef isdigit
|
||||
#undef isxdigit
|
||||
#undef isalnum
|
||||
#undef isspace
|
||||
#undef ispunct
|
||||
#undef isprint
|
||||
#undef isgraph
|
||||
#undef iscntrl
|
||||
#undef isascii
|
||||
#undef toascii
|
||||
typedef struct my_uni_idx_st {
|
||||
uint16 from;
|
||||
uint16 to;
|
||||
uchar *tab;
|
||||
} MY_UNI_IDX;
|
||||
|
||||
|
||||
typedef struct charset_info_st
|
||||
{
|
||||
uint number;
|
||||
uint state;
|
||||
const char *name;
|
||||
const char *comment;
|
||||
uchar *ctype;
|
||||
uchar *to_lower;
|
||||
uchar *to_upper;
|
||||
uchar *sort_order;
|
||||
uint16 *tab_to_uni;
|
||||
MY_UNI_IDX *tab_from_uni;
|
||||
|
||||
/* Collation routines */
|
||||
uint strxfrm_multiply;
|
||||
int (*strnncoll)(struct charset_info_st *,
|
||||
const uchar *, uint, const uchar *, uint);
|
||||
int (*strnxfrm)(struct charset_info_st *,
|
||||
uchar *, uint, const uchar *, uint);
|
||||
my_bool (*like_range)(struct charset_info_st *,
|
||||
const char *, uint, pchar, uint,
|
||||
char *, char *, uint *, uint *);
|
||||
|
||||
/* Multibyte routines */
|
||||
uint mbmaxlen;
|
||||
int (*ismbchar)(struct charset_info_st *, const char *, const char *);
|
||||
my_bool (*ismbhead)(struct charset_info_st *, uint);
|
||||
int (*mbcharlen)(struct charset_info_st *, uint);
|
||||
|
||||
/* Unicode convertion */
|
||||
int (*mb_wc)(struct charset_info_st *cs,my_wc_t *wc,
|
||||
const unsigned char *s,const unsigned char *e);
|
||||
int (*wc_mb)(struct charset_info_st *cs,my_wc_t wc,
|
||||
unsigned char *s,unsigned char *e);
|
||||
|
||||
/* Functions for case and sort convertion */
|
||||
void (*caseup_str)(struct charset_info_st *, char *);
|
||||
void (*casedn_str)(struct charset_info_st *, char *);
|
||||
void (*caseup)(struct charset_info_st *, char *, uint);
|
||||
void (*casedn)(struct charset_info_st *, char *, uint);
|
||||
void (*tosort)(struct charset_info_st *, char *, uint);
|
||||
|
||||
/* Functions for case comparison */
|
||||
int (*strcasecmp)(struct charset_info_st *, const char *, const char *);
|
||||
int (*strncasecmp)(struct charset_info_st *, const char *, const char *,
|
||||
uint);
|
||||
|
||||
/* Hash calculation */
|
||||
uint (*hash_caseup)(struct charset_info_st *cs, const byte *key, uint len);
|
||||
void (*hash_sort)(struct charset_info_st *cs, const uchar *key, uint len,
|
||||
ulong *nr1, ulong *nr2);
|
||||
|
||||
char max_sort_char; /* For LIKE optimization */
|
||||
} CHARSET_INFO;
|
||||
|
||||
|
||||
extern CHARSET_INFO *default_charset_info;
|
||||
extern CHARSET_INFO *system_charset_info;
|
||||
extern CHARSET_INFO *all_charsets[256];
|
||||
extern my_bool init_compiled_charsets(myf flags);
|
||||
|
||||
|
||||
/* declarations for simple charsets */
|
||||
extern int my_strnxfrm_simple(CHARSET_INFO *, uchar *, uint, const uchar *, uint);
|
||||
extern int my_strnncoll_simple(CHARSET_INFO *, const uchar *, uint, const uchar *, uint);
|
||||
|
||||
extern uint my_hash_caseup_simple(CHARSET_INFO *cs,
|
||||
const byte *key, uint len);
|
||||
|
||||
extern void my_hash_sort_simple(CHARSET_INFO *cs,
|
||||
const uchar *key, uint len,
|
||||
ulong *nr1, ulong *nr2);
|
||||
|
||||
|
||||
/* Functions for 8bit */
|
||||
extern void my_caseup_str_8bit(CHARSET_INFO *, char *);
|
||||
extern void my_casedn_str_8bit(CHARSET_INFO *, char *);
|
||||
extern void my_caseup_8bit(CHARSET_INFO *, char *, uint);
|
||||
extern void my_casedn_8bit(CHARSET_INFO *, char *, uint);
|
||||
extern void my_tosort_8bit(CHARSET_INFO *, char *, uint);
|
||||
|
||||
extern int my_strcasecmp_8bit(CHARSET_INFO * cs, const char *, const char *);
|
||||
extern int my_strncasecmp_8bit(CHARSET_INFO * cs, const char *, const char *, uint);
|
||||
|
||||
int my_mb_wc_8bit(CHARSET_INFO *cs,my_wc_t *wc, const uchar *s,const uchar *e);
|
||||
int my_wc_mb_8bit(CHARSET_INFO *cs,my_wc_t wc, uchar *s, uchar *e);
|
||||
|
||||
|
||||
#ifdef USE_MB
|
||||
/* Functions for multibyte charsets */
|
||||
extern void my_caseup_str_mb(CHARSET_INFO *, char *);
|
||||
extern void my_casedn_str_mb(CHARSET_INFO *, char *);
|
||||
extern void my_caseup_mb(CHARSET_INFO *, char *, uint);
|
||||
extern void my_casedn_mb(CHARSET_INFO *, char *, uint);
|
||||
extern int my_strcasecmp_mb(CHARSET_INFO * cs,const char *, const char *);
|
||||
extern int my_strncasecmp_mb(CHARSET_INFO * cs,const char *, const char *t, uint);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define _U 01 /* Upper case */
|
||||
#define _L 02 /* Lower case */
|
||||
@ -98,34 +169,13 @@ extern const char *compiled_charset_name(uint charset_number);
|
||||
#define _B 0100 /* Blank */
|
||||
#define _X 0200 /* heXadecimal digit */
|
||||
|
||||
#define my_ctype (default_charset_info->ctype)
|
||||
#define my_to_upper (default_charset_info->to_upper)
|
||||
#define my_to_lower (default_charset_info->to_lower)
|
||||
#define my_sort_order (default_charset_info->sort_order)
|
||||
|
||||
#define _toupper(c) (char) my_to_upper[(uchar) (c)]
|
||||
#define _tolower(c) (char) my_to_lower[(uchar) (c)]
|
||||
#define toupper(c) (char) my_to_upper[(uchar) (c)]
|
||||
#define tolower(c) (char) my_to_lower[(uchar) (c)]
|
||||
|
||||
#define isalpha(c) ((my_ctype+1)[(uchar) (c)] & (_U | _L))
|
||||
#define isupper(c) ((my_ctype+1)[(uchar) (c)] & _U)
|
||||
#define islower(c) ((my_ctype+1)[(uchar) (c)] & _L)
|
||||
#define isdigit(c) ((my_ctype+1)[(uchar) (c)] & _NMR)
|
||||
#define isxdigit(c) ((my_ctype+1)[(uchar) (c)] & _X)
|
||||
#define isalnum(c) ((my_ctype+1)[(uchar) (c)] & (_U | _L | _NMR))
|
||||
#define isspace(c) ((my_ctype+1)[(uchar) (c)] & _SPC)
|
||||
#define ispunct(c) ((my_ctype+1)[(uchar) (c)] & _PNT)
|
||||
#define isprint(c) ((my_ctype+1)[(uchar) (c)] & (_PNT | _U | _L | _NMR | _B))
|
||||
#define isgraph(c) ((my_ctype+1)[(uchar) (c)] & (_PNT | _U | _L | _NMR))
|
||||
#define iscntrl(c) ((my_ctype+1)[(uchar) (c)] & _CTR)
|
||||
#define isascii(c) (!((c) & ~0177))
|
||||
#define toascii(c) ((c) & 0177)
|
||||
|
||||
#ifdef ctype
|
||||
#undef ctype
|
||||
#endif /* ctype */
|
||||
|
||||
#define my_isascii(c) (!((c) & ~0177))
|
||||
#define my_toascii(c) ((c) & 0177)
|
||||
#define my_tocntrl(c) ((c) & 31)
|
||||
#define my_toprint(c) ((c) | 64)
|
||||
#define my_toupper(s,c) (char) ((s)->to_upper[(uchar) (c)])
|
||||
#define my_tolower(s,c) (char) ((s)->to_lower[(uchar) (c)])
|
||||
#define my_isalpha(s, c) (((s)->ctype+1)[(uchar) (c)] & (_U | _L))
|
||||
#define my_isupper(s, c) (((s)->ctype+1)[(uchar) (c)] & _U)
|
||||
#define my_islower(s, c) (((s)->ctype+1)[(uchar) (c)] & _L)
|
||||
@ -138,26 +188,29 @@ extern const char *compiled_charset_name(uint charset_number);
|
||||
#define my_isgraph(s, c) (((s)->ctype+1)[(uchar) (c)] & (_PNT | _U | _L | _NMR))
|
||||
#define my_iscntrl(s, c) (((s)->ctype+1)[(uchar) (c)] & _CTR)
|
||||
|
||||
#define use_strcoll(s) ((s)->strcoll != NULL)
|
||||
#define MY_STRXFRM_MULTIPLY (default_charset_info->strxfrm_multiply)
|
||||
#define my_strnxfrm(s, a, b, c, d) ((s)->strnxfrm((a), (b), (c), (d)))
|
||||
#define my_strnncoll(s, a, b, c, d) ((s)->strnncoll((a), (b), (c), (d)))
|
||||
#define my_strxfrm(s, a, b, c, d) ((s)->strnxfrm((a), (b), (c)))
|
||||
#define my_strcoll(s, a, b) ((s)->strcoll((a), (b)))
|
||||
/* Some macros that should be cleaned up a little */
|
||||
#define my_isvar(s,c) (my_isalnum(s,c) || (c) == '_')
|
||||
#define my_isvar_start(s,c) (my_isalpha(s,c) || (c) == '_')
|
||||
|
||||
#define use_strnxfrm(s) ((s)->strnxfrm != NULL)
|
||||
#define my_strnxfrm(s, a, b, c, d) ((s)->strnxfrm((s), (a), (b), (c), (d)))
|
||||
#define my_strnncoll(s, a, b, c, d) ((s)->strnncoll((s), (a), (b), (c), (d)))
|
||||
#define my_like_range(s, a, b, c, d, e, f, g, h) \
|
||||
((s)->like_range((a), (b), (c), (d), (e), (f), (g), (h)))
|
||||
((s)->like_range((s), (a), (b), (c), (d), (e), (f), (g), (h)))
|
||||
|
||||
#define use_mb(s) ((s)->ismbchar != NULL)
|
||||
#define MBMAXLEN (default_charset_info->mbmaxlen)
|
||||
#define my_ismbchar(s, a, b) ((s)->ismbchar((a), (b)))
|
||||
#define my_ismbhead(s, a) ((s)->ismbhead((a)))
|
||||
#define my_mbcharlen(s, a) ((s)->mbcharlen((a)))
|
||||
#define my_ismbchar(s, a, b) ((s)->ismbchar((s), (a), (b)))
|
||||
#define my_ismbhead(s, a) ((s)->ismbhead((s), (a)))
|
||||
#define my_mbcharlen(s, a) ((s)->mbcharlen((s),(a)))
|
||||
|
||||
#define my_caseup(s, a, l) ((s)->caseup((s), (a), (l)))
|
||||
#define my_casedn(s, a, l) ((s)->casedn((s), (a), (l)))
|
||||
#define my_tosort(s, a, l) ((s)->tosort((s), (a), (l)))
|
||||
#define my_caseup_str(s, a) ((s)->caseup_str((s), (a)))
|
||||
#define my_casedn_str(s, a) ((s)->casedn_str((s), (a)))
|
||||
#define my_strcasecmp(s, a, b) ((s)->strcasecmp((s), (a), (b)))
|
||||
#define my_strncasecmp(s, a, b, l) ((s)->strncasecmp((s), (a), (b), (l)))
|
||||
|
||||
/* Some macros that should be cleaned up a little */
|
||||
#define isvar(c) (isalnum(c) || (c) == '_')
|
||||
#define isvar_start(c) (isalpha(c) || (c) == '_')
|
||||
#define tocntrl(c) ((c) & 31)
|
||||
#define toprint(c) ((c) | 64)
|
||||
|
||||
/* XXX: still need to take care of this one */
|
||||
#ifdef MY_CHARSET_TIS620
|
||||
|
@ -150,9 +150,9 @@ enum ha_base_keytype {
|
||||
#define HA_PACK_KEY 2 /* Pack string key to previous key */
|
||||
#define HA_AUTO_KEY 16
|
||||
#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_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 */
|
||||
|
||||
|
||||
|
59
include/my_handler.h
Normal file
59
include/my_handler.h
Normal file
@ -0,0 +1,59 @@
|
||||
/* 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 */
|
||||
#define MY_SEEK_CUR 1
|
||||
#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 */
|
||||
#define MY_WAIT_FOR_USER_TO_FIX_PANIC 60 /* in seconds */
|
||||
#define MY_WAIT_GIVE_USER_A_MESSAGE 10 /* Every 10 times of prev */
|
||||
@ -300,6 +293,14 @@ extern struct my_file_info
|
||||
#endif
|
||||
} 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
|
||||
{
|
||||
@ -589,12 +590,11 @@ extern void allow_break(void);
|
||||
#define allow_break()
|
||||
#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 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_length(const char *name);
|
||||
#define base_name(A) (A+dirname_length(A))
|
||||
@ -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,
|
||||
const char *own_path_prefix);
|
||||
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 int wf_test(struct wild_file_pack *wf_pack,const char *name);
|
||||
extern void wf_end(struct wild_file_pack *buffer);
|
||||
extern size_s strip_sp(my_string str);
|
||||
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,
|
||||
uint reclength,enum cache_type type,
|
||||
pbool use_async_io);
|
||||
|
@ -20,13 +20,17 @@
|
||||
extern "C" {
|
||||
#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)\
|
||||
(tree->offset_to_key ? (void*)((byte*) element+tree->offset_to_key) :\
|
||||
*((void**) (element+1)))
|
||||
|
||||
#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 uint32 element_count;
|
||||
typedef int (*tree_walk_action)(void *,element_count,void *);
|
||||
@ -48,15 +52,18 @@ typedef struct st_tree_element {
|
||||
} TREE_ELEMENT;
|
||||
#endif /* MSDOS */
|
||||
|
||||
#define ELEMENT_CHILD(element, offs) (*(TREE_ELEMENT**)((char*)element + offs))
|
||||
|
||||
typedef struct st_tree {
|
||||
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;
|
||||
qsort_cmp2 compare;
|
||||
void* custom_arg;
|
||||
void *custom_arg;
|
||||
MEM_ROOT mem_root;
|
||||
my_bool with_delete;
|
||||
tree_element_free free;
|
||||
uint flag;
|
||||
} TREE;
|
||||
|
||||
/* Functions on whole tree */
|
||||
@ -70,12 +77,22 @@ void reset_tree(TREE*);
|
||||
#define is_tree_inited(tree) ((tree)->root != 0)
|
||||
|
||||
/* Functions on leafs */
|
||||
TREE_ELEMENT *tree_insert(TREE *tree,void *key,uint key_size);
|
||||
void *tree_search(TREE *tree,void *key);
|
||||
TREE_ELEMENT *tree_insert(TREE *tree,void *key, uint key_size,
|
||||
void *custom_arg);
|
||||
void *tree_search(TREE *tree, void *key, void *custom_arg);
|
||||
int tree_walk(TREE *tree,tree_walk_action action,
|
||||
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
|
||||
}
|
||||
#endif
|
||||
|
@ -28,6 +28,7 @@ extern "C" {
|
||||
#ifndef _m_ctype_h
|
||||
#include <m_ctype.h>
|
||||
#endif
|
||||
#include "my_handler.h"
|
||||
|
||||
/* defines used by myisam-funktions */
|
||||
|
||||
@ -105,20 +106,6 @@ typedef struct st_mi_create_info
|
||||
struct st_myisam_info; /* For referense */
|
||||
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;
|
||||
|
||||
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) */
|
||||
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,
|
||||
uchar *page,uchar *key,
|
||||
uint key_len,uint comp_flag,uchar * *ret_pos,
|
||||
@ -147,6 +134,8 @@ typedef struct st_mi_keydef /* Key definition with open & info */
|
||||
struct st_mi_s_param *s_temp);
|
||||
void (*store_key)(struct st_mi_keydef *keyinfo, uchar *key_pos,
|
||||
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;
|
||||
|
||||
|
||||
@ -157,7 +146,7 @@ typedef struct st_unique_def /* Segment definition of unique */
|
||||
uint16 keysegs; /* Number of key-segment */
|
||||
uchar key; /* Mapped to which key */
|
||||
uint8 null_are_equal;
|
||||
MI_KEYSEG *seg,*end;
|
||||
HA_KEYSEG *seg,*end;
|
||||
} MI_UNIQUEDEF;
|
||||
|
||||
typedef struct st_mi_decode_tree /* Decode huff-table */
|
||||
@ -321,6 +310,7 @@ typedef struct st_sort_key_blocks /* Used when sorting */
|
||||
int inited;
|
||||
} SORT_KEY_BLOCKS;
|
||||
|
||||
|
||||
typedef struct st_mi_check_param
|
||||
{
|
||||
ulonglong auto_increment_value;
|
||||
@ -339,7 +329,8 @@ typedef struct st_mi_check_param
|
||||
uint8 language;
|
||||
my_bool using_global_keycache, opt_lock_memory, opt_follow_links;
|
||||
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;
|
||||
myf myf_rw;
|
||||
IO_CACHE read_cache;
|
||||
@ -386,7 +377,7 @@ typedef struct st_mi_sort_param
|
||||
byte *rec_buff;
|
||||
void *wordlist, *wordptr;
|
||||
char *record;
|
||||
char *tmpdir;
|
||||
MY_TMPDIR *tmpdir;
|
||||
int (*key_cmp)(struct st_mi_sort_param *, const void *, const void *);
|
||||
int (*key_read)(struct st_mi_sort_param *,void *);
|
||||
int (*key_write)(struct st_mi_sort_param *, const void *);
|
||||
|
115
include/mysql.h
115
include/mysql.h
@ -69,8 +69,9 @@ extern char *mysql_unix_port;
|
||||
|
||||
typedef struct st_mysql_field {
|
||||
char *name; /* Name of column */
|
||||
char *org_name; /* Original column name, if an alias */
|
||||
char *table; /* Table of column if column was a field */
|
||||
char *org_table; /* Org table name if table was an alias */
|
||||
char *org_table; /* Org table name, if table was an alias */
|
||||
char *db; /* Database for table */
|
||||
char *def; /* Default value (set by mysql_list_fields) */
|
||||
unsigned long length; /* Width of column */
|
||||
@ -156,7 +157,8 @@ enum mysql_rpl_type { MYSQL_RPL_MASTER, MYSQL_RPL_SLAVE,
|
||||
MYSQL_RPL_ADMIN };
|
||||
|
||||
|
||||
typedef struct st_mysql {
|
||||
typedef struct st_mysql
|
||||
{
|
||||
NET net; /* Communication parameters */
|
||||
gptr connector_fd; /* ConnectorFd for SSL */
|
||||
char *host,*user,*passwd,*unix_socket,*server_version,*host_info,
|
||||
@ -174,6 +176,7 @@ typedef struct st_mysql {
|
||||
unsigned int field_count;
|
||||
unsigned int server_status;
|
||||
unsigned int server_language;
|
||||
unsigned int warning_count;
|
||||
struct st_mysql_options options;
|
||||
enum mysql_status status;
|
||||
my_bool free_me; /* If free in mysql_close */
|
||||
@ -272,12 +275,13 @@ my_ulonglong STDCALL mysql_affected_rows(MYSQL *mysql);
|
||||
my_ulonglong STDCALL mysql_insert_id(MYSQL *mysql);
|
||||
unsigned int STDCALL mysql_errno(MYSQL *mysql);
|
||||
const char * STDCALL mysql_error(MYSQL *mysql);
|
||||
unsigned int STDCALL mysql_warning_count(MYSQL *mysql);
|
||||
const char * STDCALL mysql_info(MYSQL *mysql);
|
||||
unsigned long STDCALL mysql_thread_id(MYSQL *mysql);
|
||||
const char * STDCALL mysql_character_set_name(MYSQL *mysql);
|
||||
|
||||
MYSQL * STDCALL mysql_init(MYSQL *mysql);
|
||||
int STDCALL mysql_ssl_set(MYSQL *mysql, const char *key,
|
||||
my_bool STDCALL mysql_ssl_set(MYSQL *mysql, const char *key,
|
||||
const char *cert, const char *ca,
|
||||
const char *capath, const char *cipher);
|
||||
my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
|
||||
@ -294,18 +298,18 @@ int STDCALL mysql_select_db(MYSQL *mysql, const char *db);
|
||||
int STDCALL mysql_query(MYSQL *mysql, const char *q);
|
||||
int STDCALL mysql_send_query(MYSQL *mysql, const char *q,
|
||||
unsigned long length);
|
||||
int STDCALL mysql_read_query_result(MYSQL *mysql);
|
||||
my_bool STDCALL mysql_read_query_result(MYSQL *mysql);
|
||||
int STDCALL mysql_real_query(MYSQL *mysql, const char *q,
|
||||
unsigned long length);
|
||||
/* perform query on master */
|
||||
int STDCALL mysql_master_query(MYSQL *mysql, const char *q,
|
||||
my_bool STDCALL mysql_master_query(MYSQL *mysql, const char *q,
|
||||
unsigned long length);
|
||||
int STDCALL mysql_master_send_query(MYSQL *mysql, const char *q,
|
||||
my_bool STDCALL mysql_master_send_query(MYSQL *mysql, const char *q,
|
||||
unsigned long length);
|
||||
/* perform query on slave */
|
||||
int STDCALL mysql_slave_query(MYSQL *mysql, const char *q,
|
||||
my_bool STDCALL mysql_slave_query(MYSQL *mysql, const char *q,
|
||||
unsigned long length);
|
||||
int STDCALL mysql_slave_send_query(MYSQL *mysql, const char *q,
|
||||
my_bool STDCALL mysql_slave_send_query(MYSQL *mysql, const char *q,
|
||||
unsigned long length);
|
||||
|
||||
/*
|
||||
@ -321,12 +325,12 @@ int STDCALL mysql_rpl_parse_enabled(MYSQL* mysql);
|
||||
void STDCALL mysql_enable_reads_from_master(MYSQL* mysql);
|
||||
void STDCALL mysql_disable_reads_from_master(MYSQL* mysql);
|
||||
/* get the value of the master read flag */
|
||||
int STDCALL mysql_reads_from_master_enabled(MYSQL* mysql);
|
||||
my_bool STDCALL mysql_reads_from_master_enabled(MYSQL* mysql);
|
||||
|
||||
enum mysql_rpl_type STDCALL mysql_rpl_query_type(const char* q, int len);
|
||||
|
||||
/* discover the master and its slaves */
|
||||
int STDCALL mysql_rpl_probe(MYSQL* mysql);
|
||||
my_bool STDCALL mysql_rpl_probe(MYSQL* mysql);
|
||||
|
||||
/* set the master, close/free the old one, if it is not a pivot */
|
||||
int STDCALL mysql_set_master(MYSQL* mysql, const char* host,
|
||||
@ -356,6 +360,7 @@ MYSQL_RES * STDCALL mysql_list_fields(MYSQL *mysql, const char *table,
|
||||
MYSQL_RES * STDCALL mysql_list_processes(MYSQL *mysql);
|
||||
MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql);
|
||||
MYSQL_RES * STDCALL mysql_use_result(MYSQL *mysql);
|
||||
MYSQL_RES * STDCALL mysql_warnings(MYSQL *mysql);
|
||||
int STDCALL mysql_options(MYSQL *mysql,enum mysql_option option,
|
||||
const char *arg);
|
||||
void STDCALL mysql_free_result(MYSQL_RES *result);
|
||||
@ -398,6 +403,91 @@ int STDCALL mysql_manager_command(MYSQL_MANAGER* con,
|
||||
int STDCALL mysql_manager_fetch_line(MYSQL_MANAGER* con,
|
||||
char* res_buf,
|
||||
int res_buf_size);
|
||||
|
||||
|
||||
/*
|
||||
The following definitions are added for the enhanced
|
||||
client-server protocol
|
||||
*/
|
||||
|
||||
/* statement state */
|
||||
enum MY_STMT_STATE { MY_ST_UNKNOWN, MY_ST_PREPARE, MY_ST_EXECUTE };
|
||||
|
||||
/* bind structure */
|
||||
typedef struct st_mysql_bind
|
||||
{
|
||||
long *length; /* output length pointer */
|
||||
gptr buffer; /* buffer */
|
||||
unsigned long buffer_length; /* buffer length */
|
||||
enum enum_field_types buffer_type; /* buffer type */
|
||||
enum enum_field_types field_type; /* field type */
|
||||
my_bool is_null; /* NULL indicator */
|
||||
my_bool is_long_data; /* long data indicator */
|
||||
|
||||
/* The following are for internal use. Set by mysql_bind_param */
|
||||
long bind_length; /* Default length of data */
|
||||
my_bool long_ended; /* All data supplied for long */
|
||||
unsigned int param_number; /* For null count and error messages */
|
||||
void (*store_param_func)(NET *net, struct st_mysql_bind *param);
|
||||
char *(*fetch_result)(struct st_mysql_bind *, const char *row);
|
||||
} MYSQL_BIND;
|
||||
|
||||
|
||||
/* statement handler */
|
||||
typedef struct st_mysql_stmt
|
||||
{
|
||||
MYSQL *mysql; /* connection handle */
|
||||
MYSQL_BIND *params; /* input parameters */
|
||||
MYSQL_RES *result; /* resultset */
|
||||
MYSQL_BIND *bind; /* row binding */
|
||||
MYSQL_FIELD *fields; /* prepare meta info */
|
||||
char *query; /* query buffer */
|
||||
MEM_ROOT mem_root; /* root allocations */
|
||||
MYSQL_RES tmp_result; /* Used by mysql_prepare_result */
|
||||
unsigned long param_count; /* parameters count */
|
||||
unsigned long field_count; /* fields count */
|
||||
unsigned long long_length; /* long buffer alloced length */
|
||||
unsigned long stmt_id; /* Id for prepared statement */
|
||||
unsigned int last_errno; /* error code */
|
||||
enum MY_STMT_STATE state; /* statement state */
|
||||
char last_error[MYSQL_ERRMSG_SIZE]; /* error message */
|
||||
my_bool long_alloced; /* flag to indicate long alloced */
|
||||
my_bool types_supplied; /* to indicate types supply */
|
||||
} MYSQL_STMT;
|
||||
|
||||
|
||||
MYSQL_STMT * STDCALL mysql_prepare(MYSQL * mysql, const char *query,
|
||||
unsigned long length);
|
||||
int STDCALL mysql_execute(MYSQL_STMT * stmt);
|
||||
unsigned long STDCALL mysql_param_count(MYSQL_STMT * stmt);
|
||||
my_bool STDCALL mysql_bind_param(MYSQL_STMT * stmt, MYSQL_BIND * bind);
|
||||
my_bool STDCALL mysql_bind_result(MYSQL_STMT * stmt, MYSQL_BIND * bind);
|
||||
my_bool STDCALL mysql_stmt_close(MYSQL_STMT * stmt);
|
||||
unsigned int STDCALL mysql_stmt_errno(MYSQL_STMT * stmt);
|
||||
const char *STDCALL mysql_stmt_error(MYSQL_STMT * stmt);
|
||||
my_bool STDCALL mysql_commit(MYSQL * mysql);
|
||||
my_bool STDCALL mysql_rollback(MYSQL * mysql);
|
||||
my_bool STDCALL mysql_autocommit(MYSQL * mysql, my_bool auto_mode);
|
||||
int STDCALL mysql_fetch(MYSQL_STMT *stmt);
|
||||
my_bool STDCALL mysql_send_long_data(MYSQL_STMT *stmt,
|
||||
unsigned int param_number,
|
||||
const char *data,
|
||||
unsigned long length,
|
||||
my_bool last_data);
|
||||
int STDCALL mysql_multi_query(MYSQL *mysql,const char *query,
|
||||
unsigned long len);
|
||||
MYSQL_RES *STDCALL mysql_next_result(MYSQL *mysql);
|
||||
MYSQL_RES *STDCALL mysql_prepare_result(MYSQL_STMT *stmt);
|
||||
|
||||
|
||||
/* new status messages */
|
||||
#define MYSQL_SUCCESS 0
|
||||
#define MYSQL_WARNING 1
|
||||
#define MYSQL_STATUS_ERROR 2
|
||||
#define MYSQL_NO_DATA 100
|
||||
#define MYSQL_NEED_DATA 99
|
||||
#define MYSQL_LONG_DATA_END 0xFF
|
||||
|
||||
#define mysql_reload(mysql) mysql_refresh((mysql),REFRESH_GRANT)
|
||||
|
||||
#ifdef USE_OLD_FUNCTIONS
|
||||
@ -414,8 +504,9 @@ int STDCALL mysql_drop_db(MYSQL *mysql, const char *DB);
|
||||
They are not for general usage
|
||||
*/
|
||||
|
||||
int simple_command(MYSQL *mysql,enum enum_server_command command,
|
||||
const char *arg, unsigned long length, my_bool skipp_check);
|
||||
my_bool
|
||||
simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
|
||||
unsigned long length, my_bool skip_check);
|
||||
unsigned long net_safe_read(MYSQL* mysql);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -34,14 +34,15 @@
|
||||
#define MYSQL_SERVICENAME "MySql"
|
||||
#endif /* __WIN__ */
|
||||
|
||||
enum enum_server_command {COM_SLEEP,COM_QUIT,COM_INIT_DB,COM_QUERY,
|
||||
COM_FIELD_LIST,COM_CREATE_DB,COM_DROP_DB,COM_REFRESH,
|
||||
COM_SHUTDOWN,COM_STATISTICS,
|
||||
COM_PROCESS_INFO,COM_CONNECT,COM_PROCESS_KILL,
|
||||
COM_DEBUG,COM_PING,COM_TIME,COM_DELAYED_INSERT,
|
||||
COM_CHANGE_USER, COM_BINLOG_DUMP,
|
||||
COM_TABLE_DUMP, COM_CONNECT_OUT,
|
||||
COM_REGISTER_SLAVE};
|
||||
enum enum_server_command
|
||||
{
|
||||
COM_SLEEP, COM_QUIT, COM_INIT_DB, COM_QUERY, COM_FIELD_LIST,
|
||||
COM_CREATE_DB, COM_DROP_DB, COM_REFRESH, COM_SHUTDOWN, COM_STATISTICS,
|
||||
COM_PROCESS_INFO, COM_CONNECT, COM_PROCESS_KILL, COM_DEBUG, COM_PING,
|
||||
COM_TIME, COM_DELAYED_INSERT, COM_CHANGE_USER, COM_BINLOG_DUMP,
|
||||
COM_TABLE_DUMP, COM_CONNECT_OUT, COM_REGISTER_SLAVE,
|
||||
COM_PREPARE, COM_EXECUTE, COM_LONG_DATA, COM_CLOSE_STMT
|
||||
};
|
||||
|
||||
#define NOT_NULL_FLAG 1 /* Field can't be NULL */
|
||||
#define PRI_KEY_FLAG 2 /* Field is part of a primary key */
|
||||
@ -95,9 +96,11 @@ enum enum_server_command {COM_SLEEP,COM_QUIT,COM_INIT_DB,COM_QUERY,
|
||||
#define CLIENT_SSL 2048 /* Switch to SSL after handshake */
|
||||
#define CLIENT_IGNORE_SIGPIPE 4096 /* IGNORE sigpipes */
|
||||
#define CLIENT_TRANSACTIONS 8192 /* Client knows about transactions */
|
||||
#define CLIENT_PROTOCOL_41 16384 /* New 4.1 protocol */
|
||||
|
||||
#define SERVER_STATUS_IN_TRANS 1 /* Transaction has started */
|
||||
#define SERVER_STATUS_AUTOCOMMIT 2 /* Server in auto_commit mode */
|
||||
#define SERVER_STATUS_MORE_RESULTS 4 /* More results on server */
|
||||
|
||||
#define MYSQL_ERRMSG_SIZE 200
|
||||
#define NET_READ_TIMEOUT 30 /* Timeout on read */
|
||||
@ -130,33 +133,75 @@ typedef struct st_net {
|
||||
unsigned int *return_status;
|
||||
unsigned char reading_or_writing;
|
||||
char save_char;
|
||||
my_bool report_error; /* We should report error (we have unreported error) */
|
||||
my_bool no_send_ok;
|
||||
/*
|
||||
Pointer to query object in query cache, do not equal NULL (0) for
|
||||
queries in cache that have not stored its results yet
|
||||
*/
|
||||
gptr query_cache_query;
|
||||
} NET;
|
||||
|
||||
#define packet_error (~(unsigned long) 0)
|
||||
|
||||
enum enum_field_types { FIELD_TYPE_DECIMAL, FIELD_TYPE_TINY,
|
||||
FIELD_TYPE_SHORT, FIELD_TYPE_LONG,
|
||||
FIELD_TYPE_FLOAT, FIELD_TYPE_DOUBLE,
|
||||
FIELD_TYPE_NULL, FIELD_TYPE_TIMESTAMP,
|
||||
FIELD_TYPE_LONGLONG,FIELD_TYPE_INT24,
|
||||
FIELD_TYPE_DATE, FIELD_TYPE_TIME,
|
||||
FIELD_TYPE_DATETIME, FIELD_TYPE_YEAR,
|
||||
FIELD_TYPE_NEWDATE,
|
||||
FIELD_TYPE_ENUM=247,
|
||||
FIELD_TYPE_SET=248,
|
||||
FIELD_TYPE_TINY_BLOB=249,
|
||||
FIELD_TYPE_MEDIUM_BLOB=250,
|
||||
FIELD_TYPE_LONG_BLOB=251,
|
||||
FIELD_TYPE_BLOB=252,
|
||||
FIELD_TYPE_VAR_STRING=253,
|
||||
FIELD_TYPE_STRING=254,
|
||||
FIELD_TYPE_GEOMETRY=255
|
||||
enum enum_field_types { MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY,
|
||||
MYSQL_TYPE_SHORT, MYSQL_TYPE_LONG,
|
||||
MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE,
|
||||
MYSQL_TYPE_NULL, MYSQL_TYPE_TIMESTAMP,
|
||||
MYSQL_TYPE_LONGLONG,MYSQL_TYPE_INT24,
|
||||
MYSQL_TYPE_DATE, MYSQL_TYPE_TIME,
|
||||
MYSQL_TYPE_DATETIME, MYSQL_TYPE_YEAR,
|
||||
MYSQL_TYPE_NEWDATE,
|
||||
MYSQL_TYPE_ENUM=247,
|
||||
MYSQL_TYPE_SET=248,
|
||||
MYSQL_TYPE_TINY_BLOB=249,
|
||||
MYSQL_TYPE_MEDIUM_BLOB=250,
|
||||
MYSQL_TYPE_LONG_BLOB=251,
|
||||
MYSQL_TYPE_BLOB=252,
|
||||
MYSQL_TYPE_VAR_STRING=253,
|
||||
MYSQL_TYPE_STRING=254,
|
||||
MYSQL_TYPE_GEOMETRY=255
|
||||
|
||||
};
|
||||
|
||||
#define FIELD_TYPE_CHAR FIELD_TYPE_TINY /* For compability */
|
||||
#define FIELD_TYPE_INTERVAL FIELD_TYPE_ENUM /* For compability */
|
||||
/* For backward compatibility */
|
||||
#define FIELD_TYPE_DECIMAL MYSQL_TYPE_DECIMAL
|
||||
#define FIELD_TYPE_TINY MYSQL_TYPE_TINY
|
||||
#define FIELD_TYPE_SHORT MYSQL_TYPE_SHORT
|
||||
#define FIELD_TYPE_LONG MYSQL_TYPE_LONG
|
||||
#define FIELD_TYPE_FLOAT MYSQL_TYPE_FLOAT
|
||||
#define FIELD_TYPE_DOUBLE MYSQL_TYPE_DOUBLE
|
||||
#define FIELD_TYPE_NULL MYSQL_TYPE_NULL
|
||||
#define FIELD_TYPE_TIMESTAMP MYSQL_TYPE_TIMESTAMP
|
||||
#define FIELD_TYPE_LONGLONG MYSQL_TYPE_LONGLONG
|
||||
#define FIELD_TYPE_INT24 MYSQL_TYPE_INT24
|
||||
#define FIELD_TYPE_DATE MYSQL_TYPE_DATE
|
||||
#define FIELD_TYPE_TIME MYSQL_TYPE_TIME
|
||||
#define FIELD_TYPE_DATETIME MYSQL_TYPE_DATETIME
|
||||
#define FIELD_TYPE_YEAR MYSQL_TYPE_YEAR
|
||||
#define FIELD_TYPE_NEWDATE MYSQL_TYPE_NEWDATE
|
||||
#define FIELD_TYPE_ENUM MYSQL_TYPE_ENUM
|
||||
#define FIELD_TYPE_SET MYSQL_TYPE_SET
|
||||
#define FIELD_TYPE_TINY_BLOB MYSQL_TYPE_TINY_BLOB
|
||||
#define FIELD_TYPE_MEDIUM_BLOB MYSQL_TYPE_MEDIUM_BLOB
|
||||
#define FIELD_TYPE_LONG_BLOB MYSQL_TYPE_LONG_BLOB
|
||||
#define FIELD_TYPE_BLOB MYSQL_TYPE_BLOB
|
||||
#define FIELD_TYPE_VAR_STRING MYSQL_TYPE_VAR_STRING
|
||||
#define FIELD_TYPE_STRING MYSQL_TYPE_STRING
|
||||
#define FIELD_TYPE_CHAR MYSQL_TYPE_TINY
|
||||
#define FIELD_TYPE_INTERVAL MYSQL_TYPE_ENUM
|
||||
#define FIELD_TYPE_GEOMETRY MYSQL_TYPE_GEOMETRY
|
||||
|
||||
#if TO_BE_INCLUDED_LATER
|
||||
/* For bind applications, to indicate unsigned buffers */
|
||||
#define MYSQL_TYPE_UTINY -10
|
||||
#define MYSQL_TYPE_USHORT -9
|
||||
#define MYSQL_TYPE_ULONG -8
|
||||
#define MYSQL_TYPE_UFLOAT -7
|
||||
#define MYSQL_TYPE_UDOUBLE -6
|
||||
#define MYSQL_TYPE_ULONGLONG -5
|
||||
#define MYSQL_TYPE_UINT24 -4
|
||||
#endif
|
||||
|
||||
#define net_new_transaction(net) ((net)->pkt_nr=0)
|
||||
|
||||
@ -164,21 +209,26 @@ enum enum_field_types { FIELD_TYPE_DECIMAL, FIELD_TYPE_TINY,
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int my_net_init(NET *net, Vio* vio);
|
||||
my_bool my_net_init(NET *net, Vio* vio);
|
||||
void my_net_local_init(NET *net);
|
||||
void net_end(NET *net);
|
||||
void net_clear(NET *net);
|
||||
int net_flush(NET *net);
|
||||
int my_net_write(NET *net,const char *packet,unsigned long len);
|
||||
int net_write_command(NET *net,unsigned char command,const char *packet,
|
||||
unsigned long len);
|
||||
my_bool net_realloc(NET *net, unsigned long length);
|
||||
my_bool net_flush(NET *net);
|
||||
my_bool my_net_write(NET *net,const char *packet,unsigned long len);
|
||||
my_bool net_write_command(NET *net,unsigned char command,
|
||||
const char *header, unsigned long head_len,
|
||||
const char *packet, unsigned long len);
|
||||
int net_real_write(NET *net,const char *packet,unsigned long len);
|
||||
unsigned long my_net_read(NET *net);
|
||||
|
||||
/* The following function is not meant for normal usage */
|
||||
/*
|
||||
The following function is not meant for normal usage
|
||||
Currently it's used internally by manager.c
|
||||
*/
|
||||
struct sockaddr;
|
||||
int my_connect(my_socket s, const struct sockaddr *name, unsigned int namelen,
|
||||
unsigned int timeout);
|
||||
my_bool my_connect(my_socket s, const struct sockaddr *name,
|
||||
unsigned int namelen, unsigned int timeout);
|
||||
|
||||
struct rand_struct {
|
||||
unsigned long seed1,seed2,max_value;
|
||||
@ -252,5 +302,6 @@ void my_thread_end(void);
|
||||
#endif
|
||||
|
||||
#define NULL_LENGTH ((unsigned long) ~0) /* For net_store_length */
|
||||
#define MYSQL_LONG_DATA_HEADER 8
|
||||
|
||||
#endif
|
||||
|
@ -253,4 +253,9 @@
|
||||
#define ER_CANT_USE_OPTION_HERE 1234
|
||||
#define ER_NOT_SUPPORTED_YET 1235
|
||||
#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
|
||||
|
12
isam/_key.c
12
isam/_key.c
@ -54,11 +54,11 @@ uint _nisam_make_key(register N_INFO *info, uint keynr, uchar *key, const char *
|
||||
*key++= (uchar) (length=(uint) (end-pos));
|
||||
memcpy((byte*) key,(byte*) pos,(size_t) length);
|
||||
#ifdef USE_STRCOLL
|
||||
if (!use_strcoll(default_charset_info))
|
||||
if (!use_strnxfrm(default_charset_info))
|
||||
#endif
|
||||
{
|
||||
if (type == HA_KEYTYPE_TEXT)
|
||||
case_sort((byte*) key,length);
|
||||
my_tosort(default_charset_info,(byte*) key,length);
|
||||
}
|
||||
key+=length;
|
||||
}
|
||||
@ -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,
|
||||
(size_t) keyseg->base.length);
|
||||
#ifdef USE_STRCOLL
|
||||
if (!use_strcoll(default_charset_info))
|
||||
if (!use_strnxfrm(default_charset_info))
|
||||
#endif
|
||||
{
|
||||
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
|
||||
else if (type == HA_KEYTYPE_FLOAT)
|
||||
@ -150,11 +150,11 @@ uint _nisam_pack_key(register N_INFO *info, uint keynr, uchar *key, uchar *old,
|
||||
else
|
||||
memcpy((byte*) key,old,(size_t) length);
|
||||
#ifdef USE_STRCOLL
|
||||
if (!use_strcoll(default_charset_info))
|
||||
if (!use_strnxfrm(default_charset_info))
|
||||
#endif
|
||||
{
|
||||
if (type == HA_KEYTYPE_TEXT)
|
||||
case_sort((byte*) key,length);
|
||||
my_tosort(default_charset_info,(byte*) key,length);
|
||||
}
|
||||
key+= length;
|
||||
}
|
||||
|
@ -332,7 +332,7 @@ int _nisam_key_cmp(register N_KEYSEG *keyseg, register uchar *a, register uchar
|
||||
end= a+ min(key_length,(uint) length);
|
||||
|
||||
#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)
|
||||
{
|
||||
while (a < end)
|
||||
@ -383,7 +383,7 @@ int _nisam_key_cmp(register N_KEYSEG *keyseg, register uchar *a, register uchar
|
||||
else
|
||||
{
|
||||
#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)
|
||||
{
|
||||
while (a < end)
|
||||
@ -515,11 +515,13 @@ int _nisam_key_cmp(register N_KEYSEG *keyseg, register uchar *a, register uchar
|
||||
if (*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);
|
||||
if (*a == '-' || isdigit((char) *b))
|
||||
if (*a == '-' || my_isdigit(default_charset_info,(char) *b))
|
||||
return (-1);
|
||||
if (*b == '-' || *b++ == ' ' || isdigit((char) *a))
|
||||
if (*b == '-' || *b++ == ' ' ||
|
||||
my_isdigit(default_charset_info,(char) *a))
|
||||
return (1);
|
||||
if (*a++ == ' ')
|
||||
return (-1);
|
||||
@ -539,11 +541,13 @@ int _nisam_key_cmp(register N_KEYSEG *keyseg, register uchar *a, register uchar
|
||||
if (*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);
|
||||
if (*a == '-' || isdigit((char) *b))
|
||||
if (*a == '-' || my_isdigit(default_charset_info,(char) *b))
|
||||
return (-1);
|
||||
if (*b == '-' || *b++ == ' ' || isdigit((char) *a))
|
||||
if (*b == '-' || *b++ == ' ' ||
|
||||
my_isdigit(default_charset_info,(char) *a))
|
||||
return (1);
|
||||
if (*a++ == ' ')
|
||||
return -1;
|
||||
|
@ -342,7 +342,7 @@ static int examine_log(my_string file_name, char **table_names)
|
||||
file_info.process=0;
|
||||
result=uint2korr(head+7);
|
||||
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;
|
||||
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)
|
||||
files_open++;
|
||||
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 (verbose && !record_pos_file)
|
||||
@ -463,7 +463,7 @@ static int examine_log(my_string file_name, char **table_names)
|
||||
{
|
||||
if (!curr_file_info->closed)
|
||||
files_open--;
|
||||
VOID(tree_delete(&tree,(gptr) curr_file_info));
|
||||
VOID(tree_delete(&tree, (gptr) curr_file_info, tree.custom_arg));
|
||||
}
|
||||
break;
|
||||
case LOG_EXTRA:
|
||||
|
@ -687,7 +687,8 @@ static HUFF_COUNTS *init_huff_count(N_INFO *info,my_off_t records)
|
||||
(type == FIELD_NORMAL ||
|
||||
type == FIELD_SKIP_ZERO))
|
||||
count[i].max_zero_fill= count[i].field_length;
|
||||
init_tree(&count[i].int_tree,0,0,-1,(qsort_cmp2) compare_tree,0,NULL,NULL);
|
||||
init_tree(&count[i].int_tree,0,0,-1,(qsort_cmp2) compare_tree,0,
|
||||
NULL, NULL);
|
||||
if (records)
|
||||
count[i].tree_pos=count[i].tree_buff =
|
||||
my_malloc(count[i].field_length > 1 ? tree_buff_length : 2,
|
||||
@ -765,7 +766,8 @@ static int get_statistic(MRG_INFO *mrg,HUFF_COUNTS *huff_counts)
|
||||
if (count->tree_buff)
|
||||
{
|
||||
global_count=count;
|
||||
if (!(element=tree_insert(&count->int_tree,pos,0)) ||
|
||||
if (!(element=tree_insert(&count->int_tree, pos, 0,
|
||||
count->int_tree.custom_arg)) ||
|
||||
((element->count == 1 &&
|
||||
count->tree_buff + tree_buff_length <
|
||||
count->tree_pos + count->field_length) ||
|
||||
@ -1736,7 +1738,8 @@ static int compress_isam_file(MRG_INFO *mrg, HUFF_COUNTS *huff_counts)
|
||||
break;
|
||||
case FIELD_INTERVALL:
|
||||
global_count=count;
|
||||
pos=(byte*) tree_search(&count->int_tree,start_pos);
|
||||
pos=(byte*) tree_search(&count->int_tree, start_pos,
|
||||
count->int_tree.custom_arg);
|
||||
intervall=(uint) (pos - count->tree_buff)/field_length;
|
||||
write_bits(tree->code[intervall],(uint) tree->code_len[intervall]);
|
||||
start_pos=end_pos;
|
||||
|
@ -49,10 +49,6 @@ link_sources:
|
||||
rm -f $(srcdir)/$$f; \
|
||||
@LN_CP_F@ $(srcdir)/../strings/$$f $(srcdir)/$$f; \
|
||||
done; \
|
||||
for f in $(mystringsgen); do \
|
||||
rm -f $(srcdir)/$$f; \
|
||||
@LN_CP_F@ ../strings/$$f $(srcdir)/$$f; \
|
||||
done; \
|
||||
for f in $$qs; do \
|
||||
rm -f $(srcdir)/$$f; \
|
||||
@LN_CP_F@ $(srcdir)/../sql/$$f $(srcdir)/$$f; \
|
||||
|
@ -27,9 +27,6 @@ pkglib_LTLIBRARIES = $(target)
|
||||
|
||||
noinst_PROGRAMS = conf_to_src
|
||||
|
||||
# We need .lo, not .o files for everything.
|
||||
CHARSET_OBJS=@CHARSET_OBJS@
|
||||
LTCHARSET_OBJS= ${CHARSET_OBJS:.o=.lo}
|
||||
|
||||
target_sources = libmysql.c password.c manager.c \
|
||||
get_password.c errmsg.c
|
||||
@ -41,14 +38,18 @@ mystringsobjects = strmov.lo strxmov.lo strxnmov.lo strnmov.lo \
|
||||
strcend.lo bcmp.lo \
|
||||
bchange.lo bmove.lo bmove_upp.lo longlong2str.lo \
|
||||
strtoull.lo strtoll.lo llstr.lo \
|
||||
ctype.lo $(LTCHARSET_OBJS)
|
||||
ctype.lo ctype-simple.lo ctype-mb.lo \
|
||||
ctype-big5.lo ctype-czech.lo ctype-euc_kr.lo \
|
||||
ctype-win1250ch.lo ctype-utf8.lo \
|
||||
ctype-gb2312.lo ctype-gbk.lo ctype-latin1_de.lo \
|
||||
ctype-sjis.lo ctype-tis620.lo ctype-ujis.lo
|
||||
|
||||
mystringsextra= strto.c
|
||||
mystringsgen= ctype_autoconf.c
|
||||
dbugobjects = dbug.lo # IT IS IN SAFEMALLOC.C sanity.lo
|
||||
mysysheaders = mysys_priv.h my_static.h
|
||||
mysysobjects1 = my_init.lo my_static.lo my_malloc.lo my_realloc.lo \
|
||||
my_create.lo my_delete.lo mf_tempfile.lo my_open.lo \
|
||||
mf_casecnv.lo my_read.lo my_write.lo errors.lo \
|
||||
my_read.lo my_write.lo errors.lo \
|
||||
my_error.lo my_getwd.lo my_div.lo \
|
||||
mf_pack.lo my_messnc.lo mf_dirname.lo mf_fn_ext.lo\
|
||||
mf_wcomp.lo typelib.lo safemalloc.lo my_alloc.lo \
|
||||
@ -77,19 +78,15 @@ DEFS = -DDEFAULT_CHARSET_HOME="\"$(MYSQLBASEdir)\"" \
|
||||
-DSHAREDIR="\"$(MYSQLSHAREdir)\"" $(target_defs)
|
||||
|
||||
# The automatic dependencies miss this
|
||||
bmove_upp.lo: $(LTCHARSET_OBJS)
|
||||
ctype.lo: ctype_extra_sources.c
|
||||
#bmove_upp.lo: $(LTCHARSET_OBJS)
|
||||
|
||||
clean-local:
|
||||
rm -f `echo $(mystringsobjects) | sed "s;\.lo;.c;g"` \
|
||||
`echo $(dbugobjects) | sed "s;\.lo;.c;g"` \
|
||||
`echo $(mysysobjects) | sed "s;\.lo;.c;g"` \
|
||||
$(mystringsextra) $(mystringsgen) $(mysysheaders) \
|
||||
ctype_extra_sources.c net.c ../linked_client_sources
|
||||
$(mystringsextra) $(mysysheaders) \
|
||||
../linked_client_sources net.c
|
||||
|
||||
ctype_extra_sources.c: conf_to_src
|
||||
./conf_to_src $(top_srcdir) @CHARSETS_NEED_SOURCE@ > \
|
||||
$(srcdir)/ctype_extra_sources.c
|
||||
conf_to_src_SOURCES = conf_to_src.c
|
||||
conf_to_src_LDADD=
|
||||
#force static linking of conf_to_src - essential when linking against
|
||||
|
@ -49,7 +49,16 @@ const char *client_errors[]=
|
||||
"Error on SHOW SLAVE STATUS:",
|
||||
"Error on SHOW SLAVE HOSTS:",
|
||||
"Error connecting to slave:",
|
||||
"Error connecting to master:"
|
||||
"Error connecting to master:",
|
||||
"Invalid connection handle",
|
||||
"Invalid use of null pointer",
|
||||
"Statement not prepared",
|
||||
"Not all parameters data supplied",
|
||||
"Data truncated",
|
||||
"No parameters exists in the statement",
|
||||
"Invalid parameter number",
|
||||
"Can't send long data for non string or binary data types (parameter: %d)",
|
||||
"Using not supported parameter type: %d (parameter: %d)"
|
||||
};
|
||||
|
||||
/* Start of code added by Roberto M. Serqueira - martinsc@uol.com.br - 05.24.2001 */
|
||||
@ -82,7 +91,16 @@ const char *client_errors[]=
|
||||
"Error on SHOW SLAVE STATUS:",
|
||||
"Error on SHOW SLAVE HOSTS:",
|
||||
"Error connecting to slave:",
|
||||
"Error connecting to master:"
|
||||
"Error connecting to master:",
|
||||
"Invalid connection handle",
|
||||
"Invalid use of null pointer",
|
||||
"Statement not prepared",
|
||||
"Not all parameters data supplied",
|
||||
"Data truncated",
|
||||
"No parameters exists in the statement",
|
||||
"Invalid parameter number",
|
||||
"Can't send long data for non string or binary data types (parameter: %d)",
|
||||
"Using not supported parameter type: %d (parameter: %d)"
|
||||
};
|
||||
|
||||
#else /* ENGLISH */
|
||||
@ -113,7 +131,16 @@ const char *client_errors[]=
|
||||
"Error on SHOW SLAVE STATUS:",
|
||||
"Error on SHOW SLAVE HOSTS:",
|
||||
"Error connecting to slave:",
|
||||
"Error connecting to master:"
|
||||
"Error connecting to master:",
|
||||
"Invalid connection handle",
|
||||
"Invalid use of null pointer",
|
||||
"Statement not prepared",
|
||||
"Not all parameters data supplied",
|
||||
"Data truncated",
|
||||
"No parameters exists in the statement",
|
||||
"Invalid parameter number",
|
||||
"Can't send long data for non string or binary data types (parameter: %d)",
|
||||
"Using not supported parameter type: %d (parameter: %d)"
|
||||
};
|
||||
#endif
|
||||
|
||||
|
1142
libmysql/libmysql.c
1142
libmysql/libmysql.c
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
LIBRARY LIBMYSQL
|
||||
DESCRIPTION 'MySQL 4.0 Client Library'
|
||||
VERSION 5.0
|
||||
DESCRIPTION 'MySQL 4.1 Client Library'
|
||||
VERSION 6.0
|
||||
EXPORTS
|
||||
mysql_affected_rows
|
||||
mysql_close
|
||||
@ -59,7 +59,6 @@ EXPORTS
|
||||
list_add
|
||||
list_delete
|
||||
max_allowed_packet
|
||||
my_casecmp
|
||||
my_init
|
||||
my_end
|
||||
my_strdup
|
||||
@ -101,8 +100,8 @@ EXPORTS
|
||||
mysql_rpl_probe
|
||||
mysql_set_master
|
||||
mysql_add_slave
|
||||
|
||||
|
||||
mysql_warning_count
|
||||
mysql_warnings
|
||||
|
||||
|
||||
|
||||
|
@ -138,7 +138,7 @@ MYSQL_MANAGER* STDCALL mysql_manager_connect(MYSQL_MANAGER* con,
|
||||
}
|
||||
sock_addr.sin_port = (ushort) htons((ushort) port);
|
||||
if (my_connect(sock,(struct sockaddr *) &sock_addr, sizeof(sock_addr),
|
||||
0) <0)
|
||||
0))
|
||||
{
|
||||
con->last_errno=errno;
|
||||
sprintf(con->last_error ,"Could not connect to %-.64s", host);
|
||||
|
@ -43,17 +43,20 @@ sqlsources = convert.cc derror.cc field.cc field_conv.cc filesort.cc \
|
||||
hostname.cc init.cc \
|
||||
item.cc item_buff.cc item_cmpfunc.cc item_create.cc \
|
||||
item_func.cc item_strfunc.cc item_sum.cc item_timefunc.cc \
|
||||
item_uniq.cc key.cc lock.cc log.cc log_event.cc mf_iocache.cc\
|
||||
item_uniq.cc item_subselect.cc \
|
||||
key.cc lock.cc log.cc log_event.cc mf_iocache.cc\
|
||||
mini_client.cc net_pkg.cc net_serv.cc opt_ft.cc opt_range.cc \
|
||||
opt_sum.cc procedure.cc records.cc sql_acl.cc \
|
||||
repl_failsafe.cc slave.cc sql_load.cc sql_olap.cc \
|
||||
sql_analyse.cc sql_base.cc sql_cache.cc sql_class.cc \
|
||||
sql_crypt.cc sql_db.cc sql_delete.cc sql_insert.cc sql_lex.cc \
|
||||
sql_list.cc sql_manager.cc sql_map.cc set_var.cc sql_parse.cc \
|
||||
sql_rename.cc sql_repl.cc sql_select.cc sql_do.cc sql_show.cc \
|
||||
sql_crypt.cc sql_db.cc sql_delete.cc sql_error.cc sql_insert.cc \
|
||||
sql_lex.cc sql_list.cc sql_manager.cc sql_map.cc sql_parse.cc \
|
||||
sql_prepare.cc sql_derived.cc sql_rename.cc sql_repl.cc \
|
||||
sql_select.cc sql_do.cc sql_show.cc set_var.cc \
|
||||
sql_string.cc sql_table.cc sql_test.cc sql_udf.cc \
|
||||
sql_update.cc sql_yacc.cc table.cc thr_malloc.cc time.cc \
|
||||
unireg.cc uniques.cc stacktrace.c sql_union.cc hash_filo.cc
|
||||
unireg.cc uniques.cc stacktrace.c sql_union.cc hash_filo.cc \
|
||||
spatial.cc gstream.cc
|
||||
|
||||
EXTRA_DIST = lib_vio.c
|
||||
|
||||
|
@ -154,14 +154,12 @@ check_connections1(THD *thd)
|
||||
end+=SCRAMBLE_LENGTH +1;
|
||||
int2store(end,client_flags);
|
||||
end[2]=MY_CHARSET_CURRENT;
|
||||
|
||||
#define MIN_HANDSHAKE_SIZE 6
|
||||
|
||||
int2store(end+3,thd->server_status);
|
||||
bzero(end+5,13);
|
||||
end+=18;
|
||||
if (net_write_command(net,protocol_version, buff,
|
||||
(uint) (end-buff)))
|
||||
if (net_write_command(net,protocol_version,
|
||||
NullS, 0,
|
||||
buff, (uint) (end-buff)))
|
||||
{
|
||||
inc_host_errors(&thd->remote.sin_addr);
|
||||
return(ER_HANDSHAKE_ERROR);
|
||||
@ -169,6 +167,8 @@ check_connections1(THD *thd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MIN_HANDSHAKE_SIZE 6
|
||||
|
||||
static int
|
||||
check_connections2(THD * thd)
|
||||
{
|
||||
@ -214,13 +214,12 @@ check_connections2(THD * thd)
|
||||
static bool check_user(THD *thd,enum_server_command command, const char *user,
|
||||
const char *passwd, const char *db, bool check_count)
|
||||
{
|
||||
NET *net= &thd->net;
|
||||
USER_RESOURCES ur;
|
||||
thd->db=0;
|
||||
|
||||
if (!(thd->user = my_strdup(user, MYF(0))))
|
||||
{
|
||||
send_error(net,ER_OUT_OF_RESOURCES);
|
||||
send_error(thd,ER_OUT_OF_RESOURCES);
|
||||
return 1;
|
||||
}
|
||||
thd->master_access=acl_getroot(thd, thd->host, thd->ip, thd->user,
|
||||
@ -236,7 +235,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user,
|
||||
thd->master_access, thd->db ? thd->db : "*none*"));
|
||||
if (thd->master_access & NO_ACCESS)
|
||||
{
|
||||
net_printf(net, ER_ACCESS_DENIED_ERROR,
|
||||
net_printf(thd, ER_ACCESS_DENIED_ERROR,
|
||||
thd->user,
|
||||
thd->host_or_ip,
|
||||
passwd[0] ? ER(ER_YES) : ER(ER_NO));
|
||||
@ -254,7 +253,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user,
|
||||
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
||||
if (tmp)
|
||||
{ // Too many connections
|
||||
send_error(net, ER_CON_COUNT_ERROR);
|
||||
send_error(thd, ER_CON_COUNT_ERROR);
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
@ -269,7 +268,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user,
|
||||
if (db && db[0])
|
||||
return test(mysql_change_db(thd,db));
|
||||
else
|
||||
send_ok(net); // Ready to handle questions
|
||||
send_ok(thd); // Ready to handle questions
|
||||
return 0; // ok
|
||||
}
|
||||
|
||||
@ -370,7 +369,6 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups)
|
||||
|
||||
(void) pthread_mutex_init(&LOCK_mysql_create_db,MY_MUTEX_INIT_SLOW);
|
||||
(void) pthread_mutex_init(&LOCK_Acl,MY_MUTEX_INIT_SLOW);
|
||||
(void) pthread_mutex_init(&LOCK_grant,MY_MUTEX_INIT_FAST);
|
||||
(void) pthread_mutex_init(&LOCK_open,MY_MUTEX_INIT_FAST);
|
||||
(void) pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST);
|
||||
(void) pthread_mutex_init(&LOCK_mapped_file,MY_MUTEX_INIT_SLOW);
|
||||
@ -388,6 +386,7 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups)
|
||||
(void) pthread_mutex_init(&LOCK_rpl_status, MY_MUTEX_INIT_FAST);
|
||||
(void) pthread_mutex_init(&LOCK_active_mi, MY_MUTEX_INIT_FAST);
|
||||
(void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
|
||||
(void) my_rwlock_init(&LOCK_grant, NULL);
|
||||
(void) pthread_cond_init(&COND_thread_count,NULL);
|
||||
(void) pthread_cond_init(&COND_refresh,NULL);
|
||||
(void) pthread_cond_init(&COND_thread_cache,NULL);
|
||||
@ -400,7 +399,7 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups)
|
||||
mysql_server_end();
|
||||
return 1;
|
||||
}
|
||||
charsets_list = list_charsets(MYF(MY_COMPILED_SETS|MY_CONFIG_SETS));
|
||||
charsets_list = list_charsets(MYF(MY_CS_COMPILED|MY_CS_CONFIG));
|
||||
|
||||
/* Parameter for threads created for connections */
|
||||
(void) pthread_attr_init(&connection_attrib);
|
||||
@ -499,7 +498,7 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups)
|
||||
After this we can't quit by a simple unireg_abort
|
||||
*/
|
||||
error_handler_hook = my_message_sql;
|
||||
if (pthread_key_create(&THR_THD,NULL) || pthread_key_create(&THR_NET,NULL) ||
|
||||
if (pthread_key_create(&THR_THD,NULL) ||
|
||||
pthread_key_create(&THR_MALLOC,NULL))
|
||||
{
|
||||
sql_print_error("Can't create thread-keys");
|
||||
|
@ -50,7 +50,7 @@ static my_bool mysql_client_init=0;
|
||||
uint mysql_port=0;
|
||||
my_string mysql_unix_port=0;
|
||||
|
||||
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_TRANSACTIONS)
|
||||
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_TRANSACTIONS | CLIENT_PROTOCOL_41)
|
||||
|
||||
#if defined(MSDOS) || defined(__WIN__)
|
||||
#define ERRNO WSAGetLastError()
|
||||
@ -212,12 +212,12 @@ static void free_rows(MYSQL_DATA *cur)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
my_bool
|
||||
simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
|
||||
ulong length, my_bool skipp_check)
|
||||
{
|
||||
NET *net= &mysql->net;
|
||||
int result= -1;
|
||||
my_bool result= 1;
|
||||
|
||||
/* Check that we are calling the client functions in right order */
|
||||
if (mysql->status != MYSQL_STATUS_READY)
|
||||
@ -239,7 +239,7 @@ simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
|
||||
result = lib_dispatch_command(command, net, arg,length);
|
||||
if (!skipp_check)
|
||||
result= ((mysql->packet_length=net_safe_read(mysql)) == packet_error ?
|
||||
-1 : 0);
|
||||
1 : 0);
|
||||
end:
|
||||
return result;
|
||||
}
|
||||
@ -412,7 +412,7 @@ mysql_free_result(MYSQL_RES *result)
|
||||
uint pkt_len;
|
||||
if ((pkt_len=(uint) net_safe_read(result->handle)) == packet_error)
|
||||
break;
|
||||
if (pkt_len == 1 && result->handle->net.read_pos[0] == 254)
|
||||
if (pkt_len <= 8 && result->handle->net.read_pos[0] == 254)
|
||||
break; /* End of data */
|
||||
}
|
||||
result->handle->status=MYSQL_STATUS_READY;
|
||||
@ -632,7 +632,7 @@ static MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
|
||||
result->rows=0;
|
||||
result->fields=fields;
|
||||
|
||||
while (*(cp=net->read_pos) != 254 || pkt_len != 1)
|
||||
while (*(cp=net->read_pos) != 254 || pkt_len >= 8)
|
||||
{
|
||||
result->rows++;
|
||||
if (!(cur= (MYSQL_ROWS*) alloc_root(&result->alloc,
|
||||
@ -676,6 +676,8 @@ static MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
|
||||
}
|
||||
}
|
||||
*prev_ptr=0; /* last pointer is null */
|
||||
mysql->warning_count= uint2korr(cp+1);
|
||||
DBUG_PRINT("info",("warning_count: %ld", mysql->warning_count));
|
||||
DBUG_PRINT("exit",("Got %d rows",result->rows));
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
@ -696,8 +698,11 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths)
|
||||
|
||||
if ((pkt_len=net_safe_read(mysql)) == packet_error)
|
||||
return -1;
|
||||
if (pkt_len == 1 && mysql->net.read_pos[0] == 254)
|
||||
if (pkt_len <= 8 && mysql->net.read_pos[0] == 254)
|
||||
{
|
||||
mysql->warning_count= uint2korr(mysql->net.read_pos+1);
|
||||
return 1; /* End of data */
|
||||
}
|
||||
prev_pos= 0; /* allowed to write at packet[-1] */
|
||||
pos=mysql->net.read_pos;
|
||||
for (field=0 ; field < fields ; field++)
|
||||
@ -1124,7 +1129,7 @@ mysql_send_query(MYSQL* mysql, const char* query, ulong length)
|
||||
}
|
||||
|
||||
|
||||
int STDCALL
|
||||
my_bool STDCALL
|
||||
mysql_read_query_result(MYSQL *mysql)
|
||||
{
|
||||
uchar *pos;
|
||||
@ -1134,7 +1139,7 @@ mysql_read_query_result(MYSQL *mysql)
|
||||
DBUG_ENTER("mysql_read_query_result");
|
||||
|
||||
if ((length=net_safe_read(mysql)) == packet_error)
|
||||
DBUG_RETURN(-1);
|
||||
DBUG_RETURN(1);
|
||||
free_old_query(mysql); /* Free old result */
|
||||
get_info:
|
||||
pos=(uchar*) mysql->net.read_pos;
|
||||
@ -1142,10 +1147,8 @@ get_info:
|
||||
{
|
||||
mysql->affected_rows= net_field_length_ll(&pos);
|
||||
mysql->insert_id= net_field_length_ll(&pos);
|
||||
if (mysql->server_capabilities & CLIENT_TRANSACTIONS)
|
||||
{
|
||||
mysql->server_status=uint2korr(pos); pos+=2;
|
||||
}
|
||||
mysql->warning_count=uint2korr(pos); pos+=2;
|
||||
if (pos < mysql->net.read_pos+length && net_field_length(&pos))
|
||||
mysql->info=(char*) pos;
|
||||
DBUG_RETURN(0);
|
||||
@ -1154,7 +1157,7 @@ get_info:
|
||||
{
|
||||
int error=send_file_to_server(mysql,(char*) pos);
|
||||
if ((length=net_safe_read(mysql)) == packet_error || error)
|
||||
DBUG_RETURN(-1);
|
||||
DBUG_RETURN(1);
|
||||
goto get_info; /* Get info packet */
|
||||
}
|
||||
if (!(mysql->server_status & SERVER_STATUS_AUTOCOMMIT))
|
||||
@ -1162,19 +1165,20 @@ get_info:
|
||||
|
||||
mysql->extra_info= net_field_length_ll(&pos); /* Maybe number of rec */
|
||||
if (!(fields=read_rows(mysql,(MYSQL_FIELD*) 0,5)))
|
||||
DBUG_RETURN(-1);
|
||||
DBUG_RETURN(1);
|
||||
if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc,
|
||||
(uint) field_count,0,
|
||||
(my_bool) test(mysql->server_capabilities &
|
||||
CLIENT_LONG_FLAG))))
|
||||
DBUG_RETURN(-1);
|
||||
DBUG_RETURN(1);
|
||||
mysql->status=MYSQL_STATUS_GET_RESULT;
|
||||
mysql->field_count=field_count;
|
||||
mysql->warning_count= 0;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* A modified version of connect(). connect2() allows you to specify
|
||||
* A modified version of connect(). my_connect() allows you to specify
|
||||
* a timeout value, in seconds, that we should wait until we
|
||||
* derermine we can't connect to a particular host. If timeout is 0,
|
||||
* my_connect() will behave exactly like connect().
|
||||
@ -1182,11 +1186,11 @@ get_info:
|
||||
* Base version coded by Steve Bernacki, Jr. <steve@navinet.net>
|
||||
*****************************************************************************/
|
||||
|
||||
int my_connect(my_socket s, const struct sockaddr *name, uint namelen,
|
||||
my_bool my_connect(my_socket s, const struct sockaddr *name, uint namelen,
|
||||
uint timeout)
|
||||
{
|
||||
#if defined(__WIN__) || defined(OS2)
|
||||
return connect(s, (struct sockaddr*) name, namelen);
|
||||
return connect(s, (struct sockaddr*) name, namelen) != 0;
|
||||
#else
|
||||
int flags, res, s_err;
|
||||
SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint);
|
||||
@ -1199,7 +1203,7 @@ int my_connect(my_socket s, const struct sockaddr *name, uint namelen,
|
||||
*/
|
||||
|
||||
if (timeout == 0)
|
||||
return connect(s, (struct sockaddr*) name, namelen);
|
||||
return connect(s, (struct sockaddr*) name, namelen) != 0;
|
||||
|
||||
flags = fcntl(s, F_GETFL, 0); /* Set socket to not block */
|
||||
#ifdef O_NONBLOCK
|
||||
@ -1212,7 +1216,7 @@ int my_connect(my_socket s, const struct sockaddr *name, uint namelen,
|
||||
if ((res != 0) && (s_err != EINPROGRESS))
|
||||
{
|
||||
errno = s_err; /* Restore it */
|
||||
return(-1);
|
||||
return(1);
|
||||
}
|
||||
if (res == 0) /* Connected quickly! */
|
||||
return(0);
|
||||
@ -1252,7 +1256,7 @@ int my_connect(my_socket s, const struct sockaddr *name, uint namelen,
|
||||
now_time=time(NULL);
|
||||
timeout-= (uint) (now_time - start_time);
|
||||
if (errno != EINTR || (int) timeout <= 0)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* select() returned something more interesting than zero, let's
|
||||
@ -1262,12 +1266,12 @@ int my_connect(my_socket s, const struct sockaddr *name, uint namelen,
|
||||
|
||||
s_err=0;
|
||||
if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0)
|
||||
return(-1);
|
||||
return(1);
|
||||
|
||||
if (s_err)
|
||||
{ /* getsockopt could succeed */
|
||||
errno = s_err;
|
||||
return(-1); /* but return an error... */
|
||||
return(1); /* but return an error... */
|
||||
}
|
||||
return(0); /* It's all good! */
|
||||
#endif
|
||||
@ -1881,6 +1885,11 @@ const char * STDCALL mysql_error(MYSQL *mysql)
|
||||
return (mysql)->net.last_error;
|
||||
}
|
||||
|
||||
uint STDCALL mysql_warning_count(MYSQL *mysql)
|
||||
{
|
||||
return mysql->warning_count;
|
||||
}
|
||||
|
||||
const char *STDCALL mysql_info(MYSQL *mysql)
|
||||
{
|
||||
return (mysql)->info;
|
||||
@ -1906,6 +1915,18 @@ uint STDCALL mysql_thread_safe(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
MYSQL_RES *STDCALL mysql_warnings(MYSQL *mysql)
|
||||
{
|
||||
uint warning_count;
|
||||
DBUG_ENTER("mysql_warnings");
|
||||
/* Save warning count as mysql_real_query may change this */
|
||||
warning_count= mysql->warning_count;
|
||||
if (mysql_real_query(mysql, "SHOW WARNINGS", 13))
|
||||
DBUG_RETURN(0);
|
||||
mysql->warning_count= warning_count;
|
||||
DBUG_RETURN(mysql_store_result(mysql));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
** Some support functions
|
||||
****************************************************************************/
|
||||
|
@ -7,6 +7,8 @@ ft_test1
|
||||
mi_test1
|
||||
mi_test2
|
||||
mi_test3
|
||||
rt_test
|
||||
sp_test
|
||||
myisamchk
|
||||
myisamlog
|
||||
myisampack
|
||||
|
@ -25,14 +25,16 @@ bin_PROGRAMS = myisamchk myisamlog myisampack
|
||||
myisamchk_DEPENDENCIES= $(LIBRARIES)
|
||||
myisamlog_DEPENDENCIES= $(LIBRARIES)
|
||||
myisampack_DEPENDENCIES=$(LIBRARIES)
|
||||
noinst_PROGRAMS = mi_test1 mi_test2 mi_test3 ft_dump #ft_test1 ft_eval
|
||||
noinst_HEADERS = myisamdef.h fulltext.h ftdefs.h ft_test1.h ft_eval.h
|
||||
noinst_PROGRAMS = mi_test1 mi_test2 mi_test3 rt_test sp_test ft_dump #ft_test1 ft_eval
|
||||
noinst_HEADERS = myisamdef.h rt_index.h rt_key.h rt_mbr.h sp_defs.h fulltext.h ftdefs.h ft_test1.h ft_eval.h
|
||||
mi_test1_DEPENDENCIES= $(LIBRARIES)
|
||||
mi_test2_DEPENDENCIES= $(LIBRARIES)
|
||||
mi_test3_DEPENDENCIES= $(LIBRARIES)
|
||||
#ft_test1_DEPENDENCIES= $(LIBRARIES)
|
||||
#ft_eval_DEPENDENCIES= $(LIBRARIES)
|
||||
ft_dump_DEPENDENCIES= $(LIBRARIES)
|
||||
rt_test_DEPENDENCIES= $(LIBRARIES)
|
||||
sp_test_DEPENDENCIES= $(LIBRARIES)
|
||||
libmyisam_a_SOURCES = mi_open.c mi_extra.c mi_info.c mi_rkey.c \
|
||||
mi_rnext.c mi_rnext_same.c \
|
||||
mi_search.c mi_page.c mi_key.c mi_locking.c \
|
||||
@ -46,8 +48,9 @@ libmyisam_a_SOURCES = mi_open.c mi_extra.c mi_info.c mi_rkey.c \
|
||||
mi_changed.c mi_static.c mi_delete_all.c \
|
||||
mi_delete_table.c mi_rename.c mi_check.c \
|
||||
ft_parser.c ft_stopwords.c ft_static.c \
|
||||
ft_update.c ft_boolean_search.c ft_nlq_search.c sort.c
|
||||
CLEANFILES = test?.MY? FT?.MY? isam.log mi_test_all
|
||||
ft_update.c ft_boolean_search.c ft_nlq_search.c sort.c \
|
||||
rt_index.c rt_key.c rt_mbr.c rt_split.c sp_key.c
|
||||
CLEANFILES = test?.MY? FT?.MY? isam.log mi_test_all rt_test.MY? sp_test.MY?
|
||||
DEFS = -DMAP_TO_USE_RAID
|
||||
|
||||
# Move to automake rules ?
|
||||
|
@ -119,7 +119,7 @@ static int FTB_WORD_cmp(my_off_t *v, FTB_WORD *a, FTB_WORD *b)
|
||||
static int FTB_WORD_cmp_list(CHARSET_INFO *cs, FTB_WORD **a, FTB_WORD **b)
|
||||
{
|
||||
/* ORDER BY word DESC, ndepth DESC */
|
||||
int i=_mi_compare_text(cs, (*b)->word+1,(*b)->len-1,
|
||||
int i= mi_compare_text(cs, (*b)->word+1,(*b)->len-1,
|
||||
(*a)->word+1,(*a)->len-1,0);
|
||||
if (!i)
|
||||
i=CMP_NUM((*b)->ndepth,(*a)->ndepth);
|
||||
@ -242,8 +242,8 @@ static void _ftb_init_index_search(FT_INFO *ftb)
|
||||
{
|
||||
if (!is_tree_inited(& ftb->no_dupes))
|
||||
{
|
||||
init_tree(& ftb->no_dupes,0,0,sizeof(my_off_t),
|
||||
_ftb_no_dupes_cmp,0,0,0);
|
||||
init_tree(&ftb->no_dupes,0,0,sizeof(my_off_t),
|
||||
_ftb_no_dupes_cmp, 0, NULL, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -251,7 +251,7 @@ static void _ftb_init_index_search(FT_INFO *ftb)
|
||||
SEARCH_FIND | SEARCH_BIGGER, keyroot);
|
||||
if (!r)
|
||||
{
|
||||
r=_mi_compare_text(ftb->charset,
|
||||
r= mi_compare_text(ftb->charset,
|
||||
info->lastkey + (ftbw->flags&FTB_FLAG_TRUNC),
|
||||
ftbw->len - (ftbw->flags&FTB_FLAG_TRUNC),
|
||||
ftbw->word + (ftbw->flags&FTB_FLAG_TRUNC),
|
||||
@ -460,7 +460,7 @@ int ft_boolean_read_next(FT_INFO *ftb, char *record)
|
||||
(curdoc=((FTB_WORD *)queue_top(& ftb->queue))->docid[0]) !=
|
||||
HA_POS_ERROR)
|
||||
{
|
||||
while (curdoc==(ftbw=(FTB_WORD *)queue_top(& ftb->queue))->docid[0])
|
||||
while (curdoc == (ftbw=(FTB_WORD *)queue_top(& ftb->queue))->docid[0])
|
||||
{
|
||||
_ftb_climb_the_tree(ftb, ftbw, 0);
|
||||
|
||||
@ -469,7 +469,7 @@ int ft_boolean_read_next(FT_INFO *ftb, char *record)
|
||||
SEARCH_BIGGER , keyroot);
|
||||
if (!r)
|
||||
{
|
||||
r=_mi_compare_text(ftb->charset,
|
||||
r= mi_compare_text(ftb->charset,
|
||||
info->lastkey + (ftbw->flags&FTB_FLAG_TRUNC),
|
||||
ftbw->len - (ftbw->flags&FTB_FLAG_TRUNC),
|
||||
ftbw->word + (ftbw->flags&FTB_FLAG_TRUNC),
|
||||
@ -501,12 +501,14 @@ int ft_boolean_read_next(FT_INFO *ftb, char *record)
|
||||
ftbe->yesses>=(ftbe->ythresh-ftbe->yweaks) && !ftbe->nos)
|
||||
{
|
||||
/* curdoc matched ! */
|
||||
if (is_tree_inited(& ftb->no_dupes) &&
|
||||
tree_insert(& ftb->no_dupes, &curdoc, 0)->count >1)
|
||||
if (is_tree_inited(&ftb->no_dupes) &&
|
||||
tree_insert(&ftb->no_dupes, &curdoc, 0,
|
||||
ftb->no_dupes.custom_arg)->count >1)
|
||||
/* but it managed to get past this line once */
|
||||
continue;
|
||||
|
||||
info->lastpos=curdoc;
|
||||
/* Clear all states, except that the table was updated */
|
||||
info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
|
||||
|
||||
if (!(*info->read_record)(info,curdoc,record))
|
||||
@ -575,7 +577,7 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length)
|
||||
for (a=0, b=ftb->queue.elements, c=(a+b)/2; b-a>1; c=(a+b)/2)
|
||||
{
|
||||
ftbw=ftb->list[c];
|
||||
if (_mi_compare_text(ftb->charset, word.pos, word.len,
|
||||
if (mi_compare_text(ftb->charset, word.pos, word.len,
|
||||
(uchar*) ftbw->word+1, ftbw->len-1,
|
||||
(my_bool) (ftbw->flags&FTB_FLAG_TRUNC)) >0)
|
||||
b=c;
|
||||
@ -585,7 +587,7 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length)
|
||||
for (; c>=0; c--)
|
||||
{
|
||||
ftbw=ftb->list[c];
|
||||
if (_mi_compare_text(ftb->charset, word.pos,word.len,
|
||||
if (mi_compare_text(ftb->charset, word.pos,word.len,
|
||||
(uchar*) ftbw->word+1,ftbw->len-1,
|
||||
(my_bool) (ftbw->flags&FTB_FLAG_TRUNC)))
|
||||
break;
|
||||
|
@ -131,7 +131,7 @@ int main(int argc,char *argv[])
|
||||
#endif
|
||||
|
||||
snprintf(buf,MAX_LEN,"%.*s",(int) keylen,info->lastkey+1);
|
||||
casedn_str(buf);
|
||||
my_casedn_str(default_charset_info,buf);
|
||||
total++;
|
||||
lengths[keylen]++;
|
||||
|
||||
|
@ -33,7 +33,7 @@ FILE *df,*qf;
|
||||
|
||||
MI_COLUMNDEF recinfo[3];
|
||||
MI_KEYDEF keyinfo[2];
|
||||
MI_KEYSEG keyseg[10];
|
||||
HA_KEYSEG keyseg[10];
|
||||
|
||||
#define SWL_INIT 500
|
||||
#define SWL_PLUS 50
|
||||
|
@ -98,9 +98,10 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
|
||||
|
||||
while (!r)
|
||||
{
|
||||
if (_mi_compare_text(aio->charset,
|
||||
if (mi_compare_text(aio->charset,
|
||||
aio->info->lastkey,keylen,
|
||||
aio->keybuff,keylen,0)) break;
|
||||
aio->keybuff,keylen,0))
|
||||
break;
|
||||
|
||||
#if HA_FT_WTYPE == HA_KEYTYPE_FLOAT
|
||||
#ifdef EVAL_RUN
|
||||
@ -120,7 +121,7 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
|
||||
sdoc.doc.dpos=aio->info->lastpos;
|
||||
|
||||
/* saving document matched into dtree */
|
||||
if (!(selem=tree_insert(&aio->dtree, &sdoc, 0)))
|
||||
if (!(selem=tree_insert(&aio->dtree, &sdoc, 0, aio->dtree.custom_arg)))
|
||||
return 1;
|
||||
|
||||
sptr=(FT_SUPERDOC *)ELEMENT_KEY((&aio->dtree), selem);
|
||||
|
@ -37,7 +37,7 @@ typedef struct st_ft_docstat {
|
||||
|
||||
static int FT_WORD_cmp(CHARSET_INFO* cs, FT_WORD *w1, FT_WORD *w2)
|
||||
{
|
||||
return _mi_compare_text(cs, (uchar*) w1->pos, w1->len,
|
||||
return mi_compare_text(cs, (uchar*) w1->pos, w1->len,
|
||||
(uchar*) w2->pos, w2->len, 0);
|
||||
}
|
||||
|
||||
@ -105,13 +105,13 @@ FT_WORD * ft_linearize(TREE *wtree)
|
||||
DBUG_RETURN(wlist);
|
||||
}
|
||||
|
||||
#define true_word_char(X) (isalnum(X) || (X)=='_')
|
||||
#define true_word_char(s,X) (my_isalnum(s,X) || (X)=='_')
|
||||
#ifdef HYPHEN_IS_DELIM
|
||||
#define misc_word_char(X) ((X)=='\'')
|
||||
#else
|
||||
#define misc_word_char(X) ((X)=='\'' || (X)=='-')
|
||||
#endif
|
||||
#define word_char(X) (true_word_char(X) || misc_word_char(X))
|
||||
#define word_char(s,X) (true_word_char(s,X) || misc_word_char(s,X))
|
||||
|
||||
|
||||
/* returns:
|
||||
@ -132,7 +132,11 @@ byte ft_get_word(byte **start, byte *end, FT_WORD *word, FTB_PARAM *param)
|
||||
{
|
||||
for (;doc<end;doc++)
|
||||
{
|
||||
if (true_word_char(*doc)) break;
|
||||
/*
|
||||
BAR TODO: discuss with Serge how to remove
|
||||
default_charset_info correctly
|
||||
*/
|
||||
if (true_word_char(default_charset_info,*doc)) break;
|
||||
if (*doc == FTB_RQUOT && param->quot) {
|
||||
param->quot=doc;
|
||||
*start=doc+1;
|
||||
@ -162,7 +166,7 @@ byte ft_get_word(byte **start, byte *end, FT_WORD *word, FTB_PARAM *param)
|
||||
|
||||
mwc=0;
|
||||
for (word->pos=doc; doc<end; doc++)
|
||||
if (true_word_char(*doc))
|
||||
if (true_word_char(default_charset_info,*doc))
|
||||
mwc=0;
|
||||
else if (!misc_word_char(*doc) || mwc++)
|
||||
break;
|
||||
@ -191,12 +195,12 @@ byte ft_simple_get_word(byte **start, byte *end, FT_WORD *word)
|
||||
{
|
||||
for (;doc<end;doc++)
|
||||
{
|
||||
if (true_word_char(*doc)) break;
|
||||
if (true_word_char(default_charset_info,*doc)) break;
|
||||
}
|
||||
|
||||
mwc=0;
|
||||
for(word->pos=doc; doc<end; doc++)
|
||||
if (true_word_char(*doc))
|
||||
if (true_word_char(default_charset_info,*doc))
|
||||
mwc=0;
|
||||
else if (!misc_word_char(*doc) || mwc++)
|
||||
break;
|
||||
@ -226,7 +230,7 @@ int ft_parse(TREE *wtree, byte *doc, int doclen)
|
||||
|
||||
while (ft_simple_get_word(&doc,end,&w))
|
||||
{
|
||||
if (!tree_insert(wtree, &w, 0))
|
||||
if (!tree_insert(wtree, &w, 0, wtree->custom_arg))
|
||||
goto err;
|
||||
}
|
||||
return 0;
|
||||
|
@ -23,7 +23,7 @@ ulong ft_max_word_len=HA_FT_MAXLEN;
|
||||
ulong ft_max_word_len_for_sort=20;
|
||||
const char *ft_boolean_syntax="+ -><()~*:\"\"&|";
|
||||
|
||||
const MI_KEYSEG ft_keysegs[FT_SEGS]={
|
||||
const HA_KEYSEG ft_keysegs[FT_SEGS]={
|
||||
{
|
||||
HA_KEYTYPE_VARTEXT, /* type */
|
||||
7, /* language (will be overwritten) */
|
||||
@ -36,7 +36,7 @@ const MI_KEYSEG ft_keysegs[FT_SEGS]={
|
||||
HA_FT_WLEN, /* start */
|
||||
#endif /* EVAL_RUN */
|
||||
0, /* null_pos */
|
||||
NULL /* sort_order */
|
||||
NULL /* charset */
|
||||
},
|
||||
#ifdef EVAL_RUN
|
||||
{
|
||||
|
@ -28,7 +28,7 @@ static TREE *stopwords3=NULL;
|
||||
static int FT_STOPWORD_cmp(void* cmp_arg __attribute__((unused)),
|
||||
FT_STOPWORD *w1, FT_STOPWORD *w2)
|
||||
{
|
||||
return _mi_compare_text(default_charset_info,
|
||||
return mi_compare_text(default_charset_info,
|
||||
(uchar *)w1->pos,w1->len,
|
||||
(uchar *)w2->pos,w2->len,0);
|
||||
}
|
||||
@ -41,8 +41,8 @@ int ft_init_stopwords(const char **sws)
|
||||
if(!stopwords3)
|
||||
{
|
||||
if(!(stopwords3=(TREE *)my_malloc(sizeof(TREE),MYF(0)))) return -1;
|
||||
init_tree(stopwords3,0,0,sizeof(FT_STOPWORD),(qsort_cmp2)&FT_STOPWORD_cmp,0,
|
||||
NULL, NULL);
|
||||
init_tree(stopwords3,0,0,sizeof(FT_STOPWORD),(qsort_cmp2)&FT_STOPWORD_cmp,
|
||||
0, NULL, NULL);
|
||||
}
|
||||
|
||||
if(!sws) return 0;
|
||||
@ -50,7 +50,7 @@ int ft_init_stopwords(const char **sws)
|
||||
for(;*sws;sws++)
|
||||
{
|
||||
if( (sw.len= (uint) strlen(sw.pos=*sws)) < ft_min_word_len) continue;
|
||||
if(!tree_insert(stopwords3, &sw, 0))
|
||||
if(!tree_insert(stopwords3, &sw, 0, stopwords3->custom_arg))
|
||||
{
|
||||
delete_tree(stopwords3); /* purecov: inspected */
|
||||
return -1; /* purecov: inspected */
|
||||
@ -64,7 +64,7 @@ int is_stopword(char *word, uint len)
|
||||
FT_STOPWORD sw;
|
||||
sw.pos=word;
|
||||
sw.len=len;
|
||||
return tree_search(stopwords3,&sw) != NULL;
|
||||
return tree_search(stopwords3, &sw, stopwords3->custom_arg) != NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -64,7 +64,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
static MI_COLUMNDEF recinfo[3];
|
||||
static MI_KEYDEF keyinfo[2];
|
||||
static MI_KEYSEG keyseg[10];
|
||||
static HA_KEYSEG keyseg[10];
|
||||
|
||||
static int run_test(const char *filename)
|
||||
{
|
||||
|
@ -163,7 +163,7 @@ int _mi_ft_cmp(MI_INFO *info, uint keynr, const byte *rec1, const byte *rec2)
|
||||
{
|
||||
if ((ftsi1.pos != ftsi2.pos) &&
|
||||
(!ftsi1.pos || !ftsi2.pos ||
|
||||
_mi_compare_text(cs, (uchar*) ftsi1.pos,ftsi1.len,
|
||||
mi_compare_text(cs, (uchar*) ftsi1.pos,ftsi1.len,
|
||||
(uchar*) ftsi2.pos,ftsi2.len,0)))
|
||||
return THOSE_TWO_DAMN_KEYS_ARE_REALLY_DIFFERENT;
|
||||
}
|
||||
@ -190,7 +190,7 @@ int _mi_ft_update(MI_INFO *info, uint keynr, byte *keybuf,
|
||||
error=0;
|
||||
while(old_word->pos && new_word->pos)
|
||||
{
|
||||
cmp=_mi_compare_text(cs, (uchar*) old_word->pos,old_word->len,
|
||||
cmp= mi_compare_text(cs, (uchar*) old_word->pos,old_word->len,
|
||||
(uchar*) new_word->pos,new_word->len,0);
|
||||
cmp2= cmp ? 0 : (fabs(old_word->weight - new_word->weight) > 1.e-5);
|
||||
|
||||
|
@ -125,7 +125,7 @@ byte ft_simple_get_word(byte **, byte *, FT_WORD *);
|
||||
|
||||
typedef struct _st_ft_seg_iterator {
|
||||
uint num, len;
|
||||
MI_KEYSEG *seg;
|
||||
HA_KEYSEG *seg;
|
||||
const byte *rec, *pos;
|
||||
} FT_SEG_ITERATOR;
|
||||
|
||||
|
@ -32,7 +32,7 @@
|
||||
#define FT_SEGS 2
|
||||
#endif /* EVAL_RUN */
|
||||
|
||||
extern const MI_KEYSEG ft_keysegs[FT_SEGS];
|
||||
extern const HA_KEYSEG ft_keysegs[FT_SEGS];
|
||||
|
||||
int _mi_ft_cmp(MI_INFO *, uint, const byte *, const byte *);
|
||||
int _mi_ft_add(MI_INFO *, uint, byte *, const byte *, my_off_t);
|
||||
|
@ -583,7 +583,7 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
|
||||
goto err;
|
||||
}
|
||||
if ((*keys)++ &&
|
||||
(flag=_mi_key_cmp(keyinfo->seg,info->lastkey,key,key_length,
|
||||
(flag=ha_key_cmp(keyinfo->seg,info->lastkey,key,key_length,
|
||||
comp_flag, ¬_used)) >=0)
|
||||
{
|
||||
DBUG_DUMP("old",(byte*) info->lastkey, info->lastkey_length);
|
||||
@ -601,7 +601,7 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
|
||||
if (*keys != 1L) /* not first_key */
|
||||
{
|
||||
uint diff;
|
||||
_mi_key_cmp(keyinfo->seg,info->lastkey,key,USE_WHOLE_KEY,SEARCH_FIND,
|
||||
ha_key_cmp(keyinfo->seg,info->lastkey,key,USE_WHOLE_KEY,SEARCH_FIND,
|
||||
&diff);
|
||||
param->unique_count[diff-1]++;
|
||||
}
|
||||
@ -669,7 +669,7 @@ static ha_checksum calc_checksum(ha_rows count)
|
||||
static uint isam_key_length(MI_INFO *info, register MI_KEYDEF *keyinfo)
|
||||
{
|
||||
uint length;
|
||||
MI_KEYSEG *keyseg;
|
||||
HA_KEYSEG *keyseg;
|
||||
DBUG_ENTER("isam_key_length");
|
||||
|
||||
length= info->s->rec_reflength;
|
||||
@ -1771,7 +1771,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
|
||||
File new_file;
|
||||
MI_SORT_PARAM sort_param;
|
||||
MYISAM_SHARE *share=info->s;
|
||||
MI_KEYSEG *keyseg;
|
||||
HA_KEYSEG *keyseg;
|
||||
ulong *rec_per_key_part;
|
||||
char llbuff[22];
|
||||
SORT_INFO sort_info;
|
||||
@ -2136,7 +2136,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
|
||||
MI_SORT_PARAM *sort_param=0;
|
||||
MYISAM_SHARE *share=info->s;
|
||||
ulong *rec_per_key_part;
|
||||
MI_KEYSEG *keyseg;
|
||||
HA_KEYSEG *keyseg;
|
||||
char llbuff[22];
|
||||
IO_CACHE_SHARE io_share;
|
||||
SORT_INFO sort_info;
|
||||
@ -3052,7 +3052,7 @@ static int sort_key_cmp(MI_SORT_PARAM *sort_param, const void *a,
|
||||
const void *b)
|
||||
{
|
||||
uint not_used;
|
||||
return (_mi_key_cmp(sort_param->keyinfo->seg,*((uchar**) a),*((uchar**) b),
|
||||
return (ha_key_cmp(sort_param->keyinfo->seg, *((uchar**) a), *((uchar**) b),
|
||||
USE_WHOLE_KEY, SEARCH_SAME,¬_used));
|
||||
} /* sort_key_cmp */
|
||||
|
||||
@ -3067,8 +3067,8 @@ static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a)
|
||||
|
||||
if (sort_info->key_block->inited)
|
||||
{
|
||||
cmp=_mi_key_cmp(sort_param->keyinfo->seg, sort_info->key_block->lastkey,
|
||||
(uchar*) a, USE_WHOLE_KEY, SEARCH_FIND | SEARCH_UPDATE,
|
||||
cmp=ha_key_cmp(sort_param->keyinfo->seg,sort_info->key_block->lastkey,
|
||||
(uchar*) a, USE_WHOLE_KEY,SEARCH_FIND | SEARCH_UPDATE,
|
||||
&diff_pos);
|
||||
sort_param->unique[diff_pos-1]++;
|
||||
}
|
||||
@ -3085,8 +3085,11 @@ static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a)
|
||||
mi_check_print_warning(param,
|
||||
"Duplicate key for record at %10s against record at %10s",
|
||||
llstr(sort_info->info->lastpos,llbuff),
|
||||
llstr(get_record_for_key(sort_info->info, sort_param->keyinfo,
|
||||
sort_info->key_block->lastkey), llbuff2));
|
||||
llstr(get_record_for_key(sort_info->info,
|
||||
sort_param->keyinfo,
|
||||
sort_info->key_block->
|
||||
lastkey),
|
||||
llbuff2));
|
||||
param->testflag|=T_RETRY_WITHOUT_QUICK;
|
||||
if (sort_info->param->testflag & T_VERBOSE)
|
||||
_mi_print_key(stdout,sort_param->keyinfo->seg,(uchar*) a, USE_WHOLE_KEY);
|
||||
@ -3342,7 +3345,7 @@ int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename)
|
||||
MI_INFO info;
|
||||
MYISAM_SHARE share;
|
||||
MI_KEYDEF *keyinfo,*key,*key_end;
|
||||
MI_KEYSEG *keysegs,*keyseg;
|
||||
HA_KEYSEG *keysegs,*keyseg;
|
||||
MI_COLUMNDEF *recdef,*rec,*end;
|
||||
MI_UNIQUEDEF *uniquedef,*u_ptr,*u_end;
|
||||
MI_STATUS_INFO status_info;
|
||||
@ -3364,7 +3367,7 @@ int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename)
|
||||
(size_t) (sizeof(MI_KEYDEF)*share.base.keys));
|
||||
|
||||
key_parts= share.base.all_key_parts;
|
||||
if (!(keysegs=(MI_KEYSEG*) my_alloca(sizeof(MI_KEYSEG)*
|
||||
if (!(keysegs=(HA_KEYSEG*) my_alloca(sizeof(HA_KEYSEG)*
|
||||
(key_parts+share.base.keys))))
|
||||
{
|
||||
my_afree((gptr) keyinfo);
|
||||
@ -3400,7 +3403,7 @@ int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename)
|
||||
|
||||
/* Change the new key to point at the saved key segments */
|
||||
memcpy((byte*) keysegs,(byte*) share.keyparts,
|
||||
(size_t) (sizeof(MI_KEYSEG)*(key_parts+share.base.keys+
|
||||
(size_t) (sizeof(HA_KEYSEG)*(key_parts+share.base.keys+
|
||||
share.state.header.uniques)));
|
||||
keyseg=keysegs;
|
||||
for (key=keyinfo,key_end=keyinfo+share.base.keys; key != key_end ; key++)
|
||||
|
@ -17,6 +17,8 @@
|
||||
/* Create a MyISAM table */
|
||||
|
||||
#include "fulltext.h"
|
||||
#include "sp_defs.h"
|
||||
|
||||
#if defined(MSDOS) || defined(__WIN__)
|
||||
#ifdef __WIN__
|
||||
#include <fcntl.h>
|
||||
@ -51,7 +53,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
|
||||
MYISAM_SHARE share;
|
||||
MI_KEYDEF *keydef,tmp_keydef;
|
||||
MI_UNIQUEDEF *uniquedef;
|
||||
MI_KEYSEG *keyseg,tmp_keyseg;
|
||||
HA_KEYSEG *keyseg,tmp_keyseg;
|
||||
MI_COLUMNDEF *rec;
|
||||
ulong *rec_per_key_part;
|
||||
my_off_t key_root[MI_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
|
||||
@ -233,11 +235,42 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
|
||||
|
||||
for (i=0, keydef=keydefs ; i < keys ; i++ , keydef++)
|
||||
{
|
||||
share.state.key_root[i]= HA_OFFSET_ERROR;
|
||||
|
||||
share.state.key_root[i]= HA_OFFSET_ERROR;
|
||||
min_key_length_skipp=length=0;
|
||||
key_length=pointer;
|
||||
if (keydef->flag & HA_SPATIAL)
|
||||
{
|
||||
/* BAR TODO to support 3D and more dimensions in the future */
|
||||
uint sp_segs=SPDIMS*2;
|
||||
keydef->flag=HA_SPATIAL;
|
||||
|
||||
if (flags & HA_DONT_TOUCH_DATA)
|
||||
{
|
||||
/*
|
||||
called by myisamchk - i.e. table structure was taken from
|
||||
MYI file and SPATIAL key *do has* additional sp_segs keysegs.
|
||||
We'd better delete them now
|
||||
*/
|
||||
keydef->keysegs-=sp_segs;
|
||||
}
|
||||
|
||||
for (j=0, keyseg=keydef->seg ; (int) j < keydef->keysegs ;
|
||||
j++, keyseg++)
|
||||
{
|
||||
if (keyseg->type != HA_KEYTYPE_BINARY &&
|
||||
keyseg->type != HA_KEYTYPE_VARBINARY)
|
||||
{
|
||||
my_errno=HA_WRONG_CREATE_OPTION;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
keydef->keysegs+=sp_segs;
|
||||
key_length+=SPLEN*sp_segs;
|
||||
length++; /* At least one length byte */
|
||||
min_key_length_skipp+=SPLEN*2*SPDIMS;
|
||||
}
|
||||
else
|
||||
if (keydef->flag & HA_FULLTEXT) /* SerG */
|
||||
{
|
||||
keydef->flag=HA_FULLTEXT | HA_PACK_KEY | HA_VAR_LENGTH_KEY;
|
||||
@ -411,7 +444,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
|
||||
info_length=base_pos+(uint) (MI_BASE_INFO_SIZE+
|
||||
keys * MI_KEYDEF_SIZE+
|
||||
uniques * MI_UNIQUEDEF_SIZE +
|
||||
(key_segs + unique_key_parts)*MI_KEYSEG_SIZE+
|
||||
(key_segs + unique_key_parts)*HA_KEYSEG_SIZE+
|
||||
columns*MI_COLUMNDEF_SIZE);
|
||||
|
||||
bmove(share.state.header.file_version,(byte*) myisam_file_magic,4);
|
||||
@ -558,19 +591,35 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
|
||||
for (i=0 ; i < share.base.keys - uniques; i++)
|
||||
{
|
||||
uint ft_segs=(keydefs[i].flag & HA_FULLTEXT) ? FT_SEGS : 0;
|
||||
uint sp_segs=(keydefs[i].flag & HA_SPATIAL) ? 2*SPDIMS : 0;
|
||||
|
||||
if (mi_keydef_write(file, &keydefs[i]))
|
||||
goto err;
|
||||
for (j=0 ; j < keydefs[i].keysegs-ft_segs ; j++)
|
||||
for (j=0 ; j < keydefs[i].keysegs-ft_segs-sp_segs ; j++)
|
||||
if (mi_keyseg_write(file, &keydefs[i].seg[j]))
|
||||
goto err;
|
||||
for (j=0 ; j < ft_segs ; j++)
|
||||
{
|
||||
MI_KEYSEG seg=ft_keysegs[j];
|
||||
HA_KEYSEG seg=ft_keysegs[j];
|
||||
seg.language= keydefs[i].seg[0].language;
|
||||
if (mi_keyseg_write(file, &seg))
|
||||
goto err;
|
||||
}
|
||||
for (j=0 ; j < sp_segs ; j++)
|
||||
{
|
||||
HA_KEYSEG sseg;
|
||||
sseg.type=SPTYPE;
|
||||
sseg.language= 7;
|
||||
sseg.null_bit=0;
|
||||
sseg.bit_start=0;
|
||||
sseg.bit_end=0;
|
||||
sseg.length=SPLEN;
|
||||
sseg.null_pos=0;
|
||||
sseg.start=j*SPLEN;
|
||||
sseg.flag= HA_SWAP_KEY;
|
||||
if (mi_keyseg_write(file, &sseg))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
/* Create extra keys for unique definitions */
|
||||
offset=reclength-uniques*MI_UNIQUE_HASH_LENGTH;
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
/* Print a key in user understandable format */
|
||||
|
||||
void _mi_print_key(FILE *stream, register MI_KEYSEG *keyseg,
|
||||
void _mi_print_key(FILE *stream, register HA_KEYSEG *keyseg,
|
||||
const uchar *key, uint length)
|
||||
{
|
||||
int flag;
|
||||
|
@ -17,6 +17,8 @@
|
||||
/* Remove a row from a MyISAM table */
|
||||
|
||||
#include "fulltext.h"
|
||||
#include "rt_index.h"
|
||||
|
||||
#ifdef __WIN__
|
||||
#include <errno.h>
|
||||
#endif
|
||||
@ -79,8 +81,8 @@ int mi_delete(MI_INFO *info,const byte *record)
|
||||
}
|
||||
else
|
||||
{
|
||||
uint key_length=_mi_make_key(info,i,old_key,record,info->lastpos);
|
||||
if (_mi_ck_delete(info,i,old_key,key_length))
|
||||
if (info->s->keyinfo[i].ck_delete(info,i,old_key,
|
||||
_mi_make_key(info,i,old_key,record,info->lastpos)))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "myisamdef.h"
|
||||
#include "m_ctype.h"
|
||||
#include "sp_defs.h"
|
||||
#ifdef HAVE_IEEEFP_H
|
||||
#include <ieeefp.h>
|
||||
#endif
|
||||
@ -36,9 +37,17 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
|
||||
{
|
||||
byte *pos,*end;
|
||||
uchar *start;
|
||||
reg1 MI_KEYSEG *keyseg;
|
||||
reg1 HA_KEYSEG *keyseg;
|
||||
DBUG_ENTER("_mi_make_key");
|
||||
|
||||
if(info->s->keyinfo[keynr].flag & HA_SPATIAL)
|
||||
{
|
||||
/*
|
||||
TODO: nulls processing
|
||||
*/
|
||||
return sp_make_key(info,keynr,key,record,filepos);
|
||||
}
|
||||
|
||||
start=key;
|
||||
for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type ;keyseg++)
|
||||
{
|
||||
@ -144,7 +153,7 @@ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old,
|
||||
{
|
||||
uint length;
|
||||
uchar *pos,*end,*start_key=key;
|
||||
reg1 MI_KEYSEG *keyseg;
|
||||
reg1 HA_KEYSEG *keyseg;
|
||||
enum ha_base_keytype type;
|
||||
DBUG_ENTER("_mi_pack_key");
|
||||
|
||||
@ -243,7 +252,7 @@ static int _mi_put_key_in_record(register MI_INFO *info, uint keynr,
|
||||
{
|
||||
reg2 byte *key;
|
||||
byte *pos,*key_end;
|
||||
reg1 MI_KEYSEG *keyseg;
|
||||
reg1 HA_KEYSEG *keyseg;
|
||||
byte *blob_ptr;
|
||||
DBUG_ENTER("_mi_put_key_in_record");
|
||||
|
||||
@ -377,7 +386,7 @@ int _mi_read_key_record(MI_INFO *info, my_off_t filepos, byte *buf)
|
||||
void update_auto_increment(MI_INFO *info,const byte *record)
|
||||
{
|
||||
ulonglong value;
|
||||
MI_KEYSEG *keyseg=info->s->keyinfo[info->s->base.auto_key-1].seg;
|
||||
HA_KEYSEG *keyseg=info->s->keyinfo[info->s->base.auto_key-1].seg;
|
||||
const uchar *key=(uchar*) record+keyseg->start;
|
||||
|
||||
switch (keyseg->type) {
|
||||
|
@ -17,6 +17,8 @@
|
||||
/* open a isam-database */
|
||||
|
||||
#include "fulltext.h"
|
||||
#include "sp_defs.h"
|
||||
#include "rt_index.h"
|
||||
#include <m_ctype.h>
|
||||
|
||||
#if defined(MSDOS) || defined(__WIN__)
|
||||
@ -65,7 +67,7 @@ static MI_INFO *test_if_reopen(char *filename)
|
||||
|
||||
MI_INFO *mi_open(const char *name, int mode, uint open_flags)
|
||||
{
|
||||
int lock_error,kfile,open_mode,save_errno;
|
||||
int lock_error,kfile,open_mode,save_errno,have_rtree=0;
|
||||
uint i,j,len,errpos,head_length,base_pos,offset,info_length,keys,
|
||||
key_parts,unique_key_parts,tmp_length,uniques;
|
||||
char name_buff[FN_REFLEN], org_name [FN_REFLEN], index_name[FN_REFLEN],
|
||||
@ -254,7 +256,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
|
||||
&share->uniqueinfo,uniques*sizeof(MI_UNIQUEDEF),
|
||||
&share->keyparts,
|
||||
(key_parts+unique_key_parts+keys+uniques) *
|
||||
sizeof(MI_KEYSEG),
|
||||
sizeof(HA_KEYSEG),
|
||||
&share->rec,
|
||||
(share->base.fields+1)*sizeof(MI_COLUMNDEF),
|
||||
&share->blobs,sizeof(MI_BLOB)*share->base.blobs,
|
||||
@ -284,7 +286,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
|
||||
|
||||
share->blocksize=min(IO_SIZE,myisam_block_size);
|
||||
{
|
||||
MI_KEYSEG *pos=share->keyparts;
|
||||
HA_KEYSEG *pos=share->keyparts;
|
||||
for (i=0 ; i < keys ; i++)
|
||||
{
|
||||
disk_pos=mi_keydef_read(disk_pos, &share->keyinfo[i]);
|
||||
@ -293,6 +295,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
|
||||
for (j=0 ; j < share->keyinfo[i].keysegs; j++,pos++)
|
||||
{
|
||||
disk_pos=mi_keyseg_read(disk_pos, pos);
|
||||
|
||||
if (pos->type == HA_KEYTYPE_TEXT || pos->type == HA_KEYTYPE_VARTEXT)
|
||||
{
|
||||
if (!pos->language)
|
||||
@ -304,7 +307,12 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (share->keyinfo[i].flag & HA_FULLTEXT)
|
||||
if (share->keyinfo[i].flag & HA_SPATIAL)
|
||||
{
|
||||
uint sp_segs=SPDIMS*2;
|
||||
share->keyinfo[i].seg=pos-sp_segs;
|
||||
share->keyinfo[i].keysegs--;
|
||||
} else if (share->keyinfo[i].flag & HA_FULLTEXT)
|
||||
{
|
||||
share->keyinfo[i].seg=pos-FT_SEGS;
|
||||
share->fulltext_index=1;
|
||||
@ -342,7 +350,11 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
|
||||
}
|
||||
}
|
||||
for (i=0 ; i < keys ; i++)
|
||||
{
|
||||
if (share->keyinfo[i].key_alg == HA_KEY_ALG_RTREE)
|
||||
have_rtree=1;
|
||||
setup_key_functions(share->keyinfo+i);
|
||||
}
|
||||
|
||||
for (i=j=offset=0 ; i < share->base.fields ; i++)
|
||||
{
|
||||
@ -421,7 +433,8 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
|
||||
((share->options & (HA_OPTION_READ_ONLY_DATA | HA_OPTION_TMP_TABLE |
|
||||
HA_OPTION_COMPRESS_RECORD |
|
||||
HA_OPTION_TEMP_COMPRESS_RECORD)) ||
|
||||
(open_flags & HA_OPEN_TMP_TABLE)) ? 0 : 1;
|
||||
(open_flags & HA_OPEN_TMP_TABLE) ||
|
||||
have_rtree) ? 0 : 1;
|
||||
if (share->concurrent_insert)
|
||||
{
|
||||
share->lock.get_status=mi_get_status;
|
||||
@ -451,6 +464,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
|
||||
&info.blobs,sizeof(MI_BLOB)*share->base.blobs,
|
||||
&info.buff,(share->base.max_key_block_length*2+
|
||||
share->base.max_key_length),
|
||||
&info.rtree_recursion_state,have_rtree ? 1024 : 0,
|
||||
&info.lastkey,share->base.max_key_length*3+1,
|
||||
&info.filename,strlen(org_name)+1,
|
||||
NullS))
|
||||
@ -649,6 +663,16 @@ void mi_setup_functions(register MYISAM_SHARE *share)
|
||||
|
||||
static void setup_key_functions(register MI_KEYDEF *keyinfo)
|
||||
{
|
||||
if (keyinfo->key_alg == HA_KEY_ALG_RTREE)
|
||||
{
|
||||
keyinfo->ck_insert = rtree_insert;
|
||||
keyinfo->ck_delete = rtree_delete;
|
||||
}
|
||||
else
|
||||
{
|
||||
keyinfo->ck_insert = _mi_ck_write;
|
||||
keyinfo->ck_delete = _mi_ck_delete;
|
||||
}
|
||||
if (keyinfo->flag & HA_BINARY_PACK_KEY)
|
||||
{ /* Simple prefix compression */
|
||||
keyinfo->bin_search=_mi_seq_search;
|
||||
@ -661,7 +685,7 @@ static void setup_key_functions(register MI_KEYDEF *keyinfo)
|
||||
keyinfo->get_key= _mi_get_pack_key;
|
||||
if (keyinfo->seg[0].flag & HA_PACK_KEY)
|
||||
{ /* Prefix compression */
|
||||
if (!keyinfo->seg->charset || use_strcoll(keyinfo->seg->charset) ||
|
||||
if (!keyinfo->seg->charset || use_strnxfrm(keyinfo->seg->charset) ||
|
||||
(keyinfo->seg->flag & HA_NULL_PART))
|
||||
keyinfo->bin_search=_mi_seq_search;
|
||||
else
|
||||
@ -914,7 +938,7 @@ uint mi_keydef_write(File file, MI_KEYDEF *keydef)
|
||||
uchar *ptr=buff;
|
||||
|
||||
*ptr++ = (uchar) keydef->keysegs;
|
||||
*ptr++ = 0; /* not used */
|
||||
*ptr++ = keydef->key_alg; /* Rtree or Btree */
|
||||
mi_int2store(ptr,keydef->flag); ptr +=2;
|
||||
mi_int2store(ptr,keydef->block_length); ptr +=2;
|
||||
mi_int2store(ptr,keydef->keylength); ptr +=2;
|
||||
@ -926,7 +950,8 @@ uint mi_keydef_write(File file, MI_KEYDEF *keydef)
|
||||
char *mi_keydef_read(char *ptr, MI_KEYDEF *keydef)
|
||||
{
|
||||
keydef->keysegs = (uint) *ptr++;
|
||||
ptr++;
|
||||
keydef->key_alg = *ptr++; /* Rtree or Btree */
|
||||
|
||||
keydef->flag = mi_uint2korr(ptr); ptr +=2;
|
||||
keydef->block_length = mi_uint2korr(ptr); ptr +=2;
|
||||
keydef->keylength = mi_uint2korr(ptr); ptr +=2;
|
||||
@ -942,9 +967,9 @@ char *mi_keydef_read(char *ptr, MI_KEYDEF *keydef)
|
||||
** mi_keyseg
|
||||
***************************************************************************/
|
||||
|
||||
int mi_keyseg_write(File file, const MI_KEYSEG *keyseg)
|
||||
int mi_keyseg_write(File file, const HA_KEYSEG *keyseg)
|
||||
{
|
||||
uchar buff[MI_KEYSEG_SIZE];
|
||||
uchar buff[HA_KEYSEG_SIZE];
|
||||
uchar *ptr=buff;
|
||||
|
||||
*ptr++ =keyseg->type;
|
||||
@ -962,7 +987,7 @@ int mi_keyseg_write(File file, const MI_KEYSEG *keyseg)
|
||||
}
|
||||
|
||||
|
||||
char *mi_keyseg_read(char *ptr, MI_KEYSEG *keyseg)
|
||||
char *mi_keyseg_read(char *ptr, HA_KEYSEG *keyseg)
|
||||
{
|
||||
keyseg->type = *ptr++;
|
||||
keyseg->language = *ptr++;
|
||||
|
@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
#include "myisamdef.h"
|
||||
#include "rt_index.h"
|
||||
|
||||
static ha_rows _mi_record_pos(MI_INFO *info,const byte *key,uint key_len,
|
||||
enum ha_rkey_function search_flag);
|
||||
@ -39,7 +40,7 @@ ha_rows mi_records_in_range(MI_INFO *info, int inx, const byte *start_key,
|
||||
const byte *end_key, uint end_key_len,
|
||||
enum ha_rkey_function end_search_flag)
|
||||
{
|
||||
ha_rows start_pos,end_pos;
|
||||
ha_rows start_pos,end_pos,res;
|
||||
DBUG_ENTER("mi_records_in_range");
|
||||
|
||||
if ((inx = _mi_check_index(info,inx)) < 0)
|
||||
@ -50,20 +51,39 @@ ha_rows mi_records_in_range(MI_INFO *info, int inx, const byte *start_key,
|
||||
info->update&= (HA_STATE_CHANGED+HA_STATE_ROW_CHANGED);
|
||||
if (info->s->concurrent_insert)
|
||||
rw_rdlock(&info->s->key_root_lock[inx]);
|
||||
|
||||
switch(info->s->keyinfo[inx].key_alg){
|
||||
case HA_KEY_ALG_RTREE:
|
||||
{
|
||||
uchar * key_buff;
|
||||
if (start_key_len == 0)
|
||||
start_key_len=USE_WHOLE_KEY;
|
||||
key_buff=info->lastkey+info->s->base.max_key_length;
|
||||
start_key_len=_mi_pack_key(info,inx,key_buff,(uchar*) start_key,start_key_len);
|
||||
res=rtree_estimate(info, inx, key_buff, start_key_len, myisam_read_vec[start_search_flag]);
|
||||
res=res?res:1;
|
||||
break;
|
||||
}
|
||||
case HA_KEY_ALG_BTREE:
|
||||
default:
|
||||
start_pos= (start_key ?
|
||||
_mi_record_pos(info,start_key,start_key_len,start_search_flag) :
|
||||
(ha_rows) 0);
|
||||
end_pos= (end_key ?
|
||||
_mi_record_pos(info,end_key,end_key_len,end_search_flag) :
|
||||
info->state->records+ (ha_rows) 1);
|
||||
res=end_pos < start_pos ? (ha_rows) 0 :
|
||||
(end_pos == start_pos ? (ha_rows) 1 : end_pos-start_pos);
|
||||
if (start_pos == HA_POS_ERROR || end_pos == HA_POS_ERROR)
|
||||
res=HA_POS_ERROR;
|
||||
}
|
||||
|
||||
if (info->s->concurrent_insert)
|
||||
rw_unlock(&info->s->key_root_lock[inx]);
|
||||
fast_mi_writeinfo(info);
|
||||
if (start_pos == HA_POS_ERROR || end_pos == HA_POS_ERROR)
|
||||
DBUG_RETURN(HA_POS_ERROR);
|
||||
DBUG_PRINT("info",("records: %ld",(ulong) (end_pos-start_pos)));
|
||||
DBUG_RETURN(end_pos < start_pos ? (ha_rows) 0 :
|
||||
(end_pos == start_pos ? (ha_rows) 1 : end_pos-start_pos));
|
||||
|
||||
DBUG_PRINT("info",("records: %ld",(ulong) (res)));
|
||||
DBUG_RETURN(res);
|
||||
}
|
||||
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
/* Read record based on a key */
|
||||
|
||||
#include "myisamdef.h"
|
||||
|
||||
#include "rt_index.h"
|
||||
|
||||
/* Read a record using key */
|
||||
/* Ordinary search_flag is 0 ; Give error if no record with key */
|
||||
@ -36,6 +36,7 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
|
||||
DBUG_RETURN(my_errno);
|
||||
|
||||
info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
|
||||
info->last_key_func=search_flag;
|
||||
|
||||
if (!info->use_packed_key)
|
||||
{
|
||||
@ -65,6 +66,16 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
|
||||
if (!(nextflag & (SEARCH_FIND | SEARCH_NO_FIND | SEARCH_LAST)))
|
||||
use_key_length=USE_WHOLE_KEY;
|
||||
|
||||
switch(info->s->keyinfo[inx].key_alg){
|
||||
case HA_KEY_ALG_RTREE:
|
||||
if(rtree_find_first(info,inx,key_buff,use_key_length,nextflag)<0)
|
||||
{
|
||||
my_errno=HA_ERR_CRASHED;
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
case HA_KEY_ALG_BTREE:
|
||||
default:
|
||||
if (!_mi_search(info,info->s->keyinfo+inx,key_buff,use_key_length,
|
||||
myisam_read_vec[search_flag],info->s->state.key_root[inx]))
|
||||
{
|
||||
@ -83,6 +94,7 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (share->concurrent_insert)
|
||||
rw_unlock(&share->key_root_lock[inx]);
|
||||
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
#include "myisamdef.h"
|
||||
|
||||
#include "rt_index.h"
|
||||
|
||||
/*
|
||||
Read next row with the same key as previous read
|
||||
One may have done a write, update or delete of the previous row.
|
||||
@ -42,17 +44,43 @@ int mi_rnext(MI_INFO *info, byte *buf, int inx)
|
||||
changed=_mi_test_if_changed(info);
|
||||
if (!flag)
|
||||
{
|
||||
switch(info->s->keyinfo[inx].key_alg){
|
||||
case HA_KEY_ALG_RTREE:
|
||||
error=rtree_get_first(info,inx,info->lastkey_length);
|
||||
break;
|
||||
case HA_KEY_ALG_BTREE:
|
||||
default:
|
||||
error=_mi_search_first(info,info->s->keyinfo+inx,
|
||||
info->s->state.key_root[inx]);
|
||||
break;
|
||||
}
|
||||
else if (!changed)
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(info->s->keyinfo[inx].key_alg)
|
||||
{
|
||||
case HA_KEY_ALG_RTREE:
|
||||
/*
|
||||
Note that rtree doesn't support that the table
|
||||
may be changed since last call, so we do need
|
||||
to skip rows inserted by other threads like in btree
|
||||
*/
|
||||
error=rtree_get_next(info,inx,info->lastkey_length);
|
||||
break;
|
||||
|
||||
case HA_KEY_ALG_BTREE:
|
||||
default:
|
||||
if (!changed)
|
||||
{
|
||||
error=_mi_search_next(info,info->s->keyinfo+inx,info->lastkey,
|
||||
info->lastkey_length,flag,
|
||||
info->s->state.key_root[inx]);
|
||||
}
|
||||
else
|
||||
{
|
||||
error=_mi_search(info,info->s->keyinfo+inx,info->lastkey,
|
||||
USE_WHOLE_KEY,flag, info->s->state.key_root[inx]);
|
||||
|
||||
}
|
||||
if (!error)
|
||||
{
|
||||
while (info->lastpos >= info->state->data_file_length)
|
||||
@ -65,6 +93,8 @@ int mi_rnext(MI_INFO *info, byte *buf, int inx)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (info->s->concurrent_insert)
|
||||
rw_unlock(&info->s->key_root_lock[inx]);
|
||||
|
@ -15,6 +15,7 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include "myisamdef.h"
|
||||
#include "rt_index.h"
|
||||
|
||||
/*
|
||||
Read next row with the same key as previous read, but abort if
|
||||
@ -38,16 +39,28 @@ int mi_rnext_same(MI_INFO *info, byte *buf)
|
||||
if (fast_mi_readinfo(info))
|
||||
DBUG_RETURN(my_errno);
|
||||
|
||||
memcpy(info->lastkey2,info->lastkey,info->last_rkey_length);
|
||||
if (info->s->concurrent_insert)
|
||||
rw_rdlock(&info->s->key_root_lock[inx]);
|
||||
|
||||
switch(keyinfo->key_alg)
|
||||
{
|
||||
case HA_KEY_ALG_RTREE:
|
||||
if((error=rtree_find_next(info,inx,myisam_read_vec[info->last_key_func])))
|
||||
{
|
||||
/* FIXME: What to do?*/
|
||||
}
|
||||
break;
|
||||
case HA_KEY_ALG_BTREE:
|
||||
default:
|
||||
|
||||
memcpy(info->lastkey2,info->lastkey,info->last_rkey_length);
|
||||
for (;;)
|
||||
{
|
||||
if ((error=_mi_search_next(info,keyinfo,info->lastkey,
|
||||
info->lastkey_length,flag,
|
||||
info->s->state.key_root[inx])))
|
||||
break;
|
||||
if (_mi_key_cmp(keyinfo->seg,info->lastkey2,info->lastkey,
|
||||
if (ha_key_cmp(keyinfo->seg,info->lastkey2,info->lastkey,
|
||||
info->last_rkey_length, SEARCH_FIND, ¬_used))
|
||||
{
|
||||
error=1;
|
||||
@ -59,6 +72,7 @@ int mi_rnext_same(MI_INFO *info, byte *buf)
|
||||
if (info->lastpos < info->state->data_file_length)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (info->s->concurrent_insert)
|
||||
rw_unlock(&info->s->key_root_lock[inx]);
|
||||
/* Don't clear if database-changed */
|
||||
|
@ -133,7 +133,7 @@ int _mi_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
|
||||
&info->lastkey_length))
|
||||
goto err;
|
||||
if ((nextflag & SEARCH_LAST) &&
|
||||
_mi_key_cmp(keyinfo->seg, info->lastkey, key, key_len, SEARCH_FIND,
|
||||
ha_key_cmp(keyinfo->seg, info->lastkey, key, key_len, SEARCH_FIND,
|
||||
¬_used))
|
||||
{
|
||||
my_errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */
|
||||
@ -191,7 +191,7 @@ int _mi_bin_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
|
||||
while (start != end)
|
||||
{
|
||||
mid= (start+end)/2;
|
||||
if ((flag=_mi_key_cmp(keyinfo->seg,page+(uint) mid*totlength,key,key_len,
|
||||
if ((flag=ha_key_cmp(keyinfo->seg,page+(uint) mid*totlength,key,key_len,
|
||||
comp_flag,¬_used))
|
||||
>= 0)
|
||||
end=mid;
|
||||
@ -199,7 +199,7 @@ int _mi_bin_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
|
||||
start=mid+1;
|
||||
}
|
||||
if (mid != start)
|
||||
flag=_mi_key_cmp(keyinfo->seg,page+(uint) start*totlength,key,key_len,
|
||||
flag=ha_key_cmp(keyinfo->seg,page+(uint) start*totlength,key,key_len,
|
||||
comp_flag,¬_used);
|
||||
if (flag < 0)
|
||||
start++; /* point at next, bigger key */
|
||||
@ -239,7 +239,7 @@ int _mi_seq_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
|
||||
length,page,end));
|
||||
DBUG_RETURN(MI_FOUND_WRONG_KEY);
|
||||
}
|
||||
if ((flag=_mi_key_cmp(keyinfo->seg,t_buff,key,key_len,comp_flag,
|
||||
if ((flag=ha_key_cmp(keyinfo->seg,t_buff,key,key_len,comp_flag,
|
||||
¬_used)) >= 0)
|
||||
break;
|
||||
#ifdef EXTRA_DEBUG
|
||||
@ -262,7 +262,7 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
|
||||
{
|
||||
/* my_flag is raw comparison result to be changed according to
|
||||
SEARCH_NO_FIND,SEARCH_LAST and HA_REVERSE_SORT flags.
|
||||
flag is the value returned by _mi_key_cmp and as treated as final */
|
||||
flag is the value returned by ha_key_cmp and as treated as final */
|
||||
int flag=0, my_flag=-1;
|
||||
uint nod_flag, length, len, matched, cmplen, kseg_len;
|
||||
uint prefix_len,suffix_len;
|
||||
@ -351,7 +351,7 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
|
||||
DBUG_PRINT("loop",("page: '%.*s%.*s'",prefix_len,t_buff+seg_len_pack,suffix_len,vseg));
|
||||
{
|
||||
uchar *from=vseg+suffix_len;
|
||||
MI_KEYSEG *keyseg;
|
||||
HA_KEYSEG *keyseg;
|
||||
uint l;
|
||||
|
||||
for (keyseg=keyinfo->seg+1 ; keyseg->type ; keyseg++ )
|
||||
@ -423,7 +423,7 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
|
||||
else if (key_len_left>0)
|
||||
{
|
||||
uint not_used;
|
||||
if ((flag = _mi_key_cmp(keyinfo->seg+1,vseg,
|
||||
if ((flag = ha_key_cmp(keyinfo->seg+1,vseg,
|
||||
k,key_len_left,nextflag,¬_used)) >= 0)
|
||||
break;
|
||||
}
|
||||
@ -651,389 +651,6 @@ void _mi_dpointer(MI_INFO *info, uchar *buff, my_off_t pos)
|
||||
} /* _mi_dpointer */
|
||||
|
||||
|
||||
int _mi_compare_text(CHARSET_INFO *charset_info, uchar *a, uint a_length,
|
||||
uchar *b, uint b_length, my_bool part_key)
|
||||
{
|
||||
int flag;
|
||||
|
||||
#ifdef USE_STRCOLL
|
||||
if (use_strcoll(charset_info))
|
||||
{
|
||||
if (part_key && b_length < a_length)
|
||||
a_length=b_length;
|
||||
return my_strnncoll(charset_info, a, a_length, b, b_length);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
uint length= min(a_length,b_length);
|
||||
uchar *end= a+ length;
|
||||
uchar *sort_order=charset_info->sort_order;
|
||||
while (a < end)
|
||||
if ((flag= (int) sort_order[*a++] - (int) sort_order[*b++]))
|
||||
return flag;
|
||||
}
|
||||
if (part_key && b_length < a_length)
|
||||
return 0;
|
||||
return (int) (a_length-b_length);
|
||||
}
|
||||
|
||||
|
||||
static int compare_bin(uchar *a, uint a_length, uchar *b, uint b_length,
|
||||
my_bool part_key)
|
||||
{
|
||||
uint length= min(a_length,b_length);
|
||||
uchar *end= a+ length;
|
||||
int flag;
|
||||
|
||||
while (a < end)
|
||||
if ((flag= (int) *a++ - (int) *b++))
|
||||
return flag;
|
||||
if (part_key && b_length < a_length)
|
||||
return 0;
|
||||
return (int) (a_length-b_length);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Compare two keys
|
||||
** Returns <0, 0, >0 acording to which is bigger
|
||||
** Key_length specifies length of key to use. Number-keys can't
|
||||
** be splited
|
||||
** If flag <> SEARCH_FIND compare also position
|
||||
*/
|
||||
|
||||
#define FCMP(A,B) ((int) (A) - (int) (B))
|
||||
|
||||
int _mi_key_cmp(register MI_KEYSEG *keyseg, register uchar *a,
|
||||
register uchar *b, uint key_length, uint nextflag,
|
||||
uint *diff_pos)
|
||||
{
|
||||
int flag;
|
||||
int16 s_1,s_2;
|
||||
int32 l_1,l_2;
|
||||
uint32 u_1,u_2;
|
||||
float f_1,f_2;
|
||||
double d_1,d_2;
|
||||
uint next_key_length;
|
||||
|
||||
*diff_pos=0;
|
||||
for ( ; (int) key_length >0 ; key_length=next_key_length, keyseg++)
|
||||
{
|
||||
uchar *end;
|
||||
uint piks=! (keyseg->flag & HA_NO_SORT);
|
||||
(*diff_pos)++;
|
||||
|
||||
/* Handle NULL part */
|
||||
if (keyseg->null_bit)
|
||||
{
|
||||
key_length--;
|
||||
if (*a != *b && piks)
|
||||
{
|
||||
flag = (int) *a - (int) *b;
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
}
|
||||
b++;
|
||||
if (!*a++) /* If key was NULL */
|
||||
{
|
||||
if (nextflag == (SEARCH_FIND | SEARCH_UPDATE))
|
||||
nextflag=SEARCH_SAME; /* Allow duplicate keys */
|
||||
next_key_length=key_length;
|
||||
continue; /* To next key part */
|
||||
}
|
||||
}
|
||||
end= a+ min(keyseg->length,key_length);
|
||||
next_key_length=key_length-keyseg->length;
|
||||
|
||||
switch ((enum ha_base_keytype) keyseg->type) {
|
||||
case HA_KEYTYPE_TEXT: /* Ascii; Key is converted */
|
||||
if (keyseg->flag & HA_SPACE_PACK)
|
||||
{
|
||||
int a_length,b_length,pack_length;
|
||||
get_key_length(a_length,a);
|
||||
get_key_pack_length(b_length,pack_length,b);
|
||||
next_key_length=key_length-b_length-pack_length;
|
||||
|
||||
if (piks &&
|
||||
(flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length,
|
||||
(my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0))))
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a+=a_length;
|
||||
b+=b_length;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint length=(uint) (end-a), a_length=length, b_length=length;
|
||||
if (!(nextflag & SEARCH_PREFIX))
|
||||
{
|
||||
while (a_length && a[a_length-1] == ' ')
|
||||
a_length--;
|
||||
while (b_length && b[b_length-1] == ' ')
|
||||
b_length--;
|
||||
}
|
||||
if (piks &&
|
||||
(flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length,
|
||||
(my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0))))
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a=end;
|
||||
b+=length;
|
||||
}
|
||||
break;
|
||||
case HA_KEYTYPE_BINARY:
|
||||
if (keyseg->flag & HA_SPACE_PACK)
|
||||
{
|
||||
int a_length,b_length,pack_length;
|
||||
get_key_length(a_length,a);
|
||||
get_key_pack_length(b_length,pack_length,b);
|
||||
next_key_length=key_length-b_length-pack_length;
|
||||
|
||||
if (piks &&
|
||||
(flag=compare_bin(a,a_length,b,b_length,
|
||||
(my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0))))
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a+=a_length;
|
||||
b+=b_length;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint length=keyseg->length;
|
||||
if (piks &&
|
||||
(flag=compare_bin(a,length,b,length,
|
||||
(my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0))))
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a+=length;
|
||||
b+=length;
|
||||
}
|
||||
break;
|
||||
case HA_KEYTYPE_VARTEXT:
|
||||
{
|
||||
int a_length,b_length,pack_length;
|
||||
get_key_length(a_length,a);
|
||||
get_key_pack_length(b_length,pack_length,b);
|
||||
next_key_length=key_length-b_length-pack_length;
|
||||
|
||||
if (piks &&
|
||||
(flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length,
|
||||
(my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0))))
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a+=a_length;
|
||||
b+=b_length;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case HA_KEYTYPE_VARBINARY:
|
||||
{
|
||||
int a_length,b_length,pack_length;
|
||||
get_key_length(a_length,a);
|
||||
get_key_pack_length(b_length,pack_length,b);
|
||||
next_key_length=key_length-b_length-pack_length;
|
||||
|
||||
if (piks &&
|
||||
(flag=compare_bin(a,a_length,b,b_length,
|
||||
(my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0))))
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a+=a_length;
|
||||
b+=b_length;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case HA_KEYTYPE_INT8:
|
||||
{
|
||||
int i_1= (int) *((signed char*) a);
|
||||
int i_2= (int) *((signed char*) b);
|
||||
if (piks && (flag = CMP_NUM(i_1,i_2)))
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a= end;
|
||||
b++;
|
||||
break;
|
||||
}
|
||||
case HA_KEYTYPE_SHORT_INT:
|
||||
s_1= mi_sint2korr(a);
|
||||
s_2= mi_sint2korr(b);
|
||||
if (piks && (flag = CMP_NUM(s_1,s_2)))
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a= end;
|
||||
b+= 2; /* sizeof(short int); */
|
||||
break;
|
||||
case HA_KEYTYPE_USHORT_INT:
|
||||
{
|
||||
uint16 us_1,us_2;
|
||||
us_1= mi_sint2korr(a);
|
||||
us_2= mi_sint2korr(b);
|
||||
if (piks && (flag = CMP_NUM(us_1,us_2)))
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a= end;
|
||||
b+=2; /* sizeof(short int); */
|
||||
break;
|
||||
}
|
||||
case HA_KEYTYPE_LONG_INT:
|
||||
l_1= mi_sint4korr(a);
|
||||
l_2= mi_sint4korr(b);
|
||||
if (piks && (flag = CMP_NUM(l_1,l_2)))
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a= end;
|
||||
b+= 4; /* sizeof(long int); */
|
||||
break;
|
||||
case HA_KEYTYPE_ULONG_INT:
|
||||
u_1= mi_sint4korr(a);
|
||||
u_2= mi_sint4korr(b);
|
||||
if (piks && (flag = CMP_NUM(u_1,u_2)))
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a= end;
|
||||
b+= 4; /* sizeof(long int); */
|
||||
break;
|
||||
case HA_KEYTYPE_INT24:
|
||||
l_1=mi_sint3korr(a);
|
||||
l_2=mi_sint3korr(b);
|
||||
if (piks && (flag = CMP_NUM(l_1,l_2)))
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a= end;
|
||||
b+= 3;
|
||||
break;
|
||||
case HA_KEYTYPE_UINT24:
|
||||
l_1=mi_uint3korr(a);
|
||||
l_2=mi_uint3korr(b);
|
||||
if (piks && (flag = CMP_NUM(l_1,l_2)))
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a= end;
|
||||
b+= 3;
|
||||
break;
|
||||
case HA_KEYTYPE_FLOAT:
|
||||
mi_float4get(f_1,a);
|
||||
mi_float4get(f_2,b);
|
||||
if (piks && (flag = CMP_NUM(f_1,f_2)))
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a= end;
|
||||
b+= 4; /* sizeof(float); */
|
||||
break;
|
||||
case HA_KEYTYPE_DOUBLE:
|
||||
mi_float8get(d_1,a);
|
||||
mi_float8get(d_2,b);
|
||||
if (piks && (flag = CMP_NUM(d_1,d_2)))
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a= end;
|
||||
b+= 8; /* sizeof(double); */
|
||||
break;
|
||||
case HA_KEYTYPE_NUM: /* Numeric key */
|
||||
{
|
||||
int swap_flag= 0;
|
||||
int alength,blength;
|
||||
|
||||
if (keyseg->flag & HA_REVERSE_SORT)
|
||||
{
|
||||
swap(uchar*,a,b);
|
||||
swap_flag=1; /* Remember swap of a & b */
|
||||
end= a+ (int) (end-b);
|
||||
}
|
||||
if (keyseg->flag & HA_SPACE_PACK)
|
||||
{
|
||||
alength= *a++; blength= *b++;
|
||||
end=a+alength;
|
||||
next_key_length=key_length-blength-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
alength= (int) (end-a);
|
||||
blength=keyseg->length;
|
||||
/* remove pre space from keys */
|
||||
for ( ; alength && *a == ' ' ; a++, alength--) ;
|
||||
for ( ; blength && *b == ' ' ; b++, blength--) ;
|
||||
}
|
||||
if (piks)
|
||||
{
|
||||
if (*a == '-')
|
||||
{
|
||||
if (*b != '-')
|
||||
return -1;
|
||||
a++; b++;
|
||||
swap(uchar*,a,b);
|
||||
swap(int,alength,blength);
|
||||
swap_flag=1-swap_flag;
|
||||
alength--; blength--;
|
||||
end=a+alength;
|
||||
}
|
||||
else if (*b == '-')
|
||||
return 1;
|
||||
while (alength && (*a == '+' || *a == '0'))
|
||||
{
|
||||
a++; alength--;
|
||||
}
|
||||
while (blength && (*b == '+' || *b == '0'))
|
||||
{
|
||||
b++; blength--;
|
||||
}
|
||||
if (alength != blength)
|
||||
return (alength < blength) ? -1 : 1;
|
||||
while (a < end)
|
||||
if (*a++ != *b++)
|
||||
return ((int) a[-1] - (int) b[-1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
b+=(end-a);
|
||||
a=end;
|
||||
}
|
||||
|
||||
if (swap_flag) /* Restore pointers */
|
||||
swap(uchar*,a,b);
|
||||
break;
|
||||
}
|
||||
#ifdef HAVE_LONG_LONG
|
||||
case HA_KEYTYPE_LONGLONG:
|
||||
{
|
||||
longlong ll_a,ll_b;
|
||||
ll_a= mi_sint8korr(a);
|
||||
ll_b= mi_sint8korr(b);
|
||||
if (piks && (flag = CMP_NUM(ll_a,ll_b)))
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a= end;
|
||||
b+= 8;
|
||||
break;
|
||||
}
|
||||
case HA_KEYTYPE_ULONGLONG:
|
||||
{
|
||||
ulonglong ll_a,ll_b;
|
||||
ll_a= mi_uint8korr(a);
|
||||
ll_b= mi_uint8korr(b);
|
||||
if (piks && (flag = CMP_NUM(ll_a,ll_b)))
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a= end;
|
||||
b+= 8;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case HA_KEYTYPE_END: /* Ready */
|
||||
goto end; /* diff_pos is incremented */
|
||||
}
|
||||
}
|
||||
(*diff_pos)++;
|
||||
end:
|
||||
if (!(nextflag & SEARCH_FIND))
|
||||
{
|
||||
uint i;
|
||||
if (nextflag & (SEARCH_NO_FIND | SEARCH_LAST)) /* Find record after key */
|
||||
return (nextflag & (SEARCH_BIGGER | SEARCH_LAST)) ? -1 : 1;
|
||||
flag=0;
|
||||
for (i=keyseg->length ; i-- > 0 ; )
|
||||
{
|
||||
if (*a++ != *b++)
|
||||
{
|
||||
flag= FCMP(a[-1],b[-1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (nextflag & SEARCH_SAME)
|
||||
return (flag); /* read same */
|
||||
if (nextflag & SEARCH_BIGGER)
|
||||
return (flag <= 0 ? -1 : 1); /* read next */
|
||||
return (flag < 0 ? -1 : 1); /* read previous */
|
||||
}
|
||||
return 0;
|
||||
} /* _mi_key_cmp */
|
||||
|
||||
|
||||
/* Get key from key-block */
|
||||
/* page points at previous key; its advanced to point at next key */
|
||||
/* key should contain previous key */
|
||||
@ -1057,7 +674,7 @@ uint _mi_get_static_key(register MI_KEYDEF *keyinfo, uint nod_flag,
|
||||
uint _mi_get_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
|
||||
register uchar **page_pos, register uchar *key)
|
||||
{
|
||||
reg1 MI_KEYSEG *keyseg;
|
||||
reg1 HA_KEYSEG *keyseg;
|
||||
uchar *start_key,*page=*page_pos;
|
||||
uint length;
|
||||
|
||||
@ -1190,7 +807,7 @@ uint _mi_get_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
|
||||
uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
|
||||
register uchar **page_pos, register uchar *key)
|
||||
{
|
||||
reg1 MI_KEYSEG *keyseg;
|
||||
reg1 HA_KEYSEG *keyseg;
|
||||
uchar *start_key,*page=*page_pos,*page_end,*from,*from_end;
|
||||
uint length,tmp;
|
||||
|
||||
@ -1389,7 +1006,7 @@ uchar *_mi_get_last_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
|
||||
|
||||
uint _mi_keylength(MI_KEYDEF *keyinfo, register uchar *key)
|
||||
{
|
||||
reg1 MI_KEYSEG *keyseg;
|
||||
reg1 HA_KEYSEG *keyseg;
|
||||
uchar *start;
|
||||
|
||||
if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)))
|
||||
@ -1655,7 +1272,7 @@ _mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
|
||||
uchar *org_key, uchar *prev_key, uchar *key,
|
||||
MI_KEY_PARAM *s_temp)
|
||||
{
|
||||
reg1 MI_KEYSEG *keyseg;
|
||||
reg1 HA_KEYSEG *keyseg;
|
||||
int length;
|
||||
uint key_length,ref_length,org_key_length=0,
|
||||
length_pack,new_key_length,diff_flag,pack_marker;
|
||||
@ -1670,7 +1287,7 @@ _mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
|
||||
if ((keyinfo->flag & HA_FULLTEXT) &&
|
||||
((keyseg->type == HA_KEYTYPE_TEXT) ||
|
||||
(keyseg->type == HA_KEYTYPE_VARTEXT)) &&
|
||||
!use_strcoll(keyseg->charset))
|
||||
!use_strnxfrm(keyseg->charset))
|
||||
sort_order=keyseg->charset->sort_order;
|
||||
|
||||
/* diff flag contains how many bytes is needed to pack key */
|
||||
|
@ -51,7 +51,8 @@ uint NEAR myisam_read_vec[]=
|
||||
{
|
||||
SEARCH_FIND, SEARCH_FIND | SEARCH_BIGGER, SEARCH_FIND | SEARCH_SMALLER,
|
||||
SEARCH_NO_FIND | SEARCH_BIGGER, SEARCH_NO_FIND | SEARCH_SMALLER,
|
||||
SEARCH_FIND | SEARCH_PREFIX, SEARCH_LAST
|
||||
SEARCH_FIND | SEARCH_PREFIX, SEARCH_LAST,
|
||||
MBR_CONTAIN, MBR_INTERSECT, MBR_WITHIN, MBR_DISJOINT, MBR_EQUAL
|
||||
};
|
||||
|
||||
uint NEAR myisam_readnext_vec[]=
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user