summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <monty@hundin.mysql.fi>2002-01-02 22:02:03 +0200
committerunknown <monty@hundin.mysql.fi>2002-01-02 22:02:03 +0200
commit301cdf9f240106978b04d4f8044b24e4a3fa6d00 (patch)
tree0041cf05ee45a8b92584dd5d81ef8b4c5c1f9283
parentb47495360cbd21fa80efc72c18e9892ffeebd1ed (diff)
parent62c4fa399e0c7acb1e7dfdae4ceac4b61daeb744 (diff)
downloadmariadb-git-301cdf9f240106978b04d4f8044b24e4a3fa6d00.tar.gz
merge
Docs/manual.texi: Auto merged sql/item_func.h: Auto merged sql/lex.h: Auto merged sql/mysqld.cc: Auto merged sql/sql_parse.cc: Auto merged sql/sql_select.cc: Auto merged sql/sql_table.cc: Auto merged
-rw-r--r--BUILD/FINISH.sh3
-rw-r--r--BUILD/Makefile.am45
-rw-r--r--BUILD/SETUP.sh4
-rw-r--r--Docs/manual.texi96
-rw-r--r--Makefile.am3
-rw-r--r--client/Makefile.am1
-rw-r--r--client/mysql.cc1
-rw-r--r--client/mysqldump.c71
-rw-r--r--client/readline.cc19
-rw-r--r--configure.in4
-rw-r--r--extra/my_print_defaults.c2
-rw-r--r--include/my_global.h27
-rw-r--r--innobase/btr/btr0sea.c2
-rw-r--r--innobase/include/data0type.ic11
-rw-r--r--innobase/include/dyn0dyn.h5
-rw-r--r--innobase/log/log0recv.c18
-rw-r--r--innobase/os/os0file.c7
-rw-r--r--innobase/rem/rem0cmp.c10
-rw-r--r--innobase/row/row0mysql.c18
-rw-r--r--innobase/srv/srv0srv.c14
-rw-r--r--libmysql/Makefile.shared3
-rw-r--r--libmysqld/examples/Makefile.am2
-rw-r--r--libmysqld/lib_vio.c15
-rw-r--r--myisam/ft_dump.c6
-rw-r--r--myisam/ftdefs.h4
-rw-r--r--mysql-test/r/bdb.result30
-rw-r--r--mysql-test/r/bigint.result9
-rw-r--r--mysql-test/r/fulltext.result6
-rw-r--r--mysql-test/r/heap.result4
-rw-r--r--mysql-test/r/innodb.result30
-rw-r--r--mysql-test/r/isam.result8
-rw-r--r--mysql-test/r/key.result9
-rw-r--r--mysql-test/r/myisam.result12
-rw-r--r--mysql-test/r/query_cache.result53
-rw-r--r--mysql-test/r/select.result8
-rw-r--r--mysql-test/r/show_check.result28
-rw-r--r--mysql-test/r/type_ranges.result30
-rw-r--r--mysql-test/r/variables.result11
-rw-r--r--mysql-test/t/bigint.test4
-rw-r--r--mysql-test/t/key.test8
-rw-r--r--mysql-test/t/query_cache.test28
-rw-r--r--mysql-test/t/variables.test13
-rw-r--r--sql-bench/crash-me.sh33
-rw-r--r--sql/derror.cc34
-rw-r--r--sql/ha_berkeley.h1
-rw-r--r--sql/ha_heap.h1
-rw-r--r--sql/ha_innobase.cc25
-rw-r--r--sql/ha_innobase.h8
-rw-r--r--sql/ha_isam.h1
-rw-r--r--sql/ha_myisam.cc14
-rw-r--r--sql/ha_myisam.h3
-rw-r--r--sql/handler.h1
-rw-r--r--sql/item_func.cc56
-rw-r--r--sql/item_func.h25
-rw-r--r--sql/lex.h1
-rw-r--r--sql/mysqld.cc15
-rw-r--r--sql/net_pkg.cc2
-rw-r--r--sql/net_serv.cc2
-rw-r--r--sql/slave.cc62
-rw-r--r--sql/sql_cache.cc62
-rw-r--r--sql/sql_cache.h7
-rw-r--r--sql/sql_insert.cc16
-rw-r--r--sql/sql_manager.cc8
-rw-r--r--sql/sql_parse.cc4
-rw-r--r--sql/sql_repl.cc25
-rw-r--r--sql/sql_select.cc2
-rw-r--r--sql/sql_show.cc14
-rw-r--r--sql/sql_table.cc105
-rw-r--r--sql/sql_yacc.yy16
69 files changed, 839 insertions, 386 deletions
diff --git a/BUILD/FINISH.sh b/BUILD/FINISH.sh
index 2e2ba1f7358..fbeaf1e3c68 100644
--- a/BUILD/FINISH.sh
+++ b/BUILD/FINISH.sh
@@ -20,7 +20,8 @@ then
(cd gemini && aclocal && autoheader && aclocal && automake && autoconf)
fi
-CFLAGS=\"$cflags\" CXX=$CXX CXXFLAGS=\"$cxxflags\" $configure"
+CFLAGS=\"$cflags\" CXX=\"$CXX\" CXXFLAGS=\"$cxxflags\" CXXLDFLAGS=\"$CXXLDFLAGS\" \
+$configure"
if [ -z "$just_configure" ]
then
diff --git a/BUILD/Makefile.am b/BUILD/Makefile.am
new file mode 100644
index 00000000000..ca42a79eec0
--- /dev/null
+++ b/BUILD/Makefile.am
@@ -0,0 +1,45 @@
+# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+# MA 02111-1307, USA
+
+## Process this file with automake to create Makefile.in
+
+EXTRA_DIST = FINISH.sh \
+ SETUP.sh \
+ compile-alpha \
+ compile-alpha-ccc \
+ compile-alpha-cxx \
+ compile-alpha-debug \
+ compile-ia64-debug-max \
+ compile-pentium \
+ compile-pentium-debug \
+ compile-pentium-debug-max \
+ compile-pentium-debug-no-bdb \
+ compile-pentium-debug-openssl \
+ compile-pentium-gcov \
+ compile-pentium-gprof \
+ compile-pentium-max \
+ compile-pentium-myodbc \
+ compile-pentium-mysqlfs-debug \
+ compile-pentium-pgcc \
+ compile-pentium-symbols \
+ compile-solaris-sparc \
+ compile-solaris-sparc-debug \
+ compile-solaris-sparc-fortre \
+ compile-solaris-sparc-purify
+
+# Don't update the files from bitkeeper
+%::SCCS/s.%
diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh
index f878123db59..3fa297fea1a 100644
--- a/BUILD/SETUP.sh
+++ b/BUILD/SETUP.sh
@@ -69,7 +69,9 @@ fi
if gcc -v 2>&1 | grep 'version 3' > /dev/null 2>&1
then
- CXX=c++
+ CXX="gcc -DUSE_MYSYS_NEW"
+ CXXLDFLAGS="-Wl,--defsym -Wl,__cxa_pure_virtual=0"
else
CXX=gcc
+ CXXLDFLAGS=""
fi
diff --git a/Docs/manual.texi b/Docs/manual.texi
index 9997026afa1..a37d53a289b 100644
--- a/Docs/manual.texi
+++ b/Docs/manual.texi
@@ -1763,7 +1763,7 @@ Many embedded MySQL users will benefit from the @emph{dual licensing}
scheme of the MySQL software, where besides the GPL license also commercial
licensing is available for those not wishing to be bound by the GPL.
The embedded MySQL library uses the same interface as the normal
-client library, so it is convenient and easy to use.
+client library, so it is convenient and easy to use. @xref{libmysqld}.
@node Nutshell Other features, Nutshell Future features, Nutshell Embedded MySQL, MySQL 4.0 In A Nutshell
@@ -8063,6 +8063,11 @@ version 4.0;
@itemize @bullet
@item
+@code{SHOW INDEX} has 2 columns more (@code{Null} and @code{Index_type})
+than it had in 3.23.
+@item
+@code{SIGNED} is a reserved word.
+@item
To use @code{MATCH ... AGAINST (... IN BOOLEAN MODE)} with your tables,
you need to rebuild them with @code{ALTER TABLE table_name TYPE=MyISAM},
@strong{even} if they are of @code{MyISAM} type.
@@ -14172,7 +14177,6 @@ MySQL reads default options from the following files on Windows:
@item @strong{Filename} @tab @strong{Purpose}
@item @code{windows-system-directory\my.ini} @tab Global options
@item @code{C:\my.cnf} @tab Global options
-@item @code{C:\mysql\data\my.cnf} @tab Server-specific options
@end multitable
Note that on Windows, you should specify all paths with @code{/} instead of
@@ -18916,13 +18920,16 @@ are returned:
@item @code{Sub_part} @tab Number of indexed characters if the
column is only partly indexed.
@code{NULL} if the entire key is indexed.
+@item @code{Null} $tab Contains 'YES' if the column may contain @code{NULL}.
+@item @code{Index_type} @tab Index method used.
@item @code{Comment} @tab Various remarks. For now, it tells
- whether index is FULLTEXT or not.
+in MySQL < 4.0.2 whether index is @code{FULLTEXT} or not.
@end multitable
Note that as the @code{Cardinality} is counted based on statistics
stored as integers, it's not necessarily accurate for small tables.
+The @code{Null} and @code{Index_type} column was added in MySQL 4.0.2.
@node SHOW TABLE STATUS, SHOW STATUS, SHOW DATABASE INFO, SHOW
@subsubsection @code{SHOW TABLE STATUS}
@@ -19759,7 +19766,7 @@ subsystem)
@cindex threads, display
@cindex processes, display
-@code{SHOW PROCESSLIST} shows you which threads are running. You can
+@code{SHOW [FULL] PROCESSLIST} shows you which threads are running. You can
also get this information using the @code{mysqladmin processlist}
command. If you have the @strong{process} privilege, you can see all
threads. Otherwise, you can see only your own threads. @xref{KILL, ,
@@ -21164,7 +21171,7 @@ the following configure options:
You can find the MySQL-max binaries at
@uref{http://www.mysql.com/downloads/mysql-max-3.23.html}.
-The Windows MySQL 3.23 binary distribution includes both the
+The Windows MySQL binary distributions includes both the
standard @code{mysqld.exe} binary and the @code{mysqld-max.exe} binary.
@uref{http://www.mysql.com/downloads/mysql-3.23.html}.
@xref{Windows installation}.
@@ -30678,6 +30685,7 @@ make string comparison even more flexible.
@menu
* Arithmetic functions:: Arithmetic Operations
* Mathematical functions:: Mathematical Functions
+* Numerical casts::
@end menu
@@ -30746,7 +30754,7 @@ in a context where its result is converted to an integer!
@end table
-@node Mathematical functions, , Arithmetic functions, Numeric Functions
+@node Mathematical functions, Numerical casts, Arithmetic functions, Numeric Functions
@subsubsection Mathematical Functions
All mathematical functions return @code{NULL} in case of an error.
@@ -31143,6 +31151,35 @@ The above happens because 10.28 is actually stored as something like
10.2799999999999999.
@end table
+@node Numerical casts, , Mathematical functions, Numeric Functions
+@subsubsection Casting numbers to signed / unsigned
+
+@cindex casts, SIGNED
+@cindex casts, UNSIGNED
+
+To cast a string to a numeric value, you don't have to do anything; Just
+use the string value as it would be a number:
+
+@example
+mysql> select 1+'1';
+ -> 2
+@end example
+
+MySQL support arithmetic with both signed and unsigned 64 bit values.
+If you are using an numerical operations (like @code{+}) and one of the
+operands are @code{unsigned}, then the result will be unsigned. You can
+override this by using the @code{SIGNED} and @code{UNSIGNED} cast
+operators, which will cast the operation to signed respective unsigned
+64 bit integer.
+
+@example
+mysql> select UNSIGNED 1-2;
+ -> 18446744073709551615
+mysql select SIGNED (UNSIGNED 1-2);
+ -> -1
+@end example
+
+@code{SIGNED} and @code{UNSIGNED} where added in MySQL 4.0.2.
@node Date and time functions, Other Functions, Numeric Functions, Functions
@subsection Date and Time Functions
@@ -31621,10 +31658,11 @@ mysql> select NOW() + 0;
@item UNIX_TIMESTAMP()
@itemx UNIX_TIMESTAMP(date)
If called with no argument, returns a Unix timestamp (seconds since
-@code{'1970-01-01 00:00:00'} GMT). If @code{UNIX_TIMESTAMP()} is called with
-a @code{date} argument, it returns the value of the argument as seconds since
-@code{'1970-01-01 00:00:00'} GMT. @code{date} may be a @code{DATE} string,
-a @code{DATETIME} string, a @code{TIMESTAMP}, or a number in the format
+@code{'1970-01-01 00:00:00'} GMT) as an unsigned integer. If
+@code{UNIX_TIMESTAMP()} is called with a @code{date} argument, it
+returns the value of the argument as seconds since @code{'1970-01-01
+00:00:00'} GMT. @code{date} may be a @code{DATE} string, a
+@code{DATETIME} string, a @code{TIMESTAMP}, or a number in the format
@code{YYMMDD} or @code{YYYYMMDD} in local time:
@example
@@ -31635,11 +31673,14 @@ mysql> select UNIX_TIMESTAMP('1997-10-04 22:23:00');
@end example
When @code{UNIX_TIMESTAMP} is used on a @code{TIMESTAMP} column, the function
-will receive the value directly, with no implicit
+will return the internal timestamp value directly, with no implicit
``string-to-unix-timestamp'' conversion.
If you give @code{UNIX_TIMESTAMP()} a wrong or out-of-range date, it will
return 0.
+If you want to subtract @code{UNIX_TIMESTAMP()} columns,
+@xref{Numerical casts}.
+
@findex FROM_UNIXTIME()
@item FROM_UNIXTIME(unix_timestamp)
Returns a representation of the @code{unix_timestamp} argument as a value in
@@ -43189,6 +43230,11 @@ No UDF functions.
No stack trace on core dump.
@item
No internal RAID support.
+@item
+You can set this up as a server or a master (no replication).
+@item
+You can't connect to the embedded server from an outside process with
+sockets or TCP/IP.
@end itemize
Some of these limitations can be changed by editing the @file{mysql_embed.h}
@@ -43197,6 +43243,8 @@ include file and recompiling MySQL.
@node libmysqld options, libmysqld TODO, libmysqld restrictions, libmysqld
@subsubsection Using Option Files with the Embedded Server
+@cindex defaults, embedded
+
The following is the recommended way to use option files to make it easy
to switch between a client/server application and one where MySQL is
embedded. @xref{Option files}.
@@ -43930,7 +43978,7 @@ is not the case, you should run the script
@menu
* UDF calling:: UDF Calling Sequences
-* UDF aggr. calling:: UDF Calling Sequences for aggregate functions
+* UDF aggr. calling ::
* UDF arguments:: Argument Processing
* UDF return values:: Return Values and Error Handling
* UDF compiling:: Compiling and Installing User-definable Functions
@@ -47893,11 +47941,24 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}.
@cindex changes, version 4.0
@menu
+* News-4.0.2:: Changes in release 4.0.2
* News-4.0.1:: Changes in release 4.0.1
* News-4.0.0:: Changes in release 4.0.0
@end menu
-@node News-4.0.1, News-4.0.0, News-4.0.x, News-4.0.x
+@node News-4.0.2, News-4.0.1, News-4.0.x, News-4.0.x
+@appendixsubsec Changes in release 4.0.2
+
+@itemize @bullet
+@item
+Added cast functions @code{SIGNED} and @code{UNSIGNED}.
+@item
+Changed order of how keys are created in tables.
+@item
+Added a new columns @code{Null} and @code{Index_type} to @code{SHOW INDEX}.
+@end itemize
+
+@node News-4.0.1, News-4.0.0, News-4.0.2, News-4.0.x
@appendixsubsec Changes in release 4.0.1
@itemize @bullet
@@ -48180,15 +48241,18 @@ not yet 100% confident in this code.
@appendixsubsec Changes in release 3.23.47
@itemize @bullet
@item
+Fixed in when using the following construct:
+@code{SELECT ... WHERE key=@@var_name OR $key=@@var_name2}
+@item
+Restrict InnoDB keys to 500 bytes.
+@item
InnoDB now supports @code{NULL} in keys.
@item
Fixed shutdown problem on HPUX. (Introduced in 3.23.46)
@item
-Added 'DO expression' command.
-@item
Fixed core-dump bug in replication when using SELECT RELEASE_LOCK();
@item
-Added new statement DO expression,[expression].
+Added new command: @code{DO expression,[expression]}
@item
Added @code{slave-skip-errors} option
@item
diff --git a/Makefile.am b/Makefile.am
index 7257617b8e6..af2f13f8f5b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -23,7 +23,8 @@ EXTRA_DIST = INSTALL-SOURCE README \
COPYING COPYING.LIB MIRRORS
SUBDIRS = include @docs_dirs@ @readline_dir@ \
@thread_dirs@ pstack @sql_client_dirs@ \
- @sql_server_dirs@ @libmysqld_dirs@ scripts tests man \
+ @sql_server_dirs@ @libmysqld_dirs@ scripts man \
+ tests BUILD \
@bench_dirs@ support-files @fs_dirs@ @tools_dirs@
# Relink after clean
diff --git a/client/Makefile.am b/client/Makefile.am
index 8763486d3e2..cccb612af98 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -28,6 +28,7 @@ noinst_HEADERS = sql_string.h completion_hash.h my_readline.h \
client_priv.h
mysql_SOURCES = mysql.cc readline.cc sql_string.cc completion_hash.cc
mysql_LDADD = @readline_link@ @TERMCAP_LIB@ $(LDADD) $(CXXLDFLAGS)
+mysqlbinlog_LDADD = $(LDADD) $(CXXLDFLAGS)
mysql_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
mysqladmin_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
mysqlcheck_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
diff --git a/client/mysql.cc b/client/mysql.cc
index 2f040a0596f..72c97872455 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -171,7 +171,6 @@ static int sql_connect(char *host,char *database,char *user,char *password,
uint silent);
static int put_info(const char *str,INFO_TYPE info,uint error=0);
static void safe_put_field(const char *pos,ulong length);
-static const char *array_value(const char **array, char *key);
static void xmlencode_print(const char *src, uint length);
static void init_pager();
static void end_pager();
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 083f7a02d6f..25768dbe188 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -35,7 +35,7 @@
** and adapted to mysqldump 05/11/01 by Jani Tolonen
*/
-#define DUMP_VERSION "8.19"
+#define DUMP_VERSION "8.20"
#include <my_global.h>
#include <my_sys.h>
@@ -101,6 +101,7 @@ static struct option long_options[] =
{"debug", optional_argument, 0, '#'},
{"default-character-set", required_argument, 0, OPT_DEFAULT_CHARSET},
{"delayed-insert", no_argument, 0, OPT_DELAYED},
+ {"disable-keys", no_argument, 0, 'K'},
{"extended-insert", no_argument, 0, 'e'},
{"fields-terminated-by", required_argument, 0, (int) OPT_FTB},
{"fields-enclosed-by", required_argument, 0, (int) OPT_ENC},
@@ -118,7 +119,6 @@ static struct option long_options[] =
{"no-create-db", no_argument, 0, 'n'},
{"no-create-info", no_argument, 0, 't'},
{"no-data", no_argument, 0, 'd'},
- {"no-disable-keys", no_argument, 0, 'K'},
{"opt", no_argument, 0, OPT_OPTIMIZE},
{"password", optional_argument, 0, 'p'},
#ifdef __WIN__
@@ -154,7 +154,7 @@ CHANGEABLE_VAR md_changeable_vars[] = {
};
static void safe_exit(int error);
-static void write_heder(FILE *sql_file, char *db_name);
+static void write_header(FILE *sql_file, char *db_name);
static void print_value(FILE *file, MYSQL_RES *result, MYSQL_ROW row,
const char *prefix,const char *name,
int string_value);
@@ -215,9 +215,9 @@ static void usage(void)
puts("\
-l, --lock-tables Lock all tables for read.\n\
--no-autocommit Wrap tables with autocommit/commit statements.\n\
- -K, --no-disable-keys '/*!40000 ALTER TABLE tb_name DISABLE KEYS */;\n\
+ -K, --disable-keys '/*!40000 ALTER TABLE tb_name DISABLE KEYS */;\n\
and '/*!40000 ALTER TABLE tb_name ENABLE KEYS */;\n\
- will not be put in the output.\n\
+ will be put in the output.\n\
-n, --no-create-db 'CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;'\n\
will not be put in the output. The above line will\n\
be added otherwise, if --databases or\n\
@@ -226,8 +226,8 @@ puts("\
-d, --no-data No row information.\n\
-O, --set-variable var=option\n\
give a variable a value. --help lists variables\n\
- --opt Same as --add-drop-table --add-locks --all\n\
- --extended-insert --quick --lock-tables\n\
+ --opt Same as --add-drop-table --add-locks --all --quick\n\
+ --extended-insert --lock-tables --disable-keys\n\
-p, --password[=...] Password to use when connecting to server.\n\
If password is not given it's solicited on the tty.\n");
#ifdef __WIN__
@@ -282,7 +282,7 @@ puts("\
} /* usage */
-static void write_heder(FILE *sql_file, char *db_name)
+static void write_header(FILE *sql_file, char *db_name)
{
if (opt_xml)
fprintf(sql_file,"<?xml version=\"1.0\"?>\n");
@@ -297,7 +297,7 @@ static void write_heder(FILE *sql_file, char *db_name)
mysql_get_server_info(&mysql_connection));
}
return;
-} /* write_heder */
+} /* write_header */
static int get_options(int *argc,char ***argv)
@@ -394,6 +394,7 @@ static int get_options(int *argc,char ***argv)
break;
case 'T':
path= optarg;
+ opt_disable_keys=0;
break;
case 'B':
opt_databases = 1;
@@ -415,7 +416,10 @@ static int get_options(int *argc,char ***argv)
case 'w':
where=optarg;
break;
- case 'X': opt_xml = 1; opt_disable_keys=1; break;
+ case 'X':
+ opt_xml = 1;
+ opt_disable_keys=0;
+ break;
case 'x':
opt_first_slave=1;
break;
@@ -451,7 +455,8 @@ static int get_options(int *argc,char ***argv)
opt_lock=1;
break;
case (int) OPT_OPTIMIZE:
- extended_insert=opt_drop=opt_lock=lock_tables=quick=create_options=1;
+ extended_insert=opt_drop=opt_lock=lock_tables=quick=create_options=
+ opt_disable_keys=1;
break;
case (int) OPT_DELAYED:
opt_delayed=1;
@@ -666,7 +671,7 @@ static uint getTableStructure(char *table, char* db)
safe_exit(EX_MYSQLERR);
DBUG_RETURN(0);
}
- write_heder(sql_file, db);
+ write_header(sql_file, db);
}
if (!opt_xml)
fprintf(sql_file, "\n--\n-- Table structure for table '%s'\n--\n\n",
@@ -685,6 +690,8 @@ static uint getTableStructure(char *table, char* db)
{
fprintf(stderr, "%s: Can't get info about table: '%s'\nerror: %s\n",
my_progname, table, mysql_error(sock));
+ if (path)
+ my_fclose(sql_file, MYF(MY_WME));
safe_exit(EX_MYSQLERR);
DBUG_RETURN(0);
}
@@ -738,10 +745,10 @@ static uint getTableStructure(char *table, char* db)
O_WRONLY, MYF(MY_WME));
if (!sql_file) /* If file couldn't be opened */
{
- safe_exit(EX_MYSQLERR);
- DBUG_RETURN(0);
+ safe_exit(EX_MYSQLERR);
+ DBUG_RETURN(0);
}
- write_heder(sql_file, db);
+ write_header(sql_file, db);
}
if (!opt_xml)
fprintf(sql_file, "\n--\n-- Table structure for table '%s'\n--\n\n",
@@ -804,7 +811,7 @@ static uint getTableStructure(char *table, char* db)
{
fprintf(stderr, "%s: Can't get keys for table '%s' (%s)\n",
my_progname, table, mysql_error(sock));
- if (sql_file != stdout)
+ if (path)
my_fclose(sql_file, MYF(MY_WME));
safe_exit(EX_MYSQLERR);
DBUG_RETURN(0);
@@ -890,7 +897,7 @@ static uint getTableStructure(char *table, char* db)
fputs(";\n", sql_file);
}
}
- if (!opt_disable_keys)
+ if (opt_disable_keys)
fprintf(sql_file,"\n/*!40000 ALTER TABLE %s DISABLE KEYS */;\n",table_name);
if (cFlag)
{
@@ -898,6 +905,8 @@ static uint getTableStructure(char *table, char* db)
if (!extended_insert)
strpos=strmov(strpos,"(");
}
+ if (sql_file != md_result_file)
+ my_fclose(sql_file, MYF(MY_WME));
DBUG_RETURN(numFields);
} /* getTableStructure */
@@ -1198,7 +1207,7 @@ static void dumpTable(uint numFields, char *table)
safe_exit(EX_CONSCHECK);
return;
}
- if (!opt_disable_keys)
+ if (opt_disable_keys)
fprintf(md_result_file,"\n/*!40000 ALTER TABLE %s ENABLE KEYS */;\n",
quote_name(table,table_buff));
if (opt_lock)
@@ -1447,19 +1456,19 @@ int main(int argc, char **argv)
if (dbConnect(current_host, current_user, opt_password))
exit(EX_MYSQLERR);
if (!path)
- write_heder(md_result_file, *argv);
-
- if (opt_first_slave)
- {
- lock_tables=0; /* No other locks needed */
- if (mysql_query(sock, "FLUSH TABLES WITH READ LOCK"))
- {
- my_printf_error(0, "Error: Couldn't execute 'FLUSH TABLES WITH READ LOCK': %s",
- MYF(0), mysql_error(sock));
- my_end(0);
- return(first_error);
- }
- }
+ write_header(md_result_file, *argv);
+
+ if (opt_first_slave)
+ {
+ lock_tables=0; /* No other locks needed */
+ if (mysql_query(sock, "FLUSH TABLES WITH READ LOCK"))
+ {
+ my_printf_error(0, "Error: Couldn't execute 'FLUSH TABLES WITH READ LOCK': %s",
+ MYF(0), mysql_error(sock));
+ my_end(0);
+ return(first_error);
+ }
+ }
if (opt_alldbs)
dump_all_databases();
/* Only one database and selected table(s) */
diff --git a/client/readline.cc b/client/readline.cc
index 38da8499eef..f5fbfd8cd0c 100644
--- a/client/readline.cc
+++ b/client/readline.cc
@@ -119,20 +119,11 @@ static bool init_line_buffer_from_string(LINE_BUFFER *buffer,my_string str)
}
-static void free_line_buffer(LINE_BUFFER *buffer)
-{
- if (buffer->buffer)
- {
- my_free((gptr) buffer->buffer,MYF(0));
- buffer->buffer=0;
- }
-}
-
-
-/* Fill the buffer retaining the last n bytes at the beginning of the
- newly filled buffer (for backward context). Returns the number of new
- bytes read from disk. */
-
+/*
+ Fill the buffer retaining the last n bytes at the beginning of the
+ newly filled buffer (for backward context). Returns the number of new
+ bytes read from disk.
+*/
static uint fill_buffer(LINE_BUFFER *buffer)
{
diff --git a/configure.in b/configure.in
index 25bdaf18f34..894b0f157e2 100644
--- a/configure.in
+++ b/configure.in
@@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script.
AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line!
-AM_INIT_AUTOMAKE(mysql, 4.0.1-alpha)
+AM_INIT_AUTOMAKE(mysql, 4.0.2-alpha)
AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10
@@ -2262,7 +2262,7 @@ AC_OUTPUT(Makefile extra/Makefile mysys/Makefile isam/Makefile \
strings/Makefile regex/Makefile heap/Makefile \
bdb/Makefile \
myisam/Makefile myisammrg/Makefile \
- man/Makefile readline/Makefile vio/Makefile \
+ man/Makefile BUILD/Makefile readline/Makefile vio/Makefile \
libmysql_r/Makefile libmysqld/Makefile libmysqld/examples/Makefile \
libmysql/Makefile client/Makefile \
pstack/Makefile pstack/aout/Makefile sql/Makefile sql/share/Makefile \
diff --git a/extra/my_print_defaults.c b/extra/my_print_defaults.c
index d8edb8cc448..70ccb3797e6 100644
--- a/extra/my_print_defaults.c
+++ b/extra/my_print_defaults.c
@@ -58,7 +58,7 @@ static void usage(my_bool version)
-?, --help Display this help message and exit.\n\
-V, --version Output version information and exit.\n",
config_file);
- printf("\nExample usage: %s --config-file=my client mysql\n",my_progname);
+ printf("\nExample usage:\n%s --config-file=my client mysql\n",my_progname);
}
static int get_options(int *argc,char ***argv)
diff --git a/include/my_global.h b/include/my_global.h
index 27781b230fd..7277bdcd715 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -216,8 +216,13 @@
#ifdef DONT_USE_FINITE /* HPUX 11.x has is_finite() */
#undef HAVE_FINITE
#endif
+#if defined(HPUX) && defined(_LARGEFILE64_SOURCE) && defined(THREAD)
+/* Fix bug in setrlimit */
+#undef setrlimit
+#define setrlimit cma_setrlimit64
+#endif
-/* We can not live without these */
+/* We can not live without the following defines */
#define USE_MYFUNC 1 /* Must use syscall indirection */
#define MASTER 1 /* Compile without unireg */
@@ -226,7 +231,7 @@
#define USE_REGEX 1 /* We want the use the regex library */
/* Do not define for ultra sparcs */
#ifndef OS2
-#define USE_BMOVE512 1 /* Use this unless the system bmove is faster */
+#define USE_BMOVE512 1 /* Use this unless system bmove is faster */
#endif
/* Paranoid settings. Define I_AM_PARANOID if you are paranoid */
@@ -611,8 +616,8 @@ typedef unsigned long ulong; /* Short for unsigned long */
#endif
#ifndef longlong_defined
#if defined(HAVE_LONG_LONG) && SIZEOF_LONG != 8
-typedef unsigned long long ulonglong; /* ulong or unsigned long long */
-typedef long long longlong;
+typedef unsigned long long int ulonglong; /* ulong or unsigned long long */
+typedef long long int longlong;
#else
typedef unsigned long ulonglong; /* ulong or unsigned long long */
typedef long longlong;
@@ -713,6 +718,20 @@ typedef char bool; /* Ordinary boolean values 0 1 */
#define MY_HOW_OFTEN_TO_ALARM 2 /* How often we want info on screen */
#define MY_HOW_OFTEN_TO_WRITE 1000 /* How often we want info on screen */
+#ifdef HAVE_TIMESPEC_TS_SEC
+#define set_timespec(ABSTIME,SEC) { (ABSTIME).ts_sec=time(0) + (time_t) (SEC); (ABSTIME).ts_nsec=0; }
+#elif defined(__WIN__)
+#define set_timespec(ABSTIME,SEC) { (ABSTIME).tv_sec=time((time_t*)0) + (time_t) (SEC); (ABSTIME).tv_nsec=0; }
+#else
+#define set_timespec(ABSTIME,SEC) \
+{\
+ struct timeval tv;\
+ gettimeofday(&tv,0);\
+ (ABSTIME).tv_sec=tv.tv_sec+(time_t) (SEC);\
+ (ABSTIME).tv_nsec=tv.tv_usec*1000;\
+}
+#endif
+
/*
** Define-funktions for reading and storing in machine independent format
** (low byte first)
diff --git a/innobase/btr/btr0sea.c b/innobase/btr/btr0sea.c
index 2e08941894c..21b4c12ab56 100644
--- a/innobase/btr/btr0sea.c
+++ b/innobase/btr/btr0sea.c
@@ -452,7 +452,7 @@ btr_search_info_update_slow(
Checks if a guessed position for a tree cursor is right. Note that if
mode is PAGE_CUR_LE, which is used in inserts, and the function returns
TRUE, then cursor->up_match and cursor->low_match both have sensible values. */
-UNIV_INLINE
+static
ibool
btr_search_check_guess(
/*===================*/
diff --git a/innobase/include/data0type.ic b/innobase/include/data0type.ic
index 4a62902eb1b..d82d976d076 100644
--- a/innobase/include/data0type.ic
+++ b/innobase/include/data0type.ic
@@ -107,14 +107,17 @@ dtype_get_pad_char(
ULINT_UNDEFINED if no padding specified */
dtype_t* type) /* in: type */
{
- if (type->mtype == DATA_CHAR) {
- /* space is the padding character for all char strings */
+ if (type->mtype == DATA_CHAR
+ || type->mtype == DATA_VARCHAR
+ || type->mtype == DATA_BINARY
+ || type->mtype == DATA_FIXBINARY) {
+
+ /* Space is the padding character for all char and binary
+ strings */
return((ulint)' ');
}
- ut_ad((type->mtype == DATA_BINARY) || (type->mtype == DATA_VARCHAR));
-
/* No padding specified */
return(ULINT_UNDEFINED);
diff --git a/innobase/include/dyn0dyn.h b/innobase/include/dyn0dyn.h
index 07ad8539b38..332622b6d4c 100644
--- a/innobase/include/dyn0dyn.h
+++ b/innobase/include/dyn0dyn.h
@@ -18,7 +18,12 @@ typedef dyn_block_t dyn_array_t;
/* Initial 'payload' size in bytes in a dynamic array block */
+#ifndef _AIX
#define DYN_ARRAY_DATA_SIZE 1024
+#else
+/* AIX has a quite small stack / thread */
+#define DYN_ARRAY_DATA_SIZE 128
+#endif
/*************************************************************************
Initializes a dynamic array. */
diff --git a/innobase/log/log0recv.c b/innobase/log/log0recv.c
index f83a49d01a6..5cd5850d1a1 100644
--- a/innobase/log/log0recv.c
+++ b/innobase/log/log0recv.c
@@ -1019,7 +1019,8 @@ loop:
if (recv_addr->state == RECV_NOT_PROCESSED) {
if (!has_printed) {
fprintf(stderr,
-"InnoDB: Starting an apply batch of log records to the database...\n");
+"InnoDB: Starting an apply batch of log records to the database...\n"
+"InnoDB: Progress in percents:");
has_printed = TRUE;
}
@@ -1046,6 +1047,16 @@ loop:
recv_addr = HASH_GET_NEXT(addr_hash, recv_addr);
}
+
+ if (has_printed
+ && (i * 100) / hash_get_n_cells(recv_sys->addr_hash)
+ != ((i + 1) * 100)
+ / hash_get_n_cells(recv_sys->addr_hash)) {
+
+ fprintf(stderr, "%lu ",
+ (i * 100) / hash_get_n_cells(recv_sys->addr_hash));
+
+ }
}
/* Wait until all the pages have been processed */
@@ -1059,6 +1070,11 @@ loop:
mutex_enter(&(recv_sys->mutex));
}
+ if (has_printed) {
+
+ fprintf(stderr, "\n");
+ }
+
if (!allow_ibuf) {
/* Flush all the file pages to disk and invalidate them in
the buffer pool */
diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c
index a7cd31af2ee..ac29b292f6a 100644
--- a/innobase/os/os0file.c
+++ b/innobase/os/os0file.c
@@ -581,6 +581,13 @@ os_file_flush(
return(TRUE);
}
+ /* Since Linux returns EINVAL if the 'file' is actually a raw device,
+ we choose to ignore that error */
+
+ if (errno == EINVAL) {
+ return(TRUE);
+ }
+
fprintf(stderr,
"InnoDB: Error: the OS said file flush did not succeed\n");
diff --git a/innobase/rem/rem0cmp.c b/innobase/rem/rem0cmp.c
index 1f2987f0182..47b7021bf27 100644
--- a/innobase/rem/rem0cmp.c
+++ b/innobase/rem/rem0cmp.c
@@ -100,7 +100,15 @@ cmp_types_are_equal(
dtype_t* type1, /* in: type 1 */
dtype_t* type2) /* in: type 2 */
{
- if (type1->mtype != type2->mtype) {
+ if ((type1->mtype == DATA_VARCHAR && type2->mtype == DATA_CHAR)
+ || (type1->mtype == DATA_CHAR && type2->mtype == DATA_VARCHAR)
+ || (type1->mtype == DATA_FIXBINARY && type2->mtype == DATA_BINARY)
+ || (type1->mtype == DATA_BINARY && type2->mtype == DATA_FIXBINARY)) {
+
+ return(TRUE);
+ }
+
+ if (type1->mtype != type2->mtype) {
return(FALSE);
}
diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c
index db2dcb0125f..50ec88c595d 100644
--- a/innobase/row/row0mysql.c
+++ b/innobase/row/row0mysql.c
@@ -1683,6 +1683,8 @@ row_scan_and_check_index(
rec_t* rec;
ibool is_ok = TRUE;
int cmp;
+ ibool contains_null;
+ ulint i;
char err_buf[1000];
*n_rows = 0;
@@ -1728,6 +1730,21 @@ loop:
cmp = cmp_dtuple_rec_with_match(prev_entry, rec,
&matched_fields,
&matched_bytes);
+ contains_null = FALSE;
+
+ /* In a unique secondary index we allow equal key values if
+ they contain SQL NULLs */
+
+ for (i = 0;
+ i < dict_index_get_n_ordering_defined_by_user(index);
+ i++) {
+ if (UNIV_SQL_NULL == dfield_get_len(
+ dtuple_get_nth_field(prev_entry, i))) {
+
+ contains_null = TRUE;
+ }
+ }
+
if (cmp > 0) {
fprintf(stderr,
"Error: index records in a wrong order in index %s\n",
@@ -1741,6 +1758,7 @@ loop:
is_ok = FALSE;
} else if ((index->type & DICT_UNIQUE)
+ && !contains_null
&& matched_fields >=
dict_index_get_n_ordering_defined_by_user(index)) {
diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c
index 424bb8a7086..3f8763f91d6 100644
--- a/innobase/srv/srv0srv.c
+++ b/innobase/srv/srv0srv.c
@@ -2427,7 +2427,19 @@ loop:
background_loop:
/* In this loop we run background operations when the server
- is quiet */
+ is quiet and we also come here about once in 10 seconds */
+
+ srv_main_thread_op_info = "flushing buffer pool pages";
+
+ /* Flush a few oldest pages to make the checkpoint younger */
+
+ n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 10, ut_dulint_max);
+
+ srv_main_thread_op_info = "making checkpoint";
+
+ /* Make a new checkpoint about once in 10 seconds */
+
+ log_checkpoint(TRUE, FALSE);
srv_main_thread_op_info = (char *) "reserving kernel mutex";
diff --git a/libmysql/Makefile.shared b/libmysql/Makefile.shared
index 934051bb2bf..0d3aa79b9ce 100644
--- a/libmysql/Makefile.shared
+++ b/libmysql/Makefile.shared
@@ -34,7 +34,8 @@ LTCHARSET_OBJS= ${CHARSET_OBJS:.o=.lo}
target_sources = libmysql.c net.c password.c manager.c \
get_password.c errmsg.c
-mystringsobjects = strmov.lo strxmov.lo strnmov.lo strmake.lo strend.lo \
+mystringsobjects = strmov.lo strxmov.lo strxnmov.lo strnmov.lo \
+ strmake.lo strend.lo \
strnlen.lo strfill.lo is_prefix.lo \
int2str.lo str2int.lo strinstr.lo strcont.lo \
strcend.lo bcmp.lo \
diff --git a/libmysqld/examples/Makefile.am b/libmysqld/examples/Makefile.am
index d1cf24caf48..d9f9f05ae97 100644
--- a/libmysqld/examples/Makefile.am
+++ b/libmysqld/examples/Makefile.am
@@ -11,7 +11,7 @@ DEFS = -DEMBEDDED_LIBRARY
INCLUDES = -I$(top_srcdir)/include $(openssl_includes) \
-I$(srcdir) -I$(top_srcdir) -I$(top_srcdir)/client
LIBS = @LIBS@
-LDADD = ../libmysqld.a @innodb_system_libs@ @LIBDL@
+LDADD = ../libmysqld.a @innodb_system_libs@ @LIBDL@ $(CXXLDFLAGS)
mysqltest_SOURCES = mysqltest.c
diff --git a/libmysqld/lib_vio.c b/libmysqld/lib_vio.c
index a6723f8322e..9bf492ed5ea 100644
--- a/libmysqld/lib_vio.c
+++ b/libmysqld/lib_vio.c
@@ -146,27 +146,23 @@ int vio_write(Vio * vio, const gptr buf, int size)
int vio_blocking(Vio * vio, my_bool set_blocking_mode)
{
- int r=0;
- return (r);
+ return (0);
}
my_bool
vio_is_blocking(Vio * vio)
{
- my_bool r=0;
- return(r);
+ return(0);
}
int vio_fastsend(Vio * vio)
{
- int r=0;
- return(r);
+ return(0);
}
int vio_keepalive(Vio* vio, my_bool set_keep_alive)
{
- int r=0;
- return (r);
+ return (0);
}
@@ -181,8 +177,7 @@ vio_should_retry(Vio * vio __attribute__((unused)))
int vio_close(Vio * vio)
{
- int r=0;
- return(r);
+ return(0);
}
diff --git a/myisam/ft_dump.c b/myisam/ft_dump.c
index f8e0fab8357..a693878acd9 100644
--- a/myisam/ft_dump.c
+++ b/myisam/ft_dump.c
@@ -27,7 +27,7 @@ static int count=0, stats=0, dump=0, verbose=0, lstats=0;
static char *query=NULL;
static uint lengths[256];
-#define MAX (HA_FT_MAXLEN+10)
+#define MAX_LEN (HA_FT_MAXLEN+10)
#define HOW_OFTEN_TO_WRITE 10000
int main(int argc,char *argv[])
@@ -37,7 +37,7 @@ int main(int argc,char *argv[])
float weight;
double gws, min_gws=0, avg_gws=0;
MI_INFO *info;
- char buf[MAX], buf2[MAX], buf_maxlen[MAX], buf_min_gws[MAX];
+ char buf[MAX_LEN], buf2[MAX_LEN], buf_maxlen[MAX_LEN], buf_min_gws[MAX_LEN];
ulong total=0, maxlen=0, uniq=0, max_doc_cnt=0;
struct { MI_INFO *info; } aio0, *aio=&aio0; /* for GWS_IN_USE */
@@ -105,7 +105,7 @@ int main(int argc,char *argv[])
#error
#endif
- snprintf(buf,MAX,"%.*s",(int) keylen,info->lastkey+1);
+ snprintf(buf,MAX_LEN,"%.*s",(int) keylen,info->lastkey+1);
casedn_str(buf);
total++;
lengths[keylen]++;
diff --git a/myisam/ftdefs.h b/myisam/ftdefs.h
index f8b50cb45b9..1a3c0ef60dc 100644
--- a/myisam/ftdefs.h
+++ b/myisam/ftdefs.h
@@ -135,7 +135,7 @@ FT_WORD * ft_linearize(/*MI_INFO *, uint, byte *, */TREE *);
FT_WORD * _mi_ft_parserecord(MI_INFO *, uint, byte *, const byte *);
uint _mi_ft_parse(TREE *parsed, MI_INFO *info, uint keynr, const byte *record);
-const struct _ft_vft _ft_vft_nlq;
+extern const struct _ft_vft _ft_vft_nlq;
FT_INFO *ft_init_nlq_search(MI_INFO *, uint, byte *, uint, my_bool);
int ft_nlq_read_next(FT_INFO *, char *);
float ft_nlq_find_relevance(FT_INFO *, byte *, uint);
@@ -144,7 +144,7 @@ float ft_nlq_get_relevance(FT_INFO *);
my_off_t ft_nlq_get_docid(FT_INFO *);
void ft_nlq_reinit_search(FT_INFO *);
-const struct _ft_vft _ft_vft_boolean;
+extern const struct _ft_vft _ft_vft_boolean;
FT_INFO *ft_init_boolean_search(MI_INFO *, uint, byte *, uint, my_bool);
int ft_boolean_read_next(FT_INFO *, char *);
float ft_boolean_find_relevance(FT_INFO *, byte *, uint);
diff --git a/mysql-test/r/bdb.result b/mysql-test/r/bdb.result
index a7ddff5c532..e553105fcc7 100644
--- a/mysql-test/r/bdb.result
+++ b/mysql-test/r/bdb.result
@@ -167,10 +167,10 @@ optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
show keys from t1;
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 id A 39 NULL NULL
-t1 1 parent_id 1 parent_id A 9 NULL NULL
-t1 1 level 1 level A 3 NULL NULL
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 id A 39 NULL NULL BTREE
+t1 1 parent_id 1 parent_id A 9 NULL NULL BTREE
+t1 1 level 1 level A 3 NULL NULL BTREE
drop table t1;
CREATE TABLE t1 (
gesuchnr int(11) DEFAULT '0' NOT NULL,
@@ -217,8 +217,8 @@ 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 Comment
-t1 1 skr 1 a A 3 NULL NULL
+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
drop table t1;
create table t1 (a int,b varchar(20),key(a)) type=bdb;
insert into t1 values (1,""), (2,"testing");
@@ -381,13 +381,13 @@ drop table t1;
CREATE TABLE t1 (a int not null, b int not null,c int not null,
key(a),primary key(a,b), unique(c),key(a),unique(b));
show index from t1;
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 a A NULL NULL NULL
-t1 0 PRIMARY 2 b A 0 NULL NULL
-t1 0 b 1 b A 0 NULL NULL
-t1 0 c 1 c A 0 NULL NULL
-t1 1 a 1 a A NULL NULL NULL
-t1 1 a_2 1 a A NULL NULL NULL
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 a A NULL NULL NULL BTREE
+t1 0 PRIMARY 2 b A 0 NULL NULL BTREE
+t1 0 c 1 c A 0 NULL NULL BTREE
+t1 0 b 1 b A 0 NULL NULL BTREE
+t1 1 a 1 a A NULL NULL NULL BTREE
+t1 1 a_2 1 a A NULL NULL NULL BTREE
drop table t1;
create table t1 (col1 int not null, col2 char(4) not null, primary key(col1));
alter table t1 type=BDB;
@@ -784,8 +784,8 @@ optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
show keys from t1;
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 a A 2 NULL NULL
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 a A 2 NULL NULL BTREE
drop table t1;
create table t1 (i int, j int )TYPE=BDB;
insert into t1 values (1,2);
diff --git a/mysql-test/r/bigint.result b/mysql-test/r/bigint.result
index 1c4a94ef1ee..1618f3f27a2 100644
--- a/mysql-test/r/bigint.result
+++ b/mysql-test/r/bigint.result
@@ -55,3 +55,12 @@ select min(big),max(big),max(big)-1 from t1 group by a;
min(big) max(big) max(big)-1
-1 9223372036854775807 9223372036854775806
drop table t1;
+select UNSIGNED 1-2;
+UNSIGNED 1-2
+18446744073709551615
+select SIGNED (UNSIGNED 1-2);
+SIGNED (UNSIGNED 1-2)
+-1
+select UNSIGNED '-1';
+UNSIGNED '-1'
+18446744073709551615
diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result
index d3038acdc5c..6660a788646 100644
--- a/mysql-test/r/fulltext.result
+++ b/mysql-test/r/fulltext.result
@@ -101,9 +101,9 @@ match(ttxt.inhalt) against ('foobar');
id
3
show keys from t2;
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t2 1 tig 1 ticket A NULL NULL NULL
-t2 1 tix 1 inhalt A NULL 1 NULL FULLTEXT
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t2 1 tig 1 ticket A NULL NULL NULL YES BTREE
+t2 1 tix 1 inhalt A NULL 1 NULL YES FULLTEXT
show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
diff --git a/mysql-test/r/heap.result b/mysql-test/r/heap.result
index 3acd0d14118..5495997324a 100644
--- a/mysql-test/r/heap.result
+++ b/mysql-test/r/heap.result
@@ -3,8 +3,8 @@ create table t1 (a int not null,b int not null, primary key (a)) type=heap comme
insert into t1 values(1,1),(2,2),(3,3),(4,4);
delete from t1 where a=1 or a=0;
show keys from t1;
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 a NULL NULL NULL NULL
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 a NULL NULL NULL NULL HASH
select * from t1;
a b
2 2
diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
index 8664cab0b84..1a48b6d6294 100644
--- a/mysql-test/r/innodb.result
+++ b/mysql-test/r/innodb.result
@@ -167,10 +167,10 @@ optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize error The handler for the table doesn't support check/repair
show keys from t1;
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 id A 87 NULL NULL
-t1 1 parent_id 1 parent_id A 21 NULL NULL
-t1 1 level 1 level A 4 NULL NULL
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 id A 87 NULL NULL BTREE
+t1 1 parent_id 1 parent_id A 21 NULL NULL BTREE
+t1 1 level 1 level A 4 NULL NULL BTREE
drop table t1;
CREATE TABLE t1 (
gesuchnr int(11) DEFAULT '0' NOT NULL,
@@ -210,8 +210,8 @@ analyze table t1;
Table Op Msg_type Msg_text
test.t1 analyze error The handler for the table doesn't support check/repair
show keys from t1;
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 1 skr 1 a A 1 NULL NULL
+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 1 NULL NULL YES BTREE
drop table t1;
create table t1 (a int,b varchar(20),key(a)) type=innodb;
insert into t1 values (1,""), (2,"testing");
@@ -353,13 +353,13 @@ drop table t1;
CREATE TABLE t1 (a int not null, b int not null,c int not null,
key(a),primary key(a,b), unique(c),key(a),unique(b));
show index from t1;
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 a A NULL NULL NULL
-t1 0 PRIMARY 2 b A 0 NULL NULL
-t1 0 b 1 b A 0 NULL NULL
-t1 0 c 1 c A 0 NULL NULL
-t1 1 a 1 a A NULL NULL NULL
-t1 1 a_2 1 a A NULL NULL NULL
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 a A NULL NULL NULL BTREE
+t1 0 PRIMARY 2 b A 0 NULL NULL BTREE
+t1 0 c 1 c A 0 NULL NULL BTREE
+t1 0 b 1 b A 0 NULL NULL BTREE
+t1 1 a 1 a A NULL NULL NULL BTREE
+t1 1 a_2 1 a A NULL NULL NULL BTREE
drop table t1;
create table t1 (col1 int not null, col2 char(4) not null, primary key(col1));
alter table t1 type=innodb;
@@ -726,8 +726,8 @@ optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize error The handler for the table doesn't support check/repair
show keys from t1;
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 a A 1 NULL NULL
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 a A 1 NULL NULL BTREE
drop table t1;
create table t1 (i int, j int ) TYPE=innodb;
insert into t1 values (1,2);
diff --git a/mysql-test/r/isam.result b/mysql-test/r/isam.result
index baeda5537e5..d19352aad42 100644
--- a/mysql-test/r/isam.result
+++ b/mysql-test/r/isam.result
@@ -72,8 +72,8 @@ a int(11) PRI 0 select,insert,update,references
b int(11) MUL 0 select,insert,update,references
c int(11) 0 select,insert,update,references
show index from t1;
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 a A 4 NULL NULL
-t1 1 b 1 b A 1 NULL NULL
-t1 1 b 2 c A 4 NULL NULL
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 a A 4 NULL NULL BTREE
+t1 1 b 1 b A 1 NULL NULL BTREE
+t1 1 b 2 c A 4 NULL NULL BTREE
drop table t1,t2;
diff --git a/mysql-test/r/key.result b/mysql-test/r/key.result
index 0c73fc086c5..6dfe0809e7f 100644
--- a/mysql-test/r/key.result
+++ b/mysql-test/r/key.result
@@ -138,3 +138,12 @@ a b
a 1
a 2
drop table t1;
+create table t1 (a int not null unique, b int unique, c int, d int not null primary key, key(c), e int not null unique);
+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 PRIMARY 1 d A 0 NULL NULL BTREE
+t1 0 a 1 a A 0 NULL NULL BTREE
+t1 0 e 1 e A 0 NULL NULL BTREE
+t1 0 b 1 b A NULL NULL NULL YES BTREE
+t1 1 c 1 c A NULL NULL NULL YES BTREE
+drop table t1;
diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result
index efcc610cbd4..c5c69c1ba7b 100644
--- a/mysql-test/r/myisam.result
+++ b/mysql-test/r/myisam.result
@@ -37,16 +37,16 @@ optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
show index from t1;
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 a A 5 NULL NULL
-t1 1 b 1 b A 1 NULL NULL
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 a A 5 NULL NULL BTREE
+t1 1 b 1 b A 1 NULL NULL BTREE
optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize status Table is already up to date
show index from t1;
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 a A 5 NULL NULL
-t1 1 b 1 b A 1 NULL NULL
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 a A 5 NULL NULL BTREE
+t1 1 b 1 b A 1 NULL NULL BTREE
drop table t1;
create table t1 (a int not null, b int not null, c int not null, primary key (a),key(b)) type=myisam;
insert into t1 values (3,3,3),(1,1,1),(2,2,2),(4,4,4);
diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result
index fa130deec19..632f64e25de 100644
--- a/mysql-test/r/query_cache.result
+++ b/mysql-test/r/query_cache.result
@@ -406,6 +406,59 @@ Variable_name Value
Qcache_hits 6
drop database mysqltest;
drop table t1;
+create table t1 (i int not null);
+insert into t1 (i) values (1),(2),(3),(4);
+select SQL_CALC_FOUND_ROWS * from t1 limit 2;
+i
+1
+2
+select FOUND_ROWS();
+FOUND_ROWS()
+4
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 6
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
+select * from t1 where i=1;
+i
+1
+select FOUND_ROWS();
+FOUND_ROWS()
+1
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 6
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 2
+select SQL_CALC_FOUND_ROWS * from t1 limit 2;
+i
+1
+2
+select FOUND_ROWS();
+FOUND_ROWS()
+4
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 7
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 2
+select * from t1 where i=1;
+i
+1
+select FOUND_ROWS();
+FOUND_ROWS()
+1
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 8
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 2
+drop table t1;
flush query cache;
reset query cache;
create table t1 (a int not null);
diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result
index 702d4a6de03..ee057b268fd 100644
--- a/mysql-test/r/select.result
+++ b/mysql-test/r/select.result
@@ -3225,10 +3225,10 @@ fld6 char(4) select,insert,update,references
show full columns from t2 from test like 's%';
Field Type Null Key Default Extra Privileges
show keys from t2;
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t2 0 PRIMARY 1 auto A 1199 NULL NULL
-t2 0 fld1 1 fld1 A 1199 NULL NULL
-t2 1 fld3 1 fld3 A NULL NULL NULL
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t2 0 PRIMARY 1 auto A 1199 NULL NULL BTREE
+t2 0 fld1 1 fld1 A 1199 NULL NULL BTREE
+t2 1 fld3 1 fld3 A NULL NULL NULL BTREE
DO 1;
DO benchmark(100,1+1),1,1;
drop table t4, t3,t2, t1;
diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result
index f66bf22b224..2530e5b09fb 100644
--- a/mysql-test/r/show_check.result
+++ b/mysql-test/r/show_check.result
@@ -21,10 +21,10 @@ check table t1 type=extended;
Table Op Msg_type Msg_text
test.t1 check status OK
show index from t1;
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 a A 5 NULL NULL
-t1 1 b 1 b A 1 NULL NULL
-t1 1 b 2 c A 5 NULL NULL
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 a A 5 NULL NULL BTREE
+t1 1 b 1 b A 1 NULL NULL BTREE
+t1 1 b 2 c A 5 NULL NULL BTREE
insert into t1 values (5,5,5);
Duplicate entry '5' for key 1
optimize table t1;
@@ -54,20 +54,20 @@ analyze table t1;
Table Op Msg_type Msg_text
test.t1 analyze status OK
show index from t1;
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 f1 A 1 NULL NULL
-t1 0 PRIMARY 2 f2 A 3 NULL NULL
-t1 0 PRIMARY 3 f3 A 9 NULL NULL
-t1 0 PRIMARY 4 f4 A 18 NULL NULL
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 f1 A 1 NULL NULL BTREE
+t1 0 PRIMARY 2 f2 A 3 NULL NULL BTREE
+t1 0 PRIMARY 3 f3 A 9 NULL NULL BTREE
+t1 0 PRIMARY 4 f4 A 18 NULL NULL BTREE
repair table t1;
Table Op Msg_type Msg_text
test.t1 repair status OK
show index from t1;
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 f1 A 1 NULL NULL
-t1 0 PRIMARY 2 f2 A 3 NULL NULL
-t1 0 PRIMARY 3 f3 A 9 NULL NULL
-t1 0 PRIMARY 4 f4 A 18 NULL NULL
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 f1 A 1 NULL NULL BTREE
+t1 0 PRIMARY 2 f2 A 3 NULL NULL BTREE
+t1 0 PRIMARY 3 f3 A 9 NULL NULL BTREE
+t1 0 PRIMARY 4 f4 A 18 NULL NULL BTREE
drop table t1;
create temporary table t1 (a int not null);
show create table t1;
diff --git a/mysql-test/r/type_ranges.result b/mysql-test/r/type_ranges.result
index 22b4292fa39..fc7cc5255cf 100644
--- a/mysql-test/r/type_ranges.result
+++ b/mysql-test/r/type_ranges.result
@@ -64,21 +64,21 @@ longblob_col longblob select,insert,update,references
options enum('one','two','tree') MUL one select,insert,update,references
flags set('one','two','tree') select,insert,update,references
show keys from t1;
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 auto A 0 NULL NULL
-t1 1 utiny 1 utiny A NULL NULL NULL
-t1 1 tiny 1 tiny A NULL NULL NULL
-t1 1 short 1 short A NULL NULL NULL
-t1 1 any_name 1 medium A NULL NULL NULL
-t1 1 longlong 1 longlong A NULL NULL NULL
-t1 1 real_float 1 real_float A NULL NULL NULL
-t1 1 ushort 1 ushort A NULL NULL NULL
-t1 1 umedium 1 umedium A NULL NULL NULL
-t1 1 ulong 1 ulong A NULL NULL NULL
-t1 1 ulonglong 1 ulonglong A NULL NULL NULL
-t1 1 ulonglong 2 ulong A NULL NULL NULL
-t1 1 options 1 options A NULL NULL NULL
-t1 1 options 2 flags A NULL NULL NULL
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 auto A 0 NULL NULL BTREE
+t1 1 utiny 1 utiny A NULL NULL NULL BTREE
+t1 1 tiny 1 tiny A NULL NULL NULL BTREE
+t1 1 short 1 short A NULL NULL NULL BTREE
+t1 1 any_name 1 medium A NULL NULL NULL BTREE
+t1 1 longlong 1 longlong A NULL NULL NULL BTREE
+t1 1 real_float 1 real_float A NULL NULL NULL BTREE
+t1 1 ushort 1 ushort A NULL NULL NULL BTREE
+t1 1 umedium 1 umedium A NULL NULL NULL BTREE
+t1 1 ulong 1 ulong A NULL NULL NULL BTREE
+t1 1 ulonglong 1 ulonglong A NULL NULL NULL BTREE
+t1 1 ulonglong 2 ulong A NULL NULL NULL BTREE
+t1 1 options 1 options A NULL NULL NULL BTREE
+t1 1 options 2 flags A NULL NULL NULL BTREE
CREATE UNIQUE INDEX test on t1 ( auto ) ;
CREATE INDEX test2 on t1 ( ulonglong,ulong) ;
CREATE INDEX test3 on t1 ( medium ) ;
diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result
index ca67bdeb857..52189c36831 100644
--- a/mysql-test/r/variables.result
+++ b/mysql-test/r/variables.result
@@ -24,3 +24,14 @@ select @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3;
select @t5;
@t5
1.23456
+@min_cid:=min(c_id) @max_cid:=max(c_id)
+1 4
+c_id c_name c_country
+1 Bozo USA
+4 Mr. Floppy GB
+c_id c_name c_country
+1 Bozo USA
+4 Mr. Floppy GB
+c_id c_name c_country
+1 Bozo USA
+4 Mr. Floppy GB
diff --git a/mysql-test/t/bigint.test b/mysql-test/t/bigint.test
index 52ae9ad35db..27ac346825b 100644
--- a/mysql-test/t/bigint.test
+++ b/mysql-test/t/bigint.test
@@ -29,3 +29,7 @@ alter table t1 modify big bigint not null;
select min(big),max(big),max(big)-1 from t1;
select min(big),max(big),max(big)-1 from t1 group by a;
drop table t1;
+
+select UNSIGNED 1-2;
+select SIGNED (UNSIGNED 1-2);
+select UNSIGNED '-1';
diff --git a/mysql-test/t/key.test b/mysql-test/t/key.test
index a8417fad876..6fc975a1cb3 100644
--- a/mysql-test/t/key.test
+++ b/mysql-test/t/key.test
@@ -160,3 +160,11 @@ SELECT * FROM t1 WHERE a='a' AND b=2;
SELECT * FROM t1 WHERE a='a' AND b in (2);
SELECT * FROM t1 WHERE a='a' AND b in (1,2);
drop table t1;
+
+#
+# Test of create key order
+#
+
+create table t1 (a int not null unique, b int unique, c int, d int not null primary key, key(c), e int not null unique);
+show keys from t1;
+drop table t1;
diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test
index 8a577d0be05..280f2202af1 100644
--- a/mysql-test/t/query_cache.test
+++ b/mysql-test/t/query_cache.test
@@ -288,6 +288,34 @@ drop database mysqltest;
drop table t1;
#
+# FOUND_ROWS()
+#
+
+create table t1 (i int not null);
+insert into t1 (i) values (1),(2),(3),(4);
+
+select SQL_CALC_FOUND_ROWS * from t1 limit 2;
+select FOUND_ROWS();
+show status like "Qcache_hits";
+show status like "Qcache_queries_in_cache";
+
+select * from t1 where i=1;
+select FOUND_ROWS();
+show status like "Qcache_hits";
+show status like "Qcache_queries_in_cache";
+
+select SQL_CALC_FOUND_ROWS * from t1 limit 2;
+select FOUND_ROWS();
+show status like "Qcache_hits";
+show status like "Qcache_queries_in_cache";
+
+select * from t1 where i=1;
+select FOUND_ROWS();
+show status like "Qcache_hits";
+show status like "Qcache_queries_in_cache";
+drop table t1;
+
+#
# Test insert delayed
#
diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test
index d5ff64d199b..0499263467c 100644
--- a/mysql-test/t/variables.test
+++ b/mysql-test/t/variables.test
@@ -1,6 +1,7 @@
#
# test variables
#
+drop table if exists t1;
set @`test`=1,@TEST=3,@select=2,@t5=1.23456;
select @test,@`select`,@TEST,@not_used;
set @test_int=10,@test_double=1e-10,@test_string="abcdeghi",@test_string2="abcdefghij",@select=NULL;
@@ -14,3 +15,15 @@ select @test_int,@test_double,@test_string,@test_string2;
select @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3;
select @t5;
+#
+# Test problem with WHERE and variables
+#
+
+CREATE TABLE t1 (c_id INT(4) NOT NULL, c_name CHAR(20), c_country CHAR(3), PRIMARY KEY(c_id));
+INSERT INTO t1 VALUES (1,'Bozo','USA'),(2,'Ronald','USA'),(3,'Kinko','IRE'),(4,'Mr. Floppy','GB');
+SELECT @min_cid:=min(c_id), @max_cid:=max(c_id) from t1;
+SELECT * FROM t1 WHERE c_id=@min_cid OR c_id=@max_cid;
+SELECT * FROM t1 WHERE c_id=@min_cid OR c_id=@max_cid OR c_id=666;
+ALTER TABLE t1 DROP PRIMARY KEY;
+select * from t1 where c_id=@min_cid OR c_id=@max_cid;
+drop table t1;
diff --git a/sql-bench/crash-me.sh b/sql-bench/crash-me.sh
index 434599a1ac4..9572143ae53 100644
--- a/sql-bench/crash-me.sh
+++ b/sql-bench/crash-me.sh
@@ -143,7 +143,15 @@ $longreadlen=16000000; # For retrieval buffer
#
use sigtrap; # Must be removed with perl5.005_2 on Win98
$SIG{PIPE} = 'IGNORE';
-$SIG{SEGV} = sub {warn('SEGFAULT')};
+$problem_counter=0;
+$SIG{SEGV} = sub {
+ $problem_counter +=1;
+ if ($problem_counter >= 100) {
+ die("Too many problems, try to restart");
+ } else {
+ warn('SEGFAULT');
+ };
+};
$dbh=safe_connect();
#
@@ -252,6 +260,8 @@ report("Functions",'functions',"select 1+1 $end_query");
report("Group functions",'group_functions',"select count(*) from crash_me");
report("Group functions with distinct",'group_distinct_functions',
"select count(distinct a) from crash_me");
+report("Group functions with several distinct",'group_many_distinct_functions',
+ "select count(distinct a), count(distinct b) from crash_me");
report("Group by",'group_by',"select a from crash_me group by a");
report("Group by position",'group_by_position',
"select a from crash_me group by 1");
@@ -1438,6 +1448,14 @@ if (!report("case independent table names","table_name_case",
safe_query("drop table crash_q $drop_attr");
}
+if (!report("case independent field names","field_name_case",
+ "create table crash_q (q integer)",
+ "insert into crash_q(Q) values (1)",
+ "drop table crash_q $drop_attr"))
+{
+ safe_query("drop table crash_q $drop_attr");
+}
+
if (!report("drop table if exists","drop_if_exists",
"create table crash_q (q integer)",
"drop table if exists crash_q $drop_attr"))
@@ -2450,6 +2468,7 @@ sub report
print "$prompt: ";
if (!defined($limits{$limit}))
{
+ save_config_data($limit,"incompleted",$prompt);
save_config_data($limit,safe_query(\@queries) ? "yes" : "no",$prompt);
}
print "$limits{$limit}\n";
@@ -2462,6 +2481,7 @@ sub report_fail
print "$prompt: ";
if (!defined($limits{$limit}))
{
+ save_config_data($limit,"incompleted",$prompt);
save_config_data($limit,safe_query(\@queries) ? "no" : "yes",$prompt);
}
print "$limits{$limit}\n";
@@ -2478,6 +2498,7 @@ sub report_one
print "$prompt: ";
if (!defined($limits{$limit}))
{
+ save_config_data($limit,"incompleted",$prompt);
$result="no";
foreach $query (@$queries)
{
@@ -2503,6 +2524,7 @@ sub report_result
print "$prompt: ";
if (!defined($limits{$limit}))
{
+ save_config_data($limit,"incompleted",$prompt);
$error=safe_query_result($query,"1",2);
save_config_data($limit,$error ? "not supported" : $last_result,$prompt);
}
@@ -2515,6 +2537,7 @@ sub report_trans
my ($limit,$queries,$check,$clear)=@_;
if (!defined($limits{$limit}))
{
+ save_config_data($limit,"incompleted",$prompt);
eval {undef($dbh->{AutoCommit})};
if (!$@)
{
@@ -2556,9 +2579,11 @@ sub check_and_report
print "$prompt: " if (!defined($skip_prompt));
if (!defined($limits{$limit}))
{
+ save_config_data($limit,"incompleted",$prompt);
$tmp=1-safe_query(\@$pre);
$tmp=safe_query_result($query,$answer,$string_type) if (!$tmp);
safe_query(\@$post);
+ delete $limits{$limit};
if ($function == 3) # Report error as 'no'.
{
$function=0;
@@ -2587,8 +2612,10 @@ sub try_and_report
my ($tmp,$test,$type);
print "$prompt: ";
+
if (!defined($limits{$limit}))
{
+ save_config_data($limit,"incompleted",$prompt);
$type="no"; # Not supported
foreach $test (@tests)
{
@@ -2699,7 +2726,7 @@ sub safe_query_result
elsif ($result_type == 5) # Result should have given prefix
{
$result= -1 if (length($row->[0]) < length($answer) &&
- substring($row->[0],1,length($answer)) ne $answer);
+ substr($row->[0],1,length($answer)) ne $answer);
}
elsif ($result_type == 6) # Exact match but ignore errors
{
@@ -2760,6 +2787,8 @@ sub find_limit()
print "$end (cache)\n";
return $end;
}
+ save_config_data($limit,"incompleted",$prompt);
+
if (defined($query->{'init'}) && !defined($end=$limits{'restart'}{'tohigh'}))
{
if (!safe_query($query->{'init'}))
diff --git a/sql/derror.cc b/sql/derror.cc
index d0519c37dca..7ebe6e4b3c5 100644
--- a/sql/derror.cc
+++ b/sql/derror.cc
@@ -44,7 +44,7 @@ static void read_texts(const char *file_name,const char ***point,
uint error_messages)
{
register uint i;
- uint ant,funktpos,length,textant;
+ uint count,funktpos,length,textcount;
File file;
char name[FN_REFLEN];
const char *buff;
@@ -64,36 +64,38 @@ static void read_texts(const char *file_name,const char ***point,
if (head[0] != (uchar) 254 || head[1] != (uchar) 254 ||
head[2] != 2 || head[3] != 1)
goto err; /* purecov: inspected */
- textant=head[4];
- length=uint2korr(head+6); ant=uint2korr(head+8);
+ textcount=head[4];
+ length=uint2korr(head+6); count=uint2korr(head+8);
- if (ant < error_messages)
+ if (count < error_messages)
{
- fprintf(stderr,"\n%s: Fatal error: Error message file '%s' had only %d error messages, but it should have at least %d error messages.\n\
-Check that the above file is the right version for this program!\n\n",
- my_progname,name,ant,error_messages);
+ sql_print_error("\
+Error message file '%s' had only %d error messages,\n\
+but it should contain at least %d error messages.\n\
+Check that the above file is the right version for this program!",
+ name,count,error_messages);
VOID(my_close(file,MYF(MY_WME)));
unireg_abort(1);
}
x_free((gptr) *point); /* Free old language */
if (!(*point= (const char**)
- my_malloc((uint) (length+ant*sizeof(char*)),MYF(0))))
+ my_malloc((uint) (length+count*sizeof(char*)),MYF(0))))
{
funktpos=2; /* purecov: inspected */
goto err; /* purecov: inspected */
}
- buff= (char*) (*point + ant);
+ buff= (char*) (*point + count);
- if (my_read(file,(byte*) buff,(uint) ant*2,MYF(MY_NABP))) goto err;
- for (i=0, pos= (uchar*) buff ; i< ant ; i++)
+ if (my_read(file,(byte*) buff,(uint) count*2,MYF(MY_NABP))) goto err;
+ for (i=0, pos= (uchar*) buff ; i< count ; i++)
{
(*point)[i]=buff+uint2korr(pos);
pos+=2;
}
if (my_read(file,(byte*) buff,(uint) length,MYF(MY_NABP))) goto err;
- for (i=1 ; i < textant ; i++)
+ for (i=1 ; i < textcount ; i++)
{
point[i]= *point +uint2korr(head+10+i+i);
}
@@ -103,18 +105,18 @@ Check that the above file is the right version for this program!\n\n",
err:
switch (funktpos) {
case 2:
- buff="\n%s: Fatal error: Not enough memory for messagefile '%s'\n\n";
+ buff="Not enough memory for messagefile '%s'";
break;
case 1:
- buff="\n%s: Fatal error: Can't read from messagefile '%s'\n\n";
+ buff="Can't read from messagefile '%s'";
break;
default:
- buff="\n%s: Fatal error: Can't find messagefile '%s'\n\n";
+ buff="Can't find messagefile '%s'";
break;
}
if (file != FERR)
VOID(my_close(file,MYF(MY_WME)));
- fprintf(stderr,buff,my_progname,name);
+ sql_print_error(buff,name);
unireg_abort(1);
} /* read_texts */
diff --git a/sql/ha_berkeley.h b/sql/ha_berkeley.h
index 65116f908ac..fbc858b5996 100644
--- a/sql/ha_berkeley.h
+++ b/sql/ha_berkeley.h
@@ -98,6 +98,7 @@ class ha_berkeley: public handler
}
~ha_berkeley() {}
const char *table_type() const { return "BerkeleyDB"; }
+ const char *index_type(uint key_number) { return "BTREE"; }
const char **bas_ext() const;
ulong option_flag() const { return int_option_flag; }
uint max_record_length() const { return HA_MAX_REC_LENGTH; }
diff --git a/sql/ha_heap.h b/sql/ha_heap.h
index 9b041411012..fa077cef60a 100644
--- a/sql/ha_heap.h
+++ b/sql/ha_heap.h
@@ -31,6 +31,7 @@ class ha_heap: public handler
ha_heap(TABLE *table): handler(table), file(0) {}
~ha_heap() {}
const char *table_type() const { return "HEAP"; }
+ const char *index_type(uint key_number) { return "HASH"; }
const char **bas_ext() const;
ulong option_flag() const
{ return (HA_READ_RND_SAME | HA_NO_INDEX | HA_ONLY_WHOLE_INDEX |
diff --git a/sql/ha_innobase.cc b/sql/ha_innobase.cc
index 836a1a4331e..683e76a19ad 100644
--- a/sql/ha_innobase.cc
+++ b/sql/ha_innobase.cc
@@ -580,7 +580,7 @@ innobase_init(void)
ret = innobase_parse_data_file_paths_and_sizes();
if (ret == FALSE) {
- fprintf(stderr, "InnoDB: syntax error in innodb_data_file_path\n");
+ sql_print_error("InnoDB: syntax error in innodb_data_file_path");
DBUG_RETURN(TRUE);
}
@@ -928,13 +928,13 @@ ha_innobase::open(
if (NULL == (ib_table = dict_table_get(norm_name, NULL))) {
- fprintf(stderr,
-"InnoDB: Error: cannot find table %s from the internal data dictionary\n"
-"InnoDB: of InnoDB though the .frm file for the table exists. Maybe you\n"
-"InnoDB: have deleted and recreated InnoDB data files but have forgotten\n"
-"InnoDB: to delete the corresponding .frm files of InnoDB tables, or you\n"
-"InnoDB: have moved .frm files to another database?\n",
- norm_name);
+ sql_print_error("InnoDB error:\n\
+Cannot find table %s from the internal data dictionary\n\
+of InnoDB though the .frm file for the table exists. Maybe you\n\
+have deleted and recreated InnoDB data files but have forgotten\n\
+to delete the corresponding .frm files of InnoDB tables, or you\n\
+have moved .frm files to another database?",
+ norm_name);
free_share(share);
my_free((char*) upd_buff, MYF(0));
@@ -2034,10 +2034,7 @@ ha_innobase::change_active_index(
prebuilt->index=dict_table_get_index_noninline(prebuilt->table, key->name);
if (!prebuilt->index)
{
- fprintf(stderr,
- "InnoDB: Could not find key n:o %u with name %s from dict cache\n"
- "InnoDB: for table %s\n", keynr, key->name,
- prebuilt->table->name);
+ sql_print_error("Innodb could not find key n:o %u with name %s from dict cache for table %s", keynr, key->name, prebuilt->table->name);
return(1);
}
}
@@ -3225,7 +3222,7 @@ ha_innobase::update_table_comment(
{
row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
uint length = strlen(comment);
- char* str = my_malloc(length + 200, MYF(0));
+ char* str = my_malloc(length + 550, MYF(0));
char* pos;
if (!str) {
@@ -3244,7 +3241,7 @@ ha_innobase::update_table_comment(
/* We assume 150 bytes of space to print info */
- dict_print_info_on_foreign_keys(pos, 150, prebuilt->table);
+ dict_print_info_on_foreign_keys(pos, 500, prebuilt->table);
return(str);
}
diff --git a/sql/ha_innobase.h b/sql/ha_innobase.h
index b1613c2503c..3c3025c39c1 100644
--- a/sql/ha_innobase.h
+++ b/sql/ha_innobase.h
@@ -91,6 +91,7 @@ class ha_innobase: public handler
~ha_innobase() {}
const char* table_type() const { return("InnoDB");}
+ const char *index_type(uint key_number) { return "BTREE"; }
const char** bas_ext() const;
ulong option_flag() const { return int_option_flag; }
uint max_record_length() const { return HA_MAX_REC_LENGTH; }
@@ -100,8 +101,11 @@ class ha_innobase: public handler
a secondary key record must also contain the
primary key value:
max key length is therefore set to slightly
- less than 1 / 4 of page size which is 16 kB */
- uint max_key_length() const { return 3500; }
+ less than 1 / 4 of page size which is 16 kB;
+ but currently MySQL does not work with keys
+ whose size is > MAX_KEY_LENGTH */
+ uint max_key_length() const { return((MAX_KEY_LENGTH <= 3500) ?
+ MAX_KEY_LENGTH : 3500);}
bool fast_key_read() { return 1;}
key_map keys_to_use_for_scanning() { return ~(key_map) 0; }
bool has_transactions() { return 1;}
diff --git a/sql/ha_isam.h b/sql/ha_isam.h
index 33ca99b5063..e878f0fe697 100644
--- a/sql/ha_isam.h
+++ b/sql/ha_isam.h
@@ -38,6 +38,7 @@ class ha_isam: public handler
{}
~ha_isam() {}
const char *table_type() const { return "ISAM"; }
+ const char *index_type(uint key_number) { return "BTREE"; }
const char **bas_ext() const;
ulong option_flag() const { return int_option_flag; }
uint max_record_length() const { return HA_MAX_REC_LENGTH; }
diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc
index 0378ff7ba6f..77d541bfdfb 100644
--- a/sql/ha_myisam.cc
+++ b/sql/ha_myisam.cc
@@ -80,9 +80,8 @@ static void mi_check_print_msg(MI_CHECK *param, const char* msg_type,
net_store_data(packet, msgbuf);
if (my_net_write(&thd->net, (char*)thd->packet.ptr(), thd->packet.length()))
- fprintf(stderr,
- "Failed on my_net_write, writing to stderr instead: %s\n",
- msgbuf);
+ sql_print_error("Failed on my_net_write, writing to stderr instead: %s\n",
+ msgbuf);
return;
}
@@ -122,6 +121,13 @@ const char **ha_myisam::bas_ext() const
{ static const char *ext[]= { ".MYD",".MYI", NullS }; return ext; }
+const char *ha_myisam::index_type(uint key_number)
+{
+ return ((table->key_info[key_number].flags & HA_FULLTEXT) ?
+ "FULLTEXT" :
+ "BTREE");
+}
+
int ha_myisam::net_read_dump(NET* net)
{
int data_fd = file->dfile;
@@ -1170,7 +1176,7 @@ longlong ha_myisam::get_auto_increment()
longlong nr;
int error;
- byte key[MAX_KEY_LENGTH];
+ byte key[MI_MAX_KEY_LENGTH];
(void) extra(HA_EXTRA_KEYREAD);
key_copy(key,table,table->next_number_index,
table->next_number_key_offset);
diff --git a/sql/ha_myisam.h b/sql/ha_myisam.h
index 7b5c959ccfa..e2044dfe1e2 100644
--- a/sql/ha_myisam.h
+++ b/sql/ha_myisam.h
@@ -54,12 +54,13 @@ class ha_myisam: public handler
{}
~ha_myisam() {}
const char *table_type() const { return "MyISAM"; }
+ const char *index_type(uint key_number);
const char **bas_ext() const;
ulong option_flag() const { return int_option_flag; }
uint max_record_length() const { return HA_MAX_REC_LENGTH; }
uint max_keys() const { return MI_MAX_KEY; }
uint max_key_parts() const { return MAX_REF_PARTS; }
- uint max_key_length() const { return MAX_KEY_LENGTH; }
+ uint max_key_length() const { return MI_MAX_KEY_LENGTH; }
int open(const char *name, int mode, uint test_if_locked);
int close(void);
diff --git a/sql/handler.h b/sql/handler.h
index 1e2c0074475..33cfa965363 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -236,6 +236,7 @@ public:
virtual bool has_transactions(){ return 0;}
virtual uint extra_rec_buf_length() { return 0; }
virtual ha_rows estimate_number_of_rows() { return records+EXTRA_RECORDS; }
+ virtual const char *index_type(uint key_number) { return "";}
virtual int index_init(uint idx) { active_index=idx; return 0;}
virtual int index_end() {return 0; }
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 4caa959bce8..b59aceb512e 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -1496,14 +1496,7 @@ void debug_sync_point(const char* lock_name, uint lock_timeout)
thd->mysys_var->current_mutex= &LOCK_user_locks;
thd->mysys_var->current_cond= &ull->cond;
-#ifdef HAVE_TIMESPEC_TS_SEC
- abstime.ts_sec=time((time_t*) 0)+(time_t) lock_timeout;
- abstime.ts_nsec=0;
-#else
- abstime.tv_sec=time((time_t*) 0)+(time_t) lock_timeout;
- abstime.tv_nsec=0;
-#endif
-
+ set_timespec(abstime,lock_timeout);
while (!thd->killed &&
(error=pthread_cond_timedwait(&ull->cond,&LOCK_user_locks,&abstime))
!= ETIME && error != ETIMEDOUT && ull->locked) ;
@@ -1591,14 +1584,7 @@ longlong Item_func_get_lock::val_int()
thd->mysys_var->current_mutex= &LOCK_user_locks;
thd->mysys_var->current_cond= &ull->cond;
-#ifdef HAVE_TIMESPEC_TS_SEC
- abstime.ts_sec=time((time_t*) 0)+(time_t) timeout;
- abstime.ts_nsec=0;
-#else
- abstime.tv_sec=time((time_t*) 0)+(time_t) timeout;
- abstime.tv_nsec=0;
-#endif
-
+ set_timespec(abstime,timeout);
while (!thd->killed &&
(error=pthread_cond_timedwait(&ull->cond,&LOCK_user_locks,&abstime))
!= ETIME && error != ETIMEDOUT && ull->locked) ;
@@ -1859,6 +1845,16 @@ Item_func_set_user_var::val_str(String *str)
}
+void Item_func_set_user_var::print(String *str)
+{
+ str->append('(');
+ str->append(name.str,name.length);
+ str->append(":=",2);
+ args[0]->print(str);
+ str->append(')');
+}
+
+
user_var_entry *Item_func_get_user_var::get_entry()
{
if (!entry || ! entry->value)
@@ -1951,6 +1947,34 @@ enum Item_result Item_func_get_user_var::result_type() const
return entry->type;
}
+
+void Item_func_get_user_var::print(String *str)
+{
+ str->append('@');
+ str->append(name.str,name.length);
+ str->append(')');
+}
+
+bool Item_func_get_user_var::eq(const Item *item) const
+{
+ /* Assume we don't have rtti */
+ if (this == item)
+ return 1; // Same item is same.
+ /* Check if other type is also a get_user_var() object */
+#ifdef FIX_THIS
+ if (item->eq == &Item_func_get_user_var::eq)
+ return 0;
+#else
+ if (item->type() != FUNC_ITEM ||
+ ((Item_func*) item)->func_name() != func_name())
+ return 0;
+#endif
+ Item_func_get_user_var *other=(Item_func_get_user_var*) item;
+ return (name.length == other->name.length &&
+ !memcmp(name.str, other->name.str, name.length));
+}
+
+
longlong Item_func_inet_aton::val_int()
{
uint byte_result = 0;
diff --git a/sql/item_func.h b/sql/item_func.h
index d944ef6bc36..d1d836db67b 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -196,6 +196,27 @@ public:
}
};
+class Item_func_signed :public Item_int_func
+{
+public:
+ Item_func_signed(Item *a) :Item_int_func(a) {}
+ double val() { return args[0]->val(); }
+ longlong val_int() { return args[0]->val_int(); }
+ void fix_length_and_dec()
+ { decimals=0; max_length=args[0]->max_length; unsigned_flag=0; }
+};
+
+class Item_func_unsigned :public Item_int_func
+{
+public:
+ Item_func_unsigned(Item *a) :Item_int_func(a) {}
+ double val() { return args[0]->val(); }
+ longlong val_int() { return args[0]->val_int(); }
+ void fix_length_and_dec()
+ { decimals=0; max_length=args[0]->max_length; unsigned_flag=1; }
+};
+
+
class Item_func_plus :public Item_num_op
{
public:
@@ -835,6 +856,7 @@ public:
enum Item_result result_type () const { return cached_result_type; }
bool fix_fields(THD *thd,struct st_table_list *tables);
void fix_length_and_dec();
+ void print(String *str);
const char *func_name() const { return "set_user_var"; }
};
@@ -853,13 +875,16 @@ public:
longlong val_int();
String *val_str(String* str);
void fix_length_and_dec();
+ void print(String *str);
enum Item_result result_type() const;
const char *func_name() const { return "get_user_var"; }
bool const_item() const { return const_var_flag; }
table_map used_tables() const
{ return const_var_flag ? 0 : RAND_TABLE_BIT; }
+ bool eq(const Item *item) const;
};
+
class Item_func_inet_aton : public Item_int_func
{
public:
diff --git a/sql/lex.h b/sql/lex.h
index 887fcb78754..3b91a0b35ef 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -305,6 +305,7 @@ static SYMBOL symbols[] = {
{ "SERIALIZABLE", SYM(SERIALIZABLE_SYM),0,0},
{ "SESSION", SYM(SESSION_SYM),0,0},
{ "SET", SYM(SET),0,0},
+ { "SIGNED", SYM(SIGNED),0,0},
{ "SHARE", SYM(SHARE_SYM),0,0},
{ "SHOW", SYM(SHOW),0,0},
{ "SHUTDOWN", SYM(SHUTDOWN),0,0},
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 1aa030dba9e..8e9ff17387c 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -448,15 +448,7 @@ static void close_connections(void)
if (pthread_kill(select_thread,THR_CLIENT_ALARM))
break; // allready dead
#endif
-#ifdef HAVE_TIMESPEC_TS_SEC
- abstime.ts_sec=time(NULL)+2; // Bsd 2.1
- abstime.ts_nsec=0;
-#else
- struct timeval tv;
- gettimeofday(&tv,0);
- abstime.tv_sec=tv.tv_sec+2;
- abstime.tv_nsec=tv.tv_usec*1000;
-#endif
+ set_timespec(abstime, 2);
for (uint tmp=0 ; tmp < 10 ; tmp++)
{
error=pthread_cond_timedwait(&COND_thread_count,&LOCK_thread_count,
@@ -2918,9 +2910,9 @@ CHANGEABLE_VAR changeable_vars[] = {
(long*) &innobase_additional_mem_pool_size, 1*1024*1024L, 512*1024L,
~0L, 0, 1024},
{"innodb_file_io_threads",
- (long*) &innobase_file_io_threads, 9, 4, 64, 0, 1},
+ (long*) &innobase_file_io_threads, 4, 4, 64, 0, 1},
{"innodb_lock_wait_timeout",
- (long*) &innobase_lock_wait_timeout, 1024 * 1024 * 1024, 1,
+ (long*) &innobase_lock_wait_timeout, 50, 1,
1024 * 1024 * 1024, 0, 1},
{"innodb_thread_concurrency",
(long*) &innobase_thread_concurrency, 8, 1, 1000, 0, 1},
@@ -4087,6 +4079,7 @@ static void get_options(int argc,char **argv)
break;
case OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT:
innobase_flush_log_at_trx_commit= optarg ? test(atoi(optarg)) : 1;
+ break;
case OPT_INNODB_FAST_SHUTDOWN:
innobase_fast_shutdown= optarg ? test(atoi(optarg)) : 1;
break;
diff --git a/sql/net_pkg.cc b/sql/net_pkg.cc
index 2f26ad81bd5..64c1b07a493 100644
--- a/sql/net_pkg.cc
+++ b/sql/net_pkg.cc
@@ -52,6 +52,7 @@ void send_error(NET *net, uint sql_errno, const char *err)
{
if (thd && thd->bootstrap)
{
+ /* In bootstrap it's ok to print on stderr */
fprintf(stderr,"ERROR: %d %s\n",sql_errno,err);
}
DBUG_VOID_RETURN;
@@ -120,6 +121,7 @@ net_printf(NET *net, uint errcode, ...)
{
if (thd && thd->bootstrap)
{
+ /* In bootstrap it's ok to print on stderr */
fprintf(stderr,"ERROR: %d %s\n",errcode,text_pos);
thd->fatal_error=1;
}
diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index 3e4dcb75ebb..9a8d6b5e967 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -167,7 +167,7 @@ static my_bool net_realloc(NET *net, ulong length)
void net_clear(NET *net)
{
-#ifndef EXTRA_DEBUG
+#if !defined(EXTRA_DEBUG) && !defined(EMBEDDED_LIBRARY)
int count; /* One may get 'unused' warn */
bool is_blocking=vio_is_blocking(net->vio);
if (is_blocking)
diff --git a/sql/slave.cc b/sql/slave.cc
index 33c4273bcb0..f2c29146308 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -285,11 +285,11 @@ char* rewrite_db(char* db)
I_List_iterator<i_string_pair> it(replicate_rewrite_db);
i_string_pair* tmp;
- while((tmp=it++))
- {
- if (!strcmp(tmp->key, db))
- return tmp->val;
- }
+ while ((tmp=it++))
+ {
+ if (!strcmp(tmp->key, db))
+ return tmp->val;
+ }
return db;
}
@@ -310,7 +310,7 @@ int db_ok(const char* db, I_List<i_string> &do_list,
I_List_iterator<i_string> it(do_list);
i_string* tmp;
- while((tmp=it++))
+ while ((tmp=it++))
{
if (!strcmp(tmp->ptr, db))
return 1; // match
@@ -322,7 +322,7 @@ int db_ok(const char* db, I_List<i_string> &do_list,
I_List_iterator<i_string> it(ignore_list);
i_string* tmp;
- while((tmp=it++))
+ while ((tmp=it++))
{
if (!strcmp(tmp->ptr, db))
return 0; // match
@@ -346,7 +346,7 @@ static int init_strvar_from_file(char* var, int max_size, IO_CACHE* f,
// if we truncated a line or stopped on last char, remove all chars
// up to and including newline
int c;
- while( ((c=my_b_get(f)) != '\n' && c != my_b_EOF));
+ while (((c=my_b_get(f)) != '\n' && c != my_b_EOF));
}
return 0;
}
@@ -803,7 +803,7 @@ int st_master_info::wait_for_pos(THD* thd, String* log_name, ulonglong log_pos)
bool pos_reached;
int event_count = 0;
pthread_mutex_lock(&lock);
- while(!thd->killed)
+ while (!thd->killed)
{
int cmp_result;
if (*log_file_name)
@@ -1002,8 +1002,8 @@ server_errno=%d)",
if (len == 1)
{
- sql_print_error("Slave: received 0 length packet from server, apparent\
- master shutdown: %s (%d)",
+ sql_print_error("Slave: received 0 length packet from server, apparent \
+master shutdown: %s (%d)",
mc_mysql_error(mysql), read_errno);
return packet_error;
}
@@ -1015,24 +1015,23 @@ server_errno=%d)",
int check_expected_error(THD* thd, int expected_error)
{
- switch(expected_error)
- {
- case ER_NET_READ_ERROR:
- case ER_NET_ERROR_ON_WRITE:
- case ER_SERVER_SHUTDOWN:
- case ER_NEW_ABORTING_CONNECTION:
- my_snprintf(last_slave_error, sizeof(last_slave_error),
- "Slave: query '%s' partially completed on the master \
+ switch (expected_error) {
+ case ER_NET_READ_ERROR:
+ case ER_NET_ERROR_ON_WRITE:
+ case ER_SERVER_SHUTDOWN:
+ case ER_NEW_ABORTING_CONNECTION:
+ my_snprintf(last_slave_error, sizeof(last_slave_error),"\
+Slave: query '%s' partially completed on the master \
and was aborted. There is a chance that your master is inconsistent at this \
-point. If you are sure that your master is ok, run this query manually on the\
- slave and then restart the slave with SET SQL_SLAVE_SKIP_COUNTER=1;\
- SLAVE START;", thd->query);
- last_slave_errno = expected_error;
- sql_print_error("%s",last_slave_error);
- return 1;
- default:
- return 0;
- }
+point. If you are sure that your master is ok, run this query manually on the \
+slave and then restart the slave with SET SQL_SLAVE_SKIP_COUNTER=1;\
+SLAVE START;", thd->query);
+ last_slave_errno = expected_error;
+ sql_print_error("%s",last_slave_error);
+ return 1;
+ default:
+ return 0;
+ }
}
@@ -1230,8 +1229,7 @@ try again, log '%s' at postion %s", RPL_LOG_NAME,
goto connected;
}
-
- while(!slave_killed(thd))
+ while (!slave_killed(thd))
{
thd->proc_info = "Reading master update";
ulong event_len = read_event(mysql, &glob_mi);
@@ -1323,8 +1321,8 @@ the slave thread with \"mysqladmin start-slave\". We stopped at log \
events_till_disconnect++;
}
#endif
- } // while(!slave_killed(thd)) - read/exec loop
- } // while(!slave_killed(thd)) - slave loop
+ } // while (!slave_killed(thd)) - read/exec loop
+ } // while (!slave_killed(thd)) - slave loop
// error = 0;
err:
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index 70790a4efb5..e21a674eb07 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -288,6 +288,11 @@ If join_results allocated new block(s) then we need call pack_cache again.
pthread_mutex_lock(M);}
#define MUTEX_UNLOCK(M) {DBUG_PRINT("lock", ("mutex unlock 0x%lx",\
(ulong)(M))); pthread_mutex_unlock(M);}
+#define SEM_LOCK(M) { int val = 0; sem_getvalue (M, &val); \
+ DBUG_PRINT("lock", ("sem lock 0x%lx (%d)", (ulong)(M), val)); \
+ sem_wait(M); DBUG_PRINT("lock", ("sem lock ok")); }
+#define SEM_UNLOCK(M) {DBUG_PRINT("info", ("sem unlock 0x%lx", (ulong)(M))); \
+ sem_post(M); DBUG_PRINT("info", ("sem unlock ok")); }
#define STRUCT_LOCK(M) {DBUG_PRINT("lock", ("%d struct lock...",__LINE__)); \
pthread_mutex_lock(M);DBUG_PRINT("lock", ("struct lock OK"));}
#define STRUCT_UNLOCK(M) { \
@@ -310,6 +315,8 @@ If join_results allocated new block(s) then we need call pack_cache again.
#else
#define MUTEX_LOCK(M) pthread_mutex_lock(M)
#define MUTEX_UNLOCK(M) pthread_mutex_unlock(M)
+#define SEM_LOCK(M) sem_wait(M)
+#define SEM_UNLOCK(M) sem_post(M)
#define STRUCT_LOCK(M) pthread_mutex_lock(M)
#define STRUCT_UNLOCK(M) pthread_mutex_unlock(M)
#define BLOCK_LOCK_WR(B) B->query()->lock_writing()
@@ -426,7 +433,7 @@ void Query_cache_query::init_n_lock()
{
DBUG_ENTER("Query_cache_query::init_n_lock");
res=0; wri = 0; len = 0;
- pthread_cond_init(&lock, NULL);
+ sem_init(&lock, 0, 1);
pthread_mutex_init(&clients_guard,MY_MUTEX_INIT_FAST);
clients = 0;
lock_writing();
@@ -446,7 +453,7 @@ void Query_cache_query::unlock_n_destroy()
active semaphore
*/
this->unlock_writing();
- pthread_cond_destroy(&lock);
+ sem_destroy(&lock);
pthread_mutex_destroy(&clients_guard);
DBUG_VOID_RETURN;
}
@@ -462,9 +469,7 @@ void Query_cache_query::unlock_n_destroy()
void Query_cache_query::lock_writing()
{
- MUTEX_LOCK(&clients_guard);
- while (clients != 0)
- pthread_cond_wait(&lock,&clients_guard);
+ SEM_LOCK(&lock);
}
@@ -478,18 +483,12 @@ void Query_cache_query::lock_writing()
my_bool Query_cache_query::try_lock_writing()
{
DBUG_ENTER("Query_cache_block::try_lock_writing");
- if (pthread_mutex_trylock(&clients_guard))
- {
- DBUG_PRINT("qcache", ("can't lock mutex"));
- DBUG_RETURN(0);
- }
- if (clients != 0)
+ if (sem_trywait(&lock)!=0 || clients != 0)
{
- DBUG_PRINT("info", ("already locked (r)"));
- MUTEX_UNLOCK(&clients_guard);
+ DBUG_PRINT("info", ("can't lock semaphore"));
DBUG_RETURN(0);
}
- DBUG_PRINT("qcache", ("mutex 'lock' 0x%lx locked", (ulong) &lock));
+ DBUG_PRINT("info", ("mutex 'lock' 0x%lx locked", (ulong) &lock));
DBUG_RETURN(1);
}
@@ -497,23 +496,28 @@ my_bool Query_cache_query::try_lock_writing()
void Query_cache_query::lock_reading()
{
MUTEX_LOCK(&clients_guard);
- clients++;
+ if ( ++clients == 1 )
+ SEM_LOCK(&lock);
MUTEX_UNLOCK(&clients_guard);
}
void Query_cache_query::unlock_writing()
{
- MUTEX_UNLOCK(&clients_guard);
+ SEM_UNLOCK(&lock);
}
void Query_cache_query::unlock_reading()
{
+ /*
+ To avoid unlocking semaphore before unlocking mutex (that may cause
+ destroying locked mutex), we use temporary boolean variable 'unlock'.
+ */
MUTEX_LOCK(&clients_guard);
- if (--clients == 0)
- pthread_cond_broadcast(&lock);
+ bool ulock = ((--clients) == 0);
MUTEX_UNLOCK(&clients_guard);
+ if (ulock) SEM_UNLOCK(&lock);
}
extern "C"
@@ -1377,8 +1381,11 @@ void Query_cache::free_cache(my_bool destruction)
/* Becasue we did a flush, all cache memory must be in one this block */
bins[0].free_blocks->destroy();
total_blocks--;
- DBUG_PRINT("qcache", ("free memory %lu (should be %lu)",
- free_memory , query_cache_size));
+#ifndef DBUG_OFF
+ if (free_memory != query_cache_size)
+ DBUG_PRINT("qcache", ("free memory %lu (should be %lu)",
+ free_memory , query_cache_size));
+#endif
my_free((gptr) cache, MYF(MY_ALLOW_ZERO_PTR));
make_disabled();
hash_free(&queries);
@@ -2572,7 +2579,7 @@ my_bool Query_cache::move_by_type(byte **border,
} while ( result_block != first_result_block );
}
Query_cache_query *new_query= ((Query_cache_query *) new_block->data());
- pthread_cond_init(&new_query->lock, NULL);
+ sem_init(&new_query->lock, 0, 1);
pthread_mutex_init(&new_query->clients_guard,MY_MUTEX_INIT_FAST);
/*
@@ -2975,12 +2982,13 @@ my_bool Query_cache::check_integrity()
my_bool result = 0;
uint i;
STRUCT_LOCK(&structure_guard_mutex);
+ DBUG_ENTER("check_integrity");
if ( !initialized )
{
STRUCT_UNLOCK(&structure_guard_mutex);
DBUG_PRINT("qcache", ("Query Cache not initialized"));
- return 0;
+ DBUG_RETURN(0);
}
if (hash_check(&queries))
@@ -3064,6 +3072,8 @@ my_bool Query_cache::check_integrity()
result = 1;
break;
case Query_cache_block::RES_INCOMPLETE:
+ // This type of block can be not lincked yet (in multithread environment)
+ break;
case Query_cache_block::RES_BEG:
case Query_cache_block::RES_CONT:
case Query_cache_block::RESULT:
@@ -3082,11 +3092,13 @@ my_bool Query_cache::check_integrity()
}
else
{
+ BLOCK_LOCK_RD(query_block);
if (in_list(queries_blocks, query_block, "query from results"))
result = 1;
if (in_list(query_block->query()->result(), block,
"results"))
result = 1;
+ BLOCK_UNLOCK_RD(query_block);
}
break;
}
@@ -3194,15 +3206,15 @@ my_bool Query_cache::check_integrity()
} while (block != bins[i].free_blocks);
if (count != bins[i].number)
{
- DBUG_PRINT("qcache", ("bin[%d].number is %d, but bin have %d blocks",
- bins[i].number, count));
+ DBUG_PRINT("error", ("bin[%d].number is %d, but bin have %d blocks",
+ bins[i].number, count));
result = 1;
}
}
}
DBUG_ASSERT(result == 0);
STRUCT_UNLOCK(&structure_guard_mutex);
- return result;
+ DBUG_RETURN(result);
}
diff --git a/sql/sql_cache.h b/sql/sql_cache.h
index 50ae765e446..bde11d2dbb6 100644
--- a/sql/sql_cache.h
+++ b/sql/sql_cache.h
@@ -55,6 +55,8 @@
#define TABLE_COUNTER_TYPE uint8
+#include <my_semaphore.h>
+
struct Query_cache_block;
struct Query_cache_block_table;
struct Query_cache_table;
@@ -107,7 +109,7 @@ struct Query_cache_query
Query_cache_block *res;
NET *wri;
ulong len;
- pthread_cond_t lock; // R/W lock of block
+ sem_t lock; // R/W lock of block
pthread_mutex_t clients_guard;
uint clients;
@@ -396,5 +398,8 @@ protected:
};
extern Query_cache query_cache;
+void query_cache_insert(NET *net, const char *packet, ulong length);
+void query_cache_end_of_result(NET *net);
+void query_cache_abort(NET *net);
#endif
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 06a1818b50d..75feca8d759 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -988,23 +988,12 @@ static pthread_handler_decl(handle_delayed_insert,arg)
if (!di->status && !di->stacked_inserts)
{
struct timespec abstime;
-#if defined(HAVE_TIMESPEC_TS_SEC)
- abstime.ts_sec=time((time_t*) 0)+(time_t) delayed_insert_timeout;
- abstime.ts_nsec=0;
-#elif defined(__WIN__)
- abstime.tv_sec=time((time_t*) 0)+(time_t) delayed_insert_timeout;
- abstime.tv_nsec=0;
-#else
- struct timeval tv;
- gettimeofday(&tv,0);
- abstime.tv_sec=tv.tv_sec+(time_t) delayed_insert_timeout;
- abstime.tv_nsec=tv.tv_usec*1000;
-#endif
+ set_timespec(abstime, delayed_insert_timeout);
/* Information for pthread_kill */
di->thd.mysys_var->current_mutex= &di->mutex;
di->thd.mysys_var->current_cond= &di->cond;
- di->thd.proc_info=0;
+ di->thd.proc_info="Waiting for INSERT";
DBUG_PRINT("info",("Waiting for someone to insert rows"));
while (!thd->killed)
@@ -1039,6 +1028,7 @@ static pthread_handler_decl(handle_delayed_insert,arg)
pthread_mutex_unlock(&di->thd.mysys_var->mutex);
pthread_mutex_lock(&di->mutex);
}
+ di->thd.proc_info=0;
if (di->tables_in_use && ! thd->lock)
{
diff --git a/sql/sql_manager.cc b/sql/sql_manager.cc
index 53953c96d0b..13cac83fc3f 100644
--- a/sql/sql_manager.cc
+++ b/sql/sql_manager.cc
@@ -55,13 +55,7 @@ pthread_handler_decl(handle_manager,arg __attribute__((unused)))
{
if (reset_flush_time)
{
-#ifdef HAVE_TIMESPEC_TS_SEC
- abstime.ts_sec = time(NULL)+flush_time; // Bsd 2.1
- abstime.ts_nsec = 0;
-#else
- abstime.tv_sec = time(NULL)+flush_time; // Linux or Solairs
- abstime.tv_nsec = 0;
-#endif
+ set_timespec(abstime, flush_time);
reset_flush_time = FALSE;
}
while (!manager_status && !error && !abort_loop)
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index f964a74240a..2f2e3deaa0d 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -89,8 +89,8 @@ static void test_signal(int sig_ptr)
MessageBox(NULL,"Test signal","DBUG",MB_OK);
#endif
#if defined(OS2)
- fprintf( stderr, "Test signal %d\n", sig_ptr);
- fflush( stderr);
+ fprintf(stderr, "Test signal %d\n", sig_ptr);
+ fflush(stderr);
#endif
}
static void init_signals(void)
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index bfee5f9235b..c65654faefb 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -607,25 +607,14 @@ int stop_slave(THD* thd, bool net_report )
// do not abort the slave in the middle of a query, so we do not set
// thd->killed for the slave thread
thd->proc_info = "waiting for slave to die";
- while(slave_running)
+ while (slave_running)
{
- /* there is a small chance that slave thread might miss the first
- alarm. To protect againts it, resend the signal until it reacts
+ /*
+ There is a small chance that slave thread might miss the first
+ alarm. To protect againts it, resend the signal until it reacts
*/
-
struct timespec abstime;
-#ifdef HAVE_TIMESPEC_TS_SEC
- abstime.ts_sec=time(NULL)+2;
- abstime.ts_nsec=0;
-#elif defined(__WIN__)
- abstime.tv_sec=time((time_t*) 0)+2;
- abstime.tv_nsec=0;
-#else
- struct timeval tv;
- gettimeofday(&tv,0);
- abstime.tv_sec=tv.tv_sec+2;
- abstime.tv_nsec=tv.tv_usec*1000;
-#endif
+ set_timespec(abstime, 2);
pthread_cond_timedwait(&COND_slave_stopped, &LOCK_slave, &abstime);
if (slave_running)
KICK_SLAVE;
@@ -659,8 +648,8 @@ void reset_slave()
pthread_mutex_lock(&LOCK_slave);
if ((slave_was_running = slave_running))
{
- pthread_mutex_unlock(&LOCK_slave);
- stop_slave(0,0);
+ pthread_mutex_unlock(&LOCK_slave);
+ stop_slave(0,0);
}
else
pthread_mutex_unlock(&LOCK_slave);
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 60a40730afc..46c1dc80762 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -35,7 +35,7 @@ const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref",
"MAYBE_REF","ALL","range","index","fulltext" };
static bool make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
- DYNAMIC_ARRAY *keyuse);
+ DYNAMIC_ARRAY *keyuse);
static bool update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,
JOIN_TAB *join_tab,
uint tables,COND *conds,table_map table_map);
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 821ec3fe972..8ffeb70e912 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -652,6 +652,8 @@ mysqld_show_keys(THD *thd, TABLE_LIST *table_list)
item->maybe_null=1;
field_list.push_back(item=new Item_empty_string("Packed",10));
item->maybe_null=1;
+ field_list.push_back(new Item_empty_string("Null",3));
+ field_list.push_back(new Item_empty_string("Index_type",16));
field_list.push_back(new Item_empty_string("Comment",255));
item->maybe_null=1;
@@ -691,6 +693,8 @@ mysqld_show_keys(THD *thd, TABLE_LIST *table_list)
}
else
net_store_null(packet);
+
+ /* Check if we have a key part that only uses part of the field */
if (!key_part->field ||
key_part->length !=
table->field[key_part->fieldnr-1]->key_length())
@@ -701,8 +705,14 @@ mysqld_show_keys(THD *thd, TABLE_LIST *table_list)
else
net_store_null(packet);
net_store_null(packet); // No pack_information yet
- net_store_data(packet,convert,
- key_info->flags & HA_FULLTEXT ? "FULLTEXT":"");
+
+ /* Null flag */
+ uint flags= key_part->field ? key_part->field->flags : 0;
+ char *pos=(byte*) ((flags & NOT_NULL_FLAG) ? "" : "YES");
+ net_store_data(packet,convert,(const char*) pos);
+ net_store_data(packet,convert,table->file->index_type(i));
+ /* Comment */
+ net_store_data(packet,convert,"");
if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length()))
DBUG_RETURN(1); /* purecov: inspected */
}
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 523358b780e..250c8fad5d1 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -26,6 +26,7 @@
#endif
extern HASH open_cache;
+static const char *primary_key_name="PRIMARY";
static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end);
static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end);
@@ -196,6 +197,48 @@ int quick_rm_table(enum db_type base,const char *db,
return ha_delete_table(base,path) || error;
}
+/*
+ Sort keys in the following order:
+ - PRIMARY KEY
+ - UNIQUE keyws where all column are NOT NULL
+ - Other UNIQUE keys
+ - Normal keys
+ - Fulltext keys
+
+ This will make checking for duplicated keys faster and ensure that
+ PRIMARY keys are prioritized.
+*/
+
+
+static int sort_keys(KEY *a, KEY *b)
+{
+ if (a == b) // Safety
+ return 0;
+ if (a->flags & HA_NOSAME)
+ {
+ if (!(b->flags & HA_NOSAME))
+ return -1;
+ if ((a->flags ^ b->flags) & HA_NULL_PART_KEY)
+ {
+ /* Sort NOT NULL keys before other keys */
+ return (a->flags & HA_NULL_PART_KEY) ? 1 : -1;
+ }
+ if (a->name == primary_key_name)
+ return -1;
+ if (b->name == primary_key_name)
+ return 1;
+ }
+ else if (b->flags & HA_NOSAME)
+ return 1; // Prefer b
+
+ if ((a->flags ^ b->flags) & HA_FULLTEXT)
+ {
+ return (a->flags & HA_FULLTEXT) ? 1 : -1;
+ }
+ return a < b ? -1 : 1; // Prefer original key order
+}
+
+
/*****************************************************************************
* Create a table.
* If one creates a temporary table, this is automaticly opened
@@ -351,8 +394,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
List_iterator<Key> key_iterator(keys);
uint key_parts=0,key_count=keys.elements;
List<Key> keys_in_order; // Add new keys here
- Key *primary_key=0;
- bool unique_key=0;
+ bool primary_key=0,unique_key=0;
Key *key;
uint tmp;
tmp=min(file->max_keys(), MAX_KEY);
@@ -362,12 +404,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
DBUG_RETURN(-1);
}
- /*
- Check keys;
- Put PRIMARY KEY first, then UNIQUE keys and other keys last
- This will make checking for duplicated keys faster and ensure that
- primary keys are prioritized.
- */
+ /* Calculate number of key segements */
while ((key=key_iterator++))
{
@@ -383,33 +420,6 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
DBUG_RETURN(-1);
}
key_parts+=key->columns.elements;
- if (key->type == Key::PRIMARY)
- {
- if (primary_key)
- {
- my_error(ER_MULTIPLE_PRI_KEY,MYF(0));
- DBUG_RETURN(-1);
- }
- primary_key=key;
- }
- else if (key->type == Key::UNIQUE)
- {
- unique_key=1;
- if (keys_in_order.push_front(key))
- DBUG_RETURN(-1);
- }
- else if (keys_in_order.push_back(key))
- DBUG_RETURN(-1);
- }
- if (primary_key)
- {
- if (keys_in_order.push_front(primary_key))
- DBUG_RETURN(-1);
- }
- else if (!unique_key && (file->option_flag() & HA_REQUIRE_PRIMARY_KEY))
- {
- my_error(ER_REQUIRES_PRIMARY_KEY,MYF(0));
- DBUG_RETURN(-1);
}
key_info_buffer=key_info=(KEY*) sql_calloc(sizeof(KEY)*key_count);
@@ -417,8 +427,8 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
if (!key_info_buffer || ! key_part_info)
DBUG_RETURN(-1); // Out of memory
- List_iterator<Key> key_iterator_in_order(keys_in_order);
- for (; (key=key_iterator_in_order++) ; key_info++)
+ key_iterator.rewind();
+ for (; (key=key_iterator++) ; key_info++)
{
uint key_length=0;
key_part_spec *column;
@@ -486,6 +496,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
MYF(0),column->field_name);
DBUG_RETURN(-1);
}
+ key_info->flags|= HA_NULL_PART_KEY;
}
if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
{
@@ -545,7 +556,15 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
if (column_nr == 0)
{
if (key->type == Key::PRIMARY)
- key_name="PRIMARY";
+ {
+ if (primary_key)
+ {
+ my_error(ER_MULTIPLE_PRI_KEY,MYF(0));
+ DBUG_RETURN(-1);
+ }
+ key_name=primary_key_name;
+ primary_key=1;
+ }
else if (!(key_name = key->name()))
key_name=make_unique_key_name(sql_field->field_name,
key_info_buffer,key_info);
@@ -557,6 +576,8 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
key_info->name=(char*) key_name;
}
}
+ if (!(key_info->flags & HA_NULL_PART_KEY))
+ unique_key=1;
key_info->key_length=(uint16) key_length;
uint max_key_length= max(file->max_key_length(), MAX_KEY_LENGTH);
if (key_length > max_key_length && key->type != Key::FULLTEXT)
@@ -565,11 +586,19 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
DBUG_RETURN(-1);
}
}
+ if (!unique_key && !primary_key &&
+ (file->option_flag() & HA_REQUIRE_PRIMARY_KEY))
+ {
+ my_error(ER_REQUIRES_PRIMARY_KEY,MYF(0));
+ DBUG_RETURN(-1);
+ }
if (auto_increment > 0)
{
my_error(ER_WRONG_AUTO_KEY,MYF(0));
DBUG_RETURN(-1);
}
+ /* Sort keys in optimized order */
+ qsort((gptr) key_info_buffer, key_count, sizeof(KEY), (qsort_cmp) sort_keys);
/* Check if table exists */
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index ed76982b12a..fc2432d5c03 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -356,6 +356,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token PRECISION
%token QUICK
%token REAL
+%token SIGNED
%token SMALLINT
%token STRING_SYM
%token TEXT_SYM
@@ -486,6 +487,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%left NEG '~'
%right NOT
%right BINARY
+%right SIGNED
+%right UNSIGNED
%right DATE_SYM
%right TIME_SYM
%right DATETIME
@@ -1017,7 +1020,8 @@ field_opt_list:
| field_option {}
field_option:
- UNSIGNED { Lex->type|= UNSIGNED_FLAG;}
+ SIGNED {}
+ | UNSIGNED { Lex->type|= UNSIGNED_FLAG;}
| ZEROFILL { Lex->type|= UNSIGNED_FLAG | ZEROFILL_FLAG; }
opt_len:
@@ -1603,10 +1607,12 @@ simple_expr:
| MATCH ident_list_arg AGAINST '(' expr IN_SYM BOOLEAN_SYM MODE_SYM ')'
{ Select->ftfunc_list.push_back((Item_func_match *)
($$=new Item_func_match_bool(*$2,$5))); }
- | BINARY expr %prec NEG { $$= new Item_func_binary($2); }
- | DATE_SYM expr { $$= new Item_date_typecast($2); }
- | TIME_SYM expr { $$= new Item_time_typecast($2); }
- | DATETIME expr { $$= new Item_datetime_typecast($2); }
+ | BINARY expr %prec NEG { $$= new Item_func_binary($2); }
+ | SIGNED expr %prec NEG { $$= new Item_func_signed($2); }
+ | UNSIGNED expr %prec NEG { $$= new Item_func_unsigned($2); }
+ | DATE_SYM expr { $$= new Item_date_typecast($2); }
+ | TIME_SYM expr { $$= new Item_time_typecast($2); }
+ | DATETIME expr { $$= new Item_datetime_typecast($2); }
| CASE_SYM opt_expr WHEN_SYM when_list opt_else END
{ $$= new Item_func_case(* $4, $2, $5 ) }
| FUNC_ARG0 '(' ')'