mirror of
https://github.com/MariaDB/server.git
synced 2026-05-16 20:07:13 +02:00
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:
parent
db41437a10
commit
2aecdd1a91
91 changed files with 2466 additions and 2173 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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}.
|
||||||
|
|
||||||
|
|
|
||||||
148
client/mysql.cc
148
client/mysql.cc
|
|
@ -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.",
|
||||||
|
|
@ -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
|
/*
|
||||||
|
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
|
on command names if this is the first word in the line, or on filenames
|
||||||
if not. */
|
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
|
/*
|
||||||
|
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
|
region of TEXT that contains the word to complete. We can use the
|
||||||
entire line in case we want to do some simple parsing. Return the
|
entire line in case we want to do some simple parsing. Return the
|
||||||
array of matches, or NULL if there aren't any. */
|
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,68 +1070,73 @@ 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 {
|
}
|
||||||
|
else
|
||||||
e = b->pData;
|
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
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -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,8 +2007,10 @@ 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
|
||||||
|
get directed to the pager or the outfile
|
||||||
|
*/
|
||||||
if (system(shell_cmd) == -1)
|
if (system(shell_cmd) == -1)
|
||||||
{
|
{
|
||||||
put_info(strerror(errno), INFO_ERROR, errno);
|
put_info(strerror(errno), INFO_ERROR, errno);
|
||||||
|
|
@ -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));
|
||||||
|
|
||||||
|
|
@ -2696,14 +2711,13 @@ static void init_username() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
|
||||||
|
|
@ -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
|
/*
|
||||||
|
When using extended-status relatively, ex_val_max_len is the estimated
|
||||||
maximum length for any relative value printed by extended-status. The
|
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. */
|
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))
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
@ -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,15 +335,16 @@ 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);
|
||||||
|
|
@ -358,8 +361,7 @@ static void dump_remote_log_entries(const char* logname)
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
@ -435,7 +436,7 @@ 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))
|
||||||
|
|
@ -516,9 +517,7 @@ int main(int argc, char** argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_remote)
|
if (use_remote)
|
||||||
{
|
|
||||||
mysql = safe_connect();
|
mysql = safe_connect();
|
||||||
}
|
|
||||||
|
|
||||||
if (table)
|
if (table)
|
||||||
{
|
{
|
||||||
|
|
@ -534,10 +533,8 @@ int main(int argc, char** argv)
|
||||||
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));
|
||||||
if (use_remote)
|
if (use_remote)
|
||||||
|
|
|
||||||
|
|
@ -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,16 +1406,12 @@ 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);
|
||||||
if (md_result_file != stdout)
|
if (md_result_file != stdout)
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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]);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -1530,16 +1531,13 @@ 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;
|
state = ST_ESCAPED;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
*p_dest++ = c;
|
*p_dest++ = c;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -706,7 +706,8 @@ 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
|
/*
|
||||||
|
Sasha: the test below is so we could call functions with DBUG_ENTER
|
||||||
before my_thread_init(). I needed this because I suspected corruption
|
before my_thread_init(). I needed this because I suspected corruption
|
||||||
of a block allocated by my_thread_init() itself, so I wanted to use
|
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()
|
my_malloc()/my_free() in my_thread_init()/my_thread_end()
|
||||||
|
|
|
||||||
|
|
@ -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\
|
||||||
|
|
@ -202,21 +203,14 @@ static int init_sym_entry(SYM_ENTRY* se, char* 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)
|
||||||
{
|
|
||||||
if(p < p_end)
|
|
||||||
*p = *buf;
|
*p = *buf;
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*p = 0;
|
*p = 0;
|
||||||
if (!strcmp(se->symbol, "gcc2_compiled."))
|
if (!strcmp(se->symbol, "gcc2_compiled."))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -263,6 +257,7 @@ static void verify_sort()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static SYM_ENTRY* resolve_addr(uchar* addr, SYM_ENTRY* se)
|
static SYM_ENTRY* resolve_addr(uchar* addr, SYM_ENTRY* se)
|
||||||
{
|
{
|
||||||
uint i;
|
uint i;
|
||||||
|
|
@ -283,6 +278,7 @@ static SYM_ENTRY* resolve_addr(uchar* addr, SYM_ENTRY* se)
|
||||||
return se;
|
return se;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void do_resolve()
|
static void do_resolve()
|
||||||
{
|
{
|
||||||
char buf[1024], *p;
|
char buf[1024], *p;
|
||||||
|
|
@ -291,7 +287,6 @@ static void do_resolve()
|
||||||
p = buf;
|
p = buf;
|
||||||
while(isspace(*p))
|
while(isspace(*p))
|
||||||
++p;
|
++p;
|
||||||
/* skip space */;
|
|
||||||
|
|
||||||
if (*p++ == '0' && *p++ == 'x')
|
if (*p++ == '0' && *p++ == 'x')
|
||||||
{
|
{
|
||||||
|
|
@ -312,6 +307,7 @@ static void do_resolve()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
MY_INIT(argv[0]);
|
MY_INIT(argv[0]);
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -18,14 +18,19 @@
|
||||||
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 */
|
||||||
|
|
|
||||||
|
|
@ -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
|
/*
|
||||||
|
Support macros for non ansi & other old compilers. Since such
|
||||||
things are no longer supported we do nothing. We keep then since
|
things are no longer supported we do nothing. We keep then since
|
||||||
some of our code may still be needed to upgrade old customers. */
|
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
|
/*
|
||||||
|
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
|
smaller what the disk page size. This influences the speed of the
|
||||||
isam btree library. eg to big to slow. */
|
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))
|
||||||
|
|
@ -661,8 +648,10 @@ typedef long longlong;
|
||||||
#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
|
/*
|
||||||
|
Define-funktions for reading and storing in machine format from/to
|
||||||
short/long to/from some place in memory V should be a (not
|
short/long to/from some place in memory V should be a (not
|
||||||
register) variable, M is a pointer to byte */
|
register) variable, M is a pointer to byte
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -249,12 +249,16 @@ typedef struct st_typelib { /* Different types saved here */
|
||||||
const char **type_names;
|
const char **type_names;
|
||||||
} TYPELIB;
|
} TYPELIB;
|
||||||
|
|
||||||
enum cache_type {READ_CACHE,WRITE_CACHE,
|
enum cache_type
|
||||||
|
{
|
||||||
|
READ_CACHE,WRITE_CACHE,
|
||||||
SEQ_READ_APPEND /* sequential read or append */,
|
SEQ_READ_APPEND /* sequential read or append */,
|
||||||
READ_FIFO,
|
READ_FIFO, READ_NET,WRITE_NET};
|
||||||
READ_NET,WRITE_NET};
|
|
||||||
enum flush_type { FLUSH_KEEP, FLUSH_RELEASE, FLUSH_IGNORE_CHANGED,
|
enum flush_type
|
||||||
FLUSH_FORCE_WRITE};
|
{
|
||||||
|
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 */
|
||||||
|
|
|
||||||
|
|
@ -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 !
|
/*
|
||||||
|
Note that null markers should always be first in a row !
|
||||||
When creating a column, one should only specify:
|
When creating a column, one should only specify:
|
||||||
type, length, null_bit and null_pos */
|
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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
/*
|
||||||
|
This function assumes we have just called SHOW SLAVE STATUS and have
|
||||||
read the given result and row
|
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,
|
|
||||||
|
/*
|
||||||
|
Assuming we already know that mysql points to a master connection,
|
||||||
retrieve all the slaves
|
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;
|
||||||
|
|
@ -1186,8 +1191,7 @@ static inline int get_slaves_from_master(MYSQL* mysql)
|
||||||
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,7 +1240,8 @@ 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
|
/*
|
||||||
|
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
|
the most reliable way to do this is to run SHOW SLAVE STATUS and see
|
||||||
if we have a non-empty master host. This is still not fool-proof -
|
if we have a non-empty master host. This is still not fool-proof -
|
||||||
it is not a sin to have a master that has a dormant slave thread with
|
it is not a sin to have a master that has a dormant slave thread with
|
||||||
|
|
@ -1275,7 +1280,8 @@ err:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* make a not so fool-proof decision on where the query should go, to
|
/*
|
||||||
|
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
|
the master or the slave. Ideally the user should always make this
|
||||||
decision himself with mysql_master_query() or mysql_slave_query().
|
decision himself with mysql_master_query() or mysql_slave_query().
|
||||||
However, to be able to more easily port the old code, we support the
|
However, to be able to more easily port the old code, we support the
|
||||||
|
|
@ -1285,6 +1291,7 @@ err:
|
||||||
mysql_master_query() or mysql_slave_query() explicitly in the place
|
mysql_master_query() or mysql_slave_query() explicitly in the place
|
||||||
where we have made the wrong decision
|
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)
|
||||||
{
|
{
|
||||||
|
|
@ -1294,8 +1301,8 @@ STDCALL mysql_rpl_query_type(const char* q, int len)
|
||||||
{
|
{
|
||||||
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 */
|
||||||
|
|
@ -1314,12 +1321,13 @@ STDCALL mysql_rpl_query_type(const char* q, int len)
|
||||||
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,7 +1346,8 @@ 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
|
/*
|
||||||
|
By default, we are a replication pivot. The caller must reset it
|
||||||
after we return if this is not the case.
|
after we return if this is not the case.
|
||||||
*/
|
*/
|
||||||
mysql->rpl_pivot = 1;
|
mysql->rpl_pivot = 1;
|
||||||
|
|
@ -1403,10 +1412,12 @@ 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)),
|
||||||
|
|
@ -1416,24 +1427,27 @@ mysql_ssl_set(MYSQL *mysql __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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -197,16 +195,18 @@ err:
|
||||||
|
|
||||||
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,6 +222,7 @@ 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 STDCALL mysql_manager_fetch_line(MYSQL_MANAGER* con, char* res_buf,
|
||||||
int res_buf_size)
|
int res_buf_size)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -201,7 +206,9 @@ 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 :((
|
{
|
||||||
|
/*
|
||||||
|
special treatment for truncation operator :((
|
||||||
1. +trunc* and there're other (not +trunc*) words
|
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
|
||||||
|
|
@ -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,8 +294,9 @@ 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*));
|
||||||
|
|
@ -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,19 +396,21 @@ 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;
|
||||||
|
|
@ -403,6 +420,7 @@ void _ftb_climb_the_tree(FTB *ftb, FTB_WORD *ftbw, FT_SEG_ITERATOR *ftsi_orig)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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;
|
||||||
|
|
@ -427,7 +445,8 @@ 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;
|
||||||
|
|
||||||
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);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
@ -136,7 +140,8 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
||||||
{
|
{
|
||||||
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;
|
||||||
|
|
||||||
|
|
@ -144,14 +149,17 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
||||||
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 *));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -190,15 +199,20 @@ static void get_options(int argc, char *argv[])
|
||||||
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);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -116,7 +120,8 @@ 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);
|
||||||
|
|
||||||
|
|
@ -144,14 +149,16 @@ 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)
|
||||||
{
|
{
|
||||||
|
|
@ -162,11 +169,13 @@ static int walk_and_copy(FT_SUPERDOC *from,
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
|
@ -204,7 +213,8 @@ FT_INFO *ft_init_nlq_search(MI_INFO *info, uint keynr, byte *query,
|
||||||
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;
|
||||||
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,8 @@ 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"
|
/*
|
||||||
|
This function breaks convention "return 0 in success"
|
||||||
but it's easier to use like this
|
but it's easier to use like this
|
||||||
|
|
||||||
while(_mi_ft_segiterator())
|
while(_mi_ft_segiterator())
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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[]=
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -14,15 +14,15 @@
|
||||||
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
|
/*
|
||||||
|
Return a pointerto the extension of the filename
|
||||||
The pointer points at the extension character (normally '.'))
|
The pointer points at the extension character (normally '.'))
|
||||||
If there isn't any extension, the pointer points at the end
|
If there isn't any extension, the pointer points at the end
|
||||||
NULL of the filename
|
ASCII(0) of the filename.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
my_string fn_ext(const char *name)
|
my_string fn_ext(const char *name)
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,8 @@ 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
|
/*
|
||||||
|
Must be initialized by the caller. The problem is that
|
||||||
_my_b_net_read has to be defined in sql directory because of
|
_my_b_net_read has to be defined in sql directory because of
|
||||||
the dependency on THD, and therefore cannot be visible to
|
the dependency on THD, and therefore cannot be visible to
|
||||||
programs that link against mysys but know nothing about THD, such
|
programs that link against mysys but know nothing about THD, such
|
||||||
|
|
|
||||||
|
|
@ -27,22 +27,23 @@
|
||||||
|
|
||||||
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
|
/*
|
||||||
|
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
|
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()
|
|
||||||
|
/*
|
||||||
|
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
|
from messing with the variables that we need in order to provide the
|
||||||
answer to the question.
|
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
|
/*
|
||||||
|
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
|
my_tell() because we have a reader thread that could have left the
|
||||||
file offset in a non-EOF location
|
file offset in a non-EOF location
|
||||||
*/
|
*/
|
||||||
|
|
@ -50,6 +51,9 @@ my_off_t my_b_append_tell(IO_CACHE* info)
|
||||||
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));
|
||||||
|
/*
|
||||||
|
Save the value of my_tell in res so we can see it when studying coredump
|
||||||
|
*/
|
||||||
DBUG_ASSERT(info->end_of_file - (info->append_read_pos-info->write_buffer)
|
DBUG_ASSERT(info->end_of_file - (info->append_read_pos-info->write_buffer)
|
||||||
== (res=my_tell(info->file,MYF(0))));
|
== (res=my_tell(info->file,MYF(0))));
|
||||||
my_seek(info->file,save_pos,MY_SEEK_SET,MYF(0));
|
my_seek(info->file,save_pos,MY_SEEK_SET,MYF(0));
|
||||||
|
|
@ -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:
|
||||||
|
Verify that it is OK to do seek in the non-append
|
||||||
area in SEQ_READ_APPEND cache
|
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
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -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,11 +405,12 @@ 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
|
/*
|
||||||
|
Destroy the first, already handled option, so that programs that look
|
||||||
for arguments in 'argv', without checking 'argc', know when to stop.
|
for arguments in 'argv', without checking 'argc', know when to stop.
|
||||||
Items in argv, before the destroyed one, are all non-option -arguments
|
Items in argv, before the destroyed one, are all non-option -arguments
|
||||||
to the program, yet to be (possibly) handled. */
|
to the program, yet to be (possibly) handled.
|
||||||
if (option_used)
|
*/
|
||||||
(*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;
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
/*
|
||||||
|
Fix heap when every element was changed
|
||||||
actually, it can be done in linear time,
|
actually, it can be done in linear time,
|
||||||
not in n*log(n), but some code (myisam/ft_boolean_search.c)
|
not in n*log(n), but some code (myisam/ft_boolean_search.c)
|
||||||
requires a strict order here, not just a queue property
|
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 *),
|
||||||
|
|
|
||||||
|
|
@ -14,53 +14,50 @@
|
||||||
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
|
||||||
|
|
@ -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 */
|
NEW'ed memory is filled with this value so that references to it will
|
||||||
/* end up being very strange. */
|
end up being very strange.
|
||||||
#define FREE_VAL (uchar) 0x8F /* FREE'ed memory is filled with this */
|
*/
|
||||||
/* value so that references to it will */
|
#define ALLOC_VAL (uchar) 0xA5
|
||||||
/* also end up being strange. */
|
/*
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
|
|
@ -147,6 +145,7 @@ gptr _mymalloc (uint uSize, const char *sFile, uint uLine, myf MyFlags)
|
||||||
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,8 +224,8 @@ 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,
|
||||||
|
|
@ -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))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -1502,7 +1502,8 @@ 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
|
/*
|
||||||
|
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
|
create an entry for it, since we immediately release the lock. In
|
||||||
this case, we will not be waiting, but rather, just waste CPU and
|
this case, we will not be waiting, but rather, just waste CPU and
|
||||||
memory on the whole deal
|
memory on the whole deal
|
||||||
|
|
@ -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,7 +2095,8 @@ 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
|
/*
|
||||||
|
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
|
to remove; If it would ever to be removed, this should include
|
||||||
modifications to find_best and auto_close as complement to auto_init code
|
modifications to find_best and auto_close as complement to auto_init code
|
||||||
above.
|
above.
|
||||||
|
|
@ -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);
|
||||||
|
|
@ -2204,12 +2214,11 @@ err:
|
||||||
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,7 +2240,6 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
52
sql/log.cc
52
sql/log.cc
|
|
@ -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)
|
||||||
|
|
|
||||||
365
sql/log_event.cc
365
sql/log_event.cc
|
|
@ -113,8 +113,7 @@ static inline char* slave_load_file_stem(char*buf, uint file_id,
|
||||||
|
|
||||||
const char* Log_event::get_type_str()
|
const char* Log_event::get_type_str()
|
||||||
{
|
{
|
||||||
switch(get_type_code())
|
switch(get_type_code()) {
|
||||||
{
|
|
||||||
case START_EVENT: return "Start";
|
case START_EVENT: return "Start";
|
||||||
case STOP_EVENT: return "Stop";
|
case STOP_EVENT: return "Stop";
|
||||||
case QUERY_EVENT: return "Query";
|
case QUERY_EVENT: return "Query";
|
||||||
|
|
@ -132,9 +131,8 @@ const char* Log_event::get_type_str()
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
Log_event::Log_event(THD* thd_arg, uint16 flags_arg):
|
Log_event::Log_event(THD* thd_arg, uint16 flags_arg)
|
||||||
exec_time(0),
|
:exec_time(0), flags(flags_arg), cached_event_len(0),
|
||||||
flags(flags_arg),cached_event_len(0),
|
|
||||||
temp_buf(0), thd(thd_arg)
|
temp_buf(0), thd(thd_arg)
|
||||||
{
|
{
|
||||||
if (thd)
|
if (thd)
|
||||||
|
|
@ -151,6 +149,7 @@ Log_event::Log_event(THD* thd_arg, uint16 flags_arg):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void cleanup_load_tmpdir()
|
static void cleanup_load_tmpdir()
|
||||||
{
|
{
|
||||||
MY_DIR *dirp;
|
MY_DIR *dirp;
|
||||||
|
|
@ -171,8 +170,8 @@ static void cleanup_load_tmpdir()
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Log_event::Log_event(const char* buf, bool old_format):
|
Log_event::Log_event(const char* buf, bool old_format)
|
||||||
cached_event_len(0),temp_buf(0)
|
:cached_event_len(0), temp_buf(0)
|
||||||
{
|
{
|
||||||
when = uint4korr(buf);
|
when = uint4korr(buf);
|
||||||
server_id = uint4korr(buf + SERVER_ID_OFFSET);
|
server_id = uint4korr(buf + SERVER_ID_OFFSET);
|
||||||
|
|
@ -319,10 +318,9 @@ void Load_log_event::pack_info(String* packet)
|
||||||
|
|
||||||
void Rotate_log_event::pack_info(String* packet)
|
void Rotate_log_event::pack_info(String* packet)
|
||||||
{
|
{
|
||||||
char buf1[256];
|
char buf1[256], buf[22];
|
||||||
String tmp(buf1, sizeof(buf1));
|
String tmp(buf1, sizeof(buf1));
|
||||||
tmp.length(0);
|
tmp.length(0);
|
||||||
char buf[22];
|
|
||||||
tmp.append(new_log_ident, ident_len);
|
tmp.append(new_log_ident, ident_len);
|
||||||
tmp.append(";pos=");
|
tmp.append(";pos=");
|
||||||
tmp.append(llstr(pos,buf));
|
tmp.append(llstr(pos,buf));
|
||||||
|
|
@ -333,10 +331,9 @@ void Rotate_log_event::pack_info(String* packet)
|
||||||
|
|
||||||
void Intvar_log_event::pack_info(String* packet)
|
void Intvar_log_event::pack_info(String* packet)
|
||||||
{
|
{
|
||||||
char buf1[256];
|
char buf1[256], buf[22];
|
||||||
String tmp(buf1, sizeof(buf1));
|
String tmp(buf1, sizeof(buf1));
|
||||||
tmp.length(0);
|
tmp.length(0);
|
||||||
char buf[22];
|
|
||||||
tmp.append(get_var_type_name());
|
tmp.append(get_var_type_name());
|
||||||
tmp.append('=');
|
tmp.append('=');
|
||||||
tmp.append(llstr(val, buf));
|
tmp.append(llstr(val, buf));
|
||||||
|
|
@ -345,14 +342,14 @@ void Intvar_log_event::pack_info(String* packet)
|
||||||
|
|
||||||
void Slave_log_event::pack_info(String* packet)
|
void Slave_log_event::pack_info(String* packet)
|
||||||
{
|
{
|
||||||
char buf1[256];
|
char buf1[256], buf[22], *end;
|
||||||
String tmp(buf1, sizeof(buf1));
|
String tmp(buf1, sizeof(buf1));
|
||||||
tmp.length(0);
|
tmp.length(0);
|
||||||
char buf[22];
|
|
||||||
tmp.append("host=");
|
tmp.append("host=");
|
||||||
tmp.append(master_host);
|
tmp.append(master_host);
|
||||||
tmp.append(",port=");
|
tmp.append(",port=");
|
||||||
tmp.append(llstr(master_port,buf));
|
end= int10_to_str((long) master_port, buf, 10);
|
||||||
|
tmp.append(buf, (uint32) (end-buf));
|
||||||
tmp.append(",log=");
|
tmp.append(",log=");
|
||||||
tmp.append(master_log);
|
tmp.append(master_log);
|
||||||
tmp.append(",pos=");
|
tmp.append(",pos=");
|
||||||
|
|
@ -390,18 +387,21 @@ int Log_event::net_send(THD* thd, const char* log_name, my_off_t pos)
|
||||||
return my_net_write(&thd->net, (char*) packet->ptr(), packet->length());
|
return my_net_write(&thd->net, (char*) packet->ptr(), packet->length());
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif /* MYSQL_CLIENT */
|
||||||
|
|
||||||
|
|
||||||
int Query_log_event::write(IO_CACHE* file)
|
int Query_log_event::write(IO_CACHE* file)
|
||||||
{
|
{
|
||||||
return query ? Log_event::write(file) : -1;
|
return query ? Log_event::write(file) : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Log_event::write(IO_CACHE* file)
|
int Log_event::write(IO_CACHE* file)
|
||||||
{
|
{
|
||||||
return (write_header(file) || write_data(file)) ? -1 : 0;
|
return (write_header(file) || write_data(file)) ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Log_event::write_header(IO_CACHE* file)
|
int Log_event::write_header(IO_CACHE* file)
|
||||||
{
|
{
|
||||||
char buf[LOG_EVENT_HEADER_LEN];
|
char buf[LOG_EVENT_HEADER_LEN];
|
||||||
|
|
@ -427,24 +427,31 @@ int Log_event::read_log_event(IO_CACHE* file, String* packet,
|
||||||
pthread_mutex_t* log_lock)
|
pthread_mutex_t* log_lock)
|
||||||
{
|
{
|
||||||
ulong data_len;
|
ulong data_len;
|
||||||
|
int result=0;
|
||||||
char buf[LOG_EVENT_HEADER_LEN];
|
char buf[LOG_EVENT_HEADER_LEN];
|
||||||
|
|
||||||
if (log_lock)
|
if (log_lock)
|
||||||
pthread_mutex_lock(log_lock);
|
pthread_mutex_lock(log_lock);
|
||||||
if (my_b_read(file, (byte*) buf, sizeof(buf)))
|
if (my_b_read(file, (byte*) buf, sizeof(buf)))
|
||||||
{
|
{
|
||||||
if (log_lock) pthread_mutex_unlock(log_lock);
|
/*
|
||||||
// if the read hits eof, we must report it as eof
|
If the read hits eof, we must report it as eof so the caller
|
||||||
// so the caller will know it can go into cond_wait to be woken up
|
will know it can go into cond_wait to be woken up on the next
|
||||||
// on the next update to the log
|
update to the log.
|
||||||
if (!file->error) return LOG_READ_EOF;
|
*/
|
||||||
return file->error > 0 ? LOG_READ_TRUNC: LOG_READ_IO;
|
if (!file->error)
|
||||||
|
result= LOG_READ_EOF;
|
||||||
|
else
|
||||||
|
result= (file->error > 0 ? LOG_READ_TRUNC: LOG_READ_IO);
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
data_len= uint4korr(buf + EVENT_LEN_OFFSET);
|
data_len= uint4korr(buf + EVENT_LEN_OFFSET);
|
||||||
if (data_len < LOG_EVENT_HEADER_LEN || data_len > max_allowed_packet)
|
if (data_len < LOG_EVENT_HEADER_LEN || data_len > max_allowed_packet)
|
||||||
{
|
{
|
||||||
if (log_lock) pthread_mutex_unlock(log_lock);
|
|
||||||
return (data_len < LOG_EVENT_HEADER_LEN) ? LOG_READ_BOGUS :
|
result= ((data_len < LOG_EVENT_HEADER_LEN) ? LOG_READ_BOGUS :
|
||||||
LOG_READ_TOO_LARGE;
|
LOG_READ_TOO_LARGE);
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
packet->append(buf, sizeof(buf));
|
packet->append(buf, sizeof(buf));
|
||||||
data_len-= LOG_EVENT_HEADER_LEN;
|
data_len-= LOG_EVENT_HEADER_LEN;
|
||||||
|
|
@ -452,29 +459,29 @@ int Log_event::read_log_event(IO_CACHE* file, String* packet,
|
||||||
{
|
{
|
||||||
if (packet->append(file, data_len))
|
if (packet->append(file, data_len))
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
Here we should never hit eof in a non-error condtion
|
||||||
|
eof means we are reading the event partially, which should
|
||||||
|
never happen.
|
||||||
|
*/
|
||||||
|
result= file->error >= 0 ? LOG_READ_TRUNC: LOG_READ_IO;
|
||||||
|
/* Implicit goto end; */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
if (log_lock)
|
if (log_lock)
|
||||||
pthread_mutex_unlock(log_lock);
|
pthread_mutex_unlock(log_lock);
|
||||||
// here we should never hit eof in a non-error condtion
|
return result;
|
||||||
// eof means we are reading the event partially, which should
|
|
||||||
// never happen
|
|
||||||
return file->error >= 0 ? LOG_READ_TRUNC: LOG_READ_IO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (log_lock) pthread_mutex_unlock(log_lock);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // MYSQL_CLIENT
|
#endif // MYSQL_CLIENT
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
#define UNLOCK_MUTEX if (log_lock) pthread_mutex_unlock(log_lock);
|
#define UNLOCK_MUTEX if (log_lock) pthread_mutex_unlock(log_lock);
|
||||||
#else
|
|
||||||
#define UNLOCK_MUTEX
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
|
||||||
#define LOCK_MUTEX if (log_lock) pthread_mutex_lock(log_lock);
|
#define LOCK_MUTEX if (log_lock) pthread_mutex_lock(log_lock);
|
||||||
#else
|
#else
|
||||||
|
#define UNLOCK_MUTEX
|
||||||
#define LOCK_MUTEX
|
#define LOCK_MUTEX
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -488,8 +495,8 @@ Log_event* Log_event::read_log_event(IO_CACHE* file, bool old_format)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
char head[LOG_EVENT_HEADER_LEN];
|
char head[LOG_EVENT_HEADER_LEN];
|
||||||
uint header_size = old_format ? OLD_HEADER_LEN :
|
uint header_size= old_format ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN;
|
||||||
LOG_EVENT_HEADER_LEN;
|
|
||||||
LOCK_MUTEX;
|
LOCK_MUTEX;
|
||||||
if (my_b_read(file, (byte *) head, header_size))
|
if (my_b_read(file, (byte *) head, header_size))
|
||||||
{
|
{
|
||||||
|
|
@ -522,14 +529,14 @@ Log_event* Log_event::read_log_event(IO_CACHE* file, bool old_format)
|
||||||
}
|
}
|
||||||
buf[data_len] = 0;
|
buf[data_len] = 0;
|
||||||
memcpy(buf, head, header_size);
|
memcpy(buf, head, header_size);
|
||||||
if (my_b_read(file, (byte*) buf + header_size,
|
if (my_b_read(file, (byte*) buf + header_size, data_len - header_size))
|
||||||
data_len - header_size))
|
|
||||||
{
|
{
|
||||||
error = "read error";
|
error = "read error";
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if ((res = read_log_event(buf, data_len, &error, old_format)))
|
if ((res = read_log_event(buf, data_len, &error, old_format)))
|
||||||
res->register_temp_buf(buf);
|
res->register_temp_buf(buf);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
UNLOCK_MUTEX;
|
UNLOCK_MUTEX;
|
||||||
if (error)
|
if (error)
|
||||||
|
|
@ -541,17 +548,20 @@ data_len=%d,event_type=%d",error,data_len,head[EVENT_TYPE_OFFSET]);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Log_event* Log_event::read_log_event(const char* buf, int event_len,
|
Log_event* Log_event::read_log_event(const char* buf, int event_len,
|
||||||
const char **error, bool old_format)
|
const char **error, bool old_format)
|
||||||
{
|
{
|
||||||
if (event_len < EVENT_LEN_OFFSET ||
|
if (event_len < EVENT_LEN_OFFSET ||
|
||||||
(uint) event_len != uint4korr(buf+EVENT_LEN_OFFSET))
|
(uint) event_len != uint4korr(buf+EVENT_LEN_OFFSET))
|
||||||
|
{
|
||||||
|
*error="Sanity check failed"; // Needed to free buffer
|
||||||
return NULL; // general sanity check - will fail on a partial read
|
return NULL; // general sanity check - will fail on a partial read
|
||||||
|
}
|
||||||
|
|
||||||
Log_event* ev = NULL;
|
Log_event* ev = NULL;
|
||||||
|
|
||||||
switch(buf[EVENT_TYPE_OFFSET])
|
switch(buf[EVENT_TYPE_OFFSET]) {
|
||||||
{
|
|
||||||
case QUERY_EVENT:
|
case QUERY_EVENT:
|
||||||
ev = new Query_log_event(buf, event_len, old_format);
|
ev = new Query_log_event(buf, event_len, old_format);
|
||||||
break;
|
break;
|
||||||
|
|
@ -591,8 +601,7 @@ Log_event* Log_event::read_log_event(const char* buf, int event_len,
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!ev) return 0;
|
if (!ev || !ev->is_valid())
|
||||||
if (!ev->is_valid())
|
|
||||||
{
|
{
|
||||||
*error= "Found invalid event in binary log";
|
*error= "Found invalid event in binary log";
|
||||||
delete ev;
|
delete ev;
|
||||||
|
|
@ -602,6 +611,7 @@ Log_event* Log_event::read_log_event(const char* buf, int event_len,
|
||||||
return ev;
|
return ev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef MYSQL_CLIENT
|
#ifdef MYSQL_CLIENT
|
||||||
void Log_event::print_header(FILE* file)
|
void Log_event::print_header(FILE* file)
|
||||||
{
|
{
|
||||||
|
|
@ -614,15 +624,11 @@ void Log_event::print_header(FILE* file)
|
||||||
|
|
||||||
void Log_event::print_timestamp(FILE* file, time_t* ts)
|
void Log_event::print_timestamp(FILE* file, time_t* ts)
|
||||||
{
|
{
|
||||||
#ifdef MYSQL_SERVER
|
|
||||||
struct tm tm_tmp;
|
|
||||||
#endif
|
|
||||||
struct tm *res;
|
struct tm *res;
|
||||||
if (!ts)
|
if (!ts)
|
||||||
{
|
|
||||||
ts = &when;
|
ts = &when;
|
||||||
}
|
#ifdef MYSQL_SERVER // This is always false
|
||||||
#ifdef MYSQL_SERVER
|
struct tm tm_tmp;
|
||||||
localtime_r(ts,(res= &tm_tmp));
|
localtime_r(ts,(res= &tm_tmp));
|
||||||
#else
|
#else
|
||||||
res=localtime(ts);
|
res=localtime(ts);
|
||||||
|
|
@ -678,8 +684,10 @@ void Rotate_log_event::print(FILE* file, bool short_form, char* last_db)
|
||||||
|
|
||||||
#endif /* #ifdef MYSQL_CLIENT */
|
#endif /* #ifdef MYSQL_CLIENT */
|
||||||
|
|
||||||
|
|
||||||
Start_log_event::Start_log_event(const char* buf,
|
Start_log_event::Start_log_event(const char* buf,
|
||||||
bool old_format) :Log_event(buf, old_format)
|
bool old_format)
|
||||||
|
:Log_event(buf, old_format)
|
||||||
{
|
{
|
||||||
buf += (old_format) ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN;
|
buf += (old_format) ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN;
|
||||||
binlog_version = uint2korr(buf+ST_BINLOG_VER_OFFSET);
|
binlog_version = uint2korr(buf+ST_BINLOG_VER_OFFSET);
|
||||||
|
|
@ -697,9 +705,10 @@ int Start_log_event::write_data(IO_CACHE* file)
|
||||||
return (my_b_safe_write(file, (byte*) buff, sizeof(buff)) ? -1 : 0);
|
return (my_b_safe_write(file, (byte*) buff, sizeof(buff)) ? -1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Rotate_log_event::Rotate_log_event(const char* buf, int event_len,
|
Rotate_log_event::Rotate_log_event(const char* buf, int event_len,
|
||||||
bool old_format):
|
bool old_format)
|
||||||
Log_event(buf, old_format),new_log_ident(NULL),alloced(0)
|
:Log_event(buf, old_format),new_log_ident(NULL),alloced(0)
|
||||||
{
|
{
|
||||||
// The caller will ensure that event_len is what we have at EVENT_LEN_OFFSET
|
// The caller will ensure that event_len is what we have at EVENT_LEN_OFFSET
|
||||||
int header_size = (old_format) ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN;
|
int header_size = (old_format) ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN;
|
||||||
|
|
@ -726,18 +735,20 @@ Rotate_log_event::Rotate_log_event(const char* buf, int event_len,
|
||||||
alloced = 1;
|
alloced = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Rotate_log_event::write_data(IO_CACHE* file)
|
int Rotate_log_event::write_data(IO_CACHE* file)
|
||||||
{
|
{
|
||||||
char buf[ROTATE_HEADER_LEN];
|
char buf[ROTATE_HEADER_LEN];
|
||||||
int8store(buf, pos + R_POS_OFFSET);
|
int8store(buf, pos + R_POS_OFFSET);
|
||||||
return my_b_safe_write(file, (byte*)buf, ROTATE_HEADER_LEN) ||
|
return (my_b_safe_write(file, (byte*)buf, ROTATE_HEADER_LEN) ||
|
||||||
my_b_safe_write(file, (byte*)new_log_ident, (uint) ident_len);
|
my_b_safe_write(file, (byte*)new_log_ident, (uint) ident_len));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
|
Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
|
||||||
bool using_trans):
|
bool using_trans)
|
||||||
Log_event(thd_arg), data_buf(0), query(query_arg), db(thd_arg->db),
|
:Log_event(thd_arg), data_buf(0), query(query_arg), db(thd_arg->db),
|
||||||
q_len(thd_arg->query_length),
|
q_len(thd_arg->query_length),
|
||||||
error_code(thd_arg->killed ? ER_SERVER_SHUTDOWN: thd_arg->net.last_errno),
|
error_code(thd_arg->killed ? ER_SERVER_SHUTDOWN: thd_arg->net.last_errno),
|
||||||
thread_id(thd_arg->thread_id),
|
thread_id(thd_arg->thread_id),
|
||||||
|
|
@ -786,6 +797,7 @@ Query_log_event::Query_log_event(const char* buf, int event_len,
|
||||||
*((char*)query+q_len) = 0;
|
*((char*)query+q_len) = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef MYSQL_CLIENT
|
#ifdef MYSQL_CLIENT
|
||||||
|
|
||||||
void Query_log_event::print(FILE* file, bool short_form, char* last_db)
|
void Query_log_event::print(FILE* file, bool short_form, char* last_db)
|
||||||
|
|
@ -815,12 +827,13 @@ void Query_log_event::print(FILE* file, bool short_form, char* last_db)
|
||||||
my_fwrite(file, (byte*) query, q_len, MYF(MY_NABP | MY_WME));
|
my_fwrite(file, (byte*) query, q_len, MYF(MY_NABP | MY_WME));
|
||||||
fprintf(file, ";\n");
|
fprintf(file, ";\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
int Query_log_event::write_data(IO_CACHE* file)
|
int Query_log_event::write_data(IO_CACHE* file)
|
||||||
{
|
{
|
||||||
if (!query) return -1;
|
if (!query)
|
||||||
|
return -1;
|
||||||
|
|
||||||
char buf[QUERY_HEADER_LEN];
|
char buf[QUERY_HEADER_LEN];
|
||||||
int4store(buf + Q_THREAD_ID_OFFSET, thread_id);
|
int4store(buf + Q_THREAD_ID_OFFSET, thread_id);
|
||||||
|
|
@ -833,8 +846,8 @@ int Query_log_event::write_data(IO_CACHE* file)
|
||||||
my_b_safe_write(file, (byte*) query, q_len)) ? -1 : 0;
|
my_b_safe_write(file, (byte*) query, q_len)) ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Intvar_log_event::Intvar_log_event(const char* buf, bool old_format):
|
Intvar_log_event::Intvar_log_event(const char* buf, bool old_format)
|
||||||
Log_event(buf, old_format)
|
:Log_event(buf, old_format)
|
||||||
{
|
{
|
||||||
buf += (old_format) ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN;
|
buf += (old_format) ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN;
|
||||||
type = buf[I_TYPE_OFFSET];
|
type = buf[I_TYPE_OFFSET];
|
||||||
|
|
@ -843,8 +856,7 @@ Intvar_log_event::Intvar_log_event(const char* buf, bool old_format):
|
||||||
|
|
||||||
const char* Intvar_log_event::get_var_type_name()
|
const char* Intvar_log_event::get_var_type_name()
|
||||||
{
|
{
|
||||||
switch(type)
|
switch(type) {
|
||||||
{
|
|
||||||
case LAST_INSERT_ID_EVENT: return "LAST_INSERT_ID";
|
case LAST_INSERT_ID_EVENT: return "LAST_INSERT_ID";
|
||||||
case INSERT_ID_EVENT: return "INSERT_ID";
|
case INSERT_ID_EVENT: return "INSERT_ID";
|
||||||
default: /* impossible */ return "UNKNOWN";
|
default: /* impossible */ return "UNKNOWN";
|
||||||
|
|
@ -863,6 +875,9 @@ int Intvar_log_event::write_data(IO_CACHE* file)
|
||||||
void Intvar_log_event::print(FILE* file, bool short_form, char* last_db)
|
void Intvar_log_event::print(FILE* file, bool short_form, char* last_db)
|
||||||
{
|
{
|
||||||
char llbuff[22];
|
char llbuff[22];
|
||||||
|
const char *msg;
|
||||||
|
LINT_INIT(msg);
|
||||||
|
|
||||||
if (!short_form)
|
if (!short_form)
|
||||||
{
|
{
|
||||||
print_header(file);
|
print_header(file);
|
||||||
|
|
@ -870,21 +885,20 @@ void Intvar_log_event::print(FILE* file, bool short_form, char* last_db)
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(file, "SET ");
|
fprintf(file, "SET ");
|
||||||
switch(type)
|
switch (type) {
|
||||||
{
|
|
||||||
case LAST_INSERT_ID_EVENT:
|
case LAST_INSERT_ID_EVENT:
|
||||||
fprintf(file, "LAST_INSERT_ID = ");
|
msg="LAST_INSERT_ID";
|
||||||
break;
|
break;
|
||||||
case INSERT_ID_EVENT:
|
case INSERT_ID_EVENT:
|
||||||
fprintf(file, "INSERT_ID = ");
|
msg="INSERT_ID";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fprintf(file, "%s;\n", llstr(val,llbuff));
|
fprintf(file, "%s=%s;\n", msg, llstr(val,llbuff));
|
||||||
fflush(file);
|
fflush(file);
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
int Load_log_event::write_data_header(IO_CACHE* file)
|
int Load_log_event::write_data_header(IO_CACHE* file)
|
||||||
{
|
{
|
||||||
char buf[LOAD_HEADER_LEN];
|
char buf[LOAD_HEADER_LEN];
|
||||||
|
|
@ -899,7 +913,8 @@ int Load_log_event::write_data_header(IO_CACHE* file)
|
||||||
|
|
||||||
int Load_log_event::write_data_body(IO_CACHE* file)
|
int Load_log_event::write_data_body(IO_CACHE* file)
|
||||||
{
|
{
|
||||||
if (sql_ex.write_data(file)) return 1;
|
if (sql_ex.write_data(file))
|
||||||
|
return 1;
|
||||||
if (num_fields && fields && field_lens)
|
if (num_fields && fields && field_lens)
|
||||||
{
|
{
|
||||||
if (my_b_safe_write(file, (byte*)field_lens, num_fields) ||
|
if (my_b_safe_write(file, (byte*)field_lens, num_fields) ||
|
||||||
|
|
@ -912,12 +927,14 @@ int Load_log_event::write_data_body(IO_CACHE* file)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static bool write_str(IO_CACHE *file, char *str, byte length)
|
static bool write_str(IO_CACHE *file, char *str, byte length)
|
||||||
{
|
{
|
||||||
return (my_b_safe_write(file, &length, 1) ||
|
return (my_b_safe_write(file, &length, 1) ||
|
||||||
my_b_safe_write(file, (byte*) str, (int) length));
|
my_b_safe_write(file, (byte*) str, (int) length));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int sql_ex_info::write_data(IO_CACHE* file)
|
int sql_ex_info::write_data(IO_CACHE* file)
|
||||||
{
|
{
|
||||||
if (new_format())
|
if (new_format())
|
||||||
|
|
@ -943,6 +960,7 @@ int sql_ex_info::write_data(IO_CACHE* file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline int read_str(char * &buf, char *buf_end, char * &str,
|
static inline int read_str(char * &buf, char *buf_end, char * &str,
|
||||||
uint8 &len)
|
uint8 &len)
|
||||||
{
|
{
|
||||||
|
|
@ -954,6 +972,7 @@ static inline int read_str(char * &buf, char *buf_end, char * &str,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char* sql_ex_info::init(char* buf,char* buf_end,bool use_new_format)
|
char* sql_ex_info::init(char* buf,char* buf_end,bool use_new_format)
|
||||||
{
|
{
|
||||||
cached_new_format = use_new_format;
|
cached_new_format = use_new_format;
|
||||||
|
|
@ -978,7 +997,7 @@ char* sql_ex_info::init(char* buf,char* buf_end,bool use_new_format)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
field_term_len= enclosed_len= line_term_len= line_start_len= escaped_len=1;
|
field_term_len= enclosed_len= line_term_len= line_start_len= escaped_len=1;
|
||||||
field_term = buf++;
|
field_term = buf++; // Use first byte in string
|
||||||
enclosed= buf++;
|
enclosed= buf++;
|
||||||
line_term= buf++;
|
line_term= buf++;
|
||||||
line_start= buf++;
|
line_start= buf++;
|
||||||
|
|
@ -1034,14 +1053,12 @@ Load_log_event::Load_log_event(THD* thd, sql_exchange* ex,
|
||||||
|
|
||||||
sql_ex.empty_flags = 0;
|
sql_ex.empty_flags = 0;
|
||||||
|
|
||||||
switch(handle_dup)
|
switch (handle_dup) {
|
||||||
{
|
|
||||||
case DUP_IGNORE: sql_ex.opt_flags |= IGNORE_FLAG; break;
|
case DUP_IGNORE: sql_ex.opt_flags |= IGNORE_FLAG; break;
|
||||||
case DUP_REPLACE: sql_ex.opt_flags |= REPLACE_FLAG; break;
|
case DUP_REPLACE: sql_ex.opt_flags |= REPLACE_FLAG; break;
|
||||||
case DUP_ERROR: break;
|
case DUP_ERROR: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!ex->field_term->length())
|
if (!ex->field_term->length())
|
||||||
sql_ex.empty_flags |= FIELD_TERM_EMPTY;
|
sql_ex.empty_flags |= FIELD_TERM_EMPTY;
|
||||||
if (!ex->enclosed->length())
|
if (!ex->enclosed->length())
|
||||||
|
|
@ -1074,8 +1091,11 @@ Load_log_event::Load_log_event(THD* thd, sql_exchange* ex,
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// the caller must do buf[event_len] = 0 before he starts using the
|
/*
|
||||||
// constructed event
|
The caller must do buf[event_len] = 0 before he starts using the
|
||||||
|
constructed event.
|
||||||
|
*/
|
||||||
|
|
||||||
Load_log_event::Load_log_event(const char* buf, int event_len,
|
Load_log_event::Load_log_event(const char* buf, int event_len,
|
||||||
bool old_format):
|
bool old_format):
|
||||||
Log_event(buf, old_format),num_fields(0),fields(0),
|
Log_event(buf, old_format),num_fields(0),fields(0),
|
||||||
|
|
@ -1101,13 +1121,16 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len,
|
||||||
db_len = (uint)data_head[L_DB_LEN_OFFSET];
|
db_len = (uint)data_head[L_DB_LEN_OFFSET];
|
||||||
num_fields = uint4korr(data_head + L_NUM_FIELDS_OFFSET);
|
num_fields = uint4korr(data_head + L_NUM_FIELDS_OFFSET);
|
||||||
|
|
||||||
int body_offset = (buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ?
|
int body_offset = ((buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ?
|
||||||
LOAD_HEADER_LEN + OLD_HEADER_LEN : get_data_body_offset();
|
LOAD_HEADER_LEN + OLD_HEADER_LEN :
|
||||||
|
get_data_body_offset());
|
||||||
|
|
||||||
if ((int) event_len < body_offset)
|
if ((int) event_len < body_offset)
|
||||||
return 1;
|
return 1;
|
||||||
//sql_ex.init() on success returns the pointer to the first byte after
|
/*
|
||||||
//the sql_ex structure, which is the start of field lengths array
|
Sql_ex.init() on success returns the pointer to the first byte after
|
||||||
|
the sql_ex structure, which is the start of field lengths array.
|
||||||
|
*/
|
||||||
if (!(field_lens=(uchar*)sql_ex.init((char*)buf + body_offset,
|
if (!(field_lens=(uchar*)sql_ex.init((char*)buf + body_offset,
|
||||||
buf_end,
|
buf_end,
|
||||||
buf[EVENT_TYPE_OFFSET] != LOAD_EVENT)))
|
buf[EVENT_TYPE_OFFSET] != LOAD_EVENT)))
|
||||||
|
|
@ -1116,11 +1139,9 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len,
|
||||||
data_len = event_len - body_offset;
|
data_len = event_len - body_offset;
|
||||||
if (num_fields > data_len) // simple sanity check against corruption
|
if (num_fields > data_len) // simple sanity check against corruption
|
||||||
return 1;
|
return 1;
|
||||||
uint i;
|
for (uint i = 0; i < num_fields; i++)
|
||||||
for (i = 0; i < num_fields; i++)
|
|
||||||
{
|
|
||||||
field_block_len += (uint)field_lens[i] + 1;
|
field_block_len += (uint)field_lens[i] + 1;
|
||||||
}
|
|
||||||
fields = (char*)field_lens + num_fields;
|
fields = (char*)field_lens + num_fields;
|
||||||
table_name = fields + field_block_len;
|
table_name = fields + field_block_len;
|
||||||
db = table_name + table_name_len + 1;
|
db = table_name + table_name_len + 1;
|
||||||
|
|
@ -1142,7 +1163,6 @@ void Load_log_event::print(FILE* file, bool short_form, char* last_db)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool same_db = 0;
|
bool same_db = 0;
|
||||||
|
|
||||||
if (db && last_db)
|
if (db && last_db)
|
||||||
{
|
{
|
||||||
if (!(same_db = !memcmp(last_db, db, db_len + 1)))
|
if (!(same_db = !memcmp(last_db, db, db_len + 1)))
|
||||||
|
|
@ -1224,6 +1244,7 @@ void Log_event::set_log_pos(MYSQL_LOG* log)
|
||||||
log_pos = my_b_tell(&log->log_file);
|
log_pos = my_b_tell(&log->log_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Load_log_event::set_fields(List<Item> &fields)
|
void Load_log_event::set_fields(List<Item> &fields)
|
||||||
{
|
{
|
||||||
uint i;
|
uint i;
|
||||||
|
|
@ -1270,8 +1291,7 @@ Slave_log_event::Slave_log_event(THD* thd_arg,
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* ! MYSQL_CLIENT */
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
Slave_log_event::~Slave_log_event()
|
Slave_log_event::~Slave_log_event()
|
||||||
|
|
@ -1293,7 +1313,7 @@ master_log: '%s' master_pos: %s\n",
|
||||||
master_host, master_port, master_log, llstr(master_pos, llbuff));
|
master_host, master_port, master_log, llstr(master_pos, llbuff));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif /* MYSQL_CLIENT */
|
||||||
|
|
||||||
int Slave_log_event::get_data_size()
|
int Slave_log_event::get_data_size()
|
||||||
{
|
{
|
||||||
|
|
@ -1308,6 +1328,7 @@ int Slave_log_event::write_data(IO_CACHE* file)
|
||||||
return my_b_safe_write(file, (byte*)mem_pool, get_data_size());
|
return my_b_safe_write(file, (byte*)mem_pool, get_data_size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Slave_log_event::init_from_mem_pool(int data_size)
|
void Slave_log_event::init_from_mem_pool(int data_size)
|
||||||
{
|
{
|
||||||
master_pos = uint8korr(mem_pool + SL_MASTER_POS_OFFSET);
|
master_pos = uint8korr(mem_pool + SL_MASTER_POS_OFFSET);
|
||||||
|
|
@ -1324,8 +1345,8 @@ void Slave_log_event::init_from_mem_pool(int data_size)
|
||||||
master_log_len = strlen(master_log);
|
master_log_len = strlen(master_log);
|
||||||
}
|
}
|
||||||
|
|
||||||
Slave_log_event::Slave_log_event(const char* buf, int event_len):
|
Slave_log_event::Slave_log_event(const char* buf, int event_len)
|
||||||
Log_event(buf,0),mem_pool(0),master_host(0)
|
:Log_event(buf,0),mem_pool(0),master_host(0)
|
||||||
{
|
{
|
||||||
event_len -= LOG_EVENT_HEADER_LEN;
|
event_len -= LOG_EVENT_HEADER_LEN;
|
||||||
if (event_len < 0)
|
if (event_len < 0)
|
||||||
|
|
@ -1341,8 +1362,8 @@ Slave_log_event::Slave_log_event(const char* buf, int event_len):
|
||||||
Create_file_log_event::Create_file_log_event(THD* thd_arg, sql_exchange* ex,
|
Create_file_log_event::Create_file_log_event(THD* thd_arg, sql_exchange* ex,
|
||||||
const char* db_arg, const char* table_name_arg,
|
const char* db_arg, const char* table_name_arg,
|
||||||
List<Item>& fields_arg, enum enum_duplicates handle_dup,
|
List<Item>& fields_arg, enum enum_duplicates handle_dup,
|
||||||
char* block_arg, uint block_len_arg):
|
char* block_arg, uint block_len_arg)
|
||||||
Load_log_event(thd_arg,ex,db_arg,table_name_arg,fields_arg,handle_dup),
|
:Load_log_event(thd_arg,ex,db_arg,table_name_arg,fields_arg,handle_dup),
|
||||||
fake_base(0),block(block_arg),block_len(block_len_arg),
|
fake_base(0),block(block_arg),block_len(block_len_arg),
|
||||||
file_id(thd_arg->file_id = mysql_bin_log.next_file_id())
|
file_id(thd_arg->file_id = mysql_bin_log.next_file_id())
|
||||||
{
|
{
|
||||||
|
|
@ -1379,8 +1400,8 @@ int Create_file_log_event::write_base(IO_CACHE* file)
|
||||||
}
|
}
|
||||||
|
|
||||||
Create_file_log_event::Create_file_log_event(const char* buf, int len,
|
Create_file_log_event::Create_file_log_event(const char* buf, int len,
|
||||||
bool old_format):
|
bool old_format)
|
||||||
Load_log_event(buf,0,old_format),fake_base(0),block(0),inited_from_old(0)
|
:Load_log_event(buf,0,old_format),fake_base(0),block(0),inited_from_old(0)
|
||||||
{
|
{
|
||||||
int block_offset;
|
int block_offset;
|
||||||
if (copy_log_event(buf,len,old_format))
|
if (copy_log_event(buf,len,old_format))
|
||||||
|
|
@ -1389,8 +1410,9 @@ Create_file_log_event::Create_file_log_event(const char* buf, int len,
|
||||||
{
|
{
|
||||||
file_id = uint4korr(buf + LOG_EVENT_HEADER_LEN +
|
file_id = uint4korr(buf + LOG_EVENT_HEADER_LEN +
|
||||||
+ LOAD_HEADER_LEN + CF_FILE_ID_OFFSET);
|
+ LOAD_HEADER_LEN + CF_FILE_ID_OFFSET);
|
||||||
block_offset = LOG_EVENT_HEADER_LEN + Load_log_event::get_data_size() +
|
// + 1 for \0 terminating fname
|
||||||
CREATE_FILE_HEADER_LEN + 1; // 1 for \0 terminating fname
|
block_offset = (LOG_EVENT_HEADER_LEN + Load_log_event::get_data_size() +
|
||||||
|
CREATE_FILE_HEADER_LEN + 1);
|
||||||
if (len < block_offset)
|
if (len < block_offset)
|
||||||
return;
|
return;
|
||||||
block = (char*)buf + block_offset;
|
block = (char*)buf + block_offset;
|
||||||
|
|
@ -1418,33 +1440,34 @@ void Create_file_log_event::print(FILE* file, bool short_form,
|
||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
void Create_file_log_event::pack_info(String* packet)
|
void Create_file_log_event::pack_info(String* packet)
|
||||||
{
|
{
|
||||||
char buf1[256];
|
char buf1[256],buf[22], *end;
|
||||||
String tmp(buf1, sizeof(buf1));
|
String tmp(buf1, sizeof(buf1));
|
||||||
tmp.length(0);
|
tmp.length(0);
|
||||||
char buf[22];
|
|
||||||
tmp.append("db=");
|
tmp.append("db=");
|
||||||
tmp.append(db, db_len);
|
tmp.append(db, db_len);
|
||||||
tmp.append(";table=");
|
tmp.append(";table=");
|
||||||
tmp.append(table_name, table_name_len);
|
tmp.append(table_name, table_name_len);
|
||||||
tmp.append(";file_id=");
|
tmp.append(";file_id=");
|
||||||
tmp.append(llstr(file_id,buf));
|
end= int10_to_str((long) file_id, buf, 10);
|
||||||
|
tmp.append(buf, (uint32) (end-buf));
|
||||||
tmp.append(";block_len=");
|
tmp.append(";block_len=");
|
||||||
tmp.append(llstr(block_len,buf));
|
end= int10_to_str((long) block_len, buf, 10);
|
||||||
|
tmp.append(buf, (uint32) (end-buf));
|
||||||
net_store_data(packet, (char*) tmp.ptr(), tmp.length());
|
net_store_data(packet, (char*) tmp.ptr(), tmp.length());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
Append_block_log_event::Append_block_log_event(THD* thd_arg, char* block_arg,
|
Append_block_log_event::Append_block_log_event(THD* thd_arg, char* block_arg,
|
||||||
uint block_len_arg):
|
uint block_len_arg)
|
||||||
Log_event(thd_arg), block(block_arg),block_len(block_len_arg),
|
:Log_event(thd_arg), block(block_arg),block_len(block_len_arg),
|
||||||
file_id(thd_arg->file_id)
|
file_id(thd_arg->file_id)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Append_block_log_event::Append_block_log_event(const char* buf, int len):
|
Append_block_log_event::Append_block_log_event(const char* buf, int len)
|
||||||
Log_event(buf, 0),block(0)
|
:Log_event(buf, 0),block(0)
|
||||||
{
|
{
|
||||||
if ((uint)len < APPEND_BLOCK_EVENT_OVERHEAD)
|
if ((uint)len < APPEND_BLOCK_EVENT_OVERHEAD)
|
||||||
return;
|
return;
|
||||||
|
|
@ -1473,36 +1496,31 @@ void Append_block_log_event::print(FILE* file, bool short_form,
|
||||||
file_id, block_len);
|
file_id, block_len);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
void Append_block_log_event::pack_info(String* packet)
|
void Append_block_log_event::pack_info(String* packet)
|
||||||
{
|
{
|
||||||
char buf1[256];
|
char buf1[256];
|
||||||
String tmp(buf1, sizeof(buf1));
|
sprintf(buf1, ";file_id=%u;block_len=%u", file_id, block_len);
|
||||||
tmp.length(0);
|
net_store_data(packet, buf1);
|
||||||
char buf[22];
|
|
||||||
tmp.append(";file_id=");
|
|
||||||
tmp.append(llstr(file_id,buf));
|
|
||||||
tmp.append(";block_len=");
|
|
||||||
tmp.append(llstr(block_len,buf));
|
|
||||||
net_store_data(packet, (char*)tmp.ptr(), tmp.length());
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
Delete_file_log_event::Delete_file_log_event(THD* thd_arg)
|
||||||
Delete_file_log_event::Delete_file_log_event(THD* thd_arg):
|
:Log_event(thd_arg),file_id(thd_arg->file_id)
|
||||||
Log_event(thd_arg),file_id(thd_arg->file_id)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Delete_file_log_event::Delete_file_log_event(const char* buf, int len):
|
|
||||||
Log_event(buf, 0),file_id(0)
|
Delete_file_log_event::Delete_file_log_event(const char* buf, int len)
|
||||||
|
:Log_event(buf, 0),file_id(0)
|
||||||
{
|
{
|
||||||
if ((uint)len < DELETE_FILE_EVENT_OVERHEAD)
|
if ((uint)len < DELETE_FILE_EVENT_OVERHEAD)
|
||||||
return;
|
return;
|
||||||
file_id = uint4korr(buf + LOG_EVENT_HEADER_LEN + AB_FILE_ID_OFFSET);
|
file_id = uint4korr(buf + LOG_EVENT_HEADER_LEN + AB_FILE_ID_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Delete_file_log_event::write_data(IO_CACHE* file)
|
int Delete_file_log_event::write_data(IO_CACHE* file)
|
||||||
{
|
{
|
||||||
byte buf[DELETE_FILE_HEADER_LEN];
|
byte buf[DELETE_FILE_HEADER_LEN];
|
||||||
|
|
@ -1518,32 +1536,29 @@ void Delete_file_log_event::print(FILE* file, bool short_form,
|
||||||
return;
|
return;
|
||||||
print_header(file);
|
print_header(file);
|
||||||
fputc('\n', file);
|
fputc('\n', file);
|
||||||
fprintf(file, "#Delete_file: file_id=%d\n",
|
fprintf(file, "#Delete_file: file_id=%u\n", file_id);
|
||||||
file_id);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
void Delete_file_log_event::pack_info(String* packet)
|
void Delete_file_log_event::pack_info(String* packet)
|
||||||
{
|
{
|
||||||
char buf1[256];
|
char buf1[64];
|
||||||
String tmp(buf1, sizeof(buf1));
|
sprintf(buf1, ";file_id=%u", (uint) file_id);
|
||||||
tmp.length(0);
|
net_store_data(packet, buf1);
|
||||||
char buf[22];
|
|
||||||
tmp.append(";file_id=");
|
|
||||||
tmp.append(llstr(file_id,buf));
|
|
||||||
net_store_data(packet, (char*)tmp.ptr(), tmp.length());
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
Execute_load_log_event::Execute_load_log_event(THD* thd_arg):
|
Execute_load_log_event::Execute_load_log_event(THD* thd_arg)
|
||||||
Log_event(thd_arg),file_id(thd_arg->file_id)
|
:Log_event(thd_arg),file_id(thd_arg->file_id)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Execute_load_log_event::Execute_load_log_event(const char* buf,int len):
|
Execute_load_log_event::Execute_load_log_event(const char* buf,int len)
|
||||||
Log_event(buf, 0),file_id(0)
|
:Log_event(buf, 0),file_id(0)
|
||||||
{
|
{
|
||||||
if ((uint)len < EXEC_LOAD_EVENT_OVERHEAD)
|
if ((uint)len < EXEC_LOAD_EVENT_OVERHEAD)
|
||||||
return;
|
return;
|
||||||
|
|
@ -1572,13 +1587,9 @@ void Execute_load_log_event::print(FILE* file, bool short_form,
|
||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
void Execute_load_log_event::pack_info(String* packet)
|
void Execute_load_log_event::pack_info(String* packet)
|
||||||
{
|
{
|
||||||
char buf1[256];
|
char buf[64];
|
||||||
String tmp(buf1, sizeof(buf1));
|
sprintf(buf, ";file_id=%u", (uint) file_id);
|
||||||
tmp.length(0);
|
net_store_data(packet, buf);
|
||||||
char buf[22];
|
|
||||||
tmp.append(";file_id=");
|
|
||||||
tmp.append(llstr(file_id,buf));
|
|
||||||
net_store_data(packet, (char*)tmp.ptr(), tmp.length());
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -1602,14 +1613,16 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli)
|
||||||
thd->net.last_error[0] = 0;
|
thd->net.last_error[0] = 0;
|
||||||
thd->slave_proxy_id = thread_id; // for temp tables
|
thd->slave_proxy_id = thread_id; // for temp tables
|
||||||
|
|
||||||
// sanity check to make sure the master did not get a really bad
|
/*
|
||||||
// error on the query
|
Sanity check to make sure the master did not get a really bad
|
||||||
|
error on the query.
|
||||||
|
*/
|
||||||
if (ignored_error_code((expected_error = error_code)) ||
|
if (ignored_error_code((expected_error = error_code)) ||
|
||||||
!check_expected_error(thd,rli,expected_error))
|
!check_expected_error(thd,rli,expected_error))
|
||||||
{
|
{
|
||||||
mysql_parse(thd, thd->query, q_len);
|
mysql_parse(thd, thd->query, q_len);
|
||||||
if (expected_error !=
|
if ((expected_error != (actual_error = thd->net.last_errno)) &&
|
||||||
(actual_error = thd->net.last_errno) && expected_error &&
|
expected_error &&
|
||||||
!ignored_error_code(actual_error) &&
|
!ignored_error_code(actual_error) &&
|
||||||
!ignored_error_code(expected_error))
|
!ignored_error_code(expected_error))
|
||||||
{
|
{
|
||||||
|
|
@ -1621,8 +1634,8 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli)
|
||||||
actual_error);
|
actual_error);
|
||||||
thd->query_error = 1;
|
thd->query_error = 1;
|
||||||
}
|
}
|
||||||
else if (expected_error == actual_error
|
else if (expected_error == actual_error ||
|
||||||
|| ignored_error_code(actual_error))
|
ignored_error_code(actual_error))
|
||||||
{
|
{
|
||||||
thd->query_error = 0;
|
thd->query_error = 0;
|
||||||
*rli->last_slave_error = 0;
|
*rli->last_slave_error = 0;
|
||||||
|
|
@ -1657,6 +1670,7 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli)
|
||||||
return Log_event::exec_event(rli);
|
return Log_event::exec_event(rli);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli)
|
int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli)
|
||||||
{
|
{
|
||||||
init_sql_alloc(&thd->mem_root, 8192,0);
|
init_sql_alloc(&thd->mem_root, 8192,0);
|
||||||
|
|
@ -1710,8 +1724,9 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli)
|
||||||
{
|
{
|
||||||
// mysql_load will use thd->net to read the file
|
// mysql_load will use thd->net to read the file
|
||||||
thd->net.vio = net->vio;
|
thd->net.vio = net->vio;
|
||||||
// make sure the client does not get confused
|
/*
|
||||||
// about the packet sequence
|
Make sure the client does not get confused about the packet sequence
|
||||||
|
*/
|
||||||
thd->net.pkt_nr = net->pkt_nr;
|
thd->net.pkt_nr = net->pkt_nr;
|
||||||
}
|
}
|
||||||
if (mysql_load(thd, &ex, &tables, fields, handle_dup, net != 0,
|
if (mysql_load(thd, &ex, &tables, fields, handle_dup, net != 0,
|
||||||
|
|
@ -1727,9 +1742,11 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// we will just ask the master to send us /dev/null if we do not
|
/*
|
||||||
// want to load the data
|
We will just ask the master to send us /dev/null if we do not
|
||||||
// TODO: this a bug - needs to be done in I/O thread
|
want to load the data.
|
||||||
|
TODO: this a bug - needs to be done in I/O thread
|
||||||
|
*/
|
||||||
if (net)
|
if (net)
|
||||||
skip_load_data_infile(net);
|
skip_load_data_infile(net);
|
||||||
}
|
}
|
||||||
|
|
@ -1760,21 +1777,26 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli)
|
||||||
return Log_event::exec_event(rli);
|
return Log_event::exec_event(rli);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Start_log_event::exec_event(struct st_relay_log_info* rli)
|
int Start_log_event::exec_event(struct st_relay_log_info* rli)
|
||||||
{
|
{
|
||||||
close_temporary_tables(thd);
|
close_temporary_tables(thd);
|
||||||
// if we have old format, load_tmpdir is cleaned up by the I/O thread
|
/*
|
||||||
// TODO: cleanup_load_tmpdir() needs to remove only the files associated
|
If we have old format, load_tmpdir is cleaned up by the I/O thread
|
||||||
// with the server id that has just started
|
|
||||||
|
TODO: cleanup_load_tmpdir() needs to remove only the files associated
|
||||||
|
with the server id that has just started
|
||||||
|
*/
|
||||||
if (!rli->mi->old_format)
|
if (!rli->mi->old_format)
|
||||||
cleanup_load_tmpdir();
|
cleanup_load_tmpdir();
|
||||||
return Log_event::exec_event(rli);
|
return Log_event::exec_event(rli);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Stop_log_event::exec_event(struct st_relay_log_info* rli)
|
int Stop_log_event::exec_event(struct st_relay_log_info* rli)
|
||||||
{
|
{
|
||||||
// do not clean up immediately after rotate event
|
// do not clean up immediately after rotate event
|
||||||
if (rli->master_log_pos > 4)
|
if (rli->master_log_pos > BIN_LOG_HEADER_SIZE)
|
||||||
{
|
{
|
||||||
close_temporary_tables(thd);
|
close_temporary_tables(thd);
|
||||||
cleanup_load_tmpdir();
|
cleanup_load_tmpdir();
|
||||||
|
|
@ -1809,7 +1831,10 @@ int Rotate_log_event::exec_event(struct st_relay_log_info* rli)
|
||||||
&& mysql_bin_log.is_open());
|
&& mysql_bin_log.is_open());
|
||||||
rotate_binlog = (*log_name && write_slave_event);
|
rotate_binlog = (*log_name && write_slave_event);
|
||||||
if (ident_len >= sizeof(rli->master_log_name))
|
if (ident_len >= sizeof(rli->master_log_name))
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&rli->data_lock);
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
memcpy(log_name, new_log_ident,ident_len);
|
memcpy(log_name, new_log_ident,ident_len);
|
||||||
log_name[ident_len] = 0;
|
log_name[ident_len] = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1907,7 +1932,8 @@ int Create_file_log_event::exec_event(struct st_relay_log_info* rli)
|
||||||
}
|
}
|
||||||
if (mysql_bin_log.is_open())
|
if (mysql_bin_log.is_open())
|
||||||
mysql_bin_log.write(this);
|
mysql_bin_log.write(this);
|
||||||
error=0;
|
error=0; // Everything is ok
|
||||||
|
|
||||||
err:
|
err:
|
||||||
if (error)
|
if (error)
|
||||||
end_io_cache(&file);
|
end_io_cache(&file);
|
||||||
|
|
@ -1919,8 +1945,7 @@ err:
|
||||||
int Delete_file_log_event::exec_event(struct st_relay_log_info* rli)
|
int Delete_file_log_event::exec_event(struct st_relay_log_info* rli)
|
||||||
{
|
{
|
||||||
char fname[FN_REFLEN+10];
|
char fname[FN_REFLEN+10];
|
||||||
char* p;
|
char *p= slave_load_file_stem(fname, file_id, server_id);
|
||||||
p = slave_load_file_stem(fname, file_id, server_id);
|
|
||||||
memcpy(p, ".data", 6);
|
memcpy(p, ".data", 6);
|
||||||
(void) my_delete(fname, MYF(MY_WME));
|
(void) my_delete(fname, MYF(MY_WME));
|
||||||
memcpy(p, ".info", 6);
|
memcpy(p, ".info", 6);
|
||||||
|
|
@ -1933,10 +1958,10 @@ int Delete_file_log_event::exec_event(struct st_relay_log_info* rli)
|
||||||
int Append_block_log_event::exec_event(struct st_relay_log_info* rli)
|
int Append_block_log_event::exec_event(struct st_relay_log_info* rli)
|
||||||
{
|
{
|
||||||
char fname[FN_REFLEN+10];
|
char fname[FN_REFLEN+10];
|
||||||
char* p;
|
char *p= slave_load_file_stem(fname, file_id, server_id);
|
||||||
int fd = -1;
|
int fd;
|
||||||
int error = 1;
|
int error = 1;
|
||||||
p = slave_load_file_stem(fname, file_id, server_id);
|
|
||||||
memcpy(p, ".data", 6);
|
memcpy(p, ".data", 6);
|
||||||
if ((fd = my_open(fname, O_WRONLY|O_APPEND|O_BINARY, MYF(MY_WME))) < 0)
|
if ((fd = my_open(fname, O_WRONLY|O_APPEND|O_BINARY, MYF(MY_WME))) < 0)
|
||||||
{
|
{
|
||||||
|
|
@ -1951,6 +1976,7 @@ int Append_block_log_event::exec_event(struct st_relay_log_info* rli)
|
||||||
if (mysql_bin_log.is_open())
|
if (mysql_bin_log.is_open())
|
||||||
mysql_bin_log.write(this);
|
mysql_bin_log.write(this);
|
||||||
error=0;
|
error=0;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
if (fd >= 0)
|
if (fd >= 0)
|
||||||
my_close(fd, MYF(0));
|
my_close(fd, MYF(0));
|
||||||
|
|
@ -1960,15 +1986,14 @@ err:
|
||||||
int Execute_load_log_event::exec_event(struct st_relay_log_info* rli)
|
int Execute_load_log_event::exec_event(struct st_relay_log_info* rli)
|
||||||
{
|
{
|
||||||
char fname[FN_REFLEN+10];
|
char fname[FN_REFLEN+10];
|
||||||
char* p;
|
char *p= slave_load_file_stem(fname, file_id, server_id);
|
||||||
int fd = -1;
|
int fd;
|
||||||
int error = 1;
|
int error = 1;
|
||||||
ulong save_options;
|
ulong save_options;
|
||||||
IO_CACHE file;
|
IO_CACHE file;
|
||||||
Load_log_event* lev = 0;
|
Load_log_event* lev = 0;
|
||||||
p = slave_load_file_stem(fname, file_id, server_id);
|
|
||||||
memcpy(p, ".info", 6);
|
memcpy(p, ".info", 6);
|
||||||
bzero((char*)&file, sizeof(file));
|
|
||||||
if ((fd = my_open(fname, O_RDONLY|O_BINARY, MYF(MY_WME))) < 0 ||
|
if ((fd = my_open(fname, O_RDONLY|O_BINARY, MYF(MY_WME))) < 0 ||
|
||||||
init_io_cache(&file, fd, IO_SIZE, READ_CACHE, (my_off_t)0, 0,
|
init_io_cache(&file, fd, IO_SIZE, READ_CACHE, (my_off_t)0, 0,
|
||||||
MYF(MY_WME|MY_NABP)))
|
MYF(MY_WME|MY_NABP)))
|
||||||
|
|
@ -1978,8 +2003,8 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli)
|
||||||
}
|
}
|
||||||
if (!(lev = (Load_log_event*)Log_event::read_log_event(&file,
|
if (!(lev = (Load_log_event*)Log_event::read_log_event(&file,
|
||||||
(pthread_mutex_t*)0,
|
(pthread_mutex_t*)0,
|
||||||
(bool)0))
|
(bool)0)) ||
|
||||||
|| lev->get_type_code() != NEW_LOAD_EVENT)
|
lev->get_type_code() != NEW_LOAD_EVENT)
|
||||||
{
|
{
|
||||||
slave_print_error(rli,0, "File '%s' appears corrupted", fname);
|
slave_print_error(rli,0, "File '%s' appears corrupted", fname);
|
||||||
goto err;
|
goto err;
|
||||||
|
|
@ -2006,13 +2031,15 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli)
|
||||||
if (mysql_bin_log.is_open())
|
if (mysql_bin_log.is_open())
|
||||||
mysql_bin_log.write(this);
|
mysql_bin_log.write(this);
|
||||||
error = 0;
|
error = 0;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
delete lev;
|
delete lev;
|
||||||
end_io_cache(&file);
|
|
||||||
if (fd >= 0)
|
if (fd >= 0)
|
||||||
|
{
|
||||||
my_close(fd, MYF(0));
|
my_close(fd, MYF(0));
|
||||||
|
end_io_cache(&file);
|
||||||
|
}
|
||||||
return error ? error : Log_event::exec_event(rli);
|
return error ? error : Log_event::exec_event(rli);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* !MYSQL_CLIENT */
|
||||||
#endif
|
|
||||||
|
|
|
||||||
313
sql/log_event.h
313
sql/log_event.h
|
|
@ -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,7 +36,8 @@
|
||||||
#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
|
/*
|
||||||
|
We could have used SERVER_VERSION_LENGTH, but this introduces an
|
||||||
obscure dependency - if somebody decided to change SERVER_VERSION_LENGTH
|
obscure dependency - if somebody decided to change SERVER_VERSION_LENGTH
|
||||||
this would have broke the replication protocol
|
this would have broke the replication protocol
|
||||||
*/
|
*/
|
||||||
|
|
@ -66,7 +67,6 @@ struct old_sql_ex
|
||||||
|
|
||||||
#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;
|
||||||
|
|
@ -74,37 +74,39 @@ struct sql_ex_info
|
||||||
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()
|
||||||
|
{
|
||||||
|
return (new_format() ?
|
||||||
field_term_len + enclosed_len + line_term_len +
|
field_term_len + enclosed_len + line_term_len +
|
||||||
line_start_len + escaped_len + 6 : 7;}
|
line_start_len + escaped_len + 6 : 7);
|
||||||
|
}
|
||||||
int write_data(IO_CACHE* file);
|
int write_data(IO_CACHE* file);
|
||||||
char* init(char* buf,char* buf_end,bool use_new_format);
|
char* init(char* buf,char* buf_end,bool use_new_format);
|
||||||
bool new_format()
|
bool new_format()
|
||||||
{
|
{
|
||||||
return (cached_new_format != -1) ? cached_new_format :
|
return ((cached_new_format != -1) ? cached_new_format :
|
||||||
(cached_new_format=(field_term_len > 1 ||
|
(cached_new_format=(field_term_len > 1 ||
|
||||||
enclosed_len > 1 ||
|
enclosed_len > 1 ||
|
||||||
line_term_len > 1 || line_start_len > 1 ||
|
line_term_len > 1 || line_start_len > 1 ||
|
||||||
escaped_len > 1));
|
escaped_len > 1)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Binary log consists of events. Each event has a fixed length header,
|
/*
|
||||||
|
Binary log consists of events. Each event has a fixed length header,
|
||||||
followed by possibly variable ( depending on the type of event) length
|
followed by possibly variable ( depending on the type of event) length
|
||||||
data body. The data body consists of an optional fixed length segment
|
data body. The data body consists of an optional fixed length segment
|
||||||
(post-header), and an optional variable length segment. See #defines and
|
(post-header), and an optional variable length segment. See #defines and
|
||||||
comments below for the format specifics
|
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
|
||||||
|
|
@ -192,14 +194,20 @@ 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,
|
||||||
|
INTVAR_EVENT=5, LOAD_EVENT=6, SLAVE_EVENT=7, CREATE_FILE_EVENT=8,
|
||||||
APPEND_BLOCK_EVENT=9, EXEC_LOAD_EVENT=10, DELETE_FILE_EVENT=11,
|
APPEND_BLOCK_EVENT=9, EXEC_LOAD_EVENT=10, DELETE_FILE_EVENT=11,
|
||||||
NEW_LOAD_EVENT=12};
|
NEW_LOAD_EVENT=12
|
||||||
enum Int_event_type { INVALID_INT_EVENT = 0, LAST_INSERT_ID_EVENT = 1, INSERT_ID_EVENT = 2
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
class MYSQL_LOG;
|
class MYSQL_LOG;
|
||||||
|
|
@ -220,15 +228,38 @@ 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;
|
||||||
|
|
||||||
|
Log_event(THD* thd_arg, uint16 flags_arg = 0);
|
||||||
|
// if mutex is 0, the read will proceed without mutex
|
||||||
|
static Log_event* read_log_event(IO_CACHE* file,
|
||||||
|
pthread_mutex_t* log_lock,
|
||||||
|
bool old_format);
|
||||||
|
static int read_log_event(IO_CACHE* file, String* packet,
|
||||||
|
pthread_mutex_t* log_lock);
|
||||||
|
void set_log_pos(MYSQL_LOG* log);
|
||||||
|
virtual void pack_info(String* packet);
|
||||||
|
int net_send(THD* thd, const char* log_name, my_off_t pos);
|
||||||
|
static void init_show_field_list(List<Item>* field_list);
|
||||||
|
virtual int exec_event(struct st_relay_log_info* rli);
|
||||||
|
virtual const char* get_db()
|
||||||
|
{
|
||||||
|
return thd ? thd->db : 0;
|
||||||
|
}
|
||||||
|
#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
|
#endif
|
||||||
|
|
||||||
static void *operator new(size_t size)
|
static void *operator new(size_t size)
|
||||||
{
|
{
|
||||||
return (void*) my_malloc((uint)size, MYF(MY_WME|MY_FAE));
|
return (void*) my_malloc((uint)size, MYF(MY_WME|MY_FAE));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void operator delete(void *ptr, size_t size)
|
static void operator delete(void *ptr, size_t size)
|
||||||
{
|
{
|
||||||
my_free((gptr) ptr, MYF(MY_WME|MY_ALLOW_ZERO_PTR));
|
my_free((gptr) ptr, MYF(MY_WME|MY_ALLOW_ZERO_PTR));
|
||||||
|
|
@ -246,9 +277,6 @@ public:
|
||||||
virtual bool is_valid() = 0;
|
virtual bool is_valid() = 0;
|
||||||
virtual bool get_cache_stmt() { return 0; }
|
virtual bool get_cache_stmt() { return 0; }
|
||||||
Log_event(const char* buf, bool old_format);
|
Log_event(const char* buf, bool old_format);
|
||||||
#ifndef MYSQL_CLIENT
|
|
||||||
Log_event(THD* thd_arg, uint16 flags_arg = 0);
|
|
||||||
#endif
|
|
||||||
virtual ~Log_event() { free_temp_buf();}
|
virtual ~Log_event() { free_temp_buf();}
|
||||||
void register_temp_buf(char* buf) { temp_buf = buf; }
|
void register_temp_buf(char* buf) { temp_buf = buf; }
|
||||||
void free_temp_buf()
|
void free_temp_buf()
|
||||||
|
|
@ -261,40 +289,14 @@ public:
|
||||||
}
|
}
|
||||||
virtual int get_data_size() { return 0;}
|
virtual int get_data_size() { return 0;}
|
||||||
virtual int get_data_body_offset() { return 0; }
|
virtual int get_data_body_offset() { return 0; }
|
||||||
int get_event_len() { return cached_event_len ? cached_event_len :
|
int get_event_len()
|
||||||
(cached_event_len = LOG_EVENT_HEADER_LEN + get_data_size()); }
|
{
|
||||||
#ifdef MYSQL_CLIENT
|
return (cached_event_len ? cached_event_len :
|
||||||
virtual void print(FILE* file, bool short_form = 0, char* last_db = 0) = 0;
|
(cached_event_len = LOG_EVENT_HEADER_LEN + get_data_size()));
|
||||||
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
|
|
||||||
static Log_event* read_log_event(IO_CACHE* file,
|
|
||||||
pthread_mutex_t* log_lock,
|
|
||||||
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,
|
static Log_event* read_log_event(const char* buf, int event_len,
|
||||||
const char **error, bool old_format);
|
const char **error, bool old_format);
|
||||||
const char* get_type_str();
|
const char* get_type_str();
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
|
||||||
static int read_log_event(IO_CACHE* file, String* packet,
|
|
||||||
pthread_mutex_t* log_lock);
|
|
||||||
void set_log_pos(MYSQL_LOG* log);
|
|
||||||
virtual void pack_info(String* packet);
|
|
||||||
int net_send(THD* thd, const char* log_name, my_off_t pos);
|
|
||||||
static void init_show_field_list(List<Item>* field_list);
|
|
||||||
virtual int exec_event(struct st_relay_log_info* rli);
|
|
||||||
virtual const char* get_db()
|
|
||||||
{
|
|
||||||
return thd ? thd->db : 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -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,6 +369,8 @@ 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);
|
||||||
|
#else
|
||||||
|
void print(FILE* file, bool short_form = 0, char* last_db = 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Slave_log_event(const char* buf, int event_len);
|
Slave_log_event(const char* buf, int event_len);
|
||||||
|
|
@ -371,11 +378,7 @@ public:
|
||||||
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)
|
||||||
{}
|
{}
|
||||||
|
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
|
||||||
|
|
||||||
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)
|
||||||
{}
|
{}
|
||||||
|
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
|
||||||
|
|
||||||
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()
|
||||||
|
{
|
||||||
|
return (fake_base ? Load_log_event::get_data_size() :
|
||||||
Load_log_event::get_data_size() +
|
Load_log_event::get_data_size() +
|
||||||
4 + 1 + block_len;}
|
4 + 1 + block_len);
|
||||||
int get_data_body_offset() { return fake_base ? LOAD_EVENT_OVERHEAD:
|
}
|
||||||
LOAD_EVENT_OVERHEAD + CREATE_FILE_HEADER_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:
|
||||||
|
|
@ -620,25 +623,20 @@ public:
|
||||||
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);
|
||||||
|
void pack_info(String* packet);
|
||||||
|
#else
|
||||||
|
void print(FILE* file, bool short_form = 0, char* last_db = 0);
|
||||||
#endif
|
#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 */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -238,8 +238,9 @@ 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;
|
||||||
|
|
@ -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
|
||||||
|
|
@ -1227,9 +1225,9 @@ 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
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -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
|
/*
|
||||||
|
Initialize signal_th and shutdown_th to main_th for default value
|
||||||
as we need to initialize them to something safe. They are used
|
as we need to initialize them to something safe. They are used
|
||||||
when compiled with safemalloc
|
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)
|
||||||
{
|
{
|
||||||
|
/* having ssl_acceptor_fd != 0 signals the use of SSL */
|
||||||
ssl_acceptor_fd= new_VioSSLAcceptorFd(opt_ssl_key, opt_ssl_cert,
|
ssl_acceptor_fd= new_VioSSLAcceptorFd(opt_ssl_key, opt_ssl_cert,
|
||||||
opt_ssl_ca, opt_ssl_capath,
|
opt_ssl_ca, opt_ssl_capath,
|
||||||
opt_ssl_cipher);
|
opt_ssl_cipher);
|
||||||
DBUG_PRINT("info",("ssl_acceptor_fd: %p", ssl_acceptor_fd));
|
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.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
|
/****************************************************************************
|
||||||
/* ------------------------------------------------------------------------
|
Main and thread entry function for Win32
|
||||||
main and thread entry function for Win32
|
|
||||||
(all this is needed only to run mysqld as a service on WinNT)
|
(all this is needed only to run mysqld as a service on WinNT)
|
||||||
-------------------------------------------------------------------------- */
|
****************************************************************************/
|
||||||
|
|
||||||
|
#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
|
||||||
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);
|
||||||
|
|
@ -2203,7 +2203,7 @@ int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
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))
|
||||||
{
|
{
|
||||||
|
|
@ -4045,15 +4047,16 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
||||||
case (int)OPT_REPLICATE_REWRITE_DB:
|
case (int)OPT_REPLICATE_REWRITE_DB:
|
||||||
{
|
{
|
||||||
char* key = argument,*p, *val;
|
char* key = argument,*p, *val;
|
||||||
p = strstr(argument, "->");
|
|
||||||
if (!p)
|
if (!(p= strstr(argument, "->")))
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Bad syntax in replicate-rewrite-db - missing '->'!\n");
|
"Bad syntax in replicate-rewrite-db - missing '->'!\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
val= p--;
|
val= p--;
|
||||||
while(isspace(*p) && p > argument) *p-- = 0;
|
while (isspace(*p) && p > argument)
|
||||||
|
*p-- = 0;
|
||||||
if (p == argument)
|
if (p == argument)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
|
|
@ -4062,7 +4065,8 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
||||||
}
|
}
|
||||||
*val= 0;
|
*val= 0;
|
||||||
val+= 2;
|
val+= 2;
|
||||||
while(*val && isspace(*val)) *val++;
|
while (*val && isspace(*val))
|
||||||
|
*val++;
|
||||||
if (!*val)
|
if (!*val)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
|
|
@ -4637,7 +4641,7 @@ skipp: ;
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
** Instantiate templates
|
Instantiate templates
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
|
|
||||||
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,27 +117,32 @@ 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 (thd->server_id)
|
||||||
{
|
{
|
||||||
if (need_mutex)
|
if (need_mutex)
|
||||||
pthread_mutex_lock(&LOCK_slave_list);
|
pthread_mutex_lock(&LOCK_slave_list);
|
||||||
if (thd->server_id)
|
|
||||||
{
|
|
||||||
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)
|
if (need_mutex)
|
||||||
pthread_mutex_unlock(&LOCK_slave_list);
|
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)
|
||||||
{
|
{
|
||||||
|
|
@ -201,14 +212,13 @@ 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;
|
||||||
|
|
@ -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 */
|
||||||
|
|
@ -838,8 +853,8 @@ 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);
|
||||||
|
|
|
||||||
10
sql/slave.cc
10
sql/slave.cc
|
|
@ -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;
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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,7 +269,8 @@ 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 ?
|
||||||
|
(uint) strlen(user.host.hostname) : 0);
|
||||||
if (table->fields >= 23)
|
if (table->fields >= 23)
|
||||||
{
|
{
|
||||||
/* Table has new MySQL usage limits */
|
/* Table has new MySQL usage limits */
|
||||||
|
|
@ -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");
|
||||||
|
|
@ -2703,14 +2705,14 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
|
|
|
||||||
|
|
@ -1188,15 +1188,17 @@ void Query_cache::pack(ulong join_limit, uint iteration_limit)
|
||||||
|
|
||||||
void Query_cache::destroy()
|
void Query_cache::destroy()
|
||||||
{
|
{
|
||||||
|
DBUG_ENTER("Query_cache::destroy");
|
||||||
if (!initialized)
|
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);
|
free_cache(1);
|
||||||
pthread_mutex_destroy(&structure_guard_mutex);
|
pthread_mutex_destroy(&structure_guard_mutex);
|
||||||
initialized = 0;
|
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);
|
||||||
|
|
||||||
|
|
@ -2911,7 +2915,6 @@ 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"));
|
||||||
|
|
@ -3001,7 +3004,6 @@ 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"));
|
||||||
|
|
|
||||||
|
|
@ -286,6 +286,7 @@ 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)");
|
||||||
|
|
@ -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 =
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 *
|
||||||
|
|
@ -103,11 +105,15 @@ typedef struct st_lex_master_info
|
||||||
} 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;
|
||||||
|
|
|
||||||
|
|
@ -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,7 +537,8 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, String &field_term,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* init_io_cache() will not initialize read_function member
|
/*
|
||||||
|
init_io_cache() will not initialize read_function member
|
||||||
if the cache is READ_NET. The reason is explained in
|
if the cache is READ_NET. The reason is explained in
|
||||||
mysys/mf_iocache.c. So we work around the problem with a
|
mysys/mf_iocache.c. So we work around the problem with a
|
||||||
manual assignment
|
manual assignment
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 */
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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,9 +4872,9 @@ 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 */
|
||||||
|
|
@ -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,
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -872,6 +872,7 @@ 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)
|
||||||
{
|
{
|
||||||
|
|
@ -915,13 +916,16 @@ 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)
|
||||||
{
|
{
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
@ -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));
|
||||||
|
|
@ -475,8 +481,10 @@ multi_update::prepare(List<Item> &values)
|
||||||
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)
|
||||||
|
|
@ -645,7 +654,7 @@ void multi_update::send_error(uint errcode,const char *err)
|
||||||
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 ... */
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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,7 +91,8 @@
|
||||||
|
|
||||||
#define MAX_RETRY_COUNT 100
|
#define MAX_RETRY_COUNT 100
|
||||||
|
|
||||||
/* Variable naming convention - if starts with manager_, either is set
|
/*
|
||||||
|
Variable naming convention - if starts with manager_, either is set
|
||||||
directly by the user, or used closely in ocnjunction with a variable
|
directly by the user, or used closely in ocnjunction with a variable
|
||||||
set by the user
|
set by the user
|
||||||
*/
|
*/
|
||||||
|
|
@ -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.
|
||||||
|
To solve this, we fork off a launcher at the very start
|
||||||
and communicate with it through a pipe
|
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,12 +234,13 @@ 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) \
|
||||||
|
static int com(struct manager_thd *thd,\
|
||||||
|
char *args_start __attribute__((unused)),\
|
||||||
char* args_end __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);
|
||||||
HANDLE_NOARG_DECL(handle_help);
|
HANDLE_NOARG_DECL(handle_help);
|
||||||
|
|
@ -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);
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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));
|
||||||
|
|
@ -1348,7 +1348,8 @@ static int init_server()
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1476,8 +1480,7 @@ static uint tokenize_args(char* arg_start,char** arg_end)
|
||||||
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,15 +1525,15 @@ 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,8 +1801,7 @@ 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:
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
@ -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,13 +164,14 @@ 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 *
|
||||||
|
new_VioSSLConnectorFd(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,
|
||||||
|
|
@ -177,7 +185,11 @@ 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));
|
|
||||||
|
if (!(ptr=((struct st_VioSSLConnectorFd*)
|
||||||
|
my_malloc(sizeof(struct st_VioSSLConnectorFd),MYF(0)))))
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
ptr->ssl_context_= 0;
|
ptr->ssl_context_= 0;
|
||||||
ptr->ssl_method_= 0;
|
ptr->ssl_method_= 0;
|
||||||
/* FIXME: constants! */
|
/* FIXME: constants! */
|
||||||
|
|
@ -204,8 +216,8 @@ 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)
|
||||||
{
|
{
|
||||||
|
|
@ -255,7 +267,6 @@ new_VioSSLAcceptorFd(const char* key_file,
|
||||||
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,7 +275,8 @@ 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! */
|
||||||
|
|
@ -296,21 +308,17 @@ new_VioSSLAcceptorFd(const char* key_file,
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
|
@ -332,8 +340,8 @@ 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));
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue