summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <hf@deer.(none)>2004-01-19 21:06:27 +0400
committerunknown <hf@deer.(none)>2004-01-19 21:06:27 +0400
commit73a5742881fd2c38e9695887bcb607aa75ee0ac1 (patch)
tree68d020ad65ffc40d49179abe19fb94245bfbf5d6
parent75a9472678b3ed2f4d23e70a4a402e1c828c12b4 (diff)
parent5c57c6ce2edde35837e9ef8e26e66dff5be6b2a8 (diff)
downloadmariadb-git-73a5742881fd2c38e9695887bcb607aa75ee0ac1.tar.gz
Merge deer.(none):/home/hf/work/mysql-4.1.clean
into deer.(none):/home/hf/work/mysql-4.1.1676 sql/item.cc: Auto merged sql/item.h: Auto merged sql/item_func.h: Auto merged sql/item_strfunc.cc: Auto merged sql/item_subselect.cc: Auto merged sql/mysql_priv.h: Auto merged sql/sql_prepare.cc: Auto merged sql/sql_select.cc: Auto merged sql/sql_yacc.yy: Auto merged
-rw-r--r--BitKeeper/etc/logging_ok1
-rw-r--r--client/mysql.cc75
-rw-r--r--client/mysqldump.c11
-rw-r--r--cmd-line-utils/libedit/Makefile.am13
-rw-r--r--cmd-line-utils/libedit/makelist.sh (renamed from cmd-line-utils/libedit/makelist)2
-rw-r--r--include/my_getopt.h7
-rw-r--r--include/mysql_embed.h2
-rw-r--r--include/mysys_err.h1
-rw-r--r--innobase/row/row0mysql.c2
-rw-r--r--innobase/row/row0sel.c24
-rw-r--r--innobase/srv/srv0srv.c4
-rw-r--r--innobase/srv/srv0start.c16
-rw-r--r--libmysqld/Makefile.am4
-rw-r--r--libmysqld/emb_qcache.cc446
-rw-r--r--libmysqld/emb_qcache.h61
-rw-r--r--libmysqld/embedded_priv.h9
-rw-r--r--libmysqld/lib_sql.cc31
-rw-r--r--libmysqld/libmysqld.c17
-rw-r--r--myisam/mi_check.c8
-rw-r--r--myisam/mi_write.c2
-rw-r--r--mysql-test/mysql-test-run.sh5
-rw-r--r--mysql-test/r/alter_table.result9
-rw-r--r--mysql-test/r/ctype_recoding.result6
-rw-r--r--mysql-test/r/ctype_ucs.result6
-rw-r--r--mysql-test/r/ctype_utf8.result17
-rw-r--r--mysql-test/r/derived.result28
-rw-r--r--mysql-test/r/func_str.result3
-rw-r--r--mysql-test/r/mysqldump.result42
-rw-r--r--mysql-test/r/null.result3
-rw-r--r--mysql-test/r/query_cache.result8
-rw-r--r--mysql-test/r/show_check.result25
-rw-r--r--mysql-test/r/subselect.result9
-rw-r--r--mysql-test/r/subselect_innodb.result37
-rw-r--r--mysql-test/r/symlink.result2
-rw-r--r--mysql-test/r/warnings.result4
-rw-r--r--mysql-test/t/alter_table.test9
-rw-r--r--mysql-test/t/ctype_recoding.test10
-rw-r--r--mysql-test/t/ctype_ucs.test7
-rw-r--r--mysql-test/t/ctype_utf8.test18
-rw-r--r--mysql-test/t/derived.test27
-rw-r--r--mysql-test/t/func_str.test6
-rw-r--r--mysql-test/t/null.test1
-rw-r--r--mysql-test/t/query_cache.test13
-rw-r--r--mysql-test/t/show_check.test9
-rw-r--r--mysql-test/t/subselect.test12
-rw-r--r--mysql-test/t/subselect_innodb.test35
-rw-r--r--mysys/charset.c13
-rw-r--r--mysys/default.c3
-rw-r--r--mysys/mf_iocache.c4
-rw-r--r--mysys/my_getopt.c29
-rw-r--r--netware/init_db.sql4
-rw-r--r--netware/libmysql.imp2
-rw-r--r--sql/field.cc12
-rw-r--r--sql/item.cc3
-rw-r--r--sql/item.h16
-rw-r--r--sql/item_func.h8
-rw-r--r--sql/item_strfunc.cc12
-rw-r--r--sql/item_subselect.cc20
-rw-r--r--sql/mysql_priv.h3
-rw-r--r--sql/sql_base.cc27
-rw-r--r--sql/sql_cache.cc41
-rw-r--r--sql/sql_cache.h4
-rw-r--r--sql/sql_class.cc83
-rw-r--r--sql/sql_db.cc12
-rw-r--r--sql/sql_derived.cc24
-rw-r--r--sql/sql_help.cc6
-rw-r--r--sql/sql_insert.cc4
-rw-r--r--sql/sql_lex.cc5
-rw-r--r--sql/sql_lex.h2
-rw-r--r--sql/sql_load.cc2
-rw-r--r--sql/sql_olap.cc2
-rw-r--r--sql/sql_parse.cc4
-rw-r--r--sql/sql_prepare.cc2
-rw-r--r--sql/sql_select.cc15
-rw-r--r--sql/sql_show.cc18
-rw-r--r--sql/sql_table.cc12
-rw-r--r--sql/sql_union.cc7
-rw-r--r--sql/sql_update.cc2
-rw-r--r--sql/sql_yacc.yy2
-rw-r--r--sql/table.cc4
-rw-r--r--strings/ctype-mb.c2
-rw-r--r--support-files/mysql.spec.sh7
82 files changed, 1226 insertions, 277 deletions
diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok
index 785ea13b492..a7eb7c81105 100644
--- a/BitKeeper/etc/logging_ok
+++ b/BitKeeper/etc/logging_ok
@@ -5,6 +5,7 @@ Administrator@fred.
Miguel@light.local
Sinisa@sinisa.nasamreza.org
WAX@sergbook.mysql.com
+acurtis@pcgem.rdg.cyberkinetica.com
administrador@light.hegel.local
ahlentz@co3064164-a.rochd1.qld.optusnet.com.au
akishkin@work.mysql.com
diff --git a/client/mysql.cc b/client/mysql.cc
index 2ce0d769924..2cdcd23165e 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -44,7 +44,7 @@
#include <locale.h>
#endif
-const char *VER= "14.3";
+const char *VER= "14.4";
/* Don't try to make a nice table if the data is too big */
#define MAX_COLUMN_LENGTH 1024
@@ -134,7 +134,8 @@ static my_bool info_flag=0,ignore_errors=0,wait_flag=0,quick=0,
vertical=0, line_numbers=1, column_names=1,opt_html=0,
opt_xml=0,opt_nopager=1, opt_outfile=0, named_cmds= 0,
tty_password= 0, opt_nobeep=0, opt_reconnect=1,
- default_charset_used= 0, opt_secure_auth= 0;
+ default_charset_used= 0, opt_secure_auth= 0,
+ default_pager_set= 0;
static uint verbose=0,opt_silent=0,opt_mysql_port=0, opt_local_infile=0;
static my_string opt_mysql_unix_port=0;
static int connect_flag=CLIENT_INTERACTIVE;
@@ -173,9 +174,7 @@ static CHARSET_INFO *charset_info= &my_charset_latin1;
#include "sslopt-vars.h"
-#ifndef DBUG_OFF
const char *default_dbug_option="d:t:o,/tmp/mysql.trace";
-#endif
void tee_fprintf(FILE *file, const char *fmt, ...);
void tee_fputs(const char *s, FILE *file);
@@ -331,8 +330,11 @@ int main(int argc,char *argv[])
strmov(pager, "stdout"); // the default, if --pager wasn't given
{
char *tmp=getenv("PAGER");
- if (tmp)
- strmov(default_pager,tmp);
+ if (tmp && strlen(tmp))
+ {
+ default_pager_set= 1;
+ strmov(default_pager, tmp);
+ }
}
if (!isatty(0) || !isatty(1))
{
@@ -467,6 +469,8 @@ static struct my_option my_long_options[] =
{
{"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
0, 0, 0, 0, 0},
+ {"help", 'I', "Synonym for -?", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
+ 0, 0, 0, 0, 0},
{"auto-rehash", OPT_AUTO_REHASH,
"Enable automatic rehashing. One doesn't need to use 'rehash' to get table and field completion, but startup and reconnecting may take a longer time. Disable with --disable-auto-rehash.",
(gptr*) &rehash, (gptr*) &rehash, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
@@ -484,8 +488,11 @@ static struct my_option my_long_options[] =
{"compress", 'C', "Use compression in server/client protocol.",
(gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
0, 0, 0},
-#ifndef DBUG_OFF
- {"debug", '#', "Output debug log.", (gptr*) &default_dbug_option,
+#ifdef DBUG_OFF
+ {"debug", '#', "This is a non-debug version. Catch this and exit",
+ 0,0, 0, GET_DISABLED, OPT_ARG, 0, 0, 0, 0, 0, 0},
+#else
+ {"debug", '#', "Output debug log", (gptr*) &default_dbug_option,
(gptr*) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"database", 'D', "Database to use.", (gptr*) &current_db,
@@ -608,19 +615,27 @@ static struct my_option my_long_options[] =
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"wait", 'w', "Wait and retry if connection is down.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
- {"connect_timeout", OPT_CONNECT_TIMEOUT, "", (gptr*) &opt_connect_timeout,
+ {"connect_timeout", OPT_CONNECT_TIMEOUT,
+ "Number of seconds before connection timeout.",
+ (gptr*) &opt_connect_timeout,
(gptr*) &opt_connect_timeout, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 3600*12, 0,
0, 1},
- {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, "",
+ {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET,
+ "Max packet length to send to, or receive from server",
(gptr*) &max_allowed_packet, (gptr*) &max_allowed_packet, 0, GET_ULONG,
REQUIRED_ARG, 16 *1024L*1024L, 4096, (longlong) 2*1024L*1024L*1024L,
MALLOC_OVERHEAD, 1024, 0},
- {"net_buffer_length", OPT_NET_BUFFER_LENGTH, "",
+ {"net_buffer_length", OPT_NET_BUFFER_LENGTH,
+ "Buffer for TCP/IP and socket communication",
(gptr*) &net_buffer_length, (gptr*) &net_buffer_length, 0, GET_ULONG,
REQUIRED_ARG, 16384, 1024, 512*1024*1024L, MALLOC_OVERHEAD, 1024, 0},
- {"select_limit", OPT_SELECT_LIMIT, "", (gptr*) &select_limit,
+ {"select_limit", OPT_SELECT_LIMIT,
+ "Automatic limit for SELECT when using --safe-updates",
+ (gptr*) &select_limit,
(gptr*) &select_limit, 0, GET_ULONG, REQUIRED_ARG, 1000L, 1, ~0L, 0, 1, 0},
- {"max_join_size", OPT_MAX_JOIN_SIZE, "", (gptr*) &max_join_size,
+ {"max_join_size", OPT_MAX_JOIN_SIZE,
+ "Automatic limit for rows in a join when using --safe-updates",
+ (gptr*) &max_join_size,
(gptr*) &max_join_size, 0, GET_ULONG, REQUIRED_ARG, 1000000L, 1, ~0L, 0, 1,
0},
{"secure-auth", OPT_SECURE_AUTH, "Refuse client connecting to server if it"
@@ -689,11 +704,16 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
else
{
opt_nopager= 0;
- if (argument)
+ if (argument && strlen(argument))
+ {
+ default_pager_set= 1;
strmov(pager, argument);
- else
+ strmov(default_pager, pager);
+ }
+ else if (default_pager_set)
strmov(pager, default_pager);
- strmov(default_pager, pager);
+ else
+ opt_nopager= 1;
}
break;
case OPT_NOPAGER:
@@ -814,6 +834,7 @@ static int get_options(int argc, char **argv)
strmov(default_pager, "stdout");
strmov(pager, "stdout");
opt_nopager= 1;
+ default_pager_set= 0;
opt_outfile= 0;
opt_reconnect= 0;
connect_flag= 0; /* Not in interactive mode */
@@ -1535,7 +1556,7 @@ static int com_server_help(String *buffer __attribute__((unused)),
init_pager();
char last_char;
- int num_name, num_cat;
+ int num_name= 0, num_cat= 0;
LINT_INIT(num_name);
LINT_INIT(num_cat);
@@ -2163,12 +2184,17 @@ com_pager(String *buffer, char *line __attribute__((unused)))
if (status.batch)
return 0;
- /* Skip space from file name */
- while (my_isspace(charset_info,*line))
+ /* Skip spaces in front of the pager command */
+ while (my_isspace(charset_info, *line))
line++;
- if (!(param= strchr(line, ' '))) // if pager was not given, use the default
+ /* Skip the pager command */
+ param= strchr(line, ' ');
+ /* Skip the spaces between the command and the argument */
+ while (param && my_isspace(charset_info, *param))
+ param++;
+ if (!param || !strlen(param)) // if pager was not given, use the default
{
- if (!default_pager[0])
+ if (!default_pager_set)
{
tee_fprintf(stdout, "Default pager wasn't set, using stdout.\n");
opt_nopager=1;
@@ -2180,9 +2206,7 @@ com_pager(String *buffer, char *line __attribute__((unused)))
}
else
{
- while (my_isspace(charset_info,*param))
- param++;
- end=strmake(pager_name, param, sizeof(pager_name)-1);
+ end= strmake(pager_name, param, sizeof(pager_name)-1);
while (end > pager_name && (my_isspace(charset_info,end[-1]) ||
my_iscntrl(charset_info,end[-1])))
end--;
@@ -2191,7 +2215,7 @@ com_pager(String *buffer, char *line __attribute__((unused)))
strmov(default_pager, pager_name);
}
opt_nopager=0;
- tee_fprintf(stdout, "PAGER set to %s\n", pager);
+ tee_fprintf(stdout, "PAGER set to '%s'\n", pager);
return 0;
}
@@ -2202,6 +2226,7 @@ com_nopager(String *buffer __attribute__((unused)),
{
strmov(pager, "stdout");
opt_nopager=1;
+ PAGER= stdout;
tee_fprintf(stdout, "PAGER set to stdout\n");
return 0;
}
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 018cd43ce87..921ffbaab5b 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -37,7 +37,7 @@
** 10 Jun 2003: SET NAMES and --no-set-names by Alexander Barkov
*/
-#define DUMP_VERSION "10.4"
+#define DUMP_VERSION "10.5"
#include <my_global.h>
#include <my_sys.h>
@@ -107,7 +107,8 @@ static CHARSET_INFO *charset_info= &my_charset_latin1;
const char *compatible_mode_names[]=
{
"MYSQL323", "MYSQL40", "POSTGRESQL", "ORACLE", "MSSQL", "DB2",
- "SAPDB", "NO_KEY_OPTIONS", "NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS",
+ "MAXDB", "NO_KEY_OPTIONS", "NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS",
+ "ANSI",
NullS
};
TYPELIB compatible_mode_typelib= {array_elements(compatible_mode_names) - 1,
@@ -136,7 +137,7 @@ static struct my_option my_long_options[] =
"Directory where character sets are.", (gptr*) &charsets_dir,
(gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"compatible", OPT_COMPATIBLE,
- "Change the dump to be compatible with a given mode. By default tables are dumped without any restrictions. Legal modes are: mysql323, mysql40, postgresql, oracle, mssql, db2, sapdb, no_key_options, no_table_options, no_field_options. One can use several modes separated by commas. Note: Requires MySQL server version 4.1.0 or higher. This option does a no operation on earlier server versions.",
+ "Change the dump to be compatible with a given mode. By default tables are dumped without any restrictions. Legal modes are: ansi, mysql323, mysql40, postgresql, oracle, mssql, db2, maxdb, no_key_options, no_table_options, no_field_options. One can use several modes separated by commas. Note: Requires MySQL server version 4.1.0 or higher. This option does a no operation on earlier server versions.",
(gptr*) &opt_compatible_mode_str, (gptr*) &opt_compatible_mode_str, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"complete-insert", 'c', "Use complete insert statements.", (gptr*) &cFlag,
@@ -239,7 +240,7 @@ static struct my_option my_long_options[] =
{"quick", 'q', "Don't buffer query, dump directly to stdout.",
(gptr*) &quick, (gptr*) &quick, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
{"quote-names",'Q', "Quote table and column names with backticks (`).",
- (gptr*) &opt_quoted, (gptr*) &opt_quoted, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
+ (gptr*) &opt_quoted, (gptr*) &opt_quoted, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0,
0, 0},
{"result-file", 'r',
"Direct output to a given file. This option should be used in MSDOS, because it prevents new line '\\n' from being converted to '\\r\\n' (carriage return + line feed).",
@@ -830,7 +831,7 @@ static uint getTableStructure(char *table, char* db)
char *end;
uint i;
- sprintf(buff, "/*!41000 SET @@sql_mode=\"");
+ sprintf(buff, "/*!40100 SET @@sql_mode=\"");
end= strend(buff);
for (i= 0; opt_compatible_mode; opt_compatible_mode>>= 1, i++)
{
diff --git a/cmd-line-utils/libedit/Makefile.am b/cmd-line-utils/libedit/Makefile.am
index 19171f62ffb..eb6b930c0b2 100644
--- a/cmd-line-utils/libedit/Makefile.am
+++ b/cmd-line-utils/libedit/Makefile.am
@@ -24,10 +24,21 @@ noinst_HEADERS = chared.h el.h histedit.h key.h \
hist.h map.h prompt.h search.h \
strlcpy.h libedit_term.h tty.h
-EXTRA_DIST = makelist
+EXTRA_DIST = makelist.sh
+
+CLEANFILES = makelist
DEFS = -DUNDEF_THREADS_HACK -DHAVE_CONFIG_H -DNO_KILL_INTR
+SUFFIXES = .sh
+
+.sh:
+ @RM@ -f $@ $@-t
+ @SED@ \
+ -e 's!@''AWK''@!@AWK@!' \
+ $< > $@-t
+ @MV@ $@-t $@
+
vi.h: vi.c makelist
sh ./makelist -h ./vi.c > $@.tmp && \
mv $@.tmp $@
diff --git a/cmd-line-utils/libedit/makelist b/cmd-line-utils/libedit/makelist.sh
index 3c3338e9875..13d37512591 100644
--- a/cmd-line-utils/libedit/makelist
+++ b/cmd-line-utils/libedit/makelist.sh
@@ -39,7 +39,7 @@
# makelist.sh: Automatically generate header files...
-AWK=/usr/bin/awk
+AWK=@AWK@
USAGE="Usage: $0 -h|-e|-fc|-fh|-bc|-bh|-m <filenames>"
if [ "x$1" = "x" ]
diff --git a/include/my_getopt.h b/include/my_getopt.h
index 148238f8d1b..5f4025efa0e 100644
--- a/include/my_getopt.h
+++ b/include/my_getopt.h
@@ -17,11 +17,12 @@
C_MODE_START
enum get_opt_var_type { GET_NO_ARG, GET_BOOL, GET_INT, GET_UINT, GET_LONG,
- GET_ULONG, GET_LL, GET_ULL, GET_STR, GET_STR_ALLOC
+ GET_ULONG, GET_LL, GET_ULL, GET_STR, GET_STR_ALLOC,
+ GET_DISABLED
};
-#define GET_ASK_ADDR 128
-#define GET_TYPE_MASK 127
+#define GET_ASK_ADDR 128
+#define GET_TYPE_MASK 127
enum get_opt_arg_type { NO_ARG, OPT_ARG, REQUIRED_ARG };
diff --git a/include/mysql_embed.h b/include/mysql_embed.h
index df358e29872..7a169d4133e 100644
--- a/include/mysql_embed.h
+++ b/include/mysql_embed.h
@@ -32,6 +32,4 @@
#undef MYSQL_SERVER_SUFFIX
#define MYSQL_SERVER_SUFFIX "-embedded"
-#undef HAVE_QUERY_CACHE /* Cache dosn't work yet */
-
#endif /* EMBEDDED_LIBRARY */
diff --git a/include/mysys_err.h b/include/mysys_err.h
index 0ee89e91ee4..230be5f4720 100644
--- a/include/mysys_err.h
+++ b/include/mysys_err.h
@@ -68,6 +68,7 @@ extern const char * NEAR globerrs[]; /* my_error_messages is here */
#define EXIT_UNKNOWN_SUFFIX 9
#define EXIT_NO_PTR_TO_VARIABLE 10
#define EXIT_CANNOT_CONNECT_TO_SERVICE 11
+#define EXIT_OPTION_DISABLED 12
#ifdef __cplusplus
diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c
index d5472219d09..cf7a3efcdfc 100644
--- a/innobase/row/row0mysql.c
+++ b/innobase/row/row0mysql.c
@@ -1447,7 +1447,7 @@ row_create_table_for_mysql(
fprintf(stderr,
" InnoDB: Error: table %s already exists in InnoDB internal\n"
"InnoDB: data dictionary. Have you deleted the .frm file\n"
- "InnoDB: and not used DROPT ABLE? Have you used DROP DATABASE\n"
+ "InnoDB: and not used DROP TABLE? Have you used DROP DATABASE\n"
"InnoDB: for InnoDB tables in MySQL version <= 3.23.43?\n"
"InnoDB: See the Restrictions section of the InnoDB manual.\n",
table->name);
diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c
index 2215e3feff8..5a5da3ba59a 100644
--- a/innobase/row/row0sel.c
+++ b/innobase/row/row0sel.c
@@ -2773,6 +2773,18 @@ row_search_for_mysql(
ut_a(0);
}
+ if (trx->n_mysql_tables_in_use == 0) {
+ char err_buf[1000];
+
+ trx_print(err_buf, trx);
+
+ fprintf(stderr,
+"InnoDB: Error: MySQL is trying to perform a SELECT\n"
+"InnoDB: but it has not locked any tables in ::external_lock()!\n%s\n",
+ err_buf);
+ ut_a(0);
+ }
+
/* printf("Match mode %lu\n search tuple ", match_mode);
dtuple_print(search_tuple);
@@ -3072,6 +3084,18 @@ shortcut_fails_too_big_rec:
if (!prebuilt->sql_stat_start) {
/* No need to set an intention lock or assign a read view */
+ if (trx->read_view == NULL
+ && prebuilt->select_lock_type == LOCK_NONE) {
+ char err_buf[1000];
+
+ trx_print(err_buf, trx);
+
+ fprintf(stderr,
+"InnoDB: Error: MySQL is trying to perform a consistent read\n"
+"InnoDB: but the read view is not assigned!\n%s\n", err_buf);
+
+ ut_a(0);
+ }
} else if (prebuilt->select_lock_type == LOCK_NONE) {
/* This is a consistent read */
/* Assign a read view for the query */
diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c
index 027d7c8fb6e..d2368c5341f 100644
--- a/innobase/srv/srv0srv.c
+++ b/innobase/srv/srv0srv.c
@@ -2739,8 +2739,6 @@ loop:
cnt++;
- os_thread_sleep(2000000);
-
/* Try to track a strange bug reported by Harald Fuchs and others,
where the lsn seems to decrease at times */
@@ -2782,6 +2780,8 @@ loop:
fflush(stderr);
fflush(stdout);
+ os_thread_sleep(2000000);
+
if (srv_shutdown_state < SRV_SHUTDOWN_LAST_PHASE) {
goto loop;
diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c
index 9dd270b6e15..e6fdc95fad0 100644
--- a/innobase/srv/srv0start.c
+++ b/innobase/srv/srv0start.c
@@ -1512,12 +1512,13 @@ NetWare. */
srv_is_being_started = FALSE;
#ifdef UNIV_DEBUG
- /* Wait a while so that creates threads have time to suspend themselves
- before we switch sync debugging on; otherwise a thread may execute
- mutex_enter() before the checks are on, and mutex_exit() after the
- checks are on. */
+ /* Wait a while so that the created threads have time to suspend
+ themselves before we switch sync debugging on; otherwise a thread may
+ execute mutex_enter() before the checks are on, and mutex_exit() after
+ the checks are on, which will cause an assertion failure in sync
+ debug. */
- os_thread_sleep(2000000);
+ os_thread_sleep(3000000);
#endif
sync_order_checks_on = TRUE;
@@ -1638,8 +1639,9 @@ NetWare. */
fprintf(stderr,
"InnoDB: You have now successfully upgraded to the multiple tablespaces\n"
-"InnoDB: format. You should not downgrade again to an earlier version of\n"
-"InnoDB: InnoDB!\n");
+"InnoDB: format. You should NOT DOWNGRADE again to an earlier version of\n"
+"InnoDB: InnoDB! But if you absolutely need to downgrade, see section 4.6 of\n"
+"InnoDB: http://www.innodb.com/ibman.php for instructions.\n");
}
if (srv_force_recovery == 0) {
diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am
index 95cbd4ec826..e51fb5e315e 100644
--- a/libmysqld/Makefile.am
+++ b/libmysqld/Makefile.am
@@ -33,10 +33,10 @@ INCLUDES= @MT_INCLUDES@ @bdb_includes@ -I$(top_srcdir)/include \
noinst_LIBRARIES = libmysqld_int.a
pkglib_LIBRARIES = libmysqld.a
SUBDIRS = . examples
-libmysqld_sources= libmysqld.c lib_sql.cc
+libmysqld_sources= libmysqld.c lib_sql.cc emb_qcache.cc
libmysqlsources = errmsg.c get_password.c libmysql.c client.c pack.c
-noinst_HEADERS = embedded_priv.h
+noinst_HEADERS = embedded_priv.h emb_qcache.h
sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
ha_innodb.cc ha_berkeley.cc ha_heap.cc ha_isam.cc ha_isammrg.cc \
diff --git a/libmysqld/emb_qcache.cc b/libmysqld/emb_qcache.cc
new file mode 100644
index 00000000000..4dac154ab80
--- /dev/null
+++ b/libmysqld/emb_qcache.cc
@@ -0,0 +1,446 @@
+/* Copyright (C) 2000-2003 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "mysql_priv.h"
+#ifdef HAVE_QUERY_CACHE
+#include <mysql.h>
+#include "emb_qcache.h"
+
+void Querycache_stream::store_char(char c)
+{
+ if (data_end == cur_data)
+ use_next_block();
+ *(cur_data++)= c;
+#ifndef DBUG_OFF
+ stored_size++;
+#endif
+}
+
+void Querycache_stream::store_short(ushort s)
+{
+#ifndef DBUG_OFF
+ stored_size+= 2;
+#endif
+ if (data_end - cur_data > 1)
+ {
+ int2store(cur_data, s);
+ cur_data+= 2;
+ return;
+ }
+ if (data_end == cur_data)
+ {
+ use_next_block();
+ int2store(cur_data, s);
+ cur_data+= 2;
+ return;
+ }
+ *cur_data= ((byte *)(&s))[0];
+ use_next_block();
+ *(cur_data++)= ((byte *)(&s))[1];
+}
+
+void Querycache_stream::store_int(uint i)
+{
+#ifndef DBUG_OFF
+ stored_size+= 4;
+#endif
+ size_t rest_len= data_end - cur_data;
+ if (rest_len > 3)
+ {
+ int4store(cur_data, i);
+ cur_data+= 4;
+ return;
+ }
+ if (!rest_len)
+ {
+ use_next_block();
+ int4store(cur_data, i);
+ cur_data+= 4;
+ return;
+ }
+ memcpy(cur_data, &i, rest_len);
+ use_next_block();
+ memcpy(cur_data, ((byte*)&i)+rest_len, 4-rest_len);
+ cur_data+= 4-rest_len;
+}
+
+void Querycache_stream::store_ll(ulonglong ll)
+{
+#ifndef DBUG_OFF
+ stored_size+= 8;
+#endif
+ size_t rest_len= data_end - cur_data;
+ if (rest_len > 7)
+ {
+ int8store(cur_data, ll);
+ cur_data+= 8;
+ return;
+ }
+ if (!rest_len)
+ {
+ use_next_block();
+ int8store(cur_data, ll);
+ cur_data+= 8;
+ return;
+ }
+ memcpy(cur_data, &ll, rest_len);
+ use_next_block();
+ memcpy(cur_data, ((byte*)&ll)+rest_len, 8-rest_len);
+ cur_data+= 8-rest_len;
+}
+
+void Querycache_stream::store_str_only(const char *str, uint str_len)
+{
+#ifndef DBUG_OFF
+ stored_size+= str_len;
+#endif
+ do
+ {
+ size_t rest_len= data_end - cur_data;
+ if (rest_len > str_len)
+ {
+ memcpy(cur_data, str, str_len);
+ cur_data+= str_len;
+ return;
+ }
+ memcpy(cur_data, str, rest_len);
+ use_next_block();
+ str_len-= rest_len;
+ str+= rest_len;
+ } while(str_len);
+}
+
+void Querycache_stream::store_str(const char *str, uint str_len)
+{
+ store_int(str_len);
+ store_str_only(str, str_len);
+}
+
+void Querycache_stream::store_safe_str(const char *str, uint str_len)
+{
+ if (str)
+ {
+ store_int(str_len+1);
+ store_str_only(str, str_len);
+ }
+ else
+ store_int(0);
+}
+
+char Querycache_stream::load_char()
+{
+ if (cur_data == data_end)
+ use_next_block();
+ return *(cur_data++);
+}
+
+ushort Querycache_stream::load_short()
+{
+ ushort result;
+ if (data_end-cur_data > 1)
+ {
+ result= uint2korr(cur_data);
+ cur_data+= 2;
+ return result;
+ }
+ if (data_end == cur_data)
+ {
+ use_next_block();
+ result= uint2korr(cur_data);
+ cur_data+= 2;
+ return result;
+ }
+ ((byte*)&result)[0]= *cur_data;
+ use_next_block();
+ ((byte*)&result)[1]= *(cur_data++);
+ return result;
+}
+
+uint Querycache_stream::load_int()
+{
+ int result;
+ size_t rest_len= data_end - cur_data;
+ if (rest_len > 3)
+ {
+ result= uint4korr(cur_data);
+ cur_data+= 4;
+ return result;
+ }
+ if (!rest_len)
+ {
+ use_next_block();
+ result= uint4korr(cur_data);
+ cur_data+= 4;
+ return result;
+ }
+ memcpy(&result, cur_data, rest_len);
+ use_next_block();
+ memcpy(((byte*)&result)+rest_len, cur_data, 4-rest_len);
+ cur_data+= 4-rest_len;
+ return result;
+}
+
+ulonglong Querycache_stream::load_ll()
+{
+ ulonglong result;
+ size_t rest_len= data_end - cur_data;
+ if (rest_len > 7)
+ {
+ result= uint8korr(cur_data);
+ cur_data+= 8;
+ return result;
+ }
+ if (!rest_len)
+ {
+ use_next_block();
+ result= uint8korr(cur_data);
+ cur_data+= 8;
+ return result;
+ }
+ memcpy(&result, cur_data, rest_len);
+ use_next_block();
+ memcpy(((byte*)&result)+rest_len, cur_data, 8-rest_len);
+ cur_data+= 8-rest_len;
+ return result;
+}
+
+void Querycache_stream::load_str_only(char *buffer, uint str_len)
+{
+ do
+ {
+ size_t rest_len= data_end - cur_data;
+ if (rest_len > str_len)
+ {
+ memcpy(buffer, cur_data, str_len);
+ cur_data+= str_len;
+ buffer+= str_len;
+ break;
+ }
+ memcpy(buffer, cur_data, rest_len);
+ use_next_block();
+ str_len-= rest_len;
+ buffer+= rest_len;
+ } while(str_len);
+ *buffer= 0;
+}
+
+char *Querycache_stream::load_str(MEM_ROOT *alloc, uint *str_len)
+{
+ char *result;
+ *str_len= load_int();
+ if (!(result= alloc_root(alloc, *str_len + 1)))
+ return 0;
+ load_str_only(result, *str_len);
+ return result;
+}
+
+int Querycache_stream::load_safe_str(MEM_ROOT *alloc, char **str, uint *str_len)
+{
+ if (!(*str_len= load_int()))
+ {
+ *str= NULL;
+ return 0;
+ }
+ (*str_len)--;
+ if (!(*str= alloc_root(alloc, *str_len + 1)))
+ return 1;
+ load_str_only(*str, *str_len);
+ return 0;
+}
+
+int Querycache_stream::load_column(MEM_ROOT *alloc, char** column)
+{
+ int len;
+ if (!(len = load_int()))
+ {
+ *column= NULL;
+ return 0;
+ }
+ len--;
+ if (!(*column= (char *)alloc_root(alloc, len + 4 + 1)))
+ return 1;
+ int4store(*column, len);
+ (*column)+= 4;
+ load_str_only(*column, len);
+ return 1;
+}
+
+uint emb_count_querycache_size(THD *thd)
+{
+ uint result;
+ MYSQL *mysql= thd->mysql;
+ MYSQL_FIELD *field= mysql->fields;
+ MYSQL_FIELD *field_end= field + mysql->field_count;
+ MYSQL_ROWS *cur_row=NULL;
+ my_ulonglong n_rows=0;
+
+ if (!field)
+ return 0;
+ if (thd->data)
+ {
+ *thd->data->prev_ptr= NULL; // this marks the last record
+ cur_row= thd->data->data;
+ n_rows= thd->data->rows;
+ }
+ result= 4+8 + (42 + 4*n_rows)*mysql->field_count;
+
+ for(; field < field_end; field++)
+ {
+ result+= field->name_length + field->table_length +
+ field->org_name_length + field->org_table_length + field->db_length +
+ field->catalog_length;
+ if (field->def)
+ result+= field->def_length;
+ }
+
+ for (; cur_row; cur_row=cur_row->next)
+ {
+ MYSQL_ROW col= cur_row->data;
+ MYSQL_ROW col_end= col + mysql->field_count;
+ for (; col < col_end; col++)
+ if (*col)
+ result+= *(uint *)((*col) - sizeof(uint));
+ }
+ return result;
+}
+
+void emb_store_querycache_result(Querycache_stream *dst, THD *thd)
+{
+ MYSQL *mysql= thd->mysql;
+ MYSQL_FIELD *field= mysql->fields;
+ MYSQL_FIELD *field_end= field + mysql->field_count;
+ MYSQL_ROWS *cur_row= NULL;
+ my_ulonglong n_rows= 0;
+
+ if (!field)
+ return;
+
+ if (thd->data)
+ {
+ *thd->data->prev_ptr= NULL; // this marks the last record
+ cur_row= thd->data->data;
+ n_rows= thd->data->rows;
+ }
+
+ dst->store_int((uint)mysql->field_count);
+ dst->store_ll((uint)n_rows);
+
+ for(; field < field_end; field++)
+ {
+ dst->store_int((uint)field->length);
+ dst->store_int((uint)field->max_length);
+ dst->store_char((char)field->type);
+ dst->store_short((ushort)field->flags);
+ dst->store_short((ushort)field->charsetnr);
+ dst->store_char((char)field->decimals);
+ dst->store_str(field->name, field->name_length);
+ dst->store_str(field->table, field->table_length);
+ dst->store_str(field->org_name, field->org_name_length);
+ dst->store_str(field->org_table, field->org_table_length);
+ dst->store_str(field->db, field->db_length);
+ dst->store_str(field->catalog, field->catalog_length);
+
+ dst->store_safe_str(field->def, field->def_length);
+ }
+
+ for (; cur_row; cur_row=cur_row->next)
+ {
+ MYSQL_ROW col= cur_row->data;
+ MYSQL_ROW col_end= col + mysql->field_count;
+ for (; col < col_end; col++)
+ {
+ uint len= *col ? *(uint *)((*col) - sizeof(uint)) : 0;
+ dst->store_safe_str(*col, len);
+ }
+ }
+ DBUG_ASSERT(emb_count_querycache_size(thd) == dst->stored_size);
+}
+
+int emb_load_querycache_result(THD *thd, Querycache_stream *src)
+{
+ MYSQL *mysql= thd->mysql;
+ MYSQL_DATA *data;
+ MYSQL_FIELD *field;
+ MYSQL_FIELD *field_end;
+ MEM_ROOT *f_alloc= &mysql->field_alloc;
+ MYSQL_ROWS *row, *end_row;
+ MYSQL_ROWS **prev_row;
+ ulonglong rows;
+ MYSQL_ROW columns;
+
+ mysql->field_count= src->load_int();
+ rows= src->load_ll();
+
+ if (!(field= (MYSQL_FIELD *)
+ alloc_root(&mysql->field_alloc,mysql->field_count*sizeof(MYSQL_FIELD))))
+ goto err;
+ mysql->fields= field;
+ for(field_end= field+mysql->field_count; field < field_end; field++)
+ {
+ field->length= src->load_int();
+ field->max_length= (unsigned int)src->load_int();
+ field->type= (enum enum_field_types)src->load_char();
+ field->flags= (unsigned int)src->load_short();
+ field->charsetnr= (unsigned int)src->load_short();
+ field->decimals= (unsigned int)src->load_char();
+
+ if (!(field->name= src->load_str(f_alloc, &field->name_length)) ||
+ !(field->table= src->load_str(f_alloc,&field->table_length)) ||
+ !(field->org_name= src->load_str(f_alloc, &field->org_name_length)) ||
+ !(field->org_table= src->load_str(f_alloc, &field->org_table_length))||
+ !(field->db= src->load_str(f_alloc, &field->db_length)) ||
+ !(field->catalog= src->load_str(f_alloc, &field->catalog_length)) ||
+ src->load_safe_str(f_alloc, &field->def, &field->def_length))
+ goto err;
+ }
+
+ if (!rows)
+ return 0;
+ if (!(data= (MYSQL_DATA*)my_malloc(sizeof(MYSQL_DATA),
+ MYF(MY_WME | MY_ZEROFILL))))
+ goto err;
+ thd->data= data;
+ init_alloc_root(&data->alloc, 8192,0);
+ row= (MYSQL_ROWS *)alloc_root(&data->alloc, rows * sizeof(MYSQL_ROWS) +
+ rows * (mysql->field_count+1)*sizeof(char*));
+ end_row= row + rows;
+ columns= (MYSQL_ROW)end_row;
+
+ data->rows= rows;
+ data->fields= mysql->field_count;
+ data->data= row;
+
+ for (prev_row= &row->next; row < end_row; prev_row= &row->next, row++)
+ {
+ *prev_row= row;
+ row->data= columns;
+ MYSQL_ROW col_end= columns + mysql->field_count;
+ uint len;
+ for (; columns < col_end; columns++)
+ src->load_column(&data->alloc, columns);
+
+ *(columns++)= NULL;
+ }
+ *prev_row= NULL;
+ data->prev_ptr= prev_row;
+
+ return 0;
+err:
+ return 1;
+}
+
+#endif /*HAVE_QUERY_CACHE*/
+
diff --git a/libmysqld/emb_qcache.h b/libmysqld/emb_qcache.h
new file mode 100644
index 00000000000..32ce19847ff
--- /dev/null
+++ b/libmysqld/emb_qcache.h
@@ -0,0 +1,61 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+class Querycache_stream
+{
+ byte *cur_data;
+ byte *data_end;
+ Query_cache_block *block;
+ uint headers_len;
+public:
+#ifndef DBUG_OFF
+ uint stored_size;
+#endif
+ Querycache_stream(Query_cache_block *ini_block, uint ini_headers_len) :
+ block(ini_block), headers_len(ini_headers_len)
+ {
+ use_next_block();
+#ifndef DBUG_OFF
+ stored_size= 0;
+#endif
+ }
+ void use_next_block()
+ {
+ cur_data= ((byte*)block)+headers_len;
+ data_end= cur_data + (block->used-headers_len);
+ }
+
+ void store_char(char c);
+ void store_short(ushort s);
+ void store_int(uint i);
+ void store_ll(ulonglong ll);
+ void store_str_only(const char *str, uint str_len);
+ void store_str(const char *str, uint str_len);
+ void store_safe_str(const char *str, uint str_len);
+
+ char load_char();
+ ushort load_short();
+ uint load_int();
+ ulonglong load_ll();
+ void load_str_only(char *buffer, uint str_len);
+ char *load_str(MEM_ROOT *alloc, uint *str_len);
+ int load_safe_str(MEM_ROOT *alloc, char **str, uint *str_len);
+ int load_column(MEM_ROOT *alloc, char **column);
+};
+
+uint emb_count_querycache_size(THD *thd);
+int emb_load_querycache_result(THD *thd, Querycache_stream *src);
+void emb_store_querycache_result(Querycache_stream *dst, THD* thd);
diff --git a/libmysqld/embedded_priv.h b/libmysqld/embedded_priv.h
index 673531c0c14..1608f4ed4ad 100644
--- a/libmysqld/embedded_priv.h
+++ b/libmysqld/embedded_priv.h
@@ -23,9 +23,10 @@
#include <my_pthread.h>
C_MODE_START
-extern void lib_connection_phase(NET *net, int phase);
-extern void init_embedded_mysql(MYSQL *mysql, int client_flag, char *db);
-extern void *create_embedded_thd(int client_flag, char *db);
-extern MYSQL_METHODS embedded_methods;
+void lib_connection_phase(NET *net, int phase);
+void init_embedded_mysql(MYSQL *mysql, int client_flag, char *db);
+void *create_embedded_thd(int client_flag, char *db);
+int check_embedded_connection(MYSQL *mysql);
void free_old_query(MYSQL *mysql);
+extern MYSQL_METHODS embedded_methods;
C_MODE_END
diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc
index 365e9bc820a..2d451d6cecd 100644
--- a/libmysqld/lib_sql.cc
+++ b/libmysqld/lib_sql.cc
@@ -478,7 +478,17 @@ void *create_embedded_thd(int client_flag, char *db)
return thd;
}
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
+#ifdef NO_EMBEDDED_ACCESS_CHECKS
+int check_embedded_connection(MYSQL *mysql)
+{
+ THD *thd= (THD*)mysql->thd;
+ thd->host= (char*)my_localhost;
+ thd->host_or_ip= thd->host;
+ thd->user= mysql->user;
+ return 0;
+}
+
+#else
int check_embedded_connection(MYSQL *mysql)
{
THD *thd= (THD*)mysql->thd;
@@ -486,9 +496,13 @@ int check_embedded_connection(MYSQL *mysql)
char scramble_buff[SCRAMBLE_LENGTH];
int passwd_len;
- thd->host= mysql->options.client_ip ?
- mysql->options.client_ip : (char*)my_localhost;
- thd->ip= thd->host;
+ if (mysql->options.client_ip)
+ {
+ thd->host= mysql->options.client_ip;
+ thd->ip= thd->host;
+ }
+ else
+ thd->host= (char*)my_localhost;
thd->host_or_ip= thd->host;
if (acl_check_host(thd->host,thd->ip))
@@ -565,6 +579,9 @@ bool Protocol::send_fields(List<Item> *list, uint flag)
client_field->org_name_length= strlen(client_field->org_name);
client_field->org_table_length= strlen(client_field->org_table);
client_field->charsetnr= server_field.charsetnr;
+
+ client_field->catalog= strdup_root(field_alloc, "std");
+ client_field->catalog_length= 3;
if (INTERNAL_NUM_FIELD(client_field))
client_field->flags|= NUM_FLAG;
@@ -575,9 +592,15 @@ bool Protocol::send_fields(List<Item> *list, uint flag)
String tmp(buff, sizeof(buff), default_charset_info), *res;
if (!(res=item->val_str(&tmp)))
+ {
client_field->def= strdup_root(field_alloc, "");
+ client_field->def_length= 0;
+ }
else
+ {
client_field->def= strdup_root(field_alloc, tmp.ptr());
+ client_field->def_length= tmp.length();
+ }
}
else
client_field->def=0;
diff --git a/libmysqld/libmysqld.c b/libmysqld/libmysqld.c
index 69fdf14eca4..95f745aef5f 100644
--- a/libmysqld/libmysqld.c
+++ b/libmysqld/libmysqld.c
@@ -124,17 +124,14 @@ static inline int mysql_init_charset(MYSQL *mysql)
return 0;
}
-int check_embedded_connection(MYSQL *mysql);
-
MYSQL * STDCALL
mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
const char *passwd, const char *db,
uint port, const char *unix_socket,ulong client_flag)
{
char *db_name;
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
char name_buff[USERNAME_LENGTH];
-#endif
+
DBUG_ENTER("mysql_real_connect");
DBUG_PRINT("enter",("host: %s db: %s user: %s",
host ? host : "(Null)",
@@ -165,10 +162,10 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
if (!db || !db[0])
db=mysql->options.db;
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (!user || !user[0])
user=mysql->options.user;
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (!passwd)
{
passwd=mysql->options.password;
@@ -177,16 +174,18 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
passwd=getenv("MYSQL_PWD"); /* get it from environment */
#endif
}
+ mysql->passwd= passwd ? my_strdup(passwd,MYF(0)) : NULL;
+#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/
if (!user || !user[0])
{
read_user_name(name_buff);
- if (!name_buff[0])
+ if (name_buff[0])
user= name_buff;
}
+ if (!user)
+ user= "";
mysql->user=my_strdup(user,MYF(0));
- mysql->passwd= passwd ? my_strdup(passwd,MYF(0)) : NULL;
-#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/
port=0;
unix_socket=0;
@@ -196,10 +195,8 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
init_embedded_mysql(mysql, client_flag, db_name);
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_embedded_connection(mysql))
goto error;
-#endif
if (mysql_init_charset(mysql))
goto error;
diff --git a/myisam/mi_check.c b/myisam/mi_check.c
index a55929805fa..5687e7d48e3 100644
--- a/myisam/mi_check.c
+++ b/myisam/mi_check.c
@@ -551,7 +551,7 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
ha_checksum *key_checksum, uint level)
{
int flag;
- uint used_length,comp_flag,nod_flag,key_length,not_used;
+ uint used_length,comp_flag,nod_flag,key_length=0,not_used;
uchar key[MI_MAX_POSSIBLE_KEY_BUFF],*temp_buff,*keypos,*old_keypos,*endpos;
my_off_t next_page,record;
char llbuff[22];
@@ -586,6 +586,8 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
}
for ( ;; )
{
+ memcpy((char*) info->lastkey,(char*) key,key_length);
+ info->lastkey_length=key_length;
if (nod_flag)
{
next_page=_mi_kpos(nod_flag,keypos);
@@ -629,8 +631,6 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
}
(*key_checksum)+= mi_byte_checksum((byte*) key,
key_length- info->s->rec_reflength);
- memcpy((char*) info->lastkey,(char*) key,key_length);
- info->lastkey_length=key_length;
record= _mi_dpos(info,0,key+key_length);
if (keyinfo->flag & HA_FULLTEXT) /* special handling for ft2 */
{
@@ -658,7 +658,7 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
DBUG_PRINT("test",("page: %s record: %s filelength: %s",
llstr(page,llbuff),llstr(record,llbuff2),
llstr(info->state->data_file_length,llbuff3)));
- DBUG_DUMP("key",(byte*) info->lastkey,key_length);
+ DBUG_DUMP("key",(byte*) key,key_length);
DBUG_DUMP("new_in_page",(char*) old_keypos,(uint) (keypos-old_keypos));
goto err;
}
diff --git a/myisam/mi_write.c b/myisam/mi_write.c
index d13ba6c2c4e..060d4431de6 100644
--- a/myisam/mi_write.c
+++ b/myisam/mi_write.c
@@ -378,7 +378,7 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
my_off_t root=info->dupp_key_pos;
keyinfo=&info->s->ft2_keyinfo;
key+=off;
- keypos-=keyinfo->keylength; /* we'll modify key entry 'in vivo' */
+ keypos-=keyinfo->keylength+nod_flag; /* we'll modify key entry 'in vivo' */
error=_mi_ck_real_write_btree(info, keyinfo, key, 0,
&root, comp_flag);
_mi_dpointer(info, keypos+HA_FT_WLEN, root);
diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh
index 265ff036998..3f7efd3d6bc 100644
--- a/mysql-test/mysql-test-run.sh
+++ b/mysql-test/mysql-test-run.sh
@@ -603,7 +603,7 @@ error () {
error_is () {
$ECHO "Errors are (from $TIMEFILE) :"
$CAT < $TIMEFILE
- $ECHO "(the last line(s) may be the ones that caused the die() in mysqltest)"
+ $ECHO "(the last lines may be the most important ones)"
}
prefix_to_8() {
@@ -1309,6 +1309,9 @@ run_testcase ()
skip_inc
$ECHO "$RES$RES_SPACE [ skipped ]"
else
+ if [ $res -gt 2 ]; then
+ $ECHO "mysqltest returned unexpected code $res, it has probably crashed" >> $TIMEFILE
+ fi
total_inc
fail_inc
$ECHO "$RES$RES_SPACE [ fail ]"
diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result
index 7ec12c1b021..33af0b30d1c 100644
--- a/mysql-test/r/alter_table.result
+++ b/mysql-test/r/alter_table.result
@@ -412,3 +412,12 @@ t1 0 PRIMARY 1 Host A NULL NULL NULL BTREE
t1 0 PRIMARY 2 User A 0 NULL NULL BTREE
t1 1 Host 1 Host A NULL NULL NULL BTREE disabled
DROP TABLE t1;
+CREATE TABLE t1 (a int UNIQUE);
+ALTER TABLE t1 DROP PRIMARY KEY;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) default NULL,
+ UNIQUE KEY `a` (`a`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
diff --git a/mysql-test/r/ctype_recoding.result b/mysql-test/r/ctype_recoding.result
index 571c89ef467..7209c86bb31 100644
--- a/mysql-test/r/ctype_recoding.result
+++ b/mysql-test/r/ctype_recoding.result
@@ -19,6 +19,12 @@ SELECT HEX(a) FROM t2;
HEX(a)
D0BFD180D0BED0B1D0B0
DROP TABLE t1, t2;
+CREATE TABLE t1 (description text character set cp1250 NOT NULL);
+INSERT INTO t1 (description) VALUES (_latin2'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasssssssssssaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddde');
+SELECT description FROM t1;
+description
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasssssssssssaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddde
+DROP TABLE t1;
CREATE TABLE t1 (a TEXT CHARACTER SET cp1251) SELECT _koi8r'ĐÒÏÂÁ' AS a;
CREATE TABLE t2 (a TEXT CHARACTER SET utf8);
SHOW CREATE TABLE t1;
diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result
index 2f6dc0c23ca..58761526150 100644
--- a/mysql-test/r/ctype_ucs.result
+++ b/mysql-test/r/ctype_ucs.result
@@ -173,6 +173,12 @@ SELECT * FROM t1 WHERE word LIKE _ucs2 x'00630061005F';
word
cat
DROP TABLE t1;
+select insert(_ucs2 0x006100620063,10,2,_ucs2 0x006400650066);
+insert(_ucs2 0x006100620063,10,2,_ucs2 0x006400650066)
+abc
+select insert(_ucs2 0x006100620063,1,2,_ucs2 0x006400650066);
+insert(_ucs2 0x006100620063,1,2,_ucs2 0x006400650066)
+defc
SET NAMES latin1;
CREATE TABLE t1 (
word VARCHAR(64),
diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result
index 1aef43cd570..7c05b1ea446 100644
--- a/mysql-test/r/ctype_utf8.result
+++ b/mysql-test/r/ctype_utf8.result
@@ -1,3 +1,4 @@
+drop table if exists t1;
set names utf8;
select left(_utf8 0xD0B0D0B1D0B2,1);
left(_utf8 0xD0B0D0B1D0B2,1)
@@ -62,3 +63,19 @@ select 'A' like 'a' collate utf8_bin;
select _utf8 0xD0B0D0B1D0B2 like concat(_utf8'%',_utf8 0xD0B1,_utf8 '%');
_utf8 0xD0B0D0B1D0B2 like concat(_utf8'%',_utf8 0xD0B1,_utf8 '%')
1
+select insert('txs',2,1,'hi'),insert('is ',4,0,'a'),insert('txxxxt',2,4,'es');
+insert('txs',2,1,'hi') insert('is ',4,0,'a') insert('txxxxt',2,4,'es')
+this is a test
+select insert("aa",100,1,"b"),insert("aa",1,3,"b");
+insert("aa",100,1,"b") insert("aa",1,3,"b")
+aa b
+create table t1 select date_format("2004-01-19 10:10:10", "%Y-%m-%d");
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `date_format("2004-01-19 10:10:10", "%Y-%m-%d")` char(4) character set utf8 default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+select * from t1;
+date_format("2004-01-19 10:10:10", "%Y-%m-%d")
+2004-01-19
+drop table t1;
diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result
index bb268cd1094..c0d2ce287db 100644
--- a/mysql-test/r/derived.result
+++ b/mysql-test/r/derived.result
@@ -85,6 +85,10 @@ a b
2 b
3 c
3 c
+select * from (select * from t1 union all select * from t1 limit 2) a;
+a b
+1 a
+2 b
explain select * from (select * from t1 union select * from t1) a;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3
@@ -245,3 +249,27 @@ id select_type table type possible_keys key key_len ref rows Extra
2 DERIVED t1 ALL NULL NULL NULL NULL 2
3 UNION t1 ALL NULL NULL NULL NULL 2
drop table t1;
+CREATE TABLE t1 (
+OBJECTID int(11) NOT NULL default '0',
+SORTORDER int(11) NOT NULL auto_increment,
+KEY t1_SortIndex (SORTORDER),
+KEY t1_IdIndex (OBJECTID)
+) TYPE=MyISAM DEFAULT CHARSET=latin1;
+Warnings:
+Warning 1286 'TYPE=storage_engine' is deprecated. Use 'ENGINE=storage_engine' instead.
+CREATE TABLE t2 (
+ID int(11) default NULL,
+PARID int(11) default NULL,
+UNIQUE KEY t2_ID_IDX (ID),
+KEY t2_PARID_IDX (PARID)
+) engine=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO t2 VALUES (1000,0),(1001,0),(1002,0),(1003,0),(1008,1),(1009,1),(1010,1),(1011,1),(1016,2);
+CREATE TABLE t3 (
+ID int(11) default NULL,
+DATA decimal(10,2) default NULL,
+UNIQUE KEY t3_ID_IDX (ID)
+) engine=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO t3 VALUES (1000,0.00),(1001,0.25),(1002,0.50),(1003,0.75),(1008,1.00),(1009,1.25),(1010,1.50),(1011,1.75);
+select 497, TMP.ID, NULL from (select 497 as ID, MAX(t3.DATA) as DATA from t1 join t2 on (t1.ObjectID = t2.ID) join t3 on (t1.ObjectID = t3.ID) group by t2.ParID order by DATA DESC) as TMP;
+497 ID NULL
+drop table t1, t2, t3;
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result
index c74feccfb7f..f08ae1b1efd 100644
--- a/mysql-test/r/func_str.result
+++ b/mysql-test/r/func_str.result
@@ -605,3 +605,6 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select high_priority md5(_latin1'hello') AS `md5('hello')`,sha(_latin1'abc') AS `sha('abc')`,sha(_latin1'abc') AS `sha1('abc')`,soundex(_latin1'') AS `soundex('')`,(soundex(_latin1'mood') = soundex(_latin1'mud')) AS `'mood' sounds like 'mud'`,aes_decrypt(aes_encrypt(_latin1'abc',_latin1'1'),_latin1'1') AS `aes_decrypt(aes_encrypt('abc','1'),'1')`,concat(_latin1'*',repeat(_latin1' ',5),_latin1'*') AS `concat('*',space(5),'*')`,reverse(_latin1'abc') AS `reverse('abc')`,rpad(_latin1'a',4,_latin1'1') AS `rpad('a',4,'1')`,lpad(_latin1'a',4,_latin1'1') AS `lpad('a',4,'1')`,concat_ws(_latin1',',_latin1'',NULL,_latin1'a') AS `concat_ws(',','',NULL,'a')`,make_set(255,_latin2'a',_latin2'b',_latin2'c') AS `make_set(255,_latin2'a',_latin2'b',_latin2'c')`,elt(2,1) AS `elt(2,1)`,locate(_latin1'a',_latin1'b',2) AS `locate("a","b",2)`,format(130,10) AS `format(130,10)`,char(0) AS `char(0)`,conv(130,16,10) AS `conv(130,16,10)`,hex(130) AS `hex(130)`,(_latin1'HE' collate _latin1'BINARY') AS `binary 'HE'`,export_set(255,_latin2'y',_latin2'n',_latin2' ') AS `export_set(255,_latin2'y',_latin2'n',_latin2' ')`,field((_latin1'b' collate _latin1'latin1_bin'),_latin1'A',_latin1'B') AS `FIELD('b' COLLATE latin1_bin,'A','B')`,find_in_set(_latin1'B',_latin1'a,b,c,d') AS `FIND_IN_SET(_latin1'B',_latin1'a,b,c,d')`,collation(conv(130,16,10)) AS `collation(conv(130,16,10))`,coercibility(conv(130,16,10)) AS `coercibility(conv(130,16,10))`,length(_latin1'\n \r\0\\_\\%\\') AS `length('\n\t\r\b\0\_\%\\')`,bit_length(_latin1'\n \r\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`,bit_length(_latin1'\n \r\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`,concat(_latin1'monty',_latin1' was here ',_latin1'again') AS `concat('monty',' was here ','again')`,length(_latin1'hello') AS `length('hello')`,char(ascii(_latin1'h')) AS `char(ascii('h'))`,ord(_latin1'h') AS `ord('h')`,quote((1 / 0)) AS `quote(1/0)`,crc32(_latin1'123') AS `crc32("123")`,replace(_latin1'aaaa',_latin1'a',_latin1'b') AS `replace('aaaa','a','b')`,insert(_latin1'txs',2,1,_latin1'hi') AS `insert('txs',2,1,'hi')`,left(_latin2'a',1) AS `left(_latin2'a',1)`,right(_latin2'a',1) AS `right(_latin2'a',1)`,lcase(_latin2'a') AS `lcase(_latin2'a')`,ucase(_latin2'a') AS `ucase(_latin2'a')`,substr(_latin1'abcdefg',3,2) AS `SUBSTR('abcdefg',3,2)`,substr_index(_latin1'1abcd;2abcd;3abcd;4abcd',_latin1';',2) AS `substring_index("1abcd;2abcd;3abcd;4abcd", ';', 2)`,trim(_latin2' a ') AS `trim(_latin2' a ')`,ltrim(_latin2' a ') AS `ltrim(_latin2' a ')`,rtrim(_latin2' a ') AS `rtrim(_latin2' a ')`,decode(encode(repeat(_latin1'a',100000))) AS `decode(encode(repeat("a",100000),"monty"),"monty")`
+SELECT lpad(12345, 5, "#");
+lpad(12345, 5, "#")
+12345
diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result
index 04effdfef7c..f51caee39d6 100644
--- a/mysql-test/r/mysqldump.result
+++ b/mysql-test/r/mysqldump.result
@@ -21,17 +21,17 @@ DROP TABLE t1;
CREATE TABLE t1 (a decimal(240, 20));
INSERT INTO t1 VALUES ("1234567890123456789012345678901234567890"),
("0987654321098765432109876543210987654321");
-DROP TABLE IF EXISTS t1;
-CREATE TABLE t1 (
- a decimal(240,20) default NULL
+DROP TABLE IF EXISTS `t1`;
+CREATE TABLE `t1` (
+ `a` decimal(240,20) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
-/*!40000 ALTER TABLE t1 DISABLE KEYS */;
-LOCK TABLES t1 WRITE;
-INSERT INTO t1 VALUES ("1234567890123456789012345678901234567890.00000000000000000000"),("0987654321098765432109876543210987654321.00000000000000000000");
+/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
+LOCK TABLES `t1` WRITE;
+INSERT INTO `t1` VALUES ("1234567890123456789012345678901234567890.00000000000000000000"),("0987654321098765432109876543210987654321.00000000000000000000");
UNLOCK TABLES;
-/*!40000 ALTER TABLE t1 ENABLE KEYS */;
+/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
@@ -41,17 +41,17 @@ UNLOCK TABLES;
DROP TABLE t1;
CREATE TABLE t1 (a double);
INSERT INTO t1 VALUES (-9e999999);
-DROP TABLE IF EXISTS t1;
-CREATE TABLE t1 (
- a double default NULL
+DROP TABLE IF EXISTS `t1`;
+CREATE TABLE `t1` (
+ `a` double default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
-/*!40000 ALTER TABLE t1 DISABLE KEYS */;
-LOCK TABLES t1 WRITE;
-INSERT INTO t1 VALUES (RES);
+/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
+LOCK TABLES `t1` WRITE;
+INSERT INTO `t1` VALUES (RES);
UNLOCK TABLES;
-/*!40000 ALTER TABLE t1 ENABLE KEYS */;
+/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
@@ -105,17 +105,17 @@ INSERT INTO t1 VALUES ("1\""), ("\"2");
DROP TABLE t1;
CREATE TABLE t1 (a VARCHAR(255)) DEFAULT CHARSET koi8r;
INSERT INTO t1 VALUES (_koi8r x'C1C2C3C4C5');
-DROP TABLE IF EXISTS t1;
-CREATE TABLE t1 (
- a varchar(255) default NULL
+DROP TABLE IF EXISTS `t1`;
+CREATE TABLE `t1` (
+ `a` varchar(255) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=koi8r;
-/*!40000 ALTER TABLE t1 DISABLE KEYS */;
-LOCK TABLES t1 WRITE;
-INSERT INTO t1 VALUES ('абцЎД');
+/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
+LOCK TABLES `t1` WRITE;
+INSERT INTO `t1` VALUES ('абцЎД');
UNLOCK TABLES;
-/*!40000 ALTER TABLE t1 ENABLE KEYS */;
+/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
diff --git a/mysql-test/r/null.result b/mysql-test/r/null.result
index c4af221e117..aa56bce6453 100644
--- a/mysql-test/r/null.result
+++ b/mysql-test/r/null.result
@@ -153,3 +153,6 @@ explain select * from t1 where a between 2 and 3 or b is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range idx idx 4 NULL 2 Using where
drop table t1;
+select cast(NULL as signed);
+cast(NULL as signed)
+NULL
diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result
index fe2ded691d4..49ae082dead 100644
--- a/mysql-test/r/query_cache.result
+++ b/mysql-test/r/query_cache.result
@@ -816,4 +816,12 @@ show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 4
DROP TABLE t1;
+CREATE TABLE t1 (a int(1));
+CREATE DATABASE mysqltest;
+USE mysqltest;
+DROP DATABASE mysqltest;
+SELECT * FROM test.t1;
+a
+USE test;
+DROP TABLE t1;
SET GLOBAL query_cache_size=0;
diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result
index f39fa3e7576..290f916ae72 100644
--- a/mysql-test/r/show_check.result
+++ b/mysql-test/r/show_check.result
@@ -88,20 +88,37 @@ drop table t2;
create table t1 (
test_set set( 'val1', 'val2', 'val3' ) not null default '',
name char(20) default 'O''Brien' comment 'O''Brien as default',
-c int not null comment 'int column'
- ) comment = 'it\'s a table' ;
-show create table t1 ;
+c int not null comment 'int column',
+`c-b` int comment 'name with a space',
+`space ` int comment 'name with a space',
+) comment = 'it\'s a table' ;
+show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`test_set` set('val1','val2','val3') NOT NULL default '',
`name` char(20) default 'O''Brien' COMMENT 'O''Brien as default',
- `c` int(11) NOT NULL default '0' COMMENT 'int column'
+ `c` int(11) NOT NULL default '0' COMMENT 'int column',
+ `c-b` int(11) default NULL COMMENT 'name with a space',
+ `space ` int(11) default NULL COMMENT 'name with a space'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='it''s a table'
+set sql_quote_show_create=0;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE t1 (
+ test_set set('val1','val2','val3') NOT NULL default '',
+ name char(20) default 'O''Brien' COMMENT 'O''Brien as default',
+ c int(11) NOT NULL default '0' COMMENT 'int column',
+ `c-b` int(11) default NULL COMMENT 'name with a space',
+ `space ` int(11) default NULL COMMENT 'name with a space'
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='it''s a table'
+set sql_quote_show_create=1;
show full columns from t1;
Field Type Collation Null Key Default Extra Privileges Comment
test_set set('val1','val2','val3') latin1_swedish_ci select,insert,update,references
name char(20) latin1_swedish_ci YES O'Brien select,insert,update,references O'Brien as default
c int(11) NULL 0 select,insert,update,references int column
+c-b int(11) NULL YES NULL select,insert,update,references name with a space
+space int(11) NULL YES NULL select,insert,update,references name with a space
drop table t1;
create table t1 (a int not null, unique aa (a));
show create table t1;
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index 672a39299dd..ded98265a1c 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -1569,3 +1569,12 @@ INSERT INTO t2 VALUES (100, 200, 'C');
SELECT DISTINCT COLC FROM t1 WHERE COLA = (SELECT COLA FROM t2 WHERE COLB = 200 AND COLC ='C' LIMIT 1);
COLC
DROP TABLE t1, t2;
+create table t1 (a int, b decimal(13, 3));
+insert into t1 values (1, 0.123);
+select a, (select max(b) from t1) into outfile "subselect.out.file.1" from t1;
+delete from t1;
+load data infile "subselect.out.file.1" into table t1;
+select * from t1;
+a b
+1 0.123
+drop table t1;
diff --git a/mysql-test/r/subselect_innodb.result b/mysql-test/r/subselect_innodb.result
index 6729916f1c8..b2a055fa72c 100644
--- a/mysql-test/r/subselect_innodb.result
+++ b/mysql-test/r/subselect_innodb.result
@@ -60,6 +60,39 @@ INSERT INTO t2 VALUES (1,1),(2,2),(3,3);
SELECT distinct p1.processor_id, (SELECT y.yod_id FROM t1 p2, t2 y WHERE p2.processor_id = p1.processor_id and p2.processor_id = y.processor_id) FROM t1 p1;
processor_id (SELECT y.yod_id FROM t1 p2, t2 y WHERE p2.processor_id = p1.processor_id and p2.processor_id = y.processor_id)
1 1
-2 1
-3 1
+2 2
+3 3
drop table t1,t2,t3;
+CREATE TABLE t1 (
+id int(11) NOT NULL default '0',
+b int(11) default NULL,
+c char(3) default NULL,
+PRIMARY KEY (id),
+KEY t2i1 (b)
+) ENGINE=innodb DEFAULT CHARSET=latin1;
+INSERT INTO t1 VALUES (0,0,'GPL'),(1,0,'GPL'),(2,1,'GPL'),(3,2,'GPL');
+CREATE TABLE t2 (
+id int(11) NOT NULL default '0',
+b int(11) default NULL,
+c char(3) default NULL,
+PRIMARY KEY (id),
+KEY t2i (b)
+) ENGINE=innodb DEFAULT CHARSET=latin1;
+INSERT INTO t2 VALUES (0,0,'GPL'),(1,0,'GPL'),(2,1,'GPL'),(3,2,'GPL');
+select (select max(id) from t2 where b=1 group by b) as x,b from t1 where b=1;
+x b
+2 1
+drop table t1,t2;
+create table t1 (id int not null, value char(255), primary key(id)) engine=innodb;
+create table t2 (id int not null, value char(255)) engine=innodb;
+insert into t1 values (1,'a'),(2,'b');
+insert into t2 values (1,'z'),(2,'x');
+select t2.id,t2.value,(select t1.value from t1 where t1.id=t2.id) from t2;
+id value (select t1.value from t1 where t1.id=t2.id)
+1 z a
+2 x b
+select t2.id,t2.value,(select t1.value from t1 where t1.id=t2.id) from t2;
+id value (select t1.value from t1 where t1.id=t2.id)
+1 z a
+2 x b
+drop table t1,t2;
diff --git a/mysql-test/r/symlink.result b/mysql-test/r/symlink.result
index 4ba0ca0eac4..6dc48a0a77e 100644
--- a/mysql-test/r/symlink.result
+++ b/mysql-test/r/symlink.result
@@ -66,7 +66,7 @@ t9 CREATE TABLE `t9` (
drop database mysqltest;
create table t1 (a int not null) type=myisam;
Warnings:
-Warning 1286 'TYPE=database_engine' is deprecated. Use 'ENGINE=database_engine' instead.
+Warning 1286 'TYPE=storage_engine' is deprecated. Use 'ENGINE=storage_engine' instead.
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
diff --git a/mysql-test/r/warnings.result b/mysql-test/r/warnings.result
index 5c7c75bac00..c3d9f165fed 100644
--- a/mysql-test/r/warnings.result
+++ b/mysql-test/r/warnings.result
@@ -128,10 +128,10 @@ Warning 1265 Using storage engine MyISAM for table 't1'
drop table t1;
create table t1 (id int) type=heap;
Warnings:
-Warning 1286 'TYPE=database_engine' is deprecated. Use 'ENGINE=database_engine' instead.
+Warning 1286 'TYPE=storage_engine' is deprecated. Use 'ENGINE=storage_engine' instead.
alter table t1 type=myisam;
Warnings:
-Warning 1286 'TYPE=database_engine' is deprecated. Use 'ENGINE=database_engine' instead.
+Warning 1286 'TYPE=storage_engine' is deprecated. Use 'ENGINE=storage_engine' instead.
drop table t1;
set table_type=MYISAM;
Warnings:
diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test
index eab4fd7f5f0..71991973105 100644
--- a/mysql-test/t/alter_table.test
+++ b/mysql-test/t/alter_table.test
@@ -244,3 +244,12 @@ LOCK TABLES t1 WRITE;
ALTER TABLE t1 DISABLE KEYS;
SHOW INDEX FROM t1;
DROP TABLE t1;
+
+#
+# Bug 2361
+#
+
+CREATE TABLE t1 (a int UNIQUE);
+ALTER TABLE t1 DROP PRIMARY KEY;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
diff --git a/mysql-test/t/ctype_recoding.test b/mysql-test/t/ctype_recoding.test
index 0b901009041..40349da8aa9 100644
--- a/mysql-test/t/ctype_recoding.test
+++ b/mysql-test/t/ctype_recoding.test
@@ -14,6 +14,15 @@ INSERT t2 SELECT * FROM t1;
SELECT HEX(a) FROM t2;
DROP TABLE t1, t2;
+
+#
+# Check that long strings conversion does not fail (bug#2218)
+#
+CREATE TABLE t1 (description text character set cp1250 NOT NULL);
+INSERT INTO t1 (description) VALUES (_latin2'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasssssssssssaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddde');
+SELECT description FROM t1;
+DROP TABLE t1;
+
# same with TEXT
CREATE TABLE t1 (a TEXT CHARACTER SET cp1251) SELECT _koi8r'ĐÒÏÂÁ' AS a;
CREATE TABLE t2 (a TEXT CHARACTER SET utf8);
@@ -62,3 +71,4 @@ SET NAMES koi8r;
SELECT hex('ÔĆÓÔ');
SET character_set_connection=cp1251;
SELECT hex('ÔĆÓÔ');
+
diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test
index 90b423cd1e0..7eec58563b3 100644
--- a/mysql-test/t/ctype_ucs.test
+++ b/mysql-test/t/ctype_ucs.test
@@ -93,6 +93,12 @@ SELECT * FROM t1 WHERE word LIKE _ucs2 x'00630025';
SELECT * FROM t1 WHERE word LIKE _ucs2 x'00630061005F';
DROP TABLE t1;
+#
+# Check that INSERT works fine.
+# This invokes charpos() function.
+select insert(_ucs2 0x006100620063,10,2,_ucs2 0x006400650066);
+select insert(_ucs2 0x006100620063,1,2,_ucs2 0x006400650066);
+
######################################################
#
@@ -191,4 +197,3 @@ DROP TABLE t1;
# END OF Bug 1264 test
#
########################################################
-
diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test
index 54d934b66db..5e9324dd68f 100644
--- a/mysql-test/t/ctype_utf8.test
+++ b/mysql-test/t/ctype_utf8.test
@@ -2,6 +2,9 @@
# Tests with the utf8 character set
#
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
set names utf8;
select left(_utf8 0xD0B0D0B1D0B2,1);
@@ -35,3 +38,18 @@ select _utf8 0xD0B0D0B1D0B2 like concat(_utf8'%',_utf8 0xD0B1,_utf8 '%');
#
#select _utf8 0xD0B0D0B1D0B2 like concat(_utf8'%',_utf8 0xD091,_utf8 '%');
#
+
+#
+# Bug 2367: INSERT() behaviour is different for different charsets.
+#
+select insert('txs',2,1,'hi'),insert('is ',4,0,'a'),insert('txxxxt',2,4,'es');
+select insert("aa",100,1,"b"),insert("aa",1,3,"b");
+
+#
+# CREATE ... SELECT
+#
+create table t1 select date_format("2004-01-19 10:10:10", "%Y-%m-%d");
+show create table t1;
+select * from t1;
+drop table t1;
+
diff --git a/mysql-test/t/derived.test b/mysql-test/t/derived.test
index caf673d95c1..8de95b4b600 100644
--- a/mysql-test/t/derived.test
+++ b/mysql-test/t/derived.test
@@ -35,6 +35,7 @@ select a from (select 1 as a) as b;
select 1 from (select 1) as a;
select * from (select * from t1 union select * from t1) a;
select * from (select * from t1 union all select * from t1) a;
+select * from (select * from t1 union all select * from t1 limit 2) a;
explain select * from (select * from t1 union select * from t1) a;
explain select * from (select * from t1 union all select * from t1) a;
CREATE TABLE t2 (a int not null);
@@ -138,3 +139,29 @@ insert into t1 values (1),(2);
select * from ( select * from t1 union select * from t1) a,(select * from t1 union select * from t1) b;
explain select * from ( select * from t1 union select * from t1) a,(select * from t1 union select * from t1) b;
drop table t1;
+
+
+#
+# correct lex->current_select
+#
+CREATE TABLE t1 (
+ OBJECTID int(11) NOT NULL default '0',
+ SORTORDER int(11) NOT NULL auto_increment,
+ KEY t1_SortIndex (SORTORDER),
+ KEY t1_IdIndex (OBJECTID)
+) TYPE=MyISAM DEFAULT CHARSET=latin1;
+CREATE TABLE t2 (
+ ID int(11) default NULL,
+ PARID int(11) default NULL,
+ UNIQUE KEY t2_ID_IDX (ID),
+ KEY t2_PARID_IDX (PARID)
+) engine=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO t2 VALUES (1000,0),(1001,0),(1002,0),(1003,0),(1008,1),(1009,1),(1010,1),(1011,1),(1016,2);
+CREATE TABLE t3 (
+ ID int(11) default NULL,
+ DATA decimal(10,2) default NULL,
+ UNIQUE KEY t3_ID_IDX (ID)
+) engine=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO t3 VALUES (1000,0.00),(1001,0.25),(1002,0.50),(1003,0.75),(1008,1.00),(1009,1.25),(1010,1.50),(1011,1.75);
+select 497, TMP.ID, NULL from (select 497 as ID, MAX(t3.DATA) as DATA from t1 join t2 on (t1.ObjectID = t2.ID) join t3 on (t1.ObjectID = t3.ID) group by t2.ParID order by DATA DESC) as TMP;
+drop table t1, t2, t3;
diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test
index ad7b9b21b51..155ed459d1f 100644
--- a/mysql-test/t/func_str.test
+++ b/mysql-test/t/func_str.test
@@ -346,3 +346,9 @@ DROP TABLE t1;
select substring_index("1abcd;2abcd;3abcd;4abcd", ';', 2),substring_index("1abcd;2abcd;3abcd;4abcd", ';', -2);
explain extended select md5('hello'), sha('abc'), sha1('abc'), soundex(''), 'mood' sounds like 'mud', aes_decrypt(aes_encrypt('abc','1'),'1'),concat('*',space(5),'*'), reverse('abc'), rpad('a',4,'1'), lpad('a',4,'1'), concat_ws(',','',NULL,'a'),make_set(255,_latin2'a',_latin2'b',_latin2'c'),elt(2,1),locate("a","b",2),format(130,10),char(0),conv(130,16,10),hex(130),binary 'HE', export_set(255,_latin2'y',_latin2'n',_latin2' '),FIELD('b' COLLATE latin1_bin,'A','B'),FIND_IN_SET(_latin1'B',_latin1'a,b,c,d'),collation(conv(130,16,10)), coercibility(conv(130,16,10)),length('\n\t\r\b\0\_\%\\'),bit_length('\n\t\r\b\0\_\%\\'),bit_length('\n\t\r\b\0\_\%\\'),concat('monty',' was here ','again'),length('hello'),char(ascii('h')),ord('h'),quote(1/0),crc32("123"),replace('aaaa','a','b'),insert('txs',2,1,'hi'),left(_latin2'a',1),right(_latin2'a',1),lcase(_latin2'a'),ucase(_latin2'a'),SUBSTR('abcdefg',3,2),substring_index("1abcd;2abcd;3abcd;4abcd", ';', 2),trim(_latin2' a '),ltrim(_latin2' a '),rtrim(_latin2' a '), decode(encode(repeat("a",100000),"monty"),"monty");
+
+#
+# Bug #2182
+#
+
+SELECT lpad(12345, 5, "#");
diff --git a/mysql-test/t/null.test b/mysql-test/t/null.test
index c11ed78253b..9f3b6646e7f 100644
--- a/mysql-test/t/null.test
+++ b/mysql-test/t/null.test
@@ -97,3 +97,4 @@ insert into t1 values
explain select * from t1 where a between 2 and 3;
explain select * from t1 where a between 2 and 3 or b is null;
drop table t1;
+select cast(NULL as signed);
diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test
index d7681e9c2ec..dba5619b777 100644
--- a/mysql-test/t/query_cache.test
+++ b/mysql-test/t/query_cache.test
@@ -589,4 +589,17 @@ show status like "Qcache_queries_in_cache";
# Keep things tidy
#
DROP TABLE t1;
+
+#
+# DROP current database test
+#
+CREATE TABLE t1 (a int(1));
+CREATE DATABASE mysqltest;
+USE mysqltest;
+DROP DATABASE mysqltest;
+SELECT * FROM test.t1;
+USE test;
+DROP TABLE t1;
+
+
SET GLOBAL query_cache_size=0;
diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test
index 4ab39e3ccbc..d262f02c978 100644
--- a/mysql-test/t/show_check.test
+++ b/mysql-test/t/show_check.test
@@ -53,9 +53,14 @@ drop table t2;
create table t1 (
test_set set( 'val1', 'val2', 'val3' ) not null default '',
name char(20) default 'O''Brien' comment 'O''Brien as default',
- c int not null comment 'int column'
+ c int not null comment 'int column',
+ `c-b` int comment 'name with a space',
+ `space ` int comment 'name with a space',
) comment = 'it\'s a table' ;
-show create table t1 ;
+show create table t1;
+set sql_quote_show_create=0;
+show create table t1;
+set sql_quote_show_create=1;
show full columns from t1;
drop table t1;
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index 95e4f022f2d..37dbc8f24d9 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -1009,3 +1009,15 @@ INSERT INTO t1 VALUES (1,1,'1A3240'), (1,2,'4W2365');
INSERT INTO t2 VALUES (100, 200, 'C');
SELECT DISTINCT COLC FROM t1 WHERE COLA = (SELECT COLA FROM t2 WHERE COLB = 200 AND COLC ='C' LIMIT 1);
DROP TABLE t1, t2;
+
+#
+# Bug 2198
+#
+
+create table t1 (a int, b decimal(13, 3));
+insert into t1 values (1, 0.123);
+select a, (select max(b) from t1) into outfile "subselect.out.file.1" from t1;
+delete from t1;
+load data infile "subselect.out.file.1" into table t1;
+select * from t1;
+drop table t1;
diff --git a/mysql-test/t/subselect_innodb.test b/mysql-test/t/subselect_innodb.test
index 9eb35ffc0fd..8e8d41f7653 100644
--- a/mysql-test/t/subselect_innodb.test
+++ b/mysql-test/t/subselect_innodb.test
@@ -67,4 +67,37 @@ INSERT INTO t1 VALUES (1),(2),(3);
INSERT INTO t3 VALUES (1,1),(2,2),(3,3);
INSERT INTO t2 VALUES (1,1),(2,2),(3,3);
SELECT distinct p1.processor_id, (SELECT y.yod_id FROM t1 p2, t2 y WHERE p2.processor_id = p1.processor_id and p2.processor_id = y.processor_id) FROM t1 p1;
-drop table t1,t2,t3; \ No newline at end of file
+drop table t1,t2,t3;
+
+#
+# innodb locking
+#
+CREATE TABLE t1 (
+ id int(11) NOT NULL default '0',
+ b int(11) default NULL,
+ c char(3) default NULL,
+ PRIMARY KEY (id),
+ KEY t2i1 (b)
+) ENGINE=innodb DEFAULT CHARSET=latin1;
+INSERT INTO t1 VALUES (0,0,'GPL'),(1,0,'GPL'),(2,1,'GPL'),(3,2,'GPL');
+CREATE TABLE t2 (
+ id int(11) NOT NULL default '0',
+ b int(11) default NULL,
+ c char(3) default NULL,
+ PRIMARY KEY (id),
+ KEY t2i (b)
+) ENGINE=innodb DEFAULT CHARSET=latin1;
+INSERT INTO t2 VALUES (0,0,'GPL'),(1,0,'GPL'),(2,1,'GPL'),(3,2,'GPL');
+select (select max(id) from t2 where b=1 group by b) as x,b from t1 where b=1;
+drop table t1,t2;
+
+#
+# reiniting innodb tables
+#
+create table t1 (id int not null, value char(255), primary key(id)) engine=innodb;
+create table t2 (id int not null, value char(255)) engine=innodb;
+insert into t1 values (1,'a'),(2,'b');
+insert into t2 values (1,'z'),(2,'x');
+select t2.id,t2.value,(select t1.value from t1 where t1.id=t2.id) from t2;
+select t2.id,t2.value,(select t1.value from t1 where t1.id=t2.id) from t2;
+drop table t1,t2;
diff --git a/mysys/charset.c b/mysys/charset.c
index f8c8237c88b..5e9e3c3fcaa 100644
--- a/mysys/charset.c
+++ b/mysys/charset.c
@@ -357,7 +357,7 @@ static int add_collation(CHARSET_INFO *cs)
}
-#define MAX_BUF 1024*16
+#define MY_MAX_ALLOWED_BUF 1024*1024
#define MY_CHARSET_INDEX "Index.xml"
const char *charsets_dir= NULL;
@@ -369,16 +369,19 @@ static my_bool my_read_charset_file(const char *filename, myf myflags)
char *buf;
int fd;
uint len;
+ MY_STAT stat_info;
- if (!(buf= (char *)my_malloc(MAX_BUF,myflags)))
- return FALSE;
+ if (!my_stat(filename, &stat_info, MYF(MY_WME)) ||
+ ((len= (uint)stat_info.st_size) > MY_MAX_ALLOWED_BUF) ||
+ !(buf= (char *)my_malloc(len,myflags)))
+ return TRUE;
if ((fd=my_open(filename,O_RDONLY,myflags)) < 0)
{
my_free(buf,myflags);
return TRUE;
}
- len=read(fd,buf,MAX_BUF);
+ len=read(fd,buf,len);
my_close(fd,myflags);
if (my_parse_charset_xml(buf,len,add_collation))
@@ -540,7 +543,7 @@ static CHARSET_INFO *get_internal_charset(uint cs_number, myf flags)
strxmov(get_charsets_dir(buf), cs->csname, ".xml", NullS);
my_read_charset_file(buf,flags);
}
- cs= (cs->state & MY_CS_AVAILABLE) ? cs : NULL;
+ cs= (cs && cs->state & MY_CS_AVAILABLE) ? cs : NULL;
pthread_mutex_unlock(&THR_LOCK_charset);
return cs;
}
diff --git a/mysys/default.c b/mysys/default.c
index 3a751eb4e29..81e1fd06374 100644
--- a/mysys/default.c
+++ b/mysys/default.c
@@ -461,7 +461,8 @@ static char *remove_end_comment(char *ptr)
else if (quote == *ptr)
quote= 0;
}
- if (!quote && *ptr == '#') /* We are not inside a comment */
+ /* We are not inside a comment */
+ if (!quote && (*ptr == '#' || *ptr == ';'))
{
*ptr= 0;
return ptr;
diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c
index b5c80d9482f..1dd3108e151 100644
--- a/mysys/mf_iocache.c
+++ b/mysys/mf_iocache.c
@@ -1175,8 +1175,8 @@ int _flush_io_cache(IO_CACHE *info, int need_append_buffer_lock)
info IO_CACHE Handle to free
NOTES
- It's currently safe to call this if one has called io_cache_init()
- on the 'info' object, even if io_cache_init() failed.
+ It's currently safe to call this if one has called init_io_cache()
+ on the 'info' object, even if init_io_cache() failed.
This function is also safe to call twice with the same handle.
RETURN
diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c
index 76f8f6bf852..b278eaa36e1 100644
--- a/mysys/my_getopt.c
+++ b/mysys/my_getopt.c
@@ -285,6 +285,19 @@ int handle_options(int *argc, char ***argv,
return EXIT_AMBIGUOUS_OPTION;
}
}
+ if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
+ {
+ if (my_getopt_print_errors)
+ fprintf(stderr,
+ "%s: %s: Option '%s' used, but is disabled\n", my_progname,
+ option_is_loose ? "WARNING" : "ERROR", opt_str);
+ if (option_is_loose)
+ {
+ (*argc)--;
+ continue;
+ }
+ return EXIT_OPTION_DISABLED;
+ }
if (must_be_var && (optp->var_type & GET_TYPE_MASK) == GET_NO_ARG)
{
if (my_getopt_print_errors)
@@ -358,6 +371,14 @@ int handle_options(int *argc, char ***argv,
{
/* Option recognized. Find next what to do with it */
opt_found= 1;
+ if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
+ {
+ if (my_getopt_print_errors)
+ fprintf(stderr,
+ "%s: ERROR: Option '-%c' used, but is disabled\n",
+ my_progname, optp->id);
+ return EXIT_OPTION_DISABLED;
+ }
if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL &&
optp->arg_type == NO_ARG)
{
@@ -550,7 +571,7 @@ static int findopt(char *optpat, uint length,
const struct my_option **opt_res,
char **ffname)
{
- int count;
+ uint count;
struct my_option *opt= (struct my_option *) *opt_res;
for (count= 0; opt->name; opt++)
@@ -562,7 +583,8 @@ static int findopt(char *optpat, uint length,
*ffname= (char *) opt->name; /* We only need to know one prev */
if (!opt->name[length]) /* Exact match */
return 1;
- count++;
+ if (!count || strcmp(*ffname, opt->name)) /* Don't count synonyms */
+ count++;
}
}
return count;
@@ -882,7 +904,8 @@ void my_print_variables(const struct my_option *options)
longlong2str(*((ulonglong*) value), buff, 10);
printf("%s\n", buff);
break;
- default: /* dummy default to avoid compiler warnings */
+ default:
+ printf("(Disabled)\n");
break;
}
}
diff --git a/netware/init_db.sql b/netware/init_db.sql
index 4613e5c0274..063c1815eb1 100644
--- a/netware/init_db.sql
+++ b/netware/init_db.sql
@@ -24,3 +24,7 @@ CREATE TABLE tables_priv (Host char(60) binary DEFAULT '' NOT NULL, Db char(64)
CREATE TABLE columns_priv (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Column_name char(64) binary DEFAULT '' NOT NULL, Timestamp timestamp(14), Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name,Column_name)) comment='Column privileges';
+CREATE TABLE help_topic (help_topic_id int unsigned NOT NULL, name varchar(64) NOT NULL, help_category_id smallint unsigned NOT NULL, description text NOT NULL, example text NOT NULL, url varchar(128) NOT NULL, primary key (help_topic_id), unique index (name))comment='help topics';
+CREATE TABLE help_category (help_category_id smallint unsigned NOT NULL, name varchar(64) NOT NULL, parent_category_id smallint unsigned null, url varchar(128) NOT NULL, primary key (help_category_id), unique index (name)) comment='help categories';
+CREATE TABLE help_keyword (help_keyword_id int unsigned NOT NULL, name varchar(64) NOT NULL, primary key (help_keyword_id), unique index (name)) comment='help keywords';
+CREATE TABLE help_relation (help_topic_id int unsigned NOT NULL references help_topic, help_keyword_id int unsigned NOT NULL references help_keyword, primary key (help_keyword_id, help_topic_id)) comment='keyword-topic relation';
diff --git a/netware/libmysql.imp b/netware/libmysql.imp
index 75fcc8d1a99..977fb1b0b1f 100644
--- a/netware/libmysql.imp
+++ b/netware/libmysql.imp
@@ -77,7 +77,7 @@ mysql_thread_init,
mysql_thread_safe,
mysql_use_result,
net_safe_read,
-simple_command,
+#simple_command,
mysql_connect,
mysql_create_db,
mysql_drop_db,
diff --git a/sql/field.cc b/sql/field.cc
index a9029b893e3..1a0716326fe 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -4567,17 +4567,19 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
}
else
{
+ bool was_conversion;
char buff[80];
String tmpstr(buff,sizeof(buff), &my_charset_bin);
+
/* Convert character set if nesessary */
- if (use_conversion(cs, field_charset))
+ if ((was_conversion= use_conversion(cs, field_charset)))
{
tmpstr.copy(from, length, cs, field_charset);
from= tmpstr.ptr();
length= tmpstr.length();
}
Field_blob::store_length(length);
- if (table->copy_blobs || length <= MAX_FIELD_WIDTH)
+ if (was_conversion || table->copy_blobs || length <= MAX_FIELD_WIDTH)
{ // Must make a copy
if (from != value.ptr()) // For valgrind
{
@@ -5609,16 +5611,16 @@ create_field::create_field(Field *old_field,Field *orig_field)
case 3: sql_type= FIELD_TYPE_MEDIUM_BLOB; break;
default: sql_type= FIELD_TYPE_LONG_BLOB; break;
}
- length /= charset->mbmaxlen; // QQ: Probably not needed
+ length=(length+charset->mbmaxlen-1)/charset->mbmaxlen; // QQ: Probably not needed
break;
case FIELD_TYPE_STRING:
case FIELD_TYPE_VAR_STRING:
- length /= charset->mbmaxlen;
+ length=(length+charset->mbmaxlen-1)/charset->mbmaxlen;
break;
default:
break;
}
-
+
decimals= old_field->decimals();
if (sql_type == FIELD_TYPE_STRING)
{
diff --git a/sql/item.cc b/sql/item.cc
index cbac16cba8d..72c5ac3fd55 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1882,7 +1882,6 @@ void Item_cache_int::store(Item *item)
{
value= item->val_int_result();
null_value= item->null_value;
- collation.set(item->collation);
}
@@ -1890,7 +1889,6 @@ void Item_cache_real::store(Item *item)
{
value= item->val_result();
null_value= item->null_value;
- collation.set(item->collation);
}
@@ -1913,7 +1911,6 @@ void Item_cache_str::store(Item *item)
value_buff.copy(*value);
value= &value_buff;
}
- collation.set(item->collation);
}
diff --git a/sql/item.h b/sql/item.h
index dc3a9114601..e9d34568350 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -882,13 +882,15 @@ public:
void set_used_tables(table_map map) { used_table_map= map; }
virtual bool allocate(uint i) { return 0; };
- virtual bool setup(Item *item) { example= item; return 0; };
- virtual void store(Item *)= 0;
- void set_len_n_dec(uint32 max_len, uint8 dec)
+ virtual bool setup(Item *item)
{
- max_length= max_len;
- decimals= dec;
- }
+ example= item;
+ max_length= item->max_length;
+ decimals= item->decimals;
+ collation.set(item->collation);
+ return 0;
+ };
+ virtual void store(Item *)= 0;
enum Type type() const { return CACHE_ITEM; }
static Item_cache* get_cache(Item_result type);
table_map used_tables() const { return used_table_map; }
@@ -913,7 +915,7 @@ class Item_cache_real: public Item_cache
double value;
public:
Item_cache_real(): Item_cache() {}
-
+
void store(Item *item);
double val() { return value; }
longlong val_int() { return (longlong) (value+(value > 0 ? 0.5 : -0.5)); }
diff --git a/sql/item_func.h b/sql/item_func.h
index 75839bb80c3..be20a9b4fc7 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -211,8 +211,8 @@ 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(); }
+ double val() { null_value=args[0]->null_value; return args[0]->val(); }
+ longlong val_int() { null_value=args[0]->null_value; return args[0]->val_int(); }
void fix_length_and_dec()
{ max_length=args[0]->max_length; unsigned_flag=0; }
void print(String *str);
@@ -223,8 +223,8 @@ 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(); }
+ double val() { null_value=args[0]->null_value; return args[0]->val(); }
+ longlong val_int() { null_value=args[0]->null_value; return args[0]->val_int(); }
void fix_length_and_dec()
{ max_length=args[0]->max_length; unsigned_flag=1; }
void print(String *str);
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index b19a6e06230..badc134ae1d 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -976,9 +976,10 @@ String *Item_func_right::val_str(String *str)
if (res->length() <= (uint) length)
return res; /* purecov: inspected */
- uint start=res->numchars()-(uint) length;
- if (start<=0) return res;
- start=res->charpos(start);
+ uint start=res->numchars();
+ if (start <= (uint) length)
+ return res;
+ start=res->charpos(start - (uint) length);
tmp_value.set(*res,start,res->length()-start);
return &tmp_value;
}
@@ -2023,9 +2024,8 @@ String *Item_func_lpad::val_str(String *str)
{
uint32 res_char_length,pad_char_length;
ulong count= (long) args[1]->val_int(), byte_count;
- String a1,a3;
- String *res= args[0]->val_str(&a1);
- String *pad= args[2]->val_str(&a3);
+ String *res= args[0]->val_str(&tmp_value);
+ String *pad= args[2]->val_str(&lpad_str);
if (!res || args[1]->null_value || !pad)
goto err;
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index e0d9bcf3bd6..518b712ad18 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -306,8 +306,6 @@ void Item_singlerow_subselect::fix_length_and_dec()
if ((max_columns= engine->cols()) == 1)
{
engine->fix_length_and_dec(row= &value);
- if (!(value= Item_cache::get_cache(engine->type())))
- return;
}
else
{
@@ -919,7 +917,8 @@ int subselect_single_select_engine::prepare()
{
if (prepared)
return 0;
- join= new JOIN(thd, select_lex->item_list, select_lex->options, result);
+ join= new JOIN(thd, select_lex->item_list,
+ select_lex->options | SELECT_NO_UNLOCK, result);
if (!join || !result)
{
thd->fatal_error(); //out of memory
@@ -946,7 +945,7 @@ int subselect_single_select_engine::prepare()
int subselect_union_engine::prepare()
{
- return unit->prepare(thd, result);
+ return unit->prepare(thd, result, SELECT_NO_UNLOCK);
}
int subselect_uniquesubquery_engine::prepare()
@@ -968,13 +967,9 @@ static Item_result set_row(List<Item> &item_list, Item *item,
res_type= sel_item->result_type();
item->decimals= sel_item->decimals;
*maybe_null= sel_item->maybe_null;
- if (row)
- {
- if (!(row[i]= Item_cache::get_cache(res_type)))
- return STRING_RESULT; // we should return something
- row[i]->set_len_n_dec(sel_item->max_length, sel_item->decimals);
- row[i]->collation.set(sel_item->collation);
- }
+ if (!(row[i]= Item_cache::get_cache(res_type)))
+ return STRING_RESULT; // we should return something
+ row[i]->setup(sel_item);
}
if (item_list.elements > 1)
res_type= ROW_RESULT;
@@ -995,7 +990,10 @@ void subselect_union_engine::fix_length_and_dec(Item_cache **row)
DBUG_ASSERT(row || unit->first_select()->item_list.elements==1);
if (unit->first_select()->item_list.elements == 1)
+ {
res_type= set_row(unit->types, item, row, &maybe_null);
+ item->collation.set(row[0]->collation);
+ }
else
{
bool fake= 0;
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index d5a521dffe7..d8b65ec81b9 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -38,6 +38,7 @@ typedef ulong key_part_map; /* Used for finding key parts */
/* useful constants */
extern const key_map key_map_empty;
extern const key_map key_map_full;
+extern const char *primary_key_name;
#include "mysql_com.h"
#include <violite.h>
@@ -664,7 +665,7 @@ bool get_key_map_from_key_list(key_map *map, TABLE *table,
bool insert_fields(THD *thd,TABLE_LIST *tables,
const char *db_name, const char *table_name,
List_iterator<Item> *it);
-bool setup_tables(TABLE_LIST *tables);
+bool setup_tables(TABLE_LIST *tables, my_bool reinit);
int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
List<Item> *sum_func_list, uint wild_num);
int setup_fields(THD *thd, Item** ref_pointer_array, TABLE_LIST *tables,
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index d7984213fd6..3125c392751 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -2039,15 +2039,28 @@ int setup_fields(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
/*
- Remap table numbers if INSERT ... SELECT
- Check also that the 'used keys' and 'ignored keys' exists and set up the
- table structure accordingly
+ prepare tables
- This has to be called for all tables that are used by items, as otherwise
- table->map is not set and all Item_field will be regarded as const items.
+ SYNOPSIS
+ setup_tables()
+ tables - tables list
+ reinit - true if called for table reinitialization before
+ subquery reexecuting
+
+ RETURN
+ 0 ok; In this case *map will includes the choosed index
+ 1 error
+
+ NOTE
+ Remap table numbers if INSERT ... SELECT
+ Check also that the 'used keys' and 'ignored keys' exists and set up the
+ table structure accordingly
+
+ This has to be called for all tables that are used by items, as otherwise
+ table->map is not set and all Item_field will be regarded as const items.
*/
-bool setup_tables(TABLE_LIST *tables)
+bool setup_tables(TABLE_LIST *tables, my_bool reinit)
{
DBUG_ENTER("setup_tables");
uint tablenr=0;
@@ -2074,7 +2087,7 @@ bool setup_tables(TABLE_LIST *tables)
table->keys_in_use_for_query.subtract(map);
}
table->used_keys.intersect(table->keys_in_use_for_query);
- if (table_list->shared || table->clear_query_id)
+ if ((table_list->shared || table->clear_query_id) && !reinit)
{
table->clear_query_id= 0;
/* Clear query_id that may have been set by previous select */
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index c63b1a9e026..7c31281c926 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -308,6 +308,10 @@ TODO list:
#include "../myisammrg/myrg_def.h"
#endif
+#ifdef EMBEDDED_LIBRARY
+#include "emb_qcache.h"
+#endif
+
#if defined(EXTRA_DEBUG) && !defined(DBUG_OFF)
#define MUTEX_LOCK(M) { DBUG_PRINT("lock", ("mutex lock 0x%lx", (ulong)(M))); \
pthread_mutex_lock(M);}
@@ -646,7 +650,7 @@ void query_cache_abort(NET *net)
}
-void query_cache_end_of_result(NET *net)
+void query_cache_end_of_result(THD *thd)
{
DBUG_ENTER("query_cache_end_of_result");
@@ -655,11 +659,15 @@ void query_cache_end_of_result(NET *net)
if (query_cache.query_cache_size == 0) DBUG_VOID_RETURN;
#endif
- if (net->query_cache_query != 0) // Quick check on unlocked structure
+ if (thd->net.query_cache_query != 0) // Quick check on unlocked structure
{
+#ifdef EMBEDDED_LIBRARY
+ query_cache_insert(&thd->net, (byte*)thd,
+ emb_count_querycache_size(thd));
+#endif
STRUCT_LOCK(&query_cache.structure_guard_mutex);
Query_cache_block *query_block = ((Query_cache_block*)
- net->query_cache_query);
+ thd->net.query_cache_query);
if (query_block)
{
DUMP(&query_cache);
@@ -691,7 +699,7 @@ void query_cache_end_of_result(NET *net)
// Cache was flushed or resized and query was deleted => do nothing
STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
}
- net->query_cache_query=0;
+ thd->net.query_cache_query=0;
DBUG_EXECUTE("check_querycache",query_cache.check_integrity(0););
}
DBUG_VOID_RETURN;
@@ -1052,23 +1060,29 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
/*
Send cached result to client
*/
+#ifndef EMBEDDED_LIBRARY
do
{
DBUG_PRINT("qcache", ("Results (len %lu, used %lu, headers %lu)",
- result_block->length, result_block->used,
- result_block->headers_len()+
- ALIGN_SIZE(sizeof(Query_cache_result))));
-
+ result_block->length, result_block->used,
+ result_block->headers_len()+
+ ALIGN_SIZE(sizeof(Query_cache_result))));
+
Query_cache_result *result = result_block->result();
-#ifndef EMBEDDED_LIBRARY /* TODO query cache in embedded library*/
if (net_real_write(&thd->net, result->data(),
result_block->used -
result_block->headers_len() -
ALIGN_SIZE(sizeof(Query_cache_result))))
break; // Client aborted
-#endif
result_block = result_block->next;
} while (result_block != first_result_block);
+#else
+ {
+ Querycache_stream qs(result_block, result_block->headers_len() +
+ ALIGN_SIZE(sizeof(Query_cache_result)));
+ emb_load_querycache_result(thd, &qs);
+ }
+#endif /*!EMBEDDED_LIBRARY*/
thd->limit_found_rows = query->found_rows();
@@ -1804,18 +1818,23 @@ my_bool Query_cache::write_result_data(Query_cache_block **result_block,
Query_cache_block *block = *result_block;
uint headers_len = (ALIGN_SIZE(sizeof(Query_cache_block)) +
ALIGN_SIZE(sizeof(Query_cache_result)));
+#ifndef EMBEDDED_LIBRARY
// Now fill list of blocks that created by allocate_data_chain
do
{
block->type = type;
ulong length = block->used - headers_len;
DBUG_PRINT("qcache", ("write %lu byte in block 0x%lx",length,
- (ulong)block));
+ (ulong)block));
memcpy((void*)(((byte*) block)+headers_len), (void*) rest, length);
rest += length;
block = block->next;
type = Query_cache_block::RES_CONT;
} while (block != *result_block);
+#else
+ Querycache_stream qs(*result_block, headers_len);
+ emb_store_querycache_result(&qs, (THD*)data);
+#endif /*!EMBEDDED_LIBRARY*/
}
else
{
diff --git a/sql/sql_cache.h b/sql/sql_cache.h
index 68e69ab523f..ac4f465bf79 100644
--- a/sql/sql_cache.h
+++ b/sql/sql_cache.h
@@ -392,7 +392,7 @@ protected:
void destroy();
friend void query_cache_insert(NET *net, const char *packet, ulong length);
- friend void query_cache_end_of_result(NET *net);
+ friend void query_cache_end_of_result(THD *thd);
friend void query_cache_abort(NET *net);
/*
@@ -416,7 +416,7 @@ protected:
extern Query_cache query_cache;
extern TYPELIB query_cache_type_typelib;
-void query_cache_end_of_result(NET *net);
+void query_cache_end_of_result(THD *thd);
void query_cache_abort(NET *net);
#endif
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 60220ffc889..ce30c6f3d09 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -323,12 +323,14 @@ THD::~THD()
#endif
DBUG_PRINT("info", ("freeing host"));
+#ifndef EMBEDDED_LIBRARY
if (host != my_localhost) // If not pointer to constant
safeFree(host);
if (user != delayed_user)
safeFree(user);
- safeFree(db);
safeFree(ip);
+#endif
+ safeFree(db);
free_root(&warn_root,MYF(0));
free_root(&transaction.mem_root,MYF(0));
mysys_var=0; // Safety (shouldn't be needed)
@@ -693,39 +695,53 @@ select_export::~select_export()
thd->sent_row_count=row_count;
}
-int
-select_export::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
+
+static int create_file(THD *thd, char *path, sql_exchange *exchange,
+ File *file, IO_CACHE *cache)
{
- char path[FN_REFLEN];
- uint option=4;
- bool blob_flag=0;
- unit= u;
+ uint option= 4;
+
#ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS
- option|=1; // Force use of db directory
+ option|= 1; // Force use of db directory
#endif
- if ((uint) strlen(exchange->file_name) + NAME_LEN >= FN_REFLEN)
- strmake(path,exchange->file_name,FN_REFLEN-1);
- (void) fn_format(path,exchange->file_name, thd->db ? thd->db : "", "",
+ (void) fn_format(path, exchange->file_name, thd->db ? thd->db : "", "",
option);
- if (!access(path,F_OK))
+ if (!access(path, F_OK))
{
my_error(ER_FILE_EXISTS_ERROR, MYF(0), exchange->file_name);
return 1;
}
/* Create the file world readable */
- if ((file=my_create(path, 0666, O_WRONLY, MYF(MY_WME))) < 0)
+ if ((*file= my_create(path, 0666, O_WRONLY, MYF(MY_WME))) < 0)
return 1;
#ifdef HAVE_FCHMOD
- (void) fchmod(file,0666); // Because of umask()
+ (void) fchmod(*file, 0666); // Because of umask()
#else
- (void) chmod(path,0666);
+ (void) chmod(path, 0666);
#endif
- if (init_io_cache(&cache,file,0L,WRITE_CACHE,0L,1,MYF(MY_WME)))
+ if (init_io_cache(cache, *file, 0L, WRITE_CACHE, 0L, 1, MYF(MY_WME)))
{
- my_close(file,MYF(0));
- file= -1;
+ my_close(*file, MYF(0));
+ my_delete(path, MYF(0)); // Delete file on error, it was just created
+ *file= -1;
+ end_io_cache(cache);
return 1;
}
+ return 0;
+}
+
+
+int
+select_export::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
+{
+ char path[FN_REFLEN];
+ bool blob_flag=0;
+ unit= u;
+ if ((uint) strlen(exchange->file_name) + NAME_LEN >= FN_REFLEN)
+ strmake(path,exchange->file_name,FN_REFLEN-1);
+
+ if (create_file(thd, path, exchange, &file, &cache))
+ return 1;
/* Check if there is any blobs in data */
{
List_iterator_fast<Item> li(list);
@@ -899,7 +915,6 @@ err:
void select_export::send_error(uint errcode, const char *err)
{
::send_error(thd,errcode,err);
- (void) end_io_cache(&cache);
(void) my_close(file,MYF(0));
file= -1;
}
@@ -936,33 +951,9 @@ int
select_dump::prepare(List<Item> &list __attribute__((unused)),
SELECT_LEX_UNIT *u)
{
- uint option=4;
unit= u;
-#ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS
- option|=1; // Force use of db directory
-#endif
- (void) fn_format(path,exchange->file_name, thd->db ? thd->db : "", "",
- option);
- if (!access(path,F_OK))
- {
- my_error(ER_FILE_EXISTS_ERROR,MYF(0),exchange->file_name);
+ if (create_file(thd, path, exchange, &file, &cache))
return 1;
- }
- /* Create the file world readable */
- if ((file=my_create(path, 0666, O_WRONLY, MYF(MY_WME))) < 0)
- return 1;
-#ifdef HAVE_FCHMOD
- (void) fchmod(file,0666); // Because of umask()
-#else
- (void) chmod(path,0666);
-#endif
- if (init_io_cache(&cache,file,0L,WRITE_CACHE,0L,1,MYF(MY_WME)))
- {
- my_close(file,MYF(0));
- my_delete(path,MYF(0));
- file= -1;
- return 1;
- }
return 0;
}
@@ -1009,9 +1000,7 @@ err:
void select_dump::send_error(uint errcode,const char *err)
{
::send_error(thd,errcode,err);
- (void) end_io_cache(&cache);
(void) my_close(file,MYF(0));
- (void) my_delete(path,MYF(0)); // Delete file on error
file= -1;
}
@@ -1037,7 +1026,7 @@ bool select_singlerow_subselect::send_data(List<Item> &items)
Item_singlerow_subselect *it= (Item_singlerow_subselect *)item;
if (it->assigned())
{
- my_message(ER_SUBQUERY_NO_1_ROW, ER(ER_SUBQUERY_NO_1_ROW), MYF(0));
+ my_message(ER_SUBQUERY_NO_1_ROW, ER(ER_SUBQUERY_NO_1_ROW), MYF(0));
DBUG_RETURN(1);
}
if (unit->offset_limit_cnt)
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 70b1d1d0d3a..697859eb264 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -270,11 +270,8 @@ int mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info)
VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
// do not alter database if another thread is holding read lock
- if (wait_if_global_read_lock(thd,0))
- {
- error= -1;
+ if ((error=wait_if_global_read_lock(thd,0)))
goto exit2;
- }
/* Check directory */
(void)sprintf(path,"%s/%s/%s", mysql_data_home, db, MY_DB_OPT_FILE);
@@ -307,7 +304,7 @@ exit:
start_waiting_global_read_lock(thd);
exit2:
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
- DBUG_RETURN(error);
+ DBUG_RETURN(error ? -1 : 0); /* -1 to delegate send_error() */
}
@@ -411,7 +408,7 @@ exit:
when the slave is replicating a DROP DATABASE:
- garbage characters in the error message:
"Error 'Can't drop database 'test2'; database doesn't exist' on query
- 'h4zIż'"
+ 'h4zI©'"
- segfault
- hang in "free(vio)" (yes!) in the I/O or SQL slave threads (so slave
server hangs at shutdown etc).
@@ -420,7 +417,8 @@ exit:
{
if (!(thd->slave_thread)) /* a slave thread will free it itself */
x_free(thd->db);
- thd->db= 0;
+ thd->db= 0;
+ thd->db_length= 0;
}
exit2:
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index e8f1c5d87de..374e56ecdd4 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -114,7 +114,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
DBUG_RETURN(1); // out of memory
// st_select_lex_unit::prepare correctly work for single select
- if ((res= unit->prepare(thd, derived_result)))
+ if ((res= unit->prepare(thd, derived_result, 0)))
goto exit;
/*
@@ -146,17 +146,19 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
}
derived_result->set_table(table);
- unit->offset_limit_cnt= first_select->offset_limit;
- unit->select_limit_cnt= first_select->select_limit+
- first_select->offset_limit;
- if (unit->select_limit_cnt < first_select->select_limit)
- unit->select_limit_cnt= HA_POS_ERROR;
- if (unit->select_limit_cnt == HA_POS_ERROR)
- first_select->options&= ~OPTION_FOUND_ROWS;
-
if (is_union)
res= mysql_union(thd, lex, derived_result, unit);
else
+ {
+ unit->offset_limit_cnt= first_select->offset_limit;
+ unit->select_limit_cnt= first_select->select_limit+
+ first_select->offset_limit;
+ if (unit->select_limit_cnt < first_select->select_limit)
+ unit->select_limit_cnt= HA_POS_ERROR;
+ if (unit->select_limit_cnt == HA_POS_ERROR)
+ first_select->options&= ~OPTION_FOUND_ROWS;
+
+ lex->current_select= first_select;
res= mysql_select(thd, &first_select->ref_pointer_array,
(TABLE_LIST*) first_select->table_list.first,
first_select->with_wild,
@@ -169,6 +171,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
(first_select->options | thd->options |
SELECT_NO_UNLOCK),
derived_result, unit, first_select);
+ }
if (!res)
{
@@ -198,7 +201,10 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
}
}
else
+ {
unit->exclude_tree();
+ unit->cleanup();
+ }
org_table_list->db= (char *)"";
// Force read of table stats in the optimizer
table->file->info(HA_STATUS_VARIABLE);
diff --git a/sql/sql_help.cc b/sql/sql_help.cc
index c40133c04a8..3c98b7b0bb4 100644
--- a/sql/sql_help.cc
+++ b/sql/sql_help.cc
@@ -274,9 +274,9 @@ int get_topics_for_keyword(THD *thd, TABLE *topics, TABLE *relations,
DBUG_ENTER("get_topics_for_keyword");
- if ((iindex_topic= find_type((char*) "PRIMARY",
+ if ((iindex_topic= find_type((char*) primary_key_name,
&topics->keynames, 1+2)-1)<0 ||
- (iindex_relations= find_type((char*) "PRIMARY",
+ (iindex_relations= find_type((char*) primary_key_name,
&relations->keynames, 1+2)-1)<0)
{
send_error(thd,ER_CORRUPT_HELP_DB);
@@ -686,7 +686,7 @@ int mysqld_help(THD *thd, const char *mask)
goto end;
}
/* Init tables and fields to be usable from items */
- setup_tables(tables);
+ setup_tables(tables, 0);
memcpy((char*) used_fields, (char*) init_used_fields, sizeof(used_fields));
if (init_fields(thd, tables, used_fields, array_elements(used_fields)))
{
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index e23e62fb714..c2f3e737daf 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -84,7 +84,7 @@ check_insert_fields(THD *thd,TABLE *table,List<Item> &fields,
table_list.grant=table->grant;
thd->dupp_field=0;
- if (setup_tables(&table_list) ||
+ if (setup_tables(&table_list, 0) ||
setup_fields(thd, 0, &table_list,fields,1,0,0))
return -1;
if (thd->dupp_field)
@@ -204,7 +204,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
}
if (check_insert_fields(thd,table,fields,*values,1) ||
- setup_tables(insert_table_list) ||
+ setup_tables(insert_table_list, 0) ||
setup_fields(thd, 0, insert_table_list, *values, 0, 0, 0) ||
(duplic == DUP_UPDATE &&
(setup_fields(thd, 0, insert_table_list, update_fields, 0, 0, 0) ||
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index de0d6ade618..efb0ce92ad0 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -1222,11 +1222,6 @@ void st_select_lex::mark_as_dependent(SELECT_LEX *last)
s->uncacheable|= UNCACHEABLE_DEPENDENT;
SELECT_LEX_UNIT *munit= s->master_unit();
munit->uncacheable|= UNCACHEABLE_DEPENDENT;
- //Tables will be reopened many times
- for (TABLE_LIST *tbl= s->get_table_list();
- tbl;
- tbl= tbl->next)
- tbl->shared= 1;
}
}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index c1f7809e0b5..bcbd60e9716 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -351,7 +351,7 @@ public:
void exclude_tree();
/* UNION methods */
- int prepare(THD *thd, select_result *result);
+ int prepare(THD *thd, select_result *result, ulong additional_options);
int exec();
int cleanup();
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 0c35e99ed08..175791ef31e 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -123,7 +123,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
else
{ // Part field list
thd->dupp_field=0;
- if (setup_tables(table_list) ||
+ if (setup_tables(table_list, 0) ||
setup_fields(thd, 0, table_list, fields, 1, 0, 0))
DBUG_RETURN(-1);
if (thd->dupp_field)
diff --git a/sql/sql_olap.cc b/sql/sql_olap.cc
index ef7bf013be8..1d16771c1a4 100644
--- a/sql/sql_olap.cc
+++ b/sql/sql_olap.cc
@@ -164,7 +164,7 @@ int handle_olaps(LEX *lex, SELECT_LEX *select_lex)
List<Item> all_fields(select_lex->item_list);
- if (setup_tables((TABLE_LIST *)select_lex->table_list.first) ||
+ if (setup_tables((TABLE_LIST *)select_lex->table_list.first, 0) ||
setup_fields(lex->thd, 0, (TABLE_LIST *)select_lex->table_list.first,
select_lex->item_list, 1, &all_fields,1) ||
setup_fields(lex->thd, 0, (TABLE_LIST *)select_lex->table_list.first,
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 465d840e2b8..de75ed301e5 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1624,9 +1624,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
switch (command) {
case MYSQL_OPTION_MULTI_STATEMENTS_ON:
thd->client_capabilities|= CLIENT_MULTI_STATEMENTS;
+ send_eof(thd);
break;
case MYSQL_OPTION_MULTI_STATEMENTS_OFF:
thd->client_capabilities&= ~CLIENT_MULTI_STATEMENTS;
+ send_eof(thd);
break;
default:
send_error(thd, ER_UNKNOWN_COM_ERROR);
@@ -3877,7 +3879,7 @@ mysql_parse(THD *thd, char *inBuf, uint length)
else
{
mysql_execute_command(thd);
- query_cache_end_of_result(&thd->net);
+ query_cache_end_of_result(thd);
}
}
}
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index b5dd4083dcf..de0d0c8aca8 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -679,7 +679,7 @@ static bool mysql_test_upd_fields(Prepared_statement *stmt,
#endif
if (open_and_lock_tables(thd, table_list))
DBUG_RETURN(1);
- if (setup_tables(table_list) ||
+ if (setup_tables(table_list, 0) ||
setup_fields(thd, 0, table_list, fields, 1, 0, 0) ||
setup_conds(thd, table_list, &conds) || thd->net.report_error)
DBUG_RETURN(1);
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 58b876704b0..e4f7214ad00 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -301,7 +301,7 @@ JOIN::prepare(Item ***rref_pointer_array,
/* Check that all tables, fields, conds and order are ok */
- if (setup_tables(tables_list) ||
+ if (setup_tables(tables_list, 0) ||
setup_wild(thd, tables_list, fields_list, &all_fields, wild_num) ||
select_lex->setup_ref_array(thd, og_num) ||
setup_fields(thd, (*rref_pointer_array), tables_list, fields_list, 1,
@@ -1015,7 +1015,7 @@ JOIN::reinit()
if (unit->select_limit_cnt == HA_POS_ERROR)
select_lex->options&= ~OPTION_FOUND_ROWS;
- if (setup_tables(tables_list))
+ if (setup_tables(tables_list, 1))
DBUG_RETURN(1);
/* Reset of sum functions */
@@ -1586,7 +1586,8 @@ mysql_select(THD *thd, Item ***rref_pointer_array,
}
else
{
- join= new JOIN(thd, fields, select_options, result);
+ if (!(join= new JOIN(thd, fields, select_options, result)))
+ DBUG_RETURN(-1);
thd->proc_info="init";
thd->used_tables=0; // Updated by setup_fields
if (join->prepare(rref_pointer_array, tables, wild_num,
@@ -9130,16 +9131,16 @@ int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
{
res= mysql_explain_select(thd, sl,
(((&thd->lex->select_lex)==sl)?
- ((thd->lex->all_selects_list != sl)?"PRIMARY":
- "SIMPLE"):
+ ((thd->lex->all_selects_list != sl) ?
+ primary_key_name : "SIMPLE"):
((sl == first)?
((sl->linkage == DERIVED_TABLE_TYPE) ?
"DERIVED":
- ((sl->uncacheable & UNCACHEABLE_DEPENDENT)?
+ ((sl->uncacheable & UNCACHEABLE_DEPENDENT) ?
"DEPENDENT SUBQUERY":
(sl->uncacheable?"UNCACHEABLE SUBQUERY":
"SUBQUERY"))):
- ((sl->uncacheable & UNCACHEABLE_DEPENDENT)?
+ ((sl->uncacheable & UNCACHEABLE_DEPENDENT) ?
"DEPENDENT UNION":
sl->uncacheable?"UNCACHEABLE UNION":
"UNION"))),
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 52f7e6cb9ed..4ae59093a0e 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -997,6 +997,19 @@ mysqld_dump_create_info(THD *thd, TABLE *table, int fd)
DBUG_RETURN(0);
}
+/* possible TODO: call find_keyword() from sql_lex.cc here */
+static bool require_quotes(const char *name, uint length)
+{
+ uint i, d, c;
+ for (i=0; i<length; i+=d)
+ {
+ c=((uchar *)name)[i];
+ d=my_mbcharlen(system_charset_info, c);
+ if (d==1 && !system_charset_info->ident_map[c])
+ return 1;
+ }
+ return 0;
+}
void
append_identifier(THD *thd, String *packet, const char *name, uint length)
@@ -1007,7 +1020,8 @@ append_identifier(THD *thd, String *packet, const char *name, uint length)
else
qtype= '`';
- if (thd->options & OPTION_QUOTE_SHOW_CREATE)
+ if ((thd->options & OPTION_QUOTE_SHOW_CREATE) ||
+ require_quotes(name, length))
{
packet->append(&qtype, 1);
packet->append(name, length, system_charset_info);
@@ -1167,7 +1181,7 @@ store_create_info(THD *thd, TABLE *table, String *packet)
bool found_primary=0;
packet->append(",\n ", 4);
- if (i == primary_key && !strcmp(key_info->name,"PRIMARY"))
+ if (i == primary_key && !strcmp(key_info->name, primary_key_name))
{
found_primary=1;
packet->append("PRIMARY ", 8);
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index ecd5f9ccb66..413fb77d929 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -29,7 +29,7 @@
#include <io.h>
#endif
-static const char *primary_key_name="PRIMARY";
+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);
@@ -2242,13 +2242,15 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
KEY *key_info=table->key_info;
for (uint i=0 ; i < table->keys ; i++,key_info++)
{
- if (drop_primary && (key_info->flags & HA_NOSAME))
+ char *key_name= key_info->name;
+
+ if (drop_primary && (key_info-> flags & HA_NOSAME) &&
+ !my_strcasecmp(system_charset_info, key_name, primary_key_name))
{
- drop_primary=0;
+ drop_primary= 0;
continue;
}
- char *key_name=key_info->name;
Alter_drop *drop;
drop_it.rewind();
while ((drop=drop_it++))
@@ -2303,7 +2305,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
key_list.push_back(new Key(key_info->flags & HA_SPATIAL ? Key::SPATIAL :
(key_info->flags & HA_NOSAME ?
(!my_strcasecmp(system_charset_info,
- key_name, "PRIMARY") ?
+ key_name, primary_key_name) ?
Key::PRIMARY : Key::UNIQUE) :
(key_info->flags & HA_FULLTEXT ?
Key::FULLTEXT : Key::MULTIPLE)),
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 25620229844..260903c9dd1 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -29,7 +29,7 @@ int mysql_union(THD *thd, LEX *lex, select_result *result,
{
DBUG_ENTER("mysql_union");
int res= 0;
- if (!(res= unit->prepare(thd, result)))
+ if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK)))
res= unit->exec();
res|= unit->cleanup();
DBUG_RETURN(res);
@@ -106,7 +106,8 @@ bool select_union::flush()
}
-int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result)
+int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
+ ulong additional_options)
{
SELECT_LEX *lex_select_save= thd_arg->lex->current_select;
SELECT_LEX *sl, *first_select;
@@ -146,7 +147,7 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result)
for (;sl; sl= sl->next_select())
{
JOIN *join= new JOIN(thd_arg, sl->item_list,
- sl->options | thd_arg->options | SELECT_NO_UNLOCK,
+ sl->options | thd_arg->options | additional_options,
tmp_result);
thd_arg->lex->current_select= sl;
offset_limit_cnt= sl->offset_limit;
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index cdea32ad3f6..9fc8d482bfa 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -95,7 +95,7 @@ int mysql_update(THD *thd,
tables.table= table;
tables.alias= table_list->alias;
- if (setup_tables(update_table_list) ||
+ if (setup_tables(update_table_list, 0) ||
setup_conds(thd,update_table_list,&conds) ||
thd->lex->select_lex.setup_ref_array(thd, order_num) ||
setup_order(thd, thd->lex->select_lex.ref_pointer_array,
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 5fee5ab13a7..0532a1b375f 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1077,7 +1077,7 @@ create_table_options:
create_table_option:
ENGINE_SYM opt_equal storage_engines { Lex->create_info.db_type= $3; }
- | TYPE_SYM opt_equal storage_engines { Lex->create_info.db_type= $3; WARN_DEPRECATED("TYPE=database_engine","ENGINE=database_engine"); }
+ | TYPE_SYM opt_equal storage_engines { Lex->create_info.db_type= $3; WARN_DEPRECATED("TYPE=storage_engine","ENGINE=storage_engine"); }
| MAX_ROWS opt_equal ulonglong_num { Lex->create_info.max_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MAX_ROWS;}
| MIN_ROWS opt_equal ulonglong_num { Lex->create_info.min_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MIN_ROWS;}
| AVG_ROW_LENGTH opt_equal ULONG_NUM { Lex->create_info.avg_row_length=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AVG_ROW_LENGTH;}
diff --git a/sql/table.cc b/sql/table.cc
index 912c133e571..1127349db20 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -481,8 +481,8 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
/* Fix key->name and key_part->field */
if (key_parts)
{
- uint primary_key=(uint) (find_type((char*) "PRIMARY",&outparam->keynames,
- 3)-1);
+ uint primary_key=(uint) (find_type((char*) primary_key_name,
+ &outparam->keynames, 3) - 1);
uint ha_option=outparam->file->table_flags();
keyinfo=outparam->key_info;
key_part=keyinfo->key_part;
diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c
index 271c56b8a0a..b5e8c4598a0 100644
--- a/strings/ctype-mb.c
+++ b/strings/ctype-mb.c
@@ -271,7 +271,7 @@ uint my_charpos_mb(CHARSET_INFO *cs __attribute__((unused)),
b+= (mblen= my_ismbchar(cs,b,e)) ? mblen : 1;
pos--;
}
- return b-b0;
+ return pos ? e+2-b0 : b-b0;
}
uint my_instr_mb(CHARSET_INFO *cs,
diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh
index 5a9fbf64b1c..1ee88096def 100644
--- a/support-files/mysql.spec.sh
+++ b/support-files/mysql.spec.sh
@@ -220,7 +220,8 @@ sh -c "PATH=\"${MYSQL_BUILD_PATH:-$PATH}\" \
--includedir=%{_includedir} \
--mandir=%{_mandir} \
--enable-thread-safe-client \
- --with-comment=\"Official MySQL RPM\";
+ --with-comment=\"Official MySQL RPM\" \
+ --with-readline ;
# Add this for more debugging support
# --with-debug
# Add this for MyISAM RAID support:
@@ -574,6 +575,10 @@ fi
# The spec file changelog only includes changes made to the spec file
# itself
%changelog
+* Tue Jan 13 2004 Lenz Grimmer <lenz@mysql.com>
+
+- link the mysql client against libreadline instead of libedit (BUG 2289)
+
* Fri Dec 13 2003 Lenz Grimmer <lenz@mysql.com>
- fixed file permissions (BUG 1672)