Commit 43502bb0 authored by monty@donna.mysql.com's avatar monty@donna.mysql.com

Merge work:/my/mysql into donna.mysql.com:/home/my/bk/mysql

parents caed453e 9a91d46f
...@@ -187,3 +187,4 @@ sql-bench/Results-linux/ATIS-mysql_bdb-Linux_2.2.14_my_SMP_i686 ...@@ -187,3 +187,4 @@ sql-bench/Results-linux/ATIS-mysql_bdb-Linux_2.2.14_my_SMP_i686
Docs/my_sys.doc Docs/my_sys.doc
tmp/* tmp/*
extra/resolve_stack_dump extra/resolve_stack_dump
sql/share/*.sys
jani@hynda.mysql.fi jani@hynda.mysql.fi
monty@donna.mysql.com
This diff is collapsed.
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
#include "my_readline.h" #include "my_readline.h"
#include <signal.h> #include <signal.h>
const char *VER="11.10"; const char *VER="11.11";
gptr sql_alloc(unsigned size); // Don't use mysqld alloc for these gptr sql_alloc(unsigned size); // Don't use mysqld alloc for these
void sql_element_free(void *ptr); void sql_element_free(void *ptr);
...@@ -1192,7 +1192,8 @@ You can turn off this feature to get a quicker startup with -A\n\n"); ...@@ -1192,7 +1192,8 @@ You can turn off this feature to get a quicker startup with -A\n\n");
field_names=0; field_names=0;
/* hash all field names, both with the table prefix and without it */ /* hash all field names, both with the table prefix and without it */
if (!tables) { /* no tables */ if (!tables) /* no tables */
{
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
mysql_data_seek(tables,0); mysql_data_seek(tables,0);
...@@ -1201,7 +1202,6 @@ You can turn off this feature to get a quicker startup with -A\n\n"); ...@@ -1201,7 +1202,6 @@ You can turn off this feature to get a quicker startup with -A\n\n");
MYF(MY_WME)); MYF(MY_WME));
if (!field_names) if (!field_names)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
field_names[mysql_num_rows(tables)]='\0';
i=0; i=0;
while ((table_row=mysql_fetch_row(tables))) while ((table_row=mysql_fetch_row(tables)))
{ {
...@@ -1229,10 +1229,14 @@ You can turn off this feature to get a quicker startup with -A\n\n"); ...@@ -1229,10 +1229,14 @@ You can turn off this feature to get a quicker startup with -A\n\n");
} }
} }
else else
{
tee_fprintf(stdout, tee_fprintf(stdout,
"Didn't find any fields in table '%s'\n",table_row[0]); "Didn't find any fields in table '%s'\n",table_row[0]);
field_names[i]=0;
}
i++; i++;
} }
field_names[i]=0; // End pointer
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -2018,11 +2022,11 @@ com_use(String *buffer __attribute__((unused)), char *line) ...@@ -2018,11 +2022,11 @@ com_use(String *buffer __attribute__((unused)), char *line)
if (mysql_select_db(&mysql,tmp)) if (mysql_select_db(&mysql,tmp))
return put_info(mysql_error(&mysql),INFO_ERROR,mysql_errno(&mysql)); return put_info(mysql_error(&mysql),INFO_ERROR,mysql_errno(&mysql));
} }
my_free(current_db,MYF(MY_ALLOW_ZERO_PTR));
current_db=my_strdup(tmp,MYF(MY_WME));
#ifdef HAVE_READLINE #ifdef HAVE_READLINE
build_completion_hash(no_rehash,1); build_completion_hash(no_rehash,1);
#endif #endif
my_free(current_db,MYF(MY_ALLOW_ZERO_PTR));
current_db=my_strdup(tmp,MYF(MY_WME));
} }
} }
else else
......
...@@ -1241,7 +1241,7 @@ MYSQL_HAVE_FIONREAD ...@@ -1241,7 +1241,7 @@ MYSQL_HAVE_FIONREAD
MYSQL_HAVE_TIOCSTAT MYSQL_HAVE_TIOCSTAT
MYSQL_STRUCT_DIRENT_D_INO MYSQL_STRUCT_DIRENT_D_INO
MYSQL_TYPE_SIGHANDLER MYSQL_TYPE_SIGHANDLER
if test $with_named_curses = "no" if test "$with_named_curses" = "no"
then then
MYSQL_CHECK_LIB_TERMCAP MYSQL_CHECK_LIB_TERMCAP
else else
......
...@@ -196,3 +196,7 @@ Changes done to this distrubtion (pthreads-1_60_beta6) by Monty (monty@tcx.se) ...@@ -196,3 +196,7 @@ Changes done to this distrubtion (pthreads-1_60_beta6) by Monty (monty@tcx.se)
00.10.18 by Monty (monty@mysql.com) 00.10.18 by Monty (monty@mysql.com)
- Added patch by Dave Huang <khym@bga.com> to fix problem with date/time - Added patch by Dave Huang <khym@bga.com> to fix problem with date/time
on NETBSD/Alpha. on NETBSD/Alpha.
01.01.11 by Monty (monty@mysql.com)
- Added patch by Allen Briggs <briggs@ninthwonder.com> for
Apple PowerMac 8500 w/ G3 upgrade running NetBSD/macppc
...@@ -295,7 +295,8 @@ EOF ...@@ -295,7 +295,8 @@ EOF
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit 0 ;; exit 0 ;;
*:NetBSD:*:*) *:NetBSD:*:*)
echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` UNAME_PROCESSOR=`uname -p 2>/dev/null` || UNAME_PROCESSOR=$UNAME_MACHINE
echo ${UNAME_PROCESSOR}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
exit 0 ;; exit 0 ;;
*:OpenBSD:*:*) *:OpenBSD:*:*)
echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
......
...@@ -1298,6 +1298,12 @@ case $host in ...@@ -1298,6 +1298,12 @@ case $host in
# hpux-9.03.mk seems to be missing; what should this be? # hpux-9.03.mk seems to be missing; what should this be?
except="fork" except="fork"
;; ;;
powerpc-*-netbsd1.*)
name=powerpc-netbsd
sysincludes=netbsd-1.1
except="fork lseek ftruncate pipe fstat"
available_syscalls="sigprocmask sigaction sigsuspend"
;;
sparc-*-sunos4.1.3* | sparc-*-sunos4.1.4*) sparc-*-sunos4.1.3* | sparc-*-sunos4.1.4*)
name=sparc-sunos-4.1.3 name=sparc-sunos-4.1.3
sysincludes=sunos-4.1.3 sysincludes=sunos-4.1.3
......
...@@ -175,6 +175,12 @@ changequote([,])dnl ...@@ -175,6 +175,12 @@ changequote([,])dnl
# hpux-9.03.mk seems to be missing; what should this be? # hpux-9.03.mk seems to be missing; what should this be?
except="fork" except="fork"
;; ;;
powerpc-*-netbsd1.*)
name=powerpc-netbsd
sysincludes=netbsd-1.1
except="fork lseek ftruncate pipe fstat"
available_syscalls="sigprocmask sigaction sigsuspend"
;;
sparc-*-sunos4.1.3* | sparc-*-sunos4.1.4*) sparc-*-sunos4.1.3* | sparc-*-sunos4.1.4*)
name=sparc-sunos-4.1.3 name=sparc-sunos-4.1.3
sysincludes=sunos-4.1.3 sysincludes=sunos-4.1.3
......
/* ==== machdep.c ============================================================
* Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
*
* Description : Machine dependent functions for NetBSD/PowerPC (1.5+)
*
* 1.00 93/08/04 proven
* -Started coding this file.
*
* 2001/01/10 briggs
* -Modified to make it go with NetBSD/PowerPC
*/
#ifndef lint
static const char rcsid[] = "engine-alpha-osf1.c,v 1.4.4.1 1995/12/13 05:41:37 proven Exp";
#endif
#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/syscall.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdio.h>
/* ==========================================================================
* machdep_pthread_start()
*/
void machdep_pthread_start(void)
{
context_switch_done();
pthread_sched_resume ();
/* XXXMLG
* This is EXTREMELY bogus, but it seems that this function is called
* with the pthread kernel locked. If this happens, __errno() will
* return the wrong address until after the first context switch.
*
* Clearly there is a leak of pthread_kernel somewhere, but until
* it is found, we force a context switch here, just before calling
* the thread start routine. When we return from pthread_yield
* the kernel will be unlocked.
*/
pthread_yield();
/* Run current threads start routine with argument */
pthread_exit(pthread_run->machdep_data.start_routine
(pthread_run->machdep_data.start_argument));
/* should never reach here */
PANIC();
}
/* ==========================================================================
* __machdep_pthread_create()
*/
void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
void *(* start_routine)(void *), void *start_argument,
long stack_size, long nsec, long flags)
{
machdep_pthread->start_routine = start_routine;
machdep_pthread->start_argument = start_argument;
machdep_pthread->machdep_timer.it_value.tv_sec = 0;
machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
/* Set up new stack frame so that it looks like it returned from a
longjmp() to the beginning of machdep_pthread_start(). */
/* state is sigmask, then r8-r31 where r11 is the LR
* So, istate[3] is r10, which is the SP
* So, istate[4] is r11, which is the LR
* So, istate[5] is r12, which is the CR
*/
machdep_pthread->machdep_istate[4] = (long)machdep_pthread_start;
machdep_pthread->machdep_istate[5] = 0;
/* PowerPC stack starts high and builds down, and needs to be 16-byte
aligned. */
machdep_pthread->machdep_istate[3] =
((long) machdep_pthread->machdep_stack + stack_size) & ~0xf;
}
/* ==========================================================================
* machdep_save_state()
*/
int machdep_save_state(void)
{
return( _setjmp(pthread_run->machdep_data.machdep_istate) );
}
void machdep_restore_state(void)
{
_longjmp(pthread_run->machdep_data.machdep_istate, 1);
}
void machdep_save_float_state (struct pthread *pthread)
{
__machdep_save_fp_state(pthread->machdep_data.machdep_fstate);
}
void machdep_restore_float_state (void)
{
__machdep_restore_fp_state(pthread_run->machdep_data.machdep_fstate);
}
/* ==========================================================================
* machdep_set_thread_timer()
*/
void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
{
if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
PANIC();
}
}
/* ==========================================================================
* machdep_unset_thread_timer()
*/
void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
{
struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
PANIC();
}
}
/* ==========================================================================
* machdep_pthread_cleanup()
*/
void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
{
return(machdep_pthread->machdep_stack);
}
void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread);
void machdep_pthread_start(void);
/* ==========================================================================
* __machdep_stack_free()
*/
void
__machdep_stack_free(void * stack)
{
free(stack);
}
/* ==========================================================================
* __machdep_stack_alloc()
*/
void *
__machdep_stack_alloc(size_t size)
{
return(malloc(size));
}
/* ==========================================================================
* machdep_sys_creat()
*/
int
machdep_sys_creat(char * path, int mode)
{
return(machdep_sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode));
}
/* ==========================================================================
* machdep_sys_wait3()
*/
int
machdep_sys_wait3(int * b, int c, int *d)
{
return(machdep_sys_wait4(0, b, c, d));
}
/* ==========================================================================
* machdep_sys_waitpid()
*/
int
machdep_sys_waitpid(int a, int * b, int c)
{
return(machdep_sys_wait4(a, b, c, NULL));
}
/* ==========================================================================
* machdep_sys_getdtablesize()
*/
int
machdep_sys_getdtablesize(void)
{
return(sysconf(_SC_OPEN_MAX));
}
/* ==========================================================================
* machdep_sys_lseek()
*/
off_t
machdep_sys_lseek(int fd, off_t offset, int whence)
{
return(__syscall((quad_t)SYS_lseek, fd, 0, offset, whence));
}
int
machdep_sys_ftruncate( int fd, off_t length)
{
quad_t q;
int rv;
q = __syscall((quad_t)SYS_ftruncate, fd,0, length);
if( /* LINTED constant */ sizeof( quad_t ) == sizeof( register_t ) ||
/* LINTED constant */ BYTE_ORDER == LITTLE_ENDIAN )
rv = (int)q;
else
rv = (int)((u_quad_t)q >> 32);
return rv;
}
/* ==========================================================================
* machdep_sys_getdirentries()
*/
int
machdep_sys_getdirentries(int fd, char * buf, int len, int * seek)
{
return(machdep_sys_getdents(fd, buf, len));
}
/* ==== machdep.h ============================================================
* Copyright (c) 1994 Chris Provenzano (proven@athena.mit.edu) and
* Ken Raeburn (raeburn@mit.edu).
*
* engine-alpha-osf1.h,v 1.4.4.1 1995/12/13 05:41:42 proven Exp
*
*/
#include <unistd.h>
#include <setjmp.h>
#include <sys/time.h>
#include <sys/cdefs.h>
#include <sys/signal.h> /* for _NSIG */
/*
* The first machine dependent functions are the SEMAPHORES
* needing the test and set instruction.
*/
#define SEMAPHORE_CLEAR 0
#define SEMAPHORE_SET 0xffff
#define SEMAPHORE_TEST_AND_SET(lock) \
({ \
volatile long t1, temp = SEMAPHORE_SET; \
__asm__ volatile( \
"1: lwarx %0,0,%1; \
cmpwi %0, 0; \
bne 2f; \
stwcx. %2,0,%1; \
bne- 1b; \
2: " \
:"=r" (t1) \
:"m" (lock), "r" (temp)); \
t1; \
})
#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
/*
* New types
*/
typedef int semaphore;
/*
* sigset_t macros
*/
#define SIG_ANY(sig) (sig)
#define SIGMAX (_NSIG-1)
/*
* New Strutures
*/
struct machdep_pthread {
void *(*start_routine)(void *);
void *start_argument;
void *machdep_stack;
struct itimerval machdep_timer;
jmp_buf machdep_istate;
unsigned long machdep_fstate[66];
/* 64-bit fp regs 0-31 + fpscr */
/* We pretend the fpscr is 64 bits */
};
/*
* Static machdep_pthread initialization values.
* For initial thread only.
*/
#define MACHDEP_PTHREAD_INIT \
{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, { 0 }, { 0 } }
/*
* Minimum stack size
*/
#define PTHREAD_STACK_MIN 2048
/*
* Some fd flag defines that are necessary to distinguish between posix
* behavior and bsd4.3 behavior.
*/
#define __FD_NONBLOCK O_NONBLOCK
/*
* New functions
*/
__BEGIN_DECLS
#if defined(PTHREAD_KERNEL)
#define __machdep_stack_get(x) (x)->machdep_stack
#define __machdep_stack_set(x, y) (x)->machdep_stack = y
#define __machdep_stack_repl(x, y) \
{ \
if ((stack = __machdep_stack_get(x))) { \
__machdep_stack_free(stack); \
} \
__machdep_stack_set(x, y); \
}
int machdep_save_state(void);
void __machdep_save_fp_state(unsigned long *);
void __machdep_restore_fp_state(unsigned long *);
void *__machdep_stack_alloc(size_t);
void __machdep_stack_free(void *);
#endif
__END_DECLS
#include <machine/asm.h>
#define COMPAT_43
#include <sys/syscall.h>
#ifndef __CONCAT
#include <sys/cdefs.h>
#endif
#define CONCAT __CONCAT
#undef SYSCALL
/* Kernel syscall interface:
Input:
0 - system call number
3-8 - arguments, as in C
Output:
so - (summary overflow) clear iff successful
This macro is similar to SYSCALL in asm.h, but not completely.
There's room for optimization, if we assume this will continue to
be assembled as one file.
This macro expansions does not include the return instruction.
If there's no other work to be done, use something like:
SYSCALL(foo) ; ret
If there is other work to do (in fork, maybe?), do it after the
SYSCALL invocation. */
ENTRY(machdep_cerror)
mflr 0 # Save LR in 0
stwu 1,-16(1) # allocate new stack frame
stw 0,20(1) # Stash 0 in stack
stw 31,8(1) # Stash 31 in stack (since it's callee-saved
mr 31,3 # and we stash return there)
bl PIC_PLT(_C_LABEL(__errno))
stw 31,0(3) # *errno() = err
lwz 0,20(1) # Restore LR from stack to 0
neg 3,31 # return -errno to 3
lwz 31,8(1) # Restore 31 from stack
mtlr 0
la 1,16(1) # Restore stack frame
li 4,-1 # Put -1 in r4 for those syscalls that return
blr # two values
/* The fork system call is special... */
ENTRY(machdep_sys_fork)
li 0, SYS_fork
sc
bso PIC_PLT(_C_LABEL(machdep_cerror))
addi 4,4,-1
blr
/* The pipe system call is special... */
ENTRY(machdep_sys_pipe)
mr 5,3
li 0,SYS_pipe
sc
bso PIC_PLT(_C_LABEL(machdep_cerror))
stw 3,0(5) # Success, store fds
stw 4,4(5)
li 3,0
blr # And return 0
#ifndef SYS___sigsuspend14
/* The sigsuspend system call is special... */
ENTRY(machdep_sys_sigsuspend)
lwz 3,0(3)
li 0,SYS_compat_13_sigsuspend13
sc
b PIC_PLT(_C_LABEL(machdep_cerror))
#endif /* SYS_sigsuspend14 */
#ifndef SYS___sigprocmask14
/* The sigprocmask system call is special... */
ENTRY(machdep_sys_sigprocmask)
or. 4,4,4 # Set == NULL ?
li 6,1 # how = SIG_BLOCK
beq Ldoit
lwz 4,0(4) # if not, replace it in r4 with #set
mr 6,3
Ldoit: mr 3,6 # ... using sigprocmask(SIG_BLOCK)
li 0,SYS_compat_13_sigprocmask13
sc
bso PIC_PLT(_C_LABEL(machdep_cerror))
or. 5,5,5 # Check to see if oset requested
beq Ldone # if oset != NULL
stw 3,0(5) # *oset = oldmask
Ldone:
li 3,0 # return 0
blr
#endif /* SYS_sigprocmask14 */
/* More stuff ... */
/* For fstat() we actually syscall fstat13. */
ENTRY(machdep_sys_fstat)
li 0, SYS___fstat13
sc
bnslr
b PIC_PLT(_C_LABEL(machdep_cerror))
/* Do we need to save the entire floating point state? I think so... */
ENTRY(__machdep_save_fp_state)
stwu 1,-8(1)
stw 3,4(1)
stfd 0,0(3)
stfdu 1,8(3)
stfdu 2,8(3)
stfdu 3,8(3)
stfdu 4,8(3)
stfdu 5,8(3)
stfdu 6,8(3)
stfdu 7,8(3)
stfdu 8,8(3)
stfdu 9,8(3)
stfdu 10,8(3)
stfdu 11,8(3)
stfdu 12,8(3)
stfdu 13,8(3)
stfdu 14,8(3)
stfdu 15,8(3)
stfdu 16,8(3)
stfdu 17,8(3)
stfdu 18,8(3)
stfdu 19,8(3)
stfdu 20,8(3)
stfdu 21,8(3)
stfdu 22,8(3)
stfdu 23,8(3)
stfdu 24,8(3)
stfdu 25,8(3)
stfdu 26,8(3)
stfdu 27,8(3)
stfdu 28,8(3)
stfdu 29,8(3)
stfdu 30,8(3)
stfdu 31,8(3)
mffs 0
stfdu 0,8(3)
lwz 3,4(1)
lwz 1,0(1)
blr
ENTRY(__machdep_restore_fp_state)
stwu 1,-12(1)
stw 3,4(1)
stw 4,8(1)
mr 4,3
lfdu 1,8(3)
lfdu 2,8(3)
lfdu 3,8(3)
lfdu 4,8(3)
lfdu 5,8(3)
lfdu 6,8(3)
lfdu 7,8(3)
lfdu 8,8(3)
lfdu 9,8(3)
lfdu 10,8(3)
lfdu 11,8(3)
lfdu 12,8(3)
lfdu 13,8(3)
lfdu 14,8(3)
lfdu 15,8(3)
lfdu 16,8(3)
lfdu 17,8(3)
lfdu 18,8(3)
lfdu 19,8(3)
lfdu 20,8(3)
lfdu 21,8(3)
lfdu 22,8(3)
lfdu 23,8(3)
lfdu 24,8(3)
lfdu 25,8(3)
lfdu 26,8(3)
lfdu 27,8(3)
lfdu 28,8(3)
lfdu 29,8(3)
lfdu 30,8(3)
lfdu 31,8(3)
lfdu 0,8(3)
mtfsf 127,0
lfd 0,0(4)
lwz 3,4(1)
lwz 4,8(1)
lwz 1,0(1)
blr
#include <machine/asm.h>
#define COMPAT_43
#include <sys/syscall.h>
#ifdef SYS___sigsuspend14
#define SYS_sigsuspend SYS___sigsuspend14
#endif
#ifdef SYS___sigaction14
#define SYS_sigaction SYS___sigaction14
#endif
#ifdef SYS___sigprocmask14
#define SYS_sigprocmask SYS___sigprocmask14
#endif
#undef SYSCALL
/* Kernel syscall interface:
Input:
0 - system call number
3-8 - arguments, as in C
Output:
so - (summary overflow) clear iff successful
This macro is similar to SYSCALL in asm.h, but not completely.
There's room for optimization, if we assume this will continue to
be assembled as one file.
This macro expansions does not include the return instruction.
If there's no other work to be done, use something like:
SYSCALL(foo) ; ret
If there is other work to do (in fork, maybe?), do it after the
SYSCALL invocation. */
#define SYSCALL(x) \
ENTRY(machdep_sys_ ## x) \
li 0, SYS_ ## x ; \
sc ; \
bnslr ; \
b PIC_PLT(_C_LABEL(machdep_cerror))
#define XSYSCALL(x) SYSCALL(x) ; blr
XSYSCALL(SYSCALL_NAME)
...@@ -35,6 +35,14 @@ grp a c id a c d ...@@ -35,6 +35,14 @@ grp a c id a c d
1 1 a 1 1 a 1 1 1 a 1 1 a 1
2 2 b NULL NULL NULL NULL 2 2 b NULL NULL NULL NULL
2 3 c NULL NULL NULL NULL 2 3 c NULL NULL NULL NULL
3 4 E 3 4 A 4
3 5 C 3 5 B 5
3 6 D 3 6 C 6
NULL NULL NULL NULL NULL NULL
grp a c id a c d
1 1 a 1 1 a 1
2 2 b NULL NULL NULL NULL
2 3 c NULL NULL NULL NULL
3 4 E NULL NULL NULL NULL 3 4 E NULL NULL NULL NULL
3 5 C NULL NULL NULL NULL 3 5 C NULL NULL NULL NULL
3 6 D NULL NULL NULL NULL 3 6 D NULL NULL NULL NULL
......
...@@ -18,6 +18,7 @@ select t1.*,t2.* from t1 left join t2 on (t1.a=t2.a) order by t1.grp,t1.a,t2.c; ...@@ -18,6 +18,7 @@ select t1.*,t2.* from t1 left join t2 on (t1.a=t2.a) order by t1.grp,t1.a,t2.c;
select t1.*,t2.* from { oj t2 left outer join t1 on (t1.a=t2.a) }; select t1.*,t2.* from { oj t2 left outer join t1 on (t1.a=t2.a) };
select t1.*,t2.* from t1 as t0,{ oj t2 left outer join t1 on (t1.a=t2.a) } WHERE t0.a=2; select t1.*,t2.* from t1 as t0,{ oj t2 left outer join t1 on (t1.a=t2.a) } WHERE t0.a=2;
select t1.*,t2.* from t1 left join t2 using (a); select t1.*,t2.* from t1 left join t2 using (a);
select t1.*,t2.* from t1 left join t2 using (a) where t1.a=t2.a;
select t1.*,t2.* from t1 left join t2 using (a,c); select t1.*,t2.* from t1 left join t2 using (a,c);
select t1.*,t2.* from t1 left join t2 using (c); select t1.*,t2.* from t1 left join t2 using (c);
select t1.*,t2.* from t1 natural left outer join t2; select t1.*,t2.* from t1 natural left outer join t2;
......
#!@PERL@ #!@PERL@ -w
use strict; use strict;
use Getopt::Long; use Getopt::Long;
...@@ -36,8 +36,9 @@ WARNING: THIS IS VERY MUCH A FIRST-CUT ALPHA. Comments/patches welcome. ...@@ -36,8 +36,9 @@ WARNING: THIS IS VERY MUCH A FIRST-CUT ALPHA. Comments/patches welcome.
# Documentation continued at end of file # Documentation continued at end of file
my $VERSION = "1.9"; my $VERSION = "1.10";
my $opt_tmpdir= $main::ENV{TMPDIR};
my $opt_tmpdir = $ENV{TMPDIR} || "/tmp";
my $OPTIONS = <<"_OPTIONS"; my $OPTIONS = <<"_OPTIONS";
...@@ -74,7 +75,7 @@ sub usage { ...@@ -74,7 +75,7 @@ sub usage {
} }
my %opt = ( my %opt = (
user => getpwuid($>), user => scalar getpwuid($>),
noindices => 0, noindices => 0,
allowold => 0, # for safety allowold => 0, # for safety
keepold => 0, keepold => 0,
...@@ -139,7 +140,7 @@ else { ...@@ -139,7 +140,7 @@ else {
my %mysqld_vars; my %mysqld_vars;
my $start_time = time; my $start_time = time;
my $opt_tmpdir= $opt{tmpdir} ? $opt{tmpdir} : $main::ENV{TMPDIR}; $opt_tmpdir= $opt{tmpdir} if $opt{tmpdir};
$0 = $1 if $0 =~ m:/([^/]+)$:; $0 = $1 if $0 =~ m:/([^/]+)$:;
$opt{quiet} = 0 if $opt{debug}; $opt{quiet} = 0 if $opt{debug};
$opt{allowold} = 1 if $opt{keepold}; $opt{allowold} = 1 if $opt{keepold};
...@@ -235,16 +236,17 @@ foreach my $rdb ( @db_desc ) { ...@@ -235,16 +236,17 @@ foreach my $rdb ( @db_desc ) {
or die "Cannot open dir '$db_dir': $!"; or die "Cannot open dir '$db_dir': $!";
my %db_files; my %db_files;
map { ( /(.+)\.\w+$/ ? { $db_files{$_} = $1 } : () ) } readdir(DBDIR); map { ( /(.+)\.\w+$/ ? ( $db_files{$_} = $1 ) : () ) } readdir(DBDIR);
unless( keys %db_files ) { unless( keys %db_files ) {
warn "'$db' is an empty database\n"; warn "'$db' is an empty database\n";
} }
closedir( DBDIR ); closedir( DBDIR );
## filter (out) files specified in t_regex ## filter (out) files specified in t_regex
my @db_files = sort ( $negated my @db_files = ( $negated
? grep { $db_files{$_} !~ $t_regex } keys %db_files ? grep { $db_files{$_} !~ $t_regex } keys %db_files
: grep { $db_files{$_} =~ $t_regex } keys %db_files ); : grep { $db_files{$_} =~ $t_regex } keys %db_files );
@db_files = sort @db_files;
my @index_files=(); my @index_files=();
## remove indices unless we're told to keep them ## remove indices unless we're told to keep them
...@@ -776,3 +778,5 @@ Scott Wiersdorf - added table regex and scp support ...@@ -776,3 +778,5 @@ Scott Wiersdorf - added table regex and scp support
Monty - working --noindex (copy only first 2048 bytes of index file) Monty - working --noindex (copy only first 2048 bytes of index file)
Fixes for --method=scp Fixes for --method=scp
Ask Bjoern Hansen - Cleanup code to fix a few bugs and enable -w again.
...@@ -78,7 +78,7 @@ const char *ha_berkeley_ext=".db"; ...@@ -78,7 +78,7 @@ const char *ha_berkeley_ext=".db";
bool berkeley_skip=0,berkeley_shared_data=0; bool berkeley_skip=0,berkeley_shared_data=0;
u_int32_t berkeley_init_flags= DB_PRIVATE | DB_RECOVER, berkeley_env_flags=0, u_int32_t berkeley_init_flags= DB_PRIVATE | DB_RECOVER, berkeley_env_flags=0,
berkeley_lock_type=DB_LOCK_DEFAULT; berkeley_lock_type=DB_LOCK_DEFAULT;
ulong berkeley_cache_size; ulong berkeley_cache_size, berkeley_log_buffer_size, berkeley_log_file_size=0;
char *berkeley_home, *berkeley_tmpdir, *berkeley_logdir; char *berkeley_home, *berkeley_tmpdir, *berkeley_logdir;
long berkeley_lock_scan_time=0; long berkeley_lock_scan_time=0;
ulong berkeley_trans_retry=1; ulong berkeley_trans_retry=1;
...@@ -99,7 +99,8 @@ static void berkeley_print_error(const char *db_errpfx, char *buffer); ...@@ -99,7 +99,8 @@ static void berkeley_print_error(const char *db_errpfx, char *buffer);
static byte* bdb_get_key(BDB_SHARE *share,uint *length, static byte* bdb_get_key(BDB_SHARE *share,uint *length,
my_bool not_used __attribute__((unused))); my_bool not_used __attribute__((unused)));
static BDB_SHARE *get_share(const char *table_name, TABLE *table); static BDB_SHARE *get_share(const char *table_name, TABLE *table);
static int free_share(BDB_SHARE *share, TABLE *table, uint hidden_primary_key); static int free_share(BDB_SHARE *share, TABLE *table, uint hidden_primary_key,
bool mutex_is_locked);
static int write_status(DB *status_block, char *buff, uint length); static int write_status(DB *status_block, char *buff, uint length);
static void update_status(BDB_SHARE *share, TABLE *table); static void update_status(BDB_SHARE *share, TABLE *table);
static void berkeley_noticecall(DB_ENV *db_env, db_notices notice); static void berkeley_noticecall(DB_ENV *db_env, db_notices notice);
...@@ -118,6 +119,23 @@ bool berkeley_init(void) ...@@ -118,6 +119,23 @@ bool berkeley_init(void)
berkeley_tmpdir=mysql_tmpdir; berkeley_tmpdir=mysql_tmpdir;
if (!berkeley_home) if (!berkeley_home)
berkeley_home=mysql_real_data_home; berkeley_home=mysql_real_data_home;
/*
If we don't set set_lg_bsize() we will get into trouble when
trying to use many open BDB tables.
If log buffer is not set, assume that the we will need 512 byte per
open table. This is a number that we have reached by testing.
*/
if (!berkeley_log_buffer_size)
{
berkeley_log_buffer_size= max(table_cache_size*512,32*1024);
}
/*
Berkeley DB require that
berkeley_log_file_size >= berkeley_log_buffer_size*4
*/
berkeley_log_file_size= berkeley_log_buffer_size*4;
berkeley_log_file_size= MY_ALIGN(berkeley_log_file_size,1024*1024L);
berkeley_log_file_size= max(berkeley_log_file_size, 10*1024*1024L);
if (db_env_create(&db_env,0)) if (db_env_create(&db_env,0))
DBUG_RETURN(1); DBUG_RETURN(1);
...@@ -136,6 +154,8 @@ bool berkeley_init(void) ...@@ -136,6 +154,8 @@ bool berkeley_init(void)
1); 1);
db_env->set_cachesize(db_env, 0, berkeley_cache_size, 0); db_env->set_cachesize(db_env, 0, berkeley_cache_size, 0);
db_env->set_lg_max(db_env, berkeley_log_file_size);
db_env->set_lg_bsize(db_env, berkeley_log_buffer_size);
db_env->set_lk_detect(db_env, berkeley_lock_type); db_env->set_lk_detect(db_env, berkeley_lock_type);
if (berkeley_max_lock) if (berkeley_max_lock)
db_env->set_lk_max(db_env, berkeley_max_lock); db_env->set_lk_max(db_env, berkeley_max_lock);
...@@ -465,7 +485,7 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked) ...@@ -465,7 +485,7 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
{ {
if ((error=db_create(&file, db_env, 0))) if ((error=db_create(&file, db_env, 0)))
{ {
free_share(share,table, hidden_primary_key); free_share(share,table, hidden_primary_key,1);
my_free(rec_buff,MYF(0)); my_free(rec_buff,MYF(0));
my_free(alloc_ptr,MYF(0)); my_free(alloc_ptr,MYF(0));
my_errno=error; my_errno=error;
...@@ -482,7 +502,7 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked) ...@@ -482,7 +502,7 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
2 | 4), 2 | 4),
"main", DB_BTREE, open_mode,0)))) "main", DB_BTREE, open_mode,0))))
{ {
free_share(share,table, hidden_primary_key); free_share(share,table, hidden_primary_key,1);
my_free(rec_buff,MYF(0)); my_free(rec_buff,MYF(0));
my_free(alloc_ptr,MYF(0)); my_free(alloc_ptr,MYF(0));
my_errno=error; my_errno=error;
...@@ -555,7 +575,7 @@ int ha_berkeley::close(void) ...@@ -555,7 +575,7 @@ int ha_berkeley::close(void)
my_free(rec_buff,MYF(MY_ALLOW_ZERO_PTR)); my_free(rec_buff,MYF(MY_ALLOW_ZERO_PTR));
my_free(alloc_ptr,MYF(MY_ALLOW_ZERO_PTR)); my_free(alloc_ptr,MYF(MY_ALLOW_ZERO_PTR));
DBUG_RETURN(free_share(share,table, hidden_primary_key)); DBUG_RETURN(free_share(share,table, hidden_primary_key,0));
} }
...@@ -2077,11 +2097,14 @@ static BDB_SHARE *get_share(const char *table_name, TABLE *table) ...@@ -2077,11 +2097,14 @@ static BDB_SHARE *get_share(const char *table_name, TABLE *table)
return share; return share;
} }
static int free_share(BDB_SHARE *share, TABLE *table, uint hidden_primary_key) static int free_share(BDB_SHARE *share, TABLE *table, uint hidden_primary_key,
bool mutex_is_locked)
{ {
int error, result = 0; int error, result = 0;
uint keys=table->keys + test(hidden_primary_key); uint keys=table->keys + test(hidden_primary_key);
pthread_mutex_lock(&bdb_mutex); pthread_mutex_lock(&bdb_mutex);
if (mutex_is_locked)
pthread_mutex_unlock(&share->mutex);
if (!--share->use_count) if (!--share->use_count)
{ {
DB **key_file = share->key_file; DB **key_file = share->key_file;
......
...@@ -168,7 +168,7 @@ class ha_berkeley: public handler ...@@ -168,7 +168,7 @@ class ha_berkeley: public handler
extern bool berkeley_skip, berkeley_shared_data; extern bool berkeley_skip, berkeley_shared_data;
extern u_int32_t berkeley_init_flags,berkeley_env_flags, berkeley_lock_type, extern u_int32_t berkeley_init_flags,berkeley_env_flags, berkeley_lock_type,
berkeley_lock_types[]; berkeley_lock_types[];
extern ulong berkeley_cache_size, berkeley_max_lock; extern ulong berkeley_cache_size, berkeley_max_lock, berkeley_log_buffer_size;
extern char *berkeley_home, *berkeley_tmpdir, *berkeley_logdir; extern char *berkeley_home, *berkeley_tmpdir, *berkeley_logdir;
extern long berkeley_lock_scan_time; extern long berkeley_lock_scan_time;
extern TYPELIB berkeley_lock_typelib; extern TYPELIB berkeley_lock_typelib;
......
This diff is collapsed.
...@@ -21,15 +21,13 @@ ...@@ -21,15 +21,13 @@
#pragma interface /* gcc class implementation */ #pragma interface /* gcc class implementation */
#endif #endif
/* Store the MySQL bool type definition to this defined type:
inside ha_innobase we use the Innobase definition of the bool type! */
typedef bool mysql_bool;
/* This file defines the Innobase handler: the interface between MySQL and /* This file defines the Innobase handler: the interface between MySQL and
Innobase */ Innobase */
extern "C" {
#include <data0types.h>
#include <dict0types.h>
#include <row0types.h>
}
typedef struct st_innobase_share { typedef struct st_innobase_share {
THR_LOCK lock; THR_LOCK lock;
pthread_mutex_t mutex; pthread_mutex_t mutex;
...@@ -73,12 +71,6 @@ class ha_innobase: public handler ...@@ -73,12 +71,6 @@ class ha_innobase: public handler
ulong max_row_length(const byte *buf); ulong max_row_length(const byte *buf);
uint store_key_val_for_row(uint keynr, char* buff, const byte* record); uint store_key_val_for_row(uint keynr, char* buff, const byte* record);
void convert_row_to_innobase(dtuple_t* row, char* record);
void convert_row_to_mysql(char* record, dtuple_t* row);
dtuple_t* convert_key_to_innobase(dtuple_t* tuple, byte* buf,
dict_index_t* index,
KEY* key, byte* key_ptr, int key_len);
int calc_row_difference(upd_t* uvect, byte* old_row, byte* new_row);
int update_thd(THD* thd); int update_thd(THD* thd);
int change_active_index(uint keynr); int change_active_index(uint keynr);
int general_fetch(byte* buf, uint direction, uint match_mode); int general_fetch(byte* buf, uint direction, uint match_mode);
...@@ -110,7 +102,7 @@ class ha_innobase: public handler ...@@ -110,7 +102,7 @@ class ha_innobase: public handler
bool fast_key_read() { return 1;} bool fast_key_read() { return 1;}
bool has_transactions() { return 1;} bool has_transactions() { return 1;}
int open(const char *name, int mode, int test_if_locked); int open(const char *name, int mode, uint test_if_locked);
void initialize(void); void initialize(void);
int close(void); int close(void);
double scan_time(); double scan_time();
...@@ -162,13 +154,14 @@ extern uint innobase_init_flags, innobase_lock_type; ...@@ -162,13 +154,14 @@ extern uint innobase_init_flags, innobase_lock_type;
extern ulong innobase_cache_size; extern ulong innobase_cache_size;
extern char *innobase_home, *innobase_tmpdir, *innobase_logdir; extern char *innobase_home, *innobase_tmpdir, *innobase_logdir;
extern long innobase_lock_scan_time; extern long innobase_lock_scan_time;
extern long innobase_mirrored_log_groups, innobase_mirrored_log_groups; extern long innobase_mirrored_log_groups, innobase_log_files_in_group;
extern long innobase_log_file_size, innobase_log_buffer_size; extern long innobase_log_file_size, innobase_log_buffer_size;
extern long innobase_buffer_pool_size, innobase_additional_mem_pool_size; extern long innobase_buffer_pool_size, innobase_additional_mem_pool_size;
extern long innobase_file_io_threads; extern long innobase_file_io_threads;
extern char *innobase_data_home_dir, *innobase_data_file_path; extern char *innobase_data_home_dir, *innobase_data_file_path;
extern char *innobase_log_group_home_dir, *innobase_log_arch_dir; extern char *innobase_log_group_home_dir, *innobase_log_arch_dir;
extern bool innobase_flush_log_at_trx_commit,innobase_log_archive; extern bool innobase_flush_log_at_trx_commit, innobase_log_archive,
innobase_use_native_aio;
extern TYPELIB innobase_lock_typelib; extern TYPELIB innobase_lock_typelib;
...@@ -176,7 +169,6 @@ bool innobase_init(void); ...@@ -176,7 +169,6 @@ bool innobase_init(void);
bool innobase_end(void); bool innobase_end(void);
bool innobase_flush_logs(void); bool innobase_flush_logs(void);
int innobase_commit(THD *thd); int innobase_commit(THD *thd, void* trx_handle);
int innobase_rollback(THD *thd); int innobase_rollback(THD *thd, void* trx_handle);
int innobase_close_connection(THD *thd); int innobase_close_connection(THD *thd);
...@@ -952,7 +952,7 @@ void sql_print_error(const char *format,...) ...@@ -952,7 +952,7 @@ void sql_print_error(const char *format,...)
#ifndef DBUG_OFF #ifndef DBUG_OFF
{ {
char buff[1024]; char buff[1024];
vsprintf(buff,format,args); vsnprintf(buff,sizeof(buff)-1,format,args);
DBUG_PRINT("error",("%s",buff)); DBUG_PRINT("error",("%s",buff));
} }
#endif #endif
......
...@@ -1190,7 +1190,11 @@ static void init_signals(void) ...@@ -1190,7 +1190,11 @@ static void init_signals(void)
struct sigaction sa; sa.sa_flags = 0; struct sigaction sa; sa.sa_flags = 0;
sigemptyset(&sa.sa_mask); sigemptyset(&sa.sa_mask);
sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL); sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
sa.sa_handler=handle_segfault; #ifdef HAVE_DARWIN_THREADS
sa.sa_handler=( void (*)() ) handle_segfault;
#else
sa.sa_handler=handle_segfault;
#endif
sigaction(SIGSEGV, &sa, NULL); sigaction(SIGSEGV, &sa, NULL);
(void) sigemptyset(&set); (void) sigemptyset(&set);
#ifdef THREAD_SPECIFIC_SIGPIPE #ifdef THREAD_SPECIFIC_SIGPIPE
...@@ -2512,6 +2516,8 @@ CHANGEABLE_VAR changeable_vars[] = { ...@@ -2512,6 +2516,8 @@ CHANGEABLE_VAR changeable_vars[] = {
#ifdef HAVE_BERKELEY_DB #ifdef HAVE_BERKELEY_DB
{ "bdb_cache_size", (long*) &berkeley_cache_size, { "bdb_cache_size", (long*) &berkeley_cache_size,
KEY_CACHE_SIZE, 20*1024, (long) ~0, 0, IO_SIZE }, KEY_CACHE_SIZE, 20*1024, (long) ~0, 0, IO_SIZE },
{"bdb_log_buffer_size", (long*) &berkeley_log_buffer_size, 0, 256*1024L,
~0L, 0, 1024},
{ "bdb_max_lock", (long*) &berkeley_max_lock, { "bdb_max_lock", (long*) &berkeley_max_lock,
10000, 0, (long) ~0, 0, 1 }, 10000, 0, (long) ~0, 0, 1 },
/* QQ: The following should be removed soon! */ /* QQ: The following should be removed soon! */
...@@ -2622,6 +2628,7 @@ struct show_var_st init_vars[]= { ...@@ -2622,6 +2628,7 @@ struct show_var_st init_vars[]= {
{"basedir", mysql_home, SHOW_CHAR}, {"basedir", mysql_home, SHOW_CHAR},
#ifdef HAVE_BERKELEY_DB #ifdef HAVE_BERKELEY_DB
{"bdb_cache_size", (char*) &berkeley_cache_size, SHOW_LONG}, {"bdb_cache_size", (char*) &berkeley_cache_size, SHOW_LONG},
{"bdb_log_buffer_size", (char*) &berkeley_log_buffer_size, SHOW_LONG},
{"bdb_home", (char*) &berkeley_home, SHOW_CHAR_PTR}, {"bdb_home", (char*) &berkeley_home, SHOW_CHAR_PTR},
{"bdb_max_lock", (char*) &berkeley_max_lock, SHOW_LONG}, {"bdb_max_lock", (char*) &berkeley_max_lock, SHOW_LONG},
{"bdb_logdir", (char*) &berkeley_logdir, SHOW_CHAR_PTR}, {"bdb_logdir", (char*) &berkeley_logdir, SHOW_CHAR_PTR},
...@@ -2812,7 +2819,7 @@ static void usage(void) ...@@ -2812,7 +2819,7 @@ static void usage(void)
Don't flush key buffers between writes for any MyISAM\n\ Don't flush key buffers between writes for any MyISAM\n\
table\n\ table\n\
--enable-locking Enable system locking\n\ --enable-locking Enable system locking\n\
-T, --exit-info Print some debug info at exit\n\ -T, --exit-info Used for debugging; Use at your own risk!\n\
--flush Flush tables to disk between SQL commands\n\ --flush Flush tables to disk between SQL commands\n\
-?, --help Display this help and exit\n\ -?, --help Display this help and exit\n\
--init-file=file Read SQL commands from this file at startup\n\ --init-file=file Read SQL commands from this file at startup\n\
......
...@@ -4837,7 +4837,8 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), ...@@ -4837,7 +4837,8 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
/***************************************************************************** /*****************************************************************************
** Remove calculation with tables that aren't yet read. Remove also tests ** Remove calculation with tables that aren't yet read. Remove also tests
** against fields that are read through key. ** against fields that are read through key where the table is not a
** outer join table.
** We can't remove tests that are made against columns which are stored ** We can't remove tests that are made against columns which are stored
** in sorted order. ** in sorted order.
*****************************************************************************/ *****************************************************************************/
...@@ -4853,7 +4854,8 @@ static bool test_if_ref(Item_field *left_item,Item *right_item) ...@@ -4853,7 +4854,8 @@ static bool test_if_ref(Item_field *left_item,Item *right_item)
if (ref_item && ref_item->eq(right_item)) if (ref_item && ref_item->eq(right_item))
{ {
if (right_item->type() == Item::FIELD_ITEM) if (right_item->type() == Item::FIELD_ITEM)
return field->eq_def(((Item_field *) right_item)->field); return (field->eq_def(((Item_field *) right_item)->field) &&
!field->table->maybe_null);
if (right_item->const_item()) if (right_item->const_item())
{ {
// We can remove binary fields and numerical fields except float, // We can remove binary fields and numerical fields except float,
......
...@@ -17,7 +17,7 @@ use DBI; ...@@ -17,7 +17,7 @@ use DBI;
use Getopt::Long; use Getopt::Long;
$| = 1; $| = 1;
$VER = "2.0"; $VER = "2.1";
$opt_help = 0; $opt_help = 0;
$opt_version = 0; $opt_version = 0;
...@@ -40,6 +40,32 @@ my ($dbh, $progname, $mail_no_from_f, $mail_no_txt_f, $mail_too_big, ...@@ -40,6 +40,32 @@ my ($dbh, $progname, $mail_no_from_f, $mail_no_txt_f, $mail_too_big,
$mail_no_from_f = $mail_no_txt_f = $mail_too_big = $mail_forwarded = $mail_no_from_f = $mail_no_txt_f = $mail_too_big = $mail_forwarded =
$mail_duplicates = $mail_no_subject_f = $mail_inserted = 0; $mail_duplicates = $mail_no_subject_f = $mail_inserted = 0;
$mail_fixed=0;
#
# Remove the following message-ends from message
#
@remove_tail= (
"\n-*\nSend a mail to .*\n.*\n.*\$",
"\n-*\nPlease check .*\n.*\n\nTo unsubscribe, .*\n.*\n.*\nIf you have a broken.*\n.*\n.*\$",
"\n-*\nPlease check .*\n(.*\n){1,3}\nTo unsubscribe.*\n.*\n.*\$",
"\n-*\nPlease check .*\n.*\n\nTo unsubscribe.*\n.*\$",
"\n-*\nTo request this thread.*\nTo unsubscribe.*\n.*\.*\n.*\$",
"\n -*\n.*Send a mail to.*\n.*\n.*unsubscribe.*\$",
"\n-*\nTo request this thread.*\n\nTo unsubscribe.*\n.*\$"
);
# Generate regexp to remove tails where the unsubscribed is quoted
{
my (@tmp, $tail);
@tmp=();
foreach $tail (@remove_tail)
{
$tail =~ s/\n/\n[> ]*/g;
push(@tmp, $tail);
}
push @remove_tail,@tmp;
}
my %months = ('Jan' => 1, 'Feb' => 2, 'Mar' => 3, 'Apr' => 4, 'May' => 5, my %months = ('Jan' => 1, 'Feb' => 2, 'Mar' => 3, 'Apr' => 4, 'May' => 5,
'Jun' => 6, 'Jul' => 7, 'Aug' => 8, 'Sep' => 9, 'Oct' => 10, 'Jun' => 6, 'Jul' => 7, 'Aug' => 8, 'Sep' => 9, 'Oct' => 10,
...@@ -90,7 +116,8 @@ sub main ...@@ -90,7 +116,8 @@ sub main
push @args, "mysql_socket=$opt_socket" if defined($opt_socket); push @args, "mysql_socket=$opt_socket" if defined($opt_socket);
push @args, "mysql_read_default_group=mail_to_db"; push @args, "mysql_read_default_group=mail_to_db";
$connect_arg .= join ';', @args; $connect_arg .= join ';', @args;
$dbh = DBI->connect("$connect_arg", $opt_user, $opt_password) $dbh = DBI->connect("$connect_arg", $opt_user, $opt_password,
{ PrintError => 0})
|| die "Couldn't connect: $DBI::errstr\n"; || die "Couldn't connect: $DBI::errstr\n";
die "You must specify the database; use --db=" if (!defined($opt_db)); die "You must specify the database; use --db=" if (!defined($opt_db));
...@@ -127,6 +154,7 @@ sub main ...@@ -127,6 +154,7 @@ sub main
print "Total number of mails:\t\t"; print "Total number of mails:\t\t";
print $mail_inserted + $ignored; print $mail_inserted + $ignored;
print "\n"; print "\n";
print "Mails with unsubscribe removed:\t$mail_fixed\n";
exit(0); exit(0);
} }
...@@ -279,6 +307,9 @@ sub date_parser ...@@ -279,6 +307,9 @@ sub date_parser
print "Inbox filename: $file_name\n"; print "Inbox filename: $file_name\n";
} }
exit(1) if ($opt_stop_on_error); exit(1) if ($opt_stop_on_error);
$values->{'date'} = "";
$values->{'time_zone'} = "";
return;
} }
$tmp = $3 . "-" . $months{$2} . "-" . "$1 $4"; $tmp = $3 . "-" . $months{$2} . "-" . "$1 $4";
$tmp.= defined($5) ? $5 : ":00"; $tmp.= defined($5) ? $5 : ":00";
...@@ -294,15 +325,29 @@ sub date_parser ...@@ -294,15 +325,29 @@ sub date_parser
sub update_table sub update_table
{ {
my($dbh, $file_name, $values) = @_; my($dbh, $file_name, $values) = @_;
my($q); my($q,$tail,$message);
if (!defined($values->{'subject'}) || !defined($values->{'to'})) if (!defined($values->{'subject'}) || !defined($values->{'to'}))
{ {
$mail_no_subject_f++; $mail_no_subject_f++;
return; # Ignore these return; # Ignore these
} }
$values->{'message'} =~ s/^\s*//; #removes whitespaces from the beginning $message=$values->{'message'};
$values->{'message'} =~ s/\s*$//; #removes whitespaces from the end $message =~ s/^\s*//; #removes whitespaces from the beginning
restart:
$message =~ s/[\s\n>]*$//; #removes whitespaces and '>' from the end
$values->{'message'}=$message;
foreach $tail (@remove_tail)
{
$message =~ s/$tail//;
}
if ($message ne $values->{'message'})
{
$message =~ s/\s*$//; #removes whitespaces from the end
$mail_fixed++;
goto restart; # Some mails may have duplicated messages
}
$q = "INSERT INTO $opt_table ("; $q = "INSERT INTO $opt_table (";
$q.= "mail_id,"; $q.= "mail_id,";
...@@ -320,7 +365,8 @@ sub update_table ...@@ -320,7 +365,8 @@ sub update_table
$q.= "NULL,"; $q.= "NULL,";
$q.= "'" . $values->{'date'} . "',"; $q.= "'" . $values->{'date'} . "',";
$q.= (defined($values->{'time_zone'}) ? $q.= (defined($values->{'time_zone'}) ?
("'" . $values->{'time_zone'} . "',") : "NULL,"); $dbh->quote($values->{'time_zone'}) : "NULL");
$q.= ",";
$q.= defined($values->{'from'}) ? $dbh->quote($values->{'from'}) : "NULL"; $q.= defined($values->{'from'}) ? $dbh->quote($values->{'from'}) : "NULL";
$q.= ","; $q.= ",";
$q.= defined($values->{'reply'}) ? $dbh->quote($values->{'reply'}) : "NULL"; $q.= defined($values->{'reply'}) ? $dbh->quote($values->{'reply'}) : "NULL";
...@@ -331,7 +377,7 @@ sub update_table ...@@ -331,7 +377,7 @@ sub update_table
$q.= ","; $q.= ",";
$q.= $dbh->quote($values->{'subject'}); $q.= $dbh->quote($values->{'subject'});
$q.= ","; $q.= ",";
$q.= $dbh->quote($values->{'message'}); $q.= $dbh->quote($message);
$q.= ","; $q.= ",";
$q.= $dbh->quote($file_name); $q.= $dbh->quote($file_name);
$q.= ","; $q.= ",";
...@@ -339,12 +385,12 @@ sub update_table ...@@ -339,12 +385,12 @@ sub update_table
$q.= ")"; $q.= ")";
# Don't insert mails bigger than $opt_max_mail_size # Don't insert mails bigger than $opt_max_mail_size
if (length($values->{'message'}) > $opt_max_mail_size) if (length($message) > $opt_max_mail_size)
{ {
$mail_too_big++; $mail_too_big++;
} }
# Don't insert mails without 'From' field # Don't insert mails without 'From' field
elsif ($values->{'from'} eq "") elsif (!defined($values->{'from'}) || $values->{'from'} eq "")
{ {
$mail_no_from_f++; $mail_no_from_f++;
} }
...@@ -354,7 +400,7 @@ sub update_table ...@@ -354,7 +400,7 @@ sub update_table
$mail_inserted++; $mail_inserted++;
} }
# Don't insert mails without the 'message' # Don't insert mails without the 'message'
elsif ($values->{'message'} eq "") elsif ($message eq "")
{ {
$mail_no_txt_f++; $mail_no_txt_f++;
} }
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
use DBI; use DBI;
use Getopt::Long; use Getopt::Long;
$VER="1.4a"; $VER="1.5";
@fldnms= ("mail_from","mail_to","cc","date","time_zone","file","sbj","txt"); @fldnms= ("mail_from","mail_to","cc","date","time_zone","file","sbj","txt");
$fields=8; $fields=8;
...@@ -18,7 +18,7 @@ $fields=8; ...@@ -18,7 +18,7 @@ $fields=8;
$opt_user= $opt_password= ""; $opt_user= $opt_password= "";
$opt_socket= "/tmp/mysql.sock"; $opt_socket= "/tmp/mysql.sock";
$opt_port= 3306; $opt_port= 3306;
$opt_db="test"; $opt_db="mail";
$opt_table="mails"; $opt_table="mails";
$opt_help=$opt_count=0; $opt_help=$opt_count=0;
...@@ -61,7 +61,7 @@ foreach $val (@fldnms) ...@@ -61,7 +61,7 @@ foreach $val (@fldnms)
} }
$fields++; $fields++;
} }
$query.= " from $opt_table where $ARGV[0]"; $query.= " from $opt_table where $ARGV[0] order by date desc";
#### ####
#### Send query and save result #### Send query and save result
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment