Merge lambda.hsd1.co.comcast.net.:/home/malff/TREE/mysql-5.1-base

into  lambda.hsd1.co.comcast.net.:/home/malff/TREE/mysql-5.1-rt-merge
This commit is contained in:
malff@lambda.hsd1.co.comcast.net. 2007-11-21 18:42:15 -07:00
commit 1f4cff2863
26 changed files with 579 additions and 215 deletions

View file

@ -598,3 +598,97 @@ handler a2 read a last;
handler a2 read a prev;
handler a2 close;
drop table t1;
#
# Bug#31397 Inconsistent drop table behavior of handler tables.
#
--disable_warnings
drop table if exists t1,t2;
--enable_warnings
create table t1 (a int);
handler t1 open as t1_alias;
drop table t1;
create table t1 (a int);
handler t1 open as t1_alias;
flush tables;
drop table t1;
create table t1 (a int);
handler t1 open as t1_alias;
handler t1_alias close;
drop table t1;
create table t1 (a int);
handler t1 open as t1_alias;
handler t1_alias read first;
drop table t1;
--error ER_UNKNOWN_TABLE
handler t1_alias read next;
# Test that temporary tables associated with handlers are properly dropped.
create table t1 (a int);
create temporary table t2 (a int, key(a));
handler t1 open as a1;
handler t2 open as a2;
handler a2 read a first;
drop table t1, t2;
--error ER_UNKNOWN_TABLE
handler a2 read a next;
--error ER_UNKNOWN_TABLE
handler a1 close;
# Alter table drop handlers
create table t1 (a int, key(a));
create table t2 like t1;
handler t1 open as a1;
handler t2 open as a2;
handler a1 read a first;
handler a2 read a first;
alter table t1 add b int;
--error ER_UNKNOWN_TABLE
handler a1 close;
handler a2 close;
drop table t1, t2;
# Rename table drop handlers
create table t1 (a int, key(a));
handler t1 open as a1;
handler a1 read a first;
rename table t1 to t2;
--error ER_UNKNOWN_TABLE
handler a1 read a first;
drop table t2;
# Optimize table drop handlers
create table t1 (a int, key(a));
create table t2 like t1;
handler t1 open as a1;
handler t2 open as a2;
handler a1 read a first;
handler a2 read a first;
optimize table t1;
--error ER_UNKNOWN_TABLE
handler a1 close;
handler a2 close;
drop table t1, t2;
# Flush tables causes handlers reopen
create table t1 (a int, b char(1), key a(a), key b(a,b));
insert into t1 values (0,"a"),(1,"b"),(2,"c"),(3,"d"),(4,"e"),
(5,"f"),(6,"g"),(7,"h"),(8,"i"),(9,"j");
handler t1 open;
handler t1 read a first;
handler t1 read a next;
flush tables;
handler t1 read a next;
handler t1 read a next;
flush tables with read lock;
handler t1 read a next;
unlock tables;
drop table t1;
--error ER_UNKNOWN_TABLE
handler t1 read a next;

View file

@ -3,6 +3,10 @@ drop database if exists mysqltest_db1;
drop database if exists mysqltest_db2;
create database events_test;
use events_test;
select * from information_schema.global_variables where variable_name like 'event_scheduler';
VARIABLE_NAME VARIABLE_VALUE
EVENT_SCHEDULER ON
SET GLOBAL event_scheduler = 'OFF';
CREATE EVENT lower_case ON SCHEDULE EVERY 1 MINUTE DO SELECT 1;
CREATE EVENT Lower_case ON SCHEDULE EVERY 2 MINUTE DO SELECT 2;
ERROR HY000: Event 'Lower_case' already exists

View file

@ -637,3 +637,94 @@ a b
8 i
handler a2 close;
drop table t1;
drop table if exists t1,t2;
create table t1 (a int);
handler t1 open as t1_alias;
drop table t1;
create table t1 (a int);
handler t1 open as t1_alias;
flush tables;
drop table t1;
create table t1 (a int);
handler t1 open as t1_alias;
handler t1_alias close;
drop table t1;
create table t1 (a int);
handler t1 open as t1_alias;
handler t1_alias read first;
a
drop table t1;
handler t1_alias read next;
ERROR 42S02: Unknown table 't1_alias' in HANDLER
create table t1 (a int);
create temporary table t2 (a int, key(a));
handler t1 open as a1;
handler t2 open as a2;
handler a2 read a first;
a
drop table t1, t2;
handler a2 read a next;
ERROR 42S02: Unknown table 'a2' in HANDLER
handler a1 close;
ERROR 42S02: Unknown table 'a1' in HANDLER
create table t1 (a int, key(a));
create table t2 like t1;
handler t1 open as a1;
handler t2 open as a2;
handler a1 read a first;
a
handler a2 read a first;
a
alter table t1 add b int;
handler a1 close;
ERROR 42S02: Unknown table 'a1' in HANDLER
handler a2 close;
drop table t1, t2;
create table t1 (a int, key(a));
handler t1 open as a1;
handler a1 read a first;
a
rename table t1 to t2;
handler a1 read a first;
ERROR 42S02: Unknown table 'a1' in HANDLER
drop table t2;
create table t1 (a int, key(a));
create table t2 like t1;
handler t1 open as a1;
handler t2 open as a2;
handler a1 read a first;
a
handler a2 read a first;
a
optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
handler a1 close;
ERROR 42S02: Unknown table 'a1' in HANDLER
handler a2 close;
drop table t1, t2;
create table t1 (a int, b char(1), key a(a), key b(a,b));
insert into t1 values (0,"a"),(1,"b"),(2,"c"),(3,"d"),(4,"e"),
(5,"f"),(6,"g"),(7,"h"),(8,"i"),(9,"j");
handler t1 open;
handler t1 read a first;
a b
0 a
handler t1 read a next;
a b
1 b
flush tables;
handler t1 read a next;
a b
0 a
handler t1 read a next;
a b
1 b
flush tables with read lock;
handler t1 read a next;
a b
0 a
unlock tables;
drop table t1;
handler t1 read a next;
ERROR 42S02: Unknown table 't1' in HANDLER

View file

@ -637,3 +637,94 @@ a b
8 i
handler a2 close;
drop table t1;
drop table if exists t1,t2;
create table t1 (a int);
handler t1 open as t1_alias;
drop table t1;
create table t1 (a int);
handler t1 open as t1_alias;
flush tables;
drop table t1;
create table t1 (a int);
handler t1 open as t1_alias;
handler t1_alias close;
drop table t1;
create table t1 (a int);
handler t1 open as t1_alias;
handler t1_alias read first;
a
drop table t1;
handler t1_alias read next;
ERROR 42S02: Unknown table 't1_alias' in HANDLER
create table t1 (a int);
create temporary table t2 (a int, key(a));
handler t1 open as a1;
handler t2 open as a2;
handler a2 read a first;
a
drop table t1, t2;
handler a2 read a next;
ERROR 42S02: Unknown table 'a2' in HANDLER
handler a1 close;
ERROR 42S02: Unknown table 'a1' in HANDLER
create table t1 (a int, key(a));
create table t2 like t1;
handler t1 open as a1;
handler t2 open as a2;
handler a1 read a first;
a
handler a2 read a first;
a
alter table t1 add b int;
handler a1 close;
ERROR 42S02: Unknown table 'a1' in HANDLER
handler a2 close;
drop table t1, t2;
create table t1 (a int, key(a));
handler t1 open as a1;
handler a1 read a first;
a
rename table t1 to t2;
handler a1 read a first;
ERROR 42S02: Unknown table 'a1' in HANDLER
drop table t2;
create table t1 (a int, key(a));
create table t2 like t1;
handler t1 open as a1;
handler t2 open as a2;
handler a1 read a first;
a
handler a2 read a first;
a
optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize status Table is already up to date
handler a1 close;
ERROR 42S02: Unknown table 'a1' in HANDLER
handler a2 close;
drop table t1, t2;
create table t1 (a int, b char(1), key a(a), key b(a,b));
insert into t1 values (0,"a"),(1,"b"),(2,"c"),(3,"d"),(4,"e"),
(5,"f"),(6,"g"),(7,"h"),(8,"i"),(9,"j");
handler t1 open;
handler t1 read a first;
a b
0 a
handler t1 read a next;
a b
1 b
flush tables;
handler t1 read a next;
a b
0 a
handler t1 read a next;
a b
1 b
flush tables with read lock;
handler t1 read a next;
a b
0 a
unlock tables;
drop table t1;
handler t1 read a next;
ERROR 42S02: Unknown table 't1' in HANDLER

View file

@ -125,3 +125,14 @@ drop function bug27563;
drop procedure proc27563;
PREPARE stmt FROM 'EXPLAIN SELECT * FROM t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38,t39,t40 WHERE a1=a2 AND a2=a3 AND a3=a4 AND a4=a5 AND a5=a6 AND a6=a7 AND a7=a8 AND a8=a9 AND a9=a10 AND a10=a11 AND a11=a12 AND a12=a13 AND a13=a14 AND a14=a15 AND a15=a16 AND a16=a17 AND a17=a18 AND a18=a19 AND a19=a20 AND a20=a21 AND a21=a22 AND a22=a23 AND a23=a24 AND a24=a25 AND a25=a26 AND a26=a27 AND a27=a28 AND a28=a29 AND a29=a30 AND a30=a31 AND a31=a32 AND a32=a33 AND a33=a34 AND a34=a35 AND a35=a36 AND a36=a37 AND a37=a38 AND a38=a39 AND a39=a40 ';
EXECUTE stmt;
#
# Bug#19723: kill of active connection yields different error code
# depending on platform.
#
# Connection: con2.
KILL CONNECTION_ID();
# CR_SERVER_LOST, CR_SERVER_GONE_ERROR, depending on the timing
# of close of the connection socket
SELECT 1;
Got one of the listed errors

View file

@ -4,3 +4,6 @@ select 1+1;
select 1+2;
1+2
3
SHOW GLOBAL VARIABLES LIKE 'thread_handling';
Variable_name Value
thread_handling no-threads

View file

@ -0,0 +1 @@
--event-scheduler

View file

@ -9,6 +9,21 @@ drop database if exists mysqltest_db2;
create database events_test;
use events_test;
#
# START: Bug #31332 --event-scheduler option misbehaving
#
# NOTE!! this test must come first! It's testing that the --event-scheduler
# option with no argument in events_bugs-master.opt turns the scheduler on.
select * from information_schema.global_variables where variable_name like 'event_scheduler';
SET GLOBAL event_scheduler = 'OFF';
#
# END: Bug #31332
#
#
# START - 16415: Events: event names are case sensitive
#

View file

@ -1143,6 +1143,7 @@ END$$
DELIMITER ;$$
let $wait_timeout= 300;
let $wait_condition=select count(*) = 0 from information_schema.events where event_name='event_status';
--source include/wait_condition.inc

View file

@ -304,3 +304,21 @@ while ($i)
dec $i ;
}
--enable_query_log
###########################################################################
--echo #
--echo # Bug#19723: kill of active connection yields different error code
--echo # depending on platform.
--echo #
--echo
--echo # Connection: con2.
--connection con2
KILL CONNECTION_ID();
--echo # CR_SERVER_LOST, CR_SERVER_GONE_ERROR, depending on the timing
--echo # of close of the connection socket
--error 2013, 2006
SELECT 1;

View file

@ -3,3 +3,4 @@
#
select 1+1;
select 1+2;
SHOW GLOBAL VARIABLES LIKE 'thread_handling';

View file

@ -45,27 +45,9 @@ call bug4902_2()|
call bug4902_2()|
drop procedure bug4902_2|
# Disable until bug#17244 is fixed
--disable_parsing
#
# BUG#5278: Stored procedure packets out of order if SET PASSWORD.
# BUG#3583: query cache doesn't work for stored procedures
#
--disable_warnings
drop function if exists bug5278|
--enable_warnings
create function bug5278 () returns char
begin
SET PASSWORD FOR 'bob'@'%.loc.gov' = PASSWORD('newpass');
return 'okay';
end|
--error 1133
select bug5278()|
--error 1133
select bug5278()|
drop function bug5278|
--enable_parsing
--disable_warnings
drop table if exists t1|
@ -74,9 +56,6 @@ create table t1 (
id char(16) not null default '',
data int not null
)|
#
# BUG#3583: query cache doesn't work for stored procedures
#
--disable_warnings
drop procedure if exists bug3583|
--enable_warnings

View file

@ -146,7 +146,7 @@ bool
Events::set_opt_event_scheduler(char *argument)
{
if (argument == NULL)
opt_event_scheduler= Events::EVENTS_DISABLED;
opt_event_scheduler= Events::EVENTS_ON;
else
{
int type;

View file

@ -356,10 +356,35 @@ String *Item_func_concat::val_str(String *str)
}
else
{ // Two big const strings
if (tmp_value.alloc(max_length) ||
tmp_value.copy(*res) ||
tmp_value.append(*res2))
/*
NOTE: We should be prudent in the initial allocation unit -- the
size of the arguments is a function of data distribution, which
can be any. Instead of overcommitting at the first row, we grow
the allocated amount by the factor of 2. This ensures that no
more than 25% of memory will be overcommitted on average.
*/
uint concat_len= res->length() + res2->length();
if (tmp_value.alloced_length() < concat_len)
{
if (tmp_value.alloced_length() == 0)
{
if (tmp_value.alloc(concat_len))
goto null;
}
else
{
uint new_len = max(tmp_value.alloced_length() * 2, concat_len);
if (tmp_value.realloc(new_len))
goto null;
}
}
if (tmp_value.copy(*res) || tmp_value.append(*res2))
goto null;
res= &tmp_value;
use_as_buff=str;
}
@ -679,8 +704,33 @@ String *Item_func_concat_ws::val_str(String *str)
}
else
{ // Two big const strings
if (tmp_value.alloc(max_length) ||
tmp_value.copy(*res) ||
/*
NOTE: We should be prudent in the initial allocation unit -- the
size of the arguments is a function of data distribution, which can
be any. Instead of overcommitting at the first row, we grow the
allocated amount by the factor of 2. This ensures that no more than
25% of memory will be overcommitted on average.
*/
uint concat_len= res->length() + sep_str->length() + res2->length();
if (tmp_value.alloced_length() < concat_len)
{
if (tmp_value.alloced_length() == 0)
{
if (tmp_value.alloc(concat_len))
goto null;
}
else
{
uint new_len = max(tmp_value.alloced_length() * 2, concat_len);
if (tmp_value.realloc(new_len))
goto null;
}
}
if (tmp_value.copy(*res) ||
tmp_value.append(*sep_str) ||
tmp_value.append(*res2))
goto null;

View file

@ -1289,12 +1289,9 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen);
bool mysql_ha_close(THD *thd, TABLE_LIST *tables);
bool mysql_ha_read(THD *, TABLE_LIST *,enum enum_ha_read_modes,char *,
List<Item> *,enum ha_rkey_function,Item *,ha_rows,ha_rows);
int mysql_ha_flush(THD *thd, TABLE_LIST *tables, uint mode_flags,
bool is_locked);
/* mysql_ha_flush mode_flags bits */
#define MYSQL_HA_CLOSE_FINAL 0x00
#define MYSQL_HA_REOPEN_ON_USAGE 0x01
#define MYSQL_HA_FLUSH_ALL 0x02
void mysql_ha_flush(THD *thd);
void mysql_ha_rm_tables(THD *thd, TABLE_LIST *tables);
void mysql_ha_cleanup(THD *thd);
/* sql_base.cc */
#define TMP_TABLE_KEY_EXTRA 8

View file

@ -2596,7 +2596,12 @@ int my_message_sql(uint error, const char *str, myf MyFlags)
thd->is_slave_error= 1; // needed to catch query errors during replication
if (!thd->no_warnings_for_error)
{
thd->no_warnings_for_error= TRUE;
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error, str);
thd->no_warnings_for_error= FALSE;
}
/*
thd->lex->current_select == 0 if lex structure is not inited
(not query command (COM_QUERY))
@ -4599,8 +4604,13 @@ pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused)))
sock == unix_sock ? VIO_LOCALHOST: 0)) ||
my_net_init(&thd->net,vio_tmp))
{
if (vio_tmp)
vio_delete(vio_tmp);
/*
Only delete the temporary vio if we didn't already attach it to the
NET object. The destructor in THD will delete any initialized net
structure.
*/
if (vio_tmp && thd->net.vio != vio_tmp)
vio_delete(vio_tmp);
else
{
(void) shutdown(new_sock, SHUT_RDWR);
@ -7745,12 +7755,13 @@ mysqld_get_one_option(int optid,
break;
}
case OPT_ONE_THREAD:
global_system_variables.thread_handling= 2;
global_system_variables.thread_handling=
SCHEDULER_ONE_THREAD_PER_CONNECTION;
break;
case OPT_THREAD_HANDLING:
{
global_system_variables.thread_handling=
find_type_or_exit(argument, &thread_handling_typelib, opt->name);
find_type_or_exit(argument, &thread_handling_typelib, opt->name)-1;
break;
}
case OPT_FT_BOOLEAN_SYNTAX:

View file

@ -40,7 +40,7 @@ public:
enum scheduler_types
{
SCHEDULER_ONE_THREAD_PER_CONNECTION=1,
SCHEDULER_ONE_THREAD_PER_CONNECTION=0,
SCHEDULER_NO_THREADS,
SCHEDULER_POOL_OF_THREADS
};

View file

@ -465,14 +465,16 @@ check_routine_name(LEX_STRING *ident)
*/
void *
sp_head::operator new(size_t size)
sp_head::operator new(size_t size) throw()
{
DBUG_ENTER("sp_head::operator new");
MEM_ROOT own_root;
sp_head *sp;
init_alloc_root(&own_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC);
init_sql_alloc(&own_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC);
sp= (sp_head *) alloc_root(&own_root, size);
if (sp == NULL)
return NULL;
sp->main_mem_root= own_root;
DBUG_PRINT("info", ("mem_root 0x%lx", (ulong) &sp->mem_root));
DBUG_RETURN(sp);
@ -483,6 +485,10 @@ sp_head::operator delete(void *ptr, size_t size)
{
DBUG_ENTER("sp_head::operator delete");
MEM_ROOT own_root;
if (ptr == NULL)
DBUG_VOID_RETURN;
sp_head *sp= (sp_head *) ptr;
/* Make a copy of main_mem_root as free_root will free the sp */
@ -536,6 +542,9 @@ sp_head::init(LEX *lex)
lex->spcont= m_pcont= new sp_pcontext();
if (!lex->spcont)
DBUG_VOID_RETURN;
/*
Altough trg_table_fields list is used only in triggers we init for all
types of stored procedures to simplify reset_lex()/restore_lex() code.
@ -1069,7 +1078,7 @@ sp_head::execute(THD *thd)
DBUG_RETURN(TRUE);
/* init per-instruction memroot */
init_alloc_root(&execute_mem_root, MEM_ROOT_BLOCK_SIZE, 0);
init_sql_alloc(&execute_mem_root, MEM_ROOT_BLOCK_SIZE, 0);
DBUG_ASSERT(!(m_flags & IS_INVOKED));
m_flags|= IS_INVOKED;
@ -1961,16 +1970,29 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
}
// Reset lex during parsing, before we parse a sub statement.
void
/**
@brief Reset lex during parsing, before we parse a sub statement.
@param thd Thread handler.
@return Error state
@retval true An error occurred.
@retval false Success.
*/
bool
sp_head::reset_lex(THD *thd)
{
DBUG_ENTER("sp_head::reset_lex");
LEX *sublex;
LEX *oldlex= thd->lex;
sublex= new (thd->mem_root)st_lex_local;
if (sublex == 0)
DBUG_RETURN(TRUE);
thd->lex= sublex;
(void)m_lex.push_front(oldlex);
thd->lex= sublex= new st_lex;
/* Reset most stuff. */
lex_start(thd);
@ -1991,7 +2013,7 @@ sp_head::reset_lex(THD *thd)
sublex->interval_list.empty();
sublex->type= 0;
DBUG_VOID_RETURN;
DBUG_RETURN(FALSE);
}
// Restore lex during parsing, after we have parsed a sub statement.
@ -3856,7 +3878,7 @@ sp_add_to_query_tables(THD *thd, LEX *lex,
if (!(table= (TABLE_LIST *)thd->calloc(sizeof(TABLE_LIST))))
{
my_error(ER_OUTOFMEMORY, MYF(0), sizeof(TABLE_LIST));
thd->fatal_error();
return NULL;
}
table->db_length= strlen(db);

View file

@ -260,10 +260,10 @@ public:
Security_context m_security_ctx;
static void *
operator new(size_t size);
operator new(size_t size) throw ();
static void
operator delete(void *ptr, size_t size);
operator delete(void *ptr, size_t size) throw ();
sp_head();
@ -326,7 +326,7 @@ public:
}
// Resets lex in 'thd' and keeps a copy of the old one.
void
bool
reset_lex(THD *thd);
// Restores lex in 'thd' from our copy, but keeps some status from the

View file

@ -87,7 +87,6 @@ bool Prelock_error_handler::safely_trapped_errors()
@defgroup Data_Dictionary Data Dictionary
@{
*/
TABLE *unused_tables; /* Used by mysql_test */
HASH open_cache; /* Used by mysql_test */
static HASH table_def_cache;
@ -929,8 +928,8 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
thd->proc_info="Flushing tables";
close_old_data_files(thd,thd->open_tables,1,1);
mysql_ha_flush(thd, tables, MYSQL_HA_REOPEN_ON_USAGE | MYSQL_HA_FLUSH_ALL,
TRUE);
mysql_ha_flush(thd);
bool found=1;
/* Wait until all threads has closed all the tables we had locked */
DBUG_PRINT("info",
@ -2516,7 +2515,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
deadlock may occur.
*/
if (thd->handler_tables)
mysql_ha_flush(thd, (TABLE_LIST*) NULL, MYSQL_HA_REOPEN_ON_USAGE, TRUE);
mysql_ha_flush(thd);
/*
Actually try to find the table in the open_cache.
@ -3136,7 +3135,7 @@ bool wait_for_tables(THD *thd)
{
thd->some_tables_deleted=0;
close_old_data_files(thd,thd->open_tables,0,dropping_tables != 0);
mysql_ha_flush(thd, (TABLE_LIST*) NULL, MYSQL_HA_REOPEN_ON_USAGE, TRUE);
mysql_ha_flush(thd);
if (!table_is_used(thd->open_tables,1))
break;
(void) pthread_cond_wait(&COND_refresh,&LOCK_open);
@ -3554,7 +3553,7 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
temporary mem_root for new .frm parsing.
TODO: variables for size
*/
init_alloc_root(&new_frm_mem, 8024, 8024);
init_sql_alloc(&new_frm_mem, 8024, 8024);
thd->current_tablenr= 0;
restart:

View file

@ -678,9 +678,7 @@ void THD::cleanup(void)
lock=locked_tables; locked_tables=0;
close_thread_tables(this);
}
mysql_ha_flush(this, (TABLE_LIST*) 0,
MYSQL_HA_CLOSE_FINAL | MYSQL_HA_FLUSH_ALL, FALSE);
hash_free(&handler_tables_hash);
mysql_ha_cleanup(this);
delete_dynamic(&user_var_events);
hash_free(&user_vars);
close_temporary_tables(this);
@ -818,7 +816,20 @@ void THD::awake(THD::killed_state state_to_set)
if (!slave_thread)
thread_scheduler.post_kill_notification(this);
#ifdef SIGNAL_WITH_VIO_CLOSE
close_active_vio();
if (this != current_thd)
{
/*
In addition to a signal, let's close the socket of the thread that
is being killed. This is to make sure it does not block if the
signal is lost. This needs to be done only on platforms where
signals are not a reliable interruption mechanism.
If we're killing ourselves, we know that we're not blocked, so this
hack is not used.
*/
close_active_vio();
}
#endif
}
if (mysys_var)

View file

@ -65,9 +65,6 @@
static enum enum_ha_read_modes rkey_to_rnext[]=
{ RNEXT_SAME, RNEXT, RPREV, RNEXT, RPREV, RNEXT, RPREV, RPREV };
static int mysql_ha_flush_table(THD *thd, TABLE **table_ptr, uint mode_flags);
/*
Get hash key and hash key length.
@ -119,13 +116,15 @@ static void mysql_ha_hash_free(TABLE_LIST *tables)
@param thd Thread identifier.
@param tables A list of tables with the first entry to close.
@param is_locked If LOCK_open is locked.
@note Though this function takes a list of tables, only the first list entry
will be closed.
@note Broadcasts refresh if it closed the table.
@note Broadcasts refresh if it closed a table with old version.
*/
static void mysql_ha_close_table(THD *thd, TABLE_LIST *tables)
static void mysql_ha_close_table(THD *thd, TABLE_LIST *tables,
bool is_locked)
{
TABLE **table_ptr;
@ -143,13 +142,15 @@ static void mysql_ha_close_table(THD *thd, TABLE_LIST *tables)
if (*table_ptr)
{
(*table_ptr)->file->ha_index_or_rnd_end();
VOID(pthread_mutex_lock(&LOCK_open));
if (! is_locked)
VOID(pthread_mutex_lock(&LOCK_open));
if (close_thread_table(thd, table_ptr))
{
/* Tell threads waiting for refresh that something has happened */
broadcast_refresh();
}
VOID(pthread_mutex_unlock(&LOCK_open));
if (! is_locked)
VOID(pthread_mutex_unlock(&LOCK_open));
}
else if (tables->table)
{
@ -305,7 +306,7 @@ err:
if (hash_tables)
my_free((char*) hash_tables, MYF(0));
if (tables->table)
mysql_ha_close_table(thd, tables);
mysql_ha_close_table(thd, tables, FALSE);
DBUG_PRINT("exit",("ERROR"));
DBUG_RETURN(TRUE);
}
@ -339,7 +340,7 @@ bool mysql_ha_close(THD *thd, TABLE_LIST *tables)
(uchar*) tables->alias,
strlen(tables->alias) + 1)))
{
mysql_ha_close_table(thd, hash_tables);
mysql_ha_close_table(thd, hash_tables, FALSE);
hash_delete(&thd->handler_tables_hash, (uchar*) hash_tables);
}
else
@ -478,7 +479,7 @@ retry:
if (need_reopen)
{
mysql_ha_close_table(thd, tables);
mysql_ha_close_table(thd, tables, FALSE);
hash_tables->table= NULL;
/*
The lock might have been aborted, we need to manually reset
@ -669,163 +670,131 @@ err0:
}
/*
Flush (close) a list of HANDLER tables.
/**
Scan the handler tables hash for matching tables.
SYNOPSIS
mysql_ha_flush()
thd Thread identifier.
tables The list of tables to close. If NULL,
close all HANDLER tables [marked as flushed].
mode_flags MYSQL_HA_CLOSE_FINAL finally close the table.
MYSQL_HA_REOPEN_ON_USAGE mark for reopen.
MYSQL_HA_FLUSH_ALL flush all tables, not only
those marked for flush.
is_locked If LOCK_open is locked.
@param thd Thread identifier.
@param tables The list of tables to remove.
DESCRIPTION
The list of HANDLER tables may be NULL, in which case all HANDLER
tables are closed (if MYSQL_HA_FLUSH_ALL) is set.
If 'tables' is NULL and MYSQL_HA_FLUSH_ALL is not set,
all HANDLER tables marked for flush are closed.
Broadcasts refresh for every table closed.
NOTE
Since mysql_ha_flush() is called when the base table has to be closed,
we compare real table names, not aliases. Hence, database names matter.
RETURN
0 ok
@return Pointer to head of linked list (TABLE_LIST::next_local) of matching
TABLE_LIST elements from handler_tables_hash. Otherwise, NULL if no
table was matched.
*/
int mysql_ha_flush(THD *thd, TABLE_LIST *tables, uint mode_flags,
bool is_locked)
static TABLE_LIST *mysql_ha_find(THD *thd, TABLE_LIST *tables)
{
TABLE_LIST *tmp_tables;
TABLE **table_ptr;
bool did_lock= FALSE;
DBUG_ENTER("mysql_ha_flush");
DBUG_PRINT("enter", ("tables: 0x%lx mode_flags: 0x%02x",
(long) tables, mode_flags));
TABLE_LIST *hash_tables, *head= NULL, *first= tables;
DBUG_ENTER("mysql_ha_find");
if (tables)
/* search for all handlers with matching table names */
for (uint i= 0; i < thd->handler_tables_hash.records; i++)
{
/* Close all tables in the list. */
for (tmp_tables= tables ; tmp_tables; tmp_tables= tmp_tables->next_local)
hash_tables= (TABLE_LIST*) hash_element(&thd->handler_tables_hash, i);
for (tables= first; tables; tables= tables->next_local)
{
DBUG_PRINT("info-in-tables-list",("'%s'.'%s' as '%s'",
tmp_tables->db, tmp_tables->table_name,
tmp_tables->alias));
/* Close all currently open handler tables with the same base table. */
table_ptr= &(thd->handler_tables);
while (*table_ptr)
{
if ((!*tmp_tables->db ||
!my_strcasecmp(&my_charset_latin1, (*table_ptr)->s->db.str,
tmp_tables->db)) &&
! my_strcasecmp(&my_charset_latin1,
(*table_ptr)->s->table_name.str,
tmp_tables->table_name))
{
DBUG_PRINT("info",("*table_ptr '%s'.'%s' as '%s'",
(*table_ptr)->s->db.str,
(*table_ptr)->s->table_name.str,
(*table_ptr)->alias));
/* The first time it is required, lock for close_thread_table(). */
if (! did_lock && ! is_locked)
{
VOID(pthread_mutex_lock(&LOCK_open));
did_lock= TRUE;
}
mysql_ha_flush_table(thd, table_ptr, mode_flags);
continue;
}
table_ptr= &(*table_ptr)->next;
}
/* end of handler_tables list */
if ((! *tables->db ||
! my_strcasecmp(&my_charset_latin1, hash_tables->db, tables->db)) &&
! my_strcasecmp(&my_charset_latin1, hash_tables->table_name,
tables->table_name))
break;
}
/* end of flush tables list */
}
else
{
/* Close all currently open tables [which are marked for flush]. */
table_ptr= &(thd->handler_tables);
while (*table_ptr)
if (tables)
{
if ((mode_flags & MYSQL_HA_FLUSH_ALL) ||
(*table_ptr)->needs_reopen_or_name_lock())
{
/* The first time it is required, lock for close_thread_table(). */
if (! did_lock && ! is_locked)
{
VOID(pthread_mutex_lock(&LOCK_open));
did_lock= TRUE;
}
mysql_ha_flush_table(thd, table_ptr, mode_flags);
continue;
}
table_ptr= &(*table_ptr)->next;
hash_tables->next_local= head;
head= hash_tables;
}
}
/* Release the lock if it was taken by this function. */
if (did_lock)
VOID(pthread_mutex_unlock(&LOCK_open));
DBUG_RETURN(0);
DBUG_RETURN(head);
}
/*
Flush (close) a table.
SYNOPSIS
mysql_ha_flush_table()
thd Thread identifier.
table The table to close.
mode_flags MYSQL_HA_CLOSE_FINAL finally close the table.
MYSQL_HA_REOPEN_ON_USAGE mark for reopen.
/**
Remove matching tables from the HANDLER's hash table.
DESCRIPTION
Broadcasts refresh if it closed the table.
The caller must lock LOCK_open.
@param thd Thread identifier.
@param tables The list of tables to remove.
RETURN
0 ok
@note Broadcasts refresh if it closed a table with old version.
*/
static int mysql_ha_flush_table(THD *thd, TABLE **table_ptr, uint mode_flags)
void mysql_ha_rm_tables(THD *thd, TABLE_LIST *tables)
{
TABLE_LIST *hash_tables;
TABLE *table= *table_ptr;
DBUG_ENTER("mysql_ha_flush_table");
DBUG_PRINT("enter",("'%s'.'%s' as '%s' flags: 0x%02x",
table->s->db.str, table->s->table_name.str,
table->alias, mode_flags));
TABLE_LIST *hash_tables, *next;
DBUG_ENTER("mysql_ha_rm_tables");
if ((hash_tables= (TABLE_LIST*) hash_search(&thd->handler_tables_hash,
(uchar*) table->alias,
strlen(table->alias) + 1)))
safe_mutex_assert_not_owner(&LOCK_open);
DBUG_ASSERT(tables);
hash_tables= mysql_ha_find(thd, tables);
while (hash_tables)
{
if (! (mode_flags & MYSQL_HA_REOPEN_ON_USAGE))
{
/* This is a final close. Remove from hash. */
hash_delete(&thd->handler_tables_hash, (uchar*) hash_tables);
}
else
next= hash_tables->next_local;
if (hash_tables->table)
mysql_ha_close_table(thd, hash_tables, FALSE);
hash_delete(&thd->handler_tables_hash, (uchar*) hash_tables);
hash_tables= next;
}
DBUG_VOID_RETURN;
}
/**
Flush (close and mark for re-open) all tables that should be should
be reopen.
@param thd Thread identifier.
@note Broadcasts refresh if it closed a table with old version.
*/
void mysql_ha_flush(THD *thd)
{
TABLE_LIST *hash_tables;
DBUG_ENTER("mysql_ha_flush");
safe_mutex_assert_owner(&LOCK_open);
for (uint i= 0; i < thd->handler_tables_hash.records; i++)
{
hash_tables= (TABLE_LIST*) hash_element(&thd->handler_tables_hash, i);
if (hash_tables->table && hash_tables->table->needs_reopen_or_name_lock())
{
mysql_ha_close_table(thd, hash_tables, TRUE);
/* Mark table as closed, ready for re-open. */
hash_tables->table= NULL;
}
}
safe_mutex_assert_owner(&LOCK_open);
(*table_ptr)->file->ha_index_or_rnd_end();
safe_mutex_assert_owner(&LOCK_open);
if (close_thread_table(thd, table_ptr))
{
/* Tell threads waiting for refresh that something has happened */
broadcast_refresh();
}
DBUG_RETURN(0);
DBUG_VOID_RETURN;
}
/**
Close all HANDLER's tables.
@param thd Thread identifier.
@note Broadcasts refresh if it closed a table with old version.
*/
void mysql_ha_cleanup(THD *thd)
{
TABLE_LIST *hash_tables;
DBUG_ENTER("mysql_ha_cleanup");
for (uint i= 0; i < thd->handler_tables_hash.records; i++)
{
hash_tables= (TABLE_LIST*) hash_element(&thd->handler_tables_hash, i);
if (hash_tables->table)
mysql_ha_close_table(thd, hash_tables, FALSE);
}
hash_free(&thd->handler_tables_hash);
DBUG_VOID_RETURN;
}

View file

@ -1834,11 +1834,11 @@ typedef struct st_lex : public Query_tables_list
struct st_lex_local: public st_lex
{
static void *operator new(size_t size)
static void *operator new(size_t size) throw()
{
return sql_alloc(size);
}
static void *operator new(size_t size, MEM_ROOT *mem_root)
static void *operator new(size_t size, MEM_ROOT *mem_root) throw()
{
return (void*) alloc_root(mem_root, (uint) size);
}

View file

@ -2700,7 +2700,7 @@ Prepared_statement::Prepared_statement(THD *thd_arg, Protocol *protocol_arg)
last_errno(0),
flags((uint) IS_IN_USE)
{
init_alloc_root(&main_mem_root, thd_arg->variables.query_alloc_block_size,
init_sql_alloc(&main_mem_root, thd_arg->variables.query_alloc_block_size,
thd_arg->variables.query_prealloc_size);
*last_error= '\0';
}

View file

@ -51,6 +51,8 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
DBUG_RETURN(1);
}
mysql_ha_rm_tables(thd, table_list);
if (wait_if_global_read_lock(thd,0,1))
DBUG_RETURN(1);

View file

@ -1521,6 +1521,8 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
built_query.append("DROP TABLE ");
}
mysql_ha_rm_tables(thd, tables);
pthread_mutex_lock(&LOCK_open);
/*
@ -1562,8 +1564,6 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
handlerton *table_type;
enum legacy_db_type frm_db_type;
mysql_ha_flush(thd, table, MYSQL_HA_CLOSE_FINAL, 1);
error= drop_temporary_table(thd, table);
switch (error) {
@ -1572,13 +1572,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
tmp_table_deleted= 1;
continue;
case -1:
// table already in use
/*
XXX: This branch should never be taken outside of SF, trigger or
prelocked mode.
DBUG_ASSERT(thd->in_sub_stmt);
*/
DBUG_ASSERT(thd->in_sub_stmt);
error= 1;
goto err_with_placeholders;
default:
@ -4025,7 +4019,8 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
DBUG_RETURN(TRUE);
mysql_ha_flush(thd, tables, MYSQL_HA_CLOSE_FINAL, FALSE);
mysql_ha_rm_tables(thd, tables);
for (table= tables; table; table= table->next_local)
{
char table_name[NAME_LEN*2+2];
@ -5766,8 +5761,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
build_table_filename(reg_path, sizeof(reg_path), db, table_name, reg_ext, 0);
build_table_filename(path, sizeof(path), db, table_name, "", 0);
mysql_ha_flush(thd, table_list, MYSQL_HA_CLOSE_FINAL, FALSE);
mysql_ha_rm_tables(thd, table_list);
/* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */
if (alter_info->tablespace_op != NO_TABLESPACE_OP)