diff options
103 files changed, 1378 insertions, 981 deletions
diff --git a/.bzrignore b/.bzrignore index f497aa69ffd..5d5909ce4da 100644 --- a/.bzrignore +++ b/.bzrignore @@ -530,3 +530,4 @@ vio/test-ssl vio/test-sslclient vio/test-sslserver vio/viotest-ssl +support-files/MacOSX/ReadMe.txt diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index dbd4df6efe4..aca77159202 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -11,6 +11,7 @@ arjen@fred.bitbike.com arjen@george.bitbike.com bar@bar.mysql.r18.ru bar@bar.udmsearch.izhnet.ru +bell@laptop.sanja.is.com.ua bell@sanja.is.com.ua bk@admin.bk davida@isil.mysql.com @@ -45,6 +46,7 @@ miguel@hegel.br miguel@hegel.local miguel@light. miguel@light.local +mmatthew@markslaptop. monty@bitch.mysql.fi monty@butch. monty@donna.mysql.fi @@ -67,6 +69,7 @@ paul@teton.kitebird.com pem@mysql.com peter@linux.local peter@mysql.com +peterg@mysql.com pgulutzan@linux.local ram@mysql.r18.ru ram@ram.(none) diff --git a/Docs/Makefile.am b/Docs/Makefile.am index af771a5728d..00eb936c408 100644 --- a/Docs/Makefile.am +++ b/Docs/Makefile.am @@ -27,7 +27,7 @@ EXTRA_DIST = $(noinst_SCRIPTS) $(BUILT_SOURCES) mysqld_error.txt \ all: $(targets) txt_files txt_files: ../INSTALL-SOURCE ../COPYING ../COPYING.LIB \ - INSTALL-BINARY + INSTALL-BINARY ../support-files/MacOSX/ReadMe.txt CLEAN_FILES: $(BUILD_SOURCES) touch $(BUILD_SOURCES) @@ -254,5 +254,8 @@ INSTALL-BINARY: mysql.info $(GT) ../COPYING.LIB: mysql.info $(GT) perl -w $(GT) mysql.info "LGPL license" "Function Index" > $@ +../support-files/MacOSX/ReadMe.txt: mysql.info $(GT) + perl -w $(GT) mysql.info "Mac OS X installation" "Netware installation" > $@ + # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/Docs/internals.texi b/Docs/internals.texi index 686ecd27fda..07eea90e229 100644 --- a/Docs/internals.texi +++ b/Docs/internals.texi @@ -1994,7 +1994,7 @@ When you say: @* MySQL creates files named Table1.MYD ("MySQL Data"), Table1.MYI -("MySQL Index"), and Table1.FRM ("Format"). These files will be in the +("MySQL Index"), and Table1.frm ("Format"). These files will be in the directory: @* /<datadir>/<database>/ @* @@ -2030,6 +2030,12 @@ The minimal record header is a set of flags: @end table @* +The length of the record header is thus:@* +(1 + number of NULL columns + 7) / 8 bytes@* +After the header, all columns are stored in +the order that they were created, which is the +same order that you would get from SHOW COLUMNS. + Here's an example. Suppose you say: @* @@ -2072,8 +2078,8 @@ right is @code{on}, and (b) remember that the first flag bit is the X bit.) There are complications -- the record header is more complex if there are variable-length fields -- but the simple display shown in the -example is exactly what you'd see if you took a debugger and looked -at the MySQL Data file. +example is exactly what you'd see if you looked at the MySQL Data file +with a debugger or a hexadecimal file dumper. @* @section Physical Attributes of Columns @@ -2106,8 +2112,8 @@ Example: a VARCHAR(7) column containing 'A' looks like:@* @item The numeric data types -Important: MySQL stores all multi-byte binary numbers with the -high byte first. This is called "little-endian" numeric storage; +Important: MySQL almost always stores multi-byte binary numbers with +the low byte first. This is called "little-endian" numeric storage; it's normal on Intel x86 machines; MySQL uses it even for non-Intel machines so that databases will be portable. @* @@ -2282,7 +2288,7 @@ Example: a SET('A','B','C') column containing 'A' looks like:@* Storage: one byte if less than 256 alternatives, else two bytes. @item This is an index. The value 1 corresponds to the first listed -alternative. (Note: ENUM always reserves 0 for a blank '' value. This +alternative. (Note: ENUM always reserves 0 for an erroneous value. This explains why 'A' is 1 instead of 0.) @item Example: an ENUM('A','B','C') column containing 'A' looks like:@* @@ -2367,7 +2373,10 @@ Storage: same as LONGBLOB. @strong{References:} @* Most of the formatting work for MyISAM columns is visible -in the program /sql/field.cc in the source code directory. +in the program /sql/field.cc in the source code directory. +And in the MyISAM directory, the files that do formatting +work for different record formats are: /myisam/mi_statrec.c, +/myisam/mi_dynrec.c, and /myisam/mi_packrec.c. @* @node InnoDB Record Structure,InnoDB Page Structure,MyISAM Record Structure,Top @@ -3112,7 +3121,7 @@ page0page.ic, and page0page.h in \page directory. This is a description of the files that you get when you download the source code of MySQL. This description begins with a list -of the 43 directories and a short comment about each one. Then, for +of the main directories and a short comment about each one. Then, for each directory, in alphabetical order, a longer description is supplied. When a directory contains significant program files, a list of each C program is given along with an explanation of its intended function. @@ -3124,43 +3133,37 @@ program is given along with an explanation of its intended function. @item bdb -- The Berkeley Database table handler @item -BitKeeper -- BitKeeper administration +BitKeeper -- BitKeeper administration (not part of the source distribution) @item -BUILD -- Build switches +BUILD -- Some very often used build scripts @item -Build-tools -- Build tools +Build-tools -- Build tools @item client -- Client library @item -cmd-line-utils -- Command-line utilities -@item -dbug -- Fred Fish's dbug library +cmd-line-utils -- Command-line utilities (libedit and readline) @item -div -- Deadlock test +dbug -- Fred Fish's dbug library @item Docs -- Preliminary documents about internals and new modules @item -extra -- Eight minor standalone utility programs -@item -fs -- File System +extra -- Some minor standalone utility programs @item -heap -- The HEAP table handler +heap -- The HEAP table handler @item -Images -- Empty directory +include -- Include (*.h) files @item -include -- Include (*.h) files +innobase -- The Innobase (InnoDB) table handler @item -innobase -- The Innobase (InnoDB) table handler +isam -- The ISAM (MySQL) table handler @item -isam -- The ISAM (MySQL) table handler +libmysql -- For producing a thread-safe libmysql library @item -libmysql -- For producing MySQL as a library (e.g. a Windows DLL) +libmysql_r -- Only one file, a makefile @item -libmysql_r -- Only one file, a makefile +libmysqld -- The MySQL Server as an embeddable library @item -libmysqld -- The MySQL Library -@item -man -- Manual pages +man -- Some user-contributed manual pages @item merge -- The MERGE table handler (see Reference Manual section 7.2) @item @@ -3170,24 +3173,21 @@ myisammrg -- The MyISAM Merge table handler @item mysql-test -- A test suite for mysqld @item -mysys -- MySQL system library (Low level routines for file access -etc.) +mysys -- MySQL system library (Low level routines for file access etc.) @item netware -- Files related to the Novell NetWare version of MySQL @item -NEW-RPMS -- New "RPM Package Manager" files +NEW-RPMS -- Directory to place RPMS while making a distribution @item os2 -- Routines for working with the OS/2 operating system @item -pstack -- Process stack display -@item -regex -- Regular Expression library for support of REGEXP function +pstack -- Process stack display (not currently used) @item -repl-tests -- Test cases for replication +regex -- Henry Spencer's Regular Expression library for support of REGEXP function @item -SCCS -- Source Code Control System +SCCS -- Source Code Control System (not part of source distribution) @item -scripts -- SQL batches, e.g. for converting msql to MySQL +scripts -- SQL batches, e.g. mysqlbug and mysql_install_db @item sql -- Programs for handling SQL commands. The "core" of MySQL @item @@ -3197,18 +3197,17 @@ SSL -- Secure Sockets Layer @item strings -- Library for C string routines, e.g. atof, strchr @item -support-files -- 15 files used for building, containing switches? +support-files -- Files used to build MySQL on different systems @item tests -- Tests in Perl @item -tools -- mysqlmanager.c +tools -- mysqlmanager.c (under development, not yet useful) @item -VC++Files -- Includes this entire directory, repeated for VC++ -(Windows) use +VC++Files -- Includes this entire directory, repeated for VC++ (Windows) use @item vio -- Virtual I/O Library @item -zlib -- data compression library +zlib -- data compression library, used on Windows @end itemize @subsection bdb @@ -3216,7 +3215,9 @@ zlib -- data compression library The Berkeley Database table handler. @*@* -The Berkeley Database (BDB) is maintained by Sleepycat Software. +The Berkeley Database (BDB) is maintained by Sleepycat Software. +MySQL AB maintains only a few small patches to make BDB work +better with MySQL. @*@* The documentation for BDB is available at @@ -3236,6 +3237,10 @@ BitKeeper directory are for maintenance purposes only -- they are not part of the MySQL package. @*@* +The MySQL Reference Manual explains how to use Bitkeeper to get the +MySQL source. +@*@* + @subsection BUILD Build switches. @@ -3262,9 +3267,10 @@ Build tools. @*@* This directory contains batch files for extracting, making -directories, and making programs from source files. There are several -subdirectories -- for building Linux executables, for compiling, for -performing all build steps, etc. +directories, and making programs from source files. There are +several subdirectories with different scripts -- for building +Linux executables, for compiling, for performing all build steps, +and so on. @*@* @subsection client @@ -3282,32 +3288,31 @@ server. The C program files in the directory are: @itemize @bullet @item -connect_test.c -- test that a connect is possible +connect_test.c -- test that a connect is possible @item -get_password.c -- ask for a password from the console +get_password.c -- ask for a password from the console @item -insert_test.c -- test that an insert is possible +insert_test.c -- test that an insert is possible @item -list_test.c -- test that a select is possible +list_test.c -- test that a select is possible @item -mysql.cc -- "The MySQL command tool" +mysql.cc -- "The MySQL command tool" @item -mysqladmin.c -- maintenance of MYSQL databases +mysqladmin.c -- maintenance of MYSQL databases @item -mysqlcheck.c -- check all databases, check connect, etc. +mysqlcheck.c -- check all databases, check connect, etc. @item -mysqldump.c -- dump table's contents in ascii +mysqldump.c -- dump table's contents as SQL statements @item -mysqlimport.c -- import file into a table +mysqlimport.c -- import text files in different formats into tables @item -mysqlmanager-pwgen.c -- pwgen seems to stand for "password -generation" +mysqlmanager-pwgen.c -- pwgen stands for "password generation" (not currently maintained) @item -mysqlmanagerc.c -- entry point for mysql manager +mysqlmanagerc.c -- entry point for mysql manager (not currently maintained) @item mysqlshow.c -- show databases, tables or columns @item -mysqltest.c -- test program +mysqltest.c -- test program used by the mysql-test suite, mysql-test-run @item password.c -- password checking routines @item @@ -3341,7 +3346,10 @@ Software Foundation. @*@* The \libedit (library of edit functions) subdirectory has files -written by Christos Zoulas. They are for editing the line contents. +written by Christos Zoulas. They are distributed and modifed under +the BSD License. These files are for editing the line contents. +@*@* + These are the program files in the \libedit subdirectory: @itemize @bullet @item @@ -3395,7 +3403,9 @@ Fred Fish's dbug library. @*@* This is not really part of the MySQL package. Rather, it's a set of -public-domain routines which are useful for debugging MySQL programs. +public-domain routines which are useful for debugging MySQL programs. +The MySQL Server and all .c and .cc programs support the use of this +package. @*@* How it works: One inserts a function call that begins with DBUG_* in @@ -3405,7 +3415,8 @@ DBUG_ENTER("get_tty_password"); @* at the start of a routine, and this line: @* DBUG_RETURN(my_strdup(to,MYF(MY_FAE))); @* at the end of the routine. These lines don't affect production code. -Features of the dbug library include profiling and state pushing. +Features of the dbug library include extensive reporting and profiling +(the latter has not been used by the MySQL team). @*@* The C programs in this directory are: @@ -3429,14 +3440,6 @@ sanity.c -- Declaration of a variable @end itemize @*@* -@subsection div - -Deadlock test. -@*@* - -This file contains only one program, deadlock_test.c. -@*@* - @subsection Docs Preliminary documents about internals and new modules. @@ -3445,7 +3448,8 @@ Preliminary documents about internals and new modules. This directory doesn't have much at present that's very useful to the student, but the plan is that some documentation related to the source files and the internal workings of MySQL, including perhaps some -documentation from developers themselves, will be placed here. +documentation from developers themselves, will be placed here. Some of +these files will eventually be moved to the MySQL documentation repository. @*@* These sub-directories are part of this directory: @@ -3461,8 +3465,7 @@ mysql-logos -- more MySQL-related logos, some of them moving @item raw-flags -- more country flags, all .gif files @item -support -- various files for generating texinfo/docbook -documentation +support -- various files for generating texinfo/docbook documentation @item to-be-included... -- an empty subdirectory @item @@ -3489,7 +3492,7 @@ make their own JDBC drivers, or just sniff). Eight minor standalone utility programs. @*@* -These eight programs are all standalone utilities, that is, they have +These programs are all standalone utilities, that is, they have a main() function and their main role is to show information that the MySQL server needs or produces. Most are unimportant. They are as follows: @@ -3503,7 +3506,7 @@ mysql_waitpid.c -- wait for a program to terminate @item perror.c -- "print error" -- given error number, display message @item -replace.c -- replace strings in text files +replace.c -- replace strings in text files or pipe @item resolve_stack_dump.c -- show symbolic info from a stack dump @item @@ -3562,7 +3565,7 @@ an "*" in the following list. For example, you will find that @item hp_block.c -- Read/write a block (i.e. a page) @item -hp_clear.c -- Remove all records in the database +hp_clear.c -- Remove all records in the table @item hp_close.c -- * close database @item @@ -3578,7 +3581,7 @@ hp_info.c -- * Information about database status @item hp_open.c -- * open database @item -hp_panic.c -- * the hp_panic routine, probably for sudden shutdowns +hp_panic.c -- * the hp_panic routine, for shutdowns and flushes @item hp_rename.c -- * rename a table @item @@ -3590,8 +3593,7 @@ hp_rlast.c -- * read last row with same key as previously-read row @item hp_rnext.c -- * read next row with same key as previously-read row @item -hp_rprev.c -- * read previous row with same key as previously-read -row +hp_rprev.c -- * read previous row with same key as previously-read row @item hp_rrnd.c -- * read a row based on position @item @@ -3618,14 +3620,6 @@ for a \myisam\mi_cache.c equivalent (to cache reads) or a \myisam\log.c equivalent (to log statements). @*@* -@subsection Images - -Empty directory. -@*@* - -There are no files in this directory. -@*@* - @subsection include Include (*.h) files. @@ -3940,25 +3934,23 @@ mi_dynrec.c -- functions to handle space-packed records and blobs @item mi_extra.c -- setting options and buffer sizes when optimizing @item -mi_info.c -- "Ger tillbaka en struct med information om isam-filen" +mi_info.c -- return useful base information for an open table @item -mi_key.c -- for handling keys +mi_key.c -- for handling keys @item mi_locking.c -- lock database @item -mi_log.c -- save commands in log file which myisamlog program can -read +mi_log.c -- save commands in log file which myisamlog program can read @item mi_open.c -- open database @item -mi_packrec.c -- compress records +mi_packrec.c -- read from a data file compresed with myisampack @item mi_page.c -- read and write pages containing keys @item mi_panic.c -- the mi_panic routine, probably for sudden shutdowns @item -mi_range.c -- approximate count of how many records lie between two -keys +mi_range.c -- approximate count of how many records lie between two keys @item mi_rename.c -- rename a table @item @@ -4107,8 +4099,6 @@ There are other tests in these directories: @item sql-bench @item -repl-tests -@item tests @end itemize @@ -4275,8 +4265,7 @@ free" @item my_open.c -- Open a file @item -my_os2cond.c -- OS2-specific: "A simple implementation of posix -conditions" +my_os2cond.c -- OS2-specific: "A simple implementation of posix conditions" @item my_os2dirsrch.c -- OS2-specific: Emulate a Win32 directory search @item @@ -4290,12 +4279,11 @@ my_os2thread.c -- OS2-specific: For thread handling @item my_os2tls.c -- OS2-specific: For thread-local storage @item -my_port.c -- AIX-specific: my_ulonglong2double() +my_port.c -- OS/machine-dependent porting functions, e.g. AIX-specific my_ulonglong2double() @item my_pread.c -- Read a specified number of bytes from a file @item -my_pthread.c -- A wrapper for thread-handling functions in different -OSs +my_pthread.c -- A wrapper for thread-handling functions in different OSs @item my_quick.c -- Read/write (labelled a "quicker" interface, perhaps obsolete) @@ -4317,15 +4305,13 @@ support them @item my_sleep.c -- Wait n microseconds @item -my_static.c -- Static-variable definitions +my_static.c -- Static variables used by the mysys library @item -my_symlink.c -- Read a symbolic link (symlinks are a UNIX thing, I -guess) +my_symlink.c -- Read a symbolic link (symlinks are a UNIX thing, I guess) @item my_symlink2.c -- Part 2 of my_symlink.c @item -my_tempnam.c -- Obsolete temporary-filename routine used by ISAM -table handler +my_tempnam.c -- Obsolete temporary-filename routine used by ISAM table handler @item my_thr_init.c -- initialize/allocate "all mysys & debug thread variables" @@ -4442,9 +4428,8 @@ NetWare AMP" at: New "RPM Package Manager" files. @*@* -This directory is not part of the Windows distribution. Perhaps in -MYSQL's Linux distribution it has files for use with Red Hat -installations -- a point that needs checking someday. +This directory is not part of the Windows distribution. It is +a temporary directory used during RPM builds with Linux distributions. @*@* @subsection os2 @@ -4517,28 +4502,6 @@ This program calls the 'regcomp' function, which is the entry point in \regex\regexp.c. @*@* -@subsection repl-tests - -Test cases for replication. -@*@* - -There are six short and trivial-looking tests in these subdirectories: -@itemize @bullet -@item -\test-auto-inc -- Do auto-Increment columns work? -@item -\test-bad-query -- Does insert in PK column work? -@item -\test-dump -- Do LOAD statements work? -@item -\test-repl -- Does replication work? -@item -\test-repl-alter -- Does ALTER TABLE work? -@item -\test-repl-ts -- Does TIMESTAMP column work? -@end itemize -@*@* - @subsection SCCS Source Code Control System. @@ -4554,8 +4517,8 @@ administration and are not of interest to application programmers. SQL batches, e.g. for converting msql to MySQL. @*@* -The *.sh filename extension apparently stands for "shell script". -Linux programmers use it where Windows programmers would use a *.bat +The *.sh filename extension stands for "shell script". Linux +programmers use it where Windows programmers would use a *.bat (batch filename extension). @*@* @@ -4564,10 +4527,9 @@ The *.sh files on this directory are: @item fill_help_tables.sh -- Create help-information tables and insert @item -make_binary_distribution.sh -- Get configure information, make, -produce tar +make_binary_distribution.sh -- Get configure information, make, produce tar @item -msql2mysql.sh -- Convert mSQL to MySQL +msql2mysql.sh -- Convert mSQL programs and scripts to MySQL, partly @item mysqlbug.sh -- Create a bug report and mail it @item @@ -4581,33 +4543,29 @@ mysqldumpslow.sh -- Parse and summarize the slow query log @item mysqlhotcopy.sh -- Hot backup @item -mysql_config.sh -- Get configure information that client might need +mysql_config.sh -- Get configuration information that might be needed to compile a client @item -mysql_convert_table_format.sh -- Conversion, e.g. from ISAM to -MyISAM +mysql_convert_table_format.sh -- Conversion, e.g. from ISAM to MyISAM @item -mysql_explain_log.sh -- Put a log (made with --log) into a MySQL -table +mysql_explain_log.sh -- Put a log (made with --log) into a MySQL table @item -mysql_find_rows.sh -- Search for queries containing <regexp> +mysql_find_rows.sh -- Search for queries containing <regexp> @item -mysql_fix_extensions.sh -- Renames some file extensions, not -recommended +mysql_fix_extensions.sh -- Renames some file extensions, not recommended @item -mysql_fix_privilege_tables.sh -- Fix mysql.user etc. if upgrading to -MySQL 3.23.14+ +mysql_fix_privilege_tables.sh -- Fix mysql.user etc. if upgrading to MySQL 3.23.14+ @item -mysql_install_db.sh -- Create privilege tables and func table +mysql_install_db.sh -- Create privilege tables and func table @item mysql_secure_installation.sh -- Disallow remote root login, -eliminate test, etc. +eliminate test, etc. @item mysql_setpermission.sh -- Aid to add users or databases, sets -privileges +privileges @item mysql_tableinfo.sh -- Puts info re MySQL tables into a MySQL table @item -mysql_zap.sh -- Kill processes which match pattern +mysql_zap.sh -- Kill processes which match pattern @end itemize @*@* @@ -4629,16 +4587,15 @@ des_key_file.cc -- load DES keys from plaintext file @item field.cc -- "implement classes defined in field.h" (long) @item -field_conv.cc -- functions to copy data to or from fields +field_conv.cc -- functions to copy data between fields @item -filesort.cc -- sort file +filesort.cc -- sort a result set, using memory or temporary files @item frm_crypt.cc -- contains only one short function: get_crypt_for_frm @item -gen_lex_hash.cc -- Knuth's algorithm from Vol 3 Sorting and -Searching, Chapter 6.3 +gen_lex_hash.cc -- Knuth's algorithm from Vol 3 Sorting and Searching, Chapter 6.3 @item -gstream.cc -- GTextReadStream +gstream.cc -- GTextReadStream, used to read GIS objects @item handler.cc -- handler-calling functions @item @@ -4674,7 +4631,7 @@ item_func.cc -- Numerical functions @item item_row.cc -- Row items for comparing rows and for IN on rows @item -item_sum.cc -- Set functions (sum, avg, etc.) +item_sum.cc -- Set functions (SUM, AVG, etc.) @item item_strfunc.cc -- String functions @item @@ -4682,7 +4639,7 @@ item_subselect.cc -- Item subselect @item item_timefunc.cc -- Date/time functions, e.g. week of year @item -item_uniq.cc -- Empty file, here for compatibility reasons +item_uniq.cc -- Empty file, here for compatibility reasons @item key.cc -- Functions to handle keys and fields in forms @item @@ -4694,10 +4651,9 @@ log_event.cc -- Log event @item matherr.c -- Handling overflow, underflow, etc. @item -mf_iocache.cc -- Caching of (sequential) reads +mf_iocache.cc -- Caching of (sequential) reads and writes @item -mini_client.cc -- Client included in server for server-server -messaging +mini_client.cc -- Client included in server for server-server messaging @item mysqld.cc -- Source of mysqld.exe @item @@ -4708,58 +4664,56 @@ net_serv.cc -- Read/write of packets on a network socket nt_servc.cc -- Initialize/register/remove an NT service @item opt_ft.cc -- Create a FT or QUICK RANGE based on a key (very short) -* opt_range.cc -- Range of keys +@item +opt_range.cc -- Range of keys @item opt_sum.cc -- Optimize functions in presence of (implied) GROUP BY @item -password.c -- Password checking +password.c -- Password checking @item -procedure.cc -- Procedure +procedure.cc -- Procedure @item -protocol.cc -- Low level functions for storing data to be sent to -client +protocol.cc -- Low level functions for storing data to be sent to client @item -records.cc -- Functions to read, write, and lock records +records.cc -- Functions for easy reading of records, possible through a cache @item -repl_failsafe.cc -- Replication fail-save +repl_failsafe.cc -- Replication fail-save (not yet implemented) @item -set_var.cc -- MySQL variables +set_var.cc -- Set and retrieve MySQL user variables @item -slave.cc -- Procedures for a slave in a master/slave (replication?) -relation +slave.cc -- Procedures for a slave in a master/slave (replication) relation @item spatial.cc -- Geometry stuff (lines, points, etc.) @item -sql_acl.cc -- Functions related to ACL security +sql_acl.cc -- Functions related to ACL security @item sql_analyse.cc -- Analyse an input string (?) @item -sql_base.cc -- Basic functions needed by many modules +sql_base.cc -- Basic functions needed by many modules @item -sql_cache.cc -- SQL cache, with long comments about how caching -works +sql_cache.cc -- SQL query cache, with long comments about how caching works @item -sql_class.cc -- SQL class +sql_class.cc -- SQL class @item -sql_crypt.cc -- Encode / decode, very short +sql_crypt.cc -- Encode / decode, very short @item -sql_db.cc -- Create / drop database +sql_db.cc -- Create / drop database @item -sql_delete.cc -- The DELETE statement +sql_delete.cc -- The DELETE statement @item -sql_derived.cc -- Derived tables, with long comments +sql_derived.cc -- Derived tables, with long comments @item -sql_do.cc -- The DO statement +sql_do.cc -- The DO statement @item -sql_error.cc -- Errors and warnings +sql_error.cc -- Errors and warnings @item -sql_handler.cc -- Direct access to ISAM +sql_handler.cc -- Direct access to ISAM @item sql_help.cc -- The HELP statement (if there is one?) @item -sql_insert.cc -- The INSERT statement +sql_insert.cc -- The INSERT statement @item -sql_lex.cc -- Related to lex or yacc +sql_lex.cc -- Related to lex or yacc @item sql_list.cc -- Only list_node_end_of_list, short @item diff --git a/Images/.cvsignore b/Images/.cvsignore deleted file mode 100644 index 6d0d61a83d5..00000000000 --- a/Images/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -logo_nusphere_b.tif diff --git a/client/mysql.cc b/client/mysql.cc index d7aa0d1404d..a237561d83d 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1007,7 +1007,7 @@ static bool add_line(String &buffer,char *line,char *in_string) { // Add found char to buffer if (inchar == *in_string) *in_string=0; - else if (!*in_string && (inchar == '\'' || inchar == '"')) + else if (!*in_string && (inchar == '\'' || inchar == '"' || inchar == '`')) *in_string=(char) inchar; *out++ = (char) inchar; if (inchar == '*' && !*in_string) diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 1fe3dc86b35..75b875b4f4e 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -43,6 +43,7 @@ static const char* default_dbug_option = "d:t:o,/tmp/mysqlbinlog.trace"; void sql_print_error(const char *format, ...); static bool one_database = 0; +static bool force_opt= 0; static const char* database; static bool short_form = 0; static ulonglong offset = 0; @@ -73,6 +74,9 @@ static struct my_option my_long_options[] = {"database", 'd', "List entries for just this database (local log only)", (gptr*) &database, (gptr*) &database, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"force-read", 'f', "Force reading unknown binlog events", + (gptr*) &force_opt, (gptr*) &force_opt, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, + 0, 0}, {"help", '?', "Display this help and exit", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"host", 'h', "Get the binlog from server", (gptr*) &host, (gptr*) &host, diff --git a/include/Makefile.am b/include/Makefile.am index 83cf4290d3d..4b881d0e7ed 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -34,7 +34,7 @@ noinst_HEADERS = config-win.h config-os2.h config-netware.h \ SUPERCLEANFILES = mysql_version.h my_config.h # Some include files that may be moved and patched by configure -DISTCLEANFILES = sched.h +DISTCLEANFILES = sched.h $(SUPERCLEANFILES) all-local: my_config.h diff --git a/include/config-win.h b/include/config-win.h index 74b2ae71017..9931d2c4b95 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -145,6 +145,9 @@ typedef uint rf_SetTimer; #define USE_MB_IDENT 1 #define USE_STRCOLL 1 +/* If LOAD DATA LOCAL INFILE should be enabled by default */ +#define ENABLED_LOCAL_INFILE 1 + /* Convert some simple functions to Posix */ #define sigset(A,B) signal((A),(B)) diff --git a/include/my_global.h b/include/my_global.h index b6b2dfcda32..e12a7d7273b 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -850,7 +850,13 @@ typedef char bool; /* Ordinary boolean values 0 1 */ ((uint32) (uchar) (A)[0]))) #define sint4korr(A) (*((long *) (A))) #define uint2korr(A) (*((uint16 *) (A))) +#ifdef HAVE_purify +#define uint3korr(A) (uint32) (((uint32) ((uchar) (A)[0])) +\ + (((uint32) ((uchar) (A)[1])) << 8) +\ + (((uint32) ((uchar) (A)[2])) << 16)) +#else #define uint3korr(A) (long) (*((unsigned long *) (A)) & 0xFFFFFF) +#endif #define uint4korr(A) (*((unsigned long *) (A))) #define uint5korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) +\ (((uint32) ((uchar) (A)[1])) << 8) +\ diff --git a/innobase/buf/buf0buf.c b/innobase/buf/buf0buf.c index bbce52f0b00..42799da9d7c 100644 --- a/innobase/buf/buf0buf.c +++ b/innobase/buf/buf0buf.c @@ -480,9 +480,6 @@ buf_pool_create( block = buf_pool_get_nth_block(buf_pool, i); - /* Wipe contents of page to eliminate a Purify warning */ - memset(block->frame, '\0', UNIV_PAGE_SIZE); - UT_LIST_ADD_FIRST(free, buf_pool->free, block); } @@ -1907,7 +1904,7 @@ buf_print_io( / (buf_pool->n_page_gets - buf_pool->n_page_gets_old))); } else { buf += sprintf(buf, - "No buffer pool activity since the last printout\n"); + "No buffer pool page gets since the last printout\n"); } buf_pool->n_page_gets_old = buf_pool->n_page_gets; diff --git a/innobase/include/univ.i b/innobase/include/univ.i index bf606efcf64..e29f3ec92e1 100644 --- a/innobase/include/univ.i +++ b/innobase/include/univ.i @@ -100,6 +100,15 @@ memory is read outside the allocated blocks. */ #define YYDEBUG 1 +#ifdef HAVE_purify +/* The following sets all new allocated memory to zero before use: +this can be used to eliminate unnecessary Purify warnings, but note that +it also masks many bugs Purify could detect. For detailed Purify analysis it +is best to remove the define below and look through the warnings one +by one. */ +#define UNIV_SET_MEM_TO_ZERO +#endif + /* #define UNIV_SQL_DEBUG #define UNIV_LOG_DEBUG diff --git a/innobase/include/ut0dbg.h b/innobase/include/ut0dbg.h index 3407483696c..e99dc8c09d6 100644 --- a/innobase/include/ut0dbg.h +++ b/innobase/include/ut0dbg.h @@ -20,7 +20,6 @@ extern ibool ut_dbg_stop_threads; extern ulint* ut_dbg_null_ptr; - #define ut_a(EXPR)\ {\ ulint dbg_i;\ @@ -31,8 +30,10 @@ extern ulint* ut_dbg_null_ptr; " InnoDB: Assertion failure in thread %lu in file %s line %lu\n",\ os_thread_pf(os_thread_get_curr_id()), IB__FILE__,\ (ulint)__LINE__);\ + fprintf(stderr,\ + "InnoDB: Failing assertion: " #EXPR);\ fprintf(stderr,\ - "InnoDB: We intentionally generate a memory trap.\n");\ + "\nInnoDB: We intentionally generate a memory trap.\n");\ fprintf(stderr,\ "InnoDB: Send a detailed bug report to mysql@lists.mysql.com\n");\ ut_dbg_stop_threads = TRUE;\ diff --git a/innobase/log/log0recv.c b/innobase/log/log0recv.c index dfe67c444b4..47833214d15 100644 --- a/innobase/log/log0recv.c +++ b/innobase/log/log0recv.c @@ -1825,7 +1825,12 @@ recv_report_corrupt_log( "InnoDB: WARNING: the log file may have been corrupt and it\n" "InnoDB: is possible that the log scan did not proceed\n" "InnoDB: far enough in recovery! Please run CHECK TABLE\n" - "InnoDB: on your InnoDB tables to check that they are ok!\n"); + "InnoDB: on your InnoDB tables to check that they are ok!\n" + "InnoDB: If mysqld crashes after this recovery, look at\n" + "InnoDB: section 6.1 of http://www.innodb.com/ibman.html\n" + "InnoDB: about forcing recovery.\n"); + + fflush(stderr); } /*********************************************************** @@ -2462,7 +2467,7 @@ recv_recovery_from_checkpoint_start( log_hdr_buf, max_cp_group); if (0 == ut_memcmp(log_hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, - "ibbackup", ut_strlen("ibbackup"))) { + (byte*)"ibbackup", ut_strlen((char*)"ibbackup"))) { /* This log file was created by ibbackup --restore: print a note to the user about it */ @@ -2473,7 +2478,7 @@ recv_recovery_from_checkpoint_start( /* Wipe over the label now */ ut_memcpy(log_hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, - " ", 4); + (char*)" ", 4); /* Write to the log file to wipe over the label */ fil_io(OS_FILE_WRITE | OS_FILE_LOG, TRUE, max_cp_group->space_id, diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index af4f484b43d..db1119a2abc 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -276,6 +276,17 @@ handle_new_error: "InnoDB: my.cnf and restart the database.\n"); exit(1); + } else if (err == DB_CORRUPTION) { + + fprintf(stderr, + "InnoDB: We detected index corruption in an InnoDB type table.\n" + "InnoDB: You have to dump + drop + reimport the table or, in\n" + "InnoDB: a case of widespread corruption, dump all InnoDB\n" + "InnoDB: tables and recreate the whole InnoDB tablespace.\n" + "InnoDB: If the mysqld server crashes after the startup or when\n" + "InnoDB: you dump the tables, look at section 6.1 of\n" + "InnoDB: http://www.innodb.com/ibman.html for help.\n"); + } else { fprintf(stderr, "InnoDB: unknown error code %lu\n", err); ut_a(0); diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index ccb3755b252..d90b818ad4b 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -2780,9 +2780,6 @@ loop: mutex_exit(&kernel_mutex); - /* We run purge and a batch of ibuf_contract every 10 seconds, even - if the server were active: */ - for (i = 0; i < 10; i++) { n_ios_old = log_sys->n_log_ios + buf_pool->n_pages_read + buf_pool->n_pages_written; @@ -2805,6 +2802,11 @@ loop: goto suspend_thread; } + if (srv_fast_shutdown && srv_shutdown_state > 0) { + + goto background_loop; + } + /* We flush the log once in a second even if no commit is issued or the we have specified in my.cnf no flush at transaction commit */ @@ -2832,11 +2834,6 @@ loop: log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP); log_flush_to_disk(); } - - if (srv_fast_shutdown && srv_shutdown_state > 0) { - - goto background_loop; - } if (srv_activity_count == old_activity_count) { @@ -2867,7 +2864,7 @@ loop: if (n_pend_ios < 3 && (n_ios - n_ios_very_old < 200)) { srv_main_thread_op_info = (char*) "flushing buffer pool pages"; - buf_flush_batch(BUF_FLUSH_LIST, 50, ut_dulint_max); + buf_flush_batch(BUF_FLUSH_LIST, 100, ut_dulint_max); srv_main_thread_op_info = (char*) "flushing log"; log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP); @@ -2926,7 +2923,13 @@ background_loop: /* Flush a few oldest pages to make the checkpoint younger */ - n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 10, ut_dulint_max); + if (srv_fast_shutdown && srv_shutdown_state > 0) { + n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 100, + ut_dulint_max); + } else { + n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 10, + ut_dulint_max); + } srv_main_thread_op_info = (char*)"making checkpoint"; @@ -2993,7 +2996,8 @@ background_loop: } mutex_exit(&kernel_mutex); - srv_main_thread_op_info = (char*) "waiting for buffer pool flush to end"; + srv_main_thread_op_info = + (char*) "waiting for buffer pool flush to end"; buf_flush_wait_batch_end(BUF_FLUSH_LIST); srv_main_thread_op_info = (char*)"making checkpoint"; diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 5cbe0a7d2f3..b23d4b2277b 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -3544,12 +3544,14 @@ int update_state_info(MI_CHECK *param, MI_INFO *info,uint update) } if (update & UPDATE_STAT) { - uint key_parts= mi_uint2korr(share->state.header.key_parts); + uint i, key_parts= mi_uint2korr(share->state.header.key_parts); share->state.rec_per_key_rows=info->state->records; - memcpy((char*) share->state.rec_per_key_part, - (char*) param->rec_per_key_part, - sizeof(*param->rec_per_key_part)*key_parts); share->state.changed&= ~STATE_NOT_ANALYZED; + for (i=0; i<key_parts; i++) + { + if (!(share->state.rec_per_key_part[i]=param->rec_per_key_part[i])) + share->state.changed|= STATE_NOT_ANALYZED; + } } if (update & (UPDATE_STAT | UPDATE_SORT | UPDATE_TIME | UPDATE_AUTO_INC)) { diff --git a/myisam/mi_info.c b/myisam/mi_info.c index 0be3cc44d80..32767e73bb1 100644 --- a/myisam/mi_info.c +++ b/myisam/mi_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 */ -/* Ger tillbaka en struct med information om isam-filen */ +/* Return useful base information for an open table */ #include "myisamdef.h" #ifdef __WIN__ diff --git a/myisam/mi_open.c b/myisam/mi_open.c index 60049325c5c..2f3ef872492 100644 --- a/myisam/mi_open.c +++ b/myisam/mi_open.c @@ -182,6 +182,9 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) } share->state_diff_length=len-MI_STATE_INFO_SIZE; + if (share->state.header.fulltext_keys) + fprintf(stderr, "Table file %s was created in MySQL 4.1+, use REPAIR TABLE ... USE_FRM to recreate it as a valid MySQL 4.0 table\n", name_buff); + mi_state_info_read(disk_cache, &share->state); len= mi_uint2korr(share->state.header.base_info_length); if (len != MI_BASE_INFO_SIZE) diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h index 92eead7b96c..7c035bc6097 100644 --- a/myisam/myisamdef.h +++ b/myisam/myisamdef.h @@ -55,7 +55,8 @@ typedef struct st_mi_state_info uchar uniques; /* number of UNIQUE definitions */ uchar language; /* Language for indexes */ uchar max_block_size; /* max keyblock size */ - uchar not_used[2]; /* To align to 8 */ + uchar fulltext_keys; /* reserved for 4.1 */ + uchar not_used; /* To align to 8 */ } header; MI_STATUS_INFO state; diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index 670ed172c76..cfbc46bc78f 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -160,3 +160,119 @@ Field Type Null Key Default Extra i int(10) unsigned PRI NULL auto_increment c char(10) YES NULL drop table t1; +create table t1 (a int, b int); +insert into t1 values(1,100), (2,100), (3, 100); +insert into t1 values(1,99), (2,99), (3, 99); +insert into t1 values(1,98), (2,98), (3, 98); +insert into t1 values(1,97), (2,97), (3, 97); +insert into t1 values(1,96), (2,96), (3, 96); +insert into t1 values(1,95), (2,95), (3, 95); +insert into t1 values(1,94), (2,94), (3, 94); +insert into t1 values(1,93), (2,93), (3, 93); +insert into t1 values(1,92), (2,92), (3, 92); +insert into t1 values(1,91), (2,91), (3, 91); +insert into t1 values(1,90), (2,90), (3, 90); +insert into t1 values(1,89), (2,89), (3, 89); +insert into t1 values(1,88), (2,88), (3, 88); +insert into t1 values(1,87), (2,87), (3, 87); +insert into t1 values(1,86), (2,86), (3, 86); +insert into t1 values(1,85), (2,85), (3, 85); +insert into t1 values(1,84), (2,84), (3, 84); +insert into t1 values(1,83), (2,83), (3, 83); +insert into t1 values(1,82), (2,82), (3, 82); +insert into t1 values(1,81), (2,81), (3, 81); +insert into t1 values(1,80), (2,80), (3, 80); +insert into t1 values(1,79), (2,79), (3, 79); +insert into t1 values(1,78), (2,78), (3, 78); +insert into t1 values(1,77), (2,77), (3, 77); +insert into t1 values(1,76), (2,76), (3, 76); +insert into t1 values(1,75), (2,75), (3, 75); +insert into t1 values(1,74), (2,74), (3, 74); +insert into t1 values(1,73), (2,73), (3, 73); +insert into t1 values(1,72), (2,72), (3, 72); +insert into t1 values(1,71), (2,71), (3, 71); +insert into t1 values(1,70), (2,70), (3, 70); +insert into t1 values(1,69), (2,69), (3, 69); +insert into t1 values(1,68), (2,68), (3, 68); +insert into t1 values(1,67), (2,67), (3, 67); +insert into t1 values(1,66), (2,66), (3, 66); +insert into t1 values(1,65), (2,65), (3, 65); +insert into t1 values(1,64), (2,64), (3, 64); +insert into t1 values(1,63), (2,63), (3, 63); +insert into t1 values(1,62), (2,62), (3, 62); +insert into t1 values(1,61), (2,61), (3, 61); +insert into t1 values(1,60), (2,60), (3, 60); +insert into t1 values(1,59), (2,59), (3, 59); +insert into t1 values(1,58), (2,58), (3, 58); +insert into t1 values(1,57), (2,57), (3, 57); +insert into t1 values(1,56), (2,56), (3, 56); +insert into t1 values(1,55), (2,55), (3, 55); +insert into t1 values(1,54), (2,54), (3, 54); +insert into t1 values(1,53), (2,53), (3, 53); +insert into t1 values(1,52), (2,52), (3, 52); +insert into t1 values(1,51), (2,51), (3, 51); +insert into t1 values(1,50), (2,50), (3, 50); +insert into t1 values(1,49), (2,49), (3, 49); +insert into t1 values(1,48), (2,48), (3, 48); +insert into t1 values(1,47), (2,47), (3, 47); +insert into t1 values(1,46), (2,46), (3, 46); +insert into t1 values(1,45), (2,45), (3, 45); +insert into t1 values(1,44), (2,44), (3, 44); +insert into t1 values(1,43), (2,43), (3, 43); +insert into t1 values(1,42), (2,42), (3, 42); +insert into t1 values(1,41), (2,41), (3, 41); +insert into t1 values(1,40), (2,40), (3, 40); +insert into t1 values(1,39), (2,39), (3, 39); +insert into t1 values(1,38), (2,38), (3, 38); +insert into t1 values(1,37), (2,37), (3, 37); +insert into t1 values(1,36), (2,36), (3, 36); +insert into t1 values(1,35), (2,35), (3, 35); +insert into t1 values(1,34), (2,34), (3, 34); +insert into t1 values(1,33), (2,33), (3, 33); +insert into t1 values(1,32), (2,32), (3, 32); +insert into t1 values(1,31), (2,31), (3, 31); +insert into t1 values(1,30), (2,30), (3, 30); +insert into t1 values(1,29), (2,29), (3, 29); +insert into t1 values(1,28), (2,28), (3, 28); +insert into t1 values(1,27), (2,27), (3, 27); +insert into t1 values(1,26), (2,26), (3, 26); +insert into t1 values(1,25), (2,25), (3, 25); +insert into t1 values(1,24), (2,24), (3, 24); +insert into t1 values(1,23), (2,23), (3, 23); +insert into t1 values(1,22), (2,22), (3, 22); +insert into t1 values(1,21), (2,21), (3, 21); +insert into t1 values(1,20), (2,20), (3, 20); +insert into t1 values(1,19), (2,19), (3, 19); +insert into t1 values(1,18), (2,18), (3, 18); +insert into t1 values(1,17), (2,17), (3, 17); +insert into t1 values(1,16), (2,16), (3, 16); +insert into t1 values(1,15), (2,15), (3, 15); +insert into t1 values(1,14), (2,14), (3, 14); +insert into t1 values(1,13), (2,13), (3, 13); +insert into t1 values(1,12), (2,12), (3, 12); +insert into t1 values(1,11), (2,11), (3, 11); +insert into t1 values(1,10), (2,10), (3, 10); +insert into t1 values(1,9), (2,9), (3, 9); +insert into t1 values(1,8), (2,8), (3, 8); +insert into t1 values(1,7), (2,7), (3, 7); +insert into t1 values(1,6), (2,6), (3, 6); +insert into t1 values(1,5), (2,5), (3, 5); +insert into t1 values(1,4), (2,4), (3, 4); +insert into t1 values(1,3), (2,3), (3, 3); +insert into t1 values(1,2), (2,2), (3, 2); +insert into t1 values(1,1), (2,1), (3, 1); +alter table t1 add unique (a,b), add key (b); +show keys from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 a 1 a A NULL NULL NULL YES BTREE +t1 0 a 2 b A NULL NULL NULL YES BTREE +t1 1 b 1 b A 100 NULL NULL YES BTREE +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +show keys from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 a 1 a A 3 NULL NULL YES BTREE +t1 0 a 2 b A 300 NULL NULL YES BTREE +t1 1 b 1 b A 100 NULL NULL YES BTREE +drop table t1; diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index edf109fcc93..eaaaf9c8880 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -215,3 +215,14 @@ test.t1 repair status OK select * from t1 where match (a) against ('aaaa'); a drop table t1; +drop table if exists t1; +create table t1 ( ref_mag text not null, fulltext (ref_mag)); +insert into t1 values ('test'); +select ref_mag from t1 where match ref_mag against ('+test' in boolean mode); +ref_mag +test +alter table t1 change ref_mag ref_mag char (255) not null; +select ref_mag from t1 where match ref_mag against ('+test' in boolean mode); +ref_mag +test +drop table t1; diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result index f73c4d7f8af..94e1ce59585 100644 --- a/mysql-test/r/group_by.result +++ b/mysql-test/r/group_by.result @@ -27,6 +27,8 @@ PRIMARY KEY (userID) INSERT INTO t2 VALUES (1,'name','pass','mail','Y','v','n','adr','1','1','1'); INSERT INTO t2 VALUES (2,'name','pass','mail','Y','v','n','adr','1','1','1'); INSERT INTO t2 VALUES (3,'name','pass','mail','Y','v','n','adr','1','1','1'); +INSERT INTO t2 VALUES (4,'name','pass','mail','Y','v','n','adr','1','1','1'); +INSERT INTO t2 VALUES (5,'name','pass','mail','Y','v','n','adr','1','1','1'); SELECT t2.userid, MIN(t1.score) FROM t1, t2 WHERE t1.userID=t2.userID GROUP BY t2.userid; userid MIN(t1.score) 1 1 @@ -47,8 +49,12 @@ userid MIN(t1.score+0.0) 2 2.0 SELECT t2.userid, MIN(t1.score+0.0) FROM t1, t2 WHERE t1.userID=t2.userID AND t1.spID=2 GROUP BY t2.userid ORDER BY NULL; userid MIN(t1.score+0.0) -1 1.0 2 2.0 +1 1.0 +EXPLAIN SELECT t2.userid, MIN(t1.score+0.0) FROM t1, t2 WHERE t1.userID=t2.userID AND t1.spID=2 GROUP BY t2.userid ORDER BY NULL; +table type possible_keys key key_len ref rows Extra +t1 ALL NULL NULL NULL NULL 4 Using where; Using temporary +t2 eq_ref PRIMARY PRIMARY 4 t1.userID 1 Using index drop table test.t1,test.t2; CREATE TABLE t1 ( PID int(10) unsigned NOT NULL auto_increment, @@ -242,34 +248,32 @@ score smallint(5) unsigned, key (spid), key (score) ); -INSERT INTO t1 VALUES (1,1,1),(2,2,2),(2,1,1),(3,3,3),(4,3,3),(5,3,3); +INSERT INTO t1 VALUES (1,1,1),(2,2,2),(2,1,1),(3,3,3),(4,3,3),(5,3,3),(6,3,3),(7,3,3); explain select userid,count(*) from t1 group by userid desc; table type possible_keys key key_len ref rows Extra -t1 ALL NULL NULL NULL NULL 6 Using temporary; Using filesort +t1 ALL NULL NULL NULL NULL 8 Using temporary; Using filesort explain select userid,count(*) from t1 group by userid desc order by null; table type possible_keys key key_len ref rows Extra -t1 ALL NULL NULL NULL NULL 6 Using temporary +t1 ALL NULL NULL NULL NULL 8 Using temporary select userid,count(*) from t1 group by userid desc; userid count(*) -3 3 +3 5 2 1 1 2 select userid,count(*) from t1 group by userid desc having (count(*)+1) IN (4,3); userid count(*) -3 3 1 2 select userid,count(*) from t1 group by userid desc having 3 IN (1,COUNT(*)); userid count(*) -3 3 explain select spid,count(*) from t1 where spid between 1 and 2 group by spid desc; table type possible_keys key key_len ref rows Extra -t1 range spID spID 5 NULL 2 Using where; Using index +t1 range spID spID 5 NULL 3 Using where; Using index explain select spid,count(*) from t1 where spid between 1 and 2 group by spid; table type possible_keys key key_len ref rows Extra -t1 range spID spID 5 NULL 2 Using where; Using index +t1 range spID spID 5 NULL 3 Using where; Using index explain select spid,count(*) from t1 where spid between 1 and 2 group by spid order by null; table type possible_keys key key_len ref rows Extra -t1 range spID spID 5 NULL 2 Using where; Using index +t1 range spID spID 5 NULL 3 Using where; Using index select spid,count(*) from t1 where spid between 1 and 2 group by spid; spid count(*) 1 1 @@ -280,12 +284,14 @@ spid count(*) 1 1 explain select sql_big_result spid,sum(userid) from t1 group by spid desc; table type possible_keys key key_len ref rows Extra -t1 ALL NULL NULL NULL NULL 6 Using filesort +t1 ALL NULL NULL NULL NULL 8 Using filesort explain select sql_big_result spid,sum(userid) from t1 group by spid desc order by null; table type possible_keys key key_len ref rows Extra -t1 ALL NULL NULL NULL NULL 6 +t1 ALL NULL NULL NULL NULL 8 select sql_big_result spid,sum(userid) from t1 group by spid desc; spid sum(userid) +7 3 +6 3 5 3 4 3 3 3 @@ -293,13 +299,13 @@ spid sum(userid) 1 1 explain select sql_big_result score,count(*) from t1 group by score desc; table type possible_keys key key_len ref rows Extra -t1 index NULL score 3 NULL 6 Using index +t1 index NULL score 3 NULL 8 Using index explain select sql_big_result score,count(*) from t1 group by score desc order by null; table type possible_keys key key_len ref rows Extra -t1 index NULL score 3 NULL 6 Using index +t1 index NULL score 3 NULL 8 Using index select sql_big_result score,count(*) from t1 group by score desc; score count(*) -3 3 +3 5 2 1 1 2 drop table t1; @@ -535,15 +541,7 @@ t1 ALL NULL NULL NULL NULL 6 Using temporary t2 ALL a NULL NULL NULL 4 Using where drop table t1,t2; create table t1 (a int, b int); -insert into t1 values (1, 4); -insert into t1 values (10, 40); -insert into t1 values (1, 4); -insert into t1 values (10, 43); -insert into t1 values (1, 4); -insert into t1 values (10, 41); -insert into t1 values (1, 4); -insert into t1 values (10, 43); -insert into t1 values (1, 4); +insert into t1 values (1, 4),(10, 40),(1, 4),(10, 43),(1, 4),(10, 41),(1, 4),(10, 43),(1, 4); select a, MAX(b), INTERVAL (MAX(b), 1,3,10,30,39,40,50,60,100,1000) from t1 group by a; a MAX(b) INTERVAL (MAX(b), 1,3,10,30,39,40,50,60,100,1000) 1 4 2 diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 96bc66222d3..aefcd135dd8 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -208,7 +208,7 @@ create index skr on t1 (a); insert into t1 values (3,""), (4,"testing"); analyze table t1; Table Op Msg_type Msg_text -test.t1 analyze error The handler for the table doesn't support analyze +test.t1 analyze status OK show keys from t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment t1 1 skr 1 a A 3 NULL NULL YES BTREE @@ -1219,4 +1219,74 @@ parent child 1 2 1 3 2 1 +create table t1 (a int not null auto_increment primary key, b int, c int, key(c)) type=innodb; +create table t2 (a int not null auto_increment primary key, b int); +insert into t1 (b) values (null),(null),(null),(null),(null),(null),(null); +insert into t2 (a) select b from t1; +insert into t1 (b) select b from t2; +insert into t2 (a) select b from t1; +insert into t1 (a) select b from t2; +insert into t2 (a) select b from t1; +insert into t1 (a) select b from t2; +insert into t2 (a) select b from t1; +insert into t1 (a) select b from t2; +insert into t2 (a) select b from t1; +insert into t1 (a) select b from t2; +insert into t2 (a) select b from t1; +insert into t1 (a) select b from t2; +insert into t2 (a) select b from t1; +insert into t1 (a) select b from t2; +insert into t2 (a) select b from t1; +insert into t1 (a) select b from t2; +insert into t2 (a) select b from t1; +insert into t1 (a) select b from t2; +select count(*) from t1; +count(*) +29267 +explain select a from t1 where a between 1 and 10000; +table type possible_keys key key_len ref rows Extra +t1 range PRIMARY PRIMARY 4 NULL 14745 Using where; Using index +explain select * from t1 where a between 1 and 10000; +table type possible_keys key key_len ref rows Extra +t1 range PRIMARY PRIMARY 4 NULL 14745 Using where +explain select * from t1 where c between 1 and 10000; +table type possible_keys key key_len ref rows Extra +t1 range c c 5 NULL 1 Using where +update t1 set c=a; +explain select * from t1 where c between 1 and 10000; +table type possible_keys key key_len ref rows Extra +t1 ALL c NULL NULL NULL 29537 Using where +drop table t1,t2; +create table t1 (id int primary key auto_increment, fk int, index index_fk (fk)) type=innodb; +insert into t1 (id) values (null),(null),(null),(null),(null); +update t1 set fk=69 where fk is null order by id limit 1; +SELECT * from t1; +id fk +2 NULL +3 NULL +4 NULL +5 NULL +1 69 +drop table t1; +create table t1 (a int not null, b int not null, key (a)); +insert into t1 values (1,1),(1,2),(1,3),(3,1),(3,2),(3,3),(3,1),(3,2),(3,3),(2,1),(2,2),(2,3); +SET @tmp=0; +update t1 set b=(@tmp:=@tmp+1) order by a; +update t1 set b=99 where a=1 order by b asc limit 1; +update t1 set b=100 where a=1 order by b desc limit 2; +update t1 set a=a+10+b where a=1 order by b; +select * from t1 order by a,b; +a b +2 4 +2 5 +2 6 +3 7 +3 8 +3 9 +3 10 +3 11 +3 12 +13 2 +111 100 +111 100 drop table t1; diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result index e68f3e6b006..fe30458d8de 100644 --- a/mysql-test/r/join_outer.result +++ b/mysql-test/r/join_outer.result @@ -373,10 +373,10 @@ Thimble Smith Happy 3 3 3 drop table t1,t2; create table t1 (id int not null, str char(10), index(str)); insert into t1 values (1, null), (2, null), (3, "foo"), (4, "bar"); -select * from t1 where str is not null; +select * from t1 where str is not null order by id; id str -4 bar 3 foo +4 bar select * from t1 where str is null; id str 1 NULL diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result index 75c22caaa72..91170f885a3 100644 --- a/mysql-test/r/multi_update.result +++ b/mysql-test/r/multi_update.result @@ -286,7 +286,7 @@ a b 107 7 108 8 109 9 -update t1,t2 set t1.b=t1.b+2,t2.b=t1.b where t1.b between 3 and 5; +update t1,t2 set t1.b=t1.b+2,t2.b=t1.b+10 where t1.b between 3 and 5 and t2.a=t1.a-100; select * from t1; a b 201 1 @@ -300,15 +300,15 @@ a b 109 9 select * from t2; a b -1 3 -2 3 -3 3 -4 3 -5 3 -6 3 -7 3 -8 3 -9 3 +1 1 +2 2 +3 13 +4 14 +5 15 +6 6 +7 7 +8 8 +9 9 drop table t1,t2; CREATE TABLE t3 ( KEY1 varchar(50) NOT NULL default '', PARAM_CORR_DISTANCE_RUSH double default NULL, PARAM_CORR_DISTANCE_GEM double default NULL, PARAM_AVG_TARE double default NULL, PARAM_AVG_NB_DAYS double default NULL, PARAM_DEFAULT_PROP_GEM_SRVC varchar(50) default NULL, PARAM_DEFAULT_PROP_GEM_NO_ETIK varchar(50) default NULL, PARAM_SCENARIO_COSTS varchar(50) default NULL, PARAM_DEFAULT_WAGON_COST double default NULL, tmp int(11) default NULL, PRIMARY KEY (KEY1)) TYPE=MyISAM; INSERT INTO t3 VALUES ('A',1,1,22,3.2,'R','R','BASE2',0.24,NULL); diff --git a/mysql-test/r/null_key.result b/mysql-test/r/null_key.result index 236def64b5e..009a3e06eb2 100644 --- a/mysql-test/r/null_key.result +++ b/mysql-test/r/null_key.result @@ -84,7 +84,7 @@ table type possible_keys key key_len ref rows Extra t1 range a,b a 5 NULL 5 Using where explain select * from t1 where (a is null or a = 7) and b=7 and c=0; table type possible_keys key key_len ref rows Extra -t1 range a,b a 5 NULL 4 Using where +t1 ALL a,b NULL NULL NULL 12 Using where explain select * from t1 where (a is null and b>a) or a is null and b=7 limit 2; table type possible_keys key key_len ref rows Extra t1 ref a,b a 5 const 3 Using where diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index 79c6c9fa6fb..ff2dd93311c 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -517,3 +517,28 @@ SELECT titre,t1.numeropost,auteur,icone,nbrep,'0',date,vue,ouvert,lastauteur,des titre numeropost auteur icone nbrep 0 date vue ouvert lastauteur dest test 1 joce 0 0 0 0000-00-00 00:00:00 0 1 bug drop table t1,t2; +CREATE TABLE t1 (a int, b int); +INSERT INTO t1 VALUES (1, 2); +INSERT INTO t1 VALUES (3, 4); +INSERT INTO t1 VALUES (5, NULL); +SELECT * FROM t1 ORDER BY b; +a b +5 NULL +1 2 +3 4 +SELECT * FROM t1 ORDER BY b DESC; +a b +3 4 +1 2 +5 NULL +SELECT * FROM t1 ORDER BY (a + b); +a b +5 NULL +1 2 +3 4 +SELECT * FROM t1 ORDER BY (a + b) DESC; +a b +3 4 +1 2 +5 NULL +DROP TABLE t1; diff --git a/mysql-test/r/select_safe.result b/mysql-test/r/select_safe.result index 8f2b621ac8a..3303f19d9c7 100644 --- a/mysql-test/r/select_safe.result +++ b/mysql-test/r/select_safe.result @@ -1,6 +1,6 @@ drop table if exists t1; SET SQL_SAFE_UPDATES=1,SQL_SELECT_LIMIT=4, SQL_MAX_JOIN_SIZE=9; -create table t1 (a int primary key, b char(20)); +create table t1 (a int auto_increment primary key, b char(20)); insert into t1 values(1,"test"); SELECT SQL_BUFFER_RESULT * from t1; a b @@ -30,10 +30,34 @@ You are using safe update mode and you tried to update a table without a WHERE t delete from t1 where a+0=1; You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column select 1 from t1,t1 as t2,t1 as t3,t1 as t4,t1 as t5; -The SELECT would examine too many records and probably take a very long time. Check your WHERE and use SET SQL_BIG_SELECTS=1 if the SELECT is ok +The SELECT would examine more rows than MAX_JOIN_SIZE. Check your WHERE and use SET SQL_BIG_SELECTS=1 or SET SQL_MAX_JOIN_SIZE=# if the SELECT is ok update t1 set b="a" limit 1; update t1 set b="a" where b="b" limit 2; delete from t1 where b="test" limit 1; delete from t1 where a+0=1 limit 2; +SET MAX_JOIN_SIZE=2; +SELECT @@MAX_JOIN_SIZE, @@SQL_BIG_SELECTS; +@@max_join_size @@sql_big_selects +2 0 +insert into t1 values (null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"); +SELECT * from t1; +The SELECT would examine more rows than MAX_JOIN_SIZE. Check your WHERE and use SET SQL_BIG_SELECTS=1 or SET SQL_MAX_JOIN_SIZE=# if the SELECT is ok +SET SQL_BIG_SELECTS=1; +SELECT * from t1; +a b +3 a +2 test2 +4 a +5 a +SET MAX_JOIN_SIZE=2; +SELECT * from t1; +The SELECT would examine more rows than MAX_JOIN_SIZE. Check your WHERE and use SET SQL_BIG_SELECTS=1 or SET SQL_MAX_JOIN_SIZE=# if the SELECT is ok +SET MAX_JOIN_SIZE=DEFAULT; +SELECT * from t1; +a b +3 a +2 test2 +4 a +5 a drop table t1; SET SQL_SAFE_UPDATES=0,SQL_SELECT_LIMIT=DEFAULT, SQL_MAX_JOIN_SIZE=DEFAULT; diff --git a/mysql-test/r/update.result b/mysql-test/r/update.result index db209c5855c..86647e845a9 100644 --- a/mysql-test/r/update.result +++ b/mysql-test/r/update.result @@ -102,13 +102,39 @@ select status from t1; status 1 drop table t1; -create table t1 (a int not null, b int not null); -insert into t1 values (1,1),(1,2),(1,3); -update t1 set b=4 where a=1 order by b asc limit 1; -update t1 set b=4 where a=1 order by b desc limit 1; -select * from t1; +create table t1 (a int not null, b int not null, key (a)); +insert into t1 values (1,1),(1,2),(1,3),(3,1),(3,2),(3,3),(3,1),(3,2),(3,3),(2,1),(2,2),(2,3); +SET @tmp=0; +update t1 set b=(@tmp:=@tmp+1) order by a; +update t1 set b=99 where a=1 order by b asc limit 1; +select * from t1 order by a,b; a b -1 4 1 2 -1 4 +1 3 +1 99 +2 4 +2 5 +2 6 +3 7 +3 8 +3 9 +3 10 +3 11 +3 12 +update t1 set b=100 where a=1 order by b desc limit 2; +update t1 set a=a+10+b where a=1 order by b; +select * from t1 order by a,b; +a b +2 4 +2 5 +2 6 +3 7 +3 8 +3 9 +3 10 +3 11 +3 12 +13 2 +111 100 +111 100 drop table t1; diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test index d32c554aec8..96f969c8776 100644 --- a/mysql-test/t/alter_table.test +++ b/mysql-test/t/alter_table.test @@ -117,3 +117,19 @@ alter table t1 rename t2; alter table t2 rename t1, add c char(10) comment "no comment"; show columns from t1; drop table t1; + +# implicit analyze + +create table t1 (a int, b int); +let $1=100; +while ($1) +{ + eval insert into t1 values(1,$1), (2,$1), (3, $1); + dec $1; +} +alter table t1 add unique (a,b), add key (b); +show keys from t1; +analyze table t1; +show keys from t1; +drop table t1; + diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test index 5a64f2614aa..128af680854 100644 --- a/mysql-test/t/fulltext.test +++ b/mysql-test/t/fulltext.test @@ -173,3 +173,16 @@ repair table t1; select * from t1 where match (a) against ('aaaa'); drop table t1; +# +# bug 283 by jocelyn fournier <joc@presence-pc.com> +# FULLTEXT index on a TEXT filed converted to a CHAR field doesn't work anymore +# + +drop table if exists t1; +create table t1 ( ref_mag text not null, fulltext (ref_mag)); +insert into t1 values ('test'); +select ref_mag from t1 where match ref_mag against ('+test' in boolean mode); +alter table t1 change ref_mag ref_mag char (255) not null; +select ref_mag from t1 where match ref_mag against ('+test' in boolean mode); +drop table t1; + diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test index 9e5ee4b8b2a..67f4eb580a6 100644 --- a/mysql-test/t/group_by.test +++ b/mysql-test/t/group_by.test @@ -34,12 +34,15 @@ CREATE TABLE t2 ( INSERT INTO t2 VALUES (1,'name','pass','mail','Y','v','n','adr','1','1','1'); INSERT INTO t2 VALUES (2,'name','pass','mail','Y','v','n','adr','1','1','1'); INSERT INTO t2 VALUES (3,'name','pass','mail','Y','v','n','adr','1','1','1'); +INSERT INTO t2 VALUES (4,'name','pass','mail','Y','v','n','adr','1','1','1'); +INSERT INTO t2 VALUES (5,'name','pass','mail','Y','v','n','adr','1','1','1'); SELECT t2.userid, MIN(t1.score) FROM t1, t2 WHERE t1.userID=t2.userID GROUP BY t2.userid; SELECT t2.userid, MIN(t1.score) FROM t1, t2 WHERE t1.userID=t2.userID GROUP BY t2.userid ORDER BY NULL; SELECT t2.userid, MIN(t1.score) FROM t1, t2 WHERE t1.userID=t2.userID AND t1.spID=2 GROUP BY t2.userid; SELECT t2.userid, MIN(t1.score+0.0) FROM t1, t2 WHERE t1.userID=t2.userID AND t1.spID=2 GROUP BY t2.userid; SELECT t2.userid, MIN(t1.score+0.0) FROM t1, t2 WHERE t1.userID=t2.userID AND t1.spID=2 GROUP BY t2.userid ORDER BY NULL; +EXPLAIN SELECT t2.userid, MIN(t1.score+0.0) FROM t1, t2 WHERE t1.userID=t2.userID AND t1.spID=2 GROUP BY t2.userid ORDER BY NULL; drop table test.t1,test.t2; # @@ -236,7 +239,7 @@ CREATE TABLE t1 ( key (score) ); -INSERT INTO t1 VALUES (1,1,1),(2,2,2),(2,1,1),(3,3,3),(4,3,3),(5,3,3); +INSERT INTO t1 VALUES (1,1,1),(2,2,2),(2,1,1),(3,3,3),(4,3,3),(5,3,3),(6,3,3),(7,3,3); explain select userid,count(*) from t1 group by userid desc; explain select userid,count(*) from t1 group by userid desc order by null; select userid,count(*) from t1 group by userid desc; @@ -255,8 +258,6 @@ explain select sql_big_result score,count(*) from t1 group by score desc order b select sql_big_result score,count(*) from t1 group by score desc; drop table t1; -# - # not purely group_by bug, but group_by is involved... create table t1 (a date default null, b date default null); @@ -265,7 +266,6 @@ select a,min(b) c,count(distinct rand()) from t1 group by a having c<a + interva drop table t1; # Compare with hash keys -# CREATE TABLE t1 (a char(1)); INSERT INTO t1 VALUES ('A'),('B'),('A'),('B'),('A'),('B'),(NULL),('a'),('b'),(NULL),('A'),('B'),(NULL); @@ -401,15 +401,7 @@ drop table t1,t2; # create table t1 (a int, b int); -insert into t1 values (1, 4); -insert into t1 values (10, 40); -insert into t1 values (1, 4); -insert into t1 values (10, 43); -insert into t1 values (1, 4); -insert into t1 values (10, 41); -insert into t1 values (1, 4); -insert into t1 values (10, 43); -insert into t1 values (1, 4); +insert into t1 values (1, 4),(10, 40),(1, 4),(10, 43),(1, 4),(10, 41),(1, 4),(10, 43),(1, 4); select a, MAX(b), INTERVAL (MAX(b), 1,3,10,30,39,40,50,60,100,1000) from t1 group by a; select a, MAX(b), CASE MAX(b) when 4 then 4 when 43 then 43 else 0 end from t1 group by a; select a, MAX(b), FIELD(MAX(b), '43', '4', '5') from t1 group by a; diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index b8929d5c4de..393112beb27 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -809,4 +809,58 @@ drop table t1,t2; create table t1 ( pk int primary key, parent int not null, child int not null, index (parent) ) type = innodb; insert into t1 values (1,0,4), (2,1,3), (3,2,1), (4,1,2); select distinct parent,child from t1 order by parent; +drop table t1,t2; + +# +# Test that MySQL priorities clustered indexes +# + +create table t1 (a int not null auto_increment primary key, b int, c int, key(c)) type=innodb; +create table t2 (a int not null auto_increment primary key, b int); +insert into t1 (b) values (null),(null),(null),(null),(null),(null),(null); +insert into t2 (a) select b from t1; +insert into t1 (b) select b from t2; +insert into t2 (a) select b from t1; +insert into t1 (a) select b from t2; +insert into t2 (a) select b from t1; +insert into t1 (a) select b from t2; +insert into t2 (a) select b from t1; +insert into t1 (a) select b from t2; +insert into t2 (a) select b from t1; +insert into t1 (a) select b from t2; +insert into t2 (a) select b from t1; +insert into t1 (a) select b from t2; +insert into t2 (a) select b from t1; +insert into t1 (a) select b from t2; +insert into t2 (a) select b from t1; +insert into t1 (a) select b from t2; +insert into t2 (a) select b from t1; +insert into t1 (a) select b from t2; +select count(*) from t1; +explain select a from t1 where a between 1 and 10000; +explain select * from t1 where a between 1 and 10000; +explain select * from t1 where c between 1 and 10000; +update t1 set c=a; +explain select * from t1 where c between 1 and 10000; +drop table t1,t2; + +# +# Test of UPDATE ... ORDER BY +# + +create table t1 (id int primary key auto_increment, fk int, index index_fk (fk)) type=innodb; + +insert into t1 (id) values (null),(null),(null),(null),(null); +update t1 set fk=69 where fk is null order by id limit 1; +SELECT * from t1; +drop table t1; + +create table t1 (a int not null, b int not null, key (a)); +insert into t1 values (1,1),(1,2),(1,3),(3,1),(3,2),(3,3),(3,1),(3,2),(3,3),(2,1),(2,2),(2,3); +SET @tmp=0; +update t1 set b=(@tmp:=@tmp+1) order by a; +update t1 set b=99 where a=1 order by b asc limit 1; +update t1 set b=100 where a=1 order by b desc limit 2; +update t1 set a=a+10+b where a=1 order by b; +select * from t1 order by a,b; drop table t1; diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test index 80fa6501758..e172d54194e 100644 --- a/mysql-test/t/join_outer.test +++ b/mysql-test/t/join_outer.test @@ -248,7 +248,7 @@ drop table t1,t2; create table t1 (id int not null, str char(10), index(str)); insert into t1 values (1, null), (2, null), (3, "foo"), (4, "bar"); -select * from t1 where str is not null; +select * from t1 where str is not null order by id; select * from t1 where str is null; drop table t1; diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test index 04f3508e078..0c7ad6160ee 100644 --- a/mysql-test/t/multi_update.test +++ b/mysql-test/t/multi_update.test @@ -247,7 +247,7 @@ update t1,t2 set t1.b=t1.b+10 where t1.b=2; select * from t1; # Range key (in t1) -update t1,t2 set t1.b=t1.b+2,t2.b=t1.b where t1.b between 3 and 5; +update t1,t2 set t1.b=t1.b+2,t2.b=t1.b+10 where t1.b between 3 and 5 and t2.a=t1.a-100; select * from t1; select * from t2; diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index 06a5d0ceb20..1fb83509ebb 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -331,3 +331,17 @@ INSERT INTO t2 (numeropost,pseudo) VALUES (1,'joce'),(1,'bug'); SELECT titre,t1.numeropost,auteur,icone,nbrep,0,date,vue,ouvert,lastauteur,dest FROM t2 LEFT JOIN t1 USING(numeropost) WHERE t2.pseudo='joce' ORDER BY date DESC LIMIT 0,30; SELECT titre,t1.numeropost,auteur,icone,nbrep,'0',date,vue,ouvert,lastauteur,dest FROM t2 LEFT JOIN t1 USING(numeropost) WHERE t2.pseudo='joce' ORDER BY date DESC LIMIT 0,30; drop table t1,t2; + +# +# Test order by with NULL values +# +CREATE TABLE t1 (a int, b int); +INSERT INTO t1 VALUES (1, 2); +INSERT INTO t1 VALUES (3, 4); +INSERT INTO t1 VALUES (5, NULL); +SELECT * FROM t1 ORDER BY b; +SELECT * FROM t1 ORDER BY b DESC; +SELECT * FROM t1 ORDER BY (a + b); +SELECT * FROM t1 ORDER BY (a + b) DESC; +DROP TABLE t1; + diff --git a/mysql-test/t/select_safe.test b/mysql-test/t/select_safe.test index e76b7558997..a085cfee29d 100644 --- a/mysql-test/t/select_safe.test +++ b/mysql-test/t/select_safe.test @@ -4,7 +4,7 @@ drop table if exists t1; SET SQL_SAFE_UPDATES=1,SQL_SELECT_LIMIT=4, SQL_MAX_JOIN_SIZE=9; -create table t1 (a int primary key, b char(20)); +create table t1 (a int auto_increment primary key, b char(20)); insert into t1 values(1,"test"); SELECT SQL_BUFFER_RESULT * from t1; update t1 set b="a" where a=1; @@ -15,18 +15,40 @@ update t1 set b="a" where a=1; select 1 from t1,t1 as t2,t1 as t3,t1 as t4; # The following should give errors: -!$1175 update t1 set b="a"; -!$1175 update t1 set b="a" where b="test"; -!$1175 delete from t1; -!$1175 delete from t1 where b="test"; -!$1175 delete from t1 where a+0=1; -!$1104 select 1 from t1,t1 as t2,t1 as t3,t1 as t4,t1 as t5; +--error 1175 +update t1 set b="a"; +--error 1175 +update t1 set b="a" where b="test"; +--error 1175 +delete from t1; +--error 1175 +delete from t1 where b="test"; +--error 1175 +delete from t1 where a+0=1; +--error 1104 +select 1 from t1,t1 as t2,t1 as t3,t1 as t4,t1 as t5; # The following should be ok: update t1 set b="a" limit 1; update t1 set b="a" where b="b" limit 2; delete from t1 where b="test" limit 1; delete from t1 where a+0=1 limit 2; + +# Test SQL_BIG_SELECTS + +SET MAX_JOIN_SIZE=2; +SELECT @@MAX_JOIN_SIZE, @@SQL_BIG_SELECTS; +insert into t1 values (null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"); +--error 1104 +SELECT * from t1; +SET SQL_BIG_SELECTS=1; +SELECT * from t1; +SET MAX_JOIN_SIZE=2; +--error 1104 +SELECT * from t1; +SET MAX_JOIN_SIZE=DEFAULT; +SELECT * from t1; + drop table t1; SET SQL_SAFE_UPDATES=0,SQL_SELECT_LIMIT=DEFAULT, SQL_MAX_JOIN_SIZE=DEFAULT; diff --git a/mysql-test/t/update.test b/mysql-test/t/update.test index 76a27b62206..359ae815197 100644 --- a/mysql-test/t/update.test +++ b/mysql-test/t/update.test @@ -81,9 +81,13 @@ drop table t1; # Test of ORDER BY # -create table t1 (a int not null, b int not null); -insert into t1 values (1,1),(1,2),(1,3); -update t1 set b=4 where a=1 order by b asc limit 1; -update t1 set b=4 where a=1 order by b desc limit 1; -select * from t1; +create table t1 (a int not null, b int not null, key (a)); +insert into t1 values (1,1),(1,2),(1,3),(3,1),(3,2),(3,3),(3,1),(3,2),(3,3),(2,1),(2,2),(2,3); +SET @tmp=0; +update t1 set b=(@tmp:=@tmp+1) order by a; +update t1 set b=99 where a=1 order by b asc limit 1; +select * from t1 order by a,b; +update t1 set b=100 where a=1 order by b desc limit 2; +update t1 set a=a+10+b where a=1 order by b; +select * from t1 order by a,b; drop table t1; diff --git a/mysys/default.c b/mysys/default.c index a3942425b7d..26121cc0e56 100644 --- a/mysys/default.c +++ b/mysys/default.c @@ -249,7 +249,8 @@ static my_bool search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc, MY_STAT stat_info; if (!my_stat(name,&stat_info,MYF(0))) return 0; - if (stat_info.st_mode & S_IWOTH) /* ignore world-writeable files */ + /* ignore world-writeable _regular_ files */ + if (stat_info.st_mode & S_IWOTH && stat_info.st_mode & S_IFREG) { fprintf(stderr, "warning: World-writeable config file %s is ignored\n", name); diff --git a/netware/BUILD/compile-AUTOTOOLS b/netware/BUILD/compile-AUTOTOOLS index 0688ea5aaca..57213b1b3d0 100755 --- a/netware/BUILD/compile-AUTOTOOLS +++ b/netware/BUILD/compile-AUTOTOOLS @@ -1,5 +1,11 @@ #! /bin/sh +# debug +#set -x + +# stop on errors +set -e + for package in . ./innobase do (cd $package diff --git a/netware/BUILD/compile-linux-tools b/netware/BUILD/compile-linux-tools index 598be96ab66..3590a900338 100755 --- a/netware/BUILD/compile-linux-tools +++ b/netware/BUILD/compile-linux-tools @@ -1,8 +1,11 @@ #! /bin/sh -#debug +# debug #set -x +# stop on errors +set -e + if test ! -r ./sql/mysqld.cc then echo "you must start from the top source directory" diff --git a/netware/BUILD/compile-netware-END b/netware/BUILD/compile-netware-END index beb15fbeda3..e0097484500 100755 --- a/netware/BUILD/compile-netware-END +++ b/netware/BUILD/compile-netware-END @@ -1,5 +1,11 @@ #! /bin/sh +# debug +#set -x + +# stop on errors +set -e + path=`dirname $0` # clean diff --git a/netware/BUILD/compile-netware-START b/netware/BUILD/compile-netware-START index 2941d8868e4..7eef192a907 100755 --- a/netware/BUILD/compile-netware-START +++ b/netware/BUILD/compile-netware-START @@ -1,8 +1,11 @@ #! /bin/sh -#debug +# debug #set -x +# stop on errors +set -e + if test ! -r ./sql/mysqld.cc then echo "you must start from the top source directory" diff --git a/netware/BUILD/compile-netware-all b/netware/BUILD/compile-netware-all index f8dea0f7583..35d275f3b42 100755 --- a/netware/BUILD/compile-netware-all +++ b/netware/BUILD/compile-netware-all @@ -1,5 +1,11 @@ #! /bin/sh +# debug +#set -x + +# stop on errors +set -e + path=`dirname $0` $path/compile-netware-standard diff --git a/netware/BUILD/compile-netware-debug b/netware/BUILD/compile-netware-debug index 2cd292c82fd..e44d64e3074 100755 --- a/netware/BUILD/compile-netware-debug +++ b/netware/BUILD/compile-netware-debug @@ -1,5 +1,11 @@ #! /bin/sh +# debug +#set -x + +# stop on errors +set -e + path=`dirname $0` . $path/compile-netware-START diff --git a/netware/BUILD/compile-netware-standard b/netware/BUILD/compile-netware-standard index c09337b5fe0..12cae1f024e 100755 --- a/netware/BUILD/compile-netware-standard +++ b/netware/BUILD/compile-netware-standard @@ -1,5 +1,12 @@ #! /bin/sh +# debug +#set -x + +# stop on errors +set -e + + path=`dirname $0` . $path/compile-netware-START diff --git a/netware/BUILD/cron-build b/netware/BUILD/cron-build new file mode 100755 index 00000000000..26ccde28e2a --- /dev/null +++ b/netware/BUILD/cron-build @@ -0,0 +1,46 @@ +#! /bin/sh + +# debug +#set -x + +# stop on errors +set -e + +# repository direcotry +repo_dir=`pwd` + +# show usage +show_usage() +{ + cat << EOF + +usage: cron-patch + +EOF + exit 0; +} + +echo "starting build..." + +# check for bk and repo_dir +bk help > /dev/null +repo_dir=`bk root $repo_dir` +cd $repo_dir + +# pull latest code +echo 'y' | bk pull + +# determine version +version=`grep -e "AM_INIT_AUTOMAKE(mysql, .*)" < configure.in | sed -e "s/AM_INIT_AUTOMAKE(mysql, \(.*\))/\1/"` +echo "version: $version" + +# latest revision +rev=`bk changes -e -n -d':REV:' | head -1` +echo "latest revision: $rev" + +# run bootstrap +./netware/BUILD/nwbootstrap --revision=$rev --suffix=$rev --build=all + +echo "done" + + diff --git a/netware/BUILD/crontab b/netware/BUILD/crontab new file mode 100755 index 00000000000..0097f8acaaf --- /dev/null +++ b/netware/BUILD/crontab @@ -0,0 +1,4 @@ +00 23 * * * (export PATH='/usr/local/bin:/usr/bin:/bin'; export DISPLAY=':0'; cd ~/bk/mysqldoc; echo 'y' | bk pull) +00 00 * * * (export PATH='/usr/local/bin:/usr/bin:/bin'; export DISPLAY=':0'; cd ~/bk/mysql-4.0; ./netware/BUILD/cron-build) +00 04 * * * (export PATH='/usr/local/bin:/usr/bin:/bin'; export DISPLAY=':0'; cd ~/bk/mysql-4.1; ./netware/BUILD/cron-build) + diff --git a/netware/BUILD/mwasmnlm b/netware/BUILD/mwasmnlm index c3501112aa5..381f84ec0c8 100755 --- a/netware/BUILD/mwasmnlm +++ b/netware/BUILD/mwasmnlm @@ -1,5 +1,8 @@ #! /bin/sh +# stop on errors +set -e + args=" $*" wine --debugmsg -all -- mwasmnlm $args diff --git a/netware/BUILD/mwccnlm b/netware/BUILD/mwccnlm index 9e989485bd9..cb2d62fe8cf 100755 --- a/netware/BUILD/mwccnlm +++ b/netware/BUILD/mwccnlm @@ -1,5 +1,8 @@ #! /bin/sh +# stop on errors +set -e + # mwccnlm is having a hard time understanding "-I./../include" # convert it to "-I../include" args=" "`echo $* | sed -e 's/-I.\/../-I../g'` diff --git a/netware/BUILD/mwldnlm b/netware/BUILD/mwldnlm index 7ad2872ccbb..28566fc5cb1 100755 --- a/netware/BUILD/mwldnlm +++ b/netware/BUILD/mwldnlm @@ -1,5 +1,8 @@ #! /bin/sh +# stop on errors +set -e + args=" $*" wine --debugmsg -all -- mwldnlm $args diff --git a/netware/BUILD/nwbootstrap b/netware/BUILD/nwbootstrap index 002e19c8e49..5d068e4e4de 100755 --- a/netware/BUILD/nwbootstrap +++ b/netware/BUILD/nwbootstrap @@ -3,11 +3,11 @@ # debug #set -x -path=`dirname $0` - # stop on errors set -e +path=`dirname $0` + # repository direcotry repo_dir=`pwd` @@ -24,6 +24,7 @@ temp_dir="" revision="" rev="" build="" +suffix="" mwenv="" # show usage @@ -81,6 +82,7 @@ for arg do --wine-build-dir=*) wine_build_dir=`echo "$arg" | sed -e "s;--wine-build-dir=;;"` ;; --revision=*) revision=`echo "$arg" | sed -e "s;--revision=;;"` ;; --build=*) build=`echo "$arg" | sed -e "s;--build=;;"` ;; + --suffix=*) suffix=`echo "$arg" | sed -e "s;--suffix=;;"` ;; --doc-dir=*) doc_dir=`echo "$arg" | sed -e "s;--doc-dir=;;"` ;; *) show_usage ;; esac @@ -111,6 +113,12 @@ echo "version: $version" # build target directory target_dir="$build_dir/mysql-$version" +# add suffix +if test $suffix +then + target_dir="$target_dir-$suffix" +fi + # delete any old target if test -d $target_dir.old; then rm -rf $target_dir.old; fi diff --git a/repl-tests/README b/repl-tests/README deleted file mode 100644 index 95611c6538d..00000000000 --- a/repl-tests/README +++ /dev/null @@ -1,12 +0,0 @@ -This directory contains a set of test cases for replication. To get it -to work on your system, install this version of MySQL on the master and on -the slave, configure them according to the Replication HOWTO in the manual, -modify include/master-slave.inc to specify correct connection parameters -for the master and the slave and do - -sh run-all-tests - -If you would like to add your own test case, create a directory -test-your-test-case-name, write your own run.test following the examples -in the other test cases. Note that you can create the files containing -the expected output ( master files) by running mysqltest --record < run.test
\ No newline at end of file diff --git a/repl-tests/include/master-slave.inc b/repl-tests/include/master-slave.inc deleted file mode 100644 index ad2dea1f520..00000000000 --- a/repl-tests/include/master-slave.inc +++ /dev/null @@ -1,2 +0,0 @@ -connect (slave,localhost,root,,test,0,/var/lib/mysql/mysql.sock); -connect (master,sarochka,admin,,test,0,0); diff --git a/repl-tests/run-all-tests b/repl-tests/run-all-tests deleted file mode 100755 index d9f08d8a8fb..00000000000 --- a/repl-tests/run-all-tests +++ /dev/null @@ -1,9 +0,0 @@ -#! /bin/sh - -for d in test-*; do -cd $d -echo -n $d | sed -e s/test-// -echo -n "...." -../../client/mysqltest $@ < run.test -cd .. -done
\ No newline at end of file diff --git a/repl-tests/test-auto-inc/run.test b/repl-tests/test-auto-inc/run.test deleted file mode 100755 index 8405329f458..00000000000 --- a/repl-tests/test-auto-inc/run.test +++ /dev/null @@ -1,10 +0,0 @@ -source ../include/master-slave.inc; -connection master; -drop table if exists x; -create table x(n int auto_increment primary key); -set insert_id = 2000; -insert into x values (NULL),(NULL),(NULL); -connection slave; -sleep 3; -@x.master select * from x; - diff --git a/repl-tests/test-auto-inc/x.master b/repl-tests/test-auto-inc/x.master deleted file mode 100644 index c76fc46ae97..00000000000 --- a/repl-tests/test-auto-inc/x.master +++ /dev/null @@ -1,4 +0,0 @@ -n -2000 -2001 -2002 diff --git a/repl-tests/test-bad-query/run.test b/repl-tests/test-bad-query/run.test deleted file mode 100755 index a86aaf84096..00000000000 --- a/repl-tests/test-bad-query/run.test +++ /dev/null @@ -1,10 +0,0 @@ -source ../include/master-slave.inc; -connection master; -drop table if exists x; -create table x(n int primary key); -!insert into x values (1),(2),(2); -insert into x values (3); -connection slave; -sleep 3; -@x.master select * from x; - diff --git a/repl-tests/test-bad-query/x.master b/repl-tests/test-bad-query/x.master deleted file mode 100644 index c62967af0bb..00000000000 --- a/repl-tests/test-bad-query/x.master +++ /dev/null @@ -1,4 +0,0 @@ -n -1 -2 -3 diff --git a/repl-tests/test-dump/run.test b/repl-tests/test-dump/run.test deleted file mode 100644 index c714186a67b..00000000000 --- a/repl-tests/test-dump/run.test +++ /dev/null @@ -1,25 +0,0 @@ -source ../include/master-slave.inc; -connection slave; -!slave stop; -flush slave; -connection master; -flush master; -connection slave; -slave start; -connection master; -use test; -drop table if exists words; -create table words (word char(20) not null, index(word)); -load data infile '/usr/dict/words' into table words; -drop table if exists words1; -create table words1 (word char(20) not null); -load data infile '/usr/dict/words' into table words1; -sleep 20; -connection slave; -use test; -drop table if exists words; -load table words from master; -drop table if exists words1; -load table words1 from master; -@table-dump-check.master check table words; -@table-dump-select.master select count(*) from words1; diff --git a/repl-tests/test-dump/table-dump-check.master b/repl-tests/test-dump/table-dump-check.master deleted file mode 100644 index 4061fdb4a0d..00000000000 --- a/repl-tests/test-dump/table-dump-check.master +++ /dev/null @@ -1,2 +0,0 @@ -Table Op Msg_type Msg_text -test.words check status OK diff --git a/repl-tests/test-dump/table-dump-select.master b/repl-tests/test-dump/table-dump-select.master deleted file mode 100644 index ae93d31c066..00000000000 --- a/repl-tests/test-dump/table-dump-select.master +++ /dev/null @@ -1,2 +0,0 @@ -count(*) -45402 diff --git a/repl-tests/test-repl-alter/run.test b/repl-tests/test-repl-alter/run.test deleted file mode 100644 index 2e031010d5c..00000000000 --- a/repl-tests/test-repl-alter/run.test +++ /dev/null @@ -1,12 +0,0 @@ -source ../include/master-slave.inc; -connection master; -drop table if exists test; -CREATE TABLE test (name varchar(64), age smallint(3)); -INSERT INTO test SET name='Andy', age=31; -INSERT test SET name='Jacob', age=2; -INSERT into test SET name='Caleb', age=1; -ALTER TABLE test ADD id int(8) ZEROFILL AUTO_INCREMENT PRIMARY KEY; -@test.master select * from test; -connection slave; -sleep 3; -@test.master select * from test; diff --git a/repl-tests/test-repl-alter/test.master b/repl-tests/test-repl-alter/test.master deleted file mode 100644 index 763154b938e..00000000000 --- a/repl-tests/test-repl-alter/test.master +++ /dev/null @@ -1,4 +0,0 @@ -name age id -Andy 31 00000001 -Jacob 2 00000002 -Caleb 1 00000003 diff --git a/repl-tests/test-repl-ts/repl-timestamp.master b/repl-tests/test-repl-ts/repl-timestamp.master deleted file mode 100644 index c3e4a2326d0..00000000000 --- a/repl-tests/test-repl-ts/repl-timestamp.master +++ /dev/null @@ -1,2 +0,0 @@ -unix_timestamp(t) -200006 diff --git a/repl-tests/test-repl-ts/repl-timestamp.master.reject b/repl-tests/test-repl-ts/repl-timestamp.master.reject deleted file mode 100644 index 091b18351ed..00000000000 --- a/repl-tests/test-repl-ts/repl-timestamp.master.reject +++ /dev/null @@ -1,2 +0,0 @@ -unix_timestamp(t) -973999074 diff --git a/repl-tests/test-repl-ts/run.test b/repl-tests/test-repl-ts/run.test deleted file mode 100644 index 0a5224ce02a..00000000000 --- a/repl-tests/test-repl-ts/run.test +++ /dev/null @@ -1,17 +0,0 @@ -#! ../client/mysqltest -# tests if the replicaion preserves timestamp properly - -source ../include/master-slave.inc; -connection master; -set timestamp=200006; -drop table if exists foo; -create table foo(t timestamp not null,a char(1)); -insert into foo ( a) values ('F'); -@repl-timestamp.master select unix_timestamp(t) from foo; -sleep 3; -connection slave; -drop table if exists foo; -load table foo from master; -@repl-timestamp.master select unix_timestamp(t) from foo; - - diff --git a/repl-tests/test-repl/foo-dump-master.master b/repl-tests/test-repl/foo-dump-master.master deleted file mode 100644 index 982e0523cfb..00000000000 --- a/repl-tests/test-repl/foo-dump-master.master +++ /dev/null @@ -1,3 +0,0 @@ -n -1 -2 diff --git a/repl-tests/test-repl/foo-dump-slave.master b/repl-tests/test-repl/foo-dump-slave.master deleted file mode 100644 index 982e0523cfb..00000000000 --- a/repl-tests/test-repl/foo-dump-slave.master +++ /dev/null @@ -1,3 +0,0 @@ -n -1 -2 diff --git a/repl-tests/test-repl/run.test b/repl-tests/test-repl/run.test deleted file mode 100755 index cc93d964efa..00000000000 --- a/repl-tests/test-repl/run.test +++ /dev/null @@ -1,24 +0,0 @@ -source ../include/master-slave.inc; -connection slave; -!slave stop; -connection master; -flush master; -connection slave; -flush slave; -!slave start; -sleep 3; -connection master; -use test; -drop table if exists words; -create table words (word char(20) not null, index(word)); -load data infile '/usr/dict/words' into table words; -drop table if exists foo; -create table foo(n int); -insert into foo values(1),(2); -@foo-dump-master.master select * from foo; -@sum-wlen-master.master select sum(length(word)) from words; -connection slave; -sleep 15; -use test; -@sum-wlen-slave.master select sum(length(word)) from words; -@foo-dump-slave.master select * from foo; diff --git a/repl-tests/test-repl/sum-wlen-master.master b/repl-tests/test-repl/sum-wlen-master.master deleted file mode 100644 index e749ab4840a..00000000000 --- a/repl-tests/test-repl/sum-wlen-master.master +++ /dev/null @@ -1,2 +0,0 @@ -sum(length(word)) -363634 diff --git a/repl-tests/test-repl/sum-wlen-slave.master b/repl-tests/test-repl/sum-wlen-slave.master deleted file mode 100644 index e749ab4840a..00000000000 --- a/repl-tests/test-repl/sum-wlen-slave.master +++ /dev/null @@ -1,2 +0,0 @@ -sum(length(word)) -363634 diff --git a/scripts/mysql_setpermission.sh b/scripts/mysql_setpermission.sh index 43bf8a14c06..9699cd28047 100644 --- a/scripts/mysql_setpermission.sh +++ b/scripts/mysql_setpermission.sh @@ -16,20 +16,25 @@ ## 1.2 begin screen now in a loop + quit is using 0 instead of 9 ## after ideas of Paul DuBois. ## 1.2a Add Grant, References, Index and Alter privilege handling (Monty) +## 1.3 Applied patch provided by Martin Mokrejs <mmokrejs@natur.cuni.cz> +## (General code cleanup, use the GRANT statement instead of updating +## the privilege tables directly, added option to revoke privileges) #### TODO # # empty ... suggestions ... mail them to me ... -$version="1.2"; +$version="1.3"; use DBI; use Getopt::Long; use strict; -use vars qw($dbh $hostname $opt_user $opt_password $opt_help $opt_host +use vars qw($dbh $sth $hostname $opt_user $opt_password $opt_help $opt_host $opt_socket $opt_port $host $version); +my $sqlhost = ""; +my $user = ""; $dbh=$host=$opt_user= $opt_password= $opt_help= $opt_host= $opt_socket= ""; $opt_port=0; @@ -42,11 +47,11 @@ usage() if ($opt_help); # the help function if ($opt_host eq '') { - $hostname = "localhost"; + $sqlhost = "localhost"; } else { - $hostname = $opt_host; + $sqlhost = $opt_host; } # ask for a password if no password is set already @@ -62,7 +67,7 @@ if ($opt_password eq '') # make the connection to MySQL -$dbh= DBI->connect("DBI:mysql:mysql:host=$hostname:port=$opt_port:mysql_socket=$opt_socket",$opt_user,$opt_password, {PrintError => 0}) || +$dbh= DBI->connect("DBI:mysql:mysql:host=$sqlhost:port=$opt_port:mysql_socket=$opt_socket",$opt_user,$opt_password, {PrintError => 0}) || die("Can't make a connection to the mysql server.\n The error: $DBI::errstr"); # the start of the program @@ -86,27 +91,44 @@ sub q1 { # first question ... print "#"x70; print "\n"; print "What would you like to do:\n"; - print " 1. Set password for a user.\n"; - print " 2. Add a database + user privilege for that database.\n"; - print " - user can do all except all admin functions\n"; - print " 3. Add user privilege for an existing database.\n"; - print " - user can do all except all admin functions\n"; - print " 4. Add user privilege for an existing database.\n"; - print " - user can do all except all admin functions + no create/drop\n"; - print " 5. Add user privilege for an existing database.\n"; - print " - user can do only selects (no update/delete/insert etc.)\n"; + print " 1. Set password for an existing user.\n"; + print " 2. Create a database + user privilege for that database\n"; + print " and host combination (user can only do SELECT)\n"; + print " 3. Create/append user privilege for an existing database\n"; + print " and host combination (user can only do SELECT)\n"; + print " 4. Create/append broader user privileges for an existing\n"; + print " database and host combination\n"; + print " (user can do SELECT,INSERT,UPDATE,DELETE)\n"; + print " 5. Create/append quite extended user privileges for an\n"; + print " existing database and host combination (user can do\n"; + print " SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,\n"; + print " LOCK TABLES,CREATE TEMPORARY TABLES)\n"; + print " 6. Create/append database administrative privileges for an\n"; + print " existing database and host combination (user can do\n"; + print " SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,LOCK TABLES,\n"; + print " CREATE TEMPORARY TABLES,SHOW DATABASES,PROCESS)\n"; + print " 7. Create/append full privileges for an existing database\n"; + print " and host combination (user has FULL privilege)\n"; + print " 8. Remove all privileges for for an existing database and\n"; + print " host combination.\n"; + print " (user will have all permission fields set to N)\n"; print " 0. exit this program\n"; - print "\nMake your choice [1,2,3,4,5,0]: "; + print "\nMake your choice [1,2,3,4,5,6,7,0]: "; while (<STDIN>) { $answer = $_; chomp($answer); - if ($answer =~ /1|2|3|4|5|0/) { - &setpwd if ($answer == 1); - &addall($answer) if ($answer =~ /^[2345]$/); - if ($answer == 0) { - print "Sorry, hope we can help you next time \n\n"; + if ($answer =~ /^[12345678]$/) { + if ($answer == 1) { + setpwd(); + } elsif ($answer =~ /^[2345678]$/) { + addall($answer); + } else { + print "Sorry, something went wrong. With such option number you should not get here.\n\n"; $end = 1; } + } elsif ($answer == 0) { + print "We hope we can help you next time \n\n"; + $end = 1; } else { print "Your answer was $answer\n"; print "and that's wrong .... Try again\n"; @@ -121,7 +143,7 @@ sub q1 { # first question ... ### sub setpwd { - my ($user,$pass,$host); + my ($user,$pass,$host) = ""; print "\n\nSetting a (new) password for a user.\n"; $user = user(); @@ -168,22 +190,18 @@ sub setpwd ### # all things which will be added are done here ### -sub addall -{ +sub addall { my ($todo) = @_; my ($answer,$good,$db,$user,$pass,$host,$priv); - if ($todo == 2) - { + if ($todo == 2) { $db = newdatabase(); - } - else - { + } else { $db = database(); } $user = newuser(); - $pass = newpass(); + $pass = newpass("$user"); $host = newhosts(); print "#"x70; @@ -198,104 +216,80 @@ sub addall print "Are you pretty sure you would like to implement this [yes/no]: "; my $no = <STDIN>; chomp($no); - if ($no =~ /n/i) - { + if ($no =~ /n/i) { print "Okay .. that was it then ... See ya\n\n"; return(0); - } - else - { + } else { print "Okay ... let's go then ...\n\n"; } - if ($todo == 2) - { + if ($todo == 2) { # create the database - my $sth = $dbh->do("create database $db") || $dbh->errstr; - } - - # select the privilege .... - if (($todo == 2) || ($todo == 3)) - { - $priv = "'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y'"; + if ($db) { + my $sth = $dbh->do("CREATE DATABASE $db") || $dbh->errstr; + } else { + print STDERR "What do you want? You wanted to create new database and add new user, right?\n"; + die "But then specify databasename, please\n"; } - elsif ($todo == 4) - { - $priv = "'Y','Y','Y','Y','N','N','N','Y','Y','Y'"; } - elsif ($todo == 5) - { - $priv = "'Y','N','N','N','N','N','N','N','N','N'"; - } - else - { - print "Sorry, choice number $todo isn't known inside the program .. See ya\n"; + + if ( ( !$todo ) or not ( $todo =~ m/^[2-8]$/ ) ) { + print STDERR "Sorry, select option $todo isn't known inside the program .. See ya\n"; quit(); } my @hosts = split(/,/,$host); - $user = $dbh->quote($user); - $db = $dbh->quote($db); - if ($pass eq '') - { - $pass = "''"; + if (!$user) { + die "username not specified: $user\n"; } - else - { - $pass = "PASSWORD(". $dbh->quote($pass) . ")"; + if (!$db) { + die "databasename is not specified nor *\n"; } - foreach my $key (@hosts) - { - my $key1 = $dbh->quote($key); - my $sth = $dbh->prepare("select Host,User from user where Host = $key1 and User = $user") || die $dbh->errstr; - $sth->execute || die $dbh->errstr; - my @r = $sth->fetchrow_array; - if ($r[0]) - { - print "WARNING WARNING SKIPPING CREATE FOR USER $user AND HOST $key\n"; - print "Reason: entry already exists in the user table.\n"; + foreach $host (@hosts) { + # user privileges: SELECT + if (($todo == 2) || ($todo == 3)) { + $sth = $dbh->do("GRANT SELECT ON $db.* TO $user@\"$host\" IDENTIFIED BY \'$pass\'") || die $dbh->errstr; + } elsif ($todo == 4) { + # user privileges: SELECT,INSERT,UPDATE,DELETE + $sth = $dbh->do("GRANT SELECT,INSERT,UPDATE,DELETE ON $db.* TO $user@\"$host\" IDENTIFIED BY \'$pass\'") || die $dbh->errstr; + } elsif ($todo == 5) { + # user privileges: SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,LOCK TABLES,CREATE TEMPORARY TABLES + $sth = $dbh->do("GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,LOCK TABLES,CREATE TEMPORARY TABLES ON $db.* TO $user@\"$host\" IDENTIFIED BY \'$pass\'") || die $dbh->errstr; + } elsif ($todo == 6) { + # admin privileges: GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,LOCK TABLES,CREATE TEMPORARY TABLES,SHOW DATABASES,PROCESS + $sth = $dbh->do("GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,LOCK TABLES,CREATE TEMPORARY TABLES,SHOW DATABASES,PROCESS ON $db.* TO $user@\"$host\" IDENTIFIED BY \'$pass\'") || die $dbh->errstr; + } elsif ($todo == 7) { + # all privileges + $sth = $dbh->do("GRANT ALL ON $db.* TO \'$user\'\@\'$host\' IDENTIFIED BY \'$pass\'") || die $dbh->errstr; + } elsif ($todo == 8) { + # all privileges set to N + $sth = $dbh->do("REVOKE ALL ON *.* FROM \'$user\'\@\'$host\'") || die $dbh->errstr; } - else - { - $sth = $dbh->prepare("insert into user (Host,User,Password) values($key1,$user,$pass)") || die $dbh->errstr; - $sth->execute || die $dbh->errstr; - $sth->finish; } - $sth = $dbh->prepare("INSERT INTO db (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Grant_priv,References_priv,Index_priv,Alter_priv) VALUES ($key1,$db,$user,$priv)") || die $dbh->errstr; - $sth->execute || die $dbh->errstr; - $sth->finish; - } - $dbh->do("flush privileges") || print "Can't load privileges\n"; + $dbh->do("FLUSH PRIVILEGES") || print STDERR "Can't flush privileges\n"; print "Everything is inserted and mysql privileges have been reloaded.\n\n"; } ### # ask for a new database name ### -sub newdatabase -{ +sub newdatabase { my ($answer,$good,$db); print "\n\nWhich database would you like to add: "; - while (<STDIN>) - { + while (<STDIN>) { $answer = $_; $good = 0; chomp($answer); - if ($answer) - { - my $sth = $dbh->prepare("show databases") || die $dbh->errstr; + if ($answer) { + my $sth = $dbh->prepare("SHOW DATABASES") || die $dbh->errstr; $sth->execute || die $dbh->errstr; - while (my @r = $sth->fetchrow_array) - { - if ($r[0] eq $answer) - { + while (my @r = $sth->fetchrow_array) { + if ($r[0] eq $answer) { print "\n\nSorry, this database name is already in use; try something else: "; $good = 1; } } - } - else - { + } else { print "You must type something ...\nTry again: "; next; } @@ -309,48 +303,44 @@ sub newdatabase ### # select a database ### -sub database -{ +sub database { my ($answer,$good,$db); - print "\n\nWhich database would you like to select: \n"; + print "\n\nWhich database from existing databases would you like to select: \n"; print "You can choose from: \n"; my $sth = $dbh->prepare("show databases") || die $dbh->errstr; $sth->execute || die $dbh->errstr; - while (my @r = $sth->fetchrow_array) - { + while (my @r = $sth->fetchrow_array) { print " - $r[0] \n"; } - print "Which database will it be (case sensitive): "; - while (<STDIN>) - { + print "Which database will it be (case sensitive). Type * for any: \n"; + while (<STDIN>) { $answer = $_; $good = 0; chomp($answer); - if ($answer) - { + if ($answer) { + if ($answer eq "*") { + print "OK, the user entry will NOT be limited to any database"; + return("*"); + } my $sth = $dbh->prepare("show databases") || die $dbh->errstr; $sth->execute || die $dbh->errstr; - while (my @r = $sth->fetchrow_array) - { - if ($r[0] eq $answer) - { + while (my @r = $sth->fetchrow_array) { + if ($r[0] eq $answer) { $good = 1; $db = $r[0]; last; } } - } - else - { - print "You must type something ...\nTry again: "; + } else { + print "Type either database name or * meaning any databasename. That means"; + print " any of those above but also any which will be created in future!"; + print " This option gives a user chance to operate on databse mysql, which"; + print " contains privilege settings. That is really risky!\n"; next; } - if ($good == 1) - { + if ($good == 1) { last; - } - else - { + } else { print "You must select one from the list.\nTry again: "; next; } @@ -364,7 +354,8 @@ sub database ### sub newuser { - my ($answer,$user); + my $user = ""; + my $answer = ""; print "\nWhat username is to be created: "; while(<STDIN>) @@ -430,7 +421,7 @@ sub user sub newpass { my ($user) = @_; - my ($answer,$good,$pass,$yes); + my ($pass,$answer,$good,$yes); print "Would you like to set a password for $user [y/n]: "; $yes = <STDIN>; @@ -487,7 +478,7 @@ sub newpass ### sub newhosts { - my ($answer,$good,$host); + my ($host,$answer,$good); print "We now need to know from what host(s) the user will connect.\n"; print "Keep in mind that % means 'from any host' ...\n"; diff --git a/sql/field.cc b/sql/field.cc index ce5e240aba8..eb7d3dc5686 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -3322,11 +3322,11 @@ bool Field_newdate::get_date(TIME *ltime,bool fuzzydate) if (is_null()) return 1; uint32 tmp=(uint32) uint3korr(ptr); - bzero((char*) ltime,sizeof(*ltime)); ltime->day= tmp & 31; ltime->month= (tmp >> 5) & 15; ltime->year= (tmp >> 9); ltime->time_type=TIMESTAMP_DATE; + ltime->hour= ltime->minute= ltime->second= ltime->second_part= 0; return (!fuzzydate && (!ltime->month || !ltime->day)) ? 1 : 0; } diff --git a/sql/filesort.cc b/sql/filesort.cc index 86574e4dd57..1d30c23a15e 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -456,6 +456,7 @@ static void make_sortkey(register SORTPARAM *param, sort_field != param->end ; sort_field++) { + bool maybe_null=0; if ((field=sort_field->field)) { // Field if (field->maybe_null()) @@ -480,7 +481,7 @@ static void make_sortkey(register SORTPARAM *param, switch (sort_field->result_type) { case STRING_RESULT: { - if (item->maybe_null) + if ((maybe_null=item->maybe_null)) *to++=1; /* All item->str() to use some extra byte for end null.. */ String tmp((char*) to,sort_field->length+4); @@ -546,7 +547,7 @@ static void make_sortkey(register SORTPARAM *param, case INT_RESULT: { longlong value=item->val_int(); - if (item->maybe_null) + if ((maybe_null=item->maybe_null)) *to++=1; /* purecov: inspected */ if (item->null_value) { @@ -580,13 +581,13 @@ static void make_sortkey(register SORTPARAM *param, case REAL_RESULT: { double value=item->val(); - if (item->null_value) + if ((maybe_null=item->null_value)) { bzero((char*) to,sort_field->length+1); to++; break; } - if (item->maybe_null) + if ((maybe_null=item->maybe_null)) *to++=1; change_double_for_sort(value,(byte*) to); break; @@ -595,6 +596,8 @@ static void make_sortkey(register SORTPARAM *param, } if (sort_field->reverse) { /* Revers key */ + if (maybe_null) + to[-1]= ~to[-1]; length=sort_field->length; while (length--) { diff --git a/sql/ha_heap.h b/sql/ha_heap.h index 504f5262bf3..31126111d9d 100644 --- a/sql/ha_heap.h +++ b/sql/ha_heap.h @@ -54,8 +54,9 @@ class ha_heap: public handler uint max_keys() const { return MAX_KEY; } uint max_key_parts() const { return MAX_REF_PARTS; } uint max_key_length() const { return HA_MAX_REC_LENGTH; } - virtual double scan_time() { return (double) (records+deleted) / 20.0+10; } - virtual double read_time(ha_rows rows) { return (double) rows / 20.0+1; } + double scan_time() { return (double) (records+deleted) / 20.0+10; } + double read_time(uint index, uint ranges, ha_rows rows) + { return (double) rows / 20.0+1; } virtual bool fast_key_read() { return 1;} int open(const char *name, int mode, uint test_if_locked); diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 30d44f183a4..1363227605e 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -873,6 +873,7 @@ innobase_flush_logs(void) DBUG_ENTER("innobase_flush_logs"); log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP); + log_flush_to_disk(); DBUG_RETURN(result); } @@ -1182,6 +1183,9 @@ ha_innobase::open( last_query_id = (ulong)-1; + active_index = 0; + active_index_before_scan = (uint)-1; /* undefined value */ + if (!(share=get_share(name))) DBUG_RETURN(1); @@ -2026,7 +2030,8 @@ calc_row_difference( upd_t* uvect, /* in/out: update vector */ mysql_byte* old_row, /* in: old row in MySQL format */ mysql_byte* new_row, /* in: new row in MySQL format */ - struct st_table* table, /* in: table in MySQL data dictionary */ + struct st_table* table, /* in: table in MySQL data + dictionary */ mysql_byte* upd_buff, /* in: buffer to use */ row_prebuilt_t* prebuilt, /* in: InnoDB prebuilt struct */ THD* thd) /* in: user thread */ @@ -2076,8 +2081,10 @@ calc_row_difference( case DATA_VARCHAR: case DATA_BINARY: case DATA_VARMYSQL: - o_ptr = row_mysql_read_var_ref_noninline(&o_len, o_ptr); - n_ptr = row_mysql_read_var_ref_noninline(&n_len, n_ptr); + o_ptr = row_mysql_read_var_ref_noninline(&o_len, + o_ptr); + n_ptr = row_mysql_read_var_ref_noninline(&n_len, + n_ptr); default: ; } @@ -2489,46 +2496,48 @@ ha_innobase::change_active_index( index, even if it was internally generated by InnoDB */ { - row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; - KEY* key=0; - statistic_increment(ha_read_key_count, &LOCK_status); - DBUG_ENTER("change_active_index"); + row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; + KEY* key=0; + statistic_increment(ha_read_key_count, &LOCK_status); + DBUG_ENTER("change_active_index"); - ut_a(prebuilt->trx == + ut_a(prebuilt->trx == (trx_t*) current_thd->transaction.all.innobase_tid); - active_index = keynr; + active_index = keynr; - if (keynr != MAX_KEY && table->keys > 0) { - key = table->key_info + active_index; + if (keynr != MAX_KEY && table->keys > 0) { + key = table->key_info + active_index; - prebuilt->index = dict_table_get_index_noninline( + prebuilt->index = dict_table_get_index_noninline( prebuilt->table, key->name); - } else { - prebuilt->index = dict_table_get_first_index_noninline( + } else { + prebuilt->index = dict_table_get_first_index_noninline( prebuilt->table); - } + } - if (!prebuilt->index) { - sql_print_error("Innodb could not find key n:o %u with name %s from dict cache for table %s", keynr, key ? key->name : "NULL", prebuilt->table->name); - DBUG_RETURN(1); - } + if (!prebuilt->index) { + sql_print_error( +"Innodb could not find key n:o %u with name %s from dict cache for table %s", + keynr, key ? key->name : "NULL", prebuilt->table->name); + DBUG_RETURN(1); + } - assert(prebuilt->search_tuple != 0); + assert(prebuilt->search_tuple != 0); - dtuple_set_n_fields(prebuilt->search_tuple, prebuilt->index->n_fields); + dtuple_set_n_fields(prebuilt->search_tuple, prebuilt->index->n_fields); - dict_index_copy_types(prebuilt->search_tuple, prebuilt->index, + dict_index_copy_types(prebuilt->search_tuple, prebuilt->index, prebuilt->index->n_fields); - /* Maybe MySQL changes the active index for a handle also - during some queries, we do not know: then it is safest to build - the template such that all columns will be fetched. */ + /* Maybe MySQL changes the active index for a handle also + during some queries, we do not know: then it is safest to build + the template such that all columns will be fetched. */ - build_template(prebuilt, NULL, table, ROW_MYSQL_WHOLE_ROW); + build_template(prebuilt, NULL, table, ROW_MYSQL_WHOLE_ROW); - DBUG_RETURN(0); + DBUG_RETURN(0); } /************************************************************************** @@ -2721,6 +2730,11 @@ ha_innobase::rnd_init( row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; + /* Store the active index value so that we can restore the original + value after a scan */ + + active_index_before_scan = active_index; + if (prebuilt->clust_index_was_generated) { err = change_active_index(MAX_KEY); } else { @@ -2733,13 +2747,25 @@ ha_innobase::rnd_init( } /********************************************************************* -Ends a table scan ???????????????? */ +Ends a table scan. */ int ha_innobase::rnd_end(void) /*======================*/ /* out: 0 or error number */ { + /* Restore the old active_index back; MySQL may assume that a table + scan does not change active_index. We only restore the value if + MySQL has called rnd_init before: sometimes MySQL seems to call + rnd_end WITHOUT calling rnd_init. */ + + if (active_index_before_scan != (uint)-1) { + + change_active_index(active_index_before_scan); + + active_index_before_scan = (uint)-1; + } + return(index_end()); } @@ -3517,10 +3543,8 @@ ha_innobase::records_in_range( /************************************************************************* Gives an UPPER BOUND to the number of rows in a table. This is used in -filesort.cc and the upper bound must hold. TODO: Since the number of -rows in a table may change after this function is called, we still may -get a 'Sort aborted' error in filesort.cc of MySQL. The ultimate fix is to -improve the algorithm of filesort.cc. */ +filesort.cc and its better if the upper bound hold. +*/ ha_rows ha_innobase::estimate_number_of_rows(void) @@ -3586,6 +3610,29 @@ ha_innobase::scan_time() return((double) (prebuilt->table->stat_clustered_index_size)); } +/* + Calculate the time it takes to read a set of ranges through and index + This enables us to optimise reads for clustered indexes. +*/ + +double ha_innobase::read_time(uint index, uint ranges, ha_rows rows) +{ + ha_rows total_rows; + double time_for_scan; + if (index != table->primary_key) + return handler::read_time(index, ranges, rows); // Not clustered + if (rows <= 2) + return (double) rows; + /* + Assume that the read is proportional to scan time for all rows + one + seek per range. + */ + time_for_scan= scan_time(); + if ((total_rows= estimate_number_of_rows()) < rows) + return time_for_scan; + return (ranges + (double) rows / (double) total_rows * time_for_scan); +} + /************************************************************************* Returns statistics information of the table to the MySQL interpreter, in various fields of the handle object. */ @@ -3710,6 +3757,23 @@ ha_innobase::info( DBUG_VOID_RETURN; } +/************************************************************************** +Updates index cardinalities of the table, based on 10 random dives into +each index tree. This does NOT calculate exact statistics of the table. */ + +int +ha_innobase::analyze( +/*=================*/ + /* out: returns always 0 (success) */ + THD* thd, /* in: connection thread handle */ + HA_CHECK_OPT* check_opt) /* in: currently ignored */ +{ + /* Simply call ::info() with all the flags */ + info(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE); + + return(0); +} + /*********************************************************************** Tries to check that an InnoDB table is not corrupted. If corruption is noticed, prints to stderr information about it. In case of corruption diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h index 8031fa0aa29..5677d22a2ca 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -58,7 +58,15 @@ class ha_innobase: public handler ulong start_of_scan; /* this is set to 1 when we are starting a table scan but have not yet fetched any row, else 0 */ - + uint active_index_before_scan; + /* since a table scan in InnoDB is + always done through an index, a table + scan may change active_index; but + MySQL may assume that active_index + after a table scan is the same as + before; we store the value here so + that we can restore the value after + a scan */ uint last_match_mode;/* match mode of the latest search: ROW_SEL_EXACT, ROW_SEL_EXACT_PREFIX, or undefined */ @@ -118,6 +126,7 @@ class ha_innobase: public handler void initialize(void); int close(void); double scan_time(); + double read_time(uint index, uint ranges, ha_rows rows); int write_row(byte * buf); int update_row(const byte * old_data, byte * new_data); @@ -143,6 +152,7 @@ class ha_innobase: public handler void position(const byte *record); void info(uint); + int analyze(THD* thd,HA_CHECK_OPT* check_opt); int extra(enum ha_extra_function operation); int reset(void); int external_lock(THD *thd, int lock_type); diff --git a/sql/handler.h b/sql/handler.h index 8f1d00f64b5..72a05d7ebee 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -227,7 +227,8 @@ public: void change_table_ptr(TABLE *table_arg) { table=table_arg; } virtual double scan_time() { return ulonglong2double(data_file_length) / IO_SIZE + 1; } - virtual double read_time(ha_rows rows) { return rows2double(rows); } + virtual double read_time(uint index, uint ranges, ha_rows rows) + { return rows2double(ranges+rows); } virtual bool fast_key_read() { return 0;} virtual key_map keys_to_use_for_scanning() { return 0; } virtual bool has_transactions(){ return 0;} diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 3a513505913..d88894d4fb4 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1066,7 +1066,7 @@ bool Item_sum_count_distinct::setup(THD *thd) int Item_sum_count_distinct::tree_to_myisam() { - if (create_myisam_from_heap(table, tmp_table_param, + if (create_myisam_from_heap(current_thd, table, tmp_table_param, HA_ERR_RECORD_FILE_FULL, 1) || tree_walk(&tree, (tree_walk_action)&dump_leaf, (void*)this, left_root_right)) @@ -1120,7 +1120,8 @@ bool Item_sum_count_distinct::add() if (error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE) { - if (create_myisam_from_heap(table, tmp_table_param, error,1)) + if (create_myisam_from_heap(current_thd, table, tmp_table_param, error, + 1)) return 1; // Not a table_is_full error } } diff --git a/sql/log_event.cc b/sql/log_event.cc index 3b499b8d502..05d5788f5ae 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -659,9 +659,18 @@ Log_event* Log_event::read_log_event(const char* buf, int event_len, } if (!ev || !ev->is_valid()) { - *error= "Found invalid event in binary log"; delete ev; +#ifdef MYSQL_CLIENT + if (!force_opt) + { + *error= "Found invalid event in binary log"; + return 0; + } + ev= new Unknown_log_event(buf, old_format); +#else + *error= "Found invalid event in binary log"; return 0; +#endif } ev->cached_event_len = event_len; return ev; @@ -1695,6 +1704,17 @@ void Execute_load_log_event::pack_info(String* packet) } #endif +#ifdef MYSQL_CLIENT +void Unknown_log_event::print(FILE* file, bool short_form, char* last_db) +{ + if (short_form) + return; + print_header(file); + fputc('\n', file); + fprintf(file, "# %s", "Unknown event\n"); +} +#endif + #ifndef MYSQL_CLIENT int Query_log_event::exec_event(struct st_relay_log_info* rli) { @@ -1921,13 +1941,13 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, close_thread_tables(thd); if (thd->query_error) { - int sql_error = thd->net.last_errno; + int sql_error= thd->net.last_errno; if (!sql_error) - sql_error = ER_UNKNOWN_ERROR; - + sql_error= ER_UNKNOWN_ERROR; slave_print_error(rli,sql_error, - "Slave: Error '%s' running load data infile ", - ER_SAFE(sql_error)); + "Error '%s' running load data infile", + sql_error ? thd->net.last_error : + ER_SAFE(ER_UNKNOWN_ERROR)); free_root(&thd->mem_root,0); return 1; } @@ -1935,7 +1955,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, if (thd->fatal_error) { - sql_print_error("Slave: Fatal error running LOAD DATA INFILE "); + sql_print_error("Fatal error running LOAD DATA INFILE "); return 1; } diff --git a/sql/log_event.h b/sql/log_event.h index 5b9f30b3afd..b46f78d2ce0 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -201,10 +201,10 @@ struct sql_ex_info enum Log_event_type { - START_EVENT = 1, QUERY_EVENT =2, STOP_EVENT=3, ROTATE_EVENT = 4, - INTVAR_EVENT=5, LOAD_EVENT=6, SLAVE_EVENT=7, CREATE_FILE_EVENT=8, - APPEND_BLOCK_EVENT=9, EXEC_LOAD_EVENT=10, DELETE_FILE_EVENT=11, - NEW_LOAD_EVENT=12, RAND_EVENT=13 + UNKNOWN_EVENT = 0, START_EVENT = 1, QUERY_EVENT =2, STOP_EVENT=3, + ROTATE_EVENT = 4, INTVAR_EVENT=5, LOAD_EVENT=6, SLAVE_EVENT=7, + CREATE_FILE_EVENT=8, APPEND_BLOCK_EVENT=9, EXEC_LOAD_EVENT=10, + DELETE_FILE_EVENT=11, NEW_LOAD_EVENT=12, RAND_EVENT=13 }; enum Int_event_type @@ -714,4 +714,18 @@ public: int write_data(IO_CACHE* file); }; +#ifdef MYSQL_CLIENT +class Unknown_log_event: public Log_event +{ +public: + Unknown_log_event(const char* buf, bool old_format): + Log_event(buf, old_format) + {} + ~Unknown_log_event() {} + void print(FILE* file, bool short_form= 0, char* last_db= 0); + Log_event_type get_type_code() { return UNKNOWN_EVENT;} + bool is_valid() { return 1; } +}; +#endif + #endif /* _log_event_h */ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index df83d1909cb..3910bfc880b 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -42,7 +42,7 @@ #define MAIN_THD #define SIGNAL_THD -#ifdef PURIFY +#ifdef HAVE_purify #define IF_PURIFY(A,B) (A) #else #define IF_PURIFY(A,B) (B) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index aeeabb7d29c..cc45e18e54c 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -284,7 +284,7 @@ typedef struct st_qsel_param { KEY_PART *key_parts,*key_parts_end,*key[MAX_KEY]; MEM_ROOT *mem_root; table_map prev_tables,read_tables,current_table; - uint baseflag,keys,max_key_part; + uint baseflag, keys, max_key_part, range_count; uint real_keynr[MAX_KEY]; char min_key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH], max_key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH]; @@ -710,8 +710,10 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables, (double) keys_per_block); } else - found_read_time= head->file->read_time(found_records)+ - (double) found_records / TIME_FOR_COMPARE; + found_read_time= (head->file->read_time(keynr, + param.range_count, + found_records)+ + (double) found_records / TIME_FOR_COMPARE); if (read_time > found_read_time) { read_time=found_read_time; @@ -2113,11 +2115,12 @@ check_quick_select(PARAM *param,uint idx,SEL_ARG *tree) if (!tree) DBUG_RETURN(HA_POS_ERROR); // Can't use it + param->max_key_part=0; + param->range_count=0; if (tree->type == SEL_ARG::IMPOSSIBLE) DBUG_RETURN(0L); // Impossible select. return if (tree->type != SEL_ARG::KEY_RANGE || tree->part != 0) DBUG_RETURN(HA_POS_ERROR); // Don't use tree - param->max_key_part=0; records=check_quick_keys(param,idx,tree,param->min_key,0,param->max_key,0); if (records != HA_POS_ERROR) { @@ -2185,6 +2188,7 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree, } keynr=param->real_keynr[idx]; + param->range_count++; if (!tmp_min_flag && ! tmp_max_flag && (uint) key_tree->part+1 == param->table->key_info[keynr].key_parts && (param->table->key_info[keynr].flags & HA_NOSAME) && diff --git a/sql/records.cc b/sql/records.cc index 22c4d54550c..fd46506203f 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -15,7 +15,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* Functions to read, write and lock records */ +/* Functions for easy reading of records, possible through a cache */ #include "mysql_priv.h" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 19de162b3fb..b7910bd07b3 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -105,7 +105,7 @@ "BLOB column '%-.64s' can't have a default value", "Incorrect database name '%-.100s'", "Incorrect table name '%-.100s'", -"The SELECT would examine too many records and probably take a very long time. Check your WHERE and use SET SQL_BIG_SELECTS=1 if the SELECT is ok", +"The SELECT would examine more rows than MAX_JOIN_SIZE. Check your WHERE and use SET SQL_BIG_SELECTS=1 or SET SQL_MAX_JOIN_SIZE=# if the SELECT is ok", "Unknown error", "Unknown procedure '%-.64s'", "Incorrect parameter count to procedure '%-.64s'", diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 850fc5f22bc..1b04ee5c2e4 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -107,7 +107,7 @@ "BLOB column '%-.64s' can't have a default value", "»ØÄꤷ¤¿ database ̾ '%-.100s' ¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹", "»ØÄꤷ¤¿ table ̾ '%-.100s' ¤Ï¤Þ¤Á¤¬¤Ã¤Æ¤¤¤Þ¤¹", -"The SELECT would examine too many records and probably take a very long time. Check your WHERE and use SET SQL_BIG_SELECTS=1 if the SELECT is ok", +"The SELECT would examine more rows than MAX_JOIN_SIZE. Check your WHERE and use SET SQL_BIG_SELECTS=1 or SET SQL_MAX_JOIN_SIZE=# if the SELECT is ok", "Unknown error", "Unknown procedure '%-.64s'", "Incorrect parameter count to procedure '%-.64s'", diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 11ae22d3013..7ef663839c9 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -105,7 +105,7 @@ "BLOB fält '%-.64s' kan inte ha ett DEFAULT-värde", "Felaktigt databasnamn '%-.64s'", "Felaktigt tabellnamn '%-.64s'", -"Den angivna frågan skulle troligen ta mycket lång tid! Kontrollera din WHERE och använd SET SQL_BIG_SELECTS=1 ifall du vill hantera stora joins", +"Den angivna frågan skulle läsa mer än MAX_JOIN_SIZE rader. Kontrollera din WHERE och använd SET SQL_BIG_SELECTS=1 eller SET MAX_JOIN_SIZE=# ifall du vill hantera stora joins", "Oidentifierat fel", "Okänd procedur: %s", "Felaktigt antal parametrar till procedur %s", diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index ace15771449..0e7a487276d 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1392,7 +1392,7 @@ bool select_insert::send_eof() thd->cuted_fields); if (last_insert_id) thd->insert_id(last_insert_id); // For update log - ::send_ok(&thd->net,info.copied,last_insert_id,buff); + ::send_ok(&thd->net,info.copied+info.deleted,last_insert_id,buff); mysql_update_log.write(thd,thd->query,thd->query_length); return 0; } diff --git a/sql/sql_list.h b/sql/sql_list.h index d42c344957c..15bbb5c5ec7 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2003 MySQL 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 diff --git a/sql/sql_select.cc b/sql/sql_select.cc index a35f5cc2314..f870f8f5178 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1839,7 +1839,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count, { ha_rows rec; double tmp; - THD *thd= current_thd; + THD *thd= join->thd; if (!rest_tables) { @@ -1970,7 +1970,10 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count, if (table->quick_keys & ((key_map) 1 << key)) records= (double) table->quick_rows[key]; else - records= (double) s->records/rec; // quick_range couldn't use key! + { + /* quick_range couldn't use key! */ + records= (double) s->records/rec; + } } else { @@ -4316,12 +4319,11 @@ free_tmp_table(THD *thd, TABLE *entry) * If a HEAP table gets full, create a MyISAM table and copy all rows to this */ -bool create_myisam_from_heap(TABLE *table, TMP_TABLE_PARAM *param, int error, - bool ignore_last_dupp_key_error) +bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param, + int error, bool ignore_last_dupp_key_error) { TABLE new_table; const char *save_proc_info; - THD *thd=current_thd; int write_err; DBUG_ENTER("create_myisam_from_heap"); @@ -5328,7 +5330,8 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if (error == HA_ERR_FOUND_DUPP_KEY || error == HA_ERR_FOUND_DUPP_UNIQUE) goto end; - if (create_myisam_from_heap(table, &join->tmp_table_param, error,1)) + if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param, + error,1)) DBUG_RETURN(-1); // Not a table_is_full error table->uniques=0; // To ensure rows are the same } @@ -5405,7 +5408,8 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), copy_funcs(join->tmp_table_param.items_to_copy); if ((error=table->file->write_row(table->record[0]))) { - if (create_myisam_from_heap(table, &join->tmp_table_param, error, 0)) + if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param, + error, 0)) DBUG_RETURN(-1); // Not a table_is_full error /* Change method to update rows */ table->file->index_init(0); @@ -5499,8 +5503,8 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), { if ((error=table->file->write_row(table->record[0]))) { - if (create_myisam_from_heap(table, &join->tmp_table_param, - error, 0)) + if (create_myisam_from_heap(join->thd, table, + &join->tmp_table_param, error, 0)) DBUG_RETURN(-1); // Not a table_is_full error } else @@ -6029,7 +6033,7 @@ remove_duplicates(JOIN *join, TABLE *entry,List<Item> &fields, Item *having) int error; ulong reclength,offset; uint field_count; - THD *thd= current_thd; + THD *thd= join->thd; DBUG_ENTER("remove_duplicates"); entry->reginfo.lock_type=TL_WRITE; diff --git a/sql/sql_select.h b/sql/sql_select.h index 332778aafe6..5c987e74163 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -195,8 +195,8 @@ void count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields, bool setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,List<Item> &fields); void copy_fields(TMP_TABLE_PARAM *param); void copy_funcs(Item **func_ptr); -bool create_myisam_from_heap(TABLE *table, TMP_TABLE_PARAM *param, int error, - bool ignore_last_dupp_error); +bool create_myisam_from_heap(THD *Thd, TABLE *table, TMP_TABLE_PARAM *param, + int error, bool ignore_last_dupp_error); /* functions from opt_sum.cc */ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 8cec738edb0..ec4f55f246d 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -569,6 +569,14 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, column->field_name); DBUG_RETURN(-1); } + /* for fulltext keys keyseg length is 1 for blobs (it's ignored in + ft code anyway, and 0 (set to column width later) for char's. + it has to be correct col width for char's, as char data are not + prefixed with length (unlike blobs, where ft code takes data length + from a data prefix, ignoring column->length). + */ + if (key->type == Key::FULLTEXT) + column->length=test(f_is_blob(sql_field->pack_flag)); if (f_is_blob(sql_field->pack_flag)) { if (!(file->table_flags() & HA_BLOB_KEY)) @@ -579,15 +587,10 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, } if (!column->length) { - if (key->type == Key::FULLTEXT) - column->length=1; /* ft-code ignores it anyway :-) */ - else - { - my_printf_error(ER_BLOB_KEY_WITHOUT_LENGTH, - ER(ER_BLOB_KEY_WITHOUT_LENGTH),MYF(0), - column->field_name); - DBUG_RETURN(-1); - } + my_printf_error(ER_BLOB_KEY_WITHOUT_LENGTH, + ER(ER_BLOB_KEY_WITHOUT_LENGTH),MYF(0), + column->field_name); + DBUG_RETURN(-1); } } if (!(sql_field->flags & NOT_NULL_FLAG)) diff --git a/sql/sql_union.cc b/sql/sql_union.cc index faa106d4f42..e7afa7fbd23 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -262,7 +262,8 @@ bool select_union::send_data(List<Item> &values) fill_record(table->field,values); if ((write_record(table,&info))) { - if (create_myisam_from_heap(table, tmp_table_param, info.last_errno, 0)) + if (create_myisam_from_heap(thd, table, tmp_table_param, info.last_errno, + 0)) return 1; } return 0; diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 19961f5d9e1..462206b25f3 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -66,7 +66,10 @@ int mysql_update(THD *thd, TABLE *table; SQL_SELECT *select; READ_RECORD info; + TABLE_LIST tables; + List<Item> all_fields; DBUG_ENTER("mysql_update"); + LINT_INIT(used_index); LINT_INIT(timestamp_query_id); @@ -80,8 +83,13 @@ int mysql_update(THD *thd, table->quick_keys=0; want_privilege=table->grant.want_privilege; table->grant.want_privilege=(SELECT_ACL & ~table->grant.privilege); - if (setup_tables(table_list) || setup_conds(thd,table_list,&conds) - || setup_ftfuncs(thd)) + + bzero((char*) &tables,sizeof(tables)); // For ORDER BY + tables.table = table; + + if (setup_tables(table_list) || setup_conds(thd,table_list,&conds) || + setup_order(thd, &tables, all_fields, all_fields, order) || + setup_ftfuncs(thd)) DBUG_RETURN(-1); /* purecov: inspected */ old_used_keys=table->used_keys; // Keys used in WHERE @@ -159,13 +167,6 @@ int mysql_update(THD *thd, matching rows before updating the table! */ table->file->extra(HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE); - IO_CACHE tempfile; - if (open_cached_file(&tempfile, mysql_tmpdir,TEMP_PREFIX, - DISK_BUFFER_SIZE, MYF(MY_WME))) - { - delete select; /* purecov: inspected */ - DBUG_RETURN(-1); - } if (old_used_keys & ((key_map) 1 << used_index)) { table->key_read=1; @@ -174,81 +175,97 @@ int mysql_update(THD *thd, if (order) { + /* + Doing an ORDER BY; Let filesort find and sort the rows we are going + to update + */ uint length; SORT_FIELD *sortorder; - TABLE_LIST tables; List<Item> fields; - List<Item> all_fields; ha_rows examined_rows; - bzero((char*) &tables,sizeof(tables)); - tables.table = table; - table->io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE), MYF(MY_FAE | MY_ZEROFILL)); - if (setup_order(thd, &tables, fields, all_fields, order) || - !(sortorder=make_unireg_sortorder(order, &length)) || + if (!(sortorder=make_unireg_sortorder(order, &length)) || (table->found_records = filesort(table, sortorder, length, - (SQL_SELECT *) 0, 0L, - HA_POS_ERROR, &examined_rows)) - == HA_POS_ERROR) + select, 0L, + limit, &examined_rows)) == + HA_POS_ERROR) { delete select; + free_io_cache(table); DBUG_RETURN(-1); } + /* + Filesort has already found and selected the rows we want to update, + so we don't need the where clause + */ + delete select; + select= 0; } - - init_read_record(&info,thd,table,select,0,1); - thd->proc_info="Searching rows for update"; - - while (!(error=info.read_record(&info)) && !thd->killed) + else { - if (!(select && select->skipp_record())) + /* + We are doing a search on a key that is updated. In this case + we go trough the matching rows, save a pointer to them and + update these in a separate loop based on the pointer. + */ + + IO_CACHE tempfile; + if (open_cached_file(&tempfile, mysql_tmpdir,TEMP_PREFIX, + DISK_BUFFER_SIZE, MYF(MY_WME))) { - table->file->position(table->record[0]); - if (my_b_write(&tempfile,table->file->ref, - table->file->ref_length)) + delete select; /* purecov: inspected */ + DBUG_RETURN(-1); + } + + init_read_record(&info,thd,table,select,0,1); + thd->proc_info="Searching rows for update"; + uint tmp_limit= limit; + while (!(error=info.read_record(&info)) && !thd->killed) + { + if (!(select && select->skipp_record())) { - error=1; /* purecov: inspected */ - break; /* purecov: inspected */ + table->file->position(table->record[0]); + if (my_b_write(&tempfile,table->file->ref, + table->file->ref_length)) + { + error=1; /* purecov: inspected */ + break; /* purecov: inspected */ + } + if (!--limit && using_limit) + break; } } + end_read_record(&info); + /* Change select to use tempfile */ + if (select) + { + delete select->quick; + if (select->free_cond) + delete select->cond; + select->quick=0; + select->cond=0; + } else { - if (!(test_flags & 512)) /* For debugging */ - { - DBUG_DUMP("record",(char*) table->record[0],table->reclength); - } + select= new SQL_SELECT; + select->head=table; + } + if (reinit_io_cache(&tempfile,READ_CACHE,0L,0,0)) + error=1; /* purecov: inspected */ + select->file=tempfile; // Read row ptrs from this file + if (error >= 0) + { + delete select; + DBUG_RETURN(-1); } } - end_read_record(&info); if (table->key_read) { table->key_read=0; table->file->extra(HA_EXTRA_NO_KEYREAD); } - /* Change select to use tempfile */ - if (select) - { - delete select->quick; - if (select->free_cond) - delete select->cond; - select->quick=0; - select->cond=0; - } - else - { - select= new SQL_SELECT; - select->head=table; - } - if (reinit_io_cache(&tempfile,READ_CACHE,0L,0,0)) - error=1; /* purecov: inspected */ - select->file=tempfile; // Read row ptrs from this file - if (error >= 0) - { - delete select; - DBUG_RETURN(-1); - } } if (handle_duplicates == DUP_IGNORE) @@ -275,11 +292,6 @@ int mysql_update(THD *thd, (byte*) table->record[0]))) { updated++; - if (!--limit && using_limit) - { - error= -1; - break; - } } else if (handle_duplicates != DUP_IGNORE || error != HA_ERR_FOUND_DUPP_KEY) @@ -289,11 +301,17 @@ int mysql_update(THD *thd, break; } } + if (!--limit && using_limit) + { + error= -1; // Simulate end of file + break; + } } else table->file->unlock_row(); } end_read_record(&info); + free_io_cache(table); // If ORDER BY thd->proc_info="end"; VOID(table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY)); transactional_table= table->file->has_transactions(); @@ -743,7 +761,8 @@ bool multi_update::send_data(List<Item> ¬_used_values) (error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE)) { - if (create_myisam_from_heap(tmp_table, tmp_table_param + offset, error, 1)) + if (create_myisam_from_heap(thd, tmp_table, tmp_table_param + offset, + error, 1)) { do_update=0; DBUG_RETURN(1); // Not a table_is_full error diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c index 5fab4f86ff2..885d4406cd6 100644 --- a/strings/ctype-tis620.c +++ b/strings/ctype-tis620.c @@ -453,81 +453,78 @@ uchar NEAR sort_order_tis620[]= Arg: const source string and length of converted string Ret: Sortable string */ - +/* + NOTE: isn't it faster to alloc buffer in calling function? + */ static uchar* thai2sortable(const uchar * tstr,uint len) { /* We use only 3 levels (neglect capitalization). */ - const uchar* p = tstr; + const uchar* p= tstr; uchar *outBuf; -/* uchar *pRight1, *pRight2, *pRight3, *pRight4; */ -/* uchar *pLeft1, *pLeft2, *pLeft3, *pLeft4; */ uchar *pRight1, *pRight2, *pRight3; uchar *pLeft1, *pLeft2, *pLeft3; uint bufSize; - - len = (uint) strnlen((char*) tstr,len); - bufSize = (uint) buffsize((char*) tstr); - if(!(pRight1 = (uchar *)malloc(sizeof(uchar) * bufSize))) { - return( (uchar*) tstr); - } - pLeft1 = pRight1; - outBuf = pRight1; - if(!(pRight2 = (uchar *)malloc(sizeof(uchar) * (len + 1)))) { - free(pRight1); - return((uchar*) tstr); - } - pLeft2 = pRight2; - if(!(pRight3 = (uchar *)malloc(sizeof(uchar) * (len + 1)))) { - free(pRight1); - free(pRight2); - return((uchar*) tstr); - } - pLeft3 = pRight3; -/* if(!(pRight4 = (uchar *)malloc(sizeof(uchar) * (len + 1)))) { - free(pRight1); - free(pRight2); - free(pRight3); - return((uchar*) tstr); - } - pLeft4 = pRight4;*/ - while((len--)) { - if(isldvowel(*p) && isconsnt(p[1])) { - *pRight1++ = t_ctype[p[1]][0]; - *pRight2++ = t_ctype[p[1]][1]; - *pRight3++ = t_ctype[p[1]][2]; -/* *pRight4++ = t_ctype[p[1]][3]; */ - *pRight1++ = t_ctype[*p][0]; - *pRight2++ = t_ctype[*p][1]; - *pRight3++ = t_ctype[*p][2]; -/* *pRight4++ = t_ctype[*p][3]; */ - p += 2; - } else { - *pRight1 = t_ctype[*p][0]; - if(*pRight1 != IGNORE) pRight1++; - *pRight2 = t_ctype[*p][1]; - if(*pRight2 != IGNORE) pRight2++; - *pRight3 = t_ctype[*p][2]; - if(*pRight3 != IGNORE) pRight3++; -/* *pRight4 = t_ctype[*p][3]; - if(*pRight4 != IGNORE) pRight4++;*/ + uint RightSize; + + len= (uint) strnlen((char*) tstr,len); + bufSize= (uint) buffsize((char*) tstr); + RightSize= sizeof(uchar) * (len + 1); + if (!(outBuf= pLeft1= pRight1= + (uchar *)malloc(sizeof(uchar) * bufSize + RightSize*2))) + return (uchar*) tstr; + pLeft2= pRight2= pRight1 + sizeof(uchar) * bufSize; + pLeft3= pRight3= pRight2 + RightSize; + + while (--len) + { + int *t_ctype0= t_ctype[p[0]]; + if (isldvowel(*p) && isconsnt(p[1])) + { + int *t_ctype1= t_ctype[p[1]]; + *pRight1++= t_ctype1[0]; + *pRight2++= t_ctype1[1]; + *pRight3++= t_ctype1[2]; + *pRight1++= t_ctype0[0]; + *pRight2++= t_ctype0[1]; + *pRight3++= t_ctype0[2]; + p+= 2; + len--; + } + else + { + *pRight1= t_ctype0[0]; + if(*pRight1 != IGNORE) + pRight1++; + *pRight2= t_ctype0[1]; + if (*pRight2 != IGNORE) + pRight2++; + *pRight3= t_ctype0[2]; + if(*pRight3 != IGNORE) + pRight3++; p++; } } - *pRight1++ = L2_BLANK; - *pRight2++ = L3_BLANK; -/* *pRight3++ = L4_BLANK; */ - *pRight3++ = '\0'; -/* *pRight4++ = '\0'; */ + if (!len) + { + int *t_ctype0= t_ctype[p[0]]; + *pRight1= t_ctype0[0]; + if (*pRight1 != IGNORE) + pRight1++; + *pRight2= t_ctype0[1]; + if (*pRight2 != IGNORE) + pRight2++; + *pRight3= t_ctype0[2]; + if (*pRight3 != IGNORE) + pRight3++; + } + *pRight1++= L2_BLANK; + *pRight2++= L3_BLANK; + *pRight3++= '\0'; memcpy(pRight1, pLeft2, pRight2 - pLeft2); - pRight1 += pRight2 - pLeft2; + pRight1+= pRight2 - pLeft2; memcpy(pRight1, pLeft3, pRight3 - pLeft3); -/* pRight1 += pRight3 - pLeft3; */ -/* memcpy(pRight1, pLeft4, pRight4 - pLeft4); */ - free(pLeft2); - free(pLeft3); -/* free(pLeft4); */ - return(outBuf); + return outBuf; } /* strncoll() replacement, compare 2 string, both are conveted to sortable string @@ -538,12 +535,12 @@ int my_strnncoll_tis620(const uchar * s1, int len1, const uchar * s2, int len2) { uchar *tc1, *tc2; int i; - tc1 = thai2sortable(s1, len1); - tc2 = thai2sortable(s2, len2); - i = strcmp((char*)tc1, (char*)tc2); + tc1= thai2sortable(s1, len1); + tc2= thai2sortable(s2, len2); + i= strcmp((char*)tc1, (char*)tc2); free(tc1); free(tc2); - return(i); + return i; } /* strnxfrm replacment, convert Thai string to sortable string @@ -554,12 +551,12 @@ int my_strnxfrm_tis620(uchar * dest, const uchar * src, int len, int srclen) { uint bufSize; uchar *tmp; - bufSize = (uint) buffsize((char*)src); - tmp = thai2sortable(src,srclen); + bufSize= (uint) buffsize((char*)src); + tmp= thai2sortable(src,srclen); set_if_smaller(bufSize,(uint) len); memcpy((uchar *)dest, tmp, bufSize); free(tmp); - return (int) bufSize; + return (int)bufSize; } /* strcoll replacment, compare 2 strings @@ -570,12 +567,12 @@ int my_strcoll_tis620(const uchar * s1, const uchar * s2) { uchar *tc1, *tc2; int i; - tc1 = thai2sortable(s1, (uint) strlen((char*)s1)); - tc2 = thai2sortable(s2, (uint) strlen((char*)s2)); - i = strcmp((char*)tc1, (char*)tc2); + tc1= thai2sortable(s1, (uint) strlen((char*)s1)); + tc2= thai2sortable(s2, (uint) strlen((char*)s2)); + i= strcmp((char*)tc1, (char*)tc2); free(tc1); free(tc2); - return(i); + return i; } /* strxfrm replacment, convert Thai string to sortable string @@ -587,9 +584,9 @@ int my_strxfrm_tis620(uchar * dest, const uchar * src, int len) uint bufSize; uchar *tmp; - bufSize = (uint) buffsize((char*) src); - tmp = thai2sortable(src, len); - memcpy((uchar *) dest, tmp, bufSize); + bufSize= (uint)buffsize((char*) src); + tmp= thai2sortable(src, len); + memcpy((uchar *)dest, tmp, bufSize); free(tmp); return bufSize; } @@ -619,7 +616,7 @@ my_bool my_like_range_tis620(const char *ptr, uint ptr_length, pchar escape, if (*ptr == escape && ptr+1 != end) { ptr++; /* Skipp escape */ - *min_str++= *max_str++ = *ptr; + *min_str++ = *max_str++ = *ptr; continue; } if (*ptr == wild_one) /* '_' in SQL */ @@ -653,26 +650,22 @@ my_bool my_like_range_tis620(const char *ptr, uint ptr_length, pchar escape, */ void ThNormalize(uchar* ptr, uint field_length, const uchar* from, uint length) { - const uchar* fr = from; - uchar* p = ptr; + const uchar* fr= from; + uchar* p= ptr; + + if (length > field_length) + length= field_length; - if(length > field_length) { - length = field_length; - } while (length--) - { - if((istone(*fr) || isdiacrt1(*fr)) && + if ((istone(*fr) || isdiacrt1(*fr)) && (islwrvowel(fr[1]) || isuprvowel(fr[1]))) { - *p = fr[1]; - p[1] = *fr; - fr += 2; - p += 2; + *p= fr[1]; + p[1]= *fr; + fr+= 2; + p+= 2; length--; } else - { *p++ = *fr++; - } - } } diff --git a/support-files/MacOSX/Makefile.am b/support-files/MacOSX/Makefile.am index d030ff39d84..b8047942190 100644 --- a/support-files/MacOSX/Makefile.am +++ b/support-files/MacOSX/Makefile.am @@ -34,7 +34,8 @@ CLEANFILES = Info.plist \ Description.plist \ StartupParameters.plist \ postinstall \ - preinstall + preinstall \ + ReadMe.txt SUFFIXES = .sh diff --git a/support-files/MacOSX/ReadMe.txt b/support-files/MacOSX/ReadMe.txt deleted file mode 100644 index a18c5f3aa41..00000000000 --- a/support-files/MacOSX/ReadMe.txt +++ /dev/null @@ -1,80 +0,0 @@ -Installation notes for MySQL on Mac OS X - -PLEASE READ! - -For more details about installing and running -MySQL on Mac OS X, also refer to the manual, -which is available online: - -http://www.mysql.com/doc/en/Mac_OS_X_installation.html - -NOTE: Before proceeding with the installation, please -make sure that no other MySQL server is running! - -Please shut down all running MySQL instances before -continuing by either using the MySQL Manager -Application (on Mac OS X Server) or via "mysqladmin -shutdown" on the command line. - -This MySQL package will be installed into -"/usr/local/mysql-<version>" and will also create a -symbolic link "/usr/local/mysql", pointing to the new -location. - -A previously existing /usr/local/mysql directory will -be renamed to /usr/local/mysql.bak before proceeding -with the installation. - -Additionally, it will install the mysql grant tables by -executing "mysql_install_db" after the installation. - -If you are running Mac OS X Server, you already have a -version MySQL installed. Make sure to read Apple's help -about installing MySQL (Run the "Help View" application, -select "Mac OS X Server help", and do a search for MySQL -and read the item entitled "Installing MySQL"). - -If you previously used Marc Liyanage's MySQL packages -for MacOS X from http://www.entropy.ch, you can simply -follow the update instructions given on his pages. - -After the installation (and restoring the old database -files, if necessary), you can start up MySQL by running -the following commands in a terminal window: - - cd /usr/local/mysql - sudo ./bin/mysqld_safe - (Enter your password) - (Press CTRL+Z) - bg - (Press CTRL+D to exit the shell) - -You should now be able to connect to the MySQL server, -e.g. by running /usr/local/mysql/bin/mysql - -If you installed MySQL for the first time, -PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER! -This is done with the following two commands: - -/usr/local/mysql/bin/mysqladmin -u root password 'new-password' - -/usr/local/mysql/bin/mysqladmin -u root -h $hostname password 'new-password' - -Please note, that after upgrading from MySQL 3.23 to -MySQL 4.0 it is recommended to convert the MySQL -privilege tables using the mysql_fix_privilege_tables -script, since some new security privileges have been -added. - -Please see -http://www.mysql.com/doc/en/Upgrading-from-3.23.html -for more information on how to upgrade from MySQL 3.23. - -If you do not want to have to type the full path -"/usr/local/mysql/bin" in front of every command, you -can to add this directory to your PATH environment -variable in your login script. For the default shell -"tcsh", you can do this by running this command once: - -echo 'setenv PATH $PATH:/usr/local/mysql/bin' >> ~/.tcshrc - diff --git a/support-files/my-huge.cnf.sh b/support-files/my-huge.cnf.sh index 3362d5bd131..18e926b1400 100644 --- a/support-files/my-huge.cnf.sh +++ b/support-files/my-huge.cnf.sh @@ -26,21 +26,22 @@ socket = @MYSQL_UNIX_ADDR@ port = @MYSQL_TCP_PORT@ socket = @MYSQL_UNIX_ADDR@ skip-locking -set-variable = key_buffer=384M -set-variable = max_allowed_packet=1M -set-variable = table_cache=512 -set-variable = sort_buffer_size=2M -set-variable = read_buffer_size=2M -set-variable = myisam_sort_buffer_size=64M -set-variable = thread_cache=8 +key_buffer = 384M +max_allowed_packet = 1M +table_cache = 512 +sort_buffer_size = 2M +read_buffer_size = 2M +myisam_sort_buffer_size = 64M +thread_cache = 8 +query_cache_size = 32M # Try number of CPU's*2 for thread_concurrency -set-variable = thread_concurrency=8 +thread_concurrency = 8 # Don't listen on a TCP/IP port at all. This can be a security enhancement, # if all processes that need to connect to mysqld run on the same host. # All interaction with mysqld must be made via Unix sockets or named pipes. # Note that using this option without enabling named pipes on Windows -# (via the "pipe" option) will render mysqld useless! +# (via the "enable-named-pipe" option) will render mysqld useless! # #skip-networking @@ -113,8 +114,8 @@ server-id = 1 #log-update = /path-to-dedicated-directory/hostname # Uncomment the following if you are using BDB tables -#set-variable = bdb_cache_size=384M -#set-variable = bdb_max_lock=100000 +#bdb_cache_size = 384M +#bdb_max_lock = 100000 # Uncomment the following if you are using InnoDB tables #innodb_data_home_dir = @localstatedir@/ @@ -123,17 +124,17 @@ server-id = 1 #innodb_log_arch_dir = @localstatedir@/ # You can set .._buffer_pool_size up to 50 - 80 % # of RAM but beware of setting memory usage too high -#set-variable = innodb_buffer_pool_size=384M -#set-variable = innodb_additional_mem_pool_size=20M +#innodb_buffer_pool_size = 384M +#innodb_additional_mem_pool_size = 20M # Set .._log_file_size to 25 % of buffer pool size -#set-variable = innodb_log_file_size=100M -#set-variable = innodb_log_buffer_size=8M -#innodb_flush_log_at_trx_commit=1 -#set-variable = innodb_lock_wait_timeout=50 +#innodb_log_file_size = 100M +#innodb_log_buffer_size = 8M +#innodb_flush_log_at_trx_commit = 1 +#innodb_lock_wait_timeout = 50 [mysqldump] quick -set-variable = max_allowed_packet=16M +max_allowed_packet = 16M [mysql] no-auto-rehash @@ -141,16 +142,16 @@ no-auto-rehash #safe-updates [isamchk] -set-variable = key_buffer=256M -set-variable = sort_buffer_size=256M -set-variable = read_buffer=2M -set-variable = write_buffer=2M +key_buffer = 256M +sort_buffer_size = 256M +read_buffer = 2M +write_buffer = 2M [myisamchk] -set-variable = key_buffer=256M -set-variable = sort_buffer_size=256M -set-variable = read_buffer=2M -set-variable = write_buffer=2M +key_buffer = 256M +sort_buffer_size = 256M +read_buffer = 2M +write_buffer = 2M [mysqlhotcopy] interactive-timeout diff --git a/support-files/my-large.cnf.sh b/support-files/my-large.cnf.sh index 5bc3a8eb0c4..2b92dc61053 100644 --- a/support-files/my-large.cnf.sh +++ b/support-files/my-large.cnf.sh @@ -26,21 +26,22 @@ socket = @MYSQL_UNIX_ADDR@ port = @MYSQL_TCP_PORT@ socket = @MYSQL_UNIX_ADDR@ skip-locking -set-variable = key_buffer=256M -set-variable = max_allowed_packet=1M -set-variable = table_cache=256 -set-variable = sort_buffer_size=1M -set-variable = read_buffer_size=1M -set-variable = myisam_sort_buffer_size=64M -set-variable = thread_cache=8 +key_buffer = 256M +max_allowed_packet = 1M +table_cache = 256 +sort_buffer_size = 1M +read_buffer_size = 1M +myisam_sort_buffer_size = 64M +thread_cache = 8 +query_cache_size= 16M # Try number of CPU's*2 for thread_concurrency -set-variable = thread_concurrency=8 +thread_concurrency = 8 # Don't listen on a TCP/IP port at all. This can be a security enhancement, # if all processes that need to connect to mysqld run on the same host. # All interaction with mysqld must be made via Unix sockets or named pipes. # Note that using this option without enabling named pipes on Windows -# (via the "pipe" option) will render mysqld useless! +# (via the "enable-named-pipe" option) will render mysqld useless! # #skip-networking @@ -113,8 +114,8 @@ server-id = 1 #log-update = /path-to-dedicated-directory/hostname # Uncomment the following if you are using BDB tables -#set-variable = bdb_cache_size=64M -#set-variable = bdb_max_lock=100000 +#bdb_cache_size = 64M +#bdb_max_lock = 100000 # Uncomment the following if you are using InnoDB tables #innodb_data_home_dir = @localstatedir@/ @@ -123,17 +124,17 @@ server-id = 1 #innodb_log_arch_dir = @localstatedir@/ # You can set .._buffer_pool_size up to 50 - 80 % # of RAM but beware of setting memory usage too high -#set-variable = innodb_buffer_pool_size=256M -#set-variable = innodb_additional_mem_pool_size=20M +#innodb_buffer_pool_size = 256M +#innodb_additional_mem_pool_size = 20M # Set .._log_file_size to 25 % of buffer pool size -#set-variable = innodb_log_file_size=64M -#set-variable = innodb_log_buffer_size=8M -#innodb_flush_log_at_trx_commit=1 -#set-variable = innodb_lock_wait_timeout=50 +#innodb_log_file_size = 64M +#innodb_log_buffer_size = 8M +#innodb_flush_log_at_trx_commit = 1 +#innodb_lock_wait_timeout = 50 [mysqldump] quick -set-variable = max_allowed_packet=16M +max_allowed_packet = 16M [mysql] no-auto-rehash @@ -141,16 +142,16 @@ no-auto-rehash #safe-updates [isamchk] -set-variable = key_buffer=128M -set-variable = sort_buffer_size=128M -set-variable = read_buffer=2M -set-variable = write_buffer=2M +key_buffer = 128M +sort_buffer_size = 128M +read_buffer = 2M +write_buffer = 2M [myisamchk] -set-variable = key_buffer=128M -set-variable = sort_buffer_size=128M -set-variable = read_buffer=2M -set-variable = write_buffer=2M +key_buffer = 128M +sort_buffer_size = 128M +read_buffer = 2M +write_buffer = 2M [mysqlhotcopy] interactive-timeout diff --git a/support-files/my-medium.cnf.sh b/support-files/my-medium.cnf.sh index 084f23cbc94..601ffc503c0 100644 --- a/support-files/my-medium.cnf.sh +++ b/support-files/my-medium.cnf.sh @@ -27,18 +27,18 @@ socket = @MYSQL_UNIX_ADDR@ port = @MYSQL_TCP_PORT@ socket = @MYSQL_UNIX_ADDR@ skip-locking -set-variable = key_buffer=16M -set-variable = max_allowed_packet=1M -set-variable = table_cache=64 -set-variable = sort_buffer_size=512K -set-variable = net_buffer_length=8K -set-variable = myisam_sort_buffer_size=8M +key_buffer = 16M +max_allowed_packet = 1M +table_cache = 64 +sort_buffer_size = 512K +net_buffer_length = 8K +myisam_sort_buffer_size = 8M # Don't listen on a TCP/IP port at all. This can be a security enhancement, # if all processes that need to connect to mysqld run on the same host. # All interaction with mysqld must be made via Unix sockets or named pipes. # Note that using this option without enabling named pipes on Windows -# (via the "pipe" option) will render mysqld useless! +# (via the "enable-named-pipe" option) will render mysqld useless! # #skip-networking @@ -111,8 +111,8 @@ server-id = 1 #log-update = /path-to-dedicated-directory/hostname # Uncomment the following if you are using BDB tables -#set-variable = bdb_cache_size=4M -#set-variable = bdb_max_lock=10000 +#bdb_cache_size = 4M +#bdb_max_lock = 10000 # Uncomment the following if you are using InnoDB tables #innodb_data_home_dir = @localstatedir@/ @@ -121,17 +121,17 @@ server-id = 1 #innodb_log_arch_dir = @localstatedir@/ # You can set .._buffer_pool_size up to 50 - 80 % # of RAM but beware of setting memory usage too high -#set-variable = innodb_buffer_pool_size=16M -#set-variable = innodb_additional_mem_pool_size=2M +#innodb_buffer_pool_size = 16M +#innodb_additional_mem_pool_size = 2M # Set .._log_file_size to 25 % of buffer pool size -#set-variable = innodb_log_file_size=5M -#set-variable = innodb_log_buffer_size=8M -#innodb_flush_log_at_trx_commit=1 -#set-variable = innodb_lock_wait_timeout=50 +#innodb_log_file_size = 5M +#innodb_log_buffer_size = 8M +#innodb_flush_log_at_trx_commit = 1 +#innodb_lock_wait_timeout = 50 [mysqldump] quick -set-variable = max_allowed_packet=16M +max_allowed_packet = 16M [mysql] no-auto-rehash @@ -139,16 +139,16 @@ no-auto-rehash #safe-updates [isamchk] -set-variable = key_buffer=20M -set-variable = sort_buffer_size=20M -set-variable = read_buffer=2M -set-variable = write_buffer=2M +key_buffer = 20M +sort_buffer_size = 20M +read_buffer = 2M +write_buffer = 2M [myisamchk] -set-variable = key_buffer=20M -set-variable = sort_buffer_size=20M -set-variable = read_buffer=2M -set-variable = write_buffer=2M +key_buffer = 20M +sort_buffer_size = 20M +read_buffer = 2M +write_buffer = 2M [mysqlhotcopy] interactive-timeout diff --git a/support-files/my-small.cnf.sh b/support-files/my-small.cnf.sh index b11277c1b4a..f9e30da78ac 100644 --- a/support-files/my-small.cnf.sh +++ b/support-files/my-small.cnf.sh @@ -27,18 +27,18 @@ socket = @MYSQL_UNIX_ADDR@ port = @MYSQL_TCP_PORT@ socket = @MYSQL_UNIX_ADDR@ skip-locking -set-variable = key_buffer=16K -set-variable = max_allowed_packet=1M -set-variable = table_cache=4 -set-variable = sort_buffer_size=64K -set-variable = net_buffer_length=2K -set-variable = thread_stack=64K +key_buffer = 16K +max_allowed_packet = 1M +table_cache = 4 +sort_buffer_size = 64K +net_buffer_length = 2K +thread_stack = 64K # Don't listen on a TCP/IP port at all. This can be a security enhancement, # if all processes that need to connect to mysqld run on the same host. # All interaction with mysqld must be made via Unix sockets or named pipes. # Note that using this option without enabling named pipes on Windows -# (via the "pipe" option) will render mysqld useless! +# (using the "enable-named-pipe" option) will render mysqld useless! # #skip-networking server-id = 1 @@ -56,17 +56,17 @@ server-id = 1 #innodb_log_arch_dir = @localstatedir@/ # You can set .._buffer_pool_size up to 50 - 80 % # of RAM but beware of setting memory usage too high -#set-variable = innodb_buffer_pool_size=16M -#set-variable = innodb_additional_mem_pool_size=2M +#innodb_buffer_pool_size = 16M +#innodb_additional_mem_pool_size = 2M # Set .._log_file_size to 25 % of buffer pool size -#set-variable = innodb_log_file_size=5M -#set-variable = innodb_log_buffer_size=8M -#innodb_flush_log_at_trx_commit=1 -#set-variable = innodb_lock_wait_timeout=50 +#innodb_log_file_size = 5M +#innodb_log_buffer_size = 8M +#innodb_flush_log_at_trx_commit = 1 +#innodb_lock_wait_timeout = 50 [mysqldump] quick -set-variable = max_allowed_packet=16M +max_allowed_packet = 16M [mysql] no-auto-rehash @@ -74,12 +74,12 @@ no-auto-rehash #safe-updates [isamchk] -set-variable = key_buffer=8M -set-variable = sort_buffer_size=8M +key_buffer = 8M +sort_buffer_size = 8M [myisamchk] -set-variable = key_buffer=8M -set-variable = sort_buffer_size=8M +key_buffer = 8M +sort_buffer_size = 8M [mysqlhotcopy] interactive-timeout |