mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Added new range of MariaDB error messages, starting from 3000
This is done by splitting variables.errmsg and locale.errmsg to variables.errmsg_extra and locale.errmsg_extra The ER() macros in unireg.h now looks more complex than before, but this isn't critical as most usage of them are with constants and the compiler will remove most of the test code.
This commit is contained in:
@ -32,9 +32,11 @@
|
|||||||
#include <my_getopt.h>
|
#include <my_getopt.h>
|
||||||
#include <my_dir.h>
|
#include <my_dir.h>
|
||||||
|
|
||||||
#define MAX_ROWS 2000
|
#define MAX_ROWS 3000
|
||||||
|
#define ERRORS_PER_RANGE 1000
|
||||||
|
#define MAX_SECTIONS 4
|
||||||
#define HEADER_LENGTH 32 /* Length of header in errmsg.sys */
|
#define HEADER_LENGTH 32 /* Length of header in errmsg.sys */
|
||||||
#define ERRMSG_VERSION 3 /* Version number of errmsg.sys */
|
#define ERRMSG_VERSION 4 /* Version number of errmsg.sys */
|
||||||
#define DEFAULT_CHARSET_DIR "../sql/share/charsets"
|
#define DEFAULT_CHARSET_DIR "../sql/share/charsets"
|
||||||
#define ER_PREFIX "ER_"
|
#define ER_PREFIX "ER_"
|
||||||
#define ER_PREFIX2 "MARIA_ER_"
|
#define ER_PREFIX2 "MARIA_ER_"
|
||||||
@ -53,6 +55,8 @@ static char *default_dbug_option= (char*) "d:t:O,/tmp/comp_err.trace";
|
|||||||
uchar file_head[]= { 254, 254, 2, ERRMSG_VERSION };
|
uchar file_head[]= { 254, 254, 2, ERRMSG_VERSION };
|
||||||
/* Store positions to each error message row to store in errmsg.sys header */
|
/* Store positions to each error message row to store in errmsg.sys header */
|
||||||
uint file_pos[MAX_ROWS+1];
|
uint file_pos[MAX_ROWS+1];
|
||||||
|
uint section_count,section_start;
|
||||||
|
uchar section_header[MAX_SECTIONS*2];
|
||||||
|
|
||||||
const char *empty_string= ""; /* For empty states */
|
const char *empty_string= ""; /* For empty states */
|
||||||
/*
|
/*
|
||||||
@ -131,7 +135,7 @@ static struct my_option my_long_options[]=
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static struct errors *generate_empty_message(uint dcode);
|
static struct errors *generate_empty_message(uint dcode, my_bool skip);
|
||||||
static struct languages *parse_charset_string(char *str);
|
static struct languages *parse_charset_string(char *str);
|
||||||
static struct errors *parse_error_string(char *ptr, int er_count);
|
static struct errors *parse_error_string(char *ptr, int er_count);
|
||||||
static struct message *parse_message_string(struct message *new_message,
|
static struct message *parse_message_string(struct message *new_message,
|
||||||
@ -140,8 +144,8 @@ static struct message *find_message(struct errors *err, const char *lang,
|
|||||||
my_bool no_default);
|
my_bool no_default);
|
||||||
static int check_message_format(struct errors *err,
|
static int check_message_format(struct errors *err,
|
||||||
const char* mess);
|
const char* mess);
|
||||||
static int parse_input_file(const char *file_name, struct errors **top_error,
|
static uint parse_input_file(const char *file_name, struct errors **top_error,
|
||||||
struct languages **top_language);
|
struct languages **top_language);
|
||||||
static int get_options(int *argc, char ***argv);
|
static int get_options(int *argc, char ***argv);
|
||||||
static void print_version(void);
|
static void print_version(void);
|
||||||
static void usage(void);
|
static void usage(void);
|
||||||
@ -226,6 +230,7 @@ static void print_escaped_string(FILE *f, const char *str)
|
|||||||
static int create_header_files(struct errors *error_head)
|
static int create_header_files(struct errors *error_head)
|
||||||
{
|
{
|
||||||
uint er_last= 0;
|
uint er_last= 0;
|
||||||
|
uint section= 1;
|
||||||
FILE *er_definef, *sql_statef, *er_namef;
|
FILE *er_definef, *sql_statef, *er_namef;
|
||||||
struct errors *tmp_error;
|
struct errors *tmp_error;
|
||||||
struct message *er_msg;
|
struct message *er_msg;
|
||||||
@ -266,8 +271,19 @@ static int create_header_files(struct errors *error_head)
|
|||||||
if (!tmp_error->er_name)
|
if (!tmp_error->er_name)
|
||||||
continue; /* Placeholder for gap */
|
continue; /* Placeholder for gap */
|
||||||
|
|
||||||
if (tmp_error->d_code > current_d_code + 1)
|
while (tmp_error->d_code > current_d_code + 1)
|
||||||
|
{
|
||||||
|
uint next_range= (((current_d_code + ERRORS_PER_RANGE) /
|
||||||
|
ERRORS_PER_RANGE) * ERRORS_PER_RANGE);
|
||||||
|
|
||||||
|
fprintf(er_definef, "#define ER_ERROR_LAST_SECTION_%d %d\n", section,
|
||||||
|
current_d_code);
|
||||||
fprintf(er_definef, "\n/* New section */\n\n");
|
fprintf(er_definef, "\n/* New section */\n\n");
|
||||||
|
fprintf(er_definef, "#define ER_ERROR_FIRST_SECTION_%d %d\n", section+1,
|
||||||
|
MY_MIN(tmp_error->d_code, next_range));
|
||||||
|
section++;
|
||||||
|
current_d_code= MY_MIN(tmp_error->d_code, next_range);
|
||||||
|
}
|
||||||
current_d_code= tmp_error->d_code;
|
current_d_code= tmp_error->d_code;
|
||||||
|
|
||||||
fprintf(er_definef, "#define %s %u\n", tmp_error->er_name,
|
fprintf(er_definef, "#define %s %u\n", tmp_error->er_name,
|
||||||
@ -301,13 +317,12 @@ static int create_sys_files(struct languages *lang_head,
|
|||||||
{
|
{
|
||||||
FILE *to;
|
FILE *to;
|
||||||
uint csnum= 0, length, i, row_nr;
|
uint csnum= 0, length, i, row_nr;
|
||||||
uchar head[32];
|
uchar head[HEADER_LENGTH];
|
||||||
char outfile[FN_REFLEN], *outfile_end;
|
char outfile[FN_REFLEN], *outfile_end;
|
||||||
long start_pos;
|
long start_pos;
|
||||||
struct message *tmp;
|
struct message *tmp;
|
||||||
struct languages *tmp_lang;
|
struct languages *tmp_lang;
|
||||||
struct errors *tmp_error;
|
struct errors *tmp_error;
|
||||||
|
|
||||||
MY_STAT stat_info;
|
MY_STAT stat_info;
|
||||||
DBUG_ENTER("create_sys_files");
|
DBUG_ENTER("create_sys_files");
|
||||||
|
|
||||||
@ -331,7 +346,7 @@ static int create_sys_files(struct languages *lang_head,
|
|||||||
{
|
{
|
||||||
if (my_mkdir(outfile, 0777,MYF(0)) < 0)
|
if (my_mkdir(outfile, 0777,MYF(0)) < 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Can't create output directory for %s\n",
|
fprintf(stderr, "Can't creqate output directory for %s\n",
|
||||||
outfile);
|
outfile);
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
@ -343,7 +358,7 @@ static int create_sys_files(struct languages *lang_head,
|
|||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
/* 2 is for 2 bytes to store row position / error message */
|
/* 2 is for 2 bytes to store row position / error message */
|
||||||
start_pos= (long) (HEADER_LENGTH + row_count * 2);
|
start_pos= (long) (HEADER_LENGTH + (row_count + section_count) * 2);
|
||||||
fseek(to, start_pos, 0);
|
fseek(to, start_pos, 0);
|
||||||
row_nr= 0;
|
row_nr= 0;
|
||||||
for (tmp_error= error_head; tmp_error; tmp_error= tmp_error->next_error)
|
for (tmp_error= error_head; tmp_error; tmp_error= tmp_error->next_error)
|
||||||
@ -358,25 +373,31 @@ static int create_sys_files(struct languages *lang_head,
|
|||||||
"language\n", tmp_error->er_name, tmp_lang->lang_short_name);
|
"language\n", tmp_error->er_name, tmp_lang->lang_short_name);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (copy_rows(to, tmp->text, row_nr, start_pos))
|
if (tmp->text) /* If not skipped row */
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Failed to copy rows to %s\n", outfile);
|
if (copy_rows(to, tmp->text, row_nr, start_pos))
|
||||||
goto err;
|
{
|
||||||
|
fprintf(stderr, "Failed to copy rows to %s\n", outfile);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
row_nr++;
|
||||||
}
|
}
|
||||||
row_nr++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* continue with header of the errmsg.sys file */
|
/* continue with header of the errmsg.sys file */
|
||||||
length= ftell(to) - HEADER_LENGTH - row_count * 2;
|
length= ftell(to) - HEADER_LENGTH - (row_count + section_count) * 2;
|
||||||
bzero((uchar*) head, HEADER_LENGTH);
|
bzero((uchar*) head, HEADER_LENGTH);
|
||||||
bmove((uchar *) head, (uchar *) file_head, 4);
|
bmove((uchar *) head, (uchar *) file_head, 4);
|
||||||
head[4]= 1;
|
head[4]= 1;
|
||||||
int4store(head + 6, length);
|
int4store(head + 6, length);
|
||||||
int2store(head + 10, row_count);
|
int2store(head + 10, row_count);
|
||||||
|
int2store(head + 12, section_count);
|
||||||
head[30]= csnum;
|
head[30]= csnum;
|
||||||
|
|
||||||
my_fseek(to, 0l, MY_SEEK_SET, MYF(0));
|
my_fseek(to, 0l, MY_SEEK_SET, MYF(0));
|
||||||
if (my_fwrite(to, (uchar*) head, HEADER_LENGTH, MYF(MY_WME | MY_FNABP)))
|
if (my_fwrite(to, (uchar*) head, HEADER_LENGTH, MYF(MY_WME | MY_FNABP)) ||
|
||||||
|
my_fwrite(to, (uchar*) section_header, section_count*2,
|
||||||
|
MYF(MY_WME | MY_FNABP)))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
file_pos[row_count]= (ftell(to) - start_pos);
|
file_pos[row_count]= (ftell(to) - start_pos);
|
||||||
@ -437,8 +458,8 @@ static void clean_up(struct languages *lang_head, struct errors *error_head)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int parse_input_file(const char *file_name, struct errors **top_error,
|
static uint parse_input_file(const char *file_name, struct errors **top_error,
|
||||||
struct languages **top_lang)
|
struct languages **top_lang)
|
||||||
{
|
{
|
||||||
FILE *file;
|
FILE *file;
|
||||||
char *str, buff[1000];
|
char *str, buff[1000];
|
||||||
@ -450,11 +471,15 @@ static int parse_input_file(const char *file_name, struct errors **top_error,
|
|||||||
|
|
||||||
*top_error= 0;
|
*top_error= 0;
|
||||||
*top_lang= 0;
|
*top_lang= 0;
|
||||||
|
section_start= er_offset;
|
||||||
|
section_count= 0;
|
||||||
|
|
||||||
if (!(file= my_fopen(file_name, O_RDONLY | O_SHARE, MYF(MY_WME))))
|
if (!(file= my_fopen(file_name, O_RDONLY | O_SHARE, MYF(MY_WME))))
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
while ((str= fgets(buff, sizeof(buff), file)))
|
while ((str= fgets(buff, sizeof(buff), file)))
|
||||||
{
|
{
|
||||||
|
my_bool skip;
|
||||||
if (is_prefix(str, "language"))
|
if (is_prefix(str, "language"))
|
||||||
{
|
{
|
||||||
if (!(*top_lang= parse_charset_string(str)))
|
if (!(*top_lang= parse_charset_string(str)))
|
||||||
@ -464,18 +489,34 @@ static int parse_input_file(const char *file_name, struct errors **top_error,
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (is_prefix(str, "start-error-number"))
|
skip= 0;
|
||||||
|
if (is_prefix(str, "start-error-number") ||
|
||||||
|
(skip= is_prefix(str, "skip-to-error-number")))
|
||||||
{
|
{
|
||||||
uint tmp_er_offset;
|
uint tmp_er_offset;
|
||||||
|
|
||||||
if (!(tmp_er_offset= parse_error_offset(str)))
|
if (!(tmp_er_offset= parse_error_offset(str)))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Failed to parse the error offset string!\n");
|
fprintf(stderr, "Failed to parse the error offset string!\n");
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
if (skip)
|
||||||
|
{
|
||||||
|
if (section_count >= MAX_SECTIONS-1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Found too many skip-to-error-number entries. "
|
||||||
|
"We only support %d entries\n", MAX_SECTIONS);
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
int2store(section_header + section_count*2,
|
||||||
|
er_offset +rcount - section_start);
|
||||||
|
section_count++;
|
||||||
|
section_start= tmp_er_offset;
|
||||||
|
}
|
||||||
if (!er_offset_found)
|
if (!er_offset_found)
|
||||||
{
|
{
|
||||||
er_offset_found= 1;
|
er_offset_found= 1;
|
||||||
er_offset= tmp_er_offset;
|
er_offset= section_start= tmp_er_offset;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -487,7 +528,7 @@ static int parse_input_file(const char *file_name, struct errors **top_error,
|
|||||||
}
|
}
|
||||||
for ( ; er_offset + rcount < tmp_er_offset ; rcount++)
|
for ( ; er_offset + rcount < tmp_er_offset ; rcount++)
|
||||||
{
|
{
|
||||||
current_error= generate_empty_message(er_offset + rcount);
|
current_error= generate_empty_message(er_offset + rcount, skip);
|
||||||
*tail_error= current_error;
|
*tail_error= current_error;
|
||||||
tail_error= ¤t_error->next_error;
|
tail_error= ¤t_error->next_error;
|
||||||
}
|
}
|
||||||
@ -559,6 +600,10 @@ static int parse_input_file(const char *file_name, struct errors **top_error,
|
|||||||
fprintf(stderr, "Wrong input file format. Stop!\nLine: %s\n", str);
|
fprintf(stderr, "Wrong input file format. Stop!\nLine: %s\n", str);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
int2store(section_header + section_count*2,
|
||||||
|
er_offset + rcount - section_start);
|
||||||
|
section_count++;
|
||||||
|
|
||||||
*tail_error= 0; /* Mark end of list */
|
*tail_error= 0; /* Mark end of list */
|
||||||
|
|
||||||
my_fclose(file, MYF(0));
|
my_fclose(file, MYF(0));
|
||||||
@ -887,7 +932,7 @@ static struct message *parse_message_string(struct message *new_message,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static struct errors *generate_empty_message(uint d_code)
|
static struct errors *generate_empty_message(uint d_code, my_bool skip)
|
||||||
{
|
{
|
||||||
struct errors *new_error;
|
struct errors *new_error;
|
||||||
struct message message;
|
struct message message;
|
||||||
@ -896,7 +941,8 @@ static struct errors *generate_empty_message(uint d_code)
|
|||||||
if (!(new_error= (struct errors *) my_malloc(sizeof(*new_error),
|
if (!(new_error= (struct errors *) my_malloc(sizeof(*new_error),
|
||||||
MYF(MY_WME))))
|
MYF(MY_WME))))
|
||||||
return(0);
|
return(0);
|
||||||
if (my_init_dynamic_array(&new_error->msg, sizeof(struct message), 0, 1, MYF(0)))
|
if (my_init_dynamic_array(&new_error->msg, sizeof(struct message), 0, 1,
|
||||||
|
MYF(0)))
|
||||||
return(0); /* OOM: Fatal error */
|
return(0); /* OOM: Fatal error */
|
||||||
|
|
||||||
new_error->er_name= NULL;
|
new_error->er_name= NULL;
|
||||||
@ -904,8 +950,10 @@ static struct errors *generate_empty_message(uint d_code)
|
|||||||
new_error->sql_code1= empty_string;
|
new_error->sql_code1= empty_string;
|
||||||
new_error->sql_code2= empty_string;
|
new_error->sql_code2= empty_string;
|
||||||
|
|
||||||
|
message.text= 0; /* If skip set, don't generate a text */
|
||||||
|
|
||||||
if (!(message.lang_short_name= my_strdup(default_language, MYF(MY_WME))) ||
|
if (!(message.lang_short_name= my_strdup(default_language, MYF(MY_WME))) ||
|
||||||
!(message.text= my_strdup("", MYF(MY_WME))))
|
(!skip && !(message.text= my_strdup("", MYF(MY_WME)))))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
/* Can't fail as msg is preallocated */
|
/* Can't fail as msg is preallocated */
|
||||||
|
@ -689,7 +689,7 @@ extern void my_osmaperr(unsigned long last_error);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern void init_glob_errs(void);
|
extern void init_glob_errs(void);
|
||||||
extern const char** get_global_errmsgs(void);
|
extern const char** get_global_errmsgs(int nr);
|
||||||
extern void wait_for_free_space(const char *filename, int errors);
|
extern void wait_for_free_space(const char *filename, int errors);
|
||||||
extern FILE *my_fopen(const char *FileName,int Flags,myf MyFlags);
|
extern FILE *my_fopen(const char *FileName,int Flags,myf MyFlags);
|
||||||
extern FILE *my_fdopen(File Filedes,const char *name, int Flags,myf MyFlags);
|
extern FILE *my_fdopen(File Filedes,const char *name, int Flags,myf MyFlags);
|
||||||
@ -714,9 +714,9 @@ extern void my_printf_error(uint my_err, const char *format,
|
|||||||
ATTRIBUTE_FORMAT(printf, 2, 4);
|
ATTRIBUTE_FORMAT(printf, 2, 4);
|
||||||
extern void my_printv_error(uint error, const char *format, myf MyFlags,
|
extern void my_printv_error(uint error, const char *format, myf MyFlags,
|
||||||
va_list ap);
|
va_list ap);
|
||||||
extern int my_error_register(const char** (*get_errmsgs) (void),
|
extern int my_error_register(const char** (*get_errmsgs) (int nr),
|
||||||
uint first, uint last);
|
uint first, uint last);
|
||||||
extern const char **my_error_unregister(uint first, uint last);
|
extern my_bool my_error_unregister(uint first, uint last);
|
||||||
extern void my_message(uint my_err, const char *str,myf MyFlags);
|
extern void my_message(uint my_err, const char *str,myf MyFlags);
|
||||||
extern void my_message_stderr(uint my_err, const char *str, myf MyFlags);
|
extern void my_message_stderr(uint my_err, const char *str, myf MyFlags);
|
||||||
extern my_bool my_init(void);
|
extern my_bool my_init(void);
|
||||||
|
@ -90,7 +90,7 @@ const char *client_errors[]=
|
|||||||
""
|
""
|
||||||
};
|
};
|
||||||
|
|
||||||
const char** get_client_errmsgs(void)
|
const char** get_client_errmsgs(int nr __attribute((unused)))
|
||||||
{
|
{
|
||||||
return client_errors;
|
return client_errors;
|
||||||
}
|
}
|
||||||
|
@ -119,7 +119,7 @@ void wait_for_free_space(const char *filename, int errors)
|
|||||||
(void) sleep(MY_WAIT_FOR_USER_TO_FIX_PANIC);
|
(void) sleep(MY_WAIT_FOR_USER_TO_FIX_PANIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char **get_global_errmsgs()
|
const char **get_global_errmsgs(int nr __attribute((unused)))
|
||||||
{
|
{
|
||||||
return globerrs;
|
return globerrs;
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
static struct my_err_head
|
static struct my_err_head
|
||||||
{
|
{
|
||||||
struct my_err_head *meh_next; /* chain link */
|
struct my_err_head *meh_next; /* chain link */
|
||||||
const char** (*get_errmsgs)(); /* returns error message format */
|
const char** (*get_errmsgs)(int nr); /* returns error message format */
|
||||||
uint meh_first; /* error number matching array slot 0 */
|
uint meh_first; /* error number matching array slot 0 */
|
||||||
uint meh_last; /* error number matching last slot */
|
uint meh_last; /* error number matching last slot */
|
||||||
} my_errmsgs_globerrs=
|
} my_errmsgs_globerrs=
|
||||||
@ -86,7 +86,7 @@ const char *my_get_err_msg(uint nr)
|
|||||||
we return NULL.
|
we return NULL.
|
||||||
*/
|
*/
|
||||||
if (!(format= (meh_p && (nr >= meh_p->meh_first)) ?
|
if (!(format= (meh_p && (nr >= meh_p->meh_first)) ?
|
||||||
meh_p->get_errmsgs()[nr - meh_p->meh_first] : NULL) ||
|
meh_p->get_errmsgs(nr)[nr - meh_p->meh_first] : NULL) ||
|
||||||
!*format)
|
!*format)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -217,7 +217,8 @@ void my_message(uint error, const char *str, register myf MyFlags)
|
|||||||
@retval != 0 Error
|
@retval != 0 Error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int my_error_register(const char** (*get_errmsgs) (), uint first, uint last)
|
int my_error_register(const char** (*get_errmsgs)(int error), uint first,
|
||||||
|
uint last)
|
||||||
{
|
{
|
||||||
struct my_err_head *meh_p;
|
struct my_err_head *meh_p;
|
||||||
struct my_err_head **search_meh_pp;
|
struct my_err_head **search_meh_pp;
|
||||||
@ -273,11 +274,10 @@ int my_error_register(const char** (*get_errmsgs) (), uint first, uint last)
|
|||||||
@retval non-NULL OK, returns address of error messages pointers array.
|
@retval non-NULL OK, returns address of error messages pointers array.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const char **my_error_unregister(uint first, uint last)
|
my_bool my_error_unregister(uint first, uint last)
|
||||||
{
|
{
|
||||||
struct my_err_head *meh_p;
|
struct my_err_head *meh_p;
|
||||||
struct my_err_head **search_meh_pp;
|
struct my_err_head **search_meh_pp;
|
||||||
const char **errmsgs;
|
|
||||||
|
|
||||||
/* Search for the registration in the list. */
|
/* Search for the registration in the list. */
|
||||||
for (search_meh_pp= &my_errmsgs_list;
|
for (search_meh_pp= &my_errmsgs_list;
|
||||||
@ -289,17 +289,15 @@ const char **my_error_unregister(uint first, uint last)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (! *search_meh_pp)
|
if (! *search_meh_pp)
|
||||||
return NULL;
|
return TRUE;
|
||||||
|
|
||||||
/* Remove header from the chain. */
|
/* Remove header from the chain. */
|
||||||
meh_p= *search_meh_pp;
|
meh_p= *search_meh_pp;
|
||||||
*search_meh_pp= meh_p->meh_next;
|
*search_meh_pp= meh_p->meh_next;
|
||||||
|
|
||||||
/* Save the return value and free the header. */
|
|
||||||
errmsgs= meh_p->get_errmsgs();
|
|
||||||
my_free(meh_p);
|
my_free(meh_p);
|
||||||
|
|
||||||
return errmsgs;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
265
sql/derror.cc
265
sql/derror.cc
@ -30,16 +30,19 @@
|
|||||||
#include "derror.h" // read_texts
|
#include "derror.h" // read_texts
|
||||||
#include "sql_class.h" // THD
|
#include "sql_class.h" // THD
|
||||||
|
|
||||||
|
uint errors_per_range[MAX_ERROR_RANGES+1];
|
||||||
|
|
||||||
static bool check_error_mesg(const char *file_name, const char **errmsg);
|
static bool check_error_mesg(const char *file_name, const char **errmsg);
|
||||||
static void init_myfunc_errs(void);
|
static void init_myfunc_errs(void);
|
||||||
|
|
||||||
|
|
||||||
C_MODE_START
|
C_MODE_START
|
||||||
static const char **get_server_errmsgs()
|
static const char **get_server_errmsgs(int nr)
|
||||||
{
|
{
|
||||||
|
int section= (nr-ER_ERROR_FIRST) / ERRORS_PER_RANGE;
|
||||||
if (!current_thd)
|
if (!current_thd)
|
||||||
return DEFAULT_ERRMSGS;
|
return DEFAULT_ERRMSGS[section];
|
||||||
return CURRENT_THD_ERRMSGS;
|
return CURRENT_THD_ERRMSGS[section];
|
||||||
}
|
}
|
||||||
C_MODE_END
|
C_MODE_END
|
||||||
|
|
||||||
@ -60,61 +63,88 @@ C_MODE_END
|
|||||||
TRUE Error
|
TRUE Error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static const char ***original_error_messages;
|
||||||
|
|
||||||
bool init_errmessage(void)
|
bool init_errmessage(void)
|
||||||
{
|
{
|
||||||
const char **errmsgs, **ptr, **org_errmsgs;
|
const char **errmsgs;
|
||||||
bool error= FALSE;
|
bool error= FALSE;
|
||||||
DBUG_ENTER("init_errmessage");
|
DBUG_ENTER("init_errmessage");
|
||||||
|
|
||||||
/*
|
free_error_messages();
|
||||||
Get a pointer to the old error messages pointer array.
|
my_free(original_error_messages);
|
||||||
read_texts() tries to free it.
|
original_error_messages= 0;
|
||||||
*/
|
|
||||||
org_errmsgs= my_error_unregister(ER_ERROR_FIRST, ER_ERROR_LAST);
|
error_message_charset_info= system_charset_info;
|
||||||
|
|
||||||
/* Read messages from file. */
|
/* Read messages from file. */
|
||||||
if (read_texts(ERRMSG_FILE, my_default_lc_messages->errmsgs->language,
|
if (read_texts(ERRMSG_FILE, my_default_lc_messages->errmsgs->language,
|
||||||
&errmsgs, ER_ERROR_LAST - ER_ERROR_FIRST + 1) &&
|
&original_error_messages))
|
||||||
!errmsgs)
|
|
||||||
{
|
{
|
||||||
my_free(errmsgs);
|
/*
|
||||||
|
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 (!(original_error_messages= (const char***)
|
||||||
|
my_malloc(MAX_ERROR_RANGES * sizeof(char**) +
|
||||||
|
(ERRORS_PER_RANGE * sizeof(char*)),
|
||||||
|
MYF(0))))
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
errmsgs= (const char**) (original_error_messages + MAX_ERROR_RANGES);
|
||||||
|
|
||||||
if (org_errmsgs)
|
for (uint i=0 ; i < MAX_ERROR_RANGES ; i++)
|
||||||
{
|
{
|
||||||
/* Use old error messages */
|
original_error_messages[i]= errmsgs;
|
||||||
errmsgs= org_errmsgs;
|
errors_per_range[i]= ERRORS_PER_RANGE;
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
errors_per_range[2]= 0; // MYSYS error messages
|
||||||
|
|
||||||
|
for (const char **ptr= errmsgs;
|
||||||
|
ptr < errmsgs + ERRORS_PER_RANGE ;
|
||||||
|
ptr++)
|
||||||
|
*ptr= "";
|
||||||
|
|
||||||
|
error= TRUE;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
my_free(org_errmsgs); // Free old language
|
|
||||||
|
|
||||||
/* Register messages for use with my_error(). */
|
/* Register messages for use with my_error(). */
|
||||||
if (my_error_register(get_server_errmsgs, ER_ERROR_FIRST, ER_ERROR_LAST))
|
for (uint i=0 ; i < MAX_ERROR_RANGES ; i++)
|
||||||
{
|
{
|
||||||
my_free(errmsgs);
|
if (errors_per_range[i])
|
||||||
DBUG_RETURN(TRUE);
|
{
|
||||||
|
if (my_error_register(get_server_errmsgs, (i+1)*ERRORS_PER_RANGE,
|
||||||
|
(i+1)*ERRORS_PER_RANGE +
|
||||||
|
errors_per_range[i]-1))
|
||||||
|
{
|
||||||
|
my_free(original_error_messages);
|
||||||
|
original_error_messages= 0;
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
DEFAULT_ERRMSGS= original_error_messages;
|
||||||
DEFAULT_ERRMSGS= errmsgs; /* Init global variable */
|
|
||||||
init_myfunc_errs(); /* Init myfunc messages */
|
init_myfunc_errs(); /* Init myfunc messages */
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void free_error_messages()
|
||||||
|
{
|
||||||
|
/* We don't need to free errmsg as it's done in cleanup_errmsg */
|
||||||
|
for (uint i= 0 ; i < MAX_ERROR_RANGES ; i++)
|
||||||
|
{
|
||||||
|
if (errors_per_range[i])
|
||||||
|
{
|
||||||
|
my_error_unregister((i+1)*ERRORS_PER_RANGE,
|
||||||
|
(i+1)*ERRORS_PER_RANGE +
|
||||||
|
errors_per_range[i]-1);
|
||||||
|
errors_per_range[i]= 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Check the error messages array contains all relevant error messages
|
Check the error messages array contains all relevant error messages
|
||||||
*/
|
*/
|
||||||
@ -125,11 +155,17 @@ 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,
|
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
|
it means that the error file doesn't contain all MySQL messages
|
||||||
and is probably from an older version of MySQL / MariaDB.
|
and is probably from an older version of MySQL / MariaDB.
|
||||||
|
We also check that each section has enough error messages.
|
||||||
*/
|
*/
|
||||||
if (errmsg[ER_LAST_MYSQL_ERROR_MESSAGE -1 - ER_ERROR_FIRST][0] == 0)
|
if (errmsg[ER_LAST_MYSQL_ERROR_MESSAGE -1 - ER_ERROR_FIRST][0] == 0 ||
|
||||||
|
(errors_per_range[0] < ER_ERROR_LAST_SECTION_2 - ER_ERROR_FIRST + 1) ||
|
||||||
|
errors_per_range[1] != 0 ||
|
||||||
|
(errors_per_range[2] < ER_ERROR_LAST_SECTION_4 -
|
||||||
|
ER_ERROR_FIRST_SECTION_4 +1) ||
|
||||||
|
(errors_per_range[2] < ER_ERROR_LAST - ER_ERROR_FIRST_SECTION_5 + 1))
|
||||||
{
|
{
|
||||||
sql_print_error("Error message file '%s' is probably from and older "
|
sql_print_error("Error message file '%s' is probably from and older "
|
||||||
"version of MariaDB / MYSQL as it doesn't contain all "
|
"version of MariaDB as it doesn't contain all "
|
||||||
"error messages", file_name);
|
"error messages", file_name);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -137,27 +173,27 @@ static bool check_error_mesg(const char *file_name, const char **errmsg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
struct st_msg_file
|
||||||
Read text from packed textfile in language-directory.
|
{
|
||||||
|
uint sections;
|
||||||
|
uint errors;
|
||||||
|
size_t text_length;
|
||||||
|
};
|
||||||
|
|
||||||
If we can't read messagefile then it's panic- we can't continue.
|
/**
|
||||||
|
Open file for packed textfile in language-directory.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool read_texts(const char *file_name, const char *language,
|
static File open_error_msg_file(const char *file_name, const char *language,
|
||||||
const char ***point, uint error_messages)
|
uint error_messages, struct st_msg_file *ret)
|
||||||
{
|
{
|
||||||
register uint i;
|
int error_pos= 0;
|
||||||
uint count,funktpos;
|
|
||||||
size_t offset, length;
|
|
||||||
File file;
|
File file;
|
||||||
char name[FN_REFLEN];
|
char name[FN_REFLEN];
|
||||||
char lang_path[FN_REFLEN];
|
char lang_path[FN_REFLEN];
|
||||||
uchar *UNINIT_VAR(buff);
|
uchar head[32];
|
||||||
uchar head[32],*pos;
|
DBUG_ENTER("open_error_msg_file");
|
||||||
DBUG_ENTER("read_texts");
|
|
||||||
|
|
||||||
*point= 0;
|
|
||||||
funktpos=0;
|
|
||||||
convert_dirname(lang_path, language, NullS);
|
convert_dirname(lang_path, language, NullS);
|
||||||
(void) my_load_path(lang_path, lang_path, lc_messages_dir);
|
(void) my_load_path(lang_path, lang_path, lc_messages_dir);
|
||||||
if ((file= mysql_file_open(key_file_ERRMSG,
|
if ((file= mysql_file_open(key_file_ERRMSG,
|
||||||
@ -168,69 +204,120 @@ bool read_texts(const char *file_name, const char *language,
|
|||||||
/*
|
/*
|
||||||
Trying pre-5.4 sematics of the --language parameter.
|
Trying pre-5.4 sematics of the --language parameter.
|
||||||
It included the language-specific part, e.g.:
|
It included the language-specific part, e.g.:
|
||||||
|
|
||||||
--language=/path/to/english/
|
--language=/path/to/english/
|
||||||
*/
|
*/
|
||||||
if ((file= mysql_file_open(key_file_ERRMSG,
|
if ((file= mysql_file_open(key_file_ERRMSG,
|
||||||
fn_format(name, file_name, lc_messages_dir, "", 4),
|
fn_format(name, file_name, lc_messages_dir, "",
|
||||||
|
4),
|
||||||
O_RDONLY | O_SHARE | O_BINARY,
|
O_RDONLY | O_SHARE | O_BINARY,
|
||||||
MYF(0))) < 0)
|
MYF(0))) < 0)
|
||||||
goto err;
|
goto err;
|
||||||
sql_print_warning("An old style --language or -lc-message-dir value with language specific part detected: %s", lc_messages_dir);
|
sql_print_warning("An old style --language or -lc-message-dir value with language specific part detected: %s", lc_messages_dir);
|
||||||
sql_print_warning("Use --lc-messages-dir without language specific part instead.");
|
sql_print_warning("Use --lc-messages-dir without language specific part instead.");
|
||||||
}
|
}
|
||||||
|
error_pos=1;
|
||||||
funktpos=1;
|
|
||||||
if (mysql_file_read(file, (uchar*) head, 32, MYF(MY_NABP)))
|
if (mysql_file_read(file, (uchar*) head, 32, MYF(MY_NABP)))
|
||||||
goto err;
|
goto err;
|
||||||
funktpos=2;
|
error_pos=2;
|
||||||
if (head[0] != (uchar) 254 || head[1] != (uchar) 254 ||
|
if (head[0] != (uchar) 254 || head[1] != (uchar) 254 ||
|
||||||
head[2] != 2 || head[3] != 3)
|
head[2] != 2 || head[3] != 4)
|
||||||
goto err; /* purecov: inspected */
|
goto err; /* purecov: inspected */
|
||||||
|
|
||||||
error_message_charset_info= system_charset_info;
|
ret->text_length= uint4korr(head+6);
|
||||||
length=uint4korr(head+6); count=uint2korr(head+10);
|
ret->errors= uint2korr(head+10);
|
||||||
|
ret->sections= uint2korr(head+12);
|
||||||
|
|
||||||
if (count < error_messages)
|
if (ret->errors < error_messages || ret->sections != MAX_ERROR_RANGES)
|
||||||
{
|
{
|
||||||
sql_print_error("\
|
sql_print_error("\
|
||||||
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!",
|
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);
|
name,ret->errors,error_messages);
|
||||||
(void) mysql_file_close(file, MYF(MY_WME));
|
(void) mysql_file_close(file, MYF(MY_WME));
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(FERR);
|
||||||
}
|
}
|
||||||
|
DBUG_RETURN(file);
|
||||||
if (!(*point= (const char**)
|
|
||||||
my_malloc((size_t) (MY_MAX(length,count*2)+count*sizeof(char*)),MYF(0))))
|
|
||||||
{
|
|
||||||
funktpos=3; /* purecov: inspected */
|
|
||||||
goto err; /* purecov: inspected */
|
|
||||||
}
|
|
||||||
buff= (uchar*) (*point + count);
|
|
||||||
|
|
||||||
if (mysql_file_read(file, buff, (size_t) count*2, MYF(MY_NABP)))
|
|
||||||
goto err;
|
|
||||||
for (i=0, offset=0, pos= buff ; i< count ; i++)
|
|
||||||
{
|
|
||||||
(*point)[i]= (char*) buff+offset;
|
|
||||||
offset+= uint2korr(pos);
|
|
||||||
pos+=2;
|
|
||||||
}
|
|
||||||
if (mysql_file_read(file, buff, length, MYF(MY_NABP)))
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
(void) mysql_file_close(file, MYF(0));
|
|
||||||
|
|
||||||
i= check_error_mesg(file_name, *point);
|
|
||||||
DBUG_RETURN(i);
|
|
||||||
|
|
||||||
err:
|
err:
|
||||||
sql_print_error((funktpos == 3) ? "Not enough memory for messagefile '%s'" :
|
sql_print_error((error_pos == 2) ?
|
||||||
(funktpos == 2) ? "Incompatible header in messagefile '%s'. Probably from another version of MariaDB" :
|
"Incompatible header in messagefile '%s'. Probably from "
|
||||||
((funktpos == 1) ? "Can't read from messagefile '%s'" :
|
"another version of MariaDB" :
|
||||||
|
((error_pos == 1) ? "Can't read from messagefile '%s'" :
|
||||||
"Can't find messagefile '%s'"), name);
|
"Can't find messagefile '%s'"), name);
|
||||||
if (file != FERR)
|
if (file != FERR)
|
||||||
(void) mysql_file_close(file, MYF(MY_WME));
|
(void) mysql_file_close(file, MYF(MY_WME));
|
||||||
|
DBUG_RETURN(FERR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Define the number of normal and extra error messages in the errmsg.sys
|
||||||
|
file
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const uint error_messages= ER_ERROR_LAST - ER_ERROR_FIRST+1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Read text from packed textfile in language-directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool read_texts(const char *file_name, const char *language,
|
||||||
|
const char ****data)
|
||||||
|
{
|
||||||
|
uint i, range_size;
|
||||||
|
const char **point;
|
||||||
|
size_t offset;
|
||||||
|
File file;
|
||||||
|
uchar *buff, *pos;
|
||||||
|
struct st_msg_file msg_file;
|
||||||
|
DBUG_ENTER("read_texts");
|
||||||
|
|
||||||
|
if ((file= open_error_msg_file(file_name, language, error_messages,
|
||||||
|
&msg_file)) == FERR)
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
|
if (!(*data= (const char***)
|
||||||
|
my_malloc((size_t) ((MAX_ERROR_RANGES+1) * sizeof(char**) +
|
||||||
|
MY_MAX(msg_file.text_length, msg_file.errors * 2)+
|
||||||
|
msg_file.errors * sizeof(char*)),
|
||||||
|
MYF(MY_WME))))
|
||||||
|
goto err; /* purecov: inspected */
|
||||||
|
|
||||||
|
point= (const char**) ((*data) + MAX_ERROR_RANGES);
|
||||||
|
buff= (uchar*) (point + msg_file.errors);
|
||||||
|
|
||||||
|
if (mysql_file_read(file, buff,
|
||||||
|
(size_t) (msg_file.errors + msg_file.sections) * 2,
|
||||||
|
MYF(MY_NABP | MY_WME)))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
pos= buff;
|
||||||
|
/* read in sections */
|
||||||
|
for (i= 0, offset= 0; i < msg_file.sections ; i++)
|
||||||
|
{
|
||||||
|
(*data)[i]= point + offset;
|
||||||
|
errors_per_range[i]= range_size= uint2korr(pos);
|
||||||
|
offset+= range_size;
|
||||||
|
pos+= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate pointers to text data */
|
||||||
|
for (i=0, offset=0 ; i < msg_file.errors ; i++)
|
||||||
|
{
|
||||||
|
point[i]= (char*) buff+offset;
|
||||||
|
offset+=uint2korr(pos);
|
||||||
|
pos+=2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read error message texts */
|
||||||
|
if (mysql_file_read(file, buff, msg_file.text_length, MYF(MY_NABP | MY_WME)))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
(void) mysql_file_close(file, MYF(MY_WME));
|
||||||
|
|
||||||
|
DBUG_RETURN(check_error_mesg(file_name, point));
|
||||||
|
|
||||||
|
err:
|
||||||
|
(void) mysql_file_close(file, MYF(0));
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
} /* read_texts */
|
} /* read_texts */
|
||||||
|
|
||||||
|
@ -19,7 +19,8 @@
|
|||||||
#include "my_global.h" /* uint */
|
#include "my_global.h" /* uint */
|
||||||
|
|
||||||
bool init_errmessage(void);
|
bool init_errmessage(void);
|
||||||
|
void free_error_messages();
|
||||||
bool read_texts(const char *file_name, const char *language,
|
bool read_texts(const char *file_name, const char *language,
|
||||||
const char ***point, uint error_messages);
|
const char ****data);
|
||||||
|
|
||||||
#endif /* DERROR_INCLUDED */
|
#endif /* DERROR_INCLUDED */
|
||||||
|
@ -295,7 +295,7 @@ handler *get_ha_partition(partition_info *part_info)
|
|||||||
static const char **handler_errmsgs;
|
static const char **handler_errmsgs;
|
||||||
|
|
||||||
C_MODE_START
|
C_MODE_START
|
||||||
static const char **get_handler_errmsgs()
|
static const char **get_handler_errmsgs(int nr)
|
||||||
{
|
{
|
||||||
return handler_errmsgs;
|
return handler_errmsgs;
|
||||||
}
|
}
|
||||||
@ -386,12 +386,10 @@ int ha_init_errors(void)
|
|||||||
*/
|
*/
|
||||||
static int ha_finish_errors(void)
|
static int ha_finish_errors(void)
|
||||||
{
|
{
|
||||||
const char **errmsgs;
|
|
||||||
|
|
||||||
/* Allocate a pointer array for the error message strings. */
|
/* Allocate a pointer array for the error message strings. */
|
||||||
if (! (errmsgs= my_error_unregister(HA_ERR_FIRST, HA_ERR_LAST)))
|
my_error_unregister(HA_ERR_FIRST, HA_ERR_LAST);
|
||||||
return 1;
|
my_free(handler_errmsgs);
|
||||||
my_free(errmsgs);
|
handler_errmsgs= 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4523,7 +4523,7 @@ compare_errors:
|
|||||||
"Error on master: message (format)='%s' error code=%d ; "
|
"Error on master: message (format)='%s' error code=%d ; "
|
||||||
"Error on slave: actual message='%s', error code=%d. "
|
"Error on slave: actual message='%s', error code=%d. "
|
||||||
"Default database: '%s'. Query: '%s'",
|
"Default database: '%s'. Query: '%s'",
|
||||||
ER_SAFE_THD(thd, expected_error),
|
ER_THD(thd, expected_error),
|
||||||
expected_error,
|
expected_error,
|
||||||
actual_error ? thd->get_stmt_da()->message() : "no error",
|
actual_error ? thd->get_stmt_da()->message() : "no error",
|
||||||
actual_error,
|
actual_error,
|
||||||
|
@ -2234,13 +2234,12 @@ void clean_up(bool print_message)
|
|||||||
|
|
||||||
if (print_message && my_default_lc_messages && server_start_time)
|
if (print_message && my_default_lc_messages && server_start_time)
|
||||||
sql_print_information(ER_DEFAULT(ER_SHUTDOWN_COMPLETE),my_progname);
|
sql_print_information(ER_DEFAULT(ER_SHUTDOWN_COMPLETE),my_progname);
|
||||||
cleanup_errmsgs();
|
|
||||||
MYSQL_CALLBACK(thread_scheduler, end, ());
|
MYSQL_CALLBACK(thread_scheduler, end, ());
|
||||||
thread_scheduler= 0;
|
thread_scheduler= 0;
|
||||||
mysql_library_end();
|
mysql_library_end();
|
||||||
finish_client_errs();
|
finish_client_errs();
|
||||||
(void) my_error_unregister(ER_ERROR_FIRST, ER_ERROR_LAST); // finish server errs
|
cleanup_errmsgs();
|
||||||
DBUG_PRINT("quit", ("Error messages freed"));
|
free_error_messages();
|
||||||
/* Tell main we are ready */
|
/* Tell main we are ready */
|
||||||
logger.cleanup_end();
|
logger.cleanup_end();
|
||||||
sys_var_end();
|
sys_var_end();
|
||||||
@ -6012,6 +6011,8 @@ int mysqld_main(int argc, char **argv)
|
|||||||
mysqld_port,
|
mysqld_port,
|
||||||
MYSQL_COMPILATION_COMMENT);
|
MYSQL_COMPILATION_COMMENT);
|
||||||
|
|
||||||
|
sql_print_information(ER_DEFAULT(ER_EXTRA_TEST)); // QQ
|
||||||
|
|
||||||
// try to keep fd=0 busy
|
// try to keep fd=0 busy
|
||||||
if (!freopen(IF_WIN("NUL","/dev/null"), "r", stdin))
|
if (!freopen(IF_WIN("NUL","/dev/null"), "r", stdin))
|
||||||
{
|
{
|
||||||
|
@ -7154,3 +7154,20 @@ ER_WRONG_ORDER_IN_WITH_CLAUSE
|
|||||||
eng "The definition of the table '%s' refers to the table '%s' defined later in a non-recursive WITH clause"
|
eng "The definition of the table '%s' refers to the table '%s' defined later in a non-recursive WITH clause"
|
||||||
ER_RECURSIVE_QUERY_IN_WITH_CLAUSE
|
ER_RECURSIVE_QUERY_IN_WITH_CLAUSE
|
||||||
eng "Recursive queries in WITH clause are not supported yet"
|
eng "Recursive queries in WITH clause are not supported yet"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Internal errors, not used
|
||||||
|
#
|
||||||
|
skip-to-error-number 2000
|
||||||
|
|
||||||
|
# MySQL 5.7 error numbers starts here
|
||||||
|
skip-to-error-number 3000
|
||||||
|
|
||||||
|
ER_MYSQL_57_TEST
|
||||||
|
eng "5.7 test"
|
||||||
|
|
||||||
|
# MariaDB extra error numbers starts from 4000
|
||||||
|
skip-to-error-number 4000
|
||||||
|
|
||||||
|
ER_EXTRA_TEST
|
||||||
|
eng "10.2 test"
|
||||||
|
@ -658,7 +658,7 @@ typedef struct system_variables
|
|||||||
|
|
||||||
/* Error messages */
|
/* Error messages */
|
||||||
MY_LOCALE *lc_messages;
|
MY_LOCALE *lc_messages;
|
||||||
const char **errmsgs; /* lc_messages->errmsg->errmsgs */
|
const char ***errmsgs; /* lc_messages->errmsg->errmsgs */
|
||||||
|
|
||||||
/* Locale Support */
|
/* Locale Support */
|
||||||
MY_LOCALE *lc_time_names;
|
MY_LOCALE *lc_time_names;
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
typedef struct my_locale_errmsgs
|
typedef struct my_locale_errmsgs
|
||||||
{
|
{
|
||||||
const char *language;
|
const char *language;
|
||||||
const char **errmsgs;
|
const char ***errmsgs;
|
||||||
} MY_LOCALE_ERRMSGS;
|
} MY_LOCALE_ERRMSGS;
|
||||||
|
|
||||||
#include "my_global.h" /* uint */
|
#include "my_global.h" /* uint */
|
||||||
|
@ -4629,8 +4629,7 @@ static bool check_locale(sys_var *self, THD *thd, set_var *var)
|
|||||||
mysql_mutex_lock(&LOCK_error_messages);
|
mysql_mutex_lock(&LOCK_error_messages);
|
||||||
res= (!locale->errmsgs->errmsgs &&
|
res= (!locale->errmsgs->errmsgs &&
|
||||||
read_texts(ERRMSG_FILE, locale->errmsgs->language,
|
read_texts(ERRMSG_FILE, locale->errmsgs->language,
|
||||||
&locale->errmsgs->errmsgs,
|
&locale->errmsgs->errmsgs));
|
||||||
ER_ERROR_LAST - ER_ERROR_FIRST + 1));
|
|
||||||
mysql_mutex_unlock(&LOCK_error_messages);
|
mysql_mutex_unlock(&LOCK_error_messages);
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
|
17
sql/unireg.h
17
sql/unireg.h
@ -43,15 +43,16 @@
|
|||||||
#define PLUGINDIR "lib/plugin"
|
#define PLUGINDIR "lib/plugin"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CURRENT_THD_ERRMSGS current_thd->variables.errmsgs
|
#define MAX_ERROR_RANGES 4 /* 1000-2000, 2000-3000, 3000-4000, 4000-5000 */
|
||||||
#define DEFAULT_ERRMSGS my_default_lc_messages->errmsgs->errmsgs
|
#define ERRORS_PER_RANGE 1000
|
||||||
|
|
||||||
#define ER(X) CURRENT_THD_ERRMSGS[(X) - ER_ERROR_FIRST]
|
#define DEFAULT_ERRMSGS my_default_lc_messages->errmsgs->errmsgs
|
||||||
#define ER_DEFAULT(X) DEFAULT_ERRMSGS[(X) - ER_ERROR_FIRST]
|
#define CURRENT_THD_ERRMSGS (current_thd)->variables.errmsgs
|
||||||
#define ER_SAFE(X) (((X) >= ER_ERROR_FIRST && (X) <= ER_ERROR_LAST) ? ER(X) : "Invalid error code")
|
|
||||||
#define ER_SAFE_THD(T,X) (((X) >= ER_ERROR_FIRST && (X) <= ER_ERROR_LAST) ? ER_THD(T,X) : "Invalid error code")
|
#define ER_DEFAULT(X) DEFAULT_ERRMSGS[((X)-ER_ERROR_FIRST) / ERRORS_PER_RANGE][(X)% ERRORS_PER_RANGE]
|
||||||
#define ER_THD(thd,X) ((thd)->variables.errmsgs[(X) - ER_ERROR_FIRST])
|
#define ER_THD(thd,X) ((thd)->variables.errmsgs[((X)-ER_ERROR_FIRST) / ERRORS_PER_RANGE][(X) % ERRORS_PER_RANGE])
|
||||||
#define ER_THD_OR_DEFAULT(thd,X) ((thd) ? ER_THD(thd, X) : ER_DEFAULT(X))
|
#define ER(X) ER_THD(current_thd, (X))
|
||||||
|
#define ER_THD_OR_DEFAULT(thd,X) ((thd) ? ER_THD(thd, (X)) : ER_DEFAULT(X))
|
||||||
|
|
||||||
#define ME_INFO (ME_HOLDTANG+ME_OLDWIN+ME_NOREFRESH)
|
#define ME_INFO (ME_HOLDTANG+ME_OLDWIN+ME_NOREFRESH)
|
||||||
#define ME_ERROR (ME_BELL+ME_OLDWIN+ME_NOREFRESH)
|
#define ME_ERROR (ME_BELL+ME_OLDWIN+ME_NOREFRESH)
|
||||||
|
@ -26,7 +26,8 @@
|
|||||||
char to[BUFLEN];
|
char to[BUFLEN];
|
||||||
char from[BUFLEN];
|
char from[BUFLEN];
|
||||||
|
|
||||||
const char *error_messages[1000];
|
static const char *error_messages_txt[1000];
|
||||||
|
static const char **error_messages[1]= { error_messages_txt };
|
||||||
|
|
||||||
int setup()
|
int setup()
|
||||||
{
|
{
|
||||||
@ -34,12 +35,12 @@ int setup()
|
|||||||
my_default_lc_messages = &my_locale_en_US;
|
my_default_lc_messages = &my_locale_en_US;
|
||||||
|
|
||||||
/* Populate the necessary error messages */
|
/* Populate the necessary error messages */
|
||||||
error_messages[ER_DATABASE_NAME - ER_ERROR_FIRST] = "Database";
|
error_messages[0][ER_DATABASE_NAME - ER_ERROR_FIRST] = "Database";
|
||||||
error_messages[ER_TABLE_NAME - ER_ERROR_FIRST] = "Table";
|
error_messages[0][ER_TABLE_NAME - ER_ERROR_FIRST] = "Table";
|
||||||
error_messages[ER_PARTITION_NAME - ER_ERROR_FIRST] = "Partition";
|
error_messages[0][ER_PARTITION_NAME - ER_ERROR_FIRST] = "Partition";
|
||||||
error_messages[ER_SUBPARTITION_NAME - ER_ERROR_FIRST] = "Subpartition";
|
error_messages[0][ER_SUBPARTITION_NAME - ER_ERROR_FIRST] = "Subpartition";
|
||||||
error_messages[ER_TEMPORARY_NAME - ER_ERROR_FIRST] = "Temporary";
|
error_messages[0][ER_TEMPORARY_NAME - ER_ERROR_FIRST] = "Temporary";
|
||||||
error_messages[ER_RENAMED_NAME - ER_ERROR_FIRST] = "Renamed";
|
error_messages[0][ER_RENAMED_NAME - ER_ERROR_FIRST] = "Renamed";
|
||||||
|
|
||||||
my_default_lc_messages->errmsgs->errmsgs = error_messages;
|
my_default_lc_messages->errmsgs->errmsgs = error_messages;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user