mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Merge bk-internal.mysql.com:/home/bk/mysql-5.0
into serg.mylan:/usr/home/serg/Abk/mysql-5.0-merged
This commit is contained in:
@ -369,6 +369,10 @@ SOURCE=.\my_compress.c
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\my_conio.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\my_copy.c
|
SOURCE=.\my_copy.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
@ -362,6 +362,10 @@ SOURCE=.\my_compress.c
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\my_conio.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\my_copy.c
|
SOURCE=.\my_copy.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
@ -959,10 +959,15 @@ static int get_options(int argc, char **argv)
|
|||||||
|
|
||||||
static int read_and_execute(bool interactive)
|
static int read_and_execute(bool interactive)
|
||||||
{
|
{
|
||||||
#if defined( __WIN__) || defined(OS2) || defined(__NETWARE__)
|
#if defined(OS2) || defined(__NETWARE__)
|
||||||
char linebuffer[254];
|
char linebuffer[254];
|
||||||
String buffer;
|
String buffer;
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(__WIN__)
|
||||||
|
String tmpbuf;
|
||||||
|
String buffer;
|
||||||
|
#endif
|
||||||
|
|
||||||
char *line;
|
char *line;
|
||||||
char in_string=0;
|
char in_string=0;
|
||||||
ulong line_number=0;
|
ulong line_number=0;
|
||||||
@ -993,7 +998,7 @@ static int read_and_execute(bool interactive)
|
|||||||
|
|
||||||
#if defined( __WIN__) || defined(OS2) || defined(__NETWARE__)
|
#if defined( __WIN__) || defined(OS2) || defined(__NETWARE__)
|
||||||
tee_fputs(prompt, stdout);
|
tee_fputs(prompt, stdout);
|
||||||
#ifdef __NETWARE__
|
#if defined(__NETWARE__)
|
||||||
line=fgets(linebuffer, sizeof(linebuffer)-1, stdin);
|
line=fgets(linebuffer, sizeof(linebuffer)-1, stdin);
|
||||||
/* Remove the '\n' */
|
/* Remove the '\n' */
|
||||||
if (line)
|
if (line)
|
||||||
@ -1002,7 +1007,22 @@ static int read_and_execute(bool interactive)
|
|||||||
if (p != NULL)
|
if (p != NULL)
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
}
|
}
|
||||||
#else
|
#elif defined(__WIN__)
|
||||||
|
if (!tmpbuf.is_alloced())
|
||||||
|
tmpbuf.alloc(65535);
|
||||||
|
buffer.length(0);
|
||||||
|
unsigned long clen;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
line= my_cgets(tmpbuf.c_ptr(), tmpbuf.alloced_length(), &clen);
|
||||||
|
buffer.append(line, clen);
|
||||||
|
/*
|
||||||
|
if we got buffer fully filled than there is a chance that
|
||||||
|
something else is still in console input buffer
|
||||||
|
*/
|
||||||
|
} while (tmpbuf.alloced_length() <= clen + 1);
|
||||||
|
line= buffer.c_ptr();
|
||||||
|
#else /* OS2 */
|
||||||
buffer.length(0);
|
buffer.length(0);
|
||||||
/* _cgets() expects the buffer size - 3 as the first byte */
|
/* _cgets() expects the buffer size - 3 as the first byte */
|
||||||
linebuffer[0]= (char) sizeof(linebuffer) - 3;
|
linebuffer[0]= (char) sizeof(linebuffer) - 3;
|
||||||
@ -1078,9 +1098,14 @@ static int read_and_execute(bool interactive)
|
|||||||
status.exit_status=0;
|
status.exit_status=0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined( __WIN__) || defined(OS2) || defined(__NETWARE__)
|
#if defined( __WIN__) || defined(OS2) || defined(__NETWARE__)
|
||||||
buffer.free();
|
buffer.free();
|
||||||
#endif
|
#endif
|
||||||
|
#if defined( __WIN__)
|
||||||
|
tmpbuf.free();
|
||||||
|
#endif
|
||||||
|
|
||||||
return status.exit_status;
|
return status.exit_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -887,6 +887,9 @@ int my_security_attr_create(SECURITY_ATTRIBUTES **psa, const char **perror,
|
|||||||
|
|
||||||
void my_security_attr_free(SECURITY_ATTRIBUTES *sa);
|
void my_security_attr_free(SECURITY_ATTRIBUTES *sa);
|
||||||
|
|
||||||
|
/* implemented in my_conio.c */
|
||||||
|
char* my_cgets(char *string, unsigned long clen, unsigned long* plen);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef __NETWARE__
|
#ifdef __NETWARE__
|
||||||
void netware_reg_user(const char *ip, const char *user,
|
void netware_reg_user(const char *ip, const char *user,
|
||||||
|
@ -381,6 +381,20 @@ typedef struct st_sort_key_blocks /* Used when sorting */
|
|||||||
} SORT_KEY_BLOCKS;
|
} SORT_KEY_BLOCKS;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
MyISAM supports several statistics collection methods. Currently statistics
|
||||||
|
collection method is not stored in MyISAM file and has to be specified for
|
||||||
|
each table analyze/repair operation in MI_CHECK::stats_method.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
/* Treat NULLs as inequal when collecting statistics (default for 4.1/5.0) */
|
||||||
|
MI_STATS_METHOD_NULLS_NOT_EQUAL,
|
||||||
|
/* Treat NULLs as equal when collecting statistics (like 4.0 did) */
|
||||||
|
MI_STATS_METHOD_NULLS_EQUAL
|
||||||
|
} enum_mi_stats_method;
|
||||||
|
|
||||||
typedef struct st_mi_check_param
|
typedef struct st_mi_check_param
|
||||||
{
|
{
|
||||||
ulonglong auto_increment_value;
|
ulonglong auto_increment_value;
|
||||||
@ -411,6 +425,7 @@ typedef struct st_mi_check_param
|
|||||||
void *thd;
|
void *thd;
|
||||||
const char *db_name, *table_name;
|
const char *db_name, *table_name;
|
||||||
const char *op_name;
|
const char *op_name;
|
||||||
|
enum_mi_stats_method stats_method;
|
||||||
} MI_CHECK;
|
} MI_CHECK;
|
||||||
|
|
||||||
typedef struct st_sort_ft_buf
|
typedef struct st_sort_ft_buf
|
||||||
|
@ -80,6 +80,7 @@ void myisamchk_init(MI_CHECK *param)
|
|||||||
param->start_check_pos=0;
|
param->start_check_pos=0;
|
||||||
param->max_record_length= LONGLONG_MAX;
|
param->max_record_length= LONGLONG_MAX;
|
||||||
param->key_cache_block_size= KEY_CACHE_BLOCK_SIZE;
|
param->key_cache_block_size= KEY_CACHE_BLOCK_SIZE;
|
||||||
|
param->stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check the status flags for the table */
|
/* Check the status flags for the table */
|
||||||
@ -559,10 +560,11 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
|
|||||||
ha_checksum *key_checksum, uint level)
|
ha_checksum *key_checksum, uint level)
|
||||||
{
|
{
|
||||||
int flag;
|
int flag;
|
||||||
uint used_length,comp_flag,nod_flag,key_length=0,not_used;
|
uint used_length,comp_flag,nod_flag,key_length=0;
|
||||||
uchar key[MI_MAX_POSSIBLE_KEY_BUFF],*temp_buff,*keypos,*old_keypos,*endpos;
|
uchar key[MI_MAX_POSSIBLE_KEY_BUFF],*temp_buff,*keypos,*old_keypos,*endpos;
|
||||||
my_off_t next_page,record;
|
my_off_t next_page,record;
|
||||||
char llbuff[22];
|
char llbuff[22];
|
||||||
|
uint diff_pos;
|
||||||
DBUG_ENTER("chk_index");
|
DBUG_ENTER("chk_index");
|
||||||
DBUG_DUMP("buff",(byte*) buff,mi_getint(buff));
|
DBUG_DUMP("buff",(byte*) buff,mi_getint(buff));
|
||||||
|
|
||||||
@ -620,7 +622,7 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
|
|||||||
}
|
}
|
||||||
if ((*keys)++ &&
|
if ((*keys)++ &&
|
||||||
(flag=ha_key_cmp(keyinfo->seg,info->lastkey,key,key_length,
|
(flag=ha_key_cmp(keyinfo->seg,info->lastkey,key,key_length,
|
||||||
comp_flag, ¬_used)) >=0)
|
comp_flag, &diff_pos)) >=0)
|
||||||
{
|
{
|
||||||
DBUG_DUMP("old",(byte*) info->lastkey, info->lastkey_length);
|
DBUG_DUMP("old",(byte*) info->lastkey, info->lastkey_length);
|
||||||
DBUG_DUMP("new",(byte*) key, key_length);
|
DBUG_DUMP("new",(byte*) key, key_length);
|
||||||
@ -636,11 +638,11 @@ 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;
|
if (param->stats_method == MI_STATS_METHOD_NULLS_NOT_EQUAL)
|
||||||
ha_key_cmp(keyinfo->seg,info->lastkey,key,USE_WHOLE_KEY,
|
ha_key_cmp(keyinfo->seg,info->lastkey,key,USE_WHOLE_KEY,
|
||||||
SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL,
|
SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL,
|
||||||
&diff);
|
&diff_pos);
|
||||||
param->unique_count[diff-1]++;
|
param->unique_count[diff_pos-1]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(*key_checksum)+= mi_byte_checksum((byte*) key,
|
(*key_checksum)+= mi_byte_checksum((byte*) key,
|
||||||
@ -2014,7 +2016,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
|
|||||||
sort_param.sort_info=&sort_info;
|
sort_param.sort_info=&sort_info;
|
||||||
sort_param.fix_datafile= (my_bool) (! rep_quick);
|
sort_param.fix_datafile= (my_bool) (! rep_quick);
|
||||||
sort_param.master =1;
|
sort_param.master =1;
|
||||||
|
|
||||||
del=info->state->del;
|
del=info->state->del;
|
||||||
param->glob_crc=0;
|
param->glob_crc=0;
|
||||||
if (param->testflag & T_CALC_CHECKSUM)
|
if (param->testflag & T_CALC_CHECKSUM)
|
||||||
@ -3250,9 +3252,10 @@ static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a)
|
|||||||
cmp=ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey,
|
cmp=ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey,
|
||||||
(uchar*) a, USE_WHOLE_KEY,SEARCH_FIND | SEARCH_UPDATE,
|
(uchar*) a, USE_WHOLE_KEY,SEARCH_FIND | SEARCH_UPDATE,
|
||||||
&diff_pos);
|
&diff_pos);
|
||||||
ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey,
|
if (param->stats_method == MI_STATS_METHOD_NULLS_NOT_EQUAL)
|
||||||
(uchar*) a, USE_WHOLE_KEY,SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL,
|
ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey,
|
||||||
&diff_pos);
|
(uchar*) a, USE_WHOLE_KEY,
|
||||||
|
SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL, &diff_pos);
|
||||||
sort_param->unique[diff_pos-1]++;
|
sort_param->unique[diff_pos-1]++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -3989,9 +3992,10 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info,
|
|||||||
unique[0]= (#different values of {keypart1}) - 1
|
unique[0]= (#different values of {keypart1}) - 1
|
||||||
unique[1]= (#different values of {keypart2,keypart1} tuple) - unique[0] - 1
|
unique[1]= (#different values of {keypart2,keypart1} tuple) - unique[0] - 1
|
||||||
...
|
...
|
||||||
Here we assume that NULL != NULL (see SEARCH_NULL_ARE_NOT_EQUAL). The
|
The 'unique' array is collected in one sequential scan through the entire
|
||||||
'unique' array is collected in one sequential scan through the entire
|
|
||||||
index. This is done in two places: in chk_index() and in sort_key_write().
|
index. This is done in two places: in chk_index() and in sort_key_write().
|
||||||
|
Statistics collection may consider NULLs as either equal or inequal (see
|
||||||
|
SEARCH_NULL_ARE_NOT_EQUAL, MI_STATS_METHOD_*).
|
||||||
|
|
||||||
Output is an array:
|
Output is an array:
|
||||||
rec_per_key_part[k] =
|
rec_per_key_part[k] =
|
||||||
|
@ -67,6 +67,7 @@ static const char *field_pack[]=
|
|||||||
"no zeros", "blob", "constant", "table-lockup",
|
"no zeros", "blob", "constant", "table-lockup",
|
||||||
"always zero","varchar","unique-hash","?","?"};
|
"always zero","varchar","unique-hash","?","?"};
|
||||||
|
|
||||||
|
static const char *myisam_stats_method_str="nulls_inequal";
|
||||||
|
|
||||||
static void get_options(int *argc,char * * *argv);
|
static void get_options(int *argc,char * * *argv);
|
||||||
static void print_version(void);
|
static void print_version(void);
|
||||||
@ -155,7 +156,7 @@ enum options_mc {
|
|||||||
OPT_READ_BUFFER_SIZE, OPT_WRITE_BUFFER_SIZE, OPT_SORT_BUFFER_SIZE,
|
OPT_READ_BUFFER_SIZE, OPT_WRITE_BUFFER_SIZE, OPT_SORT_BUFFER_SIZE,
|
||||||
OPT_SORT_KEY_BLOCKS, OPT_DECODE_BITS, OPT_FT_MIN_WORD_LEN,
|
OPT_SORT_KEY_BLOCKS, OPT_DECODE_BITS, OPT_FT_MIN_WORD_LEN,
|
||||||
OPT_FT_MAX_WORD_LEN, OPT_FT_STOPWORD_FILE,
|
OPT_FT_MAX_WORD_LEN, OPT_FT_STOPWORD_FILE,
|
||||||
OPT_MAX_RECORD_LENGTH, OPT_AUTO_CLOSE
|
OPT_MAX_RECORD_LENGTH, OPT_AUTO_CLOSE, OPT_STATS_METHOD
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct my_option my_long_options[] =
|
static struct my_option my_long_options[] =
|
||||||
@ -336,6 +337,11 @@ static struct my_option my_long_options[] =
|
|||||||
"Use stopwords from this file instead of built-in list.",
|
"Use stopwords from this file instead of built-in list.",
|
||||||
(gptr*) &ft_stopword_file, (gptr*) &ft_stopword_file, 0, GET_STR,
|
(gptr*) &ft_stopword_file, (gptr*) &ft_stopword_file, 0, GET_STR,
|
||||||
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
|
{"stats_method", OPT_STATS_METHOD,
|
||||||
|
"Specifies how index statistics collection code should threat NULLs. "
|
||||||
|
"Possible values of name are \"nulls_inequal\" (default behavior for 4.1/5.0), and \"nulls_equal\" (emulate 4.0 behavior).",
|
||||||
|
(gptr*) &myisam_stats_method_str, (gptr*) &myisam_stats_method_str, 0,
|
||||||
|
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
|
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -465,6 +471,12 @@ static void usage(void)
|
|||||||
|
|
||||||
#include <help_end.h>
|
#include <help_end.h>
|
||||||
|
|
||||||
|
const char *myisam_stats_method_names[] = {"nulls_inequal", "nulls_equal",
|
||||||
|
NullS};
|
||||||
|
TYPELIB myisam_stats_method_typelib= {
|
||||||
|
array_elements(myisam_stats_method_names) - 1, "",
|
||||||
|
myisam_stats_method_names, NULL};
|
||||||
|
|
||||||
/* Read options */
|
/* Read options */
|
||||||
|
|
||||||
static my_bool
|
static my_bool
|
||||||
@ -684,6 +696,18 @@ get_one_option(int optid,
|
|||||||
else
|
else
|
||||||
check_param.testflag|= T_CALC_CHECKSUM;
|
check_param.testflag|= T_CALC_CHECKSUM;
|
||||||
break;
|
break;
|
||||||
|
case OPT_STATS_METHOD:
|
||||||
|
{
|
||||||
|
int method;
|
||||||
|
myisam_stats_method_str= argument;
|
||||||
|
if ((method=find_type(argument, &myisam_stats_method_typelib, 2)) <= 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Invalid value of stats_method: %s.\n", argument);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
check_param.stats_method= method-1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
#ifdef DEBUG /* Only useful if debugging */
|
#ifdef DEBUG /* Only useful if debugging */
|
||||||
case OPT_START_CHECK_POS:
|
case OPT_START_CHECK_POS:
|
||||||
check_param.start_check_pos= strtoull(argument, NULL, 0);
|
check_param.start_check_pos= strtoull(argument, NULL, 0);
|
||||||
|
@ -2450,11 +2450,6 @@ sub run_mysqltest ($) {
|
|||||||
mtr_add_arg($args, "--big-test");
|
mtr_add_arg($args, "--big-test");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $opt_record )
|
|
||||||
{
|
|
||||||
mtr_add_arg($args, "--record");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( $opt_compress )
|
if ( $opt_compress )
|
||||||
{
|
{
|
||||||
mtr_add_arg($args, "--compress");
|
mtr_add_arg($args, "--compress");
|
||||||
@ -2480,9 +2475,6 @@ sub run_mysqltest ($) {
|
|||||||
$glob_mysql_test_dir);
|
$glob_mysql_test_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
mtr_add_arg($args, "-R");
|
|
||||||
mtr_add_arg($args, $tinfo->{'result_file'});
|
|
||||||
|
|
||||||
# ----------------------------------------------------------------------
|
# ----------------------------------------------------------------------
|
||||||
# If embedded server, we create server args to give mysqltest to pass on
|
# If embedded server, we create server args to give mysqltest to pass on
|
||||||
# ----------------------------------------------------------------------
|
# ----------------------------------------------------------------------
|
||||||
@ -2497,6 +2489,18 @@ sub run_mysqltest ($) {
|
|||||||
# ----------------------------------------------------------------------
|
# ----------------------------------------------------------------------
|
||||||
$ENV{'MYSQL_TEST'}= "$exe_mysqltest " . join(" ", @$args);
|
$ENV{'MYSQL_TEST'}= "$exe_mysqltest " . join(" ", @$args);
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
# Add args that should not go into the MYSQL_TEST environment var
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
mtr_add_arg($args, "-R");
|
||||||
|
mtr_add_arg($args, $tinfo->{'result_file'});
|
||||||
|
|
||||||
|
if ( $opt_record )
|
||||||
|
{
|
||||||
|
mtr_add_arg($args, "--record");
|
||||||
|
}
|
||||||
|
|
||||||
return mtr_run_test($exe,$args,$tinfo->{'path'},"",$path_timefile,"");
|
return mtr_run_test($exe,$args,$tinfo->{'path'},"",$path_timefile,"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1730,6 +1730,15 @@ explain select * from t1 order by a,b,c,d;
|
|||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using filesort
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using filesort
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1 (a char(1), b char(1), key(a, b)) engine=innodb;
|
||||||
|
insert into t1 values ('8', '6'), ('4', '7');
|
||||||
|
select min(a) from t1;
|
||||||
|
min(a)
|
||||||
|
4
|
||||||
|
select min(b) from t1 where a='8';
|
||||||
|
min(b)
|
||||||
|
6
|
||||||
|
drop table t1;
|
||||||
create table t1 (x bigint unsigned not null primary key) engine=innodb;
|
create table t1 (x bigint unsigned not null primary key) engine=innodb;
|
||||||
insert into t1(x) values (0xfffffffffffffff0),(0xfffffffffffffff1);
|
insert into t1(x) values (0xfffffffffffffff0),(0xfffffffffffffff1);
|
||||||
select * from t1;
|
select * from t1;
|
||||||
@ -1776,7 +1785,7 @@ Variable_name Value
|
|||||||
Innodb_rows_deleted 2070
|
Innodb_rows_deleted 2070
|
||||||
show status like "Innodb_rows_inserted";
|
show status like "Innodb_rows_inserted";
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
Innodb_rows_inserted 31725
|
Innodb_rows_inserted 31727
|
||||||
show status like "Innodb_rows_updated";
|
show status like "Innodb_rows_updated";
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
Innodb_rows_updated 29530
|
Innodb_rows_updated 29530
|
||||||
|
@ -608,6 +608,67 @@ checksum table t2;
|
|||||||
Table Checksum
|
Table Checksum
|
||||||
test.t2 984116287
|
test.t2 984116287
|
||||||
drop table t1, t2;
|
drop table t1, t2;
|
||||||
|
show variables like 'myisam_stats_method';
|
||||||
|
Variable_name Value
|
||||||
|
myisam_stats_method nulls_inequal
|
||||||
|
create table t1 (a int, key(a));
|
||||||
|
insert into t1 values (0),(1),(2),(3),(4);
|
||||||
|
insert into t1 select NULL from t1;
|
||||||
|
analyze table t1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 analyze 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 a 1 a A 10 NULL NULL YES BTREE
|
||||||
|
insert into t1 values (11);
|
||||||
|
delete from t1 where a=11;
|
||||||
|
check table t1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 check 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 a 1 a A 10 NULL NULL YES BTREE
|
||||||
|
set myisam_stats_method=nulls_equal;
|
||||||
|
show variables like 'myisam_stats_method';
|
||||||
|
Variable_name Value
|
||||||
|
myisam_stats_method nulls_equal
|
||||||
|
insert into t1 values (11);
|
||||||
|
delete from t1 where a=11;
|
||||||
|
analyze table t1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 analyze 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 a 1 a A 5 NULL NULL YES BTREE
|
||||||
|
insert into t1 values (11);
|
||||||
|
delete from t1 where a=11;
|
||||||
|
check table t1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 check 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 a 1 a A 5 NULL NULL YES BTREE
|
||||||
|
set myisam_stats_method=DEFAULT;
|
||||||
|
show variables like 'myisam_stats_method';
|
||||||
|
Variable_name Value
|
||||||
|
myisam_stats_method nulls_inequal
|
||||||
|
insert into t1 values (11);
|
||||||
|
delete from t1 where a=11;
|
||||||
|
analyze table t1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 analyze 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 a 1 a A 10 NULL NULL YES BTREE
|
||||||
|
insert into t1 values (11);
|
||||||
|
delete from t1 where a=11;
|
||||||
|
check table t1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 check 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 a 1 a A 10 NULL NULL YES BTREE
|
||||||
|
drop table t1;
|
||||||
set storage_engine=MyISAM;
|
set storage_engine=MyISAM;
|
||||||
drop table if exists t1,t2,t3;
|
drop table if exists t1,t2,t3;
|
||||||
--- Testing varchar ---
|
--- Testing varchar ---
|
||||||
|
@ -4,6 +4,26 @@ reset master;
|
|||||||
reset slave;
|
reset slave;
|
||||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||||
start slave;
|
start slave;
|
||||||
|
set sql_log_bin=0;
|
||||||
|
create database mysqltest_from;
|
||||||
|
set sql_log_bin=1;
|
||||||
|
create database mysqltest_to;
|
||||||
|
use mysqltest_from;
|
||||||
|
drop table if exists a;
|
||||||
|
CREATE TABLE a (i INT);
|
||||||
|
INSERT INTO a VALUES(1);
|
||||||
|
DELETE alias FROM a alias WHERE alias.i=1;
|
||||||
|
SELECT * FROM a;
|
||||||
|
i
|
||||||
|
insert into a values(2),(3);
|
||||||
|
delete a alias FROM a alias where alias.i=2;
|
||||||
|
select * from a;
|
||||||
|
i
|
||||||
|
3
|
||||||
|
use mysqltest_to;
|
||||||
|
select * from a;
|
||||||
|
i
|
||||||
|
3
|
||||||
create table t1 (a int);
|
create table t1 (a int);
|
||||||
create table t2 (a int);
|
create table t2 (a int);
|
||||||
insert into t1 values (1);
|
insert into t1 values (1);
|
||||||
@ -15,7 +35,10 @@ select * from t2;
|
|||||||
a
|
a
|
||||||
1
|
1
|
||||||
select * from t1;
|
select * from t1;
|
||||||
ERROR 42S02: Table 'test.t1' doesn't exist
|
ERROR 42S02: Table 'mysqltest_to.t1' doesn't exist
|
||||||
select * from t2;
|
select * from t2;
|
||||||
ERROR 42S02: Table 'test.t2' doesn't exist
|
ERROR 42S02: Table 'mysqltest_to.t2' doesn't exist
|
||||||
drop table t1,t2;
|
set sql_log_bin=0;
|
||||||
|
drop database mysqltest_from;
|
||||||
|
set sql_log_bin=1;
|
||||||
|
drop database mysqltest_to;
|
||||||
|
@ -1259,6 +1259,15 @@ select * from t1 order by a,b,c,d;
|
|||||||
explain select * from t1 order by a,b,c,d;
|
explain select * from t1 order by a,b,c,d;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# BUG#11039,#13218 Wrong key length in min()
|
||||||
|
#
|
||||||
|
|
||||||
|
create table t1 (a char(1), b char(1), key(a, b)) engine=innodb;
|
||||||
|
insert into t1 values ('8', '6'), ('4', '7');
|
||||||
|
select min(a) from t1;
|
||||||
|
select min(b) from t1 where a='8';
|
||||||
|
drop table t1;
|
||||||
# End of 4.1 tests
|
# End of 4.1 tests
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -578,6 +578,59 @@ checksum table t1;
|
|||||||
# The above should give the same number as the following.
|
# The above should give the same number as the following.
|
||||||
checksum table t2;
|
checksum table t2;
|
||||||
drop table t1, t2;
|
drop table t1, t2;
|
||||||
|
|
||||||
|
#
|
||||||
|
# BUG#12232: New myisam_stats_method variable.
|
||||||
|
#
|
||||||
|
|
||||||
|
show variables like 'myisam_stats_method';
|
||||||
|
|
||||||
|
create table t1 (a int, key(a));
|
||||||
|
insert into t1 values (0),(1),(2),(3),(4);
|
||||||
|
insert into t1 select NULL from t1;
|
||||||
|
|
||||||
|
# default: NULLs considered inequal
|
||||||
|
analyze table t1;
|
||||||
|
show index from t1;
|
||||||
|
insert into t1 values (11);
|
||||||
|
delete from t1 where a=11;
|
||||||
|
check table t1;
|
||||||
|
show index from t1;
|
||||||
|
|
||||||
|
# Set nulls to be equal:
|
||||||
|
set myisam_stats_method=nulls_equal;
|
||||||
|
show variables like 'myisam_stats_method';
|
||||||
|
insert into t1 values (11);
|
||||||
|
delete from t1 where a=11;
|
||||||
|
|
||||||
|
analyze table t1;
|
||||||
|
show index from t1;
|
||||||
|
|
||||||
|
insert into t1 values (11);
|
||||||
|
delete from t1 where a=11;
|
||||||
|
|
||||||
|
check table t1;
|
||||||
|
show index from t1;
|
||||||
|
|
||||||
|
# Set nulls back to be equal
|
||||||
|
set myisam_stats_method=DEFAULT;
|
||||||
|
show variables like 'myisam_stats_method';
|
||||||
|
insert into t1 values (11);
|
||||||
|
delete from t1 where a=11;
|
||||||
|
|
||||||
|
analyze table t1;
|
||||||
|
show index from t1;
|
||||||
|
|
||||||
|
insert into t1 values (11);
|
||||||
|
delete from t1 where a=11;
|
||||||
|
|
||||||
|
check table t1;
|
||||||
|
show index from t1;
|
||||||
|
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
# End of 4.1 tests
|
||||||
|
|
||||||
#
|
#
|
||||||
# Test varchar
|
# Test varchar
|
||||||
#
|
#
|
||||||
@ -700,4 +753,3 @@ create table t3 (c1 int) engine=myisam pack_keys=default;
|
|||||||
create table t4 (c1 int) engine=myisam pack_keys=2;
|
create table t4 (c1 int) engine=myisam pack_keys=2;
|
||||||
drop table t1, t2, t3;
|
drop table t1, t2, t3;
|
||||||
|
|
||||||
# End of 4.1 tests
|
|
||||||
|
@ -1 +1 @@
|
|||||||
--replicate-wild-ignore-table=test.%
|
"--replicate-rewrite-db=mysqltest_from->mysqltest_to" --replicate-do-table=mysqltest_to.a
|
||||||
|
@ -1,4 +1,41 @@
|
|||||||
|
#multi delete replication bugs
|
||||||
|
|
||||||
|
|
||||||
source include/master-slave.inc;
|
source include/master-slave.inc;
|
||||||
|
|
||||||
|
#BUG#11139 - improper wild-table and table rules
|
||||||
|
#checking for multi deletes with an alias
|
||||||
|
|
||||||
|
connection master;
|
||||||
|
set sql_log_bin=0;
|
||||||
|
create database mysqltest_from;
|
||||||
|
set sql_log_bin=1;
|
||||||
|
|
||||||
|
connection slave;
|
||||||
|
create database mysqltest_to;
|
||||||
|
|
||||||
|
|
||||||
|
connection master;
|
||||||
|
use mysqltest_from;
|
||||||
|
--disable_warnings
|
||||||
|
drop table if exists a;
|
||||||
|
--enable_warnings
|
||||||
|
CREATE TABLE a (i INT);
|
||||||
|
INSERT INTO a VALUES(1);
|
||||||
|
DELETE alias FROM a alias WHERE alias.i=1;
|
||||||
|
SELECT * FROM a;
|
||||||
|
insert into a values(2),(3);
|
||||||
|
delete a alias FROM a alias where alias.i=2;
|
||||||
|
select * from a;
|
||||||
|
save_master_pos;
|
||||||
|
connection slave;
|
||||||
|
|
||||||
|
use mysqltest_to;
|
||||||
|
sync_with_master;
|
||||||
|
select * from a;
|
||||||
|
|
||||||
|
# BUG#3461
|
||||||
|
connection master;
|
||||||
create table t1 (a int);
|
create table t1 (a int);
|
||||||
create table t2 (a int);
|
create table t2 (a int);
|
||||||
|
|
||||||
@ -19,7 +56,13 @@ select * from t1;
|
|||||||
error 1146;
|
error 1146;
|
||||||
select * from t2;
|
select * from t2;
|
||||||
|
|
||||||
|
# cleanup
|
||||||
connection master;
|
connection master;
|
||||||
drop table t1,t2;
|
set sql_log_bin=0;
|
||||||
|
drop database mysqltest_from;
|
||||||
|
set sql_log_bin=1;
|
||||||
|
connection slave;
|
||||||
|
drop database mysqltest_to;
|
||||||
|
|
||||||
# End of 4.1 tests
|
# End of 4.1 tests
|
||||||
|
|
||||||
|
217
mysys/my_conio.c
Normal file
217
mysys/my_conio.c
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
|
#include "mysys_priv.h"
|
||||||
|
|
||||||
|
#ifdef __WIN__
|
||||||
|
|
||||||
|
static HANDLE my_coninpfh= 0; /* console input */
|
||||||
|
|
||||||
|
/*
|
||||||
|
functions my_pthread_auto_mutex_lock & my_pthread_auto_mutex_free
|
||||||
|
are experimental at this moment, they are intended to bring
|
||||||
|
ability of protecting code sections without necessity to explicitly
|
||||||
|
initialize synchronization object in one of threads
|
||||||
|
|
||||||
|
if found useful they are to be exported in mysys
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
int my_pthread_auto_mutex_lock(HANDLE* ph, const char* name,
|
||||||
|
int id, int time)
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
creates a mutex with given name and tries to lock it time msec.
|
||||||
|
mutex name is appended with id to allow system wide or process wide
|
||||||
|
locks. Handle to created mutex returned in ph argument.
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 thread owns mutex
|
||||||
|
<>0 error
|
||||||
|
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
int my_pthread_auto_mutex_lock(HANDLE* ph, const char* name, int id, int time)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
char tname[FN_REFLEN];
|
||||||
|
|
||||||
|
sprintf(tname, "%s-%08X", name, id);
|
||||||
|
|
||||||
|
*ph= CreateMutex(NULL, FALSE, tname);
|
||||||
|
if (*ph == NULL)
|
||||||
|
return GetLastError();
|
||||||
|
|
||||||
|
res= WaitForSingleObject(*ph, time);
|
||||||
|
|
||||||
|
if (res == WAIT_TIMEOUT)
|
||||||
|
return ERROR_SEM_TIMEOUT;
|
||||||
|
|
||||||
|
if (res == WAIT_FAILED)
|
||||||
|
return GetLastError();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
int my_pthread_auto_mutex_free(HANDLE* ph)
|
||||||
|
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
releases a mutex.
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 thread released mutex
|
||||||
|
<>0 error
|
||||||
|
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
int my_pthread_auto_mutex_free(HANDLE* ph)
|
||||||
|
{
|
||||||
|
if (*ph)
|
||||||
|
{
|
||||||
|
ReleaseMutex(*ph);
|
||||||
|
CloseHandle(*ph);
|
||||||
|
*ph= NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define pthread_auto_mutex_decl(name) \
|
||||||
|
HANDLE __h##name= NULL;
|
||||||
|
|
||||||
|
#define pthread_auto_mutex_lock(name, proc, time) \
|
||||||
|
my_pthread_auto_mutex_lock(&__h##name, #name, (proc), (time))
|
||||||
|
|
||||||
|
#define pthread_auto_mutex_free(name) \
|
||||||
|
my_pthread_auto_mutex_free(&__h##name)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
char* my_cgets(char *string, unsigned long clen, unsigned long* plen)
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
Replaces _cgets from libc to support input of more than 255 chars.
|
||||||
|
Reads from the console via ReadConsole into buffer which
|
||||||
|
should be at least clen characters.
|
||||||
|
Actual length of string returned in plen.
|
||||||
|
|
||||||
|
WARNING
|
||||||
|
my_cgets() does NOT check the pushback character buffer (i.e., _chbuf).
|
||||||
|
Thus, my_cgets() will not return any character that is pushed back by
|
||||||
|
the _ungetch() call.
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
string pointer ok
|
||||||
|
NULL Error
|
||||||
|
|
||||||
|
*/
|
||||||
|
char* my_cgets(char *buffer, unsigned long clen, unsigned long* plen)
|
||||||
|
{
|
||||||
|
ULONG state;
|
||||||
|
char *result;
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||||
|
|
||||||
|
pthread_auto_mutex_decl(my_conio_cs);
|
||||||
|
|
||||||
|
/* lock the console for the current process*/
|
||||||
|
if (pthread_auto_mutex_lock(my_conio_cs, GetCurrentProcessId(), INFINITE))
|
||||||
|
{
|
||||||
|
/* can not lock console */
|
||||||
|
pthread_auto_mutex_free(my_conio_cs);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* init console input */
|
||||||
|
if (my_coninpfh == 0)
|
||||||
|
{
|
||||||
|
/* same handle will be used until process termination */
|
||||||
|
my_coninpfh= CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (my_coninpfh == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
/* unlock the console */
|
||||||
|
pthread_auto_mutex_free(my_conio_cs);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
GetConsoleMode((HANDLE)my_coninpfh, &state);
|
||||||
|
SetConsoleMode((HANDLE)my_coninpfh, ENABLE_LINE_INPUT |
|
||||||
|
ENABLE_PROCESSED_INPUT | ENABLE_ECHO_INPUT);
|
||||||
|
|
||||||
|
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
|
||||||
|
|
||||||
|
/*
|
||||||
|
there is no known way to determine allowed buffer size for input
|
||||||
|
though it is known it should not be more than 64K
|
||||||
|
so we cut 64K and try first size of screen buffer
|
||||||
|
if it is still to large we cut half of it and try again
|
||||||
|
later we may want to cycle from min(clen, 65535) to allowed size
|
||||||
|
with small decrement to determine exact allowed buffer
|
||||||
|
*/
|
||||||
|
clen= min(clen, 65535);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
clen= min(clen, (unsigned long)csbi.dwSize.X*csbi.dwSize.Y);
|
||||||
|
if (!ReadConsole((HANDLE)my_coninpfh, (LPVOID)buffer, clen - 1, plen, NULL))
|
||||||
|
{
|
||||||
|
result= NULL;
|
||||||
|
clen>>= 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result= buffer;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (GetLastError() == ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
|
||||||
|
|
||||||
|
if (result != NULL)
|
||||||
|
{
|
||||||
|
if (buffer[*plen - 2] == '\r')
|
||||||
|
{
|
||||||
|
*plen= *plen - 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (buffer[*plen - 1] == '\r')
|
||||||
|
{
|
||||||
|
char tmp[3];
|
||||||
|
int tmplen= sizeof(tmp);
|
||||||
|
|
||||||
|
*plen= *plen - 1;
|
||||||
|
/* read /n left in the buffer */
|
||||||
|
ReadConsole((HANDLE)my_coninpfh, (LPVOID)tmp, tmplen, &tmplen, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer[*plen]= '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
SetConsoleMode((HANDLE)my_coninpfh, state);
|
||||||
|
/* unlock the console */
|
||||||
|
pthread_auto_mutex_free(my_conio_cs);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __WIN__ */
|
@ -39,6 +39,12 @@ const char *myisam_recover_names[] =
|
|||||||
TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names)-1,"",
|
TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names)-1,"",
|
||||||
myisam_recover_names, NULL};
|
myisam_recover_names, NULL};
|
||||||
|
|
||||||
|
const char *myisam_stats_method_names[] = {"nulls_inequal", "nulls_equal",
|
||||||
|
NullS};
|
||||||
|
TYPELIB myisam_stats_method_typelib= {
|
||||||
|
array_elements(myisam_stats_method_names) - 1, "",
|
||||||
|
myisam_stats_method_names, NULL};
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
** MyISAM tables
|
** MyISAM tables
|
||||||
@ -324,6 +330,7 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
|
|||||||
param.db_name= table->s->db;
|
param.db_name= table->s->db;
|
||||||
param.table_name= table->alias;
|
param.table_name= table->alias;
|
||||||
param.testflag = check_opt->flags | T_CHECK | T_SILENT;
|
param.testflag = check_opt->flags | T_CHECK | T_SILENT;
|
||||||
|
param.stats_method= (enum_mi_stats_method)thd->variables.myisam_stats_method;
|
||||||
|
|
||||||
if (!(table->db_stat & HA_READ_ONLY))
|
if (!(table->db_stat & HA_READ_ONLY))
|
||||||
param.testflag|= T_STATISTICS;
|
param.testflag|= T_STATISTICS;
|
||||||
@ -413,6 +420,7 @@ int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt)
|
|||||||
param.testflag= (T_FAST | T_CHECK | T_SILENT | T_STATISTICS |
|
param.testflag= (T_FAST | T_CHECK | T_SILENT | T_STATISTICS |
|
||||||
T_DONT_CHECK_CHECKSUM);
|
T_DONT_CHECK_CHECKSUM);
|
||||||
param.using_global_keycache = 1;
|
param.using_global_keycache = 1;
|
||||||
|
param.stats_method= (enum_mi_stats_method)thd->variables.myisam_stats_method;
|
||||||
|
|
||||||
if (!(share->state.changed & STATE_NOT_ANALYZED))
|
if (!(share->state.changed & STATE_NOT_ANALYZED))
|
||||||
return HA_ADMIN_ALREADY_DONE;
|
return HA_ADMIN_ALREADY_DONE;
|
||||||
@ -967,6 +975,7 @@ int ha_myisam::enable_indexes(uint mode)
|
|||||||
T_CREATE_MISSING_KEYS);
|
T_CREATE_MISSING_KEYS);
|
||||||
param.myf_rw&= ~MY_WAIT_IF_FULL;
|
param.myf_rw&= ~MY_WAIT_IF_FULL;
|
||||||
param.sort_buffer_length= thd->variables.myisam_sort_buff_size;
|
param.sort_buffer_length= thd->variables.myisam_sort_buff_size;
|
||||||
|
param.stats_method= (enum_mi_stats_method)thd->variables.myisam_stats_method;
|
||||||
param.tmpdir=&mysql_tmpdir_list;
|
param.tmpdir=&mysql_tmpdir_list;
|
||||||
if ((error= (repair(thd,param,0) != HA_ADMIN_OK)) && param.retry_repair)
|
if ((error= (repair(thd,param,0) != HA_ADMIN_OK)) && param.retry_repair)
|
||||||
{
|
{
|
||||||
|
@ -832,6 +832,7 @@ public:
|
|||||||
extern struct show_table_type_st sys_table_types[];
|
extern struct show_table_type_st sys_table_types[];
|
||||||
extern const char *ha_row_type[];
|
extern const char *ha_row_type[];
|
||||||
extern TYPELIB tx_isolation_typelib;
|
extern TYPELIB tx_isolation_typelib;
|
||||||
|
extern TYPELIB myisam_stats_method_typelib;
|
||||||
extern handlerton *handlertons[MAX_HA];
|
extern handlerton *handlertons[MAX_HA];
|
||||||
extern ulong total_ha, total_ha_2pc;
|
extern ulong total_ha, total_ha_2pc;
|
||||||
|
|
||||||
|
@ -432,6 +432,7 @@ char server_version[SERVER_VERSION_LENGTH];
|
|||||||
char *mysqld_unix_port, *opt_mysql_tmpdir;
|
char *mysqld_unix_port, *opt_mysql_tmpdir;
|
||||||
const char **errmesg; /* Error messages */
|
const char **errmesg; /* Error messages */
|
||||||
const char *myisam_recover_options_str="OFF";
|
const char *myisam_recover_options_str="OFF";
|
||||||
|
const char *myisam_stats_method_str="nulls_inequal";
|
||||||
/* name of reference on left espression in rewritten IN subquery */
|
/* name of reference on left espression in rewritten IN subquery */
|
||||||
const char *in_left_expr_name= "<left expr>";
|
const char *in_left_expr_name= "<left expr>";
|
||||||
/* name of additional condition */
|
/* name of additional condition */
|
||||||
@ -4360,6 +4361,7 @@ enum options_mysqld
|
|||||||
OPT_MAX_ERROR_COUNT, OPT_MULTI_RANGE_COUNT, OPT_MYISAM_DATA_POINTER_SIZE,
|
OPT_MAX_ERROR_COUNT, OPT_MULTI_RANGE_COUNT, OPT_MYISAM_DATA_POINTER_SIZE,
|
||||||
OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
|
OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
|
||||||
OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE,
|
OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE,
|
||||||
|
OPT_MYISAM_STATS_METHOD,
|
||||||
OPT_NET_BUFFER_LENGTH, OPT_NET_RETRY_COUNT,
|
OPT_NET_BUFFER_LENGTH, OPT_NET_RETRY_COUNT,
|
||||||
OPT_NET_READ_TIMEOUT, OPT_NET_WRITE_TIMEOUT,
|
OPT_NET_READ_TIMEOUT, OPT_NET_WRITE_TIMEOUT,
|
||||||
OPT_OPEN_FILES_LIMIT,
|
OPT_OPEN_FILES_LIMIT,
|
||||||
@ -5515,6 +5517,11 @@ The minimum value for this variable is 4096.",
|
|||||||
(gptr*) &global_system_variables.myisam_sort_buff_size,
|
(gptr*) &global_system_variables.myisam_sort_buff_size,
|
||||||
(gptr*) &max_system_variables.myisam_sort_buff_size, 0,
|
(gptr*) &max_system_variables.myisam_sort_buff_size, 0,
|
||||||
GET_ULONG, REQUIRED_ARG, 8192*1024, 4, ~0L, 0, 1, 0},
|
GET_ULONG, REQUIRED_ARG, 8192*1024, 4, ~0L, 0, 1, 0},
|
||||||
|
{"myisam_stats_method", OPT_MYISAM_STATS_METHOD,
|
||||||
|
"Specifies how MyISAM index statistics collection code should threat NULLs. "
|
||||||
|
"Possible values of name are \"nulls_inequal\" (default behavior for 4.1/5.0), and \"nulls_equal\" (emulate 4.0 behavior).",
|
||||||
|
(gptr*) &myisam_stats_method_str, (gptr*) &myisam_stats_method_str, 0,
|
||||||
|
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
{"net_buffer_length", OPT_NET_BUFFER_LENGTH,
|
{"net_buffer_length", OPT_NET_BUFFER_LENGTH,
|
||||||
"Buffer length for TCP/IP and socket communication.",
|
"Buffer length for TCP/IP and socket communication.",
|
||||||
(gptr*) &global_system_variables.net_buffer_length,
|
(gptr*) &global_system_variables.net_buffer_length,
|
||||||
@ -6099,6 +6106,7 @@ static void mysql_init_variables(void)
|
|||||||
query_id= thread_id= 1L;
|
query_id= thread_id= 1L;
|
||||||
strmov(server_version, MYSQL_SERVER_VERSION);
|
strmov(server_version, MYSQL_SERVER_VERSION);
|
||||||
myisam_recover_options_str= sql_mode_str= "OFF";
|
myisam_recover_options_str= sql_mode_str= "OFF";
|
||||||
|
myisam_stats_method_str= "nulls_inequal";
|
||||||
my_bind_addr = htonl(INADDR_ANY);
|
my_bind_addr = htonl(INADDR_ANY);
|
||||||
threads.empty();
|
threads.empty();
|
||||||
thread_cache.empty();
|
thread_cache.empty();
|
||||||
@ -6147,6 +6155,12 @@ static void mysql_init_variables(void)
|
|||||||
global_system_variables.max_join_size= (ulonglong) HA_POS_ERROR;
|
global_system_variables.max_join_size= (ulonglong) HA_POS_ERROR;
|
||||||
max_system_variables.max_join_size= (ulonglong) HA_POS_ERROR;
|
max_system_variables.max_join_size= (ulonglong) HA_POS_ERROR;
|
||||||
global_system_variables.old_passwords= 0;
|
global_system_variables.old_passwords= 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Default behavior for 4.1 and 5.0 is to treat NULL values as inequal
|
||||||
|
when collecting index statistics for MyISAM tables.
|
||||||
|
*/
|
||||||
|
global_system_variables.myisam_stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
|
||||||
|
|
||||||
/* Variables that depends on compile options */
|
/* Variables that depends on compile options */
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
@ -6756,6 +6770,17 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
|||||||
fprintf(stderr, "Unknown option to tc-heuristic-recover: %s\n",argument);
|
fprintf(stderr, "Unknown option to tc-heuristic-recover: %s\n",argument);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
case OPT_MYISAM_STATS_METHOD:
|
||||||
|
{
|
||||||
|
myisam_stats_method_str= argument;
|
||||||
|
int method;
|
||||||
|
if ((method=find_type(argument, &myisam_stats_method_typelib, 2)) <= 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Invalid value of myisam_stats_method: %s.\n", argument);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
global_system_variables.myisam_stats_method= method-1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OPT_SQL_MODE:
|
case OPT_SQL_MODE:
|
||||||
|
@ -270,6 +270,12 @@ sys_var_long_ptr sys_myisam_data_pointer_size("myisam_data_pointer_size",
|
|||||||
sys_var_thd_ulonglong sys_myisam_max_sort_file_size("myisam_max_sort_file_size", &SV::myisam_max_sort_file_size, fix_myisam_max_sort_file_size, 1);
|
sys_var_thd_ulonglong sys_myisam_max_sort_file_size("myisam_max_sort_file_size", &SV::myisam_max_sort_file_size, fix_myisam_max_sort_file_size, 1);
|
||||||
sys_var_thd_ulong sys_myisam_repair_threads("myisam_repair_threads", &SV::myisam_repair_threads);
|
sys_var_thd_ulong sys_myisam_repair_threads("myisam_repair_threads", &SV::myisam_repair_threads);
|
||||||
sys_var_thd_ulong sys_myisam_sort_buffer_size("myisam_sort_buffer_size", &SV::myisam_sort_buff_size);
|
sys_var_thd_ulong sys_myisam_sort_buffer_size("myisam_sort_buffer_size", &SV::myisam_sort_buff_size);
|
||||||
|
|
||||||
|
sys_var_thd_enum sys_myisam_stats_method("myisam_stats_method",
|
||||||
|
&SV::myisam_stats_method,
|
||||||
|
&myisam_stats_method_typelib,
|
||||||
|
NULL);
|
||||||
|
|
||||||
sys_var_thd_ulong sys_net_buffer_length("net_buffer_length",
|
sys_var_thd_ulong sys_net_buffer_length("net_buffer_length",
|
||||||
&SV::net_buffer_length);
|
&SV::net_buffer_length);
|
||||||
sys_var_thd_ulong sys_net_read_timeout("net_read_timeout",
|
sys_var_thd_ulong sys_net_read_timeout("net_read_timeout",
|
||||||
@ -630,6 +636,7 @@ sys_var *sys_variables[]=
|
|||||||
&sys_myisam_max_sort_file_size,
|
&sys_myisam_max_sort_file_size,
|
||||||
&sys_myisam_repair_threads,
|
&sys_myisam_repair_threads,
|
||||||
&sys_myisam_sort_buffer_size,
|
&sys_myisam_sort_buffer_size,
|
||||||
|
&sys_myisam_stats_method,
|
||||||
&sys_net_buffer_length,
|
&sys_net_buffer_length,
|
||||||
&sys_net_read_timeout,
|
&sys_net_read_timeout,
|
||||||
&sys_net_retry_count,
|
&sys_net_retry_count,
|
||||||
@ -896,6 +903,9 @@ struct show_var_st init_vars[]= {
|
|||||||
{sys_myisam_repair_threads.name, (char*) &sys_myisam_repair_threads,
|
{sys_myisam_repair_threads.name, (char*) &sys_myisam_repair_threads,
|
||||||
SHOW_SYS},
|
SHOW_SYS},
|
||||||
{sys_myisam_sort_buffer_size.name, (char*) &sys_myisam_sort_buffer_size, SHOW_SYS},
|
{sys_myisam_sort_buffer_size.name, (char*) &sys_myisam_sort_buffer_size, SHOW_SYS},
|
||||||
|
|
||||||
|
{sys_myisam_stats_method.name, (char*) &sys_myisam_stats_method, SHOW_SYS},
|
||||||
|
|
||||||
#ifdef __NT__
|
#ifdef __NT__
|
||||||
{"named_pipe", (char*) &opt_enable_named_pipe, SHOW_MY_BOOL},
|
{"named_pipe", (char*) &opt_enable_named_pipe, SHOW_MY_BOOL},
|
||||||
#endif
|
#endif
|
||||||
|
@ -861,14 +861,6 @@ static TABLE_RULE_ENT* find_wild(DYNAMIC_ARRAY *a, const char* key, int len)
|
|||||||
rules (see code below). For that reason, users should not set conflicting
|
rules (see code below). For that reason, users should not set conflicting
|
||||||
rules because they may get unpredicted results (precedence order is
|
rules because they may get unpredicted results (precedence order is
|
||||||
explained in the manual).
|
explained in the manual).
|
||||||
If no table of the list is marked "updating" (so far this can only happen
|
|
||||||
if the statement is a multi-delete (SQLCOM_DELETE_MULTI) and the "tables"
|
|
||||||
is the tables in the FROM): then we always return 0, because there is no
|
|
||||||
reason we play this statement on this slave if it updates nothing. In the
|
|
||||||
case of SQLCOM_DELETE_MULTI, there will be a second call to tables_ok(),
|
|
||||||
with tables having "updating==TRUE" (those after the DELETE), so this
|
|
||||||
second call will make the decision (because
|
|
||||||
all_tables_not_ok() = !tables_ok(1st_list) && !tables_ok(2nd_list)).
|
|
||||||
|
|
||||||
Thought which arose from a question of a big customer "I want to include
|
Thought which arose from a question of a big customer "I want to include
|
||||||
all tables like "abc.%" except the "%.EFG"". This can't be done now. If we
|
all tables like "abc.%" except the "%.EFG"". This can't be done now. If we
|
||||||
|
@ -509,6 +509,7 @@ struct system_variables
|
|||||||
ulong multi_range_count;
|
ulong multi_range_count;
|
||||||
ulong myisam_repair_threads;
|
ulong myisam_repair_threads;
|
||||||
ulong myisam_sort_buff_size;
|
ulong myisam_sort_buff_size;
|
||||||
|
ulong myisam_stats_method;
|
||||||
ulong net_buffer_length;
|
ulong net_buffer_length;
|
||||||
ulong net_interactive_timeout;
|
ulong net_interactive_timeout;
|
||||||
ulong net_read_timeout;
|
ulong net_read_timeout;
|
||||||
|
@ -147,6 +147,10 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
|||||||
MYF(0));
|
MYF(0));
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
This needs to be done before external_lock
|
||||||
|
*/
|
||||||
|
ha_enable_transaction(thd, FALSE);
|
||||||
if (open_and_lock_tables(thd, table_list))
|
if (open_and_lock_tables(thd, table_list))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
if (setup_tables(thd, &thd->lex->select_lex.context,
|
if (setup_tables(thd, &thd->lex->select_lex.context,
|
||||||
@ -352,7 +356,6 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
|||||||
if (ignore ||
|
if (ignore ||
|
||||||
handle_duplicates == DUP_REPLACE)
|
handle_duplicates == DUP_REPLACE)
|
||||||
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
|
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
|
||||||
ha_enable_transaction(thd, FALSE);
|
|
||||||
table->file->start_bulk_insert((ha_rows) 0);
|
table->file->start_bulk_insert((ha_rows) 0);
|
||||||
table->copy_blobs=1;
|
table->copy_blobs=1;
|
||||||
|
|
||||||
@ -372,10 +375,10 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
|||||||
*enclosed, skip_lines, ignore);
|
*enclosed, skip_lines, ignore);
|
||||||
if (table->file->end_bulk_insert())
|
if (table->file->end_bulk_insert())
|
||||||
error=1; /* purecov: inspected */
|
error=1; /* purecov: inspected */
|
||||||
ha_enable_transaction(thd, TRUE);
|
|
||||||
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
|
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
|
||||||
table->next_number_field=0;
|
table->next_number_field=0;
|
||||||
}
|
}
|
||||||
|
ha_enable_transaction(thd, TRUE);
|
||||||
if (file >= 0)
|
if (file >= 0)
|
||||||
my_close(file,MYF(0));
|
my_close(file,MYF(0));
|
||||||
free_blobs(table); /* if pack_blob was used */
|
free_blobs(table); /* if pack_blob was used */
|
||||||
|
@ -183,10 +183,7 @@ static bool begin_trans(THD *thd)
|
|||||||
*/
|
*/
|
||||||
inline bool all_tables_not_ok(THD *thd, TABLE_LIST *tables)
|
inline bool all_tables_not_ok(THD *thd, TABLE_LIST *tables)
|
||||||
{
|
{
|
||||||
return (table_rules_on && tables && !tables_ok(thd,tables) &&
|
return table_rules_on && tables && !tables_ok(thd,tables);
|
||||||
((thd->lex->sql_command != SQLCOM_DELETE_MULTI) ||
|
|
||||||
!tables_ok(thd,
|
|
||||||
(TABLE_LIST *)thd->lex->auxilliary_table_list.first)));
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -7212,6 +7209,12 @@ bool multi_delete_set_locks_and_link_aux_tables(LEX *lex)
|
|||||||
target_tbl->table_name, "MULTI DELETE");
|
target_tbl->table_name, "MULTI DELETE");
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
|
if (!walk->derived)
|
||||||
|
{
|
||||||
|
target_tbl->table_name= walk->table_name;
|
||||||
|
target_tbl->table_name_length= walk->table_name_length;
|
||||||
|
}
|
||||||
|
walk->updating= target_tbl->updating;
|
||||||
walk->lock_type= target_tbl->lock_type;
|
walk->lock_type= target_tbl->lock_type;
|
||||||
target_tbl->correspondent_table= walk; // Remember corresponding table
|
target_tbl->correspondent_table= walk; // Remember corresponding table
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user