mirror of
https://github.com/MariaDB/server.git
synced 2026-05-15 19:37:16 +02:00
Merge work:/my/mysql-4.0 into mashka.mysql.fi:/home/my/mysql-4.0
This commit is contained in:
commit
cf2ef3c68f
17 changed files with 207 additions and 52 deletions
|
|
@ -263,6 +263,7 @@ enum ha_base_keytype {
|
||||||
#define MBR_EQUAL 8192
|
#define MBR_EQUAL 8192
|
||||||
#define MBR_DATA 16384
|
#define MBR_DATA 16384
|
||||||
#define SEARCH_NULL_ARE_EQUAL 32768 /* NULL in keys are equal */
|
#define SEARCH_NULL_ARE_EQUAL 32768 /* NULL in keys are equal */
|
||||||
|
#define SEARCH_NULL_ARE_NOT_EQUAL 65536 /* NULL in keys are not equal */
|
||||||
|
|
||||||
/* bits in opt_flag */
|
/* bits in opt_flag */
|
||||||
#define QUICK_USED 1
|
#define QUICK_USED 1
|
||||||
|
|
|
||||||
|
|
@ -601,7 +601,8 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
|
||||||
if (*keys != 1L) /* not first_key */
|
if (*keys != 1L) /* not first_key */
|
||||||
{
|
{
|
||||||
uint diff;
|
uint diff;
|
||||||
_mi_key_cmp(keyinfo->seg,info->lastkey,key,USE_WHOLE_KEY,SEARCH_FIND,
|
_mi_key_cmp(keyinfo->seg,info->lastkey,key,USE_WHOLE_KEY,
|
||||||
|
SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL,
|
||||||
&diff);
|
&diff);
|
||||||
param->unique_count[diff-1]++;
|
param->unique_count[diff-1]++;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,12 +55,17 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
|
||||||
/*
|
/*
|
||||||
Free buffers and reset the following flags:
|
Free buffers and reset the following flags:
|
||||||
EXTRA_CACHE, EXTRA_WRITE_CACHE, EXTRA_KEYREAD, EXTRA_QUICK
|
EXTRA_CACHE, EXTRA_WRITE_CACHE, EXTRA_KEYREAD, EXTRA_QUICK
|
||||||
|
|
||||||
|
If the row buffer cache is large (for dynamic tables), reduce it
|
||||||
|
to save memory.
|
||||||
*/
|
*/
|
||||||
if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
|
if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
|
||||||
{
|
{
|
||||||
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
|
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
|
||||||
error=end_io_cache(&info->rec_cache);
|
error=end_io_cache(&info->rec_cache);
|
||||||
}
|
}
|
||||||
|
if (share->base.blobs)
|
||||||
|
mi_alloc_rec_buff(info, -1, &info->rec_buff);
|
||||||
#if defined(HAVE_MMAP) && defined(HAVE_MADVICE)
|
#if defined(HAVE_MMAP) && defined(HAVE_MADVICE)
|
||||||
if (info->opt_flag & MEMMAP_USED)
|
if (info->opt_flag & MEMMAP_USED)
|
||||||
madvise(share->file_map,share->state.state.data_file_length,MADV_RANDOM);
|
madvise(share->file_map,share->state.state.data_file_length,MADV_RANDOM);
|
||||||
|
|
|
||||||
|
|
@ -559,28 +559,36 @@ err:
|
||||||
DBUG_RETURN (NULL);
|
DBUG_RETURN (NULL);
|
||||||
} /* mi_open */
|
} /* mi_open */
|
||||||
|
|
||||||
|
|
||||||
byte *mi_alloc_rec_buff(MI_INFO *info, ulong length, byte **buf)
|
byte *mi_alloc_rec_buff(MI_INFO *info, ulong length, byte **buf)
|
||||||
{
|
{
|
||||||
uint extra;
|
uint extra;
|
||||||
|
uint32 old_length;
|
||||||
|
LINT_INIT(old_length);
|
||||||
|
|
||||||
if (! *buf || length > mi_get_rec_buff_len(info, *buf))
|
if (! *buf || length > (old_length=mi_get_rec_buff_len(info, *buf)))
|
||||||
{
|
{
|
||||||
byte *newptr = *buf;
|
byte *newptr = *buf;
|
||||||
|
|
||||||
/* to simplify initial init of info->rec_buf in mi_open and mi_extra */
|
/* to simplify initial init of info->rec_buf in mi_open and mi_extra */
|
||||||
if (length == (ulong) -1)
|
if (length == (ulong) -1)
|
||||||
|
{
|
||||||
length= max(info->s->base.pack_reclength+info->s->base.pack_bits,
|
length= max(info->s->base.pack_reclength+info->s->base.pack_bits,
|
||||||
info->s->base.max_key_length);
|
info->s->base.max_key_length);
|
||||||
|
/* Avoid unnecessary realloc */
|
||||||
|
if (newptr && length == old_length)
|
||||||
|
return newptr;
|
||||||
|
}
|
||||||
|
|
||||||
extra= ((info->s->options & HA_OPTION_PACK_RECORD) ?
|
extra= ((info->s->options & HA_OPTION_PACK_RECORD) ?
|
||||||
ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER)+MI_SPLIT_LENGTH+
|
ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER)+MI_SPLIT_LENGTH+
|
||||||
MI_REC_BUFF_OFFSET : 0);
|
MI_REC_BUFF_OFFSET : 0);
|
||||||
if (extra && newptr)
|
if (extra && newptr)
|
||||||
newptr-=MI_REC_BUFF_OFFSET;
|
newptr-= MI_REC_BUFF_OFFSET;
|
||||||
if (!(newptr=(byte*) my_realloc((gptr)newptr, length+extra+8,
|
if (!(newptr=(byte*) my_realloc((gptr)newptr, length+extra+8,
|
||||||
MYF(MY_ALLOW_ZERO_PTR))))
|
MYF(MY_ALLOW_ZERO_PTR))))
|
||||||
return newptr;
|
return newptr;
|
||||||
*((uint *)newptr)=length;
|
*((uint32 *) newptr)= (uint32) length;
|
||||||
*buf= newptr+(extra ? MI_REC_BUFF_OFFSET : 0);
|
*buf= newptr+(extra ? MI_REC_BUFF_OFFSET : 0);
|
||||||
}
|
}
|
||||||
return *buf;
|
return *buf;
|
||||||
|
|
|
||||||
|
|
@ -260,9 +260,11 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
|
||||||
uchar *key, uint key_len, uint nextflag, uchar **ret_pos,
|
uchar *key, uint key_len, uint nextflag, uchar **ret_pos,
|
||||||
uchar *buff, my_bool *last_key)
|
uchar *buff, my_bool *last_key)
|
||||||
{
|
{
|
||||||
/* my_flag is raw comparison result to be changed according to
|
/*
|
||||||
SEARCH_NO_FIND,SEARCH_LAST and HA_REVERSE_SORT flags.
|
my_flag is raw comparison result to be changed according to
|
||||||
flag is the value returned by _mi_key_cmp and as treated as final */
|
SEARCH_NO_FIND,SEARCH_LAST and HA_REVERSE_SORT flags.
|
||||||
|
flag is the value returned by _mi_key_cmp and as treated as final
|
||||||
|
*/
|
||||||
int flag=0, my_flag=-1;
|
int flag=0, my_flag=-1;
|
||||||
uint nod_flag, length, len, matched, cmplen, kseg_len;
|
uint nod_flag, length, len, matched, cmplen, kseg_len;
|
||||||
uint prefix_len,suffix_len;
|
uint prefix_len,suffix_len;
|
||||||
|
|
@ -695,13 +697,29 @@ static int compare_bin(uchar *a, uint a_length, uchar *b, uint b_length,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Compare two keys
|
Compare two keys
|
||||||
** Returns <0, 0, >0 acording to which is bigger
|
|
||||||
** Key_length specifies length of key to use. Number-keys can't
|
SYNOPSIS
|
||||||
** be splited
|
_mi_key_cmp()
|
||||||
** If flag <> SEARCH_FIND compare also position
|
keyseg Key segments of key to compare
|
||||||
*/
|
a First key to compare, in format from _mi_pack_key()
|
||||||
|
This is normally key specified by user
|
||||||
|
b Second key to compare. This is always from a row
|
||||||
|
key_length Length of key to compare. This can be shorter than
|
||||||
|
a to just compare sub keys
|
||||||
|
next_flag How keys should be compared
|
||||||
|
If bit SEARCH_FIND is not set the keys includes the row
|
||||||
|
position and this should also be compared
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
Number-keys can't be splited
|
||||||
|
|
||||||
|
RETURN VALUES
|
||||||
|
<0 If a < b
|
||||||
|
0 If a == b
|
||||||
|
>0 If a > b
|
||||||
|
*/
|
||||||
|
|
||||||
#define FCMP(A,B) ((int) (A) - (int) (B))
|
#define FCMP(A,B) ((int) (A) - (int) (B))
|
||||||
|
|
||||||
|
|
@ -738,6 +756,15 @@ int _mi_key_cmp(register MI_KEYSEG *keyseg, register uchar *a,
|
||||||
{
|
{
|
||||||
if (nextflag == (SEARCH_FIND | SEARCH_UPDATE))
|
if (nextflag == (SEARCH_FIND | SEARCH_UPDATE))
|
||||||
nextflag=SEARCH_SAME; /* Allow duplicate keys */
|
nextflag=SEARCH_SAME; /* Allow duplicate keys */
|
||||||
|
else if (nextflag & SEARCH_NULL_ARE_NOT_EQUAL)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
This is only used from mi_check() to calculate cardinality.
|
||||||
|
It can't be used when searching for a key as this would cause
|
||||||
|
compare of (a,b) and (b,a) to return the same value.
|
||||||
|
*/
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
next_key_length=key_length;
|
next_key_length=key_length;
|
||||||
continue; /* To next key part */
|
continue; /* To next key part */
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -358,7 +358,7 @@ struct st_myisam_info {
|
||||||
#define MI_DYN_ALIGN_SIZE 4 /* Align blocks on this */
|
#define MI_DYN_ALIGN_SIZE 4 /* Align blocks on this */
|
||||||
#define MI_MAX_DYN_HEADER_BYTE 13 /* max header byte for dynamic rows */
|
#define MI_MAX_DYN_HEADER_BYTE 13 /* max header byte for dynamic rows */
|
||||||
#define MI_MAX_BLOCK_LENGTH ((((ulong) 1 << 24)-1) & (~ (ulong) (MI_DYN_ALIGN_SIZE-1)))
|
#define MI_MAX_BLOCK_LENGTH ((((ulong) 1 << 24)-1) & (~ (ulong) (MI_DYN_ALIGN_SIZE-1)))
|
||||||
#define MI_REC_BUFF_OFFSET ALIGN_SIZE(MI_DYN_DELETE_BLOCK_HEADER+sizeof(uint))
|
#define MI_REC_BUFF_OFFSET ALIGN_SIZE(MI_DYN_DELETE_BLOCK_HEADER+sizeof(uint32))
|
||||||
|
|
||||||
#define MEMMAP_EXTRA_MARGIN 7 /* Write this as a suffix for file */
|
#define MEMMAP_EXTRA_MARGIN 7 /* Write this as a suffix for file */
|
||||||
|
|
||||||
|
|
@ -529,7 +529,7 @@ extern byte *mi_alloc_rec_buff(MI_INFO *,ulong, byte**);
|
||||||
((((info)->s->options & HA_OPTION_PACK_RECORD) && (buf)) ? \
|
((((info)->s->options & HA_OPTION_PACK_RECORD) && (buf)) ? \
|
||||||
(buf) - MI_REC_BUFF_OFFSET : (buf))
|
(buf) - MI_REC_BUFF_OFFSET : (buf))
|
||||||
#define mi_get_rec_buff_len(info,buf) \
|
#define mi_get_rec_buff_len(info,buf) \
|
||||||
(*((uint *)(mi_get_rec_buff_ptr(info,buf))))
|
(*((uint32 *)(mi_get_rec_buff_ptr(info,buf))))
|
||||||
|
|
||||||
extern ulong _mi_rec_unpack(MI_INFO *info,byte *to,byte *from,
|
extern ulong _mi_rec_unpack(MI_INFO *info,byte *to,byte *from,
|
||||||
ulong reclength);
|
ulong reclength);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
drop table if exists t1;
|
drop table if exists t1,t2;
|
||||||
CREATE TABLE t1 (
|
CREATE TABLE t1 (
|
||||||
STRING_DATA char(255) default NULL,
|
STRING_DATA char(255) default NULL,
|
||||||
KEY STRING_DATA (STRING_DATA)
|
KEY STRING_DATA (STRING_DATA)
|
||||||
|
|
@ -318,3 +318,45 @@ CREATE TABLE t1 (a varchar(255), b varchar(255), c varchar(255));
|
||||||
ALTER TABLE t1 ADD INDEX t1 (a, b, c);
|
ALTER TABLE t1 ADD INDEX t1 (a, b, c);
|
||||||
Specified key was too long. Max key length is 500
|
Specified key was too long. Max key length is 500
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a int not null, b int, c int, key(b), key(c), key(a,b), key(c,a));
|
||||||
|
INSERT into t1 values (0, null, 0), (0, null, 1), (0, null, 2), (0, null,3), (1,1,4);
|
||||||
|
create table t2 (a int not null, b int, c int, key(b), key(c), key(a));
|
||||||
|
INSERT into t2 values (1,1,1), (2,2,2);
|
||||||
|
optimize table t1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 optimize status OK
|
||||||
|
show index from t1;
|
||||||
|
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
|
||||||
|
t1 1 b 1 b A 5 NULL NULL YES BTREE
|
||||||
|
t1 1 c 1 c A 5 NULL NULL YES BTREE
|
||||||
|
t1 1 a 1 a A 1 NULL NULL BTREE
|
||||||
|
t1 1 a 2 b A 5 NULL NULL YES BTREE
|
||||||
|
t1 1 c_2 1 c A 5 NULL NULL YES BTREE
|
||||||
|
t1 1 c_2 2 a A 5 NULL NULL BTREE
|
||||||
|
explain select * from t1,t2 where t1.a=t2.a;
|
||||||
|
table type possible_keys key key_len ref rows Extra
|
||||||
|
t1 ALL a NULL NULL NULL 5
|
||||||
|
t2 ALL a NULL NULL NULL 2 Using where
|
||||||
|
explain select * from t1,t2 force index(a) where t1.a=t2.a;
|
||||||
|
table type possible_keys key key_len ref rows Extra
|
||||||
|
t2 ALL a NULL NULL NULL 2
|
||||||
|
t1 ALL a NULL NULL NULL 5 Using where
|
||||||
|
explain select * from t1 force index(a),t2 force index(a) where t1.a=t2.a;
|
||||||
|
table type possible_keys key key_len ref rows Extra
|
||||||
|
t2 ALL a NULL NULL NULL 2
|
||||||
|
t1 ref a a 4 t2.a 3
|
||||||
|
explain select * from t1,t2 where t1.b=t2.b;
|
||||||
|
table type possible_keys key key_len ref rows Extra
|
||||||
|
t2 ALL b NULL NULL NULL 2
|
||||||
|
t1 ref b b 5 t2.b 1 Using where
|
||||||
|
explain select * from t1,t2 force index(c) where t1.a=t2.a;
|
||||||
|
table type possible_keys key key_len ref rows Extra
|
||||||
|
t1 ALL a NULL NULL NULL 5
|
||||||
|
t2 ALL NULL NULL NULL NULL 2 Using where
|
||||||
|
explain select * from t1 where a=0 or a=2;
|
||||||
|
table type possible_keys key key_len ref rows Extra
|
||||||
|
t1 ALL a NULL NULL NULL 5 Using where
|
||||||
|
explain select * from t1 force index (a) where a=0 or a=2;
|
||||||
|
table type possible_keys key key_len ref rows Extra
|
||||||
|
t1 range a a 4 NULL 4 Using where
|
||||||
|
drop table t1,t2;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,13 @@
|
||||||
# Test bugs in the MyISAM code
|
# Test bugs in the MyISAM code
|
||||||
#
|
#
|
||||||
|
|
||||||
drop table if exists t1;
|
# Initialise
|
||||||
|
drop table if exists t1,t2;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test problem with CHECK TABLE;
|
||||||
|
#
|
||||||
|
|
||||||
CREATE TABLE t1 (
|
CREATE TABLE t1 (
|
||||||
STRING_DATA char(255) default NULL,
|
STRING_DATA char(255) default NULL,
|
||||||
KEY STRING_DATA (STRING_DATA)
|
KEY STRING_DATA (STRING_DATA)
|
||||||
|
|
@ -326,3 +332,21 @@ CREATE TABLE t1 (a varchar(255), b varchar(255), c varchar(255));
|
||||||
ALTER TABLE t1 ADD INDEX t1 (a, b, c);
|
ALTER TABLE t1 ADD INDEX t1 (a, b, c);
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test of cardinality of keys with NULL
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a int not null, b int, c int, key(b), key(c), key(a,b), key(c,a));
|
||||||
|
INSERT into t1 values (0, null, 0), (0, null, 1), (0, null, 2), (0, null,3), (1,1,4);
|
||||||
|
create table t2 (a int not null, b int, c int, key(b), key(c), key(a));
|
||||||
|
INSERT into t2 values (1,1,1), (2,2,2);
|
||||||
|
optimize table t1;
|
||||||
|
show index from t1;
|
||||||
|
explain select * from t1,t2 where t1.a=t2.a;
|
||||||
|
explain select * from t1,t2 force index(a) where t1.a=t2.a;
|
||||||
|
explain select * from t1 force index(a),t2 force index(a) where t1.a=t2.a;
|
||||||
|
explain select * from t1,t2 where t1.b=t2.b;
|
||||||
|
explain select * from t1,t2 force index(c) where t1.a=t2.a;
|
||||||
|
explain select * from t1 where a=0 or a=2;
|
||||||
|
explain select * from t1 force index (a) where a=0 or a=2;
|
||||||
|
drop table t1,t2;
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,7 @@ static SYMBOL symbols[] = {
|
||||||
{ "FLOAT8", SYM(DOUBLE_SYM),0,0},
|
{ "FLOAT8", SYM(DOUBLE_SYM),0,0},
|
||||||
{ "FLUSH", SYM(FLUSH_SYM),0,0},
|
{ "FLUSH", SYM(FLUSH_SYM),0,0},
|
||||||
{ "FOREIGN", SYM(FOREIGN),0,0},
|
{ "FOREIGN", SYM(FOREIGN),0,0},
|
||||||
|
{ "FORCE", SYM(FORCE_SYM),0,0},
|
||||||
{ "RAID_TYPE", SYM(RAID_TYPE),0,0},
|
{ "RAID_TYPE", SYM(RAID_TYPE),0,0},
|
||||||
{ "RAID_CHUNKS", SYM(RAID_CHUNKS),0,0},
|
{ "RAID_CHUNKS", SYM(RAID_CHUNKS),0,0},
|
||||||
{ "RAID_CHUNKSIZE", SYM(RAID_CHUNKSIZE),0,0},
|
{ "RAID_CHUNKSIZE", SYM(RAID_CHUNKSIZE),0,0},
|
||||||
|
|
|
||||||
|
|
@ -226,6 +226,10 @@ void debug_sync_point(const char* lock_name, uint lock_timeout);
|
||||||
#define SHOW_LOG_STATUS_FREE "FREE"
|
#define SHOW_LOG_STATUS_FREE "FREE"
|
||||||
#define SHOW_LOG_STATUS_INUSE "IN USE"
|
#define SHOW_LOG_STATUS_INUSE "IN USE"
|
||||||
|
|
||||||
|
/* Options to add_table_to_list() */
|
||||||
|
#define TL_OPTION_UPDATING 1
|
||||||
|
#define TL_OPTION_FORCE_INDEX 2
|
||||||
|
|
||||||
/* Some portable defines */
|
/* Some portable defines */
|
||||||
|
|
||||||
#define portable_sizeof_char_ptr 8
|
#define portable_sizeof_char_ptr 8
|
||||||
|
|
@ -509,7 +513,7 @@ bool add_field_to_list(char *field_name, enum enum_field_types type,
|
||||||
void store_position_for_column(const char *name);
|
void store_position_for_column(const char *name);
|
||||||
bool add_to_list(SQL_LIST &list,Item *group,bool asc=0);
|
bool add_to_list(SQL_LIST &list,Item *group,bool asc=0);
|
||||||
TABLE_LIST *add_table_to_list(Table_ident *table,LEX_STRING *alias,
|
TABLE_LIST *add_table_to_list(Table_ident *table,LEX_STRING *alias,
|
||||||
bool updating,
|
ulong table_option,
|
||||||
thr_lock_type flags=TL_UNLOCK,
|
thr_lock_type flags=TL_UNLOCK,
|
||||||
List<String> *use_index=0,
|
List<String> *use_index=0,
|
||||||
List<String> *ignore_index=0);
|
List<String> *ignore_index=0);
|
||||||
|
|
|
||||||
|
|
@ -605,12 +605,14 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables,
|
||||||
records++; /* purecov: inspected */
|
records++; /* purecov: inspected */
|
||||||
scan_time=(double) records / TIME_FOR_COMPARE+1;
|
scan_time=(double) records / TIME_FOR_COMPARE+1;
|
||||||
read_time=(double) head->file->scan_time()+ scan_time + 1.0;
|
read_time=(double) head->file->scan_time()+ scan_time + 1.0;
|
||||||
|
if (head->force_index)
|
||||||
|
scan_time= read_time= DBL_MAX;
|
||||||
if (limit < records)
|
if (limit < records)
|
||||||
read_time=(double) records+scan_time+1; // Force to use index
|
read_time=(double) records+scan_time+1; // Force to use index
|
||||||
else if (read_time <= 2.0 && !force_quick_range)
|
else if (read_time <= 2.0 && !force_quick_range)
|
||||||
DBUG_RETURN(0); /* No need for quick select */
|
DBUG_RETURN(0); /* No need for quick select */
|
||||||
|
|
||||||
DBUG_PRINT("info",("Time to scan table: %ld",(long) read_time));
|
DBUG_PRINT("info",("Time to scan table: %g", read_time));
|
||||||
|
|
||||||
keys_to_use&=head->keys_in_use_for_query;
|
keys_to_use&=head->keys_in_use_for_query;
|
||||||
if (keys_to_use)
|
if (keys_to_use)
|
||||||
|
|
|
||||||
|
|
@ -752,7 +752,7 @@ TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
|
||||||
table->tablenr=thd->current_tablenr++;
|
table->tablenr=thd->current_tablenr++;
|
||||||
table->used_fields=0;
|
table->used_fields=0;
|
||||||
table->const_table=0;
|
table->const_table=0;
|
||||||
table->outer_join=table->null_row=table->maybe_null=0;
|
table->outer_join= table->null_row= table->maybe_null= table->force_index= 0;
|
||||||
table->status=STATUS_NO_RECORD;
|
table->status=STATUS_NO_RECORD;
|
||||||
table->keys_in_use_for_query= table->keys_in_use;
|
table->keys_in_use_for_query= table->keys_in_use;
|
||||||
table->used_keys= table->keys_for_keyread;
|
table->used_keys= table->keys_for_keyread;
|
||||||
|
|
@ -910,7 +910,7 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
|
||||||
table->tablenr=thd->current_tablenr++;
|
table->tablenr=thd->current_tablenr++;
|
||||||
table->used_fields=0;
|
table->used_fields=0;
|
||||||
table->const_table=0;
|
table->const_table=0;
|
||||||
table->outer_join=table->null_row=table->maybe_null=0;
|
table->outer_join= table->null_row= table->maybe_null= table->force_index= 0;
|
||||||
table->status=STATUS_NO_RECORD;
|
table->status=STATUS_NO_RECORD;
|
||||||
table->keys_in_use_for_query= table->keys_in_use;
|
table->keys_in_use_for_query= table->keys_in_use;
|
||||||
table->used_keys= table->keys_for_keyread;
|
table->used_keys= table->keys_for_keyread;
|
||||||
|
|
@ -981,6 +981,7 @@ bool reopen_table(TABLE *table,bool locked)
|
||||||
tmp.status= table->status;
|
tmp.status= table->status;
|
||||||
tmp.keys_in_use_for_query= tmp.keys_in_use;
|
tmp.keys_in_use_for_query= tmp.keys_in_use;
|
||||||
tmp.used_keys= tmp.keys_for_keyread;
|
tmp.used_keys= tmp.keys_for_keyread;
|
||||||
|
tmp.force_index= tmp.force_index;
|
||||||
|
|
||||||
/* Get state */
|
/* Get state */
|
||||||
tmp.key_length= table->key_length;
|
tmp.key_length= table->key_length;
|
||||||
|
|
@ -1888,6 +1889,7 @@ bool setup_tables(TABLE_LIST *tables)
|
||||||
table->maybe_null=test(table->outer_join=table_list->outer_join);
|
table->maybe_null=test(table->outer_join=table_list->outer_join);
|
||||||
table->tablenr=tablenr;
|
table->tablenr=tablenr;
|
||||||
table->map= (table_map) 1 << tablenr;
|
table->map= (table_map) 1 << tablenr;
|
||||||
|
table->force_index= table_list->force_index;
|
||||||
if (table_list->use_index)
|
if (table_list->use_index)
|
||||||
{
|
{
|
||||||
key_map map= get_key_map_from_key_list(table,
|
key_map map= get_key_map_from_key_list(table,
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,7 @@ typedef struct st_select_lex
|
||||||
char *db,*db1,*table1,*db2,*table2; /* For outer join using .. */
|
char *db,*db1,*table1,*db2,*table2; /* For outer join using .. */
|
||||||
Item *where,*having;
|
Item *where,*having;
|
||||||
ha_rows select_limit,offset_limit;
|
ha_rows select_limit,offset_limit;
|
||||||
ulong options;
|
ulong options, table_join_options;
|
||||||
List<List_item> expr_list;
|
List<List_item> expr_list;
|
||||||
List<List_item> when_list;
|
List<List_item> when_list;
|
||||||
SQL_LIST order_list,table_list,group_list;
|
SQL_LIST order_list,table_list,group_list;
|
||||||
|
|
|
||||||
|
|
@ -498,7 +498,8 @@ check_connections(THD *thd)
|
||||||
vio_in_addr(net->vio,&thd->remote.sin_addr);
|
vio_in_addr(net->vio,&thd->remote.sin_addr);
|
||||||
thd->host=ip_to_hostname(&thd->remote.sin_addr,&connect_errors);
|
thd->host=ip_to_hostname(&thd->remote.sin_addr,&connect_errors);
|
||||||
/* Cut very long hostnames to avoid possible overflows */
|
/* Cut very long hostnames to avoid possible overflows */
|
||||||
thd->host[min(strlen(thd->host), HOSTNAME_LENGTH)]= 0;
|
if (thd->host)
|
||||||
|
thd->host[min(strlen(thd->host), HOSTNAME_LENGTH)]= 0;
|
||||||
if (connect_errors > max_connect_errors)
|
if (connect_errors > max_connect_errors)
|
||||||
return(ER_HOST_IS_BLOCKED);
|
return(ER_HOST_IS_BLOCKED);
|
||||||
}
|
}
|
||||||
|
|
@ -3158,12 +3159,30 @@ bool add_to_list(SQL_LIST &list,Item *item,bool asc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Add a table to list of used tables
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
add_table_to_list()
|
||||||
|
table Table to add
|
||||||
|
alias alias for table (or null if no alias)
|
||||||
|
table_options A set of the following bits:
|
||||||
|
TL_OPTION_UPDATING Table will be updated
|
||||||
|
TL_OPTION_FORCE_INDEX Force usage of index
|
||||||
|
lock_type How table should be locked
|
||||||
|
use_index List of indexed used in USE INDEX
|
||||||
|
ignore_index List of indexed used in IGNORE INDEX
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 Error
|
||||||
|
# Pointer to TABLE_LIST element added to the total table list
|
||||||
|
*/
|
||||||
|
|
||||||
TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
|
TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
|
||||||
bool updating,
|
ulong table_options,
|
||||||
thr_lock_type flags,
|
thr_lock_type lock_type,
|
||||||
List<String> *use_index,
|
List<String> *use_index,
|
||||||
List<String> *ignore_index
|
List<String> *ignore_index)
|
||||||
)
|
|
||||||
{
|
{
|
||||||
register TABLE_LIST *ptr;
|
register TABLE_LIST *ptr;
|
||||||
THD *thd=current_thd;
|
THD *thd=current_thd;
|
||||||
|
|
@ -3211,8 +3230,9 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
|
||||||
}
|
}
|
||||||
ptr->real_name=table->table.str;
|
ptr->real_name=table->table.str;
|
||||||
ptr->real_name_length=table->table.length;
|
ptr->real_name_length=table->table.length;
|
||||||
ptr->lock_type=flags;
|
ptr->lock_type= lock_type;
|
||||||
ptr->updating=updating;
|
ptr->updating= test(table_options & TL_OPTION_UPDATING);
|
||||||
|
ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX);
|
||||||
if (use_index)
|
if (use_index)
|
||||||
ptr->use_index=(List<String> *) thd->memdup((gptr) use_index,
|
ptr->use_index=(List<String> *) thd->memdup((gptr) use_index,
|
||||||
sizeof(*use_index));
|
sizeof(*use_index));
|
||||||
|
|
@ -3221,7 +3241,7 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
|
||||||
sizeof(*ignore_index));
|
sizeof(*ignore_index));
|
||||||
|
|
||||||
/* check that used name is unique */
|
/* check that used name is unique */
|
||||||
if (flags != TL_IGNORE)
|
if (lock_type != TL_IGNORE)
|
||||||
{
|
{
|
||||||
for (TABLE_LIST *tables=(TABLE_LIST*) thd->lex.select->table_list.first ;
|
for (TABLE_LIST *tables=(TABLE_LIST*) thd->lex.select->table_list.first ;
|
||||||
tables ;
|
tables ;
|
||||||
|
|
|
||||||
|
|
@ -2057,7 +2057,8 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
|
||||||
!(s->quick && best_key && s->quick->index == best_key->key &&
|
!(s->quick && best_key && s->quick->index == best_key->key &&
|
||||||
best_max_key_part >= s->table->quick_key_parts[best_key->key]) &&
|
best_max_key_part >= s->table->quick_key_parts[best_key->key]) &&
|
||||||
!((s->table->file->table_flags() & HA_TABLE_SCAN_ON_INDEX) &&
|
!((s->table->file->table_flags() & HA_TABLE_SCAN_ON_INDEX) &&
|
||||||
s->table->used_keys && best_key))
|
s->table->used_keys && best_key) &&
|
||||||
|
!(s->table->force_index && best_key))
|
||||||
{ // Check full join
|
{ // Check full join
|
||||||
if (s->on_expr)
|
if (s->on_expr)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright (C) 2000-2001 MySQL AB
|
/* Copyright (C) 2000-2003 MySQL AB
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -198,6 +198,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
|
||||||
%token FIRST_SYM
|
%token FIRST_SYM
|
||||||
%token FIXED_SYM
|
%token FIXED_SYM
|
||||||
%token FLOAT_NUM
|
%token FLOAT_NUM
|
||||||
|
%token FORCE_SYM
|
||||||
%token FOREIGN
|
%token FOREIGN
|
||||||
%token FROM
|
%token FROM
|
||||||
%token FULL
|
%token FULL
|
||||||
|
|
@ -735,7 +736,8 @@ create:
|
||||||
lex->sql_command= SQLCOM_CREATE_TABLE;
|
lex->sql_command= SQLCOM_CREATE_TABLE;
|
||||||
if (!add_table_to_list($5,
|
if (!add_table_to_list($5,
|
||||||
($2 & HA_LEX_CREATE_TMP_TABLE ?
|
($2 & HA_LEX_CREATE_TMP_TABLE ?
|
||||||
&tmp_table_alias : (LEX_STRING*) 0),1))
|
&tmp_table_alias : (LEX_STRING*) 0),
|
||||||
|
TL_OPTION_UPDATING))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
lex->create_list.empty();
|
lex->create_list.empty();
|
||||||
lex->key_list.empty();
|
lex->key_list.empty();
|
||||||
|
|
@ -751,7 +753,7 @@ create:
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->sql_command= SQLCOM_CREATE_INDEX;
|
lex->sql_command= SQLCOM_CREATE_INDEX;
|
||||||
if (!add_table_to_list($6,NULL,1))
|
if (!add_table_to_list($6, NULL, TL_OPTION_UPDATING))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
lex->create_list.empty();
|
lex->create_list.empty();
|
||||||
lex->key_list.empty();
|
lex->key_list.empty();
|
||||||
|
|
@ -1171,7 +1173,7 @@ alter:
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->sql_command = SQLCOM_ALTER_TABLE;
|
lex->sql_command = SQLCOM_ALTER_TABLE;
|
||||||
lex->name=0;
|
lex->name=0;
|
||||||
if (!add_table_to_list($4, NULL,1))
|
if (!add_table_to_list($4, NULL, TL_OPTION_UPDATING))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
lex->drop_primary=0;
|
lex->drop_primary=0;
|
||||||
lex->create_list.empty();
|
lex->create_list.empty();
|
||||||
|
|
@ -1442,8 +1444,9 @@ table_to_table_list:
|
||||||
|
|
||||||
table_to_table:
|
table_to_table:
|
||||||
table_ident TO_SYM table_ident
|
table_ident TO_SYM table_ident
|
||||||
{ if (!add_table_to_list($1,NULL,1,TL_IGNORE) ||
|
{
|
||||||
!add_table_to_list($3,NULL,1,TL_IGNORE))
|
if (!add_table_to_list($1, NULL, TL_OPTION_UPDATING, TL_IGNORE) ||
|
||||||
|
!add_table_to_list($3, NULL, TL_OPTION_UPDATING, TL_IGNORE))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -2127,11 +2130,13 @@ join_table:
|
||||||
{
|
{
|
||||||
SELECT_LEX *sel=Select;
|
SELECT_LEX *sel=Select;
|
||||||
sel->use_index_ptr=sel->ignore_index_ptr=0;
|
sel->use_index_ptr=sel->ignore_index_ptr=0;
|
||||||
|
sel->table_join_options= 0;
|
||||||
}
|
}
|
||||||
table_ident opt_table_alias opt_key_definition
|
table_ident opt_table_alias opt_key_definition
|
||||||
{
|
{
|
||||||
SELECT_LEX *sel=Select;
|
SELECT_LEX *sel=Select;
|
||||||
if (!($$=add_table_to_list($2,$3,0,TL_UNLOCK, sel->use_index_ptr,
|
if (!($$=add_table_to_list($2, $3, sel->table_join_options,
|
||||||
|
TL_UNLOCK, sel->use_index_ptr,
|
||||||
sel->ignore_index_ptr)))
|
sel->ignore_index_ptr)))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
|
|
@ -2150,12 +2155,20 @@ opt_key_definition:
|
||||||
sel->use_index= *$2;
|
sel->use_index= *$2;
|
||||||
sel->use_index_ptr= &sel->use_index;
|
sel->use_index_ptr= &sel->use_index;
|
||||||
}
|
}
|
||||||
|
| FORCE_SYM key_usage_list
|
||||||
|
{
|
||||||
|
SELECT_LEX *sel=Select;
|
||||||
|
sel->use_index= *$2;
|
||||||
|
sel->use_index_ptr= &sel->use_index;
|
||||||
|
sel->table_join_options|= TL_OPTION_FORCE_INDEX;
|
||||||
|
}
|
||||||
| IGNORE_SYM key_usage_list
|
| IGNORE_SYM key_usage_list
|
||||||
{
|
{
|
||||||
SELECT_LEX *sel=Select;
|
SELECT_LEX *sel=Select;
|
||||||
sel->ignore_index= *$2;
|
sel->ignore_index= *$2;
|
||||||
sel->ignore_index_ptr= &sel->ignore_index;
|
sel->ignore_index_ptr= &sel->ignore_index;
|
||||||
};
|
}
|
||||||
|
;
|
||||||
|
|
||||||
key_usage_list:
|
key_usage_list:
|
||||||
key_or_index { Select->interval_list.empty(); } '(' key_usage_list2 ')'
|
key_or_index { Select->interval_list.empty(); } '(' key_usage_list2 ')'
|
||||||
|
|
@ -2443,7 +2456,7 @@ drop:
|
||||||
lex->drop_list.empty();
|
lex->drop_list.empty();
|
||||||
lex->drop_list.push_back(new Alter_drop(Alter_drop::KEY,
|
lex->drop_list.push_back(new Alter_drop(Alter_drop::KEY,
|
||||||
$3.str));
|
$3.str));
|
||||||
if (!add_table_to_list($5,NULL, 1))
|
if (!add_table_to_list($5, NULL, TL_OPTION_UPDATING))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
| DROP DATABASE if_exists ident
|
| DROP DATABASE if_exists ident
|
||||||
|
|
@ -2467,7 +2480,7 @@ table_list:
|
||||||
|
|
||||||
table_name:
|
table_name:
|
||||||
table_ident
|
table_ident
|
||||||
{ if (!add_table_to_list($1,NULL,1)) YYABORT; };
|
{ if (!add_table_to_list($1,NULL,TL_OPTION_UPDATING)) YYABORT; };
|
||||||
|
|
||||||
if_exists:
|
if_exists:
|
||||||
/* empty */ { $$= 0; }
|
/* empty */ { $$= 0; }
|
||||||
|
|
@ -2678,7 +2691,8 @@ delete:
|
||||||
single_multi:
|
single_multi:
|
||||||
FROM table_ident
|
FROM table_ident
|
||||||
{
|
{
|
||||||
if (!add_table_to_list($2, NULL, 1, Lex->lock_option))
|
if (!add_table_to_list($2, NULL, TL_OPTION_UPDATING,
|
||||||
|
Lex->lock_option))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
where_clause opt_order_clause
|
where_clause opt_order_clause
|
||||||
|
|
@ -2699,13 +2713,14 @@ table_wild_list:
|
||||||
table_wild_one:
|
table_wild_one:
|
||||||
ident opt_wild
|
ident opt_wild
|
||||||
{
|
{
|
||||||
if (!add_table_to_list(new Table_ident($1), NULL, 1,
|
if (!add_table_to_list(new Table_ident($1), NULL,
|
||||||
Lex->lock_option))
|
TL_OPTION_UPDATING, Lex->lock_option))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
| ident '.' ident opt_wild
|
| ident '.' ident opt_wild
|
||||||
{
|
{
|
||||||
if (!add_table_to_list(new Table_ident($1,$3,0), NULL, 1,
|
if (!add_table_to_list(new Table_ident($1,$3,0), NULL,
|
||||||
|
TL_OPTION_UPDATING,
|
||||||
Lex->lock_option))
|
Lex->lock_option))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
|
|
@ -2774,7 +2789,7 @@ show_param:
|
||||||
Lex->sql_command= SQLCOM_SHOW_FIELDS;
|
Lex->sql_command= SQLCOM_SHOW_FIELDS;
|
||||||
if ($5)
|
if ($5)
|
||||||
$4->change_db($5);
|
$4->change_db($5);
|
||||||
if (!add_table_to_list($4,NULL,0))
|
if (!add_table_to_list($4, NULL, 0))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
| NEW_SYM MASTER_SYM FOR_SYM SLAVE WITH MASTER_LOG_FILE_SYM EQ
|
| NEW_SYM MASTER_SYM FOR_SYM SLAVE WITH MASTER_LOG_FILE_SYM EQ
|
||||||
|
|
@ -2807,7 +2822,7 @@ show_param:
|
||||||
Lex->sql_command= SQLCOM_SHOW_KEYS;
|
Lex->sql_command= SQLCOM_SHOW_KEYS;
|
||||||
if ($4)
|
if ($4)
|
||||||
$3->change_db($4);
|
$3->change_db($4);
|
||||||
if (!add_table_to_list($3,NULL,0))
|
if (!add_table_to_list($3, NULL, 0))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
| STATUS_SYM wild
|
| STATUS_SYM wild
|
||||||
|
|
@ -2834,7 +2849,7 @@ show_param:
|
||||||
| CREATE TABLE_SYM table_ident
|
| CREATE TABLE_SYM table_ident
|
||||||
{
|
{
|
||||||
Lex->sql_command = SQLCOM_SHOW_CREATE;
|
Lex->sql_command = SQLCOM_SHOW_CREATE;
|
||||||
if(!add_table_to_list($3, NULL,0))
|
if(!add_table_to_list($3, NULL, 0))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
| MASTER_SYM STATUS_SYM
|
| MASTER_SYM STATUS_SYM
|
||||||
|
|
@ -2879,7 +2894,7 @@ describe:
|
||||||
lex->wild=0;
|
lex->wild=0;
|
||||||
lex->verbose=0;
|
lex->verbose=0;
|
||||||
lex->sql_command=SQLCOM_SHOW_FIELDS;
|
lex->sql_command=SQLCOM_SHOW_FIELDS;
|
||||||
if (!add_table_to_list($2, NULL,0))
|
if (!add_table_to_list($2, NULL, 0))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
opt_describe_column {}
|
opt_describe_column {}
|
||||||
|
|
@ -2999,14 +3014,14 @@ load: LOAD DATA_SYM load_data_lock opt_local INFILE TEXT_STRING
|
||||||
opt_duplicate INTO TABLE_SYM table_ident opt_field_term opt_line_term
|
opt_duplicate INTO TABLE_SYM table_ident opt_field_term opt_line_term
|
||||||
opt_ignore_lines opt_field_spec
|
opt_ignore_lines opt_field_spec
|
||||||
{
|
{
|
||||||
if (!add_table_to_list($11,NULL,1))
|
if (!add_table_to_list($11, NULL, TL_OPTION_UPDATING))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
|
|
|
|
||||||
LOAD TABLE_SYM table_ident FROM MASTER_SYM
|
LOAD TABLE_SYM table_ident FROM MASTER_SYM
|
||||||
{
|
{
|
||||||
Lex->sql_command = SQLCOM_LOAD_MASTER_TABLE;
|
Lex->sql_command = SQLCOM_LOAD_MASTER_TABLE;
|
||||||
if (!add_table_to_list($3,NULL,1))
|
if (!add_table_to_list($3, NULL, TL_OPTION_UPDATING))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,7 @@ struct st_table {
|
||||||
my_bool copy_blobs; /* copy_blobs when storing */
|
my_bool copy_blobs; /* copy_blobs when storing */
|
||||||
my_bool null_row; /* All columns are null */
|
my_bool null_row; /* All columns are null */
|
||||||
my_bool maybe_null,outer_join; /* Used with OUTER JOIN */
|
my_bool maybe_null,outer_join; /* Used with OUTER JOIN */
|
||||||
|
my_bool force_index;
|
||||||
my_bool distinct,const_table,no_rows;
|
my_bool distinct,const_table,no_rows;
|
||||||
my_bool key_read, bulk_insert;
|
my_bool key_read, bulk_insert;
|
||||||
my_bool crypted;
|
my_bool crypted;
|
||||||
|
|
@ -157,6 +158,7 @@ typedef struct st_table_list
|
||||||
bool straight; /* optimize with prev table */
|
bool straight; /* optimize with prev table */
|
||||||
bool updating; /* for replicate-do/ignore table */
|
bool updating; /* for replicate-do/ignore table */
|
||||||
bool do_redirect; /* To get the struct in UNION's */
|
bool do_redirect; /* To get the struct in UNION's */
|
||||||
|
bool force_index; /* Prefer index over table scan */
|
||||||
} TABLE_LIST;
|
} TABLE_LIST;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue