Big code cleanup/review before 4.0.2 release.

(All commit emails since 4.0.1 checked)
This had to be done now, before the 4.1 tree changes to much, to make it easy to propagate bug fixes to the 4.1 tree.
This commit is contained in:
monty@mashka.mysql.fi 2002-06-11 11:20:31 +03:00
commit 2aecdd1a91
91 changed files with 2466 additions and 2173 deletions

View file

@ -471,3 +471,4 @@ vio/test-sslserver
vio/viotest-ssl vio/viotest-ssl
mysys/getopt.c mysys/getopt.c
mysys/getopt1.c mysys/getopt1.c
scripts/mysql_secure_installation

View file

@ -48,7 +48,7 @@ fast_cflags="-O3 -fno-omit-frame-pointer"
# this is one is for someone who thinks 1% speedup is worth not being # this is one is for someone who thinks 1% speedup is worth not being
# able to backtrace # able to backtrace
reckless_cflags="-O3 -fomit-frame-pointer " reckless_cflags="-O3 -fomit-frame-pointer "
debug_cflags="-DEXTRA_DEBUG -DFORCE_INIT_OF_VARS -DSAFEMALLOC -DSAFE_MUTEX -O1" debug_cflags="-DEXTRA_DEBUG -DFORCE_INIT_OF_VARS -DSAFEMALLOC -DPEDANTIC_SAFEMALLOC -DSAFE_MUTEX -O1"
base_cxxflags="-felide-constructors -fno-exceptions -fno-rtti" base_cxxflags="-felide-constructors -fno-exceptions -fno-rtti"

View file

@ -65,3 +65,4 @@ worm@altair.is.lan
zak@balfor.local zak@balfor.local
zak@linux.local zak@linux.local
tfr@indrek.tfr.cafe.ee tfr@indrek.tfr.cafe.ee
monty@mashka.mysql.fi

View file

@ -8180,7 +8180,7 @@ you need to rebuild them with @code{ALTER TABLE table_name TYPE=MyISAM},
@strong{even} if they are of @code{MyISAM} type. @strong{even} if they are of @code{MyISAM} type.
@item @item
@code{LOCATE()} and @code{INSTR()} are case-sensitive if one of the @code{LOCATE()} and @code{INSTR()} are case-sensitive if one of the
arguments is a binary string. arguments is a binary string. Otherwise they are case insensitive.
@item @item
@code{STRCMP()} now uses the current character set when doing comparisons, @code{STRCMP()} now uses the current character set when doing comparisons,
which means that the default comparison behavior now is case-insensitive. which means that the default comparison behavior now is case-insensitive.
@ -16425,9 +16425,9 @@ GRANT priv_type [(column_list)] [, priv_type [(column_list)] ...]
[CIPHER cipher [AND]] [CIPHER cipher [AND]]
[ISSUER issuer [AND]] [ISSUER issuer [AND]]
[SUBJECT subject]] [SUBJECT subject]]
[WITH [GRANT OPTION | MAX_QUERIES_PER_HOUR=# | [WITH [GRANT OPTION | MAX_QUERIES_PER_HOUR # |
MAX_UPDATES_PER_HOUR=# | MAX_UPDATES_PER_HOUR # |
MAX_CONNECTIONS_PER_HOUR=#]] MAX_CONNECTIONS_PER_HOUR #]]
REVOKE priv_type [(column_list)] [, priv_type [(column_list)] ...] REVOKE priv_type [(column_list)] [, priv_type [(column_list)] ...]
ON @{tbl_name | * | *.* | db_name.*@} ON @{tbl_name | * | *.* | db_name.*@}
@ -16590,8 +16590,8 @@ to other users any privileges the user has at the specified privilege level.
You should be careful to whom you give the @strong{grant} privilege, as two You should be careful to whom you give the @strong{grant} privilege, as two
users with different privileges may be able to join privileges! users with different privileges may be able to join privileges!
@code{MAX_QUERIES_PER_HOUR=#}, @code{MAX_UPDATES_PER_HOUR=#} and @code{MAX_QUERIES_PER_HOUR #}, @code{MAX_UPDATES_PER_HOUR #} and
@code{MAX_CONNECTIONS_PER_HOUR=#} limit the number of @code{MAX_CONNECTIONS_PER_HOUR #} limit the number of
queries/updates and logins the user can do during one hour. queries/updates and logins the user can do during one hour.
If @code{#} is 0 (default), then this means that there is no limitations If @code{#} is 0 (default), then this means that there is no limitations
for the user. @xref{User resources}. for the user. @xref{User resources}.
@ -17109,9 +17109,9 @@ unless the limits are granted to them. These limits can be granted
@strong{only} via global @code{GRANT (*.*)}, using this syntax: @strong{only} via global @code{GRANT (*.*)}, using this syntax:
@example @example
GRANT ... WITH MAX_QUERIES_PER_HOUR = N1 GRANT ... WITH MAX_QUERIES_PER_HOUR N1
MAX_UPDATES_PER_HOUR = N2 MAX_UPDATES_PER_HOUR N2
MAX_CONNECTIONS_PER_HOUR = N3; MAX_CONNECTIONS_PER_HOUR N3;
@end example @end example
One can specify any combination of the above resources. One can specify any combination of the above resources.
@ -30959,7 +30959,7 @@ mysql> SELECT LOCATE('xbar', 'foobar');
@end example @end example
This function is multi-byte safe. In MySQL 3.23 this function is case This function is multi-byte safe. In MySQL 3.23 this function is case
insensitive, while in 4.0 it's only case-insensitive if either argument is sensitive, while in 4.0 it's only case sensitive if either argument is
a binary string. a binary string.
@findex LOCATE() @findex LOCATE()
@ -30974,7 +30974,7 @@ mysql> SELECT LOCATE('bar', 'foobarbar',5);
@end example @end example
This function is multi-byte safe. In MySQL 3.23 this function is case This function is multi-byte safe. In MySQL 3.23 this function is case
insensitive, while in 4.0 it's only case-insensitive if either argument is sensitive, while in 4.0 it's only case sensitive if either argument is
a binary string. a binary string.
@findex INSTR() @findex INSTR()
@ -30991,7 +30991,7 @@ mysql> SELECT INSTR('xbar', 'foobar');
@end example @end example
This function is multi-byte safe. In MySQL 3.23 this function is case This function is multi-byte safe. In MySQL 3.23 this function is case
insensitive, while in 4.0 it's only case-insensitive if either argument is sensitive, while in 4.0 it's only case sensitive if either argument is
a binary string. a binary string.
@findex LPAD() @findex LPAD()
@ -49547,9 +49547,9 @@ Added @code{--no-beep} and @code{--prompt} options to @code{mysql} command-line
@item @item
New feature: management of user resources. New feature: management of user resources.
@example @example
GRANT ... WITH MAX_QUERIES_PER_HOUR = N1 GRANT ... WITH MAX_QUERIES_PER_HOUR N1
MAX_UPDATES_PER_HOUR = N2 MAX_UPDATES_PER_HOUR N2
MAX_CONNECTIONS_PER_HOUR = N3; MAX_CONNECTIONS_PER_HOUR N3;
@end example @end example
@xref{User resources}. @xref{User resources}.

View file

@ -343,7 +343,7 @@ int main(int argc,char *argv[])
signal(SIGINT, mysql_end); // Catch SIGINT to clean up signal(SIGINT, mysql_end); // Catch SIGINT to clean up
/* /*
** Run in interactive mode like the ingres/postgres monitor Run in interactive mode like the ingres/postgres monitor
*/ */
put_info("Welcome to the MySQL monitor. Commands end with ; or \\g.", put_info("Welcome to the MySQL monitor. Commands end with ; or \\g.",
@ -357,7 +357,7 @@ int main(int argc,char *argv[])
initialize_readline(my_progname); initialize_readline(my_progname);
if (!status.batch && !quick && !opt_html && !opt_xml) if (!status.batch && !quick && !opt_html && !opt_xml)
{ {
/*read-history from file, default ~/.mysql_history*/ /* read-history from file, default ~/.mysql_history*/
if (getenv("MYSQL_HISTFILE")) if (getenv("MYSQL_HISTFILE"))
histfile=my_strdup(getenv("MYSQL_HISTFILE"),MYF(MY_WME)); histfile=my_strdup(getenv("MYSQL_HISTFILE"),MYF(MY_WME));
else if (getenv("HOME")) else if (getenv("HOME"))
@ -438,7 +438,7 @@ static struct my_option my_long_options[] =
0, 0, 0, 0, 0}, 0, 0, 0, 0, 0},
{"auto-rehash", OPT_AUTO_REHASH, {"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.", "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, 0, 0, 0, 0, 0, 0}, (gptr*) &rehash, (gptr*) &rehash, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
{"no-auto-rehash", 'A', {"no-auto-rehash", 'A',
"No automatic rehashing. One has to use 'rehash' to get table and field completion. This gives a quicker start of mysql and disables rehashing on reconnect. WARNING: options deprecated; use --disable-auto-rehash instead.", "No automatic rehashing. One has to use 'rehash' to get table and field completion. This gives a quicker start of mysql and disables rehashing on reconnect. WARNING: options deprecated; use --disable-auto-rehash instead.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
@ -488,7 +488,7 @@ static struct my_option my_long_options[] =
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"line-numbers", OPT_LINE_NUMBERS, "Write line numbers for errors.", {"line-numbers", OPT_LINE_NUMBERS, "Write line numbers for errors.",
(gptr*) &line_numbers, (gptr*) &line_numbers, 0, GET_BOOL, (gptr*) &line_numbers, (gptr*) &line_numbers, 0, GET_BOOL,
NO_ARG, 0, 0, 0, 0, 0, 0}, NO_ARG, 1, 0, 0, 0, 0, 0},
{"skip-line-numbers", 'L', "Don't write line number for errors. WARNING: -L is deprecated, use long version of this option instead.", 0, 0, 0, GET_NO_ARG, {"skip-line-numbers", 'L', "Don't write line number for errors. WARNING: -L is deprecated, use long version of this option instead.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0}, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifndef __WIN__ #ifndef __WIN__
@ -590,7 +590,7 @@ static void usage(int version)
if (version) if (version)
return; return;
printf("\ printf("\
Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB\n\ Copyright (C) 2002 MySQL AB\n\
This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\ This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\
and you are welcome to modify and redistribute it under the GPL license\n"); and you are welcome to modify and redistribute it under the GPL license\n");
printf("Usage: %s [OPTIONS] [database]\n", my_progname); printf("Usage: %s [OPTIONS] [database]\n", my_progname);
@ -827,8 +827,10 @@ static int read_lines(bool execute_commands)
line[0] == 0)) line[0] == 0))
continue; // Skip comment lines continue; // Skip comment lines
/* Check if line is a mysql command line */ /*
/* (We want to allow help, print and clear anywhere at line start */ Check if line is a mysql command line
(We want to allow help, print and clear anywhere at line start
*/
if (execute_commands && (named_cmds || glob_buffer.is_empty()) if (execute_commands && (named_cmds || glob_buffer.is_empty())
&& !in_string && (com=find_command(line,0))) && !in_string && (com=find_command(line,0)))
{ {
@ -1011,20 +1013,20 @@ static bool add_line(String &buffer,char *line,char *in_string)
return 0; return 0;
} }
/* **************************************************************** */ /*****************************************************************
/* */ Interface to Readline Completion
/* Interface to Readline Completion */ ******************************************************************/
/* */
/* **************************************************************** */
#ifdef HAVE_READLINE #ifdef HAVE_READLINE
static char *new_command_generator(char *text, int); static char *new_command_generator(char *text, int);
static char **new_mysql_completion (char *text, int start, int end); static char **new_mysql_completion (char *text, int start, int end);
/* Tell the GNU Readline library how to complete. We want to try to complete /*
on command names if this is the first word in the line, or on filenames Tell the GNU Readline library how to complete. We want to try to complete
if not. */ on command names if this is the first word in the line, or on filenames
if not.
*/
char **no_completion (char *text __attribute__ ((unused)), char **no_completion (char *text __attribute__ ((unused)),
char *word __attribute__ ((unused))) char *word __attribute__ ((unused)))
@ -1043,11 +1045,12 @@ static void initialize_readline (char *name)
rl_completion_entry_function=(Function *) no_completion; rl_completion_entry_function=(Function *) no_completion;
} }
/* Attempt to complete on the contents of TEXT. START and END show the /*
region of TEXT that contains the word to complete. We can use the Attempt to complete on the contents of TEXT. START and END show the
entire line in case we want to do some simple parsing. Return the region of TEXT that contains the word to complete. We can use the
array of matches, or NULL if there aren't any. */ entire line in case we want to do some simple parsing. Return the
array of matches, or NULL if there aren't any.
*/
static char **new_mysql_completion (char *text, static char **new_mysql_completion (char *text,
int start __attribute__((unused)), int start __attribute__((unused)),
@ -1067,67 +1070,72 @@ static char *new_command_generator(char *text,int state)
static entry *e; static entry *e;
static uint i; static uint i;
if (!state) { if (!state)
textlen=(uint) strlen(text); textlen=(uint) strlen(text);
}
if (textlen>0) { /* lookup in the hash */ if (textlen>0)
if (!state) { { /* lookup in the hash */
if (!state)
{
uint len; uint len;
b = find_all_matches(&ht,text,(uint) strlen(text),&len); b = find_all_matches(&ht,text,(uint) strlen(text),&len);
if (!b) { if (!b)
return NullS; return NullS;
}
e = b->pData; e = b->pData;
} }
while (e) { if (e)
{
ptr= strdup(e->str); ptr= strdup(e->str);
e = e->pNext; e = e->pNext;
return ptr; return ptr;
} }
} else { /* traverse the entire hash, ugly but works */ }
else
{ /* traverse the entire hash, ugly but works */
if (!state) { if (!state)
i=0; {
/* find the first used bucket */ /* find the first used bucket */
while (i<ht.nTableSize) { for (i=0 ; i < ht.nTableSize ; i++)
if (ht.arBuckets[i]) { {
if (ht.arBuckets[i])
{
b = ht.arBuckets[i]; b = ht.arBuckets[i];
e = b->pData; e = b->pData;
break; break;
} }
i++;
} }
} }
ptr= NullS; ptr= NullS;
while (e && !ptr) { /* find valid entry in bucket */ while (e && !ptr)
if ((uint) strlen(e->str)==b->nKeyLength) { { /* find valid entry in bucket */
if ((uint) strlen(e->str) == b->nKeyLength)
ptr = strdup(e->str); ptr = strdup(e->str);
}
/* find the next used entry */ /* find the next used entry */
e = e->pNext; e = e->pNext;
if (!e) { /* find the next used bucket */ if (!e)
{ /* find the next used bucket */
b = b->pNext; b = b->pNext;
if (!b) { if (!b)
i++; {
while (i<ht.nTableSize) { for (i++ ; i<ht.nTableSize; i++)
if (ht.arBuckets[i]) { {
if (ht.arBuckets[i])
{
b = ht.arBuckets[i]; b = ht.arBuckets[i];
e = b->pData; e = b->pData;
break; break;
} }
i++;
} }
} else {
e = b->pData;
} }
else
e = b->pData;
} }
} }
if (ptr) { if (ptr)
return ptr; return ptr;
}
} }
return NullS; return NullS;
} }
@ -1262,7 +1270,6 @@ You can turn off this feature to get a quicker startup with -A\n\n");
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/* for gnu readline */ /* for gnu readline */
#ifndef HAVE_INDEX #ifndef HAVE_INDEX
@ -1294,13 +1301,15 @@ char *rindex(const char *s,pchar c)
#endif #endif
#endif /* HAVE_READLINE */ #endif /* HAVE_READLINE */
static int reconnect(void) static int reconnect(void)
{ {
if (!status.batch) if (!status.batch)
{ {
put_info("No connection. Trying to reconnect...",INFO_INFO); put_info("No connection. Trying to reconnect...",INFO_INFO);
(void) com_connect((String *) 0, 0); (void) com_connect((String *) 0, 0);
if(rehash) com_rehash(NULL, NULL); if (rehash)
com_rehash(NULL, NULL);
} }
if (!connected) if (!connected)
return put_info("Can't connect to the server\n",INFO_ERROR); return put_info("Can't connect to the server\n",INFO_ERROR);
@ -1347,10 +1356,10 @@ com_clear(String *buffer,char *line __attribute__((unused)))
/* /*
** Execute command Execute command
** Returns: 0 if ok Returns: 0 if ok
** -1 if not fatal error -1 if not fatal error
** 1 if fatal error 1 if fatal error
*/ */
@ -1368,7 +1377,7 @@ com_go(String *buffer,char *line __attribute__((unused)))
old_buffer.copy(); old_buffer.copy();
} }
/* Remove garbage for nicer messages */ /* Remove garbage for nicer messages */
LINT_INIT(buff[0]); LINT_INIT(buff[0]);
remove_cntrl(*buffer); remove_cntrl(*buffer);
@ -1511,10 +1520,9 @@ static void end_pager()
static void init_tee() static void init_tee()
{ {
if (opt_outfile) if (opt_outfile)
end_tee(); end_tee(); // This resets opt_outfile
if (!(OUTFILE= my_fopen(outfile, O_APPEND | O_WRONLY, MYF(MY_WME)))) if (!(OUTFILE= my_fopen(outfile, O_APPEND | O_WRONLY, MYF(MY_WME))))
{ {
opt_outfile= 0;
init_pager(); init_pager();
return; return;
} }
@ -1867,7 +1875,7 @@ com_notee(String *buffer __attribute__((unused)),
} }
/* /*
** Sorry, this command is not available in Windows. Sorry, this command is not available in Windows.
*/ */
#ifndef __WIN__ #ifndef __WIN__
@ -1923,7 +1931,7 @@ com_nopager(String *buffer __attribute__((unused)),
/* /*
** Sorry, you can't send the result to an editor in Win32 Sorry, you can't send the result to an editor in Win32
*/ */
#ifndef __WIN__ #ifndef __WIN__
@ -1999,9 +2007,11 @@ com_shell(String *buffer, char *line __attribute__((unused)))
put_info("Usage: \\! shell-command", INFO_ERROR); put_info("Usage: \\! shell-command", INFO_ERROR);
return -1; return -1;
} }
/* The output of the shell command does not /*
get directed to the pager or the outfile */ The output of the shell command does not
if(system(shell_cmd) == -1) get directed to the pager or the outfile
*/
if (system(shell_cmd) == -1)
{ {
put_info(strerror(errno), INFO_ERROR, errno); put_info(strerror(errno), INFO_ERROR, errno);
return -1; return -1;
@ -2397,7 +2407,7 @@ put_info(const char *str,INFO_TYPE info_type,uint error)
} }
if (info_type == INFO_ERROR) if (info_type == INFO_ERROR)
{ {
if(!opt_nobeep) if (!opt_nobeep)
putchar('\007'); /* This should make a bell */ putchar('\007'); /* This should make a bell */
vidattr(A_STANDOUT); vidattr(A_STANDOUT);
if (error) if (error)
@ -2541,18 +2551,20 @@ static void mysql_end_timer(ulong start_time,char *buff)
strmov(strend(buff),")"); strmov(strend(buff),")");
} }
static const char* construct_prompt() { static const char* construct_prompt()
{
//erase the old prompt //erase the old prompt
processed_prompt.free(); processed_prompt.free();
//get the date struct //get the date struct
time_t lclock = time(NULL); time_t lclock = time(NULL);
struct tm *t = localtime(&lclock); struct tm *t = localtime(&lclock);
//parse thru the settings for the prompt //parse thru the settings for the prompt
for (char *c = current_prompt;*c;*c++) { for (char *c = current_prompt; *c ; *c++)
if (*c != PROMPT_CHAR) { {
if (*c != PROMPT_CHAR)
processed_prompt.append(*c); processed_prompt.append(*c);
} else
else { {
switch (*++c) { switch (*++c) {
case '\0': case '\0':
//stop it from going beyond if ends with % //stop it from going beyond if ends with %
@ -2674,13 +2686,16 @@ static const char* construct_prompt() {
return processed_prompt.ptr(); return processed_prompt.ptr();
} }
static void add_int_to_prompt(int toadd) {
static void add_int_to_prompt(int toadd)
{
char buffer[16]; char buffer[16];
int10_to_str(toadd,buffer,10); int10_to_str(toadd,buffer,10);
processed_prompt.append(buffer); processed_prompt.append(buffer);
} }
static void init_username() { static void init_username()
{
my_free(full_username,MYF(MY_ALLOW_ZERO_PTR)); my_free(full_username,MYF(MY_ALLOW_ZERO_PTR));
my_free(part_username,MYF(MY_ALLOW_ZERO_PTR)); my_free(part_username,MYF(MY_ALLOW_ZERO_PTR));
@ -2688,22 +2703,21 @@ static void init_username() {
LINT_INIT(result); LINT_INIT(result);
if (!mysql_query(&mysql,"select USER()") && if (!mysql_query(&mysql,"select USER()") &&
(result=mysql_use_result(&mysql))) (result=mysql_use_result(&mysql)))
{ {
MYSQL_ROW cur=mysql_fetch_row(result); MYSQL_ROW cur=mysql_fetch_row(result);
full_username=my_strdup(cur[0],MYF(MY_WME)); full_username=my_strdup(cur[0],MYF(MY_WME));
part_username=my_strdup(strtok(cur[0],"@"),MYF(MY_WME)); part_username=my_strdup(strtok(cur[0],"@"),MYF(MY_WME));
(void) mysql_fetch_row(result); // Read eof (void) mysql_fetch_row(result); // Read eof
} }
} }
static int static int com_prompt(String *buffer, char *line)
com_prompt(String *buffer, char *line __attribute__((unused))) { {
char *ptr=strchr(line, ' ');
prompt_counter = 0; prompt_counter = 0;
my_free(current_prompt,MYF(MY_ALLOW_ZERO_PTR)); my_free(current_prompt,MYF(MY_ALLOW_ZERO_PTR));
current_prompt=my_strdup(strchr(line, ' ') ? current_prompt=my_strdup(ptr ? ptr+1 : default_prompt,MYF(MY_WME));
strchr(line, ' ')+1 : if (!ptr)
default_prompt,MYF(MY_WME));
if (!strchr(line, ' '))
tee_fprintf(stdout, "Returning to default PROMPT of %s\n", default_prompt); tee_fprintf(stdout, "Returning to default PROMPT of %s\n", default_prompt);
else else
tee_fprintf(stdout, "PROMPT set to '%s'\n", current_prompt); tee_fprintf(stdout, "PROMPT set to '%s'\n", current_prompt);

View file

@ -24,7 +24,7 @@
#endif #endif
#define ADMIN_VERSION "8.35" #define ADMIN_VERSION "8.35"
#define MAX_MYSQL_VAR 64 #define MAX_MYSQL_VAR 128
#define SHUTDOWN_DEF_TIMEOUT 3600 /* Wait for shutdown */ #define SHUTDOWN_DEF_TIMEOUT 3600 /* Wait for shutdown */
#define MAX_TRUNC_LENGTH 3 #define MAX_TRUNC_LENGTH 3
@ -40,9 +40,12 @@ static uint tcp_port = 0, option_wait = 0, option_silent=0;
static ulong opt_connect_timeout, opt_shutdown_timeout; static ulong opt_connect_timeout, opt_shutdown_timeout;
static my_string unix_port=0; static my_string unix_port=0;
/* When using extended-status relatively, ex_val_max_len is the estimated /*
maximum length for any relative value printed by extended-status. The When using extended-status relatively, ex_val_max_len is the estimated
idea is to try to keep the length of output as short as possible. */ maximum length for any relative value printed by extended-status. The
idea is to try to keep the length of output as short as possible.
*/
static uint ex_val_max_len[MAX_MYSQL_VAR]; static uint ex_val_max_len[MAX_MYSQL_VAR];
static my_bool ex_status_printed = 0; /* First output is not relative. */ static my_bool ex_status_printed = 0; /* First output is not relative. */
static uint ex_var_count, max_var_length, max_val_length; static uint ex_var_count, max_var_length, max_val_length;
@ -235,17 +238,12 @@ int main(int argc,char *argv[])
{ {
int error, ho_error; int error, ho_error;
MYSQL mysql; MYSQL mysql;
char **commands; char **commands, **save_argv;
char** save_argv;
MY_INIT(argv[0]); MY_INIT(argv[0]);
mysql_init(&mysql); mysql_init(&mysql);
load_defaults("my",load_default_groups,&argc,&argv); load_defaults("my",load_default_groups,&argc,&argv);
save_argv = argv; save_argv = argv; /* Save for free_defaults */
/* Sasha: with the change to handle_options() we now need to do this fix
with save_argv in all client utilities. The problem is that
handle_options may modify argv, and that wreaks havoc with
free_defaults()
*/
if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
exit(ho_error); exit(ho_error);
@ -444,8 +442,10 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
{ {
char pidfile[FN_REFLEN]; char pidfile[FN_REFLEN];
my_bool got_pidfile=0; my_bool got_pidfile=0;
/* Only wait for pidfile on local connections */ /*
/* If pidfile doesn't exist, continue without pid file checking */ Only wait for pidfile on local connections
If pidfile doesn't exist, continue without pid file checking
*/
if (mysql->unix_socket) if (mysql->unix_socket)
got_pidfile= !get_pidfile(mysql, pidfile); got_pidfile= !get_pidfile(mysql, pidfile);
if (mysql_shutdown(mysql)) if (mysql_shutdown(mysql))

View file

@ -20,7 +20,9 @@
#include <time.h> #include <time.h>
#include "log_event.h" #include "log_event.h"
#define PROBE_HEADER_LEN (4+EVENT_LEN_OFFSET+4) #define BIN_LOG_HEADER_SIZE 4
#define PROBE_HEADER_LEN (BIN_LOG_HEADER_SIZE+EVENT_LEN_OFFSET+4)
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_LOCAL_FILES) #define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_LOCAL_FILES)
@ -178,8 +180,7 @@ static my_bool
get_one_option(int optid, const struct my_option *opt __attribute__((unused)), get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
char *argument) char *argument)
{ {
switch(optid) switch(optid) {
{
#ifndef DBUG_OFF #ifndef DBUG_OFF
case '#': case '#':
DBUG_PUSH(argument ? argument : default_dbug_option); DBUG_PUSH(argument ? argument : default_dbug_option);
@ -234,7 +235,7 @@ static MYSQL* safe_connect()
if(!local_mysql) if(!local_mysql)
die("Failed on mysql_init"); die("Failed on mysql_init");
if(!mysql_real_connect(local_mysql, host, user, pass, 0, port, 0, 0)) if (!mysql_real_connect(local_mysql, host, user, pass, 0, port, 0, 0))
die("failed on connect: %s", mysql_error(local_mysql)); die("failed on connect: %s", mysql_error(local_mysql));
return local_mysql; return local_mysql;
@ -242,7 +243,7 @@ static MYSQL* safe_connect()
static void dump_log_entries(const char* logname) static void dump_log_entries(const char* logname)
{ {
if(use_remote) if (use_remote)
dump_remote_log_entries(logname); dump_remote_log_entries(logname);
else else
dump_local_log_entries(logname); dump_local_log_entries(logname);
@ -254,7 +255,7 @@ static void dump_remote_table(NET* net, const char* db, const char* table)
char * p = buf; char * p = buf;
uint table_len = (uint) strlen(table); uint table_len = (uint) strlen(table);
uint db_len = (uint) strlen(db); uint db_len = (uint) strlen(db);
if(table_len + db_len > sizeof(buf) - 2) if (table_len + db_len > sizeof(buf) - 2)
die("Buffer overrun"); die("Buffer overrun");
*p++ = db_len; *p++ = db_len;
@ -263,14 +264,14 @@ static void dump_remote_table(NET* net, const char* db, const char* table)
*p++ = table_len; *p++ = table_len;
memcpy(p, table, table_len); memcpy(p, table, table_len);
if(simple_command(mysql, COM_TABLE_DUMP, buf, p - buf + table_len, 1)) if (simple_command(mysql, COM_TABLE_DUMP, buf, p - buf + table_len, 1))
die("Error sending the table dump command"); die("Error sending the table dump command");
for(;;) for (;;)
{ {
uint packet_len = my_net_read(net); uint packet_len = my_net_read(net);
if(packet_len == 0) break; // end of file if (packet_len == 0) break; // end of file
if(packet_len == packet_error) if (packet_len == packet_error)
die("Error reading packet in table dump"); die("Error reading packet in table dump");
my_fwrite(result_file, (byte*)net->read_pos, packet_len, MYF(MY_WME)); my_fwrite(result_file, (byte*)net->read_pos, packet_len, MYF(MY_WME));
fflush(result_file); fflush(result_file);
@ -284,8 +285,8 @@ static int check_master_version(MYSQL* mysql)
const char* version; const char* version;
int old_format = 0; int old_format = 0;
if (mysql_query(mysql, "SELECT VERSION()") if (mysql_query(mysql, "SELECT VERSION()") ||
|| !(res = mysql_store_result(mysql))) !(res = mysql_store_result(mysql)))
{ {
mysql_close(mysql); mysql_close(mysql);
die("Error checking master version: %s", die("Error checking master version: %s",
@ -305,12 +306,12 @@ static int check_master_version(MYSQL* mysql)
die("Master reported NULL for the version"); die("Master reported NULL for the version");
} }
switch (*version) switch (*version) {
{
case '3': case '3':
old_format = 1; old_format = 1;
break; break;
case '4': case '4':
case '5':
old_format = 0; old_format = 0;
break; break;
default: default:
@ -324,6 +325,7 @@ static int check_master_version(MYSQL* mysql)
return old_format; return old_format;
} }
static void dump_remote_log_entries(const char* logname) static void dump_remote_log_entries(const char* logname)
{ {
char buf[128]; char buf[128];
@ -333,38 +335,38 @@ static void dump_remote_log_entries(const char* logname)
int old_format; int old_format;
old_format = check_master_version(mysql); old_format = check_master_version(mysql);
if(!position) position = 4; // protect the innocent from spam if (!position)
if (position < 4) position = BIN_LOG_HEADER_SIZE; // protect the innocent from spam
if (position < BIN_LOG_HEADER_SIZE)
{ {
position = 4; position = BIN_LOG_HEADER_SIZE;
// warn the guity // warn the guity
sql_print_error("Warning: The position in the binary log can't be less than 4.\nStarting from position 4\n"); sql_print_error("Warning: The position in the binary log can't be less than %d.\nStarting from position %d\n", BIN_LOG_HEADER_SIZE, BIN_LOG_HEADER_SIZE);
} }
int4store(buf, position); int4store(buf, position);
int2store(buf + 4, binlog_flags); int2store(buf + BIN_LOG_HEADER_SIZE, binlog_flags);
len = (uint) strlen(logname); len = (uint) strlen(logname);
int4store(buf + 6, 0); int4store(buf + 6, 0);
memcpy(buf + 10, logname,len); memcpy(buf + 10, logname,len);
if (simple_command(mysql, COM_BINLOG_DUMP, buf, len + 10, 1)) if (simple_command(mysql, COM_BINLOG_DUMP, buf, len + 10, 1))
die("Error sending the log dump command"); die("Error sending the log dump command");
for(;;) for (;;)
{ {
const char *error; const char *error;
len = net_safe_read(mysql); len = net_safe_read(mysql);
if (len == packet_error) if (len == packet_error)
die("Error reading packet from server: %s", mysql_error(mysql)); die("Error reading packet from server: %s", mysql_error(mysql));
if(len == 1 && net->read_pos[0] == 254) if (len == 1 && net->read_pos[0] == 254)
break; // end of data break; // end of data
DBUG_PRINT("info",( "len= %u, net->read_pos[5] = %d\n", DBUG_PRINT("info",( "len= %u, net->read_pos[5] = %d\n",
len, net->read_pos[5])); len, net->read_pos[5]));
Log_event * ev = Log_event::read_log_event( Log_event *ev = Log_event::read_log_event((const char*) net->read_pos + 1 ,
(const char*) net->read_pos + 1 , len - 1, &error, old_format);
len - 1, &error, old_format);
if (ev) if (ev)
{ {
ev->print(result_file, short_form, last_db); ev->print(result_file, short_form, last_db);
if(ev->get_type_code() == LOAD_EVENT) if (ev->get_type_code() == LOAD_EVENT)
dump_remote_file(net, ((Load_log_event*)ev)->fname); dump_remote_file(net, ((Load_log_event*)ev)->fname);
delete ev; delete ev;
} }
@ -373,10 +375,11 @@ static void dump_remote_log_entries(const char* logname)
} }
} }
static int check_header(IO_CACHE* file) static int check_header(IO_CACHE* file)
{ {
byte buf[PROBE_HEADER_LEN]; byte buf[PROBE_HEADER_LEN];
int old_format; int old_format=0;
my_off_t pos = my_b_tell(file); my_off_t pos = my_b_tell(file);
my_b_seek(file, (my_off_t)0); my_b_seek(file, (my_off_t)0);
@ -388,8 +391,6 @@ static int check_header(IO_CACHE* file)
event_len = uint4korr(buf + EVENT_LEN_OFFSET + 4); event_len = uint4korr(buf + EVENT_LEN_OFFSET + 4);
old_format = (event_len < LOG_EVENT_HEADER_LEN + START_HEADER_LEN); old_format = (event_len < LOG_EVENT_HEADER_LEN + START_HEADER_LEN);
} }
else
old_format = 0;
my_b_seek(file, pos); my_b_seek(file, pos);
return old_format; return old_format;
} }
@ -425,7 +426,7 @@ static void dump_local_log_entries(const char* logname)
for (length= (my_off_t) position ; length > 0 ; length-=tmp) for (length= (my_off_t) position ; length > 0 ; length-=tmp)
{ {
tmp=min(length,sizeof(buff)); tmp=min(length,sizeof(buff));
if (my_b_read(file,buff, (uint) tmp)) if (my_b_read(file, buff, (uint) tmp))
exit(1); exit(1);
} }
} }
@ -435,10 +436,10 @@ static void dump_local_log_entries(const char* logname)
if (!position) if (!position)
{ {
char magic[4]; char magic[BIN_LOG_HEADER_SIZE];
if (my_b_read(file, (byte*) magic, sizeof(magic))) if (my_b_read(file, (byte*) magic, sizeof(magic)))
die("I/O error reading binlog magic number"); die("I/O error reading binlog magic number");
if(memcmp(magic, BINLOG_MAGIC, 4)) if (memcmp(magic, BINLOG_MAGIC, 4))
die("Bad magic number; The file is probably not a MySQL binary log"); die("Bad magic number; The file is probably not a MySQL binary log");
} }
@ -498,7 +499,7 @@ Could not read entry at offset %s : Error in log format or read error",
rec_count++; rec_count++;
delete ev; delete ev;
} }
if(fd >= 0) if (fd >= 0)
my_close(fd, MYF(MY_WME)); my_close(fd, MYF(MY_WME));
end_io_cache(file); end_io_cache(file);
} }
@ -509,34 +510,30 @@ int main(int argc, char** argv)
MY_INIT(argv[0]); MY_INIT(argv[0]);
parse_args(&argc, (char***)&argv); parse_args(&argc, (char***)&argv);
if(!argc && !table) if (!argc && !table)
{ {
usage(); usage();
return -1; return -1;
} }
if(use_remote) if (use_remote)
{
mysql = safe_connect(); mysql = safe_connect();
}
if (table) if (table)
{ {
if(!use_remote) if (!use_remote)
die("You must specify connection parameter to get table dump"); die("You must specify connection parameter to get table dump");
char* db = (char*)table; char* db = (char*) table;
char* tbl = (char*) strchr(table, '.'); char* tbl = (char*) strchr(table, '.');
if(!tbl) if (!tbl)
die("You must use database.table syntax to specify the table"); die("You must use database.table syntax to specify the table");
*tbl++ = 0; *tbl++ = 0;
dump_remote_table(&mysql->net, db, tbl); dump_remote_table(&mysql->net, db, tbl);
} }
else else
{ {
while(--argc >= 0) while (--argc >= 0)
{
dump_log_entries(*(argv++)); dump_log_entries(*(argv++));
}
} }
if (result_file != stdout) if (result_file != stdout)
my_fclose(result_file, MYF(0)); my_fclose(result_file, MYF(0));

View file

@ -1348,9 +1348,6 @@ int main(int argc, char **argv)
MYSQL_RES *master; MYSQL_RES *master;
MY_INIT(argv[0]); MY_INIT(argv[0]);
/*
** Check out the args
*/
if (get_options(&argc, &argv)) if (get_options(&argc, &argv))
{ {
my_end(0); my_end(0);
@ -1374,12 +1371,16 @@ int main(int argc, char **argv)
} }
if (opt_alldbs) if (opt_alldbs)
dump_all_databases(); dump_all_databases();
/* Only one database and selected table(s) */
else if (argc > 1 && !opt_databases) else if (argc > 1 && !opt_databases)
{
/* Only one database and selected table(s) */
dump_selected_tables(*argv, (argv + 1), (argc - 1)); dump_selected_tables(*argv, (argv + 1), (argc - 1));
/* One or more databases, all tables */ }
else else
{
/* One or more databases, all tables */
dump_databases(argv); dump_databases(argv);
}
if (opt_first_slave) if (opt_first_slave)
{ {
@ -1387,14 +1388,13 @@ int main(int argc, char **argv)
{ {
if (mysql_query(sock, "SHOW MASTER STATUS") || if (mysql_query(sock, "SHOW MASTER STATUS") ||
!(master = mysql_store_result(sock))) !(master = mysql_store_result(sock)))
{
my_printf_error(0, "Error: Couldn't execute 'SHOW MASTER STATUS': %s", my_printf_error(0, "Error: Couldn't execute 'SHOW MASTER STATUS': %s",
MYF(0), mysql_error(sock)); MYF(0), mysql_error(sock));
}
else else
{ {
row = mysql_fetch_row(master); row = mysql_fetch_row(master);
if(row[0] && row[1]) { if (row[0] && row[1])
{
fprintf(md_result_file, fprintf(md_result_file,
"\n--\n-- Position to start replication from\n--\n\n"); "\n--\n-- Position to start replication from\n--\n\n");
fprintf(md_result_file, fprintf(md_result_file,
@ -1406,15 +1406,11 @@ int main(int argc, char **argv)
} }
} }
if (mysql_query(sock, "FLUSH MASTER")) if (mysql_query(sock, "FLUSH MASTER"))
{
my_printf_error(0, "Error: Couldn't execute 'FLUSH MASTER': %s", my_printf_error(0, "Error: Couldn't execute 'FLUSH MASTER': %s",
MYF(0), mysql_error(sock)); MYF(0), mysql_error(sock));
}
if (mysql_query(sock, "UNLOCK TABLES")) if (mysql_query(sock, "UNLOCK TABLES"))
{
my_printf_error(0, "Error: Couldn't execute 'UNLOCK TABLES': %s", my_printf_error(0, "Error: Couldn't execute 'UNLOCK TABLES': %s",
MYF(0), mysql_error(sock)); MYF(0), mysql_error(sock));
}
} }
dbDisconnect(current_host); dbDisconnect(current_host);
fputs("\n", md_result_file); fputs("\n", md_result_file);

View file

@ -105,8 +105,10 @@ void get_pass(char* pw, int len)
{ {
FILE* fp; FILE* fp;
char* pw_end=pw+len; char* pw_end=pw+len;
/* /dev/random is more secure than rand() because the seed is easy to /*
predict, so we resort to rand() only if /dev/random is not available */ /dev/random is more secure than rand() because the seed is easy to
predict, so we resort to rand() only if /dev/random is not available
*/
if ((fp=fopen("/dev/random","r"))) if ((fp=fopen("/dev/random","r")))
{ {
fread(pw,len,1,fp); fread(pw,len,1,fp);
@ -129,6 +131,7 @@ void get_pass(char* pw, int len)
*pw_end=0; *pw_end=0;
} }
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
FILE* fp; FILE* fp;

View file

@ -138,6 +138,8 @@ int parse_args(int argc, char **argv)
return 0; return 0;
} }
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
MY_INIT(argv[0]); MY_INIT(argv[0]);
@ -147,7 +149,7 @@ int main(int argc, char** argv)
if (!(manager=mysql_manager_init(0))) if (!(manager=mysql_manager_init(0)))
die("Failed in mysql_manager_init()"); die("Failed in mysql_manager_init()");
if (!mysql_manager_connect(manager,host,user,pass,port)) if (!mysql_manager_connect(manager,host,user,pass,port))
die("Could not connect to MySQL manager: %s(%d)",manager->last_error, die("Could not connect to MySQL manager: %s (%d)",manager->last_error,
manager->last_errno); manager->last_errno);
for (;!feof(fp);) for (;!feof(fp);)
{ {
@ -157,11 +159,11 @@ int main(int argc, char** argv)
if (!quiet) if (!quiet)
fprintf(fp_out,"<<%s",buf); fprintf(fp_out,"<<%s",buf);
if (mysql_manager_command(manager,buf,strlen(buf))) if (mysql_manager_command(manager,buf,strlen(buf)))
die("Error in command: %s(%d)",manager->last_error,manager->last_errno); die("Error in command: %s (%d)",manager->last_error,manager->last_errno);
while (!manager->eof) while (!manager->eof)
{ {
if (mysql_manager_fetch_line(manager,buf,sizeof(buf))) if (mysql_manager_fetch_line(manager,buf,sizeof(buf)))
die("Error fetching result line: %s(%d)", manager->last_error, die("Error fetching result line: %s (%d)", manager->last_error,
manager->last_errno); manager->last_errno);
if (!quiet) if (!quiet)
fprintf(fp_out,">>%s\n",buf); fprintf(fp_out,">>%s\n",buf);

View file

@ -1425,7 +1425,7 @@ int do_connect(struct st_query* q)
con_port = var_port->int_val; con_port = var_port->int_val;
} }
else else
con_port=atoi(con_port_str); con_port=atoi(con_port_str);
p = safe_get_param(p, &con_sock, "missing connection socket"); p = safe_get_param(p, &con_sock, "missing connection socket");
if (*con_sock == '$') if (*con_sock == '$')
{ {
@ -1469,6 +1469,7 @@ int do_connect(struct st_query* q)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
int do_done(struct st_query* q) int do_done(struct st_query* q)
{ {
q->type = Q_END_BLOCK; q->type = Q_END_BLOCK;
@ -1480,8 +1481,8 @@ int do_done(struct st_query* q)
} }
else else
{ {
++parser.current_line; ++parser.current_line;
--cur_block; --cur_block;
} }
return 0; return 0;
} }
@ -1492,14 +1493,14 @@ int do_while(struct st_query* q)
const char* expr_start, *expr_end; const char* expr_start, *expr_end;
VAR v; VAR v;
if (cur_block == block_stack_end) if (cur_block == block_stack_end)
die("Nesting too deeply"); die("Nesting too deeply");
if (!*block_ok) if (!*block_ok)
{ {
++false_block_depth; ++false_block_depth;
*++block_ok = 0; *++block_ok = 0;
*cur_block++ = parser.current_line++; *cur_block++ = parser.current_line++;
return 0; return 0;
} }
expr_start = strchr(p, '('); expr_start = strchr(p, '(');
if (!expr_start) if (!expr_start)
@ -1511,10 +1512,10 @@ int do_while(struct st_query* q)
eval_expr(&v, ++expr_start, &expr_end); eval_expr(&v, ++expr_start, &expr_end);
*cur_block++ = parser.current_line++; *cur_block++ = parser.current_line++;
if (!v.int_val) if (!v.int_val)
{ {
*++block_ok = 0; *++block_ok = 0;
false_block_depth++; false_block_depth++;
} }
else else
*++block_ok = 1; *++block_ok = 1;
var_free(&v); var_free(&v);
@ -1530,45 +1531,42 @@ int safe_copy_unescape(char* dest, char* src, int size)
size--; /* just to make life easier */ size--; /* just to make life easier */
for(; p_dest - size < dest && p_src - size < src for (; p_dest - size < dest && p_src - size < src &&
&& (c = *p_src) != '\n' && c; ++p_src ) (c = *p_src) != '\n' && c; ++p_src)
{ {
switch(state) switch(state) {
{ case ST_NORMAL:
case ST_NORMAL: if (c == '\\')
if (c == '\\') state = ST_ESCAPED;
{ else
state = ST_ESCAPED; *p_dest++ = c;
} break;
else case ST_ESCAPED:
*p_dest++ = c; if ((val = hex_val(c)) > 0)
break; {
case ST_ESCAPED: *p_dest = val;
if ((val = hex_val(c)) > 0) state = ST_HEX2;
{ }
*p_dest = val; else
state = ST_HEX2; {
} state = ST_NORMAL;
else *p_dest++ = c;
{ }
state = ST_NORMAL; break;
*p_dest++ = c; case ST_HEX2:
} if ((val = hex_val(c)) > 0)
break; {
case ST_HEX2: *p_dest = (*p_dest << 4) + val;
if ((val = hex_val(c)) > 0) p_dest++;
{ }
*p_dest = (*p_dest << 4) + val; else
p_dest++; *p_dest++ = c;
}
else
*p_dest++ = c;
state = ST_NORMAL; state = ST_NORMAL;
break; break;
}
} }
}
*p_dest = 0; *p_dest = 0;
return (p_dest - dest); return (p_dest - dest);

View file

@ -706,10 +706,11 @@ char ***_sframep_ __attribute__((unused)))
if (!_no_db_) if (!_no_db_)
{ {
int save_errno=errno; int save_errno=errno;
/* Sasha: the test below is so we could call functions with DBUG_ENTER /*
before my_thread_init(). I needed this because I suspected corruption Sasha: the test below is so we could call functions with DBUG_ENTER
of a block allocated by my_thread_init() itself, so I wanted to use before my_thread_init(). I needed this because I suspected corruption
my_malloc()/my_free() in my_thread_init()/my_thread_end() of a block allocated by my_thread_init() itself, so I wanted to use
my_malloc()/my_free() in my_thread_init()/my_thread_end()
*/ */
if (!(state=code_state())) if (!(state=code_state()))
return; return;

View file

@ -77,7 +77,8 @@ static void usage()
printf("MySQL AB, by Sasha Pachev\n"); printf("MySQL AB, by Sasha Pachev\n");
printf("This software comes with ABSOLUTELY NO WARRANTY\n\n"); printf("This software comes with ABSOLUTELY NO WARRANTY\n\n");
printf("Resolve numeric stack strace dump into symbols.\n\n"); printf("Resolve numeric stack strace dump into symbols.\n\n");
printf("Usage: %s [OPTIONS] symbols-file [numeric-dump-file]\n", my_progname); printf("Usage: %s [OPTIONS] symbols-file [numeric-dump-file]\n",
my_progname);
my_print_help(my_long_options); my_print_help(my_long_options);
my_print_variables(my_long_options); my_print_variables(my_long_options);
printf("\n\ printf("\n\
@ -159,14 +160,14 @@ static void open_files()
fp_out = stdout; fp_out = stdout;
fp_dump = stdin; fp_dump = stdin;
if(dump_fname && !(fp_dump = my_fopen(dump_fname, O_RDONLY, MYF(MY_WME)))) if (dump_fname && !(fp_dump = my_fopen(dump_fname, O_RDONLY, MYF(MY_WME))))
die("Could not open %s", dump_fname); die("Could not open %s", dump_fname);
/* if name not given, assume stdin*/ /* if name not given, assume stdin*/
if(!sym_fname) if (!sym_fname)
die("Please run nm --numeric-sort on mysqld binary that produced stack \ die("Please run nm --numeric-sort on mysqld binary that produced stack \
trace dump and specify the path to it with -s or --symbols-file"); trace dump and specify the path to it with -s or --symbols-file");
if(!(fp_sym = my_fopen(sym_fname, O_RDONLY, MYF(MY_WME)))) if (!(fp_sym = my_fopen(sym_fname, O_RDONLY, MYF(MY_WME))))
die("Could not open %s", sym_fname); die("Could not open %s", sym_fname);
} }
@ -174,10 +175,10 @@ trace dump and specify the path to it with -s or --symbols-file");
static uchar hex_val(char c) static uchar hex_val(char c)
{ {
uchar l; uchar l;
if(isdigit(c)) if (isdigit(c))
return c - '0'; return c - '0';
l = tolower(c); l = tolower(c);
if(l < 'a' || l > 'f') if (l < 'a' || l > 'f')
return HEX_INVALID; return HEX_INVALID;
return (uchar)10 + ((uchar)c - (uchar)'a'); return (uchar)10 + ((uchar)c - (uchar)'a');
} }
@ -200,25 +201,18 @@ static int init_sym_entry(SYM_ENTRY* se, char* buf)
char* p, *p_end; char* p, *p_end;
se->addr = (uchar*)read_addr(&buf); se->addr = (uchar*)read_addr(&buf);
if(!se->addr) if (!se->addr)
return -1; return -1;
while(isspace(*buf++)) while (isspace(*buf++)) ;
/* empty */;
while(isspace(*buf++)) while (isspace(*buf++)) ; /* skip more space */
/* empty - skip more space */;
--buf; --buf;
/* now we are on the symbol */ /* now we are on the symbol */
for(p = se->symbol, p_end = se->symbol + sizeof(se->symbol) - 1; for (p = se->symbol, p_end = se->symbol + sizeof(se->symbol) - 1;
*buf != '\n' && *buf; ++buf,++p ) *buf != '\n' && *buf && p < p_end; ++buf,++p)
{ *p = *buf;
if(p < p_end)
*p = *buf;
else
break;
}
*p = 0; *p = 0;
if(!strcmp(se->symbol, "gcc2_compiled.")) if (!strcmp(se->symbol, "gcc2_compiled."))
return -1; return -1;
return 0; return 0;
} }
@ -226,18 +220,18 @@ static int init_sym_entry(SYM_ENTRY* se, char* buf)
static void init_sym_table() static void init_sym_table()
{ {
char buf[512]; char buf[512];
if(my_init_dynamic_array(&sym_table, sizeof(SYM_ENTRY), INIT_SYM_TABLE, if (my_init_dynamic_array(&sym_table, sizeof(SYM_ENTRY), INIT_SYM_TABLE,
INC_SYM_TABLE)) INC_SYM_TABLE))
die("Failed in my_init_dynamic_array() -- looks like out of memory problem"); die("Failed in my_init_dynamic_array() -- looks like out of memory problem");
while(fgets(buf, sizeof(buf), fp_sym)) while (fgets(buf, sizeof(buf), fp_sym))
{ {
SYM_ENTRY se; SYM_ENTRY se;
if(init_sym_entry(&se, buf)) if (init_sym_entry(&se, buf))
continue; continue;
if(insert_dynamic(&sym_table, (gptr)&se)) if (insert_dynamic(&sym_table, (gptr)&se))
die("insert_dynamic() failed - looks like we are out of memory"); die("insert_dynamic() failed - looks like we are out of memory");
} }
verify_sort(); verify_sort();
} }
@ -252,66 +246,68 @@ static void verify_sort()
uint i; uint i;
uchar* last = 0; uchar* last = 0;
for(i = 0; i < sym_table.elements; i++) for (i = 0; i < sym_table.elements; i++)
{ {
SYM_ENTRY se; SYM_ENTRY se;
get_dynamic(&sym_table, (gptr)&se, i); get_dynamic(&sym_table, (gptr)&se, i);
if(se.addr < last) if (se.addr < last)
die("sym table does not appear to be sorted, did you forget \ die("sym table does not appear to be sorted, did you forget \
--numeric-sort arg to nm? trouble addr = %p, last = %p", se.addr, last); --numeric-sort arg to nm? trouble addr = %p, last = %p", se.addr, last);
last = se.addr; last = se.addr;
} }
} }
static SYM_ENTRY* resolve_addr(uchar* addr, SYM_ENTRY* se) static SYM_ENTRY* resolve_addr(uchar* addr, SYM_ENTRY* se)
{ {
uint i; uint i;
get_dynamic(&sym_table, (gptr)se, 0); get_dynamic(&sym_table, (gptr)se, 0);
if(addr < se->addr) if (addr < se->addr)
return 0; return 0;
for(i = 1; i < sym_table.elements; i++) for (i = 1; i < sym_table.elements; i++)
{
get_dynamic(&sym_table, (gptr)se, i);
if (addr < se->addr)
{ {
get_dynamic(&sym_table, (gptr)se, i); get_dynamic(&sym_table, (gptr)se, i - 1);
if(addr < se->addr) return se;
{
get_dynamic(&sym_table, (gptr)se, i - 1);
return se;
}
} }
}
return se; return se;
} }
static void do_resolve() static void do_resolve()
{ {
char buf[1024], *p; char buf[1024], *p;
while(fgets(buf, sizeof(buf), fp_dump)) while (fgets(buf, sizeof(buf), fp_dump))
{
p = buf;
while(isspace(*p))
++p;
if (*p++ == '0' && *p++ == 'x')
{ {
p = buf; SYM_ENTRY se ;
while(isspace(*p)) uchar* addr = (uchar*)read_addr(&p);
++p; if (resolve_addr(addr, &se))
/* skip space */; fprintf(fp_out, "%p %s + %d\n", addr, se.symbol,
(int) (addr - se.addr));
if(*p++ == '0' && *p++ == 'x')
{
SYM_ENTRY se ;
uchar* addr = (uchar*)read_addr(&p);
if(resolve_addr(addr, &se))
fprintf(fp_out, "%p %s + %d\n", addr, se.symbol,
(int) (addr - se.addr));
else
fprintf(fp_out, "%p (?)\n", addr);
}
else else
{ fprintf(fp_out, "%p (?)\n", addr);
fputs(buf, fp_out);
continue;
}
} }
else
{
fputs(buf, fp_out);
continue;
}
}
} }
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
MY_INIT(argv[0]); MY_INIT(argv[0]);

View file

@ -30,7 +30,8 @@ extern "C" {
#define HA_FT_MAXLEN 254 #define HA_FT_MAXLEN 254
typedef struct st_ft_info FT_INFO; typedef struct st_ft_info FT_INFO;
struct _ft_vft { struct _ft_vft
{
int (*read_next)(FT_INFO *, char *); int (*read_next)(FT_INFO *, char *);
float (*find_relevance)(FT_INFO *, byte *, uint); float (*find_relevance)(FT_INFO *, byte *, uint);
void (*close_search)(FT_INFO *); void (*close_search)(FT_INFO *);
@ -39,7 +40,8 @@ struct _ft_vft {
}; };
#ifndef FT_CORE #ifndef FT_CORE
struct st_ft_info { struct st_ft_info
{
struct _ft_vft *please; /* INTERCAL style :-) */ struct _ft_vft *please; /* INTERCAL style :-) */
}; };
#endif #endif

View file

@ -18,18 +18,23 @@
Data structures for mysys/my_alloc.c (root memory allocator) Data structures for mysys/my_alloc.c (root memory allocator)
*/ */
#ifndef ST_USED_MEM_DEFINED #ifndef _my_alloc_h
#define ST_USED_MEM_DEFINED #define _my_alloc_h
typedef struct st_used_mem { /* struct for once_alloc (block) */
typedef struct st_used_mem
{ /* struct for once_alloc (block) */
struct st_used_mem *next; /* Next block in use */ struct st_used_mem *next; /* Next block in use */
unsigned int left; /* memory left in block */ unsigned int left; /* memory left in block */
unsigned int size; /* size of block */ unsigned int size; /* size of block */
} USED_MEM; } USED_MEM;
typedef struct st_mem_root {
typedef struct st_mem_root
{
USED_MEM *free; /* blocks with free memory in it */ USED_MEM *free; /* blocks with free memory in it */
USED_MEM *used; /* blocks almost without free memory */ USED_MEM *used; /* blocks almost without free memory */
USED_MEM *pre_alloc; /* preallocated block */ USED_MEM *pre_alloc; /* preallocated block */
/* if block have less memory it will be put in 'used' list*/ /* if block have less memory it will be put in 'used' list */
unsigned int min_malloc; unsigned int min_malloc;
unsigned int block_size; /* initial block size */ unsigned int block_size; /* initial block size */
unsigned int block_num; /* allocated blocks counter */ unsigned int block_num; /* allocated blocks counter */

View file

@ -14,8 +14,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This is the main include file that should included 'first' in every /* This is the include file that should be included 'first' in every C file. */
C file. */
#ifndef _global_h #ifndef _global_h
#define _global_h #define _global_h
@ -51,16 +50,6 @@
#endif #endif
#endif /* _WIN32... */ #endif /* _WIN32... */
/* sometimes we want to make sure that the variable is not put into
a register in debugging mode so we can see its value in the core
*/
#ifndef DBUG_OFF
#define dbug_volatile volatile
#else
#define dbug_volatile
#endif
/* /*
The macros below are borrowed from include/linux/compiler.h in the The macros below are borrowed from include/linux/compiler.h in the
Linux kernel. Use them to indicate the likelyhood of the truthfulness Linux kernel. Use them to indicate the likelyhood of the truthfulness
@ -106,7 +95,7 @@
#ifndef _POSIX_PTHREAD_SEMANTICS #ifndef _POSIX_PTHREAD_SEMANTICS
#define _POSIX_PTHREAD_SEMANTICS /* We want posix threads */ #define _POSIX_PTHREAD_SEMANTICS /* We want posix threads */
#endif #endif
/* was #if defined(HAVE_LINUXTHREADS) || defined(HAVE_DEC_THREADS) || defined(HPUX) */
#if !defined(SCO) #if !defined(SCO)
#define _REENTRANT 1 /* Some thread libraries require this */ #define _REENTRANT 1 /* Some thread libraries require this */
#endif #endif
@ -275,10 +264,6 @@
#define DONT_USE_MYSQL_PWD 1 #define DONT_USE_MYSQL_PWD 1
#endif #endif
/* #define USE_some_charset 1 was deprecated by changes to configure */
/* my_ctype my_to_upper, my_to_lower, my_sort_order gain theit right value */
/* automagically during configuration */
/* Does the system remember a signal handler after a signal ? */ /* Does the system remember a signal handler after a signal ? */
#ifndef HAVE_BSD_SIGNALS #ifndef HAVE_BSD_SIGNALS
#define DONT_REMEMBER_SIGNAL #define DONT_REMEMBER_SIGNAL
@ -348,9 +333,11 @@ typedef unsigned short ushort;
/* From old s-system.h */ /* From old s-system.h */
/* Support macros for non ansi & other old compilers. Since such /*
things are no longer supported we do nothing. We keep then since Support macros for non ansi & other old compilers. Since such
some of our code may still be needed to upgrade old customers. */ things are no longer supported we do nothing. We keep then since
some of our code may still be needed to upgrade old customers.
*/
#define _VARARGS(X) X #define _VARARGS(X) X
#define _STATIC_VARARGS(X) X #define _STATIC_VARARGS(X) X
#define _PC(X) X #define _PC(X) X
@ -468,12 +455,16 @@ typedef SOCKET_SIZE_TYPE size_socket;
/* #define FN_NO_CASE_SENCE */ /* #define FN_NO_CASE_SENCE */
/* #define FN_UPPER_CASE TRUE */ /* #define FN_UPPER_CASE TRUE */
/* Io buffer size; Must be a power of 2 and a multiple of 512. May be /*
smaller what the disk page size. This influences the speed of the Io buffer size; Must be a power of 2 and a multiple of 512. May be
isam btree library. eg to big to slow. */ smaller what the disk page size. This influences the speed of the
isam btree library. eg to big to slow.
*/
#define IO_SIZE 4096 #define IO_SIZE 4096
/* How much overhead does malloc have. The code often allocates /*
something like 1024-MALLOC_OVERHEAD bytes */ How much overhead does malloc have. The code often allocates
something like 1024-MALLOC_OVERHEAD bytes
*/
#ifdef SAFEMALLOC #ifdef SAFEMALLOC
#define MALLOC_OVERHEAD (8+24+4) #define MALLOC_OVERHEAD (8+24+4)
#else #else
@ -488,7 +479,6 @@ typedef SOCKET_SIZE_TYPE size_socket;
/* Some things that this system doesn't have */ /* Some things that this system doesn't have */
#define ONLY_OWN_DATABASES /* We are using only databases by monty */
#define NO_HASH /* Not needed anymore */ #define NO_HASH /* Not needed anymore */
#ifdef __WIN__ #ifdef __WIN__
#define NO_DIR_LIBRARY /* Not standar dir-library */ #define NO_DIR_LIBRARY /* Not standar dir-library */
@ -534,11 +524,6 @@ extern double my_atof(const char*);
#define strtok_r(A,B,C) strtok((A),(B)) #define strtok_r(A,B,C) strtok((A),(B))
#endif #endif
#ifdef HAVE_LINUXTHREADS
/* #define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C)) */
/* #define sigset(A,B) signal((A),(B)) */
#endif
/* Remove some things that mit_thread break or doesn't support */ /* Remove some things that mit_thread break or doesn't support */
#if defined(HAVE_mit_thread) && defined(THREAD) #if defined(HAVE_mit_thread) && defined(THREAD)
#undef HAVE_PREAD #undef HAVE_PREAD
@ -589,8 +574,10 @@ extern double my_atof(const char*);
#define FLT_MAX ((float)3.40282346638528860e+38) #define FLT_MAX ((float)3.40282346638528860e+38)
#endif #endif
/* Max size that must be added to a so that we know Size to make /*
adressable obj. */ Max size that must be added to a so that we know Size to make
adressable obj.
*/
typedef long my_ptrdiff_t; typedef long my_ptrdiff_t;
#define MY_ALIGN(A,L) (((A) + (L) - 1) & ~((L) - 1)) #define MY_ALIGN(A,L) (((A) + (L) - 1) & ~((L) - 1))
#define ALIGN_SIZE(A) MY_ALIGN((A),sizeof(double)) #define ALIGN_SIZE(A) MY_ALIGN((A),sizeof(double))
@ -648,21 +635,23 @@ error "Neither int or long is of 4 bytes width"
#endif #endif
#if !defined(HAVE_ULONG) && !defined(HAVE_LINUXTHREADS) && !defined(__USE_MISC) #if !defined(HAVE_ULONG) && !defined(HAVE_LINUXTHREADS) && !defined(__USE_MISC)
typedef unsigned long ulong; /* Short for unsigned long */ typedef unsigned long ulong; /* Short for unsigned long */
#endif #endif
#ifndef longlong_defined #ifndef longlong_defined
#if defined(HAVE_LONG_LONG) && SIZEOF_LONG != 8 #if defined(HAVE_LONG_LONG) && SIZEOF_LONG != 8
typedef unsigned long long int ulonglong; /* ulong or unsigned long long */ typedef unsigned long long int ulonglong; /* ulong or unsigned long long */
typedef long long int longlong; typedef long long int longlong;
#else #else
typedef unsigned long ulonglong; /* ulong or unsigned long long */ typedef unsigned long ulonglong; /* ulong or unsigned long long */
typedef long longlong; typedef long longlong;
#endif #endif
#endif #endif
#ifdef USE_RAID #ifdef USE_RAID
/* The following is done with a if to not get problems with pre-processors /*
with late define evaluation */ The following is done with a if to not get problems with pre-processors
with late define evaluation
*/
#if SIZEOF_OFF_T == 4 #if SIZEOF_OFF_T == 4
#define SYSTEM_SIZEOF_OFF_T 4 #define SYSTEM_SIZEOF_OFF_T 4
#else #else
@ -727,8 +716,10 @@ typedef char bool; /* Ordinary boolean values 0 1 */
#define INT32(v) (int32) (v) #define INT32(v) (int32) (v)
#define MYF(v) (myf) (v) #define MYF(v) (myf) (v)
/* Defines to make it possible to prioritize register assignments. No /*
longer needed with moder compilers */ Defines to make it possible to prioritize register assignments. No
longer that important with modern compilers.
*/
#ifndef USING_X #ifndef USING_X
#define reg1 register #define reg1 register
#define reg2 register #define reg2 register
@ -748,6 +739,17 @@ typedef char bool; /* Ordinary boolean values 0 1 */
#define reg16 register #define reg16 register
#endif #endif
/*
Sometimes we want to make sure that the variable is not put into
a register in debugging mode so we can see its value in the core
*/
#ifndef DBUG_OFF
#define dbug_volatile volatile
#else
#define dbug_volatile
#endif
/* Defines for time function */ /* Defines for time function */
#define SCALE_SEC 100 #define SCALE_SEC 100
#define SCALE_USEC 10000 #define SCALE_USEC 10000
@ -769,8 +771,8 @@ typedef char bool; /* Ordinary boolean values 0 1 */
#endif #endif
/* /*
** Define-funktions for reading and storing in machine independent format Define-funktions for reading and storing in machine independent format
** (low byte first) (low byte first)
*/ */
/* Optimized store functions for Intel x86 */ /* Optimized store functions for Intel x86 */
@ -943,9 +945,11 @@ typedef union {
#endif /* sint2korr */ #endif /* sint2korr */
/* Define-funktions for reading and storing in machine format from/to /*
short/long to/from some place in memory V should be a (not Define-funktions for reading and storing in machine format from/to
register) variable, M is a pointer to byte */ short/long to/from some place in memory V should be a (not
register) variable, M is a pointer to byte
*/
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN

View file

@ -245,16 +245,20 @@ typedef struct wild_file_pack /* Struct to hold info when selecting files */
typedef struct st_typelib { /* Different types saved here */ typedef struct st_typelib { /* Different types saved here */
uint count; /* How many types */ uint count; /* How many types */
const char *name; /* Name of typelib */ const char *name; /* Name of typelib */
const char **type_names; const char **type_names;
} TYPELIB; } TYPELIB;
enum cache_type {READ_CACHE,WRITE_CACHE, enum cache_type
SEQ_READ_APPEND /* sequential read or append */, {
READ_FIFO, READ_CACHE,WRITE_CACHE,
READ_NET,WRITE_NET}; SEQ_READ_APPEND /* sequential read or append */,
enum flush_type { FLUSH_KEEP, FLUSH_RELEASE, FLUSH_IGNORE_CHANGED, READ_FIFO, READ_NET,WRITE_NET};
FLUSH_FORCE_WRITE};
enum flush_type
{
FLUSH_KEEP, FLUSH_RELEASE, FLUSH_IGNORE_CHANGED, FLUSH_FORCE_WRITE
};
typedef struct st_record_cache /* Used when cacheing records */ typedef struct st_record_cache /* Used when cacheing records */
{ {
@ -270,9 +274,11 @@ typedef struct st_record_cache /* Used when cacheing records */
enum cache_type type; enum cache_type type;
} RECORD_CACHE; } RECORD_CACHE;
enum file_type { UNOPEN = 0, FILE_BY_OPEN, FILE_BY_CREATE, enum file_type
STREAM_BY_FOPEN, STREAM_BY_FDOPEN, FILE_BY_MKSTEMP, {
FILE_BY_DUP }; UNOPEN = 0, FILE_BY_OPEN, FILE_BY_CREATE, STREAM_BY_FOPEN, STREAM_BY_FDOPEN,
FILE_BY_MKSTEMP, FILE_BY_DUP
};
extern struct my_file_info extern struct my_file_info
{ {
@ -284,14 +290,16 @@ extern struct my_file_info
} my_file_info[MY_NFILE]; } my_file_info[MY_NFILE];
typedef struct st_dynamic_array { typedef struct st_dynamic_array
{
char *buffer; char *buffer;
uint elements,max_element; uint elements,max_element;
uint alloc_increment; uint alloc_increment;
uint size_of_element; uint size_of_element;
} DYNAMIC_ARRAY; } DYNAMIC_ARRAY;
typedef struct st_dynamic_string { typedef struct st_dynamic_string
{
char *str; char *str;
uint length,max_length,alloc_increment; uint length,max_length,alloc_increment;
} DYNAMIC_STRING; } DYNAMIC_STRING;
@ -453,8 +461,8 @@ my_off_t my_b_append_tell(IO_CACHE* info);
#define my_b_bytes_in_cache(info) (uint) (*(info)->current_end - \ #define my_b_bytes_in_cache(info) (uint) (*(info)->current_end - \
*(info)->current_pos) *(info)->current_pos)
typedef struct st_changeable_var
typedef struct st_changeable_var { {
const char *name; /* Name of variable */ const char *name; /* Name of variable */
long *varptr; /* Pointer to variable */ long *varptr; /* Pointer to variable */
long def_value, /* Default value */ long def_value, /* Default value */

View file

@ -170,9 +170,11 @@ typedef struct st_mi_decode_tree /* Decode huff-table */
struct st_mi_bit_buff; struct st_mi_bit_buff;
/* Note that null markers should always be first in a row ! /*
When creating a column, one should only specify: Note that null markers should always be first in a row !
type, length, null_bit and null_pos */ When creating a column, one should only specify:
type, length, null_bit and null_pos
*/
typedef struct st_columndef /* column information */ typedef struct st_columndef /* column information */
{ {
@ -253,14 +255,15 @@ extern uint mi_get_pointer_length(ulonglong file_length, uint def);
#define MYISAMCHK_VERIFY 2 /* run equivalent of myisamchk -c, #define MYISAMCHK_VERIFY 2 /* run equivalent of myisamchk -c,
* if corruption is detected, do myisamchk -r*/ * if corruption is detected, do myisamchk -r*/
/* definitions needed for myisamchk.c -- by Sasha Pachev */ /*
Definitions needed for myisamchk.c
/* entries marked as "QQ to be removed" are NOT used to Entries marked as "QQ to be removed" are NOT used to
* pass check/repair options to mi_check.c. They are used pass check/repair options to mi_check.c. They are used
* internally by myisamchk.c or/and ha_myisam.cc and should NOT internally by myisamchk.c or/and ha_myisam.cc and should NOT
* be stored together with other flags. They should be removed be stored together with other flags. They should be removed
* from the following list to make adding of new flags possible. from the following list to make adding of new flags possible.
* -- Sergei */ */
#define T_VERBOSE 1 #define T_VERBOSE 1
#define T_SILENT 2 #define T_SILENT 2
@ -295,9 +298,10 @@ extern uint mi_get_pointer_length(ulonglong file_length, uint def);
#define T_QUICK (1L << 30) #define T_QUICK (1L << 30)
#define T_RETRY_WITHOUT_QUICK (1L << 31) #define T_RETRY_WITHOUT_QUICK (1L << 31)
/* flags used by myisamchk.c or/and ha_myisam.cc that are NOT passed /*
* to mi_check.c follows: Flags used by myisamchk.c or/and ha_myisam.cc that are NOT passed
* */ to mi_check.c follows:
*/
#define TT_USEFRM 1 #define TT_USEFRM 1
@ -307,7 +311,8 @@ extern uint mi_get_pointer_length(ulonglong file_length, uint def);
/* these struct is used by my_check to tell it what to do */ /* these struct is used by my_check to tell it what to do */
typedef struct st_sort_key_blocks { /* Used when sorting */ typedef struct st_sort_key_blocks /* Used when sorting */
{
uchar *buff,*end_pos; uchar *buff,*end_pos;
uchar lastkey[MI_MAX_POSSIBLE_KEY_BUFF]; uchar lastkey[MI_MAX_POSSIBLE_KEY_BUFF];
uint last_length; uint last_length;
@ -316,7 +321,8 @@ typedef struct st_sort_key_blocks { /* Used when sorting */
struct st_mi_check_param; struct st_mi_check_param;
typedef struct st_sort_info { typedef struct st_sort_info
{
MI_INFO *info; MI_INFO *info;
struct st_mi_check_param *param; struct st_mi_check_param *param;
enum data_file_type new_data_file_type; enum data_file_type new_data_file_type;
@ -364,7 +370,8 @@ typedef struct st_mi_check_param
} MI_CHECK; } MI_CHECK;
typedef struct st_mi_sortinfo { typedef struct st_mi_sortinfo
{
ha_rows max_records; ha_rows max_records;
SORT_INFO *sort_info; SORT_INFO *sort_info;
char *tmpdir; char *tmpdir;
@ -403,7 +410,7 @@ int filecopy(MI_CHECK *param, File to,File from,my_off_t start,
int movepoint(MI_INFO *info,byte *record,my_off_t oldpos, int movepoint(MI_INFO *info,byte *record,my_off_t oldpos,
my_off_t newpos, uint prot_key); my_off_t newpos, uint prot_key);
int sort_write_record(SORT_INFO *sort_info); int sort_write_record(SORT_INFO *sort_info);
int write_data_suffix(MI_CHECK *param, MI_INFO *info); int write_data_suffix(MI_CHECK *param, MI_INFO *info);
int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages, int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
ulong); ulong);
int test_if_almost_full(MI_INFO *info); int test_if_almost_full(MI_INFO *info);

View file

@ -144,12 +144,12 @@ static MYSQL* spawn_init(MYSQL* parent, const char* host,
/**************************************************************************** /****************************************************************************
* A modified version of connect(). connect2() allows you to specify A modified version of connect(). connect2() allows you to specify
* a timeout value, in seconds, that we should wait until we a timeout value, in seconds, that we should wait until we
* derermine we can't connect to a particular host. If timeout is 0, derermine we can't connect to a particular host. If timeout is 0,
* my_connect() will behave exactly like connect(). my_connect() will behave exactly like connect().
*
* Base version coded by Steve Bernacki, Jr. <steve@navinet.net> Base version coded by Steve Bernacki, Jr. <steve@navinet.net>
*****************************************************************************/ *****************************************************************************/
int my_connect(my_socket s, const struct sockaddr *name, uint namelen, int my_connect(my_socket s, const struct sockaddr *name, uint namelen,
@ -249,7 +249,7 @@ int my_connect(my_socket s, const struct sockaddr *name, uint namelen,
} }
/* /*
** Create a named pipe connection Create a named pipe connection
*/ */
#ifdef __WIN__ #ifdef __WIN__
@ -322,8 +322,8 @@ HANDLE create_named_pipe(NET *net, uint connect_timeout, char **arg_host,
/***************************************************************************** /*****************************************************************************
** read a packet from server. Give error message if socket was down read a packet from server. Give error message if socket was down
** or packet is an error message or packet is an error message
*****************************************************************************/ *****************************************************************************/
ulong ulong
@ -569,7 +569,7 @@ static my_bool is_NT(void)
#endif #endif
/* /*
** Expand wildcard to a sql string Expand wildcard to a sql string
*/ */
static void static void
@ -595,7 +595,7 @@ append_wild(char *to, char *end, const char *wild)
/************************************************************************** /**************************************************************************
** Init debugging if MYSQL_DEBUG environment variable is found Init debugging if MYSQL_DEBUG environment variable is found
**************************************************************************/ **************************************************************************/
void STDCALL void STDCALL
@ -632,7 +632,7 @@ mysql_debug(const char *debug __attribute__((unused)))
/************************************************************************** /**************************************************************************
** Close the server connection if we get a SIGPIPE Close the server connection if we get a SIGPIPE
ARGSUSED ARGSUSED
**************************************************************************/ **************************************************************************/
@ -647,7 +647,7 @@ pipe_sig_handler(int sig __attribute__((unused)))
/************************************************************************** /**************************************************************************
** Shut down connection Shut down connection
**************************************************************************/ **************************************************************************/
static void static void
@ -701,7 +701,7 @@ mysql_free_result(MYSQL_RES *result)
/**************************************************************************** /****************************************************************************
** Get options from my.cnf Get options from my.cnf
****************************************************************************/ ****************************************************************************/
static const char *default_options[]= static const char *default_options[]=
@ -879,7 +879,7 @@ static void mysql_read_default_options(struct st_mysql_options *options,
/*************************************************************************** /***************************************************************************
** Change field rows to field structs Change field rows to field structs
***************************************************************************/ ***************************************************************************/
static MYSQL_FIELD * static MYSQL_FIELD *
@ -1004,8 +1004,8 @@ static MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
/* /*
** Read one row. Uses packet buffer as storage for fields. Read one row. Uses packet buffer as storage for fields.
** When next packet is read, the previous field values are destroyed When next packet is read, the previous field values are destroyed
*/ */
@ -1146,9 +1146,11 @@ static inline void expand_error(MYSQL* mysql, int error)
mysql->net.last_errno = error; mysql->net.last_errno = error;
} }
/* This function assumes we have just called SHOW SLAVE STATUS and have /*
read the given result and row This function assumes we have just called SHOW SLAVE STATUS and have
read the given result and row
*/ */
static inline int get_master(MYSQL* mysql, MYSQL_RES* res, MYSQL_ROW row) static inline int get_master(MYSQL* mysql, MYSQL_RES* res, MYSQL_ROW row)
{ {
MYSQL* master; MYSQL* master;
@ -1162,9 +1164,12 @@ static inline int get_master(MYSQL* mysql, MYSQL_RES* res, MYSQL_ROW row)
return 0; return 0;
} }
/* assuming we already know that mysql points to a master connection,
retrieve all the slaves /*
Assuming we already know that mysql points to a master connection,
retrieve all the slaves
*/ */
static inline int get_slaves_from_master(MYSQL* mysql) static inline int get_slaves_from_master(MYSQL* mysql)
{ {
MYSQL_RES* res = 0; MYSQL_RES* res = 0;
@ -1180,14 +1185,13 @@ static inline int get_slaves_from_master(MYSQL* mysql)
} }
if (mysql_query(mysql, "SHOW SLAVE HOSTS") || if (mysql_query(mysql, "SHOW SLAVE HOSTS") ||
!(res = mysql_store_result(mysql))) !(res = mysql_store_result(mysql)))
{ {
expand_error(mysql, CR_PROBE_SLAVE_HOSTS); expand_error(mysql, CR_PROBE_SLAVE_HOSTS);
return 1; return 1;
} }
switch (mysql_num_fields(res)) switch (mysql_num_fields(res)) {
{
case 5: case 5:
has_auth_info = 0; has_auth_info = 0;
port_ind=2; port_ind=2;
@ -1236,15 +1240,16 @@ int STDCALL mysql_rpl_probe(MYSQL* mysql)
MYSQL_RES* res = 0; MYSQL_RES* res = 0;
MYSQL_ROW row; MYSQL_ROW row;
int error = 1; int error = 1;
/* first determine the replication role of the server we connected to /*
the most reliable way to do this is to run SHOW SLAVE STATUS and see First determine the replication role of the server we connected to
if we have a non-empty master host. This is still not fool-proof - the most reliable way to do this is to run SHOW SLAVE STATUS and see
it is not a sin to have a master that has a dormant slave thread with if we have a non-empty master host. This is still not fool-proof -
a non-empty master host. However, it is more reliable to check it is not a sin to have a master that has a dormant slave thread with
for empty master than whether the slave thread is actually running a non-empty master host. However, it is more reliable to check
for empty master than whether the slave thread is actually running
*/ */
if (mysql_query(mysql, "SHOW SLAVE STATUS") || if (mysql_query(mysql, "SHOW SLAVE STATUS") ||
!(res = mysql_store_result(mysql))) !(res = mysql_store_result(mysql)))
{ {
expand_error(mysql, CR_PROBE_SLAVE_STATUS); expand_error(mysql, CR_PROBE_SLAVE_STATUS);
return 1; return 1;
@ -1275,51 +1280,54 @@ err:
} }
/* make a not so fool-proof decision on where the query should go, to /*
the master or the slave. Ideally the user should always make this Make a not so fool-proof decision on where the query should go, to
decision himself with mysql_master_query() or mysql_slave_query(). the master or the slave. Ideally the user should always make this
However, to be able to more easily port the old code, we support the decision himself with mysql_master_query() or mysql_slave_query().
option of an educated guess - this should work for most applications, However, to be able to more easily port the old code, we support the
however, it may make the wrong decision in some particular cases. If option of an educated guess - this should work for most applications,
that happens, the user would have to change the code to call however, it may make the wrong decision in some particular cases. If
mysql_master_query() or mysql_slave_query() explicitly in the place that happens, the user would have to change the code to call
where we have made the wrong decision mysql_master_query() or mysql_slave_query() explicitly in the place
where we have made the wrong decision
*/ */
enum mysql_rpl_type enum mysql_rpl_type
STDCALL mysql_rpl_query_type(const char* q, int len) STDCALL mysql_rpl_query_type(const char* q, int len)
{ {
const char* q_end; const char* q_end;
q_end = (len) ? q + len : strend(q); q_end = (len) ? q + len : strend(q);
for(; q < q_end; ++q) for (; q < q_end; ++q)
{ {
char c; char c;
if (isalpha(c=*q)) if (isalpha(c=*q))
switch(tolower(c)) {
{ switch(tolower(c)) {
case 'i': /* insert */ case 'i': /* insert */
case 'u': /* update or unlock tables */ case 'u': /* update or unlock tables */
case 'l': /* lock tables or load data infile */ case 'l': /* lock tables or load data infile */
case 'd': /* drop or delete */ case 'd': /* drop or delete */
case 'a': /* alter */ case 'a': /* alter */
return MYSQL_RPL_MASTER; return MYSQL_RPL_MASTER;
case 'c': /* create or check */ case 'c': /* create or check */
return tolower(q[1]) == 'h' ? MYSQL_RPL_ADMIN : MYSQL_RPL_MASTER ; return tolower(q[1]) == 'h' ? MYSQL_RPL_ADMIN : MYSQL_RPL_MASTER ;
case 's': /* select or show */ case 's': /* select or show */
return tolower(q[1]) == 'h' ? MYSQL_RPL_ADMIN : MYSQL_RPL_SLAVE; return tolower(q[1]) == 'h' ? MYSQL_RPL_ADMIN : MYSQL_RPL_SLAVE;
case 'f': /* flush */ case 'f': /* flush */
case 'r': /* repair */ case 'r': /* repair */
case 'g': /* grant */ case 'g': /* grant */
return MYSQL_RPL_ADMIN; return MYSQL_RPL_ADMIN;
default: default:
return MYSQL_RPL_SLAVE; return MYSQL_RPL_SLAVE;
} }
}
} }
return MYSQL_RPL_MASTER; /* By default, send to master */ return MYSQL_RPL_MASTER; /* By default, send to master */
} }
/**************************************************************************** /****************************************************************************
** Init MySQL structure or allocate one Init MySQL structure or allocate one
****************************************************************************/ ****************************************************************************/
MYSQL * STDCALL MYSQL * STDCALL
@ -1338,8 +1346,9 @@ mysql_init(MYSQL *mysql)
mysql->options.connect_timeout=CONNECT_TIMEOUT; mysql->options.connect_timeout=CONNECT_TIMEOUT;
mysql->last_used_con = mysql->next_slave = mysql->master = mysql; mysql->last_used_con = mysql->next_slave = mysql->master = mysql;
mysql->last_used_slave = 0; mysql->last_used_slave = 0;
/* By default, we are a replication pivot. The caller must reset it /*
after we return if this is not the case. By default, we are a replication pivot. The caller must reset it
after we return if this is not the case.
*/ */
mysql->rpl_pivot = 1; mysql->rpl_pivot = 1;
#if defined(SIGPIPE) && defined(THREAD) && !defined(__WIN__) #if defined(SIGPIPE) && defined(THREAD) && !defined(__WIN__)
@ -1403,37 +1412,42 @@ static void mysql_once_init()
} }
/************************************************************************** /**************************************************************************
** Fill in SSL part of MYSQL structure and set 'use_ssl' flag. Fill in SSL part of MYSQL structure and set 'use_ssl' flag.
** NB! Errors are not reported until you do mysql_real_connect. NB! Errors are not reported until you do mysql_real_connect.
**************************************************************************/ **************************************************************************/
#define strdup_if_not_null(A) (A) == 0 ? 0 : my_strdup((A),MYF(MY_WME))
int STDCALL int STDCALL
mysql_ssl_set(MYSQL *mysql __attribute__((unused)) , mysql_ssl_set(MYSQL *mysql __attribute__((unused)) ,
const char *key __attribute__((unused)), const char *key __attribute__((unused)),
const char *cert __attribute__((unused)), const char *cert __attribute__((unused)),
const char *ca __attribute__((unused)), const char *ca __attribute__((unused)),
const char *capath __attribute__((unused)), const char *capath __attribute__((unused)),
const char *cipher __attribute__((unused))) const char *cipher __attribute__((unused)))
{ {
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
mysql->options.ssl_key = key==0 ? 0 : my_strdup(key,MYF(0)); mysql->options.ssl_key= strdup_if_not_null(key);
mysql->options.ssl_cert = cert==0 ? 0 : my_strdup(cert,MYF(0)); mysql->options.ssl_cert= strdup_if_not_null(cert);
mysql->options.ssl_ca = ca==0 ? 0 : my_strdup(ca,MYF(0)); mysql->options.ssl_ca= strdup_if_not_null(ca);
mysql->options.ssl_capath = capath==0 ? 0 : my_strdup(capath,MYF(0)); mysql->options.ssl_capath= strdup_if_not_null(capath);
mysql->options.ssl_cipher = cipher==0 ? 0 : my_strdup(cipher,MYF(0)); mysql->options.ssl_cipher= strdup_if_not_null(cipher);
mysql->options.use_ssl = TRUE; mysql->options.use_ssl= TRUE;
mysql->connector_fd = (gptr)new_VioSSLConnectorFd(key, cert, ca, capath, cipher); mysql->connector_fd = (gptr) new_VioSSLConnectorFd(key, cert, ca, capath,
DBUG_PRINT("info",("mysql_ssl_set, context: %p",((struct st_VioSSLConnectorFd *)(mysql->connector_fd))->ssl_context_)); cipher);
DBUG_PRINT("info",("mysql_ssl_set, context: %p",
((struct st_VioSSLConnectorFd *) (mysql->connector_fd))->
ssl_context_));
#endif #endif
return 0; return 0;
} }
/*
*************************************************************************** /**************************************************************************
** Free strings in the SSL structure and clear 'use_ssl' flag. Free strings in the SSL structure and clear 'use_ssl' flag.
** NB! Errors are not reported until you do mysql_real_connect. NB! Errors are not reported until you do mysql_real_connect.
************************************************************************** **************************************************************************/
*/
int STDCALL int STDCALL
mysql_ssl_clear(MYSQL *mysql __attribute__((unused))) mysql_ssl_clear(MYSQL *mysql __attribute__((unused)))
{ {
@ -1443,21 +1457,21 @@ mysql_ssl_clear(MYSQL *mysql __attribute__((unused)))
my_free(mysql->options.ssl_ca, MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.ssl_ca, MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.ssl_capath, MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.ssl_capath, MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.ssl_cipher, MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.ssl_cipher, MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->connector_fd,MYF(MY_ALLOW_ZERO_PTR));
mysql->options.ssl_key = 0; mysql->options.ssl_key = 0;
mysql->options.ssl_cert = 0; mysql->options.ssl_cert = 0;
mysql->options.ssl_ca = 0; mysql->options.ssl_ca = 0;
mysql->options.ssl_capath = 0; mysql->options.ssl_capath = 0;
mysql->options.ssl_cipher= 0; mysql->options.ssl_cipher= 0;
mysql->options.use_ssl = FALSE; mysql->options.use_ssl = FALSE;
my_free(mysql->connector_fd,MYF(MY_ALLOW_ZERO_PTR));
mysql->connector_fd = 0; mysql->connector_fd = 0;
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
return 0; return 0;
} }
/************************************************************************** /**************************************************************************
** Connect to sql server Connect to sql server
** If host == 0 then use localhost If host == 0 then use localhost
**************************************************************************/ **************************************************************************/
#ifdef USE_OLD_FUNCTIONS #ifdef USE_OLD_FUNCTIONS
@ -1481,8 +1495,8 @@ mysql_connect(MYSQL *mysql,const char *host,
/* /*
** Note that the mysql argument must be initialized with mysql_init() Note that the mysql argument must be initialized with mysql_init()
** before calling mysql_real_connect ! before calling mysql_real_connect !
*/ */
MYSQL * STDCALL MYSQL * STDCALL
@ -1824,8 +1838,10 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
mysql->client_flag=client_flag; mysql->client_flag=client_flag;
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
/* Oops.. are we careful enough to not send ANY information */ /*
/* without encryption? */ Oops.. are we careful enough to not send ANY information without
encryption?
*/
if (client_flag & CLIENT_SSL) if (client_flag & CLIENT_SSL)
{ {
if (my_net_write(net,buff,(uint) (2)) || net_flush(net)) if (my_net_write(net,buff,(uint) (2)) || net_flush(net))
@ -1897,7 +1913,9 @@ error:
DBUG_RETURN(0); DBUG_RETURN(0);
} }
/* needed when we move MYSQL structure to a different address */ /* needed when we move MYSQL structure to a different address */
static void mysql_fix_pointers(MYSQL* mysql, MYSQL* old_mysql) static void mysql_fix_pointers(MYSQL* mysql, MYSQL* old_mysql)
{ {
MYSQL *tmp, *tmp_prev; MYSQL *tmp, *tmp_prev;
@ -1915,6 +1933,7 @@ static void mysql_fix_pointers(MYSQL* mysql, MYSQL* old_mysql)
tmp_prev->next_slave = mysql; tmp_prev->next_slave = mysql;
} }
static my_bool mysql_reconnect(MYSQL *mysql) static my_bool mysql_reconnect(MYSQL *mysql)
{ {
MYSQL tmp_mysql; MYSQL tmp_mysql;
@ -1947,7 +1966,7 @@ static my_bool mysql_reconnect(MYSQL *mysql)
/************************************************************************** /**************************************************************************
** Change user and database Change user and database
**************************************************************************/ **************************************************************************/
my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
@ -1980,7 +1999,7 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
/************************************************************************** /**************************************************************************
** Set current database Set current database
**************************************************************************/ **************************************************************************/
int STDCALL int STDCALL
@ -1999,8 +2018,8 @@ mysql_select_db(MYSQL *mysql, const char *db)
/************************************************************************* /*************************************************************************
** Send a QUIT to the server and close the connection Send a QUIT to the server and close the connection
** If handle is alloced by mysql connect free it. If handle is alloced by mysql connect free it.
*************************************************************************/ *************************************************************************/
void STDCALL void STDCALL
@ -2062,8 +2081,8 @@ mysql_close(MYSQL *mysql)
/************************************************************************** /**************************************************************************
** Do a query. If query returned rows, free old rows. Do a query. If query returned rows, free old rows.
** Read data by mysql_store_result or by repeat call of mysql_fetch_row Read data by mysql_store_result or by repeat call of mysql_fetch_row
**************************************************************************/ **************************************************************************/
int STDCALL int STDCALL
@ -2287,8 +2306,8 @@ err:
/************************************************************************** /**************************************************************************
** Alloc result struct for buffered results. All rows are read to buffer. Alloc result struct for buffered results. All rows are read to buffer.
** mysql_data_seek may be used. mysql_data_seek may be used.
**************************************************************************/ **************************************************************************/
MYSQL_RES * STDCALL MYSQL_RES * STDCALL
@ -2338,13 +2357,13 @@ mysql_store_result(MYSQL *mysql)
/************************************************************************** /**************************************************************************
** Alloc struct for use with unbuffered reads. Data is fetched by domand Alloc struct for use with unbuffered reads. Data is fetched by domand
** when calling to mysql_fetch_row. when calling to mysql_fetch_row.
** mysql_data_seek is a noop. mysql_data_seek is a noop.
**
** No other queries may be specified with the same MYSQL handle. No other queries may be specified with the same MYSQL handle.
** There shouldn't be much processing per row because mysql server shouldn't There shouldn't be much processing per row because mysql server shouldn't
** have to wait for the client (and will not wait more than 30 sec/packet). have to wait for the client (and will not wait more than 30 sec/packet).
**************************************************************************/ **************************************************************************/
MYSQL_RES * STDCALL MYSQL_RES * STDCALL
@ -2388,7 +2407,7 @@ mysql_use_result(MYSQL *mysql)
/************************************************************************** /**************************************************************************
** Return next field of the query results Return next field of the query results
**************************************************************************/ **************************************************************************/
MYSQL_FIELD * STDCALL MYSQL_FIELD * STDCALL
@ -2401,7 +2420,7 @@ mysql_fetch_field(MYSQL_RES *result)
/************************************************************************** /**************************************************************************
** Return next row of the query results Return next row of the query results
**************************************************************************/ **************************************************************************/
MYSQL_ROW STDCALL MYSQL_ROW STDCALL
@ -2442,9 +2461,9 @@ mysql_fetch_row(MYSQL_RES *res)
} }
/************************************************************************** /**************************************************************************
** Get column lengths of the current row Get column lengths of the current row
** If one uses mysql_use_result, res->lengths contains the length information, If one uses mysql_use_result, res->lengths contains the length information,
** else the lengths are calculated from the offset between pointers. else the lengths are calculated from the offset between pointers.
**************************************************************************/ **************************************************************************/
ulong * STDCALL ulong * STDCALL
@ -2478,7 +2497,7 @@ mysql_fetch_lengths(MYSQL_RES *res)
} }
/************************************************************************** /**************************************************************************
** Move to a specific row and column Move to a specific row and column
**************************************************************************/ **************************************************************************/
void STDCALL void STDCALL
@ -2493,9 +2512,9 @@ mysql_data_seek(MYSQL_RES *result, my_ulonglong row)
} }
/************************************************************************* /*************************************************************************
** put the row or field cursor one a position one got from mysql_row_tell() put the row or field cursor one a position one got from mysql_row_tell()
** This doesn't restore any data. The next mysql_fetch_row or This doesn't restore any data. The next mysql_fetch_row or
** mysql_fetch_field will return the next row or field after the last used mysql_fetch_field will return the next row or field after the last used
*************************************************************************/ *************************************************************************/
MYSQL_ROW_OFFSET STDCALL MYSQL_ROW_OFFSET STDCALL
@ -2517,7 +2536,7 @@ mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET field_offset)
} }
/***************************************************************************** /*****************************************************************************
** List all databases List all databases
*****************************************************************************/ *****************************************************************************/
MYSQL_RES * STDCALL MYSQL_RES * STDCALL
@ -2534,8 +2553,8 @@ mysql_list_dbs(MYSQL *mysql, const char *wild)
/***************************************************************************** /*****************************************************************************
** List all tables in a database List all tables in a database
** If wild is given then only the tables matching wild is returned If wild is given then only the tables matching wild is returned
*****************************************************************************/ *****************************************************************************/
MYSQL_RES * STDCALL MYSQL_RES * STDCALL
@ -2552,10 +2571,10 @@ mysql_list_tables(MYSQL *mysql, const char *wild)
/************************************************************************** /**************************************************************************
** List all fields in a table List all fields in a table
** If wild is given then only the fields matching wild is returned If wild is given then only the fields matching wild is returned
** Instead of this use query: Instead of this use query:
** show fields in 'table' like "wild" show fields in 'table' like "wild"
**************************************************************************/ **************************************************************************/
MYSQL_RES * STDCALL MYSQL_RES * STDCALL
@ -2774,8 +2793,8 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const char *arg)
} }
/**************************************************************************** /****************************************************************************
** Functions to get information from the MySQL structure Functions to get information from the MySQL structure
** These are functions to make shared libraries more usable. These are functions to make shared libraries more usable.
****************************************************************************/ ****************************************************************************/
/* MYSQL_RES */ /* MYSQL_RES */
@ -2867,13 +2886,13 @@ uint STDCALL mysql_thread_safe(void)
} }
/**************************************************************************** /****************************************************************************
** Some support functions Some support functions
****************************************************************************/ ****************************************************************************/
/* /*
** Add escape characters to a string (blob?) to make it suitable for a insert Add escape characters to a string (blob?) to make it suitable for a insert
** to should at least have place for length*2+1 chars to should at least have place for length*2+1 chars
** Returns the length of the to string Returns the length of the to string
*/ */
ulong STDCALL ulong STDCALL

View file

@ -54,9 +54,6 @@
#endif #endif
#define RES_BUF_SHIFT 5 #define RES_BUF_SHIFT 5
#ifndef __WIN__
#define SOCKET_ERROR -1
#endif
#define NET_BUF_SIZE 2048 #define NET_BUF_SIZE 2048
MYSQL_MANAGER* STDCALL mysql_manager_init(MYSQL_MANAGER* con) MYSQL_MANAGER* STDCALL mysql_manager_init(MYSQL_MANAGER* con)
@ -101,7 +98,7 @@ MYSQL_MANAGER* STDCALL mysql_manager_connect(MYSQL_MANAGER* con,
if (!passwd) if (!passwd)
passwd=""; passwd="";
if ((sock=(my_socket)socket(AF_INET,SOCK_STREAM,0)) == SOCKET_ERROR) if ((sock=(my_socket)socket(AF_INET,SOCK_STREAM,0)) == INVALID_SOCKET)
{ {
con->last_errno=errno; con->last_errno=errno;
strmov(con->last_error,"Cannot create socket"); strmov(con->last_error,"Cannot create socket");
@ -185,6 +182,7 @@ MYSQL_MANAGER* STDCALL mysql_manager_connect(MYSQL_MANAGER* con,
strmov(con->user,user); strmov(con->user,user);
strmov(con->passwd,passwd); strmov(con->passwd,passwd);
return con; return con;
err: err:
{ {
my_bool free_me=con->free_me; my_bool free_me=con->free_me;
@ -195,18 +193,20 @@ err:
return 0; return 0;
} }
void STDCALL mysql_manager_close(MYSQL_MANAGER* con) void STDCALL mysql_manager_close(MYSQL_MANAGER* con)
{ {
my_free((gptr)con->host,MYF(MY_ALLOW_ZERO_PTR)); /*
/* no need to free con->user and con->passwd, because they were No need to free con->user and con->passwd, because they were
allocated in my_multimalloc() along with con->host, freeing allocated in my_multimalloc() along with con->host, freeing
con->hosts frees the whole block con->hosts frees the whole block
*/ */
my_free((gptr)con->host,MYF(MY_ALLOW_ZERO_PTR));
net_end(&con->net); net_end(&con->net);
if (con->free_me) if (con->free_me)
my_free((gptr)con,MYF(0)); my_free((gptr)con,MYF(0));
} }
int STDCALL mysql_manager_command(MYSQL_MANAGER* con,const char* cmd, int STDCALL mysql_manager_command(MYSQL_MANAGER* con,const char* cmd,
int cmd_len) int cmd_len)
{ {
@ -222,8 +222,9 @@ int STDCALL mysql_manager_command(MYSQL_MANAGER* con,const char* cmd,
return 0; return 0;
} }
int STDCALL mysql_manager_fetch_line(MYSQL_MANAGER* con, char* res_buf,
int res_buf_size) int STDCALL mysql_manager_fetch_line(MYSQL_MANAGER* con, char* res_buf,
int res_buf_size)
{ {
char* res_buf_end=res_buf+res_buf_size; char* res_buf_end=res_buf+res_buf_size;
char* net_buf=(char*) con->net.read_pos, *net_buf_end; char* net_buf=(char*) con->net.read_pos, *net_buf_end;
@ -252,7 +253,7 @@ int STDCALL mysql_manager_fetch_line(MYSQL_MANAGER* con, char* res_buf,
res_buf_end[-1]=0; res_buf_end[-1]=0;
for (;net_buf<net_buf_end && res_buf < res_buf_end;res_buf++,net_buf++) for (;net_buf<net_buf_end && res_buf < res_buf_end;res_buf++,net_buf++)
{ {
if((*res_buf=*net_buf) == '\r') if ((*res_buf=*net_buf) == '\r')
{ {
*res_buf=0; *res_buf=0;
break; break;

View file

@ -24,7 +24,8 @@
/* search with boolean queries */ /* search with boolean queries */
static double _wghts[11]={ static double _wghts[11]=
{
0.131687242798354, 0.131687242798354,
0.197530864197531, 0.197530864197531,
0.296296296296296, 0.296296296296296,
@ -38,7 +39,8 @@ static double _wghts[11]={
7.593750000000000}; 7.593750000000000};
static double *wghts=_wghts+5; /* wghts[i] = 1.5**i */ static double *wghts=_wghts+5; /* wghts[i] = 1.5**i */
static double _nwghts[11]={ static double _nwghts[11]=
{
-0.065843621399177, -0.065843621399177,
-0.098765432098766, -0.098765432098766,
-0.148148148148148, -0.148148148148148,
@ -57,7 +59,8 @@ static double *nwghts=_nwghts+5; /* nwghts[i] = -0.5*1.5**i */
#define FTB_FLAG_NO 4 /* should NEVER be set both */ #define FTB_FLAG_NO 4 /* should NEVER be set both */
typedef struct st_ftb_expr FTB_EXPR; typedef struct st_ftb_expr FTB_EXPR;
struct st_ftb_expr { struct st_ftb_expr
{
FTB_EXPR *up; FTB_EXPR *up;
byte *quot, *qend; byte *quot, *qend;
float weight; float weight;
@ -70,7 +73,8 @@ struct st_ftb_expr {
int yweaks; /* number of "yes" words for scan only */ int yweaks; /* number of "yes" words for scan only */
}; };
typedef struct st_ftb_word { typedef struct st_ftb_word
{
FTB_EXPR *up; FTB_EXPR *up;
float weight; float weight;
uint flags; uint flags;
@ -81,7 +85,8 @@ typedef struct st_ftb_word {
byte word[1]; byte word[1];
} FTB_WORD; } FTB_WORD;
typedef struct st_ft_info { typedef struct st_ft_info
{
struct _ft_vft *please; struct _ft_vft *please;
MI_INFO *info; MI_INFO *info;
uint keynr; uint keynr;
@ -200,21 +205,23 @@ void _ftb_init_index_search(FT_INFO *ftb)
{ {
ftbw=(FTB_WORD *)(ftb->queue.root[i]); ftbw=(FTB_WORD *)(ftb->queue.root[i]);
if (ftbw->flags&FTB_FLAG_TRUNC) if (ftbw->flags & FTB_FLAG_TRUNC)
/* special treatment for truncation operator :(( {
1. +trunc* and there're other (not +trunc*) words /*
special treatment for truncation operator :((
1. +trunc* and there're other (not +trunc*) words
| no need to search in the index, it can never ADD new rows | no need to search in the index, it can never ADD new rows
| to the result, and to remove half-matched rows we do scan anyway | to the result, and to remove half-matched rows we do scan anyway
2. -trunc* 2. -trunc*
| same as 1. | same as 1.
3. trunc* 3. trunc*
| We have to index-search for this prefix. | We have to index-search for this prefix.
| It may cause duplicates, as in the index (sorted by <word,docid>) | It may cause duplicates, as in the index (sorted by <word,docid>)
| <aaaa,row1> | <aaaa,row1>
| <aabb,row2> | <aabb,row2>
| <aacc,row1> | <aacc,row1>
| Searching for "aa*" will find row1 twice... | Searching for "aa*" will find row1 twice...
*/ */
if ( test(ftbw->flags&FTB_FLAG_NO) || /* 2 */ if ( test(ftbw->flags&FTB_FLAG_NO) || /* 2 */
(test(ftbw->flags&FTB_FLAG_YES) && /* 1 */ (test(ftbw->flags&FTB_FLAG_YES) && /* 1 */
ftbw->up->ythresh - ftbw->up->yweaks >1)) /* 1 */ ftbw->up->ythresh - ftbw->up->yweaks >1)) /* 1 */
@ -231,7 +238,7 @@ void _ftb_init_index_search(FT_INFO *ftb)
_ftb_no_dupes_cmp,0,0,0); _ftb_no_dupes_cmp,0,0,0);
} }
} }
}
r=_mi_search(info, keyinfo, (uchar*) ftbw->word, ftbw->len, r=_mi_search(info, keyinfo, (uchar*) ftbw->word, ftbw->len,
SEARCH_FIND | SEARCH_BIGGER, keyroot); SEARCH_FIND | SEARCH_BIGGER, keyroot);
if (!r) if (!r)
@ -246,8 +253,11 @@ void _ftb_init_index_search(FT_INFO *ftb)
if (r) /* not found */ if (r) /* not found */
{ {
if (ftbw->flags&FTB_FLAG_YES && ftbw->up->up==0) if (ftbw->flags&FTB_FLAG_YES && ftbw->up->up==0)
{ /* this word MUST BE present in every document returned, {
so we can abort the search right now */ /*
This word MUST BE present in every document returned,
so we can abort the search right now
*/
ftb->state=INDEX_DONE; ftb->state=INDEX_DONE;
return; return;
} }
@ -261,8 +271,10 @@ void _ftb_init_index_search(FT_INFO *ftb)
queue_fix(& ftb->queue); queue_fix(& ftb->queue);
} }
FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query, FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query,
uint query_len, my_bool presort __attribute__((unused))) uint query_len,
my_bool presort __attribute__((unused)))
{ {
FTB *ftb; FTB *ftb;
FTB_EXPR *ftbe; FTB_EXPR *ftbe;
@ -282,9 +294,10 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query,
init_alloc_root(&ftb->mem_root, 1024, 1024); init_alloc_root(&ftb->mem_root, 1024, 1024);
/* hack: instead of init_queue, we'll use reinit queue to be able /*
* to alloc queue with alloc_root() Hack: instead of init_queue, we'll use reinit queue to be able
*/ to alloc queue with alloc_root()
*/
res=ftb->queue.max_elements=1+query_len/(ft_min_word_len+1); res=ftb->queue.max_elements=1+query_len/(ft_min_word_len+1);
ftb->queue.root=(byte **)alloc_root(&ftb->mem_root, (res+1)*sizeof(void*)); ftb->queue.root=(byte **)alloc_root(&ftb->mem_root, (res+1)*sizeof(void*));
reinit_queue(& ftb->queue, res, 0, 0, reinit_queue(& ftb->queue, res, 0, 0,
@ -309,6 +322,7 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query,
return ftb; return ftb;
} }
/* returns 1 if str0 contain str1 */ /* returns 1 if str0 contain str1 */
int _ftb_strstr(const byte *s0, const byte *e0, int _ftb_strstr(const byte *s0, const byte *e0,
const byte *s1, const byte *e1, const byte *s1, const byte *e1,
@ -333,6 +347,7 @@ int _ftb_strstr(const byte *s0, const byte *e0,
return 0; return 0;
} }
void _ftb_climb_the_tree(FTB *ftb, FTB_WORD *ftbw, FT_SEG_ITERATOR *ftsi_orig) void _ftb_climb_the_tree(FTB *ftb, FTB_WORD *ftbw, FT_SEG_ITERATOR *ftsi_orig)
{ {
FT_SEG_ITERATOR ftsi; FT_SEG_ITERATOR ftsi;
@ -381,28 +396,31 @@ void _ftb_climb_the_tree(FTB *ftb, FTB_WORD *ftbw, FT_SEG_ITERATOR *ftsi_orig)
else else
if (yn & FTB_FLAG_NO) if (yn & FTB_FLAG_NO)
{ {
/* NOTE: special sort function of queue assures that all /*
* (yn & FTB_FLAG_NO) != 0 NOTE: special sort function of queue assures that all
* events for every particular subexpression will (yn & FTB_FLAG_NO) != 0
* "auto-magically" happen BEFORE all the events for every particular subexpression will
* (yn & FTB_FLAG_YES) != 0 events. So no "auto-magically" happen BEFORE all the
* already matched expression can become not-matched again. (yn & FTB_FLAG_YES) != 0 events. So no
already matched expression can become not-matched again.
*/ */
++ftbe->nos; ++ftbe->nos;
break; break;
} }
else else
{ {
if (ftbe->ythresh) weight/=3; if (ftbe->ythresh)
weight/=3;
ftbe->cur_weight += weight; ftbe->cur_weight += weight;
if (ftbe->yesses < ythresh) if (ftbe->yesses < ythresh)
break; break;
yn= (ftbe->yesses++ == ythresh) ? ftbe->flags : 0 ; yn= (ftbe->yesses++ == ythresh) ? ftbe->flags : 0 ;
weight*=ftbe->weight; weight*= ftbe->weight;
} }
} }
} }
int ft_boolean_read_next(FT_INFO *ftb, char *record) int ft_boolean_read_next(FT_INFO *ftb, char *record)
{ {
FTB_EXPR *ftbe; FTB_EXPR *ftbe;
@ -426,8 +444,9 @@ int ft_boolean_read_next(FT_INFO *ftb, char *record)
if (!ftb->queue.elements) if (!ftb->queue.elements)
return my_errno=HA_ERR_END_OF_FILE; return my_errno=HA_ERR_END_OF_FILE;
while(ftb->state == INDEX_SEARCH && while (ftb->state == INDEX_SEARCH &&
(curdoc=((FTB_WORD *)queue_top(& ftb->queue))->docid[0]) != HA_POS_ERROR) (curdoc=((FTB_WORD *)queue_top(& ftb->queue))->docid[0]) !=
HA_POS_ERROR)
{ {
while (curdoc==(ftbw=(FTB_WORD *)queue_top(& ftb->queue))->docid[0]) while (curdoc==(ftbw=(FTB_WORD *)queue_top(& ftb->queue))->docid[0])
{ {
@ -449,8 +468,11 @@ int ft_boolean_read_next(FT_INFO *ftb, char *record)
{ {
ftbw->docid[0]=HA_POS_ERROR; ftbw->docid[0]=HA_POS_ERROR;
if (ftbw->flags&FTB_FLAG_YES && ftbw->up->up==0) if (ftbw->flags&FTB_FLAG_YES && ftbw->up->up==0)
{ /* this word MUST BE present in every document returned, {
so we can stop the search right now */ /*
This word MUST BE present in every document returned,
so we can stop the search right now
*/
ftb->state=INDEX_DONE; ftb->state=INDEX_DONE;
} }
} }
@ -473,7 +495,7 @@ int ft_boolean_read_next(FT_INFO *ftb, char *record)
continue; continue;
info->lastpos=curdoc; info->lastpos=curdoc;
info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); /* why is this ? */ info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
if (!(*info->read_record)(info,curdoc,record)) if (!(*info->read_record)(info,curdoc,record))
{ {
@ -489,6 +511,7 @@ int ft_boolean_read_next(FT_INFO *ftb, char *record)
return my_errno=HA_ERR_END_OF_FILE; return my_errno=HA_ERR_END_OF_FILE;
} }
float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length) float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length)
{ {
FT_WORD word; FT_WORD word;
@ -555,6 +578,7 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length)
} }
} }
void ft_boolean_close_search(FT_INFO *ftb) void ft_boolean_close_search(FT_INFO *ftb)
{ {
if (is_tree_inited(& ftb->no_dupes)) if (is_tree_inited(& ftb->no_dupes))
@ -565,11 +589,13 @@ void ft_boolean_close_search(FT_INFO *ftb)
my_free((gptr)ftb,MYF(0)); my_free((gptr)ftb,MYF(0));
} }
float ft_boolean_get_relevance(FT_INFO *ftb) float ft_boolean_get_relevance(FT_INFO *ftb)
{ {
return ftb->root->cur_weight; return ftb->root->cur_weight;
} }
void ft_boolean_reinit_search(FT_INFO *ftb) void ft_boolean_reinit_search(FT_INFO *ftb)
{ {
_ftb_init_index_search(ftb); _ftb_init_index_search(ftb);

View file

@ -148,16 +148,16 @@ int main(int argc,char *argv[])
if (maxlen<keylen2) if (maxlen<keylen2)
{ {
maxlen=keylen2; maxlen=keylen2;
strcpy(buf_maxlen, buf2); strmov(buf_maxlen, buf2);
} }
if (max_doc_cnt < doc_cnt) if (max_doc_cnt < doc_cnt)
{ {
max_doc_cnt=doc_cnt; max_doc_cnt=doc_cnt;
strcpy(buf_min_gws, buf2); strmov(buf_min_gws, buf2);
min_gws=gws; min_gws=gws;
} }
} }
strcpy(buf2, buf); strmov(buf2, buf);
keylen2=keylen; keylen2=keylen;
doc_cnt=0; doc_cnt=0;
} }

View file

@ -79,7 +79,7 @@ int main(int argc, char *argv[])
my_errno=0; my_errno=0;
i=0; i=0;
while(create_record(record,df)) while (create_record(record,df))
{ {
error=mi_write(file,record); error=mi_write(file,record);
if (error) if (error)
@ -94,24 +94,28 @@ int main(int argc, char *argv[])
if (!(file=mi_open(filename,2,0))) goto err; if (!(file=mi_open(filename,2,0))) goto err;
if (!silent) if (!silent)
printf("- Reading rows with key\n"); printf("- Reading rows with key\n");
for(i=1;create_record(record,qf);i++) { for (i=1;create_record(record,qf);i++)
{
FT_DOCLIST *result; FT_DOCLIST *result;
double w; double w;
int t, err; int t, err;
result=ft_nlq_init_search(file,0,blob_record,(uint) strlen(blob_record),1); result=ft_nlq_init_search(file,0,blob_record,(uint) strlen(blob_record),1);
if(!result) { if (!result)
{
printf("Query %d failed with errno %3d\n",i,my_errno); printf("Query %d failed with errno %3d\n",i,my_errno);
goto err; goto err;
} }
if (!silent) if (!silent)
printf("Query %d. Found: %d.\n",i,result->ndocs); printf("Query %d. Found: %d.\n",i,result->ndocs);
for(j=0;(err=ft_nlq_read_next(result, read_record))==0;j++) { for (j=0;(err=ft_nlq_read_next(result, read_record))==0;j++)
{
t=uint2korr(read_record); t=uint2korr(read_record);
w=ft_nlq_get_relevance(result); w=ft_nlq_get_relevance(result);
printf("%d %.*s %f\n",i,t,read_record+2,w); printf("%d %.*s %f\n",i,t,read_record+2,w);
} }
if(err != HA_ERR_END_OF_FILE) { if (err != HA_ERR_END_OF_FILE)
{
printf("ft_read_next %d failed with errno %3d\n",j,my_errno); printf("ft_read_next %d failed with errno %3d\n",j,my_errno);
goto err; goto err;
} }
@ -134,24 +138,28 @@ static my_bool
get_one_option(int optid, const struct my_option *opt __attribute__((unused)), get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
char *argument) char *argument)
{ {
switch(optid) { switch (optid) {
case 's': case 's':
if(stopwordlist && stopwordlist!=ft_precompiled_stopwords) break; if (stopwordlist && stopwordlist != ft_precompiled_stopwords)
break;
{ {
FILE *f; char s[HA_FT_MAXLEN]; int i=0,n=SWL_INIT; FILE *f; char s[HA_FT_MAXLEN]; int i=0,n=SWL_INIT;
if(!(stopwordlist=(const char**) malloc(n*sizeof(char *)))) if (!(stopwordlist=(const char**) malloc(n*sizeof(char *))))
print_error(1,"malloc(%d)",n*sizeof(char *)); print_error(1,"malloc(%d)",n*sizeof(char *));
if(!(f=fopen(argument,"r"))) if (!(f=fopen(argument,"r")))
print_error(1,"fopen(%s)",argument); print_error(1,"fopen(%s)",argument);
while(!feof(f)) { while (!feof(f))
if(!(fgets(s,HA_FT_MAXLEN,f))) {
if (!(fgets(s,HA_FT_MAXLEN,f)))
print_error(1,"fgets(s,%d,%s)",HA_FT_MAXLEN,argument); print_error(1,"fgets(s,%d,%s)",HA_FT_MAXLEN,argument);
if(!(stopwordlist[i++]=strdup(s))) if (!(stopwordlist[i++]=strdup(s)))
print_error(1,"strdup(%s)",s); print_error(1,"strdup(%s)",s);
if(i>=n) { if (i >= n)
{
n+=SWL_PLUS; n+=SWL_PLUS;
if(!(stopwordlist=(const char**) realloc((char*) stopwordlist,n*sizeof(char *)))) if (!(stopwordlist=(const char**) realloc((char*) stopwordlist,
n*sizeof(char *))))
print_error(1,"realloc(%d)",n*sizeof(char *)); print_error(1,"realloc(%d)",n*sizeof(char *));
} }
} }
@ -160,7 +168,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
break; break;
} }
case 'q': silent=1; break; case 'q': silent=1; break;
case 'S': if(stopwordlist==ft_precompiled_stopwords) stopwordlist=NULL; break; case 'S': if (stopwordlist==ft_precompiled_stopwords) stopwordlist=NULL; break;
case '#': case '#':
DEBUGGER_ON; DEBUGGER_ON;
DBUG_PUSH (argument); DBUG_PUSH (argument);
@ -174,6 +182,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
return 0; return 0;
} }
static void get_options(int argc, char *argv[]) static void get_options(int argc, char *argv[])
{ {
int ho_error; int ho_error;
@ -181,24 +190,29 @@ static void get_options(int argc, char *argv[])
if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
exit(ho_error); exit(ho_error);
if(!(d_file=argv[optind])) print_error(1,"No d_file"); if (!(d_file=argv[optind])) print_error(1,"No d_file");
if(!(df=fopen(d_file,"r"))) if (!(df=fopen(d_file,"r")))
print_error(1,"fopen(%s)",d_file); print_error(1,"fopen(%s)",d_file);
if(!(q_file=argv[optind+1])) print_error(1,"No q_file"); if (!(q_file=argv[optind+1])) print_error(1,"No q_file");
if(!(qf=fopen(q_file,"r"))) if (!(qf=fopen(q_file,"r")))
print_error(1,"fopen(%s)",q_file); print_error(1,"fopen(%s)",q_file);
return; return;
} /* get options */ } /* get options */
static int create_record(char *pos, FILE *file) static int create_record(char *pos, FILE *file)
{ uint tmp; char *ptr; {
uint tmp; char *ptr;
bzero((char *)pos,MAX_REC_LENGTH); bzero((char *)pos,MAX_REC_LENGTH);
/* column 1 - VARCHAR */ /* column 1 - VARCHAR */
if(!(fgets(pos+2,MAX_REC_LENGTH-32,file))) if (!(fgets(pos+2,MAX_REC_LENGTH-32,file)))
{ {
if(feof(file)) return 0; else print_error(1,"fgets(docid) - 1"); if (feof(file))
return 0;
else
print_error(1,"fgets(docid) - 1");
} }
tmp=(uint) strlen(pos+2)-1; tmp=(uint) strlen(pos+2)-1;
int2store(pos,tmp); int2store(pos,tmp);
@ -206,7 +220,7 @@ static int create_record(char *pos, FILE *file)
/* column 2 - BLOB */ /* column 2 - BLOB */
if(!(fgets(blob_record,MAX_BLOB_LENGTH,file))) if (!(fgets(blob_record,MAX_BLOB_LENGTH,file)))
print_error(1,"fgets(docid) - 2"); print_error(1,"fgets(docid) - 2");
tmp=(uint) strlen(blob_record); tmp=(uint) strlen(blob_record);
int4store(pos,tmp); int4store(pos,tmp);

View file

@ -21,12 +21,14 @@
/* search with natural language queries */ /* search with natural language queries */
typedef struct ft_doc_rec { typedef struct ft_doc_rec
{
my_off_t dpos; my_off_t dpos;
double weight; double weight;
} FT_DOC; } FT_DOC;
struct st_ft_info { struct st_ft_info
{
struct _ft_vft *please; struct _ft_vft *please;
MI_INFO *info; MI_INFO *info;
int ndocs; int ndocs;
@ -34,7 +36,8 @@ struct st_ft_info {
FT_DOC doc[1]; FT_DOC doc[1];
}; };
typedef struct st_all_in_one { typedef struct st_all_in_one
{
MI_INFO *info; MI_INFO *info;
uint keynr; uint keynr;
CHARSET_INFO *charset; CHARSET_INFO *charset;
@ -44,7 +47,8 @@ typedef struct st_all_in_one {
TREE dtree; TREE dtree;
} ALL_IN_ONE; } ALL_IN_ONE;
typedef struct st_ft_superdoc { typedef struct st_ft_superdoc
{
FT_DOC doc; FT_DOC doc;
FT_WORD *word_ptr; FT_WORD *word_ptr;
double tmp_weight; double tmp_weight;
@ -92,7 +96,7 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
r=_mi_search(aio->info, aio->keyinfo, aio->keybuff, keylen, r=_mi_search(aio->info, aio->keyinfo, aio->keybuff, keylen,
SEARCH_FIND | SEARCH_PREFIX, aio->key_root); SEARCH_FIND | SEARCH_PREFIX, aio->key_root);
while(!r) while (!r)
{ {
if (_mi_compare_text(aio->charset, if (_mi_compare_text(aio->charset,
aio->info->lastkey,keylen, aio->info->lastkey,keylen,
@ -116,11 +120,12 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
sdoc.doc.dpos=aio->info->lastpos; sdoc.doc.dpos=aio->info->lastpos;
/* saving document matched into dtree */ /* saving document matched into dtree */
if(!(selem=tree_insert(&aio->dtree, &sdoc, 0))) return 1; if (!(selem=tree_insert(&aio->dtree, &sdoc, 0)))
return 1;
sptr=(FT_SUPERDOC *)ELEMENT_KEY((&aio->dtree), selem); sptr=(FT_SUPERDOC *)ELEMENT_KEY((&aio->dtree), selem);
if(selem->count==1) /* document's first match */ if (selem->count==1) /* document's first match */
sptr->doc.weight=0; sptr->doc.weight=0;
else else
sptr->doc.weight+=sptr->tmp_weight*sptr->word_ptr->weight; sptr->doc.weight+=sptr->tmp_weight*sptr->word_ptr->weight;
@ -144,31 +149,35 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
aio->info->lastkey_length, SEARCH_BIGGER, aio->info->lastkey_length, SEARCH_BIGGER,
aio->key_root); aio->key_root);
} }
if(doc_cnt) { if (doc_cnt)
{
word->weight*=GWS_IN_USE; word->weight*=GWS_IN_USE;
if(word->weight < 0) word->weight=0; if (word->weight < 0)
word->weight=0;
} }
return 0; return 0;
} }
static int walk_and_copy(FT_SUPERDOC *from, static int walk_and_copy(FT_SUPERDOC *from,
uint32 count __attribute__((unused)), FT_DOC **to) uint32 count __attribute__((unused)), FT_DOC **to)
{ {
from->doc.weight+=from->tmp_weight*from->word_ptr->weight; from->doc.weight+=from->tmp_weight*from->word_ptr->weight;
(*to)->dpos=from->doc.dpos; (*to)->dpos=from->doc.dpos;
(*to)->weight=from->doc.weight; (*to)->weight=from->doc.weight;
(*to)++; (*to)++;
return 0; return 0;
} }
static int FT_DOC_cmp(FT_DOC *a, FT_DOC *b) static int FT_DOC_cmp(FT_DOC *a, FT_DOC *b)
{ {
return sgn(b->weight - a->weight); return sgn(b->weight - a->weight);
} }
FT_INFO *ft_init_nlq_search(MI_INFO *info, uint keynr, byte *query, FT_INFO *ft_init_nlq_search(MI_INFO *info, uint keynr, byte *query,
uint query_len, my_bool presort) uint query_len, my_bool presort)
{ {
TREE allocated_wtree, *wtree=&allocated_wtree; TREE allocated_wtree, *wtree=&allocated_wtree;
ALL_IN_ONE aio; ALL_IN_ONE aio;
@ -196,15 +205,16 @@ FT_INFO *ft_init_nlq_search(MI_INFO *info, uint keynr, byte *query,
NULL, NULL); NULL, NULL);
ft_parse_init(&allocated_wtree, aio.charset); ft_parse_init(&allocated_wtree, aio.charset);
if(ft_parse(&allocated_wtree,query,query_len)) if (ft_parse(&allocated_wtree,query,query_len))
goto err; goto err;
if(tree_walk(wtree, (tree_walk_action)&walk_and_match, &aio, if (tree_walk(wtree, (tree_walk_action)&walk_and_match, &aio,
left_root_right)) left_root_right))
goto err2; goto err2;
dlist=(FT_INFO *)my_malloc(sizeof(FT_INFO)+ dlist=(FT_INFO *)my_malloc(sizeof(FT_INFO)+
sizeof(FT_DOC)*(aio.dtree.elements_in_tree-1),MYF(0)); sizeof(FT_DOC)*(aio.dtree.elements_in_tree-1),
MYF(0));
if(!dlist) if(!dlist)
goto err2; goto err2;
@ -214,10 +224,10 @@ FT_INFO *ft_init_nlq_search(MI_INFO *info, uint keynr, byte *query,
dlist->info=aio.info; dlist->info=aio.info;
dptr=dlist->doc; dptr=dlist->doc;
tree_walk(&aio.dtree, (tree_walk_action)&walk_and_copy, tree_walk(&aio.dtree, (tree_walk_action) &walk_and_copy,
&dptr, left_root_right); &dptr, left_root_right);
if(presort) if (presort)
qsort(dlist->doc, dlist->ndocs, sizeof(FT_DOC), (qsort_cmp)&FT_DOC_cmp); qsort(dlist->doc, dlist->ndocs, sizeof(FT_DOC), (qsort_cmp)&FT_DOC_cmp);
err2: err2:
@ -229,6 +239,7 @@ err:
return dlist; return dlist;
} }
int ft_nlq_read_next(FT_INFO *handler, char *record) int ft_nlq_read_next(FT_INFO *handler, char *record)
{ {
MI_INFO *info= (MI_INFO *) handler->info; MI_INFO *info= (MI_INFO *) handler->info;
@ -250,6 +261,7 @@ int ft_nlq_read_next(FT_INFO *handler, char *record)
return my_errno; return my_errno;
} }
float ft_nlq_find_relevance(FT_INFO *handler, float ft_nlq_find_relevance(FT_INFO *handler,
byte *record __attribute__((unused)), byte *record __attribute__((unused)),
uint length __attribute__((unused))) uint length __attribute__((unused)))
@ -276,16 +288,19 @@ float ft_nlq_find_relevance(FT_INFO *handler,
return 0.0; return 0.0;
} }
void ft_nlq_close_search(FT_INFO *handler) void ft_nlq_close_search(FT_INFO *handler)
{ {
my_free((gptr)handler,MYF(0)); my_free((gptr)handler,MYF(0));
} }
float ft_nlq_get_relevance(FT_INFO *handler) float ft_nlq_get_relevance(FT_INFO *handler)
{ {
return (float) handler->doc[handler->curdoc].weight; return (float) handler->doc[handler->curdoc].weight;
} }
void ft_nlq_reinit_search(FT_INFO *handler) void ft_nlq_reinit_search(FT_INFO *handler)
{ {
handler->curdoc=-1; handler->curdoc=-1;

View file

@ -205,7 +205,7 @@ void create_record(char *pos, int n)
{ {
uint tmp; uint tmp;
char *ptr; char *ptr;
strncpy(blob_key,data[n].f0,keyinfo[0].seg[0].length); strnmov(blob_key,data[n].f0,keyinfo[0].seg[0].length);
tmp=strlen(blob_key); tmp=strlen(blob_key);
int4store(pos,tmp); int4store(pos,tmp);
ptr=blob_key; ptr=blob_key;
@ -215,21 +215,21 @@ void create_record(char *pos, int n)
else if (recinfo[0].type == FIELD_VARCHAR) else if (recinfo[0].type == FIELD_VARCHAR)
{ {
uint tmp; uint tmp;
strncpy(pos+2,data[n].f0,keyinfo[0].seg[0].length); strnmov(pos+2,data[n].f0,keyinfo[0].seg[0].length);
tmp=strlen(pos+2); tmp=strlen(pos+2);
int2store(pos,tmp); int2store(pos,tmp);
pos+=recinfo[0].length; pos+=recinfo[0].length;
} }
else else
{ {
strncpy(pos,data[n].f0,keyinfo[0].seg[0].length); strnmov(pos,data[n].f0,keyinfo[0].seg[0].length);
pos+=recinfo[0].length; pos+=recinfo[0].length;
} }
if (recinfo[1].type == FIELD_BLOB) if (recinfo[1].type == FIELD_BLOB)
{ {
uint tmp; uint tmp;
char *ptr; char *ptr;
strncpy(blob_key,data[n].f2,keyinfo[0].seg[0].length); strnmov(blob_key,data[n].f2,keyinfo[0].seg[0].length);
tmp=strlen(blob_key); tmp=strlen(blob_key);
int4store(pos,tmp); int4store(pos,tmp);
ptr=blob_key; ptr=blob_key;
@ -239,14 +239,14 @@ void create_record(char *pos, int n)
else if (recinfo[1].type == FIELD_VARCHAR) else if (recinfo[1].type == FIELD_VARCHAR)
{ {
uint tmp; uint tmp;
strncpy(pos+2,data[n].f2,keyinfo[0].seg[0].length); strnmov(pos+2,data[n].f2,keyinfo[0].seg[0].length);
tmp=strlen(pos+2); tmp=strlen(pos+2);
int2store(pos,tmp); int2store(pos,tmp);
pos+=recinfo[1].length; pos+=recinfo[1].length;
} }
else else
{ {
strncpy(pos,data[n].f2,keyinfo[0].seg[0].length); strnmov(pos,data[n].f2,keyinfo[0].seg[0].length);
pos+=recinfo[1].length; pos+=recinfo[1].length;
} }
} }

View file

@ -29,7 +29,7 @@
/**************************************************************/ /**************************************************************/
void _mi_ft_segiterator_init(MI_INFO *info, uint keynr, const byte *record, void _mi_ft_segiterator_init(MI_INFO *info, uint keynr, const byte *record,
FT_SEG_ITERATOR *ftsi) FT_SEG_ITERATOR *ftsi)
{ {
ftsi->num=info->s->keyinfo[keynr].keysegs-FT_SEGS; ftsi->num=info->s->keyinfo[keynr].keysegs-FT_SEGS;
ftsi->seg=info->s->keyinfo[keynr].seg; ftsi->seg=info->s->keyinfo[keynr].seg;
@ -37,7 +37,7 @@ void _mi_ft_segiterator_init(MI_INFO *info, uint keynr, const byte *record,
} }
void _mi_ft_segiterator_dummy_init(const byte *record, uint len, void _mi_ft_segiterator_dummy_init(const byte *record, uint len,
FT_SEG_ITERATOR *ftsi) FT_SEG_ITERATOR *ftsi)
{ {
ftsi->num=1; ftsi->num=1;
ftsi->seg=0; ftsi->seg=0;
@ -45,12 +45,13 @@ void _mi_ft_segiterator_dummy_init(const byte *record, uint len,
ftsi->len=len; ftsi->len=len;
} }
/* This function breaks convention "return 0 in success" /*
but it's easier to use like this This function breaks convention "return 0 in success"
but it's easier to use like this
while(_mi_ft_segiterator()) while(_mi_ft_segiterator())
so "1" means "OK", "0" means "EOF" so "1" means "OK", "0" means "EOF"
*/ */
uint _mi_ft_segiterator(register FT_SEG_ITERATOR *ftsi) uint _mi_ft_segiterator(register FT_SEG_ITERATOR *ftsi)
@ -68,7 +69,7 @@ uint _mi_ft_segiterator(register FT_SEG_ITERATOR *ftsi)
if (ftsi->seg->flag & HA_VAR_LENGTH) if (ftsi->seg->flag & HA_VAR_LENGTH)
{ {
ftsi->len=uint2korr(ftsi->pos); ftsi->len=uint2korr(ftsi->pos);
ftsi->pos+=2; /* Skip VARCHAR length */ ftsi->pos+=2; /* Skip VARCHAR length */
set_if_smaller(ftsi->len,ftsi->seg->length); set_if_smaller(ftsi->len,ftsi->seg->length);
return 1; return 1;
} }
@ -84,7 +85,9 @@ uint _mi_ft_segiterator(register FT_SEG_ITERATOR *ftsi)
return 1; return 1;
} }
/* parses a document i.e. calls ft_parse for every keyseg */ /* parses a document i.e. calls ft_parse for every keyseg */
uint _mi_ft_parse(TREE *parsed, MI_INFO *info, uint keynr, const byte *record) uint _mi_ft_parse(TREE *parsed, MI_INFO *info, uint keynr, const byte *record)
{ {
FT_SEG_ITERATOR ftsi; FT_SEG_ITERATOR ftsi;
@ -92,10 +95,11 @@ uint _mi_ft_parse(TREE *parsed, MI_INFO *info, uint keynr, const byte *record)
ft_parse_init(parsed, info->s->keyinfo[keynr].seg->charset); ft_parse_init(parsed, info->s->keyinfo[keynr].seg->charset);
while (_mi_ft_segiterator(&ftsi)) while (_mi_ft_segiterator(&ftsi))
{
if (ftsi.pos) if (ftsi.pos)
if (ft_parse(parsed, (byte *)ftsi.pos, ftsi.len)) if (ft_parse(parsed, (byte *)ftsi.pos, ftsi.len))
return 1; return 1;
}
return 0; return 0;
} }
@ -117,32 +121,33 @@ static int _mi_ft_store(MI_INFO *info, uint keynr, byte *keybuf,
{ {
uint key_length; uint key_length;
while(wlist->pos) for (; wlist->pos; wlist++)
{ {
key_length=_ft_make_key(info,keynr,keybuf,wlist,filepos); key_length=_ft_make_key(info,keynr,keybuf,wlist,filepos);
if (_mi_ck_write(info,keynr,(uchar*) keybuf,key_length)) if (_mi_ck_write(info,keynr,(uchar*) keybuf,key_length))
return 1; return 1;
wlist++;
} }
return 0; return 0;
} }
static int _mi_ft_erase(MI_INFO *info, uint keynr, byte *keybuf, FT_WORD *wlist, my_off_t filepos) static int _mi_ft_erase(MI_INFO *info, uint keynr, byte *keybuf,
FT_WORD *wlist, my_off_t filepos)
{ {
uint key_length, err=0; uint key_length, err=0;
while(wlist->pos) for (; wlist->pos; wlist++)
{ {
key_length=_ft_make_key(info,keynr,keybuf,wlist,filepos); key_length=_ft_make_key(info,keynr,keybuf,wlist,filepos);
if (_mi_ck_delete(info,keynr,(uchar*) keybuf,key_length)) if (_mi_ck_delete(info,keynr,(uchar*) keybuf,key_length))
err=1; err=1;
wlist++;
} }
return err; return err;
} }
/* compares an appropriate parts of two WORD_KEY keys directly out of records */ /*
/* returns 1 if they are different */ Compares an appropriate parts of two WORD_KEY keys directly out of records
returns 1 if they are different
*/
#define THOSE_TWO_DAMN_KEYS_ARE_REALLY_DIFFERENT 1 #define THOSE_TWO_DAMN_KEYS_ARE_REALLY_DIFFERENT 1
#define GEE_THEY_ARE_ABSOLUTELY_IDENTICAL 0 #define GEE_THEY_ARE_ABSOLUTELY_IDENTICAL 0
@ -154,7 +159,7 @@ int _mi_ft_cmp(MI_INFO *info, uint keynr, const byte *rec1, const byte *rec2)
_mi_ft_segiterator_init(info, keynr, rec1, &ftsi1); _mi_ft_segiterator_init(info, keynr, rec1, &ftsi1);
_mi_ft_segiterator_init(info, keynr, rec2, &ftsi2); _mi_ft_segiterator_init(info, keynr, rec2, &ftsi2);
while(_mi_ft_segiterator(&ftsi1) && _mi_ft_segiterator(&ftsi2)) while (_mi_ft_segiterator(&ftsi1) && _mi_ft_segiterator(&ftsi2))
{ {
if ((ftsi1.pos != ftsi2.pos) && if ((ftsi1.pos != ftsi2.pos) &&
(!ftsi1.pos || !ftsi2.pos || (!ftsi1.pos || !ftsi2.pos ||
@ -165,7 +170,9 @@ int _mi_ft_cmp(MI_INFO *info, uint keynr, const byte *rec1, const byte *rec2)
return GEE_THEY_ARE_ABSOLUTELY_IDENTICAL; return GEE_THEY_ARE_ABSOLUTELY_IDENTICAL;
} }
/* update a document entry */ /* update a document entry */
int _mi_ft_update(MI_INFO *info, uint keynr, byte *keybuf, int _mi_ft_update(MI_INFO *info, uint keynr, byte *keybuf,
const byte *oldrec, const byte *newrec, my_off_t pos) const byte *oldrec, const byte *newrec, my_off_t pos)
{ {
@ -215,7 +222,9 @@ err0:
return error; return error;
} }
/* adds a document to the collection */ /* adds a document to the collection */
int _mi_ft_add(MI_INFO *info, uint keynr, byte *keybuf, const byte *record, int _mi_ft_add(MI_INFO *info, uint keynr, byte *keybuf, const byte *record,
my_off_t pos) my_off_t pos)
{ {
@ -230,7 +239,9 @@ int _mi_ft_add(MI_INFO *info, uint keynr, byte *keybuf, const byte *record,
return error; return error;
} }
/* removes a document from the collection */ /* removes a document from the collection */
int _mi_ft_del(MI_INFO *info, uint keynr, byte *keybuf, const byte *record, int _mi_ft_del(MI_INFO *info, uint keynr, byte *keybuf, const byte *record,
my_off_t pos) my_off_t pos)
{ {

View file

@ -42,8 +42,10 @@ my_off_t myisam_max_extra_temp_length= MI_MAX_TEMP_LENGTH;
my_off_t myisam_max_temp_length= MAX_FILE_SIZE; my_off_t myisam_max_temp_length= MAX_FILE_SIZE;
ulong myisam_bulk_insert_tree_size=8192*1024; ulong myisam_bulk_insert_tree_size=8192*1024;
/* read_vec[] is used for converting between P_READ_KEY.. and SEARCH_ */ /*
/* Position is , == , >= , <= , > , < */ read_vec[] is used for converting between P_READ_KEY.. and SEARCH_
Position is , == , >= , <= , > , <
*/
uint NEAR myisam_read_vec[]= uint NEAR myisam_read_vec[]=
{ {

View file

@ -341,13 +341,19 @@ int main(int argc, char *argv[])
} }
} }
} }
if (testflag==3) goto end; if (testflag == 3)
goto end;
for (i=999, dupp_keys=j=0 ; i>0 ; i--) for (i=999, dupp_keys=j=0 ; i>0 ; i--)
{ {
if (key1[i] > dupp_keys) { dupp_keys=key1[i]; j=i; } if (key1[i] > dupp_keys)
{
dupp_keys=key1[i]; j=i;
}
} }
sprintf(key,"%6d",j); sprintf(key,"%6d",j);
start=keyinfo[0].seg[0].start;
length=keyinfo[0].seg[0].length;
if (dupp_keys) if (dupp_keys)
{ {
if (!silent) if (!silent)
@ -355,8 +361,10 @@ int main(int argc, char *argv[])
DBUG_PRINT("progpos",("first - next -> last - prev -> first")); DBUG_PRINT("progpos",("first - next -> last - prev -> first"));
if (verbose) printf(" Using key: \"%s\" Keys: %d\n",key,dupp_keys); if (verbose) printf(" Using key: \"%s\" Keys: %d\n",key,dupp_keys);
if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT)) goto err; if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT))
if (mi_rsame(file,read_record2,-1)) goto err; goto err;
if (mi_rsame(file,read_record2,-1))
goto err;
if (memcmp(read_record,read_record2,reclength) != 0) if (memcmp(read_record,read_record2,reclength) != 0)
{ {
printf("mi_rsame didn't find same record\n"); printf("mi_rsame didn't find same record\n");
@ -381,7 +389,6 @@ int main(int argc, char *argv[])
} }
} }
ant=1; ant=1;
start=keyinfo[0].seg[0].start; length=keyinfo[0].seg[0].length;
while (mi_rnext(file,read_record2,0) == 0 && while (mi_rnext(file,read_record2,0) == 0 &&
memcmp(read_record2+start,key,length) == 0) ant++; memcmp(read_record2+start,key,length) == 0) ant++;
if (ant != dupp_keys) if (ant != dupp_keys)

View file

@ -103,7 +103,7 @@ int mi_write(MI_INFO *info, byte *record)
{ {
bool local_lock_tree= (lock_tree && bool local_lock_tree= (lock_tree &&
!(info->bulk_insert && !(info->bulk_insert &&
is_tree_inited(& info->bulk_insert[i]))); is_tree_inited(&info->bulk_insert[i])));
if (local_lock_tree) if (local_lock_tree)
{ {
rw_wrlock(&share->key_root_lock[i]); rw_wrlock(&share->key_root_lock[i]);
@ -168,9 +168,9 @@ err:
uint j; uint j;
for (j=0 ; j < share->base.keys ; j++) for (j=0 ; j < share->base.keys ; j++)
{ {
if (is_tree_inited(& info->bulk_insert[j])) if (is_tree_inited(&info->bulk_insert[j]))
{ {
reset_tree(& info->bulk_insert[j]); reset_tree(&info->bulk_insert[j]);
} }
} }
} }
@ -181,7 +181,7 @@ err:
{ {
bool local_lock_tree= (lock_tree && bool local_lock_tree= (lock_tree &&
!(info->bulk_insert && !(info->bulk_insert &&
is_tree_inited(& info->bulk_insert[i]))); is_tree_inited(&info->bulk_insert[i])));
if (local_lock_tree) if (local_lock_tree)
rw_wrlock(&share->key_root_lock[i]); rw_wrlock(&share->key_root_lock[i]);
if (share->keyinfo[i].flag & HA_FULLTEXT) if (share->keyinfo[i].flag & HA_FULLTEXT)
@ -227,7 +227,7 @@ int _mi_ck_write(MI_INFO *info, uint keynr, uchar *key, uint key_length)
{ {
DBUG_ENTER("_mi_ck_write"); DBUG_ENTER("_mi_ck_write");
if (info->bulk_insert && is_tree_inited(& info->bulk_insert[keynr])) if (info->bulk_insert && is_tree_inited(&info->bulk_insert[keynr]))
{ {
DBUG_RETURN(_mi_ck_write_tree(info, keynr, key, key_length)); DBUG_RETURN(_mi_ck_write_tree(info, keynr, key, key_length));
} }
@ -750,7 +750,7 @@ int _mi_ck_write_tree(register MI_INFO *info, uint keynr, uchar *key,
int error; int error;
DBUG_ENTER("_mi_ck_write_tree"); DBUG_ENTER("_mi_ck_write_tree");
error= tree_insert(& info->bulk_insert[keynr], key, error= tree_insert(&info->bulk_insert[keynr], key,
key_length + info->s->rec_reflength) ? 0 : HA_ERR_OUT_OF_MEM ; key_length + info->s->rec_reflength) ? 0 : HA_ERR_OUT_OF_MEM ;
DBUG_RETURN(error); DBUG_RETURN(error);

View file

@ -14,16 +14,16 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Returnerar en pekare till filnamnets extension. */
#include "mysys_priv.h" #include "mysys_priv.h"
#include <m_string.h> #include <m_string.h>
/* Return a pointerto the extension of the filename /*
The pointer points at the extension character (normally '.')) Return a pointerto the extension of the filename
If there isn't any extension, the pointer points at the end The pointer points at the extension character (normally '.'))
NULL of the filename If there isn't any extension, the pointer points at the end
*/ ASCII(0) of the filename.
*/
my_string fn_ext(const char *name) my_string fn_ext(const char *name)
{ {

View file

@ -73,11 +73,12 @@ init_functions(IO_CACHE* info, enum cache_type type)
{ {
switch (type) { switch (type) {
case READ_NET: case READ_NET:
/* must be initialized by the caller. The problem is that /*
_my_b_net_read has to be defined in sql directory because of Must be initialized by the caller. The problem is that
the dependency on THD, and therefore cannot be visible to _my_b_net_read has to be defined in sql directory because of
programs that link against mysys but know nothing about THD, such the dependency on THD, and therefore cannot be visible to
as myisamchk programs that link against mysys but know nothing about THD, such
as myisamchk
*/ */
break; break;
case SEQ_READ_APPEND: case SEQ_READ_APPEND:

View file

@ -27,32 +27,36 @@
my_off_t my_b_append_tell(IO_CACHE* info) my_off_t my_b_append_tell(IO_CACHE* info)
{ {
/* prevent optimizer from putting res in a register when debugging /*
we need this to be able to see the value of res when the assert fails Prevent optimizer from putting res in a register when debugging
we need this to be able to see the value of res when the assert fails
*/ */
dbug_volatile my_off_t res; dbug_volatile my_off_t res;
/* we need to lock the append buffer mutex to keep flush_io_cache()
from messing with the variables that we need in order to provide the /*
answer to the question. We need to lock the append buffer mutex to keep flush_io_cache()
*/ from messing with the variables that we need in order to provide the
answer to the question.
*/
#ifdef THREAD #ifdef THREAD
pthread_mutex_lock(&info->append_buffer_lock); pthread_mutex_lock(&info->append_buffer_lock);
#endif #endif
/* save the value of my_tell in res so we can see it when studying
coredump
*/
#ifndef DBUG_OFF #ifndef DBUG_OFF
/* make sure EOF is where we think it is. Note that we cannot just use /*
my_tell() because we have a reader thread that could have left the Make sure EOF is where we think it is. Note that we cannot just use
file offset in a non-EOF location my_tell() because we have a reader thread that could have left the
*/ file offset in a non-EOF location
*/
{ {
volatile my_off_t save_pos; volatile my_off_t save_pos;
save_pos = my_tell(info->file,MYF(0)); save_pos = my_tell(info->file,MYF(0));
my_seek(info->file,(my_off_t)0,MY_SEEK_END,MYF(0)); my_seek(info->file,(my_off_t)0,MY_SEEK_END,MYF(0));
DBUG_ASSERT(info->end_of_file - (info->append_read_pos-info->write_buffer) /*
== (res=my_tell(info->file,MYF(0)))); Save the value of my_tell in res so we can see it when studying coredump
my_seek(info->file,save_pos,MY_SEEK_SET,MYF(0)); */
DBUG_ASSERT(info->end_of_file - (info->append_read_pos-info->write_buffer)
== (res=my_tell(info->file,MYF(0))));
my_seek(info->file,save_pos,MY_SEEK_SET,MYF(0));
} }
#endif #endif
res = info->end_of_file + (info->write_pos-info->append_read_pos); res = info->end_of_file + (info->write_pos-info->append_read_pos);
@ -74,10 +78,9 @@ void my_b_seek(IO_CACHE *info,my_off_t pos)
DBUG_PRINT("enter",("pos: %lu", (ulong) pos)); DBUG_PRINT("enter",("pos: %lu", (ulong) pos));
/* /*
TODO: verify that it is OK to do seek in the non-append TODO:
area in SEQ_READ_APPEND cache Verify that it is OK to do seek in the non-append
*/ area in SEQ_READ_APPEND cache
/* TODO:
a) see if this always works a) see if this always works
b) see if there is a better way to make it work b) see if there is a better way to make it work
*/ */

View file

@ -22,17 +22,17 @@
#include <my_sys.h> #include <my_sys.h>
#include <mysys_err.h> #include <mysys_err.h>
static int findopt (char *optpat, uint length, static int findopt(char *optpat, uint length,
const struct my_option **opt_res, const struct my_option **opt_res,
char **ffname); char **ffname);
static my_bool compare_strings (register const char *s, register const char *t, static my_bool compare_strings(register const char *s, register const char *t,
uint length); uint length);
static longlong getopt_ll (char *arg, const struct my_option *optp, int *err); static longlong getopt_ll(char *arg, const struct my_option *optp, int *err);
static ulonglong getopt_ull (char *arg, const struct my_option *optp, static ulonglong getopt_ull(char *arg, const struct my_option *optp,
int *err); int *err);
static void init_variables(const struct my_option *options); static void init_variables(const struct my_option *options);
static int setval (const struct my_option *opts, char *argument, static int setval(const struct my_option *opts, char *argument,
my_bool set_maximum_value); my_bool set_maximum_value);
/* /*
The following three variables belong to same group and the number and The following three variables belong to same group and the number and
@ -42,8 +42,8 @@ static const char *special_opt_prefix[]=
{"skip", "disable", "enable", "maximum", "loose", 0}; {"skip", "disable", "enable", "maximum", "loose", 0};
static const uint special_opt_prefix_lengths[]= static const uint special_opt_prefix_lengths[]=
{ 4, 7, 6, 7, 5, 0}; { 4, 7, 6, 7, 5, 0};
enum enum_special_opt { OPT_SKIP, OPT_DISABLE, OPT_ENABLE, OPT_MAXIMUM, enum enum_special_opt
OPT_LOOSE}; { OPT_SKIP, OPT_DISABLE, OPT_ENABLE, OPT_MAXIMUM, OPT_LOOSE};
char *disabled_my_option= (char*) "0"; char *disabled_my_option= (char*) "0";
@ -74,7 +74,7 @@ int handle_options(int *argc, char ***argv,
{ {
uint opt_found, argvpos= 0, length, i; uint opt_found, argvpos= 0, length, i;
my_bool end_of_options= 0, must_be_var, set_maximum_value, special_used, my_bool end_of_options= 0, must_be_var, set_maximum_value, special_used,
option_is_loose, option_used= 0; option_is_loose;
char *progname= *(*argv), **pos, *optend, *prev_found; char *progname= *(*argv), **pos, *optend, *prev_found;
const struct my_option *optp; const struct my_option *optp;
int error; int error;
@ -90,7 +90,6 @@ int handle_options(int *argc, char ***argv,
if (cur_arg[0] == '-' && cur_arg[1] && !end_of_options) /* must be opt */ if (cur_arg[0] == '-' && cur_arg[1] && !end_of_options) /* must be opt */
{ {
char *argument= 0; char *argument= 0;
option_used= 1;
must_be_var= 0; must_be_var= 0;
set_maximum_value= 0; set_maximum_value= 0;
special_used= 0; special_used= 0;
@ -406,12 +405,13 @@ int handle_options(int *argc, char ***argv,
else /* non-option found */ else /* non-option found */
(*argv)[argvpos++]= cur_arg; (*argv)[argvpos++]= cur_arg;
} }
/* Destroy the first, already handled option, so that programs that look /*
for arguments in 'argv', without checking 'argc', know when to stop. Destroy the first, already handled option, so that programs that look
Items in argv, before the destroyed one, are all non-option -arguments for arguments in 'argv', without checking 'argc', know when to stop.
to the program, yet to be (possibly) handled. */ Items in argv, before the destroyed one, are all non-option -arguments
if (option_used) to the program, yet to be (possibly) handled.
(*argv)[argvpos]= 0; */
(*argv)[argvpos]= 0;
return 0; return 0;
} }
@ -429,8 +429,8 @@ static int setval (const struct my_option *opts, char *argument,
if (opts->value && argument) if (opts->value && argument)
{ {
gptr *result_pos= (set_maximum_value) ? gptr *result_pos= ((set_maximum_value) ?
opts->u_max_value : opts->value; opts->u_max_value : opts->value);
if (!result_pos) if (!result_pos)
return EXIT_NO_PTR_TO_VARIABLE; return EXIT_NO_PTR_TO_VARIABLE;

View file

@ -19,13 +19,22 @@
#include <errno.h> #include <errno.h>
/* Read a chunk of bytes from a file */ /*
Read a chunk of bytes from a file with retry's if needed
The parameters are:
File descriptor
Buffer to hold at least Count bytes
Bytes to read
Flags on what to do on error
Return:
-1 on error
0 if flag has bits MY_NABP or MY_FNABP set
N number of bytes read.
*/
uint my_read(File Filedes, byte *Buffer, uint Count, myf MyFlags) uint my_read(File Filedes, byte *Buffer, uint Count, myf MyFlags)
/* File descriptor */
/* Buffer must be at least count bytes */
/* Max number of bytes returnd */
/* Flags on what to do on error */
{ {
uint readbytes,save_count; uint readbytes,save_count;
DBUG_ENTER("my_read"); DBUG_ENTER("my_read");

View file

@ -15,8 +15,8 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* /*
** Functions to handle initializating and allocationg of all mysys & debug Functions to handle initializating and allocationg of all mysys & debug
** thread variables. thread variables.
*/ */
#include "mysys_priv.h" #include "mysys_priv.h"
@ -44,10 +44,6 @@ pthread_mutexattr_t my_fast_mutexattr;
pthread_mutexattr_t my_errchk_mutexattr; pthread_mutexattr_t my_errchk_mutexattr;
#endif #endif
/* FIXME Note. TlsAlloc does not set an auto destructor, so
the function my_thread_global_free must be called from
somewhere before final exit of the library */
my_bool my_thread_global_init(void) my_bool my_thread_global_init(void)
{ {
if (pthread_key_create(&THR_KEY_mysys,free)) if (pthread_key_create(&THR_KEY_mysys,free))
@ -86,6 +82,7 @@ my_bool my_thread_global_init(void)
return my_thread_init(); return my_thread_init();
} }
void my_thread_global_end(void) void my_thread_global_end(void)
{ {
#if defined(USE_TLS) #if defined(USE_TLS)
@ -158,6 +155,7 @@ end:
return error; return error;
} }
void my_thread_end(void) void my_thread_end(void)
{ {
struct st_my_thread_var *tmp=my_thread_var; struct st_my_thread_var *tmp=my_thread_var;
@ -204,8 +202,9 @@ struct st_my_thread_var *_my_thread_var(void)
return tmp; return tmp;
} }
/**************************************************************************** /****************************************************************************
** Get name of current thread. Get name of current thread.
****************************************************************************/ ****************************************************************************/
#define UNKNOWN_THREAD -1 #define UNKNOWN_THREAD -1

View file

@ -173,11 +173,13 @@ static int queue_fix_cmp(QUEUE *queue, void **a, void **b)
(char*) (*b)+queue->offset_to_key); (char*) (*b)+queue->offset_to_key);
} }
/* Fix heap when every element was changed /*
actually, it can be done in linear time, Fix heap when every element was changed
not in n*log(n), but some code (myisam/ft_boolean_search.c) actually, it can be done in linear time,
requires a strict order here, not just a queue property not in n*log(n), but some code (myisam/ft_boolean_search.c)
requires a strict order here, not just a queue property
*/ */
void queue_fix(QUEUE *queue) void queue_fix(QUEUE *queue)
{ {
qsort2(queue->root+1,queue->elements, sizeof(void *), qsort2(queue->root+1,queue->elements, sizeof(void *),

View file

@ -14,54 +14,51 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
* [This posting refers to an article entitled "oops, corrupted memory
* again!" in net.lang.c. I am posting it here because it is source.]
*
* My tool for approaching this problem is to build another level of data
* abstraction on top of malloc() and free() that implements some checking.
* This does a number of things for you:
* - Checks for overruns and underruns on allocated data
* - Keeps track of where in the program the memory was malloc'ed
* - Reports on pieces of memory that were not free'ed
* - Records some statistics such as maximum memory used
* - Marks newly malloc'ed and newly free'ed memory with special values
* You can use this scheme to:
* - Find bugs such as overrun, underrun, etc because you know where
* a piece of data was malloc'ed and where it was free'ed
* - Find bugs where memory was not free'ed
* - Find bugs where newly malloc'ed memory is used without initializing
* - Find bugs where newly free'ed memory is still used
* - Determine how much memory your program really uses
* - and other things
*/
/*
* To implement my scheme you must have a C compiler that has __LINE__ and
* __FILE__ macros. If your compiler doesn't have these then (a) buy another:
* compilers that do are available on UNIX 4.2bsd based systems and the PC,
* and probably on other machines; or (b) change my scheme somehow. I have
* recomendations on both these points if you would like them (e-mail please).
*
* There are 4 functions in my package:
* char *NEW( uSize ) Allocate memory of uSize bytes
* (equivalent to malloc())
* char *REA( pPtr, uSize) Allocate memory of uSize bytes, move data and
* free pPtr.
* (equivalent to realloc())
* FREE( pPtr ) Free memory allocated by NEW
* (equivalent to free())
* TERMINATE(file) End system, report errors and stats on file
* I personally use two more functions, but have not included them here:
* char *STRSAVE( sPtr ) Save a copy of the string in dynamic memory
* char *RENEW( pPtr, uSize )
* (equivalent to realloc())
*/
/* /*
* Memory sub-system, written by Bjorn Benson * Memory sub-system, written by Bjorn Benson
Fixed to use my_sys scheme by Michael Widenius Fixed to use my_sys scheme by Michael Widenius
*/
[This posting refers to an article entitled "oops, corrupted memory
again!" in net.lang.c. I am posting it here because it is source.]
My tool for approaching this problem is to build another level of data
abstraction on top of malloc() and free() that implements some checking.
This does a number of things for you:
- Checks for overruns and underruns on allocated data
- Keeps track of where in the program the memory was malloc'ed
- Reports on pieces of memory that were not free'ed
- Records some statistics such as maximum memory used
- Marks newly malloc'ed and newly free'ed memory with special values
You can use this scheme to:
- Find bugs such as overrun, underrun, etc because you know where
a piece of data was malloc'ed and where it was free'ed
- Find bugs where memory was not free'ed
- Find bugs where newly malloc'ed memory is used without initializing
- Find bugs where newly free'ed memory is still used
- Determine how much memory your program really uses
- and other things
To implement my scheme you must have a C compiler that has __LINE__ and
__FILE__ macros. If your compiler doesn't have these then (a) buy another:
compilers that do are available on UNIX 4.2bsd based systems and the PC,
and probably on other machines; or (b) change my scheme somehow. I have
recomendations on both these points if you would like them (e-mail please).
There are 4 functions in my package:
char *NEW( uSize ) Allocate memory of uSize bytes
(equivalent to malloc())
char *REA( pPtr, uSize) Allocate memory of uSize bytes, move data and
free pPtr.
(equivalent to realloc())
FREE( pPtr ) Free memory allocated by NEW
(equivalent to free())
TERMINATE(file) End system, report errors and stats on file
I personally use two more functions, but have not included them here:
char *STRSAVE( sPtr ) Save a copy of the string in dynamic memory
char *RENEW( pPtr, uSize )
(equivalent to realloc())
*/
#ifndef SAFEMALLOC #ifndef SAFEMALLOC
#define SAFEMALLOC /* Get protos from my_sys */ #define SAFEMALLOC /* Get protos from my_sys */
@ -87,11 +84,12 @@ pthread_t shutdown_th,main_th,signal_th;
#define lSpecialValue tInt._lSpecialValue #define lSpecialValue tInt._lSpecialValue
#ifndef PEDANTIC_SAFEMALLOC #ifndef PEDANTIC_SAFEMALLOC
static int sf_malloc_tampered = 0; /* set to 1 after TERMINATE() if we had /*
to fiddle with cNewCount and the linked Set to 1 after TERMINATE() if we had to fiddle with cNewCount and
list of blocks so that _sanity() will the linked list of blocks so that _sanity() will not fuss when it
not fuss when it is not supposed to is not supposed to
*/ */
static int sf_malloc_tampered = 0;
#endif #endif
@ -102,37 +100,37 @@ static int check_ptr(const char *where, byte *ptr, const char *sFile,
static int _checkchunk(struct remember *pRec, const char *sFile, uint uLine); static int _checkchunk(struct remember *pRec, const char *sFile, uint uLine);
/* /*
* Note: both these refer to the NEW'ed Note: both these refer to the NEW'ed data only. They do not include
* data only. They do not include malloc() roundoff or the extra space required by the remember
* malloc() roundoff or the extra structures.
* space required by the remember */
* structures.
*/
#define ALLOC_VAL (uchar) 0xA5 /* NEW'ed memory is filled with this */
/* value so that references to it will */
/* end up being very strange. */
#define FREE_VAL (uchar) 0x8F /* FREE'ed memory is filled with this */
/* value so that references to it will */
/* also end up being strange. */
/*
NEW'ed memory is filled with this value so that references to it will
end up being very strange.
*/
#define ALLOC_VAL (uchar) 0xA5
/*
FEEE'ed memory is filled with this value so that references to it will
end up being very strange.
*/
#define FREE_VAL (uchar) 0x8F
#define MAGICKEY 0x14235296 /* A magic value for underrun key */ #define MAGICKEY 0x14235296 /* A magic value for underrun key */
/*
Warning: do not change the MAGICEND? values to something with the
high bit set. Various C compilers (like the 4.2bsd one) do not do
the sign extension right later on in this code and you will get
erroneous errors.
*/
#define MAGICEND0 0x68 /* Magic values for overrun keys */ #define MAGICEND0 0x68 /* Magic values for overrun keys */
#define MAGICEND1 0x34 /* " */ #define MAGICEND1 0x34 /* " */
#define MAGICEND2 0x7A /* " */ #define MAGICEND2 0x7A /* " */
#define MAGICEND3 0x15 /* " */ #define MAGICEND3 0x15 /* " */
/* Warning: do not change the MAGICEND? values to */
/* something with the high bit set. Various C */
/* compilers (like the 4.2bsd one) do not do the */
/* sign extension right later on in this code and */
/* you will get erroneous errors. */
/* Allocate some memory. */
/*
* gptr _mymalloc( uint uSize, my_string sFile, uint uLine, MyFlags )
* Allocate some memory.
*/
gptr _mymalloc (uint uSize, const char *sFile, uint uLine, myf MyFlags) gptr _mymalloc (uint uSize, const char *sFile, uint uLine, myf MyFlags)
{ {
@ -144,9 +142,10 @@ gptr _mymalloc (uint uSize, const char *sFile, uint uLine, myf MyFlags)
if (!sf_malloc_quick) if (!sf_malloc_quick)
(void) _sanity (sFile, uLine); (void) _sanity (sFile, uLine);
if(uSize + lCurMemory > safemalloc_mem_limit) if (uSize + lCurMemory > safemalloc_mem_limit)
pTmp = 0; pTmp = 0;
else else
{
/* Allocate the physical memory */ /* Allocate the physical memory */
pTmp = (struct remember *) malloc ( pTmp = (struct remember *) malloc (
sizeof (struct irem) /* remember data */ sizeof (struct irem) /* remember data */
@ -155,7 +154,7 @@ gptr _mymalloc (uint uSize, const char *sFile, uint uLine, myf MyFlags)
+ 4 /* overrun mark */ + 4 /* overrun mark */
+ sf_malloc_endhunc + sf_malloc_endhunc
); );
}
/* Check if there isn't anymore memory avaiable */ /* Check if there isn't anymore memory avaiable */
if (pTmp == NULL) if (pTmp == NULL)
{ {
@ -225,9 +224,9 @@ gptr _mymalloc (uint uSize, const char *sFile, uint uLine, myf MyFlags)
} }
/* /*
* Allocate some new memory and move old memoryblock there. Allocate some new memory and move old memoryblock there.
* Free then old memoryblock Free then old memoryblock
*/ */
gptr _myrealloc (register gptr pPtr, register uint uSize, gptr _myrealloc (register gptr pPtr, register uint uSize,
const char *sFile, uint uLine, myf MyFlags) const char *sFile, uint uLine, myf MyFlags)
@ -258,7 +257,7 @@ gptr _myrealloc (register gptr pPtr, register uint uSize,
DBUG_RETURN((gptr) NULL); DBUG_RETURN((gptr) NULL);
} }
if ((ptr=_mymalloc(uSize,sFile,uLine,MyFlags))) /* Allocate new area */ if ((ptr=_mymalloc(uSize,sFile,uLine,MyFlags))) /* Allocate new area */
{ {
uSize=min(uSize,pRec-> uDataSize); /* Move as much as possibly */ uSize=min(uSize,pRec-> uDataSize); /* Move as much as possibly */
memcpy((byte*) ptr,pPtr,(size_t) uSize); /* Copy old data */ memcpy((byte*) ptr,pPtr,(size_t) uSize); /* Copy old data */
@ -275,10 +274,7 @@ gptr _myrealloc (register gptr pPtr, register uint uSize,
} /* _myrealloc */ } /* _myrealloc */
/* /* Deallocate some memory. */
* void _myfree( my_string pPtr, my_string sFile, uint uLine, myf myflags)
* Deallocate some memory.
*/
void _myfree (gptr pPtr, const char *sFile, uint uLine, myf myflags) void _myfree (gptr pPtr, const char *sFile, uint uLine, myf myflags)
{ {
@ -297,12 +293,14 @@ void _myfree (gptr pPtr, const char *sFile, uint uLine, myf myflags)
pRec = (struct remember *) ((byte*) pPtr-sizeof(struct irem)- pRec = (struct remember *) ((byte*) pPtr-sizeof(struct irem)-
sf_malloc_prehunc); sf_malloc_prehunc);
/* Check to make sure that we have a real remember structure */ /*
/* Note: this test could fail for four reasons: */ Check to make sure that we have a real remember structure.
/* (1) The memory was already free'ed */ Note: this test could fail for four reasons:
/* (2) The memory was never new'ed */ (1) The memory was already free'ed
/* (3) There was an underrun */ (2) The memory was never new'ed
/* (4) A stray pointer hit this location */ (3) There was an underrun
(4) A stray pointer hit this location
*/
if (*((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc)) if (*((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc))
!= MAGICKEY) != MAGICKEY)
@ -379,9 +377,9 @@ static int check_ptr(const char *where, byte *ptr, const char *sFile,
#ifdef THREAD #ifdef THREAD
static int legal_leak(struct remember* pPtr) static int legal_leak(struct remember* pPtr)
{ {
return pthread_self() == pPtr->thread_id || main_th == pPtr->thread_id /* TODO: This code needs to be made more general */
|| shutdown_th == pPtr->thread_id return (pthread_self() == pPtr->thread_id || main_th == pPtr->thread_id ||
|| signal_th == pPtr->thread_id; shutdown_th == pPtr->thread_id || signal_th == pPtr->thread_id);
} }
#else #else
static int legal_leak(struct remember* pPtr) static int legal_leak(struct remember* pPtr)
@ -391,9 +389,9 @@ static int legal_leak(struct remember* pPtr)
#endif #endif
/* /*
* TERMINATE(FILE *file) TERMINATE(FILE *file)
* Report on all the memory pieces that have not been Report on all the memory pieces that have not been
* free'ed as well as the statistics. free'ed as well as the statistics.
*/ */
void TERMINATE (FILE *file) void TERMINATE (FILE *file)
@ -460,8 +458,10 @@ void TERMINATE (FILE *file)
DBUG_PRINT("safe",("cNewCount: %d",cNewCount)); DBUG_PRINT("safe",("cNewCount: %d",cNewCount));
} }
/* Report on all the memory that was allocated with NEW */ /*
/* but not free'ed with FREE. */ Report on all the memory that was allocated with NEW
but not free'ed with FREE.
*/
if ((pPtr=pRememberRoot)) if ((pPtr=pRememberRoot))
{ {

View file

@ -141,7 +141,7 @@ bool test_if_int(const char *str,int length)
str++; str++;
if (str == end) if (str == end)
return 0; // Error: Empty string return 0; // Error: Empty string
for ( ; str != end ; str++) for (; str != end ; str++)
{ {
if (!isdigit(*str)) if (!isdigit(*str))
{ {
@ -204,7 +204,7 @@ static bool test_if_real(const char *str,int length)
length--; str++; length--; str++;
} }
} }
for ( ; length ; length--, str++) for (; length ; length--, str++)
{ // Allow end space { // Allow end space
if (!isspace(*str)) if (!isspace(*str))
return 0; return 0;
@ -3336,9 +3336,9 @@ void Field_datetime::sql_type(String &res) const
void Field_string::store(const char *from,uint length) void Field_string::store(const char *from,uint length)
{ {
#ifdef USE_TIS620 #ifdef USE_TIS620
if(!binary_flag) { if (!binary_flag) {
ThNormalize((uchar *)ptr, field_length, (uchar *)from, length); ThNormalize((uchar *)ptr, field_length, (uchar *)from, length);
if(length < field_length) { if (length < field_length) {
bfill(ptr + length, field_length - length, ' '); bfill(ptr + length, field_length - length, ' ');
} }
} }
@ -3540,7 +3540,7 @@ uint Field_string::max_packed_col_length(uint max_length)
void Field_varstring::store(const char *from,uint length) void Field_varstring::store(const char *from,uint length)
{ {
#ifdef USE_TIS620 #ifdef USE_TIS620
if(!binary_flag) if (!binary_flag)
{ {
ThNormalize((uchar *) ptr+2, field_length, (uchar *) from, length); ThNormalize((uchar *) ptr+2, field_length, (uchar *) from, length);
} }
@ -3869,7 +3869,7 @@ void Field_blob::store(const char *from,uint len)
if (table->copy_blobs || len <= MAX_FIELD_WIDTH) if (table->copy_blobs || len <= MAX_FIELD_WIDTH)
{ // Must make a copy { // Must make a copy
#ifdef USE_TIS620 #ifdef USE_TIS620
if(!binary_flag) if (!binary_flag)
{ {
/* If there isn't enough memory, use original string */ /* If there isn't enough memory, use original string */
if ((th_ptr=(char * ) my_malloc(sizeof(char) * len,MYF(0)))) if ((th_ptr=(char * ) my_malloc(sizeof(char) * len,MYF(0))))
@ -4489,7 +4489,7 @@ ulonglong find_set(TYPELIB *lib,const char *x,uint length)
for (;;) for (;;)
{ {
const char *pos=start; const char *pos=start;
for ( ; pos != end && *pos != field_separator ; pos++) ; for (; pos != end && *pos != field_separator ; pos++) ;
uint find=find_enum(lib,start,(uint) (pos-start)); uint find=find_enum(lib,start,(uint) (pos-start));
if (!find) if (!find)
error=1; error=1;

View file

@ -358,7 +358,7 @@ berkeley_cmp_packed_key(DB *file, const DBT *new_key, const DBT *saved_key)
KEY_PART_INFO *key_part= key->key_part, *end=key_part+key->key_parts; KEY_PART_INFO *key_part= key->key_part, *end=key_part+key->key_parts;
uint key_length=new_key->size; uint key_length=new_key->size;
for ( ; key_part != end && (int) key_length > 0; key_part++) for (; key_part != end && (int) key_length > 0; key_part++)
{ {
int cmp; int cmp;
if (key_part->null_bit) if (key_part->null_bit)
@ -396,7 +396,7 @@ berkeley_cmp_fix_length_key(DB *file, const DBT *new_key, const DBT *saved_key)
KEY_PART_INFO *key_part= key->key_part, *end=key_part+key->key_parts; KEY_PART_INFO *key_part= key->key_part, *end=key_part+key->key_parts;
uint key_length=new_key->size; uint key_length=new_key->size;
for ( ; key_part != end && (int) key_length > 0 ; key_part++) for (; key_part != end && (int) key_length > 0 ; key_part++)
{ {
int cmp; int cmp;
if ((cmp=key_part->field->pack_cmp(new_key_ptr,saved_key_ptr,0))) if ((cmp=key_part->field->pack_cmp(new_key_ptr,saved_key_ptr,0)))
@ -417,7 +417,7 @@ berkeley_key_cmp(TABLE *table, KEY *key_info, const char *key, uint key_length)
KEY_PART_INFO *key_part= key_info->key_part, KEY_PART_INFO *key_part= key_info->key_part,
*end=key_part+key_info->key_parts; *end=key_part+key_info->key_parts;
for ( ; key_part != end && (int) key_length > 0; key_part++) for (; key_part != end && (int) key_length > 0; key_part++)
{ {
int cmp; int cmp;
if (key_part->null_bit) if (key_part->null_bit)
@ -561,7 +561,7 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
ref_length=0; ref_length=0;
KEY_PART_INFO *key_part= table->key_info[primary_key].key_part; KEY_PART_INFO *key_part= table->key_info[primary_key].key_part;
KEY_PART_INFO *end=key_part+table->key_info[primary_key].key_parts; KEY_PART_INFO *end=key_part+table->key_info[primary_key].key_parts;
for ( ; key_part != end ; key_part++) for (; key_part != end ; key_part++)
ref_length+= key_part->field->max_packed_col_length(key_part->length); ref_length+= key_part->field->max_packed_col_length(key_part->length);
share->fixed_length_primary_key= share->fixed_length_primary_key=
(ref_length == table->key_info[primary_key].key_length); (ref_length == table->key_info[primary_key].key_length);
@ -701,7 +701,7 @@ void ha_berkeley::unpack_key(char *record, DBT *key, uint index)
*end=key_part+key_info->key_parts; *end=key_part+key_info->key_parts;
char *pos=(char*) key->data; char *pos=(char*) key->data;
for ( ; key_part != end; key_part++) for (; key_part != end; key_part++)
{ {
if (key_part->null_bit) if (key_part->null_bit)
{ {
@ -747,7 +747,7 @@ DBT *ha_berkeley::create_key(DBT *key, uint keynr, char *buff,
key->data=buff; key->data=buff;
key->app_private= key_info; key->app_private= key_info;
for ( ; key_part != end && key_length > 0; key_part++) for (; key_part != end && key_length > 0; key_part++)
{ {
if (key_part->null_bit) if (key_part->null_bit)
{ {
@ -925,7 +925,7 @@ int ha_berkeley::key_cmp(uint keynr, const byte * old_row,
KEY_PART_INFO *key_part=table->key_info[keynr].key_part; KEY_PART_INFO *key_part=table->key_info[keynr].key_part;
KEY_PART_INFO *end=key_part+table->key_info[keynr].key_parts; KEY_PART_INFO *end=key_part+table->key_info[keynr].key_parts;
for ( ; key_part != end ; key_part++) for (; key_part != end ; key_part++)
{ {
if (key_part->null_bit) if (key_part->null_bit)
{ {
@ -1584,7 +1584,7 @@ DBT *ha_berkeley::get_pos(DBT *to, byte *pos)
KEY_PART_INFO *key_part=table->key_info[primary_key].key_part; KEY_PART_INFO *key_part=table->key_info[primary_key].key_part;
KEY_PART_INFO *end=key_part+table->key_info[primary_key].key_parts; KEY_PART_INFO *end=key_part+table->key_info[primary_key].key_parts;
for ( ; key_part != end ; key_part++) for (; key_part != end ; key_part++)
pos+=key_part->field->packed_col_length((char*) pos,key_part->length); pos+=key_part->field->packed_col_length((char*) pos,key_part->length);
to->size= (uint) (pos- (byte*) to->data); to->size= (uint) (pos- (byte*) to->data);
} }

View file

@ -45,6 +45,7 @@ TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names)-1,"",
*****************************************************************************/ *****************************************************************************/
// collect errors printed by mi_check routines // collect errors printed by mi_check routines
static void mi_check_print_msg(MI_CHECK *param, const char* msg_type, static void mi_check_print_msg(MI_CHECK *param, const char* msg_type,
const char *fmt, va_list args) const char *fmt, va_list args)
{ {
@ -134,7 +135,7 @@ int ha_myisam::net_read_dump(NET* net)
int error = 0; int error = 0;
my_seek(data_fd, 0L, MY_SEEK_SET, MYF(MY_WME)); my_seek(data_fd, 0L, MY_SEEK_SET, MYF(MY_WME));
for(;;) for (;;)
{ {
ulong packet_len = my_net_read(net); ulong packet_len = my_net_read(net);
if (!packet_len) if (!packet_len)
@ -171,7 +172,7 @@ int ha_myisam::dump(THD* thd, int fd)
int error = 0; int error = 0;
my_seek(data_fd, 0L, MY_SEEK_SET, MYF(MY_WME)); my_seek(data_fd, 0L, MY_SEEK_SET, MYF(MY_WME));
for(; bytes_to_read > 0;) for (; bytes_to_read > 0;)
{ {
uint bytes = my_read(data_fd, buf, blocksize, MYF(MY_WME)); uint bytes = my_read(data_fd, buf, blocksize, MYF(MY_WME));
if (bytes == MY_FILE_ERROR) if (bytes == MY_FILE_ERROR)
@ -494,8 +495,8 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt)
while ((error=repair(thd,param,0)) && param.retry_repair) while ((error=repair(thd,param,0)) && param.retry_repair)
{ {
param.retry_repair=0; param.retry_repair=0;
if ((param.testflag & T_RETRY_WITHOUT_QUICK) && if (test_all_bits(param.testflag,
(param.testflag & T_QUICK)) (uint) (T_RETRY_WITHOUT_QUICK | T_QUICK)))
{ {
param.testflag&= ~T_RETRY_WITHOUT_QUICK; param.testflag&= ~T_RETRY_WITHOUT_QUICK;
sql_print_error("Warning: Retrying repair of: '%s' without quick", sql_print_error("Warning: Retrying repair of: '%s' without quick",

View file

@ -118,7 +118,10 @@ public:
double val_result(); double val_result();
longlong val_int_result(); longlong val_int_result();
String *str_result(String* tmp); String *str_result(String* tmp);
bool send(THD *thd, String *str_arg) { return result_field->send(thd,str_arg); } bool send(THD *thd, String *str_arg)
{
return result_field->send(thd,str_arg);
}
void make_field(Send_field *field); void make_field(Send_field *field);
bool fix_fields(THD *,struct st_table_list *); bool fix_fields(THD *,struct st_table_list *);
bool save_in_field(Field *field); bool save_in_field(Field *field);

View file

@ -549,7 +549,7 @@ Item_func_nullif::fix_length_and_dec()
} }
/* /*
nullif() returns NULL if arguments are different, else it returns the nullif () returns NULL if arguments are different, else it returns the
first argument. first argument.
Note that we have to evaluate the first argument twice as the compare Note that we have to evaluate the first argument twice as the compare
may have been done with a different type than return value may have been done with a different type than return value
@ -1296,7 +1296,7 @@ bool Item_func_like::fix_fields(THD *thd,struct st_table_list *tlist)
*last == wild_many) *last == wild_many)
{ {
const char* tmp = first + 1; const char* tmp = first + 1;
for ( ; *tmp != wild_many && *tmp != wild_one && *tmp != escape; tmp++) ; for (; *tmp != wild_many && *tmp != wild_one && *tmp != escape; tmp++) ;
canDoTurboBM = tmp == last; canDoTurboBM = tmp == last;
} }

View file

@ -1502,10 +1502,11 @@ void debug_sync_point(const char* lock_name, uint lock_timeout)
thd->ull=0; thd->ull=0;
} }
/* if the lock has not been aquired by some client, we do not want to /*
create an entry for it, since we immediately release the lock. In If the lock has not been aquired by some client, we do not want to
this case, we will not be waiting, but rather, just waste CPU and create an entry for it, since we immediately release the lock. In
memory on the whole deal this case, we will not be waiting, but rather, just waste CPU and
memory on the whole deal
*/ */
if (!(ull= ((ULL*) hash_search(&hash_user_locks,lock_name, if (!(ull= ((ULL*) hash_search(&hash_user_locks,lock_name,
lock_name_len)))) lock_name_len))))
@ -1515,8 +1516,10 @@ void debug_sync_point(const char* lock_name, uint lock_timeout)
} }
ull->count++; ull->count++;
/* structure is now initialized. Try to get the lock */ /*
/* Set up control struct to allow others to abort locks */ Structure is now initialized. Try to get the lock.
Set up control struct to allow others to abort locks
*/
thd->proc_info="User lock"; thd->proc_info="User lock";
thd->mysys_var->current_mutex= &LOCK_user_locks; thd->mysys_var->current_mutex= &LOCK_user_locks;
thd->mysys_var->current_cond= &ull->cond; thd->mysys_var->current_cond= &ull->cond;
@ -1603,8 +1606,10 @@ longlong Item_func_get_lock::val_int()
} }
ull->count++; ull->count++;
/* structure is now initialized. Try to get the lock */ /*
/* Set up control struct to allow others to abort locks */ Structure is now initialized. Try to get the lock.
Set up control struct to allow others to abort locks.
*/
thd->proc_info="User lock"; thd->proc_info="User lock";
thd->mysys_var->current_mutex= &LOCK_user_locks; thd->mysys_var->current_mutex= &LOCK_user_locks;
thd->mysys_var->current_cond= &ull->cond; thd->mysys_var->current_cond= &ull->cond;
@ -1645,10 +1650,11 @@ longlong Item_func_get_lock::val_int()
/* /*
** Release a user level lock. Release a user level lock.
** Returns 1 if lock released Return:
** 0 if lock wasn't held 1 if lock released
** NULL if no such lock 0 if lock wasn't held
(SQL) NULL if no such lock
*/ */
longlong Item_func_release_lock::val_int() longlong Item_func_release_lock::val_int()
@ -1717,6 +1723,7 @@ longlong Item_func_benchmark::val_int()
return 0; return 0;
} }
#define extra_size sizeof(double) #define extra_size sizeof(double)
static user_var_entry *get_variable(HASH *hash, LEX_STRING &name, static user_var_entry *get_variable(HASH *hash, LEX_STRING &name,
@ -1980,6 +1987,7 @@ void Item_func_get_user_var::print(String *str)
str->append(')'); str->append(')');
} }
bool Item_func_get_user_var::eq(const Item *item, bool binary_cmp) const bool Item_func_get_user_var::eq(const Item *item, bool binary_cmp) const
{ {
/* Assume we don't have rtti */ /* Assume we don't have rtti */
@ -2087,10 +2095,11 @@ bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist)
maybe_null=1; maybe_null=1;
join_key=0; join_key=0;
/* const_item is assumed in quite a bit of places, so it would be difficult /*
to remove; If it would ever to be removed, this should include const_item is assumed in quite a bit of places, so it would be difficult
modifications to find_best and auto_close as complement to auto_init code to remove; If it would ever to be removed, this should include
above. modifications to find_best and auto_close as complement to auto_init code
above.
*/ */
if (Item_func::fix_fields(thd,tlist) || !const_item()) if (Item_func::fix_fields(thd,tlist) || !const_item())
{ {
@ -2110,7 +2119,7 @@ bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist)
} }
/* check that all columns come from the same table */ /* check that all columns come from the same table */
if (count_bits(used_tables_cache) != 1) if (count_bits(used_tables_cache) != 1)
key=NO_SUCH_KEY; key=NO_SUCH_KEY;
const_item_cache=0; const_item_cache=0;
table=((Item_field *)fields.head())->field->table; table=((Item_field *)fields.head())->field->table;
table->fulltext_searched=1; table->fulltext_searched=1;
@ -2124,6 +2133,7 @@ bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist)
return 0; return 0;
} }
bool Item_func_match::fix_index() bool Item_func_match::fix_index()
{ {
List_iterator_fast<Item> li(fields); List_iterator_fast<Item> li(fields);
@ -2200,16 +2210,15 @@ err:
return 0; return 0;
} }
my_printf_error(ER_FT_MATCHING_KEY_NOT_FOUND, my_printf_error(ER_FT_MATCHING_KEY_NOT_FOUND,
ER(ER_FT_MATCHING_KEY_NOT_FOUND),MYF(0)); ER(ER_FT_MATCHING_KEY_NOT_FOUND),MYF(0));
return 1; return 1;
} }
bool Item_func_match::eq(const Item *item, bool binary_cmp) const bool Item_func_match::eq(const Item *item, bool binary_cmp) const
{ {
if (item->type() != FUNC_ITEM) if (item->type() != FUNC_ITEM ||
return 0; func_name() != ((Item_func*)item)->func_name())
if (func_name() != ((Item_func*)item)->func_name())
return 0; return 0;
Item_func_match *ifm=(Item_func_match*) item; Item_func_match *ifm=(Item_func_match*) item;
@ -2221,6 +2230,7 @@ bool Item_func_match::eq(const Item *item, bool binary_cmp) const
return 0; return 0;
} }
double Item_func_match::val() double Item_func_match::val()
{ {
if (ft_handler == NULL) if (ft_handler == NULL)
@ -2230,14 +2240,13 @@ double Item_func_match::val()
{ {
if (table->file->ft_handler) if (table->file->ft_handler)
return ft_handler->please->get_relevance(ft_handler); return ft_handler->please->get_relevance(ft_handler);
join_key=0; join_key=0;
} }
if (key == NO_SUCH_KEY) if (key == NO_SUCH_KEY)
{ {
String *a=concat->val_str(&value); String *a= concat->val_str(&value);
if ((null_value= (a==0))) if ((null_value= (a == 0)))
return 0; return 0;
return ft_handler->please->find_relevance(ft_handler, return ft_handler->please->find_relevance(ft_handler,
(byte *)a->ptr(), a->length()); (byte *)a->ptr(), a->length());
@ -2246,6 +2255,7 @@ double Item_func_match::val()
return ft_handler->please->find_relevance(ft_handler, record, 0); return ft_handler->please->find_relevance(ft_handler, record, 0);
} }
/*************************************************************************** /***************************************************************************
System variables System variables
This has to be recoded after we get more than 3 system variables This has to be recoded after we get more than 3 system variables

View file

@ -921,7 +921,8 @@ public:
Item_func_match(List<Item> &a, Item *b): Item_real_func(b), Item_func_match(List<Item> &a, Item *b): Item_real_func(b),
fields(a), table(0), master(0), ft_handler(0), fields(a), table(0), master(0), ft_handler(0),
concat(0), key(0), join_key(0) {} concat(0), key(0), join_key(0)
{}
~Item_func_match() ~Item_func_match()
{ {
if (!master && ft_handler) if (!master && ft_handler)
@ -932,7 +933,8 @@ public:
table->file->ft_handler=0; table->file->ft_handler=0;
table->fulltext_searched=0; table->fulltext_searched=0;
} }
if (concat) delete concat; if (concat)
delete concat;
} }
enum Functype functype() const { return FT_FUNC; } enum Functype functype() const { return FT_FUNC; }
void update_used_tables() {} void update_used_tables() {}
@ -945,19 +947,23 @@ public:
void init_search(bool no_order); void init_search(bool no_order);
}; };
class Item_func_match_nl :public Item_func_match class Item_func_match_nl :public Item_func_match
{ {
public: public:
Item_func_match_nl(List<Item> &a, Item *b): Item_func_match_nl(List<Item> &a, Item *b)
Item_func_match(a,b) { mode=FT_NL; } :Item_func_match(a,b)
{ mode=FT_NL; }
const char *func_name() const { return "match_nl"; } const char *func_name() const { return "match_nl"; }
}; };
class Item_func_match_bool :public Item_func_match class Item_func_match_bool :public Item_func_match
{ {
public: public:
Item_func_match_bool(List<Item> &a, Item *b): Item_func_match_bool(List<Item> &a, Item *b)
Item_func_match(a,b) { mode=FT_BOOL; } :Item_func_match(a,b)
{ mode=FT_BOOL; }
const char *func_name() const { return "match_bool"; } const char *func_name() const { return "match_bool"; }
}; };

View file

@ -42,7 +42,7 @@ uint nr_of_decimals(const char *str)
if ((str=strchr(str,'.'))) if ((str=strchr(str,'.')))
{ {
const char *start= ++str; const char *start= ++str;
for ( ; isdigit(*str) ; str++) ; for (; isdigit(*str) ; str++) ;
return (uint) (str-start); return (uint) (str-start);
} }
return 0; return 0;
@ -208,8 +208,7 @@ void Item_func_concat::fix_length_and_dec()
/* /*
Function des_encrypt() by tonu@spam.ee & monty Function des_encrypt() by tonu@spam.ee & monty
Works only if compiled with OpenSSL library support. Works only if compiled with OpenSSL library support.
This returns a binary string where first character is This returns a binary string where first character is CHAR(128 | key-number).
CHAR(128 | key-number).
If one uses a string key key_number is 127. If one uses a string key key_number is 127.
Encryption result is longer than original by formula: Encryption result is longer than original by formula:
new_length= org_length + (8-(org_length % 8))+1 new_length= org_length + (8-(org_length % 8))+1
@ -1903,7 +1902,7 @@ String* Item_func_export_set::val_str(String* str)
str->append(*yes); str->append(*yes);
else else
str->append(*no); str->append(*no);
if(i != num_set_values - 1) if (i != num_set_values - 1)
str->append(*sep); str->append(*sep);
} }
return str; return str;

View file

@ -1102,7 +1102,7 @@ bool Item_sum_count_distinct::add()
*/ */
if (tree.elements_in_tree > max_elements_in_tree) if (tree.elements_in_tree > max_elements_in_tree)
{ {
if(tree_to_myisam()) if (tree_to_myisam())
return 1; return 1;
} }
else if (!tree_insert(&tree, table->record[0] + rec_offset, 0)) else if (!tree_insert(&tree, table->record[0] + rec_offset, 0))

View file

@ -683,7 +683,7 @@ String *Item_func_date_format::val_str(String *str)
/* Create the result string */ /* Create the result string */
const char *ptr=format->ptr(); const char *ptr=format->ptr();
const char *end=ptr+format->length(); const char *end=ptr+format->length();
for ( ; ptr != end ; ptr++) for (; ptr != end ; ptr++)
{ {
if (*ptr != '%' || ptr+1 == end) if (*ptr != '%' || ptr+1 == end)
str->append(*ptr); str->append(*ptr);
@ -691,7 +691,7 @@ String *Item_func_date_format::val_str(String *str)
{ {
switch (*++ptr) { switch (*++ptr) {
case 'M': case 'M':
if(!l_time.month) if (!l_time.month)
{ {
null_value=1; null_value=1;
return 0; return 0;
@ -699,7 +699,7 @@ String *Item_func_date_format::val_str(String *str)
str->append(month_names[l_time.month-1]); str->append(month_names[l_time.month-1]);
break; break;
case 'b': case 'b':
if(!l_time.month) if (!l_time.month)
{ {
null_value=1; null_value=1;
return 0; return 0;
@ -707,7 +707,7 @@ String *Item_func_date_format::val_str(String *str)
str->append(month_names[l_time.month-1].ptr(),3); str->append(month_names[l_time.month-1].ptr(),3);
break; break;
case 'W': case 'W':
if(date_or_time) if (date_or_time)
{ {
null_value=1; null_value=1;
return 0; return 0;
@ -716,7 +716,7 @@ String *Item_func_date_format::val_str(String *str)
str->append(day_names[weekday]); str->append(day_names[weekday]);
break; break;
case 'a': case 'a':
if(date_or_time) if (date_or_time)
{ {
null_value=1; null_value=1;
return 0; return 0;
@ -725,7 +725,7 @@ String *Item_func_date_format::val_str(String *str)
str->append(day_names[weekday].ptr(),3); str->append(day_names[weekday].ptr(),3);
break; break;
case 'D': case 'D':
if(date_or_time) if (date_or_time)
{ {
null_value=1; null_value=1;
return 0; return 0;
@ -791,7 +791,7 @@ String *Item_func_date_format::val_str(String *str)
str->append(intbuff); str->append(intbuff);
break; break;
case 'j': case 'j':
if(date_or_time) if (date_or_time)
{ {
null_value=1; null_value=1;
return 0; return 0;

View file

@ -135,7 +135,7 @@ static int lock_external(TABLE **tables,uint count)
if ((error=(*tables)->file->external_lock(thd,lock_type))) if ((error=(*tables)->file->external_lock(thd,lock_type)))
{ {
for ( ; i-- ; tables--) for (; i-- ; tables--)
{ {
(*tables)->file->external_lock(thd, F_UNLCK); (*tables)->file->external_lock(thd, F_UNLCK);
(*tables)->current_lock=F_UNLCK; (*tables)->current_lock=F_UNLCK;
@ -473,7 +473,7 @@ void unlock_table_name(THD *thd, TABLE_LIST *table_list)
static bool locked_named_table(THD *thd, TABLE_LIST *table_list) static bool locked_named_table(THD *thd, TABLE_LIST *table_list)
{ {
for ( ; table_list ; table_list=table_list->next) for (; table_list ; table_list=table_list->next)
{ {
if (table_list->table && table_is_used(table_list->table,0)) if (table_list->table && table_is_used(table_list->table,0))
return 1; return 1;

View file

@ -384,6 +384,7 @@ int MYSQL_LOG::reset_logs(THD* thd)
int error=0; int error=0;
const char* save_name; const char* save_name;
enum_log_type save_log_type; enum_log_type save_log_type;
pthread_mutex_lock(&LOCK_log); pthread_mutex_lock(&LOCK_log);
if (find_first_log(&linfo,"")) if (find_first_log(&linfo,""))
{ {
@ -406,6 +407,7 @@ int MYSQL_LOG::reset_logs(THD* thd)
need_start_event=1; need_start_event=1;
open(save_name,save_log_type,0,io_cache_type,no_auto_events); open(save_name,save_log_type,0,io_cache_type,no_auto_events);
my_free((gptr)save_name,MYF(0)); my_free((gptr)save_name,MYF(0));
err: err:
pthread_mutex_unlock(&LOCK_log); pthread_mutex_unlock(&LOCK_log);
return error; return error;
@ -414,17 +416,19 @@ err:
int MYSQL_LOG::purge_first_log(struct st_relay_log_info* rli) int MYSQL_LOG::purge_first_log(struct st_relay_log_info* rli)
{ {
// pre-conditions /*
Test pre-conditions.
Assume that we have previously read the first log and
stored it in rli->relay_log_name
*/
DBUG_ASSERT(is_open()); DBUG_ASSERT(is_open());
DBUG_ASSERT(index_file >= 0); DBUG_ASSERT(index_file >= 0);
DBUG_ASSERT(rli->slave_running == 1); DBUG_ASSERT(rli->slave_running == 1);
DBUG_ASSERT(!strcmp(rli->linfo.log_file_name,rli->relay_log_name)); DBUG_ASSERT(!strcmp(rli->linfo.log_file_name,rli->relay_log_name));
/*
Assume that we have previously read the first log and
stored it in rli->relay_log_name
*/
DBUG_ASSERT(rli->linfo.index_file_offset == DBUG_ASSERT(rli->linfo.index_file_offset ==
strlen(rli->relay_log_name) + 1); strlen(rli->relay_log_name) + 1);
int tmp_fd; int tmp_fd;
char* fname, *io_buf; char* fname, *io_buf;
int error = 0; int error = 0;
@ -486,9 +490,11 @@ err:
pthread_mutex_lock(&rli->log_space_lock); pthread_mutex_lock(&rli->log_space_lock);
rli->log_space_total -= s.st_size; rli->log_space_total -= s.st_size;
pthread_mutex_unlock(&rli->log_space_lock); pthread_mutex_unlock(&rli->log_space_lock);
// ok to broadcast after the critical region as there is no risk of /*
// the mutex being destroyed by this thread later - this helps save Ok to broadcast after the critical region as there is no risk of
// context switches the mutex being destroyed by this thread later - this helps save
context switches
*/
pthread_cond_broadcast(&rli->log_space_cond); pthread_cond_broadcast(&rli->log_space_cond);
if ((error=find_first_log(&rli->linfo,"",0/*no mutex*/))) if ((error=find_first_log(&rli->linfo,"",0/*no mutex*/)))
@ -500,8 +506,8 @@ err:
goto err2; goto err2;
} }
rli->relay_log_pos = BIN_LOG_HEADER_SIZE; rli->relay_log_pos = BIN_LOG_HEADER_SIZE;
strnmov(rli->relay_log_name,rli->linfo.log_file_name, strmake(rli->relay_log_name,rli->linfo.log_file_name,
sizeof(rli->relay_log_name)); sizeof(rli->relay_log_name)-1);
flush_relay_log_info(rli); flush_relay_log_info(rli);
} }
/* /*
@ -689,7 +695,7 @@ void MYSQL_LOG::new_file(bool inside_mutex)
if (!no_rotate) if (!no_rotate)
{ {
/* /*
only rotate open logs that are marked non-rotatable Only rotate open logs that are marked non-rotatable
(binlog with constant name are non-rotatable) (binlog with constant name are non-rotatable)
*/ */
if (generate_new_name(new_name, name)) if (generate_new_name(new_name, name))
@ -720,9 +726,11 @@ void MYSQL_LOG::new_file(bool inside_mutex)
r.write(&log_file); r.write(&log_file);
bytes_written += r.get_event_len(); bytes_written += r.get_event_len();
} }
// update needs to be signaled even if there is no rotate event /*
// log rotation should give the waiting thread a signal to Update needs to be signaled even if there is no rotate event
// discover EOF and move on to the next log log rotation should give the waiting thread a signal to
discover EOF and move on to the next log.
*/
signal_update(); signal_update();
} }
else else
@ -745,8 +753,10 @@ bool MYSQL_LOG::append(Log_event* ev)
pthread_mutex_lock(&LOCK_log); pthread_mutex_lock(&LOCK_log);
DBUG_ASSERT(log_file.type == SEQ_READ_APPEND); DBUG_ASSERT(log_file.type == SEQ_READ_APPEND);
// Log_event::write() is smart enough to use my_b_write() or /*
// my_b_append() depending on the kind of cache we have Log_event::write() is smart enough to use my_b_write() or
my_b_append() depending on the kind of cache we have.
*/
if (ev->write(&log_file)) if (ev->write(&log_file))
{ {
error=1; error=1;
@ -758,11 +768,13 @@ bool MYSQL_LOG::append(Log_event* ev)
new_file(1); new_file(1);
} }
signal_update(); signal_update();
err: err:
pthread_mutex_unlock(&LOCK_log); pthread_mutex_unlock(&LOCK_log);
return error; return error;
} }
bool MYSQL_LOG::appendv(const char* buf, uint len,...) bool MYSQL_LOG::appendv(const char* buf, uint len,...)
{ {
bool error = 0; bool error = 0;
@ -1232,8 +1244,12 @@ void MYSQL_LOG::close(bool exiting)
} }
/* Check if a string is a valid number */ /*
/* Output: TRUE -> number */ Check if a string is a valid number
Return:
TRUE String is a number
FALSE Error
*/
static bool test_if_number(register const char *str, static bool test_if_number(register const char *str,
long *res, bool allow_wildcards) long *res, bool allow_wildcards)

File diff suppressed because it is too large Load diff

View file

@ -15,8 +15,8 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef _LOG_EVENT_H #ifndef _log_event_h
#define _LOG_EVENT_H #define _log_event_h
#ifdef __EMX__ #ifdef __EMX__
#undef write // remove pthread.h macro definition, conflict with write() class member #undef write // remove pthread.h macro definition, conflict with write() class member
@ -36,75 +36,77 @@
#define LOG_EVENT_OFFSET 4 #define LOG_EVENT_OFFSET 4
#define BINLOG_VERSION 3 #define BINLOG_VERSION 3
/* we could have used SERVER_VERSION_LENGTH, but this introduces an /*
obscure dependency - if somebody decided to change SERVER_VERSION_LENGTH We could have used SERVER_VERSION_LENGTH, but this introduces an
this would have broke the replication protocol obscure dependency - if somebody decided to change SERVER_VERSION_LENGTH
this would have broke the replication protocol
*/ */
#define ST_SERVER_VER_LEN 50 #define ST_SERVER_VER_LEN 50
#define DUMPFILE_FLAG 0x1 #define DUMPFILE_FLAG 0x1
#define OPT_ENCLOSED_FLAG 0x2 #define OPT_ENCLOSED_FLAG 0x2
#define REPLACE_FLAG 0x4 #define REPLACE_FLAG 0x4
#define IGNORE_FLAG 0x8 #define IGNORE_FLAG 0x8
#define FIELD_TERM_EMPTY 0x1 #define FIELD_TERM_EMPTY 0x1
#define ENCLOSED_EMPTY 0x2 #define ENCLOSED_EMPTY 0x2
#define LINE_TERM_EMPTY 0x4 #define LINE_TERM_EMPTY 0x4
#define LINE_START_EMPTY 0x8 #define LINE_START_EMPTY 0x8
#define ESCAPED_EMPTY 0x10 #define ESCAPED_EMPTY 0x10
struct old_sql_ex struct old_sql_ex
{ {
char field_term; char field_term;
char enclosed; char enclosed;
char line_term; char line_term;
char line_start; char line_start;
char escaped; char escaped;
char opt_flags; char opt_flags;
char empty_flags; char empty_flags;
}; };
#define NUM_LOAD_DELIM_STRS 5 #define NUM_LOAD_DELIM_STRS 5
struct sql_ex_info struct sql_ex_info
{ {
char* field_term; char* field_term;
char* enclosed; char* enclosed;
char* line_term; char* line_term;
char* line_start; char* line_start;
char* escaped; char* escaped;
uint8 field_term_len,enclosed_len,line_term_len,line_start_len, int cached_new_format;
escaped_len; uint8 field_term_len,enclosed_len,line_term_len,line_start_len, escaped_len;
char opt_flags; char opt_flags;
char empty_flags; char empty_flags;
int cached_new_format;
// store in new format even if old is possible // store in new format even if old is possible
void force_new_format() { cached_new_format = 1;} void force_new_format() { cached_new_format = 1;}
int data_size() { return new_format() ? int data_size()
field_term_len + enclosed_len + line_term_len + {
line_start_len + escaped_len + 6 : 7;} return (new_format() ?
int write_data(IO_CACHE* file); field_term_len + enclosed_len + line_term_len +
char* init(char* buf,char* buf_end,bool use_new_format); line_start_len + escaped_len + 6 : 7);
bool new_format() }
{ int write_data(IO_CACHE* file);
return (cached_new_format != -1) ? cached_new_format : char* init(char* buf,char* buf_end,bool use_new_format);
(cached_new_format=(field_term_len > 1 || bool new_format()
enclosed_len > 1 || {
line_term_len > 1 || line_start_len > 1 || return ((cached_new_format != -1) ? cached_new_format :
escaped_len > 1)); (cached_new_format=(field_term_len > 1 ||
} enclosed_len > 1 ||
} ; line_term_len > 1 || line_start_len > 1 ||
escaped_len > 1)));
}
};
/* Binary log consists of events. Each event has a fixed length header, /*
followed by possibly variable ( depending on the type of event) length Binary log consists of events. Each event has a fixed length header,
data body. The data body consists of an optional fixed length segment followed by possibly variable ( depending on the type of event) length
(post-header), and an optional variable length segment. See #defines and data body. The data body consists of an optional fixed length segment
comments below for the format specifics (post-header), and an optional variable length segment. See #defines and
comments below for the format specifics
*/ */
/* event-specific post-header sizes */ /* event-specific post-header sizes */
#define LOG_EVENT_HEADER_LEN 19 #define LOG_EVENT_HEADER_LEN 19
#define OLD_HEADER_LEN 13 #define OLD_HEADER_LEN 13
@ -139,11 +141,11 @@ struct sql_ex_info
/* query event post-header */ /* query event post-header */
#define Q_THREAD_ID_OFFSET 0 #define Q_THREAD_ID_OFFSET 0
#define Q_EXEC_TIME_OFFSET 4 #define Q_EXEC_TIME_OFFSET 4
#define Q_DB_LEN_OFFSET 8 #define Q_DB_LEN_OFFSET 8
#define Q_ERR_CODE_OFFSET 9 #define Q_ERR_CODE_OFFSET 9
#define Q_DATA_OFFSET QUERY_HEADER_LEN #define Q_DATA_OFFSET QUERY_HEADER_LEN
/* Intvar event post-header */ /* Intvar event post-header */
@ -159,7 +161,7 @@ struct sql_ex_info
#define L_DB_LEN_OFFSET 13 #define L_DB_LEN_OFFSET 13
#define L_NUM_FIELDS_OFFSET 14 #define L_NUM_FIELDS_OFFSET 14
#define L_SQL_EX_OFFSET 18 #define L_SQL_EX_OFFSET 18
#define L_DATA_OFFSET LOAD_HEADER_LEN #define L_DATA_OFFSET LOAD_HEADER_LEN
/* Rotate event post-header */ /* Rotate event post-header */
@ -176,10 +178,10 @@ struct sql_ex_info
#define DF_FILE_ID_OFFSET 0 #define DF_FILE_ID_OFFSET 0
#define QUERY_EVENT_OVERHEAD (LOG_EVENT_HEADER_LEN+QUERY_HEADER_LEN) #define QUERY_EVENT_OVERHEAD (LOG_EVENT_HEADER_LEN+QUERY_HEADER_LEN)
#define QUERY_DATA_OFFSET (LOG_EVENT_HEADER_LEN+QUERY_HEADER_LEN) #define QUERY_DATA_OFFSET (LOG_EVENT_HEADER_LEN+QUERY_HEADER_LEN)
#define ROTATE_EVENT_OVERHEAD (LOG_EVENT_HEADER_LEN+ROTATE_HEADER_LEN) #define ROTATE_EVENT_OVERHEAD (LOG_EVENT_HEADER_LEN+ROTATE_HEADER_LEN)
#define LOAD_EVENT_OVERHEAD (LOG_EVENT_HEADER_LEN+LOAD_HEADER_LEN) #define LOAD_EVENT_OVERHEAD (LOG_EVENT_HEADER_LEN+LOAD_HEADER_LEN)
#define CREATE_FILE_EVENT_OVERHEAD (LOG_EVENT_HEADER_LEN+\ #define CREATE_FILE_EVENT_OVERHEAD (LOG_EVENT_HEADER_LEN+\
+LOAD_HEADER_LEN+CREATE_FILE_HEADER_LEN) +LOAD_HEADER_LEN+CREATE_FILE_HEADER_LEN)
#define DELETE_FILE_EVENT_OVERHEAD (LOG_EVENT_HEADER_LEN+DELETE_FILE_HEADER_LEN) #define DELETE_FILE_EVENT_OVERHEAD (LOG_EVENT_HEADER_LEN+DELETE_FILE_HEADER_LEN)
@ -192,13 +194,19 @@ struct sql_ex_info
#define LOG_EVENT_TIME_F 0x1 #define LOG_EVENT_TIME_F 0x1
#define LOG_EVENT_FORCED_ROTATE_F 0x2 #define LOG_EVENT_FORCED_ROTATE_F 0x2
enum Log_event_type { START_EVENT = 1, QUERY_EVENT =2, enum Log_event_type
STOP_EVENT=3, ROTATE_EVENT = 4, INTVAR_EVENT=5, {
LOAD_EVENT=6, SLAVE_EVENT=7, CREATE_FILE_EVENT=8, START_EVENT = 1, QUERY_EVENT =2, STOP_EVENT=3, ROTATE_EVENT = 4,
APPEND_BLOCK_EVENT=9, EXEC_LOAD_EVENT=10, DELETE_FILE_EVENT=11, INTVAR_EVENT=5, LOAD_EVENT=6, SLAVE_EVENT=7, CREATE_FILE_EVENT=8,
NEW_LOAD_EVENT=12}; APPEND_BLOCK_EVENT=9, EXEC_LOAD_EVENT=10, DELETE_FILE_EVENT=11,
enum Int_event_type { INVALID_INT_EVENT = 0, LAST_INSERT_ID_EVENT = 1, INSERT_ID_EVENT = 2 NEW_LOAD_EVENT=12
}; };
enum Int_event_type
{
INVALID_INT_EVENT = 0, LAST_INSERT_ID_EVENT = 1, INSERT_ID_EVENT = 2
};
#ifndef MYSQL_CLIENT #ifndef MYSQL_CLIENT
class String; class String;
@ -220,68 +228,15 @@ public:
uint16 flags; uint16 flags;
int cached_event_len; int cached_event_len;
char* temp_buf; char* temp_buf;
#ifndef MYSQL_CLIENT
#ifndef MYSQL_CLIENT
THD* thd; THD* thd;
#endif
static void *operator new(size_t size)
{
return (void*) my_malloc((uint)size, MYF(MY_WME|MY_FAE));
}
static void operator delete(void *ptr, size_t size)
{
my_free((gptr) ptr, MYF(MY_WME|MY_ALLOW_ZERO_PTR));
}
int write(IO_CACHE* file);
int write_header(IO_CACHE* file);
virtual int write_data(IO_CACHE* file)
{ return write_data_header(file) || write_data_body(file); }
virtual int write_data_header(IO_CACHE* file __attribute__((unused)))
{ return 0; }
virtual int write_data_body(IO_CACHE* file __attribute__((unused)))
{ return 0; }
virtual Log_event_type get_type_code() = 0;
virtual bool is_valid() = 0;
virtual bool get_cache_stmt() { return 0; }
Log_event(const char* buf, bool old_format);
#ifndef MYSQL_CLIENT
Log_event(THD* thd_arg, uint16 flags_arg = 0); Log_event(THD* thd_arg, uint16 flags_arg = 0);
#endif
virtual ~Log_event() { free_temp_buf();}
void register_temp_buf(char* buf) { temp_buf = buf; }
void free_temp_buf()
{
if (temp_buf)
{
my_free(temp_buf, MYF(0));
temp_buf = 0;
}
}
virtual int get_data_size() { return 0;}
virtual int get_data_body_offset() { return 0; }
int get_event_len() { return cached_event_len ? cached_event_len :
(cached_event_len = LOG_EVENT_HEADER_LEN + get_data_size()); }
#ifdef MYSQL_CLIENT
virtual void print(FILE* file, bool short_form = 0, char* last_db = 0) = 0;
void print_timestamp(FILE* file, time_t *ts = 0);
void print_header(FILE* file);
#endif
#ifndef MYSQL_CLIENT
// if mutex is 0, the read will proceed without mutex // if mutex is 0, the read will proceed without mutex
static Log_event* read_log_event(IO_CACHE* file, static Log_event* read_log_event(IO_CACHE* file,
pthread_mutex_t* log_lock, pthread_mutex_t* log_lock,
bool old_format); bool old_format);
#else // avoid having to link mysqlbinlog against libpthread
static Log_event* read_log_event(IO_CACHE* file, bool old_format);
#endif
static Log_event* read_log_event(const char* buf, int event_len,
const char **error, bool old_format);
const char* get_type_str();
#ifndef MYSQL_CLIENT
static int read_log_event(IO_CACHE* file, String* packet, static int read_log_event(IO_CACHE* file, String* packet,
pthread_mutex_t* log_lock); pthread_mutex_t* log_lock);
void set_log_pos(MYSQL_LOG* log); void set_log_pos(MYSQL_LOG* log);
@ -290,11 +245,58 @@ public:
static void init_show_field_list(List<Item>* field_list); static void init_show_field_list(List<Item>* field_list);
virtual int exec_event(struct st_relay_log_info* rli); virtual int exec_event(struct st_relay_log_info* rli);
virtual const char* get_db() virtual const char* get_db()
{ {
return thd ? thd->db : 0; return thd ? thd->db : 0;
} }
#endif #else
// avoid having to link mysqlbinlog against libpthread
static Log_event* read_log_event(IO_CACHE* file, bool old_format);
virtual void print(FILE* file, bool short_form = 0, char* last_db = 0) = 0;
void print_timestamp(FILE* file, time_t *ts = 0);
void print_header(FILE* file);
#endif
static void *operator new(size_t size)
{
return (void*) my_malloc((uint)size, MYF(MY_WME|MY_FAE));
}
static void operator delete(void *ptr, size_t size)
{
my_free((gptr) ptr, MYF(MY_WME|MY_ALLOW_ZERO_PTR));
}
int write(IO_CACHE* file);
int write_header(IO_CACHE* file);
virtual int write_data(IO_CACHE* file)
{ return write_data_header(file) || write_data_body(file); }
virtual int write_data_header(IO_CACHE* file __attribute__((unused)))
{ return 0; }
virtual int write_data_body(IO_CACHE* file __attribute__((unused)))
{ return 0; }
virtual Log_event_type get_type_code() = 0;
virtual bool is_valid() = 0;
virtual bool get_cache_stmt() { return 0; }
Log_event(const char* buf, bool old_format);
virtual ~Log_event() { free_temp_buf();}
void register_temp_buf(char* buf) { temp_buf = buf; }
void free_temp_buf()
{
if (temp_buf)
{
my_free(temp_buf, MYF(0));
temp_buf = 0;
}
}
virtual int get_data_size() { return 0;}
virtual int get_data_body_offset() { return 0; }
int get_event_len()
{
return (cached_event_len ? cached_event_len :
(cached_event_len = LOG_EVENT_HEADER_LEN + get_data_size()));
}
static Log_event* read_log_event(const char* buf, int event_len,
const char **error, bool old_format);
const char* get_type_str();
}; };
@ -305,13 +307,16 @@ protected:
public: public:
const char* query; const char* query;
const char* db; const char* db;
uint32 q_len; // if we already know the length of the query string /*
// we pass it here, so we would not have to call strlen() If we already know the length of the query string
// otherwise, set it to 0, in which case, we compute it with strlen() we pass it with q_len, so we would not have to call strlen()
otherwise, set it to 0, in which case, we compute it with strlen()
*/
uint32 q_len;
uint32 db_len; uint32 db_len;
uint16 error_code; uint16 error_code;
ulong thread_id; ulong thread_id;
#if !defined(MYSQL_CLIENT) #ifndef MYSQL_CLIENT
bool cache_stmt; bool cache_stmt;
Query_log_event(THD* thd_arg, const char* query_arg, Query_log_event(THD* thd_arg, const char* query_arg,
@ -320,6 +325,8 @@ public:
void pack_info(String* packet); void pack_info(String* packet);
int exec_event(struct st_relay_log_info* rli); int exec_event(struct st_relay_log_info* rli);
bool get_cache_stmt() { return cache_stmt; } bool get_cache_stmt() { return cache_stmt; }
#else
void print(FILE* file, bool short_form = 0, char* last_db = 0);
#endif #endif
Query_log_event(const char* buf, int event_len, bool old_format); Query_log_event(const char* buf, int event_len, bool old_format);
@ -336,17 +343,15 @@ public:
bool is_valid() { return query != 0; } bool is_valid() { return query != 0; }
int get_data_size() int get_data_size()
{ {
return q_len + db_len + 2 + return (q_len + db_len + 2
4 // thread_id + 4 // thread_id
+ 4 // exec_time + 4 // exec_time
+ 2 // error_code + 2 // error_code
; );
} }
#ifdef MYSQL_CLIENT
void print(FILE* file, bool short_form = 0, char* last_db = 0);
#endif
}; };
class Slave_log_event: public Log_event class Slave_log_event: public Log_event
{ {
protected: protected:
@ -364,18 +369,16 @@ public:
Slave_log_event(THD* thd_arg, struct st_relay_log_info* rli); Slave_log_event(THD* thd_arg, struct st_relay_log_info* rli);
void pack_info(String* packet); void pack_info(String* packet);
int exec_event(struct st_relay_log_info* rli); int exec_event(struct st_relay_log_info* rli);
#endif #else
void print(FILE* file, bool short_form = 0, char* last_db = 0);
#endif
Slave_log_event(const char* buf, int event_len); Slave_log_event(const char* buf, int event_len);
~Slave_log_event(); ~Slave_log_event();
int get_data_size(); int get_data_size();
bool is_valid() { return master_host != 0; } bool is_valid() { return master_host != 0; }
Log_event_type get_type_code() { return SLAVE_EVENT; } Log_event_type get_type_code() { return SLAVE_EVENT; }
#ifdef MYSQL_CLIENT
void print(FILE* file, bool short_form = 0, char* last_db = 0);
#endif
int write_data(IO_CACHE* file ); int write_data(IO_CACHE* file );
}; };
class Load_log_event: public Log_event class Load_log_event: public Log_event
@ -399,7 +402,7 @@ public:
uint32 skip_lines; uint32 skip_lines;
sql_ex_info sql_ex; sql_ex_info sql_ex;
#if !defined(MYSQL_CLIENT) #ifndef MYSQL_CLIENT
String field_lens_buf; String field_lens_buf;
String fields_buf; String fields_buf;
@ -414,6 +417,8 @@ public:
return exec_event(thd->slave_net,rli); return exec_event(thd->slave_net,rli);
} }
int exec_event(NET* net, struct st_relay_log_info* rli); int exec_event(NET* net, struct st_relay_log_info* rli);
#else
void print(FILE* file, bool short_form = 0, char* last_db = 0);
#endif #endif
Load_log_event(const char* buf, int event_len, bool old_format); Load_log_event(const char* buf, int event_len, bool old_format);
@ -427,18 +432,14 @@ public:
bool is_valid() { return table_name != 0; } bool is_valid() { return table_name != 0; }
int get_data_size() int get_data_size()
{ {
return table_name_len + 2 + db_len + 2 + fname_len return (table_name_len + 2 + db_len + 2 + fname_len
+ 4 // thread_id + 4 // thread_id
+ 4 // exec_time + 4 // exec_time
+ 4 // skip_lines + 4 // skip_lines
+ 4 // field block len + 4 // field block len
+ sql_ex.data_size() + field_block_len + num_fields; + sql_ex.data_size() + field_block_len + num_fields);
;
} }
int get_data_body_offset() { return LOAD_EVENT_OVERHEAD; } int get_data_body_offset() { return LOAD_EVENT_OVERHEAD; }
#ifdef MYSQL_CLIENT
void print(FILE* file, bool short_form = 0, char* last_db = 0);
#endif
}; };
extern char server_version[SERVER_VERSION_LENGTH]; extern char server_version[SERVER_VERSION_LENGTH];
@ -449,13 +450,19 @@ public:
uint32 created; uint32 created;
uint16 binlog_version; uint16 binlog_version;
char server_version[ST_SERVER_VER_LEN]; char server_version[ST_SERVER_VER_LEN];
#ifndef MYSQL_CLIENT
#ifndef MYSQL_CLIENT
Start_log_event() :Log_event((THD*)0),binlog_version(BINLOG_VERSION) Start_log_event() :Log_event((THD*)0),binlog_version(BINLOG_VERSION)
{ {
created = (uint32) when; created = (uint32) when;
memcpy(server_version, ::server_version, ST_SERVER_VER_LEN); memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
} }
void pack_info(String* packet);
int exec_event(struct st_relay_log_info* rli);
#else
void print(FILE* file, bool short_form = 0, char* last_db = 0);
#endif #endif
Start_log_event(const char* buf, bool old_format); Start_log_event(const char* buf, bool old_format);
~Start_log_event() {} ~Start_log_event() {}
Log_event_type get_type_code() { return START_EVENT;} Log_event_type get_type_code() { return START_EVENT;}
@ -465,25 +472,25 @@ public:
{ {
return START_HEADER_LEN; return START_HEADER_LEN;
} }
#ifndef MYSQL_CLIENT
void pack_info(String* packet);
int exec_event(struct st_relay_log_info* rli);
#endif
#ifdef MYSQL_CLIENT
void print(FILE* file, bool short_form = 0, char* last_db = 0);
#endif
}; };
class Intvar_log_event: public Log_event class Intvar_log_event: public Log_event
{ {
public: public:
ulonglong val; ulonglong val;
uchar type; uchar type;
#ifndef MYSQL_CLIENT #ifndef MYSQL_CLIENT
Intvar_log_event(THD* thd_arg,uchar type_arg, ulonglong val_arg) Intvar_log_event(THD* thd_arg,uchar type_arg, ulonglong val_arg)
:Log_event(thd_arg),val(val_arg),type(type_arg) :Log_event(thd_arg),val(val_arg),type(type_arg)
{} {}
#endif void pack_info(String* packet);
int exec_event(struct st_relay_log_info* rli);
#else
void print(FILE* file, bool short_form = 0, char* last_db = 0);
#endif
Intvar_log_event(const char* buf, bool old_format); Intvar_log_event(const char* buf, bool old_format);
~Intvar_log_event() {} ~Intvar_log_event() {}
Log_event_type get_type_code() { return INTVAR_EVENT;} Log_event_type get_type_code() { return INTVAR_EVENT;}
@ -491,38 +498,29 @@ public:
int get_data_size() { return sizeof(type) + sizeof(val);} int get_data_size() { return sizeof(type) + sizeof(val);}
int write_data(IO_CACHE* file); int write_data(IO_CACHE* file);
bool is_valid() { return 1; } bool is_valid() { return 1; }
#ifndef MYSQL_CLIENT
void pack_info(String* packet);
int exec_event(struct st_relay_log_info* rli);
#endif
#ifdef MYSQL_CLIENT
void print(FILE* file, bool short_form = 0, char* last_db = 0);
#endif
}; };
class Stop_log_event: public Log_event class Stop_log_event: public Log_event
{ {
public: public:
#ifndef MYSQL_CLIENT #ifndef MYSQL_CLIENT
Stop_log_event() :Log_event((THD*)0) Stop_log_event() :Log_event((THD*)0)
{} {}
int exec_event(struct st_relay_log_info* rli);
#else
void print(FILE* file, bool short_form = 0, char* last_db = 0);
#endif #endif
Stop_log_event(const char* buf, bool old_format):Log_event(buf,
old_format) Stop_log_event(const char* buf, bool old_format):
{ Log_event(buf, old_format)
} {}
~Stop_log_event() {} ~Stop_log_event() {}
Log_event_type get_type_code() { return STOP_EVENT;} Log_event_type get_type_code() { return STOP_EVENT;}
bool is_valid() { return 1; } bool is_valid() { return 1; }
#ifdef MYSQL_CLIENT
void print(FILE* file, bool short_form = 0, char* last_db = 0);
#endif
#ifndef MYSQL_CLIENT
int exec_event(struct st_relay_log_info* rli);
#endif
}; };
class Rotate_log_event: public Log_event class Rotate_log_event: public Log_event
{ {
public: public:
@ -532,14 +530,18 @@ public:
bool alloced; bool alloced;
#ifndef MYSQL_CLIENT #ifndef MYSQL_CLIENT
Rotate_log_event(THD* thd_arg, const char* new_log_ident_arg, Rotate_log_event(THD* thd_arg, const char* new_log_ident_arg,
uint ident_len_arg = 0,ulonglong pos_arg = 4) : uint ident_len_arg = 0,ulonglong pos_arg = 4)
Log_event(thd_arg), : Log_event(thd_arg), new_log_ident(new_log_ident_arg),
new_log_ident(new_log_ident_arg),
ident_len(ident_len_arg ? ident_len_arg : ident_len(ident_len_arg ? ident_len_arg :
(uint) strlen(new_log_ident_arg)), pos(pos_arg), (uint) strlen(new_log_ident_arg)), pos(pos_arg),
alloced(0) alloced(0)
{} {}
#endif void pack_info(String* packet);
int exec_event(struct st_relay_log_info* rli);
#else
void print(FILE* file, bool short_form = 0, char* last_db = 0);
#endif
Rotate_log_event(const char* buf, int event_len, bool old_format); Rotate_log_event(const char* buf, int event_len, bool old_format);
~Rotate_log_event() ~Rotate_log_event()
{ {
@ -550,13 +552,6 @@ public:
int get_data_size() { return ident_len + ROTATE_HEADER_LEN;} int get_data_size() { return ident_len + ROTATE_HEADER_LEN;}
bool is_valid() { return new_log_ident != 0; } bool is_valid() { return new_log_ident != 0; }
int write_data(IO_CACHE* file); int write_data(IO_CACHE* file);
#ifdef MYSQL_CLIENT
void print(FILE* file, bool short_form = 0, char* last_db = 0);
#endif
#ifndef MYSQL_CLIENT
void pack_info(String* packet);
int exec_event(struct st_relay_log_info* rli);
#endif
}; };
/* the classes below are for the new LOAD DATA INFILE logging */ /* the classes below are for the new LOAD DATA INFILE logging */
@ -564,51 +559,59 @@ public:
class Create_file_log_event: public Load_log_event class Create_file_log_event: public Load_log_event
{ {
protected: protected:
// pretend we are Load event, so we can write out just /*
// our Load part - used on the slave when writing event out to Pretend we are Load event, so we can write out just
// SQL_LOAD-*.info file our Load part - used on the slave when writing event out to
SQL_LOAD-*.info file
*/
bool fake_base; bool fake_base;
public: public:
char* block; char* block;
uint block_len; uint block_len;
uint file_id; uint file_id;
bool inited_from_old; bool inited_from_old;
#ifndef MYSQL_CLIENT #ifndef MYSQL_CLIENT
Create_file_log_event(THD* thd, sql_exchange* ex, const char* db_arg, Create_file_log_event(THD* thd, sql_exchange* ex, const char* db_arg,
const char* table_name_arg, const char* table_name_arg,
List<Item>& fields_arg, List<Item>& fields_arg,
enum enum_duplicates handle_dup, enum enum_duplicates handle_dup,
char* block_arg, uint block_len_arg); char* block_arg, uint block_len_arg);
void pack_info(String* packet);
int exec_event(struct st_relay_log_info* rli);
#else
void print(FILE* file, bool short_form = 0, char* last_db = 0);
#endif #endif
Create_file_log_event(const char* buf, int event_len, bool old_format); Create_file_log_event(const char* buf, int event_len, bool old_format);
~Create_file_log_event() ~Create_file_log_event() {}
{
}
Log_event_type get_type_code() Log_event_type get_type_code()
{ {
return fake_base ? Load_log_event::get_type_code() : CREATE_FILE_EVENT; return fake_base ? Load_log_event::get_type_code() : CREATE_FILE_EVENT;
} }
int get_data_size() { return fake_base ? Load_log_event::get_data_size() : int get_data_size()
Load_log_event::get_data_size() + {
4 + 1 + block_len;} return (fake_base ? Load_log_event::get_data_size() :
int get_data_body_offset() { return fake_base ? LOAD_EVENT_OVERHEAD: Load_log_event::get_data_size() +
LOAD_EVENT_OVERHEAD + CREATE_FILE_HEADER_LEN; } 4 + 1 + block_len);
}
int get_data_body_offset()
{
return (fake_base ? LOAD_EVENT_OVERHEAD:
LOAD_EVENT_OVERHEAD + CREATE_FILE_HEADER_LEN);
}
bool is_valid() { return inited_from_old || block != 0; } bool is_valid() { return inited_from_old || block != 0; }
int write_data_header(IO_CACHE* file); int write_data_header(IO_CACHE* file);
int write_data_body(IO_CACHE* file); int write_data_body(IO_CACHE* file);
int write_base(IO_CACHE* file); // cut out Create_file extentions and /*
// write it as Load event - used on the slave Cut out Create_file extentions and
write it as Load event - used on the slave
#ifdef MYSQL_CLIENT */
void print(FILE* file, bool short_form = 0, char* last_db = 0); int write_base(IO_CACHE* file);
#endif
#ifndef MYSQL_CLIENT
void pack_info(String* packet);
int exec_event(struct st_relay_log_info* rli);
#endif
}; };
class Append_block_log_event: public Log_event class Append_block_log_event: public Log_event
{ {
public: public:
@ -618,27 +621,22 @@ public:
#ifndef MYSQL_CLIENT #ifndef MYSQL_CLIENT
Append_block_log_event(THD* thd, char* block_arg, Append_block_log_event(THD* thd, char* block_arg,
uint block_len_arg); uint block_len_arg);
int exec_event(struct st_relay_log_info* rli); int exec_event(struct st_relay_log_info* rli);
#endif void pack_info(String* packet);
#else
void print(FILE* file, bool short_form = 0, char* last_db = 0);
#endif
Append_block_log_event(const char* buf, int event_len); Append_block_log_event(const char* buf, int event_len);
~Append_block_log_event() ~Append_block_log_event() {}
{
}
Log_event_type get_type_code() { return APPEND_BLOCK_EVENT;} Log_event_type get_type_code() { return APPEND_BLOCK_EVENT;}
int get_data_size() { return block_len + APPEND_BLOCK_HEADER_LEN ;} int get_data_size() { return block_len + APPEND_BLOCK_HEADER_LEN ;}
bool is_valid() { return block != 0; } bool is_valid() { return block != 0; }
int write_data(IO_CACHE* file); int write_data(IO_CACHE* file);
#ifdef MYSQL_CLIENT
void print(FILE* file, bool short_form = 0, char* last_db = 0);
#endif
#ifndef MYSQL_CLIENT
void pack_info(String* packet);
#endif
}; };
class Delete_file_log_event: public Log_event class Delete_file_log_event: public Log_event
{ {
public: public:
@ -646,24 +644,18 @@ public:
#ifndef MYSQL_CLIENT #ifndef MYSQL_CLIENT
Delete_file_log_event(THD* thd); Delete_file_log_event(THD* thd);
void pack_info(String* packet);
int exec_event(struct st_relay_log_info* rli);
#else
void print(FILE* file, bool short_form = 0, char* last_db = 0);
#endif #endif
Delete_file_log_event(const char* buf, int event_len); Delete_file_log_event(const char* buf, int event_len);
~Delete_file_log_event() ~Delete_file_log_event() {}
{
}
Log_event_type get_type_code() { return DELETE_FILE_EVENT;} Log_event_type get_type_code() { return DELETE_FILE_EVENT;}
int get_data_size() { return DELETE_FILE_HEADER_LEN ;} int get_data_size() { return DELETE_FILE_HEADER_LEN ;}
bool is_valid() { return file_id != 0; } bool is_valid() { return file_id != 0; }
int write_data(IO_CACHE* file); int write_data(IO_CACHE* file);
#ifdef MYSQL_CLIENT
void print(FILE* file, bool short_form = 0, char* last_db = 0);
#endif
#ifndef MYSQL_CLIENT
void pack_info(String* packet);
int exec_event(struct st_relay_log_info* rli);
#endif
}; };
class Execute_load_log_event: public Log_event class Execute_load_log_event: public Log_event
@ -673,27 +665,18 @@ public:
#ifndef MYSQL_CLIENT #ifndef MYSQL_CLIENT
Execute_load_log_event(THD* thd); Execute_load_log_event(THD* thd);
void pack_info(String* packet);
int exec_event(struct st_relay_log_info* rli);
#else
void print(FILE* file, bool short_form = 0, char* last_db = 0);
#endif #endif
Execute_load_log_event(const char* buf, int event_len); Execute_load_log_event(const char* buf, int event_len);
~Execute_load_log_event() ~Execute_load_log_event() {}
{
}
Log_event_type get_type_code() { return EXEC_LOAD_EVENT;} Log_event_type get_type_code() { return EXEC_LOAD_EVENT;}
int get_data_size() { return EXEC_LOAD_HEADER_LEN ;} int get_data_size() { return EXEC_LOAD_HEADER_LEN ;}
bool is_valid() { return file_id != 0; } bool is_valid() { return file_id != 0; }
int write_data(IO_CACHE* file); int write_data(IO_CACHE* file);
#ifdef MYSQL_CLIENT
void print(FILE* file, bool short_form = 0, char* last_db = 0);
#endif
#ifndef MYSQL_CLIENT
void pack_info(String* packet);
int exec_event(struct st_relay_log_info* rli);
#endif
}; };
#endif #endif /* _log_event_h */

View file

@ -354,7 +354,7 @@ mc_net_safe_read(MYSQL *mysql)
if (socket_errno != SOCKET_EINTR) if (socket_errno != SOCKET_EINTR)
{ {
mc_end_server(mysql); mc_end_server(mysql);
if(net->last_errno != ER_NET_PACKET_TOO_LARGE) if (net->last_errno != ER_NET_PACKET_TOO_LARGE)
{ {
net->last_errno=CR_SERVER_LOST; net->last_errno=CR_SERVER_LOST;
strmov(net->last_error,ER(net->last_errno)); strmov(net->last_error,ER(net->last_errno));
@ -375,7 +375,7 @@ max_allowed_packet on this server");
net->last_errno=uint2korr(pos); net->last_errno=uint2korr(pos);
pos+=2; pos+=2;
len-=2; len-=2;
if(!net->last_errno) if (!net->last_errno)
net->last_errno = CR_UNKNOWN_ERROR; net->last_errno = CR_UNKNOWN_ERROR;
} }
else else
@ -791,7 +791,7 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
else else
{ {
user = getenv("USER"); user = getenv("USER");
if(!user) user = "mysql"; if (!user) user = "mysql";
strmov((char*) buff+5, user ); strmov((char*) buff+5, user );
} }

View file

@ -48,7 +48,7 @@ char *sql_strmake(const char *str,uint len);
gptr sql_memdup(const void * ptr,unsigned size); gptr sql_memdup(const void * ptr,unsigned size);
void sql_element_free(void *ptr); void sql_element_free(void *ptr);
void kill_one_thread(THD *thd, ulong id); void kill_one_thread(THD *thd, ulong id);
int net_request_file(NET* net, const char* fname); bool net_request_file(NET* net, const char* fname);
char* query_table_status(THD *thd,const char *db,const char *table_name); char* query_table_status(THD *thd,const char *db,const char *table_name);
#define x_free(A) { my_free((gptr) (A),MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR)); } #define x_free(A) { my_free((gptr) (A),MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR)); }
@ -200,18 +200,20 @@ char* query_table_status(THD *thd,const char *db,const char *table_name);
#define RAID_BLOCK_SIZE 1024 #define RAID_BLOCK_SIZE 1024
// Sync points allow us to force the server to reach a certain line of code
// and block there until the client tells the server it is ok to go on.
// The client tells the server to block with SELECT GET_LOCK()
// and unblocks it with SELECT RELEASE_LOCK(). Used for debugging difficult
// concurrency problems
#ifdef EXTRA_DEBUG #ifdef EXTRA_DEBUG
/*
Sync points allow us to force the server to reach a certain line of code
and block there until the client tells the server it is ok to go on.
The client tells the server to block with SELECT GET_LOCK()
and unblocks it with SELECT RELEASE_LOCK(). Used for debugging difficult
concurrency problems
*/
#define DBUG_SYNC_POINT(lock_name,lock_timeout) \ #define DBUG_SYNC_POINT(lock_name,lock_timeout) \
debug_sync_point(lock_name,lock_timeout) debug_sync_point(lock_name,lock_timeout)
void debug_sync_point(const char* lock_name, uint lock_timeout); void debug_sync_point(const char* lock_name, uint lock_timeout);
#else #else
#define DBUG_SYNC_POINT(lock_name,lock_timeout) #define DBUG_SYNC_POINT(lock_name,lock_timeout)
#endif #endif /* EXTRA_DEBUG */
/* BINLOG_DUMP options */ /* BINLOG_DUMP options */
@ -376,9 +378,6 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
HA_CREATE_INFO *create_info, HA_CREATE_INFO *create_info,
List<create_field> &fields, List<Key> &keys, List<create_field> &fields, List<Key> &keys,
bool tmp_table, bool no_log); bool tmp_table, bool no_log);
// no_log is needed for the case of CREATE TABLE ... SELECT , as the logging
// will be done later in sql_insert.cc
TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
const char *db, const char *name, const char *db, const char *name,
List<create_field> *extra_fields, List<create_field> *extra_fields,

View file

@ -238,9 +238,10 @@ SHOW_COMP_OPTION have_query_cache=SHOW_OPTION_NO;
bool opt_skip_slave_start = 0; // If set, slave is not autostarted bool opt_skip_slave_start = 0; // If set, slave is not autostarted
/* if set, some standard measures to enforce /*
slave data intergity will not be performed If set, some standard measures to enforce slave data integrity will not
*/ be performed
*/
bool opt_reckless_slave = 0; bool opt_reckless_slave = 0;
static bool opt_do_pstack = 0; static bool opt_do_pstack = 0;
static ulong opt_specialflag=SPECIAL_ENGLISH; static ulong opt_specialflag=SPECIAL_ENGLISH;
@ -279,7 +280,7 @@ char glob_hostname[FN_REFLEN];
#include "sslopt-vars.h" #include "sslopt-vars.h"
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
char *des_key_file = 0; char *des_key_file = 0;
struct st_VioSSLAcceptorFd * ssl_acceptor_fd = 0; struct st_VioSSLAcceptorFd *ssl_acceptor_fd= 0;
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
I_List <i_string_pair> replicate_rewrite_db; I_List <i_string_pair> replicate_rewrite_db;
@ -582,9 +583,7 @@ static void close_connections(void)
(void) pthread_mutex_unlock(&LOCK_thread_count); // For unlink from list (void) pthread_mutex_unlock(&LOCK_thread_count); // For unlink from list
if (thread_count) if (thread_count)
{
sleep(1); // Give threads time to die sleep(1); // Give threads time to die
}
/* Force remaining threads to die by closing the connection to the client */ /* Force remaining threads to die by closing the connection to the client */
@ -1185,9 +1184,8 @@ void end_thread(THD *thd, bool put_in_cache)
DBUG_PRINT("info", ("sending a broadcast")) DBUG_PRINT("info", ("sending a broadcast"))
/* Tell main we are ready */ /* Tell main we are ready */
// TODO: explain why we broadcast outside of the lock or
// fix the bug - Sasha
(void) pthread_mutex_unlock(&LOCK_thread_count); (void) pthread_mutex_unlock(&LOCK_thread_count);
/* It's safe to broadcast outside a lock (COND... is not deleted here) */
(void) pthread_cond_broadcast(&COND_thread_count); (void) pthread_cond_broadcast(&COND_thread_count);
DBUG_PRINT("info", ("unlocked thread_count mutex")) DBUG_PRINT("info", ("unlocked thread_count mutex"))
#ifdef ONE_THREAD #ifdef ONE_THREAD
@ -1226,11 +1224,11 @@ void flush_thread_cache()
} }
/* /*
** Aborts a thread nicely. Commes here on SIGPIPE Aborts a thread nicely. Commes here on SIGPIPE
** TODO: One should have to fix that thr_alarm know about this TODO: One should have to fix that thr_alarm know about this
** thread too thread too.
*/ */
#ifdef THREAD_SPECIFIC_SIGPIPE #ifdef THREAD_SPECIFIC_SIGPIPE
static sig_handler abort_thread(int sig __attribute__((unused))) static sig_handler abort_thread(int sig __attribute__((unused)))
@ -1244,9 +1242,9 @@ static sig_handler abort_thread(int sig __attribute__((unused)))
#endif #endif
/****************************************************************************** /******************************************************************************
** Setup a signal thread with handles all signals Setup a signal thread with handles all signals.
** Because linux doesn't support scemas use a mutex to check that Because Linux doesn't support schemas use a mutex to check that
** the signal thread is ready before continuing the signal thread is ready before continuing
******************************************************************************/ ******************************************************************************/
#if defined(__WIN__) || defined(OS2) #if defined(__WIN__) || defined(OS2)
@ -1269,7 +1267,8 @@ static void start_signal_handler(void)
#elif defined(__EMX__) #elif defined(__EMX__)
static void sig_reload(int signo) static void sig_reload(int signo)
{ {
reload_acl_and_cache((THD*) 0,REFRESH_LOG, (TABLE_LIST*) 0); // Flush everything // Flush everything
reload_acl_and_cache((THD*) 0,REFRESH_LOG, (TABLE_LIST*) 0);
signal(signo, SIG_ACK); signal(signo, SIG_ACK);
} }
@ -1357,7 +1356,7 @@ the thread stack. Please read http://www.mysql.com/doc/L/i/Linux.html\n\n",
#endif /* HAVE_LINUXTHREADS */ #endif /* HAVE_LINUXTHREADS */
#ifdef HAVE_STACKTRACE #ifdef HAVE_STACKTRACE
if(!(test_flags & TEST_NO_STACKTRACE)) if (!(test_flags & TEST_NO_STACKTRACE))
{ {
fprintf(stderr,"thd=%p\n",thd); fprintf(stderr,"thd=%p\n",thd);
print_stacktrace(thd ? (gptr) thd->thread_stack : (gptr) 0, print_stacktrace(thd ? (gptr) thd->thread_stack : (gptr) 0,
@ -1476,9 +1475,7 @@ static void start_signal_handler(void)
} }
/* /* This threads handles all signals and alarms */
** This threads handles all signals and alarms
*/
/* ARGSUSED */ /* ARGSUSED */
static void *signal_hand(void *arg __attribute__((unused))) static void *signal_hand(void *arg __attribute__((unused)))
@ -1596,8 +1593,8 @@ static void *signal_hand(void *arg __attribute__((unused)))
/* /*
** All global error messages are sent here where the first one is stored for All global error messages are sent here where the first one is stored for
** the client the client
*/ */
@ -1689,6 +1686,7 @@ pthread_handler_decl(handle_shutdown,arg)
} }
#endif #endif
const char *load_default_groups[]= { "mysqld","server",0 }; const char *load_default_groups[]= { "mysqld","server",0 };
#ifdef HAVE_LIBWRAP #ifdef HAVE_LIBWRAP
@ -1739,9 +1737,10 @@ int main(int argc, char **argv)
my_umask=0660; // Default umask for new files my_umask=0660; // Default umask for new files
my_umask_dir=0700; // Default umask for new directories my_umask_dir=0700; // Default umask for new directories
MAIN_THD; MAIN_THD;
/* initialize signal_th and shutdown_th to main_th for default value /*
as we need to initialize them to something safe. They are used Initialize signal_th and shutdown_th to main_th for default value
when compiled with safemalloc as we need to initialize them to something safe. They are used
when compiled with safemalloc.
*/ */
SIGNAL_THD; SIGNAL_THD;
SHUTDOWN_THD; SHUTDOWN_THD;
@ -1845,13 +1844,13 @@ int main(int argc, char **argv)
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
if (opt_use_ssl) if (opt_use_ssl)
{ {
ssl_acceptor_fd = new_VioSSLAcceptorFd(opt_ssl_key, opt_ssl_cert, /* having ssl_acceptor_fd != 0 signals the use of SSL */
opt_ssl_ca, opt_ssl_capath, ssl_acceptor_fd= new_VioSSLAcceptorFd(opt_ssl_key, opt_ssl_cert,
opt_ssl_cipher); opt_ssl_ca, opt_ssl_capath,
DBUG_PRINT("info",("ssl_acceptor_fd: %p",ssl_acceptor_fd)); opt_ssl_cipher);
DBUG_PRINT("info",("ssl_acceptor_fd: %p", ssl_acceptor_fd));
if (!ssl_acceptor_fd) if (!ssl_acceptor_fd)
opt_use_ssl = 0; opt_use_ssl = 0;
/* having ssl_acceptor_fd != 0 signals the use of SSL */
} }
if (des_key_file) if (des_key_file)
load_des_key_file(des_key_file); load_des_key_file(des_key_file);
@ -2186,11 +2185,12 @@ The server will not act as a slave.");
} }
/****************************************************************************
Main and thread entry function for Win32
(all this is needed only to run mysqld as a service on WinNT)
****************************************************************************/
#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY) #if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
/* ------------------------------------------------------------------------
main and thread entry function for Win32
(all this is needed only to run mysqld as a service on WinNT)
-------------------------------------------------------------------------- */
int mysql_service(void *p) int mysql_service(void *p)
{ {
win_main(Service.my_argc, Service.my_argv); win_main(Service.my_argc, Service.my_argv);
@ -2202,8 +2202,8 @@ int main(int argc, char **argv)
if (Service.GetOS()) /* true NT family */ if (Service.GetOS()) /* true NT family */
{ {
char file_path[FN_REFLEN]; char file_path[FN_REFLEN];
my_path(file_path, argv[0], ""); /* Find name in path */ my_path(file_path, argv[0], ""); /* Find name in path */
fn_format(file_path,argv[0],file_path,"",1+4+16); /* Force use of full path */ fn_format(file_path,argv[0],file_path,"",1+4+16); /* Force full path */
if (argc == 2) if (argc == 2)
{ {
@ -2268,10 +2268,14 @@ int main(int argc, char **argv)
mysql_service(NULL); mysql_service(NULL);
return 0; return 0;
} }
/* ------------------------------------------------------------------------ */
#endif #endif
/*
Execute all commands from a file. Used by the mysql_install_db script to
create MySQL privilege tables without having to start a full MySQL server.
*/
static int bootstrap(FILE *file) static int bootstrap(FILE *file)
{ {
THD *thd= new THD; THD *thd= new THD;
@ -2476,10 +2480,8 @@ pthread_handler_decl(handle_connections_sockets,arg __attribute__((unused)))
MAYBE_BROKEN_SYSCALL; MAYBE_BROKEN_SYSCALL;
break; break;
} }
/*
** Is this a new connection request
*/
/* Is this a new connection request ? */
#ifdef HAVE_SYS_UN_H #ifdef HAVE_SYS_UN_H
if (FD_ISSET(unix_sock,&readFDs)) if (FD_ISSET(unix_sock,&readFDs))
{ {
@ -2717,109 +2719,109 @@ pthread_handler_decl(handle_connections_namedpipes,arg)
******************************************************************************/ ******************************************************************************/
enum options { enum options {
OPT_ISAM_LOG=256, OPT_SKIP_NEW, OPT_ISAM_LOG=256, OPT_SKIP_NEW,
OPT_SKIP_GRANT, OPT_SKIP_LOCK, OPT_SKIP_GRANT, OPT_SKIP_LOCK,
OPT_ENABLE_LOCK, OPT_USE_LOCKING, OPT_ENABLE_LOCK, OPT_USE_LOCKING,
OPT_SOCKET, OPT_UPDATE_LOG, OPT_SOCKET, OPT_UPDATE_LOG,
OPT_BIN_LOG, OPT_SKIP_RESOLVE, OPT_BIN_LOG, OPT_SKIP_RESOLVE,
OPT_SKIP_NETWORKING, OPT_BIN_LOG_INDEX, OPT_SKIP_NETWORKING, OPT_BIN_LOG_INDEX,
OPT_BIND_ADDRESS, OPT_PID_FILE, OPT_BIND_ADDRESS, OPT_PID_FILE,
OPT_SKIP_PRIOR, OPT_BIG_TABLES, OPT_SKIP_PRIOR, OPT_BIG_TABLES,
OPT_STANDALONE, OPT_ONE_THREAD, OPT_STANDALONE, OPT_ONE_THREAD,
OPT_CONSOLE, OPT_LOW_PRIORITY_UPDATES, OPT_CONSOLE, OPT_LOW_PRIORITY_UPDATES,
OPT_SKIP_HOST_CACHE, OPT_LONG_FORMAT, OPT_SKIP_HOST_CACHE, OPT_LONG_FORMAT,
OPT_FLUSH, OPT_SAFE, OPT_FLUSH, OPT_SAFE,
OPT_BOOTSTRAP, OPT_SKIP_SHOW_DB, OPT_BOOTSTRAP, OPT_SKIP_SHOW_DB,
OPT_TABLE_TYPE, OPT_INIT_FILE, OPT_TABLE_TYPE, OPT_INIT_FILE,
OPT_DELAY_KEY_WRITE, OPT_SLOW_QUERY_LOG, OPT_DELAY_KEY_WRITE, OPT_SLOW_QUERY_LOG,
OPT_USE_DELAY_KEY_WRITE, OPT_CHARSETS_DIR, OPT_USE_DELAY_KEY_WRITE, OPT_CHARSETS_DIR,
OPT_BDB_HOME, OPT_BDB_LOG, OPT_BDB_HOME, OPT_BDB_LOG,
OPT_BDB_TMP, OPT_BDB_NOSYNC, OPT_BDB_TMP, OPT_BDB_NOSYNC,
OPT_BDB_LOCK, OPT_BDB_SKIP, OPT_BDB_LOCK, OPT_BDB_SKIP,
OPT_BDB_NO_RECOVER, OPT_BDB_SHARED, OPT_BDB_NO_RECOVER, OPT_BDB_SHARED,
OPT_MASTER_HOST, OPT_MASTER_USER, OPT_MASTER_HOST, OPT_MASTER_USER,
OPT_MASTER_PASSWORD, OPT_MASTER_PORT, OPT_MASTER_PASSWORD, OPT_MASTER_PORT,
OPT_MASTER_INFO_FILE, OPT_MASTER_CONNECT_RETRY, OPT_MASTER_INFO_FILE, OPT_MASTER_CONNECT_RETRY,
OPT_MASTER_RETRY_COUNT, OPT_MASTER_RETRY_COUNT,
OPT_MASTER_SSL, OPT_MASTER_SSL_KEY, OPT_MASTER_SSL, OPT_MASTER_SSL_KEY,
OPT_MASTER_SSL_CERT, OPT_MASTER_SSL_CERT,
OPT_SQL_BIN_UPDATE_SAME, OPT_REPLICATE_DO_DB, OPT_SQL_BIN_UPDATE_SAME, OPT_REPLICATE_DO_DB,
OPT_REPLICATE_IGNORE_DB, OPT_LOG_SLAVE_UPDATES, OPT_REPLICATE_IGNORE_DB, OPT_LOG_SLAVE_UPDATES,
OPT_BINLOG_DO_DB, OPT_BINLOG_IGNORE_DB, OPT_BINLOG_DO_DB, OPT_BINLOG_IGNORE_DB,
OPT_WANT_CORE, OPT_CONCURRENT_INSERT, OPT_WANT_CORE, OPT_CONCURRENT_INSERT,
OPT_MEMLOCK, OPT_MYISAM_RECOVER, OPT_MEMLOCK, OPT_MYISAM_RECOVER,
OPT_REPLICATE_REWRITE_DB, OPT_SERVER_ID, OPT_REPLICATE_REWRITE_DB, OPT_SERVER_ID,
OPT_SKIP_SLAVE_START, OPT_SKIP_INNOBASE, OPT_SKIP_SLAVE_START, OPT_SKIP_INNOBASE,
OPT_SAFEMALLOC_MEM_LIMIT, OPT_REPLICATE_DO_TABLE, OPT_SAFEMALLOC_MEM_LIMIT, OPT_REPLICATE_DO_TABLE,
OPT_REPLICATE_IGNORE_TABLE, OPT_REPLICATE_WILD_DO_TABLE, OPT_REPLICATE_IGNORE_TABLE, OPT_REPLICATE_WILD_DO_TABLE,
OPT_REPLICATE_WILD_IGNORE_TABLE, OPT_REPLICATE_WILD_IGNORE_TABLE,
OPT_DISCONNECT_SLAVE_EVENT_COUNT, OPT_DISCONNECT_SLAVE_EVENT_COUNT,
OPT_ABORT_SLAVE_EVENT_COUNT, OPT_ABORT_SLAVE_EVENT_COUNT,
OPT_INNODB_DATA_HOME_DIR, OPT_INNODB_DATA_HOME_DIR,
OPT_INNODB_DATA_FILE_PATH, OPT_INNODB_DATA_FILE_PATH,
OPT_INNODB_LOG_GROUP_HOME_DIR, OPT_INNODB_LOG_GROUP_HOME_DIR,
OPT_INNODB_LOG_ARCH_DIR, OPT_INNODB_LOG_ARCH_DIR,
OPT_INNODB_LOG_ARCHIVE, OPT_INNODB_LOG_ARCHIVE,
OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT, OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT,
OPT_INNODB_FLUSH_METHOD, OPT_INNODB_FLUSH_METHOD,
OPT_INNODB_FAST_SHUTDOWN, OPT_INNODB_FAST_SHUTDOWN,
OPT_SAFE_SHOW_DB, OPT_SAFE_SHOW_DB,
OPT_INNODB_SKIP, OPT_SKIP_SAFEMALLOC, OPT_INNODB_SKIP, OPT_SKIP_SAFEMALLOC,
OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_TEMP_POOL, OPT_TX_ISOLATION,
OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS, OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS,
OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL, OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL,
OPT_SAFE_USER_CREATE, OPT_SQL_MODE, OPT_SAFE_USER_CREATE, OPT_SQL_MODE,
OPT_HAVE_NAMED_PIPE, OPT_HAVE_NAMED_PIPE,
OPT_DO_PSTACK, OPT_REPORT_HOST, OPT_DO_PSTACK, OPT_REPORT_HOST,
OPT_REPORT_USER, OPT_REPORT_PASSWORD, OPT_REPORT_PORT, OPT_REPORT_USER, OPT_REPORT_PASSWORD, OPT_REPORT_PORT,
OPT_SHOW_SLAVE_AUTH_INFO, OPT_OLD_RPL_COMPAT, OPT_SHOW_SLAVE_AUTH_INFO, OPT_OLD_RPL_COMPAT,
OPT_SLAVE_LOAD_TMPDIR, OPT_NO_MIX_TYPE, OPT_SLAVE_LOAD_TMPDIR, OPT_NO_MIX_TYPE,
OPT_RPL_RECOVERY_RANK,OPT_INIT_RPL_ROLE, OPT_RPL_RECOVERY_RANK,OPT_INIT_RPL_ROLE,
OPT_RELAY_LOG, OPT_RELAY_LOG_INDEX, OPT_RELAY_LOG_INFO_FILE, OPT_RELAY_LOG, OPT_RELAY_LOG_INDEX, OPT_RELAY_LOG_INFO_FILE,
OPT_SLAVE_SKIP_ERRORS, OPT_DES_KEY_FILE, OPT_LOCAL_INFILE, OPT_SLAVE_SKIP_ERRORS, OPT_DES_KEY_FILE, OPT_LOCAL_INFILE,
OPT_RECKLESS_SLAVE, OPT_RECKLESS_SLAVE,
OPT_SSL_SSL, OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA, OPT_SSL_SSL, OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA,
OPT_SSL_CAPATH, OPT_SSL_CIPHER, OPT_SSL_CAPATH, OPT_SSL_CIPHER,
OPT_BACK_LOG, OPT_BINLOG_CACHE_SIZE, OPT_BACK_LOG, OPT_BINLOG_CACHE_SIZE,
OPT_CONNECT_TIMEOUT, OPT_DELAYED_INSERT_TIMEOUT, OPT_CONNECT_TIMEOUT, OPT_DELAYED_INSERT_TIMEOUT,
OPT_DELAYED_INSERT_LIMIT, OPT_DELAYED_QUEUE_SIZE, OPT_DELAYED_INSERT_LIMIT, OPT_DELAYED_QUEUE_SIZE,
OPT_FLUSH_TIME, OPT_FT_MIN_WORD_LEN, OPT_FLUSH_TIME, OPT_FT_MIN_WORD_LEN,
OPT_FT_MAX_WORD_LEN, OPT_FT_MAX_WORD_LEN_FOR_SORT, OPT_FT_MAX_WORD_LEN, OPT_FT_MAX_WORD_LEN_FOR_SORT,
OPT_INTERACTIVE_TIMEOUT, OPT_JOIN_BUFF_SIZE, OPT_INTERACTIVE_TIMEOUT, OPT_JOIN_BUFF_SIZE,
OPT_KEY_BUFFER_SIZE, OPT_LONG_QUERY_TIME, OPT_KEY_BUFFER_SIZE, OPT_LONG_QUERY_TIME,
OPT_LOWER_CASE_TABLE_NAMES, OPT_MAX_ALLOWED_PACKET, OPT_LOWER_CASE_TABLE_NAMES, OPT_MAX_ALLOWED_PACKET,
OPT_MAX_BINLOG_CACHE_SIZE, OPT_MAX_BINLOG_SIZE, OPT_MAX_BINLOG_CACHE_SIZE, OPT_MAX_BINLOG_SIZE,
OPT_MAX_CONNECTIONS, OPT_MAX_CONNECT_ERRORS, OPT_MAX_CONNECTIONS, OPT_MAX_CONNECT_ERRORS,
OPT_MAX_DELAYED_THREADS, OPT_MAX_HEP_TABLE_SIZE, OPT_MAX_DELAYED_THREADS, OPT_MAX_HEP_TABLE_SIZE,
OPT_MAX_JOIN_SIZE, OPT_MAX_SORT_LENGTH, OPT_MAX_JOIN_SIZE, OPT_MAX_SORT_LENGTH,
OPT_MAX_TMP_TABLES, OPT_MAX_USER_CONNECTIONS, OPT_MAX_TMP_TABLES, OPT_MAX_USER_CONNECTIONS,
OPT_MAX_WRITE_LOCK_COUNT, OPT_MYISAM_BULK_INSERT_TREE_SIZE, OPT_MAX_WRITE_LOCK_COUNT, OPT_MYISAM_BULK_INSERT_TREE_SIZE,
OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE, OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE, OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE,
OPT_NET_BUFFER_LENGTH, OPT_NET_RETRY_COUNT, OPT_NET_BUFFER_LENGTH, OPT_NET_RETRY_COUNT,
OPT_NET_READ_TIMEOUT, OPT_NET_WRITE_TIMEOUT, OPT_NET_READ_TIMEOUT, OPT_NET_WRITE_TIMEOUT,
OPT_OPEN_FILES_LIMIT, OPT_QUERY_BUFFER_SIZE, OPT_OPEN_FILES_LIMIT, OPT_QUERY_BUFFER_SIZE,
OPT_QUERY_CACHE_LIMIT, OPT_QUERY_CACHE_SIZE, OPT_QUERY_CACHE_LIMIT, OPT_QUERY_CACHE_SIZE,
OPT_QUERY_CACHE_STARTUP_TYPE, OPT_RECORD_BUFFER, OPT_QUERY_CACHE_STARTUP_TYPE, OPT_RECORD_BUFFER,
OPT_RECORD_RND_BUFFER, OPT_RELAY_LOG_SPACE_LIMIT, OPT_RECORD_RND_BUFFER, OPT_RELAY_LOG_SPACE_LIMIT,
OPT_SLAVE_NET_TIMEOUT, OPT_SLOW_LAUNCH_TIME, OPT_SLAVE_NET_TIMEOUT, OPT_SLOW_LAUNCH_TIME,
OPT_SORT_BUFFER, OPT_TABLE_CACHE, OPT_SORT_BUFFER, OPT_TABLE_CACHE,
OPT_THREAD_CONCURRENCY, OPT_THREAD_CACHE_SIZE, OPT_THREAD_CONCURRENCY, OPT_THREAD_CACHE_SIZE,
OPT_TMP_TABLE_SIZE, OPT_THREAD_STACK, OPT_TMP_TABLE_SIZE, OPT_THREAD_STACK,
OPT_WAIT_TIMEOUT, OPT_WAIT_TIMEOUT,
OPT_INNODB_MIRRORED_LOG_GROUPS, OPT_INNODB_MIRRORED_LOG_GROUPS,
OPT_INNODB_LOG_FILES_IN_GROUP, OPT_INNODB_LOG_FILES_IN_GROUP,
OPT_INNODB_LOG_FILE_SIZE, OPT_INNODB_LOG_FILE_SIZE,
OPT_INNODB_LOG_BUFFER_SIZE, OPT_INNODB_LOG_BUFFER_SIZE,
OPT_INNODB_BUFFER_POOL_SIZE, OPT_INNODB_BUFFER_POOL_SIZE,
OPT_INNODB_ADDITIONAL_MEM_POOL_SIZE, OPT_INNODB_ADDITIONAL_MEM_POOL_SIZE,
OPT_INNODB_FILE_IO_THREADS, OPT_INNODB_FILE_IO_THREADS,
OPT_INNODB_LOCK_WAIT_TIMEOUT, OPT_INNODB_LOCK_WAIT_TIMEOUT,
OPT_INNODB_THREAD_CONCURRENCY, OPT_INNODB_THREAD_CONCURRENCY,
OPT_INNODB_FORCE_RECOVERY, OPT_INNODB_FORCE_RECOVERY,
OPT_BDB_CACHE_SIZE, OPT_BDB_CACHE_SIZE,
OPT_BDB_LOG_BUFFER_SIZE, OPT_BDB_LOG_BUFFER_SIZE,
OPT_BDB_MAX_LOCK OPT_BDB_MAX_LOCK
}; };
@ -4020,123 +4022,125 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
opt_bin_log=1; opt_bin_log=1;
break; break;
case (int) OPT_INIT_RPL_ROLE: case (int) OPT_INIT_RPL_ROLE:
{
int role;
if ((role=find_type(argument, &rpl_role_typelib, 2)) <= 0)
{ {
int role; fprintf(stderr, "Unknown replication role: %s\n", argument);
if ((role=find_type(argument, &rpl_role_typelib, 2)) <= 0) exit(1);
{
fprintf(stderr, "Unknown replication role: %s\n", argument);
exit(1);
}
rpl_status = (role == 1) ? RPL_AUTH_MASTER : RPL_IDLE_SLAVE;
break;
} }
rpl_status = (role == 1) ? RPL_AUTH_MASTER : RPL_IDLE_SLAVE;
break;
}
case (int)OPT_REPLICATE_IGNORE_DB: case (int)OPT_REPLICATE_IGNORE_DB:
{ {
i_string *db = new i_string(argument); i_string *db = new i_string(argument);
replicate_ignore_db.push_back(db); replicate_ignore_db.push_back(db);
break; break;
} }
case (int)OPT_REPLICATE_DO_DB: case (int)OPT_REPLICATE_DO_DB:
{ {
i_string *db = new i_string(argument); i_string *db = new i_string(argument);
replicate_do_db.push_back(db); replicate_do_db.push_back(db);
break; break;
} }
case (int)OPT_REPLICATE_REWRITE_DB: case (int)OPT_REPLICATE_REWRITE_DB:
{
char* key = argument,*p, *val;
if (!(p= strstr(argument, "->")))
{ {
char* key = argument,*p, *val; fprintf(stderr,
p = strstr(argument, "->"); "Bad syntax in replicate-rewrite-db - missing '->'!\n");
if (!p) exit(1);
{
fprintf(stderr,
"Bad syntax in replicate-rewrite-db - missing '->'!\n");
exit(1);
}
val = p--;
while(isspace(*p) && p > argument) *p-- = 0;
if(p == argument)
{
fprintf(stderr,
"Bad syntax in replicate-rewrite-db - empty FROM db!\n");
exit(1);
}
*val = 0;
val += 2;
while(*val && isspace(*val)) *val++;
if (!*val)
{
fprintf(stderr,
"Bad syntax in replicate-rewrite-db - empty TO db!\n");
exit(1);
}
i_string_pair* db_pair = new i_string_pair(key, val);
replicate_rewrite_db.push_back(db_pair);
break;
} }
val= p--;
while (isspace(*p) && p > argument)
*p-- = 0;
if (p == argument)
{
fprintf(stderr,
"Bad syntax in replicate-rewrite-db - empty FROM db!\n");
exit(1);
}
*val= 0;
val+= 2;
while (*val && isspace(*val))
*val++;
if (!*val)
{
fprintf(stderr,
"Bad syntax in replicate-rewrite-db - empty TO db!\n");
exit(1);
}
i_string_pair *db_pair = new i_string_pair(key, val);
replicate_rewrite_db.push_back(db_pair);
break;
}
case (int)OPT_BINLOG_IGNORE_DB: case (int)OPT_BINLOG_IGNORE_DB:
{ {
i_string *db = new i_string(argument); i_string *db = new i_string(argument);
binlog_ignore_db.push_back(db); binlog_ignore_db.push_back(db);
break; break;
} }
case (int)OPT_BINLOG_DO_DB: case (int)OPT_BINLOG_DO_DB:
{ {
i_string *db = new i_string(argument); i_string *db = new i_string(argument);
binlog_do_db.push_back(db); binlog_do_db.push_back(db);
break; break;
} }
case (int)OPT_REPLICATE_DO_TABLE: case (int)OPT_REPLICATE_DO_TABLE:
{
if (!do_table_inited)
init_table_rule_hash(&replicate_do_table, &do_table_inited);
if (add_table_rule(&replicate_do_table, argument))
{ {
if (!do_table_inited) fprintf(stderr, "Could not add do table rule '%s'!\n", argument);
init_table_rule_hash(&replicate_do_table, &do_table_inited); exit(1);
if(add_table_rule(&replicate_do_table, argument))
{
fprintf(stderr, "Could not add do table rule '%s'!\n", argument);
exit(1);
}
table_rules_on = 1;
break;
} }
table_rules_on = 1;
break;
}
case (int)OPT_REPLICATE_WILD_DO_TABLE: case (int)OPT_REPLICATE_WILD_DO_TABLE:
{
if (!wild_do_table_inited)
init_table_rule_array(&replicate_wild_do_table,
&wild_do_table_inited);
if (add_wild_table_rule(&replicate_wild_do_table, argument))
{ {
if (!wild_do_table_inited) fprintf(stderr, "Could not add do table rule '%s'!\n", argument);
init_table_rule_array(&replicate_wild_do_table, exit(1);
&wild_do_table_inited);
if(add_wild_table_rule(&replicate_wild_do_table, argument))
{
fprintf(stderr, "Could not add do table rule '%s'!\n", argument);
exit(1);
}
table_rules_on = 1;
break;
} }
table_rules_on = 1;
break;
}
case (int)OPT_REPLICATE_WILD_IGNORE_TABLE: case (int)OPT_REPLICATE_WILD_IGNORE_TABLE:
{
if (!wild_ignore_table_inited)
init_table_rule_array(&replicate_wild_ignore_table,
&wild_ignore_table_inited);
if (add_wild_table_rule(&replicate_wild_ignore_table, argument))
{ {
if (!wild_ignore_table_inited) fprintf(stderr, "Could not add ignore table rule '%s'!\n", argument);
init_table_rule_array(&replicate_wild_ignore_table, exit(1);
&wild_ignore_table_inited);
if(add_wild_table_rule(&replicate_wild_ignore_table, argument))
{
fprintf(stderr, "Could not add ignore table rule '%s'!\n", argument);
exit(1);
}
table_rules_on = 1;
break;
} }
table_rules_on = 1;
break;
}
case (int)OPT_REPLICATE_IGNORE_TABLE: case (int)OPT_REPLICATE_IGNORE_TABLE:
{
if (!ignore_table_inited)
init_table_rule_hash(&replicate_ignore_table, &ignore_table_inited);
if (add_table_rule(&replicate_ignore_table, argument))
{ {
if (!ignore_table_inited) fprintf(stderr, "Could not add ignore table rule '%s'!\n", argument);
init_table_rule_hash(&replicate_ignore_table, &ignore_table_inited); exit(1);
if(add_table_rule(&replicate_ignore_table, argument))
{
fprintf(stderr, "Could not add ignore table rule '%s'!\n", argument);
exit(1);
}
table_rules_on = 1;
break;
} }
table_rules_on = 1;
break;
}
case (int) OPT_SLOW_QUERY_LOG: case (int) OPT_SLOW_QUERY_LOG:
opt_slow_log=1; opt_slow_log=1;
break; break;
@ -4260,16 +4264,16 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
opt_noacl=opt_bootstrap=1; opt_noacl=opt_bootstrap=1;
break; break;
case OPT_TABLE_TYPE: case OPT_TABLE_TYPE:
{
int type;
if ((type=find_type(argument, &ha_table_typelib, 2)) <= 0)
{ {
int type; fprintf(stderr,"Unknown table type: %s\n",argument);
if ((type=find_type(argument, &ha_table_typelib, 2)) <= 0) exit(1);
{
fprintf(stderr,"Unknown table type: %s\n",argument);
exit(1);
}
default_table_type= (enum db_type) type;
break;
} }
default_table_type= (enum db_type) type;
break;
}
case OPT_SERVER_ID: case OPT_SERVER_ID:
server_id_supplied = 1; server_id_supplied = 1;
break; break;
@ -4293,16 +4297,16 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
#endif #endif
break; break;
case OPT_TX_ISOLATION: case OPT_TX_ISOLATION:
{
int type;
if ((type=find_type(argument, &tx_isolation_typelib, 2)) <= 0)
{ {
int type; fprintf(stderr,"Unknown transaction isolation type: %s\n",argument);
if ((type=find_type(argument, &tx_isolation_typelib, 2)) <= 0) exit(1);
{
fprintf(stderr,"Unknown transaction isolation type: %s\n",argument);
exit(1);
}
default_tx_isolation= (enum_tx_isolation) (type-1);
break;
} }
default_tx_isolation= (enum_tx_isolation) (type-1);
break;
}
#ifdef HAVE_BERKELEY_DB #ifdef HAVE_BERKELEY_DB
case OPT_BDB_NOSYNC: case OPT_BDB_NOSYNC:
berkeley_env_flags|=DB_TXN_NOSYNC; berkeley_env_flags|=DB_TXN_NOSYNC;
@ -4311,22 +4315,22 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
berkeley_init_flags&= ~(DB_RECOVER); berkeley_init_flags&= ~(DB_RECOVER);
break; break;
case OPT_BDB_LOCK: case OPT_BDB_LOCK:
{
int type;
if ((type=find_type(argument, &berkeley_lock_typelib, 2)) > 0)
berkeley_lock_type=berkeley_lock_types[type-1];
else
{ {
int type; if (test_if_int(argument,(uint) strlen(argument)))
if ((type=find_type(argument, &berkeley_lock_typelib, 2)) > 0) berkeley_lock_scan_time=atoi(argument);
berkeley_lock_type=berkeley_lock_types[type-1];
else else
{ {
if (test_if_int(argument,(uint) strlen(argument))) fprintf(stderr,"Unknown lock type: %s\n",argument);
berkeley_lock_scan_time=atoi(argument); exit(1);
else
{
fprintf(stderr,"Unknown lock type: %s\n",argument);
exit(1);
}
} }
break;
} }
break;
}
case OPT_BDB_SHARED: case OPT_BDB_SHARED:
berkeley_init_flags&= ~(DB_PRIVATE); berkeley_init_flags&= ~(DB_PRIVATE);
berkeley_shared_data=1; berkeley_shared_data=1;
@ -4361,39 +4365,39 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
break; break;
#endif /* HAVE_INNOBASE_DB */ #endif /* HAVE_INNOBASE_DB */
case OPT_MYISAM_RECOVER: case OPT_MYISAM_RECOVER:
{
if (!argument || !argument[0])
{ {
if (!argument || !argument[0]) myisam_recover_options= HA_RECOVER_DEFAULT;
{ myisam_recover_options_str= myisam_recover_typelib.type_names[0];
myisam_recover_options= HA_RECOVER_DEFAULT;
myisam_recover_options_str= myisam_recover_typelib.type_names[0];
}
else
{
myisam_recover_options_str=argument;
if ((myisam_recover_options=
find_bit_type(argument, &myisam_recover_typelib)) == ~(ulong) 0)
{
fprintf(stderr, "Unknown option to myisam-recover: %s\n",argument);
exit(1);
}
}
ha_open_options|=HA_OPEN_ABORT_IF_CRASHED;
break;
} }
case OPT_SQL_MODE: else
{ {
sql_mode_str = argument; myisam_recover_options_str=argument;
if ((opt_sql_mode = if ((myisam_recover_options=
find_bit_type(argument, &sql_mode_typelib)) == ~(ulong) 0) find_bit_type(argument, &myisam_recover_typelib)) == ~(ulong) 0)
{ {
fprintf(stderr, "Unknown option to sql-mode: %s\n", argument); fprintf(stderr, "Unknown option to myisam-recover: %s\n",argument);
exit(1); exit(1);
} }
default_tx_isolation= ((opt_sql_mode & MODE_SERIALIZABLE) ?
ISO_SERIALIZABLE :
ISO_READ_COMMITTED);
break;
} }
ha_open_options|=HA_OPEN_ABORT_IF_CRASHED;
break;
}
case OPT_SQL_MODE:
{
sql_mode_str = argument;
if ((opt_sql_mode =
find_bit_type(argument, &sql_mode_typelib)) == ~(ulong) 0)
{
fprintf(stderr, "Unknown option to sql-mode: %s\n", argument);
exit(1);
}
default_tx_isolation= ((opt_sql_mode & MODE_SERIALIZABLE) ?
ISO_SERIALIZABLE :
ISO_READ_COMMITTED);
break;
}
case OPT_MASTER_PASSWORD: case OPT_MASTER_PASSWORD:
master_password=argument; master_password=argument;
break; break;
@ -4576,10 +4580,10 @@ static uint set_maximum_open_files(uint max_file_limit)
} }
#endif #endif
/* /*
Return a bitfield from a string of substrings separated by ',' Return a bitfield from a string of substrings separated by ','
returns ~(ulong) 0 on error. returns ~(ulong) 0 on error.
*/ */
static ulong find_bit_type(const char *x, TYPELIB *bit_lib) static ulong find_bit_type(const char *x, TYPELIB *bit_lib)
{ {
@ -4637,7 +4641,7 @@ skipp: ;
/***************************************************************************** /*****************************************************************************
** Instantiate templates Instantiate templates
*****************************************************************************/ *****************************************************************************/
#ifdef __GNUC__ #ifdef __GNUC__

View file

@ -87,9 +87,9 @@ void send_warning(NET *net, uint sql_errno, const char *err)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/** /*
** write error package and flush to client Write error package and flush to client
** It's a little too low level, but I don't want to allow another buffer It's a little too low level, but I don't want to allow another buffer
*/ */
/* VARARGS3 */ /* VARARGS3 */
@ -339,9 +339,9 @@ bool net_store_data(String* packet, I_List<i_string>* str_list)
I_List_iterator<i_string> it(*str_list); I_List_iterator<i_string> it(*str_list);
i_string* s; i_string* s;
while((s=it++)) while ((s=it++))
{ {
if(tmp.length()) if (tmp.length())
tmp.append(','); tmp.append(',');
tmp.append(s->ptr); tmp.append(s->ptr);
} }

View file

@ -815,7 +815,7 @@ my_net_read(NET *net)
return len; return len;
} }
int net_request_file(NET* net, const char* fname) bool net_request_file(NET* net, const char* fname)
{ {
char tmp [FN_REFLEN+1],*end; char tmp [FN_REFLEN+1],*end;
DBUG_ENTER("net_request_file"); DBUG_ENTER("net_request_file");

View file

@ -501,11 +501,9 @@ BOOL NTService::IsService(LPCSTR ServiceName)
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
BOOL NTService::got_service_option(char **argv, char *service_option) BOOL NTService::got_service_option(char **argv, char *service_option)
{ {
char *option = argv[1]; char *option;
for (option= argv[1]; *option; option++)
while (*option) if (!strcmp(option, service_option))
if (!strcmp(option++, service_option)) return TRUE;
return TRUE;
return FALSE; return FALSE;
} }

View file

@ -885,7 +885,7 @@ get_mm_parts(PARAM *param,Field *field, Item_func::Functype type,Item *value,
if (value && if (value &&
value->used_tables() & ~(param->prev_tables | param->read_tables)) value->used_tables() & ~(param->prev_tables | param->read_tables))
DBUG_RETURN(0); DBUG_RETURN(0);
for ( ; key_part != end ; key_part++) for (; key_part != end ; key_part++)
{ {
if (field->eq(key_part->field)) if (field->eq(key_part->field))
{ {

View file

@ -40,16 +40,20 @@ const char *rpl_role_type[] = {"MASTER","SLAVE",NullS};
TYPELIB rpl_role_typelib = {array_elements(rpl_role_type)-1,"", TYPELIB rpl_role_typelib = {array_elements(rpl_role_type)-1,"",
rpl_role_type}; rpl_role_type};
const char* rpl_status_type[] = {"AUTH_MASTER","ACTIVE_SLAVE","IDLE_SLAVE", const char* rpl_status_type[]=
"LOST_SOLDIER","TROOP_SOLDIER", {
"RECOVERY_CAPTAIN","NULL",NullS}; "AUTH_MASTER","ACTIVE_SLAVE","IDLE_SLAVE", "LOST_SOLDIER","TROOP_SOLDIER",
"RECOVERY_CAPTAIN","NULL",NullS
};
TYPELIB rpl_status_typelib= {array_elements(rpl_status_type)-1,"", TYPELIB rpl_status_typelib= {array_elements(rpl_status_type)-1,"",
rpl_status_type}; rpl_status_type};
static Slave_log_event* find_slave_event(IO_CACHE* log, static Slave_log_event* find_slave_event(IO_CACHE* log,
const char* log_file_name, const char* log_file_name,
char* errmsg); char* errmsg);
static int init_failsafe_rpl_thread(THD* thd) static int init_failsafe_rpl_thread(THD* thd)
{ {
DBUG_ENTER("init_failsafe_rpl_thread"); DBUG_ENTER("init_failsafe_rpl_thread");
@ -93,6 +97,7 @@ static int init_failsafe_rpl_thread(THD* thd)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
void change_rpl_status(RPL_STATUS from_status, RPL_STATUS to_status) void change_rpl_status(RPL_STATUS from_status, RPL_STATUS to_status)
{ {
pthread_mutex_lock(&LOCK_rpl_status); pthread_mutex_lock(&LOCK_rpl_status);
@ -102,6 +107,7 @@ void change_rpl_status(RPL_STATUS from_status, RPL_STATUS to_status)
pthread_mutex_unlock(&LOCK_rpl_status); pthread_mutex_unlock(&LOCK_rpl_status);
} }
#define get_object(p, obj) \ #define get_object(p, obj) \
{\ {\
uint len = (uint)*p++; \ uint len = (uint)*p++; \
@ -111,28 +117,33 @@ void change_rpl_status(RPL_STATUS from_status, RPL_STATUS to_status)
p+= len; \ p+= len; \
}\ }\
static inline int cmp_master_pos(Slave_log_event* sev, LEX_MASTER_INFO* mi) static inline int cmp_master_pos(Slave_log_event* sev, LEX_MASTER_INFO* mi)
{ {
return cmp_master_pos(sev->master_log, sev->master_pos, mi->log_file_name, return cmp_master_pos(sev->master_log, sev->master_pos, mi->log_file_name,
mi->pos); mi->pos);
} }
void unregister_slave(THD* thd, bool only_mine, bool need_mutex) void unregister_slave(THD* thd, bool only_mine, bool need_mutex)
{ {
if (need_mutex)
pthread_mutex_lock(&LOCK_slave_list);
if (thd->server_id) if (thd->server_id)
{ {
if (need_mutex)
pthread_mutex_lock(&LOCK_slave_list);
SLAVE_INFO* old_si; SLAVE_INFO* old_si;
if ((old_si = (SLAVE_INFO*)hash_search(&slave_list, if ((old_si = (SLAVE_INFO*)hash_search(&slave_list,
(byte*)&thd->server_id, 4)) && (byte*)&thd->server_id, 4)) &&
(!only_mine || old_si->thd == thd)) (!only_mine || old_si->thd == thd))
hash_delete(&slave_list, (byte*)old_si); hash_delete(&slave_list, (byte*)old_si);
if (need_mutex)
pthread_mutex_unlock(&LOCK_slave_list);
} }
if (need_mutex)
pthread_mutex_unlock(&LOCK_slave_list);
} }
int register_slave(THD* thd, uchar* packet, uint packet_length) int register_slave(THD* thd, uchar* packet, uint packet_length)
{ {
SLAVE_INFO *si; SLAVE_INFO *si;
@ -199,16 +210,15 @@ void end_slave_list()
} }
} }
static int find_target_pos(LEX_MASTER_INFO* mi, IO_CACHE* log, char* errmsg) static int find_target_pos(LEX_MASTER_INFO *mi, IO_CACHE *log, char *errmsg)
{ {
uint32 log_pos = (uint32) mi->pos; my_off_t log_pos = (my_off_t) mi->pos;
uint32 target_server_id = mi->server_id; uint32 target_server_id = mi->server_id;
for (;;) for (;;)
{ {
Log_event* ev; Log_event* ev;
if (!(ev = Log_event::read_log_event(log, (pthread_mutex_t*)0, if (!(ev = Log_event::read_log_event(log, (pthread_mutex_t*) 0, 0)))
0)))
{ {
if (log->error > 0) if (log->error > 0)
strmov(errmsg, "Binary log truncated in the middle of event"); strmov(errmsg, "Binary log truncated in the middle of event");
@ -225,9 +235,9 @@ static int find_target_pos(LEX_MASTER_INFO* mi, IO_CACHE* log, char* errmsg)
mi->pos = my_b_tell(log); mi->pos = my_b_tell(log);
return 0; return 0;
} }
delete ev; delete ev;
} }
/* Impossible */
} }
@ -258,8 +268,6 @@ int translate_master(THD* thd, LEX_MASTER_INFO* mi, char* errmsg)
} }
linfo.index_file_offset = 0; linfo.index_file_offset = 0;
search_file_name[0] = 0; search_file_name[0] = 0;
if (mysql_bin_log.find_first_log(&linfo, search_file_name)) if (mysql_bin_log.find_first_log(&linfo, search_file_name))
@ -357,7 +365,11 @@ err:
return error; return error;
} }
// caller must delete result when done
/*
Caller must delete result when done
*/
static Slave_log_event* find_slave_event(IO_CACHE* log, static Slave_log_event* find_slave_event(IO_CACHE* log,
const char* log_file_name, const char* log_file_name,
char* errmsg) char* errmsg)
@ -431,6 +443,7 @@ int show_new_master(THD* thd)
} }
} }
int update_slave_list(MYSQL* mysql) int update_slave_list(MYSQL* mysql)
{ {
MYSQL_RES* res=0; MYSQL_RES* res=0;
@ -446,8 +459,7 @@ int update_slave_list(MYSQL* mysql)
goto err; goto err;
} }
switch (mc_mysql_num_fields(res)) switch (mc_mysql_num_fields(res)) {
{
case 5: case 5:
have_auth_info = 0; have_auth_info = 0;
port_ind=2; port_ind=2;
@ -463,13 +475,13 @@ int update_slave_list(MYSQL* mysql)
pthread_mutex_lock(&LOCK_slave_list); pthread_mutex_lock(&LOCK_slave_list);
while ((row = mc_mysql_fetch_row(res))) while ((row= mc_mysql_fetch_row(res)))
{ {
uint32 server_id; uint32 server_id;
SLAVE_INFO* si, *old_si; SLAVE_INFO* si, *old_si;
server_id = atoi(row[0]); server_id = atoi(row[0]);
if ((old_si = (SLAVE_INFO*)hash_search(&slave_list, if ((old_si= (SLAVE_INFO*)hash_search(&slave_list,
(byte*)&server_id,4))) (byte*)&server_id,4)))
si = old_si; si = old_si;
else else
{ {
@ -482,17 +494,18 @@ int update_slave_list(MYSQL* mysql)
si->server_id = server_id; si->server_id = server_id;
hash_insert(&slave_list, (byte*)si); hash_insert(&slave_list, (byte*)si);
} }
strnmov(si->host, row[1], sizeof(si->host)); strmake(si->host, row[1], sizeof(si->host)-1);
si->port = atoi(row[port_ind]); si->port = atoi(row[port_ind]);
si->rpl_recovery_rank = atoi(row[port_ind+1]); si->rpl_recovery_rank = atoi(row[port_ind+1]);
si->master_id = atoi(row[port_ind+2]); si->master_id = atoi(row[port_ind+2]);
if (have_auth_info) if (have_auth_info)
{ {
strnmov(si->user, row[2], sizeof(si->user)); strmake(si->user, row[2], sizeof(si->user)-1);
strnmov(si->password, row[3], sizeof(si->password)); strmake(si->password, row[3], sizeof(si->password)-1);
} }
} }
pthread_mutex_unlock(&LOCK_slave_list); pthread_mutex_unlock(&LOCK_slave_list);
err: err:
if (res) if (res)
mc_mysql_free_result(res); mc_mysql_free_result(res);
@ -504,12 +517,13 @@ err:
return 0; return 0;
} }
int find_recovery_captain(THD* thd, MYSQL* mysql) int find_recovery_captain(THD* thd, MYSQL* mysql)
{ {
return 0; return 0;
} }
pthread_handler_decl(handle_failsafe_rpl,arg) pthread_handler_decl(handle_failsafe_rpl,arg)
{ {
DBUG_ENTER("handle_failsafe_rpl"); DBUG_ENTER("handle_failsafe_rpl");
@ -532,8 +546,7 @@ pthread_handler_decl(handle_failsafe_rpl,arg)
thd->proc_info="Processing request"; thd->proc_info="Processing request";
while (!break_req_chain) while (!break_req_chain)
{ {
switch (rpl_status) switch (rpl_status) {
{
case RPL_LOST_SOLDIER: case RPL_LOST_SOLDIER:
if (find_recovery_captain(thd, recovery_captain)) if (find_recovery_captain(thd, recovery_captain))
rpl_status=RPL_TROOP_SOLDIER; rpl_status=RPL_TROOP_SOLDIER;
@ -558,6 +571,7 @@ err:
DBUG_RETURN(0); DBUG_RETURN(0);
} }
int show_slave_hosts(THD* thd) int show_slave_hosts(THD* thd)
{ {
List<Item> field_list; List<Item> field_list;
@ -606,6 +620,7 @@ int show_slave_hosts(THD* thd)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
int connect_to_master(THD *thd, MYSQL* mysql, MASTER_INFO* mi) int connect_to_master(THD *thd, MYSQL* mysql, MASTER_INFO* mi)
{ {
if (!mi->host || !*mi->host) /* empty host */ if (!mi->host || !*mi->host) /* empty host */
@ -623,9 +638,9 @@ int connect_to_master(THD *thd, MYSQL* mysql, MASTER_INFO* mi)
static inline void cleanup_mysql_results(MYSQL_RES* db_res, static inline void cleanup_mysql_results(MYSQL_RES* db_res,
MYSQL_RES** cur, MYSQL_RES** start) MYSQL_RES** cur, MYSQL_RES** start)
{ {
for( ; cur >= start; --cur) for (; cur >= start; --cur)
{ {
if (*cur) if (*cur)
mc_mysql_free_result(*cur); mc_mysql_free_result(*cur);
@ -638,7 +653,7 @@ static inline int fetch_db_tables(THD* thd, MYSQL* mysql, const char* db,
MYSQL_RES* table_res, MASTER_INFO* mi) MYSQL_RES* table_res, MASTER_INFO* mi)
{ {
MYSQL_ROW row; MYSQL_ROW row;
for( row = mc_mysql_fetch_row(table_res); row; for (row = mc_mysql_fetch_row(table_res); row;
row = mc_mysql_fetch_row(table_res)) row = mc_mysql_fetch_row(table_res))
{ {
TABLE_LIST table; TABLE_LIST table;
@ -690,7 +705,7 @@ int load_master_data(THD* thd)
if (connect_to_master(thd, &mysql, active_mi)) if (connect_to_master(thd, &mysql, active_mi))
{ {
net_printf(&thd->net, error = ER_CONNECT_TO_MASTER, net_printf(&thd->net, error = ER_CONNECT_TO_MASTER,
mc_mysql_error(&mysql)); mc_mysql_error(&mysql));
goto err; goto err;
} }
@ -742,8 +757,8 @@ int load_master_data(THD* thd)
table_res_end = table_res + num_dbs; table_res_end = table_res + num_dbs;
for(cur_table_res = table_res; cur_table_res < table_res_end; for (cur_table_res = table_res; cur_table_res < table_res_end;
cur_table_res++) cur_table_res++)
{ {
// since we know how many rows we have, this can never be NULL // since we know how many rows we have, this can never be NULL
MYSQL_ROW row = mc_mysql_fetch_row(db_res); MYSQL_ROW row = mc_mysql_fetch_row(db_res);
@ -761,7 +776,7 @@ int load_master_data(THD* thd)
*/ */
if (!db_ok(db, replicate_do_db, replicate_ignore_db) || if (!db_ok(db, replicate_do_db, replicate_ignore_db) ||
!strcmp(db,"mysql")) !strcmp(db,"mysql"))
{ {
*cur_table_res = 0; *cur_table_res = 0;
continue; continue;
@ -777,7 +792,7 @@ int load_master_data(THD* thd)
if (mc_mysql_select_db(&mysql, db) || if (mc_mysql_select_db(&mysql, db) ||
mc_mysql_query(&mysql, "show tables", 0) || mc_mysql_query(&mysql, "show tables", 0) ||
!(*cur_table_res = mc_mysql_store_result(&mysql))) !(*cur_table_res = mc_mysql_store_result(&mysql)))
{ {
net_printf(&thd->net, error = ER_QUERY_ON_MASTER, net_printf(&thd->net, error = ER_QUERY_ON_MASTER,
mc_mysql_error(&mysql)); mc_mysql_error(&mysql));
@ -804,7 +819,7 @@ int load_master_data(THD* thd)
We need this check because the master may not be running with We need this check because the master may not be running with
log-bin, but it will still allow us to do all the steps log-bin, but it will still allow us to do all the steps
of LOAD DATA FROM MASTER - no reason to forbid it, really, of LOAD DATA FROM MASTER - no reason to forbid it, really,
although it does not make much sense for the user to do it although it does not make much sense for the user to do it
*/ */
if (row[0] && row[1]) if (row[0] && row[1])
{ {
@ -838,18 +853,18 @@ int load_master_data(THD* thd)
} }
pthread_mutex_lock(&active_mi->rli.data_lock); pthread_mutex_lock(&active_mi->rli.data_lock);
active_mi->rli.master_log_pos = active_mi->master_log_pos; active_mi->rli.master_log_pos = active_mi->master_log_pos;
strnmov(active_mi->rli.master_log_name,active_mi->master_log_name, strmake(active_mi->rli.master_log_name,active_mi->master_log_name,
sizeof(active_mi->rli.master_log_name)); sizeof(active_mi->rli.master_log_name)-1);
flush_relay_log_info(&active_mi->rli); flush_relay_log_info(&active_mi->rli);
pthread_cond_broadcast(&active_mi->rli.data_cond); pthread_cond_broadcast(&active_mi->rli.data_cond);
pthread_mutex_unlock(&active_mi->rli.data_lock); pthread_mutex_unlock(&active_mi->rli.data_lock);
thd->proc_info = "starting slave"; thd->proc_info = "starting slave";
if (restart_thread_mask) if (restart_thread_mask)
{ {
error=start_slave_threads(0 /* mutex not needed*/, error=start_slave_threads(0 /* mutex not needed */,
1 /* wait for start*/, 1 /* wait for start */,
active_mi,master_info_file,relay_log_info_file, active_mi,master_info_file,relay_log_info_file,
restart_thread_mask); restart_thread_mask);
} }
err: err:

View file

@ -221,8 +221,8 @@ int init_relay_log_pos(RELAY_LOG_INFO* rli,const char* log,
*errmsg="Could not find target log during relay log initialization"; *errmsg="Could not find target log during relay log initialization";
goto err; goto err;
} }
strnmov(rli->relay_log_name,rli->linfo.log_file_name, strmake(rli->relay_log_name,rli->linfo.log_file_name,
sizeof(rli->relay_log_name)); sizeof(rli->relay_log_name)-1);
// to make end_io_cache(&rli->cache_buf) safe in all cases // to make end_io_cache(&rli->cache_buf) safe in all cases
if (!rli->inited) if (!rli->inited)
bzero((char*) &rli->cache_buf, sizeof(IO_CACHE)); bzero((char*) &rli->cache_buf, sizeof(IO_CACHE));
@ -315,7 +315,7 @@ int purge_relay_logs(RELAY_LOG_INFO* rli, bool just_reset, const char** errmsg)
error=1; error=1;
goto err; goto err;
} }
strnmov(rli->relay_log_name,rli->linfo.log_file_name, strmake(rli->relay_log_name,rli->linfo.log_file_name,
sizeof(rli->relay_log_name)-1); sizeof(rli->relay_log_name)-1);
// Just first log with magic number and nothing else // Just first log with magic number and nothing else
rli->log_space_total= BIN_LOG_HEADER_SIZE; rli->log_space_total= BIN_LOG_HEADER_SIZE;
@ -635,7 +635,7 @@ int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec)
static void free_string_array(DYNAMIC_ARRAY *a) static void free_string_array(DYNAMIC_ARRAY *a)
{ {
uint i; uint i;
for(i = 0; i < a->elements; i++) for (i = 0; i < a->elements; i++)
{ {
char* p; char* p;
get_dynamic(a, (gptr) &p, i); get_dynamic(a, (gptr) &p, i);
@ -2656,8 +2656,8 @@ Log_event* next_event(RELAY_LOG_INFO* rli)
} }
rli->relay_log_pos = BIN_LOG_HEADER_SIZE; rli->relay_log_pos = BIN_LOG_HEADER_SIZE;
rli->pending=0; rli->pending=0;
strnmov(rli->relay_log_name,rli->linfo.log_file_name, strmake(rli->relay_log_name,rli->linfo.log_file_name,
sizeof(rli->relay_log_name)); sizeof(rli->relay_log_name)-1);
flush_relay_log_info(rli); flush_relay_log_info(rli);
} }

View file

@ -70,6 +70,7 @@ struct st_master_info;
typedef struct st_relay_log_info typedef struct st_relay_log_info
{ {
/*** The following variables can only be read when protect by data lock ****/ /*** The following variables can only be read when protect by data lock ****/
/* /*
info_fd - file descriptor of the info file. set only during info_fd - file descriptor of the info file. set only during
initialization or clean up - safe to read anytime initialization or clean up - safe to read anytime
@ -126,7 +127,7 @@ typedef struct st_relay_log_info
uint32 cur_log_old_open_count; uint32 cur_log_old_open_count;
/* /*
current offset in the relay log. Current offset in the relay log.
pending - in some cases we do not increment offset immediately after pending - in some cases we do not increment offset immediately after
processing an event, because the following event needs to be processed processing an event, because the following event needs to be processed
atomically together with this one ( so far, there is only one type of atomically together with this one ( so far, there is only one type of

View file

@ -255,7 +255,7 @@ int acl_init(bool dont_read_acl_tables)
protocol_version == PROTOCOL_VERSION) protocol_version == PROTOCOL_VERSION)
{ {
sql_print_error( sql_print_error(
"Found old style password for user '%s'. Ignoring user. (You may want to restart using --old-protocol)", "Found old style password for user '%s'. Ignoring user. (You may want to restart mysqld using --old-protocol)",
user.user ? user.user : ""); /* purecov: tested */ user.user ? user.user : ""); /* purecov: tested */
} }
else if (length % 8) // This holds true for passwords else if (length % 8) // This holds true for passwords
@ -269,8 +269,9 @@ int acl_init(bool dont_read_acl_tables)
get_salt_from_password(user.salt,user.password); get_salt_from_password(user.salt,user.password);
user.access=get_access(table,3); user.access=get_access(table,3);
user.sort=get_sort(2,user.host.hostname,user.user); user.sort=get_sort(2,user.host.hostname,user.user);
user.hostname_length=user.host.hostname ? (uint) strlen(user.host.hostname) : 0; user.hostname_length= (user.host.hostname ?
if (table->fields >=23) (uint) strlen(user.host.hostname) : 0);
if (table->fields >= 23)
{ {
/* Table has new MySQL usage limits */ /* Table has new MySQL usage limits */
char *ptr = get_field(&mem, table, 21); char *ptr = get_field(&mem, table, 21);
@ -279,7 +280,8 @@ int acl_init(bool dont_read_acl_tables)
user.user_resource.updates=atoi(ptr); user.user_resource.updates=atoi(ptr);
ptr = get_field(&mem, table, 23); ptr = get_field(&mem, table, 23);
user.user_resource.connections=atoi(ptr); user.user_resource.connections=atoi(ptr);
if (user.user_resource.questions || user.user_resource.updates || user.user_resource.connections) if (user.user_resource.questions || user.user_resource.updates ||
user.user_resource.connections)
mqh_used=1; mqh_used=1;
} }
else else
@ -829,7 +831,7 @@ int wild_case_compare(const char *str,const char *wildstr)
{ {
reg3 int flag; reg3 int flag;
DBUG_ENTER("wild_case_compare"); DBUG_ENTER("wild_case_compare");
DBUG_PRINT("enter",("str='%s', wildstr='%s'",str,wildstr)); DBUG_PRINT("enter",("str: '%s' wildstr: '%s'",str,wildstr));
while (*wildstr) while (*wildstr)
{ {
while (*wildstr && *wildstr != wild_many && *wildstr != wild_one) while (*wildstr && *wildstr != wild_many && *wildstr != wild_one)
@ -954,7 +956,8 @@ bool change_password(THD *thd, const char *host, const char *user,
{ {
uint length=0; uint length=0;
DBUG_ENTER("change_password"); DBUG_ENTER("change_password");
DBUG_PRINT("enter",("thd=%x, host='%s', user='%s', new_password='%s'",thd,host,user,new_password)); DBUG_PRINT("enter",("host: '%s' user: '%s' new_password: '%s'",
host,user,new_password));
if (!initialized) if (!initialized)
{ {
@ -1027,7 +1030,7 @@ static ACL_USER *
find_acl_user(const char *host, const char *user) find_acl_user(const char *host, const char *user)
{ {
DBUG_ENTER("find_acl_user"); DBUG_ENTER("find_acl_user");
DBUG_PRINT("enter",("host='%s', user='%s'",host,user)); DBUG_PRINT("enter",("host: '%s' user: '%s'",host,user));
for (uint i=0 ; i < acl_users.elements ; i++) for (uint i=0 ; i < acl_users.elements ; i++)
{ {
ACL_USER *acl_user=dynamic_element(&acl_users,i,ACL_USER*); ACL_USER *acl_user=dynamic_element(&acl_users,i,ACL_USER*);
@ -1238,7 +1241,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
rights=get_access(table,3); rights=get_access(table,3);
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
/* We write down SSL related ACL stuff */ /* We write down SSL related ACL stuff */
DBUG_PRINT("info",("table->fields=%d",table->fields)); DBUG_PRINT("info",("table->fields: %d",table->fields));
if (table->fields >= 21) /* From 4.0.0 we have more fields */ if (table->fields >= 21) /* From 4.0.0 we have more fields */
{ {
table->field[18]->store("",0); table->field[18]->store("",0);
@ -1883,9 +1886,9 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list,
TABLE_LIST tables[3]; TABLE_LIST tables[3];
bool create_new_users=0; bool create_new_users=0;
DBUG_ENTER("mysql_table_grant"); DBUG_ENTER("mysql_table_grant");
DBUG_PRINT("info",("ssl_cipher=%s",thd->lex.ssl_cipher)); DBUG_PRINT("info",("ssl_cipher: %s",thd->lex.ssl_cipher));
DBUG_PRINT("info",("x509_issuer=%s",thd->lex.x509_issuer)); DBUG_PRINT("info",("x509_issuer: %s",thd->lex.x509_issuer));
DBUG_PRINT("info",("x509_subject=%s",thd->lex.x509_subject)); DBUG_PRINT("info",("x509_subject: %s",thd->lex.x509_subject));
if (!initialized) if (!initialized)
{ {
@ -2601,7 +2604,6 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
{ {
uint counter, want_access,index; uint counter, want_access,index;
int error = 0; int error = 0;
int ssl_options = 0;
ACL_USER *acl_user; ACL_DB *acl_db; ACL_USER *acl_user; ACL_DB *acl_db;
char buff[1024]; char buff[1024];
DBUG_ENTER("mysql_show_grants"); DBUG_ENTER("mysql_show_grants");
@ -2699,18 +2701,18 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
/* "show grants" SSL related stuff */ /* "show grants" SSL related stuff */
if (acl_user->ssl_type == SSL_TYPE_ANY) if (acl_user->ssl_type == SSL_TYPE_ANY)
global.append(" REQUIRE SSL",12); global.append(" REQUIRE SSL",12);
else if (acl_user->ssl_type==SSL_TYPE_X509) else if (acl_user->ssl_type == SSL_TYPE_X509)
global.append(" REQUIRE X509",13); global.append(" REQUIRE X509",13);
else if (acl_user->ssl_type==SSL_TYPE_SPECIFIED) else if (acl_user->ssl_type == SSL_TYPE_SPECIFIED)
{ {
int ssl_options = 0;
global.append(" REQUIRE ",9); global.append(" REQUIRE ",9);
if (acl_user->x509_issuer) if (acl_user->x509_issuer)
{ {
if (ssl_options++) ssl_options++;
global.append(" AND ",5);
global.append("ISSUER \"",8); global.append("ISSUER \"",8);
global.append(acl_user->x509_issuer,strlen(acl_user->x509_issuer)); global.append(acl_user->x509_issuer,strlen(acl_user->x509_issuer));
global.append("\"",1); global.append('\'');
} }
if (acl_user->x509_subject) if (acl_user->x509_subject)
{ {
@ -2718,15 +2720,15 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
global.append(" AND ",5); global.append(" AND ",5);
global.append("SUBJECT \"",9); global.append("SUBJECT \"",9);
global.append(acl_user->x509_subject,strlen(acl_user->x509_subject)); global.append(acl_user->x509_subject,strlen(acl_user->x509_subject));
global.append("\"",1); global.append('\'');
} }
if (acl_user->ssl_cipher) if (acl_user->ssl_cipher)
{ {
if (ssl_options++) if (ssl_options++)
global.append(" AND ",5); global.append(" AND ",5);
global.append("CIPHER \"",8); global.append("CIPHER '",8);
global.append(acl_user->ssl_cipher,strlen(acl_user->ssl_cipher)); global.append(acl_user->ssl_cipher,strlen(acl_user->ssl_cipher));
global.append("\"",1); global.append('\'');
} }
} }
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
@ -2735,21 +2737,21 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
if (acl_user->user_resource.questions) if (acl_user->user_resource.questions)
{ {
char buff[65], *p; // just as in int2str char buff[65], *p; // just as in int2str
global.append(" WITH MAX_QUERIES_PER_HOUR = ",29); global.append(" WITH MAX_QUERIES_PER_HOUR ",27);
p=int2str(acl_user->user_resource.questions,buff,10); p=int2str(acl_user->user_resource.questions,buff,10);
global.append(buff,p-buff); global.append(buff,p-buff);
} }
if (acl_user->user_resource.updates) if (acl_user->user_resource.updates)
{ {
char buff[65], *p; // just as in int2str char buff[65], *p; // just as in int2str
global.append(" WITH MAX_UPDATES_PER_HOUR = ",29); global.append(" WITH MAX_UPDATES_PER_HOUR ",27);
p=int2str(acl_user->user_resource.updates,buff,10); p=int2str(acl_user->user_resource.updates,buff,10);
global.append(buff,p-buff); global.append(buff,p-buff);
} }
if (acl_user->user_resource.connections) if (acl_user->user_resource.connections)
{ {
char buff[65], *p; // just as in int2str char buff[65], *p; // just as in int2str
global.append(" WITH MAX_CONNECTIONS_PER_HOUR = ",33); global.append(" WITH MAX_CONNECTIONS_PER_HOUR ",31);
p=int2str(acl_user->user_resource.connections,buff,10); p=int2str(acl_user->user_resource.connections,buff,10);
global.append(buff,p-buff); global.append(buff,p-buff);
} }

View file

@ -691,6 +691,7 @@ void wait_for_refresh(THD *thd)
pthread_mutex_unlock(&thd->mysys_var->mutex); pthread_mutex_unlock(&thd->mysys_var->mutex);
} }
TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list) TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
{ {
DBUG_ENTER("reopen_name_locked_table"); DBUG_ENTER("reopen_name_locked_table");

View file

@ -508,7 +508,7 @@ my_bool Query_cache_query::try_lock_writing()
void Query_cache_query::lock_reading() void Query_cache_query::lock_reading()
{ {
MUTEX_LOCK(&clients_guard); MUTEX_LOCK(&clients_guard);
if ( ++clients == 1 ) if (++clients == 1)
SEM_LOCK(&lock); SEM_LOCK(&lock);
MUTEX_UNLOCK(&clients_guard); MUTEX_UNLOCK(&clients_guard);
} }
@ -961,7 +961,7 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
// Check access; // Check access;
block_table= query_block->table(0); block_table= query_block->table(0);
block_table_end= block_table+query_block->n_tables; block_table_end= block_table+query_block->n_tables;
for ( ; block_table != block_table_end; block_table++) for (; block_table != block_table_end; block_table++)
{ {
TABLE_LIST table_list; TABLE_LIST table_list;
bzero((char*) &table_list,sizeof(table_list)); bzero((char*) &table_list,sizeof(table_list));
@ -1040,7 +1040,7 @@ void Query_cache::invalidate(THD *thd, TABLE_LIST *tables_used,
using_transactions = using_transactions && using_transactions = using_transactions &&
(thd->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN)); (thd->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN));
for ( ; tables_used; tables_used=tables_used->next) for (; tables_used; tables_used=tables_used->next)
{ {
DBUG_ASSERT(!using_transactions || tables_used->table!=0); DBUG_ASSERT(!using_transactions || tables_used->table!=0);
if (using_transactions && if (using_transactions &&
@ -1069,7 +1069,7 @@ void Query_cache::invalidate(CHANGED_TABLE_LIST *tables_used)
if (query_cache_size > 0) if (query_cache_size > 0)
{ {
DUMP(this); DUMP(this);
for ( ; tables_used; tables_used=tables_used->next) for (; tables_used; tables_used=tables_used->next)
{ {
invalidate_table((byte*) tables_used->key, tables_used->key_length); invalidate_table((byte*) tables_used->key, tables_used->key_length);
DBUG_PRINT("qcache", (" db %s, table %s", tables_used->key, DBUG_PRINT("qcache", (" db %s, table %s", tables_used->key,
@ -1188,15 +1188,17 @@ void Query_cache::pack(ulong join_limit, uint iteration_limit)
void Query_cache::destroy() void Query_cache::destroy()
{ {
if ( !initialized ) DBUG_ENTER("Query_cache::destroy");
if (!initialized)
{ {
DBUG_PRINT("qcache", ("Query Cache not initialized")); DBUG_PRINT("qcache", ("Query Cache not initialized"));
return;
} }
DBUG_ENTER("Query_cache::destroy"); else
free_cache(1); {
pthread_mutex_destroy(&structure_guard_mutex); free_cache(1);
initialized = 0; pthread_mutex_destroy(&structure_guard_mutex);
initialized = 0;
}
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@ -2138,8 +2140,10 @@ void Query_cache::split_block(Query_cache_block *block, ulong len)
new_block->pnext->pprev = new_block; new_block->pnext->pprev = new_block;
if (block->type == Query_cache_block::FREE) if (block->type == Query_cache_block::FREE)
{
// if block was free then it already joined with all free neighbours // if block was free then it already joined with all free neighbours
insert_into_free_memory_list(new_block); insert_into_free_memory_list(new_block);
}
else else
free_memory_block(new_block); free_memory_block(new_block);
@ -2870,7 +2874,7 @@ void Query_cache::bins_dump()
{ {
uint i; uint i;
if ( !initialized ) if (!initialized)
{ {
DBUG_PRINT("qcache", ("Query Cache not initialized")); DBUG_PRINT("qcache", ("Query Cache not initialized"));
return; return;
@ -2911,8 +2915,7 @@ void Query_cache::bins_dump()
void Query_cache::cache_dump() void Query_cache::cache_dump()
{ {
if (!initialized)
if ( !initialized )
{ {
DBUG_PRINT("qcache", ("Query Cache not initialized")); DBUG_PRINT("qcache", ("Query Cache not initialized"));
return; return;
@ -2939,7 +2942,7 @@ void Query_cache::cache_dump()
void Query_cache::queries_dump() void Query_cache::queries_dump()
{ {
if ( !initialized ) if (!initialized)
{ {
DBUG_PRINT("qcache", ("Query Cache not initialized")); DBUG_PRINT("qcache", ("Query Cache not initialized"));
return; return;
@ -3001,8 +3004,7 @@ void Query_cache::queries_dump()
void Query_cache::tables_dump() void Query_cache::tables_dump()
{ {
if (!initialized)
if ( !initialized )
{ {
DBUG_PRINT("qcache", ("Query Cache not initialized")); DBUG_PRINT("qcache", ("Query Cache not initialized"));
return; return;
@ -3072,8 +3074,8 @@ my_bool Query_cache::check_integrity(bool not_locked)
// Check memory allocation // Check memory allocation
if (block->pnext == first_block) // Is it last block? if (block->pnext == first_block) // Is it last block?
{ {
if ( ((byte*)block) + block->length != if (((byte*)block) + block->length !=
((byte*)first_block) + query_cache_size ) ((byte*)first_block) + query_cache_size)
{ {
DBUG_PRINT("error", DBUG_PRINT("error",
("block 0x%lx, type %u, ended at 0x%lx, but cache ended at 0x%lx", ("block 0x%lx, type %u, ended at 0x%lx, but cache ended at 0x%lx",
@ -3093,16 +3095,16 @@ my_bool Query_cache::check_integrity(bool not_locked)
(ulong) ((byte*)block->pnext))); (ulong) ((byte*)block->pnext)));
} }
if (block->type == Query_cache_block::FREE) if (block->type == Query_cache_block::FREE)
free+=block->length; free+= block->length;
else else
used+=block->length; used+= block->length;
switch(block->type) { switch(block->type) {
case Query_cache_block::FREE: case Query_cache_block::FREE:
{ {
Query_cache_memory_bin *bin = *((Query_cache_memory_bin **) Query_cache_memory_bin *bin = *((Query_cache_memory_bin **)
block->data()); block->data());
//is it correct pointer? //is it correct pointer?
if ( ((byte*)bin) < ((byte*)bins) || if (((byte*)bin) < ((byte*)bins) ||
((byte*)bin) >= ((byte*)first_block)) ((byte*)bin) >= ((byte*)first_block))
{ {
DBUG_PRINT("error", DBUG_PRINT("error",
@ -3153,7 +3155,7 @@ my_bool Query_cache::check_integrity(bool not_locked)
case Query_cache_block::RESULT: case Query_cache_block::RESULT:
{ {
Query_cache_block * query_block = block->result()->parent(); Query_cache_block * query_block = block->result()->parent();
if ( ((byte*)query_block) < ((byte*)first_block) || if (((byte*)query_block) < ((byte*)first_block) ||
((byte*)query_block) >= (((byte*)first_block) + query_cache_size)) ((byte*)query_block) >= (((byte*)first_block) + query_cache_size))
{ {
DBUG_PRINT("error", DBUG_PRINT("error",
@ -3305,7 +3307,7 @@ my_bool Query_cache::in_blocks(Query_cache_block * point)
(ulong) block->pprev->pnext, (ulong) block->pprev->pnext,
(ulong) point)); (ulong) point));
//back trace //back trace
for(; block != point; block = block->pnext) for (; block != point; block = block->pnext)
DBUG_PRINT("error", ("back trace 0x%lx", (ulong) block)); DBUG_PRINT("error", ("back trace 0x%lx", (ulong) block));
result = 1; result = 1;
goto err1; goto err1;
@ -3333,7 +3335,7 @@ err1:
(ulong) block->pnext->pprev, (ulong) block->pnext->pprev,
(ulong) point)); (ulong) point));
//back trace //back trace
for(; block != point; block = block->pprev) for (; block != point; block = block->pprev)
DBUG_PRINT("error", ("back trace 0x%lx", (ulong) block)); DBUG_PRINT("error", ("back trace 0x%lx", (ulong) block));
result = 1; result = 1;
goto err2; goto err2;
@ -3362,7 +3364,7 @@ my_bool Query_cache::in_list(Query_cache_block * root,
(ulong) block->prev->next, (ulong) block->prev->next,
(ulong) point)); (ulong) point));
//back trace //back trace
for(; block != point; block = block->next) for (; block != point; block = block->next)
DBUG_PRINT("error", ("back trace 0x%lx", (ulong) block)); DBUG_PRINT("error", ("back trace 0x%lx", (ulong) block));
result = 1; result = 1;
goto err1; goto err1;
@ -3436,7 +3438,7 @@ my_bool Query_cache::in_table_list(Query_cache_block_table * root,
(ulong) table->prev->next->block(), (ulong) table->prev->next->block(),
(ulong) point, (ulong) point->block())); (ulong) point, (ulong) point->block()));
//back trace //back trace
for(; table != point; table = table->next) for (; table != point; table = table->next)
DBUG_PRINT("error", ("back trace 0x%lx(0x%lx)", DBUG_PRINT("error", ("back trace 0x%lx(0x%lx)",
(ulong) table, (ulong) table->block())); (ulong) table, (ulong) table->block()));
result = 1; result = 1;

View file

@ -286,17 +286,18 @@ inline static void list_include(CHANGED_TABLE_LIST** prev,
} }
/* add table to list of changed in transaction tables */ /* add table to list of changed in transaction tables */
void THD::add_changed_table(TABLE *table) void THD::add_changed_table(TABLE *table)
{ {
DBUG_ENTER("THD::add_changed_table (table)"); DBUG_ENTER("THD::add_changed_table(table)");
DBUG_ASSERT((options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN)) && DBUG_ASSERT((options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN)) &&
table->file->has_transactions()); table->file->has_transactions());
CHANGED_TABLE_LIST** prev = &transaction.changed_tables; CHANGED_TABLE_LIST** prev = &transaction.changed_tables;
CHANGED_TABLE_LIST* curr = transaction.changed_tables; CHANGED_TABLE_LIST* curr = transaction.changed_tables;
for(; curr; prev = &(curr->next), curr = curr->next) for (; curr; prev = &(curr->next), curr = curr->next)
{ {
int cmp = (long)curr->key_length - (long)table->key_length; int cmp = (long)curr->key_length - (long)table->key_length;
if (cmp < 0) if (cmp < 0)
@ -313,7 +314,8 @@ void THD::add_changed_table(TABLE *table)
{ {
list_include(prev, curr, changed_table_dup(table)); list_include(prev, curr, changed_table_dup(table));
DBUG_PRINT("info", DBUG_PRINT("info",
("key_length %u %u", table->key_length, (*prev)->key_length)); ("key_length %u %u", table->key_length,
(*prev)->key_length));
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
else if (cmp == 0) else if (cmp == 0)
@ -324,10 +326,12 @@ void THD::add_changed_table(TABLE *table)
} }
} }
*prev = changed_table_dup(table); *prev = changed_table_dup(table);
DBUG_PRINT("info", ("key_length %u %u", table->key_length, (*prev)->key_length)); DBUG_PRINT("info", ("key_length %u %u", table->key_length,
(*prev)->key_length));
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
CHANGED_TABLE_LIST* THD::changed_table_dup(TABLE *table) CHANGED_TABLE_LIST* THD::changed_table_dup(TABLE *table)
{ {
CHANGED_TABLE_LIST* new_table = CHANGED_TABLE_LIST* new_table =
@ -603,7 +607,7 @@ bool select_export::send_data(List<Item> &items)
bfill(space,sizeof(space),' '); bfill(space,sizeof(space),' ');
} }
uint length=item->max_length-used_length; uint length=item->max_length-used_length;
for ( ; length > sizeof(space) ; length-=sizeof(space)) for (; length > sizeof(space) ; length-=sizeof(space))
{ {
if (my_b_write(&cache,(byte*) space,sizeof(space))) if (my_b_write(&cache,(byte*) space,sizeof(space)))
goto err; goto err;

View file

@ -185,9 +185,9 @@ typedef struct st_copy_info {
ha_rows records; ha_rows records;
ha_rows deleted; ha_rows deleted;
ha_rows copied; ha_rows copied;
ha_rows error; ha_rows error_count;
enum enum_duplicates handle_duplicates; enum enum_duplicates handle_duplicates;
int escape_char, errorno; int escape_char, last_errno;
} COPY_INFO; } COPY_INFO;

View file

@ -198,7 +198,7 @@ cleanup:
/*************************************************************************** /***************************************************************************
** delete multiple tables from join Delete multiple tables from join
***************************************************************************/ ***************************************************************************/
#define MEM_STRIP_BUF_SIZE sortbuff_size #define MEM_STRIP_BUF_SIZE sortbuff_size
@ -357,7 +357,7 @@ void multi_delete::send_error(uint errcode,const char *err)
if (!deleted) if (!deleted)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
/* Somthing alredy deleted consequently we have to invalidate cache */ /* Something already deleted so we have to invalidate cache */
query_cache_invalidate3(thd, delete_tables, 1); query_cache_invalidate3(thd, delete_tables, 1);
/* Below can happen when thread is killed early ... */ /* Below can happen when thread is killed early ... */
@ -436,6 +436,8 @@ int multi_delete::do_deletes(bool from_send_error)
/* /*
Send ok to the client
return: 0 sucess return: 0 sucess
1 error 1 error
*/ */
@ -484,7 +486,7 @@ bool multi_delete::send_eof()
/*************************************************************************** /***************************************************************************
* TRUNCATE TABLE TRUNCATE TABLE
****************************************************************************/ ****************************************************************************/
/* /*
@ -527,9 +529,9 @@ int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
if ((error= (int) !(open_temporary_table(thd, path, table_list->db, if ((error= (int) !(open_temporary_table(thd, path, table_list->db,
table_list->real_name, 1)))) table_list->real_name, 1))))
(void) rm_temporary_table(table_type, path); (void) rm_temporary_table(table_type, path);
/* Sasha: if we return here we will not have binloged the truncation and /*
we will not send_ok() to the client. Yes, we do need better coverage Sasha: if we return here we will not have binloged the truncation and
testing, this bug has been here for a few months :-). we will not send_ok() to the client.
*/ */
goto end; goto end;
} }

View file

@ -212,7 +212,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
if (cond) if (cond)
{ {
err=err; err=err;
if(!cond->val_int()) if (!cond->val_int())
continue; continue;
} }
if (num_rows>=offset_limit) if (num_rows>=offset_limit)

View file

@ -449,7 +449,7 @@ int write_record(TABLE *table,COPY_INFO *info)
err: err:
if (key) if (key)
my_afree(key); my_afree(key);
info->errorno= error; info->last_errno= error;
table->file->print_error(error,MYF(0)); table->file->print_error(error,MYF(0));
return 1; return 1;
} }
@ -1181,7 +1181,7 @@ bool delayed_insert::handle_inserts(void)
thd.net.last_errno = 0; // reset error for binlog thd.net.last_errno = 0; // reset error for binlog
if (write_record(table,&info)) if (write_record(table,&info))
{ {
info.error++; // Ignore errors info.error_count++; // Ignore errors
thread_safe_increment(delayed_insert_errors,&LOCK_delayed_status); thread_safe_increment(delayed_insert_errors,&LOCK_delayed_status);
row->log_query = 0; row->log_query = 0;
} }

View file

@ -507,7 +507,7 @@ int yylex(void *arg)
length= (uint) (lex->ptr - lex->tok_start)-1; length= (uint) (lex->ptr - lex->tok_start)-1;
if (lex->ignore_space) if (lex->ignore_space)
{ {
for ( ; state_map[c] == STATE_SKIP ; c= yyGet()); for (; state_map[c] == STATE_SKIP ; c= yyGet());
} }
if (c == '.' && (state_map[yyPeek()] == STATE_IDENT || if (c == '.' && (state_map[yyPeek()] == STATE_IDENT ||
state_map[yyPeek()] == STATE_NUMBER_IDENT)) state_map[yyPeek()] == STATE_NUMBER_IDENT))

View file

@ -22,8 +22,10 @@ class Table_ident;
class sql_exchange; class sql_exchange;
class LEX_COLUMN; class LEX_COLUMN;
// The following hack is needed because mysql_yacc.cc does not define /*
// YYSTYPE before including this file The following hack is needed because mysql_yacc.cc does not define
YYSTYPE before including this file
*/
#ifdef MYSQL_YACC #ifdef MYSQL_YACC
#define LEX_YYSTYPE void * #define LEX_YYSTYPE void *
@ -94,20 +96,24 @@ typedef List<Item> List_item;
typedef struct st_lex_master_info typedef struct st_lex_master_info
{ {
char* host, *user, *password,*log_file_name; char *host, *user, *password, *log_file_name;
uint port, connect_retry; uint port, connect_retry;
ulonglong pos; ulonglong pos;
ulong server_id; ulong server_id;
char* relay_log_name; char *relay_log_name;
ulong relay_log_pos; ulong relay_log_pos;
} LEX_MASTER_INFO; } LEX_MASTER_INFO;
enum sub_select_type {UNSPECIFIED_TYPE,UNION_TYPE, INTERSECT_TYPE, EXCEPT_TYPE, NOT_A_SELECT}; enum sub_select_type
{
UNSPECIFIED_TYPE, UNION_TYPE, INTERSECT_TYPE, EXCEPT_TYPE, NOT_A_SELECT
};
/* The state of the lex parsing for selects */ /* The state of the lex parsing for selects */
typedef struct st_select_lex { typedef struct st_select_lex
{
enum sub_select_type linkage; enum sub_select_type linkage;
char *db,*db1,*table1,*db2,*table2; /* For outer join using .. */ char *db,*db1,*table1,*db2,*table2; /* For outer join using .. */
Item *where,*having; Item *where,*having;
@ -126,7 +132,8 @@ typedef struct st_select_lex {
} SELECT_LEX; } SELECT_LEX;
class Set_option :public Sql_alloc { class Set_option :public Sql_alloc
{
public: public:
const char *name; const char *name;
Item *item; Item *item;
@ -140,7 +147,8 @@ public:
/* The state of the lex parsing. This is saved in the THD struct */ /* The state of the lex parsing. This is saved in the THD struct */
typedef struct st_lex { typedef struct st_lex
{
uint yylineno,yytoklen; /* Simulate lex */ uint yylineno,yytoklen; /* Simulate lex */
LEX_YYSTYPE yylval; LEX_YYSTYPE yylval;
SELECT_LEX select_lex, *select; SELECT_LEX select_lex, *select;

View file

@ -285,7 +285,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
info.records-info.copied,thd->cuted_fields); info.records-info.copied,thd->cuted_fields);
send_ok(&thd->net,info.copied+info.deleted,0L,name); send_ok(&thd->net,info.copied+info.deleted,0L,name);
// on the slave thd->query is never initialized // on the slave thd->query is never initialized
if(!thd->slave_thread) if (!thd->slave_thread)
mysql_update_log.write(thd,thd->query,thd->query_length); mysql_update_log.write(thd,thd->query,thd->query_length);
if (!using_transactions) if (!using_transactions)
@ -435,7 +435,7 @@ read_sep_field(THD *thd,COPY_INFO &info,TABLE *table,
{ // Last record { // Last record
if (sql_field == (Item_field*) fields.head()) if (sql_field == (Item_field*) fields.head())
break; break;
for ( ; sql_field ; sql_field=(Item_field*) it++) for (; sql_field ; sql_field=(Item_field*) it++)
{ {
sql_field->field->set_null(); sql_field->field->set_null();
sql_field->field->reset(); sql_field->field->reset();
@ -475,8 +475,10 @@ READ_INFO::unescape(char chr)
} }
/* Read a line using buffering */ /*
/* If last line is empty (in line mode) then it isn't outputed */ Read a line using buffering
If last line is empty (in line mode) then it isn't outputed
*/
READ_INFO::READ_INFO(File file_par, uint tot_length, String &field_term, READ_INFO::READ_INFO(File file_par, uint tot_length, String &field_term,
@ -535,10 +537,11 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, String &field_term,
} }
else else
{ {
/* init_io_cache() will not initialize read_function member /*
if the cache is READ_NET. The reason is explained in init_io_cache() will not initialize read_function member
mysys/mf_iocache.c. So we work around the problem with a if the cache is READ_NET. The reason is explained in
manual assignment mysys/mf_iocache.c. So we work around the problem with a
manual assignment
*/ */
if (get_it_from_net) if (get_it_from_net)
cache.read_function = _my_b_net_read; cache.read_function = _my_b_net_read;

View file

@ -101,7 +101,7 @@ static void test_signal(int sig_ptr)
static void init_signals(void) static void init_signals(void)
{ {
int signals[7] = {SIGINT,SIGILL,SIGFPE,SIGSEGV,SIGTERM,SIGBREAK,SIGABRT } ; int signals[7] = {SIGINT,SIGILL,SIGFPE,SIGSEGV,SIGTERM,SIGBREAK,SIGABRT } ;
for(int i=0 ; i < 7 ; i++) for (int i=0 ; i < 7 ; i++)
signal( signals[i], test_signal) ; signal( signals[i], test_signal) ;
} }
#endif #endif
@ -2216,8 +2216,8 @@ mysql_execute_command(void)
} }
if (check_db_used(thd,tables) || end_active_trans(thd)) if (check_db_used(thd,tables) || end_active_trans(thd))
goto error; goto error;
if (check_table_access(thd, SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL , tables) if (check_table_access(thd, SELECT_ACL | INSERT_ACL | UPDATE_ACL |
|| (grant_option && check_grant(thd,SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL,tables))) DELETE_ACL, tables))
goto error; goto error;
thd->in_lock_tables=1; thd->in_lock_tables=1;
thd->options|= OPTION_TABLE_LOCK; thd->options|= OPTION_TABLE_LOCK;

View file

@ -752,7 +752,7 @@ int change_master(THD* thd, MASTER_INFO* mi)
{ {
need_relay_log_purge = 0; need_relay_log_purge = 0;
mi->rli.skip_log_purge=1; mi->rli.skip_log_purge=1;
strnmov(mi->rli.relay_log_name,lex_mi->relay_log_name, strmake(mi->rli.relay_log_name,lex_mi->relay_log_name,
sizeof(mi->rli.relay_log_name)-1); sizeof(mi->rli.relay_log_name)-1);
} }
@ -790,8 +790,8 @@ int change_master(THD* thd, MASTER_INFO* mi)
} }
mi->rli.master_log_pos = mi->master_log_pos; mi->rli.master_log_pos = mi->master_log_pos;
DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos)); DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos));
strnmov(mi->rli.master_log_name,mi->master_log_name, strmake(mi->rli.master_log_name,mi->master_log_name,
sizeof(mi->rli.master_log_name)); sizeof(mi->rli.master_log_name)-1);
if (!mi->rli.master_log_name[0]) // uninitialized case if (!mi->rli.master_log_name[0]) // uninitialized case
mi->rli.master_log_pos=0; mi->rli.master_log_pos=0;

View file

@ -1,6 +1,3 @@
#ifndef SQL_REPL_H
#define SQL_REPL_H
#include "slave.h" #include "slave.h"
typedef struct st_slave_info typedef struct st_slave_info
@ -27,7 +24,7 @@ extern bool opt_sporadic_binlog_dump_fail;
#define KICK_SLAVE(thd) thd->awake(0 /* do not prepare to die*/); #define KICK_SLAVE(thd) thd->awake(0 /* do not prepare to die*/);
File open_binlog(IO_CACHE *log, const char *log_file_name, File open_binlog(IO_CACHE *log, const char *log_file_name,
const char **errmsg); const char **errmsg);
int start_slave(THD* thd, MASTER_INFO* mi, bool net_report); int start_slave(THD* thd, MASTER_INFO* mi, bool net_report);
int stop_slave(THD* thd, MASTER_INFO* mi, bool net_report); int stop_slave(THD* thd, MASTER_INFO* mi, bool net_report);
@ -58,6 +55,3 @@ typedef struct st_load_file_info
} LOAD_FILE_INFO; } LOAD_FILE_INFO;
int log_loaded_block(IO_CACHE* file); int log_loaded_block(IO_CACHE* file);
#endif

View file

@ -175,8 +175,8 @@ int handle_select(THD *thd, LEX *lex, select_result *result)
/***************************************************************************** /*****************************************************************************
** check fields, find best join, do the select and output fields. Check fields, find best join, do the select and output fields.
** mysql_select assumes that all tables are already opened mysql_select assumes that all tables are already opened
*****************************************************************************/ *****************************************************************************/
int int
@ -731,11 +731,11 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
} }
/* /*
** If we have different sort & group then we must sort the data by group If we have different sort & group then we must sort the data by group
** and copy it to another tmp table and copy it to another tmp table
** This code is also used if we are using distinct something This code is also used if we are using distinct something
** we haven't been able to store in the temporary table yet we haven't been able to store in the temporary table yet
** like SEC_TO_TIME(SUM(...)). like SEC_TO_TIME(SUM(...)).
*/ */
if (group && (!test_if_subpart(group,order) || select_distinct) || if (group && (!test_if_subpart(group,order) || select_distinct) ||
@ -889,8 +889,8 @@ err:
} }
/***************************************************************************** /*****************************************************************************
** Create JOIN_TABS, make a guess about the table types, Create JOIN_TABS, make a guess about the table types,
** Approximate how many records will be used in each table Approximate how many records will be used in each table
*****************************************************************************/ *****************************************************************************/
static ha_rows get_quick_record_count(SQL_SELECT *select,TABLE *table, static ha_rows get_quick_record_count(SQL_SELECT *select,TABLE *table,
@ -1210,11 +1210,11 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
/***************************************************************************** /*****************************************************************************
** check with keys are used and with tables references with tables Check with keys are used and with tables references with tables
** updates in stat: Updates in stat:
** keys Bitmap of all used keys keys Bitmap of all used keys
** const_keys Bitmap of all keys with may be used with quick_select const_keys Bitmap of all keys with may be used with quick_select
** keyuse Pointer to possible keys keyuse Pointer to possible keys
*****************************************************************************/ *****************************************************************************/
typedef struct key_field_t { // Used when finding key fields typedef struct key_field_t { // Used when finding key fields
@ -1446,8 +1446,8 @@ add_key_fields(JOIN_TAB *stat,KEY_FIELD **key_fields,uint *and_level,
} }
/* /*
** Add all keys with uses 'field' for some keypart Add all keys with uses 'field' for some keypart
** If field->and_level != and_level then only mark key_part as const_part If field->and_level != and_level then only mark key_part as const_part
*/ */
static uint static uint
@ -1582,9 +1582,9 @@ sort_keyuse(KEYUSE *a,KEYUSE *b)
/* /*
** Update keyuse array with all possible keys we can use to fetch rows Update keyuse array with all possible keys we can use to fetch rows
** join_tab is a array in tablenr_order join_tab is a array in tablenr_order
** stat is a reference array in 'prefered' order. stat is a reference array in 'prefered' order.
*/ */
static bool static bool
@ -1623,9 +1623,9 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
} }
/* /*
** remove ref if there is a keypart which is a ref and a const. Remove ref if there is a keypart which is a ref and a const.
** remove keyparts without previous keyparts. Remove keyparts without previous keyparts.
** Special treatment for ft-keys. Special treatment for ft-keys.
*/ */
if (keyuse->elements) if (keyuse->elements)
{ {
@ -1675,8 +1675,8 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
/***************************************************************************** /*****************************************************************************
** Go through all combinations of not marked tables and find the one Go through all combinations of not marked tables and find the one
** which uses least records which uses least records
*****************************************************************************/ *****************************************************************************/
/* Save const tables first as used tables */ /* Save const tables first as used tables */
@ -1691,7 +1691,7 @@ set_position(JOIN *join,uint idx,JOIN_TAB *table,KEYUSE *key)
/* Move the const table as down as possible in best_ref */ /* Move the const table as down as possible in best_ref */
JOIN_TAB **pos=join->best_ref+idx+1; JOIN_TAB **pos=join->best_ref+idx+1;
JOIN_TAB *next=join->best_ref[idx]; JOIN_TAB *next=join->best_ref[idx];
for ( ;next != table ; pos++) for (;next != table ; pos++)
{ {
JOIN_TAB *tmp=pos[0]; JOIN_TAB *tmp=pos[0];
pos[0]=next; pos[0]=next;
@ -1782,12 +1782,12 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
found_ref|= keyuse->used_tables; found_ref|= keyuse->used_tables;
} }
/* /*
** If we find a ref, assume this table matches a proportional If we find a ref, assume this table matches a proportional
** part of this table. part of this table.
** For example 100 records matching a table with 5000 records For example 100 records matching a table with 5000 records
** gives 5000/100 = 50 records per key gives 5000/100 = 50 records per key
** Constant tables are ignored and to avoid bad matches, Constant tables are ignored and to avoid bad matches,
** we don't make rec less than 100. we don't make rec less than 100.
*/ */
if (keyuse->used_tables & if (keyuse->used_tables &
(map=(keyuse->used_tables & ~join->const_table_map))) (map=(keyuse->used_tables & ~join->const_table_map)))
@ -1808,7 +1808,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
} while (keyuse->table == table && keyuse->key == key); } while (keyuse->table == table && keyuse->key == key);
/* /*
** Assume that that each key matches a proportional part of table. Assume that that each key matches a proportional part of table.
*/ */
if (!found_part && !ft_key) if (!found_part && !ft_key)
continue; // Nothing usable found continue; // Nothing usable found
@ -1816,13 +1816,13 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
rec=1L; // Fix for small tables rec=1L; // Fix for small tables
/* /*
** ft-keys require special treatment ft-keys require special treatment
*/ */
if (ft_key) if (ft_key)
{ {
/* /*
** Really, there should be records=0.0 (yes!) Really, there should be records=0.0 (yes!)
** but 1.0 would be probably safer but 1.0 would be probably safer
*/ */
tmp=prev_record_reads(join,found_ref); tmp=prev_record_reads(join,found_ref);
records=1.0; records=1.0;
@ -1830,7 +1830,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
else else
{ {
/* /*
** Check if we found full key Check if we found full key
*/ */
if (found_part == PREV_BITS(uint,keyinfo->key_parts)) if (found_part == PREV_BITS(uint,keyinfo->key_parts))
{ /* use eq key */ { /* use eq key */
@ -1877,17 +1877,18 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
else else
{ {
/* /*
** Use as much key-parts as possible and a uniq key is better Use as much key-parts as possible and a uniq key is better
** than a not unique key than a not unique key
** Set tmp to (previous record count) * (records / combination) Set tmp to (previous record count) * (records / combination)
*/ */
if ((found_part & 1) && if ((found_part & 1) &&
!(table->file->index_flags(key) & HA_ONLY_WHOLE_INDEX)) !(table->file->index_flags(key) & HA_ONLY_WHOLE_INDEX))
{ {
max_key_part=max_part_bit(found_part); max_key_part=max_part_bit(found_part);
/* Check if quick_range could determinate how many rows we /*
will match */ Check if quick_range could determinate how many rows we
will match
*/
if (table->quick_keys & ((key_map) 1 << key) && if (table->quick_keys & ((key_map) 1 << key) &&
table->quick_key_parts[key] <= max_key_part) table->quick_key_parts[key] <= max_key_part)
tmp=records= (double) table->quick_rows[key]; tmp=records= (double) table->quick_rows[key];
@ -1899,18 +1900,18 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
else else
{ {
/* /*
** Assume that the first key part matches 1% of the file Assume that the first key part matches 1% of the file
** and that the hole key matches 10 (dupplicates) or 1 and that the hole key matches 10 (dupplicates) or 1
** (unique) records. (unique) records.
** Assume also that more key matches proportionally more Assume also that more key matches proportionally more
** records records
** This gives the formula: This gives the formula:
** records= (x * (b-a) + a*c-b)/(c-1) records= (x * (b-a) + a*c-b)/(c-1)
**
** b = records matched by whole key b = records matched by whole key
** a = records matched by first key part (10% of all records?) a = records matched by first key part (10% of all records?)
** c = number of key parts in key c = number of key parts in key
** x = used key parts (1 <= x <= c) x = used key parts (1 <= x <= c)
*/ */
double rec_per_key; double rec_per_key;
if (!(rec_per_key=(double) if (!(rec_per_key=(double)
@ -2034,7 +2035,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
/* /*
** Find how much space the prevous read not const tables takes in cache Find how much space the prevous read not const tables takes in cache
*/ */
static void calc_used_field_length(THD *thd, JOIN_TAB *join_tab) static void calc_used_field_length(THD *thd, JOIN_TAB *join_tab)
@ -2110,7 +2111,7 @@ prev_record_reads(JOIN *join,table_map found_ref)
/***************************************************************************** /*****************************************************************************
** Set up join struct according to best position. Set up join struct according to best position.
*****************************************************************************/ *****************************************************************************/
static bool static bool
@ -2176,7 +2177,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
KEY *keyinfo; KEY *keyinfo;
/* /*
** Use best key from find_best Use best key from find_best
*/ */
table=j->table; table=j->table;
key=keyuse->key; key=keyuse->key;
@ -2325,8 +2326,8 @@ get_store_key(THD *thd, KEYUSE *keyuse, table_map used_tables,
} }
/* /*
** This function is only called for const items on fields which are keys This function is only called for const items on fields which are keys
** returns 1 if there was some conversion made when the field was stored. returns 1 if there was some conversion made when the field was stored.
*/ */
bool bool
@ -2603,7 +2604,7 @@ make_join_readinfo(JOIN *join,uint options)
break; break;
case JT_ALL: case JT_ALL:
/* /*
** if previous table use cache If previous table use cache
*/ */
table->status=STATUS_NO_RECORD; table->status=STATUS_NO_RECORD;
if (i != join->const_tables && !(options & SELECT_NO_JOIN_CACHE) && if (i != join->const_tables && !(options & SELECT_NO_JOIN_CACHE) &&
@ -2715,8 +2716,10 @@ join_free(JOIN *join)
} }
join->table=0; join->table=0;
} }
// We are not using tables anymore /*
// Unlock all tables. We may be in an INSERT .... SELECT statement. We are not using tables anymore
Unlock all tables. We may be in an INSERT .... SELECT statement.
*/
if (join->lock && join->thd->lock && if (join->lock && join->thd->lock &&
!(join->select_options & SELECT_NO_UNLOCK)) !(join->select_options & SELECT_NO_UNLOCK))
{ {
@ -2733,19 +2736,19 @@ join_free(JOIN *join)
/***************************************************************************** /*****************************************************************************
** Remove the following expressions from ORDER BY and GROUP BY: Remove the following expressions from ORDER BY and GROUP BY:
** Constant expressions Constant expressions
** Expression that only uses tables that are of type EQ_REF and the reference Expression that only uses tables that are of type EQ_REF and the reference
** is in the ORDER list or if all refereed tables are of the above type. is in the ORDER list or if all refereed tables are of the above type.
**
** In the following, the X field can be removed: In the following, the X field can be removed:
** SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t1.a,t2.X SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t1.a,t2.X
** SELECT * FROM t1,t2,t3 WHERE t1.a=t2.a AND t2.b=t3.b ORDER BY t1.a,t3.X SELECT * FROM t1,t2,t3 WHERE t1.a=t2.a AND t2.b=t3.b ORDER BY t1.a,t3.X
**
** These can't be optimized: These can't be optimized:
** SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.X,t1.a SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.X,t1.a
** SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b=t2.b ORDER BY t1.a,t2.c SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b=t2.b ORDER BY t1.a,t2.c
** SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.b,t1.a SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.b,t1.a
*****************************************************************************/ *****************************************************************************/
static bool static bool
@ -2785,7 +2788,7 @@ eq_ref_table(JOIN *join, ORDER *start_order, JOIN_TAB *tab)
} }
} }
/* Check that there was no reference to table before sort order */ /* Check that there was no reference to table before sort order */
for ( ; found && start_order ; start_order=start_order->next) for (; found && start_order ; start_order=start_order->next)
{ {
if (start_order->used & map) if (start_order->used & map)
{ {
@ -2803,7 +2806,7 @@ static bool
only_eq_ref_tables(JOIN *join,ORDER *order,table_map tables) only_eq_ref_tables(JOIN *join,ORDER *order,table_map tables)
{ {
if (specialflag & SPECIAL_SAFE_MODE) if (specialflag & SPECIAL_SAFE_MODE)
return 0; // skip this optimize /* purecov: inspected */ return 0; // skip this optimize /* purecov: inspected */
for (JOIN_TAB **tab=join->map2table ; tables ; tab++, tables>>=1) for (JOIN_TAB **tab=join->map2table ; tables ; tab++, tables>>=1)
{ {
if (tables & 1 && !eq_ref_table(join, order, *tab)) if (tables & 1 && !eq_ref_table(join, order, *tab))
@ -2819,7 +2822,7 @@ static void update_depend_map(JOIN *join)
{ {
JOIN_TAB *join_tab=join->join_tab, *end=join_tab+join->tables; JOIN_TAB *join_tab=join->join_tab, *end=join_tab+join->tables;
for ( ; join_tab != end ; join_tab++) for (; join_tab != end ; join_tab++)
{ {
TABLE_REF *ref= &join_tab->ref; TABLE_REF *ref= &join_tab->ref;
table_map depend_map=0; table_map depend_map=0;
@ -2843,7 +2846,7 @@ static void update_depend_map(JOIN *join)
static void update_depend_map(JOIN *join, ORDER *order) static void update_depend_map(JOIN *join, ORDER *order)
{ {
for ( ; order ; order=order->next) for (; order ; order=order->next)
{ {
table_map depend_map; table_map depend_map;
order->item[0]->update_used_tables(); order->item[0]->update_used_tables();
@ -2973,12 +2976,12 @@ static void clear_tables(JOIN *join)
} }
/***************************************************************************** /*****************************************************************************
** Make som simple condition optimization: Make som simple condition optimization:
** If there is a test 'field = const' change all refs to 'field' to 'const' If there is a test 'field = const' change all refs to 'field' to 'const'
** Remove all dummy tests 'item = item', 'const op const'. Remove all dummy tests 'item = item', 'const op const'.
** Remove all 'item is NULL', when item can never be null! Remove all 'item is NULL', when item can never be null!
** item->marker should be 0 for all items on entry item->marker should be 0 for all items on entry
** Return in cond_value FALSE if condition is impossible (1 = 2) Return in cond_value FALSE if condition is impossible (1 = 2)
*****************************************************************************/ *****************************************************************************/
class COND_CMP :public ilink { class COND_CMP :public ilink {
@ -3000,8 +3003,8 @@ template class List_iterator<Item_func_match>;
#endif #endif
/* /*
** change field = field to field = const for each found field = const in the change field = field to field = const for each found field = const in the
** and_level and_level
*/ */
static void static void
@ -3146,8 +3149,8 @@ optimize_cond(COND *conds,Item::cond_result *cond_value)
DBUG_EXECUTE("where",print_where(conds,"original");); DBUG_EXECUTE("where",print_where(conds,"original"););
propagate_cond_constants((I_List<COND_CMP> *) 0,conds,conds); propagate_cond_constants((I_List<COND_CMP> *) 0,conds,conds);
/* /*
** Remove all instances of item == item Remove all instances of item == item
** Remove all and-levels where CONST item != CONST item Remove all and-levels where CONST item != CONST item
*/ */
DBUG_EXECUTE("where",print_where(conds,"after const change");); DBUG_EXECUTE("where",print_where(conds,"after const change"););
conds=remove_eq_conds(conds,cond_value) ; conds=remove_eq_conds(conds,cond_value) ;
@ -3157,11 +3160,11 @@ optimize_cond(COND *conds,Item::cond_result *cond_value)
/* /*
** remove const and eq items. Return new item, or NULL if no condition Remove const and eq items. Return new item, or NULL if no condition
** cond_value is set to according: cond_value is set to according:
** COND_OK query is possible (field = constant) COND_OK query is possible (field = constant)
** COND_TRUE always true ( 1 = 1 ) COND_TRUE always true ( 1 = 1 )
** COND_FALSE always false ( 1 = 2 ) COND_FALSE always false ( 1 = 2 )
*/ */
static COND * static COND *
@ -3299,7 +3302,7 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
} }
/* /*
** Return 1 if the item is a const value in all the WHERE clause Return 1 if the item is a const value in all the WHERE clause
*/ */
static bool static bool
@ -3358,10 +3361,10 @@ const_expression_in_where(COND *cond, Item *comp_item, Item **const_item)
/**************************************************************************** /****************************************************************************
** Create a temp table according to a field list. Create a temp table according to a field list.
** Set distinct if duplicates could be removed Set distinct if duplicates could be removed
** Given fields field pointers are changed to point at tmp_table Given fields field pointers are changed to point at tmp_table
** for send_fields for send_fields
****************************************************************************/ ****************************************************************************/
Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
@ -3824,7 +3827,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
key_part_info->null_offset= (uint) (field->null_ptr - key_part_info->null_offset= (uint) (field->null_ptr -
(uchar*) table->record[0]); (uchar*) table->record[0]);
group->field->move_field((char*) ++group->buff); group->field->move_field((char*) ++group->buff);
++group_buff; group_buff++;
} }
else else
group->field->move_field((char*) group_buff); group->field->move_field((char*) group_buff);
@ -4168,7 +4171,7 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
join->procedure=procedure; join->procedure=procedure;
/* /*
** Tell the client how many fields there are in a row Tell the client how many fields there are in a row
*/ */
if (!table) if (!table)
join->result->send_fields(*fields,1); join->result->send_fields(*fields,1);
@ -4430,10 +4433,9 @@ flush_cached_records(JOIN *join,JOIN_TAB *join_tab,bool skipp_last)
/***************************************************************************** /*****************************************************************************
** The different ways to read a record The different ways to read a record
** Returns -1 if row was not found, 0 if row was found and 1 on errors Returns -1 if row was not found, 0 if row was found and 1 on errors
*****************************************************************************/ *****************************************************************************/
static int static int
join_read_const_table(JOIN_TAB *tab, POSITION *pos) join_read_const_table(JOIN_TAB *tab, POSITION *pos)
{ {
@ -4870,12 +4872,12 @@ join_ft_read_next(READ_RECORD *info)
/***************************************************************************** /*****************************************************************************
** The different end of select functions The different end of select functions
** These functions returns < 0 when end is reached, 0 on ok and > 0 if a These functions returns < 0 when end is reached, 0 on ok and > 0 if a
** fatal error (like table corruption) was detected fatal error (like table corruption) was detected
*****************************************************************************/ *****************************************************************************/
/* ARGSUSED */ /* ARGSUSED */
static int static int
end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
bool end_of_records) bool end_of_records)
@ -5268,11 +5270,11 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
/***************************************************************************** /*****************************************************************************
** Remove calculation with tables that aren't yet read. Remove also tests Remove calculation with tables that aren't yet read. Remove also tests
** against fields that are read through key where the table is not a against fields that are read through key where the table is not a
** outer join table. outer join table.
** We can't remove tests that are made against columns which are stored We can't remove tests that are made against columns which are stored
** in sorted order. in sorted order.
*****************************************************************************/ *****************************************************************************/
/* Return 1 if right_item is used removable reference key on left_item */ /* Return 1 if right_item is used removable reference key on left_item */
@ -5290,8 +5292,10 @@ static bool test_if_ref(Item_field *left_item,Item *right_item)
return (field->eq_def(((Item_field *) right_item)->field)); return (field->eq_def(((Item_field *) right_item)->field));
if (right_item->const_item() && !(right_item->is_null())) if (right_item->const_item() && !(right_item->is_null()))
{ {
// We can remove binary fields and numerical fields except float, /*
// as float comparison isn't 100 % secure We can remove binary fields and numerical fields except float,
as float comparison isn't 100 % secure
*/
if (field->binary() && if (field->binary() &&
(field->type() != FIELD_TYPE_FLOAT || field->decimals() == 0)) (field->type() != FIELD_TYPE_FLOAT || field->decimals() == 0))
{ {
@ -5355,9 +5359,9 @@ make_cond_for_table(COND *cond,table_map tables,table_map used_table)
} }
/* /*
** Because the following test takes a while and it can be done Because the following test takes a while and it can be done
** table_count times, we mark each item that we have examined with the result table_count times, we mark each item that we have examined with the result
** of the test of the test
*/ */
if (cond->marker == 3 || (cond->used_tables() & ~tables)) if (cond->marker == 3 || (cond->used_tables() & ~tables))
@ -5405,11 +5409,11 @@ part_of_refkey(TABLE *table,Field *field)
/***************************************************************************** /*****************************************************************************
** Test if one can use the key to resolve ORDER BY Test if one can use the key to resolve ORDER BY
** Returns: 1 if key is ok. Returns: 1 if key is ok.
** 0 if key can't be used 0 if key can't be used
** -1 if reverse key can be used -1 if reverse key can be used
** used_key_parts is set to key parts used if length != 0 used_key_parts is set to key parts used if length != 0
*****************************************************************************/ *****************************************************************************/
static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx, static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
@ -5676,7 +5680,7 @@ err:
} }
/* /*
** Add the HAVING criteria to table->select Add the HAVING criteria to table->select
*/ */
#ifdef NOT_YET #ifdef NOT_YET
@ -5711,11 +5715,11 @@ static bool fix_having(JOIN *join, Item **having)
/***************************************************************************** /*****************************************************************************
** Remove duplicates from tmp table Remove duplicates from tmp table
** This should be recoded to add a uniuqe index to the table and remove This should be recoded to add a unique index to the table and remove
** dupplicates duplicates
** Table is a locked single thread table Table is a locked single thread table
** fields is the number of fields to check (from the end) fields is the number of fields to check (from the end)
*****************************************************************************/ *****************************************************************************/
static bool compare_record(TABLE *table, Field **ptr) static bool compare_record(TABLE *table, Field **ptr)
@ -6145,7 +6149,7 @@ store_record_in_cache(JOIN_CACHE *cache)
cache->ptr_record=cache->records; cache->ptr_record=cache->records;
/* /*
** There is room in cache. Put record there There is room in cache. Put record there
*/ */
cache->records++; cache->records++;
for (copy=cache->field ; copy < end_field; copy++) for (copy=cache->field ; copy < end_field; copy++)
@ -6271,13 +6275,13 @@ cp_buffer_from_ref(TABLE_REF *ref)
/***************************************************************************** /*****************************************************************************
** Group and order functions Group and order functions
*****************************************************************************/ *****************************************************************************/
/* /*
** Find order/group item in requested columns and change the item to point at Find order/group item in requested columns and change the item to point at
** it. If item doesn't exists, add it first in the field list it. If item doesn't exists, add it first in the field list
** Return 0 if ok. Return 0 if ok.
*/ */
static int static int
@ -6322,8 +6326,8 @@ find_order_in_list(THD *thd,TABLE_LIST *tables,ORDER *order,List<Item> &fields,
/* /*
** Change order to point at item in select list. If item isn't a number Change order to point at item in select list. If item isn't a number
** and doesn't exits in the select list, add it the the field list. and doesn't exits in the select list, add it the the field list.
*/ */
int setup_order(THD *thd,TABLE_LIST *tables,List<Item> &fields, int setup_order(THD *thd,TABLE_LIST *tables,List<Item> &fields,
@ -6357,7 +6361,7 @@ setup_group(THD *thd,TABLE_LIST *tables,List<Item> &fields,
uint org_fields=all_fields.elements; uint org_fields=all_fields.elements;
thd->where="group statement"; thd->where="group statement";
for ( ; order; order=order->next) for (; order; order=order->next)
{ {
if (find_order_in_list(thd,tables,order,fields,all_fields)) if (find_order_in_list(thd,tables,order,fields,all_fields))
return 1; return 1;
@ -6392,7 +6396,7 @@ setup_group(THD *thd,TABLE_LIST *tables,List<Item> &fields,
} }
/* /*
** Add fields with aren't used at start of field list. Return FALSE if ok Add fields with aren't used at start of field list. Return FALSE if ok
*/ */
static bool static bool
@ -6404,7 +6408,7 @@ setup_new_fields(THD *thd,TABLE_LIST *tables,List<Item> &fields,
thd->set_query_id=1; // Not really needed, but... thd->set_query_id=1; // Not really needed, but...
thd->where=0; // Don't give error thd->where=0; // Don't give error
for ( ; new_field ; new_field=new_field->next) for (; new_field ; new_field=new_field->next)
{ {
if ((item=find_item_in_list(*new_field->item,fields))) if ((item=find_item_in_list(*new_field->item,fields)))
new_field->item=item; /* Change to shared Item */ new_field->item=item; /* Change to shared Item */
@ -6422,9 +6426,9 @@ setup_new_fields(THD *thd,TABLE_LIST *tables,List<Item> &fields,
} }
/* /*
** Create a group by that consist of all non const fields. Try to use Create a group by that consist of all non const fields. Try to use
** the fields in the order given by 'order' to allow one to optimize the fields in the order given by 'order' to allow one to optimize
** away 'order by'. away 'order by'.
*/ */
static ORDER * static ORDER *
@ -6473,7 +6477,7 @@ create_distinct_group(ORDER *order_list,List<Item> &fields)
/***************************************************************************** /*****************************************************************************
** Update join with count of the different type of fields Update join with count of the different type of fields
*****************************************************************************/ *****************************************************************************/
void void
@ -6564,7 +6568,7 @@ get_sort_by_table(ORDER *a,ORDER *b,TABLE_LIST *tables)
if (!map || (map & RAND_TABLE_BIT)) if (!map || (map & RAND_TABLE_BIT))
DBUG_RETURN(0); DBUG_RETURN(0);
for ( ; !(map & tables->table->map) ; tables=tables->next) ; for (; !(map & tables->table->map) ; tables=tables->next) ;
if (map != tables->table->map) if (map != tables->table->map)
DBUG_RETURN(0); // More than one table DBUG_RETURN(0); // More than one table
DBUG_PRINT("exit",("sort by table: %d",tables->table->tablenr)); DBUG_PRINT("exit",("sort by table: %d",tables->table->tablenr));
@ -6608,8 +6612,8 @@ calc_group_buffer(JOIN *join,ORDER *group)
/* /*
** Get a list of buffers for saveing last group Get a list of buffers for saveing last group
** Groups are saved in reverse order for easyer check loop Groups are saved in reverse order for easyer check loop
*/ */
static bool static bool
@ -6647,10 +6651,10 @@ test_if_group_changed(List<Item_buff> &list)
/* /*
** Setup copy_fields to save fields at start of new group Setup copy_fields to save fields at start of new group
** Only FIELD_ITEM:s and FUNC_ITEM:s needs to be saved between groups. Only FIELD_ITEM:s and FUNC_ITEM:s needs to be saved between groups.
** Change old item_field to use a new field with points at saved fieldvalue Change old item_field to use a new field with points at saved fieldvalue
** This function is only called before use of send_fields This function is only called before use of send_fields
*/ */
bool bool
@ -6719,7 +6723,7 @@ err2:
/* /*
** Copy fields and null values between two tables Copy fields and null values between two tables
*/ */
void void
@ -6728,7 +6732,7 @@ copy_fields(TMP_TABLE_PARAM *param)
Copy_field *ptr=param->copy_field; Copy_field *ptr=param->copy_field;
Copy_field *end=param->copy_field_end; Copy_field *end=param->copy_field_end;
for ( ; ptr != end; ptr++) for (; ptr != end; ptr++)
(*ptr->do_copy)(ptr); (*ptr->do_copy)(ptr);
List_iterator_fast<Item> &it=param->copy_funcs_it; List_iterator_fast<Item> &it=param->copy_funcs_it;
@ -6740,7 +6744,7 @@ copy_fields(TMP_TABLE_PARAM *param)
/***************************************************************************** /*****************************************************************************
** Make an array of pointer to sum_functions to speed up sum_func calculation Make an array of pointer to sum_functions to speed up sum_func calculation
*****************************************************************************/ *****************************************************************************/
static bool static bool
@ -6772,7 +6776,7 @@ make_sum_func_list(JOIN *join,List<Item> &fields)
/* /*
** Change all funcs and sum_funcs to fields in tmp table Change all funcs and sum_funcs to fields in tmp table
*/ */
static bool static bool
@ -6822,8 +6826,8 @@ change_to_use_tmp_fields(List<Item> &items)
/* /*
** Change all sum_func refs to fields to point at fields in tmp table Change all sum_func refs to fields to point at fields in tmp table
** Change all funcs to be fields in tmp table Change all funcs to be fields in tmp table
*/ */
static bool static bool
@ -6879,7 +6883,7 @@ change_refs_to_tmp_fields(THD *thd,List<Item> &items)
/****************************************************************************** /******************************************************************************
** code for calculating functions Code for calculating functions
******************************************************************************/ ******************************************************************************/
static void static void
@ -6947,8 +6951,8 @@ copy_funcs(Item_result_field **func_ptr)
/***************************************************************************** /*****************************************************************************
** Create a condition for a const reference and add this to the Create a condition for a const reference and add this to the
** currenct select for the table currenct select for the table
*****************************************************************************/ *****************************************************************************/
static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab) static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
@ -6989,7 +6993,7 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
} }
/**************************************************************************** /****************************************************************************
** Send a description about what how the select will be done to stdout Send a description about what how the select will be done to stdout
****************************************************************************/ ****************************************************************************/
static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,

View file

@ -116,7 +116,7 @@ int mysqld_show_open_tables(THD *thd,const char *wild)
if (!(open_list=list_open_tables(thd,wild)) && thd->fatal_error) if (!(open_list=list_open_tables(thd,wild)) && thd->fatal_error)
DBUG_RETURN(-1); DBUG_RETURN(-1);
for ( ; open_list ; open_list=open_list->next) for (; open_list ; open_list=open_list->next)
{ {
thd->packet.length(0); thd->packet.length(0);
net_store_data(&thd->packet,convert, open_list->db); net_store_data(&thd->packet,convert, open_list->db);
@ -1301,7 +1301,7 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables)
net_store_data(&packet2,"NONE" ); net_store_data(&packet2,"NONE" );
break; break;
} }
switch(SSL_CTX_get_session_cache_mode(ssl_acceptor_fd->ssl_context_)) switch (SSL_CTX_get_session_cache_mode(ssl_acceptor_fd->ssl_context_))
{ {
case SSL_SESS_CACHE_OFF: case SSL_SESS_CACHE_OFF:
net_store_data(&packet2,"OFF" ); net_store_data(&packet2,"OFF" );

View file

@ -615,7 +615,7 @@ int wild_case_compare(const char *str,const char *str_end,
{ // Found wild_many { // Found wild_many
wildstr++; wildstr++;
/* Remove any '%' and '_' from the wild search string */ /* Remove any '%' and '_' from the wild search string */
for ( ; wildstr != wildend ; wildstr++) for (; wildstr != wildend ; wildstr++)
{ {
if (*wildstr == wild_many) if (*wildstr == wild_many)
continue; continue;
@ -744,7 +744,7 @@ int wild_compare(const char *str,const char *str_end,
{ // Found wild_many { // Found wild_many
wildstr++; wildstr++;
/* Remove any '%' and '_' from the wild search string */ /* Remove any '%' and '_' from the wild search string */
for ( ; wildstr != wildend ; wildstr++) for (; wildstr != wildend ; wildstr++)
{ {
if (*wildstr == wild_many) if (*wildstr == wild_many)
continue; continue;

View file

@ -872,8 +872,9 @@ static int send_check_errmsg(THD* thd, TABLE_LIST* table,
return 1; return 1;
} }
static int prepare_for_restore(THD* thd, TABLE_LIST* table, static int prepare_for_restore(THD* thd, TABLE_LIST* table,
HA_CHECK_OPT *check_opt) HA_CHECK_OPT *check_opt)
{ {
DBUG_ENTER("prepare_for_restore"); DBUG_ENTER("prepare_for_restore");
@ -915,15 +916,18 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table,
} }
} }
// now we should be able to open the partially restored table /*
// to finish the restore in the handler later on Now we should be able to open the partially restored table
to finish the restore in the handler later on
*/
if (!(table->table = reopen_name_locked_table(thd, table))) if (!(table->table = reopen_name_locked_table(thd, table)))
unlock_table_name(thd, table); unlock_table_name(thd, table);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
static int prepare_for_repair(THD* thd, TABLE_LIST* table, static int prepare_for_repair(THD* thd, TABLE_LIST* table,
HA_CHECK_OPT *check_opt) HA_CHECK_OPT *check_opt)
{ {
DBUG_ENTER("prepare_for_repair"); DBUG_ENTER("prepare_for_repair");
@ -966,13 +970,16 @@ static int prepare_for_repair(THD* thd, TABLE_LIST* table,
} }
} }
// now we should be able to open the partially repaired table /*
// to finish the repair in the handler later on Now we should be able to open the partially repaired table
to finish the repair in the handler later on.
*/
if (!(table->table = reopen_name_locked_table(thd, table))) if (!(table->table = reopen_name_locked_table(thd, table)))
unlock_table_name(thd, table); unlock_table_name(thd, table);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
static int mysql_admin_table(THD* thd, TABLE_LIST* tables, static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
HA_CHECK_OPT* check_opt, HA_CHECK_OPT* check_opt,
const char *operator_name, const char *operator_name,

View file

@ -255,7 +255,7 @@ bool select_union::send_data(List<Item> &values)
fill_record(table->field,values); fill_record(table->field,values);
if ((write_record(table,&info))) if ((write_record(table,&info)))
{ {
if (create_myisam_from_heap(table, tmp_table_param, info.errorno, 0)) if (create_myisam_from_heap(table, tmp_table_param, info.last_errno, 0))
return 1; return 1;
} }
return 0; return 0;

View file

@ -16,9 +16,7 @@
/* Update of records /* Update of records
Multi-table updates were introduced by Monty and Sinisa <sinisa@mysql.com> Multi-table updates were introduced by Monty and Sinisa <sinisa@mysql.com>
*/ */
#include "mysql_priv.h" #include "mysql_priv.h"
@ -347,7 +345,7 @@ int mysql_update(THD *thd,
} }
/*************************************************************************** /***************************************************************************
** update multiple tables from join Update multiple tables from join
***************************************************************************/ ***************************************************************************/
multi_update::multi_update(THD *thd_arg, TABLE_LIST *ut, List<Item> &fs, multi_update::multi_update(THD *thd_arg, TABLE_LIST *ut, List<Item> &fs,
@ -363,7 +361,7 @@ multi_update::multi_update(THD *thd_arg, TABLE_LIST *ut, List<Item> &fs,
for (TABLE_LIST *dt=ut ; dt ; dt=dt->next,counter++) for (TABLE_LIST *dt=ut ; dt ; dt=dt->next,counter++)
{ {
TABLE *table=ut->table; TABLE *table=ut->table;
// (void) ut->table->file->extra(HA_EXTRA_NO_KEYREAD); // (void) ut->table->file->extra(HA_EXTRA_NO_KEYREAD);
dt->table->used_keys=0; dt->table->used_keys=0;
if (table->timestamp_field) if (table->timestamp_field)
{ {
@ -402,10 +400,14 @@ multi_update::prepare(List<Item> &values)
} }
} }
} }
// Here I have to connect fields with tables and only update tables that need to be updated ... /*
Here I have to connect fields with tables and only update tables that
need to be updated.
I calculate num_updated and fill-up table_sequence
Set table_list->shared to true or false, depending on whether table is
to be updated or not
*/
// I calculate num_updated and fill-up table_sequence
// Set table_list->shared to true or false, depending on whether table is to be updated or not
Item_field *item; Item_field *item;
List_iterator<Item> it(fields); List_iterator<Item> it(fields);
num_fields=fields.elements; num_fields=fields.elements;
@ -414,7 +416,8 @@ multi_update::prepare(List<Item> &values)
while ((item= (Item_field *)it++)) while ((item= (Item_field *)it++))
{ {
unsigned int counter=0; unsigned int counter=0;
for (table_ref=update_tables; table_ref; table_ref=table_ref->next, counter++) for (table_ref=update_tables; table_ref;
table_ref=table_ref->next, counter++)
{ {
if (table_ref->table == item->field->table && !table_ref->shared) if (table_ref->table == item->field->table && !table_ref->shared)
{ {
@ -422,7 +425,8 @@ multi_update::prepare(List<Item> &values)
table_ref->shared=1; table_ref->shared=1;
if (!not_trans_safe && !table_ref->table->file->has_transactions()) if (!not_trans_safe && !table_ref->table->file->has_transactions())
not_trans_safe=true; not_trans_safe=true;
table_ref->table->no_keyread=1; // to be moved if initialize_tables has to be used // to be moved if initialize_tables has to be used
table_ref->table->no_keyread=1;
break; break;
} }
} }
@ -440,8 +444,10 @@ multi_update::prepare(List<Item> &values)
DBUG_RETURN(1); DBUG_RETURN(1);
} }
// Here, I have to allocate the array of temporary tables /*
// I have to treat a case of num_updated=1 differently in send_data() method. Here, I have to allocate the array of temporary tables
I have to treat a case of num_updated=1 differently in send_data() method.
*/
if (num_updated > 1) if (num_updated > 1)
{ {
tmp_tables = (TABLE **) sql_calloc(sizeof(TABLE *) * (num_updated - 1)); tmp_tables = (TABLE **) sql_calloc(sizeof(TABLE *) * (num_updated - 1));
@ -453,7 +459,7 @@ multi_update::prepare(List<Item> &values)
{ {
if (!table_ref->shared) if (!table_ref->shared)
continue; continue;
// Here we have to add row offset as an additional field ... // Here we have to add row offset as an additional field ...
if (!(temp_fields = (List_item *)sql_calloc(sizeof(List_item)))) if (!(temp_fields = (List_item *)sql_calloc(sizeof(List_item))))
{ {
error = 1; // A proper error message is due here error = 1; // A proper error message is due here
@ -470,13 +476,15 @@ multi_update::prepare(List<Item> &values)
{ {
Field_string offset(table_ref->table->file->ref_length,false,"offset",table_ref->table,true); Field_string offset(table_ref->table->file->ref_length,false,"offset",table_ref->table,true);
temp_fields->push_front(new Item_field(((Field *)&offset))); temp_fields->push_front(new Item_field(((Field *)&offset)));
// Here I make tmp tables // Here I make tmp tables
int cnt=counter-1; int cnt=counter-1;
TMP_TABLE_PARAM tmp_table_param; TMP_TABLE_PARAM tmp_table_param;
bzero((char*) &tmp_table_param,sizeof(tmp_table_param)); bzero((char*) &tmp_table_param,sizeof(tmp_table_param));
tmp_table_param.field_count=temp_fields->elements; tmp_table_param.field_count=temp_fields->elements;
if (!(tmp_tables[cnt]=create_tmp_table(thd, &tmp_table_param, *temp_fields, if (!(tmp_tables[cnt]=create_tmp_table(thd, &tmp_table_param,
(ORDER*) 0, 1, 0, 0, TMP_TABLE_ALL_COLUMNS))) *temp_fields,
(ORDER*) 0, 1, 0, 0,
TMP_TABLE_ALL_COLUMNS)))
{ {
error = 1; // A proper error message is due here error = 1; // A proper error message is due here
DBUG_RETURN(1); DBUG_RETURN(1);
@ -498,7 +506,8 @@ multi_update::prepare(List<Item> &values)
void void
multi_update::initialize_tables(JOIN *join) multi_update::initialize_tables(JOIN *join)
{ {
/* We skip it as it only makes a mess ........... /*
We skip it as it only makes a mess ...........
TABLE_LIST *walk; TABLE_LIST *walk;
table_map tables_to_update_from=0; table_map tables_to_update_from=0;
for (walk= update_tables ; walk ; walk=walk->next) for (walk= update_tables ; walk ; walk=walk->next)
@ -546,7 +555,7 @@ bool multi_update::send_data(List<Item> &values)
List<Item> real_values(values); List<Item> real_values(values);
for (uint counter = 0; counter < fields.elements; counter++) for (uint counter = 0; counter < fields.elements; counter++)
real_values.pop(); real_values.pop();
// We have skipped fields .... // We have skipped fields ....
if (num_updated == 1) if (num_updated == 1)
{ {
for (table_being_updated=update_tables ; for (table_being_updated=update_tables ;
@ -560,7 +569,7 @@ bool multi_update::send_data(List<Item> &values)
if (table->status & (STATUS_NULL_ROW | STATUS_UPDATED)) if (table->status & (STATUS_NULL_ROW | STATUS_UPDATED))
return 0; return 0;
table->file->position(table->record[0]); table->file->position(table->record[0]);
// Only one table being updated receives a completely different treatment // Only one table being updated receives a completely different treatment
table->status|= STATUS_UPDATED; table->status|= STATUS_UPDATED;
store_record(table,1); store_record(table,1);
if (fill_record(fields,real_values)) if (fill_record(fields,real_values))
@ -596,7 +605,7 @@ bool multi_update::send_data(List<Item> &values)
if (*int_ptr++ == (uint) (secure_counter + 1)) if (*int_ptr++ == (uint) (secure_counter + 1))
values_by_table.push_back(item); values_by_table.push_back(item);
} }
// Here I am breaking values as per each table // Here I am breaking values as per each table
if (secure_counter < 0) if (secure_counter < 0)
{ {
table->status|= STATUS_UPDATED; table->status|= STATUS_UPDATED;
@ -639,13 +648,13 @@ void multi_update::send_error(uint errcode,const char *err)
::send_error(&thd->net,errcode,err); ::send_error(&thd->net,errcode,err);
/* reset used flags */ /* reset used flags */
// update_tables->table->no_keyread=0; // update_tables->table->no_keyread=0;
/* If nothing updated return */ /* If nothing updated return */
if (!updated) if (!updated)
return; return;
/* Somthing alredy updated consequently we have to invalidate cache */ /* Something already updated so we have to invalidate cache */
query_cache_invalidate3(thd, update_tables, 1); query_cache_invalidate3(thd, update_tables, 1);
/* Below can happen when thread is killed early ... */ /* Below can happen when thread is killed early ... */

View file

@ -3654,17 +3654,17 @@ grant_option_list:
grant_option: grant_option:
GRANT OPTION { Lex->grant |= GRANT_ACL;} GRANT OPTION { Lex->grant |= GRANT_ACL;}
| MAX_QUERIES_PER_HOUR EQ ULONG_NUM | MAX_QUERIES_PER_HOUR ULONG_NUM
{ {
Lex->mqh.questions=$3; Lex->mqh.questions=$2;
} }
| MAX_UPDATES_PER_HOUR EQ ULONG_NUM | MAX_UPDATES_PER_HOUR ULONG_NUM
{ {
Lex->mqh.updates=$3; Lex->mqh.updates=$2;
} }
| MAX_CONNECTIONS_PER_HOUR EQ ULONG_NUM | MAX_CONNECTIONS_PER_HOUR ULONG_NUM
{ {
Lex->mqh.connections=$3; Lex->mqh.connections=$2;
} }
begin: begin:

View file

@ -922,7 +922,7 @@ ulong next_io_size(register ulong pos)
void append_unescaped(String *res,const char *pos) void append_unescaped(String *res,const char *pos)
{ {
for ( ; *pos ; pos++) for (; *pos ; pos++)
{ {
switch (*pos) { switch (*pos) {
case 0: /* Must be escaped for 'mysql' */ case 0: /* Must be escaped for 'mysql' */

View file

@ -135,7 +135,8 @@ struct st_table {
#define JOIN_TYPE_LEFT 1 #define JOIN_TYPE_LEFT 1
#define JOIN_TYPE_RIGHT 2 #define JOIN_TYPE_RIGHT 2
typedef struct st_table_list { typedef struct st_table_list
{
struct st_table_list *next; struct st_table_list *next;
char *db,*name,*real_name; char *db,*name,*real_name;
uint32 db_length, real_name_length; uint32 db_length, real_name_length;
@ -152,12 +153,15 @@ typedef struct st_table_list {
bool shared; /* Used twice in union */ bool shared; /* Used twice in union */
} TABLE_LIST; } TABLE_LIST;
typedef struct st_changed_table_list {
typedef struct st_changed_table_list
{
struct st_changed_table_list *next; struct st_changed_table_list *next;
char *key; char *key;
uint32 key_length; uint32 key_length;
} CHANGED_TABLE_LIST; } CHANGED_TABLE_LIST;
typedef struct st_open_table_list typedef struct st_open_table_list
{ {
struct st_open_table_list *next; struct st_open_table_list *next;

View file

@ -496,7 +496,7 @@ str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date)
} }
if (str != end && current_thd->count_cuted_fields) if (str != end && current_thd->count_cuted_fields)
{ {
for ( ; str != end ; str++) for (; str != end ; str++)
{ {
if (!isspace(*str)) if (!isspace(*str))
{ {

View file

@ -271,7 +271,7 @@ char *metaphon(UDF_INIT *initid, UDF_ARGS *args, char *result,
* characters and converting to uppercase. * characters and converting to uppercase.
*-------------------------------------------------------*/ *-------------------------------------------------------*/
for ( n = ntrans + 1, n_end = ntrans + sizeof(ntrans)-2; for (n = ntrans + 1, n_end = ntrans + sizeof(ntrans)-2;
word != w_end && n < n_end; word++ ) word != w_end && n < n_end; word++ )
if ( isalpha ( *word )) if ( isalpha ( *word ))
*n++ = toupper ( *word ); *n++ = toupper ( *word );
@ -324,7 +324,7 @@ char *metaphon(UDF_INIT *initid, UDF_ARGS *args, char *result,
KSflag = 0; /* state flag for KS translation */ KSflag = 0; /* state flag for KS translation */
for ( metaph_end = result + MAXMETAPH, n_start = n; for (metaph_end = result + MAXMETAPH, n_start = n;
n <= n_end && result < metaph_end; n++ ) n <= n_end && result < metaph_end; n++ )
{ {
@ -402,7 +402,7 @@ char *metaphon(UDF_INIT *initid, UDF_ARGS *args, char *result,
n[2] != 'G' ) ? n[2] != 'G' ) ?
(char)'J' : (char)'K'; (char)'J' : (char)'K';
else else
if( n[1] == 'H' && if ( n[1] == 'H' &&
!NOGHTOF( *( n - 3 )) && !NOGHTOF( *( n - 3 )) &&
*( n - 4 ) != 'H') *( n - 4 ) != 'H')
*result++ = 'F'; *result++ = 'F';
@ -440,7 +440,7 @@ char *metaphon(UDF_INIT *initid, UDF_ARGS *args, char *result,
case 'T': /* TIO, TIA = X ("sh" sound) */ case 'T': /* TIO, TIA = X ("sh" sound) */
/* TH = 0, ("th" sound ) */ /* TH = 0, ("th" sound ) */
if( *( n + 1 ) == 'I' && ( n[2] == 'O' if ( *( n + 1 ) == 'I' && ( n[2] == 'O'
|| n[2] == 'A') ) || n[2] == 'A') )
*result++ = 'X'; *result++ = 'X';
else else

View file

@ -105,7 +105,7 @@ int rea_create_table(my_string file_name,
fileinfo[26]= (uchar) test((create_info->max_rows == 1) && fileinfo[26]= (uchar) test((create_info->max_rows == 1) &&
(create_info->min_rows == 1) && (keys == 0)); (create_info->min_rows == 1) && (keys == 0));
int2store(fileinfo+28,key_info_length); int2store(fileinfo+28,key_info_length);
strnmov((char*) forminfo+47,create_info->comment ? create_info->comment : "", strmake((char*) forminfo+47,create_info->comment ? create_info->comment : "",
60); 60);
forminfo[46]=(uchar) strlen((char*)forminfo+47); // Length of comment forminfo[46]=(uchar) strlen((char*)forminfo+47); // Length of comment

View file

@ -381,11 +381,15 @@ safe_query("select $tables_cols from mysql.tables_priv where user = '$opt_user'"
safe_query("select $columns_cols from mysql.columns_priv where user = '$opt_user'"); safe_query("select $columns_cols from mysql.columns_priv where user = '$opt_user'");
# #
# Test IDENTIFIED BY # Clear up privileges to make future tests easier
#
safe_query("delete from user where user='$opt_user'"); safe_query("delete from user where user='$opt_user'");
safe_query("flush privileges"); safe_query("flush privileges");
#
# Test IDENTIFIED BY
#
safe_query("grant ALL PRIVILEGES on $opt_database.test to $user identified by 'dummy', ${opt_user}\@127.0.0.1 identified by 'dummy2'"); safe_query("grant ALL PRIVILEGES on $opt_database.test to $user identified by 'dummy', ${opt_user}\@127.0.0.1 identified by 'dummy2'");
user_connect(0,"dummy"); user_connect(0,"dummy");
safe_query("grant SELECT on $opt_database.* to $user identified by ''"); safe_query("grant SELECT on $opt_database.* to $user identified by ''");
@ -402,6 +406,33 @@ safe_query("grant FILE on *.* to $user");
safe_query("insert into $opt_database.test3 values (1)"); safe_query("insert into $opt_database.test3 values (1)");
user_connect(0); user_connect(0);
user_query("select * into outfile '$tmp_table' from $opt_database.test3"); user_query("select * into outfile '$tmp_table' from $opt_database.test3");
safe_query("revoke SELECT on $opt_database.test3 from $user");
safe_query("revoke FILE from *.* from $user");
safe_query("drop table $opt_database.test3");
#
# Test privileges needed for LOCK TABLES
#
safe_query("create table $opt_database.test3 (a int)");
user_connect(0);
user_query("select * into outfile '$tmp_table' from $opt_database.test3",1);
safe_query("grant SELECT on $opt_database.test3 to $user");
user_connect(0);
user_query("LOCK TABLES $opt_database.test3",1);
safe_query("grant INSERT,UPDATE,DELETE on $opt_database.test3 to $user");
user_connect(0);
user_query("LOCK TABLES $opt_database.test3");
safe_query("revoke SELECT, INSERT,UPDATE,DELETE on $opt_database.test3 from $user");
safe_query("grant SELECT,INSERT,UPDATE,DELETE on $opt_database.* to $user");
user_connect(0);
user_query("LOCK TABLES $opt_database.test3");
safe_query("revoke SELECT, INSERT,UPDATE,DELETE on $opt_database.* from $user");
safe_query("grant SELECT,INSERT,UPDATE,DELETE on *.* to $user");
user_connect(0);
user_query("LOCK TABLES $opt_database.test3");
user_query("UNLOCK TABLES");
safe_query("revoke SELECT, INSERT,UPDATE,DELETE on *.* from $user");
# #
# Clean up things # Clean up things

View file

@ -14,11 +14,12 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* MySQL server management daemon /*
* MySQL server management daemon
* Written by:
* Sasha Pachev <sasha@mysql.com> Written by:
**/ Sasha Pachev <sasha@mysql.com>
*/
#include <my_global.h> #include <my_global.h>
#include <my_pthread.h> #include <my_pthread.h>
@ -90,9 +91,10 @@
#define MAX_RETRY_COUNT 100 #define MAX_RETRY_COUNT 100
/* Variable naming convention - if starts with manager_, either is set /*
directly by the user, or used closely in ocnjunction with a variable Variable naming convention - if starts with manager_, either is set
set by the user directly by the user, or used closely in ocnjunction with a variable
set by the user
*/ */
#if defined(__i386__) && defined(HAVE_LINUXTHREADS) #if defined(__i386__) && defined(HAVE_LINUXTHREADS)
@ -180,10 +182,12 @@ typedef int (*manager_cmd_handler)(struct manager_thd*,char*,char*);
static void handle_child(int __attribute__((unused)) sig); static void handle_child(int __attribute__((unused)) sig);
static void handle_sigpipe(int __attribute__((unused)) sig); static void handle_sigpipe(int __attribute__((unused)) sig);
/* exec() in a threaded application is full of problems /*
to solve this, we fork off a launcher at the very start exec() in a threaded application is full of problems.
and communicate with it through a pipe To solve this, we fork off a launcher at the very start
and communicate with it through a pipe
*/ */
static void fork_launcher(); static void fork_launcher();
static void run_launcher_loop(); static void run_launcher_loop();
int to_launcher_pipe[2],from_launcher_pipe[2]; int to_launcher_pipe[2],from_launcher_pipe[2];
@ -230,11 +234,12 @@ struct manager_exec
static int set_exec_param(struct manager_thd* thd, char* args_start, static int set_exec_param(struct manager_thd* thd, char* args_start,
char* args_end, PARAM_TYPE param_type); char* args_end, PARAM_TYPE param_type);
#define HANDLE_DECL(com) static int com (struct manager_thd* thd, char* args_start,char* args_end) #define HANDLE_DECL(com) \
#define HANDLE_NOARG_DECL(com) static int com \ static int com(struct manager_thd* thd, char* args_start,char* args_end)
(struct manager_thd* thd, char *args_start __attribute__((unused)),\ #define HANDLE_NOARG_DECL(com) \
char* args_end __attribute__((unused))) static int com(struct manager_thd *thd,\
char *args_start __attribute__((unused)),\
char* args_end __attribute__((unused)))
HANDLE_NOARG_DECL(handle_ping); HANDLE_NOARG_DECL(handle_ping);
HANDLE_NOARG_DECL(handle_quit); HANDLE_NOARG_DECL(handle_quit);
@ -321,9 +326,8 @@ static int client_msg_pre(NET* net,int err_code,const char* fmt,...);
static int client_msg_raw(NET* net,int err_code,int pre,const char* fmt, static int client_msg_raw(NET* net,int err_code,int pre,const char* fmt,
va_list args); va_list args);
static int authenticate(struct manager_thd* thd); static int authenticate(struct manager_thd* thd);
static char* read_line(struct manager_thd* thd); /* returns pointer to end of /* returns pointer to end of line */
line static char* read_line(struct manager_thd* thd);
*/
static pthread_handler_decl(process_connection, arg); static pthread_handler_decl(process_connection, arg);
static pthread_handler_decl(process_launcher_messages, arg); static pthread_handler_decl(process_launcher_messages, arg);
static int exec_line(struct manager_thd* thd,char* buf,char* buf_end); static int exec_line(struct manager_thd* thd,char* buf,char* buf_end);
@ -400,7 +404,7 @@ void print_stacktrace()
fprintf(errfp,"frame points is NULL, cannot trace stack\n"); fprintf(errfp,"frame points is NULL, cannot trace stack\n");
return; return;
} }
for(i=0;i<MAX_DEPTH && fp<(uchar**)stack_bottom;i++) for (i=0;i<MAX_DEPTH && fp<(uchar**)stack_bottom;i++)
{ {
#ifdef __i386__ #ifdef __i386__
uchar** new_fp = (uchar**)*fp; uchar** new_fp = (uchar**)*fp;
@ -429,8 +433,8 @@ static int exec_line(struct manager_thd* thd,char* buf,char* buf_end)
log_info("Command '%s'", buf); log_info("Command '%s'", buf);
if (!(cmd=lookup_cmd(buf,(int)(p-buf)))) if (!(cmd=lookup_cmd(buf,(int)(p-buf))))
{ {
if(client_msg(&thd->net,MANAGER_CLIENT_ERR, if (client_msg(&thd->net,MANAGER_CLIENT_ERR,
"Unrecognized command '%s', type help to see list of supported\ "Unrecognized command '%s', type help to see list of supported\
commands", buf)) commands", buf))
thd->fatal=1; thd->fatal=1;
return 1; return 1;
@ -521,7 +525,7 @@ HANDLE_DECL(handle_set_exec_con)
else else
e->con_sock[0]=0; e->con_sock[0]=0;
} }
else if(num_args > 4) else if (num_args > 4)
{ {
pthread_mutex_unlock(&lock_exec_hash); pthread_mutex_unlock(&lock_exec_hash);
error="Too many arguments"; error="Too many arguments";
@ -572,8 +576,7 @@ static int set_exec_param(struct manager_thd* thd, char* args_start,
} }
arg_p+=strlen(arg_p)+1; arg_p+=strlen(arg_p)+1;
param_size=strlen(arg_p)+1; param_size=strlen(arg_p)+1;
switch (param_type) switch (param_type) {
{
case PARAM_STDOUT: case PARAM_STDOUT:
param=e->stdout_path; param=e->stdout_path;
e->req_len+=(param_size-e->stdout_path_size); e->req_len+=(param_size-e->stdout_path_size);
@ -881,8 +884,7 @@ static int manager_exec_launch(struct manager_exec* e)
if (one_thread) if (one_thread)
{ {
pid_t tmp_pid; pid_t tmp_pid;
switch ((tmp_pid=fork())) switch ((tmp_pid=fork())) {
{
case -1: case -1:
e->error="Cannot fork"; e->error="Cannot fork";
return 1; return 1;
@ -973,7 +975,7 @@ static void manager_exec_print(NET* net,struct manager_exec* e)
goto end; goto end;
*p++='\t'; *p++='\t';
for(;p<buf_end && *args;args++) for (;p<buf_end && *args;args++)
{ {
p=arg_strmov(p,*args,(int)(buf_end-p)-1); p=arg_strmov(p,*args,(int)(buf_end-p)-1);
*p++='\t'; *p++='\t';
@ -1060,8 +1062,7 @@ static void die(const char* fmt, ...)
void print_msg_type(int msg_type) void print_msg_type(int msg_type)
{ {
const char* msg; const char* msg;
switch (msg_type) switch (msg_type) {
{
case LOG_ERR: msg = "ERROR"; break; case LOG_ERR: msg = "ERROR"; break;
case LOG_WARN: msg = "WARNING"; break; case LOG_WARN: msg = "WARNING"; break;
case LOG_INFO: msg = "INFO"; break; case LOG_INFO: msg = "INFO"; break;
@ -1099,8 +1100,7 @@ static pthread_handler_decl(process_launcher_messages,
sleep(1); sleep(1);
continue; continue;
} }
switch (buf[0]) switch (buf[0]) {
{
case CHILD_START: case CHILD_START:
{ {
char* ident=buf+1; char* ident=buf+1;
@ -1229,7 +1229,7 @@ static void handle_child(int __attribute__((unused)) sig)
pid_t child; pid_t child;
int child_status; int child_status;
for(;(child=waitpid(-1,&child_status,WNOHANG))>0;) for (;(child=waitpid(-1,&child_status,WNOHANG))>0;)
{ {
char msg_buf[1+sizeof(int)+sizeof(int)]; char msg_buf[1+sizeof(int)+sizeof(int)];
msg_buf[0]=CHILD_STOP; msg_buf[0]=CHILD_STOP;
@ -1284,7 +1284,7 @@ static void clean_up()
close(manager_sock); close(manager_sock);
log_info("Ended"); log_info("Ended");
if (errfp != stderr) if (errfp != stderr)
fclose(errfp); my_fclose(errfp, MYF(0));
hash_free(&exec_hash); hash_free(&exec_hash);
if (created_pid_file) if (created_pid_file)
my_delete(pid_file, MYF(0)); my_delete(pid_file, MYF(0));
@ -1343,12 +1343,13 @@ static int init_server()
log_info("Started"); log_info("Started");
if ((manager_sock=socket(PF_INET,SOCK_STREAM,0)) < 0) if ((manager_sock=socket(PF_INET,SOCK_STREAM,0)) < 0)
die("Could not create socket"); die("Could not create socket");
bzero((char*)&manager_addr, sizeof(manager_addr)); bzero((char*) &manager_addr, sizeof(manager_addr));
manager_addr.sin_family = AF_INET; manager_addr.sin_family = AF_INET;
manager_addr.sin_addr.s_addr = manager_bind_addr; manager_addr.sin_addr.s_addr = manager_bind_addr;
manager_addr.sin_port = htons(manager_port); manager_addr.sin_port = htons(manager_port);
setsockopt(manager_sock,SOL_SOCKET, SO_REUSEADDR,(char*)&arg,sizeof(arg)); setsockopt(manager_sock,SOL_SOCKET, SO_REUSEADDR,(char*)&arg,sizeof(arg));
if (bind(manager_sock,(struct sockaddr*)&manager_addr, sizeof(manager_addr)) < 0) if (bind(manager_sock,(struct sockaddr*)&manager_addr, sizeof(manager_addr))
< 0)
die("Could not bind"); die("Could not bind");
if (listen(manager_sock,manager_back_log) < 0) if (listen(manager_sock,manager_back_log) < 0)
die("Could not listen"); die("Could not listen");
@ -1432,8 +1433,11 @@ static int run_server_loop()
static FILE* open_log_stream() static FILE* open_log_stream()
{ {
FILE* fp; FILE* fp;
if (!(fp=fopen(manager_log_file,"a"))) if (!(fp=my_fopen(manager_log_file, O_APPEND | FILE_BINARY, MYF(MY_WME))))
die("Could not open log file '%s'", manager_log_file); {
clean_up();
exit(1);
}
return fp; return fp;
} }
@ -1473,11 +1477,10 @@ static uint tokenize_args(char* arg_start,char** arg_end)
int quoted=0,escaped=0,last_space=0; int quoted=0,escaped=0,last_space=0;
p_end=*arg_end; p_end=*arg_end;
p_write=p=arg_start; p_write=p=arg_start;
for(;p<p_end;p++) for (; p < p_end ; p++)
{ {
char c = *p; char c = *p;
switch (c) switch (c) {
{
case ' ': case ' ':
case '\r': case '\r':
case '\n': case '\n':
@ -1522,16 +1525,16 @@ static uint tokenize_args(char* arg_start,char** arg_end)
arg_count++; arg_count++;
*p_write=0; *p_write=0;
*arg_end=p_write; *arg_end=p_write;
log_debug("arg_count=%d,arg_start='%s'",arg_count,arg_start); log_debug("arg_count: %d arg_start: '%s'",arg_count,arg_start);
return arg_count; return arg_count;
} }
static void update_req_len(struct manager_exec* e) static void update_req_len(struct manager_exec* e)
{ {
e->req_len=e->data_buf_size+ e->req_len=(e->data_buf_size+
(e->stdout_path_size=strlen(e->stdout_path)+1)+ (e->stdout_path_size=strlen(e->stdout_path)+1)+
(e->stderr_path_size=strlen(e->stderr_path)+1); (e->stderr_path_size=strlen(e->stderr_path)+1));
} }
static struct manager_exec* manager_exec_new(char* arg_start,char* arg_end) static struct manager_exec* manager_exec_new(char* arg_start,char* arg_end)
{ {
@ -1640,8 +1643,11 @@ static void init_user_hash()
int line_num=1; int line_num=1;
if (hash_init(&user_hash,1024,0,0,get_user_key,manager_user_free,MYF(0))) if (hash_init(&user_hash,1024,0,0,get_user_key,manager_user_free,MYF(0)))
die("Could not initialize user hash"); die("Could not initialize user hash");
if (!(f=fopen(manager_pw_file,"r"))) if (!(f=my_fopen(manager_pw_file, O_RDONLY | O_BINARY, MYF(MY_WME))))
die("Could not open password file '%s'", manager_pw_file); {
clean_up();
exit(1);
}
for (;;line_num++) for (;;line_num++)
{ {
struct manager_user* u; struct manager_user* u;
@ -1660,19 +1666,24 @@ static void init_user_hash()
hash_insert(&user_hash,(gptr)u); hash_insert(&user_hash,(gptr)u);
} }
} }
fclose(f); my_fclose(f, MYF(0));
} }
static void init_pid_file() static void init_pid_file()
{ {
FILE* fp = fopen(pid_file, "w"); FILE* fp = my_fopen(pid_file, O_WRONLY | O_BINARY, MYF(MY_WME));
if (!fp) if (!fp)
die("Could not open pid file %s", pid_file); {
clean_up();
exit(1);
}
created_pid_file=1; created_pid_file=1;
fprintf(fp, "%d\n", (int) getpid()); fprintf(fp, "%d\n", (int) getpid());
fclose(fp); my_fclose(fp, MYF(0));
} }
static void init_globals() static void init_globals()
{ {
pthread_attr_t thr_attr; pthread_attr_t thr_attr;
@ -1751,8 +1762,7 @@ stdout_path=%s,stderr_path=%s",
req_len,ident,ident_len,exec_path,stdout_path,stderr_path); req_len,ident,ident_len,exec_path,stdout_path,stderr_path);
init_arg_array(exec_path,args,num_args-1); init_arg_array(exec_path,args,num_args-1);
switch ((pid=fork())) switch ((pid=fork())) {
{
case -1: case -1:
log_err("launcher: cannot fork"); log_err("launcher: cannot fork");
sleep(1); sleep(1);
@ -1779,8 +1789,7 @@ static void fork_launcher()
{ {
if (pipe(to_launcher_pipe) || pipe(from_launcher_pipe)) if (pipe(to_launcher_pipe) || pipe(from_launcher_pipe))
die("Could not create launcher pipes"); die("Could not create launcher pipes");
switch ((launcher_pid=fork())) switch ((launcher_pid=fork())) {
{
case 0: case 0:
signal(SIGCHLD,handle_child); signal(SIGCHLD,handle_child);
run_launcher_loop(); run_launcher_loop();
@ -1792,23 +1801,22 @@ static void fork_launcher()
static int daemonize() static int daemonize()
{ {
switch (fork()) switch (fork()) {
{ case -1:
case -1: die("Cannot fork");
die("Cannot fork"); case 0:
case 0: errfp = open_log_stream();
errfp = open_log_stream(); init_globals();
init_globals(); close(0);
close(0); close(1);
close(1); close(2);
close(2); init_server();
init_server(); run_server_loop();
run_server_loop(); clean_up();
clean_up(); break;
break; default:
default: break;
break; }
}
return 0; return 0;
} }

View file

@ -153,7 +153,7 @@ int vio_blocking(Vio * vio __attribute__((unused)), my_bool set_blocking_mode)
} }
#endif /* !defined(__WIN__) && !defined(__EMX__) */ #endif /* !defined(__WIN__) && !defined(__EMX__) */
#endif /* !defined (HAVE_OPENSSL) */ #endif /* !defined (HAVE_OPENSSL) */
DBUG_PRINT("exit", ("return %d", r)); DBUG_PRINT("exit", ("%d", r));
DBUG_RETURN(r); DBUG_RETURN(r);
} }
@ -273,7 +273,7 @@ my_socket vio_fd(Vio* vio)
my_bool vio_peer_addr(Vio * vio, char *buf) my_bool vio_peer_addr(Vio * vio, char *buf)
{ {
DBUG_ENTER("vio_peer_addr"); DBUG_ENTER("vio_peer_addr");
DBUG_PRINT("enter", ("sd=%d", vio->sd)); DBUG_PRINT("enter", ("sd: %d", vio->sd));
if (vio->localhost) if (vio->localhost)
{ {
strmov(buf,"127.0.0.1"); strmov(buf,"127.0.0.1");
@ -284,12 +284,12 @@ my_bool vio_peer_addr(Vio * vio, char *buf)
if (getpeername(vio->sd, (struct sockaddr *) (& (vio->remote)), if (getpeername(vio->sd, (struct sockaddr *) (& (vio->remote)),
&addrLen) != 0) &addrLen) != 0)
{ {
DBUG_PRINT("exit", ("getpeername, error: %d", socket_errno)); DBUG_PRINT("exit", ("getpeername gave error: %d", socket_errno));
DBUG_RETURN(1); DBUG_RETURN(1);
} }
my_inet_ntoa(vio->remote.sin_addr,buf); my_inet_ntoa(vio->remote.sin_addr,buf);
} }
DBUG_PRINT("exit", ("addr=%s", buf)); DBUG_PRINT("exit", ("addr: %s", buf));
DBUG_RETURN(0); DBUG_RETURN(0);
} }

View file

@ -28,7 +28,8 @@ static bool ssl_error_strings_loaded= FALSE;
static int verify_depth = 0; static int verify_depth = 0;
static int verify_error = X509_V_OK; static int verify_error = X509_V_OK;
static unsigned char dh512_p[]={ static unsigned char dh512_p[]=
{
0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75, 0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F, 0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F,
0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3, 0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3,
@ -36,22 +37,28 @@ static unsigned char dh512_p[]={
0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C, 0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C,
0x47,0x74,0xE8,0x33, 0x47,0x74,0xE8,0x33,
}; };
static unsigned char dh512_g[]={ static unsigned char dh512_g[]={
0x02, 0x02,
}; };
static DH *get_dh512(void) static DH *get_dh512(void)
{ {
DH *dh=NULL; DH *dh;
if ((dh=DH_new()))
if ((dh=DH_new()) == NULL) return(NULL); {
dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL); dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);
dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL); dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);
if ((dh->p == NULL) || (dh->g == NULL)) if (! dh->p || ! dh->g)
return(NULL); {
DH_free(dh);
dh=0;
}
}
return(dh); return(dh);
} }
static void static void
report_errors() report_errors()
{ {
@ -66,7 +73,7 @@ report_errors()
{ {
char buf[200]; char buf[200];
DBUG_PRINT("error", ("OpenSSL: %s:%s:%d:%s\n", ERR_error_string(l,buf), DBUG_PRINT("error", ("OpenSSL: %s:%s:%d:%s\n", ERR_error_string(l,buf),
file,line,(flags&ERR_TXT_STRING)?data:"")) ; file,line,(flags & ERR_TXT_STRING) ? data : "")) ;
} }
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@ -98,13 +105,14 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
/* If we are using DSA, we can copy the parameters from /*
* the private key */ If we are using DSA, we can copy the parameters from the private key
/* Now we know that a key and cert have been set against Now we know that a key and cert have been set against the SSL context
* the SSL context */ */
if (!SSL_CTX_check_private_key(ctx)) if (!SSL_CTX_check_private_key(ctx))
{ {
DBUG_PRINT("error", ("Private key does not match the certificate public key\n")); DBUG_PRINT("error",
("Private key does not match the certificate public key\n"));
DBUG_RETURN(0); DBUG_RETURN(0);
} }
} }
@ -128,7 +136,7 @@ vio_verify_callback(int ok, X509_STORE_CTX *ctx)
X509_NAME_oneline(X509_get_subject_name(err_cert),buf,sizeof(buf)); X509_NAME_oneline(X509_get_subject_name(err_cert),buf,sizeof(buf));
if (!ok) if (!ok)
{ {
DBUG_PRINT("error",("verify error:num=%d:%s\n",err, DBUG_PRINT("error",("verify error: num: %d : '%s'\n",err,
X509_verify_cert_error_string(err))); X509_verify_cert_error_string(err)));
if (verify_depth >= depth) if (verify_depth >= depth)
{ {
@ -137,7 +145,6 @@ vio_verify_callback(int ok, X509_STORE_CTX *ctx)
} }
else else
{ {
ok=0;
verify_error=X509_V_ERR_CERT_CHAIN_TOO_LONG; verify_error=X509_V_ERR_CERT_CHAIN_TOO_LONG;
} }
} }
@ -157,17 +164,18 @@ vio_verify_callback(int ok, X509_STORE_CTX *ctx)
/*ASN1_TIME_print_fp(stderr,X509_get_notAfter(ctx->current_cert));*/ /*ASN1_TIME_print_fp(stderr,X509_get_notAfter(ctx->current_cert));*/
break; break;
} }
DBUG_PRINT("exit", ("r=%d", ok)); DBUG_PRINT("exit", ("%d", ok));
DBUG_RETURN(ok); DBUG_RETURN(ok);
} }
/************************ VioSSLConnectorFd **********************************/ /************************ VioSSLConnectorFd **********************************/
struct st_VioSSLConnectorFd* new_VioSSLConnectorFd(const char* key_file, struct st_VioSSLConnectorFd *
const char* cert_file, new_VioSSLConnectorFd(const char* key_file,
const char* ca_file, const char* cert_file,
const char* ca_path, const char* ca_file,
const char* cipher) const char* ca_path,
const char* cipher)
{ {
int verify = SSL_VERIFY_PEER; int verify = SSL_VERIFY_PEER;
struct st_VioSSLConnectorFd* ptr; struct st_VioSSLConnectorFd* ptr;
@ -177,9 +185,13 @@ struct st_VioSSLConnectorFd* new_VioSSLConnectorFd(const char* key_file,
DBUG_PRINT("enter", DBUG_PRINT("enter",
("key_file=%s, cert_file=%s, ca_path=%s, ca_file=%s, cipher=%s", ("key_file=%s, cert_file=%s, ca_path=%s, ca_file=%s, cipher=%s",
key_file, cert_file, ca_path, ca_file, cipher)); key_file, cert_file, ca_path, ca_file, cipher));
ptr=(struct st_VioSSLConnectorFd*)my_malloc(sizeof(struct st_VioSSLConnectorFd),MYF(0));
ptr->ssl_context_=0; if (!(ptr=((struct st_VioSSLConnectorFd*)
ptr->ssl_method_=0; my_malloc(sizeof(struct st_VioSSLConnectorFd),MYF(0)))))
DBUG_RETURN(0);
ptr->ssl_context_= 0;
ptr->ssl_method_= 0;
/* FIXME: constants! */ /* FIXME: constants! */
if (!ssl_algorithms_added) if (!ssl_algorithms_added)
@ -204,10 +216,10 @@ struct st_VioSSLConnectorFd* new_VioSSLConnectorFd(const char* key_file,
goto ctor_failure; goto ctor_failure;
} }
/* /*
* SSL_CTX_set_options SSL_CTX_set_options
* SSL_CTX_set_info_callback SSL_CTX_set_info_callback
*/ */
if(cipher) if (cipher)
{ {
result=SSL_CTX_set_cipher_list(ptr->ssl_context_, cipher); result=SSL_CTX_set_cipher_list(ptr->ssl_context_, cipher);
DBUG_PRINT("info",("SSL_set_cipher_list() returned %d",result)); DBUG_PRINT("info",("SSL_set_cipher_list() returned %d",result));
@ -219,10 +231,10 @@ struct st_VioSSLConnectorFd* new_VioSSLConnectorFd(const char* key_file,
report_errors(); report_errors();
goto ctor_failure; goto ctor_failure;
} }
if (SSL_CTX_load_verify_locations( ptr->ssl_context_, ca_file,ca_path)==0) if (SSL_CTX_load_verify_locations( ptr->ssl_context_, ca_file,ca_path) == 0)
{ {
DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed")); DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed"));
if (SSL_CTX_set_default_verify_paths(ptr->ssl_context_)==0) if (SSL_CTX_set_default_verify_paths(ptr->ssl_context_) == 0)
{ {
DBUG_PRINT("error", ("SSL_CTX_set_default_verify_paths failed")); DBUG_PRINT("error", ("SSL_CTX_set_default_verify_paths failed"));
report_errors(); report_errors();
@ -246,16 +258,15 @@ ctor_failure:
/************************ VioSSLAcceptorFd **********************************/ /************************ VioSSLAcceptorFd **********************************/
struct st_VioSSLAcceptorFd* struct st_VioSSLAcceptorFd*
new_VioSSLAcceptorFd(const char* key_file, new_VioSSLAcceptorFd(const char *key_file,
const char* cert_file, const char *cert_file,
const char* ca_file, const char *ca_file,
const char* ca_path, const char *ca_path,
const char* cipher) const char *cipher)
{ {
int verify = (SSL_VERIFY_PEER | int verify = (SSL_VERIFY_PEER |
SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_FAIL_IF_NO_PEER_CERT |
SSL_VERIFY_CLIENT_ONCE); SSL_VERIFY_CLIENT_ONCE);
struct st_VioSSLAcceptorFd* ptr; struct st_VioSSLAcceptorFd* ptr;
int result; int result;
DH *dh=NULL; DH *dh=NULL;
@ -264,11 +275,12 @@ new_VioSSLAcceptorFd(const char* key_file,
("key_file=%s, cert_file=%s, ca_path=%s, ca_file=%s, cipher=%s", ("key_file=%s, cert_file=%s, ca_path=%s, ca_file=%s, cipher=%s",
key_file, cert_file, ca_path, ca_file, cipher)); key_file, cert_file, ca_path, ca_file, cipher));
ptr=(struct st_VioSSLAcceptorFd*)my_malloc(sizeof(struct st_VioSSLAcceptorFd),MYF(0)); ptr= ((struct st_VioSSLAcceptorFd*)
my_malloc(sizeof(struct st_VioSSLAcceptorFd),MYF(0)));
ptr->ssl_context_=0; ptr->ssl_context_=0;
ptr->ssl_method_=0; ptr->ssl_method_=0;
/* FIXME: constants! */ /* FIXME: constants! */
ptr->session_id_context_ = ptr; ptr->session_id_context_ = ptr;
if (!ssl_algorithms_added) if (!ssl_algorithms_added)
{ {
@ -283,42 +295,38 @@ new_VioSSLAcceptorFd(const char* key_file,
ssl_error_strings_loaded = TRUE; ssl_error_strings_loaded = TRUE;
SSL_load_error_strings(); SSL_load_error_strings();
} }
ptr->ssl_method_ = TLSv1_server_method(); ptr->ssl_method_= TLSv1_server_method();
ptr->ssl_context_ = SSL_CTX_new(ptr->ssl_method_); ptr->ssl_context_= SSL_CTX_new(ptr->ssl_method_);
if (ptr->ssl_context_==0) if (ptr->ssl_context_ == 0)
{ {
DBUG_PRINT("error", ("SSL_CTX_new failed")); DBUG_PRINT("error", ("SSL_CTX_new failed"));
report_errors(); report_errors();
goto ctor_failure; goto ctor_failure;
} }
if(cipher) if (cipher)
{ {
result=SSL_CTX_set_cipher_list(ptr->ssl_context_, cipher); result=SSL_CTX_set_cipher_list(ptr->ssl_context_, cipher);
DBUG_PRINT("info",("SSL_set_cipher_list() returned %d",result)); DBUG_PRINT("info",("SSL_set_cipher_list() returned %d",result));
} }
/* /* SSL_CTX_set_quiet_shutdown(ctx,1); */
* SSL_CTX_set_quiet_shutdown(ctx,1);
*
*/
SSL_CTX_sess_set_cache_size(ptr->ssl_context_,128); SSL_CTX_sess_set_cache_size(ptr->ssl_context_,128);
/* DH? */
/* DH?
*/
SSL_CTX_set_verify(ptr->ssl_context_, verify, vio_verify_callback); SSL_CTX_set_verify(ptr->ssl_context_, verify, vio_verify_callback);
SSL_CTX_set_session_id_context(ptr->ssl_context_,(const uchar*)&(ptr->session_id_context_),sizeof(ptr->session_id_context_)); SSL_CTX_set_session_id_context(ptr->ssl_context_,
(const uchar*) &(ptr->session_id_context_),
sizeof(ptr->session_id_context_));
/* /*
* SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile)); SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));
*/ */
if (vio_set_cert_stuff(ptr->ssl_context_, cert_file, key_file) == -1) if (vio_set_cert_stuff(ptr->ssl_context_, cert_file, key_file) == -1)
{ {
DBUG_PRINT("error", ("vio_set_cert_stuff failed")); DBUG_PRINT("error", ("vio_set_cert_stuff failed"));
report_errors(); report_errors();
goto ctor_failure; goto ctor_failure;
} }
if (SSL_CTX_load_verify_locations( ptr->ssl_context_, ca_file, ca_path)==0) if (SSL_CTX_load_verify_locations( ptr->ssl_context_, ca_file, ca_path) == 0)
{ {
DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed")); DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed"));
if (SSL_CTX_set_default_verify_paths(ptr->ssl_context_)==0) if (SSL_CTX_set_default_verify_paths(ptr->ssl_context_)==0)
@ -332,11 +340,11 @@ new_VioSSLAcceptorFd(const char* key_file,
dh=get_dh512(); dh=get_dh512();
SSL_CTX_set_tmp_dh(ptr->ssl_context_,dh); SSL_CTX_set_tmp_dh(ptr->ssl_context_,dh);
DH_free(dh); DH_free(dh);
DBUG_RETURN(ptr); DBUG_RETURN(ptr);
ctor_failure: ctor_failure:
DBUG_PRINT("exit", ("there was an error")); DBUG_PRINT("exit", ("there was an error"));
my_free((gptr)ptr,MYF(0)); my_free((gptr) ptr,MYF(0));
DBUG_RETURN(0); DBUG_RETURN(0);
} }