merge with 3.23
This commit is contained in:
commit
fd0459a521
@ -48193,15 +48193,18 @@ not yet 100% confident in this code.
|
|||||||
@appendixsubsec Changes in release 3.23.47
|
@appendixsubsec Changes in release 3.23.47
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
@item
|
@item
|
||||||
|
Fixed in when using the following construct:
|
||||||
|
@code{SELECT ... WHERE key=@@var_name OR $key=@@var_name2}
|
||||||
|
@item
|
||||||
|
Restrict InnoDB keys to 500 bytes.
|
||||||
|
@item
|
||||||
InnoDB now supports @code{NULL} in keys.
|
InnoDB now supports @code{NULL} in keys.
|
||||||
@item
|
@item
|
||||||
Fixed shutdown problem on HPUX. (Introduced in 3.23.46)
|
Fixed shutdown problem on HPUX. (Introduced in 3.23.46)
|
||||||
@item
|
@item
|
||||||
Added 'DO expression' command.
|
|
||||||
@item
|
|
||||||
Fixed core-dump bug in replication when using SELECT RELEASE_LOCK();
|
Fixed core-dump bug in replication when using SELECT RELEASE_LOCK();
|
||||||
@item
|
@item
|
||||||
Added new statement DO expression,[expression].
|
Added new command: @code{DO expression,[expression]}
|
||||||
@item
|
@item
|
||||||
Added @code{slave-skip-errors} option
|
Added @code{slave-skip-errors} option
|
||||||
@item
|
@item
|
||||||
|
@ -452,7 +452,7 @@ btr_search_info_update_slow(
|
|||||||
Checks if a guessed position for a tree cursor is right. Note that if
|
Checks if a guessed position for a tree cursor is right. Note that if
|
||||||
mode is PAGE_CUR_LE, which is used in inserts, and the function returns
|
mode is PAGE_CUR_LE, which is used in inserts, and the function returns
|
||||||
TRUE, then cursor->up_match and cursor->low_match both have sensible values. */
|
TRUE, then cursor->up_match and cursor->low_match both have sensible values. */
|
||||||
UNIV_INLINE
|
static
|
||||||
ibool
|
ibool
|
||||||
btr_search_check_guess(
|
btr_search_check_guess(
|
||||||
/*===================*/
|
/*===================*/
|
||||||
|
@ -107,14 +107,17 @@ dtype_get_pad_char(
|
|||||||
ULINT_UNDEFINED if no padding specified */
|
ULINT_UNDEFINED if no padding specified */
|
||||||
dtype_t* type) /* in: type */
|
dtype_t* type) /* in: type */
|
||||||
{
|
{
|
||||||
if (type->mtype == DATA_CHAR) {
|
if (type->mtype == DATA_CHAR
|
||||||
/* space is the padding character for all char strings */
|
|| type->mtype == DATA_VARCHAR
|
||||||
|
|| type->mtype == DATA_BINARY
|
||||||
|
|| type->mtype == DATA_FIXBINARY) {
|
||||||
|
|
||||||
|
/* Space is the padding character for all char and binary
|
||||||
|
strings */
|
||||||
|
|
||||||
return((ulint)' ');
|
return((ulint)' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
ut_ad((type->mtype == DATA_BINARY) || (type->mtype == DATA_VARCHAR));
|
|
||||||
|
|
||||||
/* No padding specified */
|
/* No padding specified */
|
||||||
|
|
||||||
return(ULINT_UNDEFINED);
|
return(ULINT_UNDEFINED);
|
||||||
|
@ -1019,7 +1019,8 @@ loop:
|
|||||||
if (recv_addr->state == RECV_NOT_PROCESSED) {
|
if (recv_addr->state == RECV_NOT_PROCESSED) {
|
||||||
if (!has_printed) {
|
if (!has_printed) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"InnoDB: Starting an apply batch of log records to the database...\n");
|
"InnoDB: Starting an apply batch of log records to the database...\n"
|
||||||
|
"InnoDB: Progress in percents:");
|
||||||
has_printed = TRUE;
|
has_printed = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1046,6 +1047,16 @@ loop:
|
|||||||
|
|
||||||
recv_addr = HASH_GET_NEXT(addr_hash, recv_addr);
|
recv_addr = HASH_GET_NEXT(addr_hash, recv_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (has_printed
|
||||||
|
&& (i * 100) / hash_get_n_cells(recv_sys->addr_hash)
|
||||||
|
!= ((i + 1) * 100)
|
||||||
|
/ hash_get_n_cells(recv_sys->addr_hash)) {
|
||||||
|
|
||||||
|
fprintf(stderr, "%lu ",
|
||||||
|
(i * 100) / hash_get_n_cells(recv_sys->addr_hash));
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait until all the pages have been processed */
|
/* Wait until all the pages have been processed */
|
||||||
@ -1059,6 +1070,11 @@ loop:
|
|||||||
mutex_enter(&(recv_sys->mutex));
|
mutex_enter(&(recv_sys->mutex));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (has_printed) {
|
||||||
|
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (!allow_ibuf) {
|
if (!allow_ibuf) {
|
||||||
/* Flush all the file pages to disk and invalidate them in
|
/* Flush all the file pages to disk and invalidate them in
|
||||||
the buffer pool */
|
the buffer pool */
|
||||||
|
@ -581,6 +581,13 @@ os_file_flush(
|
|||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Since Linux returns EINVAL if the 'file' is actually a raw device,
|
||||||
|
we choose to ignore that error */
|
||||||
|
|
||||||
|
if (errno == EINVAL) {
|
||||||
|
return(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"InnoDB: Error: the OS said file flush did not succeed\n");
|
"InnoDB: Error: the OS said file flush did not succeed\n");
|
||||||
|
|
||||||
|
@ -100,7 +100,15 @@ cmp_types_are_equal(
|
|||||||
dtype_t* type1, /* in: type 1 */
|
dtype_t* type1, /* in: type 1 */
|
||||||
dtype_t* type2) /* in: type 2 */
|
dtype_t* type2) /* in: type 2 */
|
||||||
{
|
{
|
||||||
if (type1->mtype != type2->mtype) {
|
if ((type1->mtype == DATA_VARCHAR && type2->mtype == DATA_CHAR)
|
||||||
|
|| (type1->mtype == DATA_CHAR && type2->mtype == DATA_VARCHAR)
|
||||||
|
|| (type1->mtype == DATA_FIXBINARY && type2->mtype == DATA_BINARY)
|
||||||
|
|| (type1->mtype == DATA_BINARY && type2->mtype == DATA_FIXBINARY)) {
|
||||||
|
|
||||||
|
return(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type1->mtype != type2->mtype) {
|
||||||
|
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
@ -1683,6 +1683,8 @@ row_scan_and_check_index(
|
|||||||
rec_t* rec;
|
rec_t* rec;
|
||||||
ibool is_ok = TRUE;
|
ibool is_ok = TRUE;
|
||||||
int cmp;
|
int cmp;
|
||||||
|
ibool contains_null;
|
||||||
|
ulint i;
|
||||||
char err_buf[1000];
|
char err_buf[1000];
|
||||||
|
|
||||||
*n_rows = 0;
|
*n_rows = 0;
|
||||||
@ -1728,6 +1730,21 @@ loop:
|
|||||||
cmp = cmp_dtuple_rec_with_match(prev_entry, rec,
|
cmp = cmp_dtuple_rec_with_match(prev_entry, rec,
|
||||||
&matched_fields,
|
&matched_fields,
|
||||||
&matched_bytes);
|
&matched_bytes);
|
||||||
|
contains_null = FALSE;
|
||||||
|
|
||||||
|
/* In a unique secondary index we allow equal key values if
|
||||||
|
they contain SQL NULLs */
|
||||||
|
|
||||||
|
for (i = 0;
|
||||||
|
i < dict_index_get_n_ordering_defined_by_user(index);
|
||||||
|
i++) {
|
||||||
|
if (UNIV_SQL_NULL == dfield_get_len(
|
||||||
|
dtuple_get_nth_field(prev_entry, i))) {
|
||||||
|
|
||||||
|
contains_null = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (cmp > 0) {
|
if (cmp > 0) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Error: index records in a wrong order in index %s\n",
|
"Error: index records in a wrong order in index %s\n",
|
||||||
@ -1741,6 +1758,7 @@ loop:
|
|||||||
|
|
||||||
is_ok = FALSE;
|
is_ok = FALSE;
|
||||||
} else if ((index->type & DICT_UNIQUE)
|
} else if ((index->type & DICT_UNIQUE)
|
||||||
|
&& !contains_null
|
||||||
&& matched_fields >=
|
&& matched_fields >=
|
||||||
dict_index_get_n_ordering_defined_by_user(index)) {
|
dict_index_get_n_ordering_defined_by_user(index)) {
|
||||||
|
|
||||||
|
@ -2427,7 +2427,19 @@ loop:
|
|||||||
|
|
||||||
background_loop:
|
background_loop:
|
||||||
/* In this loop we run background operations when the server
|
/* In this loop we run background operations when the server
|
||||||
is quiet */
|
is quiet and we also come here about once in 10 seconds */
|
||||||
|
|
||||||
|
srv_main_thread_op_info = "flushing buffer pool pages";
|
||||||
|
|
||||||
|
/* Flush a few oldest pages to make the checkpoint younger */
|
||||||
|
|
||||||
|
n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 10, ut_dulint_max);
|
||||||
|
|
||||||
|
srv_main_thread_op_info = "making checkpoint";
|
||||||
|
|
||||||
|
/* Make a new checkpoint about once in 10 seconds */
|
||||||
|
|
||||||
|
log_checkpoint(TRUE, FALSE);
|
||||||
|
|
||||||
srv_main_thread_op_info = (char *) "reserving kernel mutex";
|
srv_main_thread_op_info = (char *) "reserving kernel mutex";
|
||||||
|
|
||||||
|
@ -24,3 +24,14 @@ select @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3;
|
|||||||
select @t5;
|
select @t5;
|
||||||
@t5
|
@t5
|
||||||
1.23456
|
1.23456
|
||||||
|
@min_cid:=min(c_id) @max_cid:=max(c_id)
|
||||||
|
1 4
|
||||||
|
c_id c_name c_country
|
||||||
|
1 Bozo USA
|
||||||
|
4 Mr. Floppy GB
|
||||||
|
c_id c_name c_country
|
||||||
|
1 Bozo USA
|
||||||
|
4 Mr. Floppy GB
|
||||||
|
c_id c_name c_country
|
||||||
|
1 Bozo USA
|
||||||
|
4 Mr. Floppy GB
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#
|
#
|
||||||
# test variables
|
# test variables
|
||||||
#
|
#
|
||||||
|
drop table if exists t1;
|
||||||
set @`test`=1,@TEST=3,@select=2,@t5=1.23456;
|
set @`test`=1,@TEST=3,@select=2,@t5=1.23456;
|
||||||
select @test,@`select`,@TEST,@not_used;
|
select @test,@`select`,@TEST,@not_used;
|
||||||
set @test_int=10,@test_double=1e-10,@test_string="abcdeghi",@test_string2="abcdefghij",@select=NULL;
|
set @test_int=10,@test_double=1e-10,@test_string="abcdeghi",@test_string2="abcdefghij",@select=NULL;
|
||||||
@ -14,3 +15,15 @@ select @test_int,@test_double,@test_string,@test_string2;
|
|||||||
select @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3;
|
select @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3;
|
||||||
select @t5;
|
select @t5;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test problem with WHERE and variables
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE TABLE t1 (c_id INT(4) NOT NULL, c_name CHAR(20), c_country CHAR(3), PRIMARY KEY(c_id));
|
||||||
|
INSERT INTO t1 VALUES (1,'Bozo','USA'),(2,'Ronald','USA'),(3,'Kinko','IRE'),(4,'Mr. Floppy','GB');
|
||||||
|
SELECT @min_cid:=min(c_id), @max_cid:=max(c_id) from t1;
|
||||||
|
SELECT * FROM t1 WHERE c_id=@min_cid OR c_id=@max_cid;
|
||||||
|
SELECT * FROM t1 WHERE c_id=@min_cid OR c_id=@max_cid OR c_id=666;
|
||||||
|
ALTER TABLE t1 DROP PRIMARY KEY;
|
||||||
|
select * from t1 where c_id=@min_cid OR c_id=@max_cid;
|
||||||
|
drop table t1;
|
||||||
|
@ -3222,7 +3222,7 @@ ha_innobase::update_table_comment(
|
|||||||
{
|
{
|
||||||
row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
|
row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
|
||||||
uint length = strlen(comment);
|
uint length = strlen(comment);
|
||||||
char* str = my_malloc(length + 200, MYF(0));
|
char* str = my_malloc(length + 550, MYF(0));
|
||||||
char* pos;
|
char* pos;
|
||||||
|
|
||||||
if (!str) {
|
if (!str) {
|
||||||
@ -3241,7 +3241,7 @@ ha_innobase::update_table_comment(
|
|||||||
|
|
||||||
/* We assume 150 bytes of space to print info */
|
/* We assume 150 bytes of space to print info */
|
||||||
|
|
||||||
dict_print_info_on_foreign_keys(pos, 150, prebuilt->table);
|
dict_print_info_on_foreign_keys(pos, 500, prebuilt->table);
|
||||||
|
|
||||||
return(str);
|
return(str);
|
||||||
}
|
}
|
||||||
|
@ -101,8 +101,11 @@ class ha_innobase: public handler
|
|||||||
a secondary key record must also contain the
|
a secondary key record must also contain the
|
||||||
primary key value:
|
primary key value:
|
||||||
max key length is therefore set to slightly
|
max key length is therefore set to slightly
|
||||||
less than 1 / 4 of page size which is 16 kB */
|
less than 1 / 4 of page size which is 16 kB;
|
||||||
uint max_key_length() const { return 3500; }
|
but currently MySQL does not work with keys
|
||||||
|
whose size is > MAX_KEY_LENGTH */
|
||||||
|
uint max_key_length() const { return((MAX_KEY_LENGTH <= 3500) ?
|
||||||
|
MAX_KEY_LENGTH : 3500);}
|
||||||
bool fast_key_read() { return 1;}
|
bool fast_key_read() { return 1;}
|
||||||
key_map keys_to_use_for_scanning() { return ~(key_map) 0; }
|
key_map keys_to_use_for_scanning() { return ~(key_map) 0; }
|
||||||
bool has_transactions() { return 1;}
|
bool has_transactions() { return 1;}
|
||||||
|
@ -1845,6 +1845,16 @@ Item_func_set_user_var::val_str(String *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Item_func_set_user_var::print(String *str)
|
||||||
|
{
|
||||||
|
str->append('(');
|
||||||
|
str->append(name.str,name.length);
|
||||||
|
str->append(":=",2);
|
||||||
|
args[0]->print(str);
|
||||||
|
str->append(')');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
user_var_entry *Item_func_get_user_var::get_entry()
|
user_var_entry *Item_func_get_user_var::get_entry()
|
||||||
{
|
{
|
||||||
if (!entry || ! entry->value)
|
if (!entry || ! entry->value)
|
||||||
@ -1937,6 +1947,34 @@ enum Item_result Item_func_get_user_var::result_type() const
|
|||||||
return entry->type;
|
return entry->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Item_func_get_user_var::print(String *str)
|
||||||
|
{
|
||||||
|
str->append('@');
|
||||||
|
str->append(name.str,name.length);
|
||||||
|
str->append(')');
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Item_func_get_user_var::eq(const Item *item) const
|
||||||
|
{
|
||||||
|
/* Assume we don't have rtti */
|
||||||
|
if (this == item)
|
||||||
|
return 1; // Same item is same.
|
||||||
|
/* Check if other type is also a get_user_var() object */
|
||||||
|
#ifdef FIX_THIS
|
||||||
|
if (item->eq == &Item_func_get_user_var::eq)
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
if (item->type() != FUNC_ITEM ||
|
||||||
|
((Item_func*) item)->func_name() != func_name())
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
Item_func_get_user_var *other=(Item_func_get_user_var*) item;
|
||||||
|
return (name.length == other->name.length &&
|
||||||
|
!memcmp(name.str, other->name.str, name.length));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
longlong Item_func_inet_aton::val_int()
|
longlong Item_func_inet_aton::val_int()
|
||||||
{
|
{
|
||||||
uint byte_result = 0;
|
uint byte_result = 0;
|
||||||
|
@ -841,6 +841,7 @@ public:
|
|||||||
enum Item_result result_type () const { return cached_result_type; }
|
enum Item_result result_type () const { return cached_result_type; }
|
||||||
bool fix_fields(THD *thd,struct st_table_list *tables);
|
bool fix_fields(THD *thd,struct st_table_list *tables);
|
||||||
void fix_length_and_dec();
|
void fix_length_and_dec();
|
||||||
|
void print(String *str);
|
||||||
const char *func_name() const { return "set_user_var"; }
|
const char *func_name() const { return "set_user_var"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -859,13 +860,16 @@ public:
|
|||||||
longlong val_int();
|
longlong val_int();
|
||||||
String *val_str(String* str);
|
String *val_str(String* str);
|
||||||
void fix_length_and_dec();
|
void fix_length_and_dec();
|
||||||
|
void print(String *str);
|
||||||
enum Item_result result_type() const;
|
enum Item_result result_type() const;
|
||||||
const char *func_name() const { return "get_user_var"; }
|
const char *func_name() const { return "get_user_var"; }
|
||||||
bool const_item() const { return const_var_flag; }
|
bool const_item() const { return const_var_flag; }
|
||||||
table_map used_tables() const
|
table_map used_tables() const
|
||||||
{ return const_var_flag ? 0 : RAND_TABLE_BIT; }
|
{ return const_var_flag ? 0 : RAND_TABLE_BIT; }
|
||||||
|
bool eq(const Item *item) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Item_func_inet_aton : public Item_int_func
|
class Item_func_inet_aton : public Item_int_func
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -2909,9 +2909,9 @@ CHANGEABLE_VAR changeable_vars[] = {
|
|||||||
(long*) &innobase_additional_mem_pool_size, 1*1024*1024L, 512*1024L,
|
(long*) &innobase_additional_mem_pool_size, 1*1024*1024L, 512*1024L,
|
||||||
~0L, 0, 1024},
|
~0L, 0, 1024},
|
||||||
{"innodb_file_io_threads",
|
{"innodb_file_io_threads",
|
||||||
(long*) &innobase_file_io_threads, 9, 4, 64, 0, 1},
|
(long*) &innobase_file_io_threads, 4, 4, 64, 0, 1},
|
||||||
{"innodb_lock_wait_timeout",
|
{"innodb_lock_wait_timeout",
|
||||||
(long*) &innobase_lock_wait_timeout, 1024 * 1024 * 1024, 1,
|
(long*) &innobase_lock_wait_timeout, 50, 1,
|
||||||
1024 * 1024 * 1024, 0, 1},
|
1024 * 1024 * 1024, 0, 1},
|
||||||
{"innodb_thread_concurrency",
|
{"innodb_thread_concurrency",
|
||||||
(long*) &innobase_thread_concurrency, 8, 1, 1000, 0, 1},
|
(long*) &innobase_thread_concurrency, 8, 1, 1000, 0, 1},
|
||||||
@ -4078,6 +4078,7 @@ static void get_options(int argc,char **argv)
|
|||||||
break;
|
break;
|
||||||
case OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT:
|
case OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT:
|
||||||
innobase_flush_log_at_trx_commit= optarg ? test(atoi(optarg)) : 1;
|
innobase_flush_log_at_trx_commit= optarg ? test(atoi(optarg)) : 1;
|
||||||
|
break;
|
||||||
case OPT_INNODB_FAST_SHUTDOWN:
|
case OPT_INNODB_FAST_SHUTDOWN:
|
||||||
innobase_fast_shutdown= optarg ? test(atoi(optarg)) : 1;
|
innobase_fast_shutdown= optarg ? test(atoi(optarg)) : 1;
|
||||||
break;
|
break;
|
||||||
|
@ -35,7 +35,7 @@ const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref",
|
|||||||
"MAYBE_REF","ALL","range","index","fulltext" };
|
"MAYBE_REF","ALL","range","index","fulltext" };
|
||||||
|
|
||||||
static bool make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
|
static bool make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
|
||||||
DYNAMIC_ARRAY *keyuse);
|
DYNAMIC_ARRAY *keyuse);
|
||||||
static bool update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,
|
static bool update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,
|
||||||
JOIN_TAB *join_tab,
|
JOIN_TAB *join_tab,
|
||||||
uint tables,COND *conds,table_map table_map);
|
uint tables,COND *conds,table_map table_map);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user