Commit 2e8cb7c3 authored by guilhem@mysql.com's avatar guilhem@mysql.com

Merge gbichot@213.136.52.20:/home/bk/mysql-4.0

into mysql.com:/home/mysql_src/mysql-4.0
parents 28d3c3d7 8a52c2d2
......@@ -24,6 +24,7 @@ heikki@donna.mysql.fi
heikki@hundin.mysql.fi
heikki@rescue.
heikki@work.mysql.com
hf@deer.(none)
hf@deer.mysql.r18.ru
hf@genie.(none)
igor@hundin.mysql.fi
......
......@@ -640,9 +640,6 @@ typedef long my_ptrdiff_t;
typedef long long my_ptrdiff_t;
#endif
/* typedef used for length of string; Should be unsigned! */
typedef ulong size_str;
#define MY_ALIGN(A,L) (((A) + (L) - 1) & ~((L) - 1))
#define ALIGN_SIZE(A) MY_ALIGN((A),sizeof(double))
/* Size to make adressable obj. */
......@@ -711,6 +708,9 @@ typedef long longlong;
#endif
#endif
/* typedef used for length of string; Should be unsigned! */
typedef ulong size_str;
#ifdef USE_RAID
/*
The following is done with a if to not get problems with pre-processors
......
......@@ -138,7 +138,7 @@ extern int NEAR my_errno; /* Last error in mysys */
#define QUICK_SAFEMALLOC sf_malloc_quick=1
#define NORMAL_SAFEMALLOC sf_malloc_quick=0
extern uint sf_malloc_prehunc,sf_malloc_endhunc,sf_malloc_quick;
extern ulonglong safemalloc_mem_limit;
extern ulonglong sf_malloc_mem_limit;
#define CALLER_INFO_PROTO , const char *sFile, uint uLine
#define CALLER_INFO , __FILE__, __LINE__
......@@ -239,7 +239,7 @@ extern int NEAR my_umask, /* Default creation mask */
NEAR my_safe_to_handle_signal, /* Set when allowed to SIGTSTP */
NEAR my_dont_interrupt; /* call remember_intr when set */
extern my_bool NEAR mysys_uses_curses, my_use_symdir;
extern long lCurMemory,lMaxMemory; /* from safemalloc */
extern ulong sf_malloc_cur_memory, sf_malloc_max_memory;
extern ulong my_default_record_cache_size;
extern my_bool NEAR my_disable_locking,NEAR my_disable_async_io,
......
......@@ -329,6 +329,9 @@ insert into t1 values ('2001-01-12 12:23:40');
select ctime, hour(ctime) from t1;
ctime hour(ctime)
2001-01-12 12:23:40 12
select ctime from t1 where extract(MONTH FROM ctime) = 1 AND extract(YEAR FROM ctime) = 2001;
ctime
2001-01-12 12:23:40
drop table t1;
create table t1 (id int);
create table t2 (id int, date date);
......
......@@ -123,6 +123,8 @@ select extract(MONTH FROM "2001-02-00");
create table t1 (ctime varchar(20));
insert into t1 values ('2001-01-12 12:23:40');
select ctime, hour(ctime) from t1;
# test bug 614 (multiple extracts in where)
select ctime from t1 where extract(MONTH FROM ctime) = 1 AND extract(YEAR FROM ctime) = 2001;
drop table t1;
#
......
......@@ -33,8 +33,6 @@
** --print-defaults ; Print the modified command line and exit
****************************************************************************/
#undef SAFEMALLOC /* safe_malloc is not yet initailized */
#include "mysys_priv.h"
#include "m_string.h"
#include "m_ctype.h"
......
......@@ -609,9 +609,9 @@ static ulonglong getopt_ull(char *arg, const struct my_option *optp, int *err)
ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp)
{
if ((ulonglong) num > (ulonglong) (ulong) optp->max_value &&
if ((ulonglong) num > (ulonglong) optp->max_value &&
optp->max_value) /* if max value is not set -> no upper limit */
num= (ulonglong) (ulong) optp->max_value;
num= (ulonglong) optp->max_value;
if (optp->block_size > 1)
{
num/= (ulonglong) optp->block_size;
......
......@@ -69,14 +69,13 @@ uint sf_malloc_prehunc=0, /* If you have problem with core- */
sf_malloc_endhunc=0, /* dump when malloc-message.... */
/* set theese to 64 or 128 */
sf_malloc_quick=0; /* set if no calls to sanity */
long lCurMemory = 0L; /* Current memory usage */
long lMaxMemory = 0L; /* Maximum memory usage */
uint cNewCount = 0; /* Number of times NEW() was called */
ulong sf_malloc_cur_memory= 0L; /* Current memory usage */
ulong sf_malloc_max_memory= 0L; /* Maximum memory usage */
uint sf_malloc_count= 0; /* Number of times NEW() was called */
byte *sf_min_adress= (byte*) ~(unsigned long) 0L,
*sf_max_adress= (byte*) 0L;
/* Root of the linked list of remembers */
struct remember *pRememberRoot = NULL;
/* Root of the linked list of struct st_irem */
struct st_irem *sf_malloc_root = NULL;
/* from my_alarm */
int volatile my_have_got_alarm=0; /* declare variable to reset */
......
......@@ -33,27 +33,23 @@ struct st_remember {
};
/*
The size of the following structure MUST be dividable by 8 to not cause
alignment problems on some cpu's
Structure that stores information of a allocated memory block
The data is at &struct_adr+sizeof(ALIGN_SIZE(sizeof(struct irem)))
The lspecialvalue is at the previous 4 bytes from this, which may not
necessarily be in the struct if the struct size isn't aligned at a 8 byte
boundary.
*/
struct irem
struct st_irem
{
struct remember *_pNext; /* Linked list of structures */
struct remember *_pPrev; /* Other link */
char *_sFileName; /* File in which memory was new'ed */
uint32 _uLineNum; /* Line number in above file */
uint32 _uDataSize; /* Size requested */
#if SIZEOF_CHARP == 8
long _filler; /* For alignment */
#endif
long _lSpecialValue; /* Underrun marker value */
struct st_irem *next; /* Linked list of structures */
struct st_irem *prev; /* Other link */
char *filename; /* File in which memory was new'ed */
uint32 linenum; /* Line number in above file */
uint32 datasize; /* Size requested */
uint32 SpecialValue; /* Underrun marker value */
};
struct remember {
struct irem tInt;
char aData[1];
};
extern char NEAR curr_dir[FN_REFLEN],NEAR home_dir_buff[FN_REFLEN];
......@@ -70,8 +66,8 @@ extern int _my_tempnam_used;
#endif
extern byte *sf_min_adress,*sf_max_adress;
extern uint cNewCount;
extern struct remember *pRememberRoot;
extern uint sf_malloc_count;
extern struct st_irem *sf_malloc_root;
#if defined(THREAD) && !defined(__WIN__)
extern sigset_t my_signals; /* signals blocked by mf_brkhant */
......
/* Copyright (C) 2000 MySQL AB
/* Copyright (C) 2000-2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -69,22 +69,15 @@
#include "my_static.h"
#include "mysys_err.h"
ulonglong safemalloc_mem_limit = ~(ulonglong)0;
#define pNext tInt._pNext
#define pPrev tInt._pPrev
#define sFileName tInt._sFileName
#define uLineNum tInt._uLineNum
#define uDataSize tInt._uDataSize
#define lSpecialValue tInt._lSpecialValue
ulonglong sf_malloc_mem_limit= ~(ulonglong)0;
#ifndef PEDANTIC_SAFEMALLOC
/*
Set to 1 after TERMINATE() if we had to fiddle with cNewCount and
Set to 1 after TERMINATE() if we had to fiddle with sf_malloc_count and
the linked list of blocks so that _sanity() will not fuss when it
is not supposed to
*/
static int sf_malloc_tampered = 0;
static int sf_malloc_tampered= 0;
#endif
......@@ -92,11 +85,11 @@ static int sf_malloc_tampered = 0;
static int check_ptr(const char *where, byte *ptr, const char *sFile,
uint uLine);
static int _checkchunk(struct remember *pRec, const char *sFile, uint uLine);
static int _checkchunk(struct st_irem *pRec, const char *sFile, uint uLine);
/*
Note: both these refer to the NEW'ed data only. They do not include
malloc() roundoff or the extra space required by the remember
Note: We only fill up the allocated block. This do not include
malloc() roundoff or the extra space required by the irem
structures.
*/
......@@ -127,218 +120,211 @@ static int _checkchunk(struct remember *pRec, const char *sFile, uint uLine);
/* Allocate some memory. */
gptr _mymalloc (uint uSize, const char *sFile, uint uLine, myf MyFlags)
gptr _mymalloc(uint size, const char *filename, uint lineno, myf MyFlags)
{
struct remember *pTmp;
DBUG_ENTER("_mymalloc");
DBUG_PRINT("enter",("Size: %u",uSize));
struct st_irem *irem;
char *data;
DBUG_ENTER("_mymalloc");
DBUG_PRINT("enter",("Size: %u",size));
if (!sf_malloc_quick)
(void) _sanity (sFile, uLine);
if (!sf_malloc_quick)
(void) _sanity (filename, lineno);
if (uSize + lCurMemory > safemalloc_mem_limit)
pTmp = 0;
else
{
/* Allocate the physical memory */
pTmp = (struct remember *) malloc (
ALIGN_SIZE(sizeof(struct irem)) /* remember data */
+ sf_malloc_prehunc
+ uSize /* size requested */
+ 4 /* overrun mark */
+ sf_malloc_endhunc
);
}
/* Check if there isn't anymore memory avaiable */
if (pTmp == NULL)
if (size + sf_malloc_cur_memory > sf_malloc_mem_limit)
irem= 0;
else
{
/* Allocate the physical memory */
irem= (struct st_irem *) malloc (ALIGN_SIZE(sizeof(struct st_irem)) +
sf_malloc_prehunc +
size + /* size requested */
4 + /* overrun mark */
sf_malloc_endhunc);
}
/* Check if there isn't anymore memory avaiable */
if (!irem)
{
if (MyFlags & MY_FAE)
error_handler_hook=fatal_error_handler_hook;
if (MyFlags & (MY_FAE+MY_WME))
{
if (MyFlags & MY_FAE)
error_handler_hook=fatal_error_handler_hook;
if (MyFlags & (MY_FAE+MY_WME))
{
char buff[SC_MAXWIDTH];
my_errno=errno;
sprintf(buff,"Out of memory at line %d, '%s'", uLine, sFile);
my_message(EE_OUTOFMEMORY,buff,MYF(ME_BELL+ME_WAITTANG));
sprintf(buff,"needed %d byte (%ldk), memory in use: %ld bytes (%ldk)",
uSize, (uSize + 1023L) / 1024L,
lMaxMemory, (lMaxMemory + 1023L) / 1024L);
my_message(EE_OUTOFMEMORY,buff,MYF(ME_BELL+ME_WAITTANG));
}
DBUG_PRINT("error",("Out of memory, in use: %ld at line %d, '%s'",
lMaxMemory,uLine, sFile));
if (MyFlags & MY_FAE)
exit(1);
DBUG_RETURN ((gptr) NULL);
char buff[SC_MAXWIDTH];
my_errno=errno;
sprintf(buff,"Out of memory at line %d, '%s'", lineno, filename);
my_message(EE_OUTOFMEMORY,buff,MYF(ME_BELL+ME_WAITTANG));
sprintf(buff,"needed %d byte (%ldk), memory in use: %ld bytes (%ldk)",
size, (size + 1023L) / 1024L,
sf_malloc_max_memory, (sf_malloc_max_memory + 1023L) / 1024L);
my_message(EE_OUTOFMEMORY,buff,MYF(ME_BELL+ME_WAITTANG));
}
DBUG_PRINT("error",("Out of memory, in use: %ld at line %d, '%s'",
sf_malloc_max_memory,lineno, filename));
if (MyFlags & MY_FAE)
exit(1);
DBUG_RETURN ((gptr) 0);
}
/* Fill up the structure */
*((long*) ((char*) &pTmp -> lSpecialValue+sf_malloc_prehunc)) = MAGICKEY;
pTmp -> aData[uSize + sf_malloc_prehunc+0] = MAGICEND0;
pTmp -> aData[uSize + sf_malloc_prehunc+1] = MAGICEND1;
pTmp -> aData[uSize + sf_malloc_prehunc+2] = MAGICEND2;
pTmp -> aData[uSize + sf_malloc_prehunc+3] = MAGICEND3;
pTmp -> sFileName = (my_string) sFile;
pTmp -> uLineNum = uLine;
pTmp -> uDataSize = uSize;
pTmp -> pPrev = NULL;
/* Add this remember structure to the linked list */
pthread_mutex_lock(&THR_LOCK_malloc);
if ((pTmp->pNext=pRememberRoot))
{
pRememberRoot -> pPrev = pTmp;
}
pRememberRoot = pTmp;
/* Fill up the structure */
data= (((char*) irem) + ALIGN_SIZE(sizeof(struct st_irem)) +
sf_malloc_prehunc);
*((uint32*) (data-sizeof(uint32)))= MAGICKEY;
data[size + 0]= MAGICEND0;
data[size + 1]= MAGICEND1;
data[size + 2]= MAGICEND2;
data[size + 3]= MAGICEND3;
irem->filename= (my_string) filename;
irem->linenum= lineno;
irem->datasize= size;
irem->prev= NULL;
/* Add this remember structure to the linked list */
pthread_mutex_lock(&THR_LOCK_malloc);
if ((irem->next= sf_malloc_root))
sf_malloc_root->prev= irem;
sf_malloc_root= irem;
/* Keep the statistics */
sf_malloc_cur_memory+= size;
if (sf_malloc_cur_memory > sf_malloc_max_memory)
sf_malloc_max_memory= sf_malloc_cur_memory;
sf_malloc_count++;
pthread_mutex_unlock(&THR_LOCK_malloc);
/* Keep the statistics */
lCurMemory += uSize;
if (lCurMemory > lMaxMemory) {
lMaxMemory = lCurMemory;
}
cNewCount++;
pthread_mutex_unlock(&THR_LOCK_malloc);
/* Set the memory to the aribtrary wierd value */
if ((MyFlags & MY_ZEROFILL) || !sf_malloc_quick)
bfill(&pTmp -> aData[sf_malloc_prehunc],uSize,
(char) (MyFlags & MY_ZEROFILL ? 0 : ALLOC_VAL));
/* Return a pointer to the real data */
DBUG_PRINT("exit",("ptr: %lx",&(pTmp -> aData[sf_malloc_prehunc])));
if (sf_min_adress > &(pTmp -> aData[sf_malloc_prehunc]))
sf_min_adress = &(pTmp -> aData[sf_malloc_prehunc]);
if (sf_max_adress < &(pTmp -> aData[sf_malloc_prehunc]))
sf_max_adress = &(pTmp -> aData[sf_malloc_prehunc]);
DBUG_RETURN ((gptr) &(pTmp -> aData[sf_malloc_prehunc]));
/* Set the memory to the aribtrary wierd value */
if ((MyFlags & MY_ZEROFILL) || !sf_malloc_quick)
bfill(data, size, (char) (MyFlags & MY_ZEROFILL ? 0 : ALLOC_VAL));
/* Return a pointer to the real data */
DBUG_PRINT("exit",("ptr: %lx", data));
if (sf_min_adress > data)
sf_min_adress= data;
if (sf_max_adress < data)
sf_max_adress= data;
DBUG_RETURN ((gptr) data);
}
/*
Allocate some new memory and move old memoryblock there.
Free then old memoryblock
*/
gptr _myrealloc (register gptr pPtr, register uint uSize,
const char *sFile, uint uLine, myf MyFlags)
gptr _myrealloc(register gptr ptr, register uint size,
const char *filename, uint lineno, myf MyFlags)
{
struct remember *pRec;
gptr ptr;
struct st_irem *irem;
char *data;
DBUG_ENTER("_myrealloc");
if (!pPtr && (MyFlags & MY_ALLOW_ZERO_PTR))
DBUG_RETURN(_mymalloc(uSize,sFile,uLine,MyFlags));
if (!ptr && (MyFlags & MY_ALLOW_ZERO_PTR))
DBUG_RETURN(_mymalloc(size, filename, lineno, MyFlags));
if (!sf_malloc_quick)
(void) _sanity (sFile, uLine);
(void) _sanity (filename, lineno);
if (check_ptr("Reallocating",(byte*) pPtr,sFile,uLine))
if (check_ptr("Reallocating", (byte*) ptr, filename, lineno))
DBUG_RETURN((gptr) NULL);
pRec = (struct remember *) ((char*) pPtr - ALIGN_SIZE(sizeof(struct irem))-
sf_malloc_prehunc);
if (*((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc))
!= MAGICKEY)
irem= (struct st_irem *) (((char*) ptr) - ALIGN_SIZE(sizeof(struct st_irem))-
sf_malloc_prehunc);
if (*((uint32*) (((char*) ptr)- sizeof(uint32))) != MAGICKEY)
{
fprintf(stderr, "Error: Reallocating unallocated data at line %d, '%s'\n",
uLine, sFile);
lineno, filename);
DBUG_PRINT("safe",("Reallocating unallocated data at line %d, '%s'",
uLine, sFile));
lineno, filename));
(void) fflush(stderr);
DBUG_RETURN((gptr) NULL);
}
if ((ptr=_mymalloc(uSize,sFile,uLine,MyFlags))) /* Allocate new area */
if ((data= _mymalloc(size,filename,lineno,MyFlags))) /* Allocate new area */
{
uSize=min(uSize,pRec-> uDataSize); /* Move as much as possibly */
memcpy((byte*) ptr,pPtr,(size_t) uSize); /* Copy old data */
_myfree(pPtr,sFile,uLine,0); /* Free not needed area */
size=min(size, irem->datasize); /* Move as much as possibly */
memcpy((byte*) data, ptr, (size_t) size); /* Copy old data */
_myfree(ptr, filename, lineno, 0); /* Free not needed area */
}
else
{
if (MyFlags & MY_HOLD_ON_ERROR)
DBUG_RETURN(pPtr);
DBUG_RETURN(ptr);
if (MyFlags & MY_FREE_ON_ERROR)
_myfree(pPtr,sFile,uLine,0);
_myfree(ptr, filename, lineno, 0);
}
DBUG_RETURN(ptr);
DBUG_RETURN(data);
} /* _myrealloc */
/* Deallocate some memory. */
void _myfree (gptr pPtr, const char *sFile, uint uLine, myf myflags)
void _myfree(gptr ptr, const char *filename, uint lineno, myf myflags)
{
struct remember *pRec;
struct st_irem *irem;
DBUG_ENTER("_myfree");
DBUG_PRINT("enter",("ptr: %lx",pPtr));
DBUG_PRINT("enter",("ptr: %lx", ptr));
if (!sf_malloc_quick)
(void) _sanity (sFile, uLine);
(void) _sanity (filename, lineno);
if ((!pPtr && (myflags & MY_ALLOW_ZERO_PTR)) ||
check_ptr("Freeing",(byte*) pPtr,sFile,uLine))
if ((!ptr && (myflags & MY_ALLOW_ZERO_PTR)) ||
check_ptr("Freeing",(byte*) ptr,filename,lineno))
DBUG_VOID_RETURN;
/* Calculate the address of the remember structure */
pRec = (struct remember *) ((byte*) pPtr- ALIGN_SIZE(sizeof(struct irem))-
sf_malloc_prehunc);
irem= (struct st_irem *) ((char*) ptr- ALIGN_SIZE(sizeof(struct st_irem))-
sf_malloc_prehunc);
/*
Check to make sure that we have a real remember structure.
Note: this test could fail for four reasons:
(1) The memory was already free'ed
(2) The memory was never new'ed
(3) There was an underrun
(4) A stray pointer hit this location
(1) The memory was already free'ed
(2) The memory was never new'ed
(3) There was an underrun
(4) A stray pointer hit this location
*/
if (*((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc))
!= MAGICKEY)
if (*((uint32*) ((char*) ptr- sizeof(uint32))) != MAGICKEY)
{
fprintf(stderr, "Error: Freeing unallocated data at line %d, '%s'\n",
uLine, sFile);
DBUG_PRINT("safe",("Unallocated data at line %d, '%s'",uLine,sFile));
lineno, filename);
DBUG_PRINT("safe",("Unallocated data at line %d, '%s'",lineno,filename));
(void) fflush(stderr);
DBUG_VOID_RETURN;
}
/* Remove this structure from the linked list */
pthread_mutex_lock(&THR_LOCK_malloc);
if (pRec -> pPrev) {
pRec -> pPrev -> pNext = pRec -> pNext;
} else {
pRememberRoot = pRec -> pNext;
}
if (pRec -> pNext) {
pRec -> pNext -> pPrev = pRec -> pPrev;
}
if (irem->prev)
irem->prev->next= irem->next;
else
sf_malloc_root= irem->next;
if (irem->next)
irem->next->prev= irem->prev;
/* Handle the statistics */
lCurMemory -= pRec -> uDataSize;
cNewCount--;
sf_malloc_cur_memory-= irem->datasize;
sf_malloc_count--;
pthread_mutex_unlock(&THR_LOCK_malloc);
#ifndef HAVE_purify
/* Mark this data as free'ed */
if (!sf_malloc_quick)
bfill(&pRec->aData[sf_malloc_prehunc],pRec->uDataSize,(pchar) FREE_VAL);
bfill(ptr, irem->datasize, (pchar) FREE_VAL);
#endif
*((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc)) = ~MAGICKEY;
*((uint32*) ((char*) ptr- sizeof(uint32)))= ~MAGICKEY;
/* Actually free the memory */
free ((my_string ) pRec);
free((char*) irem);
DBUG_VOID_RETURN;
}
/* Check if we have a wrong pointer */
static int check_ptr(const char *where, byte *ptr, const char *sFile,
uint uLine)
static int check_ptr(const char *where, byte *ptr, const char *filename,
uint lineno)
{
if (!ptr)
{
fprintf(stderr, "Error: %s NULL pointer at line %d, '%s'\n",
where,uLine, sFile);
DBUG_PRINT("safe",("Null pointer at line %d '%s'", uLine, sFile));
where,lineno, filename);
DBUG_PRINT("safe",("Null pointer at line %d '%s'", lineno, filename));
(void) fflush(stderr);
return 1;
}
......@@ -346,9 +332,9 @@ static int check_ptr(const char *where, byte *ptr, const char *sFile,
if ((long) ptr & (ALIGN_SIZE(1)-1))
{
fprintf(stderr, "Error: %s wrong aligned pointer at line %d, '%s'\n",
where,uLine, sFile);
where,lineno, filename);
DBUG_PRINT("safe",("Wrong aligned pointer at line %d, '%s'",
uLine,sFile));
lineno,filename));
(void) fflush(stderr);
return 1;
}
......@@ -356,9 +342,9 @@ static int check_ptr(const char *where, byte *ptr, const char *sFile,
if (ptr < sf_min_adress || ptr > sf_max_adress)
{
fprintf(stderr, "Error: %s pointer out of range at line %d, '%s'\n",
where,uLine, sFile);
where,lineno, filename);
DBUG_PRINT("safe",("Pointer out of range at line %d '%s'",
uLine,sFile));
lineno,filename));
(void) fflush(stderr);
return 1;
}
......@@ -372,9 +358,9 @@ static int check_ptr(const char *where, byte *ptr, const char *sFile,
free'ed as well as the statistics.
*/
void TERMINATE (FILE *file)
void TERMINATE(FILE *file)
{
struct remember *pPtr;
struct st_irem *irem;
DBUG_ENTER("TERMINATE");
pthread_mutex_lock(&THR_LOCK_malloc);
......@@ -384,14 +370,15 @@ void TERMINATE (FILE *file)
NEWs than FREEs. <0, etc.
*/
if (cNewCount)
if (sf_malloc_count)
{
if (file)
{
fprintf(file, "Warning: Not freed memory segments: %d\n", cNewCount);
fprintf(file, "Warning: Not freed memory segments: %d\n",
sf_malloc_count);
(void) fflush(file);
}
DBUG_PRINT("safe",("cNewCount: %d",cNewCount));
DBUG_PRINT("safe",("sf_malloc_count: %d", sf_malloc_count));
}
/*
......@@ -399,42 +386,44 @@ void TERMINATE (FILE *file)
but not free'ed with FREE.
*/
if ((pPtr=pRememberRoot))
if ((irem= sf_malloc_root))
{
if (file)
{
fprintf(file, "Warning: Memory that was not free'ed (%ld bytes):\n",lCurMemory);
fprintf(file, "Warning: Memory that was not free'ed (%ld bytes):\n",
sf_malloc_cur_memory);
(void) fflush(file);
}
DBUG_PRINT("safe",("Memory that was not free'ed (%ld bytes):",lCurMemory));
while (pPtr)
DBUG_PRINT("safe",("Memory that was not free'ed (%ld bytes):",
sf_malloc_cur_memory));
while (irem)
{
char *data= (((char*) irem) + ALIGN_SIZE(sizeof(struct st_irem)) +
sf_malloc_prehunc);
if (file)
{
fprintf(file,
"\t%6u bytes at 0x%09lx, allocated at line %4u in '%s'",
pPtr -> uDataSize,
(ulong) &(pPtr -> aData[sf_malloc_prehunc]),
pPtr -> uLineNum, pPtr -> sFileName);
irem->datasize, (long) data, irem->linenum, irem->filename);
fprintf(file, "\n");
(void) fflush(file);
}
DBUG_PRINT("safe",
("%6u bytes at 0x%09lx, allocated at line %4d in '%s'",
pPtr -> uDataSize, &(pPtr -> aData[sf_malloc_prehunc]),
pPtr -> uLineNum, pPtr -> sFileName));
pPtr = pPtr -> pNext;
irem->datasize, data, irem->linenum, irem->filename));
irem= irem->next;
}
}
/* Report the memory usage statistics */
if (file)
{
fprintf(file, "Maximum memory usage: %ld bytes (%ldk)\n",
lMaxMemory, (lMaxMemory + 1023L) / 1024L);
sf_malloc_max_memory, (sf_malloc_max_memory + 1023L) / 1024L);
(void) fflush(file);
}
DBUG_PRINT("safe",("Maximum memory usage: %ld bytes (%ldk)",
lMaxMemory, (lMaxMemory + 1023L) / 1024L));
sf_malloc_max_memory, (sf_malloc_max_memory + 1023L) /
1024L));
pthread_mutex_unlock(&THR_LOCK_malloc);
DBUG_VOID_RETURN;
}
......@@ -442,44 +431,41 @@ void TERMINATE (FILE *file)
/* Returns 0 if chunk is ok */
static int _checkchunk (register struct remember *pRec, const char *sFile,
uint uLine)
static int _checkchunk(register struct st_irem *irem, const char *filename,
uint lineno)
{
reg1 uint uSize;
reg2 my_string magicp;
reg3 int flag=0;
int flag=0;
char *magicp, *data;
data= (((char*) irem) + ALIGN_SIZE(sizeof(struct st_irem)) +
sf_malloc_prehunc);
/* Check for a possible underrun */
if (*((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc))
!= MAGICKEY)
if (*((uint32*) (data- sizeof(uint32))) != MAGICKEY)
{
fprintf(stderr, "Error: Memory allocated at %s:%d was underrun,",
pRec -> sFileName, pRec -> uLineNum);
fprintf(stderr, " discovered at %s:%d\n", sFile, uLine);
irem->filename, irem->linenum);
fprintf(stderr, " discovered at %s:%d\n", filename, lineno);
(void) fflush(stderr);
DBUG_PRINT("safe",("Underrun at %lx, allocated at %s:%d",
&(pRec -> aData[sf_malloc_prehunc]),
pRec -> sFileName,
pRec -> uLineNum));
data, irem->filename, irem->linenum));
flag=1;
}
/* Check for a possible overrun */
uSize = pRec -> uDataSize;
magicp = &(pRec -> aData[uSize+sf_malloc_prehunc]);
magicp= data + irem->datasize;
if (*magicp++ != MAGICEND0 ||
*magicp++ != MAGICEND1 ||
*magicp++ != MAGICEND2 ||
*magicp++ != MAGICEND3)
{
fprintf(stderr, "Error: Memory allocated at %s:%d was overrun,",
pRec -> sFileName, pRec -> uLineNum);
fprintf(stderr, " discovered at '%s:%d'\n", sFile, uLine);
irem->filename, irem->linenum);
fprintf(stderr, " discovered at '%s:%d'\n", filename, lineno);
(void) fflush(stderr);
DBUG_PRINT("safe",("Overrun at %lx, allocated at %s:%d",
&(pRec -> aData[sf_malloc_prehunc]),
pRec -> sFileName,
pRec -> uLineNum));
data,
irem->filename,
irem->linenum));
flag=1;
}
return(flag);
......@@ -488,28 +474,28 @@ static int _checkchunk (register struct remember *pRec, const char *sFile,
/* Returns how many wrong chunks */
int _sanity (const char *sFile, uint uLine)
int _sanity(const char *filename, uint lineno)
{
reg1 struct remember *pTmp;
reg1 struct st_irem *irem;
reg2 int flag=0;
uint count=0;
pthread_mutex_lock(&THR_LOCK_malloc);
#ifndef PEDANTIC_SAFEMALLOC
if (sf_malloc_tampered && cNewCount < 0)
cNewCount=0;
if (sf_malloc_tampered && sf_malloc_count < 0)
sf_malloc_count=0;
#endif
count=cNewCount;
for (pTmp = pRememberRoot; pTmp != NULL && count-- ; pTmp = pTmp -> pNext)
flag+=_checkchunk (pTmp, sFile, uLine);
count=sf_malloc_count;
for (irem= sf_malloc_root; irem != NULL && count-- ; irem= irem->next)
flag+= _checkchunk (irem, filename, lineno);
pthread_mutex_unlock(&THR_LOCK_malloc);
if (count || pTmp)
if (count || irem)
{
const char *format="Error: Safemalloc link list destroyed, discovered at '%s:%d'";
fprintf(stderr, format, sFile, uLine); fputc('\n',stderr);
fprintf(stderr, "root=%p,count=%d,pTmp=%p\n", pRememberRoot,count,pTmp);
fprintf(stderr, format, filename, lineno); fputc('\n',stderr);
fprintf(stderr, "root=%p,count=%d,irem=%p\n", sf_malloc_root,count,irem);
(void) fflush(stderr);
DBUG_PRINT("safe",(format, sFile, uLine));
DBUG_PRINT("safe",(format, filename, lineno));
flag=1;
}
return flag;
......@@ -518,33 +504,33 @@ int _sanity (const char *sFile, uint uLine)
/* malloc and copy */
gptr _my_memdup(const byte *from, uint length, const char *sFile, uint uLine,
myf MyFlags)
gptr _my_memdup(const byte *from, uint length, const char *filename,
uint lineno, myf MyFlags)
{
gptr ptr;
if ((ptr=_mymalloc(length,sFile,uLine,MyFlags)) != 0)
if ((ptr=_mymalloc(length,filename,lineno,MyFlags)) != 0)
memcpy((byte*) ptr, (byte*) from,(size_t) length);
return(ptr);
} /*_my_memdup */
char *_my_strdup(const char *from, const char *sFile, uint uLine,
char *_my_strdup(const char *from, const char *filename, uint lineno,
myf MyFlags)
{
gptr ptr;
uint length=(uint) strlen(from)+1;
if ((ptr=_mymalloc(length,sFile,uLine,MyFlags)) != 0)
if ((ptr=_mymalloc(length,filename,lineno,MyFlags)) != 0)
memcpy((byte*) ptr, (byte*) from,(size_t) length);
return((char*) ptr);
} /* _my_strdup */
char *_my_strdup_with_length(const byte *from, uint length,
const char *sFile, uint uLine,
const char *filename, uint lineno,
myf MyFlags)
{
gptr ptr;
if ((ptr=_mymalloc(length+1,sFile,uLine,MyFlags)) != 0)
if ((ptr=_mymalloc(length+1,filename,lineno,MyFlags)) != 0)
{
memcpy((byte*) ptr, (byte*) from,(size_t) length);
ptr[length]=0;
......
......@@ -14,12 +14,14 @@ $Param->{host}='';
$Param->{user}='';
$Param->{password}='';
$Param->{PrintError}=0;
$Param->{socket}='';
if (!GetOptions ('date|d:i' => \$Param->{ViewDate},
'host|h:s' => \$Param->{host},
'user|u:s' => \$Param->{user},
'password|p:s' => \$Param->{password},
'printerror|e:s' => \$Param->{PrintError},
'socket|s:s' => \$Param->{socket},
)) {
ShowOptions();
}
......@@ -50,7 +52,7 @@ else {
#print "Date=$Param->{ViewDate}, host=$Param->{host}, user=$Param->{user}, password=$Param->{password}\n";
$Param->{dbh}=DBI->connect("DBI:mysql:host=$Param->{host}",$Param->{user},$Param->{password},{PrintError=>0});
$Param->{dbh}=DBI->connect("DBI:mysql:host=$Param->{host}".($Param->{socket}?";mysql_socket=$Param->{socket}":""),$Param->{user},$Param->{password},{PrintError=>0});
if (DBI::err()) {
print "Error: " . DBI::errstr() . "\n";
}
......@@ -313,6 +315,8 @@ Usage: $0 [OPTIONS] < LOGFILE
-u=USERNAME
--password=PASSWORD password of db-user
-p=PASSWORD
--socket=SOCKET mysqld socket file to connect
-s=SOCKET
Read logfile from STDIN an try to EXPLAIN all SELECT statements. All UPDATE statements are rewritten to an EXPLAIN SELECT statement. The results of the EXPLAIN statement are collected and counted. All results with type=ALL are collected in an separete list. Results are printed to STDOUT.
......@@ -344,7 +348,7 @@ Then add indices to avoid table scans and remove those which aren't used.
=head1 USAGE
explain_log.pl [--date=YYMMDD] --host=dbhost] [--user=dbuser] [--password=dbpw] < logfile
explain_log.pl [--date=YYMMDD] --host=dbhost] [--user=dbuser] [--password=dbpw] [--socket=/path/to/socket] < logfile
--date=YYMMDD select only entrys of date
......@@ -362,14 +366,19 @@ explain_log.pl [--date=YYMMDD] --host=dbhost] [--user=dbuser] [--password=dbpw]
-p=PASSWORD
--socket=SOCKET change path to the socket
-s=SOCKET
=head1 EXAMPLE
explain_log.pl --host=localhost --user=foo --password=bar < /var/lib/mysql/mobile.log
=head1 AUTHOR
=head1 AUTHORS
Stefan Nitz
Jan Willamowius <jan@mobile.de>, http://www.mobile.de
Dennis Haney <davh@davh.dk> (Added socket support)
=head1 RECRUITING
......
......@@ -10,6 +10,8 @@
# mysql.server works by first doing a cd to the base directory and from there
# executing mysqld_safe
KILL_MYSQLD=1;
trap '' 1 2 3 15 # we shouldn't let anyone kill us
umask 007
......@@ -34,6 +36,9 @@ parse_arguments() {
for arg do
case "$arg" in
--skip-kill-mysqld*)
KILL_MYSQLD=0;
;;
# these get passed explicitly to mysqld
--basedir=*) MY_BASEDIR_VERSION=`echo "$arg" | sed -e "s;--basedir=;;"` ;;
--datadir=*) DATADIR=`echo "$arg" | sed -e "s;--datadir=;;"` ;;
......@@ -70,6 +75,7 @@ parse_arguments() {
MYSQLD="mysqld"
fi
;;
--nice=*) niceness=`echo "$arg" | sed -e "s;--nice=;;"` ;;
*)
if test -n "$pick_args"
then
......@@ -82,6 +88,7 @@ parse_arguments() {
done
}
MY_PWD=`pwd`
# Check if we are starting this relative (for the binary release)
if test -d $MY_PWD/data/mysql -a -f ./share/mysql/english/errmsg.sys -a \
......@@ -110,6 +117,7 @@ fi
MYSQL_UNIX_PORT=${MYSQL_UNIX_PORT:-@MYSQL_UNIX_ADDR@}
MYSQL_TCP_PORT=${MYSQL_TCP_PORT:-@MYSQL_TCP_PORT@}
user=@MYSQLD_USER@
niceness=0
# Use the mysqld-max binary by default if the user doesn't specify a binary
if test -x $ledir/mysqld-max
......@@ -167,7 +175,12 @@ export MYSQL_UNIX_PORT
export MYSQL_TCP_PORT
NOHUP_NICENESS="nohup"
if test $niceness -eq 0
then
NOHUP_NICENESS="nohup"
else
NOHUP_NICENESS="nohup nice -$niceness"
fi
# Using nice with no args to get the niceness level is GNU-specific.
# This check could be extended for other operating systems (e.g.,
......@@ -198,8 +211,10 @@ then
nice --$nice_value_diff echo testing > /dev/null 2>&1
then
# nohup increases the priority (bad), and we are permitted
# to lower the priority
NOHUP_NICENESS="nice --$nice_value_diff nohup"
# to lower the priority with respect to the value the user
# might have been given
niceness=`expr $niceness - $nice_value_diff`
NOHUP_NICENESS="nice -$niceness nohup"
fi
fi
else
......@@ -289,7 +304,7 @@ do
break
fi
if @IS_LINUX@
if test @IS_LINUX@ -a $KILL_MYSQLD -eq 1
then
# Test if one process was hanging.
# This is only a fix for Linux (running as base 3 mysqld processes)
......
......@@ -1137,6 +1137,22 @@ longlong Item_extract::val_int()
return 0; // Impossible
}
bool Item_extract::eq(const Item *item, bool binary_cmp) const
{
if (this == item)
return 1;
if (item->type() != FUNC_ITEM ||
func_name() != ((Item_func*)item)->func_name())
return 0;
Item_extract* ie= (Item_extract*)item;
if (ie->int_type != int_type)
return 0;
if (!args[0]->eq(ie->args[0], binary_cmp))
return 0;
return 1;
}
void Item_typecast::print(String *str)
{
......
......@@ -422,6 +422,7 @@ class Item_extract :public Item_int_func
longlong val_int();
const char *func_name() const { return "extract"; }
void fix_length_and_dec();
bool eq(const Item *item, bool binary_cmp) const;
unsigned int size_of() { return sizeof(*this);}
};
......
......@@ -4292,7 +4292,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
break;
case OPT_SAFEMALLOC_MEM_LIMIT:
#if !defined(DBUG_OFF) && defined(SAFEMALLOC)
safemalloc_mem_limit = atoi(argument);
sf_malloc_mem_limit = atoi(argument);
#endif
break;
#ifdef EMBEDDED_LIBRARY
......
......@@ -1208,9 +1208,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
opened_tables,refresh_version, cached_tables(),
uptime ? (float)thd->query_id/(float)uptime : 0);
#ifdef SAFEMALLOC
if (lCurMemory) // Using SAFEMALLOC
if (sf_malloc_cur_memory) // Using SAFEMALLOC
sprintf(strend(buff), " Memory in use: %ldK Max memory used: %ldK",
(lCurMemory+1023L)/1024L,(lMaxMemory+1023L)/1024L);
(sf_malloc_cur_memory+1023L)/1024L,
(sf_malloc_max_memory+1023L)/1024L);
#endif
VOID(my_net_write(net, buff,(uint) strlen(buff)));
VOID(net_flush(net));
......@@ -2476,8 +2477,10 @@ mysql_execute_command(void)
res = mysql_ha_close(thd, tables);
break;
case SQLCOM_HA_READ:
if (check_db_used(thd,tables) ||
check_table_access(thd,SELECT_ACL, tables))
/* there is no need to check for table permissions here, because
if a user has no permissions to read a table, he won't be
able to open it (with SQLCOM_HA_OPEN) in the first place. */
if (check_db_used(thd,tables))
goto error;
res = mysql_ha_read(thd, tables, lex->ha_read_mode, lex->backup_dir,
lex->insert_list, lex->ha_rkey_mode, select_lex->where,
......
......@@ -327,7 +327,7 @@ install -m755 $MBD/support-files/mysql.server $RBR/etc/init.d/mysql
# Create a symlink "rcmysql", pointing to the init.script. SuSE users
# will appreciate that, as all services usually offer this.
ln -s ../../sbin/init.d/mysql $RPM_BUILD_ROOT/usr/sbin/rcmysql
ln -s ../../etc/init.d/mysql $RPM_BUILD_ROOT/usr/sbin/rcmysql
# Create symbolic compatibility link safe_mysqld -> mysqld_safe
# (safe_mysqld will be gone in MySQL 4.1)
......
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