Commit fd0459a5 authored by monty@hundin.mysql.fi's avatar monty@hundin.mysql.fi

merge with 3.23

parents 4b877e00 89f8ca05
...@@ -48193,15 +48193,18 @@ not yet 100% confident in this code. ...@@ -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( ...@@ -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( ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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( ...@@ -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,6 +100,14 @@ cmp_types_are_equal( ...@@ -100,6 +100,14 @@ 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 == 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) { if (type1->mtype != type2->mtype) {
return(FALSE); return(FALSE);
......
...@@ -1683,6 +1683,8 @@ row_scan_and_check_index( ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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; ...@@ -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
# #
# 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; ...@@ -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( ...@@ -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( ...@@ -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 ...@@ -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) ...@@ -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 ...@@ -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: ...@@ -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: ...@@ -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[] = { ...@@ -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) ...@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment