configure.in:
  merged
BitKeeper/etc/logging_ok:
  Auto merged
sql/filesort.cc:
  merged
sql/sql_select.cc:
  merged
This commit is contained in:
unknown 2000-10-07 14:05:45 +02:00
commit 4af074054b
65 changed files with 1992 additions and 931 deletions

View File

@ -16,11 +16,11 @@ paul@work.mysql.com
sasha@mysql.sashanet.com sasha@mysql.sashanet.com
sasha@work.mysql.com sasha@work.mysql.com
serg@infomag.ape.relarn.ru serg@infomag.ape.relarn.ru
serg@serg.mysql.com
serg@work.mysql.com serg@work.mysql.com
sinisa@work.mysql.com sinisa@work.mysql.com
spurr@nslinux.bedford.progress.com
tim@localhost.polyesthetic.msg tim@localhost.polyesthetic.msg
tim@threads.polyesthetic.msg
tim@work.mysql.com tim@work.mysql.com
tonu@work.mysql.com tonu@work.mysql.com
spurr@nslinux.bedford.progress.com
tim@threads.polyesthetic.msg
serg@serg.mysql.com

File diff suppressed because it is too large Load Diff

View File

@ -1543,12 +1543,12 @@ com_edit(String *buffer,char *line __attribute__((unused)))
put_info("Sorry, you can't send the result to an editor in Win32", put_info("Sorry, you can't send the result to an editor in Win32",
INFO_ERROR); INFO_ERROR);
#else #else
char *filename,buff[160]; char filename[FN_REFLEN],buff[160];
int fd,tmp; int fd,tmp;
const char *editor; const char *editor;
filename = my_tempnam(NullS,"sql",MYF(MY_WME)); if ((fd=create_temp_file(filename,NullS,"sql", O_CREAT | O_WRONLY,
if ((fd = my_create(filename,0,O_CREAT | O_WRONLY, MYF(MY_WME))) < 0) MYF(MY_WME))) < 0)
goto err; goto err;
if (buffer->is_empty() && !old_buffer.is_empty()) if (buffer->is_empty() && !old_buffer.is_empty())
(void) my_write(fd,(byte*) old_buffer.ptr(),old_buffer.length(), (void) my_write(fd,(byte*) old_buffer.ptr(),old_buffer.length(),
@ -1576,7 +1576,6 @@ com_edit(String *buffer,char *line __attribute__((unused)))
(void) my_close(fd,MYF(0)); (void) my_close(fd,MYF(0));
(void) my_delete(filename,MYF(MY_WME)); (void) my_delete(filename,MYF(MY_WME));
err: err:
free(filename);
#endif #endif
return 0; return 0;
} }

3
config.guess vendored
View File

@ -987,6 +987,9 @@ EOF
*:Rhapsody:*:*) *:Rhapsody:*:*)
echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
*:Darwin:*:*)
echo `uname -p`-apple-darwin${UNAME_RELEASE}
exit 0 ;;
esac esac
#echo '(No uname command or uname output not recognized.)' 1>&2 #echo '(No uname command or uname output not recognized.)' 1>&2

2
config.sub vendored
View File

@ -919,7 +919,7 @@ case $os in
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -rhapsody* | -openstep* | -oskit*) | -interix* | -uwin* | -rhapsody* | -darwin* | -openstep* | -oskit*)
# Remember, each alternative MUST END IN *, to match a version number. # Remember, each alternative MUST END IN *, to match a version number.
;; ;;
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \

View File

@ -332,7 +332,13 @@ elif $PS $$ 2> /dev/null | grep $0 > /dev/null
then then
FIND_PROC="$PS \$\$PID | grep mysqld > /dev/null" FIND_PROC="$PS \$\$PID | grep mysqld > /dev/null"
else else
AC_MSG_ERROR([Could not find the right ps switches. Which OS is this ?. See the Installation chapter in the Reference Manual.]) case $SYSTEM_TYPE in
*darwin*)
FIND_PROC="$PS -uaxww | grep mysqld | grep \" \$\$PID \" > /dev/null"
;;
*)
AC_MSG_ERROR([Could not find the right ps switches. Which OS is this ?. See the Installation chapter in the Reference Manual.])
esac
fi fi
AC_SUBST(FIND_PROC) AC_SUBST(FIND_PROC)
AC_MSG_RESULT("$FIND_PROC") AC_MSG_RESULT("$FIND_PROC")
@ -620,6 +626,7 @@ int main()
# Some system specific hacks # Some system specific hacks
# #
MAX_C_OPTIMIZE="-O6"
case $SYSTEM_TYPE in case $SYSTEM_TYPE in
*solaris2.7*) *solaris2.7*)
# Solaris 2.7 has a broken /usr/include/widec.h # Solaris 2.7 has a broken /usr/include/widec.h
@ -675,6 +682,15 @@ case $SYSTEM_TYPE in
fi fi
fi fi
;; ;;
*darwin*)
if test "$ac_cv_prog_gcc" = "yes"
then
CFLAGS="$CFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS"
CXXFLAGS="$CXXFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS"
MAX_C_OPTIMIZE="-O"
with_named_curses=""
fi
;;
*freebsd*) *freebsd*)
echo "Adding fix for interrupted reads" echo "Adding fix for interrupted reads"
CXXFLAGS="$CXXFLAGS -DMYSQLD_NET_RETRY_COUNT=1000000" CXXFLAGS="$CXXFLAGS -DMYSQLD_NET_RETRY_COUNT=1000000"
@ -1013,7 +1029,7 @@ if test "$ac_cv_prog_gcc" = "yes"
then then
DEBUG_CFLAGS="-g" DEBUG_CFLAGS="-g"
DEBUG_OPTIMIZE_CC="-O" DEBUG_OPTIMIZE_CC="-O"
OPTIMIZE_CFLAGS="-O6" OPTIMIZE_CFLAGS="$MAX_C_OPTIMIZE"
else else
DEBUG_CFLAGS="-g" DEBUG_CFLAGS="-g"
DEBUG_OPTIMIZE_CC="" DEBUG_OPTIMIZE_CC=""
@ -1186,7 +1202,8 @@ AC_SUBST(MAKE_SHELL)
# Already-done: stdlib.h string.h unistd.h termios.h # Already-done: stdlib.h string.h unistd.h termios.h
AC_CHECK_HEADERS(varargs.h stdarg.h dirent.h locale.h ndir.h sys/dir.h \ AC_CHECK_HEADERS(varargs.h stdarg.h dirent.h locale.h ndir.h sys/dir.h \
sys/file.h sys/ndir.h sys/ptem.h sys/pte.h sys/select.h sys/stream.h \ sys/file.h sys/ndir.h sys/ptem.h sys/pte.h sys/select.h sys/stream.h \
sys/mman.h curses.h termcap.h termio.h termbits.h asm/termbits.h grp.h) sys/mman.h curses.h termcap.h termio.h termbits.h asm/termbits.h grp.h \
paths.h)
# Already-done: strcasecmp # Already-done: strcasecmp
AC_CHECK_FUNCS(lstat putenv select setenv setlocale strcoll tcgetattr) AC_CHECK_FUNCS(lstat putenv select setenv setlocale strcoll tcgetattr)
@ -1222,7 +1239,7 @@ AC_CHECK_FUNCS(alarm bmove \
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 \ socket strnlen madvise \
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 \

View File

@ -32,6 +32,8 @@ static struct option long_options[] =
{ {
{"config-file", required_argument, 0, 'c'}, {"config-file", required_argument, 0, 'c'},
{"defaults-file", required_argument, 0, 'c'}, {"defaults-file", required_argument, 0, 'c'},
{"defaults-extra-file", required_argument, 0, 'e'},
{"extra-file", required_argument, 0, 'e'},
{"no-defaults", no_argument, 0, 'd'}, {"no-defaults", no_argument, 0, 'd'},
{"help", no_argument, 0, '?'}, {"help", no_argument, 0, '?'},
{"version", no_argument, 0, 'V'}, {"version", no_argument, 0, 'V'},
@ -40,7 +42,7 @@ static struct option long_options[] =
static void usage(my_bool version) static void usage(my_bool version)
{ {
printf("%s Ver 1.1 for %s at %s\n",my_progname,SYSTEM_TYPE, printf("%s Ver 1.2 for %s at %s\n",my_progname,SYSTEM_TYPE,
MACHINE_TYPE); MACHINE_TYPE);
if (version) if (version)
return; return;
@ -48,8 +50,11 @@ static void usage(my_bool version)
puts("Prints all arguments that is give to some program using the default files"); puts("Prints all arguments that is give to some program using the default files");
printf("Usage: %s [OPTIONS] groups\n",my_progname); printf("Usage: %s [OPTIONS] groups\n",my_progname);
printf("\n\ printf("\n\
-c, --config-file=# --defaults-file=#\n\ -c, --config-file=#, --defaults-file=#\n\
The config file to use (default '%s')\n\ The config file to use (default '%s')\n\
-e, --extra-file=#, --defaults-extra-file=#\n\
Read this file after the global /etc config file and\n\
before the config file in the users home directory.\n\
--no-defaults Return an empty string (useful for scripts)\n\ --no-defaults Return an empty string (useful for scripts)\n\
-?, --help Display this help message and exit.\n\ -?, --help Display this help message and exit.\n\
-V, --version Output version information and exit.\n", -V, --version Output version information and exit.\n",
@ -61,13 +66,16 @@ static int get_options(int *argc,char ***argv)
{ {
int c,option_index; int c,option_index;
while ((c=getopt_long(*argc,*argv,"c:V?I", while ((c=getopt_long(*argc,*argv,"c:e:V?I",
long_options, &option_index)) != EOF) long_options, &option_index)) != EOF)
{ {
switch (c) { switch (c) {
case 'c': case 'c':
config_file=optarg; config_file=optarg;
break; break;
case 'e':
defaults_extra_file=optarg; /* Used by the load_defaults */
break;
case 'n': case 'n':
exit(0); exit(0);
case 'I': case 'I':
@ -102,7 +110,7 @@ int main(int argc, char **argv)
if (get_options(&argc,&argv)) if (get_options(&argc,&argv))
exit(1); exit(1);
if (!(load_default_groups=(char**) my_malloc((argc+2)*sizeof(char*), if (!(load_default_groups=(char**) my_malloc((argc+2)*sizeof(char*),
MYF(MY_WME)))) MYF(MY_WME))))
exit(1); exit(1);
for (count=0; *argv ; argv++,count++) for (count=0; *argv ; argv++,count++)

View File

@ -346,6 +346,19 @@ struct tm *localtime_r(const time_t *clock, struct tm *res);
#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); }
#endif #endif
#ifdef HAVE_DARWIN_THREADS
#define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C))
#define pthread_kill(A,B) pthread_dummy(0)
#define pthread_condattr_init(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)
#undef pthread_detach_this_thread
#define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(&tmp); }
#undef sigset
#define sigset(A,B) pthread_signal((A),(void (*)(int)) (B))
#endif
#if ((defined(HAVE_PTHREAD_ATTR_CREATE) && !defined(HAVE_SIGWAIT)) || defined(HAVE_DEC_3_2_THREADS)) && !defined(HAVE_CTHREADS_WRAPPER) #if ((defined(HAVE_PTHREAD_ATTR_CREATE) && !defined(HAVE_SIGWAIT)) || defined(HAVE_DEC_3_2_THREADS)) && !defined(HAVE_CTHREADS_WRAPPER)
/* This is set on AIX_3_2 and Siemens unix (and DEC OSF/1 3.2 too) */ /* This is set on AIX_3_2 and Siemens unix (and DEC OSF/1 3.2 too) */
#define pthread_key_create(A,B) \ #define pthread_key_create(A,B) \

View File

@ -206,6 +206,7 @@ extern my_bool NEAR my_disable_locking,NEAR my_disable_async_io,
NEAR my_disable_flush_key_blocks; NEAR my_disable_flush_key_blocks;
extern char wild_many,wild_one,wild_prefix; extern char wild_many,wild_one,wild_prefix;
extern const char *charsets_dir; extern const char *charsets_dir;
extern char *defaults_extra_file;
typedef struct wild_file_pack /* Struct to hold info when selecting files */ typedef struct wild_file_pack /* Struct to hold info when selecting files */
{ {
@ -266,20 +267,21 @@ typedef struct st_dynamic_string {
typedef struct st_io_cache /* Used when cacheing files */ typedef struct st_io_cache /* Used when cacheing files */
{ {
my_off_t pos_in_file,end_of_file;
byte *rc_pos,*rc_end,*buffer,*rc_request_pos; byte *rc_pos,*rc_end,*buffer,*rc_request_pos;
int (*read_function)(struct st_io_cache *,byte *,uint);
char *file_name; /* if used with 'open_cached_file' */
char *dir,*prefix;
File file; File file;
int seek_not_done,error; int seek_not_done,error;
uint buffer_length,read_length; uint buffer_length,read_length;
my_off_t pos_in_file,end_of_file;
myf myflags; /* Flags used to my_read/my_write */ myf myflags; /* Flags used to my_read/my_write */
enum cache_type type;
#ifdef HAVE_AIOWAIT #ifdef HAVE_AIOWAIT
uint inited; uint inited;
my_off_t aio_read_pos; my_off_t aio_read_pos;
my_aio_result aio_result; my_aio_result aio_result;
#endif #endif
enum cache_type type;
int (*read_function)(struct st_io_cache *,byte *,uint);
char *file_name; /* if used with 'open_cached_file' */
} IO_CACHE; } IO_CACHE;
typedef int (*qsort2_cmp)(const void *, const void *, const void *); typedef int (*qsort2_cmp)(const void *, const void *, const void *);
@ -399,7 +401,7 @@ extern void TERMINATE(FILE *file);
#endif #endif
extern void init_glob_errs(void); extern void init_glob_errs(void);
extern FILE *my_fopen(const char *FileName,int Flags,myf MyFlags); extern FILE *my_fopen(const char *FileName,int Flags,myf MyFlags);
extern FILE *my_fdopen(File Filedes,int Flags,myf MyFlags); extern FILE *my_fdopen(File Filedes,const char *name, int Flags,myf MyFlags);
extern int my_fclose(FILE *fd,myf MyFlags); extern int my_fclose(FILE *fd,myf MyFlags);
extern int my_chsize(File fd,my_off_t newlength,myf MyFlags); extern int my_chsize(File fd,my_off_t newlength,myf MyFlags);
extern int my_error _VARARGS((int nr,myf MyFlags, ...)); extern int my_error _VARARGS((int nr,myf MyFlags, ...));
@ -430,7 +432,7 @@ extern uint dirname_part(my_string to,const char *name);
extern uint dirname_length(const char *name); extern uint dirname_length(const char *name);
#define base_name(A) (A+dirname_length(A)) #define base_name(A) (A+dirname_length(A))
extern int test_if_hard_path(const char *dir_name); extern int test_if_hard_path(const char *dir_name);
extern void convert_dirname(my_string name); extern char *convert_dirname(my_string name);
extern void to_unix_path(my_string name); extern void to_unix_path(my_string name);
extern my_string fn_ext(const char *name); extern my_string fn_ext(const char *name);
extern my_string fn_same(my_string toname,const char *name,int flag); extern my_string fn_same(my_string toname,const char *name,int flag);
@ -507,6 +509,8 @@ extern my_bool open_cached_file(IO_CACHE *cache,const char *dir,
myf cache_myflags); myf cache_myflags);
extern my_bool real_open_cached_file(IO_CACHE *cache); extern my_bool real_open_cached_file(IO_CACHE *cache);
extern void close_cached_file(IO_CACHE *cache); extern void close_cached_file(IO_CACHE *cache);
File create_temp_file(char *to, const char *dir, const char *pfx,
int mode, myf MyFlags);
extern my_bool init_dynamic_array(DYNAMIC_ARRAY *array,uint element_size, extern my_bool init_dynamic_array(DYNAMIC_ARRAY *array,uint element_size,
uint init_alloc,uint alloc_increment); uint init_alloc,uint alloc_increment);
extern my_bool insert_dynamic(DYNAMIC_ARRAY *array,gptr element); extern my_bool insert_dynamic(DYNAMIC_ARRAY *array,gptr element);

View File

@ -339,7 +339,6 @@ typedef struct st_mi_check_param
typedef struct st_mi_sortinfo { typedef struct st_mi_sortinfo {
uint key_length;
ha_rows max_records; ha_rows max_records;
SORT_INFO *sort_info; SORT_INFO *sort_info;
char *tmpdir; char *tmpdir;
@ -347,6 +346,8 @@ typedef struct st_mi_sortinfo {
int (*key_read)(SORT_INFO *info,void *buff); int (*key_read)(SORT_INFO *info,void *buff);
int (*key_write)(SORT_INFO *info, const void *buff); int (*key_write)(SORT_INFO *info, const void *buff);
void (*lock_in_memory)(MI_CHECK *info); void (*lock_in_memory)(MI_CHECK *info);
uint key_length;
myf myf_rw;
} MI_SORT_PARAM; } MI_SORT_PARAM;
/* functions in mi_check */ /* functions in mi_check */

View File

@ -45,7 +45,7 @@ mystringsextra= strto.c ctype_autoconf.c
dbugobjects = dbug.lo # IT IS IN SAFEMALLOC.C sanity.lo dbugobjects = dbug.lo # IT IS IN SAFEMALLOC.C sanity.lo
mysysheaders = mysys_priv.h my_static.h mysysheaders = mysys_priv.h my_static.h
mysysobjects1 = my_init.lo my_static.lo my_malloc.lo my_realloc.lo \ mysysobjects1 = my_init.lo my_static.lo my_malloc.lo my_realloc.lo \
my_create.lo my_delete.lo my_tempnam.lo my_open.lo \ my_create.lo my_delete.lo mf_tempfile.lo my_open.lo \
mf_casecnv.lo my_read.lo my_write.lo errors.lo \ mf_casecnv.lo my_read.lo my_write.lo errors.lo \
my_error.lo my_getwd.lo my_div.lo \ my_error.lo my_getwd.lo my_div.lo \
mf_pack.lo my_messnc.lo mf_dirname.lo mf_fn_ext.lo\ mf_pack.lo my_messnc.lo mf_dirname.lo mf_fn_ext.lo\

View File

@ -1798,7 +1798,7 @@ bsdi4*)
finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
shlibpath_var=LD_LIBRARY_PATH shlibpath_var=LD_LIBRARY_PATH
deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
file_magic_cmd=/usr/bin/file file_magic_cmd="/usr/bin/file -L"
file_magic_test_file=/shlib/libc.so file_magic_test_file=/shlib/libc.so
sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"

View File

@ -1789,6 +1789,9 @@ compiler."
*-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*) *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*)
# these systems don't actually have a c library (as such)! # these systems don't actually have a c library (as such)!
;; ;;
*-*-freebsd*)
# FreeBSD needs to handle -lc (or -lc_r) itself
;;
*) *)
# Add libc to deplibs on all other systems. # Add libc to deplibs on all other systems.
deplibs="$deplibs -lc" deplibs="$deplibs -lc"

View File

@ -1759,6 +1759,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
sort_param.key_read=sort_key_read; sort_param.key_read=sort_key_read;
sort_param.lock_in_memory=lock_memory; sort_param.lock_in_memory=lock_memory;
sort_param.tmpdir=param->tmpdir; sort_param.tmpdir=param->tmpdir;
sort_param.myf_rw=param->myf_rw;
sort_param.sort_info=sort_info; sort_param.sort_info=sort_info;
del=info->state->del; del=info->state->del;
@ -2921,8 +2922,10 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info,
!(((ulonglong) 1 << (info->s->base.auto_key-1) !(((ulonglong) 1 << (info->s->base.auto_key-1)
& info->s->state.key_map))) & info->s->state.key_map)))
{ {
mi_check_print_info(param,"Table: %s doesn't have an auto increment key\n", if (!(param->testflag & T_VERY_SILENT))
param->isam_file_name); mi_check_print_info(param,
"Table: %s doesn't have an auto increment key\n",
param->isam_file_name);
return; return;
} }
if (!(param->testflag & T_SILENT) && if (!(param->testflag & T_SILENT) &&

View File

@ -178,6 +178,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
((share->state.changed & STATE_CRASHED) || ((share->state.changed & STATE_CRASHED) ||
(my_disable_locking && share->state.open_count))) (my_disable_locking && share->state.open_count)))
{ {
DBUG_PRINT("error",("Table is marked as crashed"));
my_errno=((share->state.changed & STATE_CRASHED_ON_REPAIR) ? my_errno=((share->state.changed & STATE_CRASHED_ON_REPAIR) ?
HA_ERR_CRASHED_ON_REPAIR : HA_ERR_CRASHED); HA_ERR_CRASHED_ON_REPAIR : HA_ERR_CRASHED);
goto err; goto err;
@ -209,6 +210,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
#elif !defined(USE_RAID) #elif !defined(USE_RAID)
if (share->base.raid_type) if (share->base.raid_type)
{ {
DBUG_PRINT("error",("Table uses RAID but we don't have RAID support"));
my_errno=HA_ERR_UNSUPPORTED; my_errno=HA_ERR_UNSUPPORTED;
goto err; goto err;
} }
@ -219,6 +221,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
if (share->base.max_key_length > MI_MAX_KEY_BUFF || keys > MI_MAX_KEY || if (share->base.max_key_length > MI_MAX_KEY_BUFF || keys > MI_MAX_KEY ||
key_parts >= MI_MAX_KEY * MI_MAX_KEY_SEG) key_parts >= MI_MAX_KEY * MI_MAX_KEY_SEG)
{ {
DBUG_PRINT("error",("Wrong key info: Max_key_length: %d keys: %d key_parts: %d", share->base.max_key_length, keys, key_parts));
my_errno=HA_ERR_UNSUPPORTED; my_errno=HA_ERR_UNSUPPORTED;
goto err; goto err;
} }

View File

@ -33,6 +33,7 @@
#define MERGEBUFF2 31 #define MERGEBUFF2 31
#define MIN_SORT_MEMORY (4096-MALLOC_OVERHEAD) #define MIN_SORT_MEMORY (4096-MALLOC_OVERHEAD)
#define MYF_RW MYF(MY_NABP | MY_WME | MY_WAIT_IF_FULL) #define MYF_RW MYF(MY_NABP | MY_WME | MY_WAIT_IF_FULL)
#define DISK_BUFFER_SIZE (IO_SIZE*16)
typedef struct st_buffpek { typedef struct st_buffpek {
my_off_t file_pos; /* position to buffer */ my_off_t file_pos; /* position to buffer */
@ -47,30 +48,26 @@ extern void print_error _VARARGS((const char *fmt,...));
/* functions defined in this file */ /* functions defined in this file */
static ha_rows NEAR_F find_all_keys(MI_SORT_PARAM *info,uint keys, static ha_rows NEAR_F find_all_keys(MI_SORT_PARAM *info,uint keys,
uchar * *sort_keys, uchar **sort_keys,
BUFFPEK *buffpek,int *maxbuffer, BUFFPEK *buffpek,int *maxbuffer,
FILE **tempfile, my_string tempname); IO_CACHE *tempfile);
static int NEAR_F write_keys(MI_SORT_PARAM *info,uchar * *sort_keys, static int NEAR_F write_keys(MI_SORT_PARAM *info,uchar * *sort_keys,
uint count, BUFFPEK *buffpek,FILE **tempfile, uint count, BUFFPEK *buffpek,IO_CACHE *tempfile);
my_string tempname);
static int NEAR_F write_index(MI_SORT_PARAM *info,uchar * *sort_keys, static int NEAR_F write_index(MI_SORT_PARAM *info,uchar * *sort_keys,
uint count); uint count);
static int NEAR_F merge_many_buff(MI_SORT_PARAM *info,uint keys, static int NEAR_F merge_many_buff(MI_SORT_PARAM *info,uint keys,
uchar * *sort_keys, uchar * *sort_keys,
BUFFPEK *buffpek,int *maxbuffer, BUFFPEK *buffpek,int *maxbuffer,
FILE * *t_file, my_string tempname); IO_CACHE *t_file);
static uint NEAR_F read_to_buffer(FILE *fromfile,BUFFPEK *buffpek, static uint NEAR_F read_to_buffer(IO_CACHE *fromfile,BUFFPEK *buffpek,
uint sort_length); uint sort_length);
static int NEAR_F merge_buffers(MI_SORT_PARAM *info,uint keys,FILE *from_file, static int NEAR_F merge_buffers(MI_SORT_PARAM *info,uint keys,
FILE *to_file, uchar * *sort_keys, IO_CACHE *from_file, IO_CACHE *to_file,
BUFFPEK *lastbuff,BUFFPEK *Fb, uchar * *sort_keys, BUFFPEK *lastbuff,
BUFFPEK *Tb); BUFFPEK *Fb, BUFFPEK *Tb);
static int NEAR_F merge_index(MI_SORT_PARAM *,uint,uchar **,BUFFPEK *, int, static int NEAR_F merge_index(MI_SORT_PARAM *,uint,uchar **,BUFFPEK *, int,
FILE *); IO_CACHE *);
static char **make_char_array(uint fields,uint length,myf my_flag); static char **make_char_array(uint fields,uint length,myf my_flag);
static FILE *opentemp(my_string name,const char *temp_dir);
static void closetemp(my_string name,FILE *stream);
/* Creates a index of sorted keys */ /* Creates a index of sorted keys */
/* Returns 0 if everything went ok */ /* Returns 0 if everything went ok */
@ -81,14 +78,14 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
int error,maxbuffer,skr; int error,maxbuffer,skr;
uint memavl,old_memavl,keys,sort_length; uint memavl,old_memavl,keys,sort_length;
BUFFPEK *buffpek; BUFFPEK *buffpek;
char tempname[FN_REFLEN];
ha_rows records; ha_rows records;
uchar **sort_keys; uchar **sort_keys;
FILE *tempfile; IO_CACHE tempfile;
DBUG_ENTER("_create_index_by_sort"); DBUG_ENTER("_create_index_by_sort");
DBUG_PRINT("enter",("sort_length: %d", info->key_length)); DBUG_PRINT("enter",("sort_length: %d", info->key_length));
tempfile=0; buffpek= (BUFFPEK *) NULL; sort_keys= (uchar **) NULL; error= 1; my_b_clear(&tempfile);
buffpek= (BUFFPEK *) NULL; sort_keys= (uchar **) NULL; error= 1;
maxbuffer=1; maxbuffer=1;
memavl=max(sortbuff_size,MIN_SORT_MEMORY); memavl=max(sortbuff_size,MIN_SORT_MEMORY);
@ -139,8 +136,7 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
if (!no_messages) if (!no_messages)
printf(" - Searching for keys, allocating buffer for %d keys\n",keys); printf(" - Searching for keys, allocating buffer for %d keys\n",keys);
if ((records=find_all_keys(info,keys,sort_keys,buffpek,&maxbuffer,&tempfile, if ((records=find_all_keys(info,keys,sort_keys,buffpek,&maxbuffer,&tempfile))
tempname))
== HA_POS_ERROR) == HA_POS_ERROR)
goto err; goto err;
if (maxbuffer == 0) if (maxbuffer == 0)
@ -157,13 +153,15 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
{ {
if (!no_messages) if (!no_messages)
printf(" - Merging %lu keys\n",records); printf(" - Merging %lu keys\n",records);
if (merge_many_buff(info,keys,sort_keys,buffpek,&maxbuffer,&tempfile, if (merge_many_buff(info,keys,sort_keys,buffpek,&maxbuffer,&tempfile))
tempname))
goto err; goto err;
if (flush_io_cache(&tempfile) ||
reinit_io_cache(&tempfile,READ_CACHE,0L,0,0))
goto err;
} }
if (!no_messages) if (!no_messages)
puts(" - Last merge and dumping keys"); puts(" - Last merge and dumping keys");
if (merge_index(info,keys,sort_keys,buffpek,maxbuffer,tempfile)) if (merge_index(info,keys,sort_keys,buffpek,maxbuffer,&tempfile))
goto err; goto err;
} }
error =0; error =0;
@ -173,8 +171,7 @@ err:
my_free((gptr) sort_keys,MYF(0)); my_free((gptr) sort_keys,MYF(0));
if (buffpek) if (buffpek)
my_free((gptr) buffpek,MYF(0)); my_free((gptr) buffpek,MYF(0));
if (tempfile) close_cached_file(&tempfile);
closetemp(tempname,tempfile);
DBUG_RETURN(error ? -1 : 0); DBUG_RETURN(error ? -1 : 0);
} /* _create_index_by_sort */ } /* _create_index_by_sort */
@ -184,8 +181,7 @@ err:
static ha_rows NEAR_F find_all_keys(MI_SORT_PARAM *info, uint keys, static ha_rows NEAR_F find_all_keys(MI_SORT_PARAM *info, uint keys,
uchar **sort_keys, BUFFPEK *buffpek, uchar **sort_keys, BUFFPEK *buffpek,
int *maxbuffer, FILE **tempfile, int *maxbuffer, IO_CACHE *tempfile)
my_string tempname)
{ {
int error; int error;
uint idx,indexpos; uint idx,indexpos;
@ -198,8 +194,7 @@ static ha_rows NEAR_F find_all_keys(MI_SORT_PARAM *info, uint keys,
if ((uint) ++idx == keys) if ((uint) ++idx == keys)
{ {
if (indexpos >= (uint) *maxbuffer || if (indexpos >= (uint) *maxbuffer ||
write_keys(info,sort_keys,idx-1,buffpek+indexpos,tempfile, write_keys(info,sort_keys,idx-1,buffpek+indexpos,tempfile))
tempname))
DBUG_RETURN((ha_rows) -1); DBUG_RETURN((ha_rows) -1);
memcpy(sort_keys[0],sort_keys[idx-1],(size_t) info->key_length); memcpy(sort_keys[0],sort_keys[idx-1],(size_t) info->key_length);
idx=1; indexpos++; idx=1; indexpos++;
@ -209,7 +204,7 @@ static ha_rows NEAR_F find_all_keys(MI_SORT_PARAM *info, uint keys,
DBUG_RETURN(HA_POS_ERROR); /* Aborted by get_key */ DBUG_RETURN(HA_POS_ERROR); /* Aborted by get_key */
if (indexpos) if (indexpos)
if (indexpos >= (uint) *maxbuffer || if (indexpos >= (uint) *maxbuffer ||
write_keys(info,sort_keys,idx,buffpek+indexpos,tempfile,tempname)) write_keys(info,sort_keys,idx,buffpek+indexpos,tempfile))
DBUG_RETURN(HA_POS_ERROR); DBUG_RETURN(HA_POS_ERROR);
*maxbuffer=(int) indexpos; *maxbuffer=(int) indexpos;
DBUG_RETURN(indexpos*(keys-1)+idx); DBUG_RETURN(indexpos*(keys-1)+idx);
@ -220,18 +215,23 @@ static ha_rows NEAR_F find_all_keys(MI_SORT_PARAM *info, uint keys,
static int NEAR_F write_keys(MI_SORT_PARAM *info, register uchar **sort_keys, static int NEAR_F write_keys(MI_SORT_PARAM *info, register uchar **sort_keys,
uint count, BUFFPEK *buffpek, uint count, BUFFPEK *buffpek,
register FILE **tempfile, my_string tempname) IO_CACHE *tempfile)
{ {
uchar **end;
uint sort_length=info->key_length;
DBUG_ENTER("write_keys"); DBUG_ENTER("write_keys");
qsort2((byte*) sort_keys,count,sizeof(byte*),(qsort2_cmp) info->key_cmp, qsort2((byte*) sort_keys,count,sizeof(byte*),(qsort2_cmp) info->key_cmp,
info->sort_info); info->sort_info);
if (! *tempfile && ! (*tempfile=opentemp(tempname,info->tmpdir))) if (!my_b_inited(tempfile) &&
open_cached_file(tempfile, info->tmpdir, "ST", DISK_BUFFER_SIZE,
info->myf_rw))
DBUG_RETURN(1); DBUG_RETURN(1);
buffpek->file_pos=my_ftell(*tempfile,MYF(0)); buffpek->file_pos=my_b_tell(tempfile);
buffpek->count=count; buffpek->count=count;
while (count--)
if (my_fwrite(*tempfile,(byte*)*sort_keys++,info->key_length,MYF_RW)) for (end=sort_keys+count ; sort_keys != end ; sort_keys++)
if (my_b_write(tempfile,(byte*) *sort_keys,(uint) sort_length))
DBUG_RETURN(1); DBUG_RETURN(1);
DBUG_RETURN(0); DBUG_RETURN(0);
} /* write_keys */ } /* write_keys */
@ -239,7 +239,8 @@ static int NEAR_F write_keys(MI_SORT_PARAM *info, register uchar **sort_keys,
/* Write index */ /* Write index */
static int NEAR_F write_index(MI_SORT_PARAM *info, register uchar **sort_keys, register uint count) static int NEAR_F write_index(MI_SORT_PARAM *info, register uchar **sort_keys,
register uint count)
{ {
DBUG_ENTER("write_index"); DBUG_ENTER("write_index");
@ -256,22 +257,25 @@ static int NEAR_F write_index(MI_SORT_PARAM *info, register uchar **sort_keys, r
static int NEAR_F merge_many_buff(MI_SORT_PARAM *info, uint keys, static int NEAR_F merge_many_buff(MI_SORT_PARAM *info, uint keys,
uchar **sort_keys, BUFFPEK *buffpek, uchar **sort_keys, BUFFPEK *buffpek,
int *maxbuffer, FILE **t_file, int *maxbuffer, IO_CACHE *t_file)
my_string t_name)
{ {
register int i; register int i;
FILE *from_file,*to_file,*temp; IO_CACHE t_file2, *from_file, *to_file, *temp;
FILE *t_file2;
char t_name2[FN_REFLEN];
BUFFPEK *lastbuff; BUFFPEK *lastbuff;
DBUG_ENTER("merge_many_buff"); DBUG_ENTER("merge_many_buff");
if (!(t_file2=opentemp(t_name2,info->tmpdir))) if (*maxbuffer < MERGEBUFF2)
DBUG_RETURN(1); DBUG_RETURN(0); /* purecov: inspected */
if (flush_io_cache(t_file) ||
open_cached_file(&t_file2,info->tmpdir,"ST",DISK_BUFFER_SIZE,
info->myf_rw))
DBUG_RETURN(1); /* purecov: inspected */
from_file= *t_file ; to_file= t_file2; from_file= t_file ; to_file= &t_file2;
while (*maxbuffer >= MERGEBUFF2) while (*maxbuffer >= MERGEBUFF2)
{ {
reinit_io_cache(from_file,READ_CACHE,0L,0,0);
reinit_io_cache(to_file,WRITE_CACHE,0L,0,0);
lastbuff=buffpek; lastbuff=buffpek;
for (i=0 ; i <= *maxbuffer-MERGEBUFF*3/2 ; i+=MERGEBUFF) for (i=0 ; i <= *maxbuffer-MERGEBUFF*3/2 ; i+=MERGEBUFF)
{ {
@ -282,17 +286,14 @@ static int NEAR_F merge_many_buff(MI_SORT_PARAM *info, uint keys,
if (merge_buffers(info,keys,from_file,to_file,sort_keys,lastbuff++, if (merge_buffers(info,keys,from_file,to_file,sort_keys,lastbuff++,
buffpek+i,buffpek+ *maxbuffer)) buffpek+i,buffpek+ *maxbuffer))
break; break;
*maxbuffer= (int) (lastbuff-buffpek)-1; if (flush_io_cache(to_file))
break; /* purecov: inspected */
temp=from_file; from_file=to_file; to_file=temp; temp=from_file; from_file=to_file; to_file=temp;
VOID(my_fseek(to_file,0L,MY_SEEK_SET,MYF(0))); *maxbuffer= (int) (lastbuff-buffpek)-1;
} }
if (to_file == *t_file) close_cached_file(to_file); // This holds old result
{ if (to_file == t_file)
closetemp(t_name,to_file); *t_file=t_file2; // Copy result file
*t_file=t_file2;
VOID(strmov(t_name,t_name2));
}
else closetemp(t_name2,to_file);
DBUG_RETURN(*maxbuffer >= MERGEBUFF2); /* Return 1 if interrupted */ DBUG_RETURN(*maxbuffer >= MERGEBUFF2); /* Return 1 if interrupted */
} /* merge_many_buff */ } /* merge_many_buff */
@ -301,20 +302,17 @@ static int NEAR_F merge_many_buff(MI_SORT_PARAM *info, uint keys,
/* Read data to buffer */ /* Read data to buffer */
/* This returns (uint) -1 if something goes wrong */ /* This returns (uint) -1 if something goes wrong */
static uint NEAR_F read_to_buffer(FILE *fromfile, BUFFPEK *buffpek, uint sort_length) static uint NEAR_F read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
uint sort_length)
{ {
register uint count; register uint count;
uint length; uint length;
count=buffpek->max_keys; if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
if ((ha_rows) count > buffpek->count)
count=(uint) buffpek->count;
if (count)
{ {
VOID(my_fseek(fromfile,buffpek->file_pos,MY_SEEK_SET,MYF(0))); if (my_pread(fromfile->file,(byte*) buffpek->base,
if (my_fread(fromfile,(byte*) buffpek->base, (length= sort_length*count),buffpek->file_pos,MYF_RW))
(length= sort_length*count),MYF_RW)) return((uint) -1); /* purecov: inspected */
return((uint) -1);
buffpek->key=buffpek->base; buffpek->key=buffpek->base;
buffpek->file_pos+= length; /* New filepos */ buffpek->file_pos+= length; /* New filepos */
buffpek->count-= count; buffpek->count-= count;
@ -328,8 +326,9 @@ static uint NEAR_F read_to_buffer(FILE *fromfile, BUFFPEK *buffpek, uint sort_le
/* If to_file == 0 then use info->key_write */ /* If to_file == 0 then use info->key_write */
static int NEAR_F static int NEAR_F
merge_buffers(MI_SORT_PARAM *info, uint keys, FILE *from_file, FILE *to_file, merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
uchar **sort_keys, BUFFPEK *lastbuff, BUFFPEK *Fb, BUFFPEK *Tb) IO_CACHE *to_file, uchar **sort_keys, BUFFPEK *lastbuff,
BUFFPEK *Fb, BUFFPEK *Tb)
{ {
int error; int error;
uint sort_length,maxcount; uint sort_length,maxcount;
@ -342,12 +341,11 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, FILE *from_file, FILE *to_file,
count=error=0; count=error=0;
maxcount=keys/((uint) (Tb-Fb) +1); maxcount=keys/((uint) (Tb-Fb) +1);
sort_length=info->key_length;
LINT_INIT(to_start_filepos); LINT_INIT(to_start_filepos);
if (to_file) if (to_file)
to_start_filepos=my_ftell(to_file,MYF(0)); to_start_filepos=my_b_tell(to_file);
strpos=(uchar*) sort_keys; strpos=(uchar*) sort_keys;
sort_length=info->key_length;
if (init_queue(&queue,(uint) (Tb-Fb)+1,offsetof(BUFFPEK,key),0, if (init_queue(&queue,(uint) (Tb-Fb)+1,offsetof(BUFFPEK,key),0,
(int (*)(void*, byte *,byte*)) info->key_cmp, (int (*)(void*, byte *,byte*)) info->key_cmp,
@ -373,8 +371,7 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, FILE *from_file, FILE *to_file,
buffpek=(BUFFPEK*) queue_top(&queue); buffpek=(BUFFPEK*) queue_top(&queue);
if (to_file) if (to_file)
{ {
if (my_fwrite(to_file,(byte*) buffpek->key,(uint) sort_length, if (my_b_write(to_file,(byte*) buffpek->key,(uint) sort_length))
MYF_RW | MY_WAIT_IF_FULL))
{ {
error=1; goto err; error=1; goto err;
} }
@ -417,6 +414,8 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, FILE *from_file, FILE *to_file,
break; /* One buffer have been removed */ break; /* One buffer have been removed */
} }
} }
else if (error == -1)
goto err; /* purecov: inspected */
queue_replaced(&queue); /* Top element has been replaced */ queue_replaced(&queue); /* Top element has been replaced */
} }
} }
@ -427,9 +426,8 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, FILE *from_file, FILE *to_file,
{ {
if (to_file) if (to_file)
{ {
if (my_fwrite(to_file,(byte*) buffpek->key, if (my_b_write(to_file,(byte*) buffpek->key,
(uint) (sort_length*buffpek->mem_count), (sort_length*buffpek->mem_count)))
MYF_RW | MY_WAIT_IF_FULL))
{ {
error=1; goto err; error=1; goto err;
} }
@ -454,7 +452,7 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, FILE *from_file, FILE *to_file,
lastbuff->count=count; lastbuff->count=count;
if (to_file) if (to_file)
lastbuff->file_pos=to_start_filepos; /* New block starts here */ lastbuff->file_pos=to_start_filepos;
err: err:
delete_queue(&queue); delete_queue(&queue);
DBUG_RETURN(error); DBUG_RETURN(error);
@ -465,10 +463,10 @@ err:
static int NEAR_F static int NEAR_F
merge_index(MI_SORT_PARAM *info, uint keys, uchar **sort_keys, merge_index(MI_SORT_PARAM *info, uint keys, uchar **sort_keys,
BUFFPEK *buffpek, int maxbuffer, FILE *tempfile) BUFFPEK *buffpek, int maxbuffer, IO_CACHE *tempfile)
{ {
DBUG_ENTER("merge_index"); DBUG_ENTER("merge_index");
if (merge_buffers(info,keys,tempfile,(FILE*) 0,sort_keys,buffpek,buffpek, if (merge_buffers(info,keys,tempfile,(IO_CACHE*) 0,sort_keys,buffpek,buffpek,
buffpek+maxbuffer)) buffpek+maxbuffer))
DBUG_RETURN(1); DBUG_RETURN(1);
DBUG_RETURN(0); DBUG_RETURN(0);
@ -492,40 +490,3 @@ static char **make_char_array(register uint fields, uint length, myf my_flag)
DBUG_RETURN(old_pos); DBUG_RETURN(old_pos);
} /* make_char_array */ } /* make_char_array */
/* Open a temporary file that will be deleted on close */
static FILE *opentemp(my_string name,const char *temp_dir)
{
FILE *stream;
reg1 my_string str_pos;
DBUG_ENTER("opentemp");
if (!(str_pos=my_tempnam(temp_dir,"ST",MYF(MY_WME))))
DBUG_RETURN(0);
VOID(strmov(name,str_pos));
(*free)(str_pos); /* Avoid the 'free' macro */
stream=my_fopen(name,(int) (O_RDWR | FILE_BINARY | O_CREAT | O_TEMPORARY),
MYF(MY_WME));
#if O_TEMPORARY == 0 && !defined(CANT_DELETE_OPEN_FILES)
VOID(my_delete(name,MYF(MY_WME | ME_NOINPUT)));
#endif
DBUG_PRINT("exit",("stream: %lx",stream));
DBUG_RETURN (stream);
} /* opentemp */
static void closetemp(my_string name __attribute__((unused)), FILE *stream)
{
DBUG_ENTER("closetemp");
if (stream)
VOID(my_fclose(stream,MYF(MY_WME)));
#if !(O_TEMPORARY == 0 && !defined(CANT_DELETE_OPEN_FILES))
if (name)
VOID(my_delete(name,MYF(MY_WME)));
#endif
DBUG_VOID_RETURN;
} /* closetemp */

View File

@ -26,7 +26,8 @@ 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_iocache.c mf_cache.c \ mf_reccache.c mf_keycache.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 \
my_alloc.c safemalloc.c my_fopen.c my_fstream.c \ my_alloc.c safemalloc.c my_fopen.c my_fstream.c \

View File

@ -29,8 +29,9 @@
** The following arguments are handled automaticly; If used, they must be ** The following arguments are handled automaticly; If used, they must be
** first argument on the command line! ** first argument on the command line!
** --no-defaults ; no options are read. ** --no-defaults ; no options are read.
** --print-defaults ; Print the modified command line and exit
** --defaults-file=full-path-to-default-file ; Only this file will be read. ** --defaults-file=full-path-to-default-file ; Only this file will be read.
** --defaults-extra-file=full-path-to-default-file ; Read this file before ~/
** --print-defaults ; Print the modified command line and exit
****************************************************************************/ ****************************************************************************/
#undef SAFEMALLOC /* safe_malloc is not yet initailized */ #undef SAFEMALLOC /* safe_malloc is not yet initailized */
@ -39,6 +40,8 @@
#include "m_string.h" #include "m_string.h"
#include "m_ctype.h" #include "m_ctype.h"
char *defaults_extra_file=0;
/* Which directories are searched for options (and in which order) */ /* Which directories are searched for options (and in which order) */
const char *default_directories[]= { const char *default_directories[]= {
@ -50,6 +53,7 @@ const char *default_directories[]= {
#ifdef DATADIR #ifdef DATADIR
DATADIR, DATADIR,
#endif #endif
"", /* Place for defaults_extra_dir */
#ifndef __WIN__ #ifndef __WIN__
"~/", "~/",
#endif #endif
@ -71,9 +75,10 @@ void load_defaults(const char *conf_file, const char **groups,
int *argc, char ***argv) int *argc, char ***argv)
{ {
DYNAMIC_ARRAY args; DYNAMIC_ARRAY args;
const char **dirs, *extra_default_file; const char **dirs, *forced_default_file;
TYPELIB group; TYPELIB group;
my_bool found_print_defaults=0; my_bool found_print_defaults=0;
uint args_used=0;
MEM_ROOT alloc; MEM_ROOT alloc;
char *ptr,**res; char *ptr,**res;
DBUG_ENTER("load_defaults"); DBUG_ENTER("load_defaults");
@ -97,9 +102,20 @@ void load_defaults(const char *conf_file, const char **groups,
} }
/* Check if we want to force the use a specific default file */ /* Check if we want to force the use a specific default file */
extra_default_file=0; forced_default_file=0;
if (*argc >= 2 && is_prefix(argv[0][1],"--defaults-file=")) if (*argc >= 2)
extra_default_file=strchr(argv[0][1],'=')+1; {
if (is_prefix(argv[0][1],"--defaults-file="))
{
forced_default_file=strchr(argv[0][1],'=')+1;
args_used++;
}
else if (is_prefix(argv[0][1],"--defaults-extra-file="))
{
defaults_extra_file=strchr(argv[0][1],'=')+1;
args_used++;
}
}
group.count=0; group.count=0;
group.name= "defaults"; group.name= "defaults";
@ -109,9 +125,9 @@ void load_defaults(const char *conf_file, const char **groups,
if (init_dynamic_array(&args, sizeof(char*),*argc, 32)) if (init_dynamic_array(&args, sizeof(char*),*argc, 32))
goto err; goto err;
if (extra_default_file) if (forced_default_file)
{ {
if (search_default_file(&args, &alloc, "", extra_default_file, "", if (search_default_file(&args, &alloc, "", forced_default_file, "",
&group)) &group))
goto err; goto err;
} }
@ -132,8 +148,14 @@ void load_defaults(const char *conf_file, const char **groups,
#endif #endif
for (dirs=default_directories ; *dirs; dirs++) for (dirs=default_directories ; *dirs; dirs++)
{ {
if (search_default_file(&args, &alloc, *dirs, conf_file, default_ext, int error;
&group)) if (**dirs)
error=search_default_file(&args, &alloc, *dirs, conf_file,
default_ext, &group);
else if (defaults_extra_file)
error=search_default_file(&args, &alloc, NullS, defaults_extra_file,
default_ext, &group);
if (error)
goto err; goto err;
} }
} }
@ -145,11 +167,9 @@ void load_defaults(const char *conf_file, const char **groups,
/* copy name + found arguments + command line arguments to new array */ /* copy name + found arguments + command line arguments to new array */
res[0]=argv[0][0]; res[0]=argv[0][0];
memcpy((gptr) (res+1), args.buffer, args.elements*sizeof(char*)); memcpy((gptr) (res+1), args.buffer, args.elements*sizeof(char*));
if (extra_default_file) /* Skipp --defaults-file and --defaults-extra-file */
{ (*argc)-= args_used;
--*argc; /* Skipp --defaults-file */ (*argv)+= args_used;
++*argv;
}
/* Check if we wan't to see the new argument list */ /* Check if we wan't to see the new argument list */
if (*argc >= 2 && !strcmp(argv[0][1],"--print-defaults")) if (*argc >= 2 && !strcmp(argv[0][1],"--print-defaults"))

View File

@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version. version 2 of the License, or (at your option) any later version.
This library 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 GNU MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details. Library General Public License for more details.
You should have received a copy of the GNU Library General Public You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
@ -18,66 +18,103 @@
/* Open a temporary file and cache it with io_cache. Delete it on close */ /* Open a temporary file and cache it with io_cache. Delete it on close */
#include "mysys_priv.h" #include "mysys_priv.h"
#include <m_string.h>
#include "my_static.h"
#include "mysys_err.h"
/* /*
** Open a cached tempfile by IO_CACHE Remove an open tempfile so that it doesn't survive
if we crash; If the operating system doesn't support
this, just remember the file name for later removal
*/
static my_bool cache_remove_open_tmp(IO_CACHE *cache, const char *name)
{
#if O_TEMPORARY == 0
#if !defined(CANT_DELETE_OPEN_FILES)
/* The following should always succeed */
(void) my_delete(name,MYF(MY_WME | ME_NOINPUT));
#else
int length;
if (!(cache->file_name=
(char*) my_malloc((length=strlen(name)+1),MYF(MY_WME)))
{
my_close(cache->file,MYF(0));
cache->file = -1;
errno=my_error=ENOMEM;
return 1;
}
memcpy(cache->file_name,name,length);
#endif
#endif /* O_TEMPORARY == 0 */
return 0;
}
/*
** Open tempfile cached by IO_CACHE
** Should be used when no seeks are done (only reinit_io_buff) ** Should be used when no seeks are done (only reinit_io_buff)
** Return 0 if cache is inited ok ** Return 0 if cache is inited ok
** The actual file is created when the IO_CACHE buffer gets filled ** The actual file is created when the IO_CACHE buffer gets filled
** If dir is not given, use TMPDIR.
*/ */
my_bool open_cached_file(IO_CACHE *cache, const char* dir, const char *prefix, my_bool open_cached_file(IO_CACHE *cache, const char* dir, const char *prefix,
uint cache_size, myf cache_myflags) uint cache_size, myf cache_myflags)
{ {
DBUG_ENTER("open_cached_file"); DBUG_ENTER("open_cached_file");
cache->dir= dir ? my_strdup(dir,MYF(cache_myflags & MY_WME)) : (char*) 0;
cache->prefix= (prefix ? my_strdup(prefix,MYF(cache_myflags & MY_WME)) :
(char*) 0);
cache->file_name=0;
cache->buffer=0; /* Mark that not open */ cache->buffer=0; /* Mark that not open */
if (!(cache->file_name=my_tempnam(dir,prefix,MYF(MY_WME))))
DBUG_RETURN(1);
if (!init_io_cache(cache,-1,cache_size,WRITE_CACHE,0L,0, if (!init_io_cache(cache,-1,cache_size,WRITE_CACHE,0L,0,
MYF(cache_myflags | MY_NABP))) MYF(cache_myflags | MY_NABP)))
{ {
DBUG_RETURN(0); DBUG_RETURN(0);
} }
(*free)(cache->file_name); /* my_tempnam uses malloc() */ my_free(cache->dir, MYF(MY_ALLOW_ZERO_PTR));
cache->file_name=0; my_free(cache->prefix,MYF(MY_ALLOW_ZERO_PTR));
DBUG_RETURN(0); DBUG_RETURN(0);
} }
/* Create the temporary file */
my_bool real_open_cached_file(IO_CACHE *cache) my_bool real_open_cached_file(IO_CACHE *cache)
{ {
char name_buff[FN_REFLEN];
int error=1;
DBUG_ENTER("real_open_cached_file"); DBUG_ENTER("real_open_cached_file");
if ((cache->file=my_create(cache->file_name,0, if ((cache->file=create_temp_file(name_buff, cache->dir, cache->prefix,
(int) (O_RDWR | O_BINARY | O_TRUNC | O_TEMPORARY | (O_RDWR | O_BINARY | O_TRUNC |
O_SHORT_LIVED), O_TEMPORARY | O_SHORT_LIVED),
MYF(MY_WME))) >= 0) MYF(MY_WME))) >= 0)
{ {
#if O_TEMPORARY == 0 && !defined(CANT_DELETE_OPEN_FILES) error=0;
VOID(my_delete(cache->file_name,MYF(MY_WME | ME_NOINPUT))); cache_remove_open_tmp(cache, name_buff);
#endif
DBUG_RETURN(0);
} }
DBUG_RETURN(1); DBUG_RETURN(error);
} }
void close_cached_file(IO_CACHE *cache) 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))
{ {
VOID(end_io_cache(cache)); (void) end_io_cache(cache);
if (cache->file >= 0) if (cache->file >= 0)
{ {
VOID(my_close(cache->file,MYF(MY_WME))); (void) my_close(cache->file,MYF(0));
#ifdef CANT_DELETE_OPEN_FILES #ifdef CANT_DELETE_OPEN_FILES
VOID(my_delete(cache->file_name,MYF(MY_WME | ME_NOINPUT))); if (cache->file_name)
{
(void) my_delete(cache->file_name,MYF(MY_WME | ME_NOINPUT));
my_free(cache->file_name,MYF(0));
}
#endif #endif
} }
if (cache->file_name) my_free(cache->dir,MYF(MY_ALLOW_ZERO_PTR));
(*free)(cache->file_name); /* my_tempnam uses malloc() */ my_free(cache->prefix,MYF(MY_ALLOW_ZERO_PTR));
} }
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }

View File

@ -66,8 +66,9 @@ uint dirname_part(my_string to, const char *name)
#define FN_DEVCHAR '\0' /* For easier code */ #define FN_DEVCHAR '\0' /* For easier code */
#endif #endif
void convert_dirname(my_string to) char *convert_dirname(my_string to)
{ {
reg1 char *pos;
#ifdef FN_UPPER_CASE #ifdef FN_UPPER_CASE
caseup_str(to); caseup_str(to);
#endif #endif
@ -76,7 +77,6 @@ void convert_dirname(my_string to)
#endif #endif
#if FN_LIBCHAR != '/' #if FN_LIBCHAR != '/'
{ {
reg1 my_string pos;
pos=to-1; /* Change from '/' */ pos=to-1; /* Change from '/' */
while ((pos=strchr(pos+1,'/')) != 0) while ((pos=strchr(pos+1,'/')) != 0)
*pos=FN_LIBCHAR; *pos=FN_LIBCHAR;
@ -84,7 +84,6 @@ void convert_dirname(my_string to)
#endif #endif
#ifdef FN_C_BEFORE_DIR_2 #ifdef FN_C_BEFORE_DIR_2
{ {
reg1 my_string pos;
for (pos=to ; *pos ; pos++) for (pos=to ; *pos ; pos++)
{ {
if (*pos == FN_C_BEFORE_DIR_2) if (*pos == FN_C_BEFORE_DIR_2)
@ -95,12 +94,13 @@ void convert_dirname(my_string to)
} }
#else #else
{ /* Append FN_LIBCHAR if not there */ { /* Append FN_LIBCHAR if not there */
char *end=strend(to); pos=strend(to);
if (end != to && (end[-1] != FN_LIBCHAR && end[-1] != FN_DEVCHAR)) if (pos != to && (pos[-1] != FN_LIBCHAR && pos[-1] != FN_DEVCHAR))
{ {
end[0]=FN_LIBCHAR; *pos++=FN_LIBCHAR;
end[1]=0; *pos=0;
} }
} }
#endif #endif
return pos; /* Pointer to end of dir */
} /* convert_dirname */ } /* convert_dirname */

173
mysys/mf_tempfile.c Normal file
View File

@ -0,0 +1,173 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA */
#include "mysys_priv.h"
#include <m_string.h>
#include "my_static.h"
#include "mysys_err.h"
#include <errno.h>
#ifdef HAVE_PATHS_H
#include <paths.h>
#endif
#ifdef HAVE_TEMPNAM
#ifndef MSDOS
extern char **environ;
#endif
#endif
/*
Create a temporary file in a given directory
This function should be used instead of my_tempnam() !
*/
File create_temp_file(char *to, const char *dir, const char *prefix,
int mode, myf MyFlags)
{
File file= -1;
DBUG_ENTER("open_temp_file");
#if defined(_MSC_VER)
{
char *end,*res,**old_env,*temp_env[1];
old_env=environ;
if (dir)
{
end=strend(dir)-1;
if (!dir[0])
{ /* Change empty string to current dir */
to[0]= FN_CURLIB;
to[1]= 0;
dir=to;
}
else if (*end == FN_DEVCHAR)
{ /* Get current dir for drive */
_fullpath(temp,dir,FN_REFLEN);
dir=to;
}
else if (*end == FN_LIBCHAR && dir < end && end[-1] != FN_DEVCHAR)
{
strmake(to,dir,(uint) (end-dir)); /* Copy and remove last '\' */
dir=to;
}
environ=temp_env; /* Force use of dir (dir not checked) */
temp_env[0]=0;
}
if ((res=tempnam((char*) dir,(char *) prefix)))
{
strnmov(to,res,FN_REFLEN);
(*free)(res);
file=my_create(to,0, mode, MyFlags);
}
environ=old_env;
}
#elif defined(_ZTC__)
if (!dir)
dir=getenv("TMPDIR");
if ((res=tempnam((char*) dir,(char *) prefix)))
{
strnmov(to,res,FN_REFLEN);
(*free)(res);
file=my_create(to, 0, mode, MyFlags);
}
#elif defined(HAVE_MKSTEMP)
{
char prefix[30];
uint pfx_len;
pfx_len=(strmov(strnmov(prefix,
prefix ? prefix : "tmp.",
sizeof(prefix)-7),"XXXXXX") - prefix);
if (!dir && ! (dir =getenv("TMPDIR")))
dir=P_tmpdir;
if (strlen(dir)+ pfx_len > FN_REFLEN-2)
{
errno=my_errno= ENAMETOOLONG;
return 1;
}
strmov(to,dir);
strmov(convert_dirname(to),prefix);
file=mkstemp(to);
}
#elif defined(HAVE_TEMPNAM)
{
char *res,**old_env,*temp_env[1];
if (dir && !dir[0])
{ /* Change empty string to current dir */
to[0]= FN_CURLIB;
to[1]= 0;
dir=to;
}
old_env=environ;
if (dir)
{ /* Don't use TMPDIR if dir is given */
environ=temp_env;
temp_env[0]=0;
}
if ((res=tempnam((char*) dir, (char*) prefix)))
{
strnmov(to,res,FN_REFLEN);
(*free)(res);
file=my_create(to,0,
(int) (O_RDWR | O_BINARY | O_TRUNC |
O_TEMPORARY | O_SHORT_LIVED),
MYF(MY_WME));
}
else
{
DBUG_PRINT("error",("Got error: %d from tempnam",errno));
}
environ=old_env;
}
#else
{
register long uniq;
register int length;
my_string pos,end_pos;
/* Make an unique number */
pthread_mutex_lock(&THR_LOCK_open);
uniq= ((long) getpid() << 20) + (long) _my_tempnam_used++ ;
pthread_mutex_unlock(&THR_LOCK_open);
if (!dir && !(dir=getenv("TMPDIR"))) /* Use this if possibly */
dir=P_tmpdir; /* Use system default */
length=strlen(dir)+strlen(pfx)+1;
DBUG_PRINT("test",("mallocing %d byte",length+8+sizeof(TMP_EXT)+1));
if (length+8+sizeof(TMP_EXT)+1 > FN_REFLENGTH)
errno=my_errno= ENAMETOOLONG;
else
{
end_pos=strmov(to,dir);
if (end_pos != to && end_pos[-1] != FN_LIBCHAR)
*end_pos++=FN_LIBCHAR;
end_pos=strmov(end_pos,pfx);
for (length=0 ; length < 8 && uniq ; length++)
{
*end_pos++= _dig_vec[(int) (uniq & 31)];
uniq >>= 5;
}
(void) strmov(end_pos,TMP_EXT);
file=my_create(to,0,
(int) (O_RDWR | O_BINARY | O_TRUNC |
O_TEMPORARY | O_SHORT_LIVED),
MYF(MY_WME));
}
}
#endif
DBUG_RETURN(file);
}

View File

@ -95,7 +95,7 @@ int my_fclose(FILE *fd, myf MyFlags)
if ((uint) file < MY_NFILE && my_file_info[file].type != UNOPEN) if ((uint) file < MY_NFILE && my_file_info[file].type != UNOPEN)
{ {
my_file_info[file].type = UNOPEN; my_file_info[file].type = UNOPEN;
my_free(my_file_info[file].name, MYF(0)); my_free(my_file_info[file].name, MYF(MY_ALLOW_ZERO_PTR));
} }
pthread_mutex_unlock(&THR_LOCK_open); pthread_mutex_unlock(&THR_LOCK_open);
DBUG_RETURN(err); DBUG_RETURN(err);
@ -103,11 +103,9 @@ int my_fclose(FILE *fd, myf MyFlags)
/* Make a stream out of a file handle */ /* Make a stream out of a file handle */
/* Name may be 0 */
FILE *my_fdopen(File Filedes, int Flags, myf MyFlags) FILE *my_fdopen(File Filedes, const char *name, int Flags, myf MyFlags)
/* Read | write .. */
/* Special flags */
{ {
FILE *fd; FILE *fd;
char type[5]; char type[5];
@ -125,11 +123,18 @@ FILE *my_fdopen(File Filedes, int Flags, myf MyFlags)
else else
{ {
pthread_mutex_lock(&THR_LOCK_open); pthread_mutex_lock(&THR_LOCK_open);
if (my_file_info[Filedes].type != UNOPEN) my_stream_opened++;
if (Filedes < MY_NFILE)
{ {
if (my_file_info[Filedes].type != UNOPEN)
{
my_file_opened--; /* File is opened with my_open ! */
}
else
{
my_file_info[Filedes].name= my_strdup(name,MyFlags);
}
my_file_info[Filedes].type = STREAM_BY_FDOPEN; my_file_info[Filedes].type = STREAM_BY_FDOPEN;
my_file_opened--; /* File is opened with my_open ! */
my_stream_opened++;
} }
pthread_mutex_unlock(&THR_LOCK_open); pthread_mutex_unlock(&THR_LOCK_open);
} }

View File

@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version. version 2 of the License, or (at your option) any later version.
This library 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 GNU MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details. Library General Public License for more details.
You should have received a copy of the GNU Library General Public You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,

View File

@ -351,7 +351,7 @@ rl_translate_keyseq (seq, array, len)
{ {
register int i, c, l, temp; register int i, c, l, temp;
for (i = l = 0; c = seq[i]; i++) for (i = l = 0; (c = seq[i]); i++)
{ {
if (c == '\\') if (c == '\\')
{ {
@ -1028,7 +1028,7 @@ rl_parse_and_bind (string)
{ {
int passc = 0; int passc = 0;
for (i = 1; c = string[i]; i++) for (i = 1; (c = string[i]); i++)
{ {
if (passc) if (passc)
{ {
@ -1104,7 +1104,7 @@ rl_parse_and_bind (string)
{ {
int delimiter = string[i++], passc; int delimiter = string[i++], passc;
for (passc = 0; c = string[i]; i++) for (passc = 0; (c = string[i]); i++)
{ {
if (passc) if (passc)
{ {
@ -1721,7 +1721,7 @@ rl_function_dumper (print_readably)
fprintf (rl_outstream, "\n"); fprintf (rl_outstream, "\n");
for (i = 0; name = names[i]; i++) for (i = 0; (name = names[i]); i++)
{ {
Function *function; Function *function;
char **invokers; char **invokers;

View File

@ -1377,7 +1377,7 @@ completion_matches (text, entry_function)
match_list = (char **)xmalloc ((match_list_size + 1) * sizeof (char *)); match_list = (char **)xmalloc ((match_list_size + 1) * sizeof (char *));
match_list[1] = (char *)NULL; match_list[1] = (char *)NULL;
while (string = (*entry_function) (text, matches)) while ((string = (*entry_function) (text, matches)))
{ {
if (matches + 1 == match_list_size) if (matches + 1 == match_list_size)
match_list = (char **)xrealloc match_list = (char **)xrealloc
@ -1427,7 +1427,7 @@ username_completion_function (text, state)
setpwent (); setpwent ();
} }
while (entry = getpwent ()) while ((entry = getpwent ()))
{ {
/* Null usernames should result in all users as possible completions. */ /* Null usernames should result in all users as possible completions. */
if (namelen == 0 || (STREQN (username, entry->pw_name, namelen))) if (namelen == 0 || (STREQN (username, entry->pw_name, namelen)))

View File

@ -200,7 +200,7 @@ get_history_event (string, caller_index, delimiting_quote)
} }
/* Only a closing `?' or a newline delimit a substring search string. */ /* Only a closing `?' or a newline delimit a substring search string. */
for (local_index = i; c = string[i]; i++) for (local_index = i; (c = string[i]); i++)
if ((!substring_okay && (whitespace (c) || c == ':' || if ((!substring_okay && (whitespace (c) || c == ':' ||
(history_search_delimiter_chars && member (c, history_search_delimiter_chars)) || (history_search_delimiter_chars && member (c, history_search_delimiter_chars)) ||
string[i] == delimiting_quote)) || string[i] == delimiting_quote)) ||

View File

@ -368,7 +368,7 @@ rl_read_key ()
else else
{ {
/* If input is coming from a macro, then use that. */ /* If input is coming from a macro, then use that. */
if (c = _rl_next_macro_key ()) if ((c = _rl_next_macro_key ()))
return (c); return (c);
/* If the user has an event function, then call it periodically. */ /* If the user has an event function, then call it periodically. */

View File

@ -174,7 +174,7 @@ noninc_search (dir, pchar)
#define SEARCH_RETURN rl_restore_prompt (); return #define SEARCH_RETURN rl_restore_prompt (); return
/* Read the search string. */ /* Read the search string. */
while (c = rl_read_key ()) while ((c = rl_read_key ()))
{ {
switch (c) switch (c)
{ {

View File

@ -38,6 +38,10 @@
# include "ansi_stdlib.h" # include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */ #endif /* HAVE_STDLIB_H */
#if defined (HAVE_STDIO_H)
# include <stdio.h>
#endif /* HAVE_STDIO_H */
#if defined (HAVE_STRING_H) #if defined (HAVE_STRING_H)
# include <string.h> # include <string.h>
#else #else

View File

@ -232,6 +232,8 @@ _rl_set_screen_size (rows, cols)
screenchars = screenwidth * screenheight; screenchars = screenwidth * screenheight;
} }
extern void _rl_redisplay_after_sigwinch();
void void
rl_resize_terminal () rl_resize_terminal ()
{ {
@ -251,32 +253,32 @@ struct _tc_string {
search algorithm to something smarter. */ search algorithm to something smarter. */
static struct _tc_string tc_strings[] = static struct _tc_string tc_strings[] =
{ {
"DC", &term_DC, {"DC", &term_DC},
"IC", &term_IC, {"IC", &term_IC},
"ce", &term_clreol, {"ce", &term_clreol},
"cl", &term_clrpag, {"cl", &term_clrpag},
"cr", &term_cr, {"cr", &term_cr},
"dc", &term_dc, {"dc", &term_dc},
"ei", &term_ei, {"ei", &term_ei},
"ic", &term_ic, {"ic", &term_ic},
"im", &term_im, {"im", &term_im},
"kd", &term_kd, {"kd", &term_kd},
"kh", &term_kh, /* home */ {"kh", &term_kh}, /* home */
"kH", &term_kH, /* end */ {"kH", &term_kH}, /* end */
"kl", &term_kl, {"kl", &term_kl},
"kr", &term_kr, {"kr", &term_kr},
"ku", &term_ku, {"ku", &term_ku},
"ks", &term_ks, {"ks", &term_ks},
"ke", &term_ke, {"ke", &term_ke},
"le", &term_backspace, {"le", &term_backspace},
"mm", &term_mm, {"mm", &term_mm},
"mo", &term_mo, {"mo", &term_mo},
#if defined (HACK_TERMCAP_MOTION) #if defined (HACK_TERMCAP_MOTION)
"nd", &term_forward_char, {"nd", &term_forward_char},
#endif #endif
"pc", &term_pc, {"pc", &term_pc},
"up", &term_up, {"up", &term_up},
"vb", &visible_bell, {"vb", &visible_bell},
}; };
#define NUM_TC_STRINGS (sizeof (tc_strings) / sizeof (struct _tc_string)) #define NUM_TC_STRINGS (sizeof (tc_strings) / sizeof (struct _tc_string))

View File

@ -182,7 +182,7 @@ tilde_expand (string)
int result_size, result_index; int result_size, result_index;
result_index = result_size = 0; result_index = result_size = 0;
if (result = strchr (string, '~')) if ((result = strchr (string, '~')))
result = xmalloc (result_size = (strlen (string) + 16)); result = xmalloc (result_size = (strlen (string) + 16));
else else
result = xmalloc (result_size = (strlen (string) + 1)); result = xmalloc (result_size = (strlen (string) + 1));

View File

@ -106,7 +106,7 @@ rl_do_undo ()
{ {
UNDO_LIST *release; UNDO_LIST *release;
int waiting_for_begin = 0; int waiting_for_begin = 0;
int start, end; int start = 0, end = 0;
#define TRANS(i) ((i) == -1 ? rl_point : ((i) == -2 ? rl_end : (i))) #define TRANS(i) ((i) == -1 ? rl_point : ((i) == -2 ? rl_end : (i)))

View File

@ -3,100 +3,102 @@ static struct cname {
char *name; char *name;
char code; char code;
} cnames[] = { } cnames[] = {
"NUL", '\0', {"NUL", '\0'},
"SOH", '\001', {"SOH", '\001'},
"STX", '\002', {"STX", '\002'},
"ETX", '\003', {"ETX", '\003'},
"EOT", '\004', {"EOT", '\004'},
"ENQ", '\005', {"ENQ", '\005'},
"ACK", '\006', {"ACK", '\006'},
"BEL", '\007', {"BEL", '\007'},
"alert", '\007', {"alert", '\007'},
"BS", '\010', {"BS", '\010'},
"backspace", '\b', {"backspace", '\b'},
"HT", '\011', {"HT", '\011'},
"tab", '\t', {"tab", '\t'},
"LF", '\012', {"LF", '\012'},
"newline", '\n', {"newline", '\n'},
"VT", '\013', {"VT", '\013'},
"vertical-tab", '\v', {"vertical-tab",'\v'},
"FF", '\014', {"FF", '\014'},
"form-feed", '\f', {"form-feed", '\f'},
"CR", '\015', {"CR", '\015'},
"carriage-return", '\r', {"carriage-return", '\r'},
"SO", '\016', {"SO", '\016'},
"SI", '\017', {"SI", '\017'},
"DLE", '\020', {"DLE", '\020'},
"DC1", '\021', {"DC1", '\021'},
"DC2", '\022', {"DC2", '\022'},
"DC3", '\023', {"DC3", '\023'},
"DC4", '\024', {"DC4", '\024'},
"NAK", '\025', {"NAK", '\025'},
"SYN", '\026', {"SYN", '\026'},
"ETB", '\027', {"ETB", '\027'},
"CAN", '\030', {"CAN", '\030'},
"EM", '\031', {"EM", '\031'},
"SUB", '\032', {"SUB", '\032'},
"ESC", '\033', {"ESC", '\033'},
"IS4", '\034', {"IS4", '\034'},
"FS", '\034', {"FS", '\034'},
"IS3", '\035', {"IS3", '\035'},
"GS", '\035', {"GS", '\035'},
"IS2", '\036', {"IS2", '\036'},
"RS", '\036', {"RS", '\036'},
"IS1", '\037', {"IS1", '\037'},
"US", '\037', {"US", '\037'},
"space", ' ', {"space", ' '},
"exclamation-mark", '!', {"exclamation-mark", '!'},
"quotation-mark", '"', {"quotation-mark", '"'},
"number-sign", '#', {"number-sign", '#'},
"dollar-sign", '$', {"dollar-sign", '$'},
"percent-sign", '%', {"percent-sign", '%'},
"ampersand", '&', {"ampersand", '&'},
"apostrophe", '\'', {"apostrophe", '\''},
"left-parenthesis", '(', {"left-parenthesis", '('},
"right-parenthesis", ')', {"right-parenthesis", ')'},
"asterisk", '*', {"asterisk", '*'},
"plus-sign", '+', {"plus-sign", '+'},
"comma", ',', {"comma", ','},
"hyphen", '-', {"hyphen", '-'},
"hyphen-minus", '-', {"hyphen-minus", '-'},
"period", '.', {"period", '.'},
"full-stop", '.', {"full-stop", '.'},
"slash", '/', {"slash", '/'},
"solidus", '/', {"solidus", '/'},
"zero", '0', {"zero", '0'},
"one", '1', {"one", '1'},
"two", '2', {"two", '2'},
"three", '3', {"three", '3'},
"four", '4', {"four", '4'},
"five", '5', {"five", '5'},
"six", '6', {"six", '6'},
"seven", '7', {"seven", '7'},
"eight", '8', {"eight", '8'},
"nine", '9', {"nine", '9'},
"colon", ':', {"colon", ':'},
"semicolon", ';', {"semicolon", ';'},
"less-than-sign", '<', {"less-than-sign", '<'},
"equals-sign", '=', {"equals-sign", '='},
"greater-than-sign", '>', {"greater-than-sign", '>'},
"question-mark", '?', {"question-mark", '?'},
"commercial-at", '@', {"commercial-at", '@'},
"left-square-bracket", '[', {"left-square-bracket", '['},
"backslash", '\\', {"backslash", '\\'},
"reverse-solidus", '\\', {"reverse-solidus", '\\'},
"right-square-bracket", ']', {"right-square-bracket",']'},
"circumflex", '^', {"circumflex", '^'},
"circumflex-accent", '^', {"circumflex-accent", '^'},
"underscore", '_', {"underscore", '_'},
"low-line", '_', {"low-line", '_'},
"grave-accent", '`', {"grave-accent", '`'},
"left-brace", '{', {"left-brace", '{'},
"left-curly-bracket", '{', {"left-curly-bracket", '{'},
"vertical-line", '|', {"vertical-line", '|'},
"right-brace", '}', {"right-brace", '}'},
"right-curly-bracket", '}', {"right-curly-bracket", '}'},
"tilde", '~', {"tilde", '~'},
"DEL", '\177', {"DEL", '\177'},
NULL, 0, {NULL, 0},
}; };

View File

@ -217,7 +217,7 @@ FILE *d;
fprintf(d, ">"); fprintf(d, ">");
break; break;
default: default:
fprintf(d, "!%d(%d)!", OP(*s), opnd); fprintf(d, "!%ld(%ld)!", OP(*s), opnd);
break; break;
} }
if (!done) if (!done)

View File

@ -103,7 +103,7 @@ char *argv[];
len = (int)(subs[0].rm_eo - subs[0].rm_so); len = (int)(subs[0].rm_eo - subs[0].rm_so);
if (subs[0].rm_so != -1) { if (subs[0].rm_so != -1) {
if (len != 0) if (len != 0)
printf("match `%.*s'\n", len, printf("match `%.*s'\n", (int)len,
argv[optind] + subs[0].rm_so); argv[optind] + subs[0].rm_so);
else else
printf("match `'@%.1s\n", printf("match `'@%.1s\n",

View File

@ -219,7 +219,7 @@ int stop; /* character this ERE should end at */
conc = HERE(); conc = HERE();
while (MORE() && (c = PEEK()) != '|' && c != stop) while (MORE() && (c = PEEK()) != '|' && c != stop)
p_ere_exp(p); p_ere_exp(p);
REQUIRE(HERE() != conc, REG_EMPTY); /* require nonempty */ if(REQUIRE(HERE() != conc, REG_EMPTY)); /* require nonempty */
if (!EAT('|')) if (!EAT('|'))
break; /* NOTE BREAK OUT */ break; /* NOTE BREAK OUT */
@ -266,7 +266,7 @@ register struct parse *p;
pos = HERE(); pos = HERE();
switch (c) { switch (c) {
case '(': case '(':
REQUIRE(MORE(), REG_EPAREN); if(REQUIRE(MORE(), REG_EPAREN));
p->g->nsub++; p->g->nsub++;
subno = (sopno) p->g->nsub; subno = (sopno) p->g->nsub;
if (subno < NPAREN) if (subno < NPAREN)
@ -279,7 +279,7 @@ register struct parse *p;
assert(p->pend[subno] != 0); assert(p->pend[subno] != 0);
} }
EMIT(ORPAREN, subno); EMIT(ORPAREN, subno);
MUSTEAT(')', REG_EPAREN); if(MUSTEAT(')', REG_EPAREN));
break; break;
#ifndef POSIX_MISTAKE #ifndef POSIX_MISTAKE
case ')': /* happens only if no current unmatched ( */ case ')': /* happens only if no current unmatched ( */
@ -322,12 +322,12 @@ register struct parse *p;
p_bracket(p); p_bracket(p);
break; break;
case '\\': case '\\':
REQUIRE(MORE(), REG_EESCAPE); if(REQUIRE(MORE(), REG_EESCAPE));
c = GETNEXT(); c = GETNEXT();
ordinary(p, c); ordinary(p, c);
break; break;
case '{': /* okay as ordinary except if digit follows */ case '{': /* okay as ordinary except if digit follows */
REQUIRE(!MORE() || !isdigit(PEEK()), REG_BADRPT); if(REQUIRE(!MORE() || !isdigit(PEEK()), REG_BADRPT));
/* FALLTHROUGH */ /* FALLTHROUGH */
default: default:
ordinary(p, c); ordinary(p, c);
@ -343,7 +343,7 @@ register struct parse *p;
return; /* no repetition, we're done */ return; /* no repetition, we're done */
NEXT(); NEXT();
REQUIRE(!wascaret, REG_BADRPT); if(REQUIRE(!wascaret, REG_BADRPT));
switch (c) { switch (c) {
case '*': /* implemented as +? */ case '*': /* implemented as +? */
/* this case does not require the (y|) trick, noKLUDGE */ /* this case does not require the (y|) trick, noKLUDGE */
@ -370,7 +370,7 @@ register struct parse *p;
if (EAT(',')) { if (EAT(',')) {
if (isdigit(PEEK())) { if (isdigit(PEEK())) {
count2 = p_count(p); count2 = p_count(p);
REQUIRE(count <= count2, REG_BADBR); if(REQUIRE(count <= count2, REG_BADBR));
} else /* single number with comma */ } else /* single number with comma */
count2 = RE_INFINITY; count2 = RE_INFINITY;
} else /* just a single number */ } else /* just a single number */
@ -379,7 +379,7 @@ register struct parse *p;
if (!EAT('}')) { /* error heuristics */ if (!EAT('}')) { /* error heuristics */
while (MORE() && PEEK() != '}') while (MORE() && PEEK() != '}')
NEXT(); NEXT();
REQUIRE(MORE(), REG_EBRACE); if(REQUIRE(MORE(), REG_EBRACE));
SETERROR(REG_BADBR); SETERROR(REG_BADBR);
} }
break; break;
@ -402,7 +402,7 @@ static void
p_str(p) p_str(p)
register struct parse *p; register struct parse *p;
{ {
REQUIRE(MORE(), REG_EMPTY); if(REQUIRE(MORE(), REG_EMPTY));
while (MORE()) while (MORE())
ordinary(p, GETNEXT()); ordinary(p, GETNEXT());
} }
@ -445,7 +445,7 @@ register int end2; /* second terminating character */
p->g->neol++; p->g->neol++;
} }
REQUIRE(HERE() != start, REG_EMPTY); /* require nonempty */ if(REQUIRE(HERE() != start, REG_EMPTY)); /* require nonempty */
} }
/* /*
@ -470,7 +470,7 @@ int starordinary; /* is a leading * an ordinary character? */
assert(MORE()); /* caller should have ensured this */ assert(MORE()); /* caller should have ensured this */
c = GETNEXT(); c = GETNEXT();
if (c == '\\') { if (c == '\\') {
REQUIRE(MORE(), REG_EESCAPE); if(REQUIRE(MORE(), REG_EESCAPE));
c = BACKSL | (unsigned char)GETNEXT(); c = BACKSL | (unsigned char)GETNEXT();
} }
switch (c) { switch (c) {
@ -500,7 +500,7 @@ int starordinary; /* is a leading * an ordinary character? */
assert(p->pend[subno] != 0); assert(p->pend[subno] != 0);
} }
EMIT(ORPAREN, subno); EMIT(ORPAREN, subno);
REQUIRE(EATTWO('\\', ')'), REG_EPAREN); if(REQUIRE(EATTWO('\\', ')'), REG_EPAREN));
break; break;
case BACKSL|')': /* should not get here -- must be user */ case BACKSL|')': /* should not get here -- must be user */
case BACKSL|'}': case BACKSL|'}':
@ -530,7 +530,7 @@ int starordinary; /* is a leading * an ordinary character? */
p->g->backrefs = 1; p->g->backrefs = 1;
break; break;
case '*': case '*':
REQUIRE(starordinary, REG_BADRPT); if(REQUIRE(starordinary, REG_BADRPT));
/* FALLTHROUGH */ /* FALLTHROUGH */
default: default:
ordinary(p, c &~ BACKSL); ordinary(p, c &~ BACKSL);
@ -548,7 +548,7 @@ int starordinary; /* is a leading * an ordinary character? */
if (EAT(',')) { if (EAT(',')) {
if (MORE() && isdigit(PEEK())) { if (MORE() && isdigit(PEEK())) {
count2 = p_count(p); count2 = p_count(p);
REQUIRE(count <= count2, REG_BADBR); if(REQUIRE(count <= count2, REG_BADBR));
} else /* single number with comma */ } else /* single number with comma */
count2 = RE_INFINITY; count2 = RE_INFINITY;
} else /* just a single number */ } else /* just a single number */
@ -557,7 +557,7 @@ int starordinary; /* is a leading * an ordinary character? */
if (!EATTWO('\\', '}')) { /* error heuristics */ if (!EATTWO('\\', '}')) { /* error heuristics */
while (MORE() && !SEETWO('\\', '}')) while (MORE() && !SEETWO('\\', '}'))
NEXT(); NEXT();
REQUIRE(MORE(), REG_EBRACE); if(REQUIRE(MORE(), REG_EBRACE));
SETERROR(REG_BADBR); SETERROR(REG_BADBR);
} }
} else if (c == (unsigned char)'$') /* $ (but not \$) ends it */ } else if (c == (unsigned char)'$') /* $ (but not \$) ends it */
@ -582,7 +582,7 @@ register struct parse *p;
ndigits++; ndigits++;
} }
REQUIRE(ndigits > 0 && count <= DUPMAX, REG_BADBR); if(REQUIRE(ndigits > 0 && count <= DUPMAX, REG_BADBR));
return(count); return(count);
} }
@ -622,7 +622,7 @@ register struct parse *p;
p_b_term(p, cs); p_b_term(p, cs);
if (EAT('-')) if (EAT('-'))
CHadd(cs, '-'); CHadd(cs, '-');
MUSTEAT(']', REG_EBRACK); if(MUSTEAT(']', REG_EBRACK));
if (p->error != 0) /* don't mess things up further */ if (p->error != 0) /* don't mess things up further */
return; return;
@ -693,21 +693,21 @@ register cset *cs;
switch (c) { switch (c) {
case ':': /* character class */ case ':': /* character class */
NEXT2(); NEXT2();
REQUIRE(MORE(), REG_EBRACK); if(REQUIRE(MORE(), REG_EBRACK));
c = PEEK(); c = PEEK();
REQUIRE(c != '-' && c != ']', REG_ECTYPE); if(REQUIRE(c != '-' && c != ']', REG_ECTYPE));
p_b_cclass(p, cs); p_b_cclass(p, cs);
REQUIRE(MORE(), REG_EBRACK); if(REQUIRE(MORE(), REG_EBRACK));
REQUIRE(EATTWO(':', ']'), REG_ECTYPE); if(REQUIRE(EATTWO(':', ']'), REG_ECTYPE));
break; break;
case '=': /* equivalence class */ case '=': /* equivalence class */
NEXT2(); NEXT2();
REQUIRE(MORE(), REG_EBRACK); if(REQUIRE(MORE(), REG_EBRACK));
c = PEEK(); c = PEEK();
REQUIRE(c != '-' && c != ']', REG_ECOLLATE); if(REQUIRE(c != '-' && c != ']', REG_ECOLLATE));
p_b_eclass(p, cs); p_b_eclass(p, cs);
REQUIRE(MORE(), REG_EBRACK); if(REQUIRE(MORE(), REG_EBRACK));
REQUIRE(EATTWO('=', ']'), REG_ECOLLATE); if(REQUIRE(EATTWO('=', ']'), REG_ECOLLATE));
break; break;
default: /* symbol, ordinary character, or range */ default: /* symbol, ordinary character, or range */
/* xxx revision needed for multichar stuff */ /* xxx revision needed for multichar stuff */
@ -722,7 +722,7 @@ register cset *cs;
} else } else
finish = start; finish = start;
/* xxx what about signed chars here... */ /* xxx what about signed chars here... */
REQUIRE(start <= finish, REG_ERANGE); if(REQUIRE(start <= finish, REG_ERANGE));
for (i = start; i <= finish; i++) for (i = start; i <= finish; i++)
CHadd(cs, i); CHadd(cs, i);
break; break;
@ -790,13 +790,13 @@ register struct parse *p;
{ {
register char value; register char value;
REQUIRE(MORE(), REG_EBRACK); if(REQUIRE(MORE(), REG_EBRACK));
if (!EATTWO('[', '.')) if (!EATTWO('[', '.'))
return(GETNEXT()); return(GETNEXT());
/* collating symbol */ /* collating symbol */
value = p_b_coll_elem(p, '.'); value = p_b_coll_elem(p, '.');
REQUIRE(EATTWO('.', ']'), REG_ECOLLATE); if(REQUIRE(EATTWO('.', ']'), REG_ECOLLATE));
return(value); return(value);
} }

View File

@ -31,23 +31,23 @@ static struct rerr {
char *name; char *name;
char *explain; char *explain;
} rerrs[] = { } rerrs[] = {
REG_NOMATCH, "REG_NOMATCH", "regexec() failed to match", {REG_NOMATCH, "REG_NOMATCH", "regexec() failed to match"},
REG_BADPAT, "REG_BADPAT", "invalid regular expression", {REG_BADPAT, "REG_BADPAT", "invalid regular expression"},
REG_ECOLLATE, "REG_ECOLLATE", "invalid collating element", {REG_ECOLLATE, "REG_ECOLLATE", "invalid collating element"},
REG_ECTYPE, "REG_ECTYPE", "invalid character class", {REG_ECTYPE, "REG_ECTYPE", "invalid character class"},
REG_EESCAPE, "REG_EESCAPE", "trailing backslash (\\)", {REG_EESCAPE, "REG_EESCAPE", "trailing backslash (\\)"},
REG_ESUBREG, "REG_ESUBREG", "invalid backreference number", {REG_ESUBREG, "REG_ESUBREG", "invalid backreference number"},
REG_EBRACK, "REG_EBRACK", "brackets ([ ]) not balanced", {REG_EBRACK, "REG_EBRACK", "brackets ([ ]) not balanced"},
REG_EPAREN, "REG_EPAREN", "parentheses not balanced", {REG_EPAREN, "REG_EPAREN", "parentheses not balanced"},
REG_EBRACE, "REG_EBRACE", "braces not balanced", {REG_EBRACE, "REG_EBRACE", "braces not balanced"},
REG_BADBR, "REG_BADBR", "invalid repetition count(s)", {REG_BADBR, "REG_BADBR", "invalid repetition count(s)"},
REG_ERANGE, "REG_ERANGE", "invalid character range", {REG_ERANGE, "REG_ERANGE", "invalid character range"},
REG_ESPACE, "REG_ESPACE", "out of memory", {REG_ESPACE, "REG_ESPACE", "out of memory"},
REG_BADRPT, "REG_BADRPT", "repetition-operator operand invalid", {REG_BADRPT, "REG_BADRPT", "repetition-operator operand invalid"},
REG_EMPTY, "REG_EMPTY", "empty (sub)expression", {REG_EMPTY, "REG_EMPTY", "empty (sub)expression"},
REG_ASSERT, "REG_ASSERT", "\"can't happen\" -- you found a bug", {REG_ASSERT, "REG_ASSERT", "\"can't happen\" -- you found a bug"},
REG_INVARG, "REG_INVARG", "invalid argument to regex routine", {REG_INVARG, "REG_INVARG", "invalid argument to regex routine"},
0, "", "*** unknown regexp error code ***", {0, "", "*** unknown regexp error code ***"},
}; };
/* /*

View File

@ -0,0 +1,10 @@
source ../include/master-slave.inc;
connection master;
drop table if exists x;
create table x(n int primary key);
!insert into x values (1),(2),(2);
insert into x values (3);
connection slave;
sleep 3;
@x.master select * from x;

View File

@ -0,0 +1,4 @@
n
1
2
3

View File

@ -865,7 +865,6 @@ static int merge_index(SORTPARAM *param, uchar **sort_keys,
buffpek+maxbuffer,1)) buffpek+maxbuffer,1))
DBUG_RETURN(1); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */
DBUG_RETURN(0); DBUG_RETURN(0);
/* Was: DBUG_RETURN(my_b_write(outfile,last_ref,param->ref_length)); */
} /* merge_index */ } /* merge_index */

View File

@ -31,10 +31,11 @@
#endif #endif
ulong myisam_sort_buffer_size; ulong myisam_sort_buffer_size;
myisam_recover_types myisam_recover_type= HA_RECOVER_NONE; ulong myisam_recover_options= HA_RECOVER_NONE;
/* bits in myisam_recover_options */
const char *myisam_recover_names[] = const char *myisam_recover_names[] =
{ "NO","DEFAULT", "BACKUP"}; { "DEFAULT", "BACKUP", "FORCE"};
TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names),"", TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names),"",
myisam_recover_names}; myisam_recover_names};
@ -152,7 +153,7 @@ int ha_myisam::dump(THD* thd, int fd)
my_off_t bytes_to_read = share->state.state.data_file_length; my_off_t bytes_to_read = share->state.state.data_file_length;
int data_fd = file->dfile; int data_fd = file->dfile;
byte * buf = (byte*) my_malloc(blocksize, MYF(MY_WME)); byte * buf = (byte*) my_malloc(blocksize, MYF(MY_WME));
if(!buf) if (!buf)
return ENOMEM; return ENOMEM;
int error = 0; int error = 0;
@ -249,10 +250,11 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
if (!mi_is_crashed(file) && if (!mi_is_crashed(file) &&
(((param.testflag & T_CHECK_ONLY_CHANGED) && (((param.testflag & T_CHECK_ONLY_CHANGED) &&
(share->state.changed & (STATE_CHANGED | STATE_CRASHED | !(share->state.changed & (STATE_CHANGED | STATE_CRASHED |
STATE_CRASHED_ON_REPAIR)) && STATE_CRASHED_ON_REPAIR)) &&
share->state.open_count == 0) || share->state.open_count == 0) ||
((param.testflag & T_FAST) && share->state.open_count == 0))) ((param.testflag & T_FAST) && (share->state.open_count ==
(share->global_changed ? 1 : 0)))))
return HA_ADMIN_ALREADY_DONE; return HA_ADMIN_ALREADY_DONE;
error = chk_size(&param, file); error = chk_size(&param, file);
@ -342,19 +344,19 @@ int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt)
char* backup_dir = thd->lex.backup_dir; char* backup_dir = thd->lex.backup_dir;
char src_path[FN_REFLEN], dst_path[FN_REFLEN]; char src_path[FN_REFLEN], dst_path[FN_REFLEN];
char* table_name = table->real_name; char* table_name = table->real_name;
if(!fn_format(src_path, table_name, backup_dir, MI_NAME_DEXT, 4 + 64)) if (!fn_format(src_path, table_name, backup_dir, MI_NAME_DEXT, 4 + 64))
return HA_ADMIN_INVALID; return HA_ADMIN_INVALID;
int error = 0; int error = 0;
const char* errmsg = ""; const char* errmsg = "";
if(my_copy(src_path, fn_format(dst_path, table->path, "", if (my_copy(src_path, fn_format(dst_path, table->path, "",
MI_NAME_DEXT, 4), MYF(MY_WME))) MI_NAME_DEXT, 4), MYF(MY_WME)))
{ {
error = HA_ADMIN_FAILED; error = HA_ADMIN_FAILED;
errmsg = "failed in my_copy( Error %d)"; errmsg = "failed in my_copy( Error %d)";
goto err; goto err;
} }
tmp_check_opt.init(); tmp_check_opt.init();
tmp_check_opt.quick = 1; tmp_check_opt.quick = 1;
@ -373,26 +375,27 @@ int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt)
} }
} }
int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt) int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt)
{ {
char* backup_dir = thd->lex.backup_dir; char* backup_dir = thd->lex.backup_dir;
char src_path[FN_REFLEN], dst_path[FN_REFLEN]; char src_path[FN_REFLEN], dst_path[FN_REFLEN];
char* table_name = table->real_name; char* table_name = table->real_name;
if(!fn_format(dst_path, table_name, backup_dir, reg_ext, 4 + 64)) if (!fn_format(dst_path, table_name, backup_dir, reg_ext, 4 + 64))
return HA_ADMIN_INVALID; return HA_ADMIN_INVALID;
if(my_copy(fn_format(src_path, table->path,"", reg_ext, 4), if (my_copy(fn_format(src_path, table->path,"", reg_ext, 4),
dst_path, dst_path,
MYF(MY_WME | MY_HOLD_ORIGINAL_MODES ))) MYF(MY_WME | MY_HOLD_ORIGINAL_MODES )))
{ {
return HA_ADMIN_FAILED; return HA_ADMIN_FAILED;
} }
if(!fn_format(dst_path, table_name, backup_dir, MI_NAME_DEXT, 4 + 64)) if (!fn_format(dst_path, table_name, backup_dir, MI_NAME_DEXT, 4 + 64))
return HA_ADMIN_INVALID; return HA_ADMIN_INVALID;
if(my_copy(fn_format(src_path, table->path,"", MI_NAME_DEXT, 4), if (my_copy(fn_format(src_path, table->path,"", MI_NAME_DEXT, 4),
dst_path, dst_path,
MYF(MY_WME | MY_HOLD_ORIGINAL_MODES )) ) MYF(MY_WME | MY_HOLD_ORIGINAL_MODES )) )
return HA_ADMIN_FAILED; return HA_ADMIN_FAILED;
return HA_ADMIN_OK; return HA_ADMIN_OK;
@ -572,6 +575,33 @@ bool ha_myisam::activate_all_index(THD *thd)
DBUG_RETURN(error); DBUG_RETURN(error);
} }
bool ha_myisam::check_and_repair(THD *thd, const char *name)
{
int error=0;
HA_CHECK_OPT check_opt;
DBUG_ENTER("ha_myisam::auto_check_and_repair");
if (open(name, O_RDWR, HA_OPEN_WAIT_IF_LOCKED))
DBUG_RETURN(1);
check_opt.init();
check_opt.flags=T_MEDIUM;
if (mi_is_crashed(file) || check(thd, &check_opt))
{
check_opt.flags=(((myisam_recover_options & HA_RECOVER_BACKUP) ?
T_BACKUP_DATA : 0) |
(!(myisam_recover_options & HA_RECOVER_FORCE) ?
T_SAFE_REPAIR : 0));
if (repair(thd, &check_opt))
error=1;
}
if (close())
error=1;
DBUG_RETURN(error);
}
int ha_myisam::update_row(const byte * old_data, byte * new_data) int ha_myisam::update_row(const byte * old_data, byte * new_data)
{ {
statistic_increment(ha_update_count,&LOCK_status); statistic_increment(ha_update_count,&LOCK_status);

View File

@ -24,12 +24,14 @@
#include <myisam.h> #include <myisam.h>
#include <ft_global.h> #include <ft_global.h>
enum myisam_recover_types { HA_RECOVER_NONE, HA_RECOVER_DEFAULT, #define HA_RECOVER_NONE 0 // No automatic recover
HA_RECOVER_BACKUP}; #define HA_RECOVER_DEFAULT 1 // Automatic recover active
#define HA_RECOVER_BACKUP 2 // Make a backupfile on recover
#define HA_RECOVER_FORCE 4 // Recover even if we loose rows
extern ulong myisam_sort_buffer_size; extern ulong myisam_sort_buffer_size;
extern TYPELIB myisam_recover_typelib; extern TYPELIB myisam_recover_typelib;
extern myisam_recover_types myisam_recover_type; extern ulong myisam_recover_options;
class ha_myisam: public handler class ha_myisam: public handler
{ {
@ -39,11 +41,12 @@ class ha_myisam: public handler
public: public:
ha_myisam(TABLE *table): handler(table), file(0), ha_myisam(TABLE *table): handler(table), file(0),
int_option_flag(HA_READ_NEXT+HA_READ_PREV+HA_READ_RND_SAME+ int_option_flag(HA_READ_NEXT | HA_READ_PREV | HA_READ_RND_SAME |
HA_KEYPOS_TO_RNDPOS+ HA_READ_ORDER+ HA_LASTKEY_ORDER+ HA_KEYPOS_TO_RNDPOS | HA_READ_ORDER | HA_LASTKEY_ORDER |
HA_HAVE_KEY_READ_ONLY+ HA_READ_NOT_EXACT_KEY+ HA_HAVE_KEY_READ_ONLY | HA_READ_NOT_EXACT_KEY |
HA_LONGLONG_KEYS+ HA_NULL_KEY + HA_LONGLONG_KEYS | HA_NULL_KEY |
HA_DUPP_POS + HA_BLOB_KEY + HA_AUTO_PART_KEY) HA_DUPP_POS | HA_BLOB_KEY | HA_AUTO_PART_KEY |
HA_CHECK_AND_REPAIR)
{} {}
~ha_myisam() {} ~ha_myisam() {}
const char *table_type() const { return "MyISAM"; } const char *table_type() const { return "MyISAM"; }
@ -100,6 +103,7 @@ class ha_myisam: public handler
int check(THD* thd, HA_CHECK_OPT* check_opt); int check(THD* thd, HA_CHECK_OPT* check_opt);
int analyze(THD* thd,HA_CHECK_OPT* check_opt); int analyze(THD* thd,HA_CHECK_OPT* check_opt);
int repair(THD* thd, HA_CHECK_OPT* check_opt); int repair(THD* thd, HA_CHECK_OPT* check_opt);
bool check_and_repair(THD *thd, const char *name);
int optimize(THD* thd, HA_CHECK_OPT* check_opt); int optimize(THD* thd, HA_CHECK_OPT* check_opt);
int restore(THD* thd, HA_CHECK_OPT* check_opt); int restore(THD* thd, HA_CHECK_OPT* check_opt);
int backup(THD* thd, HA_CHECK_OPT* check_opt); int backup(THD* thd, HA_CHECK_OPT* check_opt);

View File

@ -594,7 +594,7 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
TABLE table; TABLE table;
DBUG_ENTER("ha_create_table"); DBUG_ENTER("ha_create_table");
if (openfrm(name,"",0,(uint) READ_ALL,&table)) if (openfrm(name,"",0,(uint) READ_ALL, 0, &table))
DBUG_RETURN(1); DBUG_RETURN(1);
if (update_create_info) if (update_create_info)
{ {

View File

@ -66,6 +66,7 @@
#define HA_NO_WRITE_DELAYED (HA_NOT_EXACT_COUNT*2) #define HA_NO_WRITE_DELAYED (HA_NOT_EXACT_COUNT*2)
#define HA_PRIMARY_KEY_IN_READ_INDEX (HA_NO_WRITE_DELAYED*2) #define HA_PRIMARY_KEY_IN_READ_INDEX (HA_NO_WRITE_DELAYED*2)
#define HA_DROP_BEFORE_CREATE (HA_PRIMARY_KEY_IN_READ_INDEX*2) #define HA_DROP_BEFORE_CREATE (HA_PRIMARY_KEY_IN_READ_INDEX*2)
#define HA_CHECK_AND_REPAIR (HA_DROP_BEFORE_CREATE*2)
/* Parameters for open() (in register form->filestat) */ /* Parameters for open() (in register form->filestat) */
/* HA_GET_INFO does a implicit HA_ABORT_IF_LOCKED */ /* HA_GET_INFO does a implicit HA_ABORT_IF_LOCKED */
@ -248,6 +249,7 @@ public:
virtual void update_create_info(HA_CREATE_INFO *create_info) {} virtual void update_create_info(HA_CREATE_INFO *create_info) {}
virtual int check(THD* thd, HA_CHECK_OPT* check_opt ); virtual int check(THD* thd, HA_CHECK_OPT* check_opt );
virtual int repair(THD* thd, HA_CHECK_OPT* check_opt); virtual int repair(THD* thd, HA_CHECK_OPT* check_opt);
virtual bool check_and_repair(THD *thd, const char *name) {return 1;}
virtual int optimize(THD* thd,HA_CHECK_OPT* check_opt); virtual int optimize(THD* thd,HA_CHECK_OPT* check_opt);
virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt); virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt);
virtual int backup(THD* thd, HA_CHECK_OPT* check_opt); virtual int backup(THD* thd, HA_CHECK_OPT* check_opt);

View File

@ -243,7 +243,10 @@ void key_unpack(String *to,TABLE *table,uint idx)
} }
/* Return 1 if any field in a list is part of key */ /*
Return 1 if any field in a list is part of key or the key uses a field
that is automaticly updated (like a timestamp)
*/
bool check_if_key_used(TABLE *table, uint idx, List<Item> &fields) bool check_if_key_used(TABLE *table, uint idx, List<Item> &fields)
{ {
@ -255,6 +258,10 @@ bool check_if_key_used(TABLE *table, uint idx, List<Item> &fields)
key_part++) key_part++)
{ {
Item_field *field; Item_field *field;
if (key_part->field == table->timestamp_field)
return 1; // Can't be used for update
f.rewind(); f.rewind();
while ((field=(Item_field*) f++)) while ((field=(Item_field*) f++))
{ {

View File

@ -149,7 +149,12 @@ void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
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;
file=my_fopen(log_file_name,O_APPEND | O_WRONLY,MYF(MY_WME | ME_WAITTANG)); MY_STAT tmp_stat;
bool do_magic = ((log_type == LOG_BIN) && !my_stat(log_file_name,
&tmp_stat, MYF(0)));
file=my_fopen(log_file_name,O_APPEND | O_WRONLY | O_BINARY,
MYF(MY_WME | ME_WAITTANG));
if (!file) if (!file)
{ {
my_free(name,MYF(0)); my_free(name,MYF(0));
@ -186,10 +191,18 @@ void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
} }
else if (log_type == LOG_BIN) else if (log_type == LOG_BIN)
{ {
Start_log_event s;
if(!index_file && // Explanation of the boolean black magic:
!(index_file = my_fopen(index_file_name,O_APPEND | O_RDWR, //
MYF(MY_WME)))) // if we are supposed to write magic number try write
// clean up if failed
// then if index_file has not been previously opened, try to open it
// clean up if failed
if((do_magic && my_fwrite(file, (byte*)BINLOG_MAGIC, 4,
MYF(MY_NABP|MY_WME)) ||
(!index_file &&
!(index_file = my_fopen(index_file_name,O_APPEND | O_BINARY | O_RDWR,
MYF(MY_WME))))))
{ {
my_fclose(file,MYF(MY_WME)); my_fclose(file,MYF(MY_WME));
my_free(name,MYF(0)); my_free(name,MYF(0));
@ -198,6 +211,7 @@ void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
log_type=LOG_CLOSED; log_type=LOG_CLOSED;
return; return;
} }
Start_log_event s;
s.write(file); s.write(file);
pthread_mutex_lock(&LOCK_index); pthread_mutex_lock(&LOCK_index);
my_fseek(index_file, 0L, MY_SEEK_END, MYF(MY_WME)); my_fseek(index_file, 0L, MY_SEEK_END, MYF(MY_WME));
@ -461,6 +475,25 @@ void MYSQL_LOG::write(Query_log_event* event_info)
goto err; goto err;
} }
} }
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(file))
{
sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
goto err;
}
thd->query_length = save_query_length; // clean up
}
if (event_info->write(file)) if (event_info->write(file))
{ {

View File

@ -100,7 +100,7 @@ int Log_event::read_log_event(FILE* file, String* packet,
{ {
if(log_lock) if(log_lock)
pthread_mutex_unlock(log_lock); pthread_mutex_unlock(log_lock);
return feof(file) ? LOG_READ_BOGUS: LOG_READ_IO; return feof(file) ? LOG_READ_TRUNC: LOG_READ_IO;
} }
if(log_lock) pthread_mutex_unlock(log_lock); if(log_lock) pthread_mutex_unlock(log_lock);

View File

@ -26,6 +26,7 @@
#define LOG_READ_BOGUS -2 #define LOG_READ_BOGUS -2
#define LOG_READ_IO -3 #define LOG_READ_IO -3
#define LOG_READ_MEM -5 #define LOG_READ_MEM -5
#define LOG_READ_TRUNC -6
#define LOG_EVENT_OFFSET 4 #define LOG_EVENT_OFFSET 4
#define BINLOG_VERSION 1 #define BINLOG_VERSION 1
@ -42,6 +43,7 @@
#define ROTATE_EVENT_OVERHEAD LOG_EVENT_HEADER_LEN #define ROTATE_EVENT_OVERHEAD LOG_EVENT_HEADER_LEN
#define LOAD_EVENT_OVERHEAD (LOG_EVENT_HEADER_LEN+LOAD_HEADER_LEN+sizeof(sql_ex_info)) #define LOAD_EVENT_OVERHEAD (LOG_EVENT_HEADER_LEN+LOAD_HEADER_LEN+sizeof(sql_ex_info))
#define BINLOG_MAGIC "\xfe\x62\x69\x6e"
enum Log_event_type { START_EVENT = 1, QUERY_EVENT =2, enum Log_event_type { START_EVENT = 1, QUERY_EVENT =2,
STOP_EVENT=3, ROTATE_EVENT = 4, INTVAR_EVENT=5, STOP_EVENT=3, ROTATE_EVENT = 4, INTVAR_EVENT=5,

View File

@ -533,7 +533,7 @@ int rea_create_table(my_string file_name,HA_CREATE_INFO *create_info,
int format_number(uint inputflag,uint max_length,my_string pos,uint length, int format_number(uint inputflag,uint max_length,my_string pos,uint length,
my_string *errpos); my_string *errpos);
int openfrm(const char *name,const char *alias,uint filestat,uint prgflag, int openfrm(const char *name,const char *alias,uint filestat,uint prgflag,
TABLE *outparam); uint ha_open_flags, TABLE *outparam);
int closefrm(TABLE *table); int closefrm(TABLE *table);
db_type get_table_type(const char *name); db_type get_table_type(const char *name);
int read_string(File file, gptr *to, uint length); int read_string(File file, gptr *to, uint length);

View File

@ -267,6 +267,15 @@ static void dump_remote_log_entries(const char* logname)
char buf[128]; char buf[128];
uint len; uint len;
NET* net = &mysql->net; NET* net = &mysql->net;
if(!position) position = 4; // protect the innocent from spam
if(position < 4)
{
position = 4;
// warn the guity
fprintf(stderr,
"Warning: with the position so small you would hit the magic number\n\
Unfortunately, no sweepstakes today, adjusted position to 4\n");
}
int4store(buf, position); int4store(buf, position);
int2store(buf + 4, binlog_flags); int2store(buf + 4, binlog_flags);
len = (uint) strlen(logname); len = (uint) strlen(logname);
@ -305,7 +314,7 @@ static void dump_local_log_entries(const char* logname)
int rec_count = 0; int rec_count = 0;
if(logname && logname[0] != '-') if(logname && logname[0] != '-')
file = my_fopen(logname, O_RDONLY, MYF(MY_WME)); file = my_fopen(logname, O_RDONLY|O_BINARY, MYF(MY_WME));
else else
file = stdin; file = stdin;
@ -314,6 +323,15 @@ static void dump_local_log_entries(const char* logname)
if(my_fseek(file, position, MY_SEEK_SET, MYF(MY_WME))) if(my_fseek(file, position, MY_SEEK_SET, MYF(MY_WME)))
die("failed on my_fseek()"); die("failed on my_fseek()");
if(!position)
{
char magic[4];
if(my_fread(file, 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)
{ {

View File

@ -177,6 +177,7 @@ static VioSSLAcceptorFd* ssl_acceptor_fd = 0;
extern bool slave_running; extern bool slave_running;
I_List <i_string_pair> replicate_rewrite_db;
I_List<i_string> replicate_do_db, replicate_ignore_db; I_List<i_string> replicate_do_db, replicate_ignore_db;
// allow the user to tell us which db to replicate and which to ignore // allow the user to tell us which db to replicate and which to ignore
I_List<i_string> binlog_do_db, binlog_ignore_db; I_List<i_string> binlog_do_db, binlog_ignore_db;
@ -284,7 +285,7 @@ extern pthread_handler_decl(handle_slave,arg);
#ifdef SET_RLIMIT_NOFILE #ifdef SET_RLIMIT_NOFILE
static uint set_maximum_open_files(uint max_file_limit); static uint set_maximum_open_files(uint max_file_limit);
#endif #endif
static ulong find_bit_type(const char *x, TYPELIB *bit_lib);
/**************************************************************************** /****************************************************************************
** Code to end mysqld ** Code to end mysqld
@ -1066,6 +1067,7 @@ static void init_signals(void)
sigaddset(&set,SIGTERM); sigaddset(&set,SIGTERM);
sigaddset(&set,SIGHUP); sigaddset(&set,SIGHUP);
signal(SIGTERM,SIG_DFL); // If it's blocked by parent signal(SIGTERM,SIG_DFL); // If it's blocked by parent
signal(SIGHUP,SIG_DFL); // If it's blocked by parent
#ifdef SIGTSTP #ifdef SIGTSTP
sigaddset(&set,SIGTSTP); sigaddset(&set,SIGTSTP);
#endif #endif
@ -2588,6 +2590,8 @@ static void usage(void)
Log slow queries to this log file. Defaults logging\n\ Log slow queries to this log file. Defaults logging\n\
to hostname-slow.log\n\ to hostname-slow.log\n\
--pid-file=path Pid file used by safe_mysqld\n\ --pid-file=path Pid file used by safe_mysqld\n\
--myisam-recover[=option[,option...]] where options is one of DEAULT,\n\
BACKUP or FORCE.\n\
--memlock Lock mysqld in memory\n\ --memlock Lock mysqld in memory\n\
-n, --new Use very new possible 'unsafe' functions\n\ -n, --new Use very new possible 'unsafe' functions\n\
-o, --old-protocol Use the old (3.20) protocol\n\ -o, --old-protocol Use the old (3.20) protocol\n\
@ -2851,6 +2855,38 @@ static void get_options(int argc,char **argv)
replicate_do_db.push_back(db); replicate_do_db.push_back(db);
break; break;
} }
case (int)OPT_REPLICATE_REWRITE_DB:
{
char* key = optarg,*p, *val;
p = strstr(optarg, "->");
if(!p)
{
fprintf(stderr,
"bad syntax in replicate-rewrite-db - missing ->\n");
exit(1);
}
val = p--;
while(isspace(*p) && p > optarg) *p-- = 0;
if(p == optarg)
{
fprintf(stderr,
"bad syntax in replicate-rewrite-db - empty FROM db\n");
exit(1);
}
*val = 0;
val += 2;
while(*val && isspace(*val)) *val++;
if(!*val)
{
fprintf(stderr,
"bad syntax in replicate-rewrite-db - empty TO db\n");
exit(1);
}
i_string_pair* db_pair = new i_string_pair(key, val);
replicate_rewrite_db.push_back(db_pair);
break;
}
case (int)OPT_BINLOG_IGNORE_DB: case (int)OPT_BINLOG_IGNORE_DB:
{ {
@ -2879,13 +2915,13 @@ static void get_options(int argc,char **argv)
default_table_type=DB_TYPE_ISAM; default_table_type=DB_TYPE_ISAM;
myisam_delay_key_write=0; myisam_delay_key_write=0;
myisam_concurrent_insert=0; myisam_concurrent_insert=0;
myisam_recover_type= HA_RECOVER_NONE; myisam_recover_options= 0;
break; break;
case (int) OPT_SAFE: case (int) OPT_SAFE:
opt_specialflag|= SPECIAL_SAFE_MODE; opt_specialflag|= SPECIAL_SAFE_MODE;
myisam_delay_key_write=0; myisam_delay_key_write=0;
myisam_concurrent_insert=0; myisam_concurrent_insert=0;
myisam_recover_type= HA_RECOVER_NONE; // For now myisam_recover_options= HA_RECOVER_NONE; // To be changed
break; break;
case (int) OPT_SKIP_CONCURRENT_INSERT: case (int) OPT_SKIP_CONCURRENT_INSERT:
myisam_concurrent_insert=0; myisam_concurrent_insert=0;
@ -3052,13 +3088,14 @@ static void get_options(int argc,char **argv)
#endif #endif
case OPT_MYISAM_RECOVER: case OPT_MYISAM_RECOVER:
{ {
int type; if (!optarg || !optarg[0])
if ((type=find_type(optarg, &myisam_recover_typelib, 2)) <= 0) myisam_recover_options=HA_RECOVER_DEFAULT;
else if ((myisam_recover_options=
find_bit_type(optarg, &myisam_recover_typelib)) == ~(ulong) 0)
{ {
fprintf(stderr,"Unknown option to myisam-recover: %s\n",optarg); fprintf(stderr, "Unknown option to myisam-recover: %s\n",optarg);
exit(1); exit(1);
} }
myisam_recover_type=(myisam_recover_types) (type-1);
break; break;
} }
case OPT_MASTER_HOST: case OPT_MASTER_HOST:
@ -3594,6 +3631,64 @@ static uint set_maximum_open_files(uint max_file_limit)
#endif #endif
/*
Return a bitfield from a string of substrings separated by ','
returns ~(ulong) 0 on error.
*/
static ulong find_bit_type(const char *x, TYPELIB *bit_lib)
{
bool found_end;
int found_count;
const char *end,*i,*j;
const char **array, *pos;
ulong found,found_int,bit;
DBUG_ENTER("find_bit_type");
DBUG_PRINT("enter",("x: '%s'",x));
found=0;
found_end= 0;
pos=(my_string) x;
do
{
if (!*(end=strcend(pos,','))) /* Let end point at fieldend */
{
while (end > pos && end[-1] == ' ')
end--; /* Skipp end-space */
found_end=1;
}
found_int=0; found_count=0;
for (array=bit_lib->type_names, bit=1 ; (i= *array++) ; bit<<=1)
{
j=pos;
while (j != end)
{
if (toupper(*i++) != toupper(*j++))
goto skipp;
}
found_int=bit;
if (! *i)
{
found_count=1;
break;
}
else if (j != pos) // Half field found
{
found_count++; // Could be one of two values
}
skipp: ;
}
if (found_count != 1)
DBUG_RETURN(~(ulong) 0); // No unique value
found|=found_int;
pos=end+1;
} while (! found_end);
DBUG_PRINT("exit",("bit-field: %ld",(ulong) found));
DBUG_RETURN(found);
} /* find_bit_type */
/***************************************************************************** /*****************************************************************************
** Instantiate templates ** Instantiate templates
*****************************************************************************/ *****************************************************************************/

View File

@ -30,6 +30,7 @@ extern my_string master_user, master_password, master_host,
master_info_file; master_info_file;
extern I_List<i_string> replicate_do_db, replicate_ignore_db; extern I_List<i_string> replicate_do_db, replicate_ignore_db;
extern I_List<i_string_pair> replicate_rewrite_db;
extern I_List<THD> threads; extern I_List<THD> threads;
bool slave_running = 0; bool slave_running = 0;
pthread_t slave_real_id; pthread_t slave_real_id;
@ -48,6 +49,7 @@ static int safe_sleep(THD* thd, int sec);
static int request_table_dump(MYSQL* mysql, char* db, char* table); static int request_table_dump(MYSQL* mysql, char* db, char* table);
static int create_table_from_dump(THD* thd, NET* net, const char* db, static int create_table_from_dump(THD* thd, NET* net, const char* db,
const char* table_name); const char* table_name);
static inline char* rewrite_db(char* db);
static inline bool slave_killed(THD* thd) static inline bool slave_killed(THD* thd)
{ {
@ -62,6 +64,20 @@ static inline void skip_load_data_infile(NET* net)
send_ok(net); // the master expects it send_ok(net); // the master expects it
} }
static inline char* rewrite_db(char* db)
{
if(replicate_rewrite_db.is_empty() || !db) return db;
I_List_iterator<i_string_pair> it(replicate_rewrite_db);
i_string_pair* tmp;
while((tmp=it++))
{
if(!strcmp(tmp->key, db))
return tmp->val;
}
return db;
}
int db_ok(const char* db, I_List<i_string> &do_list, int db_ok(const char* db, I_List<i_string> &do_list,
I_List<i_string> &ignore_list ) I_List<i_string> &ignore_list )
@ -278,11 +294,11 @@ int init_master_info(MASTER_INFO* mi)
if(!my_stat(fname, &stat_area, MYF(0))) // we do not want any messages if(!my_stat(fname, &stat_area, MYF(0))) // we do not want any messages
// if the file does not exist // if the file does not exist
{ {
file = my_fopen(fname, O_CREAT|O_RDWR, MYF(MY_WME)); file = my_fopen(fname, O_CREAT|O_RDWR|O_BINARY, MYF(MY_WME));
if(!file) if(!file)
return 1; return 1;
mi->log_file_name[0] = 0; mi->log_file_name[0] = 0;
mi->pos = 0; mi->pos = 4; // skip magic number
mi->file = file; mi->file = file;
if(master_host) if(master_host)
@ -299,7 +315,7 @@ int init_master_info(MASTER_INFO* mi)
} }
else else
{ {
file = my_fopen(fname, O_RDWR, MYF(MY_WME)); file = my_fopen(fname, O_RDWR|O_BINARY, MYF(MY_WME));
if(!file) if(!file)
return 1; return 1;
@ -589,7 +605,7 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len)
Query_log_event* qev = (Query_log_event*)ev; Query_log_event* qev = (Query_log_event*)ev;
int q_len = qev->q_len; int q_len = qev->q_len;
init_sql_alloc(&thd->mem_root, 8192,0); init_sql_alloc(&thd->mem_root, 8192,0);
thd->db = (char*)qev->db; thd->db = rewrite_db((char*)qev->db);
if(db_ok(thd->db, replicate_do_db, replicate_ignore_db)) if(db_ok(thd->db, replicate_do_db, replicate_ignore_db))
{ {
thd->query = (char*)qev->query; thd->query = (char*)qev->query;
@ -645,7 +661,7 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len)
{ {
Load_log_event* lev = (Load_log_event*)ev; Load_log_event* lev = (Load_log_event*)ev;
init_sql_alloc(&thd->mem_root, 8192,0); init_sql_alloc(&thd->mem_root, 8192,0);
thd->db = (char*)lev->db; thd->db = rewrite_db((char*)lev->db);
thd->query = 0; thd->query = 0;
thd->query_error = 0; thd->query_error = 0;
@ -766,7 +782,8 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len)
int ident_len = rev->ident_len; int ident_len = rev->ident_len;
memcpy(mi->log_file_name, rev->new_log_ident,ident_len ); memcpy(mi->log_file_name, rev->new_log_ident,ident_len );
mi->log_file_name[ident_len] = 0; mi->log_file_name[ident_len] = 0;
mi->pos = 0; mi->pos = 4; // skip magic number
flush_master_info(mi);
break; break;
} }

View File

@ -2004,6 +2004,8 @@ bool check_grant(THD *thd, uint want_access, TABLE_LIST *tables,
want_access &= ~table->grant.privilege; want_access &= ~table->grant.privilege;
goto err; // No grants goto err; // No grants
} }
if (show_table)
continue; // We have some priv on this
table->grant.grant_table=grant_table; // Remember for column test table->grant.grant_table=grant_table; // Remember for column test
table->grant.version=grant_version; table->grant.version=grant_version;
@ -2013,8 +2015,6 @@ bool check_grant(THD *thd, uint want_access, TABLE_LIST *tables,
if (!(~table->grant.privilege & want_access)) if (!(~table->grant.privilege & want_access))
continue; continue;
if (show_table && table->grant.privilege)
continue; // Test from show tables
if (want_access & ~(grant_table->cols | table->grant.privilege)) if (want_access & ~(grant_table->cols | table->grant.privilege))
{ {
@ -2457,18 +2457,18 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
!strcmp(lex_user->host.str,host)) !strcmp(lex_user->host.str,host))
{ {
want_access=grant_table->privs; want_access=grant_table->privs;
if (want_access) if ((want_access | grant_table->cols) != 0)
{ {
String global(buff,sizeof(buff)); String global(buff,sizeof(buff));
global.length(0); global.length(0);
global.append("GRANT ",6); global.append("GRANT ",6);
if (test_all_bits(want_access,(TABLE_ACLS & ~GRANT_ACL))) if (test_all_bits(grant_table->privs,(TABLE_ACLS & ~GRANT_ACL)))
global.append("ALL PRIVILEGES",14); global.append("ALL PRIVILEGES",14);
else else
{ {
int found=0; int found=0;
uint j,test_access= want_access & ~GRANT_ACL; uint j,test_access= (want_access | grant_table->cols) & ~GRANT_ACL;
for (counter=0, j = SELECT_ACL;j <= TABLE_ACLS; counter++,j <<= 1) for (counter=0, j = SELECT_ACL;j <= TABLE_ACLS; counter++,j <<= 1)
{ {

View File

@ -388,7 +388,7 @@ void close_thread_tables(THD *thd, bool locked)
} }
thd->open_tables=0; thd->open_tables=0;
/* Free tables to hold down open files */ /* Free tables to hold down open files */
while (open_cache.records >= table_cache_size && unused_tables) while (open_cache.records > table_cache_size && unused_tables)
VOID(hash_delete(&open_cache,(byte*) unused_tables)); /* purecov: tested */ VOID(hash_delete(&open_cache,(byte*) unused_tables)); /* purecov: tested */
check_unused(); check_unused();
if (found_old_table) if (found_old_table)
@ -700,7 +700,7 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
else else
{ {
/* Free cache if too big */ /* Free cache if too big */
while (open_cache.records >= table_cache_size && unused_tables) while (open_cache.records > table_cache_size && unused_tables)
VOID(hash_delete(&open_cache,(byte*) unused_tables)); /* purecov: tested */ VOID(hash_delete(&open_cache,(byte*) unused_tables)); /* purecov: tested */
/* make a new table */ /* make a new table */
@ -1123,6 +1123,7 @@ static int open_unireg_entry(TABLE *entry,const char *db,const char *name,
(uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX | (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX |
HA_TRY_READ_ONLY), HA_TRY_READ_ONLY),
READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD, READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD,
ha_open_options,
entry)) entry))
{ {
DBUG_RETURN(1); DBUG_RETURN(1);
@ -1288,6 +1289,7 @@ TABLE *open_temporary_table(THD *thd, const char *path, const char *db,
(uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX | (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX |
HA_TRY_READ_ONLY), HA_TRY_READ_ONLY),
READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD, READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD,
ha_open_options,
tmp_table)) tmp_table))
{ {
DBUG_RETURN(0); DBUG_RETURN(0);
@ -1572,6 +1574,7 @@ int setup_fields(THD *thd, TABLE_LIST *tables, List<Item> &fields,
DBUG_RETURN(-1); /* purecov: inspected */ DBUG_RETURN(-1); /* purecov: inspected */
if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM) if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM)
item->split_sum_func(*sum_func_list); item->split_sum_func(*sum_func_list);
thd->used_tables|=item->used_tables();
} }
} }
DBUG_RETURN(test(thd->fatal_error)); DBUG_RETURN(test(thd->fatal_error));

View File

@ -19,10 +19,10 @@
#include <my_dir.h> #include <my_dir.h>
#include <hash.h> #include <hash.h>
#define SQL_CACHE_LENGTH 300 #define SQL_CACHE_LENGTH 30 // 300 crashes apple gcc.
HASH sql_cache; HASH sql_cache;
LEX lex_array_static[SQL_CACHE_LENGTH]; static LEX lex_array_static[SQL_CACHE_LENGTH];
LEX * lex_array = lex_array_static; LEX * lex_array = lex_array_static;
int last_lex_array_item = SQL_CACHE_LENGTH - 1; int last_lex_array_item = SQL_CACHE_LENGTH - 1;

View File

@ -89,6 +89,7 @@ THD::THD()
open_tables=temporary_tables=0; open_tables=temporary_tables=0;
tmp_table=0; tmp_table=0;
lock=locked_tables=0; lock=locked_tables=0;
used_tables=0;
cuted_fields=0L; cuted_fields=0L;
options=thd_startup_options; options=thd_startup_options;
update_lock_default= low_priority_updates ? TL_WRITE_LOW_PRIORITY : TL_WRITE; update_lock_default= low_priority_updates ? TL_WRITE_LOW_PRIORITY : TL_WRITE;

View File

@ -218,6 +218,17 @@ public:
i_string(char* s) : ptr(s) {} i_string(char* s) : ptr(s) {}
}; };
//needed for linked list of two strings for replicate-rewrite-db
class i_string_pair: public ilink
{
public:
char* key;
char* val;
i_string_pair():key(0),val(0) { }
i_string_pair(char* key, char* val) : key(key),val(val) {}
};
/**************************************************************************** /****************************************************************************
** every connection is handle by a thread with a THD ** every connection is handle by a thread with a THD
****************************************************************************/ ****************************************************************************/
@ -264,6 +275,7 @@ public:
ulonglong next_insert_id,last_insert_id,current_insert_id; ulonglong next_insert_id,last_insert_id,current_insert_id;
ha_rows select_limit,offset_limit,default_select_limit,cuted_fields, ha_rows select_limit,offset_limit,default_select_limit,cuted_fields,
max_join_size,sent_row_count; max_join_size,sent_row_count;
table_map used_tables;
ulong query_id,version, inactive_timeout,options,thread_id; ulong query_id,version, inactive_timeout,options,thread_id;
long dbug_thread_id; long dbug_thread_id;
pthread_t real_id; pthread_t real_id;

View File

@ -140,6 +140,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
if (!table) if (!table)
DBUG_RETURN(-1); DBUG_RETURN(-1);
thd->proc_info="init"; thd->proc_info="init";
thd->used_tables=0;
save_time_stamp=table->time_stamp; save_time_stamp=table->time_stamp;
values= its++; values= its++;
if (check_insert_fields(thd,table,fields,*values,1) || if (check_insert_fields(thd,table,fields,*values,1) ||
@ -200,7 +201,10 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
} }
else else
{ {
table->record[0][0]=table->record[2][0]; // Fix delete marker if (thd->used_tables) // Column used in values()
restore_record(table,2); // Get empty record
else
table->record[0][0]=table->record[2][0]; // Fix delete marker
if (fill_record(table->field,*values)) if (fill_record(table->field,*values))
{ {
if (values_list.elements != 1) if (values_list.elements != 1)
@ -1166,12 +1170,7 @@ select_insert::prepare(List<Item> &values)
if (check_insert_fields(thd,table,*fields,values,1)) if (check_insert_fields(thd,table,*fields,values,1))
DBUG_RETURN(1); DBUG_RETURN(1);
if (fields->elements) restore_record(table,2); // Get empty record
{
restore_record(table,2); // Get empty record
}
else
table->record[0][0]=table->record[2][0]; // Fix delete marker
table->next_number_field=table->found_next_number_field; table->next_number_field=table->found_next_number_field;
thd->count_cuted_fields=1; /* calc cuted fields */ thd->count_cuted_fields=1; /* calc cuted fields */
thd->cuted_fields=0; thd->cuted_fields=0;

View File

@ -21,6 +21,7 @@
#include "sql_repl.h" #include "sql_repl.h"
#include "sql_acl.h" #include "sql_acl.h"
#include "log_event.h" #include "log_event.h"
#include <thr_alarm.h>
#include <my_dir.h> #include <my_dir.h>
extern const char* any_db; extern const char* any_db;
@ -97,6 +98,7 @@ 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];
FILE* log = NULL; FILE* log = NULL;
String* packet = &thd->packet; String* packet = &thd->packet;
int error; int error;
@ -128,7 +130,25 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
errmsg = "Could not open log file"; errmsg = "Could not open log file";
goto err; goto err;
} }
if(my_fread(log, 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)
{
errmsg = "Contratulations! You have hit the magic number and can win \
sweepstakes if you report the bug";
goto err;
}
if(my_fseek(log, pos, MY_SEEK_SET, MYF(MY_WME)) == MY_FILEPOS_ERROR ) if(my_fseek(log, pos, MY_SEEK_SET, MYF(MY_WME)) == MY_FILEPOS_ERROR )
{ {
errmsg = "Error on fseek()"; errmsg = "Error on fseek()";
@ -167,7 +187,21 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
} }
if(error != LOG_READ_EOF) if(error != LOG_READ_EOF)
{ {
errmsg = "error reading log event"; 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;
} }
@ -260,7 +294,8 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
} }
else else
{ {
bool loop_breaker = 0; // need this to break out of the for loop from switch bool loop_breaker = 0;
// need this to break out of the for loop from switch
thd->proc_info = "switching to next log"; thd->proc_info = "switching to next log";
switch(mysql_bin_log.find_next_log(&linfo)) switch(mysql_bin_log.find_next_log(&linfo))
{ {
@ -280,14 +315,31 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
(void) my_fclose(log, MYF(MY_WME)); (void) my_fclose(log, MYF(MY_WME));
log = my_fopen(log_file_name, O_RDONLY|O_BINARY, MYF(MY_WME)); log = my_fopen(log_file_name, O_RDONLY|O_BINARY, MYF(MY_WME));
if(!log) if(!log)
goto err; {
errmsg = "Could not open next log";
goto err;
}
//check the magic
if(my_fread(log, 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 // fake Rotate_log event just in case it did not make it to the log
// otherwise the slave make get confused about the offset // otherwise the slave make get confused about the offset
{ {
char header[LOG_EVENT_HEADER_LEN]; char header[LOG_EVENT_HEADER_LEN];
memset(header, 0, 4); // when does not matter memset(header, 0, 4); // when does not matter
header[EVENT_TYPE_OFFSET] = ROTATE_EVENT; header[EVENT_TYPE_OFFSET] = ROTATE_EVENT;
char* p = strrchr(log_file_name, FN_LIBCHAR); // find the last slash char* p = strrchr(log_file_name, FN_LIBCHAR);
// find the last slash
if(p) if(p)
p++; p++;
else else

View File

@ -137,7 +137,8 @@ static void copy_sum_funcs(Item_sum **func_ptr);
static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab); static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab);
static void init_sum_functions(Item_sum **func); static void init_sum_functions(Item_sum **func);
static bool update_sum_func(Item_sum **func); static bool update_sum_func(Item_sum **func);
static void select_describe(JOIN *join, bool need_tmp_table, bool need_order); static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
bool distinct);
static void describe_info(const char *info); static void describe_info(const char *info);
/***************************************************************************** /*****************************************************************************
@ -172,6 +173,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
no_order=0; no_order=0;
bzero((char*) &keyuse,sizeof(keyuse)); bzero((char*) &keyuse,sizeof(keyuse));
thd->proc_info="init"; thd->proc_info="init";
thd->used_tables=0; // Updated by setup_fields
if (setup_fields(thd,tables,fields,1,&all_fields) || if (setup_fields(thd,tables,fields,1,&all_fields) ||
setup_conds(thd,tables,&conds) || setup_conds(thd,tables,&conds) ||
@ -262,7 +264,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
join.join_tab=0; join.join_tab=0;
join.tmp_table_param.copy_field=0; join.tmp_table_param.copy_field=0;
join.sum_funcs=0; join.sum_funcs=0;
join.send_records=0L; join.send_records=join.found_records=0;
join.tmp_table_param.end_write_records= HA_POS_ERROR; join.tmp_table_param.end_write_records= HA_POS_ERROR;
join.first_record=join.sort_and_group=0; join.first_record=join.sort_and_group=0;
join.select_options=select_options; join.select_options=select_options;
@ -507,7 +509,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
order=0; order=0;
select_describe(&join,need_tmp, select_describe(&join,need_tmp,
(order != 0 && (order != 0 &&
(!need_tmp || order != group || simple_group))); (!need_tmp || order != group || simple_group)),
select_distinct);
error=0; error=0;
goto err; goto err;
} }
@ -558,6 +561,26 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
order=0; order=0;
} }
} }
/*
Optimize distinct when used on some of the tables
SELECT DISTINCT t1.a FROM t1,t2 WHERE t1.b=t2.b
In this case we can stop scanning t2 when we have found one t1.a
*/
if (tmp_table->distinct)
{
table_map used_tables= thd->used_tables;
JOIN_TAB *join_tab=join.join_tab+join.tables-1;
do
{
if (used_tables & join_tab->table->map)
break;
join_tab->not_used_in_distinct=1;
} while (join_tab-- != join.join_tab);
}
/* Copy data to the temporary table */
thd->proc_info="Copying to tmp table"; thd->proc_info="Copying to tmp table";
if (do_select(&join,(List<Item> *) 0,tmp_table,0)) if (do_select(&join,(List<Item> *) 0,tmp_table,0))
goto err; /* purecov: inspected */ goto err; /* purecov: inspected */
@ -2123,7 +2146,7 @@ make_simple_join(JOIN *join,TABLE *tmp_table)
join->tmp_table_param.copy_field=0; join->tmp_table_param.copy_field=0;
join->first_record=join->sort_and_group=0; join->first_record=join->sort_and_group=0;
join->sum_funcs=0; join->sum_funcs=0;
join->send_records=0L; join->send_records=(ha_rows) 0;
join->group=0; join->group=0;
join_tab->cache.buff=0; /* No cacheing */ join_tab->cache.buff=0; /* No cacheing */
@ -2131,15 +2154,16 @@ make_simple_join(JOIN *join,TABLE *tmp_table)
join_tab->select=0; join_tab->select=0;
join_tab->select_cond=0; join_tab->select_cond=0;
join_tab->quick=0; join_tab->quick=0;
bzero((char*) &join_tab->read_record,sizeof(join_tab->read_record));
join_tab->type= JT_ALL; /* Map through all records */ join_tab->type= JT_ALL; /* Map through all records */
join_tab->keys= (uint) ~0; /* test everything in quick */ join_tab->keys= (uint) ~0; /* test everything in quick */
join_tab->info=0; join_tab->info=0;
join_tab->on_expr=0; join_tab->on_expr=0;
join_tab->ref.key = -1; join_tab->ref.key = -1;
join_tab->not_used_in_distinct=0;
join_tab->read_first_record= join_init_read_record;
bzero((char*) &join_tab->read_record,sizeof(join_tab->read_record));
tmp_table->status=0; tmp_table->status=0;
tmp_table->null_row=0; tmp_table->null_row=0;
join_tab->read_first_record= join_init_read_record;
return FALSE; return FALSE;
} }
@ -3257,7 +3281,6 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
if (item->with_sum_func && type != Item::SUM_FUNC_ITEM || if (item->with_sum_func && type != Item::SUM_FUNC_ITEM ||
item->const_item()) item->const_item())
continue; continue;
if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields) if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields)
{ /* Can't calc group yet */ { /* Can't calc group yet */
((Item_sum*) item)->result_field=0; ((Item_sum*) item)->result_field=0;
@ -3914,7 +3937,9 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
if (!(error=(*join_tab->read_first_record)(join_tab))) if (!(error=(*join_tab->read_first_record)(join_tab)))
{ {
bool not_exists_optimize=join_tab->table->reginfo.not_exists_optimize; bool not_exists_optimize= join_tab->table->reginfo.not_exists_optimize;
bool not_used_in_distinct=join_tab->not_used_in_distinct;
ha_rows found_records=join->found_records;
READ_RECORD *info= &join_tab->read_record; READ_RECORD *info= &join_tab->read_record;
do do
@ -3933,6 +3958,8 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
{ {
if ((error=(*next_select)(join,join_tab+1,0)) < 0) if ((error=(*next_select)(join,join_tab+1,0)) < 0)
return error; return error;
if (not_used_in_distinct && found_records != join->found_records)
return 0;
} }
} }
} while (!(error=info->read_record(info))); } while (!(error=info->read_record(info)));
@ -4546,23 +4573,21 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
} }
if (!join->having || join->having->val_int()) if (!join->having || join->having->val_int())
{ {
join->found_records++;
if ((error=table->file->write_row(table->record[0]))) if ((error=table->file->write_row(table->record[0])))
{ {
if (error != HA_ERR_FOUND_DUPP_KEY && if (error == HA_ERR_FOUND_DUPP_KEY ||
error != HA_ERR_FOUND_DUPP_UNIQUE) error == HA_ERR_FOUND_DUPP_UNIQUE)
{ goto end;
if (create_myisam_from_heap(table, &join->tmp_table_param, error,1)) if (create_myisam_from_heap(table, &join->tmp_table_param, error,1))
DBUG_RETURN(1); // Not a table_is_full error DBUG_RETURN(1); // Not a table_is_full error
table->uniques=0; // To ensure rows are the same table->uniques=0; // To ensure rows are the same
}
}
else
{
if (++join->send_records >= join->tmp_table_param.end_write_records) if (++join->send_records >= join->tmp_table_param.end_write_records)
DBUG_RETURN(-3); DBUG_RETURN(-3);
} }
} }
} }
end:
DBUG_RETURN(0); DBUG_RETURN(0);
} }
@ -4586,6 +4611,7 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
DBUG_RETURN(-2); /* purecov: inspected */ DBUG_RETURN(-2); /* purecov: inspected */
} }
join->found_records++;
copy_fields(&join->tmp_table_param); // Groups are copied twice. copy_fields(&join->tmp_table_param); // Groups are copied twice.
/* Make a key of group index */ /* Make a key of group index */
for (group=table->group ; group ; group=group->next) for (group=table->group ; group ; group=group->next)
@ -5053,7 +5079,6 @@ create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit)
} }
} }
else else
// if (tab->type != JT_FT) /* Beware! SerG */
{ {
/* /*
We have a ref on a const; Change this to a range that filesort We have a ref on a const; Change this to a range that filesort
@ -6336,12 +6361,13 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
** Send a description about what how the select will be done to stdout ** Send a description about what how the select will be done to stdout
****************************************************************************/ ****************************************************************************/
static void select_describe(JOIN *join, bool need_tmp_table, bool need_order) static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
bool distinct)
{ {
DBUG_ENTER("select_describe");
List<Item> field_list; List<Item> field_list;
Item *item; Item *item;
THD *thd=join->thd;
DBUG_ENTER("select_describe");
field_list.push_back(new Item_empty_string("table",NAME_LEN)); field_list.push_back(new Item_empty_string("table",NAME_LEN));
field_list.push_back(new Item_empty_string("type",10)); field_list.push_back(new Item_empty_string("type",10));
@ -6357,11 +6383,12 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order)
item->maybe_null=1; item->maybe_null=1;
field_list.push_back(new Item_real("rows",0.0,0,10)); field_list.push_back(new Item_real("rows",0.0,0,10));
field_list.push_back(new Item_empty_string("Extra",255)); field_list.push_back(new Item_empty_string("Extra",255));
if (send_fields(join->thd,field_list,1)) if (send_fields(thd,field_list,1))
return; /* purecov: inspected */ return; /* purecov: inspected */
char buff[512],*buff_ptr; char buff[512],*buff_ptr;
String tmp(buff,sizeof(buff)),*packet= &join->thd->packet; String tmp(buff,sizeof(buff)),*packet= &thd->packet;
table_map used_tables=0;
for (uint i=0 ; i < join->tables ; i++) for (uint i=0 ; i < join->tables ; i++)
{ {
JOIN_TAB *tab=join->join_tab+i; JOIN_TAB *tab=join->join_tab+i;
@ -6474,11 +6501,22 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order)
} }
buff_ptr=strmov(buff_ptr,"Using filesort"); buff_ptr=strmov(buff_ptr,"Using filesort");
} }
if (distinct & test_all_bits(used_tables,thd->used_tables))
{
if (buff != buff_ptr)
{
buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2;
}
buff_ptr=strmov(buff_ptr,"Distinct");
}
net_store_data(packet,buff,(uint) (buff_ptr - buff)); net_store_data(packet,buff,(uint) (buff_ptr - buff));
if (my_net_write(&join->thd->net,(char*) packet->ptr(),packet->length())) if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length()))
DBUG_VOID_RETURN; /* purecov: inspected */ DBUG_VOID_RETURN; /* purecov: inspected */
// For next iteration
used_tables|=table->map;
} }
send_eof(&join->thd->net); send_eof(&thd->net);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }

View File

@ -79,36 +79,36 @@ class JOIN;
typedef struct st_join_table { typedef struct st_join_table {
TABLE *table; TABLE *table;
int (*read_first_record)(struct st_join_table *tab);
int (*next_select)(JOIN *,struct st_join_table *,bool);
bool cached_eq_ref_table,eq_ref_table;
READ_RECORD read_record;
uint keys; /* all keys with can be used */
key_map const_keys; /* Keys with constant part */
key_map checked_keys; /* Keys checked in find_best */
key_map needed_reg;
ha_rows records,found_records,read_time;
table_map dependent,key_dependent;
uint use_quick,index;
uint status; // Save status for cache
enum join_type type;
JOIN_CACHE cache;
KEYUSE *keyuse; /* pointer to first used key */ KEYUSE *keyuse; /* pointer to first used key */
SQL_SELECT *select; SQL_SELECT *select;
COND *select_cond; COND *select_cond;
QUICK_SELECT *quick; QUICK_SELECT *quick;
Item *on_expr; Item *on_expr;
uint used_fields,used_fieldlength,used_blobs;
const char *info; const char *info;
int (*read_first_record)(struct st_join_table *tab);
int (*next_select)(JOIN *,struct st_join_table *,bool);
READ_RECORD read_record;
double worst_seeks; double worst_seeks;
key_map const_keys; /* Keys with constant part */
key_map checked_keys; /* Keys checked in find_best */
key_map needed_reg;
ha_rows records,found_records,read_time;
table_map dependent,key_dependent;
uint keys; /* all keys with can be used */
uint use_quick,index;
uint status; // Save status for cache
uint used_fields,used_fieldlength,used_blobs;
enum join_type type;
bool cached_eq_ref_table,eq_ref_table,not_used_in_distinct;
TABLE_REF ref; TABLE_REF ref;
JOIN_CACHE cache;
} JOIN_TAB; } JOIN_TAB;
typedef struct st_position { /* Used in find_best */ typedef struct st_position { /* Used in find_best */
double records_read;
JOIN_TAB *table; JOIN_TAB *table;
KEYUSE *key; KEYUSE *key;
double records_read;
} POSITION; } POSITION;
@ -116,16 +116,16 @@ typedef struct st_position { /* Used in find_best */
class TMP_TABLE_PARAM { class TMP_TABLE_PARAM {
public: public:
List<Item> copy_funcs;
Copy_field *copy_field;
byte *group_buff;
Item_result_field **funcs;
MI_COLUMNDEF *recinfo,*start_recinfo;
KEY *keyinfo;
ha_rows end_write_records;
uint copy_field_count,field_count,sum_func_count,func_count; uint copy_field_count,field_count,sum_func_count,func_count;
uint group_parts,group_length; uint group_parts,group_length;
uint quick_group; uint quick_group;
Copy_field *copy_field;
byte *group_buff;
ha_rows end_write_records;
Item_result_field **funcs;
List<Item> copy_funcs;
MI_COLUMNDEF *recinfo,*start_recinfo;
KEY *keyinfo;
TMP_TABLE_PARAM() :group_parts(0),group_length(0),copy_field(0) {} TMP_TABLE_PARAM() :group_parts(0),group_length(0),copy_field(0) {}
~TMP_TABLE_PARAM() ~TMP_TABLE_PARAM()
@ -148,7 +148,7 @@ class JOIN {
uint send_group_parts; uint send_group_parts;
bool sort_and_group,first_record,full_join,group, no_field_update; bool sort_and_group,first_record,full_join,group, no_field_update;
table_map const_table_map; table_map const_table_map;
ha_rows send_records; ha_rows send_records,found_records;
POSITION positions[MAX_TABLES+1],best_positions[MAX_TABLES+1]; POSITION positions[MAX_TABLES+1],best_positions[MAX_TABLES+1];
double best_read; double best_read;
List<Item> *fields; List<Item> *fields;

View File

@ -476,6 +476,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
DBUG_PRINT("enter",("db: %s table: %s",table_list->db, DBUG_PRINT("enter",("db: %s table: %s",table_list->db,
table_list->real_name)); table_list->real_name));
/* Only one table for now */
if (!(table = open_ltable(thd, table_list, TL_UNLOCK))) if (!(table = open_ltable(thd, table_list, TL_UNLOCK)))
{ {
send_error(&thd->net); send_error(&thd->net);
@ -490,34 +491,32 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
DBUG_RETURN(1); DBUG_RETURN(1);
String *packet = &thd->packet; String *packet = &thd->packet;
for(;table; table = table->next) {
{ packet->length(0);
packet->length(0); net_store_data(packet, table->table_name);
net_store_data(packet, table->table_name); // a hack - we need to reserve some space for the length before
// a hack - we need to reserve some space for the length before // we know what it is - let's assume that the length of create table
// we know what it is - let's assume that the length of create table // statement will fit into 3 bytes ( 16 MB max :-) )
// statement will fit into 3 bytes ( 16 MB max :-) ) ulong store_len_offset = packet->length();
ulong store_len_offset = packet->length(); packet->length(store_len_offset + 4);
packet->length(store_len_offset + 4); if (store_create_info(thd, table, packet))
if(store_create_info(thd, table, packet)) DBUG_RETURN(-1);
DBUG_RETURN(-1); ulong create_len = packet->length() - store_len_offset - 4;
ulong create_len = packet->length() - store_len_offset - 4; if (create_len > 0x00ffffff) // better readable in HEX ...
if(create_len > 0x00ffffff) // better readable in HEX ... DBUG_RETURN(1); // just in case somebody manages to create a table
DBUG_RETURN(1); // just in case somebody manages to create a table // with *that* much stuff in the definition
// with *that* much stuff in the definition
// now we have to store the length in three bytes, even if it would fit // now we have to store the length in three bytes, even if it would fit
// into fewer, so we cannot use net_store_data() anymore, // into fewer, so we cannot use net_store_data() anymore,
// and do it ourselves // and do it ourselves
char* p = (char*)packet->ptr() + store_len_offset; char* p = (char*)packet->ptr() + store_len_offset;
*p++ = (char) 253; // The client the length is stored using 3-bytes *p++ = (char) 253; // The client the length is stored using 3-bytes
int3store(p, create_len); int3store(p, create_len);
// now we are in business :-)
if(my_net_write(&thd->net, (char*)packet->ptr(), packet->length()))
DBUG_RETURN(1);
}
// now we are in business :-)
if (my_net_write(&thd->net, (char*)packet->ptr(), packet->length()))
DBUG_RETURN(1);
}
send_eof(&thd->net); send_eof(&thd->net);
DBUG_RETURN(0); DBUG_RETURN(0);
} }

View File

@ -40,7 +40,7 @@ static byte* get_field_name(Field *buff,uint *length,
/* Open a .frm file */ /* Open a .frm file */
int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
TABLE *outparam) uint ha_open_flags, TABLE *outparam)
{ {
reg1 uint i; reg1 uint i;
reg2 uchar *strpos; reg2 uchar *strpos;
@ -216,12 +216,12 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
ha_open(index_file, ha_open(index_file,
(db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR), (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
(db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE : (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
db_stat & HA_WAIT_IF_LOCKED || (db_stat & HA_WAIT_IF_LOCKED ||
specialflag & SPECIAL_WAIT_IF_LOCKED ? specialflag & SPECIAL_WAIT_IF_LOCKED) ?
HA_OPEN_WAIT_IF_LOCKED : HA_OPEN_WAIT_IF_LOCKED :
(db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ? (db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ?
HA_OPEN_ABORT_IF_LOCKED : HA_OPEN_ABORT_IF_LOCKED :
HA_OPEN_IGNORE_IF_LOCKED) | ha_open_options))) HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags)))
goto err_not_open; /* purecov: inspected */ goto err_not_open; /* purecov: inspected */
} }
outparam->db_low_byte_first=outparam->file->low_byte_first(); outparam->db_low_byte_first=outparam->file->low_byte_first();

View File

@ -18,6 +18,6 @@
/* This defines strtol() if neaded */ /* This defines strtol() if neaded */
#include <global.h> #include <global.h>
#if !defined(MSDOS) && !defined(HAVE_STRTOUL) && !defined(__WIN__) #if !defined(MSDOS) && !defined(HAVE_STRTOL) && !defined(__WIN__)
#include "strto.c" #include "strto.c"
#endif #endif

View File

@ -12,3 +12,4 @@
>3 byte x Version %d >3 byte x Version %d
0 belong&0xffffff00 0xfefe0600 MySQL ISAM compressed data file 0 belong&0xffffff00 0xfefe0600 MySQL ISAM compressed data file
>3 byte x Version %d >3 byte x Version %d
0 string \376bin MySQL replication log