Merge mysql.com:/home/jonas/src/mysql-5.0

into mysql.com:/home/jonas/src/mysql-5.0-ndb
This commit is contained in:
joreland@mysql.com 2004-11-18 20:59:03 +01:00
commit d7f6078d45
83 changed files with 1977 additions and 816 deletions

View file

@ -960,3 +960,4 @@ vio/test-sslclient
vio/test-sslserver
vio/viotest-ssl
ac_available_languages_fragment
ndb/tools/ndb_restore

View file

@ -544,6 +544,10 @@ SOURCE=..\sql\sql_test.cpp
# End Source File
# Begin Source File
SOURCE=..\sql\sql_trigger.cpp
# End Source File
# Begin Source File
SOURCE=..\sql\sql_udf.cpp
# End Source File
# Begin Source File

View file

@ -1779,6 +1779,10 @@ SOURCE=.\sql_test.cpp
# End Source File
# Begin Source File
SOURCE=.\sql_trigger.cpp
# End Source File
# Begin Source File
SOURCE=.\sql_udf.cpp
# End Source File
# Begin Source File

View file

@ -20,8 +20,8 @@
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/regex \
$(openssl_includes)
LIBS = @CLIENT_LIBS@
DEPLIB= ../libmysql/libmysqlclient.la \
@ndb_mgmclient_libs@
DEPLIB= @ndb_mgmclient_libs@ \
../libmysql/libmysqlclient.la
LDADD = @CLIENT_EXTRA_LDFLAGS@ $(DEPLIB)
bin_PROGRAMS = mysql mysqladmin mysqlcheck mysqlshow \
mysqldump mysqlimport mysqltest mysqlbinlog mysqlmanagerc mysqlmanager-pwgen

View file

@ -102,9 +102,11 @@ static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records,
int error;
uint i,found,max_links,seek,links;
uint rec_link; /* Only used with debugging */
uint hash_buckets_found;
HASH_INFO *hash_info;
error=0;
hash_buckets_found= 0;
for (i=found=max_links=seek=0 ; i < records ; i++)
{
hash_info=hp_find_hash(&keydef->block,i);
@ -128,21 +130,32 @@ static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records,
found++;
}
if (links > max_links) max_links=links;
hash_buckets_found++;
}
}
if (found != records)
{
DBUG_PRINT("error",("Found %ld of %ld records"));
DBUG_PRINT("error",("Found %ld of %ld records", found, records));
error=1;
}
if (keydef->hash_buckets != hash_buckets_found)
{
DBUG_PRINT("error",("Found %ld buckets, stats shows %ld buckets",
hash_buckets_found, keydef->hash_buckets));
error=1;
}
DBUG_PRINT("info",
("records: %ld seeks: %d max links: %d hitrate: %.2f",
("records: %ld seeks: %d max links: %d hitrate: %.2f "
"buckets: %d",
records,seek,max_links,
(float) seek / (float) (records ? records : 1)));
(float) seek / (float) (records ? records : 1),
hash_buckets_found));
if (print_status)
printf("Key: %d records: %ld seeks: %d max links: %d hitrate: %.2f\n",
printf("Key: %d records: %ld seeks: %d max links: %d "
"hitrate: %.2f buckets: %d\n",
keynr, records, seek, max_links,
(float) seek / (float) (records ? records : 1));
(float) seek / (float) (records ? records : 1),
hash_buckets_found);
return error;
}

View file

@ -18,12 +18,19 @@
#include "heapdef.h"
/* Find record according to record-position */
/*
Find record according to record-position.
The record is located by factoring position number pos into (p_0, p_1, ...)
such that
pos = SUM_i(block->level_info[i].records_under_level * p_i)
{p_0, p_1, ...} serve as indexes to descend the blocks tree.
*/
byte *hp_find_block(HP_BLOCK *block, ulong pos)
{
reg1 int i;
reg3 HP_PTRS *ptr;
reg3 HP_PTRS *ptr; /* block base ptr */
for (i=block->levels-1, ptr=block->root ; i > 0 ; i--)
{
@ -34,8 +41,18 @@ byte *hp_find_block(HP_BLOCK *block, ulong pos)
}
/* get one new block-of-records. Alloc ptr to block if neaded */
/* Interrupts are stopped to allow ha_panic in interrupts */
/*
Get one new block-of-records. Alloc ptr to block if needed
SYNOPSIS
hp_get_new_block()
block HP_BLOCK tree-like block
alloc_length OUT Amount of memory allocated from the heap
Interrupts are stopped to allow ha_panic in interrupts
RETURN
0 OK
1 Out of memory
*/
int hp_get_new_block(HP_BLOCK *block, ulong *alloc_length)
{
@ -46,6 +63,18 @@ int hp_get_new_block(HP_BLOCK *block, ulong *alloc_length)
if (block->level_info[i].free_ptrs_in_block)
break;
/*
Allocate space for leaf block plus space for upper level blocks up to
first level that has a free slot to put the pointer.
In some cases we actually allocate more then we need:
Consider e.g. a situation where we have one level 1 block and one level 0
block, the level 0 block is full and this function is called. We only
need a leaf block in this case. Nevertheless, we will get here with i=1
and will also allocate sizeof(HP_PTRS) for non-leaf block and will never
use this space.
This doesn't add much overhead - with current values of sizeof(HP_PTRS)
and my_default_record_cache_size we get about 1/128 unused memory.
*/
*alloc_length=sizeof(HP_PTRS)*i+block->records_in_block* block->recbuffer;
if (!(root=(HP_PTRS*) my_malloc(*alloc_length,MYF(0))))
return 1;
@ -60,21 +89,33 @@ int hp_get_new_block(HP_BLOCK *block, ulong *alloc_length)
dont_break(); /* Dont allow SIGHUP or SIGINT */
if ((uint) i == block->levels)
{
/* Adding a new level on top of the existing ones. */
block->levels=i+1;
/*
Use first allocated HP_PTRS as a top-level block. Put the current
block tree into the first slot of a new top-level block.
*/
block->level_info[i].free_ptrs_in_block=HP_PTRS_IN_NOD-1;
((HP_PTRS**) root)[0]= block->root;
block->root=block->level_info[i].last_blocks= root++;
}
/* Occupy the free slot we've found at level i */
block->level_info[i].last_blocks->
blocks[HP_PTRS_IN_NOD - block->level_info[i].free_ptrs_in_block--]=
(byte*) root;
/* Add a block subtree with each node having one left-most child */
for (j=i-1 ; j >0 ; j--)
{
block->level_info[j].last_blocks= root++;
block->level_info[j].last_blocks->blocks[0]=(byte*) root;
block->level_info[j].free_ptrs_in_block=HP_PTRS_IN_NOD-1;
}
/*
root now points to last (block->records_in_block* block->recbuffer)
allocated bytes. Use it as a leaf block.
*/
block->level_info[0].last_blocks= root;
allow_break(); /* Allow SIGHUP & SIGINT */
}

View file

@ -97,6 +97,7 @@ void hp_clear_keys(HP_SHARE *info)
VOID(hp_free_level(block,block->levels,block->root,(byte*) 0));
block->levels=0;
block->last_allocated=0;
keyinfo->hash_buckets= 0;
}
}
info->index_length=0;

View file

@ -128,6 +128,7 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef,
max_records);
keyinfo->delete_key= hp_delete_key;
keyinfo->write_key= hp_write_key;
keyinfo->hash_buckets= 0;
}
}
share->min_records= min_records;

View file

@ -97,8 +97,8 @@ int hp_rb_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
flag Is set if we want's to correct info->current_ptr
RETURN
0 ok
# error number
0 Ok
other Error code
*/
int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
@ -151,6 +151,8 @@ int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
pos->ptr_to_rec=empty->ptr_to_rec;
pos->next_key=empty->next_key;
}
else
keyinfo->hash_buckets--;
if (empty == lastpos) /* deleted last hash key */
DBUG_RETURN (0);
@ -187,7 +189,11 @@ int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
}
pos3= pos; /* Link pos->next after lastpos */
}
else pos3= 0; /* Different positions merge */
else
{
pos3= 0; /* Different positions merge */
keyinfo->hash_buckets--;
}
empty[0]=lastpos[0];
hp_movelink(pos3, empty, pos->next_key);

View file

@ -196,7 +196,18 @@ byte *hp_search_next(HP_INFO *info, HP_KEYDEF *keyinfo, const byte *key,
}
/* Calculate pos according to keys */
/*
Calculate position number for hash value.
SYNOPSIS
hp_mask()
hashnr Hash value
buffmax Value such that
2^(n-1) < maxlength <= 2^n = buffmax
maxlength
RETURN
Array index, in [0..maxlength)
*/
ulong hp_mask(ulong hashnr, ulong buffmax, ulong maxlength)
{
@ -205,7 +216,12 @@ ulong hp_mask(ulong hashnr, ulong buffmax, ulong maxlength)
}
/* Change link from pos to new_link */
/*
Change
next_link -> ... -> X -> pos
to
next_link -> ... -> X -> newlink
*/
void hp_movelink(HASH_INFO *pos, HASH_INFO *next_link, HASH_INFO *newlink)
{

View file

@ -36,7 +36,6 @@ int heap_write(HP_INFO *info, const byte *record)
byte *pos;
HP_SHARE *share=info->s;
DBUG_ENTER("heap_write");
#ifndef DBUG_OFF
if (info->mode & O_RDONLY)
{
@ -160,7 +159,31 @@ static byte *next_free_record_pos(HP_SHARE *info)
block_pos*info->block.recbuffer);
}
/* Write a hash-key to the hash-index */
/*
Write a hash-key to the hash-index
SYNOPSIS
info Heap table info
keyinfo Key info
record Table record to added
recpos Memory buffer where the table record will be stored if added
successfully
NOTE
Hash index uses HP_BLOCK structure as a 'growable array' of HASH_INFO
structs. Array size == number of entries in hash index.
hp_mask(hp_rec_hashnr()) maps hash entries values to hash array positions.
If there are several hash entries with the same hash array position P,
they are connected in a linked list via HASH_INFO::next_key. The first
list element is located at position P, next elements are located at
positions for which there is no record that should be located at that
position. The order of elements in the list is arbitrary.
RETURN
0 - OK
-1 - Out of memory
HA_ERR_FOUND_DUPP_KEY - Duplicate record on unique key. The record was
still added and the caller must call hp_delete_key for it.
*/
int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
const byte *record, byte *recpos)
@ -180,19 +203,54 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
DBUG_RETURN(-1); /* No more memory */
halfbuff= (long) share->blength >> 1;
pos= hp_find_hash(&keyinfo->block,(first_index=share->records-halfbuff));
/*
We're about to add one more hash array position, with hash_mask=#records.
The number of hash positions will change and some entries might need to
be relocated to the newly added position. Those entries are currently
members of the list that starts at #first_index position (this is
guaranteed by properties of hp_mask(hp_rec_hashnr(X)) mapping function)
At #first_index position currently there may be either:
a) An entry with hashnr != first_index. We don't need to move it.
or
b) A list of items with hash_mask=first_index. The list contains entries
of 2 types:
1) entries that should be relocated to the list that starts at new
position we're adding ('uppper' list)
2) entries that should be left in the list starting at #first_index
position ('lower' list)
*/
if (pos != empty) /* If some records */
{
do
{
hashnr = hp_rec_hashnr(keyinfo, pos->ptr_to_rec);
if (flag == 0) /* First loop; Check if ok */
if (flag == 0)
{
/*
First loop, bail out if we're dealing with case a) from above
comment
*/
if (hp_mask(hashnr, share->blength, share->records) != first_index)
break;
}
/*
flag & LOWFIND - found a record that should be put into lower position
flag & LOWUSED - lower position occupied by the record
Same for HIGHFIND and HIGHUSED and 'upper' position
gpos - ptr to last element in lower position's list
gpos2 - ptr to last element in upper position's list
ptr_to_rec - ptr to last entry that should go into lower list.
ptr_to_rec2 - same for upper list.
*/
if (!(hashnr & halfbuff))
{ /* Key will not move */
{
/* Key should be put into 'lower' list */
if (!(flag & LOWFIND))
{
/* key is the first element to go into lower position */
if (flag & HIGHFIND)
{
flag=LOWFIND | HIGHFIND;
@ -203,16 +261,21 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
}
else
{
flag=LOWFIND | LOWUSED; /* key isn't changed */
/*
We can only get here at first iteration: key is at 'lower'
position pos and should be left here.
*/
flag=LOWFIND | LOWUSED;
gpos=pos;
ptr_to_rec=pos->ptr_to_rec;
}
}
else
{
{
/* Already have another key for lower position */
if (!(flag & LOWUSED))
{
/* Change link of previous LOW-key */
/* Change link of previous lower-list key */
gpos->ptr_to_rec=ptr_to_rec;
gpos->next_key=pos;
flag= (flag & HIGHFIND) | (LOWFIND | LOWUSED);
@ -222,19 +285,21 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
}
}
else
{ /* key will be moved */
{
/* key will be put into 'higher' list */
if (!(flag & HIGHFIND))
{
flag= (flag & LOWFIND) | HIGHFIND;
/* key shall be moved to the last (empty) position */
gpos2 = empty; empty=pos;
gpos2= empty;
empty= pos;
ptr_to_rec2=pos->ptr_to_rec;
}
else
{
if (!(flag & HIGHUSED))
{
/* Change link of previous hash-key and save */
/* Change link of previous upper-list key and save */
gpos2->ptr_to_rec=ptr_to_rec2;
gpos2->next_key=pos;
flag= (flag & LOWFIND) | (HIGHFIND | HIGHUSED);
@ -245,6 +310,15 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
}
}
while ((pos=pos->next_key));
if ((flag & (LOWFIND | HIGHFIND)) == (LOWFIND | HIGHFIND))
{
/*
If both 'higher' and 'lower' list have at least one element, now
there are two hash buckets instead of one.
*/
keyinfo->hash_buckets++;
}
if ((flag & (LOWFIND | LOWUSED)) == LOWFIND)
{
@ -265,6 +339,7 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
{
pos->ptr_to_rec=recpos;
pos->next_key=0;
keyinfo->hash_buckets++;
}
else
{
@ -280,6 +355,7 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
}
else
{
keyinfo->hash_buckets++;
pos->ptr_to_rec=recpos;
pos->next_key=0;
hp_movelink(pos, gpos, empty);

View file

@ -63,18 +63,48 @@ typedef struct st_heap_ptrs
struct st_level_info
{
uint free_ptrs_in_block,records_under_level;
HP_PTRS *last_blocks; /* pointers to HP_PTRS or records */
/* Number of unused slots in *last_blocks HP_PTRS block (0 for 0th level) */
uint free_ptrs_in_block;
/*
Maximum number of records that can be 'contained' inside of each element
of last_blocks array. For level 0 - 1, for level 1 - HP_PTRS_IN_NOD, for
level 2 - HP_PTRS_IN_NOD^2 and so forth.
*/
uint records_under_level;
/*
Ptr to last allocated HP_PTRS (or records buffer for level 0) on this
level.
*/
HP_PTRS *last_blocks;
};
typedef struct st_heap_block /* The data is saved in blocks */
/*
Heap table records and hash index entries are stored in HP_BLOCKs.
HP_BLOCK is used as a 'growable array' of fixed-size records. Size of record
is recbuffer bytes.
The internal representation is as follows:
HP_BLOCK is a hierarchical structure of 'blocks'.
A block at level 0 is an array records_in_block records.
A block at higher level is an HP_PTRS structure with pointers to blocks at
lower levels.
At the highest level there is one top block. It is stored in HP_BLOCK::root.
See hp_find_block for a description of how record pointer is obtained from
its index.
See hp_get_new_block
*/
typedef struct st_heap_block
{
HP_PTRS *root;
HP_PTRS *root; /* Top-level block */
struct st_level_info level_info[HP_MAX_LEVELS+1];
uint levels;
uint records_in_block; /* Records in a heap-block */
uint levels; /* number of used levels */
uint records_in_block; /* Records in one heap-block */
uint recbuffer; /* Length of one saved record */
ulong last_allocated; /* Blocks allocated, used by keys */
ulong last_allocated; /* number of records there is allocated space for */
} HP_BLOCK;
struct st_heap_info; /* For referense */
@ -87,6 +117,11 @@ typedef struct st_hp_keydef /* Key definition with open */
uint8 algorithm; /* HASH / BTREE */
HA_KEYSEG *seg;
HP_BLOCK block; /* Where keys are saved */
/*
Number of buckets used in hash table. Used only to provide
#records estimates for heap key scans.
*/
ha_rows hash_buckets;
TREE rb_tree;
int (*write_key)(struct st_heap_info *info, struct st_hp_keydef *keyinfo,
const byte *record, byte *recpos);
@ -102,7 +137,7 @@ typedef struct st_heap_share
ulong min_records,max_records; /* Params to open */
ulong data_length,index_length;
uint records; /* records */
uint blength;
uint blength; /* records rounded up to 2^n */
uint deleted; /* Deleted records in database */
uint reclength; /* Length of one record */
uint changed;

View file

@ -2136,6 +2136,30 @@ buf_print(void)
ut_a(buf_validate());
}
/*************************************************************************
Returns the number of latched pages in the buffer pool. */
ulint
buf_get_latched_pages_number(void)
{
buf_block_t* block;
ulint i;
ulint fixed_pages_number = 0;
mutex_enter(&(buf_pool->mutex));
for (i = 0; i < buf_pool->curr_size; i++) {
block = buf_pool_get_nth_block(buf_pool, i);
if ((block->buf_fix_count != 0) || (block->io_fix != 0))
fixed_pages_number++;
}
mutex_exit(&(buf_pool->mutex));
return fixed_pages_number;
}
/*************************************************************************
Returns the number of pending buf pool ios. */

View file

@ -273,6 +273,10 @@ buf_flush_buffered_writes(void)
}
}
/* increment the doublewrite flushed pages counter */
srv_dblwr_pages_written+= trx_doublewrite->first_free;
srv_dblwr_writes++;
if (trx_doublewrite->first_free > TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) {
len = TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE;
} else {
@ -901,6 +905,9 @@ buf_flush_batch(
(ulong) page_count);
}
if (page_count != ULINT_UNDEFINED)
srv_buf_pool_flushed+= page_count;
return(page_count);
}

View file

@ -432,6 +432,7 @@ loop:
/* No free block was found: try to flush the LRU list */
buf_flush_free_margin();
++srv_buf_pool_wait_free;
os_aio_simulated_wake_handler_threads();

View file

@ -20,6 +20,10 @@ Created 11/5/1995 Heikki Tuuri
#include "os0file.h"
#include "srv0start.h"
extern ulint srv_read_ahead_rnd;
extern ulint srv_read_ahead_seq;
extern ulint srv_buf_pool_reads;
/* The size in blocks of the area where the random read-ahead algorithm counts
the accessed pages when deciding whether to read-ahead */
#define BUF_READ_AHEAD_RANDOM_AREA BUF_READ_AHEAD_AREA
@ -291,6 +295,7 @@ buf_read_ahead_random(
(ulong) count);
}
++srv_read_ahead_rnd;
return(count);
}
@ -323,6 +328,7 @@ buf_read_page(
count2 = buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
tablespace_version, offset);
srv_buf_pool_reads+= count2;
if (err == DB_TABLESPACE_DELETED) {
ut_print_timestamp(stderr);
fprintf(stderr,
@ -575,6 +581,7 @@ buf_read_ahead_linear(
(ulong) space, (ulong) offset, (ulong) count);
}
++srv_read_ahead_seq;
return(count);
}

View file

@ -88,6 +88,9 @@ but in the MySQL Embedded Server Library and ibbackup it is not the default
directory, and we must set the base file path explicitly */
const char* fil_path_to_mysql_datadir = ".";
/* The number of fsyncs done to the log */
ulint fil_n_log_flushes = 0;
ulint fil_n_pending_log_flushes = 0;
ulint fil_n_pending_tablespace_flushes = 0;
@ -3671,6 +3674,12 @@ fil_io(
mode = OS_AIO_NORMAL;
}
if (type == OS_FILE_READ) {
srv_data_read+= len;
} else if (type == OS_FILE_WRITE) {
srv_data_written+= len;
}
/* Reserve the fil_system mutex and make sure that we can open at
least one file while holding it, if the file is not already open */
@ -3956,6 +3965,7 @@ fil_flush(
fil_n_pending_tablespace_flushes++;
} else {
fil_n_pending_log_flushes++;
fil_n_log_flushes++;
}
#ifdef __WIN__
if (node->is_raw_disk) {

View file

@ -58,6 +58,8 @@ extern buf_pool_t* buf_pool; /* The buffer pool of the database */
extern ibool buf_debug_prints;/* If this is set TRUE, the program
prints info whenever read or flush
occurs */
extern ulint srv_buf_pool_write_requests; /* variable to count write request
issued */
/************************************************************************
Creates the buffer pool. */
@ -497,6 +499,12 @@ void
buf_print(void);
/*============*/
/*************************************************************************
Returns the number of latched pages in the buffer pool. */
ulint
buf_get_latched_pages_number(void);
/*==============================*/
/*************************************************************************
Returns the number of pending buf pool ios. */
ulint

View file

@ -61,6 +61,8 @@ buf_flush_note_modification(
ut_ad(ut_dulint_cmp(block->oldest_modification,
mtr->start_lsn) <= 0);
}
++srv_buf_pool_write_requests;
}
/************************************************************************

View file

@ -89,6 +89,8 @@ extern fil_addr_t fil_addr_null;
#define FIL_TABLESPACE 501
#define FIL_LOG 502
extern ulint fil_n_log_flushes;
extern ulint fil_n_pending_log_flushes;
extern ulint fil_n_pending_tablespace_flushes;

View file

@ -24,6 +24,9 @@ extern ibool os_aio_print_debug;
extern ulint os_file_n_pending_preads;
extern ulint os_file_n_pending_pwrites;
extern ulint os_n_pending_reads;
extern ulint os_n_pending_writes;
#ifdef __WIN__
/* We define always WIN_ASYNC_IO, and check at run-time whether

View file

@ -184,6 +184,63 @@ i/o handler thread */
extern const char* srv_io_thread_op_info[];
extern const char* srv_io_thread_function[];
/* the number of the log write requests done */
extern ulint srv_log_write_requests;
/* the number of physical writes to the log performed */
extern ulint srv_log_writes;
/* amount of data written to the log files in bytes */
extern ulint srv_os_log_written;
/* amount of writes being done to the log files */
extern ulint srv_os_log_pending_writes;
/* we increase this counter, when there we don't have enough space in the
log buffer and have to flush it */
extern ulint srv_log_waits;
/* variable that counts amount of data read in total (in bytes) */
extern ulint srv_data_read;
/* here we count the amount of data written in total (in bytes) */
extern ulint srv_data_written;
/* this variable counts the amount of times, when the doublewrite buffer
was flushed */
extern ulint srv_dblwr_writes;
/* here we store the number of pages that have been flushed to the
doublewrite buffer */
extern ulint srv_dblwr_pages_written;
/* in this variable we store the number of write requests issued */
extern ulint srv_buf_pool_write_requests;
/* here we store the number of times when we had to wait for a free page
in the buffer pool. It happens when the buffer pool is full and we need
to make a flush, in order to be able to read or create a page. */
extern ulint srv_buf_pool_wait_free;
/* variable to count the number of pages that were written from the
buffer pool to disk */
extern ulint srv_buf_pool_flushed;
/* variable to count the number of buffer pool reads that led to the
reading of a disk page */
extern ulint srv_buf_pool_reads;
/* variable to count the number of sequential read-aheads were done */
extern ulint srv_read_ahead_seq;
/* variable to count the number of random read-aheads were done */
extern ulint srv_read_ahead_rnd;
/* In this structure we store status variables to be passed to MySQL */
typedef struct export_var_struct export_struc;
extern export_struc export_vars;
typedef struct srv_sys_struct srv_sys_t;
/* The server system */
@ -400,7 +457,12 @@ void
srv_printf_innodb_monitor(
/*======================*/
FILE* file); /* in: output stream */
/************************************************************************
Function to pass InnoDB status variables to MySQL */
void
srv_export_innodb_status(void);
/*=====================*/
/* Types for the threads existing in the system. Threads of types 4 - 9
are called utility threads. Note that utility threads are mainly disk
@ -426,6 +488,48 @@ typedef struct srv_slot_struct srv_slot_t;
/* Thread table is an array of slots */
typedef srv_slot_t srv_table_t;
/* In this structure we store status variables to be passed to MySQL */
struct export_var_struct{
ulint innodb_data_pending_reads;
ulint innodb_data_pending_writes;
ulint innodb_data_pending_fsyncs;
ulint innodb_data_fsyncs;
ulint innodb_data_read;
ulint innodb_data_writes;
ulint innodb_data_written;
ulint innodb_data_reads;
ulint innodb_buffer_pool_pages_total;
ulint innodb_buffer_pool_pages_data;
ulint innodb_buffer_pool_pages_dirty;
ulint innodb_buffer_pool_pages_misc;
ulint innodb_buffer_pool_pages_free;
ulint innodb_buffer_pool_pages_latched;
ulint innodb_buffer_pool_read_requests;
ulint innodb_buffer_pool_reads;
ulint innodb_buffer_pool_wait_free;
ulint innodb_buffer_pool_pages_flushed;
ulint innodb_buffer_pool_write_requests;
ulint innodb_buffer_pool_read_ahead_seq;
ulint innodb_buffer_pool_read_ahead_rnd;
ulint innodb_dblwr_pages_written;
ulint innodb_dblwr_writes;
ulint innodb_log_waits;
ulint innodb_log_write_requests;
ulint innodb_log_writes;
ulint innodb_os_log_written;
ulint innodb_os_log_fsyncs;
ulint innodb_os_log_pending_writes;
ulint innodb_os_log_pending_fsyncs;
ulint innodb_page_size;
ulint innodb_pages_created;
ulint innodb_pages_read;
ulint innodb_pages_written;
ulint innodb_rows_read;
ulint innodb_rows_inserted;
ulint innodb_rows_updated;
ulint innodb_rows_deleted;
};
/* The server system struct */
struct srv_sys_struct{
os_event_t operational; /* created threads must wait for the

View file

@ -190,6 +190,8 @@ loop:
log_buffer_flush_to_disk();
srv_log_waits++;
ut_ad(++count < 50);
goto loop;
@ -292,6 +294,8 @@ part_loop:
if (str_len > 0) {
goto part_loop;
}
srv_log_write_requests++;
}
/****************************************************************
@ -1112,11 +1116,15 @@ log_group_file_header_flush(
if (log_do_write) {
log_sys->n_log_ios++;
srv_os_log_pending_writes++;
fil_io(OS_FILE_WRITE | OS_FILE_LOG, TRUE, group->space_id,
dest_offset / UNIV_PAGE_SIZE,
dest_offset % UNIV_PAGE_SIZE,
OS_FILE_LOG_BLOCK_SIZE,
buf, group);
srv_os_log_pending_writes--;
}
}
@ -1181,6 +1189,8 @@ loop:
log_group_file_header_flush(group,
next_offset / group->file_size, start_lsn);
srv_os_log_written+= OS_FILE_LOG_BLOCK_SIZE;
srv_log_writes++;
}
if ((next_offset % group->file_size) + len > group->file_size) {
@ -1225,9 +1235,16 @@ loop:
if (log_do_write) {
log_sys->n_log_ios++;
srv_os_log_pending_writes++;
fil_io(OS_FILE_WRITE | OS_FILE_LOG, TRUE, group->space_id,
next_offset / UNIV_PAGE_SIZE,
next_offset % UNIV_PAGE_SIZE, write_len, buf, group);
srv_os_log_pending_writes--;
srv_os_log_written+= write_len;
srv_log_writes++;
}
if (write_len < len) {

View file

@ -155,6 +155,10 @@ os_mutex_t os_file_count_mutex;
ulint os_file_n_pending_preads = 0;
ulint os_file_n_pending_pwrites = 0;
/* These are not protected by any mutex */
ulint os_n_pending_writes = 0;
ulint os_n_pending_reads = 0;
/***************************************************************************
Gets the operating system version. Currently works only on Windows. */
@ -1987,8 +1991,12 @@ try_again:
goto error_handling;
}
os_n_pending_reads++;
ret = ReadFile(file, buf, n, &len, NULL);
os_n_pending_reads--;
os_mutex_exit(os_file_seek_mutexes[i]);
if (ret && len == n) {
@ -2001,8 +2009,12 @@ try_again:
os_bytes_read_since_printout += n;
try_again:
os_n_pending_reads++;
ret = os_file_pread(file, buf, n, offset, offset_high);
os_n_pending_reads--;
if ((ulint)ret == n) {
return(TRUE);
@ -2090,8 +2102,12 @@ try_again:
goto error_handling;
}
os_n_pending_reads++;
ret = ReadFile(file, buf, n, &len, NULL);
os_n_pending_reads--;
os_mutex_exit(os_file_seek_mutexes[i]);
if (ret && len == n) {
@ -2104,8 +2120,12 @@ try_again:
os_bytes_read_since_printout += n;
try_again:
os_n_pending_reads++;
ret = os_file_pread(file, buf, n, offset, offset_high);
os_n_pending_reads--;
if ((ulint)ret == n) {
return(TRUE);
@ -2187,7 +2207,11 @@ retry:
return(FALSE);
}
os_n_pending_writes++;
ret = WriteFile(file, buf, n, &len, NULL);
os_n_pending_writes--;
/* Always do fsync to reduce the probability that when the OS crashes,
a database page is only partially physically written to disk. */
@ -2248,8 +2272,12 @@ retry:
#else
ssize_t ret;
os_n_pending_writes++;
ret = os_file_pwrite(file, buf, n, offset, offset_high);
os_n_pending_writes--;
if ((ulint)ret == n) {
return(TRUE);

View file

@ -186,6 +186,61 @@ that during a time of heavy update/insert activity. */
ulint srv_max_buf_pool_modified_pct = 90;
/* variable counts amount of data read in total (in bytes) */
ulint srv_data_read = 0;
/* here we count the amount of data written in total (in bytes) */
ulint srv_data_written = 0;
/* the number of the log write requests done */
ulint srv_log_write_requests = 0;
/* the number of physical writes to the log performed */
ulint srv_log_writes = 0;
/* amount of data written to the log files in bytes */
ulint srv_os_log_written = 0;
/* amount of writes being done to the log files */
ulint srv_os_log_pending_writes = 0;
/* we increase this counter, when there we don't have enough space in the
log buffer and have to flush it */
ulint srv_log_waits = 0;
/* this variable counts the amount of times, when the doublewrite buffer
was flushed */
ulint srv_dblwr_writes = 0;
/* here we store the number of pages that have been flushed to the
doublewrite buffer */
ulint srv_dblwr_pages_written = 0;
/* in this variable we store the number of write requests issued */
ulint srv_buf_pool_write_requests = 0;
/* here we store the number of times when we had to wait for a free page
in the buffer pool. It happens when the buffer pool is full and we need
to make a flush, in order to be able to read or create a page. */
ulint srv_buf_pool_wait_free = 0;
/* variable to count the number of pages that were written from buffer
pool to the disk */
ulint srv_buf_pool_flushed = 0;
/* variable to count the number of buffer pool reads that led to the
reading of a disk page */
ulint srv_buf_pool_reads = 0;
/* variable to count the number of sequential read-aheads */
ulint srv_read_ahead_seq = 0;
/* variable to count the number of random read-aheads */
ulint srv_read_ahead_rnd = 0;
/* structure to pass status variables to MySQL */
export_struc export_vars;
/* If the following is != 0 we do not allow inserts etc. This protects
the user from forgetting the innodb_force_recovery keyword to my.cnf */
@ -1619,6 +1674,57 @@ srv_printf_innodb_monitor(
fflush(file);
}
/**********************************************************************
Function to pass InnoDB status variables to MySQL */
void
srv_export_innodb_status(void)
{
mutex_enter(&srv_innodb_monitor_mutex);
export_vars.innodb_data_pending_reads= os_n_pending_reads;
export_vars.innodb_data_pending_writes= os_n_pending_writes;
export_vars.innodb_data_pending_fsyncs=
fil_n_pending_log_flushes + fil_n_pending_tablespace_flushes;
export_vars.innodb_data_fsyncs= os_n_fsyncs;
export_vars.innodb_data_read= srv_data_read;
export_vars.innodb_data_reads= os_n_file_reads;
export_vars.innodb_data_writes= os_n_file_writes;
export_vars.innodb_data_written= srv_data_written;
export_vars.innodb_buffer_pool_read_requests= buf_pool->n_page_gets;
export_vars.innodb_buffer_pool_write_requests= srv_buf_pool_write_requests;
export_vars.innodb_buffer_pool_wait_free= srv_buf_pool_wait_free;
export_vars.innodb_buffer_pool_pages_flushed= srv_buf_pool_flushed;
export_vars.innodb_buffer_pool_reads= srv_buf_pool_reads;
export_vars.innodb_buffer_pool_read_ahead_rnd= srv_read_ahead_rnd;
export_vars.innodb_buffer_pool_read_ahead_seq= srv_read_ahead_seq;
export_vars.innodb_buffer_pool_pages_data= UT_LIST_GET_LEN(buf_pool->LRU);
export_vars.innodb_buffer_pool_pages_dirty= UT_LIST_GET_LEN(buf_pool->flush_list);
export_vars.innodb_buffer_pool_pages_free= UT_LIST_GET_LEN(buf_pool->free);
export_vars.innodb_buffer_pool_pages_latched= buf_get_latched_pages_number();
export_vars.innodb_buffer_pool_pages_total= buf_pool->curr_size;
export_vars.innodb_buffer_pool_pages_misc= buf_pool->max_size -
UT_LIST_GET_LEN(buf_pool->LRU) - UT_LIST_GET_LEN(buf_pool->free);
export_vars.innodb_page_size= UNIV_PAGE_SIZE;
export_vars.innodb_log_waits= srv_log_waits;
export_vars.innodb_os_log_written= srv_os_log_written;
export_vars.innodb_os_log_fsyncs= fil_n_log_flushes;
export_vars.innodb_os_log_pending_fsyncs= fil_n_pending_log_flushes;
export_vars.innodb_os_log_pending_writes= srv_os_log_pending_writes;
export_vars.innodb_log_write_requests= srv_log_write_requests;
export_vars.innodb_log_writes= srv_log_writes;
export_vars.innodb_dblwr_pages_written= srv_dblwr_pages_written;
export_vars.innodb_dblwr_writes= srv_dblwr_writes;
export_vars.innodb_pages_created= buf_pool->n_pages_created;
export_vars.innodb_pages_read= buf_pool->n_pages_read;
export_vars.innodb_pages_written= buf_pool->n_pages_written;
export_vars.innodb_rows_read= srv_n_rows_read;
export_vars.innodb_rows_inserted= srv_n_rows_inserted;
export_vars.innodb_rows_updated= srv_n_rows_updated;
export_vars.innodb_rows_deleted= srv_n_rows_deleted;
mutex_exit(&srv_innodb_monitor_mutex);
}
/*************************************************************************
A thread which wakes up threads whose lock wait may have lasted too long.
This also prints the info output by various InnoDB monitors. */

View file

@ -164,9 +164,9 @@ static void _ftb_parse_query(FTB *ftb, byte **start, byte *end,
if (param.trunc) ftbw->flags|=FTB_FLAG_TRUNC;
ftbw->weight=weight;
ftbw->up=up;
ftbw->docid[0]=ftbw->docid[1]=HA_POS_ERROR;
ftbw->docid[0]=ftbw->docid[1]=HA_OFFSET_ERROR;
ftbw->ndepth= (param.yesno<0) + depth;
ftbw->key_root=HA_POS_ERROR;
ftbw->key_root=HA_OFFSET_ERROR;
memcpy(ftbw->word+1, w.pos, w.len);
ftbw->word[0]=w.len;
if (param.yesno > 0) up->ythresh++;
@ -181,7 +181,7 @@ static void _ftb_parse_query(FTB *ftb, byte **start, byte *end,
ftbe->weight=weight;
ftbe->up=up;
ftbe->ythresh=ftbe->yweaks=0;
ftbe->docid[0]=ftbe->docid[1]=HA_POS_ERROR;
ftbe->docid[0]=ftbe->docid[1]=HA_OFFSET_ERROR;
if ((ftbe->quot=param.quot)) ftb->with_scan|=2;
if (param.yesno > 0) up->ythresh++;
_ftb_parse_query(ftb, start, end, ftbe, depth+1);
@ -259,7 +259,7 @@ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search)
{
if (!ftbw->off || !(ftbw->flags & FTB_FLAG_TRUNC))
{
ftbw->docid[0]=HA_POS_ERROR;
ftbw->docid[0]=HA_OFFSET_ERROR;
if ((ftbw->flags & FTB_FLAG_YES) && ftbw->up->up==0)
{
/*
@ -346,7 +346,7 @@ static void _ftb_init_index_search(FT_INFO *ftb)
ftbe->up->ythresh - ftbe->up->yweaks >1) /* 1 */
{
FTB_EXPR *top_ftbe=ftbe->up->up;
ftbw->docid[0]=HA_POS_ERROR;
ftbw->docid[0]=HA_OFFSET_ERROR;
for (ftbe=ftbw->up; ftbe != top_ftbe; ftbe=ftbe->up)
if (ftbe->flags & FTB_FLAG_YES)
ftbe->yweaks++;
@ -387,7 +387,7 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query,
ftb->charset= ((keynr==NO_SUCH_KEY) ?
default_charset_info : info->s->keyinfo[keynr].seg->charset);
ftb->with_scan=0;
ftb->lastpos=HA_POS_ERROR;
ftb->lastpos=HA_OFFSET_ERROR;
bzero(& ftb->no_dupes, sizeof(TREE));
init_alloc_root(&ftb->mem_root, 1024, 1024);
@ -410,7 +410,7 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query,
ftbe->quot=0;
ftbe->up=0;
ftbe->ythresh=ftbe->yweaks=0;
ftbe->docid[0]=ftbe->docid[1]=HA_POS_ERROR;
ftbe->docid[0]=ftbe->docid[1]=HA_OFFSET_ERROR;
ftb->root=ftbe;
_ftb_parse_query(ftb, &query, query+query_len, ftbe, 0);
ftb->list=(FTB_WORD **)alloc_root(&ftb->mem_root,
@ -561,7 +561,7 @@ int ft_boolean_read_next(FT_INFO *ftb, char *record)
while (ftb->state == INDEX_SEARCH &&
(curdoc=((FTB_WORD *)queue_top(& ftb->queue))->docid[0]) !=
HA_POS_ERROR)
HA_OFFSET_ERROR)
{
while (curdoc == (ftbw=(FTB_WORD *)queue_top(& ftb->queue))->docid[0])
{
@ -615,7 +615,7 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length)
const byte *end;
my_off_t docid=ftb->info->lastpos;
if (docid == HA_POS_ERROR)
if (docid == HA_OFFSET_ERROR)
return -2.0;
if (!ftb->queue.elements)
return 0;
@ -627,9 +627,9 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length)
for (i=0; i < ftb->queue.elements; i++)
{
ftb->list[i]->docid[1]=HA_POS_ERROR;
ftb->list[i]->docid[1]=HA_OFFSET_ERROR;
for (x=ftb->list[i]->up; x; x=x->up)
x->docid[1]=HA_POS_ERROR;
x->docid[1]=HA_OFFSET_ERROR;
}
}

View file

@ -2,7 +2,7 @@ drop table if exists t1;
set sql_mode="MySQL40";
select @@sql_mode;
@@sql_mode
NO_FIELD_OPTIONS,MYSQL40
NO_FIELD_OPTIONS,MYSQL40,BROKEN_NOT
set @@sql_mode="ANSI";
select @@sql_mode;
@@sql_mode

View file

@ -134,3 +134,10 @@ select * from t1 where firstname='john' and firstname like binary 'John';
firstname lastname
John Doe
drop table t1;
create table t1 (a binary);
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` binary(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;

View file

@ -33,6 +33,24 @@ a
SELECT * FROM t1 where (1 AND a) IS NULL;
a
NULL
set sql_mode='broken_not';
select * from t1 where not a between 2 and 3;
a
set sql_mode=default;
select * from t1 where not a between 2 and 3;
a
0
1
select a, a is false, a is true, a is unknown from t1;
a a is false a is true a is unknown
0 1 0 0
1 0 1 0
NULL 0 0 1
select a, a is not false, a is not true, a is not unknown from t1;
a a is not false a is not true a is not unknown
0 0 1 1
1 1 0 1
NULL 1 1 0
SET @a=0, @b=0;
SELECT * FROM t1 WHERE NULL AND (@a:=@a+1);
a

View file

@ -487,3 +487,20 @@ prepare stmt1 from @str2;
execute stmt1 using @ivar;
?
1234
SET TIMESTAMP=10000;
create table t2 (c char(30)) charset=ucs2;
set @v=convert('abc' using ucs2);
reset master;
insert into t2 values (@v);
show binlog events from 95;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 95 User var 1 135 @`v`=_ucs2 0x006100620063 COLLATE ucs2_general_ci
master-bin.000001 135 Query 1 218 use `test`; insert into t2 values (@v)
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
SET @`v`:=_ucs2 0x006100620063 COLLATE ucs2_general_ci;
use test;
SET TIMESTAMP=10000;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1;
SET @@session.sql_mode=0;
insert into t2 values (@v);
drop table t2;

View file

@ -382,3 +382,12 @@ s
pära para para
para para para
DROP TABLE t1;
CREATE TABLE t1 (h text, FULLTEXT (h));
INSERT INTO t1 VALUES ('Jesses Hasse Ling and his syncopators of Swing');
REPAIR TABLE t1;
Table Op Msg_type Msg_text
test.t1 repair status OK
select count(*) from t1;
count(*)
1
drop table t1;

View file

@ -4,7 +4,7 @@ insert into t1 values(1,1),(2,2),(3,3),(4,4);
delete from t1 where a=1 or a=0;
show keys from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 0 PRIMARY 1 a NULL NULL NULL NULL HASH
t1 0 PRIMARY 1 a NULL 3 NULL NULL HASH
select * from t1;
a b
2 2
@ -169,7 +169,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL btn NULL NULL NULL 11 Using where
explain select * from t1 where btn="a" and new_col="a";
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref btn btn 11 const,const 10 Using where
1 SIMPLE t1 ref btn btn 11 const,const 2 Using where
drop table t1;
CREATE TABLE t1 (
a int default NULL,
@ -182,7 +182,7 @@ SELECT * FROM t1 WHERE a=NULL;
a b
explain SELECT * FROM t1 WHERE a IS NULL;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a a 5 const 10 Using where
1 SIMPLE t1 ref a a 5 const 1 Using where
SELECT * FROM t1 WHERE a<=>NULL;
a b
NULL 99
@ -204,7 +204,7 @@ key a (a)
INSERT INTO t1 VALUES (10), (10), (10);
EXPLAIN SELECT * FROM t1 WHERE a=10;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a a 5 const 10 Using where
1 SIMPLE t1 ref a a 5 const 3 Using where
SELECT * FROM t1 WHERE a=10;
a
10

View file

@ -1,10 +1,10 @@
drop table if exists t1;
drop table if exists t1,t2;
create table t1 (a int not null,b int not null, primary key using HASH (a)) engine=heap comment="testing heaps" avg_row_length=100 min_rows=1 max_rows=100;
insert into t1 values(1,1),(2,2),(3,3),(4,4);
delete from t1 where a=1 or a=0;
show keys from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 0 PRIMARY 1 a NULL NULL NULL NULL HASH
t1 0 PRIMARY 1 a NULL 3 NULL NULL HASH
select * from t1;
a b
2 2
@ -169,7 +169,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL btn NULL NULL NULL 11 Using where
explain select * from t1 where btn="a" and new_col="a";
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref btn btn 11 const,const 10 Using where
1 SIMPLE t1 ref btn btn 11 const,const 2 Using where
drop table t1;
CREATE TABLE t1 (
a int default NULL,
@ -182,7 +182,7 @@ SELECT * FROM t1 WHERE a=NULL;
a b
explain SELECT * FROM t1 WHERE a IS NULL;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a a 5 const 10 Using where
1 SIMPLE t1 ref a a 5 const 1 Using where
SELECT * FROM t1 WHERE a<=>NULL;
a b
NULL 99
@ -203,3 +203,155 @@ DELETE from t1 where a < 100;
SELECT * from t1;
a
DROP TABLE t1;
create table t1
(
a char(8) not null,
b char(20) not null,
c int not null,
key (a)
) engine=heap;
insert into t1 values ('aaaa', 'prefill-hash=5',0);
insert into t1 values ('aaab', 'prefill-hash=0',0);
insert into t1 values ('aaac', 'prefill-hash=7',0);
insert into t1 values ('aaad', 'prefill-hash=2',0);
insert into t1 values ('aaae', 'prefill-hash=1',0);
insert into t1 values ('aaaf', 'prefill-hash=4',0);
insert into t1 values ('aaag', 'prefill-hash=3',0);
insert into t1 values ('aaah', 'prefill-hash=6',0);
explain select * from t1 where a='aaaa';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a a 8 const 1 Using where
explain select * from t1 where a='aaab';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a a 8 const 1 Using where
explain select * from t1 where a='aaac';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a a 8 const 1 Using where
explain select * from t1 where a='aaad';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a a 8 const 1 Using where
insert into t1 select * from t1;
explain select * from t1 where a='aaaa';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a a 8 const 1 Using where
explain select * from t1 where a='aaab';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a a 8 const 1 Using where
explain select * from t1 where a='aaac';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a a 8 const 1 Using where
explain select * from t1 where a='aaad';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a a 8 const 1 Using where
flush tables;
explain select * from t1 where a='aaaa';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a a 8 const 2 Using where
explain select * from t1 where a='aaab';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a a 8 const 2 Using where
explain select * from t1 where a='aaac';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a a 8 const 2 Using where
explain select * from t1 where a='aaad';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a a 8 const 2 Using where
create table t2 as select * from t1;
delete from t1;
insert into t1 select * from t2;
explain select * from t1 where a='aaaa';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a a 8 const 1 Using where
explain select * from t1 where a='aaab';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a a 8 const 1 Using where
explain select * from t1 where a='aaac';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a a 8 const 1 Using where
explain select * from t1 where a='aaad';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a a 8 const 1 Using where
drop table t1, t2;
create table t1 (
id int unsigned not null primary key auto_increment,
name varchar(20) not null,
index heap_idx(name),
index btree_idx using btree(name)
) engine=heap;
create table t2 (
id int unsigned not null primary key auto_increment,
name varchar(20) not null,
index btree_idx using btree(name),
index heap_idx(name)
) engine=heap;
insert into t1 (name) values ('Matt'), ('Lilu'), ('Corbin'), ('Carly'),
('Suzy'), ('Hoppy'), ('Burrito'), ('Mimi'), ('Sherry'), ('Ben'), ('Phil'),
('Emily'), ('Mike');
insert into t2 select * from t1;
explain select * from t1 where name='matt';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref heap_idx,btree_idx heap_idx 20 const 1 Using where
explain select * from t2 where name='matt';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ref btree_idx,heap_idx btree_idx 20 const 1 Using where
explain select * from t1 where name='Lilu';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref heap_idx,btree_idx heap_idx 20 const 1 Using where
explain select * from t2 where name='Lilu';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ref btree_idx,heap_idx btree_idx 20 const 1 Using where
explain select * from t1 where name='Phil';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref heap_idx,btree_idx heap_idx 20 const 1 Using where
explain select * from t2 where name='Phil';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ref btree_idx,heap_idx btree_idx 20 const 1 Using where
explain select * from t1 where name='Lilu';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref heap_idx,btree_idx heap_idx 20 const 1 Using where
explain select * from t2 where name='Lilu';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ref btree_idx,heap_idx btree_idx 20 const 1 Using where
insert into t1 (name) select name from t2;
insert into t1 (name) select name from t2;
insert into t1 (name) select name from t2;
insert into t1 (name) select name from t2;
insert into t1 (name) select name from t2;
insert into t1 (name) select name from t2;
flush tables;
select count(*) from t1 where name='Matt';
count(*)
7
explain select * from t1 ignore index (btree_idx) where name='matt';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref heap_idx heap_idx 20 const 7 Using where
show index from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 0 PRIMARY 1 id NULL 91 NULL NULL HASH
t1 1 heap_idx 1 name NULL 13 NULL NULL HASH
t1 1 btree_idx 1 name A NULL NULL NULL BTREE
show index from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 0 PRIMARY 1 id NULL 91 NULL NULL HASH
t1 1 heap_idx 1 name NULL 13 NULL NULL HASH
t1 1 btree_idx 1 name A NULL NULL NULL BTREE
create table t3
(
a varchar(20) not null,
b varchar(20) not null,
key (a,b)
) engine=heap;
insert into t3 select name, name from t1;
show index from t3;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t3 1 a 1 a NULL NULL NULL NULL HASH
t3 1 a 2 b NULL 15 NULL NULL HASH
show index from t3;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t3 1 a 1 a NULL NULL NULL NULL HASH
t3 1 a 2 b NULL 15 NULL NULL HASH
explain select * from t1 ignore key(btree_idx), t3 where t1.name='matt' and t3.a = concat('',t1.name) and t3.b=t1.name;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t3 ref a a 40 const,const 6 Using where
1 SIMPLE t1 ref heap_idx heap_idx 20 const 7 Using where
drop table t1, t2, t3;

View file

@ -116,7 +116,7 @@ Field Type Collation Null Key Default Extra Privileges Comment
Insert_priv enum('N','Y') utf8_bin N select,insert,update,references
show full columns from v1;
Field Type Collation Null Key Default Extra Privileges Comment
c char(64) latin1_swedish_ci select,insert,update,references
c char(64) utf8_general_ci select,insert,update,references
select * from information_schema.COLUMNS where table_name="t1"
and column_name= "a";
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME TYPE COLLATION_NAME IS_NULLABLE KEY COLUMN_DEFAULT EXTRA PRIVILEGES COMMENT
@ -245,7 +245,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE # ALL NULL NULL NULL NULL 2
1 SIMPLE # ALL NULL NULL NULL NULL 2 Using where
select a.ROUTINE_NAME, b.name from information_schema.ROUTINES a,
mysql.proc b where a.ROUTINE_NAME = b.name;
mysql.proc b where a.ROUTINE_NAME = convert(b.name using utf8);
ROUTINE_NAME name
sub1 sub1
sel2 sel2
@ -292,10 +292,10 @@ Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_par
select * from information_schema.VIEWS where TABLE_NAME like "v%";
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME VIEW_DEFINITION CHECK_OPTION IS_UPDATABLE
NULL test v0 select `SCHEMATA`.`SCHEMA_NAME` AS `c` from `information_schema`.`SCHEMATA` NONE NO
NULL test v1 select `TABLES`.`TABLE_NAME` AS `c` from `information_schema`.`TABLES` where (`TABLES`.`TABLE_NAME` = _latin1'v1') NONE NO
NULL test v2 select `COLUMNS`.`COLUMN_NAME` AS `c` from `information_schema`.`COLUMNS` where (`COLUMNS`.`TABLE_NAME` = _latin1'v2') NONE NO
NULL test v3 select `CHARACTER_SETS`.`CHARACTER_SET_NAME` AS `c` from `information_schema`.`CHARACTER_SETS` where (`CHARACTER_SETS`.`CHARACTER_SET_NAME` like _latin1'latin1%') NONE NO
NULL test v4 select `COLLATIONS`.`COLLATION_NAME` AS `c` from `information_schema`.`COLLATIONS` where (`COLLATIONS`.`COLLATION_NAME` like _latin1'latin1%') NONE NO
NULL test v1 select `TABLES`.`TABLE_NAME` AS `c` from `information_schema`.`TABLES` where (`TABLES`.`TABLE_NAME` = _utf8'v1') NONE NO
NULL test v2 select `COLUMNS`.`COLUMN_NAME` AS `c` from `information_schema`.`COLUMNS` where (`COLUMNS`.`TABLE_NAME` = _utf8'v2') NONE NO
NULL test v3 select `CHARACTER_SETS`.`CHARACTER_SET_NAME` AS `c` from `information_schema`.`CHARACTER_SETS` where (`CHARACTER_SETS`.`CHARACTER_SET_NAME` like _utf8'latin1%') NONE NO
NULL test v4 select `COLLATIONS`.`COLLATION_NAME` AS `c` from `information_schema`.`COLLATIONS` where (`COLLATIONS`.`COLLATION_NAME` like _utf8'latin1%') NONE NO
drop view v0, v1, v2, v3, v4;
create table t1 (a int);
grant select,update,insert on t1 to mysqltest_1@localhost;
@ -445,3 +445,44 @@ select AUTO_INCREMENT from information_schema.tables where table_name = 't1';
AUTO_INCREMENT
4
drop table t1;
create table t1 (s1 int);
insert into t1 values (0),(9),(0);
select s1 from t1 where s1 in (select version from
information_schema.tables) union select version from
information_schema.tables;
s1
9
drop table t1;
SHOW CREATE TABLE INFORMATION_SCHEMA.CHARACTER_SETS;
Table Create Table
CHARACTER_SETS CREATE TEMPORARY TABLE `CHARACTER_SETS` (
`CHARACTER_SET_NAME` char(30) NOT NULL default '',
`Description` char(60) NOT NULL default '',
`DEFAULT_COLLATE_NAME` char(60) NOT NULL default '',
`Maxlen` bigint(3) NOT NULL default '0'
) ENGINE=HEAP DEFAULT CHARSET=utf8 MAX_ROWS=2282
set names latin2;
SHOW CREATE TABLE INFORMATION_SCHEMA.CHARACTER_SETS;
Table Create Table
CHARACTER_SETS CREATE TEMPORARY TABLE `CHARACTER_SETS` (
`CHARACTER_SET_NAME` char(30) NOT NULL default '',
`Description` char(60) NOT NULL default '',
`DEFAULT_COLLATE_NAME` char(60) NOT NULL default '',
`Maxlen` bigint(3) NOT NULL default '0'
) ENGINE=HEAP DEFAULT CHARSET=utf8 MAX_ROWS=2282
set names latin1;
create table t1 select * from information_schema.CHARACTER_SETS
where CHARACTER_SET_NAME like "latin1";
select * from t1;
CHARACTER_SET_NAME Description DEFAULT_COLLATE_NAME Maxlen
latin1 ISO 8859-1 West European latin1_swedish_ci 1
alter table t1 default character set utf8;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`CHARACTER_SET_NAME` char(30) NOT NULL default '',
`Description` char(60) NOT NULL default '',
`DEFAULT_COLLATE_NAME` char(60) NOT NULL default '',
`Maxlen` bigint(3) NOT NULL default '0'
) ENGINE=MyISAM DEFAULT CHARSET=utf8
drop table t1;

View file

@ -1664,3 +1664,21 @@ select count(*) from t1 where x = 18446744073709551601;
count(*)
1
drop table t1;
show status like "Innodb_buffer_pool_pages_total";
Variable_name Value
Innodb_buffer_pool_pages_total 512
show status like "Innodb_page_size";
Variable_name Value
Innodb_page_size 16384
show status like "Innodb_rows_deleted";
Variable_name Value
Innodb_rows_deleted 2078
show status like "Innodb_rows_inserted";
Variable_name Value
Innodb_rows_inserted 31706
show status like "Innodb_rows_read";
Variable_name Value
Innodb_rows_read 80161
show status like "Innodb_rows_updated";
Variable_name Value
Innodb_rows_updated 29530

View file

@ -277,3 +277,13 @@ Key_blocks_unused KEY_BLOCKS_UNUSED
set global keycache2.key_buffer_size=0;
set global keycache3.key_buffer_size=100;
set global keycache3.key_buffer_size=0;
create table t1 (mytext text, FULLTEXT (mytext));
insert t1 values ('aaabbb');
check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
set GLOBAL key_cache_block_size=2048;
check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
drop table t1;

View file

@ -543,7 +543,7 @@ Warnings:
Note 1031 Table storage engine for 't1' doesn't have this option
show keys from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 1 a 1 a NULL NULL NULL NULL YES HASH
t1 1 a 1 a NULL 1000 NULL NULL YES HASH
drop table t1,t2;
create table t1 ( a tinytext, b char(1), index idx (a(1),b) );
insert into t1 values (null,''), (null,'');

View file

@ -2058,6 +2058,10 @@ t2 1 fld3 1 fld3 A NULL NULL NULL BTREE
drop table t4, t3, t2, t1;
DO 1;
DO benchmark(100,1+1),1,1;
do default;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
do foobar;
ERROR 42S22: Unknown column 'foobar' in 'field list'
CREATE TABLE t1 (
id mediumint(8) unsigned NOT NULL auto_increment,
pseudo varchar(35) NOT NULL default '',

View file

@ -61,7 +61,7 @@ t1 CREATE TABLE `t1` (
set @@sql_mode="no_field_options,mysql323,mysql40";
show variables like 'sql_mode';
Variable_name Value
sql_mode NO_FIELD_OPTIONS,MYSQL323,MYSQL40
sql_mode NO_FIELD_OPTIONS,MYSQL323,MYSQL40,BROKEN_NOT
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (

View file

@ -173,18 +173,12 @@ SET @`a b`='hello';
INSERT INTO t1 VALUES(@`a b`);
set @var1= "';aaa";
insert into t1 values (@var1);
create table t2 (c char(30)) charset=ucs2;
set @v=convert('abc' using ucs2);
insert into t2 values (@v);
show binlog events from 95;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 95 User var 1 136 @`a b`=_latin1 0x68656C6C6F COLLATE latin1_swedish_ci
master-bin.000001 136 Query 1 222 use `test`; INSERT INTO t1 VALUES(@`a b`)
master-bin.000001 222 User var 1 264 @`var1`=_latin1 0x273B616161 COLLATE latin1_swedish_ci
master-bin.000001 264 Query 1 350 use `test`; insert into t1 values (@var1)
master-bin.000001 350 Query 1 448 use `test`; create table t2 (c char(30)) charset=ucs2
master-bin.000001 448 User var 1 488 @`v`=_ucs2 0x006100620063 COLLATE ucs2_general_ci
master-bin.000001 488 Query 1 571 use `test`; insert into t2 values (@v)
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
SET @`a b`:=_latin1 0x68656C6C6F COLLATE latin1_swedish_ci;
use test;
@ -195,12 +189,7 @@ INSERT INTO t1 VALUES(@`a b`);
SET @`var1`:=_latin1 0x273B616161 COLLATE latin1_swedish_ci;
SET TIMESTAMP=10000;
insert into t1 values (@var1);
SET TIMESTAMP=10000;
create table t2 (c char(30)) charset=ucs2;
SET @`v`:=_ucs2 0x006100620063 COLLATE ucs2_general_ci;
SET TIMESTAMP=10000;
insert into t2 values (@v);
drop table t1, t2;
drop table t1;
set @var= NULL ;
select FIELD( @var,'1it','Hit') as my_column;
my_column

View file

@ -80,3 +80,10 @@ select * from t1 where firstname='john' and firstname = binary 'john';
select * from t1 where firstname='John' and firstname like binary 'john';
select * from t1 where firstname='john' and firstname like binary 'John';
drop table t1;
#
# Bug #6552 CHAR column w/o length is legal, BINARY w/o length is not
#
create table t1 (a binary);
show create table t1;
drop table t1;

View file

@ -20,6 +20,16 @@ SELECT * FROM t1 where (1 AND a)=0;
SELECT * FROM t1 where (1 AND a)=1;
SELECT * FROM t1 where (1 AND a) IS NULL;
# WL#638 - Behaviour of NOT does not follow SQL specification
set sql_mode='broken_not';
select * from t1 where not a between 2 and 3;
set sql_mode=default;
select * from t1 where not a between 2 and 3;
# SQL boolean tests
select a, a is false, a is true, a is unknown from t1;
select a, a is not false, a is not true, a is not unknown from t1;
# Verify that NULL optimisation works in AND clause:
SET @a=0, @b=0;
SELECT * FROM t1 WHERE NULL AND (@a:=@a+1);

View file

@ -323,3 +323,19 @@ set @str1 = 'select ?';
set @str2 = convert(@str1 using ucs2);
prepare stmt1 from @str2;
execute stmt1 using @ivar;
#
# Check correct binlogging of UCS2 user variables (BUG#3875)
#
SET TIMESTAMP=10000;
create table t2 (c char(30)) charset=ucs2;
set @v=convert('abc' using ucs2);
reset master;
insert into t2 values (@v);
show binlog events from 95;
# more important than SHOW BINLOG EVENTS, mysqlbinlog (where we
# absolutely need variables names to be quoted and strings to be
# escaped).
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
--exec $MYSQL_BINLOG --short-form $MYSQL_TEST_DIR/var/log/master-bin.000001
drop table t2;

View file

@ -295,3 +295,14 @@ insert into t1 (s) values ('p
select * from t1 where match(s) against('para' in boolean mode);
select * from t1 where match(s) against('par*' in boolean mode);
DROP TABLE t1;
#
# icc -ip bug (ip = interprocedural optimization)
# bug#5528
#
CREATE TABLE t1 (h text, FULLTEXT (h));
INSERT INTO t1 VALUES ('Jesses Hasse Ling and his syncopators of Swing');
REPAIR TABLE t1;
select count(*) from t1;
drop table t1;

View file

@ -598,8 +598,10 @@ drop table t3;
# Bug #6142: a problem with the empty innodb table
#
--disable_warnings
create table t1 (
a varchar(30), b varchar(30), primary key(a), key(b)
) engine=innodb;
--enable_warnings
select distinct a from t1;
drop table t1;

View file

@ -3,7 +3,7 @@
#
--disable_warnings
drop table if exists t1;
drop table if exists t1,t2;
--enable_warnings
create table t1 (a int not null,b int not null, primary key using HASH (a)) engine=heap comment="testing heaps" avg_row_length=100 min_rows=1 max_rows=100;
@ -141,3 +141,113 @@ INSERT into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11);
DELETE from t1 where a < 100;
SELECT * from t1;
DROP TABLE t1;
#
# Hash index # records estimate test
#
create table t1
(
a char(8) not null,
b char(20) not null,
c int not null,
key (a)
) engine=heap;
insert into t1 values ('aaaa', 'prefill-hash=5',0);
insert into t1 values ('aaab', 'prefill-hash=0',0);
insert into t1 values ('aaac', 'prefill-hash=7',0);
insert into t1 values ('aaad', 'prefill-hash=2',0);
insert into t1 values ('aaae', 'prefill-hash=1',0);
insert into t1 values ('aaaf', 'prefill-hash=4',0);
insert into t1 values ('aaag', 'prefill-hash=3',0);
insert into t1 values ('aaah', 'prefill-hash=6',0);
explain select * from t1 where a='aaaa';
explain select * from t1 where a='aaab';
explain select * from t1 where a='aaac';
explain select * from t1 where a='aaad';
insert into t1 select * from t1;
explain select * from t1 where a='aaaa';
explain select * from t1 where a='aaab';
explain select * from t1 where a='aaac';
explain select * from t1 where a='aaad';
# a known effect: table reload causes statistics to be updated:
flush tables;
explain select * from t1 where a='aaaa';
explain select * from t1 where a='aaab';
explain select * from t1 where a='aaac';
explain select * from t1 where a='aaad';
# Check if delete_all_rows() updates #hash_buckets
create table t2 as select * from t1;
delete from t1;
insert into t1 select * from t2;
explain select * from t1 where a='aaaa';
explain select * from t1 where a='aaab';
explain select * from t1 where a='aaac';
explain select * from t1 where a='aaad';
drop table t1, t2;
# Btree and hash index use costs.
create table t1 (
id int unsigned not null primary key auto_increment,
name varchar(20) not null,
index heap_idx(name),
index btree_idx using btree(name)
) engine=heap;
create table t2 (
id int unsigned not null primary key auto_increment,
name varchar(20) not null,
index btree_idx using btree(name),
index heap_idx(name)
) engine=heap;
insert into t1 (name) values ('Matt'), ('Lilu'), ('Corbin'), ('Carly'),
('Suzy'), ('Hoppy'), ('Burrito'), ('Mimi'), ('Sherry'), ('Ben'), ('Phil'),
('Emily'), ('Mike');
insert into t2 select * from t1;
explain select * from t1 where name='matt';
explain select * from t2 where name='matt';
explain select * from t1 where name='Lilu';
explain select * from t2 where name='Lilu';
explain select * from t1 where name='Phil';
explain select * from t2 where name='Phil';
explain select * from t1 where name='Lilu';
explain select * from t2 where name='Lilu';
insert into t1 (name) select name from t2;
insert into t1 (name) select name from t2;
insert into t1 (name) select name from t2;
insert into t1 (name) select name from t2;
insert into t1 (name) select name from t2;
insert into t1 (name) select name from t2;
flush tables;
select count(*) from t1 where name='Matt';
explain select * from t1 ignore index (btree_idx) where name='matt';
show index from t1;
show index from t1;
create table t3
(
a varchar(20) not null,
b varchar(20) not null,
key (a,b)
) engine=heap;
insert into t3 select name, name from t1;
show index from t3;
show index from t3;
# test rec_per_key use for joins.
explain select * from t1 ignore key(btree_idx), t3 where t1.name='matt' and t3.a = concat('',t1.name) and t3.b=t1.name;
drop table t1, t2, t3;

View file

@ -104,7 +104,7 @@ information_schema.SCHEMATA b where
a.ROUTINE_SCHEMA = b.SCHEMA_NAME;
select a.ROUTINE_NAME, b.name from information_schema.ROUTINES a,
mysql.proc b where a.ROUTINE_NAME = b.name;
mysql.proc b where a.ROUTINE_NAME = convert(b.name using utf8);
select count(*) from information_schema.ROUTINES;
#
@ -222,4 +222,23 @@ create table t1 (a int not null auto_increment,b int, primary key (a));
insert into t1 values (1,1),(NULL,3),(NULL,4);
select AUTO_INCREMENT from information_schema.tables where table_name = 't1';
drop table t1;
create table t1 (s1 int);
insert into t1 values (0),(9),(0);
select s1 from t1 where s1 in (select version from
information_schema.tables) union select version from
information_schema.tables;
drop table t1;
SHOW CREATE TABLE INFORMATION_SCHEMA.CHARACTER_SETS;
set names latin2;
SHOW CREATE TABLE INFORMATION_SCHEMA.CHARACTER_SETS;
set names latin1;
create table t1 select * from information_schema.CHARACTER_SETS
where CHARACTER_SET_NAME like "latin1";
select * from t1;
alter table t1 default character set utf8;
show create table t1;
drop table t1;

View file

@ -1180,3 +1180,11 @@ select count(*) from t1 where x = 18446744073709551601;
drop table t1;
# Test for testable InnoDB status variables. This test
# uses previous ones(pages_created, rows_deleted, ...).
show status like "Innodb_buffer_pool_pages_total";
show status like "Innodb_page_size";
show status like "Innodb_rows_deleted";
show status like "Innodb_rows_inserted";
show status like "Innodb_rows_read";
show status like "Innodb_rows_updated";

View file

@ -156,3 +156,14 @@ set global keycache2.key_buffer_size=0;
# Test to set up a too small size for a key cache (bug #2064)
set global keycache3.key_buffer_size=100;
set global keycache3.key_buffer_size=0;
# Test case for buf 6447
create table t1 (mytext text, FULLTEXT (mytext));
insert t1 values ('aaabbb');
check table t1;
set GLOBAL key_cache_block_size=2048;
check table t1;
drop table t1;

View file

@ -1757,6 +1757,15 @@ drop table t4, t3, t2, t1;
DO 1;
DO benchmark(100,1+1),1,1;
#
# Bug #6449: do default;
#
--error 1064
do default;
--error 1054
do foobar;
#
# random in WHERE clause
#

View file

@ -109,16 +109,13 @@ SET @`a b`='hello';
INSERT INTO t1 VALUES(@`a b`);
set @var1= "';aaa";
insert into t1 values (@var1);
create table t2 (c char(30)) charset=ucs2;
set @v=convert('abc' using ucs2);
insert into t2 values (@v);
show binlog events from 95;
# more important than SHOW BINLOG EVENTS, mysqlbinlog (where we
# absolutely need variables names to be quoted and strings to be
# escaped).
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
--exec $MYSQL_BINLOG --short-form $MYSQL_TEST_DIR/var/log/master-bin.000001
drop table t1, t2;
drop table t1;
#

View file

@ -1699,11 +1699,12 @@ byte *key_cache_read(KEY_CACHE *keycache,
keycache_pthread_mutex_unlock(&keycache->cache_lock);
goto no_key_cache;
}
read_length= length > keycache->key_cache_block_size ?
keycache->key_cache_block_size : length;
KEYCACHE_DBUG_ASSERT(read_length > 0);
offset= (uint) (filepos & (keycache->key_cache_block_size-1));
filepos-= offset;
read_length= length;
set_if_smaller(read_length, keycache->key_cache_block_size-offset);
KEYCACHE_DBUG_ASSERT(read_length > 0);
#ifndef THREAD
if (block_length > keycache->key_cache_block_size || offset)
return_buffer=0;
@ -1773,7 +1774,7 @@ byte *key_cache_read(KEY_CACHE *keycache,
return (block->buffer);
#endif
buff+= read_length;
filepos+= read_length;
filepos+= read_length+offset;
} while ((length-= read_length));
DBUG_RETURN(start);
@ -1835,12 +1836,12 @@ int key_cache_insert(KEY_CACHE *keycache,
keycache_pthread_mutex_unlock(&keycache->cache_lock);
DBUG_RETURN(0);
}
read_length= length > keycache->key_cache_block_size ?
keycache->key_cache_block_size : length;
KEYCACHE_DBUG_ASSERT(read_length > 0);
offset= (uint) (filepos & (keycache->key_cache_block_size-1));
/* Read data into key cache from buff in key_cache_block_size incr. */
filepos-= offset;
read_length= length;
set_if_smaller(read_length, keycache->key_cache_block_size-offset);
KEYCACHE_DBUG_ASSERT(read_length > 0);
inc_counter_for_resize_op(keycache);
keycache->global_cache_r_requests++;
@ -1882,7 +1883,7 @@ int key_cache_insert(KEY_CACHE *keycache,
DBUG_RETURN(1);
buff+= read_length;
filepos+= read_length;
filepos+= read_length+offset;
} while ((length-= read_length));
}
@ -1959,12 +1960,12 @@ int key_cache_write(KEY_CACHE *keycache,
keycache_pthread_mutex_unlock(&keycache->cache_lock);
goto no_key_cache;
}
read_length= length > keycache->key_cache_block_size ?
keycache->key_cache_block_size : length;
KEYCACHE_DBUG_ASSERT(read_length > 0);
offset= (uint) (filepos & (keycache->key_cache_block_size-1));
/* Write data in key_cache_block_size increments */
filepos-= offset;
read_length= length;
set_if_smaller(read_length, keycache->key_cache_block_size-offset);
KEYCACHE_DBUG_ASSERT(read_length > 0);
inc_counter_for_resize_op(keycache);
keycache->global_cache_w_requests++;
@ -2032,7 +2033,7 @@ int key_cache_write(KEY_CACHE *keycache,
next_block:
buff+= read_length;
filepos+= read_length;
filepos+= read_length+offset;
offset= 0;
} while ((length-= read_length));

View file

@ -238,7 +238,8 @@ ConfigRetriever::verifyConfig(const struct ndb_mgm_configuration * conf, Uint32
char buf[255];
ndb_mgm_configuration_iterator * it;
it = ndb_mgm_create_configuration_iterator((struct ndb_mgm_configuration *)conf, CFG_SECTION_NODE);
it = ndb_mgm_create_configuration_iterator((struct ndb_mgm_configuration *)conf,
CFG_SECTION_NODE);
if(it == 0){
BaseString::snprintf(buf, 255, "Unable to create config iterator");
@ -284,8 +285,14 @@ ConfigRetriever::verifyConfig(const struct ndb_mgm_configuration * conf, Uint32
}
if(_type != m_node_type){
BaseString::snprintf(buf, 255, "Supplied node type(%d) and config node type(%d) "
" don't match", m_node_type, _type);
const char *type_s, *alias_s, *type_s2, *alias_s2;
alias_s= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)m_node_type,
&type_s);
alias_s2= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)_type,
&type_s2);
BaseString::snprintf(buf, 255, "This node type %s(%s) and config "
"node type %s(%s) don't match for nodeid %d",
alias_s, type_s, alias_s2, type_s2, nodeid);
setError(CR_ERROR, buf);
return false;
}

View file

@ -193,7 +193,7 @@ int main(int argc, char** argv)
* Read configuration files *
****************************/
LocalConfig local_config;
if(!local_config.init(0,glob.local_config_filename)){
if(!local_config.init(opt_connect_str,glob.local_config_filename)){
local_config.printError();
goto error_end;
}

View file

@ -30,6 +30,18 @@
const char **ha_heap::bas_ext() const
{ static const char *ext[1]= { NullS }; return ext; }
/*
Hash index statistics is updated (copied from HP_KEYDEF::hash_buckets to
rec_per_key) after 1/HEAP_STATS_UPDATE_THRESHOLD fraction of table records
have been inserted/updated/deleted. delete_all_rows() and table flush cause
immediate update.
NOTE
hash index statistics must be updated when number of table records changes
from 0 to non-zero value and vice versa. Otherwise records_in_range may
erroneously return 0 and 'range' may miss records.
*/
#define HEAP_STATS_UPDATE_THRESHOLD 10
int ha_heap::open(const char *name, int mode, uint test_if_locked)
{
@ -48,6 +60,8 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked)
{
/* Initialize variables for the opened table */
set_keys_for_scanning();
if (table->tmp_table == NO_TMP_TABLE)
update_key_stats();
}
return (file ? 0 : 1);
}
@ -84,28 +98,58 @@ void ha_heap::set_keys_for_scanning(void)
}
}
void ha_heap::update_key_stats()
{
for (uint i= 0; i < table->keys; i++)
{
KEY *key=table->key_info+i;
if (key->algorithm != HA_KEY_ALG_BTREE)
{
ha_rows hash_buckets= file->s->keydef[i].hash_buckets;
key->rec_per_key[key->key_parts-1]=
hash_buckets ? file->s->records/hash_buckets : 0;
}
}
records_changed= 0;
}
int ha_heap::write_row(byte * buf)
{
int res;
statistic_increment(table->in_use->status_var.ha_write_count,&LOCK_status);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
table->timestamp_field->set_time();
if (table->next_number_field && buf == table->record[0])
update_auto_increment();
return heap_write(file,buf);
res= heap_write(file,buf);
if (!res && table->tmp_table == NO_TMP_TABLE &&
++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records)
update_key_stats();
return res;
}
int ha_heap::update_row(const byte * old_data, byte * new_data)
{
int res;
statistic_increment(table->in_use->status_var.ha_update_count,&LOCK_status);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
table->timestamp_field->set_time();
return heap_update(file,old_data,new_data);
res= heap_update(file,old_data,new_data);
if (!res && table->tmp_table == NO_TMP_TABLE &&
++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records)
update_key_stats();
return res;
}
int ha_heap::delete_row(const byte * buf)
{
int res;
statistic_increment(table->in_use->status_var.ha_delete_count,&LOCK_status);
return heap_delete(file,buf);
res= heap_delete(file,buf);
if (!res && table->tmp_table == NO_TMP_TABLE &&
++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records)
update_key_stats();
return res;
}
int ha_heap::index_read(byte * buf, const byte * key, uint key_len,
@ -236,6 +280,8 @@ int ha_heap::extra(enum ha_extra_function operation)
int ha_heap::delete_all_rows()
{
heap_clear(file);
if (table->tmp_table == NO_TMP_TABLE)
update_key_stats();
return 0;
}
@ -393,7 +439,8 @@ ha_rows ha_heap::records_in_range(uint inx, key_range *min_key,
min_key->flag != HA_READ_KEY_EXACT ||
max_key->flag != HA_READ_AFTER_KEY)
return HA_POS_ERROR; // Can only use exact keys
return 10; // Good guess
else
return key->rec_per_key[key->key_parts-1];
}

View file

@ -27,9 +27,10 @@ class ha_heap: public handler
{
HP_INFO *file;
key_map btree_keys;
public:
ha_heap(TABLE *table): handler(table), file(0) {}
/* number of records changed since last statistics update */
uint records_changed;
public:
ha_heap(TABLE *table): handler(table), file(0), records_changed(0) {}
~ha_heap() {}
const char *table_type() const { return "HEAP"; }
const char *index_type(uint inx)
@ -97,4 +98,6 @@ class ha_heap: public handler
HEAP_PTR ptr2=*(HEAP_PTR*)ref2;
return ptr1 < ptr2? -1 : (ptr1 > ptr2? 1 : 0);
}
private:
void update_key_stats();
};

View file

@ -149,6 +149,85 @@ static mysql_byte* innobase_get_key(INNOBASE_SHARE *share,uint *length,
static INNOBASE_SHARE *get_share(const char *table_name);
static void free_share(INNOBASE_SHARE *share);
struct show_var_st innodb_status_variables[]= {
{"buffer_pool_pages_data",
(char*) &export_vars.innodb_buffer_pool_pages_data, SHOW_LONG},
{"buffer_pool_pages_dirty",
(char*) &export_vars.innodb_buffer_pool_pages_dirty, SHOW_LONG},
{"buffer_pool_pages_flushed",
(char*) &export_vars.innodb_buffer_pool_pages_flushed, SHOW_LONG},
{"buffer_pool_pages_free",
(char*) &export_vars.innodb_buffer_pool_pages_free, SHOW_LONG},
{"buffer_pool_pages_latched",
(char*) &export_vars.innodb_buffer_pool_pages_latched, SHOW_LONG},
{"buffer_pool_pages_misc",
(char*) &export_vars.innodb_buffer_pool_pages_misc, SHOW_LONG},
{"buffer_pool_pages_total",
(char*) &export_vars.innodb_buffer_pool_pages_total, SHOW_LONG},
{"buffer_pool_read_ahead_rnd",
(char*) &export_vars.innodb_buffer_pool_read_ahead_rnd, SHOW_LONG},
{"buffer_pool_read_ahead_seq",
(char*) &export_vars.innodb_buffer_pool_read_ahead_seq, SHOW_LONG},
{"buffer_pool_read_requests",
(char*) &export_vars.innodb_buffer_pool_read_requests, SHOW_LONG},
{"buffer_pool_reads",
(char*) &export_vars.innodb_buffer_pool_reads, SHOW_LONG},
{"buffer_pool_wait_free",
(char*) &export_vars.innodb_buffer_pool_wait_free, SHOW_LONG},
{"buffer_pool_write_requests",
(char*) &export_vars.innodb_buffer_pool_write_requests, SHOW_LONG},
{"data_fsyncs",
(char*) &export_vars.innodb_data_fsyncs, SHOW_LONG},
{"data_pending_fsyncs",
(char*) &export_vars.innodb_data_pending_fsyncs, SHOW_LONG},
{"data_pending_reads",
(char*) &export_vars.innodb_data_pending_reads, SHOW_LONG},
{"data_pending_writes",
(char*) &export_vars.innodb_data_pending_writes, SHOW_LONG},
{"data_read",
(char*) &export_vars.innodb_data_read, SHOW_LONG},
{"data_reads",
(char*) &export_vars.innodb_data_reads, SHOW_LONG},
{"data_writes",
(char*) &export_vars.innodb_data_writes, SHOW_LONG},
{"data_written",
(char*) &export_vars.innodb_data_written, SHOW_LONG},
{"dblwr_pages_written",
(char*) &export_vars.innodb_dblwr_pages_written, SHOW_LONG},
{"dblwr_writes",
(char*) &export_vars.innodb_dblwr_writes, SHOW_LONG},
{"log_waits",
(char*) &export_vars.innodb_log_waits, SHOW_LONG},
{"log_write_requests",
(char*) &export_vars.innodb_log_write_requests, SHOW_LONG},
{"log_writes",
(char*) &export_vars.innodb_log_writes, SHOW_LONG},
{"os_log_fsyncs",
(char*) &export_vars.innodb_os_log_fsyncs, SHOW_LONG},
{"os_log_pending_fsyncs",
(char*) &export_vars.innodb_os_log_pending_fsyncs, SHOW_LONG},
{"os_log_pending_writes",
(char*) &export_vars.innodb_os_log_pending_writes, SHOW_LONG},
{"os_log_written",
(char*) &export_vars.innodb_os_log_written, SHOW_LONG},
{"page_size",
(char*) &export_vars.innodb_page_size, SHOW_LONG},
{"pages_created",
(char*) &export_vars.innodb_pages_created, SHOW_LONG},
{"pages_read",
(char*) &export_vars.innodb_pages_read, SHOW_LONG},
{"pages_written",
(char*) &export_vars.innodb_pages_written, SHOW_LONG},
{"rows_deleted",
(char*) &export_vars.innodb_rows_deleted, SHOW_LONG},
{"rows_inserted",
(char*) &export_vars.innodb_rows_inserted, SHOW_LONG},
{"rows_read",
(char*) &export_vars.innodb_rows_read, SHOW_LONG},
{"rows_updated",
(char*) &export_vars.innodb_rows_updated, SHOW_LONG},
{NullS, NullS, SHOW_LONG}};
/* General functions */
/**********************************************************************
@ -1508,17 +1587,14 @@ innobase_close_connection(
*****************************************************************************/
/********************************************************************
This function is not relevant since we store the tables and indexes
into our own tablespace, not as files, whose extension this function would
give. */
Gives the file extension of an InnoDB single-table tablespace. */
const char**
ha_innobase::bas_ext() const
/*========================*/
/* out: file extension strings, currently not
used */
/* out: file extension string */
{
static const char* ext[] = {".InnoDB", NullS};
static const char* ext[] = {".ibd", NullS};
return(ext);
}
@ -5123,6 +5199,17 @@ ha_innobase::external_lock(
DBUG_RETURN(0);
}
/****************************************************************************
Here we export InnoDB status variables to MySQL. */
void
innodb_export_status(void)
/*======================*/
{
srv_export_innodb_status();
}
/****************************************************************************
Implements the SHOW INNODB STATUS command. Sends the output of the InnoDB
Monitor to the client. */

View file

@ -176,6 +176,7 @@ class ha_innobase: public handler
int cmp_ref(const byte *ref1, const byte *ref2);
};
extern struct show_var_st innodb_status_variables[];
extern uint innobase_init_flags, innobase_lock_type;
extern uint innobase_flush_log_at_trx_commit;
extern ulong innobase_cache_size;
@ -235,6 +236,7 @@ int innobase_savepoint(
int innobase_close_connection(THD *thd);
int innobase_drop_database(char *path);
bool innodb_show_status(THD* thd);
void innodb_export_status(void);
my_bool innobase_query_caching_of_table_permitted(THD* thd, char* full_name,
uint full_name_len);

View file

@ -144,7 +144,7 @@ static int ndb_to_mysql_error(const NdbError *err)
// Push the NDB error message as warning
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
ER_GET_ERRMSG, ER(ER_GET_ERRMSG),
err->code, err->message, "NDB");
err->code, err->message, "NDB");
return err->code;
}
}

View file

@ -468,6 +468,21 @@ int ha_release_temporary_latches(THD *thd)
return 0;
}
/*
Export statistics for different engines. Currently we use it only for
InnoDB.
*/
int ha_update_statistics()
{
#ifdef HAVE_INNOBASE_DB
if (opt_innodb)
innodb_export_status();
#endif
return 0;
}
int ha_commit_trans(THD *thd, THD_TRANS* trans)
{
int error=0;

View file

@ -581,6 +581,7 @@ int ha_report_binlog_offset_and_commit(THD *thd, char *log_file_name,
my_off_t end_offset);
int ha_commit_complete(THD *thd);
int ha_release_temporary_latches(THD *thd);
int ha_update_statistics();
int ha_commit_trans(THD *thd, THD_TRANS *trans);
int ha_rollback_trans(THD *thd, THD_TRANS *trans);
int ha_rollback_to_savepoint(THD *thd, char *savepoint_name);

View file

@ -1722,7 +1722,10 @@ resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select)
else if (group_by_ref)
return group_by_ref;
else
{
DBUG_ASSERT(FALSE);
return NULL; /* So there is no compiler warning. */
}
}
else
return (Item**) not_found_item;

View file

@ -269,7 +269,7 @@ Item_func::Item_func(THD *thd, Item_func *item)
Sets as a side effect the following class variables:
maybe_null Set if any argument may return NULL
with_sum_func Set if any of the arguments contains a sum function
used_table_cache Set to union of the arguments used table
used_tables_cache Set to union of the tables used by arguments
str_value.charset If this is a string function, set this to the
character set for the first argument.

View file

@ -48,7 +48,7 @@ SYM_GROUP sym_group_rtree= {"RTree keys", "HAVE_RTREE_KEYS"};
*/
static SYMBOL symbols[] = {
{ "&&", SYM(AND_SYM)},
{ "&&", SYM(AND_AND_SYM)},
{ "<", SYM(LT)},
{ "<=", SYM(LE)},
{ "<>", SYM(NE)},
@ -334,7 +334,7 @@ static SYMBOL symbols[] = {
{ "NEXT", SYM(NEXT_SYM)},
{ "NO", SYM(NO_SYM)},
{ "NONE", SYM(NONE_SYM)},
{ "NOT", SYM(NOT)},
{ "NOT", SYM(NOT_SYM)},
{ "NO_WRITE_TO_BINLOG", SYM(NO_WRITE_TO_BINLOG)},
{ "NULL", SYM(NULL_SYM)},
{ "NUMERIC", SYM(NUMERIC_SYM)},
@ -489,6 +489,7 @@ static SYMBOL symbols[] = {
{ "UNICODE", SYM(UNICODE_SYM)},
{ "UNION", SYM(UNION_SYM)},
{ "UNIQUE", SYM(UNIQUE_SYM)},
{ "UNKNOWN", SYM(UNKNOWN_SYM)},
{ "UNLOCK", SYM(UNLOCK_SYM)},
{ "UNSIGNED", SYM(UNSIGNED)},
{ "UNTIL", SYM(UNTIL_SYM)},
@ -523,7 +524,7 @@ static SYMBOL symbols[] = {
{ "YEAR", SYM(YEAR_SYM)},
{ "YEAR_MONTH", SYM(YEAR_MONTH_SYM)},
{ "ZEROFILL", SYM(ZEROFILL)},
{ "||", SYM(OR_OR_CONCAT)}
{ "||", SYM(OR_OR_SYM)}
};

View file

@ -282,6 +282,7 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset;
#define MODE_ERROR_FOR_DIVISION_BY_ZERO (MODE_INVALID_DATES*2)
#define MODE_TRADITIONAL (MODE_ERROR_FOR_DIVISION_BY_ZERO*2)
#define MODE_NO_AUTO_CREATE_USER (MODE_TRADITIONAL*2)
#define MODE_BROKEN_NOT (MODE_NO_AUTO_CREATE_USER*2)
#define RAID_BLOCK_SIZE 1024
@ -700,7 +701,7 @@ void append_identifier(THD *thd, String *packet, const char *name,
uint length);
int get_quote_char_for_identifier(THD *thd, const char *name, uint length);
void mysqld_list_fields(THD *thd,TABLE_LIST *table, const char *wild);
int mysqld_dump_create_info(THD *thd, TABLE *table, int fd = -1);
int mysqld_dump_create_info(THD *thd, TABLE_LIST *table_list, int fd = -1);
bool mysqld_show_create(THD *thd, TABLE_LIST *table_list);
bool mysqld_show_create_db(THD *thd, char *dbname, HA_CREATE_INFO *create);
@ -990,7 +991,7 @@ extern ulong rpl_recovery_rank, thread_cache_size;
extern ulong back_log;
extern ulong specialflag, current_pid;
extern ulong expire_logs_days, sync_binlog_period, sync_binlog_counter;
extern my_bool relay_log_purge, opt_innodb_safe_binlog;
extern my_bool relay_log_purge, opt_innodb_safe_binlog, opt_innodb;
extern uint test_flags,select_errors,ha_open_options;
extern uint protocol_version, mysqld_port, dropping_tables;
extern uint delay_key_write_options, lower_case_table_names;

View file

@ -221,7 +221,7 @@ const char *sql_mode_names[] =
"NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS", "MYSQL323", "MYSQL40", "ANSI",
"NO_AUTO_VALUE_ON_ZERO", "NO_BACKSLASH_ESCAPES", "STRICT_TRANS_TABLES", "STRICT_ALL_TABLES",
"NO_ZERO_IN_DATE", "NO_ZERO_DATE", "ALLOW_INVALID_DATES", "ERROR_FOR_DIVISION_BY_ZERO",
"TRADITIONAL", "NO_AUTO_CREATE_USER",
"TRADITIONAL", "NO_AUTO_CREATE_USER", "BROKEN_NOT",
NullS
};
TYPELIB sql_mode_typelib= { array_elements(sql_mode_names)-1,"",
@ -5402,6 +5402,9 @@ struct show_var_st status_vars[]= {
SHOW_LONG_STATUS},
{"Handler_write", (char*) offsetof(STATUS_VAR, ha_write_count),
SHOW_LONG_STATUS},
#ifdef HAVE_INNOBASE_DB
{"Innodb_", (char*) &innodb_status_variables, SHOW_VARS},
#endif /*HAVE_INNOBASE_DB*/
{"Key_blocks_not_flushed", (char*) &dflt_key_cache_var.global_blocks_changed,
SHOW_KEY_CACHE_LONG},
{"Key_blocks_unused", (char*) &dflt_key_cache_var.blocks_unused,

View file

@ -8066,7 +8066,7 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_min_in_range()
boundary of cur_range, there is no need to check this range.
*/
if (range_idx != 0 && !(cur_range->flag & NO_MAX_RANGE) &&
(key_cmp(min_max_arg_part, (byte*) cur_range->max_key,
(key_cmp(min_max_arg_part, (const byte*) cur_range->max_key,
min_max_arg_len) == 1))
continue;
@ -8193,7 +8193,7 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_max_in_range()
*/
if (range_idx != min_max_ranges.elements &&
!(cur_range->flag & NO_MIN_RANGE) &&
(key_cmp(min_max_arg_part, (byte*) cur_range->min_key,
(key_cmp(min_max_arg_part, (const byte*) cur_range->min_key,
min_max_arg_len) == -1))
continue;

View file

@ -3111,9 +3111,9 @@ ulong fix_sql_mode(ulong sql_mode)
MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS |
MODE_NO_FIELD_OPTIONS | MODE_NO_AUTO_CREATE_USER);
if (sql_mode & MODE_MYSQL40)
sql_mode|= MODE_NO_FIELD_OPTIONS;
sql_mode|= MODE_NO_FIELD_OPTIONS | MODE_BROKEN_NOT;
if (sql_mode & MODE_MYSQL323)
sql_mode|= MODE_NO_FIELD_OPTIONS;
sql_mode|= MODE_NO_FIELD_OPTIONS | MODE_BROKEN_NOT;
if (sql_mode & MODE_TRADITIONAL)
sql_mode|= (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES |
MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |

View file

@ -1150,7 +1150,7 @@ bool net_request_file(NET* net, const char* fname)
}
const char *rewrite_db(const char* db, uint *new_len)
const char *rewrite_db(const char* db, uint32 *new_len)
{
if (replicate_rewrite_db.is_empty() || !db)
return db;
@ -1161,7 +1161,7 @@ const char *rewrite_db(const char* db, uint *new_len)
{
if (!strcmp(tmp->key, db))
{
*new_len= strlen(tmp->val);
*new_len= (uint32)strlen(tmp->val);
return tmp->val;
}
}

View file

@ -508,7 +508,7 @@ int add_table_rule(HASH* h, const char* table_spec);
int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec);
void init_table_rule_hash(HASH* h, bool* h_inited);
void init_table_rule_array(DYNAMIC_ARRAY* a, bool* a_inited);
const char *rewrite_db(const char* db, uint *new_db_len);
const char *rewrite_db(const char* db, uint32 *new_db_len);
const char *print_slave_db_safe(const char *db);
int check_expected_error(THD* thd, RELAY_LOG_INFO* rli, int error_code);
void skip_load_data_infile(NET* net);

View file

@ -3037,8 +3037,9 @@ insert_fields(THD *thd, TABLE_LIST *tables, const char *db_name,
my_message(ER_NO_TABLES_USED, ER(ER_NO_TABLES_USED), MYF(0));
else
my_error(ER_BAD_TABLE_ERROR, MYF(0), table_name);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
err:
#endif
DBUG_RETURN(1);
}

View file

@ -1765,6 +1765,7 @@ void TMP_TABLE_PARAM::init()
field_count= sum_func_count= func_count= hidden_field_count= 0;
group_parts= group_length= group_null_parts= 0;
quick_group= 1;
table_charset= 0;
}

View file

@ -1425,6 +1425,7 @@ public:
bool using_indirect_summary_function;
/* If >0 convert all blob fields to varchar(convert_blob_length) */
uint convert_blob_length;
CHARSET_INFO *table_charset;
TMP_TABLE_PARAM()
:copy_funcs_it(copy_funcs), copy_field(0), group_parts(0),

View file

@ -200,6 +200,14 @@ static int find_keyword(LEX *lex, uint len, bool function)
lex->yylval->symbol.symbol=symbol;
lex->yylval->symbol.str= (char*) tok;
lex->yylval->symbol.length=len;
if ((symbol->tok == NOT_SYM) &&
(lex->thd->variables.sql_mode & MODE_BROKEN_NOT))
return NOT2_SYM;
if ((symbol->tok == OR_OR_SYM) &&
!(lex->thd->variables.sql_mode & MODE_PIPES_AS_CONCAT))
return OR2_SYM;
return symbol->tok;
}
return 0;

View file

@ -1220,7 +1220,7 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd)
thd->free_list = 0;
thd->query_length=(uint) strlen(tbl_name);
thd->query = tbl_name;
if ((error = mysqld_dump_create_info(thd, table, -1)))
if ((error = mysqld_dump_create_info(thd, table_list, -1)))
{
my_error(ER_GET_ERRNO, MYF(0), my_errno);
goto err;
@ -4651,7 +4651,7 @@ bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length)
- SET uses tot_length.
*/
void calculate_interval_lengths(THD *thd, TYPELIB *interval,
uint *max_length, uint *tot_length)
uint32 *max_length, uint32 *tot_length)
{
const char **pos;
uint *len;
@ -4663,7 +4663,7 @@ void calculate_interval_lengths(THD *thd, TYPELIB *interval,
*len= (uint) strip_sp((char*) *pos);
uint length= cs->cset->numchars(cs, *pos, *pos + *len);
*tot_length+= length;
set_if_bigger(*max_length, length);
set_if_bigger(*max_length, (uint32)length);
}
}
@ -4994,7 +4994,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
if (new_field->pack_length > 4)
new_field->pack_length=8;
new_field->interval=interval;
uint dummy_max_length;
uint32 dummy_max_length;
calculate_interval_lengths(thd, interval,
&dummy_max_length, &new_field->length);
new_field->length+= (interval->count - 1);
@ -5024,7 +5024,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
new_field->interval=interval;
new_field->pack_length=interval->count < 256 ? 1 : 2; // Should be safe
uint dummy_tot_length;
uint32 dummy_tot_length;
calculate_interval_lengths(thd, interval,
&new_field->length, &dummy_tot_length);
set_if_smaller(new_field->length,MAX_FIELD_WIDTH-1);

View file

@ -7833,6 +7833,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
table->temp_pool_slot = temp_pool_slot;
table->copy_blobs= 1;
table->in_use= thd;
table->table_charset= param->table_charset;
table->keys_for_keyread.init();
table->keys_in_use.init();
table->read_only_keys.init();

File diff suppressed because it is too large Load diff

View file

@ -55,7 +55,10 @@ bool mysql_create_view(THD *thd,
TABLE_LIST *view= lex->unlink_first_table(&link_to_local);
TABLE_LIST *tables= lex->query_tables;
TABLE_LIST *tbl;
SELECT_LEX *select_lex= &lex->select_lex, *sl;
SELECT_LEX *select_lex= &lex->select_lex;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
SELECT_LEX *sl;
#endif
SELECT_LEX_UNIT *unit= &lex->unit;
bool res= FALSE;
DBUG_ENTER("mysql_create_view");
@ -745,7 +748,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
table->effective_algorithm= VIEW_ALGORITHM_MERGE;
DBUG_PRINT("info", ("algorithm: MERGE"));
table->updatable= (table->updatable_view != 0);
table->effective_with_check= table->with_check;
table->effective_with_check= (uint8)table->with_check;
table->ancestor= view_tables;
/*

View file

@ -51,10 +51,13 @@ int yylex(void *yylval, void *yythd);
ER_WARN_DEPRECATED_SYNTAX, \
ER(ER_WARN_DEPRECATED_SYNTAX), (A), (B));
inline Item *or_or_concat(THD *thd, Item* A, Item* B)
/* Helper for parsing "IS [NOT] truth_value" */
inline Item *is_truth_value(Item *A, bool v1, bool v2)
{
return (thd->variables.sql_mode & MODE_PIPES_AS_CONCAT ?
(Item*) new Item_func_concat(A,B) : (Item*) new Item_cond_or(A,B));
return new Item_func_if(create_func_ifnull(A,
new Item_int((char *) (v2 ? "TRUE" : "FALSE"), v2, 1)),
new Item_int((char *) (v1 ? "TRUE" : "FALSE"), v1, 1),
new Item_int((char *) (v1 ? "FALSE" : "TRUE"),!v1, 1));
}
%}
@ -197,6 +200,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token ALGORITHM_SYM
%token ALL
%token AND_SYM
%token AND_AND_SYM
%token AS
%token ASC
%token AUTO_INC
@ -341,7 +345,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token NCHAR_SYM
%token NCHAR_STRING
%token NVARCHAR_SYM
%token NOT
%token NOT_SYM
%token NOT2_SYM
%token NO_SYM
%token NULL_SYM
%token NUM
@ -352,7 +357,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token OPTION
%token OPTIONALLY
%token OR_SYM
%token OR_OR_CONCAT
%token OR2_SYM
%token OR_OR_SYM
%token ORDER_SYM
%token OUT_SYM
%token OUTER
@ -436,6 +442,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token UNICODE_SYM
%token UNION_SYM
%token UNIQUE_SYM
%token UNKNOWN_SYM
%token USAGE
%token USE_FRM
%token USE_SYM
@ -638,8 +645,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token BEFORE_SYM
%left SET_VAR
%left OR_OR_CONCAT OR_SYM XOR
%left AND_SYM
%left OR_OR_SYM OR_SYM OR2_SYM XOR
%left AND_SYM AND_AND_SYM
%left BETWEEN_SYM CASE_SYM WHEN_SYM THEN_SYM ELSE
%left EQ EQUAL_SYM GE GT_SYM LE LT NE IS LIKE REGEXP IN_SYM
%left '|'
@ -649,7 +656,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%left '*' '/' '%' DIV_SYM MOD_SYM
%left '^'
%left NEG '~'
%right NOT
%right NOT_SYM NOT2_SYM
%right BINARY COLLATE_SYM
%type <lex_str>
@ -692,7 +699,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <item>
literal text_literal insert_ident order_ident
simple_ident select_item2 expr opt_expr opt_else sum_expr in_sum_expr
table_wild no_in_expr expr_expr simple_expr no_and_expr udf_expr
bool_term bool_factor bool_test bool_pri
predicate bit_expr bit_term bit_factor value_expr term factor
table_wild simple_expr udf_expr
using_list expr_or_default set_expr_or_default interval_expr
param_marker singlerow_subselect singlerow_subselect_init
exists_subselect exists_subselect_init geometry_function
@ -805,7 +814,7 @@ END_OF_INPUT
%type <NONE>
'-' '+' '*' '/' '%' '(' ')'
',' '!' '{' '}' '&' '|' AND_SYM OR_SYM OR_OR_CONCAT BETWEEN_SYM CASE_SYM
',' '!' '{' '}' '&' '|' AND_SYM OR_SYM OR_OR_SYM BETWEEN_SYM CASE_SYM
THEN_SYM WHEN_SYM DIV_SYM MOD_SYM
%%
@ -1405,7 +1414,7 @@ sp_chistic:
sp_c_chistic:
sp_chistic { }
| DETERMINISTIC_SYM { Lex->sp_chistics.detistic= TRUE; }
| NOT DETERMINISTIC_SYM { Lex->sp_chistics.detistic= FALSE; }
| not DETERMINISTIC_SYM { Lex->sp_chistics.detistic= FALSE; }
;
sp_suid:
@ -1756,7 +1765,7 @@ sp_hcond:
$$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t));
$$->type= sp_cond_type_t::warning;
}
| NOT FOUND_SYM /* SQLSTATEs 02??? */
| not FOUND_SYM /* SQLSTATEs 02??? */
{
$$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t));
$$->type= sp_cond_type_t::notfound;
@ -2495,7 +2504,7 @@ table_option:
opt_if_not_exists:
/* empty */ { $$= 0; }
| IF NOT EXISTS { $$=HA_LEX_CREATE_IF_NOT_EXISTS; };
| IF not EXISTS { $$=HA_LEX_CREATE_IF_NOT_EXISTS; };
opt_create_table_options:
/* empty */
@ -2741,6 +2750,9 @@ type:
| BINARY '(' NUM ')' { Lex->length=$3.str;
Lex->charset=&my_charset_bin;
$$=FIELD_TYPE_STRING; }
| BINARY { Lex->length= (char*) "1";
Lex->charset=&my_charset_bin;
$$=FIELD_TYPE_STRING; }
| varchar '(' NUM ')' opt_binary { Lex->length=$3.str;
$$=FIELD_TYPE_VAR_STRING; }
| nvarchar '(' NUM ')' { Lex->length=$3.str;
@ -2917,7 +2929,7 @@ opt_attribute_list:
attribute:
NULL_SYM { Lex->type&= ~ NOT_NULL_FLAG; }
| NOT NULL_SYM { Lex->type|= NOT_NULL_FLAG; }
| not NULL_SYM { Lex->type|= NOT_NULL_FLAG; }
| DEFAULT now_or_signed_literal { Lex->default_value=$2; }
| ON UPDATE_SYM NOW_SYM optional_braces
{ Lex->on_update_value= new Item_func_now_local(); }
@ -3956,9 +3968,102 @@ optional_braces:
/* all possible expressions */
expr:
expr_expr { $$= $1; }
| simple_expr { $$= $1; }
;
expr or bool_term { $$= new Item_cond_or($1,$3); }
| expr XOR bool_term { $$= new Item_cond_xor($1,$3); }
| bool_term ;
bool_term:
bool_term and bool_factor { $$= new Item_cond_and($1,$3); }
| bool_factor ;
bool_factor:
NOT_SYM bool_factor { $$= negate_expression(YYTHD, $2); }
| bool_test ;
bool_test:
bool_pri IS TRUE_SYM { $$= is_truth_value($1,1,0); }
| bool_pri IS not TRUE_SYM { $$= is_truth_value($1,0,0); }
| bool_pri IS FALSE_SYM { $$= is_truth_value($1,0,1); }
| bool_pri IS not FALSE_SYM { $$= is_truth_value($1,1,1); }
| bool_pri IS UNKNOWN_SYM { $$= new Item_func_isnull($1); }
| bool_pri IS not UNKNOWN_SYM { $$= new Item_func_isnotnull($1); }
| bool_pri ;
bool_pri:
bool_pri IS NULL_SYM { $$= new Item_func_isnull($1); }
| bool_pri IS not NULL_SYM { $$= new Item_func_isnotnull($1); }
| predicate BETWEEN_SYM bit_expr AND_SYM bool_pri
{ $$= new Item_func_between($1,$3,$5); }
| predicate not BETWEEN_SYM bit_expr AND_SYM bool_pri
{ $$= negate_expression(YYTHD, new Item_func_between($1,$4,$6)); }
| predicate ;
predicate:
bit_expr IN_SYM '(' expr_list ')'
{ $4->push_front($1); $$= new Item_func_in(*$4); }
| bit_expr not IN_SYM '(' expr_list ')'
{ $5->push_front($1); $$= negate_expression(YYTHD, new Item_func_in(*$5)); }
| bit_expr IN_SYM in_subselect
{ $$= new Item_in_subselect($1, $3); }
| bit_expr not IN_SYM in_subselect
{ $$= negate_expression(YYTHD, new Item_in_subselect($1, $4)); }
| bit_expr SOUNDS_SYM LIKE bit_expr
{ $$= new Item_func_eq(new Item_func_soundex($1),
new Item_func_soundex($4)); }
| bit_expr LIKE simple_expr opt_escape
{ $$= new Item_func_like($1,$3,$4); }
| bit_expr not LIKE simple_expr opt_escape
{ $$= new Item_func_not(new Item_func_like($1,$4,$5)); }
| bit_expr REGEXP bit_expr { $$= new Item_func_regex($1,$3); }
| bit_expr not REGEXP bit_expr
{ $$= negate_expression(YYTHD, new Item_func_regex($1,$4)); }
| bit_expr EQUAL_SYM bit_expr { $$= new Item_func_equal($1,$3); }
| bit_expr comp_op bit_expr %prec EQ
{ $$= (*$2)(0)->create($1,$3); }
| bit_expr comp_op all_or_any in_subselect %prec EQ
{ $$= all_any_subquery_creator($1, $2, $3, $4); }
| bit_expr ;
bit_expr:
bit_expr '|' bit_term { $$= new Item_func_bit_or($1,$3); }
| bit_term ;
bit_term:
bit_term '&' bit_factor { $$= new Item_func_bit_and($1,$3); }
| bit_factor ;
bit_factor:
bit_factor SHIFT_LEFT value_expr
{ $$= new Item_func_shift_left($1,$3); }
| bit_factor SHIFT_RIGHT value_expr
{ $$= new Item_func_shift_right($1,$3); }
| value_expr ;
value_expr:
value_expr '+' term { $$= new Item_func_plus($1,$3); }
| value_expr '-' term { $$= new Item_func_minus($1,$3); }
| value_expr '+' interval_expr interval
{ $$= new Item_date_add_interval($1,$3,$4,0); }
| value_expr '-' interval_expr interval
{ $$= new Item_date_add_interval($1,$3,$4,1); }
| term ;
term:
term '*' factor { $$= new Item_func_mul($1,$3); }
| term '/' factor { $$= new Item_func_div($1,$3); }
| term '%' factor { $$= new Item_func_mod($1,$3); }
| term DIV_SYM factor { $$= new Item_func_int_div($1,$3); }
| term MOD_SYM factor { $$= new Item_func_mod($1,$3); }
| factor ;
factor:
factor '^' simple_expr { $$= new Item_func_bit_xor($1,$3); }
| simple_expr ;
or: OR_SYM | OR2_SYM;
and: AND_SYM | AND_AND_SYM;
not: NOT_SYM | NOT2_SYM;
not2: '!' | NOT2_SYM;
comp_op: EQ { $$ = &comp_eq_creator; }
| GE { $$ = &comp_ge_creator; }
@ -3972,169 +4077,6 @@ all_or_any: ALL { $$ = 1; }
| ANY_SYM { $$ = 0; }
;
/* expressions that begin with 'expr' */
expr_expr:
expr IN_SYM '(' expr_list ')'
{ $4->push_front($1); $$= new Item_func_in(*$4); }
| expr NOT IN_SYM '(' expr_list ')'
{ $5->push_front($1); $$= new Item_func_not(new Item_func_in(*$5)); }
| expr IN_SYM in_subselect
{ $$= new Item_in_subselect($1, $3); }
| expr NOT IN_SYM in_subselect
{
$$= new Item_func_not(new Item_in_subselect($1, $4));
}
| expr BETWEEN_SYM no_and_expr AND_SYM expr
{ $$= new Item_func_between($1,$3,$5); }
| expr NOT BETWEEN_SYM no_and_expr AND_SYM expr
{ $$= new Item_func_not(new Item_func_between($1,$4,$6)); }
| expr OR_OR_CONCAT expr { $$= or_or_concat(YYTHD, $1,$3); }
| expr OR_SYM expr { $$= new Item_cond_or($1,$3); }
| expr XOR expr { $$= new Item_cond_xor($1,$3); }
| expr AND_SYM expr { $$= new Item_cond_and($1,$3); }
| expr SOUNDS_SYM LIKE expr
{
$$= new Item_func_eq(new Item_func_soundex($1),
new Item_func_soundex($4));
}
| expr LIKE simple_expr opt_escape
{ $$= new Item_func_like($1,$3,$4); }
| expr NOT LIKE simple_expr opt_escape
{ $$= new Item_func_not(new Item_func_like($1,$4,$5));}
| expr REGEXP expr { $$= new Item_func_regex($1,$3); }
| expr NOT REGEXP expr
{ $$= new Item_func_not(new Item_func_regex($1,$4)); }
| expr IS NULL_SYM { $$= new Item_func_isnull($1); }
| expr IS NOT NULL_SYM { $$= new Item_func_isnotnull($1); }
| expr EQUAL_SYM expr { $$= new Item_func_equal($1,$3); }
| expr comp_op expr %prec EQ { $$= (*$2)(0)->create($1,$3); }
| expr comp_op all_or_any in_subselect %prec EQ
{
$$= all_any_subquery_creator($1, $2, $3, $4);
}
| expr SHIFT_LEFT expr { $$= new Item_func_shift_left($1,$3); }
| expr SHIFT_RIGHT expr { $$= new Item_func_shift_right($1,$3); }
| expr '+' expr { $$= new Item_func_plus($1,$3); }
| expr '-' expr { $$= new Item_func_minus($1,$3); }
| expr '*' expr { $$= new Item_func_mul($1,$3); }
| expr '/' expr { $$= new Item_func_div($1,$3); }
| expr DIV_SYM expr { $$= new Item_func_int_div($1,$3); }
| expr MOD_SYM expr { $$= new Item_func_mod($1,$3); }
| expr '|' expr { $$= new Item_func_bit_or($1,$3); }
| expr '^' expr { $$= new Item_func_bit_xor($1,$3); }
| expr '&' expr { $$= new Item_func_bit_and($1,$3); }
| expr '%' expr { $$= new Item_func_mod($1,$3); }
| expr '+' interval_expr interval
{ $$= new Item_date_add_interval($1,$3,$4,0); }
| expr '-' interval_expr interval
{ $$= new Item_date_add_interval($1,$3,$4,1); }
;
/* expressions that begin with 'expr' that do NOT follow IN_SYM */
no_in_expr:
no_in_expr BETWEEN_SYM no_and_expr AND_SYM expr
{ $$= new Item_func_between($1,$3,$5); }
| no_in_expr NOT BETWEEN_SYM no_and_expr AND_SYM expr
{ $$= new Item_func_not(new Item_func_between($1,$4,$6)); }
| no_in_expr OR_OR_CONCAT expr { $$= or_or_concat(YYTHD, $1,$3); }
| no_in_expr OR_SYM expr { $$= new Item_cond_or($1,$3); }
| no_in_expr XOR expr { $$= new Item_cond_xor($1,$3); }
| no_in_expr AND_SYM expr { $$= new Item_cond_and($1,$3); }
| no_in_expr SOUNDS_SYM LIKE expr
{
$$= new Item_func_eq(new Item_func_soundex($1),
new Item_func_soundex($4));
}
| no_in_expr LIKE simple_expr opt_escape
{ $$= new Item_func_like($1,$3,$4); }
| no_in_expr NOT LIKE simple_expr opt_escape
{ $$= new Item_func_not(new Item_func_like($1,$4,$5)); }
| no_in_expr REGEXP expr { $$= new Item_func_regex($1,$3); }
| no_in_expr NOT REGEXP expr
{ $$= new Item_func_not(new Item_func_regex($1,$4)); }
| no_in_expr IS NULL_SYM { $$= new Item_func_isnull($1); }
| no_in_expr IS NOT NULL_SYM { $$= new Item_func_isnotnull($1); }
| no_in_expr EQUAL_SYM expr { $$= new Item_func_equal($1,$3); }
| no_in_expr comp_op expr %prec EQ { $$= (*$2)(0)->create($1,$3); }
| no_in_expr comp_op all_or_any in_subselect %prec EQ
{
all_any_subquery_creator($1, $2, $3, $4);
}
| no_in_expr SHIFT_LEFT expr { $$= new Item_func_shift_left($1,$3); }
| no_in_expr SHIFT_RIGHT expr { $$= new Item_func_shift_right($1,$3); }
| no_in_expr '+' expr { $$= new Item_func_plus($1,$3); }
| no_in_expr '-' expr { $$= new Item_func_minus($1,$3); }
| no_in_expr '*' expr { $$= new Item_func_mul($1,$3); }
| no_in_expr '/' expr { $$= new Item_func_div($1,$3); }
| no_in_expr DIV_SYM expr { $$= new Item_func_int_div($1,$3); }
| no_in_expr '|' expr { $$= new Item_func_bit_or($1,$3); }
| no_in_expr '^' expr { $$= new Item_func_bit_xor($1,$3); }
| no_in_expr '&' expr { $$= new Item_func_bit_and($1,$3); }
| no_in_expr '%' expr { $$= new Item_func_mod($1,$3); }
| no_in_expr MOD_SYM expr { $$= new Item_func_mod($1,$3); }
| no_in_expr '+' interval_expr interval
{ $$= new Item_date_add_interval($1,$3,$4,0); }
| no_in_expr '-' interval_expr interval
{ $$= new Item_date_add_interval($1,$3,$4,1); }
| simple_expr;
/* expressions that begin with 'expr' that does NOT follow AND */
no_and_expr:
no_and_expr IN_SYM '(' expr_list ')'
{ $4->push_front($1); $$= new Item_func_in(*$4); }
| no_and_expr NOT IN_SYM '(' expr_list ')'
{ $5->push_front($1); $$= new Item_func_not(new Item_func_in(*$5)); }
| no_and_expr IN_SYM in_subselect
{ $$= new Item_in_subselect($1, $3); }
| no_and_expr NOT IN_SYM in_subselect
{
$$= new Item_func_not(new Item_in_subselect($1, $4));
}
| no_and_expr BETWEEN_SYM no_and_expr AND_SYM expr
{ $$= new Item_func_between($1,$3,$5); }
| no_and_expr NOT BETWEEN_SYM no_and_expr AND_SYM expr
{ $$= new Item_func_not(new Item_func_between($1,$4,$6)); }
| no_and_expr OR_OR_CONCAT expr { $$= or_or_concat(YYTHD, $1,$3); }
| no_and_expr OR_SYM expr { $$= new Item_cond_or($1,$3); }
| no_and_expr XOR expr { $$= new Item_cond_xor($1,$3); }
| no_and_expr SOUNDS_SYM LIKE expr
{
$$= new Item_func_eq(new Item_func_soundex($1),
new Item_func_soundex($4));
}
| no_and_expr LIKE simple_expr opt_escape
{ $$= new Item_func_like($1,$3,$4); }
| no_and_expr NOT LIKE simple_expr opt_escape
{ $$= new Item_func_not(new Item_func_like($1,$4,$5)); }
| no_and_expr REGEXP expr { $$= new Item_func_regex($1,$3); }
| no_and_expr NOT REGEXP expr
{ $$= new Item_func_not(new Item_func_regex($1,$4)); }
| no_and_expr IS NULL_SYM { $$= new Item_func_isnull($1); }
| no_and_expr IS NOT NULL_SYM { $$= new Item_func_isnotnull($1); }
| no_and_expr EQUAL_SYM expr { $$= new Item_func_equal($1,$3); }
| no_and_expr comp_op expr %prec EQ { $$= (*$2)(0)->create($1,$3); }
| no_and_expr comp_op all_or_any in_subselect %prec EQ
{
all_any_subquery_creator($1, $2, $3, $4);
}
| no_and_expr SHIFT_LEFT expr { $$= new Item_func_shift_left($1,$3); }
| no_and_expr SHIFT_RIGHT expr { $$= new Item_func_shift_right($1,$3); }
| no_and_expr '+' expr { $$= new Item_func_plus($1,$3); }
| no_and_expr '-' expr { $$= new Item_func_minus($1,$3); }
| no_and_expr '*' expr { $$= new Item_func_mul($1,$3); }
| no_and_expr '/' expr { $$= new Item_func_div($1,$3); }
| no_and_expr DIV_SYM expr { $$= new Item_func_int_div($1,$3); }
| no_and_expr '|' expr { $$= new Item_func_bit_or($1,$3); }
| no_and_expr '^' expr { $$= new Item_func_bit_xor($1,$3); }
| no_and_expr '&' expr { $$= new Item_func_bit_and($1,$3); }
| no_and_expr '%' expr { $$= new Item_func_mod($1,$3); }
| no_and_expr MOD_SYM expr { $$= new Item_func_mod($1,$3); }
| no_and_expr '+' interval_expr interval
{ $$= new Item_date_add_interval($1,$3,$4,0); }
| no_and_expr '-' interval_expr interval
{ $$= new Item_date_add_interval($1,$3,$4,1); }
| simple_expr;
interval_expr:
INTERVAL_SYM expr { $$=$2; }
;
@ -4177,17 +4119,12 @@ simple_expr:
Lex->variables_used= 1;
}
| sum_expr
| '+' expr %prec NEG { $$= $2; }
| '-' expr %prec NEG { $$= new Item_func_neg($2); }
| '~' expr %prec NEG { $$= new Item_func_bit_neg($2); }
| NOT expr %prec NEG
{
$$= negate_expression(YYTHD, $2);
}
| '!' expr %prec NEG
{
$$= negate_expression(YYTHD, $2);
}
| simple_expr OR_OR_SYM simple_expr
{ $$= new Item_func_concat($1, $3); }
| '+' simple_expr %prec NEG { $$= $2; }
| '-' simple_expr %prec NEG { $$= new Item_func_neg($2); }
| '~' simple_expr %prec NEG { $$= new Item_func_bit_neg($2); }
| not2 simple_expr %prec NEG { $$= negate_expression(YYTHD, $2); }
| '(' expr ')' { $$= $2; }
| '(' expr ',' expr_list ')'
{
@ -4202,12 +4139,12 @@ simple_expr:
| EXISTS exists_subselect { $$= $2; }
| singlerow_subselect { $$= $1; }
| '{' ident expr '}' { $$= $3; }
| MATCH ident_list_arg AGAINST '(' expr fulltext_options ')'
| MATCH ident_list_arg AGAINST '(' bit_expr fulltext_options ')'
{ $2->push_front($5);
Select->add_ftfunc_to_list((Item_func_match*)
($$=new Item_func_match(*$2,$6))); }
| ASCII_SYM '(' expr ')' { $$= new Item_func_ascii($3); }
| BINARY expr %prec NEG
| BINARY simple_expr %prec NEG
{
$$= create_func_cast($2, ITEM_CAST_CHAR, -1, &my_charset_bin);
}
@ -4452,7 +4389,7 @@ simple_expr:
}
| OLD_PASSWORD '(' expr ')'
{ $$= new Item_func_old_password($3); }
| POSITION_SYM '(' no_in_expr IN_SYM expr ')'
| POSITION_SYM '(' bit_expr IN_SYM expr ')'
{ $$ = new Item_func_locate($5,$3); }
| QUARTER_SYM '(' expr ')'
{ $$ = new Item_func_quarter($3); }
@ -5479,11 +5416,12 @@ do: DO_SYM
{
LEX *lex=Lex;
lex->sql_command = SQLCOM_DO;
if (!(lex->insert_list = new List_item))
YYABORT;
mysql_init_select(lex);
}
expr_list
{
Lex->insert_list= $3;
}
values
{}
;
/*
@ -7107,6 +7045,7 @@ keyword:
| UNCOMMITTED_SYM {}
| UNDEFINED_SYM {}
| UNICODE_SYM {}
| UNKNOWN_SYM {}
| UNTIL_SYM {}
| USER {}
| USE_FRM {}

View file

@ -89,7 +89,12 @@ typedef struct st_key {
enum ha_key_alg algorithm;
KEY_PART_INFO *key_part;
char *name; /* Name of key */
ulong *rec_per_key; /* Key part distribution */
/*
Array of AVG(#records with the same field value) for 1st ... Nth key part.
0 means 'not known'.
For temporary heap tables this member is NULL.
*/
ulong *rec_per_key;
union {
int bdb_return_if_eq;
} handler;
@ -161,6 +166,7 @@ enum SHOW_TYPE
SHOW_LONG, SHOW_LONGLONG, SHOW_INT, SHOW_CHAR, SHOW_CHAR_PTR, SHOW_DOUBLE,
SHOW_BOOL, SHOW_MY_BOOL, SHOW_OPENTABLES, SHOW_STARTTIME, SHOW_QUESTION,
SHOW_LONG_CONST, SHOW_INT_CONST, SHOW_HAVE, SHOW_SYS, SHOW_HA_ROWS,
SHOW_VARS,
#ifdef HAVE_OPENSSL
SHOW_SSL_CTX_SESS_ACCEPT, SHOW_SSL_CTX_SESS_ACCEPT_GOOD,
SHOW_SSL_GET_VERSION, SHOW_SSL_CTX_GET_SESSION_CACHE_MODE,

View file

@ -232,7 +232,6 @@ typedef struct st_field_info
enum enum_field_types field_type;
int value;
bool maybe_null;
bool utf8;
const char* old_name;
} ST_FIELD_INFO;

View file

@ -541,7 +541,7 @@ int my_strnncoll_tis620(CHARSET_INFO *cs __attribute__((unused)),
tc1= buf;
if ((len1 + len2 +2) > (int) sizeof(buf))
tc1= (uchar*) malloc(len1+len2);
tc1= (uchar*) malloc(len1+len2+2);
tc2= tc1 + len1+1;
memcpy((char*) tc1, (char*) s1, len1);
tc1[len1]= 0; /* if length(s1)> len1, need to put 'end of string' */
@ -568,7 +568,7 @@ int my_strnncollsp_tis620(CHARSET_INFO * cs __attribute__((unused)),
a= buf;
if ((a_length + b_length +2) > (int) sizeof(buf))
alloced= a= (uchar*) malloc(a_length+b_length);
alloced= a= (uchar*) malloc(a_length+b_length+2);
b= a + a_length+1;
memcpy((char*) a, (char*) a0, a_length);

View file

@ -7261,22 +7261,22 @@ static void test_explain_bug()
DIE_UNLESS(6 == mysql_num_fields(result));
verify_prepare_field(result, 0, "Field", "COLUMN_NAME",
MYSQL_TYPE_STRING, 0, 0, "", NAME_LEN, 0);
MYSQL_TYPE_STRING, 0, 0, "", 192, 0);
verify_prepare_field(result, 1, "Type", "TYPE",
MYSQL_TYPE_STRING, 0, 0, "", 40, 0);
MYSQL_TYPE_STRING, 0, 0, "", 120, 0);
verify_prepare_field(result, 2, "Null", "IS_NULLABLE",
MYSQL_TYPE_STRING, 0, 0, "", 3, 0);
MYSQL_TYPE_STRING, 0, 0, "", 9, 0);
verify_prepare_field(result, 3, "Key", "KEY",
MYSQL_TYPE_STRING, 0, 0, "", 3, 0);
MYSQL_TYPE_STRING, 0, 0, "", 9, 0);
verify_prepare_field(result, 4, "Default", "COLUMN_DEFAULT",
MYSQL_TYPE_STRING, 0, 0, "", NAME_LEN, 0);
MYSQL_TYPE_STRING, 0, 0, "", 192, 0);
verify_prepare_field(result, 5, "Extra", "EXTRA",
MYSQL_TYPE_STRING, 0, 0, "", 20, 0);
MYSQL_TYPE_STRING, 0, 0, "", 60, 0);
mysql_free_result(result);
mysql_stmt_close(stmt);