summaryrefslogtreecommitdiff
path: root/sql/derror.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/derror.cc')
-rw-r--r--sql/derror.cc86
1 files changed, 67 insertions, 19 deletions
diff --git a/sql/derror.cc b/sql/derror.cc
index a8cfa00ad1d..fd9cb02095f 100644
--- a/sql/derror.cc
+++ b/sql/derror.cc
@@ -1,4 +1,5 @@
/* Copyright (C) 2000-2005 MySQL AB
+ 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
@@ -24,6 +25,7 @@
#include "mysql_priv.h"
#include "mysys_err.h"
+static bool check_error_mesg(const char *file_name, const char **errmsg);
static bool read_texts(const char *file_name,const char ***point,
uint error_messages);
static void init_myfunc_errs(void);
@@ -32,9 +34,12 @@ static void init_myfunc_errs(void);
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
@@ -44,25 +49,44 @@ static void init_myfunc_errs(void);
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, &errmsgs, ER_ERROR_LAST - ER_ERROR_FIRST + 1) &&
- !errmsgs)
+ if (read_texts(ERRMSG_FILE, &errmsgs, ER_ERROR_LAST - ER_ERROR_FIRST + 1) ||
+ check_error_mesg(ERRMSG_FILE, 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= "";
+ x_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
+ x_free(org_errmsgs); // Free old language
/* Register messages for use with my_error(). */
if (my_error_register(errmsgs, ER_ERROR_FIRST, ER_ERROR_LAST))
@@ -73,7 +97,29 @@ bool init_errmessage(void)
errmesg= errmsgs; /* Init global variabel */
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_ERROR_LAST - 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;
}
@@ -99,6 +145,8 @@ static bool read_texts(const char *file_name,const char ***point,
const char *errmsg;
DBUG_ENTER("read_texts");
+ *point= 0;
+
LINT_INIT(buff);
funktpos=0;
if ((file=my_open(fn_format(name,file_name,language,"",4),
@@ -108,6 +156,7 @@ static bool read_texts(const char *file_name,const char ***point,
funktpos=1;
if (my_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 */
@@ -133,19 +182,16 @@ Please install the latest version of this file.",name);
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(my_close(file,MYF(MY_WME)));
DBUG_RETURN(1);
}
- x_free((uchar*) *point); /* Free old language */
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);
@@ -169,9 +215,11 @@ Check that the above file is the right version for this program!",
err:
switch (funktpos) {
- case 2:
+ 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;