mirror of
https://github.com/MariaDB/server.git
synced 2025-01-31 11:01:52 +01:00
Merge bk-internal:/home/bk/mysql-5.0
into mysql.com:/home/jimw/my/mysql-5.0-clean
This commit is contained in:
commit
3b090265ee
18 changed files with 222 additions and 24 deletions
|
@ -6,7 +6,7 @@ AC_PREREQ(2.50)dnl Minimum Autoconf version required.
|
||||||
AC_INIT(sql/mysqld.cc)
|
AC_INIT(sql/mysqld.cc)
|
||||||
AC_CANONICAL_SYSTEM
|
AC_CANONICAL_SYSTEM
|
||||||
# Don't forget to also update the NDB lines below.
|
# Don't forget to also update the NDB lines below.
|
||||||
AM_INIT_AUTOMAKE(mysql, 5.0.3-beta)
|
AM_INIT_AUTOMAKE(mysql, 5.0.4-beta)
|
||||||
AM_CONFIG_HEADER(config.h)
|
AM_CONFIG_HEADER(config.h)
|
||||||
|
|
||||||
PROTOCOL_VERSION=10
|
PROTOCOL_VERSION=10
|
||||||
|
@ -17,7 +17,7 @@ SHARED_LIB_VERSION=14:0:0
|
||||||
# ndb version
|
# ndb version
|
||||||
NDB_VERSION_MAJOR=5
|
NDB_VERSION_MAJOR=5
|
||||||
NDB_VERSION_MINOR=0
|
NDB_VERSION_MINOR=0
|
||||||
NDB_VERSION_BUILD=3
|
NDB_VERSION_BUILD=4
|
||||||
NDB_VERSION_STATUS="beta"
|
NDB_VERSION_STATUS="beta"
|
||||||
|
|
||||||
# Set all version vars based on $VERSION. How do we do this more elegant ?
|
# Set all version vars based on $VERSION. How do we do this more elegant ?
|
||||||
|
|
|
@ -96,7 +96,8 @@ clean-local:
|
||||||
`echo $(sql_cmn_objects) | sed "s;\.lo;.c;g"` \
|
`echo $(sql_cmn_objects) | sed "s;\.lo;.c;g"` \
|
||||||
$(CHARSET_SRCS) $(CHARSET_OBJS) \
|
$(CHARSET_SRCS) $(CHARSET_OBJS) \
|
||||||
$(mystringsextra) $(mysysheaders) $(vioheaders)\
|
$(mystringsextra) $(mysysheaders) $(vioheaders)\
|
||||||
../linked_client_sources net.c
|
../linked_libmysql_sources ../linked_libmysql_r_sources \
|
||||||
|
net.c
|
||||||
|
|
||||||
conf_to_src_SOURCES = conf_to_src.c
|
conf_to_src_SOURCES = conf_to_src.c
|
||||||
conf_to_src_LDADD=
|
conf_to_src_LDADD=
|
||||||
|
|
|
@ -2862,6 +2862,17 @@ int STDCALL mysql_stmt_execute(MYSQL_STMT *stmt)
|
||||||
mysql->status= MYSQL_STATUS_READY;
|
mysql->status= MYSQL_STATUS_READY;
|
||||||
stmt->read_row_func= stmt_read_row_from_cursor;
|
stmt->read_row_func= stmt_read_row_from_cursor;
|
||||||
}
|
}
|
||||||
|
else if (stmt->flags & CURSOR_TYPE_READ_ONLY)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
This is a single-row result set, a result set with no rows, EXPLAIN,
|
||||||
|
SHOW VARIABLES, or some other command which either a) bypasses the
|
||||||
|
cursors framework in the server and writes rows directly to the
|
||||||
|
network or b) is more efficient if all (few) result set rows are
|
||||||
|
precached on client and server's resources are freed.
|
||||||
|
*/
|
||||||
|
DBUG_RETURN(mysql_stmt_store_result(stmt));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
stmt->mysql->unbuffered_fetch_owner= &stmt->unbuffered_fetch_cancelled;
|
stmt->mysql->unbuffered_fetch_owner= &stmt->unbuffered_fetch_cancelled;
|
||||||
|
|
|
@ -8,6 +8,9 @@ create table t1 (a int not null, key(a)) engine=innodb;
|
||||||
create table t2 (a int not null, key(a)) engine=innodb;
|
create table t2 (a int not null, key(a)) engine=innodb;
|
||||||
create table t3 (a int) engine=innodb;
|
create table t3 (a int) engine=innodb;
|
||||||
create table t4 (a int) engine=innodb;
|
create table t4 (a int) engine=innodb;
|
||||||
|
show variables like 'slave_transaction_retries';
|
||||||
|
Variable_name Value
|
||||||
|
slave_transaction_retries 10
|
||||||
show create table t1;
|
show create table t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
|
@ -20,6 +23,9 @@ t2 CREATE TABLE `t2` (
|
||||||
`a` int(11) NOT NULL,
|
`a` int(11) NOT NULL,
|
||||||
KEY `a` (`a`)
|
KEY `a` (`a`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||||
|
show variables like 'slave_transaction_retries';
|
||||||
|
Variable_name Value
|
||||||
|
slave_transaction_retries 2
|
||||||
stop slave;
|
stop slave;
|
||||||
begin;
|
begin;
|
||||||
insert into t3 select * from t2 for update;
|
insert into t3 select * from t2 for update;
|
||||||
|
|
|
@ -65,6 +65,22 @@ SET @@session.time_zone='Europe/Moscow';
|
||||||
insert into t1 values ('20040101000000'), ('20040611093902');
|
insert into t1 values ('20040101000000'), ('20040611093902');
|
||||||
ROLLBACK;
|
ROLLBACK;
|
||||||
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
|
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
|
||||||
|
delete from t1;
|
||||||
|
set time_zone='UTC';
|
||||||
|
load data infile '../../std_data/rpl_timezone.dat' into table t1;
|
||||||
|
select * from t1;
|
||||||
|
t
|
||||||
|
2004-01-01 00:00:00
|
||||||
|
2004-06-11 09:39:02
|
||||||
|
set time_zone='UTC';
|
||||||
|
select * from t1;
|
||||||
|
t
|
||||||
|
2004-01-01 00:00:00
|
||||||
|
2004-06-11 09:39:02
|
||||||
|
set time_zone='Europe/Moscow';
|
||||||
|
set time_zone='Europe/Moscow';
|
||||||
|
delete from t1;
|
||||||
|
insert into t1 values ('20040101000000'), ('20040611093902');
|
||||||
set time_zone='MET';
|
set time_zone='MET';
|
||||||
insert into t2 (select t from t1);
|
insert into t2 (select t from t1);
|
||||||
select * from t1;
|
select * from t1;
|
||||||
|
|
|
@ -142,6 +142,25 @@ Warning 1265 Data truncated for column 'b' at row 10
|
||||||
select @@warning_count;
|
select @@warning_count;
|
||||||
@@warning_count
|
@@warning_count
|
||||||
50
|
50
|
||||||
|
set max_error_count=0;
|
||||||
|
show variables like 'max_error_count';
|
||||||
|
Variable_name Value
|
||||||
|
max_error_count 0
|
||||||
|
update t1 set b='hi';
|
||||||
|
Warnings:
|
||||||
|
select @@warning_count;
|
||||||
|
@@warning_count
|
||||||
|
50
|
||||||
|
show warnings;
|
||||||
|
Level Code Message
|
||||||
|
set max_error_count=65535;
|
||||||
|
show variables like 'max_error_count';
|
||||||
|
Variable_name Value
|
||||||
|
max_error_count 65535
|
||||||
|
set max_error_count=10;
|
||||||
|
show variables like 'max_error_count';
|
||||||
|
Variable_name Value
|
||||||
|
max_error_count 10
|
||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1 (id int) engine=isam;
|
create table t1 (id int) engine=isam;
|
||||||
Warnings:
|
Warnings:
|
||||||
|
|
2
mysql-test/std_data/rpl_timezone.dat
Normal file
2
mysql-test/std_data/rpl_timezone.dat
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
20040101000000
|
||||||
|
20040611093902
|
|
@ -7,6 +7,8 @@
|
||||||
# (Guilhem) have seen the test manage to provoke lock wait timeout
|
# (Guilhem) have seen the test manage to provoke lock wait timeout
|
||||||
# error but not deadlock error; that is ok as code deals with the two
|
# error but not deadlock error; that is ok as code deals with the two
|
||||||
# errors in exactly the same way.
|
# errors in exactly the same way.
|
||||||
|
# We don't 'show status like 'slave_retried_transactions'' because this
|
||||||
|
# is not repeatable (depends on sleeps).
|
||||||
|
|
||||||
source include/have_innodb.inc;
|
source include/have_innodb.inc;
|
||||||
source include/master-slave.inc;
|
source include/master-slave.inc;
|
||||||
|
@ -16,10 +18,12 @@ create table t1 (a int not null, key(a)) engine=innodb;
|
||||||
create table t2 (a int not null, key(a)) engine=innodb;
|
create table t2 (a int not null, key(a)) engine=innodb;
|
||||||
create table t3 (a int) engine=innodb;
|
create table t3 (a int) engine=innodb;
|
||||||
create table t4 (a int) engine=innodb;
|
create table t4 (a int) engine=innodb;
|
||||||
|
show variables like 'slave_transaction_retries';
|
||||||
sync_slave_with_master;
|
sync_slave_with_master;
|
||||||
|
|
||||||
show create table t1;
|
show create table t1;
|
||||||
show create table t2;
|
show create table t2;
|
||||||
|
show variables like 'slave_transaction_retries';
|
||||||
stop slave;
|
stop slave;
|
||||||
|
|
||||||
# 1) Test deadlock
|
# 1) Test deadlock
|
||||||
|
|
|
@ -49,6 +49,24 @@ connection master;
|
||||||
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
|
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
|
||||||
--exec $MYSQL_BINLOG --short-form $MYSQL_TEST_DIR/var/log/master-bin.000001
|
--exec $MYSQL_BINLOG --short-form $MYSQL_TEST_DIR/var/log/master-bin.000001
|
||||||
|
|
||||||
|
# Let us check with LOAD DATA INFILE
|
||||||
|
# (we do it after mysqlbinlog because the temp files names are not constant)
|
||||||
|
connection master;
|
||||||
|
delete from t1;
|
||||||
|
set time_zone='UTC';
|
||||||
|
load data infile '../../std_data/rpl_timezone.dat' into table t1;
|
||||||
|
select * from t1;
|
||||||
|
sync_slave_with_master;
|
||||||
|
set time_zone='UTC';
|
||||||
|
select * from t1;
|
||||||
|
set time_zone='Europe/Moscow';
|
||||||
|
|
||||||
|
# Put back values of before the LOAD
|
||||||
|
connection master;
|
||||||
|
set time_zone='Europe/Moscow';
|
||||||
|
delete from t1;
|
||||||
|
insert into t1 values ('20040101000000'), ('20040611093902');
|
||||||
|
|
||||||
#
|
#
|
||||||
# Now let us check how well we replicate statments reading TIMESTAMP fields
|
# Now let us check how well we replicate statments reading TIMESTAMP fields
|
||||||
# (We should see the same data on master and on slave but it should differ
|
# (We should see the same data on master and on slave but it should differ
|
||||||
|
|
|
@ -96,6 +96,19 @@ update t1 set b=a;
|
||||||
select @@warning_count;
|
select @@warning_count;
|
||||||
--enable_ps_protocol
|
--enable_ps_protocol
|
||||||
|
|
||||||
|
# Bug#9072
|
||||||
|
set max_error_count=0;
|
||||||
|
show variables like 'max_error_count';
|
||||||
|
update t1 set b='hi';
|
||||||
|
--disable_ps_protocol
|
||||||
|
select @@warning_count;
|
||||||
|
--enable_ps_protocol
|
||||||
|
show warnings;
|
||||||
|
set max_error_count=65535;
|
||||||
|
show variables like 'max_error_count';
|
||||||
|
set max_error_count=10;
|
||||||
|
show variables like 'max_error_count';
|
||||||
|
|
||||||
#
|
#
|
||||||
# Test for handler type
|
# Test for handler type
|
||||||
#
|
#
|
||||||
|
|
|
@ -3134,8 +3134,17 @@ we force server id to 2, but this MySQL server will not act as a slave.");
|
||||||
#endif
|
#endif
|
||||||
if (opt_bootstrap) /* If running with bootstrap, do not start replication. */
|
if (opt_bootstrap) /* If running with bootstrap, do not start replication. */
|
||||||
opt_skip_slave_start= 1;
|
opt_skip_slave_start= 1;
|
||||||
/* init_slave() must be called after the thread keys are created */
|
/*
|
||||||
init_slave();
|
init_slave() must be called after the thread keys are created.
|
||||||
|
Some parts of the code (e.g. SHOW STATUS LIKE 'slave_running' and other
|
||||||
|
places) assume that active_mi != 0, so let's fail if it's 0 (out of
|
||||||
|
memory); a message has already been printed.
|
||||||
|
*/
|
||||||
|
if (init_slave() && !active_mi)
|
||||||
|
{
|
||||||
|
end_thr_alarm(1); // Don't allow alarms
|
||||||
|
unireg_abort(1);
|
||||||
|
}
|
||||||
|
|
||||||
if (opt_bootstrap)
|
if (opt_bootstrap)
|
||||||
{
|
{
|
||||||
|
@ -5225,7 +5234,7 @@ The minimum value for this variable is 4096.",
|
||||||
"Max number of errors/warnings to store for a statement.",
|
"Max number of errors/warnings to store for a statement.",
|
||||||
(gptr*) &global_system_variables.max_error_count,
|
(gptr*) &global_system_variables.max_error_count,
|
||||||
(gptr*) &max_system_variables.max_error_count,
|
(gptr*) &max_system_variables.max_error_count,
|
||||||
0, GET_ULONG, REQUIRED_ARG, DEFAULT_ERROR_COUNT, 1, 65535, 0, 1, 0},
|
0, GET_ULONG, REQUIRED_ARG, DEFAULT_ERROR_COUNT, 0, 65535, 0, 1, 0},
|
||||||
{"max_heap_table_size", OPT_MAX_HEP_TABLE_SIZE,
|
{"max_heap_table_size", OPT_MAX_HEP_TABLE_SIZE,
|
||||||
"Don't allow creation of heap tables bigger than this.",
|
"Don't allow creation of heap tables bigger than this.",
|
||||||
(gptr*) &global_system_variables.max_heap_table_size,
|
(gptr*) &global_system_variables.max_heap_table_size,
|
||||||
|
@ -5689,7 +5698,8 @@ struct show_var_st status_vars[]= {
|
||||||
{"Select_range_check", (char*) offsetof(STATUS_VAR, select_range_check_count), SHOW_LONG_STATUS},
|
{"Select_range_check", (char*) offsetof(STATUS_VAR, select_range_check_count), SHOW_LONG_STATUS},
|
||||||
{"Select_scan", (char*) offsetof(STATUS_VAR, select_scan_count), SHOW_LONG_STATUS},
|
{"Select_scan", (char*) offsetof(STATUS_VAR, select_scan_count), SHOW_LONG_STATUS},
|
||||||
{"Slave_open_temp_tables", (char*) &slave_open_temp_tables, SHOW_LONG},
|
{"Slave_open_temp_tables", (char*) &slave_open_temp_tables, SHOW_LONG},
|
||||||
{"Slave_running", (char*) 0, SHOW_SLAVE_RUNNING},
|
{"Slave_running", (char*) 0, SHOW_SLAVE_RUNNING},
|
||||||
|
{"Slave_retried_transactions",(char*) 0, SHOW_SLAVE_RETRIED_TRANS},
|
||||||
{"Slow_launch_threads", (char*) &slow_launch_threads, SHOW_LONG},
|
{"Slow_launch_threads", (char*) &slow_launch_threads, SHOW_LONG},
|
||||||
{"Slow_queries", (char*) offsetof(STATUS_VAR, long_query_count), SHOW_LONG_STATUS},
|
{"Slow_queries", (char*) offsetof(STATUS_VAR, long_query_count), SHOW_LONG_STATUS},
|
||||||
{"Sort_merge_passes", (char*) offsetof(STATUS_VAR, filesort_merge_passes), SHOW_LONG_STATUS},
|
{"Sort_merge_passes", (char*) offsetof(STATUS_VAR, filesort_merge_passes), SHOW_LONG_STATUS},
|
||||||
|
|
24
sql/slave.cc
24
sql/slave.cc
|
@ -27,6 +27,7 @@
|
||||||
#include <my_dir.h>
|
#include <my_dir.h>
|
||||||
#include <sql_common.h>
|
#include <sql_common.h>
|
||||||
|
|
||||||
|
#define MAX_SLAVE_RETRY_PAUSE 5
|
||||||
bool use_slave_mask = 0;
|
bool use_slave_mask = 0;
|
||||||
MY_BITMAP slave_error_mask;
|
MY_BITMAP slave_error_mask;
|
||||||
|
|
||||||
|
@ -2528,7 +2529,7 @@ st_relay_log_info::st_relay_log_info()
|
||||||
ignore_log_space_limit(0), last_master_timestamp(0), slave_skip_counter(0),
|
ignore_log_space_limit(0), last_master_timestamp(0), slave_skip_counter(0),
|
||||||
abort_pos_wait(0), slave_run_id(0), sql_thd(0), last_slave_errno(0),
|
abort_pos_wait(0), slave_run_id(0), sql_thd(0), last_slave_errno(0),
|
||||||
inited(0), abort_slave(0), slave_running(0), until_condition(UNTIL_NONE),
|
inited(0), abort_slave(0), slave_running(0), until_condition(UNTIL_NONE),
|
||||||
until_log_pos(0)
|
until_log_pos(0), retried_trans(0)
|
||||||
{
|
{
|
||||||
group_relay_log_name[0]= event_relay_log_name[0]=
|
group_relay_log_name[0]= event_relay_log_name[0]=
|
||||||
group_master_log_name[0]= 0;
|
group_master_log_name[0]= 0;
|
||||||
|
@ -3261,9 +3262,8 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
|
||||||
init_master_info()).
|
init_master_info()).
|
||||||
b) init_relay_log_pos(), because the BEGIN may be an older relay log.
|
b) init_relay_log_pos(), because the BEGIN may be an older relay log.
|
||||||
*/
|
*/
|
||||||
if (rli->trans_retries--)
|
if (rli->trans_retries < slave_trans_retries)
|
||||||
{
|
{
|
||||||
sql_print_information("Slave SQL thread retries transaction");
|
|
||||||
if (init_master_info(rli->mi, 0, 0, 0, SLAVE_SQL))
|
if (init_master_info(rli->mi, 0, 0, 0, SLAVE_SQL))
|
||||||
sql_print_error("Failed to initialize the master info structure");
|
sql_print_error("Failed to initialize the master info structure");
|
||||||
else if (init_relay_log_pos(rli,
|
else if (init_relay_log_pos(rli,
|
||||||
|
@ -3275,8 +3275,16 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
exec_res= 0;
|
exec_res= 0;
|
||||||
sleep(2); // chance for concurrent connection to get more locks
|
/* chance for concurrent connection to get more locks */
|
||||||
}
|
safe_sleep(thd, min(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE),
|
||||||
|
(CHECK_KILLED_FUNC)sql_slave_killed, (void*)rli);
|
||||||
|
pthread_mutex_lock(&rli->data_lock); // because of SHOW STATUS
|
||||||
|
rli->trans_retries++;
|
||||||
|
rli->retried_trans++;
|
||||||
|
pthread_mutex_unlock(&rli->data_lock);
|
||||||
|
DBUG_PRINT("info", ("Slave retries transaction "
|
||||||
|
"rli->trans_retries: %lu", rli->trans_retries));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
sql_print_error("Slave SQL thread retried transaction %lu time(s) "
|
sql_print_error("Slave SQL thread retried transaction %lu time(s) "
|
||||||
|
@ -3285,8 +3293,8 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
|
||||||
slave_trans_retries);
|
slave_trans_retries);
|
||||||
}
|
}
|
||||||
if (!((thd->options & OPTION_BEGIN) && opt_using_transactions))
|
if (!((thd->options & OPTION_BEGIN) && opt_using_transactions))
|
||||||
rli->trans_retries= slave_trans_retries; // restart from fresh
|
rli->trans_retries= 0; // restart from fresh
|
||||||
}
|
}
|
||||||
return exec_res;
|
return exec_res;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3701,7 +3709,7 @@ slave_begin:
|
||||||
pthread_mutex_lock(&rli->log_space_lock);
|
pthread_mutex_lock(&rli->log_space_lock);
|
||||||
rli->ignore_log_space_limit= 0;
|
rli->ignore_log_space_limit= 0;
|
||||||
pthread_mutex_unlock(&rli->log_space_lock);
|
pthread_mutex_unlock(&rli->log_space_lock);
|
||||||
rli->trans_retries= slave_trans_retries; // start from "no error"
|
rli->trans_retries= 0; // start from "no error"
|
||||||
|
|
||||||
if (init_relay_log_pos(rli,
|
if (init_relay_log_pos(rli,
|
||||||
rli->group_relay_log_name,
|
rli->group_relay_log_name,
|
||||||
|
|
|
@ -293,7 +293,14 @@ typedef struct st_relay_log_info
|
||||||
} until_log_names_cmp_result;
|
} until_log_names_cmp_result;
|
||||||
|
|
||||||
char cached_charset[6];
|
char cached_charset[6];
|
||||||
ulong trans_retries;
|
/*
|
||||||
|
trans_retries varies between 0 to slave_transaction_retries and counts how
|
||||||
|
many times the slave has retried the present transaction; gets reset to 0
|
||||||
|
when the transaction finally succeeds. retried_trans is a cumulative
|
||||||
|
counter: how many times the slave has retried a transaction (any) since
|
||||||
|
slave started.
|
||||||
|
*/
|
||||||
|
ulong trans_retries, retried_trans;
|
||||||
|
|
||||||
st_relay_log_info();
|
st_relay_log_info();
|
||||||
~st_relay_log_info();
|
~st_relay_log_info();
|
||||||
|
|
|
@ -1970,6 +1970,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
|
||||||
{
|
{
|
||||||
ulong stmt_id= uint4korr(packet);
|
ulong stmt_id= uint4korr(packet);
|
||||||
ulong flags= (ulong) ((uchar) packet[4]);
|
ulong flags= (ulong) ((uchar) packet[4]);
|
||||||
|
Cursor *cursor= 0;
|
||||||
/*
|
/*
|
||||||
Query text for binary log, or empty string if the query is not put into
|
Query text for binary log, or empty string if the query is not put into
|
||||||
binary log.
|
binary log.
|
||||||
|
@ -2007,15 +2008,17 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
|
||||||
statement: we can't open a cursor for it.
|
statement: we can't open a cursor for it.
|
||||||
*/
|
*/
|
||||||
flags= 0;
|
flags= 0;
|
||||||
|
my_error(ER_SP_BAD_CURSOR_QUERY, MYF(0));
|
||||||
|
goto err;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DBUG_PRINT("info",("Using READ_ONLY cursor"));
|
DBUG_PRINT("info",("Using READ_ONLY cursor"));
|
||||||
if (!stmt->cursor &&
|
if (!stmt->cursor &&
|
||||||
!(stmt->cursor= new (&stmt->main_mem_root) Cursor()))
|
!(cursor= stmt->cursor= new (&stmt->main_mem_root) Cursor()))
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
/* If lex->result is set, mysql_execute_command will use it */
|
/* If lex->result is set, mysql_execute_command will use it */
|
||||||
stmt->lex->result= &stmt->cursor->result;
|
stmt->lex->result= &cursor->result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
@ -2061,11 +2064,10 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
|
||||||
my_pthread_setprio(pthread_self(), WAIT_PRIOR);
|
my_pthread_setprio(pthread_self(), WAIT_PRIOR);
|
||||||
thd->protocol= &thd->protocol_simple; // Use normal protocol
|
thd->protocol= &thd->protocol_simple; // Use normal protocol
|
||||||
|
|
||||||
if (flags & (ulong) CURSOR_TYPE_READ_ONLY)
|
if (cursor && cursor->is_open())
|
||||||
{
|
{
|
||||||
if (stmt->cursor->is_open())
|
cursor->init_from_thd(thd);
|
||||||
stmt->cursor->init_from_thd(thd);
|
cursor->state= stmt->state;
|
||||||
stmt->cursor->state= stmt->state;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -370,7 +370,7 @@ public:
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
void set_unit(SELECT_LEX_UNIT *unit_arg) { unit= unit_arg; }
|
void set_unit(SELECT_LEX_UNIT *unit_arg) { unit= unit_arg; }
|
||||||
Cursor() :join(0), unit(0) {}
|
Cursor() :Item_arena(TRUE), join(0), unit(0) {}
|
||||||
~Cursor();
|
~Cursor();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1331,6 +1331,19 @@ static bool show_status_array(THD *thd, const char *wild,
|
||||||
pthread_mutex_unlock(&LOCK_active_mi);
|
pthread_mutex_unlock(&LOCK_active_mi);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SHOW_SLAVE_RETRIED_TRANS:
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
TODO: in 5.1 with multimaster, have one such counter per line in SHOW
|
||||||
|
SLAVE STATUS, and have the sum over all lines here.
|
||||||
|
*/
|
||||||
|
pthread_mutex_lock(&LOCK_active_mi);
|
||||||
|
pthread_mutex_lock(&active_mi->rli.data_lock);
|
||||||
|
end= int10_to_str(active_mi->rli.retried_trans, buff, 10);
|
||||||
|
pthread_mutex_unlock(&active_mi->rli.data_lock);
|
||||||
|
pthread_mutex_unlock(&LOCK_active_mi);
|
||||||
|
break;
|
||||||
|
}
|
||||||
#endif /* HAVE_REPLICATION */
|
#endif /* HAVE_REPLICATION */
|
||||||
case SHOW_OPENTABLES:
|
case SHOW_OPENTABLES:
|
||||||
end= int10_to_str((long) cached_tables(), buff, 10);
|
end= int10_to_str((long) cached_tables(), buff, 10);
|
||||||
|
|
|
@ -182,7 +182,7 @@ enum SHOW_TYPE
|
||||||
SHOW_SSL_CTX_SESS_TIMEOUTS, SHOW_SSL_CTX_SESS_CACHE_FULL,
|
SHOW_SSL_CTX_SESS_TIMEOUTS, SHOW_SSL_CTX_SESS_CACHE_FULL,
|
||||||
SHOW_SSL_GET_CIPHER_LIST,
|
SHOW_SSL_GET_CIPHER_LIST,
|
||||||
#endif /* HAVE_OPENSSL */
|
#endif /* HAVE_OPENSSL */
|
||||||
SHOW_RPL_STATUS, SHOW_SLAVE_RUNNING,
|
SHOW_RPL_STATUS, SHOW_SLAVE_RUNNING, SHOW_SLAVE_RETRIED_TRANS,
|
||||||
SHOW_KEY_CACHE_LONG, SHOW_KEY_CACHE_CONST_LONG,
|
SHOW_KEY_CACHE_LONG, SHOW_KEY_CACHE_CONST_LONG,
|
||||||
SHOW_LONG_STATUS, SHOW_LONG_CONST_STATUS
|
SHOW_LONG_STATUS, SHOW_LONG_CONST_STATUS
|
||||||
};
|
};
|
||||||
|
|
|
@ -12782,6 +12782,72 @@ static void test_bug8722()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MYSQL_STMT *open_cursor(char *query)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
const ulong type= (ulong)CURSOR_TYPE_READ_ONLY;
|
||||||
|
|
||||||
|
MYSQL_STMT *stmt= mysql_stmt_init(mysql);
|
||||||
|
rc= mysql_stmt_prepare(stmt, query, strlen(query));
|
||||||
|
check_execute(stmt, rc);
|
||||||
|
|
||||||
|
mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
|
||||||
|
return stmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void test_bug8880()
|
||||||
|
{
|
||||||
|
MYSQL_STMT *stmt_list[2], **stmt;
|
||||||
|
MYSQL_STMT **stmt_list_end= (MYSQL_STMT**) stmt_list + 2;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
myheader("test_bug8880");
|
||||||
|
|
||||||
|
mysql_query(mysql, "drop table if exists t1");
|
||||||
|
mysql_query(mysql, "create table t1 (a int not null primary key, b int)");
|
||||||
|
rc= mysql_query(mysql, "insert into t1 values (1,1)");
|
||||||
|
myquery(rc); /* one check is enough */
|
||||||
|
/*
|
||||||
|
when inserting 2 rows everything works well
|
||||||
|
mysql_query(mysql, "INSERT INTO t1 VALUES (1,1),(2,2)");
|
||||||
|
*/
|
||||||
|
for (stmt= stmt_list; stmt < stmt_list_end; stmt++)
|
||||||
|
*stmt= open_cursor("select a from t1");
|
||||||
|
for (stmt= stmt_list; stmt < stmt_list_end; stmt++)
|
||||||
|
{
|
||||||
|
rc= mysql_stmt_execute(*stmt);
|
||||||
|
check_execute(*stmt, rc);
|
||||||
|
}
|
||||||
|
for (stmt= stmt_list; stmt < stmt_list_end; stmt++)
|
||||||
|
mysql_stmt_close(*stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void test_bug9159()
|
||||||
|
{
|
||||||
|
MYSQL_STMT *stmt;
|
||||||
|
int rc;
|
||||||
|
const char *stmt_text= "select a, b from t1";
|
||||||
|
const unsigned long type= CURSOR_TYPE_READ_ONLY;
|
||||||
|
|
||||||
|
myheader("test_bug9159");
|
||||||
|
|
||||||
|
mysql_query(mysql, "drop table if exists t1");
|
||||||
|
mysql_query(mysql, "create table t1 (a int not null primary key, b int)");
|
||||||
|
rc= mysql_query(mysql, "insert into t1 values (1,1)");
|
||||||
|
myquery(rc);
|
||||||
|
|
||||||
|
stmt= mysql_stmt_init(mysql);
|
||||||
|
mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
|
||||||
|
mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void *)&type);
|
||||||
|
|
||||||
|
mysql_stmt_execute(stmt);
|
||||||
|
mysql_stmt_close(stmt);
|
||||||
|
rc= mysql_query(mysql, "drop table if exists t1");
|
||||||
|
myquery(rc);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Read and parse arguments and MySQL options from my.cnf
|
Read and parse arguments and MySQL options from my.cnf
|
||||||
*/
|
*/
|
||||||
|
@ -13005,6 +13071,8 @@ static struct my_tests_st my_tests[]= {
|
||||||
{ "test_bug7990", test_bug7990 },
|
{ "test_bug7990", test_bug7990 },
|
||||||
{ "test_bug8378", test_bug8378 },
|
{ "test_bug8378", test_bug8378 },
|
||||||
{ "test_bug8722", test_bug8722 },
|
{ "test_bug8722", test_bug8722 },
|
||||||
|
{ "test_bug8880", test_bug8880 },
|
||||||
|
{ "test_bug9159", test_bug9159 },
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue