Commit dd121781 authored by unknown's avatar unknown

Merge bk-internal.mysql.com:/home/bk/mysql-5.1-runtime

into  damien-katzs-computer.local:/Users/dkatz/mysql-5.1-runtime

parents 219af872 4db46e26
......@@ -203,7 +203,7 @@ typedef struct st_net {
unsigned char reading_or_writing;
char save_char;
my_bool no_send_ok; /* For SPs and other things that do multiple stmts */
my_bool no_send_eof; /* For SPs' first version read-only cursors */
my_bool unused; /* Please remove with the next incompatible ABI change */
my_bool compress;
/*
Set if OK packet is already sent, and we do not need to send error
......
......@@ -498,3 +498,71 @@ handler t1_alias read a next;
handler t1_alias READ a next where inexistent > 0;
handler t1_alias close;
drop table t1;
#
# Bug#21587 FLUSH TABLES causes server crash when used with HANDLER statements
#
--disable_warnings
drop table if exists t1,t2;
--enable_warnings
create table t1 (c1 int);
create table t2 (c1 int);
insert into t1 values (1);
insert into t2 values (2);
--echo connection: default
handler t1 open;
handler t1 read first;
connect (flush,localhost,root,,);
connection flush;
--echo connection: flush
--send flush tables;
connection default;
--echo connection: default
let $wait_condition=
select count(*) = 1 from information_schema.processlist
where state = "Flushing tables";
--source include/wait_condition.inc
handler t2 open;
handler t2 read first;
handler t1 read next;
handler t1 close;
handler t2 close;
connection flush;
reap;
connection default;
drop table t1,t2;
disconnect flush;
#
# Bug#31409 RENAME TABLE causes server crash or deadlock when used with HANDLER statements
#
--disable_warnings
drop table if exists t1,t2;
--enable_warnings
create table t1 (c1 int);
--echo connection: default
handler t1 open;
handler t1 read first;
connect (flush,localhost,root,,);
connection flush;
--echo connection: flush
--send rename table t1 to t2;
connection default;
--echo connection: default
let $wait_condition=
select count(*) = 1 from information_schema.processlist
where state = "Waiting for table" and info = "rename table t1 to t2";
--source include/wait_condition.inc
handler t2 open;
handler t2 read first;
--error ER_NO_SUCH_TABLE
handler t1 read next;
handler t1 close;
handler t2 close;
connection flush;
reap;
connection default;
drop table t2;
disconnect flush;
......@@ -535,3 +535,43 @@ handler t1_alias READ a next where inexistent > 0;
ERROR 42S22: Unknown column 'inexistent' in 'field list'
handler t1_alias close;
drop table t1;
drop table if exists t1,t2;
create table t1 (c1 int);
create table t2 (c1 int);
insert into t1 values (1);
insert into t2 values (2);
connection: default
handler t1 open;
handler t1 read first;
c1
1
connection: flush
flush tables;;
connection: default
handler t2 open;
handler t2 read first;
c1
2
handler t1 read next;
c1
1
handler t1 close;
handler t2 close;
drop table t1,t2;
drop table if exists t1,t2;
create table t1 (c1 int);
connection: default
handler t1 open;
handler t1 read first;
c1
connection: flush
rename table t1 to t2;;
connection: default
handler t2 open;
handler t2 read first;
c1
handler t1 read next;
ERROR 42S02: Table 'test.t1' doesn't exist
handler t1 close;
handler t2 close;
drop table t2;
......@@ -535,3 +535,43 @@ handler t1_alias READ a next where inexistent > 0;
ERROR 42S22: Unknown column 'inexistent' in 'field list'
handler t1_alias close;
drop table t1;
drop table if exists t1,t2;
create table t1 (c1 int);
create table t2 (c1 int);
insert into t1 values (1);
insert into t2 values (2);
connection: default
handler t1 open;
handler t1 read first;
c1
1
connection: flush
flush tables;;
connection: default
handler t2 open;
handler t2 read first;
c1
2
handler t1 read next;
c1
1
handler t1 close;
handler t2 close;
drop table t1,t2;
drop table if exists t1,t2;
create table t1 (c1 int);
connection: default
handler t1 open;
handler t1 read first;
c1
connection: flush
rename table t1 to t2;;
connection: default
handler t2 open;
handler t2 read first;
c1
handler t1 read next;
ERROR 42S02: Table 'test.t1' doesn't exist
handler t1 close;
handler t2 close;
drop table t2;
......@@ -270,6 +270,10 @@ use mysql;
lock tables general_log read local, help_category read local;
ERROR HY000: You can't use locks with log tables.
unlock tables;
drop table if exists mysql.renamed_general_log;
drop table if exists mysql.renamed_slow_log;
drop table if exists mysql.general_log_new;
drop table if exists mysql.slow_log_new;
use mysql;
RENAME TABLE general_log TO renamed_general_log;
ERROR HY000: Cannot rename 'general_log'. When logging enabled, rename to/from log table must rename two tables: the log table to an archive table and another table back to 'general_log'
......
......@@ -142,7 +142,10 @@ declare c cursor for insert into test.t1 values ("foo", 42);
open c;
close c;
end|
ERROR 42000: Cursor statement must be a SELECT
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'insert into test.t1 values ("foo", 42);
open c;
close c;
end' at line 3
create procedure p()
begin
declare x int;
......@@ -1491,3 +1494,19 @@ ALTER DATABASE `#mysql50#upgrade-me` UPGRADE DATA DIRECTORY NAME;
RETURN 0;
END//
ERROR HY000: Can't drop or alter a DATABASE from within another stored routine
DROP PROCEDURE IF EXISTS p1;
CREATE PROCEDURE p1()
BEGIN
DECLARE c char(100);
DECLARE cur1 CURSOR FOR SHOW TABLES;
OPEN cur1;
FETCH cur1 INTO c;
select c;
CLOSE cur1;
END|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SHOW TABLES;
OPEN cur1;
FETCH cur1 INTO c;
select c;
CLOSE cur1;
END' at line 4
......@@ -953,7 +953,7 @@ BEGIN
DECLARE col1, col2, col3, col4, col6 CHAR(255);
DECLARE default_val VARCHAR(65532);
DECLARE done INT DEFAULT 0;
DECLARE cur1 CURSOR FOR SHOW COLUMNS FROM bug23037;
DECLARE cur1 CURSOR FOR SELECT COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, COLUMN_KEY, COLUMN_DEFAULT, EXTRA FROM INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='bug23037';
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
OPEN cur1;
FETCH cur1 INTO col1, col2, col3, col4, default_val, col6;
......
......@@ -295,6 +295,13 @@ unlock tables;
# Bug #21785 Server crashes after rename of the log table
#
--disable_warnings
drop table if exists mysql.renamed_general_log;
drop table if exists mysql.renamed_slow_log;
drop table if exists mysql.general_log_new;
drop table if exists mysql.slow_log_new;
--enable_warnings
use mysql;
# Should result in error
--error ER_CANT_RENAME_LOG_TABLE
......@@ -358,6 +365,55 @@ flush logs;
drop table renamed_general_log, renamed_slow_log;
use test;
#
# Bug#27858 (Failing to log to a log table doesn't log anything to error log)
#
# This test works as expected, it's a negative test.
# The message "[ERROR] Failed to write to mysql.general_log"
# is printed to master.err when writing to the table mysql.general_log
# failed.
# However, this message is picked up by mysql-test-run.pl,
# and reported as a test failure, which is a false negative.
# There is no current way to *selectively* filter out these expected error conditions
# (see mysql-test/lib/mtr_report.pl, mtr_report_stats()).
# Instead of filtering all occurences of "Failed to write to
# mysql.general_log", which could hide bugs when the error is not expected,
# this test case is commented instead.
# TODO: improve filtering of expected errors in master.err in
# mysql-test-run.pl (based on the test name ?), and uncomment this test.
# --disable_warnings
# drop table if exists mysql.bad_general_log;
# drop table if exists mysql.bad_slow_log;
# drop table if exists mysql.general_log_hide;
# drop table if exists mysql.slow_log_hide;
# --enable_warnings
#
# create table mysql.bad_general_log (a int) engine= CSV;
# create table mysql.bad_slow_log (a int) engine= CSV;
#
# # Rename does not perform checks on the table structure,
# # exploiting this to force a failure to log
# rename table mysql.general_log to mysql.general_log_hide, mysql.bad_general_log TO mysql.general_log;
# rename table mysql.slow_log to mysql.slow_log_hide, mysql.bad_slow_log TO mysql.slow_log;
#
# # The following message should be printed in master.log:
# # [ERROR] Failed to write to mysql.general_log
# # TODO: See how verifying this could be automated
#
# flush tables;
# select "logging this should fail";
#
# # Restore the log tables
#
# rename table mysql.general_log to mysql.bad_general_log, mysql.general_log_hide TO mysql.general_log;
# rename table mysql.slow_log to mysql.bad_slow_log, mysql.slow_log_hide TO mysql.slow_log;
#
# flush tables;
#
# drop table mysql.bad_general_log;
# drop table mysql.bad_slow_log;
#
# Bug #21966 Strange warnings on repair of the log tables
#
......
......@@ -196,7 +196,7 @@ select f(10)|
drop function f|
--error 1322
--error ER_PARSE_ERROR
create procedure p()
begin
declare c cursor for insert into test.t1 values ("foo", 42);
......@@ -2178,6 +2178,27 @@ END//
delimiter ;//
#
# Bug#29223 declare cursor c for SHOW .....
#
--disable_warnings
DROP PROCEDURE IF EXISTS p1;
--enable_warnings
--delimiter |
--error ER_PARSE_ERROR
CREATE PROCEDURE p1()
BEGIN
DECLARE c char(100);
DECLARE cur1 CURSOR FOR SHOW TABLES;
OPEN cur1;
FETCH cur1 INTO c;
select c;
CLOSE cur1;
END|
--delimiter ;
#
# BUG#NNNN: New bug synopsis
#
......
......@@ -387,10 +387,15 @@ bool Log_to_csv_event_handler::
if (table->field[1]->store(user_host, user_host_len, client_cs) ||
table->field[2]->store((longlong) thread_id, TRUE) ||
table->field[3]->store((longlong) server_id, TRUE) ||
table->field[4]->store(command_type, command_type_len, client_cs) ||
table->field[5]->store(sql_text, sql_text_len, client_cs))
table->field[4]->store(command_type, command_type_len, client_cs))
goto err;
/*
A positive return value in store() means truncation.
Still logging a message in the log in this case.
*/
if (table->field[5]->store(sql_text, sql_text_len, client_cs) < 0)
goto err;
/* mark all fields as not null */
table->field[1]->set_notnull();
......@@ -407,19 +412,14 @@ bool Log_to_csv_event_handler::
/* log table entries are not replicated */
if (table->file->ha_write_row(table->record[0]))
{
struct tm start;
localtime_r(&event_time, &start);
sql_print_error("%02d%02d%02d %2d:%02d:%02d - Failed to write to mysql.general_log",
start.tm_year % 100, start.tm_mon + 1,
start.tm_mday, start.tm_hour,
start.tm_min, start.tm_sec);
}
goto err;
result= FALSE;
err:
if (result)
sql_print_error("Failed to write to mysql.general_log");
if (need_rnd_end)
{
table->file->ha_rnd_end();
......@@ -595,25 +595,24 @@ bool Log_to_csv_event_handler::
goto err;
table->field[9]->set_notnull();
/* sql_text */
if (table->field[10]->store(sql_text,sql_text_len, client_cs))
/*
Column sql_text.
A positive return value in store() means truncation.
Still logging a message in the log in this case.
*/
if (table->field[10]->store(sql_text, sql_text_len, client_cs) < 0)
goto err;
/* log table entries are not replicated */
if (table->file->ha_write_row(table->record[0]))
{
struct tm start;
localtime_r(&current_time, &start);
sql_print_error("%02d%02d%02d %2d:%02d:%02d - Failed to write to mysql.slow_log",
start.tm_year % 100, start.tm_mon + 1,
start.tm_mday, start.tm_hour,
start.tm_min, start.tm_sec);
}
goto err;
result= FALSE;
err:
if (result)
sql_print_error("Failed to write to mysql.slow_log");
if (need_rnd_end)
{
table->file->ha_rnd_end();
......
......@@ -123,7 +123,7 @@ my_bool my_net_init(NET *net, Vio* vio)
MYF(MY_WME))))
DBUG_RETURN(1);
net->buff_end=net->buff+net->max_packet;
net->no_send_ok= net->no_send_eof= net->no_send_error= 0;
net->no_send_ok= net->no_send_error= 0;
net->error=0; net->return_errno=0; net->return_status=0;
net->pkt_nr=net->compress_pkt_nr=0;
net->write_pos=net->read_pos = net->buff;
......
......@@ -346,7 +346,7 @@ send_eof(THD *thd)
{
NET *net= &thd->net;
DBUG_ENTER("send_eof");
if (net->vio != 0 && !net->no_send_eof)
if (net->vio != 0)
{
write_eof_packet(thd, net);
VOID(net_flush(net));
......
......@@ -2466,7 +2466,13 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
DBUG_RETURN(0);
}
/* close handler tables which are marked for flush */
/*
In order for the back off and re-start process to work properly,
handler tables having old versions (due to FLUSH TABLES or pending
name-lock) MUST be closed. This is specially important if a name-lock
is pending for any table of the handler_tables list, otherwise a
deadlock may occur.
*/
if (thd->handler_tables)
mysql_ha_flush(thd, (TABLE_LIST*) NULL, MYSQL_HA_REOPEN_ON_USAGE, TRUE);
......@@ -2533,6 +2539,10 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
table->db_stat == 0 signals wait_for_locked_table_names
that the tables in question are not used any more. See
table_is_used call for details.
Notice that HANDLER tables were already taken care of by
the earlier call to mysql_ha_flush() in this same critical
section.
*/
close_old_data_files(thd,thd->open_tables,0,0);
/*
......
......@@ -698,6 +698,7 @@ void THD::cleanup(void)
pthread_mutex_lock(&LOCK_user_locks);
item_user_lock_release(ull);
pthread_mutex_unlock(&LOCK_user_locks);
ull= NULL;
}
cleanup_done=1;
......@@ -1422,7 +1423,14 @@ bool select_to_file::send_eof()
if (my_close(file,MYF(MY_WME)))
error= 1;
if (!error)
{
/*
In order to remember the value of affected rows for ROW_COUNT()
function, SELECT INTO has to have an own SQLCOM.
TODO: split from SQLCOM_SELECT
*/
::send_ok(thd,row_count);
}
file= -1;
return error;
}
......@@ -2337,6 +2345,11 @@ bool select_dumpvar::send_eof()
if (! row_count)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_SP_FETCH_NO_DATA, ER(ER_SP_FETCH_NO_DATA));
/*
In order to remember the value of affected rows for ROW_COUNT()
function, SELECT INTO has to have an own SQLCOM.
TODO: split from SQLCOM_SELECT
*/
::send_ok(thd,row_count);
return 0;
}
......
......@@ -142,7 +142,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
{
free_underlaid_joins(thd, select_lex);
thd->row_count_func= 0;
send_ok(thd); // No matching records
send_ok(thd, (ha_rows) thd->row_count_func); // No matching records
DBUG_RETURN(0);
}
#endif
......@@ -159,7 +159,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
delete select;
free_underlaid_joins(thd, select_lex);
thd->row_count_func= 0;
send_ok(thd,0L);
send_ok(thd, (ha_rows) thd->row_count_func);
/*
We don't need to call reset_auto_increment in this case, because
mysql_truncate always gives a NULL conds argument, hence we never
......@@ -386,7 +386,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
if (error < 0 || (thd->lex->ignore && !thd->is_fatal_error))
{
thd->row_count_func= deleted;
send_ok(thd,deleted);
send_ok(thd, (ha_rows) thd->row_count_func);
DBUG_PRINT("info",("%ld records deleted",(long) deleted));
}
DBUG_RETURN(error >= 0 || thd->net.report_error);
......@@ -889,7 +889,7 @@ bool multi_delete::send_eof()
if (!local_error)
{
thd->row_count_func= deleted;
::send_ok(thd, deleted);
::send_ok(thd, (ha_rows) thd->row_count_func);
}
return 0;
}
......
......@@ -65,11 +65,6 @@
static enum enum_ha_read_modes rkey_to_rnext[]=
{ RNEXT_SAME, RNEXT, RPREV, RNEXT, RPREV, RNEXT, RPREV, RPREV };
#define HANDLER_TABLES_HACK(thd) { \
TABLE *tmp=thd->open_tables; \
thd->open_tables=thd->handler_tables; \
thd->handler_tables=tmp; }
static int mysql_ha_flush_table(THD *thd, TABLE **table_ptr, uint mode_flags);
......@@ -187,6 +182,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen)
char *db, *name, *alias;
uint dblen, namelen, aliaslen, counter;
int error;
TABLE *backup_open_tables;
DBUG_ENTER("mysql_ha_open");
DBUG_PRINT("enter",("'%s'.'%s' as '%s' reopen: %d",
tables->db, tables->table_name, tables->alias,
......@@ -215,17 +211,38 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen)
}
}
/*
Save and reset the open_tables list so that open_tables() won't
be able to access (or know about) the previous list. And on return
from open_tables(), thd->open_tables will contain only the opened
table.
The thd->handler_tables list is kept as-is to avoid deadlocks if
open_table(), called by open_tables(), needs to back-off because
of a pending name-lock on the table being opened.
See open_table() back-off comments for more details.
*/
backup_open_tables= thd->open_tables;
thd->open_tables= NULL;
/*
open_tables() will set 'tables->table' if successful.
It must be NULL for a real open when calling open_tables().
*/
DBUG_ASSERT(! tables->table);
HANDLER_TABLES_HACK(thd);
/* for now HANDLER can be used only for real TABLES */
tables->required_type= FRMTYPE_TABLE;
error= open_tables(thd, &tables, &counter, 0);
HANDLER_TABLES_HACK(thd);
/* restore the state and merge the opened table into handler_tables list */
if (thd->open_tables)
{
thd->open_tables->next= thd->handler_tables;
thd->handler_tables= thd->open_tables;
}
thd->open_tables= backup_open_tables;
if (error)
goto err;
......@@ -351,7 +368,7 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables,
ha_rows select_limit_cnt, ha_rows offset_limit_cnt)
{
TABLE_LIST *hash_tables;
TABLE *table;
TABLE *table, *backup_open_tables;
MYSQL_LOCK *lock;
List<Item> list;
Protocol *protocol= thd->protocol;
......@@ -361,7 +378,7 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables,
uint num_rows;
uchar *key;
uint key_len;
bool not_used;
bool need_reopen;
DBUG_ENTER("mysql_ha_read");
DBUG_PRINT("enter",("'%s'.'%s' as '%s'",
tables->db, tables->table_name, tables->alias));
......@@ -375,6 +392,7 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables,
List_iterator<Item> it(list);
it++;
retry:
if ((hash_tables= (TABLE_LIST*) hash_search(&thd->handler_tables_hash,
(uchar*) tables->alias,
strlen(tables->alias) + 1)))
......@@ -428,9 +446,34 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables,
}
tables->table=table;
HANDLER_TABLES_HACK(thd);
lock= mysql_lock_tables(thd, &tables->table, 1, 0, &not_used);
HANDLER_TABLES_HACK(thd);
/* save open_tables state */
backup_open_tables= thd->open_tables;
/*
mysql_lock_tables() needs thd->open_tables to be set correctly to
be able to handle aborts properly. When the abort happens, it's
safe to not protect thd->handler_tables because it won't close any
tables.
*/
thd->open_tables= thd->handler_tables;
lock= mysql_lock_tables(thd, &tables->table, 1,
MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN, &need_reopen);
/* restore previous context */
thd->open_tables= backup_open_tables;
if (need_reopen)
{
mysql_ha_close_table(thd, tables);
hash_tables->table= NULL;
/*
The lock might have been aborted, we need to manually reset
thd->some_tables_deleted because handler's tables are closed
in a non-standard way. Otherwise we might loop indefinitely.
*/
thd->some_tables_deleted= 0;
goto retry;
}
if (!lock)
goto err0; // mysql_lock_tables() printed error message already
......
......@@ -2540,25 +2540,13 @@ sp_decl:
sp_cursor_stmt:
{
Lex->sphead->reset_lex(YYTHD);
/*
We use statement here just be able to get a better
error message. Using 'select' works too, but will then
result in a generic "syntax error" if a non-select
statement is given.
*/
}
statement
select
{
LEX *lex= Lex;
if (lex->sql_command != SQLCOM_SELECT &&
!(sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND))
{
my_message(ER_SP_BAD_CURSOR_QUERY, ER(ER_SP_BAD_CURSOR_QUERY),
MYF(0));
MYSQL_YYABORT;
}
DBUG_ASSERT(lex->sql_command == SQLCOM_SELECT);
if (lex->result)
{
my_message(ER_SP_BAD_CURSOR_SELECT, ER(ER_SP_BAD_CURSOR_SELECT),
......
......@@ -16827,7 +16827,7 @@ static void bug20023_change_user(MYSQL *con)
opt_db ? opt_db : "test"));
}
static void bug20023_query_int_variable(MYSQL *con,
static bool query_int_variable(MYSQL *con,
const char *var_name,
int *var_value)
{
......@@ -16836,16 +16836,25 @@ static void bug20023_query_int_variable(MYSQL *con,
char query_buffer[MAX_TEST_QUERY_LENGTH];
bool is_null;
my_snprintf(query_buffer,
sizeof (query_buffer),
"SELECT @@%s",
"SELECT %s",
(const char *) var_name);
DIE_IF(mysql_query(con, query_buffer));
DIE_UNLESS(rs= mysql_store_result(con));
DIE_UNLESS(row= mysql_fetch_row(rs));
is_null= row[0] == NULL;
if (!is_null)
*var_value= atoi(row[0]);
mysql_free_result(rs);
return is_null;
}
static void test_bug20023()
......@@ -16879,12 +16888,12 @@ static void test_bug20023()
Remember original SQL_BIG_SELECTS, MAX_JOIN_SIZE values.
***********************************************************************/
bug20023_query_int_variable(&con,
"session.sql_big_selects",
query_int_variable(&con,
"@@session.sql_big_selects",
&sql_big_selects_orig);
bug20023_query_int_variable(&con,
"global.max_join_size",
query_int_variable(&con,
"@@global.max_join_size",
&max_join_size_orig);
/***********************************************************************
......@@ -16897,8 +16906,8 @@ static void test_bug20023()
/* Query SQL_BIG_SELECTS. */
bug20023_query_int_variable(&con,
"session.sql_big_selects",
query_int_variable(&con,
"@@session.sql_big_selects",
&sql_big_selects_2);
/* Check that SQL_BIG_SELECTS is reset properly. */
......@@ -16921,8 +16930,8 @@ static void test_bug20023()
/* Query SQL_BIG_SELECTS. */
bug20023_query_int_variable(&con,
"session.sql_big_selects",
query_int_variable(&con,
"@@session.sql_big_selects",
&sql_big_selects_3);
/* Check that SQL_BIG_SELECTS is 0. */
......@@ -16945,8 +16954,8 @@ static void test_bug20023()
/* Query SQL_BIG_SELECTS. */
bug20023_query_int_variable(&con,
"session.sql_big_selects",
query_int_variable(&con,
"@@session.sql_big_selects",
&sql_big_selects_4);
/* Check that SQL_BIG_SELECTS is 1. */
......@@ -16974,8 +16983,8 @@ static void test_bug20023()
/* Query SQL_BIG_SELECTS. */
bug20023_query_int_variable(&con,
"session.sql_big_selects",
query_int_variable(&con,
"@@session.sql_big_selects",
&sql_big_selects_5);
/* Check that SQL_BIG_SELECTS is 1. */
......@@ -16989,6 +16998,98 @@ static void test_bug20023()
mysql_close(&con);
}
static void bug31418_impl()
{
MYSQL con;
bool is_null;
int rc;
/* Create a new connection. */
DIE_UNLESS(mysql_init(&con));
DIE_UNLESS(mysql_real_connect(&con,
opt_host,
opt_user,
opt_password,
opt_db ? opt_db : "test",
opt_port,
opt_unix_socket,
CLIENT_FOUND_ROWS));
/***********************************************************************
Check that lock is free:
- IS_FREE_LOCK() should return 1;
- IS_USED_LOCK() should return NULL;
***********************************************************************/
is_null= query_int_variable(&con,
"IS_FREE_LOCK('bug31418')",
&rc);
DIE_UNLESS(!is_null && rc);
is_null= query_int_variable(&con,
"IS_USED_LOCK('bug31418')",
&rc);
DIE_UNLESS(is_null);
/***********************************************************************
Acquire lock and check the lock status (the lock must be in use):
- IS_FREE_LOCK() should return 0;
- IS_USED_LOCK() should return non-zero thread id;
***********************************************************************/
query_int_variable(&con, "GET_LOCK('bug31418', 1)", &rc);
DIE_UNLESS(rc);
is_null= query_int_variable(&con,
"IS_FREE_LOCK('bug31418')",
&rc);
DIE_UNLESS(!is_null && !rc);
is_null= query_int_variable(&con,
"IS_USED_LOCK('bug31418')",
&rc);
DIE_UNLESS(!is_null && rc);
/***********************************************************************
Issue COM_CHANGE_USER command and check the lock status
(the lock must be free):
- IS_FREE_LOCK() should return 1;
- IS_USED_LOCK() should return NULL;
**********************************************************************/
bug20023_change_user(&con);
is_null= query_int_variable(&con,
"IS_FREE_LOCK('bug31418')",
&rc);
DIE_UNLESS(!is_null && rc);
is_null= query_int_variable(&con,
"IS_USED_LOCK('bug31418')",
&rc);
DIE_UNLESS(is_null);
/***********************************************************************
That's it. Cleanup.
***********************************************************************/
mysql_close(&con);
}
static void test_bug31418()
{
/* Run test case for BUG#31418 for three different connections. */
bug31418_impl();
bug31418_impl();
bug31418_impl();
}
/*
Read and parse arguments and MySQL options from my.cnf
......@@ -17286,6 +17387,7 @@ static struct my_tests_st my_tests[]= {
{ "test_change_user", test_change_user },
{ "test_bug30472", test_bug30472 },
{ "test_bug20023", test_bug20023 },
{ "test_bug31418", test_bug31418 },
{ 0, 0 }
};
......
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