summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <kostja@bodhi.(none)>2007-07-31 23:47:38 +0400
committerunknown <kostja@bodhi.(none)>2007-07-31 23:47:38 +0400
commit2914bad6ac429cd401803210b5a7389d141a27a2 (patch)
tree3aa1ba7703851e4f51c6bce20c1be35c0e039b74
parent5713d2e069017b8fbfda9dcf5c3380534e39a52a (diff)
parent5404ba422e35d75054d3941b6e52f237fbb46e91 (diff)
downloadmariadb-git-2914bad6ac429cd401803210b5a7389d141a27a2.tar.gz
Merge bk-internal.mysql.com:/home/bk/mysql-5.1
into bodhi.(none):/opt/local/work/mysql-5.1-runtime client/mysqldump.c: Auto merged mysql-test/r/mysqldump.result: Auto merged mysql-test/t/disabled.def: Auto merged mysql-test/t/mysqldump.test: Auto merged sql/handler.cc: Auto merged sql/lock.cc: Auto merged sql/sql_base.cc: Auto merged sql/sql_lex.cc: Auto merged sql/sql_parse.cc: Auto merged sql/sql_table.cc: Auto merged sql/table.cc: Auto merged sql/table.h: Auto merged mysql-test/include/mix1.inc: Manual merge. mysql-test/r/innodb_mysql.result: Manual merge.
-rw-r--r--client/mysqldump.c107
-rw-r--r--mysql-test/include/mix1.inc32
-rw-r--r--mysql-test/r/ddl_i18n_koi8r.result12
-rw-r--r--mysql-test/r/ddl_i18n_utf8.result12
-rw-r--r--mysql-test/r/events_bugs.result7
-rw-r--r--mysql-test/r/im_options.result10
-rw-r--r--mysql-test/r/innodb_mysql.result28
-rw-r--r--mysql-test/r/log_state.result22
-rw-r--r--mysql-test/r/log_tables.result297
-rw-r--r--mysql-test/r/mysqldump-max.result36
-rw-r--r--mysql-test/r/mysqldump.result252
-rw-r--r--mysql-test/r/openssl_1.result9
-rw-r--r--mysql-test/r/ps.result54
-rw-r--r--mysql-test/r/show_check.result51
-rw-r--r--mysql-test/r/sp-prelocking.result30
-rw-r--r--mysql-test/r/status.result12
-rw-r--r--mysql-test/t/disabled.def1
-rw-r--r--mysql-test/t/events_bugs.test15
-rw-r--r--mysql-test/t/log_state.test53
-rw-r--r--mysql-test/t/log_tables.test410
-rw-r--r--mysql-test/t/mysqldump.test57
-rw-r--r--mysql-test/t/ps.test7
-rw-r--r--mysql-test/t/show_check.test64
-rw-r--r--mysql-test/t/sp-prelocking.test31
-rw-r--r--scripts/mysql_system_tables.sql21
-rw-r--r--server-tools/instance-manager/guardian.cc31
-rw-r--r--server-tools/instance-manager/instance.cc44
-rw-r--r--server-tools/instance-manager/instance.h2
-rw-r--r--server-tools/instance-manager/instance_options.cc13
-rw-r--r--server-tools/instance-manager/parse_output.cc401
-rw-r--r--server-tools/instance-manager/parse_output.h16
-rw-r--r--server-tools/instance-manager/portability.h5
-rw-r--r--server-tools/instance-manager/thread_registry.cc11
-rw-r--r--sql/event_data_objects.cc9
-rw-r--r--sql/event_db_repository.cc8
-rw-r--r--sql/event_queue.cc2
-rw-r--r--sql/handler.cc29
-rw-r--r--sql/handler.h72
-rw-r--r--sql/lock.cc125
-rw-r--r--sql/log.cc731
-rw-r--r--sql/log.h90
-rw-r--r--sql/mysql_priv.h17
-rw-r--r--sql/set_var.cc22
-rw-r--r--sql/share/errmsg.txt4
-rw-r--r--sql/slave.cc2
-rw-r--r--sql/sp.cc6
-rw-r--r--sql/sql_acl.cc2
-rw-r--r--sql/sql_base.cc177
-rw-r--r--sql/sql_class.h25
-rw-r--r--sql/sql_delete.cc22
-rw-r--r--sql/sql_error.cc3
-rw-r--r--sql/sql_insert.cc2
-rw-r--r--sql/sql_lex.cc133
-rw-r--r--sql/sql_parse.cc27
-rw-r--r--sql/sql_plugin.cc4
-rw-r--r--sql/sql_rename.cc20
-rw-r--r--sql/sql_servers.cc6
-rw-r--r--sql/sql_show.cc3
-rw-r--r--sql/sql_table.cc49
-rw-r--r--sql/sql_udf.cc4
-rw-r--r--sql/sql_yacc.yy2
-rw-r--r--sql/table.cc209
-rw-r--r--sql/table.h121
-rw-r--r--sql/tztime.cc15
-rw-r--r--sql/tztime.h1
-rw-r--r--storage/csv/ha_tina.cc12
-rw-r--r--storage/csv/ha_tina.h5
-rw-r--r--storage/myisam/ha_myisam.cc36
-rw-r--r--storage/myisam/ha_myisam.h5
-rw-r--r--storage/myisam/mi_test1.c5
-rw-r--r--storage/myisam/mi_test2.c23
-rw-r--r--storage/myisam/mi_test3.c8
72 files changed, 2860 insertions, 1329 deletions
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 0f30ebddacc..cfdde285040 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -2116,7 +2116,10 @@ static uint get_table_structure(char *table, char *db, char *table_type,
MYSQL_FIELD *field;
my_snprintf(buff, sizeof(buff), "show create table %s", result_table);
- if (mysql_query_with_error_report(mysql, 0, buff))
+
+ if (switch_character_set_results(mysql, "binary") ||
+ mysql_query_with_error_report(mysql, &result, buff) ||
+ switch_character_set_results(mysql, default_charset))
DBUG_RETURN(0);
if (path)
@@ -2147,7 +2150,6 @@ static uint get_table_structure(char *table, char *db, char *table_type,
check_io(sql_file);
}
- result= mysql_store_result(mysql);
field= mysql_fetch_field_direct(result, 0);
if (strcmp(field->name, "View") == 0)
{
@@ -2174,7 +2176,9 @@ static uint get_table_structure(char *table, char *db, char *table_type,
*/
my_snprintf(query_buff, sizeof(query_buff),
"SHOW FIELDS FROM %s", result_table);
- if (mysql_query_with_error_report(mysql, 0, query_buff))
+ if (switch_character_set_results(mysql, "binary") ||
+ mysql_query_with_error_report(mysql, &result, query_buff) ||
+ switch_character_set_results(mysql, default_charset))
{
/*
View references invalid or privileged table/col/fun (err 1356),
@@ -2192,43 +2196,50 @@ static uint get_table_structure(char *table, char *db, char *table_type,
else
my_free(scv_buff, MYF(MY_ALLOW_ZERO_PTR));
- if ((result= mysql_store_result(mysql)))
+ if (mysql_num_rows(result))
{
- if (mysql_num_rows(result))
+ if (opt_drop)
{
- if (opt_drop)
- {
/*
- We have already dropped any table of the same name
- above, so here we just drop the view.
- */
+ We have already dropped any table of the same name above, so
+ here we just drop the view.
+ */
- fprintf(sql_file, "/*!50001 DROP VIEW IF EXISTS %s*/;\n",
- opt_quoted_table);
- check_io(sql_file);
- }
+ fprintf(sql_file, "/*!50001 DROP VIEW IF EXISTS %s*/;\n",
+ opt_quoted_table);
+ check_io(sql_file);
+ }
- fprintf(sql_file, "/*!50001 CREATE TABLE %s (\n", result_table);
- /*
- Get first row, following loop will prepend comma - keeps
- from having to know if the row being printed is last to
- determine if there should be a _trailing_ comma.
- */
- row= mysql_fetch_row(result);
+ fprintf(sql_file,
+ "SET @saved_cs_client = @@character_set_client;\n"
+ "SET character_set_client = utf8;\n"
+ "/*!50001 CREATE TABLE %s (\n",
+ result_table);
- fprintf(sql_file, " %s %s", quote_name(row[0], name_buff, 0),
- row[1]);
+ /*
+ Get first row, following loop will prepend comma - keeps from
+ having to know if the row being printed is last to determine if
+ there should be a _trailing_ comma.
+ */
- while((row= mysql_fetch_row(result)))
- {
- /* col name, col type */
- fprintf(sql_file, ",\n %s %s",
- quote_name(row[0], name_buff, 0), row[1]);
- }
- fprintf(sql_file, "\n) */;\n");
- check_io(sql_file);
+ row= mysql_fetch_row(result);
+
+ fprintf(sql_file, " %s %s", quote_name(row[0], name_buff, 0),
+ row[1]);
+
+ while((row= mysql_fetch_row(result)))
+ {
+ /* col name, col type */
+ fprintf(sql_file, ",\n %s %s",
+ quote_name(row[0], name_buff, 0), row[1]);
}
+ fprintf(sql_file,
+ "\n) */;\n"
+ "SET character_set_client = @saved_cs_client;\n");
+
+ check_io(sql_file);
}
+
mysql_free_result(result);
if (path)
@@ -2239,7 +2250,14 @@ static uint get_table_structure(char *table, char *db, char *table_type,
}
row= mysql_fetch_row(result);
- fprintf(sql_file, "%s;\n", row[1]);
+
+ fprintf(sql_file,
+ "SET @saved_cs_client = @@character_set_client;\n"
+ "SET character_set_client = utf8;\n"
+ "%s;\n"
+ "SET character_set_client = @saved_cs_client;\n",
+ row[1]);
+
check_io(sql_file);
mysql_free_result(result);
}
@@ -3726,11 +3744,12 @@ static int dump_all_tables_in_db(char *database)
{
DYNAMIC_STRING query;
init_dynamic_string_checked(&query, "LOCK TABLES ", 256, 1024);
- for (numrows= 0 ; (table= getTableName(1)) ; numrows++)
+ for (numrows= 0 ; (table= getTableName(1)) ; )
{
char *end= strmov(afterdot, table);
if (include_table(hash_key,end - hash_key))
{
+ numrows++;
dynstr_append_checked(&query, quote_name(table, table_buff, 1));
dynstr_append_checked(&query, " READ /*!32311 LOCAL */,");
}
@@ -3804,6 +3823,11 @@ static my_bool dump_all_views_in_db(char *database)
char *table;
uint numrows;
char table_buff[NAME_LEN*2+3];
+ char hash_key[2*NAME_LEN+2]; /* "db.tablename" */
+ char *afterdot;
+
+ afterdot= strmov(hash_key, database);
+ *afterdot++= '.';
if (init_dumping(database, init_dumping_views))
return 1;
@@ -3813,10 +3837,15 @@ static my_bool dump_all_views_in_db(char *database)
{
DYNAMIC_STRING query;
init_dynamic_string_checked(&query, "LOCK TABLES ", 256, 1024);
- for (numrows= 0 ; (table= getTableName(1)); numrows++)
+ for (numrows= 0 ; (table= getTableName(1)); )
{
- dynstr_append_checked(&query, quote_name(table, table_buff, 1));
- dynstr_append_checked(&query, " READ /*!32311 LOCAL */,");
+ char *end= strmov(afterdot, table);
+ if (include_table(hash_key,end - hash_key))
+ {
+ numrows++;
+ dynstr_append_checked(&query, quote_name(table, table_buff, 1));
+ dynstr_append_checked(&query, " READ /*!32311 LOCAL */,");
+ }
}
if (numrows && mysql_real_query(mysql, query.str, query.length-1))
DB_error(mysql, "when using LOCK TABLES");
@@ -3830,7 +3859,11 @@ static my_bool dump_all_views_in_db(char *database)
/* We shall continue here, if --force was given */
}
while ((table= getTableName(0)))
- get_view_structure(table, database);
+ {
+ char *end= strmov(afterdot, table);
+ if (include_table(hash_key, end - hash_key))
+ get_view_structure(table, database);
+ }
if (opt_xml)
{
fputs("</database>\n", md_result_file);
diff --git a/mysql-test/include/mix1.inc b/mysql-test/include/mix1.inc
index 591971a32a4..7ca6bb57909 100644
--- a/mysql-test/include/mix1.inc
+++ b/mysql-test/include/mix1.inc
@@ -814,6 +814,38 @@ create table t1 (a int) engine=innodb;
alter table t1 alter a set default 1;
drop table t1;
+--echo
+--echo Bug#24918 drop table and lock / inconsistent between
+--echo perm and temp tables
+--echo
+--echo Check transactional tables under LOCK TABLES
+--echo
+--disable_warnings
+drop table if exists t24918, t24918_tmp, t24918_trans, t24918_trans_tmp,
+t24918_access;
+--enable_warnings
+create table t24918_access (id int);
+create table t24918 (id int) engine=myisam;
+create temporary table t24918_tmp (id int) engine=myisam;
+create table t24918_trans (id int) engine=innodb;
+create temporary table t24918_trans_tmp (id int) engine=innodb;
+
+lock table t24918 write, t24918_tmp write, t24918_trans write, t24918_trans_tmp write;
+drop table t24918;
+--error ER_TABLE_NOT_LOCKED
+select * from t24918_access;
+drop table t24918_trans;
+--error ER_TABLE_NOT_LOCKED
+select * from t24918_access;
+drop table t24918_trans_tmp;
+--error ER_TABLE_NOT_LOCKED
+select * from t24918_access;
+drop table t24918_tmp;
+--error ER_TABLE_NOT_LOCKED
+select * from t24918_access;
+unlock tables;
+
+drop table t24918_access;
#
# Bug #28591: MySQL need not sort the records in case of ORDER BY
# primary_key on InnoDB table
diff --git a/mysql-test/r/ddl_i18n_koi8r.result b/mysql-test/r/ddl_i18n_koi8r.result
index 9e5931330e2..3d38319df21 100644
--- a/mysql-test/r/ddl_i18n_koi8r.result
+++ b/mysql-test/r/ddl_i18n_koi8r.result
@@ -1689,12 +1689,18 @@ DELETE FROM mysqltest2.log|
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest1` /*!40100 DEFAULT CHARACTER SET cp866 */;
USE `mysqltest1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `log` (
`msg` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+SET character_set_client = @saved_cs_client;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`c` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+SET character_set_client = @saved_cs_client;
INSERT INTO `t1` VALUES (1),(0),(1);
ALTER DATABASE mysqltest1 CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
@@ -1762,12 +1768,18 @@ ALTER DATABASE mysqltest1 CHARACTER SET cp866 COLLATE cp866_general_ci ;
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest2` /*!40100 DEFAULT CHARACTER SET cp866 */;
USE `mysqltest2`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `log` (
`msg` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+SET character_set_client = @saved_cs_client;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`c` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+SET character_set_client = @saved_cs_client;
INSERT INTO `t1` VALUES (1),(0),(1);
ALTER DATABASE mysqltest2 CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
diff --git a/mysql-test/r/ddl_i18n_utf8.result b/mysql-test/r/ddl_i18n_utf8.result
index d74d014d755..b8e690bfeb7 100644
--- a/mysql-test/r/ddl_i18n_utf8.result
+++ b/mysql-test/r/ddl_i18n_utf8.result
@@ -1689,12 +1689,18 @@ DELETE FROM mysqltest2.log|
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest1` /*!40100 DEFAULT CHARACTER SET cp866 */;
USE `mysqltest1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `log` (
`msg` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+SET character_set_client = @saved_cs_client;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`c` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+SET character_set_client = @saved_cs_client;
INSERT INTO `t1` VALUES (1),(0),(1);
ALTER DATABASE mysqltest1 CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
@@ -1762,12 +1768,18 @@ ALTER DATABASE mysqltest1 CHARACTER SET cp866 COLLATE cp866_general_ci ;
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest2` /*!40100 DEFAULT CHARACTER SET cp866 */;
USE `mysqltest2`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `log` (
`msg` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+SET character_set_client = @saved_cs_client;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`c` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+SET character_set_client = @saved_cs_client;
INSERT INTO `t1` VALUES (1),(0),(1);
ALTER DATABASE mysqltest2 CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
diff --git a/mysql-test/r/events_bugs.result b/mysql-test/r/events_bugs.result
index 557c8e0b477..1bfa0e84f72 100644
--- a/mysql-test/r/events_bugs.result
+++ b/mysql-test/r/events_bugs.result
@@ -611,3 +611,10 @@ id ev_nm ev_cnt
DROP TABLE event_log;
SET GLOBAL event_scheduler = OFF;
DROP DATABASE events_test;
+SET GLOBAL event_scheduler= ON;
+CREATE EVENT bug28641 ON SCHEDULE AT '2038.01.18 03:00:00'
+ DO BEGIN
+SELECT 1;
+END;|
+SET GLOBAL event_scheduler= OFF;
+DROP EVENT bug28641;
diff --git a/mysql-test/r/im_options.result b/mysql-test/r/im_options.result
index 3225db0c8c5..22bd5d5bdf6 100644
--- a/mysql-test/r/im_options.result
+++ b/mysql-test/r/im_options.result
@@ -37,9 +37,10 @@ log-slow-queries option_value
language option_value
character-sets-dir option_value
basedir option_value
+shutdown-delay option_value
skip-stack-trace option_value
-skip-innodb option_value
-skip-ndbcluster option_value
+loose-skip-innodb option_value
+loose-skip-ndbcluster option_value
nonguarded option_value
log-output option_value
SET mysqld2.server_id = 2;
@@ -57,9 +58,10 @@ log-slow-queries option_value
language option_value
character-sets-dir option_value
basedir option_value
+shutdown-delay option_value
skip-stack-trace option_value
-skip-innodb option_value
-skip-ndbcluster option_value
+loose-skip-innodb option_value
+loose-skip-ndbcluster option_value
nonguarded option_value
log-output option_value
server_id option_value
diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result
index 273374d016b..947f8abcc53 100644
--- a/mysql-test/r/innodb_mysql.result
+++ b/mysql-test/r/innodb_mysql.result
@@ -814,6 +814,34 @@ drop table if exists t1;
create table t1 (a int) engine=innodb;
alter table t1 alter a set default 1;
drop table t1;
+
+Bug#24918 drop table and lock / inconsistent between
+perm and temp tables
+
+Check transactional tables under LOCK TABLES
+
+drop table if exists t24918, t24918_tmp, t24918_trans, t24918_trans_tmp,
+t24918_access;
+create table t24918_access (id int);
+create table t24918 (id int) engine=myisam;
+create temporary table t24918_tmp (id int) engine=myisam;
+create table t24918_trans (id int) engine=innodb;
+create temporary table t24918_trans_tmp (id int) engine=innodb;
+lock table t24918 write, t24918_tmp write, t24918_trans write, t24918_trans_tmp write;
+drop table t24918;
+select * from t24918_access;
+ERROR HY000: Table 't24918_access' was not locked with LOCK TABLES
+drop table t24918_trans;
+select * from t24918_access;
+ERROR HY000: Table 't24918_access' was not locked with LOCK TABLES
+drop table t24918_trans_tmp;
+select * from t24918_access;
+ERROR HY000: Table 't24918_access' was not locked with LOCK TABLES
+drop table t24918_tmp;
+select * from t24918_access;
+ERROR HY000: Table 't24918_access' was not locked with LOCK TABLES
+unlock tables;
+drop table t24918_access;
CREATE TABLE t1 (a int, b int, PRIMARY KEY (a), KEY bkey (b)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1,2),(3,2),(2,2),(4,2),(5,2),(6,2),(7,2),(8,2);
INSERT INTO t1 SELECT a + 8, 2 FROM t1;
diff --git a/mysql-test/r/log_state.result b/mysql-test/r/log_state.result
index 38b3ebd6e98..0c6be16b9b7 100644
--- a/mysql-test/r/log_state.result
+++ b/mysql-test/r/log_state.result
@@ -153,3 +153,25 @@ select * from mysql.general_log;
event_time user_host thread_id server_id command_type argument
TIMESTAMP USER_HOST # 1 Query drop table t1
TIMESTAMP USER_HOST # 1 Query select * from mysql.general_log
+SET @old_general_log_state = @@global.general_log;
+SET @old_slow_log_state = @@global.slow_query_log;
+SET GLOBAL general_log = ON;
+SET GLOBAL slow_query_log = ON;
+FLUSH TABLES WITH READ LOCK;
+SET GLOBAL general_log = OFF;
+SET GLOBAL slow_query_log = OFF;
+UNLOCK TABLES;
+FLUSH TABLES WITH READ LOCK;
+SET GLOBAL general_log = ON;
+SET GLOBAL slow_query_log = ON;
+UNLOCK TABLES;
+SET GLOBAL READ_ONLY = ON;
+SET GLOBAL general_log = OFF;
+SET GLOBAL slow_query_log = OFF;
+SET GLOBAL READ_ONLY = OFF;
+SET GLOBAL READ_ONLY = ON;
+SET GLOBAL general_log = ON;
+SET GLOBAL slow_query_log = ON;
+SET GLOBAL READ_ONLY = OFF;
+SET GLOBAL general_log = @old_general_log_state;
+SET GLOBAL slow_query_log = @old_slow_log_state;
diff --git a/mysql-test/r/log_tables.result b/mysql-test/r/log_tables.result
index ce3dabe3a56..39349183276 100644
--- a/mysql-test/r/log_tables.result
+++ b/mysql-test/r/log_tables.result
@@ -29,30 +29,83 @@ on (mysql.general_log.command_type = join_test.command_type)
drop table join_test;
flush logs;
lock tables mysql.general_log WRITE;
-ERROR HY000: You can't write-lock a log table. Only read access is possible
+ERROR HY000: You can't use locks with log tables.
lock tables mysql.slow_log WRITE;
-ERROR HY000: You can't write-lock a log table. Only read access is possible
+ERROR HY000: You can't use locks with log tables.
lock tables mysql.general_log READ;
-ERROR HY000: You can't use usual read lock with log tables. Try READ LOCAL instead
+ERROR HY000: You can't use locks with log tables.
lock tables mysql.slow_log READ;
-ERROR HY000: You can't use usual read lock with log tables. Try READ LOCAL instead
+ERROR HY000: You can't use locks with log tables.
lock tables mysql.slow_log READ LOCAL, mysql.general_log READ LOCAL;
-unlock tables;
-lock tables mysql.general_log READ LOCAL;
+ERROR HY000: You can't use locks with log tables.
+show create table mysql.general_log;
+Table Create Table
+general_log CREATE TABLE `general_log` (
+ `event_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `user_host` mediumtext,
+ `thread_id` int(11) DEFAULT NULL,
+ `server_id` int(11) DEFAULT NULL,
+ `command_type` varchar(64) DEFAULT NULL,
+ `argument` mediumtext
+) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='General log'
+show fields from mysql.general_log;
+Field Type Null Key Default Extra
+event_time timestamp NO CURRENT_TIMESTAMP
+user_host mediumtext YES NULL
+thread_id int(11) YES NULL
+server_id int(11) YES NULL
+command_type varchar(64) YES NULL
+argument mediumtext YES NULL
+show create table mysql.slow_log;
+Table Create Table
+slow_log CREATE TABLE `slow_log` (
+ `start_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `user_host` mediumtext NOT NULL,
+ `query_time` time NOT NULL,
+ `lock_time` time NOT NULL,
+ `rows_sent` int(11) NOT NULL,
+ `rows_examined` int(11) NOT NULL,
+ `db` varchar(512) DEFAULT NULL,
+ `last_insert_id` int(11) DEFAULT NULL,
+ `insert_id` int(11) DEFAULT NULL,
+ `server_id` int(11) DEFAULT NULL,
+ `sql_text` mediumtext NOT NULL
+) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='Slow log'
+show fields from mysql.slow_log;
+Field Type Null Key Default Extra
+start_time timestamp NO CURRENT_TIMESTAMP
+user_host mediumtext NO
+query_time time NO
+lock_time time NO
+rows_sent int(11) NO
+rows_examined int(11) NO
+db varchar(512) YES NULL
+last_insert_id int(11) YES NULL
+insert_id int(11) YES NULL
+server_id int(11) YES NULL
+sql_text mediumtext NO
flush logs;
-unlock tables;
-select "Mark that we woke up from flush logs in the test"
- as "test passed";
-test passed
-Mark that we woke up from flush logs in the test
-lock tables mysql.general_log READ LOCAL;
-truncate mysql.general_log;
-unlock tables;
-select "Mark that we woke up from TRUNCATE in the test"
- as "test passed";
-test passed
-Mark that we woke up from TRUNCATE in the test
-use test;
+flush tables;
+SET GLOBAL GENERAL_LOG=ON;
+SET GLOBAL SLOW_QUERY_LOG=ON;
+show open tables;
+Database Table In_use Name_locked
+mysql general_log 0 0
+flush logs;
+show open tables;
+Database Table In_use Name_locked
+mysql general_log 0 0
+flush tables;
+show open tables;
+Database Table In_use Name_locked
+mysql general_log 0 0
+SET GLOBAL GENERAL_LOG=OFF;
+SET GLOBAL SLOW_QUERY_LOG=OFF;
+flush tables;
+show open tables;
+Database Table In_use Name_locked
+SET GLOBAL GENERAL_LOG=ON;
+SET GLOBAL SLOW_QUERY_LOG=ON;
truncate table mysql.general_log;
set names utf8;
create table bug16905 (s char(15) character set utf8 default 'пуÑто');
@@ -71,7 +124,7 @@ sleep(2)
0
select * from mysql.slow_log;
start_time user_host query_time lock_time rows_sent rows_examined db last_insert_id insert_id server_id sql_text
-TIMESTAMP USER_HOST QUERY_TIME 00:00:00 1 0 test 0 0 1 select sleep(2)
+TIMESTAMP USER_HOST QUERY_TIME 00:00:00 1 0 mysql 0 0 1 select sleep(2)
alter table mysql.general_log engine=myisam;
ERROR HY000: You cannot 'ALTER' a log table if logging is enabled
alter table mysql.slow_log engine=myisam;
@@ -158,15 +211,13 @@ TIMESTAMP USER_HOST THREAD_ID 1 Query set global slow_query_log='ON'
TIMESTAMP USER_HOST THREAD_ID 1 Query select * from mysql.general_log
flush logs;
lock tables mysql.general_log WRITE;
-ERROR HY000: You can't write-lock a log table. Only read access is possible
+ERROR HY000: You can't use locks with log tables.
lock tables mysql.slow_log WRITE;
-ERROR HY000: You can't write-lock a log table. Only read access is possible
+ERROR HY000: You can't use locks with log tables.
lock tables mysql.general_log READ;
-ERROR HY000: You can't use usual read lock with log tables. Try READ LOCAL instead
+ERROR HY000: You can't use locks with log tables.
lock tables mysql.slow_log READ;
-ERROR HY000: You can't use usual read lock with log tables. Try READ LOCAL instead
-lock tables mysql.slow_log READ LOCAL, mysql.general_log READ LOCAL;
-unlock tables;
+ERROR HY000: You can't use locks with log tables.
set global general_log='OFF';
set global slow_query_log='OFF';
set @save_storage_engine= @@session.storage_engine;
@@ -217,6 +268,7 @@ flush tables with read lock;
unlock tables;
use mysql;
lock tables general_log read local, help_category read local;
+ERROR HY000: You can't use locks with log tables.
unlock tables;
use mysql;
RENAME TABLE general_log TO renamed_general_log;
@@ -258,9 +310,9 @@ RENAME TABLE general_log TO general_log2;
set global slow_query_log='OFF';
RENAME TABLE slow_log TO slow_log2;
set global general_log='ON';
-ERROR HY000: Cannot activate 'general' log
+ERROR 42S02: Table 'mysql.general_log' doesn't exist
set global slow_query_log='ON';
-ERROR HY000: Cannot activate 'slow query' log
+ERROR 42S02: Table 'mysql.slow_log' doesn't exist
RENAME TABLE general_log2 TO general_log;
RENAME TABLE slow_log2 TO slow_log;
set global general_log='ON';
@@ -355,3 +407,192 @@ SET SESSION long_query_time =@old_long_query_time;
FLUSH LOGS;
ALTER TABLE mysql.slow_log DROP COLUMN seq;
ALTER TABLE mysql.slow_log ENGINE = CSV;
+drop procedure if exists proc25422_truncate_slow;
+drop procedure if exists proc25422_truncate_general;
+drop procedure if exists proc25422_alter_slow;
+drop procedure if exists proc25422_alter_general;
+use test//
+create procedure proc25422_truncate_slow (loops int)
+begin
+declare v1 int default 0;
+while v1 < loops do
+truncate mysql.slow_log;
+set v1 = v1 + 1;
+end while;
+end//
+create procedure proc25422_truncate_general (loops int)
+begin
+declare v1 int default 0;
+while v1 < loops do
+truncate mysql.general_log;
+set v1 = v1 + 1;
+end while;
+end//
+create procedure proc25422_alter_slow (loops int)
+begin
+declare v1 int default 0;
+declare ER_BAD_LOG_STATEMENT condition for 1575;
+declare continue handler for ER_BAD_LOG_STATEMENT begin end;
+while v1 < loops do
+set @old_log_state = @@global.slow_query_log;
+set global slow_query_log = 'OFF';
+alter table mysql.slow_log engine = CSV;
+set global slow_query_log = @old_log_state;
+set v1 = v1 + 1;
+end while;
+end//
+create procedure proc25422_alter_general (loops int)
+begin
+declare v1 int default 0;
+declare ER_BAD_LOG_STATEMENT condition for 1575;
+declare continue handler for ER_BAD_LOG_STATEMENT begin end;
+while v1 < loops do
+set @old_log_state = @@global.general_log;
+set global general_log = 'OFF';
+alter table mysql.general_log engine = CSV;
+set global general_log = @old_log_state;
+set v1 = v1 + 1;
+end while;
+end//
+"Serial test (proc25422_truncate_slow)"
+call proc25422_truncate_slow(100);
+"Serial test (proc25422_truncate_general)"
+call proc25422_truncate_general(100);
+"Serial test (proc25422_alter_slow)"
+call proc25422_alter_slow(100);
+"Serial test (proc25422_alter_general)"
+call proc25422_alter_general(100);
+"Parallel test"
+call proc25422_truncate_slow(100);
+call proc25422_truncate_slow(100);
+call proc25422_truncate_general(100);
+call proc25422_truncate_general(100);
+call proc25422_alter_slow(100);
+call proc25422_alter_slow(100);
+call proc25422_alter_general(100);
+call proc25422_alter_general(100);
+drop procedure proc25422_truncate_slow;
+drop procedure proc25422_truncate_general;
+drop procedure proc25422_alter_slow;
+drop procedure proc25422_alter_general;
+FLUSH TABLE mysql.general_log;
+show warnings;
+Level Code Message
+FLUSH TABLE mysql.slow_log;
+show warnings;
+Level Code Message
+DROP TABLE IF EXISTS `db_17876.slow_log_data`;
+DROP TABLE IF EXISTS `db_17876.general_log_data`;
+DROP PROCEDURE IF EXISTS `db_17876.archiveSlowLog`;
+DROP PROCEDURE IF EXISTS `db_17876.archiveGeneralLog`;
+DROP DATABASE IF EXISTS `db_17876`;
+CREATE DATABASE db_17876;
+CREATE TABLE `db_17876.slow_log_data` (
+`start_time` timestamp default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+`user_host` mediumtext ,
+`query_time` time ,
+`lock_time` time ,
+`rows_sent` int(11) ,
+`rows_examined` int(11) ,
+`db` varchar(512) default NULL,
+`last_insert_id` int(11) default NULL,
+`insert_id` int(11) default NULL,
+`server_id` int(11) default NULL,
+`sql_text` mediumtext
+);
+CREATE TABLE `db_17876.general_log_data` (
+`event_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+`user_host` mediumtext,
+`thread_id` int(11) DEFAULT NULL,
+`server_id` int(11) DEFAULT NULL,
+`command_type` varchar(64) DEFAULT NULL,
+`argument` mediumtext
+);
+CREATE procedure `db_17876.archiveSlowLog`()
+BEGIN
+DECLARE start_time, query_time, lock_time CHAR(20);
+DECLARE user_host MEDIUMTEXT;
+DECLARE rows_set, rows_examined, last_insert_id, insert_id, server_id INT;
+DECLARE dbname MEDIUMTEXT;
+DECLARE sql_text BLOB;
+DECLARE done INT DEFAULT 0;
+DECLARE ER_SP_FETCH_NO_DATA CONDITION for 1329;
+DECLARE cur1 CURSOR FOR SELECT * FROM mysql.slow_log;
+OPEN cur1;
+REPEAT
+BEGIN
+BEGIN
+DECLARE CONTINUE HANDLER FOR ER_SP_FETCH_NO_DATA SET done = 1;
+FETCH cur1 INTO
+start_time, user_host, query_time, lock_time,
+rows_set, rows_examined, dbname, last_insert_id,
+insert_id, server_id, sql_text;
+END;
+IF NOT done THEN
+BEGIN
+INSERT INTO
+`db_17876.slow_log_data`
+ VALUES(start_time, user_host, query_time, lock_time, rows_set, rows_examined,
+dbname, last_insert_id, insert_id, server_id, sql_text);
+END;
+END IF;
+END;
+UNTIL done END REPEAT;
+CLOSE cur1;
+TRUNCATE mysql.slow_log;
+END //
+CREATE procedure `db_17876.archiveGeneralLog`()
+BEGIN
+DECLARE event_time CHAR(20);
+DECLARE user_host, argument MEDIUMTEXT;
+DECLARE thread_id, server_id INT;
+DECLARE sql_text BLOB;
+DECLARE done INT DEFAULT 0;
+DECLARE command_type VARCHAR(64);
+DECLARE ER_SP_FETCH_NO_DATA CONDITION for 1329;
+DECLARE cur1 CURSOR FOR SELECT * FROM mysql.general_log;
+OPEN cur1;
+REPEAT
+BEGIN
+BEGIN
+DECLARE CONTINUE HANDLER FOR ER_SP_FETCH_NO_DATA SET done = 1;
+FETCH cur1 INTO
+event_time, user_host, thread_id, server_id,
+command_type, argument;
+END;
+IF NOT done THEN
+BEGIN
+INSERT INTO
+`db_17876.general_log_data`
+ VALUES(event_time, user_host, thread_id, server_id,
+command_type, argument);
+END;
+END IF;
+END;
+UNTIL done END REPEAT;
+CLOSE cur1;
+TRUNCATE mysql.general_log;
+END //
+SET @old_general_log_state = @@global.general_log;
+SET @old_slow_log_state = @@global.slow_query_log;
+SET GLOBAL general_log = ON;
+SET GLOBAL slow_query_log = ON;
+select "put something into general_log";
+put something into general_log
+put something into general_log
+select "... and something more ...";
+... and something more ...
+... and something more ...
+call `db_17876.archiveSlowLog`();
+call `db_17876.archiveGeneralLog`();
+SET GLOBAL general_log = OFF;
+SET GLOBAL slow_query_log = OFF;
+call `db_17876.archiveSlowLog`();
+call `db_17876.archiveGeneralLog`();
+DROP TABLE `db_17876.slow_log_data`;
+DROP TABLE `db_17876.general_log_data`;
+DROP PROCEDURE IF EXISTS `db_17876.archiveSlowLog`;
+DROP PROCEDURE IF EXISTS `db_17876.archiveGeneralLog`;
+DROP DATABASE IF EXISTS `db_17876`;
+SET GLOBAL general_log = @old_general_log_state;
+SET GLOBAL slow_query_log = @old_slow_log_state;
diff --git a/mysql-test/r/mysqldump-max.result b/mysql-test/r/mysqldump-max.result
index e78fc4d386a..2d118092a2c 100644
--- a/mysql-test/r/mysqldump-max.result
+++ b/mysql-test/r/mysqldump-max.result
@@ -93,55 +93,73 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l
USE `test`;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`id` int(8) DEFAULT NULL,
`name` varchar(32) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
INSERT DELAYED IGNORE INTO `t1` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
DROP TABLE IF EXISTS `t2`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t2` (
`id` int(8) DEFAULT NULL,
`name` varchar(32) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
/*!40000 ALTER TABLE `t2` DISABLE KEYS */;
INSERT DELAYED IGNORE INTO `t2` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
/*!40000 ALTER TABLE `t2` ENABLE KEYS */;
DROP TABLE IF EXISTS `t3`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t3` (
`id` int(8) DEFAULT NULL,
`name` varchar(32) DEFAULT NULL
) ENGINE=MEMORY DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
/*!40000 ALTER TABLE `t3` DISABLE KEYS */;
INSERT DELAYED IGNORE INTO `t3` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
/*!40000 ALTER TABLE `t3` ENABLE KEYS */;
DROP TABLE IF EXISTS `t4`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t4` (
`id` int(8) DEFAULT NULL,
`name` varchar(32) DEFAULT NULL
) ENGINE=MEMORY DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
/*!40000 ALTER TABLE `t4` DISABLE KEYS */;
INSERT DELAYED IGNORE INTO `t4` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
/*!40000 ALTER TABLE `t4` ENABLE KEYS */;
DROP TABLE IF EXISTS `t5`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t5` (
`id` int(8) DEFAULT NULL,
`name` varchar(32) DEFAULT NULL
) ENGINE=ARCHIVE DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
/*!40000 ALTER TABLE `t5` DISABLE KEYS */;
INSERT DELAYED IGNORE INTO `t5` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
/*!40000 ALTER TABLE `t5` ENABLE KEYS */;
DROP TABLE IF EXISTS `t6`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t6` (
`id` int(8) DEFAULT NULL,
`name` varchar(32) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
/*!40000 ALTER TABLE `t6` DISABLE KEYS */;
INSERT IGNORE INTO `t6` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
@@ -172,55 +190,73 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l
USE `test`;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`id` int(8) DEFAULT NULL,
`name` varchar(32) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
INSERT DELAYED INTO `t1` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
DROP TABLE IF EXISTS `t2`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t2` (
`id` int(8) DEFAULT NULL,
`name` varchar(32) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
/*!40000 ALTER TABLE `t2` DISABLE KEYS */;
INSERT DELAYED INTO `t2` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
/*!40000 ALTER TABLE `t2` ENABLE KEYS */;
DROP TABLE IF EXISTS `t3`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t3` (
`id` int(8) DEFAULT NULL,
`name` varchar(32) DEFAULT NULL
) ENGINE=MEMORY DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
/*!40000 ALTER TABLE `t3` DISABLE KEYS */;
INSERT DELAYED INTO `t3` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
/*!40000 ALTER TABLE `t3` ENABLE KEYS */;
DROP TABLE IF EXISTS `t4`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t4` (
`id` int(8) DEFAULT NULL,
`name` varchar(32) DEFAULT NULL
) ENGINE=MEMORY DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
/*!40000 ALTER TABLE `t4` DISABLE KEYS */;
INSERT DELAYED INTO `t4` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
/*!40000 ALTER TABLE `t4` ENABLE KEYS */;
DROP TABLE IF EXISTS `t5`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t5` (
`id` int(8) DEFAULT NULL,
`name` varchar(32) DEFAULT NULL
) ENGINE=ARCHIVE DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
/*!40000 ALTER TABLE `t5` DISABLE KEYS */;
INSERT DELAYED INTO `t5` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
/*!40000 ALTER TABLE `t5` ENABLE KEYS */;
DROP TABLE IF EXISTS `t6`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t6` (
`id` int(8) DEFAULT NULL,
`name` varchar(32) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
/*!40000 ALTER TABLE `t6` DISABLE KEYS */;
INSERT INTO `t6` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result
index 1fa18482b9c..58bcac42f9c 100644
--- a/mysql-test/r/mysqldump.result
+++ b/mysql-test/r/mysqldump.result
@@ -29,9 +29,12 @@ DROP TABLE t1;
CREATE TABLE t1 (a decimal(64, 20));
INSERT INTO t1 VALUES ("1234567890123456789012345678901234567890"),
("0987654321098765432109876543210987654321");
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` decimal(64,20) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
INSERT INTO `t1` VALUES ('1234567890123456789012345678901234567890.00000000000000000000'),('987654321098765432109876543210987654321.00000000000000000000');
DROP TABLE t1;
#
@@ -41,9 +44,12 @@ CREATE TABLE t1 (a double);
INSERT INTO t1 VALUES ('-9e999999');
Warnings:
Warning 1264 Out of range value for column 'a' at row 1
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` double DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
INSERT INTO `t1` VALUES (RES);
DROP TABLE t1;
#
@@ -59,15 +65,21 @@ INSERT INTO t1 VALUES ('1.2345', 2.3456);
INSERT INTO t1 VALUES ("1.2345", 2.3456);
ERROR 42S22: Unknown column '1.2345' in 'field list'
SET SQL_MODE=@OLD_SQL_MODE;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` decimal(10,5) DEFAULT NULL,
`b` float DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
INSERT INTO `t1` VALUES ('1.23450',2.3456),('1.23450',2.3456),('1.23450',2.3456),('1.23450',2.3456),('1.23450',2.3456);
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` decimal(10,5) DEFAULT NULL,
`b` float DEFAULT NULL
);
+SET character_set_client = @saved_cs_client;
INSERT INTO `t1` VALUES ('1.23450',2.3456),('1.23450',2.3456),('1.23450',2.3456),('1.23450',2.3456),('1.23450',2.3456);
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
@@ -81,10 +93,13 @@ INSERT INTO `t1` VALUES ('1.23450',2.3456),('1.23450',2.3456),('1.23450',2.3456)
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` decimal(10,5) DEFAULT NULL,
`b` float DEFAULT NULL
);
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -107,10 +122,13 @@ UNLOCK TABLES;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` decimal(10,5) DEFAULT NULL,
`b` float DEFAULT NULL
);
+SET character_set_client = @saved_cs_client;
INSERT INTO `t1` VALUES ('1.23450',2.3456),('1.23450',2.3456),('1.23450',2.3456),('1.23450',2.3456),('1.23450',2.3456);
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
@@ -186,9 +204,12 @@ INSERT INTO t1 VALUES (_koi8r x'C1C2C3C4C5'), (NULL);
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` varchar(255) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=koi8r;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -219,9 +240,12 @@ INSERT INTO t1 VALUES (1), (2);
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,MYSQL40' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) TYPE=MyISAM;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -242,9 +266,12 @@ UNLOCK TABLES;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,MYSQL323' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) TYPE=MyISAM;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -263,9 +290,12 @@ DROP TABLE t1;
# Bug #2592 'mysqldump doesn't quote "tricky" names correctly'
#
create table ```a` (i int);
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE ```a` (
`i` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
drop table ```a`;
#
# Bug #2591 "mysqldump quotes names inconsistently"
@@ -283,9 +313,12 @@ create table t1(a int);
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -308,9 +341,12 @@ UNLOCK TABLES;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,ANSI' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS "t1";
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE "t1" (
"a" int(11) DEFAULT NULL
);
+SET character_set_client = @saved_cs_client;
LOCK TABLES "t1" WRITE;
/*!40000 ALTER TABLE "t1" DISABLE KEYS */;
@@ -336,9 +372,12 @@ set global sql_mode='ANSI_QUOTES';
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -361,9 +400,12 @@ UNLOCK TABLES;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,ANSI' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS "t1";
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE "t1" (
"a" int(11) DEFAULT NULL
);
+SET character_set_client = @saved_cs_client;
LOCK TABLES "t1" WRITE;
/*!40000 ALTER TABLE "t1" DISABLE KEYS */;
@@ -393,9 +435,12 @@ insert into t1 values (1),(2),(3);
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
@@ -484,9 +529,12 @@ INSERT INTO t1 VALUES (_latin1 'ÄÖÜß');
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` char(10) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -517,9 +565,12 @@ UNLOCK TABLES;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,MYSQL323' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` char(10) DEFAULT NULL
) TYPE=MyISAM;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -540,9 +591,12 @@ UNLOCK TABLES;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,MYSQL323' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` char(10) DEFAULT NULL
) TYPE=MyISAM;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -563,9 +617,12 @@ UNLOCK TABLES;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,MYSQL323' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` char(10) DEFAULT NULL
) TYPE=MyISAM;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -599,9 +656,12 @@ INSERT INTO t2 VALUES (4),(5),(6);
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t2`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t2` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t2` WRITE;
/*!40000 ALTER TABLE `t2` DISABLE KEYS */;
@@ -637,9 +697,12 @@ INSERT INTO `t1` VALUES (0x602010000280100005E71A);
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`b` blob
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -675,9 +738,12 @@ INSERT INTO t1 VALUES (4),(5),(6);
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -706,9 +772,12 @@ UNLOCK TABLES;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
INSERT DELAYED IGNORE INTO `t1` VALUES (1),(2),(3),(4),(5),(6);
@@ -1072,6 +1141,8 @@ insert into t1 (F_8d3bba7425e7c98c50f52ca1b52d3735) values (1);
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`F_c4ca4238a0b923820dcc509a6f75849b` int(11) DEFAULT NULL,
`F_c81e728d9d4c2f636f067f89cc14862c` int(11) DEFAULT NULL,
@@ -1404,6 +1475,7 @@ CREATE TABLE `t1` (
`F_6faa8040da20ef399b63a72d0e4ab575` int(11) DEFAULT NULL,
`F_fe73f687e5bc5280214e0486b273a5f9` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -1444,9 +1516,12 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l
USE `test`;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -1485,13 +1560,19 @@ INSERT INTO t2 VALUES (1), (2);
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS `t2`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t2` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
@@ -1514,13 +1595,19 @@ CREATE TABLE `t2` (
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS `t2`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t2` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
@@ -1720,17 +1807,26 @@ create table t3(a int);
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t3`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t3` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS `t2`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t2` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
@@ -1760,9 +1856,12 @@ mysqldump: Got error: 1064: You have an error in your SQL syntax; check the manu
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
@@ -1793,12 +1892,15 @@ insert into t1 values (0815, 4711, 2006);
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,ANSI' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS "t1";
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE "t1" (
"a b" int(11) NOT NULL DEFAULT '0',
"c""d" int(11) NOT NULL DEFAULT '0',
"e`f" int(11) NOT NULL DEFAULT '0',
PRIMARY KEY ("a b","c""d","e`f")
);
+SET character_set_client = @saved_cs_client;
LOCK TABLES "t1" WRITE;
/*!40000 ALTER TABLE "t1" DISABLE KEYS */;
@@ -1824,12 +1926,15 @@ UNLOCK TABLES;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a b` int(11) NOT NULL DEFAULT '0',
`c"d` int(11) NOT NULL DEFAULT '0',
`e``f` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`a b`,`c"d`,`e``f`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -1875,10 +1980,13 @@ create view v2 as select * from t2 where a like 'a%' with check option;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t2`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t2` (
`a` varchar(30) DEFAULT NULL,
KEY `a` (`a`(5))
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t2` WRITE;
/*!40000 ALTER TABLE `t2` DISABLE KEYS */;
@@ -1887,9 +1995,12 @@ INSERT INTO `t2` VALUES ('alfred'),('angie'),('bingo'),('waffle'),('lemon');
UNLOCK TABLES;
DROP TABLE IF EXISTS `v2`;
/*!50001 DROP VIEW IF EXISTS `v2`*/;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
/*!50001 CREATE TABLE `v2` (
`a` varchar(30)
) */;
+SET character_set_client = @saved_cs_client;
/*!50001 DROP TABLE `v2`*/;
/*!50001 DROP VIEW IF EXISTS `v2`*/;
/*!50001 SET @saved_cs_client = @@character_set_client */;
@@ -1968,9 +2079,12 @@ create view v1 as select * from t1;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -1978,9 +2092,12 @@ LOCK TABLES `t1` WRITE;
UNLOCK TABLES;
DROP TABLE IF EXISTS `v1`;
/*!50001 DROP VIEW IF EXISTS `v1`*/;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
/*!50001 CREATE TABLE `v1` (
`a` int(11)
) */;
+SET character_set_client = @saved_cs_client;
/*!50001 DROP TABLE `v1`*/;
/*!50001 DROP VIEW IF EXISTS `v1`*/;
/*!50001 SET @saved_cs_client = @@character_set_client */;
@@ -2034,10 +2151,13 @@ create view v2 as select * from t2 where a like 'a%' with check option;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t2`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t2` (
`a` varchar(30) DEFAULT NULL,
KEY `a` (`a`(5))
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t2` WRITE;
/*!40000 ALTER TABLE `t2` DISABLE KEYS */;
@@ -2046,9 +2166,12 @@ INSERT INTO `t2` VALUES ('alfred'),('angie'),('bingo'),('waffle'),('lemon');
UNLOCK TABLES;
DROP TABLE IF EXISTS `v2`;
/*!50001 DROP VIEW IF EXISTS `v2`*/;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
/*!50001 CREATE TABLE `v2` (
`a` varchar(30)
) */;
+SET character_set_client = @saved_cs_client;
/*!50001 DROP TABLE `v2`*/;
/*!50001 DROP VIEW IF EXISTS `v2`*/;
/*!50001 SET @saved_cs_client = @@character_set_client */;
@@ -2095,9 +2218,12 @@ INSERT INTO t1 VALUES ('\'');
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` char(10) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -2138,11 +2264,14 @@ select v3.a from v3, v1 where v1.a=v3.a and v3.b=3 limit 1;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL,
`c` varchar(30) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -2151,23 +2280,32 @@ INSERT INTO `t1` VALUES (1,2,'one'),(2,4,'two'),(3,6,'three');
UNLOCK TABLES;
DROP TABLE IF EXISTS `v1`;
/*!50001 DROP VIEW IF EXISTS `v1`*/;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
/*!50001 CREATE TABLE `v1` (
`a` int(11),
`b` int(11),
`c` varchar(30)
) */;
+SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS `v2`;
/*!50001 DROP VIEW IF EXISTS `v2`*/;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
/*!50001 CREATE TABLE `v2` (
`a` int(11)
) */;
+SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS `v3`;
/*!50001 DROP VIEW IF EXISTS `v3`*/;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
/*!50001 CREATE TABLE `v3` (
`a` int(11),
`b` int(11),
`c` varchar(30)
) */;
+SET character_set_client = @saved_cs_client;
/*!50001 DROP TABLE `v1`*/;
/*!50001 DROP VIEW IF EXISTS `v1`*/;
/*!50001 SET @saved_cs_client = @@character_set_client */;
@@ -2285,10 +2423,13 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l
USE `test`;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL,
`b` bigint(20) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -2354,9 +2495,12 @@ DELIMITER ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
DROP TABLE IF EXISTS `t2`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t2` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t2` WRITE;
/*!40000 ALTER TABLE `t2` DISABLE KEYS */;
@@ -2408,10 +2552,13 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l
USE `test`;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL,
`b` bigint(20) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -2419,9 +2566,12 @@ INSERT INTO `t1` VALUES (1,NULL),(2,NULL),(4,NULL),(11,NULL);
/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
UNLOCK TABLES;
DROP TABLE IF EXISTS `t2`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t2` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t2` WRITE;
/*!40000 ALTER TABLE `t2` DISABLE KEYS */;
@@ -2545,9 +2695,12 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l
USE `test`;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`id` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -2693,10 +2846,13 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l
USE `test`;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`d` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY `d` (`d`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -2727,10 +2883,13 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l
USE `test`;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`d` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY `d` (`d`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -2777,9 +2936,12 @@ a2
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,ANSI' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS "t1 test";
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE "t1 test" (
"a1" int(11) DEFAULT NULL
);
+SET character_set_client = @saved_cs_client;
LOCK TABLES "t1 test" WRITE;
/*!40000 ALTER TABLE "t1 test" DISABLE KEYS */;
@@ -2803,9 +2965,12 @@ DELIMITER ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
DROP TABLE IF EXISTS "t2 test";
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE "t2 test" (
"a2" int(11) DEFAULT NULL
);
+SET character_set_client = @saved_cs_client;
LOCK TABLES "t2 test" WRITE;
/*!40000 ALTER TABLE "t2 test" DISABLE KEYS */;
@@ -2854,11 +3019,14 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l
USE `test`;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL,
`b` varchar(32) DEFAULT NULL,
`c` varchar(32) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -2867,25 +3035,34 @@ INSERT INTO `t1` VALUES (1,'first value','xxxx'),(2,'second value','tttt'),(3,'t
UNLOCK TABLES;
DROP TABLE IF EXISTS `v0`;
/*!50001 DROP VIEW IF EXISTS `v0`*/;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
/*!50001 CREATE TABLE `v0` (
`a` int(11),
`b` varchar(32),
`c` varchar(32)
) */;
+SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS `v1`;
/*!50001 DROP VIEW IF EXISTS `v1`*/;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
/*!50001 CREATE TABLE `v1` (
`a` int(11),
`b` varchar(32),
`c` varchar(32)
) */;
+SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS `v2`;
/*!50001 DROP VIEW IF EXISTS `v2`*/;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
/*!50001 CREATE TABLE `v2` (
`a` int(11),
`b` varchar(32),
`c` varchar(32)
) */;
+SET character_set_client = @saved_cs_client;
USE `test`;
/*!50001 DROP TABLE `v0`*/;
@@ -2973,9 +3150,12 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l
USE `test`;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -3029,10 +3209,13 @@ insert into t1 values ('','');
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` binary(1) DEFAULT NULL,
`b` blob
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -3061,10 +3244,13 @@ UNLOCK TABLES;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` binary(1) DEFAULT NULL,
`b` blob
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -3237,9 +3423,12 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqldump_test_db` /*!40100 DEFAULT CH
USE `mysqldump_test_db`;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`id` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -3248,9 +3437,12 @@ INSERT INTO `t1` VALUES (1232131),(4711),(3231),(815);
UNLOCK TABLES;
DROP TABLE IF EXISTS `v1`;
/*!50001 DROP VIEW IF EXISTS `v1`*/;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
/*!50001 CREATE TABLE `v1` (
`id` int(11)
) */;
+SET character_set_client = @saved_cs_client;
USE `mysqldump_test_db`;
/*!50001 DROP TABLE `v1`*/;
@@ -3293,18 +3485,24 @@ create view nasishnasifu as select mysqldump_tables.basetable.id from mysqldump_
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqldump_tables` /*!40100 DEFAULT CHARACTER SET latin1 */;
USE `mysqldump_tables`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `basetable` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`tag` varchar(64) DEFAULT NULL,
UNIQUE KEY `id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqldump_views` /*!40100 DEFAULT CHARACTER SET latin1 */;
USE `mysqldump_views`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
/*!50001 CREATE TABLE `nasishnasifu` (
`id` bigint(20) unsigned
) */;
+SET character_set_client = @saved_cs_client;
USE `mysqldump_tables`;
@@ -3461,22 +3659,31 @@ CREATE TABLE t1 (a int) ENGINE=merge UNION=(t2, t3);
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 UNION=(`t2`,`t3`);
+SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS `t2`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t2` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t2` WRITE;
/*!40000 ALTER TABLE `t2` DISABLE KEYS */;
/*!40000 ALTER TABLE `t2` ENABLE KEYS */;
UNLOCK TABLES;
DROP TABLE IF EXISTS `t3`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t3` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t3` WRITE;
/*!40000 ALTER TABLE `t3` DISABLE KEYS */;
@@ -3556,10 +3763,13 @@ drop database mysqldump_test_db;
#
CREATE TABLE t1 (c1 INT, c2 LONGBLOB);
INSERT INTO t1 SET c1=11, c2=REPEAT('q',509);
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`c1` int(11) DEFAULT NULL,
`c2` longblob
);
+SET character_set_client = @saved_cs_client;
INSERT INTO `t1` VALUES (11,0x7171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171);
DROP TABLE t1;
#
@@ -3614,10 +3824,13 @@ INSERT INTO t1 VALUES (3,4), (4,5);
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -3881,9 +4094,12 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqldump_test_db` /*!40100 DEFAULT CH
USE `mysqldump_test_db`;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`id` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -3892,9 +4108,12 @@ INSERT INTO `t1` VALUES (1232131),(4711),(3231),(815);
UNLOCK TABLES;
DROP TABLE IF EXISTS `v1`;
/*!50001 DROP VIEW IF EXISTS `v1`*/;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
/*!50001 CREATE TABLE `v1` (
`id` int(11)
) */;
+SET character_set_client = @saved_cs_client;
USE `mysqldump_test_db`;
/*!50001 DROP TABLE `v1`*/;
@@ -3925,5 +4144,38 @@ drop view v1;
drop table t1;
drop database mysqldump_test_db;
#
+# Bug #30027: mysqldump does not dump views properly.
+#
+
+# Cleanup.
+DROP DATABASE IF EXISTS mysqldump_test_db;
+
+# Create objects.
+CREATE DATABASE mysqldump_test_db;
+set names koi8r;
+CREATE VIEW mysqldump_test_db.v2 AS SELECT 1 AS ËÏÌÏÎËÁ1;
+CREATE VIEW mysqldump_test_db.v1 AS SELECT ËÏÌÏÎËÁ1 FROM mysqldump_test_db.v2;
+set names latin1;
+
+# Dump mysqldump_test_db to bug30027.sql.
+
+# Drop mysqldump_test_db.
+DROP DATABASE mysqldump_test_db;
+
+# Restore mysqldump_test_db from bug30027.sql.
+
+# Check the view.
+set names utf8;
+SHOW CREATE VIEW mysqldump_test_db.v1;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqldump_test_db`.`v1` AS select `v2`.`колонка1` AS `колонка1` from `mysqldump_test_db`.`v2` koi8r koi8r_general_ci
+SHOW CREATE VIEW mysqldump_test_db.v2;
+View Create View character_set_client collation_connection
+v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqldump_test_db`.`v2` AS select 1 AS `колонка1` koi8r koi8r_general_ci
+set names latin1;
+
+# Cleanup.
+DROP DATABASE mysqldump_test_db;
+#
# End of 5.1 tests
#
diff --git a/mysql-test/r/openssl_1.result b/mysql-test/r/openssl_1.result
index 5e29e30732f..a042d0a5dc3 100644
--- a/mysql-test/r/openssl_1.result
+++ b/mysql-test/r/openssl_1.result
@@ -99,9 +99,12 @@ INSERT INTO t1 VALUES (1), (2);
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
);
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -130,9 +133,12 @@ UNLOCK TABLES;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
);
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -161,9 +167,12 @@ UNLOCK TABLES;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
);
+SET character_set_client = @saved_cs_client;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index 9214d470b37..341a6b7cd43 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -1850,61 +1850,57 @@ create procedure proc_1() flush tables;
flush tables;
show open tables from mysql;
Database Table In_use Name_locked
-mysql general_log 1 0
-mysql slow_log 1 0
+mysql general_log 0 0
select Host, User from mysql.user limit 0;
Host User
select Host, Db from mysql.host limit 0;
Host Db
show open tables from mysql;
Database Table In_use Name_locked
-mysql general_log 1 0
-mysql slow_log 1 0
+mysql general_log 0 0
+mysql slow_log 0 0
mysql host 0 0
mysql user 0 0
call proc_1();
show open tables from mysql;
Database Table In_use Name_locked
-mysql general_log 1 0
-mysql slow_log 1 0
+mysql general_log 0 0
select Host, User from mysql.user limit 0;
Host User
select Host, Db from mysql.host limit 0;
Host Db
show open tables from mysql;
Database Table In_use Name_locked
-mysql general_log 1 0
-mysql slow_log 1 0
+mysql general_log 0 0
+mysql slow_log 0 0
mysql host 0 0
mysql user 0 0
call proc_1();
show open tables from mysql;
Database Table In_use Name_locked
-mysql general_log 1 0
-mysql slow_log 1 0
+mysql general_log 0 0
select Host, User from mysql.user limit 0;
Host User
select Host, Db from mysql.host limit 0;
Host Db
show open tables from mysql;
Database Table In_use Name_locked
-mysql general_log 1 0
-mysql slow_log 1 0
+mysql general_log 0 0
+mysql slow_log 0 0
mysql host 0 0
mysql user 0 0
call proc_1();
show open tables from mysql;
Database Table In_use Name_locked
-mysql general_log 1 0
-mysql slow_log 1 0
+mysql general_log 0 0
select Host, User from mysql.user limit 0;
Host User
select Host, Db from mysql.host limit 0;
Host Db
show open tables from mysql;
Database Table In_use Name_locked
-mysql general_log 1 0
-mysql slow_log 1 0
+mysql general_log 0 0
+mysql slow_log 0 0
mysql host 0 0
mysql user 0 0
flush tables;
@@ -1922,54 +1918,50 @@ select Host, Db from mysql.host limit 0;
Host Db
show open tables from mysql;
Database Table In_use Name_locked
-mysql general_log 1 0
-mysql slow_log 1 0
-mysql host 0 0
mysql user 0 0
+mysql general_log 0 0
+mysql host 0 0
prepare abc from "flush tables";
execute abc;
show open tables from mysql;
Database Table In_use Name_locked
-mysql general_log 1 0
-mysql slow_log 1 0
+mysql general_log 0 0
select Host, User from mysql.user limit 0;
Host User
select Host, Db from mysql.host limit 0;
Host Db
show open tables from mysql;
Database Table In_use Name_locked
-mysql general_log 1 0
-mysql slow_log 1 0
+mysql general_log 0 0
+mysql slow_log 0 0
mysql host 0 0
mysql user 0 0
execute abc;
show open tables from mysql;
Database Table In_use Name_locked
-mysql general_log 1 0
-mysql slow_log 1 0
+mysql general_log 0 0
select Host, User from mysql.user limit 0;
Host User
select Host, Db from mysql.host limit 0;
Host Db
show open tables from mysql;
Database Table In_use Name_locked
-mysql general_log 1 0
-mysql slow_log 1 0
+mysql general_log 0 0
+mysql slow_log 0 0
mysql host 0 0
mysql user 0 0
execute abc;
show open tables from mysql;
Database Table In_use Name_locked
-mysql general_log 1 0
-mysql slow_log 1 0
+mysql general_log 0 0
select Host, User from mysql.user limit 0;
Host User
select Host, Db from mysql.host limit 0;
Host Db
show open tables from mysql;
Database Table In_use Name_locked
-mysql general_log 1 0
-mysql slow_log 1 0
+mysql general_log 0 0
+mysql slow_log 0 0
mysql host 0 0
mysql user 0 0
flush tables;
diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result
index 2bdd29602fb..3a20cbb11da 100644
--- a/mysql-test/r/show_check.result
+++ b/mysql-test/r/show_check.result
@@ -251,14 +251,13 @@ drop table t1;
flush tables;
show open tables;
Database Table In_use Name_locked
-mysql general_log 1 0
-mysql slow_log 1 0
+mysql general_log 0 0
create table t1(n int);
insert into t1 values (1);
show open tables;
Database Table In_use Name_locked
-mysql general_log 1 0
-mysql slow_log 1 0
+mysql general_log 0 0
+mysql slow_log 0 0
test t1 0 0
drop table t1;
create table t1 (a int not null, b VARCHAR(10), INDEX (b) ) AVG_ROW_LENGTH=10 CHECKSUM=1 COMMENT="test" ENGINE=MYISAM MIN_ROWS=10 MAX_ROWS=100 PACK_KEYS=1 DELAY_KEY_WRITE=1 ROW_FORMAT=fixed;
@@ -672,24 +671,23 @@ SELECT 1 FROM mysql.db, mysql.proc, mysql.user, mysql.time_zone, mysql.time_zone
1
SHOW OPEN TABLES;
Database Table In_use Name_locked
-mysql proc 0 0
+mysql db 0 0
test urkunde 0 0
mysql time_zone 0 0
-mysql db 0 0
+mysql general_log 0 0
test txt1 0 0
-mysql slow_log 1 0
+mysql proc 0 0
test tyt2 0 0
-mysql general_log 1 0
mysql user 0 0
mysql time_zone_name 0 0
SHOW OPEN TABLES FROM mysql;
Database Table In_use Name_locked
-mysql proc 0 0
-mysql time_zone 0 0
mysql db 0 0
-mysql slow_log 1 0
-mysql general_log 1 0
+mysql time_zone 0 0
+mysql general_log 0 0
+mysql slow_log 0 0
mysql user 0 0
+mysql proc 0 0
mysql time_zone_name 0 0
SHOW OPEN TABLES FROM mysql LIKE 'u%';
Database Table In_use Name_locked
@@ -702,16 +700,15 @@ test tyt2 0 0
mysql time_zone_name 0 0
SHOW OPEN TABLES LIKE '%o%';
Database Table In_use Name_locked
-mysql proc 0 0
mysql time_zone 0 0
-mysql slow_log 1 0
-mysql general_log 1 0
+mysql general_log 0 0
+mysql slow_log 0 0
+mysql proc 0 0
mysql time_zone_name 0 0
FLUSH TABLES;
SHOW OPEN TABLES;
Database Table In_use Name_locked
-mysql general_log 1 0
-mysql slow_log 1 0
+mysql general_log 0 0
DROP TABLE txt1;
DROP TABLE tyt2;
DROP TABLE urkunde;
@@ -1148,6 +1145,26 @@ DROP TABLE t1;
DROP VIEW v1;
DROP PROCEDURE p1;
DROP FUNCTION f1;
+set names koi8r;
+DROP DATABASE IF EXISTS mysqltest1;
+CREATE DATABASE mysqltest1;
+use mysqltest1;
+CREATE TABLE t1(ËÏÌÏÎËÁ1 INT);
+
+---> Dumping mysqltest1 to show_check.mysqltest1.sql
+
+
+DROP DATABASE mysqltest1;
+
+
+---> Restoring mysqltest1...
+SHOW CREATE TABLE mysqltest1.t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `ËÏÌÏÎËÁ1` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP DATABASE mysqltest1;
+use test;
flush status;
show variables like "log_queries_not_using_indexes";
Variable_name Value
diff --git a/mysql-test/r/sp-prelocking.result b/mysql-test/r/sp-prelocking.result
index c19bd1abd26..186b2c05d34 100644
--- a/mysql-test/r/sp-prelocking.result
+++ b/mysql-test/r/sp-prelocking.result
@@ -289,4 +289,34 @@ create table t1 select f_bug22427() as i;
ERROR 42S01: Table 't1' already exists
drop table t1;
drop function f_bug22427;
+#
+# Bug #29929 LOCK TABLES does not pre-lock tables used in triggers of the locked tables
+#
+DROP table IF EXISTS t1,t2;
+CREATE TABLE t1 (c1 INT);
+CREATE TABLE t2 (c2 INT);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+CREATE TRIGGER t1_ai AFTER INSERT ON t1 FOR EACH ROW
+BEGIN
+UPDATE t2 SET c2= c2 + 1;
+END//
+# Take a table lock on t1.
+# This should pre-lock t2 through the trigger.
+LOCK TABLE t1 WRITE;
+INSERT INTO t1 VALUES (3);
+UNLOCK TABLES;
+LOCK TABLE t1 READ;
+INSERT INTO t2 values(4);
+ERROR HY000: Table 't2' was not locked with LOCK TABLES
+UNLOCK TABLES;
+SELECT * FROM t1;
+c1
+1
+3
+SELECT * FROM t2;
+c2
+3
+DROP TRIGGER t1_ai;
+DROP TABLE t1, t2;
End of 5.0 tests
diff --git a/mysql-test/r/status.result b/mysql-test/r/status.result
index b6dcbc251d7..8f10625744b 100644
--- a/mysql-test/r/status.result
+++ b/mysql-test/r/status.result
@@ -1,11 +1,11 @@
flush status;
show status like 'Table_lock%';
Variable_name Value
-Table_locks_immediate 0
+Table_locks_immediate 1
Table_locks_waited 0
select * from information_schema.session_status where variable_name like 'Table_lock%';
VARIABLE_NAME VARIABLE_VALUE
-TABLE_LOCKS_IMMEDIATE 0
+TABLE_LOCKS_IMMEDIATE 2
TABLE_LOCKS_WAITED 0
SET SQL_LOG_BIN=0;
drop table if exists t1;
@@ -18,11 +18,11 @@ update t1 set n = 3;
unlock tables;
show status like 'Table_lock%';
Variable_name Value
-Table_locks_immediate 3
+Table_locks_immediate 17
Table_locks_waited 1
select * from information_schema.session_status where variable_name like 'Table_lock%';
VARIABLE_NAME VARIABLE_VALUE
-TABLE_LOCKS_IMMEDIATE 3
+TABLE_LOCKS_IMMEDIATE 18
TABLE_LOCKS_WAITED 1
drop table t1;
select 1;
@@ -97,7 +97,7 @@ Variable_name Value
Com_show_status 3
show status like 'hand%write%';
Variable_name Value
-Handler_write 0
+Handler_write 5
show status like '%tmp%';
Variable_name Value
Created_tmp_disk_tables 0
@@ -105,7 +105,7 @@ Created_tmp_files 0
Created_tmp_tables 0
show status like 'hand%write%';
Variable_name Value
-Handler_write 0
+Handler_write 7
show status like '%tmp%';
Variable_name Value
Created_tmp_disk_tables 0
diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def
index 368a659d939..96b5c8049b8 100644
--- a/mysql-test/t/disabled.def
+++ b/mysql-test/t/disabled.def
@@ -19,6 +19,7 @@ im_instance_conf : Bug#20294 2007-05-30 alik Instance manager tests
im_life_cycle : BUG#27851 Instance manager dies on ASSERT in ~Thread_registry() or from not being able to close a mysqld instance.
im_instance_conf : BUG#28743 Instance manager generates warnings in test suite
im_utils : BUG#28743 Instance manager generates warnings in test suite
+
concurrent_innodb : BUG#21579 2006-08-11 mleich innodb_concurrent random failures with varying differences
ctype_big5 : BUG#26711 2007-06-21 Lars Test has never worked on Double Whopper
diff --git a/mysql-test/t/events_bugs.test b/mysql-test/t/events_bugs.test
index 4186b4701fa..36052fdb9af 100644
--- a/mysql-test/t/events_bugs.test
+++ b/mysql-test/t/events_bugs.test
@@ -722,3 +722,18 @@ let $wait_condition=
--source include/wait_condition.inc
DROP DATABASE events_test;
+
+
+#
+# Bug#28641 CREATE EVENT with '2038.01.18 03:00:00' let server crash.
+#
+SET GLOBAL event_scheduler= ON;
+DELIMITER |;
+CREATE EVENT bug28641 ON SCHEDULE AT '2038.01.18 03:00:00'
+ DO BEGIN
+ SELECT 1;
+ END;|
+
+DELIMITER ;|
+SET GLOBAL event_scheduler= OFF;
+DROP EVENT bug28641;
diff --git a/mysql-test/t/log_state.test b/mysql-test/t/log_state.test
index 16f466e9b54..b0bb818b783 100644
--- a/mysql-test/t/log_state.test
+++ b/mysql-test/t/log_state.test
@@ -126,6 +126,59 @@ drop table t1;
--replace_column 1 TIMESTAMP 2 USER_HOST 3 #
select * from mysql.general_log;
+#
+# Bug#29129 (Resetting general_log while the GLOBAL READ LOCK is set causes
+# a deadlock)
+
+# save state
+
+SET @old_general_log_state = @@global.general_log;
+SET @old_slow_log_state = @@global.slow_query_log;
+
+# Test ON->OFF transition under a GLOBAL READ LOCK
+
+SET GLOBAL general_log = ON;
+SET GLOBAL slow_query_log = ON;
+
+FLUSH TABLES WITH READ LOCK;
+
+SET GLOBAL general_log = OFF;
+SET GLOBAL slow_query_log = OFF;
+
+UNLOCK TABLES;
+
+# Test OFF->ON transition under a GLOBAL READ LOCK
+
+FLUSH TABLES WITH READ LOCK;
+
+SET GLOBAL general_log = ON;
+SET GLOBAL slow_query_log = ON;
+
+UNLOCK TABLES;
+
+# Test ON->OFF transition under a GLOBAL READ_ONLY
+
+SET GLOBAL READ_ONLY = ON;
+
+SET GLOBAL general_log = OFF;
+SET GLOBAL slow_query_log = OFF;
+
+SET GLOBAL READ_ONLY = OFF;
+
+# Test OFF->ON transition under a GLOBAL READ_ONLY
+
+SET GLOBAL READ_ONLY = ON;
+
+SET GLOBAL general_log = ON;
+SET GLOBAL slow_query_log = ON;
+
+SET GLOBAL READ_ONLY = OFF;
+
+# Restore state
+
+SET GLOBAL general_log = @old_general_log_state;
+SET GLOBAL slow_query_log = @old_slow_log_state;
+
--enable_ps_protocol
#
diff --git a/mysql-test/t/log_tables.test b/mysql-test/t/log_tables.test
index e8eff7cba0a..8baa4e5a373 100644
--- a/mysql-test/t/log_tables.test
+++ b/mysql-test/t/log_tables.test
@@ -64,10 +64,10 @@ flush logs;
# check locking of the log tables
#
---error ER_CANT_WRITE_LOCK_LOG_TABLE
+--error ER_CANT_LOCK_LOG_TABLE
lock tables mysql.general_log WRITE;
---error ER_CANT_WRITE_LOCK_LOG_TABLE
+--error ER_CANT_LOCK_LOG_TABLE
lock tables mysql.slow_log WRITE;
#
@@ -76,78 +76,59 @@ lock tables mysql.slow_log WRITE;
# tables are always opened and locked by the logger.
#
---error ER_CANT_READ_LOCK_LOG_TABLE
+--error ER_CANT_LOCK_LOG_TABLE
lock tables mysql.general_log READ;
---error ER_CANT_READ_LOCK_LOG_TABLE
+--error ER_CANT_LOCK_LOG_TABLE
lock tables mysql.slow_log READ;
#
-# This call should result in TL_READ lock on the log table. This is ok and
-# should pass.
+# This call should result in TL_READ lock on the log table.
+# This is not ok and should fail.
#
+--error ER_CANT_LOCK_LOG_TABLE
lock tables mysql.slow_log READ LOCAL, mysql.general_log READ LOCAL;
-unlock tables;
-
-#
-# check that FLUSH LOGS waits for all readers of the log table to vanish
-#
-
-connect (con1,localhost,root,,);
-connect (con2,localhost,root,,);
-
-connection con1;
-
-lock tables mysql.general_log READ LOCAL;
-
-connection con2;
+# Misc locking tests
-# this should wait for log tables to unlock
-send flush logs;
-
-connection con1;
-
-unlock tables;
-
-# this connection should be alive by the time
-connection con2;
-
-reap;
+show create table mysql.general_log;
+show fields from mysql.general_log;
-select "Mark that we woke up from flush logs in the test"
- as "test passed";
+show create table mysql.slow_log;
+show fields from mysql.slow_log;
#
-# perform the same check for TRUNCATE: it should also wait for readers
-# to disappear
+# check that FLUSH LOGS does not flush the log tables
#
-connection con1;
-
-lock tables mysql.general_log READ LOCAL;
-
-connection con2;
-
-# this should wait for log tables to unlock
-send truncate mysql.general_log;
+flush logs;
+flush tables;
-connection con1;
+SET GLOBAL GENERAL_LOG=ON;
+SET GLOBAL SLOW_QUERY_LOG=ON;
-unlock tables;
+show open tables;
+flush logs;
+show open tables;
-# this connection should be alive by the time
-connection con2;
+#
+# check that FLUSH TABLES does flush the log tables
+#
-reap;
+flush tables;
+# Since the flush is logged, mysql.general_log will be in the cache
+show open tables;
-select "Mark that we woke up from TRUNCATE in the test"
- as "test passed";
+SET GLOBAL GENERAL_LOG=OFF;
+SET GLOBAL SLOW_QUERY_LOG=OFF;
-connection con1;
+flush tables;
+# Here the table cache is empty
+show open tables;
-use test;
+SET GLOBAL GENERAL_LOG=ON;
+SET GLOBAL SLOW_QUERY_LOG=ON;
#
# Bug #16905 Log tables: unicode statements are logged incorrectly
@@ -220,10 +201,10 @@ flush logs;
# check locking of myisam-based log tables
---error ER_CANT_WRITE_LOCK_LOG_TABLE
+--error ER_CANT_LOCK_LOG_TABLE
lock tables mysql.general_log WRITE;
---error ER_CANT_WRITE_LOCK_LOG_TABLE
+--error ER_CANT_LOCK_LOG_TABLE
lock tables mysql.slow_log WRITE;
#
@@ -232,21 +213,12 @@ lock tables mysql.slow_log WRITE;
# tables are always opened and locked by the logger.
#
---error ER_CANT_READ_LOCK_LOG_TABLE
+--error ER_CANT_LOCK_LOG_TABLE
lock tables mysql.general_log READ;
---error ER_CANT_READ_LOCK_LOG_TABLE
+--error ER_CANT_LOCK_LOG_TABLE
lock tables mysql.slow_log READ;
-#
-# This call should result in TL_READ lock on the log table. This is ok and
-# should pass.
-#
-
-lock tables mysql.slow_log READ LOCAL, mysql.general_log READ LOCAL;
-
-unlock tables;
-
# check that we can drop them
set global general_log='OFF';
set global slow_query_log='OFF';
@@ -314,6 +286,7 @@ use test;
flush tables with read lock;
unlock tables;
use mysql;
+--error ER_CANT_LOCK_LOG_TABLE
lock tables general_log read local, help_category read local;
unlock tables;
@@ -368,9 +341,9 @@ set global slow_query_log='OFF';
RENAME TABLE slow_log TO slow_log2;
# this should fail
---error ER_CANT_ACTIVATE_LOG
+--error ER_NO_SUCH_TABLE
set global general_log='ON';
---error ER_CANT_ACTIVATE_LOG
+--error ER_NO_SUCH_TABLE
set global slow_query_log='ON';
RENAME TABLE general_log2 TO general_log;
@@ -470,8 +443,305 @@ FLUSH LOGS;
ALTER TABLE mysql.slow_log DROP COLUMN seq;
ALTER TABLE mysql.slow_log ENGINE = CSV;
-# kill all connections
-disconnect con1;
-disconnect con2;
+#
+# Bug#25422 (Hang with log tables)
+#
+
+--disable_warnings
+drop procedure if exists proc25422_truncate_slow;
+drop procedure if exists proc25422_truncate_general;
+drop procedure if exists proc25422_alter_slow;
+drop procedure if exists proc25422_alter_general;
+--enable_warnings
+
+delimiter //;
+
+use test//
+create procedure proc25422_truncate_slow (loops int)
+begin
+ declare v1 int default 0;
+ while v1 < loops do
+ truncate mysql.slow_log;
+ set v1 = v1 + 1;
+ end while;
+end//
+
+create procedure proc25422_truncate_general (loops int)
+begin
+ declare v1 int default 0;
+ while v1 < loops do
+ truncate mysql.general_log;
+ set v1 = v1 + 1;
+ end while;
+end//
+
+create procedure proc25422_alter_slow (loops int)
+begin
+ declare v1 int default 0;
+ declare ER_BAD_LOG_STATEMENT condition for 1575;
+ declare continue handler for ER_BAD_LOG_STATEMENT begin end;
+
+ while v1 < loops do
+ set @old_log_state = @@global.slow_query_log;
+ set global slow_query_log = 'OFF';
+ alter table mysql.slow_log engine = CSV;
+ set global slow_query_log = @old_log_state;
+ set v1 = v1 + 1;
+ end while;
+end//
+
+create procedure proc25422_alter_general (loops int)
+begin
+ declare v1 int default 0;
+ declare ER_BAD_LOG_STATEMENT condition for 1575;
+ declare continue handler for ER_BAD_LOG_STATEMENT begin end;
+
+ while v1 < loops do
+ set @old_log_state = @@global.general_log;
+ set global general_log = 'OFF';
+ alter table mysql.general_log engine = CSV;
+ set global general_log = @old_log_state;
+ set v1 = v1 + 1;
+ end while;
+end//
+
+delimiter ;//
+
+--echo "Serial test (proc25422_truncate_slow)"
+call proc25422_truncate_slow(100);
+--echo "Serial test (proc25422_truncate_general)"
+call proc25422_truncate_general(100);
+--echo "Serial test (proc25422_alter_slow)"
+call proc25422_alter_slow(100);
+--echo "Serial test (proc25422_alter_general)"
+call proc25422_alter_general(100);
+
+--echo "Parallel test"
+
+# ER_BAD_LOG_STATEMENT errors will occur,
+# since concurrent threads do SET GLOBAL general_log= ...
+# This is silenced by handlers and will not affect the test
+
+connect (addconroot1, localhost, root,,);
+connect (addconroot2, localhost, root,,);
+connect (addconroot3, localhost, root,,);
+connect (addconroot4, localhost, root,,);
+connect (addconroot5, localhost, root,,);
+connect (addconroot6, localhost, root,,);
+connect (addconroot7, localhost, root,,);
+connect (addconroot8, localhost, root,,);
+
+connection addconroot1;
+send call proc25422_truncate_slow(100);
+connection addconroot2;
+send call proc25422_truncate_slow(100);
+
+connection addconroot3;
+send call proc25422_truncate_general(100);
+connection addconroot4;
+send call proc25422_truncate_general(100);
+
+connection addconroot5;
+send call proc25422_alter_slow(100);
+connection addconroot6;
+send call proc25422_alter_slow(100);
+
+connection addconroot7;
+send call proc25422_alter_general(100);
+connection addconroot8;
+send call proc25422_alter_general(100);
+
+connection addconroot1;
+reap;
+connection addconroot2;
+reap;
+connection addconroot3;
+reap;
+connection addconroot4;
+reap;
+connection addconroot5;
+reap;
+connection addconroot6;
+reap;
+connection addconroot7;
+reap;
+connection addconroot8;
+reap;
+
+connection default;
+
+disconnect addconroot1;
+disconnect addconroot2;
+disconnect addconroot3;
+disconnect addconroot4;
+disconnect addconroot5;
+disconnect addconroot6;
+disconnect addconroot7;
+disconnect addconroot8;
+
+drop procedure proc25422_truncate_slow;
+drop procedure proc25422_truncate_general;
+drop procedure proc25422_alter_slow;
+drop procedure proc25422_alter_general;
+
--enable_ps_protocol
+
+#
+# Bug#23044 (Warnings on flush of a log table)
+#
+
+FLUSH TABLE mysql.general_log;
+show warnings;
+
+FLUSH TABLE mysql.slow_log;
+show warnings;
+
+#
+# Bug#17876 (Truncating mysql.slow_log in a SP after using cursor locks the
+# thread)
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS `db_17876.slow_log_data`;
+DROP TABLE IF EXISTS `db_17876.general_log_data`;
+DROP PROCEDURE IF EXISTS `db_17876.archiveSlowLog`;
+DROP PROCEDURE IF EXISTS `db_17876.archiveGeneralLog`;
+DROP DATABASE IF EXISTS `db_17876`;
+--enable_warnings
+
+CREATE DATABASE db_17876;
+
+CREATE TABLE `db_17876.slow_log_data` (
+ `start_time` timestamp default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ `user_host` mediumtext ,
+ `query_time` time ,
+ `lock_time` time ,
+ `rows_sent` int(11) ,
+ `rows_examined` int(11) ,
+ `db` varchar(512) default NULL,
+ `last_insert_id` int(11) default NULL,
+ `insert_id` int(11) default NULL,
+ `server_id` int(11) default NULL,
+ `sql_text` mediumtext
+);
+
+CREATE TABLE `db_17876.general_log_data` (
+ `event_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `user_host` mediumtext,
+ `thread_id` int(11) DEFAULT NULL,
+ `server_id` int(11) DEFAULT NULL,
+ `command_type` varchar(64) DEFAULT NULL,
+ `argument` mediumtext
+);
+
+DELIMITER //;
+
+CREATE procedure `db_17876.archiveSlowLog`()
+BEGIN
+ DECLARE start_time, query_time, lock_time CHAR(20);
+ DECLARE user_host MEDIUMTEXT;
+ DECLARE rows_set, rows_examined, last_insert_id, insert_id, server_id INT;
+ DECLARE dbname MEDIUMTEXT;
+ DECLARE sql_text BLOB;
+ DECLARE done INT DEFAULT 0;
+ DECLARE ER_SP_FETCH_NO_DATA CONDITION for 1329;
+
+ DECLARE cur1 CURSOR FOR SELECT * FROM mysql.slow_log;
+
+ OPEN cur1;
+
+ REPEAT
+ BEGIN
+ BEGIN
+ DECLARE CONTINUE HANDLER FOR ER_SP_FETCH_NO_DATA SET done = 1;
+
+ FETCH cur1 INTO
+ start_time, user_host, query_time, lock_time,
+ rows_set, rows_examined, dbname, last_insert_id,
+ insert_id, server_id, sql_text;
+ END;
+
+ IF NOT done THEN
+ BEGIN
+ INSERT INTO
+ `db_17876.slow_log_data`
+ VALUES(start_time, user_host, query_time, lock_time, rows_set, rows_examined,
+ dbname, last_insert_id, insert_id, server_id, sql_text);
+ END;
+ END IF;
+ END;
+ UNTIL done END REPEAT;
+
+ CLOSE cur1;
+ TRUNCATE mysql.slow_log;
+END //
+
+CREATE procedure `db_17876.archiveGeneralLog`()
+BEGIN
+ DECLARE event_time CHAR(20);
+ DECLARE user_host, argument MEDIUMTEXT;
+ DECLARE thread_id, server_id INT;
+ DECLARE sql_text BLOB;
+ DECLARE done INT DEFAULT 0;
+ DECLARE command_type VARCHAR(64);
+ DECLARE ER_SP_FETCH_NO_DATA CONDITION for 1329;
+
+ DECLARE cur1 CURSOR FOR SELECT * FROM mysql.general_log;
+
+ OPEN cur1;
+
+ REPEAT
+ BEGIN
+ BEGIN
+ DECLARE CONTINUE HANDLER FOR ER_SP_FETCH_NO_DATA SET done = 1;
+
+ FETCH cur1 INTO
+ event_time, user_host, thread_id, server_id,
+ command_type, argument;
+ END;
+
+ IF NOT done THEN
+ BEGIN
+ INSERT INTO
+ `db_17876.general_log_data`
+ VALUES(event_time, user_host, thread_id, server_id,
+ command_type, argument);
+ END;
+ END IF;
+ END;
+ UNTIL done END REPEAT;
+
+ CLOSE cur1;
+ TRUNCATE mysql.general_log;
+END //
+
+DELIMITER ;//
+
+SET @old_general_log_state = @@global.general_log;
+SET @old_slow_log_state = @@global.slow_query_log;
+
+SET GLOBAL general_log = ON;
+SET GLOBAL slow_query_log = ON;
+
+select "put something into general_log";
+select "... and something more ...";
+
+call `db_17876.archiveSlowLog`();
+call `db_17876.archiveGeneralLog`();
+
+SET GLOBAL general_log = OFF;
+SET GLOBAL slow_query_log = OFF;
+
+call `db_17876.archiveSlowLog`();
+call `db_17876.archiveGeneralLog`();
+
+DROP TABLE `db_17876.slow_log_data`;
+DROP TABLE `db_17876.general_log_data`;
+DROP PROCEDURE IF EXISTS `db_17876.archiveSlowLog`;
+DROP PROCEDURE IF EXISTS `db_17876.archiveGeneralLog`;
+DROP DATABASE IF EXISTS `db_17876`;
+
+SET GLOBAL general_log = @old_general_log_state;
+SET GLOBAL slow_query_log = @old_slow_log_state;
+
diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test
index 4e8d3ae916e..171434f9dfd 100644
--- a/mysql-test/t/mysqldump.test
+++ b/mysql-test/t/mysqldump.test
@@ -1698,6 +1698,63 @@ drop database mysqldump_test_db;
--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug26121.sql
--remove_file $MYSQLTEST_VARDIR/tmp/bug26121.sql
+###########################################################################
+
+--echo #
+--echo # Bug #30027: mysqldump does not dump views properly.
+--echo #
+
+--echo
+--echo # Cleanup.
+
+--disable_warnings
+DROP DATABASE IF EXISTS mysqldump_test_db;
+--enable_warnings
+
+--echo
+--echo # Create objects.
+
+CREATE DATABASE mysqldump_test_db;
+
+set names koi8r;
+
+CREATE VIEW mysqldump_test_db.v2 AS SELECT 1 AS ËÏÌÏÎËÁ1;
+CREATE VIEW mysqldump_test_db.v1 AS SELECT ËÏÌÏÎËÁ1 FROM mysqldump_test_db.v2;
+
+set names latin1;
+
+--echo
+--echo # Dump mysqldump_test_db to bug30027.sql.
+
+--exec $MYSQL_DUMP --character-sets-dir=$CHARSETSDIR --default-character-set=latin1 --databases mysqldump_test_db > $MYSQLTEST_VARDIR/tmp/bug30027.sql
+
+--echo
+--echo # Drop mysqldump_test_db.
+
+DROP DATABASE mysqldump_test_db;
+
+--echo
+--echo # Restore mysqldump_test_db from bug30027.sql.
+
+--exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/bug30027.sql
+
+--echo
+--echo # Check the view.
+
+set names utf8;
+
+SHOW CREATE VIEW mysqldump_test_db.v1;
+SHOW CREATE VIEW mysqldump_test_db.v2;
+
+set names latin1;
+
+--echo
+--echo # Cleanup.
+
+DROP DATABASE mysqldump_test_db;
+
+###########################################################################
+
--echo #
--echo # End of 5.1 tests
--echo #
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index 394f44bbc83..5a4d30fdd50 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -2018,10 +2018,17 @@ delimiter ;|
select func_1(), func_1(), func_1() from dual;
drop function func_1;
drop procedure proc_1;
+
+# make the output deterministic:
+# the order used in SHOW OPEN TABLES
+# is too much implementation dependent
+--disable_ps_protocol
flush tables;
select Host, User from mysql.user limit 0;
select Host, Db from mysql.host limit 0;
show open tables from mysql;
+--enable_ps_protocol
+
prepare abc from "flush tables";
execute abc;
show open tables from mysql;
diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test
index 09c0b08a3cd..77ba1b22065 100644
--- a/mysql-test/t/show_check.test
+++ b/mysql-test/t/show_check.test
@@ -438,6 +438,11 @@ drop table if exists t1;
CREATE TABLE txt1(a int);
CREATE TABLE tyt2(a int);
CREATE TABLE urkunde(a int);
+
+# make the output deterministic:
+# the order used in SHOW OPEN TABLES
+# is too much implementation dependent
+--disable_ps_protocol
FLUSH TABLES;
SELECT 1 FROM mysql.db, mysql.proc, mysql.user, mysql.time_zone, mysql.time_zone_name, txt1, tyt2, urkunde LIMIT 0;
SHOW OPEN TABLES;
@@ -447,6 +452,8 @@ SHOW OPEN TABLES LIKE 't%';
SHOW OPEN TABLES LIKE '%o%';
FLUSH TABLES;
SHOW OPEN TABLES;
+--enable_ps_protocol
+
DROP TABLE txt1;
DROP TABLE tyt2;
DROP TABLE urkunde;
@@ -554,6 +561,10 @@ show status like 'slow_queries';
# FROM I_S.
#
+#
+# Part 1: check that meta-data specifies not-binary character set.
+#
+
# Ensure that all needed objects are dropped.
--disable_warnings
@@ -762,6 +773,59 @@ DROP PROCEDURE p1;
DROP FUNCTION f1;
#
+# Part 2: check that table with non-latin1 characters are dumped/restored
+# correctly.
+#
+
+# Ensure that all needed objects are dropped.
+
+set names koi8r;
+
+--disable_warnings
+DROP DATABASE IF EXISTS mysqltest1;
+--enable_warnings
+
+# Create objects.
+
+CREATE DATABASE mysqltest1;
+
+use mysqltest1;
+
+CREATE TABLE t1(ËÏÌÏÎËÁ1 INT);
+
+# Check:
+# - Dump mysqltest1;
+
+--echo
+--echo ---> Dumping mysqltest1 to show_check.mysqltest1.sql
+
+--exec $MYSQL_DUMP --default-character-set=latin1 --character-sets-dir=$CHARSETSDIR --databases mysqltest1 > $MYSQLTEST_VARDIR/tmp/show_check.mysqltest1.sql
+
+# - Clean mysqltest1;
+
+--echo
+--echo
+
+DROP DATABASE mysqltest1;
+
+# - Restore mysqltest1;
+
+--echo
+--echo
+
+--echo ---> Restoring mysqltest1...
+--exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/show_check.mysqltest1.sql
+
+# - Check definition of the table.
+
+SHOW CREATE TABLE mysqltest1.t1;
+
+# Cleanup.
+
+DROP DATABASE mysqltest1;
+use test;
+
+#
# Bug #28808: log_queries_not_using_indexes variable dynamic change is ignored
#
flush status;
diff --git a/mysql-test/t/sp-prelocking.test b/mysql-test/t/sp-prelocking.test
index 60e97260839..966c59a5789 100644
--- a/mysql-test/t/sp-prelocking.test
+++ b/mysql-test/t/sp-prelocking.test
@@ -356,4 +356,35 @@ create table t1 select f_bug22427() as i;
drop table t1;
drop function f_bug22427;
+--echo #
+--echo # Bug #29929 LOCK TABLES does not pre-lock tables used in triggers of the locked tables
+--echo #
+--disable_warnings
+DROP table IF EXISTS t1,t2;
+--enable_warnings
+CREATE TABLE t1 (c1 INT);
+CREATE TABLE t2 (c2 INT);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+DELIMITER //;
+CREATE TRIGGER t1_ai AFTER INSERT ON t1 FOR EACH ROW
+BEGIN
+UPDATE t2 SET c2= c2 + 1;
+END//
+DELIMITER ;//
+--echo # Take a table lock on t1.
+--echo # This should pre-lock t2 through the trigger.
+LOCK TABLE t1 WRITE;
+INSERT INTO t1 VALUES (3);
+UNLOCK TABLES;
+LOCK TABLE t1 READ;
+--error ER_TABLE_NOT_LOCKED
+INSERT INTO t2 values(4);
+UNLOCK TABLES;
+SELECT * FROM t1;
+SELECT * FROM t2;
+DROP TRIGGER t1_ai;
+DROP TABLE t1, t2;
+
--echo End of 5.0 tests
+
diff --git a/scripts/mysql_system_tables.sql b/scripts/mysql_system_tables.sql
index f46c7c7027a..cd0882e3af4 100644
--- a/scripts/mysql_system_tables.sql
+++ b/scripts/mysql_system_tables.sql
@@ -63,16 +63,21 @@ CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NUL
CREATE TABLE IF NOT EXISTS procs_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Routine_name char(64) binary DEFAULT '' NOT NULL, Routine_type enum('FUNCTION','PROCEDURE') NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Timestamp timestamp(14), PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges';
+-- Create general_log if CSV is enabled.
-delimiter ;;
-CREATE PROCEDURE create_general_log_table() BEGIN DECLARE is_csv_enabled int DEFAULT 0; SELECT @@have_csv = 'YES' INTO is_csv_enabled; IF (is_csv_enabled) THEN CREATE TABLE IF NOT EXISTS general_log (event_time TIMESTAMP NOT NULL, user_host MEDIUMTEXT, thread_id INTEGER, server_id INTEGER, command_type VARCHAR(64), argument MEDIUMTEXT) engine=CSV CHARACTER SET utf8 comment='General log'; END IF; END;;
-CALL create_general_log_table();;
-DROP PROCEDURE create_general_log_table;;
+SET @str = IF (@@have_csv = 'YES', 'CREATE TABLE IF NOT EXISTS general_log (event_time TIMESTAMP NOT NULL, user_host MEDIUMTEXT, thread_id INTEGER, server_id INTEGER, command_type VARCHAR(64), argument MEDIUMTEXT) engine=CSV CHARACTER SET utf8 comment="General log"', 'SET @dummy = 0');
-CREATE PROCEDURE create_slow_log_table() BEGIN DECLARE is_csv_enabled int DEFAULT 0; SELECT @@have_csv = 'YES' INTO is_csv_enabled; IF (is_csv_enabled) THEN CREATE TABLE IF NOT EXISTS slow_log (start_time TIMESTAMP NOT NULL, user_host MEDIUMTEXT NOT NULL, query_time TIME NOT NULL, lock_time TIME NOT NULL, rows_sent INTEGER NOT NULL, rows_examined INTEGER NOT NULL, db VARCHAR(512), last_insert_id INTEGER, insert_id INTEGER, server_id INTEGER, sql_text MEDIUMTEXT NOT NULL) engine=CSV CHARACTER SET utf8 comment='Slow log'; END IF; END;;
-CALL create_slow_log_table();;
-DROP PROCEDURE create_slow_log_table;;
-delimiter ;
+PREPARE stmt FROM @str;
+EXECUTE stmt;
+DROP PREPARE stmt;
+
+-- Create slow_log if CSV is enabled.
+
+SET @str = IF (@@have_csv = 'YES', 'CREATE TABLE IF NOT EXISTS slow_log (start_time TIMESTAMP NOT NULL, user_host MEDIUMTEXT NOT NULL, query_time TIME NOT NULL, lock_time TIME NOT NULL, rows_sent INTEGER NOT NULL, rows_examined INTEGER NOT NULL, db VARCHAR(512), last_insert_id INTEGER, insert_id INTEGER, server_id INTEGER, sql_text MEDIUMTEXT NOT NULL) engine=CSV CHARACTER SET utf8 comment="Slow log"', 'SET @dummy = 0');
+
+PREPARE stmt FROM @str;
+EXECUTE stmt;
+DROP PREPARE stmt;
CREATE TABLE IF NOT EXISTS event ( db char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', name char(64) CHARACTER SET utf8 NOT NULL default '', body longblob NOT NULL, definer char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', execute_at DATETIME default NULL, interval_value int(11) default NULL, interval_field ENUM('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND') default NULL, created TIMESTAMP NOT NULL, modified TIMESTAMP NOT NULL, last_executed DATETIME default NULL, starts DATETIME default NULL, ends DATETIME default NULL, status ENUM('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL default 'ENABLED', on_completion ENUM('DROP','PRESERVE') NOT NULL default 'DROP', sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE') DEFAULT '' NOT NULL, comment char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', originator int(10) NOT NULL, time_zone char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM', character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db, name) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events';
diff --git a/server-tools/instance-manager/guardian.cc b/server-tools/instance-manager/guardian.cc
index e114496248e..b49b0ec0a00 100644
--- a/server-tools/instance-manager/guardian.cc
+++ b/server-tools/instance-manager/guardian.cc
@@ -403,6 +403,8 @@ void Guardian::init()
void Guardian::stop_instances()
{
+ static const int NUM_STOP_ATTEMPTS = 100;
+
Instance_map::Iterator instances_it(instance_map);
Instance *instance;
@@ -438,7 +440,34 @@ void Guardian::stop_instances()
/* Request mysqld to stop. */
- instance->kill_mysqld(SIGTERM);
+ bool instance_stopped= FALSE;
+
+ for (int cur_attempt= 0; cur_attempt < NUM_STOP_ATTEMPTS; ++cur_attempt)
+ {
+ if (!instance->kill_mysqld(SIGTERM))
+ {
+ instance_stopped= TRUE;
+ break;
+ }
+
+ if (!instance->is_active())
+ {
+ instance_stopped= TRUE;
+ break;
+ }
+
+ /* Sleep for 0.3 sec and check again. */
+
+ my_sleep(300000);
+ }
+
+ /*
+ Abort if we failed to stop mysqld instance. That should not happen,
+ but if it happened, we don't know what to do and prefer to have clear
+ failure with coredump.
+ */
+
+ DBUG_ASSERT(instance_stopped);
instance->unlock();
}
diff --git a/server-tools/instance-manager/instance.cc b/server-tools/instance-manager/instance.cc
index edc9c88fe9f..4a1b658737e 100644
--- a/server-tools/instance-manager/instance.cc
+++ b/server-tools/instance-manager/instance.cc
@@ -524,24 +524,17 @@ bool Instance::init(const LEX_STRING *name_arg)
/**
- Complete instance options initialization.
+ @brief Complete instance options initialization.
- SYNOPSIS
- complete_initialization()
-
- RETURN
- FALSE - ok
- TRUE - error
+ @return Error status.
+ @retval FALSE ok
+ @retval TRUE error
*/
bool Instance::complete_initialization()
{
configured= ! options.complete_initialization();
- return FALSE;
- /*
- TODO: return actual status (from
- Instance_options::complete_initialization()) here.
- */
+ return !configured;
}
/**************************************************************************
@@ -644,25 +637,24 @@ bool Instance::is_mysqld_running()
/**
- Start mysqld.
+ @brief Start mysqld.
- SYNOPSIS
- start_mysqld()
-
- DESCRIPTION
- Reset flags and start Instance Monitor thread, which will start mysqld.
+ Reset flags and start Instance Monitor thread, which will start mysqld.
- MT-NOTE: instance must be locked before calling the operation.
+ @note Instance must be locked before calling the operation.
- RETURN
- FALSE - ok
- TRUE - could not start instance
+ @return Error status code
+ @retval FALSE Ok
+ @retval TRUE Could not start instance
*/
bool Instance::start_mysqld()
{
Instance_monitor *instance_monitor;
+ if (!configured)
+ return TRUE;
+
/*
Prepare instance to start Instance Monitor thread.
@@ -779,7 +771,7 @@ bool Instance::stop_mysqld()
These operations should also be used in Guardian to manage instances.
*/
-void Instance::kill_mysqld(int signum)
+bool Instance::kill_mysqld(int signum)
{
pid_t mysqld_pid= options.load_pid();
@@ -788,7 +780,7 @@ void Instance::kill_mysqld(int signum)
log_info("Instance '%s': no pid file to send a signal (%d).",
(const char *) get_name()->str,
(int) signum);
- return;
+ return TRUE;
}
log_info("Instance '%s': sending %d to %d...",
@@ -800,7 +792,7 @@ void Instance::kill_mysqld(int signum)
{
log_info("Instance '%s': kill() failed.",
(const char *) get_name()->str);
- return;
+ return TRUE;
}
/* Kill suceeded */
@@ -812,6 +804,8 @@ void Instance::kill_mysqld(int signum)
/* After sucessful hard kill the pidfile need to be removed */
options.unlink_pidfile();
}
+
+ return FALSE;
}
diff --git a/server-tools/instance-manager/instance.h b/server-tools/instance-manager/instance.h
index e87bb49b49c..aa9c923cba1 100644
--- a/server-tools/instance-manager/instance.h
+++ b/server-tools/instance-manager/instance.h
@@ -104,7 +104,7 @@ public:
bool start_mysqld();
bool stop_mysqld();
- void kill_mysqld(int signo);
+ bool kill_mysqld(int signo);
void lock();
void unlock();
diff --git a/server-tools/instance-manager/instance_options.cc b/server-tools/instance-manager/instance_options.cc
index 5665c6f8670..8b96d6f0f96 100644
--- a/server-tools/instance-manager/instance_options.cc
+++ b/server-tools/instance-manager/instance_options.cc
@@ -156,7 +156,8 @@ int Instance_options::get_default_option(char *result, size_t result_len,
goto err;
/* +2 eats first "--" from the option string (E.g. "--datadir") */
- rc= parse_output_and_get_value((char*) cmd.buffer, option_name + 2,
+ rc= parse_output_and_get_value((char*) cmd.buffer,
+ option_name + 2, strlen(option_name + 2),
result, result_len, GET_VALUE);
err:
return rc;
@@ -194,8 +195,8 @@ bool Instance_options::fill_instance_version()
bzero(result, MAX_VERSION_LENGTH);
- if (parse_output_and_get_value((char*) cmd.buffer, "Ver", result,
- MAX_VERSION_LENGTH, GET_LINE))
+ if (parse_output_and_get_value((char*) cmd.buffer, STRING_WITH_LEN("Ver"),
+ result, MAX_VERSION_LENGTH, GET_LINE))
{
log_error("Failed to get version of '%s': unexpected output.",
(const char *) mysqld_path.str);
@@ -206,8 +207,7 @@ bool Instance_options::fill_instance_version()
{
char *start;
- /* chop the newline from the end of the version string */
- result[strlen(result) - NEWLINE_LEN]= '\0';
+
/* trim leading whitespaces */
start= result;
while (my_isspace(default_charset_info, *start))
@@ -255,7 +255,8 @@ bool Instance_options::fill_mysqld_real_path()
bzero(result, FN_REFLEN);
- if (parse_output_and_get_value((char*) cmd.buffer, "Usage: ",
+ if (parse_output_and_get_value((char*) cmd.buffer,
+ STRING_WITH_LEN("Usage: "),
result, FN_REFLEN,
GET_LINE))
{
diff --git a/server-tools/instance-manager/parse_output.cc b/server-tools/instance-manager/parse_output.cc
index 36eb5185f6b..3511589acd6 100644
--- a/server-tools/instance-manager/parse_output.cc
+++ b/server-tools/instance-manager/parse_output.cc
@@ -24,6 +24,13 @@
#include "parse.h"
#include "portability.h"
+/**************************************************************************
+ Private module implementation.
+**************************************************************************/
+
+namespace { /* no-indent */
+
+/*************************************************************************/
void trim_space(const char **text, uint *word_len)
{
@@ -39,90 +46,362 @@ void trim_space(const char **text, uint *word_len)
*word_len= (end - start)+1;
}
-/*
- Parse output of the given command
+/*************************************************************************/
- SYNOPSIS
- parse_output_and_get_value()
+/**
+ @brief A facade to the internal workings of optaining the output from an
+ executed system process.
+*/
- command the command to execue with popen.
- word the word to look for (usually an option name)
- result the buffer to store the next word (option value)
- input_buffer_len self-explanatory
- flag this equals to GET_LINE if we want to get all the line after
- the matched word and GET_VALUE otherwise.
+class Mysqld_output_parser
+{
+public:
+ Mysqld_output_parser()
+ { }
- DESCRIPTION
+ virtual ~Mysqld_output_parser()
+ { }
- Parse output of the "command". Find the "word" and return the next one
- if flag is GET_VALUE. Return the rest of the parsed string otherwise.
+public:
+ bool parse(const char *command,
+ const char *option_name_str,
+ uint option_name_length,
+ char *option_value_buf,
+ size_t option_value_buf_size,
+ enum_option_type option_type);
- RETURN
- 0 - ok, the word has been found
- 1 - error occured or the word is not found
-*/
+protected:
+ /**
+ @brief Run a process and attach stdout- and stdin-pipes to it.
-int parse_output_and_get_value(const char *command, const char *word,
- char *result, size_t input_buffer_len,
- uint flag)
-{
- FILE *output;
- uint wordlen;
- /* should be enough to store the string from the output */
- enum { MAX_LINE_LEN= 512 };
- char linebuf[MAX_LINE_LEN];
- int rc= 1;
+ @param command The path to the process to be executed
- wordlen= strlen(word);
+ @return Error status.
+ @retval TRUE An error occurred
+ @retval FALSE Operation was a success
+ */
- /*
- Successful return of popen does not tell us whether the command has been
- executed successfully: if the command was not found, we'll get EOF
- when reading the output buffer below.
+ virtual bool run_command(const char *command)= 0;
+
+
+ /**
+ @brief Read a sequence of bytes from the executed process' stdout pipe.
+
+ The sequence is terminated by either '\0', LF or CRLF tokens. The
+ terminating token is excluded from the result.
+
+ @param line_buffer A pointer to a character buffer
+ @param line_buffer_size The size of the buffer in bytes
+
+ @return Error status.
+ @retval TRUE An error occured
+ @retval FALSE Operation was a success
*/
- if (!(output= popen(command, "r")))
- goto err;
- /*
- We want fully buffered stream. We also want system to
- allocate appropriate buffer.
+ virtual bool read_line(char *line_buffer,
+ uint line_buffer_size)= 0;
+
+
+ /**
+ @brief Release any resources needed after a execution and parsing.
*/
- setvbuf(output, NULL, _IOFBF, 0);
- while (fgets(linebuf, sizeof(linebuf) - 1, output))
+ virtual bool cleanup()= 0;
+};
+
+/*************************************************************************/
+
+bool Mysqld_output_parser::parse(const char *command,
+ const char *option_name_str,
+ uint option_name_length,
+ char *option_value_buf,
+ size_t option_value_buf_size,
+ enum_option_type option_type)
+{
+ /* should be enough to store the string from the output */
+ const int LINE_BUFFER_SIZE= 512;
+ char line_buffer[LINE_BUFFER_SIZE];
+
+ if (run_command(command))
+ return TRUE;
+
+ while (true)
{
+ if (read_line(line_buffer, LINE_BUFFER_SIZE))
+ {
+ cleanup();
+ return TRUE;
+ }
+
uint found_word_len= 0;
- char *linep= linebuf;
+ char *linep= line_buffer;
+
+ line_buffer[sizeof(line_buffer) - 1]= '\0'; /* safety */
+
+ /* Find the word(s) we are looking for in the line. */
- linebuf[sizeof(linebuf) - 1]= '\0'; /* safety */
+ linep= strstr(linep, option_name_str);
- /*
- Find the word(s) we are looking for in the line
- */
- if ((linep= strstr(linep, word)))
+ if (!linep)
+ continue;
+
+ linep+= option_name_length;
+
+ switch (option_type)
{
- /*
- If we have found our word(s), then move linep past the word(s)
- */
- linep+= wordlen;
- if (flag & GET_VALUE)
+ case GET_VALUE:
+ trim_space((const char**) &linep, &found_word_len);
+
+ if (option_value_buf_size <= found_word_len)
{
- trim_space((const char**) &linep, &found_word_len);
- if (input_buffer_len <= found_word_len)
- goto err;
- strmake(result, linep, found_word_len);
+ cleanup();
+ return TRUE;
}
- else /* currently there are only two options */
- strmake(result, linep, input_buffer_len - 1);
- rc= 0;
+
+ strmake(option_value_buf, linep, found_word_len);
+
+ break;
+
+ case GET_LINE:
+ strmake(option_value_buf, linep, option_value_buf_size - 1);
+
break;
}
+
+ cleanup();
+
+ return FALSE;
}
+}
+
+/**************************************************************************
+ Platform-specific implementation: UNIX.
+**************************************************************************/
+
+#ifndef __WIN__
+
+class Mysqld_output_parser_unix : public Mysqld_output_parser
+{
+public:
+ Mysqld_output_parser_unix() :
+ m_stdout(NULL)
+ { }
+
+protected:
+ virtual bool run_command(const char *command);
+
+ virtual bool read_line(char *line_buffer,
+ uint line_buffer_size);
+
+ virtual bool cleanup();
+
+private:
+ FILE *m_stdout;
+};
+
+bool Mysqld_output_parser_unix::run_command(const char *command)
+{
+ if (!(m_stdout= popen(command, "r")))
+ return TRUE;
- /* we are not interested in the termination status */
- pclose(output);
+ /*
+ We want fully buffered stream. We also want system to allocate
+ appropriate buffer.
+ */
-err:
- return rc;
+ setvbuf(m_stdout, NULL, _IOFBF, 0);
+
+ return FALSE;
}
+bool Mysqld_output_parser_unix::read_line(char *line_buffer,
+ uint line_buffer_size)
+{
+ char *retbuff = fgets(line_buffer, line_buffer_size, m_stdout);
+ /* Remove any tailing new line charaters */
+ if (line_buffer[line_buffer_size-1] == LF)
+ line_buffer[line_buffer_size-1]= '\0';
+ return (retbuff == NULL);
+}
+
+bool Mysqld_output_parser_unix::cleanup()
+{
+ if (m_stdout)
+ pclose(m_stdout);
+
+ return FALSE;
+}
+
+#else /* Windows */
+
+/**************************************************************************
+ Platform-specific implementation: Windows.
+**************************************************************************/
+
+class Mysqld_output_parser_win : public Mysqld_output_parser
+{
+public:
+ Mysqld_output_parser_win() :
+ m_internal_buffer(NULL),
+ m_internal_buffer_offset(0),
+ m_internal_buffer_size(0)
+ { }
+
+protected:
+ virtual bool run_command(const char *command);
+ virtual bool read_line(char *line_buffer,
+ uint line_buffer_size);
+ virtual bool cleanup();
+
+private:
+ HANDLE m_h_child_stdout_wr;
+ HANDLE m_h_child_stdout_rd;
+ uint m_internal_buffer_offset;
+ uint m_internal_buffer_size;
+ char *m_internal_buffer;
+};
+
+bool Mysqld_output_parser_win::run_command(const char *command)
+{
+ BOOL op_status;
+
+ SECURITY_ATTRIBUTES sa_attr;
+ sa_attr.nLength= sizeof(SECURITY_ATTRIBUTES);
+ sa_attr.bInheritHandle= TRUE;
+ sa_attr.lpSecurityDescriptor= NULL;
+
+ op_status= CreatePipe(&m_h_child_stdout_rd,
+ &m_h_child_stdout_wr,
+ &sa_attr,
+ 0 /* Use system-default buffer size. */);
+
+ if (!op_status)
+ return TRUE;
+
+ SetHandleInformation(m_h_child_stdout_rd, HANDLE_FLAG_INHERIT, 0);
+
+ STARTUPINFO si_start_info;
+ ZeroMemory(&si_start_info, sizeof(STARTUPINFO));
+ si_start_info.cb= sizeof(STARTUPINFO);
+ si_start_info.hStdError= m_h_child_stdout_wr;
+ si_start_info.hStdOutput= m_h_child_stdout_wr;
+ si_start_info.dwFlags|= STARTF_USESTDHANDLES;
+
+ PROCESS_INFORMATION pi_proc_info;
+
+ op_status= CreateProcess(NULL, /* Application name. */
+ (char*)command, /* Command line. */
+ NULL, /* Process security attributes. */
+ NULL, /* Primary thread security attr.*/
+ TRUE, /* Handles are inherited. */
+ 0, /* Creation flags. */
+ NULL, /* Use parent's environment. */
+ NULL, /* Use parent's curr. directory. */
+ &si_start_info, /* STARTUPINFO pointer. */
+ &pi_proc_info); /* Rec. PROCESS_INFORMATION. */
+
+ if (!op_status)
+ {
+ CloseHandle(m_h_child_stdout_rd);
+ CloseHandle(m_h_child_stdout_wr);
+
+ return TRUE;
+ }
+
+ /* Close unnessary handles. */
+
+ CloseHandle(pi_proc_info.hProcess);
+ CloseHandle(pi_proc_info.hThread);
+
+ return FALSE;
+}
+
+bool Mysqld_output_parser_win::read_line(char *line_buffer,
+ uint line_buffer_size)
+{
+ DWORD dw_read_count= m_internal_buffer_size;
+ bzero(line_buffer,line_buffer_size);
+ char *buff_ptr= line_buffer;
+ char ch;
+
+ while ((unsigned)(buff_ptr - line_buffer) < line_buffer_size)
+ {
+ do
+ {
+ ReadFile(m_h_child_stdout_rd, &ch,
+ 1, &dw_read_count, NULL);
+ } while ((ch == CR || ch == LF) && buff_ptr == line_buffer);
+
+ if (dw_read_count == 0)
+ return TRUE;
+
+ if (ch == CR || ch == LF)
+ break;
+
+ *buff_ptr++ = ch;
+ }
+
+ return FALSE;
+}
+
+bool Mysqld_output_parser_win::cleanup()
+{
+ /* Close all handles. */
+
+ CloseHandle(m_h_child_stdout_wr);
+ CloseHandle(m_h_child_stdout_rd);
+
+ return FALSE;
+}
+#endif
+
+/*************************************************************************/
+
+} /* End of private module implementation. */
+
+/*************************************************************************/
+
+/**
+ @brief Parse output of the given command
+
+ @param command The command to execute.
+ @param option_name_str Option name.
+ @param option_name_length Length of the option name.
+ @param[out] option_value_buf The buffer to store option value.
+ @param option_value_buf_size Size of the option value buffer.
+ @param option_type Type of the option:
+ - GET_LINE if we want to get all the
+ line after the option name;
+ - GET_VALUE otherwise.
+
+ Execute the process by running "command". Find the "option name" and
+ return the next word if "option_type" is GET_VALUE. Return the rest of
+ the parsed string otherwise.
+
+ @note This function has a separate windows implementation.
+
+ @return The error status.
+ @retval FALSE Ok, the option name has been found.
+ @retval TRUE Error occured or the option name is not found.
+*/
+
+bool parse_output_and_get_value(const char *command,
+ const char *option_name_str,
+ uint option_name_length,
+ char *option_value_buf,
+ size_t option_value_buf_size,
+ enum_option_type option_type)
+{
+#ifndef __WIN__
+ Mysqld_output_parser_unix parser;
+#else /* __WIN__ */
+ Mysqld_output_parser_win parser;
+#endif
+
+ return parser.parse(command,
+ option_name_str,
+ option_name_length,
+ option_value_buf,
+ option_value_buf_size,
+ option_type);
+}
diff --git a/server-tools/instance-manager/parse_output.h b/server-tools/instance-manager/parse_output.h
index 8851934f230..41618f643a3 100644
--- a/server-tools/instance-manager/parse_output.h
+++ b/server-tools/instance-manager/parse_output.h
@@ -17,11 +17,17 @@
#include <my_global.h>
-#define GET_VALUE 1
-#define GET_LINE 2
+enum enum_option_type
+{
+ GET_VALUE = 1,
+ GET_LINE
+};
-int parse_output_and_get_value(const char *command, const char *word,
- char *result, size_t input_buffer_len,
- uint flag);
+bool parse_output_and_get_value(const char *command,
+ const char *option_name_str,
+ uint option_name_length,
+ char *option_value_buf,
+ size_t option_value_buf_size,
+ enum_option_type option_type);
#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_PARSE_OUTPUT_H */
diff --git a/server-tools/instance-manager/portability.h b/server-tools/instance-manager/portability.h
index eb677a0135c..990e6140a9e 100644
--- a/server-tools/instance-manager/portability.h
+++ b/server-tools/instance-manager/portability.h
@@ -48,11 +48,16 @@ typedef int pid_t;
#define NEWLINE "\r\n"
#define NEWLINE_LEN 2
+const char CR = '\r';
+const char LF = '\n';
+
#else /* ! __WIN__ */
#define NEWLINE "\n"
#define NEWLINE_LEN 1
+const char LF = '\n';
+
#endif /* __WIN__ */
#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_PORTABILITY_H */
diff --git a/server-tools/instance-manager/thread_registry.cc b/server-tools/instance-manager/thread_registry.cc
index b06c1240d92..72d81523022 100644
--- a/server-tools/instance-manager/thread_registry.cc
+++ b/server-tools/instance-manager/thread_registry.cc
@@ -64,11 +64,14 @@ Thread_registry::~Thread_registry()
/* Check that no one uses the repository. */
pthread_mutex_lock(&LOCK_thread_registry);
- if (head.next != &head)
- log_error("Not all threads died properly\n");
+ for (Thread_info *ti= head.next; ti != &head; ti= ti->next)
+ {
+ log_error("Thread_registry: unregistered thread: %lu.",
+ (unsigned long) ti->thread_id);
+ }
+
/* All threads must unregister */
- // Disabled assert temporarily - BUG#28030
- // DBUG_ASSERT(head.next == &head);
+ DBUG_ASSERT(head.next == &head);
pthread_mutex_unlock(&LOCK_thread_registry);
pthread_cond_destroy(&COND_thread_registry_is_empty);
diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc
index 7b58c10079a..144a87e13f6 100644
--- a/sql/event_data_objects.cc
+++ b/sql/event_data_objects.cc
@@ -979,17 +979,18 @@ Event_queue_element::load_from_row(THD *thd, TABLE *table)
DBUG_RETURN(TRUE);
starts_null= table->field[ET_FIELD_STARTS]->is_null();
+ my_bool not_used= FALSE;
if (!starts_null)
{
table->field[ET_FIELD_STARTS]->get_date(&time, TIME_NO_ZERO_DATE);
- starts= sec_since_epoch_TIME(&time);
+ starts= my_tz_OFFSET0->TIME_to_gmt_sec(&time,&not_used);
}
ends_null= table->field[ET_FIELD_ENDS]->is_null();
if (!ends_null)
{
table->field[ET_FIELD_ENDS]->get_date(&time, TIME_NO_ZERO_DATE);
- ends= sec_since_epoch_TIME(&time);
+ ends= my_tz_OFFSET0->TIME_to_gmt_sec(&time,&not_used);
}
if (!table->field[ET_FIELD_INTERVAL_EXPR]->is_null())
@@ -1007,7 +1008,7 @@ Event_queue_element::load_from_row(THD *thd, TABLE *table)
if (table->field[ET_FIELD_EXECUTE_AT]->get_date(&time,
TIME_NO_ZERO_DATE))
DBUG_RETURN(TRUE);
- execute_at= sec_since_epoch_TIME(&time);
+ execute_at= my_tz_OFFSET0->TIME_to_gmt_sec(&time,&not_used);
}
/*
@@ -1039,7 +1040,7 @@ Event_queue_element::load_from_row(THD *thd, TABLE *table)
{
table->field[ET_FIELD_LAST_EXECUTED]->get_date(&time,
TIME_NO_ZERO_DATE);
- last_executed= sec_since_epoch_TIME(&time);
+ last_executed= my_tz_OFFSET0->TIME_to_gmt_sec(&time,&not_used);
}
last_executed_changed= FALSE;
diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc
index a16a04739e2..b7bcb6344fd 100644
--- a/sql/event_db_repository.cc
+++ b/sql/event_db_repository.cc
@@ -250,7 +250,7 @@ mysql_event_fill_row(THD *thd,
if (!et->starts_null)
{
MYSQL_TIME time;
- my_tz_UTC->gmt_sec_to_TIME(&time, et->starts);
+ my_tz_OFFSET0->gmt_sec_to_TIME(&time, et->starts);
fields[ET_FIELD_STARTS]->set_notnull();
fields[ET_FIELD_STARTS]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
@@ -259,7 +259,7 @@ mysql_event_fill_row(THD *thd,
if (!et->ends_null)
{
MYSQL_TIME time;
- my_tz_UTC->gmt_sec_to_TIME(&time, et->ends);
+ my_tz_OFFSET0->gmt_sec_to_TIME(&time, et->ends);
fields[ET_FIELD_ENDS]->set_notnull();
fields[ET_FIELD_ENDS]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
@@ -278,7 +278,7 @@ mysql_event_fill_row(THD *thd,
fields[ET_FIELD_ENDS]->set_null();
MYSQL_TIME time;
- my_tz_UTC->gmt_sec_to_TIME(&time, et->execute_at);
+ my_tz_OFFSET0->gmt_sec_to_TIME(&time, et->execute_at);
fields[ET_FIELD_EXECUTE_AT]->set_notnull();
fields[ET_FIELD_EXECUTE_AT]->
@@ -1004,7 +1004,7 @@ update_timing_fields_for_event(THD *thd,
if (update_last_executed)
{
MYSQL_TIME time;
- my_tz_UTC->gmt_sec_to_TIME(&time, last_executed);
+ my_tz_OFFSET0->gmt_sec_to_TIME(&time, last_executed);
fields[ET_FIELD_LAST_EXECUTED]->set_notnull();
fields[ET_FIELD_LAST_EXECUTED]->store_time(&time,
diff --git a/sql/event_queue.cc b/sql/event_queue.cc
index 634cc764d74..04449dd48a1 100644
--- a/sql/event_queue.cc
+++ b/sql/event_queue.cc
@@ -740,7 +740,7 @@ Event_queue::dump_internal_status()
printf("WOC : %s\n", waiting_on_cond? "YES":"NO");
MYSQL_TIME time;
- my_tz_UTC->gmt_sec_to_TIME(&time, next_activation_at);
+ my_tz_OFFSET0->gmt_sec_to_TIME(&time, next_activation_at);
if (time.year != 1970)
printf("Next activation : %04d-%02d-%02d %02d:%02d:%02d\n",
time.year, time.month, time.day, time.hour, time.minute, time.second);
diff --git a/sql/handler.cc b/sql/handler.cc
index 55e2e478027..f06ad282efa 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -1516,34 +1516,6 @@ THD *handler::ha_thd(void) const
}
-bool handler::check_if_log_table_locking_is_allowed(uint sql_command,
- ulong type, TABLE *table)
-{
- /*
- Deny locking of the log tables, which is incompatible with
- concurrent insert. The routine is not called if the table is
- being locked from a logger THD (general_log_thd or slow_log_thd)
- or from a privileged thread (see log.cc for details)
- */
- if (table->s->log_table &&
- sql_command != SQLCOM_TRUNCATE &&
- sql_command != SQLCOM_ALTER_TABLE &&
- !(sql_command == SQLCOM_FLUSH &&
- type & REFRESH_LOG) &&
- (table->reginfo.lock_type >= TL_READ_NO_INSERT))
- {
- /*
- The check >= TL_READ_NO_INSERT denies all write locks
- plus the only read lock (TL_READ_NO_INSERT itself)
- */
- table->reginfo.lock_type == TL_READ_NO_INSERT ?
- my_error(ER_CANT_READ_LOCK_LOG_TABLE, MYF(0)) :
- my_error(ER_CANT_WRITE_LOCK_LOG_TABLE, MYF(0));
- return FALSE;
- }
- return TRUE;
-}
-
/** @brief
Open database-handler.
@@ -3687,6 +3659,7 @@ int handler::ha_write_row(uchar *buf)
return 0;
}
+
int handler::ha_update_row(const uchar *old_data, uchar *new_data)
{
int error;
diff --git a/sql/handler.h b/sql/handler.h
index f45b28c55f5..7cf7bfe043d 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -992,6 +992,7 @@ public:
uint ref_length;
FT_INFO *ft_handler;
enum {NONE=0, INDEX, RND} inited;
+ bool locked;
bool implicit_emptied; /* Can be !=0 only if HEAP */
const COND *pushed_cond;
/*
@@ -1022,11 +1023,13 @@ public:
estimation_rows_to_insert(0), ht(ht_arg),
ref(0), key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
ref_length(sizeof(my_off_t)),
- ft_handler(0), inited(NONE), implicit_emptied(0),
+ ft_handler(0), inited(NONE),
+ locked(FALSE), implicit_emptied(0),
pushed_cond(0), next_insert_id(0), insert_id_for_cur_row(0)
{}
virtual ~handler(void)
{
+ DBUG_ASSERT(locked == FALSE);
/* TODO: DBUG_ASSERT(inited == NONE); */
}
virtual handler *clone(MEM_ROOT *mem_root);
@@ -1035,44 +1038,6 @@ public:
{
cached_table_flags= table_flags();
}
- /*
- Check whether a handler allows to lock the table.
-
- SYNOPSIS
- check_if_locking_is_allowed()
- thd Handler of the thread, trying to lock the table
- table Table handler to check
- 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
- has the right to lock log tables.
-
- DESCRIPTION
- Check whether a handler allows to lock the table. For instance,
- MyISAM does not allow to lock mysql.proc along with other tables.
- This limitation stems from the fact that MyISAM does not support
- row-level locking and we have to add this limitation to avoid
- deadlocks.
-
- RETURN
- TRUE Locking is allowed
- FALSE Locking is not allowed. The error was thrown.
- */
- virtual bool check_if_locking_is_allowed(uint sql_command,
- ulong type, TABLE *table,
- uint count, uint current,
- uint *system_count,
- bool called_by_privileged_thread)
- {
- return TRUE;
- }
- bool check_if_log_table_locking_is_allowed(uint sql_command,
- ulong type, TABLE *table);
int ha_open(TABLE *table, const char *name, int mode, int test_if_locked);
void adjust_next_insert_id_after_explicit_value(ulonglong nr);
int update_auto_increment();
@@ -1629,8 +1594,10 @@ public:
/* lock_count() can be more than one if the table is a MERGE */
virtual uint lock_count(void) const { return 1; }
- /*
- NOTE that one can NOT rely on table->in_use in store_lock(). It may
+ /**
+ Is not invoked for non-transactional temporary tables.
+
+ @note that one can NOT rely on table->in_use in store_lock(). It may
refer to a different thread if called from mysql_lock_abort_for_thread().
*/
virtual THR_LOCK_DATA **store_lock(THD *thd,
@@ -1761,6 +1728,29 @@ private:
overridden by the storage engine class. To call these methods, use
the corresponding 'ha_*' method above.
*/
+
+ /**
+ Is not invoked for non-transactional temporary tables.
+
+ Tells the storage engine that we intend to read or write data
+ from the table. This call is prefixed with a call to handler::store_lock()
+ and is invoked only for those handler instances that stored the lock.
+
+ Calls to rnd_init/index_init are prefixed with this call. When table
+ IO is complete, we call external_lock(F_UNLCK).
+ A storage engine writer should expect that each call to
+ ::external_lock(F_[RD|WR]LOCK is followed by a call to
+ ::external_lock(F_UNLCK). If it is not, it is a bug in MySQL.
+
+ The name and signature originate from the first implementation
+ in MyISAM, which would call fcntl to set/clear an advisory
+ lock on the data file in this method.
+
+ @param lock_type F_RDLCK, F_WRLCK, F_UNLCK
+
+ @return non-0 in case of failure, 0 in case of success.
+ When lock_type is F_UNLCK, the return value is ignored.
+ */
virtual int external_lock(THD *thd __attribute__((unused)),
int lock_type __attribute__((unused)))
{
diff --git a/sql/lock.cc b/sql/lock.cc
index 63d0807b975..08ff90ce983 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -116,16 +116,90 @@ static void print_lock_error(int error, const char *);
static int thr_lock_errno_to_mysql[]=
{ 0, 1, ER_LOCK_WAIT_TIMEOUT, ER_LOCK_DEADLOCK };
+/**
+ Perform semantic checks for mysql_lock_tables.
+ @param thd The current thread
+ @param tables The tables to lock
+ @param count The number of tables to lock
+ @param flags Lock flags
+ @return 0 if all the check passed, non zero if a check failed.
+*/
+int mysql_lock_tables_check(THD *thd, TABLE **tables, uint count, uint flags)
+{
+ bool log_table_write_query;
+ uint system_count;
+ uint i;
+
+ DBUG_ENTER("mysql_lock_tables_check");
+
+ system_count= 0;
+ log_table_write_query= (is_log_table_write_query(thd->lex->sql_command)
+ || ((flags & MYSQL_LOCK_PERF_SCHEMA) != 0));
+
+ for (i=0 ; i<count; i++)
+ {
+ TABLE *t= tables[i];
+
+ /* Protect against 'fake' partially initialized TABLE_SHARE */
+ DBUG_ASSERT(t->s->table_category != TABLE_UNKNOWN_CATEGORY);
+
+ /*
+ Table I/O to performance schema tables is performed
+ only internally by the server implementation.
+ When a user is requesting a lock, the following
+ constraints are enforced:
+ */
+ if (t->s->require_write_privileges() &&
+ ! log_table_write_query)
+ {
+ /*
+ A user should not be able to prevent writes,
+ or hold any type of lock in a session,
+ since this would be a DOS attack.
+ */
+ if ((t->reginfo.lock_type >= TL_READ_NO_INSERT)
+ || (thd->lex->sql_command == SQLCOM_LOCK_TABLES))
+ {
+ my_error(ER_CANT_LOCK_LOG_TABLE, MYF(0));
+ DBUG_RETURN(1);
+ }
+ }
+
+ if ((t->s->table_category == TABLE_CATEGORY_SYSTEM) &&
+ (t->reginfo.lock_type >= TL_WRITE_ALLOW_WRITE))
+ {
+ system_count++;
+ }
+ }
+
+ /*
+ Locking of system tables is restricted:
+ locking a mix of system and non-system tables in the same lock
+ is prohibited, to prevent contention.
+ */
+ if ((system_count > 0) && (system_count < count))
+ {
+ my_error(ER_WRONG_LOCK_OF_SYSTEM_TABLE, MYF(0));
+ DBUG_RETURN(1);
+ }
+
+ DBUG_RETURN(0);
+}
+
MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
uint flags, bool *need_reopen)
{
MYSQL_LOCK *sql_lock;
TABLE *write_lock_used;
int rc;
+
DBUG_ENTER("mysql_lock_tables");
*need_reopen= FALSE;
+ if (mysql_lock_tables_check(thd, tables, count, flags))
+ DBUG_RETURN (NULL);
+
for (;;)
{
if (! (sql_lock= get_lock_data(thd, tables, count, GET_LOCK_STORE_LOCKS,
@@ -175,7 +249,8 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
thd->proc_info="System lock";
DBUG_PRINT("info", ("thd->proc_info %s", thd->proc_info));
- if (lock_external(thd, tables, count))
+ if (sql_lock->table_count && lock_external(thd, sql_lock->table,
+ sql_lock->table_count))
{
/* Clear the lock type of all lock data to avoid reusage. */
reset_lock_data(sql_lock);
@@ -271,6 +346,7 @@ static int lock_external(THD *thd, TABLE **tables, uint count)
((*tables)->reginfo.lock_type >= TL_READ &&
(*tables)->reginfo.lock_type <= TL_READ_NO_INSERT))
lock_type=F_RDLCK;
+
if ((error=(*tables)->file->ha_external_lock(thd,lock_type)))
{
print_lock_error(error, (*tables)->file->table_type());
@@ -379,10 +455,28 @@ void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock)
}
+/**
+ Try to find the table in the list of locked tables.
+ In case of success, unlock the table and remove it from this list.
+
+ @note This function has a legacy side effect: the table is
+ unlocked even if it is not found in the locked list.
+ It's not clear if this side effect is intentional or still
+ desirable. It might lead to unmatched calls to
+ unlock_external(). Moreover, a discrepancy can be left
+ unnoticed by the storage engine, because in
+ unlock_external() we call handler::external_lock(F_UNLCK) only
+ if table->current_lock is not F_UNLCK.
+
+ @param always_unlock specify explicitly if the legacy side
+ effect is desired.
+*/
-void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table)
+void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table,
+ bool always_unlock)
{
- mysql_unlock_some_tables(thd, &table,1);
+ if (always_unlock == TRUE)
+ mysql_unlock_some_tables(thd, &table, /* table count */ 1);
if (locked)
{
reg1 uint i;
@@ -396,6 +490,10 @@ void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table)
DBUG_ASSERT(table->lock_position == i);
+ /* Unlock if not yet unlocked */
+ if (always_unlock == FALSE)
+ mysql_unlock_some_tables(thd, &table, /* table count */ 1);
+
/* Decrement table_count in advance, making below expressions easier */
old_tables= --locked->table_count;
@@ -445,7 +543,8 @@ void mysql_lock_downgrade_write(THD *thd, TABLE *table,
{
MYSQL_LOCK *locked;
TABLE *write_lock_used;
- if ((locked = get_lock_data(thd,&table,1,1,&write_lock_used)))
+ if ((locked = get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK,
+ &write_lock_used)))
{
for (uint i=0; i < locked->lock_count; i++)
thr_downgrade_write_lock(locked->locks[i], new_lock_type);
@@ -704,25 +803,19 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
TABLE **to, **table_buf;
DBUG_ENTER("get_lock_data");
+ DBUG_ASSERT((flags == GET_LOCK_UNLOCK) || (flags == GET_LOCK_STORE_LOCKS));
+
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 != NON_TRANSACTIONAL_TMP_TABLE)
+ TABLE *t= table_ptr[i];
+
+ if (t->s->tmp_table != NON_TRANSACTIONAL_TMP_TABLE)
{
- tables+=table_ptr[i]->file->lock_count();
+ tables+= t->file->lock_count();
lock_count++;
}
- /*
- Check if we can lock the table. For some tables we cannot do that
- beacause of handler-specific locking issues.
- */
- if (!table_ptr[i]-> file->
- check_if_locking_is_allowed(thd->lex->sql_command, thd->lex->type,
- table_ptr[i], count, i, &system_count,
- logger.is_privileged_thread(thd)))
- DBUG_RETURN(0);
}
/*
diff --git a/sql/log.cc b/sql/log.cc
index 0bf77d68410..dbb664c9d18 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -57,6 +57,35 @@ static int binlog_commit(handlerton *hton, THD *thd, bool all);
static int binlog_rollback(handlerton *hton, THD *thd, bool all);
static int binlog_prepare(handlerton *hton, THD *thd, bool all);
+/**
+ Silence all errors and warnings reported when performing a write
+ to a log table.
+ Errors and warnings are not reported to the client or SQL exception
+ handlers, so that the presence of logging does not interfere and affect
+ the logic of an application.
+*/
+class Silence_log_table_errors : public Internal_error_handler
+{
+public:
+ Silence_log_table_errors()
+ {}
+
+ virtual ~Silence_log_table_errors() {}
+
+ virtual bool handle_error(uint sql_errno,
+ MYSQL_ERROR::enum_warning_level level,
+ THD *thd);
+};
+
+bool
+Silence_log_table_errors::handle_error(uint /* sql_errno */,
+ MYSQL_ERROR::enum_warning_level /* level */,
+ THD * /* thd */)
+{
+ return TRUE;
+}
+
+
sql_print_message_func sql_print_message_handlers[3] =
{
sql_print_information,
@@ -187,6 +216,19 @@ public:
handlerton *binlog_hton;
+bool LOGGER::is_log_table_enabled(uint log_table_type)
+{
+ switch (log_table_type) {
+ case QUERY_LOG_SLOW:
+ return (table_log_handler != NULL) && opt_slow_log;
+ case QUERY_LOG_GENERAL:
+ return (table_log_handler != NULL) && opt_log ;
+ default:
+ DBUG_ASSERT(0);
+ return FALSE; /* make compiler happy */
+ }
+}
+
/* Check if a given table is opened log table */
int check_if_log_table(uint db_len, const char *db, uint table_name_len,
@@ -200,211 +242,38 @@ int check_if_log_table(uint db_len, const char *db, uint table_name_len,
if (table_name_len == 11 && !(lower_case_table_names ?
my_strcasecmp(system_charset_info,
table_name, "general_log") :
- strcmp(table_name, "general_log")) &&
- (!check_if_opened || logger.is_log_table_enabled(QUERY_LOG_GENERAL)))
- return QUERY_LOG_GENERAL;
- else
- if (table_name_len == 8 && !(lower_case_table_names ?
- my_strcasecmp(system_charset_info, table_name, "slow_log") :
- strcmp(table_name, "slow_log")) &&
- (!check_if_opened ||logger.is_log_table_enabled(QUERY_LOG_SLOW)))
+ strcmp(table_name, "general_log")))
+ {
+ if (!check_if_opened || logger.is_log_table_enabled(QUERY_LOG_GENERAL))
+ return QUERY_LOG_GENERAL;
+ return 0;
+ }
+
+ if (table_name_len == 8 && !(lower_case_table_names ?
+ my_strcasecmp(system_charset_info, table_name, "slow_log") :
+ strcmp(table_name, "slow_log")))
+ {
+ if (!check_if_opened || logger.is_log_table_enabled(QUERY_LOG_SLOW))
return QUERY_LOG_SLOW;
+ return 0;
+ }
}
return 0;
}
-/*
- Open log table of a given type (general or slow log)
-
- SYNOPSIS
- open_log_table()
-
- log_table_type type of the log table to open: QUERY_LOG_GENERAL
- or QUERY_LOG_SLOW
-
- DESCRIPTION
-
- The function opens a log table and marks it as such. Log tables are open
- during the whole time, while server is running. Except for the moments
- when they have to be reopened: during FLUSH LOGS and TRUNCATE. This
- function is invoked directly only once during startup. All subsequent
- calls happen through reopen_log_table(), which performs additional check.
-
- RETURN
- FALSE - OK
- TRUE - error occured
-*/
-
-bool Log_to_csv_event_handler::open_log_table(uint log_table_type)
-{
- THD *log_thd, *curr= current_thd;
- TABLE_LIST *table;
- bool error= FALSE;
- DBUG_ENTER("open_log_table");
-
- switch (log_table_type) {
- case QUERY_LOG_GENERAL:
- log_thd= general_log_thd;
- table= &general_log;
- /* clean up table before reuse/initial usage */
- bzero((char*) table, sizeof(TABLE_LIST));
- table->alias= table->table_name= (char*) "general_log";
- table->table_name_length= 11;
- break;
- case QUERY_LOG_SLOW:
- log_thd= slow_log_thd;
- table= &slow_log;
- bzero((char*) table, sizeof(TABLE_LIST));
- table->alias= table->table_name= (char*) "slow_log";
- table->table_name_length= 8;
- break;
- default:
- assert(0); // Impossible
- }
-
- /*
- This way we check that appropriate log thd was created ok during
- initialization. We cannot check "is_log_tables_initialized" var, as
- the very initialization is not finished until this function is
- completed in the very first time.
- */
- if (!log_thd)
- {
- DBUG_PRINT("error",("Cannot initialize log tables"));
- DBUG_RETURN(TRUE);
- }
-
- /*
- Set THD's thread_stack. This is needed to perform stack overrun
- check, which is done by some routines (e.g. open_table()).
- In the case we are called by thread, which already has this parameter
- set, we use this value. Otherwise we do a wild guess. This won't help
- to correctly track the stack overrun in these exceptional cases (which
- could probably happen only during startup and shutdown) but at least
- lets us to pass asserts.
- The problem stems from the fact that logger THDs are not real threads.
- */
- if (curr)
- log_thd->thread_stack= curr->thread_stack;
- else
- log_thd->thread_stack= (char*) &log_thd;
-
- log_thd->store_globals();
-
- table->lock_type= TL_WRITE_CONCURRENT_INSERT;
- table->db= log_thd->db;
- table->db_length= log_thd->db_length;
-
- lex_start(log_thd);
- log_thd->clear_error();
- if (simple_open_n_lock_tables(log_thd, table) ||
- table->table->file->extra(HA_EXTRA_MARK_AS_LOG_TABLE) ||
- table->table->file->ha_rnd_init(0))
- error= TRUE;
- else
- {
- table->table->use_all_columns();
- table->table->locked_by_logger= TRUE;
- table->table->no_replicate= TRUE;
-
- /* Honor next number columns if present */
- table->table->next_number_field= table->table->found_next_number_field;
- }
- /* restore thread settings */
- if (curr)
- curr->store_globals();
- else
- {
- my_pthread_setspecific_ptr(THR_THD, 0);
- my_pthread_setspecific_ptr(THR_MALLOC, 0);
- }
-
- /*
- After a log table was opened, we should clear privileged thread
- flag (which allows locking of a log table by a special thread, usually
- the one who closed log tables temporarily).
- */
- privileged_thread= 0;
- DBUG_RETURN(error);
-}
-
-
Log_to_csv_event_handler::Log_to_csv_event_handler()
{
- /* init artificial THD's */
- general_log_thd= new THD;
- /* logger thread always works with mysql database */
- general_log_thd->db= my_strdup("mysql", MYF(0));
- general_log_thd->db_length= 5;
- general_log.table= 0;
-
- slow_log_thd= new THD;
- /* logger thread always works with mysql database */
- slow_log_thd->db= my_strdup("mysql", MYF(0));;
- slow_log_thd->db_length= 5;
- slow_log.table= 0;
- /* no privileged thread exists at the moment */
- privileged_thread= 0;
}
Log_to_csv_event_handler::~Log_to_csv_event_handler()
{
- /* now cleanup the tables */
- if (general_log_thd)
- {
- delete general_log_thd;
- general_log_thd= NULL;
- }
-
- if (slow_log_thd)
- {
- delete slow_log_thd;
- slow_log_thd= NULL;
- }
-}
-
-
-/*
- Reopen log table of a given type
-
- SYNOPSIS
- reopen_log_table()
-
- log_table_type type of the log table to open: QUERY_LOG_GENERAL
- or QUERY_LOG_SLOW
-
- DESCRIPTION
-
- The function is a wrapper around open_log_table(). It is used during
- FLUSH LOGS and TRUNCATE of the log tables (i.e. when we need to close
- and reopen them). The difference is in the check of the
- logger.is_log_tables_initialized var, which can't be done in
- open_log_table(), as it makes no sense during startup.
-
- NOTE: this code assumes that we have logger mutex locked
-
- RETURN
- FALSE - ok
- TRUE - open_log_table() returned an error
-*/
-
-bool Log_to_csv_event_handler::reopen_log_table(uint log_table_type)
-{
- /* don't open the log table, if it wasn't enabled during startup */
- if (!logger.is_log_tables_initialized)
- return FALSE;
- return open_log_table(log_table_type);
}
void Log_to_csv_event_handler::cleanup()
{
- if (opt_log)
- close_log_table(QUERY_LOG_GENERAL, FALSE);
- if (opt_slow_log)
- close_log_table(QUERY_LOG_SLOW, FALSE);
logger.is_log_tables_initialized= FALSE;
}
@@ -436,49 +305,88 @@ void Log_to_csv_event_handler::cleanup()
*/
bool Log_to_csv_event_handler::
- log_general(time_t event_time, const char *user_host,
+ log_general(THD *thd, time_t event_time, const char *user_host,
uint user_host_len, int thread_id,
const char *command_type, uint command_type_len,
const char *sql_text, uint sql_text_len,
CHARSET_INFO *client_cs)
{
- TABLE *table= general_log.table;
+ TABLE_LIST table_list;
+ TABLE *table;
+ bool result= TRUE;
+ bool need_close= FALSE;
+ bool need_pop= FALSE;
+ bool need_rnd_end= FALSE;
uint field_index;
+ Silence_log_table_errors error_handler;
+ Open_tables_state open_tables_backup;
+ Field_timestamp *field0;
+ ulonglong save_thd_options;
+ bool save_query_start_used;
+ time_t save_start_time;
+ time_t save_time_after_lock;
+ time_t save_user_time;
+ bool save_time_zone_used;
+
+ save_thd_options= thd->options;
+ thd->options&= ~OPTION_BIN_LOG;
+
+ save_query_start_used= thd->query_start_used;
+ save_start_time= thd->start_time;
+ save_time_after_lock= thd->time_after_lock;
+ save_user_time= thd->user_time;
+ save_time_zone_used= thd->time_zone_used;
+
+ bzero(& table_list, sizeof(TABLE_LIST));
+ table_list.alias= table_list.table_name= GENERAL_LOG_NAME.str;
+ table_list.table_name_length= GENERAL_LOG_NAME.length;
+
+ table_list.lock_type= TL_WRITE_CONCURRENT_INSERT;
+
+ table_list.db= MYSQL_SCHEMA_NAME.str;
+ table_list.db_length= MYSQL_SCHEMA_NAME.length;
+
+ table= open_performance_schema_table(thd, & table_list,
+ & open_tables_backup);
+ need_close= TRUE;
+
+ if (!table ||
+ table->file->extra(HA_EXTRA_MARK_AS_LOG_TABLE) ||
+ table->file->ha_rnd_init(0))
+ goto err;
+
+ need_rnd_end= TRUE;
+
+ /* Honor next number columns if present */
+ table->next_number_field= table->found_next_number_field;
/*
"INSERT INTO general_log" can generate warning sometimes.
- Let's reset warnings from previous queries,
- otherwise warning list can grow too much,
- so thd->query gets spoiled as some point in time,
- and mysql_parse() receives a broken query.
QQ: this problem needs to be studied in more details.
- Probably it's better to suppress warnings in logging INSERTs at all.
- Comment this line and run "cast.test" to see what's happening:
+ Comment this 2 lines and run "cast.test" to see what's happening:
*/
- mysql_reset_errors(table->in_use, 1);
-
- /* below should never happen */
- if (unlikely(!logger.is_log_tables_initialized))
- return FALSE;
+ thd->push_internal_handler(& error_handler);
+ need_pop= TRUE;
/*
NOTE: we do not call restore_record() here, as all fields are
filled by the Logger (=> no need to load default ones).
*/
- /* Set current time. Required for CURRENT_TIMESTAMP to work */
- general_log_thd->start_time= event_time;
-
/*
We do not set a value for table->field[0], as it will use
default value (which is CURRENT_TIMESTAMP).
*/
/* check that all columns exist */
- if (!table->field[1] || !table->field[2] || !table->field[3] ||
- !table->field[4] || !table->field[5])
+ if (table->s->fields < 6)
goto err;
+ DBUG_ASSERT(table->field[0]->type() == MYSQL_TYPE_TIMESTAMP);
+
+ field0= (Field_timestamp*) (table->field[0]);
+ field0->set_time();
+
/* do a write */
if (table->field[1]->store(user_host, user_host_len, client_cs) ||
table->field[2]->store((longlong) thread_id, TRUE) ||
@@ -500,16 +408,39 @@ bool Log_to_csv_event_handler::
table->field[field_index]->set_default();
}
- /* log table entries are not replicated at the moment */
- tmp_disable_binlog(current_thd);
+ /* log table entries are not replicated */
+ if (table->file->ha_write_row(table->record[0]))
+ {
+ struct tm start;
+ localtime_r(&event_time, &start);
- table->file->ha_write_row(table->record[0]);
+ 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);
+ }
- reenable_binlog(current_thd);
+ result= FALSE;
- return FALSE;
err:
- return TRUE;
+ if (need_rnd_end)
+ {
+ table->file->ha_rnd_end();
+ table->file->ha_release_auto_increment();
+ }
+ if (need_pop)
+ thd->pop_internal_handler();
+ if (need_close)
+ close_performance_schema_table(thd, & open_tables_backup);
+
+ thd->options= save_thd_options;
+
+ thd->query_start_used= save_query_start_used;
+ thd->start_time= save_start_time;
+ thd->time_after_lock= save_time_after_lock;
+ thd->user_time= save_user_time;
+ thd->time_zone_used= save_time_zone_used;
+ return result;
}
@@ -548,34 +479,61 @@ bool Log_to_csv_event_handler::
longlong query_time, longlong lock_time, bool is_command,
const char *sql_text, uint sql_text_len)
{
- /* table variables */
- TABLE *table= slow_log.table;
+ TABLE_LIST table_list;
+ TABLE *table;
+ bool result= TRUE;
+ bool need_close= FALSE;
+ bool need_rnd_end= FALSE;
+ Open_tables_state open_tables_backup;
+ bool save_query_start_used;
+ time_t save_start_time;
+ time_t save_time_after_lock;
+ time_t save_user_time;
+ bool save_time_zone_used;
CHARSET_INFO *client_cs= thd->variables.character_set_client;
- DBUG_ENTER("log_slow");
+ DBUG_ENTER("Log_to_csv_event_handler::log_slow");
- /* below should never happen */
- if (unlikely(!logger.is_log_tables_initialized))
- return FALSE;
+ bzero(& table_list, sizeof(TABLE_LIST));
+ table_list.alias= table_list.table_name= SLOW_LOG_NAME.str;
+ table_list.table_name_length= SLOW_LOG_NAME.length;
+
+ table_list.lock_type= TL_WRITE_CONCURRENT_INSERT;
+
+ table_list.db= MYSQL_SCHEMA_NAME.str;
+ table_list.db_length= MYSQL_SCHEMA_NAME.length;
+
+ save_query_start_used= thd->query_start_used;
+ save_start_time= thd->start_time;
+ save_time_after_lock= thd->time_after_lock;
+ save_user_time= thd->user_time;
+ save_time_zone_used= thd->time_zone_used;
+
+ table= open_performance_schema_table(thd, & table_list,
+ & open_tables_backup);
+ need_close= TRUE;
+
+ if (!table ||
+ table->file->extra(HA_EXTRA_MARK_AS_LOG_TABLE) ||
+ table->file->ha_rnd_init(0))
+ goto err;
+
+ need_rnd_end= TRUE;
+
+ /* Honor next number columns if present */
+ table->next_number_field= table->found_next_number_field;
- /*
- Set start time for CURRENT_TIMESTAMP to the start of the query.
- This will be default value for the field[0]
- */
- slow_log_thd->start_time= query_start_arg;
restore_record(table, s->default_values); // Get empty record
+ /* check that all columns exist */
+ if (table->s->fields < 11)
+ goto err;
+
/*
We do not set a value for table->field[0], as it will use
default value.
*/
- if (!table->field[1] || !table->field[2] || !table->field[3] ||
- !table->field[4] || !table->field[5] || !table->field[6] ||
- !table->field[7] || !table->field[8] || !table->field[9] ||
- !table->field[10])
- goto err;
-
/* store the value */
if (table->field[1]->store(user_host, user_host_len, client_cs))
goto err;
@@ -612,7 +570,6 @@ bool Log_to_csv_event_handler::
table->field[4]->set_null();
table->field[5]->set_null();
}
-
/* fill database field */
if (thd->db)
{
@@ -654,17 +611,71 @@ bool Log_to_csv_event_handler::
if (table->field[10]->store(sql_text,sql_text_len, client_cs))
goto err;
- /* log table entries are not replicated at the moment */
- tmp_disable_binlog(current_thd);
+ /* log table entries are not replicated */
+ if (table->file->ha_write_row(table->record[0]))
+ {
+ struct tm start;
+ localtime_r(&current_time, &start);
- /* write the row */
- table->file->ha_write_row(table->record[0]);
+ 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);
+ }
- reenable_binlog(current_thd);
+ result= FALSE;
- DBUG_RETURN(0);
err:
- DBUG_RETURN(1);
+ if (need_rnd_end)
+ {
+ table->file->ha_rnd_end();
+ table->file->ha_release_auto_increment();
+ }
+ if (need_close)
+ close_performance_schema_table(thd, & open_tables_backup);
+
+ thd->query_start_used= save_query_start_used;
+ thd->start_time= save_start_time;
+ thd->time_after_lock= save_time_after_lock;
+ thd->user_time= save_user_time;
+ thd->time_zone_used= save_time_zone_used;
+ DBUG_RETURN(result);
+}
+
+int Log_to_csv_event_handler::
+ activate_log(THD *thd, uint log_table_type)
+{
+ TABLE_LIST table_list;
+ TABLE *table;
+ int result;
+ Open_tables_state open_tables_backup;
+
+ DBUG_ENTER("Log_to_csv_event_handler::activate_log");
+
+ bzero(& table_list, sizeof(TABLE_LIST));
+
+ if (log_table_type == QUERY_LOG_GENERAL)
+ {
+ table_list.alias= table_list.table_name= GENERAL_LOG_NAME.str;
+ table_list.table_name_length= GENERAL_LOG_NAME.length;
+ }
+ else
+ {
+ DBUG_ASSERT(log_table_type == QUERY_LOG_SLOW);
+ table_list.alias= table_list.table_name= SLOW_LOG_NAME.str;
+ table_list.table_name_length= SLOW_LOG_NAME.length;
+ }
+
+ table_list.lock_type= TL_WRITE_CONCURRENT_INSERT;
+
+ table_list.db= MYSQL_SCHEMA_NAME.str;
+ table_list.db_length= MYSQL_SCHEMA_NAME.length;
+
+ table= open_performance_schema_table(thd, & table_list,
+ & open_tables_backup);
+ result= (table ? 0 : 1);
+ close_performance_schema_table(thd, & open_tables_backup);
+ DBUG_RETURN(result);
}
bool Log_to_csv_event_handler::
@@ -710,7 +721,7 @@ bool Log_to_file_event_handler::
*/
bool Log_to_file_event_handler::
- log_general(time_t event_time, const char *user_host,
+ log_general(THD *thd, time_t event_time, const char *user_host,
uint user_host_len, int thread_id,
const char *command_type, uint command_type_len,
const char *sql_text, uint sql_text_len,
@@ -787,7 +798,7 @@ bool LOGGER::error_log_print(enum loglevel level, const char *format,
void LOGGER::cleanup_base()
{
DBUG_ASSERT(inited == 1);
- (void) pthread_mutex_destroy(&LOCK_logger);
+ rwlock_destroy(&LOCK_logger);
if (table_log_handler)
{
table_log_handler->cleanup();
@@ -806,12 +817,6 @@ void LOGGER::cleanup_end()
}
-void LOGGER::close_log_table(uint log_table_type, bool lock_in_use)
-{
- table_log_handler->close_log_table(log_table_type, lock_in_use);
-}
-
-
/*
Perform basic log initialization: create file-based log handler and
init error log.
@@ -833,7 +838,7 @@ void LOGGER::init_base()
init_error_log(LOG_FILE);
file_log_handler->init_pthread_objects();
- (void) pthread_mutex_init(&LOCK_logger, MY_MUTEX_INIT_SLOW);
+ my_rwlock_init(&LOCK_logger, NULL);
}
@@ -848,29 +853,6 @@ void LOGGER::init_log_tables()
}
-bool LOGGER::reopen_log_table(uint log_table_type)
-{
- return table_log_handler->reopen_log_table(log_table_type);
-}
-
-bool LOGGER::reopen_log_tables()
-{
- /*
- we use | and not || here, to ensure that both reopen_log_table
- are called, even if the first one fails
- */
- if ((opt_slow_log && logger.reopen_log_table(QUERY_LOG_SLOW)) |
- (opt_log && logger.reopen_log_table(QUERY_LOG_GENERAL)))
- return TRUE;
- return FALSE;
-}
-
-
-void LOGGER::tmp_close_log_tables(THD *thd)
-{
- table_log_handler->tmp_close_log_tables(thd);
-}
-
bool LOGGER::flush_logs(THD *thd)
{
int rc= 0;
@@ -879,19 +861,11 @@ bool LOGGER::flush_logs(THD *thd)
Now we lock logger, as nobody should be able to use logging routines while
log tables are closed
*/
- logger.lock();
- if (logger.is_log_tables_initialized)
- table_log_handler->tmp_close_log_tables(thd); // the locking happens here
+ logger.lock_exclusive();
/* reopen log files */
file_log_handler->flush();
- /* reopen tables in the case they were enabled */
- if (logger.is_log_tables_initialized)
- {
- if (reopen_log_tables())
- rc= TRUE;
- }
/* end of log flush */
logger.unlock();
return rc;
@@ -939,7 +913,7 @@ bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length,
if (thd->slave_thread)
return 0;
- lock();
+ lock_shared();
if (!opt_slow_log)
{
unlock();
@@ -1011,7 +985,7 @@ bool LOGGER::general_log_print(THD *thd, enum enum_server_command command,
else
id=0; /* Log from connect handler */
- lock();
+ lock_shared();
if (!opt_log)
{
unlock();
@@ -1035,7 +1009,7 @@ bool LOGGER::general_log_print(THD *thd, enum enum_server_command command,
while (*current_handler)
error+= (*current_handler++)->
- log_general(current_time, user_host_buff,
+ log_general(thd, current_time, user_host_buff,
user_host_len, id,
command_name[(uint) command].str,
command_name[(uint) command].length,
@@ -1122,35 +1096,51 @@ void LOGGER::init_general_log(uint general_log_printer)
bool LOGGER::activate_log_handler(THD* thd, uint log_type)
{
- bool res= 0;
- lock();
+ MYSQL_QUERY_LOG *file_log;
+ bool res= FALSE;
+ lock_exclusive();
switch (log_type) {
case QUERY_LOG_SLOW:
if (!opt_slow_log)
{
- if ((res= reopen_log_table(log_type)))
- goto err;
- file_log_handler->get_mysql_slow_log()->
- open_slow_log(sys_var_slow_log_path.value);
- init_slow_log(log_output_options);
- opt_slow_log= TRUE;
+ file_log= file_log_handler->get_mysql_slow_log();
+
+ file_log->open_slow_log(sys_var_slow_log_path.value);
+ if (table_log_handler->activate_log(thd, QUERY_LOG_SLOW))
+ {
+ /* Error printed by open table in activate_log() */
+ res= TRUE;
+ file_log->close(0);
+ }
+ else
+ {
+ init_slow_log(log_output_options);
+ opt_slow_log= TRUE;
+ }
}
break;
case QUERY_LOG_GENERAL:
if (!opt_log)
{
- if ((res= reopen_log_table(log_type)))
- goto err;
- file_log_handler->get_mysql_log()->
- open_query_log(sys_var_general_log_path.value);
- init_general_log(log_output_options);
- opt_log= TRUE;
+ file_log= file_log_handler->get_mysql_log();
+
+ file_log->open_query_log(sys_var_general_log_path.value);
+ if (table_log_handler->activate_log(thd, QUERY_LOG_GENERAL))
+ {
+ /* Error printed by open table in activate_log() */
+ res= TRUE;
+ file_log->close(0);
+ }
+ else
+ {
+ init_general_log(log_output_options);
+ opt_log= TRUE;
+ }
}
break;
default:
DBUG_ASSERT(0);
}
-err:
unlock();
return res;
}
@@ -1158,23 +1148,17 @@ err:
void LOGGER::deactivate_log_handler(THD *thd, uint log_type)
{
- TABLE_LIST *table_list;
my_bool *tmp_opt= 0;
MYSQL_LOG *file_log;
- THD *log_thd;
switch (log_type) {
case QUERY_LOG_SLOW:
- table_list= &table_log_handler->slow_log;
tmp_opt= &opt_slow_log;
file_log= file_log_handler->get_mysql_slow_log();
- log_thd= table_log_handler->slow_log_thd;
break;
case QUERY_LOG_GENERAL:
- table_list= &table_log_handler->general_log;
tmp_opt= &opt_log;
file_log= file_log_handler->get_mysql_log();
- log_thd= table_log_handler->general_log_thd;
break;
default:
assert(0); // Impossible
@@ -1183,81 +1167,16 @@ void LOGGER::deactivate_log_handler(THD *thd, uint log_type)
if (!(*tmp_opt))
return;
- if (is_log_tables_initialized)
- lock_and_wait_for_table_name(log_thd, table_list);
- lock();
-
- if (is_log_tables_initialized)
- {
- VOID(pthread_mutex_lock(&LOCK_open));
- close_log_table(log_type, TRUE);
- table_list->table= 0;
- query_cache_invalidate3(log_thd, table_list, 0);
- unlock_table_name(log_thd, table_list);
- VOID(pthread_mutex_unlock(&LOCK_open));
- }
+ lock_exclusive();
file_log->close(0);
*tmp_opt= FALSE;
unlock();
}
-/*
- Close log tables temporarily. The thread which closed
- them this way can lock them in any mode it needs.
- NOTE: one should call logger.lock() before entering this
- function.
-*/
-void Log_to_csv_event_handler::tmp_close_log_tables(THD *thd)
-{
- TABLE_LIST close_slow_log, close_general_log;
-
- /* fill lists, we will need to perform operations on tables */
- bzero((char*) &close_slow_log, sizeof(TABLE_LIST));
- close_slow_log.alias= close_slow_log.table_name=(char*) "slow_log";
- close_slow_log.table_name_length= 8;
- close_slow_log.db= (char*) "mysql";
- close_slow_log.db_length= 5;
-
- bzero((char*) &close_general_log, sizeof(TABLE_LIST));
- close_general_log.alias= close_general_log.table_name=(char*) "general_log";
- close_general_log.table_name_length= 11;
- close_general_log.db= (char*) "mysql";
- close_general_log.db_length= 5;
-
- privileged_thread= thd;
-
- VOID(pthread_mutex_lock(&LOCK_open));
- /*
- NOTE: in fact, the first parameter used in query_cache_invalidate3()
- could be any non-NULL THD, as the underlying code makes certain
- assumptions about this.
- Here we use one of the logger handler THD's. Simply because it
- seems appropriate.
- */
- if (opt_log)
- {
- close_log_table(QUERY_LOG_GENERAL, TRUE);
- query_cache_invalidate3(general_log_thd, &close_general_log, 0);
- }
- if (opt_slow_log)
- {
- close_log_table(QUERY_LOG_SLOW, TRUE);
- query_cache_invalidate3(general_log_thd, &close_slow_log, 0);
- }
- VOID(pthread_mutex_unlock(&LOCK_open));
-}
-
/* the parameters are unused for the log tables */
bool Log_to_csv_event_handler::init()
{
- /*
- we use | and not || here, to ensure that both open_log_table
- are called, even if the first one fails
- */
- if ((opt_log && open_log_table(QUERY_LOG_GENERAL)) |
- (opt_slow_log && open_log_table(QUERY_LOG_SLOW)))
- return 1;
return 0;
}
@@ -1268,7 +1187,7 @@ int LOGGER::set_handlers(uint error_log_printer,
/* error log table is not supported yet */
DBUG_ASSERT(error_log_printer < LOG_TABLE);
- lock();
+ lock_exclusive();
if ((slow_log_printer & LOG_TABLE || general_log_printer & LOG_TABLE) &&
!is_log_tables_initialized)
@@ -1290,72 +1209,6 @@ int LOGGER::set_handlers(uint error_log_printer,
}
-/*
- Close log table of a given type (general or slow log)
-
- SYNOPSIS
- close_log_table()
-
- log_table_type type of the log table to close: QUERY_LOG_GENERAL
- or QUERY_LOG_SLOW
- lock_in_use Set to TRUE if the caller owns LOCK_open. FALSE otherwise.
-
- DESCRIPTION
-
- The function closes a log table. It is invoked (1) when we need to reopen
- log tables (e.g. FLUSH LOGS or TRUNCATE on the log table is being
- executed) or (2) during shutdown.
-*/
-
-void Log_to_csv_event_handler::
- close_log_table(uint log_table_type, bool lock_in_use)
-{
- THD *log_thd, *curr= current_thd;
- TABLE_LIST *table;
-
- if (!logger.is_log_table_enabled(log_table_type))
- return; /* do nothing */
-
- switch (log_table_type) {
- case QUERY_LOG_GENERAL:
- log_thd= general_log_thd;
- table= &general_log;
- break;
- case QUERY_LOG_SLOW:
- log_thd= slow_log_thd;
- table= &slow_log;
- break;
- default:
- assert(0); // Impossible
- }
-
- /*
- Set thread stack start for the logger thread. See comment in
- open_log_table() for details.
- */
- if (curr)
- log_thd->thread_stack= curr->thread_stack;
- else
- log_thd->thread_stack= (char*) &log_thd;
-
- /* close the table */
- log_thd->store_globals();
- table->table->file->ha_rnd_end();
- table->table->file->ha_release_auto_increment();
- /* discard logger mark before unlock*/
- table->table->locked_by_logger= FALSE;
- close_thread_tables(log_thd, lock_in_use);
-
- if (curr)
- curr->store_globals();
- else
- {
- my_pthread_setspecific_ptr(THR_THD, 0);
- my_pthread_setspecific_ptr(THR_MALLOC, 0);
- }
-}
-
-
/*
Save position of binary log transaction cache.
@@ -2097,6 +1950,8 @@ bool MYSQL_QUERY_LOG::write(time_t event_time, const char *user_host,
struct tm start;
uint time_buff_len= 0;
+ (void) pthread_mutex_lock(&LOCK_log);
+
/* Test if someone closed between the is_open test and lock */
if (is_open())
{
@@ -2141,6 +1996,7 @@ bool MYSQL_QUERY_LOG::write(time_t event_time, const char *user_host,
goto err;
}
+ (void) pthread_mutex_unlock(&LOCK_log);
return FALSE;
err:
@@ -2149,6 +2005,7 @@ err:
write_error= 1;
sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
}
+ (void) pthread_mutex_unlock(&LOCK_log);
return TRUE;
}
@@ -2191,8 +2048,13 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time,
bool error= 0;
DBUG_ENTER("MYSQL_QUERY_LOG::write");
+ (void) pthread_mutex_lock(&LOCK_log);
+
if (!is_open())
+ {
+ (void) pthread_mutex_unlock(&LOCK_log);
DBUG_RETURN(0);
+ }
if (is_open())
{ // Safety agains reopen
@@ -2296,6 +2158,7 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time,
}
}
}
+ (void) pthread_mutex_unlock(&LOCK_log);
DBUG_RETURN(error);
}
diff --git a/sql/log.h b/sql/log.h
index d92e0117bcc..3b1a0950daa 100644
--- a/sql/log.h
+++ b/sql/log.h
@@ -212,6 +212,7 @@ public:
return open(generate_name(log_name, ".log", 0, buf), LOG_NORMAL, 0,
WRITE_CACHE);
}
+
private:
time_t last_time;
};
@@ -398,7 +399,7 @@ public:
const char *sql_text, uint sql_text_len)= 0;
virtual bool log_error(enum loglevel level, const char *format,
va_list args)= 0;
- virtual bool log_general(time_t event_time, const char *user_host,
+ virtual bool log_general(THD *thd, time_t event_time, const char *user_host,
uint user_host_len, int thread_id,
const char *command_type, uint command_type_len,
const char *sql_text, uint sql_text_len,
@@ -412,27 +413,7 @@ int check_if_log_table(uint db_len, const char *db, uint table_name_len,
class Log_to_csv_event_handler: public Log_event_handler
{
- /*
- We create artificial THD for each of the logs. This is to avoid
- locking issues: we don't want locks on the log tables reside in the
- THD's of the query. The reason is the locking order and duration.
- */
- THD *general_log_thd, *slow_log_thd;
- /*
- This is for the thread, which called tmp_close_log_tables. The thread
- will be allowed to write-lock the log tables (as it explicitly disabled
- logging). This is used for such operations as REPAIR, which require
- exclusive lock on the log tables.
- NOTE: there can be only one priviliged thread, as one should
- lock logger with logger.lock() before calling tmp_close_log_tables().
- So no other thread could get privileged status at the same time.
- */
- THD *privileged_thread;
friend class LOGGER;
- TABLE_LIST general_log, slow_log;
-
-private:
- bool open_log_table(uint log_type);
public:
Log_to_csv_event_handler();
@@ -447,18 +428,13 @@ public:
const char *sql_text, uint sql_text_len);
virtual bool log_error(enum loglevel level, const char *format,
va_list args);
- virtual bool log_general(time_t event_time, const char *user_host,
+ virtual bool log_general(THD *thd, time_t event_time, const char *user_host,
uint user_host_len, int thread_id,
const char *command_type, uint command_type_len,
const char *sql_text, uint sql_text_len,
- CHARSET_INFO *client_cs);
- void tmp_close_log_tables(THD *thd);
- void close_log_table(uint log_type, bool lock_in_use);
- bool reopen_log_table(uint log_type);
- THD* get_privileged_thread()
- {
- return privileged_thread;
- }
+ CHARSET_INFO *client_cs);
+
+ int activate_log(THD *thd, uint log_type);
};
@@ -484,7 +460,7 @@ public:
const char *sql_text, uint sql_text_len);
virtual bool log_error(enum loglevel level, const char *format,
va_list args);
- virtual bool log_general(time_t event_time, const char *user_host,
+ virtual bool log_general(THD *thd, time_t event_time, const char *user_host,
uint user_host_len, int thread_id,
const char *command_type, uint command_type_len,
const char *sql_text, uint sql_text_len,
@@ -499,7 +475,7 @@ public:
/* Class which manages slow, general and error log event handlers */
class LOGGER
{
- pthread_mutex_t LOCK_logger;
+ rw_lock_t LOCK_logger;
/* flag to check whether logger mutex is initialized */
uint inited;
@@ -519,21 +495,10 @@ public:
LOGGER() : inited(0), table_log_handler(NULL),
file_log_handler(NULL), is_log_tables_initialized(FALSE)
{}
- void lock() { (void) pthread_mutex_lock(&LOCK_logger); }
- void unlock() { (void) pthread_mutex_unlock(&LOCK_logger); }
- void tmp_close_log_tables(THD *thd);
- bool is_log_table_enabled(uint log_table_type)
- {
- switch (log_table_type) {
- case QUERY_LOG_SLOW:
- return table_log_handler && table_log_handler->slow_log.table != 0;
- case QUERY_LOG_GENERAL:
- return table_log_handler && table_log_handler->general_log.table != 0;
- default:
- DBUG_ASSERT(0);
- return FALSE; /* make compiler happy */
- }
- }
+ void lock_shared() { rw_rdlock(&LOCK_logger); }
+ void lock_exclusive() { rw_wrlock(&LOCK_logger); }
+ void unlock() { rw_unlock(&LOCK_logger); }
+ bool is_log_table_enabled(uint log_table_type);
/*
We want to initialize all log mutexes as soon as possible,
but we cannot do it in constructor, as safe_mutex relies on
@@ -543,20 +508,6 @@ public:
void init_base();
void init_log_tables();
bool flush_logs(THD *thd);
- THD *get_general_log_thd()
- {
- if (table_log_handler)
- return (THD *) table_log_handler->general_log_thd;
- else
- return NULL;
- }
- THD *get_slow_log_thd()
- {
- if (table_log_handler)
- return (THD *) table_log_handler->slow_log_thd;
- else
- return NULL;
- }
/* Perform basic logger cleanup. this will leave e.g. error log open. */
void cleanup_base();
/* Free memory. Nothing could be logged after this function is called */
@@ -568,10 +519,6 @@ public:
bool general_log_print(THD *thd,enum enum_server_command command,
const char *format, va_list args);
- void close_log_table(uint log_type, bool lock_in_use);
- bool reopen_log_table(uint log_type);
- bool reopen_log_tables();
-
/* we use this function to setup all enabled log event handlers */
int set_handlers(uint error_log_printer,
uint slow_log_printer,
@@ -593,19 +540,6 @@ public:
return file_log_handler->get_mysql_log();
return NULL;
}
- THD* get_privileged_thread()
- {
- if (table_log_handler)
- return table_log_handler->get_privileged_thread();
- else
- return NULL;
- }
- bool is_privileged_thread(THD *thd)
- {
- return thd == get_general_log_thd() ||
- thd == get_slow_log_thd() ||
- thd == get_privileged_thread();
- }
};
enum enum_binlog_format {
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 7b7bc81957e..2fe70980ea8 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -944,6 +944,7 @@ void mysql_parse(THD *thd, const char *inBuf, uint length,
bool mysql_test_parse_for_slave(THD *thd,char *inBuf,uint length);
bool is_update_query(enum enum_sql_command command);
+bool is_log_table_write_query(enum enum_sql_command command);
bool alloc_query(THD *thd, const char *packet, uint packet_length);
void mysql_init_select(LEX *lex);
void mysql_reset_thd_for_next_command(THD *thd);
@@ -1123,7 +1124,8 @@ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key,
uint key_length, uint db_flags, int *error);
void release_table_share(TABLE_SHARE *share, enum release_type type);
TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name);
-TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update);
+TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update,
+ uint lock_flags);
TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT* mem,
bool *refresh, uint flags);
bool reopen_name_locked_table(THD* thd, TABLE_LIST* table_list, bool link_in);
@@ -1231,6 +1233,11 @@ void reset_status_vars();
/* information schema */
extern LEX_STRING INFORMATION_SCHEMA_NAME;
+/* log tables */
+extern LEX_STRING MYSQL_SCHEMA_NAME;
+extern LEX_STRING GENERAL_LOG_NAME;
+extern LEX_STRING SLOW_LOG_NAME;
+
extern const LEX_STRING partition_keywords[];
ST_SCHEMA_TABLE *find_schema_table(THD *thd, const char* table_name);
ST_SCHEMA_TABLE *get_schema_table(enum enum_schema_tables schema_table_idx);
@@ -1557,6 +1564,10 @@ bool open_system_tables_for_read(THD *thd, TABLE_LIST *table_list,
void close_system_tables(THD *thd, Open_tables_state *backup);
TABLE *open_system_table_for_update(THD *thd, TABLE_LIST *one_table);
+TABLE *open_performance_schema_table(THD *thd, TABLE_LIST *one_table,
+ Open_tables_state *backup);
+void close_performance_schema_table(THD *thd, Open_tables_state *backup);
+
bool close_cached_tables(THD *thd, bool wait_for_refresh, TABLE_LIST *tables, bool have_lock = FALSE);
bool close_cached_connection_tables(THD *thd, bool wait_for_refresh,
LEX_STRING *connect_string,
@@ -1891,11 +1902,13 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **table, uint count,
#define MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN 0x0004
#define MYSQL_OPEN_TEMPORARY_ONLY 0x0008
#define MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY 0x0010
+#define MYSQL_LOCK_PERF_SCHEMA 0x0020
void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock);
void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock);
void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count);
-void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table);
+void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table,
+ bool always_unlock);
void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock);
void mysql_lock_downgrade_write(THD *thd, TABLE *table,
thr_lock_type new_lock_type);
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 7f3e808090d..d21a4c18716 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -2053,21 +2053,15 @@ end:
bool sys_var_log_state::update(THD *thd, set_var *var)
{
- bool res= 0;
+ bool res;
pthread_mutex_lock(&LOCK_global_system_variables);
if (!var->save_result.ulong_value)
- logger.deactivate_log_handler(thd, log_type);
- else
{
- if ((res= logger.activate_log_handler(thd, log_type)))
- {
- my_error(ER_CANT_ACTIVATE_LOG, MYF(0),
- log_type == QUERY_LOG_GENERAL ? "general" :
- "slow query");
- goto err;
- }
+ logger.deactivate_log_handler(thd, log_type);
+ res= false;
}
-err:
+ else
+ res= logger.activate_log_handler(thd, log_type);
pthread_mutex_unlock(&LOCK_global_system_variables);
return res;
}
@@ -2143,7 +2137,7 @@ bool update_sys_var_str_path(THD *thd, sys_var_str *var_str,
}
pthread_mutex_lock(&LOCK_global_system_variables);
- logger.lock();
+ logger.lock_exclusive();
if (file_log && log_state)
file_log->close(0);
@@ -2206,7 +2200,7 @@ static void sys_default_slow_log_path(THD *thd, enum_var_type type)
bool sys_var_log_output::update(THD *thd, set_var *var)
{
pthread_mutex_lock(&LOCK_global_system_variables);
- logger.lock();
+ logger.lock_exclusive();
logger.init_slow_log(var->save_result.ulong_value);
logger.init_general_log(var->save_result.ulong_value);
*value= var->save_result.ulong_value;
@@ -2219,7 +2213,7 @@ bool sys_var_log_output::update(THD *thd, set_var *var)
void sys_var_log_output::set_default(THD *thd, enum_var_type type)
{
pthread_mutex_lock(&LOCK_global_system_variables);
- logger.lock();
+ logger.lock_exclusive();
logger.init_slow_log(LOG_FILE);
logger.init_general_log(LOG_FILE);
*value= LOG_FILE;
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index 682eee06e02..966e841ccbf 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -5936,8 +5936,8 @@ ER_WARN_DEPRECATED_SYNTAX_WITH_VER
ER_CANT_WRITE_LOCK_LOG_TABLE
eng "You can't write-lock a log table. Only read access is possible"
ger "Eine Log-Tabelle kann nicht schreibgesperrt werden. Es ist ohnehin nur Lesezugriff möglich"
-ER_CANT_READ_LOCK_LOG_TABLE
- eng "You can't use usual read lock with log tables. Try READ LOCAL instead"
+ER_CANT_LOCK_LOG_TABLE
+ eng "You can't use locks with log tables."
ger "Log-Tabellen können nicht mit normalen Lesesperren gesperrt werden. Verwenden Sie statt dessen READ LOCAL"
ER_FOREIGN_DUPLICATE_KEY 23000 S1009
eng "Upholding foreign key constraints for table '%.192s', entry '%-.192s', key %d would lead to a duplicate entry"
diff --git a/sql/slave.cc b/sql/slave.cc
index 2e8e3f582de..96a105b06e4 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -977,7 +977,7 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db,
thd->proc_info = "Opening master dump table";
tables.lock_type = TL_WRITE;
- if (!open_ltable(thd, &tables, TL_WRITE))
+ if (!open_ltable(thd, &tables, TL_WRITE, 0))
{
sql_print_error("create_table_from_dump: could not open created table");
goto err;
diff --git a/sql/sp.cc b/sql/sp.cc
index aed4976f839..372aa9c6780 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -406,7 +406,7 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp)
if ((ret= db_find_routine_aux(thd, type, name, table)) != SP_OK)
goto done;
- if (table->s->fields != MYSQL_PROC_FIELD_COUNT)
+ if (table->s->fields < MYSQL_PROC_FIELD_COUNT)
{
ret= SP_GET_FIELD_FAILED;
goto done;
@@ -695,7 +695,7 @@ sp_create_routine(THD *thd, int type, sp_head *sp)
strxnmov(definer, sizeof(definer)-1, thd->lex->definer->user.str, "@",
thd->lex->definer->host.str, NullS);
- if (table->s->fields != MYSQL_PROC_FIELD_COUNT)
+ if (table->s->fields < MYSQL_PROC_FIELD_COUNT)
{
ret= SP_GET_FIELD_FAILED;
goto done;
@@ -1067,7 +1067,7 @@ sp_show_status_routine(THD *thd, int type, const char *name_pattern)
tables.db= (char*)"mysql";
tables.table_name= tables.alias= (char*)"proc";
- if (! (table= open_ltable(thd, &tables, TL_READ)))
+ if (! (table= open_ltable(thd, &tables, TL_READ, 0)))
{
res= SP_OPEN_TABLE_FAILED;
goto done;
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 67fa380d313..91f1570f653 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -1602,7 +1602,7 @@ bool change_password(THD *thd, const char *host, const char *user,
}
#endif
- if (!(table= open_ltable(thd, &tables, TL_WRITE)))
+ if (!(table= open_ltable(thd, &tables, TL_WRITE, 0)))
DBUG_RETURN(1);
VOID(pthread_mutex_lock(&acl_cache->lock));
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index f1319010270..cf3ef111780 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -902,8 +902,7 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
bool found=0;
for (TABLE_LIST *table= tables; table; table= table->next_local)
{
- if ((!table->table || !table->table->s->log_table) &&
- remove_table_from_cache(thd, table->db, table->table_name,
+ if (remove_table_from_cache(thd, table->db, table->table_name,
RTFC_OWNED_BY_THD_FLAG))
found=1;
}
@@ -951,8 +950,7 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
are employed by CREATE TABLE as in this case table simply does not
exist yet.
*/
- if (!table->s->log_table &&
- (table->needs_reopen_or_name_lock() && table->db_stat))
+ if (table->needs_reopen_or_name_lock() && table->db_stat)
{
found=1;
DBUG_PRINT("signal", ("Waiting for COND_refresh"));
@@ -1679,8 +1677,28 @@ TABLE *find_temporary_table(THD *thd, TABLE_LIST *table_list)
}
-/*
- Close temporary table and unlink from thd->temporary tables
+/**
+ Drop a temporary table.
+
+ Try to locate the table in the list of thd->temporary_tables.
+ If the table is found:
+ - if the table is in thd->locked_tables, unlock it and
+ remove it from the list of locked tables. Currently only transactional
+ temporary tables are present in the locked_tables list.
+ - Close the temporary table, remove its .FRM
+ - remove the table from the list of temporary tables
+
+ This function is used to drop user temporary tables, as well as
+ internal tables created in CREATE TEMPORARY TABLE ... SELECT
+ or ALTER TABLE. Even though part of the work done by this function
+ is redundant when the table is internal, as long as we
+ link both internal and user temporary tables into the same
+ thd->temporary_tables list, it's impossible to tell here whether
+ we're dealing with an internal or a user temporary table.
+
+ @retval TRUE the table was not found in the list of temporary tables
+ of this thread
+ @retval FALSE the table was found and dropped successfully.
*/
bool close_temporary_table(THD *thd, TABLE_LIST *table_list)
@@ -1689,6 +1707,11 @@ bool close_temporary_table(THD *thd, TABLE_LIST *table_list)
if (!(table= find_temporary_table(thd, table_list)))
return 1;
+ /*
+ If LOCK TABLES list is not empty and contains this table,
+ unlock the table and remove the table from this list.
+ */
+ mysql_lock_remove(thd, thd->locked_tables, table, FALSE);
close_temporary_table(thd, table, 1, 1);
return 0;
}
@@ -1835,7 +1858,7 @@ void unlink_open_table(THD *thd, TABLE *find, bool unlock)
!memcmp(list->s->table_cache_key.str, key, key_length))
{
if (unlock && thd->locked_tables)
- mysql_lock_remove(thd, thd->locked_tables,list);
+ mysql_lock_remove(thd, thd->locked_tables, list, TRUE);
VOID(hash_delete(&open_cache,(uchar*) list)); // Close table
}
else
@@ -1861,8 +1884,13 @@ void unlink_open_table(THD *thd, TABLE *find, bool unlock)
@note This routine assumes that table to be closed is open only
by calling thread so we needn't wait until other threads
- will close the table. It also assumes that table to be
- dropped is already unlocked.
+ will close the table. Also unless called under implicit or
+ explicit LOCK TABLES mode it assumes that table to be
+ dropped is already unlocked. In the former case it will
+ also remove lock on the table. But one should not rely on
+ this behaviour as it may change in future.
+ Currently, however, this function is never called for a
+ table that was locked with LOCK TABLES.
*/
void drop_open_table(THD *thd, TABLE *table, const char *db_name,
@@ -2468,8 +2496,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
&state))
{
/*
- Here we flush tables marked for flush. However we never flush log
- tables here. They are flushed only on FLUSH LOGS.
+ Here we flush tables marked for flush.
Normally, table->s->version contains the value of
refresh_version from the moment when this table was
(re-)opened and added to the cache.
@@ -2486,7 +2513,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
c1: name lock t2; -- blocks
c2: open t1; -- blocks
*/
- if (table->needs_reopen_or_name_lock() && !table->s->log_table)
+ if (table->needs_reopen_or_name_lock())
{
DBUG_PRINT("note",
("Found table '%s.%s' with different refresh version",
@@ -2840,7 +2867,7 @@ void close_data_files_and_morph_locks(THD *thd, const char *db,
!strcmp(table->s->db.str, db))
{
if (thd->locked_tables)
- mysql_lock_remove(thd, thd->locked_tables, table);
+ mysql_lock_remove(thd, thd->locked_tables, table, TRUE);
table->open_placeholder= 1;
close_handle_and_leave_table_as_lock(table);
}
@@ -2962,10 +2989,9 @@ void close_old_data_files(THD *thd, TABLE *table, bool morph_locks,
for (; table ; table=table->next)
{
/*
- Reopen marked for flush. But close log tables. They are flushed only
- explicitly on FLUSH LOGS
+ Reopen marked for flush.
*/
- if (table->needs_reopen_or_name_lock() && !table->s->log_table)
+ if (table->needs_reopen_or_name_lock())
{
found=1;
if (table->db_stat)
@@ -2979,7 +3005,7 @@ void close_old_data_files(THD *thd, TABLE *table, bool morph_locks,
instances of this table.
*/
mysql_lock_abort(thd, table, TRUE);
- mysql_lock_remove(thd, thd->locked_tables, table);
+ mysql_lock_remove(thd, thd->locked_tables, table, TRUE);
/*
We want to protect the table from concurrent DDL operations
(like RENAME TABLE) until we will re-open and re-lock it.
@@ -3012,10 +3038,6 @@ void close_old_data_files(THD *thd, TABLE *table, bool morph_locks,
Wait until all threads has closed the tables in the list
We have also to wait if there is thread that has a lock on this table even
if the table is closed
- NOTE: log tables are handled differently by the logging routines.
- E.g. general_log is always opened and locked by the logger
- and the table handler used by the logger, will be skipped by
- this check.
*/
bool table_is_used(TABLE *table, bool wait_for_name_lock)
@@ -3034,10 +3056,10 @@ bool table_is_used(TABLE *table, bool wait_for_name_lock)
search= (TABLE*) hash_next(&open_cache, (uchar*) key,
key_length, &state))
{
- DBUG_PRINT("info", ("share: 0x%lx locked_by_logger: %d "
+ DBUG_PRINT("info", ("share: 0x%lx "
"open_placeholder: %d locked_by_name: %d "
"db_stat: %u version: %lu",
- (ulong) search->s, search->locked_by_logger,
+ (ulong) search->s,
search->open_placeholder, search->locked_by_name,
search->db_stat,
search->s->version));
@@ -3049,12 +3071,9 @@ bool table_is_used(TABLE *table, bool wait_for_name_lock)
- If we are in flush table and we didn't execute the flush
- If the table engine is open and it's an old version
(We must wait until all engines are shut down to use the table)
- However we fo not wait if we encountered a table, locked by the logger.
- Log tables are managed separately by logging routines.
*/
- if (!search->locked_by_logger &&
- (search->locked_by_name && wait_for_name_lock ||
- (search->is_name_opened() && search->needs_reopen_or_name_lock())))
+ if ( (search->locked_by_name && wait_for_name_lock) ||
+ (search->is_name_opened() && search->needs_reopen_or_name_lock()))
DBUG_RETURN(1);
}
} while ((table=table->next));
@@ -3131,7 +3150,7 @@ TABLE *drop_locked_tables(THD *thd,const char *db, const char *table_name)
if (!strcmp(table->s->table_name.str, table_name) &&
!strcmp(table->s->db.str, db))
{
- mysql_lock_remove(thd, thd->locked_tables,table);
+ mysql_lock_remove(thd, thd->locked_tables, table, TRUE);
if (!found)
{
found= table;
@@ -3766,6 +3785,7 @@ static bool check_lock_and_start_stmt(THD *thd, TABLE *table,
thd Thread handler
table_list Table to open is first table in this list
lock_type Lock to use for open
+ lock_flags Flags passed to mysql_lock_table
NOTE
This function don't do anything like SP/SF/views/triggers analysis done
@@ -3781,7 +3801,8 @@ static bool check_lock_and_start_stmt(THD *thd, TABLE *table,
table_list->table table
*/
-TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type)
+TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type,
+ uint lock_flags)
{
TABLE *table;
bool refresh;
@@ -3809,8 +3830,8 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type)
{
DBUG_ASSERT(thd->lock == 0); // You must lock everything at once
if ((table->reginfo.lock_type= lock_type) != TL_UNLOCK)
- if (! (thd->lock= mysql_lock_tables(thd, &table_list->table, 1, 0,
- &refresh)))
+ if (! (thd->lock= mysql_lock_tables(thd, &table_list->table, 1,
+ lock_flags, &refresh)))
table= 0;
}
}
@@ -4149,11 +4170,6 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
DBUG_ASSERT(thd->lock == 0); // You must lock everything at once
TABLE **start,**ptr;
uint lock_flag= MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN;
-
- /* Ignore GLOBAL READ LOCK and GLOBAL READ_ONLY if called from a logger */
- if (logger.is_privileged_thread(thd))
- lock_flag|= (MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK |
- MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY);
if (!(ptr=start=(TABLE**) thd->alloc(sizeof(TABLE*)*count)))
DBUG_RETURN(-1);
@@ -7182,7 +7198,6 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
else if (in_use != thd)
{
DBUG_PRINT("info", ("Table was in use by other thread"));
- in_use->some_tables_deleted=1;
if (table->is_name_opened())
{
DBUG_PRINT("info", ("Found another active instance of the table"));
@@ -7618,7 +7633,7 @@ open_system_tables_for_read(THD *thd, TABLE_LIST *table_list,
if (!table)
goto error;
- DBUG_ASSERT(table->s->system_table);
+ DBUG_ASSERT(table->s->table_category == TABLE_CATEGORY_SYSTEM);
table->use_all_columns();
table->reginfo.lock_type= tables->lock_type;
@@ -7685,12 +7700,92 @@ 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);
+ TABLE *table= open_ltable(thd, one_table, one_table->lock_type, 0);
if (table)
{
- DBUG_ASSERT(table->s->system_table);
+ DBUG_ASSERT(table->s->table_category == TABLE_CATEGORY_SYSTEM);
table->use_all_columns();
}
DBUG_RETURN(table);
}
+
+/**
+ Open a performance schema table.
+ Opening such tables is performed internally in the server
+ implementation, and is a 'nested' open, since some tables
+ might be already opened by the current thread.
+ The thread context before this call is saved, and is restored
+ when calling close_performance_schema_table().
+ @param thd The current thread
+ @param one_table Performance schema table to open
+ @param backup [out] Temporary storage used to save the thread context
+*/
+TABLE *
+open_performance_schema_table(THD *thd, TABLE_LIST *one_table,
+ Open_tables_state *backup)
+{
+ uint flags= ( MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK
+ | MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY
+ | MYSQL_LOCK_PERF_SCHEMA );
+
+ DBUG_ENTER("open_performance_schema_table");
+
+ thd->reset_n_backup_open_tables_state(backup);
+
+ TABLE *table= open_ltable(thd, one_table, one_table->lock_type, flags);
+ if (table)
+ {
+ DBUG_ASSERT(table->s->table_category == TABLE_CATEGORY_PERFORMANCE);
+ /* Make sure all columns get assigned to a default value */
+ table->use_all_columns();
+ table->no_replicate= 1;
+ }
+
+ DBUG_RETURN(table);
+}
+
+/**
+ Close a performance schema table.
+ The last table opened by open_performance_schema_table()
+ is closed, then the thread context is restored.
+ @param thd The current thread
+ @param backup [in] the context to restore.
+*/
+void close_performance_schema_table(THD *thd, Open_tables_state *backup)
+{
+ bool found_old_table;
+
+ if (thd->lock)
+ {
+ /*
+ Note:
+ We do not create explicitly a separate transaction for the
+ performance table I/O, but borrow the current transaction.
+ lock + unlock will autocommit the change done in the
+ performance schema table: this is the expected result.
+ The current transaction should not be affected by this code.
+ TODO: Note that if a transactional engine is used for log tables,
+ this code will need to be revised, as a separate transaction
+ might be needed.
+ */
+ mysql_unlock_tables(thd, thd->lock);
+ thd->lock= 0;
+ }
+
+ safe_mutex_assert_not_owner(&LOCK_open);
+
+ pthread_mutex_lock(&LOCK_open);
+
+ found_old_table= false;
+ while (thd->open_tables)
+ found_old_table|= close_thread_table(thd, &thd->open_tables);
+
+ if (found_old_table)
+ broadcast_refresh();
+
+ pthread_mutex_unlock(&LOCK_open);
+
+ thd->restore_backup_open_tables_state(backup);
+}
+
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 71c13e001ee..ff4f3022c2b 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -765,13 +765,25 @@ enum prelocked_mode_type {NON_PRELOCKED= 0, PRELOCKED= 1,
class Open_tables_state
{
public:
- /*
- open_tables - list of regular tables in use by this thread
- temporary_tables - list of temp tables in use by this thread
- handler_tables - list of tables that were opened with HANDLER OPEN
- and are still in use by this thread
+ /**
+ List of regular tables in use by this thread. Contains temporary and
+ base tables that were opened with @see open_tables().
+ */
+ TABLE *open_tables;
+ /**
+ List of temporary tables used by this thread. Contains user-level
+ temporary tables, created with CREATE TEMPORARY TABLE, and
+ internal temporary tables, created, e.g., to resolve a SELECT,
+ or for an intermediate table used in ALTER.
+ XXX Why are internal temporary tables added to this list?
+ */
+ TABLE *temporary_tables;
+ /**
+ List of tables that were opened with HANDLER OPEN and are
+ still in use by this thread.
*/
- TABLE *open_tables, *temporary_tables, *handler_tables, *derived_tables;
+ TABLE *handler_tables;
+ TABLE *derived_tables;
/*
During a MySQL session, one can lock tables in two modes: automatic
or manual. In automatic mode all necessary tables are locked just before
@@ -2438,6 +2450,7 @@ public:
#define CF_HAS_ROW_COUNT 2
#define CF_STATUS_COMMAND 4
#define CF_SHOW_TABLE_COMMAND 8
+#define CF_WRITE_LOGS_COMMAND 16
/* Functions in sql_class.cc */
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 7c868092921..7d8fc119cf9 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -906,9 +906,7 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
char path[FN_REFLEN];
TABLE *table;
bool error;
- uint closed_log_tables= 0, lock_logger= 0;
uint path_length;
- uint log_type;
DBUG_ENTER("mysql_truncate");
bzero((char*) &create_info,sizeof(create_info));
@@ -960,18 +958,6 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
DBUG_RETURN(TRUE);
}
- log_type= check_if_log_table(table_list->db_length, table_list->db,
- table_list->table_name_length,
- table_list->table_name, 1);
- /* close log tables in use */
- if (log_type)
- {
- lock_logger= 1;
- logger.lock();
- logger.close_log_table(log_type, FALSE);
- closed_log_tables= closed_log_tables | log_type;
- }
-
// Remove the .frm extension AIX 5.2 64-bit compiler bug (BUG#16155): this
// crashes, replacement works. *(path + path_length - reg_ext_length)=
// '\0';
@@ -997,14 +983,6 @@ end:
VOID(pthread_mutex_lock(&LOCK_open));
unlock_table_name(thd, table_list);
VOID(pthread_mutex_unlock(&LOCK_open));
-
- if (opt_slow_log && (closed_log_tables & QUERY_LOG_SLOW))
- logger.reopen_log_table(QUERY_LOG_SLOW);
-
- if (opt_log && (closed_log_tables & QUERY_LOG_GENERAL))
- logger.reopen_log_table(QUERY_LOG_GENERAL);
- if (lock_logger)
- logger.unlock();
}
else if (error)
{
diff --git a/sql/sql_error.cc b/sql/sql_error.cc
index 5ebeba6109a..8bdb2e59ed5 100644
--- a/sql/sql_error.cc
+++ b/sql/sql_error.cc
@@ -137,6 +137,9 @@ MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
level= MYSQL_ERROR::WARN_LEVEL_ERROR;
}
+ if (thd->handle_error(code, level))
+ DBUG_RETURN(NULL);
+
if (thd->spcont &&
thd->spcont->handle_error(code, level, thd))
{
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index b747c706f75..dc5db54e128 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -2254,7 +2254,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
}
/* open table */
- if (!(di->table=open_ltable(thd,&di->table_list,TL_WRITE_DELAYED)))
+ if (!(di->table=open_ltable(thd, &di->table_list, TL_WRITE_DELAYED, 0)))
{
thd->fatal_error(); // Abort waiting inserts
goto err;
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 8ab4dee12ac..055dc1e8424 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -2367,12 +2367,129 @@ void st_select_lex_unit::set_limit(SELECT_LEX *sl)
/**
- Update the parsed tree with information about triggers that
- may be fired when executing this statement.
+ @brief Set the initial purpose of this TABLE_LIST object in the list of used
+ tables.
+
+ We need to track this information on table-by-table basis, since when this
+ table becomes an element of the pre-locked list, it's impossible to identify
+ which SQL sub-statement it has been originally used in.
+
+ E.g.:
+
+ User request: SELECT * FROM t1 WHERE f1();
+ FUNCTION f1(): DELETE FROM t2; RETURN 1;
+ BEFORE DELETE trigger on t2: INSERT INTO t3 VALUES (old.a);
+
+ For this user request, the pre-locked list will contain t1, t2, t3
+ table elements, each needed for different DML.
+
+ The trigger event map is updated to reflect INSERT, UPDATE, DELETE,
+ REPLACE, LOAD DATA, CREATE TABLE .. SELECT, CREATE TABLE ..
+ REPLACE SELECT statements, and additionally ON DUPLICATE KEY UPDATE
+ clause.
*/
void st_lex::set_trg_event_type_for_tables()
{
+ uint8 new_trg_event_map= 0;
+
+ /*
+ Some auxiliary operations
+ (e.g. GRANT processing) create TABLE_LIST instances outside
+ the parser. Additionally, some commands (e.g. OPTIMIZE) change
+ the lock type for a table only after parsing is done. Luckily,
+ these do not fire triggers and do not need to pre-load them.
+ For these TABLE_LISTs set_trg_event_type is never called, and
+ trg_event_map is always empty. That means that the pre-locking
+ algorithm will ignore triggers defined on these tables, if
+ any, and the execution will either fail with an assert in
+ sql_trigger.cc or with an error that a used table was not
+ pre-locked, in case of a production build.
+
+ TODO: this usage pattern creates unnecessary module dependencies
+ and should be rewritten to go through the parser.
+ Table list instances created outside the parser in most cases
+ refer to mysql.* system tables. It is not allowed to have
+ a trigger on a system table, but keeping track of
+ initialization provides extra safety in case this limitation
+ is circumvented.
+ */
+
+ switch (sql_command) {
+ case SQLCOM_LOCK_TABLES:
+ /*
+ On a LOCK TABLE, all triggers must be pre-loaded for this TABLE_LIST
+ when opening an associated TABLE.
+ */
+ new_trg_event_map= static_cast<uint8>
+ (1 << static_cast<int>(TRG_EVENT_INSERT)) |
+ static_cast<uint8>
+ (1 << static_cast<int>(TRG_EVENT_UPDATE)) |
+ static_cast<uint8>
+ (1 << static_cast<int>(TRG_EVENT_DELETE));
+ break;
+ /*
+ Basic INSERT. If there is an additional ON DUPLIATE KEY UPDATE
+ clause, it will be handled later in this method.
+ */
+ case SQLCOM_INSERT: /* fall through */
+ case SQLCOM_INSERT_SELECT:
+ /*
+ LOAD DATA ... INFILE is expected to fire BEFORE/AFTER INSERT
+ triggers.
+ If the statement also has REPLACE clause, it will be
+ handled later in this method.
+ */
+ case SQLCOM_LOAD: /* fall through */
+ /*
+ REPLACE is semantically equivalent to INSERT. In case
+ of a primary or unique key conflict, it deletes the old
+ record and inserts a new one. So we also may need to
+ fire ON DELETE triggers. This functionality is handled
+ later in this method.
+ */
+ case SQLCOM_REPLACE: /* fall through */
+ case SQLCOM_REPLACE_SELECT:
+ /*
+ CREATE TABLE ... SELECT defaults to INSERT if the table or
+ view already exists. REPLACE option of CREATE TABLE ...
+ REPLACE SELECT is handled later in this method.
+ */
+ case SQLCOM_CREATE_TABLE:
+ new_trg_event_map|= static_cast<uint8>
+ (1 << static_cast<int>(TRG_EVENT_INSERT));
+ break;
+ /* Basic update and multi-update */
+ case SQLCOM_UPDATE: /* fall through */
+ case SQLCOM_UPDATE_MULTI:
+ new_trg_event_map|= static_cast<uint8>
+ (1 << static_cast<int>(TRG_EVENT_UPDATE));
+ break;
+ /* Basic delete and multi-delete */
+ case SQLCOM_DELETE: /* fall through */
+ case SQLCOM_DELETE_MULTI:
+ new_trg_event_map|= static_cast<uint8>
+ (1 << static_cast<int>(TRG_EVENT_DELETE));
+ break;
+ default:
+ break;
+ }
+
+ switch (duplicates) {
+ case DUP_UPDATE:
+ new_trg_event_map|= static_cast<uint8>
+ (1 << static_cast<int>(TRG_EVENT_UPDATE));
+ break;
+ case DUP_REPLACE:
+ new_trg_event_map|= static_cast<uint8>
+ (1 << static_cast<int>(TRG_EVENT_DELETE));
+ break;
+ case DUP_ERROR:
+ default:
+ break;
+ }
+
+
/*
Do not iterate over sub-selects, only the tables in the outermost
SELECT_LEX can be modified, if any.
@@ -2381,7 +2498,17 @@ void st_lex::set_trg_event_type_for_tables()
while (tables)
{
- tables->set_trg_event_type(this);
+ /*
+ This is a fast check to filter out statements that do
+ not change data, or tables on the right side, in case of
+ INSERT .. SELECT, CREATE TABLE .. SELECT and so on.
+ Here we also filter out OPTIMIZE statement and non-updateable
+ views, for which lock_type is TL_UNLOCK or TL_READ after
+ parsing.
+ */
+ if (static_cast<int>(tables->lock_type) >=
+ static_cast<int>(TL_WRITE_ALLOW_WRITE))
+ tables->trg_event_map= new_trg_event_map;
tables= tables->next_local;
}
}
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 93887db88e1..c98d22d9091 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -197,8 +197,8 @@ void init_update_queries(void)
sql_command_flags[SQLCOM_CREATE_TABLE]= CF_CHANGES_DATA;
sql_command_flags[SQLCOM_CREATE_INDEX]= CF_CHANGES_DATA;
- sql_command_flags[SQLCOM_ALTER_TABLE]= CF_CHANGES_DATA;
- sql_command_flags[SQLCOM_TRUNCATE]= CF_CHANGES_DATA;
+ sql_command_flags[SQLCOM_ALTER_TABLE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND;
+ sql_command_flags[SQLCOM_TRUNCATE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND;
sql_command_flags[SQLCOM_DROP_TABLE]= CF_CHANGES_DATA;
sql_command_flags[SQLCOM_LOAD]= CF_CHANGES_DATA;
sql_command_flags[SQLCOM_CREATE_DB]= CF_CHANGES_DATA;
@@ -211,7 +211,7 @@ void init_update_queries(void)
sql_command_flags[SQLCOM_DROP_VIEW]= CF_CHANGES_DATA;
sql_command_flags[SQLCOM_CREATE_EVENT]= CF_CHANGES_DATA;
sql_command_flags[SQLCOM_ALTER_EVENT]= CF_CHANGES_DATA;
- sql_command_flags[SQLCOM_DROP_EVENT]= CF_CHANGES_DATA;
+ sql_command_flags[SQLCOM_DROP_EVENT]= CF_CHANGES_DATA;
sql_command_flags[SQLCOM_UPDATE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
sql_command_flags[SQLCOM_UPDATE_MULTI]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
@@ -250,6 +250,14 @@ void init_update_queries(void)
*/
sql_command_flags[SQLCOM_CALL]= CF_HAS_ROW_COUNT;
sql_command_flags[SQLCOM_EXECUTE]= CF_HAS_ROW_COUNT;
+
+ /*
+ The following admin table operations are allowed
+ on log tables.
+ */
+ sql_command_flags[SQLCOM_REPAIR]= CF_WRITE_LOGS_COMMAND;
+ sql_command_flags[SQLCOM_OPTIMIZE]= CF_WRITE_LOGS_COMMAND;
+ sql_command_flags[SQLCOM_ANALYZE]= CF_WRITE_LOGS_COMMAND;
}
@@ -259,6 +267,17 @@ bool is_update_query(enum enum_sql_command command)
return (sql_command_flags[command] & CF_CHANGES_DATA) != 0;
}
+/**
+ Check if a sql command is allowed to write to log tables.
+ @param command The SQL command
+ @return true if writing is allowed
+*/
+bool is_log_table_write_query(enum enum_sql_command command)
+{
+ DBUG_ASSERT(command >= 0 && command <= SQLCOM_END);
+ return (sql_command_flags[command] & CF_WRITE_LOGS_COMMAND) != 0;
+}
+
void execute_init_command(THD *thd, sys_var_str *init_command_var,
rw_lock_t *var_mutex)
{
@@ -493,7 +512,7 @@ int mysql_table_dump(THD *thd, LEX_STRING *db, char *tbl_name)
if (lower_case_table_names)
my_casedn_str(files_charset_info, tbl_name);
- if (!(table=open_ltable(thd, table_list, TL_READ_NO_INSERT)))
+ if (!(table=open_ltable(thd, table_list, TL_READ_NO_INSERT, 0)))
DBUG_RETURN(1);
if (check_one_table_access(thd, SELECT_ACL, table_list))
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index a44e20b8daf..0d088063462 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -1617,7 +1617,7 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING *dl
DBUG_RETURN(TRUE);
/* need to open before acquiring LOCK_plugin or it will deadlock */
- if (! (table = open_ltable(thd, &tables, TL_WRITE)))
+ if (! (table = open_ltable(thd, &tables, TL_WRITE, 0)))
DBUG_RETURN(TRUE);
pthread_mutex_lock(&LOCK_plugin);
@@ -1674,7 +1674,7 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name)
tables.table_name= tables.alias= (char *)"plugin";
/* need to open before acquiring LOCK_plugin or it will deadlock */
- if (! (table= open_ltable(thd, &tables, TL_WRITE)))
+ if (! (table= open_ltable(thd, &tables, TL_WRITE, 0)))
DBUG_RETURN(TRUE);
pthread_mutex_lock(&LOCK_plugin);
diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc
index f5e1b8988f3..750bcd50479 100644
--- a/sql/sql_rename.cc
+++ b/sql/sql_rename.cc
@@ -37,7 +37,6 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
TABLE_LIST *ren_table= 0;
int to_table;
char *rename_log_table[2]= {NULL, NULL};
- int disable_logs= 0;
DBUG_ENTER("mysql_rename_tables");
/*
@@ -80,12 +79,6 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
ren_table->table_name, 1)))
{
/*
- Log table encoutered we will need to disable and lock logs
- for duration of rename.
- */
- disable_logs= TRUE;
-
- /*
as we use log_table_rename as an array index, we need it to start
with 0, while QUERY_LOG_SLOW == 1 and QUERY_LOG_GENERAL == 2.
So, we shift the value to start with 0;
@@ -136,12 +129,6 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
rename_log_table[1]);
DBUG_RETURN(1);
}
-
- if (disable_logs)
- {
- logger.lock();
- logger.tmp_close_log_tables(thd);
- }
}
pthread_mutex_lock(&LOCK_open);
@@ -200,13 +187,6 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
pthread_mutex_unlock(&LOCK_open);
err:
- /* enable logging back if needed */
- if (disable_logs)
- {
- if (logger.reopen_log_tables())
- error= TRUE;
- logger.unlock();
- }
start_waiting_global_read_lock(thd);
DBUG_RETURN(error);
}
diff --git a/sql/sql_servers.cc b/sql/sql_servers.cc
index ac5ea6f4ac4..911372d5f4e 100644
--- a/sql/sql_servers.cc
+++ b/sql/sql_servers.cc
@@ -366,7 +366,7 @@ insert_server(THD *thd, FOREIGN_SERVER *server)
tables.alias= tables.table_name= (char*) "servers";
/* need to open before acquiring THR_LOCK_plugin or it will deadlock */
- if (! (table= open_ltable(thd, &tables, TL_WRITE)))
+ if (! (table= open_ltable(thd, &tables, TL_WRITE, 0)))
goto end;
/* insert the server into the table */
@@ -588,7 +588,7 @@ int drop_server(THD *thd, LEX_SERVER_OPTIONS *server_options)
if ((error= delete_server_record_in_cache(server_options)))
goto end;
- if (! (table= open_ltable(thd, &tables, TL_WRITE)))
+ if (! (table= open_ltable(thd, &tables, TL_WRITE, 0)))
{
error= my_errno;
goto end;
@@ -705,7 +705,7 @@ int update_server(THD *thd, FOREIGN_SERVER *existing, FOREIGN_SERVER *altered)
tables.db= (char*)"mysql";
tables.alias= tables.table_name= (char*)"servers";
- if (!(table= open_ltable(thd, &tables, TL_WRITE)))
+ if (!(table= open_ltable(thd, &tables, TL_WRITE, 0)))
{
error= my_errno;
goto end;
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 5b8cb93baab..fdd75fbe844 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -2176,9 +2176,6 @@ void calc_sum_of_all_status(STATUS_VAR *to)
}
-/* INFORMATION_SCHEMA name */
-LEX_STRING INFORMATION_SCHEMA_NAME= { C_STRING_WITH_LEN("information_schema")};
-
/* This is only used internally, but we need it here as a forward reference */
extern ST_SCHEMA_TABLE schema_tables[];
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 54b115af19f..7ffb83bc266 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1513,7 +1513,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
table->db_type= share->db_type();
/* Disable drop of enabled log tables */
- if (share && share->log_table &&
+ if (share && (share->table_category == TABLE_CATEGORY_PERFORMANCE) &&
check_if_log_table(table->db_length, table->db,
table->table_name_length, table->table_name, 1))
{
@@ -3966,7 +3966,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
Item *item;
Protocol *protocol= thd->protocol;
LEX *lex= thd->lex;
- int result_code, disable_logs= 0;
+ int result_code;
DBUG_ENTER("mysql_admin_table");
if (end_active_trans(thd))
@@ -4014,22 +4014,6 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
if (view_operator_func == NULL)
table->required_type=FRMTYPE_TABLE;
- /*
- If we want to perform an admin operation on the log table
- (E.g. rename) and lock_type >= TL_READ_NO_INSERT disable
- log tables
- */
-
- if (check_if_log_table(table->db_length, table->db,
- table->table_name_length,
- table->table_name, 1) &&
- lock_type >= TL_READ_NO_INSERT)
- {
- disable_logs= 1;
- logger.lock();
- logger.tmp_close_log_tables(thd);
- }
-
open_and_lock_tables(thd, table);
thd->no_warnings_for_error= 0;
table->next_global= save_next_global;
@@ -4099,8 +4083,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
}
/* Close all instances of the table to allow repair to rename files */
- if (lock_type == TL_WRITE && table->table->s->version &&
- !table->table->s->log_table)
+ if (lock_type == TL_WRITE && table->table->s->version)
{
pthread_mutex_lock(&LOCK_open);
const char *old_message=thd->enter_cond(&COND_refresh, &LOCK_open,
@@ -4258,7 +4241,7 @@ send_result_message:
close_thread_tables(thd);
if (!result_code) // recreation went ok
{
- if ((table->table= open_ltable(thd, table, lock_type)) &&
+ if ((table->table= open_ltable(thd, table, lock_type, 0)) &&
((result_code= table->table->file->analyze(thd, check_opt)) > 0))
result_code= 0; // analyze went ok
}
@@ -4324,10 +4307,9 @@ send_result_message:
}
if (table->table)
{
- /* in the below check we do not refresh the log tables */
if (fatal_error)
table->table->s->version=0; // Force close of table
- else if (open_for_modify && !table->table->s->log_table)
+ else if (open_for_modify)
{
if (table->table->s->tmp_table)
table->table->file->info(HA_STATUS_CONST);
@@ -4350,24 +4332,11 @@ send_result_message:
}
send_eof(thd);
- if (disable_logs)
- {
- if (logger.reopen_log_tables())
- my_error(ER_CANT_ACTIVATE_LOG, MYF(0));
- logger.unlock();
- }
DBUG_RETURN(FALSE);
err:
ha_autocommit_or_rollback(thd, 1);
close_thread_tables(thd); // Shouldn't be needed
- /* enable logging back if needed */
- if (disable_logs)
- {
- if (logger.reopen_log_tables())
- my_error(ER_CANT_ACTIVATE_LOG, MYF(0));
- logger.unlock();
- }
if (table)
table->table=0;
DBUG_RETURN(TRUE);
@@ -4812,7 +4781,7 @@ mysql_discard_or_import_tablespace(THD *thd,
not complain when we lock the table
*/
thd->tablespace_op= TRUE;
- if (!(table=open_ltable(thd,table_list,TL_WRITE)))
+ if (!(table=open_ltable(thd, table_list, TL_WRITE, 0)))
{
thd->tablespace_op=FALSE;
DBUG_RETURN(-1);
@@ -5728,7 +5697,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
#ifdef WITH_PARTITION_STORAGE_ENGINE
if (alter_info->flags & ALTER_PARTITION)
{
- my_error(ER_WRONG_USAGE, MYF(0), "PARTITION", "log table");
+ my_error(ER_WRONG_USAGE, MYF(0), "PARTITION", "log table");
DBUG_RETURN(TRUE);
}
#endif
@@ -5817,7 +5786,7 @@ view_err:
start_waiting_global_read_lock(thd);
DBUG_RETURN(error);
}
- if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
+ if (!(table=open_ltable(thd, table_list, TL_WRITE_ALLOW_READ, 0)))
DBUG_RETURN(TRUE);
table->use_all_columns();
@@ -6984,7 +6953,7 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
strxmov(table_name, table->db ,".", table->table_name, NullS);
- t= table->table= open_ltable(thd, table, TL_READ);
+ t= table->table= open_ltable(thd, table, TL_READ, 0);
thd->clear_error(); // these errors shouldn't get client
protocol->prepare_for_resend();
diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc
index 8361fc64f33..10bb7844d88 100644
--- a/sql/sql_udf.cc
+++ b/sql/sql_udf.cc
@@ -472,7 +472,7 @@ int mysql_create_function(THD *thd,udf_func *udf)
tables.db= (char*) "mysql";
tables.table_name= tables.alias= (char*) "func";
/* Allow creation of functions even if we can't open func table */
- if (!(table = open_ltable(thd,&tables,TL_WRITE)))
+ if (!(table = open_ltable(thd, &tables, TL_WRITE, 0)))
goto err;
table->use_all_columns();
restore_record(table, s->default_values); // Default values for fields
@@ -547,7 +547,7 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name)
bzero((char*) &tables,sizeof(tables));
tables.db=(char*) "mysql";
tables.table_name= tables.alias= (char*) "func";
- if (!(table = open_ltable(thd,&tables,TL_WRITE)))
+ if (!(table = open_ltable(thd, &tables, TL_WRITE, 0)))
goto err;
table->use_all_columns();
table->field[0]->store(exact_name_str, exact_name_len, &my_charset_bin);
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index d9a808bf8f7..81bb1c2dae9 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -7277,7 +7277,7 @@ join_table:
so that [INNER | CROSS] JOIN is properly nested as other
left-associative joins.
*/
- table_ref %prec TABLE_REF_PRIORITY normal_join table_ref
+ table_ref normal_join table_ref %prec TABLE_REF_PRIORITY
{ MYSQL_YYABORT_UNLESS($1 && ($$=$3)); }
| table_ref STRAIGHT_JOIN table_factor
{ MYSQL_YYABORT_UNLESS($1 && ($$=$3)); $3->straight=1; }
diff --git a/sql/table.cc b/sql/table.cc
index e6f9b1086c7..f52c81d7889 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -21,6 +21,18 @@
#include <m_ctype.h>
#include "my_md5.h"
+/* INFORMATION_SCHEMA name */
+LEX_STRING INFORMATION_SCHEMA_NAME= {C_STRING_WITH_LEN("information_schema")};
+
+/* MYSQL_SCHEMA name */
+LEX_STRING MYSQL_SCHEMA_NAME= {C_STRING_WITH_LEN("mysql")};
+
+/* GENERAL_LOG name */
+LEX_STRING GENERAL_LOG_NAME= {C_STRING_WITH_LEN("general_log")};
+
+/* SLOW_LOG name */
+LEX_STRING SLOW_LOG_NAME= {C_STRING_WITH_LEN("slow_log")};
+
/* Functions defined in this file */
void open_table_error(TABLE_SHARE *share, int error, int db_errno,
@@ -31,6 +43,7 @@ static void fix_type_pointers(const char ***array, TYPELIB *point_to_type,
uint types, char **names);
static uint find_field(Field **fields, uchar *record, uint start, uint length);
+inline bool is_system_table_name(const char *name, uint length);
/**************************************************************************
Object_creation_ctx implementation.
@@ -192,6 +205,49 @@ char *fn_rext(char *name)
return name + strlen(name);
}
+TABLE_CATEGORY get_table_category(const LEX_STRING *db, const LEX_STRING *name)
+{
+ DBUG_ASSERT(db != NULL);
+ DBUG_ASSERT(name != NULL);
+
+ if ((db->length == INFORMATION_SCHEMA_NAME.length) &&
+ (my_strcasecmp(system_charset_info,
+ INFORMATION_SCHEMA_NAME.str,
+ db->str) == 0))
+ {
+ return TABLE_CATEGORY_INFORMATION;
+ }
+
+ if ((db->length == MYSQL_SCHEMA_NAME.length) &&
+ (my_strcasecmp(system_charset_info,
+ MYSQL_SCHEMA_NAME.str,
+ db->str) == 0))
+ {
+ if (is_system_table_name(name->str, name->length))
+ {
+ return TABLE_CATEGORY_SYSTEM;
+ }
+
+ if ((name->length == GENERAL_LOG_NAME.length) &&
+ (my_strcasecmp(system_charset_info,
+ GENERAL_LOG_NAME.str,
+ name->str) == 0))
+ {
+ return TABLE_CATEGORY_PERFORMANCE;
+ }
+
+ if ((name->length == SLOW_LOG_NAME.length) &&
+ (my_strcasecmp(system_charset_info,
+ SLOW_LOG_NAME.str,
+ name->str) == 0))
+ {
+ return TABLE_CATEGORY_PERFORMANCE;
+ }
+ }
+
+ return TABLE_CATEGORY_USER;
+}
+
/*
Allocate a setup TABLE_SHARE structure
@@ -297,7 +353,8 @@ void init_tmp_table_share(TABLE_SHARE *share, const char *key,
bzero((char*) share, sizeof(*share));
init_sql_alloc(&share->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
- share->tmp_table= INTERNAL_TMP_TABLE;
+ share->table_category= TABLE_CATEGORY_TEMPORARY;
+ share->tmp_table= INTERNAL_TMP_TABLE;
share->db.str= (char*) key;
share->db.length= strlen(key);
share->table_cache_key.str= (char*) key;
@@ -544,28 +601,11 @@ int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags)
*root_ptr= &share->mem_root;
error= open_binary_frm(thd, share, head, file);
*root_ptr= old_root;
-
- if (share->db.length == 5 && !(lower_case_table_names ?
- my_strcasecmp(system_charset_info, share->db.str, "mysql") :
- strcmp(share->db.str, "mysql")))
- {
- /*
- We can't mark all tables in 'mysql' database as system since we don't
- allow to lock such tables for writing with any other tables (even with
- other system tables) and some privilege tables need this.
- */
- 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,
- share->table_name.str, 0);
- }
- }
error_given= 1;
}
+ share->table_category= get_table_category(& share->db, & share->table_name);
+
if (!error)
thd->status_var.opened_shares++;
@@ -2854,135 +2894,6 @@ void st_table::reset_item_list(List<Item> *item_list) const
}
}
-
-/**
- Set the initial purpose of this TABLE_LIST object in the list of
- used tables. We need to track this information on table-by-
- table basis, since when this table becomes an element of the
- pre-locked list, it's impossible to identify which SQL
- sub-statement it has been originally used in.
-
- E.g.:
-
- User request: SELECT * FROM t1 WHERE f1();
- FUNCTION f1(): DELETE FROM t2; RETURN 1;
- BEFORE DELETE trigger on t2: INSERT INTO t3 VALUES (old.a);
-
- For this user request, the pre-locked list will contain t1, t2, t3
- table elements, each needed for different DML.
-
- This method is called immediately after parsing for tables
- of the table list of the top-level select lex.
-
- The trigger event map is updated to reflect INSERT, UPDATE, DELETE,
- REPLACE, LOAD DATA, CREATE TABLE .. SELECT, CREATE TABLE ..
- REPLACE SELECT statements, and additionally ON DUPLICATE KEY UPDATE
- clause.
-*/
-
-void
-TABLE_LIST::set_trg_event_type(const st_lex *lex)
-{
- enum trg_event_type trg_event;
-
- /*
- Some auxiliary operations
- (e.g. GRANT processing) create TABLE_LIST instances outside
- the parser. Additionally, some commands (e.g. OPTIMIZE) change
- the lock type for a table only after parsing is done. Luckily,
- these do not fire triggers and do not need to pre-load them.
- For these TABLE_LISTs set_trg_event_type is never called, and
- trg_event_map is always empty. That means that the pre-locking
- algorithm will ignore triggers defined on these tables, if
- any, and the execution will either fail with an assert in
- sql_trigger.cc or with an error that a used table was not
- pre-locked, in case of a production build.
-
- TODO: this usage pattern creates unnecessary module dependencies
- and should be rewritten to go through the parser.
- Table list instances created outside the parser in most cases
- refer to mysql.* system tables. It is not allowed to have
- a trigger on a system table, but keeping track of
- initialization provides extra safety in case this limitation
- is circumvented.
- */
-
- /*
- This is a fast check to filter out statements that do
- not change data, or tables on the right side, in case of
- INSERT .. SELECT, CREATE TABLE .. SELECT and so on.
- Here we also filter out OPTIMIZE statement and non-updateable
- views, for which lock_type is TL_UNLOCK or TL_READ after
- parsing.
- */
- if (static_cast<int>(lock_type) < static_cast<int>(TL_WRITE_ALLOW_WRITE))
- return;
-
- switch (lex->sql_command) {
- /*
- Basic INSERT. If there is an additional ON DUPLIATE KEY UPDATE
- clause, it will be handled later in this method.
- */
- case SQLCOM_INSERT: /* fall through */
- case SQLCOM_INSERT_SELECT:
- /*
- LOAD DATA ... INFILE is expected to fire BEFORE/AFTER INSERT
- triggers.
- If the statement also has REPLACE clause, it will be
- handled later in this method.
- */
- case SQLCOM_LOAD: /* fall through */
- /*
- REPLACE is semantically equivalent to INSERT. In case
- of a primary or unique key conflict, it deletes the old
- record and inserts a new one. So we also may need to
- fire ON DELETE triggers. This functionality is handled
- later in this method.
- */
- case SQLCOM_REPLACE: /* fall through */
- case SQLCOM_REPLACE_SELECT:
- /*
- CREATE TABLE ... SELECT defaults to INSERT if the table or
- view already exists. REPLACE option of CREATE TABLE ...
- REPLACE SELECT is handled later in this method.
- */
- case SQLCOM_CREATE_TABLE:
- trg_event= TRG_EVENT_INSERT;
- break;
- /* Basic update and multi-update */
- case SQLCOM_UPDATE: /* fall through */
- case SQLCOM_UPDATE_MULTI:
- trg_event= TRG_EVENT_UPDATE;
- break;
- /* Basic delete and multi-delete */
- case SQLCOM_DELETE: /* fall through */
- case SQLCOM_DELETE_MULTI:
- trg_event= TRG_EVENT_DELETE;
- break;
- default:
- /*
- OK to return, since value of 'duplicates' is irrelevant
- for non-updating commands.
- */
- return;
- }
- trg_event_map|= static_cast<uint8>(1 << static_cast<int>(trg_event));
-
- switch (lex->duplicates) {
- case DUP_UPDATE:
- trg_event= TRG_EVENT_UPDATE;
- break;
- case DUP_REPLACE:
- trg_event= TRG_EVENT_DELETE;
- break;
- case DUP_ERROR:
- default:
- return;
- }
- trg_event_map|= static_cast<uint8>(1 << static_cast<int>(trg_event));
-}
-
-
/*
calculate md5 of query
diff --git a/sql/table.h b/sql/table.h
index a276a9f32fd..e46036f3ee9 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -140,6 +140,100 @@ class Field_timestamp;
class Field_blob;
class Table_triggers_list;
+/**
+ Category of table found in the table share.
+*/
+enum enum_table_category
+{
+ /**
+ Unknown value.
+ */
+ TABLE_UNKNOWN_CATEGORY=0,
+
+ /**
+ Temporary table.
+ The table is visible only in the session.
+ Therefore,
+ - FLUSH TABLES WITH READ LOCK
+ - SET GLOBAL READ_ONLY = ON
+ do not apply to this table.
+ Note that LOCK TABLE <t> FOR READ/WRITE
+ can be used on temporary tables.
+ Temporary tables are not part of the table cache.
+ */
+ TABLE_CATEGORY_TEMPORARY=1,
+
+ /**
+ User table.
+ These tables do honor:
+ - LOCK TABLE <t> FOR READ/WRITE
+ - FLUSH TABLES WITH READ LOCK
+ - SET GLOBAL READ_ONLY = ON
+ User tables are cached in the table cache.
+ */
+ TABLE_CATEGORY_USER=2,
+
+ /**
+ System table, maintained by the server.
+ These tables do honor:
+ - LOCK TABLE <t> FOR READ/WRITE
+ - FLUSH TABLES WITH READ LOCK
+ - SET GLOBAL READ_ONLY = ON
+ Typically, writes to system tables are performed by
+ the server implementation, not explicitly be a user.
+ System tables are cached in the table cache.
+ */
+ TABLE_CATEGORY_SYSTEM=3,
+
+ /**
+ Information schema tables.
+ These tables are an interface provided by the system
+ to inspect the system metadata.
+ These tables do *not* honor:
+ - LOCK TABLE <t> FOR READ/WRITE
+ - FLUSH TABLES WITH READ LOCK
+ - SET GLOBAL READ_ONLY = ON
+ as there is no point in locking explicitely
+ an INFORMATION_SCHEMA table.
+ Nothing is directly written to information schema tables.
+ Note that this value is not used currently,
+ since information schema tables are not shared,
+ but implemented as session specific temporary tables.
+ */
+ /*
+ TODO: Fixing the performance issues of I_S will lead
+ to I_S tables in the table cache, which should use
+ this table type.
+ */
+ TABLE_CATEGORY_INFORMATION=4,
+
+ /**
+ Performance schema tables.
+ These tables are an interface provided by the system
+ to inspect the system performance data.
+ These tables do *not* honor:
+ - LOCK TABLE <t> FOR READ/WRITE
+ - FLUSH TABLES WITH READ LOCK
+ - SET GLOBAL READ_ONLY = ON
+ as there is no point in locking explicitely
+ a PERFORMANCE_SCHEMA table.
+ An example of PERFORMANCE_SCHEMA tables are:
+ - mysql.slow_log
+ - mysql.general_log,
+ which *are* updated even when there is either
+ a GLOBAL READ LOCK or a GLOBAL READ_ONLY in effect.
+ User queries do not write directly to these tables
+ (there are exceptions for log tables).
+ The server implementation perform writes.
+ Performance tables are cached in the table cache.
+ */
+ TABLE_CATEGORY_PERFORMANCE=5
+};
+typedef enum enum_table_category TABLE_CATEGORY;
+
+TABLE_CATEGORY get_table_category(const LEX_STRING *db,
+ const LEX_STRING *name);
+
/*
This structure is shared between different table objects. There is one
instance of table share per one table in the database.
@@ -148,6 +242,10 @@ class Table_triggers_list;
typedef struct st_table_share
{
st_table_share() {} /* Remove gcc warning */
+
+ /** Category of this table. */
+ TABLE_CATEGORY table_category;
+
/* hash of field names (contains pointers to elements of field array) */
HASH name_hash; /* hash of field names */
MEM_ROOT mem_root;
@@ -259,18 +357,6 @@ typedef struct st_table_share
*/
int cached_row_logging_check;
- /*
- TRUE if this is a system table like 'mysql.proc', which we want to be
- able to open and lock even when we already have some tables open and
- locked. To avoid deadlocks we have to put certain restrictions on
- locking of this table for writing. FALSE - otherwise.
- */
- bool system_table;
- /*
- This flag is set for the log tables. Used during FLUSH instances to skip
- log tables, while closing tables (since logs must be always available)
- */
- bool log_table;
#ifdef WITH_PARTITION_STORAGE_ENGINE
bool auto_partitioned;
const char *partition_info;
@@ -334,6 +420,16 @@ typedef struct st_table_share
set_table_cache_key(key_buff, key_length);
}
+ inline bool honor_global_locks()
+ {
+ return ((table_category == TABLE_CATEGORY_USER)
+ || (table_category == TABLE_CATEGORY_SYSTEM));
+ }
+
+ inline bool require_write_privileges()
+ {
+ return (table_category == TABLE_CATEGORY_PERFORMANCE);
+ }
} TABLE_SHARE;
@@ -1052,7 +1148,6 @@ struct TABLE_LIST
*/
bool process_index_hints(TABLE *table);
- void set_trg_event_type(const st_lex *lex);
private:
bool prep_check_option(THD *thd, uint8 check_opt_type);
bool prep_where(THD *thd, Item **conds, bool no_where_clause);
diff --git a/sql/tztime.cc b/sql/tztime.cc
index 0c717dd2ece..14192d06978 100644
--- a/sql/tztime.cc
+++ b/sql/tztime.cc
@@ -807,19 +807,6 @@ sec_since_epoch(int year, int mon, int mday, int hour, int min ,int sec)
SECS_PER_MIN + sec;
}
-
- /*
- Works like sec_since_epoch but expects MYSQL_TIME structure as parameter.
-*/
-
-my_time_t
-sec_since_epoch_TIME(MYSQL_TIME *t)
-{
- return sec_since_epoch(t->year, t->month, t->day,
- t->hour, t->minute, t->second);
-}
-
-
/*
Converts local time in broken down MYSQL_TIME representation to my_time_t
representation.
@@ -1425,7 +1412,9 @@ Time_zone_offset::get_name() const
static Time_zone_utc tz_UTC;
static Time_zone_system tz_SYSTEM;
+static Time_zone_offset tz_OFFSET0(0);
+Time_zone *my_tz_OFFSET0= &tz_OFFSET0;
Time_zone *my_tz_UTC= &tz_UTC;
Time_zone *my_tz_SYSTEM= &tz_SYSTEM;
diff --git a/sql/tztime.h b/sql/tztime.h
index f7cc7042d79..ddd80b88bf2 100644
--- a/sql/tztime.h
+++ b/sql/tztime.h
@@ -59,6 +59,7 @@ public:
extern Time_zone * my_tz_UTC;
extern Time_zone * my_tz_SYSTEM;
+extern Time_zone * my_tz_OFFSET0;
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();
diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc
index 34c1fcde58d..00ca2a6c07f 100644
--- a/storage/csv/ha_tina.cc
+++ b/storage/csv/ha_tina.cc
@@ -786,18 +786,6 @@ void ha_tina::update_status()
}
-bool ha_tina::check_if_locking_is_allowed(uint sql_command,
- ulong type, TABLE *table,
- uint count, uint current,
- uint *system_count,
- bool called_by_privileged_thread)
-{
- if (!called_by_privileged_thread)
- return check_if_log_table_locking_is_allowed(sql_command, type, table);
-
- return TRUE;
-}
-
/*
Open a database file. Keep in mind that tables are caches, so
this will not be called for every request. Any sort of positions
diff --git a/storage/csv/ha_tina.h b/storage/csv/ha_tina.h
index 5bb3e9a79a0..5ce09783b9b 100644
--- a/storage/csv/ha_tina.h
+++ b/storage/csv/ha_tina.h
@@ -131,11 +131,6 @@ public:
*/
ha_rows estimate_rows_upper_bound() { return HA_POS_ERROR; }
- virtual bool check_if_locking_is_allowed(uint sql_command,
- ulong type, TABLE *table,
- 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);
int write_row(uchar * buf);
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index c86459ae0a7..77334b2cfba 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -607,41 +607,7 @@ err:
#endif /* HAVE_REPLICATION */
-bool ha_myisam::check_if_locking_is_allowed(uint sql_command,
- ulong type, TABLE *table,
- uint count, uint current,
- uint *system_count,
- bool called_by_privileged_thread)
-{
- /*
- To be able to open and lock for reading system tables like 'mysql.proc',
- when we already have some tables opened and locked, and avoid deadlocks
- 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)
- (*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));
- return FALSE;
- }
-
- /*
- Deny locking of the log tables, which is incompatible with
- concurrent insert. Unless called from a logger THD (general_log_thd
- or slow_log_thd) or by a privileged thread.
- */
- if (!called_by_privileged_thread)
- return check_if_log_table_locking_is_allowed(sql_command, type, table);
-
- return TRUE;
-}
-
- /* Name is here without an extension */
-
+/* Name is here without an extension */
int ha_myisam::open(const char *name, int mode, uint test_if_locked)
{
MI_KEYDEF *keyinfo;
diff --git a/storage/myisam/ha_myisam.h b/storage/myisam/ha_myisam.h
index 024675075c2..635f314b3da 100644
--- a/storage/myisam/ha_myisam.h
+++ b/storage/myisam/ha_myisam.h
@@ -60,11 +60,6 @@ class ha_myisam: public handler
uint max_supported_key_part_length() const { return MI_MAX_KEY_LENGTH; }
uint checksum() const;
- virtual bool check_if_locking_is_allowed(uint sql_command,
- ulong type, TABLE *table,
- 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);
int write_row(uchar * buf);
diff --git a/storage/myisam/mi_test1.c b/storage/myisam/mi_test1.c
index 1165ea4bb32..08627ba7e92 100644
--- a/storage/myisam/mi_test1.c
+++ b/storage/myisam/mi_test1.c
@@ -258,7 +258,8 @@ static int run_test(const char *filename)
continue;
create_key(key,j);
my_errno=0;
- if ((error = mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT)))
+ if ((error = mi_rkey(file,read_record,0,key,HA_WHOLE_KEY,
+ HA_READ_KEY_EXACT)))
{
if (verbose || (flags[j] >= 1 ||
(error && my_errno != HA_ERR_KEY_NOT_FOUND)))
@@ -285,7 +286,7 @@ static int run_test(const char *filename)
{
create_key(key,i);
my_errno=0;
- error=mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT);
+ error=mi_rkey(file,read_record,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT);
if (verbose ||
(error == 0 && flags[i] == 0 && unique_key) ||
(error && (flags[i] != 0 || my_errno != HA_ERR_KEY_NOT_FOUND)))
diff --git a/storage/myisam/mi_test2.c b/storage/myisam/mi_test2.c
index 96ee82e023c..99d0c23d2a4 100644
--- a/storage/myisam/mi_test2.c
+++ b/storage/myisam/mi_test2.c
@@ -263,7 +263,7 @@ int main(int argc, char *argv[])
if (!j)
for (j=999 ; j>0 && key1[j] == 0 ; j--) ;
sprintf(key,"%6d",j);
- if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT))
+ if (mi_rkey(file,read_record,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT))
{
printf("Test in loop: Can't find key: \"%s\"\n",key);
goto err;
@@ -291,7 +291,7 @@ int main(int argc, char *argv[])
if (j != 0)
{
sprintf(key,"%6d",j);
- if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT))
+ if (mi_rkey(file,read_record,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT))
{
printf("can't find key1: \"%s\"\n",key);
goto err;
@@ -325,7 +325,7 @@ int main(int argc, char *argv[])
if (j != 0)
{
sprintf(key,"%6d",j);
- if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT))
+ if (mi_rkey(file,read_record,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT))
{
printf("can't find key1: \"%s\"\n",key);
goto err;
@@ -377,7 +377,7 @@ int main(int argc, char *argv[])
DBUG_PRINT("progpos",("first - next -> last - prev -> first"));
if (verbose) printf(" Using key: \"%s\" Keys: %d\n",key,dupp_keys);
- if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT))
+ if (mi_rkey(file,read_record,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT))
goto err;
if (mi_rsame(file,read_record2,-1))
goto err;
@@ -422,7 +422,7 @@ int main(int argc, char *argv[])
}
/* Check of mi_rnext_same */
- if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT))
+ if (mi_rkey(file,read_record,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT))
goto err;
ant=1;
while (!mi_rnext_same(file,read_record3) && ant < dupp_keys+10)
@@ -496,7 +496,7 @@ int main(int argc, char *argv[])
goto err;
if (bcmp(read_record2,read_record3,reclength))
printf("Can't find last record\n");
-
+#ifdef NOT_ANYMORE
if (!silent)
puts("- Test read key-part");
strmov(key2,key);
@@ -514,12 +514,14 @@ int main(int argc, char *argv[])
goto end;
}
}
+#endif
if (dupp_keys > 2)
{
if (!silent)
printf("- Read key (first) - next - delete - next -> last\n");
DBUG_PRINT("progpos",("first - next - delete - next -> last"));
- if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT)) goto err;
+ if (mi_rkey(file,read_record,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT))
+ goto err;
if (mi_rnext(file,read_record3,0)) goto err;
if (mi_delete(file,read_record3)) goto err;
opt_delete++;
@@ -555,7 +557,8 @@ int main(int argc, char *argv[])
if (!silent)
printf("- Read first - delete - next -> last\n");
DBUG_PRINT("progpos",("first - delete - next -> last"));
- if (mi_rkey(file,read_record3,0,key,0,HA_READ_KEY_EXACT)) goto err;
+ if (mi_rkey(file,read_record3,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT))
+ goto err;
if (mi_delete(file,read_record3)) goto err;
opt_delete++;
ant=1;
@@ -618,10 +621,10 @@ int main(int argc, char *argv[])
copy_key(file,(uint) i,(uchar*) read_record,(uchar*) key);
copy_key(file,(uint) i,(uchar*) read_record2,(uchar*) key2);
min_key.key= key;
- min_key.length= USE_WHOLE_KEY;
+ min_key.keypart_map= HA_WHOLE_KEY;
min_key.flag= HA_READ_KEY_EXACT;
max_key.key= key2;
- max_key.length= USE_WHOLE_KEY;
+ max_key.keypart_map= HA_WHOLE_KEY;
max_key.flag= HA_READ_AFTER_KEY;
range_records= mi_records_in_range(file,(int) i, &min_key, &max_key);
diff --git a/storage/myisam/mi_test3.c b/storage/myisam/mi_test3.c
index 982b999c3a5..ed9cd8e7b8c 100644
--- a/storage/myisam/mi_test3.c
+++ b/storage/myisam/mi_test3.c
@@ -243,8 +243,8 @@ int test_read(MI_INFO *file,int id)
for (i=0 ; i < 100 ; i++)
{
find=rnd(100000);
- if (!mi_rkey(file,record.id,1,(uchar*) &find,
- sizeof(find),HA_READ_KEY_EXACT))
+ if (!mi_rkey(file,record.id,1,(uchar*) &find, HA_WHOLE_KEY,
+ HA_READ_KEY_EXACT))
found++;
else
{
@@ -426,8 +426,8 @@ int test_update(MI_INFO *file,int id,int lock_type)
{
tmp=rnd(100000);
int4store(find,tmp);
- if (!mi_rkey(file,record.id,1,(uchar*) find,
- sizeof(find),HA_READ_KEY_EXACT))
+ if (!mi_rkey(file,record.id,1,(uchar*) find, HA_WHOLE_KEY,
+ HA_READ_KEY_EXACT))
found++;
else
{