Merge moonlight.home:/home/tomash/src/mysql_ab/mysql-5.1

into  moonlight.home:/home/tomash/src/mysql_ab/mysql-5.1-bug9953


mysql-test/r/sp-error.result:
  Auto merged
mysql-test/r/view.result:
  Auto merged
sql/item_timefunc.cc:
  Auto merged
sql/lock.cc:
  Auto merged
sql/log_event.cc:
  Auto merged
sql/mysql_priv.h:
  Auto merged
sql/set_var.cc:
  Auto merged
sql/sp.cc:
  Auto merged
sql/sql_base.cc:
  Auto merged
sql/sql_help.cc:
  Auto merged
sql/sql_lex.cc:
  Auto merged
sql/sql_lex.h:
  Auto merged
sql/sql_parse.cc:
  Auto merged
sql/sql_show.cc:
  Auto merged
sql/sql_view.cc:
  Auto merged
sql/table.cc:
  Auto merged
sql/tztime.cc:
  Auto merged
storage/myisam/ha_myisam.cc:
  Auto merged
sql/sql_yacc.yy:
  SCCS merged
This commit is contained in:
unknown 2007-03-09 13:17:46 +03:00
commit b311d87052
35 changed files with 430 additions and 365 deletions

View File

@ -257,3 +257,12 @@ delete from mysql.help_relation where help_keyword_id=@keyword1_id and help_topi
delete from mysql.help_relation where help_keyword_id=@keyword2_id and help_topic_id=@topic1_id;
delete from mysql.help_relation where help_keyword_id=@keyword3_id and help_topic_id=@topic3_id;
delete from mysql.help_relation where help_keyword_id=@keyword3_id and help_topic_id=@topic4_id;
End of 4.1 tests.
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (i INT);
LOCK TABLES t1 WRITE;
HELP no_such_topic;
name is_it_category
UNLOCK TABLES;
DROP TABLE t1;
End of 5.1 tests.

View File

@ -68,6 +68,7 @@ ERROR HY000: Table 't2' was locked with a READ lock and can't be updated
delete t2 from t1,t2 where t1.a=t2.a;
ERROR HY000: Table 't2' was locked with a READ lock and can't be updated
drop table t1,t2;
End of 4.1 tests.
drop table if exists t1;
create table t1 (a int);
lock table t1 write;
@ -75,3 +76,23 @@ flush tables with read lock;
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
unlock tables;
drop table t1;
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (i INT);
LOCK TABLES mysql.time_zone READ, mysql.proc READ, t1 READ;
UNLOCK TABLES;
LOCK TABLES mysql.time_zone READ, mysql.proc READ, t1 WRITE;
UNLOCK TABLES;
LOCK TABLES mysql.time_zone READ, mysql.proc READ;
UNLOCK TABLES;
LOCK TABLES mysql.time_zone WRITE, mysql.proc WRITE;
UNLOCK TABLES;
LOCK TABLES mysql.time_zone READ, mysql.proc WRITE, t1 READ;
ERROR HY000: You can't combine write-locking of system tables with other tables or lock types
LOCK TABLES mysql.time_zone WRITE, mysql.proc WRITE, t1 READ;
ERROR HY000: You can't combine write-locking of system tables with other tables or lock types
LOCK TABLES mysql.time_zone WRITE, mysql.proc WRITE, t1 WRITE;
ERROR HY000: You can't combine write-locking of system tables with other tables or lock types
LOCK TABLES mysql.time_zone READ, mysql.proc WRITE;
ERROR HY000: You can't combine write-locking of system tables with other tables or lock types
DROP TABLE t1;
End of 5.1 tests.

View File

@ -292,9 +292,9 @@ call p()|
unlock tables|
drop procedure p|
lock tables t1 read, mysql.proc write|
ERROR HY000: You can't combine write-locking of system 'mysql.proc' table with other tables
ERROR HY000: You can't combine write-locking of system tables with other tables or lock types
lock tables mysql.proc write, mysql.user write|
ERROR HY000: You can't combine write-locking of system 'mysql.proc' table with other tables
ERROR HY000: You can't combine write-locking of system tables with other tables or lock types
lock tables t1 read, mysql.proc read|
unlock tables|
lock tables mysql.proc write|

View File

@ -285,3 +285,14 @@ ldt ldt2
drop table t1;
drop function f1;
SET GLOBAL log_bin_trust_function_creators = 0;
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (t TIMESTAMP);
INSERT INTO t1 VALUES (NULL), (NULL);
LOCK TABLES t1 WRITE;
SELECT CONVERT_TZ(NOW(), 'UTC', 'Europe/Moscow') IS NULL;
CONVERT_TZ(NOW(), 'UTC', 'Europe/Moscow') IS NULL
0
UPDATE t1 SET t = CONVERT_TZ(t, 'UTC', 'Europe/Moscow');
UNLOCK TABLES;
DROP TABLE t1;
End of 5.1 tests

View File

@ -900,6 +900,7 @@ drop view v1;
drop table t1;
create table t1 (col1 int);
create table t2 (col1 int);
create table t3 (col1 datetime not null);
create view v1 as select * from t1;
create view v2 as select * from v1;
create view v3 as select v2.col1 from v2,t2 where v2.col1 = t2.col1;
@ -1004,8 +1005,8 @@ ERROR HY000: The definition of table 'v2' prevents operation INSERT on table 'v3
insert into v3 (col1) values ((select CONVERT_TZ('20050101000000','UTC','MET') from v2));
ERROR HY000: The definition of table 'v2' prevents operation INSERT on table 'v3'.
insert into v3 (col1) values ((select CONVERT_TZ('20050101000000','UTC','MET') from t2));
insert into mysql.time_zone values ('', (select CONVERT_TZ('20050101000000','UTC','MET') from t2));
ERROR 23000: Column 'Use_leap_seconds' cannot be null
insert into t3 values ((select CONVERT_TZ('20050101000000','UTC','MET') from t2));
ERROR 23000: Column 'col1' cannot be null
create algorithm=temptable view v4 as select * from t1;
insert into t1 values (1),(2),(3);
insert into t1 (col1) values ((select max(col1) from v4));
@ -1017,7 +1018,7 @@ NULL
3
3
drop view v4,v3,v2,v1;
drop table t1,t2;
drop table t1,t2,t3;
create table t1 (s1 int);
create view v1 as select * from t1;
handler v1 open as xx;

View File

@ -114,4 +114,25 @@ delete from mysql.help_relation where help_keyword_id=@keyword2_id and help_topi
delete from mysql.help_relation where help_keyword_id=@keyword3_id and help_topic_id=@topic3_id;
delete from mysql.help_relation where help_keyword_id=@keyword3_id and help_topic_id=@topic4_id;
# End of 4.1 tests
--echo End of 4.1 tests.
#
# Test that we can use HELP even under LOCK TABLES. See bug#9953:
# CONVERT_TZ requires mysql.time_zone_name to be locked.
#
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
CREATE TABLE t1 (i INT);
LOCK TABLES t1 WRITE;
HELP no_such_topic;
UNLOCK TABLES;
DROP TABLE t1;
--echo End of 5.1 tests.

View File

@ -92,7 +92,8 @@ delete from t2 using t1,t2 where t1.a=t2.a;
delete t2 from t1,t2 where t1.a=t2.a;
drop table t1,t2;
# End of 4.1 tests
--echo End of 4.1 tests.
#
# Bug#18884 "lock table + global read lock = crash"
@ -108,3 +109,44 @@ flush tables with read lock;
unlock tables;
drop table t1;
#
# Test LOCK TABLE on system tables. See bug#9953: CONVERT_TZ requires
# mysql.time_zone_name to be locked.
#
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
CREATE TABLE t1 (i INT);
LOCK TABLES mysql.time_zone READ, mysql.proc READ, t1 READ;
UNLOCK TABLES;
LOCK TABLES mysql.time_zone READ, mysql.proc READ, t1 WRITE;
UNLOCK TABLES;
LOCK TABLES mysql.time_zone READ, mysql.proc READ;
UNLOCK TABLES;
LOCK TABLES mysql.time_zone WRITE, mysql.proc WRITE;
UNLOCK TABLES;
# If at least one system table is locked for WRITE, then all other
# tables should be system tables locked also for WRITE.
--error ER_WRONG_LOCK_OF_SYSTEM_TABLE
LOCK TABLES mysql.time_zone READ, mysql.proc WRITE, t1 READ;
--error ER_WRONG_LOCK_OF_SYSTEM_TABLE
LOCK TABLES mysql.time_zone WRITE, mysql.proc WRITE, t1 READ;
--error ER_WRONG_LOCK_OF_SYSTEM_TABLE
LOCK TABLES mysql.time_zone WRITE, mysql.proc WRITE, t1 WRITE;
--error ER_WRONG_LOCK_OF_SYSTEM_TABLE
LOCK TABLES mysql.time_zone READ, mysql.proc WRITE;
DROP TABLE t1;
--echo End of 5.1 tests.

View File

@ -246,3 +246,31 @@ drop function f1;
SET GLOBAL log_bin_trust_function_creators = 0;
# End of 5.0 tests
#
# BUG#9953: CONVERT_TZ requires mysql.time_zone_name to be locked
# BUG#19339: CONVERT_TZ(): overly aggressive in locking time_zone_name
# table
#
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
CREATE TABLE t1 (t TIMESTAMP);
INSERT INTO t1 VALUES (NULL), (NULL);
LOCK TABLES t1 WRITE;
# The following two queries should not return error that time zone
# tables aren't locked. We use IS NULL below to supress timestamp
# result.
SELECT CONVERT_TZ(NOW(), 'UTC', 'Europe/Moscow') IS NULL;
UPDATE t1 SET t = CONVERT_TZ(t, 'UTC', 'Europe/Moscow');
UNLOCK TABLES;
DROP TABLE t1;
--echo End of 5.1 tests

View File

@ -832,6 +832,7 @@ drop table t1;
#
create table t1 (col1 int);
create table t2 (col1 int);
create table t3 (col1 datetime not null);
create view v1 as select * from t1;
create view v2 as select * from v1;
create view v3 as select v2.col1 from v2,t2 where v2.col1 = t2.col1;
@ -938,7 +939,7 @@ insert into v3 (col1) values ((select max(col1) from v2));
insert into v3 (col1) values ((select CONVERT_TZ('20050101000000','UTC','MET') from v2));
insert into v3 (col1) values ((select CONVERT_TZ('20050101000000','UTC','MET') from t2));
-- error 1048
insert into mysql.time_zone values ('', (select CONVERT_TZ('20050101000000','UTC','MET') from t2));
insert into t3 values ((select CONVERT_TZ('20050101000000','UTC','MET') from t2));
# temporary table algorithm view should be equal to subquery in the from clause
create algorithm=temptable view v4 as select * from t1;
insert into t1 values (1),(2),(3);
@ -946,7 +947,7 @@ insert into t1 (col1) values ((select max(col1) from v4));
select * from t1;
drop view v4,v3,v2,v1;
drop table t1,t2;
drop table t1,t2,t3;
#
# HANDLER with VIEW

View File

@ -974,7 +974,11 @@ public:
check_if_locking_is_allowed()
thd Handler of the thread, trying to lock the table
table Table handler to check
count Number of locks already granted to the table
count Total number of tables to be locked
current Index of the current table in the list of the tables
to be locked.
system_count Pointer to the counter of system tables seen thus
far.
called_by_privileged_thread TRUE if called from a logger THD
(general_log_thd or slow_log_thd)
or by a privileged thread, which
@ -993,7 +997,8 @@ public:
*/
virtual bool check_if_locking_is_allowed(uint sql_command,
ulong type, TABLE *table,
uint count,
uint count, uint current,
uint *system_count,
bool called_by_privileged_thread)
{
return TRUE;

View File

@ -2877,9 +2877,6 @@ Create_func_convert_tz Create_func_convert_tz::s_singleton;
Item*
Create_func_convert_tz::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
if (thd->lex->add_time_zone_tables_to_query_tables(thd))
return NULL;
return new (thd->mem_root) Item_func_convert_tz(arg1, arg2, arg3);
}

View File

@ -1927,19 +1927,6 @@ void Item_func_convert_tz::fix_length_and_dec()
}
bool
Item_func_convert_tz::fix_fields(THD *thd_arg, Item **ref)
{
String str;
if (Item_date_func::fix_fields(thd_arg, ref))
return TRUE;
tz_tables= thd_arg->lex->time_zone_tables_used;
return FALSE;
}
String *Item_func_convert_tz::val_str(String *str)
{
TIME time_tmp;
@ -1974,16 +1961,17 @@ bool Item_func_convert_tz::get_date(TIME *ltime,
{
my_time_t my_time_tmp;
String str;
THD *thd= current_thd;
if (!from_tz_cached)
{
from_tz= my_tz_find(args[1]->val_str(&str), tz_tables);
from_tz= my_tz_find(thd, args[1]->val_str(&str));
from_tz_cached= args[1]->const_item();
}
if (!to_tz_cached)
{
to_tz= my_tz_find(args[2]->val_str(&str), tz_tables);
to_tz= my_tz_find(thd, args[2]->val_str(&str));
to_tz_cached= args[2]->const_item();
}

View File

@ -641,8 +641,6 @@ class Time_zone;
*/
class Item_func_convert_tz :public Item_date_func
{
/* Cached pointer to list of pre-opened time zone tables. */
TABLE_LIST *tz_tables;
/*
If time zone parameters are constants we are caching objects that
represent them (we use separate from_tz_cached/to_tz_cached members
@ -658,7 +656,6 @@ class Item_func_convert_tz :public Item_date_func
double val_real() { return (double) val_int(); }
String *val_str(String *str);
const char *func_name() const { return "convert_tz"; }
bool fix_fields(THD *, Item **);
void fix_length_and_dec();
bool get_date(TIME *res, uint fuzzy_date);
void cleanup();

View File

@ -692,6 +692,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
DBUG_PRINT("info", ("count %d", count));
*write_lock_used=0;
uint system_count= 0;
for (i=tables=lock_count=0 ; i < count ; i++)
{
if (table_ptr[i]->s->tmp_table != TMP_TABLE)
@ -705,7 +706,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
*/
if (!table_ptr[i]-> file->
check_if_locking_is_allowed(thd->lex->sql_command, thd->lex->type,
table_ptr[i], count,
table_ptr[i], count, i, &system_count,
(thd == logger.get_general_log_thd()) ||
(thd == logger.get_slow_log_thd()) ||
(thd == logger.get_privileged_thread())))

View File

@ -2006,8 +2006,7 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli,
if (time_zone_len)
{
String tmp(time_zone_str, time_zone_len, &my_charset_bin);
if (!(thd->variables.time_zone=
my_tz_find_with_opening_tz_tables(thd, &tmp)))
if (!(thd->variables.time_zone= my_tz_find(thd, &tmp)))
{
my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), tmp.c_ptr());
thd->variables.time_zone= global_system_variables.time_zone;

View File

@ -1408,6 +1408,12 @@ int abort_and_upgrade_lock(ALTER_PARTITION_PARAM_TYPE *lpt);
void close_open_tables_and_downgrade(ALTER_PARTITION_PARAM_TYPE *lpt);
void mysql_wait_completed_table(ALTER_PARTITION_PARAM_TYPE *lpt, TABLE *my_table);
/* Functions to work with system tables. */
bool open_system_tables_for_read(THD *thd, TABLE_LIST *table_list,
Open_tables_state *backup);
void close_system_tables(THD *thd, Open_tables_state *backup);
TABLE *open_system_table_for_update(THD *thd, TABLE_LIST *one_table);
bool close_cached_tables(THD *thd, bool wait_for_refresh, TABLE_LIST *tables, bool have_lock = FALSE);
void copy_field_from_tmp_record(Field *field,int offset);
bool fill_record(THD *thd, Field **field, List<Item> &values,

View File

@ -2869,8 +2869,7 @@ bool sys_var_thd_time_zone::check(THD *thd, set_var *var)
String str(buff, sizeof(buff), &my_charset_latin1);
String *res= var->value->val_str(&str);
if (!(var->save_result.time_zone=
my_tz_find(res, thd->lex->time_zone_tables_used)))
if (!(var->save_result.time_zone= my_tz_find(thd, res)))
{
my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), res ? res->c_ptr() : "NULL");
return 1;
@ -2931,8 +2930,7 @@ void sys_var_thd_time_zone::set_default(THD *thd, enum_var_type type)
We are guaranteed to find this time zone since its existence
is checked during start-up.
*/
global_system_variables.time_zone=
my_tz_find(&str, thd->lex->time_zone_tables_used);
global_system_variables.time_zone= my_tz_find(thd, &str);
}
else
global_system_variables.time_zone= my_tz_SYSTEM;

View File

@ -5518,8 +5518,7 @@ ER_M_BIGGER_THAN_D 42000 S1009
eng "For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column '%-.64s')."
ger "Für FLOAT(M,D), DOUBLE(M,D) oder DECIMAL(M,D) muss M >= D sein (Feld '%-.64s')"
ER_WRONG_LOCK_OF_SYSTEM_TABLE
eng "You can't combine write-locking of system '%-.64s.%-.64s' table with other tables"
ger "Sie können Schreibsperren auf der Systemtabelle '%-.64s.%-.64s' nicht mit anderen Tabellen kombinieren"
eng "You can't combine write-locking of system tables with other tables or lock types"
ER_CONNECT_TO_FOREIGN_DATA_SOURCE
eng "Unable to connect to foreign data source: %.64s"
ger "Kann nicht mit Fremddatenquelle verbinden: %.64s"

View File

@ -68,24 +68,6 @@ enum
#define SP_DEFAULT_ACCESS_MAPPING SP_CONTAINS_SQL
/*
Close mysql.proc, opened with open_proc_table_for_read().
SYNOPSIS
close_proc_table()
thd Thread context
backup Pointer to Open_tables_state instance which holds
information about tables which were open before we
decided to access mysql.proc.
*/
void close_proc_table(THD *thd, Open_tables_state *backup)
{
close_thread_tables(thd);
thd->restore_backup_open_tables_state(backup);
}
/*
Open the mysql.proc table for read.
@ -96,13 +78,6 @@ void close_proc_table(THD *thd, Open_tables_state *backup)
currently open tables will be saved, and from which will be
restored when we will end work with mysql.proc.
NOTES
Thanks to restrictions which we put on opening and locking of
this table for writing, we can open and lock it for reading
even when we already have some other tables open and locked.
One must call close_proc_table() to close table opened with
this call.
RETURN
0 Error
# Pointer to TABLE object of mysql.proc
@ -110,38 +85,18 @@ void close_proc_table(THD *thd, Open_tables_state *backup)
TABLE *open_proc_table_for_read(THD *thd, Open_tables_state *backup)
{
TABLE_LIST tables;
TABLE *table;
bool not_used;
DBUG_ENTER("open_proc_table");
DBUG_ENTER("open_proc_table_for_read");
thd->reset_n_backup_open_tables_state(backup);
TABLE_LIST table;
bzero((char*) &table, sizeof(table));
table.db= (char*) "mysql";
table.table_name= table.alias= (char*)"proc";
table.lock_type= TL_READ;
bzero((char*) &tables, sizeof(tables));
tables.db= (char*) "mysql";
tables.table_name= tables.alias= (char*)"proc";
if (!(table= open_table(thd, &tables, thd->mem_root, &not_used,
MYSQL_LOCK_IGNORE_FLUSH)))
{
thd->restore_backup_open_tables_state(backup);
if (!open_system_tables_for_read(thd, &table, backup))
DBUG_RETURN(table.table);
else
DBUG_RETURN(0);
}
table->use_all_columns();
DBUG_ASSERT(table->s->system_table);
table->reginfo.lock_type= TL_READ;
/*
We have to ensure we are not blocked by a flush tables, as this
could lead to a deadlock if we have other tables opened.
*/
if (!(thd->lock= mysql_lock_tables(thd, &table, 1,
MYSQL_LOCK_IGNORE_FLUSH, &not_used)))
{
close_proc_table(thd, backup);
DBUG_RETURN(0);
}
DBUG_RETURN(table);
}
@ -162,20 +117,15 @@ TABLE *open_proc_table_for_read(THD *thd, Open_tables_state *backup)
static TABLE *open_proc_table_for_update(THD *thd)
{
TABLE_LIST tables;
TABLE *table;
DBUG_ENTER("open_proc_table");
DBUG_ENTER("open_proc_table_for_update");
bzero((char*) &tables, sizeof(tables));
tables.db= (char*) "mysql";
tables.table_name= tables.alias= (char*)"proc";
tables.lock_type= TL_WRITE;
TABLE_LIST table;
bzero((char*) &table, sizeof(table));
table.db= (char*) "mysql";
table.table_name= table.alias= (char*)"proc";
table.lock_type= TL_WRITE;
table= open_ltable(thd, &tables, TL_WRITE);
if (table)
table->use_all_columns();
DBUG_RETURN(table);
DBUG_RETURN(open_system_table_for_update(thd, &table));
}
@ -364,7 +314,7 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp)
chistics.comment.str= ptr;
chistics.comment.length= length;
close_proc_table(thd, &open_tables_state_backup);
close_system_tables(thd, &open_tables_state_backup);
table= 0;
ret= db_load_routine(thd, type, name, sphp,
@ -373,7 +323,7 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp)
done:
if (table)
close_proc_table(thd, &open_tables_state_backup);
close_system_tables(thd, &open_tables_state_backup);
DBUG_RETURN(ret);
}
@ -1147,7 +1097,7 @@ sp_routine_exists_in_table(THD *thd, int type, sp_name *name)
{
if ((ret= db_find_routine_aux(thd, type, name, table)) != SP_OK)
ret= SP_KEY_NOT_FOUND;
close_proc_table(thd, &open_tables_state_backup);
close_system_tables(thd, &open_tables_state_backup);
}
return ret;
}

View File

@ -100,7 +100,6 @@ extern "C" byte* sp_sroutine_key(const byte *ptr, uint *plen, my_bool first);
we already have some tables open and locked.
*/
TABLE *open_proc_table_for_read(THD *thd, Open_tables_state *backup);
void close_proc_table(THD *thd, Open_tables_state *backup);
/*

View File

@ -6874,3 +6874,122 @@ has_two_write_locked_tables_with_auto_increment(TABLE_LIST *tables)
}
return 0;
}
/*
Open and lock system tables for read.
SYNOPSIS
open_system_tables_for_read()
thd Thread context.
table_list List of tables to open.
backup Pointer to Open_tables_state instance where
information about currently open tables will be
saved, and from which will be restored when we will
end work with system tables.
NOTES
Thanks to restrictions which we put on opening and locking of
system tables for writing, we can open and lock them for reading
even when we already have some other tables open and locked. One
must call close_system_tables() to close systems tables opened
with this call.
RETURN
FALSE Success
TRUE Error
*/
bool
open_system_tables_for_read(THD *thd, TABLE_LIST *table_list,
Open_tables_state *backup)
{
DBUG_ENTER("open_system_tables_for_read");
thd->reset_n_backup_open_tables_state(backup);
uint count= 0;
bool not_used;
for (TABLE_LIST *tables= table_list; tables; tables= tables->next_global)
{
TABLE *table= open_table(thd, tables, thd->mem_root, &not_used,
MYSQL_LOCK_IGNORE_FLUSH);
if (!table)
goto error;
DBUG_ASSERT(table->s->system_table);
table->use_all_columns();
table->reginfo.lock_type= tables->lock_type;
tables->table= table;
count++;
}
{
TABLE **list= (TABLE**) thd->alloc(sizeof(TABLE*) * count);
TABLE **ptr= list;
for (TABLE_LIST *tables= table_list; tables; tables= tables->next_global)
*(ptr++)= tables->table;
thd->lock= mysql_lock_tables(thd, list, count,
MYSQL_LOCK_IGNORE_FLUSH, &not_used);
}
if (thd->lock)
DBUG_RETURN(FALSE);
error:
close_system_tables(thd, backup);
DBUG_RETURN(TRUE);
}
/*
Close system tables, opened with open_system_tables_for_read().
SYNOPSIS
close_system_tables()
thd Thread context
backup Pointer to Open_tables_state instance which holds
information about tables which were open before we
decided to access system tables.
*/
void
close_system_tables(THD *thd, Open_tables_state *backup)
{
close_thread_tables(thd);
thd->restore_backup_open_tables_state(backup);
}
/*
Open and lock one system table for update.
SYNOPSIS
open_system_table_for_update()
thd Thread context.
one_table Table to open.
NOTES
Table opened with this call should closed using close_thread_tables().
RETURN
0 Error
# Pointer to TABLE object of system table
*/
TABLE *
open_system_table_for_update(THD *thd, TABLE_LIST *one_table)
{
DBUG_ENTER("open_system_table_for_update");
TABLE *table= open_ltable(thd, one_table, one_table->lock_type);
if (table)
{
DBUG_ASSERT(table->s->system_table);
table->use_all_columns();
}
DBUG_RETURN(table);
}

View File

@ -655,8 +655,9 @@ bool mysqld_help(THD *thd, const char *mask)
tables[3].lock_type= TL_READ;
tables[0].db= tables[1].db= tables[2].db= tables[3].db= (char*) "mysql";
if (open_and_lock_tables(thd, tables))
goto error;
Open_tables_state open_tables_state_backup;
if (open_system_tables_for_read(thd, tables, &open_tables_state_backup))
goto error2;
/*
Init tables and fields to be usable from items
@ -781,8 +782,13 @@ bool mysqld_help(THD *thd, const char *mask)
}
send_eof(thd);
close_system_tables(thd, &open_tables_state_backup);
DBUG_RETURN(FALSE);
error:
close_system_tables(thd, &open_tables_state_backup);
error2:
DBUG_RETURN(TRUE);
}

View File

@ -158,7 +158,6 @@ void lex_start(THD *thd, const uchar *buf, uint length)
lex->lock_option= TL_READ;
lex->found_semicolon= 0;
lex->safe_to_cache_query= 1;
lex->time_zone_tables_used= 0;
lex->leaf_tables_insert= 0;
lex->parsing_options.reset();
lex->empty_field_list_on_rset= 0;
@ -2092,31 +2091,6 @@ void st_lex::first_lists_tables_same()
}
/*
Add implicitly used time zone description tables to global table list
(if needed).
SYNOPSYS
st_lex::add_time_zone_tables_to_query_tables()
thd - pointer to current thread context
RETURN VALUE
TRUE - error
FALSE - success
*/
bool st_lex::add_time_zone_tables_to_query_tables(THD *thd_arg)
{
/* We should not add these tables twice */
if (!time_zone_tables_used)
{
time_zone_tables_used= my_tz_get_table_list(thd_arg, &query_tables_last);
if (time_zone_tables_used == &fake_time_zone_tables_list)
return TRUE;
}
return FALSE;
}
/*
Link table back that was unlinked with unlink_first_table()
@ -2186,7 +2160,6 @@ void st_lex::cleanup_after_one_table_open()
/* remove underlying units (units of VIEW) subtree */
select_lex.cut_subtree();
}
time_zone_tables_used= 0;
}

View File

@ -1092,11 +1092,6 @@ typedef struct st_lex : public Query_tables_list
bool prepared_stmt_code_is_varref;
/* Names of user variables holding parameters (in EXECUTE) */
List<LEX_STRING> prepared_stmt_params;
/*
Points to part of global table list which contains time zone tables
implicitly used by the statement.
*/
TABLE_LIST *time_zone_tables_used;
sp_head *sphead;
sp_name *spname;
bool sp_lex_in_use; /* Keep track on lex usage in SPs for error handling */
@ -1183,7 +1178,6 @@ typedef struct st_lex : public Query_tables_list
TABLE_LIST *unlink_first_table(bool *link_to_local);
void link_first_table_back(TABLE_LIST *first, bool link_to_local);
void first_lists_tables_same();
bool add_time_zone_tables_to_query_tables(THD *thd);
bool can_be_merged();
bool can_use_merged();

View File

@ -1676,8 +1676,7 @@ mysql_execute_command(THD *thd)
Don't reset warnings when executing a stored routine.
*/
if ((all_tables || &lex->select_lex != lex->all_selects_list ||
lex->sroutines.records) && !thd->spcont ||
lex->time_zone_tables_used)
lex->sroutines.records) && !thd->spcont)
mysql_reset_errors(thd, 0);
#ifdef HAVE_REPLICATION
@ -4726,9 +4725,7 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
*/
tables->grant.orig_want_privilege= (want_access & ~SHOW_VIEW_ACL);
if (tables->derived || tables->schema_table ||
(tables->table && (int)tables->table->s->tmp_table) ||
my_tz_check_n_skip_implicit_tables(&tables,
thd->lex->time_zone_tables_used))
(tables->table && (int)tables->table->s->tmp_table))
continue;
thd->security_ctx= sctx;
if ((sctx->master_access & want_access) ==
@ -6496,14 +6493,12 @@ bool multi_update_precheck(THD *thd, TABLE_LIST *tables)
/*
Is there tables of subqueries?
*/
if (&lex->select_lex != lex->all_selects_list || lex->time_zone_tables_used)
if (&lex->select_lex != lex->all_selects_list)
{
DBUG_PRINT("info",("Checking sub query list"));
for (table= tables; table; table= table->next_global)
{
if (!my_tz_check_n_skip_implicit_tables(&table,
lex->time_zone_tables_used) &&
!table->table_in_first_from_clause)
if (!table->table_in_first_from_clause)
{
if (check_access(thd, SELECT_ACL, table->db,
&table->grant.privilege, 0, 0,

View File

@ -3511,7 +3511,7 @@ int fill_schema_proc(THD *thd, TABLE_LIST *tables, COND *cond)
err:
proc_table->file->ha_index_end();
close_proc_table(thd, &open_tables_state_backup);
close_system_tables(thd, &open_tables_state_backup);
DBUG_RETURN(res);
}

View File

@ -1302,8 +1302,6 @@ ok:
(st_select_lex_node**)&old_lex->all_selects_list;
ok2:
if (!old_lex->time_zone_tables_used && thd->lex->time_zone_tables_used)
old_lex->time_zone_tables_used= thd->lex->time_zone_tables_used;
DBUG_ASSERT(lex == thd->lex);
thd->lex= old_lex; // Needed for prepare_security
result= !table->prelocking_placeholder && table->prepare_security(thd);

View File

@ -10357,14 +10357,7 @@ internal_variable_name:
MYSQL_YYABORT;
$$.var= tmp;
$$.base_name= null_lex_str;
/*
If this is time_zone variable we should open time zone
describing tables
*/
if (tmp == &sys_time_zone &&
lex->add_time_zone_tables_to_query_tables(YYTHD))
MYSQL_YYABORT;
else if (spc && tmp == &sys_autocommit)
if (spc && tmp == &sys_autocommit)
{
/*
We don't allow setting AUTOCOMMIT from a stored function

View File

@ -245,6 +245,50 @@ void free_table_share(TABLE_SHARE *share)
}
/**
Return TRUE if a table name matches one of the system table names.
Currently these are:
help_category, help_keyword, help_relation, help_topic,
proc,
time_zone, time_zone_leap_second, time_zone_name, time_zone_transition,
time_zone_transition_type
This function trades accuracy for speed, so may return false
positives. Presumably mysql.* database is for internal purposes only
and should not contain user tables.
*/
inline bool is_system_table_name(const char *name, uint length)
{
CHARSET_INFO *ci= system_charset_info;
return (
/* mysql.proc table */
length == 4 &&
my_tolower(ci, name[0]) == 'p' &&
my_tolower(ci, name[1]) == 'r' &&
my_tolower(ci, name[2]) == 'o' &&
my_tolower(ci, name[3]) == 'c' ||
length > 4 &&
(
/* one of mysql.help* tables */
my_tolower(ci, name[0]) == 'h' &&
my_tolower(ci, name[1]) == 'e' &&
my_tolower(ci, name[2]) == 'l' &&
my_tolower(ci, name[3]) == 'p' ||
/* one of mysql.time_zone* tables */
my_tolower(ci, name[0]) == 't' &&
my_tolower(ci, name[1]) == 'i' &&
my_tolower(ci, name[2]) == 'm' &&
my_tolower(ci, name[3]) == 'e'
)
);
}
/*
Read table definition from a binary / text based .frm file
@ -365,11 +409,9 @@ int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags)
allow to lock such tables for writing with any other tables (even with
other system tables) and some privilege tables need this.
*/
if (!(lower_case_table_names ?
my_strcasecmp(system_charset_info, share->table_name.str, "proc") :
strcmp(share->table_name.str, "proc")))
share->system_table= 1;
else
share->system_table= is_system_table_name(share->table_name.str,
share->table_name.length);
if (!share->system_table)
{
share->log_table= check_if_log_table(share->db.length, share->db.str,
share->table_name.length,

View File

@ -1488,26 +1488,20 @@ extern "C" byte* my_offset_tzs_get_key(Time_zone_offset *entry, uint *length,
/*
Prepare table list with time zone related tables from preallocated array
and add to global table list.
Prepare table list with time zone related tables from preallocated array.
SYNOPSIS
tz_init_table_list()
tz_tabs - pointer to preallocated array of MY_TZ_TABLES_COUNT
TABLE_LIST objects
global_next_ptr - pointer to variable which points to global_next member
of last element of global table list (or list root
then list is empty) (in/out).
DESCRIPTION
This function prepares list of TABLE_LIST objects which can be used
for opening of time zone tables from preallocated array. It also links
this list to the end of global table list (it will read and update
accordingly variable pointed by global_next_ptr for this).
for opening of time zone tables from preallocated array.
*/
static void
tz_init_table_list(TABLE_LIST *tz_tabs, TABLE_LIST ***global_next_ptr)
tz_init_table_list(TABLE_LIST *tz_tabs)
{
bzero(tz_tabs, sizeof(TABLE_LIST) * MY_TZ_TABLES_COUNT);
@ -1524,64 +1518,6 @@ tz_init_table_list(TABLE_LIST *tz_tabs, TABLE_LIST ***global_next_ptr)
if (i != 0)
tz_tabs[i].prev_global= &tz_tabs[i-1].next_global;
}
/* Link into global list */
tz_tabs[0].prev_global= *global_next_ptr;
**global_next_ptr= tz_tabs;
/* Update last-global-pointer to point to pointer in last table */
*global_next_ptr= &tz_tabs[MY_TZ_TABLES_COUNT-1].next_global;
}
/*
Fake table list object, pointer to which is returned by
my_tz_get_tables_list() as indication of error.
*/
TABLE_LIST fake_time_zone_tables_list;
/*
Create table list with time zone related tables and add it to the end
of global table list.
SYNOPSIS
my_tz_get_table_list()
thd - current thread object
global_next_ptr - pointer to variable which points to global_next member
of last element of global table list (or list root
then list is empty) (in/out).
DESCRIPTION
This function creates list of TABLE_LIST objects allocated in thd's
memroot, which can be used for opening of time zone tables. It will also
link this list to the end of global table list (it will read and update
accordingly variable pointed by global_next_ptr for this).
NOTE
my_tz_check_n_skip_implicit_tables() function depends on fact that
elements of list created are allocated as TABLE_LIST[MY_TZ_TABLES_COUNT]
array.
RETURN VALUES
Returns pointer to first TABLE_LIST object, (could be 0 if time zone
tables don't exist) and &fake_time_zone_tables_list in case of error.
*/
TABLE_LIST *
my_tz_get_table_list(THD *thd, TABLE_LIST ***global_next_ptr)
{
TABLE_LIST *tz_tabs;
DBUG_ENTER("my_tz_get_table_list");
if (!time_zone_tables_exist)
DBUG_RETURN(0);
if (!(tz_tabs= (TABLE_LIST *)thd->alloc(sizeof(TABLE_LIST) *
MY_TZ_TABLES_COUNT)))
DBUG_RETURN(&fake_time_zone_tables_list);
tz_init_table_list(tz_tabs, global_next_ptr);
DBUG_RETURN(tz_tabs);
}
@ -1614,8 +1550,8 @@ my_bool
my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap)
{
THD *thd;
TABLE_LIST *tables= 0;
TABLE_LIST tables_buff[1+MY_TZ_TABLES_COUNT], **last_global_next_ptr;
TABLE_LIST tz_tables[1+MY_TZ_TABLES_COUNT];
Open_tables_state open_tables_state_backup;
TABLE *table;
Tz_names_entry *tmp_tzname;
my_bool return_val= 1;
@ -1677,19 +1613,23 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap)
*/
thd->set_db(db, sizeof(db)-1);
bzero((char*) &tables_buff, sizeof(TABLE_LIST));
tables_buff[0].alias= tables_buff[0].table_name=
bzero((char*) &tz_tables[0], sizeof(TABLE_LIST));
tz_tables[0].alias= tz_tables[0].table_name=
(char*)"time_zone_leap_second";
tables_buff[0].lock_type= TL_READ;
tables_buff[0].db= db;
/*
Fill TABLE_LIST for the rest of the time zone describing tables
and link it to first one.
*/
last_global_next_ptr= &(tables_buff[0].next_global);
tz_init_table_list(tables_buff + 1, &last_global_next_ptr);
tz_tables[0].table_name_length= 21;
tz_tables[0].db= db;
tz_tables[0].db_length= sizeof(db)-1;
tz_tables[0].lock_type= TL_READ;
if (simple_open_n_lock_tables(thd, tables_buff))
tz_init_table_list(tz_tables+1);
tz_tables[0].next_global= tz_tables[0].next_local= &tz_tables[1];
tz_tables[1].prev_global= &tz_tables[0].next_global;
/*
We need to open only mysql.time_zone_leap_second, but we try to
open all time zone tables to see if they exist.
*/
if (open_system_tables_for_read(thd, tz_tables, &open_tables_state_backup))
{
sql_print_warning("Can't open and lock time zone table: %s "
"trying to live without them", thd->net.last_error);
@ -1697,7 +1637,6 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap)
return_val= time_zone_tables_exist= 0;
goto end_with_setting_default_tz;
}
tables= tables_buff + 1;
/*
Now we are going to load leap seconds descriptions that are shared
@ -1713,7 +1652,7 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap)
goto end_with_close;
}
table= tables_buff[0].table;
table= tz_tables[0].table;
/*
It is OK to ignore ha_index_init()/ha_index_end() return values since
mysql.time_zone* tables are MyISAM and these operations always succeed
@ -1770,7 +1709,12 @@ end_with_setting_default_tz:
if (default_tzname)
{
String tmp_tzname2(default_tzname, &my_charset_latin1);
if (!(global_system_variables.time_zone= my_tz_find(&tmp_tzname2, tables)))
/*
Time zone tables may be open here, and my_tz_find() may open
most of them once more, but this is OK for system tables open
for READ.
*/
if (!(global_system_variables.time_zone= my_tz_find(thd, &tmp_tzname2)))
{
sql_print_error("Fatal error: Illegal or unknown default time zone '%s'",
default_tzname);
@ -1779,8 +1723,11 @@ end_with_setting_default_tz:
}
end_with_close:
thd->version--; /* Force close to free memory */
close_thread_tables(thd);
if (time_zone_tables_exist)
{
thd->version--; /* Force close to free memory */
close_system_tables(thd, &open_tables_state_backup);
}
end_with_cleanup:
@ -1889,7 +1836,6 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
*/
table= tz_tables->table;
tz_tables= tz_tables->next_local;
table->use_all_columns();
table->field[0]->store(tz_name->ptr(), tz_name->length(),
&my_charset_latin1);
/*
@ -1922,7 +1868,6 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
using the only index in this table).
*/
table= tz_tables->table;
table->use_all_columns();
tz_tables= tz_tables->next_local;
table->field[0]->store((longlong) tzid, TRUE);
(void)table->file->ha_index_init(0, 1);
@ -1950,7 +1895,6 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
Right - using special index.
*/
table= tz_tables->table;
table->use_all_columns();
tz_tables= tz_tables->next_local;
table->field[0]->store((longlong) tzid, TRUE);
(void)table->file->ha_index_init(0, 1);
@ -2024,7 +1968,6 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
in ascending order by index scan also satisfies us.
*/
table= tz_tables->table;
table->use_all_columns();
table->field[0]->store((longlong) tzid, TRUE);
(void)table->file->ha_index_init(0, 1);
@ -2234,8 +2177,8 @@ str_to_offset(const char *str, uint length, long *offset)
SYNOPSIS
my_tz_find()
thd - pointer to thread THD structure
name - time zone specification
tz_tables - list of opened'n'locked time zone describing tables
DESCRIPTION
This function checks if name is one of time zones described in db,
@ -2257,11 +2200,10 @@ str_to_offset(const char *str, uint length, long *offset)
values as parameter without additional external check and this property
is used by @@time_zone variable handling code).
It will perform lookup in system tables (mysql.time_zone*) if needed
using tz_tables as list of already opened tables (for info about this
list look at tz_load_from_open_tables() description). It won't perform
such lookup if no time zone describing tables were found during server
start up.
It will perform lookup in system tables (mysql.time_zone*),
opening and locking them, and closing afterwards. It won't perform
such lookup if no time zone describing tables were found during
server start up.
RETURN VALUE
Pointer to corresponding Time_zone object. 0 - in case of bad time zone
@ -2269,7 +2211,7 @@ str_to_offset(const char *str, uint length, long *offset)
*/
Time_zone *
my_tz_find(const String * name, TABLE_LIST *tz_tables)
my_tz_find(THD *thd, const String *name)
{
Tz_names_entry *tmp_tzname;
Time_zone *result_tz= 0;
@ -2277,8 +2219,6 @@ my_tz_find(const String * name, TABLE_LIST *tz_tables)
DBUG_ENTER("my_tz_find");
DBUG_PRINT("enter", ("time zone name='%s'",
name ? ((String *)name)->c_ptr_safe() : "NULL"));
DBUG_ASSERT(!time_zone_tables_exist || tz_tables ||
current_thd->slave_thread);
if (!name)
DBUG_RETURN(0);
@ -2310,8 +2250,19 @@ my_tz_find(const String * name, TABLE_LIST *tz_tables)
(const byte *)name->ptr(),
name->length())))
result_tz= tmp_tzname->tz;
else if (time_zone_tables_exist && tz_tables)
result_tz= tz_load_from_open_tables(name, tz_tables);
else if (time_zone_tables_exist)
{
TABLE_LIST tz_tables[MY_TZ_TABLES_COUNT];
Open_tables_state open_tables_state_backup;
tz_init_table_list(tz_tables);
if (!open_system_tables_for_read(thd, tz_tables,
&open_tables_state_backup))
{
result_tz= tz_load_from_open_tables(name, tz_tables);
close_system_tables(thd, &open_tables_state_backup);
}
}
}
VOID(pthread_mutex_unlock(&tz_LOCK));
@ -2320,58 +2271,6 @@ my_tz_find(const String * name, TABLE_LIST *tz_tables)
}
/*
A more standalone version of my_tz_find(): will open tz tables if needed.
This is so far only used by replication, where time zone setting does not
happen in the usual query context.
SYNOPSIS
my_tz_find_with_opening_tz_tables()
thd - pointer to thread's THD structure
name - time zone specification
DESCRIPTION
This function tries to find a time zone which matches the named passed in
argument. If it fails, it will open time zone tables and re-try the
search.
This function is needed for the slave SQL thread, which does not do the
addition of time zone tables which is usually done during query parsing
(as time zone setting by slave does not happen in mysql_parse() but
before). So it needs to open tz tables by itself if needed.
See notes of my_tz_find() as they also apply here.
RETURN VALUE
Pointer to corresponding Time_zone object. 0 - in case of bad time zone
specification or other error.
*/
Time_zone *my_tz_find_with_opening_tz_tables(THD *thd, const String *name)
{
Time_zone *tz;
DBUG_ENTER("my_tz_find_with_opening_tables");
DBUG_ASSERT(thd);
DBUG_ASSERT(thd->slave_thread); // intended for use with slave thread only
if (!(tz= my_tz_find(name, 0)) && time_zone_tables_exist)
{
/*
Probably we have not loaded this time zone yet so let us look it up in
our time zone tables. Note that if we don't have tz tables on this
slave, we don't even try.
*/
TABLE_LIST tables[MY_TZ_TABLES_COUNT];
TABLE_LIST *dummy;
TABLE_LIST **dummyp= &dummy;
tz_init_table_list(tables, &dummyp);
if (simple_open_n_lock_tables(thd, tables))
DBUG_RETURN(0);
tz= my_tz_find(name, tables);
/* We need to close tables _now_ to not pollute coming query */
close_thread_tables(thd);
}
DBUG_RETURN(tz);
}
#endif /* !defined(TESTTIME) && !defined(TZINFO2SQL) */

View File

@ -59,15 +59,11 @@ public:
extern Time_zone * my_tz_UTC;
extern Time_zone * my_tz_SYSTEM;
extern TABLE_LIST * my_tz_get_table_list(THD *thd, TABLE_LIST ***global_next_ptr);
extern Time_zone * my_tz_find(const String *name, TABLE_LIST *tz_tables);
extern Time_zone * my_tz_find_with_opening_tz_tables(THD *thd, const String *name);
extern Time_zone * my_tz_find(THD *thd, const String *name);
extern my_bool my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap);
extern void my_tz_free();
extern my_time_t sec_since_epoch_TIME(TIME *t);
extern TABLE_LIST fake_time_zone_tables_list;
/*
Number of elements in table list produced by my_tz_get_table_list()
(this table list contains tables which are needed for dynamical loading
@ -77,34 +73,5 @@ extern TABLE_LIST fake_time_zone_tables_list;
static const int MY_TZ_TABLES_COUNT= 4;
/*
Check if we have pointer to the begining of list of implicitly used time
zone tables, set SELECT_ACL for them and fast-forward to its end.
SYNOPSIS
my_tz_check_n_skip_implicit_tables()
table - (in/out) pointer to element of table list to check
tz_tables - list of implicitly used time zone tables received
from my_tz_get_table_list() function.
NOTE
This function relies on my_tz_get_table_list() implementation.
RETURN VALUE
TRUE - if table points to the beggining of tz_tables list
FALSE - otherwise.
*/
inline bool my_tz_check_n_skip_implicit_tables(TABLE_LIST **table,
TABLE_LIST *tz_tables)
{
if (*table == tz_tables)
{
for (int i= 0; i < MY_TZ_TABLES_COUNT; i++)
(*table)[i].grant.privilege= SELECT_ACL;
(*table)+= MY_TZ_TABLES_COUNT - 1;
return TRUE;
}
return FALSE;
}
#endif /* !defined(TESTTIME) && !defined(TZINFO2SQL) */

View File

@ -787,7 +787,8 @@ void ha_tina::update_status()
bool ha_tina::check_if_locking_is_allowed(uint sql_command,
ulong type, TABLE *table,
uint count,
uint count, uint current,
uint *system_count,
bool called_by_privileged_thread)
{
if (!called_by_privileged_thread)

View File

@ -128,7 +128,8 @@ public:
virtual bool check_if_locking_is_allowed(uint sql_command,
ulong type, TABLE *table,
uint count,
uint count, uint current,
uint *system_count,
bool called_by_logger_thread);
int open(const char *name, int mode, uint open_options);
int close(void);

View File

@ -565,7 +565,8 @@ err:
bool ha_myisam::check_if_locking_is_allowed(uint sql_command,
ulong type, TABLE *table,
uint count,
uint count, uint current,
uint *system_count,
bool called_by_privileged_thread)
{
/*
@ -574,11 +575,13 @@ bool ha_myisam::check_if_locking_is_allowed(uint sql_command,
we have to disallow write-locking of these tables with any other tables.
*/
if (table->s->system_table &&
table->reginfo.lock_type >= TL_WRITE_ALLOW_WRITE &&
count != 1)
table->reginfo.lock_type >= TL_WRITE_ALLOW_WRITE)
(*system_count)++;
/* 'current' is an index, that's why '<=' below. */
if (*system_count > 0 && *system_count <= current)
{
my_error(ER_WRONG_LOCK_OF_SYSTEM_TABLE, MYF(0), table->s->db.str,
table->s->table_name.str);
my_error(ER_WRONG_LOCK_OF_SYSTEM_TABLE, MYF(0));
return FALSE;
}

View File

@ -62,7 +62,8 @@ class ha_myisam: public handler
virtual bool check_if_locking_is_allowed(uint sql_command,
ulong type, TABLE *table,
uint count,
uint count, uint current,
uint *system_count,
bool called_by_logger_thread);
int open(const char *name, int mode, uint test_if_locked);
int close(void);