This commit is contained in:
monty@narttu.mysql.fi 2000-11-16 00:24:11 +02:00
commit b689a1a752
56 changed files with 1946 additions and 1506 deletions

View File

@ -1,8 +1,9 @@
jcole@tetra.bedford.progress.com jcole@tetra.bedford.progress.com
jcole@tetra.spaceapes.com jcole@tetra.spaceapes.com
monty@narttu.mysql.fi
mwagner@evoq.home.mwagner.org
sasha@laptop.slkc.uswest.net sasha@laptop.slkc.uswest.net
sasha@mysql.sashanet.com sasha@mysql.sashanet.com
sasha@work.mysql.com sasha@work.mysql.com
serg@serg.mysql.com serg@serg.mysql.com
yfaktoro@nslinuxw2.bedford.progress.com yfaktoro@nslinuxw2.bedford.progress.com
mwagner@evoq.home.mwagner.org

File diff suppressed because it is too large Load Diff

View File

@ -115,7 +115,7 @@ static bool info_flag=0,ignore_errors=0,wait_flag=0,quick=0,
opt_compress=0, opt_compress=0,
vertical=0,skip_line_numbers=0,skip_column_names=0,opt_html=0, vertical=0,skip_line_numbers=0,skip_column_names=0,opt_html=0,
no_named_cmds=1; // we want this to be the default no_named_cmds=1; // we want this to be the default
static uint verbose=0,opt_silent=0,opt_mysql_port=0; static uint verbose=0,opt_silent=0,opt_mysql_port=0,opt_connect_timeout=0;
static my_string opt_mysql_unix_port=0; static my_string opt_mysql_unix_port=0;
static int connect_flag=CLIENT_INTERACTIVE; static int connect_flag=CLIENT_INTERACTIVE;
static char *current_host,*current_db,*current_user=0,*opt_password=0, static char *current_host,*current_db,*current_user=0,*opt_password=0,
@ -334,7 +334,7 @@ sig_handler mysql_end(int sig)
exit(status.exit_status); exit(status.exit_status);
} }
enum options {OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET} ; enum options {OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET, OPT_TIMEOUT} ;
static struct option long_options[] = static struct option long_options[] =
@ -374,6 +374,7 @@ static struct option long_options[] =
{"socket", required_argument, 0, 'S'}, {"socket", required_argument, 0, 'S'},
#include "sslopt-longopts.h" #include "sslopt-longopts.h"
{"table", no_argument, 0, 't'}, {"table", no_argument, 0, 't'},
{"timeout", required_argument, 0, OPT_TIMEOUT},
#ifndef DONT_ALLOW_USER_CHANGE #ifndef DONT_ALLOW_USER_CHANGE
{"user", required_argument, 0, 'u'}, {"user", required_argument, 0, 'u'},
#endif #endif
@ -545,9 +546,12 @@ static int get_options(int argc, char **argv)
case 'p': case 'p':
if (optarg) if (optarg)
{ {
char *start=optarg;
my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR)); my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
opt_password=my_strdup(optarg,MYF(MY_FAE)); opt_password=my_strdup(optarg,MYF(MY_FAE));
while (*optarg) *optarg++= 'x'; // Destroy argument while (*optarg) *optarg++= 'x'; // Destroy argument
if (*start)
start[1]=0;
} }
else else
tty_password=1; tty_password=1;
@ -603,6 +607,9 @@ static int get_options(int argc, char **argv)
opt_mysql_unix_port=my_strdup(MYSQL_NAMEDPIPE,MYF(0)); opt_mysql_unix_port=my_strdup(MYSQL_NAMEDPIPE,MYF(0));
#endif #endif
break; break;
case OPT_TIMEOUT:
opt_connect_timeout=atoi(optarg);
break;
case 'V': usage(1); exit(0); case 'V': usage(1); exit(0);
case 'I': case 'I':
case '?': case '?':
@ -1772,6 +1779,9 @@ sql_real_connect(char *host,char *database,char *user,char *password,
connected= 0; connected= 0;
} }
mysql_init(&mysql); mysql_init(&mysql);
if (opt_connect_timeout)
mysql_options(&mysql,MYSQL_OPT_CONNECT_TIMEOUT,
(char*) &opt_connect_timeout);
if (opt_compress) if (opt_compress)
mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS); mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS);
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL

View File

@ -28,7 +28,7 @@
#include <my_pthread.h> /* because of signal() */ #include <my_pthread.h> /* because of signal() */
#endif #endif
#define ADMIN_VERSION "8.9" #define ADMIN_VERSION "8.11"
#define MAX_MYSQL_VAR 64 #define MAX_MYSQL_VAR 64
#define MAX_TIME_TO_WAIT 3600 /* Wait for shutdown */ #define MAX_TIME_TO_WAIT 3600 /* Wait for shutdown */
#define MAX_TRUNC_LENGTH 3 #define MAX_TRUNC_LENGTH 3
@ -137,7 +137,7 @@ int main(int argc,char *argv[])
{ {
int c, error = 0,option_index=0; int c, error = 0,option_index=0;
MYSQL mysql; MYSQL mysql;
char *host = NULL,*password=0,*user=0,**commands; char *host = NULL,*opt_password=0,*user=0,**commands;
my_bool tty_password=0; my_bool tty_password=0;
MY_INIT(argv[0]); MY_INIT(argv[0]);
mysql_init(&mysql); mysql_init(&mysql);
@ -160,9 +160,12 @@ int main(int argc,char *argv[])
case 'p': case 'p':
if (optarg) if (optarg)
{ {
my_free(password,MYF(MY_ALLOW_ZERO_PTR)); char *start=optarg;
password=my_strdup(optarg,MYF(MY_FAE)); my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
opt_password=my_strdup(optarg,MYF(MY_FAE));
while (*optarg) *optarg++= 'x'; /* Destroy argument */ while (*optarg) *optarg++= 'x'; /* Destroy argument */
if (*start)
start[1]=0; /* Cut length of argument */
} }
else else
tty_password=1; tty_password=1;
@ -243,12 +246,11 @@ int main(int argc,char *argv[])
exit(1); exit(1);
} }
if (tty_password) if (tty_password)
password = get_tty_password(NullS); opt_password = get_tty_password(NullS);
VOID(signal(SIGINT,endprog)); /* Here if abort */ VOID(signal(SIGINT,endprog)); /* Here if abort */
VOID(signal(SIGTERM,endprog)); /* Here if abort */ VOID(signal(SIGTERM,endprog)); /* Here if abort */
mysql_init(&mysql);
if (opt_compress) if (opt_compress)
mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS); mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS);
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
@ -256,7 +258,7 @@ int main(int argc,char *argv[])
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath); opt_ssl_capath);
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
if (sql_connect(&mysql,host,user,password,option_wait)) if (sql_connect(&mysql,host,user,opt_password,option_wait))
error = 1; error = 1;
else else
{ {
@ -269,7 +271,7 @@ int main(int argc,char *argv[])
if (option_wait && !interrupted) if (option_wait && !interrupted)
{ {
mysql_close(&mysql); mysql_close(&mysql);
if (!sql_connect(&mysql,host,user,password,option_wait)) if (!sql_connect(&mysql,host,user,opt_password,option_wait))
continue; /* Retry */ continue; /* Retry */
} }
error=1; error=1;
@ -286,7 +288,7 @@ int main(int argc,char *argv[])
} }
mysql_close(&mysql); mysql_close(&mysql);
} }
my_free(password,MYF(MY_ALLOW_ZERO_PTR)); my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
my_free(user,MYF(MY_ALLOW_ZERO_PTR)); my_free(user,MYF(MY_ALLOW_ZERO_PTR));
free_defaults(argv); free_defaults(argv);
my_end(0); my_end(0);

View File

@ -37,7 +37,7 @@
** Tõnu Samuel <tonu@please.do.not.remove.this.spam.ee> ** Tõnu Samuel <tonu@please.do.not.remove.this.spam.ee>
**/ **/
#define DUMP_VERSION "8.10" #define DUMP_VERSION "8.11"
#include <global.h> #include <global.h>
#include <my_sys.h> #include <my_sys.h>
@ -75,7 +75,7 @@ static my_bool verbose=0,tFlag=0,cFlag=0,dFlag=0,quick=0, extended_insert = 0,
opt_delayed=0,create_options=0,opt_quoted=0,opt_databases=0, opt_delayed=0,create_options=0,opt_quoted=0,opt_databases=0,
opt_alldbs=0,opt_create_db=0,opt_first_slave=0; opt_alldbs=0,opt_create_db=0,opt_first_slave=0;
static MYSQL mysql_connection,*sock=0; static MYSQL mysql_connection,*sock=0;
static char insert_pat[12 * 1024],*password=0,*current_user=0, static char insert_pat[12 * 1024],*opt_password=0,*current_user=0,
*current_host=0,*path=0,*fields_terminated=0, *current_host=0,*path=0,*fields_terminated=0,
*lines_terminated=0, *enclosed=0, *opt_enclosed=0, *escaped=0, *lines_terminated=0, *enclosed=0, *opt_enclosed=0, *escaped=0,
*where=0, *default_charset; *where=0, *default_charset;
@ -333,9 +333,12 @@ static int get_options(int *argc,char ***argv)
case 'p': case 'p':
if (optarg) if (optarg)
{ {
my_free(password,MYF(MY_ALLOW_ZERO_PTR)); char *start=optarg;
password=my_strdup(optarg,MYF(MY_FAE)); my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
while (*optarg) *optarg++= 'x'; /* Destroy argument */ opt_password=my_strdup(optarg,MYF(MY_FAE));
while (*optarg) *optarg++= 'x'; /* Destroy argument */
if (*start)
start[1]=0; /* Cut length of argument */
} }
else else
tty_password=1; tty_password=1;
@ -459,7 +462,7 @@ static int get_options(int *argc,char ***argv)
return 1; return 1;
} }
if (tty_password) if (tty_password)
password=get_tty_password(NullS); opt_password=get_tty_password(NullS);
return(0); return(0);
} /* get_options */ } /* get_options */
@ -596,7 +599,6 @@ static uint getTableStructure(char *table, char* db)
sprintf(insert_pat,"SET OPTION SQL_QUOTE_SHOW_CREATE=%d", opt_quoted); sprintf(insert_pat,"SET OPTION SQL_QUOTE_SHOW_CREATE=%d", opt_quoted);
table_name=quote_name(table,table_buff); table_name=quote_name(table,table_buff);
if (mysql_query(sock,insert_pat)) if (mysql_query(sock,insert_pat))
{ {
/* using SHOW CREATE statement */ /* using SHOW CREATE statement */
@ -1318,7 +1320,7 @@ int main(int argc, char **argv)
my_end(0); my_end(0);
exit(EX_USAGE); exit(EX_USAGE);
} }
if (dbConnect(current_host, current_user, password)) if (dbConnect(current_host, current_user, opt_password))
exit(EX_MYSQLERR); exit(EX_MYSQLERR);
if (!path) if (!path)
write_heder(stdout, *argv); write_heder(stdout, *argv);
@ -1358,7 +1360,7 @@ int main(int argc, char **argv)
} }
dbDisconnect(current_host); dbDisconnect(current_host);
puts(""); puts("");
my_free(password, MYF(MY_ALLOW_ZERO_PTR)); my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
if (extended_insert) if (extended_insert)
dynstr_free(&extended_row); dynstr_free(&extended_row);
my_end(0); my_end(0);

View File

@ -25,7 +25,7 @@
** * * ** * *
** ************************* ** *************************
*/ */
#define IMPORT_VERSION "2.4" #define IMPORT_VERSION "2.6"
#include <global.h> #include <global.h>
#include <my_sys.h> #include <my_sys.h>
@ -45,7 +45,7 @@ static my_bool verbose=0,lock_tables=0,ignore_errors=0,delete=0,
replace=0,silent=0,ignore=0,opt_compress=0,opt_local_file=0; replace=0,silent=0,ignore=0,opt_compress=0,opt_local_file=0;
static MYSQL mysql_connection; static MYSQL mysql_connection;
static char *password=0, *current_user=0, static char *opt_password=0, *current_user=0,
*current_host=0, *current_db=0, *fields_terminated=0, *current_host=0, *current_db=0, *fields_terminated=0,
*lines_terminated=0, *enclosed=0, *opt_enclosed=0, *lines_terminated=0, *enclosed=0, *opt_enclosed=0,
*escaped=0, opt_low_priority=0, *opt_columns=0; *escaped=0, opt_low_priority=0, *opt_columns=0;
@ -125,7 +125,7 @@ file. The SQL command 'LOAD DATA INFILE' is used to import the rows.\n");
Give the column names in a comma separated list.\n\ Give the column names in a comma separated list.\n\
This is same as giving columns to LOAD DATA INFILE.\n\ This is same as giving columns to LOAD DATA INFILE.\n\
-C, --compress Use compression in server/client protocol\n\ -C, --compress Use compression in server/client protocol\n\
-d, --delete Deletes first all rows from table.\n\ -d, --delete First delete all rows from table.\n\
-f, --force Continue even if we get an sql-error.\n\ -f, --force Continue even if we get an sql-error.\n\
-h, --host=... Connect to host.\n\ -h, --host=... Connect to host.\n\
-i, --ignore If duplicate unique key was found, keep old row.\n\ -i, --ignore If duplicate unique key was found, keep old row.\n\
@ -202,9 +202,12 @@ static int get_options(int *argc, char ***argv)
case 'p': case 'p':
if (optarg) if (optarg)
{ {
my_free(password,MYF(MY_ALLOW_ZERO_PTR)); char *start=optarg;
password= my_strdup(optarg,MYF(MY_FAE)); my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
opt_password=my_strdup(optarg,MYF(MY_FAE));
while (*optarg) *optarg++= 'x'; /* Destroy argument */ while (*optarg) *optarg++= 'x'; /* Destroy argument */
if (*start)
start[1]=0; /* Cut length of argument */
} }
else else
tty_password= 1; tty_password= 1;
@ -276,7 +279,7 @@ static int get_options(int *argc, char ***argv)
current_db= *((*argv)++); current_db= *((*argv)++);
(*argc)--; (*argc)--;
if (tty_password) if (tty_password)
password=get_tty_password(NullS); opt_password=get_tty_password(NullS);
return(0); return(0);
} }
@ -504,7 +507,7 @@ int main(int argc, char **argv)
argv_to_free= argv; argv_to_free= argv;
if (get_options(&argc, &argv)) if (get_options(&argc, &argv))
return(1); return(1);
if (!(sock= db_connect(current_host,current_db,current_user,password))) if (!(sock= db_connect(current_host,current_db,current_user,opt_password)))
return(1); /* purecov: deadcode */ return(1); /* purecov: deadcode */
if (lock_tables) if (lock_tables)
lock_table(sock, argc, argv); lock_table(sock, argc, argv);
@ -513,7 +516,7 @@ int main(int argc, char **argv)
if (exitcode == 0) if (exitcode == 0)
exitcode = error; exitcode = error;
db_disconnect(current_host, sock); db_disconnect(current_host, sock);
my_free(password,MYF(MY_ALLOW_ZERO_PTR)); my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
free_defaults(argv_to_free); free_defaults(argv_to_free);
my_end(0); my_end(0);
return(exitcode); return(exitcode);

View File

@ -28,7 +28,7 @@
#include <stdarg.h> #include <stdarg.h>
#include <getopt.h> #include <getopt.h>
static my_string host=0,password=0,user=0; static my_string host=0,opt_password=0,user=0;
static my_bool opt_show_keys=0,opt_compress=0,opt_status=0; static my_bool opt_show_keys=0,opt_compress=0,opt_status=0;
static void get_options(int *argc,char ***argv); static void get_options(int *argc,char ***argv);
@ -88,15 +88,13 @@ int main(int argc, char **argv)
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath); opt_ssl_capath);
#endif #endif
if (!(mysql_real_connect(&mysql,host,user,password, if (!(mysql_real_connect(&mysql,host,user,opt_password,
argv[0],opt_mysql_port,opt_mysql_unix_port, argv[0],opt_mysql_port,opt_mysql_unix_port,
0))) 0)))
{ {
fprintf(stderr,"%s: %s\n",my_progname,mysql_error(&mysql)); fprintf(stderr,"%s: %s\n",my_progname,mysql_error(&mysql));
exit(1); exit(1);
} }
/* if (!(mysql_connect(&mysql,host,user,password))) */
switch (argc) switch (argc)
{ {
@ -111,11 +109,12 @@ int main(int argc, char **argv)
if (opt_status && ! wild) if (opt_status && ! wild)
error=list_table_status(&mysql,argv[0],argv[1]); error=list_table_status(&mysql,argv[0],argv[1]);
else else
error=list_fields(&mysql,argv[0],argv[1],wild); break; error=list_fields(&mysql,argv[0],argv[1],wild);
break;
} }
mysql_close(&mysql); /* Close & free connection */ mysql_close(&mysql); /* Close & free connection */
if (password) if (opt_password)
my_free(password,MYF(0)); my_free(opt_password,MYF(0));
my_end(0); my_end(0);
exit(error ? 1 : 0); exit(error ? 1 : 0);
return 0; /* No compiler warnings */ return 0; /* No compiler warnings */
@ -223,9 +222,12 @@ get_options(int *argc,char ***argv)
case 'p': case 'p':
if (optarg) if (optarg)
{ {
my_free(password,MYF(MY_ALLOW_ZERO_PTR)); char *start=optarg;
password=my_strdup(optarg,MYF(MY_FAE)); my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
opt_password=my_strdup(optarg,MYF(MY_FAE));
while (*optarg) *optarg++= 'x'; /* Destroy argument */ while (*optarg) *optarg++= 'x'; /* Destroy argument */
if (*start)
start[1]=0; /* Cut length of argument */
} }
else else
tty_password=1; tty_password=1;
@ -266,7 +268,7 @@ get_options(int *argc,char ***argv)
(*argc)-=optind; (*argc)-=optind;
(*argv)+=optind; (*argv)+=optind;
if (tty_password) if (tty_password)
password=get_tty_password(NullS); opt_password=get_tty_password(NullS);
return; return;
} }

View File

@ -95,17 +95,6 @@ bool String::realloc(uint32 alloc_length)
return FALSE; return FALSE;
} }
#ifdef NOT_NEEDED
bool String::set(long num)
{
if (alloc(14))
return TRUE;
str_length=(uint32) (int10_to_str(num,Ptr,-10)-Ptr);
return FALSE;
}
#endif
bool String::set(longlong num) bool String::set(longlong num)
{ {
if (alloc(21)) if (alloc(21))
@ -274,6 +263,7 @@ bool String::append(const char *s,uint32 arg_length)
return FALSE; return FALSE;
} }
#ifdef TO_BE_REMOVED
bool String::append(FILE* file, uint32 arg_length, myf my_flags) bool String::append(FILE* file, uint32 arg_length, myf my_flags)
{ {
if (realloc(str_length+arg_length)) if (realloc(str_length+arg_length))
@ -286,6 +276,20 @@ bool String::append(FILE* file, uint32 arg_length, myf my_flags)
str_length+=arg_length; str_length+=arg_length;
return FALSE; return FALSE;
} }
#endif
bool String::append(IO_CACHE* file, uint32 arg_length)
{
if (realloc(str_length+arg_length))
return TRUE;
if (my_b_read(file, (byte*) Ptr + str_length, arg_length))
{
shrink(str_length);
return TRUE;
}
str_length+=arg_length;
return FALSE;
}
uint32 String::numchars() uint32 String::numchars()
{ {

View File

@ -100,16 +100,16 @@ public:
bool set(ulonglong num); bool set(ulonglong num);
bool set(double num,uint decimals=2); bool set(double num,uint decimals=2);
inline void free() inline void free()
{
if (alloced)
{ {
if (alloced) alloced=0;
{ Alloced_length=0;
alloced=0; my_free(Ptr,MYF(0));
Alloced_length=0; Ptr=0;
my_free(Ptr,MYF(0)); str_length=0; /* Safety */
Ptr=0;
}
} }
}
inline bool alloc(uint32 arg_length) inline bool alloc(uint32 arg_length)
{ {
if (arg_length < Alloced_length) if (arg_length < Alloced_length)
@ -152,7 +152,7 @@ public:
bool copy(const char *s,uint32 arg_length); // Allocate new string bool copy(const char *s,uint32 arg_length); // Allocate new string
bool append(const String &s); bool append(const String &s);
bool append(const char *s,uint32 arg_length=0); bool append(const char *s,uint32 arg_length=0);
bool append(FILE* file, uint32 arg_length, myf my_flags); bool append(IO_CACHE* file, uint32 arg_length);
int strstr(const String &search,uint32 offset=0); // Returns offset to substring or -1 int strstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
int strrstr(const String &search,uint32 offset=0); // Returns offset to substring or -1 int strrstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
bool replace(uint32 offset,uint32 arg_length,const String &to); bool replace(uint32 offset,uint32 arg_length,const String &to);

View File

@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script.
AC_INIT(sql/mysqld.cc) AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line! # The Docs Makefile.am parses this line!
AM_INIT_AUTOMAKE(mysql, 3.23.27-beta) AM_INIT_AUTOMAKE(mysql, 3.23.28-gamma)
AM_CONFIG_HEADER(config.h) AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10 PROTOCOL_VERSION=10
@ -687,6 +687,8 @@ case $SYSTEM_TYPE in
then then
CFLAGS="$CFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS" CFLAGS="$CFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS"
CXXFLAGS="$CXXFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS" CXXFLAGS="$CXXFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS"
CFLAGS="$CFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE"
CXXFLAGS="$CXXFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE"
MAX_C_OPTIMIZE="-O" MAX_C_OPTIMIZE="-O"
with_named_curses="" with_named_curses=""
fi fi
@ -1235,13 +1237,13 @@ AC_FUNC_UTIME_NULL
AC_FUNC_VPRINTF AC_FUNC_VPRINTF
AC_CHECK_FUNCS(alarm bmove \ AC_CHECK_FUNCS(alarm bmove \
chsize ftruncate rint finite fpsetmask fpresetsticky\ chsize ftruncate rint finite fpsetmask fpresetsticky\
cuserid fcntl fconvert \ cuserid fcntl fconvert poll \
getrusage getpwuid getcwd getrlimit getwd index stpcpy locking longjmp \ getrusage getpwuid getcwd getrlimit getwd index stpcpy locking longjmp \
perror pread realpath rename \ perror pread realpath rename \
socket strnlen madvise mkstemp \ socket strnlen madvise mkstemp \
strtol strtoul strtoull snprintf tempnam thr_setconcurrency \ strtol strtoul strtoull snprintf tempnam thr_setconcurrency \
gethostbyaddr_r gethostbyname_r getpwnam \ gethostbyaddr_r gethostbyname_r getpwnam \
bfill bzero bcmp strstr strpbrk strerror\ bfill bzero bcmp strstr strpbrk strerror \
tell atod memcpy memmove \ tell atod memcpy memmove \
setupterm strcasecmp sighold \ setupterm strcasecmp sighold \
vidattr setupterm lrand48 localtime_r \ vidattr setupterm lrand48 localtime_r \

View File

@ -351,10 +351,9 @@ struct tm *localtime_r(const time_t *clock, struct tm *res);
#define pthread_kill(A,B) pthread_dummy(0) #define pthread_kill(A,B) pthread_dummy(0)
#define pthread_condattr_init(A) pthread_dummy(0) #define pthread_condattr_init(A) pthread_dummy(0)
#define pthread_condattr_destroy(A) pthread_dummy(0) #define pthread_condattr_destroy(A) pthread_dummy(0)
#define pthread_cond_init( A, B ) pthread_cond_init( (A), 0 )
#define pthread_signal(A,B) pthread_dummy(0) #define pthread_signal(A,B) pthread_dummy(0)
#undef pthread_detach_this_thread #undef pthread_detach_this_thread
#define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(&tmp); } #define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(tmp); }
#undef sigset #undef sigset
#define sigset(A,B) pthread_signal((A),(void (*)(int)) (B)) #define sigset(A,B) pthread_signal((A),(void (*)(int)) (B))
#endif #endif

View File

@ -59,6 +59,7 @@ extern int NEAR my_errno; /* Last error in mysys */
#define MY_WME 16 /* Write message on error */ #define MY_WME 16 /* Write message on error */
#define MY_WAIT_IF_FULL 32 /* Wait and try again if disk full error */ #define MY_WAIT_IF_FULL 32 /* Wait and try again if disk full error */
#define MY_RAID 64 /* Support for RAID (not the "Johnson&Johnson"-s one ;) */ #define MY_RAID 64 /* Support for RAID (not the "Johnson&Johnson"-s one ;) */
#define MY_DONT_CHECK_FILESIZE 128 /* Option to init_io_cache() */
#define MY_LINK_WARNING 32 /* my_redel() gives warning if links */ #define MY_LINK_WARNING 32 /* my_redel() gives warning if links */
#define MY_COPYTIME 64 /* my_redel() copys time */ #define MY_COPYTIME 64 /* my_redel() copys time */
#define MY_HOLD_ORIGINAL_MODES 128 /* my_copy() holds to file modes */ #define MY_HOLD_ORIGINAL_MODES 128 /* my_copy() holds to file modes */
@ -506,6 +507,10 @@ extern int my_block_write(IO_CACHE *info, const byte *Buffer,
uint Count, my_off_t pos); uint Count, my_off_t pos);
extern int flush_io_cache(IO_CACHE *info); extern int flush_io_cache(IO_CACHE *info);
extern int end_io_cache(IO_CACHE *info); extern int end_io_cache(IO_CACHE *info);
extern uint my_b_fill(IO_CACHE *info);
extern void my_b_seek(IO_CACHE *info,my_off_t pos);
extern uint my_b_gets(IO_CACHE *info, char *to, uint max_length);
extern uint my_b_printf(IO_CACHE *info, const char* fmt, ...);
extern my_bool open_cached_file(IO_CACHE *cache,const char *dir, extern my_bool open_cached_file(IO_CACHE *cache,const char *dir,
const char *prefix, uint cache_size, const char *prefix, uint cache_size,
myf cache_myflags); myf cache_myflags);

View File

@ -108,6 +108,9 @@ my_bool vio_peer_addr(Vio * vio, char *buf);
void vio_in_addr(Vio *vio, struct in_addr *in); void vio_in_addr(Vio *vio, struct in_addr *in);
/* Return 1 if there is data to be read */
my_bool vio_poll_read(Vio *vio,uint timeout);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -64,6 +64,12 @@ my_string mysql_unix_port=0;
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_LOCAL_FILES | CLIENT_TRANSACTIONS) #define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_LOCAL_FILES | CLIENT_TRANSACTIONS)
#ifdef __WIN__
#define CONNECT_TIMEOUT 20
#else
#define CONNECT_TIMEOUT 0
#endif
#if defined(MSDOS) || defined(__WIN__) #if defined(MSDOS) || defined(__WIN__)
#define ERRNO WSAGetLastError() #define ERRNO WSAGetLastError()
#define perror(A) #define perror(A)
@ -113,7 +119,7 @@ static ulong mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to,
*****************************************************************************/ *****************************************************************************/
static int connect2(my_socket s, const struct sockaddr *name, uint namelen, static int connect2(my_socket s, const struct sockaddr *name, uint namelen,
uint to) uint timeout)
{ {
#if defined(__WIN__) #if defined(__WIN__)
return connect(s, (struct sockaddr*) name, namelen); return connect(s, (struct sockaddr*) name, namelen);
@ -128,7 +134,7 @@ static int connect2(my_socket s, const struct sockaddr *name, uint namelen,
* exactly like the normal connect() call does. * exactly like the normal connect() call does.
*/ */
if (to == 0) if (timeout == 0)
return connect(s, (struct sockaddr*) name, namelen); return connect(s, (struct sockaddr*) name, namelen);
flags = fcntl(s, F_GETFL, 0); /* Set socket to not block */ flags = fcntl(s, F_GETFL, 0); /* Set socket to not block */
@ -175,13 +181,13 @@ static int connect2(my_socket s, const struct sockaddr *name, uint namelen,
start_time = time(NULL); start_time = time(NULL);
for (;;) for (;;)
{ {
tv.tv_sec = (long) to; tv.tv_sec = (long) timeout;
tv.tv_usec = 0; tv.tv_usec = 0;
if ((res = select(s+1, NULL, &sfds, NULL, &tv)) >= 0) if ((res = select(s+1, NULL, &sfds, NULL, &tv)) >= 0)
break; break;
now_time=time(NULL); now_time=time(NULL);
to-= (uint) (now_time - start_time); timeout-= (uint) (now_time - start_time);
if (errno != EINTR || (int) to <= 0) if (errno != EINTR || (int) timeout <= 0)
return -1; return -1;
} }
@ -195,7 +201,7 @@ static int connect2(my_socket s, const struct sockaddr *name, uint namelen,
return(-1); return(-1);
if (s_err) if (s_err)
{ /* getsockopt() could suceed */ { /* getsockopt could succeed */
errno = s_err; errno = s_err;
return(-1); /* but return an error... */ return(-1); /* but return an error... */
} }
@ -1001,9 +1007,7 @@ mysql_init(MYSQL *mysql)
} }
else else
bzero((char*) (mysql),sizeof(*(mysql))); bzero((char*) (mysql),sizeof(*(mysql)));
#ifdef __WIN__ mysql->options.connect_timeout=CONNECT_TIMEOUT;
mysql->options.connect_timeout=20;
#endif
#if defined(SIGPIPE) && defined(THREAD) #if defined(SIGPIPE) && defined(THREAD)
if (!((mysql)->client_flag & CLIENT_IGNORE_SIGPIPE)) if (!((mysql)->client_flag & CLIENT_IGNORE_SIGPIPE))
(void) signal(SIGPIPE,pipe_sig_handler); (void) signal(SIGPIPE,pipe_sig_handler);
@ -1140,7 +1144,8 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
const char *passwd, const char *db, const char *passwd, const char *db,
uint port, const char *unix_socket,uint client_flag) uint port, const char *unix_socket,uint client_flag)
{ {
char buff[100],charset_name_buff[16],*end,*host_info, *charset_name; char buff[NAME_LEN+100],charset_name_buff[16],*end,*host_info,
*charset_name;
my_socket sock; my_socket sock;
uint32 ip_addr; uint32 ip_addr;
struct sockaddr_in sock_addr; struct sockaddr_in sock_addr;
@ -1342,6 +1347,13 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
/* Get version info */ /* Get version info */
mysql->protocol_version= PROTOCOL_VERSION; /* Assume this */ mysql->protocol_version= PROTOCOL_VERSION; /* Assume this */
if (mysql->options.connect_timeout &&
vio_poll_read(net->vio, mysql->options.connect_timeout))
{
net->last_errno= CR_SERVER_LOST;
strmov(net->last_error,ER(net->last_errno));
goto error;
}
if ((pkt_length=net_safe_read(mysql)) == packet_error) if ((pkt_length=net_safe_read(mysql)) == packet_error)
goto error; goto error;
@ -1497,7 +1509,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
int3store(buff+2,max_allowed_packet); int3store(buff+2,max_allowed_packet);
if (user && user[0]) if (user && user[0])
strmake(buff+5,user,32); strmake(buff+5,user,32); /* Max user name */
else else
read_user_name((char*) buff+5); read_user_name((char*) buff+5);
#ifdef _CUSTOMCONFIG_ #ifdef _CUSTOMCONFIG_
@ -1508,7 +1520,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
(my_bool) (mysql->protocol_version == 9)); (my_bool) (mysql->protocol_version == 9));
if (db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB)) if (db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB))
{ {
end=strmov(end+1,db); end=strmake(end+1,db,NAME_LEN);
mysql->db=my_strdup(db,MYF(MY_WME)); mysql->db=my_strdup(db,MYF(MY_WME));
db=0; db=0;
} }

View File

@ -32,6 +32,9 @@
#include <my_sys.h> #include <my_sys.h>
#include <my_net.h> #include <my_net.h>
#include <m_string.h> #include <m_string.h>
#ifdef HAVE_POLL
#include <sys/poll.h>
#endif
#if defined(__EMX__) #if defined(__EMX__)
#include <sys/ioctl.h> #include <sys/ioctl.h>
@ -98,7 +101,9 @@ Vio *vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost)
if ((vio = (Vio*) my_malloc(sizeof(*vio),MYF(MY_WME)))) if ((vio = (Vio*) my_malloc(sizeof(*vio),MYF(MY_WME))))
{ {
vio_reset(vio, type, sd, 0, localhost); vio_reset(vio, type, sd, 0, localhost);
sprintf(vio->desc, "socket (%d)", vio->sd); sprintf(vio->desc,
(vio->type == VIO_TYPE_SOCKET ? "socket (%d)" : "TCP/IP (%d)"),
vio->sd);
#if !defined(___WIN__) && !defined(__EMX__) #if !defined(___WIN__) && !defined(__EMX__)
#if !defined(NO_FCNTL_NONBLOCK) #if !defined(NO_FCNTL_NONBLOCK)
vio->fcntl_mode = fcntl(sd, F_GETFL); vio->fcntl_mode = fcntl(sd, F_GETFL);
@ -261,7 +266,7 @@ vio_is_blocking(Vio * vio)
} }
int vio_fastsend(Vio * vio, my_bool onoff) int vio_fastsend(Vio * vio __attribute__((unused)), my_bool onoff)
{ {
int r=0; int r=0;
DBUG_ENTER("vio_fastsend"); DBUG_ENTER("vio_fastsend");
@ -322,7 +327,7 @@ int vio_close(Vio * vio)
if (vio->type == VIO_TYPE_NAMEDPIPE) if (vio->type == VIO_TYPE_NAMEDPIPE)
{ {
#if defined(__NT__) && defined(MYSQL_SERVER) #if defined(__NT__) && defined(MYSQL_SERVER)
CancelIO(vio->hPipe); CancelIo(vio->hPipe);
DisconnectNamedPipe(vio->hPipe); DisconnectNamedPipe(vio->hPipe);
#endif #endif
r=CloseHandle(vio->hPipe); r=CloseHandle(vio->hPipe);
@ -397,4 +402,26 @@ void vio_in_addr(Vio *vio, struct in_addr *in)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/* Return 0 if there is data to be read */
my_bool vio_poll_read(Vio *vio,uint timeout)
{
#ifndef HAVE_POLL
return 0;
#else
struct pollfd fds;
int res;
DBUG_ENTER("vio_poll");
fds.fd=vio->sd;
fds.events=POLLIN;
fds.revents=0;
if ((res=poll(&fds,1,(int) timeout*1000)) <= 0)
{
DBUG_RETURN(res < 0 ? 0 : 1); /* Don't return 1 on errors */
}
DBUG_RETURN(fds.revents & POLLIN ? 0 : 1);
#endif
}
#endif /* HAVE_VIO */ #endif /* HAVE_VIO */

Binary file not shown.

View File

@ -26,7 +26,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c\
mf_path.c mf_loadpath.c\ mf_path.c mf_loadpath.c\
my_open.c my_create.c my_seek.c my_read.c \ my_open.c my_create.c my_seek.c my_read.c \
my_pread.c my_write.c \ my_pread.c my_write.c \
mf_reccache.c mf_keycache.c \ mf_keycache.c \
mf_iocache.c mf_cache.c mf_tempfile.c \ mf_iocache.c mf_cache.c mf_tempfile.c \
my_lock.c mf_brkhant.c my_alarm.c \ my_lock.c mf_brkhant.c my_alarm.c \
my_malloc.c my_realloc.c my_once.c mulalloc.c \ my_malloc.c my_realloc.c my_once.c mulalloc.c \

View File

@ -374,10 +374,11 @@ my_bool hash_delete(HASH *hash,byte *record)
uint blength,pos2,pos_hashnr,lastpos_hashnr,idx,empty_index; uint blength,pos2,pos_hashnr,lastpos_hashnr,idx,empty_index;
HASH_LINK *data,*lastpos,*gpos,*pos,*pos3,*empty; HASH_LINK *data,*lastpos,*gpos,*pos,*pos3,*empty;
DBUG_ENTER("hash_delete"); DBUG_ENTER("hash_delete");
if (!hash->records)
DBUG_RETURN(1);
blength=hash->blength; blength=hash->blength;
data=dynamic_element(&hash->array,0,HASH_LINK*); data=dynamic_element(&hash->array,0,HASH_LINK*);
/* Search after record with key */ /* Search after record with key */
pos=data+ hash_mask(rec_hashnr(hash,record),blength,hash->records); pos=data+ hash_mask(rec_hashnr(hash,record),blength,hash->records);
gpos = 0; gpos = 0;

View File

@ -74,7 +74,7 @@ my_bool open_cached_file(IO_CACHE *cache, const char* dir, const char *prefix,
} }
my_free(cache->dir, MYF(MY_ALLOW_ZERO_PTR)); my_free(cache->dir, MYF(MY_ALLOW_ZERO_PTR));
my_free(cache->prefix,MYF(MY_ALLOW_ZERO_PTR)); my_free(cache->prefix,MYF(MY_ALLOW_ZERO_PTR));
DBUG_RETURN(0); DBUG_RETURN(1);
} }
/* Create the temporary file */ /* Create the temporary file */
@ -101,10 +101,12 @@ void close_cached_file(IO_CACHE *cache)
DBUG_ENTER("close_cached_file"); DBUG_ENTER("close_cached_file");
if (my_b_inited(cache)) if (my_b_inited(cache))
{ {
File file=cache->file;
cache->file= -1; /* Don't flush data */
(void) end_io_cache(cache); (void) end_io_cache(cache);
if (cache->file >= 0) if (file >= 0)
{ {
(void) my_close(cache->file,MYF(0)); (void) my_close(file,MYF(0));
#ifdef CANT_DELETE_OPEN_FILES #ifdef CANT_DELETE_OPEN_FILES
if (cache->file_name) if (cache->file_name)
{ {

View File

@ -22,10 +22,13 @@
(and get a EOF-error). (and get a EOF-error).
Possibly use of asyncronic io. Possibly use of asyncronic io.
macros for read and writes for faster io. macros for read and writes for faster io.
Used instead of FILE when reading or writing hole files. Used instead of FILE when reading or writing whole files.
This shall make mf_rec_cache obsolite. This will make mf_rec_cache obsolete.
One can change info->pos_in_file to a higer value to skipp bytes in file if One can change info->pos_in_file to a higher value to skip bytes in file if
also info->rc_pos is set to info->rc_end. also info->rc_pos is set to info->rc_end.
If called through open_cached_file(), then the temporary file will
only be created if a write exeeds the file buffer or if one calls
flush_io_cache().
*/ */
#define MAP_TO_USE_RAID #define MAP_TO_USE_RAID
@ -40,7 +43,7 @@ static void my_aiowait(my_aio_result *result);
/* /*
** if cachesize == 0 then use default cachesize (from s-file) ** if cachesize == 0 then use default cachesize (from s-file)
** if file == -1 then real_open_cached_file() will be called to ** if file == -1 then real_open_cached_file() will be called.
** returns 0 if ok ** returns 0 if ok
*/ */
@ -59,17 +62,24 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize,
min_cache=use_async_io ? IO_SIZE*4 : IO_SIZE*2; min_cache=use_async_io ? IO_SIZE*4 : IO_SIZE*2;
if (type == READ_CACHE) if (type == READ_CACHE)
{ /* Assume file isn't growing */ { /* Assume file isn't growing */
my_off_t file_pos,end_of_file; if (cache_myflags & MY_DONT_CHECK_FILESIZE)
if ((file_pos=my_tell(file,MYF(0)) == MY_FILEPOS_ERROR))
DBUG_RETURN(1);
end_of_file=my_seek(file,0L,MY_SEEK_END,MYF(0));
if (end_of_file < seek_offset)
end_of_file=seek_offset;
VOID(my_seek(file,file_pos,MY_SEEK_SET,MYF(0)));
if ((my_off_t) cachesize > end_of_file-seek_offset+IO_SIZE*2-1)
{ {
cachesize=(uint) (end_of_file-seek_offset)+IO_SIZE*2-1; cache_myflags &= ~MY_DONT_CHECK_FILESIZE;
use_async_io=0; /* No nead to use async */ }
else
{
my_off_t file_pos,end_of_file;
if ((file_pos=my_tell(file,MYF(0)) == MY_FILEPOS_ERROR))
DBUG_RETURN(1);
end_of_file=my_seek(file,0L,MY_SEEK_END,MYF(0));
if (end_of_file < seek_offset)
end_of_file=seek_offset;
VOID(my_seek(file,file_pos,MY_SEEK_SET,MYF(0)));
if ((my_off_t) cachesize > end_of_file-seek_offset+IO_SIZE*2-1)
{
cachesize=(uint) (end_of_file-seek_offset)+IO_SIZE*2-1;
use_async_io=0; /* No nead to use async */
}
} }
} }
@ -545,7 +555,6 @@ int my_block_write(register IO_CACHE *info, const byte *Buffer, uint Count,
return error; return error;
} }
/* Flush write cache */ /* Flush write cache */
int flush_io_cache(IO_CACHE *info) int flush_io_cache(IO_CACHE *info)
@ -565,7 +574,9 @@ int flush_io_cache(IO_CACHE *info)
length=(uint) (info->rc_pos - info->buffer); length=(uint) (info->rc_pos - info->buffer);
if (info->seek_not_done) if (info->seek_not_done)
{ /* File touched, do seek */ { /* File touched, do seek */
VOID(my_seek(info->file,info->pos_in_file,MY_SEEK_SET,MYF(0))); if (my_seek(info->file,info->pos_in_file,MY_SEEK_SET,MYF(0)) ==
MY_FILEPOS_ERROR)
DBUG_RETURN((info->error= -1));
info->seek_not_done=0; info->seek_not_done=0;
} }
info->rc_pos=info->buffer; info->rc_pos=info->buffer;

View File

@ -21,74 +21,49 @@
#include <stdarg.h> #include <stdarg.h>
#include <m_ctype.h> #include <m_ctype.h>
int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap)
int my_vsnprintf(char* str, size_t n, const char* fmt, va_list ap)
{ {
uint olen = 0, plen; char *start=to, *end=to+n-1;
const char *tpos;
reg1 char *endpos;
reg2 char * par;
char* ebuff = str;
endpos=ebuff;
tpos = fmt;
while (*tpos) for (; *fmt ; fmt++)
{ {
if (tpos[0] != '%') if (fmt[0] != '%')
{ {
if(olen + 1 >= n) if (to == end) /* End of buffer */
break; break;
*to++= *fmt; /* Copy ordinary char */
*endpos++= *tpos++; /* Copy ordinary char */
olen++;
continue; continue;
} }
if (*++tpos == '%') /* test if %% */ /* Skipp if max size is used (to be compatible with printf) */
while (isdigit(*fmt) || *fmt == '.' || *fmt == '-')
fmt++;
if (*fmt == 's') /* String parameter */
{ {
olen--; reg2 char *par = va_arg(ap, char *);
} uint plen = (uint) strlen(par);
else if ((uint) (end-to) > plen) /* Replace if possible */
{
/* Skipp if max size is used (to be compatible with printf) */
while (isdigit(*tpos) || *tpos == '.' || *tpos == '-')
tpos++;
if (*tpos == 's') /* String parameter */
{ {
par = va_arg(ap, char *); to=strmov(to,par);
plen = (uint) strlen(par); continue;
if (olen + plen < n) /* Replace if possible */
{
endpos=strmov(endpos,par);
tpos++;
olen+=plen;
continue;
}
}
else if (*tpos == 'd' || *tpos == 'u') /* Integer parameter */
{
register int iarg;
iarg = va_arg(ap, int);
if(olen + 16 >= n) break;
if (*tpos == 'd')
plen= (uint) (int2str((long) iarg,endpos, -10) - endpos);
else
plen= (uint) (int2str((long) (uint) iarg,endpos,10)- endpos);
if (olen + plen < n) /* Replace parameter if possible */
{
endpos+=plen;
tpos++;
olen+=plen;
continue;
}
} }
} }
*endpos++='%'; /* % used as % or unknown code */ else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */
{
register int iarg;
if ((uint) (end-to) < 16)
break;
iarg = va_arg(ap, int);
if (*fmt == 'd')
to=int10_to_str((long) iarg,to, -10);
else
to=int10_to_str((long) (uint) iarg,to,10);
continue;
}
/* We come here on '%%', unknown code or too long parameter */
if (to == end)
break;
*to++='%'; /* % used as % or unknown code */
} }
*endpos='\0'; *to='\0'; /* End of errmessage */
/* End of errmessage */ return (uint) (to - start);
return olen;
} }

View File

@ -28,10 +28,13 @@ parse_arguments() {
--socket=*) MYSQL_UNIX_PORT=`echo "$arg" | sed -e "s;--socket=;;"` ;; --socket=*) MYSQL_UNIX_PORT=`echo "$arg" | sed -e "s;--socket=;;"` ;;
--port=*) MYSQL_TCP_PORT=`echo "$arg" | sed -e "s;--port=;;"` ;; --port=*) MYSQL_TCP_PORT=`echo "$arg" | sed -e "s;--port=;;"` ;;
--log=*) log=`echo "$arg" | sed -e "s;--log=;;"` ;; --log=*) log=`echo "$arg" | sed -e "s;--log=;;"` ;;
--err-log=*) err_log=`echo "$arg" | sed -e "s;--err-log=;;"` ;;
--basedir=*) MY_BASEDIR_VERSION=`echo "$arg" | sed -e "s;--basedir=;;"` ;; --basedir=*) MY_BASEDIR_VERSION=`echo "$arg" | sed -e "s;--basedir=;;"` ;;
--ledir=*) ledir=`echo "$arg" | sed -e "s;--ledir=;;"` ;;
--user=*) user=`echo "$arg" | sed -e "s;--user=;;"` ;; --user=*) user=`echo "$arg" | sed -e "s;--user=;;"` ;;
--ledir=*) ledir=`echo "$arg" | sed -e "s;--ledir=;;"` ;;
--err-log=*) err_log=`echo "$arg" | sed -e "s;--err-log=;;"` ;;
--open-files=*) open_files=`echo "$arg" | sed -e "s;--open-files=;;"` ;;
--core-file-size*) core_file_size=`echo "$arg" | sed -e "s;--core_file_size=;;"` ;;
--timezone=*) TZ=`echo "$arg" | sed -e "s;--timezone=;;"` ; export TZ; ;;
esac esac
done done
} }
@ -105,6 +108,14 @@ if test -w /
then then
# If we are root, change the err log to the right user. # If we are root, change the err log to the right user.
touch $err_log; chown $user $err_log touch $err_log; chown $user $err_log
if test -n "$open_files"
then
ulimit -n $open_files
fi
if test -n "$core_file_size"
then
ulimit -c $core_file_size
fi
fi fi
# #

View File

@ -339,6 +339,15 @@ sub end_benchmark
exit 0; exit 0;
} }
sub print_time
{
my ($estimated)=@_;
if ($estimated)
{ print "Estimated time"; }
else
{ print "Time"; }
}
# #
# Create a filename part for the machine that can be used for log file. # Create a filename part for the machine that can be used for log file.
# #

View File

@ -39,7 +39,7 @@
# "3-byte int" or "same as xxx". # "3-byte int" or "same as xxx".
$version="1.50"; $version="1.51";
use DBI; use DBI;
use Getopt::Long; use Getopt::Long;
@ -289,6 +289,11 @@ report("rename table","rename_table",
$dbh->do("drop table crash_q1"); $dbh->do("drop table crash_q1");
$dbh->do("drop table crash_q"); $dbh->do("drop table crash_q");
report("truncate table","truncate_table",
"create table crash_q (a integer, b integer,c CHAR(10))",
"truncate table crash_q",
"drop table crash_q1");
if ($dbh->do("create table crash_q (a integer, b integer,c CHAR(10))") && if ($dbh->do("create table crash_q (a integer, b integer,c CHAR(10))") &&
$dbh->do("create table crash_q1 (a integer, b integer,c CHAR(10) not null)")) $dbh->do("create table crash_q1 (a integer, b integer,c CHAR(10) not null)"))
{ {

View File

@ -270,7 +270,7 @@ for ($i=1 ; $i <= $small_loop_count ; $i++)
{ {
if (!$error++) if (!$error++)
{ {
print "Warning: Got $found_rows rows when selecting a hole table of " . ($total_rows) . " rows\nContact the database or DBD author!\n"; print "Warning: Got $found_rows rows when selecting a whole table of " . ($total_rows) . " rows\nContact the database or DBD author!\n";
} }
} }
$count+=$found_rows; $count+=$found_rows;
@ -280,44 +280,125 @@ $end_time=new Benchmark;
print "Time for select_big ($small_loop_count:$count): " . print "Time for select_big ($small_loop_count:$count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n"; timestr(timediff($end_time, $loop_time),"all") . "\n";
#
# Do a lot of different ORDER BY queries
#
$loop_time=new Benchmark; $loop_time=new Benchmark;
$estimated=0; $estimated=$rows=0;
$rows=0; for ($i=1 ; $i <= $small_loop_count ; $i++)
$count=0;
for ($i=1 ; $i <= $small_loop_count/2 ; $i++)
{ {
$rows+=fetch_all_rows($dbh,"select id from bench1 order by id",1); $rows+=fetch_all_rows($dbh,"select id from bench1 order by id",1);
$rows+=fetch_all_rows($dbh,"select id from bench1 order by id desc",1);
$count+=2;
$end_time=new Benchmark; $end_time=new Benchmark;
last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$count, last if ($estimated=predict_query_time($loop_time,$end_time,\$i,$i,
$small_loop_count)); $small_loop_count));
} }
if ($estimated) if ($estimated)
{ print "Estimated time"; } { print "Estimated time"; }
else else
{ print "Time"; } { print "Time"; }
print " for order_by_key ($count:$rows): " . print " for order_by_big_key ($small_loop_count:$rows): " .
timestr(timediff($end_time, $loop_time),"all") . "\n"; timestr(timediff($end_time, $loop_time),"all") . "\n";
$loop_time=new Benchmark; $loop_time=new Benchmark;
$estimated=0; $estimated=$rows=0;
$rows=0; for ($i=1 ; $i <= $small_loop_count ; $i++)
$count=0;
for ($i=1 ; $i <= $small_loop_count/2 ; $i++)
{ {
$rows+=fetch_all_rows($dbh,"select id2 from bench1 order by id2",1); $rows+=fetch_all_rows($dbh,"select id from bench1 order by id desc",1);
$rows+=fetch_all_rows($dbh,"select id2 from bench1 order by id2 desc",1);
$count+=2;
$end_time=new Benchmark; $end_time=new Benchmark;
last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$count, last if ($estimated=predict_query_time($loop_time,$end_time,\$i,$i,
$small_loop_count)); $small_loop_count));
} }
if ($estimated) if ($estimated)
{ print "Estimated time"; } { print "Estimated time"; }
else else
{ print "Time"; } { print "Time"; }
print " for order_by ($count:$rows): " . print " for order_by_big_key_desc ($small_loop_count:$rows): " .
timestr(timediff($end_time, $loop_time),"all") . "\n";
$loop_time=new Benchmark;
$estimated=$rows=0;
for ($i=1 ; $i <= $small_loop_count ; $i++)
{
$rows+=fetch_all_rows($dbh,"select id3 from bench1 order by id3",1);
$end_time=new Benchmark;
last if ($estimated=predict_query_time($loop_time,$end_time,\$i,$i,
$small_loop_count));
}
if ($estimated)
{ print "Estimated time"; }
else
{ print "Time"; }
print " for order_by_big_key2 ($small_loop_count:$rows): " .
timestr(timediff($end_time, $loop_time),"all") . "\n";
$loop_time=new Benchmark;
$estimated=$rows=0;
for ($i=1 ; $i <= $small_loop_count ; $i++)
{
$rows+=fetch_all_rows($dbh,"select id2 from bench1 order by id3",1);
$end_time=new Benchmark;
last if ($estimated=predict_query_time($loop_time,$end_time,\$i,$i,
$small_loop_count));
}
if ($estimated)
{ print "Estimated time"; }
else
{ print "Time"; }
print " for order_by_big_key_diff ($small_loop_count:$rows): " .
timestr(timediff($end_time, $loop_time),"all") . "\n";
$loop_time=new Benchmark;
$estimated=$rows=0;
for ($i=1 ; $i <= $small_loop_count ; $i++)
{
$rows+=fetch_all_rows($dbh,"select id from bench1 order by id2,id3",1);
$end_time=new Benchmark;
last if ($estimated=predict_query_time($loop_time,$end_time,\$i,$i,
$small_loop_count));
}
if ($estimated)
{ print "Estimated time"; }
else
{ print "Time"; }
print " for order_by_big ($small_loop_count:$rows): " .
timestr(timediff($end_time, $loop_time),"all") . "\n";
$loop_time=new Benchmark;
$estimated=$rows=0;
for ($i=1 ; $i <= $small_loop_count ; $i++)
{
$start=$opt_loop_count/$small_loop_count*$i;
$end=$start+$i;
$rows+=fetch_all_rows($dbh,"select dummy1 from bench1 where id>=$start and id <= $end order by id",1);
$end_time=new Benchmark;
last if ($estimated=predict_query_time($loop_time,$end_time,\$i,$i,
$small_loop_count));
}
if ($estimated)
{ print "Estimated time"; }
else
{ print "Time"; }
print " for order_by_key ($small_loop_count:$rows): " .
timestr(timediff($end_time, $loop_time),"all") . "\n";
$loop_time=new Benchmark;
$estimated=$rows=0;
for ($i=1 ; $i <= $small_loop_count ; $i++)
{
$start=$opt_loop_count/$small_loop_count*$i;
$end=$start+$small_loop_count;
$rows+=fetch_all_rows($dbh,"select id2 from bench1 where id3>=$start and id3 <= $end order by id3",1);
$end_time=new Benchmark;
last if ($estimated=predict_query_time($loop_time,$end_time,\$i,$i,
$small_loop_count));
}
if ($estimated)
{ print "Estimated time"; }
else
{ print "Time"; }
print " for order_by_key2_diff ($small_loop_count:$rows): " .
timestr(timediff($end_time, $loop_time),"all") . "\n"; timestr(timediff($end_time, $loop_time),"all") . "\n";
# #
@ -417,6 +498,7 @@ if ($limits->{'group_functions'})
$loop_time=new Benchmark; $loop_time=new Benchmark;
$count=1; $count=1;
$estimated=0;
for ($tests=0 ; $tests < $small_loop_count ; $tests++) for ($tests=0 ; $tests < $small_loop_count ; $tests++)
{ {
$sth=$dbh->prepare($query="select count(*) from bench1") or die $DBI::errstr; $sth=$dbh->prepare($query="select count(*) from bench1") or die $DBI::errstr;
@ -492,9 +574,12 @@ if ($limits->{'group_functions'})
print "Warning: '$query' returned wrong number of rows\n"; print "Warning: '$query' returned wrong number of rows\n";
} }
} }
$end_time=new Benchmark;
last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$tests,
$small_loop_count));
} }
$end_time=new Benchmark; print_time($estimated);
print "Time for select_group ($count): " . print " for select_group ($count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n"; timestr(timediff($end_time, $loop_time),"all") . "\n";
$loop_time=new Benchmark; $loop_time=new Benchmark;

View File

@ -205,10 +205,7 @@ for ($i=0 ; $i < $opt_small_loop_count ; $i++)
$opt_small_loop_count)); $opt_small_loop_count));
} }
if ($estimated) print_time($estimated);
{ print "Estimated time"; }
else
{ print "Time"; }
print " for select_range ($count:$rows): " . print " for select_range ($count:$rows): " .
timestr(timediff($end_time, $loop_time),"all") . "\n"; timestr(timediff($end_time, $loop_time),"all") . "\n";
@ -243,10 +240,7 @@ if ($limits->{'group_functions'})
last if ($estimated=predict_query_time($loop_time,$end_time,\$count, last if ($estimated=predict_query_time($loop_time,$end_time,\$count,
$tests+1, $opt_loop_count)); $tests+1, $opt_loop_count));
} }
if ($estimated) print_time($estimated);
{ print "Estimated time"; }
else
{ print "Time"; }
print " for min_max_on_key ($count): " . print " for min_max_on_key ($count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n"; timestr(timediff($end_time, $loop_time),"all") . "\n";
@ -267,10 +261,7 @@ if ($limits->{'group_functions'})
last if ($estimated=predict_query_time($loop_time,$end_time,\$count, last if ($estimated=predict_query_time($loop_time,$end_time,\$count,
$tests+1, $opt_loop_count)); $tests+1, $opt_loop_count));
} }
if ($estimated) print_time($estimated);
{ print "Estimated time"; }
else
{ print "Time"; }
print " for count_on_key ($count): " . print " for count_on_key ($count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n"; timestr(timediff($end_time, $loop_time),"all") . "\n\n";
@ -278,7 +269,7 @@ if ($limits->{'group_functions'})
$rows=0; $rows=0;
for ($i=0 ; $i < $opt_medium_loop_count ; $i++) for ($i=0 ; $i < $opt_medium_loop_count ; $i++)
{ {
fetch_all_rows($dbh,"select grp,count(*) from bench1 group by grp"); $rows+=fetch_all_rows($dbh,"select grp,count(*) from bench1 group by grp");
} }
$end_time=new Benchmark; $end_time=new Benchmark;
print "Time for count_group_on_key_parts ($i:$rows): " . print "Time for count_group_on_key_parts ($i:$rows): " .
@ -289,54 +280,74 @@ if ($limits->{'group_functions'})
{ {
print "Testing count(distinct) on the table\n"; print "Testing count(distinct) on the table\n";
$loop_time=new Benchmark; $loop_time=new Benchmark;
$rows=0; $rows=$estimated=$count=0;
for ($i=0 ; $i < $opt_medium_loop_count ; $i++) for ($i=0 ; $i < $opt_medium_loop_count ; $i++)
{ {
$count+=2;
$rows+=fetch_all_rows($dbh,"select count(distinct region) from bench1"); $rows+=fetch_all_rows($dbh,"select count(distinct region) from bench1");
$rows+=fetch_all_rows($dbh,"select count(distinct grp) from bench1"); $rows+=fetch_all_rows($dbh,"select count(distinct grp) from bench1");
$end_time=new Benchmark;
last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$i+1,
$opt_medium_loop_count));
} }
$end_time=new Benchmark; print_time($estimated);
print "Time for count_distinct ($i:$rows): " . print " for count_distinct ($count:$rows): " .
timestr(timediff($end_time, $loop_time),"all") . "\n"; timestr(timediff($end_time, $loop_time),"all") . "\n";
$loop_time=new Benchmark; $loop_time=new Benchmark;
$rows=0; $rows=$estimated=$count=0;
for ($i=0 ; $i < $opt_medium_loop_count ; $i++) for ($i=0 ; $i < $opt_medium_loop_count ; $i++)
{ {
$count++;
$rows+=fetch_all_rows($dbh,"select region,count(distinct idn) from bench1 group by region"); $rows+=fetch_all_rows($dbh,"select region,count(distinct idn) from bench1 group by region");
$end_time=new Benchmark;
last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$i+1,
$opt_medium_loop_count));
} }
$end_time=new Benchmark; print_time($estimated);
print "Time for count_distinct_group_on_key ($i:$rows): " . print " for count_distinct_group_on_key ($count:$rows): " .
timestr(timediff($end_time, $loop_time),"all") . "\n"; timestr(timediff($end_time, $loop_time),"all") . "\n";
$loop_time=new Benchmark; $loop_time=new Benchmark;
$rows=0; $rows=$estimated=$count=0;
for ($i=0 ; $i < $opt_medium_loop_count ; $i++) for ($i=0 ; $i < $opt_medium_loop_count ; $i++)
{ {
$count++;
$rows+=fetch_all_rows($dbh,"select grp,count(distinct idn) from bench1 group by grp"); $rows+=fetch_all_rows($dbh,"select grp,count(distinct idn) from bench1 group by grp");
$end_time=new Benchmark;
last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$i+1,
$opt_medium_loop_count));
} }
$end_time=new Benchmark; print_time($estimated);
print "Time for count_distinct_group_on_key_parts ($i:$rows): " . print " for count_distinct_group_on_key_parts ($count:$rows): " .
timestr(timediff($end_time, $loop_time),"all") . "\n"; timestr(timediff($end_time, $loop_time),"all") . "\n";
$loop_time=new Benchmark; $loop_time=new Benchmark;
$rows=0; $rows=$estimated=$count=0;
for ($i=0 ; $i < $opt_medium_loop_count ; $i++) for ($i=0 ; $i < $opt_medium_loop_count ; $i++)
{ {
$count++;
$rows+=fetch_all_rows($dbh,"select grp,count(distinct rev_idn) from bench1 group by grp"); $rows+=fetch_all_rows($dbh,"select grp,count(distinct rev_idn) from bench1 group by grp");
$end_time=new Benchmark;
last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$i+1,
$opt_medium_loop_count));
} }
$end_time=new Benchmark; print_time($estimated);
print "Time for count_distinct_group ($i:$rows): " . print " for count_distinct_group ($count:$rows): " .
timestr(timediff($end_time, $loop_time),"all") . "\n"; timestr(timediff($end_time, $loop_time),"all") . "\n";
$loop_time=new Benchmark; $loop_time=new Benchmark;
$rows=0; $rows=$estimated=$count=0;
for ($i=0 ; $i < $opt_medium_loop_count ; $i++) for ($i=0 ; $i < $opt_medium_loop_count ; $i++)
{ {
$count++;
$rows+=fetch_all_rows($dbh,"select idn,count(distinct region) from bench1 group by idn"); $rows+=fetch_all_rows($dbh,"select idn,count(distinct region) from bench1 group by idn");
$end_time=new Benchmark;
last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$i+1,
$opt_medium_loop_count));
} }
$end_time=new Benchmark; print_time($estimated);
print "Time for count_distinct_big ($i:$rows): " . print " for count_distinct_big ($count:$rows): " .
timestr(timediff($end_time, $loop_time),"all") . "\n"; timestr(timediff($end_time, $loop_time),"all") . "\n";
} }

View File

@ -38,8 +38,8 @@ if (my_b_write((file),(byte*) (from),param->ref_length)) \
typedef struct st_buffpek { /* Struktur om sorteringsbuffrarna */ typedef struct st_buffpek { /* Struktur om sorteringsbuffrarna */
my_off_t file_pos; /* Where we are in the sort file */ my_off_t file_pos; /* Where we are in the sort file */
ha_rows count; /* Number of rows in table */
uchar *base,*key; /* key pointers */ uchar *base,*key; /* key pointers */
ha_rows count; /* Number of rows in table */
ulong mem_count; /* numbers of keys in memory */ ulong mem_count; /* numbers of keys in memory */
ulong max_keys; /* Max keys in buffert */ ulong max_keys; /* Max keys in buffert */
} BUFFPEK; } BUFFPEK;
@ -98,7 +98,6 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
BUFFPEK *buffpek; BUFFPEK *buffpek;
ha_rows records; ha_rows records;
uchar **sort_keys; uchar **sort_keys;
gptr save_1,save_2;
IO_CACHE tempfile,*selected_records_file,*outfile; IO_CACHE tempfile,*selected_records_file,*outfile;
SORTPARAM param; SORTPARAM param;
DBUG_ENTER("filesort"); DBUG_ENTER("filesort");
@ -109,7 +108,6 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
outfile= table[0]->io_cache; outfile= table[0]->io_cache;
my_b_clear(&tempfile); my_b_clear(&tempfile);
save_1=save_2=0;
buffpek= (BUFFPEK *) NULL; sort_keys= (uchar **) NULL; error= 1; buffpek= (BUFFPEK *) NULL; sort_keys= (uchar **) NULL; error= 1;
maxbuffer=1; maxbuffer=1;
param.ref_length= table[0]->file->ref_length; param.ref_length= table[0]->file->ref_length;
@ -148,7 +146,7 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
else else
{ {
table[0]->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);/* Get record-count */ table[0]->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);/* Get record-count */
records=table[0]->file->records+EXTRA_RECORDS; records=table[0]->file->estimate_number_of_rows();
selected_records_file= 0; selected_records_file= 0;
} }
if (param.sort_length == param.ref_length && records > param.max_rows) if (param.sort_length == param.ref_length && records > param.max_rows)
@ -160,16 +158,11 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
goto err; goto err;
#endif #endif
/* Reserve memory for IO_CACHE files */
if (! (save_1=my_malloc(DISK_BUFFER_SIZE,MYF(MY_WME))) ||
! (save_2=my_malloc(DISK_BUFFER_SIZE,MYF(MY_WME))))
goto err;
memavl=sortbuff_size; memavl=sortbuff_size;
while (memavl >= MIN_SORT_MEMORY) while (memavl >= MIN_SORT_MEMORY)
{ {
if ((records+1)*(param.sort_length+sizeof(char*))+sizeof(BUFFPEK)*10 < if ((ulonglong) (records+1)*(param.sort_length+sizeof(char*))+sizeof(BUFFPEK)*10 <
(ulong) memavl) (ulonglong) memavl)
param.keys=(uint) records+1; param.keys=(uint) records+1;
else else
{ {
@ -207,10 +200,6 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
my_error(ER_OUTOFMEMORY,MYF(ME_ERROR+ME_WAITTANG),sortbuff_size); my_error(ER_OUTOFMEMORY,MYF(ME_ERROR+ME_WAITTANG),sortbuff_size);
goto err; goto err;
} }
my_free(save_1,MYF(0)); /* Free for later use */
my_free(save_2,MYF(0));
save_1=save_2=0;
param.sort_form= table[0]; param.sort_form= table[0];
param.end=(param.local_sortorder=sortorder)+s_length; param.end=(param.local_sortorder=sortorder)+s_length;
if ((records=find_all_keys(&param,select,sort_keys,buffpek,&maxbuffer, if ((records=find_all_keys(&param,select,sort_keys,buffpek,&maxbuffer,
@ -252,8 +241,6 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
#endif #endif
x_free((gptr) sort_keys); x_free((gptr) sort_keys);
x_free((gptr) buffpek); x_free((gptr) buffpek);
x_free(save_1);
x_free(save_2);
close_cached_file(&tempfile); close_cached_file(&tempfile);
if (my_b_inited(outfile)) if (my_b_inited(outfile))
{ {
@ -382,6 +369,7 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
} }
if (*killed) if (*killed)
{ {
DBUG_PRINT("info",("Sort killed by user"));
(void) file->extra(HA_EXTRA_NO_CACHE); (void) file->extra(HA_EXTRA_NO_CACHE);
file->rnd_end(); file->rnd_end();
DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */ DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */

View File

@ -25,8 +25,9 @@
We will need an updated Berkeley DB version for this. We will need an updated Berkeley DB version for this.
- Killing threads that has got a 'deadlock' - Killing threads that has got a 'deadlock'
- SHOW TABLE STATUS should give more information about the table. - SHOW TABLE STATUS should give more information about the table.
- Get a more accurate count of the number of rows. - Get a more accurate count of the number of rows (estimate_number_of_rows()).
We could store the found number of rows when the table is scanned. We could store the found number of rows when the table is scanned and
then increment the counter for each attempted write.
- We will need a manager thread that calls flush_logs, removes old - We will need a manager thread that calls flush_logs, removes old
logs and makes checkpoints at given intervals. logs and makes checkpoints at given intervals.
- When not using UPDATE IGNORE, don't make a sub transaction but abort - When not using UPDATE IGNORE, don't make a sub transaction but abort
@ -42,7 +43,6 @@
- LOCK TABLES - LOCK TABLES
- CHAR keys - CHAR keys
- BLOBS - BLOBS
- delete from t1;
*/ */
@ -60,6 +60,7 @@
#define HA_BERKELEY_ROWS_IN_TABLE 10000 /* to get optimization right */ #define HA_BERKELEY_ROWS_IN_TABLE 10000 /* to get optimization right */
#define HA_BERKELEY_RANGE_COUNT 100 #define HA_BERKELEY_RANGE_COUNT 100
#define HA_BERKELEY_MAX_ROWS 10000000 /* Max rows in table */
const char *ha_berkeley_ext=".db"; const char *ha_berkeley_ext=".db";
bool berkeley_skip=0; bool berkeley_skip=0;
@ -1297,7 +1298,7 @@ void ha_berkeley::info(uint flag)
DBUG_ENTER("info"); DBUG_ENTER("info");
if (flag & HA_STATUS_VARIABLE) if (flag & HA_STATUS_VARIABLE)
{ {
records = HA_BERKELEY_ROWS_IN_TABLE; // Just to get optimisations right records = estimate_number_of_rows(); // Just to get optimisations right
deleted = 0; deleted = 0;
} }
else if (flag & HA_STATUS_ERRKEY) else if (flag & HA_STATUS_ERRKEY)
@ -1607,4 +1608,21 @@ void ha_berkeley::update_auto_primary_key()
pthread_mutex_unlock(&share->mutex); pthread_mutex_unlock(&share->mutex);
} }
/*
Return an estimated of the number of rows in the table.
Used when sorting to allocate buffers and by the optimizer.
*/
ha_rows ha_berkeley::estimate_number_of_rows()
{
ulonglong max_ident;
ulonglong max_rows=table->max_rows ? table->max_rows : HA_BERKELEY_MAX_ROWS;
if (!hidden_primary_key)
return (ha_rows) max_rows;
pthread_mutex_lock(&share->mutex);
max_ident=share->auto_ident+EXTRA_RECORDS;
pthread_mutex_unlock(&share->mutex);
return (ha_rows) min(max_ident,max_rows);
}
#endif /* HAVE_BERKELEY_DB */ #endif /* HAVE_BERKELEY_DB */

View File

@ -91,7 +91,8 @@ class ha_berkeley: public handler
uint max_keys() const { return MAX_KEY-1; } uint max_keys() const { return MAX_KEY-1; }
uint max_key_parts() const { return MAX_REF_PARTS; } uint max_key_parts() const { return MAX_REF_PARTS; }
uint max_key_length() const { return MAX_KEY_LENGTH; } uint max_key_length() const { return MAX_KEY_LENGTH; }
uint extra_rec_buf_length() { return BDB_HIDDEN_PRIMARY_KEY_LENGTH; } uint extra_rec_buf_length() { return BDB_HIDDEN_PRIMARY_KEY_LENGTH; }
ha_rows estimate_number_of_rows();
bool fast_key_read() { return 1;} bool fast_key_read() { return 1;}
bool has_transactions() { return 1;} bool has_transactions() { return 1;}

View File

@ -203,6 +203,7 @@ public:
virtual bool fast_key_read() { return 0;} virtual bool fast_key_read() { return 0;}
virtual bool has_transactions(){ return 0;} virtual bool has_transactions(){ return 0;}
virtual uint extra_rec_buf_length() { return 0; } virtual uint extra_rec_buf_length() { return 0; }
virtual ha_rows estimate_number_of_rows() { return records+EXTRA_RECORDS; }
virtual int index_init(uint idx) { active_index=idx; return 0;} virtual int index_init(uint idx) { active_index=idx; return 0;}
virtual int index_end() {return 0; } virtual int index_end() {return 0; }

View File

@ -352,11 +352,6 @@ Item *create_func_to_days(Item* a)
return new Item_func_to_days(a); return new Item_func_to_days(a);
} }
Item *create_func_truncate (Item *a, Item *b)
{
return new Item_func_round(a,b,1);
}
Item *create_func_ucase(Item* a) Item *create_func_ucase(Item* a)
{ {
return new Item_func_ucase(a); return new Item_func_ucase(a);

View File

@ -81,7 +81,6 @@ Item *create_func_tan(Item* a);;
Item *create_func_time_format(Item *a, Item *b); Item *create_func_time_format(Item *a, Item *b);
Item *create_func_time_to_sec(Item* a); Item *create_func_time_to_sec(Item* a);
Item *create_func_to_days(Item* a); Item *create_func_to_days(Item* a);
Item *create_func_truncate (Item *a, Item *b);
Item *create_func_ucase(Item* a); Item *create_func_ucase(Item* a);
Item *create_func_version(void); Item *create_func_version(void);
Item *create_func_weekday(Item* a); Item *create_func_weekday(Item* a);

View File

@ -1598,7 +1598,7 @@ String *Item_load_file::val_str(String *str)
if (!(file_name= args[0]->val_str(str)) || if (!(file_name= args[0]->val_str(str)) ||
!(current_thd->master_access & FILE_ACL) || !(current_thd->master_access & FILE_ACL) ||
!my_stat(file_name->c_ptr(), &stat_info, MYF(MY_FAE))) !my_stat(file_name->c_ptr(), &stat_info, MYF(MY_WME)))
goto err; goto err;
if (!(stat_info.st_mode & S_IROTH)) if (!(stat_info.st_mode & S_IROTH))
{ {

View File

@ -302,6 +302,7 @@ static SYMBOL symbols[] = {
{ "TINYTEXT", SYM(TINYTEXT),0,0}, { "TINYTEXT", SYM(TINYTEXT),0,0},
{ "TINYINT", SYM(TINYINT),0,0}, { "TINYINT", SYM(TINYINT),0,0},
{ "TRAILING", SYM(TRAILING),0,0}, { "TRAILING", SYM(TRAILING),0,0},
{ "TRUNCATE", SYM(TRUNCATE_SYM),0,0},
{ "TO", SYM(TO_SYM),0,0}, { "TO", SYM(TO_SYM),0,0},
{ "TYPE", SYM(TYPE_SYM),0,0}, { "TYPE", SYM(TYPE_SYM),0,0},
{ "UNION", SYM(UNION_SYM),0,0}, { "UNION", SYM(UNION_SYM),0,0},
@ -443,7 +444,6 @@ static SYMBOL sql_functions[] = {
{ "TIME_TO_SEC", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_time_to_sec)}, { "TIME_TO_SEC", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_time_to_sec)},
{ "TO_DAYS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_to_days)}, { "TO_DAYS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_to_days)},
{ "TRIM", SYM(TRIM),0,0}, { "TRIM", SYM(TRIM),0,0},
{ "TRUNCATE", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_truncate )},
{ "UCASE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ucase)}, { "UCASE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ucase)},
{ "UPPER", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ucase)}, { "UPPER", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ucase)},
{ "UNIQUE_USERS", SYM(UNIQUE_USERS),0,0}, { "UNIQUE_USERS", SYM(UNIQUE_USERS),0,0},

View File

@ -70,8 +70,8 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd,TABLE **tables,uint count)
thd->proc_info="Waiting for table"; thd->proc_info="Waiting for table";
pthread_mutex_unlock(&thd->mysys_var->mutex); pthread_mutex_unlock(&thd->mysys_var->mutex);
while (global_read_lock && ! thd->killed || while (global_read_lock && ! thd->killed &&
thd->version != refresh_version) thd->version == refresh_version)
{ {
(void) pthread_cond_wait(&COND_refresh,&LOCK_open); (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
} }

View File

@ -25,8 +25,6 @@
#include <stdarg.h> #include <stdarg.h>
#include <m_ctype.h> // For test_if_number #include <m_ctype.h> // For test_if_number
MYSQL_LOG mysql_log,mysql_update_log,mysql_slow_log,mysql_bin_log; MYSQL_LOG mysql_log,mysql_update_log,mysql_slow_log,mysql_bin_log;
extern I_List<i_string> binlog_do_db, binlog_ignore_db; extern I_List<i_string> binlog_do_db, binlog_ignore_db;
@ -75,26 +73,25 @@ static int find_uniq_filename(char *name)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
MYSQL_LOG::MYSQL_LOG(): last_time(0), query_start(0),
name(0), log_type(LOG_CLOSED),write_error(0),
MYSQL_LOG::MYSQL_LOG(): file(0),index_file(0),last_time(0),query_start(0), inited(0), opened(0), no_rotate(0)
name(0), log_type(LOG_CLOSED),write_error(0),inited(0),
no_rotate(0)
{ {
/* /*
We don't want to intialize LOCK_Log here as the thread system may We don't want to intialize LOCK_Log here as the thread system may
not have been initailized yet. We do it instead at 'open'. not have been initailized yet. We do it instead at 'open'.
*/ */
index_file_name[0] = 0; index_file_name[0] = 0;
bzero((char*) &log_file,sizeof(log_file));
} }
MYSQL_LOG::~MYSQL_LOG() MYSQL_LOG::~MYSQL_LOG()
{ {
if (inited) if (inited)
{ {
(void) pthread_mutex_destroy(&LOCK_log); (void) pthread_mutex_destroy(&LOCK_log);
(void) pthread_mutex_destroy(&LOCK_index); (void) pthread_mutex_destroy(&LOCK_index);
} }
} }
void MYSQL_LOG::set_index_file_name(const char* index_file_name) void MYSQL_LOG::set_index_file_name(const char* index_file_name)
@ -106,6 +103,7 @@ void MYSQL_LOG::set_index_file_name(const char* index_file_name)
this->index_file_name[0] = 0; this->index_file_name[0] = 0;
} }
int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name) int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name)
{ {
if (log_type == LOG_NORMAL) if (log_type == LOG_NORMAL)
@ -129,58 +127,60 @@ int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name)
void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
const char *new_name) const char *new_name)
{ {
MY_STAT tmp_stat;
char buff[512];
File file= -1;
bool do_magic;
if (!inited) if (!inited)
{ {
inited=1; inited=1;
(void) pthread_mutex_init(&LOCK_log,NULL); (void) pthread_mutex_init(&LOCK_log,NULL);
(void) pthread_mutex_init(&LOCK_index, NULL); (void) pthread_mutex_init(&LOCK_index, NULL);
if(log_type_arg == LOG_BIN && *fn_ext(log_name)) if (log_type_arg == LOG_BIN && *fn_ext(log_name))
no_rotate = 1; no_rotate = 1;
} }
log_type=log_type_arg; log_type=log_type_arg;
name=my_strdup(log_name,MYF(0)); if (!(name=my_strdup(log_name,MYF(MY_WME))))
goto err;
if (new_name) if (new_name)
strmov(log_file_name,new_name); strmov(log_file_name,new_name);
else if (generate_new_name(log_file_name, name)) else if (generate_new_name(log_file_name, name))
return; goto err;
if (log_type == LOG_BIN && !index_file_name[0]) if (log_type == LOG_BIN && !index_file_name[0])
fn_format(index_file_name, name, mysql_data_home, ".index", 6); fn_format(index_file_name, name, mysql_data_home, ".index", 6);
db[0]=0; db[0]=0;
MY_STAT tmp_stat; do_magic = ((log_type == LOG_BIN) && !my_stat(log_file_name,
bool do_magic = ((log_type == LOG_BIN) && !my_stat(log_file_name, &tmp_stat, MYF(0)));
&tmp_stat, MYF(0)));
file=my_fopen(log_file_name,O_APPEND | O_WRONLY | O_BINARY, if ((file=my_open(log_file_name,O_APPEND | O_WRONLY | O_BINARY,
MYF(MY_WME | ME_WAITTANG)); MYF(MY_WME | ME_WAITTANG))) < 0 ||
if (!file) init_io_cache(&log_file, file, IO_SIZE, WRITE_CACHE,
{ my_tell(file,MYF(MY_WME)), 0, MYF(MY_WME | MY_NABP)))
my_free(name,MYF(0)); goto err;
name=0;
log_type=LOG_CLOSED;
return;
}
if (log_type == LOG_NORMAL) if (log_type == LOG_NORMAL)
{ {
char *end;
#ifdef __NT__ #ifdef __NT__
fprintf(file, "%s, Version: %s, started with:\nTCP Port: %d, Named Pipe: %s\n", my_progname, server_version, mysql_port, mysql_unix_port); sprintf(buff, "%s, Version: %s, started with:\nTCP Port: %d, Named Pipe: %s\n", my_progname, server_version, mysql_port, mysql_unix_port);
#else #else
fprintf(file, "%s, Version: %s, started with:\nTcp port: %d Unix socket: %s\n", my_progname,server_version,mysql_port,mysql_unix_port); sprintf(buff, "%s, Version: %s, started with:\nTcp port: %d Unix socket: %s\n", my_progname,server_version,mysql_port,mysql_unix_port);
#endif #endif
fprintf(file,"Time Id Command Argument\n"); end=strmov(strend(buff),"Time Id Command Argument\n");
(void) fflush(file); if (my_b_write(&log_file,buff,(uint) (end-buff)) ||
flush_io_cache(&log_file))
goto err;
} }
else if (log_type == LOG_NEW) else if (log_type == LOG_NEW)
{ {
time_t skr=time(NULL); time_t skr=time(NULL);
struct tm tm_tmp; struct tm tm_tmp;
localtime_r(&skr,&tm_tmp); localtime_r(&skr,&tm_tmp);
sprintf(buff,"# %s, Version: %s at %02d%02d%02d %2d:%02d:%02d\n",
fprintf(file,"# %s, Version: %s at %02d%02d%02d %2d:%02d:%02d\n",
my_progname,server_version, my_progname,server_version,
tm_tmp.tm_year % 100, tm_tmp.tm_year % 100,
tm_tmp.tm_mon+1, tm_tmp.tm_mon+1,
@ -188,45 +188,49 @@ void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
tm_tmp.tm_hour, tm_tmp.tm_hour,
tm_tmp.tm_min, tm_tmp.tm_min,
tm_tmp.tm_sec); tm_tmp.tm_sec);
(void) fflush(file); if (my_b_write(&log_file,buff,(uint) strlen(buff)) ||
flush_io_cache(&log_file))
goto err;
} }
else if (log_type == LOG_BIN) else if (log_type == LOG_BIN)
{ {
// Explanation of the boolean black magic: // Explanation of the boolean black magic:
// //
// if we are supposed to write magic number try write // if we are supposed to write magic number try write
// clean up if failed // clean up if failed
// then if index_file has not been previously opened, try to open it // then if index_file has not been previously opened, try to open it
// clean up if failed // clean up if failed
if((do_magic && my_fwrite(file, (byte*)BINLOG_MAGIC, 4,
MYF(MY_NABP|MY_WME)) || if ((do_magic && my_b_write(&log_file, (byte*) BINLOG_MAGIC, 4)) ||
(!index_file && (index_file < 0 &&
!(index_file = my_fopen(index_file_name,O_APPEND | O_BINARY | O_RDWR, (index_file = my_open(index_file_name,O_APPEND | O_BINARY | O_RDWR,
MYF(MY_WME)))))) MYF(MY_WME))) < 0))
{ goto err;
my_fclose(file,MYF(MY_WME));
my_free(name,MYF(0));
name=0;
file=0;
log_type=LOG_CLOSED;
return;
}
Start_log_event s; Start_log_event s;
s.write(file); s.write(&log_file);
pthread_mutex_lock(&LOCK_index); pthread_mutex_lock(&LOCK_index);
my_fseek(index_file, 0L, MY_SEEK_END, MYF(MY_WME)); my_write(index_file, log_file_name,strlen(log_file_name), MYF(0));
fprintf(index_file, "%s\n", log_file_name); my_write(index_file, "\n",1, MYF(0));
fflush(index_file);
pthread_mutex_unlock(&LOCK_index); pthread_mutex_unlock(&LOCK_index);
} }
return;
err:
if (file >= 0)
my_close(file,MYF(0));
end_io_cache(&log_file);
x_free(name); name=0;
log_type=LOG_CLOSED;
return;
} }
int MYSQL_LOG::get_current_log(LOG_INFO* linfo) int MYSQL_LOG::get_current_log(LOG_INFO* linfo)
{ {
pthread_mutex_lock(&LOCK_log); pthread_mutex_lock(&LOCK_log);
strmake(linfo->log_file_name, log_file_name, sizeof(linfo->log_file_name)); strmake(linfo->log_file_name, log_file_name, sizeof(linfo->log_file_name)-1);
linfo->pos = my_ftell(file, MYF(MY_WME)); linfo->pos = my_b_tell(&log_file);
pthread_mutex_unlock(&LOCK_log); pthread_mutex_unlock(&LOCK_log);
return 0; return 0;
} }
@ -234,50 +238,85 @@ int MYSQL_LOG::get_current_log(LOG_INFO* linfo)
// if log_name is "" we stop at the first entry // if log_name is "" we stop at the first entry
int MYSQL_LOG::find_first_log(LOG_INFO* linfo, const char* log_name) int MYSQL_LOG::find_first_log(LOG_INFO* linfo, const char* log_name)
{ {
// mutex needed because we need to make sure the file pointer does not move if (index_file < 0)
// from under our feet return LOG_INFO_INVALID;
if(!index_file) return LOG_INFO_INVALID;
int error = 0; int error = 0;
char* fname = linfo->log_file_name; char* fname = linfo->log_file_name;
int log_name_len = (uint) strlen(log_name); int log_name_len = (uint) strlen(log_name);
IO_CACHE io_cache;
// mutex needed because we need to make sure the file pointer does not move
// from under our feet
pthread_mutex_lock(&LOCK_index); pthread_mutex_lock(&LOCK_index);
if(my_fseek(index_file, 0L, MY_SEEK_SET, MYF(MY_WME) ) == MY_FILEPOS_ERROR) if (init_io_cache(&io_cache, index_file, IO_SIZE, READ_CACHE, (my_off_t) 0,
0, MYF(MY_WME)))
{
error = LOG_INFO_SEEK;
goto err;
}
for(;;)
{
uint length;
if (!(length=my_b_gets(&io_cache, fname, FN_REFLEN)))
{ {
error = LOG_INFO_SEEK; error = !io_cache.error ? LOG_INFO_EOF : LOG_INFO_IO;
goto err; goto err;
} }
for(;;) // if the log entry matches, empty string matching anything
if (!log_name_len ||
(log_name_len == length+1 && fname[log_name_len] == '\n' &&
!memcmp(fname, log_name, log_name_len)))
{ {
if(!fgets(fname, FN_REFLEN, index_file)) fname[length-1]=0; // remove last \n
{ linfo->index_file_offset = my_b_tell(&io_cache);
error = feof(index_file) ? LOG_INFO_EOF : LOG_INFO_IO; break;
goto err;
}
// if the log entry matches, empty string matching anything
if(!log_name_len || (fname[log_name_len] == '\n' &&
!memcmp(fname, log_name, log_name_len)))
{
if(log_name_len)
fname[log_name_len] = 0; // to kill \n
else
{
*(strend(fname) - 1) = 0;
}
linfo->index_file_offset = my_ftell(index_file, MYF(MY_WME));
break;
}
} }
}
error = 0; error = 0;
err: err:
pthread_mutex_unlock(&LOCK_index); pthread_mutex_unlock(&LOCK_index);
end_io_cache(&io_cache);
return error; return error;
} }
int MYSQL_LOG::find_next_log(LOG_INFO* linfo)
{
// mutex needed because we need to make sure the file pointer does not move
// from under our feet
if (!index_file) return LOG_INFO_INVALID;
int error = 0;
char* fname = linfo->log_file_name;
IO_CACHE io_cache;
uint length;
pthread_mutex_lock(&LOCK_index);
if (init_io_cache(&io_cache, index_file, IO_SIZE,
READ_CACHE, (my_off_t) linfo->index_file_offset, 0,
MYF(MY_WME)))
{
error = LOG_INFO_SEEK;
goto err;
}
if (!(length=my_b_gets(&io_cache, fname, FN_REFLEN)))
{
error = !io_cache.error ? LOG_INFO_EOF : LOG_INFO_IO;
goto err;
}
fname[length-1]=0; // kill /n
linfo->index_file_offset = my_b_tell(&io_cache);
error = 0;
err:
pthread_mutex_unlock(&LOCK_index);
end_io_cache(&io_cache);
return error;
}
int MYSQL_LOG::purge_logs(THD* thd, const char* to_log) int MYSQL_LOG::purge_logs(THD* thd, const char* to_log)
{ {
if(!index_file) return LOG_INFO_INVALID; if(!index_file) return LOG_INFO_INVALID;
@ -409,63 +448,21 @@ err:
} }
int MYSQL_LOG::find_next_log(LOG_INFO* linfo)
{
// mutex needed because we need to make sure the file pointer does not move
// from under our feet
if(!index_file) return LOG_INFO_INVALID;
int error = 0;
char* fname = linfo->log_file_name;
char* end ;
pthread_mutex_lock(&LOCK_index);
if(linfo->fatal)
{
error = LOG_INFO_FATAL;
goto err;
}
if(my_fseek(index_file, linfo->index_file_offset, MY_SEEK_SET, MYF(MY_WME) ) == MY_FILEPOS_ERROR)
{
error = LOG_INFO_SEEK;
goto err;
}
if(!fgets(fname, FN_REFLEN, index_file))
{
error = feof(index_file) ? LOG_INFO_EOF : LOG_INFO_IO;
goto err;
}
end = strend(fname) - 1;
*end = 0; // kill /n
linfo->index_file_offset = ftell(index_file);
error = 0;
err:
pthread_mutex_unlock(&LOCK_index);
return error;
}
// we assume that buf has at least FN_REFLEN bytes alloced // we assume that buf has at least FN_REFLEN bytes alloced
void MYSQL_LOG::make_log_name(char* buf, const char* log_ident) void MYSQL_LOG::make_log_name(char* buf, const char* log_ident)
{ {
if(inited) buf[0] = 0; // In case of error
{ if (inited)
int dir_len = dirname_length(log_file_name); {
int ident_len = (uint) strlen(log_ident); int dir_len = dirname_length(log_file_name);
if(dir_len + ident_len + 1 > FN_REFLEN) int ident_len = (uint) strlen(log_ident);
{ if (dir_len + ident_len + 1 > FN_REFLEN)
buf[0] = 0; return; // protection agains malicious buffer overflow
return; // protection agains malicious buffer overflow
}
memcpy(buf, log_file_name, dir_len); memcpy(buf, log_file_name, dir_len);
memcpy(buf + dir_len, log_ident, ident_len + 1); // this takes care of \0 // copy filename + end null
// at the end memcpy(buf + dir_len, log_ident, ident_len + 1);
} }
else
buf[0] = 0;
} }
bool MYSQL_LOG::is_active(const char* log_file_name) bool MYSQL_LOG::is_active(const char* log_file_name)
@ -475,15 +472,17 @@ bool MYSQL_LOG::is_active(const char* log_file_name)
void MYSQL_LOG::new_file() void MYSQL_LOG::new_file()
{ {
if (file) // only rotate open logs that are marked non-rotatable
// (binlog with constant name are non-rotatable)
if (is_open() && ! no_rotate)
{ {
if(no_rotate) // do not rotate logs that are marked non-rotatable
return; // ( for binlog with constant name)
char new_name[FN_REFLEN], *old_name=name; char new_name[FN_REFLEN], *old_name=name;
VOID(pthread_mutex_lock(&LOCK_log)); VOID(pthread_mutex_lock(&LOCK_log));
if (generate_new_name(new_name, name)) if (generate_new_name(new_name, name))
{
VOID(pthread_mutex_unlock(&LOCK_log));
return; // Something went wrong return; // Something went wrong
}
if (log_type == LOG_BIN) if (log_type == LOG_BIN)
{ {
/* /*
@ -491,15 +490,13 @@ void MYSQL_LOG::new_file()
to change base names at some point. to change base names at some point.
*/ */
Rotate_log_event r(new_name+dirname_length(new_name)); Rotate_log_event r(new_name+dirname_length(new_name));
r.write(file); r.write(&log_file);
VOID(pthread_cond_broadcast(&COND_binlog_update)); VOID(pthread_cond_broadcast(&COND_binlog_update));
} }
name=0; name=0;
close(); close();
open(old_name, log_type, new_name); open(old_name, log_type, new_name);
my_free(old_name,MYF(0)); my_free(old_name,MYF(0));
if (!file) // Something went wrong
log_type=LOG_CLOSED;
last_time=query_start=0; last_time=query_start=0;
write_error=0; write_error=0;
VOID(pthread_mutex_unlock(&LOCK_log)); VOID(pthread_mutex_unlock(&LOCK_log));
@ -514,7 +511,10 @@ void MYSQL_LOG::write(THD *thd,enum enum_server_command command,
{ {
va_list args; va_list args;
va_start(args,format); va_start(args,format);
char buff[32];
VOID(pthread_mutex_lock(&LOCK_log)); VOID(pthread_mutex_lock(&LOCK_log));
/* Test if someone closed after the is_open test */
if (log_type != LOG_CLOSED) if (log_type != LOG_CLOSED)
{ {
time_t skr; time_t skr;
@ -544,28 +544,30 @@ void MYSQL_LOG::write(THD *thd,enum enum_server_command command,
struct tm *start; struct tm *start;
localtime_r(&skr,&tm_tmp); localtime_r(&skr,&tm_tmp);
start=&tm_tmp; start=&tm_tmp;
if (fprintf(file,"%02d%02d%02d %2d:%02d:%02d\t", /* Note that my_b_write() assumes it knows the length for this */
start->tm_year % 100, sprintf(buff,"%02d%02d%02d %2d:%02d:%02d\t",
start->tm_mon+1, start->tm_year % 100,
start->tm_mday, start->tm_mon+1,
start->tm_hour, start->tm_mday,
start->tm_min, start->tm_hour,
start->tm_sec) < 0) start->tm_min,
start->tm_sec);
if (my_b_write(&log_file,buff,16))
error=errno; error=errno;
} }
else if (fputs("\t\t",file) < 0) else if (my_b_write(&log_file,"\t\t",2) < 0)
error=errno; error=errno;
if (fprintf(file,"%7ld %-10.10s", sprintf(buff,"%7ld %-10.10s", id,command_name[(uint) command]);
id,command_name[(uint) command]) < 0) if (my_b_write(&log_file,buff,strlen(buff)))
error=errno; error=errno;
if (format) if (format)
{ {
if (fputc(' ',file) < 0 || vfprintf(file,format,args) < 0) if (my_b_write(&log_file," ",1) ||
my_b_printf(&log_file,format,args) == (uint) -1)
error=errno; error=errno;
} }
if (fputc('\n',file) < 0) if (my_b_write(&log_file,"\n",1) ||
error=errno; flush_io_cache(&log_file))
if (fflush(file) < 0)
error=errno; error=errno;
if (error && ! write_error) if (error && ! write_error)
{ {
@ -585,7 +587,7 @@ void MYSQL_LOG::write(Query_log_event* event_info)
if (is_open()) if (is_open())
{ {
VOID(pthread_mutex_lock(&LOCK_log)); VOID(pthread_mutex_lock(&LOCK_log));
if (file) if (is_open())
{ {
THD *thd=event_info->thd; THD *thd=event_info->thd;
if ((!(thd->options & OPTION_BIN_LOG) && if ((!(thd->options & OPTION_BIN_LOG) &&
@ -599,43 +601,38 @@ void MYSQL_LOG::write(Query_log_event* event_info)
if (thd->last_insert_id_used) if (thd->last_insert_id_used)
{ {
Intvar_log_event e((uchar)LAST_INSERT_ID_EVENT, thd->last_insert_id); Intvar_log_event e((uchar)LAST_INSERT_ID_EVENT, thd->last_insert_id);
if (e.write(file)) if (e.write(&log_file))
{ {
sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno); sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
goto err; goto err;
} }
} }
if (thd->insert_id_used) if (thd->insert_id_used)
{ {
Intvar_log_event e((uchar)INSERT_ID_EVENT, thd->last_insert_id); Intvar_log_event e((uchar)INSERT_ID_EVENT, thd->last_insert_id);
if(e.write(file)) if (e.write(&log_file))
{ {
sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno); sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
goto err; goto err;
} }
} }
if (thd->convert_set)
if(thd->convert_set) {
char buf[1024] = "SET CHARACTER SET ";
char* p = strend(buf);
p = strmov(p, thd->convert_set->name);
int save_query_length = thd->query_length;
// just in case somebody wants it later
thd->query_length = (uint)(p - buf);
Query_log_event e(thd, buf);
if (e.write(&log_file))
{ {
char buf[1024] = "SET CHARACTER SET "; sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
char* p = strend(buf); goto err;
p = strmov(p, thd->convert_set->name);
int save_query_length = thd->query_length;
// just in case somebody wants it later
thd->query_length = (uint)(p - buf);
Query_log_event e(thd, buf);
if(e.write(file))
{
sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
goto err;
}
thd->query_length = save_query_length; // clean up
} }
thd->query_length = save_query_length; // clean up
if (event_info->write(file)) }
if (event_info->write(&log_file) || flush_io_cache(&log_file))
{ {
sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno); sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
} }
@ -651,13 +648,13 @@ void MYSQL_LOG::write(Load_log_event* event_info)
if (is_open()) if (is_open())
{ {
VOID(pthread_mutex_lock(&LOCK_log)); VOID(pthread_mutex_lock(&LOCK_log));
if (file) if (is_open())
{ {
THD *thd=event_info->thd; THD *thd=event_info->thd;
if ((thd->options & OPTION_BIN_LOG) || if ((thd->options & OPTION_BIN_LOG) ||
!(thd->master_access & PROCESS_ACL)) !(thd->master_access & PROCESS_ACL))
{ {
if (event_info->write(file)) if (event_info->write(&log_file) || flush_io_cache(&log_file))
sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno); sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
VOID(pthread_cond_broadcast(&COND_binlog_update)); VOID(pthread_cond_broadcast(&COND_binlog_update));
} }
@ -676,7 +673,7 @@ void MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
{ {
time_t current_time; time_t current_time;
VOID(pthread_mutex_lock(&LOCK_log)); VOID(pthread_mutex_lock(&LOCK_log));
if (file) if (is_open())
{ // Safety agains reopen { // Safety agains reopen
int error=0; int error=0;
char buff[80],*end; char buff[80],*end;
@ -695,37 +692,42 @@ void MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
last_time=current_time; last_time=current_time;
struct tm tm_tmp; struct tm tm_tmp;
struct tm *start; struct tm *start;
char buff[32];
localtime_r(&current_time,&tm_tmp); localtime_r(&current_time,&tm_tmp);
start=&tm_tmp; start=&tm_tmp;
if (fprintf(file,"# Time: %02d%02d%02d %2d:%02d:%02d\n", /* Note that my_b_write() assumes it knows the length for this */
start->tm_year % 100, sprintf(buff,"# Time: %02d%02d%02d %2d:%02d:%02d\n",
start->tm_mon+1, start->tm_year % 100,
start->tm_mday, start->tm_mon+1,
start->tm_hour, start->tm_mday,
start->tm_min, start->tm_hour,
start->tm_sec) < 0) start->tm_min,
start->tm_sec);
if (my_b_write(&log_file,buff,24))
error=errno; error=errno;
} }
if (fprintf(file, "# User@Host: %s [%s] @ %s [%s]\n", if (my_b_printf(&log_file, "# User@Host: %s [%s] @ %s [%s]\n",
thd->priv_user, thd->priv_user,
thd->user, thd->user,
thd->host ? thd->host : "", thd->host ? thd->host : "",
thd->ip ? thd->ip : "") < 0) thd->ip ? thd->ip : ""))
error=errno;; error=errno;
} }
if (query_start) if (query_start)
{ {
/* For slow query log */ /* For slow query log */
if (!(specialflag & SPECIAL_LONG_LOG_FORMAT)) if (!(specialflag & SPECIAL_LONG_LOG_FORMAT))
current_time=time(NULL); current_time=time(NULL);
fprintf(file,"# Time: %lu Lock_time: %lu Rows_sent: %lu\n", if (my_b_printf(&log_file,
(ulong) (current_time - query_start), "# Time: %lu Lock_time: %lu Rows_sent: %lu\n",
(ulong) (thd->time_after_lock - query_start), (ulong) (current_time - query_start),
(ulong) thd->sent_row_count); (ulong) (thd->time_after_lock - query_start),
(ulong) thd->sent_row_count))
error=errno;
} }
if (thd->db && strcmp(thd->db,db)) if (thd->db && strcmp(thd->db,db))
{ // Database changed { // Database changed
if (fprintf(file,"use %s;\n",thd->db) < 0) if (my_b_printf(&log_file,"use %s;\n",thd->db))
error=errno; error=errno;
strmov(db,thd->db); strmov(db,thd->db);
} }
@ -757,7 +759,8 @@ void MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
*end++=';'; *end++=';';
*end++='\n'; *end++='\n';
*end=0; *end=0;
if (fputs("SET ",file) < 0 || fputs(buff+1,file) < 0) if (my_b_write(&log_file,"SET ",4) ||
my_b_write(&log_file,buff+1,(uint) (end-buff)-1))
error=errno; error=errno;
} }
if (!query) if (!query)
@ -765,10 +768,9 @@ void MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
query="#adminstrator command"; query="#adminstrator command";
query_length=21; query_length=21;
} }
if (my_fwrite(file,(byte*) query,query_length,MYF(MY_NABP)) || if (my_b_write(&log_file,(byte*) query,query_length) ||
fputc(';',file) < 0 || fputc('\n',file) < 0) my_b_write(&log_file,";\n",2) ||
error=errno; flush_io_cache(&log_file))
if (fflush(file) < 0)
error=errno; error=errno;
if (error && ! write_error) if (error && ! write_error)
{ {
@ -780,51 +782,48 @@ void MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
} }
} }
#ifdef TO_BE_REMOVED
void MYSQL_LOG::flush() void MYSQL_LOG::flush()
{ {
if (file) if (is_open())
if (fflush(file) < 0 && ! write_error) if (flush_io_cache(log_file) && ! write_error)
{ {
write_error=1; write_error=1;
sql_print_error(ER(ER_ERROR_ON_WRITE),name,errno); sql_print_error(ER(ER_ERROR_ON_WRITE),name,errno);
} }
} }
#endif
void MYSQL_LOG::close(bool exiting) void MYSQL_LOG::close(bool exiting)
{ // One can't set log_type here! { // One can't set log_type here!
if (file) if (is_open())
{ {
File file=log_file.file;
if (log_type == LOG_BIN) if (log_type == LOG_BIN)
{ {
Stop_log_event s; Stop_log_event s;
s.write(file); s.write(&log_file);
VOID(pthread_cond_broadcast(&COND_binlog_update)); VOID(pthread_cond_broadcast(&COND_binlog_update));
} }
if (my_fclose(file,MYF(0)) < 0 && ! write_error) end_io_cache(&log_file);
if (my_close(file,MYF(0)) < 0 && ! write_error)
{ {
write_error=1; write_error=1;
sql_print_error(ER(ER_ERROR_ON_WRITE),name,errno); sql_print_error(ER(ER_ERROR_ON_WRITE),name,errno);
} }
file=0; log_type=LOG_CLOSED;
} }
if (name) if (exiting && index_file >= 0)
{ {
my_free(name,MYF(0)); if (my_close(index_file,MYF(0)) < 0 && ! write_error)
name=0;
}
if (exiting && index_file)
{
if (my_fclose(index_file,MYF(0)) < 0 && ! write_error)
{ {
write_error=1; write_error=1;
sql_print_error(ER(ER_ERROR_ON_WRITE),name,errno); sql_print_error(ER(ER_ERROR_ON_WRITE),name,errno);
} }
index_file=0; index_file=0;
} }
safeFree(name);
} }

View File

@ -26,84 +26,78 @@
static void pretty_print_char(FILE* file, int c) static void pretty_print_char(FILE* file, int c)
{ {
fputc('\'', file); fputc('\'', file);
switch(c) switch(c) {
{ case '\n': fprintf(file, "\\n"); break;
case '\n': fprintf(file, "\\n"); break; case '\r': fprintf(file, "\\r"); break;
case '\r': fprintf(file, "\\r"); break; case '\\': fprintf(file, "\\\\"); break;
case '\\': fprintf(file, "\\\\"); break; case '\b': fprintf(file, "\\b"); break;
case '\b': fprintf(file, "\\b"); break; case '\'': fprintf(file, "\\'"); break;
case '\'': fprintf(file, "\\'"); break; case 0 : fprintf(file, "\\0"); break;
case 0 : fprintf(file, "\\0"); break; default:
default: fputc(c, file);
fputc(c, file); break;
break; }
} fputc('\'', file);
fputc( '\'', file);
} }
int Query_log_event::write(FILE* 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(FILE* file) int Log_event::write(IO_CACHE* file)
{ {
if (write_header(file) return (write_header(file) || write_data(file)) ? -1 : 0;
|| write_data(file) || fflush(file)) return -1;
return 0;
} }
int Log_event::write_header(FILE* file) int Log_event::write_header(IO_CACHE* file)
{ {
char buf[LOG_EVENT_HEADER_LEN];
// make sure to change this when the header gets bigger // make sure to change this when the header gets bigger
char buf[LOG_EVENT_HEADER_LEN];
char* pos = buf; char* pos = buf;
int4store(pos, when); // timestamp int4store(pos, when); // timestamp
pos += 4; pos += 4;
*pos++ = get_type_code(); // event type code *pos++ = get_type_code(); // event type code
int4store(pos, server_id); int4store(pos, server_id);
pos += 4; pos += 4;
int4store(pos, get_data_size() + LOG_EVENT_HEADER_LEN); long tmp=get_data_size() + LOG_EVENT_HEADER_LEN;
int4store(pos, tmp);
pos += 4; pos += 4;
return (my_fwrite(file, (byte*) buf, (uint) (pos - buf), return (my_b_write(file, (byte*) buf, (uint) (pos - buf)));
MYF(MY_NABP | MY_WME)));
} }
#ifndef MYSQL_CLIENT #ifndef MYSQL_CLIENT
int Log_event::read_log_event(FILE* file, String* packet, 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;
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_fread(file, (byte*)buf, sizeof(buf), MYF(MY_NABP))) if (my_b_read(file, (byte*) buf, sizeof(buf)))
{ {
if(log_lock) pthread_mutex_unlock(log_lock); if (log_lock) pthread_mutex_unlock(log_lock);
return feof(file) ? LOG_READ_EOF: LOG_READ_IO; return file->error >= 0 ? LOG_READ_TRUNC: LOG_READ_IO;
} }
data_len = uint4korr(buf + EVENT_LEN_OFFSET); data_len = uint4korr(buf + EVENT_LEN_OFFSET);
if (data_len < LOG_EVENT_HEADER_LEN || data_len > MAX_EVENT_LEN) if (data_len < LOG_EVENT_HEADER_LEN || data_len > MAX_EVENT_LEN)
{ {
if(log_lock) pthread_mutex_unlock(log_lock); if (log_lock) pthread_mutex_unlock(log_lock);
return LOG_READ_BOGUS; return LOG_READ_BOGUS;
} }
packet->append(buf, sizeof(buf)); packet->append(buf, sizeof(buf));
data_len -= LOG_EVENT_HEADER_LEN; data_len -= LOG_EVENT_HEADER_LEN;
if (!data_len) if (data_len)
{ {
if(log_lock) pthread_mutex_unlock(log_lock); if (packet->append(file, data_len))
return 0; // the event does not have a data section
}
if (packet->append(file, data_len, MYF(MY_WME|MY_NABP)))
{ {
if(log_lock) if(log_lock)
pthread_mutex_unlock(log_lock); pthread_mutex_unlock(log_lock);
return feof(file) ? LOG_READ_TRUNC: LOG_READ_IO; return file->error >= 0 ? LOG_READ_TRUNC: LOG_READ_IO;
} }
}
if(log_lock) pthread_mutex_unlock(log_lock); if (log_lock) pthread_mutex_unlock(log_lock);
return 0; return 0;
} }
@ -111,18 +105,18 @@ int Log_event::read_log_event(FILE* file, String* packet,
// allocates memory - the caller is responsible for clean-up // allocates memory - the caller is responsible for clean-up
Log_event* Log_event::read_log_event(FILE* file, pthread_mutex_t* log_lock) Log_event* Log_event::read_log_event(IO_CACHE* file, pthread_mutex_t* log_lock)
{ {
time_t timestamp; time_t timestamp;
uint32 server_id; uint32 server_id;
char buf[LOG_EVENT_HEADER_LEN-4]; char buf[LOG_EVENT_HEADER_LEN-4];
if(log_lock) pthread_mutex_lock(log_lock); if(log_lock) pthread_mutex_lock(log_lock);
if (my_fread(file, (byte *) buf, sizeof(buf), MY_NABP)) if (my_b_read(file, (byte *) buf, sizeof(buf)))
{ {
if(log_lock) pthread_mutex_unlock(log_lock); if (log_lock) pthread_mutex_unlock(log_lock);
return NULL; return NULL;
} }
timestamp = uint4korr(buf); timestamp = uint4korr(buf);
server_id = uint4korr(buf + 5); server_id = uint4korr(buf + 5);
@ -132,13 +126,11 @@ Log_event* Log_event::read_log_event(FILE* file, pthread_mutex_t* log_lock)
{ {
Query_log_event* q = new Query_log_event(file, timestamp, server_id); Query_log_event* q = new Query_log_event(file, timestamp, server_id);
if(log_lock) pthread_mutex_unlock(log_lock); if(log_lock) pthread_mutex_unlock(log_lock);
if (!q->query) if (!q->query)
{ {
delete q; delete q;
return NULL; q=NULL;
} }
return q; return q;
} }
@ -146,13 +138,11 @@ Log_event* Log_event::read_log_event(FILE* file, pthread_mutex_t* log_lock)
{ {
Load_log_event* l = new Load_log_event(file, timestamp, server_id); Load_log_event* l = new Load_log_event(file, timestamp, server_id);
if(log_lock) pthread_mutex_unlock(log_lock); if(log_lock) pthread_mutex_unlock(log_lock);
if (!l->table_name) if (!l->table_name)
{ {
delete l; delete l;
return NULL; l=NULL;
} }
return l; return l;
} }
@ -165,9 +155,8 @@ Log_event* Log_event::read_log_event(FILE* file, pthread_mutex_t* log_lock)
if (!r->new_log_ident) if (!r->new_log_ident)
{ {
delete r; delete r;
return NULL; r=NULL;
} }
return r; return r;
} }
@ -179,9 +168,8 @@ Log_event* Log_event::read_log_event(FILE* file, pthread_mutex_t* log_lock)
if (e->type == INVALID_INT_EVENT) if (e->type == INVALID_INT_EVENT)
{ {
delete e; delete e;
return NULL; e=NULL;
} }
return e; return e;
} }
@ -198,12 +186,11 @@ Log_event* Log_event::read_log_event(FILE* file, pthread_mutex_t* log_lock)
return e; return e;
} }
default: default:
if(log_lock) pthread_mutex_unlock(log_lock); break;
return NULL;
} }
//impossible // default
if(log_lock) pthread_mutex_unlock(log_lock); if (log_lock) pthread_mutex_unlock(log_lock);
return NULL; return NULL;
} }
@ -323,26 +310,24 @@ void Rotate_log_event::print(FILE* file, bool short_form)
fflush(file); fflush(file);
} }
Rotate_log_event::Rotate_log_event(FILE* file, time_t when_arg, Rotate_log_event::Rotate_log_event(IO_CACHE* file, time_t when_arg,
uint32 server_id): uint32 server_id):
Log_event(when_arg, 0, 0, server_id),new_log_ident(NULL),alloced(0) Log_event(when_arg, 0, 0, server_id),new_log_ident(NULL),alloced(0)
{ {
char *tmp_ident; char *tmp_ident;
char buf[4]; char buf[4];
if (my_fread(file, (byte*) buf, sizeof(buf), MYF(MY_NABP | MY_WME))) if (my_b_read(file, (byte*) buf, sizeof(buf)))
return; return;
ulong event_len; ulong event_len;
event_len = uint4korr(buf); event_len = uint4korr(buf);
if(event_len < ROTATE_EVENT_OVERHEAD) if (event_len < ROTATE_EVENT_OVERHEAD)
return; return;
ident_len = (uchar)(event_len - ROTATE_EVENT_OVERHEAD); ident_len = (uchar)(event_len - ROTATE_EVENT_OVERHEAD);
if (!(tmp_ident = (char*) my_malloc((uint)ident_len, MYF(MY_WME)))) if (!(tmp_ident = (char*) my_malloc((uint)ident_len, MYF(MY_WME))))
return; return;
if (my_fread( file, (byte*) tmp_ident, (uint)ident_len, MYF(MY_NABP | MY_WME))) if (my_b_read( file, (byte*) tmp_ident, (uint) ident_len))
{ {
my_free((gptr) tmp_ident, MYF(0)); my_free((gptr) tmp_ident, MYF(0));
return; return;
@ -376,21 +361,18 @@ Rotate_log_event::Rotate_log_event(const char* buf, int event_len):
alloced = 1; alloced = 1;
} }
int Rotate_log_event::write_data(FILE* file) int Rotate_log_event::write_data(IO_CACHE* file)
{ {
if (my_fwrite(file, (byte*) new_log_ident, (uint) ident_len, return my_b_write(file, (byte*) new_log_ident, (uint) ident_len) ? -1 :0;
MYF(MY_NABP | MY_WME)))
return -1;
return 0;
} }
Query_log_event::Query_log_event(FILE* file, time_t when_arg, Query_log_event::Query_log_event(IO_CACHE* file, time_t when_arg,
uint32 server_id): uint32 server_id):
Log_event(when_arg,0,0,server_id),data_buf(0),query(NULL),db(NULL) Log_event(when_arg,0,0,server_id),data_buf(0),query(NULL),db(NULL)
{ {
char buf[QUERY_HEADER_LEN + 4]; char buf[QUERY_HEADER_LEN + 4];
ulong data_len; ulong data_len;
if (my_fread(file, (byte*) buf, sizeof(buf), MYF(MY_NABP | MY_WME))) if (my_b_read(file, (byte*) buf, sizeof(buf)))
return; // query == NULL will tell the return; // query == NULL will tell the
// caller there was a problem // caller there was a problem
data_len = uint4korr(buf); data_len = uint4korr(buf);
@ -402,9 +384,10 @@ Query_log_event::Query_log_event(FILE* file, time_t when_arg,
db_len = (uint)buf[12]; db_len = (uint)buf[12];
error_code = uint2korr(buf + 13); error_code = uint2korr(buf + 13);
/* Allocate one byte extra for end \0 */
if (!(data_buf = (char*) my_malloc(data_len+1, MYF(MY_WME)))) if (!(data_buf = (char*) my_malloc(data_len+1, MYF(MY_WME))))
return; return;
if (my_fread( file, (byte*) data_buf, data_len, MYF(MY_NABP | MY_WME))) if (my_b_read( file, (byte*) data_buf, data_len))
{ {
my_free((gptr) data_buf, MYF(0)); my_free((gptr) data_buf, MYF(0));
data_buf = 0; data_buf = 0;
@ -415,7 +398,7 @@ Query_log_event::Query_log_event(FILE* file, time_t when_arg,
db = data_buf; db = data_buf;
query=data_buf + db_len + 1; query=data_buf + db_len + 1;
q_len = data_len - 1 - db_len; q_len = data_len - 1 - db_len;
*((char*)query + q_len) = 0; *((char*) query + q_len) = 0; // Safety
} }
Query_log_event::Query_log_event(const char* buf, int event_len): Query_log_event::Query_log_event(const char* buf, int event_len):
@ -430,7 +413,7 @@ Query_log_event::Query_log_event(const char* buf, int event_len):
exec_time = uint4korr(buf + 8); exec_time = uint4korr(buf + 8);
error_code = uint2korr(buf + 13); error_code = uint2korr(buf + 13);
if (!(data_buf = (char*) my_malloc( data_len + 1, MYF(MY_WME)))) if (!(data_buf = (char*) my_malloc(data_len + 1, MYF(MY_WME))))
return; return;
memcpy(data_buf, buf + QUERY_HEADER_LEN + 4, data_len); memcpy(data_buf, buf + QUERY_HEADER_LEN + 4, data_len);
@ -457,9 +440,9 @@ void Query_log_event::print(FILE* file, bool short_form)
fprintf(file, ";\n"); fprintf(file, ";\n");
} }
int Query_log_event::write_data(FILE* 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];
char* pos = buf; char* pos = buf;
@ -471,23 +454,21 @@ int Query_log_event::write_data(FILE* file)
int2store(pos, error_code); int2store(pos, error_code);
pos += 2; pos += 2;
if (my_fwrite(file, (byte*) buf, (uint)(pos - buf), MYF(MY_NABP | MY_WME)) || return (my_b_write(file, (byte*) buf, (uint)(pos - buf)) ||
my_fwrite(file, (db) ? (byte*) db : (byte*)"", my_b_write(file, (db) ? (byte*) db : (byte*)"", db_len + 1) ||
db_len + 1, MYF(MY_NABP | MY_WME)) || my_b_write(file, (byte*) query, q_len)) ? -1 : 0;
my_fwrite(file, (byte*) query, q_len, MYF(MY_NABP | MY_WME)))
return -1;
return 0;
} }
Intvar_log_event:: Intvar_log_event(FILE* file, time_t when_arg, Intvar_log_event:: Intvar_log_event(IO_CACHE* file, time_t when_arg,
uint32 server_id) uint32 server_id)
:Log_event(when_arg,0,0,server_id), type(INVALID_INT_EVENT) :Log_event(when_arg,0,0,server_id), type(INVALID_INT_EVENT)
{ {
my_fseek(file, 4L, MY_SEEK_CUR, MYF(MY_WME)); // skip the event length char buf[9+4];
char buf[9]; if (!my_b_read(file, (byte*) buf, sizeof(buf)))
if(my_fread(file, (byte*)buf, sizeof(buf), MYF(MY_NABP|MY_WME))) return; {
type = buf[0]; type = buf[4];
val = uint8korr(buf+1); val = uint8korr(buf+1+4);
}
} }
Intvar_log_event::Intvar_log_event(const char* buf):Log_event(buf) Intvar_log_event::Intvar_log_event(const char* buf):Log_event(buf)
@ -497,12 +478,12 @@ Intvar_log_event::Intvar_log_event(const char* buf):Log_event(buf)
val = uint8korr(buf+1); val = uint8korr(buf+1);
} }
int Intvar_log_event::write_data(FILE* file) int Intvar_log_event::write_data(IO_CACHE* file)
{ {
char buf[9]; char buf[9];
buf[0] = type; buf[0] = type;
int8store(buf + 1, val); int8store(buf + 1, val);
return my_fwrite(file, (byte*) buf, sizeof(buf), MYF(MY_NABP|MY_WME)); return my_b_write(file, (byte*) buf, sizeof(buf));
} }
void Intvar_log_event::print(FILE* file, bool short_form) void Intvar_log_event::print(FILE* file, bool short_form)
@ -529,7 +510,7 @@ void Intvar_log_event::print(FILE* file, bool short_form)
} }
int Load_log_event::write_data(FILE* file __attribute__((unused))) int Load_log_event::write_data(IO_CACHE* file)
{ {
char buf[LOAD_HEADER_LEN]; char buf[LOAD_HEADER_LEN];
int4store(buf, thread_id); int4store(buf, thread_id);
@ -539,77 +520,46 @@ int Load_log_event::write_data(FILE* file __attribute__((unused)))
buf[13] = (char)db_len; buf[13] = (char)db_len;
int4store(buf + 14, num_fields); int4store(buf + 14, num_fields);
if(my_fwrite(file, (byte*)buf, sizeof(buf), MYF(MY_NABP|MY_WME)) || if(my_b_write(file, (byte*)buf, sizeof(buf)) ||
my_fwrite(file, (byte*)&sql_ex, sizeof(sql_ex), MYF(MY_NABP|MY_WME))) my_b_write(file, (byte*)&sql_ex, sizeof(sql_ex)))
return 1; return 1;
if(num_fields && fields && field_lens) if (num_fields && fields && field_lens)
{ {
if(my_fwrite(file, (byte*)field_lens, num_fields, MYF(MY_NABP|MY_WME)) || if(my_b_write(file, (byte*)field_lens, num_fields) ||
my_fwrite(file, (byte*)fields, field_block_len, MYF(MY_NABP|MY_WME))) my_b_write(file, (byte*)fields, field_block_len))
return 1; return 1;
} }
if(my_b_write(file, (byte*)table_name, table_name_len + 1) ||
if(my_fwrite(file, (byte*)table_name, table_name_len + 1, MYF(MY_NABP|MY_WME)) || my_b_write(file, (byte*)db, db_len + 1) ||
my_fwrite(file, (byte*)db, db_len + 1, MYF(MY_NABP|MY_WME)) || my_b_write(file, (byte*)fname, fname_len))
my_fwrite(file, (byte*)fname, fname_len, MYF(MY_NABP|MY_WME)) )
return 1; return 1;
return 0; return 0;
} }
Load_log_event::Load_log_event(FILE* file, time_t when, uint32 server_id): Load_log_event::Load_log_event(IO_CACHE* file, time_t when, uint32 server_id):
Log_event(when,0,0,server_id),data_buf(0),num_fields(0), Log_event(when,0,0,server_id),data_buf(0),num_fields(0),
fields(0),field_lens(0),field_block_len(0), fields(0),field_lens(0),field_block_len(0),
table_name(0),db(0),fname(0) table_name(0),db(0),fname(0)
{ {
char buf[LOAD_HEADER_LEN + 4]; char buf[LOAD_HEADER_LEN + 4];
ulong data_len; ulong data_len;
if(my_fread(file, (byte*)buf, sizeof(buf), MYF(MY_NABP|MY_WME)) || if (my_b_read(file, (byte*)buf, sizeof(buf)) ||
my_fread(file, (byte*)&sql_ex, sizeof(sql_ex), MYF(MY_NABP|MY_WME))) my_b_read(file, (byte*)&sql_ex, sizeof(sql_ex)))
return; return;
data_len = uint4korr(buf); data_len = uint4korr(buf) - LOAD_EVENT_OVERHEAD;
thread_id = uint4korr(buf+4); if (!(data_buf = (char*)my_malloc(data_len + 1, MYF(MY_WME))))
exec_time = uint4korr(buf+8);
skip_lines = uint4korr(buf + 12);
table_name_len = (uint)buf[16];
db_len = (uint)buf[17];
num_fields = uint4korr(buf + 18);
data_len -= LOAD_EVENT_OVERHEAD;
if(!(data_buf = (char*)my_malloc(data_len + 1, MYF(MY_WME))))
return; return;
if (my_b_read(file, (byte*)data_buf, data_len))
if(my_fread(file, (byte*)data_buf, data_len, MYF(MY_NABP|MY_WME)))
return; return;
copy_log_event(buf,data_len);
if(num_fields > data_len) // simple sanity check against corruption
return;
field_lens = (uchar*)data_buf;
uint i;
for(i = 0; i < num_fields; i++)
{
field_block_len += (uint)field_lens[i] + 1;
}
fields = (char*)field_lens + num_fields;
*((char*)data_buf+data_len) = 0;
table_name = fields + field_block_len;
db = table_name + table_name_len + 1;
fname = db + db_len + 1;
fname_len = data_len - 2 - db_len - table_name_len - num_fields - field_block_len;
} }
Load_log_event::Load_log_event(const char* buf, int event_len): Load_log_event::Load_log_event(const char* buf, int event_len):
Log_event(when,0,0,server_id),data_buf(0),num_fields(0),fields(0), Log_event(when,0,0,server_id),data_buf(0),num_fields(0),fields(0),
field_lens(0),field_block_len(0), field_lens(0),field_block_len(0),
table_name(0),db(0),fname(0) table_name(0),db(0),fname(0)
{ {
ulong data_len; ulong data_len;
@ -617,9 +567,16 @@ Load_log_event::Load_log_event(const char* buf, int event_len):
return; return;
buf += EVENT_LEN_OFFSET; buf += EVENT_LEN_OFFSET;
data_len = event_len; data_len = event_len;
if(!(data_buf = (char*)my_malloc(data_len + 1, MYF(MY_WME))))
return;
memcpy(data_buf, buf + 22 + sizeof(sql_ex), data_len);
copy_log_event(buf, data_len);
}
void Load_log_event::copy_log_event(const char *buf, ulong data_len)
{
thread_id = uint4korr(buf+4); thread_id = uint4korr(buf+4);
exec_time = uint4korr(buf+8); exec_time = uint4korr(buf+8);
skip_lines = uint4korr(buf + 12); skip_lines = uint4korr(buf + 12);
@ -627,32 +584,23 @@ Load_log_event::Load_log_event(const char* buf, int event_len):
db_len = (uint)buf[17]; db_len = (uint)buf[17];
num_fields = uint4korr(buf + 18); num_fields = uint4korr(buf + 18);
data_len -= LOAD_EVENT_OVERHEAD; if (num_fields > data_len) // simple sanity check against corruption
memcpy(&sql_ex, buf + 22, sizeof(sql_ex));
if(!(data_buf = (char*)my_malloc(data_len + 1, MYF(MY_WME))))
return; return;
memcpy(data_buf, buf + 22 + sizeof(sql_ex), data_len); field_lens = (uchar*) data_buf;
if(num_fields > data_len) // simple sanity check against corruption
return;
field_lens = (uchar*)data_buf;
uint i; uint i;
for(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;
*((char*)data_buf+data_len) = 0; *((char*)data_buf+data_len) = 0;
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;
fname = db + db_len + 1; fname = db + db_len + 1;
fname_len = data_len - 2 - db_len - table_name_len - num_fields - field_block_len; fname_len = data_len - 2 - db_len - table_name_len - num_fields -
field_block_len;
} }
@ -711,21 +659,21 @@ void Load_log_event::print(FILE* file, bool short_form)
if((int)skip_lines > 0) if((int)skip_lines > 0)
fprintf(file, " IGNORE %ld LINES ", skip_lines); fprintf(file, " IGNORE %ld LINES ", skip_lines);
if(num_fields) if (num_fields)
{
uint i;
const char* field = fields;
fprintf( file, " (");
for(i = 0; i < num_fields; i++)
{ {
uint i; if(i)
const char* field = fields; fputc(',', file);
fprintf( file, " ("); fprintf(file, field);
for(i = 0; i < num_fields; i++)
{
if(i)
fputc(',', file);
fprintf(file, field);
field += field_lens[i] + 1; field += field_lens[i] + 1;
}
fputc(')', file);
} }
fputc(')', file);
}
fprintf(file, ";\n"); fprintf(file, ";\n");
} }

View File

@ -65,9 +65,9 @@ public:
int valid_exec_time; // if false, the exec time setting is bogus int valid_exec_time; // if false, the exec time setting is bogus
uint32 server_id; uint32 server_id;
int write(FILE* file); int write(IO_CACHE* file);
int write_header(FILE* file); int write_header(IO_CACHE* file);
virtual int write_data(FILE* file __attribute__((unused))) { return 0; } virtual int write_data(IO_CACHE* file __attribute__((unused))) { return 0; }
virtual Log_event_type get_type_code() = 0; virtual Log_event_type get_type_code() = 0;
Log_event(time_t when_arg, ulong exec_time_arg = 0, Log_event(time_t when_arg, ulong exec_time_arg = 0,
int valid_exec_time_arg = 0, uint32 server_id = 0): when(when_arg), int valid_exec_time_arg = 0, uint32 server_id = 0): when(when_arg),
@ -92,11 +92,11 @@ public:
void print_header(FILE* file); void print_header(FILE* file);
// if mutex is 0, the read will proceed without mutex // if mutex is 0, the read will proceed without mutex
static Log_event* read_log_event(FILE* file, pthread_mutex_t* log_lock); static Log_event* read_log_event(IO_CACHE* file, pthread_mutex_t* log_lock);
static Log_event* read_log_event(const char* buf, int event_len); static Log_event* read_log_event(const char* buf, int event_len);
#ifndef MYSQL_CLIENT #ifndef MYSQL_CLIENT
static int read_log_event(FILE* file, String* packet, static int read_log_event(IO_CACHE* file, String* packet,
pthread_mutex_t* log_lock); pthread_mutex_t* log_lock);
#endif #endif
@ -132,18 +132,18 @@ public:
} }
#endif #endif
Query_log_event(FILE* file, time_t when, uint32 server_id); Query_log_event(IO_CACHE* file, time_t when, uint32 server_id);
Query_log_event(const char* buf, int event_len); Query_log_event(const char* buf, int event_len);
~Query_log_event() ~Query_log_event()
{ {
if (data_buf) if (data_buf)
{ {
my_free((gptr)data_buf, MYF(0)); my_free((gptr) data_buf, MYF(0));
} }
} }
Log_event_type get_type_code() { return QUERY_EVENT; } Log_event_type get_type_code() { return QUERY_EVENT; }
int write(FILE* file); int write(IO_CACHE* file);
int write_data(FILE* file); // returns 0 on success, -1 on error int write_data(IO_CACHE* file); // returns 0 on success, -1 on error
int get_data_size() int get_data_size()
{ {
return q_len + db_len + 2 + return q_len + db_len + 2 +
@ -183,6 +183,8 @@ class Load_log_event: public Log_event
{ {
protected: protected:
char* data_buf; char* data_buf;
void Load_log_event::copy_log_event(const char *buf, ulong data_len);
public: public:
int thread_id; int thread_id;
uint32 table_name_len; uint32 table_name_len;
@ -272,17 +274,17 @@ public:
void set_fields(List<Item> &fields); void set_fields(List<Item> &fields);
#endif #endif
Load_log_event(FILE* file, time_t when, uint32 server_id); Load_log_event(IO_CACHE * file, time_t when, uint32 server_id);
Load_log_event(const char* buf, int event_len); Load_log_event(const char* buf, int event_len);
~Load_log_event() ~Load_log_event()
{ {
if (data_buf) if (data_buf)
{ {
my_free((gptr)data_buf, MYF(0)); my_free((gptr) data_buf, MYF(0));
} }
} }
Log_event_type get_type_code() { return LOAD_EVENT; } Log_event_type get_type_code() { return LOAD_EVENT; }
int write_data(FILE* file); // returns 0 on success, -1 on error int write_data(IO_CACHE* file); // returns 0 on success, -1 on error
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
@ -311,30 +313,26 @@ public:
created = (uint32) when; created = (uint32) when;
memcpy(server_version, ::server_version, sizeof(server_version)); memcpy(server_version, ::server_version, sizeof(server_version));
} }
Start_log_event(FILE* file, time_t when_arg, uint32 server_id) : Start_log_event(IO_CACHE* file, time_t when_arg, uint32 server_id) :
Log_event(when_arg, 0, 0, server_id) Log_event(when_arg, 0, 0, server_id)
{ {
char buf[sizeof(server_version) + sizeof(binlog_version) + char buf[sizeof(server_version) + sizeof(binlog_version) +
sizeof(created)]; sizeof(created)+4];
my_fseek(file, 4L, MY_SEEK_CUR, MYF(MY_WME)); // skip the event length if (my_b_read(file, (byte*) buf, sizeof(buf)))
if (my_fread(file, (byte*) buf, sizeof(buf), MYF(MY_NABP | MY_WME)))
return; return;
binlog_version = uint2korr(buf); binlog_version = uint2korr(buf+4);
memcpy(server_version, buf + 2, sizeof(server_version)); memcpy(server_version, buf + 6, sizeof(server_version));
created = uint4korr(buf + 2 + sizeof(server_version)); created = uint4korr(buf + 6 + sizeof(server_version));
} }
Start_log_event(const char* buf); Start_log_event(const char* buf);
~Start_log_event() {} ~Start_log_event() {}
Log_event_type get_type_code() { return START_EVENT;} Log_event_type get_type_code() { return START_EVENT;}
int write_data(FILE* file) int write_data(IO_CACHE* file)
{ {
if(my_fwrite(file, (byte*) &binlog_version, sizeof(binlog_version), if (my_b_write(file, (byte*) &binlog_version, sizeof(binlog_version)) ||
MYF(MY_NABP | MY_WME)) || my_b_write(file, (byte*) server_version, sizeof(server_version)) ||
my_fwrite(file, (byte*) server_version, sizeof(server_version), my_b_write(file, (byte*) &created, sizeof(created)))
MYF(MY_NABP | MY_WME)) ||
my_fwrite(file, (byte*) &created, sizeof(created),
MYF(MY_NABP | MY_WME)))
return -1; return -1;
return 0; return 0;
} }
@ -354,12 +352,12 @@ public:
Intvar_log_event(uchar type_arg, ulonglong val_arg) Intvar_log_event(uchar type_arg, ulonglong val_arg)
:Log_event(time(NULL)),val(val_arg),type(type_arg) :Log_event(time(NULL)),val(val_arg),type(type_arg)
{} {}
Intvar_log_event(FILE* file, time_t when, uint32 server_id); Intvar_log_event(IO_CACHE* file, time_t when, uint32 server_id);
Intvar_log_event(const char* buf); Intvar_log_event(const char* buf);
~Intvar_log_event() {} ~Intvar_log_event() {}
Log_event_type get_type_code() { return INTVAR_EVENT;} Log_event_type get_type_code() { return INTVAR_EVENT;}
int get_data_size() { return sizeof(type) + sizeof(val);} int get_data_size() { return sizeof(type) + sizeof(val);}
int write_data(FILE* file); int write_data(IO_CACHE* file);
void print(FILE* file, bool short_form = 0); void print(FILE* file, bool short_form = 0);
@ -370,10 +368,11 @@ class Stop_log_event: public Log_event
public: public:
Stop_log_event() :Log_event(time(NULL)) Stop_log_event() :Log_event(time(NULL))
{} {}
Stop_log_event(FILE* file, time_t when_arg, uint32 server_id): Stop_log_event(IO_CACHE* file, time_t when_arg, uint32 server_id):
Log_event(when_arg,0,0,server_id) Log_event(when_arg,0,0,server_id)
{ {
my_fseek(file, 4L, MY_SEEK_CUR, MYF(MY_WME)); // skip the event length char skip[4];
my_b_read(file, skip, sizeof(skip)); // skip the event length
} }
Stop_log_event(const char* buf):Log_event(buf) Stop_log_event(const char* buf):Log_event(buf)
{ {
@ -397,7 +396,7 @@ public:
alloced(0) alloced(0)
{} {}
Rotate_log_event(FILE* file, time_t when, uint32 server_id) ; Rotate_log_event(IO_CACHE* file, time_t when, uint32 server_id) ;
Rotate_log_event(const char* buf, int event_len); Rotate_log_event(const char* buf, int event_len);
~Rotate_log_event() ~Rotate_log_event()
{ {
@ -406,7 +405,7 @@ public:
} }
Log_event_type get_type_code() { return ROTATE_EVENT;} Log_event_type get_type_code() { return ROTATE_EVENT;}
int get_data_size() { return ident_len;} int get_data_size() { return ident_len;}
int write_data(FILE* file); int write_data(IO_CACHE* file);
void print(FILE* file, bool short_form = 0); void print(FILE* file, bool short_form = 0);
}; };

View File

@ -32,17 +32,19 @@
#define MAP_TO_USE_RAID #define MAP_TO_USE_RAID
#include "mysql_priv.h" #include "mysql_priv.h"
#include <mysys_err.h>
#ifdef HAVE_AIOWAIT #ifdef HAVE_AIOWAIT
#include <mysys_err.h>
#include <errno.h> #include <errno.h>
static void my_aiowait(my_aio_result *result); static void my_aiowait(my_aio_result *result);
#endif #endif
/* if cachesize == 0 then use default cachesize (from s-file) */
/* returns 0 if we have enough memory */
extern "C" { extern "C" {
/*
** if cachesize == 0 then use default cachesize (from s-file)
** if file == -1 then real_open_cached_file() will be called.
** returns 0 if ok
*/
int init_io_cache(IO_CACHE *info, File file, uint cachesize, int init_io_cache(IO_CACHE *info, File file, uint cachesize,
enum cache_type type, my_off_t seek_offset, enum cache_type type, my_off_t seek_offset,
@ -60,20 +62,26 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize,
min_cache=use_async_io ? IO_SIZE*4 : IO_SIZE*2; min_cache=use_async_io ? IO_SIZE*4 : IO_SIZE*2;
if (type == READ_CACHE) if (type == READ_CACHE)
{ /* Assume file isn't growing */ { /* Assume file isn't growing */
my_off_t file_pos,end_of_file; if (cache_myflags & MY_DONT_CHECK_FILESIZE)
if ((file_pos=my_tell(file,MYF(0)) == MY_FILEPOS_ERROR))
DBUG_RETURN(1);
end_of_file=my_seek(file,0L,MY_SEEK_END,MYF(0));
if (end_of_file < seek_offset)
end_of_file=seek_offset;
VOID(my_seek(file,file_pos,MY_SEEK_SET,MYF(0)));
if ((my_off_t) cachesize > end_of_file-seek_offset+IO_SIZE*2-1)
{ {
cachesize=(uint) (end_of_file-seek_offset)+IO_SIZE*2-1; cache_myflags &= ~MY_DONT_CHECK_FILESIZE;
use_async_io=0; /* No nead to use async */ }
else
{
my_off_t file_pos,end_of_file;
if ((file_pos=my_tell(file,MYF(0)) == MY_FILEPOS_ERROR))
DBUG_RETURN(1);
end_of_file=my_seek(file,0L,MY_SEEK_END,MYF(0));
if (end_of_file < seek_offset)
end_of_file=seek_offset;
VOID(my_seek(file,file_pos,MY_SEEK_SET,MYF(0)));
if ((my_off_t) cachesize > end_of_file-seek_offset+IO_SIZE*2-1)
{
cachesize=(uint) (end_of_file-seek_offset)+IO_SIZE*2-1;
use_async_io=0; /* No nead to use async */
}
} }
} }
if ((int) type < (int) READ_NET) if ((int) type < (int) READ_NET)
{ {
for (;;) for (;;)
@ -167,7 +175,8 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
DBUG_ENTER("reinit_io_cache"); DBUG_ENTER("reinit_io_cache");
info->seek_not_done= test(info->file >= 0); /* Seek not done */ info->seek_not_done= test(info->file >= 0); /* Seek not done */
if (!clear_cache && seek_offset >= info->pos_in_file && if (! clear_cache &&
seek_offset >= info->pos_in_file &&
seek_offset <= info->pos_in_file + seek_offset <= info->pos_in_file +
(uint) (info->rc_end - info->rc_request_pos)) (uint) (info->rc_end - info->rc_request_pos))
{ /* use current buffer */ { /* use current buffer */
@ -231,6 +240,7 @@ int _my_b_read(register IO_CACHE *info, byte *Buffer, uint Count)
{ {
uint length,diff_length,left_length; uint length,diff_length,left_length;
my_off_t max_length, pos_in_file; my_off_t max_length, pos_in_file;
memcpy(Buffer,info->rc_pos, memcpy(Buffer,info->rc_pos,
(size_t) (left_length=(uint) (info->rc_end-info->rc_pos))); (size_t) (left_length=(uint) (info->rc_end-info->rc_pos)));
Buffer+=left_length; Buffer+=left_length;
@ -607,7 +617,9 @@ int flush_io_cache(IO_CACHE *info)
length=(uint) (info->rc_pos - info->buffer); length=(uint) (info->rc_pos - info->buffer);
if (info->seek_not_done) if (info->seek_not_done)
{ /* File touched, do seek */ { /* File touched, do seek */
VOID(my_seek(info->file,info->pos_in_file,MY_SEEK_SET,MYF(0))); if (my_seek(info->file,info->pos_in_file,MY_SEEK_SET,MYF(0)) ==
MY_FILEPOS_ERROR)
DBUG_RETURN((info->error= -1));
info->seek_not_done=0; info->seek_not_done=0;
} }
info->rc_pos=info->buffer; info->rc_pos=info->buffer;
@ -644,4 +656,4 @@ int end_io_cache(IO_CACHE *info)
DBUG_RETURN(error); DBUG_RETURN(error);
} /* end_io_cache */ } /* end_io_cache */
} } /* extern "C" */

View File

@ -55,7 +55,7 @@ static struct option long_options[] =
{"password", required_argument,0, 'p'}, {"password", required_argument,0, 'p'},
{"position", required_argument,0, 'j'}, {"position", required_argument,0, 'j'},
#ifndef DBUG_OFF #ifndef DBUG_OFF
{"debug", required_argument, 0, '#'} {"debug", optional_argument, 0, '#'}
#endif #endif
}; };
@ -151,7 +151,7 @@ static int parse_args(int *argc, char*** argv)
{ {
int c, opt_index = 0; int c, opt_index = 0;
while((c = getopt_long(*argc, *argv, "so:#:h:j:u:p:P:t:?", long_options, while((c = getopt_long(*argc, *argv, "so:#::h:j:u:p:P:t:?", long_options,
&opt_index)) != EOF) &opt_index)) != EOF)
{ {
switch(c) switch(c)
@ -310,86 +310,106 @@ Unfortunately, no sweepstakes today, adjusted position to 4\n");
static void dump_local_log_entries(const char* logname) static void dump_local_log_entries(const char* logname)
{ {
FILE* file; File fd;
int rec_count = 0; IO_CACHE cache,*file= &cache;
int rec_count = 0;
if(logname && logname[0] != '-') if (logname && logname[0] != '-')
file = my_fopen(logname, O_RDONLY|O_BINARY, MYF(MY_WME)); {
else if ((fd = my_open(logname, O_RDONLY | O_BINARY, MYF(MY_WME))) < 0)
file = stdin; exit(1);
if (init_io_cache(file, fd, 0, READ_CACHE, (my_off_t) position, 0,
MYF(MY_WME | MY_NABP)))
exit(1);
}
else
{
if (init_io_cache(file, fileno(stdout), 0, READ_CACHE, (my_off_t) 0,
0, MYF(MY_WME | MY_NABP | MY_DONT_CHECK_FILESIZE)))
exit(1);
if (position)
{
/* skip 'position' characters from stdout */
char buff[IO_SIZE];
my_off_t length,tmp;
for (length=position ; length > 0 ; length-=tmp)
{
tmp=min(length,sizeof(buff));
if (my_b_read(file,buff,tmp))
exit(1);
}
}
file->pos_in_file=position;
file->seek_not_done=0;
}
if(!file) if (!position)
die("Could not open log file %s", logname); {
char magic[4];
if(my_fseek(file, position, MY_SEEK_SET, MYF(MY_WME)) == MY_FILEPOS_ERROR) if (my_b_read(file, (byte*) magic, sizeof(magic)))
die("failed on my_fseek()"); die("I/O error reading binlog magic number");
if(memcmp(magic, BINLOG_MAGIC, 4))
if(!position) die("Bad magic number");
{
char magic[4];
if (my_fread(file, (byte*) magic, sizeof(magic), MYF(MY_NABP|MY_WME)))
die("I/O error reading binlog magic number");
if(memcmp(magic, BINLOG_MAGIC, 4))
die("Bad magic number");
} }
while(1) while(1)
{ {
Log_event* ev = Log_event::read_log_event(file, 0); Log_event* ev = Log_event::read_log_event(file, 0);
if(!ev) if (!ev)
if(!feof(file)) {
if (file->error)
die("Could not read entry at offset %ld : Error in log format or \ die("Could not read entry at offset %ld : Error in log format or \
read error", read error",
my_ftell(file, MYF(MY_WME))); my_b_tell(file));
else break;
break; }
if (rec_count >= offset)
if(rec_count >= offset) ev->print(stdout, short_form);
ev->print(stdout, short_form); rec_count++;
rec_count++; delete ev;
delete ev; }
} my_close(fd, MYF(MY_WME));
end_io_cache(file);
my_fclose(file, MYF(MY_WME));
} }
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
MY_INIT(argv[0]); MY_INIT(argv[0]);
parse_args(&argc, (char***)&argv); parse_args(&argc, (char***)&argv);
if(!argc && !table) if(!argc && !table)
{ {
usage(); usage();
return -1; return -1;
} }
if(use_remote) if(use_remote)
{ {
init_thr_alarm(10); // need to do this manually init_thr_alarm(10); // need to do this manually
mysql = safe_connect(); mysql = safe_connect();
} }
if(table) if (table)
{ {
if(!use_remote) if(!use_remote)
die("You must specify connection parameter to get table dump"); die("You must specify connection parameter to get table dump");
char* db = (char*)table; char* db = (char*)table;
char* tbl = (char*) strchr(table, '.'); char* tbl = (char*) strchr(table, '.');
if(!tbl) if(!tbl)
die("You must use database.table syntax to specify the table"); die("You must use database.table syntax to specify the table");
*tbl++ = 0; *tbl++ = 0;
dump_remote_table(&mysql->net, db, tbl); dump_remote_table(&mysql->net, db, tbl);
} }
else else
while(--argc >= 0) {
while(--argc >= 0)
{ {
dump_log_entries(*(argv++)); dump_log_entries(*(argv++));
} }
}
if(use_remote) if (use_remote)
mc_mysql_close(mysql); mc_mysql_close(mysql);
return 0; return 0;
} }

View File

@ -131,7 +131,7 @@ extern "C" int gethostname(char *name, int namelen);
#ifndef DBUG_OFF #ifndef DBUG_OFF
static const char* default_dbug_option=IF_WIN("d:t:i:O,\\mysqld.trace", static const char* default_dbug_option=IF_WIN("d:t:i:O,\\mysqld.trace",
"d:t:i:o,/tmp/mysqld.trace"); "d:t:i:o,/tmp/mysqld.trace");
#endif #endif
#ifdef __NT__ #ifdef __NT__
@ -157,7 +157,7 @@ static pthread_t select_thread;
static pthread_t flush_thread; // Used when debugging static pthread_t flush_thread; // Used when debugging
static bool opt_log,opt_update_log,opt_bin_log,opt_slow_log,opt_noacl, static bool opt_log,opt_update_log,opt_bin_log,opt_slow_log,opt_noacl,
opt_disable_networking=0, opt_bootstrap=0,opt_skip_show_db=0, opt_disable_networking=0, opt_bootstrap=0,opt_skip_show_db=0,
opt_ansi_mode=0,opt_myisam_log=0; opt_ansi_mode=0,opt_myisam_log=0, opt_large_files=sizeof(my_off_t) > 4;
bool opt_sql_bin_update = 0, opt_log_slave_updates = 0; bool opt_sql_bin_update = 0, opt_log_slave_updates = 0;
extern MASTER_INFO glob_mi; extern MASTER_INFO glob_mi;
extern int init_master_info(MASTER_INFO* mi); extern int init_master_info(MASTER_INFO* mi);
@ -579,8 +579,8 @@ void unireg_abort(int exit_code)
{ {
if (exit_code) if (exit_code)
sql_print_error("Aborting\n"); sql_print_error("Aborting\n");
(void) my_delete(pidfile_name,MYF(0)); // This may not always exist
clean_up(); /* purecov: inspected */ clean_up(); /* purecov: inspected */
(void) my_delete(pidfile_name,MYF(0)); // This may not always exist
exit(exit_code); /* purecov: inspected */ exit(exit_code); /* purecov: inspected */
} }
@ -2436,20 +2436,21 @@ struct show_var_st init_vars[]= {
#endif #endif
{"character_set", default_charset, SHOW_CHAR}, {"character_set", default_charset, SHOW_CHAR},
{"character_sets", (char*) &charsets_list, SHOW_CHAR_PTR}, {"character_sets", (char*) &charsets_list, SHOW_CHAR_PTR},
{"connect_timeout", (char*) &connect_timeout, SHOW_LONG},
{"concurrent_insert", (char*) &myisam_concurrent_insert, SHOW_MY_BOOL}, {"concurrent_insert", (char*) &myisam_concurrent_insert, SHOW_MY_BOOL},
{"connect_timeout", (char*) &connect_timeout, SHOW_LONG},
{"datadir", mysql_real_data_home, SHOW_CHAR}, {"datadir", mysql_real_data_home, SHOW_CHAR},
{"delay_key_write", (char*) &myisam_delay_key_write, SHOW_MY_BOOL}, {"delay_key_write", (char*) &myisam_delay_key_write, SHOW_MY_BOOL},
{"delayed_insert_limit", (char*) &delayed_insert_limit, SHOW_LONG}, {"delayed_insert_limit", (char*) &delayed_insert_limit, SHOW_LONG},
{"delayed_insert_timeout", (char*) &delayed_insert_timeout, SHOW_LONG}, {"delayed_insert_timeout", (char*) &delayed_insert_timeout, SHOW_LONG},
{"delayed_queue_size", (char*) &delayed_queue_size, SHOW_LONG}, {"delayed_queue_size", (char*) &delayed_queue_size, SHOW_LONG},
{"join_buffer_size", (char*) &join_buff_size, SHOW_LONG},
{"flush", (char*) &myisam_flush, SHOW_MY_BOOL}, {"flush", (char*) &myisam_flush, SHOW_MY_BOOL},
{"flush_time", (char*) &flush_time, SHOW_LONG}, {"flush_time", (char*) &flush_time, SHOW_LONG},
{"init_file", (char*) &opt_init_file, SHOW_CHAR_PTR}, {"init_file", (char*) &opt_init_file, SHOW_CHAR_PTR},
{"interactive_timeout", (char*) &net_interactive_timeout, SHOW_LONG}, {"interactive_timeout", (char*) &net_interactive_timeout, SHOW_LONG},
{"join_buffer_size", (char*) &join_buff_size, SHOW_LONG},
{"key_buffer_size", (char*) &keybuff_size, SHOW_LONG}, {"key_buffer_size", (char*) &keybuff_size, SHOW_LONG},
{"language", language, SHOW_CHAR}, {"language", language, SHOW_CHAR},
{"large_files_support", (char*) &opt_large_files, SHOW_BOOL},
#ifdef HAVE_MLOCKALL #ifdef HAVE_MLOCKALL
{"locked_in_memory", (char*) &locked_in_memory, SHOW_BOOL}, {"locked_in_memory", (char*) &locked_in_memory, SHOW_BOOL},
#endif #endif
@ -2472,12 +2473,15 @@ struct show_var_st init_vars[]= {
{"myisam_recover_options", (char*) &myisam_recover_options_str, SHOW_CHAR_PTR}, {"myisam_recover_options", (char*) &myisam_recover_options_str, SHOW_CHAR_PTR},
{"myisam_sort_buffer_size", (char*) &myisam_sort_buffer_size, SHOW_LONG}, {"myisam_sort_buffer_size", (char*) &myisam_sort_buffer_size, SHOW_LONG},
{"net_buffer_length", (char*) &net_buffer_length, SHOW_LONG}, {"net_buffer_length", (char*) &net_buffer_length, SHOW_LONG},
{"net_read_timeout", (char*) &net_read_timeout, SHOW_LONG},
{"net_retry_count", (char*) &mysqld_net_retry_count, SHOW_LONG}, {"net_retry_count", (char*) &mysqld_net_retry_count, SHOW_LONG},
{"net_write_timeout", (char*) &net_write_timeout, SHOW_LONG},
{"pid_file", (char*) pidfile_name, SHOW_CHAR}, {"pid_file", (char*) pidfile_name, SHOW_CHAR},
{"port", (char*) &mysql_port, SHOW_INT}, {"port", (char*) &mysql_port, SHOW_INT},
{"protocol_version", (char*) &protocol_version, SHOW_INT}, {"protocol_version", (char*) &protocol_version, SHOW_INT},
{"record_buffer", (char*) &my_default_record_cache_size,SHOW_LONG}, {"record_buffer", (char*) &my_default_record_cache_size,SHOW_LONG},
{"server_id", (char*) &server_id, SHOW_LONG}, {"query_buffer_size", (char*) &query_buff_size, SHOW_LONG},
{"server_id", (char*) &server_id, SHOW_LONG},
{"skip_locking", (char*) &my_disable_locking, SHOW_MY_BOOL}, {"skip_locking", (char*) &my_disable_locking, SHOW_MY_BOOL},
{"skip_networking", (char*) &opt_disable_networking, SHOW_BOOL}, {"skip_networking", (char*) &opt_disable_networking, SHOW_BOOL},
{"skip_show_database", (char*) &opt_skip_show_db, SHOW_BOOL}, {"skip_show_database", (char*) &opt_skip_show_db, SHOW_BOOL},
@ -2486,11 +2490,11 @@ struct show_var_st init_vars[]= {
{"sort_buffer", (char*) &sortbuff_size, SHOW_LONG}, {"sort_buffer", (char*) &sortbuff_size, SHOW_LONG},
{"table_cache", (char*) &table_cache_size, SHOW_LONG}, {"table_cache", (char*) &table_cache_size, SHOW_LONG},
{"table_type", (char*) &default_table_type_name, SHOW_CHAR_PTR}, {"table_type", (char*) &default_table_type_name, SHOW_CHAR_PTR},
{"thread_cache_size", (char*) &thread_cache_size, SHOW_LONG},
#ifdef HAVE_THR_SETCONCURRENCY #ifdef HAVE_THR_SETCONCURRENCY
{"thread_concurrency", (char*) &concurrency, SHOW_LONG}, {"thread_concurrency", (char*) &concurrency, SHOW_LONG},
#endif #endif
{"thread_stack", (char*) &thread_stack, SHOW_LONG}, {"thread_stack", (char*) &thread_stack, SHOW_LONG},
{"thread_cache_size", (char*) &thread_cache_size, SHOW_LONG},
#ifdef HAVE_TZNAME #ifdef HAVE_TZNAME
{"timezone", time_zone, SHOW_CHAR}, {"timezone", time_zone, SHOW_CHAR},
#endif #endif
@ -3414,7 +3418,7 @@ static int get_service_parameters()
else if ( lstrcmp(szKeyValueName, TEXT("ShowDatabase")) == 0 ) else if ( lstrcmp(szKeyValueName, TEXT("ShowDatabase")) == 0 )
{ {
CHECK_KEY_TYPE( REG_DWORD, szKeyValueName ); CHECK_KEY_TYPE( REG_DWORD, szKeyValueName );
opt_disable_networking = !(*lpdwValue); opt_skip_show_db = !(*lpdwValue);
} }
else if ( lstrcmp(szKeyValueName, TEXT("HostnameCaching")) == 0 ) else if ( lstrcmp(szKeyValueName, TEXT("HostnameCaching")) == 0 )
{ {

View File

@ -319,11 +319,11 @@ bool net_store_data(String* packet, I_List<i_string>* str_list)
i_string* s; i_string* s;
while((s=it++)) while((s=it++))
{ {
if(tmp.length()) if(tmp.length())
tmp.append(','); tmp.append(',');
tmp.append(s->ptr); tmp.append(s->ptr);
} }
return net_store_data(packet, (char*)tmp.ptr(), tmp.length()); return net_store_data(packet, (char*)tmp.ptr(), tmp.length());
} }

View File

@ -114,11 +114,17 @@ THD::THD()
ull=0; ull=0;
system_thread=0; system_thread=0;
bzero((char*) &mem_root,sizeof(mem_root)); bzero((char*) &mem_root,sizeof(mem_root));
#if defined(HAVE_BDB) || defined(HAVE_INNOBASE) || defined(HAVE_GEMENI)
if (open_cached_file(&transactions.trans_log,
mysql_tempdir,LOG_PREFIX,0,MYF(MY_WME)))
killed=1;
transaction.bdb_lock_count=0;
#endif
transaction.bdb_tid=0;
#ifdef __WIN__ #ifdef __WIN__
real_id = 0 ; real_id = 0 ;
#endif #endif
transaction.bdb_lock_count=0;
transaction.bdb_tid=0;
} }
THD::~THD() THD::~THD()
@ -137,6 +143,9 @@ THD::~THD()
close_thread_tables(this); close_thread_tables(this);
} }
close_temporary_tables(this); close_temporary_tables(this);
#if defined(HAVE_BDB) || defined(HAVE_INNOBASE) || defined(HAVE_GEMENI)
close_cached_file(transactions.trans_log);
#endif
if (global_read_lock) if (global_read_lock)
{ {
pthread_mutex_lock(&LOCK_open); pthread_mutex_lock(&LOCK_open);

View File

@ -52,16 +52,16 @@ typedef struct st_log_info
class MYSQL_LOG { class MYSQL_LOG {
public:
private: private:
pthread_mutex_t LOCK_log, LOCK_index; pthread_mutex_t LOCK_log, LOCK_index;
FILE *file, *index_file;
time_t last_time,query_start; time_t last_time,query_start;
IO_CACHE log_file;
File index_file;
char *name; char *name;
enum_log_type log_type; volatile enum_log_type log_type;
char time_buff[20],db[NAME_LEN+1]; char time_buff[20],db[NAME_LEN+1];
char log_file_name[FN_REFLEN],index_file_name[FN_REFLEN]; char log_file_name[FN_REFLEN],index_file_name[FN_REFLEN];
bool write_error,inited; bool write_error,inited,opened;
bool no_rotate; // for binlog - if log name can never change bool no_rotate; // for binlog - if log name can never change
// we should not try to rotate it or write any rotation events // we should not try to rotate it or write any rotation events
// the user should use FLUSH MASTER instead of FLUSH LOGS for // the user should use FLUSH MASTER instead of FLUSH LOGS for
@ -85,7 +85,6 @@ public:
void make_log_name(char* buf, const char* log_ident); void make_log_name(char* buf, const char* log_ident);
bool is_active(const char* log_file_name); bool is_active(const char* log_file_name);
int purge_logs(THD* thd, const char* to_log); int purge_logs(THD* thd, const char* to_log);
void flush(void);
void close(bool exiting = 0); // if we are exiting, we also want to close the void close(bool exiting = 0); // if we are exiting, we also want to close the
// index file // index file
@ -244,6 +243,7 @@ public:
thr_lock_type update_lock_default; thr_lock_type update_lock_default;
delayed_insert *di; delayed_insert *di;
struct st_transactions { struct st_transactions {
IO_CACHE trans_log;
void *bdb_tid; void *bdb_tid;
uint bdb_lock_count; uint bdb_lock_count;
} transaction; } transaction;

View File

@ -571,7 +571,7 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list)
thread_count++; thread_count++;
pthread_mutex_unlock(&LOCK_thread_count); pthread_mutex_unlock(&LOCK_thread_count);
if (!(tmp->thd.db=my_strdup(table_list->db,MYF(MY_WME))) || if (!(tmp->thd.db=my_strdup(table_list->db,MYF(MY_WME))) ||
!(tmp->thd.query=my_strdup(table_list->real_name,MYF(MY_FAE)))) !(tmp->thd.query=my_strdup(table_list->real_name,MYF(MY_WME))))
{ {
delete tmp; delete tmp;
thd->fatal_error=1; thd->fatal_error=1;
@ -1325,7 +1325,8 @@ bool select_create::send_eof()
{ {
VOID(pthread_mutex_lock(&LOCK_open)); VOID(pthread_mutex_lock(&LOCK_open));
mysql_unlock_tables(thd, lock); mysql_unlock_tables(thd, lock);
hash_delete(&open_cache,(byte*) table); if (!table->tmp_table)
hash_delete(&open_cache,(byte*) table);
lock=0; table=0; lock=0; table=0;
VOID(pthread_mutex_unlock(&LOCK_open)); VOID(pthread_mutex_unlock(&LOCK_open));
} }
@ -1343,7 +1344,8 @@ void select_create::abort()
if (table) if (table)
{ {
enum db_type table_type=table->db_type; enum db_type table_type=table->db_type;
hash_delete(&open_cache,(byte*) table); if (!table->tmp_table)
hash_delete(&open_cache,(byte*) table);
quick_rm_table(table_type,db,name); quick_rm_table(table_type,db,name);
table=0; table=0;
} }

View File

@ -34,19 +34,23 @@ class LEX_COLUMN;
#endif #endif
enum enum_sql_command { enum enum_sql_command {
SQLCOM_SELECT,SQLCOM_CREATE_TABLE,SQLCOM_CREATE_INDEX,SQLCOM_ALTER_TABLE, SQLCOM_SELECT, SQLCOM_CREATE_TABLE, SQLCOM_CREATE_INDEX, SQLCOM_ALTER_TABLE,
SQLCOM_UPDATE,SQLCOM_INSERT,SQLCOM_INSERT_SELECT,SQLCOM_DELETE, SQLCOM_UPDATE, SQLCOM_INSERT, SQLCOM_INSERT_SELECT,
SQLCOM_DROP_TABLE,SQLCOM_DROP_INDEX,SQLCOM_SHOW_DATABASES, SQLCOM_DELETE, SQLCOM_TRUNCATE, SQLCOM_DROP_TABLE, SQLCOM_DROP_INDEX,
SQLCOM_SHOW_TABLES,SQLCOM_SHOW_FIELDS,SQLCOM_SHOW_KEYS,
SQLCOM_SHOW_DATABASES, SQLCOM_SHOW_TABLES, SQLCOM_SHOW_FIELDS,
SQLCOM_SHOW_KEYS, SQLCOM_SHOW_VARIABLES, SQLCOM_SHOW_STATUS,
SQLCOM_SHOW_PROCESSLIST, SQLCOM_SHOW_MASTER_STAT, SQLCOM_SHOW_SLAVE_STAT,
SQLCOM_SHOW_GRANTS, SQLCOM_SHOW_CREATE,
SQLCOM_LOAD,SQLCOM_SET_OPTION,SQLCOM_LOCK_TABLES,SQLCOM_UNLOCK_TABLES, SQLCOM_LOAD,SQLCOM_SET_OPTION,SQLCOM_LOCK_TABLES,SQLCOM_UNLOCK_TABLES,
SQLCOM_GRANT, SQLCOM_CHANGE_DB, SQLCOM_CREATE_DB, SQLCOM_DROP_DB, SQLCOM_GRANT, SQLCOM_CHANGE_DB, SQLCOM_CREATE_DB, SQLCOM_DROP_DB,
SQLCOM_REPAIR, SQLCOM_REPLACE, SQLCOM_REPLACE_SELECT, SQLCOM_SHOW_VARIABLES, SQLCOM_REPAIR, SQLCOM_REPLACE, SQLCOM_REPLACE_SELECT,
SQLCOM_SHOW_STATUS, SQLCOM_CREATE_FUNCTION, SQLCOM_DROP_FUNCTION, SQLCOM_CREATE_FUNCTION, SQLCOM_DROP_FUNCTION,
SQLCOM_SHOW_PROCESSLIST,SQLCOM_REVOKE,SQLCOM_OPTIMIZE, SQLCOM_CHECK, SQLCOM_REVOKE,SQLCOM_OPTIMIZE, SQLCOM_CHECK,
SQLCOM_FLUSH, SQLCOM_KILL, SQLCOM_SHOW_GRANTS, SQLCOM_ANALYZE, SQLCOM_FLUSH, SQLCOM_KILL, SQLCOM_ANALYZE,
SQLCOM_ROLLBACK, SQLCOM_COMMIT, SQLCOM_SLAVE_START, SQLCOM_SLAVE_STOP, SQLCOM_ROLLBACK, SQLCOM_COMMIT, SQLCOM_SLAVE_START, SQLCOM_SLAVE_STOP,
SQLCOM_BEGIN, SQLCOM_LOAD_MASTER_TABLE, SQLCOM_SHOW_CREATE, SQLCOM_BEGIN, SQLCOM_LOAD_MASTER_TABLE, SQLCOM_CHANGE_MASTER,
SQLCOM_SHOW_MASTER_STAT, SQLCOM_SHOW_SLAVE_STAT, SQLCOM_CHANGE_MASTER,
SQLCOM_RENAME_TABLE, SQLCOM_BACKUP_TABLE, SQLCOM_RESTORE_TABLE, SQLCOM_RENAME_TABLE, SQLCOM_BACKUP_TABLE, SQLCOM_RESTORE_TABLE,
SQLCOM_RESET, SQLCOM_PURGE, SQLCOM_SHOW_BINLOGS SQLCOM_RESET, SQLCOM_PURGE, SQLCOM_SHOW_BINLOGS
}; };

View File

@ -158,7 +158,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
unpack_filename(name,ex->file_name); unpack_filename(name,ex->file_name);
#ifndef __WIN__ #ifndef __WIN__
MY_STAT stat_info; MY_STAT stat_info;
if (!my_stat(name,&stat_info,MYF(MY_FAE))) if (!my_stat(name,&stat_info,MYF(MY_WME)))
DBUG_RETURN(-1); DBUG_RETURN(-1);
// the file must be: // the file must be:

View File

@ -71,6 +71,20 @@ static void init_signals(void)
} }
#endif #endif
static inline bool end_active_trans(THD *thd)
{
if (!(thd->options & OPTION_AUTO_COMMIT) ||
(thd->options & OPTION_BEGIN))
{
if (ha_commit(thd))
return 1;
thd->options&= ~OPTION_BEGIN;
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
}
return 0;
}
/* /*
** Check if user is ok ** Check if user is ok
** Updates: ** Updates:
@ -1150,8 +1164,7 @@ mysql_execute_command(void)
} }
} }
/* ALTER TABLE ends previous transaction */ /* ALTER TABLE ends previous transaction */
if ((!(thd->options & OPTION_AUTO_COMMIT) || if (end_active_trans(thd))
(thd->options & OPTION_BEGIN)) && ha_commit(thd))
res= -1; res= -1;
else else
res= mysql_alter_table(thd, lex->db, lex->name, res= mysql_alter_table(thd, lex->db, lex->name,
@ -1369,6 +1382,7 @@ mysql_execute_command(void)
break; break;
} }
case SQLCOM_DELETE: case SQLCOM_DELETE:
case SQLCOM_TRUNCATE:
{ {
if (check_access(thd,DELETE_ACL,tables->db,&tables->grant.privilege)) if (check_access(thd,DELETE_ACL,tables->db,&tables->grant.privilege))
goto error; /* purecov: inspected */ goto error; /* purecov: inspected */
@ -1376,11 +1390,12 @@ mysql_execute_command(void)
goto error; goto error;
// Set privilege for the WHERE clause // Set privilege for the WHERE clause
tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege); tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege);
res = mysql_delete(thd,tables,lex->where,lex->select_limit, /* TRUNCATE ends previous transaction */
lex->lock_option, lex->options); if (lex->sql_command == SQLCOM_TRUNCATE && end_active_trans(thd))
#ifdef DELETE_ITEMS res= -1;
delete lex->where; else
#endif res = mysql_delete(thd,tables,lex->where,lex->select_limit,
lex->lock_option, lex->options);
break; break;
} }
case SQLCOM_DROP_TABLE: case SQLCOM_DROP_TABLE:
@ -1722,6 +1737,11 @@ mysql_execute_command(void)
send_ok(&thd->net); send_ok(&thd->net);
break; break;
case SQLCOM_COMMIT: case SQLCOM_COMMIT:
/*
We don't use end_active_trans() here to ensure that this works
even if there is a problem with the OPTION_AUTO_COMMIT flag
(Which of course should never happen...)
*/
thd->options&= ~OPTION_BEGIN; thd->options&= ~OPTION_BEGIN;
thd->server_status&= ~SERVER_STATUS_IN_TRANS; thd->server_status&= ~SERVER_STATUS_IN_TRANS;
if (!ha_commit(thd)) if (!ha_commit(thd))
@ -2441,7 +2461,7 @@ bool reload_acl_and_cache(THD *thd, uint options, TABLE_LIST *tables)
bool result=0; bool result=0;
select_errors=0; /* Write if more errors */ select_errors=0; /* Write if more errors */
mysql_log.flush(); // Flush log // mysql_log.flush(); // Flush log
if (options & REFRESH_GRANT) if (options & REFRESH_GRANT)
{ {
acl_reload(); acl_reload();

View File

@ -93,6 +93,40 @@ static int send_file(THD *thd)
DBUG_RETURN(error); DBUG_RETURN(error);
} }
static File open_log(IO_CACHE *log, const char *log_file_name,
const char **errmsg)
{
File file;
char magic[4];
if ((file = my_open(log_file_name, O_RDONLY | O_BINARY, MYF(MY_WME))) < 0 ||
init_io_cache(log, file, IO_SIZE*2, READ_CACHE, 0, 0,
MYF(MY_WME)))
{
*errmsg = "Could not open log file"; // This will not be sent
goto err;
}
if (my_b_read(log, (byte*) magic, sizeof(magic)))
{
*errmsg = "I/O error reading binlog magic number";
goto err;
}
if (memcmp(magic, BINLOG_MAGIC, 4))
{
*errmsg = "Binlog has bad magic number, fire your magician";
goto err;
}
return file;
err:
if (file > 0)
my_close(file,MYF(0));
end_io_cache(log);
return -1;
}
void adjust_linfo_offsets(my_off_t purge_offset) void adjust_linfo_offsets(my_off_t purge_offset)
{ {
THD *tmp; THD *tmp;
@ -119,6 +153,7 @@ void adjust_linfo_offsets(my_off_t purge_offset)
pthread_mutex_unlock(&LOCK_thread_count); pthread_mutex_unlock(&LOCK_thread_count);
} }
bool log_in_use(const char* log_name) bool log_in_use(const char* log_name)
{ {
int log_name_len = strlen(log_name) + 1; int log_name_len = strlen(log_name) + 1;
@ -144,6 +179,7 @@ bool log_in_use(const char* log_name)
return result; return result;
} }
int purge_master_logs(THD* thd, const char* to_log) int purge_master_logs(THD* thd, const char* to_log)
{ {
char search_file_name[FN_REFLEN]; char search_file_name[FN_REFLEN];
@ -179,27 +215,29 @@ binlog purge"; break;
return 0; return 0;
} }
void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags) void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
{ {
LOG_INFO linfo; LOG_INFO linfo;
char *log_file_name = linfo.log_file_name; char *log_file_name = linfo.log_file_name;
char search_file_name[FN_REFLEN]; char search_file_name[FN_REFLEN];
char magic[4]; IO_CACHE log;
FILE* log = NULL; File file = -1;
String* packet = &thd->packet; String* packet = &thd->packet;
int error; int error;
const char *errmsg = "Unknown error"; const char *errmsg = "Unknown error";
NET* net = &thd->net; NET* net = &thd->net;
DBUG_ENTER("mysql_binlog_send"); DBUG_ENTER("mysql_binlog_send");
if(!mysql_bin_log.is_open()) bzero((char*) &log,sizeof(log));
{
errmsg = "Binary log is not open";
goto err;
}
if(log_ident[0]) if(!mysql_bin_log.is_open())
{
errmsg = "Binary log is not open";
goto err;
}
if (log_ident[0])
mysql_bin_log.make_log_name(search_file_name, log_ident); mysql_bin_log.make_log_name(search_file_name, log_ident);
else else
search_file_name[0] = 0; search_file_name[0] = 0;
@ -207,251 +245,214 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
linfo.index_file_offset = 0; linfo.index_file_offset = 0;
thd->current_linfo = &linfo; thd->current_linfo = &linfo;
if(mysql_bin_log.find_first_log(&linfo, search_file_name)) if (mysql_bin_log.find_first_log(&linfo, search_file_name))
{ {
errmsg = "Could not find first log"; errmsg = "Could not find first log";
goto err; goto err;
} }
log = my_fopen(log_file_name, O_RDONLY|O_BINARY, MYF(MY_WME));
if(!log) if ((file=open_log(&log, log_file_name, &errmsg)) < 0)
{ goto err;
errmsg = "Could not open log file";
goto err;
}
if(my_fread(log, (byte*) magic, sizeof(magic), MYF(MY_NABP|MY_WME)))
{
errmsg = "I/O error reading binlog magic number";
goto err;
}
if(memcmp(magic, BINLOG_MAGIC, 4))
{
errmsg = "Binlog has bad magic number, fire your magician";
goto err;
}
if(pos < 4) if(pos < 4)
{ {
errmsg = "Congratulations! You have hit the magic number and can win \ errmsg = "Contratulations! You have hit the magic number and can win \
sweepstakes if you report the bug"; sweepstakes if you report the bug";
goto err; goto err;
} }
if(my_fseek(log, pos, MY_SEEK_SET, MYF(MY_WME)) == MY_FILEPOS_ERROR ) my_b_seek(&log, pos); // Seek will done on next read
{
errmsg = "Error on fseek()";
goto err;
}
packet->length(0); packet->length(0);
packet->append("\0", 1); packet->append("\0", 1);
// we need to start a packet with something other than 255 // we need to start a packet with something other than 255
// to distiquish it from error // to distiquish it from error
while(!net->error && net->vio != 0 && !thd->killed) while(!net->error && net->vio != 0 && !thd->killed)
{ {
pthread_mutex_t *log_lock = mysql_bin_log.get_log_lock(); pthread_mutex_t *log_lock = mysql_bin_log.get_log_lock();
while(!(error = Log_event::read_log_event(log, packet, log_lock))) while (!(error = Log_event::read_log_event(&log, packet, log_lock)))
{
if(my_net_write(net, (char*)packet->ptr(), packet->length()) )
{
errmsg = "Failed on my_net_write()";
goto err;
}
DBUG_PRINT("info", ("log event code %d",
(*packet)[LOG_EVENT_OFFSET+1] ));
if((*packet)[LOG_EVENT_OFFSET+1] == LOAD_EVENT)
{
if(send_file(thd))
{ {
if(my_net_write(net, (char*)packet->ptr(), packet->length()) ) errmsg = "failed in send_file()";
{
errmsg = "Failed on my_net_write()";
goto err;
}
DBUG_PRINT("info", ("log event code %d",
(*packet)[LOG_EVENT_OFFSET+1] ));
if((*packet)[LOG_EVENT_OFFSET+1] == LOAD_EVENT)
{
if(send_file(thd))
{
errmsg = "failed in send_file()";
goto err;
}
}
packet->length(0);
packet->append("\0",1);
}
if(error != LOG_READ_EOF)
{
switch(error)
{
case LOG_READ_BOGUS:
errmsg = "bogus data in log event";
break;
case LOG_READ_IO:
errmsg = "I/O error reading log event";
break;
case LOG_READ_MEM:
errmsg = "memory allocation failed reading log event";
break;
case LOG_READ_TRUNC:
errmsg = "binlog truncated in the middle of event";
break;
}
goto err; goto err;
} }
}
if(!(flags & BINLOG_DUMP_NON_BLOCK) && packet->length(0);
mysql_bin_log.is_active(log_file_name)) packet->append("\0",1);
// block until there is more data in the log }
// unless non-blocking mode requested if(error != LOG_READ_EOF)
{ {
if(net_flush(net)) switch(error)
{ {
errmsg = "failed on net_flush()"; case LOG_READ_BOGUS:
goto err; errmsg = "bogus data in log event";
} break;
case LOG_READ_IO:
// we may have missed the update broadcast from the log errmsg = "I/O error reading log event";
// that has just happened, let's try to catch it if it did break;
// if we did not miss anything, we just wait for other threads case LOG_READ_MEM:
// to signal us errmsg = "memory allocation failed reading log event";
{ break;
clearerr(log); case LOG_READ_TRUNC:
errmsg = "binlog truncated in the middle of event";
// tell the kill thread how to wake us up break;
pthread_mutex_lock(&thd->mysys_var->mutex); }
thd->mysys_var->current_mutex = log_lock; goto err;
thd->mysys_var->current_cond = &COND_binlog_update;
const char* proc_info = thd->proc_info;
thd->proc_info = "Waiting for update";
pthread_mutex_unlock(&thd->mysys_var->mutex);
bool read_packet = 0, fatal_error = 0;
// no one will update the log while we are reading
// now, but we'll be quick and just read one record
switch(Log_event::read_log_event(log, packet, log_lock))
{
case 0:
read_packet = 1;
// we read successfully, so we'll need to send it to the
// slave
break;
case LOG_READ_EOF:
pthread_mutex_lock(log_lock);
pthread_cond_wait(&COND_binlog_update, log_lock);
pthread_mutex_unlock(log_lock);
break;
default:
fatal_error = 1;
break;
}
pthread_mutex_lock(&thd->mysys_var->mutex);
thd->mysys_var->current_mutex= 0;
thd->mysys_var->current_cond= 0;
thd->proc_info= proc_info;
pthread_mutex_unlock(&thd->mysys_var->mutex);
if(read_packet)
{
thd->proc_info = "sending update to slave";
if(my_net_write(net, (char*)packet->ptr(), packet->length()) )
{
errmsg = "Failed on my_net_write()";
goto err;
}
if((*packet)[LOG_EVENT_OFFSET+1] == LOAD_EVENT)
{
if(send_file(thd))
{
errmsg = "failed in send_file()";
goto err;
}
}
packet->length(0);
packet->append("\0",1);
// no need to net_flush because we will get to flush later when
// we hit EOF pretty quick
}
if(fatal_error)
{
errmsg = "error reading log entry";
goto err;
}
clearerr(log);
}
}
else
{
bool loop_breaker = 0;
// need this to break out of the for loop from switch
thd->proc_info = "switching to next log";
switch(mysql_bin_log.find_next_log(&linfo))
{
case LOG_INFO_EOF:
loop_breaker = (flags & BINLOG_DUMP_NON_BLOCK);
break;
case 0:
break;
default:
errmsg = "could not find next log";
goto err;
}
if(loop_breaker)
break;
(void) my_fclose(log, MYF(MY_WME));
log = my_fopen(log_file_name, O_RDONLY|O_BINARY, MYF(MY_WME));
if(!log)
{
errmsg = "Could not open next log";
goto err;
}
//check the magic
if(my_fread(log, (byte*) magic, sizeof(magic), MYF(MY_NABP|MY_WME)))
{
errmsg = "I/O error reading binlog magic number";
goto err;
}
if(memcmp(magic, BINLOG_MAGIC, 4))
{
errmsg = "Binlog has bad magic number, fire your magician";
goto err;
}
// fake Rotate_log event just in case it did not make it to the log
// otherwise the slave make get confused about the offset
{
char header[LOG_EVENT_HEADER_LEN];
memset(header, 0, 4); // when does not matter
header[EVENT_TYPE_OFFSET] = ROTATE_EVENT;
char* p = strrchr(log_file_name, FN_LIBCHAR);
// find the last slash
if(p)
p++;
else
p = log_file_name;
uint ident_len = (uint) strlen(p);
ulong event_len = ident_len + sizeof(header);
int4store(header + EVENT_TYPE_OFFSET + 1, server_id);
int4store(header + EVENT_LEN_OFFSET, event_len);
packet->append(header, sizeof(header));
packet->append(p,ident_len);
if(my_net_write(net, (char*)packet->ptr(), packet->length()))
{
errmsg = "failed on my_net_write()";
goto err;
}
packet->length(0);
packet->append("\0",1);
}
}
} }
(void)my_fclose(log, MYF(MY_WME)); if(!(flags & BINLOG_DUMP_NON_BLOCK) &&
mysql_bin_log.is_active(log_file_name))
// block until there is more data in the log
// unless non-blocking mode requested
{
if(net_flush(net))
{
errmsg = "failed on net_flush()";
goto err;
}
// we may have missed the update broadcast from the log
// that has just happened, let's try to catch it if it did
// if we did not miss anything, we just wait for other threads
// to signal us
{
log.error=0;
// tell the kill thread how to wake us up
pthread_mutex_lock(&thd->mysys_var->mutex);
thd->mysys_var->current_mutex = log_lock;
thd->mysys_var->current_cond = &COND_binlog_update;
const char* proc_info = thd->proc_info;
thd->proc_info = "Waiting for update";
pthread_mutex_unlock(&thd->mysys_var->mutex);
bool read_packet = 0, fatal_error = 0;
// no one will update the log while we are reading
// now, but we'll be quick and just read one record
switch(Log_event::read_log_event(&log, packet, log_lock))
{
case 0:
read_packet = 1;
// we read successfully, so we'll need to send it to the
// slave
break;
case LOG_READ_EOF:
pthread_mutex_lock(log_lock);
pthread_cond_wait(&COND_binlog_update, log_lock);
pthread_mutex_unlock(log_lock);
break;
default:
fatal_error = 1;
break;
}
pthread_mutex_lock(&thd->mysys_var->mutex);
thd->mysys_var->current_mutex= 0;
thd->mysys_var->current_cond= 0;
thd->proc_info= proc_info;
pthread_mutex_unlock(&thd->mysys_var->mutex);
if(read_packet)
{
thd->proc_info = "sending update to slave";
if(my_net_write(net, (char*)packet->ptr(), packet->length()) )
{
errmsg = "Failed on my_net_write()";
goto err;
}
if((*packet)[LOG_EVENT_OFFSET+1] == LOAD_EVENT)
{
if(send_file(thd))
{
errmsg = "failed in send_file()";
goto err;
}
}
packet->length(0);
packet->append("\0",1);
// no need to net_flush because we will get to flush later when
// we hit EOF pretty quick
}
if(fatal_error)
{
errmsg = "error reading log entry";
goto err;
}
log.error=0;
}
}
else
{
bool loop_breaker = 0;
// need this to break out of the for loop from switch
thd->proc_info = "switching to next log";
switch(mysql_bin_log.find_next_log(&linfo))
{
case LOG_INFO_EOF:
loop_breaker = (flags & BINLOG_DUMP_NON_BLOCK);
break;
case 0:
break;
default:
errmsg = "could not find next log";
goto err;
}
if(loop_breaker)
break;
end_io_cache(&log);
(void) my_close(file, MYF(MY_WME));
if ((file=open_log(&log, log_file_name, &errmsg)) < 0)
goto err;
// fake Rotate_log event just in case it did not make it to the log
// otherwise the slave make get confused about the offset
{
char header[LOG_EVENT_HEADER_LEN];
memset(header, 0, 4); // when does not matter
header[EVENT_TYPE_OFFSET] = ROTATE_EVENT;
char* p = strrchr(log_file_name, FN_LIBCHAR);
// find the last slash
if(p)
p++;
else
p = log_file_name;
uint ident_len = (uint) strlen(p);
ulong event_len = ident_len + sizeof(header);
int4store(header + EVENT_TYPE_OFFSET + 1, server_id);
int4store(header + EVENT_LEN_OFFSET, event_len);
packet->append(header, sizeof(header));
packet->append(p,ident_len);
if(my_net_write(net, (char*)packet->ptr(), packet->length()))
{
errmsg = "failed on my_net_write()";
goto err;
}
packet->length(0);
packet->append("\0",1);
}
}
}
end_io_cache(&log);
(void)my_close(file, MYF(MY_WME));
send_eof(&thd->net); send_eof(&thd->net);
thd->proc_info = "waiting to finalize termination"; thd->proc_info = "waiting to finalize termination";
@ -461,6 +462,7 @@ sweepstakes if you report the bug";
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
err: err:
thd->proc_info = "waiting to finalize termination"; thd->proc_info = "waiting to finalize termination";
end_io_cache(&log);
pthread_mutex_lock(&LOCK_thread_count); pthread_mutex_lock(&LOCK_thread_count);
// exclude iteration through thread list // exclude iteration through thread list
// this is needed for purge_logs() - it will iterate through // this is needed for purge_logs() - it will iterate through
@ -469,8 +471,8 @@ sweepstakes if you report the bug";
// after we return from this stack frame // after we return from this stack frame
thd->current_linfo = 0; thd->current_linfo = 0;
pthread_mutex_unlock(&LOCK_thread_count); pthread_mutex_unlock(&LOCK_thread_count);
if(log) if (file >= 0)
(void) my_fclose(log, MYF(MY_WME)); (void) my_close(file, MYF(MY_WME));
send_error(&thd->net, my_errno, errmsg); send_error(&thd->net, my_errno, errmsg);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }

View File

@ -2735,7 +2735,7 @@ return_zero_rows(select_result *result,TABLE_LIST *tables,List<Item> &fields,
{ {
for (TABLE_LIST *table=tables; table ; table=table->next) for (TABLE_LIST *table=tables; table ; table=table->next)
mark_as_null_row(table->table); // All fields are NULL mark_as_null_row(table->table); // All fields are NULL
if (having && having->val_int() == 0.0) if (having && having->val_int() == 0)
send_row=0; send_row=0;
} }
if (!tables || !(result->send_fields(fields,1))) if (!tables || !(result->send_fields(fields,1)))
@ -3214,6 +3214,7 @@ Field *create_tmp_field(TABLE *table,Item *item, Item::Type type,
case Item::REAL_ITEM: case Item::REAL_ITEM:
case Item::STRING_ITEM: case Item::STRING_ITEM:
case Item::REF_ITEM: case Item::REF_ITEM:
case Item::NULL_ITEM:
{ {
bool maybe_null=item->maybe_null; bool maybe_null=item->maybe_null;
Field *new_field; Field *new_field;
@ -4499,7 +4500,7 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (!end_of_records) if (!end_of_records)
{ {
int error; int error;
if (join->having && join->having->val_int() == 0.0) if (join->having && join->having->val_int() == 0)
DBUG_RETURN(0); // Didn't match having DBUG_RETURN(0); // Didn't match having
if (join->procedure) if (join->procedure)
error=join->procedure->send_row(*join->fields); error=join->procedure->send_row(*join->fields);
@ -4539,7 +4540,7 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
int error; int error;
if (join->procedure) if (join->procedure)
{ {
if (join->having && join->having->val_int() == 0.0) if (join->having && join->having->val_int() == 0)
error= -1; // Didn't satisfy having error= -1; // Didn't satisfy having
else else
error=join->procedure->send_row(*join->fields) ? 1 : 0; error=join->procedure->send_row(*join->fields) ? 1 : 0;
@ -4550,7 +4551,7 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
{ {
if (!join->first_record) if (!join->first_record)
clear_tables(join); clear_tables(join);
if (join->having && join->having->val_int() == 0.0) if (join->having && join->having->val_int() == 0)
error= -1; // Didn't satisfy having error= -1; // Didn't satisfy having
else else
error=join->result->send_data(*join->fields) ? 1 : 0; error=join->result->send_data(*join->fields) ? 1 : 0;
@ -5109,7 +5110,7 @@ create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit)
goto err; /* purecov: inspected */ goto err; /* purecov: inspected */
/* It's not fatal if the following alloc fails */ /* It's not fatal if the following alloc fails */
table->io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE), table->io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
MYF(MY_FAE | MY_ZEROFILL)); MYF(MY_WME | MY_ZEROFILL));
table->status=0; // May be wrong if quick_select table->status=0; // May be wrong if quick_select
// If table has a range, move it to select // If table has a range, move it to select

View File

@ -95,17 +95,6 @@ bool String::realloc(uint32 alloc_length)
return FALSE; return FALSE;
} }
#ifdef NOT_NEEDED
bool String::set(long num)
{
if (alloc(14))
return TRUE;
str_length=(uint32) (int10_to_str(num,Ptr,-10)-Ptr);
return FALSE;
}
#endif
bool String::set(longlong num) bool String::set(longlong num)
{ {
if (alloc(21)) if (alloc(21))
@ -274,6 +263,7 @@ bool String::append(const char *s,uint32 arg_length)
return FALSE; return FALSE;
} }
#ifdef TO_BE_REMOVED
bool String::append(FILE* file, uint32 arg_length, myf my_flags) bool String::append(FILE* file, uint32 arg_length, myf my_flags)
{ {
if (realloc(str_length+arg_length)) if (realloc(str_length+arg_length))
@ -286,6 +276,20 @@ bool String::append(FILE* file, uint32 arg_length, myf my_flags)
str_length+=arg_length; str_length+=arg_length;
return FALSE; return FALSE;
} }
#endif
bool String::append(IO_CACHE* file, uint32 arg_length)
{
if (realloc(str_length+arg_length))
return TRUE;
if (my_b_read(file, (byte*) Ptr + str_length, arg_length))
{
shrink(str_length);
return TRUE;
}
str_length+=arg_length;
return FALSE;
}
uint32 String::numchars() uint32 String::numchars()
{ {

View File

@ -152,7 +152,7 @@ public:
bool copy(const char *s,uint32 arg_length); // Allocate new string bool copy(const char *s,uint32 arg_length); // Allocate new string
bool append(const String &s); bool append(const String &s);
bool append(const char *s,uint32 arg_length=0); bool append(const char *s,uint32 arg_length=0);
bool append(FILE* file, uint32 arg_length, myf my_flags); bool append(IO_CACHE* file, uint32 arg_length);
int strstr(const String &search,uint32 offset=0); // Returns offset to substring or -1 int strstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
int strrstr(const String &search,uint32 offset=0); // Returns offset to substring or -1 int strrstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
bool replace(uint32 offset,uint32 arg_length,const String &to); bool replace(uint32 offset,uint32 arg_length,const String &to);

View File

@ -111,6 +111,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token SLAVE %token SLAVE
%token START_SYM %token START_SYM
%token STOP_SYM %token STOP_SYM
%token TRUNCATE_SYM
%token ROLLBACK_SYM %token ROLLBACK_SYM
%token OPTIMIZE %token OPTIMIZE
%token SHOW %token SHOW
@ -493,9 +494,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%type <NONE> %type <NONE>
query verb_clause create change select drop insert replace insert2 query verb_clause create change select drop insert replace insert2
insert_values update delete show describe load alter optimize flush insert_values update delete truncate rename
show describe load alter optimize flush
reset purge begin commit rollback slave master_def master_defs reset purge begin commit rollback slave master_def master_defs
repair restore backup analyze check rename repair restore backup analyze check
field_list field_list_item field_spec kill field_list field_list_item field_spec kill
select_item_list select_item values_list no_braces select_item_list select_item values_list no_braces
limit_clause delete_limit_clause fields opt_values values limit_clause delete_limit_clause fields opt_values values
@ -562,6 +564,7 @@ verb_clause:
| set | set
| slave | slave
| show | show
| truncate
| unlock | unlock
| update | update
| use | use
@ -789,7 +792,7 @@ field_list_item:
Lex->key_list.push_back(new Key($1,$2,Lex->col_list)); Lex->key_list.push_back(new Key($1,$2,Lex->col_list));
Lex->col_list.empty(); /* Alloced by sql_alloc */ Lex->col_list.empty(); /* Alloced by sql_alloc */
} }
| opt_constraint FOREIGN KEY_SYM '(' key_list ')' references | opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references
{ {
Lex->col_list.empty(); /* Alloced by sql_alloc */ Lex->col_list.empty(); /* Alloced by sql_alloc */
} }
@ -1559,7 +1562,8 @@ simple_expr:
{ $$= new Item_func_trim($6,$4); } { $$= new Item_func_trim($6,$4); }
| TRIM '(' expr FROM expr ')' | TRIM '(' expr FROM expr ')'
{ $$= new Item_func_trim($5,$3); } { $$= new Item_func_trim($5,$3); }
| TRUNCATE_SYM '(' expr ',' expr ')'
{ $$= new Item_func_round($3,$5,1); }
| UDA_CHAR_SUM '(' udf_expr_list ')' | UDA_CHAR_SUM '(' udf_expr_list ')'
{ {
if ($3 != NULL) if ($3 != NULL)
@ -2131,6 +2135,11 @@ opt_delete_option:
QUICK { Lex->options|= OPTION_QUICK; } QUICK { Lex->options|= OPTION_QUICK; }
| LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; } | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; }
truncate:
TRUNCATE_SYM TABLE_SYM table
{ Lex->sql_command= SQLCOM_TRUNCATE; Lex->options=0;
Lex->lock_option= current_thd->update_lock_default; }
/* Show things */ /* Show things */
show: SHOW { Lex->wild=0;} show_param show: SHOW { Lex->wild=0;} show_param
@ -2530,6 +2539,7 @@ keyword:
| STRING_SYM {} | STRING_SYM {}
| TEMPORARY {} | TEMPORARY {}
| TEXT_SYM {} | TEXT_SYM {}
| TRUNCATE_SYM {}
| TIMESTAMP {} | TIMESTAMP {}
| TIME_SYM {} | TIME_SYM {}
| TYPE_SYM {} | TYPE_SYM {}

View File

@ -413,16 +413,6 @@ ulong convert_month_to_period(ulong month)
return year*100+month%12+1; return year*100+month%12+1;
} }
#ifdef NOT_NEEDED
ulong add_to_period(ulong period,int months)
{
if (period == 0L)
return 0L;
return convert_month_to_period(convert_period_to_month(period)+months);
}
#endif
/***************************************************************************** /*****************************************************************************
** convert a timestamp string to a TIME value. ** convert a timestamp string to a TIME value.

View File

@ -1,18 +1,19 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This program is free software; you can redistribute it and/or modify This library is free software; you can redistribute it and/or
it under the terms of the GNU General Public License as published by modify it under the terms of the GNU Library General Public
the Free Software Foundation; either version 2 of the License, or License as published by the Free Software Foundation; either
(at your option) any later version. version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
GNU General Public License for more details. Library General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Library General Public
along with this program; if not, write to the Free Software License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA */
/* /*
Note that we can't have assertion on file descriptors; The reason for Note that we can't have assertion on file descriptors; The reason for
@ -31,6 +32,9 @@
#include <my_sys.h> #include <my_sys.h>
#include <my_net.h> #include <my_net.h>
#include <m_string.h> #include <m_string.h>
#ifdef HAVE_POLL
#include <sys/poll.h>
#endif
#if defined(__EMX__) #if defined(__EMX__)
#include <sys/ioctl.h> #include <sys/ioctl.h>
@ -398,4 +402,26 @@ void vio_in_addr(Vio *vio, struct in_addr *in)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/* Return 0 if there is data to be read */
my_bool vio_poll_read(Vio *vio,uint timeout)
{
#ifndef HAVE_POLL
return 0;
#else
struct pollfd fds;
int res;
DBUG_ENTER("vio_poll");
fds.fd=vio->sd;
fds.events=POLLIN;
fds.revents=0;
if ((res=poll(&fds,1,(int) timeout*1000)) <= 0)
{
DBUG_RETURN(res < 0 ? 0 : 1); /* Don't return 1 on errors */
}
DBUG_RETURN(fds.revents & POLLIN ? 0 : 1);
#endif
}
#endif /* HAVE_VIO */ #endif /* HAVE_VIO */

View File

@ -31,7 +31,7 @@ strstr:
! if (*str++ == *search) { ! if (*str++ == *search) {
! i=(char*) str; j=(char*) search+1; ! i=(char*) str; j=(char*) search+1;
ldsb [%o1],%o2 ! g6= First char of search ldsb [%o1],%o2 ! o2= First char of search
.top: .top:
ldsb [%o0],%g3 ! g3= First char of rest of str ldsb [%o0],%g3 ! g3= First char of rest of str
cmp %g3,0 cmp %g3,0
@ -70,6 +70,3 @@ strstr:
.strstr_end: .strstr_end:
.size strstr,.strstr_end-strstr .size strstr,.strstr_end-strstr
.ident "Matt Wagner & Monty" .ident "Matt Wagner & Monty"