From cef1d752497f81229788e56abaf7fa62c1ab31a9 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 8 Oct 2001 04:58:07 +0300 Subject: Updated manual about embedded version. Speed up column-completion in 'mysql' Don't use ISAM if HAVE_ISAM is not defined A lot of fixes for the embedded version. All libraries are now included in libmysqld.a Changed arguments to convert_dirname() to make it more general. Renamed files in the 'merge' directory to all use a common prefix. Don't compile both assembler and C functions on x86 BitKeeper/deleted/.del-mf_pack2.c~f07795bbcf57be7: Delete: mysys/mf_pack2.c Docs/manual.texi: Updated chapter about embedded version acinclude.m4: Fix for using BDB and InnoDB with embedded client/completion_hash.cc: Speed up memory allocation client/completion_hash.h: Speed up memory allocation client/mysql.cc: Speed up memory allocation client/mysqldump.c: Fix to use now convert_dirname client/mysqltest.c: Fixed memory allocation bugs. Added --basedir=#, --compress=#, --server-arg, --server-file. Fixes for embedded version Changed silent mode to -s instead of -q include/my_global.h: Update to use HAVE_ISAM include/my_sys.h: Cleanup of fn_format() include/mysql.h: Prepare FIELD struct for 4.1 include/mysql_embed.h: Don't use ISAM in embedded version innobase/include/srv0srv.h: Make InnoDB startup/shutdown silent in embedded version innobase/log/log0log.c: Make InnoDB startup/shutdown silent in embedded version innobase/srv/srv0srv.c: Make InnoDB startup/shutdown silent in embedded version innobase/srv/srv0start.c: Make InnoDB startup/shutdown silent in embedded version isam/isamlog.c: new convert_dirname libmysql/libmysql.c: Prepare for 4.1 libmysqld/Makefile.am: Changed to create one libmysqld.a file that includes all other libraries. libmysqld/examples/Makefile.am: Changed to use new libmysqld.a libmysqld/examples/test-run: Lot's of fixes to get new mysqltest with embedded MySQL to work. libmysqld/lib_sql.cc: Changed type of arguments for mysql_server_init() to make code more portable. libmysqld/libmysqld.c: Cleanup merge/Makefile.am: Rename to use common prefix. merge/mrg_close.c: Rename to use common prefix. merge/mrg_create.c: Rename to use common prefix. merge/mrg_def.h: Rename to use common prefix. merge/mrg_delete.c: Rename to use common prefix. merge/mrg_extra.c: Rename to use common prefix. merge/mrg_info.c: Rename to use common prefix. merge/mrg_locking.c: Rename to use common prefix. merge/mrg_open.c: Rename to use common prefix. merge/mrg_panic.c: Rename to use common prefix. merge/mrg_rrnd.c: Rename to use common prefix. merge/mrg_rsame.c: Rename to use common prefix. merge/mrg_static.c: Rename to use common prefix. merge/mrg_update.c: Rename to use common prefix. myisam/myisamlog.c: Use new convert_dirname myisammrg/Makefile.am: Renamed mymrgdef.h -> myrg_def.h myisammrg/myrg_close.c: Renamed mymrgdef.h -> myrg_def.h myisammrg/myrg_create.c: Renamed mymrgdef.h -> myrg_def.h myisammrg/myrg_def.h: Renamed mymrgdef.h -> myrg_def.h myisammrg/myrg_delete.c: Renamed mymrgdef.h -> myrg_def.h myisammrg/myrg_extra.c: Renamed mymrgdef.h -> myrg_def.h myisammrg/myrg_info.c: Renamed mymrgdef.h -> myrg_def.h myisammrg/myrg_locking.c: Renamed mymrgdef.h -> myrg_def.h myisammrg/myrg_open.c: Renamed mymrgdef.h -> myrg_def.h myisammrg/myrg_panic.c: Renamed mymrgdef.h -> myrg_def.h myisammrg/myrg_queue.c: Renamed mymrgdef.h -> myrg_def.h myisammrg/myrg_rfirst.c: Renamed mymrgdef.h -> myrg_def.h myisammrg/myrg_rkey.c: Renamed mymrgdef.h -> myrg_def.h myisammrg/myrg_rlast.c: Renamed mymrgdef.h -> myrg_def.h myisammrg/myrg_rnext.c: Renamed mymrgdef.h -> myrg_def.h myisammrg/myrg_rprev.c: Renamed mymrgdef.h -> myrg_def.h myisammrg/myrg_rrnd.c: Renamed mymrgdef.h -> myrg_def.h myisammrg/myrg_rsame.c: Renamed mymrgdef.h -> myrg_def.h myisammrg/myrg_static.c: Renamed mymrgdef.h -> myrg_def.h myisammrg/myrg_update.c: Renamed mymrgdef.h -> myrg_def.h myisammrg/myrg_write.c: Renamed mymrgdef.h -> myrg_def.h mysql-test/include/master-slave.inc: Use short filenames for sockets (portability problem on Mac OS X) mysql-test/mysql-test-run.sh: cleanup mysql-test/r/auto_increment.result: Cleanup of tests for embedded version mysql-test/r/func_system.result: Cleanup of tests for embedded version mysql-test/r/isam.result: Cleanup of tests for embedded version mysql-test/r/lock.result: Cleanup of tests for embedded version mysql-test/r/show_check.result: Cleanup of tests for embedded version mysql-test/t/auto_increment.test: Cleanup of tests for embedded version mysql-test/t/backup.test: Cleanup of tests for embedded version mysql-test/t/count_distinct2-master.opt: Cleanup of tests for embedded version mysql-test/t/count_distinct2.test: Cleanup of tests for embedded version mysql-test/t/create.test: Cleanup of tests for embedded version mysql-test/t/flush.test: Cleanup of tests for embedded version mysql-test/t/func_system.test: Cleanup of tests for embedded version mysql-test/t/isam.test: Cleanup of tests for embedded version mysql-test/t/kill.test: Cleanup of tests for embedded version mysql-test/t/lock.test: Cleanup of tests for embedded version mysql-test/t/order_fill_sortbuf-master.opt: Cleanup of tests for embedded version mysql-test/t/rpl000015.test: Use short filenames for sockets (portability problem on Mac OS X) mysql-test/t/rpl000016.test: Use short filenames for sockets (portability problem on Mac OS X) mysql-test/t/rpl000017.test: Use short filenames for sockets (portability problem on Mac OS X) mysql-test/t/rpl000018.test: Use short filenames for sockets (portability problem on Mac OS X) mysql-test/t/show_check.test: Move ISAM specific tests to isam.test mysql-test/t/status.test: Cleanup of tests for embedded version mysql-test/t/tablelock.test: Cleanup mysys/Makefile.am: Removed not used mf_pack2.c mysys/charset.c: new convert_dirname mysys/default.c: new convert_dirname mysys/mf_dirname.c: Changed convert_dirname() to be more general mysys/mf_format.c: Changed bit flags to fn_format() to defines. Added handling of relative filenames BitKeeper/etc/ignore: Added libmysqld/examples/test-gdbinit scripts/mysql_explain_log to the ignore list mysys/mf_pack.c: new convert_dirname mysys/mf_tempfile.c: new convert_dirname scripts/Makefile.am: Adde mysql_explain_log scripts/mysql_config.sh: Added support of --libmysqld-libs sql/Makefile.am: Fix to use 'innodb_system_libs' sql/ha_innobase.cc: Make InnoDB startup/shutdown silent in embedded version sql/ha_isam.cc: Added handling of HAVE_ISAM sql/ha_isammrg.cc: Added handling of HAVE_ISAM sql/ha_myisam.cc: Handle relative paths; Needed to support BACKUP TABLE in embedded version sql/ha_myisammrg.cc: Rename of filenames sql/handler.cc: Added handling of HAVE_ISAM sql/item_func.cc: Fix for ecc (Intel Compiler) sql/mysql_priv.h: Added global variable 'mysql_embedded' sql/mysqld.cc: Use HAVE_ISAM sql/sql_parse.cc: Use new convert_dirname sql/sql_select.cc: Fix for ecc (Intel Compiler) sql/sql_table.cc: Added handling of relative filenames strings/Makefile.am: Don't compile both assembler and C functions on x86 strings/bchange.c: cleanup --- .bzrignore | 2 + Docs/manual.texi | 205 ++++++++------- acinclude.m4 | 9 +- client/completion_hash.cc | 44 +--- client/completion_hash.h | 27 +- client/mysql.cc | 76 +++--- client/mysqldump.c | 9 +- client/mysqltest.c | 191 +++++++++++--- include/my_global.h | 3 +- include/my_sys.h | 16 +- include/mysql.h | 4 +- include/mysql_embed.h | 1 + innobase/include/srv0srv.h | 1 + innobase/log/log0log.c | 15 +- innobase/srv/srv0srv.c | 6 + innobase/srv/srv0start.c | 8 +- isam/isamlog.c | 6 +- libmysql/libmysql.c | 6 +- libmysqld/Makefile.am | 79 +++--- libmysqld/examples/Makefile.am | 15 +- libmysqld/examples/test-run | 58 +++-- libmysqld/lib_sql.cc | 10 +- libmysqld/libmysqld.c | 5 - merge/Makefile.am | 8 +- merge/_locking.c | 33 --- merge/close.c | 40 --- merge/create.c | 61 ----- merge/delete.c | 29 --- merge/extra.c | 46 ---- merge/info.c | 60 ----- merge/mrg_close.c | 40 +++ merge/mrg_create.c | 61 +++++ merge/mrg_def.h | 29 +++ merge/mrg_delete.c | 29 +++ merge/mrg_extra.c | 46 ++++ merge/mrg_info.c | 60 +++++ merge/mrg_locking.c | 33 +++ merge/mrg_open.c | 150 +++++++++++ merge/mrg_panic.c | 47 ++++ merge/mrg_rrnd.c | 110 +++++++++ merge/mrg_rsame.c | 36 +++ merge/mrg_static.c | 26 ++ merge/mrg_update.c | 31 +++ merge/mrgdef.h | 29 --- merge/open.c | 150 ----------- merge/panic.c | 47 ---- merge/rrnd.c | 110 --------- merge/rsame.c | 36 --- merge/static.c | 26 -- merge/update.c | 31 --- myisam/myisamlog.c | 6 +- myisammrg/Makefile.am | 2 +- myisammrg/mymrgdef.h | 31 --- myisammrg/myrg_close.c | 2 +- myisammrg/myrg_create.c | 2 +- myisammrg/myrg_def.h | 31 +++ myisammrg/myrg_delete.c | 2 +- myisammrg/myrg_extra.c | 2 +- myisammrg/myrg_info.c | 2 +- myisammrg/myrg_locking.c | 2 +- myisammrg/myrg_open.c | 2 +- myisammrg/myrg_panic.c | 2 +- myisammrg/myrg_queue.c | 2 +- myisammrg/myrg_rfirst.c | 2 +- myisammrg/myrg_rkey.c | 2 +- myisammrg/myrg_rlast.c | 2 +- myisammrg/myrg_rnext.c | 2 +- myisammrg/myrg_rprev.c | 2 +- myisammrg/myrg_rrnd.c | 2 +- myisammrg/myrg_rsame.c | 2 +- myisammrg/myrg_static.c | 2 +- myisammrg/myrg_update.c | 2 +- myisammrg/myrg_write.c | 2 +- mysql-test/include/master-slave.inc | 8 +- mysql-test/include/not_embedded.inc | 3 + mysql-test/mysql-test-run.sh | 6 +- mysql-test/r/auto_increment.result | 12 - mysql-test/r/func_system.result | 4 +- mysql-test/r/isam.result | 38 +++ mysql-test/r/lock.result | 4 - mysql-test/r/lock_multi.result | 4 + mysql-test/r/not_embedded.require | 2 + mysql-test/r/show_check.result | 26 -- mysql-test/t/auto_increment.test | 15 +- mysql-test/t/backup.test | 6 - mysql-test/t/count_distinct2-master.opt | 2 +- mysql-test/t/count_distinct2.test | 4 +- mysql-test/t/create.test | 4 - mysql-test/t/flush.test | 8 + mysql-test/t/func_system.test | 2 +- mysql-test/t/isam.test | 49 ++++ mysql-test/t/kill.test | 8 + mysql-test/t/lock.test | 42 ---- mysql-test/t/lock_multi.test | 49 ++++ mysql-test/t/order_fill_sortbuf-master.opt | 2 +- mysql-test/t/rpl000015.test | 4 +- mysql-test/t/rpl000016.test | 4 +- mysql-test/t/rpl000017.test | 4 +- mysql-test/t/rpl000018.test | 4 +- mysql-test/t/show_check.test | 15 +- mysql-test/t/status.test | 8 + mysql-test/t/tablelock.test | 7 +- mysys/Makefile.am | 2 +- mysys/charset.c | 2 +- mysys/default.c | 19 +- mysys/mf_dirname.c | 84 ++++--- mysys/mf_format.c | 75 +++--- mysys/mf_pack.c | 3 +- mysys/mf_pack2.c | 53 ---- mysys/mf_tempfile.c | 3 +- scripts/Makefile.am | 4 + scripts/mysql_config.sh | 13 +- scripts/mysql_explain_log.sh | 383 +++++++++++++++++++++++++++++ sql/Makefile.am | 4 +- sql/ha_innobase.cc | 16 +- sql/ha_isam.cc | 2 + sql/ha_isammrg.cc | 6 +- sql/ha_myisam.cc | 72 +++--- sql/ha_myisammrg.cc | 4 +- sql/handler.cc | 20 +- sql/item_func.cc | 3 +- sql/mysql_priv.h | 4 +- sql/mysqld.cc | 63 +++-- sql/sql_parse.cc | 6 +- sql/sql_select.cc | 8 +- sql/sql_table.cc | 10 +- strings/Makefile.am | 2 +- strings/bchange.c | 3 +- 128 files changed, 2057 insertions(+), 1459 deletions(-) delete mode 100644 merge/_locking.c delete mode 100644 merge/close.c delete mode 100644 merge/create.c delete mode 100644 merge/delete.c delete mode 100644 merge/extra.c delete mode 100644 merge/info.c create mode 100644 merge/mrg_close.c create mode 100644 merge/mrg_create.c create mode 100644 merge/mrg_def.h create mode 100644 merge/mrg_delete.c create mode 100644 merge/mrg_extra.c create mode 100644 merge/mrg_info.c create mode 100644 merge/mrg_locking.c create mode 100644 merge/mrg_open.c create mode 100644 merge/mrg_panic.c create mode 100644 merge/mrg_rrnd.c create mode 100644 merge/mrg_rsame.c create mode 100644 merge/mrg_static.c create mode 100644 merge/mrg_update.c delete mode 100644 merge/mrgdef.h delete mode 100644 merge/open.c delete mode 100644 merge/panic.c delete mode 100644 merge/rrnd.c delete mode 100644 merge/rsame.c delete mode 100644 merge/static.c delete mode 100644 merge/update.c delete mode 100644 myisammrg/mymrgdef.h create mode 100644 myisammrg/myrg_def.h create mode 100644 mysql-test/include/not_embedded.inc create mode 100644 mysql-test/r/lock_multi.result create mode 100644 mysql-test/r/not_embedded.require create mode 100644 mysql-test/t/lock_multi.test delete mode 100644 mysys/mf_pack2.c create mode 100644 scripts/mysql_explain_log.sh diff --git a/.bzrignore b/.bzrignore index bfb1710d33d..9d31cf7f7bf 100644 --- a/.bzrignore +++ b/.bzrignore @@ -412,3 +412,5 @@ libmysqld/examples/sql_string.cc libmysqld/examples/sql_string.h libmysqld/examples/mysql libmysqld/examples/mysqltest +libmysqld/examples/test-gdbinit +scripts/mysql_explain_log diff --git a/Docs/manual.texi b/Docs/manual.texi index cc4a33317fa..252ef455230 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -34122,10 +34122,12 @@ detect duplicated @code{UNIQUE} keys. @item By using @code{DATA DIRECTORY="directory"} or @code{INDEX DIRECTORY="directory"} you can specify where the table handler should -put it's table and index files. This only works for @code{MyISAM} tables -in @code{MySQL} 4.0, when you are not using the @code{--skip-symlink} -option. @xref{Symbolic links to tables}. +put it's table and index files. Note that the directory should be a full +path to the directory (not relative path). +This only works for @code{MyISAM} tables in @code{MySQL} 4.0, when you +are not using the @code{--skip-symlink} option. @xref{Symbolic links to +tables}. @end itemize @@ -41933,9 +41935,9 @@ You need to use the following functions when you want to create a threaded client. @xref{Threaded clients}. @menu -* my_init:: @code{my_init()} -* mysql_thread_init:: @code{mysql_thread_init()} -* mysql_thread_end:: @code{mysql_thread_end()} +* my_init:: @code{my_init()} +* mysql_thread_init:: @code{mysql_thread_init()} +* mysql_thread_end:: @code{mysql_thread_end()} @end menu @node my_init, mysql_thread_init, C Thread functions, C Thread functions @@ -42012,7 +42014,7 @@ a stand-alone server without modifying any code. @findex @code{mysql_server_init()} -@code{int mysql_server_init(int argc, const char **argv, const char **groups)} +@code{int mysql_server_init(int argc, char **argv, char **groups)} @subsubheading Description @@ -42032,8 +42034,8 @@ command-line arguments for the server. The @code{NULL}-terminated list of strings in @code{groups} selects which groups in the option files will be active. @xref{Option files}. For convenience, @code{groups} may be -@code{NULL}, in which case the @code{[server]} group will be -active. +@code{NULL}, in which case the @code{[server]} and @code{[emedded]} groups +will be active. @subsubheading Example @@ -42047,6 +42049,7 @@ static char *server_args[] = @{ "--set-variable=key_buffer_size=32M" @}; static char *server_groups[] = @{ + "embedded", "server", "this_program_SERVER", (char *)NULL @@ -42379,6 +42382,9 @@ included the thread libraries on the link/compile line. @menu * libmysqld overview:: Overview of the Embedded MySQL Server Library * libmysqld compiling:: Compiling Programs with @code{libmysqld} +* libmysqld restrictions:: +* libmysqld options:: +* libmysqld TODO:: * libmysqld example:: A Simple Embedded Server Example * libmysqld licensing:: Licensing the Embedded Server @end menu @@ -42391,21 +42397,100 @@ full-featured MySQL server inside the client application. The main benefits are increased speed and more simple management for embedded applications. -@node libmysqld compiling, libmysqld example, libmysqld overview, libmysqld -@subsubsection Compiling Programs with @code{libmysqld} +The API is identical for the embedded MySQL version and MySQL +client/server version. To change an old threaded application to use the +embedded library, on normall only have to add calls to the following +functions: + +@multitable @columnfractions .25 .7 +@item @code{mysql_server_init()} @tab Should be called before any other other MySQL function is called, preferably early in the @code{main()} function. +@item @code{mysql_server_end()} @tab Should be called before doing an exit of your program. +@item @code{mysql_thread_init()} @tab Should be called in all threads you are created that will access MySQL. +@item @code{mysql_thread_end()} @tab Should be called before calling @code{pthread_exit()} +@end multitable + +and link your code with @code{libmysqld.a} instead of @code{libmysqlclient.a}. + +The above @code{mysql_server_xxx} functions are also included in +@code{libmysqld.a} to allow you to change between the embedded and the +client/server version by just linking your application with the right +library. @xref{mysql_server_init}. -Currently, all of the support libraries must be explicitly -listed when linking with @code{-lmysqld}. In the future, -@code{mysql_config --libmysqld-libs} will name the libraries to -make this easier. Also, all of the supporting libraries will -probably be incorporated into libmysqld at some time to simplify -this even more. +@node libmysqld compiling, libmysqld restrictions, libmysqld overview, libmysqld +@subsubsection Compiling Programs with @code{libmysqld} + +When you link your program with @code{libmysqld}, you must also include +the system specific @code{pthread} libraries and some libraries that +@code{mysqld} uses. You can get the full list of libraries by executing +@code{mysql_config --libmysqld-libs}. + The correct flags for compiling and linking a threaded program must be used, even if you do not directly call any thread functions in your code. -@node libmysqld example, libmysqld licensing, libmysqld compiling, libmysqld +@node libmysqld restrictions, libmysqld options, libmysqld compiling, libmysqld +@subsubsection Restrictions when using the Embedded MySQL Server + +The embedded server has the following limitations: +(Some of these limitations can be changed by editing the @code{mysql_embed.h} +include files and recompiling MySQL) + +@itemize @bullet +@item +No support for ISAM tables. (This is mainly done to make the library smaller) +@item +No UDF functions. +@item +No stack trace on core dump. +@item +No internal RAID support. +@end itemize + +@node libmysqld options, libmysqld TODO, libmysqld restrictions, libmysqld +@subsubsection Using option files with the embedded server + +The following is the recommended way to use option files to make it easy +to switch between a client/server application and one where MySQL is +embedded. @xref{Option files}. + +@itemize @bullet +@item +Put common options in the @code{[server]} section. These will be read by +both MySQL versions. +@item +Put client/server specific options in the @code{[mysqld]} section. +@item +Put embedded MySQL specific options in the @code{[embedded]} section. +@item +Put application specific options in a @code{[ApplicationName_SERVER]} +section. +@end itemize + +@node libmysqld TODO, libmysqld example, libmysqld options, libmysqld +@subsubsection Things left to do in Embedded Server (TODO) + +@cindex TODO, embedded server + +@itemize @bullet +@item +Currently we only provide a static version of the @code{mysqld} library, +in the future we will also provide a shared library for this. +@item +We are going to provide options to leave out some parts of MySQL to make +the library smaller. +@item +There is still a lot of speed optimization to do. +@item +Errors are written to stderr. We will add an option to specify a +filename for these. +@item +We have to change InnoDB to not be so verbose when using in the embedded +version. +@end itemize + + +@node libmysqld example, libmysqld licensing, libmysqld TODO, libmysqld @subsubsection A Simple Embedded Server Example This example program and makefile should work without any @@ -42449,7 +42534,7 @@ main(int argc, char **argv) /* This must be called before any other mysql functions. * * You can use mysql_server_init(0, NULL, NULL), and it will - * initialize the server using groups = @{ "server", NULL @}. + * initialize the server using groups = @{ "server", "embedded", NULL @}. * * In your $HOME/.my.cnf file, you probably want to put: @@ -42647,79 +42732,9 @@ else LDLIBS += -lpthread endif +# Standard libraries. This example assumes MySQL is in /usr/local/mysql -# Standard libraries - -embed_libs := \ - $m/libmysqld/.libs/libmysqld.a \ - $m/isam/libnisam.a \ - $m/myisam/libmyisam.a \ - $m/heap/libheap.a \ - $m/merge/libmerge.a \ - $m/myisammrg/libmyisammrg.a - - -# Optionally-built libraries - -ifneq (,$(shell test -r $m/innobase/usr/libusr.a && echo "yes")) -embed_libs += \ - $m/innobase/usr/libusr.a \ - $m/innobase/odbc/libodbc.a \ - $m/innobase/srv/libsrv.a \ - $m/innobase/que/libque.a \ - $m/innobase/srv/libsrv.a \ - $m/innobase/dict/libdict.a \ - $m/innobase/ibuf/libibuf.a \ - $m/innobase/row/librow.a \ - $m/innobase/pars/libpars.a \ - $m/innobase/btr/libbtr.a \ - $m/innobase/trx/libtrx.a \ - $m/innobase/read/libread.a \ - $m/innobase/usr/libusr.a \ - $m/innobase/buf/libbuf.a \ - $m/innobase/ibuf/libibuf.a \ - $m/innobase/eval/libeval.a \ - $m/innobase/log/liblog.a \ - $m/innobase/fsp/libfsp.a \ - $m/innobase/fut/libfut.a \ - $m/innobase/fil/libfil.a \ - $m/innobase/lock/liblock.a \ - $m/innobase/mtr/libmtr.a \ - $m/innobase/page/libpage.a \ - $m/innobase/rem/librem.a \ - $m/innobase/thr/libthr.a \ - $m/innobase/com/libcom.a \ - $m/innobase/sync/libsync.a \ - $m/innobase/data/libdata.a \ - $m/innobase/mach/libmach.a \ - $m/innobase/ha/libha.a \ - $m/innobase/dyn/libdyn.a \ - $m/innobase/mem/libmem.a \ - $m/innobase/sync/libsync.a \ - $m/innobase/ut/libut.a \ - $m/innobase/os/libos.a \ - $m/innobase/ut/libut.a -endif - -ifneq (,$(shell test -r $m/bdb/build_unix/libdb.a && echo "yes")) -embed_libs += $m/bdb/build_unix/libdb.a -endif - - -# Support libraries - -embed_libs += \ - $m/mysys/libmysys.a \ - $m/strings/libmystrings.a \ - $m/dbug/libdbug.a \ - $m/regex/libregex.a - - -# Optionally built support libraries - -ifneq (,$(shell test -r $m/readline/libreadline.a && echo "yes")) -embed_libs += $m/readline/libreadline.a -endif +embed_libs := -L/usr/local/mysql/lib/mysql/ -lmysqld # This works for simple one-file test programs sources := $(wildcard *.c) @@ -47449,6 +47464,8 @@ Changed @code{WEEK(#,0)} to match the calender in the USA. @item Speed up all internal list handling. @item +Speed up @code{IS NULL()} and some other internal primitives. +@item Creating full text indexes are now much faster. @item Tree-like cache to speed up bulk inserts and @@ -47496,6 +47513,12 @@ Allow ANSI SQL syntax @code{X'hexadecimal-number'} Cleaned up global lock handling for @code{FLUSH TABLES WITH READ LOCK} @item Fixed problem with @code{DATETIME = constant} in @code{WHERE} optimization. +@item +Added options @code{--master-data} and @code{--no-autocommit} to +@code{mysqldump} (Thanks to Brian Aker for this). +@item +Added script @code{mysql_explain_log.sh} to distribution. +(Thanks to mobile.de). @end itemize diff --git a/acinclude.m4 b/acinclude.m4 index 6a37e40b844..e6f6ddd760d 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -854,6 +854,7 @@ dnl echo "DBG2: [$mode] bdb='$bdb'; incl='$bdb_includes'; lib='$bdb_libs'" no ) bdb_includes= bdb_libs= + bdb_libs_with_path= ;; supplied-two ) MYSQL_CHECK_INSTALLED_BDB([$bdb_includes], [$bdb_libs]) @@ -883,6 +884,7 @@ dnl echo "DBG2: [$mode] bdb='$bdb'; incl='$bdb_includes'; lib='$bdb_libs'" esac bdb_includes= bdb_libs= + bdb_libs_with_path= ;; esac ;; @@ -911,6 +913,7 @@ dnl echo "DBG3: [$mode] bdb='$bdb'; incl='$bdb_includes'; lib='$bdb_libs'" AC_SUBST(bdb_includes) AC_SUBST(bdb_libs) + AC_SUBST(bdb_libs_with_path) ]) AC_DEFUN([MYSQL_CHECK_INSTALLED_BDB], [ @@ -931,6 +934,7 @@ dnl echo ["MYSQL_CHECK_INSTALLED_BDB ($1) ($2)"] MYSQL_TOP_BUILDDIR([lib]) bdb_includes="-I$inc" bdb_libs="-L$lib -ldb" + bdb_libs_with_path="$lib/libdb.a" ]) LDFLAGS="$save_LDFLAGS" else @@ -959,6 +963,7 @@ dnl echo ["MYSQL_CHECK_BDB_DIR ($1)"] MYSQL_TOP_BUILDDIR([dir]) bdb_includes="-I$dir/build_unix" bdb_libs="-L$dir/build_unix -ldb" + bdb_libs_with_path="$dir/build_unix/libdb.a" else bdb_dir_ok="$bdb_version_ok" fi @@ -1070,6 +1075,7 @@ AC_DEFUN([MYSQL_CHECK_INNODB], [ AC_DEFINE(HAVE_INNOBASE_DB) have_innodb="yes" innodb_includes="-I../innobase/include" + innodb_system_libs="" dnl Some libs are listed several times, in order for gcc to sort out dnl circular references. innodb_libs="\ @@ -1110,7 +1116,7 @@ dnl circular references. \$(top_builddir)/innobase/os/libos.a\ \$(top_builddir)/innobase/ut/libut.a" - AC_CHECK_LIB(rt, aio_read, [innodb_libs="$innodb_libs -lrt"]) + AC_CHECK_LIB(rt, aio_read, [innodb_system_libs="-lrt"]) ;; * ) AC_MSG_RESULT([Not using Innodb]) @@ -1119,6 +1125,7 @@ dnl circular references. AC_SUBST(innodb_includes) AC_SUBST(innodb_libs) + AC_SUBST(innodb_system_libs) ]) dnl --------------------------------------------------------------------------- diff --git a/client/completion_hash.cc b/client/completion_hash.cc index 74ff3083197..26504fdf5fe 100644 --- a/client/completion_hash.cc +++ b/client/completion_hash.cc @@ -47,10 +47,12 @@ int completion_hash_init(HashTable *ht, uint nSize) ht->arBuckets = (Bucket **) my_malloc(nSize* sizeof(Bucket *), MYF(MY_ZEROFILL | MY_WME)); - if (!ht->arBuckets) { + if (!ht->arBuckets) + { ht->initialized = 0; return FAILURE; } + init_alloc_root(&ht->mem_root, 8192, 0); ht->pHashFunction = hashpjw; ht->nTableSize = nSize; ht->initialized = 1; @@ -78,8 +80,7 @@ int completion_hash_update(HashTable *ht, char *arKey, uint nKeyLength, if (!memcmp(p->arKey, arKey, nKeyLength)) { entry *n; - n = (entry *) my_malloc(sizeof(entry), - MYF(MY_WME)); + n = (entry *) alloc_root(&ht->mem_root,sizeof(entry)); n->pNext = p->pData; n->str = str; p->pData = n; @@ -91,20 +92,16 @@ int completion_hash_update(HashTable *ht, char *arKey, uint nKeyLength, p = p->pNext; } - p = (Bucket *) my_malloc(sizeof(Bucket),MYF(MY_WME)); - - if (!p) { + if (!(p = (Bucket *) alloc_root(&ht->mem_root, sizeof(Bucket)))) return FAILURE; - } + p->arKey = arKey; p->nKeyLength = nKeyLength; p->h = h; - p->pData = (entry*) my_malloc(sizeof(entry),MYF(MY_WME)); - if (!p->pData) { - my_free((gptr) p,MYF(0)); + if (!(p->pData = (entry*) alloc_root(&ht->mem_root, sizeof(entry)))) return FAILURE; - } + p->pData->str = str; p->pData->pNext = 0; p->count = 1; @@ -209,24 +206,7 @@ Bucket *find_longest_match(HashTable *ht, char *str, uint length, void completion_hash_clean(HashTable *ht) { - uint i; - entry *e, *t; - Bucket *b, *tmp; - - for (i=0; inTableSize; i++) { - b = ht->arBuckets[i]; - while (b) { - e = b->pData; - while (e) { - t = e; - e = e->pNext; - my_free((gptr) t,MYF(0)); - } - tmp = b; - b = b->pNext; - my_free((gptr) tmp,MYF(0)); - } - } + free_root(&ht->mem_root,MYF(0)); bzero((char*) ht->arBuckets,ht->nTableSize*sizeof(Bucket *)); } @@ -241,9 +221,7 @@ void completion_hash_free(HashTable *ht) void add_word(HashTable *ht,char *str) { int i; - int length= (int) strlen(str); - - for (i=1; i<=length; i++) { + char *pos=str; + for (i=1; *pos; i++, pos++) completion_hash_update(ht, str, i, str); - } } diff --git a/client/completion_hash.h b/client/completion_hash.h index 583a42bbbe5..45b1ef2f4c9 100644 --- a/client/completion_hash.h +++ b/client/completion_hash.h @@ -22,26 +22,29 @@ #define FAILURE 1 #include +#include typedef struct _entry { char *str; struct _entry *pNext; } entry; -typedef struct bucket { - uint h; /* Used for numeric indexing */ - char *arKey; - uint nKeyLength; - uint count; - entry *pData; - struct bucket *pNext; +typedef struct bucket +{ + uint h; /* Used for numeric indexing */ + char *arKey; + uint nKeyLength; + uint count; + entry *pData; + struct bucket *pNext; } Bucket; typedef struct hashtable { - uint nTableSize; - uint initialized; - uint(*pHashFunction) (char *arKey, uint nKeyLength); - Bucket **arBuckets; + uint nTableSize; + uint initialized; + MEM_ROOT mem_root; + uint(*pHashFunction) (char *arKey, uint nKeyLength); + Bucket **arBuckets; } HashTable; extern int completion_hash_init(HashTable *ht, uint nSize); @@ -54,4 +57,4 @@ extern void completion_hash_clean(HashTable *ht); extern int completion_hash_exists(HashTable *ht, char *arKey, uint nKeyLength); extern void completion_hash_free(HashTable *ht); -#endif /* _HASH_ */ +#endif /* _HASH_ */ diff --git a/client/mysql.cc b/client/mysql.cc index d56f64289c4..67b97e30ea5 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -137,6 +137,7 @@ static const char *xmlmeta[] = { static char default_pager[FN_REFLEN]; char pager[FN_REFLEN], outfile[FN_REFLEN]; FILE *PAGER, *OUTFILE; +MEM_ROOT hash_mem_root; #include "sslopt-vars.h" @@ -302,8 +303,9 @@ int main(int argc,char *argv[]) !(status.line_buff=batch_readline_init(max_allowed_packet+512,stdin))) exit(1); glob_buffer.realloc(512); - mysql_server_init(0, NULL, server_default_groups); - completion_hash_init(&ht,50); + mysql_server_init(0, NULL, (char**) server_default_groups); + completion_hash_init(&ht, 128); + init_alloc_root(&hash_mem_root, 16384, 0); bzero((char*) &mysql, sizeof(mysql)); if (sql_connect(current_host,current_db,current_user,opt_password, opt_silent)) @@ -387,6 +389,8 @@ sig_handler mysql_end(int sig) } batch_readline_end(status.line_buff); completion_hash_free(&ht); + free_root(&hash_mem_root,MYF(0)); + #endif if (sig >= 0) put_info(sig ? "Aborted" : "Bye", INFO_RESULT); @@ -1170,7 +1174,8 @@ static char *new_command_generator(char *text,int state) static void build_completion_hash(bool skip_rehash,bool write_info) { COMMANDS *cmd=commands; - static MYSQL_RES *databases=0,*tables=0,*fields; + MYSQL_RES *databases=0,*tables=0; + MYSQL_RES *fields; static char ***field_names= 0; MYSQL_ROW database_row,table_row; MYSQL_FIELD *sql_field; @@ -1181,16 +1186,11 @@ static void build_completion_hash(bool skip_rehash,bool write_info) if (status.batch || quick || !current_db) DBUG_VOID_RETURN; // We don't need completion in batches - completion_hash_clean(&ht); if (tables) { mysql_free_result(tables); tables=0; } - if (databases) { - mysql_free_result(databases); - databases=0; - } /* hash SQL commands */ while (cmd->name) { @@ -1200,16 +1200,28 @@ static void build_completion_hash(bool skip_rehash,bool write_info) if (skip_rehash) DBUG_VOID_RETURN; + /* Free old used memory */ + if (field_names) + field_names=0; + completion_hash_clean(&ht); + free_root(&hash_mem_root,MYF(0)); + /* hash MySQL functions (to be implemented) */ /* hash all database names */ - if (mysql_query(&mysql,"show databases")==0) { + if (mysql_query(&mysql,"show databases") == 0) + { if (!(databases = mysql_store_result(&mysql))) put_info(mysql_error(&mysql),INFO_INFO); else { while ((database_row=mysql_fetch_row(databases))) - add_word(&ht,(char*) database_row[0]); + { + char *str=strdup_root(&hash_mem_root, (char*) database_row[0]); + if (str) + add_word(&ht,(char*) str); + } + mysql_free_result(databases); } } /* hash all table names */ @@ -1227,23 +1239,13 @@ You can turn off this feature to get a quicker startup with -A\n\n"); } while ((table_row=mysql_fetch_row(tables))) { - if (!completion_hash_exists(&ht,(char*) table_row[0], - (uint) strlen((const char*) table_row[0]))) - add_word(&ht,table_row[0]); - } - } - } - /* FIXME: free() on small chunks is sloooowwww. glibc bug */ - if (field_names) { - for (i=0; field_names[i]; i++) { - for (j=0; field_names[i][j]; j++) { - my_free(field_names[i][j],MYF(0)); + char *str=strdup_root(&hash_mem_root, (char*) table_row[0]); + if (str && + !completion_hash_exists(&ht,(char*) str, (uint) strlen(str))) + add_word(&ht,str); } - my_free((gptr) field_names[i],MYF(0)); } - my_free((gptr) field_names,MYF(0)); } - field_names=0; /* hash all field names, both with the table prefix and without it */ if (!tables) /* no tables */ @@ -1251,36 +1253,37 @@ You can turn off this feature to get a quicker startup with -A\n\n"); DBUG_VOID_RETURN; } mysql_data_seek(tables,0); - field_names = (char ***) my_malloc(sizeof(char **) * - (uint) (mysql_num_rows(tables)+1), - MYF(MY_WME)); - if (!field_names) + if (!(field_names= (char ***) alloc_root(&hash_mem_root,sizeof(char **) * + (uint) (mysql_num_rows(tables)+1)))) + { + mysql_free_result(tables); DBUG_VOID_RETURN; + } i=0; while ((table_row=mysql_fetch_row(tables))) { if ((fields=mysql_list_fields(&mysql,(const char*) table_row[0],NullS))) { num_fields=mysql_num_fields(fields); - field_names[i] = (char **) my_malloc(sizeof(char *)*(num_fields*2+1), - MYF(0)); - if (!field_names[i]) - { - continue; - } + if (!(field_names[i] = (char **) alloc_root(&hash_mem_root, + sizeof(char *) * + (num_fields*2+1)))) + break; field_names[i][num_fields*2]='\0'; j=0; while ((sql_field=mysql_fetch_field(fields))) { sprintf(buf,"%s.%s",table_row[0],sql_field->name); - field_names[i][j] = my_strdup(buf,MYF(0)); + field_names[i][j] = strdup_root(&hash_mem_root,buf); add_word(&ht,field_names[i][j]); - field_names[i][num_fields+j] = my_strdup(sql_field->name,MYF(0)); + field_names[i][num_fields+j] = strdup_root(&hash_mem_root, + sql_field->name); if (!completion_hash_exists(&ht,field_names[i][num_fields+j], (uint) strlen(field_names[i][num_fields+j]))) add_word(&ht,field_names[i][num_fields+j]); j++; } + mysql_free_result(fields); } else { @@ -1290,6 +1293,7 @@ You can turn off this feature to get a quicker startup with -A\n\n"); } i++; } + mysql_free_result(tables); field_names[i]=0; // End pointer DBUG_VOID_RETURN; } diff --git a/client/mysqldump.c b/client/mysqldump.c index 284ef3a0adf..894286f8896 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -643,8 +643,7 @@ static uint getTableStructure(char *table, char* db) if (path) { char filename[FN_REFLEN], tmp_path[FN_REFLEN]; - strmov(tmp_path,path); - convert_dirname(tmp_path); + convert_dirname(tmp_path,path,NullS); sql_file= my_fopen(fn_format(filename, table, tmp_path, ".sql", 4), O_WRONLY, MYF(MY_WME)); if (!sql_file) /* If file couldn't be opened */ @@ -716,8 +715,7 @@ static uint getTableStructure(char *table, char* db) if (path) { char filename[FN_REFLEN], tmp_path[FN_REFLEN]; - strmov(tmp_path,path); - convert_dirname(tmp_path); + convert_dirname(tmp_path,path,NullS); sql_file= my_fopen(fn_format(filename, table, tmp_path, ".sql", 4), O_WRONLY, MYF(MY_WME)); if (!sql_file) /* If file couldn't be opened */ @@ -949,8 +947,7 @@ static void dumpTable(uint numFields, char *table) if (path) { char filename[FN_REFLEN], tmp_path[FN_REFLEN]; - strmov(tmp_path, path); - convert_dirname(tmp_path); + convert_dirname(tmp_path,path,NullS); my_load_path(tmp_path, tmp_path, NULL); fn_format(filename, table, tmp_path, ".txt", 4); my_delete(filename, MYF(0)); /* 'INTO OUTFILE' doesn't work, if diff --git a/client/mysqltest.c b/client/mysqltest.c index 3bab28d4e5c..f7b655e7de7 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -83,7 +83,7 @@ static int record = 0, verbose = 0, silent = 0, opt_sleep=0; static char *db = 0, *pass=0; -const char* user = 0, *host = 0, *unix_sock = 0; +const char* user = 0, *host = 0, *unix_sock = 0, *opt_basedir="./"; static int port = 0, opt_big_test=0, opt_compress=0; static uint start_lineno, *lineno; @@ -123,6 +123,8 @@ typedef struct int read_lines,current_line; } PARSER; +MYSQL_RES *last_result=0; + PARSER parser; MASTER_POS master_pos; int* block_ok; /* set to 0 if the current block should not be executed */ @@ -218,6 +220,7 @@ void reject_dump(const char* record_file, char* buf, int size); int close_connection(struct st_query* q); VAR* var_get(const char* var_name, const char** var_name_end, int raw); int eval_expr(VAR* v, const char* p, const char** p_end); +static int read_server_arguments(const char* name); /* Definitions for replace */ @@ -253,6 +256,19 @@ int mysql_rpl_parse_enabled(MYSQL* mysql __attribute__((unused))) { return 1; } int mysql_rpl_probe(MYSQL *mysql __attribute__((unused))) { return 1; } #endif +#define MAX_SERVER_ARGS 20 + +static int embedded_server_arg_count=0; +static char *embedded_server_args[MAX_SERVER_ARGS]; + +static const char *embedded_server_groups[] = { + "server", + "embedded", + "mysqltest_SERVER", + NullS +}; + + static void do_eval(DYNAMIC_STRING* query_eval, const char* query) { const char* p; @@ -296,6 +312,8 @@ static void do_eval(DYNAMIC_STRING* query_eval, const char* query) static void close_cons() { DBUG_ENTER("close_cons"); + if (last_result) + mysql_free_result(last_result); for (--next_con; next_con >= cons; --next_con) { mysql_close(&next_con->mysql); @@ -333,6 +351,8 @@ static void free_used_memory() if(var_reg[i].alloced_len) my_free(var_reg[i].str_val, MYF(MY_WME)); } + while (embedded_server_arg_count > 1) + my_free(embedded_server_args[--embedded_server_arg_count],MYF(0)); delete_dynamic(&q_lines); dynstr_free(&ds_res); my_free(pass,MYF(MY_ALLOW_ZERO_PTR)); @@ -358,6 +378,8 @@ static void die(const char* fmt, ...) exit(1); } +/* Note that we will get some memory leaks when calling this! */ + static void abort_not_supported_test() { DBUG_ENTER("abort_not_supported_test"); @@ -412,13 +434,22 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char* fname) DYNAMIC_STRING res_ds; DBUG_ENTER("dyn_string_cmp"); - if (!my_stat(fname, &stat_info, MYF(MY_WME))) + if (!test_if_hard_path(fname)) + { + strxmov(eval_file, opt_basedir, fname, NullS); + fn_format(eval_file, eval_file,"","",4); + } + else + fn_format(eval_file, fname,"","",4); + + if (!my_stat(eval_file, &stat_info, MYF(MY_WME))) die(NullS); if (!eval_result && stat_info.st_size != ds->length) DBUG_RETURN(2); if (!(tmp = (char*) my_malloc(stat_info.st_size + 1, MYF(MY_WME)))) die(NullS); - if ((fd = my_open(fname, O_RDONLY, MYF(MY_WME))) < 0) + + if ((fd = my_open(eval_file, O_RDONLY, MYF(MY_WME))) < 0) die(NullS); if (my_read(fd, (byte*)tmp, stat_info.st_size, MYF(MY_WME|MY_NABP))) die(NullS); @@ -567,9 +598,17 @@ int var_set(char* var_name, char* var_name_end, char* var_val, int open_file(const char* name) { + char buff[FN_REFLEN]; + if (!test_if_hard_path(name)) + { + strxmov(buff, opt_basedir, name, NullS); + name=buff; + } + fn_format(buff,name,"","",4); + if (*cur_file && cur_file == file_stack_end) die("Source directives are nesting too deep"); - if (!(*(cur_file+1) = my_fopen(name, O_RDONLY, MYF(MY_WME)))) + if (!(*(cur_file+1) = my_fopen(buff, O_RDONLY, MYF(MY_WME)))) die(NullS); cur_file++; *++lineno=1; @@ -740,14 +779,13 @@ int do_sync_with_master(struct st_query* q) die("At line %u: failed in %s: %d: %s", start_lineno, query_buf, mysql_errno(mysql), mysql_error(mysql)); - if(!(res = mysql_store_result(mysql))) + if(!(last_result = res = mysql_store_result(mysql))) die("line %u: mysql_store_result() retuned NULL", start_lineno); if(!(row = mysql_fetch_row(res))) die("line %u: empty result in %s", start_lineno, query_buf); if(!row[0]) die("Error on slave while syncing with master"); - mysql_free_result(res); - + mysql_free_result(res); last_result=0; if(rpl_parse) mysql_enable_rpl_parse(mysql); @@ -768,13 +806,13 @@ int do_save_master_pos() die("At line %u: failed in show master status: %d: %s", start_lineno, mysql_errno(mysql), mysql_error(mysql)); - if(!(res = mysql_store_result(mysql))) + if(!(last_result =res = mysql_store_result(mysql))) die("line %u: mysql_store_result() retuned NULL", start_lineno); if(!(row = mysql_fetch_row(res))) die("line %u: empty result in show master status", start_lineno); strncpy(master_pos.file, row[0], sizeof(master_pos.file)); master_pos.pos = strtoul(row[1], (char**) 0, 10); - mysql_free_result(res); + mysql_free_result(res); last_result=0; if(rpl_parse) mysql_enable_rpl_parse(mysql); @@ -1504,16 +1542,19 @@ struct option long_options[] = { {"debug", optional_argument, 0, '#'}, {"database", required_argument, 0, 'D'}, + {"basedir", required_argument, 0, 'b'}, {"big-test", no_argument, 0, 'B'}, {"compress", no_argument, 0, 'C'}, {"help", no_argument, 0, '?'}, {"host", required_argument, 0, 'h'}, {"password", optional_argument, 0, 'p'}, {"port", required_argument, 0, 'P'}, - {"quiet", no_argument, 0, 'q'}, + {"quiet", no_argument, 0, 's'}, {"record", no_argument, 0, 'r'}, {"result-file", required_argument, 0, 'R'}, - {"silent", no_argument, 0, 'q'}, + {"server-arg", required_argument, 0, 'A'}, + {"server-file", required_argument, 0, 'F'}, + {"silent", no_argument, 0, 's'}, {"sleep", required_argument, 0, 'T'}, {"socket", required_argument, 0, 'S'}, {"test-file", required_argument, 0, 'x'}, @@ -1549,10 +1590,14 @@ void usage() -u, --user=... User for login.\n\ -p[password], --password[=...]\n\ Password to use when connecting to server.\n\ + -b, --basedir=... Basedir for tests\n\ -B, --big-test Define BIG_TEST to 1\n\ -C, --compress Use the compressed server/client protocol\n\ -D, --database=... Database to use.\n\ -P, --port=... Port number to use for connection.\n\ + --server-arg=... Send enbedded server this as a paramenter\n\ + --server-file=... Read embedded server arguments from file\n\ + -s, --silent, --quiet Suppress all normal output.\n\ -S, --socket=... Socket file to use for connection.\n\ -t, --tmpdir=... Temporary directory where sockets are put\n\ -T, --sleep=# Sleep always this many seconds on sleep commands\n\ @@ -1560,7 +1605,6 @@ void usage() -R, --result-file=... Read/Store result from/in this file.\n\ -x, --test-file=... Read test from/in this file (default stdin).\n\ -v, --verbose Write more.\n\ - -q, --quiet, --silent Suppress all normal output.\n\ -V, --version Output version information and exit.\n\ --no-defaults Don't read default options from any options file.\n\n"); } @@ -1573,12 +1617,12 @@ int parse_args(int argc, char **argv) load_defaults("my",load_default_groups,&argc,&argv); default_argv= argv; - while ((c = getopt_long(argc, argv, "h:p::u:BCP:D:S:R:x:t:T:#:?rvVq", + while ((c = getopt_long(argc, argv, "A:h:p::u:b:BCF:P:D:S:R:x:t:T:#:?rvVs", long_options, &option_index)) != EOF) { switch(c) { case '#': - DBUG_PUSH(optarg ? optarg : "d:t:O,/tmp/mysqltest.trace"); + DBUG_PUSH(optarg ? optarg : "d:t:i:O,/tmp/mysqltest.trace"); break; case 'v': verbose = 1; @@ -1593,9 +1637,18 @@ int parse_args(int argc, char **argv) result_file = optarg; break; case 'x': - if (!(*++cur_file = my_fopen(optarg, O_RDONLY, MYF(MY_WME)))) + { + char buff[FN_REFLEN]; + if (!test_if_hard_path(optarg)) + { + strxmov(buff, opt_basedir, optarg, NullS); + optarg=buff; + } + fn_format(buff,optarg,"","",4); + if (!(*++cur_file = my_fopen(buff, O_RDONLY, MYF(MY_WME)))) die("Could not open %s: errno = %d", optarg, errno); break; + } case 'p': if (optarg) { @@ -1606,6 +1659,9 @@ int parse_args(int argc, char **argv) else tty_password=1; break; + case 'b': + opt_basedir= optarg; + break; case 'B': opt_big_test=1; break; @@ -1624,7 +1680,7 @@ int parse_args(int argc, char **argv) case 'h': host = optarg; break; - case 'q': + case 's': silent = 1; break; case 't': @@ -1633,6 +1689,24 @@ int parse_args(int argc, char **argv) case 'T': opt_sleep=atoi(optarg); break; + case 'A': + if (!embedded_server_arg_count) + { + embedded_server_arg_count=1; + embedded_server_args[0]= (char*) ""; + } + embedded_server_args[embedded_server_arg_count++]= + my_strdup(optarg,MYF(MY_FAE)); + if (embedded_server_arg_count == MAX_SERVER_ARGS || + !embedded_server_args[embedded_server_arg_count-1]) + { + die("Can't use server argument"); + } + break; + case 'F': + if (read_server_arguments(optarg)) + die(NullS); + break; case 'V': print_version(); exit(0); @@ -1640,6 +1714,7 @@ int parse_args(int argc, char **argv) usage(); exit(1); /* Unknown option */ default: + fprintf(stderr,"Unknown option '%c'\n",c); usage(); exit(1); } @@ -1672,9 +1747,17 @@ char* safe_str_append(char* buf, const char* str, int size) void str_to_file(const char* fname, char* str, int size) { int fd; - if ((fd = my_open(fname, O_WRONLY | O_CREAT | O_TRUNC, + char buff[FN_REFLEN]; + if (!test_if_hard_path(fname)) + { + strxmov(buff, opt_basedir, fname, NullS); + fname=buff; + } + fn_format(buff,fname,"","",4); + + if ((fd = my_open(buff, O_WRONLY | O_CREAT | O_TRUNC, MYF(MY_WME | MY_FFNF))) < 0) - die("Could not open %s: errno = %d", fname, errno); + die("Could not open %s: errno = %d", buff, errno); if (my_write(fd, (byte*)str, size, MYF(MY_WME|MY_FNABP))) die("write failed"); my_close(fd, MYF(0)); @@ -1731,14 +1814,18 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags) if ((flags & QUERY_SEND) && mysql_send_query(mysql, query, query_len)) die("At line %u: unable to send query '%s'", start_lineno, query); - if(!(flags & QUERY_REAP)) - return 0; + if (!(flags & QUERY_REAP)) + DBUG_RETURN(0); + if (mysql_read_query_result(mysql) || - (!(res = mysql_store_result(mysql)) && mysql_field_count(mysql))) + (!(last_result = res = mysql_store_result(mysql)) && + mysql_field_count(mysql))) { if (q->require_file) + { abort_not_supported_test(); + } if (q->abort_on_error) die("At line %u: query '%s' failed: %d: %s", start_lineno, query, mysql_errno(mysql), mysql_error(mysql)); @@ -1839,6 +1926,7 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags) end: if (res) mysql_free_result(res); + last_result=0; if (ds == &ds_tmp) dynstr_free(&ds_tmp); if(q->type == Q_EVAL) @@ -1935,17 +2023,6 @@ static void init_var_hash() var_from_env("BIG_TEST", opt_big_test ? "1" : "0"); } -static const char *embedded_server_args[] = { - "", /* XXX: argv[0] is program name - we should fix the API */ - "--datadir=.", - "--language=/usr/local/mysql/share/mysql/english", - "--skip-innodb", - NullS -}; -static const char *embedded_server_groups[] = { - "mysql-test-server", - NullS -}; int main(int argc, char** argv) { @@ -1981,8 +2058,9 @@ int main(int argc, char** argv) *block_ok = 1; init_dynamic_string(&ds_res, "", 0, 65536); parse_args(argc, argv); - if (mysql_server_init(sizeof(embedded_server_args) / sizeof(char *) - 1, - embedded_server_args, embedded_server_groups)) + if (mysql_server_init(embedded_server_arg_count, + embedded_server_args, + (char**) embedded_server_groups)) die("Can't initialize MySQL server"); init_var_hash(); if (cur_file == file_stack) @@ -2130,6 +2208,51 @@ int main(int argc, char** argv) } } +/* + Read arguments for embedded server and put them into + embedded_server_args_count and embedded_server_args[] +*/ + + +static int read_server_arguments(const char* name) +{ + char argument[1024],buff[FN_REFLEN], *str=0; + FILE *file; + + if (!test_if_hard_path(name)) + { + strxmov(buff, opt_basedir, name, NullS); + name=buff; + } + fn_format(buff,name,"","",4); + + if (!embedded_server_arg_count) + { + embedded_server_arg_count=1; + embedded_server_args[0]= (char*) ""; /* Progname */ + } + if (!(file=my_fopen(buff, O_RDONLY | O_BINARY, MYF(MY_WME)))) + return 1; + while (embedded_server_arg_count < MAX_SERVER_ARGS && + (str=fgets(argument,sizeof(argument), file))) + { + *(strend(str)-1)=0; /* Remove end newline */ + if (!(embedded_server_args[embedded_server_arg_count]= + (char*) my_strdup(str,MYF(MY_WME)))) + { + my_fclose(file,MYF(0)); + return 1; + } + embedded_server_arg_count++; + } + my_fclose(file,MYF(0)); + if (str) + { + fprintf(stderr,"Too many arguments in option file: %s\n",name); + return 1; + } + return 0; +} /**************************************************************************** * Handle replacement of strings diff --git a/include/my_global.h b/include/my_global.h index e8527e83e28..50a7b7bcd40 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -453,8 +453,7 @@ typedef SOCKET_SIZE_TYPE size_socket; /* Some things that this system doesn't have */ #define ONLY_OWN_DATABASES /* We are using only databases by monty */ -#define NO_PISAM /* Not needed anymore */ -#define NO_MISAM /* Not needed anymore */ +#define HAVE_ISAM /* TO BE DELETED */ #define NO_HASH /* Not needed anymore */ #ifdef __WIN__ #define NO_DIR_LIBRARY /* Not standar dir-library */ diff --git a/include/my_sys.h b/include/my_sys.h index 0ab39f1146b..77c6c71fab9 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -90,6 +90,16 @@ extern int NEAR my_errno; /* Last error in mysys */ #define ME_COLOUR2 ((2 << ME_HIGHBYTE)) #define ME_COLOUR3 ((3 << ME_HIGHBYTE)) + /* Bits in last argument to fn_format */ +#define MY_REPLACE_DIR 1 /* replace dir in name with 'dir' */ +#define MY_REPLACE_EXT 2 /* replace extension with 'ext' */ +#define MY_UNPACK_FILENAME 4 /* Unpack name (~ -> home) */ +#define MY_PACK_FILENAME 8 /* Pack name (home -> ~) */ +#define MY_RESOLVE_SYMLINKS 16 /* Resolve all symbolic links */ +#define MY_RETURN_REAL_PATH 32 /* return full path for file */ +#define MY_SAFE_PATH 64 /* Return NULL if too long path */ +#define MY_RELATIVE_PATH 128 /* name is relative to 'dir' */ + /* My seek flags */ #define MY_SEEK_SET 0 #define MY_SEEK_CUR 1 @@ -469,12 +479,12 @@ 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)) extern int test_if_hard_path(const char *dir_name); -extern char *convert_dirname(my_string name); +extern char *convert_dirname(char *to, const char *from, const char *from_end); extern void to_unix_path(my_string name); extern my_string fn_ext(const char *name); extern my_string fn_same(my_string toname,const char *name,int flag); -extern my_string fn_format(my_string to,const char *name,const char *dsk, - const char *form,int flag); +extern my_string fn_format(my_string to,const char *name,const char *dir, + const char *form, uint flag); extern size_s strlength(const char *str); extern void pack_dirname(my_string to,const char *from); extern uint unpack_dirname(my_string to,const char *from); diff --git a/include/mysql.h b/include/mysql.h index 12c55edd6f5..f2901671749 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -71,6 +71,8 @@ extern char *mysql_unix_port; typedef struct st_mysql_field { char *name; /* Name of column */ char *table; /* Table of column if column was a field */ + 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 */ unsigned long max_length; /* Max width of selected set */ @@ -227,7 +229,7 @@ typedef struct st_mysql_res { /* Set up and bring down the server; to ensure that applications will * work when linked against either the standard client library or the * embedded server library, these functions should be called. */ -int mysql_server_init(int argc, const char **argv, const char **groups); +int mysql_server_init(int argc, char **argv, char **groups); void mysql_server_end(void); /* Set up and bring down a thread; these function should be called diff --git a/include/mysql_embed.h b/include/mysql_embed.h index 77f6f3fa32c..d381fa8aefc 100644 --- a/include/mysql_embed.h +++ b/include/mysql_embed.h @@ -24,6 +24,7 @@ #undef HAVE_DLOPEN /* No udf functions */ #undef HAVE_OPENSSL #undef HAVE_VIO +#undef HAVE_ISAM #define DONT_USE_RAID #endif /* EMBEDDED_LIBRARY */ diff --git a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h index 3f014adb76c..b77d7d5436a 100644 --- a/innobase/include/srv0srv.h +++ b/innobase/include/srv0srv.h @@ -70,6 +70,7 @@ extern ulint srv_n_rows_read; extern ibool srv_print_innodb_monitor; extern ibool srv_print_innodb_lock_monitor; extern ibool srv_print_innodb_tablespace_monitor; +extern ibool srv_print_verbose_log; extern ulint srv_n_spin_wait_rounds; extern ulint srv_spin_wait_delay; diff --git a/innobase/log/log0log.c b/innobase/log/log0log.c index beac63535ab..ec42c8f2e08 100644 --- a/innobase/log/log0log.c +++ b/innobase/log/log0log.c @@ -2641,9 +2641,11 @@ logs_empty_and_mark_files_at_shutdown(void) dulint lsn; ulint arch_log_no; - ut_print_timestamp(stderr); - fprintf(stderr, " InnoDB: Starting shutdown...\n"); - + if (srv_print_verbose_log) + { + ut_print_timestamp(stderr); + fprintf(stderr, " InnoDB: Starting shutdown...\n"); + } /* Wait until the master thread and all other operations are idle: our algorithm only works if the server is idle at shutdown */ loop: @@ -2732,8 +2734,11 @@ loop: fil_flush_file_spaces(FIL_TABLESPACE); - ut_print_timestamp(stderr); - fprintf(stderr, " InnoDB: Shutdown completed\n"); + if (srv_print_verbose_log) + { + ut_print_timestamp(stderr); + fprintf(stderr, " InnoDB: Shutdown completed\n"); + } } /********************************************************** diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index ba556e1c050..1237a788622 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -120,6 +120,12 @@ ibool srv_print_innodb_monitor = FALSE; ibool srv_print_innodb_lock_monitor = FALSE; ibool srv_print_innodb_tablespace_monitor = FALSE; +/* + Set the following to 0 if you want InnoDB to write messages on + stderr on startup/shutdown +*/ +ibool srv_print_verbose_log = TRUE; + /* The parameters below are obsolete: */ ibool srv_print_parsed_sql = FALSE; diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index 15d99ab3001..2e9bade8b35 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -888,9 +888,11 @@ innobase_start_or_create_for_mysql(void) /* buf_debug_prints = TRUE; */ - ut_print_timestamp(stderr); - fprintf(stderr, " InnoDB: Started\n"); - + if (srv_print_verbose_log) + { + ut_print_timestamp(stderr); + fprintf(stderr, " InnoDB: Started\n"); + } return((int) DB_SUCCESS); } diff --git a/isam/isamlog.c b/isam/isamlog.c index 6fc5d98cc76..6d2bde42bf7 100644 --- a/isam/isamlog.c +++ b/isam/isamlog.c @@ -400,11 +400,7 @@ static int examine_log(my_string file_name, char **table_names) } to=isam_file_name; if (filepath) - { - strmov(isam_file_name,filepath); - convert_dirname(isam_file_name); - to=strend(isam_file_name); - } + to=convert_dirname(isam_file_name, filepath, NullS); strmov(to,pos); fn_ext(isam_file_name)[0]=0; /* Remove extension */ } diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index fbf2149d7f9..8de073e94eb 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -92,8 +92,8 @@ static ulong mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to, const char *from, ulong length); int mysql_server_init(int argc __attribute__((unused)), - const char **argv __attribute__((unused)), - const char **groups __attribute__((unused))) + char **argv __attribute__((unused)), + char **groups __attribute__((unused))) { return 0; } @@ -873,7 +873,7 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, for (row=data->data; row ; row = row->next,field++) { - field->table= strdup_root(alloc,(char*) row->data[0]); + field->org_table= field->table= strdup_root(alloc,(char*) row->data[0]); field->name= strdup_root(alloc,(char*) row->data[1]); field->length= (uint) uint3korr(row->data[2]); field->type= (enum enum_field_types) (uchar) row->data[3][0]; diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am index e39cebff04a..275a761e5ac 100644 --- a/libmysqld/Makefile.am +++ b/libmysqld/Makefile.am @@ -17,27 +17,23 @@ # # This file is public domain and comes with NO WARRANTY of any kind -MYSQLDATAdir = $(localstatedir) -MYSQLSHAREdir = $(pkgdatadir) -MYSQLBASEdir= $(prefix) +MYSQLDATAdir = $(localstatedir) +MYSQLSHAREdir = $(pkgdatadir) +MYSQLBASEdir= $(prefix) DEFS = -DEMBEDDED_LIBRARY -DMYSQL_SERVER \ -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \ -DDATADIR="\"$(MYSQLDATAdir)\"" \ -DSHAREDIR="\"$(MYSQLSHAREdir)\"" -INCLUDES = @MT_INCLUDES@ @bdb_includes@ -I$(srcdir)/../include -I../include \ - -I$(srcdir)/.. -I$(top_srcdir) -I.. -I../sql -I../regex +INCLUDES= @MT_INCLUDES@ @bdb_includes@ -I$(srcdir)/../include \ + -I../include -I$(srcdir)/.. -I$(top_srcdir) -I.. \ + -I../sql -I../regex - -## XXX: should we use client or server LDFLAGS for libmysqld? -LDADD = @CLIENT_EXTRA_LDFLAGS@ libmysqld.la -pkglib_LTLIBRARIES = libmysqld.la +noinst_LIBRARIES = libmysqld_int.a +pkglib_LIBRARIES = libmysqld.a SUBDIRS = . examples -libmysqld_la_SOURCES= libmysqld.c lib_sql.cc lib_load.cc - +libmysqld_sources= libmysqld.c lib_sql.cc lib_load.cc libmysqlsources = errmsg.c get_password.c password.c -## XXX: we should not have to duplicate info from the sources list -libmysqlobjects = errmsg.lo get_password.lo password.lo noinst_HEADERS = embedded_priv.h @@ -58,37 +54,52 @@ sqlsources = convert.cc derror.cc field.cc field_conv.cc filesort.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 -## XXX: we should not have to duplicate info from the sources list -sqlobjects = convert.lo derror.lo field.lo field_conv.lo filesort.lo \ - ha_innobase.lo ha_berkeley.lo ha_heap.lo ha_isam.lo ha_isammrg.lo \ - ha_myisam.lo ha_myisammrg.lo handler.lo sql_handler.lo \ - hostname.lo init.lo \ - item.lo item_buff.lo item_cmpfunc.lo item_create.lo \ - item_func.lo item_strfunc.lo item_sum.lo item_timefunc.lo \ - item_uniq.lo key.lo lock.lo log.lo log_event.lo md5.lo \ - mini_client.lo net_pkg.lo net_serv.lo opt_ft.lo opt_range.lo \ - opt_sum.lo procedure.lo records.lo slave.lo sql_acl.lo \ - sql_analyse.lo sql_base.lo sql_cache.lo sql_class.lo \ - sql_crypt.lo sql_db.lo sql_delete.lo sql_insert.lo sql_lex.lo \ - sql_list.lo sql_manager.lo sql_map.lo sql_parse.lo \ - sql_rename.lo sql_repl.lo sql_select.lo sql_show.lo \ - sql_string.lo sql_table.lo sql_test.lo sql_udf.lo \ - sql_update.lo sql_yacc.lo table.lo thr_malloc.lo time.lo \ - unireg.lo uniques.lo stacktrace.lo sql_union.lo hash_filo.lo - EXTRA_DIST = lib_vio.c +libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources) + # automake misses these sql_yacc.cc sql_yacc.h: $(top_srcdir)/sql/sql_yacc.yy -libmysqld_la_LIBADD = $(sqlobjects) $(libmysqlobjects) +# The following libraries should be included in libmysqld.a +INC_LIB= $(top_builddir)/regex/libregex.a \ + $(top_builddir)/myisam/libmyisam.a \ + $(top_builddir)/myisammrg/libmyisammrg.a \ + $(top_builddir)/heap/libheap.a \ + @innodb_libs@ @bdb_libs_with_path@ \ + $(top_builddir)/mysys/libmysys.a \ + $(top_builddir)/strings/libmystrings.a \ + $(top_builddir)/dbug/libdbug.a \ + $(top_builddir)/regex/libregex.a + +# +# To make it easy for the end user to use the embedded library we +# generate a total libmysqld.a from all library files, + +libmysqld.a: libmysqld_int.a $(INC_LIB) + if test ! -d tmp ; then mkdir tmp ; fi + rm -f $@ libmysqld_int2.a tmp/*.o tmp/*.a + cp $(INC_LIB) tmp + cp libmysqld_int.a libmysqld_int2.a ; \ + cd tmp ; \ + for file in *.a ; do \ + bfile=`basename $$file .a` ; \ + ar x $$file; \ + for obj in *.o ; do mv $$obj $${bfile}_$$obj ; done ; \ + ar q ../libmysqld_int2.a *.o ; \ + rm *.o ; \ + done + mv libmysqld_int2.a libmysqld.a + rm tmp/* + $(RANLIB) libmysqld.a + ## XXX: any time the client interface changes, we'll need to bump ## the version info for libmysqld; however, it's possible for the ## libmysqld interface to change without affecting the standard ## libmysqlclient interface. Should we make a separate version ## string for the two? -libmysqld_la_LDFLAGS = -version-info @SHARED_LIB_VERSION@ -CLEANFILES = $(libmysqld_la_LIBADD) libmysqld.la +#libmysqld_la_LDFLAGS = -version-info @SHARED_LIB_VERSION@ +#CLEANFILES = $(libmysqld_la_LIBADD) libmysqld.la # This is called from the toplevel makefile link_sources: diff --git a/libmysqld/examples/Makefile.am b/libmysqld/examples/Makefile.am index 124bc3e05f4..d1cf24caf48 100644 --- a/libmysqld/examples/Makefile.am +++ b/libmysqld/examples/Makefile.am @@ -10,20 +10,9 @@ link_sources: DEFS = -DEMBEDDED_LIBRARY INCLUDES = -I$(top_srcdir)/include $(openssl_includes) \ -I$(srcdir) -I$(top_srcdir) -I$(top_srcdir)/client -LIBS = @LIBS@ -LDADD = $(top_builddir)/libmysqld/libmysqld.la \ - $(top_builddir)/isam/libnisam.a \ - $(top_builddir)/myisam/libmyisam.a \ - $(top_builddir)/heap/libheap.a \ - $(top_builddir)/merge/libmerge.a \ - $(top_builddir)/myisammrg/libmyisammrg.a \ - @innodb_libs@ @bdb_libs@ @pstack_libs@ \ - $(top_builddir)/mysys/libmysys.a \ - $(top_builddir)/strings/libmystrings.a \ - $(top_builddir)/dbug/libdbug.a \ - $(top_builddir)/regex/libregex.a @LIBDL@ +LIBS = @LIBS@ +LDADD = ../libmysqld.a @innodb_system_libs@ @LIBDL@ -mysqltest_DEPENDENCIES = ../libmysqld.la mysqltest_SOURCES = mysqltest.c mysql_SOURCES = mysql.cc readline.cc completion_hash.cc \ diff --git a/libmysqld/examples/test-run b/libmysqld/examples/test-run index 58c21349519..b97d2742b74 100755 --- a/libmysqld/examples/test-run +++ b/libmysqld/examples/test-run @@ -6,26 +6,19 @@ # that will run on all platforms (or incorporate it into the # standard mysql-test-run). -#test_data_dir=/tmp/mysql-data -test_data_dir=../../mysql-test/var/master-data -cd "$test_data_dir" || { - echo "can't cd to $test_data_dir" >&2 - exit 1 -} - # All paths below must be relative to $test_data_dir -#top_builddir=/home/tim/my/4 -top_builddir=../../.. +top_builddir=../.. mysql_test_dir=$top_builddir/mysql-test examples=$top_builddir/libmysqld/examples mysqltest=$examples/mysqltest -testdir=./test - +datadir=$mysql_test_dir/var/master-data +test_data_dir=test gdb=0 list=0 run= tests= start= +clean=1 cr=" " @@ -35,6 +28,7 @@ usage () { cat <&2 +if test ! -d "$datadir/$test_data_dir" +then + echo "bad setup (is '$datadir/$test_data_dir'', missing ?)" >&2 exit 1 -} +fi test -n "$tests" || tests=`/bin/ls -1 "$mysql_test_dir"/t/*.test | grep -v '^.*/rpl[^/]*$' | \ sed -e 's,^.*/,,' -e 's,.test$,,'` -echo "cleaning data directory '$test_data_dir'" -rm -f $test_data_dir/ib_* $test_data_dir/ibdata* log.* -echo "cleaning test directory '$testdir'" -rm -f $testdir/* - +echo "cleaning data directory '$datadir/$test_data_dir'" +if test $clean = 1 +then + rm -f $datadir/ib_* $datadir/ibdata* + rm -f $datadir/log.00* +fi +rm -f $datadir/../tmp/* rm -f test-gdbinit TZ=GMT-3; export TZ +# At least one of the tests needs the following environment variable +MYSQL_TEST_DIR=`( cd $mysql_test_dir ; pwd )` ; export MYSQL_TEST_DIR + skip=1 test -z "$start" && skip=0 @@ -96,16 +96,20 @@ do test $skip -eq 1 && test -n "$start" && test "$start" = "$b" && skip=0 test $skip -eq 1 && { echo "skipping '$b'"; continue; } - t="$mysql_test_dir/t/$b.test" - r="$mysql_test_dir/r/$b.result" - c="$mysql_test_dir/r/$b.reject" + t="t/$b.test" + r="r/$b.result" # Only test if $t exists; there is no $r for some tests - test -f $t || { - echo "test '$b' doesn't exist" >&2 + test -f $mysql_test_dir/$t || { + echo "test '$mysql_test_dir/$t' doesn't exist" >&2 continue } - args="$init_args -v -S /tmp/mysql.sock -R $r -x $t test" + args="$init_args -v --basedir=$mysql_test_dir/ -R $r -x $t --server-arg=--datadir=$datadir" + if test -f "$mysql_test_dir/t/$b-master.opt" ; then + args="$args --server-file=t/$b-master.opt" + fi + + args="$args $test_data_dir" # Add database last echo "set args $args$run" > test-gdbinit #if false && test -n "$run" if test -n "$run" -o $gdb -eq 1 @@ -129,5 +133,5 @@ do res=$? fi - test $res -eq 0 || echo "!!! error: $res" + test $res -eq 0 -o $res -eq 2 || echo "!!! error: $res" done diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 5641e920c9d..139f9b9c0c7 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -296,7 +296,7 @@ extern "C" static my_bool inited, org_my_init_done; -int mysql_server_init(int argc, const char **argv, const char **groups) +int mysql_server_init(int argc, char **argv, char **groups) { char glob_hostname[FN_REFLEN]; @@ -306,7 +306,7 @@ int mysql_server_init(int argc, const char **argv, const char **groups) char ***argvp; int fake_argc = 1; char *fake_argv[] = { (char *)"", 0 }; - const char *fake_groups[] = { "server", 0 }; + const char *fake_groups[] = { "server", "embedded", 0 }; if (argc) { argcp = &argc; @@ -318,7 +318,7 @@ int mysql_server_init(int argc, const char **argv, const char **groups) argvp = (char ***) &fake_argv; } if (!groups) - groups = fake_groups; + groups = (char**) fake_groups; my_umask=0660; // Default umask for new files my_umask_dir=0700; // Default umask for new directories @@ -330,7 +330,9 @@ int mysql_server_init(int argc, const char **argv, const char **groups) org_my_init_done=my_init_done; } if (!org_my_init_done) + { MY_INIT((char *)"mysql_embedded"); // init my_sys library & pthreads + } tzset(); // Set tzname @@ -357,7 +359,7 @@ int mysql_server_init(int argc, const char **argv, const char **groups) strcat(server_version,"-debug"); #endif strcat(server_version,"-embedded"); - load_defaults("my", groups, argcp, argvp); + load_defaults("my", (const char **) groups, argcp, argvp); defaults_argv=*argvp; mysql_tmpdir=getenv("TMPDIR"); /* Use this if possible */ #if defined( __WIN__) || defined(OS2) diff --git a/libmysqld/libmysqld.c b/libmysqld/libmysqld.c index 12786cce0ee..7093e5f993e 100644 --- a/libmysqld/libmysqld.c +++ b/libmysqld/libmysqld.c @@ -79,11 +79,6 @@ static ulong mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to, #define set_sigpipe(mysql) #define reset_sigpipe(mysql) -static MYSQL* spawn_init(MYSQL* parent, const char* host, - unsigned int port, - const char* user, - const char* passwd); - /***************************************************************************** ** read a packet from server. Give error message if socket was down ** or packet is an error message diff --git a/merge/Makefile.am b/merge/Makefile.am index 52abfc4cdc0..94de6d65391 100644 --- a/merge/Makefile.am +++ b/merge/Makefile.am @@ -16,10 +16,10 @@ INCLUDES = @MT_INCLUDES@ -I$(srcdir)/../include -I../include pkglib_LIBRARIES = libmerge.a -noinst_HEADERS = mrgdef.h -libmerge_a_SOURCES = open.c extra.c info.c _locking.c \ - rrnd.c update.c delete.c rsame.c panic.c \ - close.c create.c static.c +noinst_HEADERS = mrg_def.h +libmerge_a_SOURCES = mrg_open.c mrg_extra.c mrg_info.c mrg_locking.c \ + mrg_rrnd.c mrg_update.c mrg_delete.c mrg_rsame.c \ + mrg_panic.c mrg_close.c mrg_create.c mrg_static.c OMIT_DEPENDENCIES = pthread.h stdio.h __stdio.h stdlib.h __stdlib.h math.h\ __math.h time.h __time.h unistd.h __unistd.h types.h \ diff --git a/merge/_locking.c b/merge/_locking.c deleted file mode 100644 index 81582da1312..00000000000 --- a/merge/_locking.c +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* - Lock databases against read or write. -*/ - -#include "mrgdef.h" - -int mrg_lock_database(MRG_INFO *info,int lock_type) -{ - int error,new_error; - MRG_TABLE *file; - - error=0; - for (file=info->open_tables ; file != info->end_table ; file++) - if ((new_error=nisam_lock_database(file->table,lock_type))) - error=new_error; - return(error); -} diff --git a/merge/close.c b/merge/close.c deleted file mode 100644 index 2b769ade8e9..00000000000 --- a/merge/close.c +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* close a isam-database */ - -#include "mrgdef.h" - -int mrg_close(register MRG_INFO *info) -{ - int error=0,new_error; - MRG_TABLE *file; - DBUG_ENTER("mrg_close"); - - for (file=info->open_tables ; file != info->end_table ; file++) - if ((new_error=nisam_close(file->table))) - error=new_error; - pthread_mutex_lock(&THR_LOCK_open); - mrg_open_list=list_delete(mrg_open_list,&info->open_list); - pthread_mutex_unlock(&THR_LOCK_open); - my_free((gptr) info,MYF(0)); - if (error) - { - my_errno=error; - DBUG_RETURN(-1); - } - DBUG_RETURN(0); -} diff --git a/merge/create.c b/merge/create.c deleted file mode 100644 index fd2c16f9ea2..00000000000 --- a/merge/create.c +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Create a MERGE-file */ - -#include "mrgdef.h" - - /* create file named 'name' and save filenames in it - table_names should be NULL or a vector of string-pointers with - a NULL-pointer last - */ - -int mrg_create(const char *name, const char**table_names) -{ - int save_errno; - uint errpos; - File file; - char buff[FN_REFLEN],*end; - DBUG_ENTER("mrg_create"); - - errpos=0; - if ((file = my_create(fn_format(buff,name,"",MRG_NAME_EXT,4),0, - O_RDWR | O_TRUNC,MYF(MY_WME))) < 0) - goto err; - errpos=1; - if (table_names) - for ( ; *table_names ; table_names++) - { - strmov(buff,*table_names); - fn_same(buff,name,4); - *(end=strend(buff))='\n'; - if (my_write(file,*table_names,(uint) (end-buff+1), - MYF(MY_WME | MY_NABP))) - goto err; - } - if (my_close(file,MYF(0))) - goto err; - DBUG_RETURN(0); - -err: - save_errno=my_errno; - switch (errpos) { - case 1: - VOID(my_close(file,MYF(0))); - } - my_errno=save_errno; /* Return right errocode */ - DBUG_RETURN(-1); -} /* mrg_create */ diff --git a/merge/delete.c b/merge/delete.c deleted file mode 100644 index a4ee46eedc2..00000000000 --- a/merge/delete.c +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Delete last read record */ - -#include "mrgdef.h" - -int mrg_delete(MRG_INFO *info,const byte *record) -{ - if (!info->current_table) - { - my_errno=HA_ERR_NO_ACTIVE_RECORD; - return(-1); - } - return nisam_delete(info->current_table->table,record); -} diff --git a/merge/extra.c b/merge/extra.c deleted file mode 100644 index c4f048a4385..00000000000 --- a/merge/extra.c +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* - Extra functions we want to do with a database - - All flags, exept record-cache-flags, are set in all used databases - record-cache-flags are set in mrg_rrnd when we are changing database. -*/ - -#include "mrgdef.h" - -int mrg_extra( -MRG_INFO *info, -enum ha_extra_function function) -{ - MRG_TABLE *file; - - if (function == HA_EXTRA_CACHE) - info->cache_in_use=1; - else - { - if (function == HA_EXTRA_NO_CACHE || function == HA_EXTRA_RESET) - info->cache_in_use=0; - if (function == HA_EXTRA_RESET || function == HA_EXTRA_RESET_STATE) - { - info->current_table=0; - info->last_used_table=info->open_tables; - } - for (file=info->open_tables ; file != info->end_table ; file++) - nisam_extra(file->table,function); - } - return 0; -} diff --git a/merge/info.c b/merge/info.c deleted file mode 100644 index d44ada8e6e6..00000000000 --- a/merge/info.c +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include "mrgdef.h" - -ulong mrg_position(MRG_INFO *info) -{ - MRG_TABLE *current_table; - - if (!(current_table = info->current_table) && - info->open_tables != info->end_table) - current_table = info->open_tables; - return (current_table ? - (ulong) (current_table->table->lastpos + - current_table->file_offset) : - ~(ulong) 0); -} - - /* If flag != 0 one only gets pos of last record */ - -int mrg_info(MRG_INFO *info,register MERGE_INFO *x,int flag) -{ - MRG_TABLE *current_table; - DBUG_ENTER("mrg_info"); - - if (!(current_table = info->current_table) && - info->open_tables != info->end_table) - current_table = info->open_tables; - x->recpos = info->current_table ? - info->current_table->table->lastpos + info->current_table->file_offset : - (ulong) -1L; - if (flag != HA_STATUS_POS) - { - x->records = info->records; - x->deleted = info->del; - x->data_file_length = info->data_file_length; - x->reclength = info->reclength; - if (current_table) - x->errkey = current_table->table->errkey; - else - { /* No tables in MRG */ - x->errkey=0; - } - x->options = info->options; - } - DBUG_RETURN(0); -} diff --git a/merge/mrg_close.c b/merge/mrg_close.c new file mode 100644 index 00000000000..4879dbf4c36 --- /dev/null +++ b/merge/mrg_close.c @@ -0,0 +1,40 @@ +/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* close a isam-database */ + +#include "mrg_def.h" + +int mrg_close(register MRG_INFO *info) +{ + int error=0,new_error; + MRG_TABLE *file; + DBUG_ENTER("mrg_close"); + + for (file=info->open_tables ; file != info->end_table ; file++) + if ((new_error=nisam_close(file->table))) + error=new_error; + pthread_mutex_lock(&THR_LOCK_open); + mrg_open_list=list_delete(mrg_open_list,&info->open_list); + pthread_mutex_unlock(&THR_LOCK_open); + my_free((gptr) info,MYF(0)); + if (error) + { + my_errno=error; + DBUG_RETURN(-1); + } + DBUG_RETURN(0); +} diff --git a/merge/mrg_create.c b/merge/mrg_create.c new file mode 100644 index 00000000000..d92b617f4ba --- /dev/null +++ b/merge/mrg_create.c @@ -0,0 +1,61 @@ +/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* Create a MERGE-file */ + +#include "mrg_def.h" + + /* create file named 'name' and save filenames in it + table_names should be NULL or a vector of string-pointers with + a NULL-pointer last + */ + +int mrg_create(const char *name, const char**table_names) +{ + int save_errno; + uint errpos; + File file; + char buff[FN_REFLEN],*end; + DBUG_ENTER("mrg_create"); + + errpos=0; + if ((file = my_create(fn_format(buff,name,"",MRG_NAME_EXT,4),0, + O_RDWR | O_TRUNC,MYF(MY_WME))) < 0) + goto err; + errpos=1; + if (table_names) + for ( ; *table_names ; table_names++) + { + strmov(buff,*table_names); + fn_same(buff,name,4); + *(end=strend(buff))='\n'; + if (my_write(file,*table_names,(uint) (end-buff+1), + MYF(MY_WME | MY_NABP))) + goto err; + } + if (my_close(file,MYF(0))) + goto err; + DBUG_RETURN(0); + +err: + save_errno=my_errno; + switch (errpos) { + case 1: + VOID(my_close(file,MYF(0))); + } + my_errno=save_errno; /* Return right errocode */ + DBUG_RETURN(-1); +} /* mrg_create */ diff --git a/merge/mrg_def.h b/merge/mrg_def.h new file mode 100644 index 00000000000..3f22c83589a --- /dev/null +++ b/merge/mrg_def.h @@ -0,0 +1,29 @@ +/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* Denna fil includeras i alla merge-filer */ + +#ifndef N_MAXKEY +#include "../isam/isamdef.h" +#endif + +#include "merge.h" + +extern LIST *mrg_open_list; + +#ifdef THREAD +extern pthread_mutex_t THR_LOCK_open; +#endif diff --git a/merge/mrg_delete.c b/merge/mrg_delete.c new file mode 100644 index 00000000000..4eb19957c63 --- /dev/null +++ b/merge/mrg_delete.c @@ -0,0 +1,29 @@ +/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* Delete last read record */ + +#include "mrg_def.h" + +int mrg_delete(MRG_INFO *info,const byte *record) +{ + if (!info->current_table) + { + my_errno=HA_ERR_NO_ACTIVE_RECORD; + return(-1); + } + return nisam_delete(info->current_table->table,record); +} diff --git a/merge/mrg_extra.c b/merge/mrg_extra.c new file mode 100644 index 00000000000..ace931f5810 --- /dev/null +++ b/merge/mrg_extra.c @@ -0,0 +1,46 @@ +/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* + Extra functions we want to do with a database + - All flags, exept record-cache-flags, are set in all used databases + record-cache-flags are set in mrg_rrnd when we are changing database. +*/ + +#include "mrg_def.h" + +int mrg_extra( +MRG_INFO *info, +enum ha_extra_function function) +{ + MRG_TABLE *file; + + if (function == HA_EXTRA_CACHE) + info->cache_in_use=1; + else + { + if (function == HA_EXTRA_NO_CACHE || function == HA_EXTRA_RESET) + info->cache_in_use=0; + if (function == HA_EXTRA_RESET || function == HA_EXTRA_RESET_STATE) + { + info->current_table=0; + info->last_used_table=info->open_tables; + } + for (file=info->open_tables ; file != info->end_table ; file++) + nisam_extra(file->table,function); + } + return 0; +} diff --git a/merge/mrg_info.c b/merge/mrg_info.c new file mode 100644 index 00000000000..981d1975fea --- /dev/null +++ b/merge/mrg_info.c @@ -0,0 +1,60 @@ +/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include "mrg_def.h" + +ulong mrg_position(MRG_INFO *info) +{ + MRG_TABLE *current_table; + + if (!(current_table = info->current_table) && + info->open_tables != info->end_table) + current_table = info->open_tables; + return (current_table ? + (ulong) (current_table->table->lastpos + + current_table->file_offset) : + ~(ulong) 0); +} + + /* If flag != 0 one only gets pos of last record */ + +int mrg_info(MRG_INFO *info,register MERGE_INFO *x,int flag) +{ + MRG_TABLE *current_table; + DBUG_ENTER("mrg_info"); + + if (!(current_table = info->current_table) && + info->open_tables != info->end_table) + current_table = info->open_tables; + x->recpos = info->current_table ? + info->current_table->table->lastpos + info->current_table->file_offset : + (ulong) -1L; + if (flag != HA_STATUS_POS) + { + x->records = info->records; + x->deleted = info->del; + x->data_file_length = info->data_file_length; + x->reclength = info->reclength; + if (current_table) + x->errkey = current_table->table->errkey; + else + { /* No tables in MRG */ + x->errkey=0; + } + x->options = info->options; + } + DBUG_RETURN(0); +} diff --git a/merge/mrg_locking.c b/merge/mrg_locking.c new file mode 100644 index 00000000000..13ccb09bbe6 --- /dev/null +++ b/merge/mrg_locking.c @@ -0,0 +1,33 @@ +/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* + Lock databases against read or write. +*/ + +#include "mrg_def.h" + +int mrg_lock_database(MRG_INFO *info,int lock_type) +{ + int error,new_error; + MRG_TABLE *file; + + error=0; + for (file=info->open_tables ; file != info->end_table ; file++) + if ((new_error=nisam_lock_database(file->table,lock_type))) + error=new_error; + return(error); +} diff --git a/merge/mrg_open.c b/merge/mrg_open.c new file mode 100644 index 00000000000..708e56e1a81 --- /dev/null +++ b/merge/mrg_open.c @@ -0,0 +1,150 @@ +/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* open a MERGE-database */ + +#include "mrg_def.h" +#include +#include +#ifdef VMS +#include "static.c" +#endif + +/* open a MERGE-database. + + if handle_locking is 0 then exit with error if some database is locked + if handle_locking is 1 then wait if database is locked +*/ + + +MRG_INFO *mrg_open( +const char *name, +int mode, +int handle_locking) +{ + int save_errno,i,errpos; + uint files,dir_length,length, options; + ulonglong file_offset; + char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end; + MRG_INFO info,*m_info; + File fd; + IO_CACHE file; + N_INFO *isam,*last_isam; + DBUG_ENTER("mrg_open"); + + LINT_INIT(last_isam); + isam=0; + errpos=files=0; + bzero((gptr) &info,sizeof(info)); + bzero((char*) &file,sizeof(file)); + if ((fd=my_open(fn_format(name_buff,name,"",MRG_NAME_EXT,4), + O_RDONLY | O_SHARE,MYF(0))) < 0 || + init_io_cache(&file, fd, IO_SIZE, READ_CACHE, 0, 0, + MYF(MY_WME | MY_NABP))) + goto err; + errpos=1; + dir_length=dirname_part(name_buff,name); + info.reclength=0; + while ((length=my_b_gets(&file,buff,FN_REFLEN-1))) + { + if ((end=buff+length)[-1] == '\n') + end[-1]='\0'; + if (buff[0] && buff[0] != '#') /* Skipp empty lines and comments */ + { + last_isam=isam; + if (!test_if_hard_path(buff)) + { + VOID(strmake(name_buff+dir_length,buff, + sizeof(name_buff)-1-dir_length)); + VOID(cleanup_dirname(buff,name_buff)); + } + if (!(isam=nisam_open(buff,mode,test(handle_locking)))) + goto err; + files++; + } + last_isam=isam; + if (info.reclength && info.reclength != isam->s->base.reclength) + { + my_errno=HA_ERR_WRONG_IN_RECORD; + goto err; + } + info.reclength=isam->s->base.reclength; + } + if (!(m_info= (MRG_INFO*) my_malloc(sizeof(MRG_INFO)+files*sizeof(MRG_TABLE), + MYF(MY_WME)))) + goto err; + *m_info=info; + m_info->open_tables=(MRG_TABLE *) (m_info+1); + m_info->tables=files; + + options= (uint) ~0; + for (i=files ; i-- > 0 ; ) + { + m_info->open_tables[i].table=isam; + m_info->options|=isam->s->base.options; + options&=isam->s->base.options; + m_info->records+=isam->s->state.records; + m_info->del+=isam->s->state.del; + m_info->data_file_length=isam->s->state.data_file_length; + if (i) + isam=(N_INFO*) (isam->open_list.next->data); + } + /* Don't force readonly if not all tables are readonly */ + if (! (options & (HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA))) + m_info->options&= ~(HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA); + + /* Fix fileinfo for easyer debugging (actually set by rrnd) */ + file_offset=0; + for (i=0 ; (uint) i < files ; i++) + { + m_info->open_tables[i].file_offset=(my_off_t) file_offset; + file_offset+=m_info->open_tables[i].table->s->state.data_file_length; + } + if (sizeof(my_off_t) == 4 && file_offset > (ulonglong) (ulong) ~0L) + { + my_errno=HA_ERR_RECORD_FILE_FULL; + my_free((char*) m_info,MYF(0)); + goto err; + } + + m_info->end_table=m_info->open_tables+files; + m_info->last_used_table=m_info->open_tables; + + VOID(my_close(fd,MYF(0))); + end_io_cache(&file); + m_info->open_list.data=(void*) m_info; + pthread_mutex_lock(&THR_LOCK_open); + mrg_open_list=list_add(mrg_open_list,&m_info->open_list); + pthread_mutex_unlock(&THR_LOCK_open); + DBUG_RETURN(m_info); + +err: + save_errno=my_errno; + switch (errpos) { + case 1: + VOID(my_close(fd,MYF(0))); + end_io_cache(&file); + for (i=files ; i-- > 0 ; ) + { + isam=last_isam; + if (i) + last_isam=(N_INFO*) (isam->open_list.next->data); + nisam_close(isam); + } + } + my_errno=save_errno; + DBUG_RETURN (NULL); +} diff --git a/merge/mrg_panic.c b/merge/mrg_panic.c new file mode 100644 index 00000000000..dd9b8bf4e0f --- /dev/null +++ b/merge/mrg_panic.c @@ -0,0 +1,47 @@ +/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include "mrg_def.h" + + /* if flag == HA_PANIC_CLOSE then all misam files are closed */ + /* if flag == HA_PANIC_WRITE then all misam files are unlocked and + all changed data in single user misam is written to file */ + /* if flag == HA_PANIC_READ then all misam files that was locked when + nisam_panic(HA_PANIC_WRITE) was done is locked. A ni_readinfo() is + done for all single user files to get changes in database */ + + +int mrg_panic( +enum ha_panic_function flag) +{ + int error=0; + LIST *list_element,*next_open; + MRG_INFO *info; + DBUG_ENTER("mrg_panic"); + + for (list_element=mrg_open_list ; list_element ; list_element=next_open) + { + next_open=list_element->next; /* Save if close */ + info=(MRG_INFO*) list_element->data; + if (flag == HA_PANIC_CLOSE && mrg_close(info)) + error=my_errno; + } + if (mrg_open_list && flag != HA_PANIC_CLOSE) + DBUG_RETURN(nisam_panic(flag)); + if (!error) DBUG_RETURN(0); + my_errno=error; + DBUG_RETURN(-1); +} diff --git a/merge/mrg_rrnd.c b/merge/mrg_rrnd.c new file mode 100644 index 00000000000..42430a039f7 --- /dev/null +++ b/merge/mrg_rrnd.c @@ -0,0 +1,110 @@ +/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* + Read a record with random-access. The position to the record must + get by mrg_info(). The next record can be read with pos= -1 */ + + +#include "mrg_def.h" + +static MRG_TABLE *find_table(MRG_TABLE *start,MRG_TABLE *end,mrg_off_t pos); + +/* + If filepos == -1, read next + Returns same as nisam_rrnd: + 0 = Ok. + 1 = Record deleted. + -1 = EOF (or something, errno should be HA_ERR_END_OF_FILE) +*/ + +int mrg_rrnd(MRG_INFO *info,byte *buf,mrg_off_t filepos) +{ + int error; + N_INFO *isam_info; + + if (filepos == ~(mrg_off_t) 0) /* Can't use HA_POS_ERROR */ + { + if (!info->current_table) + { + if (info->open_tables == info->end_table) + { /* No tables */ + my_errno=HA_ERR_END_OF_FILE; + return -1; + } + isam_info=(info->current_table=info->open_tables)->table; + if (info->cache_in_use) + nisam_extra(isam_info,HA_EXTRA_CACHE); + filepos=isam_info->s->pack.header_length; + isam_info->lastinx= (uint) -1; /* Can't forward or backward */ + } + else + { + isam_info=info->current_table->table; + filepos= isam_info->nextpos; + } + + for (;;) + { + isam_info->update&= HA_STATE_CHANGED; + if ((error=(*isam_info->s->read_rnd)(isam_info,(byte*) buf, + filepos,1)) >= 0 || + my_errno != HA_ERR_END_OF_FILE) + return (error); + if (info->cache_in_use) + nisam_extra(info->current_table->table,HA_EXTRA_NO_CACHE); + if (info->current_table+1 == info->end_table) + return(-1); + info->current_table++; + info->last_used_table=info->current_table; + if (info->cache_in_use) + nisam_extra(info->current_table->table,HA_EXTRA_CACHE); + info->current_table->file_offset= + info->current_table[-1].file_offset+ + info->current_table[-1].table->s->state.data_file_length; + + isam_info=info->current_table->table; + filepos=isam_info->s->pack.header_length; + isam_info->lastinx= (uint) -1; + } + } + info->current_table=find_table(info->open_tables, + info->end_table-1,filepos); + isam_info=info->current_table->table; + isam_info->update&= HA_STATE_CHANGED; + return ((*isam_info->s->read_rnd)(isam_info,(byte*) buf, + (ulong) (filepos - + info->current_table->file_offset), + 0)); +} + + + /* Find which table to use according to file-pos */ + +static MRG_TABLE *find_table(MRG_TABLE *start,MRG_TABLE *end,mrg_off_t pos) +{ + MRG_TABLE *mid; + + while (start != end) + { + mid=start+((uint) (end-start)+1)/2; + if (mid->file_offset > pos) + end=mid-1; + else + start=mid; + } + return start; +} diff --git a/merge/mrg_rsame.c b/merge/mrg_rsame.c new file mode 100644 index 00000000000..307e4284486 --- /dev/null +++ b/merge/mrg_rsame.c @@ -0,0 +1,36 @@ +/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include "mrg_def.h" + + +int mrg_rsame( +MRG_INFO *info, +byte *record, +int inx) /* not used, should be 0 */ +{ + if (inx) + { + my_errno=HA_ERR_WRONG_INDEX; + return(-1); + } + if (!info->current_table) + { + my_errno=HA_ERR_NO_ACTIVE_RECORD; + return(-1); + } + return nisam_rsame(info->current_table->table,record,inx); +} diff --git a/merge/mrg_static.c b/merge/mrg_static.c new file mode 100644 index 00000000000..793dc8c4d92 --- /dev/null +++ b/merge/mrg_static.c @@ -0,0 +1,26 @@ +/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* + Static variables for pisam library. All definied here for easy making of + a shared library +*/ + +#ifndef stdin +#include "mrg_def.h" +#endif + +LIST *mrg_open_list=0; diff --git a/merge/mrg_update.c b/merge/mrg_update.c new file mode 100644 index 00000000000..88f8572eb7d --- /dev/null +++ b/merge/mrg_update.c @@ -0,0 +1,31 @@ +/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* Update last read record */ + +#include "mrg_def.h" + +int mrg_update( +register MRG_INFO *info, +const byte *oldrec, const byte *newrec) +{ + if (!info->current_table) + { + my_errno=HA_ERR_NO_ACTIVE_RECORD; + return(-1); + } + return nisam_update(info->current_table->table,oldrec,newrec); +} diff --git a/merge/mrgdef.h b/merge/mrgdef.h deleted file mode 100644 index 3f22c83589a..00000000000 --- a/merge/mrgdef.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Denna fil includeras i alla merge-filer */ - -#ifndef N_MAXKEY -#include "../isam/isamdef.h" -#endif - -#include "merge.h" - -extern LIST *mrg_open_list; - -#ifdef THREAD -extern pthread_mutex_t THR_LOCK_open; -#endif diff --git a/merge/open.c b/merge/open.c deleted file mode 100644 index 7b5e571b9ad..00000000000 --- a/merge/open.c +++ /dev/null @@ -1,150 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* open a MERGE-database */ - -#include "mrgdef.h" -#include -#include -#ifdef VMS -#include "static.c" -#endif - -/* open a MERGE-database. - - if handle_locking is 0 then exit with error if some database is locked - if handle_locking is 1 then wait if database is locked -*/ - - -MRG_INFO *mrg_open( -const char *name, -int mode, -int handle_locking) -{ - int save_errno,i,errpos; - uint files,dir_length,length, options; - ulonglong file_offset; - char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end; - MRG_INFO info,*m_info; - File fd; - IO_CACHE file; - N_INFO *isam,*last_isam; - DBUG_ENTER("mrg_open"); - - LINT_INIT(last_isam); - isam=0; - errpos=files=0; - bzero((gptr) &info,sizeof(info)); - bzero((char*) &file,sizeof(file)); - if ((fd=my_open(fn_format(name_buff,name,"",MRG_NAME_EXT,4), - O_RDONLY | O_SHARE,MYF(0))) < 0 || - init_io_cache(&file, fd, IO_SIZE, READ_CACHE, 0, 0, - MYF(MY_WME | MY_NABP))) - goto err; - errpos=1; - dir_length=dirname_part(name_buff,name); - info.reclength=0; - while ((length=my_b_gets(&file,buff,FN_REFLEN-1))) - { - if ((end=buff+length)[-1] == '\n') - end[-1]='\0'; - if (buff[0] && buff[0] != '#') /* Skipp empty lines and comments */ - { - last_isam=isam; - if (!test_if_hard_path(buff)) - { - VOID(strmake(name_buff+dir_length,buff, - sizeof(name_buff)-1-dir_length)); - VOID(cleanup_dirname(buff,name_buff)); - } - if (!(isam=nisam_open(buff,mode,test(handle_locking)))) - goto err; - files++; - } - last_isam=isam; - if (info.reclength && info.reclength != isam->s->base.reclength) - { - my_errno=HA_ERR_WRONG_IN_RECORD; - goto err; - } - info.reclength=isam->s->base.reclength; - } - if (!(m_info= (MRG_INFO*) my_malloc(sizeof(MRG_INFO)+files*sizeof(MRG_TABLE), - MYF(MY_WME)))) - goto err; - *m_info=info; - m_info->open_tables=(MRG_TABLE *) (m_info+1); - m_info->tables=files; - - options= (uint) ~0; - for (i=files ; i-- > 0 ; ) - { - m_info->open_tables[i].table=isam; - m_info->options|=isam->s->base.options; - options&=isam->s->base.options; - m_info->records+=isam->s->state.records; - m_info->del+=isam->s->state.del; - m_info->data_file_length=isam->s->state.data_file_length; - if (i) - isam=(N_INFO*) (isam->open_list.next->data); - } - /* Don't force readonly if not all tables are readonly */ - if (! (options & (HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA))) - m_info->options&= ~(HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA); - - /* Fix fileinfo for easyer debugging (actually set by rrnd) */ - file_offset=0; - for (i=0 ; (uint) i < files ; i++) - { - m_info->open_tables[i].file_offset=(my_off_t) file_offset; - file_offset+=m_info->open_tables[i].table->s->state.data_file_length; - } - if (sizeof(my_off_t) == 4 && file_offset > (ulonglong) (ulong) ~0L) - { - my_errno=HA_ERR_RECORD_FILE_FULL; - my_free((char*) m_info,MYF(0)); - goto err; - } - - m_info->end_table=m_info->open_tables+files; - m_info->last_used_table=m_info->open_tables; - - VOID(my_close(fd,MYF(0))); - end_io_cache(&file); - m_info->open_list.data=(void*) m_info; - pthread_mutex_lock(&THR_LOCK_open); - mrg_open_list=list_add(mrg_open_list,&m_info->open_list); - pthread_mutex_unlock(&THR_LOCK_open); - DBUG_RETURN(m_info); - -err: - save_errno=my_errno; - switch (errpos) { - case 1: - VOID(my_close(fd,MYF(0))); - end_io_cache(&file); - for (i=files ; i-- > 0 ; ) - { - isam=last_isam; - if (i) - last_isam=(N_INFO*) (isam->open_list.next->data); - nisam_close(isam); - } - } - my_errno=save_errno; - DBUG_RETURN (NULL); -} diff --git a/merge/panic.c b/merge/panic.c deleted file mode 100644 index cf333e3a9bf..00000000000 --- a/merge/panic.c +++ /dev/null @@ -1,47 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include "mrgdef.h" - - /* if flag == HA_PANIC_CLOSE then all misam files are closed */ - /* if flag == HA_PANIC_WRITE then all misam files are unlocked and - all changed data in single user misam is written to file */ - /* if flag == HA_PANIC_READ then all misam files that was locked when - nisam_panic(HA_PANIC_WRITE) was done is locked. A ni_readinfo() is - done for all single user files to get changes in database */ - - -int mrg_panic( -enum ha_panic_function flag) -{ - int error=0; - LIST *list_element,*next_open; - MRG_INFO *info; - DBUG_ENTER("mrg_panic"); - - for (list_element=mrg_open_list ; list_element ; list_element=next_open) - { - next_open=list_element->next; /* Save if close */ - info=(MRG_INFO*) list_element->data; - if (flag == HA_PANIC_CLOSE && mrg_close(info)) - error=my_errno; - } - if (mrg_open_list && flag != HA_PANIC_CLOSE) - DBUG_RETURN(nisam_panic(flag)); - if (!error) DBUG_RETURN(0); - my_errno=error; - DBUG_RETURN(-1); -} diff --git a/merge/rrnd.c b/merge/rrnd.c deleted file mode 100644 index e53982aca21..00000000000 --- a/merge/rrnd.c +++ /dev/null @@ -1,110 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* - Read a record with random-access. The position to the record must - get by mrg_info(). The next record can be read with pos= -1 */ - - -#include "mrgdef.h" - -static MRG_TABLE *find_table(MRG_TABLE *start,MRG_TABLE *end,mrg_off_t pos); - -/* - If filepos == -1, read next - Returns same as nisam_rrnd: - 0 = Ok. - 1 = Record deleted. - -1 = EOF (or something, errno should be HA_ERR_END_OF_FILE) -*/ - -int mrg_rrnd(MRG_INFO *info,byte *buf,mrg_off_t filepos) -{ - int error; - N_INFO *isam_info; - - if (filepos == ~(mrg_off_t) 0) /* Can't use HA_POS_ERROR */ - { - if (!info->current_table) - { - if (info->open_tables == info->end_table) - { /* No tables */ - my_errno=HA_ERR_END_OF_FILE; - return -1; - } - isam_info=(info->current_table=info->open_tables)->table; - if (info->cache_in_use) - nisam_extra(isam_info,HA_EXTRA_CACHE); - filepos=isam_info->s->pack.header_length; - isam_info->lastinx= (uint) -1; /* Can't forward or backward */ - } - else - { - isam_info=info->current_table->table; - filepos= isam_info->nextpos; - } - - for (;;) - { - isam_info->update&= HA_STATE_CHANGED; - if ((error=(*isam_info->s->read_rnd)(isam_info,(byte*) buf, - filepos,1)) >= 0 || - my_errno != HA_ERR_END_OF_FILE) - return (error); - if (info->cache_in_use) - nisam_extra(info->current_table->table,HA_EXTRA_NO_CACHE); - if (info->current_table+1 == info->end_table) - return(-1); - info->current_table++; - info->last_used_table=info->current_table; - if (info->cache_in_use) - nisam_extra(info->current_table->table,HA_EXTRA_CACHE); - info->current_table->file_offset= - info->current_table[-1].file_offset+ - info->current_table[-1].table->s->state.data_file_length; - - isam_info=info->current_table->table; - filepos=isam_info->s->pack.header_length; - isam_info->lastinx= (uint) -1; - } - } - info->current_table=find_table(info->open_tables, - info->end_table-1,filepos); - isam_info=info->current_table->table; - isam_info->update&= HA_STATE_CHANGED; - return ((*isam_info->s->read_rnd)(isam_info,(byte*) buf, - (ulong) (filepos - - info->current_table->file_offset), - 0)); -} - - - /* Find which table to use according to file-pos */ - -static MRG_TABLE *find_table(MRG_TABLE *start,MRG_TABLE *end,mrg_off_t pos) -{ - MRG_TABLE *mid; - - while (start != end) - { - mid=start+((uint) (end-start)+1)/2; - if (mid->file_offset > pos) - end=mid-1; - else - start=mid; - } - return start; -} diff --git a/merge/rsame.c b/merge/rsame.c deleted file mode 100644 index 4ebf25b21c1..00000000000 --- a/merge/rsame.c +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include "mrgdef.h" - - -int mrg_rsame( -MRG_INFO *info, -byte *record, -int inx) /* not used, should be 0 */ -{ - if (inx) - { - my_errno=HA_ERR_WRONG_INDEX; - return(-1); - } - if (!info->current_table) - { - my_errno=HA_ERR_NO_ACTIVE_RECORD; - return(-1); - } - return nisam_rsame(info->current_table->table,record,inx); -} diff --git a/merge/static.c b/merge/static.c deleted file mode 100644 index e5f95ef195a..00000000000 --- a/merge/static.c +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* - Static variables for pisam library. All definied here for easy making of - a shared library -*/ - -#ifndef stdin -#include "mrgdef.h" -#endif - -LIST *mrg_open_list=0; diff --git a/merge/update.c b/merge/update.c deleted file mode 100644 index 9fcb82089e4..00000000000 --- a/merge/update.c +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Update last read record */ - -#include "mrgdef.h" - -int mrg_update( -register MRG_INFO *info, -const byte *oldrec, const byte *newrec) -{ - if (!info->current_table) - { - my_errno=HA_ERR_NO_ACTIVE_RECORD; - return(-1); - } - return nisam_update(info->current_table->table,oldrec,newrec); -} diff --git a/myisam/myisamlog.c b/myisam/myisamlog.c index fb199c22765..2d4c7570956 100644 --- a/myisam/myisamlog.c +++ b/myisam/myisamlog.c @@ -404,11 +404,7 @@ static int examine_log(my_string file_name, char **table_names) } to=isam_file_name; if (filepath) - { - strmov(isam_file_name,filepath); - convert_dirname(isam_file_name); - to=strend(isam_file_name); - } + to=convert_dirname(isam_file_name,filepath,NullS); strmov(to,pos); fn_ext(isam_file_name)[0]=0; /* Remove extension */ } diff --git a/myisammrg/Makefile.am b/myisammrg/Makefile.am index 8b05bc5f386..5355534eb77 100644 --- a/myisammrg/Makefile.am +++ b/myisammrg/Makefile.am @@ -16,7 +16,7 @@ INCLUDES = @MT_INCLUDES@ -I$(srcdir)/../include -I../include pkglib_LIBRARIES = libmyisammrg.a -noinst_HEADERS = mymrgdef.h +noinst_HEADERS = myrg_def.h libmyisammrg_a_SOURCES = myrg_open.c myrg_extra.c myrg_info.c myrg_locking.c \ myrg_rrnd.c myrg_update.c myrg_delete.c myrg_rsame.c \ myrg_panic.c myrg_close.c myrg_create.c myrg_static.c \ diff --git a/myisammrg/mymrgdef.h b/myisammrg/mymrgdef.h deleted file mode 100644 index aae1d07cd64..00000000000 --- a/myisammrg/mymrgdef.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - 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 is included by all myisam-merge files */ - -#ifndef N_MAXKEY -#include "../myisam/myisamdef.h" -#endif - -#include "myisammrg.h" - -extern LIST *myrg_open_list; - -#ifdef THREAD -extern pthread_mutex_t THR_LOCK_open; -#endif - -int _myrg_init_queue(MYRG_INFO *info,int inx,enum ha_rkey_function search_flag); diff --git a/myisammrg/myrg_close.c b/myisammrg/myrg_close.c index 7ab73c5ded4..8ac1c4d8005 100644 --- a/myisammrg/myrg_close.c +++ b/myisammrg/myrg_close.c @@ -16,7 +16,7 @@ /* close a isam-database */ -#include "mymrgdef.h" +#include "myrg_def.h" int myrg_close(MYRG_INFO *info) { diff --git a/myisammrg/myrg_create.c b/myisammrg/myrg_create.c index d1ea018741d..c320a595e80 100644 --- a/myisammrg/myrg_create.c +++ b/myisammrg/myrg_create.c @@ -16,7 +16,7 @@ /* Create a MYMERGE_-file */ -#include "mymrgdef.h" +#include "myrg_def.h" /* create file named 'name' and save filenames in it table_names should be NULL or a vector of string-pointers with diff --git a/myisammrg/myrg_def.h b/myisammrg/myrg_def.h new file mode 100644 index 00000000000..aae1d07cd64 --- /dev/null +++ b/myisammrg/myrg_def.h @@ -0,0 +1,31 @@ +/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + 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 is included by all myisam-merge files */ + +#ifndef N_MAXKEY +#include "../myisam/myisamdef.h" +#endif + +#include "myisammrg.h" + +extern LIST *myrg_open_list; + +#ifdef THREAD +extern pthread_mutex_t THR_LOCK_open; +#endif + +int _myrg_init_queue(MYRG_INFO *info,int inx,enum ha_rkey_function search_flag); diff --git a/myisammrg/myrg_delete.c b/myisammrg/myrg_delete.c index 9ac32655172..4085c435416 100644 --- a/myisammrg/myrg_delete.c +++ b/myisammrg/myrg_delete.c @@ -16,7 +16,7 @@ /* Delete last read record */ -#include "mymrgdef.h" +#include "myrg_def.h" int myrg_delete( MYRG_INFO *info, diff --git a/myisammrg/myrg_extra.c b/myisammrg/myrg_extra.c index c8a634e748f..315abe0f29e 100644 --- a/myisammrg/myrg_extra.c +++ b/myisammrg/myrg_extra.c @@ -20,7 +20,7 @@ record-cache-flags are set in myrg_rrnd when we are changing database. */ -#include "mymrgdef.h" +#include "myrg_def.h" int myrg_extra(MYRG_INFO *info,enum ha_extra_function function) { diff --git a/myisammrg/myrg_info.c b/myisammrg/myrg_info.c index 8ca830339b9..14bc228cc1f 100644 --- a/myisammrg/myrg_info.c +++ b/myisammrg/myrg_info.c @@ -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 */ -#include "mymrgdef.h" +#include "myrg_def.h" ulonglong myrg_position(MYRG_INFO *info) { diff --git a/myisammrg/myrg_locking.c b/myisammrg/myrg_locking.c index c89acca3918..70eb2c94d13 100644 --- a/myisammrg/myrg_locking.c +++ b/myisammrg/myrg_locking.c @@ -18,7 +18,7 @@ Lock databases against read or write. */ -#include "mymrgdef.h" +#include "myrg_def.h" int myrg_lock_database( MYRG_INFO *info, diff --git a/myisammrg/myrg_open.c b/myisammrg/myrg_open.c index 60523c90ff4..c5f1330d3e4 100644 --- a/myisammrg/myrg_open.c +++ b/myisammrg/myrg_open.c @@ -16,7 +16,7 @@ /* open a MyISAM MERGE table */ -#include "mymrgdef.h" +#include "myrg_def.h" #include #include #ifdef VMS diff --git a/myisammrg/myrg_panic.c b/myisammrg/myrg_panic.c index 99a1f6828d1..67d2ee8bb19 100644 --- a/myisammrg/myrg_panic.c +++ b/myisammrg/myrg_panic.c @@ -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 */ -#include "mymrgdef.h" +#include "myrg_def.h" /* if flag == HA_PANIC_CLOSE then all misam files are closed */ /* if flag == HA_PANIC_WRITE then all misam files are unlocked and diff --git a/myisammrg/myrg_queue.c b/myisammrg/myrg_queue.c index d6f831db48c..b4f729fc2cf 100644 --- a/myisammrg/myrg_queue.c +++ b/myisammrg/myrg_queue.c @@ -16,7 +16,7 @@ /* Read record based on a key */ -#include "mymrgdef.h" +#include "myrg_def.h" static int queue_key_cmp(void *keyseg, byte *a, byte *b) { diff --git a/myisammrg/myrg_rfirst.c b/myisammrg/myrg_rfirst.c index 0625e848660..2ee9c015a84 100644 --- a/myisammrg/myrg_rfirst.c +++ b/myisammrg/myrg_rfirst.c @@ -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 */ -#include "mymrgdef.h" +#include "myrg_def.h" /* Read first row according to specific key */ diff --git a/myisammrg/myrg_rkey.c b/myisammrg/myrg_rkey.c index cd2c73c8ec2..ba042352a51 100644 --- a/myisammrg/myrg_rkey.c +++ b/myisammrg/myrg_rkey.c @@ -27,7 +27,7 @@ */ -#include "mymrgdef.h" +#include "myrg_def.h" /* todo: we could store some additional info to speedup lookups: column (key, keyseg) can be constant per table diff --git a/myisammrg/myrg_rlast.c b/myisammrg/myrg_rlast.c index f41844dfd5c..e03a07c295a 100644 --- a/myisammrg/myrg_rlast.c +++ b/myisammrg/myrg_rlast.c @@ -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 */ -#include "mymrgdef.h" +#include "myrg_def.h" /* Read last row with the same key as the previous read. */ diff --git a/myisammrg/myrg_rnext.c b/myisammrg/myrg_rnext.c index 5a3fbdfb299..abb9ef95e44 100644 --- a/myisammrg/myrg_rnext.c +++ b/myisammrg/myrg_rnext.c @@ -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 */ -#include "mymrgdef.h" +#include "myrg_def.h" /* Read next row with the same key as previous read diff --git a/myisammrg/myrg_rprev.c b/myisammrg/myrg_rprev.c index d8089e80498..bd7e6a1f6d2 100644 --- a/myisammrg/myrg_rprev.c +++ b/myisammrg/myrg_rprev.c @@ -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 */ -#include "mymrgdef.h" +#include "myrg_def.h" /* Read previous row with the same key as previous read diff --git a/myisammrg/myrg_rrnd.c b/myisammrg/myrg_rrnd.c index de731e58d5b..d50d077e6ba 100644 --- a/myisammrg/myrg_rrnd.c +++ b/myisammrg/myrg_rrnd.c @@ -19,7 +19,7 @@ get by myrg_info(). The next record can be read with pos= -1 */ -#include "mymrgdef.h" +#include "myrg_def.h" static MYRG_TABLE *find_table(MYRG_TABLE *start,MYRG_TABLE *end,ulonglong pos); diff --git a/myisammrg/myrg_rsame.c b/myisammrg/myrg_rsame.c index 301b96e667b..eeb270a1b37 100644 --- a/myisammrg/myrg_rsame.c +++ b/myisammrg/myrg_rsame.c @@ -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 */ -#include "mymrgdef.h" +#include "myrg_def.h" int myrg_rsame(MYRG_INFO *info,byte *record,int inx) { diff --git a/myisammrg/myrg_static.c b/myisammrg/myrg_static.c index d667c5a5475..fdc1c89c439 100644 --- a/myisammrg/myrg_static.c +++ b/myisammrg/myrg_static.c @@ -20,7 +20,7 @@ */ #ifndef stdin -#include "mymrgdef.h" +#include "myrg_def.h" #endif LIST *myrg_open_list=0; diff --git a/myisammrg/myrg_update.c b/myisammrg/myrg_update.c index b75c6ea6f9b..8417554727b 100644 --- a/myisammrg/myrg_update.c +++ b/myisammrg/myrg_update.c @@ -16,7 +16,7 @@ /* Update last read record */ -#include "mymrgdef.h" +#include "myrg_def.h" int myrg_update(register MYRG_INFO *info,const byte *oldrec, byte *newrec) { diff --git a/myisammrg/myrg_write.c b/myisammrg/myrg_write.c index b1b0b33f73d..8d8f4a34d18 100644 --- a/myisammrg/myrg_write.c +++ b/myisammrg/myrg_write.c @@ -16,7 +16,7 @@ /* Write a row to a MyISAM MERGE table */ -#include "mymrgdef.h" +#include "myrg_def.h" int myrg_write(register MYRG_INFO *info, byte *rec) { diff --git a/mysql-test/include/master-slave.inc b/mysql-test/include/master-slave.inc index 61077f898f6..c7c37fd01d3 100644 --- a/mysql-test/include/master-slave.inc +++ b/mysql-test/include/master-slave.inc @@ -1,7 +1,7 @@ -connect (master,localhost,root,,test,0,mysql-master.sock); -connect (master1,localhost,root,,test,0,mysql-master.sock); -connect (slave,localhost,root,,test,0,mysql-slave.sock); -connect (slave1,localhost,root,,test,0,mysql-slave.sock); +connect (master,localhost,root,,test,0,master.sock); +connect (master1,localhost,root,,test,0,master.sock); +connect (slave,localhost,root,,test,0,slave.sock); +connect (slave1,localhost,root,,test,0,slave.sock); connection slave; !slave stop; @r/slave-stopped.result show status like 'Slave_running'; diff --git a/mysql-test/include/not_embedded.inc b/mysql-test/include/not_embedded.inc new file mode 100644 index 00000000000..7d6fdbf9768 --- /dev/null +++ b/mysql-test/include/not_embedded.inc @@ -0,0 +1,3 @@ +-- require r/not_embedded.require +select version() like "%embedded%" as "have_embedded"; + diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index ffc07784b7a..478df5acd3f 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -789,10 +789,10 @@ run_testcase () if [ -f $tf ] ; then $RM -f r/$tname.*reject mysql_test_args="-R r/$tname.result $EXTRA_MYSQL_TEST_OPT" - if [ -z "$DO_CLIENT_GDB" ] ; then - mytime=`$TIME -p $MYSQL_TEST $mysql_test_args < $tf 2> $TIMEFILE` + if [ -z "$DO_CLIENT_GDB" ] ; then + mytime=`$TIME -p $MYSQL_TEST $mysql_test_args < $tf 2> $TIMEFILE` else - do_gdb_test "$mysql_test_args" "$tf" + do_gdb_test "$mysql_test_args" "$tf" fi res=$? diff --git a/mysql-test/r/auto_increment.result b/mysql-test/r/auto_increment.result index bf6265e5b64..eadb0bb0d34 100644 --- a/mysql-test/r/auto_increment.result +++ b/mysql-test/r/auto_increment.result @@ -9,18 +9,6 @@ a b c 5 5 NULL 8 8 8 9 9 9 -a b -1 1 -5 5 -3 3 -4 4 -6 6 -a b c -1 1 NULL -5 5 NULL -3 3 NULL -4 4 NULL -6 6 6 skey sval 1 hello 2 hey diff --git a/mysql-test/r/func_system.result b/mysql-test/r/func_system.result index c6ec28bfd34..5f5dc178bfc 100644 --- a/mysql-test/r/func_system.result +++ b/mysql-test/r/func_system.result @@ -1,4 +1,4 @@ -database() user() -test root@localhost +database() user() like "%@%" +test 1 version()>="3.23.29" 1 diff --git a/mysql-test/r/isam.result b/mysql-test/r/isam.result index ba12ca05feb..c5b333e06fe 100644 --- a/mysql-test/r/isam.result +++ b/mysql-test/r/isam.result @@ -8,3 +8,41 @@ Table Op Msg_type Msg_text test.t1 repair status OK Table Op Msg_type Msg_text test.t1 check status OK +a b +1 1 +5 5 +3 3 +4 4 +6 6 +a b c +1 1 NULL +5 5 NULL +3 3 NULL +4 4 NULL +6 6 6 +Table Op Msg_type Msg_text +test.t1 optimize status OK +Table Op Msg_type Msg_text +test.t1 check status OK +test.t2 check error The handler for the table doesn't support check/repair +Table Op Msg_type Msg_text +test.t1 repair status OK +test.t2 repair error The handler for the table doesn't support check/repair +Table Op Msg_type Msg_text +test.t2 check error The handler for the table doesn't support check/repair +test.t1 check status OK +Table Op Msg_type Msg_text +test.t2 check error Table 't2' was not locked with LOCK TABLES +test.t1 check status OK +Field Type Null Key Default Extra +a int(11) PRI 0 +b int(11) MUL 0 +c int(11) 0 +Field Type Null Key Default Extra Privileges +a int(11) PRI 0 select,insert,update,references +b int(11) MUL 0 select,insert,update,references +c int(11) 0 select,insert,update,references +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment +t1 0 PRIMARY 1 a A 4 NULL NULL +t1 1 b 1 b A 1 NULL NULL +t1 1 b 2 c A 4 NULL NULL diff --git a/mysql-test/r/lock.result b/mysql-test/r/lock.result index ccd3c02558d..7b1be604024 100644 --- a/mysql-test/r/lock.result +++ b/mysql-test/r/lock.result @@ -4,7 +4,3 @@ Table Op Msg_type Msg_text test.t1 check status OK Table Op Msg_type Msg_text test.t2 check error Table 't2' was not locked with LOCK TABLES -n -4 -n -1 diff --git a/mysql-test/r/lock_multi.result b/mysql-test/r/lock_multi.result new file mode 100644 index 00000000000..d75d9aa0216 --- /dev/null +++ b/mysql-test/r/lock_multi.result @@ -0,0 +1,4 @@ +n +4 +n +1 diff --git a/mysql-test/r/not_embedded.require b/mysql-test/r/not_embedded.require new file mode 100644 index 00000000000..b2ea98bcd0a --- /dev/null +++ b/mysql-test/r/not_embedded.require @@ -0,0 +1,2 @@ +have_embedded +0 diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index 2e323f73793..8e273872704 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -1,30 +1,4 @@ Table Op Msg_type Msg_text -test.t1 optimize status OK -Table Op Msg_type Msg_text -test.t1 check status OK -test.t2 check error The handler for the table doesn't support check/repair -Table Op Msg_type Msg_text -test.t1 repair status OK -test.t2 repair error The handler for the table doesn't support check/repair -Table Op Msg_type Msg_text -test.t2 check error The handler for the table doesn't support check/repair -test.t1 check status OK -Table Op Msg_type Msg_text -test.t2 check error Table 't2' was not locked with LOCK TABLES -test.t1 check status OK -Field Type Null Key Default Extra -a int(11) PRI 0 -b int(11) MUL 0 -c int(11) 0 -Field Type Null Key Default Extra Privileges -a int(11) PRI 0 select,insert,update,references -b int(11) MUL 0 select,insert,update,references -c int(11) 0 select,insert,update,references -Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment -t1 0 PRIMARY 1 a A 4 NULL NULL -t1 1 b 1 b A 1 NULL NULL -t1 1 b 2 c A 4 NULL NULL -Table Op Msg_type Msg_text test.t1 check status Table is already up to date Table Op Msg_type Msg_text test.t1 check status Table is already up to date diff --git a/mysql-test/t/auto_increment.test b/mysql-test/t/auto_increment.test index b9b8c244699..d86466572d8 100644 --- a/mysql-test/t/auto_increment.test +++ b/mysql-test/t/auto_increment.test @@ -2,6 +2,7 @@ # Test of auto_increment; The test for BDB tables is in bdb.test # +drop table if exists t1; create table t1 (a int not null auto_increment,b int, primary key (a)) type=myisam auto_increment=3; insert into t1 values (1,1),(NULL,3),(NULL,4); delete from t1 where a=4; @@ -18,20 +19,6 @@ insert into t1 values (NULL,9,9); select * from t1; drop table t1; -create table t1 (a int not null auto_increment,b int, primary key (a)) type=isam; -insert into t1 values (1,1),(NULL,2),(3,3),(NULL,4); -delete from t1 where a=4 or a=2; -insert into t1 values (NULL,4),(NULL,5),(6,6); -select * from t1; -delete from t1 where a=6; -#show table status like "t1"; -replace t1 values (3,1); -replace t1 values (3,3); -ALTER TABLE t1 add c int; -insert into t1 values (NULL,6,6); -select * from t1; -drop table t1; - create table t1 ( skey tinyint unsigned NOT NULL auto_increment PRIMARY KEY, sval char(20) diff --git a/mysql-test/t/backup.test b/mysql-test/t/backup.test index 43ea6fd19ad..c622522c870 100644 --- a/mysql-test/t/backup.test +++ b/mysql-test/t/backup.test @@ -39,9 +39,3 @@ reap; unlock tables; connection con1; reap; - - - - - - diff --git a/mysql-test/t/count_distinct2-master.opt b/mysql-test/t/count_distinct2-master.opt index 8f1be6dce3a..d81cc55090d 100644 --- a/mysql-test/t/count_distinct2-master.opt +++ b/mysql-test/t/count_distinct2-master.opt @@ -1 +1 @@ --O max_heap_table_size=16384 +--set-variable=max_heap_table_size=16384 diff --git a/mysql-test/t/count_distinct2.test b/mysql-test/t/count_distinct2.test index 33d4cf54278..073b83a40b4 100644 --- a/mysql-test/t/count_distinct2.test +++ b/mysql-test/t/count_distinct2.test @@ -1,3 +1,5 @@ +drop table if exists t1; + create table t1(n1 int, n2 int, s char(20), vs varchar(20), t text); insert into t1 values (1,11, 'one','eleven', 'eleven'), (1,11, 'one','eleven', 'eleven'), @@ -44,7 +46,7 @@ select count(distinct n1), count(distinct n2) from t1; select count(distinct n2), n1 from t1 group by n1; drop table t1; -# test the converstion from tree to MyISAM +# test the conversion from tree to MyISAM create table t1 (n int default NULL); let $1=5000; while ($1) diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index d45d013c9fb..3eb4f35bdc2 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -25,14 +25,10 @@ drop table if exists t1,t2; !$1164 create table t1 (a int not null auto_increment,primary key (a)) type=heap; !$1163 create table t1 (a int not null,b text) type=heap; !$1171 create table t1 (a int ,primary key(a)) type=heap; -!$1121 create table t1 (a int,b text, index(a)) type=isam; -!$1073 create table t1 (a int,b text, index(b)) type=isam; drop table if exists t1; -!$1075 create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ord,ordid)) type=isam; !$1164 create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ord,ordid)) type=heap; !$1171 create table t1 (ordid int(8), primary key (ordid)); -!$1121 create table t1 (ordid int(8), unique (ordid)) type=isam; -- error 1044,1 create table not_existing_database.test (a int); diff --git a/mysql-test/t/flush.test b/mysql-test/t/flush.test index 4491de1f82b..2f16212e3fc 100644 --- a/mysql-test/t/flush.test +++ b/mysql-test/t/flush.test @@ -1,3 +1,11 @@ +# This test doesn't work with the embedded version as this code +# assumes that one query is running while we are doing queries on +# a second connection. +# This would work if mysqltest run would be threaded and handle each +# connection in a separate thread. +# +-- source include/not_embedded.inc + connect (con1,localhost,root,,); connect (con2,localhost,root,,); connection con1; diff --git a/mysql-test/t/func_system.test b/mysql-test/t/func_system.test index b0bdbe472dd..052e0530cf6 100644 --- a/mysql-test/t/func_system.test +++ b/mysql-test/t/func_system.test @@ -2,5 +2,5 @@ # system functions # -select database(),user(); +select database(),user() like "%@%"; select version()>="3.23.29"; diff --git a/mysql-test/t/isam.test b/mysql-test/t/isam.test index 1cf068b42ba..60999aa641e 100644 --- a/mysql-test/t/isam.test +++ b/mysql-test/t/isam.test @@ -1,3 +1,7 @@ +-- source include/have_isam.inc + +drop table if exists t1,t2; + # # Test possible problem with rows that are about 65535 bytes long # @@ -17,3 +21,48 @@ check table t1; repair table t1; check table t1; drop table t1; + +# +# Test of auto_increment; The test for BDB tables is in bdb.test +# + +create table t1 (a int not null auto_increment,b int, primary key (a)) type=isam; +insert into t1 values (1,1),(NULL,2),(3,3),(NULL,4); +delete from t1 where a=4 or a=2; +insert into t1 values (NULL,4),(NULL,5),(6,6); +select * from t1; +delete from t1 where a=6; +#show table status like "t1"; +replace t1 values (3,1); +replace t1 values (3,3); +ALTER TABLE t1 add c int; +insert into t1 values (NULL,6,6); +select * from t1; +drop table t1; + +# +# Test of some CREATE TABLE's that should fail +# +!$1121 create table t1 (a int,b text, index(a)) type=isam; +!$1073 create table t1 (a int,b text, index(b)) type=isam; +!$1075 create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ord,ordid)) type=isam; +!$1121 create table t1 (ordid int(8), unique (ordid)) type=isam; +drop table if exists t1; + +# +# Test of some show commands +# + +create table t1 (a int not null primary key, b int not null,c int not null, key(b,c)); +insert into t1 values (1,2,2),(2,2,3),(3,2,4),(4,2,4); +create table t2 type=isam select * from t1; +optimize table t1; +check table t1,t2; +repair table t1,t2; +check table t2,t1; +lock tables t1 write; +check table t2,t1; +show columns from t1; +show full columns from t1; +show index from t1; +drop table t1,t2; diff --git a/mysql-test/t/kill.test b/mysql-test/t/kill.test index be6860a3cc3..6bcc43ac916 100644 --- a/mysql-test/t/kill.test +++ b/mysql-test/t/kill.test @@ -1,3 +1,11 @@ +# This test doesn't work with the embedded version as this code +# assumes that one query is running while we are doing queries on +# a second connection. +# This would work if mysqltest run would be threaded and handle each +# connection in a separate thread. +# +-- source include/not_embedded.inc + connect (con1, localhost, root,,); connect (con2, localhost, root,,); diff --git a/mysql-test/t/lock.test b/mysql-test/t/lock.test index 77354e63252..385713174d2 100644 --- a/mysql-test/t/lock.test +++ b/mysql-test/t/lock.test @@ -53,45 +53,3 @@ lock tables t1 write; check table t2; unlock tables; drop table t1,t2; - -#test to see if select will get the lock ahead of low priority update -connect (locker,localhost,root,,); -connect (reader,localhost,root,,); -connect (writer,localhost,root,,); - -connection locker; -create table t1(n int); -insert into t1 values (1); -lock tables t1 write; -connection writer; -send update low_priority t1 set n = 4; -connection reader; ---sleep 2 -send select n from t1; -connection locker; ---sleep 2 -unlock tables; -connection writer; -reap; -connection reader; -reap; -drop table t1; - -connection locker; -create table t1(n int); -insert into t1 values (1); -lock tables t1 read; -connection writer; -send update low_priority t1 set n = 4; -connection reader; ---sleep 2 -send select n from t1; -connection locker; ---sleep 2 -unlock tables; -connection writer; -reap; -connection reader; -reap; -drop table t1; - diff --git a/mysql-test/t/lock_multi.test b/mysql-test/t/lock_multi.test new file mode 100644 index 00000000000..53e9fd3393c --- /dev/null +++ b/mysql-test/t/lock_multi.test @@ -0,0 +1,49 @@ +# This test doesn't work with the embedded version as this code +# assumes that one query is running while we are doing queries on +# a second connection. +# This would work if mysqltest run would be threaded and handle each +# connection in a separate thread. +# +-- source include/not_embedded.inc + +#test to see if select will get the lock ahead of low priority update + +connect (locker,localhost,root,,); +connect (reader,localhost,root,,); +connect (writer,localhost,root,,); + +connection locker; +create table t1(n int); +insert into t1 values (1); +lock tables t1 write; +connection writer; +send update low_priority t1 set n = 4; +connection reader; +--sleep 2 +send select n from t1; +connection locker; +--sleep 2 +unlock tables; +connection writer; +reap; +connection reader; +reap; +drop table t1; + +connection locker; +create table t1(n int); +insert into t1 values (1); +lock tables t1 read; +connection writer; +send update low_priority t1 set n = 4; +connection reader; +--sleep 2 +send select n from t1; +connection locker; +--sleep 2 +unlock tables; +connection writer; +reap; +connection reader; +reap; +drop table t1; diff --git a/mysql-test/t/order_fill_sortbuf-master.opt b/mysql-test/t/order_fill_sortbuf-master.opt index af4e7d33143..116494d4588 100644 --- a/mysql-test/t/order_fill_sortbuf-master.opt +++ b/mysql-test/t/order_fill_sortbuf-master.opt @@ -1 +1 @@ --O sort_buffer=0 +--set-variable=sort_buffer=0 diff --git a/mysql-test/t/rpl000015.test b/mysql-test/t/rpl000015.test index 73a10bed7b3..c8711a77bd6 100644 --- a/mysql-test/t/rpl000015.test +++ b/mysql-test/t/rpl000015.test @@ -1,5 +1,5 @@ -connect (master,localhost,root,,test,0,mysql-master.sock); -connect (slave,localhost,root,,test,0, mysql-slave.sock); +connect (master,localhost,root,,test,0,master.sock); +connect (slave,localhost,root,,test,0, slave.sock); connection master; reset master; show master status; diff --git a/mysql-test/t/rpl000016.test b/mysql-test/t/rpl000016.test index 7b46bc75498..f0a6842c75d 100644 --- a/mysql-test/t/rpl000016.test +++ b/mysql-test/t/rpl000016.test @@ -1,5 +1,5 @@ -connect (master,localhost,root,,test,0,mysql-master.sock); -connect (slave,localhost,root,,test,0,mysql-slave.sock); +connect (master,localhost,root,,test,0,master.sock); +connect (slave,localhost,root,,test,0,slave.sock); system cat /dev/null > var/slave-data/master.info; system chmod 000 var/slave-data/master.info; connection slave; diff --git a/mysql-test/t/rpl000017.test b/mysql-test/t/rpl000017.test index 8e4e61cb9d6..011b6507e49 100644 --- a/mysql-test/t/rpl000017.test +++ b/mysql-test/t/rpl000017.test @@ -1,5 +1,5 @@ -connect (master,localhost,root,,test,0,mysql-master.sock); -connect (slave,localhost,root,,test,0,mysql-slave.sock); +connect (master,localhost,root,,test,0,master.sock); +connect (slave,localhost,root,,test,0,slave.sock); connection master; reset master; grant file on *.* to replicate@localhost identified by 'aaaaaaaaaaaaaaab'; diff --git a/mysql-test/t/rpl000018.test b/mysql-test/t/rpl000018.test index 44236323d1d..a160853dbf3 100644 --- a/mysql-test/t/rpl000018.test +++ b/mysql-test/t/rpl000018.test @@ -1,5 +1,5 @@ -connect (master,localhost,root,,test,0,mysql-master.sock); -connect (slave,localhost,root,,test,0,mysql-slave.sock); +connect (master,localhost,root,,test,0,master.sock); +connect (slave,localhost,root,,test,0,slave.sock); connection slave; reset slave; slave start; diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test index 6bbad3dea59..56370b9ca85 100644 --- a/mysql-test/t/show_check.test +++ b/mysql-test/t/show_check.test @@ -1,21 +1,8 @@ # # Test of some show commands # -drop table if exists t1,t2; -create table t1 (a int not null primary key, b int not null,c int not null, key(b,c)); -insert into t1 values (1,2,2),(2,2,3),(3,2,4),(4,2,4); -create table t2 type=isam select * from t1; -optimize table t1; -check table t1,t2; -repair table t1,t2; -check table t2,t1; -lock tables t1 write; -check table t2,t1; -show columns from t1; -show full columns from t1; -show index from t1; -drop table t1,t2; +drop table if exists t1,t2; create table t1 (a int not null primary key, b int not null,c int not null, key(b,c)); insert into t1 values (1,2,2),(2,2,3),(3,2,4),(4,2,4); check table t1 type=fast; diff --git a/mysql-test/t/status.test b/mysql-test/t/status.test index bdfeb26073f..cffca437cf1 100644 --- a/mysql-test/t/status.test +++ b/mysql-test/t/status.test @@ -1,3 +1,11 @@ +# This test doesn't work with the embedded version as this code +# assumes that one query is running while we are doing queries on +# a second connection. +# This would work if mysqltest run would be threaded and handle each +# connection in a separate thread. +# +-- source include/not_embedded.inc + connect (con1,localhost,root,,); connect (con2,localhost,root,,); diff --git a/mysql-test/t/tablelock.test b/mysql-test/t/tablelock.test index c32a3f7cd35..fa8c4f03675 100644 --- a/mysql-test/t/tablelock.test +++ b/mysql-test/t/tablelock.test @@ -2,6 +2,7 @@ # Test of lock tables # +drop table if exists t1,t2; create table t1 ( n int auto_increment primary key); lock tables t1 write; insert into t1 values(NULL); @@ -36,12 +37,10 @@ drop table t1; CREATE TABLE t1 (a int); CREATE TABLE t2 (a int); lock tables t1 write,t1 as b write, t2 write, t2 as c read; -drop table t1; -drop table t2; +drop table t1,t2; CREATE TABLE t1 (a int); CREATE TABLE t2 (a int); lock tables t1 write,t1 as b write, t2 write, t2 as c read; -drop table t2; -drop table t1; +drop table t2,t1; unlock tables; diff --git a/mysys/Makefile.am b/mysys/Makefile.am index 2a9841975ed..19f60e49711 100644 --- a/mysys/Makefile.am +++ b/mysys/Makefile.am @@ -34,7 +34,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c\ my_error.c errors.c my_div.c my_messnc.c \ mf_format.c mf_same.c mf_dirname.c mf_fn_ext.c \ my_symlink.c my_symlink2.c \ - mf_pack.c mf_pack2.c mf_unixpath.c mf_stripp.c \ + mf_pack.c mf_unixpath.c mf_stripp.c \ mf_casecnv.c mf_soundex.c mf_wcomp.c mf_wfile.c \ mf_qsort.c mf_qsort2.c mf_sort.c \ ptr_cmp.c mf_radix.c queues.c \ diff --git a/mysys/charset.c b/mysys/charset.c index ddabb22539e..47eaf3587d5 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -103,7 +103,7 @@ char *get_charsets_dir(char *buf) strxmov(buf, DEFAULT_CHARSET_HOME, "/", sharedir, "/", CHARSET_DIR, NullS); } - convert_dirname(buf); + convert_dirname(buf,buf,NullS); DBUG_PRINT("info",("charsets dir='%s'", buf)); DBUG_RETURN(strend(buf)); } diff --git a/mysys/default.c b/mysys/default.c index e2e80f36a68..920a3a5e70b 100644 --- a/mysys/default.c +++ b/mysys/default.c @@ -231,11 +231,10 @@ static my_bool search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc, return 0; /* Ignore wrong paths */ if (dir) { - strmov(name,dir); - convert_dirname(name); + end=convert_dirname(name, dir, NullS); if (dir[0] == FN_HOMELIB) /* Add . to filenames in home */ - strcat(name,"."); - strxmov(strend(name),config_file,ext,NullS); + *end++='.'; + strxmov(end,config_file,ext,NullS); } else { @@ -369,16 +368,18 @@ void print_defaults(const char *conf_file, const char **groups) #endif for (dirs=default_directories ; *dirs; dirs++) { + const char *pos; + char *end; if (**dirs) - strmov(name,*dirs); + pos= *dirs; else if (defaults_extra_file) - strmov(name,defaults_extra_file); + pos= defaults_extra_file; else continue; - convert_dirname(name); + end=convert_dirname(name, pos, NullS); if (name[0] == FN_HOMELIB) /* Add . to filenames in home */ - strcat(name,"."); - strxmov(strend(name),conf_file,default_ext," ",NullS); + *end++='.'; + strxmov(end,conf_file,default_ext," ",NullS); fputs(name,stdout); } puts(""); diff --git a/mysys/mf_dirname.c b/mysys/mf_dirname.c index 399082a238b..fb5d77d8ab8 100644 --- a/mysys/mf_dirname.c +++ b/mysys/mf_dirname.c @@ -50,57 +50,69 @@ uint dirname_part(my_string to, const char *name) DBUG_PRINT("enter",("'%s'",name)); length=dirname_length(name); - (void) strmake(to,(char*) name,min(length,FN_REFLEN-2)); - convert_dirname(to); /* Convert chars */ + convert_dirname(to, name, name+length); DBUG_RETURN(length); } /* dirname */ - /* convert dirname to use under this system */ - /* If MSDOS converts '/' to '\' */ - /* If VMS converts '<' to '[' and '>' to ']' */ - /* Adds a '/' to end if there isn't one and the last isn't a dev_char */ - /* ARGSUSED */ + /* + Convert directory name to use under this system + If MSDOS converts '/' to '\' + If VMS converts '<' to '[' and '>' to ']' + Adds a FN_LIBCHAR to end if the result string if there isn't one + and the last isn't dev_char. + Copies data from 'from' until ASCII(0) for until from == from_end + If you want to use the whole 'from' string, just send NullS as the + last argument. + If the result string is larger than FN_REFLEN -1, then it's cut. + + Returns pointer to end \0 + */ #ifndef FN_DEVCHAR #define FN_DEVCHAR '\0' /* For easier code */ #endif -char *convert_dirname(my_string to) +char *convert_dirname(char *to, const char *from, const char *from_end) { - reg1 char *pos; -#ifdef FN_UPPER_CASE - caseup_str(to); -#endif -#ifdef FN_LOWER_CASE - casedn_str(to); -#endif -#if FN_LIBCHAR != '/' - { - pos=to-1; /* Change from '/' */ - while ((pos=strchr(pos+1,'/')) != 0) - *pos=FN_LIBCHAR; - } -#endif -#ifdef FN_C_BEFORE_DIR_2 + char *to_org=to; + + /* We use -2 here, becasue we need place for the last FN_LIBCHAR */ + if (!from_end || (from_end - from) > FN_REFLEN-2) + from_end=from+FN_REFLEN -2; + +#if FN_LIBCHAR != '/' || defined(FN_C_BEFORE_DIR_2) { - for (pos=to ; *pos ; pos++) + while (*from && *from != end) { - if (*pos == FN_C_BEFORE_DIR_2) - *pos=FN_C_BEFORE_DIR; - if (*pos == FN_C_AFTER_DIR_2) - *pos=FN_C_AFTER_DIR; + if (*from == '/') + *to++= FN_LIBCHAR; +#ifdef FN_C_BEFORE_DIR_2 + else if (*from == FN_C_BEFORE_DIR_2) + *to++= FN_C_BEFORE_DIR; + else if (*from == FN_C_AFTER_DIR_2) + *to++= FN_C_AFTER_DIR; +#endif + else + *to++= *from++; } } #else - { /* Append FN_LIBCHAR if not there */ - pos=strend(to); - if (pos != to && (pos[-1] != FN_LIBCHAR && pos[-1] != FN_DEVCHAR)) - { - *pos++=FN_LIBCHAR; - *pos=0; - } + /* This is ok even if to == from, becasue we need to cut the string */ + to= strmake(to, from, (uint) (from_end-from)); +#endif + + /* Add FN_LIBCHAR to the end of directory path */ + if (to != to_org && (to[-1] != FN_LIBCHAR && to[-1] != FN_DEVCHAR)) + { + *to++=FN_LIBCHAR; + *to=0; } +#ifdef FN_UPPER_CASE + caseup_str(to_org); +#endif +#ifdef FN_LOWER_CASE + casedn_str(to_org); #endif - return pos; /* Pointer to end of dir */ + return to; /* Pointer to end of dir */ } /* convert_dirname */ diff --git a/mysys/mf_format.c b/mysys/mf_format.c index 5063d6ca831..d7d2af608e8 100644 --- a/mysys/mf_format.c +++ b/mysys/mf_format.c @@ -18,64 +18,68 @@ #include "mysys_priv.h" #include - /* format a filename with replace of library and extension */ - /* params to and name may be identicall */ - /* function doesn't change name if name != to */ - /* Flag may be: 1 replace filenames library with 'dsk' */ - /* 2 replace extension with 'form' */ - /* 4 Unpack filename (replace ~ with home) */ - /* 8 Pack filename as short as possibly */ - /* 16 Resolve symbolic links for filename */ - /* 32 Resolve filename to full path */ - /* 64 Return NULL if too long path */ + /* + Formats a filename with possible replace of directory of extension + Function can handle the case where 'to' == 'name' + For a description of the flag values, consult my_sys.h + The arguments should be in unix format. + */ -my_string fn_format(my_string to, const char *name, const char *dsk, - const char *form, int flag) +my_string fn_format(my_string to, const char *name, const char *dir, + const char *extension, uint flag) { reg1 uint length; char dev[FN_REFLEN], buff[FN_REFLEN], *pos, *startpos; const char *ext; DBUG_ENTER("fn_format"); - DBUG_PRINT("enter",("name: %s dsk: %s form: %s flag: %d", - name,dsk,form,flag)); + DBUG_PRINT("enter",("name: %s dir: %s extension: %s flag: %d", + name,dir,extension,flag)); - /* Kopiera & skippa enheten */ + /* Copy and skip directory */ name+=(length=dirname_part(dev,(startpos=(my_string) name))); - if (length == 0 || flag & 1) + if (length == 0 || (flag & MY_REPLACE_DIR)) + { + /* Use given directory */ + convert_dirname(dev,dir,NullS); /* Fix to this OS */ + } + else if ((flag & MY_RELATIVE_PATH) && !test_if_hard_path(name)) { - (void) strmake(dev,dsk, sizeof(dev) - 2); - /* Use given directory */ - convert_dirname(dev); /* Fix to this OS */ + /* Put 'dir' before the given path */ + strmake(buff,dev,sizeof(buff)-1); + pos=convert_dirname(dev,dir,NullS); + strmake(pos,buff,sizeof(buff)-1- (int) (pos-dev)); } - if (flag & 8) + + if (flag & MY_PACK_FILENAME) pack_dirname(dev,dev); /* Put in ./.. and ~/.. */ - if (flag & 4) + if (flag & MY_UNPACK_FILENAME) (void) unpack_dirname(dev,dev); /* Replace ~/.. with dir */ - if ((pos=(char*)strchr(name,FN_EXTCHAR)) != NullS) + if ((pos= (char*) strchr(name,FN_EXTCHAR)) != NullS) { - if ((flag & 2) == 0) /* Skall vi byta extension ? */ + if ((flag & MY_REPLACE_EXT) == 0) /* If we should keep old ext */ { - length=strlength(name); /* Old extension */ + length=strlength(name); /* Use old extension */ ext = ""; } else { length=(uint) (pos-(char*) name); /* Change extension */ - ext= form; + ext= extension; } } else { - length=strlength(name); /* Har ingen ext- tag nya */ - ext=form; + length=strlength(name); /* No ext, use the now one */ + ext=extension; } if (strlen(dev)+length+strlen(ext) >= FN_REFLEN || length >= FN_LEN ) - { /* To long path, return original */ + { + /* To long path, return original or NULL */ uint tmp_length; - if (flag & 64) - return 0; + if (flag & MY_SAFE_PATH) + return NullS; tmp_length=strlength(startpos); DBUG_PRINT("error",("dev: '%s' ext: '%s' length: %d",dev,ext,length)); (void) strmake(to,startpos,min(tmp_length,FN_REFLEN-1)); @@ -96,9 +100,14 @@ my_string fn_format(my_string to, const char *name, const char *dsk, #endif (void) strmov(pos,ext); /* Don't convert extension */ } - if (flag & 32) - (void) my_realpath(to, to, MYF(flag & 32 ? 0 : MY_RESOLVE_LINK)); - else if (flag & 16) + /* + If MY_RETURN_REAL_PATH and MY_RESOLVE_SYMLINK is given, only do + realpath if the file is a symbolic link + */ + if (flag & MY_RETURN_REAL_PATH) + (void) my_realpath(to, to, MYF(flag & MY_RESOLVE_SYMLINKS ? + MY_RESOLVE_LINK: 0)); + else if (flag & MY_RESOLVE_SYMLINKS) { strmov(buff,to); (void) my_readlink(to, buff, MYF(0)); diff --git a/mysys/mf_pack.c b/mysys/mf_pack.c index 62394050261..c8b01ce700c 100644 --- a/mysys/mf_pack.c +++ b/mysys/mf_pack.c @@ -459,8 +459,7 @@ my_string intern_filename(my_string to, const char *from) my_string pos,from_pos,to_pos,end_pos; char buff[FN_REFLEN]; - (void) strmov(buff,from); - convert_dirname(buff); /* change '<>' to '[]' */ + convert_dirname(buff,from,NullS); /* change '<>' to '[]' */ from_pos=buff; if ((pos=strrchr(from_pos,FN_DEVCHAR))) /* Skipp device part */ { diff --git a/mysys/mf_pack2.c b/mysys/mf_pack2.c deleted file mode 100644 index 1cda7797457..00000000000 --- a/mysys/mf_pack2.c +++ /dev/null @@ -1,53 +0,0 @@ -/* 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 */ - -#include "mysys_priv.h" -#include - - /* Pack a filename for output on screen */ - /* Changes long paths to .../ */ - /* Removes pathname and extension */ - /* If not possibly to pack returns '?' in to and returns 1*/ - -int pack_filename(my_string to, const char *name, size_s max_length) - /* to may be name */ - -{ - int i; - char buff[FN_REFLEN]; - - if (strlen(fn_format(to,name,"","",0)) <= max_length) - return 0; - if (strlen(fn_format(to,name,"","",8)) <= max_length) - return 0; - if (strlen(fn_format(buff,name,".../","",1)) <= max_length) - { - VOID(strmov(to,buff)); - return 0; - } - for (i= 0 ; i < 3 ; i++) - { - if (strlen(fn_format(buff,to,"","", i == 0 ? 2 : i == 1 ? 1 : 3 )) - <= max_length) - { - VOID(strmov(to,buff)); - return 0; - } - } - to[0]='?'; to[1]=0; /* Can't pack filename */ - return 1; -} /* pack_filename */ diff --git a/mysys/mf_tempfile.c b/mysys/mf_tempfile.c index a724d22964d..d8a67990a52 100644 --- a/mysys/mf_tempfile.c +++ b/mysys/mf_tempfile.c @@ -101,8 +101,7 @@ File create_temp_file(char *to, const char *dir, const char *prefix, errno=my_errno= ENAMETOOLONG; return 1; } - strmov(to,dir); - strmov(convert_dirname(to),prefix_buff); + strmov(convert_dirname(to,dir,NullS),prefix_buff); org_file=mkstemp(to); file=my_register_filename(org_file, to, FILE_BY_MKSTEMP, EE_CANTCREATEFILE, MyFlags); diff --git a/scripts/Makefile.am b/scripts/Makefile.am index d2cca98ce63..c83a7e2315f 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -28,6 +28,7 @@ bin_SCRIPTS = @server_scripts@ \ mysql_find_rows \ mysqlhotcopy \ mysqldumpslow \ + mysql_explain_log \ mysqld_multi EXTRA_SCRIPTS = make_binary_distribution.sh \ @@ -43,6 +44,7 @@ EXTRA_SCRIPTS = make_binary_distribution.sh \ mysql_find_rows.sh \ mysqlhotcopy.sh \ mysqldumpslow.sh \ + mysql_explain_log.sh \ mysqld_multi.sh \ mysqld_safe.sh @@ -95,6 +97,8 @@ SUFFIXES = .sh -e 's!@''CXXFLAGS''@!@SAVE_CXXFLAGS@!'\ -e 's!@''LDFLAGS''@!@SAVE_LDFLAGS@!'\ -e 's!@''CLIENT_LIBS''@!@CLIENT_LIBS@!' \ + -e 's!@''LIBS''@!@LIBS@!' \ + -e 's!@''innodb_system_libs''@!@innodb_system_libs@!' \ -e 's!@''VERSION''@!@VERSION@!' \ -e 's!@''MYSQL_SERVER_SUFFIX''@!@MYSQL_SERVER_SUFFIX@!' \ -e 's!@''COMPILATION_COMMENT''@!@COMPILATION_COMMENT@!' \ diff --git a/scripts/mysql_config.sh b/scripts/mysql_config.sh index ed344f4b1e3..b2a09173760 100644 --- a/scripts/mysql_config.sh +++ b/scripts/mysql_config.sh @@ -31,16 +31,18 @@ client_libs='@CLIENT_LIBS@' libs="$ldflags -L'$pkglibdir' -lmysqlclient $client_libs" cflags="-I'$pkgincludedir'" +embedded_libs="$ldflags -L'$pkglibdir' -lmysqld @LIBS@ @innodb_system_libs@" usage () { cat <{host}=''; +$Param->{user}=''; +$Param->{password}=''; +$Param->{PrintError}=0; + +if (!GetOptions ('date|d:i' => \$Param->{ViewDate}, + 'host|h:s' => \$Param->{host}, + 'user|u:s' => \$Param->{user}, + 'password|p:s' => \$Param->{password}, + 'printerror|e:s' => \$Param->{PrintError}, + )) { + ShowOptions(); +} +else { + $Param->{UpdateCount} = 0; + $Param->{SelectCount} = 0; + $Param->{IdxUseCount} = 0; + $Param->{LineCount} = 0; + + $Param->{Init} = 0; + $Param->{Field} = 0; + $Param->{Refresh} = 0; + $Param->{QueryCount} = 0; + $Param->{Statistics} =0; + + $Param->{Query} = undef; + $Param->{ALL} = undef ; + $Param->{Comment} = undef ; + + @{$Param->{Rows}} = (qw|possible_keys key type|); + + if ($Param->{ViewDate}) { + $Param->{View} = 0; + } + else { + $Param->{View} = 1; + } + + #print "Date=$Param->{ViewDate}, host=$Param->{host}, user=$Param->{user}, password=$Param->{password}\n"; + + $Param->{dbh}=DBI->connect("DBI:mysql:host=$Param->{host}",$Param->{user},$Param->{password},{PrintError=>0}); + if (DBI::err()) { + print "Error: " . DBI::errstr() . "\n"; + } + else { + $Param->{Start} = time; + while() { + $Param->{LineCount} ++ ; + + if ($Param->{ViewDate} ) { + if (m/^(\d{6})\s+\d{1,2}:\d\d:\d\d\s.*$/) { # get date + #print "# $1 #\n"; + if ($1 == $Param->{ViewDate}) { + $Param->{View} = 1; + } + else { + $Param->{View} = 0; + } + } + } + if ($Param->{View} ) { + #print "->>>$_"; + + if (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Connect.+\s+on\s+(.*)$/i) { # get connection ID($2) and database($3) + #print "C-$1--$2--$3------\n"; + RunQuery($Param); + if (defined $3) { + $Param->{CID}->{$2} = $3 ; + #print "DB:$Param->{CID}->{$2} .. $2 .. $3 \n"; + } + } + + elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Connect.+$/i) { # get connection ID($2) and database($3) + #print "\n <<<<<<<<<<<<<<<<<<----------------------------<<<<<<<<<<<<<<<< \n"; + #print "Connect \n"; + RunQuery($Param); + } + elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Change user .*\s+on\s+(.*)$/i) { # get connection ID($2) and database($3) + #print "C-$1--$2--$3------\n"; + RunQuery($Param); + if (defined $3) { + $Param->{CID}->{$2} = $3 ; + #print "DB:$Param->{CID}->{$2} .. $2 .. $3 \n"; + } + } + + elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Quit\s+$/i) { # remove connection ID($2) and querystring + #print "Q-$1--$2--------\n"; + RunQuery($Param); + delete $Param->{CID}->{$2} ; + } + + elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Query\s+(select.+)$/i) { # get connection ID($2) and querystring + #print "S1-$1--$2--$3------\n"; + RunQuery($Param); + unless ($Param->{CID}->{$2}) { + #print "Error: No Database for Handle: $2 found\n"; + } + else { + $Param->{DB}=$Param->{CID}->{$2}; + + my $s = "$3"; + $s =~ s/from\s/from $Param->{DB}./i; + $Param->{Query}="EXPLAIN $s"; + + #$s =~ m/from\s+(\w+[.]\w+)/i; + #$Param->{tab} =$1; + #print "-- $Param->{tab} -- $s --\n"; + } + } + + elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Query\s+(update.+)$/i) { # get connection ID($2) and querystring + #print "S2--$1--$2--$3------\n"; + RunQuery($Param); + unless ($Param->{CID}->{$2}) { + #print "Error: No Database for Handle: $2 found\n"; + } + else { + $Param->{DB}=$Param->{CID}->{$2}; + + my $ud = $3; + $ud =~ m/^update\s+(\w+).+(where.+)$/i; + $Param->{Query} ="EXPLAIN SELECT * FROM $1 $2"; + $Param->{Query} =~ s/from\s/from $Param->{DB}./i; + + #$Param->{Query} =~ m/from\s+(\w+[.]\w+)/i; + #$Param->{tab} =$1; + } + } + + elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Statistics\s+(.*)$/i) { # get connection ID($2) and info? + $Param->{Statistics} ++; + #print "Statistics--$1--$2--$3------\n"; + RunQuery($Param); + } + elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Query\s+(.+)$/i) { # get connection ID($2) + $Param->{QueryCount} ++; + #print "Query-NULL $3\n"; + RunQuery($Param); + } + elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Refresh\s+(.+)$/i) { # get connection ID($2) + $Param->{Refresh} ++; + #print "Refresh\n"; + RunQuery($Param); + } + elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Init\s+(.+)$/i) { # get connection ID($2) + $Param->{Init} ++; + #print "Init $3\n"; + RunQuery($Param); + } + elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Field\s+(.+)$/i) { # get connection ID($2) + $Param->{Field} ++; + #print "Field $3\n"; + RunQuery($Param); + } + + elsif (m/^\s+(.+)$/ ) { # command could be some lines ... + #print "multi-lined ($1)\n"; + my ($A)=$1; + chomp $A; + $Param->{Query} .= " $1"; + #print "multi-lined ($1)<<$Param->{Query}>>\n"; + } + + + } + + } + + $Param->{dbh}->disconnect(); + + if (1 == 0) { + print "\nunclosed handles----------------------------------------\n"; + my $count=0; + foreach (sort keys %{$Param->{CID}}) { + print "$count | $_ : $Param->{CID}->{$_} \n"; + $count ++; + } + } + + print "\nIndex usage ------------------------------------\n"; + foreach my $t (sort keys %{$Param->{Data}}) { + print "\nTable\t$t: ---\n"; + foreach my $k (sort keys %{$Param->{Data}->{$t}}) { + print " count\t$k:\n"; + my %h = %{$Param->{Data}->{$t}->{$k}}; + foreach (sort {$h{$a} <=> $h{$b}} keys %h) { + print " $Param->{Data}->{$t}->{$k}->{$_}\t$_\n"; + } + } + } + + $Param->{AllCount}=0; + print "\nQueries causing table scans -------------------\n\n"; + foreach (@{$Param->{ALL}}) { + $Param->{AllCount} ++; + print "$_\n"; + } + print "Sum: $Param->{AllCount} table scans\n"; + + print "\nSummary ---------------------------------------\n\n"; + print "Select: \t$Param->{SelectCount} queries\n"; + print "Update: \t$Param->{UpdateCount} queries\n"; + print "\n"; + + print "Init: \t$Param->{Init} times\n"; + print "Field: \t$Param->{Field} times\n"; + print "Refresh: \t$Param->{Refresh} times\n"; + print "Query: \t$Param->{QueryCount} times\n"; + print "Statistics:\t$Param->{Statistics} times\n"; + print "\n"; + + print "Logfile: \t$Param->{LineCount} lines\n"; + print "Started: \t".localtime($Param->{Start})."\n"; + print "Finished: \t".localtime(time)."\n"; + + } +} + + +########################################################################### +# +# +# +sub RunQuery { + my $Param = shift ; + + if (defined $Param->{Query}) { + if (defined $Param->{DB} ) { + + $Param->{Query} =~ m/from\s+(\w+[.]\w+|\w+)/i; + $Param->{tab} =$1; + #print "||$Param->{tab} -- $Param->{Query}\n"; + + my $sth=$Param->{dbh}->prepare("USE $Param->{DB}"); + if (DBI::err()) { + if ($Param->{PrintError}) {print "Error: ".DBI::errstr()."\n";} + } + else { + $sth->execute(); + if (DBI::err()) { + if ($Param->{PrintError}) {print "Error: ".DBI::errstr()."\n";} + } + else { + $sth->finish(); + + $sth=$Param->{dbh}->prepare($Param->{Query}); + if (DBI::err()) { + if ($Param->{PrintError}) {print "Error: ".DBI::errstr()."\n";} + } + else { + #print "$Param->{Query}\n"; + $sth->execute(); + if (DBI::err()) { + if ($Param->{PrintError}) {print "[$Param->{LineCount}]<<$Param->{Query}>>\n";} + if ($Param->{PrintError}) {print "Error: ".DBI::errstr()."\n";} + } + else { + my $row = undef; + while ($row = $sth->fetchrow_hashref()) { + $Param->{SelectCount} ++; + + if (defined $row->{Comment}) { + push (@{$Param->{Comment}}, "$row->{Comment}; $_; $Param->{DB}; $Param->{Query}"); + } + foreach (@{$Param->{Rows}}) { + if (defined $row->{$_}) { + #if (($_ eq 'type' ) and ($row->{$_} eq 'ALL')) { + if ($row->{type} eq 'ALL') { + push (@{$Param->{ALL}}, "$row->{$_} $_ $Param->{DB} $Param->{Query}"); + #print ">> $row->{$_} $_ $Param->{DB} $Param->{Query}\n"; + } + $Param->{IdxUseCount} ++; + $Param->{Data}->{$Param->{tab}}->{$_}->{$row->{$_}} ++; + } + } + } + } + } + } + } + $sth->finish(); + } + $Param->{Query} = undef ; + } +} + +########################################################################### +# +# +# +sub ShowOptions { + print <, http://www.mobile.de + +=head1 RECRUITING + +If you are looking for a MySQL or Perl job, take a look at http://www.mobile.de +and send me an email with your resume (you must be speaking German!). + +=head1 SEE ALSO + +mysql documentation + +=cut diff --git a/sql/Makefile.am b/sql/Makefile.am index ea29aa2e5a7..b9289864b3f 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -29,7 +29,7 @@ WRAPLIBS= @WRAPLIBS@ SUBDIRS = share libexec_PROGRAMS = mysqld noinst_PROGRAMS = gen_lex_hash -gen_lex_hash_LDFLAGS = @NOINST_LDFLAGS@ +gen_lex_hash_LDFLAGS = @NOINST_LDFLAGS@ LDADD = ../isam/libnisam.a \ ../merge/libmerge.a \ ../myisam/libmyisam.a \ @@ -43,7 +43,7 @@ LDADD = ../isam/libnisam.a \ mysqld_LDADD = @MYSQLD_EXTRA_LDFLAGS@ \ @bdb_libs@ @innodb_libs@ @pstack_libs@ \ - @gemini_libs@ \ + @gemini_libs@ @innodb_system_libs@ \ $(LDADD) $(CXXLDFLAGS) $(WRAPLIBS) @LIBDL@ @openssl_libs@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ item_strfunc.h item_timefunc.h item_uniq.h \ diff --git a/sql/ha_innobase.cc b/sql/ha_innobase.cc index cb76c034749..e7d98dbe406 100644 --- a/sql/ha_innobase.cc +++ b/sql/ha_innobase.cc @@ -85,7 +85,7 @@ char *innobase_data_home_dir; char *innobase_log_group_home_dir, *innobase_log_arch_dir; char *innobase_unix_file_flush_method; bool innobase_flush_log_at_trx_commit, innobase_log_archive, - innobase_use_native_aio; + innobase_use_native_aio; /* Set default InnoDB size to 64M, to let users use InnoDB without having @@ -524,7 +524,6 @@ innobase_init(void) /*===============*/ /* out: TRUE if error */ { - static char current_dir[3]; int err; bool ret; @@ -537,11 +536,6 @@ innobase_init(void) srv_query_thread_priority = QUERY_PRIOR; } - /* Use current_dir if no paths are set */ - current_dir[0]=FN_CURLIB; - current_dir[1]=FN_LIBCHAR; - current_dir[2]=0; - /* Set InnoDB initialization parameters according to the values read from MySQL .cnf file */ @@ -550,10 +544,10 @@ innobase_init(void) MYF(MY_WME)); srv_data_home = (innobase_data_home_dir ? innobase_data_home_dir : - current_dir); + mysql_real_data_home); srv_logs_home = (char*) ""; srv_arch_dir = (innobase_log_arch_dir ? innobase_log_arch_dir : - current_dir); + mysql_real_data_home); ret = innobase_parse_data_file_paths_and_sizes(); @@ -563,7 +557,7 @@ innobase_init(void) } if (!innobase_log_group_home_dir) - innobase_log_group_home_dir= current_dir; + innobase_log_group_home_dir= mysql_real_data_home; ret = innobase_parse_log_group_home_dirs(); if (ret == FALSE) { @@ -591,6 +585,8 @@ innobase_init(void) srv_lock_wait_timeout = (ulint) innobase_lock_wait_timeout; + srv_print_verbose_log = mysql_embedded ? 0 : 1; + err = innobase_start_or_create_for_mysql(); if (err != DB_SUCCESS) { diff --git a/sql/ha_isam.cc b/sql/ha_isam.cc index 746fdd2f585..2451b8bdaec 100644 --- a/sql/ha_isam.cc +++ b/sql/ha_isam.cc @@ -20,6 +20,7 @@ #endif #include "mysql_priv.h" +#ifdef HAVE_ISAM #include #include #include "ha_isam.h" @@ -388,3 +389,4 @@ ha_rows ha_isam::records_in_range(int inx, end_key,end_key_len, end_search_flag); } +#endif /* HAVE_ISAM */ diff --git a/sql/ha_isammrg.cc b/sql/ha_isammrg.cc index dd2e4e2f723..41fb99fe867 100644 --- a/sql/ha_isammrg.cc +++ b/sql/ha_isammrg.cc @@ -20,11 +20,12 @@ #endif #include "mysql_priv.h" +#ifdef HAVE_ISAM #include #ifndef MASTER -#include "../srclib/merge/mrgdef.h" +#include "../srclib/merge/mrg_def.h" #else -#include "../merge/mrgdef.h" +#include "../merge/mrg_def.h" #endif #include "ha_isammrg.h" @@ -208,3 +209,4 @@ int ha_isammrg::create(const char *name, register TABLE *form, char buff[FN_REFLEN]; return mrg_create(fn_format(buff,name,"","",2+4+16),0); } +#endif /* HAVE_ISAM */ diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 36d06022d58..ea91a460182 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -374,14 +374,14 @@ int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt) char* backup_dir = thd->lex.backup_dir; char src_path[FN_REFLEN], dst_path[FN_REFLEN]; char* table_name = table->real_name; + int error; + const char* errmsg; DBUG_ENTER("restore"); - if (!fn_format(src_path, table_name, backup_dir, MI_NAME_DEXT, 4 + 64)) + if (fn_format_relative_to_data_home(src_path, table_name, backup_dir, + MI_NAME_DEXT)) DBUG_RETURN(HA_ADMIN_INVALID); - int error = 0; - const char* errmsg = ""; - if (my_copy(src_path, fn_format(dst_path, table->path, "", MI_NAME_DEXT, 4), MYF(MY_WME))) { @@ -404,7 +404,7 @@ int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt) param.db_name = table->table_cache_key; param.table_name = table->table_name; param.testflag = 0; - mi_check_print_error(¶m,errmsg, errno ); + mi_check_print_error(¶m,errmsg, my_errno); DBUG_RETURN(error); } } @@ -415,41 +415,47 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt) char* backup_dir = thd->lex.backup_dir; char src_path[FN_REFLEN], dst_path[FN_REFLEN]; char* table_name = table->real_name; - int error = 0; - const char* errmsg = ""; - - if (!fn_format(dst_path, table_name, backup_dir, reg_ext, 4 + 64)) - { - errmsg = "Failed in fn_format() for .frm file: errno = %d"; - error = HA_ADMIN_INVALID; - goto err; - } + int error; + const char *errmsg; + DBUG_ENTER("ha_myisam::backup"); + + if (fn_format_relative_to_data_home(dst_path, table_name, backup_dir, + reg_ext)) + { + errmsg = "Failed in fn_format() for .frm file: errno = %d"; + error = HA_ADMIN_INVALID; + goto err; + } - if (my_copy(fn_format(src_path, table->path,"", reg_ext, 4), - dst_path, - MYF(MY_WME | MY_HOLD_ORIGINAL_MODES ))) + if (my_copy(fn_format(src_path, table->path,"", reg_ext, MY_UNPACK_FILENAME), + dst_path, + MYF(MY_WME | MY_HOLD_ORIGINAL_MODES))) { error = HA_ADMIN_FAILED; errmsg = "Failed copying .frm file: errno = %d"; goto err; } - if (!fn_format(dst_path, table_name, backup_dir, MI_NAME_DEXT, 4 + 64)) - { - errmsg = "Failed in fn_format() for .MYD file: errno = %d"; - error = HA_ADMIN_INVALID; - goto err; - } + /* Change extension */ + if (!fn_format(dst_path, dst_path, "", MI_NAME_DEXT, + MY_REPLACE_EXT | MY_UNPACK_FILENAME | MY_SAFE_PATH)) + { + errmsg = "Failed in fn_format() for .MYD file: errno = %d"; + error = HA_ADMIN_INVALID; + goto err; + } - if (my_copy(fn_format(src_path, table->path,"", MI_NAME_DEXT, 4), + if (my_copy(fn_format(src_path, table->path,"", MI_NAME_DEXT, + MY_UNPACK_FILENAME), dst_path, - MYF(MY_WME | MY_HOLD_ORIGINAL_MODES )) ) - { - errmsg = "Failed copying .MYD file: errno = %d"; - error= HA_ADMIN_FAILED; - goto err; - } - return HA_ADMIN_OK; + MYF(MY_WME | MY_HOLD_ORIGINAL_MODES))) + { + errmsg = "Failed copying .MYD file: errno = %d"; + error= HA_ADMIN_FAILED; + goto err; + } + DBUG_RETURN(HA_ADMIN_OK); + err: { MI_CHECK param; @@ -459,8 +465,8 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt) param.db_name = table->table_cache_key; param.table_name = table->table_name; param.testflag = 0; - mi_check_print_error(¶m,errmsg, errno ); - return error; + mi_check_print_error(¶m,errmsg, my_errno); + DBUG_RETURN(error); } } diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc index 88ae8d22f73..0a2ef534ad1 100644 --- a/sql/ha_myisammrg.cc +++ b/sql/ha_myisammrg.cc @@ -23,9 +23,9 @@ #include #include "ha_myisammrg.h" #ifndef MASTER -#include "../srclib/myisammrg/mymrgdef.h" +#include "../srclib/myisammrg/myrg_def.h" #else -#include "../myisammrg/mymrgdef.h" +#include "../myisammrg/myrg_def.h" #endif /***************************************************************************** diff --git a/sql/handler.cc b/sql/handler.cc index 8b7b7fe6799..5a41498aff1 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -25,7 +25,7 @@ #include "ha_heap.h" #include "ha_myisam.h" #include "ha_myisammrg.h" -#ifndef NO_ISAM +#ifdef HAVE_ISAM #include "ha_isam.h" #include "ha_isammrg.h" #endif @@ -88,11 +88,9 @@ enum db_type ha_checktype(enum db_type database_type) #ifndef NO_HASH case DB_TYPE_HASH: #endif -#ifndef NO_MERGE - case DB_TYPE_MRG_ISAM: -#endif -#ifndef NO_ISAM +#ifdef HAVE_ISAM case DB_TYPE_ISAM: + case DB_TYPE_MRG_ISAM: #endif case DB_TYPE_HEAP: case DB_TYPE_MYISAM: @@ -111,11 +109,9 @@ handler *get_new_handler(TABLE *table, enum db_type db_type) #ifndef NO_HASH return new ha_hash(table); #endif -#ifndef NO_MERGE +#ifdef HAVE_ISAM case DB_TYPE_MRG_ISAM: return new ha_isammrg(table); -#endif -#ifndef NO_ISAM case DB_TYPE_ISAM: return new ha_isam(table); #endif @@ -186,14 +182,14 @@ int ha_init() int ha_panic(enum ha_panic_function flag) { int error=0; -#ifndef NO_MERGE - error|=mrg_panic(flag); -#endif #ifndef NO_HASH error|=h_panic(flag); /* fix hash */ #endif - error|=heap_panic(flag); +#ifdef HAVE_ISAM + error|=mrg_panic(flag); error|=nisam_panic(flag); +#endif + error|=heap_panic(flag); error|=mi_panic(flag); error|=myrg_panic(flag); #ifdef HAVE_BERKELEY_DB diff --git a/sql/item_func.cc b/sql/item_func.cc index e09f81a4b1b..dcc3ecb2560 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1063,7 +1063,8 @@ udf_handler::~udf_handler() } free_udf(u_d); } - delete [] buffers; + if (buffers) // Because of bug in ecc + delete [] buffers; } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index f817d53f33e..1ffbb88c7f8 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -504,6 +504,8 @@ void init_errmessage(void); void sql_perror(const char *message); void sql_print_error(const char *format,...) __attribute__ ((format (printf, 1, 2))); +bool fn_format_relative_to_data_home(my_string to, const char *name, + const char *dir, const char *extension); extern uint32 server_id; extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH], @@ -540,7 +542,7 @@ extern pthread_cond_t COND_refresh,COND_thread_count, COND_binlog_update, COND_slave_stopped, COND_slave_start; extern pthread_attr_t connection_attrib; extern bool opt_endinfo, using_udf_functions, locked_in_memory, - opt_using_transactions, use_temp_pool; + opt_using_transactions, use_temp_pool, mysql_embedded; extern char f_fyllchar; extern ulong ha_read_count, ha_write_count, ha_delete_count, ha_update_count, ha_read_key_count, ha_read_next_count, ha_read_prev_count, diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 8854f6b46d2..12fea519db9 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -193,7 +193,7 @@ SHOW_COMP_OPTION have_innodb=SHOW_OPTION_YES; #else SHOW_COMP_OPTION have_innodb=SHOW_OPTION_NO; #endif -#ifndef NO_ISAM +#ifdef HAVE_ISAM SHOW_COMP_OPTION have_isam=SHOW_OPTION_YES; #else SHOW_COMP_OPTION have_isam=SHOW_OPTION_NO; @@ -317,8 +317,10 @@ char mysql_real_data_home[FN_REFLEN], *opt_init_file; #ifndef EMBEDDED_LIBRARY char mysql_data_home_buff[2], *mysql_data_home=mysql_data_home_buff; +bool mysql_embedded=0; #else char *mysql_data_home=mysql_real_data_home; +bool mysql_embedded=1; #endif char *opt_bin_logname = 0; // this one needs to be seen in sql_parse.cc @@ -333,7 +335,7 @@ enum_tx_isolation default_tx_isolation=ISO_READ_COMMITTED; #ifdef HAVE_GEMINI_DB const char *gemini_recovery_options_str="FULL"; #endif -my_string mysql_unix_port=NULL,mysql_tmpdir=NULL; +my_string mysql_unix_port=NULL, mysql_tmpdir=NULL, allocated_mysql_tmpdir=NULL; ulong my_bind_addr; /* the address we bind to */ DATE_FORMAT dayord; double log_10[32]; /* 10 potences */ @@ -730,8 +732,8 @@ void clean_up(bool print_message) #endif /* HAVE_OPENSSL */ free_defaults(defaults_argv); my_free(charsets_list, MYF(MY_ALLOW_ZERO_PTR)); - my_free(mysql_tmpdir,MYF(0)); - my_free(slave_load_tmpdir,MYF(0)); + my_free(allocated_mysql_tmpdir,MYF(MY_ALLOW_ZERO_PTR)); + my_free(slave_load_tmpdir,MYF(MY_ALLOW_ZERO_PTR)); x_free(opt_bin_logname); bitmap_free(&temp_pool); free_max_user_conn(); @@ -3770,7 +3772,10 @@ static void get_options(int argc,char **argv) break; #endif case (int) OPT_FLUSH: - nisam_flush=myisam_flush=1; +#ifdef HAVE_ISAM + nisam_flush=1; +#endif + myisam_flush=1; flush_time=0; // No auto flush break; case OPT_LOW_PRIORITY_UPDATES: @@ -4295,7 +4300,10 @@ static int get_service_parameters() else if ( lstrcmp(szKeyValueName, TEXT("FlushTables")) == 0 ) { CHECK_KEY_TYPE( REG_DWORD, szKeyValueName ); - nisam_flush = myisam_flush= *lpdwValue ? 1 : 0; +#ifdef HAVE_NISAM + nisam_flush = 1; +#endif + myisam_flush= *lpdwValue ? 1 : 0; } else if ( lstrcmp(szKeyValueName, TEXT("BackLog")) == 0 ) { @@ -4529,12 +4537,34 @@ static char *get_relative_path(const char *path) } +/* + Fix filename and replace extension where 'dir' is relative to + mysql_real_data_home. + Return 1 if len(path) > FN_REFLEN +*/ + +bool +fn_format_relative_to_data_home(my_string to, const char *name, + const char *dir, const char *extension) +{ + char tmp_path[FN_REFLEN]; + if (!test_if_hard_path(dir)) + { + strxnmov(tmp_path,sizeof(tmp_path)-1, mysql_real_data_home, + dir, NullS); + dir=tmp_path; + } + return !fn_format(to, name, dir, extension, + MY_REPLACE_EXT | MY_UNPACK_FILENAME | MY_SAFE_PATH); +} + + static void fix_paths(void) { (void) fn_format(mysql_home,mysql_home,"","",16); // Remove symlinks - convert_dirname(mysql_home); - convert_dirname(mysql_real_data_home); - convert_dirname(language); + convert_dirname(mysql_home,mysql_home,NullS); + convert_dirname(mysql_real_data_home,mysql_real_data_home,NullS); + convert_dirname(language,language,NullS); (void) my_load_path(mysql_home,mysql_home,""); // Resolve current dir (void) my_load_path(mysql_real_data_home,mysql_real_data_home,mysql_home); (void) my_load_path(pidfile_name,pidfile_name,mysql_real_data_home); @@ -4544,7 +4574,7 @@ static void fix_paths(void) strmov(buff,sharedir); /* purecov: tested */ else strxmov(buff,mysql_home,sharedir,NullS); - convert_dirname(buff); + convert_dirname(buff,buff,NullS); (void) my_load_path(language,language,buff); /* If --character-sets-dir isn't given, use shared library dir */ @@ -4558,19 +4588,16 @@ static void fix_paths(void) char *tmp= (char*) my_malloc(FN_REFLEN,MYF(MY_FAE)); if (tmp) { - strmov(tmp,mysql_tmpdir); - mysql_tmpdir=tmp; - convert_dirname(mysql_tmpdir); - mysql_tmpdir=(char*) my_realloc(mysql_tmpdir,(uint) strlen(mysql_tmpdir)+1, + char *end=convert_dirname(tmp, mysql_tmpdir, NullS); + + mysql_tmpdir=(char*) my_realloc(tmp,(uint) (end-tmp)+1, MYF(MY_HOLD_ON_ERROR)); + allocated_mysql_tmpdir=mysql_tmpdir; } if (!slave_load_tmpdir) { - int copy_len; - slave_load_tmpdir = (char*) my_malloc((copy_len=strlen(mysql_tmpdir) + 1) - , MYF(MY_FAE)); // no need to check return value, if we fail, my_malloc() never returns - memcpy(slave_load_tmpdir, mysql_tmpdir, copy_len); + slave_load_tmpdir = (char*) my_strdup(mysql_tmpdir, MYF(MY_FAE)); } } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e930dd2cfcb..35f32d50f46 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3051,7 +3051,7 @@ static void refresh_status(void) static bool append_file_to_dir(char **filename_ptr, char *table_name) { - char buff[FN_REFLEN],*ptr; + char buff[FN_REFLEN],*ptr, *end; if (!*filename_ptr) return 0; // nothing to do @@ -3064,8 +3064,8 @@ static bool append_file_to_dir(char **filename_ptr, char *table_name) } /* Fix is using unix filename format on dos */ strmov(buff,*filename_ptr); - convert_dirname(buff); - if (!(ptr=sql_alloc(strlen(buff)+strlen(table_name)+1))) + end=convert_dirname(buff, *filename_ptr, NullS); + if (!(ptr=sql_alloc((uint) (end-buff)+strlen(table_name)+1))) return 1; // End of memory *filename_ptr=ptr; strxmov(ptr,buff,table_name,NullS); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 14bdd3d7d66..53d83c350ea 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2645,7 +2645,8 @@ join_free(JOIN *join) } join->group_fields.delete_elements(); join->tmp_table_param.copy_funcs.delete_elements(); - delete [] join->tmp_table_param.copy_field; + if (join->tmp_table_param.copy_field) // Because of bug in ecc + delete [] join->tmp_table_param.copy_field; join->tmp_table_param.copy_field=0; DBUG_VOID_RETURN; } @@ -6395,7 +6396,7 @@ setup_copy_fields(TMP_TABLE_PARAM *param,List &fields) DBUG_ENTER("setup_copy_fields"); if (!(copy=param->copy_field= new Copy_field[param->field_count])) - goto err; + goto err2; param->copy_funcs.empty(); while ((pos=li++)) @@ -6444,8 +6445,9 @@ setup_copy_fields(TMP_TABLE_PARAM *param,List &fields) DBUG_RETURN(0); err: - delete [] param->copy_field; + delete [] param->copy_field; // This is never 0 param->copy_field=0; +err2: DBUG_RETURN(TRUE); } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index a5e9eec03b1..99c2b837480 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -841,7 +841,8 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table) char* table_name = table->name; char* db = thd->db ? thd->db : table->db; - if (!fn_format(src_path, table_name, backup_dir, reg_ext, 4 + 64)) + if (fn_format_relative_to_data_home(src_path, table_name, backup_dir, + reg_ext)) DBUG_RETURN(-1); // protect buffer overflow sprintf(dst_path, "%s/%s/%s", mysql_real_data_home, db, table_name); @@ -850,9 +851,8 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table) DBUG_RETURN(-1); if (my_copy(src_path, - fn_format(dst_path, dst_path,"", - reg_ext, 4), - MYF(MY_WME))) + fn_format(dst_path, dst_path,"", reg_ext, 4), + MYF(MY_WME))) { unlock_table_name(thd, table); DBUG_RETURN(send_check_errmsg(thd, table, "restore", @@ -1814,7 +1814,7 @@ copy_data_between_tables(TABLE *from,TABLE *to, } end_read_record(&info); free_io_cache(from); - delete [] copy; + delete [] copy; // This is never 0 uint tmp_error; if ((tmp_error=to->file->extra(HA_EXTRA_NO_CACHE))) { diff --git a/strings/Makefile.am b/strings/Makefile.am index d198318a0f8..3bce48045b3 100644 --- a/strings/Makefile.am +++ b/strings/Makefile.am @@ -22,7 +22,7 @@ pkglib_LIBRARIES = libmystrings.a # Exact one of ASSEMBLER_X if ASSEMBLER_x86 ASRCS = strings-x86.s longlong2str-x86.s -CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c strxmov.c bmove_upp.c strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c strstr.c strinstr.c strmake.c strnmov.c strmov.c longlong2str.c llstr.c ctype.c strnlen.c +CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c ctype.c strnlen.c else if ASSEMBLER_sparc # These file MUST all be on the same line!! Otherwise automake diff --git a/strings/bchange.c b/strings/bchange.c index 68b1434de4f..d65b80e7c2c 100644 --- a/strings/bchange.c +++ b/strings/bchange.c @@ -28,7 +28,8 @@ #include #include "m_string.h" -void bchange(register char *dst, uint old_length, register const char *src, uint new_length, uint tot_length) +void bchange(register char *dst, uint old_length, register const char *src, + uint new_length, uint tot_length) { uint rest=tot_length-old_length; if (old_length < new_length) -- cgit v1.2.1