summaryrefslogtreecommitdiff
path: root/sql/derror.cc
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2011-10-19 21:45:18 +0200
committerSergei Golubchik <sergii@pisem.net>2011-10-19 21:45:18 +0200
commit76f0b94bb0b2994d639353530c5b251d0f1a204b (patch)
tree9ed50628aac34f89a37637bab2fc4915b86b5eb4 /sql/derror.cc
parent4e46d8e5bff140f2549841167dc4b65a3c0a645d (diff)
parent5dc1a2231f55bacc9aaf0e24816f3d9c2ee1f21d (diff)
downloadmariadb-git-76f0b94bb0b2994d639353530c5b251d0f1a204b.tar.gz
merge with 5.3
sql/sql_insert.cc: CREATE ... IF NOT EXISTS may do nothing, but it is still not a failure. don't forget to my_ok it. ****** CREATE ... IF NOT EXISTS may do nothing, but it is still not a failure. don't forget to my_ok it. sql/sql_table.cc: small cleanup ****** small cleanup
Diffstat (limited to 'sql/derror.cc')
-rw-r--r--sql/derror.cc103
1 files changed, 81 insertions, 22 deletions
diff --git a/sql/derror.cc b/sql/derror.cc
index 2b4cc13073e..23319ac0c99 100644
--- a/sql/derror.cc
+++ b/sql/derror.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ Copyright (C) 2011 Monty Program 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
@@ -28,6 +29,7 @@
#include "derror.h" // read_texts
#include "sql_class.h" // THD
+static bool check_error_mesg(const char *file_name, const char **errmsg);
static void init_myfunc_errs(void);
@@ -44,9 +46,12 @@ C_MODE_END
Read messages from errorfile.
This function can be called multiple times to reload the messages.
- If it fails to load the messages, it will fail softly by initializing
- the errmesg pointer to an array of empty strings or by keeping the
- old array if it exists.
+
+ If it fails to load the messages:
+ - If we already have error messages loaded, keep the old ones and
+ return FALSE(ok)
+ - Initializing the errmesg pointer to an array of empty strings
+ and return TRUE (error)
@retval
FALSE OK
@@ -56,26 +61,45 @@ C_MODE_END
bool init_errmessage(void)
{
- const char **errmsgs, **ptr;
+ const char **errmsgs, **ptr, **org_errmsgs;
+ bool error= FALSE;
DBUG_ENTER("init_errmessage");
/*
Get a pointer to the old error messages pointer array.
read_texts() tries to free it.
*/
- errmsgs= my_error_unregister(ER_ERROR_FIRST, ER_ERROR_LAST);
+ org_errmsgs= my_error_unregister(ER_ERROR_FIRST, ER_ERROR_LAST);
/* Read messages from file. */
if (read_texts(ERRMSG_FILE, my_default_lc_messages->errmsgs->language,
&errmsgs, ER_ERROR_LAST - ER_ERROR_FIRST + 1) &&
!errmsgs)
{
- if (!(errmsgs= (const char**) my_malloc((ER_ERROR_LAST-ER_ERROR_FIRST+1)*
- sizeof(char*), MYF(0))))
- DBUG_RETURN(TRUE);
- for (ptr= errmsgs; ptr < errmsgs + ER_ERROR_LAST - ER_ERROR_FIRST; ptr++)
- *ptr= "";
+ free(errmsgs);
+
+ if (org_errmsgs)
+ {
+ /* Use old error messages */
+ errmsgs= org_errmsgs;
+ }
+ else
+ {
+ /*
+ No error messages. Create a temporary empty error message so
+ that we don't get a crash if some code wrongly tries to access
+ a non existing error message.
+ */
+ if (!(errmsgs= (const char**) my_malloc((ER_ERROR_LAST-ER_ERROR_FIRST+1)*
+ sizeof(char*), MYF(0))))
+ DBUG_RETURN(TRUE);
+ for (ptr= errmsgs; ptr < errmsgs + ER_ERROR_LAST - ER_ERROR_FIRST; ptr++)
+ *ptr= "";
+ error= TRUE;
+ }
}
+ else
+ free(org_errmsgs); // Free old language
/* Register messages for use with my_error(). */
if (my_error_register(get_server_errmsgs, ER_ERROR_FIRST, ER_ERROR_LAST))
@@ -86,7 +110,29 @@ bool init_errmessage(void)
DEFAULT_ERRMSGS= errmsgs; /* Init global variable */
init_myfunc_errs(); /* Init myfunc messages */
- DBUG_RETURN(FALSE);
+ DBUG_RETURN(error);
+}
+
+
+/**
+ Check the error messages array contains all relevant error messages
+*/
+
+static bool check_error_mesg(const char *file_name, const char **errmsg)
+{
+ /*
+ The last MySQL error message can't be an empty string; If it is,
+ it means that the error file doesn't contain all MySQL messages
+ and is probably from an older version of MySQL / MariaDB.
+ */
+ if (errmsg[ER_LAST_MYSQL_ERROR_MESSAGE -1 - ER_ERROR_FIRST][0] == 0)
+ {
+ sql_print_error("Error message file '%s' is probably from and older "
+ "version of MariaDB / MYSQL as it doesn't contain all "
+ "error messages", file_name);
+ return 1;
+ }
+ return 0;
}
@@ -107,8 +153,11 @@ bool read_texts(const char *file_name, const char *language,
char lang_path[FN_REFLEN];
uchar *buff;
uchar head[32],*pos;
+ const char *errmsg;
DBUG_ENTER("read_texts");
+ *point= 0;
+
LINT_INIT(buff);
funktpos=0;
convert_dirname(lang_path, language, NullS);
@@ -136,6 +185,7 @@ bool read_texts(const char *file_name, const char *language,
funktpos=1;
if (mysql_file_read(file, (uchar*) head, 32, MYF(MY_NABP)))
goto err;
+ funktpos=2;
if (head[0] != (uchar) 254 || head[1] != (uchar) 254 ||
head[2] != 2 || head[3] != 1)
goto err; /* purecov: inspected */
@@ -147,20 +197,16 @@ bool read_texts(const char *file_name, const char *language,
if (count < error_messages)
{
sql_print_error("\
-Error message file '%s' had only %d error messages,\n\
-but it should contain at least %d error messages.\n\
-Check that the above file is the right version for this program!",
+Error message file '%s' had only %d error messages, but it should contain at least %d error messages.\nCheck that the above file is the right version for this program!",
name,count,error_messages);
(void) mysql_file_close(file, MYF(MY_WME));
DBUG_RETURN(1);
}
- /* Free old language */
- my_free(*point);
if (!(*point= (const char**)
my_malloc((size_t) (length+count*sizeof(char*)),MYF(0))))
{
- funktpos=2; /* purecov: inspected */
+ funktpos=3; /* purecov: inspected */
goto err; /* purecov: inspected */
}
buff= (uchar*) (*point + count);
@@ -180,12 +226,25 @@ Check that the above file is the right version for this program!",
point[i]= *point +uint2korr(head+10+i+i);
}
(void) mysql_file_close(file, MYF(0));
- DBUG_RETURN(0);
+
+ i= check_error_mesg(file_name, *point);
+ DBUG_RETURN(i);
err:
- sql_print_error((funktpos == 2) ? "Not enough memory for messagefile '%s'" :
- ((funktpos == 1) ? "Can't read from messagefile '%s'" :
- "Can't find messagefile '%s'"), name);
+ switch (funktpos) {
+ case 3:
+ errmsg= "Not enough memory for messagefile '%s'";
+ break;
+ case 2:
+ errmsg= "Incompatible header in messagefile '%s'. Probably from another version of MariaDB";
+ case 1:
+ errmsg= "Can't read from messagefile '%s'";
+ break;
+ default:
+ errmsg= "Can't find messagefile '%s'";
+ break;
+ }
+ sql_print_error(errmsg, name);
if (file != FERR)
(void) mysql_file_close(file, MYF(MY_WME));
DBUG_RETURN(1);