mirror of
https://github.com/MariaDB/server.git
synced 2025-01-21 22:34:18 +01:00
Merge mysql.com:/home/jonas/src/mysql-5.0
into mysql.com:/home/jonas/src/mysql-5.0-ndb
This commit is contained in:
commit
d7f6078d45
83 changed files with 1977 additions and 816 deletions
|
@ -960,3 +960,4 @@ vio/test-sslclient
|
|||
vio/test-sslserver
|
||||
vio/viotest-ssl
|
||||
ac_available_languages_fragment
|
||||
ndb/tools/ndb_restore
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,'');
|
||||
|
|
|
@ -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 '',
|
||||
|
|
|
@ -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` (
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
#
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
#
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 |
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
995
sql/sql_show.cc
995
sql/sql_show.cc
File diff suppressed because it is too large
Load diff
|
@ -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;
|
||||
/*
|
||||
|
|
335
sql/sql_yacc.yy
335
sql/sql_yacc.yy
|
@ -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 {}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue