Merge
configure.in: merged BitKeeper/etc/logging_ok: Auto merged sql/filesort.cc: merged sql/sql_select.cc: merged
This commit is contained in:
commit
4af074054b
@ -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
|
|
||||||
|
1280
Docs/manual.texi
1280
Docs/manual.texi
File diff suppressed because it is too large
Load Diff
@ -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
3
config.guess
vendored
@ -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
2
config.sub
vendored
@ -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* \
|
||||||
|
25
configure.in
25
configure.in
@ -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 \
|
||||||
|
@ -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++)
|
||||||
|
@ -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) \
|
||||||
|
@ -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);
|
||||||
|
@ -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 */
|
||||||
|
@ -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\
|
||||||
|
2
ltconfig
2
ltconfig
@ -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"
|
||||||
|
@ -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"
|
||||||
|
@ -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) &&
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
183
myisam/sort.c
183
myisam/sort.c
@ -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 */
|
|
||||||
|
@ -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 \
|
||||||
|
@ -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"))
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
173
mysys/mf_tempfile.c
Normal 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);
|
||||||
|
}
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
|
@ -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)))
|
||||||
|
@ -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)) ||
|
||||||
|
@ -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. */
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
|
@ -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))
|
||||||
|
@ -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));
|
||||||
|
@ -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)))
|
||||||
|
|
||||||
|
194
regex/cname.h
194
regex/cname.h
@ -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},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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",
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 ***"},
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
10
repl-tests/test-bad-query/run.test
Executable file
10
repl-tests/test-bad-query/run.test
Executable 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;
|
||||||
|
|
4
repl-tests/test-bad-query/x.master
Normal file
4
repl-tests/test-bad-query/x.master
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
n
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
@ -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 */
|
||||||
|
|
||||||
|
|
||||||
|
@ -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(¶m, file);
|
error = chk_size(¶m, 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);
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
@ -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++))
|
||||||
{
|
{
|
||||||
|
43
sql/log.cc
43
sql/log.cc
@ -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))
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
109
sql/mysqld.cc
109
sql/mysqld.cc
@ -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
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
29
sql/slave.cc
29
sql/slave.cc
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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));
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user