Query cache.

Remove some warnings
This commit is contained in:
monty@hundin.mysql.fi 2001-12-02 14:34:01 +02:00
parent 8a8617075a
commit 1d26537da5
51 changed files with 3377 additions and 306 deletions

View File

@ -8528,6 +8528,14 @@ libc internal error: _rmutex_unlock: rmutex not held
Add @code{-mt} to @code{CFLAGS} and @code{CXXFLAGS} and try again.
If you are using the SFW version of gcc (which comes with Solaris 8),
you must add @file{/opt/sfw/lib} to the environment variable
@code{LD_LIBRARY_PATH} before running configure.
If you are using the gcc available from @code{sunfreeware.com}, you may
have many problems. You should recompile gcc and GNU binutils on the
machine you will be running them from to avoid any problems.
If you get the following error when compiling MySQL with @code{gcc},
it means that your @code{gcc} is not configured for your version of Solaris:

View File

@ -49,7 +49,7 @@ extern const char *ft_precompiled_stopwords[];
extern ulong ft_min_word_len;
extern ulong ft_max_word_len;
extern ulong ft_max_word_len_for_sort;
extern char *ft_boolean_syntax;
extern const char *ft_boolean_syntax;
int ft_init_stopwords(const char **);
void ft_free_stopwords(void);

View File

@ -191,6 +191,8 @@ typedef struct st_columndef /* column information */
#endif
} MI_COLUMNDEF;
/* invalidator function reference for Query Cache */
typedef void (* invalidator_by_filename) (char * filename);
extern my_string myisam_log_filename; /* Name of logfile */
extern uint myisam_block_size;

View File

@ -95,6 +95,7 @@ extern int myrg_lock_database(MYRG_INFO *file,int lock_type);
extern int myrg_create(const char *name, const char **table_names,
uint insert_method, my_bool fix_names);
extern int myrg_extra(MYRG_INFO *file,enum ha_extra_function function);
extern void myrg_extrafunc(MYRG_INFO *info,invalidator_by_filename inv);
extern ha_rows myrg_records_in_range(MYRG_INFO *info,int inx,
const byte *start_key,uint start_key_len,
enum ha_rkey_function start_search_flag,

View File

@ -78,6 +78,9 @@ enum enum_server_command {COM_SLEEP,COM_QUIT,COM_INIT_DB,COM_QUERY,
#define REFRESH_READ_LOCK 16384 /* Lock tables for read */
#define REFRESH_FAST 32768 /* Intern flag */
#define REFRESH_QUERY_CACHE 65536 /* flush query cache */
#define REFRESH_QUERY_CACHE_FREE 0x10000L /* pack query cache */
#define CLIENT_LONG_PASSWORD 1 /* new more secure passwords */
#define CLIENT_FOUND_ROWS 2 /* Found instead of affected rows */
#define CLIENT_LONG_FLAG 4 /* Get all column flags */
@ -126,6 +129,7 @@ typedef struct st_net {
unsigned char reading_or_writing;
char save_char;
my_bool no_send_ok;
gptr query_cache_query;
} NET;
#define packet_error (~(unsigned long) 0)

View File

@ -460,7 +460,7 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups)
umask(((~my_umask) & 0666));
table_cache_init();
hostname_cache_init();
sql_cache_init();
/*sql_cache_init();*/
randominit(&sql_rand,(ulong) start_time,(ulong) start_time/2);
reset_floating_point_exceptions();
init_thr_lock();

View File

@ -86,7 +86,7 @@ typedef struct st_ft_info {
MEM_ROOT mem_root;
} FTB;
int FTB_WORD_cmp(void *v, byte *a, byte *b)
int FTB_WORD_cmp(void *v __attribute__((unused)), byte *a, byte *b)
{
/* ORDER BY docid, ndepth DESC */
int i=CMP_NUM(((FTB_WORD *)a)->docid, ((FTB_WORD *)b)->docid);
@ -109,7 +109,7 @@ void _ftb_parse_query(FTB *ftb, byte **start, byte *end,
return;
param.prev=' ';
while (res=ft_get_word(start,end,&w,&param))
while ((res=ft_get_word(start,end,&w,&param)))
{
byte r=param.plusminus;
float weight=(param.pmsign ? nwghts : wghts)[(r>5)?5:((r<-5)?-5:r)];
@ -280,7 +280,7 @@ void _ftb_climb_the_tree(FTB_WORD *ftbw, my_off_t curdoc)
int ft_boolean_read_next(FT_INFO *ftb, char *record)
{
FTB_EXPR *ftbe, *up;
FTB_EXPR *ftbe;
FTB_WORD *ftbw;
MI_INFO *info=ftb->info;
MI_KEYDEF *keyinfo=info->s->keyinfo+ftb->keynr;

View File

@ -184,14 +184,14 @@ static void get_options(int argc, char *argv[])
static void usage(char *argv[])
{
printf("
Use: %s [-%s] <table_name> <index_no>
-d dump index (incl. data offsets and word weights)
-s report global stats
-c calculate per-word stats (counts and global weights)
-v be verbose
-h this text\n
printf("\n\
Use: %s [-%s] <table_name> <index_no>\n\
\n\
-d dump index (incl. data offsets and word weights)\n\
-s report global stats\n\
-c calculate per-word stats (counts and global weights)\n\
-v be verbose\n\
-h this text\n\
", *argv, options);
exit(1);
}

View File

@ -38,8 +38,9 @@ typedef struct st_ft_docstat {
static int FT_WORD_cmp(void* cmp_arg, FT_WORD *w1, FT_WORD *w2)
{
return _mi_compare_text(default_charset_info,
(uchar*) w1->pos,w1->len,
(uchar*) w2->pos, w2->len,(my_bool)cmp_arg);
(uchar*) w1->pos, w1->len,
(uchar*) w2->pos, w2->len,
(my_bool) (cmp_arg != 0));
}
static int walk_and_copy(FT_WORD *word,uint32 count,FT_DOCSTAT *docstat)

View File

@ -21,7 +21,7 @@
ulong ft_min_word_len=4;
ulong ft_max_word_len=HA_FT_MAXLEN;
ulong ft_max_word_len_for_sort=20;
char *ft_boolean_syntax="+ -><()~*";
const char *ft_boolean_syntax="+ -><()~*";
const MI_KEYSEG ft_keysegs[FT_SEGS]={
{

View File

@ -67,8 +67,9 @@ uint _mi_ft_parse(TREE *parsed, MI_INFO *info, uint keynr, const byte *record)
return 0;
}
FT_WORD * _mi_ft_parserecord(MI_INFO *info, uint keynr, byte *keybuf,
const byte *record)
FT_WORD * _mi_ft_parserecord(MI_INFO *info, uint keynr,
byte *keybuf __attribute__((unused)),
const byte *record)
{
TREE ptree;

View File

@ -123,6 +123,7 @@ byte ft_simple_get_word(byte **, byte *, FT_WORD *);
int ft_parse(TREE *, byte *, int);
FT_WORD * ft_linearize(/*MI_INFO *, uint, byte *, */TREE *);
FT_WORD * _mi_ft_parserecord(MI_INFO *, uint, byte *, const byte *);
uint _mi_ft_parse(TREE *parsed, MI_INFO *info, uint keynr, const byte *record);
const struct _ft_vft _ft_vft_nlq;
FT_INFO *ft_init_nlq_search(MI_INFO *, uint, byte *, uint, my_bool);
@ -141,4 +142,3 @@ void ft_boolean_close_search(FT_INFO *);
float ft_boolean_get_relevance(FT_INFO *);
my_off_t ft_boolean_get_docid(FT_INFO *);
void ft_boolean_reinit_search(FT_INFO *);

View File

@ -97,6 +97,12 @@ int mi_delete(MI_INFO *info,const byte *record)
myisam_log_command(MI_LOG_DELETE,info,(byte*) lastpos,sizeof(lastpos),0);
VOID(_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE));
allow_break(); /* Allow SIGHUP & SIGINT */
if (info->invalidator != 0)
{
DBUG_PRINT("info", ("invalidator... '%s' (delete)", info->filename));
(*info->invalidator)(info->filename);
info->invalidator=0;
}
DBUG_RETURN(0);
err:

View File

@ -43,8 +43,7 @@ int mi_lock_database(MI_INFO *info, int lock_type)
pthread_mutex_lock(&share->intern_lock);
if (share->kfile >= 0) /* May only be false on windows */
{
switch (lock_type)
{
switch (lock_type) {
case F_UNLCK:
if (info->lock_type == F_RDLCK)
count= --share->r_locks;
@ -201,6 +200,7 @@ int mi_lock_database(MI_INFO *info, int lock_type)
}
VOID(_mi_test_if_changed(info));
info->lock_type=lock_type;
info->invalidator=info->s->invalidator;
share->w_locks++;
share->tot_locks++;
break;
@ -319,6 +319,7 @@ int _mi_readinfo(register MI_INFO *info, int lock_type, int check_keybuffer)
}
if (check_keybuffer)
VOID(_mi_test_if_changed(info));
info->invalidator=info->s->invalidator;
}
else if (lock_type == F_WRLCK && info->lock_type == F_RDLCK)
{

View File

@ -136,6 +136,12 @@ int mi_update(register MI_INFO *info, const byte *oldrec, byte *newrec)
myisam_log_record(MI_LOG_UPDATE,info,newrec,info->lastpos,0);
VOID(_mi_writeinfo(info,key_changed ? WRITEINFO_UPDATE_KEYFILE : 0));
allow_break(); /* Allow SIGHUP & SIGINT */
if (info->invalidator != 0)
{
DBUG_PRINT("info", ("invalidator... '%s' (update)", info->filename));
(*info->invalidator)(info->filename);
info->invalidator=0;
}
DBUG_RETURN(0);
err:

View File

@ -66,8 +66,10 @@ typedef struct st_mi_state_info
ulong unique; /* Unique number for this process */
ulong update_count; /* Updated for each write lock */
ulong status;
ulong *rec_per_key_part;
my_off_t *key_root; /* Start of key trees */
my_off_t *key_del; /* delete links for trees */
my_off_t rec_per_key_rows; /* Rows when calculating rec_per_key */
ulong sec_index_changed; /* Updated when new sec_index */
ulong sec_index_used; /* which extra index are in use */
@ -80,8 +82,6 @@ typedef struct st_mi_state_info
uint sortkey; /* sorted by this key (not used) */
uint open_count;
uint8 changed; /* Changed since myisamchk */
my_off_t rec_per_key_rows; /* Rows when calculating rec_per_key */
ulong *rec_per_key_part;
/* the following isn't saved on disk */
uint state_diff_length; /* Should be 0 */
@ -164,31 +164,8 @@ typedef struct st_mi_isam_share { /* Shared between opens */
char *data_file_name, /* Resolved path names from symlinks */
*index_file_name;
byte *file_map; /* mem-map of file if possible */
ulong this_process; /* processid */
ulong last_process; /* For table-change-check */
ulong last_version; /* Version on start */
ulong options; /* Options used */
uint rec_reflength; /* rec_reflength in use now */
File kfile; /* Shared keyfile */
File data_file; /* Shared data file */
int mode; /* mode of file on open */
uint reopen; /* How many times reopened */
uint w_locks,r_locks,tot_locks; /* Number of read/write locks */
uint blocksize; /* blocksize of keyfile */
ulong min_pack_length; /* Theese are used by packed data */
ulong max_pack_length;
ulong state_diff_length;
my_bool changed, /* If changed since lock */
global_changed, /* If changed since open */
not_flushed,
temporary,delay_key_write,
concurrent_insert,
fulltext_index;
myf write_flag;
int rnd; /* rnd-counter */
MI_DECODE_TREE *decode_trees;
uint16 *decode_tables;
enum data_file_type data_file_type;
int (*read_record)(struct st_myisam_info*, my_off_t, byte*);
int (*write_record)(struct st_myisam_info*, const byte*);
int (*update_record)(struct st_myisam_info*, my_off_t, const byte*);
@ -198,6 +175,30 @@ typedef struct st_mi_isam_share { /* Shared between opens */
ha_checksum (*calc_checksum)(struct st_myisam_info*, const byte *);
int (*compare_unique)(struct st_myisam_info*, MI_UNIQUEDEF *,
const byte *record, my_off_t pos);
invalidator_by_filename invalidator; /* query cache invalidator */
ulong this_process; /* processid */
ulong last_process; /* For table-change-check */
ulong last_version; /* Version on start */
ulong options; /* Options used */
ulong min_pack_length; /* Theese are used by packed data */
ulong max_pack_length;
ulong state_diff_length;
uint rec_reflength; /* rec_reflength in use now */
File kfile; /* Shared keyfile */
File data_file; /* Shared data file */
int mode; /* mode of file on open */
uint reopen; /* How many times reopened */
uint w_locks,r_locks,tot_locks; /* Number of read/write locks */
uint blocksize; /* blocksize of keyfile */
myf write_flag;
int rnd; /* rnd-counter */
enum data_file_type data_file_type;
my_bool changed, /* If changed since lock */
global_changed, /* If changed since open */
not_flushed,
temporary,delay_key_write,
concurrent_insert,
fulltext_index;
#ifdef THREAD
THR_LOCK lock;
pthread_mutex_t intern_lock; /* Locking for use with _locking */
@ -215,16 +216,22 @@ typedef struct st_mi_bit_buff { /* Used for packing of record */
uint error;
} MI_BIT_BUFF;
struct st_myisam_info {
MYISAM_SHARE *s; /* Shared between open:s */
MI_STATUS_INFO *state,save_state;
MI_BLOB *blobs; /* Pointer to blobs */
int dfile; /* The datafile */
MI_BIT_BUFF bit_buff;
uint opt_flag; /* Optim. for space/speed */
uint update; /* If file changed since open */
MI_BIT_BUFF bit_buff;
/* accumulate indexfile changes between write's */
TREE *bulk_insert;
char *filename; /* parameter to open filename */
uchar *buff, /* Temp area for key */
*lastkey,*lastkey2; /* Last used search key */
byte *rec_buff, /* Tempbuff for recordpack */
*rec_alloc; /* Malloced area for record */
uchar *int_keypos, /* Save position for next/previous */
*int_maxpos; /* -""- */
int (*read_record)(struct st_myisam_info*, my_off_t, byte*);
invalidator_by_filename invalidator; /* query cache invalidator */
ulong this_unique; /* uniq filenumber or thread */
ulong last_unique; /* last unique number */
ulong this_loop; /* counter for this open */
@ -233,20 +240,16 @@ struct st_myisam_info {
nextpos; /* Position to next record */
my_off_t save_lastpos;
my_off_t pos; /* Intern variable */
ha_checksum checksum;
ulong packed_length,blob_length; /* Length of found, packed record */
uint alloced_rec_buff_length; /* Max recordlength malloced */
uchar *buff, /* Temp area for key */
*lastkey,*lastkey2; /* Last used search key */
byte *rec_buff, /* Tempbuff for recordpack */
*rec_alloc; /* Malloced area for record */
uchar *int_keypos, /* Save position for next/previous */
*int_maxpos; /* -""- */
uint32 int_keytree_version; /* -""- */
uint int_nod_flag; /* -""- */
my_off_t last_keypage; /* Last key page read */
my_off_t last_search_keypage; /* Last keypage when searching */
my_off_t dupp_key_pos;
ha_checksum checksum;
ulong packed_length,blob_length; /* Length of found, packed record */
int dfile; /* The datafile */
uint opt_flag; /* Optim. for space/speed */
uint update; /* If file changed since open */
uint alloced_rec_buff_length; /* Max recordlength malloced */
uint int_nod_flag; /* -""- */
int lastinx; /* Last used index */
uint lastkey_length; /* Length of key in lastkey */
uint last_rkey_length; /* Last length in mi_rkey() */
@ -257,16 +260,15 @@ struct st_myisam_info {
uint data_changed; /* Somebody has changed data */
uint save_update; /* When using KEY_READ */
int save_lastinx;
uint32 int_keytree_version; /* -""- */
LIST open_list;
IO_CACHE rec_cache; /* When cacheing records */
myf lock_wait; /* is 0 or MY_DONT_WAIT */
my_bool was_locked; /* Was locked in panic */
my_bool quick_mode;
my_bool page_changed; /* If info->buff can't be used for rnext */
my_bool buff_used; /* If info->buff has to be reread for rnext */
my_bool use_packed_key; /* For MYISAMMRG */
TREE *bulk_insert; /* accumulate indexfile changes between mi_write's */
myf lock_wait; /* is 0 or MY_DONT_WAIT */
int (*read_record)(struct st_myisam_info*, my_off_t, byte*);
LIST open_list;
IO_CACHE rec_cache; /* When cacheing records */
#ifdef THREAD
THR_LOCK_DATA lock;
#endif

View File

@ -46,3 +46,13 @@ int myrg_extra(MYRG_INFO *info,enum ha_extra_function function)
}
DBUG_RETURN(save_error);
}
void myrg_extrafunc(MYRG_INFO *info, invalidator_by_filename inv)
{
MYRG_TABLE *file;
DBUG_ENTER("myrg_extrafunc");
for (file=info->open_tables ; file != info->end_table ; file++)
file->table->s->invalidator = inv;
DBUG_VOID_RETURN;
}

View File

@ -252,6 +252,9 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
{
reg1 SEC_LINK *next;
int error=0;
DBUG_ENTER("key_cache_read");
DBUG_PRINT("enter", ("file %u, filepos %lu, length %u",
(uint) file, (ulong) filepos, length));
#ifndef THREAD
if (block_length > key_cache_block_size)
@ -270,14 +273,14 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
if (!(next=find_key_block(file,filepos,&error)))
{
pthread_mutex_unlock(&THR_LOCK_keycache);
return (byte*) 0; /* Got a fatal error */
DBUG_RETURN ((byte*) 0); /* Got a fatal error */
}
if (error)
{ /* Didn't find it in cache */
if (my_pread(file,next->buffer,read_length,filepos,MYF(MY_NABP)))
{
pthread_mutex_unlock(&THR_LOCK_keycache);
return((byte*) 0);
DBUG_RETURN((byte*) 0);
}
_my_cache_read++;
}
@ -285,7 +288,7 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
if (return_buffer)
{
pthread_mutex_unlock(&THR_LOCK_keycache);
return (next->buffer);
DBUG_RETURN (next->buffer);
}
#endif
if (! (read_length & 511))
@ -296,13 +299,13 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
filepos+=read_length;
} while ((length-= read_length));
pthread_mutex_unlock(&THR_LOCK_keycache);
return(start);
DBUG_RETURN(start);
}
_my_cache_r_requests++;
_my_cache_read++;
if (my_pread(file,(byte*) buff,length,filepos,MYF(MY_NABP)))
error=1;
return (error ? (byte*) 0 : buff);
DBUG_RETURN(error ? (byte*) 0 : buff);
} /* key_cache_read */
@ -316,12 +319,15 @@ int key_cache_write(File file, my_off_t filepos, byte *buff, uint length,
{
reg1 SEC_LINK *next;
int error=0;
DBUG_ENTER("key_cache_write");
DBUG_PRINT("enter", ("file %u, filepos %lu, length %u",
(uint) file, (ulong) filepos, length));
if (!dont_write)
{ /* Forced write of buffer */
_my_cache_write++;
if (my_pwrite(file,buff,length,filepos,MYF(MY_NABP | MY_WAIT_IF_FULL)))
return(1);
DBUG_RETURN(1);
}
#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
@ -367,7 +373,7 @@ end:
#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
DBUG_EXECUTE("check_keycache",test_key_cache("end of key_cache_write",1););
#endif
return(error);
DBUG_RETURN(error);
} /* key_cache_write */
@ -377,6 +383,9 @@ end:
static SEC_LINK *find_key_block(int file, my_off_t filepos, int *error)
{
reg1 SEC_LINK *next,**start;
DBUG_ENTER("find_key_block");
DBUG_PRINT("enter", ("file %u, filepos %lu",
(uint) file, (ulong) filepos));
#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
DBUG_EXECUTE("check_keycache2",test_key_cache("start of find_key_block",0););
@ -461,7 +470,7 @@ static SEC_LINK *find_key_block(int file, my_off_t filepos, int *error)
#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
DBUG_EXECUTE("check_keycache2",test_key_cache("end of find_key_block",0););
#endif
return next;
DBUG_RETURN(next);
} /* find_key_block */

View File

@ -15,7 +15,7 @@
#define CCLASS_LAST 12
extern struct cclass {
char *name;
char *chars;
char *multis;
const char *name;
const char *chars;
const char *multis;
} cclasses[];

View File

@ -1,7 +1,7 @@
/* character-name table */
static struct cname {
char *name;
char code;
const char *name;
const char code;
} cnames[] = {
{"NUL", '\0'},
{"SOH", '\001'},

View File

@ -133,9 +133,9 @@ FILE *in;
int i;
char erbuf[100];
size_t ne;
char *badpat = "invalid regular expression";
const char *badpat = "invalid regular expression";
# define SHORT 10
char *bpname = "REG_BADPAT";
const char *bpname = "REG_BADPAT";
regex_t re;
while (fgets(inbuf, sizeof(inbuf), in) != NULL) {
@ -152,7 +152,7 @@ FILE *in;
}
for (i = 0; i < nf; i++)
if (strcmp(f[i], "\"\"") == 0)
f[i] = "";
f[i] = (char*) "";
if (nf <= 3)
f[3] = NULL;
if (nf <= 4)
@ -217,7 +217,7 @@ int opts; /* may not match f1 */
char erbuf[100];
int err;
int len;
char *type = (opts & REG_EXTENDED) ? "ERE" : "BRE";
const char *type = (opts & REG_EXTENDED) ? "ERE" : "BRE";
register int i;
char *grump;
char f0copy[1000];
@ -291,7 +291,7 @@ int opts; /* may not match f1 */
nshould = split(f4, should+1, NSHOULD-1, ",");
if (nshould == 0) {
nshould = 1;
should[1] = "";
should[1] = (char*) "";
}
for (i = 1; i < NSUBS; i++) {
grump = check(f2, subs[i], should[i]);
@ -317,7 +317,7 @@ char *s;
{
register char *p;
register int o = (type == 'c') ? copts : eopts;
register char *legal = (type == 'c') ? "bisnmp" : "^$#tl";
register const char *legal = (type == 'c') ? "bisnmp" : "^$#tl";
for (p = s; *p != '\0'; p++)
if (strchr(legal, *p) != NULL)
@ -417,7 +417,7 @@ char *should;
should = NULL;
if (should != NULL && should[0] == '@') {
at = should + 1;
should = "";
should = (char*) "";
}
/* check rm_so and rm_eo for consistency */
@ -434,7 +434,7 @@ char *should;
if (sub.rm_so == -1 && should == NULL)
return(NULL);
if (sub.rm_so == -1)
return("did not match");
return((char*) "did not match");
/* check for in range */
if ((int) sub.rm_eo > (int) strlen(str)) {

View File

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

View File

@ -28,9 +28,11 @@ static int freezeset(register struct parse *p, register cset *cs);
static int firstch(register struct parse *p, register cset *cs);
static int nch(register struct parse *p, register cset *cs);
static void mcadd(register struct parse *p, register cset *cs, register char *cp);
#ifdef NOT_USED
static void mcsub(register cset *cs, register char *cp);
static int mcin(register cset *cs, register char *cp);
static char *mcfind(register cset *cs, register char *cp);
#endif
static void mcinvert(register struct parse *p, register cset *cs);
static void mccase(register struct parse *p, register cset *cs);
static int isinsets(register struct re_guts *g, int c);

View File

@ -28,8 +28,8 @@
*/
static struct rerr {
int code;
char *name;
char *explain;
const char *name;
const char *explain;
} rerrs[] = {
{REG_NOMATCH, "REG_NOMATCH", "regexec() failed to match"},
{REG_BADPAT, "REG_BADPAT", "invalid regular expression"},
@ -83,7 +83,7 @@ size_t errbuf_size;
assert(strlen(convbuf) < sizeof(convbuf));
s = convbuf;
} else
s = r->explain;
s = (char*) r->explain;
}
len = strlen(s) + 1;
@ -113,7 +113,7 @@ char *localbuf;
if (strcmp(r->name, preg->re_endp) == 0)
break;
if (r->code == 0)
return("0");
return((char*) "0");
sprintf(localbuf, "%d", r->code);
return(localbuf);

View File

@ -63,7 +63,7 @@ void regex_end()
{
int i;
for (i=0; i < CCLASS_LAST ; i++)
free(cclasses[i].chars);
free((char*) cclasses[i].chars);
regex_inited=0;
}
}

View File

@ -27,7 +27,7 @@ char *sep; /* "" white, "c" single char, "ab" [ab]+ */
continue;
p--;
trimtrail = 1;
sep = " \t"; /* note, code below knows this is 2 long */
sep = (char*) " \t"; /* note, code below knows this is 2 long */
sepc = ' ';
} else
trimtrail = 0;

View File

@ -27,7 +27,7 @@
use DBI;
use Benchmark;
$opt_loop_count=10000; # Change this to make test harder/easier
$opt_loop_count=100000; # Change this to make test harder/easier
$str_length=65000; # This is the length of blob strings in PART:5
$max_test=20; # How many times to test if the server is busy
@ -43,9 +43,10 @@ if ($opt_small_test)
}
$opt_loop_count=min(1000, $opt_loop_count) if ($opt_tcpip);
$small_loop_count=$opt_loop_count/10; # For connect tests
print "Testing the speed of connecting to the server and sending of data\n";
print "All tests are done $opt_loop_count times\n\n";
print "Connect tests are done $opt_small_loop_count and other tests $opt_loop_count times\n\n";
################################# PART:1 ###################################
####
@ -59,7 +60,7 @@ print "Testing connection/disconnect\n";
$loop_time=new Benchmark;
$errors=0;
for ($i=0 ; $i < $opt_loop_count ; $i++)
for ($i=0 ; $i < $small_loop_count ; $i++)
{
print "$i " if (($opt_debug));
for ($j=0; $j < $max_test ; $j++)
@ -80,27 +81,27 @@ for ($i=0 ; $i < $opt_loop_count ; $i++)
}
$end_time=new Benchmark;
print "Warning: $errors connections didn't work without a time delay\n" if ($errors);
print "Time to connect ($opt_loop_count): " .
print "Time to connect ($small_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
################################# PART:2 ###################################
#### Now we shall do first one connect, then simple select
#### (select 1..) and then close connection. This will be
#### done $opt_loop_count times.
#### done $small_loop_count times.
if ($limits->{'select_without_from'})
{
print "Test connect/simple select/disconnect\n";
$loop_time=new Benchmark;
for ($i=0; $i<$opt_loop_count; $i++)
for ($i=0; $i < $small_loop_count; $i++)
{
$dbh = DBI->connect($server->{'data_source'}, $opt_user, $opt_password) || die $DBI::errstr;
$sth = $dbh->do("select 1") or die $DBI::errstr;
$sth = $dbh->do("select $i") or die $DBI::errstr;
$dbh->disconnect;
}
$end_time=new Benchmark;
print "Time for connect+select_simple ($opt_loop_count): " .
print "Time for connect+select_simple ($small_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
}
@ -116,16 +117,33 @@ if ($limits->{'select_without_from'})
{
print "Test simple select\n";
$loop_time=new Benchmark;
for ($i=0 ; $i<$opt_loop_count ; $i++)
for ($i=0 ; $i < $opt_loop_count ; $i++)
{
$sth = $dbh->do("select 1") or die $DBI::errstr;
$sth = $dbh->do("select $i") or die $DBI::errstr;
}
$end_time=new Benchmark;
print "Time for select_simple ($opt_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
}
################################# PART:4 ###################################
###########################################################################
#### The same as the previous test, but always execute the same select
#### This is done to test the query cache for real simple selects.
if ($limits->{'select_without_from'})
{
print "Test simple select\n";
$loop_time=new Benchmark;
for ($i=0 ; $i < $opt_loop_count ; $i++)
{
$sth = $dbh->do("select 10000") or die $DBI::errstr;
}
$end_time=new Benchmark;
print "Time for select_simple_query_cache ($opt_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
}
##########################################################################
#### First, we'll create a simple table 'bench1'
#### Then we shall do $opt_loop_count selects from this table.
#### Table will contain very simple data.
@ -152,7 +170,7 @@ print "Testing connect/select 1 row from table/disconnect\n";
$loop_time=new Benchmark;
$errors=0;
for ($i=0 ; $i<$opt_loop_count ; $i++)
for ($i=0 ; $i < $small_loop_count ; $i++)
{
for ($j=0; $j < $max_test ; $j++)
{
@ -161,14 +179,14 @@ for ($i=0 ; $i<$opt_loop_count ; $i++)
}
die $DBI::errstr if ($j == $max_test);
$sth = $dbh->do("select * from bench1") #Select * from table with 1 record
$sth = $dbh->do("select a,i,s,$i from bench1") # Select * from table with 1 record
or die $DBI::errstr;
$dbh->disconnect;
}
$end_time=new Benchmark;
print "Warning: $errors connections didn't work without a time delay\n" if ($errors);
print "Time to connect+select_1_row ($opt_loop_count): " .
print "Time to connect+select_1_row ($small_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
#
@ -179,9 +197,9 @@ print "Testing select 1 row from table\n";
$dbh = $server->connect();
$loop_time=new Benchmark;
for ($i=0 ; $i<$opt_loop_count ; $i++)
for ($i=0 ; $i < $opt_loop_count ; $i++)
{
$sth = $dbh->do("select * from bench1") # Select * from table with 1 record
$sth = $dbh->do("select a,i,s,$i from bench1") # Select * from table with 1 record
or die $DBI::errstr;
}
@ -199,9 +217,9 @@ $sth = $dbh->do("insert into bench1 values(2,200,'BBB')")
$loop_time=new Benchmark;
for ($i=0 ; $i<$opt_loop_count ; $i++)
for ($i=0 ; $i < $opt_loop_count ; $i++)
{
$sth = $dbh->do("select * from bench1") # Select * from table with 2 record
$sth = $dbh->do("select a,i,s,$i from bench1") # Select * from table with 2 record
or die $DBI::errstr;
}
@ -214,9 +232,9 @@ if ($limits->{'functions'})
print "Test select with aritmetic (+)\n";
$loop_time=new Benchmark;
for ($i=0; $i<$opt_loop_count; $i++)
for ($i=0; $i < $opt_loop_count; $i++)
{
$sth = $dbh->do("select a+a+a+a+a+a+a+a+a+a from bench1") or die $DBI::errstr;
$sth = $dbh->do("select a+a+a+a+a+a+a+a+a+$i from bench1") or die $DBI::errstr;
}
$end_time=new Benchmark;
print "Time for select_column+column ($opt_loop_count): " .
@ -254,9 +272,9 @@ if ($opt_fast && defined($server->{vacuum}))
$loop_time=new Benchmark;
for ($i=0 ; $i < $opt_loop_count ; $i++)
for ($i=0 ; $i < $small_loop_count ; $i++)
{
$sth = $dbh->prepare("select * from bench1");
$sth = $dbh->prepare("select b,$i from bench1");
if (!$sth->execute || !(@row = $sth->fetchrow_array) ||
length($row[0]) != $str_length)
{
@ -266,7 +284,7 @@ for ($i=0 ; $i < $opt_loop_count ; $i++)
}
$end_time=new Benchmark;
print "Time to select_big_str ($opt_loop_count): " .
print "Time to select_big_str ($small_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
$sth = $dbh->do("drop table bench1" . $server->{'drop_attr'})

View File

@ -23,7 +23,7 @@
use DBI;
use Benchmark;
use warnings;
#use warnings;
$opt_groups=27; # Characters are 'A' -> Z
@ -34,7 +34,8 @@ chomp($pwd = `pwd`); $pwd = "." if ($pwd eq '');
require "$pwd/bench-init.pl" || die "Can't read Configuration file: $!\n";
# Avoid warnings for variables in bench-init.pl
our ($opt_small_test, $opt_small_tables, $opt_debug, $opt_force);
# (Only works with perl 5.6)
#our ($opt_small_test, $opt_small_tables, $opt_debug, $opt_force);
if ($opt_small_test || $opt_small_tables)
{

View File

@ -397,19 +397,19 @@ static unsigned char win1251ukr_koi8_ukr[256] = {
****************************************************************************/
CONVERT conv_cp1251_koi8("cp1251_koi8", cp1251_koi8, koi8_cp1251);
CONVERT conv_cp1251_koi8("cp1251_koi8", cp1251_koi8, koi8_cp1251, 1);
#ifdef DEFINE_ALL_CHARACTER_SETS
CONVERT conv_cp1250_latin2("cp1250_latin2", t1250_til2, til2_t1250);
CONVERT conv_kam_latin2("kam_latin2", tkam_til2, til2_tkam);
CONVERT conv_mac_latin2("mac_latin2", tmac_til2, til2_tmac);
CONVERT conv_macce_latin2("macce_latin2", tmacce_til2, til2_tmacce);
CONVERT conv_pc2_latin2("pc2_latin2", tpc2_til2, til2_tpc2);
CONVERT conv_vga_latin2("vga_latin2", tvga_til2, til2_tvga);
CONVERT conv_koi8_cp1251("koi8_cp1251", koi8_cp1251, cp1251_koi8);
CONVERT conv_cp1250_latin2("cp1250_latin2", t1250_til2, til2_t1250, 2);
CONVERT conv_kam_latin2("kam_latin2", tkam_til2, til2_tkam, 3);
CONVERT conv_mac_latin2("mac_latin2", tmac_til2, til2_tmac, 4);
CONVERT conv_macce_latin2("macce_latin2", tmacce_til2, til2_tmacce, 5);
CONVERT conv_pc2_latin2("pc2_latin2", tpc2_til2, til2_tpc2, 6);
CONVERT conv_vga_latin2("vga_latin2", tvga_til2, til2_tvga, 7);
CONVERT conv_koi8_cp1251("koi8_cp1251", koi8_cp1251, cp1251_koi8, 8);
CONVERT conv_win1251ukr_koi8_ukr("win1251ukr_koi8_ukr", win1251ukr_koi8_ukr,
koi8_ukr_win1251ukr);
koi8_ukr_win1251ukr, 9);
CONVERT conv_koi8_ukr_win1251ukr("koi8_ukr_win1251ukr", koi8_ukr_win1251ukr,
win1251ukr_koi8_ukr);
win1251ukr_koi8_ukr, 10);
#endif /* DEFINE_ALL_CHARACTER_SETS */
CONVERT *convert_tables[]= {

View File

@ -38,10 +38,15 @@ const char **ha_myisammrg::bas_ext() const
int ha_myisammrg::open(const char *name, int mode, uint test_if_locked)
{
char name_buff[FN_REFLEN];
DBUG_PRINT("info", ("ha_myisammrg::open"));
if (!(file=myrg_open(fn_format(name_buff,name,"","",2 | 4), mode,
test_if_locked)))
{
DBUG_PRINT("info", ("ha_myisammrg::open exit %d", my_errno));
return (my_errno ? my_errno : -1);
}
DBUG_PRINT("info", ("ha_myisammrg::open myrg_extrafunc..."))
myrg_extrafunc(file, &query_cache_invalidate_by_MyISAM_filename);
if (!(test_if_locked == HA_OPEN_WAIT_IF_LOCKED ||
test_if_locked == HA_OPEN_ABORT_IF_LOCKED))
myrg_extra(file,HA_EXTRA_NO_WAIT_LOCK);

View File

@ -74,4 +74,5 @@ class ha_myisammrg: public handler
enum thr_lock_type lock_type);
void update_create_info(HA_CREATE_INFO *create_info);
void append_create_info(String *packet);
MYRG_INFO *myrg_info() { return file; }
};

View File

@ -258,6 +258,8 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
error=1;
}
trans->innodb_active_trans=0;
if (trans == &thd->transaction.all)
query_cache.invalidate(Query_cache_table::INNODB);
}
#endif
if (error && trans == &thd->transaction.all && mysql_bin_log.is_open())

View File

@ -65,7 +65,9 @@ Item *create_func_ceiling(Item* a)
Item *create_func_connection_id(void)
{
return new Item_int("CONNECTION_ID()",(longlong) current_thd->thread_id,10);
THD *thd=current_thd;
thd->safe_to_cache_query=0;
return new Item_int("CONNECTION_ID()",(longlong) thd->thread_id,10);
}
Item *create_func_conv(Item* a, Item *b, Item *c)
@ -131,7 +133,9 @@ Item *create_func_floor(Item* a)
Item *create_func_found_rows(void)
{
return new Item_int("FOUND_ROWS()",(longlong) current_thd->found_rows(),21);
THD *thd=current_thd;
thd->safe_to_cache_query=0;
return new Item_int("FOUND_ROWS()",(longlong) thd->found_rows(),21);
}
Item *create_func_from_days(Item* a)
@ -141,6 +145,7 @@ Item *create_func_from_days(Item* a)
Item *create_func_get_lock(Item* a, Item *b)
{
current_thd->safe_to_cache_query=0;
return new Item_func_get_lock(a, b);
}
@ -279,6 +284,7 @@ Item *create_func_radians(Item *a)
Item *create_func_release_lock(Item* a)
{
current_thd->safe_to_cache_query=0;
return new Item_func_release_lock(a);
}
@ -379,10 +385,12 @@ Item *create_func_year(Item* a)
Item *create_load_file(Item* a)
{
current_thd->safe_to_cache_query=0;
return new Item_load_file(a);
}
Item *create_wait_for_master_pos(Item* a, Item* b)
{
current_thd->safe_to_cache_query=0;
return new Item_master_pos_wait(a, b);
}

View File

@ -2170,7 +2170,7 @@ bool Item_func_match::eq(const Item *item) const
double Item_func_match::val()
{
if (ft_handler==NULL)
if (ft_handler == NULL)
return -1.0;
if (join_key)
@ -2184,10 +2184,10 @@ double Item_func_match::val()
if (key == NO_SUCH_KEY)
{
String *a=concat->val_str(&value);
if (null_value=(a==0))
if ((null_value= (a==0)))
return 0;
return ft_handler->please->find_relevance(ft_handler,
(byte *)a->ptr(), a->length());
(byte *)a->ptr(), a->length());
}
else
return ft_handler->please->find_relevance(ft_handler, record, 0);

View File

@ -862,18 +862,18 @@ class Item_func_match :public Item_real_func
{
public:
List<Item> fields;
Item *concat;
String value;
TABLE *table;
uint key, mode;
bool join_key;
Item_func_match *master;
FT_INFO * ft_handler;
Item *concat;
byte *record;
uint key, mode;
bool join_key;
Item_func_match(List<Item> &a, Item *b): Item_real_func(b),
fields(a), table(0), join_key(0), master(0), ft_handler(0),
key(0), concat(0) {}
fields(a), table(0), master(0), ft_handler(0),
concat(0), key(0), join_key(0) {}
~Item_func_match()
{
if (!master && ft_handler)

View File

@ -76,6 +76,7 @@ static SYMBOL symbols[] = {
{ "BOOLEAN", SYM(BOOLEAN_SYM),0,0},
{ "BOTH", SYM(BOTH),0,0},
{ "BY", SYM(BY),0,0},
{ "CACHE", SYM(CACHE_SYM),0,0},
{ "CASCADE", SYM(CASCADE),0,0},
{ "CASE", SYM(CASE_SYM),0,0},
{ "CHAR", SYM(CHAR_SYM),0,0},
@ -114,6 +115,7 @@ static SYMBOL symbols[] = {
{ "DELAYED", SYM(DELAYED_SYM),0,0},
{ "DELAY_KEY_WRITE", SYM(DELAY_KEY_WRITE_SYM),0,0},
{ "DELETE", SYM(DELETE_SYM),0,0},
{ "DEMAND", SYM(DEMAND_SYM),0,0},
{ "DESC", SYM(DESC),0,0},
{ "DESCRIBE", SYM(DESCRIBE),0,0},
{ "DIRECTORY", SYM(DIRECTORY_SYM),0,0},
@ -248,6 +250,7 @@ static SYMBOL symbols[] = {
{ "NOT", SYM(NOT),0,0},
{ "NULL", SYM(NULL_SYM),0,0},
{ "NUMERIC", SYM(NUMERIC_SYM),0,0},
{ "OFF", SYM(OFF),0,0},
{ "ON", SYM(ON),0,0},
{ "OPEN", SYM(OPEN_SYM),0,0},
{ "OPTIMIZE", SYM(OPTIMIZE),0,0},
@ -268,6 +271,7 @@ static SYMBOL symbols[] = {
{ "PROCESS" , SYM(PROCESS),0,0},
{ "PROCESSLIST", SYM(PROCESSLIST_SYM),0,0},
{ "PRIVILEGES", SYM(PRIVILEGES),0,0},
{ "QUERY", SYM(QUERY_SYM),0,0},
{ "QUICK", SYM(QUICK),0,0},
{ "RAID0", SYM(RAID_0_SYM),0,0},
{ "READ", SYM(READ_SYM),0,0},
@ -306,12 +310,15 @@ static SYMBOL symbols[] = {
{ "SQL_BIG_SELECTS", SYM(SQL_BIG_SELECTS),0,0},
{ "SQL_BIG_TABLES", SYM(SQL_BIG_TABLES),0,0},
{ "SQL_BUFFER_RESULT", SYM(SQL_BUFFER_RESULT),0,0},
{ "SQL_CACHE", SYM(SQL_CACHE_SYM), 0, 0},
{ "SQL_CALC_FOUND_ROWS", SYM(SQL_CALC_FOUND_ROWS),0,0},
{ "SQL_LOG_BIN", SYM(SQL_LOG_BIN),0,0},
{ "SQL_LOG_OFF", SYM(SQL_LOG_OFF),0,0},
{ "SQL_LOG_UPDATE", SYM(SQL_LOG_UPDATE),0,0},
{ "SQL_LOW_PRIORITY_UPDATES", SYM(SQL_LOW_PRIORITY_UPDATES),0,0},
{ "SQL_MAX_JOIN_SIZE",SYM(SQL_MAX_JOIN_SIZE), 0, 0},
{ "SQL_NO_CACHE", SYM(SQL_NO_CACHE_SYM), 0, 0},
{ "SQL_QUERY_CACHE_TYPE",SYM(SQL_QUERY_CACHE_TYPE_SYM), 0, 0},
{ "SQL_QUOTE_SHOW_CREATE",SYM(SQL_QUOTE_SHOW_CREATE), 0, 0},
{ "SQL_SAFE_UPDATES", SYM(SQL_SAFE_UPDATES),0,0},
{ "SQL_SELECT_LIMIT", SYM(SQL_SELECT_LIMIT),0,0},

View File

@ -179,6 +179,8 @@ char* query_table_status(THD *thd,const char *db,const char *table_name);
#define SELECT_NO_UNLOCK (QUERY_NO_GOOD_INDEX_USED*2)
#define TMP_TABLE_ALL_COLUMNS (SELECT_NO_UNLOCK*2)
#define OPTION_TO_QUERY_CACHE (TMP_TABLE_ALL_COLUMNS*2)
#define MODE_REAL_AS_FLOAT 1
#define MODE_PIPES_AS_CONCAT 2
@ -248,7 +250,7 @@ inline THD *_current_thd(void)
#include "item.h"
#include "sql_class.h"
#include "opt_range.h"
#include "sql_cache.h"
int mysql_create_db(THD *thd, char *db, uint create_info, bool silent);
int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent);
@ -539,6 +541,7 @@ extern ulong select_full_range_join_count,select_full_join_count,
slave_open_temp_tables;
extern uint test_flags,select_errors,ha_open_options;
extern ulong thd_startup_options, slow_launch_threads, slow_launch_time;
extern ulong query_cache_startup_type;
extern time_t start_time;
extern const char *command_name[];
extern I_List<THD> threads;

View File

@ -270,6 +270,7 @@ ulong keybuff_size,sortbuff_size,max_item_sort_length,table_cache_size,
open_files_limit=0, max_binlog_size, record_rnd_cache_size;
ulong slave_net_timeout;
ulong thread_cache_size=0, binlog_cache_size=0, max_binlog_cache_size=0;
ulong query_cache_size=0, query_cache_limit=0, query_cache_startup_type=1;
volatile ulong cached_thread_count=0;
// replication parameters, if master_host is not NULL, we are a slave
@ -359,6 +360,8 @@ pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count,
LOCK_binlog_update, LOCK_slave, LOCK_server_id,
LOCK_user_conn, LOCK_slave_list;
Query_cache query_cache;
pthread_cond_t COND_refresh,COND_thread_count,COND_binlog_update,
COND_slave_stopped, COND_slave_start;
pthread_cond_t COND_thread_cache,COND_flush_thread_cache;
@ -732,7 +735,7 @@ void clean_up(bool print_message)
return; /* purecov: inspected */
acl_free(1);
grant_free();
sql_cache_free();
query_cache.resize(0);
table_cache_free();
hostname_cache_free();
item_user_lock_free();
@ -1810,7 +1813,8 @@ int main(int argc, char **argv)
server_init();
table_cache_init();
hostname_cache_init();
sql_cache_init();
query_cache.result_size_limit(query_cache_limit);
query_cache.resize(query_cache_size);
randominit(&sql_rand,(ulong) start_time,(ulong) start_time/2);
reset_floating_point_exceptions();
init_thr_lock();
@ -2953,6 +2957,12 @@ CHANGEABLE_VAR changeable_vars[] = {
0, 0, 65535, 0, 1},
{ "query_buffer_size", (long*) &query_buff_size,
0, MALLOC_OVERHEAD, (long) ~0, MALLOC_OVERHEAD, IO_SIZE },
{ "query_cache_limit", (long*) &query_cache_limit,
1024*1024L, 0, ULONG_MAX, 0, 1},
{ "query_cache_size", (long*) &query_cache_size,
0, 0, ULONG_MAX, 0, 1},
{ "query_cache_startup_type",(long*) &query_cache_startup_type,
1, 0, 2, 0, 1},
{ "record_buffer", (long*) &my_default_record_cache_size,
128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE },
{ "record_rnd_buffer", (long*) &record_rnd_cache_size,
@ -3007,7 +3017,7 @@ struct show_var_st init_vars[]= {
{"ft_min_word_len", (char*) &ft_min_word_len, SHOW_LONG},
{"ft_max_word_len", (char*) &ft_max_word_len, SHOW_LONG},
{"ft_max_word_len_for_sort",(char*) &ft_max_word_len_for_sort, SHOW_LONG},
{"ft_boolean_syntax", ft_boolean_syntax, SHOW_CHAR},
{"ft_boolean_syntax", (char*) ft_boolean_syntax, SHOW_CHAR},
{"have_bdb", (char*) &have_berkeley_db, SHOW_HAVE},
{"have_innodb", (char*) &have_innodb, SHOW_HAVE},
{"have_isam", (char*) &have_isam, SHOW_HAVE},
@ -3081,6 +3091,9 @@ struct show_var_st init_vars[]= {
{"record_rnd_buffer", (char*) &record_rnd_cache_size, SHOW_LONG},
{"rpl_recovery_rank", (char*) &rpl_recovery_rank, SHOW_LONG},
{"query_buffer_size", (char*) &query_buff_size, SHOW_LONG},
{"query_cache_limit", (char*) &query_cache_limit, SHOW_LONG},
{"query_cache_size", (char*) &query_cache_size, SHOW_LONG},
{"query_cache_startup_type",(char*) &query_cache_startup_type, SHOW_LONG},
{"safe_show_database", (char*) &opt_safe_show_db, SHOW_BOOL},
{"server_id", (char*) &server_id, SHOW_LONG},
{"slave_net_timeout", (char*) &slave_net_timeout, SHOW_LONG},
@ -3144,8 +3157,13 @@ struct show_var_st status_vars[]= {
{"Open_streams", (char*) &my_stream_opened, SHOW_INT_CONST},
{"Opened_tables", (char*) &opened_tables, SHOW_LONG},
{"Questions", (char*) 0, SHOW_QUESTION},
{"Rpl_status", (char*) 0,
SHOW_RPL_STATUS},
{"Qcache_queries", (char*) &query_cache.queries_in_cache,
SHOW_LONG},
{"Qcache_inserts", (char*) &query_cache.inserts, SHOW_LONG},
{"Qcache_hits", (char*) &query_cache.hits, SHOW_LONG},
{"Qcache_refused", (char*) &query_cache.refused, SHOW_LONG},
{"Qcache_free_memory", (char*) &query_cache.free_memory,SHOW_LONG},
{"Rpl_status", (char*) 0, SHOW_RPL_STATUS},
{"Select_full_join", (char*) &select_full_join_count, SHOW_LONG},
{"Select_full_range_join", (char*) &select_full_range_join_count, SHOW_LONG},
{"Select_range", (char*) &select_range_count, SHOW_LONG},
@ -3160,29 +3178,29 @@ struct show_var_st status_vars[]= {
{"Sort_rows", (char*) &filesort_rows, SHOW_LONG},
{"Sort_scan", (char*) &filesort_scan_count, SHOW_LONG},
#ifdef HAVE_OPENSSL
{"ssl_accepts", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT},
{"ssl_finished_accepts", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_GOOD},
{"ssl_finished_connects", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT_GOOD},
{"ssl_accept_renegotiates", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE},
{"ssl_connect_renegotiates", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT_RENEGOTIATE},
{"ssl_callback_cache_hits", (char*) 0, SHOW_SSL_CTX_SESS_CB_HITS},
{"ssl_session_cache_hits", (char*) 0, SHOW_SSL_CTX_SESS_HITS},
{"ssl_session_cache_misses", (char*) 0, SHOW_SSL_CTX_SESS_MISSES},
{"ssl_session_cache_timeouts", (char*) 0, SHOW_SSL_CTX_SESS_TIMEOUTS},
{"ssl_used_session_cache_entries",(char*) 0, SHOW_SSL_CTX_SESS_NUMBER},
{"ssl_client_connects", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT},
{"ssl_session_cache_overflows", (char*) 0, SHOW_SSL_CTX_SESS_CACHE_FULL},
{"ssl_session_cache_size", (char*) 0, SHOW_SSL_CTX_SESS_GET_CACHE_SIZE},
{"ssl_session_cache_mode", (char*) 0, SHOW_SSL_CTX_GET_SESSION_CACHE_MODE},
{"ssl_sessions_reused", (char*) 0, SHOW_SSL_SESSION_REUSED},
{"ssl_ctx_verify_mode", (char*) 0, SHOW_SSL_CTX_GET_VERIFY_MODE},
{"ssl_ctx_verify_depth", (char*) 0, SHOW_SSL_CTX_GET_VERIFY_DEPTH},
{"ssl_verify_mode", (char*) 0, SHOW_SSL_GET_VERIFY_MODE},
{"ssl_verify_depth", (char*) 0, SHOW_SSL_GET_VERIFY_DEPTH},
{"ssl_version", (char*) 0, SHOW_SSL_GET_VERSION},
{"ssl_cipher", (char*) 0, SHOW_SSL_GET_CIPHER},
{"ssl_cipher_list", (char*) 0, SHOW_SSL_GET_CIPHER_LIST},
{"ssl_default_timeout", (char*) 0, SHOW_SSL_GET_DEFAULT_TIMEOUT},
{"ssl_accepts", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT},
{"ssl_finished_accepts", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_GOOD},
{"ssl_finished_connects", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT_GOOD},
{"ssl_accept_renegotiates", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE},
{"ssl_connect_renegotiates", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT_RENEGOTIATE},
{"ssl_callback_cache_hits", (char*) 0, SHOW_SSL_CTX_SESS_CB_HITS},
{"ssl_session_cache_hits", (char*) 0, SHOW_SSL_CTX_SESS_HITS},
{"ssl_session_cache_misses", (char*) 0, SHOW_SSL_CTX_SESS_MISSES},
{"ssl_session_cache_timeouts", (char*) 0, SHOW_SSL_CTX_SESS_TIMEOUTS},
{"ssl_used_session_cache_entries",(char*) 0, SHOW_SSL_CTX_SESS_NUMBER},
{"ssl_client_connects", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT},
{"ssl_session_cache_overflows", (char*) 0, SHOW_SSL_CTX_SESS_CACHE_FULL},
{"ssl_session_cache_size", (char*) 0, SHOW_SSL_CTX_SESS_GET_CACHE_SIZE},
{"ssl_session_cache_mode", (char*) 0, SHOW_SSL_CTX_GET_SESSION_CACHE_MODE},
{"ssl_sessions_reused", (char*) 0, SHOW_SSL_SESSION_REUSED},
{"ssl_ctx_verify_mode", (char*) 0, SHOW_SSL_CTX_GET_VERIFY_MODE},
{"ssl_ctx_verify_depth", (char*) 0, SHOW_SSL_CTX_GET_VERIFY_DEPTH},
{"ssl_verify_mode", (char*) 0, SHOW_SSL_GET_VERIFY_MODE},
{"ssl_verify_depth", (char*) 0, SHOW_SSL_GET_VERIFY_DEPTH},
{"ssl_version", (char*) 0, SHOW_SSL_GET_VERSION},
{"ssl_cipher", (char*) 0, SHOW_SSL_GET_CIPHER},
{"ssl_cipher_list", (char*) 0, SHOW_SSL_GET_CIPHER_LIST},
{"ssl_default_timeout", (char*) 0, SHOW_SSL_GET_DEFAULT_TIMEOUT},
#endif /* HAVE_OPENSSL */
{"Table_locks_immediate", (char*) &locks_immediate, SHOW_LONG},
{"Table_locks_waited", (char*) &locks_waited, SHOW_LONG},

View File

@ -94,6 +94,7 @@ inline int local_thr_alarm(my_bool *A,int B __attribute__((unused)),ALARM *C __a
#ifdef MYSQL_SERVER
extern ulong bytes_sent, bytes_received;
extern pthread_mutex_t LOCK_bytes_sent , LOCK_bytes_received;
extern void query_cache_insert(NET *net, const char *packet, ulong length);
#else
#undef statistic_add
#define statistic_add(A,B,C)
@ -125,6 +126,7 @@ int my_net_init(NET *net, Vio* vio)
net->compress=0; net->reading_or_writing=0;
net->where_b = net->remain_in_buf=0;
net->last_errno=0;
net->query_cache_query=0;
if (vio != 0) /* If real connection */
{
@ -341,6 +343,10 @@ net_real_write(NET *net,const char *packet,ulong len)
my_bool net_blocking = vio_is_blocking(net->vio);
DBUG_ENTER("net_real_write");
#ifdef MYSQL_SERVER
query_cache_insert(net, packet, len);
#endif
if (net->error == 2)
DBUG_RETURN(-1); /* socket can't be used */

File diff suppressed because it is too large Load Diff

402
sql/sql_cache.h Normal file
View File

@ -0,0 +1,402 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult 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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef _SQL_CACHE_H
#define _SQL_CACHE_H
#include <semaphore.h>
/* Query cache */
/*
Can't create new free memory block if unused memory in block less
then QUERY_CACHE_MIN_ALLOCATION_UNIT.
if QUERY_CACHE_MIN_ALLOCATION_UNIT == 0 then
QUERY_CACHE_MIN_ALLOCATION_UNIT choosed automaticaly
*/
#define QUERY_CACHE_MIN_ALLOCATION_UNIT 0
/* inittial size of hashes */
#define QUERY_CACHE_DEF_QUERY_HASH_SIZE 1024
#define QUERY_CACHE_DEF_TABLE_HASH_SIZE 1024
/* minimal result data size when data allocated */
#define QUERY_CACHE_MIN_RESULT_DATA_SIZE 1024
/* memory bins size spacing (see at Query_cache::init_cache (sql_cache.cc)) */
#define QUERY_CACHE_MEM_BIN_FIRST_STEP_PWR2 4
#define QUERY_CACHE_MEM_BIN_STEP_PWR2 2
#define QUERY_CACHE_MEM_BIN_PARTS_INC 1
#define QUERY_CACHE_MEM_BIN_PARTS_MUL 1.2
#define QUERY_CACHE_MEM_BIN_SPC_LIM_PWR2 3
/* query flags masks */
#define QUERY_CACHE_CLIENT_LONG_FLAG_MASK 0x80
#define QUERY_CACHE_CHARSET_CONVERT_MASK 0x7F
/* packing parameters */
#define QUERY_CACHE_PACK_ITERATION 2
#define QUERY_CACHE_PACK_LIMIT (512*1024L)
#define TABLE_COUNTER_TYPE uint8
struct Query_cache_block;
struct Query_cache_block_table;
struct Query_cache_table;
struct Query_cache_query;
struct Query_cache_result;
class Query_cache;
struct Query_cache_block_table
{
TABLE_COUNTER_TYPE n; // numbr in table (from 0)
Query_cache_block_table *next, *prev;
Query_cache_table *parent;
inline Query_cache_block * block();
};
struct Query_cache_block
{
enum block_type {FREE, QUERY, RESULT, RES_CONT, RES_BEG,
RES_INCOMPLETE, TABLE, INCOMPLETE};
ulong length; // length of all block
ulong used; // length of data
/*
Not used **pprev, **prev because really needed access to pervious block:
*pprev to join free blocks
*prev to access to opposite side of list in cyclic sorted list
*/
Query_cache_block
*pnext,*pprev, // physical next/previous block
*next,*prev; // logical next/previous block
block_type type;
TABLE_COUNTER_TYPE n_tables; // number of tables in query
inline my_bool is_free(void) { return type == FREE; }
void init(ulong length);
void destroy();
inline uint headers_len();
inline gptr data(void);
inline Query_cache_query * query();
inline Query_cache_table * table();
inline Query_cache_result * result();
inline Query_cache_block_table * table(TABLE_COUNTER_TYPE n);
};
struct Query_cache_query
{
ulonglong limit_found_rows;
Query_cache_block * res;
NET * wri;
ulong len;
sem_t lock; // R/W lock of block
pthread_mutex_t clients_guard;
uint clients;
inline void init_n_lock();
void unlock_n_destroy();
inline ulonglong found_rows() { return limit_found_rows; }
inline void found_rows(ulonglong rows) { limit_found_rows = rows; }
inline Query_cache_block * result() { return res; }
inline void result(Query_cache_block *p) { res=p; }
inline NET * writer() { return wri; }
inline void writer(NET *p) { wri=p; }
inline ulong length() { return len; }
inline ulong add(ulong packet_len) { return(len += packet_len); }
inline void length(ulong length) { len = length; }
inline gptr query()
{
return (gptr)(((byte*)this)+
ALIGN_SIZE(sizeof(Query_cache_query)));
}
void lock_writing();
void lock_reading();
my_bool try_lock_writing();
void unlock_writing();
void unlock_reading();
static byte * cache_key(const byte *record, uint *length,
my_bool not_used);
static void free_cache(void *entry);
};
struct Query_cache_table
{
enum query_cache_table_type {OTHER=0, INNODB=1, TYPES_NUMBER=2};
inline static query_cache_table_type type_convertion(db_type type)
{
return (type == DB_TYPE_INNODB ? INNODB : OTHER);
}
char * tbl;
query_cache_table_type tp;
inline query_cache_table_type type() { return tp; }
inline void type(query_cache_table_type t) { tp = t;}
inline char * db() { return (char *) data(); }
inline char * table() { return tbl; }
inline void table(char * table) { tbl = table; }
inline gptr data()
{
return (gptr)(((byte*)this)+
ALIGN_SIZE(sizeof(Query_cache_table)));
}
static byte * cache_key(const byte *record, uint *length,
my_bool not_used);
static void free_cache(void *entry);
};
struct Query_cache_result
{
Query_cache_block *query;
inline gptr data(){return (gptr)(((byte*)this)+
ALIGN_SIZE(sizeof(Query_cache_result)));}
/* data_continue (if not whole packet contained by this block) */
inline Query_cache_block * parent() { return query; }
inline void parent (Query_cache_block *p) { query=p; }
};
extern "C" {
void query_cache_insert(THD *thd, const char *packet, ulong length);
void query_cache_end_of_result(THD *thd);
void query_cache_abort(THD *thd);
void query_cache_invalidate_by_MyISAM_filename(char* filename);
}
struct Query_cache_memory_bin
{
#ifndef DBUG_OFF
ulong size;
#endif
uint number;
Query_cache_block * free_blocks;
inline void init(ulong size)
{
#ifndef DBUG_OFF
this->size = size;
#endif
number = 0;
free_blocks = 0;
}
};
struct Query_cache_memory_bin_step
{
ulong size;
ulong increment;
uint idx;
inline void init(ulong size, uint idx, ulong increment)
{
this->size = size;
this->idx = idx;
this->increment = increment;
}
};
class Query_cache
{
protected:
byte * cache; // cache memory
Query_cache_block *first_block; // physical location block list
Query_cache_block *queries_blocks; // query list (LIFO)
Query_cache_block *tables_blocks[Query_cache_table::TYPES_NUMBER];
Query_cache_memory_bin * bins; // free block lists
Query_cache_memory_bin_step * steps; // bins spacing info
uint mem_bin_num, mem_bin_steps; // See at init_cache & find_bin
/* options */
ulong query_cache_size, query_cache_limit,
min_allocation_unit, min_result_data_size;
uint def_query_hash_size, def_table_hash_size;
/* statistics */
public:
ulong free_memory, queries_in_cache, hits, inserts, refused;
protected:
my_bool initialized;
/*
Locked when searched or changed global query or
tables lists or hashes. When operate inside
query structure locked own query block mutex
LOCK SEQUENCE (to prevent clinch):
1. structure_guard_mutex
2. query block / table block / free block
3. results blocks (only when must become free).
*/
pthread_mutex_t structure_guard_mutex;
HASH queries, tables;
/* Exclude/include from cyclic double linked list */
static void double_linked_list_exclude(Query_cache_block * point,
Query_cache_block * &list_pointer);
static void double_linked_list_simple_include(Query_cache_block * point,
Query_cache_block *
&list_pointer);
static void double_linked_list_join(Query_cache_block *head_tail,
Query_cache_block *tail_head);
/* Table key generation */
static uint filename_2_table_key (char * key, char *filename);
/* Following function work properly only when structure_guard_mutex locked */
void flush_cache();
my_bool free_old_query();
void free_query(Query_cache_block * point);
my_bool allocate_data_chain(Query_cache_block * &result_block,
ulong data_len,
Query_cache_block * query_block);
void invalidate_table(TABLE_LIST *table);
void invalidate_table(TABLE *table);
void invalidate_table_in_db(Query_cache_block *table_block,
char * db);
void invalidate_table(Query_cache_block *table_block);
my_bool register_all_tables(Query_cache_block * block,
TABLE_LIST * tables_used,
TABLE_COUNTER_TYPE tables);
my_bool insert_table(uint key_len, char * key,
Query_cache_block_table * node,
Query_cache_table::query_cache_table_type type);
void unlink_table(Query_cache_block_table * node);
Query_cache_block * get_free_block (ulong len, my_bool not_less,
ulong min);
void free_memory_block(Query_cache_block * point);
void split_block(Query_cache_block *block, ulong len);
Query_cache_block * join_free_blocks(Query_cache_block *first_block,
Query_cache_block * block_in_list);
my_bool append_next_free_block(Query_cache_block * block,
ulong add_size);
void exclude_from_free_memory_list(Query_cache_block * free_block);
void insert_into_free_memory_list(Query_cache_block * new_block);
my_bool move_by_type(byte * &border, Query_cache_block * &before,
ulong &gap, Query_cache_block * i);
uint find_bin(ulong size);
void move_to_query_list_end(Query_cache_block * block);
void insert_into_free_memory_sorted_list(Query_cache_block * new_block,
Query_cache_block * &list);
void pack_cache();
void relink(Query_cache_block * oblock,
Query_cache_block * nblock,
Query_cache_block * next,
Query_cache_block * prev,
Query_cache_block * pnext,
Query_cache_block * pprev);
my_bool join_results(ulong join_limit);
/*
Following function control structure_guard_mutex
by themself or don't need structure_guard_mutex
*/
void init();
ulong init_cache();
void make_disabled();
void free_cache(my_bool destruction);
Query_cache_block * write_block_data(ulong data_len, gptr data,
ulong header_len,
Query_cache_block::block_type type,
TABLE_COUNTER_TYPE ntab = 0,
my_bool under_guard=0);
my_bool append_result_data(Query_cache_block * &result,
ulong data_len, gptr data,
Query_cache_block * parent,
Query_cache_block * first_data_block);
my_bool write_result_data(Query_cache_block * &result,
ulong data_len, gptr data,
Query_cache_block * parent,
Query_cache_block::block_type
type=Query_cache_block::RESULT);
Query_cache_block * allocate_block(ulong len, my_bool not_less,
ulong min,
my_bool under_guard=0);
/*
If query is cachable return numder tables in query
(query without tables not cached)
*/
TABLE_COUNTER_TYPE is_cachable(THD *thd, uint query_len, char *query,
LEX *lex,
TABLE_LIST *tables_used);
public:
Query_cache(ulong query_cache_limit = ULONG_MAX,
ulong min_allocation_unit = QUERY_CACHE_MIN_ALLOCATION_UNIT,
ulong min_result_data_size = QUERY_CACHE_MIN_RESULT_DATA_SIZE,
uint def_query_hash_size = QUERY_CACHE_DEF_QUERY_HASH_SIZE,
uint def_table_hash_size = QUERY_CACHE_DEF_TABLE_HASH_SIZE
);
/* resize query cache (return real query size, 0 if disabled) */
ulong resize(ulong query_cache_size);
inline void result_size_limit(ulong limit){query_cache_limit=limit;}
/* register query in cache */
void store_query(THD *thd, TABLE_LIST *used_tables);
/*
Check if the query is in the cache and if this is true send the
data to client.
*/
my_bool send_result_to_client(THD *thd, char *query, uint query_length);
/* Remove all queries that uses any of the listed following tables */
void invalidate(TABLE_LIST *tables_used);
void invalidate(TABLE *table);
/* Remove all queries that uses tables of pointed type*/
void invalidate(Query_cache_table::query_cache_table_type type);
/* Remove all queries that uses any of the tables in following database */
void invalidate(char * db);
/* Remove all queries that uses any of the listed following table */
void invalidate_by_MyISAM_filename(char * filename);
/* Remove all queries from cache */
void flush();
/* Join result in cache in 1 block (if result length > join_limit) */
void pack(ulong join_limit = QUERY_CACHE_PACK_LIMIT,
uint iteration_limit = QUERY_CACHE_PACK_ITERATION);
void destroy();
#ifndef DBUG_OFF
void wreck(uint line, const char * message);
void bins_dump();
void cache_dump();
void queries_dump();
void tables_dump();
#endif
friend void query_cache_insert(NET *net, const char *packet, ulong length);
friend void query_cache_end_of_result(NET *net);
friend void query_cache_abort(NET *net);
};
extern Query_cache query_cache;
#endif

View File

@ -84,7 +84,7 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
host=user=priv_user=db=query=ip=0;
host_or_ip="unknown ip";
locked=killed=count_cuted_fields=some_tables_deleted=no_errors=password=
query_start_used=0;
query_start_used=safe_to_cache_query=0;
query_length=col_access=0;
query_error=0;
next_insert_id=last_insert_id=0;
@ -122,6 +122,7 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
server_status=SERVER_STATUS_AUTOCOMMIT;
update_lock_default= low_priority_updates ? TL_WRITE_LOW_PRIORITY : TL_WRITE;
options=thd_startup_options;
query_cache_type = (byte)query_cache_startup_type;
sql_mode=(uint) opt_sql_mode;
inactive_timeout=net_wait_timeout;
open_options=ha_open_options;

View File

@ -126,14 +126,16 @@ class CONVERT
void convert_array(const uchar *mapping,uchar *buff,uint length);
public:
const char *name;
CONVERT(const char *name_par,uchar *from_par,uchar *to_par)
:from_map(from_par),to_map(to_par),name(name_par) {}
uint numb;
CONVERT(const char *name_par,uchar *from_par,uchar *to_par, uint number)
:from_map(from_par),to_map(to_par),name(name_par),numb(number) {}
friend CONVERT *get_convert_set(const char *name_ptr);
inline void convert(char *a,uint length)
{
convert_array(from_map, (uchar*) a,length);
}
bool store(String *, const char *,uint);
inline uint number() { return numb; }
};
typedef struct st_copy_info {
@ -292,7 +294,10 @@ public:
bool query_start_used,last_insert_id_used,insert_id_used;
bool system_thread,in_lock_tables,global_read_lock;
bool query_error, bootstrap, cleanup_done;
bool safe_to_cache_query;
bool volatile killed;
//type of query cache processing
byte query_cache_type;
LOG_INFO* current_linfo;
// if we do a purge of binary logs, log index info of the threads
// that are currently reading it needs to be adjusted. To do that
@ -324,10 +329,10 @@ public:
{
pthread_mutex_lock(&active_vio_lock);
if(active_vio)
{
vio_close(active_vio);
active_vio = 0;
}
{
vio_close(active_vio);
active_vio = 0;
}
pthread_mutex_unlock(&active_vio_lock);
}
#endif

View File

@ -159,6 +159,7 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
if ((deleted=mysql_rm_known_files(thd, dirp, db, path,0)) >= 0 && thd)
{
ha_drop_database(path);
query_cache.invalidate(db);
if (!silent)
{
if (!thd->query)

View File

@ -183,6 +183,8 @@ cleanup:
mysql_unlock_tables(thd, thd->lock);
thd->lock=0;
}
if (deleted)
query_cache.invalidate(table_list);
delete select;
if (error >= 0) // Fatal error
send_error(&thd->net,thd->killed ? ER_SERVER_SHUTDOWN: 0);
@ -539,6 +541,7 @@ int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
close_temporary(table,0);
*fn_ext(path)=0; // Remove the .frm extension
ha_create_table(path, &create_info,1);
// We don't need to call invalidate() because this table is not in cache
if ((error= (int) !(open_temporary_table(thd, path, table_list->db,
table_list->real_name, 1))))
(void) rm_temporary_table(table_type, path);
@ -570,6 +573,7 @@ int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
bzero((char*) &create_info,sizeof(create_info));
*fn_ext(path)=0; // Remove the .frm extension
error= ha_create_table(path,&create_info,1) ? -1 : 0;
query_cache.invalidate(table_list);
if (!dont_send_ok)
{

View File

@ -310,6 +310,8 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
}
}
thd->proc_info="end";
if (info.copied || info.deleted)
query_cache.invalidate(table_list);
table->time_stamp=save_time_stamp; // Restore auto timestamp ptr
table->next_number_field=0;
thd->count_cuted_fields=0;
@ -1335,6 +1337,8 @@ void select_insert::send_error(uint errcode,const char *err)
table->file->extra(HA_EXTRA_NO_CACHE);
table->file->activate_all_index(thd);
ha_rollback(thd);
if (info.copied || info.deleted)
query_cache.invalidate(table);
}
@ -1346,6 +1350,8 @@ bool select_insert::send_eof()
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
if ((error2=ha_autocommit_or_rollback(thd,error)) && ! error)
error=error2;
if (info.copied || info.deleted)
query_cache.invalidate(table);
if (error)
{

View File

@ -1164,7 +1164,10 @@ mysql_execute_command(void)
}
if (!(res=open_and_lock_tables(thd,tables)))
{
query_cache.store_query(thd, tables);
res=handle_select(thd, lex, result);
}
else
delete result;
break;
@ -1420,6 +1423,7 @@ mysql_execute_command(void)
if (end_active_trans(thd))
res= -1;
else
{
res= mysql_alter_table(thd, select_lex->db, lex->name,
&lex->create_info,
tables, lex->create_list,
@ -1427,6 +1431,8 @@ mysql_execute_command(void)
(ORDER *) select_lex->order_list.first,
lex->drop_primary, lex->duplicates,
lex->alter_keys_onoff, lex->simple_alter);
query_cache.invalidate(tables);
}
break;
}
#endif
@ -1455,6 +1461,7 @@ mysql_execute_command(void)
goto error;
}
}
query_cache.invalidate(tables);
if (end_active_trans(thd))
res= -1;
else if (mysql_rename_tables(thd,tables))
@ -1493,6 +1500,7 @@ mysql_execute_command(void)
check_table_access(thd,SELECT_ACL | INSERT_ACL, tables))
goto error; /* purecov: inspected */
res = mysql_repair_table(thd, tables, &lex->check_opt);
query_cache.invalidate(tables);
break;
}
case SQLCOM_CHECK:
@ -1501,6 +1509,7 @@ mysql_execute_command(void)
check_table_access(thd, SELECT_ACL | EXTRA_ACL , tables))
goto error; /* purecov: inspected */
res = mysql_check_table(thd, tables, &lex->check_opt);
query_cache.invalidate(tables);
break;
}
case SQLCOM_ANALYZE:
@ -2152,13 +2161,17 @@ mysql_execute_command(void)
even if there is a problem with the OPTION_AUTO_COMMIT flag
(Which of course should never happen...)
*/
{
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
if (!ha_commit(thd))
{
send_ok(&thd->net);
}
else
res= -1;
break;
}
case SQLCOM_ROLLBACK:
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
if (!ha_rollback(thd))
@ -2451,12 +2464,21 @@ mysql_parse(THD *thd,char *inBuf,uint length)
mysql_init_query(thd);
thd->query_length = length;
LEX *lex=lex_start(thd, (uchar*) inBuf, length);
if (!yyparse() && ! thd->fatal_error)
mysql_execute_command();
thd->proc_info="freeing items";
free_items(thd); /* Free strings used by items */
lex_end(lex);
if (query_cache.send_result_to_client(thd, inBuf, length))
{
thd->safe_to_cache_query=1;
LEX *lex=lex_start(thd, (uchar*) inBuf, length);
if (!yyparse() && ! thd->fatal_error)
{
mysql_execute_command();
query_cache_end_of_result(&thd->net);
}
else
query_cache_abort(&thd->net);
thd->proc_info="freeing items";
free_items(thd); /* Free strings used by items */
lex_end(lex);
}
DBUG_VOID_RETURN;
}
@ -2982,6 +3004,15 @@ bool reload_acl_and_cache(THD *thd, uint options, TABLE_LIST *tables)
if (ha_flush_logs())
result=1;
}
if (options & REFRESH_QUERY_CACHE_FREE)
{
query_cache.pack();
options &= ~REFRESH_QUERY_CACHE; //don't flush all cache, just free memory
}
if (options & (REFRESH_TABLES | REFRESH_QUERY_CACHE))
{
query_cache.flush();
}
if (options & (REFRESH_TABLES | REFRESH_READ_LOCK))
{
if ((options & REFRESH_READ_LOCK) && thd)

View File

@ -3159,6 +3159,7 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
(thd->options & OPTION_AUTO_IS_NULL) &&
thd->insert_id())
{
query_cache_abort(&thd->net);
COND *new_cond;
if ((new_cond= new Item_func_eq(args[0],
new Item_int("last_insert_id()",

View File

@ -158,13 +158,17 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
wrong_tables.append(String(table->real_name));
}
}
if (some_tables_deleted && !dont_log_query)
if (some_tables_deleted)
{
mysql_update_log.write(thd, thd->query,thd->query_length);
if (mysql_bin_log.is_open())
query_cache.invalidate(tables);
if (!dont_log_query)
{
Query_log_event qinfo(thd, thd->query);
mysql_bin_log.write(&qinfo);
mysql_update_log.write(thd, thd->query,thd->query_length);
if (mysql_bin_log.is_open())
{
Query_log_event qinfo(thd, thd->query);
mysql_bin_log.write(&qinfo);
}
}
}
@ -1708,6 +1712,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
}
VOID(pthread_cond_broadcast(&COND_refresh));
VOID(pthread_mutex_unlock(&LOCK_open));
table_list->table=0; // Table is closed
query_cache.invalidate(table_list);
end_temporary:
sprintf(tmp_name,ER(ER_INSERT_INFO),(ulong) (copied+deleted),

View File

@ -321,6 +321,8 @@ int mysql_update(THD *thd,
mysql_unlock_tables(thd, thd->lock);
thd->lock=0;
}
if (updated)
query_cache.invalidate(table_list);
delete select;
if (error >= 0)
send_error(&thd->net,thd->killed ? ER_SERVER_SHUTDOWN : 0); /* purecov: inspected */

View File

@ -153,6 +153,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token BOOLEAN_SYM
%token BOTH
%token BY
%token CACHE_SYM
%token CASCADE
%token CHECKSUM_SYM
%token CHECK_SYM
@ -167,6 +168,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token DEFAULT
%token DELAYED_SYM
%token DELAY_KEY_WRITE_SYM
%token DEMAND_SYM
%token DESC
%token DESCRIBE
%token DIRECTORY_SYM
@ -246,6 +248,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token NO_SYM
%token NULL_SYM
%token NUM
%token OFF
%token ON
%token OPEN_SYM
%token OPTION
@ -262,6 +265,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token PRIVILEGES
%token PROCESS
%token PROCESSLIST_SYM
%token QUERY_SYM
%token RAID_0_SYM
%token RAID_STRIPED_SYM
%token RAID_TYPE
@ -285,6 +289,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token SERIALIZABLE_SYM
%token SESSION_SYM
%token SHUTDOWN
%token SQL_CACHE_SYM
%token SQL_NO_CACHE_SYM
%token SSL_SYM
%token STARTING
%token STATUS_SYM
@ -452,6 +458,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token SQL_WARNINGS
%token SQL_AUTO_IS_NULL
%token SQL_SAFE_UPDATES
%token SQL_QUERY_CACHE_TYPE_SYM
%token SQL_QUOTE_SHOW_CREATE
%token SQL_SLAVE_SKIP_COUNTER
@ -1341,7 +1348,7 @@ table_to_table:
select:
SELECT_SYM select_part2 {Select->braces=false;} union
SELECT_SYM select_part2 { Select->braces=false; } union
|
'(' SELECT_SYM select_part2 ')' {Select->braces=true;} union_opt
@ -1379,14 +1386,16 @@ select_option:
| SQL_BIG_RESULT { Select->options|= SELECT_BIG_RESULT; }
| SQL_BUFFER_RESULT { Select->options|= OPTION_BUFFER_RESULT; }
| SQL_CALC_FOUND_ROWS { Select->options|= OPTION_FOUND_ROWS; }
| SQL_NO_CACHE_SYM { current_thd->safe_to_cache_query=0; }
| SQL_CACHE_SYM { Select->options |= OPTION_TO_QUERY_CACHE; }
| ALL {}
select_lock_type:
/* empty */
| FOR_SYM UPDATE_SYM
{ Lex->lock_option= TL_WRITE; }
{ Lex->lock_option= TL_WRITE; current_thd->safe_to_cache_query=0; }
| IN_SYM SHARE_SYM MODE_SYM
{ Lex->lock_option= TL_READ_WITH_SHARED_LOCKS; }
{ Lex->lock_option= TL_READ_WITH_SHARED_LOCKS; current_thd->safe_to_cache_query=0; }
select_item_list:
select_item_list ',' select_item
@ -1554,9 +1563,18 @@ no_and_expr:
simple_expr:
simple_ident
| literal
| '@' ident_or_text SET_VAR expr { $$= new Item_func_set_user_var($2,$4); }
| '@' ident_or_text { $$= new Item_func_get_user_var($2); }
| '@' '@' ident_or_text { if (!($$= get_system_var($3))) YYABORT; }
| '@' ident_or_text SET_VAR expr
{ $$= new Item_func_set_user_var($2,$4);
current_thd->safe_to_cache_query=0;
}
| '@' ident_or_text
{ $$= new Item_func_get_user_var($2);
current_thd->safe_to_cache_query=0;
}
| '@' '@' ident_or_text
{ if (!($$= get_system_var($3))) YYABORT;
current_thd->safe_to_cache_query=0;
}
| sum_expr
| '-' expr %prec NEG { $$= new Item_func_neg($2); }
| '~' expr %prec NEG { $$= new Item_func_bit_neg($2); }
@ -1594,22 +1612,32 @@ simple_expr:
| CONCAT_WS '(' expr ',' expr_list ')'
{ $$= new Item_func_concat_ws($3, *$5); }
| CURDATE optional_braces
{ $$= new Item_func_curdate(); }
{ $$= new Item_func_curdate(); current_thd->safe_to_cache_query=0; }
| CURTIME optional_braces
{ $$= new Item_func_curtime(); }
{ $$= new Item_func_curtime(); current_thd->safe_to_cache_query=0; }
| CURTIME '(' expr ')'
{ $$= new Item_func_curtime($3); }
{
$$= new Item_func_curtime($3);
current_thd->safe_to_cache_query=0;
}
| DATE_ADD_INTERVAL '(' expr ',' INTERVAL_SYM expr interval ')'
{ $$= new Item_date_add_interval($3,$6,$7,0); }
| DATE_SUB_INTERVAL '(' expr ',' INTERVAL_SYM expr interval ')'
{ $$= new Item_date_add_interval($3,$6,$7,1); }
| DATABASE '(' ')'
{ $$= new Item_func_database(); }
{
$$= new Item_func_database();
current_thd->safe_to_cache_query=0;
}
| ELT_FUNC '(' expr ',' expr_list ')'
{ $$= new Item_func_elt($3, *$5); }
| MAKE_SET_SYM '(' expr ',' expr_list ')'
{ $$= new Item_func_make_set($3, *$5); }
| ENCRYPT '(' expr ')' { $$= new Item_func_encrypt($3); }
| ENCRYPT '(' expr ')'
{
$$= new Item_func_encrypt($3);
current_thd->safe_to_cache_query=0;
}
| ENCRYPT '(' expr ',' expr ')' { $$= new Item_func_encrypt($3,$5); }
| DECODE_SYM '(' expr ',' TEXT_STRING ')'
{ $$= new Item_func_decode($3,$5.str); }
@ -1633,7 +1661,7 @@ simple_expr:
{ $$= new Item_func_from_unixtime($3); }
| FROM_UNIXTIME '(' expr ',' expr ')'
{
$$= new Item_func_date_format(new Item_func_from_unixtime($3),$5,0);
$$= new Item_func_date_format (new Item_func_from_unixtime($3),$5,0);
}
| FIELD_FUNC '(' expr ',' expr_list ')'
{ $$= new Item_func_field($3, *$5); }
@ -1652,10 +1680,12 @@ simple_expr:
{
$$= new Item_int((char*) "last_insert_id()",
current_thd->insert_id(),21);
current_thd->safe_to_cache_query=0;
}
| LAST_INSERT_ID '(' expr ')'
{
$$= new Item_func_set_last_insert_id($3);
current_thd->safe_to_cache_query=0;
}
| LEFT '(' expr ',' expr ')'
{ $$= new Item_func_left($3,$5); }
@ -1672,14 +1702,19 @@ simple_expr:
| MONTH_SYM '(' expr ')'
{ $$= new Item_func_month($3); }
| NOW_SYM optional_braces
{ $$= new Item_func_now(); }
{ $$= new Item_func_now(); current_thd->safe_to_cache_query=0;}
| NOW_SYM '(' expr ')'
{ $$= new Item_func_now($3); }
| PASSWORD '(' expr ')' { $$= new Item_func_password($3); }
{ $$= new Item_func_now($3); current_thd->safe_to_cache_query=0;}
| PASSWORD '(' expr ')'
{
$$= new Item_func_password($3);
}
| POSITION_SYM '(' no_in_expr IN_SYM expr ')'
{ $$ = new Item_func_locate($5,$3); }
| RAND '(' expr ')' { $$= new Item_func_rand($3); }
| RAND '(' ')' { $$= new Item_func_rand(); }
| RAND '(' expr ')'
{ $$= new Item_func_rand($3); current_thd->safe_to_cache_query=0;}
| RAND '(' ')'
{ $$= new Item_func_rand(); current_thd->safe_to_cache_query=0;}
| REPLACE '(' expr ',' expr ',' expr ')'
{ $$= new Item_func_replace($3,$5,$7); }
| RIGHT '(' expr ',' expr ')'
@ -1717,6 +1752,7 @@ simple_expr:
$$ = new Item_sum_udf_str($1, *$3);
else
$$ = new Item_sum_udf_str($1);
current_thd->safe_to_cache_query=0;
}
| UDA_FLOAT_SUM '(' udf_expr_list ')'
{
@ -1724,6 +1760,7 @@ simple_expr:
$$ = new Item_sum_udf_float($1, *$3);
else
$$ = new Item_sum_udf_float($1);
current_thd->safe_to_cache_query=0;
}
| UDA_INT_SUM '(' udf_expr_list ')'
{
@ -1738,6 +1775,7 @@ simple_expr:
$$ = new Item_func_udf_str($1, *$3);
else
$$ = new Item_func_udf_str($1);
current_thd->safe_to_cache_query=0;
}
| UDF_FLOAT_FUNC '(' udf_expr_list ')'
{
@ -1745,6 +1783,7 @@ simple_expr:
$$ = new Item_func_udf_float($1, *$3);
else
$$ = new Item_func_udf_float($1);
current_thd->safe_to_cache_query=0;
}
| UDF_INT_FUNC '(' udf_expr_list ')'
{
@ -1752,15 +1791,21 @@ simple_expr:
$$ = new Item_func_udf_int($1, *$3);
else
$$ = new Item_func_udf_int($1);
current_thd->safe_to_cache_query=0;
}
| UNIQUE_USERS '(' text_literal ',' NUM ',' NUM ',' expr_list ')'
{ $$= new Item_func_unique_users($3,atoi($5.str),atoi($7.str), * $9); }
{
$$= new Item_func_unique_users($3,atoi($5.str),atoi($7.str), * $9);
}
| UNIX_TIMESTAMP '(' ')'
{ $$= new Item_func_unix_timestamp(); }
{
$$= new Item_func_unix_timestamp();
current_thd->safe_to_cache_query=0;
}
| UNIX_TIMESTAMP '(' expr ')'
{ $$= new Item_func_unix_timestamp($3); }
| USER '(' ')'
{ $$= new Item_func_user(); }
{ $$= new Item_func_user(); current_thd->safe_to_cache_query=0; }
| WEEK_SYM '(' expr ')'
{ $$= new Item_func_week($3,new Item_int((char*) "0",0,1)); }
| WEEK_SYM '(' expr ',' expr ')'
@ -1772,7 +1817,10 @@ simple_expr:
| YEARWEEK '(' expr ',' expr ')'
{ $$= new Item_func_yearweek($3, $5); }
| BENCHMARK_SYM '(' ULONG_NUM ',' expr ')'
{ $$=new Item_func_benchmark($3,$5); }
{
$$=new Item_func_benchmark($3,$5);
current_thd->safe_to_cache_query=0;
}
| EXTRACT_SYM '(' interval FROM expr ')'
{ $$=new Item_extract( $3, $5); }
@ -2101,6 +2149,7 @@ procedure_clause:
lex->proc_list.next= (byte**) &lex->proc_list.first;
if (add_proc_to_list(new Item_field(NULL,NULL,$2.str)))
YYABORT;
current_thd->safe_to_cache_query=0;
}
'(' procedure_list ')'
@ -2580,6 +2629,7 @@ flush_options:
flush_option:
table_or_tables { Lex->type|= REFRESH_TABLES; } opt_table_list
| TABLES WITH READ_SYM LOCK_SYM { Lex->type|= REFRESH_TABLES | REFRESH_READ_LOCK; }
| QUERY_SYM CACHE_SYM { Lex->type|= REFRESH_QUERY_CACHE_FREE; }
| HOSTS_SYM { Lex->type|= REFRESH_HOSTS; }
| PRIVILEGES { Lex->type|= REFRESH_GRANT; }
| LOGS_SYM { Lex->type|= REFRESH_LOG; }
@ -2602,8 +2652,9 @@ reset_options:
| reset_option
reset_option:
SLAVE { Lex->type|= REFRESH_SLAVE; }
| MASTER_SYM { Lex->type|= REFRESH_MASTER; }
SLAVE { Lex->type|= REFRESH_SLAVE; }
| MASTER_SYM { Lex->type|= REFRESH_MASTER; }
| QUERY_SYM CACHE_SYM { Lex->type|= REFRESH_QUERY_CACHE;}
purge:
PURGE
@ -2851,6 +2902,7 @@ keyword:
| BIT_SYM {}
| BOOL_SYM {}
| BOOLEAN_SYM {}
| CACHE_SYM {}
| CHANGED {}
| CHECKSUM_SYM {}
| CHECK_SYM {}
@ -2867,6 +2919,7 @@ keyword:
| DAY_SYM {}
| DIRECTORY_SYM {}
| DELAY_KEY_WRITE_SYM {}
| DEMAND_SYM {}
| DISABLE_SYM {}
| DUMPFILE {}
| DYNAMIC_SYM {}
@ -2922,12 +2975,14 @@ keyword:
| NEXT_SYM {}
| NEW_SYM {}
| NO_SYM {}
| OFF {}
| OPEN_SYM {}
| PACK_KEYS_SYM {}
| PASSWORD {}
| PREV_SYM {}
| PROCESS {}
| PROCESSLIST_SYM {}
| QUERY_SYM {}
| QUICK {}
| RAID_0_SYM {}
| RAID_CHUNKS {}
@ -2949,6 +3004,9 @@ keyword:
| SHARE_SYM {}
| SHUTDOWN {}
| SLAVE {}
| SQL_CACHE_SYM {}
| SQL_NO_CACHE_SYM {}
| SQL_QUERY_CACHE_TYPE_SYM {}
| START_SYM {}
| STATUS_SYM {}
| STOP_SYM {}
@ -3072,6 +3130,7 @@ option_value:
$3->user.str,$5))
YYABORT;
}
| SQL_QUERY_CACHE_TYPE_SYM equal query_cache_type
| '@' ident_or_text equal expr
{
Item_func_set_user_var *item = new Item_func_set_user_var($2,$4);
@ -3112,6 +3171,13 @@ option_value:
item));
}
query_cache_type:
'0' { current_thd->query_cache_type = 0; }
| OFF { current_thd->query_cache_type = 0; }
| '1' { current_thd->query_cache_type = 1; }
| ON { current_thd->query_cache_type = 1; }
| '2' { current_thd->query_cache_type = 2; }
| DEMAND_SYM { current_thd->query_cache_type = 2; }
text_or_password:
TEXT_STRING { $$=$1.str;}