From 6d14cae604d064ec5cd8141bfd05408cc41bf134 Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Thu, 12 Aug 2010 15:59:02 +0500 Subject: [PATCH 001/304] Bug#55146 Assertion `m_part_spec.start_part == m_part_spec.end_part' in index_read_idx_map As we check for the impossible partitions earlier, it's possible that we don't find any suitable partitions at all. So this assertion just has to be corrected for this case. per-file comments: mysql-test/r/partition_innodb.result Bug#55146 Assertion `m_part_spec.start_part == m_part_spec.end_part' in index_read_idx_map test result updated. mysql-test/t/partition_innodb.test Bug#55146 Assertion `m_part_spec.start_part == m_part_spec.end_part' in index_read_idx_map test case added. sql/ha_partition.cc Bug#55146 Assertion `m_part_spec.start_part == m_part_spec.end_part' in index_read_idx_map Assertion changed to '>=' as the prune_partition_set() in the get_partition_set() can do start_part= end_part+1 if no possible partitions were found. --- mysql-test/r/partition_innodb.result | 6 ++++++ mysql-test/t/partition_innodb.test | 13 +++++++++++++ sql/ha_partition.cc | 8 ++++++-- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/partition_innodb.result b/mysql-test/r/partition_innodb.result index 2a04aafe554..98104310227 100644 --- a/mysql-test/r/partition_innodb.result +++ b/mysql-test/r/partition_innodb.result @@ -387,3 +387,9 @@ a b 3 2003-03-03 COMMIT; DROP TABLE t1; +CREATE TABLE t1 (i1 int NOT NULL primary key, f1 int) ENGINE = InnoDB +PARTITION BY HASH(i1) PARTITIONS 2; +INSERT INTO t1 VALUES (1,1), (2,2); +SELECT * FROM t1 WHERE i1 = ( SELECT i1 FROM t1 WHERE f1=0 LIMIT 1 ); +i1 f1 +DROP TABLE t1; diff --git a/mysql-test/t/partition_innodb.test b/mysql-test/t/partition_innodb.test index e1ac7b4c7eb..cef3540f9a7 100644 --- a/mysql-test/t/partition_innodb.test +++ b/mysql-test/t/partition_innodb.test @@ -401,3 +401,16 @@ connection default; SELECT * FROM t1; COMMIT; DROP TABLE t1; + +# +# Bug #55146 Assertion `m_part_spec.start_part == m_part_spec.end_part' in index_read_idx_map +# + +CREATE TABLE t1 (i1 int NOT NULL primary key, f1 int) ENGINE = InnoDB + PARTITION BY HASH(i1) PARTITIONS 2; + +INSERT INTO t1 VALUES (1,1), (2,2); + +SELECT * FROM t1 WHERE i1 = ( SELECT i1 FROM t1 WHERE f1=0 LIMIT 1 ); + +DROP TABLE t1; diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index a87c7fbf7b8..dea889663d1 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -4242,8 +4242,12 @@ int ha_partition::index_read_idx_map(uchar *buf, uint index, get_partition_set(table, buf, index, &m_start_key, &m_part_spec); - /* How can it be more than one partition with the current use? */ - DBUG_ASSERT(m_part_spec.start_part == m_part_spec.end_part); + /* + We have either found exactly 1 partition + (in which case start_part == end_part) + or no matching partitions (start_part > end_part) + */ + DBUG_ASSERT(m_part_spec.start_part >= m_part_spec.end_part); for (part= m_part_spec.start_part; part <= m_part_spec.end_part; part++) { From 428f0bdefbf866f0a9939e4153393b1e4b8a1a82 Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Thu, 16 Sep 2010 11:01:06 +0200 Subject: [PATCH 002/304] Bug#56287: mysql5.1.50 crash when using Partition datetime in sub in query When having a sub query in partitioned innodb one could make the partitioning engine to search for a 'index_next_same' on a partition that had not been initialized. Problem was that the subselect function looks at table->status which was not set in the partitioning handler when it skipped scanning due to no matching partitions found. Fixed by setting table->status = STATUS_NOT_FOUND when there was no partitions to scan. (If there are partitions to scan, it will be set in the partitions handler.) mysql-test/r/partition_innodb.result: added result mysql-test/t/partition_innodb.test: added test sql/ha_partition.cc: set table status to not found, if there ar no partitions to scan. --- mysql-test/r/partition_innodb.result | 26 ++++++++++++++++++++++++++ mysql-test/t/partition_innodb.test | 24 ++++++++++++++++++++++++ sql/ha_partition.cc | 2 ++ 3 files changed, 52 insertions(+) diff --git a/mysql-test/r/partition_innodb.result b/mysql-test/r/partition_innodb.result index 2a04aafe554..950eb5de3d8 100644 --- a/mysql-test/r/partition_innodb.result +++ b/mysql-test/r/partition_innodb.result @@ -1,5 +1,31 @@ drop table if exists t1, t2; # +# Bug#56287: crash when using Partition datetime in sub in query +# +CREATE TABLE t1 +(c1 bigint(20) unsigned NOT NULL AUTO_INCREMENT, +c2 varchar(40) not null default '', +c3 datetime not NULL, +PRIMARY KEY (c1,c3), +KEY partidx(c3)) +ENGINE=InnoDB +PARTITION BY RANGE (TO_DAYS(c3)) +(PARTITION p200912 VALUES LESS THAN (to_days('2010-01-01')), +PARTITION p201103 VALUES LESS THAN (to_days('2011-04-01')), +PARTITION p201912 VALUES LESS THAN MAXVALUE); +insert into t1(c2,c3) values ("Test row",'2010-01-01 00:00:00'); +SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 't1' AND TABLE_SCHEMA = 'test'; +PARTITION_NAME TABLE_ROWS +p200912 0 +p201103 1 +p201912 0 +SELECT count(*) FROM t1 p where c3 in +(select c3 from t1 t where t.c3 < date '2011-04-26 19:19:44' + and t.c3 > date '2011-04-26 19:18:44') ; +count(*) +0 +DROP TABLE t1; +# # Bug#51830: Incorrect partition pruning on range partition (regression) # CREATE TABLE t1 (a INT NOT NULL) diff --git a/mysql-test/t/partition_innodb.test b/mysql-test/t/partition_innodb.test index e1ac7b4c7eb..ca668d77199 100644 --- a/mysql-test/t/partition_innodb.test +++ b/mysql-test/t/partition_innodb.test @@ -7,6 +7,30 @@ drop table if exists t1, t2; let $MYSQLD_DATADIR= `SELECT @@datadir`; +--echo # +--echo # Bug#56287: crash when using Partition datetime in sub in query +--echo # +CREATE TABLE t1 +(c1 bigint(20) unsigned NOT NULL AUTO_INCREMENT, + c2 varchar(40) not null default '', + c3 datetime not NULL, + PRIMARY KEY (c1,c3), + KEY partidx(c3)) +ENGINE=InnoDB +PARTITION BY RANGE (TO_DAYS(c3)) +(PARTITION p200912 VALUES LESS THAN (to_days('2010-01-01')), + PARTITION p201103 VALUES LESS THAN (to_days('2011-04-01')), + PARTITION p201912 VALUES LESS THAN MAXVALUE); + +insert into t1(c2,c3) values ("Test row",'2010-01-01 00:00:00'); + +SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 't1' AND TABLE_SCHEMA = 'test'; +SELECT count(*) FROM t1 p where c3 in +(select c3 from t1 t where t.c3 < date '2011-04-26 19:19:44' + and t.c3 > date '2011-04-26 19:18:44') ; + +DROP TABLE t1; + --echo # --echo # Bug#51830: Incorrect partition pruning on range partition (regression) --echo # diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 624ef1aff5b..d3846db42c2 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -4483,6 +4483,7 @@ int ha_partition::partition_scan_set_up(uchar * buf, bool idx_read_flag) key not found. */ DBUG_PRINT("info", ("scan with no partition to scan")); + table->status= STATUS_NOT_FOUND; DBUG_RETURN(HA_ERR_END_OF_FILE); } if (m_part_spec.start_part == m_part_spec.end_part) @@ -4507,6 +4508,7 @@ int ha_partition::partition_scan_set_up(uchar * buf, bool idx_read_flag) if (start_part == MY_BIT_NONE) { DBUG_PRINT("info", ("scan with no partition to scan")); + table->status= STATUS_NOT_FOUND; DBUG_RETURN(HA_ERR_END_OF_FILE); } if (start_part > m_part_spec.start_part) From 66a40d0b8ac73ece279d8a91e3da2aaa9f65ef09 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Fri, 24 Sep 2010 10:44:53 +0100 Subject: [PATCH 003/304] BUG#55263: assert in check_binlog_magic The procedure for setting up a fake binary log, by changing the relay log files manually, is run twice when we issue mtr with --repeat=2. However, when setting it up for the second time, neither the sql thread is reset nor the server is restarted. This means that previous stale relay log IO_CACHE metadata - from first run - is left around. As a consequence, when the test is run for the second time, the IO_CACHE for the relay log has position in file different than zero, triggering the assertion. We fix this by deploying a call to my_b_seek before calling check_binlog_magic in next_event. This prevents the server from asserting, in the cases that the SQL thread was reads from a hot log (relay.NNNNN), then is stopped, then is restarted from a previous cold log (relay.MMMMM), and then it reaches the hot log relay.NNNNN again, in which case, the read coordinates are not set to zero, but to the old values. Additionally, some comments to the source code were added. --- sql/rpl_rli.h | 10 ++++++++ sql/slave.cc | 64 +++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 69 insertions(+), 5 deletions(-) diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h index 87516c366fb..69988fe5995 100644 --- a/sql/rpl_rli.h +++ b/sql/rpl_rli.h @@ -94,6 +94,16 @@ public: */ MYSQL_BIN_LOG relay_log; LOG_INFO linfo; + + /* + cur_log + Pointer that either points at relay_log.get_log_file() or + &rli->cache_buf, depending on whether the log is hot or there was + the need to open a cold relay_log. + + cache_buf + IO_CACHE used when opening cold relay logs. + */ IO_CACHE cache_buf,*cur_log; /* The following variables are safe to read any time */ diff --git a/sql/slave.cc b/sql/slave.cc index f1e0962e7e8..bd9017e6318 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -4349,12 +4349,66 @@ static Log_event* next_event(Relay_log_info* rli) DBUG_ASSERT(rli->cur_log_fd == -1); /* - Read pointer has to be at the start since we are the only - reader. - We must keep the LOCK_log to read the 4 first bytes, as this is a hot - log (same as when we call read_log_event() above: for a hot log we - take the mutex). + When the SQL thread is [stopped and] (re)started the + following may happen: + + 1. Log was hot at stop time and remains hot at restart + + SQL thread reads again from hot_log (SQL thread was + reading from the active log when it was stopped and the + very same log is still active on SQL thread restart). + + In this case, my_b_seek is performed on cur_log, while + cur_log points to relay_log.get_log_file(); + + 2. Log was hot at stop time but got cold before restart + + The log was hot when SQL thread stopped, but it is not + anymore when the SQL thread restarts. + + In this case, the SQL thread reopens the log, using + cache_buf, ie, cur_log points to &cache_buf, and thence + its coordinates are reset. + + 3. Log was already cold at stop time + + The log was not hot when the SQL thread stopped, and, of + course, it will not be hot when it restarts. + + In this case, the SQL thread opens the cold log again, + using cache_buf, ie, cur_log points to &cache_buf, and + thence its coordinates are reset. + + 4. Log was hot at stop time, DBA changes to previous cold + log and restarts SQL thread + + The log was hot when the SQL thread was stopped, but the + user changed the coordinates of the SQL thread to + restart from a previous cold log. + + In this case, at start time, cur_log points to a cold + log, opened using &cache_buf as cache, and coordinates + are reset. However, as it moves on to the next logs, it + will eventually reach the hot log. If the hot log is the + same at the time the SQL thread was stopped, then + coordinates were not reset - the cur_log will point to + relay_log.get_log_file(), and not a freshly opened + IO_CACHE through cache_buf. For this reason we need to + deploy a my_b_seek before calling check_binlog_magic at + this point of the code (see: BUG#55263 for more + details). + + NOTES: + - We must keep the LOCK_log to read the 4 first bytes, as + this is a hot log (same as when we call read_log_event() + above: for a hot log we take the mutex). + + - Because of scenario #4 above, we need to have a + my_b_seek here. Otherwise, we might hit the assertion + inside check_binlog_magic. */ + + my_b_seek(cur_log, (my_off_t) 0); if (check_binlog_magic(cur_log,&errmsg)) { if (!hot_log) pthread_mutex_unlock(log_lock); From 21197c70b8e0f7ef1b7b2d74f693cfd366a05bfd Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 28 Sep 2010 11:16:30 +0200 Subject: [PATCH 004/304] Set version number for mysql-5.1.49sp1 release --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 74e575fad8c..84767b01264 100644 --- a/configure.in +++ b/configure.in @@ -12,7 +12,7 @@ dnl dnl When changing the major version number please also check the switch dnl statement in mysqlbinlog::check_master_version(). You may also need dnl to update version.c in ndb. -AC_INIT([MySQL Server], [5.1.49], [], [mysql]) +AC_INIT([MySQL Server], [5.1.49sp1], [], [mysql]) AC_CONFIG_SRCDIR([sql/mysqld.cc]) AC_CANONICAL_SYSTEM From 2331ea8edbf2dcc9bb7166b19fb038dd37da85ad Mon Sep 17 00:00:00 2001 From: smenon Date: Tue, 28 Sep 2010 12:36:08 +0200 Subject: [PATCH 005/304] Backport into mysql-5.1.49sp1-release > ------------------------------------------------------------ > revno: 3452.1.12 > revision-id: davi.arnaut@oracle.com-20100730121710-sc068t4d2f1c2gi9 > parent: dao-gang.qu@sun.com-20100730035934-8in8err1b1rqu72y > committer: Davi Arnaut > branch nick: mysql-5.1-bugteam > timestamp: Fri 2010-07-30 09:17:10 -0300 > message: > Bug#54041: MySQL 5.0.92 fails when tests from Connector/C suite run > > Fix a regression (due to a typo) which caused spurious incorrect > argument errors for long data stream parameters if all forms of > logging were disabled (binary, general and slow logs). --- mysql-test/r/mysql_client_test.result | 2 ++ mysql-test/t/mysql_client_test.test | 2 ++ sql/sql_prepare.cc | 4 +-- tests/mysql_client_test.c | 49 +++++++++++++++++++++------ 4 files changed, 45 insertions(+), 12 deletions(-) diff --git a/mysql-test/r/mysql_client_test.result b/mysql-test/r/mysql_client_test.result index 08d982c85e3..edda7980e97 100644 --- a/mysql-test/r/mysql_client_test.result +++ b/mysql-test/r/mysql_client_test.result @@ -1,3 +1,5 @@ SET @old_general_log= @@global.general_log; +SET @old_slow_query_log= @@global.slow_query_log; ok SET @@global.general_log= @old_general_log; +SET @@global.slow_query_log= @old_slow_query_log; diff --git a/mysql-test/t/mysql_client_test.test b/mysql-test/t/mysql_client_test.test index 15c0cd4ac84..41670117c7c 100644 --- a/mysql-test/t/mysql_client_test.test +++ b/mysql-test/t/mysql_client_test.test @@ -2,6 +2,7 @@ -- source include/not_embedded.inc SET @old_general_log= @@global.general_log; +SET @old_slow_query_log= @@global.slow_query_log; # We run with different binaries for normal and --embedded-server # @@ -17,3 +18,4 @@ SET @old_general_log= @@global.general_log; echo ok; SET @@global.general_log= @old_general_log; +SET @@global.slow_query_log= @old_slow_query_log; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 041d9f7c30b..e80517d4bc4 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -790,7 +790,7 @@ static bool insert_params_with_log(Prepared_statement *stmt, uchar *null_array, type (the types are supplied at execute). Check that the supplied type of placeholder can accept a data stream. */ - else if (!is_param_long_data_type(param)) + else if (! is_param_long_data_type(param)) DBUG_RETURN(1); res= param->query_val_str(&str); if (param->convert_str_value(thd)) @@ -836,7 +836,7 @@ static bool insert_params(Prepared_statement *stmt, uchar *null_array, type (the types are supplied at execute). Check that the supplied type of placeholder can accept a data stream. */ - else if (is_param_long_data_type(param)) + else if (! is_param_long_data_type(param)) DBUG_RETURN(1); if (param->convert_str_value(stmt->thd)) DBUG_RETURN(1); /* out of memory */ diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 97d146ff9ef..a5f5812c2f0 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -13246,37 +13246,52 @@ static void test_bug15518() } -static void disable_general_log() +static void disable_query_logs() { int rc; rc= mysql_query(mysql, "set @@global.general_log=off"); myquery(rc); + rc= mysql_query(mysql, "set @@global.slow_query_log=off"); + myquery(rc); } -static void enable_general_log(int truncate) +static void enable_query_logs(int truncate) { int rc; rc= mysql_query(mysql, "set @save_global_general_log=@@global.general_log"); myquery(rc); + rc= mysql_query(mysql, "set @save_global_slow_query_log=@@global.slow_query_log"); + myquery(rc); + rc= mysql_query(mysql, "set @@global.general_log=on"); myquery(rc); + rc= mysql_query(mysql, "set @@global.slow_query_log=on"); + myquery(rc); + + if (truncate) { rc= mysql_query(mysql, "truncate mysql.general_log"); myquery(rc); + + rc= mysql_query(mysql, "truncate mysql.slow_log"); + myquery(rc); } } -static void restore_general_log() +static void restore_query_logs() { int rc; rc= mysql_query(mysql, "set @@global.general_log=@save_global_general_log"); myquery(rc); + + rc= mysql_query(mysql, "set @@global.slow_query_log=@save_global_slow_query_log"); + myquery(rc); } @@ -15447,7 +15462,7 @@ static void test_bug17667() return; } - enable_general_log(1); + enable_query_logs(1); for (statement_cursor= statements; statement_cursor->buffer != NULL; statement_cursor++) @@ -15527,7 +15542,7 @@ static void test_bug17667() statement_cursor->buffer); } - restore_general_log(); + restore_query_logs(); if (!opt_silent) printf("success. All queries found intact in the log.\n"); @@ -17390,7 +17405,7 @@ static void test_bug28386() } mysql_free_result(result); - enable_general_log(1); + enable_query_logs(1); stmt= mysql_simple_prepare(mysql, "SELECT ?"); check_stmt(stmt); @@ -17429,7 +17444,7 @@ static void test_bug28386() mysql_free_result(result); - restore_general_log(); + restore_query_logs(); DBUG_VOID_RETURN; } @@ -18215,7 +18230,7 @@ static void test_bug42373() Bug#54041: MySQL 5.0.92 fails when tests from Connector/C suite run */ -static void test_bug54041() +static void test_bug54041_impl() { int rc; MYSQL_STMT *stmt; @@ -18230,7 +18245,7 @@ static void test_bug54041() rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)"); myquery(rc); - stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 (a) VALUES (?)"); + stmt= mysql_simple_prepare(mysql, "SELECT a FROM t1 WHERE a > ?"); check_stmt(stmt); verify_param_count(stmt, 1); @@ -18268,6 +18283,20 @@ static void test_bug54041() } +/** + Bug#54041: MySQL 5.0.92 fails when tests from Connector/C suite run +*/ + +static void test_bug54041() +{ + enable_query_logs(0); + test_bug54041_impl(); + disable_query_logs(); + test_bug54041_impl(); + restore_query_logs(); +} + + /* Read and parse arguments and MySQL options from my.cnf */ @@ -18348,7 +18377,7 @@ and you are welcome to modify and redistribute it under the GPL license\n"); static struct my_tests_st my_tests[]= { - { "disable_general_log", disable_general_log }, + { "disable_query_logs", disable_query_logs }, { "test_view_sp_list_fields", test_view_sp_list_fields }, { "client_query", client_query }, { "test_prepare_insert_update", test_prepare_insert_update}, From e73738f13f037fcc78ae4480007104bfdfc8778c Mon Sep 17 00:00:00 2001 From: smenon Date: Tue, 28 Sep 2010 12:39:22 +0200 Subject: [PATCH 006/304] Backport into mysql-5.1.49sp1-release > ------------------------------------------------------------ > revno: 3457.3.1 > revision-id: alexey.kopytov@sun.com-20100712145855-niybvwsthe480r69 > parent: mattias.jonsson@oracle.com-20100709130033-fgr7hggrrebf6qkc > committer: Alexey Kopytov > branch nick: 55061-5.1-bugteam > timestamp: Mon 2010-07-12 18:58:55 +0400 > message: > Bug#55061: Build failing on sol 8 x86 - assembler code vs > compiler problem > > GCC-style inline assembly is not supported by the Sun Studio > compilers prior to version 12. > > Added a check for the Sun Studio version to avoid using > _FPU_GETCW() / _FPU_SETCW() when inline assembly is > unsupported. This can lead to some differences in floating > point calculations on Solaris 8/x86 which, however, is not worth > bothering with Sun-style assembly .il templates. --- sql/mysqld.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 5514c356bd1..f9012b750f4 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -190,7 +190,7 @@ typedef fp_except fp_except_t; # define fpu_control_t unsigned int # define _FPU_EXTENDED 0x300 # define _FPU_DOUBLE 0x200 -# if defined(__GNUC__) || defined(__SUNPRO_CC) +# if defined(__GNUC__) || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x590) # define _FPU_GETCW(cw) asm volatile ("fnstcw %0" : "=m" (*&cw)) # define _FPU_SETCW(cw) asm volatile ("fldcw %0" : : "m" (*&cw)) # else From dd1d7ff161e22d697eec3c40893d380b0c0ef0bb Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Tue, 5 Oct 2010 14:57:51 +0200 Subject: [PATCH 007/304] Bug#55091: Server crashes on ADD PARTITION after a failed attempt In case of failure in ALTER ... PARTITION under LOCK TABLE the server could crash, due to it had modified the locked table object, which was not reverted in case of failure, resulting in a bad table definition used after the failed command. Solved by always closing the LOCKED TABLE, even in case of error. Note: this is a 5.1-only fix, bug#56172 fixed it in 5.5+ mysql-test/r/partition_innodb_plugin.result: updated result mysql-test/t/disabled.def: Only disabled valgrind instead. mysql-test/t/partition_innodb_plugin.test: Added test sql/sql_partition.cc: close_thread_tables do not close LOCKED TABLEs and destroys the table object (including part_info), so to avoid it to be reused, always close the table regardless of any previous failure. --- mysql-test/r/partition_innodb_plugin.result | 73 +++++++++++++++++++++ mysql-test/t/disabled.def | 1 - mysql-test/t/partition_innodb_plugin.test | 66 +++++++++++++++++++ sql/sql_partition.cc | 21 +++++- 4 files changed, 159 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/partition_innodb_plugin.result b/mysql-test/r/partition_innodb_plugin.result index dd91eee316a..f6b5ce84338 100644 --- a/mysql-test/r/partition_innodb_plugin.result +++ b/mysql-test/r/partition_innodb_plugin.result @@ -1,3 +1,76 @@ +call mtr.add_suppression("nnoDB: Error: table `test`.`t1` .* Partition.* InnoDB internal"); +# +# Bug#55091: Server crashes on ADD PARTITION after a failed attempt +# +SET @old_innodb_file_format_check = @@global.innodb_file_format_check; +SET @old_innodb_file_format = @@global.innodb_file_format; +SET @old_innodb_file_per_table = @@global.innodb_file_per_table; +SET @old_innodb_strict_mode = @@global.innodb_strict_mode; +SET @@global.innodb_file_format = Barracuda, +@@global.innodb_file_per_table = ON, +@@global.innodb_strict_mode = ON; +# Connection con1 +CREATE TABLE t1 (id INT NOT NULL +PRIMARY KEY, +user_num CHAR(10) +) ENGINE = InnoDB +KEY_BLOCK_SIZE=4 +PARTITION BY HASH(id) PARTITIONS 1; +t1#P#p0.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL, + `user_num` char(10) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=4 +/*!50100 PARTITION BY HASH (id) +PARTITIONS 1 */ +SET GLOBAL innodb_file_per_table = OFF; +# Connection con2 +LOCK TABLE t1 WRITE; +# ALTER fails because COMPRESSED/KEY_BLOCK_SIZE +# are incompatible with innodb_file_per_table = OFF; +ALTER TABLE t1 ADD PARTITION PARTITIONS 1; +ERROR HY000: Got error 1478 from storage engine +t1#P#p0.ibd +t1.frm +t1.par +# This SET is not needed to reproduce the bug, +# it is here just to make the test case more realistic +SET innodb_strict_mode = OFF; +ALTER TABLE t1 ADD PARTITION PARTITIONS 2; +Warnings: +Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=4. +Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=4. +Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=4. +t1.frm +t1.par +ALTER TABLE t1 REBUILD PARTITION p0; +Warnings: +Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=4. +UNLOCK TABLES; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL, + `user_num` char(10) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=4 +/*!50100 PARTITION BY HASH (id) +PARTITIONS 3 */ +DROP TABLE t1; +# Connection default +SET @@global.innodb_strict_mode = @old_innodb_strict_mode; +SET @@global.innodb_file_format = @old_innodb_file_format; +SET @@global.innodb_file_per_table = @old_innodb_file_per_table; +SET @@global.innodb_file_format_check = @old_innodb_file_format_check; SET NAMES utf8; CREATE TABLE `t``\""e` (a INT, PRIMARY KEY (a)) ENGINE=InnoDB diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index cede26f555a..bb931fb7b14 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -11,6 +11,5 @@ ############################################################################## kill : Bug#37780 2008-12-03 HHunger need some changes to be robust enough for pushbuild. query_cache_28249 : Bug#43861 2009-03-25 main.query_cache_28249 fails sporadically -partition_innodb_plugin : Bug#53307 2010-04-30 VasilDimov valgrind warnings main.mysqlhotcopy_myisam : bug#54129 2010-06-04 Horst main.mysqlhotcopy_archive: bug#54129 2010-06-04 Horst diff --git a/mysql-test/t/partition_innodb_plugin.test b/mysql-test/t/partition_innodb_plugin.test index eeb990c0d81..114adf67180 100644 --- a/mysql-test/t/partition_innodb_plugin.test +++ b/mysql-test/t/partition_innodb_plugin.test @@ -1,5 +1,71 @@ --source include/have_partition.inc --source include/have_innodb_plugin.inc +# Remove the line below when bug#53307 is solved. +--source include/not_valgrind.inc + +let $MYSQLD_DATADIR= `SELECT @@datadir`; + +call mtr.add_suppression("nnoDB: Error: table `test`.`t1` .* Partition.* InnoDB internal"); +--echo # +--echo # Bug#55091: Server crashes on ADD PARTITION after a failed attempt +--echo # +SET @old_innodb_file_format_check = @@global.innodb_file_format_check; +SET @old_innodb_file_format = @@global.innodb_file_format; +SET @old_innodb_file_per_table = @@global.innodb_file_per_table; +SET @old_innodb_strict_mode = @@global.innodb_strict_mode; +SET @@global.innodb_file_format = Barracuda, +@@global.innodb_file_per_table = ON, +@@global.innodb_strict_mode = ON; + +--echo # Connection con1 +--connect(con1,localhost,root,,) + +CREATE TABLE t1 (id INT NOT NULL +PRIMARY KEY, +user_num CHAR(10) +) ENGINE = InnoDB +KEY_BLOCK_SIZE=4 +PARTITION BY HASH(id) PARTITIONS 1; + +--list_files $MYSQLD_DATADIR/test +SHOW CREATE TABLE t1; + +SET GLOBAL innodb_file_per_table = OFF; + +--disconnect con1 +--connect(con2,localhost,root,,) +--echo # Connection con2 + +LOCK TABLE t1 WRITE; + +--echo # ALTER fails because COMPRESSED/KEY_BLOCK_SIZE +--echo # are incompatible with innodb_file_per_table = OFF; + +--error ER_GET_ERRNO +ALTER TABLE t1 ADD PARTITION PARTITIONS 1; + +--list_files $MYSQLD_DATADIR/test +--echo # This SET is not needed to reproduce the bug, +--echo # it is here just to make the test case more realistic +SET innodb_strict_mode = OFF; + +ALTER TABLE t1 ADD PARTITION PARTITIONS 2; +--list_files $MYSQLD_DATADIR/test + +# really bug#56172 +ALTER TABLE t1 REBUILD PARTITION p0; + +UNLOCK TABLES; +SHOW CREATE TABLE t1; +DROP TABLE t1; + +--disconnect con2 +--connection default +--echo # Connection default +SET @@global.innodb_strict_mode = @old_innodb_strict_mode; +SET @@global.innodb_file_format = @old_innodb_file_format; +SET @@global.innodb_file_per_table = @old_innodb_file_per_table; +SET @@global.innodb_file_format_check = @old_innodb_file_format_check; # # Bug#32430 - show engine innodb status causes errors diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 76caa2b0c8d..7b0c47865d8 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -5934,6 +5934,12 @@ static void alter_partition_lock_handling(ALTER_PARTITION_PARAM_TYPE *lpt) int err; if (lpt->thd->locked_tables) { + /* + Close the table if open, to remove/destroy the already altered + table->part_info object, so that it is not reused. + */ + if (lpt->table->db_stat) + abort_and_upgrade_lock_and_close_table(lpt); /* When we have the table locked, it is necessary to reopen the table since all table objects were closed and removed as part of the @@ -6436,7 +6442,20 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, table, table_list, FALSE, NULL, written_bin_log)); err: - close_thread_tables(thd); + if (thd->locked_tables) + { + /* + table->part_info was altered in prep_alter_part_table and must be + destroyed and recreated, since otherwise it will be reused, since + we are under LOCK TABLE. + */ + alter_partition_lock_handling(lpt); + } + else + { + /* Force the table to be closed to avoid reuse of the table->part_info */ + close_thread_tables(thd); + } DBUG_RETURN(TRUE); } #endif From c93eecdf0ad4d0c8fdee057ddb9eca258a29bd88 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Wed, 6 Oct 2010 12:23:46 +0100 Subject: [PATCH 008/304] BUG#38718: slave sql thread crashes when reading relay log Suprisingly, a Slave_log_event would show up in the binary log. This event is never used and should not appear in the logs. As such, when the slave (or the mysqlbinlog tool) reads the event, it will hit an invalid pointer (reference to the descriptor event when deserializing the Slave_log_event was purposodely set to NULL). The presence of the Slave_log_event denotes a corrupted log, but we cannot tell how the log got corrupted in the first place. However, we can make the server cope with such events when it reads them - in case of log corruption - and fail gracefully. This patch makes the server/mysqlbinlog to report that it has found an invalid log event when Slave_log_event is read. --- sql/log_event.cc | 14 ++++++++++---- sql/log_event.h | 4 +++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index 7becdf51747..98ce3fbade8 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1225,7 +1225,7 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len, break; #ifdef HAVE_REPLICATION case SLAVE_EVENT: /* can never happen (unused event) */ - ev = new Slave_log_event(buf, event_len); + ev = new Slave_log_event(buf, event_len, description_event); break; #endif /* HAVE_REPLICATION */ case CREATE_FILE_EVENT: @@ -1313,8 +1313,10 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len, (because constructor is "void") ; so instead we leave the pointer we wanted to allocate (e.g. 'query') to 0 and we test it in is_valid(). Same for Format_description_log_event, member 'post_header_len'. + + SLAVE_EVENT is never used, so it should not be read ever. */ - if (!ev || !ev->is_valid()) + if (!ev || !ev->is_valid() || (event_type == SLAVE_EVENT)) { DBUG_PRINT("error",("Found invalid event in binary log")); @@ -5978,8 +5980,12 @@ void Slave_log_event::init_from_mem_pool(int data_size) /** This code is not used, so has not been updated to be format-tolerant. */ -Slave_log_event::Slave_log_event(const char* buf, uint event_len) - :Log_event(buf,0) /*unused event*/ ,mem_pool(0),master_host(0) +/* We are using description_event so that slave does not crash on Log_event + constructor */ +Slave_log_event::Slave_log_event(const char* buf, + uint event_len, + const Format_description_log_event* description_event) + :Log_event(buf,description_event),mem_pool(0),master_host(0) { if (event_len < LOG_EVENT_HEADER_LEN) return; diff --git a/sql/log_event.h b/sql/log_event.h index 816a241e55d..662fec23639 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -1782,7 +1782,9 @@ public: void print(FILE* file, PRINT_EVENT_INFO* print_event_info); #endif - Slave_log_event(const char* buf, uint event_len); + Slave_log_event(const char* buf, + uint event_len, + const Format_description_log_event *description_event); ~Slave_log_event(); int get_data_size(); bool is_valid() const { return master_host != 0; } From 84662b98040ac335af659a7f5a36b887ffe57155 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Wed, 6 Oct 2010 15:15:27 +0200 Subject: [PATCH 009/304] Bug#55647:CMake build rebuilds some libraries twice for embedded A simple version of the patch : add WITH_PIC to debug compilation. Engines that are not dependent on internal stuff (like THD structure) will not be recompiled for embedded in debug mode. Examples of such engines are : archive, federated, innodb. Engines with dependencies on internals (myisam,heap,myisammrg) will still be fully recompiled. --- CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5eddad4ad15..ea544ebcbbf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,6 +61,11 @@ SET(BUILDTYPE_DOCSTRING IF(WITH_DEBUG) SET(CMAKE_BUILD_TYPE "Debug" CACHE STRING ${BUILDTYPE_DOCSTRING} FORCE) + IF(UNIX AND NOT APPLE) + # Compiling with PIC speeds up embedded build, on PIC sensitive systems + # Predefine it to ON, in case user chooses to build embedded. + SET(WITH_PIC ON CACHE BOOL "Compile with PIC") + ENDIF() SET(OLD_WITH_DEBUG 1 CACHE INTERNAL "" FORCE) ELSEIF(NOT HAVE_CMAKE_BUILD_TYPE OR OLD_WITH_DEBUG) IF(CUSTOM_C_FLAGS) From 8642812c98b37f91f1cbbc58e0964702d1d37e23 Mon Sep 17 00:00:00 2001 From: Mats Kindahl Date: Wed, 6 Oct 2010 19:20:18 +0200 Subject: [PATCH 010/304] Bug #52131: SET and ENUM stored endian-dependent in binary log Replication SET and ENUM fields from a big-endian to a little- endian machine (or the opposite) that are represented using more than 1 byte (SET fields with more than 8 members or ENUM fields with more than 256 constants) will fail to replicate correctly when using row-based replication. The reason is that there are no pack() or unpack() functions for Field_set or Field_enum, which make them rely on Field::pack and Field::unpack. These functions pack data as strings, but since Field_set and Field_enum use integral types for representation, the fields are stored incorrectly on big-endian machines. This patch adds Field_enum::pack and Field_enum::unpack functions that store the integral value correctly in the binary log even on big-endian machines. Since Field_set inherits from Field_enum, it will use the same functions for packing and unpacking the field. sql/field.cc: Removing some obsolete debug printouts and adding Field_enum::pack and Field_enum::unpack functions. sql/field.h: Adding helper functions for packing and unpacking 16- and 24-bit integral types. Field_short::pack and Field_short::unpack now use these functions. sql/rpl_record.cc: Removing some obsolete debug printouts and adding some more useful ones. --- sql/field.cc | 53 +++++++++++++++++++---- sql/field.h | 106 +++++++++++++++++++++++++++++++++------------- sql/rpl_record.cc | 10 +++-- 3 files changed, 127 insertions(+), 42 deletions(-) diff --git a/sql/field.cc b/sql/field.cc index 728cd7e4090..b83b2bfae5a 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -7725,12 +7725,6 @@ void Field_blob::sql_type(String &res) const uchar *Field_blob::pack(uchar *to, const uchar *from, uint max_length, bool low_byte_first) { - DBUG_ENTER("Field_blob::pack"); - DBUG_PRINT("enter", ("to: 0x%lx; from: 0x%lx;" - " max_length: %u; low_byte_first: %d", - (ulong) to, (ulong) from, - max_length, low_byte_first)); - DBUG_DUMP("record", from, table->s->reclength); uchar *save= ptr; ptr= (uchar*) from; uint32 length=get_length(); // Length of from string @@ -7751,8 +7745,7 @@ uchar *Field_blob::pack(uchar *to, const uchar *from, memcpy(to+packlength, from,length); } ptr=save; // Restore org row pointer - DBUG_DUMP("packed", to, packlength + length); - DBUG_RETURN(to+packlength+length); + return to+packlength+length; } @@ -8396,6 +8389,50 @@ uint Field_enum::is_equal(Create_field *new_field) } +uchar *Field_enum::pack(uchar *to, const uchar *from, + uint max_length, bool low_byte_first) +{ + DBUG_ENTER("Field_enum::pack"); + DBUG_PRINT("debug", ("packlength: %d", packlength)); + DBUG_DUMP("from", from, packlength); + + switch (packlength) + { + case 1: + *to = *from; + DBUG_RETURN(to + 1); + case 2: DBUG_RETURN(pack_int16(to, from, low_byte_first)); + case 3: DBUG_RETURN(pack_int24(to, from, low_byte_first)); + case 4: DBUG_RETURN(pack_int32(to, from, low_byte_first)); + case 8: DBUG_RETURN(pack_int64(to, from, low_byte_first)); + default: + DBUG_ASSERT(0); + } +} + +const uchar *Field_enum::unpack(uchar *to, const uchar *from, + uint param_data, bool low_byte_first) +{ + DBUG_ENTER("Field_enum::unpack"); + DBUG_PRINT("debug", ("packlength: %d", packlength)); + DBUG_DUMP("from", from, packlength); + + switch (packlength) + { + case 1: + *to = *from; + DBUG_RETURN(from + 1); + + case 2: DBUG_RETURN(unpack_int16(to, from, low_byte_first)); + case 3: DBUG_RETURN(unpack_int24(to, from, low_byte_first)); + case 4: DBUG_RETURN(unpack_int32(to, from, low_byte_first)); + case 8: DBUG_RETURN(unpack_int64(to, from, low_byte_first)); + default: + DBUG_ASSERT(0); + } +} + + /** @return returns 1 if the fields are equally defined diff --git a/sql/field.h b/sql/field.h index 7b250c34fe4..d854b78f9a3 100644 --- a/sql/field.h +++ b/sql/field.h @@ -554,6 +554,48 @@ private: { return 0; } protected: + static void handle_int16(uchar *to, const uchar *from, + bool low_byte_first_from, bool low_byte_first_to) + { + int16 val; +#ifdef WORDS_BIGENDIAN + if (low_byte_first_from) + val = sint2korr(from); + else +#endif + shortget(val, from); + +#ifdef WORDS_BIGENDIAN + if (low_byte_first_to) + int2store(to, val); + else +#endif + shortstore(to, val); + } + + static void handle_int24(uchar *to, const uchar *from, + bool low_byte_first_from, bool low_byte_first_to) + { + int32 val; +#ifdef WORDS_BIGENDIAN + if (low_byte_first_from) + val = sint3korr(from); + else +#endif + val= (from[0] << 16) + (from[1] << 8) + from[2]; + +#ifdef WORDS_BIGENDIAN + if (low_byte_first_to) + int2store(to, val); + else +#endif + { + to[0]= 0xFF & (val >> 16); + to[1]= 0xFF & (val >> 8); + to[2]= 0xFF & val; + } + } + /* Helper function to pack()/unpack() int32 values */ @@ -598,6 +640,32 @@ protected: longlongstore(to, val); } + uchar *pack_int16(uchar *to, const uchar *from, bool low_byte_first_to) + { + handle_int16(to, from, table->s->db_low_byte_first, low_byte_first_to); + return to + sizeof(int16); + } + + const uchar *unpack_int16(uchar* to, const uchar *from, + bool low_byte_first_from) + { + handle_int16(to, from, low_byte_first_from, table->s->db_low_byte_first); + return from + sizeof(int16); + } + + uchar *pack_int24(uchar *to, const uchar *from, bool low_byte_first_to) + { + handle_int24(to, from, table->s->db_low_byte_first, low_byte_first_to); + return to + 3; + } + + const uchar *unpack_int24(uchar* to, const uchar *from, + bool low_byte_first_from) + { + handle_int24(to, from, low_byte_first_from, table->s->db_low_byte_first); + return from + 3; + } + uchar *pack_int32(uchar *to, const uchar *from, bool low_byte_first_to) { handle_int32(to, from, table->s->db_low_byte_first, low_byte_first_to); @@ -918,41 +986,13 @@ public: virtual uchar *pack(uchar* to, const uchar *from, uint max_length, bool low_byte_first) { - int16 val; -#ifdef WORDS_BIGENDIAN - if (table->s->db_low_byte_first) - val = sint2korr(from); - else -#endif - shortget(val, from); - -#ifdef WORDS_BIGENDIAN - if (low_byte_first) - int2store(to, val); - else -#endif - shortstore(to, val); - return to + sizeof(val); + return pack_int16(to, from, low_byte_first); } virtual const uchar *unpack(uchar* to, const uchar *from, uint param_data, bool low_byte_first) { - int16 val; -#ifdef WORDS_BIGENDIAN - if (low_byte_first) - val = sint2korr(from); - else -#endif - shortget(val, from); - -#ifdef WORDS_BIGENDIAN - if (table->s->db_low_byte_first) - int2store(to, val); - else -#endif - shortstore(to, val); - return from + sizeof(val); + return unpack_int16(to, from, low_byte_first); } }; @@ -1895,6 +1935,12 @@ public: bool has_charset(void) const { return TRUE; } /* enum and set are sorted as integers */ CHARSET_INFO *sort_charset(void) const { return &my_charset_bin; } + + virtual uchar *pack(uchar *to, const uchar *from, + uint max_length, bool low_byte_first); + virtual const uchar *unpack(uchar *to, const uchar *from, + uint param_data, bool low_byte_first); + private: int do_save_field_metadata(uchar *first_byte); uint is_equal(Create_field *new_field); diff --git a/sql/rpl_record.cc b/sql/rpl_record.cc index 8219f70727e..dd16318303d 100644 --- a/sql/rpl_record.cc +++ b/sql/rpl_record.cc @@ -78,8 +78,6 @@ pack_row(TABLE *table, MY_BITMAP const* cols, unsigned int null_mask= 1U; for ( ; (field= *p_field) ; p_field++) { - DBUG_PRINT("debug", ("null_mask=%d; null_ptr=%p; row_data=%p; null_byte_count=%d", - null_mask, null_ptr, row_data, null_byte_count)); if (bitmap_is_set(cols, p_field - table->field)) { my_ptrdiff_t offset; @@ -110,6 +108,7 @@ pack_row(TABLE *table, MY_BITMAP const* cols, field->field_name, field->real_type(), (ulong) old_pack_ptr, (ulong) pack_ptr, (int) (pack_ptr - old_pack_ptr))); + DBUG_DUMP("packed_data", old_pack_ptr, pack_ptr - old_pack_ptr); } null_mask <<= 1; @@ -380,8 +379,11 @@ unpack_row(Relay_log_info const *rli, } DBUG_ASSERT(null_mask & 0xFF); // One of the 8 LSB should be set - if (!((null_bits & null_mask) && tabledef->maybe_null(i))) - pack_ptr+= tabledef->calc_field_size(i, (uchar *) pack_ptr); + if (!((null_bits & null_mask) && tabledef->maybe_null(i))) { + uint32 len= tabledef->calc_field_size(i, (uchar *) pack_ptr); + DBUG_DUMP("field_data", pack_ptr, len); + pack_ptr+= len; + } null_mask <<= 1; } } From d51cd894dac501d808da0c3bc08636f387014eb3 Mon Sep 17 00:00:00 2001 From: Marc Alff Date: Wed, 6 Oct 2010 18:03:27 -0600 Subject: [PATCH 011/304] Bug#57154 Rename THREADS.ID to THREADS.PROCESSLIST_ID in 5.5 This change is to align the 5.5 performance_schema.THREADS table definition with the 5.6 performance_schema.THREADS table, to facilitate the 5.5 -> 5.6 migration later. In the table performance_schema.THREADS: - renamed ID to PROCESSLIST_ID, removed not null - changed NAME from varchar(64) to varchar(128) to match the columns definitions from 5.6 Adjusted the test cases accordingly. Note: this fix is for 5.5 only, to null merge into 5.6 --- .../suite/perfschema/include/setup_helper.inc | 12 ++--- .../suite/perfschema/r/dml_threads.result | 6 +-- .../suite/perfschema/r/func_file_io.result | 17 +------ mysql-test/suite/perfschema/r/selects.result | 18 ++++---- .../suite/perfschema/t/dml_threads.test | 8 ++-- .../suite/perfschema/t/func_file_io.test | 46 +++++++++---------- mysql-test/suite/perfschema/t/selects.test | 16 +++---- .../suite/perfschema/t/thread_cache.test | 12 ++--- scripts/mysql_system_tables.sql | 4 +- storage/perfschema/table_threads.cc | 11 +++-- storage/perfschema/table_threads.h | 4 +- 11 files changed, 70 insertions(+), 84 deletions(-) diff --git a/mysql-test/suite/perfschema/include/setup_helper.inc b/mysql-test/suite/perfschema/include/setup_helper.inc index 1c8d4e412d5..195b9cf960a 100644 --- a/mysql-test/suite/perfschema/include/setup_helper.inc +++ b/mysql-test/suite/perfschema/include/setup_helper.inc @@ -1,4 +1,4 @@ -# Copyright (C) 2009 Sun Microsystems, Inc +# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -10,8 +10,8 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# along with this program; if not, write to the Free Software Foundation, +# 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA # Tests for PERFORMANCE_SCHEMA @@ -26,17 +26,17 @@ update performance_schema.SETUP_CONSUMERS set enabled='YES'; connect (con1, localhost, root, , ); let $con1_THREAD_ID=`select thread_id from performance_schema.THREADS - where ID in (select connection_id())`; + where PROCESSLIST_ID = connection_id()`; connect (con2, localhost, root, , ); let $con2_THREAD_ID=`select thread_id from performance_schema.THREADS - where ID in (select connection_id())`; + where PROCESSLIST_ID = connection_id()`; connect (con3, localhost, root, , ); let $con3_THREAD_ID=`select thread_id from performance_schema.THREADS - where ID in (select connection_id())`; + where PROCESSLIST_ID = connection_id()`; connection default; diff --git a/mysql-test/suite/perfschema/r/dml_threads.result b/mysql-test/suite/perfschema/r/dml_threads.result index b4fa8705c95..261e7977aa5 100644 --- a/mysql-test/suite/perfschema/r/dml_threads.result +++ b/mysql-test/suite/perfschema/r/dml_threads.result @@ -1,12 +1,12 @@ select * from performance_schema.THREADS where name like 'Thread/%' limit 1; -THREAD_ID ID NAME +THREAD_ID PROCESSLIST_ID NAME # # # select * from performance_schema.THREADS where name='FOO'; -THREAD_ID ID NAME +THREAD_ID PROCESSLIST_ID NAME insert into performance_schema.THREADS -set name='FOO', thread_id=1, id=2; +set name='FOO', thread_id=1, processlist_id=2; ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'THREADS' update performance_schema.THREADS set thread_id=12; diff --git a/mysql-test/suite/perfschema/r/func_file_io.result b/mysql-test/suite/perfschema/r/func_file_io.result index 201254aca21..655ce1394f9 100644 --- a/mysql-test/suite/perfschema/r/func_file_io.result +++ b/mysql-test/suite/perfschema/r/func_file_io.result @@ -94,24 +94,9 @@ FROM performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME WHERE COUNT_STAR > 0 ORDER BY SUM_TIMER_WAIT DESC LIMIT 10; -SELECT i.user, SUM(TIMER_WAIT) SUM_WAIT -# ((TIME_TO_SEC(TIMEDIFF(NOW(), i.startup_time)) * 1000) / SUM(TIMER_WAIT)) * 100 WAIT_PERCENTAGE -FROM performance_schema.EVENTS_WAITS_HISTORY_LONG h -INNER JOIN performance_schema.THREADS p USING (THREAD_ID) -LEFT JOIN information_schema.PROCESSLIST i USING (ID) -GROUP BY i.user -ORDER BY SUM_WAIT DESC -LIMIT 20; SELECT h.EVENT_NAME, SUM(h.TIMER_WAIT) TOTAL_WAIT FROM performance_schema.EVENTS_WAITS_HISTORY_LONG h INNER JOIN performance_schema.THREADS p USING (THREAD_ID) -WHERE p.ID = 1 +WHERE p.PROCESSLIST_ID = 1 GROUP BY h.EVENT_NAME HAVING TOTAL_WAIT > 0; -SELECT i.user, h.operation, SUM(NUMBER_OF_BYTES) bytes -FROM performance_schema.EVENTS_WAITS_HISTORY_LONG h -INNER JOIN performance_schema.THREADS p USING (THREAD_ID) -LEFT JOIN information_schema.PROCESSLIST i USING (ID) -GROUP BY i.user, h.operation -HAVING BYTES > 0 -ORDER BY i.user, h.operation; diff --git a/mysql-test/suite/perfschema/r/selects.result b/mysql-test/suite/perfschema/r/selects.result index dfc9007c740..6d596ba8d9a 100644 --- a/mysql-test/suite/perfschema/r/selects.result +++ b/mysql-test/suite/perfschema/r/selects.result @@ -84,22 +84,22 @@ id c 13 [EVENT_ID] DROP TRIGGER t_ps_trigger; DROP PROCEDURE IF EXISTS t_ps_proc; -CREATE PROCEDURE t_ps_proc(IN tid INT, OUT pid INT) +CREATE PROCEDURE t_ps_proc(IN conid INT, OUT pid INT) BEGIN -SELECT id FROM performance_schema.THREADS -WHERE THREAD_ID = tid INTO pid; +SELECT thread_id FROM performance_schema.THREADS +WHERE PROCESSLIST_ID = conid INTO pid; END; | -CALL t_ps_proc(0, @p_id); +CALL t_ps_proc(connection_id(), @p_id); DROP FUNCTION IF EXISTS t_ps_proc; -CREATE FUNCTION t_ps_func(tid INT) RETURNS int +CREATE FUNCTION t_ps_func(conid INT) RETURNS int BEGIN -return (SELECT id FROM performance_schema.THREADS -WHERE THREAD_ID = tid); +return (SELECT thread_id FROM performance_schema.THREADS +WHERE PROCESSLIST_ID = conid); END; | -SELECT t_ps_func(0) = @p_id; -t_ps_func(0) = @p_id +SELECT t_ps_func(connection_id()) = @p_id; +t_ps_func(connection_id()) = @p_id 1 SELECT * FROM t_event; EVENT_ID diff --git a/mysql-test/suite/perfschema/t/dml_threads.test b/mysql-test/suite/perfschema/t/dml_threads.test index 6ea456fee69..b6a65b57733 100644 --- a/mysql-test/suite/perfschema/t/dml_threads.test +++ b/mysql-test/suite/perfschema/t/dml_threads.test @@ -1,4 +1,4 @@ -# Copyright (C) 2009 Sun Microsystems, Inc +# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -10,8 +10,8 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# along with this program; if not, write to the Free Software Foundation, +# 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA # Tests for PERFORMANCE_SCHEMA @@ -28,7 +28,7 @@ select * from performance_schema.THREADS --replace_result '\'threads' '\'THREADS' --error ER_TABLEACCESS_DENIED_ERROR insert into performance_schema.THREADS - set name='FOO', thread_id=1, id=2; + set name='FOO', thread_id=1, processlist_id=2; --replace_result '\'threads' '\'THREADS' --error ER_TABLEACCESS_DENIED_ERROR diff --git a/mysql-test/suite/perfschema/t/func_file_io.test b/mysql-test/suite/perfschema/t/func_file_io.test index 6b6335ac424..dc9a7a09e40 100644 --- a/mysql-test/suite/perfschema/t/func_file_io.test +++ b/mysql-test/suite/perfschema/t/func_file_io.test @@ -1,4 +1,4 @@ -# Copyright (C) 2008-2009 Sun Microsystems, Inc +# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -10,8 +10,8 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# along with this program; if not, write to the Free Software Foundation, +# 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA ## ## WL#4814, 4.1.4 FILE IO @@ -154,16 +154,16 @@ LIMIT 10; # Total and average wait time for different users # ---disable_result_log -SELECT i.user, SUM(TIMER_WAIT) SUM_WAIT -# ((TIME_TO_SEC(TIMEDIFF(NOW(), i.startup_time)) * 1000) / SUM(TIMER_WAIT)) * 100 WAIT_PERCENTAGE -FROM performance_schema.EVENTS_WAITS_HISTORY_LONG h -INNER JOIN performance_schema.THREADS p USING (THREAD_ID) -LEFT JOIN information_schema.PROCESSLIST i USING (ID) -GROUP BY i.user -ORDER BY SUM_WAIT DESC -LIMIT 20; ---enable_result_log +## --disable_result_log +## SELECT i.user, SUM(TIMER_WAIT) SUM_WAIT +## # ((TIME_TO_SEC(TIMEDIFF(NOW(), i.startup_time)) * 1000) / SUM(TIMER_WAIT)) * 100 WAIT_PERCENTAGE +## FROM performance_schema.EVENTS_WAITS_HISTORY_LONG h +## INNER JOIN performance_schema.THREADS p USING (THREAD_ID) +## LEFT JOIN information_schema.PROCESSLIST i USING (ID) +## GROUP BY i.user +## ORDER BY SUM_WAIT DESC +## LIMIT 20; +## --enable_result_log # # Total and average wait times for different events for a session @@ -172,7 +172,7 @@ LIMIT 20; SELECT h.EVENT_NAME, SUM(h.TIMER_WAIT) TOTAL_WAIT FROM performance_schema.EVENTS_WAITS_HISTORY_LONG h INNER JOIN performance_schema.THREADS p USING (THREAD_ID) -WHERE p.ID = 1 +WHERE p.PROCESSLIST_ID = 1 GROUP BY h.EVENT_NAME HAVING TOTAL_WAIT > 0; --enable_result_log @@ -181,12 +181,12 @@ HAVING TOTAL_WAIT > 0; # Which user reads and writes data # ---disable_result_log -SELECT i.user, h.operation, SUM(NUMBER_OF_BYTES) bytes -FROM performance_schema.EVENTS_WAITS_HISTORY_LONG h -INNER JOIN performance_schema.THREADS p USING (THREAD_ID) -LEFT JOIN information_schema.PROCESSLIST i USING (ID) -GROUP BY i.user, h.operation -HAVING BYTES > 0 -ORDER BY i.user, h.operation; ---enable_result_log +## --disable_result_log +## SELECT i.user, h.operation, SUM(NUMBER_OF_BYTES) bytes +## FROM performance_schema.EVENTS_WAITS_HISTORY_LONG h +## INNER JOIN performance_schema.THREADS p USING (THREAD_ID) +## LEFT JOIN information_schema.PROCESSLIST i USING (ID) +## GROUP BY i.user, h.operation +## HAVING BYTES > 0 +## ORDER BY i.user, h.operation; +## --enable_result_log diff --git a/mysql-test/suite/perfschema/t/selects.test b/mysql-test/suite/perfschema/t/selects.test index b673c896024..d0249fe654c 100644 --- a/mysql-test/suite/perfschema/t/selects.test +++ b/mysql-test/suite/perfschema/t/selects.test @@ -136,17 +136,17 @@ DROP PROCEDURE IF EXISTS t_ps_proc; --enable_warnings delimiter |; -CREATE PROCEDURE t_ps_proc(IN tid INT, OUT pid INT) +CREATE PROCEDURE t_ps_proc(IN conid INT, OUT pid INT) BEGIN - SELECT id FROM performance_schema.THREADS - WHERE THREAD_ID = tid INTO pid; + SELECT thread_id FROM performance_schema.THREADS + WHERE PROCESSLIST_ID = conid INTO pid; END; | delimiter ;| -CALL t_ps_proc(0, @p_id); +CALL t_ps_proc(connection_id(), @p_id); # FUNCTION @@ -155,17 +155,17 @@ DROP FUNCTION IF EXISTS t_ps_proc; --enable_warnings delimiter |; -CREATE FUNCTION t_ps_func(tid INT) RETURNS int +CREATE FUNCTION t_ps_func(conid INT) RETURNS int BEGIN - return (SELECT id FROM performance_schema.THREADS - WHERE THREAD_ID = tid); + return (SELECT thread_id FROM performance_schema.THREADS + WHERE PROCESSLIST_ID = conid); END; | delimiter ;| -SELECT t_ps_func(0) = @p_id; +SELECT t_ps_func(connection_id()) = @p_id; # We might reach this point too early which means the event scheduler has not # execute our "t_ps_event". Therefore we poll till the record was inserted diff --git a/mysql-test/suite/perfschema/t/thread_cache.test b/mysql-test/suite/perfschema/t/thread_cache.test index 5560f66babb..a59f568e8a2 100644 --- a/mysql-test/suite/perfschema/t/thread_cache.test +++ b/mysql-test/suite/perfschema/t/thread_cache.test @@ -31,14 +31,14 @@ connect (con1, localhost, root, , ); let $con1_ID=`select connection_id()`; let $con1_THREAD_ID=`select thread_id from performance_schema.THREADS - where ID = connection_id()`; + where PROCESSLIST_ID = connection_id()`; connect (con2, localhost, root, , ); let $con2_ID=`select connection_id()`; let $con2_THREAD_ID=`select thread_id from performance_schema.THREADS - where ID = connection_id()`; + where PROCESSLIST_ID = connection_id()`; connection default; @@ -59,7 +59,7 @@ connect (con3, localhost, root, , ); let $con3_ID=`select connection_id()`; let $con3_THREAD_ID=`select thread_id from performance_schema.THREADS - where ID = connection_id()`; + where PROCESSLIST_ID = connection_id()`; disconnect con3; disconnect con1; @@ -83,14 +83,14 @@ connect (con1, localhost, root, , ); let $con1_ID=`select connection_id()`; let $con1_THREAD_ID=`select thread_id from performance_schema.THREADS - where ID = connection_id()`; + where PROCESSLIST_ID = connection_id()`; connect (con2, localhost, root, , ); let $con2_ID=`select connection_id()`; let $con2_THREAD_ID=`select thread_id from performance_schema.THREADS - where ID = connection_id()`; + where PROCESSLIST_ID = connection_id()`; connection default; @@ -109,7 +109,7 @@ connect (con3, localhost, root, , ); let $con3_ID=`select connection_id()`; let $con3_THREAD_ID=`select thread_id from performance_schema.THREADS - where ID = connection_id()`; + where PROCESSLIST_ID = connection_id()`; disconnect con3; disconnect con1; diff --git a/scripts/mysql_system_tables.sql b/scripts/mysql_system_tables.sql index 977907c9c14..d5dd20542ff 100644 --- a/scripts/mysql_system_tables.sql +++ b/scripts/mysql_system_tables.sql @@ -467,8 +467,8 @@ DROP PREPARE stmt; SET @l1="CREATE TABLE performance_schema.THREADS("; SET @l2="THREAD_ID INTEGER not null,"; -SET @l3="ID INTEGER not null,"; -SET @l4="NAME VARCHAR(64) not null"; +SET @l3="PROCESSLIST_ID INTEGER,"; +SET @l4="NAME VARCHAR(128) not null"; SET @l5=")ENGINE=PERFORMANCE_SCHEMA;"; SET @cmd=concat(@l1,@l2,@l3,@l4,@l5); diff --git a/storage/perfschema/table_threads.cc b/storage/perfschema/table_threads.cc index bba7806cab9..d9aa600a21e 100644 --- a/storage/perfschema/table_threads.cc +++ b/storage/perfschema/table_threads.cc @@ -34,13 +34,13 @@ static const TABLE_FIELD_TYPE field_types[]= { NULL, 0} }, { - { C_STRING_WITH_LEN("ID") }, + { C_STRING_WITH_LEN("PROCESSLIST_ID") }, { C_STRING_WITH_LEN("int(11)") }, { NULL, 0} }, { { C_STRING_WITH_LEN("NAME") }, - { C_STRING_WITH_LEN("varchar(64)") }, + { C_STRING_WITH_LEN("varchar(128)") }, { NULL, 0} } }; @@ -140,7 +140,7 @@ void table_threads::make_row(PFS_thread *pfs) } int table_threads::read_row_values(TABLE *table, - unsigned char *, + unsigned char *buf, Field **fields, bool read_all) { @@ -150,7 +150,8 @@ int table_threads::read_row_values(TABLE *table, return HA_ERR_RECORD_DELETED; /* Set the null bits */ - DBUG_ASSERT(table->s->null_bytes == 0); + DBUG_ASSERT(table->s->null_bytes == 1); + buf[0]= 0; for (; (f= *fields) ; fields++) { @@ -161,7 +162,7 @@ int table_threads::read_row_values(TABLE *table, case 0: /* THREAD_ID */ set_field_ulong(f, m_row.m_thread_internal_id); break; - case 1: /* ID */ + case 1: /* PROCESSLIST_ID */ set_field_ulong(f, m_row.m_thread_id); break; case 2: /* NAME */ diff --git a/storage/perfschema/table_threads.h b/storage/perfschema/table_threads.h index 9df323f6d82..fb239007069 100644 --- a/storage/perfschema/table_threads.h +++ b/storage/perfschema/table_threads.h @@ -36,7 +36,7 @@ struct row_threads { /** Column THREAD_ID. */ ulong m_thread_internal_id; - /** Column ID. */ + /** Column PROCESSLIST_ID. */ ulong m_thread_id; /** Column NAME. */ const char *m_name; @@ -79,7 +79,7 @@ private: /** Current row. */ row_threads m_row; - /** True is the current row exists. */ + /** True if the current row exists. */ bool m_row_exists; /** Current position. */ PFS_simple_index m_pos; From e0617fcf58eabaafac13afaeb8466b08cd3c9cc9 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Oct 2010 15:25:14 +0200 Subject: [PATCH 012/304] Raise version number after cloning 5.1.52 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index c1672557bd1..7680a60226a 100644 --- a/configure.in +++ b/configure.in @@ -12,7 +12,7 @@ dnl dnl When changing the major version number please also check the switch dnl statement in mysqlbinlog::check_master_version(). You may also need dnl to update version.c in ndb. -AC_INIT([MySQL Server], [5.1.52], [], [mysql]) +AC_INIT([MySQL Server], [5.1.53], [], [mysql]) AC_CONFIG_SRCDIR([sql/mysqld.cc]) AC_CANONICAL_SYSTEM From 2cc30ff2f169a823a81a0f1565c3b25b7888d980 Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Thu, 7 Oct 2010 18:45:02 +0400 Subject: [PATCH 013/304] Raise version. --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index a5fe8d292da..d58d978fecb 100644 --- a/configure.in +++ b/configure.in @@ -27,7 +27,7 @@ dnl dnl When changing the major version number please also check the switch dnl statement in mysqlbinlog::check_master_version(). You may also need dnl to update version.c in ndb. -AC_INIT([MySQL Server], [5.5.7-rc], [], [mysql]) +AC_INIT([MySQL Server], [5.5.8-rc], [], [mysql]) AC_CONFIG_SRCDIR([sql/mysqld.cc]) AC_CANONICAL_SYSTEM From eaae675279435c06974c166b183cc5bd9232eddc Mon Sep 17 00:00:00 2001 From: Dmitry Lenev Date: Thu, 7 Oct 2010 20:01:17 +0400 Subject: [PATCH 014/304] Fix for bug#57061 "User without privilege on routine can discover its existence". The problem was that user without any privileges on routine was able to find out whether it existed or not. DROP FUNCTION and DROP PROCEDURE statements were checking if routine being dropped existed and reported ER_SP_DOES_NOT_EXIST error/warning before checking if user had enough privileges to drop it. This patch solves this problem by changing code not to check if routine exists before checking if user has enough privileges to drop it. Moreover we no longer perform this check using a separate call instead we rely on sp_drop_routine() returning SP_KEY_NOT_FOUND if routine doesn't exist. This change also simplifies one of upcoming patches refactoring global read lock implementation. mysql-test/r/grant.result: Updated test case after fixing bug#57061 "User without privilege on routine can discover its existence". Removed DROP PROCEDURE/FUNCTION statements which have started to fail after this fix (correctly). There is no need in dropping routines in freshly created database anyway. mysql-test/r/sp-security.result: Added new test case for bug#57061 "User without privilege on routine can discover its existence". Updated existing tests according to new behaviour. mysql-test/suite/funcs_1/r/innodb_storedproc_06.result: Updated test case after fixing bug#57061 "User without privilege on routine can discover its existence". Now we drop routines under user which has enough privileges to do so. mysql-test/suite/funcs_1/r/memory_storedproc_06.result: Updated test case after fixing bug#57061 "User without privilege on routine can discover its existence". Now we drop routines under user which has enough privileges to do so. mysql-test/suite/funcs_1/r/myisam_storedproc_06.result: Updated test case after fixing bug#57061 "User without privilege on routine can discover its existence". Now we drop routines under user which has enough privileges to do so. mysql-test/suite/funcs_1/storedproc/storedproc_06.inc: Updated test case after fixing bug#57061 "User without privilege on routine can discover its existence". Now we drop routines under user which has enough privileges to do so. mysql-test/t/grant.test: Updated test case after fixing bug#57061 "User without privilege on routine can discover its existence". Removed DROP PROCEDURE/FUNCTION statements which have started to fail after this fix (correctly). There is no need in dropping routines in freshly created database anyway. mysql-test/t/sp-security.test: Added new test case for bug#57061 "User without privilege on routine can discover its existence". Updated existing tests according to new behaviour. sql/sp.cc: Removed sp_routine_exists_in_table() which is no longer used. sql/sp.h: Removed sp_routine_exists_in_table() which is no longer used. sql/sql_parse.cc: When dropping routine we no longer check if routine exists before checking if user has enough privileges to do so. Moreover we no longer perform this check using a separate call instead we rely on sp_drop_routine() returning SP_KEY_NOT_FOUND if routine doesn't exist. --- mysql-test/r/grant.result | 2 - mysql-test/r/sp-security.result | 29 ++++++++- .../funcs_1/r/innodb_storedproc_06.result | 4 +- .../funcs_1/r/memory_storedproc_06.result | 4 +- .../funcs_1/r/myisam_storedproc_06.result | 4 +- .../funcs_1/storedproc/storedproc_06.inc | 10 +-- mysql-test/t/grant.test | 5 -- mysql-test/t/sp-security.test | 37 ++++++++++- sql/sp.cc | 32 ---------- sql/sp.h | 3 - sql/sql_parse.cc | 64 ++++++++----------- 11 files changed, 100 insertions(+), 94 deletions(-) diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index 84cac386b57..37074e9a32f 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -1448,8 +1448,6 @@ CREATE USER 'userbug33464'@'localhost'; GRANT CREATE ROUTINE ON dbbug33464.* TO 'userbug33464'@'localhost'; userbug33464@localhost dbbug33464 -DROP PROCEDURE IF EXISTS sp3; -DROP FUNCTION IF EXISTS fn1; CREATE PROCEDURE sp3(v1 char(20)) BEGIN SELECT * from dbbug33464.t6 where t6.f2= 'xyz'; diff --git a/mysql-test/r/sp-security.result b/mysql-test/r/sp-security.result index 4ea26d1021a..c09579b13eb 100644 --- a/mysql-test/r/sp-security.result +++ b/mysql-test/r/sp-security.result @@ -44,7 +44,7 @@ ERROR 42000: SELECT command denied to user 'user1'@'localhost' for table 't1' create procedure db1_secret.dummy() begin end; ERROR 42000: Access denied for user 'user1'@'localhost' to database 'db1_secret' drop procedure db1_secret.dummy; -ERROR 42000: PROCEDURE db1_secret.dummy does not exist +ERROR 42000: alter routine command denied to user 'user1'@'localhost' for routine 'db1_secret.dummy' drop procedure db1_secret.stamp; ERROR 42000: alter routine command denied to user 'user1'@'localhost' for routine 'db1_secret.stamp' drop function db1_secret.db; @@ -58,7 +58,7 @@ ERROR 42000: SELECT command denied to user ''@'localhost' for table 't1' create procedure db1_secret.dummy() begin end; ERROR 42000: Access denied for user ''@'%' to database 'db1_secret' drop procedure db1_secret.dummy; -ERROR 42000: PROCEDURE db1_secret.dummy does not exist +ERROR 42000: alter routine command denied to user ''@'%' for routine 'db1_secret.dummy' drop procedure db1_secret.stamp; ERROR 42000: alter routine command denied to user ''@'%' for routine 'db1_secret.stamp' drop function db1_secret.db; @@ -567,3 +567,28 @@ DROP USER 'tester'; DROP USER 'Tester'; DROP DATABASE B48872; End of 5.0 tests. +# +# Test for bug#57061 "User without privilege on routine can discover +# its existence." +# +drop database if exists mysqltest_db; +create database mysqltest_db; +# Create user with no privileges on mysqltest_db database. +create user bug57061_user@localhost; +create function mysqltest_db.f1() returns int return 0; +create procedure mysqltest_db.p1() begin end; +# Connect as user 'bug57061_user@localhost' +# Attempt to drop routine on which user doesn't have privileges +# should result in the same 'access denied' type of error whether +# routine exists or not. +drop function if exists mysqltest_db.f_does_not_exist; +ERROR 42000: alter routine command denied to user 'bug57061_user'@'localhost' for routine 'mysqltest_db.f_does_not_exist' +drop procedure if exists mysqltest_db.p_does_not_exist; +ERROR 42000: alter routine command denied to user 'bug57061_user'@'localhost' for routine 'mysqltest_db.p_does_not_exist' +drop function if exists mysqltest_db.f1; +ERROR 42000: alter routine command denied to user 'bug57061_user'@'localhost' for routine 'mysqltest_db.f1' +drop procedure if exists mysqltest_db.p1; +ERROR 42000: alter routine command denied to user 'bug57061_user'@'localhost' for routine 'mysqltest_db.p1' +# Connection 'default'. +drop user bug57061_user@localhost; +drop database mysqltest_db; diff --git a/mysql-test/suite/funcs_1/r/innodb_storedproc_06.result b/mysql-test/suite/funcs_1/r/innodb_storedproc_06.result index ee1548fe012..f19030834c8 100644 --- a/mysql-test/suite/funcs_1/r/innodb_storedproc_06.result +++ b/mysql-test/suite/funcs_1/r/innodb_storedproc_06.result @@ -110,10 +110,10 @@ Ensure that root always has the GRANT CREATE ROUTINE privilege. -------------------------------------------------------------------------------- grant create routine on db_storedproc_1.* to 'user_1'@'localhost'; flush privileges; +DROP PROCEDURE IF EXISTS db_storedproc_1.sp3; +DROP FUNCTION IF EXISTS db_storedproc_1.fn1; user_1@localhost db_storedproc_1 -DROP PROCEDURE IF EXISTS sp3; -DROP FUNCTION IF EXISTS fn1; CREATE PROCEDURE sp3(v1 char(20)) BEGIN SELECT * from db_storedproc_1.t6 where t6.f2= 'xyz'; diff --git a/mysql-test/suite/funcs_1/r/memory_storedproc_06.result b/mysql-test/suite/funcs_1/r/memory_storedproc_06.result index 096cbd1261e..0a117c830ee 100644 --- a/mysql-test/suite/funcs_1/r/memory_storedproc_06.result +++ b/mysql-test/suite/funcs_1/r/memory_storedproc_06.result @@ -111,10 +111,10 @@ Ensure that root always has the GRANT CREATE ROUTINE privilege. -------------------------------------------------------------------------------- grant create routine on db_storedproc_1.* to 'user_1'@'localhost'; flush privileges; +DROP PROCEDURE IF EXISTS db_storedproc_1.sp3; +DROP FUNCTION IF EXISTS db_storedproc_1.fn1; user_1@localhost db_storedproc_1 -DROP PROCEDURE IF EXISTS sp3; -DROP FUNCTION IF EXISTS fn1; CREATE PROCEDURE sp3(v1 char(20)) BEGIN SELECT * from db_storedproc_1.t6 where t6.f2= 'xyz'; diff --git a/mysql-test/suite/funcs_1/r/myisam_storedproc_06.result b/mysql-test/suite/funcs_1/r/myisam_storedproc_06.result index 096cbd1261e..0a117c830ee 100644 --- a/mysql-test/suite/funcs_1/r/myisam_storedproc_06.result +++ b/mysql-test/suite/funcs_1/r/myisam_storedproc_06.result @@ -111,10 +111,10 @@ Ensure that root always has the GRANT CREATE ROUTINE privilege. -------------------------------------------------------------------------------- grant create routine on db_storedproc_1.* to 'user_1'@'localhost'; flush privileges; +DROP PROCEDURE IF EXISTS db_storedproc_1.sp3; +DROP FUNCTION IF EXISTS db_storedproc_1.fn1; user_1@localhost db_storedproc_1 -DROP PROCEDURE IF EXISTS sp3; -DROP FUNCTION IF EXISTS fn1; CREATE PROCEDURE sp3(v1 char(20)) BEGIN SELECT * from db_storedproc_1.t6 where t6.f2= 'xyz'; diff --git a/mysql-test/suite/funcs_1/storedproc/storedproc_06.inc b/mysql-test/suite/funcs_1/storedproc/storedproc_06.inc index 4ecca63351d..0695a0724d8 100644 --- a/mysql-test/suite/funcs_1/storedproc/storedproc_06.inc +++ b/mysql-test/suite/funcs_1/storedproc/storedproc_06.inc @@ -117,15 +117,15 @@ create user 'user_1'@'localhost'; grant create routine on db_storedproc_1.* to 'user_1'@'localhost'; flush privileges; +--disable_warnings +DROP PROCEDURE IF EXISTS db_storedproc_1.sp3; +DROP FUNCTION IF EXISTS db_storedproc_1.fn1; +--enable_warnings + # disconnect default; connect (user2, localhost, user_1, , db_storedproc_1); --source suite/funcs_1/include/show_connection.inc ---disable_warnings -DROP PROCEDURE IF EXISTS sp3; -DROP FUNCTION IF EXISTS fn1; ---enable_warnings - delimiter //; CREATE PROCEDURE sp3(v1 char(20)) BEGIN diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index e73f45a6c53..aad0c42a5b3 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -1419,11 +1419,6 @@ GRANT CREATE ROUTINE ON dbbug33464.* TO 'userbug33464'@'localhost'; connect (connbug33464, localhost, userbug33464, , dbbug33464); --source suite/funcs_1/include/show_connection.inc ---disable_warnings -DROP PROCEDURE IF EXISTS sp3; -DROP FUNCTION IF EXISTS fn1; ---enable_warnings - delimiter //; CREATE PROCEDURE sp3(v1 char(20)) BEGIN diff --git a/mysql-test/t/sp-security.test b/mysql-test/t/sp-security.test index 96f82c92248..d7ea829bf50 100644 --- a/mysql-test/t/sp-security.test +++ b/mysql-test/t/sp-security.test @@ -82,7 +82,7 @@ select * from db1_secret.t1; # ...and not this --error ER_DBACCESS_DENIED_ERROR create procedure db1_secret.dummy() begin end; ---error ER_SP_DOES_NOT_EXIST +--error ER_PROCACCESS_DENIED_ERROR drop procedure db1_secret.dummy; --error ER_PROCACCESS_DENIED_ERROR drop procedure db1_secret.stamp; @@ -106,7 +106,7 @@ select * from db1_secret.t1; # ...and not this --error ER_DBACCESS_DENIED_ERROR create procedure db1_secret.dummy() begin end; ---error ER_SP_DOES_NOT_EXIST +--error ER_PROCACCESS_DENIED_ERROR drop procedure db1_secret.dummy; --error ER_PROCACCESS_DENIED_ERROR drop procedure db1_secret.stamp; @@ -926,6 +926,39 @@ DROP DATABASE B48872; --echo End of 5.0 tests. + +--echo # +--echo # Test for bug#57061 "User without privilege on routine can discover +--echo # its existence." +--echo # +--disable_warnings +drop database if exists mysqltest_db; +--enable_warnings +create database mysqltest_db; +--echo # Create user with no privileges on mysqltest_db database. +create user bug57061_user@localhost; +create function mysqltest_db.f1() returns int return 0; +create procedure mysqltest_db.p1() begin end; +--echo # Connect as user 'bug57061_user@localhost' +connect (conn1, localhost, bug57061_user,,); +--echo # Attempt to drop routine on which user doesn't have privileges +--echo # should result in the same 'access denied' type of error whether +--echo # routine exists or not. +--error ER_PROCACCESS_DENIED_ERROR +drop function if exists mysqltest_db.f_does_not_exist; +--error ER_PROCACCESS_DENIED_ERROR +drop procedure if exists mysqltest_db.p_does_not_exist; +--error ER_PROCACCESS_DENIED_ERROR +drop function if exists mysqltest_db.f1; +--error ER_PROCACCESS_DENIED_ERROR +drop procedure if exists mysqltest_db.p1; +--echo # Connection 'default'. +connection default; +disconnect conn1; +drop user bug57061_user@localhost; +drop database mysqltest_db; + + # Wait till all disconnects are completed --source include/wait_until_count_sessions.inc diff --git a/sql/sp.cc b/sql/sp.cc index 8821dc9365d..87eb40c29ac 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -1636,38 +1636,6 @@ sp_exist_routines(THD *thd, TABLE_LIST *routines, bool any) } -/** - Check if a routine exists in the mysql.proc table, without actually - parsing the definition. (Used for dropping). - - @param thd thread context - @param name name of procedure - - @retval - 0 Success - @retval - non-0 Error; SP_OPEN_TABLE_FAILED or SP_KEY_NOT_FOUND -*/ - -int -sp_routine_exists_in_table(THD *thd, int type, sp_name *name) -{ - TABLE *table; - int ret; - Open_tables_backup open_tables_state_backup; - - if (!(table= open_proc_table_for_read(thd, &open_tables_state_backup))) - ret= SP_OPEN_TABLE_FAILED; - else - { - if ((ret= db_find_routine_aux(thd, type, name, table)) != SP_OK) - ret= SP_KEY_NOT_FOUND; - close_system_tables(thd, &open_tables_state_backup); - } - return ret; -} - - extern "C" uchar* sp_sroutine_key(const uchar *ptr, size_t *plen, my_bool first) { diff --git a/sql/sp.h b/sql/sp.h index 10e70261b86..5d0490586a1 100644 --- a/sql/sp.h +++ b/sql/sp.h @@ -100,9 +100,6 @@ sp_cache_routine(THD *thd, int type, sp_name *name, bool sp_exist_routines(THD *thd, TABLE_LIST *procs, bool any); -int -sp_routine_exists_in_table(THD *thd, int type, sp_name *name); - bool sp_show_create_routine(THD *thd, int type, sp_name *name); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 2f8a72ee25c..0f3338cb6a6 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4023,49 +4023,39 @@ create_sp_error: int sp_result; int type= (lex->sql_command == SQLCOM_DROP_PROCEDURE ? TYPE_ENUM_PROCEDURE : TYPE_ENUM_FUNCTION); + char *db= lex->spname->m_db.str; + char *name= lex->spname->m_name.str; - /* - @todo: here we break the metadata locking protocol by - looking up the information about the routine without - a metadata lock. Rewrite this piece to make sp_drop_routine - return whether the routine existed or not. - */ - sp_result= sp_routine_exists_in_table(thd, type, lex->spname); - thd->warning_info->opt_clear_warning_info(thd->query_id); - if (sp_result == SP_OK) - { - char *db= lex->spname->m_db.str; - char *name= lex->spname->m_name.str; + if (check_routine_access(thd, ALTER_PROC_ACL, db, name, + lex->sql_command == SQLCOM_DROP_PROCEDURE, 0)) + goto error; - if (check_routine_access(thd, ALTER_PROC_ACL, db, name, - lex->sql_command == SQLCOM_DROP_PROCEDURE, 0)) - goto error; - - /* Conditionally writes to binlog */ - sp_result= sp_drop_routine(thd, type, lex->spname); + /* Conditionally writes to binlog */ + sp_result= sp_drop_routine(thd, type, lex->spname); #ifndef NO_EMBEDDED_ACCESS_CHECKS - /* - We're going to issue an implicit REVOKE statement. - It takes metadata locks and updates system tables. - Make sure that sp_create_routine() did not leave any - locks in the MDL context, so there is no risk to - deadlock. - */ - close_mysql_tables(thd); + /* + We're going to issue an implicit REVOKE statement. + It takes metadata locks and updates system tables. + Make sure that sp_create_routine() did not leave any + locks in the MDL context, so there is no risk to + deadlock. + */ + close_mysql_tables(thd); - if (sp_automatic_privileges && !opt_noacl && - sp_revoke_privileges(thd, db, name, - lex->sql_command == SQLCOM_DROP_PROCEDURE)) - { - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_PROC_AUTO_REVOKE_FAIL, - ER(ER_PROC_AUTO_REVOKE_FAIL)); - /* If this happens, an error should have been reported. */ - goto error; - } -#endif + if (sp_result != SP_KEY_NOT_FOUND && + sp_automatic_privileges && !opt_noacl && + sp_revoke_privileges(thd, db, name, + lex->sql_command == SQLCOM_DROP_PROCEDURE)) + { + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_PROC_AUTO_REVOKE_FAIL, + ER(ER_PROC_AUTO_REVOKE_FAIL)); + /* If this happens, an error should have been reported. */ + goto error; } +#endif + res= sp_result; switch (sp_result) { case SP_OK: From df29195345758a35a2968e85f03cc1e2a0870d76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 11 Oct 2010 11:01:47 +0300 Subject: [PATCH 015/304] Bug #56947 InnoDB leaks memory when failing to create a table No mysql-test case. Tested by creating a table, removing a *.frm file and attempting to create the table again. Code coverage tested by instrumentation. Tested with Valgrind. --- storage/innobase/row/row0mysql.c | 1 + 1 file changed, 1 insertion(+) diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index c5a3a2da9e2..645260bce0f 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -1981,6 +1981,7 @@ row_create_table_for_mysql( table already exists */ trx->error_state = DB_SUCCESS; + dict_mem_table_free(table); } que_graph_free((que_t*) que_node_get_parent(thr)); From a8da1a3a581a3572edf165ffe1076b0194195a18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 11 Oct 2010 11:18:00 +0300 Subject: [PATCH 016/304] Bug #56947 InnoDB leaks memory when failing to create a table row_create_table_for_mysql(): When the table creation fails, free the dict_table_t object. --- .../suite/innodb_plugin/r/innodb_bug56947.result | 6 ++++++ .../suite/innodb_plugin/t/innodb_bug56947.test | 11 +++++++++++ storage/innodb_plugin/ChangeLog | 13 ++++++++++--- storage/innodb_plugin/row/row0mysql.c | 14 ++++++++------ 4 files changed, 35 insertions(+), 9 deletions(-) create mode 100644 mysql-test/suite/innodb_plugin/r/innodb_bug56947.result create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_bug56947.test diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug56947.result b/mysql-test/suite/innodb_plugin/r/innodb_bug56947.result new file mode 100644 index 00000000000..42101a46a5b --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_bug56947.result @@ -0,0 +1,6 @@ +create table bug56947(a int not null) engine = innodb; +CREATE TABLE `bug56947#1`(a int) ENGINE=InnoDB; +alter table bug56947 add unique index (a); +ERROR HY000: Table 'test.bug56947#1' already exists +drop table `bug56947#1`; +drop table bug56947; diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug56947.test b/mysql-test/suite/innodb_plugin/t/innodb_bug56947.test new file mode 100644 index 00000000000..88544387567 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug56947.test @@ -0,0 +1,11 @@ +# +# Bug #56947 valgrind reports a memory leak in innodb-plugin.innodb-index +# +-- source include/have_innodb_plugin.inc + +create table bug56947(a int not null) engine = innodb; +CREATE TABLE `bug56947#1`(a int) ENGINE=InnoDB; +--error 156 +alter table bug56947 add unique index (a); +drop table `bug56947#1`; +drop table bug56947; diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 342e3e32bc1..ca7900549c2 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,13 +1,21 @@ +2010-10-11 The InnoDB Team + + * row/row0mysql.c, innodb_bug56947.result, innodb_bug56947.test: + Fix Bug #56947 InnoDB leaks memory when failing to create a table + 2010-10-06 The InnoDB Team + * row/row0mysql.c, innodb_bug57255.result, innodb_bug57255.test - Fix Bug #Cascade Delete results in "Got error -1 from storage engine" - + Fix Bug #57255 Cascade Delete results in "Got error -1 from + storage engine" + 2010-09-27 The InnoDB Team * row/row0sel.c, innodb_bug56716.result, innodb_bug56716.test: Fix Bug #56716 InnoDB locks a record gap without locking the table 2010-09-06 The InnoDB Team + * dict/dict0load.c, innodb_bug53756.test innodb_bug53756.result Fix Bug #53756 ALTER TABLE ADD PRIMARY KEY affects crash recovery @@ -40,7 +48,6 @@ * handler/ha_innodb.cc Fix Bug #55382 Assignment with SELECT expressions takes unexpected S locks in READ COMMITTED ->>>>>>> MERGE-SOURCE 2010-07-27 The InnoDB Team diff --git a/storage/innodb_plugin/row/row0mysql.c b/storage/innodb_plugin/row/row0mysql.c index 9cabea507fb..f27afc253ff 100644 --- a/storage/innodb_plugin/row/row0mysql.c +++ b/storage/innodb_plugin/row/row0mysql.c @@ -1879,15 +1879,13 @@ err_exit: err = trx->error_state; - if (UNIV_UNLIKELY(err != DB_SUCCESS)) { + switch (err) { + case DB_SUCCESS: + break; + case DB_OUT_OF_FILE_SPACE: trx->error_state = DB_SUCCESS; trx_general_rollback_for_mysql(trx, NULL); - /* TO DO: free table? The code below will dereference - table->name, though. */ - } - switch (err) { - case DB_OUT_OF_FILE_SPACE: ut_print_timestamp(stderr); fputs(" InnoDB: Warning: cannot create table ", stderr); @@ -1902,9 +1900,13 @@ err_exit: break; case DB_DUPLICATE_KEY: + default: /* We may also get err == DB_ERROR if the .ibd file for the table already exists */ + trx->error_state = DB_SUCCESS; + trx_general_rollback_for_mysql(trx, NULL); + dict_mem_table_free(table); break; } From 734a7327686c16a8f8b4063aef7d0e8bdc638e89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 11 Oct 2010 11:59:43 +0300 Subject: [PATCH 017/304] Bug #56947 InnoDB leaks memory when failing to create a table row_create_table_for_mysql(): When the table creation fails, free the dict_table_t object. --- mysql-test/suite/innodb/r/innodb_bug56947.result | 8 ++++++++ mysql-test/suite/innodb/t/innodb_bug56947.test | 16 ++++++++++++++++ storage/innobase/row/row0mysql.c | 14 ++++++++------ 3 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 mysql-test/suite/innodb/r/innodb_bug56947.result create mode 100644 mysql-test/suite/innodb/t/innodb_bug56947.test diff --git a/mysql-test/suite/innodb/r/innodb_bug56947.result b/mysql-test/suite/innodb/r/innodb_bug56947.result new file mode 100644 index 00000000000..b279069d834 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug56947.result @@ -0,0 +1,8 @@ +SET @old_innodb_file_per_table=@@innodb_file_per_table; +SET GLOBAL innodb_file_per_table=0; +create table bug56947(a int not null) engine = innodb; +CREATE TABLE `bug56947#1`(a int) ENGINE=InnoDB; +alter table bug56947 add unique index (a); +ERROR HY000: Table 'test.bug56947#1' already exists +drop table `bug56947#1`; +drop table bug56947; diff --git a/mysql-test/suite/innodb/t/innodb_bug56947.test b/mysql-test/suite/innodb/t/innodb_bug56947.test new file mode 100644 index 00000000000..e11f39b97a8 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug56947.test @@ -0,0 +1,16 @@ +# +# Bug #56947 valgrind reports a memory leak in innodb-plugin.innodb-index +# +-- source include/have_innodb.inc + +SET @old_innodb_file_per_table=@@innodb_file_per_table; +# avoid a message about filed *.ibd file creation in the error log +SET GLOBAL innodb_file_per_table=0; +create table bug56947(a int not null) engine = innodb; +CREATE TABLE `bug56947#1`(a int) ENGINE=InnoDB; +--error 156 +alter table bug56947 add unique index (a); +drop table `bug56947#1`; +drop table bug56947; +--disable_query_log +SET GLOBAL innodb_file_per_table=@old_innodb_file_per_table; diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index 3e155fd14e6..20885f4098c 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -1938,15 +1938,13 @@ err_exit: err = trx->error_state; - if (UNIV_UNLIKELY(err != DB_SUCCESS)) { + switch (err) { + case DB_SUCCESS: + break; + case DB_OUT_OF_FILE_SPACE: trx->error_state = DB_SUCCESS; trx_general_rollback_for_mysql(trx, NULL); - /* TO DO: free table? The code below will dereference - table->name, though. */ - } - switch (err) { - case DB_OUT_OF_FILE_SPACE: ut_print_timestamp(stderr); fputs(" InnoDB: Warning: cannot create table ", stderr); @@ -1961,9 +1959,13 @@ err_exit: break; case DB_DUPLICATE_KEY: + default: /* We may also get err == DB_ERROR if the .ibd file for the table already exists */ + trx->error_state = DB_SUCCESS; + trx_general_rollback_for_mysql(trx, NULL); + dict_mem_table_free(table); break; } From 498ee6bd19eabc85dcbd9abebc9cf6aeb79d1985 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 11 Oct 2010 22:13:47 +0200 Subject: [PATCH 018/304] Fix bug #57345 --- storage/innobase/row/row0sel.c | 14 +++++++++++++- storage/innodb_plugin/ChangeLog | 6 +++++- storage/innodb_plugin/row/row0sel.c | 14 +++++++++++++- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c index a64dd3151ee..ecb2c492706 100644 --- a/storage/innobase/row/row0sel.c +++ b/storage/innobase/row/row0sel.c @@ -3259,6 +3259,7 @@ row_search_for_mysql( mem_heap_t* heap = NULL; ulint offsets_[REC_OFFS_NORMAL_SIZE]; ulint* offsets = offsets_; + ibool table_lock_waited = FALSE; *offsets_ = (sizeof offsets_) / sizeof *offsets_; @@ -3622,13 +3623,15 @@ shortcut_fails_too_big_rec: trx_assign_read_view(trx); prebuilt->sql_stat_start = FALSE; } else { +wait_table_again: err = lock_table(0, index->table, prebuilt->select_lock_type == LOCK_S ? LOCK_IS : LOCK_IX, thr); if (err != DB_SUCCESS) { - goto lock_wait_or_error; + table_lock_waited = TRUE; + goto lock_table_wait; } prebuilt->sql_stat_start = FALSE; } @@ -4408,6 +4411,7 @@ lock_wait_or_error: btr_pcur_store_position(pcur, &mtr); +lock_table_wait: mtr_commit(&mtr); mtr_has_extra_clust_latch = FALSE; @@ -4425,6 +4429,14 @@ lock_wait_or_error: thr->lock_state = QUE_THR_LOCK_NOLOCK; mtr_start(&mtr); + /* Table lock waited, go try to obtain table lock + again */ + if (table_lock_waited) { + table_lock_waited = FALSE; + + goto wait_table_again; + } + sel_restore_position_for_mysql(&same_user_rec, BTR_SEARCH_LEAF, pcur, moves_up, &mtr); diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 342e3e32bc1..c185215e65f 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,8 @@ +2010-10-11 The InnoDB Team + * row/row0sel.c + Fix Bug #57345 btr_pcur_store_position abort for load with + concurrent lock/unlock tables + 2010-10-06 The InnoDB Team * row/row0mysql.c, innodb_bug57255.result, innodb_bug57255.test Fix Bug #Cascade Delete results in "Got error -1 from storage engine" @@ -40,7 +45,6 @@ * handler/ha_innodb.cc Fix Bug #55382 Assignment with SELECT expressions takes unexpected S locks in READ COMMITTED ->>>>>>> MERGE-SOURCE 2010-07-27 The InnoDB Team diff --git a/storage/innodb_plugin/row/row0sel.c b/storage/innodb_plugin/row/row0sel.c index 8b17bdc6ad3..cc7a7a6fe9b 100644 --- a/storage/innodb_plugin/row/row0sel.c +++ b/storage/innodb_plugin/row/row0sel.c @@ -3356,6 +3356,7 @@ row_search_for_mysql( mem_heap_t* heap = NULL; ulint offsets_[REC_OFFS_NORMAL_SIZE]; ulint* offsets = offsets_; + ibool table_lock_waited = FALSE; rec_offs_init(offsets_); @@ -3742,13 +3743,15 @@ release_search_latch_if_needed: trx_assign_read_view(trx); prebuilt->sql_stat_start = FALSE; } else { +wait_table_again: err = lock_table(0, index->table, prebuilt->select_lock_type == LOCK_S ? LOCK_IS : LOCK_IX, thr); if (err != DB_SUCCESS) { - goto lock_wait_or_error; + table_lock_waited = TRUE; + goto lock_table_wait; } prebuilt->sql_stat_start = FALSE; } @@ -4559,6 +4562,7 @@ lock_wait_or_error: btr_pcur_store_position(pcur, &mtr); +lock_table_wait: mtr_commit(&mtr); mtr_has_extra_clust_latch = FALSE; @@ -4576,6 +4580,14 @@ lock_wait_or_error: thr->lock_state = QUE_THR_LOCK_NOLOCK; mtr_start(&mtr); + /* Table lock waited, go try to obtain table lock + again */ + if (table_lock_waited) { + table_lock_waited = FALSE; + + goto wait_table_again; + } + sel_restore_position_for_mysql(&same_user_rec, BTR_SEARCH_LEAF, pcur, moves_up, &mtr); From 0bf40b3e4c3181a0f576155baedb31696d4c6afb Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Tue, 12 Oct 2010 13:13:23 +0200 Subject: [PATCH 019/304] Bug #40406 Please make mtr print better messages when servers fail to start Added some more details to warning messages, this should be enough. --- mysql-test/lib/mtr_process.pl | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl index a42627c93cd..26a95fa13ab 100644 --- a/mysql-test/lib/mtr_process.pl +++ b/mysql-test/lib/mtr_process.pl @@ -116,18 +116,20 @@ sub sleep_until_file_created ($$$) { return 1; } + my $seconds= ($loop * $sleeptime) / 1000; + # Check if it died after the fork() was successful if ( defined $proc and ! $proc->wait_one(0) ) { - mtr_warning("Process $proc died"); + mtr_warning("Process $proc died after mysql-test-run waited $seconds " . + "seconds for $pidfile to be created."); return 0; } mtr_debug("Sleep $sleeptime milliseconds waiting for $pidfile"); # Print extra message every 60 seconds - my $seconds= ($loop * $sleeptime) / 1000; - if ( $seconds > 1 and int($seconds * 10) % 600 == 0 ) + if ( $seconds > 1 && int($seconds * 10) % 600 == 0 && $seconds < $timeout ) { my $left= $timeout - $seconds; mtr_warning("Waited $seconds seconds for $pidfile to be created, " . @@ -138,6 +140,8 @@ sub sleep_until_file_created ($$$) { } + mtr_warning("Timeout after mysql-test-run waited $timeout seconds " . + "for the process $proc to create a pid file."); return 0; } From cfcafcf5c4d89a7e947ea570ebaef91fdbbfc838 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 12 Oct 2010 12:07:09 -0500 Subject: [PATCH 020/304] Bug#56632 - The warning code related to KEY_BLOCK_SIZE and ROW_FORMAT when innodb_strict_mode=OFF is improved in order to take into account whether the KEY_BLOCK_SIZE is specified on the current ALTER statement or the previous CREATE statement. The testcase shows the expected results of 12 different combinations of these settings. --- .../suite/innodb/r/innodb_bug56632.result | 294 ++++++++++++++++++ .../suite/innodb/t/innodb_bug56632.test | 216 +++++++++++++ storage/innobase/handler/ha_innodb.cc | 17 +- 3 files changed, 519 insertions(+), 8 deletions(-) create mode 100644 mysql-test/suite/innodb/r/innodb_bug56632.result create mode 100644 mysql-test/suite/innodb/t/innodb_bug56632.test diff --git a/mysql-test/suite/innodb/r/innodb_bug56632.result b/mysql-test/suite/innodb/r/innodb_bug56632.result new file mode 100644 index 00000000000..8236b37676b --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug56632.result @@ -0,0 +1,294 @@ +SET storage_engine=InnoDB; +SET GLOBAL innodb_file_format=`Barracuda`; +SET GLOBAL innodb_file_per_table=ON; +SET SESSION innodb_strict_mode = ON; +# Test 1) CREATE with ROW_FORMAT & KEY_BLOCK_SIZE, ALTER with neither +DROP TABLE IF EXISTS bug56632; +Warnings: +Note 1051 Unknown table 'bug56632' +CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +ERROR HY000: Can't create table 'test.bug56632' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. +Error 1005 Can't create table 'test.bug56632' (errno: 1478) +# Test 2) CREATE with ROW_FORMAT, ALTER with KEY_BLOCK_SIZE +DROP TABLE IF EXISTS bug56632; +Warnings: +Note 1051 Unknown table 'bug56632' +CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact row_format=COMPACT +ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compressed row_format=COMPACT KEY_BLOCK_SIZE=1 +# Test 3) CREATE with KEY_BLOCK_SIZE, ALTER with ROW_FORMAT +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compressed KEY_BLOCK_SIZE=1 +ALTER TABLE bug56632 ROW_FORMAT=COMPACT; +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compressed KEY_BLOCK_SIZE=1 +# Test 4) CREATE with neither, ALTER with ROW_FORMAT & KEY_BLOCK_SIZE +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ); +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact +ALTER TABLE bug56632 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact +# Test 5) CREATE with KEY_BLOCK_SIZE=3 (invalid). +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; +ERROR HY000: Can't create table 'test.bug56632' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 3. Valid values are [1, 2, 4, 8, 16] +Error 1005 Can't create table 'test.bug56632' (errno: 1478) +SET SESSION innodb_strict_mode = OFF; +# Test 6) CREATE with ROW_FORMAT & KEY_BLOCK_SIZE, ALTER with neither +DROP TABLE IF EXISTS bug56632; +Warnings: +Note 1051 Unknown table 'bug56632' +CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact row_format=COMPACT KEY_BLOCK_SIZE=1 +ALTER TABLE bug56632 ADD COLUMN f1 INT; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL, + `f1` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact row_format=COMPACT KEY_BLOCK_SIZE=1 +# Test 7) CREATE with ROW_FORMAT, ALTER with KEY_BLOCK_SIZE +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact row_format=COMPACT +ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compressed row_format=COMPACT KEY_BLOCK_SIZE=1 +# Test 8) CREATE with KEY_BLOCK_SIZE, ALTER with ROW_FORMAT +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compressed KEY_BLOCK_SIZE=1 +ALTER TABLE bug56632 ROW_FORMAT=COMPACT; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact row_format=COMPACT KEY_BLOCK_SIZE=1 +# Test 9) CREATE with neither, ALTER with ROW_FORMAT & KEY_BLOCK_SIZE +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ); +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact +ALTER TABLE bug56632 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact row_format=COMPACT KEY_BLOCK_SIZE=1 +# Test 10) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with neither. +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=3 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact KEY_BLOCK_SIZE=3 +ALTER TABLE bug56632 ADD COLUMN f1 INT; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL, + `f1` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=3 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact KEY_BLOCK_SIZE=3 +# Test 11) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with ROW_FORMAT=COMPACT. +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=3 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact KEY_BLOCK_SIZE=3 +ALTER TABLE bug56632 ROW_FORMAT=COMPACT; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=3 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact row_format=COMPACT KEY_BLOCK_SIZE=3 +# Test 12) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with KEY_BLOCK_SIZE=1. +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=3 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact KEY_BLOCK_SIZE=3 +ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compressed KEY_BLOCK_SIZE=1 +# Cleanup +DROP TABLE IF EXISTS bug56632; diff --git a/mysql-test/suite/innodb/t/innodb_bug56632.test b/mysql-test/suite/innodb/t/innodb_bug56632.test new file mode 100644 index 00000000000..60703814da2 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug56632.test @@ -0,0 +1,216 @@ +# +# Bug#56632: ALTER TABLE implicitly changes ROW_FORMAT to COMPRESSED +# http://bugs.mysql.com/56632 +# +# Innodb automatically uses compressed mode when the KEY_BLOCK_SIZE +# parameter is used, except if the ROW_FORMAT is also specified, in +# which case the KEY_BLOCK_SIZE is ignored and a warning is shown. +# But Innodb was getting confused when neither of those parameters +# was used on the ALTER statement after they were both used on the +# CREATE. +# +# This will test the results of all 4 combinations of these two +# parameters of the CREATE and ALTER. +# +# Tests 1-5 use INNODB_STRICT_MODE=1 which returns an error +# if there is anything wrong with the statement. +# +# 1) CREATE with ROW_FORMAT=COMPACT & KEY_BLOCK_SIZE=1, ALTER with neither. +# Result; CREATE; fails with error ER_CANT_CREATE_TABLE +# 2) CREATE with ROW_FORMAT=COMPACT, ALTER with KEY_BLOCK_SIZE=1 +# Result; CREATE succeeds, +# ALTER quietly converts ROW_FORMAT to compressed. +# 3) CREATE with KEY_BLOCK_SIZE=1, ALTER with ROW_FORMAT=COMPACT +# Result; CREATE quietly converts ROW_FORMAT to compressed, +# ALTER fails with error ER_CANT_CREATE_TABLE. +# 4) CREATE with neither, ALTER with ROW_FORMAT=COMPACT & KEY_BLOCK_SIZE=1 +# Result; CREATE succeeds, +# ALTER; fails with error ER_CANT_CREATE_TABLE +# 5) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with neither. +# Result; CREATE; fails with error ER_CANT_CREATE_TABLE +# +# Tests 6-11 use INNODB_STRICT_MODE=0 which automatically makes +# adjustments if the prameters are incompatible. +# +# 6) CREATE with ROW_FORMAT=COMPACT & KEY_BLOCK_SIZE=1, ALTER with neither. +# Result; CREATE succeeds, warns that KEY_BLOCK_SIZE is ignored. +# ALTER succeeds, no warnings. +# 7) CREATE with ROW_FORMAT=COMPACT, ALTER with KEY_BLOCK_SIZE=1 +# Result; CREATE succeeds, +# ALTER quietly converts ROW_FORMAT to compressed. +# 8) CREATE with KEY_BLOCK_SIZE=1, ALTER with ROW_FORMAT=COMPACT +# Result; CREATE quietly converts ROW_FORMAT to compressed, +# ALTER succeeds, warns that KEY_BLOCK_SIZE is ignored. +# 9) CREATE with neither, ALTER with ROW_FORMAT=COMPACT & KEY_BLOCK_SIZE=1 +# Result; CREATE succeeds, +# ALTER succeeds, warns that KEY_BLOCK_SIZE is ignored. +# 10) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with neither. +# Result; CREATE succeeds, warns that KEY_BLOCK_SIZE=3 is ignored. +# ALTER succeeds, warns that KEY_BLOCK_SIZE=3 is ignored. +# 11) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with ROW_FORMAT=COMPACT. +# Result; CREATE succeeds, warns that KEY_BLOCK_SIZE=3 is ignored. +# ALTER succeeds, warns that KEY_BLOCK_SIZE=3 is ignored. +# 12) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with KEY_BLOCK_SIZE=1. +# Result; CREATE succeeds, warns that KEY_BLOCK_SIZE=3 is ignored. +# ALTER succeeds, quietly converts ROW_FORMAT to compressed. + +-- source include/have_innodb.inc + +SET storage_engine=InnoDB; + +--disable_query_log +# These values can change during the test +LET $innodb_file_format_orig=`select @@innodb_file_format`; +LET $innodb_file_format_max_orig=`select @@innodb_file_format_max`; +LET $innodb_file_per_table_orig=`select @@innodb_file_per_table`; +LET $innodb_strict_mode_orig=`select @@session.innodb_strict_mode`; +--enable_query_log + +SET GLOBAL innodb_file_format=`Barracuda`; +SET GLOBAL innodb_file_per_table=ON; + +# Innodb strict mode will cause an error on the CREATE or ALTER when; +# 1. both ROW_FORMAT=COMPACT and KEY_BLOCK_SIZE=1, +# 2. KEY_BLOCK_SIZE is not a valid number (0,1,2,4,8,16). +# With innodb_strict_mode = OFF, These errors are corrected +# and just a warning is returned. +SET SESSION innodb_strict_mode = ON; + +--echo # Test 1) CREATE with ROW_FORMAT & KEY_BLOCK_SIZE, ALTER with neither +DROP TABLE IF EXISTS bug56632; +--error ER_CANT_CREATE_TABLE +CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +SHOW WARNINGS; + +--echo # Test 2) CREATE with ROW_FORMAT, ALTER with KEY_BLOCK_SIZE +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 3) CREATE with KEY_BLOCK_SIZE, ALTER with ROW_FORMAT +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +--disable_result_log +--error ER_CANT_CREATE_TABLE +ALTER TABLE bug56632 ROW_FORMAT=COMPACT; +--enable_result_log +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 4) CREATE with neither, ALTER with ROW_FORMAT & KEY_BLOCK_SIZE +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ); +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +--disable_result_log +--error ER_CANT_CREATE_TABLE +ALTER TABLE bug56632 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +--enable_result_log +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 5) CREATE with KEY_BLOCK_SIZE=3 (invalid). +DROP TABLE IF EXISTS bug56632; +--error ER_CANT_CREATE_TABLE +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; +SHOW WARNINGS; + +SET SESSION innodb_strict_mode = OFF; + +--echo # Test 6) CREATE with ROW_FORMAT & KEY_BLOCK_SIZE, ALTER with neither +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +ALTER TABLE bug56632 ADD COLUMN f1 INT; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 7) CREATE with ROW_FORMAT, ALTER with KEY_BLOCK_SIZE +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 8) CREATE with KEY_BLOCK_SIZE, ALTER with ROW_FORMAT +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +ALTER TABLE bug56632 ROW_FORMAT=COMPACT; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 9) CREATE with neither, ALTER with ROW_FORMAT & KEY_BLOCK_SIZE +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ); +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +ALTER TABLE bug56632 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 10) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with neither. +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +ALTER TABLE bug56632 ADD COLUMN f1 INT; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 11) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with ROW_FORMAT=COMPACT. +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +ALTER TABLE bug56632 ROW_FORMAT=COMPACT; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 12) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with KEY_BLOCK_SIZE=1. +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Cleanup +DROP TABLE IF EXISTS bug56632; + +--disable_query_log +EVAL SET GLOBAL innodb_file_per_table=$innodb_file_per_table_orig; +EVAL SET GLOBAL innodb_file_format_max=$innodb_file_format_max_orig; +EVAL SET GLOBAL innodb_file_format=$innodb_file_format_orig; +EVAL SET SESSION innodb_strict_mode=$innodb_strict_mode_orig; +--enable_query_log + diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 567cbca868e..21afe2d0bee 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -6556,8 +6556,8 @@ create_options_are_valid( ? "COMPRESSED" : "DYNAMIC"; - /* These two ROW_FORMATs require - srv_file_per_table and srv_file_format */ + /* These two ROW_FORMATs require srv_file_per_table + and srv_file_format > Antelope */ if (!srv_file_per_table) { push_warning_printf( thd, @@ -6567,7 +6567,6 @@ create_options_are_valid( " requires innodb_file_per_table.", row_format_name); ret = FALSE; - } if (srv_file_format < DICT_TF_FORMAT_ZIP) { @@ -6766,6 +6765,8 @@ ha_innobase::create( ulint ssize, ksize; ulint key_block_size = create_info->key_block_size; + /* Set 'flags' to the correct key_block_size. + It will be zero if key_block_size is an invalid number.*/ for (ssize = ksize = 1; ssize <= DICT_TF_ZSSIZE_MAX; ssize++, ksize <<= 1) { if (key_block_size == ksize) { @@ -6806,10 +6807,10 @@ ha_innobase::create( row_type = form->s->row_type; if (flags) { - /* KEY_BLOCK_SIZE was specified. */ - if (!(create_info->used_fields & HA_CREATE_USED_ROW_FORMAT)) { - /* ROW_FORMAT was not specified; - default to ROW_FORMAT=COMPRESSED */ + /* if KEY_BLOCK_SIZE was specified on this statement and + ROW_FORMAT was not, automatically change ROW_FORMAT to COMPRESSED.*/ + if ( (create_info->used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE) + && !(create_info->used_fields & HA_CREATE_USED_ROW_FORMAT)) { row_type = ROW_TYPE_COMPRESSED; } else if (row_type != ROW_TYPE_COMPRESSED) { /* ROW_FORMAT other than COMPRESSED @@ -6828,7 +6829,7 @@ ha_innobase::create( flags = 0; } } else { - /* No KEY_BLOCK_SIZE */ + /* flags == 0 means no KEY_BLOCK_SIZE.*/ if (row_type == ROW_TYPE_COMPRESSED) { /* ROW_FORMAT=COMPRESSED without KEY_BLOCK_SIZE implies half the From 891bbf224a41e8f97b4c40ddb671da69536af12f Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 12 Oct 2010 12:59:33 -0500 Subject: [PATCH 021/304] Bug#56632 - The warning code related to KEY_BLOCK_SIZE and ROW_FORMAT when innodb_strict_mode=OFF is improved in order to take into account whether the KEY_BLOCK_SIZE is specified on the current ALTER statement or the previous CREATE statement. The testcase shows the expected results of 12 different combinations of these settings. --- .../innodb_plugin/r/innodb_bug56632.result | 294 ++++++++++++++++++ .../innodb_plugin/t/innodb_bug56632.test | 216 +++++++++++++ storage/innodb_plugin/handler/ha_innodb.cc | 17 +- 3 files changed, 519 insertions(+), 8 deletions(-) create mode 100755 mysql-test/suite/innodb_plugin/r/innodb_bug56632.result create mode 100755 mysql-test/suite/innodb_plugin/t/innodb_bug56632.test diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug56632.result b/mysql-test/suite/innodb_plugin/r/innodb_bug56632.result new file mode 100755 index 00000000000..8236b37676b --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_bug56632.result @@ -0,0 +1,294 @@ +SET storage_engine=InnoDB; +SET GLOBAL innodb_file_format=`Barracuda`; +SET GLOBAL innodb_file_per_table=ON; +SET SESSION innodb_strict_mode = ON; +# Test 1) CREATE with ROW_FORMAT & KEY_BLOCK_SIZE, ALTER with neither +DROP TABLE IF EXISTS bug56632; +Warnings: +Note 1051 Unknown table 'bug56632' +CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +ERROR HY000: Can't create table 'test.bug56632' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. +Error 1005 Can't create table 'test.bug56632' (errno: 1478) +# Test 2) CREATE with ROW_FORMAT, ALTER with KEY_BLOCK_SIZE +DROP TABLE IF EXISTS bug56632; +Warnings: +Note 1051 Unknown table 'bug56632' +CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact row_format=COMPACT +ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compressed row_format=COMPACT KEY_BLOCK_SIZE=1 +# Test 3) CREATE with KEY_BLOCK_SIZE, ALTER with ROW_FORMAT +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compressed KEY_BLOCK_SIZE=1 +ALTER TABLE bug56632 ROW_FORMAT=COMPACT; +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compressed KEY_BLOCK_SIZE=1 +# Test 4) CREATE with neither, ALTER with ROW_FORMAT & KEY_BLOCK_SIZE +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ); +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact +ALTER TABLE bug56632 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact +# Test 5) CREATE with KEY_BLOCK_SIZE=3 (invalid). +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; +ERROR HY000: Can't create table 'test.bug56632' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 3. Valid values are [1, 2, 4, 8, 16] +Error 1005 Can't create table 'test.bug56632' (errno: 1478) +SET SESSION innodb_strict_mode = OFF; +# Test 6) CREATE with ROW_FORMAT & KEY_BLOCK_SIZE, ALTER with neither +DROP TABLE IF EXISTS bug56632; +Warnings: +Note 1051 Unknown table 'bug56632' +CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact row_format=COMPACT KEY_BLOCK_SIZE=1 +ALTER TABLE bug56632 ADD COLUMN f1 INT; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL, + `f1` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact row_format=COMPACT KEY_BLOCK_SIZE=1 +# Test 7) CREATE with ROW_FORMAT, ALTER with KEY_BLOCK_SIZE +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact row_format=COMPACT +ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compressed row_format=COMPACT KEY_BLOCK_SIZE=1 +# Test 8) CREATE with KEY_BLOCK_SIZE, ALTER with ROW_FORMAT +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compressed KEY_BLOCK_SIZE=1 +ALTER TABLE bug56632 ROW_FORMAT=COMPACT; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact row_format=COMPACT KEY_BLOCK_SIZE=1 +# Test 9) CREATE with neither, ALTER with ROW_FORMAT & KEY_BLOCK_SIZE +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ); +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact +ALTER TABLE bug56632 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact row_format=COMPACT KEY_BLOCK_SIZE=1 +# Test 10) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with neither. +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=3 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact KEY_BLOCK_SIZE=3 +ALTER TABLE bug56632 ADD COLUMN f1 INT; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL, + `f1` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=3 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact KEY_BLOCK_SIZE=3 +# Test 11) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with ROW_FORMAT=COMPACT. +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=3 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact KEY_BLOCK_SIZE=3 +ALTER TABLE bug56632 ROW_FORMAT=COMPACT; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=3 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact row_format=COMPACT KEY_BLOCK_SIZE=3 +# Test 12) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with KEY_BLOCK_SIZE=1. +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=3 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compact KEY_BLOCK_SIZE=3 +ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE bug56632; +Table Create Table +bug56632 CREATE TABLE `bug56632` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1 +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug56632 Compressed KEY_BLOCK_SIZE=1 +# Cleanup +DROP TABLE IF EXISTS bug56632; diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug56632.test b/mysql-test/suite/innodb_plugin/t/innodb_bug56632.test new file mode 100755 index 00000000000..60703814da2 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug56632.test @@ -0,0 +1,216 @@ +# +# Bug#56632: ALTER TABLE implicitly changes ROW_FORMAT to COMPRESSED +# http://bugs.mysql.com/56632 +# +# Innodb automatically uses compressed mode when the KEY_BLOCK_SIZE +# parameter is used, except if the ROW_FORMAT is also specified, in +# which case the KEY_BLOCK_SIZE is ignored and a warning is shown. +# But Innodb was getting confused when neither of those parameters +# was used on the ALTER statement after they were both used on the +# CREATE. +# +# This will test the results of all 4 combinations of these two +# parameters of the CREATE and ALTER. +# +# Tests 1-5 use INNODB_STRICT_MODE=1 which returns an error +# if there is anything wrong with the statement. +# +# 1) CREATE with ROW_FORMAT=COMPACT & KEY_BLOCK_SIZE=1, ALTER with neither. +# Result; CREATE; fails with error ER_CANT_CREATE_TABLE +# 2) CREATE with ROW_FORMAT=COMPACT, ALTER with KEY_BLOCK_SIZE=1 +# Result; CREATE succeeds, +# ALTER quietly converts ROW_FORMAT to compressed. +# 3) CREATE with KEY_BLOCK_SIZE=1, ALTER with ROW_FORMAT=COMPACT +# Result; CREATE quietly converts ROW_FORMAT to compressed, +# ALTER fails with error ER_CANT_CREATE_TABLE. +# 4) CREATE with neither, ALTER with ROW_FORMAT=COMPACT & KEY_BLOCK_SIZE=1 +# Result; CREATE succeeds, +# ALTER; fails with error ER_CANT_CREATE_TABLE +# 5) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with neither. +# Result; CREATE; fails with error ER_CANT_CREATE_TABLE +# +# Tests 6-11 use INNODB_STRICT_MODE=0 which automatically makes +# adjustments if the prameters are incompatible. +# +# 6) CREATE with ROW_FORMAT=COMPACT & KEY_BLOCK_SIZE=1, ALTER with neither. +# Result; CREATE succeeds, warns that KEY_BLOCK_SIZE is ignored. +# ALTER succeeds, no warnings. +# 7) CREATE with ROW_FORMAT=COMPACT, ALTER with KEY_BLOCK_SIZE=1 +# Result; CREATE succeeds, +# ALTER quietly converts ROW_FORMAT to compressed. +# 8) CREATE with KEY_BLOCK_SIZE=1, ALTER with ROW_FORMAT=COMPACT +# Result; CREATE quietly converts ROW_FORMAT to compressed, +# ALTER succeeds, warns that KEY_BLOCK_SIZE is ignored. +# 9) CREATE with neither, ALTER with ROW_FORMAT=COMPACT & KEY_BLOCK_SIZE=1 +# Result; CREATE succeeds, +# ALTER succeeds, warns that KEY_BLOCK_SIZE is ignored. +# 10) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with neither. +# Result; CREATE succeeds, warns that KEY_BLOCK_SIZE=3 is ignored. +# ALTER succeeds, warns that KEY_BLOCK_SIZE=3 is ignored. +# 11) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with ROW_FORMAT=COMPACT. +# Result; CREATE succeeds, warns that KEY_BLOCK_SIZE=3 is ignored. +# ALTER succeeds, warns that KEY_BLOCK_SIZE=3 is ignored. +# 12) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with KEY_BLOCK_SIZE=1. +# Result; CREATE succeeds, warns that KEY_BLOCK_SIZE=3 is ignored. +# ALTER succeeds, quietly converts ROW_FORMAT to compressed. + +-- source include/have_innodb.inc + +SET storage_engine=InnoDB; + +--disable_query_log +# These values can change during the test +LET $innodb_file_format_orig=`select @@innodb_file_format`; +LET $innodb_file_format_max_orig=`select @@innodb_file_format_max`; +LET $innodb_file_per_table_orig=`select @@innodb_file_per_table`; +LET $innodb_strict_mode_orig=`select @@session.innodb_strict_mode`; +--enable_query_log + +SET GLOBAL innodb_file_format=`Barracuda`; +SET GLOBAL innodb_file_per_table=ON; + +# Innodb strict mode will cause an error on the CREATE or ALTER when; +# 1. both ROW_FORMAT=COMPACT and KEY_BLOCK_SIZE=1, +# 2. KEY_BLOCK_SIZE is not a valid number (0,1,2,4,8,16). +# With innodb_strict_mode = OFF, These errors are corrected +# and just a warning is returned. +SET SESSION innodb_strict_mode = ON; + +--echo # Test 1) CREATE with ROW_FORMAT & KEY_BLOCK_SIZE, ALTER with neither +DROP TABLE IF EXISTS bug56632; +--error ER_CANT_CREATE_TABLE +CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +SHOW WARNINGS; + +--echo # Test 2) CREATE with ROW_FORMAT, ALTER with KEY_BLOCK_SIZE +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 3) CREATE with KEY_BLOCK_SIZE, ALTER with ROW_FORMAT +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +--disable_result_log +--error ER_CANT_CREATE_TABLE +ALTER TABLE bug56632 ROW_FORMAT=COMPACT; +--enable_result_log +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 4) CREATE with neither, ALTER with ROW_FORMAT & KEY_BLOCK_SIZE +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ); +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +--disable_result_log +--error ER_CANT_CREATE_TABLE +ALTER TABLE bug56632 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +--enable_result_log +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 5) CREATE with KEY_BLOCK_SIZE=3 (invalid). +DROP TABLE IF EXISTS bug56632; +--error ER_CANT_CREATE_TABLE +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; +SHOW WARNINGS; + +SET SESSION innodb_strict_mode = OFF; + +--echo # Test 6) CREATE with ROW_FORMAT & KEY_BLOCK_SIZE, ALTER with neither +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +ALTER TABLE bug56632 ADD COLUMN f1 INT; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 7) CREATE with ROW_FORMAT, ALTER with KEY_BLOCK_SIZE +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 8) CREATE with KEY_BLOCK_SIZE, ALTER with ROW_FORMAT +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +ALTER TABLE bug56632 ROW_FORMAT=COMPACT; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 9) CREATE with neither, ALTER with ROW_FORMAT & KEY_BLOCK_SIZE +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ); +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +ALTER TABLE bug56632 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 10) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with neither. +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +ALTER TABLE bug56632 ADD COLUMN f1 INT; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 11) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with ROW_FORMAT=COMPACT. +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +ALTER TABLE bug56632 ROW_FORMAT=COMPACT; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Test 12) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with KEY_BLOCK_SIZE=1. +DROP TABLE IF EXISTS bug56632; +CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; +ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SHOW CREATE TABLE bug56632; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; + +--echo # Cleanup +DROP TABLE IF EXISTS bug56632; + +--disable_query_log +EVAL SET GLOBAL innodb_file_per_table=$innodb_file_per_table_orig; +EVAL SET GLOBAL innodb_file_format_max=$innodb_file_format_max_orig; +EVAL SET GLOBAL innodb_file_format=$innodb_file_format_orig; +EVAL SET SESSION innodb_strict_mode=$innodb_strict_mode_orig; +--enable_query_log + diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index 95778eb0744..9a9cc32c81b 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -6355,8 +6355,8 @@ create_options_are_valid( ? "COMPRESSED" : "DYNAMIC"; - /* These two ROW_FORMATs require - srv_file_per_table and srv_file_format */ + /* These two ROW_FORMATs require srv_file_per_table + and srv_file_format > Antelope */ if (!srv_file_per_table) { push_warning_printf( thd, @@ -6366,7 +6366,6 @@ create_options_are_valid( " requires innodb_file_per_table.", row_format_name); ret = FALSE; - } if (srv_file_format < DICT_TF_FORMAT_ZIP) { @@ -6565,6 +6564,8 @@ ha_innobase::create( ulint ssize, ksize; ulint key_block_size = create_info->key_block_size; + /* Set 'flags' to the correct key_block_size. + It will be zero if key_block_size is an invalid number.*/ for (ssize = ksize = 1; ssize <= DICT_TF_ZSSIZE_MAX; ssize++, ksize <<= 1) { if (key_block_size == ksize) { @@ -6605,10 +6606,10 @@ ha_innobase::create( row_type = form->s->row_type; if (flags) { - /* KEY_BLOCK_SIZE was specified. */ - if (!(create_info->used_fields & HA_CREATE_USED_ROW_FORMAT)) { - /* ROW_FORMAT was not specified; - default to ROW_FORMAT=COMPRESSED */ + /* if KEY_BLOCK_SIZE was specified on this statement and + ROW_FORMAT was not, automatically change ROW_FORMAT to COMPRESSED.*/ + if ( (create_info->used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE) + && !(create_info->used_fields & HA_CREATE_USED_ROW_FORMAT)) { row_type = ROW_TYPE_COMPRESSED; } else if (row_type != ROW_TYPE_COMPRESSED) { /* ROW_FORMAT other than COMPRESSED @@ -6627,7 +6628,7 @@ ha_innobase::create( flags = 0; } } else { - /* No KEY_BLOCK_SIZE */ + /* flags == 0 means no KEY_BLOCK_SIZE.*/ if (row_type == ROW_TYPE_COMPRESSED) { /* ROW_FORMAT=COMPRESSED without KEY_BLOCK_SIZE implies half the From 42550e21e85904877714a3215a220e471597c3e2 Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Tue, 12 Oct 2010 23:25:40 +0400 Subject: [PATCH 022/304] Fix for bug#57272: crash in rpad() when using utf8 Problem: if multibyte and binary string arguments passed to RPAD(), LPAD() or INSERT() functions, they might return wrong results or even lead to a server crash due to missed character set convertion. Fix: perform the convertion if necessary. mysql-test/r/ctype_utf8.result: Fix for bug#57272: crash in rpad() when using utf8 - test result. mysql-test/t/ctype_utf8.test: Fix for bug#57272: crash in rpad() when using utf8 - test case. sql/item_strfunc.cc: Fix for bug#57272: crash in rpad() when using utf8 - convert multibyte argument's character set to binary in case of FUNCTION(MULTIBYTE_ARG, .., BINARY_ARG,..) for RPAD(), LPAD() and INSERT() functions. --- mysql-test/r/ctype_utf8.result | 31 +++++++++++++++++++++++++ mysql-test/t/ctype_utf8.test | 20 ++++++++++++++++ sql/item_strfunc.cc | 42 ++++++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+) diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index 4c21e66a39c..b491ce504bf 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -1898,3 +1898,34 @@ CONVERT(a, CHAR) CONVERT(b, CHAR) 70000 1092 DROP TABLE t1; End of 5.0 tests +SELECT LENGTH(RPAD(0.0115E88, 61297, _utf8'ŃŹŃŤŃŽŃŹ')); +LENGTH(RPAD(0.0115E88, 61297, _utf8'ŃŹŃŤŃŽŃŹ')) +61297 +SELECT LENGTH(RPAD(0.0115E88, 61297, _utf8'йцŃŃŹ')); +LENGTH(RPAD(0.0115E88, 61297, _utf8'йцŃŃŹ')) +61297 +SELECT HEX(RPAD(0x20, 2, _utf8 0xD18F)); +HEX(RPAD(0x20, 2, _utf8 0xD18F)) +20D1 +SELECT HEX(RPAD(0x20, 4, _utf8 0xD18F)); +HEX(RPAD(0x20, 4, _utf8 0xD18F)) +20D18FD1 +SELECT HEX(LPAD(0x20, 2, _utf8 0xD18F)); +HEX(LPAD(0x20, 2, _utf8 0xD18F)) +D120 +SELECT HEX(LPAD(0x20, 4, _utf8 0xD18F)); +HEX(LPAD(0x20, 4, _utf8 0xD18F)) +D18FD120 +SELECT HEX(RPAD(_utf8 0xD18F, 3, 0x20)); +HEX(RPAD(_utf8 0xD18F, 3, 0x20)) +D18F20 +SELECT HEX(LPAD(_utf8 0xD18F, 3, 0x20)); +HEX(LPAD(_utf8 0xD18F, 3, 0x20)) +20D18F +SELECT HEX(INSERT(_utf8 0xD18F, 2, 1, 0x20)); +HEX(INSERT(_utf8 0xD18F, 2, 1, 0x20)) +D120 +SELECT HEX(INSERT(_utf8 0xD18FD18E, 2, 1, 0x20)); +HEX(INSERT(_utf8 0xD18FD18E, 2, 1, 0x20)) +D120D18E +End of 5.1 tests diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index 23c83310886..8e9f09d1e56 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -1466,3 +1466,23 @@ SELECT CONVERT(a, CHAR), CONVERT(b, CHAR) from t1 GROUP BY b; DROP TABLE t1; --echo End of 5.0 tests + + +# +# Bug #57272: crash in rpad() when using utf8 +# +SELECT LENGTH(RPAD(0.0115E88, 61297, _utf8'ŃŹŃŤŃŽŃŹ')); +SELECT LENGTH(RPAD(0.0115E88, 61297, _utf8'йцŃŃŹ')); +SELECT HEX(RPAD(0x20, 2, _utf8 0xD18F)); +SELECT HEX(RPAD(0x20, 4, _utf8 0xD18F)); +SELECT HEX(LPAD(0x20, 2, _utf8 0xD18F)); +SELECT HEX(LPAD(0x20, 4, _utf8 0xD18F)); + +SELECT HEX(RPAD(_utf8 0xD18F, 3, 0x20)); +SELECT HEX(LPAD(_utf8 0xD18F, 3, 0x20)); + +SELECT HEX(INSERT(_utf8 0xD18F, 2, 1, 0x20)); +SELECT HEX(INSERT(_utf8 0xD18FD18E, 2, 1, 0x20)); + + +--echo End of 5.1 tests diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 5d56b0a621a..9f06a4b5c9f 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1013,6 +1013,20 @@ String *Item_func_insert::val_str(String *str) if ((length < 0) || (length > res->length())) length= res->length(); + /* + There is one exception not handled (intentionaly) by the character set + aggregation code. If one string is strong side and is binary, and + another one is weak side and is a multi-byte character string, + then we need to operate on the second string in terms on bytes when + calling ::numchars() and ::charpos(), rather than in terms of characters. + Lets substitute its character set to binary. + */ + if (collation.collation == &my_charset_bin) + { + res->set_charset(&my_charset_bin); + res2->set_charset(&my_charset_bin); + } + /* start and length are now sufficiently valid to pass to charpos function */ start= res->charpos((int) start); length= res->charpos((int) length, (uint32) start); @@ -2514,6 +2528,20 @@ String *Item_func_rpad::val_str(String *str) /* Set here so that rest of code sees out-of-bound value as such. */ if ((ulonglong) count > INT_MAX32) count= INT_MAX32; + /* + There is one exception not handled (intentionaly) by the character set + aggregation code. If one string is strong side and is binary, and + another one is weak side and is a multi-byte character string, + then we need to operate on the second string in terms on bytes when + calling ::numchars() and ::charpos(), rather than in terms of characters. + Lets substitute its character set to binary. + */ + if (collation.collation == &my_charset_bin) + { + res->set_charset(&my_charset_bin); + rpad->set_charset(&my_charset_bin); + } + if (count <= (res_char_length= res->numchars())) { // String to pad is big enough res->length(res->charpos((int) count)); // Shorten result if longer @@ -2616,6 +2644,20 @@ String *Item_func_lpad::val_str(String *str) if ((ulonglong) count > INT_MAX32) count= INT_MAX32; + /* + There is one exception not handled (intentionaly) by the character set + aggregation code. If one string is strong side and is binary, and + another one is weak side and is a multi-byte character string, + then we need to operate on the second string in terms on bytes when + calling ::numchars() and ::charpos(), rather than in terms of characters. + Lets substitute its character set to binary. + */ + if (collation.collation == &my_charset_bin) + { + res->set_charset(&my_charset_bin); + pad->set_charset(&my_charset_bin); + } + res_char_length= res->numchars(); if (count <= res_char_length) From b001a5224d8b26e9706a386ca2c26320d152ee1c Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Tue, 12 Oct 2010 23:28:03 +0400 Subject: [PATCH 023/304] Fix for bug#57283: inet_ntoa() crashes Problem: some call of INET_NTOA() function may lead to a crash due to missing its character set initialization. Fix: explicitly set the character set. mysql-test/r/func_misc.result: Fix for bug#57283: inet_ntoa() crashes - test result. mysql-test/t/func_misc.test: Fix for bug#57283: inet_ntoa() crashes - test case. sql/item_strfunc.cc: Fix for bug#57283: inet_ntoa() crashes - explicitly set buffer's character set. --- mysql-test/r/func_misc.result | 6 ++++++ mysql-test/t/func_misc.test | 8 ++++++++ sql/item_strfunc.cc | 1 + 3 files changed, 15 insertions(+) diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result index eee56ae7461..082b6eb50c2 100644 --- a/mysql-test/r/func_misc.result +++ b/mysql-test/r/func_misc.result @@ -351,4 +351,10 @@ GREATEST(a, (SELECT b FROM t1 LIMIT 1)) 3 1 DROP TABLE t1; +SELECT INET_NTOA(0); +INET_NTOA(0) +0.0.0.0 +SELECT '1' IN ('1', INET_NTOA(0)); +'1' IN ('1', INET_NTOA(0)) +1 End of tests diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test index c6b5ffd5a3f..f47418fa773 100644 --- a/mysql-test/t/func_misc.test +++ b/mysql-test/t/func_misc.test @@ -479,4 +479,12 @@ SELECT DISTINCT GREATEST(a, (SELECT b FROM t1 LIMIT 1)) FROM t1 UNION SELECT 1; DROP TABLE t1; + +# +# Bug #57283: inet_ntoa() crashes +# +SELECT INET_NTOA(0); +SELECT '1' IN ('1', INET_NTOA(0)); + + --echo End of tests diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 9f06a4b5c9f..8fda281bd9e 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -3135,6 +3135,7 @@ String* Item_func_inet_ntoa::val_str(String* str) if ((null_value= (args[0]->null_value || n > (ulonglong) LL(4294967295)))) return 0; // Null value + str->set_charset(collation.collation); str->length(0); int4store(buf,n); From 8169faec2797511e649bd98329c69a6cb0c9a857 Mon Sep 17 00:00:00 2001 From: Dmitry Shulga Date: Wed, 13 Oct 2010 12:28:58 +0700 Subject: [PATCH 024/304] Fixed bug#36742 - GRANT hostname case handling inconsistent. mysql-test/r/grant.result: It was added result for test case for bug#36742. mysql-test/t/grant.test: It was added test case for bug#36742. sql/sql_yacc.yy: It was added convertation of host name part of user name to lowercase. --- mysql-test/r/grant.result | 11 +++++++++++ mysql-test/t/grant.test | 10 ++++++++++ sql/sql_yacc.yy | 6 ++++++ 3 files changed, 27 insertions(+) diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index 6831ef6183d..f6277323964 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -1429,3 +1429,14 @@ DROP USER 'testbug'@localhost; DROP TABLE db2.t1; DROP DATABASE db1; DROP DATABASE db2; +# +# Bug #36742 +# +grant usage on Foo.* to myuser@Localhost identified by 'foo'; +grant select on Foo.* to myuser@localhost; +select host,user from mysql.user where User='myuser'; +host user +localhost myuser +revoke select on Foo.* from myuser@localhost; +delete from mysql.user where User='myuser'; +flush privileges; diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index cb8d3c63be8..2fafeb7d264 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -1550,5 +1550,15 @@ DROP TABLE db2.t1; DROP DATABASE db1; DROP DATABASE db2; +--echo # +--echo # Bug #36742 +--echo # +grant usage on Foo.* to myuser@Localhost identified by 'foo'; +grant select on Foo.* to myuser@localhost; +select host,user from mysql.user where User='myuser'; +revoke select on Foo.* from myuser@localhost; +delete from mysql.user where User='myuser'; +flush privileges; + # Wait till we reached the initial number of concurrent sessions --source include/wait_until_count_sessions.inc diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index aa41a408e5b..4e24e69af42 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -11567,6 +11567,12 @@ user: system_charset_info, 0) || check_host_name(&$$->host)) MYSQL_YYABORT; + /* + Convert hostname part of username to lowercase. + It's OK to use in-place lowercase as long as + the character set is utf8. + */ + my_casedn_str(system_charset_info, $$->host.str); } | CURRENT_USER optional_braces { From eb882fe41b96bd2736dafe86a59b7f7a823ba07f Mon Sep 17 00:00:00 2001 From: Konstantin Osipov Date: Wed, 13 Oct 2010 12:48:08 +0400 Subject: [PATCH 025/304] Fix Bug#56443 remove last 'mysqld_show_column_type' remains sql/sql_show.h: Remove an unused declaration. --- sql/sql_show.h | 1 - 1 file changed, 1 deletion(-) diff --git a/sql/sql_show.h b/sql/sql_show.h index d1323ede8c1..de8f2525baa 100644 --- a/sql/sql_show.h +++ b/sql/sql_show.h @@ -104,7 +104,6 @@ bool mysqld_show_storage_engines(THD *thd); bool mysqld_show_authors(THD *thd); bool mysqld_show_contributors(THD *thd); bool mysqld_show_privileges(THD *thd); -bool mysqld_show_column_types(THD *thd); char *make_backup_log_name(char *buff, const char *name, const char* log_ext); void calc_sum_of_all_status(STATUS_VAR *to); void append_definer(THD *thd, String *buffer, const LEX_STRING *definer_user, From 609bc2c4077f4c1244763a796aa52a5d9d363e15 Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Wed, 13 Oct 2010 13:34:02 +0400 Subject: [PATCH 026/304] Reverting a patch for Bug#45445 (cannot execute procedures with thread_stack set to 128k). Some platforms don't work with 4 * STACK_MIN_SIZE. Thus, reverting back to 8 * STACK_MIN_SIZE and waiting for another fix. --- sql/sp_head.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 52f658cbe0e..1fd4e9302c4 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1233,8 +1233,11 @@ sp_head::execute(THD *thd) The same with db_load_routine() required circa 7k bytes and 14k bytes accordingly. Hence, here we book the stack with some reasonable margin. + + Reverting back to 8 * STACK_MIN_SIZE until further fix. + 8 * STACK_MIN_SIZE is required on some exotic platforms. */ - if (check_stack_overrun(thd, 4 * STACK_MIN_SIZE, (uchar*)&old_packet)) + if (check_stack_overrun(thd, 8 * STACK_MIN_SIZE, (uchar*)&old_packet)) DBUG_RETURN(TRUE); /* init per-instruction memroot */ From e8fd5b58bff9bc06012c8758ce76b39ba51e6712 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Wed, 13 Oct 2010 13:07:28 +0200 Subject: [PATCH 027/304] Bug #55968 MTR does not clean up properly and chokes on its discharge Added --clean-vardir to empty vardir if no failures Also added variable $MTR_CLEAN_VARDIR --- mysql-test/mysql-test-run.pl | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 494ec7a9be3..e6d988dfba6 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -195,6 +195,7 @@ sub using_extern { return (keys %opts_extern > 0);}; our $opt_fast= 0; our $opt_force; our $opt_mem= $ENV{'MTR_MEM'}; +our $opt_clean_vardir= $ENV{'MTR_CLEAN_VARDIR'}; our $opt_gcov; our $opt_gcov_exe= "gcov"; @@ -476,6 +477,8 @@ sub main { mtr_report_stats("Completed", $completed); + remove_vardir_subs() if $opt_clean_vardir; + exit(0); } @@ -946,6 +949,7 @@ sub command_line_setup { 'tmpdir=s' => \$opt_tmpdir, 'vardir=s' => \$opt_vardir, 'mem' => \$opt_mem, + 'clean-vardir' => \$opt_clean_vardir, 'client-bindir=s' => \$path_client_bindir, 'client-libdir=s' => \$path_client_libdir, @@ -2202,6 +2206,12 @@ sub environment_setup { } +sub remove_vardir_subs() { + foreach my $sdir ( glob("$opt_vardir/*") ) { + mtr_verbose("Removing subdir $sdir"); + rmtree($sdir); + } +} # # Remove var and any directories in var/ created by previous @@ -2246,11 +2256,7 @@ sub remove_stale_vardir () { mtr_error("The destination for symlink $opt_vardir does not exist") if ! -d readlink($opt_vardir); - foreach my $bin ( glob("$opt_vardir/*") ) - { - mtr_verbose("Removing bin $bin"); - rmtree($bin); - } + remove_vardir_subs(); } } else @@ -5502,6 +5508,8 @@ Options to control directories to use for tmpfs (/dev/shm) The option can also be set using environment variable MTR_MEM=[DIR] + clean-vardir Clean vardir if tests were successful and if + running in "memory". Otherwise this option is ignored client-bindir=PATH Path to the directory where client binaries are located client-libdir=PATH Path to the directory where client libraries are located From ec505e95708ab1bacd0c6afa8e83e411dbe4b0f7 Mon Sep 17 00:00:00 2001 From: Dmitry Lenev Date: Wed, 13 Oct 2010 15:21:45 +0400 Subject: [PATCH 028/304] Fix for bug #57422 "rpl_row_sp003 sporadically fails under heavy load". rpl_row_sp003.test has sporadically failed when run on machine under heavy load or on slow hardware. This patch fixes races in the test which were causing these failures and also removes unnecessary 100 second wait from it. --- mysql-test/extra/rpl_tests/rpl_row_sp003.test | 18 ++++++++++++++++-- mysql-test/suite/rpl/r/rpl_row_sp003.result | 10 +++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/mysql-test/extra/rpl_tests/rpl_row_sp003.test b/mysql-test/extra/rpl_tests/rpl_row_sp003.test index 7bc326a3791..d2c2ea0caf3 100644 --- a/mysql-test/extra/rpl_tests/rpl_row_sp003.test +++ b/mysql-test/extra/rpl_tests/rpl_row_sp003.test @@ -35,10 +35,23 @@ connection master1; send CALL test.p1(); connection master; -# To make sure tha the call on master1 arrived at the get_lock -sleep 1; +# Make sure that the call on master1 arrived at the get_lock. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = 'User lock' and + info = 'SELECT get_lock("test", 100)'; +--source include/wait_condition.inc CALL test.p2(); SELECT release_lock("test"); + +connection master1; +# Reap CALL test.p1() to ensure that it has fully completed +# before doing any selects on test.t1. +--reap +# Release lock acquired by it. +SELECT release_lock("test"); + +connection master; SELECT * FROM test.t1; #show binlog events; --source include/wait_for_ndb_to_binlog.inc @@ -51,6 +64,7 @@ DROP TABLE IF EXISTS test.t1; eval CREATE TABLE test.t1(a INT,PRIMARY KEY(a))ENGINE=$engine_type; CALL test.p2(); CALL test.p1(); +SELECT release_lock("test"); SELECT * FROM test.t1; sync_slave_with_master; diff --git a/mysql-test/suite/rpl/r/rpl_row_sp003.result b/mysql-test/suite/rpl/r/rpl_row_sp003.result index df3e2a7ceed..c3e2dc57740 100644 --- a/mysql-test/suite/rpl/r/rpl_row_sp003.result +++ b/mysql-test/suite/rpl/r/rpl_row_sp003.result @@ -26,6 +26,11 @@ CALL test.p2(); SELECT release_lock("test"); release_lock("test") 1 +get_lock("test", 100) +1 +SELECT release_lock("test"); +release_lock("test") +1 SELECT * FROM test.t1; a 5 @@ -37,7 +42,10 @@ CREATE TABLE test.t1(a INT,PRIMARY KEY(a))ENGINE=INNODB; CALL test.p2(); CALL test.p1(); get_lock("test", 100) -0 +1 +SELECT release_lock("test"); +release_lock("test") +1 SELECT * FROM test.t1; a 8 From b5be2fbc8df3c8e7131d88adb06bad408e446df7 Mon Sep 17 00:00:00 2001 From: Jon Olav Hauglid Date: Wed, 13 Oct 2010 16:15:28 +0200 Subject: [PATCH 029/304] Bug #55930 Assertion `thd->transaction.stmt.is_empty() || thd->in_sub_stmt || (thd->state.. OPTIMIZE TABLE is not directly supported by InnoDB. Instead, recreate and analyze of the table is done. After recreate, the table is closed and locks are released before the table is reopened and locks re-acquired for the analyze phase. This assertion was triggered if OPTIMIZE TABLE failed to acquire thr_lock locks before starting the analyze phase. The assertion tests (among other things) that there no active statement transaction. However, as part of acquiring the thr_lock lock, external_lock() is called for InnoDB tables and this causes a statement transaction to be started. If thr_multi_lock() later fails (e.g. due to timeout), the failure handling code causes this assert to be triggered. This patch fixes the problem by doing rollback of the current statement transaction in case open_ltable (used by OPTIMIZE TABLE) fails to acquire thr_lock locks. Test case added to lock_sync.test. --- mysql-test/r/lock_sync.result | 34 ++++++++++++++++++++++ mysql-test/t/lock_sync.test | 55 +++++++++++++++++++++++++++++++++++ sql/sql_base.cc | 3 ++ 3 files changed, 92 insertions(+) diff --git a/mysql-test/r/lock_sync.result b/mysql-test/r/lock_sync.result index 3682f0df26a..726b754eaa8 100644 --- a/mysql-test/r/lock_sync.result +++ b/mysql-test/r/lock_sync.result @@ -704,3 +704,37 @@ SET DEBUG_SYNC="now SIGNAL query"; # Connection default DROP EVENT e2; SET DEBUG_SYNC="RESET"; +# +# Bug#55930 Assertion `thd->transaction.stmt.is_empty() || +# thd->in_sub_stmt || (thd->state.. +# +DROP TABLE IF EXISTS t1; +CREATE TABLE t1(a INT) engine=InnoDB; +INSERT INTO t1 VALUES (1), (2); +# Connection con1 +SET SESSION lock_wait_timeout= 1; +SET DEBUG_SYNC= 'ha_admin_open_ltable SIGNAL opti_recreate WAIT_FOR opti_analyze'; +# Sending: +OPTIMIZE TABLE t1; +# Connection con2 +SET DEBUG_SYNC= 'now WAIT_FOR opti_recreate'; +SET DEBUG_SYNC= 'after_lock_tables_takes_lock SIGNAL thrlock WAIT_FOR release_thrlock'; +# Sending: +INSERT INTO t1 VALUES (3); +# Connection default +SET DEBUG_SYNC= 'now WAIT_FOR thrlock'; +SET DEBUG_SYNC= 'now SIGNAL opti_analyze'; +# Connection con1 +# Reaping: OPTIMIZE TABLE t1 +Table Op Msg_type Msg_text +test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize error Lock wait timeout exceeded; try restarting transaction +test.t1 optimize status Operation failed +Warnings: +Error 1205 Lock wait timeout exceeded; try restarting transaction +SET DEBUG_SYNC= 'now SIGNAL release_thrlock'; +# Connection con2 +# Reaping: INSERT INTO t1 VALUES (3) +# Connection default +DROP TABLE t1; +SET DEBUG_SYNC= 'RESET'; diff --git a/mysql-test/t/lock_sync.test b/mysql-test/t/lock_sync.test index 49f8f59ec5a..7131e2cde31 100644 --- a/mysql-test/t/lock_sync.test +++ b/mysql-test/t/lock_sync.test @@ -1023,6 +1023,61 @@ DROP EVENT e2; SET DEBUG_SYNC="RESET"; +--echo # +--echo # Bug#55930 Assertion `thd->transaction.stmt.is_empty() || +--echo # thd->in_sub_stmt || (thd->state.. +--echo # + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1(a INT) engine=InnoDB; +INSERT INTO t1 VALUES (1), (2); + +connect (con1, localhost, root); +connect (con2, localhost, root); + +--echo # Connection con1 +connection con1; +SET SESSION lock_wait_timeout= 1; +SET DEBUG_SYNC= 'ha_admin_open_ltable SIGNAL opti_recreate WAIT_FOR opti_analyze'; +--echo # Sending: +--send OPTIMIZE TABLE t1 + +--echo # Connection con2 +connection con2; +SET DEBUG_SYNC= 'now WAIT_FOR opti_recreate'; +SET DEBUG_SYNC= 'after_lock_tables_takes_lock SIGNAL thrlock WAIT_FOR release_thrlock'; +--echo # Sending: +--send INSERT INTO t1 VALUES (3) + +--echo # Connection default +connection default; +SET DEBUG_SYNC= 'now WAIT_FOR thrlock'; +SET DEBUG_SYNC= 'now SIGNAL opti_analyze'; + +--echo # Connection con1 +connection con1; +--echo # Reaping: OPTIMIZE TABLE t1 +--reap +SET DEBUG_SYNC= 'now SIGNAL release_thrlock'; +disconnect con1; +--source include/wait_until_disconnected.inc + +--echo # Connection con2 +connection con2; +--echo # Reaping: INSERT INTO t1 VALUES (3) +--reap +disconnect con2; +--source include/wait_until_disconnected.inc + +--echo # Connection default +connection default; +DROP TABLE t1; +SET DEBUG_SYNC= 'RESET'; + + # Check that all connections opened by test cases in this file are really # gone so execution of other tests won't be affected by their presence. --source include/wait_until_count_sessions.inc diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 8305283cd17..8090d8a9288 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -5319,7 +5319,10 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type, end: if (table == NULL) + { + trans_rollback_stmt(thd); close_thread_tables(thd); + } thd_proc_info(thd, 0); DBUG_RETURN(table); } From 215e967ace1c5cbcdcaf82d1b00b31bc9f132393 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Wed, 13 Oct 2010 12:11:29 -0300 Subject: [PATCH 030/304] Use a guard macro to prevent the inclusion of system headers when checking the ABI with the C Preprocessor. Also, add the new hearders to the cmake based ABI check. cmake/abi_check.cmake: Add headers which were added to the autotools ABI check. Remove trailing spaces. include/mysql/client_plugin.h: Guard the inclusion of system headers. --- Makefile.am | 2 ++ cmake/abi_check.cmake | 6 ++++-- include/mysql/client_plugin.h | 2 ++ include/mysql/client_plugin.h.pp | 2 -- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Makefile.am b/Makefile.am index fadd73d5094..c47d8e780cf 100644 --- a/Makefile.am +++ b/Makefile.am @@ -263,6 +263,8 @@ test-full-qa: # # Headers which need to be checked for abi/api compatibility. # +# Attention: do not forget to also add to cmake/abi_check.cmake +# API_PREPROCESSOR_HEADER = $(top_srcdir)/include/mysql/plugin_audit.h \ $(top_srcdir)/include/mysql/plugin_ftparser.h \ diff --git a/cmake/abi_check.cmake b/cmake/abi_check.cmake index b9ff9f7af73..2488bcefe33 100644 --- a/cmake/abi_check.cmake +++ b/cmake/abi_check.cmake @@ -27,12 +27,14 @@ IF(CMAKE_COMPILER_IS_GNUCC AND CMAKE_SYSTEM_NAME MATCHES "Linux") ELSE() SET(COMPILER ${CMAKE_C_COMPILER}) ENDIF() - SET(API_PREPROCESSOR_HEADER + SET(API_PREPROCESSOR_HEADER ${CMAKE_SOURCE_DIR}/include/mysql/plugin_audit.h ${CMAKE_SOURCE_DIR}/include/mysql/plugin_ftparser.h ${CMAKE_SOURCE_DIR}/include/mysql.h - ${CMAKE_SOURCE_DIR}/include/mysql/psi/psi_abi_v1.h + ${CMAKE_SOURCE_DIR}/include/mysql/psi/psi_abi_v1.h ${CMAKE_SOURCE_DIR}/include/mysql/psi/psi_abi_v2.h + ${CMAKE_SOURCE_DIR}/include/mysql/client_plugin.h + ${CMAKE_SOURCE_DIR}/include/mysql/plugin_auth.h ) ADD_CUSTOM_TARGET(abi_check ALL diff --git a/include/mysql/client_plugin.h b/include/mysql/client_plugin.h index ddd3b64ca56..d9c0dd02008 100644 --- a/include/mysql/client_plugin.h +++ b/include/mysql/client_plugin.h @@ -23,8 +23,10 @@ */ #define MYSQL_CLIENT_PLUGIN_INCLUDED +#ifndef MYSQL_ABI_CHECK #include #include +#endif /* known plugin types */ #define MYSQL_CLIENT_reserved1 0 diff --git a/include/mysql/client_plugin.h.pp b/include/mysql/client_plugin.h.pp index 58627e06f09..e508f821aad 100644 --- a/include/mysql/client_plugin.h.pp +++ b/include/mysql/client_plugin.h.pp @@ -1,5 +1,3 @@ -#include -#include struct st_mysql_client_plugin { int type; unsigned int interface_version; const char *name; const char *author; const char *desc; unsigned int version[3]; const char *license; void *mysql_api; int (*init)(char *, size_t, int, va_list); int (*deinit)(); int (*options)(const char *option, const void *); From d5055f4e8ad6872f585e1dc57b60d6eb461c9d2f Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Wed, 13 Oct 2010 21:17:00 -0700 Subject: [PATCH 031/304] Fix Bug #57397 io_handler_thread() will never cleanup rb://483 approved by Inaam --- storage/innodb_plugin/ChangeLog | 4 ++++ storage/innodb_plugin/srv/srv0start.c | 6 ++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 3b1f202c8ac..d193dcd321c 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,7 @@ +2010-10-14 The InnoDB Team + * srv/srv0start.c + Fix Bug #57397 io_handler_thread() will never cleanup + 2010-10-11 The InnoDB Team * row/row0sel.c Fix Bug #57345 btr_pcur_store_position abort for load with diff --git a/storage/innodb_plugin/srv/srv0start.c b/storage/innodb_plugin/srv/srv0start.c index ba9fc831b39..2d339596013 100644 --- a/storage/innodb_plugin/srv/srv0start.c +++ b/storage/innodb_plugin/srv/srv0start.c @@ -471,7 +471,7 @@ io_handler_thread( fprintf(stderr, "Io handler thread %lu starts, id %lu\n", segment, os_thread_pf(os_thread_get_curr_id())); #endif - for (i = 0;; i++) { + while (srv_shutdown_state != SRV_SHUTDOWN_EXIT_THREADS) { fil_aio_wait(segment); mutex_enter(&ios_mutex); @@ -479,8 +479,6 @@ io_handler_thread( mutex_exit(&ios_mutex); } - thr_local_free(os_thread_get_curr_id()); - /* We count the number of threads in os_thread_exit(). A created thread should always use that to exit and not use return() to exit. The thread actually never comes here because it is exited in an @@ -1894,7 +1892,7 @@ innobase_shutdown_for_mysql(void) #ifdef __NETWARE__ if (!panic_shutdown) #endif - logs_empty_and_mark_files_at_shutdown(); + logs_empty_and_mark_files_at_shutdown(); if (srv_conc_n_threads != 0) { fprintf(stderr, From 4c14da79754db219d063bc7fc29b8a3abfa34ba7 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 13 Oct 2010 20:18:59 +0300 Subject: [PATCH 032/304] Fix Bug#56143 too many foreign keys causes output of show create table to become invalid Just remove the check whether the file is "too big". A similar code exists in ha_innobase::update_table_comment() but that method does not seem to be used. --- .../suite/innodb/r/innodb_bug56143.result | 560 ++++++++++++++++++ .../suite/innodb/t/innodb_bug56143.test | 29 + storage/innobase/handler/ha_innodb.cc | 2 - 3 files changed, 589 insertions(+), 2 deletions(-) create mode 100644 mysql-test/suite/innodb/r/innodb_bug56143.result create mode 100644 mysql-test/suite/innodb/t/innodb_bug56143.test diff --git a/mysql-test/suite/innodb/r/innodb_bug56143.result b/mysql-test/suite/innodb/r/innodb_bug56143.result new file mode 100644 index 00000000000..cfff4d60d1b --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug56143.result @@ -0,0 +1,560 @@ +SHOW CREATE TABLE bug56143; +Table Create Table +bug56143 CREATE TABLE `bug56143` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + KEY `a` (`a`), + KEY `b` (`b`), + KEY `c` (`c`), + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa10` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa100` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa101` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa102` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa103` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa104` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa105` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa106` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa107` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa108` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa109` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa11` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa110` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa111` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa112` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa113` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa114` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa115` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa116` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa117` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa118` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa119` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa12` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa120` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa121` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa122` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa123` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa124` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa125` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa126` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa127` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa128` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa129` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa13` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa130` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa131` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa132` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa133` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa134` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa135` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa136` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa137` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa138` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa139` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa14` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa140` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa141` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa142` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa143` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa144` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa145` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa146` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa147` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa148` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa149` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa15` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa150` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa151` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa152` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa153` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa154` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa155` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa156` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa157` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa158` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa159` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa16` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa160` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa161` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa162` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa163` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa164` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa165` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa166` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa167` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa168` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa169` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa17` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa170` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa171` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa172` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa173` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa174` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa175` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa176` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa177` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa178` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa179` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa18` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa180` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa181` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa182` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa183` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa184` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa185` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa186` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa187` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa188` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa189` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa19` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa190` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa191` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa192` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa193` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa194` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa195` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa196` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa197` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa198` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa199` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa200` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa201` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa202` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa203` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa204` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa205` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa206` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa207` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa208` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa209` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa21` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa210` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa211` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa212` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa213` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa214` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa215` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa216` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa217` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa218` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa219` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa22` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa220` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa221` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa222` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa223` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa224` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa225` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa226` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa227` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa228` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa229` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa23` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa230` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa231` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa232` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa233` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa234` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa235` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa236` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa237` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa238` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa239` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa24` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa240` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa241` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa242` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa243` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa244` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa245` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa246` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa247` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa248` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa249` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa25` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa250` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa251` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa252` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa253` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa254` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa255` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa256` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa257` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa258` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa259` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa26` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa260` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa261` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa262` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa263` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa264` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa265` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa266` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa267` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa268` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa269` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa27` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa270` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa271` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa272` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa273` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa274` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa275` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa276` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa277` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa278` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa279` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa28` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa280` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa281` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa282` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa283` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa284` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa285` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa286` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa287` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa288` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa289` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa29` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa290` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa291` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa292` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa293` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa294` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa295` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa296` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa297` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa298` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa299` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa30` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa300` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa301` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa302` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa303` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa304` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa305` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa306` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa307` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa308` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa309` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa31` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa310` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa311` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa312` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa313` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa314` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa315` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa316` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa317` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa318` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa319` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa32` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa320` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa321` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa322` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa323` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa324` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa325` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa326` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa327` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa328` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa329` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa33` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa330` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa331` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa332` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa333` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa334` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa335` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa336` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa337` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa338` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa339` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa34` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa340` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa341` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa342` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa343` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa344` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa345` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa346` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa347` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa348` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa349` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa35` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa350` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa351` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa352` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa353` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa354` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa355` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa356` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa357` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa358` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa359` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa36` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa360` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa361` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa362` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa363` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa364` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa365` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa366` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa367` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa368` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa369` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa37` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa370` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa371` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa372` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa373` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa374` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa375` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa376` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa377` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa378` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa379` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa38` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa380` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa381` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa382` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa383` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa384` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa385` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa386` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa387` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa388` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa389` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa39` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa390` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa391` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa392` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa393` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa394` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa395` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa396` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa397` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa398` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa399` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa40` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa400` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa401` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa402` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa403` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa404` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa405` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa406` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa407` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa408` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa409` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa41` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa410` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa411` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa412` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa413` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa414` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa415` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa416` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa417` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa418` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa419` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa42` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa420` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa421` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa422` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa423` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa424` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa425` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa426` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa427` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa428` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa429` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa43` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa430` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa431` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa432` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa433` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa434` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa435` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa436` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa437` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa438` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa439` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa44` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa440` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa441` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa442` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa443` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa444` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa445` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa446` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa447` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa448` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa449` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa45` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa450` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa451` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa452` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa453` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa454` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa455` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa456` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa457` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa458` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa459` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa46` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa460` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa461` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa462` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa463` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa464` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa465` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa466` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa467` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa468` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa469` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa47` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa470` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa471` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa472` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa473` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa474` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa475` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa476` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa477` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa478` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa479` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa48` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa480` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa481` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa482` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa483` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa484` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa485` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa486` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa487` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa488` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa489` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa49` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa490` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa491` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa492` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa493` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa494` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa495` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa496` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa497` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa498` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa499` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa5` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa50` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa500` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa501` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa502` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa503` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa504` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa505` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa506` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa507` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa508` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa509` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa51` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa510` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa511` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa512` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa513` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa514` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa515` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa516` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa517` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa518` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa519` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa52` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa520` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa521` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa522` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa523` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa524` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa525` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa526` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa527` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa528` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa529` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa53` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa530` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa531` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa532` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa533` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa534` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa535` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa536` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa537` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa538` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa539` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa54` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa540` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa541` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa542` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa543` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa544` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa545` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa546` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa547` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa548` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa549` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa55` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa550` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa56` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa57` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa58` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa59` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa6` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa60` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa61` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa62` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa63` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa64` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa65` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa66` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa67` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa68` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa69` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa7` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa70` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa71` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa72` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa73` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa74` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa75` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa76` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa77` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa78` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa79` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa8` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa80` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa81` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa82` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa83` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa84` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa85` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa86` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa87` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa88` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa89` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa90` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa91` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa92` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa93` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa94` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa95` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa96` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa97` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa98` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa99` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 diff --git a/mysql-test/suite/innodb/t/innodb_bug56143.test b/mysql-test/suite/innodb/t/innodb_bug56143.test new file mode 100644 index 00000000000..45c174fd280 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug56143.test @@ -0,0 +1,29 @@ +# +# Bug#56143 too many foreign keys causes output of show create table to become invalid +# http://bugs.mysql.com/56143 +# + +-- source include/have_innodb.inc + +-- disable_query_log +-- disable_result_log + +SET foreign_key_checks=0; +DROP TABLE IF EXISTS bug56143; +CREATE TABLE bug56143 (a INT, b INT, c INT, KEY(a), KEY(b), KEY(c)) ENGINE=INNODB; + +let $i = 550; +while ($i) +{ + eval ALTER TABLE `bug56143` ADD CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$i` FOREIGN KEY (`b`) REFERENCES `bug56143`(`b`) ON UPDATE SET NULL; + dec $i; +} + +-- enable_query_log +-- enable_result_log + +SHOW CREATE TABLE bug56143; + +-- disable_query_log +-- disable_result_log +DROP TABLE bug56143; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index cfd4b229ce0..aac0a291223 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -6788,8 +6788,6 @@ ha_innobase::get_foreign_key_create_info(void) flen = ftell(srv_dict_tmpfile); if (flen < 0) { flen = 0; - } else if (flen > 64000 - 1) { - flen = 64000 - 1; } /* allocate buffer for the string, and From aeb24b635a32748b37b9789bf35c47044b8bb0fe Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Wed, 13 Oct 2010 21:25:41 +0400 Subject: [PATCH 033/304] Bump version after 5.5.7 clone-off. --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index c272efe9214..4725008b473 100644 --- a/configure.in +++ b/configure.in @@ -27,7 +27,7 @@ dnl dnl When changing the major version number please also check the switch dnl statement in mysqlbinlog::check_master_version(). You may also need dnl to update version.c in ndb. -AC_INIT([MySQL Server], [5.5.7-rc], [], [mysql]) +AC_INIT([MySQL Server], [5.5.8-ga], [], [mysql]) AC_CONFIG_SRCDIR([sql/mysqld.cc]) AC_CANONICAL_SYSTEM From 895506247de07b247086d267d9468f32a07de7f1 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 13 Oct 2010 13:32:10 -0500 Subject: [PATCH 034/304] Bug#55632 - Fix testcase for 5.1 plugin --- mysql-test/suite/innodb_plugin/t/innodb_bug56632.test | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug56632.test b/mysql-test/suite/innodb_plugin/t/innodb_bug56632.test index 60703814da2..7f1c41cddfa 100755 --- a/mysql-test/suite/innodb_plugin/t/innodb_bug56632.test +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug56632.test @@ -54,14 +54,14 @@ # Result; CREATE succeeds, warns that KEY_BLOCK_SIZE=3 is ignored. # ALTER succeeds, quietly converts ROW_FORMAT to compressed. --- source include/have_innodb.inc +-- source include/have_innodb_plugin.inc SET storage_engine=InnoDB; --disable_query_log # These values can change during the test LET $innodb_file_format_orig=`select @@innodb_file_format`; -LET $innodb_file_format_max_orig=`select @@innodb_file_format_max`; +LET $innodb_file_format_check_orig=`select @@innodb_file_format_check`; LET $innodb_file_per_table_orig=`select @@innodb_file_per_table`; LET $innodb_strict_mode_orig=`select @@session.innodb_strict_mode`; --enable_query_log @@ -209,8 +209,8 @@ DROP TABLE IF EXISTS bug56632; --disable_query_log EVAL SET GLOBAL innodb_file_per_table=$innodb_file_per_table_orig; -EVAL SET GLOBAL innodb_file_format_max=$innodb_file_format_max_orig; EVAL SET GLOBAL innodb_file_format=$innodb_file_format_orig; +EVAL SET GLOBAL innodb_file_format_check=$innodb_file_format_check_orig; EVAL SET SESSION innodb_strict_mode=$innodb_strict_mode_orig; --enable_query_log From 8a30cc4a79908452c5dabe50f93900c2eb873f66 Mon Sep 17 00:00:00 2001 From: smenon Date: Wed, 13 Oct 2010 21:54:45 +0200 Subject: [PATCH 035/304] Raise version number after cloning 5.5.7-rc --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index c272efe9214..dca7e548e50 100644 --- a/configure.in +++ b/configure.in @@ -27,7 +27,7 @@ dnl dnl When changing the major version number please also check the switch dnl statement in mysqlbinlog::check_master_version(). You may also need dnl to update version.c in ndb. -AC_INIT([MySQL Server], [5.5.7-rc], [], [mysql]) +AC_INIT([MySQL Server], [5.5.8-rc], [], [mysql]) AC_CONFIG_SRCDIR([sql/mysqld.cc]) AC_CANONICAL_SYSTEM From 1d43e72a0b98ed89b990965313c4c31d5d262890 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Wed, 13 Oct 2010 22:54:07 -0300 Subject: [PATCH 036/304] Bug#56096: STOP SLAVE hangs if executed in parallel with user sleep The root of the problem is that to interrupt a slave SQL thread wait, the STOP SLAVE implementation uses thd->awake(THD::NOT_KILLED). This appears as a spurious wakeup (e.g. from a sleep on a condition variable) to the code that the slave SQL thread is executing at the time of the STOP. If the code is not written to be spurious-wakeup safe, unexpected behavior can occur. For the reported case, this problem led to an infinite loop around the interruptible_wait() function in item_func.cc (SLEEP() function implementation). The loop was not being properly restarted and, consequently, would not come to an end. Since the SLEEP function sleeps on a timed event in order to be killable and to perform periodic checks until the requested time has elapsed, the spurious wake up was causing the requested sleep time to be reset every two seconds. The solution is to calculate the requested absolute time only once and to ensure that the thread only sleeps until this time is elapsed. In case of a spurious wake up, the sleep is restarted using the previously calculated absolute time. This restores the behavior present in previous releases. If a slave thread is executing a SLEEP function, a STOP SLAVE statement will wait until the time requested in the sleep function has elapsed. mysql-test/extra/rpl_tests/rpl_start_stop_slave.test: Add test case for Bug#56096. mysql-test/suite/rpl/r/rpl_stm_start_stop_slave.result: Add test case result for Bug#56096. sql/item_func.cc: Reorganize interruptible_wait into a class so that the absolute time can be preserved across calls to the wait function. This allows the sleep to be properly restarted in the presence of spurious wake ups, including those generated by a STOP SLAVE. --- .../extra/rpl_tests/rpl_start_stop_slave.test | 56 +++++++++++ .../rpl/r/rpl_stm_start_stop_slave.result | 22 +++++ sql/item_func.cc | 96 ++++++++++++++----- 3 files changed, 151 insertions(+), 23 deletions(-) diff --git a/mysql-test/extra/rpl_tests/rpl_start_stop_slave.test b/mysql-test/extra/rpl_tests/rpl_start_stop_slave.test index 05836737717..5c99fa1bc74 100644 --- a/mysql-test/extra/rpl_tests/rpl_start_stop_slave.test +++ b/mysql-test/extra/rpl_tests/rpl_start_stop_slave.test @@ -122,4 +122,60 @@ drop table t1i, t2m; sync_slave_with_master; +--echo # +--echo # Bug#56096 STOP SLAVE hangs if executed in parallel with user sleep +--echo # + +--connection master + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1 (a INT ); + +sync_slave_with_master; + +--connection slave1 +--echo # Slave1: lock table for synchronization +LOCK TABLES t1 WRITE; + +--connection master +--echo # Master: insert into the table +INSERT INTO t1 SELECT SLEEP(4); + +--connection slave +--echo # Slave: wait for the insert +let $wait_condition= + SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST + WHERE STATE = "Waiting for table metadata lock" + AND INFO = "INSERT INTO t1 SELECT SLEEP(4)"; +--source include/wait_condition.inc + +--echo # Slave: send slave stop +--send STOP SLAVE + +--connection slave1 +--echo # Slave1: wait for stop slave +let $wait_condition= + SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST + WHERE INFO = "STOP SLAVE"; +--source include/wait_condition.inc + +--echo # Slave1: unlock the table +UNLOCK TABLES; + +--connection slave +--echo # Slave: wait for the slave to stop +--reap +--source include/wait_for_slave_to_stop.inc + +--echo # Start slave again +--source include/start_slave.inc + +--echo # Clean up +--connection master +DROP TABLE t1; +sync_slave_with_master; + # End of tests diff --git a/mysql-test/suite/rpl/r/rpl_stm_start_stop_slave.result b/mysql-test/suite/rpl/r/rpl_stm_start_stop_slave.result index 71ad0177bae..8bb8b0bdf08 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_start_stop_slave.result +++ b/mysql-test/suite/rpl/r/rpl_stm_start_stop_slave.result @@ -43,3 +43,25 @@ one 1 include/start_slave.inc drop table t1i, t2m; +# +# Bug#56096 STOP SLAVE hangs if executed in parallel with user sleep +# +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (a INT ); +# Slave1: lock table for synchronization +LOCK TABLES t1 WRITE; +# Master: insert into the table +INSERT INTO t1 SELECT SLEEP(4); +Warnings: +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system function that may return a different value on the slave. +# Slave: wait for the insert +# Slave: send slave stop +STOP SLAVE; +# Slave1: wait for stop slave +# Slave1: unlock the table +UNLOCK TABLES; +# Slave: wait for the slave to stop +# Start slave again +include/start_slave.inc +# Clean up +DROP TABLE t1; diff --git a/sql/item_func.cc b/sql/item_func.cc index 7906ed71bc7..afb09ff5b17 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -3691,48 +3691,92 @@ longlong Item_master_pos_wait::val_int() } +/** + Enables a session to wait on a condition until a timeout or a network + disconnect occurs. + + @remark The connection is polled every m_interrupt_interval nanoseconds. +*/ + +class Interruptible_wait +{ + THD *m_thd; + struct timespec m_abs_timeout; + static const ulonglong m_interrupt_interval; + + public: + Interruptible_wait(THD *thd) + : m_thd(thd) {} + + ~Interruptible_wait() {} + + public: + /** + Set the absolute timeout. + + @param timeout The amount of time in nanoseconds to wait + */ + void set_timeout(ulonglong timeout) + { + /* + Calculate the absolute system time at the start so it can + be controlled in slices. It relies on the fact that once + the absolute time passes, the timed wait call will fail + automatically with a timeout error. + */ + set_timespec_nsec(m_abs_timeout, timeout); + } + + /** The timed wait. */ + int wait(mysql_cond_t *, mysql_mutex_t *); +}; + + +/** Time to wait before polling the connection status. */ +const ulonglong Interruptible_wait::m_interrupt_interval= 5 * ULL(1000000000); + /** - Wait for a given condition to be signaled within the specified timeout. + Wait for a given condition to be signaled. - @param cond the condition variable to wait on - @param lock the associated mutex - @param abstime the amount of time in seconds to wait + @param cond The condition variable to wait on. + @param mutex The associated mutex. + + @remark The absolute timeout is preserved across calls. @retval return value from mysql_cond_timedwait */ -#define INTERRUPT_INTERVAL (5 * ULL(1000000000)) - -static int interruptible_wait(THD *thd, mysql_cond_t *cond, - mysql_mutex_t *lock, double time) +int Interruptible_wait::wait(mysql_cond_t *cond, mysql_mutex_t *mutex) { int error; - struct timespec abstime; - ulonglong slice, timeout= (ulonglong) (time * 1000000000.0); + struct timespec timeout; - do + while (1) { /* Wait for a fixed interval. */ - if (timeout > INTERRUPT_INTERVAL) - slice= INTERRUPT_INTERVAL; - else - slice= timeout; + set_timespec_nsec(timeout, m_interrupt_interval); - timeout-= slice; - set_timespec_nsec(abstime, slice); - error= mysql_cond_timedwait(cond, lock, &abstime); + /* But only if not past the absolute timeout. */ + if (cmp_timespec(timeout, m_abs_timeout) > 0) + timeout= m_abs_timeout; + + error= mysql_cond_timedwait(cond, mutex, &timeout); if (error == ETIMEDOUT || error == ETIME) { /* Return error if timed out or connection is broken. */ - if (!timeout || !thd->is_connected()) + if (!cmp_timespec(timeout, m_abs_timeout) || !m_thd->is_connected()) break; } - } while (error && timeout); + /* Otherwise, propagate status to the caller. */ + else + break; + } return error; } + /** Get a user level lock. If the thread has an old lock this is first released. @@ -3748,10 +3792,11 @@ longlong Item_func_get_lock::val_int() { DBUG_ASSERT(fixed == 1); String *res=args[0]->val_str(&value); - double timeout= args[1]->val_real(); + ulonglong timeout= args[1]->val_int(); THD *thd=current_thd; User_level_lock *ull; int error; + Interruptible_wait timed_cond(thd); DBUG_ENTER("Item_func_get_lock::val_int"); /* @@ -3812,11 +3857,13 @@ longlong Item_func_get_lock::val_int() thd->mysys_var->current_mutex= &LOCK_user_locks; thd->mysys_var->current_cond= &ull->cond; + timed_cond.set_timeout(timeout * ULL(1000000000)); + error= 0; while (ull->locked && !thd->killed) { DBUG_PRINT("info", ("waiting on lock")); - error= interruptible_wait(thd, &ull->cond, &LOCK_user_locks, timeout); + error= timed_cond.wait(&ull->cond, &LOCK_user_locks); if (error == ETIMEDOUT || error == ETIME) { DBUG_PRINT("info", ("lock wait timeout")); @@ -4011,6 +4058,7 @@ void Item_func_benchmark::print(String *str, enum_query_type query_type) longlong Item_func_sleep::val_int() { THD *thd= current_thd; + Interruptible_wait timed_cond(thd); mysql_cond_t cond; double timeout; int error; @@ -4030,6 +4078,8 @@ longlong Item_func_sleep::val_int() if (timeout < 0.00001) return 0; + timed_cond.set_timeout((ulonglong) (timeout * 1000000000.0)); + mysql_cond_init(key_item_func_sleep_cond, &cond, NULL); mysql_mutex_lock(&LOCK_user_locks); @@ -4040,7 +4090,7 @@ longlong Item_func_sleep::val_int() error= 0; while (!thd->killed) { - error= interruptible_wait(thd, &cond, &LOCK_user_locks, timeout); + error= timed_cond.wait(&cond, &LOCK_user_locks); if (error == ETIMEDOUT || error == ETIME) break; error= 0; From e16a61c6a652941c62e9133cfdb885ec5858cf02 Mon Sep 17 00:00:00 2001 From: Sunny Bains Date: Thu, 14 Oct 2010 14:12:02 +1100 Subject: [PATCH 037/304] Bug# 55681 - MTR slowdown after default storage engine was changed to InnoDB Add new function os_cond_wait_timed(). Change the os_thread_sleep() calls to timed conditional waits. Signal the background threads during the shutdown phase so that we avoid waiting for the sleep to timeout thus saving some time. rb://439 -- Approved by Jimmy Yang --- storage/innobase/include/os0sync.h | 22 +++++ storage/innobase/include/srv0srv.h | 9 ++ storage/innobase/log/log0log.c | 9 +- storage/innobase/os/os0sync.c | 151 +++++++++++++++++++++++++++++ storage/innobase/srv/srv0srv.c | 95 +++++++++++------- 5 files changed, 250 insertions(+), 36 deletions(-) diff --git a/storage/innobase/include/os0sync.h b/storage/innobase/include/os0sync.h index ec5ccee3e27..b294d7421c8 100644 --- a/storage/innobase/include/os0sync.h +++ b/storage/innobase/include/os0sync.h @@ -76,6 +76,12 @@ struct os_event_struct { /*!< list of all created events */ }; +/** Denotes an infinite delay for os_event_wait_time() */ +#define OS_SYNC_INFINITE_TIME ULINT_UNDEFINED + +/** Return value of os_event_wait_time() when the time is exceeded */ +#define OS_SYNC_TIME_EXCEEDED 1 + /** Operating system mutex */ typedef struct os_mutex_struct os_mutex_str_t; /** Operating system mutex handle */ @@ -173,7 +179,23 @@ os_event_wait_low( os_event_reset(). */ #define os_event_wait(event) os_event_wait_low(event, 0) +#define os_event_wait_time(e, t) os_event_wait_time_low(event, t, 0) +/**********************************************************//** +Waits for an event object until it is in the signaled state or +a timeout is exceeded. In Unix the timeout is always infinite. +@return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */ +UNIV_INTERN +ulint +os_event_wait_time_low( +/*===================*/ + os_event_t event, /*!< in: event to wait */ + ulint time_in_usec, /*!< in: timeout in + microseconds, or + OS_SYNC_INFINITE_TIME */ + ib_int64_t reset_sig_count); /*!< in: zero or the value + returned by previous call of + os_event_reset(). */ /*********************************************************//** Creates an operating system mutex semaphore. Because these are slow, the mutex semaphore of InnoDB itself (mutex_t) should be used where possible. diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index 5d2fb808dc9..98b07f5e893 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -57,6 +57,15 @@ extern const char srv_mysql50_table_name_prefix[9]; thread starts running */ extern os_event_t srv_lock_timeout_thread_event; +/* The monitor thread waits on this event. */ +extern os_event_t srv_monitor_event; + +/* The lock timeout thread waits on this event. */ +extern os_event_t srv_timeout_event; + +/* The error monitor thread waits on this event. */ +extern os_event_t srv_error_event; + /* If the last data file is auto-extended, we add this many pages to it at a time */ #define SRV_AUTO_EXTEND_INCREMENT \ diff --git a/storage/innobase/log/log0log.c b/storage/innobase/log/log0log.c index 401cede1d8f..3fef4ee4fc5 100644 --- a/storage/innobase/log/log0log.c +++ b/storage/innobase/log/log0log.c @@ -3098,10 +3098,15 @@ loop: if (srv_fast_shutdown < 2 && (srv_error_monitor_active - || srv_lock_timeout_active || srv_monitor_active)) { + || srv_lock_timeout_active + || srv_monitor_active)) { mutex_exit(&kernel_mutex); + os_event_set(srv_error_event); + os_event_set(srv_monitor_event); + os_event_set(srv_timeout_event); + goto loop; } @@ -3128,6 +3133,8 @@ loop: log_buffer_flush_to_disk(); + mutex_exit(&kernel_mutex); + return; /* We SKIP ALL THE REST !! */ } diff --git a/storage/innobase/os/os0sync.c b/storage/innobase/os/os0sync.c index 3c70e93aae0..975c66ad1e1 100644 --- a/storage/innobase/os/os0sync.c +++ b/storage/innobase/os/os0sync.c @@ -72,6 +72,9 @@ UNIV_INTERN ulint os_event_count = 0; UNIV_INTERN ulint os_mutex_count = 0; UNIV_INTERN ulint os_fast_mutex_count = 0; +/* The number of microsecnds in a second. */ +static const ulint MICROSECS_IN_A_SECOND = 1000000; + /* Because a mutex is embedded inside an event and there is an event embedded inside a mutex, on free, this generates a recursive call. This version of the free event function doesn't acquire the global lock */ @@ -121,6 +124,47 @@ os_cond_init( #endif } +/*********************************************************//** +Do a timed wait on condition variable. +@return TRUE if timed out, FALSE otherwise */ +UNIV_INLINE +ibool +os_cond_wait_timed( +/*===============*/ + os_cond_t* cond, /*!< in: condition variable. */ + os_fast_mutex_t* mutex, /*!< in: fast mutex */ +#ifndef __WIN__ + const struct timespec* abstime /*!< in: timeout */ +#else + ulint time_in_ms /*!< in: timeout in + milliseconds */ +#endif /* !__WIN__ */ +) +{ +#ifdef __WIN__ + BOOL ret; + + ut_a(sleep_condition_variable != NULL); + + ret = sleep_condition_variable(cond, mutex, time_in_ms); + + if (!ret && GetLastError() == WAIT_TIMEOUT) { + return(TRUE); + } + + ut_a(ret); + + return(FALSE); +#else + int ret; + + ret = pthread_cond_timedwait(cond, mutex, abstime); + + ut_a(ret == 0 || ret == ETIMEDOUT); + + return(ret == ETIMEDOUT); +#endif +} /*********************************************************//** Wait on condition variable */ UNIV_INLINE @@ -572,6 +616,113 @@ os_event_wait_low( } } +/**********************************************************//** +Waits for an event object until it is in the signaled state or +a timeout is exceeded. +@return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */ +UNIV_INTERN +ulint +os_event_wait_time_low( +/*===================*/ + os_event_t event, /*!< in: event to wait */ + ulint time_in_usec, /*!< in: timeout in + microseconds, or + OS_SYNC_INFINITE_TIME */ + ib_int64_t reset_sig_count) /*!< in: zero or the value + returned by previous call of + os_event_reset(). */ + +{ + ibool timed_out; + ib_int64_t old_signal_count; + +#ifdef __WIN__ + DWORD time_in_ms = time_in_usec / 1000; + + if (!srv_use_native_conditions) { + DWORD err; + + ut_a(event); + + if (time_in_ms != OS_SYNC_INFINITE_TIME) { + err = WaitForSingleObject(event->handle, time_in_ms); + } else { + err = WaitForSingleObject(event->handle, INFINITE); + } + + if (err == WAIT_OBJECT_0) { + return(0); + } else if (err == WAIT_TIMEOUT) { + return(OS_SYNC_TIME_EXCEEDED); + } + + ut_error; + /* Dummy value to eliminate compiler warning. */ + return(42); + } else { + ut_a(sleep_condition_variable != NULL); + } +#else + struct timeval tv; + ulint sec; + ulint usec; + int ret; + struct timespec abstime; + + ret = ut_usectime(&sec, &usec); + ut_a(ret == 0); + + tv.tv_sec = sec; + tv.tv_usec = usec; + + tv.tv_usec += time_in_usec; + + if ((ulint) tv.tv_usec > MICROSECS_IN_A_SECOND) { + tv.tv_sec += time_in_usec / MICROSECS_IN_A_SECOND; + tv.tv_usec %= MICROSECS_IN_A_SECOND; + } + + /* Convert to nano seconds. We ignore overflow. */ + abstime.tv_sec = tv.tv_sec; + abstime.tv_nsec = tv.tv_usec * 1000; +#endif /* __WIN__ */ + + os_fast_mutex_lock(&event->os_mutex); + + if (reset_sig_count) { + old_signal_count = reset_sig_count; + } else { + old_signal_count = event->signal_count; + } + + do { + if (event->is_set == TRUE + || event->signal_count != old_signal_count) { + + break; + } + + timed_out = os_cond_wait_timed( + &event->cond_var, &event->os_mutex, +#ifndef __WIN__ + &abstime +#else + time_in_ms +#endif /* !__WIN__ */ + ); + + } while (!timed_out); + + os_fast_mutex_unlock(&event->os_mutex); + + if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) { + + os_thread_exit(NULL); + } + + return(timed_out ? OS_SYNC_TIME_EXCEEDED : 0); +} + /*********************************************************//** Creates an operating system mutex semaphore. Because these are slow, the mutex semaphore of InnoDB itself (mutex_t) should be used where possible. diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c index 83355bd1322..2ac5c8ce4fc 100644 --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c @@ -695,6 +695,12 @@ struct srv_slot_struct{ /* Table for MySQL threads where they will be suspended to wait for locks */ UNIV_INTERN srv_slot_t* srv_mysql_table = NULL; +UNIV_INTERN os_event_t srv_timeout_event; + +UNIV_INTERN os_event_t srv_monitor_event; + +UNIV_INTERN os_event_t srv_error_event; + UNIV_INTERN os_event_t srv_lock_timeout_thread_event; UNIV_INTERN srv_sys_t* srv_sys = NULL; @@ -1012,6 +1018,12 @@ srv_init(void) ut_a(slot->event); } + srv_error_event = os_event_create(NULL); + + srv_timeout_event = os_event_create(NULL); + + srv_monitor_event = os_event_create(NULL); + srv_lock_timeout_thread_event = os_event_create(NULL); for (i = 0; i < SRV_MASTER + 1; i++) { @@ -2049,6 +2061,7 @@ srv_monitor_thread( /*!< in: a dummy parameter required by os_thread_create */ { + ib_int64_t sig_count; double time_elapsed; time_t current_time; time_t last_table_monitor_time; @@ -2067,26 +2080,28 @@ srv_monitor_thread( #endif UT_NOT_USED(arg); - srv_last_monitor_time = time(NULL); - last_table_monitor_time = time(NULL); - last_tablespace_monitor_time = time(NULL); - last_monitor_time = time(NULL); + srv_last_monitor_time = ut_time(); + last_table_monitor_time = ut_time(); + last_tablespace_monitor_time = ut_time(); + last_monitor_time = ut_time(); mutex_skipped = 0; last_srv_print_monitor = srv_print_innodb_monitor; loop: srv_monitor_active = TRUE; /* Wake up every 5 seconds to see if we need to print - monitor information. */ + monitor information or if signalled at shutdown. */ - os_thread_sleep(5000000); + sig_count = os_event_reset(srv_monitor_event); - current_time = time(NULL); + os_event_wait_time_low(srv_monitor_event, 5000000, sig_count); + + current_time = ut_time(); time_elapsed = difftime(current_time, last_monitor_time); if (time_elapsed > 15) { - last_monitor_time = time(NULL); + last_monitor_time = ut_time(); if (srv_print_innodb_monitor) { /* Reset mutex_skipped counter everytime @@ -2130,7 +2145,7 @@ loop: if (srv_print_innodb_tablespace_monitor && difftime(current_time, last_tablespace_monitor_time) > 60) { - last_tablespace_monitor_time = time(NULL); + last_tablespace_monitor_time = ut_time(); fputs("========================" "========================\n", @@ -2156,7 +2171,7 @@ loop: if (srv_print_innodb_table_monitor && difftime(current_time, last_table_monitor_time) > 60) { - last_table_monitor_time = time(NULL); + last_table_monitor_time = ut_time(); fputs("===========================================\n", stderr); @@ -2216,16 +2231,20 @@ srv_lock_timeout_thread( ibool some_waits; double wait_time; ulint i; + ib_int64_t sig_count; #ifdef UNIV_PFS_THREAD pfs_register_thread(srv_lock_timeout_thread_key); #endif loop: + /* When someone is waiting for a lock, we wake up every second and check if a timeout has passed for a lock wait */ - os_thread_sleep(1000000); + sig_count = os_event_reset(srv_timeout_event); + + os_event_wait_time_low(srv_timeout_event, 1000000, sig_count); srv_lock_timeout_active = TRUE; @@ -2320,6 +2339,7 @@ srv_error_monitor_thread( ulint fatal_cnt = 0; ib_uint64_t old_lsn; ib_uint64_t new_lsn; + ib_int64_t sig_count; old_lsn = srv_start_lsn; @@ -2395,7 +2415,9 @@ loop: fflush(stderr); - os_thread_sleep(1000000); + sig_count = os_event_reset(srv_error_event); + + os_event_wait_time_low(srv_error_event, 1000000, sig_count); if (srv_shutdown_state < SRV_SHUTDOWN_CLEANUP) { @@ -2646,28 +2668,6 @@ loop: for (i = 0; i < 10; i++) { ulint cur_time = ut_time_ms(); - buf_get_total_stat(&buf_stat); - - n_ios_old = log_sys->n_log_ios + buf_stat.n_pages_read - + buf_stat.n_pages_written; - - srv_main_thread_op_info = "sleeping"; - srv_main_1_second_loops++; - - if (next_itr_time > cur_time) { - - /* Get sleep interval in micro seconds. We use - ut_min() to avoid long sleep in case of - wrap around. */ - os_thread_sleep(ut_min(1000000, - (next_itr_time - cur_time) - * 1000)); - srv_main_sleeps++; - } - - /* Each iteration should happen at 1 second interval. */ - next_itr_time = ut_time_ms() + 1000; - /* ALTER TABLE in MySQL requires on Unix that the table handler can drop tables lazily after there no longer are SELECT queries to them. */ @@ -2683,6 +2683,29 @@ loop: goto background_loop; } + buf_get_total_stat(&buf_stat); + + n_ios_old = log_sys->n_log_ios + buf_stat.n_pages_read + + buf_stat.n_pages_written; + + srv_main_thread_op_info = "sleeping"; + srv_main_1_second_loops++; + + if (next_itr_time > cur_time + && srv_shutdown_state == SRV_SHUTDOWN_NONE) { + + /* Get sleep interval in micro seconds. We use + ut_min() to avoid long sleep in case of + wrap around. */ + os_thread_sleep(ut_min(1000000, + (next_itr_time - cur_time) + * 1000)); + srv_main_sleeps++; + } + + /* Each iteration should happen at 1 second interval. */ + next_itr_time = ut_time_ms() + 1000; + /* Flush logs if needed */ srv_sync_log_buffer_in_background(); @@ -2860,7 +2883,9 @@ background_loop: MySQL tries to drop a table while there are still open handles to it and we had to put it to the background drop queue.) */ - os_thread_sleep(100000); + if (srv_shutdown_state == SRV_SHUTDOWN_NONE) { + os_thread_sleep(100000); + } } if (srv_n_purge_threads == 0) { From 5a57a45c663e460911f204173921cf9981158c14 Mon Sep 17 00:00:00 2001 From: Jon Olav Hauglid Date: Thu, 14 Oct 2010 11:02:37 +0200 Subject: [PATCH 038/304] Follow-up for Bug #55930 Assertion `thd->transaction.stmt.is_empty() || thd->in_sub_stmt || (thd->state.. Don't rollback statement transactions if we are in a sub-statement. This could for example happen for open_ltable() when opening the general log during execution of a stored procedure. --- sql/sql_base.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 8090d8a9288..fe7ec83b845 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -5320,7 +5320,8 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type, end: if (table == NULL) { - trans_rollback_stmt(thd); + if (!thd->in_sub_stmt) + trans_rollback_stmt(thd); close_thread_tables(thd); } thd_proc_info(thd, 0); From f918ad4381a0b3586e780749fb82c3bea3b5a82e Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Thu, 14 Oct 2010 12:28:25 +0300 Subject: [PATCH 039/304] Fix Bug#56143 too many foreign keys causes output of show create table to become invalid This is a port of the following changeset from 5.1/storage/innobase to 5.1/storage/innodb_plugin: ------------------------------------------------------------ revno: 3626 revision-id: vasil.dimov@oracle.com-20101013171859-gi9n558yj89x9v3w parent: klewis@mysql.com-20101012175933-ce9kkgl0z8oeqffa committer: Vasil Dimov branch nick: mysql-5.1-innodb timestamp: Wed 2010-10-13 20:18:59 +0300 message: Fix Bug#56143 too many foreign keys causes output of show create table to become invalid Just remove the check whether the file is "too big". A similar code exists in ha_innobase::update_table_comment() but that method does not seem to be used. Also use a CREATE statement with all the FKs instead of ALTERing the table 550 times because it is faster. --- .../innodb_plugin/r/innodb_bug56143.result | 556 +++++++++++++++++ .../innodb_plugin/t/innodb_bug56143.test | 581 ++++++++++++++++++ storage/innodb_plugin/handler/ha_innodb.cc | 2 - 3 files changed, 1137 insertions(+), 2 deletions(-) create mode 100644 mysql-test/suite/innodb_plugin/r/innodb_bug56143.result create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_bug56143.test diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug56143.result b/mysql-test/suite/innodb_plugin/r/innodb_bug56143.result new file mode 100644 index 00000000000..1efec7e8887 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_bug56143.result @@ -0,0 +1,556 @@ +SHOW CREATE TABLE bug56143_2; +Table Create Table +bug56143_2 CREATE TABLE `bug56143_2` ( + `a` int(11) DEFAULT NULL, + KEY `a` (`a`), + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa10` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa100` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa101` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa102` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa103` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa104` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa105` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa106` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa107` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa108` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa109` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa11` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa110` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa111` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa112` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa113` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa114` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa115` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa116` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa117` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa118` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa119` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa12` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa120` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa121` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa122` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa123` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa124` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa125` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa126` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa127` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa128` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa129` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa13` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa130` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa131` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa132` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa133` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa134` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa135` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa136` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa137` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa138` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa139` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa14` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa140` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa141` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa142` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa143` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa144` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa145` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa146` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa147` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa148` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa149` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa15` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa150` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa151` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa152` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa153` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa154` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa155` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa156` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa157` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa158` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa159` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa16` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa160` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa161` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa162` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa163` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa164` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa165` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa166` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa167` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa168` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa169` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa17` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa170` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa171` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa172` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa173` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa174` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa175` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa176` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa177` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa178` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa179` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa18` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa180` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa181` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa182` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa183` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa184` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa185` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa186` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa187` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa188` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa189` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa19` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa190` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa191` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa192` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa193` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa194` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa195` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa196` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa197` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa198` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa199` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa200` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa201` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa202` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa203` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa204` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa205` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa206` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa207` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa208` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa209` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa21` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa210` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa211` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa212` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa213` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa214` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa215` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa216` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa217` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa218` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa219` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa22` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa220` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa221` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa222` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa223` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa224` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa225` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa226` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa227` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa228` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa229` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa23` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa230` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa231` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa232` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa233` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa234` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa235` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa236` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa237` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa238` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa239` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa24` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa240` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa241` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa242` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa243` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa244` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa245` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa246` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa247` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa248` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa249` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa25` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa250` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa251` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa252` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa253` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa254` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa255` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa256` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa257` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa258` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa259` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa26` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa260` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa261` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa262` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa263` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa264` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa265` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa266` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa267` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa268` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa269` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa27` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa270` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa271` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa272` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa273` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa274` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa275` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa276` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa277` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa278` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa279` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa28` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa280` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa281` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa282` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa283` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa284` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa285` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa286` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa287` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa288` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa289` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa29` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa290` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa291` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa292` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa293` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa294` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa295` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa296` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa297` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa298` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa299` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa30` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa300` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa301` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa302` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa303` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa304` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa305` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa306` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa307` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa308` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa309` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa31` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa310` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa311` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa312` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa313` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa314` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa315` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa316` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa317` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa318` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa319` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa32` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa320` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa321` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa322` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa323` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa324` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa325` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa326` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa327` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa328` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa329` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa33` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa330` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa331` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa332` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa333` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa334` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa335` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa336` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa337` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa338` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa339` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa34` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa340` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa341` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa342` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa343` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa344` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa345` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa346` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa347` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa348` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa349` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa35` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa350` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa351` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa352` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa353` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa354` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa355` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa356` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa357` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa358` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa359` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa36` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa360` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa361` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa362` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa363` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa364` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa365` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa366` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa367` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa368` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa369` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa37` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa370` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa371` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa372` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa373` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa374` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa375` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa376` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa377` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa378` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa379` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa38` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa380` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa381` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa382` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa383` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa384` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa385` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa386` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa387` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa388` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa389` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa39` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa390` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa391` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa392` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa393` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa394` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa395` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa396` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa397` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa398` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa399` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa40` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa400` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa401` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa402` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa403` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa404` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa405` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa406` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa407` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa408` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa409` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa41` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa410` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa411` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa412` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa413` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa414` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa415` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa416` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa417` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa418` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa419` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa42` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa420` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa421` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa422` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa423` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa424` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa425` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa426` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa427` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa428` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa429` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa43` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa430` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa431` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa432` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa433` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa434` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa435` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa436` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa437` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa438` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa439` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa44` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa440` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa441` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa442` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa443` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa444` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa445` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa446` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa447` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa448` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa449` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa45` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa450` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa451` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa452` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa453` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa454` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa455` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa456` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa457` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa458` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa459` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa46` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa460` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa461` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa462` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa463` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa464` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa465` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa466` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa467` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa468` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa469` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa47` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa470` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa471` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa472` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa473` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa474` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa475` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa476` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa477` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa478` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa479` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa48` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa480` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa481` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa482` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa483` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa484` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa485` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa486` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa487` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa488` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa489` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa49` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa490` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa491` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa492` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa493` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa494` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa495` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa496` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa497` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa498` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa499` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa5` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa50` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa500` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa501` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa502` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa503` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa504` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa505` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa506` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa507` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa508` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa509` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa51` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa510` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa511` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa512` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa513` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa514` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa515` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa516` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa517` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa518` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa519` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa52` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa520` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa521` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa522` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa523` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa524` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa525` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa526` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa527` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa528` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa529` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa53` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa530` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa531` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa532` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa533` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa534` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa535` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa536` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa537` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa538` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa539` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa54` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa540` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa541` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa542` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa543` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa544` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa545` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa546` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa547` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa548` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa549` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa55` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa550` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa56` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa57` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa58` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa59` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa6` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa60` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa61` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa62` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa63` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa64` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa65` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa66` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa67` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa68` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa69` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa7` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa70` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa71` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa72` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa73` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa74` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa75` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa76` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa77` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa78` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa79` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa8` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa80` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa81` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa82` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa83` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa84` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa85` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa86` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa87` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa88` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa89` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa90` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa91` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa92` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa93` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa94` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa95` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa96` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa97` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa98` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa99` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug56143.test b/mysql-test/suite/innodb_plugin/t/innodb_bug56143.test new file mode 100644 index 00000000000..7c7472303db --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug56143.test @@ -0,0 +1,581 @@ +# +# Bug#56143 too many foreign keys causes output of show create table to become invalid +# http://bugs.mysql.com/56143 +# + +-- source include/have_innodb_plugin.inc + +-- disable_query_log +-- disable_result_log + +SET foreign_key_checks=0; + +DROP TABLE IF EXISTS bug56143_1; +DROP TABLE IF EXISTS bug56143_2; + +CREATE TABLE bug56143_1 (a INT, KEY(a)) ENGINE=INNODB; + +CREATE TABLE `bug56143_2` ( + `a` int(11) DEFAULT NULL, + KEY `a` (`a`), + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa10` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa100` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa101` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa102` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa103` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa104` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa105` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa106` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa107` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa108` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa109` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa11` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa110` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa111` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa112` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa113` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa114` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa115` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa116` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa117` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa118` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa119` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa12` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa120` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa121` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa122` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa123` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa124` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa125` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa126` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa127` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa128` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa129` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa13` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa130` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa131` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa132` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa133` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa134` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa135` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa136` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa137` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa138` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa139` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa14` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa140` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa141` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa142` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa143` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa144` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa145` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa146` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa147` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa148` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa149` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa15` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa150` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa151` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa152` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa153` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa154` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa155` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa156` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa157` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa158` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa159` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa16` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa160` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa161` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa162` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa163` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa164` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa165` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa166` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa167` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa168` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa169` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa17` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa170` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa171` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa172` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa173` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa174` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa175` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa176` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa177` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa178` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa179` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa18` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa180` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa181` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa182` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa183` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa184` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa185` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa186` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa187` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa188` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa189` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa19` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa190` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa191` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa192` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa193` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa194` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa195` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa196` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa197` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa198` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa199` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa200` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa201` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa202` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa203` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa204` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa205` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa206` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa207` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa208` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa209` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa21` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa210` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa211` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa212` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa213` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa214` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa215` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa216` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa217` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa218` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa219` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa22` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa220` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa221` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa222` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa223` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa224` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa225` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa226` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa227` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa228` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa229` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa23` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa230` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa231` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa232` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa233` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa234` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa235` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa236` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa237` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa238` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa239` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa24` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa240` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa241` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa242` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa243` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa244` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa245` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa246` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa247` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa248` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa249` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa25` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa250` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa251` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa252` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa253` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa254` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa255` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa256` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa257` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa258` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa259` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa26` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa260` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa261` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa262` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa263` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa264` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa265` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa266` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa267` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa268` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa269` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa27` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa270` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa271` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa272` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa273` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa274` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa275` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa276` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa277` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa278` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa279` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa28` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa280` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa281` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa282` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa283` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa284` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa285` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa286` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa287` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa288` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa289` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa29` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa290` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa291` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa292` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa293` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa294` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa295` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa296` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa297` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa298` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa299` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa30` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa300` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa301` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa302` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa303` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa304` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa305` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa306` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa307` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa308` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa309` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa31` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa310` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa311` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa312` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa313` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa314` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa315` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa316` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa317` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa318` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa319` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa32` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa320` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa321` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa322` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa323` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa324` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa325` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa326` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa327` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa328` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa329` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa33` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa330` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa331` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa332` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa333` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa334` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa335` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa336` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa337` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa338` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa339` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa34` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa340` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa341` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa342` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa343` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa344` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa345` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa346` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa347` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa348` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa349` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa35` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa350` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa351` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa352` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa353` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa354` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa355` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa356` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa357` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa358` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa359` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa36` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa360` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa361` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa362` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa363` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa364` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa365` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa366` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa367` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa368` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa369` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa37` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa370` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa371` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa372` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa373` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa374` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa375` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa376` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa377` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa378` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa379` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa38` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa380` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa381` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa382` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa383` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa384` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa385` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa386` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa387` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa388` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa389` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa39` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa390` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa391` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa392` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa393` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa394` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa395` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa396` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa397` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa398` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa399` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa40` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa400` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa401` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa402` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa403` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa404` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa405` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa406` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa407` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa408` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa409` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa41` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa410` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa411` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa412` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa413` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa414` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa415` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa416` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa417` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa418` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa419` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa42` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa420` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa421` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa422` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa423` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa424` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa425` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa426` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa427` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa428` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa429` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa43` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa430` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa431` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa432` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa433` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa434` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa435` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa436` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa437` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa438` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa439` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa44` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa440` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa441` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa442` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa443` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa444` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa445` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa446` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa447` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa448` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa449` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa45` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa450` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa451` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa452` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa453` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa454` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa455` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa456` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa457` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa458` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa459` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa46` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa460` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa461` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa462` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa463` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa464` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa465` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa466` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa467` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa468` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa469` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa47` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa470` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa471` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa472` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa473` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa474` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa475` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa476` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa477` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa478` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa479` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa48` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa480` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa481` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa482` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa483` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa484` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa485` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa486` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa487` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa488` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa489` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa49` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa490` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa491` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa492` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa493` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa494` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa495` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa496` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa497` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa498` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa499` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa5` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa50` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa500` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa501` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa502` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa503` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa504` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa505` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa506` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa507` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa508` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa509` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa51` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa510` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa511` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa512` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa513` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa514` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa515` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa516` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa517` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa518` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa519` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa52` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa520` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa521` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa522` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa523` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa524` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa525` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa526` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa527` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa528` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa529` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa53` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa530` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa531` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa532` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa533` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa534` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa535` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa536` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa537` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa538` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa539` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa54` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa540` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa541` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa542` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa543` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa544` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa545` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa546` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa547` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa548` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa549` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa55` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa550` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa56` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa57` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa58` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa59` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa6` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa60` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa61` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa62` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa63` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa64` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa65` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa66` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa67` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa68` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa69` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa7` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa70` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa71` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa72` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa73` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa74` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa75` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa76` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa77` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa78` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa79` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa8` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa80` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa81` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa82` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa83` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa84` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa85` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa86` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa87` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa88` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa89` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa90` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa91` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa92` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa93` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa94` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa95` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa96` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa97` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa98` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa99` FOREIGN KEY (`a`) REFERENCES `bug56143_1` (`a`) ON UPDATE SET NULL +) ENGINE=InnoDB; + +-- enable_query_log +-- enable_result_log + +SHOW CREATE TABLE bug56143_2; + +-- disable_query_log +-- disable_result_log +DROP TABLE bug56143_1; +DROP TABLE bug56143_2; diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index 9a9cc32c81b..bb6d192bc79 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -8097,8 +8097,6 @@ ha_innobase::get_foreign_key_create_info(void) flen = ftell(srv_dict_tmpfile); if (flen < 0) { flen = 0; - } else if (flen > 64000 - 1) { - flen = 64000 - 1; } /* allocate buffer for the string, and From c8163ef1dc7e1e726303bac8ca9638886e0d51a2 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Thu, 14 Oct 2010 12:33:56 +0300 Subject: [PATCH 040/304] Tune the test for Bug#56143 too many foreign keys causes output of show create table to become invalid Use a CREATE statement with all the FKs instead of ALTERing the table many times because it is faster (11 seconds vs 3 seconds). --- .../suite/innodb/t/innodb_bug56143.test | 566 +++++++++++++++++- 1 file changed, 558 insertions(+), 8 deletions(-) diff --git a/mysql-test/suite/innodb/t/innodb_bug56143.test b/mysql-test/suite/innodb/t/innodb_bug56143.test index 45c174fd280..1218ae6621c 100644 --- a/mysql-test/suite/innodb/t/innodb_bug56143.test +++ b/mysql-test/suite/innodb/t/innodb_bug56143.test @@ -10,14 +10,564 @@ SET foreign_key_checks=0; DROP TABLE IF EXISTS bug56143; -CREATE TABLE bug56143 (a INT, b INT, c INT, KEY(a), KEY(b), KEY(c)) ENGINE=INNODB; - -let $i = 550; -while ($i) -{ - eval ALTER TABLE `bug56143` ADD CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$i` FOREIGN KEY (`b`) REFERENCES `bug56143`(`b`) ON UPDATE SET NULL; - dec $i; -} +CREATE TABLE `bug56143` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + KEY `a` (`a`), + KEY `b` (`b`), + KEY `c` (`c`), + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa10` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa100` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa101` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa102` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa103` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa104` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa105` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa106` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa107` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa108` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa109` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa11` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa110` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa111` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa112` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa113` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa114` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa115` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa116` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa117` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa118` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa119` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa12` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa120` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa121` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa122` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa123` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa124` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa125` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa126` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa127` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa128` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa129` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa13` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa130` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa131` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa132` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa133` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa134` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa135` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa136` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa137` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa138` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa139` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa14` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa140` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa141` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa142` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa143` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa144` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa145` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa146` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa147` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa148` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa149` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa15` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa150` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa151` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa152` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa153` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa154` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa155` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa156` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa157` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa158` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa159` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa16` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa160` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa161` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa162` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa163` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa164` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa165` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa166` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa167` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa168` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa169` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa17` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa170` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa171` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa172` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa173` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa174` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa175` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa176` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa177` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa178` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa179` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa18` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa180` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa181` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa182` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa183` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa184` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa185` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa186` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa187` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa188` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa189` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa19` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa190` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa191` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa192` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa193` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa194` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa195` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa196` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa197` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa198` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa199` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa200` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa201` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa202` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa203` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa204` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa205` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa206` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa207` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa208` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa209` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa21` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa210` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa211` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa212` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa213` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa214` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa215` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa216` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa217` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa218` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa219` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa22` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa220` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa221` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa222` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa223` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa224` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa225` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa226` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa227` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa228` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa229` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa23` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa230` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa231` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa232` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa233` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa234` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa235` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa236` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa237` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa238` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa239` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa24` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa240` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa241` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa242` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa243` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa244` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa245` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa246` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa247` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa248` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa249` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa25` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa250` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa251` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa252` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa253` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa254` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa255` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa256` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa257` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa258` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa259` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa26` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa260` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa261` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa262` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa263` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa264` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa265` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa266` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa267` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa268` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa269` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa27` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa270` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa271` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa272` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa273` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa274` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa275` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa276` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa277` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa278` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa279` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa28` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa280` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa281` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa282` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa283` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa284` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa285` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa286` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa287` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa288` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa289` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa29` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa290` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa291` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa292` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa293` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa294` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa295` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa296` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa297` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa298` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa299` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa30` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa300` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa301` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa302` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa303` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa304` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa305` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa306` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa307` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa308` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa309` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa31` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa310` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa311` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa312` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa313` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa314` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa315` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa316` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa317` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa318` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa319` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa32` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa320` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa321` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa322` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa323` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa324` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa325` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa326` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa327` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa328` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa329` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa33` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa330` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa331` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa332` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa333` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa334` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa335` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa336` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa337` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa338` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa339` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa34` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa340` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa341` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa342` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa343` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa344` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa345` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa346` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa347` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa348` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa349` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa35` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa350` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa351` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa352` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa353` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa354` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa355` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa356` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa357` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa358` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa359` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa36` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa360` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa361` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa362` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa363` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa364` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa365` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa366` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa367` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa368` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa369` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa37` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa370` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa371` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa372` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa373` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa374` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa375` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa376` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa377` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa378` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa379` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa38` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa380` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa381` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa382` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa383` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa384` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa385` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa386` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa387` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa388` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa389` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa39` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa390` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa391` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa392` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa393` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa394` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa395` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa396` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa397` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa398` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa399` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa40` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa400` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa401` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa402` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa403` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa404` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa405` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa406` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa407` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa408` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa409` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa41` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa410` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa411` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa412` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa413` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa414` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa415` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa416` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa417` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa418` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa419` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa42` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa420` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa421` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa422` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa423` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa424` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa425` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa426` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa427` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa428` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa429` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa43` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa430` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa431` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa432` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa433` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa434` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa435` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa436` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa437` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa438` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa439` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa44` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa440` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa441` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa442` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa443` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa444` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa445` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa446` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa447` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa448` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa449` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa45` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa450` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa451` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa452` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa453` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa454` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa455` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa456` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa457` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa458` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa459` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa46` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa460` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa461` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa462` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa463` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa464` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa465` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa466` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa467` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa468` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa469` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa47` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa470` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa471` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa472` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa473` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa474` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa475` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa476` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa477` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa478` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa479` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa48` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa480` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa481` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa482` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa483` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa484` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa485` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa486` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa487` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa488` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa489` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa49` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa490` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa491` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa492` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa493` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa494` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa495` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa496` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa497` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa498` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa499` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa5` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa50` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa500` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa501` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa502` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa503` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa504` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa505` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa506` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa507` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa508` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa509` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa51` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa510` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa511` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa512` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa513` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa514` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa515` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa516` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa517` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa518` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa519` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa52` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa520` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa521` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa522` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa523` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa524` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa525` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa526` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa527` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa528` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa529` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa53` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa530` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa531` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa532` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa533` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa534` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa535` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa536` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa537` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa538` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa539` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa54` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa540` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa541` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa542` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa543` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa544` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa545` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa546` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa547` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa548` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa549` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa55` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa550` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa56` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa57` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa58` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa59` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa6` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa60` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa61` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa62` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa63` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa64` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa65` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa66` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa67` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa68` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa69` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa7` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa70` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa71` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa72` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa73` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa74` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa75` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa76` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa77` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa78` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa79` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa8` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa80` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa81` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa82` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa83` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa84` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa85` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa86` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa87` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa88` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa89` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa90` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa91` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa92` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa93` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa94` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa95` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa96` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa97` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa98` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL, + CONSTRAINT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa99` FOREIGN KEY (`b`) REFERENCES `bug56143` (`b`) ON UPDATE SET NULL +) ENGINE=InnoDB; -- enable_query_log -- enable_result_log From 650e4c25db94273bdf2300ddb987294f0d4edd72 Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Thu, 14 Oct 2010 14:05:59 +0400 Subject: [PATCH 041/304] A patch for Bug#48874 (Test "is_triggers" fails because of wrong charset info). The thing is that the following attributes are fixed (remembered) when a trigger is created: - character_set_client - character_set_results - collation_connection There are two triggers created in mysql-test/include/mtr_warnings.sql. They were created using "current default" character set / collation. is_triggers.test shows definition of these triggers including recorded character set information. The problem was that if "current default" changed, the recorded character set information was not accurate. There might be two ways to fix that: a) update is_triggers.test so that it does not put character-set information into result-file; b) update mtr_warnings.sql so that the triggers are created using hard-coded character sets. This patch implements option b). --- mysql-test/include/mtr_warnings.sql | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/mysql-test/include/mtr_warnings.sql b/mysql-test/include/mtr_warnings.sql index bf0a58788d6..f793ff54e86 100644 --- a/mysql-test/include/mtr_warnings.sql +++ b/mysql-test/include/mtr_warnings.sql @@ -16,6 +16,12 @@ CREATE TABLE test_suppressions ( -- no invalid patterns can be inserted -- into test_suppressions -- +SET @character_set_client_saved = @@character_set_client|| +SET @character_set_results_saved = @@character_set_results|| +SET @collation_connection_saved = @@collation_connection|| +SET @@character_set_client = latin1|| +SET @@character_set_results = latin1|| +SET @@collation_connection = latin1_swedish_ci|| /*!50002 CREATE DEFINER=root@localhost TRIGGER ts_insert BEFORE INSERT ON test_suppressions @@ -24,6 +30,9 @@ FOR EACH ROW BEGIN SELECT "" REGEXP NEW.pattern INTO dummy; END */|| +SET @@character_set_client = @character_set_client_saved|| +SET @@character_set_results = @character_set_results_saved|| +SET @@collation_connection = @collation_connection_saved|| -- @@ -38,6 +47,12 @@ CREATE TABLE global_suppressions ( -- no invalid patterns can be inserted -- into global_suppressions -- +SET @character_set_client_saved = @@character_set_client|| +SET @character_set_results_saved = @@character_set_results|| +SET @collation_connection_saved = @@collation_connection|| +SET @@character_set_client = latin1|| +SET @@character_set_results = latin1|| +SET @@collation_connection = latin1_swedish_ci|| /*!50002 CREATE DEFINER=root@localhost TRIGGER gs_insert BEFORE INSERT ON global_suppressions @@ -46,6 +61,9 @@ FOR EACH ROW BEGIN SELECT "" REGEXP NEW.pattern INTO dummy; END */|| +SET @@character_set_client = @character_set_client_saved|| +SET @@character_set_results = @character_set_results_saved|| +SET @@collation_connection = @collation_connection_saved|| From 27c80dd4242be8a04c17df5a4235ac6a5de45635 Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Thu, 14 Oct 2010 04:19:52 -0700 Subject: [PATCH 042/304] Remove an unused counter variable in io_handler_thread(). --- storage/innodb_plugin/srv/srv0start.c | 1 - 1 file changed, 1 deletion(-) diff --git a/storage/innodb_plugin/srv/srv0start.c b/storage/innodb_plugin/srv/srv0start.c index 2d339596013..f823b72fbc1 100644 --- a/storage/innodb_plugin/srv/srv0start.c +++ b/storage/innodb_plugin/srv/srv0start.c @@ -463,7 +463,6 @@ io_handler_thread( the aio array */ { ulint segment; - ulint i; segment = *((ulint*)arg); From 248625d910dda9848c99f28c5c73c4e4a9bfc4ae Mon Sep 17 00:00:00 2001 From: Konstantin Osipov Date: Thu, 14 Oct 2010 20:56:56 +0400 Subject: [PATCH 043/304] A fix and a test case for Bug#56540 "Exception (crash) in sql_show.cc during rqg_info_schema test on Windows". Ensure we do not access freed memory when filling information_schema.views when one of the views could not be properly opened. mysql-test/r/information_schema.result: Update results - a fix for Bug#56540. mysql-test/t/information_schema.test: Add a test case for Bug#56540 sql/sql_base.cc: Push an error into the Diagnostics area when we return an error. This directs get_all_tables() to the execution branch which doesn't involve 'process_table()' when no table/view was opened. sql/sql_show.cc: Do not try to access underlying table fields when opening of a view failed. The underlying table is closed in that case, and accessing its fields may lead to dereferencing a damaged pointer. --- mysql-test/r/information_schema.result | 44 +++++++++++++++++++++ mysql-test/t/information_schema.test | 53 ++++++++++++++++++++++++++ sql/sql_base.cc | 10 ++++- sql/sql_show.cc | 25 ++++++++---- 4 files changed, 124 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index aa47b8c437e..bab60774b32 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -1807,3 +1807,47 @@ USING (TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME) WHERE COLUMNS.TABLE_SCHEMA = 'test' AND COLUMNS.TABLE_NAME = 't1'; TABLE_SCHEMA TABLE_NAME COLUMN_NAME CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_CATALOG ORDINAL_POSITION POSITION_IN_UNIQUE_CONSTRAINT REFERENCED_TABLE_SCHEMA REFERENCED_TABLE_NAME REFERENCED_COLUMN_NAME TABLE_CATALOG ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT +# +# A test case for Bug#56540 "Exception (crash) in sql_show.cc +# during rqg_info_schema test on Windows" +# Ensure that we never access memory of a closed table, +# in particular, never access table->field[] array. +# Before the fix, the below test case, produced +# valgrind errors. +# +drop table if exists t1; +drop view if exists v1; +create table t1 (a int, b int); +create view v1 as select t1.a, t1.b from t1; +alter table t1 change b c int; +lock table t1 read; +# --> connection con1 +flush tables; +# --> connection default +select * from information_schema.views; +TABLE_CATALOG def +TABLE_SCHEMA test +TABLE_NAME v1 +VIEW_DEFINITION select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` +CHECK_OPTION NONE +IS_UPDATABLE +DEFINER root@localhost +SECURITY_TYPE DEFINER +CHARACTER_SET_CLIENT latin1 +COLLATION_CONNECTION latin1_swedish_ci +Warnings: +Level Warning +Code 1356 +Message View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them +unlock tables; +# +# Cleanup. +# +# --> connection con1 +# Reaping 'flush tables' +# --> connection default +drop table t1; +drop view v1; +# +# End of 5.5 tests +# diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index f5fab966bdd..bc73e8411ca 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -1555,3 +1555,56 @@ WHERE COLUMNS.TABLE_SCHEMA = 'test' AND COLUMNS.TABLE_NAME = 't1'; +--echo # +--echo # A test case for Bug#56540 "Exception (crash) in sql_show.cc +--echo # during rqg_info_schema test on Windows" +--echo # Ensure that we never access memory of a closed table, +--echo # in particular, never access table->field[] array. +--echo # Before the fix, the below test case, produced +--echo # valgrind errors. +--echo # + +--disable_warnings +drop table if exists t1; +drop view if exists v1; +--enable_warnings + +create table t1 (a int, b int); +create view v1 as select t1.a, t1.b from t1; +alter table t1 change b c int; +lock table t1 read; +connect(con1, localhost, root,,); +--echo # --> connection con1 +connection con1; +send flush tables; +--echo # --> connection default +connection default; +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for table flush" and + info = "flush tables"; +--source include/wait_condition.inc +--vertical_results +select * from information_schema.views; +--horizontal_results +unlock tables; + +--echo # +--echo # Cleanup. +--echo # + +--echo # --> connection con1 +connection con1; +--echo # Reaping 'flush tables' +reap; +disconnect con1; +--source include/wait_until_disconnected.inc +--echo # --> connection default +connection default; +drop table t1; +drop view v1; + + +--echo # +--echo # End of 5.5 tests +--echo # diff --git a/sql/sql_base.cc b/sql/sql_base.cc index fe7ec83b845..8caae3ee406 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2902,8 +2902,12 @@ retry_share: */ if (check_and_update_table_version(thd, table_list, share)) goto err_unlock; - if (table_list->i_s_requested_object & OPEN_TABLE_ONLY) + if (table_list->i_s_requested_object & OPEN_TABLE_ONLY) + { + my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, + table_list->table_name); goto err_unlock; + } /* Open view */ if (open_new_frm(thd, share, alias, @@ -2931,7 +2935,11 @@ retry_share: */ if (table_list->i_s_requested_object & OPEN_VIEW_ONLY) + { + my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, + table_list->table_name); goto err_unlock; + } if (!(flags & MYSQL_OPEN_IGNORE_FLUSH)) { diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 16deb50b17c..a25cfcdedc8 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4934,18 +4934,29 @@ static int get_schema_views_record(THD *thd, TABLE_LIST *tables, else table->field[4]->store(STRING_WITH_LEN("NONE"), cs); - if (table->pos_in_table_list->table_open_method & - OPEN_FULL_TABLE) + /* + Only try to fill in the information about view updatability + if it is requested as part of the top-level query (i.e. + it's select * from i_s.views, as opposed to, say, select + security_type from i_s.views). Do not try to access the + underlying tables if there was an error when opening the + view: all underlying tables are released back to the table + definition cache on error inside open_normal_and_derived_tables(). + If a field is not assigned explicitly, it defaults to NULL. + */ + if (res == FALSE && + table->pos_in_table_list->table_open_method & OPEN_FULL_TABLE) { updatable_view= 0; if (tables->algorithm != VIEW_ALGORITHM_TMPTABLE) { /* - We should use tables->view->select_lex.item_list here and - can not use Field_iterator_view because the view always uses - temporary algorithm during opening for I_S and - TABLE_LIST fields 'field_translation' & 'field_translation_end' - are uninitialized is this case. + We should use tables->view->select_lex.item_list here + and can not use Field_iterator_view because the view + always uses temporary algorithm during opening for I_S + and TABLE_LIST fields 'field_translation' + & 'field_translation_end' are uninitialized is this + case. */ List *fields= &tables->view->select_lex.item_list; List_iterator it(*fields); From 3ce802d5d8ef92469bf5eeec649c2dca55ac4944 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Fri, 15 Oct 2010 17:26:58 +0300 Subject: [PATCH 044/304] Fix the formatting in storage/innodb_plugin/ChangeLog --- storage/innodb_plugin/ChangeLog | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index d193dcd321c..69506b621f2 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,36 +1,39 @@ 2010-10-14 The InnoDB Team - * srv/srv0start.c - Fix Bug #57397 io_handler_thread() will never cleanup + + * srv/srv0start.c: + Fix Bug#57397 io_handler_thread() will never cleanup 2010-10-11 The InnoDB Team - * row/row0sel.c - Fix Bug #57345 btr_pcur_store_position abort for load with - concurrent lock/unlock tables + + * row/row0sel.c: + Fix Bug#57345 btr_pcur_store_position abort for load with concurrent + lock/unlock tables 2010-09-27 The InnoDB Team * row/row0sel.c, innodb_bug56716.result, innodb_bug56716.test: - Fix Bug #56716 InnoDB locks a record gap without locking the table + Fix Bug#56716 InnoDB locks a record gap without locking the table 2010-09-06 The InnoDB Team - * dict/dict0load.c, innodb_bug53756.test innodb_bug53756.result - Fix Bug #53756 ALTER TABLE ADD PRIMARY KEY affects crash recovery + + * dict/dict0load.c, innodb_bug53756.test innodb_bug53756.result: + Fix Bug#53756 ALTER TABLE ADD PRIMARY KEY affects crash recovery 2010-08-24 The InnoDB Team * handler/ha_innodb.c, dict/dict0dict.c: - Fix Bug #55832 selects crash too easily when innodb_force_recovery>3 + Fix Bug#55832 selects crash too easily when innodb_force_recovery>3 2010-08-03 The InnoDB Team * include/ut0mem.h, ut/ut0mem.c: - Fix Bug #55627 segv in ut_free pars_lexer_close innobase_shutdown + Fix Bug#55627 segv in ut_free pars_lexer_close innobase_shutdown innodb-use-sys-malloc=0 2010-08-01 The InnoDB Team - * handler/ha_innodb.cc - Fix Bug #55382 Assignment with SELECT expressions takes unexpected + * handler/ha_innodb.cc: + Fix Bug#55382 Assignment with SELECT expressions takes unexpected S locks in READ COMMITTED 2010-07-27 The InnoDB Team @@ -52,8 +55,8 @@ 2010-06-29 The InnoDB Team - * btr/btr0cur.c, include/btr0cur.h, - include/row0mysql.h, row/row0merge.c, row/row0sel.c: + * btr/btr0cur.c, include/btr0cur.h, include/row0mysql.h, + row/row0merge.c, row/row0sel.c: Fix Bug#54358 READ UNCOMMITTED access failure of off-page DYNAMIC or COMPRESSED columns From 74b42d8daad141cab6bb4933708e990d4b9d5f11 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Fri, 15 Oct 2010 17:30:32 +0300 Subject: [PATCH 045/304] Add InnoDB Plugin ChangeLog entry for Bug#56143 --- storage/innodb_plugin/ChangeLog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 69506b621f2..4441d30420f 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,9 @@ +2010-10-14 The InnoDB Team + + * handler/ha_innodb.cc, innodb_bug56143.result, innodb_bug56143.test: + Fix Bug#56143 too many foreign keys causes output of show create + table to become invalid + 2010-10-14 The InnoDB Team * srv/srv0start.c: From ef858cc463983629394c4aa9a6be3aaeaa585fd6 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Fri, 15 Oct 2010 17:50:45 +0300 Subject: [PATCH 046/304] Remove leftover conflict marker It was added in jimmy.yang@oracle.com-20100902004302-m5ax9qo0ne2msdfx --- storage/innodb_plugin/ChangeLog | 1 - 1 file changed, 1 deletion(-) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index e2aa279dc9b..0adb71fcba2 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -54,7 +54,6 @@ * handler/ha_innodb.cc: Fix Bug#55382 Assignment with SELECT expressions takes unexpected S locks in READ COMMITTED ->>>>>>> MERGE-SOURCE 2010-07-27 The InnoDB Team From 211552ccee98e381a14dfaae754528d9f6ed0494 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 16 Oct 2010 20:03:44 +0800 Subject: [PATCH 047/304] Bug#56118 STOP SLAVE does not wait till trx with CREATE TMP TABLE ends, replication aborts When recieving a 'SLAVE STOP' command, slave SQL thread will roll back the transaction and stop immidiately if there is only transactional table updated, even through 'CREATE|DROP TEMPOARY TABLE' statement are in it. But These statements can never be rolled back. Because the temporary tables to the user session mapping remain until 'RESET SLAVE', Therefore it will abort SQL thread with an error that the table already exists or doesn't exist, when it restarts and executes the whole transaction again. After this patch, SQL thread always waits till the transaction ends and then stops, if 'CREATE|DROP TEMPOARY TABLE' statement are in it. mysql-test/extra/rpl_tests/rpl_stop_slave.test: Auxiliary file which is used to test this bug. mysql-test/suite/rpl/t/rpl_stop_slave.test: Test case for this bug. sql/slave.cc: Checking if OPTION_KEEP_LOG is set. If it is set, SQL thread should wait until the transaction ends. sql/sql_parse.cc: Add a debug point for testing this bug. --- .../extra/rpl_tests/rpl_stop_slave.test | 61 +++++++++ mysql-test/suite/rpl/r/rpl_stop_slave.result | 127 ++++++++++++++++++ mysql-test/suite/rpl/t/rpl_stop_slave.test | 60 +++++++++ sql/slave.cc | 11 +- sql/sql_parse.cc | 10 ++ 5 files changed, 268 insertions(+), 1 deletion(-) create mode 100644 mysql-test/extra/rpl_tests/rpl_stop_slave.test create mode 100644 mysql-test/suite/rpl/r/rpl_stop_slave.result create mode 100644 mysql-test/suite/rpl/t/rpl_stop_slave.test diff --git a/mysql-test/extra/rpl_tests/rpl_stop_slave.test b/mysql-test/extra/rpl_tests/rpl_stop_slave.test new file mode 100644 index 00000000000..7c88afe3532 --- /dev/null +++ b/mysql-test/extra/rpl_tests/rpl_stop_slave.test @@ -0,0 +1,61 @@ +# +# Auxiliary file which is used to test BUG#56118 +# +# Slave should apply all statements in the transaction before stop if any +# temporary table is created or dropped. +# +# USEAGE: +# --let $tmp_table_stm= a SQL statement +# --source extra/rpl_tests/rpl_stop_slave.test +# + +if (`SELECT "$tmp_table_stm" = ''`) +{ + --echo \$tmp_table_stm is NULL + --die $tmp_table_stm is NULL +} + +--echo +--echo [ On Master ] +connection master; +BEGIN; +DELETE FROM t1; +eval $tmp_table_stm; +INSERT INTO t1 VALUES (1); +DROP TEMPORARY TABLE tt1; +COMMIT; + +--echo +--echo [ On Slave ] +connection slave; + +# To check if slave SQL thread is applying INSERT statement +let $show_statement= SHOW PROCESSLIST; +let $field= Info; +let $condition= LIKE 'INSERT%'; +source include/wait_show_condition.inc; + +send STOP SLAVE SQL_THREAD; + +--echo +--echo [ On Slave1 ] +connection slave1; +--echo # To resume slave SQL thread +SET DEBUG_SYNC= 'now SIGNAL signal.continue'; +SET DEBUG_SYNC= 'RESET'; + +--echo +--echo [ On Slave ] +connection slave; +reap; +source include/wait_for_slave_sql_to_stop.inc; + +--echo # Slave should stop after the transaction has committed. +--echo # So t1 on master is same to t1 on slave. +let diff_table_1=master:test.t1; +let diff_table_2=slave:test.t1; +source include/diff_tables.inc; + +connection slave; +START SLAVE SQL_THREAD; +source include/wait_for_slave_sql_to_start.inc; diff --git a/mysql-test/suite/rpl/r/rpl_stop_slave.result b/mysql-test/suite/rpl/r/rpl_stop_slave.result new file mode 100644 index 00000000000..49146417ab7 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_stop_slave.result @@ -0,0 +1,127 @@ +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; + +# BUG#56118 STOP SLAVE does not wait till trx with CREATE TMP TABLE ends +# +# If a temporary table is created or dropped, the transaction should be +# regarded similarly that a non-transactional table is modified. So +# STOP SLAVE should wait until the transaction has finished. +CREATE TABLE t1(c1 INT) ENGINE=InnoDB; +CREATE TABLE t2(c1 INT) ENGINE=InnoDB; +SET DEBUG_SYNC= 'RESET'; +include/stop_slave.inc + +# Suspend the INSERT statement in current transaction on SQL thread. +# It guarantees that SQL thread is applying the transaction when +# STOP SLAVE command launchs. +SET GLOBAL debug= 'd,after_mysql_insert'; +include/start_slave.inc + +# CREATE TEMPORARY TABLE with InnoDB engine +# ----------------------------------------- + +[ On Master ] +BEGIN; +DELETE FROM t1; +CREATE TEMPORARY TABLE tt1(c1 INT) ENGINE = InnoDB; +INSERT INTO t1 VALUES (1); +DROP TEMPORARY TABLE tt1; +COMMIT; + +[ On Slave ] +STOP SLAVE SQL_THREAD; + +[ On Slave1 ] +# To resume slave SQL thread +SET DEBUG_SYNC= 'now SIGNAL signal.continue'; +SET DEBUG_SYNC= 'RESET'; + +[ On Slave ] +# Slave should stop after the transaction has committed. +# So t1 on master is same to t1 on slave. +Comparing tables master:test.t1 and slave:test.t1 +START SLAVE SQL_THREAD; + +# CREATE TEMPORARY TABLE with MyISAM engine +# ----------------------------------------- + +[ On Master ] +BEGIN; +DELETE FROM t1; +CREATE TEMPORARY TABLE tt1(c1 INT) ENGINE = MyISAM; +INSERT INTO t1 VALUES (1); +DROP TEMPORARY TABLE tt1; +COMMIT; + +[ On Slave ] +STOP SLAVE SQL_THREAD; + +[ On Slave1 ] +# To resume slave SQL thread +SET DEBUG_SYNC= 'now SIGNAL signal.continue'; +SET DEBUG_SYNC= 'RESET'; + +[ On Slave ] +# Slave should stop after the transaction has committed. +# So t1 on master is same to t1 on slave. +Comparing tables master:test.t1 and slave:test.t1 +START SLAVE SQL_THREAD; + +# CREATE TEMPORARY TABLE ... SELECT with InnoDB engine +# ---------------------------------------------------- + +[ On Master ] +BEGIN; +DELETE FROM t1; +CREATE TEMPORARY TABLE tt1(c1 INT) ENGINE = InnoDB +SELECT c1 FROM t2; +INSERT INTO t1 VALUES (1); +DROP TEMPORARY TABLE tt1; +COMMIT; + +[ On Slave ] +STOP SLAVE SQL_THREAD; + +[ On Slave1 ] +# To resume slave SQL thread +SET DEBUG_SYNC= 'now SIGNAL signal.continue'; +SET DEBUG_SYNC= 'RESET'; + +[ On Slave ] +# Slave should stop after the transaction has committed. +# So t1 on master is same to t1 on slave. +Comparing tables master:test.t1 and slave:test.t1 +START SLAVE SQL_THREAD; + +# CREATE TEMPORARY TABLE ... SELECT with MyISAM engine +# ---------------------------------------------------- + +[ On Master ] +BEGIN; +DELETE FROM t1; +CREATE TEMPORARY TABLE tt1(c1 INT) ENGINE = MyISAM +SELECT 1 AS c1; +INSERT INTO t1 VALUES (1); +DROP TEMPORARY TABLE tt1; +COMMIT; + +[ On Slave ] +STOP SLAVE SQL_THREAD; + +[ On Slave1 ] +# To resume slave SQL thread +SET DEBUG_SYNC= 'now SIGNAL signal.continue'; +SET DEBUG_SYNC= 'RESET'; + +[ On Slave ] +# Slave should stop after the transaction has committed. +# So t1 on master is same to t1 on slave. +Comparing tables master:test.t1 and slave:test.t1 +START SLAVE SQL_THREAD; +# Test end +SET GLOBAL debug= '$debug_save'; +DROP TABLE t1, t2; diff --git a/mysql-test/suite/rpl/t/rpl_stop_slave.test b/mysql-test/suite/rpl/t/rpl_stop_slave.test new file mode 100644 index 00000000000..e44cf3e94b7 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_stop_slave.test @@ -0,0 +1,60 @@ +source include/master-slave.inc; +source include/have_innodb.inc; +source include/have_debug.inc; +source include/have_debug_sync.inc; +source include/have_binlog_format_mixed_or_statement.inc; + +--echo +--echo # BUG#56118 STOP SLAVE does not wait till trx with CREATE TMP TABLE ends +--echo # +--echo # If a temporary table is created or dropped, the transaction should be +--echo # regarded similarly that a non-transactional table is modified. So +--echo # STOP SLAVE should wait until the transaction has finished. + +CREATE TABLE t1(c1 INT) ENGINE=InnoDB; +CREATE TABLE t2(c1 INT) ENGINE=InnoDB; + +sync_slave_with_master; +SET DEBUG_SYNC= 'RESET'; +source include/stop_slave.inc; + +--echo +--echo # Suspend the INSERT statement in current transaction on SQL thread. +--echo # It guarantees that SQL thread is applying the transaction when +--echo # STOP SLAVE command launchs. +let $debug_save= `SELECT @@GLOBAL.debug`; +SET GLOBAL debug= 'd,after_mysql_insert'; +source include/start_slave.inc; + +--echo +--echo # CREATE TEMPORARY TABLE with InnoDB engine +--echo # ----------------------------------------- +let $tmp_table_stm= CREATE TEMPORARY TABLE tt1(c1 INT) ENGINE = InnoDB; +source extra/rpl_tests/rpl_stop_slave.test; + +--echo +--echo # CREATE TEMPORARY TABLE with MyISAM engine +--echo # ----------------------------------------- +let $tmp_table_stm= CREATE TEMPORARY TABLE tt1(c1 INT) ENGINE = MyISAM; +source extra/rpl_tests/rpl_stop_slave.test; + +--echo +--echo # CREATE TEMPORARY TABLE ... SELECT with InnoDB engine +--echo # ---------------------------------------------------- +let $tmp_table_stm= CREATE TEMPORARY TABLE tt1(c1 INT) ENGINE = InnoDB + SELECT c1 FROM t2; +source extra/rpl_tests/rpl_stop_slave.test; + +--echo +--echo # CREATE TEMPORARY TABLE ... SELECT with MyISAM engine +--echo # ---------------------------------------------------- +let $tmp_table_stm= CREATE TEMPORARY TABLE tt1(c1 INT) ENGINE = MyISAM + SELECT 1 AS c1; +source extra/rpl_tests/rpl_stop_slave.test; + +--echo # Test end +SET GLOBAL debug= '$debug_save'; + +connection master; +DROP TABLE t1, t2; +source include/master-slave-end.inc; diff --git a/sql/slave.cc b/sql/slave.cc index 964adfdbf53..57d673ea1f4 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -740,8 +740,17 @@ static bool sql_slave_killed(THD* thd, Relay_log_info* rli) DBUG_ASSERT(rli->slave_running == 1);// tracking buffer overrun if (abort_loop || thd->killed || rli->abort_slave) { + /* + The transaction should always be binlogged if OPTION_KEEP_LOG is set + (it implies that something can not be rolled back). And such case + should be regarded similarly as modifing a non-transactional table + because retrying of the transaction will lead to an error or inconsistency + as well. + Example: OPTION_KEEP_LOG is set if a temporary table is created or dropped. + */ if (rli->abort_slave && rli->is_in_group() && - thd->transaction.all.modified_non_trans_table) + (thd->transaction.all.modified_non_trans_table || + (thd->options & OPTION_KEEP_LOG))) DBUG_RETURN(0); /* If we are in an unsafe situation (stopping could corrupt replication), diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index fbe9c9753d9..b38cdf4a983 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -27,6 +27,7 @@ #include "sp_cache.h" #include "events.h" #include "sql_trigger.h" +#include "debug_sync.h" /** @defgroup Runtime_Environment Runtime Environment @@ -3258,6 +3259,15 @@ end_with_restore_list: thd->first_successful_insert_id_in_cur_stmt= thd->first_successful_insert_id_in_prev_stmt; + DBUG_EXECUTE_IF("after_mysql_insert", + { + const char act[]= + "now " + "wait_for signal.continue"; + DBUG_ASSERT(opt_debug_sync_timeout > 0); + DBUG_ASSERT(!debug_sync_set_action(current_thd, + STRING_WITH_LEN(act))); + };); break; } case SQLCOM_REPLACE_SELECT: From e548c322c200d4e115793e52bfda7c314f9842e8 Mon Sep 17 00:00:00 2001 From: Kristofer Pettersson Date: Sun, 17 Oct 2010 13:00:13 +0200 Subject: [PATCH 048/304] Bug#57359 Possible to circumvent secure_file_priv using '..' on Windows Where realpath(3) is used in Linux, mf_load_path is used for Windows. This function doesn't however correspond to the functionality of realpath. This patch attempts to do better by using the Windows function GetFullPathName() instead. --- mysys/my_symlink.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/mysys/my_symlink.c b/mysys/my_symlink.c index 258e227bb7b..b57edd2179a 100644 --- a/mysys/my_symlink.c +++ b/mysys/my_symlink.c @@ -113,7 +113,6 @@ int my_is_symlink(const char *filename __attribute__((unused))) #endif } - /* Resolve all symbolic links in path 'to' may be equal to 'filename' @@ -146,8 +145,24 @@ int my_realpath(char *to, const char *filename, result= -1; } DBUG_RETURN(result); +#else +#ifdef _WIN32 + int ret= GetFullPathName(filename,FN_REFLEN, + to, + NULL); + if (ret == 0 || ret > FN_REFLEN) + { + if (ret > FN_REFLEN) + my_errno= ENAMETOOLONG; + else + my_errno= EACCES; + if (MyFlags & MY_WME) + my_error(EE_REALPATH, MYF(0), filename, my_errno); + return -1; + } #else my_load_path(to, filename, NullS); +#endif return 0; #endif } From 8776f964078403947a8581d6a61b71a33f5890c7 Mon Sep 17 00:00:00 2001 From: Sunny Bains Date: Mon, 18 Oct 2010 17:05:44 +1100 Subject: [PATCH 049/304] Fix bug encountered during testing on BSD. In the original fix for bug# 55681 the check for overflow was wrong and the OS_SYNC_INFINITE_TIME was handled incorrectly. Approved by Jimmy Yang (IM) --- storage/innobase/os/os0sync.c | 63 ++++++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/storage/innobase/os/os0sync.c b/storage/innobase/os/os0sync.c index 975c66ad1e1..5c400ae31c5 100644 --- a/storage/innobase/os/os0sync.c +++ b/storage/innobase/os/os0sync.c @@ -137,7 +137,7 @@ os_cond_wait_timed( const struct timespec* abstime /*!< in: timeout */ #else ulint time_in_ms /*!< in: timeout in - milliseconds */ + milliseconds*/ #endif /* !__WIN__ */ ) { @@ -160,7 +160,17 @@ os_cond_wait_timed( ret = pthread_cond_timedwait(cond, mutex, abstime); - ut_a(ret == 0 || ret == ETIMEDOUT); + switch (ret) { + case 0: + case ETIMEDOUT: + break; + + default: + fprintf(stderr, " InnoDB: pthread_cond_timedwait() returned: " + "%d: abstime={%lu,%lu}\n", + ret, abstime->tv_sec, abstime->tv_nsec); + ut_error; + } return(ret == ETIMEDOUT); #endif @@ -637,14 +647,15 @@ os_event_wait_time_low( ib_int64_t old_signal_count; #ifdef __WIN__ - DWORD time_in_ms = time_in_usec / 1000; + DWORD time_in_ms; if (!srv_use_native_conditions) { DWORD err; ut_a(event); - if (time_in_ms != OS_SYNC_INFINITE_TIME) { + if (time_in_usec != OS_SYNC_INFINITE_TIME) { + time_in_ms = time_in_ms / 1000; err = WaitForSingleObject(event->handle, time_in_ms); } else { err = WaitForSingleObject(event->handle, INFINITE); @@ -661,30 +672,44 @@ os_event_wait_time_low( return(42); } else { ut_a(sleep_condition_variable != NULL); + + if (time_in_usec != OS_SYNC_INFINITE_TIME) { + time_in_ms = time_in_usec / 1000; + } else { + time_in_ms = INFINITE; + } } #else - struct timeval tv; - ulint sec; - ulint usec; - int ret; struct timespec abstime; - ret = ut_usectime(&sec, &usec); - ut_a(ret == 0); + if (time_in_usec != OS_SYNC_INFINITE_TIME) { + struct timeval tv; + int ret; + ulint sec; + ulint usec; - tv.tv_sec = sec; - tv.tv_usec = usec; + ret = ut_usectime(&sec, &usec); + ut_a(ret == 0); - tv.tv_usec += time_in_usec; + tv.tv_sec = sec; + tv.tv_usec = usec; - if ((ulint) tv.tv_usec > MICROSECS_IN_A_SECOND) { - tv.tv_sec += time_in_usec / MICROSECS_IN_A_SECOND; - tv.tv_usec %= MICROSECS_IN_A_SECOND; + tv.tv_usec += time_in_usec; + + if ((ulint) tv.tv_usec >= MICROSECS_IN_A_SECOND) { + tv.tv_sec += time_in_usec / MICROSECS_IN_A_SECOND; + tv.tv_usec %= MICROSECS_IN_A_SECOND; + } + + abstime.tv_sec = tv.tv_sec; + abstime.tv_nsec = tv.tv_usec * 1000; + } else { + abstime.tv_nsec = 999999999; + abstime.tv_sec = (time_t) ULINT_MAX; } - /* Convert to nano seconds. We ignore overflow. */ - abstime.tv_sec = tv.tv_sec; - abstime.tv_nsec = tv.tv_usec * 1000; + ut_a(abstime.tv_nsec <= 999999999); + #endif /* __WIN__ */ os_fast_mutex_lock(&event->os_mutex); From 127c721cef2c1b248af79a386c174a5e7addd556 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Mon, 18 Oct 2010 14:47:26 +0400 Subject: [PATCH 050/304] Bug#54484 explain + prepared statement: crash and Got error -1 from storage engine Subquery executes twice, at top level JOIN::optimize and ::execute stages. At first execution create_sort_index() function is called and FT_SELECT object is created and destroyed. HANDLER::ft_handler is cleaned up in the object destructor and at second execution FT_SELECT::get_next() method returns error. The fix is to reinit HANDLER::ft_handler field before re-execution of subquery. mysql-test/r/fulltext.result: test case mysql-test/t/fulltext.test: test case sql/item_func.cc: reinit ft_handler before re-execution of subquery sql/item_func.h: Fixed method name sql/sql_select.cc: reinit ft_handler before re-execution of subquery --- mysql-test/r/fulltext.result | 36 ++++++++++++++++++++++++++++++++++++ mysql-test/t/fulltext.test | 36 ++++++++++++++++++++++++++++++++++++ sql/item_func.cc | 10 ++++++++++ sql/item_func.h | 2 +- sql/sql_select.cc | 3 +++ 5 files changed, 86 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index 806675edc5a..4f406f5032c 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -644,4 +644,40 @@ Table Op Msg_type Msg_text test.t1 repair status OK SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size; DROP TABLE t1; +# +# Bug#54484 explain + prepared statement: crash and Got error -1 from storage engine +# +CREATE TABLE t1(f1 VARCHAR(6) NOT NULL, FULLTEXT KEY(f1), UNIQUE(f1)); +INSERT INTO t1 VALUES ('test'); +SELECT 1 FROM t1 WHERE 1 > +ALL((SELECT 1 FROM t1 JOIN t1 a +ON (MATCH(t1.f1) against ("")) +WHERE t1.f1 GROUP BY t1.f1)) xor f1; +1 +1 +PREPARE stmt FROM +'SELECT 1 FROM t1 WHERE 1 > + ALL((SELECT 1 FROM t1 RIGHT OUTER JOIN t1 a + ON (MATCH(t1.f1) against ("")) + WHERE t1.f1 GROUP BY t1.f1)) xor f1'; +EXECUTE stmt; +1 +1 +EXECUTE stmt; +1 +1 +DEALLOCATE PREPARE stmt; +PREPARE stmt FROM +'SELECT 1 FROM t1 WHERE 1 > + ALL((SELECT 1 FROM t1 JOIN t1 a + ON (MATCH(t1.f1) against ("")) + WHERE t1.f1 GROUP BY t1.f1))'; +EXECUTE stmt; +1 +1 +EXECUTE stmt; +1 +1 +DEALLOCATE PREPARE stmt; +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test index ec64728a8c9..6de8b87197c 100644 --- a/mysql-test/t/fulltext.test +++ b/mysql-test/t/fulltext.test @@ -585,4 +585,40 @@ REPAIR TABLE t1; SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size; DROP TABLE t1; +--echo # +--echo # Bug#54484 explain + prepared statement: crash and Got error -1 from storage engine +--echo # + +CREATE TABLE t1(f1 VARCHAR(6) NOT NULL, FULLTEXT KEY(f1), UNIQUE(f1)); +INSERT INTO t1 VALUES ('test'); + +SELECT 1 FROM t1 WHERE 1 > + ALL((SELECT 1 FROM t1 JOIN t1 a + ON (MATCH(t1.f1) against ("")) + WHERE t1.f1 GROUP BY t1.f1)) xor f1; + +PREPARE stmt FROM +'SELECT 1 FROM t1 WHERE 1 > + ALL((SELECT 1 FROM t1 RIGHT OUTER JOIN t1 a + ON (MATCH(t1.f1) against ("")) + WHERE t1.f1 GROUP BY t1.f1)) xor f1'; + +EXECUTE stmt; +EXECUTE stmt; + +DEALLOCATE PREPARE stmt; + +PREPARE stmt FROM +'SELECT 1 FROM t1 WHERE 1 > + ALL((SELECT 1 FROM t1 JOIN t1 a + ON (MATCH(t1.f1) against ("")) + WHERE t1.f1 GROUP BY t1.f1))'; + +EXECUTE stmt; +EXECUTE stmt; + +DEALLOCATE PREPARE stmt; + +DROP TABLE t1; + --echo End of 5.1 tests diff --git a/sql/item_func.cc b/sql/item_func.cc index eaf6a1b6d14..30d5d844f7c 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -5297,7 +5297,17 @@ void Item_func_match::init_search(bool no_order) /* Check if init_search() has been called before */ if (ft_handler) + { + /* + We should reset ft_handler as it is cleaned up + on destruction of FT_SELECT object + (necessary in case of re-execution of subquery). + TODO: FT_SELECT should not clean up ft_handler. + */ + if (join_key) + table->file->ft_handler= ft_handler; DBUG_VOID_RETURN; + } if (key == NO_SUCH_KEY) { diff --git a/sql/item_func.h b/sql/item_func.h index 256348eee08..26a7e033692 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1531,7 +1531,7 @@ public: join_key(0), ft_handler(0), table(0), master(0), concat_ws(0) { } void cleanup() { - DBUG_ENTER("Item_func_match"); + DBUG_ENTER("Item_func_match::cleanup"); Item_real_func::cleanup(); if (!master && ft_handler) ft_handler->please->close_search(ft_handler); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 08bd0c28738..a260b78f131 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1713,6 +1713,9 @@ JOIN::reinit() func->clear(); } + if (!(select_options & SELECT_DESCRIBE)) + init_ftfuncs(thd, select_lex, test(order)); + DBUG_RETURN(0); } From 902b13fa5725b8f19f52f962d5a98b65018cce5b Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 18 Oct 2010 13:48:11 +0300 Subject: [PATCH 051/304] Fix Bug#57252 disabling innobase_stats_on_metadata disables ANALYZE In order to fix this bug we need to distinguish whether ha_innobase::info() has been called from ::analyze() or not. Rename ::info() to ::info_low() and add a boolean parameter that tells whether the call is from ::analyze() or not. Create a new simple ::info() that just calls ::info_low(false => not called from analyze). From ::analyze() instead of ::info() call ::info_low(true => called from analyze). Approved by: Jimmy (rb://487) --- .../suite/innodb/r/innodb_bug57252.result | 6 +++ .../suite/innodb/t/innodb_bug57252.test | 46 +++++++++++++++++++ storage/innobase/handler/ha_innodb.cc | 26 +++++++++-- storage/innobase/handler/ha_innodb.h | 1 + 4 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 mysql-test/suite/innodb/r/innodb_bug57252.result create mode 100644 mysql-test/suite/innodb/t/innodb_bug57252.test diff --git a/mysql-test/suite/innodb/r/innodb_bug57252.result b/mysql-test/suite/innodb/r/innodb_bug57252.result new file mode 100644 index 00000000000..efa50c742e0 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug57252.result @@ -0,0 +1,6 @@ +cardinality +10 +Table Op Msg_type Msg_text +test.bug57252 analyze status OK +cardinality +10 diff --git a/mysql-test/suite/innodb/t/innodb_bug57252.test b/mysql-test/suite/innodb/t/innodb_bug57252.test new file mode 100644 index 00000000000..04c3ed0cea7 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug57252.test @@ -0,0 +1,46 @@ +# +# Bug#57252 disabling innobase_stats_on_metadata disables ANALYZE +# http://bugs.mysql.com/57252 +# + +-- source include/have_innodb.inc + +-- disable_query_log +-- disable_result_log + +SET @innodb_stats_on_metadata_orig = @@innodb_stats_on_metadata; + +CREATE TABLE bug57252 (a INT, KEY akey (a)) ENGINE=INNODB; + +BEGIN; +let $i = 10; +while ($i) { + eval INSERT INTO bug57252 VALUES ($i); + dec $i; +} +COMMIT; + +-- enable_result_log + +SET GLOBAL innodb_stats_on_metadata=0; + +# this calls ::info() without HA_STATUS_CONST and so +# index->stat_n_diff_key_vals[] is not copied to the mysql-visible +# rec_per_key +SELECT cardinality FROM information_schema.statistics +WHERE table_name='bug57252' AND index_name='akey'; + +# this calls ::info() with HA_STATUS_CONST and so +# index->stat_n_diff_key_vals[] is copied to the mysql-visible +# rec_per_key at the end; when the bug is present dict_update_statistics() +# is not called beforehand and so index->stat_n_diff_key_vals[] contains +# an outdated data and thus we get an outdated data in the result when the +# bug is present +ANALYZE TABLE bug57252; + +SELECT cardinality FROM information_schema.statistics +WHERE table_name='bug57252' AND index_name='akey'; + +DROP TABLE bug57252; + +SET GLOBAL innodb_stats_on_metadata = @innodb_stats_on_metadata_orig; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index d5944864ad9..5a8f5479223 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -6367,9 +6367,12 @@ Returns statistics information of the table to the MySQL interpreter, in various fields of the handle object. */ int -ha_innobase::info( -/*==============*/ - uint flag) /* in: what information MySQL requests */ +ha_innobase::info_low( +/*==================*/ + uint flag, /* in: what information MySQL + requests */ + bool called_from_analyze) /* in: TRUE if called from + ::analyze() */ { dict_table_t* ib_table; dict_index_t* index; @@ -6400,7 +6403,7 @@ ha_innobase::info( ib_table = prebuilt->table; if (flag & HA_STATUS_TIME) { - if (innobase_stats_on_metadata) { + if (called_from_analyze || innobase_stats_on_metadata) { /* In sql_show we call with this flag: update then statistics so that they are up-to-date */ @@ -6616,6 +6619,18 @@ func_exit: DBUG_RETURN(0); } +/************************************************************************* +Returns statistics information of the table to the MySQL interpreter, +in various fields of the handle object. */ + +int +ha_innobase::info( +/*==============*/ + uint flag) /* in: what information MySQL requests */ +{ + return(info_low(flag, false /* not called from analyze */)); +} + /************************************************************************** Updates index cardinalities of the table, based on 8 random dives into each index tree. This does NOT calculate exact statistics on the table. */ @@ -6632,7 +6647,8 @@ ha_innobase::analyze( pthread_mutex_lock(&analyze_mutex); /* Simply call ::info() with all the flags */ - info(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE); + info_low(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE, + true /* called from analyze */); pthread_mutex_unlock(&analyze_mutex); diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index eb9199b8955..8b91f7d4c51 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -80,6 +80,7 @@ class ha_innobase: public handler ulong innobase_update_autoinc(ulonglong auto_inc); void innobase_initialize_autoinc(); dict_index_t* innobase_get_index(uint keynr); + int info_low(uint flag, bool called_from_analyze); /* Init values for the class: */ public: From 78804bc8bd251a4b5f87c6d5086bbf1a19844bee Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 18 Oct 2010 14:20:16 +0300 Subject: [PATCH 052/304] Fix Bug#57252 disabling innobase_stats_on_metadata disables ANALYZE This is a merge from 5.1/builtin to 5.1/plugin of: -------------- revision-id: vasil.dimov@oracle.com-20101018104811-nwqhg9vav17kl5s1 committer: Vasil Dimov timestamp: Mon 2010-10-18 13:48:11 +0300 message: Fix Bug#57252 disabling innobase_stats_on_metadata disables ANALYZE In order to fix this bug we need to distinguish whether ha_innobase::info() has been called from ::analyze() or not. Rename ::info() to ::info_low() and add a boolean parameter that tells whether the call is from ::analyze() or not. Create a new simple ::info() that just calls ::info_low(false => not called from analyze). From ::analyze() instead of ::info() call ::info_low(true => called from analyze). Approved by: Jimmy (rb://487) -------------- --- .../innodb_plugin/r/innodb_bug57252.result | 6 +++ .../innodb_plugin/t/innodb_bug57252.test | 46 +++++++++++++++++++ storage/innodb_plugin/ChangeLog | 6 +++ storage/innodb_plugin/handler/ha_innodb.cc | 26 +++++++++-- storage/innodb_plugin/handler/ha_innodb.h | 1 + 5 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 mysql-test/suite/innodb_plugin/r/innodb_bug57252.result create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_bug57252.test diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug57252.result b/mysql-test/suite/innodb_plugin/r/innodb_bug57252.result new file mode 100644 index 00000000000..efa50c742e0 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_bug57252.result @@ -0,0 +1,6 @@ +cardinality +10 +Table Op Msg_type Msg_text +test.bug57252 analyze status OK +cardinality +10 diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug57252.test b/mysql-test/suite/innodb_plugin/t/innodb_bug57252.test new file mode 100644 index 00000000000..d66cf79ef41 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug57252.test @@ -0,0 +1,46 @@ +# +# Bug#57252 disabling innobase_stats_on_metadata disables ANALYZE +# http://bugs.mysql.com/57252 +# + +-- source include/have_innodb_plugin.inc + +-- disable_query_log +-- disable_result_log + +SET @innodb_stats_on_metadata_orig = @@innodb_stats_on_metadata; + +CREATE TABLE bug57252 (a INT, KEY akey (a)) ENGINE=INNODB; + +BEGIN; +let $i = 10; +while ($i) { + eval INSERT INTO bug57252 VALUES ($i); + dec $i; +} +COMMIT; + +-- enable_result_log + +SET GLOBAL innodb_stats_on_metadata=0; + +# this calls ::info() without HA_STATUS_CONST and so +# index->stat_n_diff_key_vals[] is not copied to the mysql-visible +# rec_per_key +SELECT cardinality FROM information_schema.statistics +WHERE table_name='bug57252' AND index_name='akey'; + +# this calls ::info() with HA_STATUS_CONST and so +# index->stat_n_diff_key_vals[] is copied to the mysql-visible +# rec_per_key at the end; when the bug is present dict_update_statistics() +# is not called beforehand and so index->stat_n_diff_key_vals[] contains +# an outdated data and thus we get an outdated data in the result when the +# bug is present +ANALYZE TABLE bug57252; + +SELECT cardinality FROM information_schema.statistics +WHERE table_name='bug57252' AND index_name='akey'; + +DROP TABLE bug57252; + +SET GLOBAL innodb_stats_on_metadata = @innodb_stats_on_metadata_orig; diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 0adb71fcba2..488669346fd 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,9 @@ +2010-10-18 The InnoDB Team + + * handler/ha_innodb.cc, handler/ha_innodb.h, innodb_bug57252.result, + innodb_bug57252.test: + Fix Bug#57252 disabling innobase_stats_on_metadata disables ANALYZE + 2010-10-14 The InnoDB Team * handler/ha_innodb.cc, innodb_bug56143.result, innodb_bug56143.test: diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index c5c8a0f848a..35f1a4974e2 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -7523,9 +7523,12 @@ Returns statistics information of the table to the MySQL interpreter, in various fields of the handle object. */ UNIV_INTERN int -ha_innobase::info( -/*==============*/ - uint flag) /*!< in: what information MySQL requests */ +ha_innobase::info_low( +/*==================*/ + uint flag, /*!< in: what information MySQL + requests */ + bool called_from_analyze) /* in: TRUE if called from + ::analyze() */ { dict_table_t* ib_table; dict_index_t* index; @@ -7556,7 +7559,7 @@ ha_innobase::info( ib_table = prebuilt->table; if (flag & HA_STATUS_TIME) { - if (innobase_stats_on_metadata) { + if (called_from_analyze || innobase_stats_on_metadata) { /* In sql_show we call with this flag: update then statistics so that they are up-to-date */ @@ -7804,6 +7807,18 @@ func_exit: DBUG_RETURN(0); } +/*********************************************************************//** +Returns statistics information of the table to the MySQL interpreter, +in various fields of the handle object. */ +UNIV_INTERN +int +ha_innobase::info( +/*==============*/ + uint flag) /*!< in: what information MySQL requests */ +{ + return(info_low(flag, false /* not called from analyze */)); +} + /**********************************************************************//** Updates index cardinalities of the table, based on 8 random dives into each index tree. This does NOT calculate exact statistics on the table. @@ -7816,7 +7831,8 @@ ha_innobase::analyze( HA_CHECK_OPT* check_opt) /*!< in: currently ignored */ { /* Simply call ::info() with all the flags */ - info(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE); + info_low(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE, + true /* called from analyze */); return(0); } diff --git a/storage/innodb_plugin/handler/ha_innodb.h b/storage/innodb_plugin/handler/ha_innodb.h index 9789e4ba639..7a8f29853de 100644 --- a/storage/innodb_plugin/handler/ha_innodb.h +++ b/storage/innodb_plugin/handler/ha_innodb.h @@ -109,6 +109,7 @@ class ha_innobase: public handler ulint innobase_update_autoinc(ulonglong auto_inc); void innobase_initialize_autoinc(); dict_index_t* innobase_get_index(uint keynr); + int info_low(uint flag, bool called_from_analyze); /* Init values for the class: */ public: From 9074307102644d43b934ce52cc0661890098698b Mon Sep 17 00:00:00 2001 From: Tor Didriksen Date: Mon, 18 Oct 2010 13:24:34 +0200 Subject: [PATCH 053/304] Bug#52172 test binlog.binlog_index needs --skip-core-file to avoid leaving core files For crash testing: kill the server without generating core file. include/my_dbug.h Use kill(getpid(), SIGKILL) which cannot be caught by signal handlers. All DBUG_XXX macros should be no-ops in optimized mode, do that for DBUG_ABORT as well. sql/handler.cc Kill server without generating core. sql/log.cc Kill server without generating core. --- dbug/dbug.c | 8 ++++++++ include/my_dbug.h | 51 +++++++++++++++++++++++++++++++++++++++++++---- sql/handler.cc | 10 +++++----- sql/log.cc | 18 ++++++++--------- 4 files changed, 69 insertions(+), 18 deletions(-) diff --git a/dbug/dbug.c b/dbug/dbug.c index 76723fa8767..7278acca2a9 100644 --- a/dbug/dbug.c +++ b/dbug/dbug.c @@ -2267,6 +2267,14 @@ static void dbug_flush(CODE_STATE *cs) } /* dbug_flush */ +void _db_flush_() +{ + CODE_STATE *cs; + get_code_state_or_return; + (void) fflush(cs->stack->out_file); +} + + void _db_lock_file_() { CODE_STATE *cs=0; diff --git a/include/my_dbug.h b/include/my_dbug.h index 0ba72b2210d..f08e94a1882 100644 --- a/include/my_dbug.h +++ b/include/my_dbug.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -13,8 +13,18 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _dbug_h -#define _dbug_h +#ifndef MY_DBUG_INCLUDED +#define MY_DBUG_INCLUDED + +#ifndef __WIN__ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#endif /* not __WIN__ */ #if defined(__cplusplus) && !defined(DBUG_OFF) class Dbug_violation_helper @@ -69,6 +79,7 @@ extern void _db_end_(void); extern void _db_lock_file_(void); extern void _db_unlock_file_(void); extern FILE *_db_fp_(void); +extern void _db_flush_(); #ifdef __cplusplus @@ -124,6 +135,34 @@ extern FILE *_db_fp_(void); #define DBUG_EXPLAIN(buf,len) _db_explain_(0, (buf),(len)) #define DBUG_EXPLAIN_INITIAL(buf,len) _db_explain_init_((buf),(len)) #define IF_DBUG(A) A +#ifndef __WIN__ +#define DBUG_ABORT() (_db_flush_(), abort()) +#else +/* + Avoid popup with abort/retry/ignore buttons. When BUG#31745 is fixed we can + call abort() instead of _exit(3) (now it would cause a "test signal" popup). +*/ +#include +#define DBUG_ABORT() (_db_flush_(),\ + (void)_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE),\ + (void)_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR),\ + _exit(3)) +#endif + +/* + Make the program fail, without creating a core file. + abort() will send SIGABRT which (most likely) generates core. + Use SIGKILL instead, which cannot be caught. + We also pause the current thread, until the signal is actually delivered. + An alternative would be to use _exit(EXIT_FAILURE), + but then valgrind would report lots of memory leaks. + */ +#ifdef __WIN__ +#define DBUG_SUICIDE() DBUG_ABORT() +#else +#define DBUG_SUICIDE() (_db_flush_(), kill(getpid(), SIGKILL), pause()) +#endif + #else /* No debugger */ #define DBUG_ENTER(a1) @@ -152,8 +191,12 @@ extern FILE *_db_fp_(void); #define DBUG_EXPLAIN(buf,len) #define DBUG_EXPLAIN_INITIAL(buf,len) #define IF_DBUG(A) +#define DBUG_ABORT() do { } while(0) +#define DBUG_SUICIDE() do { } while(0) + #endif #ifdef __cplusplus } #endif -#endif + +#endif /* MY_DBUG_INCLUDED */ diff --git a/sql/handler.cc b/sql/handler.cc index 19f397ef09f..a47a5fd8a3c 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1127,7 +1127,7 @@ int ha_commit_trans(THD *thd, bool all) uint rw_ha_count; bool rw_trans; - DBUG_EXECUTE_IF("crash_commit_before", abort();); + DBUG_EXECUTE_IF("crash_commit_before", DBUG_SUICIDE();); /* Close all cursors that can not survive COMMIT */ if (is_real_trans) /* not a statement commit */ @@ -1179,7 +1179,7 @@ int ha_commit_trans(THD *thd, bool all) } status_var_increment(thd->status_var.ha_prepare_count); } - DBUG_EXECUTE_IF("crash_commit_after_prepare", abort();); + DBUG_EXECUTE_IF("crash_commit_after_prepare", DBUG_SUICIDE();); if (error || (is_real_trans && xid && (error= !(cookie= tc_log->log_xid(thd, xid))))) { @@ -1187,13 +1187,13 @@ int ha_commit_trans(THD *thd, bool all) error= 1; goto end; } - DBUG_EXECUTE_IF("crash_commit_after_log", abort();); + DBUG_EXECUTE_IF("crash_commit_after_log", DBUG_SUICIDE();); } error=ha_commit_one_phase(thd, all) ? (cookie ? 2 : 1) : 0; - DBUG_EXECUTE_IF("crash_commit_before_unlog", abort();); + DBUG_EXECUTE_IF("crash_commit_before_unlog", DBUG_SUICIDE();); if (cookie) tc_log->unlog(cookie, xid); - DBUG_EXECUTE_IF("crash_commit_after", abort();); + DBUG_EXECUTE_IF("crash_commit_after", DBUG_SUICIDE();); end: if (rw_trans) start_waiting_global_read_lock(thd); diff --git a/sql/log.cc b/sql/log.cc index 56f151fe2ab..2d5b62a5b2b 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -2600,7 +2600,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name, sql_print_error("MSYQL_BIN_LOG::open failed to sync the index file."); DBUG_RETURN(1); } - DBUG_EXECUTE_IF("crash_create_non_critical_before_update_index", abort();); + DBUG_EXECUTE_IF("crash_create_non_critical_before_update_index", DBUG_SUICIDE();); #endif write_error= 0; @@ -2697,7 +2697,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name, if (write_file_name_to_index_file) { #ifdef HAVE_REPLICATION - DBUG_EXECUTE_IF("crash_create_critical_before_update_index", abort();); + DBUG_EXECUTE_IF("crash_create_critical_before_update_index", DBUG_SUICIDE();); #endif DBUG_ASSERT(my_b_inited(&index_file) != 0); @@ -2716,7 +2716,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name, goto err; #ifdef HAVE_REPLICATION - DBUG_EXECUTE_IF("crash_create_after_update_index", abort();); + DBUG_EXECUTE_IF("crash_create_after_update_index", DBUG_SUICIDE();); #endif } } @@ -3168,7 +3168,7 @@ int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included) /* Store where we are in the new file for the execution thread */ flush_relay_log_info(rli); - DBUG_EXECUTE_IF("crash_before_purge_logs", abort();); + DBUG_EXECUTE_IF("crash_before_purge_logs", DBUG_SUICIDE();); pthread_mutex_lock(&rli->log_space_lock); rli->relay_log.purge_logs(to_purge_if_included, included, @@ -3296,7 +3296,7 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log, break; } - DBUG_EXECUTE_IF("crash_purge_before_update_index", abort();); + DBUG_EXECUTE_IF("crash_purge_before_update_index", DBUG_SUICIDE();); if ((error= sync_purge_index_file())) { @@ -3311,7 +3311,7 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log, goto err; } - DBUG_EXECUTE_IF("crash_purge_critical_after_update_index", abort();); + DBUG_EXECUTE_IF("crash_purge_critical_after_update_index", DBUG_SUICIDE();); err: /* Read each entry from purge_index_file and delete the file. */ @@ -3321,7 +3321,7 @@ err: " that would be purged."); close_purge_index_file(); - DBUG_EXECUTE_IF("crash_purge_non_critical_after_update_index", abort();); + DBUG_EXECUTE_IF("crash_purge_non_critical_after_update_index", DBUG_SUICIDE();); if (need_mutex) pthread_mutex_unlock(&LOCK_index); @@ -4832,7 +4832,7 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event, DBUG_PRINT("info", ("error writing binlog cache: %d", write_error)); DBUG_PRINT("info", ("crashing before writing xid")); - abort(); + DBUG_SUICIDE(); }); if ((write_error= write_cache(cache, false, false))) @@ -4846,7 +4846,7 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event, if (flush_and_sync()) goto err; - DBUG_EXECUTE_IF("half_binlogged_transaction", abort();); + DBUG_EXECUTE_IF("half_binlogged_transaction", DBUG_SUICIDE();); if (cache->error) // Error on read { sql_print_error(ER(ER_ERROR_ON_READ), cache->file_name, errno); From d0ac4e2c5ade16d6d0833137aa67071b34e66964 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Mon, 18 Oct 2010 16:12:27 +0400 Subject: [PATCH 054/304] Bug#56814 Explain + subselect + fulltext crashes server create_sort_index() function overwrites original JOIN_TAB::type field. At re-execution of subquery overwritten JOIN_TAB::type(JT_ALL) is used instead of JT_FT. It misleads test_if_skip_sort_order() and the function tries to find suitable key for the order that should not be allowed for FULLTEXT(JT_FT) table. The fix is to restore JOIN_TAB strucures for subselect on re-execution for EXPLAIN. Additional fix: Update TABLE::maybe_null field which affects list_contains_unique_index() behaviour as it could have the value(maybe_null==TRUE) based on the assumption that this join is outer (see setup_table_map() func). mysql-test/r/explain.result: test case mysql-test/t/explain.test: test case sql/item_subselect.cc: Make subquery uncacheable in case of EXPLAIN. It allows to keep original JOIN_TAB::type(see JOIN::save_join_tab) and restore it on re-execution. sql/sql_select.cc: -restore JOIN_TAB strucures for subselect on re-execution for EXPLAIN -Update TABLE::maybe_null field as it could have the value(maybe_null==TRUE) based on the assumption that this join is outer(see setup_table_map() func). This change is not related to the crash problem but affects EXPLAIN results in the test case. --- mysql-test/r/explain.result | 46 +++++++++++++++++++++++++++++++++++++ mysql-test/t/explain.test | 36 +++++++++++++++++++++++++++++ sql/item_subselect.cc | 15 ++++++++---- sql/sql_select.cc | 14 +++++++++++ 4 files changed, 106 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/explain.result b/mysql-test/r/explain.result index f46fe8daaad..4bc6c0409f3 100644 --- a/mysql-test/r/explain.result +++ b/mysql-test/r/explain.result @@ -251,4 +251,50 @@ EXPLAIN SELECT c1 FROM t1 WHERE c2 = 1 AND c4 = 1 AND c5 = 1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref c2,c2_2 c2 10 const,const 3 Using where DROP TABLE t1; +# +# Bug#56814 Explain + subselect + fulltext crashes server +# +CREATE TABLE t1(f1 VARCHAR(6) NOT NULL, +FULLTEXT KEY(f1),UNIQUE(f1)); +INSERT INTO t1 VALUES ('test'); +EXPLAIN SELECT 1 FROM t1 +WHERE 1 > ALL((SELECT 1 FROM t1 JOIN t1 a ON (MATCH(t1.f1) AGAINST ("")) +WHERE t1.f1 GROUP BY t1.f1)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 system NULL NULL NULL NULL 1 +2 SUBQUERY a system NULL NULL NULL NULL 1 Using filesort +2 SUBQUERY t1 fulltext f1 f1 0 1 Using where +PREPARE stmt FROM +'EXPLAIN SELECT 1 FROM t1 + WHERE 1 > ALL((SELECT 1 FROM t1 RIGHT OUTER JOIN t1 a + ON (MATCH(t1.f1) AGAINST ("")) + WHERE t1.f1 GROUP BY t1.f1))'; +EXECUTE stmt; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 system NULL NULL NULL NULL 1 +2 SUBQUERY a system NULL NULL NULL NULL 1 Using filesort +2 SUBQUERY t1 fulltext f1 f1 0 1 Using where +EXECUTE stmt; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 system NULL NULL NULL NULL 1 +2 SUBQUERY a system NULL NULL NULL NULL 1 Using filesort +2 SUBQUERY t1 fulltext f1 f1 0 1 Using where +DEALLOCATE PREPARE stmt; +PREPARE stmt FROM +'EXPLAIN SELECT 1 FROM t1 + WHERE 1 > ALL((SELECT 1 FROM t1 JOIN t1 a + ON (MATCH(t1.f1) AGAINST ("")) + WHERE t1.f1 GROUP BY t1.f1))'; +EXECUTE stmt; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 system NULL NULL NULL NULL 1 +2 SUBQUERY a system NULL NULL NULL NULL 1 Using filesort +2 SUBQUERY t1 fulltext f1 f1 0 1 Using where +EXECUTE stmt; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 system NULL NULL NULL NULL 1 +2 SUBQUERY a system NULL NULL NULL NULL 1 Using filesort +2 SUBQUERY t1 fulltext f1 f1 0 1 Using where +DEALLOCATE PREPARE stmt; +DROP TABLE t1; End of 5.1 tests. diff --git a/mysql-test/t/explain.test b/mysql-test/t/explain.test index b635a1b2968..c6c30b58341 100644 --- a/mysql-test/t/explain.test +++ b/mysql-test/t/explain.test @@ -228,4 +228,40 @@ EXPLAIN SELECT c1 FROM t1 WHERE c2 = 1 AND c4 = 1 AND c5 = 1; DROP TABLE t1; +--echo # +--echo # Bug#56814 Explain + subselect + fulltext crashes server +--echo # + +CREATE TABLE t1(f1 VARCHAR(6) NOT NULL, +FULLTEXT KEY(f1),UNIQUE(f1)); +INSERT INTO t1 VALUES ('test'); + +EXPLAIN SELECT 1 FROM t1 +WHERE 1 > ALL((SELECT 1 FROM t1 JOIN t1 a ON (MATCH(t1.f1) AGAINST ("")) +WHERE t1.f1 GROUP BY t1.f1)); + +PREPARE stmt FROM +'EXPLAIN SELECT 1 FROM t1 + WHERE 1 > ALL((SELECT 1 FROM t1 RIGHT OUTER JOIN t1 a + ON (MATCH(t1.f1) AGAINST ("")) + WHERE t1.f1 GROUP BY t1.f1))'; + +EXECUTE stmt; +EXECUTE stmt; + +DEALLOCATE PREPARE stmt; + +PREPARE stmt FROM +'EXPLAIN SELECT 1 FROM t1 + WHERE 1 > ALL((SELECT 1 FROM t1 JOIN t1 a + ON (MATCH(t1.f1) AGAINST ("")) + WHERE t1.f1 GROUP BY t1.f1))'; + +EXECUTE stmt; +EXECUTE stmt; + +DEALLOCATE PREPARE stmt; + +DROP TABLE t1; + --echo End of 5.1 tests. diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 1ed36ce7656..d521ad0b4e8 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1906,21 +1906,26 @@ int subselect_single_select_engine::exec() DBUG_RETURN(join->error ? join->error : 1); } if (!select_lex->uncacheable && thd->lex->describe && - !(join->select_options & SELECT_DESCRIBE) && - join->need_tmp) + !(join->select_options & SELECT_DESCRIBE)) { item->update_used_tables(); if (item->const_item()) { + /* + It's necessary to keep original JOIN table because + create_sort_index() function may overwrite original + JOIN_TAB::type and wrong optimization method can be + selected on re-execution. + */ + select_lex->uncacheable|= UNCACHEABLE_EXPLAIN; + select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN; /* Force join->join_tmp creation, because this subquery will be replaced by a simple select from the materialization temp table by optimize() called by EXPLAIN and we need to preserve the initial query structure so we can display it. */ - select_lex->uncacheable|= UNCACHEABLE_EXPLAIN; - select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN; - if (join->init_save_join_tab()) + if (join->need_tmp && join->init_save_join_tab()) DBUG_RETURN(1); /* purecov: inspected */ } } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index a260b78f131..11acd0685a8 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2490,6 +2490,13 @@ mysql_select(THD *thd, Item ***rref_pointer_array, { DBUG_RETURN(TRUE); } + /* + Original join tabs might be overwritten at first + subselect execution. So we need to restore them. + */ + Item_subselect *subselect= select_lex->master_unit()->item; + if (subselect && subselect->is_uncacheable() && join->reinit()) + DBUG_RETURN(TRUE); } else { @@ -8825,6 +8832,13 @@ simplify_joins(JOIN *join, List *join_list, COND *conds, bool top) that reject nulls => the outer join can be replaced by an inner join. */ table->outer_join= 0; + /* + Update TABLE::maybe_null field as it could have + the value(maybe_null==TRUE) based on the assumption + that this join is outer(see setup_table_map() func). + */ + if (table->table) + table->table->maybe_null= FALSE; if (table->on_expr) { /* Add on expression to the where condition. */ From cdddc7bfd58f900d63b21a811ad768849311c7b7 Mon Sep 17 00:00:00 2001 From: Dmitry Shulga Date: Mon, 18 Oct 2010 21:03:53 +0700 Subject: [PATCH 055/304] Follow up for bug#36742. Changed test case for bug#19828 because currently hostname stored in db in lowercase. --- mysql-test/r/grant3.result | 25 +++++-------------------- mysql-test/t/grant3.test | 5 +++++ 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/mysql-test/r/grant3.result b/mysql-test/r/grant3.result index 59c64ee84ae..fd51a83d4b2 100644 --- a/mysql-test/r/grant3.result +++ b/mysql-test/r/grant3.result @@ -21,123 +21,108 @@ grant select on test.* to CUser@LOCALHOST; flush privileges; SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; user host -CUser LOCALHOST CUser localhost SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2; user host db select_priv -CUser LOCALHOST test Y CUser localhost test Y REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST'; flush privileges; SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; user host -CUser LOCALHOST CUser localhost SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2; user host db select_priv -CUser localhost test Y REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost'; flush privileges; SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; user host -CUser LOCALHOST CUser localhost SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2; user host db select_priv DROP USER CUser@localhost; DROP USER CUser@LOCALHOST; +ERROR HY000: Operation DROP USER failed for 'CUser'@'localhost' create table t1 (a int); grant select on test.t1 to CUser@localhost; grant select on test.t1 to CUser@LOCALHOST; flush privileges; SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; user host -CUser LOCALHOST CUser localhost SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; user host db Table_name Table_priv Column_priv -CUser LOCALHOST test t1 Select CUser localhost test t1 Select REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST'; flush privileges; SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; user host -CUser LOCALHOST CUser localhost SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; user host db Table_name Table_priv Column_priv -CUser localhost test t1 Select REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost'; flush privileges; SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; user host -CUser LOCALHOST CUser localhost SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; user host db Table_name Table_priv Column_priv DROP USER CUser@localhost; DROP USER CUser@LOCALHOST; +ERROR HY000: Operation DROP USER failed for 'CUser'@'localhost' grant select(a) on test.t1 to CUser@localhost; grant select(a) on test.t1 to CUser@LOCALHOST; flush privileges; SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; user host -CUser LOCALHOST CUser localhost SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; user host db Table_name Table_priv Column_priv -CUser LOCALHOST test t1 Select CUser localhost test t1 Select REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST'; flush privileges; SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; user host -CUser LOCALHOST CUser localhost SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; user host db Table_name Table_priv Column_priv -CUser localhost test t1 Select REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost'; flush privileges; SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; user host -CUser LOCALHOST CUser localhost SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; user host db Table_name Table_priv Column_priv DROP USER CUser@localhost; DROP USER CUser@LOCALHOST; +ERROR HY000: Operation DROP USER failed for 'CUser'@'localhost' drop table t1; grant select on test.* to CUser2@localhost; grant select on test.* to CUser2@LOCALHOST; flush privileges; SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2; user host -CUser2 LOCALHOST CUser2 localhost SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2; user host db select_priv -CUser2 LOCALHOST test Y CUser2 localhost test Y REVOKE SELECT ON test.* FROM 'CUser2'@'LOCALHOST'; flush privileges; SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2; user host -CUser2 LOCALHOST CUser2 localhost SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2; user host db select_priv -CUser2 localhost test Y REVOKE SELECT ON test.* FROM 'CUser2'@'localhost'; +ERROR 42000: There is no such grant defined for user 'CUser2' on host 'localhost' flush privileges; SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2; user host -CUser2 LOCALHOST CUser2 localhost SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2; user host db select_priv DROP USER CUser2@localhost; DROP USER CUser2@LOCALHOST; +ERROR HY000: Operation DROP USER failed for 'CUser2'@'localhost' CREATE DATABASE mysqltest_1; CREATE TABLE mysqltest_1.t1 (a INT); CREATE USER 'mysqltest1'@'%'; diff --git a/mysql-test/t/grant3.test b/mysql-test/t/grant3.test index 437fc9a278f..d24b2de17eb 100644 --- a/mysql-test/t/grant3.test +++ b/mysql-test/t/grant3.test @@ -64,6 +64,7 @@ SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2; DROP USER CUser@localhost; +--error ER_CANNOT_USER DROP USER CUser@LOCALHOST; #### table grants @@ -88,6 +89,7 @@ SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; DROP USER CUser@localhost; +--error ER_CANNOT_USER DROP USER CUser@LOCALHOST; ### column grants @@ -112,6 +114,7 @@ SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; DROP USER CUser@localhost; +--error ER_CANNOT_USER DROP USER CUser@LOCALHOST; drop table t1; @@ -131,6 +134,7 @@ flush privileges; SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2; SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2; +--error ER_NONEXISTING_GRANT REVOKE SELECT ON test.* FROM 'CUser2'@'localhost'; flush privileges; @@ -138,6 +142,7 @@ SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2; SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2; DROP USER CUser2@localhost; +--error ER_CANNOT_USER DROP USER CUser2@LOCALHOST; From 4053a5a44832552090218fb7ca685c1c2a2ae006 Mon Sep 17 00:00:00 2001 From: Dmitry Shulga Date: Mon, 18 Oct 2010 23:20:26 +0700 Subject: [PATCH 056/304] Follow-up for bug#36742: changed results for test ipv4_as_ipv6 because hostname is case-insensitive. --- mysql-test/r/ipv4_as_ipv6.result | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/mysql-test/r/ipv4_as_ipv6.result b/mysql-test/r/ipv4_as_ipv6.result index 8523dc82f02..82bca393d71 100644 --- a/mysql-test/r/ipv4_as_ipv6.result +++ b/mysql-test/r/ipv4_as_ipv6.result @@ -32,9 +32,9 @@ mysqld is alive CREATE USER testuser@'0:0:0:0:0:FFFF:127.0.0.1' identified by '1234'; GRANT ALL ON test.* TO testuser@'0:0:0:0:0:FFFF:127.0.0.1'; SHOW GRANTS FOR testuser@'0:0:0:0:0:FFFF:127.0.0.1'; -Grants for testuser@0:0:0:0:0:FFFF:127.0.0.1 -GRANT USAGE ON *.* TO 'testuser'@'0:0:0:0:0:FFFF:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF' -GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'0:0:0:0:0:FFFF:127.0.0.1' +Grants for testuser@0:0:0:0:0:ffff:127.0.0.1 +GRANT USAGE ON *.* TO 'testuser'@'0:0:0:0:0:ffff:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF' +GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'0:0:0:0:0:ffff:127.0.0.1' SET @nip= inet_aton('0:0:0:0:0:FFFF:127.0.0.1'); SELECT @nip; @nip @@ -61,9 +61,9 @@ mysqld is alive CREATE USER testuser@'0000:0000:0000:0000:0000:FFFF:127.0.0.1' identified by '1234'; GRANT ALL ON test.* TO testuser@'0000:0000:0000:0000:0000:FFFF:127.0.0.1'; SHOW GRANTS FOR testuser@'0000:0000:0000:0000:0000:FFFF:127.0.0.1'; -Grants for testuser@0000:0000:0000:0000:0000:FFFF:127.0.0.1 -GRANT USAGE ON *.* TO 'testuser'@'0000:0000:0000:0000:0000:FFFF:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF' -GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'0000:0000:0000:0000:0000:FFFF:127.0.0.1' +Grants for testuser@0000:0000:0000:0000:0000:ffff:127.0.0.1 +GRANT USAGE ON *.* TO 'testuser'@'0000:0000:0000:0000:0000:ffff:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF' +GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'0000:0000:0000:0000:0000:ffff:127.0.0.1' SET @nip= inet_aton('0000:0000:0000:0000:0000:FFFF:127.0.0.1'); SELECT @nip; @nip @@ -90,9 +90,9 @@ mysqld is alive CREATE USER testuser@'0:0000:0000:0:0000:FFFF:127.0.0.1' identified by '1234'; GRANT ALL ON test.* TO testuser@'0:0000:0000:0:0000:FFFF:127.0.0.1'; SHOW GRANTS FOR testuser@'0:0000:0000:0:0000:FFFF:127.0.0.1'; -Grants for testuser@0:0000:0000:0:0000:FFFF:127.0.0.1 -GRANT USAGE ON *.* TO 'testuser'@'0:0000:0000:0:0000:FFFF:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF' -GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'0:0000:0000:0:0000:FFFF:127.0.0.1' +Grants for testuser@0:0000:0000:0:0000:ffff:127.0.0.1 +GRANT USAGE ON *.* TO 'testuser'@'0:0000:0000:0:0000:ffff:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF' +GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'0:0000:0000:0:0000:ffff:127.0.0.1' SET @nip= inet_aton('0:0000:0000:0:0000:FFFF:127.0.0.1'); SELECT @nip; @nip @@ -119,9 +119,9 @@ mysqld is alive CREATE USER testuser@'0::0000:FFFF:127.0.0.1' identified by '1234'; GRANT ALL ON test.* TO testuser@'0::0000:FFFF:127.0.0.1'; SHOW GRANTS FOR testuser@'0::0000:FFFF:127.0.0.1'; -Grants for testuser@0::0000:FFFF:127.0.0.1 -GRANT USAGE ON *.* TO 'testuser'@'0::0000:FFFF:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF' -GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'0::0000:FFFF:127.0.0.1' +Grants for testuser@0::0000:ffff:127.0.0.1 +GRANT USAGE ON *.* TO 'testuser'@'0::0000:ffff:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF' +GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'0::0000:ffff:127.0.0.1' SET @nip= inet_aton('0::0000:FFFF:127.0.0.1'); SELECT @nip; @nip @@ -149,9 +149,9 @@ mysqld is alive CREATE USER testuser@'::FFFF:127.0.0.1' identified by '1234'; GRANT ALL ON test.* TO testuser@'::FFFF:127.0.0.1'; SHOW GRANTS FOR testuser@'::FFFF:127.0.0.1'; -Grants for testuser@::FFFF:127.0.0.1 -GRANT USAGE ON *.* TO 'testuser'@'::FFFF:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF' -GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'::FFFF:127.0.0.1' +Grants for testuser@::ffff:127.0.0.1 +GRANT USAGE ON *.* TO 'testuser'@'::ffff:127.0.0.1' IDENTIFIED BY PASSWORD '*A4B6157319038724E3560894F7F932C8886EBFCF' +GRANT ALL PRIVILEGES ON `test`.* TO 'testuser'@'::ffff:127.0.0.1' SET @nip= inet_aton('::FFFF:127.0.0.1'); SELECT @nip; @nip From 5aa81e380cde5bc9f9cd42787286d6db5292d631 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Mon, 18 Oct 2010 14:27:10 -0200 Subject: [PATCH 057/304] Bug#45288: pb2 returns a lot of compilation warnings on linux Enable the MySQL maintainer-specific development environment (which add various warning related options to the compiler flags) if debugging support is enabled. config/ac-macros/maintainer.m4: Enable the maintainer mode if debug support is enabled. configure.in: Move debug argument to before the maintainer mode check. --- config/ac-macros/maintainer.m4 | 3 ++- configure.in | 12 +++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/config/ac-macros/maintainer.m4 b/config/ac-macros/maintainer.m4 index 24be31395f2..5960853d7f1 100644 --- a/config/ac-macros/maintainer.m4 +++ b/config/ac-macros/maintainer.m4 @@ -8,7 +8,8 @@ AC_DEFUN([MY_MAINTAINER_MODE], [ [AS_HELP_STRING([--enable-mysql-maintainer-mode], [Enable a MySQL maintainer-specific development environment])], [USE_MYSQL_MAINTAINER_MODE=$enableval], - [USE_MYSQL_MAINTAINER_MODE=no]) + [AS_IF([test "$with_debug" != "no"], + [USE_MYSQL_MAINTAINER_MODE=yes], [USE_MYSQL_MAINTAINER_MODE=no])]) AC_MSG_RESULT([$USE_MYSQL_MAINTAINER_MODE]) ]) diff --git a/configure.in b/configure.in index c1672557bd1..09885dbbae7 100644 --- a/configure.in +++ b/configure.in @@ -103,6 +103,13 @@ AC_SUBST(SHARED_LIB_MAJOR_VERSION) AC_SUBST(SHARED_LIB_VERSION) AC_SUBST(AVAILABLE_LANGUAGES) +# Check whether a debug mode should be enabled. +AC_ARG_WITH([debug], + AS_HELP_STRING([--with-debug@<:@=full@:>@], + [Enable various amounts of debugging support (full adds a slow memory checker).]), + [with_debug=$withval], + [with_debug=no]) + # Whether the maintainer mode should be enabled. MY_MAINTAINER_MODE @@ -1674,11 +1681,6 @@ then DEBUG_OPTIMIZE_CXX="" fi -AC_ARG_WITH(debug, - [ --with-debug Add debug code - --with-debug=full Add debug code (adds memory checker, very slow)], - [with_debug=$withval], - [with_debug=no]) if test "$with_debug" = "yes" then # Medium debug. From a8f2f7af32c369e92205abeafec4cc0ff5f9f4bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 19 Oct 2010 08:58:53 +0300 Subject: [PATCH 058/304] Bug #56680 wrong InnoDB results from a case-insensitive covering index row_search_for_mysql(): When a secondary index record might not be visible in the current transaction's read view and we consult the clustered index and optionally some undo log records, return the relevant columns of the clustered index record to MySQL instead of the secondary index record. REC_INFO_DELETED_FLAG: Move the definition from rem0rec.ic to rem0rec.h. ibuf_insert_to_index_page_low(): New function, refactored from ibuf_insert_to_index_page(). ibuf_insert_to_index_page(): When we are inserting a record in place of a delete-marked record and some fields of the record differ, update that record just like row_ins_sec_index_entry_by_modify() would do. mysql_row_templ_t: Add clust_rec_field_no. row_sel_store_mysql_rec(), row_sel_push_cache_row_for_mysql(): Add the flag rec_clust, for returning data at clust_rec_field_no instead of rec_field_no. Resurrect the debug assertion that the record not be marked for deletion. (Bug #55626) buf_LRU_free_block(): Refactored from buf_LRU_search_and_free_block(). This is needed for the innodb_change_buffering_debug diagnostics. [UNIV_DEBUG || UNIV_IBUF_DEBUG] ibuf_debug, buf_page_get_gen(), buf_flush_page_try(): Implement innodb_change_buffering_debug=1 for evicting pages from the buffer pool, so that change buffering will be attempted more frequently. --- .../suite/innodb/r/innodb_bug56680.result | 102 ++++++++++ .../suite/innodb/t/innodb_bug56680.test | 130 ++++++++++++ storage/innobase/buf/buf0buf.c | 24 +++ storage/innobase/buf/buf0flu.c | 76 +++++++ storage/innobase/buf/buf0lru.c | 101 +++++---- storage/innobase/handler/ha_innodb.cc | 28 ++- storage/innobase/ibuf/ibuf0ibuf.c | 191 +++++++++++++----- storage/innobase/include/buf0flu.h | 14 ++ storage/innobase/include/buf0lru.h | 8 + storage/innobase/include/ibuf0ibuf.h | 5 + storage/innobase/include/rem0rec.h | 3 + storage/innobase/include/rem0rec.ic | 3 - storage/innobase/include/row0mysql.h | 4 + storage/innobase/include/row0upd.h | 8 +- storage/innobase/row/row0mysql.c | 2 +- storage/innobase/row/row0sel.c | 84 ++++---- storage/innobase/row/row0upd.c | 8 +- 17 files changed, 643 insertions(+), 148 deletions(-) create mode 100644 mysql-test/suite/innodb/r/innodb_bug56680.result create mode 100644 mysql-test/suite/innodb/t/innodb_bug56680.test diff --git a/mysql-test/suite/innodb/r/innodb_bug56680.result b/mysql-test/suite/innodb/r/innodb_bug56680.result new file mode 100644 index 00000000000..c3afc3e6581 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug56680.result @@ -0,0 +1,102 @@ +SET GLOBAL tx_isolation='REPEATABLE-READ'; +CREATE TABLE bug56680( +a INT AUTO_INCREMENT PRIMARY KEY, +b CHAR(1), +c INT, +INDEX(b)) +ENGINE=InnoDB; +INSERT INTO bug56680 VALUES(0,'x',1); +BEGIN; +SELECT b FROM bug56680; +b +x +BEGIN; +UPDATE bug56680 SET b='X'; +SELECT b FROM bug56680; +b +x +SELECT * FROM bug56680; +a b c +1 x 1 +ROLLBACK; +SELECT b FROM bug56680; +b +x +SET GLOBAL tx_isolation='READ-UNCOMMITTED'; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +BEGIN; +SELECT b FROM bug56680 LIMIT 2; +b +x +x +BEGIN; +DELETE FROM bug56680 WHERE a=1; +INSERT INTO bug56680 VALUES(1,'X',1); +SELECT b FROM bug56680 LIMIT 3; +b +X +x +x +SELECT b FROM bug56680 LIMIT 2; +b +x +x +CHECK TABLE bug56680; +Table Op Msg_type Msg_text +test.bug56680 check status OK +ROLLBACK; +SELECT b FROM bug56680 LIMIT 2; +b +x +x +CHECK TABLE bug56680; +Table Op Msg_type Msg_text +test.bug56680 check status OK +SELECT b FROM bug56680 LIMIT 2; +b +x +x +CREATE TABLE bug56680_2( +a INT AUTO_INCREMENT PRIMARY KEY, +b VARCHAR(2) CHARSET latin1 COLLATE latin1_german2_ci, +c INT, +INDEX(b)) +ENGINE=InnoDB; +INSERT INTO bug56680_2 SELECT 0,_latin1 0xdf,c FROM bug56680; +BEGIN; +SELECT HEX(b) FROM bug56680_2 LIMIT 2; +HEX(b) +DF +DF +DELETE FROM bug56680_2 WHERE a=1; +INSERT INTO bug56680_2 VALUES(1,'SS',1); +SELECT HEX(b) FROM bug56680_2 LIMIT 3; +HEX(b) +5353 +DF +DF +CHECK TABLE bug56680_2; +Table Op Msg_type Msg_text +test.bug56680_2 check status OK +DELETE FROM bug56680_2 WHERE a=1; +INSERT INTO bug56680_2 VALUES(1,_latin1 0xdf,1); +SELECT HEX(b) FROM bug56680_2 LIMIT 3; +HEX(b) +DF +DF +DF +CHECK TABLE bug56680_2; +Table Op Msg_type Msg_text +test.bug56680_2 check status OK +DROP TABLE bug56680_2; +DROP TABLE bug56680; diff --git a/mysql-test/suite/innodb/t/innodb_bug56680.test b/mysql-test/suite/innodb/t/innodb_bug56680.test new file mode 100644 index 00000000000..ab81ca2f8e6 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug56680.test @@ -0,0 +1,130 @@ +# +# Bug #56680 InnoDB may return wrong results from a case-insensitive index +# +-- source include/have_innodb.inc + +-- disable_query_log +SET @tx_isolation_orig = @@tx_isolation; +# The flag innodb_change_buffering_debug is only available in debug builds. +# It instructs InnoDB to try to evict pages from the buffer pool when +# change buffering is possible, so that the change buffer will be used +# whenever possible. +-- error 0,ER_UNKNOWN_SYSTEM_VARIABLE +SET @innodb_change_buffering_debug_orig = @@innodb_change_buffering_debug; +-- error 0,ER_UNKNOWN_SYSTEM_VARIABLE +SET GLOBAL innodb_change_buffering_debug = 1; +-- enable_query_log +SET GLOBAL tx_isolation='REPEATABLE-READ'; + +CREATE TABLE bug56680( + a INT AUTO_INCREMENT PRIMARY KEY, + b CHAR(1), + c INT, + INDEX(b)) +ENGINE=InnoDB; + +INSERT INTO bug56680 VALUES(0,'x',1); +BEGIN; +SELECT b FROM bug56680; + +connect (con1,localhost,root,,); +connection con1; +BEGIN; +UPDATE bug56680 SET b='X'; + +connection default; +# This should return the last committed value 'x', but would return 'X' +# due to a bug in row_search_for_mysql(). +SELECT b FROM bug56680; +# This would always return the last committed value 'x'. +SELECT * FROM bug56680; + +connection con1; +ROLLBACK; +disconnect con1; + +connection default; + +SELECT b FROM bug56680; + +# For the rest of this test, use the READ UNCOMMITTED isolation level +# to see what exists in the secondary index. +SET GLOBAL tx_isolation='READ-UNCOMMITTED'; + +# Create enough rows for the table, so that the insert buffer will be +# used for modifying the secondary index page. There must be multiple +# index pages, because changes to the root page are never buffered. + +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; + +BEGIN; +SELECT b FROM bug56680 LIMIT 2; + +connect (con1,localhost,root,,); +connection con1; +BEGIN; +DELETE FROM bug56680 WHERE a=1; +# This should be buffered, if innodb_change_buffering_debug = 1 is in effect. +INSERT INTO bug56680 VALUES(1,'X',1); + +# This should force an insert buffer merge, and return 'X' in the first row. +SELECT b FROM bug56680 LIMIT 3; + +connection default; +SELECT b FROM bug56680 LIMIT 2; +CHECK TABLE bug56680; + +connection con1; +ROLLBACK; +SELECT b FROM bug56680 LIMIT 2; +CHECK TABLE bug56680; + +connection default; +disconnect con1; + +SELECT b FROM bug56680 LIMIT 2; + +CREATE TABLE bug56680_2( + a INT AUTO_INCREMENT PRIMARY KEY, + b VARCHAR(2) CHARSET latin1 COLLATE latin1_german2_ci, + c INT, + INDEX(b)) +ENGINE=InnoDB; + +INSERT INTO bug56680_2 SELECT 0,_latin1 0xdf,c FROM bug56680; + +BEGIN; +SELECT HEX(b) FROM bug56680_2 LIMIT 2; +DELETE FROM bug56680_2 WHERE a=1; +# This should be buffered, if innodb_change_buffering_debug = 1 is in effect. +INSERT INTO bug56680_2 VALUES(1,'SS',1); + +# This should force an insert buffer merge, and return 'SS' in the first row. +SELECT HEX(b) FROM bug56680_2 LIMIT 3; +CHECK TABLE bug56680_2; + +DELETE FROM bug56680_2 WHERE a=1; +# This should be buffered, if innodb_change_buffering_debug = 1 is in effect. +INSERT INTO bug56680_2 VALUES(1,_latin1 0xdf,1); + +# This should force an insert buffer merge, and return 0xdf in the first row. +SELECT HEX(b) FROM bug56680_2 LIMIT 3; +CHECK TABLE bug56680_2; + +DROP TABLE bug56680_2; +DROP TABLE bug56680; + +-- disable_query_log +SET GLOBAL tx_isolation = @tx_isolation_orig; +-- error 0, ER_UNKNOWN_SYSTEM_VARIABLE +SET GLOBAL innodb_change_buffering_debug = @innodb_change_buffering_debug_orig; diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c index 45867388a61..500088c3901 100644 --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c @@ -1270,6 +1270,30 @@ loop: buf_awe_map_page_to_frame(block, TRUE); } +#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG + if (mode == BUF_GET_IF_IN_POOL && ibuf_debug) { + /* Try to evict the block from the buffer pool, to use the + insert buffer as much as possible. */ + + if (buf_LRU_free_block(block)) { + mutex_exit(&buf_pool->mutex); + mutex_exit(&block->mutex); + fprintf(stderr, + "innodb_change_buffering_debug evict %u %u\n", + (unsigned) space, (unsigned) offset); + return(NULL); + } else if (buf_flush_page_try(block)) { + fprintf(stderr, + "innodb_change_buffering_debug flush %u %u\n", + (unsigned) space, (unsigned) offset); + guess = block->frame; + goto loop; + } + + /* Failed to evict the page; change it directly */ + } +#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ + #ifdef UNIV_SYNC_DEBUG buf_block_buf_fix_inc_debug(block, file, line); #else diff --git a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c index 24fa306c127..7dd6bfd9198 100644 --- a/storage/innobase/buf/buf0flu.c +++ b/storage/innobase/buf/buf0flu.c @@ -723,6 +723,82 @@ buf_flush_try_page( return(0); } +# if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG +/********************************************************************** +Writes a flushable page asynchronously from the buffer pool to a file. +NOTE: buf_pool_mutex and block->mutex must be held upon entering this +function, and they will be released by this function after flushing. +This is loosely based on buf_flush_batch() and buf_flush_try_page(). */ + +ibool +buf_flush_page_try( +/*===============*/ + /* out: TRUE if flushed and + mutexes released */ + buf_block_t* block) /*!< in/out: buffer control block */ +{ + ut_ad(mutex_own(&buf_pool->mutex)); + ut_ad(block->state == BUF_BLOCK_FILE_PAGE); + ut_ad(mutex_own(&block->mutex)); + + if (!buf_flush_ready_for_flush(block, BUF_FLUSH_LRU)) { + return(FALSE); + } + + if (buf_pool->n_flush[BUF_FLUSH_LRU] > 0 + || buf_pool->init_flush[BUF_FLUSH_LRU]) { + /* There is already a flush batch of the same type running */ + return(FALSE); + } + + buf_pool->init_flush[BUF_FLUSH_LRU] = TRUE; + + block->io_fix = BUF_IO_WRITE; + block->flush_type = BUF_FLUSH_LRU; + + if (buf_pool->n_flush[BUF_FLUSH_LRU]++ == 0) { + + os_event_reset(buf_pool->no_flush[BUF_FLUSH_LRU]); + } + + /* VERY IMPORTANT: + Because any thread may call the LRU flush, even when owning + locks on pages, to avoid deadlocks, we must make sure that the + s-lock is acquired on the page without waiting: this is + accomplished because buf_flush_ready_for_flush() must hold, + and that requires the page not to be bufferfixed. */ + + rw_lock_s_lock_gen(&block->lock, BUF_IO_WRITE); + + /* Note that the s-latch is acquired before releasing the + buf_pool mutex: this ensures that the latch is acquired + immediately. */ + + mutex_exit(&block->mutex); + mutex_exit(&buf_pool->mutex); + + /* Even though block is not protected by any mutex at this + point, it is safe to access block, because it is io_fixed and + oldest_modification != 0. Thus, it cannot be relocated in the + buffer pool or removed from flush_list or LRU_list. */ + + buf_flush_write_block_low(block); + + mutex_enter(&buf_pool->mutex); + buf_pool->init_flush[BUF_FLUSH_LRU] = FALSE; + + if (buf_pool->n_flush[BUF_FLUSH_LRU] == 0) { + /* The running flush batch has ended */ + os_event_set(buf_pool->no_flush[BUF_FLUSH_LRU]); + } + + mutex_exit(&buf_pool->mutex); + buf_flush_buffered_writes(); + + return(TRUE); +} +#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ + /*************************************************************** Flushes to disk all flushable pages within the flush area. */ static diff --git a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c index d3c787d1578..1dc3efd1464 100644 --- a/storage/innobase/buf/buf0lru.c +++ b/storage/innobase/buf/buf0lru.c @@ -320,6 +320,60 @@ buf_LRU_get_recent_limit(void) return(limit); } +/********************************************************************** +Try to put a block from the LRU list to the free list. */ + +ibool +buf_LRU_free_block( +/*===============*/ + /* out: TRUE if freed */ + buf_block_t* block) /* in/out: block to be freed */ +{ + if (!buf_flush_ready_for_replace(block)) { + return(FALSE); + } + +#ifdef UNIV_DEBUG + if (buf_debug_prints) { + fprintf(stderr, + "Putting space %lu page %lu" + " to free list\n", + (ulong) block->space, + (ulong) block->offset); + } +#endif /* UNIV_DEBUG */ + + buf_LRU_block_remove_hashed_page(block); + + mutex_exit(&(buf_pool->mutex)); + mutex_exit(&block->mutex); + + /* Remove possible adaptive hash index built on the + page; in the case of AWE the block may not have a + frame at all */ + + if (block->frame) { + /* The page was declared uninitialized + by buf_LRU_block_remove_hashed_page(). + We need to flag the contents of the + page valid (which it still is) in + order to avoid bogus Valgrind + warnings. */ + UNIV_MEM_VALID(block->frame, UNIV_PAGE_SIZE); + btr_search_drop_page_hash_index(block->frame); + UNIV_MEM_INVALID(block->frame, UNIV_PAGE_SIZE); + } + + ut_a(block->buf_fix_count == 0); + + mutex_enter(&(buf_pool->mutex)); + mutex_enter(&block->mutex); + + buf_LRU_block_free_hashed_page(block); + + return(TRUE); +} + /********************************************************************** Look for a replaceable block from the end of the LRU list and put it to the free list if found. */ @@ -348,54 +402,13 @@ buf_LRU_search_and_free_block( ut_a(block->in_LRU_list); mutex_enter(&block->mutex); + freed = buf_LRU_free_block(block); + mutex_exit(&block->mutex); - if (buf_flush_ready_for_replace(block)) { - -#ifdef UNIV_DEBUG - if (buf_debug_prints) { - fprintf(stderr, - "Putting space %lu page %lu" - " to free list\n", - (ulong) block->space, - (ulong) block->offset); - } -#endif /* UNIV_DEBUG */ - - buf_LRU_block_remove_hashed_page(block); - - mutex_exit(&(buf_pool->mutex)); - mutex_exit(&block->mutex); - - /* Remove possible adaptive hash index built on the - page; in the case of AWE the block may not have a - frame at all */ - - if (block->frame) { - /* The page was declared uninitialized - by buf_LRU_block_remove_hashed_page(). - We need to flag the contents of the - page valid (which it still is) in - order to avoid bogus Valgrind - warnings. */ - UNIV_MEM_VALID(block->frame, UNIV_PAGE_SIZE); - btr_search_drop_page_hash_index(block->frame); - UNIV_MEM_INVALID(block->frame, UNIV_PAGE_SIZE); - } - - ut_a(block->buf_fix_count == 0); - - mutex_enter(&(buf_pool->mutex)); - mutex_enter(&block->mutex); - - buf_LRU_block_free_hashed_page(block); - freed = TRUE; - mutex_exit(&block->mutex); - + if (freed) { break; } - mutex_exit(&block->mutex); - block = UT_LIST_GET_PREV(LRU, block); distance++; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 5a8f5479223..4c52326a58a 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -79,6 +79,7 @@ extern "C" { #include "../storage/innobase/include/dict0crea.h" #include "../storage/innobase/include/btr0cur.h" #include "../storage/innobase/include/btr0btr.h" +#include "../storage/innobase/include/ibuf0ibuf.h" #include "../storage/innobase/include/fsp0fsp.h" #include "../storage/innobase/include/sync0sync.h" #include "../storage/innobase/include/fil0fil.h" @@ -3723,17 +3724,18 @@ include_field: n_requested_fields++; templ->col_no = i; + templ->clust_rec_field_no = dict_col_get_clust_pos_noninline( + &index->table->cols[i], clust_index); + ut_ad(templ->clust_rec_field_no != ULINT_UNDEFINED); if (index == clust_index) { - templ->rec_field_no = dict_col_get_clust_pos_noninline( - &index->table->cols[i], index); + templ->rec_field_no = templ->clust_rec_field_no; } else { templ->rec_field_no = dict_index_get_nth_col_pos( index, i); - } - - if (templ->rec_field_no == ULINT_UNDEFINED) { - prebuilt->need_to_access_clustered = TRUE; + if (templ->rec_field_no == ULINT_UNDEFINED) { + prebuilt->need_to_access_clustered = TRUE; + } } if (field->null_ptr) { @@ -3785,9 +3787,7 @@ skip_field: for (i = 0; i < n_requested_fields; i++) { templ = prebuilt->mysql_template + i; - templ->rec_field_no = dict_col_get_clust_pos_noninline( - &index->table->cols[templ->col_no], - clust_index); + templ->rec_field_no = templ->clust_rec_field_no; } } } @@ -8990,6 +8990,13 @@ static MYSQL_SYSVAR_LONG(autoinc_lock_mode, innobase_autoinc_lock_mode, AUTOINC_OLD_STYLE_LOCKING, /* Minimum value */ AUTOINC_NO_LOCKING, 0); /* Maximum value */ +#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG +static MYSQL_SYSVAR_UINT(change_buffering_debug, ibuf_debug, + PLUGIN_VAR_RQCMDARG, + "Debug flags for InnoDB change buffering (0=none)", + NULL, NULL, 0, 0, 1, 0); +#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ + static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(additional_mem_pool_size), MYSQL_SYSVAR(autoextend_increment), @@ -9031,6 +9038,9 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(thread_concurrency), MYSQL_SYSVAR(thread_sleep_delay), MYSQL_SYSVAR(autoinc_lock_mode), +#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG + MYSQL_SYSVAR(change_buffering_debug), +#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ NULL }; diff --git a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c index d54a3378993..71ecc7ec49f 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.c +++ b/storage/innobase/ibuf/ibuf0ibuf.c @@ -22,6 +22,7 @@ Created 7/19/1997 Heikki Tuuri #include "btr0cur.h" #include "btr0pcur.h" #include "btr0btr.h" +#include "row0upd.h" #include "sync0sync.h" #include "dict0boot.h" #include "fut0lst.h" @@ -137,6 +138,11 @@ access order rules. */ /* Buffer pool size per the maximum insert buffer size */ #define IBUF_POOL_SIZE_PER_MAX_SIZE 2 +#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG +/* Flag to control insert buffer debugging. */ +uint ibuf_debug; +#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ + /* The insert buffer control structure */ ibuf_t* ibuf = NULL; @@ -2819,6 +2825,72 @@ ibuf_insert( } } +/************************************************************************ +During merge, inserts to an index page a secondary index entry extracted +from the insert buffer. */ +static +void +ibuf_insert_to_index_page_low( +/*==========================*/ + dtuple_t* entry, /* in: buffered entry to insert */ + page_t* page, /* in: index page where the buffered entry + should be placed */ + dict_index_t* index, /* in: record descriptor */ + mtr_t* mtr, /* in: mtr */ + page_cur_t* page_cur)/* in: cursor positioned on the record + after which to insert the buffered entry */ +{ + ulint space; + ulint page_no; + page_t* bitmap_page; + ulint old_bits; + + if (UNIV_LIKELY + (page_cur_tuple_insert(page_cur, entry, index, mtr) != NULL)) { + return; + } + + /* If the record did not fit, reorganize */ + + btr_page_reorganize(page, index, mtr); + + page_cur_search(page, index, entry, PAGE_CUR_LE, page_cur); + + /* This time the record must fit */ + + if (UNIV_LIKELY + (page_cur_tuple_insert(page_cur, entry, index, mtr) != NULL)) { + return; + } + + ut_print_timestamp(stderr); + + fprintf(stderr, + " InnoDB: Error: Insert buffer insert fails;" + " page free %lu, dtuple size %lu\n", + (ulong) page_get_max_insert_size(page, 1), + (ulong) rec_get_converted_size(index, entry)); + fputs("InnoDB: Cannot insert index record ", stderr); + dtuple_print(stderr, entry); + fputs("\nInnoDB: The table where this index record belongs\n" + "InnoDB: is now probably corrupt. Please run CHECK TABLE on\n" + "InnoDB: that table.\n", stderr); + + space = buf_frame_get_space_id(page); + page_no = buf_frame_get_page_no(page); + + bitmap_page = ibuf_bitmap_get_map_page(space, page_no, mtr); + old_bits = ibuf_bitmap_page_get_bits(bitmap_page, page_no, + IBUF_BITMAP_FREE, mtr); + + fprintf(stderr, + "InnoDB: space %lu, page %lu, bitmap bits %lu\n", + (ulong) space, (ulong) page_no, (ulong) old_bits); + + fputs("InnoDB: Submit a detailed bug report" + " to http://bugs.mysql.com\n", stderr); +} + /************************************************************************ During merge, inserts to an index page a secondary index entry extracted from the insert buffer. */ @@ -2835,11 +2907,10 @@ ibuf_insert_to_index_page( page_cur_t page_cur; ulint low_match; rec_t* rec; - page_t* bitmap_page; - ulint old_bits; ut_ad(ibuf_inside()); ut_ad(dtuple_check_typed(entry)); + ut_ad(!buf_block_align(page)->is_hashed); if (UNIV_UNLIKELY(dict_table_is_comp(index->table) != (ibool)!!page_is_comp(page))) { @@ -2877,61 +2948,79 @@ dump: low_match = page_cur_search(page, index, entry, PAGE_CUR_LE, &page_cur); - if (low_match == dtuple_get_n_fields(entry)) { + if (UNIV_UNLIKELY(low_match == dtuple_get_n_fields(entry))) { + mem_heap_t* heap; + upd_t* update; + ulint* offsets; + rec = page_cur_get_rec(&page_cur); - btr_cur_del_unmark_for_ibuf(rec, mtr); - } else { - rec = page_cur_tuple_insert(&page_cur, entry, index, mtr); + /* This is based on + row_ins_sec_index_entry_by_modify(BTR_MODIFY_LEAF). */ + ut_ad(rec_get_deleted_flag(rec, page_is_comp(page))); - if (rec == NULL) { - /* If the record did not fit, reorganize */ + heap = mem_heap_create(1024); - btr_page_reorganize(page, index, mtr); + offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, + &heap); + update = row_upd_build_sec_rec_difference_binary( + index, entry, rec, NULL, heap); - page_cur_search(page, index, entry, - PAGE_CUR_LE, &page_cur); - - /* This time the record must fit */ - if (UNIV_UNLIKELY(!page_cur_tuple_insert( - &page_cur, entry, index, - mtr))) { - - ut_print_timestamp(stderr); - - fprintf(stderr, - " InnoDB: Error: Insert buffer insert" - " fails; page free %lu," - " dtuple size %lu\n", - (ulong) page_get_max_insert_size( - page, 1), - (ulong) rec_get_converted_size( - index, entry)); - fputs("InnoDB: Cannot insert index record ", - stderr); - dtuple_print(stderr, entry); - fputs("\nInnoDB: The table where" - " this index record belongs\n" - "InnoDB: is now probably corrupt." - " Please run CHECK TABLE on\n" - "InnoDB: that table.\n", stderr); - - bitmap_page = ibuf_bitmap_get_map_page( - buf_frame_get_space_id(page), - buf_frame_get_page_no(page), - mtr); - old_bits = ibuf_bitmap_page_get_bits( - bitmap_page, - buf_frame_get_page_no(page), - IBUF_BITMAP_FREE, mtr); - - fprintf(stderr, "InnoDB: Bitmap bits %lu\n", - (ulong) old_bits); - - fputs("InnoDB: Submit a detailed bug report" - " to http://bugs.mysql.com\n", stderr); - } + if (update->n_fields == 0) { + /* The records only differ in the delete-mark. + Clear the delete-mark, like we did before + Bug #56680 was fixed. */ + btr_cur_del_unmark_for_ibuf(rec, mtr); +updated_in_place: + mem_heap_free(heap); + return; } + + /* Copy the info bits. Clear the delete-mark. */ + update->info_bits = rec_get_info_bits(rec, page_is_comp(page)); + update->info_bits &= ~REC_INFO_DELETED_FLAG; + + /* We cannot invoke btr_cur_optimistic_update() here, + because we do not have a btr_cur_t or que_thr_t, + as the insert buffer merge occurs at a very low level. */ + if (!row_upd_changes_field_size_or_external(index, offsets, + update)) { + /* This is the easy case. Do something similar + to btr_cur_update_in_place(). */ + row_upd_rec_in_place(rec, offsets, update); + goto updated_in_place; + } + + /* A collation may identify values that differ in + storage length. + Some examples (1 or 2 bytes): + utf8_turkish_ci: I = U+0131 LATIN SMALL LETTER DOTLESS I + utf8_general_ci: S = U+00DF LATIN SMALL LETTER SHARP S + utf8_general_ci: A = U+00E4 LATIN SMALL LETTER A WITH DIAERESIS + + latin1_german2_ci: SS = U+00DF LATIN SMALL LETTER SHARP S + + Examples of a character (3-byte UTF-8 sequence) + identified with 2 or 4 characters (1-byte UTF-8 sequences): + + utf8_unicode_ci: 'II' = U+2171 SMALL ROMAN NUMERAL TWO + utf8_unicode_ci: '(10)' = U+247D PARENTHESIZED NUMBER TEN + */ + + /* Delete the different-length record, and insert the + buffered one. */ + + lock_rec_store_on_page_infimum(page, rec); + page_cur_delete_rec(&page_cur, index, offsets, mtr); + page_cur_move_to_prev(&page_cur); + mem_heap_free(heap); + + ibuf_insert_to_index_page_low(entry, page, index, mtr, + &page_cur); + lock_rec_restore_from_page_infimum(rec, page); + } else { + ibuf_insert_to_index_page_low(entry, page, index, mtr, + &page_cur); } } diff --git a/storage/innobase/include/buf0flu.h b/storage/innobase/include/buf0flu.h index 322848509f4..e52c22b8f57 100644 --- a/storage/innobase/include/buf0flu.h +++ b/storage/innobase/include/buf0flu.h @@ -38,6 +38,20 @@ buf_flush_init_for_writing( dulint newest_lsn, /* in: newest modification lsn to the page */ ulint space, /* in: space id */ ulint page_no); /* in: page number */ +# if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG +/********************************************************************** +Writes a flushable page asynchronously from the buffer pool to a file. +NOTE: buf_pool_mutex and block->mutex must be held upon entering this +function, and they will be released by this function after flushing. +This is loosely based on buf_flush_batch() and buf_flush_try_page(). */ + +ibool +buf_flush_page_try( +/*===============*/ + /* out: TRUE if flushed and + mutexes released */ + buf_block_t* block); /*!< in/out: buffer control block */ +#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ /*********************************************************************** This utility flushes dirty blocks from the end of the LRU list or flush_list. NOTE 1: in the case of an LRU flush the calling thread may own latches to diff --git a/storage/innobase/include/buf0lru.h b/storage/innobase/include/buf0lru.h index 6d26fd4d3b2..777e55a350d 100644 --- a/storage/innobase/include/buf0lru.h +++ b/storage/innobase/include/buf0lru.h @@ -66,6 +66,14 @@ buf_LRU_get_recent_limit(void); /*==========================*/ /* out: the limit; zero if could not determine it */ /********************************************************************** +Try to put a block from the LRU list to the free list. */ + +ibool +buf_LRU_free_block( +/*===============*/ + /* out: TRUE if freed */ + buf_block_t* block); /* in/out: block to be freed */ +/********************************************************************** Look for a replaceable block from the end of the LRU list and put it to the free list if found. */ diff --git a/storage/innobase/include/ibuf0ibuf.h b/storage/innobase/include/ibuf0ibuf.h index 77fefe2020b..d6d7a918b62 100644 --- a/storage/innobase/include/ibuf0ibuf.h +++ b/storage/innobase/include/ibuf0ibuf.h @@ -18,6 +18,11 @@ Created 7/19/1997 Heikki Tuuri #include "ibuf0types.h" #include "fsp0fsp.h" +#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG +/* Flag to control insert buffer debugging. */ +extern uint ibuf_debug; +#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ + extern ibuf_t* ibuf; /********************************************************************** diff --git a/storage/innobase/include/rem0rec.h b/storage/innobase/include/rem0rec.h index abc204bb583..58762fc3111 100644 --- a/storage/innobase/include/rem0rec.h +++ b/storage/innobase/include/rem0rec.h @@ -19,6 +19,9 @@ if and only if the record is the first user record on a non-leaf B-tree page that is the leftmost page on its level (PAGE_LEVEL is nonzero and FIL_PAGE_PREV is FIL_NULL). */ #define REC_INFO_MIN_REC_FLAG 0x10UL +/* The deleted flag in info bits */ +#define REC_INFO_DELETED_FLAG 0x20UL /* when bit is set to 1, it means the + record has been delete marked */ /* Number of extra bytes in an old-style record, in addition to the data and the offsets */ diff --git a/storage/innobase/include/rem0rec.ic b/storage/innobase/include/rem0rec.ic index d91fb4c4391..df66bb13aeb 100644 --- a/storage/innobase/include/rem0rec.ic +++ b/storage/innobase/include/rem0rec.ic @@ -98,9 +98,6 @@ and the shift needed to obtain each bit-field of the record. */ #define REC_INFO_BITS_MASK 0xF0UL #define REC_INFO_BITS_SHIFT 0 -/* The deleted flag in info bits */ -#define REC_INFO_DELETED_FLAG 0x20UL /* when bit is set to 1, it means the - record has been delete marked */ /* The following masks are used to filter the SQL null bit from one-byte and two-byte offsets */ diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index 488177791a4..52b13838cc7 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -485,6 +485,10 @@ struct mysql_row_templ_struct { Innobase record in the current index; not defined if template_type is ROW_MYSQL_WHOLE_ROW */ + ulint clust_rec_field_no; /* field number of the column in an + Innobase record in the clustered index; + not defined if template_type is + ROW_MYSQL_WHOLE_ROW */ ulint mysql_col_offset; /* offset of the column in the MySQL row format */ ulint mysql_col_len; /* length of the column in the MySQL diff --git a/storage/innobase/include/row0upd.h b/storage/innobase/include/row0upd.h index efbc6d6facf..034b1dafb17 100644 --- a/storage/innobase/include/row0upd.h +++ b/storage/innobase/include/row0upd.h @@ -129,9 +129,11 @@ row_upd_changes_field_size_or_external( const ulint* offsets,/* in: rec_get_offsets(rec, index) */ upd_t* update);/* in: update vector */ /*************************************************************** -Replaces the new column values stored in the update vector to the record -given. No field size changes are allowed. This function is used only for -a clustered index */ +Replaces the new column values stored in the update vector to the +record given. No field size changes are allowed. This function is +usually invoked on a clustered index. The only use case for a +secondary index is row_ins_sec_index_entry_by_modify() or its +counterpart in ibuf_insert_to_index_page(). */ void row_upd_rec_in_place( diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index a0f54f7288e..99738115cc7 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -400,7 +400,7 @@ row_mysql_convert_row_to_innobase( row is used, as row may contain pointers to this record! */ { - mysql_row_templ_t* templ; + const mysql_row_templ_t*templ; dfield_t* dfield; ulint i; diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c index ad15d0798a2..e03d3d79768 100644 --- a/storage/innobase/row/row0sel.c +++ b/storage/innobase/row/row0sel.c @@ -2601,20 +2601,21 @@ row_sel_store_mysql_rec( row_prebuilt_t* prebuilt, /* in: prebuilt struct */ rec_t* rec, /* in: Innobase record in the index which was described in prebuilt's - template */ + template, or in the clustered index; + must be protected by a page latch */ + ibool rec_clust, /* in: TRUE if rec is in the clustered + index instead of prebuilt->index */ const ulint* offsets) /* in: array returned by - rec_get_offsets() */ + rec_get_offsets(rec) */ { - mysql_row_templ_t* templ; mem_heap_t* extern_field_heap = NULL; mem_heap_t* heap; - byte* data; - ulint len; ulint i; ut_ad(prebuilt->mysql_template); ut_ad(prebuilt->default_rec); ut_ad(rec_offs_validate(rec, NULL, offsets)); + ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets))); if (UNIV_LIKELY_NULL(prebuilt->blob_heap)) { mem_heap_free(prebuilt->blob_heap); @@ -2623,10 +2624,15 @@ row_sel_store_mysql_rec( for (i = 0; i < prebuilt->n_template; i++) { - templ = prebuilt->mysql_template + i; + const mysql_row_templ_t*templ = prebuilt->mysql_template + i; + byte* data; + ulint len; + ulint field_no; - if (UNIV_UNLIKELY(rec_offs_nth_extern(offsets, - templ->rec_field_no))) { + field_no = rec_clust + ? templ->clust_rec_field_no : templ->rec_field_no; + + if (UNIV_UNLIKELY(rec_offs_nth_extern(offsets, field_no))) { /* Copy an externally stored field to the temporary heap */ @@ -2652,15 +2658,13 @@ row_sel_store_mysql_rec( causes an assert */ data = btr_rec_copy_externally_stored_field( - rec, offsets, templ->rec_field_no, - &len, heap); + rec, offsets, field_no, &len, heap); ut_a(len != UNIV_SQL_NULL); } else { /* Field is stored in the row. */ - data = rec_get_nth_field(rec, offsets, - templ->rec_field_no, &len); + data = rec_get_nth_field(rec, offsets, field_no, &len); if (UNIV_UNLIKELY(templ->type == DATA_BLOB) && len != UNIV_SQL_NULL) { @@ -3019,7 +3023,7 @@ row_sel_pop_cached_row_for_mysql( row_prebuilt_t* prebuilt) /* in: prebuilt struct */ { ulint i; - mysql_row_templ_t* templ; + const mysql_row_templ_t*templ; byte* cached_rec; ut_ad(prebuilt->n_fetch_cached > 0); ut_ad(prebuilt->mysql_prefix_len <= prebuilt->mysql_row_len); @@ -3075,14 +3079,19 @@ void row_sel_push_cache_row_for_mysql( /*=============================*/ row_prebuilt_t* prebuilt, /* in: prebuilt struct */ - rec_t* rec, /* in: record to push */ - const ulint* offsets) /* in: rec_get_offsets() */ + rec_t* rec, /* in: Innobase record in the index + which was described in prebuilt's + template, or in the clustered index */ + ibool rec_clust, /* in: TRUE if rec is in the clustered + index instead of prebuilt->index */ + const ulint* offsets) /* in: rec_get_offsets(rec) */ { byte* buf; ulint i; ut_ad(prebuilt->n_fetch_cached < MYSQL_FETCH_CACHE_SIZE); ut_ad(rec_offs_validate(rec, NULL, offsets)); + ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets))); ut_a(!prebuilt->templ_contains_blob); if (prebuilt->fetch_cache[0] == NULL) { @@ -3111,7 +3120,7 @@ row_sel_push_cache_row_for_mysql( if (UNIV_UNLIKELY(!row_sel_store_mysql_rec( prebuilt->fetch_cache[ prebuilt->n_fetch_cached], - prebuilt, rec, offsets))) { + prebuilt, rec, rec_clust, offsets))) { ut_error; } @@ -3500,7 +3509,8 @@ row_search_for_mysql( rec, offsets)); #endif if (!row_sel_store_mysql_rec(buf, prebuilt, - rec, offsets)) { + rec, FALSE, + offsets)) { err = DB_TOO_BIG_RECORD; /* We let the main loop to do the @@ -4233,19 +4243,8 @@ requires_clust_rec: goto next_rec; } - if (prebuilt->need_to_access_clustered) { - - result_rec = clust_rec; - - ut_ad(rec_offs_validate(result_rec, clust_index, - offsets)); - } else { - /* We used 'offsets' for the clust rec, recalculate - them for 'rec' */ - offsets = rec_get_offsets(rec, index, offsets, - ULINT_UNDEFINED, &heap); - result_rec = rec; - } + result_rec = clust_rec; + ut_ad(rec_offs_validate(result_rec, clust_index, offsets)); } else { result_rec = rec; } @@ -4256,6 +4255,7 @@ requires_clust_rec: ut_ad(rec_offs_validate(result_rec, result_rec != rec ? clust_index : index, offsets)); + ut_ad(!rec_get_deleted_flag(result_rec, comp)); if ((match_mode == ROW_SEL_EXACT || prebuilt->n_rows_fetched >= MYSQL_FETCH_CACHE_THRESHOLD) @@ -4276,7 +4276,7 @@ requires_clust_rec: cursor. */ row_sel_push_cache_row_for_mysql(prebuilt, result_rec, - offsets); + result_rec != rec, offsets); if (prebuilt->n_fetch_cached == MYSQL_FETCH_CACHE_SIZE) { goto got_row; @@ -4284,15 +4284,31 @@ requires_clust_rec: goto next_rec; } else { - if (prebuilt->template_type == ROW_MYSQL_DUMMY_TEMPLATE) { + if (UNIV_UNLIKELY + (prebuilt->template_type == ROW_MYSQL_DUMMY_TEMPLATE)) { + /* CHECK TABLE: fetch the row */ + + if (result_rec != rec + && !prebuilt->need_to_access_clustered) { + /* We used 'offsets' for the clust + rec, recalculate them for 'rec' */ + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, + &heap); + result_rec = rec; + } + memcpy(buf + 4, result_rec - rec_offs_extra_size(offsets), rec_offs_size(offsets)); mach_write_to_4(buf, rec_offs_extra_size(offsets) + 4); } else { - if (!row_sel_store_mysql_rec(buf, prebuilt, - result_rec, offsets)) { + /* Returning a row to MySQL */ + + if (!row_sel_store_mysql_rec(buf, prebuilt, result_rec, + result_rec != rec, + offsets)) { err = DB_TOO_BIG_RECORD; goto lock_wait_or_error; diff --git a/storage/innobase/row/row0upd.c b/storage/innobase/row/row0upd.c index 034b7010410..0790cfe02e2 100644 --- a/storage/innobase/row/row0upd.c +++ b/storage/innobase/row/row0upd.c @@ -430,9 +430,11 @@ row_upd_changes_field_size_or_external( } /*************************************************************** -Replaces the new column values stored in the update vector to the record -given. No field size changes are allowed. This function is used only for -a clustered index */ +Replaces the new column values stored in the update vector to the +record given. No field size changes are allowed. This function is +usually invoked on a clustered index. The only use case for a +secondary index is row_ins_sec_index_entry_by_modify() or its +counterpart in ibuf_insert_to_index_page(). */ void row_upd_rec_in_place( From c38071ec180f6e419ac0a1f2aa03cdd9263149a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 19 Oct 2010 09:04:15 +0300 Subject: [PATCH 059/304] Bug #56680 wrong InnoDB results from a case-insensitive covering index row_search_for_mysql(): When a secondary index record might not be visible in the current transaction's read view and we consult the clustered index and optionally some undo log records, return the relevant columns of the clustered index record to MySQL instead of the secondary index record. ibuf_insert_to_index_page_low(): New function, refactored from ibuf_insert_to_index_page(). ibuf_insert_to_index_page(): When we are inserting a record in place of a delete-marked record and some fields of the record differ, update that record just like row_ins_sec_index_entry_by_modify() would do. btr_cur_update_alloc_zip(): Make the function public. mysql_row_templ_t: Add clust_rec_field_no. row_sel_store_mysql_rec(), row_sel_push_cache_row_for_mysql(): Add the flag rec_clust, for returning data at clust_rec_field_no instead of rec_field_no. Resurrect the debug assertion that the record not be marked for deletion. (Bug #55626) [UNIV_DEBUG || UNIV_IBUF_DEBUG] ibuf_debug, buf_page_get_gen(), buf_flush_page_try(): Implement innodb_change_buffering_debug=1 for evicting pages from the buffer pool, so that change buffering will be attempted more frequently. --- .../innodb_plugin/r/innodb_bug56680.result | 109 +++++++++ .../innodb_plugin/t/innodb_bug56680.test | 142 ++++++++++++ storage/innodb_plugin/ChangeLog | 10 + storage/innodb_plugin/btr/btr0cur.c | 2 +- storage/innodb_plugin/buf/buf0buf.c | 24 ++ storage/innodb_plugin/buf/buf0flu.c | 76 +++++++ storage/innodb_plugin/handler/ha_innodb.cc | 27 ++- storage/innodb_plugin/ibuf/ibuf0ibuf.c | 207 +++++++++++++----- storage/innodb_plugin/include/btr0cur.h | 16 ++ storage/innodb_plugin/include/buf0flu.h | 14 ++ storage/innodb_plugin/include/ibuf0ibuf.h | 5 + storage/innodb_plugin/include/row0mysql.h | 4 + storage/innodb_plugin/include/row0upd.h | 7 +- storage/innodb_plugin/row/row0mysql.c | 2 +- storage/innodb_plugin/row/row0sel.c | 99 +++++---- storage/innodb_plugin/row/row0upd.c | 7 +- 16 files changed, 635 insertions(+), 116 deletions(-) create mode 100644 mysql-test/suite/innodb_plugin/r/innodb_bug56680.result create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_bug56680.test diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug56680.result b/mysql-test/suite/innodb_plugin/r/innodb_bug56680.result new file mode 100644 index 00000000000..5e798b69167 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_bug56680.result @@ -0,0 +1,109 @@ +SET GLOBAL tx_isolation='REPEATABLE-READ'; +SET GLOBAL innodb_file_format=Barracuda; +SET GLOBAL innodb_file_per_table=on; +CREATE TABLE bug56680( +a INT AUTO_INCREMENT PRIMARY KEY, +b CHAR(1), +c INT, +INDEX(b)) +ENGINE=InnoDB; +INSERT INTO bug56680 VALUES(0,'x',1); +BEGIN; +SELECT b FROM bug56680; +b +x +BEGIN; +UPDATE bug56680 SET b='X'; +SELECT b FROM bug56680; +b +x +SELECT * FROM bug56680; +a b c +1 x 1 +ROLLBACK; +SELECT b FROM bug56680; +b +x +SET GLOBAL tx_isolation='READ-UNCOMMITTED'; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +BEGIN; +SELECT b FROM bug56680 LIMIT 2; +b +x +x +BEGIN; +DELETE FROM bug56680 WHERE a=1; +INSERT INTO bug56680 VALUES(1,'X',1); +SELECT b FROM bug56680 LIMIT 3; +b +X +x +x +SELECT b FROM bug56680 LIMIT 2; +b +x +x +CHECK TABLE bug56680; +Table Op Msg_type Msg_text +test.bug56680 check status OK +ROLLBACK; +SELECT b FROM bug56680 LIMIT 2; +b +x +x +CHECK TABLE bug56680; +Table Op Msg_type Msg_text +test.bug56680 check status OK +SELECT b FROM bug56680 LIMIT 2; +b +x +x +CREATE TABLE bug56680_2( +a INT AUTO_INCREMENT PRIMARY KEY, +b VARCHAR(2) CHARSET latin1 COLLATE latin1_german2_ci, +c INT, +INDEX(b)) +ENGINE=InnoDB; +INSERT INTO bug56680_2 SELECT 0,_latin1 0xdf,c FROM bug56680; +BEGIN; +SELECT HEX(b) FROM bug56680_2 LIMIT 2; +HEX(b) +DF +DF +DELETE FROM bug56680_2 WHERE a=1; +INSERT INTO bug56680_2 VALUES(1,'SS',1); +SELECT HEX(b) FROM bug56680_2 LIMIT 3; +HEX(b) +5353 +DF +DF +CHECK TABLE bug56680_2; +Table Op Msg_type Msg_text +test.bug56680_2 check status OK +ALTER TABLE bug56680_2 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; +SELECT HEX(b) FROM bug56680_2 LIMIT 2; +HEX(b) +5353 +DF +DELETE FROM bug56680_2 WHERE a=1; +INSERT INTO bug56680_2 VALUES(1,_latin1 0xdf,1); +SELECT HEX(b) FROM bug56680_2 LIMIT 3; +HEX(b) +DF +DF +DF +CHECK TABLE bug56680_2; +Table Op Msg_type Msg_text +test.bug56680_2 check status OK +DROP TABLE bug56680_2; +DROP TABLE bug56680; diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug56680.test b/mysql-test/suite/innodb_plugin/t/innodb_bug56680.test new file mode 100644 index 00000000000..8d0f685c723 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug56680.test @@ -0,0 +1,142 @@ +# +# Bug #56680 InnoDB may return wrong results from a case-insensitive index +# +-- source include/have_innodb_plugin.inc + +-- disable_query_log +SET @tx_isolation_orig = @@tx_isolation; +SET @innodb_file_per_table_orig = @@innodb_file_per_table; +SET @innodb_file_format_orig = @@innodb_file_format; +SET @innodb_file_format_check_orig = @@innodb_file_format_check; +# The flag innodb_change_buffering_debug is only available in debug builds. +# It instructs InnoDB to try to evict pages from the buffer pool when +# change buffering is possible, so that the change buffer will be used +# whenever possible. +-- error 0,ER_UNKNOWN_SYSTEM_VARIABLE +SET @innodb_change_buffering_debug_orig = @@innodb_change_buffering_debug; +-- error 0,ER_UNKNOWN_SYSTEM_VARIABLE +SET GLOBAL innodb_change_buffering_debug = 1; +-- enable_query_log +SET GLOBAL tx_isolation='REPEATABLE-READ'; +SET GLOBAL innodb_file_format=Barracuda; +SET GLOBAL innodb_file_per_table=on; + +CREATE TABLE bug56680( + a INT AUTO_INCREMENT PRIMARY KEY, + b CHAR(1), + c INT, + INDEX(b)) +ENGINE=InnoDB; + +INSERT INTO bug56680 VALUES(0,'x',1); +BEGIN; +SELECT b FROM bug56680; + +connect (con1,localhost,root,,); +connection con1; +BEGIN; +UPDATE bug56680 SET b='X'; + +connection default; +# This should return the last committed value 'x', but would return 'X' +# due to a bug in row_search_for_mysql(). +SELECT b FROM bug56680; +# This would always return the last committed value 'x'. +SELECT * FROM bug56680; + +connection con1; +ROLLBACK; +disconnect con1; + +connection default; + +SELECT b FROM bug56680; + +# For the rest of this test, use the READ UNCOMMITTED isolation level +# to see what exists in the secondary index. +SET GLOBAL tx_isolation='READ-UNCOMMITTED'; + +# Create enough rows for the table, so that the insert buffer will be +# used for modifying the secondary index page. There must be multiple +# index pages, because changes to the root page are never buffered. + +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; +INSERT INTO bug56680 SELECT 0,b,c FROM bug56680; + +BEGIN; +SELECT b FROM bug56680 LIMIT 2; + +connect (con1,localhost,root,,); +connection con1; +BEGIN; +DELETE FROM bug56680 WHERE a=1; +# This should be buffered, if innodb_change_buffering_debug = 1 is in effect. +INSERT INTO bug56680 VALUES(1,'X',1); + +# This should force an insert buffer merge, and return 'X' in the first row. +SELECT b FROM bug56680 LIMIT 3; + +connection default; +SELECT b FROM bug56680 LIMIT 2; +CHECK TABLE bug56680; + +connection con1; +ROLLBACK; +SELECT b FROM bug56680 LIMIT 2; +CHECK TABLE bug56680; + +connection default; +disconnect con1; + +SELECT b FROM bug56680 LIMIT 2; + +CREATE TABLE bug56680_2( + a INT AUTO_INCREMENT PRIMARY KEY, + b VARCHAR(2) CHARSET latin1 COLLATE latin1_german2_ci, + c INT, + INDEX(b)) +ENGINE=InnoDB; + +INSERT INTO bug56680_2 SELECT 0,_latin1 0xdf,c FROM bug56680; + +BEGIN; +SELECT HEX(b) FROM bug56680_2 LIMIT 2; +DELETE FROM bug56680_2 WHERE a=1; +# This should be buffered, if innodb_change_buffering_debug = 1 is in effect. +INSERT INTO bug56680_2 VALUES(1,'SS',1); + +# This should force an insert buffer merge, and return 'SS' in the first row. +SELECT HEX(b) FROM bug56680_2 LIMIT 3; +CHECK TABLE bug56680_2; + +# Test this with compressed tables. +ALTER TABLE bug56680_2 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; + +SELECT HEX(b) FROM bug56680_2 LIMIT 2; +DELETE FROM bug56680_2 WHERE a=1; +# This should be buffered, if innodb_change_buffering_debug = 1 is in effect. +INSERT INTO bug56680_2 VALUES(1,_latin1 0xdf,1); + +# This should force an insert buffer merge, and return 0xdf in the first row. +SELECT HEX(b) FROM bug56680_2 LIMIT 3; +CHECK TABLE bug56680_2; + +DROP TABLE bug56680_2; +DROP TABLE bug56680; + +-- disable_query_log +SET GLOBAL tx_isolation = @tx_isolation_orig; +SET GLOBAL innodb_file_per_table = @innodb_file_per_table_orig; +SET GLOBAL innodb_file_format = @innodb_file_format_orig; +SET GLOBAL innodb_file_format_check = @innodb_file_format_check_orig; +-- error 0, ER_UNKNOWN_SYSTEM_VARIABLE +SET GLOBAL innodb_change_buffering_debug = @innodb_change_buffering_debug_orig; diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 488669346fd..db37fa2b4bb 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,13 @@ +2010-10-19 The InnoDB Team + + * btr/btr0cur.c, buf/buf0buf.c, buf/buf0flu.c, handler/ha_innodb.cc, + ibuf/ibuf0ibuf.c, include/btr0cur.h, include/buf0flu.h, + include/ibuf0ibuf.h, include/row0mysql.h, + row/row0mysql.c, row/row0sel.c, + innodb_bug56680.test, innodb_bug56680.result: + Fix Bug #56680 InnoDB may return wrong results from a + case-insensitive covering index + 2010-10-18 The InnoDB Team * handler/ha_innodb.cc, handler/ha_innodb.h, innodb_bug57252.result, diff --git a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0cur.c index 9812e91e8a5..79fe328a631 100644 --- a/storage/innodb_plugin/btr/btr0cur.c +++ b/storage/innodb_plugin/btr/btr0cur.c @@ -1626,7 +1626,7 @@ func_exit: See if there is enough place in the page modification log to log an update-in-place. @return TRUE if enough place */ -static +UNIV_INTERN ibool btr_cur_update_alloc_zip( /*=====================*/ diff --git a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0buf.c index 660686bac1e..65d4311b840 100644 --- a/storage/innodb_plugin/buf/buf0buf.c +++ b/storage/innodb_plugin/buf/buf0buf.c @@ -2286,6 +2286,30 @@ wait_until_unfixed: bytes. */ UNIV_MEM_ASSERT_RW(&block->page, sizeof block->page); #endif +#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG + if (mode == BUF_GET_IF_IN_POOL && ibuf_debug) { + /* Try to evict the block from the buffer pool, to use the + insert buffer as much as possible. */ + + if (buf_LRU_free_block(&block->page, TRUE, NULL) + == BUF_LRU_FREED) { + buf_pool_mutex_exit(); + mutex_exit(&block->mutex); + fprintf(stderr, + "innodb_change_buffering_debug evict %u %u\n", + (unsigned) space, (unsigned) offset); + return(NULL); + } else if (buf_flush_page_try(block)) { + fprintf(stderr, + "innodb_change_buffering_debug flush %u %u\n", + (unsigned) space, (unsigned) offset); + guess = block; + goto loop; + } + + /* Failed to evict the page; change it directly */ + } +#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ buf_block_buf_fix_inc(block, file, line); diff --git a/storage/innodb_plugin/buf/buf0flu.c b/storage/innodb_plugin/buf/buf0flu.c index 747ce65879d..2123f8a060d 100644 --- a/storage/innodb_plugin/buf/buf0flu.c +++ b/storage/innodb_plugin/buf/buf0flu.c @@ -1039,6 +1039,82 @@ buf_flush_write_block_low( } } +# if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG +/********************************************************************//** +Writes a flushable page asynchronously from the buffer pool to a file. +NOTE: buf_pool_mutex and block->mutex must be held upon entering this +function, and they will be released by this function after flushing. +This is loosely based on buf_flush_batch() and buf_flush_page(). +@return TRUE if the page was flushed and the mutexes released */ +UNIV_INTERN +ibool +buf_flush_page_try( +/*===============*/ + buf_block_t* block) /*!< in/out: buffer control block */ +{ + ut_ad(buf_pool_mutex_own()); + ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE); + ut_ad(mutex_own(&block->mutex)); + + if (!buf_flush_ready_for_flush(&block->page, BUF_FLUSH_LRU)) { + return(FALSE); + } + + if (buf_pool->n_flush[BUF_FLUSH_LRU] > 0 + || buf_pool->init_flush[BUF_FLUSH_LRU]) { + /* There is already a flush batch of the same type running */ + return(FALSE); + } + + buf_pool->init_flush[BUF_FLUSH_LRU] = TRUE; + + buf_page_set_io_fix(&block->page, BUF_IO_WRITE); + + buf_page_set_flush_type(&block->page, BUF_FLUSH_LRU); + + if (buf_pool->n_flush[BUF_FLUSH_LRU]++ == 0) { + + os_event_reset(buf_pool->no_flush[BUF_FLUSH_LRU]); + } + + /* VERY IMPORTANT: + Because any thread may call the LRU flush, even when owning + locks on pages, to avoid deadlocks, we must make sure that the + s-lock is acquired on the page without waiting: this is + accomplished because buf_flush_ready_for_flush() must hold, + and that requires the page not to be bufferfixed. */ + + rw_lock_s_lock_gen(&block->lock, BUF_IO_WRITE); + + /* Note that the s-latch is acquired before releasing the + buf_pool mutex: this ensures that the latch is acquired + immediately. */ + + mutex_exit(&block->mutex); + buf_pool_mutex_exit(); + + /* Even though block is not protected by any mutex at this + point, it is safe to access block, because it is io_fixed and + oldest_modification != 0. Thus, it cannot be relocated in the + buffer pool or removed from flush_list or LRU_list. */ + + buf_flush_write_block_low(&block->page); + + buf_pool_mutex_enter(); + buf_pool->init_flush[BUF_FLUSH_LRU] = FALSE; + + if (buf_pool->n_flush[BUF_FLUSH_LRU] == 0) { + /* The running flush batch has ended */ + os_event_set(buf_pool->no_flush[BUF_FLUSH_LRU]); + } + + buf_pool_mutex_exit(); + buf_flush_buffered_writes(); + + return(TRUE); +} +# endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ + /********************************************************************//** Writes a flushable page asynchronously from the buffer pool to a file. NOTE: in simulated aio we must call diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index 35f1a4974e2..99d4f294f81 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -4432,17 +4432,18 @@ include_field: n_requested_fields++; templ->col_no = i; + templ->clust_rec_field_no = dict_col_get_clust_pos( + &index->table->cols[i], clust_index); + ut_ad(templ->clust_rec_field_no != ULINT_UNDEFINED); if (index == clust_index) { - templ->rec_field_no = dict_col_get_clust_pos( - &index->table->cols[i], index); + templ->rec_field_no = templ->clust_rec_field_no; } else { templ->rec_field_no = dict_index_get_nth_col_pos( index, i); - } - - if (templ->rec_field_no == ULINT_UNDEFINED) { - prebuilt->need_to_access_clustered = TRUE; + if (templ->rec_field_no == ULINT_UNDEFINED) { + prebuilt->need_to_access_clustered = TRUE; + } } if (field->null_ptr) { @@ -4494,9 +4495,7 @@ skip_field: for (i = 0; i < n_requested_fields; i++) { templ = prebuilt->mysql_template + i; - templ->rec_field_no = dict_col_get_clust_pos( - &index->table->cols[templ->col_no], - clust_index); + templ->rec_field_no = templ->clust_rec_field_no; } } } @@ -10945,6 +10944,13 @@ static MYSQL_SYSVAR_STR(change_buffering, innobase_change_buffering, innodb_change_buffering_validate, innodb_change_buffering_update, "inserts"); +#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG +static MYSQL_SYSVAR_UINT(change_buffering_debug, ibuf_debug, + PLUGIN_VAR_RQCMDARG, + "Debug flags for InnoDB change buffering (0=none)", + NULL, NULL, 0, 0, 1, 0); +#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ + static MYSQL_SYSVAR_ULONG(read_ahead_threshold, srv_read_ahead_threshold, PLUGIN_VAR_RQCMDARG, "Number of pages that must be accessed sequentially for InnoDB to " @@ -11005,6 +11011,9 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(version), MYSQL_SYSVAR(use_sys_malloc), MYSQL_SYSVAR(change_buffering), +#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG + MYSQL_SYSVAR(change_buffering_debug), +#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ MYSQL_SYSVAR(read_ahead_threshold), MYSQL_SYSVAR(io_capacity), NULL diff --git a/storage/innodb_plugin/ibuf/ibuf0ibuf.c b/storage/innodb_plugin/ibuf/ibuf0ibuf.c index 5e9b4b27611..701e8f0ef04 100644 --- a/storage/innodb_plugin/ibuf/ibuf0ibuf.c +++ b/storage/innodb_plugin/ibuf/ibuf0ibuf.c @@ -49,6 +49,7 @@ Created 7/19/1997 Heikki Tuuri #include "btr0cur.h" #include "btr0pcur.h" #include "btr0btr.h" +#include "row0upd.h" #include "sync0sync.h" #include "dict0boot.h" #include "fut0lst.h" @@ -170,6 +171,11 @@ access order rules. */ /** Operations that can currently be buffered. */ UNIV_INTERN ibuf_use_t ibuf_use = IBUF_USE_INSERT; +#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG +/** Flag to control insert buffer debugging. */ +UNIV_INTERN uint ibuf_debug; +#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ + /** The insert buffer control structure */ UNIV_INTERN ibuf_t* ibuf = NULL; @@ -2881,9 +2887,80 @@ During merge, inserts to an index page a secondary index entry extracted from the insert buffer. */ static void +ibuf_insert_to_index_page_low( +/*==========================*/ + const dtuple_t* entry, /*!< in: buffered entry to insert */ + buf_block_t* block, /*!< in/out: index page where the buffered + entry should be placed */ + dict_index_t* index, /*!< in: record descriptor */ + mtr_t* mtr, /*!< in/out: mtr */ + page_cur_t* page_cur)/*!< in/out: cursor positioned on the record + after which to insert the buffered entry */ +{ + const page_t* page; + ulint space; + ulint page_no; + ulint zip_size; + const page_t* bitmap_page; + ulint old_bits; + + if (UNIV_LIKELY + (page_cur_tuple_insert(page_cur, entry, index, 0, mtr) != NULL)) { + return; + } + + /* If the record did not fit, reorganize */ + + btr_page_reorganize(block, index, mtr); + page_cur_search(block, index, entry, PAGE_CUR_LE, page_cur); + + /* This time the record must fit */ + + if (UNIV_LIKELY + (page_cur_tuple_insert(page_cur, entry, index, 0, mtr) != NULL)) { + return; + } + + page = buf_block_get_frame(block); + + ut_print_timestamp(stderr); + + fprintf(stderr, + " InnoDB: Error: Insert buffer insert fails;" + " page free %lu, dtuple size %lu\n", + (ulong) page_get_max_insert_size(page, 1), + (ulong) rec_get_converted_size(index, entry, 0)); + fputs("InnoDB: Cannot insert index record ", stderr); + dtuple_print(stderr, entry); + fputs("\nInnoDB: The table where this index record belongs\n" + "InnoDB: is now probably corrupt. Please run CHECK TABLE on\n" + "InnoDB: that table.\n", stderr); + + space = page_get_space_id(page); + zip_size = buf_block_get_zip_size(block); + page_no = page_get_page_no(page); + + bitmap_page = ibuf_bitmap_get_map_page(space, page_no, zip_size, mtr); + old_bits = ibuf_bitmap_page_get_bits(bitmap_page, page_no, zip_size, + IBUF_BITMAP_FREE, mtr); + + fprintf(stderr, + "InnoDB: space %lu, page %lu, zip_size %lu, bitmap bits %lu\n", + (ulong) space, (ulong) page_no, + (ulong) zip_size, (ulong) old_bits); + + fputs("InnoDB: Submit a detailed bug report" + " to http://bugs.mysql.com\n", stderr); +} + +/************************************************************************ +During merge, inserts to an index page a secondary index entry extracted +from the insert buffer. */ +static +void ibuf_insert_to_index_page( /*======================*/ - dtuple_t* entry, /*!< in: buffered entry to insert */ + const dtuple_t* entry, /*!< in: buffered entry to insert */ buf_block_t* block, /*!< in/out: index page where the buffered entry should be placed */ dict_index_t* index, /*!< in: record descriptor */ @@ -2893,11 +2970,10 @@ ibuf_insert_to_index_page( ulint low_match; page_t* page = buf_block_get_frame(block); rec_t* rec; - page_t* bitmap_page; - ulint old_bits; ut_ad(ibuf_inside()); ut_ad(dtuple_check_typed(entry)); + ut_ad(!buf_block_align(page)->is_hashed); if (UNIV_UNLIKELY(dict_table_is_comp(index->table) != (ibool)!!page_is_comp(page))) { @@ -2935,71 +3011,86 @@ dump: low_match = page_cur_search(block, index, entry, PAGE_CUR_LE, &page_cur); - if (low_match == dtuple_get_n_fields(entry)) { + if (UNIV_UNLIKELY(low_match == dtuple_get_n_fields(entry))) { + mem_heap_t* heap; + upd_t* update; + ulint* offsets; page_zip_des_t* page_zip; rec = page_cur_get_rec(&page_cur); + + /* This is based on + row_ins_sec_index_entry_by_modify(BTR_MODIFY_LEAF). */ + ut_ad(rec_get_deleted_flag(rec, page_is_comp(page))); + + heap = mem_heap_create(1024); + + offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, + &heap); + update = row_upd_build_sec_rec_difference_binary( + index, entry, rec, NULL, heap); + page_zip = buf_block_get_page_zip(block); - btr_cur_del_unmark_for_ibuf(rec, page_zip, mtr); - } else { - rec = page_cur_tuple_insert(&page_cur, entry, index, 0, mtr); - - if (UNIV_LIKELY(rec != NULL)) { + if (update->n_fields == 0) { + /* The records only differ in the delete-mark. + Clear the delete-mark, like we did before + Bug #56680 was fixed. */ + btr_cur_del_unmark_for_ibuf(rec, page_zip, mtr); +updated_in_place: + mem_heap_free(heap); return; } - /* If the record did not fit, reorganize */ + /* Copy the info bits. Clear the delete-mark. */ + update->info_bits = rec_get_info_bits(rec, page_is_comp(page)); + update->info_bits &= ~REC_INFO_DELETED_FLAG; - btr_page_reorganize(block, index, mtr); - page_cur_search(block, index, entry, PAGE_CUR_LE, &page_cur); - - /* This time the record must fit */ - if (UNIV_UNLIKELY - (!page_cur_tuple_insert(&page_cur, entry, index, - 0, mtr))) { - ulint space; - ulint page_no; - ulint zip_size; - - ut_print_timestamp(stderr); - - fprintf(stderr, - " InnoDB: Error: Insert buffer insert" - " fails; page free %lu," - " dtuple size %lu\n", - (ulong) page_get_max_insert_size( - page, 1), - (ulong) rec_get_converted_size( - index, entry, 0)); - fputs("InnoDB: Cannot insert index record ", - stderr); - dtuple_print(stderr, entry); - fputs("\nInnoDB: The table where" - " this index record belongs\n" - "InnoDB: is now probably corrupt." - " Please run CHECK TABLE on\n" - "InnoDB: that table.\n", stderr); - - space = page_get_space_id(page); - zip_size = buf_block_get_zip_size(block); - page_no = page_get_page_no(page); - - bitmap_page = ibuf_bitmap_get_map_page( - space, page_no, zip_size, mtr); - old_bits = ibuf_bitmap_page_get_bits( - bitmap_page, page_no, zip_size, - IBUF_BITMAP_FREE, mtr); - - fprintf(stderr, - "InnoDB: space %lu, page %lu," - " zip_size %lu, bitmap bits %lu\n", - (ulong) space, (ulong) page_no, - (ulong) zip_size, (ulong) old_bits); - - fputs("InnoDB: Submit a detailed bug report" - " to http://bugs.mysql.com\n", stderr); + /* We cannot invoke btr_cur_optimistic_update() here, + because we do not have a btr_cur_t or que_thr_t, + as the insert buffer merge occurs at a very low level. */ + if (!row_upd_changes_field_size_or_external(index, offsets, + update) + && (!page_zip || btr_cur_update_alloc_zip( + page_zip, block, index, + rec_offs_size(offsets), FALSE, mtr))) { + /* This is the easy case. Do something similar + to btr_cur_update_in_place(). */ + row_upd_rec_in_place(rec, index, offsets, + update, page_zip); + goto updated_in_place; } + + /* A collation may identify values that differ in + storage length. + Some examples (1 or 2 bytes): + utf8_turkish_ci: I = U+0131 LATIN SMALL LETTER DOTLESS I + utf8_general_ci: S = U+00DF LATIN SMALL LETTER SHARP S + utf8_general_ci: A = U+00E4 LATIN SMALL LETTER A WITH DIAERESIS + + latin1_german2_ci: SS = U+00DF LATIN SMALL LETTER SHARP S + + Examples of a character (3-byte UTF-8 sequence) + identified with 2 or 4 characters (1-byte UTF-8 sequences): + + utf8_unicode_ci: 'II' = U+2171 SMALL ROMAN NUMERAL TWO + utf8_unicode_ci: '(10)' = U+247D PARENTHESIZED NUMBER TEN + */ + + /* Delete the different-length record, and insert the + buffered one. */ + + lock_rec_store_on_page_infimum(block, rec); + page_cur_delete_rec(&page_cur, index, offsets, mtr); + page_cur_move_to_prev(&page_cur); + mem_heap_free(heap); + + ibuf_insert_to_index_page_low(entry, block, index, mtr, + &page_cur); + lock_rec_restore_from_page_infimum(block, rec, block); + } else { + ibuf_insert_to_index_page_low(entry, block, index, mtr, + &page_cur); } } diff --git a/storage/innodb_plugin/include/btr0cur.h b/storage/innodb_plugin/include/btr0cur.h index e151fdcb563..7f6bff11f84 100644 --- a/storage/innodb_plugin/include/btr0cur.h +++ b/storage/innodb_plugin/include/btr0cur.h @@ -242,6 +242,22 @@ btr_cur_pessimistic_insert( que_thr_t* thr, /*!< in: query thread or NULL */ mtr_t* mtr); /*!< in: mtr */ /*************************************************************//** +See if there is enough place in the page modification log to log +an update-in-place. +@return TRUE if enough place */ +UNIV_INTERN +ibool +btr_cur_update_alloc_zip( +/*=====================*/ + page_zip_des_t* page_zip,/*!< in/out: compressed page */ + buf_block_t* block, /*!< in/out: buffer page */ + dict_index_t* index, /*!< in: the index corresponding to the block */ + ulint length, /*!< in: size needed */ + ibool create, /*!< in: TRUE=delete-and-insert, + FALSE=update-in-place */ + mtr_t* mtr) /*!< in: mini-transaction */ + __attribute__((nonnull, warn_unused_result)); +/*************************************************************//** Updates a record when the update causes no size changes in its fields. @return DB_SUCCESS or error number */ UNIV_INTERN diff --git a/storage/innodb_plugin/include/buf0flu.h b/storage/innodb_plugin/include/buf0flu.h index c996f6eaab4..cb8c49fde15 100644 --- a/storage/innodb_plugin/include/buf0flu.h +++ b/storage/innodb_plugin/include/buf0flu.h @@ -75,6 +75,20 @@ buf_flush_init_for_writing( ib_uint64_t newest_lsn); /*!< in: newest modification lsn to the page */ #ifndef UNIV_HOTBACKUP +# if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG +/********************************************************************//** +Writes a flushable page asynchronously from the buffer pool to a file. +NOTE: buf_pool_mutex and block->mutex must be held upon entering this +function, and they will be released by this function after flushing. +This is loosely based on buf_flush_batch() and buf_flush_page(). +@return TRUE if the page was flushed and the mutexes released */ +UNIV_INTERN +ibool +buf_flush_page_try( +/*===============*/ + buf_block_t* block) /*!< in/out: buffer control block */ + __attribute__((nonnull, warn_unused_result)); +# endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ /*******************************************************************//** This utility flushes dirty blocks from the end of the LRU list or flush_list. NOTE 1: in the case of an LRU flush the calling thread may own latches to diff --git a/storage/innodb_plugin/include/ibuf0ibuf.h b/storage/innodb_plugin/include/ibuf0ibuf.h index 8aa21fb9d95..f8cc4471d43 100644 --- a/storage/innodb_plugin/include/ibuf0ibuf.h +++ b/storage/innodb_plugin/include/ibuf0ibuf.h @@ -48,6 +48,11 @@ typedef enum { /** Operations that can currently be buffered. */ extern ibuf_use_t ibuf_use; +#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG +/** Flag to control insert buffer debugging. */ +extern uint ibuf_debug; +#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ + /** The insert buffer control structure */ extern ibuf_t* ibuf; diff --git a/storage/innodb_plugin/include/row0mysql.h b/storage/innodb_plugin/include/row0mysql.h index b69e657361b..42182cc0044 100644 --- a/storage/innodb_plugin/include/row0mysql.h +++ b/storage/innodb_plugin/include/row0mysql.h @@ -527,6 +527,10 @@ struct mysql_row_templ_struct { Innobase record in the current index; not defined if template_type is ROW_MYSQL_WHOLE_ROW */ + ulint clust_rec_field_no; /*!< field number of the column in an + Innobase record in the clustered index; + not defined if template_type is + ROW_MYSQL_WHOLE_ROW */ ulint mysql_col_offset; /*!< offset of the column in the MySQL row format */ ulint mysql_col_len; /*!< length of the column in the MySQL diff --git a/storage/innodb_plugin/include/row0upd.h b/storage/innodb_plugin/include/row0upd.h index 635d746d5a1..4e2de9bd2ec 100644 --- a/storage/innodb_plugin/include/row0upd.h +++ b/storage/innodb_plugin/include/row0upd.h @@ -167,8 +167,11 @@ row_upd_changes_field_size_or_external( const upd_t* update);/*!< in: update vector */ #endif /* !UNIV_HOTBACKUP */ /***********************************************************//** -Replaces the new column values stored in the update vector to the record -given. No field size changes are allowed. */ +Replaces the new column values stored in the update vector to the +record given. No field size changes are allowed. This function is +usually invoked on a clustered index. The only use case for a +secondary index is row_ins_sec_index_entry_by_modify() or its +counterpart in ibuf_insert_to_index_page(). */ UNIV_INTERN void row_upd_rec_in_place( diff --git a/storage/innodb_plugin/row/row0mysql.c b/storage/innodb_plugin/row/row0mysql.c index 78b3b2afdbf..107af481b79 100644 --- a/storage/innodb_plugin/row/row0mysql.c +++ b/storage/innodb_plugin/row/row0mysql.c @@ -444,7 +444,7 @@ row_mysql_convert_row_to_innobase( row is used, as row may contain pointers to this record! */ { - mysql_row_templ_t* templ; + const mysql_row_templ_t*templ; dfield_t* dfield; ulint i; diff --git a/storage/innodb_plugin/row/row0sel.c b/storage/innodb_plugin/row/row0sel.c index ea1a19eb82f..ac78a95839c 100644 --- a/storage/innodb_plugin/row/row0sel.c +++ b/storage/innodb_plugin/row/row0sel.c @@ -2675,21 +2675,22 @@ row_sel_store_mysql_rec( row_prebuilt_t* prebuilt, /*!< in: prebuilt struct */ const rec_t* rec, /*!< in: Innobase record in the index which was described in prebuilt's - template; must be protected by - a page latch */ + template, or in the clustered index; + must be protected by a page latch */ + ibool rec_clust, /*!< in: TRUE if rec is in the + clustered index instead of + prebuilt->index */ const ulint* offsets) /*!< in: array returned by - rec_get_offsets() */ + rec_get_offsets(rec) */ { - mysql_row_templ_t* templ; - mem_heap_t* extern_field_heap = NULL; - mem_heap_t* heap; - const byte* data; - ulint len; - ulint i; + mem_heap_t* extern_field_heap = NULL; + mem_heap_t* heap; + ulint i; ut_ad(prebuilt->mysql_template); ut_ad(prebuilt->default_rec); ut_ad(rec_offs_validate(rec, NULL, offsets)); + ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets))); if (UNIV_LIKELY_NULL(prebuilt->blob_heap)) { mem_heap_free(prebuilt->blob_heap); @@ -2698,10 +2699,15 @@ row_sel_store_mysql_rec( for (i = 0; i < prebuilt->n_template; i++) { - templ = prebuilt->mysql_template + i; + const mysql_row_templ_t*templ = prebuilt->mysql_template + i; + const byte* data; + ulint len; + ulint field_no; - if (UNIV_UNLIKELY(rec_offs_nth_extern(offsets, - templ->rec_field_no))) { + field_no = rec_clust + ? templ->clust_rec_field_no : templ->rec_field_no; + + if (UNIV_UNLIKELY(rec_offs_nth_extern(offsets, field_no))) { /* Copy an externally stored field to the temporary heap */ @@ -2729,7 +2735,7 @@ row_sel_store_mysql_rec( data = btr_rec_copy_externally_stored_field( rec, offsets, dict_table_zip_size(prebuilt->table), - templ->rec_field_no, &len, heap); + field_no, &len, heap); if (UNIV_UNLIKELY(!data)) { /* The externally stored field @@ -2750,8 +2756,7 @@ row_sel_store_mysql_rec( } else { /* Field is stored in the row. */ - data = rec_get_nth_field(rec, offsets, - templ->rec_field_no, &len); + data = rec_get_nth_field(rec, offsets, field_no, &len); if (UNIV_UNLIKELY(templ->type == DATA_BLOB) && len != UNIV_SQL_NULL) { @@ -3113,7 +3118,7 @@ row_sel_pop_cached_row_for_mysql( row_prebuilt_t* prebuilt) /*!< in: prebuilt struct */ { ulint i; - mysql_row_templ_t* templ; + const mysql_row_templ_t*templ; byte* cached_rec; ut_ad(prebuilt->n_fetch_cached > 0); ut_ad(prebuilt->mysql_prefix_len <= prebuilt->mysql_row_len); @@ -3170,15 +3175,21 @@ ibool row_sel_push_cache_row_for_mysql( /*=============================*/ row_prebuilt_t* prebuilt, /*!< in: prebuilt struct */ - const rec_t* rec, /*!< in: record to push; must - be protected by a page latch */ - const ulint* offsets) /*!< in: rec_get_offsets() */ + const rec_t* rec, /*!< in: record to push, in the index + which was described in prebuilt's + template, or in the clustered index; + must be protected by a page latch */ + ibool rec_clust, /*!< in: TRUE if rec is in the + clustered index instead of + prebuilt->index */ + const ulint* offsets) /*!< in: rec_get_offsets(rec) */ { byte* buf; ulint i; ut_ad(prebuilt->n_fetch_cached < MYSQL_FETCH_CACHE_SIZE); ut_ad(rec_offs_validate(rec, NULL, offsets)); + ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets))); ut_a(!prebuilt->templ_contains_blob); if (prebuilt->fetch_cache[0] == NULL) { @@ -3207,7 +3218,7 @@ row_sel_push_cache_row_for_mysql( if (UNIV_UNLIKELY(!row_sel_store_mysql_rec( prebuilt->fetch_cache[ prebuilt->n_fetch_cached], - prebuilt, rec, offsets))) { + prebuilt, rec, rec_clust, offsets))) { return(FALSE); } @@ -3608,7 +3619,8 @@ row_search_for_mysql( ut_ad(!rec_get_deleted_flag(rec, comp)); if (!row_sel_store_mysql_rec(buf, prebuilt, - rec, offsets)) { + rec, FALSE, + offsets)) { /* Only fresh inserts may contain incomplete externally stored columns. Pretend that such @@ -4242,7 +4254,6 @@ no_gap_lock: is necessary, because we can only get the undo information via the clustered index record. */ - ut_ad(index != clust_index); ut_ad(!dict_index_is_clust(index)); if (!lock_sec_rec_cons_read_sees( @@ -4358,26 +4369,10 @@ requires_clust_rec: goto next_rec; } - if (prebuilt->need_to_access_clustered) { - - result_rec = clust_rec; - - ut_ad(rec_offs_validate(result_rec, clust_index, - offsets)); - } else { - /* We used 'offsets' for the clust rec, recalculate - them for 'rec' */ - offsets = rec_get_offsets(rec, index, offsets, - ULINT_UNDEFINED, &heap); - result_rec = rec; - } - - /* result_rec can legitimately be delete-marked - now that it has been established that it points to a - clustered index record that exists in the read view. */ + result_rec = clust_rec; + ut_ad(rec_offs_validate(result_rec, clust_index, offsets)); } else { result_rec = rec; - ut_ad(!rec_get_deleted_flag(rec, comp)); } /* We found a qualifying record 'result_rec'. At this point, @@ -4386,6 +4381,7 @@ requires_clust_rec: ut_ad(rec_offs_validate(result_rec, result_rec != rec ? clust_index : index, offsets)); + ut_ad(!rec_get_deleted_flag(result_rec, comp)); /* At this point, the clustered index record is protected by a page latch that was acquired when pcur was positioned. @@ -4410,6 +4406,7 @@ requires_clust_rec: cursor. */ if (!row_sel_push_cache_row_for_mysql(prebuilt, result_rec, + result_rec != rec, offsets)) { /* Only fresh inserts may contain incomplete externally stored columns. Pretend that such @@ -4427,15 +4424,31 @@ requires_clust_rec: goto next_rec; } else { - if (prebuilt->template_type == ROW_MYSQL_DUMMY_TEMPLATE) { + if (UNIV_UNLIKELY + (prebuilt->template_type == ROW_MYSQL_DUMMY_TEMPLATE)) { + /* CHECK TABLE: fetch the row */ + + if (result_rec != rec + && !prebuilt->need_to_access_clustered) { + /* We used 'offsets' for the clust + rec, recalculate them for 'rec' */ + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, + &heap); + result_rec = rec; + } + memcpy(buf + 4, result_rec - rec_offs_extra_size(offsets), rec_offs_size(offsets)); mach_write_to_4(buf, rec_offs_extra_size(offsets) + 4); } else { - if (!row_sel_store_mysql_rec(buf, prebuilt, - result_rec, offsets)) { + /* Returning a row to MySQL */ + + if (!row_sel_store_mysql_rec(buf, prebuilt, result_rec, + result_rec != rec, + offsets)) { /* Only fresh inserts may contain incomplete externally stored columns. Pretend that such records do diff --git a/storage/innodb_plugin/row/row0upd.c b/storage/innodb_plugin/row/row0upd.c index 04c3139fcc7..444003ba3f0 100644 --- a/storage/innodb_plugin/row/row0upd.c +++ b/storage/innodb_plugin/row/row0upd.c @@ -466,8 +466,11 @@ row_upd_changes_field_size_or_external( #endif /* !UNIV_HOTBACKUP */ /***********************************************************//** -Replaces the new column values stored in the update vector to the record -given. No field size changes are allowed. */ +Replaces the new column values stored in the update vector to the +record given. No field size changes are allowed. This function is +usually invoked on a clustered index. The only use case for a +secondary index is row_ins_sec_index_entry_by_modify() or its +counterpart in ibuf_insert_to_index_page(). */ UNIV_INTERN void row_upd_rec_in_place( From 923003f99dfc03a173b9e683853aa73931c38352 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 19 Oct 2010 09:44:38 +0300 Subject: [PATCH 060/304] ibuf_set_del_mark(): Do not complain about already delete-marked records. According to a comment in row_upd_sec_index_entry(), it is a legitimate situation that can be caused by a lock wait. --- storage/innobase/ibuf/ibuf0ibuf.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c index 53a11a7f2e0..7ef577e5178 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.c +++ b/storage/innobase/ibuf/ibuf0ibuf.c @@ -3997,21 +3997,22 @@ ibuf_set_del_mark( rec = page_cur_get_rec(&page_cur); page_zip = page_cur_get_page_zip(&page_cur); - if (UNIV_UNLIKELY - (rec_get_deleted_flag( - rec, dict_table_is_comp(index->table)))) { - ut_print_timestamp(stderr); - fputs(" InnoDB: record is already delete-marked\n", - stderr); - goto failure; - } + /* Delete mark the old index record. According to a + comment in row_upd_sec_index_entry(), it can already + have been delete marked if a lock wait occurred in + row_ins_index_entry() in a previous invocation of + row_upd_sec_index_entry(). */ - btr_cur_set_deleted_flag_for_ibuf(rec, page_zip, TRUE, mtr); + if (UNIV_LIKELY + (!rec_get_deleted_flag( + rec, dict_table_is_comp(index->table)))) { + btr_cur_set_deleted_flag_for_ibuf(rec, page_zip, + TRUE, mtr); + } } else { ut_print_timestamp(stderr); fputs(" InnoDB: unable to find a record to delete-mark\n", stderr); -failure: fputs("InnoDB: tuple ", stderr); dtuple_print(stderr, entry); fputs("\n" From a6df37dbbf2ba51b6785576a946f664b0996c03c Mon Sep 17 00:00:00 2001 From: Tor Didriksen Date: Tue, 19 Oct 2010 08:45:18 +0200 Subject: [PATCH 061/304] Bug #57203 Assertion `field_length <= 255' failed. After the fix for Bug #55077 Assertion failed: width > 0 && to != ((void *)0), file .\dtoa.c we no longer try to allocate a string of length 'field_length' so the asserts are relevant only for ZEROFILL columns. mysql-test/r/select.result: Add test case for Bug#57203 mysql-test/t/select.test: Add test case for Bug#57203 sql/field.cc: Rewrite the DBUG_ASSERTS on field_length. --- mysql-test/r/select.result | 19 +++++++++++++++++++ mysql-test/t/select.test | 19 +++++++++++++++++++ sql/field.cc | 4 ++-- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 96979d257f1..a345a2ae6aa 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -4887,3 +4887,22 @@ col_int_key DROP VIEW view_t1; DROP TABLE t1; # End of test BUG#54515 +# +# Bug #57203 Assertion `field_length <= 255' failed. +# +SELECT coalesce((avg(distinct (geomfromtext("point(25379 -22010)"))))) +UNION ALL +SELECT coalesce((avg(distinct (geomfromtext("point(25379 -22010)"))))) +AS foo +; +coalesce((avg(distinct (geomfromtext("point(25379 -22010)"))))) +0.0000 +0.0000 +CREATE table t1(a text); +INSERT INTO t1 VALUES (''), (''); +SELECT avg(distinct(t1.a)) FROM t1, t1 t2 +GROUP BY t2.a ORDER BY t1.a; +avg(distinct(t1.a)) +0 +DROP TABLE t1; +# End of test BUG#57203 diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 87f36c452f2..3ed7213e8d7 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -4147,3 +4147,22 @@ DROP VIEW view_t1; DROP TABLE t1; --echo # End of test BUG#54515 + +--echo # +--echo # Bug #57203 Assertion `field_length <= 255' failed. +--echo # + +SELECT coalesce((avg(distinct (geomfromtext("point(25379 -22010)"))))) +UNION ALL +SELECT coalesce((avg(distinct (geomfromtext("point(25379 -22010)"))))) +AS foo +; + +CREATE table t1(a text); +INSERT INTO t1 VALUES (''), (''); +SELECT avg(distinct(t1.a)) FROM t1, t1 t2 +GROUP BY t2.a ORDER BY t1.a; + +DROP TABLE t1; + +--echo # End of test BUG#57203 diff --git a/sql/field.cc b/sql/field.cc index be7441f6bfd..d746de385b6 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4189,7 +4189,7 @@ String *Field_float::val_str(String *val_buffer, String *val_ptr __attribute__((unused))) { ASSERT_COLUMN_MARKED_FOR_READ; - DBUG_ASSERT(field_length <= MAX_FIELD_CHARLENGTH); + DBUG_ASSERT(!zerofill || field_length <= MAX_FIELD_CHARLENGTH); float nr; #ifdef WORDS_BIGENDIAN if (table->s->db_low_byte_first) @@ -4512,7 +4512,7 @@ String *Field_double::val_str(String *val_buffer, String *val_ptr __attribute__((unused))) { ASSERT_COLUMN_MARKED_FOR_READ; - DBUG_ASSERT(field_length <= MAX_FIELD_CHARLENGTH); + DBUG_ASSERT(!zerofill || field_length <= MAX_FIELD_CHARLENGTH); double nr; #ifdef WORDS_BIGENDIAN if (table->s->db_low_byte_first) From af665ea977698676080f0e175363dc0c83755938 Mon Sep 17 00:00:00 2001 From: Tor Didriksen Date: Tue, 19 Oct 2010 09:06:48 +0200 Subject: [PATCH 062/304] Bug#52172 post-push fix: init auto-variable to NULL --- dbug/dbug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbug/dbug.c b/dbug/dbug.c index 7278acca2a9..e5e11d5be00 100644 --- a/dbug/dbug.c +++ b/dbug/dbug.c @@ -2269,7 +2269,7 @@ static void dbug_flush(CODE_STATE *cs) void _db_flush_() { - CODE_STATE *cs; + CODE_STATE *cs= NULL; get_code_state_or_return; (void) fflush(cs->stack->out_file); } From 4776282bede4da8cceeee1ce450310b281e34af9 Mon Sep 17 00:00:00 2001 From: Jon Olav Hauglid Date: Tue, 19 Oct 2010 10:19:57 +0200 Subject: [PATCH 063/304] Bug #57274 SET GLOBAL debug crashes on Solaris in embedded server mode (variables_debug fails) The problem was that "SET GLOBAL debug" could cause a crash on Solaris. The crash happened if the server failed to open the trace file given in the "SET GLOBAL debug" statement. This caused an error message to be printed to stderr containing the process name. However, printing to stderr crashed the server since the pointer to the process name had not been initialized. This patch fixes the problem by initializing the process name properly when doing "SET GLOBAL debug". No test case added as this bug was repeatable with existing test coverage in variables_debug.test. --- dbug/dbug.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dbug/dbug.c b/dbug/dbug.c index e5e11d5be00..fecdd4f8a6c 100644 --- a/dbug/dbug.c +++ b/dbug/dbug.c @@ -744,6 +744,7 @@ void _db_set_init_(const char *control) CODE_STATE tmp_cs; bzero((uchar*) &tmp_cs, sizeof(tmp_cs)); tmp_cs.stack= &init_settings; + tmp_cs.process= db_process ? db_process : "dbug"; DbugParse(&tmp_cs, control); } From 95d91c0f575fc490ac9e3d36a7d65980d9347489 Mon Sep 17 00:00:00 2001 From: Magne Mahre Date: Tue, 19 Oct 2010 12:27:09 +0200 Subject: [PATCH 064/304] Bug #46941 crash with lower_case_table_names=2 and foreign key data dictionary confusion On file systems with case insensitive file names, and lower_case_table_names set to '2', the server could crash due to a table definition cache inconsistency. This is the default setting on MacOSX, but may also be set and used on MS Windows. The bug is caused by using two different strategies for creating the hash key for the table definition cache, resulting in failure to look up an entry which is present in the cache, or failure to delete an existing entry. One strategy was to use the real table name (with case preserved), and the other to use a normalized table name (i.e a lower case version). This is manifested in two cases. One is during 'DROP DATABASE', where all known files are removed. The removal from the table definition cache is done via a generated list of TABLE_LIST with keys (wrongly) created using the case preserved name. The other is during CREATE TABLE, where the cache lookup is also (wrongly) based on the case preserved name. The fix was to use only the normalized table name when creating hash keys. sql/sql_db.cc: Normalize table name (i.e lower case it) sql/sql_table.cc: table_name contains the normalized name alias contains the real table name --- mysql-test/r/lowercase_table4.result | 7 +++ mysql-test/t/lowercase_table4-master.opt | 1 + mysql-test/t/lowercase_table4.test | 56 ++++++++++++++++++++++++ sql/sql_db.cc | 6 +++ sql/sql_table.cc | 2 +- 5 files changed, 71 insertions(+), 1 deletion(-) create mode 100755 mysql-test/r/lowercase_table4.result create mode 100755 mysql-test/t/lowercase_table4-master.opt create mode 100755 mysql-test/t/lowercase_table4.test diff --git a/mysql-test/r/lowercase_table4.result b/mysql-test/r/lowercase_table4.result new file mode 100755 index 00000000000..e3f861f8884 --- /dev/null +++ b/mysql-test/r/lowercase_table4.result @@ -0,0 +1,7 @@ +# +# Bug#46941 crash with lower_case_table_names=2 and +# foreign data dictionary confusion +# +CREATE DATABASE XY; +USE XY; +DROP DATABASE XY; diff --git a/mysql-test/t/lowercase_table4-master.opt b/mysql-test/t/lowercase_table4-master.opt new file mode 100755 index 00000000000..c0a1981fa7c --- /dev/null +++ b/mysql-test/t/lowercase_table4-master.opt @@ -0,0 +1 @@ +--lower-case-table-names=2 diff --git a/mysql-test/t/lowercase_table4.test b/mysql-test/t/lowercase_table4.test new file mode 100755 index 00000000000..93956047145 --- /dev/null +++ b/mysql-test/t/lowercase_table4.test @@ -0,0 +1,56 @@ +--source include/have_case_insensitive_file_system.inc +--source include/have_innodb.inc + +--echo # +--echo # Bug#46941 crash with lower_case_table_names=2 and +--echo # foreign data dictionary confusion +--echo # + +CREATE DATABASE XY; +USE XY; + +# +# Logs are disabled, since the number of creates tables +# and subsequent select statements may vary between +# versions +# +--disable_query_log +--disable_result_log + +let $tcs = `SELECT @@table_open_cache + 1`; + +let $i = $tcs; + +while ($i) +{ + eval CREATE TABLE XY.T_$i (a INT NOT NULL, b INT NOT NULL, c INT NOT NULL, d INT, + primary key(a, b), unique(b)) ENGINE=InnoDB; + dec $i; +} + +eval ALTER TABLE XY.T_$tcs ADD INDEX I1 (c, b), + ADD CONSTRAINT C1 FOREIGN KEY (c, b) REFERENCES XY.T_1 (a, b); + +eval ALTER TABLE XY.T_$tcs ADD INDEX I2 (b), + ADD CONSTRAINT C2 FOREIGN KEY (b) REFERENCES XY.T_1(a); + +let $i = $tcs; +while ($i) +{ + eval SELECT * FROM XY.T_$i LIMIT 1; + dec $i; +} + +DROP DATABASE XY; +CREATE DATABASE XY; +USE XY; +eval CREATE TABLE XY.T_$tcs (a INT NOT NULL, b INT NOT NULL, c INT NOT NULL, d INT, + PRIMARY KEY(a, b), UNIQUE(b)) ENGINE=InnoDB; +# +# The bug causes this SELECT to err +eval SELECT * FROM XY.T_$tcs LIMIT 1; + +--enable_query_log +--enable_result_log +DROP DATABASE XY; + diff --git a/sql/sql_db.cc b/sql/sql_db.cc index d3435b891b1..2c44c1a8449 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -1197,6 +1197,12 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, VOID(filename_to_tablename(file->name, table_list->table_name, MYSQL50_TABLE_NAME_PREFIX_LENGTH + strlen(file->name) + 1)); + + /* To be able to correctly look up the table in the table cache. */ + if (lower_case_table_names) + table_list->table_name_length= my_casedn_str(files_charset_info, + table_list->table_name); + table_list->alias= table_list->table_name; // If lower_case_table_names=2 table_list->internal_tmp_table= is_prefix(file->name, tmp_file_prefix); /* Link into list */ diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 04cc9e42413..971e1022d63 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3896,7 +3896,7 @@ bool mysql_create_table_no_lock(THD *thd, Then she could create the table. This case is pretty obscure and therefore we don't introduce a new error message only for it. */ - if (get_cached_table_share(db, alias)) + if (get_cached_table_share(db, table_name)) { my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name); goto unlock_and_end; From 8a67fc8c8246f5d7290b7e572fa092cf0cadb25d Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Tue, 19 Oct 2010 13:54:28 +0200 Subject: [PATCH 065/304] Test wait_timeout: do not fail by SQL syntax error, use die --- mysql-test/t/wait_timeout.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/t/wait_timeout.test b/mysql-test/t/wait_timeout.test index 6947e346675..eb86cf17ebb 100644 --- a/mysql-test/t/wait_timeout.test +++ b/mysql-test/t/wait_timeout.test @@ -53,7 +53,7 @@ while (!`select @aborted_clients`) dec $retries; if (!$retries) { - Failed to detect that client has been aborted; + die Failed to detect that client has been aborted; } } --enable_query_log @@ -108,7 +108,7 @@ while (!`select @aborted_clients`) dec $retries; if (!$retries) { - Failed to detect that client has been aborted; + die Failed to detect that client has been aborted; } } --enable_query_log From 84c57a5e278bbaa976c8d2961fd554e078c9b714 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Tue, 19 Oct 2010 13:56:30 +0200 Subject: [PATCH 066/304] Bug #52828 Tests that use perl fail when perl is not in path main.mysqltest skipped on Windows because a perl intentionally does exit(1) Use exit(2), as exit(1) on Windows is indistinguishable from failing to execute perl. --- mysql-test/t/mysqltest.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index caadce44dcf..d6bdbc2b3c1 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -331,7 +331,7 @@ eval select $mysql_errno as "after_!errno_masked_error" ; --exec illegal_command --cat_file does_not_exist --perl - exit(1); + exit(2); EOF # ---------------------------------------------------------------------------- From 05062d579a81ce9378560bee573f5769a94c579a Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Tue, 19 Oct 2010 14:01:14 +0200 Subject: [PATCH 067/304] Bug #56654 pb2 log is very hard to read Added some more info in a number of fail cases (re-commit for administrative reasons) --- mysql-test/mysql-test-run.pl | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index b83c32d3815..651dabcd408 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -586,13 +586,15 @@ sub run_test_server ($$$) { if ($test_has_failed and $retries <= $opt_retry){ # Test should be run one more time unless it has failed # too many times already + my $tname= $result->{name}; my $failures= $result->{failures}; if ($opt_retry > 1 and $failures >= $opt_retry_failure){ - mtr_report("\nTest has failed $failures times,", + mtr_report("\nTest $tname has failed $failures times,", "no more retries!\n"); } else { - mtr_report("\nRetrying test, attempt($retries/$opt_retry)...\n"); + mtr_report("\nRetrying test $tname, ". + "attempt($retries/$opt_retry)...\n"); delete($result->{result}); $result->{retries}= $retries+1; $result->write_test($sock, 'TESTCASE'); @@ -3094,7 +3096,8 @@ sub check_testcase($$) "\nMTR's internal check of the test case '$tname' failed. This means that the test case does not preserve the state that existed before the test case was executed. Most likely the test case did not -do a proper clean-up. +do a proper clean-up. It could also be caused by the previous test run +by this thread, if the server wasn't restarted. This is the diff of the states of the servers before and after the test case was executed:\n"; $tinfo->{check}.= $report; @@ -3136,6 +3139,10 @@ test case was executed:\n"; # Kill any check processes still running map($_->kill(), values(%started)); + mtr_warning("Check-testcase failed, this could also be caused by the" . + " previous test run by this worker thread") + if $result > 1 && $mode eq "before"; + return $result; } @@ -3789,7 +3796,9 @@ sub get_log_from_proc ($$) { foreach my $mysqld (mysqlds()) { if ($mysqld->{proc} eq $proc) { my @srv_lines= extract_server_log($mysqld->value('#log-error'), $name); - $srv_log= "\nServer log from this test:\n" . join ("", @srv_lines); + $srv_log= "\nServer log from this test:\n" . + "----------SERVER LOG START-----------\n". join ("", @srv_lines) . + "----------SERVER LOG END-------------\n"; last; } } From 138ede4609be43e177ecd60d3e4778647f8f35fd Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Tue, 19 Oct 2010 14:08:46 +0200 Subject: [PATCH 068/304] Bug #55135 Collect times used in test execution phases in mtr Adding option --report-times Can't collect times if test run is aborted --- mysql-test/lib/mtr_misc.pl | 84 ++++++++++++++++++++++++++++++++++++ mysql-test/mysql-test-run.pl | 33 +++++++++++++- 2 files changed, 116 insertions(+), 1 deletion(-) diff --git a/mysql-test/lib/mtr_misc.pl b/mysql-test/lib/mtr_misc.pl index 32960d866ce..dc9928d37c5 100644 --- a/mysql-test/lib/mtr_misc.pl +++ b/mysql-test/lib/mtr_misc.pl @@ -33,6 +33,13 @@ sub mtr_exe_maybe_exists(@); sub mtr_milli_sleep($); sub start_timer($); sub has_expired($); +sub init_timers(); +sub mark_time_used($); +sub add_total_times($); +sub print_times_used($$); +sub print_total_times($); + +our $opt_report_times; ############################################################################## # @@ -205,4 +212,81 @@ sub start_timer ($) { return time + $_[0]; } sub has_expired ($) { return $_[0] && time gt $_[0]; } +# Below code is for time usage reporting + +use Time::HiRes qw(gettimeofday); + +my %time_used= ( + 'collect' => 0, + 'restart' => 0, + 'check' => 0, + 'ch-warn' => 0, + 'test' => 0, + 'init' => 0, +); + +my %time_text= ( + 'collect' => "Collecting test cases", + 'restart' => "Server stop/start", + 'check' => "Check-testcase", + 'ch-warn' => "Check for warnings", + 'test' => "Test execution", + 'init' => "Initialization etc.", +); + +# Counts number of reports from workers + +my $time_totals= 0; + +my $last_timer_set; + +sub init_timers() { + $last_timer_set= gettimeofday(); +} + +sub mark_time_used($) { + my ($name)= @_; + return unless $opt_report_times; + die "Unknown timer $name" unless exists $time_used{$name}; + + my $curr_time= gettimeofday(); + $time_used{$name}+= int (($curr_time - $last_timer_set) * 1000 + .5); + $last_timer_set= $curr_time; +} + +sub add_total_times($) { + my ($dummy, $num, @line)= split (" ", $_[0]); + + $time_totals++; + foreach my $elem (@line) { + my ($name, $spent)= split (":", $elem); + $time_used{$name}+= $spent; + } +} + +sub print_times_used($$) { + my ($server, $num)= @_; + return unless $opt_report_times; + + my $output= "SPENT $num"; + foreach my $name (keys %time_used) { + my $spent= $time_used{$name}; + $output.= " $name:$spent"; + } + print $server $output . "\n"; +} + +sub print_total_times($) { + # Don't print if we haven't received all worker data + return if $time_totals != $_[0]; + + foreach my $name (keys %time_used) + { + my $spent= $time_used{$name}/1000; + my $text= $time_text{$name}; + print ("Spent $spent seconds on $text\n"); + } +} + + 1; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index e6d988dfba6..fe71fe69ad4 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -236,6 +236,7 @@ my $opt_skip_core; our $opt_check_testcases= 1; my $opt_mark_progress; my $opt_max_connections; +our $opt_report_times= 0; my $opt_sleep; @@ -348,8 +349,11 @@ sub main { } } + init_timers(); + mtr_report("Collecting tests..."); my $tests= collect_test_cases($opt_reorder, $opt_suites, \@opt_cases, \@opt_skip_test_list); + mark_time_used('collect'); if ( $opt_report_features ) { # Put "report features" as the first test to run @@ -418,6 +422,7 @@ sub main { $opt_tmpdir= "$opt_tmpdir/$child_num"; } + init_timers(); run_worker($server_port, $child_num); exit(1); } @@ -430,6 +435,8 @@ sub main { mtr_print_thick_line(); mtr_print_header(); + mark_time_used('init'); + my $completed= run_test_server($server, $tests, $opt_parallel); exit(0) if $opt_start_exit; @@ -475,6 +482,8 @@ sub main { $opt_gcov_msg, $opt_gcov_err); } + print_total_times($opt_parallel) if $opt_report_times; + mtr_report_stats("Completed", $completed); remove_vardir_subs() if $opt_clean_vardir; @@ -651,6 +660,9 @@ sub run_test_server ($$$) { elsif ($line eq 'START'){ ; # Send first test } + elsif ($line =~ /^SPENT/) { + add_total_times($line); + } else { mtr_error("Unknown response: '$line' from client"); } @@ -782,7 +794,9 @@ sub run_worker ($) { # Ask server for first test print $server "START\n"; - while(my $line= <$server>){ + mark_time_used('init'); + + while (my $line= <$server>){ chomp($line); if ($line eq 'TESTCASE'){ my $test= My::Test::read_test($server); @@ -800,16 +814,20 @@ sub run_worker ($) { # Send it back, now with results set #$test->print_test(); $test->write_test($server, 'TESTRESULT'); + mark_time_used('restart'); } elsif ($line eq 'BYE'){ mtr_report("Server said BYE"); stop_all_servers($opt_shutdown_timeout); + mark_time_used('restart'); if ($opt_valgrind_mysqld) { valgrind_exit_reports(); } if ( $opt_gprof ) { gprof_collect (find_mysqld($basedir), keys %gprof_dirs); } + mark_time_used('init'); + print_times_used($server, $thread_num); exit(0); } else { @@ -982,6 +1000,7 @@ sub command_line_setup { 'timediff' => \&report_option, 'max-connections=i' => \$opt_max_connections, 'default-myisam!' => \&collect_option, + 'report-times' => \$opt_report_times, 'help|h' => \$opt_usage, 'list-options' => \$opt_list_options, @@ -3169,6 +3188,7 @@ sub check_testcase($$) if ( keys(%started) == 0){ # All checks completed + mark_time_used('check'); return 0; } # Wait for next process to exit @@ -3226,6 +3246,7 @@ test case was executed:\n"; # Kill any check processes still running map($_->kill(), values(%started)); + mark_time_used('check'); return $result; } @@ -3535,6 +3556,7 @@ sub run_testcase ($) { return 1; } } + mark_time_used('restart'); # -------------------------------------------------------------------- # If --start or --start-dirty given, stop here to let user manually @@ -3587,6 +3609,8 @@ sub run_testcase ($) { do_before_run_mysqltest($tinfo); + mark_time_used('init'); + if ( $opt_check_testcases and check_testcase($tinfo, "before") ){ # Failed to record state of server or server crashed report_failure_and_restart($tinfo); @@ -3633,6 +3657,7 @@ sub run_testcase ($) { } mtr_verbose("Got $proc"); + mark_time_used('test'); # ---------------------------------------------------- # Was it the test program that exited # ---------------------------------------------------- @@ -4036,6 +4061,7 @@ sub check_warnings ($) { if ( keys(%started) == 0){ # All checks completed + mark_time_used('ch-warn'); return $result; } # Wait for next process to exit @@ -4068,6 +4094,7 @@ sub check_warnings ($) { # Kill any check processes still running map($_->kill(), values(%started)); + mark_time_used('ch-warn'); return $result; } @@ -5031,6 +5058,8 @@ sub start_mysqltest ($) { my $exe= $exe_mysqltest; my $args; + mark_time_used('init'); + mtr_init_args(\$args); mtr_add_arg($args, "--defaults-file=%s", $path_config_file); @@ -5668,6 +5697,8 @@ Misc options default-myisam Set default storage engine to MyISAM for non-innodb tests. This is needed after switching default storage engine to InnoDB. + report-times Report how much time has been spent on different + phases of test execution. HERE exit(1); From 183710558f78bb2fa55640ef1f0d2e087355240e Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 19 Oct 2010 11:49:31 -0200 Subject: [PATCH 069/304] Bug#45288: pb2 returns a lot of compilation warnings on linux Fix assorted compiler warnings on Mac OS X. BUILD/SETUP.sh: Remove -Wctor-dtor-privacy flag to workaround a GCC bug that causes it to not properly detect that implicitly generated constructors are always public. cmd-line-utils/readline/terminal.c: tgetnum and tgetflag might not take a const string argument. mysys/my_gethostbyname.c: Tag unused arguments. mysys/my_sync.c: Tag unused arguments. --- BUILD/SETUP.sh | 2 +- cmd-line-utils/readline/terminal.c | 8 +++---- mysys/my_gethostbyname.c | 6 +++-- mysys/my_sync.c | 36 +++++++++++++++++++++++------- 4 files changed, 37 insertions(+), 15 deletions(-) diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh index 08ae4de2e23..157fa7b087f 100755 --- a/BUILD/SETUP.sh +++ b/BUILD/SETUP.sh @@ -100,7 +100,7 @@ if [ "x$warning_mode" != "xpedantic" ]; then # C++ warnings cxx_warnings="$warnings -Wno-unused-parameter" # cxx_warnings="$cxx_warnings -Woverloaded-virtual -Wsign-promo" - cxx_warnings="$cxx_warnings -Wctor-dtor-privacy -Wnon-virtual-dtor" + cxx_warnings="$cxx_warnings -Wnon-virtual-dtor" # Added unless --with-debug=full debug_extra_cflags="-O0 -g3 -gdwarf-2" else diff --git a/cmd-line-utils/readline/terminal.c b/cmd-line-utils/readline/terminal.c index 3f92821f9dd..e2785908160 100644 --- a/cmd-line-utils/readline/terminal.c +++ b/cmd-line-utils/readline/terminal.c @@ -268,7 +268,7 @@ _rl_get_screen_size (tty, ignore_env) #if !defined (__DJGPP__) if (_rl_screenwidth <= 0 && term_string_buffer) - _rl_screenwidth = tgetnum ("co"); + _rl_screenwidth = tgetnum ((char *)"co"); #endif } @@ -284,7 +284,7 @@ _rl_get_screen_size (tty, ignore_env) #if !defined (__DJGPP__) if (_rl_screenheight <= 0 && term_string_buffer) - _rl_screenheight = tgetnum ("li"); + _rl_screenheight = tgetnum ((char *)"li"); #endif } @@ -516,7 +516,7 @@ _rl_init_terminal_io (terminal_name) if (!_rl_term_cr) _rl_term_cr = "\r"; - _rl_term_autowrap = tgetflag ("am") && tgetflag ("xn"); + _rl_term_autowrap = tgetflag ((char *)"am") && tgetflag ((char *)"xn"); /* Allow calling application to set default height and width, using rl_set_screen_size */ @@ -531,7 +531,7 @@ _rl_init_terminal_io (terminal_name) /* Check to see if this terminal has a meta key and clear the capability variables if there is none. */ - term_has_meta = (tgetflag ("km") || tgetflag ("MT")); + term_has_meta = (tgetflag ((char *)"km") || tgetflag ((char *)"MT")); if (!term_has_meta) _rl_term_mm = _rl_term_mo = (char *)NULL; diff --git a/mysys/my_gethostbyname.c b/mysys/my_gethostbyname.c index 067fdfee9db..12cf90271dd 100644 --- a/mysys/my_gethostbyname.c +++ b/mysys/my_gethostbyname.c @@ -92,8 +92,10 @@ extern pthread_mutex_t LOCK_gethostbyname_r; */ struct hostent *my_gethostbyname_r(const char *name, - struct hostent *result, char *buffer, - int buflen, int *h_errnop) + struct hostent *res __attribute__((unused)), + char *buffer __attribute__((unused)), + int buflen __attribute__((unused)), + int *h_errnop) { struct hostent *hp; pthread_mutex_lock(&LOCK_gethostbyname_r); diff --git a/mysys/my_sync.c b/mysys/my_sync.c index 97540f5eb48..d6ca4f1c1df 100644 --- a/mysys/my_sync.c +++ b/mysys/my_sync.c @@ -89,6 +89,8 @@ int my_sync(File fd, myf my_flags) static const char cur_dir_name[]= {FN_CURLIB, 0}; + + /* Force directory information to disk. @@ -100,9 +102,11 @@ static const char cur_dir_name[]= {FN_CURLIB, 0}; RETURN 0 if ok, !=0 if error */ + +#ifdef NEED_EXPLICIT_SYNC_DIR + int my_sync_dir(const char *dir_name, myf my_flags) { -#ifdef NEED_EXPLICIT_SYNC_DIR File dir_fd; int res= 0; const char *correct_dir_name; @@ -124,11 +128,18 @@ int my_sync_dir(const char *dir_name, myf my_flags) else res= 1; DBUG_RETURN(res); -#else - return 0; -#endif } +#else /* NEED_EXPLICIT_SYNC_DIR */ + +int my_sync_dir(const char *dir_name __attribute__((unused)), + myf my_flags __attribute__((unused))) +{ + return 0; +} + +#endif /* NEED_EXPLICIT_SYNC_DIR */ + /* Force directory information to disk. @@ -141,15 +152,24 @@ int my_sync_dir(const char *dir_name, myf my_flags) RETURN 0 if ok, !=0 if error */ + +#ifdef NEED_EXPLICIT_SYNC_DIR + int my_sync_dir_by_file(const char *file_name, myf my_flags) { -#ifdef NEED_EXPLICIT_SYNC_DIR char dir_name[FN_REFLEN]; size_t dir_name_length; dirname_part(dir_name, file_name, &dir_name_length); return my_sync_dir(dir_name, my_flags); -#else - return 0; -#endif } +#else /* NEED_EXPLICIT_SYNC_DIR */ + +int my_sync_dir_by_file(const char *file_name __attribute__((unused)), + myf my_flags __attribute__((unused))) +{ + return 0; +} + +#endif /* NEED_EXPLICIT_SYNC_DIR */ + From 8875c2c2e05253098d44b524976619dbe1e3bfb2 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 19 Oct 2010 12:09:28 -0200 Subject: [PATCH 070/304] Bug#45288: pb2 returns a lot of compilation warnings on linux Tag unused arguments. Approved by: Marko (via IRC) --- storage/innobase/os/os0file.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c index a995aee5fab..f269cd39673 100644 --- a/storage/innobase/os/os0file.c +++ b/storage/innobase/os/os0file.c @@ -1138,9 +1138,12 @@ Tries to disable OS caching on an opened file descriptor. */ void os_file_set_nocache( /*================*/ - int fd, /* in: file descriptor to alter */ - const char* file_name, /* in: used in the diagnostic message */ - const char* operation_name) /* in: used in the diagnostic message, + int fd /* in: file descriptor to alter */ + __attribute__((unused)), + const char* file_name /* in: used in the diagnostic message */ + __attribute__((unused)), + const char* operation_name __attribute__((unused))) + /* in: used in the diagnostic message, we call os_file_set_nocache() immediately after opening or creating a file, so this is either "open" or From be170c213fa285acfb79e06ba249a9bb30155275 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 19 Oct 2010 12:12:43 -0200 Subject: [PATCH 071/304] Bug#45288: pb2 returns a lot of compilation warnings on linux Tag unused arguments. Approved by: Marko (via IRC) --- storage/innodb_plugin/os/os0file.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/storage/innodb_plugin/os/os0file.c b/storage/innodb_plugin/os/os0file.c index 6a0d6ea5363..14b2fce43c3 100644 --- a/storage/innodb_plugin/os/os0file.c +++ b/storage/innodb_plugin/os/os0file.c @@ -1182,10 +1182,12 @@ UNIV_INTERN void os_file_set_nocache( /*================*/ - int fd, /*!< in: file descriptor to alter */ - const char* file_name, /*!< in: file name, used in the - diagnostic message */ - const char* operation_name) /*!< in: "open" or "create"; used in the + int fd /*!< in: file descriptor to alter */ + __attribute__((unused)), + const char* file_name /*!< in: used in the diagnostic message */ + __attribute__((unused)), + const char* operation_name __attribute__((unused))) + /*!< in: "open" or "create"; used in the diagnostic message */ { /* some versions of Solaris may not have DIRECTIO_ON */ From cb0105066157343065f85eab019660dd20609f6c Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 19 Oct 2010 17:32:26 +0300 Subject: [PATCH 072/304] Fix Bug#53916 storage/innodb_plugin does not compile on NetBSD/sparc64 Just check for all the functions that we are going to use, not a subset of them. Reviewed by: Davi (via IRC) --- storage/innodb_plugin/plug.in | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/storage/innodb_plugin/plug.in b/storage/innodb_plugin/plug.in index e638332d74a..2ee45389e9c 100644 --- a/storage/innodb_plugin/plug.in +++ b/storage/innodb_plugin/plug.in @@ -137,10 +137,11 @@ MYSQL_PLUGIN_ACTIONS(innodb_plugin, [ AC_MSG_CHECKING(whether Solaris libc atomic functions are available) # either define HAVE_IB_SOLARIS_ATOMICS or not - AC_CHECK_FUNCS(atomic_add_long \ + AC_CHECK_FUNCS(atomic_cas_ulong \ atomic_cas_32 \ atomic_cas_64 \ - atomic_cas_ulong, + atomic_add_long_nv \ + atomic_swap_uchar, AC_DEFINE([HAVE_IB_SOLARIS_ATOMICS], [1], [Define to 1 if Solaris libc atomic functions \ From 7406b38efa0a2eec5a245839c5ce13b85d51d125 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 19 Oct 2010 14:48:03 -0200 Subject: [PATCH 073/304] Bug#45288: pb2 returns a lot of compilation warnings Ensure that fdatasync is properly declared as on Mac OS X, the function is available but there is no prototype. Also, port a fix for a warning from the InnoDB plugin over to the builtin. configure.in: Check that fdatasync is declared. mysys/my_sync.c: Use fdatasync only if it is declared. storage/innobase/include/ut0dbg.h: Port over from the plugin a fix for a warning. --- configure.in | 7 +++++++ mysys/my_sync.c | 2 +- storage/innobase/include/ut0dbg.h | 4 ++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/configure.in b/configure.in index 09885dbbae7..4ea978c268e 100644 --- a/configure.in +++ b/configure.in @@ -2073,6 +2073,13 @@ MYSQL_TYPE_QSORT AC_FUNC_UTIME_NULL AC_FUNC_VPRINTF +AC_CHECK_DECLS([fdatasync],,, +[ +#ifdef HAVE_UNISTD_H +# include +#endif +]) + AC_CHECK_FUNCS(alarm bfill bmove bsearch bzero \ chsize cuserid fchmod fcntl \ fconvert fdatasync fesetround finite fpresetsticky fpsetmask fsync ftruncate \ diff --git a/mysys/my_sync.c b/mysys/my_sync.c index d6ca4f1c1df..7acbccec345 100644 --- a/mysys/my_sync.c +++ b/mysys/my_sync.c @@ -58,7 +58,7 @@ int my_sync(File fd, myf my_flags) /* Some file systems don't support F_FULLFSYNC and fail above: */ DBUG_PRINT("info",("fcntl(F_FULLFSYNC) failed, falling back")); #endif -#if defined(HAVE_FDATASYNC) +#if defined(HAVE_FDATASYNC) && HAVE_DECL_FDATASYNC res= fdatasync(fd); #elif defined(HAVE_FSYNC) res= fsync(fd); diff --git a/storage/innobase/include/ut0dbg.h b/storage/innobase/include/ut0dbg.h index a317f35f4be..06dead7fc03 100644 --- a/storage/innobase/include/ut0dbg.h +++ b/storage/innobase/include/ut0dbg.h @@ -39,7 +39,7 @@ extern ibool panic_shutdown; void ut_dbg_panic(void); # define UT_DBG_PANIC ut_dbg_panic() /* Stop threads in ut_a(). */ -# define UT_DBG_STOP while (0) /* We do not do this on NetWare */ +# define UT_DBG_STOP do {} while (0) /* We do not do this on NetWare */ #else /* __NETWARE__ */ # if defined(__WIN__) || defined(__INTEL_COMPILER) # undef UT_DBG_USE_ABORT @@ -71,7 +71,7 @@ ut_dbg_stop_thread( /* Abort the execution. */ # define UT_DBG_PANIC abort() /* Stop threads (null operation) */ -# define UT_DBG_STOP while (0) +# define UT_DBG_STOP do {} while (0) # else /* UT_DBG_USE_ABORT */ /* Abort the execution. */ # define UT_DBG_PANIC \ From 1040f98ccffccbed8d1e95fe8252e402b8ee4e3f Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 19 Oct 2010 20:36:59 -0200 Subject: [PATCH 074/304] Bug#45288: pb2 returns a lot of compilation warnings Tag or remove unused arguments and variables. regex/main.c: Use the real prototype. sql/ha_ndbcluster.cc: Make conditions less ambiguous. --- client/mysql.cc | 15 +++++++++----- client/sql_string.h | 10 ++++++--- cmd-line-utils/libedit/common.c | 5 +++-- cmd-line-utils/libedit/filecomplete.c | 3 +-- cmd-line-utils/libedit/readline.c | 23 +++++++++++++-------- cmd-line-utils/libedit/vi.c | 29 ++++++++++++++------------- regex/main.c | 8 ++++---- sql/ha_ndbcluster.cc | 10 +++++---- sql/log_event.cc | 2 +- sql/log_event.h | 4 ++-- sql/my_decimal.h | 2 +- sql/sql_string.h | 10 ++++++--- 12 files changed, 72 insertions(+), 49 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index 5b90f318629..4c2c75dc79a 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -3725,7 +3725,8 @@ print_tab_data(MYSQL_RES *result) } static int -com_tee(String *buffer, char *line __attribute__((unused))) +com_tee(String *buffer __attribute__((unused)), + char *line __attribute__((unused))) { char file_name[FN_REFLEN], *end, *param; @@ -3784,7 +3785,8 @@ com_notee(String *buffer __attribute__((unused)), #ifdef USE_POPEN static int -com_pager(String *buffer, char *line __attribute__((unused))) +com_pager(String *buffer __attribute__((unused)), + char *line __attribute__((unused))) { char pager_name[FN_REFLEN], *end, *param; @@ -3911,7 +3913,8 @@ com_rehash(String *buffer __attribute__((unused)), #ifdef USE_POPEN static int -com_shell(String *buffer, char *line __attribute__((unused))) +com_shell(String *buffer __attribute__((unused)), + char *line __attribute__((unused))) { char *shell_cmd; @@ -4003,7 +4006,8 @@ com_connect(String *buffer, char *line) } -static int com_source(String *buffer, char *line) +static int com_source(String *buffer __attribute__((unused)), + char *line) { char source_name[FN_REFLEN], *end, *param; LINE_BUFFER *line_buff; @@ -4908,7 +4912,8 @@ static void init_username() } } -static int com_prompt(String *buffer, char *line) +static int com_prompt(String *buffer __attribute__((unused)), + char *line) { char *ptr=strchr(line, ' '); prompt_counter = 0; diff --git a/client/sql_string.h b/client/sql_string.h index da19c1ccfe5..84fe26a54b9 100644 --- a/client/sql_string.h +++ b/client/sql_string.h @@ -70,9 +70,13 @@ public: } static void *operator new(size_t size, MEM_ROOT *mem_root) { return (void*) alloc_root(mem_root, (uint) size); } - static void operator delete(void *ptr_arg,size_t size) - { TRASH(ptr_arg, size); } - static void operator delete(void *ptr_arg, MEM_ROOT *mem_root) + static void operator delete(void *ptr_arg, size_t size) + { + (void) ptr_arg; + (void) size; + TRASH(ptr_arg, size); + } + static void operator delete(void *, MEM_ROOT *) { /* never called */ } ~String() { free(); } diff --git a/cmd-line-utils/libedit/common.c b/cmd-line-utils/libedit/common.c index d4d024eae10..ba5890fa606 100644 --- a/cmd-line-utils/libedit/common.c +++ b/cmd-line-utils/libedit/common.c @@ -136,7 +136,7 @@ ed_delete_prev_word(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -ed_delete_next_char(EditLine *el, int c) +ed_delete_next_char(EditLine *el, int c __attribute__((__unused__))) { #ifdef notdef /* XXX */ #define EL el->el_line @@ -431,7 +431,8 @@ ed_argument_digit(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -ed_unassigned(EditLine *el, int c __attribute__((__unused__))) +ed_unassigned(EditLine *el __attribute__((__unused__)), + int c __attribute__((__unused__))) { return (CC_ERROR); diff --git a/cmd-line-utils/libedit/filecomplete.c b/cmd-line-utils/libedit/filecomplete.c index 4c63f57bc45..05bd10e9f9e 100644 --- a/cmd-line-utils/libedit/filecomplete.c +++ b/cmd-line-utils/libedit/filecomplete.c @@ -95,10 +95,9 @@ static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$', char * fn_tilde_expand(const char *txt) { - struct passwd pwres, *pass; + struct passwd *pass; char *temp; size_t len = 0; - char pwbuf[1024]; if (txt[0] != '~') return (strdup(txt)); diff --git a/cmd-line-utils/libedit/readline.c b/cmd-line-utils/libedit/readline.c index 1f1b18c97d8..0318ab409b3 100644 --- a/cmd-line-utils/libedit/readline.c +++ b/cmd-line-utils/libedit/readline.c @@ -202,7 +202,7 @@ _move_history(int op) */ static int /*ARGSUSED*/ -_getc_function(EditLine *el, char *c) +_getc_function(EditLine *el __attribute__((__unused__)), char *c) { int i; @@ -1613,7 +1613,8 @@ rl_insert(int count, int c) /*ARGSUSED*/ int -rl_newline(int count, int c) +rl_newline(int count __attribute__((__unused__)), + int c __attribute__((__unused__))) { /* * Readline-4.0 appears to ignore the args. @@ -1623,7 +1624,7 @@ rl_newline(int count, int c) /*ARGSUSED*/ static unsigned char -rl_bind_wrapper(EditLine *el, unsigned char c) +rl_bind_wrapper(EditLine *el __attribute__((__unused__)), unsigned char c) { if (map[c] == NULL) return CC_ERROR; @@ -1718,7 +1719,7 @@ rl_get_previous_history(int count, int key) void /*ARGSUSED*/ -rl_prep_terminal(int meta_flag) +rl_prep_terminal(int meta_flag __attribute__((__unused__))) { el_set(e, EL_PREP_TERM, 1); } @@ -1922,7 +1923,8 @@ _rl_qsort_string_compare(char **s1, char **s2) int /*ARGSUSED*/ -rl_kill_text(int from, int to) +rl_kill_text(int from __attribute__((__unused__)), + int to __attribute__((__unused__))) { return 0; } @@ -1941,20 +1943,25 @@ rl_get_keymap(void) void /*ARGSUSED*/ -rl_set_keymap(Keymap k) +rl_set_keymap(Keymap k __attribute__((__unused__))) { } int /*ARGSUSED*/ -rl_generic_bind(int type, const char * keyseq, const char * data, Keymap k) +rl_generic_bind(int type __attribute__((__unused__)), + const char * keyseq __attribute__((__unused__)), + const char * data __attribute__((__unused__)), + Keymap k __attribute__((__unused__))) { return 0; } int /*ARGSUSED*/ -rl_bind_key_in_map(int key, Function *fun, Keymap k) +rl_bind_key_in_map(int key __attribute__((__unused__)), + Function *fun __attribute__((__unused__)), + Keymap k __attribute__((__unused__))) { return 0; } diff --git a/cmd-line-utils/libedit/vi.c b/cmd-line-utils/libedit/vi.c index 00a9f493a9b..d628f076a1d 100644 --- a/cmd-line-utils/libedit/vi.c +++ b/cmd-line-utils/libedit/vi.c @@ -145,7 +145,7 @@ vi_paste_prev(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_prev_big_word(EditLine *el, int c) +vi_prev_big_word(EditLine *el, int c __attribute__((__unused__))) { if (el->el_line.cursor == el->el_line.buffer) @@ -195,7 +195,7 @@ vi_prev_word(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_next_big_word(EditLine *el, int c) +vi_next_big_word(EditLine *el, int c __attribute__((__unused__))) { if (el->el_line.cursor >= el->el_line.lastchar - 1) @@ -462,7 +462,7 @@ vi_delete_meta(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_end_big_word(EditLine *el, int c) +vi_end_big_word(EditLine *el, int c __attribute__((__unused__))) { if (el->el_line.cursor == el->el_line.lastchar) @@ -797,7 +797,7 @@ vi_repeat_prev_char(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_match(EditLine *el, int c) +vi_match(EditLine *el, int c __attribute__((__unused__))) { const char match_chars[] = "()[]{}"; char *cp; @@ -844,7 +844,7 @@ vi_match(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -vi_undo_line(EditLine *el, int c) +vi_undo_line(EditLine *el, int c __attribute__((__unused__))) { cv_undo(el); @@ -858,7 +858,7 @@ vi_undo_line(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -vi_to_column(EditLine *el, int c) +vi_to_column(EditLine *el, int c __attribute__((__unused__))) { el->el_line.cursor = el->el_line.buffer; @@ -872,7 +872,7 @@ vi_to_column(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -vi_yank_end(EditLine *el, int c) +vi_yank_end(EditLine *el, int c __attribute__((__unused__))) { cv_yank(el, el->el_line.cursor, @@ -886,7 +886,7 @@ vi_yank_end(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -vi_yank(EditLine *el, int c) +vi_yank(EditLine *el, int c __attribute__((__unused__))) { return cv_action(el, YANK); @@ -898,7 +898,7 @@ vi_yank(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -vi_comment_out(EditLine *el, int c) +vi_comment_out(EditLine *el, int c __attribute__((__unused__))) { el->el_line.cursor = el->el_line.buffer; @@ -919,7 +919,8 @@ extern char *get_alias_text(const char *) __weak_reference(get_alias_text); #endif protected el_action_t /*ARGSUSED*/ -vi_alias(EditLine *el, int c) +vi_alias(EditLine *el __attribute__((__unused__)), + int c __attribute__((__unused__))) { #if defined(__weak_reference) && !defined(__FreeBSD__) char alias_name[3]; @@ -949,7 +950,7 @@ vi_alias(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -vi_to_history_line(EditLine *el, int c) +vi_to_history_line(EditLine *el, int c __attribute__((__unused__))) { int sv_event_no = el->el_history.eventno; el_action_t rval; @@ -994,7 +995,7 @@ vi_to_history_line(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -vi_histedit(EditLine *el, int c) +vi_histedit(EditLine *el, int c __attribute__((__unused__))) { int fd; pid_t pid; @@ -1050,7 +1051,7 @@ vi_histedit(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -vi_history_word(EditLine *el, int c) +vi_history_word(EditLine *el, int c __attribute__((__unused__))) { const char *wp = HIST_FIRST(el); const char *wep, *wsp; @@ -1099,7 +1100,7 @@ vi_history_word(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -vi_redo(EditLine *el, int c) +vi_redo(EditLine *el, int c __attribute__((__unused__))) { c_redo_t *r = &el->el_chared.c_redo; diff --git a/regex/main.c b/regex/main.c index fa97ca89047..f5b591907cf 100644 --- a/regex/main.c +++ b/regex/main.c @@ -17,8 +17,8 @@ regoff_t startoff = 0; regoff_t endoff = 0; -extern int split(); -extern void regprint(); +extern int split(char *string, char *fields[], int nfields, char *sep); +extern void regprint(my_regex_t *r, FILE *d); /* - main - do the simple case, hand off to regress() for regression @@ -145,7 +145,7 @@ FILE *in; inbuf[strlen(inbuf)-1] = '\0'; /* get rid of stupid \n */ if (debug) fprintf(stdout, "%d:\n", line); - nf = split(inbuf, f, MAXF, "\t\t"); + nf = split(inbuf, f, MAXF, (char*) "\t\t"); if (nf < 3) { fprintf(stderr, "bad input, line %d\n", line); exit(1); @@ -288,7 +288,7 @@ int opts; /* may not match f1 */ for (i = 1; i < NSHOULD; i++) should[i] = NULL; - nshould = split(f4, should+1, NSHOULD-1, ","); + nshould = split(f4, should+1, NSHOULD-1, (char*) ","); if (nshould == 0) { nshould = 1; should[1] = (char*) ""; diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 9c26105546d..4f99d354754 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -1293,10 +1293,12 @@ int ha_ndbcluster::open_indexes(Ndb *ndb, TABLE *tab, bool ignore_error) for (i= 0; i < tab->s->keys; i++, key_info++, key_name++) { if ((error= add_index_handle(thd, dict, key_info, *key_name, i))) + { if (ignore_error) m_index[i].index= m_index[i].unique_index= NULL; else break; + } m_index[i].null_in_unique_index= FALSE; if (check_index_fields_not_null(key_info)) m_index[i].null_in_unique_index= TRUE; @@ -6265,8 +6267,8 @@ void ha_ndbcluster::get_auto_increment(ulonglong offset, ulonglong increment, for (;;) { Ndb_tuple_id_range_guard g(m_share); - if (m_skip_auto_increment && - ndb->readAutoIncrementValue(m_table, g.range, auto_value) || + if ((m_skip_auto_increment && + ndb->readAutoIncrementValue(m_table, g.range, auto_value)) || ndb->getAutoIncrementValue(m_table, g.range, auto_value, cache_size, increment, offset)) { if (--retries && @@ -9916,8 +9918,8 @@ bool ha_ndbcluster::check_if_incompatible_data(HA_CREATE_INFO *create_info, { Field *field= table->field[i]; const NDBCOL *col= tab->getColumn(i); - if (col->getStorageType() == NDB_STORAGETYPE_MEMORY && create_info->storage_media != HA_SM_MEMORY || - col->getStorageType() == NDB_STORAGETYPE_DISK && create_info->storage_media != HA_SM_DISK) + if ((col->getStorageType() == NDB_STORAGETYPE_MEMORY && create_info->storage_media != HA_SM_MEMORY) || + (col->getStorageType() == NDB_STORAGETYPE_DISK && create_info->storage_media != HA_SM_DISK)) { DBUG_PRINT("info", ("Column storage media is changed")); DBUG_RETURN(COMPATIBLE_DATA_NO); diff --git a/sql/log_event.cc b/sql/log_event.cc index 91b2746ce8f..49f47edad72 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -8362,7 +8362,7 @@ void Table_map_log_event::pack_info(Protocol *protocol) #ifdef MYSQL_CLIENT -void Table_map_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info) +void Table_map_log_event::print(FILE *, PRINT_EVENT_INFO *print_event_info) { if (!print_event_info->short_form) { diff --git a/sql/log_event.h b/sql/log_event.h index 662fec23639..75f2015a684 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -979,9 +979,9 @@ public: return (void*) my_malloc((uint)size, MYF(MY_WME|MY_FAE)); } - static void operator delete(void *ptr, size_t size) + static void operator delete(void *ptr, size_t) { - my_free((uchar*) ptr, MYF(MY_WME|MY_ALLOW_ZERO_PTR)); + my_free(ptr, MYF(MY_WME|MY_ALLOW_ZERO_PTR)); } /* Placement version of the above operators */ diff --git a/sql/my_decimal.h b/sql/my_decimal.h index 21669e82c44..a5077f397e3 100644 --- a/sql/my_decimal.h +++ b/sql/my_decimal.h @@ -308,7 +308,7 @@ int my_decimal2int(uint mask, const my_decimal *d, my_bool unsigned_flag, inline -int my_decimal2double(uint mask, const my_decimal *d, double *result) +int my_decimal2double(uint, const my_decimal *d, double *result) { /* No need to call check_result as this will always succeed */ return decimal2double((decimal_t*) d, result); diff --git a/sql/sql_string.h b/sql/sql_string.h index bb7d69aeccc..b15179bcbe5 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -84,9 +84,13 @@ public: } static void *operator new(size_t size, MEM_ROOT *mem_root) throw () { return (void*) alloc_root(mem_root, (uint) size); } - static void operator delete(void *ptr_arg,size_t size) - { TRASH(ptr_arg, size); } - static void operator delete(void *ptr_arg, MEM_ROOT *mem_root) + static void operator delete(void *ptr_arg, size_t size) + { + (void) ptr_arg; + (void) size; + TRASH(ptr_arg, size); + } + static void operator delete(void *, MEM_ROOT *) { /* never called */ } ~String() { free(); } From 4735eafcddba5ba486e3b26211a6ab4fe25393f0 Mon Sep 17 00:00:00 2001 From: Sunny Bains Date: Wed, 20 Oct 2010 14:39:31 +1100 Subject: [PATCH 075/304] Bug #57588 - Compiler warning in InnoDB due to comparison between signed and unsigned For DATA_MBMINLEN(), cast the result of UNIV_EXPECT to ulint because in GCC it returns a long causing unsigned/signed comparison warnings. Approved by Jimmy Yang on IM. --- storage/innobase/include/data0type.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/storage/innobase/include/data0type.h b/storage/innobase/include/data0type.h index 850cf2e2975..f0be5ace306 100644 --- a/storage/innobase/include/data0type.h +++ b/storage/innobase/include/data0type.h @@ -174,8 +174,11 @@ store the charset-collation number; one byte is left unused, though */ /* Pack mbminlen, mbmaxlen to mbminmaxlen. */ #define DATA_MBMINMAXLEN(mbminlen, mbmaxlen) \ ((mbmaxlen) * DATA_MBMAX + (mbminlen)) -/* Get mbminlen from mbminmaxlen. */ -#define DATA_MBMINLEN(mbminmaxlen) UNIV_EXPECT(((mbminmaxlen) % DATA_MBMAX), 1) +/* Get mbminlen from mbminmaxlen. Cast the result of UNIV_EXPECT to ulint +because in GCC it returns a long. */ +#define DATA_MBMINLEN(mbminmaxlen) ((ulint) \ + UNIV_EXPECT(((mbminmaxlen) % DATA_MBMAX), \ + 1)) /* Get mbmaxlen from mbminmaxlen. */ #define DATA_MBMAXLEN(mbminmaxlen) ((mbminmaxlen) / DATA_MBMAX) From 6960db2dfdd90aa155bbc88cb802bdc697be4b9c Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Wed, 20 Oct 2010 11:22:08 +0200 Subject: [PATCH 076/304] Bug #52019 main.mysqltest fails on new tests for lowercase_result Limited to actual bug fix, fixing a while condition Again confirmed on Linux PPC and on AIX 5.3 --- client/mysqltest.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 53c1f1bdf85..ee03b796873 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -5742,7 +5742,7 @@ int read_line(char *buf, int size) { /* It was not a multiline char, push back the characters */ /* We leave first 'c', i.e. pretend it was a normal char */ - while (p > mb_start) + while (p-1 > mb_start) my_ungetc(*--p); } } From f73ada3722b9cd3624e9eac8d07f482baaa1f03b Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Wed, 20 Oct 2010 11:30:50 +0200 Subject: [PATCH 077/304] 48863 followup: move an array declaration out from within if block --- client/mysqltest.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index ee03b796873..2bbb1c63724 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -9781,6 +9781,7 @@ void free_pointer_array(POINTER_ARRAY *pa) void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val, int len) { + char lower[512]; #ifdef __WIN__ fix_win_paths(val, len); #endif @@ -9788,7 +9789,6 @@ void replace_dynstr_append_mem(DYNAMIC_STRING *ds, if (display_result_lower) { /* Convert to lower case, and do this first */ - char lower[512]; char *c= lower; for (const char *v= val; *v; v++) *c++= my_tolower(charset_info, *v); From e533c7cc108e5b9a00c273baa027358c4edb4dd0 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Wed, 20 Oct 2010 11:39:58 +0200 Subject: [PATCH 078/304] Fixed missing cast of arg to my_mbcharlen --- client/mysqltest.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 2bbb1c63724..8523b40fc80 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -5721,7 +5721,7 @@ int read_line(char *buf, int size) /* Could be a multibyte character */ /* This code is based on the code in "sql_load.cc" */ #ifdef USE_MB - int charlen = my_mbcharlen(charset_info, c); + int charlen = my_mbcharlen(charset_info, (unsigned char) c); /* We give up if multibyte character is started but not */ /* completed before we pass buf_end */ if ((charlen > 1) && (p + charlen) <= buf_end) From e4f9ead1403bff9ff07b659f0e2a2575036d39da Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Wed, 20 Oct 2010 11:41:51 +0200 Subject: [PATCH 079/304] Fixed wrong feof check in read_line, see 52019 --- client/mysqltest.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 8523b40fc80..de46624bf2c 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -5733,9 +5733,9 @@ int read_line(char *buf, int size) for (i= 1; i < charlen; i++) { + c= my_getc(cur_file->file); if (feof(cur_file->file)) goto found_eof; - c= my_getc(cur_file->file); *p++ = c; } if (! my_ismbchar(charset_info, mb_start, p)) From 67a0d9c0e05b1df9bd7b29878a04f50449110e10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 20 Oct 2010 14:46:28 +0300 Subject: [PATCH 080/304] Fix bit-rot left by the multiple buffer pools patch. Rename buf_pool_watch, buf_pool_mutex, buf_pool_zip_mutex to buf_pool->watch, buf_pool->mutex, buf_pool->zip_mutex in comments. Refer to buf_pool->flush_list_mutex instead of flush_list_mutex. Remove obsolete declarations of buf_pool_mutex and buf_pool_zip_mutex. --- storage/innobase/buf/buf0buddy.c | 2 +- storage/innobase/buf/buf0buf.c | 6 ++-- storage/innobase/buf/buf0flu.c | 18 +++++------ storage/innobase/buf/buf0lru.c | 10 +++--- storage/innobase/include/buf0buddy.h | 2 +- storage/innobase/include/buf0buddy.ic | 4 +-- storage/innobase/include/buf0buf.h | 45 ++++++++++++--------------- storage/innobase/include/buf0flu.h | 2 +- storage/innobase/sync/sync0sync.c | 4 +-- 9 files changed, 44 insertions(+), 49 deletions(-) diff --git a/storage/innobase/buf/buf0buddy.c b/storage/innobase/buf/buf0buddy.c index 5dc0780cbdd..787b4e652a0 100644 --- a/storage/innobase/buf/buf0buddy.c +++ b/storage/innobase/buf/buf0buddy.c @@ -281,7 +281,7 @@ buf_buddy_alloc_from( /**********************************************************************//** Allocate a block. The thread calling this function must hold -buf_pool->mutex and must not hold buf_pool_zip_mutex or any block->mutex. +buf_pool->mutex and must not hold buf_pool->zip_mutex or any block->mutex. The buf_pool->mutex may only be released and reacquired if lru != NULL. @return allocated block, possibly NULL if lru==NULL */ UNIV_INTERN diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c index af631747f48..abfde83a3bd 100644 --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c @@ -172,7 +172,7 @@ The chain of modified blocks (buf_pool->flush_list) contains the blocks holding file pages that have been modified in the memory but not written to disk yet. The block with the oldest modification which has not yet been written to disk is at the end of the chain. -The access to this list is protected by flush_list_mutex. +The access to this list is protected by buf_pool->flush_list_mutex. The chain of unmodified compressed blocks (buf_pool->zip_clean) contains the control blocks (buf_page_t) of those compressed pages @@ -1882,8 +1882,8 @@ buf_pool_watch_set( ut_ad(!bpage->in_page_hash); ut_ad(bpage->buf_fix_count == 0); - /* bpage is pointing to buf_pool_watch[], - which is protected by buf_pool_mutex. + /* bpage is pointing to buf_pool->watch[], + which is protected by buf_pool->mutex. Normally, buf_page_t objects are protected by buf_block_t::mutex or buf_pool->zip_mutex or both. */ diff --git a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c index c342b8f1901..5b0617f17b1 100644 --- a/storage/innobase/buf/buf0flu.c +++ b/storage/innobase/buf/buf0flu.c @@ -321,7 +321,7 @@ buf_flush_insert_sorted_into_flush_list( buf_flush_list_mutex_enter(buf_pool); - /* The field in_LRU_list is protected by buf_pool_mutex, which + /* The field in_LRU_list is protected by buf_pool->mutex, which we are not holding. However, while a block is in the flush list, it is dirty and cannot be discarded, not from the page_hash or from the LRU list. At most, the uncompressed @@ -1061,7 +1061,7 @@ buf_flush_write_block_low( ut_ad(buf_page_in_file(bpage)); - /* We are not holding buf_pool_mutex or block_mutex here. + /* We are not holding buf_pool->mutex or block_mutex here. Nevertheless, it is safe to access bpage, because it is io_fixed and oldest_modification != 0. Thus, it cannot be relocated in the buffer pool or removed from flush_list or @@ -1135,7 +1135,7 @@ buf_flush_write_block_low( # if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG /********************************************************************//** Writes a flushable page asynchronously from the buffer pool to a file. -NOTE: buf_pool_mutex and block->mutex must be held upon entering this +NOTE: buf_pool->mutex and block->mutex must be held upon entering this function, and they will be released by this function after flushing. This is loosely based on buf_flush_batch() and buf_flush_page(). @return TRUE if the page was flushed and the mutexes released */ @@ -2193,12 +2193,12 @@ buf_flush_validate_low( ut_ad(bpage->in_flush_list); - /* A page in flush_list can be in BUF_BLOCK_REMOVE_HASH - state. This happens when a page is in the middle of - being relocated. In that case the original descriptor - can have this state and still be in the flush list - waiting to acquire the flush_list_mutex to complete - the relocation. */ + /* A page in buf_pool->flush_list can be in + BUF_BLOCK_REMOVE_HASH state. This happens when a page + is in the middle of being relocated. In that case the + original descriptor can have this state and still be + in the flush list waiting to acquire the + buf_pool->flush_list_mutex to complete the relocation. */ ut_a(buf_page_in_file(bpage) || buf_page_get_state(bpage) == BUF_BLOCK_REMOVE_HASH); ut_a(om > 0); diff --git a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c index e1d4b5081b8..8ad5f2dad83 100644 --- a/storage/innobase/buf/buf0lru.c +++ b/storage/innobase/buf/buf0lru.c @@ -356,8 +356,8 @@ scan_again: prev_bpage = UT_LIST_GET_PREV(LRU, bpage); /* bpage->space and bpage->io_fix are protected by - buf_pool_mutex and block_mutex. It is safe to check - them while holding buf_pool_mutex only. */ + buf_pool->mutex and block_mutex. It is safe to check + them while holding buf_pool->mutex only. */ if (buf_page_get_space(bpage) != id) { /* Skip this block, as it does not belong to @@ -403,7 +403,7 @@ scan_again: /* Descriptors of uncompressed blocks will not be relocated, because we are holding the - buf_pool_mutex. */ + buf_pool->mutex. */ break; case BUF_BLOCK_ZIP_PAGE: case BUF_BLOCK_ZIP_DIRTY: @@ -1443,10 +1443,10 @@ Try to free a block. If bpage is a descriptor of a compressed-only page, the descriptor object will be freed as well. NOTE: If this function returns BUF_LRU_FREED, it will temporarily -release buf_pool_mutex. Furthermore, the page frame will no longer be +release buf_pool->mutex. Furthermore, the page frame will no longer be accessible via bpage. -The caller must hold buf_pool_mutex and buf_page_get_mutex(bpage) and +The caller must hold buf_pool->mutex and buf_page_get_mutex(bpage) and release these two mutexes after the call. No other buf_page_get_mutex() may be held when calling this function. @return BUF_LRU_FREED if freed, BUF_LRU_CANNOT_RELOCATE or diff --git a/storage/innobase/include/buf0buddy.h b/storage/innobase/include/buf0buddy.h index 03588d18197..b255d8c9351 100644 --- a/storage/innobase/include/buf0buddy.h +++ b/storage/innobase/include/buf0buddy.h @@ -36,7 +36,7 @@ Created December 2006 by Marko Makela /**********************************************************************//** Allocate a block. The thread calling this function must hold -buf_pool->mutex and must not hold buf_pool_zip_mutex or any +buf_pool->mutex and must not hold buf_pool->zip_mutex or any block->mutex. The buf_pool->mutex may only be released and reacquired if lru != NULL. This function should only be used for allocating compressed page frames or control blocks (buf_page_t). Allocated diff --git a/storage/innobase/include/buf0buddy.ic b/storage/innobase/include/buf0buddy.ic index 387eacc754a..e50c33ea15a 100644 --- a/storage/innobase/include/buf0buddy.ic +++ b/storage/innobase/include/buf0buddy.ic @@ -35,7 +35,7 @@ Created December 2006 by Marko Makela /**********************************************************************//** Allocate a block. The thread calling this function must hold -buf_pool->mutex and must not hold buf_pool_zip_mutex or any block->mutex. +buf_pool->mutex and must not hold buf_pool->zip_mutex or any block->mutex. The buf_pool->mutex may only be released and reacquired if lru != NULL. @return allocated block, possibly NULL if lru==NULL */ UNIV_INTERN @@ -86,7 +86,7 @@ buf_buddy_get_slot( /**********************************************************************//** Allocate a block. The thread calling this function must hold -buf_pool->mutex and must not hold buf_pool_zip_mutex or any +buf_pool->mutex and must not hold buf_pool->zip_mutex or any block->mutex. The buf_pool->mutex may only be released and reacquired if lru != NULL. This function should only be used for allocating compressed page frames or control blocks (buf_page_t). Allocated diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index f33ef65ddf2..b0fff919918 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -96,7 +96,7 @@ enum buf_page_state { BUF_BLOCK_ZIP_FREE = 0, /*!< contains a free compressed page */ BUF_BLOCK_POOL_WATCH = 0, /*!< a sentinel for the buffer pool - watch, element of buf_pool_watch[] */ + watch, element of buf_pool->watch[] */ BUF_BLOCK_ZIP_PAGE, /*!< contains a clean compressed page */ BUF_BLOCK_ZIP_DIRTY, /*!< contains a compressed @@ -1210,10 +1210,10 @@ struct buf_page_struct{ #endif /* !UNIV_HOTBACKUP */ page_zip_des_t zip; /*!< compressed page; zip.data (but not the data it points to) is - also protected by buf_pool_mutex; + also protected by buf_pool->mutex; state == BUF_BLOCK_ZIP_PAGE and zip.data == NULL means an active - buf_pool_watch */ + buf_pool->watch */ #ifndef UNIV_HOTBACKUP buf_page_t* hash; /*!< node used in chaining to buf_pool->page_hash or @@ -1224,15 +1224,16 @@ struct buf_page_struct{ #endif /* UNIV_DEBUG */ /** @name Page flushing fields - All these are protected by buf_pool_mutex. */ + All these are protected by buf_pool->mutex. */ /* @{ */ UT_LIST_NODE_T(buf_page_t) list; /*!< based on state, this is a list node, protected either by - buf_pool_mutex or by - flush_list_mutex, in one of the - following lists in buf_pool: + buf_pool->mutex or by + buf_pool->flush_list_mutex, + in one of the following lists in + buf_pool: - BUF_BLOCK_NOT_USED: free - BUF_BLOCK_FILE_PAGE: flush_list @@ -1242,9 +1243,9 @@ struct buf_page_struct{ If bpage is part of flush_list then the node pointers are - covered by flush_list_mutex. + covered by buf_pool->flush_list_mutex. Otherwise these pointers are - protected by buf_pool_mutex. + protected by buf_pool->mutex. The contents of the list node is undefined if !in_flush_list @@ -1256,17 +1257,18 @@ struct buf_page_struct{ #ifdef UNIV_DEBUG ibool in_flush_list; /*!< TRUE if in buf_pool->flush_list; - when flush_list_mutex is free, the - following should hold: in_flush_list + when buf_pool->flush_list_mutex is + free, the following should hold: + in_flush_list == (state == BUF_BLOCK_FILE_PAGE || state == BUF_BLOCK_ZIP_DIRTY) Writes to this field must be covered by both block->mutex - and flush_list_mutex. Hence + and buf_pool->flush_list_mutex. Hence reads can happen while holding any one of the two mutexes */ ibool in_free_list; /*!< TRUE if in buf_pool->free; when - buf_pool_mutex is free, the following + buf_pool->mutex is free, the following should hold: in_free_list == (state == BUF_BLOCK_NOT_USED) */ #endif /* UNIV_DEBUG */ @@ -1286,7 +1288,7 @@ struct buf_page_struct{ modifications are on disk. Writes to this field must be covered by both block->mutex - and flush_list_mutex. Hence + and buf_pool->flush_list_mutex. Hence reads can happen while holding any one of the two mutexes */ /* @} */ @@ -1661,20 +1663,13 @@ struct buf_pool_struct{ /* @} */ }; -/** mutex protecting the buffer pool struct and control blocks, except the -read-write lock in them */ -extern mutex_t buf_pool_mutex; -/** mutex protecting the control blocks of compressed-only pages -(of type buf_page_t, not buf_block_t) */ -extern mutex_t buf_pool_zip_mutex; - -/** @name Accessors for buf_pool_mutex. -Use these instead of accessing buf_pool_mutex directly. */ +/** @name Accessors for buf_pool->mutex. +Use these instead of accessing buf_pool->mutex directly. */ /* @{ */ -/** Test if buf_pool_mutex is owned. */ +/** Test if a buffer pool mutex is owned. */ #define buf_pool_mutex_own(b) mutex_own(&b->mutex) -/** Acquire the buffer pool mutex. */ +/** Acquire a buffer pool mutex. */ #define buf_pool_mutex_enter(b) do { \ ut_ad(!mutex_own(&b->zip_mutex)); \ mutex_enter(&b->mutex); \ diff --git a/storage/innobase/include/buf0flu.h b/storage/innobase/include/buf0flu.h index 976456972c1..28d9b90e755 100644 --- a/storage/innobase/include/buf0flu.h +++ b/storage/innobase/include/buf0flu.h @@ -87,7 +87,7 @@ buf_flush_init_for_writing( # if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG /********************************************************************//** Writes a flushable page asynchronously from the buffer pool to a file. -NOTE: buf_pool_mutex and block->mutex must be held upon entering this +NOTE: buf_pool->mutex and block->mutex must be held upon entering this function, and they will be released by this function after flushing. This is loosely based on buf_flush_batch() and buf_flush_page(). @return TRUE if the page was flushed and the mutexes released */ diff --git a/storage/innobase/sync/sync0sync.c b/storage/innobase/sync/sync0sync.c index 8062d9e902e..761cc4c805e 100644 --- a/storage/innobase/sync/sync0sync.c +++ b/storage/innobase/sync/sync0sync.c @@ -1207,8 +1207,8 @@ sync_thread_add_level( case SYNC_BUF_BLOCK: /* Either the thread must own the buffer pool mutex - (buf_pool_mutex), or it is allowed to latch only ONE - buffer block (block->mutex or buf_pool_zip_mutex). */ + (buf_pool->mutex), or it is allowed to latch only ONE + buffer block (block->mutex or buf_pool->zip_mutex). */ if (!sync_thread_levels_g(array, level, FALSE)) { ut_a(sync_thread_levels_g(array, level - 1, TRUE)); ut_a(sync_thread_levels_contain(array, SYNC_BUF_POOL)); From 8739daeef02b1b3e3303a75f3454842eb1632514 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 20 Oct 2010 15:58:47 +0300 Subject: [PATCH 081/304] Fix a compiler warning caused by fixing Bug #57588 (compiler warning). Declare DATA_MBMAXLEN with the same data type as DATA_MBMINLEN. --- storage/innobase/include/data0type.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/include/data0type.h b/storage/innobase/include/data0type.h index f0be5ace306..d7fa0b9cd44 100644 --- a/storage/innobase/include/data0type.h +++ b/storage/innobase/include/data0type.h @@ -180,7 +180,7 @@ because in GCC it returns a long. */ UNIV_EXPECT(((mbminmaxlen) % DATA_MBMAX), \ 1)) /* Get mbmaxlen from mbminmaxlen. */ -#define DATA_MBMAXLEN(mbminmaxlen) ((mbminmaxlen) / DATA_MBMAX) +#define DATA_MBMAXLEN(mbminmaxlen) ((ulint) ((mbminmaxlen) / DATA_MBMAX)) #ifndef UNIV_HOTBACKUP /*********************************************************************//** From 7a8515cc200bc867bb1d0f24bc8b51ea237ef8dd Mon Sep 17 00:00:00 2001 From: Oystein Grovlen Date: Wed, 20 Oct 2010 15:17:29 +0200 Subject: [PATCH 082/304] Bug#57512 str_to_date crash... str_to_date function should only try to generate a warning for invalid input strings, not when input value is NULL. In latter case, val_str() of input argument will return a nil pointer. Trying to generate a warning using this pointer lead to a segmentation fault. Solution: Only generate warning when pointer to input string is non-nil. mysql-test/r/func_time.result: Added test case for Bug#57512 mysql-test/t/func_time.test: Added test case for Bug#57512 sql/item_timefunc.cc: Skip generating warning when pointer to input string is nil since this implies that input argument was NULL. --- mysql-test/r/func_time.result | 9 +++++++++ mysql-test/t/func_time.test | 8 ++++++++ sql/item_timefunc.cc | 2 +- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index f1b2196ebfa..15299e6734b 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -1327,3 +1327,12 @@ SELECT * FROM t1 WHERE date_date <= addtime(date_add("2000-1-1", INTERVAL "1:1:1 date_date DROP TABLE t1; # +# Bug#57512 str_to_date crash... +# +SELECT WEEK(STR_TO_DATE(NULL,0)); +WEEK(STR_TO_DATE(NULL,0)) +NULL +SELECT SUBDATE(STR_TO_DATE(NULL,0), INTERVAL 1 HOUR); +SUBDATE(STR_TO_DATE(NULL,0), INTERVAL 1 HOUR) +NULL +# diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index 08c09adb093..901c55f4ad3 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -842,5 +842,13 @@ INSERT INTO t1 VALUES ('2008-01-03 00:00:00'), ('2008-01-03 00:00:00'); SELECT * FROM t1 WHERE date_date >= subtime(now(), "00:30:00"); SELECT * FROM t1 WHERE date_date <= addtime(date_add("2000-1-1", INTERVAL "1:1:1" HOUR_SECOND), "00:20:00"); DROP TABLE t1; + +--echo # +--echo # Bug#57512 str_to_date crash... +--echo # + +SELECT WEEK(STR_TO_DATE(NULL,0)); +SELECT SUBDATE(STR_TO_DATE(NULL,0), INTERVAL 1 HOUR); + --echo # diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 49336b04e16..3771706fb63 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -3465,7 +3465,7 @@ bool Item_func_str_to_date::get_date(MYSQL_TIME *ltime, uint fuzzy_date) return 0; null_date: - if (fuzzy_date & TIME_NO_ZERO_DATE) + if (val && (fuzzy_date & TIME_NO_ZERO_DATE)) { char buff[128]; strmake(buff, val->ptr(), min(val->length(), sizeof(buff)-1)); From b5bb13ec0380624c2e663a4e9b4b29fe574b3e05 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Wed, 20 Oct 2010 11:40:04 -0200 Subject: [PATCH 083/304] Bug#45288: pb2 returns a lot of compilation warnings Fix assorted compiler warnings. include/my_pthread.h: Like for pthread_cond_timedwait, the abstime is constant. mysys/my_gethwaddr.c: Instead of using a manual copy that introduce warnings due to type mismatch, copy the buffer using memcpy and use memcmp to check whether all bytes of the buffer are zeroed. mysys/thr_mutex.c: Like for pthread_cond_timedwait, the abstime is constant. unittest/mytap/tap.h: Introduce a ok() variant that does not take a format argument. Since ok() is tagged with a printf attribute, GCC complains if the fmt argument is NULL. --- include/my_pthread.h | 3 ++- mysys/my_gethwaddr.c | 32 +++++++++++++------------------- mysys/thr_mutex.c | 4 ++-- unittest/examples/skip-t.c | 8 ++++---- unittest/examples/skip_all-t.c | 8 ++++---- unittest/examples/todo-t.c | 8 ++++---- unittest/mytap/t/basic-t.c | 2 +- unittest/mytap/tap.c | 17 +++++++++++++++++ unittest/mytap/tap.h | 15 +++++++++++++-- 9 files changed, 60 insertions(+), 37 deletions(-) diff --git a/include/my_pthread.h b/include/my_pthread.h index fec7c972a7b..a7e4ea25064 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -492,7 +492,8 @@ int safe_mutex_destroy(safe_mutex_t *mp,const char *file, uint line); int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp,const char *file, uint line); int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp, - struct timespec *abstime, const char *file, uint line); + const struct timespec *abstime, + const char *file, uint line); void safe_mutex_global_init(void); void safe_mutex_end(FILE *file); diff --git a/mysys/my_gethwaddr.c b/mysys/my_gethwaddr.c index 00e0e90f1e4..90908bd1c0d 100644 --- a/mysys/my_gethwaddr.c +++ b/mysys/my_gethwaddr.c @@ -21,18 +21,6 @@ #ifndef MAIN -#if defined(__FreeBSD__) || defined(__linux__) -static my_bool memcpy_and_test(uchar *to, uchar *from, uint len) -{ - uint i, res=1; - - for (i=0; i < len; i++) - if ((*to++= *from++)) - res=0; - return res; -} -#endif /* FreeBSD || linux */ - #ifdef __FreeBSD__ #include @@ -44,10 +32,11 @@ static my_bool memcpy_and_test(uchar *to, uchar *from, uint len) my_bool my_gethwaddr(uchar *to) { size_t len; - uchar *buf, *next, *end, *addr; + char *buf, *next, *end; struct if_msghdr *ifm; struct sockaddr_dl *sdl; int res=1, mib[6]={CTL_NET, AF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0}; + char zero_array[ETHER_ADDR_LEN] = {0}; if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1) goto err; @@ -63,9 +52,9 @@ my_bool my_gethwaddr(uchar *to) ifm = (struct if_msghdr *)next; if (ifm->ifm_type == RTM_IFINFO) { - sdl = (struct sockaddr_dl *)(ifm + 1); - addr=LLADDR(sdl); - res=memcpy_and_test(to, addr, ETHER_ADDR_LEN); + sdl= (struct sockaddr_dl *)(ifm + 1); + memcpy(to, LLADDR(sdl), ETHER_ADDR_LEN); + res= memcmp(to, zero_array, ETHER_ADDR_LEN) ? 0 : 1; } } @@ -81,8 +70,9 @@ err: my_bool my_gethwaddr(uchar *to) { - int fd, res=1; + int fd, res= 1; struct ifreq ifr; + char zero_array[ETHER_ADDR_LEN] = {0}; fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) @@ -91,9 +81,13 @@ my_bool my_gethwaddr(uchar *to) bzero(&ifr, sizeof(ifr)); strnmov(ifr.ifr_name, "eth0", sizeof(ifr.ifr_name) - 1); - do { + do + { if (ioctl(fd, SIOCGIFHWADDR, &ifr) >= 0) - res=memcpy_and_test(to, (uchar *)&ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN); + { + memcpy(to, &ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN); + res= memcmp(to, zero_array, ETHER_ADDR_LEN) ? 0 : 1; + } } while (res && (errno == 0 || errno == ENODEV) && ifr.ifr_name[3]++ < '6'); close(fd); diff --git a/mysys/thr_mutex.c b/mysys/thr_mutex.c index 8f9928026ba..c7600b58c95 100644 --- a/mysys/thr_mutex.c +++ b/mysys/thr_mutex.c @@ -259,8 +259,8 @@ int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp, const char *file, int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp, - struct timespec *abstime, - const char *file, uint line) + const struct timespec *abstime, + const char *file, uint line) { int error; pthread_mutex_lock(&mp->global); diff --git a/unittest/examples/skip-t.c b/unittest/examples/skip-t.c index 092353fcc48..c8c910b31ff 100644 --- a/unittest/examples/skip-t.c +++ b/unittest/examples/skip-t.c @@ -18,11 +18,11 @@ int main() { plan(4); - ok(1, NULL); - ok(1, NULL); + ok1(1); + ok1(1); SKIP_BLOCK_IF(1, 2, "Example of skipping a few test points in a test") { - ok(1, NULL); - ok(1, NULL); + ok1(1); + ok1(1); } return exit_status(); } diff --git a/unittest/examples/skip_all-t.c b/unittest/examples/skip_all-t.c index a4c8648fbe4..826fa22e82f 100644 --- a/unittest/examples/skip_all-t.c +++ b/unittest/examples/skip_all-t.c @@ -31,9 +31,9 @@ int main() { if (!has_feature()) skip_all("Example of skipping an entire test"); plan(4); - ok(1, NULL); - ok(1, NULL); - ok(1, NULL); - ok(1, NULL); + ok1(1); + ok1(1); + ok1(1); + ok1(1); return exit_status(); } diff --git a/unittest/examples/todo-t.c b/unittest/examples/todo-t.c index 2de409447ba..2751da5e010 100644 --- a/unittest/examples/todo-t.c +++ b/unittest/examples/todo-t.c @@ -21,15 +21,15 @@ int main() { plan(4); - ok(1, NULL); - ok(1, NULL); + ok1(1); + ok1(1); /* Tests in the todo region is expected to fail. If they don't, something is strange. */ todo_start("Need to fix these"); - ok(0, NULL); - ok(0, NULL); + ok1(0); + ok1(0); todo_end(); return exit_status(); } diff --git a/unittest/mytap/t/basic-t.c b/unittest/mytap/t/basic-t.c index c0ceb5bf190..b588521d192 100644 --- a/unittest/mytap/t/basic-t.c +++ b/unittest/mytap/t/basic-t.c @@ -22,7 +22,7 @@ int main() { plan(5); ok(1 == 1, "testing basic functions"); ok(2 == 2, " "); - ok(3 == 3, NULL); + ok1(3 == 3); if (1 == 1) skip(2, "Sensa fragoli"); else { diff --git a/unittest/mytap/tap.c b/unittest/mytap/tap.c index a5831f2b71d..2566d90c4b0 100644 --- a/unittest/mytap/tap.c +++ b/unittest/mytap/tap.c @@ -223,6 +223,23 @@ ok(int const pass, char const *fmt, ...) emit_endl(); } +void +ok1(int const pass) +{ + va_list ap; + + memset(&ap, 0, sizeof(ap)); + + if (!pass && *g_test.todo == '\0') + ++g_test.failed; + + vemit_tap(pass, NULL, ap); + + if (*g_test.todo != '\0') + emit_dir("todo", g_test.todo); + + emit_endl(); +} void skip(int how_many, char const *fmt, ...) diff --git a/unittest/mytap/tap.h b/unittest/mytap/tap.h index 4118207ca7a..010121507bc 100644 --- a/unittest/mytap/tap.h +++ b/unittest/mytap/tap.h @@ -98,14 +98,25 @@ void plan(int const count); @endcode @param pass Zero if the test failed, non-zero if it passed. - @param fmt Format string in printf() format. NULL is allowed, in - which case nothing is printed. + @param fmt Format string in printf() format. NULL is not allowed, + use ok1() in this case. */ void ok(int const pass, char const *fmt, ...) __attribute__((format(printf,2,3))); +/** + Report test result as a TAP line. + + Same as ok() but does not take a message to be printed. + + @param pass Zero if the test failed, non-zero if it passed. +*/ + +void ok1(int const pass); + + /** Skip a determined number of tests. From 0455ff8faf97da88c0a1cb42a615e75f43e40012 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Wed, 20 Oct 2010 16:15:32 +0200 Subject: [PATCH 084/304] Follow-up to Bug #55582 which allows chaecking strings in if Simplified cases where a select was used to compare variable against '' --- .../extra/rpl_tests/rpl_get_master_version_and_clock.test | 2 +- mysql-test/extra/rpl_tests/rpl_loaddata.test | 2 +- mysql-test/include/check_concurrent_insert.inc | 4 ++-- mysql-test/include/check_no_concurrent_insert.inc | 4 ++-- mysql-test/include/get_relay_log_pos.inc | 4 ++-- mysql-test/include/kill_query.inc | 4 ++-- mysql-test/include/kill_query_and_diff_master_slave.inc | 8 ++++---- mysql-test/include/setup_fake_relay_log.inc | 2 +- mysql-test/include/show_binlog_events.inc | 4 ++-- mysql-test/include/show_rpl_debug_info.inc | 6 +++--- mysql-test/include/wait_for_slave_io_error.inc | 2 +- mysql-test/include/wait_for_slave_param.inc | 4 ++-- mysql-test/include/wait_for_slave_sql_error.inc | 2 +- mysql-test/include/wait_for_status_var.inc | 2 +- mysql-test/suite/rpl/t/rpl_killed_ddl.test | 2 +- 15 files changed, 26 insertions(+), 26 deletions(-) diff --git a/mysql-test/extra/rpl_tests/rpl_get_master_version_and_clock.test b/mysql-test/extra/rpl_tests/rpl_get_master_version_and_clock.test index 66bd61a8ea9..40e155bc314 100644 --- a/mysql-test/extra/rpl_tests/rpl_get_master_version_and_clock.test +++ b/mysql-test/extra/rpl_tests/rpl_get_master_version_and_clock.test @@ -34,7 +34,7 @@ # connection slave; -if (`SELECT $debug_sync_action = ''`) +if (!$debug_sync_action) { --die Cannot continue. Please set value for debug_sync_action. } diff --git a/mysql-test/extra/rpl_tests/rpl_loaddata.test b/mysql-test/extra/rpl_tests/rpl_loaddata.test index 1ae17398596..84419ec9cc5 100644 --- a/mysql-test/extra/rpl_tests/rpl_loaddata.test +++ b/mysql-test/extra/rpl_tests/rpl_loaddata.test @@ -24,7 +24,7 @@ connection master; # MTR is not case-sensitive. let $lower_stmt_head= load data; let $UPPER_STMT_HEAD= LOAD DATA; -if (`SELECT '$lock_option' <> ''`) +if ($lock_option) { #if $lock_option is null, an extra blank is added into the statement, #this will change the result of rpl_loaddata test case. so $lock_option diff --git a/mysql-test/include/check_concurrent_insert.inc b/mysql-test/include/check_concurrent_insert.inc index f4bec3c9cdb..62de485d8f1 100644 --- a/mysql-test/include/check_concurrent_insert.inc +++ b/mysql-test/include/check_concurrent_insert.inc @@ -23,7 +23,7 @@ # Reset DEBUG_SYNC facility for safety. set debug_sync= "RESET"; -if (`SELECT '$restore_table' <> ''`) +if ($restore_table) { --eval create temporary table t_backup select * from $restore_table; } @@ -82,7 +82,7 @@ connection default; --eval delete from $table where i = 0; -if (`SELECT '$restore_table' <> ''`) +if ($restore_table) { --eval truncate table $restore_table; --eval insert into $restore_table select * from t_backup; diff --git a/mysql-test/include/check_no_concurrent_insert.inc b/mysql-test/include/check_no_concurrent_insert.inc index f60401bcad1..6938c53fd16 100644 --- a/mysql-test/include/check_no_concurrent_insert.inc +++ b/mysql-test/include/check_no_concurrent_insert.inc @@ -23,7 +23,7 @@ # Reset DEBUG_SYNC facility for safety. set debug_sync= "RESET"; -if (`SELECT '$restore_table' <> ''`) +if ($restore_table) { --eval create temporary table t_backup select * from $restore_table; } @@ -67,7 +67,7 @@ if (!$success) --eval delete from $table where i = 0; -if (`SELECT '$restore_table' <> ''`) +if ($restore_table) { --eval truncate table $restore_table; --eval insert into $restore_table select * from t_backup; diff --git a/mysql-test/include/get_relay_log_pos.inc b/mysql-test/include/get_relay_log_pos.inc index 7ce36fd3c50..61ee07fc655 100644 --- a/mysql-test/include/get_relay_log_pos.inc +++ b/mysql-test/include/get_relay_log_pos.inc @@ -10,12 +10,12 @@ # # at this point, get_relay_log_pos.inc sets $relay_log_pos. echo position # # in $relay_log_file: $relay_log_pos. -if (`SELECT '$relay_log_file' = ''`) +if (!$relay_log_file) { --die 'variable $relay_log_file is null' } -if (`SELECT '$master_log_pos' = ''`) +if (!$master_log_pos) { --die 'variable $master_log_pos is null' } diff --git a/mysql-test/include/kill_query.inc b/mysql-test/include/kill_query.inc index b303ed0ec39..1c949d3cbad 100644 --- a/mysql-test/include/kill_query.inc +++ b/mysql-test/include/kill_query.inc @@ -44,7 +44,7 @@ connection master; # kill the query that is waiting eval kill query $connection_id; -if (`SELECT '$debug_lock' != ''`) +if ($debug_lock) { # release the lock to allow binlog continue eval SELECT RELEASE_LOCK($debug_lock); @@ -57,7 +57,7 @@ reap; connection master; -if (`SELECT '$debug_lock' != ''`) +if ($debug_lock) { # get lock again to make the next query wait eval SELECT GET_LOCK($debug_lock, 10); diff --git a/mysql-test/include/kill_query_and_diff_master_slave.inc b/mysql-test/include/kill_query_and_diff_master_slave.inc index 611d6929c99..b3846d12df1 100644 --- a/mysql-test/include/kill_query_and_diff_master_slave.inc +++ b/mysql-test/include/kill_query_and_diff_master_slave.inc @@ -25,7 +25,7 @@ source include/kill_query.inc; connection master; disable_query_log; disable_result_log; -if (`SELECT '$debug_lock' != ''`) +if ($debug_lock) { eval SELECT RELEASE_LOCK($debug_lock); } @@ -36,8 +36,8 @@ source include/diff_master_slave.inc; # Acquire the debug lock again if used connection master; -disable_query_log; disable_result_log; if (`SELECT '$debug_lock' != -''`) { eval SELECT GET_LOCK($debug_lock, 10); } enable_result_log; -enable_query_log; +disable_query_log; disable_result_log; +if ($debug_lock) { eval SELECT GET_LOCK($debug_lock, 10); } +enable_result_log; enable_query_log; connection $connection_name; diff --git a/mysql-test/include/setup_fake_relay_log.inc b/mysql-test/include/setup_fake_relay_log.inc index fb035941a29..f881f3bf4e8 100644 --- a/mysql-test/include/setup_fake_relay_log.inc +++ b/mysql-test/include/setup_fake_relay_log.inc @@ -56,7 +56,7 @@ if (`SELECT "$_sql_running" = "Yes" OR "$_io_running" = "Yes"`) { # Read server variables. let $MYSQLD_DATADIR= `SELECT @@datadir`; let $_fake_filename= query_get_value(SHOW VARIABLES LIKE 'relay_log', Value, 1); -if (`SELECT '$_fake_filename' = ''`) { +if (!$_fake_filename) { --echo Badly written test case: relay_log variable is empty. Please use the --echo server option --relay-log=FILE. } diff --git a/mysql-test/include/show_binlog_events.inc b/mysql-test/include/show_binlog_events.inc index 8649f31ad9f..6d8c8196102 100644 --- a/mysql-test/include/show_binlog_events.inc +++ b/mysql-test/include/show_binlog_events.inc @@ -27,14 +27,14 @@ if (!$binlog_start) } --let $_statement=show binlog events -if (`SELECT '$binlog_file' <> ''`) +if ($binlog_file) { --let $_statement= $_statement in '$binlog_file' } --let $_statement= $_statement from $binlog_start -if (`SELECT '$binlog_limit' <> ''`) +if ($binlog_limit) { --let $_statement= $_statement limit $binlog_limit } diff --git a/mysql-test/include/show_rpl_debug_info.inc b/mysql-test/include/show_rpl_debug_info.inc index 148d11f3b02..9944e6cd25f 100644 --- a/mysql-test/include/show_rpl_debug_info.inc +++ b/mysql-test/include/show_rpl_debug_info.inc @@ -48,13 +48,13 @@ let $binlog_name= query_get_value("SHOW MASTER STATUS", File, 1); eval SHOW BINLOG EVENTS IN '$binlog_name'; let $_master_con= $master_connection; -if (`SELECT '$_master_con' = ''`) +if (!$_master_con) { if (`SELECT '$_con' = 'slave'`) { let $_master_con= master; } - if (`SELECT '$_master_con' = ''`) + if (!$_master_con) { --echo Unable to determine master connection. No debug info printed for master. --echo Please fix the test case by setting $master_connection before sourcing @@ -62,7 +62,7 @@ if (`SELECT '$_master_con' = ''`) } } -if (`SELECT '$_master_con' != ''`) +if ($_master_con) { let $master_binlog_name_io= query_get_value("SHOW SLAVE STATUS", Master_Log_File, 1); diff --git a/mysql-test/include/wait_for_slave_io_error.inc b/mysql-test/include/wait_for_slave_io_error.inc index 34cbf20a73b..ffdcf752873 100644 --- a/mysql-test/include/wait_for_slave_io_error.inc +++ b/mysql-test/include/wait_for_slave_io_error.inc @@ -31,7 +31,7 @@ # $master_connection # See wait_for_slave_param.inc for description. -if (`SELECT '$slave_io_errno' = ''`) { +if (!$slave_io_errno) { --die !!!ERROR IN TEST: you must set \$slave_io_errno before sourcing wait_for_slave_io_error.inc } diff --git a/mysql-test/include/wait_for_slave_param.inc b/mysql-test/include/wait_for_slave_param.inc index ef864f9245e..98cd426fa11 100644 --- a/mysql-test/include/wait_for_slave_param.inc +++ b/mysql-test/include/wait_for_slave_param.inc @@ -51,7 +51,7 @@ if (!$_slave_timeout_counter) } let $_slave_param_comparison= $slave_param_comparison; -if (`SELECT '$_slave_param_comparison' = ''`) +if (!$_slave_param_comparison) { let $_slave_param_comparison= =; } @@ -71,7 +71,7 @@ while (`SELECT NOT('$_show_slave_status_value' $_slave_param_comparison '$slave_ if (!$_slave_timeout_counter) { --echo **** ERROR: timeout after $slave_timeout seconds while waiting for slave parameter $slave_param $_slave_param_comparison $slave_param_value **** - if (`SELECT '$slave_error_message' != ''`) + if ($slave_error_message) { --echo Message: $slave_error_message } diff --git a/mysql-test/include/wait_for_slave_sql_error.inc b/mysql-test/include/wait_for_slave_sql_error.inc index aab04036eea..80836f908c6 100644 --- a/mysql-test/include/wait_for_slave_sql_error.inc +++ b/mysql-test/include/wait_for_slave_sql_error.inc @@ -24,7 +24,7 @@ # $master_connection # See wait_for_slave_param.inc for description. -if (`SELECT '$slave_sql_errno' = ''`) { +if (!$slave_sql_errno) { --die !!!ERROR IN TEST: you must set \$slave_sql_errno before sourcing wait_for_slave_sql_error.inc } diff --git a/mysql-test/include/wait_for_status_var.inc b/mysql-test/include/wait_for_status_var.inc index 8b644c2c3c5..9f4962aeaed 100644 --- a/mysql-test/include/wait_for_status_var.inc +++ b/mysql-test/include/wait_for_status_var.inc @@ -45,7 +45,7 @@ if (!$_status_timeout_counter) } let $_status_var_comparsion= $status_var_comparsion; -if (`SELECT '$_status_var_comparsion' = ''`) +if (!$_status_var_comparsion) { let $_status_var_comparsion= =; } diff --git a/mysql-test/suite/rpl/t/rpl_killed_ddl.test b/mysql-test/suite/rpl/t/rpl_killed_ddl.test index 61b882efcf3..69648267ca4 100644 --- a/mysql-test/suite/rpl/t/rpl_killed_ddl.test +++ b/mysql-test/suite/rpl/t/rpl_killed_ddl.test @@ -119,7 +119,7 @@ echo [on master]; # This will block the execution of a statement at the DBUG_SYNC_POINT # with given lock name -if (`SELECT '$debug_lock' != ''`) +if ($debug_lock) { disable_query_log; disable_result_log; From d6af9bef7a72f24b05a88b6cd4fd3a69b14cc82d Mon Sep 17 00:00:00 2001 From: "Horst.Hunger" Date: Wed, 20 Oct 2010 16:56:09 +0200 Subject: [PATCH 085/304] due to merge --- mysql-test/include/have_plugin_interface.inc | 5 + mysql-test/include/have_plugin_server.inc | 5 + mysql-test/mysql-test-run.pl | 17 +- mysql-test/r/plugin_auth_qa.result | 327 ++++++++++++++++++ mysql-test/r/plugin_auth_qa_1.result | 335 ++++++++++++++++++ mysql-test/r/plugin_auth_qa_2.result | 146 ++++++++ mysql-test/r/plugin_auth_qa_3.result | 11 + mysql-test/t/plugin_auth_qa-master.opt | 2 + mysql-test/t/plugin_auth_qa.test | 338 +++++++++++++++++++ mysql-test/t/plugin_auth_qa_1-master.opt | 2 + mysql-test/t/plugin_auth_qa_1.test | 334 ++++++++++++++++++ mysql-test/t/plugin_auth_qa_2-master.opt | 2 + mysql-test/t/plugin_auth_qa_2.test | 148 ++++++++ mysql-test/t/plugin_auth_qa_3-master.opt | 2 + mysql-test/t/plugin_auth_qa_3.test | 25 ++ plugin/auth/CMakeLists.txt | 8 + plugin/auth/Makefile.am | 6 +- plugin/auth/qa_auth_client.c | 127 +++++++ plugin/auth/qa_auth_interface.c | 262 ++++++++++++++ plugin/auth/qa_auth_server.c | 87 +++++ 20 files changed, 2187 insertions(+), 2 deletions(-) create mode 100644 mysql-test/include/have_plugin_interface.inc create mode 100644 mysql-test/include/have_plugin_server.inc create mode 100644 mysql-test/r/plugin_auth_qa.result create mode 100644 mysql-test/r/plugin_auth_qa_1.result create mode 100644 mysql-test/r/plugin_auth_qa_2.result create mode 100644 mysql-test/r/plugin_auth_qa_3.result create mode 100644 mysql-test/t/plugin_auth_qa-master.opt create mode 100644 mysql-test/t/plugin_auth_qa.test create mode 100644 mysql-test/t/plugin_auth_qa_1-master.opt create mode 100644 mysql-test/t/plugin_auth_qa_1.test create mode 100644 mysql-test/t/plugin_auth_qa_2-master.opt create mode 100644 mysql-test/t/plugin_auth_qa_2.test create mode 100644 mysql-test/t/plugin_auth_qa_3-master.opt create mode 100644 mysql-test/t/plugin_auth_qa_3.test create mode 100644 plugin/auth/qa_auth_client.c create mode 100644 plugin/auth/qa_auth_interface.c create mode 100644 plugin/auth/qa_auth_server.c diff --git a/mysql-test/include/have_plugin_interface.inc b/mysql-test/include/have_plugin_interface.inc new file mode 100644 index 00000000000..afe8ffad40d --- /dev/null +++ b/mysql-test/include/have_plugin_interface.inc @@ -0,0 +1,5 @@ +--disable_query_log +--require r/true.require +select (PLUGIN_LIBRARY LIKE 'qa_auth_interface%') as `TRUE` FROM INFORMATION_SCHEMA.PLUGINS + WHERE PLUGIN_NAME='qa_auth_interface'; +--enable_query_log diff --git a/mysql-test/include/have_plugin_server.inc b/mysql-test/include/have_plugin_server.inc new file mode 100644 index 00000000000..aad1f026b44 --- /dev/null +++ b/mysql-test/include/have_plugin_server.inc @@ -0,0 +1,5 @@ +--disable_query_log +--require r/true.require +select (PLUGIN_LIBRARY LIKE 'qa_auth_server%') as `TRUE` FROM INFORMATION_SCHEMA.PLUGINS + WHERE PLUGIN_NAME='qa_auth_server'; +--enable_query_log diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 88719ff5bb2..419fb4fdbaa 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -131,6 +131,9 @@ my $opt_start_dirty; my $opt_start_exit; my $start_only; +my $auth_interface_fn; # the name of qa_auth_interface plugin +my $auth_server_fn; # the name of qa_auth_server plugin +my $auth_client_fn; # the name of qa_auth_client plugin my $auth_filename; # the name of the authentication test plugin my $auth_plugin; # the path to the authentication test plugin @@ -1062,14 +1065,20 @@ sub command_line_setup { "$basedir/sql/share/charsets", "$basedir/share/charsets"); - # Look for client test plugin + # Look for auth test plugins if (IS_WINDOWS) { $auth_filename = "auth_test_plugin.dll"; + $auth_interface_fn = "qa_auth_interface.dll"; + $auth_server_fn = "qa_auth_server.dll"; + $auth_client_fn = "qa_auth_client.dll"; } else { $auth_filename = "auth_test_plugin.so"; + $auth_interface_fn = "qa_auth_interface.so"; + $auth_server_fn = "qa_auth_server.so"; + $auth_client_fn = "qa_auth_client.so"; } $auth_plugin= mtr_file_exists(vs_config_dirs('plugin/auth/',$auth_filename), @@ -1973,12 +1982,18 @@ sub environment_setup { $ENV{'PLUGIN_AUTH_OPT'}= "--plugin-dir=".dirname($auth_plugin); $ENV{'PLUGIN_AUTH_LOAD'}="--plugin_load=test_plugin_server=".$auth_filename; + $ENV{'PLUGIN_AUTH_INTERFACE'}="--plugin_load=qa_auth_interface=".$auth_interface_fn; + $ENV{'PLUGIN_AUTH_SERVER'}="--plugin_load=qa_auth_server=".$auth_server_fn; + $ENV{'PLUGIN_AUTH_CLIENT'}="--plugin_load=qa_auth_client=".$auth_client_fn; } else { $ENV{'PLUGIN_AUTH'}= ""; $ENV{'PLUGIN_AUTH_OPT'}="--plugin-dir="; $ENV{'PLUGIN_AUTH_LOAD'}=""; + $ENV{'PLUGIN_AUTH_INTERFACE'}=""; + $ENV{'PLUGIN_AUTH_SERVER'}=""; + $ENV{'PLUGIN_AUTH_CLIENT'}=""; } diff --git a/mysql-test/r/plugin_auth_qa.result b/mysql-test/r/plugin_auth_qa.result new file mode 100644 index 00000000000..d1ecf6a6470 --- /dev/null +++ b/mysql-test/r/plugin_auth_qa.result @@ -0,0 +1,327 @@ +CREATE DATABASE test_user_db; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +========== test 1.1 ====================================================== +CREATE USER plug IDENTIFIED WITH test_plugin_server; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server +DROP USER plug; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH test_plugin_server; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server +REVOKE ALL PRIVILEGES ON test_user_db.* FROM plug; +DROP USER plug; +CREATE USER plug IDENTIFIED WITH 'test_plugin_server'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server +DROP USER plug; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server +REVOKE ALL PRIVILEGES ON test_user_db.* FROM plug; +DROP USER plug; +CREATE USER plug IDENTIFIED WITH test_plugin_server AS ''; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server +DROP USER plug; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH test_plugin_server AS ''; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server +REVOKE ALL PRIVILEGES ON test_user_db.* FROM plug; +DROP USER plug; +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS ; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server' AS; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 +CREATE USER plug IDENTIFIED WITH test_plugin_server AS plug_dest; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'plug_dest' at line 1 +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH test_plugin_server AS plug_dest; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'plug_dest' at line 1 +========== test 1.1 syntax errors ======================================== +CREATE USER plug IDENTIFIED WITH AS plug_dest; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS plug_dest' at line 1 +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH AS plug_dest; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS plug_dest' at line 1 +CREATE USER plug IDENTIFIED WITH; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 +CREATE USER plug IDENTIFIED AS ''; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS ''' at line 1 +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED AS ''; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS ''' at line 1 +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' IDENTIFIED WITH 'test_plugin_server'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IDENTIFIED WITH 'test_plugin_server'' at line 1 +GRANT ALL PRIVILEGES ON test_user_db.* TO plug +IDENTIFIED WITH 'test_plugin_server' IDENTIFIED WITH 'test_plugin_server'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IDENTIFIED WITH 'test_plugin_server'' at line 2 +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS '' AS 'plug_dest'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS 'plug_dest'' at line 1 +GRANT ALL PRIVILEGES ON test_user_db.* TO plug AS '' AS 'plug_dest'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS '' AS 'plug_dest'' at line 1 +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS '' +IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IDENTIFIED WITH test_plugin_server AS 'plug_dest'' at line 2 +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server' AS '' + IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IDENTIFIED WITH test_plugin_server AS 'plug_dest'' at line 2 +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd' +IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'' at line 2 +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED BY 'plug_dest_passwd' + IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'' at line 2 +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest' +USER plug_dest IDENTIFIED by 'plug_dest_pwd'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'USER plug_dest IDENTIFIED by 'plug_dest_pwd'' at line 2 +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest' + USER plug_dest IDENTIFIED by 'plug_dest_pwd'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'USER plug_dest IDENTIFIED by 'plug_dest_pwd'' at line 2 +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest' +plug_dest IDENTIFIED by 'plug_dest_pwd'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'plug_dest IDENTIFIED by 'plug_dest_pwd'' at line 2 +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest' + plug_dest IDENTIFIED by 'plug_dest_pwd'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'plug_dest IDENTIFIED by 'plug_dest_pwd'' at line 2 +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest' +IDENTIFIED by 'plug_dest_pwd'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IDENTIFIED by 'plug_dest_pwd'' at line 2 +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest' + IDENTIFIED by 'plug_dest_pwd'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IDENTIFIED by 'plug_dest_pwd'' at line 2 +========== test 1.1 combinations ========================== +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +========== test 1.1.1.6/1.1.2.5 ============================ +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server plug_dest +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server plug_dest +plug_dest +DROP USER plug, plug_dest; +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server plug_dest +DROP USER plug; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug_dest +DROP USER plug_dest; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server plug_dest +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server plug_dest +plug_dest +DROP USER plug, plug_dest; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server plug_dest +DROP USER plug; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug_dest +DROP USER plug_dest; +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server plug_dest +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_dest IDENTIFIED BY 'plug_dest_passwd'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server plug_dest +plug_dest +DROP USER plug, plug_dest; +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server plug_dest +DROP USER plug; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_dest IDENTIFIED BY 'plug_dest_passwd'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug_dest +DROP USER plug_dest; +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +ERROR HY000: GRANT with IDENTIFIED WITH is illegal because the user plug already exists +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server'; +ERROR HY000: GRANT with IDENTIFIED WITH is illegal because the user plug already exists +DROP USER plug; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +ERROR HY000: Operation CREATE USER failed for 'plug'@'%' +CREATE USER plug IDENTIFIED WITH 'test_plugin_server'; +ERROR HY000: Operation CREATE USER failed for 'plug'@'%' +DROP USER plug; +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; +user plugin authentication_string password +plug test_plugin_server plug_dest +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED BY 'plug_dest_passwd'; +SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; +user plugin authentication_string password +plug test_plugin_server plug_dest *939AEE68989794C0F408277411C26055CDF41119 +DROP USER plug; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +CREATE USER plug IDENTIFIED BY 'plug_dest_passwd'; +ERROR HY000: Operation CREATE USER failed for 'plug'@'%' +DROP USER plug; +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +CREATE USER plug_dest IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; +user plugin authentication_string password +plug test_plugin_server plug_dest +plug_dest test_plugin_server plug_dest +DROP USER plug,plug_dest; +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; +user plugin authentication_string password +plug test_plugin_server plug_dest +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_dest +IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; +user plugin authentication_string password +plug test_plugin_server plug_dest +plug_dest test_plugin_server plug_dest +DROP USER plug,plug_dest; +========== test 1.1.1.1/1.1.2.1/1.1.1.5 ==================== +SET NAMES utf8; +CREATE USER plĂĽg IDENTIFIED WITH 'test_plugin_server' AS 'plĂĽg_dest'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plĂĽg test_plugin_server plĂĽg_dest +DROP USER plĂĽg; +CREATE USER plĂĽg_dest IDENTIFIED BY 'plug_dest_passwd'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plĂĽg_dest +DROP USER plĂĽg_dest; +SET NAMES ascii; +CREATE USER 'plĂĽg' IDENTIFIED WITH 'test_plugin_server' AS 'plĂĽg_dest'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +pl??g test_plugin_server pl??g_dest +DROP USER 'plĂĽg'; +CREATE USER 'plĂĽg_dest' IDENTIFIED BY 'plug_dest_passwd'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +pl??g_dest +DROP USER 'plĂĽg_dest'; +SET NAMES latin1; +========== test 1.1.1.5 ==================================== +CREATE USER 'plĂĽg' IDENTIFIED WITH 'test_plĂĽgin_server' AS 'plĂĽg_dest'; +ERROR HY000: Plugin 'test_plĂĽgin_server' is not loaded +CREATE USER 'plug' IDENTIFIED WITH 'test_plugin_server' AS 'plĂĽg_dest'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server plĂĽg_dest +DROP USER 'plug'; +CREATE USER 'plĂĽg_dest' IDENTIFIED BY 'plug_dest_passwd'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plĂĽg_dest +DROP USER 'plĂĽg_dest'; +SET NAMES utf8; +CREATE USER plĂĽg IDENTIFIED WITH 'test_plĂĽgin_server' AS 'plĂĽg_dest'; +ERROR HY000: Plugin 'test_plĂĽgin_server' is not loaded +CREATE USER 'plĂĽg' IDENTIFIED WITH 'test_plugin_server' AS 'plĂĽg_dest'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plĂĽg test_plugin_server plĂĽg_dest +DROP USER 'plĂĽg'; +CREATE USER 'plĂĽg_dest' IDENTIFIED BY 'plug_dest_passwd'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plĂĽg_dest +DROP USER 'plĂĽg_dest'; +CREATE USER plĂĽg IDENTIFIED WITH test_plugin_server AS 'plĂĽg_dest'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plĂĽg test_plugin_server plĂĽg_dest +DROP USER plĂĽg; +CREATE USER plĂĽg_dest IDENTIFIED BY 'plug_dest_passwd'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plĂĽg_dest +DROP USER plĂĽg_dest; +========== test 1.1.1.2/1.1.2.2============================= +SET @auth_name= 'test_plugin_server'; +CREATE USER plug IDENTIFIED WITH @auth_name AS 'plug_dest'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@auth_name AS 'plug_dest'' at line 1 +SET @auth_string= 'plug_dest'; +CREATE USER plug IDENTIFIED WITH test_plugin_server AS @auth_string; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@auth_string' at line 1 +========== test 1.1.1.3/1.1.2.3============================= +CREATE USER plug IDENTIFIED WITH 'hh''s_test_plugin_server' AS 'plug_dest'; +ERROR HY000: Plugin 'hh's_test_plugin_server' is not loaded +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'hh''s_plug_dest'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug test_plugin_server hh's_plug_dest +DROP USER plug; +CREATE USER 'hh''s_plug_dest' IDENTIFIED BY 'plug_dest_passwd'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +hh's_plug_dest +DROP USER 'hh''s_plug_dest'; +========== test 1.1.1.4 ==================================== +CREATE USER plug IDENTIFIED WITH hh''s_test_plugin_server AS 'plug_dest'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '''s_test_plugin_server AS 'plug_dest'' at line 1 +========== test 1.1.3.1 ==================================== +GRANT INSERT ON test_user_db.* TO grant_user IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +grant_user test_plugin_server plug_dest +CREATE USER plug_dest; +DROP USER plug_dest; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_dest; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +grant_user test_plugin_server plug_dest +plug_dest +DROP USER grant_user,plug_dest; +set @save_sql_mode= @@sql_mode; +SET @@sql_mode=no_auto_create_user; +GRANT INSERT ON test_user_db.* TO grant_user IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +grant_user test_plugin_server plug_dest +CREATE USER plug_dest; +DROP USER plug_dest; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_dest; +ERROR 42000: Can't find any matching row in the user table +DROP USER grant_user; +GRANT INSERT ON test_user_db.* TO grant_user IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +grant_user test_plugin_server plug_dest +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; +user plugin authentication_string password +grant_user test_plugin_server plug_dest +plug_dest *939AEE68989794C0F408277411C26055CDF41119 +DROP USER plug_dest; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_dest IDENTIFIED BY 'plug_user_passwd'; +SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; +user plugin authentication_string password +grant_user test_plugin_server plug_dest +plug_dest *560881EB651416CEF77314D07D55EDCD5FC1BD6D +DROP USER grant_user,plug_dest; +set @@sql_mode= @save_sql_mode; +DROP DATABASE test_user_db; diff --git a/mysql-test/r/plugin_auth_qa_1.result b/mysql-test/r/plugin_auth_qa_1.result new file mode 100644 index 00000000000..00ee47b56b3 --- /dev/null +++ b/mysql-test/r/plugin_auth_qa_1.result @@ -0,0 +1,335 @@ +CREATE DATABASE test_user_db; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +========== test 1.1.3.2 ==================================== +CREATE USER plug_user IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +GRANT PROXY ON plug_dest TO plug_user; +current_user() +plug_dest@% +user() +plug_user@localhost +Tables_in_test_user_db +t1 +REVOKE PROXY ON plug_dest FROM plug_user; +ERROR 1045 (28000): Access denied for user 'plug_user'@'localhost' (using password: YES) +DROP USER plug_user,plug_dest; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_user +IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_dest IDENTIFIED BY 'plug_dest_passwd'; +GRANT PROXY ON plug_dest TO plug_user; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug_dest +plug_user test_plugin_server plug_dest +1) +current_user() +plug_dest@% +user() +plug_user@localhost +Tables_in_test_user_db +t1 +REVOKE ALL PRIVILEGES ON test_user_db.* FROM 'plug_user' + IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +2) +current_user() +plug_dest@% +user() +plug_user@localhost +Tables_in_test_user_db +t1 +REVOKE PROXY ON plug_dest FROM plug_user; +3) +ERROR 1045 (28000): Access denied for user 'plug_user'@'localhost' (using password: YES) +DROP USER plug_user,plug_dest; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_user +IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +1) +ERROR 1045 (28000): Access denied for user 'plug_user'@'localhost' (using password: YES) +GRANT PROXY ON plug_dest TO plug_user; +2) +current_user() +plug_dest@% +user() +plug_user@localhost +Tables_in_test_user_db +t1 +REVOKE ALL PRIVILEGES ON test_user_db.* FROM 'plug_user' + IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +DROP USER plug_user,plug_dest; +========== test 1.2 ======================================== +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_user +IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +GRANT PROXY ON plug_dest TO plug_user; +current_user() +plug_dest@% +user() +plug_user@localhost +RENAME USER plug_dest TO new_dest; +ERROR 1045 (28000): Access denied for user 'plug_user'@'localhost' (using password: YES) +GRANT PROXY ON new_dest TO plug_user; +ERROR 1045 (28000): Access denied for user 'plug_user'@'localhost' (using password: YES) +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +new_dest +plug_user test_plugin_server plug_dest +DROP USER plug_user,new_dest; +CREATE USER plug_user +IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +ERROR 1045 (28000): Access denied for user 'plug_user'@'localhost' (using password: YES) +GRANT PROXY ON plug_dest TO plug_user; +current_user() +plug_dest@% +user() +plug_user@localhost +RENAME USER plug_dest TO new_dest; +ERROR 1045 (28000): Access denied for user 'plug_user'@'localhost' (using password: YES) +GRANT PROXY ON new_dest TO plug_user; +ERROR 1045 (28000): Access denied for user 'plug_user'@'localhost' (using password: YES) +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +new_dest +plug_user test_plugin_server plug_dest +DROP USER plug_user,new_dest; +CREATE USER plug_user +IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +GRANT PROXY ON plug_dest TO plug_user; +connect(plug_user,localhost,plug_user,plug_dest); +select USER(),CURRENT_USER(); +USER() CURRENT_USER() +plug_user@localhost plug_dest@% +connection default; +disconnect plug_user; +RENAME USER plug_user TO new_user; +connect(plug_user,localhost,new_user,plug_dest); +select USER(),CURRENT_USER(); +USER() CURRENT_USER() +new_user@localhost plug_dest@% +connection default; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +new_user test_plugin_server plug_dest +plug_dest +disconnect plug_user; +UPDATE mysql.user SET user='plug_user' WHERE user='new_user'; +FLUSH PRIVILEGES; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug_dest +plug_user test_plugin_server plug_dest +DROP USER plug_dest,plug_user; +========== test 1.3 ======================================== +CREATE USER plug_user +IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +GRANT PROXY ON plug_dest TO plug_user; +connect(plug_user,localhost,plug_user,plug_dest); +select USER(),CURRENT_USER(); +USER() CURRENT_USER() +plug_user@localhost plug_dest@% +connection default; +disconnect plug_user; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +plug_dest +plug_user test_plugin_server plug_dest +UPDATE mysql.user SET user='new_user' WHERE user='plug_user'; +FLUSH PRIVILEGES; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +new_user test_plugin_server plug_dest +plug_dest +UPDATE mysql.user SET authentication_string='new_dest' WHERE user='new_user'; +FLUSH PRIVILEGES; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +new_user test_plugin_server new_dest +plug_dest +UPDATE mysql.user SET plugin='new_plugin_server' WHERE user='new_user'; +FLUSH PRIVILEGES; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +new_user new_plugin_server new_dest +plug_dest +connect(plug_user,localhost,new_user,new_dest); +ERROR HY000: Plugin 'new_plugin_server' is not loaded +UPDATE mysql.user SET plugin='test_plugin_server' WHERE user='new_user'; +UPDATE mysql.user SET USER='new_dest' WHERE user='plug_dest'; +FLUSH PRIVILEGES; +GRANT PROXY ON new_dest TO new_user; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +new_dest +new_user test_plugin_server new_dest +connect(plug_user,localhost,new_user,new_dest); +select USER(),CURRENT_USER(); +USER() CURRENT_USER() +new_user@localhost new_dest@% +connection default; +disconnect plug_user; +UPDATE mysql.user SET USER='plug_dest' WHERE user='new_dest'; +FLUSH PRIVILEGES; +CREATE USER new_dest IDENTIFIED BY 'new_dest_passwd'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +new_dest +new_user test_plugin_server new_dest +plug_dest +GRANT ALL PRIVILEGES ON test.* TO new_user; +connect(plug_user,localhost,new_dest,new_dest_passwd); +select USER(),CURRENT_USER(); +USER() CURRENT_USER() +new_dest@localhost new_dest@% +connection default; +disconnect plug_user; +DROP USER new_user,new_dest,plug_dest; +========== test 2, 2.1, 2.2 ================================ +CREATE USER ''@'' IDENTIFIED WITH test_plugin_server AS 'proxied_user'; +CREATE USER proxied_user IDENTIFIED BY 'proxied_user_passwd'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string + test_plugin_server proxied_user +proxied_user +connect(proxy_con,localhost,proxied_user,proxied_user_passwd); +SELECT USER(),CURRENT_USER(); +USER() CURRENT_USER() +proxied_user@localhost proxied_user@% +========== test 2.2.1 ====================================== +SELECT @@proxy_user; +@@proxy_user +NULL +connection default; +disconnect proxy_con; +connect(proxy_con,localhost,proxy_user,proxied_user); +ERROR 28000: Access denied for user 'proxy_user'@'localhost' (using password: YES) +GRANT PROXY ON proxied_user TO ''@''; +connect(proxy_con,localhost,proxied_user,proxied_user_passwd); +SELECT USER(),CURRENT_USER(); +USER() CURRENT_USER() +proxied_user@localhost proxied_user@% +connection default; +disconnect proxy_con; +connect(proxy_con,localhost,proxy_user,proxied_user); +SELECT USER(),CURRENT_USER(); +USER() CURRENT_USER() +proxy_user@localhost proxied_user@% +========== test 2.2.1 ====================================== +SELECT @@proxy_user; +@@proxy_user +''@'' +connection default; +disconnect proxy_con; +DROP USER ''@'',proxied_user; +GRANT ALL PRIVILEGES ON test_user_db.* TO ''@'' +IDENTIFIED WITH test_plugin_server AS 'proxied_user'; +CREATE USER proxied_user IDENTIFIED BY 'proxied_user_passwd'; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string + test_plugin_server proxied_user +proxied_user +connect(proxy_con,localhost,proxied_user,proxied_user_passwd); +SELECT USER(),CURRENT_USER(); +USER() CURRENT_USER() +proxied_user@localhost proxied_user@% +SELECT @@proxy_user; +@@proxy_user +NULL +connection default; +disconnect proxy_con; +connect(proxy_con,localhost,proxy_user,proxied_user); +ERROR 28000: Access denied for user 'proxy_user'@'localhost' (using password: YES) +GRANT PROXY ON proxied_user TO ''@''; +connect(proxy_con,localhost,proxied_user,proxied_user_passwd); +SELECT USER(),CURRENT_USER(); +USER() CURRENT_USER() +proxied_user@localhost proxied_user@% +connection default; +disconnect proxy_con; +connect(proxy_con,localhost,proxy_user,proxied_user); +SELECT USER(),CURRENT_USER(); +USER() CURRENT_USER() +proxy_user@localhost proxied_user@% +SELECT @@proxy_user; +@@proxy_user +''@'' +connection default; +disconnect proxy_con; +DROP USER ''@'',proxied_user; +CREATE USER ''@'' IDENTIFIED WITH test_plugin_server AS 'proxied_user'; +CREATE USER proxied_user_1 IDENTIFIED BY 'proxied_user_1_pwd'; +CREATE USER proxied_user_2 IDENTIFIED BY 'proxied_user_2_pwd'; +CREATE USER proxied_user_3 IDENTIFIED BY 'proxied_user_3_pwd'; +CREATE USER proxied_user_4 IDENTIFIED BY 'proxied_user_4_pwd'; +CREATE USER proxied_user_5 IDENTIFIED BY 'proxied_user_5_pwd'; +GRANT PROXY ON proxied_user_1 TO ''@''; +GRANT PROXY ON proxied_user_2 TO ''@''; +GRANT PROXY ON proxied_user_3 TO ''@''; +GRANT PROXY ON proxied_user_4 TO ''@''; +GRANT PROXY ON proxied_user_5 TO ''@''; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string + test_plugin_server proxied_user +proxied_user_1 +proxied_user_2 +proxied_user_3 +proxied_user_4 +proxied_user_5 +connect(proxy_con_1,localhost,proxied_user_1,'proxied_user_1_pwd'); +connect(proxy_con_2,localhost,proxied_user_2,proxied_user_2_pwd); +connect(proxy_con_3,localhost,proxied_user_3,proxied_user_3_pwd); +connect(proxy_con_4,localhost,proxied_user_4,proxied_user_4_pwd); +connect(proxy_con_5,localhost,proxied_user_5,proxied_user_5_pwd); +connection proxy_con_1; +SELECT USER(),CURRENT_USER(); +USER() CURRENT_USER() +proxied_user_1@localhost proxied_user_1@% +SELECT @@proxy_user; +@@proxy_user +NULL +connection proxy_con_2; +SELECT USER(),CURRENT_USER(); +USER() CURRENT_USER() +proxied_user_2@localhost proxied_user_2@% +SELECT @@proxy_user; +@@proxy_user +NULL +connection proxy_con_3; +SELECT USER(),CURRENT_USER(); +USER() CURRENT_USER() +proxied_user_3@localhost proxied_user_3@% +SELECT @@proxy_user; +@@proxy_user +NULL +connection proxy_con_4; +SELECT USER(),CURRENT_USER(); +USER() CURRENT_USER() +proxied_user_4@localhost proxied_user_4@% +SELECT @@proxy_user; +@@proxy_user +NULL +connection proxy_con_5; +SELECT USER(),CURRENT_USER(); +USER() CURRENT_USER() +proxied_user_5@localhost proxied_user_5@% +SELECT @@proxy_user; +@@proxy_user +NULL +connection default; +disconnect proxy_con_1; +disconnect proxy_con_2; +disconnect proxy_con_3; +disconnect proxy_con_4; +disconnect proxy_con_5; +DROP USER ''@'',proxied_user_1,proxied_user_2,proxied_user_3,proxied_user_4,proxied_user_5; +========== test 3 ========================================== +GRANT ALL PRIVILEGES ON *.* TO plug_user +IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +GRANT PROXY ON plug_dest TO plug_user; +FLUSH PRIVILEGES; +DROP USER plug_user, plug_dest; +DROP DATABASE test_user_db; diff --git a/mysql-test/r/plugin_auth_qa_2.result b/mysql-test/r/plugin_auth_qa_2.result new file mode 100644 index 00000000000..a73cc25418c --- /dev/null +++ b/mysql-test/r/plugin_auth_qa_2.result @@ -0,0 +1,146 @@ +CREATE DATABASE test_user_db; +========== test 1.1.3.2 ==================================== +=== check contens of components of info ==================== +CREATE USER qa_test_1_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_1_dest'; +CREATE USER qa_test_1_dest IDENTIFIED BY 'dest_passwd'; +GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_1_dest identified by 'dest_passwd'; +GRANT PROXY ON qa_test_1_dest TO qa_test_1_user; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +qa_test_1_dest +qa_test_1_user qa_auth_interface qa_test_1_dest +SELECT @@proxy_user; +@@proxy_user +NULL +SELECT @@external_user; +@@external_user +NULL +exec MYSQL PLUGIN_AUTH_OPT -h localhost -P 13000 -u qa_test_1_user --password=qa_test_1_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +current_user() user() @@local.proxy_user @@local.external_user +qa_test_1_user@% qa_test_1_user@localhost NULL NULL +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +qa_test_1_dest +qa_test_1_user qa_auth_interface qa_test_1_dest +DROP USER qa_test_1_user; +DROP USER qa_test_1_dest; +=== Assign values to components of info ==================== +CREATE USER qa_test_2_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_2_dest'; +CREATE USER qa_test_2_dest IDENTIFIED BY 'dest_passwd'; +CREATE USER authenticated_as IDENTIFIED BY 'dest_passwd'; +GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_2_dest identified by 'dest_passwd'; +GRANT PROXY ON qa_test_2_dest TO qa_test_2_user; +GRANT PROXY ON authenticated_as TO qa_test_2_user; +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +authenticated_as +qa_test_2_dest +qa_test_2_user qa_auth_interface qa_test_2_dest +SELECT @@proxy_user; +@@proxy_user +NULL +SELECT @@external_user; +@@external_user +NULL +exec MYSQL PLUGIN_AUTH_OPT -h localhost -P 13000 -u qa_test_2_user --password=qa_test_2_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +current_user() user() @@local.proxy_user @@local.external_user +authenticated_as@% user_name@localhost 'qa_test_2_user'@'%' 'qa_test_2_user'@'%' +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +user plugin authentication_string +authenticated_as +qa_test_2_dest +qa_test_2_user qa_auth_interface qa_test_2_dest +DROP USER qa_test_2_user; +DROP USER qa_test_2_dest; +DROP USER authenticated_as; +=== Assign too high values for *length, which should have no effect ==== +CREATE USER qa_test_3_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_3_dest'; +CREATE USER qa_test_3_dest IDENTIFIED BY 'dest_passwd'; +GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_3_dest identified by 'dest_passwd'; +GRANT PROXY ON qa_test_3_dest TO qa_test_3_user; +exec MYSQL PLUGIN_AUTH_OPT -h localhost -P 13000 -u qa_test_3_user --password=qa_test_3_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +current_user() user() @@local.proxy_user @@local.external_user +qa_test_3_dest@% qa_test_3_user@localhost 'qa_test_3_user'@'%' 'qa_test_3_user'@'%' +DROP USER qa_test_3_user; +DROP USER qa_test_3_dest; +=== Assign too low values for *length, which should have no effect ==== +CREATE USER qa_test_4_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_4_dest'; +CREATE USER qa_test_4_dest IDENTIFIED BY 'dest_passwd'; +GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_4_dest identified by 'dest_passwd'; +GRANT PROXY ON qa_test_4_dest TO qa_test_4_user; +exec MYSQL PLUGIN_AUTH_OPT -h localhost -P 13000 -u qa_test_4_user --password=qa_test_4_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +current_user() user() @@local.proxy_user @@local.external_user +qa_test_4_dest@% qa_test_4_user@localhost 'qa_test_4_user'@'%' 'qa_test_4_user'@'%' +DROP USER qa_test_4_user; +DROP USER qa_test_4_dest; +=== Assign empty string especially to authenticated_as (in plugin) ==== +CREATE USER qa_test_5_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_5_dest'; +CREATE USER qa_test_5_dest IDENTIFIED BY 'dest_passwd'; +CREATE USER ''@'localhost' IDENTIFIED BY 'dest_passwd'; +GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_5_dest identified by 'dest_passwd'; +GRANT ALL PRIVILEGES ON test_user_db.* TO ''@'localhost' identified by 'dest_passwd'; +GRANT PROXY ON qa_test_5_dest TO qa_test_5_user; +GRANT PROXY ON qa_test_5_dest TO ''@'localhost'; +SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; +user plugin authentication_string password + *DFCACE76914AD7BD801FC1A1ECF6562272621A22 +qa_test_5_user qa_auth_interface qa_test_5_dest +qa_test_5_dest *DFCACE76914AD7BD801FC1A1ECF6562272621A22 +exec MYSQL PLUGIN_AUTH_OPT -h localhost -P 13000 --user=qa_test_5_user --password=qa_test_5_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +ERROR 1045 (28000): Access denied for user 'qa_test_5_user'@'localhost' (using password: YES) +DROP USER qa_test_5_user; +DROP USER qa_test_5_dest; +DROP USER ''@'localhost'; +=== Assign 'root' especially to authenticated_as (in plugin) ==== +CREATE USER qa_test_6_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_6_dest'; +CREATE USER qa_test_6_dest IDENTIFIED BY 'dest_passwd'; +GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_6_dest identified by 'dest_passwd'; +GRANT PROXY ON qa_test_6_dest TO qa_test_6_user; +SELECT user,plugin,authentication_string,password FROM mysql.user; +user plugin authentication_string password +root +root +root +qa_test_6_user qa_auth_interface qa_test_6_dest +qa_test_6_dest *DFCACE76914AD7BD801FC1A1ECF6562272621A22 +exec MYSQL PLUGIN_AUTH_OPT -h localhost -P 13000 --user=qa_test_6_user --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +ERROR 1045 (28000): Access denied for user 'qa_test_6_user'@'localhost' (using password: YES) +GRANT PROXY ON qa_test_6_dest TO root IDENTIFIED WITH qa_auth_interface AS 'qa_test_6_dest'; +SELECT user,plugin,authentication_string,password FROM mysql.user; +user plugin authentication_string password +root +root +root +qa_test_6_user qa_auth_interface qa_test_6_dest +qa_test_6_dest *DFCACE76914AD7BD801FC1A1ECF6562272621A22 +root qa_auth_interface qa_test_6_dest +exec MYSQL PLUGIN_AUTH_OPT -h localhost -P 13000 --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) +REVOKE PROXY ON qa_test_6_dest FROM root; +SELECT user,plugin,authentication_string FROM mysql.user; +user plugin authentication_string +root +root +root +qa_test_6_user qa_auth_interface qa_test_6_dest +qa_test_6_dest +root qa_auth_interface qa_test_6_dest +exec MYSQL PLUGIN_AUTH_OPT -h localhost -P 13000 --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) +DROP USER qa_test_6_user; +DROP USER qa_test_6_dest; +DELETE FROM mysql.user WHERE user='root' AND plugin='qa_auth_interface'; +SELECT user,plugin,authentication_string,password FROM mysql.user; +user plugin authentication_string password +root +root +root +=== Test of the --default_auth option for clients ==== +CREATE USER qa_test_11_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_11_dest'; +CREATE USER qa_test_11_dest IDENTIFIED BY 'dest_passwd'; +GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_11_dest identified by 'dest_passwd'; +GRANT PROXY ON qa_test_11_dest TO qa_test_11_user; +exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P 13000 -u qa_test_11_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +ERROR 1045 (28000): Access denied for user 'qa_test_11_user'@'localhost' (using password: YES) +DROP USER qa_test_11_user, qa_test_11_dest; +DROP DATABASE test_user_db; diff --git a/mysql-test/r/plugin_auth_qa_3.result b/mysql-test/r/plugin_auth_qa_3.result new file mode 100644 index 00000000000..92d47bcf580 --- /dev/null +++ b/mysql-test/r/plugin_auth_qa_3.result @@ -0,0 +1,11 @@ +CREATE DATABASE test_user_db; +CREATE USER qa_test_11_user IDENTIFIED WITH qa_auth_server AS 'qa_test_11_dest'; +GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_11_dest identified by 'dest_passwd'; +GRANT PROXY ON qa_test_11_dest TO qa_test_11_user; +exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P 13000 -u qa_test_11_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +current_user() user() @@local.proxy_user @@local.external_user +qa_test_11_dest@% qa_test_11_user@localhost 'qa_test_11_user'@'%' 'qa_test_11_user'@'%' +exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P 13000 -u qa_test_2_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +ERROR 1045 (28000): Access denied for user 'qa_test_2_user'@'localhost' (using password: NO) +DROP USER qa_test_11_user, qa_test_11_dest; +DROP DATABASE test_user_db; diff --git a/mysql-test/t/plugin_auth_qa-master.opt b/mysql-test/t/plugin_auth_qa-master.opt new file mode 100644 index 00000000000..3536d102387 --- /dev/null +++ b/mysql-test/t/plugin_auth_qa-master.opt @@ -0,0 +1,2 @@ +$PLUGIN_AUTH_OPT +$PLUGIN_AUTH_LOAD diff --git a/mysql-test/t/plugin_auth_qa.test b/mysql-test/t/plugin_auth_qa.test new file mode 100644 index 00000000000..0961c1dfef5 --- /dev/null +++ b/mysql-test/t/plugin_auth_qa.test @@ -0,0 +1,338 @@ +# The numbers represent test cases of the test plan. + +--source include/have_plugin_auth.inc +--source include/not_embedded.inc + +CREATE DATABASE test_user_db; + +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +--echo ========== test 1.1 ====================================================== +# without '', without AS part +CREATE USER plug IDENTIFIED WITH test_plugin_server; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plug; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH test_plugin_server; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +REVOKE ALL PRIVILEGES ON test_user_db.* FROM plug; +DROP USER plug; +# with '', without AS part +CREATE USER plug IDENTIFIED WITH 'test_plugin_server'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plug; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +REVOKE ALL PRIVILEGES ON test_user_db.* FROM plug; +DROP USER plug; +# without '', AS part empty +CREATE USER plug IDENTIFIED WITH test_plugin_server AS ''; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plug; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH test_plugin_server AS ''; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +REVOKE ALL PRIVILEGES ON test_user_db.* FROM plug; +DROP USER plug; +# with '', AS part empty without '' +--error ER_PARSE_ERROR +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS ; +--error ER_PARSE_ERROR +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server' AS; +# without '', AS part without '' +--error ER_PARSE_ERROR +CREATE USER plug IDENTIFIED WITH test_plugin_server AS plug_dest; +--error ER_PARSE_ERROR +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH test_plugin_server AS plug_dest; +--echo ========== test 1.1 syntax errors ======================================== +# without auth_name +--error ER_PARSE_ERROR +CREATE USER plug IDENTIFIED WITH AS plug_dest; +--error ER_PARSE_ERROR +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH AS plug_dest; +# without auth_name and AS part +--error ER_PARSE_ERROR +CREATE USER plug IDENTIFIED WITH; +--error ER_PARSE_ERROR +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH; +# without auth_name but AS part +--error ER_PARSE_ERROR +CREATE USER plug IDENTIFIED AS ''; +--error ER_PARSE_ERROR +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED AS ''; +# with 2 auth_name parts +--error ER_PARSE_ERROR +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' IDENTIFIED WITH 'test_plugin_server'; +--error ER_PARSE_ERROR +GRANT ALL PRIVILEGES ON test_user_db.* TO plug + IDENTIFIED WITH 'test_plugin_server' IDENTIFIED WITH 'test_plugin_server'; +# with 2 AS parts +--error ER_PARSE_ERROR +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS '' AS 'plug_dest'; +--error ER_PARSE_ERROR +GRANT ALL PRIVILEGES ON test_user_db.* TO plug AS '' AS 'plug_dest'; +# with 2 complete WITH parts +--error ER_PARSE_ERROR +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS '' + IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +--error ER_PARSE_ERROR +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server' AS '' + IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +# with BY and WITH part +--error ER_PARSE_ERROR +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd' + IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +--error ER_PARSE_ERROR +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED BY 'plug_dest_passwd' + IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +# with WITH part and BY part +--error ER_PARSE_ERROR +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest' + USER plug_dest IDENTIFIED by 'plug_dest_pwd'; +--error ER_PARSE_ERROR +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest' + USER plug_dest IDENTIFIED by 'plug_dest_pwd'; +# with WITH part and BY part +--error ER_PARSE_ERROR +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest' + plug_dest IDENTIFIED by 'plug_dest_pwd'; +--error ER_PARSE_ERROR +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest' + plug_dest IDENTIFIED by 'plug_dest_pwd'; +# with WITH part and BY part +--error ER_PARSE_ERROR +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest' + IDENTIFIED by 'plug_dest_pwd'; +--error ER_PARSE_ERROR +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest' + IDENTIFIED by 'plug_dest_pwd'; + +--echo ========== test 1.1 combinations ========================== +# CREATE...WITH/CREATE...BY +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +--echo ========== test 1.1.1.6/1.1.2.5 ============================ +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plug, plug_dest; +# +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plug; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plug_dest; +# GRANT...WITH/CREATE...BY +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plug, plug_dest; +# +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plug; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plug_dest; +# CREATE...WITH/GRANT...BY +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_dest IDENTIFIED BY 'plug_dest_passwd'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plug, plug_dest; +# +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plug; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_dest IDENTIFIED BY 'plug_dest_passwd'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plug_dest; +# +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +--error 1700 +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +--error 1700 +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH 'test_plugin_server'; +DROP USER plug; +# +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +--error ER_CANNOT_USER +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +--error ER_CANNOT_USER +CREATE USER plug IDENTIFIED WITH 'test_plugin_server'; +DROP USER plug; +# +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +--sorted_result +SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED BY 'plug_dest_passwd'; +--sorted_result +SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; +DROP USER plug; +# +GRANT ALL PRIVILEGES ON test_user_db.* TO plug IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +--error ER_CANNOT_USER +CREATE USER plug IDENTIFIED BY 'plug_dest_passwd'; +DROP USER plug; +# +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +CREATE USER plug_dest IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +--sorted_result +SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; +DROP USER plug,plug_dest; +# +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest'; +--sorted_result +SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_dest + IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +--sorted_result +SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; +DROP USER plug,plug_dest; +# + +--echo ========== test 1.1.1.1/1.1.2.1/1.1.1.5 ==================== + +SET NAMES utf8; +# +CREATE USER plĂĽg IDENTIFIED WITH 'test_plugin_server' AS 'plĂĽg_dest'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plĂĽg; +CREATE USER plĂĽg_dest IDENTIFIED BY 'plug_dest_passwd'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plĂĽg_dest; + +SET NAMES ascii; +# +CREATE USER 'plĂĽg' IDENTIFIED WITH 'test_plugin_server' AS 'plĂĽg_dest'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER 'plĂĽg'; +CREATE USER 'plĂĽg_dest' IDENTIFIED BY 'plug_dest_passwd'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER 'plĂĽg_dest'; + +SET NAMES latin1; +# +--echo ========== test 1.1.1.5 ==================================== +--error ER_PLUGIN_IS_NOT_LOADED +CREATE USER 'plĂĽg' IDENTIFIED WITH 'test_plĂĽgin_server' AS 'plĂĽg_dest'; +CREATE USER 'plug' IDENTIFIED WITH 'test_plugin_server' AS 'plĂĽg_dest'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER 'plug'; +CREATE USER 'plĂĽg_dest' IDENTIFIED BY 'plug_dest_passwd'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER 'plĂĽg_dest'; + +SET NAMES utf8; +# +--error ER_PLUGIN_IS_NOT_LOADED +CREATE USER plĂĽg IDENTIFIED WITH 'test_plĂĽgin_server' AS 'plĂĽg_dest'; +CREATE USER 'plĂĽg' IDENTIFIED WITH 'test_plugin_server' AS 'plĂĽg_dest'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER 'plĂĽg'; +CREATE USER 'plĂĽg_dest' IDENTIFIED BY 'plug_dest_passwd'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER 'plĂĽg_dest'; + +CREATE USER plĂĽg IDENTIFIED WITH test_plugin_server AS 'plĂĽg_dest'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plĂĽg; +CREATE USER plĂĽg_dest IDENTIFIED BY 'plug_dest_passwd'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plĂĽg_dest; + +--echo ========== test 1.1.1.2/1.1.2.2============================= + +SET @auth_name= 'test_plugin_server'; +--error ER_PARSE_ERROR +CREATE USER plug IDENTIFIED WITH @auth_name AS 'plug_dest'; + +SET @auth_string= 'plug_dest'; +--error ER_PARSE_ERROR +CREATE USER plug IDENTIFIED WITH test_plugin_server AS @auth_string; + +--echo ========== test 1.1.1.3/1.1.2.3============================= + +--error ER_PLUGIN_IS_NOT_LOADED +CREATE USER plug IDENTIFIED WITH 'hh''s_test_plugin_server' AS 'plug_dest'; + +CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'hh''s_plug_dest'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plug; +CREATE USER 'hh''s_plug_dest' IDENTIFIED BY 'plug_dest_passwd'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER 'hh''s_plug_dest'; + +--echo ========== test 1.1.1.4 ==================================== + +--error ER_PARSE_ERROR +CREATE USER plug IDENTIFIED WITH hh''s_test_plugin_server AS 'plug_dest'; + +--echo ========== test 1.1.3.1 ==================================== + +GRANT INSERT ON test_user_db.* TO grant_user IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +CREATE USER plug_dest; +DROP USER plug_dest; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_dest; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER grant_user,plug_dest; +# +set @save_sql_mode= @@sql_mode; +SET @@sql_mode=no_auto_create_user; +GRANT INSERT ON test_user_db.* TO grant_user IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +CREATE USER plug_dest; +DROP USER plug_dest; +--error ER_PASSWORD_NO_MATCH +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_dest; +DROP USER grant_user; +# +GRANT INSERT ON test_user_db.* TO grant_user IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +--sorted_result +SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; +DROP USER plug_dest; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_dest IDENTIFIED BY 'plug_user_passwd'; +--sorted_result +SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; +DROP USER grant_user,plug_dest; +set @@sql_mode= @save_sql_mode; +# +DROP DATABASE test_user_db; +--exit + diff --git a/mysql-test/t/plugin_auth_qa_1-master.opt b/mysql-test/t/plugin_auth_qa_1-master.opt new file mode 100644 index 00000000000..3536d102387 --- /dev/null +++ b/mysql-test/t/plugin_auth_qa_1-master.opt @@ -0,0 +1,2 @@ +$PLUGIN_AUTH_OPT +$PLUGIN_AUTH_LOAD diff --git a/mysql-test/t/plugin_auth_qa_1.test b/mysql-test/t/plugin_auth_qa_1.test new file mode 100644 index 00000000000..d7a7afe9407 --- /dev/null +++ b/mysql-test/t/plugin_auth_qa_1.test @@ -0,0 +1,334 @@ +# The numbers represent test cases of the test plan. + +--source include/have_plugin_auth.inc +--source include/not_embedded.inc + +CREATE DATABASE test_user_db; + +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; + +--echo ========== test 1.1.3.2 ==================================== + +# CREATE...WITH/CREATE...BY/GRANT +CREATE USER plug_user IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +GRANT PROXY ON plug_dest TO plug_user; +--exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 +REVOKE PROXY ON plug_dest FROM plug_user; +--error 1 +--exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 +DROP USER plug_user,plug_dest; +# +# GRANT...WITH +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_user + IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_dest IDENTIFIED BY 'plug_dest_passwd'; +GRANT PROXY ON plug_dest TO plug_user; + +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +--echo 1) +--exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 +REVOKE ALL PRIVILEGES ON test_user_db.* FROM 'plug_user' + IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +--echo 2) +--exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 +REVOKE PROXY ON plug_dest FROM plug_user; +--echo 3) +--error 1 +--exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 +DROP USER plug_user,plug_dest; +# +# GRANT...WITH/CREATE...BY +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_user + IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +--echo 1) +--error 1 +--exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 +GRANT PROXY ON plug_dest TO plug_user; +--echo 2) +--exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 +REVOKE ALL PRIVILEGES ON test_user_db.* FROM 'plug_user' + IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +#REVOKE ALL PRIVILEGES ON test_user_db.* FROM 'plug_dest' +# IDENTIFIED BY 'plug_dest_passwd'; +DROP USER plug_user,plug_dest; + +--echo ========== test 1.2 ======================================== + +# GRANT...WITH/CREATE...BY +GRANT ALL PRIVILEGES ON test_user_db.* TO plug_user + IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +GRANT PROXY ON plug_dest TO plug_user; +--exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 +RENAME USER plug_dest TO new_dest; +--error 1 +--exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 +GRANT PROXY ON new_dest TO plug_user; +--error 1 +--exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=new_dest -e "SELECT current_user();SELECT user();" 2>&1 +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plug_user,new_dest; + +# CREATE...WITH/CREATE...BY +CREATE USER plug_user + IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +--error 1 +--exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 +GRANT PROXY ON plug_dest TO plug_user; +--exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 +RENAME USER plug_dest TO new_dest; +--error 1 +--exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 +GRANT PROXY ON new_dest TO plug_user; +--error 1 +--exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=new_dest -e "SELECT current_user();SELECT user();" 2>&1 +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plug_user,new_dest; +# CREATE...WITH +CREATE USER plug_user + IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +GRANT PROXY ON plug_dest TO plug_user; +--echo connect(plug_user,localhost,plug_user,plug_dest); +connect(plug_user,localhost,plug_user,plug_dest); +select USER(),CURRENT_USER(); +--echo connection default; +connection default; +--echo disconnect plug_user; +disconnect plug_user; +RENAME USER plug_user TO new_user; +--echo connect(plug_user,localhost,new_user,plug_dest); +connect(plug_user,localhost,new_user,plug_dest); +select USER(),CURRENT_USER(); +--echo connection default; +connection default; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +--echo disconnect plug_user; +disconnect plug_user; +UPDATE mysql.user SET user='plug_user' WHERE user='new_user'; +FLUSH PRIVILEGES; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +DROP USER plug_dest,plug_user; +--echo ========== test 1.3 ======================================== + +# +CREATE USER plug_user + IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +GRANT PROXY ON plug_dest TO plug_user; +--echo connect(plug_user,localhost,plug_user,plug_dest); +connect(plug_user,localhost,plug_user,plug_dest); +select USER(),CURRENT_USER(); +--echo connection default; +connection default; +--echo disconnect plug_user; +disconnect plug_user; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +UPDATE mysql.user SET user='new_user' WHERE user='plug_user'; +FLUSH PRIVILEGES; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +UPDATE mysql.user SET authentication_string='new_dest' WHERE user='new_user'; +FLUSH PRIVILEGES; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +UPDATE mysql.user SET plugin='new_plugin_server' WHERE user='new_user'; +FLUSH PRIVILEGES; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +--echo connect(plug_user,localhost,new_user,new_dest); +--disable_query_log +--error ER_PLUGIN_IS_NOT_LOADED +connect(plug_user,localhost,new_user,new_dest); +--enable_query_log +UPDATE mysql.user SET plugin='test_plugin_server' WHERE user='new_user'; +UPDATE mysql.user SET USER='new_dest' WHERE user='plug_dest'; +FLUSH PRIVILEGES; +GRANT PROXY ON new_dest TO new_user; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +--echo connect(plug_user,localhost,new_user,new_dest); +connect(plug_user,localhost,new_user,new_dest); +select USER(),CURRENT_USER(); +--echo connection default; +connection default; +--echo disconnect plug_user; +disconnect plug_user; +UPDATE mysql.user SET USER='plug_dest' WHERE user='new_dest'; +FLUSH PRIVILEGES; +CREATE USER new_dest IDENTIFIED BY 'new_dest_passwd'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +GRANT ALL PRIVILEGES ON test.* TO new_user; +--echo connect(plug_user,localhost,new_dest,new_dest_passwd); +connect(plug_user,localhost,new_dest,new_dest_passwd); +select USER(),CURRENT_USER(); +--echo connection default; +connection default; +--echo disconnect plug_user; +disconnect plug_user; +DROP USER new_user,new_dest,plug_dest; + +--echo ========== test 2, 2.1, 2.2 ================================ + +CREATE USER ''@'' IDENTIFIED WITH test_plugin_server AS 'proxied_user'; +CREATE USER proxied_user IDENTIFIED BY 'proxied_user_passwd'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +--echo connect(proxy_con,localhost,proxied_user,proxied_user_passwd); +connect(proxy_con,localhost,proxied_user,proxied_user_passwd); +SELECT USER(),CURRENT_USER(); +--echo ========== test 2.2.1 ====================================== +SELECT @@proxy_user; +--echo connection default; +connection default; +--echo disconnect proxy_con; +disconnect proxy_con; +--echo connect(proxy_con,localhost,proxy_user,proxied_user); +--disable_query_log +--error ER_ACCESS_DENIED_ERROR : this should fail : no grant +connect(proxy_con,localhost,proxy_user,proxied_user); +--enable_query_log +GRANT PROXY ON proxied_user TO ''@''; +--echo connect(proxy_con,localhost,proxied_user,proxied_user_passwd); +connect(proxy_con,localhost,proxied_user,proxied_user_passwd); +SELECT USER(),CURRENT_USER(); +--echo connection default; +connection default; +--echo disconnect proxy_con; +disconnect proxy_con; +--echo connect(proxy_con,localhost,proxy_user,proxied_user); +connect(proxy_con,localhost,proxy_user,proxied_user); +SELECT USER(),CURRENT_USER(); +--echo ========== test 2.2.1 ====================================== +SELECT @@proxy_user; +--echo connection default; +connection default; +--echo disconnect proxy_con; +disconnect proxy_con; +DROP USER ''@'',proxied_user; +# +GRANT ALL PRIVILEGES ON test_user_db.* TO ''@'' + IDENTIFIED WITH test_plugin_server AS 'proxied_user'; +CREATE USER proxied_user IDENTIFIED BY 'proxied_user_passwd'; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +--echo connect(proxy_con,localhost,proxied_user,proxied_user_passwd); +connect(proxy_con,localhost,proxied_user,proxied_user_passwd); +SELECT USER(),CURRENT_USER(); +SELECT @@proxy_user; +--echo connection default; +connection default; +--echo disconnect proxy_con; +disconnect proxy_con; +--echo connect(proxy_con,localhost,proxy_user,proxied_user); +--disable_query_log +--error ER_ACCESS_DENIED_ERROR : this should fail : no grant +connect(proxy_con,localhost,proxy_user,proxied_user); +--enable_query_log +GRANT PROXY ON proxied_user TO ''@''; +--echo connect(proxy_con,localhost,proxied_user,proxied_user_passwd); +connect(proxy_con,localhost,proxied_user,proxied_user_passwd); +SELECT USER(),CURRENT_USER(); +--echo connection default; +connection default; +--echo disconnect proxy_con; +disconnect proxy_con; +--echo connect(proxy_con,localhost,proxy_user,proxied_user); +connect(proxy_con,localhost,proxy_user,proxied_user); +SELECT USER(),CURRENT_USER(); +SELECT @@proxy_user; +--echo connection default; +connection default; +--echo disconnect proxy_con; +disconnect proxy_con; +DROP USER ''@'',proxied_user; +# +CREATE USER ''@'' IDENTIFIED WITH test_plugin_server AS 'proxied_user'; +CREATE USER proxied_user_1 IDENTIFIED BY 'proxied_user_1_pwd'; +CREATE USER proxied_user_2 IDENTIFIED BY 'proxied_user_2_pwd'; +CREATE USER proxied_user_3 IDENTIFIED BY 'proxied_user_3_pwd'; +CREATE USER proxied_user_4 IDENTIFIED BY 'proxied_user_4_pwd'; +CREATE USER proxied_user_5 IDENTIFIED BY 'proxied_user_5_pwd'; +GRANT PROXY ON proxied_user_1 TO ''@''; +GRANT PROXY ON proxied_user_2 TO ''@''; +GRANT PROXY ON proxied_user_3 TO ''@''; +GRANT PROXY ON proxied_user_4 TO ''@''; +GRANT PROXY ON proxied_user_5 TO ''@''; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +--echo connect(proxy_con_1,localhost,proxied_user_1,'proxied_user_1_pwd'); +connect(proxy_con_1,localhost,proxied_user_1,'proxied_user_1_pwd'); +--echo connect(proxy_con_2,localhost,proxied_user_2,proxied_user_2_pwd); +connect(proxy_con_2,localhost,proxied_user_2,proxied_user_2_pwd); +--echo connect(proxy_con_3,localhost,proxied_user_3,proxied_user_3_pwd); +connect(proxy_con_3,localhost,proxied_user_3,proxied_user_3_pwd); +--echo connect(proxy_con_4,localhost,proxied_user_4,proxied_user_4_pwd); +connect(proxy_con_4,localhost,proxied_user_4,proxied_user_4_pwd); +--echo connect(proxy_con_5,localhost,proxied_user_5,proxied_user_5_pwd); +connect(proxy_con_5,localhost,proxied_user_5,proxied_user_5_pwd); +--echo connection proxy_con_1; +connection proxy_con_1; +SELECT USER(),CURRENT_USER(); +SELECT @@proxy_user; +--echo connection proxy_con_2; +connection proxy_con_2; +SELECT USER(),CURRENT_USER(); +SELECT @@proxy_user; +--echo connection proxy_con_3; +connection proxy_con_3; +SELECT USER(),CURRENT_USER(); +SELECT @@proxy_user; +--echo connection proxy_con_4; +connection proxy_con_4; +SELECT USER(),CURRENT_USER(); +SELECT @@proxy_user; +--echo connection proxy_con_5; +connection proxy_con_5; +SELECT USER(),CURRENT_USER(); +SELECT @@proxy_user; +--echo connection default; +connection default; +--echo disconnect proxy_con_1; +disconnect proxy_con_1; +--echo disconnect proxy_con_2; +disconnect proxy_con_2; +--echo disconnect proxy_con_3; +disconnect proxy_con_3; +--echo disconnect proxy_con_4; +disconnect proxy_con_4; +--echo disconnect proxy_con_5; +disconnect proxy_con_5; +DROP USER ''@'',proxied_user_1,proxied_user_2,proxied_user_3,proxied_user_4,proxied_user_5; + +--echo ========== test 3 ========================================== + +GRANT ALL PRIVILEGES ON *.* TO plug_user + IDENTIFIED WITH test_plugin_server AS 'plug_dest'; +CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; +GRANT PROXY ON plug_dest TO plug_user; +FLUSH PRIVILEGES; + +# Not working with the patch. + +#--replace_result $MYSQLADMIN MYSQLADMIN $MASTER_MYPORT MYPORT $MASTER_MYSOCK MYSOCK +#--exec $MYSQLADMIN $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -S $MASTER_MYSOCK -u plug_user --password=plug_dest ping 2>&1 +#--replace_result $MYSQL_CHECK MYSQL_CHECK $MASTER_MYPORT MYPORT +#--exec $MYSQL_CHECK $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u plug_user --password=plug_dest test +#--replace_result $MYSQL_DUMP MYSQL_DUMP $MASTER_MYPORT MYPORT +#--exec $MYSQL_DUMP -h localhost -P $MASTER_MYPORT $PLUGIN_AUTH_OPT -u plug_user --password=plug_dest test +#--replace_result $MYSQL_SHOW MYSQL_SHOW $MASTER_MYPORT MYPORT +#--exec $MYSQL_SHOW $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --plugin_dir=../plugin/auth -u plug_user --password=plug_dest 2>&1 +DROP USER plug_user, plug_dest; +DROP DATABASE test_user_db; +--exit diff --git a/mysql-test/t/plugin_auth_qa_2-master.opt b/mysql-test/t/plugin_auth_qa_2-master.opt new file mode 100644 index 00000000000..c29153ac95b --- /dev/null +++ b/mysql-test/t/plugin_auth_qa_2-master.opt @@ -0,0 +1,2 @@ +$PLUGIN_AUTH_OPT +$PLUGIN_AUTH_INTERFACE diff --git a/mysql-test/t/plugin_auth_qa_2.test b/mysql-test/t/plugin_auth_qa_2.test new file mode 100644 index 00000000000..053e89166b7 --- /dev/null +++ b/mysql-test/t/plugin_auth_qa_2.test @@ -0,0 +1,148 @@ +# Horst Hunger +# Created: 2010-10-06 +# +# Test of the authentification interface. The plugin checks the expected values set +# by this application and the application checks the values set the the plugin. +--source include/have_plugin_interface.inc +--source include/not_embedded.inc + +CREATE DATABASE test_user_db; + +--echo ========== test 1.1.3.2 ==================================== +--echo === check contens of components of info ==================== + +CREATE USER qa_test_1_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_1_dest'; +CREATE USER qa_test_1_dest IDENTIFIED BY 'dest_passwd'; +GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_1_dest identified by 'dest_passwd'; +GRANT PROXY ON qa_test_1_dest TO qa_test_1_user; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +SELECT @@proxy_user; +SELECT @@external_user; + +--echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u qa_test_1_user --password=qa_test_1_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u qa_test_1_user --password=qa_test_1_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 + +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; + +DROP USER qa_test_1_user; +DROP USER qa_test_1_dest; + +--echo === Assign values to components of info ==================== + +CREATE USER qa_test_2_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_2_dest'; +CREATE USER qa_test_2_dest IDENTIFIED BY 'dest_passwd'; +CREATE USER authenticated_as IDENTIFIED BY 'dest_passwd'; +GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_2_dest identified by 'dest_passwd'; +GRANT PROXY ON qa_test_2_dest TO qa_test_2_user; +GRANT PROXY ON authenticated_as TO qa_test_2_user; +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; +SELECT @@proxy_user; +SELECT @@external_user; + +--echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u qa_test_2_user --password=qa_test_2_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u qa_test_2_user --password=qa_test_2_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 + +--sorted_result +SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; + +DROP USER qa_test_2_user; +DROP USER qa_test_2_dest; +DROP USER authenticated_as; + +--echo === Assign too high values for *length, which should have no effect ==== + +CREATE USER qa_test_3_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_3_dest'; +CREATE USER qa_test_3_dest IDENTIFIED BY 'dest_passwd'; +GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_3_dest identified by 'dest_passwd'; +GRANT PROXY ON qa_test_3_dest TO qa_test_3_user; + +--echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u qa_test_3_user --password=qa_test_3_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u qa_test_3_user --password=qa_test_3_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 + +DROP USER qa_test_3_user; +DROP USER qa_test_3_dest; + +--echo === Assign too low values for *length, which should have no effect ==== + +CREATE USER qa_test_4_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_4_dest'; +CREATE USER qa_test_4_dest IDENTIFIED BY 'dest_passwd'; +GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_4_dest identified by 'dest_passwd'; +GRANT PROXY ON qa_test_4_dest TO qa_test_4_user; + +--echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u qa_test_4_user --password=qa_test_4_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u qa_test_4_user --password=qa_test_4_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 + +DROP USER qa_test_4_user; +DROP USER qa_test_4_dest; + +--echo === Assign empty string especially to authenticated_as (in plugin) ==== + +CREATE USER qa_test_5_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_5_dest'; +CREATE USER qa_test_5_dest IDENTIFIED BY 'dest_passwd'; +CREATE USER ''@'localhost' IDENTIFIED BY 'dest_passwd'; +GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_5_dest identified by 'dest_passwd'; +GRANT ALL PRIVILEGES ON test_user_db.* TO ''@'localhost' identified by 'dest_passwd'; +GRANT PROXY ON qa_test_5_dest TO qa_test_5_user; +GRANT PROXY ON qa_test_5_dest TO ''@'localhost'; + +SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; + +--echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=qa_test_5_user --password=qa_test_5_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--error 1 +--exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=qa_test_5_user --password=qa_test_5_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 + +DROP USER qa_test_5_user; +DROP USER qa_test_5_dest; +DROP USER ''@'localhost'; + +--echo === Assign 'root' especially to authenticated_as (in plugin) ==== + +CREATE USER qa_test_6_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_6_dest'; +CREATE USER qa_test_6_dest IDENTIFIED BY 'dest_passwd'; +GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_6_dest identified by 'dest_passwd'; +GRANT PROXY ON qa_test_6_dest TO qa_test_6_user; + +SELECT user,plugin,authentication_string,password FROM mysql.user; + +--echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=qa_test_6_user --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--error 1 +--exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=qa_test_6_user --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 + +GRANT PROXY ON qa_test_6_dest TO root IDENTIFIED WITH qa_auth_interface AS 'qa_test_6_dest'; +SELECT user,plugin,authentication_string,password FROM mysql.user; + +--echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--error 1 +--exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 + +REVOKE PROXY ON qa_test_6_dest FROM root; +SELECT user,plugin,authentication_string FROM mysql.user; + +--echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--error 1 +--exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 + +DROP USER qa_test_6_user; +DROP USER qa_test_6_dest; +DELETE FROM mysql.user WHERE user='root' AND plugin='qa_auth_interface'; +SELECT user,plugin,authentication_string,password FROM mysql.user; + + +--echo === Test of the --default_auth option for clients ==== + +CREATE USER qa_test_11_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_11_dest'; +CREATE USER qa_test_11_dest IDENTIFIED BY 'dest_passwd'; +GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_11_dest identified by 'dest_passwd'; +GRANT PROXY ON qa_test_11_dest TO qa_test_11_user; + +--echo exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P $MASTER_MYPORT -u qa_test_11_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--error 1 +--exec $MYSQL $PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P $MASTER_MYPORT -u qa_test_11_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 + +DROP USER qa_test_11_user, qa_test_11_dest; +DROP DATABASE test_user_db; + +--exit diff --git a/mysql-test/t/plugin_auth_qa_3-master.opt b/mysql-test/t/plugin_auth_qa_3-master.opt new file mode 100644 index 00000000000..5cc2af0a358 --- /dev/null +++ b/mysql-test/t/plugin_auth_qa_3-master.opt @@ -0,0 +1,2 @@ +$PLUGIN_AUTH_OPT +$PLUGIN_AUTH_SERVER diff --git a/mysql-test/t/plugin_auth_qa_3.test b/mysql-test/t/plugin_auth_qa_3.test new file mode 100644 index 00000000000..4fe02f10ba6 --- /dev/null +++ b/mysql-test/t/plugin_auth_qa_3.test @@ -0,0 +1,25 @@ +# Horst Hunger +# Created: 2010-10-06 +# +# Test of the authentification interface. The plugin checks the expected values set +# by this application and the application checks the values set the the plugin. +--source include/have_plugin_server.inc +--source include/not_embedded.inc + +CREATE DATABASE test_user_db; + +CREATE USER qa_test_11_user IDENTIFIED WITH qa_auth_server AS 'qa_test_11_dest'; +GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_11_dest identified by 'dest_passwd'; +GRANT PROXY ON qa_test_11_dest TO qa_test_11_user; + +--echo exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P $MASTER_MYPORT -u qa_test_11_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--exec $MYSQL $PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P $MASTER_MYPORT -u qa_test_11_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 + +--echo exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P $MASTER_MYPORT -u qa_test_2_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--error 1 +--exec $MYSQL $PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P $MASTER_MYPORT -u qa_test_2_user --password=qa_test_2_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 + +DROP USER qa_test_11_user, qa_test_11_dest; +DROP DATABASE test_user_db; + +--exit diff --git a/plugin/auth/CMakeLists.txt b/plugin/auth/CMakeLists.txt index 7d87e151143..6a9c31f82ce 100644 --- a/plugin/auth/CMakeLists.txt +++ b/plugin/auth/CMakeLists.txt @@ -18,6 +18,14 @@ MYSQL_ADD_PLUGIN(auth dialog.c MODULE_ONLY) MYSQL_ADD_PLUGIN(auth_test_plugin test_plugin.c MODULE_ONLY) +MYSQL_ADD_PLUGIN(qa_auth_interface qa_auth_interface.c + MODULE_ONLY) + +MYSQL_ADD_PLUGIN(qa_auth_server qa_auth_server.c + MODULE_ONLY) + +MYSQL_ADD_PLUGIN(qa_auth_client qa_auth_client.c + MODULE_ONLY) CHECK_CXX_SOURCE_COMPILES( "#define _GNU_SOURCE diff --git a/plugin/auth/Makefile.am b/plugin/auth/Makefile.am index ed459b7b2b1..30e185f36f7 100644 --- a/plugin/auth/Makefile.am +++ b/plugin/auth/Makefile.am @@ -3,10 +3,14 @@ pkgplugindir=$(pkglibdir)/plugin AM_LDFLAGS=-module -rpath $(pkgplugindir) AM_CPPFLAGS=-DMYSQL_DYNAMIC_PLUGIN -Wno-pointer-sign -I$(top_srcdir)/include -pkgplugin_LTLIBRARIES= auth.la auth_test_plugin.la +pkgplugin_LTLIBRARIES= auth.la auth_test_plugin.la qa_auth_interface.la qa_auth_server.la qa_auth_client.la auth_la_SOURCES= dialog.c auth_test_plugin_la_SOURCES= test_plugin.c +qa_auth_interface_la_SOURCES= qa_auth_interface.c +qa_auth_server_la_SOURCES= qa_auth_server.c +qa_auth_client_la_SOURCES= qa_auth_client.c + if HAVE_PEERCRED pkgplugin_LTLIBRARIES+= auth_socket.la auth_socket_la_SOURCES= auth_socket.c diff --git a/plugin/auth/qa_auth_client.c b/plugin/auth/qa_auth_client.c new file mode 100644 index 00000000000..da7bfc14a73 --- /dev/null +++ b/plugin/auth/qa_auth_client.c @@ -0,0 +1,127 @@ +/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; version 2 of the + License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include +#include +#include +#include +#include +#include + +/** + first byte of the question string is the question "type". + It can be a "ordinary" or a "password" question. + The last bit set marks a last question in the authentication exchange. +*/ +#define ORDINARY_QUESTION "\2" +#define LAST_QUESTION "\3" +#define LAST_PASSWORD "\4" +#define PASSWORD_QUESTION "\5" + +/********************* CLIENT SIDE ***************************************/ +/* + client plugin used for testing the plugin API +*/ +#include + +/** + The main function of the test plugin. + + Reads the prompt, check if the handshake is done and if the prompt is a + password request and returns the password. Otherwise return error. + + @note + 1. this plugin shows how a client authentication plugin + may read a MySQL protocol OK packet internally - which is important + where a number of packets is not known in advance. + 2. the first byte of the prompt is special. it is not + shown to the user, but signals whether it is the last question + (prompt[0] & 1 == 1) or not last (prompt[0] & 1 == 0), + and whether the input is a password (not echoed). + 3. the prompt is expected to be sent zero-terminated +*/ +static int test_plugin_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) +{ + unsigned char *pkt, cmd= 0; + int pkt_len, res; + char *reply; + + do + { + /* read the prompt */ + pkt_len= vio->read_packet(vio, &pkt); + if (pkt_len < 0) + return CR_ERROR; + + if (pkt == 0) + { + /* + in mysql_change_user() the client sends the first packet, so + the first vio->read_packet() does nothing (pkt == 0). + + We send the "password", assuming the client knows what its doing. + (in other words, the dialog plugin should be only set as a default + authentication plugin on the client if the first question + asks for a password - which will be sent in cleat text, by the way) + */ + reply= mysql->passwd; + } + else + { + cmd= *pkt++; + + /* is it MySQL protocol (0=OK or 254=need old password) packet ? */ + if (cmd == 0 || cmd == 254) + return CR_OK_HANDSHAKE_COMPLETE; /* yes. we're done */ + + /* + asking for a password with an empty prompt means mysql->password + otherwise return an error + */ + if ((cmd == LAST_PASSWORD[0] || cmd == PASSWORD_QUESTION[0]) && *pkt == 0) + reply= mysql->passwd; + else + return CR_ERROR; + } + if (!reply) + return CR_ERROR; + /* send the reply to the server */ + res= vio->write_packet(vio, (const unsigned char *) reply, + strlen(reply) + 1); + + if (res) + return CR_ERROR; + + /* repeat unless it was the last question */ + } while (cmd != LAST_QUESTION[0] && cmd != PASSWORD_QUESTION[0]); + + /* the job of reading the ok/error packet is left to the server */ + return CR_OK; +} + + +mysql_declare_client_plugin(AUTHENTICATION) + "qa_auth_client", + "Horst Hunger", + "Dialog Client Authentication Plugin", + {0,1,0}, + "GPL", + NULL, + NULL, + NULL, + NULL, + test_plugin_client +mysql_end_client_plugin; diff --git a/plugin/auth/qa_auth_interface.c b/plugin/auth/qa_auth_interface.c new file mode 100644 index 00000000000..0aa6c9ce20c --- /dev/null +++ b/plugin/auth/qa_auth_interface.c @@ -0,0 +1,262 @@ +/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; version 2 of the + License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include +#include +#include +#include +#include +#include + +/** + first byte of the question string is the question "type". + It can be a "ordinary" or a "password" question. + The last bit set marks a last question in the authentication exchange. +*/ +#define ORDINARY_QUESTION "\2" +#define LAST_QUESTION "\3" +#define LAST_PASSWORD "\4" +#define PASSWORD_QUESTION "\5" + +/********************* SERVER SIDE ****************************************/ + +static int qa_auth_interface (MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info) +{ + unsigned char *pkt; + int pkt_len, err= CR_OK; + + /* send a password question */ + if (vio->write_packet(vio, (const unsigned char *) PASSWORD_QUESTION, 1)) + return CR_ERROR; + + /* read the answer */ + if ((pkt_len= vio->read_packet(vio, &pkt)) < 0) + return CR_ERROR; + + info->password_used= PASSWORD_USED_YES; + + /* fail if the password is wrong */ + if (strcmp((const char *) pkt, info->auth_string)) + return CR_ERROR; + +/* Check the contens of components of info */ + if (strcmp(info->user_name, "qa_test_1_user")== 0) + { + if (info->user_name_length != 14) + err= CR_ERROR; + if (strcmp(info->auth_string, "qa_test_1_dest")) + err= CR_ERROR; + if (info->auth_string_length != 14) + err= CR_ERROR; +/* To be set by the plugin */ +// if (strcmp(info->authenticated_as, "qa_test_1_user")) +// err= CR_ERROR; +/* To be set by the plugin */ +// if (strcmp(info->external_user, "")) +// err= CR_ERROR; + if (info->password_used != PASSWORD_USED_YES) + err= CR_ERROR; + if (strcmp(info->host_or_ip, "localhost")) + err= CR_ERROR; + if (info->host_or_ip_length != 9) + err= CR_ERROR; + } +/* Assign values to the components of info even if not intended and watch the effect */ + else if (strcmp(info->user_name, "qa_test_2_user")== 0) + { + /* Overwriting not intended, but with effect on USER() */ + strcpy(info->user_name, "user_name"); + info->user_name_length= 9; + /* Overwriting not intended, effect not visible */ + strcpy((char *)info->auth_string, "auth_string"); + info->auth_string_length= 11; + /* Assign with account for authorization, effect on CURRENT_USER() */ + strcpy(info->authenticated_as, "authenticated_as"); + /* Assign with an external account, effect on @@local.EXTERNAL_USER */ + strcpy(info->external_user, "externaluser"); + /* Overwriting will cause a core dump */ +// strcpy(info->host_or_ip, "host_or_ip"); +// info->host_or_ip_length= 10; + } +/* Invalid, means too high values for length */ + else if (strcmp(info->user_name, "qa_test_3_user")== 0) + { +/* Original value is 14. Test runs also with higher value. Changes have no effect.*/ + info->user_name_length= 28; + strcpy((char *)info->auth_string, "qa_test_3_dest"); +/* Original value is 14. Test runs also with higher value. Changes have no effect.*/ + info->auth_string_length= 28; + strcpy(info->authenticated_as, info->auth_string); + strcpy(info->external_user, info->auth_string); + } +/* Invalid, means too low values for length */ + else if (strcmp(info->user_name, "qa_test_4_user")== 0) + { +/* Original value is 14. Test runs also with lower value. Changes have no effect.*/ + info->user_name_length= 8; + strcpy((char *)info->auth_string, "qa_test_4_dest"); +/* Original value is 14. Test runs also with lower value. Changes have no effect.*/ + info->auth_string_length= 8; + strcpy(info->authenticated_as, info->auth_string); + strcpy(info->external_user, info->auth_string); + } +/* Overwrite with empty values */ + else if (strcmp(info->user_name, "qa_test_5_user")== 0) + { +/* This assignment has no effect.*/ + strcpy(info->user_name, ""); + info->user_name_length= 0; +/* This assignment has no effect.*/ + strcpy((char *)info->auth_string, ""); + info->auth_string_length= 0; +/* This assignment caused an error or an "empty" user */ + strcpy(info->authenticated_as, ""); +/* This assignment has no effect.*/ + strcpy(info->external_user, ""); + /* Overwriting will cause a core dump */ +// strcpy(info->host_or_ip, ""); +// info->host_or_ip_length= 0; + } +/* Set to 'root' */ + else if (strcmp(info->user_name, "qa_test_6_user")== 0) + { + strcpy(info->authenticated_as, "root"); + } + else + { + err= CR_ERROR; + } + return err; +} + +static struct st_mysql_auth qa_auth_test_handler= +{ + MYSQL_AUTHENTICATION_INTERFACE_VERSION, + "qa_auth_interface", /* requires test_plugin client's plugin */ + qa_auth_interface +}; + +mysql_declare_plugin(test_plugin) +{ + MYSQL_AUTHENTICATION_PLUGIN, + &qa_auth_test_handler, + "qa_auth_interface", + "Horst Hunger", + "plugin API test plugin", + PLUGIN_LICENSE_GPL, + NULL, + NULL, + 0x0100, + NULL, + NULL, + NULL +} +mysql_declare_plugin_end; + +/********************* CLIENT SIDE ***************************************/ +/* + client plugin used for testing the plugin API +*/ +#include + +/** + The main function of the test plugin. + + Reads the prompt, check if the handshake is done and if the prompt is a + password request and returns the password. Otherwise return error. + + @note + 1. this plugin shows how a client authentication plugin + may read a MySQL protocol OK packet internally - which is important + where a number of packets is not known in advance. + 2. the first byte of the prompt is special. it is not + shown to the user, but signals whether it is the last question + (prompt[0] & 1 == 1) or not last (prompt[0] & 1 == 0), + and whether the input is a password (not echoed). + 3. the prompt is expected to be sent zero-terminated +*/ +static int test_plugin_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) +{ + unsigned char *pkt, cmd= 0; + int pkt_len, res; + char *reply; + + do + { + /* read the prompt */ + pkt_len= vio->read_packet(vio, &pkt); + if (pkt_len < 0) + return CR_ERROR; + + if (pkt == 0) + { + /* + in mysql_change_user() the client sends the first packet, so + the first vio->read_packet() does nothing (pkt == 0). + + We send the "password", assuming the client knows what its doing. + (in other words, the dialog plugin should be only set as a default + authentication plugin on the client if the first question + asks for a password - which will be sent in cleat text, by the way) + */ + reply= mysql->passwd; + } + else + { + cmd= *pkt++; + + /* is it MySQL protocol (0=OK or 254=need old password) packet ? */ + if (cmd == 0 || cmd == 254) + return CR_OK_HANDSHAKE_COMPLETE; /* yes. we're done */ + + /* + asking for a password with an empty prompt means mysql->password + otherwise return an error + */ + if ((cmd == LAST_PASSWORD[0] || cmd == PASSWORD_QUESTION[0]) && *pkt == 0) + reply= mysql->passwd; + else + return CR_ERROR; + } + if (!reply) + return CR_ERROR; + /* send the reply to the server */ + res= vio->write_packet(vio, (const unsigned char *) reply, + strlen(reply) + 1); + + if (res) + return CR_ERROR; + + /* repeat unless it was the last question */ + } while (cmd != LAST_QUESTION[0] && cmd != PASSWORD_QUESTION[0]); + + /* the job of reading the ok/error packet is left to the server */ + return CR_OK; +} + + +mysql_declare_client_plugin(AUTHENTICATION) + "qa_auth_interface", + "Horst Hunger", + "Dialog Client Authentication Plugin", + {0,1,0}, + "GPL", + NULL, + NULL, + NULL, + NULL, + test_plugin_client +mysql_end_client_plugin; diff --git a/plugin/auth/qa_auth_server.c b/plugin/auth/qa_auth_server.c new file mode 100644 index 00000000000..17171610200 --- /dev/null +++ b/plugin/auth/qa_auth_server.c @@ -0,0 +1,87 @@ +/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; version 2 of the + License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include +#include +#include +#include +#include +#include + +/** + first byte of the question string is the question "type". + It can be a "ordinary" or a "password" question. + The last bit set marks a last question in the authentication exchange. +*/ +#define ORDINARY_QUESTION "\2" +#define LAST_QUESTION "\3" +#define LAST_PASSWORD "\4" +#define PASSWORD_QUESTION "\5" + +/********************* SERVER SIDE ****************************************/ + +static int qa_auth_interface (MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info) +{ + unsigned char *pkt; + int pkt_len, err= CR_OK; + + /* send a password question */ + if (vio->write_packet(vio, (const unsigned char *) PASSWORD_QUESTION, 1)) + return CR_ERROR; + + /* read the answer */ + if ((pkt_len= vio->read_packet(vio, &pkt)) < 0) + return CR_ERROR; + + info->password_used= PASSWORD_USED_YES; + + /* fail if the password is wrong */ + if (strcmp((const char *) pkt, info->auth_string)) + return CR_ERROR; + +/* Test of default_auth */ + if (strcmp(info->user_name, "qa_test_11_user")== 0) + { + strcpy(info->authenticated_as, "qa_test_11_dest"); + } + else + err= CR_ERROR; + return err; +} + +static struct st_mysql_auth qa_auth_test_handler= +{ + MYSQL_AUTHENTICATION_INTERFACE_VERSION, + "qa_auth_interface", /* requires test_plugin client's plugin */ + qa_auth_interface +}; + +mysql_declare_plugin(test_plugin) +{ + MYSQL_AUTHENTICATION_PLUGIN, + &qa_auth_test_handler, + "qa_auth_server", + "Horst Hunger", + "plugin API test plugin", + PLUGIN_LICENSE_GPL, + NULL, + NULL, + 0x0100, + NULL, + NULL, + NULL +} +mysql_declare_plugin_end; From 3e9c52250a3ab6664c53ea6b3923acfbe8e09e4e Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Wed, 20 Oct 2010 16:21:40 -0200 Subject: [PATCH 086/304] Bug#45288: pb2 returns a lot of compilation warnings Fix assorted warnings that are generated in optimized builds. Most of it is silencing variables that are set but unused. This patch also introduces the MY_ASSERT_UNREACHABLE macro which helps the compiler to deduce that a certain piece of code is unreachable. include/my_compiler.h: Use GCC's __builtin_unreachable if available. It allows GCC to deduce the unreachability of certain code paths, thus avoiding warnings that, for example, accused that a variable could be used without being initialized (due to unreachable code paths). --- client/mysqltest.cc | 22 ++++++++++++++-------- cmd-line-utils/readline/complete.c | 7 ++++++- cmd-line-utils/readline/histexpand.c | 3 +-- cmd-line-utils/readline/histfile.c | 1 + cmd-line-utils/readline/isearch.c | 8 ++++---- cmd-line-utils/readline/parens.c | 4 ++-- cmd-line-utils/readline/readline.c | 3 +-- cmd-line-utils/readline/text.c | 3 +-- include/my_compiler.h | 13 ++++++++++++- sql/lock.cc | 8 +++----- sql/log.cc | 2 +- sql/set_var.cc | 2 +- sql/sql_acl.cc | 2 +- sql/sql_help.cc | 2 +- sql/sql_partition.cc | 4 ++-- sql/sql_union.cc | 9 --------- storage/myisam/myisamchk.c | 3 +-- storage/myisammrg/ha_myisammrg.cc | 2 +- 18 files changed, 53 insertions(+), 45 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 38862210cba..d790b3f0ee7 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -5258,8 +5258,13 @@ void do_connect(struct st_command *command) opt_charsets_dir); #ifdef HAVE_OPENSSL - if (opt_use_ssl || con_ssl) + if (opt_use_ssl) + con_ssl= 1; +#endif + + if (con_ssl) { +#ifdef HAVE_OPENSSL mysql_ssl_set(&con_slot->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, opt_ssl_capath, opt_ssl_cipher); #if MYSQL_VERSION_ID >= 50000 @@ -5268,36 +5273,37 @@ void do_connect(struct st_command *command) mysql_options(&con_slot->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &opt_ssl_verify_server_cert); #endif - } #endif + } -#ifdef __WIN__ if (con_pipe) { +#ifdef __WIN__ opt_protocol= MYSQL_PROTOCOL_PIPE; - } #endif + } if (opt_protocol) mysql_options(&con_slot->mysql, MYSQL_OPT_PROTOCOL, (char*) &opt_protocol); -#ifdef HAVE_SMEM if (con_shm) { +#ifdef HAVE_SMEM uint protocol= MYSQL_PROTOCOL_MEMORY; if (!ds_shm.length) die("Missing shared memory base name"); mysql_options(&con_slot->mysql, MYSQL_SHARED_MEMORY_BASE_NAME, ds_shm.str); mysql_options(&con_slot->mysql, MYSQL_OPT_PROTOCOL, &protocol); +#endif } - else if(shared_memory_base_name) +#ifdef HAVE_SMEM + else if (shared_memory_base_name) { mysql_options(&con_slot->mysql, MYSQL_SHARED_MEMORY_BASE_NAME, - shared_memory_base_name); + shared_memory_base_name); } #endif - /* Use default db name */ if (ds_database.length == 0) dynstr_set(&ds_database, opt_db); diff --git a/cmd-line-utils/readline/complete.c b/cmd-line-utils/readline/complete.c index 2745e4e4801..d11ea2493a6 100644 --- a/cmd-line-utils/readline/complete.c +++ b/cmd-line-utils/readline/complete.c @@ -1839,8 +1839,11 @@ rl_username_completion_function (text, state) #else /* !__WIN32__ && !__OPENNT) */ static char *username = (char *)NULL; static struct passwd *entry; - static int namelen, first_char, first_char_loc; + static int first_char, first_char_loc; char *value; +#if defined (HAVE_GETPWENT) + static int namelen; +#endif if (state == 0) { @@ -1850,7 +1853,9 @@ rl_username_completion_function (text, state) first_char_loc = first_char == '~'; username = savestring (&text[first_char_loc]); +#if defined (HAVE_GETPWENT) namelen = strlen (username); +#endif setpwent (); } diff --git a/cmd-line-utils/readline/histexpand.c b/cmd-line-utils/readline/histexpand.c index ab8d8ecc866..7b51c369827 100644 --- a/cmd-line-utils/readline/histexpand.c +++ b/cmd-line-utils/readline/histexpand.c @@ -693,7 +693,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line) case 's': { char *new_event; - int delimiter, failed, si, l_temp, ws, we; + int delimiter, failed, si, l_temp, we; if (c == 's') { @@ -792,7 +792,6 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line) { for (; temp[si] && whitespace (temp[si]); si++) ; - ws = si; we = history_tokenize_word (temp, si); } diff --git a/cmd-line-utils/readline/histfile.c b/cmd-line-utils/readline/histfile.c index cbd367542ce..1a6d69b6684 100644 --- a/cmd-line-utils/readline/histfile.c +++ b/cmd-line-utils/readline/histfile.c @@ -402,6 +402,7 @@ history_truncate_file (fname, lines) if (bp > buffer && ((file = open (filename, O_WRONLY|O_TRUNC|O_BINARY, 0600)) != -1)) { bytes_written= write (file, bp, chars_read - (bp - buffer)); + (void) bytes_written; #if defined (__BEOS__) /* BeOS ignores O_TRUNC. */ diff --git a/cmd-line-utils/readline/isearch.c b/cmd-line-utils/readline/isearch.c index 305c847d8da..977e08eb9ba 100644 --- a/cmd-line-utils/readline/isearch.c +++ b/cmd-line-utils/readline/isearch.c @@ -617,7 +617,7 @@ rl_search_history (direction, invoking_key) int direction, invoking_key __attribute__((unused)); { _rl_search_cxt *cxt; /* local for now, but saved globally */ - int c, r; + int r; RL_SETSTATE(RL_STATE_ISEARCH); cxt = _rl_isearch_init (direction); @@ -632,7 +632,7 @@ rl_search_history (direction, invoking_key) r = -1; for (;;) { - c = _rl_search_getchar (cxt); + _rl_search_getchar (cxt); /* We might want to handle EOF here (c == 0) */ r = _rl_isearch_dispatch (cxt, cxt->lastc); if (r <= 0) @@ -655,9 +655,9 @@ int _rl_isearch_callback (cxt) _rl_search_cxt *cxt; { - int c, r; + int r; - c = _rl_search_getchar (cxt); + _rl_search_getchar (cxt); /* We might want to handle EOF here */ r = _rl_isearch_dispatch (cxt, cxt->lastc); diff --git a/cmd-line-utils/readline/parens.c b/cmd-line-utils/readline/parens.c index fe1578ed3e2..58f22291172 100644 --- a/cmd-line-utils/readline/parens.c +++ b/cmd-line-utils/readline/parens.c @@ -115,7 +115,7 @@ rl_insert_close (count, invoking_key) else { #if defined (HAVE_SELECT) - int orig_point, match_point, ready; + int orig_point, match_point; struct timeval timer; fd_set readfds; @@ -136,7 +136,7 @@ rl_insert_close (count, invoking_key) orig_point = rl_point; rl_point = match_point; (*rl_redisplay_function) (); - ready = select (1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer); + select (1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer); rl_point = orig_point; #else /* !HAVE_SELECT */ _rl_insert_char (count, invoking_key); diff --git a/cmd-line-utils/readline/readline.c b/cmd-line-utils/readline/readline.c index fb92becdbf9..95947551823 100644 --- a/cmd-line-utils/readline/readline.c +++ b/cmd-line-utils/readline/readline.c @@ -447,11 +447,10 @@ readline_internal_char () readline_internal_charloop () #endif { - static int lastc, eof_found; + static int lastc; int c, code, lk; lastc = -1; - eof_found = 0; #if !defined (READLINE_CALLBACKS) while (rl_done == 0) diff --git a/cmd-line-utils/readline/text.c b/cmd-line-utils/readline/text.c index bb0f5d97160..02b28750c86 100644 --- a/cmd-line-utils/readline/text.c +++ b/cmd-line-utils/readline/text.c @@ -811,11 +811,10 @@ _rl_overwrite_char (count, c) int i; #if defined (HANDLE_MULTIBYTE) char mbkey[MB_LEN_MAX]; - int k; /* Read an entire multibyte character sequence to insert COUNT times. */ if (count > 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0) - k = _rl_read_mbstring (c, mbkey, MB_LEN_MAX); + _rl_read_mbstring (c, mbkey, MB_LEN_MAX); #endif rl_begin_undo_group (); diff --git a/include/my_compiler.h b/include/my_compiler.h index 1cd46ff4260..c7d334999d0 100644 --- a/include/my_compiler.h +++ b/include/my_compiler.h @@ -32,8 +32,15 @@ /* GNU C/C++ */ #if defined __GNUC__ +/* Convenience macro to test the minimum required GCC version. */ +# define MY_GNUC_PREREQ(maj, min) \ + ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) /* Any after 2.95... */ # define MY_ALIGN_EXT +/* Comunicate to the compiler the unreachability of the code. */ +# if MY_GNUC_PREREQ(4,5) +# define MY_ASSERT_UNREACHABLE() __builtin_unreachable() +# endif /* Microsoft Visual C++ */ #elif defined _MSC_VER @@ -67,7 +74,7 @@ #endif /** - Generic compiler-dependent features. + Generic (compiler-independent) features. */ #ifndef MY_ALIGNOF # ifdef __cplusplus @@ -79,6 +86,10 @@ # endif #endif +#ifndef MY_ASSERT_UNREACHABLE +# define MY_ASSERT_UNREACHABLE() do { assert(0); } while (0) +#endif + /** C++ Type Traits */ diff --git a/sql/lock.cc b/sql/lock.cc index 93d8b868688..e2216876635 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -693,7 +693,6 @@ TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle, TABLE_LIST *haystack) { MYSQL_LOCK *mylock; - TABLE **lock_tables; TABLE *table; TABLE *table2; THR_LOCK_DATA **lock_locks; @@ -722,12 +721,11 @@ TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle, if (mylock->table_count < 2) goto end; - lock_locks= mylock->locks; - lock_tables= mylock->table; + lock_locks= mylock->locks; /* Prepare table related variables that don't change in loop. */ DBUG_ASSERT((table->lock_position < mylock->table_count) && - (table == lock_tables[table->lock_position])); + (table == mylock->table[table->lock_position])); table_lock_data= lock_locks + table->lock_data_start; end_data= table_lock_data + table->lock_count; @@ -741,7 +739,7 @@ TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle, /* All tables in list must be in lock. */ DBUG_ASSERT((table2->lock_position < mylock->table_count) && - (table2 == lock_tables[table2->lock_position])); + (table2 == mylock->table[table2->lock_position])); for (lock_data2= lock_locks + table2->lock_data_start, end_data2= lock_data2 + table2->lock_count; diff --git a/sql/log.cc b/sql/log.cc index 2d5b62a5b2b..38f4677f06f 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1217,7 +1217,7 @@ void LOGGER::deactivate_log_handler(THD *thd, uint log_type) file_log= file_log_handler->get_mysql_log(); break; default: - assert(0); // Impossible + MY_ASSERT_UNREACHABLE(); } if (!(*tmp_opt)) diff --git a/sql/set_var.cc b/sql/set_var.cc index c5517da92f8..9fbce870dc4 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -2559,7 +2559,7 @@ bool update_sys_var_str_path(THD *thd, sys_var_str *var_str, file_log= logger.get_log_file_handler(); break; default: - assert(0); // Impossible + MY_ASSERT_UNREACHABLE(); } if (!old_value) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index ea002f59fe3..1733a0f74b4 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -5479,7 +5479,7 @@ static int handle_grant_struct(uint struct_no, bool drop, host= grant_name->host.hostname; break; default: - assert(0); + MY_ASSERT_UNREACHABLE(); } if (! user) user= ""; diff --git a/sql/sql_help.cc b/sql/sql_help.cc index 2818aa5082c..c21968cb86e 100644 --- a/sql/sql_help.cc +++ b/sql/sql_help.cc @@ -686,7 +686,7 @@ bool mysqld_help(THD *thd, const char *mask) if (count_topics == 0) { - int key_id; + int UNINIT_VAR(key_id); if (!(select= prepare_select_for_name(thd,mask,mlen,tables,tables[3].table, used_fields[help_keyword_name].field, diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 76caa2b0c8d..702c3d99fda 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -6786,8 +6786,8 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info, } } else - assert(0); - + MY_ASSERT_UNREACHABLE(); + can_match_multiple_values= (flags || !min_value || !max_value || memcmp(min_value, max_value, field_len)); if (can_match_multiple_values && diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 948ba1d9d9c..70598fbfcd4 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -173,7 +173,6 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, SELECT_LEX *sl, *first_sl= first_select(); select_result *tmp_result; bool is_union_select; - TABLE *empty_table= 0; DBUG_ENTER("st_select_lex_unit::prepare"); describe= test(additional_options & SELECT_DESCRIBE); @@ -275,14 +274,6 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, types= first_sl->item_list; else if (sl == first_sl) { - /* - We need to create an empty table object. It is used - to create tmp_table fields in Item_type_holder. - The main reason of this is that we can't create - field object without table. - */ - DBUG_ASSERT(!empty_table); - empty_table= (TABLE*) thd->calloc(sizeof(TABLE)); types.empty(); List_iterator_fast it(sl->item_list); Item *item_tmp; diff --git a/storage/myisam/myisamchk.c b/storage/myisam/myisamchk.c index 96ceb35b3d5..7f9776ca8d0 100644 --- a/storage/myisam/myisamchk.c +++ b/storage/myisam/myisamchk.c @@ -697,8 +697,7 @@ get_one_option(int optid, case OPT_STATS_METHOD: { int method; - enum_mi_stats_method method_conv; - LINT_INIT(method_conv); + enum_mi_stats_method UNINIT_VAR(method_conv); myisam_stats_method_str= argument; if ((method=find_type(argument, &myisam_stats_method_typelib, 2)) <= 0) { diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index 8e18924c5b8..4c8d45d1fe1 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -415,7 +415,7 @@ static MI_INFO *myisammrg_attach_children_callback(void *callback_param) my_errno= HA_ERR_WRONG_MRG_TABLE_DEF; } DBUG_PRINT("myrg", ("MyISAM handle: 0x%lx my_errno: %d", - my_errno ? NULL : (long) myisam, my_errno)); + my_errno ? 0L : (long) myisam, my_errno)); err: DBUG_RETURN(my_errno ? NULL : myisam); From 9129cb184b5b443f0c863720c44e22875438235e Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Wed, 20 Oct 2010 19:25:28 -0200 Subject: [PATCH 087/304] GCC's link option only take a single hyphen. --- cmake/os/Linux.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/os/Linux.cmake b/cmake/os/Linux.cmake index 946e020d6f4..10d3a719609 100644 --- a/cmake/os/Linux.cmake +++ b/cmake/os/Linux.cmake @@ -33,7 +33,7 @@ ENDFOREACH() # Ensure we have clean build for shared libraries # without unresolved symbols -SET(LINK_FLAG_NO_UNDEFINED "--Wl,--no-undefined") +SET(LINK_FLAG_NO_UNDEFINED "-Wl,--no-undefined") # 64 bit file offset support flag SET(_FILE_OFFSET_BITS 64) From 1e09ea9549ce53026f25727a59f33e1eabbbfd31 Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Wed, 20 Oct 2010 19:14:25 -0700 Subject: [PATCH 088/304] Fix bug #57616 Sig 11 in dict_load_table() when failed to load index or foreign key Fix approved by Sunny Bains --- storage/innobase/dict/dict0load.c | 4 ++-- storage/innodb_plugin/ChangeLog | 6 ++++++ storage/innodb_plugin/dict/dict0load.c | 4 ++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/storage/innobase/dict/dict0load.c b/storage/innobase/dict/dict0load.c index 625956600c0..c505bfbd6c4 100644 --- a/storage/innobase/dict/dict0load.c +++ b/storage/innobase/dict/dict0load.c @@ -878,13 +878,13 @@ err_exit: if (err != DB_SUCCESS) { dict_table_remove_from_cache(table); table = NULL; + } else { + table->fk_max_recusive_level = 0; } } else if (!srv_force_recovery) { dict_table_remove_from_cache(table); table = NULL; } - - table->fk_max_recusive_level = 0; #if 0 if (err != DB_SUCCESS && table != NULL) { diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index f0dfe1ff6cc..3e1e4fc7a99 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,9 @@ +2010-10-20 The InnoDB Team + + * dict/dict0load.c + Fix Bug #57616 Sig 11 in dict_load_table() when failed to load + index or foreign key + 2010-10-11 The InnoDB Team * row/row0sel.c diff --git a/storage/innodb_plugin/dict/dict0load.c b/storage/innodb_plugin/dict/dict0load.c index b046fb32b0b..3dcee46b92c 100644 --- a/storage/innodb_plugin/dict/dict0load.c +++ b/storage/innodb_plugin/dict/dict0load.c @@ -1023,13 +1023,13 @@ err_exit: if (err != DB_SUCCESS) { dict_table_remove_from_cache(table); table = NULL; + } else { + table->fk_max_recusive_level = 0; } } else if (!srv_force_recovery) { dict_table_remove_from_cache(table); table = NULL; } - - table->fk_max_recusive_level = 0; #if 0 if (err != DB_SUCCESS && table != NULL) { From e8f228e7eb4f054bd7c272ba4c33fb7ea071ac2a Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Wed, 20 Oct 2010 19:56:42 -0700 Subject: [PATCH 089/304] Fix Bug #57616 Sig 11 in dict_load_table() when failed to load index or foreign key Approved by Sunny Bains --- storage/innobase/dict/dict0load.c | 4 ++-- storage/innodb_plugin/ChangeLog | 6 ++++++ storage/innodb_plugin/dict/dict0load.c | 4 ++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/storage/innobase/dict/dict0load.c b/storage/innobase/dict/dict0load.c index 625956600c0..c505bfbd6c4 100644 --- a/storage/innobase/dict/dict0load.c +++ b/storage/innobase/dict/dict0load.c @@ -878,13 +878,13 @@ err_exit: if (err != DB_SUCCESS) { dict_table_remove_from_cache(table); table = NULL; + } else { + table->fk_max_recusive_level = 0; } } else if (!srv_force_recovery) { dict_table_remove_from_cache(table); table = NULL; } - - table->fk_max_recusive_level = 0; #if 0 if (err != DB_SUCCESS && table != NULL) { diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index db37fa2b4bb..cccd5c0550a 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,9 @@ +2010-10-20 The InnoDB Team + + * dict/dict0load.c + Fix Bug #57616 Sig 11 in dict_load_table() when failed to load + index or foreign key + 2010-10-19 The InnoDB Team * btr/btr0cur.c, buf/buf0buf.c, buf/buf0flu.c, handler/ha_innodb.cc, diff --git a/storage/innodb_plugin/dict/dict0load.c b/storage/innodb_plugin/dict/dict0load.c index b046fb32b0b..3dcee46b92c 100644 --- a/storage/innodb_plugin/dict/dict0load.c +++ b/storage/innodb_plugin/dict/dict0load.c @@ -1023,13 +1023,13 @@ err_exit: if (err != DB_SUCCESS) { dict_table_remove_from_cache(table); table = NULL; + } else { + table->fk_max_recusive_level = 0; } } else if (!srv_force_recovery) { dict_table_remove_from_cache(table); table = NULL; } - - table->fk_max_recusive_level = 0; #if 0 if (err != DB_SUCCESS && table != NULL) { From 6646fecc1420fce3b2d2425aa07170370a7671bf Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 21 Oct 2010 13:43:19 +0800 Subject: [PATCH 090/304] Bug#55478 Row events wrongly apply on the temporary table of the same name Rows events were applied wrongly on the temporary table with the same name. But rows events are generated only for base tables. As temporary table's data never be binlogged on row mode. Normally, base table of the same name cannot be updated if a temporary table has the same name. But there are two cases which can generate rows events on the base table of same name. Case1: 'CREATE TABLE ... SELECT' statement. In mixed format, it will generate rows events if it is unsafe. Case2: Drop a transactional temporary table in a transaction (happens only on 5.5+). BEGIN; DROP TEMPORARY TABLE t1; # t1 is a InnoDB table INSERT INTO t1 VALUES(rand()); # t1 is a MyISAM table COMMIT; 'DROP TEMPORARY TABLE' will be put in the transaction cache and binlogged after the rows events generated by the 'INSERT' statement. After this patch, slave opens only base table when applying a rows event. --- .../suite/rpl/r/rpl_temp_table_mix_row.result | 44 +++++++++++++++ .../suite/rpl/t/rpl_temp_table_mix_row.test | 53 +++++++++++++++++++ sql/log_event.cc | 1 + 3 files changed, 98 insertions(+) diff --git a/mysql-test/suite/rpl/r/rpl_temp_table_mix_row.result b/mysql-test/suite/rpl/r/rpl_temp_table_mix_row.result index 3a31a206b1e..00cf238c712 100644 --- a/mysql-test/suite/rpl/r/rpl_temp_table_mix_row.result +++ b/mysql-test/suite/rpl/r/rpl_temp_table_mix_row.result @@ -69,3 +69,47 @@ slave-bin.000001 # Query # # COMMIT slave-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE IF EXISTS `t2_tmp` /* generated by server */ slave-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (2) slave-bin.000001 # Query # # use `test`; DROP TABLE t3, t1 + +# Bug#55478 Row events wrongly apply on the temporary table of the same name +# ========================================================================== +# The statement should be binlogged +CREATE TEMPORARY TABLE t1(c1 INT) ENGINE=InnoDB; + +# Case 1: CREATE TABLE t1 ... SELECT +# ---------------------------------- + +# The statement generates row events on t1. And the rows events should +# be inserted into the base table on slave. +CREATE TABLE t1 ENGINE=MyISAM SELECT rand(); +show binlog events in 'master-bin.000001' from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; CREATE TABLE `t1` ( + `rand()` double NOT NULL DEFAULT '0' +) ENGINE=MyISAM +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # COMMIT + +# Case 2: DROP TEMPORARY TABLE in a transacation(happens only on 5.5+) +# -------------------------------------------------------------------- + +BEGIN; +DROP TEMPORARY TABLE t1; +# The statement will binlogged after 'DROP TEMPORARY TABLE t1' +INSERT INTO t1 VALUES(1); +# The rows event will binlogged after 'INSERT INTO t1 VALUES(1)' +INSERT INTO t1 VALUES(Rand()); +COMMIT; +show binlog events in 'master-bin.000001' from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE IF EXISTS `t1` /* generated by server */ +master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES(1) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # COMMIT +# Compare the base table. +Comparing tables master:test.t1 and slave:test.t1 + +DROP TABLE t1; diff --git a/mysql-test/suite/rpl/t/rpl_temp_table_mix_row.test b/mysql-test/suite/rpl/t/rpl_temp_table_mix_row.test index e19c3019aa1..fa3f7929c1c 100644 --- a/mysql-test/suite/rpl/t/rpl_temp_table_mix_row.test +++ b/mysql-test/suite/rpl/t/rpl_temp_table_mix_row.test @@ -11,6 +11,7 @@ source include/master-slave.inc; source include/have_binlog_format_mixed.inc; +source include/have_innodb.inc; --echo ==== Initialize ==== @@ -146,3 +147,55 @@ DROP TABLE t3, t1; -- sync_slave_with_master -- source include/show_binlog_events.inc + +--echo +--echo # Bug#55478 Row events wrongly apply on the temporary table of the same name +--echo # ========================================================================== +connection master; + +let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1); +let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); + +--echo # The statement should be binlogged +CREATE TEMPORARY TABLE t1(c1 INT) ENGINE=InnoDB; + +--echo +--echo # Case 1: CREATE TABLE t1 ... SELECT +--echo # ---------------------------------- +let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1); +let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); + +--echo +--echo # The statement generates row events on t1. And the rows events should +--echo # be inserted into the base table on slave. +CREATE TABLE t1 ENGINE=MyISAM SELECT rand(); + +source include/show_binlog_events.inc; +let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1); +let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); + +--echo +--echo # Case 2: DROP TEMPORARY TABLE in a transacation(happens only on 5.5+) +--echo # -------------------------------------------------------------------- +--echo + +BEGIN; +DROP TEMPORARY TABLE t1; + +--echo # The statement will binlogged after 'DROP TEMPORARY TABLE t1' +INSERT INTO t1 VALUES(1); + +--echo # The rows event will binlogged after 'INSERT INTO t1 VALUES(1)' +INSERT INTO t1 VALUES(Rand()); +COMMIT; + +source include/show_binlog_events.inc; + +--echo # Compare the base table. +let diff_table= test.t1; +source include/rpl_diff_tables.inc; + +--echo +connection master; +DROP TABLE t1; +source include/master-slave-end.inc; diff --git a/sql/log_event.cc b/sql/log_event.cc index 49f47edad72..041f90a057f 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -8258,6 +8258,7 @@ int Table_map_log_event::do_apply_event(Relay_log_info const *rli) m_field_metadata, m_field_metadata_size, m_null_bits, m_flags); table_list->m_tabledef_valid= TRUE; + table_list->skip_temporary= 1; /* We record in the slave's information that the table should be From ea6b469df39c1f177cd47f0d26406f95da4d7d31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 21 Oct 2010 10:32:41 +0300 Subject: [PATCH 091/304] lock_rec_validate_page(): Disable the debug printout. It is filling the error log when testing the debug version of the server. The printout only seems to be useful when debugging a crash, not when testing an instrumented version of the server. --- storage/innobase/lock/lock0lock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c index dcfca1b6315..f38ef48df4e 100644 --- a/storage/innobase/lock/lock0lock.c +++ b/storage/innobase/lock/lock0lock.c @@ -4859,11 +4859,11 @@ loop: ut_a(rec); offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); - +#if 0 fprintf(stderr, "Validating %lu %lu\n", (ulong) space, (ulong) page_no); - +#endif lock_mutex_exit_kernel(); /* If this thread is holding the file space From ed55f540ee16b94c4211c58830194895e4cbbdde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 21 Oct 2010 10:45:44 +0300 Subject: [PATCH 092/304] Remove files that are no longer needed. These files were needed when InnoDB Plugin was maintained and distributed separately from the MySQL 5.1 source tree. They have never been needed in MySQL 5.5. storage/innobase/mysql-test: Patches to the test suite. storage/innobase/handler/mysql_addons.cc: Wrappers for private MySQL functions. --- storage/innobase/CMakeLists.txt | 2 +- storage/innobase/Makefile.am | 2 - storage/innobase/handler/mysql_addons.cc | 42 ------ storage/innobase/include/mysql_addons.h | 33 ----- storage/innobase/mysql-test/patches/README | 30 ----- .../patches/index_merge_innodb-explain.diff | 31 ----- .../patches/information_schema.diff | 124 ------------------ .../innodb_change_buffering_basic.diff | 60 --------- .../patches/innodb_file_per_table.diff | 47 ------- .../patches/innodb_lock_wait_timeout.diff | 55 -------- .../innodb_thread_concurrency_basic.diff | 31 ----- .../mysql-test/patches/partition_innodb.diff | 59 --------- storage/innobase/trx/trx0i_s.c | 2 - 13 files changed, 1 insertion(+), 517 deletions(-) delete mode 100644 storage/innobase/handler/mysql_addons.cc delete mode 100644 storage/innobase/include/mysql_addons.h delete mode 100644 storage/innobase/mysql-test/patches/README delete mode 100644 storage/innobase/mysql-test/patches/index_merge_innodb-explain.diff delete mode 100644 storage/innobase/mysql-test/patches/information_schema.diff delete mode 100644 storage/innobase/mysql-test/patches/innodb_change_buffering_basic.diff delete mode 100644 storage/innobase/mysql-test/patches/innodb_file_per_table.diff delete mode 100644 storage/innobase/mysql-test/patches/innodb_lock_wait_timeout.diff delete mode 100644 storage/innobase/mysql-test/patches/innodb_thread_concurrency_basic.diff delete mode 100644 storage/innobase/mysql-test/patches/partition_innodb.diff diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt index 34639d61903..6cfd3d754f6 100644 --- a/storage/innobase/CMakeLists.txt +++ b/storage/innobase/CMakeLists.txt @@ -235,7 +235,7 @@ SET(INNOBASE_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c os/os0file.c os/os0proc.c os/os0sync.c os/os0thread.c page/page0cur.c page/page0page.c page/page0zip.c que/que0que.c - handler/ha_innodb.cc handler/handler0alter.cc handler/i_s.cc handler/mysql_addons.cc + handler/ha_innodb.cc handler/handler0alter.cc handler/i_s.cc read/read0read.c rem/rem0cmp.c rem/rem0rec.c row/row0ext.c row/row0ins.c row/row0merge.c row/row0mysql.c row/row0purge.c row/row0row.c diff --git a/storage/innobase/Makefile.am b/storage/innobase/Makefile.am index 460abddb11e..8e8e3300d35 100644 --- a/storage/innobase/Makefile.am +++ b/storage/innobase/Makefile.am @@ -115,7 +115,6 @@ noinst_HEADERS= \ include/mtr0mtr.h \ include/mtr0mtr.ic \ include/mtr0types.h \ - include/mysql_addons.h \ include/os0file.h \ include/os0file.ic \ include/os0proc.h \ @@ -258,7 +257,6 @@ libinnobase_a_SOURCES= \ handler/ha_innodb.cc \ handler/handler0alter.cc \ handler/i_s.cc \ - handler/mysql_addons.cc \ ibuf/ibuf0ibuf.c \ lock/lock0iter.c \ lock/lock0lock.c \ diff --git a/storage/innobase/handler/mysql_addons.cc b/storage/innobase/handler/mysql_addons.cc deleted file mode 100644 index ae6306e5db9..00000000000 --- a/storage/innobase/handler/mysql_addons.cc +++ /dev/null @@ -1,42 +0,0 @@ -/***************************************************************************** - -Copyright (c) 2007, 2009, Innobase Oy. All Rights Reserved. - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place, Suite 330, Boston, MA 02111-1307 USA - -*****************************************************************************/ - -/**************************************************//** -@file handler/mysql_addons.cc -This file contains functions that need to be added to -MySQL code but have not been added yet. - -Whenever you add a function here submit a MySQL bug -report (feature request) with the implementation. Then -write the bug number in the comment before the -function in this file. - -When MySQL commits the function it can be deleted from -here. In a perfect world this file exists but is empty. - -Created November 07, 2007 Vasil Dimov -*******************************************************/ - -#ifndef MYSQL_SERVER -#define MYSQL_SERVER -#endif /* MYSQL_SERVER */ - -#include - -#include "mysql_addons.h" -#include "univ.i" diff --git a/storage/innobase/include/mysql_addons.h b/storage/innobase/include/mysql_addons.h deleted file mode 100644 index 17660c18710..00000000000 --- a/storage/innobase/include/mysql_addons.h +++ /dev/null @@ -1,33 +0,0 @@ -/***************************************************************************** - -Copyright (c) 2007, 2009, Innobase Oy. All Rights Reserved. - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place, Suite 330, Boston, MA 02111-1307 USA - -*****************************************************************************/ - -/**************************************************//** -@file include/mysql_addons.h -This file contains functions that need to be added to -MySQL code but have not been added yet. - -Whenever you add a function here submit a MySQL bug -report (feature request) with the implementation. Then -write the bug number in the comment before the -function in this file. - -When MySQL commits the function it can be deleted from -here. In a perfect world this file exists but is empty. - -Created November 07, 2007 Vasil Dimov -*******************************************************/ diff --git a/storage/innobase/mysql-test/patches/README b/storage/innobase/mysql-test/patches/README deleted file mode 100644 index 122d756e9e3..00000000000 --- a/storage/innobase/mysql-test/patches/README +++ /dev/null @@ -1,30 +0,0 @@ -This directory contains patches that need to be applied to the MySQL -source tree in order to get the mysql-test suite to succeed (when -storage/innobase is replaced with this InnoDB branch). Things to keep -in mind when adding new patches here: - -* The patch must be appliable from the mysql top-level source directory. - -* The patch filename must end in ".diff". - -* All patches here are expected to apply cleanly to the latest MySQL 5.1 - tree when storage/innobase is replaced with this InnoDB branch. If - changes to either of those cause the patch to fail, then please check - whether the patch is still needed and, if yes, adjust it so it applies - cleanly. - -* If applicable, always submit the patch at http://bugs.mysql.com and - name the file here like bug%d.diff. Once the patch is committed to - MySQL remove the file from here. - -* If the patch cannot be proposed for inclusion in the MySQL source tree - (via http://bugs.mysql.com) then add a comment at the beginning of the - patch, explaining the problem it is solving, how it does solve it and - why it is not applicable for inclusion in the MySQL source tree. - Obviously this is a very bad situation and should be avoided at all - costs, especially for files that are in the MySQL source repository - (not in storage/innobase). - -* If you ever need to add a patch here that is not related to mysql-test - suite, then please move this directory from ./mysql-test/patches to - ./patches and remove this text. diff --git a/storage/innobase/mysql-test/patches/index_merge_innodb-explain.diff b/storage/innobase/mysql-test/patches/index_merge_innodb-explain.diff deleted file mode 100644 index d1ed8afc778..00000000000 --- a/storage/innobase/mysql-test/patches/index_merge_innodb-explain.diff +++ /dev/null @@ -1,31 +0,0 @@ -InnoDB's estimate for the index cardinality depends on a pseudo random -number generator (it picks up random pages to sample). After an -optimization that was made in r2625 the following EXPLAINs started -returning a different number of rows (3 instead of 4). - -This patch adjusts the result file. - -This patch cannot be proposed to MySQL because the failures occur only -in this tree and do not occur in the standard InnoDB 5.1. Furthermore, -the file index_merge2.inc is used by other engines too. - ---- mysql-test/r/index_merge_innodb.result.orig 2008-09-30 18:32:13.000000000 +0300 -+++ mysql-test/r/index_merge_innodb.result 2008-09-30 18:33:01.000000000 +0300 -@@ -111,7 +111,7 @@ - explain select count(*) from t1 where - key1a = 2 and key1b is null and key2a = 2 and key2b is null; - id select_type table type possible_keys key key_len ref rows Extra --1 SIMPLE t1 index_merge i1,i2 i1,i2 10,10 NULL 4 Using intersect(i1,i2); Using where; Using index -+1 SIMPLE t1 index_merge i1,i2 i1,i2 10,10 NULL 3 Using intersect(i1,i2); Using where; Using index - select count(*) from t1 where - key1a = 2 and key1b is null and key2a = 2 and key2b is null; - count(*) -@@ -119,7 +119,7 @@ - explain select count(*) from t1 where - key1a = 2 and key1b is null and key3a = 2 and key3b is null; - id select_type table type possible_keys key key_len ref rows Extra --1 SIMPLE t1 index_merge i1,i3 i1,i3 10,10 NULL 4 Using intersect(i1,i3); Using where; Using index -+1 SIMPLE t1 index_merge i1,i3 i1,i3 10,10 NULL 3 Using intersect(i1,i3); Using where; Using index - select count(*) from t1 where - key1a = 2 and key1b is null and key3a = 2 and key3b is null; - count(*) diff --git a/storage/innobase/mysql-test/patches/information_schema.diff b/storage/innobase/mysql-test/patches/information_schema.diff deleted file mode 100644 index a3a21f7a08d..00000000000 --- a/storage/innobase/mysql-test/patches/information_schema.diff +++ /dev/null @@ -1,124 +0,0 @@ ---- mysql-test/r/information_schema.result.orig 2009-01-31 03:38:50.000000000 +0200 -+++ mysql-test/r/information_schema.result 2009-01-31 07:51:58.000000000 +0200 -@@ -71,6 +71,13 @@ - TRIGGERS - USER_PRIVILEGES - VIEWS -+INNODB_CMP_RESET -+INNODB_TRX -+INNODB_CMPMEM_RESET -+INNODB_LOCK_WAITS -+INNODB_CMPMEM -+INNODB_CMP -+INNODB_LOCKS - columns_priv - db - event -@@ -799,6 +806,8 @@ - TABLES UPDATE_TIME datetime - TABLES CHECK_TIME datetime - TRIGGERS CREATED datetime -+INNODB_TRX trx_started datetime -+INNODB_TRX trx_wait_started datetime - event execute_at datetime - event last_executed datetime - event starts datetime -@@ -852,7 +861,7 @@ - flush privileges; - SELECT table_schema, count(*) FROM information_schema.TABLES WHERE table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test', 'mysqltest') AND table_name<>'ndb_binlog_index' AND table_name<>'ndb_apply_status' GROUP BY TABLE_SCHEMA; - table_schema count(*) --information_schema 28 -+information_schema 35 - mysql 22 - create table t1 (i int, j int); - create trigger trg1 before insert on t1 for each row -@@ -1267,6 +1276,13 @@ - TRIGGERS TRIGGER_SCHEMA - USER_PRIVILEGES GRANTEE - VIEWS TABLE_SCHEMA -+INNODB_CMP_RESET page_size -+INNODB_TRX trx_id -+INNODB_CMPMEM_RESET page_size -+INNODB_LOCK_WAITS requesting_trx_id -+INNODB_CMPMEM page_size -+INNODB_CMP page_size -+INNODB_LOCKS lock_id - SELECT t.table_name, c1.column_name - FROM information_schema.tables t - INNER JOIN -@@ -1310,6 +1326,13 @@ - TRIGGERS TRIGGER_SCHEMA - USER_PRIVILEGES GRANTEE - VIEWS TABLE_SCHEMA -+INNODB_CMP_RESET page_size -+INNODB_TRX trx_id -+INNODB_CMPMEM_RESET page_size -+INNODB_LOCK_WAITS requesting_trx_id -+INNODB_CMPMEM page_size -+INNODB_CMP page_size -+INNODB_LOCKS lock_id - SELECT MAX(table_name) FROM information_schema.tables WHERE table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test'); - MAX(table_name) - VIEWS -@@ -1386,6 +1409,13 @@ - FILES information_schema.FILES 1 - GLOBAL_STATUS information_schema.GLOBAL_STATUS 1 - GLOBAL_VARIABLES information_schema.GLOBAL_VARIABLES 1 -+INNODB_CMP information_schema.INNODB_CMP 1 -+INNODB_CMPMEM information_schema.INNODB_CMPMEM 1 -+INNODB_CMPMEM_RESET information_schema.INNODB_CMPMEM_RESET 1 -+INNODB_CMP_RESET information_schema.INNODB_CMP_RESET 1 -+INNODB_LOCKS information_schema.INNODB_LOCKS 1 -+INNODB_LOCK_WAITS information_schema.INNODB_LOCK_WAITS 1 -+INNODB_TRX information_schema.INNODB_TRX 1 - KEY_COLUMN_USAGE information_schema.KEY_COLUMN_USAGE 1 - PARTITIONS information_schema.PARTITIONS 1 - PLUGINS information_schema.PLUGINS 1 -diff mysql-test/r/information_schema_db.result.orig mysql-test/r/information_schema_db.result ---- mysql-test/r/information_schema_db.result.orig 2008-08-04 09:27:49.000000000 +0300 -+++ mysql-test/r/information_schema_db.result 2008-10-07 12:26:31.000000000 +0300 -@@ -33,6 +33,13 @@ - TRIGGERS - USER_PRIVILEGES - VIEWS -+INNODB_CMP_RESET -+INNODB_TRX -+INNODB_CMPMEM_RESET -+INNODB_LOCK_WAITS -+INNODB_CMPMEM -+INNODB_CMP -+INNODB_LOCKS - show tables from INFORMATION_SCHEMA like 'T%'; - Tables_in_information_schema (T%) - TABLES -diff mysql-test/r/mysqlshow.result.orig mysql-test/r/mysqlshow.result ---- mysql-test/r/mysqlshow.result.orig 2008-08-04 09:27:51.000000000 +0300 -+++ mysql-test/r/mysqlshow.result 2008-10-07 12:35:39.000000000 +0300 -@@ -107,6 +107,13 @@ - | TRIGGERS | - | USER_PRIVILEGES | - | VIEWS | -+| INNODB_CMP_RESET | -+| INNODB_TRX | -+| INNODB_CMPMEM_RESET | -+| INNODB_LOCK_WAITS | -+| INNODB_CMPMEM | -+| INNODB_CMP | -+| INNODB_LOCKS | - +---------------------------------------+ - Database: INFORMATION_SCHEMA - +---------------------------------------+ -@@ -140,6 +147,13 @@ - | TRIGGERS | - | USER_PRIVILEGES | - | VIEWS | -+| INNODB_CMP_RESET | -+| INNODB_TRX | -+| INNODB_CMPMEM_RESET | -+| INNODB_LOCK_WAITS | -+| INNODB_CMPMEM | -+| INNODB_CMP | -+| INNODB_LOCKS | - +---------------------------------------+ - Wildcard: inf_rmation_schema - +--------------------+ diff --git a/storage/innobase/mysql-test/patches/innodb_change_buffering_basic.diff b/storage/innobase/mysql-test/patches/innodb_change_buffering_basic.diff deleted file mode 100644 index bfa1609a97c..00000000000 --- a/storage/innobase/mysql-test/patches/innodb_change_buffering_basic.diff +++ /dev/null @@ -1,60 +0,0 @@ ---- mysql-test/suite/sys_vars/t/innodb_change_buffering_basic.test.orig Mon Mar 15 16:15:22 2010 -+++ mysql-test/suite/sys_vars/t/innodb_change_buffering_basic.test Fri Mar 19 01:19:09 2010 -@@ -11,8 +11,8 @@ - # - # exists as global only - # ----echo Valid values are 'inserts' and 'none' --select @@global.innodb_change_buffering in ('inserts', 'none'); -+--echo Valid values are 'inserts', 'deletes', 'changes', 'purges', 'all', and 'none' -+select @@global.innodb_change_buffering in ('inserts', 'deletes', 'changes', 'purges', 'all', 'none'); - select @@global.innodb_change_buffering; - --error ER_INCORRECT_GLOBAL_LOCAL_VAR - select @@session.innodb_change_buffering; - ---- mysql-test/suite/sys_vars/r/innodb_change_buffering_basic.result.orig Mon Mar 15 16:15:22 2010 -+++ mysql-test/suite/sys_vars/r/innodb_change_buffering_basic.result Fri Mar 19 01:23:58 2010 -@@ -1,28 +1,28 @@ - SET @start_global_value = @@global.innodb_change_buffering; - SELECT @start_global_value; - @start_global_value --inserts --Valid values are 'inserts' and 'none' --select @@global.innodb_change_buffering in ('inserts', 'none'); --@@global.innodb_change_buffering in ('inserts', 'none') -+all -+Valid values are 'inserts', 'deletes', 'changes', 'purges', 'all', and 'none' -+select @@global.innodb_change_buffering in ('inserts', 'deletes', 'changes', 'purges', 'all', 'none'); -+@@global.innodb_change_buffering in ('inserts', 'deletes', 'changes', 'purges', 'all', 'none') - 1 - select @@global.innodb_change_buffering; - @@global.innodb_change_buffering --inserts -+all - select @@session.innodb_change_buffering; - ERROR HY000: Variable 'innodb_change_buffering' is a GLOBAL variable - show global variables like 'innodb_change_buffering'; - Variable_name Value --innodb_change_buffering inserts -+innodb_change_buffering all - show session variables like 'innodb_change_buffering'; - Variable_name Value --innodb_change_buffering inserts -+innodb_change_buffering all - select * from information_schema.global_variables where variable_name='innodb_change_buffering'; - VARIABLE_NAME VARIABLE_VALUE --INNODB_CHANGE_BUFFERING inserts -+INNODB_CHANGE_BUFFERING all - select * from information_schema.session_variables where variable_name='innodb_change_buffering'; - VARIABLE_NAME VARIABLE_VALUE --INNODB_CHANGE_BUFFERING inserts -+INNODB_CHANGE_BUFFERING all - set global innodb_change_buffering='none'; - select @@global.innodb_change_buffering; - @@global.innodb_change_buffering -@@ -60,4 +60,4 @@ - SET @@global.innodb_change_buffering = @start_global_value; - SELECT @@global.innodb_change_buffering; - @@global.innodb_change_buffering --inserts -+all diff --git a/storage/innobase/mysql-test/patches/innodb_file_per_table.diff b/storage/innobase/mysql-test/patches/innodb_file_per_table.diff deleted file mode 100644 index 8b7ae2036c9..00000000000 --- a/storage/innobase/mysql-test/patches/innodb_file_per_table.diff +++ /dev/null @@ -1,47 +0,0 @@ -diff mysql-test/suite/sys_vars/t/innodb_file_per_table_basic.test.orig mysql-test/suite/sys_vars/t/innodb_file_per_table_basic.test ---- mysql-test/suite/sys_vars/t/innodb_file_per_table_basic.test.orig 2008-10-07 11:32:30.000000000 +0300 -+++ mysql-test/suite/sys_vars/t/innodb_file_per_table_basic.test 2008-10-07 11:52:14.000000000 +0300 -@@ -37,10 +37,6 @@ - # Check if Value can set # - #################################################################### - ----error ER_INCORRECT_GLOBAL_LOCAL_VAR --SET @@GLOBAL.innodb_file_per_table=1; ----echo Expected error 'Read only variable' -- - SELECT COUNT(@@GLOBAL.innodb_file_per_table); - --echo 1 Expected - -@@ -52,7 +48,7 @@ - # Check if the value in GLOBAL Table matches value in variable # - ################################################################# - --SELECT @@GLOBAL.innodb_file_per_table = VARIABLE_VALUE -+SELECT IF(@@GLOBAL.innodb_file_per_table,'ON','OFF') = VARIABLE_VALUE - FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES - WHERE VARIABLE_NAME='innodb_file_per_table'; - --echo 1 Expected -diff mysql-test/suite/sys_vars/r/innodb_file_per_table_basic.result.orig mysql-test/suite/sys_vars/r/innodb_file_per_table_basic.result ---- mysql-test/suite/sys_vars/r/innodb_file_per_table_basic.result.orig 2008-10-07 11:32:02.000000000 +0300 -+++ mysql-test/suite/sys_vars/r/innodb_file_per_table_basic.result 2008-10-07 11:52:47.000000000 +0300 -@@ -4,18 +4,15 @@ - 1 - 1 Expected - '#---------------------BS_STVARS_028_02----------------------#' --SET @@GLOBAL.innodb_file_per_table=1; --ERROR HY000: Variable 'innodb_file_per_table' is a read only variable --Expected error 'Read only variable' - SELECT COUNT(@@GLOBAL.innodb_file_per_table); - COUNT(@@GLOBAL.innodb_file_per_table) - 1 - 1 Expected - '#---------------------BS_STVARS_028_03----------------------#' --SELECT @@GLOBAL.innodb_file_per_table = VARIABLE_VALUE -+SELECT IF(@@GLOBAL.innodb_file_per_table,'ON','OFF') = VARIABLE_VALUE - FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES - WHERE VARIABLE_NAME='innodb_file_per_table'; --@@GLOBAL.innodb_file_per_table = VARIABLE_VALUE -+IF(@@GLOBAL.innodb_file_per_table,'ON','OFF') = VARIABLE_VALUE - 1 - 1 Expected - SELECT COUNT(@@GLOBAL.innodb_file_per_table); diff --git a/storage/innobase/mysql-test/patches/innodb_lock_wait_timeout.diff b/storage/innobase/mysql-test/patches/innodb_lock_wait_timeout.diff deleted file mode 100644 index bc61a0f5841..00000000000 --- a/storage/innobase/mysql-test/patches/innodb_lock_wait_timeout.diff +++ /dev/null @@ -1,55 +0,0 @@ ---- mysql-test/suite/sys_vars/t/innodb_lock_wait_timeout_basic.test.orig 2008-08-04 09:28:16.000000000 +0300 -+++ mysql-test/suite/sys_vars/t/innodb_lock_wait_timeout_basic.test 2008-10-07 11:14:15.000000000 +0300 -@@ -37,10 +37,6 @@ - # Check if Value can set # - #################################################################### - ----error ER_INCORRECT_GLOBAL_LOCAL_VAR --SET @@GLOBAL.innodb_lock_wait_timeout=1; ----echo Expected error 'Read only variable' -- - SELECT COUNT(@@GLOBAL.innodb_lock_wait_timeout); - --echo 1 Expected - -@@ -84,13 +80,9 @@ - SELECT COUNT(@@innodb_lock_wait_timeout); - --echo 1 Expected - ----Error ER_INCORRECT_GLOBAL_LOCAL_VAR - SELECT COUNT(@@local.innodb_lock_wait_timeout); ----echo Expected error 'Variable is a GLOBAL variable' - ----Error ER_INCORRECT_GLOBAL_LOCAL_VAR - SELECT COUNT(@@SESSION.innodb_lock_wait_timeout); ----echo Expected error 'Variable is a GLOBAL variable' - - SELECT COUNT(@@GLOBAL.innodb_lock_wait_timeout); - --echo 1 Expected ---- mysql-test/suite/sys_vars/r/innodb_lock_wait_timeout_basic.result.orig 2008-08-04 09:27:50.000000000 +0300 -+++ mysql-test/suite/sys_vars/r/innodb_lock_wait_timeout_basic.result 2008-10-07 11:15:14.000000000 +0300 -@@ -4,9 +4,6 @@ - 1 - 1 Expected - '#---------------------BS_STVARS_032_02----------------------#' --SET @@GLOBAL.innodb_lock_wait_timeout=1; --ERROR HY000: Variable 'innodb_lock_wait_timeout' is a read only variable --Expected error 'Read only variable' - SELECT COUNT(@@GLOBAL.innodb_lock_wait_timeout); - COUNT(@@GLOBAL.innodb_lock_wait_timeout) - 1 -@@ -39,11 +36,11 @@ - 1 - 1 Expected - SELECT COUNT(@@local.innodb_lock_wait_timeout); --ERROR HY000: Variable 'innodb_lock_wait_timeout' is a GLOBAL variable --Expected error 'Variable is a GLOBAL variable' -+COUNT(@@local.innodb_lock_wait_timeout) -+1 - SELECT COUNT(@@SESSION.innodb_lock_wait_timeout); --ERROR HY000: Variable 'innodb_lock_wait_timeout' is a GLOBAL variable --Expected error 'Variable is a GLOBAL variable' -+COUNT(@@SESSION.innodb_lock_wait_timeout) -+1 - SELECT COUNT(@@GLOBAL.innodb_lock_wait_timeout); - COUNT(@@GLOBAL.innodb_lock_wait_timeout) - 1 diff --git a/storage/innobase/mysql-test/patches/innodb_thread_concurrency_basic.diff b/storage/innobase/mysql-test/patches/innodb_thread_concurrency_basic.diff deleted file mode 100644 index 72e5457905f..00000000000 --- a/storage/innobase/mysql-test/patches/innodb_thread_concurrency_basic.diff +++ /dev/null @@ -1,31 +0,0 @@ ---- mysql-test/suite/sys_vars/r/innodb_thread_concurrency_basic.result.orig 2008-12-04 18:45:52 -06:00 -+++ mysql-test/suite/sys_vars/r/innodb_thread_concurrency_basic.result 2009-02-12 02:05:48 -06:00 -@@ -1,19 +1,19 @@ - SET @global_start_value = @@global.innodb_thread_concurrency; - SELECT @global_start_value; - @global_start_value --8 -+0 - '#--------------------FN_DYNVARS_046_01------------------------#' - SET @@global.innodb_thread_concurrency = 0; - SET @@global.innodb_thread_concurrency = DEFAULT; - SELECT @@global.innodb_thread_concurrency; - @@global.innodb_thread_concurrency --8 -+0 - '#---------------------FN_DYNVARS_046_02-------------------------#' - SET innodb_thread_concurrency = 1; - ERROR HY000: Variable 'innodb_thread_concurrency' is a GLOBAL variable and should be set with SET GLOBAL - SELECT @@innodb_thread_concurrency; - @@innodb_thread_concurrency --8 -+0 - SELECT local.innodb_thread_concurrency; - ERROR 42S02: Unknown table 'local' in field list - SET global innodb_thread_concurrency = 0; -@@ -93,4 +93,4 @@ - SET @@global.innodb_thread_concurrency = @global_start_value; - SELECT @@global.innodb_thread_concurrency; - @@global.innodb_thread_concurrency --8 -+0 diff --git a/storage/innobase/mysql-test/patches/partition_innodb.diff b/storage/innobase/mysql-test/patches/partition_innodb.diff deleted file mode 100644 index 01bc073008e..00000000000 --- a/storage/innobase/mysql-test/patches/partition_innodb.diff +++ /dev/null @@ -1,59 +0,0 @@ -The partition_innodb test only fails if run immediately after innodb_trx_weight. -The reason for this failure is that innodb_trx_weight creates deadlocks and -leaves something like this in the SHOW ENGINE INNODB STATUS output: - - ------------------------ - LATEST DETECTED DEADLOCK - ------------------------ - 090213 10:26:25 - *** (1) TRANSACTION: - TRANSACTION 313, ACTIVE 0 sec, OS thread id 13644672 inserting - mysql tables in use 1, locked 1 - LOCK WAIT 4 lock struct(s), heap size 488, 3 row lock(s) - MySQL thread id 3, query id 36 localhost root update - -The regular expressions that partition_innodb is using are intended to extract -the lock structs and row locks numbers from another part of the output: - - ------------ - TRANSACTIONS - ------------ - Trx id counter 31D - Purge done for trx's n:o < 0 undo n:o < 0 - History list length 4 - LIST OF TRANSACTIONS FOR EACH SESSION: - ---TRANSACTION 0, not started, OS thread id 13645056 - 0 lock struct(s), heap size 488, 0 row lock(s) - MySQL thread id 8, query id 81 localhost root - -In the InnoDB Plugin a transaction id is not printed as 2 consecutive -decimal integers (as it is in InnoDB 5.1) but rather as a single -hexadecimal integer. Thus the regular expressions somehow pick the wrong -part of the SHOW ENGINE INNODB STATUS output. - -So after the regular expressions are adjusted to the InnoDB Plugin's variant -of trx_id prinout, then they pick the expected part of the output. - -This patch cannot be proposed to MySQL because the failures occur only -in this tree and do not occur in the standard InnoDB 5.1. - ---- mysql-test/t/partition_innodb.test 2008-11-14 22:51:17 +0000 -+++ mysql-test/t/partition_innodb.test 2009-02-13 07:36:07 +0000 -@@ -27,14 +27,14 @@ - - # grouping/referencing in replace_regex is very slow on long strings, - # removing all before/after the interesting row before grouping/referencing ----replace_regex /.*---TRANSACTION [0-9]+ [0-9]+, .*, OS thread id [0-9]+// /MySQL thread id [0-9]+, query id [0-9]+ .*// /.*([0-9]+ lock struct\(s\)), heap size [0-9]+, ([0-9]+ row lock\(s\)).*/\1 \2/ -+--replace_regex /.*---TRANSACTION [0-9A-F]+, .*, OS thread id [0-9]+// /MySQL thread id [0-9]+, query id [0-9]+ .*// /.*([0-9]+ lock struct\(s\)), heap size [0-9]+, ([0-9]+ row lock\(s\)).*/\1 \2/ - SHOW ENGINE InnoDB STATUS; - - UPDATE t1 SET data = data*2 WHERE data = 2; - - # grouping/referencing in replace_regex is very slow on long strings, - # removing all before/after the interesting row before grouping/referencing ----replace_regex /.*---TRANSACTION [0-9]+ [0-9]+, .*, OS thread id [0-9]+// /MySQL thread id [0-9]+, query id [0-9]+ .*// /.*([0-9]+ lock struct\(s\)), heap size [0-9]+, ([0-9]+ row lock\(s\)).*/\1 \2/ -+--replace_regex /.*---TRANSACTION [0-9A-F]+, .*, OS thread id [0-9]+// /MySQL thread id [0-9]+, query id [0-9]+ .*// /.*([0-9]+ lock struct\(s\)), heap size [0-9]+, ([0-9]+ row lock\(s\)).*/\1 \2/ - SHOW ENGINE InnoDB STATUS; - - SET @@session.tx_isolation = @old_tx_isolation; - diff --git a/storage/innobase/trx/trx0i_s.c b/storage/innobase/trx/trx0i_s.c index 1ad074769c7..ab10135c6c4 100644 --- a/storage/innobase/trx/trx0i_s.c +++ b/storage/innobase/trx/trx0i_s.c @@ -38,8 +38,6 @@ Created July 17, 2007 Vasil Dimov #include -#include "mysql_addons.h" - #include "buf0buf.h" #include "dict0dict.h" #include "ha0storage.h" From d1a349325c42fd633f3f55054f47685f2087453d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 21 Oct 2010 11:30:43 +0300 Subject: [PATCH 093/304] Fix a sys_vars.all_vars failure caused by Bug #56680 instrumentation. The variable innodb_change_buffering_debug is only present in debug builds. Hide it from the test, so that the test passes in both debug and non-debug. --- mysql-test/suite/sys_vars/r/all_vars.result | 1 + mysql-test/suite/sys_vars/t/all_vars.test | 3 +++ 2 files changed, 4 insertions(+) diff --git a/mysql-test/suite/sys_vars/r/all_vars.result b/mysql-test/suite/sys_vars/r/all_vars.result index 7f6dca3eb7b..e635f1201a3 100644 --- a/mysql-test/suite/sys_vars/r/all_vars.result +++ b/mysql-test/suite/sys_vars/r/all_vars.result @@ -3,6 +3,7 @@ create table t2 (variable_name text); load data infile "MYSQLTEST_VARDIR/tmp/sys_vars.all_vars.txt" into table t1; insert into t2 select variable_name from information_schema.global_variables; insert into t2 select variable_name from information_schema.session_variables; +delete from t2 where variable_name='innodb_change_buffering_debug'; update t2 set variable_name= replace(variable_name, "PERFORMANCE_SCHEMA_", "PFS_"); select variable_name as `There should be *no* long test name listed below:` from t2 where length(variable_name) > 50; diff --git a/mysql-test/suite/sys_vars/t/all_vars.test b/mysql-test/suite/sys_vars/t/all_vars.test index e9e7e16687a..a00b7d5fbb9 100644 --- a/mysql-test/suite/sys_vars/t/all_vars.test +++ b/mysql-test/suite/sys_vars/t/all_vars.test @@ -61,6 +61,9 @@ eval load data infile "$MYSQLTEST_VARDIR/tmp/sys_vars.all_vars.txt" into table t insert into t2 select variable_name from information_schema.global_variables; insert into t2 select variable_name from information_schema.session_variables; +# This is only present in debug builds. +delete from t2 where variable_name='innodb_change_buffering_debug'; + # Performance schema variables are too long for files named # 'mysql-test/suite/sys_vars/t/' ... # ... 'performance_schema_events_waits_history_long_size_basic-master.opt' From 89e43c84943da707d72f168c48b86c41f8a05aff Mon Sep 17 00:00:00 2001 From: Dmitry Shulga Date: Thu, 21 Oct 2010 15:41:13 +0700 Subject: [PATCH 094/304] Fixed bug#45445 - cannot execute procedures with thread_stack set to 128k. sql/sp.cc: Added checking for stack overrun at functions db_load_routine/sp_find_routine. sql/sp_head.cc: sp_head::execute() modified: pass constant value STACK_MIN_SIZE instead of 8 * STACK_MIN_SIZE as second argument value in call to check_stack_overrun. Added checking for stack overrun at functions sp_lex_keeper::reset_lex_and_exec_core/sp_instr_stmt::execute. sql/sql_parse.cc: check_stack_overrun modified: allocate buffer for error message at heap instead of stack. parse_sql modified: added call to check_stack_overrun() before parsing of sql statement. --- sql/sp.cc | 6 ++++++ sql/sp_head.cc | 11 +++++++---- sql/sql_parse.cc | 18 ++++++++++++++---- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/sql/sp.cc b/sql/sp.cc index 87eb40c29ac..7385a6ffcae 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -779,6 +779,9 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, int ret= 0; + if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar*)&ret)) + return TRUE; + thd->lex= &newlex; newlex.current_select= NULL; @@ -1505,6 +1508,9 @@ sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp, (int) name->m_name.length, name->m_name.str, type, cache_only)); + if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar*)&depth)) + return NULL; + if ((sp= sp_cache_lookup(cp, name))) { ulong level; diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 1fd4e9302c4..379e81d406e 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1233,11 +1233,8 @@ sp_head::execute(THD *thd) The same with db_load_routine() required circa 7k bytes and 14k bytes accordingly. Hence, here we book the stack with some reasonable margin. - - Reverting back to 8 * STACK_MIN_SIZE until further fix. - 8 * STACK_MIN_SIZE is required on some exotic platforms. */ - if (check_stack_overrun(thd, 8 * STACK_MIN_SIZE, (uchar*)&old_packet)) + if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar*)&old_packet)) DBUG_RETURN(TRUE); /* init per-instruction memroot */ @@ -2902,6 +2899,9 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp, It's merged with the saved parent's value at the exit of this func. */ bool parent_modified_non_trans_table= thd->transaction.stmt.modified_non_trans_table; + if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar*)&parent_modified_non_trans_table)) + DBUG_RETURN(TRUE); + thd->transaction.stmt.modified_non_trans_table= FALSE; DBUG_ASSERT(!thd->derived_tables); DBUG_ASSERT(thd->change_list.is_empty()); @@ -3057,6 +3057,9 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) DBUG_ENTER("sp_instr_stmt::execute"); DBUG_PRINT("info", ("command: %d", m_lex_keeper.sql_command())); + if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar*)&res)) + DBUG_RETURN(TRUE); + query= thd->query(); query_length= thd->query_length(); #if defined(ENABLED_PROFILING) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index b322c74cb40..4ed22e3a355 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -5118,10 +5118,17 @@ bool check_stack_overrun(THD *thd, long margin, if ((stack_used=used_stack(thd->thread_stack,(char*) &stack_used)) >= (long) (my_thread_stack_size - margin)) { - char ebuff[MYSQL_ERRMSG_SIZE]; - my_snprintf(ebuff, sizeof(ebuff), ER(ER_STACK_OVERRUN_NEED_MORE), - stack_used, my_thread_stack_size, margin); - my_message(ER_STACK_OVERRUN_NEED_MORE, ebuff, MYF(ME_FATALERROR)); + /* + Do not use stack for the message buffer to ensure correct + behaviour in cases we have close to no stack left. + */ + char* ebuff= new char[MYSQL_ERRMSG_SIZE]; + if (ebuff) { + my_snprintf(ebuff, MYSQL_ERRMSG_SIZE, ER(ER_STACK_OVERRUN_NEED_MORE), + stack_used, my_thread_stack_size, margin); + my_message(ER_STACK_OVERRUN_NEED_MORE, ebuff, MYF(ME_FATALERROR)); + delete [] ebuff; + } return 1; } #ifndef DBUG_OFF @@ -7210,6 +7217,9 @@ bool parse_sql(THD *thd, Object_creation_ctx *backup_ctx= NULL; + if (check_stack_overrun(thd, 2 * STACK_MIN_SIZE, (uchar*)&backup_ctx)) + return TRUE; + if (creation_ctx) backup_ctx= creation_ctx->set_n_backup(thd); From 38f54271922aaec6e47a589fdf6d0388197c8928 Mon Sep 17 00:00:00 2001 From: Sunny Bains Date: Thu, 21 Oct 2010 22:22:27 +1100 Subject: [PATCH 095/304] Bug #57243 Inconsistent use of trans_register_ha() API in InnoDB Remove trx_t::active_trans. Split into two separate fields with distinct responsibilities. trx_t::is_registered and trx_t::owns_prepare_mutex. There are wrapper functions for using this fields in ha_innodb.cc. The wrapper functions check for invariants. Fix some formatting to conform to InnoDB guidelines. Remove innobase_register_stmt() and innobase_register_trx_and_stmt(). Add: trx_is_started() trx_deregister_from_2pc() trx_register_for_2pc() trx_is_registered_for_2pc() trx_owns_prepare_commit_mutex_set() trx_has_prepare_commit_mutex() rb://479, Approved by Jimmy Yang. --- storage/innobase/handler/ha_innodb.cc | 329 +++++++++++++------------- storage/innobase/include/trx0trx.h | 17 +- storage/innobase/trx/trx0trx.c | 7 +- 3 files changed, 186 insertions(+), 167 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index f31d92f3200..97ddbfc8199 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -32,7 +32,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA *****************************************************************************/ /* TODO list for the InnoDB handler in 5.0: - - Remove the flag trx->active_trans and look at trx->conc_state - fix savepoint functions to use savepoint storage area - Find out what kind of problems the OS X case-insensitivity causes to table and database names; should we 'normalize' the names like we do @@ -1500,7 +1499,7 @@ Gets the InnoDB transaction handle for a MySQL handler object, creates an InnoDB transaction struct if the corresponding MySQL thread struct still lacks one. @return InnoDB transaction handle */ -static +static inline trx_t* check_trx_exists( /*=============*/ @@ -1522,6 +1521,77 @@ check_trx_exists( return(trx); } +/*********************************************************************//** +Note that a transaction has been registered with MySQL. +@return true if transaction is registered with MySQL 2PC coordinator */ +static inline +bool +trx_is_registered_for_2pc( +/*=========================*/ + const trx_t* trx) /* in: transaction */ +{ + return(trx->is_registered == 1); +} + +/*********************************************************************//** +Note that a transaction owns the prepare_commit_mutex. */ +static inline +void +trx_owns_prepare_commit_mutex_set( +/*==============================*/ + trx_t* trx) /* in: transaction */ +{ + ut_a(trx_is_registered_for_2pc(trx)); + trx->owns_prepare_mutex = 1; +} + +/*********************************************************************//** +Note that a transaction has been registered with MySQL 2PC coordinator. */ +static inline +void +trx_register_for_2pc( +/*==================*/ + trx_t* trx) /* in: transaction */ +{ + trx->is_registered = 1; + ut_ad(trx->owns_prepare_mutex == 0); +} + +/*********************************************************************//** +Note that a transaction has been deregistered. */ +static inline +void +trx_deregister_from_2pc( +/*====================*/ + trx_t* trx) /* in: transaction */ +{ + trx->is_registered = 0; + trx->owns_prepare_mutex = 0; +} + +/*********************************************************************//** +Check whether atransaction owns the prepare_commit_mutex. +@return true if transaction owns the prepare commit mutex */ +static inline +bool +trx_has_prepare_commit_mutex( +/*=========================*/ + const trx_t* trx) /* in: transaction */ +{ + return(trx->owns_prepare_mutex == 1); +} + +/*********************************************************************//** +Check if transaction is started. +@reutrn true if transaction is in state started */ +static +bool +trx_is_started( +/*===========*/ + trx_t* trx) /* in: transaction */ +{ + return(trx->conc_state != TRX_NOT_STARTED); +} /*********************************************************************//** Construct ha_innobase handler. */ @@ -1585,48 +1655,31 @@ ha_innobase::update_thd() } /*********************************************************************//** -Registers that InnoDB takes part in an SQL statement, so that MySQL knows to -roll back the statement if the statement results in an error. This MUST be -called for every SQL statement that may be rolled back by MySQL. Calling this -several times to register the same statement is allowed, too. */ +Registers an InnoDB transaction with the MySQL 2PC coordinator, so that +the MySQL XA code knows to call the InnoDB prepare and commit, or rollback +for the transaction. This MUST be called for every transaction for which +the user may call commit or rollback. Calling this several times to register +the same transaction is allowed, too. This function also registers the +current SQL statement. */ static inline void -innobase_register_stmt( -/*===================*/ - handlerton* hton, /*!< in: Innobase hton */ - THD* thd) /*!< in: MySQL thd (connection) object */ +innobase_register_trx( +/*==================*/ + handlerton* hton, /* in: Innobase handlerton */ + THD* thd, /* in: MySQL thd (connection) object */ + trx_t* trx) /* in: transaction to register */ { - DBUG_ASSERT(hton == innodb_hton_ptr); - /* Register the statement */ trans_register_ha(thd, FALSE, hton); -} -/*********************************************************************//** -Registers an InnoDB transaction in MySQL, so that the MySQL XA code knows -to call the InnoDB prepare and commit, or rollback for the transaction. This -MUST be called for every transaction for which the user may call commit or -rollback. Calling this several times to register the same transaction is -allowed, too. -This function also registers the current SQL statement. */ -static inline -void -innobase_register_trx_and_stmt( -/*===========================*/ - handlerton *hton, /*!< in: Innobase handlerton */ - THD* thd) /*!< in: MySQL thd (connection) object */ -{ - /* NOTE that actually innobase_register_stmt() registers also - the transaction in the AUTOCOMMIT=1 mode. */ + if (!trx_is_registered_for_2pc(trx) + && thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) { - innobase_register_stmt(hton, thd); - - if (thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) { - - /* No autocommit mode, register for a transaction */ trans_register_ha(thd, TRUE, hton); } -} + trx_register_for_2pc(trx); +} + /* BACKGROUND INFO: HOW THE MYSQL QUERY CACHE WORKS WITH INNODB ------------------------------------------------------------ @@ -1772,14 +1825,8 @@ innobase_query_caching_of_table_permitted( #ifdef __WIN__ innobase_casedn_str(norm_name); #endif - /* The call of row_search_.. will start a new transaction if it is - not yet started */ - if (trx->active_trans == 0) { - - innobase_register_trx_and_stmt(innodb_hton_ptr, thd); - trx->active_trans = 1; - } + innobase_register_trx(innodb_hton_ptr, thd, trx); if (row_search_check_if_query_cache_permitted(trx, norm_name)) { @@ -2046,14 +2093,7 @@ ha_innobase::init_table_handle_for_HANDLER(void) trx_assign_read_view(prebuilt->trx); - /* Set the MySQL flag to mark that there is an active transaction */ - - if (prebuilt->trx->active_trans == 0) { - - innobase_register_trx_and_stmt(ht, user_thd); - - prebuilt->trx->active_trans = 1; - } + innobase_register_trx(ht, user_thd, prebuilt->trx); /* We did the necessary inits in this function, no need to repeat them in row_search_for_mysql */ @@ -2548,12 +2588,10 @@ innobase_commit_low( /*================*/ trx_t* trx) /*!< in: transaction handle */ { - if (trx->conc_state == TRX_NOT_STARTED) { + if (trx_is_started(trx)) { - return; + trx_commit_for_mysql(trx); } - - trx_commit_for_mysql(trx); } /*****************************************************************//** @@ -2595,10 +2633,7 @@ innobase_start_trx_and_assign_read_view( /* Set the MySQL flag to mark that there is an active transaction */ - if (trx->active_trans == 0) { - innobase_register_trx_and_stmt(hton, thd); - trx->active_trans = 1; - } + innobase_register_trx(hton, current_thd, trx); DBUG_RETURN(0); } @@ -2632,29 +2667,19 @@ innobase_commit( trx_search_latch_release_if_reserved(trx); } - /* The flag trx->active_trans is set to 1 in + /* Transaction is deregistered only in a commit or a rollback. If + it is deregistered we know there cannot be resources to be freed + and we could return immediately. For the time being, we play safe + and do the cleanup though there should be nothing to clean up. */ - 1. ::external_lock(), - 2. ::start_stmt(), - 3. innobase_query_caching_of_table_permitted(), - 4. innobase_savepoint(), - 5. ::init_table_handle_for_HANDLER(), - 6. innobase_start_trx_and_assign_read_view(), - 7. ::transactional_table_lock() + if (!trx_is_registered_for_2pc(trx) && trx_is_started(trx)) { - and it is only set to 0 in a commit or a rollback. If it is 0 we know - there cannot be resources to be freed and we could return immediately. - For the time being, we play safe and do the cleanup though there should - be nothing to clean up. */ - - if (trx->active_trans == 0 - && trx->conc_state != TRX_NOT_STARTED) { - - sql_print_error("trx->active_trans == 0, but" - " trx->conc_state != TRX_NOT_STARTED"); + sql_print_error("Transaction not registered for MySQL 2PC, " + "but transaction is active"); } + if (all - || (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) { + || (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) { /* We were instructed to commit the whole transaction, or this is an SQL statement end and autocommit is on */ @@ -2709,15 +2734,15 @@ retry: mysql_mutex_unlock(&commit_cond_m); } - if (trx->active_trans == 2) { - + if (trx_has_prepare_commit_mutex(trx)) { + mysql_mutex_unlock(&prepare_commit_mutex); - } + } + + trx_deregister_from_2pc(trx); /* Now do a write + flush of logs. */ trx_commit_complete_for_mysql(trx); - trx->active_trans = 0; - } else { /* We just mark the SQL statement ended and do not do a transaction commit */ @@ -2786,10 +2811,10 @@ innobase_rollback( row_unlock_table_autoinc_for_mysql(trx); if (all - || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) { + || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) { error = trx_rollback_for_mysql(trx); - trx->active_trans = 0; + trx_deregister_from_2pc(trx); } else { error = trx_rollback_last_sql_stat_for_mysql(trx); } @@ -2932,8 +2957,8 @@ innobase_savepoint( innobase_release_stat_resources(trx); - /* cannot happen outside of transaction */ - DBUG_ASSERT(trx->active_trans); + /* Cannot happen outside of transaction */ + DBUG_ASSERT(trx_is_registered_for_2pc(trx)); /* TODO: use provided savepoint data area to store savepoint data */ char name[64]; @@ -2963,16 +2988,15 @@ innobase_close_connection( ut_a(trx); - if (trx->active_trans == 0 - && trx->conc_state != TRX_NOT_STARTED) { + if (!trx_is_registered_for_2pc(trx) && trx_is_started(trx)) { - sql_print_error("trx->active_trans == 0, but" - " trx->conc_state != TRX_NOT_STARTED"); + sql_print_error("Transaction not registered for MySQL 2PC, " + "but transaction is active"); } - if (trx->conc_state != TRX_NOT_STARTED && - global_system_variables.log_warnings) { + if (trx_is_started(trx) && global_system_variables.log_warnings) { + sql_print_warning( "MySQL is closing a connection that has an active " "InnoDB transaction. %llu row modifications will " @@ -4872,7 +4896,7 @@ no_commit: /* Altering to InnoDB format */ innobase_commit(ht, user_thd, 1); /* Note that this transaction is still active. */ - prebuilt->trx->active_trans = 1; + trx_register_for_2pc(prebuilt->trx); /* We will need an IX lock on the destination table. */ prebuilt->sql_stat_start = TRUE; } else { @@ -4888,7 +4912,7 @@ no_commit: locks, so they have to be acquired again. */ innobase_commit(ht, user_thd, 1); /* Note that this transaction is still active. */ - prebuilt->trx->active_trans = 1; + trx_register_for_2pc(prebuilt->trx); /* Re-acquire the table lock on the source table. */ row_lock_table_for_mysql(prebuilt, src_table, mode); /* We will need an IX lock on the destination table. */ @@ -8700,39 +8724,30 @@ ha_innobase::start_stmt( prepared for an update of a row */ prebuilt->select_lock_type = LOCK_X; + + } else if (trx->isolation_level != TRX_ISO_SERIALIZABLE + && thd_sql_command(thd) == SQLCOM_SELECT + && lock_type == TL_READ) { + + /* For other than temporary tables, we obtain + no lock for consistent read (plain SELECT). */ + + prebuilt->select_lock_type = LOCK_NONE; } else { - if (trx->isolation_level != TRX_ISO_SERIALIZABLE - && thd_sql_command(thd) == SQLCOM_SELECT - && lock_type == TL_READ) { + /* Not a consistent read: restore the + select_lock_type value. The value of + stored_select_lock_type was decided in: + 1) ::store_lock(), + 2) ::external_lock(), + 3) ::init_table_handle_for_HANDLER(), and + 4) ::transactional_table_lock(). */ - /* For other than temporary tables, we obtain - no lock for consistent read (plain SELECT). */ - - prebuilt->select_lock_type = LOCK_NONE; - } else { - /* Not a consistent read: restore the - select_lock_type value. The value of - stored_select_lock_type was decided in: - 1) ::store_lock(), - 2) ::external_lock(), - 3) ::init_table_handle_for_HANDLER(), and - 4) ::transactional_table_lock(). */ - - prebuilt->select_lock_type = - prebuilt->stored_select_lock_type; - } + prebuilt->select_lock_type = prebuilt->stored_select_lock_type; } - trx->detailed_error[0] = '\0'; + *trx->detailed_error = 0; - /* Set the MySQL flag to mark that there is an active transaction */ - if (trx->active_trans == 0) { - - innobase_register_trx_and_stmt(ht, thd); - trx->active_trans = 1; - } else { - innobase_register_stmt(ht, thd); - } + innobase_register_trx(ht, thd, trx); return(0); } @@ -8821,22 +8836,14 @@ ha_innobase::external_lock( if (lock_type != F_UNLCK) { /* MySQL is setting a new table lock */ - trx->detailed_error[0] = '\0'; + *trx->detailed_error = 0; - /* Set the MySQL flag to mark that there is an active - transaction */ - if (trx->active_trans == 0) { - - innobase_register_trx_and_stmt(ht, thd); - trx->active_trans = 1; - } else if (trx->n_mysql_tables_in_use == 0) { - innobase_register_stmt(ht, thd); - } + innobase_register_trx(ht, thd, trx); if (trx->isolation_level == TRX_ISO_SERIALIZABLE - && prebuilt->select_lock_type == LOCK_NONE - && thd_test_options(thd, - OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) { + && prebuilt->select_lock_type == LOCK_NONE + && thd_test_options( + thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) { /* To get serializable execution, we let InnoDB conceptually add 'LOCK IN SHARE MODE' to all SELECTs @@ -8906,19 +8913,20 @@ ha_innobase::external_lock( trx->mysql_n_tables_locked = 0; prebuilt->used_in_HANDLER = FALSE; - if (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) { - if (trx->active_trans != 0) { + if (!thd_test_options( + thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) { + + if (trx_is_started(trx)) { innobase_commit(ht, thd, TRUE); } - } else { - if (trx->isolation_level <= TRX_ISO_READ_COMMITTED - && trx->global_read_view) { - /* At low transaction isolation levels we let - each consistent read set its own snapshot */ + } else if (trx->isolation_level <= TRX_ISO_READ_COMMITTED + && trx->global_read_view) { - read_view_close_for_mysql(trx); - } + /* At low transaction isolation levels we let + each consistent read set its own snapshot */ + + read_view_close_for_mysql(trx); } } @@ -8987,12 +8995,7 @@ ha_innobase::transactional_table_lock( /* MySQL is setting a new transactional table lock */ - /* Set the MySQL flag to mark that there is an active transaction */ - if (trx->active_trans == 0) { - - innobase_register_trx_and_stmt(ht, thd); - trx->active_trans = 1; - } + innobase_register_trx(ht, thd, trx); if (THDVAR(thd, table_locks) && thd_in_lock_tables(thd)) { ulint error = DB_SUCCESS; @@ -9005,7 +9008,8 @@ ha_innobase::transactional_table_lock( DBUG_RETURN((int) error); } - if (thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) { + if (thd_test_options( + thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) { /* Store the current undo_no of the transaction so that we know where to roll back if we have @@ -10046,19 +10050,19 @@ innobase_xa_prepare( innobase_release_stat_resources(trx); - if (trx->active_trans == 0 && trx->conc_state != TRX_NOT_STARTED) { + if (!trx_is_registered_for_2pc(trx) && trx_is_started(trx)) { - sql_print_error("trx->active_trans == 0, but trx->conc_state != " - "TRX_NOT_STARTED"); + sql_print_error("Transaction not registered for MySQL 2PC, " + "but transaction is active"); } if (all - || (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) { + || (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) { /* We were instructed to prepare the whole transaction, or this is an SQL statement end and autocommit is on */ - ut_ad(trx->active_trans); + ut_ad(trx_is_registered_for_2pc(trx)); error = (int) trx_prepare_for_mysql(trx); } else { @@ -10082,9 +10086,10 @@ innobase_xa_prepare( srv_active_wake_master_thread(); - if (thd_sql_command(thd) != SQLCOM_XA_PREPARE && - (all || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) - { + if (thd_sql_command(thd) != SQLCOM_XA_PREPARE + && (all + || !thd_test_options( + thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) { /* For ibbackup to work the order of transactions in binlog and InnoDB must be the same. Consider the situation @@ -10105,7 +10110,7 @@ innobase_xa_prepare( will be between XA PREPARE and XA COMMIT, and we don't want to block for undefined period of time. */ mysql_mutex_lock(&prepare_commit_mutex); - trx->active_trans = 2; + trx_owns_prepare_commit_mutex_set(trx); } return(error); @@ -10140,8 +10145,8 @@ static int innobase_commit_by_xid( /*===================*/ - handlerton *hton, - XID* xid) /*!< in: X/Open XA transaction identification */ + handlerton* hton, + XID* xid) /*!< in: X/Open XA transaction identification */ { trx_t* trx; diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index 6a817ccdc8e..b4a4aa0ca44 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -470,6 +470,20 @@ struct trx_struct{ of view of concurrency control: TRX_ACTIVE, TRX_COMMITTED_IN_MEMORY, ... */ + /*------------------------------*/ + /* MySQL has a transaction coordinator to coordinate two phase + commit between multiple storage engines and the binary log. When + an engine participates in a transaction, it's responsible for + registering itself using the trans_register_ha() API. */ + unsigned is_registered:1;/* This flag is set to 1 after the + transaction has been registered with + the coordinator using the XA API, and + is set to 0 after commit or rollback. */ + unsigned owns_prepare_mutex:1;/* 1 if owns prepare mutex, if + this is set to 1 then registered should + also be set to 1. This is used in the + XA code */ + /*------------------------------*/ ulint isolation_level;/* TRX_ISO_REPEATABLE_READ, ... */ ulint check_foreigns; /* normally TRUE, but if the user wants to suppress foreign key checks, @@ -500,9 +514,6 @@ struct trx_struct{ in that case we must flush the log in trx_commit_complete_for_mysql() */ ulint duplicates; /*!< TRX_DUP_IGNORE | TRX_DUP_REPLACE */ - ulint active_trans; /*!< 1 - if a transaction in MySQL - is active. 2 - if prepare_commit_mutex - was taken */ ulint has_search_latch; /* TRUE if this trx has latched the search system latch in S-mode */ diff --git a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c index 6ef47a8dc16..6bae0527b53 100644 --- a/storage/innobase/trx/trx0trx.c +++ b/storage/innobase/trx/trx0trx.c @@ -105,7 +105,11 @@ trx_create( trx->is_purge = 0; trx->is_recovered = 0; trx->conc_state = TRX_NOT_STARTED; - trx->start_time = time(NULL); + + trx->is_registered = 0; + trx->owns_prepare_mutex = 0; + + trx->start_time = ut_time(); trx->isolation_level = TRX_ISO_REPEATABLE_READ; @@ -124,7 +128,6 @@ trx_create( trx->table_id = 0; trx->mysql_thd = NULL; - trx->active_trans = 0; trx->duplicates = 0; trx->n_mysql_tables_in_use = 0; From 909f0bf94a5bd5879fc9cf2be11b5c0cf20caed3 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Thu, 21 Oct 2010 15:20:50 +0200 Subject: [PATCH 096/304] Follow-up to Bug #55582 which allows checking strings in if Simplified cases where a select was used to compare variable against '' --- .../extra/rpl_tests/rpl_get_master_version_and_clock.test | 2 +- mysql-test/extra/rpl_tests/rpl_loaddata.test | 2 +- mysql-test/include/check_concurrent_insert.inc | 4 ++-- mysql-test/include/check_no_concurrent_insert.inc | 4 ++-- mysql-test/include/get_relay_log_pos.inc | 4 ++-- mysql-test/include/kill_query.inc | 4 ++-- mysql-test/include/kill_query_and_diff_master_slave.inc | 8 ++++---- mysql-test/include/setup_fake_relay_log.inc | 2 +- mysql-test/include/show_binlog_events.inc | 4 ++-- mysql-test/include/show_rpl_debug_info.inc | 6 +++--- mysql-test/include/wait_for_slave_io_error.inc | 2 +- mysql-test/include/wait_for_slave_param.inc | 4 ++-- mysql-test/include/wait_for_slave_sql_error.inc | 2 +- mysql-test/include/wait_for_status_var.inc | 2 +- mysql-test/suite/rpl/t/rpl_killed_ddl.test | 2 +- 15 files changed, 26 insertions(+), 26 deletions(-) diff --git a/mysql-test/extra/rpl_tests/rpl_get_master_version_and_clock.test b/mysql-test/extra/rpl_tests/rpl_get_master_version_and_clock.test index 66bd61a8ea9..40e155bc314 100644 --- a/mysql-test/extra/rpl_tests/rpl_get_master_version_and_clock.test +++ b/mysql-test/extra/rpl_tests/rpl_get_master_version_and_clock.test @@ -34,7 +34,7 @@ # connection slave; -if (`SELECT $debug_sync_action = ''`) +if (!$debug_sync_action) { --die Cannot continue. Please set value for debug_sync_action. } diff --git a/mysql-test/extra/rpl_tests/rpl_loaddata.test b/mysql-test/extra/rpl_tests/rpl_loaddata.test index 1ae17398596..84419ec9cc5 100644 --- a/mysql-test/extra/rpl_tests/rpl_loaddata.test +++ b/mysql-test/extra/rpl_tests/rpl_loaddata.test @@ -24,7 +24,7 @@ connection master; # MTR is not case-sensitive. let $lower_stmt_head= load data; let $UPPER_STMT_HEAD= LOAD DATA; -if (`SELECT '$lock_option' <> ''`) +if ($lock_option) { #if $lock_option is null, an extra blank is added into the statement, #this will change the result of rpl_loaddata test case. so $lock_option diff --git a/mysql-test/include/check_concurrent_insert.inc b/mysql-test/include/check_concurrent_insert.inc index f4bec3c9cdb..62de485d8f1 100644 --- a/mysql-test/include/check_concurrent_insert.inc +++ b/mysql-test/include/check_concurrent_insert.inc @@ -23,7 +23,7 @@ # Reset DEBUG_SYNC facility for safety. set debug_sync= "RESET"; -if (`SELECT '$restore_table' <> ''`) +if ($restore_table) { --eval create temporary table t_backup select * from $restore_table; } @@ -82,7 +82,7 @@ connection default; --eval delete from $table where i = 0; -if (`SELECT '$restore_table' <> ''`) +if ($restore_table) { --eval truncate table $restore_table; --eval insert into $restore_table select * from t_backup; diff --git a/mysql-test/include/check_no_concurrent_insert.inc b/mysql-test/include/check_no_concurrent_insert.inc index f60401bcad1..6938c53fd16 100644 --- a/mysql-test/include/check_no_concurrent_insert.inc +++ b/mysql-test/include/check_no_concurrent_insert.inc @@ -23,7 +23,7 @@ # Reset DEBUG_SYNC facility for safety. set debug_sync= "RESET"; -if (`SELECT '$restore_table' <> ''`) +if ($restore_table) { --eval create temporary table t_backup select * from $restore_table; } @@ -67,7 +67,7 @@ if (!$success) --eval delete from $table where i = 0; -if (`SELECT '$restore_table' <> ''`) +if ($restore_table) { --eval truncate table $restore_table; --eval insert into $restore_table select * from t_backup; diff --git a/mysql-test/include/get_relay_log_pos.inc b/mysql-test/include/get_relay_log_pos.inc index 7ce36fd3c50..61ee07fc655 100644 --- a/mysql-test/include/get_relay_log_pos.inc +++ b/mysql-test/include/get_relay_log_pos.inc @@ -10,12 +10,12 @@ # # at this point, get_relay_log_pos.inc sets $relay_log_pos. echo position # # in $relay_log_file: $relay_log_pos. -if (`SELECT '$relay_log_file' = ''`) +if (!$relay_log_file) { --die 'variable $relay_log_file is null' } -if (`SELECT '$master_log_pos' = ''`) +if (!$master_log_pos) { --die 'variable $master_log_pos is null' } diff --git a/mysql-test/include/kill_query.inc b/mysql-test/include/kill_query.inc index b303ed0ec39..1c949d3cbad 100644 --- a/mysql-test/include/kill_query.inc +++ b/mysql-test/include/kill_query.inc @@ -44,7 +44,7 @@ connection master; # kill the query that is waiting eval kill query $connection_id; -if (`SELECT '$debug_lock' != ''`) +if ($debug_lock) { # release the lock to allow binlog continue eval SELECT RELEASE_LOCK($debug_lock); @@ -57,7 +57,7 @@ reap; connection master; -if (`SELECT '$debug_lock' != ''`) +if ($debug_lock) { # get lock again to make the next query wait eval SELECT GET_LOCK($debug_lock, 10); diff --git a/mysql-test/include/kill_query_and_diff_master_slave.inc b/mysql-test/include/kill_query_and_diff_master_slave.inc index 611d6929c99..b3846d12df1 100644 --- a/mysql-test/include/kill_query_and_diff_master_slave.inc +++ b/mysql-test/include/kill_query_and_diff_master_slave.inc @@ -25,7 +25,7 @@ source include/kill_query.inc; connection master; disable_query_log; disable_result_log; -if (`SELECT '$debug_lock' != ''`) +if ($debug_lock) { eval SELECT RELEASE_LOCK($debug_lock); } @@ -36,8 +36,8 @@ source include/diff_master_slave.inc; # Acquire the debug lock again if used connection master; -disable_query_log; disable_result_log; if (`SELECT '$debug_lock' != -''`) { eval SELECT GET_LOCK($debug_lock, 10); } enable_result_log; -enable_query_log; +disable_query_log; disable_result_log; +if ($debug_lock) { eval SELECT GET_LOCK($debug_lock, 10); } +enable_result_log; enable_query_log; connection $connection_name; diff --git a/mysql-test/include/setup_fake_relay_log.inc b/mysql-test/include/setup_fake_relay_log.inc index fb035941a29..f881f3bf4e8 100644 --- a/mysql-test/include/setup_fake_relay_log.inc +++ b/mysql-test/include/setup_fake_relay_log.inc @@ -56,7 +56,7 @@ if (`SELECT "$_sql_running" = "Yes" OR "$_io_running" = "Yes"`) { # Read server variables. let $MYSQLD_DATADIR= `SELECT @@datadir`; let $_fake_filename= query_get_value(SHOW VARIABLES LIKE 'relay_log', Value, 1); -if (`SELECT '$_fake_filename' = ''`) { +if (!$_fake_filename) { --echo Badly written test case: relay_log variable is empty. Please use the --echo server option --relay-log=FILE. } diff --git a/mysql-test/include/show_binlog_events.inc b/mysql-test/include/show_binlog_events.inc index 8649f31ad9f..6d8c8196102 100644 --- a/mysql-test/include/show_binlog_events.inc +++ b/mysql-test/include/show_binlog_events.inc @@ -27,14 +27,14 @@ if (!$binlog_start) } --let $_statement=show binlog events -if (`SELECT '$binlog_file' <> ''`) +if ($binlog_file) { --let $_statement= $_statement in '$binlog_file' } --let $_statement= $_statement from $binlog_start -if (`SELECT '$binlog_limit' <> ''`) +if ($binlog_limit) { --let $_statement= $_statement limit $binlog_limit } diff --git a/mysql-test/include/show_rpl_debug_info.inc b/mysql-test/include/show_rpl_debug_info.inc index 148d11f3b02..9944e6cd25f 100644 --- a/mysql-test/include/show_rpl_debug_info.inc +++ b/mysql-test/include/show_rpl_debug_info.inc @@ -48,13 +48,13 @@ let $binlog_name= query_get_value("SHOW MASTER STATUS", File, 1); eval SHOW BINLOG EVENTS IN '$binlog_name'; let $_master_con= $master_connection; -if (`SELECT '$_master_con' = ''`) +if (!$_master_con) { if (`SELECT '$_con' = 'slave'`) { let $_master_con= master; } - if (`SELECT '$_master_con' = ''`) + if (!$_master_con) { --echo Unable to determine master connection. No debug info printed for master. --echo Please fix the test case by setting $master_connection before sourcing @@ -62,7 +62,7 @@ if (`SELECT '$_master_con' = ''`) } } -if (`SELECT '$_master_con' != ''`) +if ($_master_con) { let $master_binlog_name_io= query_get_value("SHOW SLAVE STATUS", Master_Log_File, 1); diff --git a/mysql-test/include/wait_for_slave_io_error.inc b/mysql-test/include/wait_for_slave_io_error.inc index 34cbf20a73b..ffdcf752873 100644 --- a/mysql-test/include/wait_for_slave_io_error.inc +++ b/mysql-test/include/wait_for_slave_io_error.inc @@ -31,7 +31,7 @@ # $master_connection # See wait_for_slave_param.inc for description. -if (`SELECT '$slave_io_errno' = ''`) { +if (!$slave_io_errno) { --die !!!ERROR IN TEST: you must set \$slave_io_errno before sourcing wait_for_slave_io_error.inc } diff --git a/mysql-test/include/wait_for_slave_param.inc b/mysql-test/include/wait_for_slave_param.inc index ef864f9245e..98cd426fa11 100644 --- a/mysql-test/include/wait_for_slave_param.inc +++ b/mysql-test/include/wait_for_slave_param.inc @@ -51,7 +51,7 @@ if (!$_slave_timeout_counter) } let $_slave_param_comparison= $slave_param_comparison; -if (`SELECT '$_slave_param_comparison' = ''`) +if (!$_slave_param_comparison) { let $_slave_param_comparison= =; } @@ -71,7 +71,7 @@ while (`SELECT NOT('$_show_slave_status_value' $_slave_param_comparison '$slave_ if (!$_slave_timeout_counter) { --echo **** ERROR: timeout after $slave_timeout seconds while waiting for slave parameter $slave_param $_slave_param_comparison $slave_param_value **** - if (`SELECT '$slave_error_message' != ''`) + if ($slave_error_message) { --echo Message: $slave_error_message } diff --git a/mysql-test/include/wait_for_slave_sql_error.inc b/mysql-test/include/wait_for_slave_sql_error.inc index aab04036eea..80836f908c6 100644 --- a/mysql-test/include/wait_for_slave_sql_error.inc +++ b/mysql-test/include/wait_for_slave_sql_error.inc @@ -24,7 +24,7 @@ # $master_connection # See wait_for_slave_param.inc for description. -if (`SELECT '$slave_sql_errno' = ''`) { +if (!$slave_sql_errno) { --die !!!ERROR IN TEST: you must set \$slave_sql_errno before sourcing wait_for_slave_sql_error.inc } diff --git a/mysql-test/include/wait_for_status_var.inc b/mysql-test/include/wait_for_status_var.inc index 8b644c2c3c5..9f4962aeaed 100644 --- a/mysql-test/include/wait_for_status_var.inc +++ b/mysql-test/include/wait_for_status_var.inc @@ -45,7 +45,7 @@ if (!$_status_timeout_counter) } let $_status_var_comparsion= $status_var_comparsion; -if (`SELECT '$_status_var_comparsion' = ''`) +if (!$_status_var_comparsion) { let $_status_var_comparsion= =; } diff --git a/mysql-test/suite/rpl/t/rpl_killed_ddl.test b/mysql-test/suite/rpl/t/rpl_killed_ddl.test index 61b882efcf3..69648267ca4 100644 --- a/mysql-test/suite/rpl/t/rpl_killed_ddl.test +++ b/mysql-test/suite/rpl/t/rpl_killed_ddl.test @@ -119,7 +119,7 @@ echo [on master]; # This will block the execution of a statement at the DBUG_SYNC_POINT # with given lock name -if (`SELECT '$debug_lock' != ''`) +if ($debug_lock) { disable_query_log; disable_result_log; From 6c1d9fd9a90117a1f8e605ec881d890618b51ac9 Mon Sep 17 00:00:00 2001 From: Calvin Sun Date: Thu, 21 Oct 2010 12:29:00 -0500 Subject: [PATCH 097/304] Fix an error introduced in a follow-up fix of Bug#57232 by Sunny Bains revno: 3185 revid: sunny.bains@oracle.com-20101018060544-wo81q6kbl3la1uq0 --- storage/innobase/os/os0sync.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/innobase/os/os0sync.c b/storage/innobase/os/os0sync.c index 5c400ae31c5..65fdd49f839 100644 --- a/storage/innobase/os/os0sync.c +++ b/storage/innobase/os/os0sync.c @@ -136,7 +136,7 @@ os_cond_wait_timed( #ifndef __WIN__ const struct timespec* abstime /*!< in: timeout */ #else - ulint time_in_ms /*!< in: timeout in + DWORD time_in_ms /*!< in: timeout in milliseconds*/ #endif /* !__WIN__ */ ) @@ -655,7 +655,7 @@ os_event_wait_time_low( ut_a(event); if (time_in_usec != OS_SYNC_INFINITE_TIME) { - time_in_ms = time_in_ms / 1000; + time_in_ms = time_in_usec / 1000; err = WaitForSingleObject(event->handle, time_in_ms); } else { err = WaitForSingleObject(event->handle, INFINITE); From 1291c004775458f2f35e24730c9694f99b5b54d7 Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Thu, 21 Oct 2010 23:34:57 -0700 Subject: [PATCH 098/304] Fix Bug #56791 Remove ios_mutex from InnoDB code rb://495 approved by Inaam --- storage/innobase/handler/ha_innodb.cc | 1 - storage/innobase/include/sync0sync.h | 1 - storage/innobase/srv/srv0start.c | 18 ------------------ 3 files changed, 20 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 97ddbfc8199..74c83e8d44b 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -240,7 +240,6 @@ static PSI_mutex_info all_innodb_mutexes[] = { {&ibuf_mutex_key, "ibuf_mutex", 0}, {&ibuf_pessimistic_insert_mutex_key, "ibuf_pessimistic_insert_mutex", 0}, - {&ios_mutex_key, "ios_mutex", 0}, {&kernel_mutex_key, "kernel_mutex", 0}, {&log_sys_mutex_key, "log_sys_mutex", 0}, # ifdef UNIV_MEM_DEBUG diff --git a/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync0sync.h index 940e583350a..fb3a24c5ee5 100644 --- a/storage/innobase/include/sync0sync.h +++ b/storage/innobase/include/sync0sync.h @@ -85,7 +85,6 @@ extern mysql_pfs_key_t hash_table_mutex_key; extern mysql_pfs_key_t ibuf_bitmap_mutex_key; extern mysql_pfs_key_t ibuf_mutex_key; extern mysql_pfs_key_t ibuf_pessimistic_insert_mutex_key; -extern mysql_pfs_key_t ios_mutex_key; extern mysql_pfs_key_t log_sys_mutex_key; extern mysql_pfs_key_t log_flush_order_mutex_key; extern mysql_pfs_key_t kernel_mutex_key; diff --git a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c index 67586de736c..d7ea3d5d3da 100644 --- a/storage/innobase/srv/srv0start.c +++ b/storage/innobase/srv/srv0start.c @@ -120,11 +120,6 @@ UNIV_INTERN enum srv_shutdown_state srv_shutdown_state = SRV_SHUTDOWN_NONE; /** Files comprising the system tablespace */ static os_file_t files[1000]; -/** Mutex protecting the ios count */ -static mutex_t ios_mutex; -/** Count of I/O operations in io_handler_thread() */ -static ulint ios; - /** io_handler_thread parameters for thread identification */ static ulint n[SRV_MAX_N_IO_THREADS + 6]; /** io_handler_thread identifiers */ @@ -152,11 +147,6 @@ UNIV_INTERN mysql_pfs_key_t srv_master_thread_key; UNIV_INTERN mysql_pfs_key_t srv_purge_thread_key; #endif /* UNIV_PFS_THREAD */ -#ifdef UNIV_PFS_MUTEX -/* Key to register ios_mutex_key with performance schema */ -UNIV_INTERN mysql_pfs_key_t ios_mutex_key; -#endif /* UNIV_PFS_MUTEX */ - /*********************************************************************//** Convert a numeric string that optionally ends in G or M, to a number containing megabytes. @@ -491,10 +481,6 @@ io_handler_thread( while (srv_shutdown_state != SRV_SHUTDOWN_EXIT_THREADS) { fil_aio_wait(segment); - - mutex_enter(&ios_mutex); - ios++; - mutex_exit(&ios_mutex); } /* We count the number of threads in os_thread_exit(). A created @@ -998,10 +984,6 @@ skip_size_check: srv_data_file_is_raw_partition[i] != 0); } - ios = 0; - - mutex_create(ios_mutex_key, &ios_mutex, SYNC_NO_ORDER_CHECK); - return(DB_SUCCESS); } From d63cbdde8e55399c1a5e677aab1cc22a35519a42 Mon Sep 17 00:00:00 2001 From: "Horst.Hunger" Date: Fri, 22 Oct 2010 10:20:17 +0200 Subject: [PATCH 099/304] Due to issues with merge. --- mysql-test/r/plugin_auth_qa_2.result | 18 +++++++++--------- mysql-test/r/plugin_auth_qa_3.result | 4 ++-- mysql-test/t/plugin_auth_qa_1.test | 18 ++++++++++++------ mysql-test/t/plugin_auth_qa_2.test | 18 +++++++++--------- mysql-test/t/plugin_auth_qa_3.test | 4 ++-- 5 files changed, 34 insertions(+), 28 deletions(-) diff --git a/mysql-test/r/plugin_auth_qa_2.result b/mysql-test/r/plugin_auth_qa_2.result index a73cc25418c..daefdaafabc 100644 --- a/mysql-test/r/plugin_auth_qa_2.result +++ b/mysql-test/r/plugin_auth_qa_2.result @@ -15,7 +15,7 @@ NULL SELECT @@external_user; @@external_user NULL -exec MYSQL PLUGIN_AUTH_OPT -h localhost -P 13000 -u qa_test_1_user --password=qa_test_1_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT -u qa_test_1_user --password=qa_test_1_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 current_user() user() @@local.proxy_user @@local.external_user qa_test_1_user@% qa_test_1_user@localhost NULL NULL SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; @@ -42,7 +42,7 @@ NULL SELECT @@external_user; @@external_user NULL -exec MYSQL PLUGIN_AUTH_OPT -h localhost -P 13000 -u qa_test_2_user --password=qa_test_2_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT -u qa_test_2_user --password=qa_test_2_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 current_user() user() @@local.proxy_user @@local.external_user authenticated_as@% user_name@localhost 'qa_test_2_user'@'%' 'qa_test_2_user'@'%' SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; @@ -58,7 +58,7 @@ CREATE USER qa_test_3_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_3_dest' CREATE USER qa_test_3_dest IDENTIFIED BY 'dest_passwd'; GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_3_dest identified by 'dest_passwd'; GRANT PROXY ON qa_test_3_dest TO qa_test_3_user; -exec MYSQL PLUGIN_AUTH_OPT -h localhost -P 13000 -u qa_test_3_user --password=qa_test_3_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT -u qa_test_3_user --password=qa_test_3_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 current_user() user() @@local.proxy_user @@local.external_user qa_test_3_dest@% qa_test_3_user@localhost 'qa_test_3_user'@'%' 'qa_test_3_user'@'%' DROP USER qa_test_3_user; @@ -68,7 +68,7 @@ CREATE USER qa_test_4_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_4_dest' CREATE USER qa_test_4_dest IDENTIFIED BY 'dest_passwd'; GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_4_dest identified by 'dest_passwd'; GRANT PROXY ON qa_test_4_dest TO qa_test_4_user; -exec MYSQL PLUGIN_AUTH_OPT -h localhost -P 13000 -u qa_test_4_user --password=qa_test_4_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT -u qa_test_4_user --password=qa_test_4_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 current_user() user() @@local.proxy_user @@local.external_user qa_test_4_dest@% qa_test_4_user@localhost 'qa_test_4_user'@'%' 'qa_test_4_user'@'%' DROP USER qa_test_4_user; @@ -86,7 +86,7 @@ user plugin authentication_string password *DFCACE76914AD7BD801FC1A1ECF6562272621A22 qa_test_5_user qa_auth_interface qa_test_5_dest qa_test_5_dest *DFCACE76914AD7BD801FC1A1ECF6562272621A22 -exec MYSQL PLUGIN_AUTH_OPT -h localhost -P 13000 --user=qa_test_5_user --password=qa_test_5_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=qa_test_5_user --password=qa_test_5_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 ERROR 1045 (28000): Access denied for user 'qa_test_5_user'@'localhost' (using password: YES) DROP USER qa_test_5_user; DROP USER qa_test_5_dest; @@ -103,7 +103,7 @@ root root qa_test_6_user qa_auth_interface qa_test_6_dest qa_test_6_dest *DFCACE76914AD7BD801FC1A1ECF6562272621A22 -exec MYSQL PLUGIN_AUTH_OPT -h localhost -P 13000 --user=qa_test_6_user --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=qa_test_6_user --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 ERROR 1045 (28000): Access denied for user 'qa_test_6_user'@'localhost' (using password: YES) GRANT PROXY ON qa_test_6_dest TO root IDENTIFIED WITH qa_auth_interface AS 'qa_test_6_dest'; SELECT user,plugin,authentication_string,password FROM mysql.user; @@ -114,7 +114,7 @@ root qa_test_6_user qa_auth_interface qa_test_6_dest qa_test_6_dest *DFCACE76914AD7BD801FC1A1ECF6562272621A22 root qa_auth_interface qa_test_6_dest -exec MYSQL PLUGIN_AUTH_OPT -h localhost -P 13000 --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) REVOKE PROXY ON qa_test_6_dest FROM root; SELECT user,plugin,authentication_string FROM mysql.user; @@ -125,7 +125,7 @@ root qa_test_6_user qa_auth_interface qa_test_6_dest qa_test_6_dest root qa_auth_interface qa_test_6_dest -exec MYSQL PLUGIN_AUTH_OPT -h localhost -P 13000 --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) DROP USER qa_test_6_user; DROP USER qa_test_6_dest; @@ -140,7 +140,7 @@ CREATE USER qa_test_11_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_11_des CREATE USER qa_test_11_dest IDENTIFIED BY 'dest_passwd'; GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_11_dest identified by 'dest_passwd'; GRANT PROXY ON qa_test_11_dest TO qa_test_11_user; -exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P 13000 -u qa_test_11_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P MASTER_MYPORT -u qa_test_11_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 ERROR 1045 (28000): Access denied for user 'qa_test_11_user'@'localhost' (using password: YES) DROP USER qa_test_11_user, qa_test_11_dest; DROP DATABASE test_user_db; diff --git a/mysql-test/r/plugin_auth_qa_3.result b/mysql-test/r/plugin_auth_qa_3.result index 92d47bcf580..d94d8879e7d 100644 --- a/mysql-test/r/plugin_auth_qa_3.result +++ b/mysql-test/r/plugin_auth_qa_3.result @@ -2,10 +2,10 @@ CREATE DATABASE test_user_db; CREATE USER qa_test_11_user IDENTIFIED WITH qa_auth_server AS 'qa_test_11_dest'; GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_11_dest identified by 'dest_passwd'; GRANT PROXY ON qa_test_11_dest TO qa_test_11_user; -exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P 13000 -u qa_test_11_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P MASTER_MYPORT -u qa_test_11_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 current_user() user() @@local.proxy_user @@local.external_user qa_test_11_dest@% qa_test_11_user@localhost 'qa_test_11_user'@'%' 'qa_test_11_user'@'%' -exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P 13000 -u qa_test_2_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P MASTER_MYPORT -u qa_test_2_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 ERROR 1045 (28000): Access denied for user 'qa_test_2_user'@'localhost' (using password: NO) DROP USER qa_test_11_user, qa_test_11_dest; DROP DATABASE test_user_db; diff --git a/mysql-test/t/plugin_auth_qa_1.test b/mysql-test/t/plugin_auth_qa_1.test index d7a7afe9407..c33c4c22893 100644 --- a/mysql-test/t/plugin_auth_qa_1.test +++ b/mysql-test/t/plugin_auth_qa_1.test @@ -14,7 +14,8 @@ SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; CREATE USER plug_user IDENTIFIED WITH test_plugin_server AS 'plug_dest'; CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; GRANT PROXY ON plug_dest TO plug_user; ---exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 +--replace_result $MASTER_MYSOCK MASTER_MYSOCK $PLUGIN_AUTH_OPT PLUGIN_AUTH_OPT +--exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 REVOKE PROXY ON plug_dest FROM plug_user; --error 1 --exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 @@ -29,11 +30,13 @@ GRANT PROXY ON plug_dest TO plug_user; --sorted_result SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; --echo 1) ---exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 +--replace_result $MASTER_MYSOCK MASTER_MYSOCK $PLUGIN_AUTH_OPT PLUGIN_AUTH_OPT +--exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 REVOKE ALL PRIVILEGES ON test_user_db.* FROM 'plug_user' IDENTIFIED WITH test_plugin_server AS 'plug_dest'; --echo 2) ---exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 +--replace_result $MASTER_MYSOCK MASTER_MYSOCK $PLUGIN_AUTH_OPT PLUGIN_AUTH_OPT +--exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 REVOKE PROXY ON plug_dest FROM plug_user; --echo 3) --error 1 @@ -49,7 +52,8 @@ CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; --exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 GRANT PROXY ON plug_dest TO plug_user; --echo 2) ---exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 +--replace_result $MASTER_MYSOCK MASTER_MYSOCK $PLUGIN_AUTH_OPT PLUGIN_AUTH_OPT +--exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 REVOKE ALL PRIVILEGES ON test_user_db.* FROM 'plug_user' IDENTIFIED WITH test_plugin_server AS 'plug_dest'; #REVOKE ALL PRIVILEGES ON test_user_db.* FROM 'plug_dest' @@ -63,7 +67,8 @@ GRANT ALL PRIVILEGES ON test_user_db.* TO plug_user IDENTIFIED WITH test_plugin_server AS 'plug_dest'; CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; GRANT PROXY ON plug_dest TO plug_user; ---exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 +--replace_result $MASTER_MYSOCK MASTER_MYSOCK $PLUGIN_AUTH_OPT PLUGIN_AUTH_OPT +--exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 RENAME USER plug_dest TO new_dest; --error 1 --exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 @@ -81,7 +86,8 @@ CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; --error 1 --exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 GRANT PROXY ON plug_dest TO plug_user; ---exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 +--replace_result $MASTER_MYSOCK MASTER_MYSOCK $PLUGIN_AUTH_OPT PLUGIN_AUTH_OPT +--exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 RENAME USER plug_dest TO new_dest; --error 1 --exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 diff --git a/mysql-test/t/plugin_auth_qa_2.test b/mysql-test/t/plugin_auth_qa_2.test index 053e89166b7..135b187f6ee 100644 --- a/mysql-test/t/plugin_auth_qa_2.test +++ b/mysql-test/t/plugin_auth_qa_2.test @@ -20,7 +20,7 @@ SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; SELECT @@proxy_user; SELECT @@external_user; ---echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u qa_test_1_user --password=qa_test_1_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT -u qa_test_1_user --password=qa_test_1_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 --exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u qa_test_1_user --password=qa_test_1_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 --sorted_result @@ -42,7 +42,7 @@ SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; SELECT @@proxy_user; SELECT @@external_user; ---echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u qa_test_2_user --password=qa_test_2_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT -u qa_test_2_user --password=qa_test_2_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 --exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u qa_test_2_user --password=qa_test_2_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 --sorted_result @@ -59,7 +59,7 @@ CREATE USER qa_test_3_dest IDENTIFIED BY 'dest_passwd'; GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_3_dest identified by 'dest_passwd'; GRANT PROXY ON qa_test_3_dest TO qa_test_3_user; ---echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u qa_test_3_user --password=qa_test_3_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT -u qa_test_3_user --password=qa_test_3_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 --exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u qa_test_3_user --password=qa_test_3_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 DROP USER qa_test_3_user; @@ -72,7 +72,7 @@ CREATE USER qa_test_4_dest IDENTIFIED BY 'dest_passwd'; GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_4_dest identified by 'dest_passwd'; GRANT PROXY ON qa_test_4_dest TO qa_test_4_user; ---echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u qa_test_4_user --password=qa_test_4_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT -u qa_test_4_user --password=qa_test_4_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 --exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT -u qa_test_4_user --password=qa_test_4_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 DROP USER qa_test_4_user; @@ -90,7 +90,7 @@ GRANT PROXY ON qa_test_5_dest TO ''@'localhost'; SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; ---echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=qa_test_5_user --password=qa_test_5_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=qa_test_5_user --password=qa_test_5_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 --error 1 --exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=qa_test_5_user --password=qa_test_5_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 @@ -107,21 +107,21 @@ GRANT PROXY ON qa_test_6_dest TO qa_test_6_user; SELECT user,plugin,authentication_string,password FROM mysql.user; ---echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=qa_test_6_user --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=qa_test_6_user --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 --error 1 --exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=qa_test_6_user --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 GRANT PROXY ON qa_test_6_dest TO root IDENTIFIED WITH qa_auth_interface AS 'qa_test_6_dest'; SELECT user,plugin,authentication_string,password FROM mysql.user; ---echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 --error 1 --exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 REVOKE PROXY ON qa_test_6_dest FROM root; SELECT user,plugin,authentication_string FROM mysql.user; ---echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 --error 1 --exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 @@ -138,7 +138,7 @@ CREATE USER qa_test_11_dest IDENTIFIED BY 'dest_passwd'; GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_11_dest identified by 'dest_passwd'; GRANT PROXY ON qa_test_11_dest TO qa_test_11_user; ---echo exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P $MASTER_MYPORT -u qa_test_11_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--echo exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P MASTER_MYPORT -u qa_test_11_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 --error 1 --exec $MYSQL $PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P $MASTER_MYPORT -u qa_test_11_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 diff --git a/mysql-test/t/plugin_auth_qa_3.test b/mysql-test/t/plugin_auth_qa_3.test index 4fe02f10ba6..f7d90226332 100644 --- a/mysql-test/t/plugin_auth_qa_3.test +++ b/mysql-test/t/plugin_auth_qa_3.test @@ -12,10 +12,10 @@ CREATE USER qa_test_11_user IDENTIFIED WITH qa_auth_server AS 'qa_test_11_dest'; GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_11_dest identified by 'dest_passwd'; GRANT PROXY ON qa_test_11_dest TO qa_test_11_user; ---echo exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P $MASTER_MYPORT -u qa_test_11_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--echo exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P MASTER_MYPORT -u qa_test_11_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 --exec $MYSQL $PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P $MASTER_MYPORT -u qa_test_11_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 ---echo exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P $MASTER_MYPORT -u qa_test_2_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 +--echo exec MYSQL PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P MASTER_MYPORT -u qa_test_2_user --password=qa_test_11_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 --error 1 --exec $MYSQL $PLUGIN_AUTH_OPT --default_auth=qa_auth_client -h localhost -P $MASTER_MYPORT -u qa_test_2_user --password=qa_test_2_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 From 2881b8014ca7101684358b25aaf54784c7f43613 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 22 Oct 2010 09:58:09 -0200 Subject: [PATCH 100/304] Bug#37780: Make KILL reliable (main.kill fails randomly) - A prerequisite cleanup patch for making KILL reliable. The test case main.kill did not work reliably. The following problems have been identified: 1. A kill signal could go lost if it came in, short before a thread went reading on the client connection. 2. A kill signal could go lost if it came in, short before a thread went waiting on a condition variable. These problems have been solved as follows. Please see also added code comments for more details. 1. There is no safe way to detect, when a thread enters the blocking state of a read(2) or recv(2) system call, where it can be interrupted by a signal. Hence it is not possible to wait for the right moment to send a kill signal. It has been decided, not to fix it in the code. Instead, the test case repeats the KILL statement until the connection terminates. 2. Before waiting on a condition variable, we register it together with a synchronizating mutex in THD::mysys_var. After this, we need to test THD::killed again. At some places we did only test it in a loop condition before the registration. When THD::killed had been set between this test and the registration, we entered waiting without noticing the killed flag. Additional checks ahve been introduced where required. In addition to the above, a re-write of the main.kill test case has been done. All sleeps have been replaced by Debug Sync Facility synchronization. A couple of sync points have been added to the server code. To avoid further problems, if the test case fails in spite of the fixes, the test case has been added to the "experimental" list for now. - Most of the work on this patch is authored by Ingo Struewing mysql-test/t/kill.test: Re-wrote test case to use Debug Sync points instead of sleeps sql/event_queue.cc: Fixed kill detection in Event_queue::cond_wait() by adding a check after enter_cond(). sql/lock.cc: Moved Debug Sync points behind enter_cond(). Fixed comments. sql/slave.cc: Fixed kill detection in start_slave_thread() by adding a check after enter_cond(). sql/sql_class.cc: Swapped order of kill and close in THD::awake(). Added comments. sql/sql_class.h: Added a comment to THD::killed. sql/sql_parse.cc: Added a sync point in do_command(). sql/sql_select.cc: Added a sync point in JOIN::optimize(). --- mysql-test/r/kill.result | 270 ++++++++++++---------- mysql-test/t/disabled.def | 1 - mysql-test/t/kill.test | 462 ++++++++++++++++++++------------------ sql/event_queue.cc | 12 +- sql/lock.cc | 27 ++- sql/slave.cc | 14 +- sql/sql_class.cc | 61 ++++- sql/sql_class.h | 6 + sql/sql_parse.cc | 16 ++ sql/sql_select.cc | 2 + 10 files changed, 502 insertions(+), 369 deletions(-) diff --git a/mysql-test/r/kill.result b/mysql-test/r/kill.result index 1f4f4bb32eb..964f2947f6a 100644 --- a/mysql-test/r/kill.result +++ b/mysql-test/r/kill.result @@ -1,143 +1,178 @@ -set @old_concurrent_insert= @@global.concurrent_insert; -set @@global.concurrent_insert= 0; -drop table if exists t1, t2, t3; -create table t1 (kill_id int); -insert into t1 values(connection_id()); -select ((@id := kill_id) - kill_id) from t1; -((@id := kill_id) - kill_id) -0 -kill @id; -select ((@id := kill_id) - kill_id) from t1; -((@id := kill_id) - kill_id) -0 -select @id != connection_id(); -@id != connection_id() -1 -select 4; -4 -4 -drop table t1; -kill (select count(*) from mysql.user); -ERROR 42000: This version of MySQL doesn't yet support 'Usage of subqueries or stored function calls as part of this statement' -create table t1 (id int primary key); -create table t2 (id int unsigned not null); -insert into t2 select id from t1; -create table t3 (kill_id int); -insert into t3 values(connection_id()); -select id from t1 where id in (select distinct a.id from t2 a, t2 b, t2 c, t2 d group by a.id, b.id, c.id, d.id having a.id between 10 and 20); -select ((@id := kill_id) - kill_id) from t3; -((@id := kill_id) - kill_id) -0 -kill @id; +SET DEBUG_SYNC = 'RESET'; +DROP TABLE IF EXISTS t1, t2, t3; +DROP FUNCTION IF EXISTS MY_KILL; +CREATE FUNCTION MY_KILL(tid INT) RETURNS INT +BEGIN +DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; +KILL tid; +RETURN (SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = tid); +END| +SET DEBUG_SYNC= 'thread_end SIGNAL con1_end'; +SET DEBUG_SYNC= 'before_do_command_net_read SIGNAL con1_read'; +SET DEBUG_SYNC='now WAIT_FOR con1_read'; +SET DEBUG_SYNC= 'now WAIT_FOR con1_end'; +SET DEBUG_SYNC = 'RESET'; +SELECT 1; Got one of the listed errors -drop table t1, t2, t3; -select get_lock("a", 10); -get_lock("a", 10) -1 -select get_lock("a", 10); -get_lock("a", 10) -NULL -select 1; +SELECT 1; 1 1 -select RELEASE_LOCK("a"); -RELEASE_LOCK("a") +SELECT @id != CONNECTION_ID(); +@id != CONNECTION_ID() 1 -create table t1(f1 int); -create function bug27563() returns int(11) -deterministic -begin -declare continue handler for sqlstate '70100' set @a:= 'killed'; -declare continue handler for sqlexception set @a:= 'exception'; -set @a= get_lock("lock27563", 10); -return 1; -end| -select get_lock("lock27563",10); -get_lock("lock27563",10) +SELECT 4; +4 +4 +KILL (SELECT COUNT(*) FROM mysql.user); +ERROR 42000: This version of MySQL doesn't yet support 'Usage of subqueries or stored function calls as part of this statement' +SET DEBUG_SYNC= 'thread_end SIGNAL con1_end'; +SET DEBUG_SYNC= 'before_do_command_net_read SIGNAL con1_read WAIT_FOR kill'; +SET DEBUG_SYNC= 'now WAIT_FOR con1_read'; +SET DEBUG_SYNC= 'now WAIT_FOR con1_end'; +SET DEBUG_SYNC = 'RESET'; +SELECT 1; +Got one of the listed errors +SELECT 1; 1 -insert into t1 values (bug27563()); +1 +SELECT @id != CONNECTION_ID(); +@id != CONNECTION_ID() +1 +SELECT 4; +4 +4 +CREATE TABLE t1 (id INT PRIMARY KEY AUTO_INCREMENT); +CREATE TABLE t2 (id INT UNSIGNED NOT NULL); +INSERT INTO t1 VALUES +(0),(0),(0),(0),(0),(0),(0),(0), (0),(0),(0),(0),(0),(0),(0),(0), +(0),(0),(0),(0),(0),(0),(0),(0), (0),(0),(0),(0),(0),(0),(0),(0), +(0),(0),(0),(0),(0),(0),(0),(0), (0),(0),(0),(0),(0),(0),(0),(0), +(0),(0),(0),(0),(0),(0),(0),(0), (0),(0),(0),(0),(0),(0),(0),(0); +INSERT t1 SELECT 0 FROM t1 AS a1, t1 AS a2 LIMIT 4032; +INSERT INTO t2 SELECT id FROM t1; +SET DEBUG_SYNC= 'thread_end SIGNAL con1_end'; +SET DEBUG_SYNC= 'before_acos_function SIGNAL in_sync'; +SELECT id FROM t1 WHERE id IN +(SELECT DISTINCT a.id FROM t2 a, t2 b, t2 c, t2 d +GROUP BY ACOS(1/a.id), b.id, c.id, d.id +HAVING a.id BETWEEN 10 AND 20); +SET DEBUG_SYNC= 'now WAIT_FOR in_sync'; +KILL @id; +SET DEBUG_SYNC= 'now WAIT_FOR con1_end'; +Got one of the listed errors +SELECT 1; +1 +1 +SET DEBUG_SYNC = 'RESET'; +DROP TABLE t1, t2; +SET DEBUG_SYNC= 'before_acos_function SIGNAL in_sync WAIT_FOR kill'; +SELECT ACOS(0); +SET DEBUG_SYNC= 'now WAIT_FOR in_sync'; +KILL QUERY @id; +ACOS(0) +1.5707963267948966 +SELECT 1; +1 +1 +SELECT @id = CONNECTION_ID(); +@id = CONNECTION_ID() +1 +SET DEBUG_SYNC = 'RESET'; +CREATE TABLE t1 (f1 INT); +CREATE FUNCTION bug27563() RETURNS INT(11) +DETERMINISTIC +BEGIN +DECLARE CONTINUE HANDLER FOR SQLSTATE '70100' SET @a:= 'killed'; +DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET @a:= 'exception'; +SET DEBUG_SYNC= 'now SIGNAL in_sync WAIT_FOR kill'; +RETURN 1; +END| +INSERT INTO t1 VALUES (bug27563()); +SET DEBUG_SYNC= 'now WAIT_FOR in_sync'; +KILL QUERY @id; ERROR 70100: Query execution was interrupted -select @a; -@a -NULL -select * from t1; +SELECT * FROM t1; f1 -insert into t1 values(0); -update t1 set f1= bug27563(); +SET DEBUG_SYNC = 'RESET'; +INSERT INTO t1 VALUES(0); +UPDATE t1 SET f1= bug27563(); +SET DEBUG_SYNC= 'now WAIT_FOR in_sync'; +KILL QUERY @id; ERROR 70100: Query execution was interrupted -select @a; -@a -NULL -select * from t1; +SELECT * FROM t1; f1 0 -insert into t1 values(1); -delete from t1 where bug27563() is null; +SET DEBUG_SYNC = 'RESET'; +INSERT INTO t1 VALUES(1); +DELETE FROM t1 WHERE bug27563() IS NULL; +SET DEBUG_SYNC= 'now WAIT_FOR in_sync'; +KILL QUERY @id; ERROR 70100: Query execution was interrupted -select @a; -@a -NULL -select * from t1; +SELECT * FROM t1; f1 0 1 -select * from t1 where f1= bug27563(); +SET DEBUG_SYNC = 'RESET'; +SELECT * FROM t1 WHERE f1= bug27563(); +SET DEBUG_SYNC= 'now WAIT_FOR in_sync'; +KILL QUERY @id; ERROR 70100: Query execution was interrupted -select @a; -@a -NULL -create procedure proc27563() -begin -declare continue handler for sqlstate '70100' set @a:= 'killed'; -declare continue handler for sqlexception set @a:= 'exception'; -select get_lock("lock27563",10); -select "shouldn't be selected"; -end| -call proc27563(); -get_lock("lock27563",10) -NULL -ERROR 70100: Query execution was interrupted -select @a; -@a -NULL -create table t2 (f2 int); -create trigger trg27563 before insert on t1 for each row -begin -declare continue handler for sqlstate '70100' set @a:= 'killed'; -declare continue handler for sqlexception set @a:= 'exception'; -set @a:= get_lock("lock27563",10); -insert into t2 values(1); -end| -insert into t1 values(2),(3); -ERROR 70100: Query execution was interrupted -select @a; -@a -NULL -select * from t1; +SELECT * FROM t1; f1 0 1 -select * from t2; +SET DEBUG_SYNC = 'RESET'; +DROP FUNCTION bug27563; +CREATE TABLE t2 (f2 INT); +CREATE TRIGGER trg27563 BEFORE INSERT ON t1 FOR EACH ROW +BEGIN +DECLARE CONTINUE HANDLER FOR SQLSTATE '70100' SET @a:= 'killed'; +DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET @a:= 'exception'; +INSERT INTO t2 VALUES(0); +SET DEBUG_SYNC= 'now SIGNAL in_sync WAIT_FOR kill'; +INSERT INTO t2 VALUES(1); +END| +INSERT INTO t1 VALUES(2),(3); +SET DEBUG_SYNC= 'now WAIT_FOR in_sync'; +KILL QUERY @id; +ERROR 70100: Query execution was interrupted +SELECT * FROM t1; +f1 +0 +1 +SELECT * FROM t2; f2 -select release_lock("lock27563"); -release_lock("lock27563") -1 -drop table t1, t2; -drop function bug27563; -drop procedure proc27563; +0 +SET DEBUG_SYNC = 'RESET'; +DROP TABLE t1, t2; +SET DEBUG_SYNC= 'before_join_optimize SIGNAL in_sync'; PREPARE stmt FROM 'EXPLAIN SELECT * FROM t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38,t39,t40 WHERE a1=a2 AND a2=a3 AND a3=a4 AND a4=a5 AND a5=a6 AND a6=a7 AND a7=a8 AND a8=a9 AND a9=a10 AND a10=a11 AND a11=a12 AND a12=a13 AND a13=a14 AND a14=a15 AND a15=a16 AND a16=a17 AND a17=a18 AND a18=a19 AND a19=a20 AND a20=a21 AND a21=a22 AND a22=a23 AND a23=a24 AND a24=a25 AND a25=a26 AND a26=a27 AND a27=a28 AND a28=a29 AND a29=a30 AND a30=a31 AND a31=a32 AND a32=a33 AND a33=a34 AND a34=a35 AND a35=a36 AND a36=a37 AND a37=a38 AND a38=a39 AND a39=a40 '; EXECUTE stmt; +SET DEBUG_SYNC= 'now WAIT_FOR in_sync'; +KILL QUERY @id; +ERROR 70100: Query execution was interrupted +SET DEBUG_SYNC = 'RESET'; # # Bug#19723: kill of active connection yields different error code # depending on platform. # -# Connection: con2. -KILL CONNECTION_ID(); -# CR_SERVER_LOST, CR_SERVER_GONE_ERROR, depending on the timing -# of close of the connection socket +# Connection: con1. +SET DEBUG_SYNC= 'thread_end SIGNAL con1_end'; +KILL @id; +ERROR 70100: Query execution was interrupted +SET DEBUG_SYNC= 'now WAIT_FOR con1_end'; +# ER_SERVER_SHUTDOWN, CR_SERVER_GONE_ERROR, CR_SERVER_LOST, +# depending on the timing of close of the connection socket SELECT 1; Got one of the listed errors +SELECT 1; +1 +1 +SELECT @id != CONNECTION_ID(); +@id != CONNECTION_ID() +1 +SET DEBUG_SYNC = 'RESET'; # # Additional test for WL#3726 "DDL locking for all metadata objects" # Check that DDL and DML statements waiting for metadata locks can @@ -208,13 +243,11 @@ ERROR 70100: Query execution was interrupted # Test for DML waiting for meta-data lock # Switching to connection 'blocker' unlock tables; -drop table t2; -create table t2 (k int); lock tables t1 read; # Switching to connection 'ddl' -rename tables t1 to t3, t2 to t1; +truncate table t1; # Switching to connection 'dml' -insert into t2 values (1); +insert into t1 values (1); # Switching to connection 'default' kill query ID2; # Switching to connection 'dml' @@ -239,6 +272,7 @@ unlock tables; # Switching to connection 'ddl' # Cleanup. # Switching to connection 'default' -drop table t3; drop table t1; -set @@global.concurrent_insert= @old_concurrent_insert; +drop table t2; +SET DEBUG_SYNC = 'RESET'; +DROP FUNCTION MY_KILL; diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 5bd53ec568e..b14342fbb3b 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -9,7 +9,6 @@ # Do not use any TAB characters for whitespace. # ############################################################################## -kill : Bug#37780 2008-12-03 HHunger need some changes to be robust enough for pushbuild. lowercase_table3 : Bug#54845 2010-06-30 alik main.lowercase_table3 on Mac OSX mysqlhotcopy_myisam : Bug#54129 2010-08-31 alik mysqlhotcopy* fails mysqlhotcopy_archive : Bug#54129 2010-08-31 alik mysqlhotcopy* fails diff --git a/mysql-test/t/kill.test b/mysql-test/t/kill.test index 706c2514d92..701d4083f86 100644 --- a/mysql-test/t/kill.test +++ b/mysql-test/t/kill.test @@ -1,307 +1,326 @@ -# This test doesn't work with the embedded version as this code -# assumes that one query is running while we are doing queries on -# a second connection. -# This would work if mysqltest run would be threaded and handle each -# connection in a separate thread. # --- source include/not_embedded.inc +# Test KILL and KILL QUERY statements. +# +# Killing a connection in an embedded server does not work like in a normal +# server, if it is waiting for a new statement. In an embedded server, the +# connection does not read() from a socket, but returns control to the +# application. 'mysqltest' does not handle the kill request. +# -# Disable concurrent inserts to avoid test failures when reading the -# connection id which was inserted into a table by another thread. -set @old_concurrent_insert= @@global.concurrent_insert; -set @@global.concurrent_insert= 0; +-- source include/not_embedded.inc +-- source include/have_debug_sync.inc + +--disable_warnings +SET DEBUG_SYNC = 'RESET'; +DROP TABLE IF EXISTS t1, t2, t3; +DROP FUNCTION IF EXISTS MY_KILL; +--enable_warnings + +delimiter |; +# Helper function used to repeatedly kill a session. +CREATE FUNCTION MY_KILL(tid INT) RETURNS INT +BEGIN + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; + KILL tid; + RETURN (SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = tid); +END| +delimiter ;| connect (con1, localhost, root,,); connect (con2, localhost, root,,); -#remember id of con1 +# Save id of con1 connection con1; ---disable_warnings -drop table if exists t1, t2, t3; ---enable_warnings - --disable_reconnect -create table t1 (kill_id int); -insert into t1 values(connection_id()); - -#kill con1 +let $ID= `SELECT @id := CONNECTION_ID()`; connection con2; -select ((@id := kill_id) - kill_id) from t1; -kill @id; +let $ignore= `SELECT @id := $ID`; +connection con1; +# Signal when this connection is terminating. +SET DEBUG_SYNC= 'thread_end SIGNAL con1_end'; +# See if we can kill read(). +# Run into read() immediately after hitting 'before_do_command_net_read'. +SET DEBUG_SYNC= 'before_do_command_net_read SIGNAL con1_read'; + +# Kill con1 +connection con2; +SET DEBUG_SYNC='now WAIT_FOR con1_read'; +# At this point we have no way to figure out, when con1 is blocked in +# reading from the socket. Sending KILL to early would not terminate +# con1. So we repeat KILL until con1 terminates. +let $wait_condition= SELECT MY_KILL(@id); +--source include/wait_condition.inc +# If KILL missed the read(), sync point wait will time out. +SET DEBUG_SYNC= 'now WAIT_FOR con1_end'; +SET DEBUG_SYNC = 'RESET'; connection con1; ---sleep 2 - ---disable_query_log ---disable_result_log -# One of the following statements should fail ---error 0,2006,2013 -select 1; ---error 0,2006,2013 -select 1; ---enable_query_log ---enable_result_log +--error 1053,2006,2013 +SELECT 1; --enable_reconnect # this should work, and we should have a new connection_id() -select ((@id := kill_id) - kill_id) from t1; -select @id != connection_id(); +SELECT 1; +let $ignore= `SELECT @id := $ID`; +SELECT @id != CONNECTION_ID(); #make sure the server is still alive connection con2; -select 4; -drop table t1; +SELECT 4; connection default; --error ER_NOT_SUPPORTED_YET -kill (select count(*) from mysql.user); +KILL (SELECT COUNT(*) FROM mysql.user); + +connection con1; +let $ID= `SELECT @id := CONNECTION_ID()`; +connection con2; +let $ignore= `SELECT @id := $ID`; +connection con1; +disable_reconnect; +# Signal when this connection is terminating. +SET DEBUG_SYNC= 'thread_end SIGNAL con1_end'; +# See if we can kill the sync point itself. +# Wait in 'before_do_command_net_read' until killed. +# It doesn't wait for a signal 'kill' but for to be killed. +# The signal name doesn't matter here. +SET DEBUG_SYNC= 'before_do_command_net_read SIGNAL con1_read WAIT_FOR kill'; +connection con2; +SET DEBUG_SYNC= 'now WAIT_FOR con1_read'; +# Repeat KILL until con1 terminates. +let $wait_condition= SELECT MY_KILL(@id); +--source include/wait_condition.inc +SET DEBUG_SYNC= 'now WAIT_FOR con1_end'; +SET DEBUG_SYNC = 'RESET'; + +connection con1; +--error 1053,2006,2013 +SELECT 1; +enable_reconnect; +SELECT 1; +let $ignore= `SELECT @id := $ID`; +SELECT @id != CONNECTION_ID(); +connection con2; +SELECT 4; +connection default; # # BUG#14851: killing long running subquery processed via a temporary table. # -create table t1 (id int primary key); -create table t2 (id int unsigned not null); -connect (conn1, localhost, root,,); -connection conn1; +CREATE TABLE t1 (id INT PRIMARY KEY AUTO_INCREMENT); +CREATE TABLE t2 (id INT UNSIGNED NOT NULL); --- disable_result_log --- disable_query_log -let $1 = 4096; -while ($1) -{ - eval insert into t1 values ($1); - dec $1; -} --- enable_query_log --- enable_result_log +INSERT INTO t1 VALUES +(0),(0),(0),(0),(0),(0),(0),(0), (0),(0),(0),(0),(0),(0),(0),(0), +(0),(0),(0),(0),(0),(0),(0),(0), (0),(0),(0),(0),(0),(0),(0),(0), +(0),(0),(0),(0),(0),(0),(0),(0), (0),(0),(0),(0),(0),(0),(0),(0), +(0),(0),(0),(0),(0),(0),(0),(0), (0),(0),(0),(0),(0),(0),(0),(0); +INSERT t1 SELECT 0 FROM t1 AS a1, t1 AS a2 LIMIT 4032; -insert into t2 select id from t1; +INSERT INTO t2 SELECT id FROM t1; -create table t3 (kill_id int); -insert into t3 values(connection_id()); +connection con1; +let $ID= `SELECT @id := CONNECTION_ID()`; +connection con2; +let $ignore= `SELECT @id := $ID`; -connect (conn2, localhost, root,,); -connection conn2; +connection con1; +SET DEBUG_SYNC= 'thread_end SIGNAL con1_end'; +SET DEBUG_SYNC= 'before_acos_function SIGNAL in_sync'; +# This is a very long running query. If this test start failing, +# it may be necessary to change to an even longer query. +send SELECT id FROM t1 WHERE id IN + (SELECT DISTINCT a.id FROM t2 a, t2 b, t2 c, t2 d + GROUP BY ACOS(1/a.id), b.id, c.id, d.id + HAVING a.id BETWEEN 10 AND 20); -connection conn1; --- disable_result_log -# This is a very long running query. If this test start failing, it may -# be necessary to change to an even longer query. -send select id from t1 where id in (select distinct a.id from t2 a, t2 b, t2 c, t2 d group by a.id, b.id, c.id, d.id having a.id between 10 and 20); --- enable_result_log +connection con2; +SET DEBUG_SYNC= 'now WAIT_FOR in_sync'; +KILL @id; +SET DEBUG_SYNC= 'now WAIT_FOR con1_end'; -connection conn2; -select ((@id := kill_id) - kill_id) from t3; --- sleep 1 -kill @id; - -connection conn1; --- error 1317,2013 +connection con1; +--error 1053,2006,2013 reap; +SELECT 1; connection default; - -drop table t1, t2, t3; - -# End of 4.1 tests +SET DEBUG_SYNC = 'RESET'; +DROP TABLE t1, t2; # -# test of blocking of sending ERROR after OK or EOF +# Test of blocking of sending ERROR after OK or EOF # connection con1; -select get_lock("a", 10); +let $ID= `SELECT @id := CONNECTION_ID()`; connection con2; -let $ID= `select connection_id()`; -send select get_lock("a", 10); -real_sleep 2; +let $ignore= `SELECT @id := $ID`; connection con1; -disable_query_log; -eval kill query $ID; -enable_query_log; +SET DEBUG_SYNC= 'before_acos_function SIGNAL in_sync WAIT_FOR kill'; +send SELECT ACOS(0); connection con2; +SET DEBUG_SYNC= 'now WAIT_FOR in_sync'; +KILL QUERY @id; +connection con1; reap; -select 1; -connection con1; -select RELEASE_LOCK("a"); +SELECT 1; +SELECT @id = CONNECTION_ID(); +connection default; +SET DEBUG_SYNC = 'RESET'; # # Bug#27563: Stored functions and triggers wasn't throwing an error when killed. # -create table t1(f1 int); +CREATE TABLE t1 (f1 INT); delimiter |; -create function bug27563() returns int(11) -deterministic -begin - declare continue handler for sqlstate '70100' set @a:= 'killed'; - declare continue handler for sqlexception set @a:= 'exception'; - set @a= get_lock("lock27563", 10); - return 1; -end| +CREATE FUNCTION bug27563() RETURNS INT(11) +DETERMINISTIC +BEGIN + DECLARE CONTINUE HANDLER FOR SQLSTATE '70100' SET @a:= 'killed'; + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET @a:= 'exception'; + SET DEBUG_SYNC= 'now SIGNAL in_sync WAIT_FOR kill'; + RETURN 1; +END| delimiter ;| # Test stored functions # Test INSERT connection con1; -select get_lock("lock27563",10); +let $ID= `SELECT @id := CONNECTION_ID()`; connection con2; -let $ID= `select connection_id()`; -send insert into t1 values (bug27563()); -real_sleep 2; +let $ignore= `SELECT @id := $ID`; connection con1; -disable_query_log; -eval kill query $ID; -enable_query_log; +send INSERT INTO t1 VALUES (bug27563()); connection con2; +SET DEBUG_SYNC= 'now WAIT_FOR in_sync'; +KILL QUERY @id; +connection con1; --error 1317 reap; -select @a; -connection con1; -select * from t1; +SELECT * FROM t1; +connection default; +SET DEBUG_SYNC = 'RESET'; # Test UPDATE -insert into t1 values(0); -connection con2; -send update t1 set f1= bug27563(); -real_sleep 2; +INSERT INTO t1 VALUES(0); connection con1; -disable_query_log; -eval kill query $ID; -enable_query_log; +send UPDATE t1 SET f1= bug27563(); connection con2; +SET DEBUG_SYNC= 'now WAIT_FOR in_sync'; +KILL QUERY @id; +connection con1; --error 1317 reap; -select @a; -connection con1; -select * from t1; +SELECT * FROM t1; +connection default; +SET DEBUG_SYNC = 'RESET'; # Test DELETE -insert into t1 values(1); -connection con2; -send delete from t1 where bug27563() is null; -real_sleep 2; +INSERT INTO t1 VALUES(1); connection con1; -disable_query_log; -eval kill query $ID; -enable_query_log; +send DELETE FROM t1 WHERE bug27563() IS NULL; connection con2; +SET DEBUG_SYNC= 'now WAIT_FOR in_sync'; +KILL QUERY @id; +connection con1; --error 1317 reap; -select @a; -connection con1; -select * from t1; +SELECT * FROM t1; +connection default; +SET DEBUG_SYNC = 'RESET'; # Test SELECT -connection con2; -send select * from t1 where f1= bug27563(); -real_sleep 2; connection con1; -disable_query_log; -eval kill query $ID; -enable_query_log; +send SELECT * FROM t1 WHERE f1= bug27563(); connection con2; +SET DEBUG_SYNC= 'now WAIT_FOR in_sync'; +KILL QUERY @id; +connection con1; --error 1317 reap; -select @a; - -# Test PROCEDURE -connection con2; -delimiter |; -create procedure proc27563() -begin - declare continue handler for sqlstate '70100' set @a:= 'killed'; - declare continue handler for sqlexception set @a:= 'exception'; - select get_lock("lock27563",10); - select "shouldn't be selected"; -end| -delimiter ;| -send call proc27563(); -real_sleep 2; -connection con1; -disable_query_log; -eval kill query $ID; -enable_query_log; -connection con2; ---error 1317 -reap; -select @a; +SELECT * FROM t1; +connection default; +SET DEBUG_SYNC = 'RESET'; +DROP FUNCTION bug27563; # Test TRIGGERS -connection con2; -create table t2 (f2 int); +CREATE TABLE t2 (f2 INT); delimiter |; -create trigger trg27563 before insert on t1 for each row -begin - declare continue handler for sqlstate '70100' set @a:= 'killed'; - declare continue handler for sqlexception set @a:= 'exception'; - set @a:= get_lock("lock27563",10); - insert into t2 values(1); -end| +CREATE TRIGGER trg27563 BEFORE INSERT ON t1 FOR EACH ROW +BEGIN + DECLARE CONTINUE HANDLER FOR SQLSTATE '70100' SET @a:= 'killed'; + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET @a:= 'exception'; + INSERT INTO t2 VALUES(0); + SET DEBUG_SYNC= 'now SIGNAL in_sync WAIT_FOR kill'; + INSERT INTO t2 VALUES(1); +END| delimiter ;| -send insert into t1 values(2),(3); -real_sleep 2; connection con1; -disable_query_log; -eval kill query $ID; -enable_query_log; +send INSERT INTO t1 VALUES(2),(3); connection con2; +SET DEBUG_SYNC= 'now WAIT_FOR in_sync'; +KILL QUERY @id; +connection con1; --error 1317 reap; -select @a; -connection con1; -select * from t1; -select * from t2; - -# Cleanup -select release_lock("lock27563"); -drop table t1, t2; -drop function bug27563; -drop procedure proc27563; +SELECT * FROM t1; +SELECT * FROM t2; +connection default; +SET DEBUG_SYNC = 'RESET'; +DROP TABLE t1, t2; # # Bug#28598: mysqld crash when killing a long-running explain query. # ---disable_query_log connection con1; -let $ID= `select connection_id()`; +let $ID= `SELECT @id := CONNECTION_ID()`; +connection con2; +let $ignore= `SELECT @id := $ID`; +connection con1; +--disable_query_log let $tab_count= 40; let $i= $tab_count; while ($i) { - eval CREATE TABLE t$i (a$i int, KEY(a$i)); + eval CREATE TABLE t$i (a$i INT, KEY(a$i)); eval INSERT INTO t$i VALUES (1),(2),(3),(4),(5),(6),(7); dec $i ; } -set session optimizer_search_depth=0; +SET SESSION optimizer_search_depth=0; let $i=$tab_count; while ($i) { - let $a= a$i; - let $t= t$i; - dec $i; - if ($i) - { - let $comma=,; - let $from=$comma$t$from; - let $where=a$i=$a $and $where; - } - if (!$i) - { - let $from=FROM $t$from; - let $where=WHERE $where; - } - let $and=AND; + let $a= a$i; + let $t= t$i; + dec $i; + if ($i) + { + let $comma=,; + let $from=$comma$t$from; + let $where=a$i=$a $and $where; + } + if (!$i) + { + let $from=FROM $t$from; + let $where=WHERE $where; + } + let $and=AND; } --enable_query_log +SET DEBUG_SYNC= 'before_join_optimize SIGNAL in_sync'; eval PREPARE stmt FROM 'EXPLAIN SELECT * $from $where'; send EXECUTE stmt; ---disable_query_log connection con2; -real_sleep 2; -eval kill query $ID; +SET DEBUG_SYNC= 'now WAIT_FOR in_sync'; +KILL QUERY @id; +connection con1; +--error 1317 +reap; +--disable_query_log let $i= $tab_count; while ($i) { @@ -309,8 +328,8 @@ while ($i) dec $i ; } --enable_query_log - -########################################################################### +connection default; +SET DEBUG_SYNC = 'RESET'; --echo # --echo # Bug#19723: kill of active connection yields different error code @@ -318,16 +337,27 @@ while ($i) --echo # --echo ---echo # Connection: con2. ---connection con2 +--echo # Connection: con1. +--connection con1 +let $ID= `SELECT @id := CONNECTION_ID()`; +SET DEBUG_SYNC= 'thread_end SIGNAL con1_end'; +--disable_reconnect +--error ER_QUERY_INTERRUPTED +KILL @id; -KILL CONNECTION_ID(); - ---echo # CR_SERVER_LOST, CR_SERVER_GONE_ERROR, depending on the timing ---echo # of close of the connection socket ---error 2013, 2006 +connection con2; +SET DEBUG_SYNC= 'now WAIT_FOR con1_end'; +connection con1; +--echo # ER_SERVER_SHUTDOWN, CR_SERVER_GONE_ERROR, CR_SERVER_LOST, +--echo # depending on the timing of close of the connection socket +--error 1053,2006,2013 SELECT 1; ---connection default +--enable_reconnect +SELECT 1; +let $ignore= `SELECT @id := $ID`; +SELECT @id != CONNECTION_ID(); +connection default; +SET DEBUG_SYNC = 'RESET'; --echo # --echo # Additional test for WL#3726 "DDL locking for all metadata objects" @@ -489,28 +519,26 @@ connection ddl; --echo # Switching to connection 'blocker' connection blocker; unlock tables; -drop table t2; -create table t2 (k int); lock tables t1 read; --echo # Switching to connection 'ddl' connection ddl; # Let us add pending exclusive metadata lock on t2 ---send rename tables t1 to t3, t2 to t1 +--send truncate table t1 --echo # Switching to connection 'dml' connection dml; let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and - info = "rename tables t1 to t3, t2 to t1"; + info = "truncate table t1"; --source include/wait_condition.inc let $ID2= `select connection_id()`; ---send insert into t2 values (1) +--send insert into t1 values (1) --echo # Switching to connection 'default' connection default; let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and - info = "insert into t2 values (1)"; + info = "insert into t1 values (1)"; --source include/wait_condition.inc --replace_result $ID2 ID2 eval kill query $ID2; @@ -564,10 +592,10 @@ connection ddl; --echo # Cleanup. --echo # Switching to connection 'default' connection default; -drop table t3; drop table t1; +drop table t2; ########################################################################### -# Restore global concurrent_insert value. Keep in the end of the test file. -set @@global.concurrent_insert= @old_concurrent_insert; +SET DEBUG_SYNC = 'RESET'; +DROP FUNCTION MY_KILL; diff --git a/sql/event_queue.cc b/sql/event_queue.cc index f0310c676d1..458a7c1defd 100644 --- a/sql/event_queue.cc +++ b/sql/event_queue.cc @@ -741,11 +741,13 @@ Event_queue::cond_wait(THD *thd, struct timespec *abstime, const char* msg, thd->enter_cond(&COND_queue_state, &LOCK_event_queue, msg); - DBUG_PRINT("info", ("mysql_cond_%swait", abstime? "timed":"")); - if (!abstime) - mysql_cond_wait(&COND_queue_state, &LOCK_event_queue); - else - mysql_cond_timedwait(&COND_queue_state, &LOCK_event_queue, abstime); + if (!thd->killed) + { + if (!abstime) + mysql_cond_wait(&COND_queue_state, &LOCK_event_queue); + else + mysql_cond_timedwait(&COND_queue_state, &LOCK_event_queue, abstime); + } mutex_last_locked_in_func= func; mutex_last_locked_at_line= line; diff --git a/sql/lock.cc b/sql/lock.cc index 0181a544824..84cc24b3f61 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -989,6 +989,14 @@ bool Global_read_lock::lock_global_read_lock(THD *thd) const char *new_message= "Waiting to get readlock"; (void) mysql_mutex_lock(&LOCK_global_read_lock); + old_message= thd->enter_cond(&COND_global_read_lock, + &LOCK_global_read_lock, new_message); + DBUG_PRINT("info", + ("waiting_for: %d protect_against: %d", + waiting_for_read_lock, protect_against_global_read_lock)); + + waiting_for_read_lock++; + #if defined(ENABLED_DEBUG_SYNC) /* The below sync point fires if we have to wait for @@ -997,27 +1005,18 @@ bool Global_read_lock::lock_global_read_lock(THD *thd) WARNING: Beware to use WAIT_FOR with this sync point. We hold LOCK_global_read_lock here. - Call the sync point before calling enter_cond() as it does use - enter_cond() and exit_cond() itself if a WAIT_FOR action is - executed in spite of the above warning. + The sync point is after enter_cond() so that proc_info is + available immediately after the sync point sends a SIGNAL. This + can make tests more reliable. - Pre-set proc_info so that it is available immediately after the - sync point sends a SIGNAL. This makes tests more reliable. + The sync point is before the loop so that it is executed only once. */ - if (protect_against_global_read_lock) + if (protect_against_global_read_lock && !thd->killed) { - thd_proc_info(thd, new_message); DEBUG_SYNC(thd, "wait_lock_global_read_lock"); } #endif /* defined(ENABLED_DEBUG_SYNC) */ - old_message=thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock, - new_message); - DBUG_PRINT("info", - ("waiting_for: %d protect_against: %d", - waiting_for_read_lock, protect_against_global_read_lock)); - - waiting_for_read_lock++; while (protect_against_global_read_lock && !thd->killed) mysql_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock); waiting_for_read_lock--; diff --git a/sql/slave.cc b/sql/slave.cc index ab8952069fb..a6313f0b850 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -721,9 +721,17 @@ int start_slave_thread( while (start_id == *slave_run_id) { DBUG_PRINT("sleep",("Waiting for slave thread to start")); - const char* old_msg = thd->enter_cond(start_cond,cond_lock, - "Waiting for slave thread to start"); - mysql_cond_wait(start_cond, cond_lock); + const char *old_msg= thd->enter_cond(start_cond, cond_lock, + "Waiting for slave thread to start"); + /* + It is not sufficient to test this at loop bottom. We must test + it after registering the mutex in enter_cond(). If the kill + happens after testing of thd->killed and before the mutex is + registered, we could otherwise go waiting though thd->killed is + set. + */ + if (!thd->killed) + mysql_cond_wait(start_cond, cond_lock); thd->exit_cond(old_msg); mysql_mutex_lock(cond_lock); // re-acquire it as exit_cond() released if (thd->killed) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 15fbc6a1480..da61c67f1c8 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1179,36 +1179,70 @@ void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var, } +/** + Awake a thread. + + @param[in] state_to_set value for THD::killed + + This is normally called from another thread's THD object. + + @note Do always call this while holding LOCK_thd_data. +*/ + void THD::awake(THD::killed_state state_to_set) { DBUG_ENTER("THD::awake"); - DBUG_PRINT("enter", ("this: 0x%lx", (long) this)); + DBUG_PRINT("enter", ("this: %p current_thd: %p", this, current_thd)); THD_CHECK_SENTRY(this); mysql_mutex_assert_owner(&LOCK_thd_data); + /* Set the 'killed' flag of 'this', which is the target THD object. */ killed= state_to_set; + if (state_to_set != THD::KILL_QUERY) { - thr_alarm_kill(thread_id); - if (!slave_thread) - MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (this)); #ifdef SIGNAL_WITH_VIO_CLOSE if (this != current_thd) { /* - In addition to a signal, let's close the socket of the thread that - is being killed. This is to make sure it does not block if the - signal is lost. This needs to be done only on platforms where - signals are not a reliable interruption mechanism. + Before sending a signal, let's close the socket of the thread + that is being killed ("this", which is not the current thread). + This is to make sure it does not block if the signal is lost. + This needs to be done only on platforms where signals are not + a reliable interruption mechanism. - If we're killing ourselves, we know that we're not blocked, so this - hack is not used. + Note that the downside of this mechanism is that we could close + the connection while "this" target thread is in the middle of + sending a result to the application, thus violating the client- + server protocol. + + On the other hand, without closing the socket we have a race + condition. If "this" target thread passes the check of + thd->killed, and then the current thread runs through + THD::awake(), sets the 'killed' flag and completes the + signaling, and then the target thread runs into read(), it will + block on the socket. As a result of the discussions around + Bug#37780, it has been decided that we accept the race + condition. A second KILL awakes the target from read(). + + If we are killing ourselves, we know that we are not blocked. + We also know that we will check thd->killed before we go for + reading the next statement. */ close_active_vio(); } -#endif +#endif + + /* Mark the target thread's alarm request expired, and signal alarm. */ + thr_alarm_kill(thread_id); + + /* Send an event to the scheduler that a thread should be killed. */ + if (!slave_thread) + MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (this)); } + + /* Broadcast a condition to kick the target if it is waiting on it. */ if (mysys_var) { mysql_mutex_lock(&mysys_var->mutex); @@ -1232,6 +1266,11 @@ void THD::awake(THD::killed_state state_to_set) we issue a second KILL or the status it's waiting for happens). It's true that we have set its thd->killed but it may not see it immediately and so may have time to reach the cond_wait(). + + However, where possible, we test for killed once again after + enter_cond(). This should make the signaling as safe as possible. + However, there is still a small chance of failure on platforms with + instruction or memory write reordering. */ if (mysys_var->current_cond && mysys_var->current_mutex) { diff --git a/sql/sql_class.h b/sql/sql_class.h index aa0f6cf1aa3..8b0399037ea 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1953,6 +1953,12 @@ public: DYNAMIC_ARRAY user_var_events; /* For user variables replication */ MEM_ROOT *user_var_events_alloc; /* Allocate above array elements here */ + /* + If checking this in conjunction with a wait condition, please + include a check after enter_cond() if you want to avoid a race + condition. For details see the implementation of awake(), + especially the "broadcast" part. + */ enum killed_state { NOT_KILLED=0, diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 4ed22e3a355..8a7f42b462d 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -712,6 +712,22 @@ bool do_command(THD *thd) net_new_transaction(net); + /* + Synchronization point for testing of KILL_CONNECTION. + This sync point can wait here, to simulate slow code execution + between the last test of thd->killed and blocking in read(). + + The goal of this test is to verify that a connection does not + hang, if it is killed at this point of execution. + (Bug#37780 - main.kill fails randomly) + + Note that the sync point wait itself will be terminated by a + kill. In this case it consumes a condition broadcast, but does + not change anything else. The consumed broadcast should not + matter here, because the read/recv() below doesn't use it. + */ + DEBUG_SYNC(thd, "before_do_command_net_read"); + if ((packet_length= my_net_read(net)) == packet_error) { DBUG_PRINT("info",("Got error %d reading command from socket %s", diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 2a2fe3eb36f..d9fefe35bd8 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -47,6 +47,7 @@ #include "records.h" // init_read_record, end_read_record #include "filesort.h" // filesort_free_buffers #include "sql_union.h" // mysql_union +#include "debug_sync.h" // DEBUG_SYNC #include #include #include @@ -852,6 +853,7 @@ JOIN::optimize() if (optimized) DBUG_RETURN(0); optimized= 1; + DEBUG_SYNC(thd, "before_join_optimize"); thd_proc_info(thd, "optimizing"); row_limit= ((select_distinct || order || group_list) ? HA_POS_ERROR : From 06c49d571be82ca927b9c37d96ab8353bd87359d Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 23 Oct 2010 20:55:44 +0800 Subject: [PATCH 101/304] Bug#27606 GRANT statement should be replicated with DEFINER information "Grantor" columns' data is lost when replicating mysql.tables_priv. Slave SQL thread used its default user ''@'' as the grantor of GRANT|REVOKE statements executing on it. In this patch, current user is put in query log event for all GRANT and REVOKE statement, SQL thread uses the user in query log event as grantor. mysql-test/suite/rpl/r/rpl_do_grant.result: Add test for this bug. mysql-test/suite/rpl/t/rpl_do_grant.test: Add test for this bug. sql/log_event.cc: Refactoring THD::current_user_used and related functions. current_user_used is used to judge if current user should be binlogged in query log event. So it is better to call it m_binlog_invoker. The related functions are renamed too. sql/sql_class.cc: Refactoring THD::current_user_used and related functions. current_user_used is used to judge if current user should be binlogged in query log event. So it is better to call it m_binlog_invoker. The related functions are renamed too. sql/sql_class.h: Refactoring THD::current_user_used and related functions. current_user_used is used to judge if current user should be binlogged in query log event. So it is better to call it m_binlog_invoker. The related functions are renamed too. sql/sql_parse.cc: Call binlog_invoker() for GRANT and REVOKE statements. --- mysql-test/suite/rpl/r/rpl_do_grant.result | 23 ++++++++++++++++++++++ mysql-test/suite/rpl/t/rpl_do_grant.test | 21 ++++++++++++++++++++ sql/log_event.cc | 2 +- sql/sql_class.cc | 6 +++--- sql/sql_class.h | 7 +++---- sql/sql_parse.cc | 7 +++++++ 6 files changed, 58 insertions(+), 8 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_do_grant.result b/mysql-test/suite/rpl/r/rpl_do_grant.result index 1cea2cfa9ad..6472294fe9d 100644 --- a/mysql-test/suite/rpl/r/rpl_do_grant.result +++ b/mysql-test/suite/rpl/r/rpl_do_grant.result @@ -260,4 +260,27 @@ Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # use `test`; grant all on *.* to foo@"1.2.3.4" master-bin.000001 # Query # # use `test`; revoke all privileges, grant option from "foo" DROP USER foo@"1.2.3.4"; + +# Bug#27606 GRANT statement should be replicated with DEFINER information +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; +GRANT SELECT, INSERT ON mysql.user TO user_bug27606@localhost; +SELECT Grantor FROM mysql.tables_priv WHERE User='user_bug27606'; +Grantor +root@localhost +SELECT Grantor FROM mysql.tables_priv WHERE User='user_bug27606'; +Grantor +root@localhost +REVOKE SELECT ON mysql.user FROM user_bug27606@localhost; +SELECT Grantor FROM mysql.tables_priv WHERE User='user_bug27606'; +Grantor +root@localhost +SELECT Grantor FROM mysql.tables_priv WHERE User='user_bug27606'; +Grantor +root@localhost +DROP USER user_bug27606@localhost; "End of test" diff --git a/mysql-test/suite/rpl/t/rpl_do_grant.test b/mysql-test/suite/rpl/t/rpl_do_grant.test index fb8ea35e869..c65eef6e939 100644 --- a/mysql-test/suite/rpl/t/rpl_do_grant.test +++ b/mysql-test/suite/rpl/t/rpl_do_grant.test @@ -355,4 +355,25 @@ revoke all privileges, grant option from "foo"; DROP USER foo@"1.2.3.4"; -- sync_slave_with_master +--echo +--echo # Bug#27606 GRANT statement should be replicated with DEFINER information +--connection master +--source include/master-slave-reset.inc +--connection master +GRANT SELECT, INSERT ON mysql.user TO user_bug27606@localhost; + +SELECT Grantor FROM mysql.tables_priv WHERE User='user_bug27606'; +sync_slave_with_master; +SELECT Grantor FROM mysql.tables_priv WHERE User='user_bug27606'; + +--connection master +REVOKE SELECT ON mysql.user FROM user_bug27606@localhost; +SELECT Grantor FROM mysql.tables_priv WHERE User='user_bug27606'; +sync_slave_with_master; +SELECT Grantor FROM mysql.tables_priv WHERE User='user_bug27606'; + +--connection master +DROP USER user_bug27606@localhost; + +--source include/master-slave-end.inc --echo "End of test" diff --git a/sql/log_event.cc b/sql/log_event.cc index 041f90a057f..d0635ddac1a 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2314,7 +2314,7 @@ bool Query_log_event::write(IO_CACHE* file) start+= 4; } - if (thd && thd->is_current_user_used()) + if (thd && thd->need_binlog_invoker()) { LEX_STRING user; LEX_STRING host; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 44bb6d51c6c..a61ce7bfd14 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -738,7 +738,7 @@ THD::THD() thr_lock_owner_init(&main_lock_id, &lock_info); m_internal_handler= NULL; - current_user_used= FALSE; + m_binlog_invoker= FALSE; memset(&invoker_user, 0, sizeof(invoker_user)); memset(&invoker_host, 0, sizeof(invoker_host)); } @@ -1247,7 +1247,7 @@ void THD::cleanup_after_query() where= THD::DEFAULT_WHERE; /* reset table map for multi-table update */ table_map_for_update= 0; - clean_current_user_used(); + m_binlog_invoker= FALSE; } @@ -3281,7 +3281,7 @@ void THD::set_query(char *query_arg, uint32 query_length_arg) void THD::get_definer(LEX_USER *definer) { - set_current_user_used(); + binlog_invoker(); #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) if (slave_thread && has_invoker()) { diff --git a/sql/sql_class.h b/sql/sql_class.h index 42c873e9fc3..774ae4abac4 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2344,9 +2344,8 @@ public: Protected with LOCK_thd_data mutex. */ void set_query(char *query_arg, uint32 query_length_arg); - void set_current_user_used() { current_user_used= TRUE; } - bool is_current_user_used() { return current_user_used; } - void clean_current_user_used() { current_user_used= FALSE; } + void binlog_invoker() { m_binlog_invoker= TRUE; } + bool need_binlog_invoker() { return m_binlog_invoker; } void get_definer(LEX_USER *definer); void set_invoker(const LEX_STRING *user, const LEX_STRING *host) { @@ -2384,7 +2383,7 @@ private: Current user will be binlogged into Query_log_event if current_user_used is TRUE; It will be stored into invoker_host and invoker_user by SQL thread. */ - bool current_user_used; + bool m_binlog_invoker; /** It points to the invoker in the Query_log_event. diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index b38cdf4a983..7cf64134d70 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3923,6 +3923,10 @@ end_with_restore_list: if (check_access(thd, UPDATE_ACL, "mysql", 0, 1, 1, 0) && check_global_access(thd,CREATE_USER_ACL)) break; + + /* Replicate current user as grantor */ + thd->binlog_invoker(); + /* Conditionally writes to binlog */ if (!(res = mysql_revoke_all(thd, lex->users_list))) my_ok(thd); @@ -3943,6 +3947,9 @@ end_with_restore_list: is_schema_db(select_lex->db) : 0)) goto error; + /* Replicate current user as grantor */ + thd->binlog_invoker(); + if (thd->security_ctx->user) // If not replication { LEX_USER *user, *tmp_user; From ed2e88e66c8dbdb2f6e95ffae7ff77a813d8148b Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Sun, 24 Oct 2010 20:31:51 -0700 Subject: [PATCH 102/304] Fix bug #57700 Latching order violation in row_truncate_table_for_mysql(). Approved by Sunny Bains --- storage/innodb_plugin/ChangeLog | 6 ++++++ storage/innodb_plugin/row/row0mysql.c | 23 ++++++++++++++--------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 3e1e4fc7a99..20d0fc86d00 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,9 @@ +2010-10-24 The InnoDB Team + + * row/row0mysql.c + Fix Bug #57700 Latching order violation in + row_truncate_table_for_mysql() + 2010-10-20 The InnoDB Team * dict/dict0load.c diff --git a/storage/innodb_plugin/row/row0mysql.c b/storage/innodb_plugin/row/row0mysql.c index f27afc253ff..24b7a983878 100644 --- a/storage/innodb_plugin/row/row0mysql.c +++ b/storage/innodb_plugin/row/row0mysql.c @@ -2782,15 +2782,6 @@ row_truncate_table_for_mysql( trx->table_id = table->id; - /* Lock all index trees for this table, as we will - truncate the table/index and possibly change their metadata. - All DML/DDL are blocked by table level lock, with - a few exceptions such as queries into information schema - about the table, MySQL could try to access index stats - for this kind of query, we need to use index locks to - sync up */ - dict_table_x_lock_indexes(table); - if (table->space && !table->dir_path_of_temp_table) { /* Discard and create the single-table tablespace. */ ulint space = table->space; @@ -2803,6 +2794,11 @@ row_truncate_table_for_mysql( dict_hdr_get_new_id(NULL, NULL, &space); + /* Lock all index trees for this table. We must + do so after dict_hdr_get_new_id() to preserve + the latch order */ + dict_table_x_lock_indexes(table); + if (space == ULINT_UNDEFINED || fil_create_new_single_table_tablespace( space, table->name, FALSE, flags, @@ -2836,6 +2832,15 @@ row_truncate_table_for_mysql( FIL_IBD_FILE_INITIAL_SIZE, &mtr); mtr_commit(&mtr); } + } else { + /* Lock all index trees for this table, as we will + truncate the table/index and possibly change their metadata. + All DML/DDL are blocked by table level lock, with + a few exceptions such as queries into information schema + about the table, MySQL could try to access index stats + for this kind of query, we need to use index locks to + sync up */ + dict_table_x_lock_indexes(table); } /* scan SYS_INDEXES for all indexes of the table */ From 112684b0ba31dbdc3f3b914a7f738793d28431fd Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Sun, 24 Oct 2010 22:51:21 -0700 Subject: [PATCH 103/304] Fix bug #57700 Latching order violation in row_truncate_table_for_mysql(). Approved by Sunny Bains --- storage/innodb_plugin/ChangeLog | 6 ++++++ storage/innodb_plugin/row/row0mysql.c | 23 ++++++++++++++--------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index cccd5c0550a..9033e5557f3 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,9 @@ +2010-10-24 The InnoDB Team + + * row/row0mysql.c + Fix Bug #57700 Latching order violation in + row_truncate_table_for_mysql() + 2010-10-20 The InnoDB Team * dict/dict0load.c diff --git a/storage/innodb_plugin/row/row0mysql.c b/storage/innodb_plugin/row/row0mysql.c index 107af481b79..827be32bdf7 100644 --- a/storage/innodb_plugin/row/row0mysql.c +++ b/storage/innodb_plugin/row/row0mysql.c @@ -2771,15 +2771,6 @@ row_truncate_table_for_mysql( trx->table_id = table->id; - /* Lock all index trees for this table, as we will - truncate the table/index and possibly change their metadata. - All DML/DDL are blocked by table level lock, with - a few exceptions such as queries into information schema - about the table, MySQL could try to access index stats - for this kind of query, we need to use index locks to - sync up */ - dict_table_x_lock_indexes(table); - if (table->space && !table->dir_path_of_temp_table) { /* Discard and create the single-table tablespace. */ ulint space = table->space; @@ -2792,6 +2783,11 @@ row_truncate_table_for_mysql( dict_hdr_get_new_id(NULL, NULL, &space); + /* Lock all index trees for this table. We must + do so after dict_hdr_get_new_id() to preserve + the latch order */ + dict_table_x_lock_indexes(table); + if (space == ULINT_UNDEFINED || fil_create_new_single_table_tablespace( space, table->name, FALSE, flags, @@ -2825,6 +2821,15 @@ row_truncate_table_for_mysql( FIL_IBD_FILE_INITIAL_SIZE, &mtr); mtr_commit(&mtr); } + } else { + /* Lock all index trees for this table, as we will + truncate the table/index and possibly change their metadata. + All DML/DDL are blocked by table level lock, with + a few exceptions such as queries into information schema + about the table, MySQL could try to access index stats + for this kind of query, we need to use index locks to + sync up */ + dict_table_x_lock_indexes(table); } /* scan SYS_INDEXES for all indexes of the table */ From 06a263e2b32bd6b5440933b4cec3eff37053cef7 Mon Sep 17 00:00:00 2001 From: "Horst.Hunger" Date: Mon, 25 Oct 2010 12:24:26 +0200 Subject: [PATCH 104/304] Due to failing on Freebsd. --- mysql-test/r/plugin_auth_qa_2.result | 30 ++++++++++++++++------------ mysql-test/t/plugin_auth_qa_1.test | 16 +++++++-------- mysql-test/t/plugin_auth_qa_2.test | 5 +++++ 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/mysql-test/r/plugin_auth_qa_2.result b/mysql-test/r/plugin_auth_qa_2.result index daefdaafabc..99fe9c6f5a9 100644 --- a/mysql-test/r/plugin_auth_qa_2.result +++ b/mysql-test/r/plugin_auth_qa_2.result @@ -84,8 +84,8 @@ GRANT PROXY ON qa_test_5_dest TO ''@'localhost'; SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; user plugin authentication_string password *DFCACE76914AD7BD801FC1A1ECF6562272621A22 -qa_test_5_user qa_auth_interface qa_test_5_dest qa_test_5_dest *DFCACE76914AD7BD801FC1A1ECF6562272621A22 +qa_test_5_user qa_auth_interface qa_test_5_dest exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=qa_test_5_user --password=qa_test_5_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 ERROR 1045 (28000): Access denied for user 'qa_test_5_user'@'localhost' (using password: YES) DROP USER qa_test_5_user; @@ -98,32 +98,35 @@ GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_6_dest identified by 'dest_pas GRANT PROXY ON qa_test_6_dest TO qa_test_6_user; SELECT user,plugin,authentication_string,password FROM mysql.user; user plugin authentication_string password -root -root -root -qa_test_6_user qa_auth_interface qa_test_6_dest qa_test_6_dest *DFCACE76914AD7BD801FC1A1ECF6562272621A22 +qa_test_6_user qa_auth_interface qa_test_6_dest +root +root +root +root exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=qa_test_6_user --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 ERROR 1045 (28000): Access denied for user 'qa_test_6_user'@'localhost' (using password: YES) GRANT PROXY ON qa_test_6_dest TO root IDENTIFIED WITH qa_auth_interface AS 'qa_test_6_dest'; SELECT user,plugin,authentication_string,password FROM mysql.user; user plugin authentication_string password -root -root -root -qa_test_6_user qa_auth_interface qa_test_6_dest qa_test_6_dest *DFCACE76914AD7BD801FC1A1ECF6562272621A22 +qa_test_6_user qa_auth_interface qa_test_6_dest +root +root +root +root root qa_auth_interface qa_test_6_dest exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) REVOKE PROXY ON qa_test_6_dest FROM root; SELECT user,plugin,authentication_string FROM mysql.user; user plugin authentication_string -root -root -root -qa_test_6_user qa_auth_interface qa_test_6_dest qa_test_6_dest +qa_test_6_user qa_auth_interface qa_test_6_dest +root +root +root +root root qa_auth_interface qa_test_6_dest exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) @@ -135,6 +138,7 @@ user plugin authentication_string password root root root +root === Test of the --default_auth option for clients ==== CREATE USER qa_test_11_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_11_dest'; CREATE USER qa_test_11_dest IDENTIFIED BY 'dest_passwd'; diff --git a/mysql-test/t/plugin_auth_qa_1.test b/mysql-test/t/plugin_auth_qa_1.test index c33c4c22893..06908935b01 100644 --- a/mysql-test/t/plugin_auth_qa_1.test +++ b/mysql-test/t/plugin_auth_qa_1.test @@ -18,7 +18,7 @@ GRANT PROXY ON plug_dest TO plug_user; --exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 REVOKE PROXY ON plug_dest FROM plug_user; --error 1 ---exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 +--exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 DROP USER plug_user,plug_dest; # # GRANT...WITH @@ -40,7 +40,7 @@ REVOKE ALL PRIVILEGES ON test_user_db.* FROM 'plug_user' REVOKE PROXY ON plug_dest FROM plug_user; --echo 3) --error 1 ---exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 +--exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 DROP USER plug_user,plug_dest; # # GRANT...WITH/CREATE...BY @@ -49,7 +49,7 @@ GRANT ALL PRIVILEGES ON test_user_db.* TO plug_user CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; --echo 1) --error 1 ---exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 +--exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();USE test_user_db;CREATE TABLE t1(a int);SHOW TABLES;DROP TABLE t1;" 2>&1 GRANT PROXY ON plug_dest TO plug_user; --echo 2) --replace_result $MASTER_MYSOCK MASTER_MYSOCK $PLUGIN_AUTH_OPT PLUGIN_AUTH_OPT @@ -71,10 +71,10 @@ GRANT PROXY ON plug_dest TO plug_user; --exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 RENAME USER plug_dest TO new_dest; --error 1 ---exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 +--exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 GRANT PROXY ON new_dest TO plug_user; --error 1 ---exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=new_dest -e "SELECT current_user();SELECT user();" 2>&1 +--exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=new_dest -e "SELECT current_user();SELECT user();" 2>&1 --sorted_result SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; DROP USER plug_user,new_dest; @@ -84,16 +84,16 @@ CREATE USER plug_user IDENTIFIED WITH test_plugin_server AS 'plug_dest'; CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd'; --error 1 ---exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 +--exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 GRANT PROXY ON plug_dest TO plug_user; --replace_result $MASTER_MYSOCK MASTER_MYSOCK $PLUGIN_AUTH_OPT PLUGIN_AUTH_OPT --exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 RENAME USER plug_dest TO new_dest; --error 1 ---exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 +--exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=plug_dest -e "SELECT current_user();SELECT user();" 2>&1 GRANT PROXY ON new_dest TO plug_user; --error 1 ---exec $MYSQL -S var/tmp/mysqld.1.sock -u plug_user $PLUGIN_AUTH_OPT --password=new_dest -e "SELECT current_user();SELECT user();" 2>&1 +--exec $MYSQL -S $MASTER_MYSOCK -u plug_user $PLUGIN_AUTH_OPT --password=new_dest -e "SELECT current_user();SELECT user();" 2>&1 --sorted_result SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root'; DROP USER plug_user,new_dest; diff --git a/mysql-test/t/plugin_auth_qa_2.test b/mysql-test/t/plugin_auth_qa_2.test index 135b187f6ee..e265690dc7d 100644 --- a/mysql-test/t/plugin_auth_qa_2.test +++ b/mysql-test/t/plugin_auth_qa_2.test @@ -88,6 +88,7 @@ GRANT ALL PRIVILEGES ON test_user_db.* TO ''@'localhost' identified by 'dest_pas GRANT PROXY ON qa_test_5_dest TO qa_test_5_user; GRANT PROXY ON qa_test_5_dest TO ''@'localhost'; +--sorted_result SELECT user,plugin,authentication_string,password FROM mysql.user WHERE user != 'root'; --echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=qa_test_5_user --password=qa_test_5_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 @@ -105,6 +106,7 @@ CREATE USER qa_test_6_dest IDENTIFIED BY 'dest_passwd'; GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_6_dest identified by 'dest_passwd'; GRANT PROXY ON qa_test_6_dest TO qa_test_6_user; +--sorted_result SELECT user,plugin,authentication_string,password FROM mysql.user; --echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=qa_test_6_user --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 @@ -112,6 +114,7 @@ SELECT user,plugin,authentication_string,password FROM mysql.user; --exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=qa_test_6_user --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 GRANT PROXY ON qa_test_6_dest TO root IDENTIFIED WITH qa_auth_interface AS 'qa_test_6_dest'; +--sorted_result SELECT user,plugin,authentication_string,password FROM mysql.user; --echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 @@ -119,6 +122,7 @@ SELECT user,plugin,authentication_string,password FROM mysql.user; --exec $MYSQL $PLUGIN_AUTH_OPT -h localhost -P $MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 REVOKE PROXY ON qa_test_6_dest FROM root; +--sorted_result SELECT user,plugin,authentication_string FROM mysql.user; --echo exec MYSQL PLUGIN_AUTH_OPT -h localhost -P MASTER_MYPORT --user=root --password=qa_test_6_dest test_user_db -e "SELECT current_user(),user(),@@local.proxy_user,@@local.external_user;" 2>&1 @@ -128,6 +132,7 @@ SELECT user,plugin,authentication_string FROM mysql.user; DROP USER qa_test_6_user; DROP USER qa_test_6_dest; DELETE FROM mysql.user WHERE user='root' AND plugin='qa_auth_interface'; +--sorted_result SELECT user,plugin,authentication_string,password FROM mysql.user; From 56354413f86be103ce6c30aed879562894fb28e6 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Mon, 25 Oct 2010 14:07:28 +0200 Subject: [PATCH 105/304] Revert simplified if() in mysql-test/include/show_events.inc --- mysql-test/include/show_events.inc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mysql-test/include/show_events.inc b/mysql-test/include/show_events.inc index df17534eb82..ff5a7105c24 100644 --- a/mysql-test/include/show_events.inc +++ b/mysql-test/include/show_events.inc @@ -25,7 +25,9 @@ if ($binlog_file) --let $_statement= $_statement from $binlog_start -if ($binlog_limit) +# Cannot use if($binlog_limit) since the variable may begin with a 0 + +if (`SELECT '$binlog_limit' <> ''`) { --let $_statement= $_statement limit $binlog_limit } From 4b36063336775fa892a2b6b9b47d8b27ae44b4de Mon Sep 17 00:00:00 2001 From: Kristofer Pettersson Date: Mon, 25 Oct 2010 14:30:07 +0200 Subject: [PATCH 106/304] Bug#54569 Some options are not allowed to take argument when passed with loose- prefix Boolean options cause parsing failures when they are given with prefix loose- and an argument, either in the command line or in configuration file. The reason was a faulty logic which forced the parsing to throw an error when an argument of type NO_ARG was used together with an argument which has been identified as a key-value pair. Despite the attribute NO_ARG these options actually take arguments if they are of type BOOL. include/my_getopt.h: * More comments to help future refactoring mysys/my_getopt.c: * removed if-statement which prevented logic for handling boolean types with arguments to be executed. * Added comments to aid in future refactoring. --- include/my_getopt.h | 7 +++++++ mysys/my_getopt.c | 22 +++++++++------------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/include/my_getopt.h b/include/my_getopt.h index 5eb0004e9c3..47feb21d85e 100644 --- a/include/my_getopt.h +++ b/include/my_getopt.h @@ -39,6 +39,13 @@ C_MODE_START #define GET_ASK_ADDR 128 #define GET_TYPE_MASK 127 +/** + Enumeration of the my_option::arg_type attributes. + It should be noted that for historical reasons variables with the combination + arg_type=NO_ARG, my_option::var_type=GET_BOOL still accepts + arguments. This is someone counter intuitive and care should be taken + if the code is refactored. +*/ enum get_opt_arg_type { NO_ARG, OPT_ARG, REQUIRED_ARG }; struct st_typelib; diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 2ec2f8eb5c9..5e66d2fc189 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -360,14 +360,6 @@ int handle_options(int *argc, char ***argv, } return EXIT_OPTION_DISABLED; } - if (must_be_var && optp->arg_type == NO_ARG) - { - if (my_getopt_print_errors) - my_getopt_error_reporter(ERROR_LEVEL, - "%s: option '%s' cannot take an argument", - my_progname, optp->name); - return EXIT_NO_ARGUMENT_ALLOWED; - } error= 0; value= optp->var_type & GET_ASK_ADDR ? (*getopt_get_addr)(key_name, (uint) strlen(key_name), optp, &error) : @@ -377,6 +369,11 @@ int handle_options(int *argc, char ***argv, if (optp->arg_type == NO_ARG) { + /* + Due to historical reasons GET_BOOL var_types still accepts arguments + despite the NO_ARG arg_type attribute. This can seems a bit unintuitive + and care should be taken when refactoring this code. + */ if (optend && (optp->var_type & GET_TYPE_MASK) != GET_BOOL) { if (my_getopt_print_errors) @@ -391,7 +388,7 @@ int handle_options(int *argc, char ***argv, Set bool to 1 if no argument or if the user has used --enable-'option-name'. *optend was set to '0' if one used --disable-option - */ + */ (*argc)--; if (!optend || *optend == '1' || !my_strcasecmp(&my_charset_latin1, optend, "true")) @@ -418,10 +415,9 @@ int handle_options(int *argc, char ***argv, else if (optp->arg_type == REQUIRED_ARG && !optend) { /* Check if there are more arguments after this one, - - Note: options loaded from config file that requires value - should always be in the form '--option=value'. - */ + Note: options loaded from config file that requires value + should always be in the form '--option=value'. + */ if (!is_cmdline_arg || !*++pos) { if (my_getopt_print_errors) From 56f6599e7c3f3b8ea0edf223c96557e111672257 Mon Sep 17 00:00:00 2001 From: Tor Didriksen Date: Mon, 25 Oct 2010 17:08:27 +0200 Subject: [PATCH 107/304] Bug#45288: pb2 returns a lot of compilation warnings sql/sql_lex.h:1437: warning: control reaches end of non-void function sql/sql_lex.h: Make compiler happy, by adding a return statement. --- sql/sql_lex.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 0f93275434d..c20c2f0bca2 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1389,6 +1389,7 @@ public: STMT_ACCESS_TABLE_COUNT }; +#ifndef DBUG_OFF static inline const char *stmt_accessed_table_string(enum_stmt_accessed_table accessed_table) { switch (accessed_table) @@ -1422,7 +1423,10 @@ public: DBUG_ASSERT(0); break; } + MY_ASSERT_UNREACHABLE(); + return ""; } +#endif /* DBUG */ #define BINLOG_DIRECT_ON 0xF0 /* unsafe when --binlog-direct-non-trans-updates From ef7982fd17b046d19e783ff1bea03af1602c381a Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Mon, 25 Oct 2010 18:11:58 +0300 Subject: [PATCH 108/304] Bug #57689: mysql_change_user() breaks user connection on older clients COM_CHANGE_USER was always handled like an implicit request to change the client plugin, so that the client can re-use the same code path for both normal login and COM_CHANGE_USER. However this doesn't really work well with old clients because they don't understand the request to change a client plugin. Fixed by implementing a special state in the code (and old client issuing COM_CHANGE_USER). In this state the server parses the COM_CHANGE_USER package and pushes back the password hash, the user name and the database to the input stream in the same order that the native password server side plugin expects. As a result it replies with an OK/FAIL just like the old server does thus making the new server compatible with older clients. No test case added, since it would requre an old client binary. Tested using accounts with and without passwords. Tested with a correct and incorrect password. --- sql/sql_acl.cc | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 49224444f5c..c741a50a1db 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -8091,6 +8091,24 @@ static bool send_plugin_request_packet(MPVIO_EXT *mpvio, DBUG_RETURN (1); } + /* + If we're dealing with an older client we can't just send a change plugin + packet to re-initiate the authentication handshake, because the client + won't understand it. The good thing is that we don't need to : the old client + expects us to just check the user credentials here, which we can do by just reading + the cached data that are placed there by parse_com_change_user_packet() + In this case we just do nothing and behave as if normal authentication + should continue. + */ + if (!(mpvio->client_capabilities & CLIENT_PLUGIN_AUTH)) + { + DBUG_PRINT("info", ("old client sent a COM_CHANGE_USER")); + DBUG_ASSERT(mpvio->cached_client_reply.pkt); + /* get the status back so the read can process the cached result */ + mpvio->status= MPVIO_EXT::RESTART; + DBUG_RETURN(0); + } + DBUG_PRINT("info", ("requesting client to use the %s plugin", client_auth_plugin)); DBUG_RETURN(net_write_command(net, switch_plugin_request_buf[0], @@ -8574,8 +8592,16 @@ static int server_mpvio_write_packet(MYSQL_PLUGIN_VIO *param, int res; DBUG_ENTER("server_mpvio_write_packet"); - /* reset cached_client_reply */ - mpvio->cached_client_reply.pkt= 0; + /* + Reset cached_client_reply if not an old client doing mysql_change_user, + as this is where the password from COM_CHANGE_USER is stored. + */ + if (!((!(mpvio->client_capabilities & CLIENT_PLUGIN_AUTH)) && + mpvio->status == MPVIO_EXT::RESTART && + mpvio->cached_client_reply.plugin == + ((st_mysql_auth *) (plugin_decl(mpvio->plugin)->info))->client_auth_plugin + )) + mpvio->cached_client_reply.pkt= 0; /* for the 1st packet we wrap plugin data into the handshake packet */ if (mpvio->packets_written == 0) res= send_server_handshake_packet(mpvio, (char*) packet, packet_len); @@ -8641,6 +8667,15 @@ static int server_mpvio_read_packet(MYSQL_PLUGIN_VIO *param, uchar **buf) mpvio->packets_read++; DBUG_RETURN ((int) mpvio->cached_client_reply.pkt_len); } + + /* older clients don't support change of client plugin request */ + if (!(mpvio->client_capabilities & CLIENT_PLUGIN_AUTH)) + { + mpvio->status= MPVIO_EXT::FAILURE; + pkt_len= packet_error; + goto err; + } + /* But if the client has used the wrong plugin, the cached data are useless. Furthermore, we have to send a "change plugin" request From e86b6c0db40116cb0dc223999e45712e1b1908ef Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Tue, 26 Oct 2010 15:48:08 +0400 Subject: [PATCH 109/304] Patch for Bug#55850 (Trigger warnings not cleared). The problem was that the warnings risen by a trigger were not cleared upon successful completion. The warnings should be cleared if the trigger completes successfully. The fix is to skip merging warnings into caller's Warning Info for triggers. --- mysql-test/r/signal.result | 7 -- mysql-test/r/sp-error.result | 91 +++++++++----- mysql-test/r/trigger.result | 23 ---- mysql-test/suite/rpl/r/rpl_row_trig003.result | 6 - mysql-test/t/sp-error.test | 114 ++++++++++++------ sql/sp_head.cc | 26 +++- sql/sp_head.h | 2 +- 7 files changed, 162 insertions(+), 107 deletions(-) diff --git a/mysql-test/r/signal.result b/mysql-test/r/signal.result index 67bf9330451..cfa056d5d13 100644 --- a/mysql-test/r/signal.result +++ b/mysql-test/r/signal.result @@ -1379,9 +1379,6 @@ MESSAGE_TEXT = msg, MYSQL_ERRNO = 1012; end $$ insert into t1 values (1), (2) $$ -Warnings: -Warning 1012 This trigger SIGNAL a warning, a=1 -Warning 1012 This trigger SIGNAL a warning, a=2 drop trigger t1_ai $$ create trigger t1_ai after insert on t1 for each row begin @@ -1416,11 +1413,7 @@ MESSAGE_TEXT = NEW.msg, MYSQL_ERRNO = NEW.errno; end $$ insert into t1 set errno=1012, msg='Warning message 1 in trigger' $$ -Warnings: -Warning 1012 Warning message 1 in trigger insert into t1 set errno=1013, msg='Warning message 2 in trigger' $$ -Warnings: -Warning 1013 Warning message 2 in trigger drop table t1 $$ drop table if exists t1 $$ drop procedure if exists p1 $$ diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index 7b8364379df..4e97429c48f 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -1877,9 +1877,6 @@ DROP PROCEDURE p1; # # Bug#5889: Exit handler for a warning doesn't hide the warning in trigger # - -# - Case 1 - CREATE TABLE t1(a INT, b INT); INSERT INTO t1 VALUES (1, 2); CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW @@ -1889,40 +1886,13 @@ SET NEW.a = 10; SET NEW.a = 99999999999; END| UPDATE t1 SET b = 20; -Warnings: -Warning 1264 Out of range value for column 'a' at row 1 SHOW WARNINGS; Level Code Message -Warning 1264 Out of range value for column 'a' at row 1 SELECT * FROM t1; a b 10 20 DROP TRIGGER t1_bu; DROP TABLE t1; - -# - Case 2 - -CREATE TABLE t1(a INT); -CREATE TABLE t2(b CHAR(1)); -CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW -BEGIN -INSERT INTO t2 VALUES('ab'); # Produces a warning. -INSERT INTO t2 VALUES('b'); # Does not produce a warning, -# previous warning should be cleared. -END| -INSERT INTO t1 VALUES(0); -SHOW WARNINGS; -Level Code Message -SELECT * FROM t1; -a -0 -SELECT * FROM t2; -b -a -b -DROP TRIGGER t1_bi; -DROP TABLE t1; -DROP TABLE t2; # # Bug#9857: Stored procedures: handler for sqlwarning ignored # @@ -1961,3 +1931,64 @@ Warning 1365 Division by 0 DROP PROCEDURE p1; DROP PROCEDURE p2; SET sql_mode = @sql_mode_saved; +# +# Bug#55850: Trigger warnings not cleared. +# +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +DROP PROCEDURE IF EXISTS p1; +CREATE TABLE t1(x SMALLINT, y SMALLINT, z SMALLINT); +CREATE TABLE t2(a SMALLINT, b SMALLINT, c SMALLINT, +d SMALLINT, e SMALLINT, f SMALLINT); +CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW +INSERT INTO t2(a, b, c) VALUES(99999, 99999, 99999); +CREATE TRIGGER t1_ai AFTER INSERT ON t1 FOR EACH ROW +INSERT INTO t2(d, e, f) VALUES(99999, 99999, 99999); +CREATE PROCEDURE p1() +INSERT INTO t1 VALUES(99999, 99999, 99999); + +CALL p1(); +Warnings: +Warning 1264 Out of range value for column 'x' at row 1 +Warning 1264 Out of range value for column 'y' at row 1 +Warning 1264 Out of range value for column 'z' at row 1 + +SHOW WARNINGS; +Level Code Message +Warning 1264 Out of range value for column 'x' at row 1 +Warning 1264 Out of range value for column 'y' at row 1 +Warning 1264 Out of range value for column 'z' at row 1 + +DROP TABLE t1; +DROP TABLE t2; +DROP PROCEDURE p1; +# ---------------------------------------------------------------------- +CREATE TABLE t1(x SMALLINT, y SMALLINT, z SMALLINT); +CREATE TABLE t2(a SMALLINT, b SMALLINT, c SMALLINT NOT NULL); +CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW +BEGIN +INSERT INTO t2 VALUES( +CAST('111111 ' AS SIGNED), +CAST('222222 ' AS SIGNED), +NULL); +END| +CREATE PROCEDURE p1() +INSERT INTO t1 VALUES(99999, 99999, 99999); + +CALL p1(); +ERROR 23000: Column 'c' cannot be null + +SHOW WARNINGS; +Level Code Message +Warning 1264 Out of range value for column 'x' at row 1 +Warning 1264 Out of range value for column 'y' at row 1 +Warning 1264 Out of range value for column 'z' at row 1 +Warning 1292 Truncated incorrect INTEGER value: '111111 ' +Warning 1264 Out of range value for column 'a' at row 1 +Warning 1292 Truncated incorrect INTEGER value: '222222 ' +Warning 1264 Out of range value for column 'b' at row 1 +Error 1048 Column 'c' cannot be null + +DROP TABLE t1; +DROP TABLE t2; +DROP PROCEDURE p1; diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result index b9b1c94ce1a..b24c5b87fa0 100644 --- a/mysql-test/r/trigger.result +++ b/mysql-test/r/trigger.result @@ -1072,8 +1072,6 @@ SELECT @x; NULL SET @x=2; UPDATE t1 SET i1 = @x; -Warnings: -Warning 1365 Division by 0 SELECT @x; @x NULL @@ -1085,9 +1083,6 @@ SELECT @x; NULL SET @x=4; UPDATE t1 SET i1 = @x; -Warnings: -Warning 1365 Division by 0 -Warning 1365 Division by 0 SELECT @x; @x NULL @@ -1198,8 +1193,6 @@ Warnings: Warning 1365 Division by 0 create trigger t1_bi before insert on t1 for each row set @a:=1/0| insert into t1 values(20, 20)| -Warnings: -Warning 1365 Division by 0 drop trigger t1_bi| create trigger t1_bi before insert on t1 for each row begin @@ -1218,8 +1211,6 @@ set @a:=1/0; end| set @check=0, @t4_bi_called=0, @t4_bu_called=0| insert into t1 values(30, 30)| -Warnings: -Warning 1365 Division by 0 select @check, @t4_bi_called, @t4_bu_called| @check @t4_bi_called @t4_bu_called 2 1 1 @@ -2090,12 +2081,8 @@ SELECT 1 FROM t1 c WHERE END// SET @bug51650 = 1; INSERT IGNORE INTO t2 VALUES(); -Warnings: -Warning 1329 No data - zero rows fetched, selected, or processed INSERT IGNORE INTO t1 SET b = '777'; INSERT IGNORE INTO t2 SET a = '111'; -Warnings: -Warning 1329 No data - zero rows fetched, selected, or processed SET @bug51650 = 1; INSERT IGNORE INTO t2 SET a = '777'; DROP TRIGGER trg1; @@ -2177,8 +2164,6 @@ SELECT 'ab' INTO a; SELECT 'a' INTO a; END| INSERT INTO t1 VALUES (1); -Warnings: -Warning 1265 Data truncated for column 'a' at row 1 DROP TRIGGER trg1; DROP TABLE t1; DROP TRIGGER IF EXISTS trg1; @@ -2196,20 +2181,12 @@ DECLARE trg2 CHAR; SELECT 'ab' INTO trg2; END| INSERT INTO t1 VALUES (0); -Warnings: -Warning 1265 Data truncated for column 'trg1' at row 1 -Warning 1265 Data truncated for column 'trg2' at row 1 SELECT * FROM t1; a 0 SHOW WARNINGS; Level Code Message INSERT INTO t1 VALUES (1),(2); -Warnings: -Warning 1265 Data truncated for column 'trg1' at row 1 -Warning 1265 Data truncated for column 'trg2' at row 1 -Warning 1265 Data truncated for column 'trg1' at row 1 -Warning 1265 Data truncated for column 'trg2' at row 1 DROP TRIGGER trg1; DROP TRIGGER trg2; DROP TABLE t1; diff --git a/mysql-test/suite/rpl/r/rpl_row_trig003.result b/mysql-test/suite/rpl/r/rpl_row_trig003.result index 131af933b41..43c2ecde2b4 100644 --- a/mysql-test/suite/rpl/r/rpl_row_trig003.result +++ b/mysql-test/suite/rpl/r/rpl_row_trig003.result @@ -69,15 +69,9 @@ INSERT INTO test.t2 VALUES(NULL,0,'Testing MySQL databases is a cool ', 'MySQL C UPDATE test.t1 SET b1 = 0 WHERE b1 = 1; INSERT INTO test.t2 VALUES(NULL,1,'This is an after update test.', 'If this works, total will not be zero on the master or slave',1.4321,5.221,0,YEAR(NOW()),NOW()); UPDATE test.t2 SET b1 = 0 WHERE b1 = 1; -Warnings: -Error 1329 No data - zero rows fetched, selected, or processed INSERT INTO test.t1 VALUES(NULL,1,'add some more test data test.', 'and hope for the best', 3.321,5.221,0,YEAR(NOW()),NOW()); DELETE FROM test.t1 WHERE id = 1; -Warnings: -Error 1329 No data - zero rows fetched, selected, or processed DELETE FROM test.t2 WHERE id = 1; -Warnings: -Error 1329 No data - zero rows fetched, selected, or processed DROP TRIGGER test.t1_bi; DROP TRIGGER test.t2_ai; DROP TRIGGER test.t1_bu; diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index 13ca55a0127..6175fc53adf 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -2719,10 +2719,6 @@ DROP PROCEDURE p1; --echo # Bug#5889: Exit handler for a warning doesn't hide the warning in trigger --echo # ---echo ---echo # - Case 1 ---echo - CREATE TABLE t1(a INT, b INT); INSERT INTO t1 VALUES (1, 2); @@ -2747,36 +2743,6 @@ SELECT * FROM t1; DROP TRIGGER t1_bu; DROP TABLE t1; ---echo ---echo # - Case 2 ---echo - -CREATE TABLE t1(a INT); -CREATE TABLE t2(b CHAR(1)); - -delimiter |; - -CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW -BEGIN - INSERT INTO t2 VALUES('ab'); # Produces a warning. - - INSERT INTO t2 VALUES('b'); # Does not produce a warning, - # previous warning should be cleared. -END| - -delimiter ;| - -INSERT INTO t1 VALUES(0); - -SHOW WARNINGS; - -SELECT * FROM t1; -SELECT * FROM t2; - -DROP TRIGGER t1_bi; -DROP TABLE t1; -DROP TABLE t2; - --echo # --echo # Bug#9857: Stored procedures: handler for sqlwarning ignored --echo # @@ -2813,3 +2779,83 @@ SHOW WARNINGS; DROP PROCEDURE p1; DROP PROCEDURE p2; SET sql_mode = @sql_mode_saved; + +--echo # +--echo # Bug#55850: Trigger warnings not cleared. +--echo # + +--disable_warnings +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +DROP PROCEDURE IF EXISTS p1; +--enable_warnings + +CREATE TABLE t1(x SMALLINT, y SMALLINT, z SMALLINT); +CREATE TABLE t2(a SMALLINT, b SMALLINT, c SMALLINT, + d SMALLINT, e SMALLINT, f SMALLINT); + +CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW + INSERT INTO t2(a, b, c) VALUES(99999, 99999, 99999); + +CREATE TRIGGER t1_ai AFTER INSERT ON t1 FOR EACH ROW + INSERT INTO t2(d, e, f) VALUES(99999, 99999, 99999); + +CREATE PROCEDURE p1() + INSERT INTO t1 VALUES(99999, 99999, 99999); + +# What happened before the patch was: +# - INSERT INTO t1 added 3 warnings about overflow in 'x', 'y' and 'z' columns; +# - t1_bi run and added 3 warnings about overflow in 'a', 'b' and 'c' columns; +# - t1_ai run and added 3 warnings about overflow in 'd', 'e' and 'f' columns; +# => we had 9 warnings. +# +# Now what happens is: +# - INSERT INTO t1 adds 3 warnings about overflow in 'x', 'y' and 'z' columns; +# - t1_bi adds 3 warnings about overflow in 'a', 'b' and 'c' columns; +# - The warnings added by triggers are cleared; +# - t1_ai run and added 3 warnings about overflow in 'd', 'e' and 'f' columns; +# - The warnings added by triggers are cleared; +# => we have 3 warnings. + +--echo +CALL p1(); + +--echo +SHOW WARNINGS; + +--echo +DROP TABLE t1; +DROP TABLE t2; +DROP PROCEDURE p1; + +--echo # ---------------------------------------------------------------------- + +CREATE TABLE t1(x SMALLINT, y SMALLINT, z SMALLINT); +CREATE TABLE t2(a SMALLINT, b SMALLINT, c SMALLINT NOT NULL); + +delimiter |; + +CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW +BEGIN + INSERT INTO t2 VALUES( + CAST('111111 ' AS SIGNED), + CAST('222222 ' AS SIGNED), + NULL); +END| + +delimiter ;| + +CREATE PROCEDURE p1() + INSERT INTO t1 VALUES(99999, 99999, 99999); + +--echo +--error ER_BAD_NULL_ERROR +CALL p1(); + +--echo +SHOW WARNINGS; + +--echo +DROP TABLE t1; +DROP TABLE t2; +DROP PROCEDURE p1; diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 379e81d406e..0d33bd5c599 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1176,10 +1176,17 @@ find_handler_after_execution(THD *thd, sp_rcontext *ctx) /** Execute the routine. The main instruction jump loop is there. Assume the parameters already set. + + @param thd Thread context. + @param merge_da_on_success Flag specifying if Warning Info should be + propagated to the caller on Completion + Condition or not. + @todo - Will write this SP statement into binlog separately (TODO: consider changing the condition to "not inside event union") + @return Error status. @retval FALSE on success @retval @@ -1187,7 +1194,7 @@ find_handler_after_execution(THD *thd, sp_rcontext *ctx) */ bool -sp_head::execute(THD *thd) +sp_head::execute(THD *thd, bool merge_da_on_success) { DBUG_ENTER("sp_head::execute"); char saved_cur_db_name_buf[NAME_LEN+1]; @@ -1481,8 +1488,15 @@ sp_head::execute(THD *thd) thd->stmt_arena= old_arena; state= EXECUTED; - /* Restore the caller's original warning information area. */ - saved_warning_info->merge_with_routine_info(thd, thd->warning_info); + /* + Restore the caller's original warning information area: + - warnings generated during trigger execution should not be + propagated to the caller on success; + - if there was an exception during execution, warning info should be + propagated to the caller in any case. + */ + if (err_status || merge_da_on_success) + saved_warning_info->merge_with_routine_info(thd, thd->warning_info); thd->warning_info= saved_warning_info; done: @@ -1704,7 +1718,7 @@ sp_head::execute_trigger(THD *thd, thd->spcont= nctx; - err_status= execute(thd); + err_status= execute(thd, FALSE); err_with_cleanup: thd->restore_active_arena(&call_arena, &backup_arena); @@ -1921,7 +1935,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, */ thd->set_n_backup_active_arena(&call_arena, &backup_arena); - err_status= execute(thd); + err_status= execute(thd, TRUE); thd->restore_active_arena(&call_arena, &backup_arena); @@ -2154,7 +2168,7 @@ sp_head::execute_procedure(THD *thd, List *args) #endif if (!err_status) - err_status= execute(thd); + err_status= execute(thd, TRUE); if (save_log_general) thd->variables.option_bits &= ~OPTION_LOG_OFF; diff --git a/sql/sp_head.h b/sql/sp_head.h index e72ce6455f6..5efd48fc7c6 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -527,7 +527,7 @@ private: HASH m_sptabs; bool - execute(THD *thd); + execute(THD *thd, bool merge_da_on_success); /** Perform a forward flow analysis in the generated code. From c039e8249717c7d299f454f3b9877382e8fe7849 Mon Sep 17 00:00:00 2001 From: Marc Alff Date: Tue, 26 Oct 2010 19:35:02 +0200 Subject: [PATCH 110/304] Fixed test result --- mysql-test/suite/perfschema/r/schema.result | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/perfschema/r/schema.result b/mysql-test/suite/perfschema/r/schema.result index a802539b7e0..1599d51a59f 100644 --- a/mysql-test/suite/perfschema/r/schema.result +++ b/mysql-test/suite/perfschema/r/schema.result @@ -195,6 +195,6 @@ show create table THREADS; Table Create Table THREADS CREATE TABLE `THREADS` ( `THREAD_ID` int(11) NOT NULL, - `ID` int(11) NOT NULL, - `NAME` varchar(64) NOT NULL + `PROCESSLIST_ID` int(11) DEFAULT NULL, + `NAME` varchar(128) NOT NULL ) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8 From 840c602e83840c76c092c6d843eb83e7ff4aebb5 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 26 Oct 2010 14:18:31 -0500 Subject: [PATCH 111/304] Bug#57720 - Windows Vista and possibly Windows 7 can return ERROR_TIMEOUT instead of WAIT_TIMEOUT from calls to SleepConditionVariableCS() which is used in os0sync.c; os_cond_wait_timeout() where it is mapped to sleep_condition_variable(). Consider ERROR_TIMEOUT to be a timeout just like WAIT_TIMEOUT. In addition, test for EINTR as a possible return value from pthread_cond_timeout() in the posix section of os_cond_wait_timeout(), even though it is not supposed to be returned, but just to be safe. --- storage/innobase/os/os0sync.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/storage/innobase/os/os0sync.c b/storage/innobase/os/os0sync.c index 65fdd49f839..2f481b76bda 100644 --- a/storage/innobase/os/os0sync.c +++ b/storage/innobase/os/os0sync.c @@ -142,14 +142,24 @@ os_cond_wait_timed( ) { #ifdef __WIN__ - BOOL ret; + BOOL ret; + DWORD err; ut_a(sleep_condition_variable != NULL); ret = sleep_condition_variable(cond, mutex, time_in_ms); - if (!ret && GetLastError() == WAIT_TIMEOUT) { - return(TRUE); + if (!ret) { + err = GetLastError(); + /* From http://msdn.microsoft.com/en-us/library/ms686301%28VS.85%29.aspx, + "Condition variables are subject to spurious wakeups + (those not associated with an explicit wake) and stolen wakeups + (another thread manages to run before the woken thread)." + Check for both types of timeouts. + Conditions are checked by the caller.*/ + if ((err == WAIT_TIMEOUT) || (err == ERROR_TIMEOUT)) { + return(TRUE); + } } ut_a(ret); @@ -163,12 +173,15 @@ os_cond_wait_timed( switch (ret) { case 0: case ETIMEDOUT: - break; + /* We play it safe by checking for EINTR even though + according to the POSIX documentation it can't return EINTR. */ + case EINTR: + break; default: fprintf(stderr, " InnoDB: pthread_cond_timedwait() returned: " "%d: abstime={%lu,%lu}\n", - ret, abstime->tv_sec, abstime->tv_nsec); + ret, abstime->tv_sec, abstime->tv_nsec); ut_error; } @@ -663,7 +676,7 @@ os_event_wait_time_low( if (err == WAIT_OBJECT_0) { return(0); - } else if (err == WAIT_TIMEOUT) { + } else if ((err == WAIT_TIMEOUT) || (err == ERROR_TIMEOUT)) { return(OS_SYNC_TIME_EXCEEDED); } From 26738c280f77962771d68c5b43becdffa8831c51 Mon Sep 17 00:00:00 2001 From: Inaam Rana Date: Tue, 26 Oct 2010 16:54:18 -0400 Subject: [PATCH 112/304] Bug #57611 ibdata file and continuous growing undo logs rb://498 Fix handling of update_undo_logs at trx commit. Previously, when rseg->update_undo_list grows beyond 500 the update_undo_logs were marked with state TRX_UNDO_TO_FREE which should have been TRX_UNDO_TO_PURGE. Approved by: Sunny Bains --- storage/innobase/trx/trx0undo.c | 18 ++++-------------- storage/innodb_plugin/trx/trx0undo.c | 18 ++++-------------- 2 files changed, 8 insertions(+), 28 deletions(-) diff --git a/storage/innobase/trx/trx0undo.c b/storage/innobase/trx/trx0undo.c index 4547ee9ea64..329565943c8 100644 --- a/storage/innobase/trx/trx0undo.c +++ b/storage/innobase/trx/trx0undo.c @@ -1752,21 +1752,11 @@ trx_undo_set_state_at_finish( if (undo->size == 1 && mach_read_from_2(page_hdr + TRX_UNDO_PAGE_FREE) - < TRX_UNDO_PAGE_REUSE_LIMIT) { + < TRX_UNDO_PAGE_REUSE_LIMIT + && UT_LIST_GET_LEN(rseg->update_undo_list) < 500 + && UT_LIST_GET_LEN(rseg->insert_undo_list) < 500) { - /* This is a heuristic to avoid the problem of all UNDO - slots ending up in one of the UNDO lists. Previously if - the server crashed with all the slots in one of the lists, - transactions that required the slots of a different type - would fail for lack of slots. */ - - if (UT_LIST_GET_LEN(rseg->update_undo_list) < 500 - && UT_LIST_GET_LEN(rseg->insert_undo_list) < 500) { - - state = TRX_UNDO_CACHED; - } else { - state = TRX_UNDO_TO_FREE; - } + state = TRX_UNDO_CACHED; } else if (undo->type == TRX_UNDO_INSERT) { diff --git a/storage/innodb_plugin/trx/trx0undo.c b/storage/innodb_plugin/trx/trx0undo.c index c8a4b15e48b..76e88948e41 100644 --- a/storage/innodb_plugin/trx/trx0undo.c +++ b/storage/innodb_plugin/trx/trx0undo.c @@ -1823,21 +1823,11 @@ trx_undo_set_state_at_finish( if (undo->size == 1 && mach_read_from_2(page_hdr + TRX_UNDO_PAGE_FREE) - < TRX_UNDO_PAGE_REUSE_LIMIT) { + < TRX_UNDO_PAGE_REUSE_LIMIT + && UT_LIST_GET_LEN(rseg->update_undo_list) < 500 + && UT_LIST_GET_LEN(rseg->insert_undo_list) < 500) { - /* This is a heuristic to avoid the problem of all UNDO - slots ending up in one of the UNDO lists. Previously if - the server crashed with all the slots in one of the lists, - transactions that required the slots of a different type - would fail for lack of slots. */ - - if (UT_LIST_GET_LEN(rseg->update_undo_list) < 500 - && UT_LIST_GET_LEN(rseg->insert_undo_list) < 500) { - - state = TRX_UNDO_CACHED; - } else { - state = TRX_UNDO_TO_FREE; - } + state = TRX_UNDO_CACHED; } else if (undo->type == TRX_UNDO_INSERT) { From 1c3dc21f2a15e94425ded3f176fd2df5cb3eb025 Mon Sep 17 00:00:00 2001 From: Inaam Rana Date: Tue, 26 Oct 2010 17:06:24 -0400 Subject: [PATCH 113/304] Bug #57611 ibdata file and continuous growing undo logs rb://498 Fix handling of update_undo_logs at trx commit. Previously, when rseg->update_undo_list grows beyond 500 the update_undo_logs were marked with state TRX_UNDO_TO_FREE which should have been TRX_UNDO_TO_PURGE. In 5.5 we don't need the heuristic as we support multiple rollback segments. Approved by: Sunny Bains --- storage/innobase/trx/trx0undo.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/storage/innobase/trx/trx0undo.c b/storage/innobase/trx/trx0undo.c index 9162c82e423..ef877f4844d 100644 --- a/storage/innobase/trx/trx0undo.c +++ b/storage/innobase/trx/trx0undo.c @@ -1830,19 +1830,7 @@ trx_undo_set_state_at_finish( && mach_read_from_2(page_hdr + TRX_UNDO_PAGE_FREE) < TRX_UNDO_PAGE_REUSE_LIMIT) { - /* This is a heuristic to avoid the problem of all UNDO - slots ending up in one of the UNDO lists. Previously if - the server crashed with all the slots in one of the lists, - transactions that required the slots of a different type - would fail for lack of slots. */ - - if (UT_LIST_GET_LEN(rseg->update_undo_list) < 500 - && UT_LIST_GET_LEN(rseg->insert_undo_list) < 500) { - - state = TRX_UNDO_CACHED; - } else { - state = TRX_UNDO_TO_FREE; - } + state = TRX_UNDO_CACHED; } else if (undo->type == TRX_UNDO_INSERT) { From 431e3ee7c6a7b72b4dd2ba63862e13cb221e2f41 Mon Sep 17 00:00:00 2001 From: Inaam Rana Date: Tue, 26 Oct 2010 21:45:58 -0400 Subject: [PATCH 114/304] Fix compiler warning introduced by previous commit. --- storage/innobase/include/trx0undo.h | 2 -- storage/innobase/trx/trx0trx.c | 5 ++--- storage/innobase/trx/trx0undo.c | 4 ---- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/storage/innobase/include/trx0undo.h b/storage/innobase/include/trx0undo.h index 54809f9c2d5..937e9d7ef79 100644 --- a/storage/innobase/include/trx0undo.h +++ b/storage/innobase/include/trx0undo.h @@ -262,8 +262,6 @@ UNIV_INTERN page_t* trx_undo_set_state_at_finish( /*=========================*/ - trx_rseg_t* rseg, /*!< in: rollback segment memory object */ - trx_t* trx, /*!< in: transaction */ trx_undo_t* undo, /*!< in: undo log memory copy */ mtr_t* mtr); /*!< in: mtr */ /******************************************************************//** diff --git a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c index 6bae0527b53..7f2ca1f1471 100644 --- a/storage/innobase/trx/trx0trx.c +++ b/storage/innobase/trx/trx0trx.c @@ -753,8 +753,7 @@ trx_commit_off_kernel( mutex_enter(&(rseg->mutex)); if (trx->insert_undo != NULL) { - trx_undo_set_state_at_finish( - rseg, trx, trx->insert_undo, &mtr); + trx_undo_set_state_at_finish(trx->insert_undo, &mtr); } undo = trx->update_undo; @@ -769,7 +768,7 @@ trx_commit_off_kernel( transaction commit for this transaction. */ update_hdr_page = trx_undo_set_state_at_finish( - rseg, trx, undo, &mtr); + undo, &mtr); /* We have to do the cleanup for the update log while holding the rseg mutex because update log headers diff --git a/storage/innobase/trx/trx0undo.c b/storage/innobase/trx/trx0undo.c index ef877f4844d..4021a2ed573 100644 --- a/storage/innobase/trx/trx0undo.c +++ b/storage/innobase/trx/trx0undo.c @@ -1798,8 +1798,6 @@ UNIV_INTERN page_t* trx_undo_set_state_at_finish( /*=========================*/ - trx_rseg_t* rseg, /*!< in: rollback segment memory object */ - trx_t* trx __attribute__((unused)), /*!< in: transaction */ trx_undo_t* undo, /*!< in: undo log memory copy */ mtr_t* mtr) /*!< in: mtr */ { @@ -1808,10 +1806,8 @@ trx_undo_set_state_at_finish( page_t* undo_page; ulint state; - ut_ad(trx); ut_ad(undo); ut_ad(mtr); - ut_ad(mutex_own(&rseg->mutex)); if (undo->id >= TRX_RSEG_N_SLOTS) { fprintf(stderr, "InnoDB: Error: undo->id is %lu\n", From fcfda43ca3b60266429c6deb78489f82f9686e67 Mon Sep 17 00:00:00 2001 From: Anitha Gopi Date: Wed, 27 Oct 2010 09:54:04 +0530 Subject: [PATCH 115/304] Fixed bug numbers in disabled.def files --- mysql-test/collections/default.experimental | 2 -- mysql-test/suite/binlog/t/disabled.def | 3 ++- mysql-test/t/disabled.def | 5 +++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index 91dada3ee05..aa2f2e9f724 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -43,8 +43,6 @@ parts.partition_mgm_lc1_ndb # joro : NDB tests marked as experiment parts.partition_mgm_lc2_ndb # joro : NDB tests marked as experimental as agreed with bochklin parts.partition_syntax_ndb # joro : NDB tests marked as experimental as agreed with bochklin parts.partition_value_ndb # joro : NDB tests marked as experimental as agreed with bochklin -main.mysqlhotcopy_myisam # horst: due to bug#54129 -main.mysqlhotcopy_archive # horst: due to bug#54129 main.gis-rtree # svoj: due to BUG#38965 main.type_float # svoj: due to BUG#38965 main.type_newdecimal # svoj: due to BUG#38965 diff --git a/mysql-test/suite/binlog/t/disabled.def b/mysql-test/suite/binlog/t/disabled.def index 0018387de94..d261364756e 100644 --- a/mysql-test/suite/binlog/t/disabled.def +++ b/mysql-test/suite/binlog/t/disabled.def @@ -9,5 +9,6 @@ # Do not use any TAB characters for whitespace. # ############################################################################## -binlog_truncate_innodb : BUG#42643 2009-02-06 mats Changes to InnoDB requires to complete fix for BUG#36763 +binlog_truncate_innodb : BUG#57291 2010-10-20 anitha Originally disabled due to BUG#42643. Product bug fixed, but test changes needed + diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index cede26f555a..fb07cb2c7e4 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -12,5 +12,6 @@ kill : Bug#37780 2008-12-03 HHunger need some changes to be robust enough for pushbuild. query_cache_28249 : Bug#43861 2009-03-25 main.query_cache_28249 fails sporadically partition_innodb_plugin : Bug#53307 2010-04-30 VasilDimov valgrind warnings -main.mysqlhotcopy_myisam : bug#54129 2010-06-04 Horst -main.mysqlhotcopy_archive: bug#54129 2010-06-04 Horst +main.mysqlhotcopy_myisam : Bug#56817 2010-10-21 anitha mysqlhotcopy* fails +main.mysqlhotcopy_archive: Bug#56817 2010-10-21 anitha mysqlhotcopy* fails + From 0fbc74a451b33b10b66c4f47000ac0f2733c69f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 27 Oct 2010 09:54:20 +0300 Subject: [PATCH 116/304] Bug #57730 Clean up references to InnoDB Plugin CMakeLists.txt: Remove the checks for mysql_storage_engine.cmake and MYSQL_VERSION_ID. ha_innodb.cc, ha_innodb.h: Remove the checks for MYSQL_VERSION_ID. --- storage/innobase/CMakeLists.txt | 32 +++++---------------------- storage/innobase/handler/ha_innodb.cc | 14 ------------ storage/innobase/handler/ha_innodb.h | 3 +-- 3 files changed, 6 insertions(+), 43 deletions(-) diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt index 6cfd3d754f6..fa45cc96687 100644 --- a/storage/innobase/CMakeLists.txt +++ b/storage/innobase/CMakeLists.txt @@ -13,7 +13,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# This is the CMakeLists for InnoDB Plugin +# This is the CMakeLists for InnoDB INCLUDE(CheckFunctionExists) INCLUDE(CheckCSourceCompiles) @@ -254,29 +254,7 @@ IF(WITH_INNODB) SET(WITH_INNOBASE_STORAGE_ENGINE TRUE) ENDIF() - -#The plugin's CMakeLists.txt still needs to work with previous versions of MySQL. -IF(EXISTS ${SOURCE_DIR}/storage/mysql_storage_engine.cmake) - # Old plugin support on Windows only, - # use tricks to force ha_innodb.dll name for DLL - INCLUDE(${SOURCE_DIR}/storage/mysql_storage_engine.cmake) - MYSQL_STORAGE_ENGINE(INNOBASE) - GET_TARGET_PROPERTY(LIB_LOCATION ha_innobase LOCATION) - IF(LIB_LOCATION) - SET_TARGET_PROPERTIES(ha_innobase PROPERTIES OUTPUT_NAME ha_innodb) - ENDIF() -ELSEIF (MYSQL_VERSION_ID LESS "50137") - # Windows only, no plugin support - IF (NOT SOURCE_SUBLIBS) - ADD_DEFINITIONS(-DMYSQL_SERVER) - ADD_LIBRARY(innobase STATIC ${INNOBASE_SOURCES}) - # Require mysqld_error.h, which is built as part of the GenError - ADD_DEPENDENCIES(innobase GenError) - ENDIF() -ELSE() - # New plugin support, cross-platform , base name for shared module is "ha_innodb" - MYSQL_ADD_PLUGIN(innobase ${INNOBASE_SOURCES} STORAGE_ENGINE - DEFAULT - MODULE_OUTPUT_NAME ha_innodb - LINK_LIBRARIES ${ZLIB_LIBRARY}) -ENDIF() +MYSQL_ADD_PLUGIN(innobase ${INNOBASE_SOURCES} STORAGE_ENGINE + DEFAULT + MODULE_OUTPUT_NAME ha_innodb + LINK_LIBRARIES ${ZLIB_LIBRARY}) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 74c83e8d44b..ce4cba3356f 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -95,10 +95,6 @@ extern "C" { # define MYSQL_PLUGIN_IMPORT /* nothing */ # endif /* MYSQL_PLUGIN_IMPORT */ -#if MYSQL_VERSION_ID < 50124 -bool check_global_access(THD *thd, ulong want_access); -#endif /* MYSQL_VERSION_ID < 50124 */ - /** to protect innobase_open_files */ static mysql_mutex_t innobase_share_mutex; /** to force correct commit order in binlog */ @@ -1885,11 +1881,7 @@ innobase_convert_identifier( FALSE=id is an UTF-8 string */ { char nz[NAME_LEN + 1]; -#if MYSQL_VERSION_ID >= 50141 char nz2[NAME_LEN + 1 + EXPLAIN_FILENAME_MAX_EXTRA_LENGTH]; -#else /* MYSQL_VERSION_ID >= 50141 */ - char nz2[NAME_LEN + 1 + sizeof srv_mysql50_table_name_prefix]; -#endif /* MYSQL_VERSION_ID >= 50141 */ const char* s = id; int q; @@ -1907,13 +1899,9 @@ innobase_convert_identifier( nz[idlen] = 0; s = nz2; -#if MYSQL_VERSION_ID >= 50141 idlen = explain_filename((THD*) thd, nz, nz2, sizeof nz2, EXPLAIN_PARTITIONS_AS_COMMENT); goto no_quote; -#else /* MYSQL_VERSION_ID >= 50141 */ - idlen = filename_to_tablename(nz, nz2, sizeof nz2); -#endif /* MYSQL_VERSION_ID >= 50141 */ } /* See if the identifier needs to be quoted. */ @@ -1924,9 +1912,7 @@ innobase_convert_identifier( } if (q == EOF) { -#if MYSQL_VERSION_ID >= 50141 no_quote: -#endif /* MYSQL_VERSION_ID >= 50141 */ if (UNIV_UNLIKELY(idlen > buflen)) { idlen = buflen; } diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index 9c78c60d71e..f05ea8801f0 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -276,14 +276,13 @@ int thd_binlog_format(const MYSQL_THD thd); */ void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all); -#if MYSQL_VERSION_ID > 50140 /** Check if binary logging is filtered for thread's current db. @param thd Thread handle @retval 1 the query is not filtered, 0 otherwise. */ bool thd_binlog_filter_ok(const MYSQL_THD thd); -#endif /* MYSQL_VERSION_ID > 50140 */ + /** Check if the query may generate row changes which may end up in the binary. From 26d81a2a9835bc16b59010ebd4017ac508215643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 27 Oct 2010 09:56:56 +0300 Subject: [PATCH 117/304] Bug #57707 InnoDB buf_page_t size has doubled on 32-bit systems buf_page_t: Remove the buf_pool pointer. Add buf_pool_index:6 next to buf_fix_count:19 (it was buf_fix_count:25). This will limit the number of concurrent transactions to somewhere around 524,288. buf_pool_index(buf_pool): A new function to determine the index of a buffer pool in buf_pool_ptr[]. buf_pool_ptr: Make this a dynamically allocated array instead of an array of pointers. Allocate the array in buf_pool_init() and free in buf_pool_free(). buf_pool_free_instance(): No longer free the buf_pool object, as it is allocated from a big array. buf_pool_from_bpage(), buf_pool_from_block(): Move the definitions to the beginning of the files, because some compilers have (had) problems with forward definitions of inline functions. Calculate the buffer pool from buf_pool_index. buf_pool_from_array(): Add debug assertions for input validation. --- storage/innobase/buf/buf0buf.c | 33 ++++++------- storage/innobase/include/buf0buf.h | 25 +++++++--- storage/innobase/include/buf0buf.ic | 77 ++++++++++++++++++----------- 3 files changed, 81 insertions(+), 54 deletions(-) diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c index abfde83a3bd..03133e81ceb 100644 --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c @@ -246,8 +246,8 @@ static const int WAIT_FOR_READ = 5000; /** Number of attemtps made to read in a page in the buffer pool */ static const ulint BUF_PAGE_READ_MAX_RETRIES = 100; -/** The buffer buf_pool of the database */ -UNIV_INTERN buf_pool_t* buf_pool_ptr[MAX_BUFFER_POOLS]; +/** The buffer pools of the database */ +UNIV_INTERN buf_pool_t* buf_pool_ptr; #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG static ulint buf_dbg_counter = 0; /*!< This is used to insert validation @@ -858,7 +858,7 @@ buf_block_init( block->frame = frame; - block->page.buf_pool = buf_pool; + block->page.buf_pool_index = buf_pool_index(buf_pool); block->page.state = BUF_BLOCK_NOT_USED; block->page.buf_fix_count = 0; block->page.io_fix = BUF_IO_NONE; @@ -1280,8 +1280,6 @@ buf_pool_free_instance( mem_free(buf_pool->chunks); hash_table_free(buf_pool->page_hash); hash_table_free(buf_pool->zip_hash); - mem_free(buf_pool); - buf_pool = NULL; } /********************************************************************//** @@ -1294,25 +1292,22 @@ buf_pool_init( ulint total_size, /*!< in: size of the total pool in bytes */ ulint n_instances) /*!< in: number of instances */ { - ulint i; + ulint i; + const ulint size = total_size / n_instances; + + ut_ad(n_instances < MAX_BUFFER_POOLS); + ut_ad(n_instances == srv_buf_pool_instances); /* We create an extra buffer pool instance, this instance is used for flushing the flush lists, to keep track of n_flush for all the buffer pools and also used as a waiting object during flushing. */ + buf_pool_ptr = mem_zalloc(n_instances * sizeof *buf_pool_ptr); + for (i = 0; i < n_instances; i++) { - buf_pool_t* ptr; - ulint size; - - ptr = mem_zalloc(sizeof(*ptr)); - - size = total_size / n_instances; - - buf_pool_ptr[i] = ptr; + buf_pool_t* ptr = &buf_pool_ptr[i]; if (buf_pool_init_instance(ptr, size, i) != DB_SUCCESS) { - mem_free(buf_pool_ptr[i]); - /* Free all the instances created so far. */ buf_pool_free(i); @@ -1341,8 +1336,10 @@ buf_pool_free( for (i = 0; i < n_instances; i++) { buf_pool_free_instance(buf_pool_from_array(i)); - buf_pool_ptr[i] = NULL; } + + mem_free(buf_pool_ptr); + buf_pool_ptr = NULL; } /********************************************************************//** @@ -3685,7 +3682,7 @@ err_exit: bpage = buf_buddy_alloc(buf_pool, sizeof *bpage, &lru); /* Initialize the buf_pool pointer. */ - bpage->buf_pool = buf_pool; + bpage->buf_pool_index = buf_pool_index(buf_pool); /* If buf_buddy_alloc() allocated storage from the LRU list, it released and reacquired buf_pool->mutex. Thus, we must diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index b0fff919918..a42eba57fd2 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -69,7 +69,7 @@ Created 11/5/1995 Heikki Tuuri #define BUF_POOL_WATCH_SIZE 1 /*!< Maximum number of concurrent buffer pool watches */ -extern buf_pool_t* buf_pool_ptr[MAX_BUFFER_POOLS]; /*!< The buffer pools +extern buf_pool_t* buf_pool_ptr; /*!< The buffer pools of the database */ #ifdef UNIV_DEBUG extern ibool buf_debug_prints;/*!< If this is set TRUE, the program @@ -1034,6 +1034,15 @@ buf_page_address_fold( ulint space, /*!< in: space id */ ulint offset) /*!< in: offset of the page within space */ __attribute__((const)); +/********************************************************************//** +Calculates the index of a buffer pool to the buf_pool[] array. +@return the position of the buffer pool in buf_pool[] */ +UNIV_INLINE +ulint +buf_pool_index( +/*===========*/ + const buf_pool_t* buf_pool) /*!< in: buffer pool */ + __attribute__((nonnull, const)); /******************************************************************//** Returns the buffer pool instance given a page instance @return buf_pool */ @@ -1065,8 +1074,9 @@ Returns the buffer pool instance given its array index UNIV_INLINE buf_pool_t* buf_pool_from_array( -/*====================*/ - ulint index); /*!< in: array index to get buffer pool instance from */ +/*================*/ + ulint index); /*!< in: array index to get + buffer pool instance from */ /******************************************************************//** Returns the control block of a file page, NULL if not found. @return block, NULL if not found */ @@ -1204,8 +1214,13 @@ struct buf_page_struct{ unsigned io_fix:2; /*!< type of pending I/O operation; also protected by buf_pool->mutex @see enum buf_io_fix */ - unsigned buf_fix_count:25;/*!< count of how manyfold this block + unsigned buf_fix_count:19;/*!< count of how manyfold this block is currently bufferfixed */ + unsigned buf_pool_index:6;/*!< index number of the buffer pool + that this block belongs to */ +# if MAX_BUFFER_POOLS > 64 +# error "MAX_BUFFER_POOLS > 64; redefine buf_pool_index:6" +# endif /* @} */ #endif /* !UNIV_HOTBACKUP */ page_zip_des_t zip; /*!< compressed page; zip.data @@ -1324,8 +1339,6 @@ struct buf_page_struct{ frees a page in buffer pool */ # endif /* UNIV_DEBUG_FILE_ACCESSES */ #endif /* !UNIV_HOTBACKUP */ - buf_pool_t* buf_pool; /*!< buffer pool instance this - page belongs to */ }; /** The buffer control block structure */ diff --git a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0buf.ic index 713b7cb990d..e2e83de0a78 100644 --- a/storage/innobase/include/buf0buf.ic +++ b/storage/innobase/include/buf0buf.ic @@ -46,6 +46,48 @@ buf_pool_get_curr_size(void) return(srv_buf_pool_curr_size); } +/********************************************************************//** +Calculates the index of a buffer pool to the buf_pool[] array. +@return the position of the buffer pool in buf_pool[] */ +UNIV_INLINE +ulint +buf_pool_index( +/*===========*/ + const buf_pool_t* buf_pool) /*!< in: buffer pool */ +{ + ulint i = buf_pool - buf_pool_ptr; + ut_ad(i < MAX_BUFFER_POOLS); + ut_ad(i < srv_buf_pool_instances); + return(i); +} + +/******************************************************************//** +Returns the buffer pool instance given a page instance +@return buf_pool */ +UNIV_INLINE +buf_pool_t* +buf_pool_from_bpage( +/*================*/ + const buf_page_t* bpage) /*!< in: buffer pool page */ +{ + ulint i; + i = bpage->buf_pool_index; + ut_ad(i < srv_buf_pool_instances); + return(&buf_pool_ptr[i]); +} + +/******************************************************************//** +Returns the buffer pool instance given a block instance +@return buf_pool */ +UNIV_INLINE +buf_pool_t* +buf_pool_from_block( +/*================*/ + const buf_block_t* block) /*!< in: block */ +{ + return(buf_pool_from_bpage(&block->page)); +} + /*********************************************************************//** Gets the current size of buffer buf_pool in pages. @return size in pages*/ @@ -885,33 +927,6 @@ buf_block_buf_fix_dec( #endif } -/******************************************************************//** -Returns the buffer pool instance given a page instance -@return buf_pool */ -UNIV_INLINE -buf_pool_t* -buf_pool_from_bpage( -/*================*/ - const buf_page_t* bpage) /*!< in: buffer pool page */ -{ - /* Every page must be in some buffer pool. */ - ut_ad(bpage->buf_pool != NULL); - - return(bpage->buf_pool); -} - -/******************************************************************//** -Returns the buffer pool instance given a block instance -@return buf_pool */ -UNIV_INLINE -buf_pool_t* -buf_pool_from_block( -/*================*/ - const buf_block_t* block) /*!< in: block */ -{ - return(buf_pool_from_bpage(&block->page)); -} - /******************************************************************//** Returns the buffer pool instance given space and offset of page @return buffer pool */ @@ -929,7 +944,7 @@ buf_pool_get( ignored_offset = offset >> 6; /* 2log of BUF_READ_AHEAD_AREA (64)*/ fold = buf_page_address_fold(space, ignored_offset); index = fold % srv_buf_pool_instances; - return buf_pool_ptr[index]; + return(&buf_pool_ptr[index]); } /******************************************************************//** @@ -939,10 +954,12 @@ UNIV_INLINE buf_pool_t* buf_pool_from_array( /*================*/ - ulint index) /*!< in: array index to get + ulint index) /*!< in: array index to get buffer pool instance from */ { - return buf_pool_ptr[index]; + ut_ad(index < MAX_BUFFER_POOLS); + ut_ad(index < srv_buf_pool_instances); + return(&buf_pool_ptr[index]); } /******************************************************************//** From 02ca1fe3f12052f4d8bb14d0e394af480eccce3d Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Wed, 27 Oct 2010 11:16:52 +0400 Subject: [PATCH 118/304] Follow-up for Bug#55850: update funcs_1 result files. --- mysql-test/suite/funcs_1/r/innodb_trig_08.result | 4 ---- mysql-test/suite/funcs_1/r/memory_trig_08.result | 4 ---- mysql-test/suite/funcs_1/r/myisam_trig_08.result | 4 ---- 3 files changed, 12 deletions(-) diff --git a/mysql-test/suite/funcs_1/r/innodb_trig_08.result b/mysql-test/suite/funcs_1/r/innodb_trig_08.result index b2b38694680..a25147a1480 100644 --- a/mysql-test/suite/funcs_1/r/innodb_trig_08.result +++ b/mysql-test/suite/funcs_1/r/innodb_trig_08.result @@ -353,8 +353,6 @@ B Test 3.5.8.5-case 00191 0000000016 C=one C Test 3.5.8.5-case 00200 0000000001 C=one Insert into tb3 (f120, f122, f136) values ('d', 'Test 3.5.8.5-case', 152); -Warnings: -Warning 1265 Data truncated for column 'f120' at row 1 select f120, f122, f136, f144, @test_var from tb3 where f122 = 'Test 3.5.8.5-case' order by f120,f136; f120 f122 f136 f144 @test_var @@ -364,8 +362,6 @@ B Test 3.5.8.5-case 00191 0000000016 1*0000099999 C Test 3.5.8.5-case 00200 0000000001 1*0000099999 Insert into tb3 (f120, f122, f136, f144) values ('e', 'Test 3.5.8.5-case', 200, 8); -Warnings: -Warning 1265 Data truncated for column 'f120' at row 1 select f120, f122, f136, f144, @test_var from tb3 where f122 = 'Test 3.5.8.5-case' order by f120,f136; f120 f122 f136 f144 @test_var diff --git a/mysql-test/suite/funcs_1/r/memory_trig_08.result b/mysql-test/suite/funcs_1/r/memory_trig_08.result index 03505af95c5..3f303ef607f 100644 --- a/mysql-test/suite/funcs_1/r/memory_trig_08.result +++ b/mysql-test/suite/funcs_1/r/memory_trig_08.result @@ -354,8 +354,6 @@ B Test 3.5.8.5-case 00191 0000000016 C=one C Test 3.5.8.5-case 00200 0000000001 C=one Insert into tb3 (f120, f122, f136) values ('d', 'Test 3.5.8.5-case', 152); -Warnings: -Warning 1265 Data truncated for column 'f120' at row 1 select f120, f122, f136, f144, @test_var from tb3 where f122 = 'Test 3.5.8.5-case' order by f120,f136; f120 f122 f136 f144 @test_var @@ -365,8 +363,6 @@ B Test 3.5.8.5-case 00191 0000000016 1*0000099999 C Test 3.5.8.5-case 00200 0000000001 1*0000099999 Insert into tb3 (f120, f122, f136, f144) values ('e', 'Test 3.5.8.5-case', 200, 8); -Warnings: -Warning 1265 Data truncated for column 'f120' at row 1 select f120, f122, f136, f144, @test_var from tb3 where f122 = 'Test 3.5.8.5-case' order by f120,f136; f120 f122 f136 f144 @test_var diff --git a/mysql-test/suite/funcs_1/r/myisam_trig_08.result b/mysql-test/suite/funcs_1/r/myisam_trig_08.result index 03505af95c5..3f303ef607f 100644 --- a/mysql-test/suite/funcs_1/r/myisam_trig_08.result +++ b/mysql-test/suite/funcs_1/r/myisam_trig_08.result @@ -354,8 +354,6 @@ B Test 3.5.8.5-case 00191 0000000016 C=one C Test 3.5.8.5-case 00200 0000000001 C=one Insert into tb3 (f120, f122, f136) values ('d', 'Test 3.5.8.5-case', 152); -Warnings: -Warning 1265 Data truncated for column 'f120' at row 1 select f120, f122, f136, f144, @test_var from tb3 where f122 = 'Test 3.5.8.5-case' order by f120,f136; f120 f122 f136 f144 @test_var @@ -365,8 +363,6 @@ B Test 3.5.8.5-case 00191 0000000016 1*0000099999 C Test 3.5.8.5-case 00200 0000000001 1*0000099999 Insert into tb3 (f120, f122, f136, f144) values ('e', 'Test 3.5.8.5-case', 200, 8); -Warnings: -Warning 1265 Data truncated for column 'f120' at row 1 select f120, f122, f136, f144, @test_var from tb3 where f122 = 'Test 3.5.8.5-case' order by f120,f136; f120 f122 f136 f144 @test_var From c7371c9e757e72cdeef3991b28f0980030d52ca5 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Wed, 27 Oct 2010 18:12:10 +0400 Subject: [PATCH 119/304] Bug#57477 SIGFPE when dividing a huge number a negative number The problem is dividing by const value when the result is out of supported range. The fix: -return LONGLONG_MIN if the result is out of supported range for DIV operator. -return 0 if divisor is -1 for MOD operator. mysql-test/r/func_math.result: test case mysql-test/t/func_math.test: test case sql/item_func.cc: -return LONGLONG_MIN if the result is out of supported range for DIV operator. -return 0 if divisor is -1 for MOD operator. --- mysql-test/r/func_math.result | 16 ++++++++++++++++ mysql-test/t/func_math.test | 6 ++++++ sql/item_func.cc | 16 ++++++++++------ 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result index fd7ef72409e..649232e0b05 100644 --- a/mysql-test/r/func_math.result +++ b/mysql-test/r/func_math.result @@ -482,4 +482,20 @@ RAND(i) 0.155220427694936 DROP TABLE t1; # +# Bug#57477 SIGFPE when dividing a huge number a negative number +# +SELECT -9999999999999999991 DIV -1; +-9999999999999999991 DIV -1 +-9223372036854775808 +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +SELECT -9223372036854775808 DIV -1; +-9223372036854775808 DIV -1 +-9223372036854775808 +SELECT -9223372036854775808 MOD -1; +-9223372036854775808 MOD -1 +0 +SELECT -9223372036854775808999 MOD -1; +-9223372036854775808999 MOD -1 +0 End of 5.1 tests diff --git a/mysql-test/t/func_math.test b/mysql-test/t/func_math.test index 91fdce8addb..b0c92c9d6ab 100644 --- a/mysql-test/t/func_math.test +++ b/mysql-test/t/func_math.test @@ -308,5 +308,11 @@ SELECT RAND(i) FROM t1; DROP TABLE t1; --echo # +--echo # Bug#57477 SIGFPE when dividing a huge number a negative number +--echo # +SELECT -9999999999999999991 DIV -1; +SELECT -9223372036854775808 DIV -1; +SELECT -9223372036854775808 MOD -1; +SELECT -9223372036854775808999 MOD -1; --echo End of 5.1 tests diff --git a/sql/item_func.cc b/sql/item_func.cc index 30d5d844f7c..3dbff43bb67 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1356,9 +1356,13 @@ longlong Item_func_int_div::val_int() signal_divide_by_null(); return 0; } - return (unsigned_flag ? - (ulonglong) value / (ulonglong) val2 : - value / val2); + + if (unsigned_flag) + return ((ulonglong) value / (ulonglong) val2); + else if (value == LONGLONG_MIN && val2 == -1) + return LONGLONG_MIN; + else + return value / val2; } @@ -1392,9 +1396,9 @@ longlong Item_func_mod::int_op() if (args[0]->unsigned_flag) result= args[1]->unsigned_flag ? ((ulonglong) value) % ((ulonglong) val2) : ((ulonglong) value) % val2; - else - result= args[1]->unsigned_flag ? - value % ((ulonglong) val2) : value % val2; + else result= args[1]->unsigned_flag ? + value % ((ulonglong) val2) : + (val2 == -1) ? 0 : value % val2; return result; } From 1a9083b94ab0fef7dbf29fe6069f588f8a4acab5 Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Thu, 28 Oct 2010 12:08:09 +0200 Subject: [PATCH 120/304] post merge fix --- sql/ha_partition.h | 12 ------------ sql/sql_partition_admin.cc | 2 ++ 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 785d2388652..f1abc0cefe2 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -935,22 +935,16 @@ private: /* lock already taken */ if (auto_increment_safe_stmt_log_lock) return; -#ifdef WITH_PARTITION_STORAGE_ENGINE DBUG_ASSERT(table_share->ha_part_data && !auto_increment_lock); -#endif if(table_share->tmp_table == NO_TMP_TABLE) { auto_increment_lock= TRUE; -#ifdef WITH_PARTITION_STORAGE_ENGINE mysql_mutex_lock(&table_share->ha_part_data->LOCK_auto_inc); -#endif } } virtual void unlock_auto_increment() { -#ifdef WITH_PARTITION_STORAGE_ENGINE DBUG_ASSERT(table_share->ha_part_data); -#endif /* If auto_increment_safe_stmt_log_lock is true, we have to keep the lock. It will be set to false and thus unlocked at the end of the statement by @@ -958,25 +952,19 @@ private: */ if(auto_increment_lock && !auto_increment_safe_stmt_log_lock) { -#ifdef WITH_PARTITION_STORAGE_ENGINE mysql_mutex_unlock(&table_share->ha_part_data->LOCK_auto_inc); -#endif auto_increment_lock= FALSE; } } virtual void set_auto_increment_if_higher(Field *field) { -#ifdef WITH_PARTITION_STORAGE_ENGINE ulonglong nr= (((Field_num*) field)->unsigned_flag || field->val_int() > 0) ? field->val_int() : 0; -#endif lock_auto_increment(); -#ifdef WITH_PARTITION_STORAGE_ENGINE DBUG_ASSERT(table_share->ha_part_data->auto_inc_initialized == TRUE); /* must check when the mutex is taken */ if (nr >= table_share->ha_part_data->next_auto_inc_val) table_share->ha_part_data->next_auto_inc_val= nr + 1; -#endif unlock_auto_increment(); } diff --git a/sql/sql_partition_admin.cc b/sql/sql_partition_admin.cc index 98750314a4a..8f6ab5803d7 100644 --- a/sql/sql_partition_admin.cc +++ b/sql/sql_partition_admin.cc @@ -18,7 +18,9 @@ #include "sql_lex.h" // Sql_statement #include "sql_admin.h" // Analyze/Check/.._table_statement #include "sql_partition_admin.h" // Alter_table_*_partition +#ifdef WITH_PARTITION_STORAGE_ENGINE #include "ha_partition.h" // ha_partition +#endif #include "sql_base.h" // open_and_lock_tables #ifndef WITH_PARTITION_STORAGE_ENGINE From c3f923857a1cfcec4f1d037b20427931f8fe9a51 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 27 Oct 2010 18:12:17 +0300 Subject: [PATCH 121/304] Bug #57774: Typos/ambiguities in the WL1054 comments Fixed few typos and added better wording as suggested. --- include/mysql/plugin_auth.h | 6 +++--- plugin/auth/dialog.c | 6 +++--- plugin/auth/test_plugin.c | 26 ++++++++------------------ 3 files changed, 14 insertions(+), 24 deletions(-) diff --git a/include/mysql/plugin_auth.h b/include/mysql/plugin_auth.h index 5622e9cdebe..420eb3bb80f 100644 --- a/include/mysql/plugin_auth.h +++ b/include/mysql/plugin_auth.h @@ -90,8 +90,8 @@ typedef struct st_mysql_server_auth_info int password_used; /** - Set to the name of the connected client if it can be resolved, or to - the address otherwise + Set to the name of the connected client host, if it can be resolved, + or to its IP address otherwise. */ const char *host_or_ip; @@ -107,7 +107,7 @@ typedef struct st_mysql_server_auth_info */ struct st_mysql_auth { - int interface_version; /**< version plugin uses */ + int interface_version; /** version plugin uses */ /** A plugin that a client must use for authentication with this server plugin. Can be NULL to mean "any plugin". diff --git a/plugin/auth/dialog.c b/plugin/auth/dialog.c index 54f88dd9b4e..41312f95674 100644 --- a/plugin/auth/dialog.c +++ b/plugin/auth/dialog.c @@ -52,7 +52,7 @@ /** first byte of the question string is the question "type". - It can be a "ordinary" or a "password" question. + It can be an "ordinary" or a "password" question. The last bit set marks a last question in the authentication exchange. */ #define ORDINARY_QUESTION "\2" @@ -176,7 +176,7 @@ mysql_declare_plugin_end; This plugin performs a dialog with the user, asking questions and reading answers. Depending on the client it may be desirable to do it using GUI, or console, with or without curses, or read answers - from a smardcard, for example. + from a smartcard, for example. To support all this variety, the dialog plugin has a callback function "authentication_dialog_ask". If the client has a function of this name @@ -256,7 +256,7 @@ static int perform_dialog(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) in mysql_change_user() the client sends the first packet, so the first vio->read_packet() does nothing (pkt == 0). - We send the "password", assuming the client knows what its doing. + We send the "password", assuming the client knows what it's doing. (in other words, the dialog plugin should be only set as a default authentication plugin on the client if the first question asks for a password - which will be sent in clear text, by the way) diff --git a/plugin/auth/test_plugin.c b/plugin/auth/test_plugin.c index caea7795833..161062d5b6c 100644 --- a/plugin/auth/test_plugin.c +++ b/plugin/auth/test_plugin.c @@ -17,22 +17,12 @@ /** @file - dialog client authentication plugin with examples + Test driver for the mysql-test/t/plugin_auth.test - dialog is a general purpose client authentication plugin, it simply - asks the user the question, as provided by the server and reports - the answer back to the server. No encryption is involved, - the answers are sent in clear text. - - Two examples are provided: two_questions server plugin, that asks - the password and an "Are you sure?" question with a reply "yes, of course". - It demonstrates the usage of "password" (input is hidden) and "ordinary" - (input can be echoed) questions, and how to mark the last question, - to avoid an extra roundtrip. - - And three_attempts plugin that gives the user three attempts to enter - a correct password. It shows the situation when a number of questions - is not known in advance. + This is a set of test plugins used to test the external authentication + implementation. + See the above test file for more details. + This test plugin is based on the dialog plugin example. */ #include @@ -55,7 +45,7 @@ /********************* SERVER SIDE ****************************************/ /** - dialog test plugin mimicing the ordinary auth mechanism. Used to test the auth plugin API + dialog test plugin mimicking the ordinary auth mechanism. Used to test the auth plugin API */ static int auth_test_plugin(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info) { @@ -150,10 +140,10 @@ static int test_plugin_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) in mysql_change_user() the client sends the first packet, so the first vio->read_packet() does nothing (pkt == 0). - We send the "password", assuming the client knows what its doing. + We send the "password", assuming the client knows what it's doing. (in other words, the dialog plugin should be only set as a default authentication plugin on the client if the first question - asks for a password - which will be sent in cleat text, by the way) + asks for a password - which will be sent in clear text, by the way) */ reply= mysql->passwd; } From 712beace38e9a621eb015663d4db4ce0ec0c5fea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 27 Oct 2010 21:50:45 +0300 Subject: [PATCH 122/304] Fix a bogus debug assertion in the fix of Bug #57707. buf_pool_init(): Replace ut_ad(n_instances < MAX_BUFFER_POOLS) with ut_ad(n_instances <= MAX_BUFFER_POOLS). (Spotted by Michael Izioumtchenko.) Add ut_ad(n_instances > 0). --- storage/innobase/buf/buf0buf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c index 03133e81ceb..b79b5634957 100644 --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c @@ -1295,7 +1295,8 @@ buf_pool_init( ulint i; const ulint size = total_size / n_instances; - ut_ad(n_instances < MAX_BUFFER_POOLS); + ut_ad(n_instances > 0); + ut_ad(n_instances <= MAX_BUFFER_POOLS); ut_ad(n_instances == srv_buf_pool_instances); /* We create an extra buffer pool instance, this instance is used From 881da26b838553832afa5ca8243d7e3c7cf505c0 Mon Sep 17 00:00:00 2001 From: Konstantin Osipov Date: Wed, 27 Oct 2010 22:57:44 +0400 Subject: [PATCH 123/304] Remove a dead declaration. --- sql/sql_base.h | 1 - 1 file changed, 1 deletion(-) diff --git a/sql/sql_base.h b/sql/sql_base.h index 7ae3971942b..00f335ab209 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -243,7 +243,6 @@ bool open_tables(THD *thd, TABLE_LIST **tables, uint *counter, uint flags, bool open_and_lock_tables(THD *thd, TABLE_LIST *tables, bool derived, uint flags, Prelocking_strategy *prelocking_strategy); -int open_and_lock_tables_derived(THD *thd, TABLE_LIST *tables, bool derived); /* simple open_and_lock_tables without derived handling for single table */ TABLE *open_n_lock_single_table(THD *thd, TABLE_LIST *table_l, thr_lock_type lock_type, uint flags, From ebd67e186e2da1ea82ee32169f149f8126f618bb Mon Sep 17 00:00:00 2001 From: MySQL Build Team Date: Wed, 27 Oct 2010 23:59:07 +0200 Subject: [PATCH 124/304] merge of 57689 revno: 3101 from mysql-5.5-bugteam --- sql/sql_acl.cc | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 5583e9a29f1..4725ef3a081 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -8091,6 +8091,24 @@ static bool send_plugin_request_packet(MPVIO_EXT *mpvio, DBUG_RETURN (1); } + /* + If we're dealing with an older client we can't just send a change plugin + packet to re-initiate the authentication handshake, because the client + won't understand it. The good thing is that we don't need to : the old client + expects us to just check the user credentials here, which we can do by just reading + the cached data that are placed there by parse_com_change_user_packet() + In this case we just do nothing and behave as if normal authentication + should continue. + */ + if (!(mpvio->client_capabilities & CLIENT_PLUGIN_AUTH)) + { + DBUG_PRINT("info", ("old client sent a COM_CHANGE_USER")); + DBUG_ASSERT(mpvio->cached_client_reply.pkt); + /* get the status back so the read can process the cached result */ + mpvio->status= MPVIO_EXT::RESTART; + DBUG_RETURN(0); + } + DBUG_PRINT("info", ("requesting client to use the %s plugin", client_auth_plugin)); DBUG_RETURN(net_write_command(net, switch_plugin_request_buf[0], @@ -8574,8 +8592,16 @@ static int server_mpvio_write_packet(MYSQL_PLUGIN_VIO *param, int res; DBUG_ENTER("server_mpvio_write_packet"); - /* reset cached_client_reply */ - mpvio->cached_client_reply.pkt= 0; + /* + Reset cached_client_reply if not an old client doing mysql_change_user, + as this is where the password from COM_CHANGE_USER is stored. + */ + if (!((!(mpvio->client_capabilities & CLIENT_PLUGIN_AUTH)) && + mpvio->status == MPVIO_EXT::RESTART && + mpvio->cached_client_reply.plugin == + ((st_mysql_auth *) (plugin_decl(mpvio->plugin)->info))->client_auth_plugin + )) + mpvio->cached_client_reply.pkt= 0; /* for the 1st packet we wrap plugin data into the handshake packet */ if (mpvio->packets_written == 0) res= send_server_handshake_packet(mpvio, (char*) packet, packet_len); @@ -8641,6 +8667,15 @@ static int server_mpvio_read_packet(MYSQL_PLUGIN_VIO *param, uchar **buf) mpvio->packets_read++; DBUG_RETURN ((int) mpvio->cached_client_reply.pkt_len); } + + /* older clients don't support change of client plugin request */ + if (!(mpvio->client_capabilities & CLIENT_PLUGIN_AUTH)) + { + mpvio->status= MPVIO_EXT::FAILURE; + pkt_len= packet_error; + goto err; + } + /* But if the client has used the wrong plugin, the cached data are useless. Furthermore, we have to send a "change plugin" request From 3fb574bf03d5c4e118d29acbc192058243a21404 Mon Sep 17 00:00:00 2001 From: Calvin Sun Date: Wed, 27 Oct 2010 17:06:20 -0500 Subject: [PATCH 125/304] Fixed a C89 violation when atomic builtins are not defined, causing a compile error with MSVC. The problem was introduced in Revision: 3150 revid:marko.makela@oracle.com-20100809085837-s1nfx6gjf7l6ttab --- storage/innobase/ibuf/ibuf0ibuf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c index 7ef577e5178..ab42f1ad4f3 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.c +++ b/storage/innobase/ibuf/ibuf0ibuf.c @@ -1363,12 +1363,12 @@ ibuf_add_ops( const ulint* ops) /*!< in: operation counts */ { + ulint i; + #ifndef HAVE_ATOMIC_BUILTINS ut_ad(mutex_own(&ibuf_mutex)); #endif /* !HAVE_ATOMIC_BUILTINS */ - ulint i; - for (i = 0; i < IBUF_OP_COUNT; i++) { #ifdef HAVE_ATOMIC_BUILTINS os_atomic_increment_ulint(&arr[i], ops[i]); From 16feea410975e17c3cf24f8af92a3f32e8c24ba1 Mon Sep 17 00:00:00 2001 From: Calvin Sun Date: Wed, 27 Oct 2010 23:18:59 -0500 Subject: [PATCH 126/304] Bug#52062: Compiler warning in os0file.c on windows 64-bit On Windows, the parameter for number of bytes passed into WriteFile() and ReadFile() is DWORD. Casting is needed to silence the warning on 64-bit Windows. Also, adding several asserts to ensure the variable for number of bytes is no more than 32 bits, even on 64-bit Windows. This is for built-in InnoDB. rb://415 Approved by: Inaam --- storage/innobase/os/os0file.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c index f269cd39673..566c50381e7 100644 --- a/storage/innobase/os/os0file.c +++ b/storage/innobase/os/os0file.c @@ -2207,7 +2207,10 @@ os_file_read( ibool retry; ulint i; + /* On 64-bit Windows, ulint is 64 bits. But offset and n should be + no more than 32 bits. */ ut_a((offset & 0xFFFFFFFFUL) == offset); + ut_a((n & 0xFFFFFFFFUL) == n); os_n_file_reads++; os_bytes_read_since_printout += n; @@ -2324,7 +2327,10 @@ os_file_read_no_error_handling( ibool retry; ulint i; + /* On 64-bit Windows, ulint is 64 bits. But offset and n should be + no more than 32 bits. */ ut_a((offset & 0xFFFFFFFFUL) == offset); + ut_a((n & 0xFFFFFFFFUL) == n); os_n_file_reads++; os_bytes_read_since_printout += n; @@ -2447,7 +2453,10 @@ os_file_write( ulint n_retries = 0; ulint err; - ut_a((offset & 0xFFFFFFFF) == offset); + /* On 64-bit Windows, ulint is 64 bits. But offset and n should be + no more than 32 bits. */ + ut_a((offset & 0xFFFFFFFFUL) == offset); + ut_a((n & 0xFFFFFFFFUL) == n); os_n_file_writes++; @@ -3245,14 +3254,16 @@ os_aio_array_reserve_slot( ulint len) /* in: length of the block to read or write */ { os_aio_slot_t* slot; + ulint i; #ifdef WIN_ASYNC_IO OVERLAPPED* control; + ut_a((len & 0xFFFFFFFFUL) == len); #elif defined(POSIX_ASYNC_IO) struct aiocb* control; #endif - ulint i; + loop: os_mutex_enter(array->mutex); @@ -3517,6 +3528,9 @@ os_aio( ut_ad(n % OS_FILE_LOG_BLOCK_SIZE == 0); ut_ad(offset % OS_FILE_LOG_BLOCK_SIZE == 0); ut_ad(os_aio_validate()); +#ifdef WIN_ASYNC_IO + ut_ad((n & 0xFFFFFFFFUL) == n); +#endif wake_later = mode & OS_AIO_SIMULATED_WAKE_LATER; mode = mode & (~OS_AIO_SIMULATED_WAKE_LATER); @@ -3765,16 +3779,18 @@ os_aio_windows_handle( /* retry failed read/write operation synchronously. No need to hold array->mutex. */ + ut_a((slot->len & 0xFFFFFFFFUL) == slot->len); + switch (slot->type) { case OS_FILE_WRITE: ret = WriteFile(slot->file, slot->buf, - slot->len, &len, + (DWORD) slot->len, &len, &(slot->control)); break; case OS_FILE_READ: ret = ReadFile(slot->file, slot->buf, - slot->len, &len, + (DWORD) slot->len, &len, &(slot->control)); break; From 460ad14e04d022ab9ccd122af7bcbc4a0030f67a Mon Sep 17 00:00:00 2001 From: Calvin Sun Date: Thu, 28 Oct 2010 00:10:28 -0500 Subject: [PATCH 127/304] Bug#52062: Compiler warning in os0file.c on windows 64-bit On Windows, the parameter for number of bytes passed into WriteFile() and ReadFile() is DWORD. Casting is needed to silence the warning on 64-bit Windows. Also, adding several asserts to ensure the variable for number of bytes is no more than 32 bits, even on 64-bit Windows. This is for InnoDB Plugin. rb://415 Approved by: Inaam --- storage/innodb_plugin/os/os0file.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/storage/innodb_plugin/os/os0file.c b/storage/innodb_plugin/os/os0file.c index 14b2fce43c3..ff80f7ed1b4 100644 --- a/storage/innodb_plugin/os/os0file.c +++ b/storage/innodb_plugin/os/os0file.c @@ -2280,7 +2280,10 @@ os_file_read( ulint i; #endif /* !UNIV_HOTBACKUP */ + /* On 64-bit Windows, ulint is 64 bits. But offset and n should be + no more than 32 bits. */ ut_a((offset & 0xFFFFFFFFUL) == offset); + ut_a((n & 0xFFFFFFFFUL) == n); os_n_file_reads++; os_bytes_read_since_printout += n; @@ -2404,7 +2407,10 @@ os_file_read_no_error_handling( ulint i; #endif /* !UNIV_HOTBACKUP */ + /* On 64-bit Windows, ulint is 64 bits. But offset and n should be + no more than 32 bits. */ ut_a((offset & 0xFFFFFFFFUL) == offset); + ut_a((n & 0xFFFFFFFFUL) == n); os_n_file_reads++; os_bytes_read_since_printout += n; @@ -2534,7 +2540,10 @@ os_file_write( ulint i; #endif /* !UNIV_HOTBACKUP */ - ut_a((offset & 0xFFFFFFFF) == offset); + /* On 64-bit Windows, ulint is 64 bits. But offset and n should be + no more than 32 bits. */ + ut_a((offset & 0xFFFFFFFFUL) == offset); + ut_a((n & 0xFFFFFFFFUL) == n); os_n_file_writes++; @@ -3304,12 +3313,14 @@ os_aio_array_reserve_slot( ulint len) /*!< in: length of the block to read or write */ { os_aio_slot_t* slot; -#ifdef WIN_ASYNC_IO - OVERLAPPED* control; -#endif ulint i; ulint slots_per_seg; ulint local_seg; +#ifdef WIN_ASYNC_IO + OVERLAPPED* control; + + ut_a((len & 0xFFFFFFFFUL) == len); +#endif /* No need of a mutex. Only reading constant fields */ slots_per_seg = array->n_slots / array->n_segments; @@ -3589,6 +3600,9 @@ os_aio( ut_ad(n % OS_FILE_LOG_BLOCK_SIZE == 0); ut_ad(offset % OS_FILE_LOG_BLOCK_SIZE == 0); ut_ad(os_aio_validate()); +#ifdef WIN_ASYNC_IO + ut_ad((n & 0xFFFFFFFFUL) == n); +#endif wake_later = mode & OS_AIO_SIMULATED_WAKE_LATER; mode = mode & (~OS_AIO_SIMULATED_WAKE_LATER); @@ -3829,16 +3843,18 @@ os_aio_windows_handle( /* retry failed read/write operation synchronously. No need to hold array->mutex. */ + ut_a((slot->len & 0xFFFFFFFFUL) == slot->len); + switch (slot->type) { case OS_FILE_WRITE: ret = WriteFile(slot->file, slot->buf, - slot->len, &len, + (DWORD) slot->len, &len, &(slot->control)); break; case OS_FILE_READ: ret = ReadFile(slot->file, slot->buf, - slot->len, &len, + (DWORD) slot->len, &len, &(slot->control)); break; From ec51b47954455b4714efbbccdeb9f7e11c17a60a Mon Sep 17 00:00:00 2001 From: Calvin Sun Date: Thu, 28 Oct 2010 00:34:53 -0500 Subject: [PATCH 128/304] Bug#52062: Compiler warning in os0file.c on windows 64-bit On Windows, the parameter for number of bytes passed into WriteFile() and ReadFile() is DWORD. Casting is needed to silence the warning on 64-bit Windows. Also, adding several asserts to ensure the variable for number of bytes is no more than 32 bits, even on 64-bit Windows. rb://415 Approved by: Inaam --- storage/innobase/os/os0file.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c index 3d1577fe3ca..93d2f72746d 100644 --- a/storage/innobase/os/os0file.c +++ b/storage/innobase/os/os0file.c @@ -2400,7 +2400,10 @@ os_file_read_func( ulint i; #endif /* !UNIV_HOTBACKUP */ + /* On 64-bit Windows, ulint is 64 bits. But offset and n should be + no more than 32 bits. */ ut_a((offset & 0xFFFFFFFFUL) == offset); + ut_a((n & 0xFFFFFFFFUL) == n); os_n_file_reads++; os_bytes_read_since_printout += n; @@ -2526,7 +2529,10 @@ os_file_read_no_error_handling_func( ulint i; #endif /* !UNIV_HOTBACKUP */ + /* On 64-bit Windows, ulint is 64 bits. But offset and n should be + no more than 32 bits. */ ut_a((offset & 0xFFFFFFFFUL) == offset); + ut_a((n & 0xFFFFFFFFUL) == n); os_n_file_reads++; os_bytes_read_since_printout += n; @@ -2658,7 +2664,10 @@ os_file_write_func( ulint i; #endif /* !UNIV_HOTBACKUP */ - ut_a((offset & 0xFFFFFFFF) == offset); + /* On 64-bit Windows, ulint is 64 bits. But offset and n should be + no more than 32 bits. */ + ut_a((offset & 0xFFFFFFFFUL) == offset); + ut_a((n & 0xFFFFFFFFUL) == n); os_n_file_writes++; @@ -3621,6 +3630,10 @@ os_aio_array_reserve_slot( ulint slots_per_seg; ulint local_seg; +#ifdef WIN_ASYNC_IO + ut_a((len & 0xFFFFFFFFUL) == len); +#endif + /* No need of a mutex. Only reading constant fields */ slots_per_seg = array->n_slots / array->n_segments; @@ -3996,6 +4009,9 @@ os_aio_func( ut_ad(n % OS_FILE_LOG_BLOCK_SIZE == 0); ut_ad(offset % OS_FILE_LOG_BLOCK_SIZE == 0); ut_ad(os_aio_validate()); +#ifdef WIN_ASYNC_IO + ut_ad((n & 0xFFFFFFFFUL) == n); +#endif wake_later = mode & OS_AIO_SIMULATED_WAKE_LATER; mode = mode & (~OS_AIO_SIMULATED_WAKE_LATER); @@ -4271,16 +4287,18 @@ os_aio_windows_handle( __FILE__, __LINE__); #endif + ut_a((slot->len & 0xFFFFFFFFUL) == slot->len); + switch (slot->type) { case OS_FILE_WRITE: ret = WriteFile(slot->file, slot->buf, - slot->len, &len, + (DWORD) slot->len, &len, &(slot->control)); break; case OS_FILE_READ: ret = ReadFile(slot->file, slot->buf, - slot->len, &len, + (DWORD) slot->len, &len, &(slot->control)); break; From e3decfa0aed2f2240eda7f0f92b14ff3a791b8d4 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Thu, 28 Oct 2010 20:12:23 +0300 Subject: [PATCH 129/304] Fix a compilation warning: /export/home/pb2/build/sb_0-2459340-1288264809.63/mysql-5.5.8-ga/storage/innobase/os/os0sync.c: In function 'os_cond_wait_timed': /export/home/pb2/build/sb_0-2459340-1288264809.63/mysql-5.5.8-ga/storage/innobase/os/os0sync.c:184: warning: format '%lu' expects type 'long unsigned int', but argument 4 has type 'time_t' gmake[2]: *** [storage/innobase/CMakeFiles/innobase.dir/os/os0sync.c.o] Error 1 --- storage/innobase/os/os0sync.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/os/os0sync.c b/storage/innobase/os/os0sync.c index 2f481b76bda..24d36acecb2 100644 --- a/storage/innobase/os/os0sync.c +++ b/storage/innobase/os/os0sync.c @@ -181,7 +181,7 @@ os_cond_wait_timed( default: fprintf(stderr, " InnoDB: pthread_cond_timedwait() returned: " "%d: abstime={%lu,%lu}\n", - ret, abstime->tv_sec, abstime->tv_nsec); + ret, (ulong) abstime->tv_sec, (ulong) abstime->tv_nsec); ut_error; } From 6f03e15cf958da34b9517a1fc4ae6cf00c80b9de Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Thu, 28 Oct 2010 21:55:43 -0700 Subject: [PATCH 130/304] Merge fix for bug#57616 from mysql-5.5-security to mysql-5.5-innodb. --- storage/innobase/dict/dict0load.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/innobase/dict/dict0load.c b/storage/innobase/dict/dict0load.c index 74f108fcf8e..9c6fa086d58 100644 --- a/storage/innobase/dict/dict0load.c +++ b/storage/innobase/dict/dict0load.c @@ -1733,13 +1733,13 @@ err_exit: if (err != DB_SUCCESS) { dict_table_remove_from_cache(table); table = NULL; + } else { + table->fk_max_recusive_level = 0; } } else if (!srv_force_recovery) { dict_table_remove_from_cache(table); table = NULL; } - - table->fk_max_recusive_level = 0; #if 0 if (err != DB_SUCCESS && table != NULL) { From c04bf683fe2582753e8d575e508902245efdd47c Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Fri, 29 Oct 2010 11:44:32 +0400 Subject: [PATCH 131/304] Bug#57194 group_concat cause crash and/or invalid memory reads with type errors The problem is caused by bug49487 fix and became visible after after bug56679 fix. Items are cleaned up and set to unfixed state after filling derived table. So we can not rely on item::fixed state in Item_func_group_concat::print and we can not use 'args' array as items there may be cleaned up. The fix is always to use orig_args array of items as it always should contain the correct data. mysql-test/r/func_gconcat.result: test case mysql-test/t/func_gconcat.test: test case sql/item_sum.cc: The fix is always to use orig_args array of items. --- mysql-test/r/func_gconcat.result | 8 ++++++++ mysql-test/t/func_gconcat.test | 10 ++++++++++ sql/item_sum.cc | 6 ++---- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index ae48eb1e0ff..de592ece285 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -1029,4 +1029,12 @@ GROUP_CONCAT(t1.a ORDER BY t1.a) 1,1,2,2 DEALLOCATE PREPARE stmt; DROP TABLE t1; +# +# Bug#57194 group_concat cause crash and/or invalid memory reads with type errors +# +CREATE TABLE t1(f1 int); +INSERT INTO t1 values (0),(0); +SELECT POLYGON((SELECT 1 FROM (SELECT 1 IN (GROUP_CONCAT(t1.f1)) FROM t1, t1 t GROUP BY t.f1 ) d)); +ERROR 22007: Illegal non geometric '(select 1 from (select (1 = group_concat(`test`.`t1`.`f1` separator ',')) AS `1 IN (GROUP_CONCAT(t1.f1))` from `test`.`t1` join `test`.`t1` `t` group by `t`.`f1`) `d`)' value found during parsing +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test index 926c1f92855..29fc8a9dc3c 100644 --- a/mysql-test/t/func_gconcat.test +++ b/mysql-test/t/func_gconcat.test @@ -734,4 +734,14 @@ EXECUTE stmt; DEALLOCATE PREPARE stmt; DROP TABLE t1; +--echo # +--echo # Bug#57194 group_concat cause crash and/or invalid memory reads with type errors +--echo # + +CREATE TABLE t1(f1 int); +INSERT INTO t1 values (0),(0); +--error ER_ILLEGAL_VALUE_FOR_TYPE +SELECT POLYGON((SELECT 1 FROM (SELECT 1 IN (GROUP_CONCAT(t1.f1)) FROM t1, t1 t GROUP BY t.f1 ) d)); +DROP TABLE t1; + --echo End of 5.1 tests diff --git a/sql/item_sum.cc b/sql/item_sum.cc index ae9e46e2abf..65f8222d38b 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -3401,8 +3401,6 @@ String* Item_func_group_concat::val_str(String* str) void Item_func_group_concat::print(String *str, enum_query_type query_type) { - /* orig_args is not filled with valid values until fix_fields() */ - Item **pargs= fixed ? orig_args : args; str->append(STRING_WITH_LEN("group_concat(")); if (distinct) str->append(STRING_WITH_LEN("distinct ")); @@ -3410,7 +3408,7 @@ void Item_func_group_concat::print(String *str, enum_query_type query_type) { if (i) str->append(','); - pargs[i]->print(str, query_type); + orig_args[i]->print(str, query_type); } if (arg_count_order) { @@ -3419,7 +3417,7 @@ void Item_func_group_concat::print(String *str, enum_query_type query_type) { if (i) str->append(','); - pargs[i + arg_count_field]->print(str, query_type); + orig_args[i + arg_count_field]->print(str, query_type); if (order[i]->asc) str->append(STRING_WITH_LEN(" ASC")); else From 4a23ac20d99118b2127d0e6adae0d8a95655e32e Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Fri, 29 Oct 2010 12:23:06 +0400 Subject: [PATCH 132/304] Bug#57688 Assertion `!table || (!table->write_set || bitmap_is_set(table->write_set, field Lines below which were added in the patch for Bug#56814 cause this crash: + if (table->table) + table->table->maybe_null= FALSE; Consider following test case: -- CREATE TABLE t1(f1 INT NOT NULL); INSERT INTO t1 VALUES (16777214),(0); SELECT COUNT(*) FROM t1 LEFT JOIN t1 t2 ON 1 WHERE t2.f1 > 1 GROUP BY t2.f1; DROP TABLE t1; -- We set TABLE::maybe_null to FALSE for t2 table and in create_tmp_field() we create appropriate tmp table field using create_tmp_field_from_item() function instead of create_tmp_field_from_field. As a result we have LONGLONG field. As we have GROUP BY clause we calculate group buffer length, see calc_group_buffer(). Item from group list which is used for calculation refer to the field from real tables and have LONG type. So group buffer length become insufficient for storing of LONGLONG value. It leads to overwriting of wrong memory area in do_field_int() function which is called from end_update(). After some investigation I found out that create_tmp_field_from_item() is used only for OLAP grouping and can not be used for common grouping as it could be an incompatibility between tmp table fields and group buffer length. We can not remove create_tmp_field_from_item() call from create_tmp_field as OLAP needs it and we can not use this function for common grouping. So we should remove setting TABLE::maybe_null to FALSE from simplify_joins(). In this case we'll get wrong behaviour of list_contains_unique_index() back. To fix it we could use Field::real_maybe_null() check instead of Field::maybe_null() and add addition check of TABLE_LIST::outer_join. mysql-test/r/group_by.result: test case mysql-test/r/join_outer.result: test case mysql-test/t/group_by.test: test case mysql-test/t/join_outer.test: test case sql/sql_select.cc: --remove wrong code --use Field::real_maybe_null() check instead of Field::maybe_null() and add addition check of TABLE_LIST::outer_join --- mysql-test/r/group_by.result | 10 ++++++++++ mysql-test/r/join_outer.result | 30 ++++++++++++++++++++++++++++++ mysql-test/t/group_by.test | 11 +++++++++++ mysql-test/t/join_outer.test | 29 +++++++++++++++++++++++++++++ sql/sql_select.cc | 11 +++-------- 5 files changed, 83 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result index f74584f6bcf..83f1f220023 100644 --- a/mysql-test/r/group_by.result +++ b/mysql-test/r/group_by.result @@ -1845,4 +1845,14 @@ SELECT SUBSTRING(a,1,10), LENGTH(a) FROM t1 GROUP BY a; SUBSTRING(a,1,10) LENGTH(a) 1111111111 1300 DROP TABLE t1; +# +# Bug#57688 Assertion `!table || (!table->write_set || bitmap_is_set(table->write_set, field +# +CREATE TABLE t1(f1 INT NOT NULL); +INSERT INTO t1 VALUES (16777214),(0); +SELECT COUNT(*) FROM t1 LEFT JOIN t1 t2 +ON 1 WHERE t2.f1 > 1 GROUP BY t2.f1; +COUNT(*) +2 +DROP TABLE t1; # End of 5.1 tests diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result index 8e438934b23..d9c4ac5478e 100644 --- a/mysql-test/r/join_outer.result +++ b/mysql-test/r/join_outer.result @@ -1397,4 +1397,34 @@ id select_type table type possible_keys key key_len ref rows filtered Extra Warnings: Note 1003 select straight_join `test`.`jt1`.`f1` AS `f1` from `test`.`t1` `jt6` left join (`test`.`t1` `jt3` join `test`.`t1` `jt4` left join `test`.`t1` `jt5` on(1) left join `test`.`t1` `jt2` on(1)) on((`test`.`jt6`.`f1` and 1)) left join `test`.`t1` `jt1` on(1) where 1 DROP TABLE t1; +# +# Bug#57688 Assertion `!table || (!table->write_set || bitmap_is_set(table->write_set, field +# +CREATE TABLE t1 (f1 INT NOT NULL, PRIMARY KEY (f1)); +CREATE TABLE t2 (f1 INT NOT NULL, f2 INT NOT NULL, PRIMARY KEY (f1, f2)); +INSERT INTO t1 VALUES (4); +INSERT INTO t2 VALUES (3, 3); +INSERT INTO t2 VALUES (7, 7); +EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1 +WHERE t1.f1 = 4 +GROUP BY t2.f1, t2.f2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 system PRIMARY NULL NULL NULL 1 Using temporary; Using filesort +1 SIMPLE t2 ref PRIMARY PRIMARY 4 const 1 Using index +SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1 +WHERE t1.f1 = 4 +GROUP BY t2.f1, t2.f2; +f1 f1 f2 +4 NULL NULL +EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1 +WHERE t1.f1 = 4 AND t2.f1 IS NOT NULL AND t2.f2 IS NOT NULL +GROUP BY t2.f1, t2.f2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 system PRIMARY NULL NULL NULL 1 Using filesort +1 SIMPLE t2 ref PRIMARY PRIMARY 4 const 1 Using where; Using index +SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1 +WHERE t1.f1 = 4 AND t2.f1 IS NOT NULL AND t2.f2 IS NOT NULL +GROUP BY t2.f1, t2.f2; +f1 f1 f2 +DROP TABLE t1,t2; End of 5.1 tests diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test index 75ec1d82b02..580c2e5091c 100644 --- a/mysql-test/t/group_by.test +++ b/mysql-test/t/group_by.test @@ -1235,5 +1235,16 @@ SELECT SUBSTRING(a,1,10), LENGTH(a) FROM t1 GROUP BY a; SELECT SUBSTRING(a,1,10), LENGTH(a) FROM t1 GROUP BY a; DROP TABLE t1; +--echo # +--echo # Bug#57688 Assertion `!table || (!table->write_set || bitmap_is_set(table->write_set, field +--echo # + +CREATE TABLE t1(f1 INT NOT NULL); +INSERT INTO t1 VALUES (16777214),(0); + +SELECT COUNT(*) FROM t1 LEFT JOIN t1 t2 +ON 1 WHERE t2.f1 > 1 GROUP BY t2.f1; + +DROP TABLE t1; --echo # End of 5.1 tests diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test index cf881e6aaa2..3251ff292b6 100644 --- a/mysql-test/t/join_outer.test +++ b/mysql-test/t/join_outer.test @@ -981,4 +981,33 @@ EXPLAIN EXTENDED SELECT STRAIGHT_JOIN jt1.f1 FROM t1 AS jt1 DROP TABLE t1; +--echo # +--echo # Bug#57688 Assertion `!table || (!table->write_set || bitmap_is_set(table->write_set, field +--echo # + +CREATE TABLE t1 (f1 INT NOT NULL, PRIMARY KEY (f1)); +CREATE TABLE t2 (f1 INT NOT NULL, f2 INT NOT NULL, PRIMARY KEY (f1, f2)); + +INSERT INTO t1 VALUES (4); +INSERT INTO t2 VALUES (3, 3); +INSERT INTO t2 VALUES (7, 7); + +EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1 +WHERE t1.f1 = 4 +GROUP BY t2.f1, t2.f2; + +SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1 +WHERE t1.f1 = 4 +GROUP BY t2.f1, t2.f2; + +EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1 +WHERE t1.f1 = 4 AND t2.f1 IS NOT NULL AND t2.f2 IS NOT NULL +GROUP BY t2.f1, t2.f2; + +SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1 +WHERE t1.f1 = 4 AND t2.f1 IS NOT NULL AND t2.f2 IS NOT NULL +GROUP BY t2.f1, t2.f2; + +DROP TABLE t1,t2; + --echo End of 5.1 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 11acd0685a8..9767839b5bf 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -8832,13 +8832,6 @@ simplify_joins(JOIN *join, List *join_list, COND *conds, bool top) that reject nulls => the outer join can be replaced by an inner join. */ table->outer_join= 0; - /* - Update TABLE::maybe_null field as it could have - the value(maybe_null==TRUE) based on the assumption - that this join is outer(see setup_table_map() func). - */ - if (table->table) - table->table->maybe_null= FALSE; if (table->on_expr) { /* Add on expression to the where condition. */ @@ -13219,6 +13212,8 @@ static bool list_contains_unique_index(TABLE *table, bool (*find_func) (Field *, void *), void *data) { + if (table->pos_in_table_list->outer_join) + return 0; for (uint keynr= 0; keynr < table->s->keys; keynr++) { if (keynr == table->s->primary_key || @@ -13232,7 +13227,7 @@ list_contains_unique_index(TABLE *table, key_part < key_part_end; key_part++) { - if (key_part->field->maybe_null() || + if (key_part->field->real_maybe_null() || !find_func(key_part->field, data)) break; } From a5eba94a1d8967d5a8c7e8d3d398a2426453f508 Mon Sep 17 00:00:00 2001 From: Tor Didriksen Date: Fri, 29 Oct 2010 11:35:07 +0200 Subject: [PATCH 133/304] Bug #52131: SET and ENUM stored endian-dependent in binary log Post-Push fix, DBUG build broken on freebsd7 sql/field.cc:8456: warning: control reaches end of non-void function sql/field.cc: Return NULL to keep compiler happy. --- sql/field.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sql/field.cc b/sql/field.cc index ce1b1fc6eb0..a9b5fedda2d 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -8408,6 +8408,8 @@ uchar *Field_enum::pack(uchar *to, const uchar *from, default: DBUG_ASSERT(0); } + MY_ASSERT_UNREACHABLE(); + DBUG_RETURN(NULL); } const uchar *Field_enum::unpack(uchar *to, const uchar *from, @@ -8430,6 +8432,8 @@ const uchar *Field_enum::unpack(uchar *to, const uchar *from, default: DBUG_ASSERT(0); } + MY_ASSERT_UNREACHABLE(); + DBUG_RETURN(NULL); } From 9d4434e393b81b96bf654bec06e49b51ff734111 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 29 Oct 2010 15:27:40 +0300 Subject: [PATCH 134/304] fix tree name --- .bzr-mysql/default.conf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index 36f40105d26..1b6d7676984 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] -post_commit_to = "commits@lists.mysql.com" -post_push_to = "commits@lists.mysql.com" -tree_name = "mysql-5.5-bugteam" +post_commit_to = "dbg_mysql_security@sun.com" +post_push_to = "dbg_mysql_security@sun.com" +tree_name = "mysql-5.5-security" From 75d59ff9672856f8e18394e822e69cd611700594 Mon Sep 17 00:00:00 2001 From: Jon Olav Hauglid Date: Fri, 29 Oct 2010 16:10:53 +0200 Subject: [PATCH 135/304] Bug #57659 Segfault in Query_cache::invalidate_data for TRUNCATE TABLE This crash could happen if TRUNCATE TABLE indirectly failed to open a merge table due to failures to open underlying tables. Even if opening failed, the TRUNCATE TABLE code would try to invalidate the table in the query cache. Since this table had been closed and memory released, this could lead to a crash. This bug was introduced by a combination of the changes introduced by the patch for Bug#52044, where failing to open a table will cause opened tables to be closed. And the changes in patch for Bug#49938, where TRUNCATE TABLE uses the standard open tables function. This patch fixes the problem by setting the TABLE pointer to NULL before invalidating the query cache. Test case added to truncate_coverage.test. --- mysql-test/r/truncate_coverage.result | 27 ++++++++++++++ mysql-test/t/truncate_coverage.test | 54 +++++++++++++++++++++++++++ sql/sql_truncate.cc | 7 ++++ 3 files changed, 88 insertions(+) diff --git a/mysql-test/r/truncate_coverage.result b/mysql-test/r/truncate_coverage.result index a7a4b9c70f4..728702f7ab5 100644 --- a/mysql-test/r/truncate_coverage.result +++ b/mysql-test/r/truncate_coverage.result @@ -78,3 +78,30 @@ COMMIT; UNLOCK TABLES; DROP TABLE t1; SET DEBUG_SYNC='RESET'; +# +# Bug#57659 Segfault in Query_cache::invalidate_data for TRUNCATE TABLE +# +# Note that this test case only reproduces the problem +# when it is run with valgrind. +DROP TABLE IF EXISTS t1, m1; +CREATE TABLE t1(a INT) engine=memory; +CREATE TABLE m1(a INT) engine=merge UNION(t1); +# Connection con1 +SET DEBUG_SYNC= 'open_tables_after_open_and_process_table SIGNAL opened WAIT_FOR dropped'; +# Sending: +TRUNCATE TABLE m1; +# Connection con2 +SET DEBUG_SYNC= 'now WAIT_FOR opened'; +# Sending: +FLUSH TABLES; +# Connection default +# Waiting for FLUSH TABLES to be blocked. +SET DEBUG_SYNC= 'now SIGNAL dropped'; +# Connection con1 +# Reaping: TRUNCATE TABLE m1 +ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist +# Connection con2 +# Reaping: FLUSH TABLES +# Connection default +SET DEBUG_SYNC= 'RESET'; +DROP TABLE m1, t1; diff --git a/mysql-test/t/truncate_coverage.test b/mysql-test/t/truncate_coverage.test index c9c4bd90ca4..135935b53b3 100644 --- a/mysql-test/t/truncate_coverage.test +++ b/mysql-test/t/truncate_coverage.test @@ -172,3 +172,57 @@ UNLOCK TABLES; DROP TABLE t1; SET DEBUG_SYNC='RESET'; +--echo # +--echo # Bug#57659 Segfault in Query_cache::invalidate_data for TRUNCATE TABLE +--echo # + +--echo # Note that this test case only reproduces the problem +--echo # when it is run with valgrind. + +--disable_warnings +DROP TABLE IF EXISTS t1, m1; +--enable_warnings + +CREATE TABLE t1(a INT) engine=memory; +CREATE TABLE m1(a INT) engine=merge UNION(t1); +connect(con2, localhost, root); + +--echo # Connection con1 +connect(con1, localhost, root); +SET DEBUG_SYNC= 'open_tables_after_open_and_process_table SIGNAL opened WAIT_FOR dropped'; +--echo # Sending: +--send TRUNCATE TABLE m1 + +--echo # Connection con2 +connection con2; +SET DEBUG_SYNC= 'now WAIT_FOR opened'; +--echo # Sending: +--send FLUSH TABLES + +--echo # Connection default +connection default; +--echo # Waiting for FLUSH TABLES to be blocked. +let $wait_condition= SELECT COUNT(*)=1 FROM information_schema.processlist + WHERE state= 'Waiting for table flush' AND info= 'FLUSH TABLES'; +--source include/wait_condition.inc +SET DEBUG_SYNC= 'now SIGNAL dropped'; + +--echo # Connection con1 +connection con1; +--echo # Reaping: TRUNCATE TABLE m1 +--error ER_WRONG_MRG_TABLE +--reap +disconnect con1; +--source include/wait_until_disconnected.inc + +--echo # Connection con2 +connection con2; +--echo # Reaping: FLUSH TABLES +--reap +disconnect con2; +--source include/wait_until_disconnected.inc + +--echo # Connection default +connection default; +SET DEBUG_SYNC= 'RESET'; +DROP TABLE m1, t1; diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc index 0cff2875ac8..909c6a08b67 100644 --- a/sql/sql_truncate.cc +++ b/sql/sql_truncate.cc @@ -472,6 +472,13 @@ bool Truncate_statement::truncate_table(THD *thd, TABLE_LIST *table_ref) binlog_stmt= !error || error != HA_ERR_WRONG_COMMAND; } + /* + If we tried to open a MERGE table and failed due to problems with the + children tables, the table will have been closed and table_ref->table + will be invalid. Reset the pointer here in any case as + query_cache_invalidate does not need a valid TABLE object. + */ + table_ref->table= NULL; query_cache_invalidate3(thd, table_ref, FALSE); } From c4a4119829756aef666f2244f2e71d09a3bfd885 Mon Sep 17 00:00:00 2001 From: Sven Sandberg Date: Fri, 29 Oct 2010 16:56:58 +0200 Subject: [PATCH 136/304] wL#5625: Deprecate mysqlbinlog options --base64-output=always and --base64-output Adds deprecation warning for the mysqlbinlog options --base64-output=always and --base64-output. A warning is printed when the flags are used, and also when running mysqlbinlog --help. client/mysqlbinlog.cc: Give a warning for --base64-output=always and --base64-output, and print warning in mysqlbinlog --help. mysql-test/r/mysqlbinlog.result: updated result file mysql-test/t/mysqlbinlog.test: Test that mysqlbinlog --base64-output=always gives a warning. --- client/mysqlbinlog.cc | 16 ++++++++++++---- mysql-test/r/mysqlbinlog.result | 4 ++++ mysql-test/t/mysqlbinlog.test | 15 +++++++++++++++ 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 226776e4404..bf4920c6f77 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -1010,10 +1010,11 @@ static struct my_option my_long_options[] = "row-based events; 'decode-rows' decodes row events into commented SQL " "statements if the --verbose option is also given; 'auto' prints base64 " "only when necessary (i.e., for row-based events and format description " - "events); 'always' prints base64 whenever possible. 'always' is for " - "debugging only and should not be used in a production system. If this " - "argument is not given, the default is 'auto'; if it is given with no " - "argument, 'always' is used.", + "events); 'always' prints base64 whenever possible. 'always' is " + "deprecated, will be removed in a future version, and should not be used " + "in a production system. --base64-output with no 'name' argument is " + "equivalent to --base64-output=always and is also deprecated. If no " + "--base64-output[=name] option is given at all, the default is 'auto'.", &opt_base64_output_mode_str, &opt_base64_output_mode_str, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, /* @@ -2024,6 +2025,13 @@ int main(int argc, char** argv) if (opt_base64_output_mode == BASE64_OUTPUT_UNSPEC) opt_base64_output_mode= BASE64_OUTPUT_AUTO; + if (opt_base64_output_mode == BASE64_OUTPUT_ALWAYS) + warning("The --base64-output=always flag and the --base64-output flag " + "(with '=MODE' omitted), are deprecated. " + "The output generated when these flags are used cannot be " + "parsed by mysql 5.6.0 and later. " + "The flags will be removed in a future version. " + "Please use --base64-output=auto instead."); my_set_max_open_files(open_files_limit); diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result index 51fad679909..ce83fe5b79b 100644 --- a/mysql-test/r/mysqlbinlog.result +++ b/mysql-test/r/mysqlbinlog.result @@ -879,3 +879,7 @@ ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; End of 5.0 tests End of 5.1 tests +# Expect deprecation warning. +WARNING: The --base64-output=always flag and the --base64-output flag (with '=MODE' omitted), are deprecated. The output generated when these flags are used cannot be parsed by mysql 5.6.0 and later. The flags will be removed in a future version. Please use --base64-output=auto instead. +# Expect deprecation warning again. +WARNING: The --base64-output=always flag and the --base64-output flag (with '=MODE' omitted), are deprecated. The output generated when these flags are used cannot be parsed by mysql 5.6.0 and later. The flags will be removed in a future version. Please use --base64-output=auto instead. diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test index 3a9dae35476..76f6c63fc1d 100644 --- a/mysql-test/t/mysqlbinlog.test +++ b/mysql-test/t/mysqlbinlog.test @@ -487,3 +487,18 @@ diff_files $MYSQLTEST_VARDIR/tmp/mysqlbinlog.warn $MYSQLTEST_VARDIR/tmp/mysqlbin # Cleanup for this part of test remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog.warn.empty; remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog.warn; + +# +# WL#5625: Deprecate mysqlbinlog options --base64-output=always and --base64-output +# + +--echo # Expect deprecation warning. +--exec $MYSQL_BINLOG --base64-output=always std_data/master-bin.000001 > /dev/null 2> $MYSQLTEST_VARDIR/tmp/mysqlbinlog.warn +--cat_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog.warn + +--echo # Expect deprecation warning again. +--exec $MYSQL_BINLOG --base64-output std_data/master-bin.000001 > /dev/null 2> $MYSQLTEST_VARDIR/tmp/mysqlbinlog.warn +--cat_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog.warn + +# Clean up this part of the test. +--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog.warn From 20d704978ddb14dee414f40f28bd58f82b21711c Mon Sep 17 00:00:00 2001 From: Gleb Shchepa Date: Sun, 31 Oct 2010 19:04:38 +0300 Subject: [PATCH 137/304] Bug #52160: crash and inconsistent results when grouping by a function and column The bugreport reveals two different bugs about grouping on a function: 1) grouping by the TIME_TO_SEC function result caused a server crash or wrong results and 2) grouping by the function returning a blob caused an unexpected "Duplicate entry" error and wrong result. Details for the 1st bug: TIME_TO_SEC() returns NULL if its argument is invalid (empty string for example). Thus its nullability depends not only on the nullability of its arguments but also on their values. Fixed by (overoptimistically) setting TIME_TO_SEC() to be nullable despite the nullability of its arguments. Details for the 2nd bug: The server is unable to create indices on blobs without explicit blob key part length. However, this fact was ignored for blob function result fields of GROUP BY intermediate tables. Fixed by disabling GROUP BY index creation for blob function result fields like regular blob fields. mysql-test/r/func_time.result: Test case for bug #52160. mysql-test/r/type_blob.result: Test case for bug #52160. mysql-test/t/func_time.test: Test case for bug #52160. mysql-test/t/type_blob.test: Test case for bug #52160. sql/item_timefunc.h: Bug #52160: crash and inconsistent results when grouping by a function and column TIME_TO_SEC() returns NULL if its argument is invalid (empty string for example). Thus its nullability depends not only Fixed by (overoptimistically) setting TIME_TO_SEC() to be nullable despite the nullability of its arguments. sql/sql_select.cc: Bug #52160: crash and inconsistent results when grouping by a function and column The server is unable to create indices on blobs without explicit blob key part length. However, this fact was ignored for blob function result fields of GROUP BY intermediate tables. Fixed by disabling GROUP BY index creation for blob function result fields like regular blob fields. --- mysql-test/r/func_time.result | 14 ++++++++++++++ mysql-test/r/type_blob.result | 11 +++++++++++ mysql-test/t/func_time.test | 10 ++++++++++ mysql-test/t/type_blob.test | 16 ++++++++++++++++ sql/item_timefunc.h | 1 + sql/sql_select.cc | 2 ++ 6 files changed, 54 insertions(+) diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index 4ff4cfa586b..48e837f180f 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -1343,4 +1343,18 @@ SELECT 1 FROM t1 ORDER BY @x:=makedate(a,a); 1 1 DROP TABLE t1; +# +# Bug #52160: crash and inconsistent results when grouping +# by a function and column +# +CREATE TABLE t1(a CHAR(10) NOT NULL); +INSERT INTO t1 VALUES (''),(''); +SELECT COUNT(*) FROM t1 GROUP BY TIME_TO_SEC(a); +COUNT(*) +2 +Warnings: +Warning 1292 Truncated incorrect time value: '' +Warning 1292 Truncated incorrect time value: '' +Warning 1292 Truncated incorrect time value: '' +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/r/type_blob.result b/mysql-test/r/type_blob.result index 08c30d884fd..e6fd49b4247 100644 --- a/mysql-test/r/type_blob.result +++ b/mysql-test/r/type_blob.result @@ -974,3 +974,14 @@ ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967 explain select convert(1, binary(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999)); ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295) End of 5.0 tests +# Bug #52160: crash and inconsistent results when grouping +# by a function and column +CREATE FUNCTION f1() RETURNS TINYBLOB RETURN 1; +CREATE TABLE t1(a CHAR(1)); +INSERT INTO t1 VALUES ('0'), ('0'); +SELECT COUNT(*) FROM t1 GROUP BY f1(), a; +COUNT(*) +2 +DROP FUNCTION f1; +DROP TABLE t1; +End of 5.1 tests diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index e764906c374..8fce7072319 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -849,4 +849,14 @@ INSERT INTO t1 VALUES (0),(9.216e-096); SELECT 1 FROM t1 ORDER BY @x:=makedate(a,a); DROP TABLE t1; +--echo # +--echo # Bug #52160: crash and inconsistent results when grouping +--echo # by a function and column +--echo # + +CREATE TABLE t1(a CHAR(10) NOT NULL); +INSERT INTO t1 VALUES (''),(''); +SELECT COUNT(*) FROM t1 GROUP BY TIME_TO_SEC(a); +DROP TABLE t1; + --echo End of 5.1 tests diff --git a/mysql-test/t/type_blob.test b/mysql-test/t/type_blob.test index 460da1c1614..4e097edf73d 100644 --- a/mysql-test/t/type_blob.test +++ b/mysql-test/t/type_blob.test @@ -612,3 +612,19 @@ explain select convert(1, binary(4294967296)); explain select convert(1, binary(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999)); --echo End of 5.0 tests + +--echo # Bug #52160: crash and inconsistent results when grouping +--echo # by a function and column + +CREATE FUNCTION f1() RETURNS TINYBLOB RETURN 1; + +CREATE TABLE t1(a CHAR(1)); +INSERT INTO t1 VALUES ('0'), ('0'); + +SELECT COUNT(*) FROM t1 GROUP BY f1(), a; + +DROP FUNCTION f1; +DROP TABLE t1; + +--echo End of 5.1 tests + diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index ef86406e1be..47bb9509582 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -331,6 +331,7 @@ public: const char *func_name() const { return "time_to_sec"; } void fix_length_and_dec() { + maybe_null= TRUE; decimals=0; max_length=10*MY_CHARSET_BIN_MB_MAXLEN; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 08bd0c28738..77d4447fd0f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -15198,6 +15198,8 @@ calc_group_buffer(JOIN *join,ORDER *group) { key_length+= 8; } + else if (type == MYSQL_TYPE_BLOB) + key_length+= MAX_BLOB_WIDTH; // Can't be used as a key else { /* From 930cf09ec7bb1dc73caf12c3af05da0e490f37d9 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Mon, 1 Nov 2010 09:47:57 +0300 Subject: [PATCH 138/304] test case fix --- mysql-test/t/func_gconcat.test | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test index 29fc8a9dc3c..a7072362759 100644 --- a/mysql-test/t/func_gconcat.test +++ b/mysql-test/t/func_gconcat.test @@ -740,8 +740,10 @@ DROP TABLE t1; CREATE TABLE t1(f1 int); INSERT INTO t1 values (0),(0); +--disable_ps_protocol --error ER_ILLEGAL_VALUE_FOR_TYPE SELECT POLYGON((SELECT 1 FROM (SELECT 1 IN (GROUP_CONCAT(t1.f1)) FROM t1, t1 t GROUP BY t.f1 ) d)); +--enable_ps_protocol DROP TABLE t1; --echo End of 5.1 tests From cdd706981c1dcda58624f38b75ac1c34e7f38a8a Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 1 Nov 2010 15:00:40 +0800 Subject: [PATCH 139/304] Re-enabled rpl.rpl_innodb_bug30888. --- mysql-test/collections/default.experimental | 1 - 1 file changed, 1 deletion(-) diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index 29046e9b8bc..ce3f50f5f94 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -24,7 +24,6 @@ main.wait_timeout @solaris # Bug#51244 2010-04-26 alik wait_timeou rpl.rpl_heartbeat_basic # BUG#54820 2010-06-26 alik rpl.rpl_heartbeat_basic fails sporadically again rpl.rpl_heartbeat_2slaves # BUG#43828 2009-10-22 luis fails sporadically rpl.rpl_innodb_bug28430* # Bug#46029 -rpl.rpl_innodb_bug30888* @solaris # Bug#47646 2009-09-25 alik rpl.rpl_innodb_bug30888 fails sporadically on Solaris rpl.rpl_killed_ddl @windows # Bug#47638 2010-01-20 alik The rpl_killed_ddl test fails on Windows sys_vars.max_sp_recursion_depth_func @solaris # Bug#47791 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun From 6b553e775cff0b25c5fea9c07389268215222396 Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Mon, 1 Nov 2010 10:53:21 +0300 Subject: [PATCH 140/304] Fix version tag (remove -ga suffix). --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index d8a45214a5c..2d67f34b4bb 100644 --- a/configure.in +++ b/configure.in @@ -27,7 +27,7 @@ dnl dnl When changing the major version number please also check the switch dnl statement in mysqlbinlog::check_master_version(). You may also need dnl to update version.c in ndb. -AC_INIT([MySQL Server], [5.5.8-ga], [], [mysql]) +AC_INIT([MySQL Server], [5.5.8], [], [mysql]) AC_CONFIG_SRCDIR([sql/mysqld.cc]) AC_CANONICAL_SYSTEM From fc3d1bfaf325be56ad618d6119bb3f0a3746e27e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 1 Nov 2010 10:18:33 +0200 Subject: [PATCH 141/304] Bug #57579 blobs cause a thread to wait for itself endlessly btr_estimate_n_rows_in_range_on_level(): Always do mtr_commit(), so that the page will not remain pinned indefinitely. --- storage/innobase/btr/btr0cur.c | 1 + 1 file changed, 1 insertion(+) diff --git a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c index 73d27a787f4..ef684be8e67 100644 --- a/storage/innobase/btr/btr0cur.c +++ b/storage/innobase/btr/btr0cur.c @@ -3277,6 +3277,7 @@ btr_estimate_n_rows_in_range_on_level( || btr_page_get_level_low(page) != level) { /* The page got reused for something else */ + mtr_commit(&mtr); goto inexact; } From 4c28bc86712d6dea4132b629adaf235e60fff55b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 1 Nov 2010 10:49:28 +0200 Subject: [PATCH 142/304] Start preprocessor directive from column 1. --- storage/innobase/btr/btr0cur.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c index ef684be8e67..378b9020c0d 100644 --- a/storage/innobase/btr/btr0cur.c +++ b/storage/innobase/btr/btr0cur.c @@ -3248,7 +3248,7 @@ btr_estimate_n_rows_in_range_on_level( performance with this code which is just an estimation. If we read this many pages before reaching slot2->page_no then we estimate the average from the pages scanned so far */ - #define N_PAGES_READ_LIMIT 10 +# define N_PAGES_READ_LIMIT 10 page_no = slot1->page_no; level = slot1->page_level; From 52ebe700c48269f95b29f2a8aa6c6fb2e770538c Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Mon, 1 Nov 2010 12:36:43 +0300 Subject: [PATCH 143/304] Temporarily fix for configure.in -- CMakeFiles requires suffix in version tag. --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 2d67f34b4bb..9f986e068cb 100644 --- a/configure.in +++ b/configure.in @@ -27,7 +27,7 @@ dnl dnl When changing the major version number please also check the switch dnl statement in mysqlbinlog::check_master_version(). You may also need dnl to update version.c in ndb. -AC_INIT([MySQL Server], [5.5.8], [], [mysql]) +AC_INIT([MySQL Server], [5.5.8-rc], [], [mysql]) AC_CONFIG_SRCDIR([sql/mysqld.cc]) AC_CANONICAL_SYSTEM From 8bdef5a27c6e7cf68493004113b2dcd354d858a4 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Mon, 1 Nov 2010 14:11:02 +0200 Subject: [PATCH 144/304] fixed a failure in the build scripts because of unexpected suffix --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index d8a45214a5c..9f986e068cb 100644 --- a/configure.in +++ b/configure.in @@ -27,7 +27,7 @@ dnl dnl When changing the major version number please also check the switch dnl statement in mysqlbinlog::check_master_version(). You may also need dnl to update version.c in ndb. -AC_INIT([MySQL Server], [5.5.8-ga], [], [mysql]) +AC_INIT([MySQL Server], [5.5.8-rc], [], [mysql]) AC_CONFIG_SRCDIR([sql/mysqld.cc]) AC_CANONICAL_SYSTEM From c3b64853e9e3c620d0f0321237ce6ce052c5e4a1 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Mon, 1 Nov 2010 15:10:02 +0200 Subject: [PATCH 145/304] fixed the .spec file to package the new QA plugins. --- support-files/mysql.spec.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 15fe4a38a54..5c2ea2305d3 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -977,6 +977,9 @@ echo "=====" >> $STATUS_HISTORY %attr(755, root, root) %{_libdir}/mysql/plugin/auth.so %attr(755, root, root) %{_libdir}/mysql/plugin/auth_socket.so %attr(755, root, root) %{_libdir}/mysql/plugin/auth_test_plugin.so +%attr(755, root, root) %{_libdir}/mysql/plugin/qa_auth_client.so +%attr(755, root, root) %{_libdir}/mysql/plugin/qa_auth_interface.so +%attr(755, root, root) %{_libdir}/mysql/plugin/qa_auth_server.so %attr(755, root, root) %{_libdir}/mysql/plugin/debug/adt_null.so %attr(755, root, root) %{_libdir}/mysql/plugin/debug/libdaemon_example.so %attr(755, root, root) %{_libdir}/mysql/plugin/debug/mypluglib.so @@ -985,6 +988,9 @@ echo "=====" >> $STATUS_HISTORY %attr(755, root, root) %{_libdir}/mysql/plugin/debug/auth.so %attr(755, root, root) %{_libdir}/mysql/plugin/debug/auth_socket.so %attr(755, root, root) %{_libdir}/mysql/plugin/debug/auth_test_plugin.so +%attr(755, root, root) %{_libdir}/mysql/plugin/debug/qa_auth_client.so +%attr(755, root, root) %{_libdir}/mysql/plugin/debug/qa_auth_interface.so +%attr(755, root, root) %{_libdir}/mysql/plugin/debug/qa_auth_server.so %if %{WITH_TCMALLOC} %attr(755, root, root) %{_libdir}/mysql/%{malloc_lib_target} @@ -1081,6 +1087,10 @@ echo "=====" >> $STATUS_HISTORY # merging BK trees) ############################################################################## %changelog +* Mon Nov 1 2010 Georgi Kodinov + +- Added test authentication (WL#1054) plugin binaries + * Wed Oct 6 2010 Georgi Kodinov - Added example external authentication (WL#1054) plugin binaries From c10eb6ec6170734d87ab7f60a1c506c544de88e7 Mon Sep 17 00:00:00 2001 From: Jon Olav Hauglid Date: Mon, 1 Nov 2010 14:12:59 +0100 Subject: [PATCH 146/304] Backport from mysql-trunk-bugfixing of: ------------------------------------------------------------ revno: 3309 committer: Tor Didriksen branch nick: trunk-bugfixing timestamp: Mon 2010-11-01 08:58:27 +0100 message: Bug#45288: pb2 returns a lot of compilation warnings DBG build broken on binary-werror-linux-x86_64-tar-gz storage/innobase/os/os0sync.c:659: warning: 'timed_out' may be used uninitialized in this function --- storage/innobase/os/os0sync.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/os/os0sync.c b/storage/innobase/os/os0sync.c index 24d36acecb2..b461f9b7c78 100644 --- a/storage/innobase/os/os0sync.c +++ b/storage/innobase/os/os0sync.c @@ -656,7 +656,7 @@ os_event_wait_time_low( os_event_reset(). */ { - ibool timed_out; + ibool timed_out = FALSE; ib_int64_t old_signal_count; #ifdef __WIN__ From 6c802b3c4307580a3387a5a8fcd29a0656fa4177 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 2 Nov 2010 09:28:05 +0200 Subject: [PATCH 147/304] White-space corrections in the InnoDB Plugin ChangeLog --- storage/innodb_plugin/ChangeLog | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 9033e5557f3..1be14034be4 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,13 +1,13 @@ 2010-10-24 The InnoDB Team * row/row0mysql.c - Fix Bug #57700 Latching order violation in + Fix Bug#57700 Latching order violation in row_truncate_table_for_mysql() 2010-10-20 The InnoDB Team * dict/dict0load.c - Fix Bug #57616 Sig 11 in dict_load_table() when failed to load + Fix Bug#57616 Sig 11 in dict_load_table() when failed to load index or foreign key 2010-10-19 The InnoDB Team @@ -17,7 +17,7 @@ include/ibuf0ibuf.h, include/row0mysql.h, row/row0mysql.c, row/row0sel.c, innodb_bug56680.test, innodb_bug56680.result: - Fix Bug #56680 InnoDB may return wrong results from a + Fix Bug#56680 InnoDB may return wrong results from a case-insensitive covering index 2010-10-18 The InnoDB Team @@ -61,7 +61,7 @@ 2010-08-03 The InnoDB Team * include/dict0dict.h, include/dict0dict.ic, row/row0mysql.c: - Fix bug #54678, InnoDB, TRUNCATE, ALTER, I_S SELECT, crash or deadlock + Fix Bug#54678 InnoDB, TRUNCATE, ALTER, I_S SELECT, crash or deadlock 2010-08-03 The InnoDB Team @@ -135,7 +135,7 @@ * dict/dict0load.c, fil/fil0fil.c: Fix Bug#54658: InnoDB: Warning: allocated tablespace %lu, - old maximum was 0 (introduced in Bug #53578 fix) + old maximum was 0 (introduced in Bug#53578 fix) 2010-06-16 The InnoDB Team From 004bb1b15ebbf4efe996d04c4bb95a235a718c62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 2 Nov 2010 09:28:48 +0200 Subject: [PATCH 148/304] Bug#57799 READ UNCOMMITTED access failure of off-page DYNAMIC or COMPRESSED columns again This is follow-up to Bug #54358. Not all occurrences of the bug were fixed. We need to check all calls to btr_copy_externally_stored_field_prefix_low() and do the right thing when the pointer to the off-page column is null (full of zero bytes). It turns out that only the call to btr_copy_externally_stored_field_prefix() in row_sel_sec_rec_is_for_blob() needs to be changed. For fetching complete off-page columns rather than prefixes, the function btr_rec_copy_externally_stored_field() already checks if the pointer is null (all-zero). Two of its callers (row_merge_copy_blobs() and row_sel_fetch_columns()) are never executed as READ COMMITTED and can rightfully assert that the fetch succeeded. The third caller, row_sel_store_mysql_rec(), already does the right thing. The calls in row_upd_ext_fetch() and trx_undo_page_fetch_ext() must expect that the off-page column exists. Update and rollback are locking operations, never READ UNCOMMITTED. --- storage/innodb_plugin/ChangeLog | 6 ++++++ storage/innodb_plugin/row/row0sel.c | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 1be14034be4..3792d48e5f2 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,9 @@ +2010-11-02 The InnoDB Team + + * row/row0sel.c: + Fix Bug#57799 READ UNCOMMITTED access failure of off-page + DYNAMIC or COMPRESSED columns again + 2010-10-24 The InnoDB Team * row/row0mysql.c diff --git a/storage/innodb_plugin/row/row0sel.c b/storage/innodb_plugin/row/row0sel.c index ac78a95839c..423ddfade22 100644 --- a/storage/innodb_plugin/row/row0sel.c +++ b/storage/innodb_plugin/row/row0sel.c @@ -106,6 +106,18 @@ row_sel_sec_rec_is_for_blob( ulint len; byte buf[DICT_MAX_INDEX_COL_LEN]; + ut_a(clust_len >= BTR_EXTERN_FIELD_REF_SIZE); + + if (UNIV_UNLIKELY + (!memcmp(clust_field + clust_len - BTR_EXTERN_FIELD_REF_SIZE, + field_ref_zero, BTR_EXTERN_FIELD_REF_SIZE))) { + /* The externally stored field was not written yet. + This record should only be seen by + recv_recovery_rollback_active() or any + TRX_ISO_READ_UNCOMMITTED transactions. */ + return(FALSE); + } + len = btr_copy_externally_stored_field_prefix(buf, sizeof buf, zip_size, clust_field, clust_len); From addb14753368e09fb3cb10e6d5cda69e3e96a4e0 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 2 Nov 2010 10:00:04 +0200 Subject: [PATCH 149/304] Increment InnoDB Plugin version to 1.0.14. InnoDB Plugin 1.0.13 has been released with MySQL 5.1.52. --- storage/innodb_plugin/include/univ.i | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innodb_plugin/include/univ.i b/storage/innodb_plugin/include/univ.i index ee77582d7f1..c1ed56684c9 100644 --- a/storage/innodb_plugin/include/univ.i +++ b/storage/innodb_plugin/include/univ.i @@ -46,7 +46,7 @@ Created 1/20/1994 Heikki Tuuri #define INNODB_VERSION_MAJOR 1 #define INNODB_VERSION_MINOR 0 -#define INNODB_VERSION_BUGFIX 13 +#define INNODB_VERSION_BUGFIX 14 /* The following is the InnoDB version as shown in SELECT plugin_version FROM information_schema.plugins; From 1a5a109524cbd3445544888170686b023c6331b8 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Tue, 2 Nov 2010 15:20:02 +0200 Subject: [PATCH 150/304] Bug #51208: Extra string allocation from thd->mem_root in sql_show.cc, find_files() Removed the extra allocation. --- sql/sql_show.cc | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index e074461b452..9b344204d64 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -534,12 +534,6 @@ find_files(THD *thd, List *files, const char *db, else if (wild_compare(uname, wild, 0)) continue; } - if (!(file_name= - thd->make_lex_string(file_name, uname, file_name_len, TRUE))) - { - my_dirend(dirp); - DBUG_RETURN(FIND_FILES_OOM); - } } else { From a63c14e9a6b4d2d2cccf302cc0e6e03f97ef0d02 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 2 Nov 2010 10:03:14 -0500 Subject: [PATCH 151/304] Bug#57904 - Only one INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS was displayed per table from Innodb --- .../suite/innodb/r/innodb_bug57904.result | 41 +++++++++++++++++++ .../suite/innodb/t/innodb_bug57904.test | 27 ++++++++++++ storage/innobase/handler/ha_innodb.cc | 2 +- 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100755 mysql-test/suite/innodb/r/innodb_bug57904.result create mode 100755 mysql-test/suite/innodb/t/innodb_bug57904.test diff --git a/mysql-test/suite/innodb/r/innodb_bug57904.result b/mysql-test/suite/innodb/r/innodb_bug57904.result new file mode 100755 index 00000000000..c3e980a6cf4 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug57904.result @@ -0,0 +1,41 @@ +CREATE TABLE product (category INT NOT NULL, id INT NOT NULL, +price DECIMAL, PRIMARY KEY(category, id)) ENGINE=INNODB; +CREATE TABLE customer (id INT NOT NULL, PRIMARY KEY (id)) ENGINE=INNODB; +CREATE TABLE product_order (no INT NOT NULL AUTO_INCREMENT, +product_category INT NOT NULL, +product_id INT NOT NULL, +customer_id INT NOT NULL, +PRIMARY KEY(no), +INDEX (product_category, product_id), +FOREIGN KEY (product_category, product_id) +REFERENCES product(category, id) ON UPDATE CASCADE ON DELETE RESTRICT, +INDEX (customer_id), +FOREIGN KEY (customer_id) +REFERENCES customer(id) +) ENGINE=INNODB; +SELECT * FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS; +CONSTRAINT_CATALOG def +CONSTRAINT_SCHEMA test +CONSTRAINT_NAME product_order_ibfk_1 +UNIQUE_CONSTRAINT_CATALOG def +UNIQUE_CONSTRAINT_SCHEMA test +UNIQUE_CONSTRAINT_NAME PRIMARY +MATCH_OPTION NONE +UPDATE_RULE CASCADE +DELETE_RULE RESTRICT +TABLE_NAME product_order +REFERENCED_TABLE_NAME pro +CONSTRAINT_CATALOG def +CONSTRAINT_SCHEMA test +CONSTRAINT_NAME product_order_ibfk_2 +UNIQUE_CONSTRAINT_CATALOG def +UNIQUE_CONSTRAINT_SCHEMA test +UNIQUE_CONSTRAINT_NAME PRIMARY +MATCH_OPTION NONE +UPDATE_RULE RESTRICT +DELETE_RULE RESTRICT +TABLE_NAME product_order +REFERENCED_TABLE_NAME cus +DROP TABLE product_order; +DROP TABLE product; +DROP TABLE customer; diff --git a/mysql-test/suite/innodb/t/innodb_bug57904.test b/mysql-test/suite/innodb/t/innodb_bug57904.test new file mode 100755 index 00000000000..d283ad11c3a --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug57904.test @@ -0,0 +1,27 @@ +# +# Bug #57904 Missing constraint from information schema REFERENTIAL_CONSTRAINTS table +# +-- source include/have_innodb.inc + +CREATE TABLE product (category INT NOT NULL, id INT NOT NULL, + price DECIMAL, PRIMARY KEY(category, id)) ENGINE=INNODB; +CREATE TABLE customer (id INT NOT NULL, PRIMARY KEY (id)) ENGINE=INNODB; +CREATE TABLE product_order (no INT NOT NULL AUTO_INCREMENT, + product_category INT NOT NULL, + product_id INT NOT NULL, + customer_id INT NOT NULL, + PRIMARY KEY(no), + INDEX (product_category, product_id), + FOREIGN KEY (product_category, product_id) + REFERENCES product(category, id) ON UPDATE CASCADE ON DELETE RESTRICT, + INDEX (customer_id), + FOREIGN KEY (customer_id) + REFERENCES customer(id) + ) ENGINE=INNODB; + +query_vertical SELECT * FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS; + +DROP TABLE product_order; +DROP TABLE product; +DROP TABLE customer; + diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index c955f807a63..1a2e26ba1ab 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -8482,7 +8482,7 @@ ha_innobase::get_foreign_key_list( for (foreign = UT_LIST_GET_FIRST(prebuilt->table->foreign_list); foreign != NULL; - foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) { + foreign = UT_LIST_GET_NEXT(foreign_list, foreign)) { pf_key_info = get_foreign_key_info(thd, foreign); if (pf_key_info) { f_key_list->push_back(pf_key_info); From 7f02528fe7d216fa2df832e7f999a1ecb99b555c Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 2 Nov 2010 10:16:55 -0500 Subject: [PATCH 152/304] Bug#57904 - Only one INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS was displayed per table from Innodb --- .../suite/innodb/r/innodb_bug57904.result | 41 +++++++++++++++++++ .../suite/innodb/t/innodb_bug57904.test | 27 ++++++++++++ storage/innobase/handler/ha_innodb.cc | 2 +- 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 mysql-test/suite/innodb/r/innodb_bug57904.result create mode 100644 mysql-test/suite/innodb/t/innodb_bug57904.test diff --git a/mysql-test/suite/innodb/r/innodb_bug57904.result b/mysql-test/suite/innodb/r/innodb_bug57904.result new file mode 100644 index 00000000000..c3e980a6cf4 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug57904.result @@ -0,0 +1,41 @@ +CREATE TABLE product (category INT NOT NULL, id INT NOT NULL, +price DECIMAL, PRIMARY KEY(category, id)) ENGINE=INNODB; +CREATE TABLE customer (id INT NOT NULL, PRIMARY KEY (id)) ENGINE=INNODB; +CREATE TABLE product_order (no INT NOT NULL AUTO_INCREMENT, +product_category INT NOT NULL, +product_id INT NOT NULL, +customer_id INT NOT NULL, +PRIMARY KEY(no), +INDEX (product_category, product_id), +FOREIGN KEY (product_category, product_id) +REFERENCES product(category, id) ON UPDATE CASCADE ON DELETE RESTRICT, +INDEX (customer_id), +FOREIGN KEY (customer_id) +REFERENCES customer(id) +) ENGINE=INNODB; +SELECT * FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS; +CONSTRAINT_CATALOG def +CONSTRAINT_SCHEMA test +CONSTRAINT_NAME product_order_ibfk_1 +UNIQUE_CONSTRAINT_CATALOG def +UNIQUE_CONSTRAINT_SCHEMA test +UNIQUE_CONSTRAINT_NAME PRIMARY +MATCH_OPTION NONE +UPDATE_RULE CASCADE +DELETE_RULE RESTRICT +TABLE_NAME product_order +REFERENCED_TABLE_NAME pro +CONSTRAINT_CATALOG def +CONSTRAINT_SCHEMA test +CONSTRAINT_NAME product_order_ibfk_2 +UNIQUE_CONSTRAINT_CATALOG def +UNIQUE_CONSTRAINT_SCHEMA test +UNIQUE_CONSTRAINT_NAME PRIMARY +MATCH_OPTION NONE +UPDATE_RULE RESTRICT +DELETE_RULE RESTRICT +TABLE_NAME product_order +REFERENCED_TABLE_NAME cus +DROP TABLE product_order; +DROP TABLE product; +DROP TABLE customer; diff --git a/mysql-test/suite/innodb/t/innodb_bug57904.test b/mysql-test/suite/innodb/t/innodb_bug57904.test new file mode 100644 index 00000000000..d283ad11c3a --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug57904.test @@ -0,0 +1,27 @@ +# +# Bug #57904 Missing constraint from information schema REFERENTIAL_CONSTRAINTS table +# +-- source include/have_innodb.inc + +CREATE TABLE product (category INT NOT NULL, id INT NOT NULL, + price DECIMAL, PRIMARY KEY(category, id)) ENGINE=INNODB; +CREATE TABLE customer (id INT NOT NULL, PRIMARY KEY (id)) ENGINE=INNODB; +CREATE TABLE product_order (no INT NOT NULL AUTO_INCREMENT, + product_category INT NOT NULL, + product_id INT NOT NULL, + customer_id INT NOT NULL, + PRIMARY KEY(no), + INDEX (product_category, product_id), + FOREIGN KEY (product_category, product_id) + REFERENCES product(category, id) ON UPDATE CASCADE ON DELETE RESTRICT, + INDEX (customer_id), + FOREIGN KEY (customer_id) + REFERENCES customer(id) + ) ENGINE=INNODB; + +query_vertical SELECT * FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS; + +DROP TABLE product_order; +DROP TABLE product; +DROP TABLE customer; + diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 7f2e8a44a09..8386512074a 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -8459,7 +8459,7 @@ ha_innobase::get_foreign_key_list( for (foreign = UT_LIST_GET_FIRST(prebuilt->table->foreign_list); foreign != NULL; - foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) { + foreign = UT_LIST_GET_NEXT(foreign_list, foreign)) { pf_key_info = get_foreign_key_info(thd, foreign); if (pf_key_info) { f_key_list->push_back(pf_key_info); From 00f1e71d9ab02ca4b7b47b194a122afd88bad7f3 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Tue, 2 Nov 2010 17:45:26 +0200 Subject: [PATCH 153/304] Bug #57916: Fix the naming of the proxy_priv table 1. Fixed the name of the table to proxies_priv 2. Fixed the column names to be of the form Capitalized_lowecarse instead of Capitalized_Capitalized 3. Added Timestamp and Grantor columns 4. Added tests to plugin_auth to check the table structure 5. Updated the existing tests --- mysql-test/r/1st.result | 2 +- mysql-test/r/connect.result | 6 +- mysql-test/r/information_schema.result | 2 +- mysql-test/r/log_tables_upgrade.result | 2 +- mysql-test/r/mysql_upgrade.result | 12 +-- mysql-test/r/mysql_upgrade_ssl.result | 2 +- mysql-test/r/mysqlcheck.result | 8 +- mysql-test/r/plugin_auth.result | 24 +++++- mysql-test/r/system_mysql_db.result | 2 +- .../suite/funcs_1/r/is_columns_mysql.result | 24 +++--- .../funcs_1/r/is_key_column_usage.result | 8 +- .../suite/funcs_1/r/is_statistics.result | 9 +- .../funcs_1/r/is_statistics_mysql.result | 9 +- .../funcs_1/r/is_table_constraints.result | 2 +- .../r/is_table_constraints_mysql.result | 2 +- .../suite/funcs_1/r/is_tables_mysql.result | 2 +- mysql-test/t/plugin_auth.test | 7 +- mysql-test/t/system_mysql_db_fix40123.test | 2 +- mysql-test/t/system_mysql_db_fix50030.test | 2 +- mysql-test/t/system_mysql_db_fix50117.test | 2 +- scripts/mysql_system_tables.sql | 6 +- scripts/mysql_system_tables_data.sql | 10 +-- scripts/mysql_system_tables_fix.sql | 2 +- sql/sql_acl.cc | 85 +++++++++++-------- 24 files changed, 137 insertions(+), 95 deletions(-) diff --git a/mysql-test/r/1st.result b/mysql-test/r/1st.result index e8562662bfd..792d9eaf2f1 100644 --- a/mysql-test/r/1st.result +++ b/mysql-test/r/1st.result @@ -21,7 +21,7 @@ ndb_binlog_index plugin proc procs_priv -proxy_priv +proxies_priv servers slow_log tables_priv diff --git a/mysql-test/r/connect.result b/mysql-test/r/connect.result index bbd0273c1c6..b21956252d2 100644 --- a/mysql-test/r/connect.result +++ b/mysql-test/r/connect.result @@ -15,7 +15,7 @@ ndb_binlog_index plugin proc procs_priv -proxy_priv +proxies_priv servers slow_log tables_priv @@ -49,7 +49,7 @@ ndb_binlog_index plugin proc procs_priv -proxy_priv +proxies_priv servers slow_log tables_priv @@ -91,7 +91,7 @@ ndb_binlog_index plugin proc procs_priv -proxy_priv +proxies_priv servers slow_log tables_priv diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index bab60774b32..1418af5b813 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -88,7 +88,7 @@ host plugin proc procs_priv -proxy_priv +proxies_priv servers slow_log tables_priv diff --git a/mysql-test/r/log_tables_upgrade.result b/mysql-test/r/log_tables_upgrade.result index 13b08c2e771..7d15005e143 100644 --- a/mysql-test/r/log_tables_upgrade.result +++ b/mysql-test/r/log_tables_upgrade.result @@ -27,7 +27,7 @@ mysql.ndb_binlog_index OK mysql.plugin OK mysql.proc OK mysql.procs_priv OK -mysql.proxy_priv OK +mysql.proxies_priv OK mysql.renamed_general_log OK mysql.servers OK mysql.slow_log OK diff --git a/mysql-test/r/mysql_upgrade.result b/mysql-test/r/mysql_upgrade.result index f705db3e509..e36b4781ddf 100644 --- a/mysql-test/r/mysql_upgrade.result +++ b/mysql-test/r/mysql_upgrade.result @@ -15,7 +15,7 @@ mysql.ndb_binlog_index OK mysql.plugin OK mysql.proc OK mysql.procs_priv OK -mysql.proxy_priv OK +mysql.proxies_priv OK mysql.servers OK mysql.slow_log OK mysql.tables_priv OK @@ -44,7 +44,7 @@ mysql.ndb_binlog_index OK mysql.plugin OK mysql.proc OK mysql.procs_priv OK -mysql.proxy_priv OK +mysql.proxies_priv OK mysql.servers OK mysql.slow_log OK mysql.tables_priv OK @@ -73,7 +73,7 @@ mysql.ndb_binlog_index OK mysql.plugin OK mysql.proc OK mysql.procs_priv OK -mysql.proxy_priv OK +mysql.proxies_priv OK mysql.servers OK mysql.slow_log OK mysql.tables_priv OK @@ -104,7 +104,7 @@ mysql.ndb_binlog_index OK mysql.plugin OK mysql.proc OK mysql.procs_priv OK -mysql.proxy_priv OK +mysql.proxies_priv OK mysql.servers OK mysql.slow_log OK mysql.tables_priv OK @@ -139,7 +139,7 @@ mysql.ndb_binlog_index OK mysql.plugin OK mysql.proc OK mysql.procs_priv OK -mysql.proxy_priv OK +mysql.proxies_priv OK mysql.servers OK mysql.slow_log OK mysql.tables_priv OK @@ -177,7 +177,7 @@ mysql.ndb_binlog_index OK mysql.plugin OK mysql.proc OK mysql.procs_priv OK -mysql.proxy_priv OK +mysql.proxies_priv OK mysql.servers OK mysql.slow_log OK mysql.tables_priv OK diff --git a/mysql-test/r/mysql_upgrade_ssl.result b/mysql-test/r/mysql_upgrade_ssl.result index 694eb1e7d88..4cc8b6ab44b 100644 --- a/mysql-test/r/mysql_upgrade_ssl.result +++ b/mysql-test/r/mysql_upgrade_ssl.result @@ -17,7 +17,7 @@ mysql.ndb_binlog_index OK mysql.plugin OK mysql.proc OK mysql.procs_priv OK -mysql.proxy_priv OK +mysql.proxies_priv OK mysql.servers OK mysql.slow_log OK mysql.tables_priv OK diff --git a/mysql-test/r/mysqlcheck.result b/mysql-test/r/mysqlcheck.result index 241c92f0aa6..ef46eba5ccb 100644 --- a/mysql-test/r/mysqlcheck.result +++ b/mysql-test/r/mysqlcheck.result @@ -18,7 +18,7 @@ mysql.ndb_binlog_index OK mysql.plugin OK mysql.proc OK mysql.procs_priv OK -mysql.proxy_priv OK +mysql.proxies_priv OK mysql.servers OK mysql.slow_log note : The storage engine for the table doesn't support analyze @@ -46,7 +46,7 @@ mysql.ndb_binlog_index OK mysql.plugin OK mysql.proc OK mysql.procs_priv OK -mysql.proxy_priv OK +mysql.proxies_priv OK mysql.servers OK mysql.slow_log note : The storage engine for the table doesn't support optimize @@ -72,7 +72,7 @@ mysql.ndb_binlog_index OK mysql.plugin OK mysql.proc OK mysql.procs_priv OK -mysql.proxy_priv OK +mysql.proxies_priv OK mysql.servers OK mysql.slow_log note : The storage engine for the table doesn't support analyze @@ -98,7 +98,7 @@ mysql.ndb_binlog_index Table is already up to date mysql.plugin Table is already up to date mysql.proc Table is already up to date mysql.procs_priv Table is already up to date -mysql.proxy_priv Table is already up to date +mysql.proxies_priv Table is already up to date mysql.servers Table is already up to date mysql.slow_log note : The storage engine for the table doesn't support optimize diff --git a/mysql-test/r/plugin_auth.result b/mysql-test/r/plugin_auth.result index 54467b78f19..d56a4e5326a 100644 --- a/mysql-test/r/plugin_auth.result +++ b/mysql-test/r/plugin_auth.result @@ -11,6 +11,26 @@ test_plugin_server plug_dest ## test plugin auth ERROR 28000: Access denied for user 'plug'@'localhost' (using password: YES) GRANT PROXY ON plug_dest TO plug; +test proxies_priv columns +SELECT * FROM mysql.proxies_priv; +Host User Proxied_host Proxied_user With_grant Grantor Timestamp +localhost root 1 xx +unknown root 1 xx +% plug % plug_dest 0 root@localhost xx +test mysql.proxies_priv; +SHOW CREATE TABLE mysql.proxies_priv; +Table Create Table +proxies_priv CREATE TABLE `proxies_priv` ( + `Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '', + `User` char(16) COLLATE utf8_bin NOT NULL DEFAULT '', + `Proxied_host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '', + `Proxied_user` char(16) COLLATE utf8_bin NOT NULL DEFAULT '', + `With_grant` tinyint(1) NOT NULL DEFAULT '0', + `Grantor` char(77) COLLATE utf8_bin NOT NULL DEFAULT '', + `Timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`Host`,`User`,`Proxied_host`,`Proxied_user`), + KEY `Grantor` (`Grantor`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='User proxy privileges' select USER(),CURRENT_USER(); USER() CURRENT_USER() plug@localhost plug_dest@% @@ -146,8 +166,8 @@ Grants for test_drop@localhost GRANT USAGE ON *.* TO 'test_drop'@'localhost' GRANT PROXY ON 'future_user'@'%' TO 'test_drop'@'localhost' DROP USER test_drop@localhost; -SELECT * FROM mysql.proxy_priv WHERE Host = 'test_drop' AND User = 'localhost'; -Host User Proxied_Host Proxied_User With_Grant +SELECT * FROM mysql.proxies_priv WHERE Host = 'test_drop' AND User = 'localhost'; +Host User Proxied_host Proxied_user With_grant Grantor Timestamp DROP USER proxy_admin; DROP USER grant_plug,grant_plug_dest,grant_plug_dest2; ## END GRANT PROXY tests diff --git a/mysql-test/r/system_mysql_db.result b/mysql-test/r/system_mysql_db.result index e82cf229912..0028f2ce5c1 100644 --- a/mysql-test/r/system_mysql_db.result +++ b/mysql-test/r/system_mysql_db.result @@ -14,7 +14,7 @@ ndb_binlog_index plugin proc procs_priv -proxy_priv +proxies_priv servers slow_log tables_priv diff --git a/mysql-test/suite/funcs_1/r/is_columns_mysql.result b/mysql-test/suite/funcs_1/r/is_columns_mysql.result index 767f9e47f13..c61a09084a8 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_mysql.result +++ b/mysql-test/suite/funcs_1/r/is_columns_mysql.result @@ -134,11 +134,13 @@ def mysql procs_priv Routine_name 4 NO char 64 192 NULL NULL utf8 utf8_general_ def mysql procs_priv Routine_type 5 NULL NO enum 9 27 NULL NULL utf8 utf8_bin enum('FUNCTION','PROCEDURE') PRI select,insert,update,references def mysql procs_priv Timestamp 8 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL NULL NULL timestamp on update CURRENT_TIMESTAMP select,insert,update,references def mysql procs_priv User 3 NO char 16 48 NULL NULL utf8 utf8_bin char(16) PRI select,insert,update,references -def mysql proxy_priv Host 1 NO char 60 180 NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references -def mysql proxy_priv Proxied_Host 3 NO char 16 48 NULL NULL utf8 utf8_bin char(16) PRI select,insert,update,references -def mysql proxy_priv Proxied_User 4 NO char 60 180 NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references -def mysql proxy_priv User 2 NO char 16 48 NULL NULL utf8 utf8_bin char(16) PRI select,insert,update,references -def mysql proxy_priv With_Grant 5 0 NO tinyint NULL NULL 3 0 NULL NULL tinyint(1) select,insert,update,references +def mysql proxies_priv Grantor 6 NO char 77 231 NULL NULL utf8 utf8_bin char(77) MUL select,insert,update,references +def mysql proxies_priv Host 1 NO char 60 180 NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references +def mysql proxies_priv Proxied_host 3 NO char 60 180 NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references +def mysql proxies_priv Proxied_user 4 NO char 16 48 NULL NULL utf8 utf8_bin char(16) PRI select,insert,update,references +def mysql proxies_priv Timestamp 7 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL NULL NULL timestamp on update CURRENT_TIMESTAMP select,insert,update,references +def mysql proxies_priv User 2 NO char 16 48 NULL NULL utf8 utf8_bin char(16) PRI select,insert,update,references +def mysql proxies_priv With_grant 5 0 NO tinyint NULL NULL 3 0 NULL NULL tinyint(1) select,insert,update,references def mysql servers Db 3 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references def mysql servers Host 2 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references def mysql servers Owner 9 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references @@ -425,11 +427,13 @@ NULL mysql proc modified timestamp NULL NULL NULL NULL timestamp 3.0000 mysql procs_priv Grantor char 77 231 utf8 utf8_bin char(77) 3.0000 mysql procs_priv Proc_priv set 27 81 utf8 utf8_general_ci set('Execute','Alter Routine','Grant') NULL mysql procs_priv Timestamp timestamp NULL NULL NULL NULL timestamp -3.0000 mysql proxy_priv Host char 60 180 utf8 utf8_bin char(60) -3.0000 mysql proxy_priv User char 16 48 utf8 utf8_bin char(16) -3.0000 mysql proxy_priv Proxied_Host char 16 48 utf8 utf8_bin char(16) -3.0000 mysql proxy_priv Proxied_User char 60 180 utf8 utf8_bin char(60) -NULL mysql proxy_priv With_Grant tinyint NULL NULL NULL NULL tinyint(1) +3.0000 mysql proxies_priv Host char 60 180 utf8 utf8_bin char(60) +3.0000 mysql proxies_priv User char 16 48 utf8 utf8_bin char(16) +3.0000 mysql proxies_priv Proxied_host char 60 180 utf8 utf8_bin char(60) +3.0000 mysql proxies_priv Proxied_user char 16 48 utf8 utf8_bin char(16) +NULL mysql proxies_priv With_grant tinyint NULL NULL NULL NULL tinyint(1) +3.0000 mysql proxies_priv Grantor char 77 231 utf8 utf8_bin char(77) +NULL mysql proxies_priv Timestamp timestamp NULL NULL NULL NULL timestamp 3.0000 mysql servers Server_name char 64 192 utf8 utf8_general_ci char(64) 3.0000 mysql servers Host char 64 192 utf8 utf8_general_ci char(64) 3.0000 mysql servers Db char 64 192 utf8 utf8_general_ci char(64) diff --git a/mysql-test/suite/funcs_1/r/is_key_column_usage.result b/mysql-test/suite/funcs_1/r/is_key_column_usage.result index 2e50a0c36bf..afd1fe15fed 100644 --- a/mysql-test/suite/funcs_1/r/is_key_column_usage.result +++ b/mysql-test/suite/funcs_1/r/is_key_column_usage.result @@ -106,10 +106,10 @@ def mysql PRIMARY def mysql procs_priv Db def mysql PRIMARY def mysql procs_priv User def mysql PRIMARY def mysql procs_priv Routine_name def mysql PRIMARY def mysql procs_priv Routine_type -def mysql PRIMARY def mysql proxy_priv Host -def mysql PRIMARY def mysql proxy_priv User -def mysql PRIMARY def mysql proxy_priv Proxied_Host -def mysql PRIMARY def mysql proxy_priv Proxied_User +def mysql PRIMARY def mysql proxies_priv Host +def mysql PRIMARY def mysql proxies_priv User +def mysql PRIMARY def mysql proxies_priv Proxied_host +def mysql PRIMARY def mysql proxies_priv Proxied_user def mysql PRIMARY def mysql servers Server_name def mysql PRIMARY def mysql tables_priv Host def mysql PRIMARY def mysql tables_priv Db diff --git a/mysql-test/suite/funcs_1/r/is_statistics.result b/mysql-test/suite/funcs_1/r/is_statistics.result index 0c43883789b..de84590e2f7 100644 --- a/mysql-test/suite/funcs_1/r/is_statistics.result +++ b/mysql-test/suite/funcs_1/r/is_statistics.result @@ -118,10 +118,11 @@ def mysql procs_priv mysql PRIMARY def mysql procs_priv mysql PRIMARY def mysql procs_priv mysql PRIMARY def mysql procs_priv mysql Grantor -def mysql proxy_priv mysql PRIMARY -def mysql proxy_priv mysql PRIMARY -def mysql proxy_priv mysql PRIMARY -def mysql proxy_priv mysql PRIMARY +def mysql proxies_priv mysql PRIMARY +def mysql proxies_priv mysql PRIMARY +def mysql proxies_priv mysql PRIMARY +def mysql proxies_priv mysql PRIMARY +def mysql proxies_priv mysql Grantor def mysql servers mysql PRIMARY def mysql tables_priv mysql PRIMARY def mysql tables_priv mysql PRIMARY diff --git a/mysql-test/suite/funcs_1/r/is_statistics_mysql.result b/mysql-test/suite/funcs_1/r/is_statistics_mysql.result index 584bbeb7af5..4c7d58f96f1 100644 --- a/mysql-test/suite/funcs_1/r/is_statistics_mysql.result +++ b/mysql-test/suite/funcs_1/r/is_statistics_mysql.result @@ -40,10 +40,11 @@ def mysql procs_priv 0 mysql PRIMARY 2 Db A #CARD# NULL NULL BTREE def mysql procs_priv 0 mysql PRIMARY 3 User A #CARD# NULL NULL BTREE def mysql procs_priv 0 mysql PRIMARY 4 Routine_name A #CARD# NULL NULL BTREE def mysql procs_priv 0 mysql PRIMARY 5 Routine_type A #CARD# NULL NULL BTREE -def mysql proxy_priv 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE -def mysql proxy_priv 0 mysql PRIMARY 2 User A #CARD# NULL NULL BTREE -def mysql proxy_priv 0 mysql PRIMARY 3 Proxied_Host A #CARD# NULL NULL BTREE -def mysql proxy_priv 0 mysql PRIMARY 4 Proxied_User A #CARD# NULL NULL BTREE +def mysql proxies_priv 1 mysql Grantor 1 Grantor A #CARD# NULL NULL BTREE +def mysql proxies_priv 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE +def mysql proxies_priv 0 mysql PRIMARY 2 User A #CARD# NULL NULL BTREE +def mysql proxies_priv 0 mysql PRIMARY 3 Proxied_host A #CARD# NULL NULL BTREE +def mysql proxies_priv 0 mysql PRIMARY 4 Proxied_user A #CARD# NULL NULL BTREE def mysql servers 0 mysql PRIMARY 1 Server_name A #CARD# NULL NULL BTREE def mysql tables_priv 1 mysql Grantor 1 Grantor A #CARD# NULL NULL BTREE def mysql tables_priv 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE diff --git a/mysql-test/suite/funcs_1/r/is_table_constraints.result b/mysql-test/suite/funcs_1/r/is_table_constraints.result index d4d2c38c9ba..559a1f1f9f5 100644 --- a/mysql-test/suite/funcs_1/r/is_table_constraints.result +++ b/mysql-test/suite/funcs_1/r/is_table_constraints.result @@ -73,7 +73,7 @@ def mysql PRIMARY mysql ndb_binlog_index def mysql PRIMARY mysql plugin def mysql PRIMARY mysql proc def mysql PRIMARY mysql procs_priv -def mysql PRIMARY mysql proxy_priv +def mysql PRIMARY mysql proxies_priv def mysql PRIMARY mysql servers def mysql PRIMARY mysql tables_priv def mysql PRIMARY mysql time_zone diff --git a/mysql-test/suite/funcs_1/r/is_table_constraints_mysql.result b/mysql-test/suite/funcs_1/r/is_table_constraints_mysql.result index 38e9c9034c9..bca333b6387 100644 --- a/mysql-test/suite/funcs_1/r/is_table_constraints_mysql.result +++ b/mysql-test/suite/funcs_1/r/is_table_constraints_mysql.result @@ -23,7 +23,7 @@ def mysql PRIMARY mysql ndb_binlog_index PRIMARY KEY def mysql PRIMARY mysql plugin PRIMARY KEY def mysql PRIMARY mysql proc PRIMARY KEY def mysql PRIMARY mysql procs_priv PRIMARY KEY -def mysql PRIMARY mysql proxy_priv PRIMARY KEY +def mysql PRIMARY mysql proxies_priv PRIMARY KEY def mysql PRIMARY mysql servers PRIMARY KEY def mysql PRIMARY mysql tables_priv PRIMARY KEY def mysql PRIMARY mysql time_zone PRIMARY KEY diff --git a/mysql-test/suite/funcs_1/r/is_tables_mysql.result b/mysql-test/suite/funcs_1/r/is_tables_mysql.result index ae512327807..7db87c4215a 100644 --- a/mysql-test/suite/funcs_1/r/is_tables_mysql.result +++ b/mysql-test/suite/funcs_1/r/is_tables_mysql.result @@ -336,7 +336,7 @@ user_comment Procedure privileges Separator ----------------------------------------------------- TABLE_CATALOG def TABLE_SCHEMA mysql -TABLE_NAME proxy_priv +TABLE_NAME proxies_priv TABLE_TYPE BASE TABLE ENGINE MyISAM VERSION 10 diff --git a/mysql-test/t/plugin_auth.test b/mysql-test/t/plugin_auth.test index 77dcd7add73..ebbaf389632 100644 --- a/mysql-test/t/plugin_auth.test +++ b/mysql-test/t/plugin_auth.test @@ -16,6 +16,11 @@ connect(plug_con,localhost,plug,plug_dest); --enable_query_log GRANT PROXY ON plug_dest TO plug; +--echo test proxies_priv columns +--replace_column 7 xx +SELECT * FROM mysql.proxies_priv; +--echo test mysql.proxies_priv; +SHOW CREATE TABLE mysql.proxies_priv; connect(plug_con,localhost,plug,plug_dest); @@ -226,7 +231,7 @@ CREATE USER test_drop@localhost; GRANT PROXY ON future_user TO test_drop@localhost; SHOW GRANTS FOR test_drop@localhost; DROP USER test_drop@localhost; -SELECT * FROM mysql.proxy_priv WHERE Host = 'test_drop' AND User = 'localhost'; +SELECT * FROM mysql.proxies_priv WHERE Host = 'test_drop' AND User = 'localhost'; DROP USER proxy_admin; diff --git a/mysql-test/t/system_mysql_db_fix40123.test b/mysql-test/t/system_mysql_db_fix40123.test index d069271a02e..8c2060d76ba 100644 --- a/mysql-test/t/system_mysql_db_fix40123.test +++ b/mysql-test/t/system_mysql_db_fix40123.test @@ -72,7 +72,7 @@ CREATE TABLE time_zone_leap_second ( Transition_time bigint signed NOT NULL, -- disable_query_log # Drop all tables created by this test -DROP TABLE db, host, user, func, plugin, tables_priv, columns_priv, procs_priv, servers, help_category, help_keyword, help_relation, help_topic, proc, time_zone, time_zone_leap_second, time_zone_name, time_zone_transition, time_zone_transition_type, general_log, slow_log, event, ndb_binlog_index, proxy_priv; +DROP TABLE db, host, user, func, plugin, tables_priv, columns_priv, procs_priv, servers, help_category, help_keyword, help_relation, help_topic, proc, time_zone, time_zone_leap_second, time_zone_name, time_zone_transition, time_zone_transition_type, general_log, slow_log, event, ndb_binlog_index, proxies_priv; -- enable_query_log diff --git a/mysql-test/t/system_mysql_db_fix50030.test b/mysql-test/t/system_mysql_db_fix50030.test index 53166919f1c..7d55a091b6d 100644 --- a/mysql-test/t/system_mysql_db_fix50030.test +++ b/mysql-test/t/system_mysql_db_fix50030.test @@ -78,7 +78,7 @@ INSERT INTO servers VALUES ('test','localhost','test','root','', 0,'','mysql','r -- disable_query_log # Drop all tables created by this test -DROP TABLE db, host, user, func, plugin, tables_priv, columns_priv, procs_priv, servers, help_category, help_keyword, help_relation, help_topic, proc, time_zone, time_zone_leap_second, time_zone_name, time_zone_transition, time_zone_transition_type, general_log, slow_log, event, ndb_binlog_index, proxy_priv; +DROP TABLE db, host, user, func, plugin, tables_priv, columns_priv, procs_priv, servers, help_category, help_keyword, help_relation, help_topic, proc, time_zone, time_zone_leap_second, time_zone_name, time_zone_transition, time_zone_transition_type, general_log, slow_log, event, ndb_binlog_index, proxies_priv; -- enable_query_log diff --git a/mysql-test/t/system_mysql_db_fix50117.test b/mysql-test/t/system_mysql_db_fix50117.test index 872829ae79d..260400b9c8a 100644 --- a/mysql-test/t/system_mysql_db_fix50117.test +++ b/mysql-test/t/system_mysql_db_fix50117.test @@ -97,7 +97,7 @@ CREATE TABLE IF NOT EXISTS ndb_binlog_index (Position BIGINT UNSIGNED NOT NULL, -- disable_query_log # Drop all tables created by this test -DROP TABLE db, host, user, func, plugin, tables_priv, columns_priv, procs_priv, servers, help_category, help_keyword, help_relation, help_topic, proc, time_zone, time_zone_leap_second, time_zone_name, time_zone_transition, time_zone_transition_type, general_log, slow_log, event, ndb_binlog_index, proxy_priv; +DROP TABLE db, host, user, func, plugin, tables_priv, columns_priv, procs_priv, servers, help_category, help_keyword, help_relation, help_topic, proc, time_zone, time_zone_leap_second, time_zone_name, time_zone_transition, time_zone_transition_type, general_log, slow_log, event, ndb_binlog_index, proxies_priv; -- enable_query_log diff --git a/scripts/mysql_system_tables.sql b/scripts/mysql_system_tables.sql index d5dd20542ff..02c5389f8d3 100644 --- a/scripts/mysql_system_tables.sql +++ b/scripts/mysql_system_tables.sql @@ -478,7 +478,7 @@ PREPARE stmt FROM @str; EXECUTE stmt; DROP PREPARE stmt; -CREATE TABLE IF NOT EXISTS proxy_priv (Host char(60) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Proxied_Host char(16) binary DEFAULT '' NOT NULL, Proxied_User char(60) binary DEFAULT '' NOT NULL, With_Grant BOOL DEFAULT 0 NOT NULL, PRIMARY KEY Host (Host,User,Proxied_Host,Proxied_User) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='User proxy privileges'; +CREATE TABLE IF NOT EXISTS proxies_priv (Host char(60) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Proxied_host char(60) binary DEFAULT '' NOT NULL, Proxied_user char(16) binary DEFAULT '' NOT NULL, With_grant BOOL DEFAULT 0 NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Timestamp timestamp, PRIMARY KEY Host (Host,User,Proxied_host,Proxied_user), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='User proxy privileges'; --- Remember for later if proxy_priv table already existed -set @had_proxy_priv_table= @@warning_count != 0; +-- Remember for later if proxies_priv table already existed +set @had_proxies_priv_table= @@warning_count != 0; diff --git a/scripts/mysql_system_tables_data.sql b/scripts/mysql_system_tables_data.sql index 293baa46523..bc5ffae2063 100644 --- a/scripts/mysql_system_tables_data.sql +++ b/scripts/mysql_system_tables_data.sql @@ -30,8 +30,8 @@ INSERT INTO tmp_user (host,user) SELECT @current_hostname,'' FROM dual WHERE LOW INSERT INTO user SELECT * FROM tmp_user WHERE @had_user_table=0; DROP TABLE tmp_user; -CREATE TEMPORARY TABLE tmp_proxy_priv LIKE proxy_priv; -INSERT INTO tmp_proxy_priv VALUES ('localhost', 'root', '', '', TRUE); -REPLACE INTO tmp_proxy_priv SELECT @current_hostname, 'root', '', '', TRUE FROM DUAL WHERE LOWER (@current_hostname) != 'localhost'; -INSERT INTO proxy_priv SELECT * FROM tmp_proxy_priv WHERE @had_proxy_priv_table=0; -DROP TABLE tmp_proxy_priv; +CREATE TEMPORARY TABLE tmp_proxies_priv LIKE proxies_priv; +INSERT INTO tmp_proxies_priv VALUES ('localhost', 'root', '', '', TRUE, '', now()); +REPLACE INTO tmp_proxies_priv SELECT @current_hostname, 'root', '', '', TRUE, '', now() FROM DUAL WHERE LOWER (@current_hostname) != 'localhost'; +INSERT INTO proxies_priv SELECT * FROM tmp_proxies_priv WHERE @had_proxies_priv_table=0; +DROP TABLE tmp_proxies_priv; diff --git a/scripts/mysql_system_tables_fix.sql b/scripts/mysql_system_tables_fix.sql index ceb910676ab..b51e4c6f549 100644 --- a/scripts/mysql_system_tables_fix.sql +++ b/scripts/mysql_system_tables_fix.sql @@ -643,7 +643,7 @@ drop procedure mysql.die; ALTER TABLE user ADD plugin char(60) DEFAULT '' NOT NULL, ADD authentication_string TEXT NOT NULL; ALTER TABLE user MODIFY plugin char(60) DEFAULT '' NOT NULL; -CREATE TABLE IF NOT EXISTS proxy_priv (Host char(60) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Proxied_User char(60) binary DEFAULT '' NOT NULL, Proxied_Host char(16) binary DEFAULT '' NOT NULL, With_Grant BOOL DEFAULT 0 NOT NULL, PRIMARY KEY Host (Host,User,Proxied_Host,Proxied_User) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Users and global privileges'; +CREATE TABLE IF NOT EXISTS proxies_priv (Host char(60) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Proxied_host char(60) binary DEFAULT '' NOT NULL, Proxied_user char(16) binary DEFAULT '' NOT NULL, With_grant BOOL DEFAULT 0 NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Timestamp timestamp, PRIMARY KEY Host (Host,User,Proxied_host,Proxied_user), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='User proxy privileges'; # Activate the new, possible modified privilege tables # This should not be needed, but gives us some extra testing that the above diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index c741a50a1db..8ef17cec6a8 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -268,11 +268,13 @@ class ACL_PROXY_USER :public ACL_ACCESS bool with_grant; typedef enum { - MYSQL_PROXY_PRIV_HOST, - MYSQL_PROXY_PRIV_USER, - MYSQL_PROXY_PRIV_PROXIED_HOST, - MYSQL_PROXY_PRIV_PROXIED_USER, - MYSQL_PROXY_PRIV_WITH_GRANT } old_acl_proxy_users; + MYSQL_PROXIES_PRIV_HOST, + MYSQL_PROXIES_PRIV_USER, + MYSQL_PROXIES_PRIV_PROXIED_HOST, + MYSQL_PROXIES_PRIV_PROXIED_USER, + MYSQL_PROXIES_PRIV_WITH_GRANT, + MYSQL_PROXIES_PRIV_GRANTOR, + MYSQL_PROXIES_PRIV_TIMESTAMP } old_acl_proxy_users; public: ACL_PROXY_USER () {}; @@ -308,11 +310,11 @@ public: void init(TABLE *table, MEM_ROOT *mem) { - init (get_field(mem, table->field[MYSQL_PROXY_PRIV_HOST]), - get_field(mem, table->field[MYSQL_PROXY_PRIV_USER]), - get_field(mem, table->field[MYSQL_PROXY_PRIV_PROXIED_HOST]), - get_field(mem, table->field[MYSQL_PROXY_PRIV_PROXIED_USER]), - table->field[MYSQL_PROXY_PRIV_WITH_GRANT]->val_int() != 0); + init (get_field(mem, table->field[MYSQL_PROXIES_PRIV_HOST]), + get_field(mem, table->field[MYSQL_PROXIES_PRIV_USER]), + get_field(mem, table->field[MYSQL_PROXIES_PRIV_PROXIED_HOST]), + get_field(mem, table->field[MYSQL_PROXIES_PRIV_PROXIED_USER]), + table->field[MYSQL_PROXIES_PRIV_WITH_GRANT]->val_int() != 0); } bool get_with_grant() { return with_grant; } @@ -337,7 +339,7 @@ public: (hostname_requires_resolving(host.hostname) || hostname_requires_resolving(proxied_host.hostname))) { - sql_print_warning("'proxy_priv' entry '%s@%s %s@%s' " + sql_print_warning("'proxes_priv' entry '%s@%s %s@%s' " "ignored in --skip-name-resolve mode.", proxied_user ? proxied_user : "", proxied_host.hostname ? proxied_host.hostname : "", @@ -452,19 +454,19 @@ public: user->str ? user->str : "", proxied_host->str ? proxied_host->str : "", proxied_user->str ? proxied_user->str : "")); - if (table->field[MYSQL_PROXY_PRIV_HOST]->store(host->str, + if (table->field[MYSQL_PROXIES_PRIV_HOST]->store(host->str, host->length, system_charset_info)) DBUG_RETURN(TRUE); - if (table->field[MYSQL_PROXY_PRIV_USER]->store(user->str, + if (table->field[MYSQL_PROXIES_PRIV_USER]->store(user->str, user->length, system_charset_info)) DBUG_RETURN(TRUE); - if (table->field[MYSQL_PROXY_PRIV_PROXIED_HOST]->store(proxied_host->str, + if (table->field[MYSQL_PROXIES_PRIV_PROXIED_HOST]->store(proxied_host->str, proxied_host->length, system_charset_info)) DBUG_RETURN(TRUE); - if (table->field[MYSQL_PROXY_PRIV_PROXIED_USER]->store(proxied_user->str, + if (table->field[MYSQL_PROXIES_PRIV_PROXIED_USER]->store(proxied_user->str, proxied_user->length, system_charset_info)) DBUG_RETURN(TRUE); @@ -472,20 +474,25 @@ public: DBUG_RETURN(FALSE); } - static int store_data_record(TABLE *table, - const LEX_STRING *host, + static int store_data_record(TABLE *table, + const LEX_STRING *host, const LEX_STRING *user, - const LEX_STRING *proxied_host, + const LEX_STRING *proxied_host, const LEX_STRING *proxied_user, - bool with_grant) + bool with_grant, + const char *grantor) { - DBUG_ENTER ("ACL_PROXY_USER::store_pk"); - if (store_pk (table, host, user, proxied_host, proxied_user)) + DBUG_ENTER("ACL_PROXY_USER::store_pk"); + if (store_pk(table, host, user, proxied_host, proxied_user)) DBUG_RETURN(TRUE); - DBUG_PRINT ("info", ("with_grant=%s", with_grant ? "TRUE" : "FALSE")); - if (table->field[MYSQL_PROXY_PRIV_WITH_GRANT]->store(with_grant ? 1 : 0, + DBUG_PRINT("info", ("with_grant=%s", with_grant ? "TRUE" : "FALSE")); + if (table->field[MYSQL_PROXIES_PRIV_WITH_GRANT]->store(with_grant ? 1 : 0, TRUE)) DBUG_RETURN(TRUE); + if (table->field[MYSQL_PROXIES_PRIV_GRANTOR]->store(grantor, + strlen(grantor), + system_charset_info)) + DBUG_RETURN(TRUE); DBUG_RETURN(FALSE); } @@ -1113,8 +1120,8 @@ my_bool acl_reload(THD *thd) tables[2].init_one_table(C_STRING_WITH_LEN("mysql"), C_STRING_WITH_LEN("db"), "db", TL_READ); tables[3].init_one_table(C_STRING_WITH_LEN("mysql"), - C_STRING_WITH_LEN("proxy_priv"), - "proxy_priv", TL_READ); + C_STRING_WITH_LEN("proxies_priv"), + "proxies_priv", TL_READ); tables[0].next_local= tables[0].next_global= tables + 1; tables[1].next_local= tables[1].next_global= tables + 2; tables[2].next_local= tables[2].next_global= tables + 3; @@ -2608,7 +2615,7 @@ acl_insert_proxy_user(ACL_PROXY_USER *new_value) static int -replace_proxy_priv_table(THD *thd, TABLE *table, const LEX_USER *user, +replace_proxies_priv_table(THD *thd, TABLE *table, const LEX_USER *user, const LEX_USER *proxied_user, bool with_grant_arg, bool revoke_grant) { @@ -2616,8 +2623,9 @@ replace_proxy_priv_table(THD *thd, TABLE *table, const LEX_USER *user, int error; uchar user_key[MAX_KEY_LENGTH]; ACL_PROXY_USER new_grant; + char grantor[USER_HOST_BUFF_SIZE]; - DBUG_ENTER("replace_proxy_priv_table"); + DBUG_ENTER("replace_proxies_priv_table"); if (!initialized) { @@ -2639,6 +2647,8 @@ replace_proxy_priv_table(THD *thd, TABLE *table, const LEX_USER *user, key_copy(user_key, table->record[0], table->key_info, table->key_info->key_length); + get_grantor(thd, grantor); + table->file->ha_index_init(0, 1); if (table->file->index_read_map(table->record[0], user_key, HA_WHOLE_KEY, @@ -2655,7 +2665,8 @@ replace_proxy_priv_table(THD *thd, TABLE *table, const LEX_USER *user, ACL_PROXY_USER::store_data_record(table, &user->host, &user->user, &proxied_user->host, &proxied_user->user, - with_grant_arg); + with_grant_arg, + grantor); } else { @@ -2712,7 +2723,7 @@ table_error: table->file->print_error(error, MYF(0)); /* purecov: inspected */ abort: - DBUG_PRINT("info", ("aborting replace_proxy_priv_table")); + DBUG_PRINT("info", ("aborting replace_proxies_priv_table")); table->file->ha_index_end(); DBUG_RETURN(-1); } @@ -3962,14 +3973,14 @@ bool mysql_grant(THD *thd, const char *db, List &list, proxied_user= str_list++; } - /* open the mysql.user and mysql.db or mysql.proxy_priv tables */ + /* open the mysql.user and mysql.db or mysql.proxies_priv tables */ tables[0].init_one_table(C_STRING_WITH_LEN("mysql"), C_STRING_WITH_LEN("user"), "user", TL_WRITE); if (is_proxy) tables[1].init_one_table(C_STRING_WITH_LEN("mysql"), - C_STRING_WITH_LEN("proxy_priv"), - "proxy_priv", + C_STRING_WITH_LEN("proxies_priv"), + "proxies_priv", TL_WRITE); else tables[1].init_one_table(C_STRING_WITH_LEN("mysql"), @@ -4063,7 +4074,7 @@ bool mysql_grant(THD *thd, const char *db, List &list, } else if (is_proxy) { - if (replace_proxy_priv_table (thd, tables[1].table, Str, proxied_user, + if (replace_proxies_priv_table (thd, tables[1].table, Str, proxied_user, rights & GRANT_ACL ? TRUE : FALSE, revoke_grant)) result= -1; @@ -5690,8 +5701,8 @@ int open_grant_tables(THD *thd, TABLE_LIST *tables) C_STRING_WITH_LEN("procs_priv"), "procs_priv", TL_WRITE); (tables+5)->init_one_table(C_STRING_WITH_LEN("mysql"), - C_STRING_WITH_LEN("proxy_priv"), - "proxy_priv", TL_WRITE); + C_STRING_WITH_LEN("proxies_priv"), + "proxies_priv", TL_WRITE); tables->next_local= tables->next_global= tables + 1; (tables+1)->next_local= (tables+1)->next_global= tables + 2; (tables+2)->next_local= (tables+2)->next_global= tables + 3; @@ -6283,7 +6294,7 @@ static int handle_grant_data(TABLE_LIST *tables, bool drop, } } - /* Handle proxy_priv table. */ + /* Handle proxies_priv table. */ if ((found= handle_grant_table(tables, 5, drop, user_from, user_to)) < 0) { /* Handle of table failed, don't touch the in-memory array. */ @@ -6291,7 +6302,7 @@ static int handle_grant_data(TABLE_LIST *tables, bool drop, } else { - /* Handle proxy_priv array. */ + /* Handle proxies_priv array. */ if ((handle_grant_struct(5, drop, user_from, user_to) && !result) || found) result= 1; /* At least one record/element found. */ From 49cbbf6ea4d9dbcd75292967a67173d21e61fc25 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 2 Nov 2010 18:57:20 +0200 Subject: [PATCH 154/304] Fix Bug#53046 dict_update_statistics_low can still be run concurrently on same table Replace the array of mutexes that used to protect dict_index_t::stat_n_diff_key_vals[] with an array of rw locks that protects all the stats related members in dict_table_t and all of its indexes. Approved by: Jimmy (rb://503) --- .../innodb_plugin/r/innodb_bug53046.result | 27 ++++ .../innodb_plugin/t/innodb_bug53046.test | 48 ++++++ storage/innodb_plugin/btr/btr0cur.c | 4 - storage/innodb_plugin/dict/dict0dict.c | 140 ++++++++++++------ storage/innodb_plugin/dict/dict0load.c | 5 +- storage/innodb_plugin/handler/ha_innodb.cc | 24 ++- storage/innodb_plugin/include/dict0dict.h | 34 +++-- storage/innodb_plugin/row/row0mysql.c | 6 +- 8 files changed, 215 insertions(+), 73 deletions(-) create mode 100644 mysql-test/suite/innodb_plugin/r/innodb_bug53046.result create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_bug53046.test diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug53046.result b/mysql-test/suite/innodb_plugin/r/innodb_bug53046.result new file mode 100644 index 00000000000..69be6c4e0a7 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_bug53046.result @@ -0,0 +1,27 @@ +CREATE TABLE bug53046_1 (c1 INT PRIMARY KEY) ENGINE=INNODB; +CREATE TABLE bug53046_2 (c2 INT PRIMARY KEY, +FOREIGN KEY (c2) REFERENCES bug53046_1(c1) +ON UPDATE CASCADE ON DELETE CASCADE) ENGINE=INNODB; +INSERT INTO bug53046_1 VALUES (1); +INSERT INTO bug53046_1 SELECT c1+(SELECT MAX(c1) FROM bug53046_1) +FROM bug53046_1; +INSERT INTO bug53046_1 SELECT c1+(SELECT MAX(c1) FROM bug53046_1) +FROM bug53046_1; +INSERT INTO bug53046_1 SELECT c1+(SELECT MAX(c1) FROM bug53046_1) +FROM bug53046_1; +INSERT INTO bug53046_1 SELECT c1+(SELECT MAX(c1) FROM bug53046_1) +FROM bug53046_1; +INSERT INTO bug53046_1 SELECT c1+(SELECT MAX(c1) FROM bug53046_1) +FROM bug53046_1; +INSERT INTO bug53046_2 VALUES (1), (2); +ANALYZE TABLE bug53046_1; +Table Op Msg_type Msg_text +test.bug53046_1 analyze status OK +SHOW TABLE STATUS LIKE 'bug53046_1'; +UPDATE bug53046_1 SET c1 = c1 - 1; +DELETE FROM bug53046_1; +INSERT INTO bug53046_1 VALUES (1); +INSERT INTO bug53046_2 VALUES (1); +TRUNCATE TABLE bug53046_2; +DROP TABLE bug53046_2; +DROP TABLE bug53046_1; diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug53046.test b/mysql-test/suite/innodb_plugin/t/innodb_bug53046.test new file mode 100644 index 00000000000..7d9422fe487 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug53046.test @@ -0,0 +1,48 @@ +# +# http://bugs.mysql.com/53046 +# dict_update_statistics_low can still be run concurrently on same table +# +# This is a symbolic test, it would not fail if the bug is present. +# Rather those SQL commands have been used during manual testing under +# UNIV_DEBUG & UNIV_SYNC_DEBUG to test all changed codepaths for locking +# correctness. +# + +-- source include/have_innodb_plugin.inc + +CREATE TABLE bug53046_1 (c1 INT PRIMARY KEY) ENGINE=INNODB; +CREATE TABLE bug53046_2 (c2 INT PRIMARY KEY, + FOREIGN KEY (c2) REFERENCES bug53046_1(c1) + ON UPDATE CASCADE ON DELETE CASCADE) ENGINE=INNODB; + +INSERT INTO bug53046_1 VALUES (1); +let $i = 5; +while ($i) { + eval INSERT INTO bug53046_1 SELECT c1+(SELECT MAX(c1) FROM bug53046_1) + FROM bug53046_1; + dec $i; +} + +INSERT INTO bug53046_2 VALUES (1), (2); + +# CREATE TABLE innodb_table_monitor (a int) ENGINE=INNODB; +# wait more than 1 minute and observe the mysqld output +# DROP TABLE innodb_table_monitor; + +ANALYZE TABLE bug53046_1; + +# this prints create time and other nondeterministic data +-- disable_result_log +SHOW TABLE STATUS LIKE 'bug53046_1'; +-- enable_result_log + +UPDATE bug53046_1 SET c1 = c1 - 1; + +DELETE FROM bug53046_1; + +INSERT INTO bug53046_1 VALUES (1); +INSERT INTO bug53046_2 VALUES (1); +TRUNCATE TABLE bug53046_2; + +DROP TABLE bug53046_2; +DROP TABLE bug53046_1; diff --git a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0cur.c index 79fe328a631..cbad05345e6 100644 --- a/storage/innodb_plugin/btr/btr0cur.c +++ b/storage/innodb_plugin/btr/btr0cur.c @@ -3355,8 +3355,6 @@ btr_estimate_number_of_different_key_vals( also the pages used for external storage of fields (those pages are included in index->stat_n_leaf_pages) */ - dict_index_stat_mutex_enter(index); - for (j = 0; j <= n_cols; j++) { index->stat_n_diff_key_vals[j] = ((n_diff[j] @@ -3386,8 +3384,6 @@ btr_estimate_number_of_different_key_vals( index->stat_n_diff_key_vals[j] += add_on; } - dict_index_stat_mutex_exit(index); - mem_free(n_diff); if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); diff --git a/storage/innodb_plugin/dict/dict0dict.c b/storage/innodb_plugin/dict/dict0dict.c index a3575c283cd..2adae4afffb 100644 --- a/storage/innodb_plugin/dict/dict0dict.c +++ b/storage/innodb_plugin/dict/dict0dict.c @@ -80,9 +80,18 @@ UNIV_INTERN rw_lock_t dict_operation_lock; /** Identifies generated InnoDB foreign key names */ static char dict_ibfk[] = "_ibfk_"; -/** array of mutexes protecting dict_index_t::stat_n_diff_key_vals[] */ -#define DICT_INDEX_STAT_MUTEX_SIZE 32 -static mutex_t dict_index_stat_mutex[DICT_INDEX_STAT_MUTEX_SIZE]; +/** array of rw locks protecting +dict_table_t::stat_initialized +dict_table_t::stat_n_rows (*) +dict_table_t::stat_clustered_index_size +dict_table_t::stat_sum_of_other_index_sizes +dict_table_t::stat_modified_counter (*) +dict_table_t::indexes*::stat_n_diff_key_vals[] +dict_table_t::indexes*::stat_index_size +dict_table_t::indexes*::stat_n_leaf_pages +(*) those are not always protected for performance reasons */ +#define DICT_TABLE_STATS_LATCHES_SIZE 64 +static rw_lock_t dict_table_stats_latches[DICT_TABLE_STATS_LATCHES_SIZE]; /*******************************************************************//** Tries to find column names for the index and sets the col field of the @@ -243,43 +252,65 @@ dict_mutex_exit_for_mysql(void) mutex_exit(&(dict_sys->mutex)); } -/** Get the mutex that protects index->stat_n_diff_key_vals[] */ -#define GET_INDEX_STAT_MUTEX(index) \ - (&dict_index_stat_mutex[ut_fold_dulint(index->id) \ - % DICT_INDEX_STAT_MUTEX_SIZE]) +/** Get the latch that protects the stats of a given table */ +#define GET_TABLE_STATS_LATCH(table) \ + (&dict_table_stats_latches[ut_fold_dulint(table->id) \ + % DICT_TABLE_STATS_LATCHES_SIZE]) /**********************************************************************//** -Lock the appropriate mutex to protect index->stat_n_diff_key_vals[]. -index->id is used to pick the right mutex and it should not change -before dict_index_stat_mutex_exit() is called on this index. */ +Lock the appropriate latch to protect a given table's statistics. +table->id is used to pick the corresponding latch from a global array of +latches. */ UNIV_INTERN void -dict_index_stat_mutex_enter( -/*========================*/ - const dict_index_t* index) /*!< in: index */ +dict_table_stats_lock( +/*==================*/ + const dict_table_t* table, /*!< in: table */ + ulint latch_mode) /*!< in: RW_S_LATCH or + RW_X_LATCH */ { - ut_ad(index != NULL); - ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); - ut_ad(index->cached); - ut_ad(!index->to_be_dropped); + ut_ad(table != NULL); + ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); - mutex_enter(GET_INDEX_STAT_MUTEX(index)); + switch (latch_mode) { + case RW_S_LATCH: + rw_lock_s_lock(GET_TABLE_STATS_LATCH(table)); + break; + case RW_X_LATCH: + rw_lock_x_lock(GET_TABLE_STATS_LATCH(table)); + break; + case RW_NO_LATCH: + /* fall through */ + default: + ut_error; + } } /**********************************************************************//** -Unlock the appropriate mutex that protects index->stat_n_diff_key_vals[]. */ +Unlock the latch that has been locked by dict_table_stats_lock() */ UNIV_INTERN void -dict_index_stat_mutex_exit( -/*=======================*/ - const dict_index_t* index) /*!< in: index */ +dict_table_stats_unlock( +/*====================*/ + const dict_table_t* table, /*!< in: table */ + ulint latch_mode) /*!< in: RW_S_LATCH or + RW_X_LATCH */ { - ut_ad(index != NULL); - ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); - ut_ad(index->cached); - ut_ad(!index->to_be_dropped); + ut_ad(table != NULL); + ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); - mutex_exit(GET_INDEX_STAT_MUTEX(index)); + switch (latch_mode) { + case RW_S_LATCH: + rw_lock_s_unlock(GET_TABLE_STATS_LATCH(table)); + break; + case RW_X_LATCH: + rw_lock_x_unlock(GET_TABLE_STATS_LATCH(table)); + break; + case RW_NO_LATCH: + /* fall through */ + default: + ut_error; + } } /********************************************************************//** @@ -668,8 +699,8 @@ dict_init(void) mutex_create(&dict_foreign_err_mutex, SYNC_ANY_LATCH); - for (i = 0; i < DICT_INDEX_STAT_MUTEX_SIZE; i++) { - mutex_create(&dict_index_stat_mutex[i], SYNC_INDEX_TREE); + for (i = 0; i < DICT_TABLE_STATS_LATCHES_SIZE; i++) { + rw_lock_create(&dict_table_stats_latches[i], SYNC_INDEX_TREE); } } @@ -700,12 +731,11 @@ dict_table_get( mutex_exit(&(dict_sys->mutex)); if (table != NULL) { - if (!table->stat_initialized) { - /* If table->ibd_file_missing == TRUE, this will - print an error message and return without doing - anything. */ - dict_update_statistics(table); - } + /* If table->ibd_file_missing == TRUE, this will + print an error message and return without doing + anything. */ + dict_update_statistics(table, TRUE /* only update stats + if they have not been initialized */); } return(table); @@ -4186,6 +4216,10 @@ void dict_update_statistics_low( /*=======================*/ dict_table_t* table, /*!< in/out: table */ + ibool only_calc_if_missing_stats,/*!< in: only + update/recalc the stats if they have + not been initialized yet, otherwise + do nothing */ ibool has_dict_mutex __attribute__((unused))) /*!< in: TRUE if the caller has the dictionary mutex */ @@ -4216,6 +4250,12 @@ dict_update_statistics_low( return; } + dict_table_stats_lock(table, RW_X_LATCH); + + if (only_calc_if_missing_stats && table->stat_initialized) { + dict_table_stats_unlock(table, RW_X_LATCH); + return; + } do { if (UNIV_LIKELY @@ -4261,13 +4301,9 @@ dict_update_statistics_low( index = dict_table_get_first_index(table); - dict_index_stat_mutex_enter(index); - table->stat_n_rows = index->stat_n_diff_key_vals[ dict_index_get_n_unique(index)]; - dict_index_stat_mutex_exit(index); - table->stat_clustered_index_size = index->stat_index_size; table->stat_sum_of_other_index_sizes = sum_of_index_sizes @@ -4276,6 +4312,8 @@ dict_update_statistics_low( table->stat_initialized = TRUE; table->stat_modified_counter = 0; + + dict_table_stats_unlock(table, RW_X_LATCH); } /*********************************************************************//** @@ -4285,9 +4323,13 @@ UNIV_INTERN void dict_update_statistics( /*===================*/ - dict_table_t* table) /*!< in/out: table */ + dict_table_t* table, /*!< in/out: table */ + ibool only_calc_if_missing_stats)/*!< in: only + update/recalc the stats if they have + not been initialized yet, otherwise + do nothing */ { - dict_update_statistics_low(table, FALSE); + dict_update_statistics_low(table, only_calc_if_missing_stats, FALSE); } /**********************************************************************//** @@ -4367,7 +4409,11 @@ dict_table_print_low( ut_ad(mutex_own(&(dict_sys->mutex))); - dict_update_statistics_low(table, TRUE); + dict_update_statistics_low(table, + FALSE /* update even if initialized */, + TRUE /* we have the dict mutex */); + + dict_table_stats_lock(table, RW_S_LATCH); fprintf(stderr, "--------------------------------------\n" @@ -4396,6 +4442,8 @@ dict_table_print_low( index = UT_LIST_GET_NEXT(indexes, index); } + dict_table_stats_unlock(table, RW_S_LATCH); + foreign = UT_LIST_GET_FIRST(table->foreign_list); while (foreign != NULL) { @@ -4444,8 +4492,6 @@ dict_index_print_low( ut_ad(mutex_own(&(dict_sys->mutex))); - dict_index_stat_mutex_enter(index); - if (index->n_user_defined_cols > 0) { n_vals = index->stat_n_diff_key_vals[ index->n_user_defined_cols]; @@ -4453,8 +4499,6 @@ dict_index_print_low( n_vals = index->stat_n_diff_key_vals[1]; } - dict_index_stat_mutex_exit(index); - fprintf(stderr, " INDEX: name %s, id %lu %lu, fields %lu/%lu," " uniq %lu, type %lu\n" @@ -4943,8 +4987,8 @@ dict_close(void) mem_free(dict_sys); dict_sys = NULL; - for (i = 0; i < DICT_INDEX_STAT_MUTEX_SIZE; i++) { - mutex_free(&dict_index_stat_mutex[i]); + for (i = 0; i < DICT_TABLE_STATS_LATCHES_SIZE; i++) { + rw_lock_free(&dict_table_stats_latches[i]); } } #endif /* !UNIV_HOTBACKUP */ diff --git a/storage/innodb_plugin/dict/dict0load.c b/storage/innodb_plugin/dict/dict0load.c index 3dcee46b92c..3baa12b4235 100644 --- a/storage/innodb_plugin/dict/dict0load.c +++ b/storage/innodb_plugin/dict/dict0load.c @@ -222,7 +222,10 @@ loop: is no index */ if (dict_table_get_first_index(table)) { - dict_update_statistics_low(table, TRUE); + dict_update_statistics_low( + table, + FALSE /* update even if initialized */, + TRUE /* we have the dict mutex */); } dict_table_print_low(table); diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index 99d4f294f81..60ca1c0bb03 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -7343,6 +7343,7 @@ ha_innobase::estimate_rows_upper_bound(void) dict_index_t* index; ulonglong estimate; ulonglong local_data_file_length; + ulint stat_n_leaf_pages; DBUG_ENTER("estimate_rows_upper_bound"); @@ -7362,10 +7363,12 @@ ha_innobase::estimate_rows_upper_bound(void) index = dict_table_get_first_index(prebuilt->table); - ut_a(index->stat_n_leaf_pages > 0); + stat_n_leaf_pages = index->stat_n_leaf_pages; + + ut_a(stat_n_leaf_pages > 0); local_data_file_length = - ((ulonglong) index->stat_n_leaf_pages) * UNIV_PAGE_SIZE; + ((ulonglong) stat_n_leaf_pages) * UNIV_PAGE_SIZE; /* Calculate a minimum length for a clustered index record and from @@ -7564,7 +7567,9 @@ ha_innobase::info_low( prebuilt->trx->op_info = "updating table statistics"; - dict_update_statistics(ib_table); + dict_update_statistics(ib_table, + FALSE /* update even if stats + are initialized */); prebuilt->trx->op_info = "returning various info to MySQL"; } @@ -7583,6 +7588,9 @@ ha_innobase::info_low( } if (flag & HA_STATUS_VARIABLE) { + + dict_table_stats_lock(ib_table, RW_S_LATCH); + n_rows = ib_table->stat_n_rows; /* Because we do not protect stat_n_rows by any mutex in a @@ -7632,6 +7640,8 @@ ha_innobase::info_low( ib_table->stat_sum_of_other_index_sizes) * UNIV_PAGE_SIZE; + dict_table_stats_unlock(ib_table, RW_S_LATCH); + /* Since fsp_get_available_space_in_free_extents() is acquiring latches inside InnoDB, we do not call it if we are asked by MySQL to avoid locking. Another reason to @@ -7708,6 +7718,8 @@ ha_innobase::info_low( table->s->keys); } + dict_table_stats_lock(ib_table, RW_S_LATCH); + for (i = 0; i < table->s->keys; i++) { ulong j; /* We could get index quickly through internal @@ -7745,8 +7757,6 @@ ha_innobase::info_low( break; } - dict_index_stat_mutex_enter(index); - if (index->stat_n_diff_key_vals[j + 1] == 0) { rec_per_key = stats.records; @@ -7755,8 +7765,6 @@ ha_innobase::info_low( index->stat_n_diff_key_vals[j + 1]); } - dict_index_stat_mutex_exit(index); - /* Since MySQL seems to favor table scans too much over index searches, we pretend index selectivity is 2 times better than @@ -7773,6 +7781,8 @@ ha_innobase::info_low( (ulong) rec_per_key; } } + + dict_table_stats_unlock(ib_table, RW_S_LATCH); } if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) { diff --git a/storage/innodb_plugin/include/dict0dict.h b/storage/innodb_plugin/include/dict0dict.h index 5ffa59538c8..44db7b3df1d 100644 --- a/storage/innodb_plugin/include/dict0dict.h +++ b/storage/innodb_plugin/include/dict0dict.h @@ -1056,6 +1056,10 @@ void dict_update_statistics_low( /*=======================*/ dict_table_t* table, /*!< in/out: table */ + ibool only_calc_if_missing_stats,/*!< in: only + update/recalc the stats if they have + not been initialized yet, otherwise + do nothing */ ibool has_dict_mutex);/*!< in: TRUE if the caller has the dictionary mutex */ /*********************************************************************//** @@ -1065,7 +1069,11 @@ UNIV_INTERN void dict_update_statistics( /*===================*/ - dict_table_t* table); /*!< in/out: table */ + dict_table_t* table, /*!< in/out: table */ + ibool only_calc_if_missing_stats);/*!< in: only + update/recalc the stats if they have + not been initialized yet, otherwise + do nothing */ /********************************************************************//** Reserves the dictionary system mutex for MySQL. */ UNIV_INTERN @@ -1079,21 +1087,25 @@ void dict_mutex_exit_for_mysql(void); /*===========================*/ /**********************************************************************//** -Lock the appropriate mutex to protect index->stat_n_diff_key_vals[]. -index->id is used to pick the right mutex and it should not change -before dict_index_stat_mutex_exit() is called on this index. */ +Lock the appropriate latch to protect a given table's statistics. +table->id is used to pick the corresponding latch from a global array of +latches. */ UNIV_INTERN void -dict_index_stat_mutex_enter( -/*========================*/ - const dict_index_t* index); /*!< in: index */ +dict_table_stats_lock( +/*==================*/ + const dict_table_t* table, /*!< in: table */ + ulint latch_mode); /*!< in: RW_S_LATCH or + RW_X_LATCH */ /**********************************************************************//** -Unlock the appropriate mutex that protects index->stat_n_diff_key_vals[]. */ +Unlock the latch that has been locked by dict_table_stats_lock() */ UNIV_INTERN void -dict_index_stat_mutex_exit( -/*=======================*/ - const dict_index_t* index); /*!< in: index */ +dict_table_stats_unlock( +/*====================*/ + const dict_table_t* table, /*!< in: table */ + ulint latch_mode); /*!< in: RW_S_LATCH or + RW_X_LATCH */ /********************************************************************//** Checks if the database name in two table names is the same. @return TRUE if same db name */ diff --git a/storage/innodb_plugin/row/row0mysql.c b/storage/innodb_plugin/row/row0mysql.c index 827be32bdf7..b121edd0f3a 100644 --- a/storage/innodb_plugin/row/row0mysql.c +++ b/storage/innodb_plugin/row/row0mysql.c @@ -871,7 +871,8 @@ row_update_statistics_if_needed( if (counter > 2000000000 || ((ib_int64_t)counter > 16 + table->stat_n_rows / 16)) { - dict_update_statistics(table); + dict_update_statistics(table, FALSE /* update even if stats + are initialized */); } } @@ -2953,7 +2954,8 @@ next_rec: dict_table_autoinc_lock(table); dict_table_autoinc_initialize(table, 1); dict_table_autoinc_unlock(table); - dict_update_statistics(table); + dict_update_statistics(table, FALSE /* update even if stats are + initialized */); trx_commit_for_mysql(trx); From 6f01f9c5acde003554af93f8f33c85198ab0813d Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Tue, 2 Nov 2010 19:52:56 +0100 Subject: [PATCH 155/304] Fix cmake's version string handling (change proposed by Jonathan Perkin). Before this, a text suffix (like "-rc") after the numeric version was needed. --- cmake/mysql_version.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmake/mysql_version.cmake b/cmake/mysql_version.cmake index 6adca2ccc2f..886d7b9e8a9 100644 --- a/cmake/mysql_version.cmake +++ b/cmake/mysql_version.cmake @@ -42,6 +42,9 @@ MACRO(GET_MYSQL_VERSION) IF(NOT VERSION_STRING) FILE(STRINGS configure.in str REGEX "AC_INIT\\(") STRING(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+[-][a-zAZ0-9]+" VERSION_STRING "${str}") + IF(NOT VERSION_STRING) + STRING(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" VERSION_STRING "${str}") + ENDIF() ENDIF() ENDIF() ENDIF() From 682f27266be2b1cfd1bd28597838ce0c6753512f Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Tue, 2 Nov 2010 19:54:58 +0100 Subject: [PATCH 156/304] Add the new "qa_auth_*" plugin files to the RPM spec file, otherwise RPM builds will fail due to "unpackaged file". --- support-files/mysql.spec.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 15fe4a38a54..53178bb4d96 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -977,6 +977,9 @@ echo "=====" >> $STATUS_HISTORY %attr(755, root, root) %{_libdir}/mysql/plugin/auth.so %attr(755, root, root) %{_libdir}/mysql/plugin/auth_socket.so %attr(755, root, root) %{_libdir}/mysql/plugin/auth_test_plugin.so +%attr(755, root, root) %{_libdir}/mysql/plugin/qa_auth_client.so +%attr(755, root, root) %{_libdir}/mysql/plugin/qa_auth_interface.so +%attr(755, root, root) %{_libdir}/mysql/plugin/qa_auth_server.so %attr(755, root, root) %{_libdir}/mysql/plugin/debug/adt_null.so %attr(755, root, root) %{_libdir}/mysql/plugin/debug/libdaemon_example.so %attr(755, root, root) %{_libdir}/mysql/plugin/debug/mypluglib.so @@ -985,6 +988,9 @@ echo "=====" >> $STATUS_HISTORY %attr(755, root, root) %{_libdir}/mysql/plugin/debug/auth.so %attr(755, root, root) %{_libdir}/mysql/plugin/debug/auth_socket.so %attr(755, root, root) %{_libdir}/mysql/plugin/debug/auth_test_plugin.so +%attr(755, root, root) %{_libdir}/mysql/plugin/debug/qa_auth_client.so +%attr(755, root, root) %{_libdir}/mysql/plugin/debug/qa_auth_interface.so +%attr(755, root, root) %{_libdir}/mysql/plugin/debug/qa_auth_server.so %if %{WITH_TCMALLOC} %attr(755, root, root) %{_libdir}/mysql/%{malloc_lib_target} From 7375a944088fabbf2109dd52d068d96d908d372e Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Tue, 2 Nov 2010 22:32:29 +0100 Subject: [PATCH 157/304] Bug #57916: Fix the naming of the proxy_priv table 1. Fixed the name of the table to proxies_priv 2. Fixed the column names to be of the form Capitalized_lowercase instead of Capitalized_Capitalized 3. Added Timestamp and Grantor columns 4. Added tests to plugin_auth to check the table structure 5. Updated the existing tests Fix done by Georgi Kodinov, now transferred to the 5.5.7 release build clone. --- mysql-test/r/1st.result | 2 +- mysql-test/r/connect.result | 6 +- mysql-test/r/information_schema.result | 2 +- mysql-test/r/log_tables_upgrade.result | 2 +- mysql-test/r/mysql_upgrade.result | 12 +-- mysql-test/r/mysql_upgrade_ssl.result | 2 +- mysql-test/r/mysqlcheck.result | 8 +- mysql-test/r/plugin_auth.result | 24 +++++- mysql-test/r/system_mysql_db.result | 2 +- .../suite/funcs_1/r/is_columns_mysql.result | 24 +++--- .../funcs_1/r/is_key_column_usage.result | 8 +- .../suite/funcs_1/r/is_statistics.result | 9 +- .../funcs_1/r/is_statistics_mysql.result | 9 +- .../funcs_1/r/is_table_constraints.result | 2 +- .../r/is_table_constraints_mysql.result | 2 +- .../suite/funcs_1/r/is_tables_mysql.result | 2 +- mysql-test/t/plugin_auth.test | 7 +- mysql-test/t/system_mysql_db_fix40123.test | 2 +- mysql-test/t/system_mysql_db_fix50030.test | 2 +- mysql-test/t/system_mysql_db_fix50117.test | 2 +- scripts/mysql_system_tables.sql | 6 +- scripts/mysql_system_tables_data.sql | 10 +-- scripts/mysql_system_tables_fix.sql | 2 +- sql/sql_acl.cc | 85 +++++++++++-------- 24 files changed, 137 insertions(+), 95 deletions(-) diff --git a/mysql-test/r/1st.result b/mysql-test/r/1st.result index e8562662bfd..792d9eaf2f1 100644 --- a/mysql-test/r/1st.result +++ b/mysql-test/r/1st.result @@ -21,7 +21,7 @@ ndb_binlog_index plugin proc procs_priv -proxy_priv +proxies_priv servers slow_log tables_priv diff --git a/mysql-test/r/connect.result b/mysql-test/r/connect.result index bbd0273c1c6..b21956252d2 100644 --- a/mysql-test/r/connect.result +++ b/mysql-test/r/connect.result @@ -15,7 +15,7 @@ ndb_binlog_index plugin proc procs_priv -proxy_priv +proxies_priv servers slow_log tables_priv @@ -49,7 +49,7 @@ ndb_binlog_index plugin proc procs_priv -proxy_priv +proxies_priv servers slow_log tables_priv @@ -91,7 +91,7 @@ ndb_binlog_index plugin proc procs_priv -proxy_priv +proxies_priv servers slow_log tables_priv diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index aa47b8c437e..fd732d94dd4 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -88,7 +88,7 @@ host plugin proc procs_priv -proxy_priv +proxies_priv servers slow_log tables_priv diff --git a/mysql-test/r/log_tables_upgrade.result b/mysql-test/r/log_tables_upgrade.result index 13b08c2e771..7d15005e143 100644 --- a/mysql-test/r/log_tables_upgrade.result +++ b/mysql-test/r/log_tables_upgrade.result @@ -27,7 +27,7 @@ mysql.ndb_binlog_index OK mysql.plugin OK mysql.proc OK mysql.procs_priv OK -mysql.proxy_priv OK +mysql.proxies_priv OK mysql.renamed_general_log OK mysql.servers OK mysql.slow_log OK diff --git a/mysql-test/r/mysql_upgrade.result b/mysql-test/r/mysql_upgrade.result index f705db3e509..e36b4781ddf 100644 --- a/mysql-test/r/mysql_upgrade.result +++ b/mysql-test/r/mysql_upgrade.result @@ -15,7 +15,7 @@ mysql.ndb_binlog_index OK mysql.plugin OK mysql.proc OK mysql.procs_priv OK -mysql.proxy_priv OK +mysql.proxies_priv OK mysql.servers OK mysql.slow_log OK mysql.tables_priv OK @@ -44,7 +44,7 @@ mysql.ndb_binlog_index OK mysql.plugin OK mysql.proc OK mysql.procs_priv OK -mysql.proxy_priv OK +mysql.proxies_priv OK mysql.servers OK mysql.slow_log OK mysql.tables_priv OK @@ -73,7 +73,7 @@ mysql.ndb_binlog_index OK mysql.plugin OK mysql.proc OK mysql.procs_priv OK -mysql.proxy_priv OK +mysql.proxies_priv OK mysql.servers OK mysql.slow_log OK mysql.tables_priv OK @@ -104,7 +104,7 @@ mysql.ndb_binlog_index OK mysql.plugin OK mysql.proc OK mysql.procs_priv OK -mysql.proxy_priv OK +mysql.proxies_priv OK mysql.servers OK mysql.slow_log OK mysql.tables_priv OK @@ -139,7 +139,7 @@ mysql.ndb_binlog_index OK mysql.plugin OK mysql.proc OK mysql.procs_priv OK -mysql.proxy_priv OK +mysql.proxies_priv OK mysql.servers OK mysql.slow_log OK mysql.tables_priv OK @@ -177,7 +177,7 @@ mysql.ndb_binlog_index OK mysql.plugin OK mysql.proc OK mysql.procs_priv OK -mysql.proxy_priv OK +mysql.proxies_priv OK mysql.servers OK mysql.slow_log OK mysql.tables_priv OK diff --git a/mysql-test/r/mysql_upgrade_ssl.result b/mysql-test/r/mysql_upgrade_ssl.result index 694eb1e7d88..4cc8b6ab44b 100644 --- a/mysql-test/r/mysql_upgrade_ssl.result +++ b/mysql-test/r/mysql_upgrade_ssl.result @@ -17,7 +17,7 @@ mysql.ndb_binlog_index OK mysql.plugin OK mysql.proc OK mysql.procs_priv OK -mysql.proxy_priv OK +mysql.proxies_priv OK mysql.servers OK mysql.slow_log OK mysql.tables_priv OK diff --git a/mysql-test/r/mysqlcheck.result b/mysql-test/r/mysqlcheck.result index 241c92f0aa6..ef46eba5ccb 100644 --- a/mysql-test/r/mysqlcheck.result +++ b/mysql-test/r/mysqlcheck.result @@ -18,7 +18,7 @@ mysql.ndb_binlog_index OK mysql.plugin OK mysql.proc OK mysql.procs_priv OK -mysql.proxy_priv OK +mysql.proxies_priv OK mysql.servers OK mysql.slow_log note : The storage engine for the table doesn't support analyze @@ -46,7 +46,7 @@ mysql.ndb_binlog_index OK mysql.plugin OK mysql.proc OK mysql.procs_priv OK -mysql.proxy_priv OK +mysql.proxies_priv OK mysql.servers OK mysql.slow_log note : The storage engine for the table doesn't support optimize @@ -72,7 +72,7 @@ mysql.ndb_binlog_index OK mysql.plugin OK mysql.proc OK mysql.procs_priv OK -mysql.proxy_priv OK +mysql.proxies_priv OK mysql.servers OK mysql.slow_log note : The storage engine for the table doesn't support analyze @@ -98,7 +98,7 @@ mysql.ndb_binlog_index Table is already up to date mysql.plugin Table is already up to date mysql.proc Table is already up to date mysql.procs_priv Table is already up to date -mysql.proxy_priv Table is already up to date +mysql.proxies_priv Table is already up to date mysql.servers Table is already up to date mysql.slow_log note : The storage engine for the table doesn't support optimize diff --git a/mysql-test/r/plugin_auth.result b/mysql-test/r/plugin_auth.result index 54467b78f19..d56a4e5326a 100644 --- a/mysql-test/r/plugin_auth.result +++ b/mysql-test/r/plugin_auth.result @@ -11,6 +11,26 @@ test_plugin_server plug_dest ## test plugin auth ERROR 28000: Access denied for user 'plug'@'localhost' (using password: YES) GRANT PROXY ON plug_dest TO plug; +test proxies_priv columns +SELECT * FROM mysql.proxies_priv; +Host User Proxied_host Proxied_user With_grant Grantor Timestamp +localhost root 1 xx +unknown root 1 xx +% plug % plug_dest 0 root@localhost xx +test mysql.proxies_priv; +SHOW CREATE TABLE mysql.proxies_priv; +Table Create Table +proxies_priv CREATE TABLE `proxies_priv` ( + `Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '', + `User` char(16) COLLATE utf8_bin NOT NULL DEFAULT '', + `Proxied_host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '', + `Proxied_user` char(16) COLLATE utf8_bin NOT NULL DEFAULT '', + `With_grant` tinyint(1) NOT NULL DEFAULT '0', + `Grantor` char(77) COLLATE utf8_bin NOT NULL DEFAULT '', + `Timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`Host`,`User`,`Proxied_host`,`Proxied_user`), + KEY `Grantor` (`Grantor`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='User proxy privileges' select USER(),CURRENT_USER(); USER() CURRENT_USER() plug@localhost plug_dest@% @@ -146,8 +166,8 @@ Grants for test_drop@localhost GRANT USAGE ON *.* TO 'test_drop'@'localhost' GRANT PROXY ON 'future_user'@'%' TO 'test_drop'@'localhost' DROP USER test_drop@localhost; -SELECT * FROM mysql.proxy_priv WHERE Host = 'test_drop' AND User = 'localhost'; -Host User Proxied_Host Proxied_User With_Grant +SELECT * FROM mysql.proxies_priv WHERE Host = 'test_drop' AND User = 'localhost'; +Host User Proxied_host Proxied_user With_grant Grantor Timestamp DROP USER proxy_admin; DROP USER grant_plug,grant_plug_dest,grant_plug_dest2; ## END GRANT PROXY tests diff --git a/mysql-test/r/system_mysql_db.result b/mysql-test/r/system_mysql_db.result index e82cf229912..0028f2ce5c1 100644 --- a/mysql-test/r/system_mysql_db.result +++ b/mysql-test/r/system_mysql_db.result @@ -14,7 +14,7 @@ ndb_binlog_index plugin proc procs_priv -proxy_priv +proxies_priv servers slow_log tables_priv diff --git a/mysql-test/suite/funcs_1/r/is_columns_mysql.result b/mysql-test/suite/funcs_1/r/is_columns_mysql.result index 767f9e47f13..c61a09084a8 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_mysql.result +++ b/mysql-test/suite/funcs_1/r/is_columns_mysql.result @@ -134,11 +134,13 @@ def mysql procs_priv Routine_name 4 NO char 64 192 NULL NULL utf8 utf8_general_ def mysql procs_priv Routine_type 5 NULL NO enum 9 27 NULL NULL utf8 utf8_bin enum('FUNCTION','PROCEDURE') PRI select,insert,update,references def mysql procs_priv Timestamp 8 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL NULL NULL timestamp on update CURRENT_TIMESTAMP select,insert,update,references def mysql procs_priv User 3 NO char 16 48 NULL NULL utf8 utf8_bin char(16) PRI select,insert,update,references -def mysql proxy_priv Host 1 NO char 60 180 NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references -def mysql proxy_priv Proxied_Host 3 NO char 16 48 NULL NULL utf8 utf8_bin char(16) PRI select,insert,update,references -def mysql proxy_priv Proxied_User 4 NO char 60 180 NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references -def mysql proxy_priv User 2 NO char 16 48 NULL NULL utf8 utf8_bin char(16) PRI select,insert,update,references -def mysql proxy_priv With_Grant 5 0 NO tinyint NULL NULL 3 0 NULL NULL tinyint(1) select,insert,update,references +def mysql proxies_priv Grantor 6 NO char 77 231 NULL NULL utf8 utf8_bin char(77) MUL select,insert,update,references +def mysql proxies_priv Host 1 NO char 60 180 NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references +def mysql proxies_priv Proxied_host 3 NO char 60 180 NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references +def mysql proxies_priv Proxied_user 4 NO char 16 48 NULL NULL utf8 utf8_bin char(16) PRI select,insert,update,references +def mysql proxies_priv Timestamp 7 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL NULL NULL timestamp on update CURRENT_TIMESTAMP select,insert,update,references +def mysql proxies_priv User 2 NO char 16 48 NULL NULL utf8 utf8_bin char(16) PRI select,insert,update,references +def mysql proxies_priv With_grant 5 0 NO tinyint NULL NULL 3 0 NULL NULL tinyint(1) select,insert,update,references def mysql servers Db 3 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references def mysql servers Host 2 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references def mysql servers Owner 9 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references @@ -425,11 +427,13 @@ NULL mysql proc modified timestamp NULL NULL NULL NULL timestamp 3.0000 mysql procs_priv Grantor char 77 231 utf8 utf8_bin char(77) 3.0000 mysql procs_priv Proc_priv set 27 81 utf8 utf8_general_ci set('Execute','Alter Routine','Grant') NULL mysql procs_priv Timestamp timestamp NULL NULL NULL NULL timestamp -3.0000 mysql proxy_priv Host char 60 180 utf8 utf8_bin char(60) -3.0000 mysql proxy_priv User char 16 48 utf8 utf8_bin char(16) -3.0000 mysql proxy_priv Proxied_Host char 16 48 utf8 utf8_bin char(16) -3.0000 mysql proxy_priv Proxied_User char 60 180 utf8 utf8_bin char(60) -NULL mysql proxy_priv With_Grant tinyint NULL NULL NULL NULL tinyint(1) +3.0000 mysql proxies_priv Host char 60 180 utf8 utf8_bin char(60) +3.0000 mysql proxies_priv User char 16 48 utf8 utf8_bin char(16) +3.0000 mysql proxies_priv Proxied_host char 60 180 utf8 utf8_bin char(60) +3.0000 mysql proxies_priv Proxied_user char 16 48 utf8 utf8_bin char(16) +NULL mysql proxies_priv With_grant tinyint NULL NULL NULL NULL tinyint(1) +3.0000 mysql proxies_priv Grantor char 77 231 utf8 utf8_bin char(77) +NULL mysql proxies_priv Timestamp timestamp NULL NULL NULL NULL timestamp 3.0000 mysql servers Server_name char 64 192 utf8 utf8_general_ci char(64) 3.0000 mysql servers Host char 64 192 utf8 utf8_general_ci char(64) 3.0000 mysql servers Db char 64 192 utf8 utf8_general_ci char(64) diff --git a/mysql-test/suite/funcs_1/r/is_key_column_usage.result b/mysql-test/suite/funcs_1/r/is_key_column_usage.result index 2e50a0c36bf..afd1fe15fed 100644 --- a/mysql-test/suite/funcs_1/r/is_key_column_usage.result +++ b/mysql-test/suite/funcs_1/r/is_key_column_usage.result @@ -106,10 +106,10 @@ def mysql PRIMARY def mysql procs_priv Db def mysql PRIMARY def mysql procs_priv User def mysql PRIMARY def mysql procs_priv Routine_name def mysql PRIMARY def mysql procs_priv Routine_type -def mysql PRIMARY def mysql proxy_priv Host -def mysql PRIMARY def mysql proxy_priv User -def mysql PRIMARY def mysql proxy_priv Proxied_Host -def mysql PRIMARY def mysql proxy_priv Proxied_User +def mysql PRIMARY def mysql proxies_priv Host +def mysql PRIMARY def mysql proxies_priv User +def mysql PRIMARY def mysql proxies_priv Proxied_host +def mysql PRIMARY def mysql proxies_priv Proxied_user def mysql PRIMARY def mysql servers Server_name def mysql PRIMARY def mysql tables_priv Host def mysql PRIMARY def mysql tables_priv Db diff --git a/mysql-test/suite/funcs_1/r/is_statistics.result b/mysql-test/suite/funcs_1/r/is_statistics.result index 0c43883789b..de84590e2f7 100644 --- a/mysql-test/suite/funcs_1/r/is_statistics.result +++ b/mysql-test/suite/funcs_1/r/is_statistics.result @@ -118,10 +118,11 @@ def mysql procs_priv mysql PRIMARY def mysql procs_priv mysql PRIMARY def mysql procs_priv mysql PRIMARY def mysql procs_priv mysql Grantor -def mysql proxy_priv mysql PRIMARY -def mysql proxy_priv mysql PRIMARY -def mysql proxy_priv mysql PRIMARY -def mysql proxy_priv mysql PRIMARY +def mysql proxies_priv mysql PRIMARY +def mysql proxies_priv mysql PRIMARY +def mysql proxies_priv mysql PRIMARY +def mysql proxies_priv mysql PRIMARY +def mysql proxies_priv mysql Grantor def mysql servers mysql PRIMARY def mysql tables_priv mysql PRIMARY def mysql tables_priv mysql PRIMARY diff --git a/mysql-test/suite/funcs_1/r/is_statistics_mysql.result b/mysql-test/suite/funcs_1/r/is_statistics_mysql.result index 584bbeb7af5..4c7d58f96f1 100644 --- a/mysql-test/suite/funcs_1/r/is_statistics_mysql.result +++ b/mysql-test/suite/funcs_1/r/is_statistics_mysql.result @@ -40,10 +40,11 @@ def mysql procs_priv 0 mysql PRIMARY 2 Db A #CARD# NULL NULL BTREE def mysql procs_priv 0 mysql PRIMARY 3 User A #CARD# NULL NULL BTREE def mysql procs_priv 0 mysql PRIMARY 4 Routine_name A #CARD# NULL NULL BTREE def mysql procs_priv 0 mysql PRIMARY 5 Routine_type A #CARD# NULL NULL BTREE -def mysql proxy_priv 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE -def mysql proxy_priv 0 mysql PRIMARY 2 User A #CARD# NULL NULL BTREE -def mysql proxy_priv 0 mysql PRIMARY 3 Proxied_Host A #CARD# NULL NULL BTREE -def mysql proxy_priv 0 mysql PRIMARY 4 Proxied_User A #CARD# NULL NULL BTREE +def mysql proxies_priv 1 mysql Grantor 1 Grantor A #CARD# NULL NULL BTREE +def mysql proxies_priv 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE +def mysql proxies_priv 0 mysql PRIMARY 2 User A #CARD# NULL NULL BTREE +def mysql proxies_priv 0 mysql PRIMARY 3 Proxied_host A #CARD# NULL NULL BTREE +def mysql proxies_priv 0 mysql PRIMARY 4 Proxied_user A #CARD# NULL NULL BTREE def mysql servers 0 mysql PRIMARY 1 Server_name A #CARD# NULL NULL BTREE def mysql tables_priv 1 mysql Grantor 1 Grantor A #CARD# NULL NULL BTREE def mysql tables_priv 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE diff --git a/mysql-test/suite/funcs_1/r/is_table_constraints.result b/mysql-test/suite/funcs_1/r/is_table_constraints.result index d4d2c38c9ba..559a1f1f9f5 100644 --- a/mysql-test/suite/funcs_1/r/is_table_constraints.result +++ b/mysql-test/suite/funcs_1/r/is_table_constraints.result @@ -73,7 +73,7 @@ def mysql PRIMARY mysql ndb_binlog_index def mysql PRIMARY mysql plugin def mysql PRIMARY mysql proc def mysql PRIMARY mysql procs_priv -def mysql PRIMARY mysql proxy_priv +def mysql PRIMARY mysql proxies_priv def mysql PRIMARY mysql servers def mysql PRIMARY mysql tables_priv def mysql PRIMARY mysql time_zone diff --git a/mysql-test/suite/funcs_1/r/is_table_constraints_mysql.result b/mysql-test/suite/funcs_1/r/is_table_constraints_mysql.result index 38e9c9034c9..bca333b6387 100644 --- a/mysql-test/suite/funcs_1/r/is_table_constraints_mysql.result +++ b/mysql-test/suite/funcs_1/r/is_table_constraints_mysql.result @@ -23,7 +23,7 @@ def mysql PRIMARY mysql ndb_binlog_index PRIMARY KEY def mysql PRIMARY mysql plugin PRIMARY KEY def mysql PRIMARY mysql proc PRIMARY KEY def mysql PRIMARY mysql procs_priv PRIMARY KEY -def mysql PRIMARY mysql proxy_priv PRIMARY KEY +def mysql PRIMARY mysql proxies_priv PRIMARY KEY def mysql PRIMARY mysql servers PRIMARY KEY def mysql PRIMARY mysql tables_priv PRIMARY KEY def mysql PRIMARY mysql time_zone PRIMARY KEY diff --git a/mysql-test/suite/funcs_1/r/is_tables_mysql.result b/mysql-test/suite/funcs_1/r/is_tables_mysql.result index ae512327807..7db87c4215a 100644 --- a/mysql-test/suite/funcs_1/r/is_tables_mysql.result +++ b/mysql-test/suite/funcs_1/r/is_tables_mysql.result @@ -336,7 +336,7 @@ user_comment Procedure privileges Separator ----------------------------------------------------- TABLE_CATALOG def TABLE_SCHEMA mysql -TABLE_NAME proxy_priv +TABLE_NAME proxies_priv TABLE_TYPE BASE TABLE ENGINE MyISAM VERSION 10 diff --git a/mysql-test/t/plugin_auth.test b/mysql-test/t/plugin_auth.test index 77dcd7add73..ebbaf389632 100644 --- a/mysql-test/t/plugin_auth.test +++ b/mysql-test/t/plugin_auth.test @@ -16,6 +16,11 @@ connect(plug_con,localhost,plug,plug_dest); --enable_query_log GRANT PROXY ON plug_dest TO plug; +--echo test proxies_priv columns +--replace_column 7 xx +SELECT * FROM mysql.proxies_priv; +--echo test mysql.proxies_priv; +SHOW CREATE TABLE mysql.proxies_priv; connect(plug_con,localhost,plug,plug_dest); @@ -226,7 +231,7 @@ CREATE USER test_drop@localhost; GRANT PROXY ON future_user TO test_drop@localhost; SHOW GRANTS FOR test_drop@localhost; DROP USER test_drop@localhost; -SELECT * FROM mysql.proxy_priv WHERE Host = 'test_drop' AND User = 'localhost'; +SELECT * FROM mysql.proxies_priv WHERE Host = 'test_drop' AND User = 'localhost'; DROP USER proxy_admin; diff --git a/mysql-test/t/system_mysql_db_fix40123.test b/mysql-test/t/system_mysql_db_fix40123.test index d069271a02e..8c2060d76ba 100644 --- a/mysql-test/t/system_mysql_db_fix40123.test +++ b/mysql-test/t/system_mysql_db_fix40123.test @@ -72,7 +72,7 @@ CREATE TABLE time_zone_leap_second ( Transition_time bigint signed NOT NULL, -- disable_query_log # Drop all tables created by this test -DROP TABLE db, host, user, func, plugin, tables_priv, columns_priv, procs_priv, servers, help_category, help_keyword, help_relation, help_topic, proc, time_zone, time_zone_leap_second, time_zone_name, time_zone_transition, time_zone_transition_type, general_log, slow_log, event, ndb_binlog_index, proxy_priv; +DROP TABLE db, host, user, func, plugin, tables_priv, columns_priv, procs_priv, servers, help_category, help_keyword, help_relation, help_topic, proc, time_zone, time_zone_leap_second, time_zone_name, time_zone_transition, time_zone_transition_type, general_log, slow_log, event, ndb_binlog_index, proxies_priv; -- enable_query_log diff --git a/mysql-test/t/system_mysql_db_fix50030.test b/mysql-test/t/system_mysql_db_fix50030.test index 53166919f1c..7d55a091b6d 100644 --- a/mysql-test/t/system_mysql_db_fix50030.test +++ b/mysql-test/t/system_mysql_db_fix50030.test @@ -78,7 +78,7 @@ INSERT INTO servers VALUES ('test','localhost','test','root','', 0,'','mysql','r -- disable_query_log # Drop all tables created by this test -DROP TABLE db, host, user, func, plugin, tables_priv, columns_priv, procs_priv, servers, help_category, help_keyword, help_relation, help_topic, proc, time_zone, time_zone_leap_second, time_zone_name, time_zone_transition, time_zone_transition_type, general_log, slow_log, event, ndb_binlog_index, proxy_priv; +DROP TABLE db, host, user, func, plugin, tables_priv, columns_priv, procs_priv, servers, help_category, help_keyword, help_relation, help_topic, proc, time_zone, time_zone_leap_second, time_zone_name, time_zone_transition, time_zone_transition_type, general_log, slow_log, event, ndb_binlog_index, proxies_priv; -- enable_query_log diff --git a/mysql-test/t/system_mysql_db_fix50117.test b/mysql-test/t/system_mysql_db_fix50117.test index 872829ae79d..260400b9c8a 100644 --- a/mysql-test/t/system_mysql_db_fix50117.test +++ b/mysql-test/t/system_mysql_db_fix50117.test @@ -97,7 +97,7 @@ CREATE TABLE IF NOT EXISTS ndb_binlog_index (Position BIGINT UNSIGNED NOT NULL, -- disable_query_log # Drop all tables created by this test -DROP TABLE db, host, user, func, plugin, tables_priv, columns_priv, procs_priv, servers, help_category, help_keyword, help_relation, help_topic, proc, time_zone, time_zone_leap_second, time_zone_name, time_zone_transition, time_zone_transition_type, general_log, slow_log, event, ndb_binlog_index, proxy_priv; +DROP TABLE db, host, user, func, plugin, tables_priv, columns_priv, procs_priv, servers, help_category, help_keyword, help_relation, help_topic, proc, time_zone, time_zone_leap_second, time_zone_name, time_zone_transition, time_zone_transition_type, general_log, slow_log, event, ndb_binlog_index, proxies_priv; -- enable_query_log diff --git a/scripts/mysql_system_tables.sql b/scripts/mysql_system_tables.sql index 977907c9c14..b9c7bc6c041 100644 --- a/scripts/mysql_system_tables.sql +++ b/scripts/mysql_system_tables.sql @@ -478,7 +478,7 @@ PREPARE stmt FROM @str; EXECUTE stmt; DROP PREPARE stmt; -CREATE TABLE IF NOT EXISTS proxy_priv (Host char(60) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Proxied_Host char(16) binary DEFAULT '' NOT NULL, Proxied_User char(60) binary DEFAULT '' NOT NULL, With_Grant BOOL DEFAULT 0 NOT NULL, PRIMARY KEY Host (Host,User,Proxied_Host,Proxied_User) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='User proxy privileges'; +CREATE TABLE IF NOT EXISTS proxies_priv (Host char(60) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Proxied_host char(60) binary DEFAULT '' NOT NULL, Proxied_user char(16) binary DEFAULT '' NOT NULL, With_grant BOOL DEFAULT 0 NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Timestamp timestamp, PRIMARY KEY Host (Host,User,Proxied_host,Proxied_user), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='User proxy privileges'; --- Remember for later if proxy_priv table already existed -set @had_proxy_priv_table= @@warning_count != 0; +-- Remember for later if proxies_priv table already existed +set @had_proxies_priv_table= @@warning_count != 0; diff --git a/scripts/mysql_system_tables_data.sql b/scripts/mysql_system_tables_data.sql index 293baa46523..bc5ffae2063 100644 --- a/scripts/mysql_system_tables_data.sql +++ b/scripts/mysql_system_tables_data.sql @@ -30,8 +30,8 @@ INSERT INTO tmp_user (host,user) SELECT @current_hostname,'' FROM dual WHERE LOW INSERT INTO user SELECT * FROM tmp_user WHERE @had_user_table=0; DROP TABLE tmp_user; -CREATE TEMPORARY TABLE tmp_proxy_priv LIKE proxy_priv; -INSERT INTO tmp_proxy_priv VALUES ('localhost', 'root', '', '', TRUE); -REPLACE INTO tmp_proxy_priv SELECT @current_hostname, 'root', '', '', TRUE FROM DUAL WHERE LOWER (@current_hostname) != 'localhost'; -INSERT INTO proxy_priv SELECT * FROM tmp_proxy_priv WHERE @had_proxy_priv_table=0; -DROP TABLE tmp_proxy_priv; +CREATE TEMPORARY TABLE tmp_proxies_priv LIKE proxies_priv; +INSERT INTO tmp_proxies_priv VALUES ('localhost', 'root', '', '', TRUE, '', now()); +REPLACE INTO tmp_proxies_priv SELECT @current_hostname, 'root', '', '', TRUE, '', now() FROM DUAL WHERE LOWER (@current_hostname) != 'localhost'; +INSERT INTO proxies_priv SELECT * FROM tmp_proxies_priv WHERE @had_proxies_priv_table=0; +DROP TABLE tmp_proxies_priv; diff --git a/scripts/mysql_system_tables_fix.sql b/scripts/mysql_system_tables_fix.sql index ceb910676ab..b51e4c6f549 100644 --- a/scripts/mysql_system_tables_fix.sql +++ b/scripts/mysql_system_tables_fix.sql @@ -643,7 +643,7 @@ drop procedure mysql.die; ALTER TABLE user ADD plugin char(60) DEFAULT '' NOT NULL, ADD authentication_string TEXT NOT NULL; ALTER TABLE user MODIFY plugin char(60) DEFAULT '' NOT NULL; -CREATE TABLE IF NOT EXISTS proxy_priv (Host char(60) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Proxied_User char(60) binary DEFAULT '' NOT NULL, Proxied_Host char(16) binary DEFAULT '' NOT NULL, With_Grant BOOL DEFAULT 0 NOT NULL, PRIMARY KEY Host (Host,User,Proxied_Host,Proxied_User) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Users and global privileges'; +CREATE TABLE IF NOT EXISTS proxies_priv (Host char(60) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Proxied_host char(60) binary DEFAULT '' NOT NULL, Proxied_user char(16) binary DEFAULT '' NOT NULL, With_grant BOOL DEFAULT 0 NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Timestamp timestamp, PRIMARY KEY Host (Host,User,Proxied_host,Proxied_user), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='User proxy privileges'; # Activate the new, possible modified privilege tables # This should not be needed, but gives us some extra testing that the above diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 4725ef3a081..60dbd15b065 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -268,11 +268,13 @@ class ACL_PROXY_USER :public ACL_ACCESS bool with_grant; typedef enum { - MYSQL_PROXY_PRIV_HOST, - MYSQL_PROXY_PRIV_USER, - MYSQL_PROXY_PRIV_PROXIED_HOST, - MYSQL_PROXY_PRIV_PROXIED_USER, - MYSQL_PROXY_PRIV_WITH_GRANT } old_acl_proxy_users; + MYSQL_PROXIES_PRIV_HOST, + MYSQL_PROXIES_PRIV_USER, + MYSQL_PROXIES_PRIV_PROXIED_HOST, + MYSQL_PROXIES_PRIV_PROXIED_USER, + MYSQL_PROXIES_PRIV_WITH_GRANT, + MYSQL_PROXIES_PRIV_GRANTOR, + MYSQL_PROXIES_PRIV_TIMESTAMP } old_acl_proxy_users; public: ACL_PROXY_USER () {}; @@ -308,11 +310,11 @@ public: void init(TABLE *table, MEM_ROOT *mem) { - init (get_field(mem, table->field[MYSQL_PROXY_PRIV_HOST]), - get_field(mem, table->field[MYSQL_PROXY_PRIV_USER]), - get_field(mem, table->field[MYSQL_PROXY_PRIV_PROXIED_HOST]), - get_field(mem, table->field[MYSQL_PROXY_PRIV_PROXIED_USER]), - table->field[MYSQL_PROXY_PRIV_WITH_GRANT]->val_int() != 0); + init (get_field(mem, table->field[MYSQL_PROXIES_PRIV_HOST]), + get_field(mem, table->field[MYSQL_PROXIES_PRIV_USER]), + get_field(mem, table->field[MYSQL_PROXIES_PRIV_PROXIED_HOST]), + get_field(mem, table->field[MYSQL_PROXIES_PRIV_PROXIED_USER]), + table->field[MYSQL_PROXIES_PRIV_WITH_GRANT]->val_int() != 0); } bool get_with_grant() { return with_grant; } @@ -337,7 +339,7 @@ public: (hostname_requires_resolving(host.hostname) || hostname_requires_resolving(proxied_host.hostname))) { - sql_print_warning("'proxy_priv' entry '%s@%s %s@%s' " + sql_print_warning("'proxes_priv' entry '%s@%s %s@%s' " "ignored in --skip-name-resolve mode.", proxied_user ? proxied_user : "", proxied_host.hostname ? proxied_host.hostname : "", @@ -452,19 +454,19 @@ public: user->str ? user->str : "", proxied_host->str ? proxied_host->str : "", proxied_user->str ? proxied_user->str : "")); - if (table->field[MYSQL_PROXY_PRIV_HOST]->store(host->str, + if (table->field[MYSQL_PROXIES_PRIV_HOST]->store(host->str, host->length, system_charset_info)) DBUG_RETURN(TRUE); - if (table->field[MYSQL_PROXY_PRIV_USER]->store(user->str, + if (table->field[MYSQL_PROXIES_PRIV_USER]->store(user->str, user->length, system_charset_info)) DBUG_RETURN(TRUE); - if (table->field[MYSQL_PROXY_PRIV_PROXIED_HOST]->store(proxied_host->str, + if (table->field[MYSQL_PROXIES_PRIV_PROXIED_HOST]->store(proxied_host->str, proxied_host->length, system_charset_info)) DBUG_RETURN(TRUE); - if (table->field[MYSQL_PROXY_PRIV_PROXIED_USER]->store(proxied_user->str, + if (table->field[MYSQL_PROXIES_PRIV_PROXIED_USER]->store(proxied_user->str, proxied_user->length, system_charset_info)) DBUG_RETURN(TRUE); @@ -472,20 +474,25 @@ public: DBUG_RETURN(FALSE); } - static int store_data_record(TABLE *table, - const LEX_STRING *host, + static int store_data_record(TABLE *table, + const LEX_STRING *host, const LEX_STRING *user, - const LEX_STRING *proxied_host, + const LEX_STRING *proxied_host, const LEX_STRING *proxied_user, - bool with_grant) + bool with_grant, + const char *grantor) { - DBUG_ENTER ("ACL_PROXY_USER::store_pk"); - if (store_pk (table, host, user, proxied_host, proxied_user)) + DBUG_ENTER("ACL_PROXY_USER::store_pk"); + if (store_pk(table, host, user, proxied_host, proxied_user)) DBUG_RETURN(TRUE); - DBUG_PRINT ("info", ("with_grant=%s", with_grant ? "TRUE" : "FALSE")); - if (table->field[MYSQL_PROXY_PRIV_WITH_GRANT]->store(with_grant ? 1 : 0, + DBUG_PRINT("info", ("with_grant=%s", with_grant ? "TRUE" : "FALSE")); + if (table->field[MYSQL_PROXIES_PRIV_WITH_GRANT]->store(with_grant ? 1 : 0, TRUE)) DBUG_RETURN(TRUE); + if (table->field[MYSQL_PROXIES_PRIV_GRANTOR]->store(grantor, + strlen(grantor), + system_charset_info)) + DBUG_RETURN(TRUE); DBUG_RETURN(FALSE); } @@ -1113,8 +1120,8 @@ my_bool acl_reload(THD *thd) tables[2].init_one_table(C_STRING_WITH_LEN("mysql"), C_STRING_WITH_LEN("db"), "db", TL_READ); tables[3].init_one_table(C_STRING_WITH_LEN("mysql"), - C_STRING_WITH_LEN("proxy_priv"), - "proxy_priv", TL_READ); + C_STRING_WITH_LEN("proxies_priv"), + "proxies_priv", TL_READ); tables[0].next_local= tables[0].next_global= tables + 1; tables[1].next_local= tables[1].next_global= tables + 2; tables[2].next_local= tables[2].next_global= tables + 3; @@ -2608,7 +2615,7 @@ acl_insert_proxy_user(ACL_PROXY_USER *new_value) static int -replace_proxy_priv_table(THD *thd, TABLE *table, const LEX_USER *user, +replace_proxies_priv_table(THD *thd, TABLE *table, const LEX_USER *user, const LEX_USER *proxied_user, bool with_grant_arg, bool revoke_grant) { @@ -2616,8 +2623,9 @@ replace_proxy_priv_table(THD *thd, TABLE *table, const LEX_USER *user, int error; uchar user_key[MAX_KEY_LENGTH]; ACL_PROXY_USER new_grant; + char grantor[USER_HOST_BUFF_SIZE]; - DBUG_ENTER("replace_proxy_priv_table"); + DBUG_ENTER("replace_proxies_priv_table"); if (!initialized) { @@ -2639,6 +2647,8 @@ replace_proxy_priv_table(THD *thd, TABLE *table, const LEX_USER *user, key_copy(user_key, table->record[0], table->key_info, table->key_info->key_length); + get_grantor(thd, grantor); + table->file->ha_index_init(0, 1); if (table->file->index_read_map(table->record[0], user_key, HA_WHOLE_KEY, @@ -2655,7 +2665,8 @@ replace_proxy_priv_table(THD *thd, TABLE *table, const LEX_USER *user, ACL_PROXY_USER::store_data_record(table, &user->host, &user->user, &proxied_user->host, &proxied_user->user, - with_grant_arg); + with_grant_arg, + grantor); } else { @@ -2712,7 +2723,7 @@ table_error: table->file->print_error(error, MYF(0)); /* purecov: inspected */ abort: - DBUG_PRINT("info", ("aborting replace_proxy_priv_table")); + DBUG_PRINT("info", ("aborting replace_proxies_priv_table")); table->file->ha_index_end(); DBUG_RETURN(-1); } @@ -3962,14 +3973,14 @@ bool mysql_grant(THD *thd, const char *db, List &list, proxied_user= str_list++; } - /* open the mysql.user and mysql.db or mysql.proxy_priv tables */ + /* open the mysql.user and mysql.db or mysql.proxies_priv tables */ tables[0].init_one_table(C_STRING_WITH_LEN("mysql"), C_STRING_WITH_LEN("user"), "user", TL_WRITE); if (is_proxy) tables[1].init_one_table(C_STRING_WITH_LEN("mysql"), - C_STRING_WITH_LEN("proxy_priv"), - "proxy_priv", + C_STRING_WITH_LEN("proxies_priv"), + "proxies_priv", TL_WRITE); else tables[1].init_one_table(C_STRING_WITH_LEN("mysql"), @@ -4063,7 +4074,7 @@ bool mysql_grant(THD *thd, const char *db, List &list, } else if (is_proxy) { - if (replace_proxy_priv_table (thd, tables[1].table, Str, proxied_user, + if (replace_proxies_priv_table (thd, tables[1].table, Str, proxied_user, rights & GRANT_ACL ? TRUE : FALSE, revoke_grant)) result= -1; @@ -5690,8 +5701,8 @@ int open_grant_tables(THD *thd, TABLE_LIST *tables) C_STRING_WITH_LEN("procs_priv"), "procs_priv", TL_WRITE); (tables+5)->init_one_table(C_STRING_WITH_LEN("mysql"), - C_STRING_WITH_LEN("proxy_priv"), - "proxy_priv", TL_WRITE); + C_STRING_WITH_LEN("proxies_priv"), + "proxies_priv", TL_WRITE); tables->next_local= tables->next_global= tables + 1; (tables+1)->next_local= (tables+1)->next_global= tables + 2; (tables+2)->next_local= (tables+2)->next_global= tables + 3; @@ -6283,7 +6294,7 @@ static int handle_grant_data(TABLE_LIST *tables, bool drop, } } - /* Handle proxy_priv table. */ + /* Handle proxies_priv table. */ if ((found= handle_grant_table(tables, 5, drop, user_from, user_to)) < 0) { /* Handle of table failed, don't touch the in-memory array. */ @@ -6291,7 +6302,7 @@ static int handle_grant_data(TABLE_LIST *tables, bool drop, } else { - /* Handle proxy_priv array. */ + /* Handle proxies_priv array. */ if ((handle_grant_struct(5, drop, user_from, user_to) && !result) || found) result= 1; /* At least one record/element found. */ From 6794155a1d437a832fcaac5dd5a374cb6a58a9c1 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 2 Nov 2010 16:54:23 -0500 Subject: [PATCH 158/304] In this patch, existing tests innodb_bug54679.test and innodb_bug56632.test are removed and replaced by the comprehensive innodb-create-options.test. It uses the rules listed in the comments at the top of that test. This patch introduces these differences from previous behavior; 1) KEY_BLOCK_SIZE=0 is allowed by Innodb in both strict and non-strict mode with no errors or warnings. It was previously used by the server to set KEY_BLOCK_SIZE to undefined. (Bug#56628) 2) An explicit valid non-DEFAULT ROW_FORMAT always takes priority over a valid KEY_BLOCK_SIZE. (bug#56632) 3) Automatic use of COMPRESSED row format is only done if the ROW_FORMAT is DEFAULT or unspecified. 4) ROW_FORMAT=FIXED is prevented in strict mode. This patch also includes various formatting changes for consistency with InnoDB coding standards. Related Bugs Bug#54679: ALTER TABLE causes compressed row_format to revert to compact Bug#56628: ALTER TABLE .. KEY_BLOCK_SIZE=0 produces untrue warning or unnecessary error Bug#56632: ALTER TABLE implicitly changes ROW_FORMAT to COMPRESSED --- .../innodb/r/innodb-create-options.result | 854 ++++++++++++++++++ mysql-test/suite/innodb/r/innodb-zip.result | 20 +- .../suite/innodb/r/innodb_bug54679.result | 88 -- .../suite/innodb/r/innodb_bug56632.result | 294 ------ .../suite/innodb/t/innodb-create-options.test | 575 ++++++++++++ mysql-test/suite/innodb/t/innodb-zip.test | 8 +- .../suite/innodb/t/innodb_bug54679.test | 101 --- .../suite/innodb/t/innodb_bug56632.test | 216 ----- storage/innobase/handler/ha_innodb.cc | 291 +++--- 9 files changed, 1575 insertions(+), 872 deletions(-) create mode 100644 mysql-test/suite/innodb/r/innodb-create-options.result delete mode 100644 mysql-test/suite/innodb/r/innodb_bug54679.result delete mode 100644 mysql-test/suite/innodb/r/innodb_bug56632.result create mode 100644 mysql-test/suite/innodb/t/innodb-create-options.test delete mode 100644 mysql-test/suite/innodb/t/innodb_bug54679.test delete mode 100644 mysql-test/suite/innodb/t/innodb_bug56632.test diff --git a/mysql-test/suite/innodb/r/innodb-create-options.result b/mysql-test/suite/innodb/r/innodb-create-options.result new file mode 100644 index 00000000000..aec9d731ce6 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb-create-options.result @@ -0,0 +1,854 @@ +SET storage_engine=InnoDB; +SET GLOBAL innodb_file_format=`Barracuda`; +SET GLOBAL innodb_file_per_table=ON; +SET SESSION innodb_strict_mode = ON; +# Test 1) StrictMode=ON, CREATE and ALTER with each ROW_FORMAT & KEY_BLOCK_SIZE=0 +# KEY_BLOCK_SIZE=0 means 'no KEY_BLOCK_SIZE is specified' +DROP TABLE IF EXISTS t1; +Warnings: +Note 1051 Unknown table 't1' +# 'FIXED' is sent to InnoDB since it is used by MyISAM. +# But it is an invalid mode in InnoDB +CREATE TABLE t1 ( i INT ) ROW_FORMAT=FIXED; +ERROR HY000: Can't create table 'test.t1' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: invalid ROW_FORMAT specifier. +Error 1005 Can't create table 'test.t1' (errno: 1478) +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED +ALTER TABLE t1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=COMPACT +ALTER TABLE t1 ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Dynamic row_format=DYNAMIC +ALTER TABLE t1 ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Redundant row_format=REDUNDANT +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact +ALTER TABLE t1 ROW_FORMAT=FIXED KEY_BLOCK_SIZE=0; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: invalid ROW_FORMAT specifier. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact +# Test 2) StrictMode=ON, CREATE with each ROW_FORMAT & a valid non-zero KEY_BLOCK_SIZE +# KEY_BLOCK_SIZE is incompatible with COMPACT, REDUNDANT, & DYNAMIC +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +ERROR HY000: Can't create table 'test.t1' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. +Error 1005 Can't create table 'test.t1' (errno: 1478) +CREATE TABLE t1 ( i INT ) ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=2; +ERROR HY000: Can't create table 'test.t1' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE. +Error 1005 Can't create table 'test.t1' (errno: 1478) +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=4; +ERROR HY000: Can't create table 'test.t1' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. +Error 1005 Can't create table 'test.t1' (errno: 1478) +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=8 +ALTER TABLE t1 ADD COLUMN f1 INT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=8 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed KEY_BLOCK_SIZE=16 +ALTER TABLE t1 ADD COLUMN f1 INT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed KEY_BLOCK_SIZE=16 +# Test 3) StrictMode=ON, ALTER with each ROW_FORMAT & a valid non-zero KEY_BLOCK_SIZE +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ); +ALTER TABLE t1 ROW_FORMAT=FIXED KEY_BLOCK_SIZE=1; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: invalid ROW_FORMAT specifier. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=2; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=4; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=8; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed KEY_BLOCK_SIZE=16 +ALTER TABLE t1 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=1 +# Test 4) StrictMode=ON, CREATE with ROW_FORMAT=COMPACT, ALTER with a valid non-zero KEY_BLOCK_SIZE +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=COMPACT +ALTER TABLE t1 KEY_BLOCK_SIZE=2; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=REDUNDANT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Redundant row_format=REDUNDANT +ALTER TABLE t1 KEY_BLOCK_SIZE=4; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=DYNAMIC; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Dynamic row_format=DYNAMIC +ALTER TABLE t1 KEY_BLOCK_SIZE=8; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=COMPRESSED; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED +ALTER TABLE t1 KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=16 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT; +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed KEY_BLOCK_SIZE=1 +# Test 5) StrictMode=ON, CREATE with a valid KEY_BLOCK_SIZE +# ALTER with each ROW_FORMAT +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) KEY_BLOCK_SIZE=2; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=2 +ALTER TABLE t1 ADD COLUMN f1 INT; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) DEFAULT NULL, + `f1` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=2 +ALTER TABLE t1 ROW_FORMAT=COMPACT; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=REDUNDANT; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=DYNAMIC; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=COMPRESSED; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=2 +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact +ALTER TABLE t1 ROW_FORMAT=COMPACT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=COMPACT +# Test 6) StrictMode=ON, CREATE with an invalid KEY_BLOCK_SIZE. +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) KEY_BLOCK_SIZE=9; +ERROR HY000: Can't create table 'test.t1' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16] +Error 1005 Can't create table 'test.t1' (errno: 1478) +# Test 7) StrictMode=ON, Make sure ROW_FORMAT= COMPRESSED & DYNAMIC and +# and a valid non-zero KEY_BLOCK_SIZE are rejected with Antelope +# and that they can be set to default values during strict mode. +SET GLOBAL innodb_file_format=Antelope; +DROP TABLE IF EXISTS t1; +Warnings: +Note 1051 Unknown table 't1' +CREATE TABLE t1 ( i INT ) KEY_BLOCK_SIZE=4; +ERROR HY000: Can't create table 'test.t1' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. +Error 1005 Can't create table 'test.t1' (errno: 1478) +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED; +ERROR HY000: Can't create table 'test.t1' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope. +Error 1005 Can't create table 'test.t1' (errno: 1478) +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC; +ERROR HY000: Can't create table 'test.t1' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope. +Error 1005 Can't create table 'test.t1' (errno: 1478) +CREATE TABLE t1 ( i INT ) ROW_FORMAT=REDUNDANT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Redundant row_format=REDUNDANT +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=COMPACT +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DEFAULT; +SHOW WARNINGS; +Level Code Message +ALTER TABLE t1 KEY_BLOCK_SIZE=8; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=COMPRESSED; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=DYNAMIC; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +SET GLOBAL innodb_file_format=Barracuda; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; +SET GLOBAL innodb_file_format=Antelope; +ALTER TABLE t1 ADD COLUMN f1 INT; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. +Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +Level Code Message +ALTER TABLE t1 ADD COLUMN f2 INT; +SHOW WARNINGS; +Level Code Message +SET GLOBAL innodb_file_format=Barracuda; +# Test 8) StrictMode=ON, Make sure ROW_FORMAT= COMPRESSED & DYNAMIC and +# and a valid non-zero KEY_BLOCK_SIZE are rejected with +# innodb_file_per_table=OFF and that they can be set to default +# values during strict mode. +SET GLOBAL innodb_file_per_table=OFF; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) KEY_BLOCK_SIZE=16; +ERROR HY000: Can't create table 'test.t1' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. +Error 1005 Can't create table 'test.t1' (errno: 1478) +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED; +ERROR HY000: Can't create table 'test.t1' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table. +Error 1005 Can't create table 'test.t1' (errno: 1478) +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC; +ERROR HY000: Can't create table 'test.t1' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table. +Error 1005 Can't create table 'test.t1' (errno: 1478) +CREATE TABLE t1 ( i INT ) ROW_FORMAT=REDUNDANT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Redundant row_format=REDUNDANT +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=COMPACT +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DEFAULT; +SHOW WARNINGS; +Level Code Message +ALTER TABLE t1 KEY_BLOCK_SIZE=1; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=COMPRESSED; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=DYNAMIC; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=COMPACT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=COMPACT +ALTER TABLE t1 ROW_FORMAT=REDUNDANT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Redundant row_format=REDUNDANT +ALTER TABLE t1 ROW_FORMAT=DEFAULT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact +SET GLOBAL innodb_file_per_table=ON; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; +SET GLOBAL innodb_file_per_table=OFF; +ALTER TABLE t1 ADD COLUMN f1 INT; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. +Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +Level Code Message +ALTER TABLE t1 ADD COLUMN f2 INT; +SHOW WARNINGS; +Level Code Message +SET GLOBAL innodb_file_per_table=ON; +################################################## +SET SESSION innodb_strict_mode = OFF; +# Test 9) StrictMode=OFF, CREATE and ALTER with each ROW_FORMAT & KEY_BLOCK_SIZE=0 +# KEY_BLOCK_SIZE=0 means 'no KEY_BLOCK_SIZE is specified' +# 'FIXED' is sent to InnoDB since it is used by MyISAM. +# It is an invalid mode in InnoDB, use COMPACT +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=FIXED; +Warnings: +Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=FIXED +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED +ALTER TABLE t1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=COMPACT +ALTER TABLE t1 ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Dynamic row_format=DYNAMIC +ALTER TABLE t1 ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Redundant row_format=REDUNDANT +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact +ALTER TABLE t1 ROW_FORMAT=FIXED KEY_BLOCK_SIZE=0; +Warnings: +Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=FIXED +# Test 10) StrictMode=OFF, CREATE with each ROW_FORMAT & a valid KEY_BLOCK_SIZE +# KEY_BLOCK_SIZE is ignored with COMPACT, REDUNDANT, & DYNAMIC +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=COMPACT KEY_BLOCK_SIZE=1 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=2; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=2 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=2 unless ROW_FORMAT=COMPRESSED. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Redundant row_format=REDUNDANT KEY_BLOCK_SIZE=2 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=4; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=4 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=4 unless ROW_FORMAT=COMPRESSED. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Dynamic row_format=DYNAMIC KEY_BLOCK_SIZE=4 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=8 +ALTER TABLE t1 ADD COLUMN f1 INT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=8 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed KEY_BLOCK_SIZE=16 +ALTER TABLE t1 ADD COLUMN f1 INT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed KEY_BLOCK_SIZE=16 +# Test 11) StrictMode=OFF, ALTER with each ROW_FORMAT & a valid KEY_BLOCK_SIZE +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ); +ALTER TABLE t1 ROW_FORMAT=FIXED KEY_BLOCK_SIZE=1; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=FIXED KEY_BLOCK_SIZE=1 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ); +ALTER TABLE t1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=2; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=2 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=2 unless ROW_FORMAT=COMPRESSED. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=COMPACT KEY_BLOCK_SIZE=2 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ); +ALTER TABLE t1 ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=4; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=4 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=4 unless ROW_FORMAT=COMPRESSED. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Dynamic row_format=DYNAMIC KEY_BLOCK_SIZE=4 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ); +ALTER TABLE t1 ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=8; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=8 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=8 unless ROW_FORMAT=COMPRESSED. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Redundant row_format=REDUNDANT KEY_BLOCK_SIZE=8 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ); +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed KEY_BLOCK_SIZE=16 +ALTER TABLE t1 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=1 +# Test 12) StrictMode=OFF, CREATE with ROW_FORMAT=COMPACT, ALTER with a valid KEY_BLOCK_SIZE +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=COMPACT +ALTER TABLE t1 KEY_BLOCK_SIZE=2; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=2 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=2 unless ROW_FORMAT=COMPRESSED. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=COMPACT KEY_BLOCK_SIZE=2 +ALTER TABLE t1 ROW_FORMAT=REDUNDANT; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=2 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=2 unless ROW_FORMAT=COMPRESSED. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Redundant row_format=REDUNDANT KEY_BLOCK_SIZE=2 +ALTER TABLE t1 ROW_FORMAT=DYNAMIC; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=2 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=2 unless ROW_FORMAT=COMPRESSED. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Dynamic row_format=DYNAMIC KEY_BLOCK_SIZE=2 +ALTER TABLE t1 ROW_FORMAT=COMPRESSED; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=2 +ALTER TABLE t1 KEY_BLOCK_SIZE=4; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=4 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT; +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=8; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed KEY_BLOCK_SIZE=8 +# Test 13) StrictMode=OFF, CREATE with a valid KEY_BLOCK_SIZE +# ALTER with each ROW_FORMAT +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=16 +ALTER TABLE t1 ADD COLUMN f1 INT; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) DEFAULT NULL, + `f1` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=16 +ALTER TABLE t1 ROW_FORMAT=COMPACT; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=16 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=16 unless ROW_FORMAT=COMPRESSED. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=COMPACT KEY_BLOCK_SIZE=16 +ALTER TABLE t1 ROW_FORMAT=REDUNDANT; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=16 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=16 unless ROW_FORMAT=COMPRESSED. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Redundant row_format=REDUNDANT KEY_BLOCK_SIZE=16 +ALTER TABLE t1 ROW_FORMAT=DYNAMIC; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=16 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=16 unless ROW_FORMAT=COMPRESSED. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Dynamic row_format=DYNAMIC KEY_BLOCK_SIZE=16 +ALTER TABLE t1 ROW_FORMAT=COMPRESSED; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=16 +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact +ALTER TABLE t1 ROW_FORMAT=COMPACT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=COMPACT +# Test 14) StrictMode=OFF, CREATE with an invalid KEY_BLOCK_SIZE, it defaults to 8 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) KEY_BLOCK_SIZE=15; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=15. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=15. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact KEY_BLOCK_SIZE=15 +# Test 15) StrictMode=OFF, Make sure ROW_FORMAT= COMPRESSED & DYNAMIC and a +valid KEY_BLOCK_SIZE are remembered but not used when ROW_FORMAT +is reverted to Antelope and then used again when ROW_FORMAT=Barracuda. +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=1 +SET GLOBAL innodb_file_format=Antelope; +ALTER TABLE t1 ADD COLUMN f1 INT; +Warnings: +Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1. +Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope. +Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1. +Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope. +Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=COMPRESSED KEY_BLOCK_SIZE=1 +SET GLOBAL innodb_file_format=Barracuda; +ALTER TABLE t1 ADD COLUMN f2 INT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=1 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Dynamic row_format=DYNAMIC +SET GLOBAL innodb_file_format=Antelope; +ALTER TABLE t1 ADD COLUMN f1 INT; +Warnings: +Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope. +Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope. +Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=DYNAMIC +SET GLOBAL innodb_file_format=Barracuda; +ALTER TABLE t1 ADD COLUMN f2 INT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Dynamic row_format=DYNAMIC +# Test 16) StrictMode=OFF, Make sure ROW_FORMAT= COMPRESSED & DYNAMIC and a +valid KEY_BLOCK_SIZE are remembered but not used when innodb_file_per_table=OFF +and then used again when innodb_file_per_table=ON. +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=2 +SET GLOBAL innodb_file_per_table=OFF; +ALTER TABLE t1 ADD COLUMN f1 INT; +Warnings: +Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=2. +Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table. +Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=2. +Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table. +Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=COMPRESSED KEY_BLOCK_SIZE=2 +SET GLOBAL innodb_file_per_table=ON; +ALTER TABLE t1 ADD COLUMN f2 INT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=2 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Dynamic row_format=DYNAMIC +SET GLOBAL innodb_file_per_table=OFF; +ALTER TABLE t1 ADD COLUMN f1 INT; +Warnings: +Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table. +Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table. +Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=DYNAMIC +SET GLOBAL innodb_file_per_table=ON; +ALTER TABLE t1 ADD COLUMN f2 INT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Dynamic row_format=DYNAMIC +# Cleanup +DROP TABLE IF EXISTS t1; diff --git a/mysql-test/suite/innodb/r/innodb-zip.result b/mysql-test/suite/innodb/r/innodb-zip.result index 18fdb63d889..a63ddff15ce 100644 --- a/mysql-test/suite/innodb/r/innodb-zip.result +++ b/mysql-test/suite/innodb/r/innodb-zip.result @@ -84,8 +84,6 @@ test t8 Compact test t9 Compact drop table t0,t00,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14; alter table t1 key_block_size=0; -Warnings: -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=0. alter table t1 row_format=dynamic; SELECT table_schema, table_name, row_format FROM information_schema.tables WHERE engine='innodb'; @@ -191,16 +189,9 @@ set global innodb_file_per_table = on; set global innodb_file_format = `1`; set innodb_strict_mode = off; create table t1 (id int primary key) engine = innodb key_block_size = 0; -Warnings: -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=0. drop table t1; set innodb_strict_mode = on; create table t1 (id int primary key) engine = innodb key_block_size = 0; -ERROR HY000: Can't create table 'test.t1' (errno: 1478) -show warnings; -Level Code Message -Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 0. Valid values are [1, 2, 4, 8, 16] -Error 1005 Can't create table 'test.t1' (errno: 1478) create table t2 (id int primary key) engine = innodb key_block_size = 9; ERROR HY000: Can't create table 'test.t2' (errno: 1478) show warnings; @@ -219,6 +210,7 @@ create table t11(id int primary key) engine = innodb row_format = redundant; SELECT table_schema, table_name, row_format FROM information_schema.tables WHERE engine='innodb'; table_schema table_name row_format +test t1 Compact test t10 Compact test t11 Redundant test t3 Compressed @@ -228,7 +220,7 @@ test t6 Compressed test t7 Compressed test t8 Compressed test t9 Dynamic -drop table t3, t4, t5, t6, t7, t8, t9, t10, t11; +drop table t1, t3, t4, t5, t6, t7, t8, t9, t10, t11; create table t1 (id int primary key) engine = innodb key_block_size = 8 row_format = compressed; create table t2 (id int primary key) engine = innodb @@ -254,16 +246,12 @@ Warning 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. Error 1005 Can't create table 'test.t4' (errno: 1478) create table t5 (id int primary key) engine = innodb key_block_size = 8 row_format = default; -ERROR HY000: Can't create table 'test.t5' (errno: 1478) -show warnings; -Level Code Message -Warning 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. -Error 1005 Can't create table 'test.t5' (errno: 1478) SELECT table_schema, table_name, row_format FROM information_schema.tables WHERE engine='innodb'; table_schema table_name row_format test t1 Compressed -drop table t1; +test t5 Compressed +drop table t1, t5; create table t1 (id int primary key) engine = innodb key_block_size = 9 row_format = redundant; ERROR HY000: Can't create table 'test.t1' (errno: 1478) diff --git a/mysql-test/suite/innodb/r/innodb_bug54679.result b/mysql-test/suite/innodb/r/innodb_bug54679.result deleted file mode 100644 index 948696fb31d..00000000000 --- a/mysql-test/suite/innodb/r/innodb_bug54679.result +++ /dev/null @@ -1,88 +0,0 @@ -SET GLOBAL innodb_file_format='Barracuda'; -SET GLOBAL innodb_file_per_table=ON; -SET innodb_strict_mode=ON; -CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables -WHERE TABLE_NAME='bug54679'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug54679 Compressed row_format=COMPRESSED -ALTER TABLE bug54679 ADD COLUMN b INT; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables -WHERE TABLE_NAME='bug54679'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug54679 Compressed row_format=COMPRESSED -DROP TABLE bug54679; -CREATE TABLE bug54679 (a INT) ENGINE=InnoDB; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables -WHERE TABLE_NAME='bug54679'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug54679 Compact -ALTER TABLE bug54679 KEY_BLOCK_SIZE=1; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables -WHERE TABLE_NAME='bug54679'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug54679 Compressed KEY_BLOCK_SIZE=1 -ALTER TABLE bug54679 ROW_FORMAT=REDUNDANT; -ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE. -Error 1005 Can't create table '#sql-temporary' (errno: 1478) -DROP TABLE bug54679; -CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=REDUNDANT; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables -WHERE TABLE_NAME='bug54679'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug54679 Redundant row_format=REDUNDANT -ALTER TABLE bug54679 KEY_BLOCK_SIZE=2; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables -WHERE TABLE_NAME='bug54679'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug54679 Compressed row_format=REDUNDANT KEY_BLOCK_SIZE=2 -SET GLOBAL innodb_file_format=Antelope; -ALTER TABLE bug54679 KEY_BLOCK_SIZE=4; -ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. -Error 1005 Can't create table '#sql-temporary' (errno: 1478) -ALTER TABLE bug54679 ROW_FORMAT=DYNAMIC; -ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. -Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope. -Warning 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. -Error 1005 Can't create table '#sql-temporary' (errno: 1478) -DROP TABLE bug54679; -CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; -ERROR HY000: Can't create table 'test.bug54679' (errno: 1478) -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope. -Error 1005 Can't create table 'test.bug54679' (errno: 1478) -CREATE TABLE bug54679 (a INT) ENGINE=InnoDB; -SET GLOBAL innodb_file_format=Barracuda; -SET GLOBAL innodb_file_per_table=OFF; -ALTER TABLE bug54679 KEY_BLOCK_SIZE=4; -ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. -Error 1005 Can't create table '#sql-temporary' (errno: 1478) -ALTER TABLE bug54679 ROW_FORMAT=DYNAMIC; -ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table. -Error 1005 Can't create table '#sql-temporary' (errno: 1478) -DROP TABLE bug54679; -CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; -ERROR HY000: Can't create table 'test.bug54679' (errno: 1478) -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table. -Error 1005 Can't create table 'test.bug54679' (errno: 1478) -SET GLOBAL innodb_file_per_table=ON; -CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; -DROP TABLE bug54679; diff --git a/mysql-test/suite/innodb/r/innodb_bug56632.result b/mysql-test/suite/innodb/r/innodb_bug56632.result deleted file mode 100644 index 8236b37676b..00000000000 --- a/mysql-test/suite/innodb/r/innodb_bug56632.result +++ /dev/null @@ -1,294 +0,0 @@ -SET storage_engine=InnoDB; -SET GLOBAL innodb_file_format=`Barracuda`; -SET GLOBAL innodb_file_per_table=ON; -SET SESSION innodb_strict_mode = ON; -# Test 1) CREATE with ROW_FORMAT & KEY_BLOCK_SIZE, ALTER with neither -DROP TABLE IF EXISTS bug56632; -Warnings: -Note 1051 Unknown table 'bug56632' -CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; -ERROR HY000: Can't create table 'test.bug56632' (errno: 1478) -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. -Error 1005 Can't create table 'test.bug56632' (errno: 1478) -# Test 2) CREATE with ROW_FORMAT, ALTER with KEY_BLOCK_SIZE -DROP TABLE IF EXISTS bug56632; -Warnings: -Note 1051 Unknown table 'bug56632' -CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT; -SHOW WARNINGS; -Level Code Message -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compact row_format=COMPACT -ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; -SHOW WARNINGS; -Level Code Message -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compressed row_format=COMPACT KEY_BLOCK_SIZE=1 -# Test 3) CREATE with KEY_BLOCK_SIZE, ALTER with ROW_FORMAT -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=1; -SHOW WARNINGS; -Level Code Message -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compressed KEY_BLOCK_SIZE=1 -ALTER TABLE bug56632 ROW_FORMAT=COMPACT; -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compressed KEY_BLOCK_SIZE=1 -# Test 4) CREATE with neither, ALTER with ROW_FORMAT & KEY_BLOCK_SIZE -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ); -SHOW WARNINGS; -Level Code Message -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compact -ALTER TABLE bug56632 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compact -# Test 5) CREATE with KEY_BLOCK_SIZE=3 (invalid). -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; -ERROR HY000: Can't create table 'test.bug56632' (errno: 1478) -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 3. Valid values are [1, 2, 4, 8, 16] -Error 1005 Can't create table 'test.bug56632' (errno: 1478) -SET SESSION innodb_strict_mode = OFF; -# Test 6) CREATE with ROW_FORMAT & KEY_BLOCK_SIZE, ALTER with neither -DROP TABLE IF EXISTS bug56632; -Warnings: -Note 1051 Unknown table 'bug56632' -CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; -Warnings: -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compact row_format=COMPACT KEY_BLOCK_SIZE=1 -ALTER TABLE bug56632 ADD COLUMN f1 INT; -Warnings: -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL, - `f1` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compact row_format=COMPACT KEY_BLOCK_SIZE=1 -# Test 7) CREATE with ROW_FORMAT, ALTER with KEY_BLOCK_SIZE -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT; -SHOW WARNINGS; -Level Code Message -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compact row_format=COMPACT -ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; -SHOW WARNINGS; -Level Code Message -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compressed row_format=COMPACT KEY_BLOCK_SIZE=1 -# Test 8) CREATE with KEY_BLOCK_SIZE, ALTER with ROW_FORMAT -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=1; -SHOW WARNINGS; -Level Code Message -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compressed KEY_BLOCK_SIZE=1 -ALTER TABLE bug56632 ROW_FORMAT=COMPACT; -Warnings: -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compact row_format=COMPACT KEY_BLOCK_SIZE=1 -# Test 9) CREATE with neither, ALTER with ROW_FORMAT & KEY_BLOCK_SIZE -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ); -SHOW WARNINGS; -Level Code Message -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compact -ALTER TABLE bug56632 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; -Warnings: -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compact row_format=COMPACT KEY_BLOCK_SIZE=1 -# Test 10) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with neither. -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; -Warnings: -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=3 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compact KEY_BLOCK_SIZE=3 -ALTER TABLE bug56632 ADD COLUMN f1 INT; -Warnings: -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL, - `f1` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=3 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compact KEY_BLOCK_SIZE=3 -# Test 11) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with ROW_FORMAT=COMPACT. -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; -Warnings: -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=3 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compact KEY_BLOCK_SIZE=3 -ALTER TABLE bug56632 ROW_FORMAT=COMPACT; -Warnings: -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=3 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compact row_format=COMPACT KEY_BLOCK_SIZE=3 -# Test 12) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with KEY_BLOCK_SIZE=1. -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; -Warnings: -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=3 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compact KEY_BLOCK_SIZE=3 -ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; -SHOW WARNINGS; -Level Code Message -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compressed KEY_BLOCK_SIZE=1 -# Cleanup -DROP TABLE IF EXISTS bug56632; diff --git a/mysql-test/suite/innodb/t/innodb-create-options.test b/mysql-test/suite/innodb/t/innodb-create-options.test new file mode 100644 index 00000000000..3daa5f09e71 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-create-options.test @@ -0,0 +1,575 @@ +# Tests for various combinations of ROW_FORMAT and KEY_BLOCK_SIZE +# Related bugs; +# Bug#54679: ALTER TABLE causes compressed row_format to revert to compact +# Bug#56628: ALTER TABLE .. KEY_BLOCK_SIZE=0 produces untrue warning or unnecessary error +# Bug#56632: ALTER TABLE implicitly changes ROW_FORMAT to COMPRESSED +# Rules for interpreting CREATE_OPTIONS +# 1) Create options on an ALTER are added to the options on the +# previous CREATE or ALTER statements. +# 2) KEY_BLOCK_SIZE=0 is considered a unspecified value. +# If the current ROW_FORMAT has explicitly been set to COMPRESSED, +# InnoDB will use a default value of 8. Otherwise KEY_BLOCK_SIZE +# will not be used. +# 3) ROW_FORMAT=DEFAULT allows InnoDB to choose its own default, COMPACT. +# 4) ROW_FORMAT=DEFAULT and KEY_BLOCK_SIZE=0 can be used at any time to +# unset or erase the values persisted in the MySQL dictionary and +# by SHOW CTREATE TABLE. +# 5) When incompatible values for ROW_FORMAT and KEY_BLOCK_SIZE are +# both explicitly given, the ROW_FORMAT is always used in non-strict +# mode. +# 6) InnoDB will automatically convert a table to COMPRESSED only if a +# valid non-zero KEY_BLOCK_SIZE has been given and ROW_FORMAT=DEFAULT +# or has not been used on a previous CREATE TABLE or ALTER TABLE. +# 7) InnoDB strict mode is designed to prevent incompatible create +# options from being used together. +# 8) The non-strict behavior is intended to permit you to import a +# mysqldump file into a database that does not support compressed +# tables, even if the source database contained compressed tables. +# All invalid values and/or incompatible combinations of ROW_FORMAT +# and KEY_BLOCK_SIZE are automatically corrected +# +# *** innodb_strict_mode=ON *** +# 1) Valid ROW_FORMATs are COMPRESSED, COMPACT, DEFAULT, DYNAMIC +# & REDUNDANT. All others are rejected. +# 2) Valid KEY_BLOCK_SIZEs are 0,1,2,4,8,16. All others are rejected. +# 3) KEY_BLOCK_SIZE=0 can be used to set it to 'unspecified'. +# 4) KEY_BLOCK_SIZE=1,2,4,8 & 16 are incompatible with COMPACT, DYNAMIC & +# REDUNDANT. +# 5) KEY_BLOCK_SIZE=1,2,4,8 & 16 as well as ROW_FORMAT=COMPRESSED and +# ROW_FORMAT=DYNAMIC are incompatible with innodb_file_format=Antelope +# and innodb_file_per_table=OFF +# 6) KEY_BLOCK_SIZE on an ALTER must occur with ROW_FORMAT=COMPRESSED +# or ROW_FORMAT=DEFAULT if the ROW_FORMAT was previously specified +# as COMPACT, DYNAMIC or REDUNDANT. +# 7) KEY_BLOCK_SIZE on an ALTER can occur without a ROW_FORMAT if the +# previous ROW_FORMAT was DEFAULT, COMPRESSED, or unspecified. +# +# *** innodb_strict_mode=OFF *** +# 1. Ignore a bad KEY_BLOCK_SIZE, defaulting it to 8. +# 2. Ignore a bad ROW_FORMAT, defaulting to COMPACT. +# 3. Ignore a valid KEY_BLOCK_SIZE when an incompatible but valid +# ROW_FORMAT is specified. +# 4. If innodb_file_format=Antelope or innodb_file_per_table=OFF +# it will ignore ROW_FORMAT=COMPRESSED or DYNAMIC and it will +# ignore all non-zero KEY_BLOCK_SIZEs. +# +# See InnoDB documentation page "SQL Compression Syntax Warnings and Errors" + +-- source include/have_innodb.inc +SET storage_engine=InnoDB; + +--disable_query_log +# These values can change during the test +LET $innodb_file_format_orig=`select @@innodb_file_format`; +LET $innodb_file_format_max_orig=`select @@innodb_file_format_max`; +LET $innodb_file_per_table_orig=`select @@innodb_file_per_table`; +LET $innodb_strict_mode_orig=`select @@session.innodb_strict_mode`; +--enable_query_log + +SET GLOBAL innodb_file_format=`Barracuda`; +SET GLOBAL innodb_file_per_table=ON; + +# The first half of these tests are with strict mode ON. +SET SESSION innodb_strict_mode = ON; + +--echo # Test 1) StrictMode=ON, CREATE and ALTER with each ROW_FORMAT & KEY_BLOCK_SIZE=0 +--echo # KEY_BLOCK_SIZE=0 means 'no KEY_BLOCK_SIZE is specified' +DROP TABLE IF EXISTS t1; +--echo # 'FIXED' is sent to InnoDB since it is used by MyISAM. +--echo # But it is an invalid mode in InnoDB +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1 ( i INT ) ROW_FORMAT=FIXED; +SHOW WARNINGS; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 ROW_FORMAT=FIXED KEY_BLOCK_SIZE=0; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; + + + +--echo # Test 2) StrictMode=ON, CREATE with each ROW_FORMAT & a valid non-zero KEY_BLOCK_SIZE +--echo # KEY_BLOCK_SIZE is incompatible with COMPACT, REDUNDANT, & DYNAMIC +DROP TABLE IF EXISTS t1; +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1 ( i INT ) ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=2; +SHOW WARNINGS; +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=4; +SHOW WARNINGS; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ADD COLUMN f1 INT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ADD COLUMN f1 INT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; + + +--echo # Test 3) StrictMode=ON, ALTER with each ROW_FORMAT & a valid non-zero KEY_BLOCK_SIZE +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ); +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 ROW_FORMAT=FIXED KEY_BLOCK_SIZE=1; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=2; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=4; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=8; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; + + +--echo # Test 4) StrictMode=ON, CREATE with ROW_FORMAT=COMPACT, ALTER with a valid non-zero KEY_BLOCK_SIZE +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 KEY_BLOCK_SIZE=2; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +ALTER TABLE t1 ROW_FORMAT=REDUNDANT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 KEY_BLOCK_SIZE=4; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +ALTER TABLE t1 ROW_FORMAT=DYNAMIC; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 KEY_BLOCK_SIZE=8; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +ALTER TABLE t1 ROW_FORMAT=COMPRESSED; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT; +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; + +--echo # Test 5) StrictMode=ON, CREATE with a valid KEY_BLOCK_SIZE +--echo # ALTER with each ROW_FORMAT +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) KEY_BLOCK_SIZE=2; +SHOW CREATE TABLE t1; +ALTER TABLE t1 ADD COLUMN f1 INT; +SHOW CREATE TABLE t1; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 ROW_FORMAT=COMPACT; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 ROW_FORMAT=REDUNDANT; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 ROW_FORMAT=DYNAMIC; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +ALTER TABLE t1 ROW_FORMAT=COMPRESSED; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=COMPACT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; + +--echo # Test 6) StrictMode=ON, CREATE with an invalid KEY_BLOCK_SIZE. +DROP TABLE IF EXISTS t1; +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1 ( i INT ) KEY_BLOCK_SIZE=9; +SHOW WARNINGS; + +--echo # Test 7) StrictMode=ON, Make sure ROW_FORMAT= COMPRESSED & DYNAMIC and +--echo # and a valid non-zero KEY_BLOCK_SIZE are rejected with Antelope +--echo # and that they can be set to default values during strict mode. +SET GLOBAL innodb_file_format=Antelope; +DROP TABLE IF EXISTS t1; +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1 ( i INT ) KEY_BLOCK_SIZE=4; +SHOW WARNINGS; +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED; +SHOW WARNINGS; +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC; +SHOW WARNINGS; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=REDUNDANT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DEFAULT; +SHOW WARNINGS; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 KEY_BLOCK_SIZE=8; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 ROW_FORMAT=COMPRESSED; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 ROW_FORMAT=DYNAMIC; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +SET GLOBAL innodb_file_format=Barracuda; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; +SET GLOBAL innodb_file_format=Antelope; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 ADD COLUMN f1 INT; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +ALTER TABLE t1 ADD COLUMN f2 INT; +SHOW WARNINGS; +SET GLOBAL innodb_file_format=Barracuda; + +--echo # Test 8) StrictMode=ON, Make sure ROW_FORMAT= COMPRESSED & DYNAMIC and +--echo # and a valid non-zero KEY_BLOCK_SIZE are rejected with +--echo # innodb_file_per_table=OFF and that they can be set to default +--echo # values during strict mode. +SET GLOBAL innodb_file_per_table=OFF; +DROP TABLE IF EXISTS t1; +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1 ( i INT ) KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED; +SHOW WARNINGS; +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC; +SHOW WARNINGS; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=REDUNDANT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DEFAULT; +SHOW WARNINGS; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 KEY_BLOCK_SIZE=1; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 ROW_FORMAT=COMPRESSED; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 ROW_FORMAT=DYNAMIC; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +ALTER TABLE t1 ROW_FORMAT=COMPACT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=REDUNDANT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=DEFAULT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +SET GLOBAL innodb_file_per_table=ON; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; +SET GLOBAL innodb_file_per_table=OFF; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 ADD COLUMN f1 INT; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +ALTER TABLE t1 ADD COLUMN f2 INT; +SHOW WARNINGS; +SET GLOBAL innodb_file_per_table=ON; + +--echo ################################################## +SET SESSION innodb_strict_mode = OFF; + +--echo # Test 9) StrictMode=OFF, CREATE and ALTER with each ROW_FORMAT & KEY_BLOCK_SIZE=0 +--echo # KEY_BLOCK_SIZE=0 means 'no KEY_BLOCK_SIZE is specified' +--echo # 'FIXED' is sent to InnoDB since it is used by MyISAM. +--echo # It is an invalid mode in InnoDB, use COMPACT +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=FIXED; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=FIXED KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; + +--echo # Test 10) StrictMode=OFF, CREATE with each ROW_FORMAT & a valid KEY_BLOCK_SIZE +--echo # KEY_BLOCK_SIZE is ignored with COMPACT, REDUNDANT, & DYNAMIC +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=2; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=4; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ADD COLUMN f1 INT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ADD COLUMN f1 INT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; + + +--echo # Test 11) StrictMode=OFF, ALTER with each ROW_FORMAT & a valid KEY_BLOCK_SIZE +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ); +ALTER TABLE t1 ROW_FORMAT=FIXED KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ); +ALTER TABLE t1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=2; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ); +ALTER TABLE t1 ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=4; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ); +ALTER TABLE t1 ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=8; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ); +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; + + +--echo # Test 12) StrictMode=OFF, CREATE with ROW_FORMAT=COMPACT, ALTER with a valid KEY_BLOCK_SIZE +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 KEY_BLOCK_SIZE=2; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=REDUNDANT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=DYNAMIC; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=COMPRESSED; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 KEY_BLOCK_SIZE=4; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT; +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=8; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; + +--echo # Test 13) StrictMode=OFF, CREATE with a valid KEY_BLOCK_SIZE +--echo # ALTER with each ROW_FORMAT +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +SHOW CREATE TABLE t1; +ALTER TABLE t1 ADD COLUMN f1 INT; +SHOW WARNINGS; +SHOW CREATE TABLE t1; +ALTER TABLE t1 ROW_FORMAT=COMPACT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=REDUNDANT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=DYNAMIC; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=COMPRESSED; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=COMPACT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; + +--echo # Test 14) StrictMode=OFF, CREATE with an invalid KEY_BLOCK_SIZE, it defaults to 8 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) KEY_BLOCK_SIZE=15; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; + +--echo # Test 15) StrictMode=OFF, Make sure ROW_FORMAT= COMPRESSED & DYNAMIC and a +--echo valid KEY_BLOCK_SIZE are remembered but not used when ROW_FORMAT +--echo is reverted to Antelope and then used again when ROW_FORMAT=Barracuda. +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +SET GLOBAL innodb_file_format=Antelope; +ALTER TABLE t1 ADD COLUMN f1 INT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +SET GLOBAL innodb_file_format=Barracuda; +ALTER TABLE t1 ADD COLUMN f2 INT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +SET GLOBAL innodb_file_format=Antelope; +ALTER TABLE t1 ADD COLUMN f1 INT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +SET GLOBAL innodb_file_format=Barracuda; +ALTER TABLE t1 ADD COLUMN f2 INT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; + +--echo # Test 16) StrictMode=OFF, Make sure ROW_FORMAT= COMPRESSED & DYNAMIC and a +--echo valid KEY_BLOCK_SIZE are remembered but not used when innodb_file_per_table=OFF +--echo and then used again when innodb_file_per_table=ON. +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +SET GLOBAL innodb_file_per_table=OFF; +ALTER TABLE t1 ADD COLUMN f1 INT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +SET GLOBAL innodb_file_per_table=ON; +ALTER TABLE t1 ADD COLUMN f2 INT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +SET GLOBAL innodb_file_per_table=OFF; +ALTER TABLE t1 ADD COLUMN f1 INT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +SET GLOBAL innodb_file_per_table=ON; +ALTER TABLE t1 ADD COLUMN f2 INT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; + + +--echo # Cleanup +DROP TABLE IF EXISTS t1; + +--disable_query_log +EVAL SET GLOBAL innodb_file_format=$innodb_file_format_orig; +EVAL SET GLOBAL innodb_file_format_max=$innodb_file_format_max_orig; +EVAL SET GLOBAL innodb_file_per_table=$innodb_file_per_table_orig; +EVAL SET SESSION innodb_strict_mode=$innodb_strict_mode_orig; +--enable_query_log + diff --git a/mysql-test/suite/innodb/t/innodb-zip.test b/mysql-test/suite/innodb/t/innodb-zip.test index 8e00a8b019b..2b4631f83db 100644 --- a/mysql-test/suite/innodb/t/innodb-zip.test +++ b/mysql-test/suite/innodb/t/innodb-zip.test @@ -176,9 +176,7 @@ set innodb_strict_mode = on; #Test different values of KEY_BLOCK_SIZE ---error ER_CANT_CREATE_TABLE create table t1 (id int primary key) engine = innodb key_block_size = 0; -show warnings; --error ER_CANT_CREATE_TABLE create table t2 (id int primary key) engine = innodb key_block_size = 9; @@ -199,7 +197,7 @@ create table t11(id int primary key) engine = innodb row_format = redundant; SELECT table_schema, table_name, row_format FROM information_schema.tables WHERE engine='innodb'; -drop table t3, t4, t5, t6, t7, t8, t9, t10, t11; +drop table t1, t3, t4, t5, t6, t7, t8, t9, t10, t11; #test different values of ROW_FORMAT with KEY_BLOCK_SIZE create table t1 (id int primary key) engine = innodb @@ -220,14 +218,12 @@ create table t4 (id int primary key) engine = innodb key_block_size = 8 row_format = dynamic; show warnings; ---error ER_CANT_CREATE_TABLE create table t5 (id int primary key) engine = innodb key_block_size = 8 row_format = default; -show warnings; SELECT table_schema, table_name, row_format FROM information_schema.tables WHERE engine='innodb'; -drop table t1; +drop table t1, t5; #test multiple errors --error ER_CANT_CREATE_TABLE diff --git a/mysql-test/suite/innodb/t/innodb_bug54679.test b/mysql-test/suite/innodb/t/innodb_bug54679.test deleted file mode 100644 index c5e308acb5e..00000000000 --- a/mysql-test/suite/innodb/t/innodb_bug54679.test +++ /dev/null @@ -1,101 +0,0 @@ -# Test Bug #54679 alter table causes compressed row_format to revert to compact - ---source include/have_innodb.inc - -let $file_format=`select @@innodb_file_format`; -let $file_format_max=`select @@innodb_file_format_max`; -let $file_per_table=`select @@innodb_file_per_table`; -SET GLOBAL innodb_file_format='Barracuda'; -SET GLOBAL innodb_file_per_table=ON; -SET innodb_strict_mode=ON; - -CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables -WHERE TABLE_NAME='bug54679'; - -# The ROW_FORMAT of the table should be preserved when it is not specified -# in ALTER TABLE. -ALTER TABLE bug54679 ADD COLUMN b INT; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables -WHERE TABLE_NAME='bug54679'; - -DROP TABLE bug54679; - -# Check that the ROW_FORMAT conversion to/from COMPRESSED works. - -CREATE TABLE bug54679 (a INT) ENGINE=InnoDB; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables -WHERE TABLE_NAME='bug54679'; - -# KEY_BLOCK_SIZE implies COMPRESSED. -ALTER TABLE bug54679 KEY_BLOCK_SIZE=1; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables -WHERE TABLE_NAME='bug54679'; - ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ ---error ER_CANT_CREATE_TABLE -ALTER TABLE bug54679 ROW_FORMAT=REDUNDANT; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ -SHOW WARNINGS; -DROP TABLE bug54679; -CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=REDUNDANT; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables -WHERE TABLE_NAME='bug54679'; - -ALTER TABLE bug54679 KEY_BLOCK_SIZE=2; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables -WHERE TABLE_NAME='bug54679'; - -# This prevents other than REDUNDANT or COMPACT ROW_FORMAT for new tables. -SET GLOBAL innodb_file_format=Antelope; - ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ ---error ER_CANT_CREATE_TABLE -ALTER TABLE bug54679 KEY_BLOCK_SIZE=4; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ -SHOW WARNINGS; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ ---error ER_CANT_CREATE_TABLE -ALTER TABLE bug54679 ROW_FORMAT=DYNAMIC; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ -SHOW WARNINGS; -DROP TABLE bug54679; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ ---error ER_CANT_CREATE_TABLE -CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ -SHOW WARNINGS; -CREATE TABLE bug54679 (a INT) ENGINE=InnoDB; - -SET GLOBAL innodb_file_format=Barracuda; -# This will prevent ROW_FORMAT=COMPRESSED, because the system tablespace -# cannot be compressed. -SET GLOBAL innodb_file_per_table=OFF; - ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ ---error ER_CANT_CREATE_TABLE -ALTER TABLE bug54679 KEY_BLOCK_SIZE=4; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ -SHOW WARNINGS; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ ---error ER_CANT_CREATE_TABLE -ALTER TABLE bug54679 ROW_FORMAT=DYNAMIC; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ -SHOW WARNINGS; -DROP TABLE bug54679; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ ---error ER_CANT_CREATE_TABLE -CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ -SHOW WARNINGS; -SET GLOBAL innodb_file_per_table=ON; -CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; -DROP TABLE bug54679; - -# restore original values, quietly so the test does not fail if those -# defaults are changed --- disable_query_log -EVAL SET GLOBAL innodb_file_format=$file_format; -EVAL SET GLOBAL innodb_file_format_max=$file_format_max; -EVAL SET GLOBAL innodb_file_per_table=$file_per_table; --- enable_query_log diff --git a/mysql-test/suite/innodb/t/innodb_bug56632.test b/mysql-test/suite/innodb/t/innodb_bug56632.test deleted file mode 100644 index 60703814da2..00000000000 --- a/mysql-test/suite/innodb/t/innodb_bug56632.test +++ /dev/null @@ -1,216 +0,0 @@ -# -# Bug#56632: ALTER TABLE implicitly changes ROW_FORMAT to COMPRESSED -# http://bugs.mysql.com/56632 -# -# Innodb automatically uses compressed mode when the KEY_BLOCK_SIZE -# parameter is used, except if the ROW_FORMAT is also specified, in -# which case the KEY_BLOCK_SIZE is ignored and a warning is shown. -# But Innodb was getting confused when neither of those parameters -# was used on the ALTER statement after they were both used on the -# CREATE. -# -# This will test the results of all 4 combinations of these two -# parameters of the CREATE and ALTER. -# -# Tests 1-5 use INNODB_STRICT_MODE=1 which returns an error -# if there is anything wrong with the statement. -# -# 1) CREATE with ROW_FORMAT=COMPACT & KEY_BLOCK_SIZE=1, ALTER with neither. -# Result; CREATE; fails with error ER_CANT_CREATE_TABLE -# 2) CREATE with ROW_FORMAT=COMPACT, ALTER with KEY_BLOCK_SIZE=1 -# Result; CREATE succeeds, -# ALTER quietly converts ROW_FORMAT to compressed. -# 3) CREATE with KEY_BLOCK_SIZE=1, ALTER with ROW_FORMAT=COMPACT -# Result; CREATE quietly converts ROW_FORMAT to compressed, -# ALTER fails with error ER_CANT_CREATE_TABLE. -# 4) CREATE with neither, ALTER with ROW_FORMAT=COMPACT & KEY_BLOCK_SIZE=1 -# Result; CREATE succeeds, -# ALTER; fails with error ER_CANT_CREATE_TABLE -# 5) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with neither. -# Result; CREATE; fails with error ER_CANT_CREATE_TABLE -# -# Tests 6-11 use INNODB_STRICT_MODE=0 which automatically makes -# adjustments if the prameters are incompatible. -# -# 6) CREATE with ROW_FORMAT=COMPACT & KEY_BLOCK_SIZE=1, ALTER with neither. -# Result; CREATE succeeds, warns that KEY_BLOCK_SIZE is ignored. -# ALTER succeeds, no warnings. -# 7) CREATE with ROW_FORMAT=COMPACT, ALTER with KEY_BLOCK_SIZE=1 -# Result; CREATE succeeds, -# ALTER quietly converts ROW_FORMAT to compressed. -# 8) CREATE with KEY_BLOCK_SIZE=1, ALTER with ROW_FORMAT=COMPACT -# Result; CREATE quietly converts ROW_FORMAT to compressed, -# ALTER succeeds, warns that KEY_BLOCK_SIZE is ignored. -# 9) CREATE with neither, ALTER with ROW_FORMAT=COMPACT & KEY_BLOCK_SIZE=1 -# Result; CREATE succeeds, -# ALTER succeeds, warns that KEY_BLOCK_SIZE is ignored. -# 10) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with neither. -# Result; CREATE succeeds, warns that KEY_BLOCK_SIZE=3 is ignored. -# ALTER succeeds, warns that KEY_BLOCK_SIZE=3 is ignored. -# 11) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with ROW_FORMAT=COMPACT. -# Result; CREATE succeeds, warns that KEY_BLOCK_SIZE=3 is ignored. -# ALTER succeeds, warns that KEY_BLOCK_SIZE=3 is ignored. -# 12) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with KEY_BLOCK_SIZE=1. -# Result; CREATE succeeds, warns that KEY_BLOCK_SIZE=3 is ignored. -# ALTER succeeds, quietly converts ROW_FORMAT to compressed. - --- source include/have_innodb.inc - -SET storage_engine=InnoDB; - ---disable_query_log -# These values can change during the test -LET $innodb_file_format_orig=`select @@innodb_file_format`; -LET $innodb_file_format_max_orig=`select @@innodb_file_format_max`; -LET $innodb_file_per_table_orig=`select @@innodb_file_per_table`; -LET $innodb_strict_mode_orig=`select @@session.innodb_strict_mode`; ---enable_query_log - -SET GLOBAL innodb_file_format=`Barracuda`; -SET GLOBAL innodb_file_per_table=ON; - -# Innodb strict mode will cause an error on the CREATE or ALTER when; -# 1. both ROW_FORMAT=COMPACT and KEY_BLOCK_SIZE=1, -# 2. KEY_BLOCK_SIZE is not a valid number (0,1,2,4,8,16). -# With innodb_strict_mode = OFF, These errors are corrected -# and just a warning is returned. -SET SESSION innodb_strict_mode = ON; - ---echo # Test 1) CREATE with ROW_FORMAT & KEY_BLOCK_SIZE, ALTER with neither -DROP TABLE IF EXISTS bug56632; ---error ER_CANT_CREATE_TABLE -CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; -SHOW WARNINGS; - ---echo # Test 2) CREATE with ROW_FORMAT, ALTER with KEY_BLOCK_SIZE -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT; -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; - ---echo # Test 3) CREATE with KEY_BLOCK_SIZE, ALTER with ROW_FORMAT -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=1; -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; ---disable_result_log ---error ER_CANT_CREATE_TABLE -ALTER TABLE bug56632 ROW_FORMAT=COMPACT; ---enable_result_log -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; - ---echo # Test 4) CREATE with neither, ALTER with ROW_FORMAT & KEY_BLOCK_SIZE -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ); -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; ---disable_result_log ---error ER_CANT_CREATE_TABLE -ALTER TABLE bug56632 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; ---enable_result_log -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; - ---echo # Test 5) CREATE with KEY_BLOCK_SIZE=3 (invalid). -DROP TABLE IF EXISTS bug56632; ---error ER_CANT_CREATE_TABLE -CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; -SHOW WARNINGS; - -SET SESSION innodb_strict_mode = OFF; - ---echo # Test 6) CREATE with ROW_FORMAT & KEY_BLOCK_SIZE, ALTER with neither -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -ALTER TABLE bug56632 ADD COLUMN f1 INT; -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; - ---echo # Test 7) CREATE with ROW_FORMAT, ALTER with KEY_BLOCK_SIZE -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT; -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; - ---echo # Test 8) CREATE with KEY_BLOCK_SIZE, ALTER with ROW_FORMAT -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=1; -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -ALTER TABLE bug56632 ROW_FORMAT=COMPACT; -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; - ---echo # Test 9) CREATE with neither, ALTER with ROW_FORMAT & KEY_BLOCK_SIZE -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ); -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -ALTER TABLE bug56632 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; - ---echo # Test 10) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with neither. -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -ALTER TABLE bug56632 ADD COLUMN f1 INT; -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; - ---echo # Test 11) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with ROW_FORMAT=COMPACT. -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -ALTER TABLE bug56632 ROW_FORMAT=COMPACT; -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; - ---echo # Test 12) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with KEY_BLOCK_SIZE=1. -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; - ---echo # Cleanup -DROP TABLE IF EXISTS bug56632; - ---disable_query_log -EVAL SET GLOBAL innodb_file_per_table=$innodb_file_per_table_orig; -EVAL SET GLOBAL innodb_file_format_max=$innodb_file_format_max_orig; -EVAL SET GLOBAL innodb_file_format=$innodb_file_format_orig; -EVAL SET SESSION innodb_strict_mode=$innodb_strict_mode_orig; ---enable_query_log - diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 1a2e26ba1ab..852c9d5f4ae 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -6493,6 +6493,33 @@ create_clustered_index_when_no_primary( return(error); } +/*****************************************************************//** +Return a display name for the row format +@return row format name */ + +const char *get_row_format_name( +/*============================*/ +enum row_type row_format) /*!< in: Row Format */ +{ + switch (row_format) { + case ROW_TYPE_COMPACT: + return("COMPACT"); + case ROW_TYPE_COMPRESSED: + return("COMPRESSED"); + case ROW_TYPE_DYNAMIC: + return("DYNAMIC"); + case ROW_TYPE_REDUNDANT: + return("REDUNDANT"); + case ROW_TYPE_DEFAULT: + return("DEFAULT"); + case ROW_TYPE_FIXED: + return("FIXED"); + default: + break; + } + return("NOT USED"); +} + /*****************************************************************//** Validates the create options. We may build on this function in future. For now, it checks two specifiers: @@ -6508,9 +6535,9 @@ create_options_are_valid( columns and indexes */ HA_CREATE_INFO* create_info) /*!< in: create info. */ { - ibool kbs_specified = FALSE; + ibool kbs_specified = FALSE; ibool ret = TRUE; - + enum row_type row_type = form->s->row_type; ut_ad(thd != NULL); @@ -6519,13 +6546,28 @@ create_options_are_valid( return(TRUE); } + /* Check for a valid Innodb ROW_FORMAT specifier. For example, + ROW_TYPE_FIXED can be sent to Innodb */ + switch (row_type) { + case ROW_TYPE_COMPACT: + case ROW_TYPE_COMPRESSED: + case ROW_TYPE_DYNAMIC: + case ROW_TYPE_REDUNDANT: + case ROW_TYPE_DEFAULT: + break; + default: + push_warning( + thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: invalid ROW_FORMAT specifier."); + ret = FALSE; + } + ut_ad(form != NULL); ut_ad(create_info != NULL); - /* First check if KEY_BLOCK_SIZE was specified. */ - if (create_info->key_block_size - || (create_info->used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE)) { - + /* First check if a non-zero KEY_BLOCK_SIZE was specified. */ + if (create_info->key_block_size) { kbs_specified = TRUE; switch (create_info->key_block_size) { case 1: @@ -6536,13 +6578,12 @@ create_options_are_valid( /* Valid value. */ break; default: - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: invalid" - " KEY_BLOCK_SIZE = %lu." - " Valid values are" - " [1, 2, 4, 8, 16]", - create_info->key_block_size); + push_warning_printf( + thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: invalid KEY_BLOCK_SIZE = %lu." + " Valid values are [1, 2, 4, 8, 16]", + create_info->key_block_size); ret = FALSE; } } @@ -6550,109 +6591,67 @@ create_options_are_valid( /* If KEY_BLOCK_SIZE was specified, check for its dependencies. */ if (kbs_specified && !srv_file_per_table) { - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: KEY_BLOCK_SIZE" - " requires innodb_file_per_table."); + push_warning( + thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: KEY_BLOCK_SIZE requires" + " innodb_file_per_table."); ret = FALSE; } if (kbs_specified && srv_file_format < DICT_TF_FORMAT_ZIP) { - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: KEY_BLOCK_SIZE" - " requires innodb_file_format >" - " Antelope."); + push_warning( + thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: KEY_BLOCK_SIZE requires" + " innodb_file_format > Antelope."); ret = FALSE; } - /* Now check for ROW_FORMAT specifier. */ - if (create_info->used_fields & HA_CREATE_USED_ROW_FORMAT) { - switch (form->s->row_type) { - const char* row_format_name; - case ROW_TYPE_COMPRESSED: - case ROW_TYPE_DYNAMIC: - row_format_name - = form->s->row_type == ROW_TYPE_COMPRESSED - ? "COMPRESSED" - : "DYNAMIC"; - - /* These two ROW_FORMATs require srv_file_per_table - and srv_file_format > Antelope */ - if (!srv_file_per_table) { - push_warning_printf( - thd, - MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: ROW_FORMAT=%s" - " requires innodb_file_per_table.", - row_format_name); - ret = FALSE; - } - - if (srv_file_format < DICT_TF_FORMAT_ZIP) { - push_warning_printf( - thd, - MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: ROW_FORMAT=%s" - " requires innodb_file_format >" - " Antelope.", - row_format_name); - ret = FALSE; - } - - /* Cannot specify KEY_BLOCK_SIZE with - ROW_FORMAT = DYNAMIC. - However, we do allow COMPRESSED to be - specified with KEY_BLOCK_SIZE. */ - if (kbs_specified - && form->s->row_type == ROW_TYPE_DYNAMIC) { - push_warning_printf( - thd, - MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: cannot specify" - " ROW_FORMAT = DYNAMIC with" - " KEY_BLOCK_SIZE."); - ret = FALSE; - } - - break; - - case ROW_TYPE_REDUNDANT: - case ROW_TYPE_COMPACT: - case ROW_TYPE_DEFAULT: - /* Default is COMPACT. */ - row_format_name - = form->s->row_type == ROW_TYPE_REDUNDANT - ? "REDUNDANT" - : "COMPACT"; - - /* Cannot specify KEY_BLOCK_SIZE with these - format specifiers. */ - if (kbs_specified) { - push_warning_printf( - thd, - MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: cannot specify" - " ROW_FORMAT = %s with" - " KEY_BLOCK_SIZE.", - row_format_name); - ret = FALSE; - } - - break; - - default: - push_warning(thd, - MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: invalid ROW_FORMAT specifier."); - ret = FALSE; - + switch (row_type) { + case ROW_TYPE_COMPRESSED: + case ROW_TYPE_DYNAMIC: + /* These two ROW_FORMATs require srv_file_per_table + and srv_file_format > Antelope */ + if (!srv_file_per_table) { + push_warning_printf( + thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: ROW_FORMAT=%s requires" + " innodb_file_per_table.", + get_row_format_name(row_type)); + ret = FALSE; } + + if (srv_file_format < DICT_TF_FORMAT_ZIP) { + push_warning_printf( + thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: ROW_FORMAT=%s requires" + " innodb_file_format > Antelope.", + get_row_format_name(row_type)); + ret = FALSE; + } + default: + break; + } + + switch (row_type) { + case ROW_TYPE_REDUNDANT: + case ROW_TYPE_COMPACT: + case ROW_TYPE_DYNAMIC: + /* KEY_BLOCK_SIZE is only allowed with Compressed or Default */ + if (kbs_specified) { + push_warning_printf( + thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: cannot specify ROW_FORMAT = %s" + " with KEY_BLOCK_SIZE.", + get_row_format_name(row_type)); + ret = FALSE; + } + default: + break; } return(ret); @@ -6778,8 +6777,7 @@ ha_innobase::create( goto cleanup; } - if (create_info->key_block_size - || (create_info->used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE)) { + if (create_info->key_block_size) { /* Determine the page_zip.ssize corresponding to the requested page size (key_block_size) in kilobytes. */ @@ -6800,38 +6798,39 @@ ha_innobase::create( } if (!srv_file_per_table) { - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: KEY_BLOCK_SIZE" - " requires innodb_file_per_table."); + push_warning( + thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: KEY_BLOCK_SIZE requires" + " innodb_file_per_table."); flags = 0; } if (file_format < DICT_TF_FORMAT_ZIP) { - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: KEY_BLOCK_SIZE" - " requires innodb_file_format >" - " Antelope."); + push_warning( + thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: KEY_BLOCK_SIZE requires" + " innodb_file_format > Antelope."); flags = 0; } if (!flags) { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: ignoring" - " KEY_BLOCK_SIZE=%lu.", - create_info->key_block_size); + push_warning_printf( + thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: ignoring" + " KEY_BLOCK_SIZE=%lu.", + create_info->key_block_size); } } row_type = form->s->row_type; if (flags) { - /* if KEY_BLOCK_SIZE was specified on this statement and - ROW_FORMAT was not, automatically change ROW_FORMAT to COMPRESSED.*/ - if ( (create_info->used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE) - && !(create_info->used_fields & HA_CREATE_USED_ROW_FORMAT)) { + /* if ROW_FORMAT is set to default, + automatically change it to COMPRESSED.*/ + if (row_type == ROW_TYPE_DEFAULT) { row_type = ROW_TYPE_COMPRESSED; } else if (row_type != ROW_TYPE_COMPRESSED) { /* ROW_FORMAT other than COMPRESSED @@ -6841,8 +6840,7 @@ ha_innobase::create( such combinations can be obtained with ALTER TABLE anyway. */ push_warning_printf( - thd, - MYSQL_ERROR::WARN_LEVEL_WARN, + thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, "InnoDB: ignoring KEY_BLOCK_SIZE=%lu" " unless ROW_FORMAT=COMPRESSED.", @@ -6867,33 +6865,24 @@ ha_innobase::create( } switch (row_type) { - const char* row_format_name; case ROW_TYPE_REDUNDANT: break; case ROW_TYPE_COMPRESSED: case ROW_TYPE_DYNAMIC: - row_format_name - = row_type == ROW_TYPE_COMPRESSED - ? "COMPRESSED" - : "DYNAMIC"; - if (!srv_file_per_table) { push_warning_printf( - thd, - MYSQL_ERROR::WARN_LEVEL_WARN, + thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: ROW_FORMAT=%s" - " requires innodb_file_per_table.", - row_format_name); + "InnoDB: ROW_FORMAT=%s requires" + " innodb_file_per_table.", + get_row_format_name(row_type)); } else if (file_format < DICT_TF_FORMAT_ZIP) { push_warning_printf( - thd, - MYSQL_ERROR::WARN_LEVEL_WARN, + thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: ROW_FORMAT=%s" - " requires innodb_file_format >" - " Antelope.", - row_format_name); + "InnoDB: ROW_FORMAT=%s requires" + " innodb_file_format > Antelope.", + get_row_format_name(row_type)); } else { flags |= DICT_TF_COMPACT | (DICT_TF_FORMAT_ZIP @@ -6905,10 +6894,10 @@ ha_innobase::create( case ROW_TYPE_NOT_USED: case ROW_TYPE_FIXED: default: - push_warning(thd, - MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: assuming ROW_FORMAT=COMPACT."); + push_warning( + thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: assuming ROW_FORMAT=COMPACT."); case ROW_TYPE_DEFAULT: case ROW_TYPE_COMPACT: flags = DICT_TF_COMPACT; From 64e476e070b473cd55b1f3338d84c24e4017e1a3 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 2 Nov 2010 17:28:34 -0500 Subject: [PATCH 159/304] In this patch, existing tests innodb_bug54679.test and innodb_bug56632.test are removed and replaced by the comprehensive innodb-create-options.test. It uses the rules listed in the comments at the top of that test. This patch introduces these differences from previous behavior; 1) KEY_BLOCK_SIZE=0 is allowed by Innodb in both strict and non-strict mode with no errors or warnings. It was previously used by the server to set KEY_BLOCK_SIZE to undefined. (Bug#56628) 2) An explicit valid non-DEFAULT ROW_FORMAT always takes priority over a valid KEY_BLOCK_SIZE. (bug#56632) 3) Automatic use of COMPRESSED row format is only done if the ROW_FORMAT is DEFAULT or unspecified. 4) ROW_FORMAT=FIXED is prevented in strict mode. This patch also includes various formatting changes for consistency with InnoDB coding standards. Related Bugs Bug#54679: ALTER TABLE causes compressed row_format to revert to compact Bug#56628: ALTER TABLE .. KEY_BLOCK_SIZE=0 produces untrue warning or unnecessary error Bug#56632: ALTER TABLE implicitly changes ROW_FORMAT to COMPRESSED --- .../r/innodb-create-options.result | 854 ++++++++++++++++++ .../suite/innodb_plugin/r/innodb-zip.result | 20 +- .../innodb_plugin/r/innodb_bug54679.result | 91 -- .../innodb_plugin/r/innodb_bug56632.result | 294 ------ .../t/innodb-create-options.test | 575 ++++++++++++ .../suite/innodb_plugin/t/innodb-zip.test | 8 +- .../innodb_plugin/t/innodb_bug54679.test | 97 -- .../innodb_plugin/t/innodb_bug56632.test | 216 ----- storage/innodb_plugin/handler/ha_innodb.cc | 291 +++--- 9 files changed, 1575 insertions(+), 871 deletions(-) create mode 100755 mysql-test/suite/innodb_plugin/r/innodb-create-options.result delete mode 100644 mysql-test/suite/innodb_plugin/r/innodb_bug54679.result delete mode 100755 mysql-test/suite/innodb_plugin/r/innodb_bug56632.result create mode 100755 mysql-test/suite/innodb_plugin/t/innodb-create-options.test delete mode 100644 mysql-test/suite/innodb_plugin/t/innodb_bug54679.test delete mode 100755 mysql-test/suite/innodb_plugin/t/innodb_bug56632.test diff --git a/mysql-test/suite/innodb_plugin/r/innodb-create-options.result b/mysql-test/suite/innodb_plugin/r/innodb-create-options.result new file mode 100755 index 00000000000..aec9d731ce6 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb-create-options.result @@ -0,0 +1,854 @@ +SET storage_engine=InnoDB; +SET GLOBAL innodb_file_format=`Barracuda`; +SET GLOBAL innodb_file_per_table=ON; +SET SESSION innodb_strict_mode = ON; +# Test 1) StrictMode=ON, CREATE and ALTER with each ROW_FORMAT & KEY_BLOCK_SIZE=0 +# KEY_BLOCK_SIZE=0 means 'no KEY_BLOCK_SIZE is specified' +DROP TABLE IF EXISTS t1; +Warnings: +Note 1051 Unknown table 't1' +# 'FIXED' is sent to InnoDB since it is used by MyISAM. +# But it is an invalid mode in InnoDB +CREATE TABLE t1 ( i INT ) ROW_FORMAT=FIXED; +ERROR HY000: Can't create table 'test.t1' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: invalid ROW_FORMAT specifier. +Error 1005 Can't create table 'test.t1' (errno: 1478) +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED +ALTER TABLE t1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=COMPACT +ALTER TABLE t1 ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Dynamic row_format=DYNAMIC +ALTER TABLE t1 ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Redundant row_format=REDUNDANT +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact +ALTER TABLE t1 ROW_FORMAT=FIXED KEY_BLOCK_SIZE=0; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: invalid ROW_FORMAT specifier. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact +# Test 2) StrictMode=ON, CREATE with each ROW_FORMAT & a valid non-zero KEY_BLOCK_SIZE +# KEY_BLOCK_SIZE is incompatible with COMPACT, REDUNDANT, & DYNAMIC +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +ERROR HY000: Can't create table 'test.t1' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. +Error 1005 Can't create table 'test.t1' (errno: 1478) +CREATE TABLE t1 ( i INT ) ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=2; +ERROR HY000: Can't create table 'test.t1' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE. +Error 1005 Can't create table 'test.t1' (errno: 1478) +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=4; +ERROR HY000: Can't create table 'test.t1' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. +Error 1005 Can't create table 'test.t1' (errno: 1478) +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=8 +ALTER TABLE t1 ADD COLUMN f1 INT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=8 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed KEY_BLOCK_SIZE=16 +ALTER TABLE t1 ADD COLUMN f1 INT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed KEY_BLOCK_SIZE=16 +# Test 3) StrictMode=ON, ALTER with each ROW_FORMAT & a valid non-zero KEY_BLOCK_SIZE +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ); +ALTER TABLE t1 ROW_FORMAT=FIXED KEY_BLOCK_SIZE=1; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: invalid ROW_FORMAT specifier. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=2; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=4; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=8; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed KEY_BLOCK_SIZE=16 +ALTER TABLE t1 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=1 +# Test 4) StrictMode=ON, CREATE with ROW_FORMAT=COMPACT, ALTER with a valid non-zero KEY_BLOCK_SIZE +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=COMPACT +ALTER TABLE t1 KEY_BLOCK_SIZE=2; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=REDUNDANT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Redundant row_format=REDUNDANT +ALTER TABLE t1 KEY_BLOCK_SIZE=4; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=DYNAMIC; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Dynamic row_format=DYNAMIC +ALTER TABLE t1 KEY_BLOCK_SIZE=8; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=COMPRESSED; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED +ALTER TABLE t1 KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=16 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT; +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed KEY_BLOCK_SIZE=1 +# Test 5) StrictMode=ON, CREATE with a valid KEY_BLOCK_SIZE +# ALTER with each ROW_FORMAT +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) KEY_BLOCK_SIZE=2; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=2 +ALTER TABLE t1 ADD COLUMN f1 INT; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) DEFAULT NULL, + `f1` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=2 +ALTER TABLE t1 ROW_FORMAT=COMPACT; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=REDUNDANT; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=DYNAMIC; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=COMPRESSED; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=2 +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact +ALTER TABLE t1 ROW_FORMAT=COMPACT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=COMPACT +# Test 6) StrictMode=ON, CREATE with an invalid KEY_BLOCK_SIZE. +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) KEY_BLOCK_SIZE=9; +ERROR HY000: Can't create table 'test.t1' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16] +Error 1005 Can't create table 'test.t1' (errno: 1478) +# Test 7) StrictMode=ON, Make sure ROW_FORMAT= COMPRESSED & DYNAMIC and +# and a valid non-zero KEY_BLOCK_SIZE are rejected with Antelope +# and that they can be set to default values during strict mode. +SET GLOBAL innodb_file_format=Antelope; +DROP TABLE IF EXISTS t1; +Warnings: +Note 1051 Unknown table 't1' +CREATE TABLE t1 ( i INT ) KEY_BLOCK_SIZE=4; +ERROR HY000: Can't create table 'test.t1' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. +Error 1005 Can't create table 'test.t1' (errno: 1478) +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED; +ERROR HY000: Can't create table 'test.t1' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope. +Error 1005 Can't create table 'test.t1' (errno: 1478) +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC; +ERROR HY000: Can't create table 'test.t1' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope. +Error 1005 Can't create table 'test.t1' (errno: 1478) +CREATE TABLE t1 ( i INT ) ROW_FORMAT=REDUNDANT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Redundant row_format=REDUNDANT +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=COMPACT +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DEFAULT; +SHOW WARNINGS; +Level Code Message +ALTER TABLE t1 KEY_BLOCK_SIZE=8; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=COMPRESSED; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=DYNAMIC; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +SET GLOBAL innodb_file_format=Barracuda; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; +SET GLOBAL innodb_file_format=Antelope; +ALTER TABLE t1 ADD COLUMN f1 INT; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. +Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +Level Code Message +ALTER TABLE t1 ADD COLUMN f2 INT; +SHOW WARNINGS; +Level Code Message +SET GLOBAL innodb_file_format=Barracuda; +# Test 8) StrictMode=ON, Make sure ROW_FORMAT= COMPRESSED & DYNAMIC and +# and a valid non-zero KEY_BLOCK_SIZE are rejected with +# innodb_file_per_table=OFF and that they can be set to default +# values during strict mode. +SET GLOBAL innodb_file_per_table=OFF; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) KEY_BLOCK_SIZE=16; +ERROR HY000: Can't create table 'test.t1' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. +Error 1005 Can't create table 'test.t1' (errno: 1478) +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED; +ERROR HY000: Can't create table 'test.t1' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table. +Error 1005 Can't create table 'test.t1' (errno: 1478) +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC; +ERROR HY000: Can't create table 'test.t1' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table. +Error 1005 Can't create table 'test.t1' (errno: 1478) +CREATE TABLE t1 ( i INT ) ROW_FORMAT=REDUNDANT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Redundant row_format=REDUNDANT +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=COMPACT +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DEFAULT; +SHOW WARNINGS; +Level Code Message +ALTER TABLE t1 KEY_BLOCK_SIZE=1; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=COMPRESSED; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=DYNAMIC; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=COMPACT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=COMPACT +ALTER TABLE t1 ROW_FORMAT=REDUNDANT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Redundant row_format=REDUNDANT +ALTER TABLE t1 ROW_FORMAT=DEFAULT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact +SET GLOBAL innodb_file_per_table=ON; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; +SET GLOBAL innodb_file_per_table=OFF; +ALTER TABLE t1 ADD COLUMN f1 INT; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. +Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +Level Code Message +ALTER TABLE t1 ADD COLUMN f2 INT; +SHOW WARNINGS; +Level Code Message +SET GLOBAL innodb_file_per_table=ON; +################################################## +SET SESSION innodb_strict_mode = OFF; +# Test 9) StrictMode=OFF, CREATE and ALTER with each ROW_FORMAT & KEY_BLOCK_SIZE=0 +# KEY_BLOCK_SIZE=0 means 'no KEY_BLOCK_SIZE is specified' +# 'FIXED' is sent to InnoDB since it is used by MyISAM. +# It is an invalid mode in InnoDB, use COMPACT +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=FIXED; +Warnings: +Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=FIXED +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED +ALTER TABLE t1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=COMPACT +ALTER TABLE t1 ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Dynamic row_format=DYNAMIC +ALTER TABLE t1 ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Redundant row_format=REDUNDANT +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact +ALTER TABLE t1 ROW_FORMAT=FIXED KEY_BLOCK_SIZE=0; +Warnings: +Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=FIXED +# Test 10) StrictMode=OFF, CREATE with each ROW_FORMAT & a valid KEY_BLOCK_SIZE +# KEY_BLOCK_SIZE is ignored with COMPACT, REDUNDANT, & DYNAMIC +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=COMPACT KEY_BLOCK_SIZE=1 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=2; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=2 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=2 unless ROW_FORMAT=COMPRESSED. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Redundant row_format=REDUNDANT KEY_BLOCK_SIZE=2 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=4; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=4 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=4 unless ROW_FORMAT=COMPRESSED. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Dynamic row_format=DYNAMIC KEY_BLOCK_SIZE=4 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=8 +ALTER TABLE t1 ADD COLUMN f1 INT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=8 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed KEY_BLOCK_SIZE=16 +ALTER TABLE t1 ADD COLUMN f1 INT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed KEY_BLOCK_SIZE=16 +# Test 11) StrictMode=OFF, ALTER with each ROW_FORMAT & a valid KEY_BLOCK_SIZE +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ); +ALTER TABLE t1 ROW_FORMAT=FIXED KEY_BLOCK_SIZE=1; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. +Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=FIXED KEY_BLOCK_SIZE=1 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ); +ALTER TABLE t1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=2; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=2 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=2 unless ROW_FORMAT=COMPRESSED. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=COMPACT KEY_BLOCK_SIZE=2 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ); +ALTER TABLE t1 ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=4; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=4 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=4 unless ROW_FORMAT=COMPRESSED. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Dynamic row_format=DYNAMIC KEY_BLOCK_SIZE=4 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ); +ALTER TABLE t1 ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=8; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=8 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=8 unless ROW_FORMAT=COMPRESSED. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Redundant row_format=REDUNDANT KEY_BLOCK_SIZE=8 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ); +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed KEY_BLOCK_SIZE=16 +ALTER TABLE t1 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=1 +# Test 12) StrictMode=OFF, CREATE with ROW_FORMAT=COMPACT, ALTER with a valid KEY_BLOCK_SIZE +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=COMPACT +ALTER TABLE t1 KEY_BLOCK_SIZE=2; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=2 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=2 unless ROW_FORMAT=COMPRESSED. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=COMPACT KEY_BLOCK_SIZE=2 +ALTER TABLE t1 ROW_FORMAT=REDUNDANT; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=2 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=2 unless ROW_FORMAT=COMPRESSED. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Redundant row_format=REDUNDANT KEY_BLOCK_SIZE=2 +ALTER TABLE t1 ROW_FORMAT=DYNAMIC; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=2 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=2 unless ROW_FORMAT=COMPRESSED. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Dynamic row_format=DYNAMIC KEY_BLOCK_SIZE=2 +ALTER TABLE t1 ROW_FORMAT=COMPRESSED; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=2 +ALTER TABLE t1 KEY_BLOCK_SIZE=4; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=4 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT; +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=8; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed KEY_BLOCK_SIZE=8 +# Test 13) StrictMode=OFF, CREATE with a valid KEY_BLOCK_SIZE +# ALTER with each ROW_FORMAT +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=16 +ALTER TABLE t1 ADD COLUMN f1 INT; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) DEFAULT NULL, + `f1` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=16 +ALTER TABLE t1 ROW_FORMAT=COMPACT; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=16 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=16 unless ROW_FORMAT=COMPRESSED. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=COMPACT KEY_BLOCK_SIZE=16 +ALTER TABLE t1 ROW_FORMAT=REDUNDANT; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=16 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=16 unless ROW_FORMAT=COMPRESSED. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Redundant row_format=REDUNDANT KEY_BLOCK_SIZE=16 +ALTER TABLE t1 ROW_FORMAT=DYNAMIC; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=16 unless ROW_FORMAT=COMPRESSED. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=16 unless ROW_FORMAT=COMPRESSED. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Dynamic row_format=DYNAMIC KEY_BLOCK_SIZE=16 +ALTER TABLE t1 ROW_FORMAT=COMPRESSED; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=16 +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact +ALTER TABLE t1 ROW_FORMAT=COMPACT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=COMPACT +# Test 14) StrictMode=OFF, CREATE with an invalid KEY_BLOCK_SIZE, it defaults to 8 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) KEY_BLOCK_SIZE=15; +Warnings: +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=15. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=15. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact KEY_BLOCK_SIZE=15 +# Test 15) StrictMode=OFF, Make sure ROW_FORMAT= COMPRESSED & DYNAMIC and a +valid KEY_BLOCK_SIZE are remembered but not used when ROW_FORMAT +is reverted to Antelope and then used again when ROW_FORMAT=Barracuda. +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=1 +SET GLOBAL innodb_file_format=Antelope; +ALTER TABLE t1 ADD COLUMN f1 INT; +Warnings: +Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1. +Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope. +Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1. +Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope. +Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=COMPRESSED KEY_BLOCK_SIZE=1 +SET GLOBAL innodb_file_format=Barracuda; +ALTER TABLE t1 ADD COLUMN f2 INT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=1 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Dynamic row_format=DYNAMIC +SET GLOBAL innodb_file_format=Antelope; +ALTER TABLE t1 ADD COLUMN f1 INT; +Warnings: +Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope. +Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope. +Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=DYNAMIC +SET GLOBAL innodb_file_format=Barracuda; +ALTER TABLE t1 ADD COLUMN f2 INT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Dynamic row_format=DYNAMIC +# Test 16) StrictMode=OFF, Make sure ROW_FORMAT= COMPRESSED & DYNAMIC and a +valid KEY_BLOCK_SIZE are remembered but not used when innodb_file_per_table=OFF +and then used again when innodb_file_per_table=ON. +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=2 +SET GLOBAL innodb_file_per_table=OFF; +ALTER TABLE t1 ADD COLUMN f1 INT; +Warnings: +Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=2. +Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table. +Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. +Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=2. +Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table. +Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=COMPRESSED KEY_BLOCK_SIZE=2 +SET GLOBAL innodb_file_per_table=ON; +ALTER TABLE t1 ADD COLUMN f2 INT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compressed row_format=COMPRESSED KEY_BLOCK_SIZE=2 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Dynamic row_format=DYNAMIC +SET GLOBAL innodb_file_per_table=OFF; +ALTER TABLE t1 ADD COLUMN f1 INT; +Warnings: +Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table. +Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table. +Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT. +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Compact row_format=DYNAMIC +SET GLOBAL innodb_file_per_table=ON; +ALTER TABLE t1 ADD COLUMN f2 INT; +SHOW WARNINGS; +Level Code Message +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +t1 Dynamic row_format=DYNAMIC +# Cleanup +DROP TABLE IF EXISTS t1; diff --git a/mysql-test/suite/innodb_plugin/r/innodb-zip.result b/mysql-test/suite/innodb_plugin/r/innodb-zip.result index 21396d81ba8..fc35143b305 100644 --- a/mysql-test/suite/innodb_plugin/r/innodb-zip.result +++ b/mysql-test/suite/innodb_plugin/r/innodb-zip.result @@ -83,8 +83,6 @@ test t8 Compact test t9 Compact drop table t0,t00,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14; alter table t1 key_block_size=0; -Warnings: -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=0. alter table t1 row_format=dynamic; SELECT table_schema, table_name, row_format FROM information_schema.tables WHERE engine='innodb'; @@ -190,16 +188,9 @@ set global innodb_file_per_table = on; set global innodb_file_format = `1`; set innodb_strict_mode = off; create table t1 (id int primary key) engine = innodb key_block_size = 0; -Warnings: -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=0. drop table t1; set innodb_strict_mode = on; create table t1 (id int primary key) engine = innodb key_block_size = 0; -ERROR HY000: Can't create table 'test.t1' (errno: 1478) -show warnings; -Level Code Message -Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 0. Valid values are [1, 2, 4, 8, 16] -Error 1005 Can't create table 'test.t1' (errno: 1478) create table t2 (id int primary key) engine = innodb key_block_size = 9; ERROR HY000: Can't create table 'test.t2' (errno: 1478) show warnings; @@ -218,6 +209,7 @@ create table t11(id int primary key) engine = innodb row_format = redundant; SELECT table_schema, table_name, row_format FROM information_schema.tables WHERE engine='innodb'; table_schema table_name row_format +test t1 Compact test t10 Compact test t11 Redundant test t3 Compressed @@ -227,7 +219,7 @@ test t6 Compressed test t7 Compressed test t8 Compressed test t9 Dynamic -drop table t3, t4, t5, t6, t7, t8, t9, t10, t11; +drop table t1, t3, t4, t5, t6, t7, t8, t9, t10, t11; create table t1 (id int primary key) engine = innodb key_block_size = 8 row_format = compressed; create table t2 (id int primary key) engine = innodb @@ -253,16 +245,12 @@ Warning 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. Error 1005 Can't create table 'test.t4' (errno: 1478) create table t5 (id int primary key) engine = innodb key_block_size = 8 row_format = default; -ERROR HY000: Can't create table 'test.t5' (errno: 1478) -show warnings; -Level Code Message -Warning 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. -Error 1005 Can't create table 'test.t5' (errno: 1478) SELECT table_schema, table_name, row_format FROM information_schema.tables WHERE engine='innodb'; table_schema table_name row_format test t1 Compressed -drop table t1; +test t5 Compressed +drop table t1, t5; create table t1 (id int primary key) engine = innodb key_block_size = 9 row_format = redundant; ERROR HY000: Can't create table 'test.t1' (errno: 1478) diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug54679.result b/mysql-test/suite/innodb_plugin/r/innodb_bug54679.result deleted file mode 100644 index 14fd32ca469..00000000000 --- a/mysql-test/suite/innodb_plugin/r/innodb_bug54679.result +++ /dev/null @@ -1,91 +0,0 @@ -SET GLOBAL innodb_file_format='Barracuda'; -SET GLOBAL innodb_file_per_table=ON; -SET innodb_strict_mode=ON; -CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables -WHERE TABLE_NAME='bug54679'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug54679 Compressed row_format=COMPRESSED -ALTER TABLE bug54679 ADD COLUMN b INT; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables -WHERE TABLE_NAME='bug54679'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug54679 Compressed row_format=COMPRESSED -DROP TABLE bug54679; -CREATE TABLE bug54679 (a INT) ENGINE=InnoDB; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables -WHERE TABLE_NAME='bug54679'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug54679 Compact -ALTER TABLE bug54679 KEY_BLOCK_SIZE=1; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables -WHERE TABLE_NAME='bug54679'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug54679 Compressed KEY_BLOCK_SIZE=1 -ALTER TABLE bug54679 ROW_FORMAT=REDUNDANT; -ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE. -Error 1005 Can't create table '#sql-temporary' (errno: 1478) -DROP TABLE bug54679; -CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=REDUNDANT; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables -WHERE TABLE_NAME='bug54679'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug54679 Redundant row_format=REDUNDANT -ALTER TABLE bug54679 KEY_BLOCK_SIZE=2; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables -WHERE TABLE_NAME='bug54679'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug54679 Compressed row_format=REDUNDANT KEY_BLOCK_SIZE=2 -SET GLOBAL innodb_file_format=Antelope; -ALTER TABLE bug54679 KEY_BLOCK_SIZE=4; -ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. -Error 1005 Can't create table '#sql-temporary' (errno: 1478) -ALTER TABLE bug54679 ROW_FORMAT=DYNAMIC; -ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. -Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope. -Warning 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. -Error 1005 Can't create table '#sql-temporary' (errno: 1478) -DROP TABLE bug54679; -CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; -ERROR HY000: Can't create table 'test.bug54679' (errno: 1478) -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope. -Error 1005 Can't create table 'test.bug54679' (errno: 1478) -CREATE TABLE bug54679 (a INT) ENGINE=InnoDB; -SET GLOBAL innodb_file_format=Barracuda; -SET GLOBAL innodb_file_per_table=OFF; -ALTER TABLE bug54679 KEY_BLOCK_SIZE=4; -ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. -Error 1005 Can't create table '#sql-temporary' (errno: 1478) -ALTER TABLE bug54679 ROW_FORMAT=DYNAMIC; -ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table. -Error 1005 Can't create table '#sql-temporary' (errno: 1478) -DROP TABLE bug54679; -CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; -ERROR HY000: Can't create table 'test.bug54679' (errno: 1478) -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table. -Error 1005 Can't create table 'test.bug54679' (errno: 1478) -SET GLOBAL innodb_file_per_table=ON; -CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; -DROP TABLE bug54679; -SET GLOBAL innodb_file_format=Antelope; -SET GLOBAL innodb_file_format_check=Antelope; -SET GLOBAL innodb_file_per_table=0; diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug56632.result b/mysql-test/suite/innodb_plugin/r/innodb_bug56632.result deleted file mode 100755 index 8236b37676b..00000000000 --- a/mysql-test/suite/innodb_plugin/r/innodb_bug56632.result +++ /dev/null @@ -1,294 +0,0 @@ -SET storage_engine=InnoDB; -SET GLOBAL innodb_file_format=`Barracuda`; -SET GLOBAL innodb_file_per_table=ON; -SET SESSION innodb_strict_mode = ON; -# Test 1) CREATE with ROW_FORMAT & KEY_BLOCK_SIZE, ALTER with neither -DROP TABLE IF EXISTS bug56632; -Warnings: -Note 1051 Unknown table 'bug56632' -CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; -ERROR HY000: Can't create table 'test.bug56632' (errno: 1478) -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. -Error 1005 Can't create table 'test.bug56632' (errno: 1478) -# Test 2) CREATE with ROW_FORMAT, ALTER with KEY_BLOCK_SIZE -DROP TABLE IF EXISTS bug56632; -Warnings: -Note 1051 Unknown table 'bug56632' -CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT; -SHOW WARNINGS; -Level Code Message -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compact row_format=COMPACT -ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; -SHOW WARNINGS; -Level Code Message -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compressed row_format=COMPACT KEY_BLOCK_SIZE=1 -# Test 3) CREATE with KEY_BLOCK_SIZE, ALTER with ROW_FORMAT -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=1; -SHOW WARNINGS; -Level Code Message -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compressed KEY_BLOCK_SIZE=1 -ALTER TABLE bug56632 ROW_FORMAT=COMPACT; -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compressed KEY_BLOCK_SIZE=1 -# Test 4) CREATE with neither, ALTER with ROW_FORMAT & KEY_BLOCK_SIZE -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ); -SHOW WARNINGS; -Level Code Message -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compact -ALTER TABLE bug56632 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compact -# Test 5) CREATE with KEY_BLOCK_SIZE=3 (invalid). -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; -ERROR HY000: Can't create table 'test.bug56632' (errno: 1478) -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 3. Valid values are [1, 2, 4, 8, 16] -Error 1005 Can't create table 'test.bug56632' (errno: 1478) -SET SESSION innodb_strict_mode = OFF; -# Test 6) CREATE with ROW_FORMAT & KEY_BLOCK_SIZE, ALTER with neither -DROP TABLE IF EXISTS bug56632; -Warnings: -Note 1051 Unknown table 'bug56632' -CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; -Warnings: -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compact row_format=COMPACT KEY_BLOCK_SIZE=1 -ALTER TABLE bug56632 ADD COLUMN f1 INT; -Warnings: -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL, - `f1` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compact row_format=COMPACT KEY_BLOCK_SIZE=1 -# Test 7) CREATE with ROW_FORMAT, ALTER with KEY_BLOCK_SIZE -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT; -SHOW WARNINGS; -Level Code Message -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compact row_format=COMPACT -ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; -SHOW WARNINGS; -Level Code Message -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compressed row_format=COMPACT KEY_BLOCK_SIZE=1 -# Test 8) CREATE with KEY_BLOCK_SIZE, ALTER with ROW_FORMAT -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=1; -SHOW WARNINGS; -Level Code Message -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compressed KEY_BLOCK_SIZE=1 -ALTER TABLE bug56632 ROW_FORMAT=COMPACT; -Warnings: -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compact row_format=COMPACT KEY_BLOCK_SIZE=1 -# Test 9) CREATE with neither, ALTER with ROW_FORMAT & KEY_BLOCK_SIZE -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ); -SHOW WARNINGS; -Level Code Message -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compact -ALTER TABLE bug56632 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; -Warnings: -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=1 unless ROW_FORMAT=COMPRESSED. -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compact row_format=COMPACT KEY_BLOCK_SIZE=1 -# Test 10) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with neither. -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; -Warnings: -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=3 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compact KEY_BLOCK_SIZE=3 -ALTER TABLE bug56632 ADD COLUMN f1 INT; -Warnings: -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL, - `f1` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=3 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compact KEY_BLOCK_SIZE=3 -# Test 11) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with ROW_FORMAT=COMPACT. -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; -Warnings: -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=3 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compact KEY_BLOCK_SIZE=3 -ALTER TABLE bug56632 ROW_FORMAT=COMPACT; -Warnings: -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=3 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compact row_format=COMPACT KEY_BLOCK_SIZE=3 -# Test 12) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with KEY_BLOCK_SIZE=1. -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; -Warnings: -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. -SHOW WARNINGS; -Level Code Message -Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=3. -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=3 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compact KEY_BLOCK_SIZE=3 -ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; -SHOW WARNINGS; -Level Code Message -SHOW CREATE TABLE bug56632; -Table Create Table -bug56632 CREATE TABLE `bug56632` ( - `i` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1 -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -TABLE_NAME ROW_FORMAT CREATE_OPTIONS -bug56632 Compressed KEY_BLOCK_SIZE=1 -# Cleanup -DROP TABLE IF EXISTS bug56632; diff --git a/mysql-test/suite/innodb_plugin/t/innodb-create-options.test b/mysql-test/suite/innodb_plugin/t/innodb-create-options.test new file mode 100755 index 00000000000..2f95ccc45cb --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb-create-options.test @@ -0,0 +1,575 @@ +# Tests for various combinations of ROW_FORMAT and KEY_BLOCK_SIZE +# Related bugs; +# Bug#54679: ALTER TABLE causes compressed row_format to revert to compact +# Bug#56628: ALTER TABLE .. KEY_BLOCK_SIZE=0 produces untrue warning or unnecessary error +# Bug#56632: ALTER TABLE implicitly changes ROW_FORMAT to COMPRESSED +# Rules for interpreting CREATE_OPTIONS +# 1) Create options on an ALTER are added to the options on the +# previous CREATE or ALTER statements. +# 2) KEY_BLOCK_SIZE=0 is considered a unspecified value. +# If the current ROW_FORMAT has explicitly been set to COMPRESSED, +# InnoDB will use a default value of 8. Otherwise KEY_BLOCK_SIZE +# will not be used. +# 3) ROW_FORMAT=DEFAULT allows InnoDB to choose its own default, COMPACT. +# 4) ROW_FORMAT=DEFAULT and KEY_BLOCK_SIZE=0 can be used at any time to +# unset or erase the values persisted in the MySQL dictionary and +# by SHOW CTREATE TABLE. +# 5) When incompatible values for ROW_FORMAT and KEY_BLOCK_SIZE are +# both explicitly given, the ROW_FORMAT is always used in non-strict +# mode. +# 6) InnoDB will automatically convert a table to COMPRESSED only if a +# valid non-zero KEY_BLOCK_SIZE has been given and ROW_FORMAT=DEFAULT +# or has not been used on a previous CREATE TABLE or ALTER TABLE. +# 7) InnoDB strict mode is designed to prevent incompatible create +# options from being used together. +# 8) The non-strict behavior is intended to permit you to import a +# mysqldump file into a database that does not support compressed +# tables, even if the source database contained compressed tables. +# All invalid values and/or incompatible combinations of ROW_FORMAT +# and KEY_BLOCK_SIZE are automatically corrected +# +# *** innodb_strict_mode=ON *** +# 1) Valid ROW_FORMATs are COMPRESSED, COMPACT, DEFAULT, DYNAMIC +# & REDUNDANT. All others are rejected. +# 2) Valid KEY_BLOCK_SIZEs are 0,1,2,4,8,16. All others are rejected. +# 3) KEY_BLOCK_SIZE=0 can be used to set it to 'unspecified'. +# 4) KEY_BLOCK_SIZE=1,2,4,8 & 16 are incompatible with COMPACT, DYNAMIC & +# REDUNDANT. +# 5) KEY_BLOCK_SIZE=1,2,4,8 & 16 as well as ROW_FORMAT=COMPRESSED and +# ROW_FORMAT=DYNAMIC are incompatible with innodb_file_format=Antelope +# and innodb_file_per_table=OFF +# 6) KEY_BLOCK_SIZE on an ALTER must occur with ROW_FORMAT=COMPRESSED +# or ROW_FORMAT=DEFAULT if the ROW_FORMAT was previously specified +# as COMPACT, DYNAMIC or REDUNDANT. +# 7) KEY_BLOCK_SIZE on an ALTER can occur without a ROW_FORMAT if the +# previous ROW_FORMAT was DEFAULT, COMPRESSED, or unspecified. +# +# *** innodb_strict_mode=OFF *** +# 1. Ignore a bad KEY_BLOCK_SIZE, defaulting it to 8. +# 2. Ignore a bad ROW_FORMAT, defaulting to COMPACT. +# 3. Ignore a valid KEY_BLOCK_SIZE when an incompatible but valid +# ROW_FORMAT is specified. +# 4. If innodb_file_format=Antelope or innodb_file_per_table=OFF +# it will ignore ROW_FORMAT=COMPRESSED or DYNAMIC and it will +# ignore all non-zero KEY_BLOCK_SIZEs. +# +# See InnoDB documentation page "SQL Compression Syntax Warnings and Errors" + +-- source include/have_innodb_plugin.inc +SET storage_engine=InnoDB; + +--disable_query_log +# These values can change during the test +LET $innodb_file_format_orig=`select @@innodb_file_format`; +LET $innodb_file_format_check_orig=`select @@innodb_file_format_check`; +LET $innodb_file_per_table_orig=`select @@innodb_file_per_table`; +LET $innodb_strict_mode_orig=`select @@session.innodb_strict_mode`; +--enable_query_log + +SET GLOBAL innodb_file_format=`Barracuda`; +SET GLOBAL innodb_file_per_table=ON; + +# The first half of these tests are with strict mode ON. +SET SESSION innodb_strict_mode = ON; + +--echo # Test 1) StrictMode=ON, CREATE and ALTER with each ROW_FORMAT & KEY_BLOCK_SIZE=0 +--echo # KEY_BLOCK_SIZE=0 means 'no KEY_BLOCK_SIZE is specified' +DROP TABLE IF EXISTS t1; +--echo # 'FIXED' is sent to InnoDB since it is used by MyISAM. +--echo # But it is an invalid mode in InnoDB +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1 ( i INT ) ROW_FORMAT=FIXED; +SHOW WARNINGS; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 ROW_FORMAT=FIXED KEY_BLOCK_SIZE=0; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; + + + +--echo # Test 2) StrictMode=ON, CREATE with each ROW_FORMAT & a valid non-zero KEY_BLOCK_SIZE +--echo # KEY_BLOCK_SIZE is incompatible with COMPACT, REDUNDANT, & DYNAMIC +DROP TABLE IF EXISTS t1; +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1 ( i INT ) ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=2; +SHOW WARNINGS; +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=4; +SHOW WARNINGS; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ADD COLUMN f1 INT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ADD COLUMN f1 INT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; + + +--echo # Test 3) StrictMode=ON, ALTER with each ROW_FORMAT & a valid non-zero KEY_BLOCK_SIZE +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ); +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 ROW_FORMAT=FIXED KEY_BLOCK_SIZE=1; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=2; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=4; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=8; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; + + +--echo # Test 4) StrictMode=ON, CREATE with ROW_FORMAT=COMPACT, ALTER with a valid non-zero KEY_BLOCK_SIZE +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 KEY_BLOCK_SIZE=2; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +ALTER TABLE t1 ROW_FORMAT=REDUNDANT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 KEY_BLOCK_SIZE=4; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +ALTER TABLE t1 ROW_FORMAT=DYNAMIC; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 KEY_BLOCK_SIZE=8; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +ALTER TABLE t1 ROW_FORMAT=COMPRESSED; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT; +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; + +--echo # Test 5) StrictMode=ON, CREATE with a valid KEY_BLOCK_SIZE +--echo # ALTER with each ROW_FORMAT +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) KEY_BLOCK_SIZE=2; +SHOW CREATE TABLE t1; +ALTER TABLE t1 ADD COLUMN f1 INT; +SHOW CREATE TABLE t1; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 ROW_FORMAT=COMPACT; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 ROW_FORMAT=REDUNDANT; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 ROW_FORMAT=DYNAMIC; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +ALTER TABLE t1 ROW_FORMAT=COMPRESSED; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=COMPACT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; + +--echo # Test 6) StrictMode=ON, CREATE with an invalid KEY_BLOCK_SIZE. +DROP TABLE IF EXISTS t1; +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1 ( i INT ) KEY_BLOCK_SIZE=9; +SHOW WARNINGS; + +--echo # Test 7) StrictMode=ON, Make sure ROW_FORMAT= COMPRESSED & DYNAMIC and +--echo # and a valid non-zero KEY_BLOCK_SIZE are rejected with Antelope +--echo # and that they can be set to default values during strict mode. +SET GLOBAL innodb_file_format=Antelope; +DROP TABLE IF EXISTS t1; +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1 ( i INT ) KEY_BLOCK_SIZE=4; +SHOW WARNINGS; +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED; +SHOW WARNINGS; +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC; +SHOW WARNINGS; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=REDUNDANT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DEFAULT; +SHOW WARNINGS; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 KEY_BLOCK_SIZE=8; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 ROW_FORMAT=COMPRESSED; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 ROW_FORMAT=DYNAMIC; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +SET GLOBAL innodb_file_format=Barracuda; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; +SET GLOBAL innodb_file_format=Antelope; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 ADD COLUMN f1 INT; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +ALTER TABLE t1 ADD COLUMN f2 INT; +SHOW WARNINGS; +SET GLOBAL innodb_file_format=Barracuda; + +--echo # Test 8) StrictMode=ON, Make sure ROW_FORMAT= COMPRESSED & DYNAMIC and +--echo # and a valid non-zero KEY_BLOCK_SIZE are rejected with +--echo # innodb_file_per_table=OFF and that they can be set to default +--echo # values during strict mode. +SET GLOBAL innodb_file_per_table=OFF; +DROP TABLE IF EXISTS t1; +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1 ( i INT ) KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED; +SHOW WARNINGS; +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC; +SHOW WARNINGS; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=REDUNDANT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DEFAULT; +SHOW WARNINGS; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 KEY_BLOCK_SIZE=1; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 ROW_FORMAT=COMPRESSED; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 ROW_FORMAT=DYNAMIC; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +ALTER TABLE t1 ROW_FORMAT=COMPACT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=REDUNDANT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=DEFAULT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +SET GLOBAL innodb_file_per_table=ON; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; +SET GLOBAL innodb_file_per_table=OFF; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE t1 ADD COLUMN f1 INT; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +ALTER TABLE t1 ADD COLUMN f2 INT; +SHOW WARNINGS; +SET GLOBAL innodb_file_per_table=ON; + +--echo ################################################## +SET SESSION innodb_strict_mode = OFF; + +--echo # Test 9) StrictMode=OFF, CREATE and ALTER with each ROW_FORMAT & KEY_BLOCK_SIZE=0 +--echo # KEY_BLOCK_SIZE=0 means 'no KEY_BLOCK_SIZE is specified' +--echo # 'FIXED' is sent to InnoDB since it is used by MyISAM. +--echo # It is an invalid mode in InnoDB, use COMPACT +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=FIXED; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=FIXED KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; + +--echo # Test 10) StrictMode=OFF, CREATE with each ROW_FORMAT & a valid KEY_BLOCK_SIZE +--echo # KEY_BLOCK_SIZE is ignored with COMPACT, REDUNDANT, & DYNAMIC +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=2; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=4; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ADD COLUMN f1 INT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ADD COLUMN f1 INT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; + + +--echo # Test 11) StrictMode=OFF, ALTER with each ROW_FORMAT & a valid KEY_BLOCK_SIZE +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ); +ALTER TABLE t1 ROW_FORMAT=FIXED KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ); +ALTER TABLE t1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=2; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ); +ALTER TABLE t1 ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=4; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ); +ALTER TABLE t1 ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=8; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ); +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; + + +--echo # Test 12) StrictMode=OFF, CREATE with ROW_FORMAT=COMPACT, ALTER with a valid KEY_BLOCK_SIZE +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 KEY_BLOCK_SIZE=2; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=REDUNDANT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=DYNAMIC; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=COMPRESSED; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 KEY_BLOCK_SIZE=4; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT; +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=8; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; + +--echo # Test 13) StrictMode=OFF, CREATE with a valid KEY_BLOCK_SIZE +--echo # ALTER with each ROW_FORMAT +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +SHOW CREATE TABLE t1; +ALTER TABLE t1 ADD COLUMN f1 INT; +SHOW WARNINGS; +SHOW CREATE TABLE t1; +ALTER TABLE t1 ROW_FORMAT=COMPACT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=REDUNDANT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=DYNAMIC; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=COMPRESSED; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +ALTER TABLE t1 ROW_FORMAT=COMPACT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; + +--echo # Test 14) StrictMode=OFF, CREATE with an invalid KEY_BLOCK_SIZE, it defaults to 8 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) KEY_BLOCK_SIZE=15; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; + +--echo # Test 15) StrictMode=OFF, Make sure ROW_FORMAT= COMPRESSED & DYNAMIC and a +--echo valid KEY_BLOCK_SIZE are remembered but not used when ROW_FORMAT +--echo is reverted to Antelope and then used again when ROW_FORMAT=Barracuda. +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +SET GLOBAL innodb_file_format=Antelope; +ALTER TABLE t1 ADD COLUMN f1 INT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +SET GLOBAL innodb_file_format=Barracuda; +ALTER TABLE t1 ADD COLUMN f2 INT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +SET GLOBAL innodb_file_format=Antelope; +ALTER TABLE t1 ADD COLUMN f1 INT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +SET GLOBAL innodb_file_format=Barracuda; +ALTER TABLE t1 ADD COLUMN f2 INT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; + +--echo # Test 16) StrictMode=OFF, Make sure ROW_FORMAT= COMPRESSED & DYNAMIC and a +--echo valid KEY_BLOCK_SIZE are remembered but not used when innodb_file_per_table=OFF +--echo and then used again when innodb_file_per_table=ON. +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +SET GLOBAL innodb_file_per_table=OFF; +ALTER TABLE t1 ADD COLUMN f1 INT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +SET GLOBAL innodb_file_per_table=ON; +ALTER TABLE t1 ADD COLUMN f2 INT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +SET GLOBAL innodb_file_per_table=OFF; +ALTER TABLE t1 ADD COLUMN f1 INT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; +SET GLOBAL innodb_file_per_table=ON; +ALTER TABLE t1 ADD COLUMN f2 INT; +SHOW WARNINGS; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; + + +--echo # Cleanup +DROP TABLE IF EXISTS t1; + +--disable_query_log +EVAL SET GLOBAL innodb_file_format=$innodb_file_format_orig; +EVAL SET GLOBAL innodb_file_format_check=$innodb_file_format_check_orig; +EVAL SET GLOBAL innodb_file_per_table=$innodb_file_per_table_orig; +EVAL SET SESSION innodb_strict_mode=$innodb_strict_mode_orig; +--enable_query_log + diff --git a/mysql-test/suite/innodb_plugin/t/innodb-zip.test b/mysql-test/suite/innodb_plugin/t/innodb-zip.test index 4980af437e6..8c1ef1f5467 100644 --- a/mysql-test/suite/innodb_plugin/t/innodb-zip.test +++ b/mysql-test/suite/innodb_plugin/t/innodb-zip.test @@ -173,9 +173,7 @@ set innodb_strict_mode = on; #Test different values of KEY_BLOCK_SIZE ---error ER_CANT_CREATE_TABLE create table t1 (id int primary key) engine = innodb key_block_size = 0; -show warnings; --error ER_CANT_CREATE_TABLE create table t2 (id int primary key) engine = innodb key_block_size = 9; @@ -196,7 +194,7 @@ create table t11(id int primary key) engine = innodb row_format = redundant; SELECT table_schema, table_name, row_format FROM information_schema.tables WHERE engine='innodb'; -drop table t3, t4, t5, t6, t7, t8, t9, t10, t11; +drop table t1, t3, t4, t5, t6, t7, t8, t9, t10, t11; #test different values of ROW_FORMAT with KEY_BLOCK_SIZE create table t1 (id int primary key) engine = innodb @@ -217,14 +215,12 @@ create table t4 (id int primary key) engine = innodb key_block_size = 8 row_format = dynamic; show warnings; ---error ER_CANT_CREATE_TABLE create table t5 (id int primary key) engine = innodb key_block_size = 8 row_format = default; -show warnings; SELECT table_schema, table_name, row_format FROM information_schema.tables WHERE engine='innodb'; -drop table t1; +drop table t1, t5; #test multiple errors --error ER_CANT_CREATE_TABLE diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug54679.test b/mysql-test/suite/innodb_plugin/t/innodb_bug54679.test deleted file mode 100644 index 863d9847ac1..00000000000 --- a/mysql-test/suite/innodb_plugin/t/innodb_bug54679.test +++ /dev/null @@ -1,97 +0,0 @@ -# Test Bug #54679 alter table causes compressed row_format to revert to compact - ---source include/have_innodb_plugin.inc - -let $file_format=`select @@innodb_file_format`; -let $file_format_check=`select @@innodb_file_format_check`; -let $file_per_table=`select @@innodb_file_per_table`; -SET GLOBAL innodb_file_format='Barracuda'; -SET GLOBAL innodb_file_per_table=ON; -SET innodb_strict_mode=ON; - -CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables -WHERE TABLE_NAME='bug54679'; - -# The ROW_FORMAT of the table should be preserved when it is not specified -# in ALTER TABLE. -ALTER TABLE bug54679 ADD COLUMN b INT; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables -WHERE TABLE_NAME='bug54679'; - -DROP TABLE bug54679; - -# Check that the ROW_FORMAT conversion to/from COMPRESSED works. - -CREATE TABLE bug54679 (a INT) ENGINE=InnoDB; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables -WHERE TABLE_NAME='bug54679'; - -# KEY_BLOCK_SIZE implies COMPRESSED. -ALTER TABLE bug54679 KEY_BLOCK_SIZE=1; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables -WHERE TABLE_NAME='bug54679'; - ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ ---error ER_CANT_CREATE_TABLE -ALTER TABLE bug54679 ROW_FORMAT=REDUNDANT; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ -SHOW WARNINGS; -DROP TABLE bug54679; -CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=REDUNDANT; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables -WHERE TABLE_NAME='bug54679'; - -ALTER TABLE bug54679 KEY_BLOCK_SIZE=2; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables -WHERE TABLE_NAME='bug54679'; - -# This prevents other than REDUNDANT or COMPACT ROW_FORMAT for new tables. -SET GLOBAL innodb_file_format=Antelope; - ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ ---error ER_CANT_CREATE_TABLE -ALTER TABLE bug54679 KEY_BLOCK_SIZE=4; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ -SHOW WARNINGS; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ ---error ER_CANT_CREATE_TABLE -ALTER TABLE bug54679 ROW_FORMAT=DYNAMIC; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ -SHOW WARNINGS; -DROP TABLE bug54679; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ ---error ER_CANT_CREATE_TABLE -CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ -SHOW WARNINGS; -CREATE TABLE bug54679 (a INT) ENGINE=InnoDB; - -SET GLOBAL innodb_file_format=Barracuda; -# This will prevent ROW_FORMAT=COMPRESSED, because the system tablespace -# cannot be compressed. -SET GLOBAL innodb_file_per_table=OFF; - ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ ---error ER_CANT_CREATE_TABLE -ALTER TABLE bug54679 KEY_BLOCK_SIZE=4; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ -SHOW WARNINGS; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ ---error ER_CANT_CREATE_TABLE -ALTER TABLE bug54679 ROW_FORMAT=DYNAMIC; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ -SHOW WARNINGS; -DROP TABLE bug54679; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ ---error ER_CANT_CREATE_TABLE -CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ -SHOW WARNINGS; -SET GLOBAL innodb_file_per_table=ON; -CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; -DROP TABLE bug54679; - -EVAL SET GLOBAL innodb_file_format=$file_format; -EVAL SET GLOBAL innodb_file_format_check=$file_format_check; -EVAL SET GLOBAL innodb_file_per_table=$file_per_table; diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug56632.test b/mysql-test/suite/innodb_plugin/t/innodb_bug56632.test deleted file mode 100755 index 7f1c41cddfa..00000000000 --- a/mysql-test/suite/innodb_plugin/t/innodb_bug56632.test +++ /dev/null @@ -1,216 +0,0 @@ -# -# Bug#56632: ALTER TABLE implicitly changes ROW_FORMAT to COMPRESSED -# http://bugs.mysql.com/56632 -# -# Innodb automatically uses compressed mode when the KEY_BLOCK_SIZE -# parameter is used, except if the ROW_FORMAT is also specified, in -# which case the KEY_BLOCK_SIZE is ignored and a warning is shown. -# But Innodb was getting confused when neither of those parameters -# was used on the ALTER statement after they were both used on the -# CREATE. -# -# This will test the results of all 4 combinations of these two -# parameters of the CREATE and ALTER. -# -# Tests 1-5 use INNODB_STRICT_MODE=1 which returns an error -# if there is anything wrong with the statement. -# -# 1) CREATE with ROW_FORMAT=COMPACT & KEY_BLOCK_SIZE=1, ALTER with neither. -# Result; CREATE; fails with error ER_CANT_CREATE_TABLE -# 2) CREATE with ROW_FORMAT=COMPACT, ALTER with KEY_BLOCK_SIZE=1 -# Result; CREATE succeeds, -# ALTER quietly converts ROW_FORMAT to compressed. -# 3) CREATE with KEY_BLOCK_SIZE=1, ALTER with ROW_FORMAT=COMPACT -# Result; CREATE quietly converts ROW_FORMAT to compressed, -# ALTER fails with error ER_CANT_CREATE_TABLE. -# 4) CREATE with neither, ALTER with ROW_FORMAT=COMPACT & KEY_BLOCK_SIZE=1 -# Result; CREATE succeeds, -# ALTER; fails with error ER_CANT_CREATE_TABLE -# 5) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with neither. -# Result; CREATE; fails with error ER_CANT_CREATE_TABLE -# -# Tests 6-11 use INNODB_STRICT_MODE=0 which automatically makes -# adjustments if the prameters are incompatible. -# -# 6) CREATE with ROW_FORMAT=COMPACT & KEY_BLOCK_SIZE=1, ALTER with neither. -# Result; CREATE succeeds, warns that KEY_BLOCK_SIZE is ignored. -# ALTER succeeds, no warnings. -# 7) CREATE with ROW_FORMAT=COMPACT, ALTER with KEY_BLOCK_SIZE=1 -# Result; CREATE succeeds, -# ALTER quietly converts ROW_FORMAT to compressed. -# 8) CREATE with KEY_BLOCK_SIZE=1, ALTER with ROW_FORMAT=COMPACT -# Result; CREATE quietly converts ROW_FORMAT to compressed, -# ALTER succeeds, warns that KEY_BLOCK_SIZE is ignored. -# 9) CREATE with neither, ALTER with ROW_FORMAT=COMPACT & KEY_BLOCK_SIZE=1 -# Result; CREATE succeeds, -# ALTER succeeds, warns that KEY_BLOCK_SIZE is ignored. -# 10) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with neither. -# Result; CREATE succeeds, warns that KEY_BLOCK_SIZE=3 is ignored. -# ALTER succeeds, warns that KEY_BLOCK_SIZE=3 is ignored. -# 11) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with ROW_FORMAT=COMPACT. -# Result; CREATE succeeds, warns that KEY_BLOCK_SIZE=3 is ignored. -# ALTER succeeds, warns that KEY_BLOCK_SIZE=3 is ignored. -# 12) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with KEY_BLOCK_SIZE=1. -# Result; CREATE succeeds, warns that KEY_BLOCK_SIZE=3 is ignored. -# ALTER succeeds, quietly converts ROW_FORMAT to compressed. - --- source include/have_innodb_plugin.inc - -SET storage_engine=InnoDB; - ---disable_query_log -# These values can change during the test -LET $innodb_file_format_orig=`select @@innodb_file_format`; -LET $innodb_file_format_check_orig=`select @@innodb_file_format_check`; -LET $innodb_file_per_table_orig=`select @@innodb_file_per_table`; -LET $innodb_strict_mode_orig=`select @@session.innodb_strict_mode`; ---enable_query_log - -SET GLOBAL innodb_file_format=`Barracuda`; -SET GLOBAL innodb_file_per_table=ON; - -# Innodb strict mode will cause an error on the CREATE or ALTER when; -# 1. both ROW_FORMAT=COMPACT and KEY_BLOCK_SIZE=1, -# 2. KEY_BLOCK_SIZE is not a valid number (0,1,2,4,8,16). -# With innodb_strict_mode = OFF, These errors are corrected -# and just a warning is returned. -SET SESSION innodb_strict_mode = ON; - ---echo # Test 1) CREATE with ROW_FORMAT & KEY_BLOCK_SIZE, ALTER with neither -DROP TABLE IF EXISTS bug56632; ---error ER_CANT_CREATE_TABLE -CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; -SHOW WARNINGS; - ---echo # Test 2) CREATE with ROW_FORMAT, ALTER with KEY_BLOCK_SIZE -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT; -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; - ---echo # Test 3) CREATE with KEY_BLOCK_SIZE, ALTER with ROW_FORMAT -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=1; -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; ---disable_result_log ---error ER_CANT_CREATE_TABLE -ALTER TABLE bug56632 ROW_FORMAT=COMPACT; ---enable_result_log -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; - ---echo # Test 4) CREATE with neither, ALTER with ROW_FORMAT & KEY_BLOCK_SIZE -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ); -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; ---disable_result_log ---error ER_CANT_CREATE_TABLE -ALTER TABLE bug56632 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; ---enable_result_log -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; - ---echo # Test 5) CREATE with KEY_BLOCK_SIZE=3 (invalid). -DROP TABLE IF EXISTS bug56632; ---error ER_CANT_CREATE_TABLE -CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; -SHOW WARNINGS; - -SET SESSION innodb_strict_mode = OFF; - ---echo # Test 6) CREATE with ROW_FORMAT & KEY_BLOCK_SIZE, ALTER with neither -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -ALTER TABLE bug56632 ADD COLUMN f1 INT; -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; - ---echo # Test 7) CREATE with ROW_FORMAT, ALTER with KEY_BLOCK_SIZE -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ) ROW_FORMAT=COMPACT; -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; - ---echo # Test 8) CREATE with KEY_BLOCK_SIZE, ALTER with ROW_FORMAT -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=1; -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -ALTER TABLE bug56632 ROW_FORMAT=COMPACT; -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; - ---echo # Test 9) CREATE with neither, ALTER with ROW_FORMAT & KEY_BLOCK_SIZE -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ); -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -ALTER TABLE bug56632 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; - ---echo # Test 10) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with neither. -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -ALTER TABLE bug56632 ADD COLUMN f1 INT; -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; - ---echo # Test 11) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with ROW_FORMAT=COMPACT. -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -ALTER TABLE bug56632 ROW_FORMAT=COMPACT; -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; - ---echo # Test 12) CREATE with KEY_BLOCK_SIZE=3 (invalid), ALTER with KEY_BLOCK_SIZE=1. -DROP TABLE IF EXISTS bug56632; -CREATE TABLE bug56632 ( i INT ) KEY_BLOCK_SIZE=3; -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; -ALTER TABLE bug56632 KEY_BLOCK_SIZE=1; -SHOW WARNINGS; -SHOW CREATE TABLE bug56632; -SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 'bug56632'; - ---echo # Cleanup -DROP TABLE IF EXISTS bug56632; - ---disable_query_log -EVAL SET GLOBAL innodb_file_per_table=$innodb_file_per_table_orig; -EVAL SET GLOBAL innodb_file_format=$innodb_file_format_orig; -EVAL SET GLOBAL innodb_file_format_check=$innodb_file_format_check_orig; -EVAL SET SESSION innodb_strict_mode=$innodb_strict_mode_orig; ---enable_query_log - diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index 99d4f294f81..ff2f46256e6 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -6290,6 +6290,33 @@ create_clustered_index_when_no_primary( return(error); } +/*****************************************************************//** +Return a display name for the row format +@return row format name */ + +const char *get_row_format_name( +/*============================*/ +enum row_type row_format) /*!< in: Row Format */ +{ + switch (row_format) { + case ROW_TYPE_COMPACT: + return("COMPACT"); + case ROW_TYPE_COMPRESSED: + return("COMPRESSED"); + case ROW_TYPE_DYNAMIC: + return("DYNAMIC"); + case ROW_TYPE_REDUNDANT: + return("REDUNDANT"); + case ROW_TYPE_DEFAULT: + return("DEFAULT"); + case ROW_TYPE_FIXED: + return("FIXED"); + default: + break; + } + return("NOT USED"); +} + /*****************************************************************//** Validates the create options. We may build on this function in future. For now, it checks two specifiers: @@ -6305,9 +6332,9 @@ create_options_are_valid( columns and indexes */ HA_CREATE_INFO* create_info) /*!< in: create info. */ { - ibool kbs_specified = FALSE; + ibool kbs_specified = FALSE; ibool ret = TRUE; - + enum row_type row_type = form->s->row_type; ut_ad(thd != NULL); @@ -6316,13 +6343,28 @@ create_options_are_valid( return(TRUE); } + /* Check for a valid Innodb ROW_FORMAT specifier. For example, + ROW_TYPE_FIXED can be sent to Innodb */ + switch (row_type) { + case ROW_TYPE_COMPACT: + case ROW_TYPE_COMPRESSED: + case ROW_TYPE_DYNAMIC: + case ROW_TYPE_REDUNDANT: + case ROW_TYPE_DEFAULT: + break; + default: + push_warning( + thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: invalid ROW_FORMAT specifier."); + ret = FALSE; + } + ut_ad(form != NULL); ut_ad(create_info != NULL); - /* First check if KEY_BLOCK_SIZE was specified. */ - if (create_info->key_block_size - || (create_info->used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE)) { - + /* First check if a non-zero KEY_BLOCK_SIZE was specified. */ + if (create_info->key_block_size) { kbs_specified = TRUE; switch (create_info->key_block_size) { case 1: @@ -6333,13 +6375,12 @@ create_options_are_valid( /* Valid value. */ break; default: - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: invalid" - " KEY_BLOCK_SIZE = %lu." - " Valid values are" - " [1, 2, 4, 8, 16]", - create_info->key_block_size); + push_warning_printf( + thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: invalid KEY_BLOCK_SIZE = %lu." + " Valid values are [1, 2, 4, 8, 16]", + create_info->key_block_size); ret = FALSE; } } @@ -6347,109 +6388,67 @@ create_options_are_valid( /* If KEY_BLOCK_SIZE was specified, check for its dependencies. */ if (kbs_specified && !srv_file_per_table) { - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: KEY_BLOCK_SIZE" - " requires innodb_file_per_table."); + push_warning( + thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: KEY_BLOCK_SIZE" + " requires innodb_file_per_table."); ret = FALSE; } if (kbs_specified && srv_file_format < DICT_TF_FORMAT_ZIP) { - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: KEY_BLOCK_SIZE" - " requires innodb_file_format >" - " Antelope."); + push_warning( + thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: KEY_BLOCK_SIZE requires" + " innodb_file_format > Antelope."); ret = FALSE; } - /* Now check for ROW_FORMAT specifier. */ - if (create_info->used_fields & HA_CREATE_USED_ROW_FORMAT) { - switch (form->s->row_type) { - const char* row_format_name; - case ROW_TYPE_COMPRESSED: - case ROW_TYPE_DYNAMIC: - row_format_name - = form->s->row_type == ROW_TYPE_COMPRESSED - ? "COMPRESSED" - : "DYNAMIC"; - - /* These two ROW_FORMATs require srv_file_per_table - and srv_file_format > Antelope */ - if (!srv_file_per_table) { - push_warning_printf( - thd, - MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: ROW_FORMAT=%s" - " requires innodb_file_per_table.", - row_format_name); - ret = FALSE; - } - - if (srv_file_format < DICT_TF_FORMAT_ZIP) { - push_warning_printf( - thd, - MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: ROW_FORMAT=%s" - " requires innodb_file_format >" - " Antelope.", - row_format_name); - ret = FALSE; - } - - /* Cannot specify KEY_BLOCK_SIZE with - ROW_FORMAT = DYNAMIC. - However, we do allow COMPRESSED to be - specified with KEY_BLOCK_SIZE. */ - if (kbs_specified - && form->s->row_type == ROW_TYPE_DYNAMIC) { - push_warning_printf( - thd, - MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: cannot specify" - " ROW_FORMAT = DYNAMIC with" - " KEY_BLOCK_SIZE."); - ret = FALSE; - } - - break; - - case ROW_TYPE_REDUNDANT: - case ROW_TYPE_COMPACT: - case ROW_TYPE_DEFAULT: - /* Default is COMPACT. */ - row_format_name - = form->s->row_type == ROW_TYPE_REDUNDANT - ? "REDUNDANT" - : "COMPACT"; - - /* Cannot specify KEY_BLOCK_SIZE with these - format specifiers. */ - if (kbs_specified) { - push_warning_printf( - thd, - MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: cannot specify" - " ROW_FORMAT = %s with" - " KEY_BLOCK_SIZE.", - row_format_name); - ret = FALSE; - } - - break; - - default: - push_warning(thd, - MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: invalid ROW_FORMAT specifier."); - ret = FALSE; - + switch (row_type) { + case ROW_TYPE_COMPRESSED: + case ROW_TYPE_DYNAMIC: + /* These two ROW_FORMATs require srv_file_per_table + and srv_file_format > Antelope */ + if (!srv_file_per_table) { + push_warning_printf( + thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: ROW_FORMAT=%s" + " requires innodb_file_per_table.", + get_row_format_name(row_type)); + ret = FALSE; } + + if (srv_file_format < DICT_TF_FORMAT_ZIP) { + push_warning_printf( + thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: ROW_FORMAT=%s requires" + " innodb_file_format > Antelope.", + get_row_format_name(row_type)); + ret = FALSE; + } + default: + break; + } + + switch (row_type) { + case ROW_TYPE_REDUNDANT: + case ROW_TYPE_COMPACT: + case ROW_TYPE_DYNAMIC: + /* KEY_BLOCK_SIZE is only allowed with Compressed or Default */ + if (kbs_specified) { + push_warning_printf( + thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: cannot specify ROW_FORMAT = %s" + " with KEY_BLOCK_SIZE.", + get_row_format_name(row_type)); + ret = FALSE; + } + default: + break; } return(ret); @@ -6575,8 +6574,7 @@ ha_innobase::create( goto cleanup; } - if (create_info->key_block_size - || (create_info->used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE)) { + if (create_info->key_block_size) { /* Determine the page_zip.ssize corresponding to the requested page size (key_block_size) in kilobytes. */ @@ -6597,38 +6595,39 @@ ha_innobase::create( } if (!srv_file_per_table) { - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: KEY_BLOCK_SIZE" - " requires innodb_file_per_table."); + push_warning( + thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: KEY_BLOCK_SIZE" + " requires innodb_file_per_table."); flags = 0; } if (file_format < DICT_TF_FORMAT_ZIP) { - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: KEY_BLOCK_SIZE" - " requires innodb_file_format >" - " Antelope."); + push_warning( + thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: KEY_BLOCK_SIZE requires" + " innodb_file_format > Antelope."); flags = 0; } if (!flags) { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: ignoring" - " KEY_BLOCK_SIZE=%lu.", - create_info->key_block_size); + push_warning_printf( + thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: ignoring" + " KEY_BLOCK_SIZE=%lu.", + create_info->key_block_size); } } row_type = form->s->row_type; if (flags) { - /* if KEY_BLOCK_SIZE was specified on this statement and - ROW_FORMAT was not, automatically change ROW_FORMAT to COMPRESSED.*/ - if ( (create_info->used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE) - && !(create_info->used_fields & HA_CREATE_USED_ROW_FORMAT)) { + /* if ROW_FORMAT is set to default, + automatically change it to COMPRESSED.*/ + if (row_type == ROW_TYPE_DEFAULT) { row_type = ROW_TYPE_COMPRESSED; } else if (row_type != ROW_TYPE_COMPRESSED) { /* ROW_FORMAT other than COMPRESSED @@ -6638,8 +6637,7 @@ ha_innobase::create( such combinations can be obtained with ALTER TABLE anyway. */ push_warning_printf( - thd, - MYSQL_ERROR::WARN_LEVEL_WARN, + thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, "InnoDB: ignoring KEY_BLOCK_SIZE=%lu" " unless ROW_FORMAT=COMPRESSED.", @@ -6664,33 +6662,24 @@ ha_innobase::create( } switch (row_type) { - const char* row_format_name; case ROW_TYPE_REDUNDANT: break; case ROW_TYPE_COMPRESSED: case ROW_TYPE_DYNAMIC: - row_format_name - = row_type == ROW_TYPE_COMPRESSED - ? "COMPRESSED" - : "DYNAMIC"; - if (!srv_file_per_table) { push_warning_printf( - thd, - MYSQL_ERROR::WARN_LEVEL_WARN, + thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: ROW_FORMAT=%s" - " requires innodb_file_per_table.", - row_format_name); + "InnoDB: ROW_FORMAT=%s requires" + " innodb_file_per_table.", + get_row_format_name(row_type)); } else if (file_format < DICT_TF_FORMAT_ZIP) { push_warning_printf( - thd, - MYSQL_ERROR::WARN_LEVEL_WARN, + thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: ROW_FORMAT=%s" - " requires innodb_file_format >" - " Antelope.", - row_format_name); + "InnoDB: ROW_FORMAT=%s requires" + " innodb_file_format > Antelope.", + get_row_format_name(row_type)); } else { flags |= DICT_TF_COMPACT | (DICT_TF_FORMAT_ZIP @@ -6702,10 +6691,10 @@ ha_innobase::create( case ROW_TYPE_NOT_USED: case ROW_TYPE_FIXED: default: - push_warning(thd, - MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: assuming ROW_FORMAT=COMPACT."); + push_warning( + thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: assuming ROW_FORMAT=COMPACT."); case ROW_TYPE_DEFAULT: case ROW_TYPE_COMPACT: flags = DICT_TF_COMPACT; From c64f9526996a6a7014eb4cb286a3d15c9c026d08 Mon Sep 17 00:00:00 2001 From: Sunny Bains Date: Wed, 3 Nov 2010 12:40:53 +1100 Subject: [PATCH 160/304] Fix Bug #54538 - use of exclusive innodb dictionary lock limits performance. This patch doesn't get rid of the need to acquire the dict_sys->mutex but reduces the need to keep the mutex locked for the duration of the query to fsp_get_available_space_in_free_extents() from ha_innobase::info(). This is a port of revno:3548 from the builtin to the plugin. rb://501 Approved by Jimmy Yang and Marko Makela. --- storage/innodb_plugin/fil/fil0fil.c | 88 ++++++++++++++++------ storage/innodb_plugin/fsp/fsp0fsp.c | 50 ++++++++++++ storage/innodb_plugin/handler/ha_innodb.cc | 19 ++--- storage/innodb_plugin/include/fil0fil.h | 8 ++ storage/innodb_plugin/include/univ.i | 3 + 5 files changed, 134 insertions(+), 34 deletions(-) diff --git a/storage/innodb_plugin/fil/fil0fil.c b/storage/innodb_plugin/fil/fil0fil.c index 796fe921a7e..0f774dcaaa1 100644 --- a/storage/innodb_plugin/fil/fil0fil.c +++ b/storage/innodb_plugin/fil/fil0fil.c @@ -329,14 +329,15 @@ fil_get_space_id_for_table( /*******************************************************************//** Frees a space object from the tablespace memory cache. Closes the files in the chain but does not delete them. There must not be any pending i/o's or -flushes on the files. */ +flushes on the files. +@return TRUE on success */ static ibool fil_space_free( /*===========*/ - /* out: TRUE if success */ - ulint id, /* in: space id */ - ibool own_mutex);/* in: TRUE if own system->mutex */ + ulint id, /* in: space id */ + ibool x_latched); /* in: TRUE if caller has space->latch + in X mode */ /********************************************************************//** Reads data from a space to a buffer. Remember that the possible incomplete blocks at the end of file are ignored: they are not taken into account when @@ -1123,6 +1124,7 @@ try_again: space = fil_space_get_by_name(name); if (UNIV_LIKELY_NULL(space)) { + ibool success; ulint namesake_id; ut_print_timestamp(stderr); @@ -1161,9 +1163,10 @@ try_again: namesake_id = space->id; - mutex_exit(&fil_system->mutex); + success = fil_space_free(namesake_id, FALSE); + ut_a(success); - fil_space_free(namesake_id, FALSE); + mutex_exit(&fil_system->mutex); goto try_again; } @@ -1314,15 +1317,14 @@ fil_space_free( /*===========*/ /* out: TRUE if success */ ulint id, /* in: space id */ - ibool own_mutex) /* in: TRUE if own system->mutex */ + ibool x_latched) /* in: TRUE if caller has space->latch + in X mode */ { fil_space_t* space; fil_space_t* namespace; fil_node_t* fil_node; - if (!own_mutex) { - mutex_enter(&fil_system->mutex); - } + ut_ad(mutex_own(&fil_system->mutex)); space = fil_space_get_by_id(id); @@ -1333,8 +1335,6 @@ fil_space_free( " from the cache but\n" "InnoDB: it is not there.\n", (ulong) id); - mutex_exit(&fil_system->mutex); - return(FALSE); } @@ -1369,8 +1369,8 @@ fil_space_free( ut_a(0 == UT_LIST_GET_LEN(space->chain)); - if (!own_mutex) { - mutex_exit(&fil_system->mutex); + if (x_latched) { + rw_lock_x_unlock(&space->latch); } rw_lock_free(&(space->latch)); @@ -1615,25 +1615,27 @@ fil_close_all_files(void) /*=====================*/ { fil_space_t* space; - fil_node_t* node; mutex_enter(&fil_system->mutex); space = UT_LIST_GET_FIRST(fil_system->space_list); while (space != NULL) { + fil_node_t* node; fil_space_t* prev_space = space; - node = UT_LIST_GET_FIRST(space->chain); + for (node = UT_LIST_GET_FIRST(space->chain); + node != NULL; + node = UT_LIST_GET_NEXT(chain, node)) { - while (node != NULL) { if (node->open) { fil_node_close_file(node, fil_system); } - node = UT_LIST_GET_NEXT(chain, node); } + space = UT_LIST_GET_NEXT(space_list, space); - fil_space_free(prev_space->id, TRUE); + + fil_space_free(prev_space->id, FALSE); } mutex_exit(&fil_system->mutex); @@ -2253,6 +2255,19 @@ try_again: path = mem_strdup(space->name); mutex_exit(&fil_system->mutex); + + /* Important: We rely on the data dictionary mutex to ensure + that a race is not possible here. It should serialize the tablespace + drop/free. We acquire an X latch only to avoid a race condition + when accessing the tablespace instance via: + + fsp_get_available_space_in_free_extents(). + + There our main motivation is to reduce the contention on the + dictionary mutex. */ + + rw_lock_x_lock(&space->latch); + #ifndef UNIV_HOTBACKUP /* Invalidate in the buffer pool all pages belonging to the tablespace. Since we have set space->is_being_deleted = TRUE, readahead @@ -2265,7 +2280,11 @@ try_again: #endif /* printf("Deleting tablespace %s id %lu\n", space->name, id); */ - success = fil_space_free(id, FALSE); + mutex_enter(&fil_system->mutex); + + success = fil_space_free(id, TRUE); + + mutex_exit(&fil_system->mutex); if (success) { success = os_file_delete(path); @@ -2273,6 +2292,8 @@ try_again: if (!success) { success = os_file_delete_if_exists(path); } + } else { + rw_lock_x_unlock(&space->latch); } if (success) { @@ -2300,6 +2321,31 @@ try_again: return(FALSE); } +/*******************************************************************//** +Returns TRUE if a single-table tablespace is being deleted. +@return TRUE if being deleted */ +UNIV_INTERN +ibool +fil_tablespace_is_being_deleted( +/*============================*/ + ulint id) /*!< in: space id */ +{ + fil_space_t* space; + ibool is_being_deleted; + + mutex_enter(&fil_system->mutex); + + space = fil_space_get_by_id(id); + + ut_a(space != NULL); + + is_being_deleted = space->is_being_deleted; + + mutex_exit(&fil_system->mutex); + + return(is_being_deleted); +} + #ifndef UNIV_HOTBACKUP /*******************************************************************//** Discards a single-table tablespace. The tablespace must be cached in the @@ -4763,7 +4809,7 @@ fil_page_get_type( return(mach_read_from_2(page + FIL_PAGE_TYPE)); } -/******************************************************************** +/****************************************************************//** Initializes the tablespace memory cache. */ UNIV_INTERN void diff --git a/storage/innodb_plugin/fsp/fsp0fsp.c b/storage/innodb_plugin/fsp/fsp0fsp.c index 2bae8481d20..f600e96bf88 100644 --- a/storage/innodb_plugin/fsp/fsp0fsp.c +++ b/storage/innodb_plugin/fsp/fsp0fsp.c @@ -3102,13 +3102,63 @@ fsp_get_available_space_in_free_extents( ut_ad(!mutex_own(&kernel_mutex)); + /* The convoluted mutex acquire is to overcome latching order + issues: The problem is that the fil_mutex is at a lower level + than the tablespace latch and the buffer pool mutex. We have to + first prevent any operations on the file system by acquiring the + dictionary mutex. Then acquire the tablespace latch to obey the + latching order and then release the dictionary mutex. That way we + ensure that the tablespace instance can't be freed while we are + examining its contents (see fil_space_free()). + + However, there is one further complication, we release the fil_mutex + when we need to invalidate the the pages in the buffer pool and we + reacquire the fil_mutex when deleting and freeing the tablespace + instance in fil0fil.c. Here we need to account for that situation + too. */ + + mutex_enter(&dict_sys->mutex); + + /* At this stage there is no guarantee that the tablespace even + exists in the cache. */ + + if (fil_tablespace_deleted_or_being_deleted_in_mem(space, -1)) { + + mutex_exit(&dict_sys->mutex); + + return(ULLINT_UNDEFINED); + } + mtr_start(&mtr); latch = fil_space_get_latch(space, &flags); + + /* This should ensure that the tablespace instance can't be freed + by another thread. However, the tablespace pages can still be freed + from the buffer pool. We need to check for that again. */ + zip_size = dict_table_flags_to_zip_size(flags); mtr_x_lock(latch, &mtr); + mutex_exit(&dict_sys->mutex); + + /* At this point it is possible for the tablespace to be deleted and + its pages removed from the buffer pool. We need to check for that + situation. However, the tablespace instance can't be deleted because + our latching above should ensure that. */ + + if (fil_tablespace_is_being_deleted(space)) { + + mtr_commit(&mtr); + + return(ULLINT_UNDEFINED); + } + + /* From here on even if the user has dropped the tablespace, the + pages _must_ still exist in the buffer pool and the tablespace + instance _must_ be in the file system hash table. */ + space_header = fsp_get_space_header(space, zip_size, &mtr); size = mtr_read_ulint(space_header + FSP_SIZE, MLOG_4BYTES, &mtr); diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index ff2f46256e6..ef323f7b87c 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -7637,19 +7637,12 @@ ha_innobase::info_low( innodb_crash_recovery is set to a high value. */ stats.delete_length = 0; } else { - /* lock the data dictionary to avoid races with - ibd_file_missing and tablespace_discarded */ - row_mysql_lock_data_dictionary(prebuilt->trx); + ullint avail_space; - /* ib_table->space must be an existent tablespace */ - if (!ib_table->ibd_file_missing - && !ib_table->tablespace_discarded) { - - stats.delete_length = - fsp_get_available_space_in_free_extents( - ib_table->space) * 1024; - } else { + avail_space = fsp_get_available_space_in_free_extents( + ib_table->space); + if (avail_space == ULLINT_UNDEFINED) { THD* thd; thd = ha_thd(); @@ -7666,9 +7659,9 @@ ha_innobase::info_low( ib_table->name); stats.delete_length = 0; + } else { + stats.delete_length = avail_space * 1024; } - - row_mysql_unlock_data_dictionary(prebuilt->trx); } stats.check_time = 0; diff --git a/storage/innodb_plugin/include/fil0fil.h b/storage/innodb_plugin/include/fil0fil.h index c894875b352..f6a19646292 100644 --- a/storage/innodb_plugin/include/fil0fil.h +++ b/storage/innodb_plugin/include/fil0fil.h @@ -716,6 +716,14 @@ fil_page_get_type( /*==============*/ const byte* page); /*!< in: file page */ +/*******************************************************************//** +Returns TRUE if a single-table tablespace is being deleted. +@return TRUE if being deleted */ +UNIV_INTERN +ibool +fil_tablespace_is_being_deleted( +/*============================*/ + ulint id); /*!< in: space id */ typedef struct fil_space_struct fil_space_t; diff --git a/storage/innodb_plugin/include/univ.i b/storage/innodb_plugin/include/univ.i index c1ed56684c9..cab3af5297e 100644 --- a/storage/innodb_plugin/include/univ.i +++ b/storage/innodb_plugin/include/univ.i @@ -360,6 +360,9 @@ typedef unsigned long long int ullint; /* Maximum value for ib_uint64_t */ #define IB_ULONGLONG_MAX ((ib_uint64_t) (~0ULL)) +/* THe 'undefined' value for ullint */ +#define ULLINT_UNDEFINED ((ullint)(-1)) + /* This 'ibool' type is used within Innobase. Remember that different included headers may define 'bool' differently. Do not assume that 'bool' is a ulint! */ #define ibool ulint From 812827e669e187e16623a327c0a5adc7cabe647a Mon Sep 17 00:00:00 2001 From: smenon Date: Wed, 3 Nov 2010 09:59:11 +0100 Subject: [PATCH 161/304] Bug #57746: Win directory of source distribution - out-of-date files / support for new files --- win/README | 34 ++++++++++++++++++++++++++-------- win/build-nmake-x64.bat | 21 --------------------- win/build-nmake.bat | 21 --------------------- win/build-vs71.bat | 22 ---------------------- win/build-vs8.bat | 21 --------------------- win/build-vs8_x64.bat | 21 --------------------- win/build-vs9.bat | 18 ------------------ win/build-vs9_x64.bat | 18 ------------------ 8 files changed, 26 insertions(+), 150 deletions(-) delete mode 100644 win/build-nmake-x64.bat delete mode 100644 win/build-nmake.bat delete mode 100755 win/build-vs71.bat delete mode 100755 win/build-vs8.bat delete mode 100755 win/build-vs8_x64.bat delete mode 100644 win/build-vs9.bat delete mode 100644 win/build-vs9_x64.bat diff --git a/win/README b/win/README index 63923a6d7e2..9886fe3a44d 100644 --- a/win/README +++ b/win/README @@ -10,7 +10,7 @@ or ealier. The Windows build system uses a tool named CMake to generate build files for a variety of project systems. This tool is combined with a set of jscript -files to enable building of MySQL for Windows directly out of a bk clone. +files to enable building of MySQL for Windows directly out of a bzr clone. The steps required are below. Step 1: @@ -41,7 +41,7 @@ before you start the build) Step 4 ------ -Clone your bk tree to any location you like. +Clone your bzr tree to any location you like. Step 5 ------ @@ -76,17 +76,35 @@ win\configure WITH_INNOBASE_STORAGE_ENGINE WITH_PARTITION_STORAGE_ENGINE MYSQL_S Step 6 ------ -From the root of your installation directory/bk clone, execute one of -the batch files to generate the type of project files you desire. +From the root of your installation directory/bzr clone, you can +use cmake to compile the sources.Use cmake --help when necessary. +Before you run cmake with changed settings (compiler, system +libraries, options, ...), make sure you delete the CMakeCache.txt +generated by your previous run. -For Visual Studio 8 (or Visual C++ 2005 express edition), do win\build-vs8. -For Visual Studio 7.1, do win\build-vs71. +C:\>del CMakeCache.txt +C:\>cmake . -G "target name" -We will support building with nmake in the near future. +For Example: +To generate the Win64 project files using Visual Studio 9, you would run +cmake . -G "Visual Studio 9 2008 Win64" +Other target names supported using CMake 2.6 patch 4 are: + + Visual Studio 7 "Visual Studio 7 .NET 2003" + Visual Studio 8 "Visual Studio 8 2005" + Visual Studio 8 (64 bit) "Visual Studio 8 2005 Win64" + Visual Studio 9 "Visual Studio 9 2008" + Visual Studio 9 (64 bit) "Visual Studio 9 2008 Win64" + +For generating project files using Visual Studio 10, you need CMake 2.8 +or higher and corresponding target names are + Visual Studio 10 + Visual Studio 10 Win64 + Step 7 ------ -From the root of your bk clone, start your build. +From the root of your bzr clone, start your build. For Visual Studio, execute mysql.sln. This will start the IDE and you can click the build solution menu option. diff --git a/win/build-nmake-x64.bat b/win/build-nmake-x64.bat deleted file mode 100644 index f73574ac8de..00000000000 --- a/win/build-nmake-x64.bat +++ /dev/null @@ -1,21 +0,0 @@ -@echo off - -REM Copyright (C) 2006 MySQL AB -REM -REM This program is free software; you can redistribute it and/or modify -REM it under the terms of the GNU General Public License as published by -REM the Free Software Foundation; version 2 of the License. -REM -REM This program is distributed in the hope that it will be useful, -REM but WITHOUT ANY WARRANTY; without even the implied warranty of -REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -REM GNU General Public License for more details. -REM -REM You should have received a copy of the GNU General Public License -REM along with this program; if not, write to the Free Software -REM Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -if exist cmakecache.txt del cmakecache.txt -copy win\nmake_x64_cache.txt cmakecache.txt -cmake -G "NMake Makefiles" -copy cmakecache.txt win\nmake_x64_cache.txt diff --git a/win/build-nmake.bat b/win/build-nmake.bat deleted file mode 100644 index 89505c08313..00000000000 --- a/win/build-nmake.bat +++ /dev/null @@ -1,21 +0,0 @@ -@echo off - -REM Copyright (C) 2006 MySQL AB -REM -REM This program is free software; you can redistribute it and/or modify -REM it under the terms of the GNU General Public License as published by -REM the Free Software Foundation; version 2 of the License. -REM -REM This program is distributed in the hope that it will be useful, -REM but WITHOUT ANY WARRANTY; without even the implied warranty of -REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -REM GNU General Public License for more details. -REM -REM You should have received a copy of the GNU General Public License -REM along with this program; if not, write to the Free Software -REM Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -if exist cmakecache.txt del cmakecache.txt -copy win\nmake_cache.txt cmakecache.txt -cmake -G "NMake Makefiles" -copy cmakecache.txt win\nmake_cache.txt diff --git a/win/build-vs71.bat b/win/build-vs71.bat deleted file mode 100755 index 159b1ec97d1..00000000000 --- a/win/build-vs71.bat +++ /dev/null @@ -1,22 +0,0 @@ -@echo off - -REM Copyright (C) 2006 MySQL AB -REM -REM This program is free software; you can redistribute it and/or modify -REM it under the terms of the GNU General Public License as published by -REM the Free Software Foundation; version 2 of the License. -REM -REM This program is distributed in the hope that it will be useful, -REM but WITHOUT ANY WARRANTY; without even the implied warranty of -REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -REM GNU General Public License for more details. -REM -REM You should have received a copy of the GNU General Public License -REM along with this program; if not, write to the Free Software -REM Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -if exist cmakecache.txt del cmakecache.txt -copy win\vs71cache.txt cmakecache.txt -cmake -G "Visual Studio 7 .NET 2003" -copy cmakecache.txt win\vs71cache.txt - diff --git a/win/build-vs8.bat b/win/build-vs8.bat deleted file mode 100755 index ff0eeb0a8cb..00000000000 --- a/win/build-vs8.bat +++ /dev/null @@ -1,21 +0,0 @@ -@echo off - -REM Copyright (C) 2006 MySQL AB -REM -REM This program is free software; you can redistribute it and/or modify -REM it under the terms of the GNU General Public License as published by -REM the Free Software Foundation; version 2 of the License. -REM -REM This program is distributed in the hope that it will be useful, -REM but WITHOUT ANY WARRANTY; without even the implied warranty of -REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -REM GNU General Public License for more details. -REM -REM You should have received a copy of the GNU General Public License -REM along with this program; if not, write to the Free Software -REM Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -if exist cmakecache.txt del cmakecache.txt -copy win\vs8cache.txt cmakecache.txt -cmake -G "Visual Studio 8 2005" -copy cmakecache.txt win\vs8cache.txt diff --git a/win/build-vs8_x64.bat b/win/build-vs8_x64.bat deleted file mode 100755 index bc13e01d742..00000000000 --- a/win/build-vs8_x64.bat +++ /dev/null @@ -1,21 +0,0 @@ -@echo off - -REM Copyright (C) 2006 MySQL AB -REM -REM This program is free software; you can redistribute it and/or modify -REM it under the terms of the GNU General Public License as published by -REM the Free Software Foundation; version 2 of the License. -REM -REM This program is distributed in the hope that it will be useful, -REM but WITHOUT ANY WARRANTY; without even the implied warranty of -REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -REM GNU General Public License for more details. -REM -REM You should have received a copy of the GNU General Public License -REM along with this program; if not, write to the Free Software -REM Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -if exist cmakecache.txt del cmakecache.txt -copy win\vs8cache.txt cmakecache.txt -cmake -G "Visual Studio 8 2005 Win64" -copy cmakecache.txt win\vs8cache.txt diff --git a/win/build-vs9.bat b/win/build-vs9.bat deleted file mode 100644 index 09f1e343013..00000000000 --- a/win/build-vs9.bat +++ /dev/null @@ -1,18 +0,0 @@ -@echo off - -REM Copyright (C) 2006 MySQL AB -REM -REM This program is free software; you can redistribute it and/or modify -REM it under the terms of the GNU General Public License as published by -REM the Free Software Foundation; version 2 of the License. -REM -REM This program is distributed in the hope that it will be useful, -REM but WITHOUT ANY WARRANTY; without even the implied warranty of -REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -REM GNU General Public License for more details. -REM -REM You should have received a copy of the GNU General Public License -REM along with this program; if not, write to the Free Software -REM Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -cmake -G "Visual Studio 9 2008" - diff --git a/win/build-vs9_x64.bat b/win/build-vs9_x64.bat deleted file mode 100644 index 61c7253132d..00000000000 --- a/win/build-vs9_x64.bat +++ /dev/null @@ -1,18 +0,0 @@ -@echo off - -REM Copyright (C) 2006 MySQL AB -REM -REM This program is free software; you can redistribute it and/or modify -REM it under the terms of the GNU General Public License as published by -REM the Free Software Foundation; version 2 of the License. -REM -REM This program is distributed in the hope that it will be useful, -REM but WITHOUT ANY WARRANTY; without even the implied warranty of -REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -REM GNU General Public License for more details. -REM -REM You should have received a copy of the GNU General Public License -REM along with this program; if not, write to the Free Software -REM Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -cmake -G "Visual Studio 9 2008 Win64" - From eab53d4e8058c05d3ac7f347700c01df93817fa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 3 Nov 2010 11:16:11 +0200 Subject: [PATCH 162/304] Non-functional change: Remove bogus const qualifiers and make some function comments more accurate. --- storage/innodb_plugin/btr/btr0cur.c | 4 ++-- storage/innodb_plugin/include/btr0cur.h | 2 +- storage/innodb_plugin/include/row0ins.h | 2 +- storage/innodb_plugin/include/row0upd.h | 4 ++-- storage/innodb_plugin/row/row0ins.c | 6 +++--- storage/innodb_plugin/row/row0upd.c | 8 ++++---- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0cur.c index 79fe328a631..cb0a61ee497 100644 --- a/storage/innodb_plugin/btr/btr0cur.c +++ b/storage/innodb_plugin/btr/btr0cur.c @@ -953,7 +953,7 @@ btr_cur_ins_lock_and_undo( not zero, the parameters index and thr should be specified */ btr_cur_t* cursor, /*!< in: cursor on page after which to insert */ - const dtuple_t* entry, /*!< in: entry to insert */ + dtuple_t* entry, /*!< in/out: entry to insert */ que_thr_t* thr, /*!< in: query thread or NULL */ mtr_t* mtr, /*!< in/out: mini-transaction */ ibool* inherit)/*!< out: TRUE if the inserted new record maybe @@ -3794,7 +3794,7 @@ Stores the fields in big_rec_vec to the tablespace and puts pointers to them in rec. The extern flags in rec will have to be set beforehand. The fields are stored on pages allocated from leaf node file segment of the index tree. -@return DB_SUCCESS or error */ +@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */ UNIV_INTERN ulint btr_store_big_rec_extern_fields( diff --git a/storage/innodb_plugin/include/btr0cur.h b/storage/innodb_plugin/include/btr0cur.h index 7f6bff11f84..1e1dc0f580a 100644 --- a/storage/innodb_plugin/include/btr0cur.h +++ b/storage/innodb_plugin/include/btr0cur.h @@ -520,7 +520,7 @@ Stores the fields in big_rec_vec to the tablespace and puts pointers to them in rec. The extern flags in rec will have to be set beforehand. The fields are stored on pages allocated from leaf node file segment of the index tree. -@return DB_SUCCESS or error */ +@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */ UNIV_INTERN ulint btr_store_big_rec_extern_fields( diff --git a/storage/innodb_plugin/include/row0ins.h b/storage/innodb_plugin/include/row0ins.h index 9f93565ddb7..c780d228a45 100644 --- a/storage/innodb_plugin/include/row0ins.h +++ b/storage/innodb_plugin/include/row0ins.h @@ -84,7 +84,7 @@ ulint row_ins_index_entry( /*================*/ dict_index_t* index, /*!< in: index */ - dtuple_t* entry, /*!< in: index entry to insert */ + dtuple_t* entry, /*!< in/out: index entry to insert */ ulint n_ext, /*!< in: number of externally stored columns */ ibool foreign,/*!< in: TRUE=check foreign key constraints */ que_thr_t* thr); /*!< in: query thread */ diff --git a/storage/innodb_plugin/include/row0upd.h b/storage/innodb_plugin/include/row0upd.h index 4e2de9bd2ec..ea14cd64213 100644 --- a/storage/innodb_plugin/include/row0upd.h +++ b/storage/innodb_plugin/include/row0upd.h @@ -126,8 +126,8 @@ UNIV_INTERN void row_upd_index_entry_sys_field( /*==========================*/ - const dtuple_t* entry, /*!< in: index entry, where the memory buffers - for sys fields are already allocated: + dtuple_t* entry, /*!< in/out: index entry, where the memory + buffers for sys fields are already allocated: the function just copies the new values to them */ dict_index_t* index, /*!< in: clustered index */ diff --git a/storage/innodb_plugin/row/row0ins.c b/storage/innodb_plugin/row/row0ins.c index a193bf21f7c..81b58465e11 100644 --- a/storage/innodb_plugin/row/row0ins.c +++ b/storage/innodb_plugin/row/row0ins.c @@ -1781,7 +1781,7 @@ ulint row_ins_duplicate_error_in_clust( /*=============================*/ btr_cur_t* cursor, /*!< in: B-tree cursor */ - dtuple_t* entry, /*!< in: entry to insert */ + const dtuple_t* entry, /*!< in: entry to insert */ que_thr_t* thr, /*!< in: query thread */ mtr_t* mtr) /*!< in: mtr */ { @@ -1977,7 +1977,7 @@ row_ins_index_entry_low( depending on whether we wish optimistic or pessimistic descent down the index tree */ dict_index_t* index, /*!< in: index */ - dtuple_t* entry, /*!< in: index entry to insert */ + dtuple_t* entry, /*!< in/out: index entry to insert */ ulint n_ext, /*!< in: number of externally stored columns */ que_thr_t* thr) /*!< in: query thread */ { @@ -2158,7 +2158,7 @@ ulint row_ins_index_entry( /*================*/ dict_index_t* index, /*!< in: index */ - dtuple_t* entry, /*!< in: index entry to insert */ + dtuple_t* entry, /*!< in/out: index entry to insert */ ulint n_ext, /*!< in: number of externally stored columns */ ibool foreign,/*!< in: TRUE=check foreign key constraints */ que_thr_t* thr) /*!< in: query thread */ diff --git a/storage/innodb_plugin/row/row0upd.c b/storage/innodb_plugin/row/row0upd.c index 444003ba3f0..0dc550b93f5 100644 --- a/storage/innodb_plugin/row/row0upd.c +++ b/storage/innodb_plugin/row/row0upd.c @@ -371,8 +371,8 @@ UNIV_INTERN void row_upd_index_entry_sys_field( /*==========================*/ - const dtuple_t* entry, /*!< in: index entry, where the memory buffers - for sys fields are already allocated: + dtuple_t* entry, /*!< in/out: index entry, where the memory + buffers for sys fields are already allocated: the function just copies the new values to them */ dict_index_t* index, /*!< in: clustered index */ @@ -1587,12 +1587,12 @@ static ulint row_upd_clust_rec_by_insert( /*========================*/ - upd_node_t* node, /*!< in: row update node */ + upd_node_t* node, /*!< in/out: row update node */ dict_index_t* index, /*!< in: clustered index of the record */ que_thr_t* thr, /*!< in: query thread */ ibool check_ref,/*!< in: TRUE if index may be referenced in a foreign key constraint */ - mtr_t* mtr) /*!< in: mtr; gets committed here */ + mtr_t* mtr) /*!< in/out: mtr; gets committed here */ { mem_heap_t* heap = NULL; btr_pcur_t* pcur; From bfc704035514564e39e0c01ba6f1dbf40086c3c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 3 Nov 2010 11:19:12 +0200 Subject: [PATCH 163/304] Bug#57947 InnoDB diagnostics shows btr_block_get calls instead of real callers Improve the diagnostics of buffer pool accesses for B-trees, so that the file names and line numbers of the real calls are shown instead of the line of the buf_page_get() call in btr_block_get(). btr_page_get(): Replaced with a macro. btr_block_get_func(): Renamed from btr_block_get(). Add file, line. btr_block_get(): A macro that passes the __FILE__, __LINE__ to btr_block_get_func(). dict_truncate_index_tree(): Replace a btr_page_get() call with btr_block_get(), since we are only latching the page, not accessing it. --- storage/innodb_plugin/ChangeLog | 6 +++ storage/innodb_plugin/dict/dict0crea.c | 2 +- storage/innodb_plugin/include/btr0btr.h | 49 ++++++++++++++---------- storage/innodb_plugin/include/btr0btr.ic | 38 ++++++------------ 4 files changed, 48 insertions(+), 47 deletions(-) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 3792d48e5f2..57a4b588703 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,9 @@ +2010-11-03 The InnoDB Team + + * include/btr0btr.h, include/btr0btr.ic, dict/dict0crea.c: + Fix Bug#57947 InnoDB diagnostics shows btr_block_get calls + instead of real callers + 2010-11-02 The InnoDB Team * row/row0sel.c: diff --git a/storage/innodb_plugin/dict/dict0crea.c b/storage/innodb_plugin/dict/dict0crea.c index e63f8bc3e6a..7d6cbc8c1c8 100644 --- a/storage/innodb_plugin/dict/dict0crea.c +++ b/storage/innodb_plugin/dict/dict0crea.c @@ -828,7 +828,7 @@ dict_truncate_index_tree( appropriate field in the SYS_INDEXES record: this mini-transaction marks the B-tree totally truncated */ - btr_page_get(space, zip_size, root_page_no, RW_X_LATCH, mtr); + btr_block_get(space, zip_size, root_page_no, RW_X_LATCH, mtr); btr_free_root(space, zip_size, root_page_no, mtr); create: diff --git a/storage/innodb_plugin/include/btr0btr.h b/storage/innodb_plugin/include/btr0btr.h index 5e6a76c7d21..dde3a0bab69 100644 --- a/storage/innodb_plugin/include/btr0btr.h +++ b/storage/innodb_plugin/include/btr0btr.h @@ -94,26 +94,35 @@ btr_root_get( Gets a buffer page and declares its latching order level. */ UNIV_INLINE buf_block_t* -btr_block_get( -/*==========*/ - ulint space, /*!< in: space id */ - ulint zip_size, /*!< in: compressed page size in bytes - or 0 for uncompressed pages */ - ulint page_no, /*!< in: page number */ - ulint mode, /*!< in: latch mode */ - mtr_t* mtr); /*!< in: mtr */ -/**************************************************************//** -Gets a buffer page and declares its latching order level. */ -UNIV_INLINE -page_t* -btr_page_get( -/*=========*/ - ulint space, /*!< in: space id */ - ulint zip_size, /*!< in: compressed page size in bytes - or 0 for uncompressed pages */ - ulint page_no, /*!< in: page number */ - ulint mode, /*!< in: latch mode */ - mtr_t* mtr); /*!< in: mtr */ +btr_block_get_func( +/*===============*/ + ulint space, /*!< in: space id */ + ulint zip_size, /*!< in: compressed page size in bytes + or 0 for uncompressed pages */ + ulint page_no, /*!< in: page number */ + ulint mode, /*!< in: latch mode */ + const char* file, /*!< in: file name */ + ulint line, /*!< in: line where called */ + mtr_t* mtr) /*!< in/out: mtr */ + __attribute__((nonnull)); +/** Gets a buffer page and declares its latching order level. +@param space tablespace identifier +@param zip_size compressed page size in bytes or 0 for uncompressed pages +@param page_no page number +@param mode latch mode +@param mtr mini-transaction handle +@return the block descriptor */ +# define btr_block_get(space,zip_size,page_no,mode,mtr) \ + btr_block_get_func(space,zip_size,page_no,mode,__FILE__,__LINE__,mtr) +/** Gets a buffer page and declares its latching order level. +@param space tablespace identifier +@param zip_size compressed page size in bytes or 0 for uncompressed pages +@param page_no page number +@param mode latch mode +@param mtr mini-transaction handle +@return the uncompressed page frame */ +# define btr_page_get(space,zip_size,page_no,mode,mtr) \ + buf_block_get_frame(btr_block_get(space,zip_size,page_no,mode,mtr)) #endif /* !UNIV_HOTBACKUP */ /**************************************************************//** Gets the index id field of a page. diff --git a/storage/innodb_plugin/include/btr0btr.ic b/storage/innodb_plugin/include/btr0btr.ic index 97944cc2e26..83eb3627abb 100644 --- a/storage/innodb_plugin/include/btr0btr.ic +++ b/storage/innodb_plugin/include/btr0btr.ic @@ -39,18 +39,21 @@ Created 6/2/1994 Heikki Tuuri Gets a buffer page and declares its latching order level. */ UNIV_INLINE buf_block_t* -btr_block_get( -/*==========*/ - ulint space, /*!< in: space id */ - ulint zip_size, /*!< in: compressed page size in bytes - or 0 for uncompressed pages */ - ulint page_no, /*!< in: page number */ - ulint mode, /*!< in: latch mode */ - mtr_t* mtr) /*!< in: mtr */ +btr_block_get_func( +/*===============*/ + ulint space, /*!< in: space id */ + ulint zip_size, /*!< in: compressed page size in bytes + or 0 for uncompressed pages */ + ulint page_no, /*!< in: page number */ + ulint mode, /*!< in: latch mode */ + const char* file, /*!< in: file name */ + ulint line, /*!< in: line where called */ + mtr_t* mtr) /*!< in/out: mtr */ { buf_block_t* block; - block = buf_page_get(space, zip_size, page_no, mode, mtr); + block = buf_page_get_gen(space, zip_size, page_no, mode, + NULL, BUF_GET, file, line, mtr); if (mode != RW_NO_LATCH) { @@ -60,23 +63,6 @@ btr_block_get( return(block); } -/**************************************************************//** -Gets a buffer page and declares its latching order level. */ -UNIV_INLINE -page_t* -btr_page_get( -/*=========*/ - ulint space, /*!< in: space id */ - ulint zip_size, /*!< in: compressed page size in bytes - or 0 for uncompressed pages */ - ulint page_no, /*!< in: page number */ - ulint mode, /*!< in: latch mode */ - mtr_t* mtr) /*!< in: mtr */ -{ - return(buf_block_get_frame(btr_block_get(space, zip_size, page_no, - mode, mtr))); -} - /**************************************************************//** Sets the index id field of a page. */ UNIV_INLINE From a491492f15ef8a06d426719cae0c20b370956790 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 3 Nov 2010 11:30:08 +0200 Subject: [PATCH 164/304] Add ChangeLog entry for Bug#53046 --- storage/innodb_plugin/ChangeLog | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 3792d48e5f2..de1530fd92c 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,11 @@ +2010-11-02 The InnoDB Team + + * btr/btr0cur.c, dict/dict0dict.c, dict/dict0load.c, + handler/ha_innodb.cc, include/dict0dict.h, row/row0mysql.c, + innodb_bug53046.result, innodb_bug53046.test: + Fix Bug#53046 dict_update_statistics_low can still be run + concurrently on same table + 2010-11-02 The InnoDB Team * row/row0sel.c: From 74328892e0f28c1b1a410df1889225639cb9152b Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 3 Nov 2010 13:47:22 +0200 Subject: [PATCH 165/304] Addendum to bug #57916 : fixed the test suite to be less environment dependent. --- mysql-test/r/plugin_auth.result | 6 +++--- mysql-test/t/plugin_auth.test | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/plugin_auth.result b/mysql-test/r/plugin_auth.result index d56a4e5326a..7119ba11077 100644 --- a/mysql-test/r/plugin_auth.result +++ b/mysql-test/r/plugin_auth.result @@ -14,9 +14,9 @@ GRANT PROXY ON plug_dest TO plug; test proxies_priv columns SELECT * FROM mysql.proxies_priv; Host User Proxied_host Proxied_user With_grant Grantor Timestamp -localhost root 1 xx -unknown root 1 xx -% plug % plug_dest 0 root@localhost xx +xx root 1 xx +xx root 1 xx +xx plug % plug_dest 0 root@localhost xx test mysql.proxies_priv; SHOW CREATE TABLE mysql.proxies_priv; Table Create Table diff --git a/mysql-test/t/plugin_auth.test b/mysql-test/t/plugin_auth.test index ebbaf389632..439cabaef18 100644 --- a/mysql-test/t/plugin_auth.test +++ b/mysql-test/t/plugin_auth.test @@ -17,7 +17,7 @@ connect(plug_con,localhost,plug,plug_dest); GRANT PROXY ON plug_dest TO plug; --echo test proxies_priv columns ---replace_column 7 xx +--replace_column 1 xx 7 xx SELECT * FROM mysql.proxies_priv; --echo test mysql.proxies_priv; SHOW CREATE TABLE mysql.proxies_priv; From e68f62e7519d540d19ec76d3c881444ebfb0b06a Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Wed, 3 Nov 2010 14:52:10 +0300 Subject: [PATCH 166/304] Fix version tag (remove -rc suffix). --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 9f986e068cb..2d67f34b4bb 100644 --- a/configure.in +++ b/configure.in @@ -27,7 +27,7 @@ dnl dnl When changing the major version number please also check the switch dnl statement in mysqlbinlog::check_master_version(). You may also need dnl to update version.c in ndb. -AC_INIT([MySQL Server], [5.5.8-rc], [], [mysql]) +AC_INIT([MySQL Server], [5.5.8], [], [mysql]) AC_CONFIG_SRCDIR([sql/mysqld.cc]) AC_CANONICAL_SYSTEM From dfe39f68a97d08f5037b6bdd82bfb63bb0657a76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 3 Nov 2010 14:38:36 +0200 Subject: [PATCH 167/304] rw_lock_debug_print(): Output the thread ID in unsigned format. --- storage/innobase/sync/sync0rw.c | 2 +- storage/innodb_plugin/sync/sync0rw.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/innobase/sync/sync0rw.c b/storage/innobase/sync/sync0rw.c index 367f019ce55..0b05fb826ac 100644 --- a/storage/innobase/sync/sync0rw.c +++ b/storage/innobase/sync/sync0rw.c @@ -888,7 +888,7 @@ rw_lock_debug_print( rwt = info->lock_type; - fprintf(stderr, "Locked: thread %ld file %s line %ld ", + fprintf(stderr, "Locked: thread %lu file %s line %lu ", (ulong) os_thread_pf(info->thread_id), info->file_name, (ulong) info->line); if (rwt == RW_LOCK_SHARED) { diff --git a/storage/innodb_plugin/sync/sync0rw.c b/storage/innodb_plugin/sync/sync0rw.c index 52eaa5d0f43..365a53dcac1 100644 --- a/storage/innodb_plugin/sync/sync0rw.c +++ b/storage/innodb_plugin/sync/sync0rw.c @@ -988,7 +988,7 @@ rw_lock_debug_print( rwt = info->lock_type; - fprintf(stderr, "Locked: thread %ld file %s line %ld ", + fprintf(stderr, "Locked: thread %lu file %s line %lu ", (ulong) os_thread_pf(info->thread_id), info->file_name, (ulong) info->line); if (rwt == RW_LOCK_SHARED) { From b01a4ceb565a1077ee93682f166e6a0420099486 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 3 Nov 2010 14:02:15 +0100 Subject: [PATCH 168/304] Raise version number after cloning 5.1.53 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index b7cd3585789..7fd581af009 100644 --- a/configure.in +++ b/configure.in @@ -12,7 +12,7 @@ dnl dnl When changing the major version number please also check the switch dnl statement in mysqlbinlog::check_master_version(). You may also need dnl to update version.c in ndb. -AC_INIT([MySQL Server], [5.1.53], [], [mysql]) +AC_INIT([MySQL Server], [5.1.54], [], [mysql]) AC_CONFIG_SRCDIR([sql/mysqld.cc]) AC_CANONICAL_SYSTEM From 39bceaac0295e556a8db5d354315b39dfb0f3ef6 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 3 Nov 2010 15:31:42 +0200 Subject: [PATCH 169/304] added windows cmake binaries --- .bzrignore | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.bzrignore b/.bzrignore index e1e2083e2d2..3d27c001e2b 100644 --- a/.bzrignore +++ b/.bzrignore @@ -9,15 +9,19 @@ *.core *.d *.da +*.dll *.exe +*.exp *.gcda *.gcno *.gcov *.idb +*.ilk *.la *.lai *.lib *.lo +*.manifest *.map *.o *.obj @@ -87,6 +91,7 @@ BitKeeper/tmp/* BitKeeper/tmp/bkr3sAHD BitKeeper/tmp/gone CMakeFiles/* +CMakeFiles COPYING COPYING.LIB Docs/#manual.texi# @@ -146,6 +151,7 @@ Makefile Makefile.in Makefile.in' PENDING/* +scripts/scripts TAGS VC++Files/client/mysql_amd64.dsp ac_available_languages_fragment @@ -1968,6 +1974,7 @@ sql-bench/test-transactions sql-bench/test-wisconsin sql/*.cpp sql/*.ds? +sql/*.def sql/*.vcproj sql/.deps/client.Po sql/.deps/derror.Po @@ -2100,6 +2107,7 @@ sql/.libs/udf_example.lai sql/.libs/udf_example.so.0 sql/.libs/udf_example.so.0.0.0 sql/client.c +sql/cmake_dummy.cc sql/Doxyfile sql/f.c sql/gen_lex_hash @@ -3030,6 +3038,7 @@ vio/viotest.cpp win/configure.data win/vs71cache.txt win/vs8cache.txt +win/nmake_cache.txt ylwrap zlib/*.ds? zlib/*.vcproj From 4cfa91f42c4cde9c35979cd2b9837cb60213d876 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 3 Nov 2010 16:03:40 +0200 Subject: [PATCH 170/304] bumped up the version --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 7680a60226a..7c781c35cc2 100644 --- a/configure.in +++ b/configure.in @@ -12,7 +12,7 @@ dnl dnl When changing the major version number please also check the switch dnl statement in mysqlbinlog::check_master_version(). You may also need dnl to update version.c in ndb. -AC_INIT([MySQL Server], [5.1.53], [], [mysql]) +AC_INIT([MySQL Server], [5.1.54], [], [mysql]) AC_CONFIG_SRCDIR([sql/mysqld.cc]) AC_CANONICAL_SYSTEM From 1602ffb8ab4e04d17db995a22bb6c33a5a638881 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Wed, 3 Nov 2010 14:51:52 +0000 Subject: [PATCH 171/304] BUG#57899: Certain reserved words should not be reserved In MySQL 5.5 the new reserved words include: SLOW as in FLUSH SLOW LOGS GENERAL as in FLUSH GENERAL LOGS IGNORE_SERVER_IDS as in CHANGE MASTER ... IGNORE_SERVER_IDS MASTER_HEARTBEAT_PERIOD as in CHANGE MASTER ... MASTER_HEARTBEAT_PERIOD These are not reserved words in standard SQL, or in Oracle 11g, and as such, may affect existing applications. We fix this by adding the new words to the list of keywords that are allowed for labels in SPs. mysql-test/t/keywords.test: Test case that checks that the target words can be used for naming fields in a table or as local routine variable names. --- mysql-test/r/keywords.result | 224 +++++++++++++++++++++++++++++++++++ mysql-test/t/keywords.test | 100 +++++++++++++++- sql/sql_yacc.yy | 4 + 3 files changed, 327 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/keywords.result b/mysql-test/r/keywords.result index 5f338ad6a62..977fe7791b9 100644 --- a/mysql-test/r/keywords.result +++ b/mysql-test/r/keywords.result @@ -45,3 +45,227 @@ p1 max=1 drop procedure p1; drop table t1; +CREATE TABLE slow (slow INT, general INT, master_heartbeat_period INT, ignore_server_ids INT); +INSERT INTO slow(slow, general, master_heartbeat_period, ignore_server_ids) VALUES (1,2,3,4), (5,6,7,8); +INSERT INTO slow(slow, general, master_heartbeat_period) VALUES (1,2,3), (5,6,7); +INSERT INTO slow(slow, general) VALUES (1,2), (5,6); +INSERT INTO slow(slow) VALUES (1), (5); +SELECT slow, general, master_heartbeat_period, slow FROM slow ORDER BY slow; +slow general master_heartbeat_period slow +1 2 3 1 +1 2 3 1 +1 2 NULL 1 +1 NULL NULL 1 +5 6 7 5 +5 6 7 5 +5 6 NULL 5 +5 NULL NULL 5 +SELECT slow, general, master_heartbeat_period FROM slow ORDER BY slow; +slow general master_heartbeat_period +1 2 3 +1 2 3 +1 2 NULL +1 NULL NULL +5 6 7 +5 6 7 +5 6 NULL +5 NULL NULL +SELECT slow, master_heartbeat_period FROM slow ORDER BY slow; +slow master_heartbeat_period +1 3 +1 3 +1 NULL +1 NULL +5 7 +5 7 +5 NULL +5 NULL +SELECT slow FROM slow ORDER BY slow; +slow +1 +1 +1 +1 +5 +5 +5 +5 +DROP TABLE slow; +CREATE TABLE general (slow INT, general INT, master_heartbeat_period INT, ignore_server_ids INT); +INSERT INTO general(slow, general, master_heartbeat_period, ignore_server_ids) VALUES (1,2,3,4), (5,6,7,8); +INSERT INTO general(slow, general, master_heartbeat_period) VALUES (1,2,3), (5,6,7); +INSERT INTO general(slow, general) VALUES (1,2), (5,6); +INSERT INTO general(slow) VALUES (1), (5); +SELECT slow, general, master_heartbeat_period, slow FROM general ORDER BY slow; +slow general master_heartbeat_period slow +1 2 3 1 +1 2 3 1 +1 2 NULL 1 +1 NULL NULL 1 +5 6 7 5 +5 6 7 5 +5 6 NULL 5 +5 NULL NULL 5 +SELECT slow, general, master_heartbeat_period FROM general ORDER BY slow; +slow general master_heartbeat_period +1 2 3 +1 2 3 +1 2 NULL +1 NULL NULL +5 6 7 +5 6 7 +5 6 NULL +5 NULL NULL +SELECT slow, master_heartbeat_period FROM general ORDER BY slow; +slow master_heartbeat_period +1 3 +1 3 +1 NULL +1 NULL +5 7 +5 7 +5 NULL +5 NULL +SELECT slow FROM general ORDER BY slow; +slow +1 +1 +1 +1 +5 +5 +5 +5 +DROP TABLE general; +CREATE TABLE master_heartbeat_period (slow INT, general INT, master_heartbeat_period INT, ignore_server_ids INT); +INSERT INTO master_heartbeat_period(slow, general, master_heartbeat_period, ignore_server_ids) VALUES (1,2,3,4), (5,6,7,8); +INSERT INTO master_heartbeat_period(slow, general, master_heartbeat_period) VALUES (1,2,3), (5,6,7); +INSERT INTO master_heartbeat_period(slow, general) VALUES (1,2), (5,6); +INSERT INTO master_heartbeat_period(slow) VALUES (1), (5); +SELECT slow, general, master_heartbeat_period, slow FROM master_heartbeat_period ORDER BY slow; +slow general master_heartbeat_period slow +1 2 3 1 +1 2 3 1 +1 2 NULL 1 +1 NULL NULL 1 +5 6 7 5 +5 6 7 5 +5 6 NULL 5 +5 NULL NULL 5 +SELECT slow, general, master_heartbeat_period FROM master_heartbeat_period ORDER BY slow; +slow general master_heartbeat_period +1 2 3 +1 2 3 +1 2 NULL +1 NULL NULL +5 6 7 +5 6 7 +5 6 NULL +5 NULL NULL +SELECT slow, master_heartbeat_period FROM master_heartbeat_period ORDER BY slow; +slow master_heartbeat_period +1 3 +1 3 +1 NULL +1 NULL +5 7 +5 7 +5 NULL +5 NULL +SELECT slow FROM master_heartbeat_period ORDER BY slow; +slow +1 +1 +1 +1 +5 +5 +5 +5 +DROP TABLE master_heartbeat_period; +CREATE TABLE ignore_server_ids (slow INT, general INT, master_heartbeat_period INT, ignore_server_ids INT); +INSERT INTO ignore_server_ids(slow, general, master_heartbeat_period, ignore_server_ids) VALUES (1,2,3,4), (5,6,7,8); +INSERT INTO ignore_server_ids(slow, general, master_heartbeat_period) VALUES (1,2,3), (5,6,7); +INSERT INTO ignore_server_ids(slow, general) VALUES (1,2), (5,6); +INSERT INTO ignore_server_ids(slow) VALUES (1), (5); +SELECT slow, general, master_heartbeat_period, slow FROM ignore_server_ids ORDER BY slow; +slow general master_heartbeat_period slow +1 2 3 1 +1 2 3 1 +1 2 NULL 1 +1 NULL NULL 1 +5 6 7 5 +5 6 7 5 +5 6 NULL 5 +5 NULL NULL 5 +SELECT slow, general, master_heartbeat_period FROM ignore_server_ids ORDER BY slow; +slow general master_heartbeat_period +1 2 3 +1 2 3 +1 2 NULL +1 NULL NULL +5 6 7 +5 6 7 +5 6 NULL +5 NULL NULL +SELECT slow, master_heartbeat_period FROM ignore_server_ids ORDER BY slow; +slow master_heartbeat_period +1 3 +1 3 +1 NULL +1 NULL +5 7 +5 7 +5 NULL +5 NULL +SELECT slow FROM ignore_server_ids ORDER BY slow; +slow +1 +1 +1 +1 +5 +5 +5 +5 +DROP TABLE ignore_server_ids; +CREATE TABLE t1 (slow INT, general INT, ignore_server_ids INT, master_heartbeat_period INT); +INSERT INTO t1 VALUES (1,2,3,4); +CREATE PROCEDURE p1() +BEGIN +DECLARE slow INT; +DECLARE general INT; +DECLARE ignore_server_ids INT; +DECLARE master_heartbeat_period INT; +SELECT max(t1.slow) INTO slow FROM t1; +SELECT max(t1.general) INTO general FROM t1; +SELECT max(t1.ignore_server_ids) INTO ignore_server_ids FROM t1; +SELECT max(t1.master_heartbeat_period) INTO master_heartbeat_period FROM t1; +SELECT slow, general, ignore_server_ids, master_heartbeat_period; +END| +CREATE PROCEDURE p2() +BEGIN +DECLARE n INT DEFAULT 2; +general: WHILE n > 0 DO +SET n = n -1; +END WHILE general; +SET n = 2; +slow: WHILE n > 0 DO +SET n = n -1; +END WHILE slow; +SET n = 2; +ignore_server_ids: WHILE n > 0 DO +SET n = n -1; +END WHILE ignore_server_ids; +SET n = 2; +master_heartbeat_period: WHILE n > 0 DO +SET n = n -1; +END WHILE master_heartbeat_period; +END| +CALL p1(); +slow general ignore_server_ids master_heartbeat_period +1 2 3 4 +call p2(); +DROP PROCEDURE p1; +DROP PROCEDURE p2; +DROP TABLE t1; diff --git a/mysql-test/t/keywords.test b/mysql-test/t/keywords.test index 3080c4847b4..2681f786f40 100644 --- a/mysql-test/t/keywords.test +++ b/mysql-test/t/keywords.test @@ -62,5 +62,103 @@ call p1(); drop procedure p1; drop table t1; - # End of 5.0 tests + +# +# BUG#57899: Certain reserved words should not be reserved +# + +# +# We are looking for SYNTAX ERRORS here, so no need to +# log the queries +# + +CREATE TABLE slow (slow INT, general INT, master_heartbeat_period INT, ignore_server_ids INT); +INSERT INTO slow(slow, general, master_heartbeat_period, ignore_server_ids) VALUES (1,2,3,4), (5,6,7,8); +INSERT INTO slow(slow, general, master_heartbeat_period) VALUES (1,2,3), (5,6,7); +INSERT INTO slow(slow, general) VALUES (1,2), (5,6); +INSERT INTO slow(slow) VALUES (1), (5); +SELECT slow, general, master_heartbeat_period, slow FROM slow ORDER BY slow; +SELECT slow, general, master_heartbeat_period FROM slow ORDER BY slow; +SELECT slow, master_heartbeat_period FROM slow ORDER BY slow; +SELECT slow FROM slow ORDER BY slow; +DROP TABLE slow; +CREATE TABLE general (slow INT, general INT, master_heartbeat_period INT, ignore_server_ids INT); +INSERT INTO general(slow, general, master_heartbeat_period, ignore_server_ids) VALUES (1,2,3,4), (5,6,7,8); +INSERT INTO general(slow, general, master_heartbeat_period) VALUES (1,2,3), (5,6,7); +INSERT INTO general(slow, general) VALUES (1,2), (5,6); +INSERT INTO general(slow) VALUES (1), (5); +SELECT slow, general, master_heartbeat_period, slow FROM general ORDER BY slow; +SELECT slow, general, master_heartbeat_period FROM general ORDER BY slow; +SELECT slow, master_heartbeat_period FROM general ORDER BY slow; +SELECT slow FROM general ORDER BY slow; +DROP TABLE general; +CREATE TABLE master_heartbeat_period (slow INT, general INT, master_heartbeat_period INT, ignore_server_ids INT); +INSERT INTO master_heartbeat_period(slow, general, master_heartbeat_period, ignore_server_ids) VALUES (1,2,3,4), (5,6,7,8); +INSERT INTO master_heartbeat_period(slow, general, master_heartbeat_period) VALUES (1,2,3), (5,6,7); +INSERT INTO master_heartbeat_period(slow, general) VALUES (1,2), (5,6); +INSERT INTO master_heartbeat_period(slow) VALUES (1), (5); +SELECT slow, general, master_heartbeat_period, slow FROM master_heartbeat_period ORDER BY slow; +SELECT slow, general, master_heartbeat_period FROM master_heartbeat_period ORDER BY slow; +SELECT slow, master_heartbeat_period FROM master_heartbeat_period ORDER BY slow; +SELECT slow FROM master_heartbeat_period ORDER BY slow; +DROP TABLE master_heartbeat_period; +CREATE TABLE ignore_server_ids (slow INT, general INT, master_heartbeat_period INT, ignore_server_ids INT); +INSERT INTO ignore_server_ids(slow, general, master_heartbeat_period, ignore_server_ids) VALUES (1,2,3,4), (5,6,7,8); +INSERT INTO ignore_server_ids(slow, general, master_heartbeat_period) VALUES (1,2,3), (5,6,7); +INSERT INTO ignore_server_ids(slow, general) VALUES (1,2), (5,6); +INSERT INTO ignore_server_ids(slow) VALUES (1), (5); +SELECT slow, general, master_heartbeat_period, slow FROM ignore_server_ids ORDER BY slow; +SELECT slow, general, master_heartbeat_period FROM ignore_server_ids ORDER BY slow; +SELECT slow, master_heartbeat_period FROM ignore_server_ids ORDER BY slow; +SELECT slow FROM ignore_server_ids ORDER BY slow; +DROP TABLE ignore_server_ids; + +CREATE TABLE t1 (slow INT, general INT, ignore_server_ids INT, master_heartbeat_period INT); +INSERT INTO t1 VALUES (1,2,3,4); +DELIMITER |; +CREATE PROCEDURE p1() +BEGIN + DECLARE slow INT; + DECLARE general INT; + DECLARE ignore_server_ids INT; + DECLARE master_heartbeat_period INT; + + SELECT max(t1.slow) INTO slow FROM t1; + SELECT max(t1.general) INTO general FROM t1; + SELECT max(t1.ignore_server_ids) INTO ignore_server_ids FROM t1; + SELECT max(t1.master_heartbeat_period) INTO master_heartbeat_period FROM t1; + + SELECT slow, general, ignore_server_ids, master_heartbeat_period; +END| + +CREATE PROCEDURE p2() +BEGIN + + DECLARE n INT DEFAULT 2; + general: WHILE n > 0 DO + SET n = n -1; + END WHILE general; + + SET n = 2; + slow: WHILE n > 0 DO + SET n = n -1; + END WHILE slow; + + SET n = 2; + ignore_server_ids: WHILE n > 0 DO + SET n = n -1; + END WHILE ignore_server_ids; + + SET n = 2; + master_heartbeat_period: WHILE n > 0 DO + SET n = n -1; + END WHILE master_heartbeat_period; + +END| +DELIMITER ;| +CALL p1(); +call p2(); +DROP PROCEDURE p1; +DROP PROCEDURE p2; +DROP TABLE t1; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 396c426f29f..66d74a398fb 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -12497,6 +12497,7 @@ keyword_sp: | FILE_SYM {} | FIRST_SYM {} | FIXED_SYM {} + | GENERAL {} | GEOMETRY_SYM {} | GEOMETRYCOLLECTION {} | GET_FORMAT {} @@ -12506,6 +12507,7 @@ keyword_sp: | HOSTS_SYM {} | HOUR_SYM {} | IDENTIFIED_SYM {} + | IGNORE_SERVER_IDS_SYM {} | INVOKER_SYM {} | IMPORT {} | INDEXES {} @@ -12528,6 +12530,7 @@ keyword_sp: | LOGS_SYM {} | MAX_ROWS {} | MASTER_SYM {} + | MASTER_HEARTBEAT_PERIOD_SYM {} | MASTER_HOST_SYM {} | MASTER_PORT_SYM {} | MASTER_LOG_FILE_SYM {} @@ -12633,6 +12636,7 @@ keyword_sp: | SIMPLE_SYM {} | SHARE_SYM {} | SHUTDOWN {} + | SLOW {} | SNAPSHOT_SYM {} | SOUNDS_SYM {} | SOURCE_SYM {} From 4e1678daca86af018fb4921a15e87ec28dbaacd1 Mon Sep 17 00:00:00 2001 From: Marc Alff Date: Wed, 3 Nov 2010 16:42:33 +0100 Subject: [PATCH 172/304] Bug#57609 performance_schema does not work with lower_case_table_names Before this fix, the performance schema tables were defined in UPPERCASE. This was incompatible with the lowercase_table_names option, and caused issues with the install / upgrade process, when changing the lower case table names setting *after* the install or upgrade. With this fix, all performance schema tables are exposed with lowercase names. As a result, the name of the performance schema table is always lowercase, no matter how / if / when the lowercase_table_names setting if changed. --- .../perfschema/include/binlog_common.inc | 12 +- .../perfschema/include/cleanup_helper.inc | 2 +- .../suite/perfschema/include/privilege.inc | 97 ++-- .../suite/perfschema/include/setup_helper.inc | 14 +- .../include/start_server_common.inc | 42 +- .../suite/perfschema/r/aggregate.result | 66 +-- .../suite/perfschema/r/binlog_mix.result | 16 +- .../suite/perfschema/r/binlog_row.result | 16 +- .../suite/perfschema/r/binlog_stmt.result | 20 +- mysql-test/suite/perfschema/r/checksum.result | 68 +-- .../perfschema/r/column_privilege.result | 32 +- .../perfschema/r/ddl_cond_instances.result | 8 +- .../r/ddl_events_waits_current.result | 8 +- .../r/ddl_events_waits_history.result | 8 +- .../r/ddl_events_waits_history_long.result | 8 +- .../perfschema/r/ddl_ews_by_instance.result | 8 +- .../r/ddl_ews_by_thread_by_event_name.result | 8 +- .../r/ddl_ews_global_by_event_name.result | 8 +- .../perfschema/r/ddl_file_instances.result | 8 +- .../perfschema/r/ddl_fs_by_event_name.result | 8 +- .../perfschema/r/ddl_fs_by_instance.result | 8 +- .../perfschema/r/ddl_mutex_instances.result | 8 +- .../r/ddl_performance_timers.result | 8 +- .../perfschema/r/ddl_rwlock_instances.result | 8 +- .../perfschema/r/ddl_setup_consumers.result | 8 +- .../perfschema/r/ddl_setup_instruments.result | 8 +- .../perfschema/r/ddl_setup_timers.result | 8 +- .../suite/perfschema/r/ddl_threads.result | 8 +- .../perfschema/r/dml_cond_instances.result | 28 +- .../r/dml_events_waits_current.result | 32 +- .../r/dml_events_waits_history.result | 36 +- .../r/dml_events_waits_history_long.result | 36 +- .../perfschema/r/dml_ews_by_instance.result | 40 +- .../r/dml_ews_by_thread_by_event_name.result | 32 +- .../r/dml_ews_global_by_event_name.result | 32 +- .../perfschema/r/dml_file_instances.result | 28 +- .../r/dml_file_summary_by_event_name.result | 32 +- .../r/dml_file_summary_by_instance.result | 32 +- .../perfschema/r/dml_mutex_instances.result | 28 +- .../r/dml_performance_timers.result | 28 +- .../perfschema/r/dml_rwlock_instances.result | 28 +- .../perfschema/r/dml_setup_consumers.result | 28 +- .../perfschema/r/dml_setup_instruments.result | 38 +- .../perfschema/r/dml_setup_timers.result | 30 +- .../suite/perfschema/r/dml_threads.result | 32 +- .../suite/perfschema/r/func_file_io.result | 46 +- .../suite/perfschema/r/func_mutex.result | 48 +- .../perfschema/r/global_read_lock.result | 22 +- .../perfschema/r/information_schema.result | 342 +++++------ mysql-test/suite/perfschema/r/misc.result | 10 +- .../suite/perfschema/r/myisam_file_io.result | 12 +- .../suite/perfschema/r/no_threads.result | 22 +- .../perfschema/r/one_thread_per_con.result | 6 +- .../suite/perfschema/r/privilege.result | 542 +++++++++--------- .../suite/perfschema/r/query_cache.result | 8 +- .../suite/perfschema/r/read_only.result | 18 +- mysql-test/suite/perfschema/r/schema.result | 102 ++-- mysql-test/suite/perfschema/r/selects.result | 42 +- .../suite/perfschema/r/server_init.result | 104 ++-- .../r/start_server_no_cond_class.result | 46 +- .../r/start_server_no_cond_inst.result | 46 +- .../r/start_server_no_file_class.result | 46 +- .../r/start_server_no_file_inst.result | 46 +- .../r/start_server_no_mutex_class.result | 46 +- .../r/start_server_no_mutex_inst.result | 46 +- .../r/start_server_no_rwlock_class.result | 46 +- .../r/start_server_no_rwlock_inst.result | 46 +- .../r/start_server_no_thread_class.result | 46 +- .../r/start_server_no_thread_inst.result | 44 +- .../perfschema/r/start_server_off.result | 42 +- .../suite/perfschema/r/start_server_on.result | 42 +- .../r/tampered_perfschema_table1.result | 6 +- mysql-test/suite/perfschema/t/aggregate.test | 96 ++-- mysql-test/suite/perfschema/t/checksum.test | 68 +-- .../suite/perfschema/t/column_privilege.test | 28 +- .../perfschema/t/ddl_cond_instances.test | 8 +- .../t/ddl_events_waits_current.test | 8 +- .../t/ddl_events_waits_history.test | 8 +- .../t/ddl_events_waits_history_long.test | 8 +- .../perfschema/t/ddl_ews_by_instance.test | 8 +- .../t/ddl_ews_by_thread_by_event_name.test | 8 +- .../t/ddl_ews_global_by_event_name.test | 8 +- .../perfschema/t/ddl_file_instances.test | 8 +- .../perfschema/t/ddl_fs_by_event_name.test | 8 +- .../perfschema/t/ddl_fs_by_instance.test | 8 +- .../perfschema/t/ddl_mutex_instances.test | 8 +- .../perfschema/t/ddl_performance_timers.test | 8 +- .../perfschema/t/ddl_rwlock_instances.test | 8 +- .../perfschema/t/ddl_setup_consumers.test | 9 +- .../perfschema/t/ddl_setup_instruments.test | 9 +- .../suite/perfschema/t/ddl_setup_timers.test | 9 +- .../suite/perfschema/t/ddl_threads.test | 8 +- .../perfschema/t/dml_cond_instances.test | 22 +- .../t/dml_events_waits_current.test | 25 +- .../t/dml_events_waits_history.test | 29 +- .../t/dml_events_waits_history_long.test | 29 +- .../perfschema/t/dml_ews_by_instance.test | 33 +- .../t/dml_ews_by_thread_by_event_name.test | 25 +- .../t/dml_ews_global_by_event_name.test | 25 +- .../perfschema/t/dml_file_instances.test | 22 +- .../t/dml_file_summary_by_event_name.test | 25 +- .../t/dml_file_summary_by_instance.test | 25 +- .../perfschema/t/dml_mutex_instances.test | 22 +- .../perfschema/t/dml_performance_timers.test | 22 +- .../perfschema/t/dml_rwlock_instances.test | 22 +- .../perfschema/t/dml_setup_consumers.test | 26 +- .../perfschema/t/dml_setup_instruments.test | 36 +- .../suite/perfschema/t/dml_setup_timers.test | 28 +- .../suite/perfschema/t/dml_threads.test | 25 +- .../suite/perfschema/t/func_file_io.test | 54 +- mysql-test/suite/perfschema/t/func_mutex.test | 48 +- .../suite/perfschema/t/global_read_lock.test | 26 +- .../perfschema/t/information_schema.test | 22 +- mysql-test/suite/perfschema/t/misc.test | 10 +- .../suite/perfschema/t/myisam_file_io.test | 12 +- mysql-test/suite/perfschema/t/no_threads.test | 22 +- .../perfschema/t/one_thread_per_con.test | 4 +- mysql-test/suite/perfschema/t/privilege.test | 160 +++--- .../suite/perfschema/t/query_cache.test | 8 +- mysql-test/suite/perfschema/t/read_only.test | 22 +- mysql-test/suite/perfschema/t/schema.test | 34 +- mysql-test/suite/perfschema/t/selects.test | 42 +- .../suite/perfschema/t/server_init.test | 112 ++-- .../t/start_server_no_cond_class.test | 4 +- .../t/start_server_no_cond_inst.test | 4 +- .../t/start_server_no_file_class.test | 4 +- .../t/start_server_no_file_inst.test | 4 +- .../t/start_server_no_mutex_class.test | 4 +- .../t/start_server_no_mutex_inst.test | 4 +- .../t/start_server_no_rwlock_class.test | 4 +- .../t/start_server_no_rwlock_inst.test | 4 +- .../t/start_server_no_thread_class.test | 4 +- .../t/start_server_no_thread_inst.test | 4 +- .../t/tampered_perfschema_table1.test | 10 +- .../suite/perfschema/t/thread_cache.test | 12 +- scripts/mysql_system_tables.sql | 34 +- storage/perfschema/table_events_waits.cc | 6 +- .../perfschema/table_events_waits_summary.cc | 4 +- .../table_ews_global_by_event_name.cc | 2 +- storage/perfschema/table_file_instances.cc | 2 +- storage/perfschema/table_file_summary.cc | 4 +- .../perfschema/table_performance_timers.cc | 2 +- storage/perfschema/table_setup_consumers.cc | 2 +- storage/perfschema/table_setup_instruments.cc | 2 +- storage/perfschema/table_setup_timers.cc | 2 +- storage/perfschema/table_sync_instances.cc | 6 +- storage/perfschema/table_threads.cc | 2 +- 147 files changed, 2132 insertions(+), 2279 deletions(-) diff --git a/mysql-test/suite/perfschema/include/binlog_common.inc b/mysql-test/suite/perfschema/include/binlog_common.inc index 10afe54ab5b..96c01d9a4c8 100644 --- a/mysql-test/suite/perfschema/include/binlog_common.inc +++ b/mysql-test/suite/perfschema/include/binlog_common.inc @@ -17,12 +17,12 @@ RESET MASTER; -select count(*) > 0 from performance_schema.SETUP_INSTRUMENTS; +select count(*) > 0 from performance_schema.setup_instruments; -update performance_schema.SETUP_INSTRUMENTS set enabled='NO' +update performance_schema.setup_instruments set enabled='NO' where name like "wait/synch/rwlock/%"; -select count(*) > 0 from performance_schema.EVENTS_WAITS_CURRENT; +select count(*) > 0 from performance_schema.events_waits_current; --disable_warnings drop table if exists test.t1; @@ -33,16 +33,16 @@ create table test.t1 (thread_id integer); create table test.t2 (name varchar(128)); insert into test.t1 - select thread_id from performance_schema.EVENTS_WAITS_CURRENT; + select thread_id from performance_schema.events_waits_current; insert into test.t2 - select name from performance_schema.SETUP_INSTRUMENTS + select name from performance_schema.setup_instruments where name like "wait/synch/rwlock/%"; drop table test.t1; drop table test.t2; -update performance_schema.SETUP_INSTRUMENTS set enabled='YES' +update performance_schema.setup_instruments set enabled='YES' where name like "wait/synch/rwlock/%"; --source include/show_binlog_events.inc diff --git a/mysql-test/suite/perfschema/include/cleanup_helper.inc b/mysql-test/suite/perfschema/include/cleanup_helper.inc index 5c2429ddb97..b7e37849f78 100644 --- a/mysql-test/suite/perfschema/include/cleanup_helper.inc +++ b/mysql-test/suite/perfschema/include/cleanup_helper.inc @@ -15,7 +15,7 @@ # Tests for PERFORMANCE_SCHEMA -update performance_schema.SETUP_INSTRUMENTS set enabled='YES'; +update performance_schema.setup_instruments set enabled='YES'; disconnect con1; disconnect con2; diff --git a/mysql-test/suite/perfschema/include/privilege.inc b/mysql-test/suite/perfschema/include/privilege.inc index ef2acc995d5..3973c41b51b 100644 --- a/mysql-test/suite/perfschema/include/privilege.inc +++ b/mysql-test/suite/perfschema/include/privilege.inc @@ -32,48 +32,48 @@ drop table if exists test.t1; ## drop table performance_schema.t1; ## ## --error ER_DBACCESS_DENIED_ERROR -## create table performance_schema.SETUP_INSTRUMENTS(a int); +## create table performance_schema.setup_instruments(a int); ## ## --error ER_DBACCESS_DENIED_ERROR -## create table performance_schema.EVENTS_WAITS_CURRENT(a int); +## create table performance_schema.events_waits_current(a int); ## ## --error ER_DBACCESS_DENIED_ERROR -## create table performance_schema.FILE_INSTANCES(a int); +## create table performance_schema.file_instances(a int); ## ## --error ER_DBACCESS_DENIED_ERROR -## drop table performance_schema.SETUP_INSTRUMENTS; +## drop table performance_schema.setup_instruments; ## ## --error ER_DBACCESS_DENIED_ERROR -## drop table performance_schema.EVENTS_WAITS_CURRENT; +## drop table performance_schema.events_waits_current; ## ## --error ER_DBACCESS_DENIED_ERROR -## drop table performance_schema.FILE_INSTANCES; +## drop table performance_schema.file_instances; --error ER_DBACCESS_DENIED_ERROR -rename table performance_schema.SETUP_INSTRUMENTS to test.t1; +rename table performance_schema.setup_instruments to test.t1; --error ER_DBACCESS_DENIED_ERROR -rename table performance_schema.EVENTS_WAITS_CURRENT to test.t1; +rename table performance_schema.events_waits_current to test.t1; --error ER_DBACCESS_DENIED_ERROR -rename table performance_schema.FILE_INSTANCES to test.t1; +rename table performance_schema.file_instances to test.t1; --error ER_DBACCESS_DENIED_ERROR -rename table performance_schema.SETUP_INSTRUMENTS to performance_schema.t1; +rename table performance_schema.setup_instruments to performance_schema.t1; --error ER_DBACCESS_DENIED_ERROR -rename table performance_schema.EVENTS_WAITS_CURRENT to performance_schema.t1; +rename table performance_schema.events_waits_current to performance_schema.t1; --error ER_DBACCESS_DENIED_ERROR -rename table performance_schema.FILE_INSTANCES to performance_schema.t1; +rename table performance_schema.file_instances to performance_schema.t1; --error ER_DBACCESS_DENIED_ERROR -rename table performance_schema.SETUP_INSTRUMENTS - to performance_schema.EVENTS_WAITS_CURRENT; +rename table performance_schema.setup_instruments + to performance_schema.events_waits_current; --error ER_DBACCESS_DENIED_ERROR -rename table performance_schema.EVENTS_WAITS_CURRENT - to performance_schema.SETUP_INSTRUMENTS; +rename table performance_schema.events_waits_current + to performance_schema.setup_instruments; --error ER_DBACCESS_DENIED_ERROR create procedure performance_schema.my_proc() begin end; @@ -87,108 +87,93 @@ do begin end; --error ER_DBACCESS_DENIED_ERROR create trigger performance_schema.bi_setup_instruments - before insert on performance_schema.SETUP_INSTRUMENTS + before insert on performance_schema.setup_instruments for each row begin end; --error ER_DBACCESS_DENIED_ERROR create trigger performance_schema.bi_events_waits_current - before insert on performance_schema.EVENTS_WAITS_CURRENT + before insert on performance_schema.events_waits_current for each row begin end; --error ER_DBACCESS_DENIED_ERROR create trigger performance_schema.bi_file_instances - before insert on performance_schema.FILE_INSTANCES + before insert on performance_schema.file_instances for each row begin end; --error ER_WRONG_PERFSCHEMA_USAGE create table test.t1(a int) engine=PERFORMANCE_SCHEMA; --error ER_WRONG_PERFSCHEMA_USAGE -create table test.t1 like performance_schema.SETUP_INSTRUMENTS; +create table test.t1 like performance_schema.setup_instruments; --error ER_WRONG_PERFSCHEMA_USAGE -create table test.t1 like performance_schema.EVENTS_WAITS_CURRENT; +create table test.t1 like performance_schema.events_waits_current; --error ER_WRONG_PERFSCHEMA_USAGE -create table test.t1 like performance_schema.FILE_INSTANCES; +create table test.t1 like performance_schema.file_instances; ---replace_result '\'setup_instruments' '\'SETUP_INSTRUMENTS' --error ER_TABLEACCESS_DENIED_ERROR -insert into performance_schema.SETUP_INSTRUMENTS +insert into performance_schema.setup_instruments set name="foo"; ---replace_result '\'events_waits_current' '\'EVENTS_WAITS_CURRENT' --error ER_TABLEACCESS_DENIED_ERROR -insert into performance_schema.EVENTS_WAITS_CURRENT +insert into performance_schema.events_waits_current set name="foo"; ---replace_result '\'file_instances' '\'FILE_INSTANCES' --error ER_TABLEACCESS_DENIED_ERROR -insert into performance_schema.FILE_INSTANCES +insert into performance_schema.file_instances set name="foo"; ---replace_result '\'setup_instruments' '\'SETUP_INSTRUMENTS' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.SETUP_INSTRUMENTS; +delete from performance_schema.setup_instruments; ---replace_result '\'events_waits_current' '\'EVENTS_WAITS_CURRENT' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.EVENTS_WAITS_CURRENT; +delete from performance_schema.events_waits_current; ---replace_result '\'file_instances' '\'FILE_INSTANCES' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.FILE_INSTANCES; +delete from performance_schema.file_instances; -lock table performance_schema.SETUP_INSTRUMENTS read; +lock table performance_schema.setup_instruments read; unlock tables; -lock table performance_schema.SETUP_INSTRUMENTS write; +lock table performance_schema.setup_instruments write; unlock tables; ---replace_result '\'events_waits_current' '\'EVENTS_WAITS_CURRENT' --error ER_TABLEACCESS_DENIED_ERROR -lock table performance_schema.EVENTS_WAITS_CURRENT read; +lock table performance_schema.events_waits_current read; unlock tables; ---replace_result '\'events_waits_current' '\'EVENTS_WAITS_CURRENT' --error ER_TABLEACCESS_DENIED_ERROR -lock table performance_schema.EVENTS_WAITS_CURRENT write; +lock table performance_schema.events_waits_current write; unlock tables; ---replace_result '\'file_instances' '\'FILE_INSTANCES' --error ER_TABLEACCESS_DENIED_ERROR -lock table performance_schema.FILE_INSTANCES read; +lock table performance_schema.file_instances read; unlock tables; ---replace_result '\'file_instances' '\'FILE_INSTANCES' --error ER_TABLEACCESS_DENIED_ERROR -lock table performance_schema.FILE_INSTANCES write; +lock table performance_schema.file_instances write; unlock tables; --echo # --echo # WL#4818, NFS2: Can use grants to give normal user access ---echo # to view data from _CURRENT and _HISTORY tables +--echo # to view data from _current and _history tables --echo # --echo # Should work as pfs_user_1 and pfs_user_2, but not as pfs_user_3. ---echo # (Except for EVENTS_WAITS_CURRENT, which is granted.) +--echo # (Except for events_waits_current, which is granted.) # Errors here will be caught by the diff afterwards --disable_abort_on_error ---replace_result '\'events_waits_history' '\'EVENTS_WAITS_HISTORY' -SELECT "can select" FROM performance_schema.EVENTS_WAITS_HISTORY LIMIT 1; +SELECT "can select" FROM performance_schema.events_waits_history LIMIT 1; ---replace_result '\'events_waits_history_long' '\'EVENTS_WAITS_HISTORY_LONG' -SELECT "can select" FROM performance_schema.EVENTS_WAITS_HISTORY_LONG LIMIT 1; +SELECT "can select" FROM performance_schema.events_waits_history_long LIMIT 1; ---replace_result '\'events_waits_current' '\'EVENTS_WAITS_CURRENT' -SELECT "can select" FROM performance_schema.EVENTS_WAITS_CURRENT LIMIT 1; +SELECT "can select" FROM performance_schema.events_waits_current LIMIT 1; ---replace_result '\'events_waits_summary_by_instance' '\'EVENTS_WAITS_SUMMARY_BY_INSTANCE' -SELECT "can select" FROM performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE LIMIT 1; +SELECT "can select" FROM performance_schema.events_waits_summary_by_instance LIMIT 1; ---replace_result '\'file_summary_by_instance' '\'FILE_SUMMARY_BY_INSTANCE' -SELECT "can select" FROM performance_schema.FILE_SUMMARY_BY_INSTANCE LIMIT 1; +SELECT "can select" FROM performance_schema.file_summary_by_instance LIMIT 1; --enable_abort_on_error diff --git a/mysql-test/suite/perfschema/include/setup_helper.inc b/mysql-test/suite/perfschema/include/setup_helper.inc index 195b9cf960a..cdbfd81a24c 100644 --- a/mysql-test/suite/perfschema/include/setup_helper.inc +++ b/mysql-test/suite/perfschema/include/setup_helper.inc @@ -19,23 +19,23 @@ let $MYSQLD_DATADIR= `select @@datadir`; let $MYSQLD_TMPDIR= `select @@tmpdir`; --disable_query_log -update performance_schema.SETUP_INSTRUMENTS set enabled='NO'; -update performance_schema.SETUP_CONSUMERS set enabled='YES'; +update performance_schema.setup_instruments set enabled='NO'; +update performance_schema.setup_consumers set enabled='YES'; --enable_query_log connect (con1, localhost, root, , ); -let $con1_THREAD_ID=`select thread_id from performance_schema.THREADS +let $con1_THREAD_ID=`select thread_id from performance_schema.threads where PROCESSLIST_ID = connection_id()`; connect (con2, localhost, root, , ); -let $con2_THREAD_ID=`select thread_id from performance_schema.THREADS +let $con2_THREAD_ID=`select thread_id from performance_schema.threads where PROCESSLIST_ID = connection_id()`; connect (con3, localhost, root, , ); -let $con3_THREAD_ID=`select thread_id from performance_schema.THREADS +let $con3_THREAD_ID=`select thread_id from performance_schema.threads where PROCESSLIST_ID = connection_id()`; connection default; @@ -45,10 +45,10 @@ prepare stmt_dump_events from "select event_name, left(source, locate(\":\", source)) as short_source, operation, number_of_bytes - from performance_schema.EVENTS_WAITS_HISTORY_LONG + from performance_schema.events_waits_history_long where thread_id=? order by event_id;"; prepare stmt_dump_thread from - "select name from performance_schema.THREADS where thread_id=? ;"; + "select name from performance_schema.threads where thread_id=? ;"; --enable_query_log diff --git a/mysql-test/suite/perfschema/include/start_server_common.inc b/mysql-test/suite/perfschema/include/start_server_common.inc index 083b302c5f7..f6e549ea44e 100644 --- a/mysql-test/suite/perfschema/include/start_server_common.inc +++ b/mysql-test/suite/perfschema/include/start_server_common.inc @@ -17,31 +17,31 @@ show databases; -select count(*) from performance_schema.PERFORMANCE_TIMERS; -select count(*) from performance_schema.SETUP_CONSUMERS; -select count(*) > 0 from performance_schema.SETUP_INSTRUMENTS; -select count(*) from performance_schema.SETUP_TIMERS; +select count(*) from performance_schema.performance_timers; +select count(*) from performance_schema.setup_consumers; +select count(*) > 0 from performance_schema.setup_instruments; +select count(*) from performance_schema.setup_timers; # Make sure we don't crash, no matter what the starting parameters are --disable_result_log -select * from performance_schema.COND_INSTANCES; -select * from performance_schema.EVENTS_WAITS_CURRENT; -select * from performance_schema.EVENTS_WAITS_HISTORY; -select * from performance_schema.EVENTS_WAITS_HISTORY_LONG; -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE; -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME; -select * from performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME; -select * from performance_schema.FILE_INSTANCES; -select * from performance_schema.FILE_SUMMARY_BY_EVENT_NAME; -select * from performance_schema.FILE_SUMMARY_BY_INSTANCE; -select * from performance_schema.MUTEX_INSTANCES; -select * from performance_schema.PERFORMANCE_TIMERS; -select * from performance_schema.RWLOCK_INSTANCES; -select * from performance_schema.SETUP_CONSUMERS; -select * from performance_schema.SETUP_INSTRUMENTS; -select * from performance_schema.SETUP_TIMERS; -select * from performance_schema.THREADS; +select * from performance_schema.cond_instances; +select * from performance_schema.events_waits_current; +select * from performance_schema.events_waits_history; +select * from performance_schema.events_waits_history_long; +select * from performance_schema.events_waits_summary_by_instance; +select * from performance_schema.events_waits_summary_by_thread_by_event_name; +select * from performance_schema.events_waits_summary_global_by_event_name; +select * from performance_schema.file_instances; +select * from performance_schema.file_summary_by_event_name; +select * from performance_schema.file_summary_by_instance; +select * from performance_schema.mutex_instances; +select * from performance_schema.performance_timers; +select * from performance_schema.rwlock_instances; +select * from performance_schema.setup_consumers; +select * from performance_schema.setup_instruments; +select * from performance_schema.setup_timers; +select * from performance_schema.threads; --enable_result_log # This has a stable output, printing the result: diff --git a/mysql-test/suite/perfschema/r/aggregate.result b/mysql-test/suite/perfschema/r/aggregate.result index c7ac05ba69d..edc7ce0bcca 100644 --- a/mysql-test/suite/perfschema/r/aggregate.result +++ b/mysql-test/suite/perfschema/r/aggregate.result @@ -1,87 +1,87 @@ "General cleanup" drop table if exists t1; -update performance_schema.SETUP_INSTRUMENTS set enabled = 'NO'; -update performance_schema.SETUP_CONSUMERS set enabled = 'NO'; -truncate table performance_schema.FILE_SUMMARY_BY_EVENT_NAME; -truncate table performance_schema.FILE_SUMMARY_BY_INSTANCE; -truncate table performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME; -truncate table performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE; -truncate table performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME; -update performance_schema.SETUP_CONSUMERS set enabled = 'YES'; -update performance_schema.SETUP_INSTRUMENTS +update performance_schema.setup_instruments set enabled = 'NO'; +update performance_schema.setup_consumers set enabled = 'NO'; +truncate table performance_schema.file_summary_by_event_name; +truncate table performance_schema.file_summary_by_instance; +truncate table performance_schema.events_waits_summary_global_by_event_name; +truncate table performance_schema.events_waits_summary_by_instance; +truncate table performance_schema.events_waits_summary_by_thread_by_event_name; +update performance_schema.setup_consumers set enabled = 'YES'; +update performance_schema.setup_instruments set enabled = 'YES', timed = 'YES'; create table t1 ( id INT PRIMARY KEY, b CHAR(100) DEFAULT 'initial value') ENGINE=MyISAM; insert into t1 (id) values (1), (2), (3), (4), (5), (6), (7), (8); -update performance_schema.SETUP_INSTRUMENTS SET enabled = 'NO'; -update performance_schema.SETUP_CONSUMERS set enabled = 'NO'; +update performance_schema.setup_instruments SET enabled = 'NO'; +update performance_schema.setup_consumers set enabled = 'NO'; set @dump_all=FALSE; "Verifying file aggregate consistency" SELECT EVENT_NAME, e.COUNT_READ, SUM(i.COUNT_READ) -FROM performance_schema.FILE_SUMMARY_BY_EVENT_NAME AS e -JOIN performance_schema.FILE_SUMMARY_BY_INSTANCE AS i USING (EVENT_NAME) +FROM performance_schema.file_summary_by_event_name AS e +JOIN performance_schema.file_summary_by_instance AS i USING (EVENT_NAME) GROUP BY EVENT_NAME HAVING (e.COUNT_READ <> SUM(i.COUNT_READ)) OR @dump_all; EVENT_NAME COUNT_READ SUM(i.COUNT_READ) SELECT EVENT_NAME, e.COUNT_WRITE, SUM(i.COUNT_WRITE) -FROM performance_schema.FILE_SUMMARY_BY_EVENT_NAME AS e -JOIN performance_schema.FILE_SUMMARY_BY_INSTANCE AS i USING (EVENT_NAME) +FROM performance_schema.file_summary_by_event_name AS e +JOIN performance_schema.file_summary_by_instance AS i USING (EVENT_NAME) GROUP BY EVENT_NAME HAVING (e.COUNT_WRITE <> SUM(i.COUNT_WRITE)) OR @dump_all; EVENT_NAME COUNT_WRITE SUM(i.COUNT_WRITE) SELECT EVENT_NAME, e.SUM_NUMBER_OF_BYTES_READ, SUM(i.SUM_NUMBER_OF_BYTES_READ) -FROM performance_schema.FILE_SUMMARY_BY_EVENT_NAME AS e -JOIN performance_schema.FILE_SUMMARY_BY_INSTANCE AS i USING (EVENT_NAME) +FROM performance_schema.file_summary_by_event_name AS e +JOIN performance_schema.file_summary_by_instance AS i USING (EVENT_NAME) GROUP BY EVENT_NAME HAVING (e.SUM_NUMBER_OF_BYTES_READ <> SUM(i.SUM_NUMBER_OF_BYTES_READ)) OR @dump_all; EVENT_NAME SUM_NUMBER_OF_BYTES_READ SUM(i.SUM_NUMBER_OF_BYTES_READ) SELECT EVENT_NAME, e.SUM_NUMBER_OF_BYTES_WRITE, SUM(i.SUM_NUMBER_OF_BYTES_WRITE) -FROM performance_schema.FILE_SUMMARY_BY_EVENT_NAME AS e -JOIN performance_schema.FILE_SUMMARY_BY_INSTANCE AS i USING (EVENT_NAME) +FROM performance_schema.file_summary_by_event_name AS e +JOIN performance_schema.file_summary_by_instance AS i USING (EVENT_NAME) GROUP BY EVENT_NAME HAVING (e.SUM_NUMBER_OF_BYTES_WRITE <> SUM(i.SUM_NUMBER_OF_BYTES_WRITE)) OR @dump_all; EVENT_NAME SUM_NUMBER_OF_BYTES_WRITE SUM(i.SUM_NUMBER_OF_BYTES_WRITE) "Verifying waits aggregate consistency (instance)" SELECT EVENT_NAME, e.SUM_TIMER_WAIT, SUM(i.SUM_TIMER_WAIT) -FROM performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME AS e -JOIN performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE AS i USING (EVENT_NAME) +FROM performance_schema.events_waits_summary_global_by_event_name AS e +JOIN performance_schema.events_waits_summary_by_instance AS i USING (EVENT_NAME) GROUP BY EVENT_NAME HAVING (e.SUM_TIMER_WAIT < SUM(i.SUM_TIMER_WAIT)) OR @dump_all; EVENT_NAME SUM_TIMER_WAIT SUM(i.SUM_TIMER_WAIT) SELECT EVENT_NAME, e.MIN_TIMER_WAIT, MIN(i.MIN_TIMER_WAIT) -FROM performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME AS e -JOIN performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE AS i USING (EVENT_NAME) +FROM performance_schema.events_waits_summary_global_by_event_name AS e +JOIN performance_schema.events_waits_summary_by_instance AS i USING (EVENT_NAME) GROUP BY EVENT_NAME HAVING (e.MIN_TIMER_WAIT > MIN(i.MIN_TIMER_WAIT)) AND (MIN(i.MIN_TIMER_WAIT) != 0) OR @dump_all; EVENT_NAME MIN_TIMER_WAIT MIN(i.MIN_TIMER_WAIT) SELECT EVENT_NAME, e.MAX_TIMER_WAIT, MAX(i.MAX_TIMER_WAIT) -FROM performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME AS e -JOIN performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE AS i USING (EVENT_NAME) +FROM performance_schema.events_waits_summary_global_by_event_name AS e +JOIN performance_schema.events_waits_summary_by_instance AS i USING (EVENT_NAME) GROUP BY EVENT_NAME HAVING (e.MAX_TIMER_WAIT < MAX(i.MAX_TIMER_WAIT)) OR @dump_all; EVENT_NAME MAX_TIMER_WAIT MAX(i.MAX_TIMER_WAIT) "Verifying waits aggregate consistency (thread)" SELECT EVENT_NAME, e.SUM_TIMER_WAIT, SUM(t.SUM_TIMER_WAIT) -FROM performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME AS e -JOIN performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME AS t +FROM performance_schema.events_waits_summary_global_by_event_name AS e +JOIN performance_schema.events_waits_summary_by_thread_by_event_name AS t USING (EVENT_NAME) GROUP BY EVENT_NAME HAVING (e.SUM_TIMER_WAIT < SUM(t.SUM_TIMER_WAIT)) OR @dump_all; EVENT_NAME SUM_TIMER_WAIT SUM(t.SUM_TIMER_WAIT) SELECT EVENT_NAME, e.MIN_TIMER_WAIT, MIN(t.MIN_TIMER_WAIT) -FROM performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME AS e -JOIN performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME AS t +FROM performance_schema.events_waits_summary_global_by_event_name AS e +JOIN performance_schema.events_waits_summary_by_thread_by_event_name AS t USING (EVENT_NAME) GROUP BY EVENT_NAME HAVING (e.MIN_TIMER_WAIT > MIN(t.MIN_TIMER_WAIT)) @@ -89,14 +89,14 @@ AND (MIN(t.MIN_TIMER_WAIT) != 0) OR @dump_all; EVENT_NAME MIN_TIMER_WAIT MIN(t.MIN_TIMER_WAIT) SELECT EVENT_NAME, e.MAX_TIMER_WAIT, MAX(t.MAX_TIMER_WAIT) -FROM performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME AS e -JOIN performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME AS t +FROM performance_schema.events_waits_summary_global_by_event_name AS e +JOIN performance_schema.events_waits_summary_by_thread_by_event_name AS t USING (EVENT_NAME) GROUP BY EVENT_NAME HAVING (e.MAX_TIMER_WAIT < MAX(t.MAX_TIMER_WAIT)) OR @dump_all; EVENT_NAME MAX_TIMER_WAIT MAX(t.MAX_TIMER_WAIT) -update performance_schema.SETUP_CONSUMERS set enabled = 'YES'; -update performance_schema.SETUP_INSTRUMENTS +update performance_schema.setup_consumers set enabled = 'YES'; +update performance_schema.setup_instruments set enabled = 'YES', timed = 'YES'; drop table test.t1; diff --git a/mysql-test/suite/perfschema/r/binlog_mix.result b/mysql-test/suite/perfschema/r/binlog_mix.result index 1e58179af51..b31b853b06d 100644 --- a/mysql-test/suite/perfschema/r/binlog_mix.result +++ b/mysql-test/suite/perfschema/r/binlog_mix.result @@ -1,11 +1,11 @@ set binlog_format=mixed; RESET MASTER; -select count(*) > 0 from performance_schema.SETUP_INSTRUMENTS; +select count(*) > 0 from performance_schema.setup_instruments; count(*) > 0 1 -update performance_schema.SETUP_INSTRUMENTS set enabled='NO' +update performance_schema.setup_instruments set enabled='NO' where name like "wait/synch/rwlock/%"; -select count(*) > 0 from performance_schema.EVENTS_WAITS_CURRENT; +select count(*) > 0 from performance_schema.events_waits_current; count(*) > 0 1 drop table if exists test.t1; @@ -13,18 +13,18 @@ drop table if exists test.t2; create table test.t1 (thread_id integer); create table test.t2 (name varchar(128)); insert into test.t1 -select thread_id from performance_schema.EVENTS_WAITS_CURRENT; +select thread_id from performance_schema.events_waits_current; insert into test.t2 -select name from performance_schema.SETUP_INSTRUMENTS +select name from performance_schema.setup_instruments where name like "wait/synch/rwlock/%"; drop table test.t1; drop table test.t2; -update performance_schema.SETUP_INSTRUMENTS set enabled='YES' +update performance_schema.setup_instruments set enabled='YES' where name like "wait/synch/rwlock/%"; show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # BEGIN -master-bin.000001 # Table_map # # table_id: # (performance_schema.SETUP_INSTRUMENTS) +master-bin.000001 # Table_map # # table_id: # (performance_schema.setup_instruments) master-bin.000001 # Update_rows # # table_id: # master-bin.000001 # Update_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # COMMIT @@ -43,7 +43,7 @@ master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ master-bin.000001 # Query # # use `test`; DROP TABLE `t2` /* generated by server */ master-bin.000001 # Query # # BEGIN -master-bin.000001 # Table_map # # table_id: # (performance_schema.SETUP_INSTRUMENTS) +master-bin.000001 # Table_map # # table_id: # (performance_schema.setup_instruments) master-bin.000001 # Update_rows # # table_id: # master-bin.000001 # Update_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # COMMIT diff --git a/mysql-test/suite/perfschema/r/binlog_row.result b/mysql-test/suite/perfschema/r/binlog_row.result index 28803c73a84..010f2de06e6 100644 --- a/mysql-test/suite/perfschema/r/binlog_row.result +++ b/mysql-test/suite/perfschema/r/binlog_row.result @@ -1,11 +1,11 @@ set binlog_format=row; RESET MASTER; -select count(*) > 0 from performance_schema.SETUP_INSTRUMENTS; +select count(*) > 0 from performance_schema.setup_instruments; count(*) > 0 1 -update performance_schema.SETUP_INSTRUMENTS set enabled='NO' +update performance_schema.setup_instruments set enabled='NO' where name like "wait/synch/rwlock/%"; -select count(*) > 0 from performance_schema.EVENTS_WAITS_CURRENT; +select count(*) > 0 from performance_schema.events_waits_current; count(*) > 0 1 drop table if exists test.t1; @@ -13,18 +13,18 @@ drop table if exists test.t2; create table test.t1 (thread_id integer); create table test.t2 (name varchar(128)); insert into test.t1 -select thread_id from performance_schema.EVENTS_WAITS_CURRENT; +select thread_id from performance_schema.events_waits_current; insert into test.t2 -select name from performance_schema.SETUP_INSTRUMENTS +select name from performance_schema.setup_instruments where name like "wait/synch/rwlock/%"; drop table test.t1; drop table test.t2; -update performance_schema.SETUP_INSTRUMENTS set enabled='YES' +update performance_schema.setup_instruments set enabled='YES' where name like "wait/synch/rwlock/%"; show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # BEGIN -master-bin.000001 # Table_map # # table_id: # (performance_schema.SETUP_INSTRUMENTS) +master-bin.000001 # Table_map # # table_id: # (performance_schema.setup_instruments) master-bin.000001 # Update_rows # # table_id: # master-bin.000001 # Update_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # COMMIT @@ -43,7 +43,7 @@ master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ master-bin.000001 # Query # # use `test`; DROP TABLE `t2` /* generated by server */ master-bin.000001 # Query # # BEGIN -master-bin.000001 # Table_map # # table_id: # (performance_schema.SETUP_INSTRUMENTS) +master-bin.000001 # Table_map # # table_id: # (performance_schema.setup_instruments) master-bin.000001 # Update_rows # # table_id: # master-bin.000001 # Update_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # COMMIT diff --git a/mysql-test/suite/perfschema/r/binlog_stmt.result b/mysql-test/suite/perfschema/r/binlog_stmt.result index 288eba4d3d6..60054ee8a74 100644 --- a/mysql-test/suite/perfschema/r/binlog_stmt.result +++ b/mysql-test/suite/perfschema/r/binlog_stmt.result @@ -1,14 +1,14 @@ set binlog_format=statement; call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); RESET MASTER; -select count(*) > 0 from performance_schema.SETUP_INSTRUMENTS; +select count(*) > 0 from performance_schema.setup_instruments; count(*) > 0 1 -update performance_schema.SETUP_INSTRUMENTS set enabled='NO' +update performance_schema.setup_instruments set enabled='NO' where name like "wait/synch/rwlock/%"; Warnings: Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. The statement is unsafe because it uses the general log, slow query log, or performance_schema table(s). This is unsafe because system tables may differ on slaves. -select count(*) > 0 from performance_schema.EVENTS_WAITS_CURRENT; +select count(*) > 0 from performance_schema.events_waits_current; count(*) > 0 1 drop table if exists test.t1; @@ -16,24 +16,24 @@ drop table if exists test.t2; create table test.t1 (thread_id integer); create table test.t2 (name varchar(128)); insert into test.t1 -select thread_id from performance_schema.EVENTS_WAITS_CURRENT; +select thread_id from performance_schema.events_waits_current; Warnings: Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. The statement is unsafe because it uses the general log, slow query log, or performance_schema table(s). This is unsafe because system tables may differ on slaves. insert into test.t2 -select name from performance_schema.SETUP_INSTRUMENTS +select name from performance_schema.setup_instruments where name like "wait/synch/rwlock/%"; Warnings: Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. The statement is unsafe because it uses the general log, slow query log, or performance_schema table(s). This is unsafe because system tables may differ on slaves. drop table test.t1; drop table test.t2; -update performance_schema.SETUP_INSTRUMENTS set enabled='YES' +update performance_schema.setup_instruments set enabled='YES' where name like "wait/synch/rwlock/%"; Warnings: Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. The statement is unsafe because it uses the general log, slow query log, or performance_schema table(s). This is unsafe because system tables may differ on slaves. show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # BEGIN -master-bin.000001 # Query # # use `test`; update performance_schema.SETUP_INSTRUMENTS set enabled='NO' +master-bin.000001 # Query # # use `test`; update performance_schema.setup_instruments set enabled='NO' where name like "wait/synch/rwlock/%" master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by server */ @@ -42,16 +42,16 @@ master-bin.000001 # Query # # use `test`; create table test.t1 (thread_id intege master-bin.000001 # Query # # use `test`; create table test.t2 (name varchar(128)) master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # use `test`; insert into test.t1 -select thread_id from performance_schema.EVENTS_WAITS_CURRENT +select thread_id from performance_schema.events_waits_current master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # use `test`; insert into test.t2 -select name from performance_schema.SETUP_INSTRUMENTS +select name from performance_schema.setup_instruments where name like "wait/synch/rwlock/%" master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ master-bin.000001 # Query # # use `test`; DROP TABLE `t2` /* generated by server */ master-bin.000001 # Query # # BEGIN -master-bin.000001 # Query # # use `test`; update performance_schema.SETUP_INSTRUMENTS set enabled='YES' +master-bin.000001 # Query # # use `test`; update performance_schema.setup_instruments set enabled='YES' where name like "wait/synch/rwlock/%" master-bin.000001 # Query # # COMMIT diff --git a/mysql-test/suite/perfschema/r/checksum.result b/mysql-test/suite/perfschema/r/checksum.result index 323cb303dae..587dead845a 100644 --- a/mysql-test/suite/perfschema/r/checksum.result +++ b/mysql-test/suite/perfschema/r/checksum.result @@ -1,34 +1,34 @@ -checksum table performance_schema.COND_INSTANCES; -checksum table performance_schema.EVENTS_WAITS_CURRENT; -checksum table performance_schema.EVENTS_WAITS_HISTORY; -checksum table performance_schema.EVENTS_WAITS_HISTORY_LONG; -checksum table performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE; -checksum table performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME; -checksum table performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME; -checksum table performance_schema.FILE_INSTANCES; -checksum table performance_schema.FILE_SUMMARY_BY_EVENT_NAME; -checksum table performance_schema.FILE_SUMMARY_BY_INSTANCE; -checksum table performance_schema.MUTEX_INSTANCES; -checksum table performance_schema.PERFORMANCE_TIMERS; -checksum table performance_schema.RWLOCK_INSTANCES; -checksum table performance_schema.SETUP_CONSUMERS; -checksum table performance_schema.SETUP_INSTRUMENTS; -checksum table performance_schema.SETUP_TIMERS; -checksum table performance_schema.THREADS; -checksum table performance_schema.COND_INSTANCES extended; -checksum table performance_schema.EVENTS_WAITS_CURRENT extended; -checksum table performance_schema.EVENTS_WAITS_HISTORY extended; -checksum table performance_schema.EVENTS_WAITS_HISTORY_LONG extended; -checksum table performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE extended; -checksum table performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME extended; -checksum table performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME extended; -checksum table performance_schema.FILE_INSTANCES extended; -checksum table performance_schema.FILE_SUMMARY_BY_EVENT_NAME extended; -checksum table performance_schema.FILE_SUMMARY_BY_INSTANCE extended; -checksum table performance_schema.MUTEX_INSTANCES extended; -checksum table performance_schema.PERFORMANCE_TIMERS extended; -checksum table performance_schema.RWLOCK_INSTANCES extended; -checksum table performance_schema.SETUP_CONSUMERS extended; -checksum table performance_schema.SETUP_INSTRUMENTS extended; -checksum table performance_schema.SETUP_TIMERS extended; -checksum table performance_schema.THREADS extended; +checksum table performance_schema.cond_instances; +checksum table performance_schema.events_waits_current; +checksum table performance_schema.events_waits_history; +checksum table performance_schema.events_waits_history_long; +checksum table performance_schema.events_waits_summary_by_instance; +checksum table performance_schema.events_waits_summary_by_thread_by_event_name; +checksum table performance_schema.events_waits_summary_global_by_event_name; +checksum table performance_schema.file_instances; +checksum table performance_schema.file_summary_by_event_name; +checksum table performance_schema.file_summary_by_instance; +checksum table performance_schema.mutex_instances; +checksum table performance_schema.performance_timers; +checksum table performance_schema.rwlock_instances; +checksum table performance_schema.setup_consumers; +checksum table performance_schema.setup_instruments; +checksum table performance_schema.setup_timers; +checksum table performance_schema.threads; +checksum table performance_schema.cond_instances extended; +checksum table performance_schema.events_waits_current extended; +checksum table performance_schema.events_waits_history extended; +checksum table performance_schema.events_waits_history_long extended; +checksum table performance_schema.events_waits_summary_by_instance extended; +checksum table performance_schema.events_waits_summary_by_thread_by_event_name extended; +checksum table performance_schema.events_waits_summary_global_by_event_name extended; +checksum table performance_schema.file_instances extended; +checksum table performance_schema.file_summary_by_event_name extended; +checksum table performance_schema.file_summary_by_instance extended; +checksum table performance_schema.mutex_instances extended; +checksum table performance_schema.performance_timers extended; +checksum table performance_schema.rwlock_instances extended; +checksum table performance_schema.setup_consumers extended; +checksum table performance_schema.setup_instruments extended; +checksum table performance_schema.setup_timers extended; +checksum table performance_schema.threads extended; diff --git a/mysql-test/suite/perfschema/r/column_privilege.result b/mysql-test/suite/perfschema/r/column_privilege.result index ac6030690dd..aff5f3e6eee 100644 --- a/mysql-test/suite/perfschema/r/column_privilege.result +++ b/mysql-test/suite/perfschema/r/column_privilege.result @@ -3,26 +3,26 @@ Grants for root@localhost GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION grant usage on *.* to 'pfs_user_5'@localhost with GRANT OPTION; -grant SELECT(thread_id, event_id) on performance_schema.EVENTS_WAITS_CURRENT +grant SELECT(thread_id, event_id) on performance_schema.events_waits_current to 'pfs_user_5'@localhost; -grant UPDATE(enabled) on performance_schema.SETUP_INSTRUMENTS +grant UPDATE(enabled) on performance_schema.setup_instruments to 'pfs_user_5'@localhost; flush privileges; -select thread_id from performance_schema.EVENTS_WAITS_CURRENT; -select thread_id, event_id from performance_schema.EVENTS_WAITS_CURRENT; -update performance_schema.SETUP_INSTRUMENTS set enabled='YES'; -select event_name from performance_schema.EVENTS_WAITS_CURRENT; -ERROR 42000: SELECT command denied to user 'pfs_user_5'@'localhost' for column 'event_name' in table 'EVENTS_WAITS_CURRENT' +select thread_id from performance_schema.events_waits_current; +select thread_id, event_id from performance_schema.events_waits_current; +update performance_schema.setup_instruments set enabled='YES'; +select event_name from performance_schema.events_waits_current; +ERROR 42000: SELECT command denied to user 'pfs_user_5'@'localhost' for column 'event_name' in table 'events_waits_current' select thread_id, event_id, event_name -from performance_schema.EVENTS_WAITS_CURRENT; -ERROR 42000: SELECT command denied to user 'pfs_user_5'@'localhost' for column 'event_name' in table 'EVENTS_WAITS_CURRENT' -update performance_schema.SETUP_INSTRUMENTS set name='illegal'; -ERROR 42000: UPDATE command denied to user 'pfs_user_5'@'localhost' for column 'name' in table 'SETUP_INSTRUMENTS' -update performance_schema.SETUP_INSTRUMENTS set timed='NO'; -ERROR 42000: UPDATE command denied to user 'pfs_user_5'@'localhost' for column 'timed' in table 'SETUP_INSTRUMENTS' +from performance_schema.events_waits_current; +ERROR 42000: SELECT command denied to user 'pfs_user_5'@'localhost' for column 'event_name' in table 'events_waits_current' +update performance_schema.setup_instruments set name='illegal'; +ERROR 42000: UPDATE command denied to user 'pfs_user_5'@'localhost' for column 'name' in table 'setup_instruments' +update performance_schema.setup_instruments set timed='NO'; +ERROR 42000: UPDATE command denied to user 'pfs_user_5'@'localhost' for column 'timed' in table 'setup_instruments' REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'pfs_user_5'@localhost; DROP USER 'pfs_user_5'@localhost; flush privileges; -UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'YES', timed = 'YES'; -UPDATE performance_schema.SETUP_CONSUMERS SET enabled = 'YES'; -UPDATE performance_schema.SETUP_TIMERS SET timer_name = 'CYCLE'; +UPDATE performance_schema.setup_instruments SET enabled = 'YES', timed = 'YES'; +UPDATE performance_schema.setup_consumers SET enabled = 'YES'; +UPDATE performance_schema.setup_timers SET timer_name = 'CYCLE'; diff --git a/mysql-test/suite/perfschema/r/ddl_cond_instances.result b/mysql-test/suite/perfschema/r/ddl_cond_instances.result index 33adcebaceb..6b8b40af463 100644 --- a/mysql-test/suite/perfschema/r/ddl_cond_instances.result +++ b/mysql-test/suite/perfschema/r/ddl_cond_instances.result @@ -1,8 +1,8 @@ -alter table performance_schema.COND_INSTANCES add column foo integer; +alter table performance_schema.cond_instances add column foo integer; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -truncate table performance_schema.COND_INSTANCES; +truncate table performance_schema.cond_instances; ERROR HY000: Invalid performance_schema usage. -ALTER TABLE performance_schema.COND_INSTANCES ADD INDEX test_index(NAME); +ALTER TABLE performance_schema.cond_instances ADD INDEX test_index(NAME); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -CREATE UNIQUE INDEX test_index ON performance_schema.COND_INSTANCES(NAME); +CREATE UNIQUE INDEX test_index ON performance_schema.cond_instances(NAME); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' diff --git a/mysql-test/suite/perfschema/r/ddl_events_waits_current.result b/mysql-test/suite/perfschema/r/ddl_events_waits_current.result index a438c93affe..545134e5bd0 100644 --- a/mysql-test/suite/perfschema/r/ddl_events_waits_current.result +++ b/mysql-test/suite/perfschema/r/ddl_events_waits_current.result @@ -1,7 +1,7 @@ -alter table performance_schema.EVENTS_WAITS_CURRENT add column foo integer; +alter table performance_schema.events_waits_current add column foo integer; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -truncate table performance_schema.EVENTS_WAITS_CURRENT; -ALTER TABLE performance_schema.EVENTS_WAITS_CURRENT ADD INDEX test_index(EVENT_ID); +truncate table performance_schema.events_waits_current; +ALTER TABLE performance_schema.events_waits_current ADD INDEX test_index(EVENT_ID); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -CREATE UNIQUE INDEX test_index ON performance_schema.EVENTS_WAITS_CURRENT(EVENT_ID); +CREATE UNIQUE INDEX test_index ON performance_schema.events_waits_current(EVENT_ID); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' diff --git a/mysql-test/suite/perfschema/r/ddl_events_waits_history.result b/mysql-test/suite/perfschema/r/ddl_events_waits_history.result index 748dc2f29cd..2907e865b37 100644 --- a/mysql-test/suite/perfschema/r/ddl_events_waits_history.result +++ b/mysql-test/suite/perfschema/r/ddl_events_waits_history.result @@ -1,7 +1,7 @@ -alter table performance_schema.EVENTS_WAITS_HISTORY add column foo integer; +alter table performance_schema.events_waits_history add column foo integer; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -truncate table performance_schema.EVENTS_WAITS_HISTORY; -ALTER TABLE performance_schema.EVENTS_WAITS_HISTORY ADD INDEX test_index(EVENT_ID); +truncate table performance_schema.events_waits_history; +ALTER TABLE performance_schema.events_waits_history ADD INDEX test_index(EVENT_ID); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -CREATE UNIQUE INDEX test_index ON performance_schema.EVENTS_WAITS_HISTORY(EVENT_ID); +CREATE UNIQUE INDEX test_index ON performance_schema.events_waits_history(EVENT_ID); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' diff --git a/mysql-test/suite/perfschema/r/ddl_events_waits_history_long.result b/mysql-test/suite/perfschema/r/ddl_events_waits_history_long.result index 1a047a765f6..8926d39374b 100644 --- a/mysql-test/suite/perfschema/r/ddl_events_waits_history_long.result +++ b/mysql-test/suite/perfschema/r/ddl_events_waits_history_long.result @@ -1,7 +1,7 @@ -alter table performance_schema.EVENTS_WAITS_HISTORY_LONG add column foo integer; +alter table performance_schema.events_waits_history_long add column foo integer; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -truncate table performance_schema.EVENTS_WAITS_HISTORY_LONG; -ALTER TABLE performance_schema.EVENTS_WAITS_HISTORY_LONG ADD INDEX test_index(EVENT_ID); +truncate table performance_schema.events_waits_history_long; +ALTER TABLE performance_schema.events_waits_history_long ADD INDEX test_index(EVENT_ID); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -CREATE UNIQUE INDEX test_index ON performance_schema.EVENTS_WAITS_HISTORY_LONG(EVENT_ID); +CREATE UNIQUE INDEX test_index ON performance_schema.events_waits_history_long(EVENT_ID); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' diff --git a/mysql-test/suite/perfschema/r/ddl_ews_by_instance.result b/mysql-test/suite/perfschema/r/ddl_ews_by_instance.result index 4a35565bae0..94168f16eb7 100644 --- a/mysql-test/suite/perfschema/r/ddl_ews_by_instance.result +++ b/mysql-test/suite/perfschema/r/ddl_ews_by_instance.result @@ -1,7 +1,7 @@ -alter table performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE add column foo integer; +alter table performance_schema.events_waits_summary_by_instance add column foo integer; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -truncate table performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE; -ALTER TABLE performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE ADD INDEX test_index(EVENT_NAME); +truncate table performance_schema.events_waits_summary_by_instance; +ALTER TABLE performance_schema.events_waits_summary_by_instance ADD INDEX test_index(EVENT_NAME); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -CREATE UNIQUE INDEX test_index ON performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE(EVENT_NAME); +CREATE UNIQUE INDEX test_index ON performance_schema.events_waits_summary_by_instance(EVENT_NAME); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' diff --git a/mysql-test/suite/perfschema/r/ddl_ews_by_thread_by_event_name.result b/mysql-test/suite/perfschema/r/ddl_ews_by_thread_by_event_name.result index 18d98006220..1694ff9287d 100644 --- a/mysql-test/suite/perfschema/r/ddl_ews_by_thread_by_event_name.result +++ b/mysql-test/suite/perfschema/r/ddl_ews_by_thread_by_event_name.result @@ -1,9 +1,9 @@ -alter table performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME +alter table performance_schema.events_waits_summary_by_thread_by_event_name add column foo integer; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -truncate table performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME; -ALTER TABLE performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME ADD INDEX test_index(THREAD_ID); +truncate table performance_schema.events_waits_summary_by_thread_by_event_name; +ALTER TABLE performance_schema.events_waits_summary_by_thread_by_event_name ADD INDEX test_index(THREAD_ID); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' CREATE UNIQUE INDEX test_index -ON performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME(THREAD_ID); +ON performance_schema.events_waits_summary_by_thread_by_event_name(THREAD_ID); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' diff --git a/mysql-test/suite/perfschema/r/ddl_ews_global_by_event_name.result b/mysql-test/suite/perfschema/r/ddl_ews_global_by_event_name.result index 4f3ebcaea43..3b8cf851f80 100644 --- a/mysql-test/suite/perfschema/r/ddl_ews_global_by_event_name.result +++ b/mysql-test/suite/perfschema/r/ddl_ews_global_by_event_name.result @@ -1,10 +1,10 @@ -alter table performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME +alter table performance_schema.events_waits_summary_global_by_event_name add column foo integer; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -truncate table performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME; -ALTER TABLE performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME +truncate table performance_schema.events_waits_summary_global_by_event_name; +ALTER TABLE performance_schema.events_waits_summary_global_by_event_name ADD INDEX test_index(EVENT_NAME); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' CREATE UNIQUE INDEX test_index -ON performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME(EVENT_NAME); +ON performance_schema.events_waits_summary_global_by_event_name(EVENT_NAME); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' diff --git a/mysql-test/suite/perfschema/r/ddl_file_instances.result b/mysql-test/suite/perfschema/r/ddl_file_instances.result index 21e65c62405..338a0260326 100644 --- a/mysql-test/suite/perfschema/r/ddl_file_instances.result +++ b/mysql-test/suite/perfschema/r/ddl_file_instances.result @@ -1,8 +1,8 @@ -alter table performance_schema.FILE_INSTANCES add column foo integer; +alter table performance_schema.file_instances add column foo integer; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -truncate table performance_schema.FILE_INSTANCES; +truncate table performance_schema.file_instances; ERROR HY000: Invalid performance_schema usage. -ALTER TABLE performance_schema.FILE_INSTANCES ADD INDEX test_index(FILE_NAME); +ALTER TABLE performance_schema.file_instances ADD INDEX test_index(FILE_NAME); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -CREATE UNIQUE INDEX test_index ON performance_schema.FILE_INSTANCES(FILE_NAME); +CREATE UNIQUE INDEX test_index ON performance_schema.file_instances(FILE_NAME); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' diff --git a/mysql-test/suite/perfschema/r/ddl_fs_by_event_name.result b/mysql-test/suite/perfschema/r/ddl_fs_by_event_name.result index 2f21ef56832..11bff4104bb 100644 --- a/mysql-test/suite/perfschema/r/ddl_fs_by_event_name.result +++ b/mysql-test/suite/perfschema/r/ddl_fs_by_event_name.result @@ -1,7 +1,7 @@ -alter table performance_schema.FILE_SUMMARY_BY_EVENT_NAME add column foo integer; +alter table performance_schema.file_summary_by_event_name add column foo integer; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -truncate table performance_schema.FILE_SUMMARY_BY_EVENT_NAME; -ALTER TABLE performance_schema.FILE_SUMMARY_BY_EVENT_NAME ADD INDEX test_index(NAME); +truncate table performance_schema.file_summary_by_event_name; +ALTER TABLE performance_schema.file_summary_by_event_name ADD INDEX test_index(NAME); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -CREATE UNIQUE INDEX test_index ON performance_schema.FILE_SUMMARY_BY_EVENT_NAME(NAME); +CREATE UNIQUE INDEX test_index ON performance_schema.file_summary_by_event_name(NAME); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' diff --git a/mysql-test/suite/perfschema/r/ddl_fs_by_instance.result b/mysql-test/suite/perfschema/r/ddl_fs_by_instance.result index 8e256d1fd8d..b28847b3aca 100644 --- a/mysql-test/suite/perfschema/r/ddl_fs_by_instance.result +++ b/mysql-test/suite/perfschema/r/ddl_fs_by_instance.result @@ -1,7 +1,7 @@ -alter table performance_schema.FILE_SUMMARY_BY_INSTANCE add column foo integer; +alter table performance_schema.file_summary_by_instance add column foo integer; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -truncate table performance_schema.FILE_SUMMARY_BY_INSTANCE; -ALTER TABLE performance_schema.FILE_SUMMARY_BY_INSTANCE ADD INDEX test_index(NAME); +truncate table performance_schema.file_summary_by_instance; +ALTER TABLE performance_schema.file_summary_by_instance ADD INDEX test_index(NAME); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -CREATE UNIQUE INDEX test_index ON performance_schema.FILE_SUMMARY_BY_INSTANCE(NAME); +CREATE UNIQUE INDEX test_index ON performance_schema.file_summary_by_instance(NAME); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' diff --git a/mysql-test/suite/perfschema/r/ddl_mutex_instances.result b/mysql-test/suite/perfschema/r/ddl_mutex_instances.result index 35397a5294d..0e35b0d766a 100644 --- a/mysql-test/suite/perfschema/r/ddl_mutex_instances.result +++ b/mysql-test/suite/perfschema/r/ddl_mutex_instances.result @@ -1,8 +1,8 @@ -alter table performance_schema.MUTEX_INSTANCES add column foo integer; +alter table performance_schema.mutex_instances add column foo integer; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -truncate table performance_schema.MUTEX_INSTANCES; +truncate table performance_schema.mutex_instances; ERROR HY000: Invalid performance_schema usage. -ALTER TABLE performance_schema.MUTEX_INSTANCES ADD INDEX test_index(NAME); +ALTER TABLE performance_schema.mutex_instances ADD INDEX test_index(NAME); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -CREATE UNIQUE INDEX test_index ON performance_schema.MUTEX_INSTANCES(NAME); +CREATE UNIQUE INDEX test_index ON performance_schema.mutex_instances(NAME); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' diff --git a/mysql-test/suite/perfschema/r/ddl_performance_timers.result b/mysql-test/suite/perfschema/r/ddl_performance_timers.result index 5de8193b205..6868d419f1b 100644 --- a/mysql-test/suite/perfschema/r/ddl_performance_timers.result +++ b/mysql-test/suite/perfschema/r/ddl_performance_timers.result @@ -1,8 +1,8 @@ -alter table performance_schema.PERFORMANCE_TIMERS add column foo integer; +alter table performance_schema.performance_timers add column foo integer; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -truncate table performance_schema.PERFORMANCE_TIMERS; +truncate table performance_schema.performance_timers; ERROR HY000: Invalid performance_schema usage. -ALTER TABLE performance_schema.PERFORMANCE_TIMERS ADD INDEX test_index(TIMER_NAME); +ALTER TABLE performance_schema.performance_timers ADD INDEX test_index(TIMER_NAME); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -CREATE UNIQUE INDEX test_index ON performance_schema.PERFORMANCE_TIMERS(TIMER_NAME); +CREATE UNIQUE INDEX test_index ON performance_schema.performance_timers(TIMER_NAME); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' diff --git a/mysql-test/suite/perfschema/r/ddl_rwlock_instances.result b/mysql-test/suite/perfschema/r/ddl_rwlock_instances.result index 849d191b17f..e93aef47a5c 100644 --- a/mysql-test/suite/perfschema/r/ddl_rwlock_instances.result +++ b/mysql-test/suite/perfschema/r/ddl_rwlock_instances.result @@ -1,8 +1,8 @@ -alter table performance_schema.RWLOCK_INSTANCES add column foo integer; +alter table performance_schema.rwlock_instances add column foo integer; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -truncate table performance_schema.RWLOCK_INSTANCES; +truncate table performance_schema.rwlock_instances; ERROR HY000: Invalid performance_schema usage. -ALTER TABLE performance_schema.RWLOCK_INSTANCES ADD INDEX test_index(NAME); +ALTER TABLE performance_schema.rwlock_instances ADD INDEX test_index(NAME); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -CREATE UNIQUE INDEX test_index ON performance_schema.RWLOCK_INSTANCES(NAME); +CREATE UNIQUE INDEX test_index ON performance_schema.rwlock_instances(NAME); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' diff --git a/mysql-test/suite/perfschema/r/ddl_setup_consumers.result b/mysql-test/suite/perfschema/r/ddl_setup_consumers.result index f141725ee1f..1b121a0ec4c 100644 --- a/mysql-test/suite/perfschema/r/ddl_setup_consumers.result +++ b/mysql-test/suite/perfschema/r/ddl_setup_consumers.result @@ -1,8 +1,8 @@ -alter table performance_schema.SETUP_CONSUMERS add column foo integer; +alter table performance_schema.setup_consumers add column foo integer; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -truncate table performance_schema.SETUP_CONSUMERS; +truncate table performance_schema.setup_consumers; ERROR HY000: Invalid performance_schema usage. -ALTER TABLE performance_schema.SETUP_CONSUMERS ADD INDEX test_index(NAME); +ALTER TABLE performance_schema.setup_consumers ADD INDEX test_index(NAME); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -CREATE UNIQUE INDEX test_index ON performance_schema.SETUP_CONSUMERS(NAME); +CREATE UNIQUE INDEX test_index ON performance_schema.setup_consumers(NAME); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' diff --git a/mysql-test/suite/perfschema/r/ddl_setup_instruments.result b/mysql-test/suite/perfschema/r/ddl_setup_instruments.result index 42e54b587d8..f67b4f5791b 100644 --- a/mysql-test/suite/perfschema/r/ddl_setup_instruments.result +++ b/mysql-test/suite/perfschema/r/ddl_setup_instruments.result @@ -1,8 +1,8 @@ -alter table performance_schema.SETUP_INSTRUMENTS add column foo integer; +alter table performance_schema.setup_instruments add column foo integer; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -truncate table performance_schema.SETUP_INSTRUMENTS; +truncate table performance_schema.setup_instruments; ERROR HY000: Invalid performance_schema usage. -ALTER TABLE performance_schema.SETUP_INSTRUMENTS ADD INDEX test_index(NAME); +ALTER TABLE performance_schema.setup_instruments ADD INDEX test_index(NAME); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -CREATE UNIQUE INDEX test_index ON performance_schema.SETUP_INSTRUMENTS(NAME); +CREATE UNIQUE INDEX test_index ON performance_schema.setup_instruments(NAME); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' diff --git a/mysql-test/suite/perfschema/r/ddl_setup_timers.result b/mysql-test/suite/perfschema/r/ddl_setup_timers.result index fc74730bd50..69b3d36cc1b 100644 --- a/mysql-test/suite/perfschema/r/ddl_setup_timers.result +++ b/mysql-test/suite/perfschema/r/ddl_setup_timers.result @@ -1,8 +1,8 @@ -alter table performance_schema.SETUP_TIMERS add column foo integer; +alter table performance_schema.setup_timers add column foo integer; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -truncate table performance_schema.SETUP_TIMERS; +truncate table performance_schema.setup_timers; ERROR HY000: Invalid performance_schema usage. -ALTER TABLE performance_schema.SETUP_TIMERS ADD INDEX test_index(NAME); +ALTER TABLE performance_schema.setup_timers ADD INDEX test_index(NAME); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -CREATE UNIQUE INDEX test_index ON performance_schema.SETUP_TIMERS(NAME); +CREATE UNIQUE INDEX test_index ON performance_schema.setup_timers(NAME); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' diff --git a/mysql-test/suite/perfschema/r/ddl_threads.result b/mysql-test/suite/perfschema/r/ddl_threads.result index 5d4b54d8bbe..9d949e0920f 100644 --- a/mysql-test/suite/perfschema/r/ddl_threads.result +++ b/mysql-test/suite/perfschema/r/ddl_threads.result @@ -1,8 +1,8 @@ -alter table performance_schema.THREADS add column foo integer; +alter table performance_schema.threads add column foo integer; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -truncate table performance_schema.THREADS; +truncate table performance_schema.threads; ERROR HY000: Invalid performance_schema usage. -ALTER TABLE performance_schema.THREADS ADD INDEX test_index(ID); +ALTER TABLE performance_schema.threads ADD INDEX test_index(ID); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -CREATE UNIQUE INDEX test_index ON performance_schema.THREADS(ID); +CREATE UNIQUE INDEX test_index ON performance_schema.threads(ID); ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' diff --git a/mysql-test/suite/perfschema/r/dml_cond_instances.result b/mysql-test/suite/perfschema/r/dml_cond_instances.result index 8adc632b91b..922effc59ae 100644 --- a/mysql-test/suite/perfschema/r/dml_cond_instances.result +++ b/mysql-test/suite/perfschema/r/dml_cond_instances.result @@ -1,23 +1,23 @@ -select * from performance_schema.COND_INSTANCES limit 1; +select * from performance_schema.cond_instances limit 1; NAME OBJECT_INSTANCE_BEGIN # # -select * from performance_schema.COND_INSTANCES +select * from performance_schema.cond_instances where name='FOO'; NAME OBJECT_INSTANCE_BEGIN -insert into performance_schema.COND_INSTANCES +insert into performance_schema.cond_instances set name='FOO', object_instance_begin=12; -ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'COND_INSTANCES' -update performance_schema.COND_INSTANCES +ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'cond_instances' +update performance_schema.cond_instances set name='FOO'; -ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'COND_INSTANCES' -delete from performance_schema.COND_INSTANCES +ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'cond_instances' +delete from performance_schema.cond_instances where name like "wait/%"; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'COND_INSTANCES' -delete from performance_schema.COND_INSTANCES; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'COND_INSTANCES' -LOCK TABLES performance_schema.COND_INSTANCES READ; -ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'COND_INSTANCES' +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'cond_instances' +delete from performance_schema.cond_instances; +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'cond_instances' +LOCK TABLES performance_schema.cond_instances READ; +ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'cond_instances' UNLOCK TABLES; -LOCK TABLES performance_schema.COND_INSTANCES WRITE; -ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'COND_INSTANCES' +LOCK TABLES performance_schema.cond_instances WRITE; +ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'cond_instances' UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/r/dml_events_waits_current.result b/mysql-test/suite/perfschema/r/dml_events_waits_current.result index 5cd0dba7ad1..9b0bcf7f876 100644 --- a/mysql-test/suite/perfschema/r/dml_events_waits_current.result +++ b/mysql-test/suite/perfschema/r/dml_events_waits_current.result @@ -1,28 +1,28 @@ -select * from performance_schema.EVENTS_WAITS_CURRENT +select * from performance_schema.events_waits_current where event_name like 'Wait/Synch/%' limit 1; THREAD_ID EVENT_ID EVENT_NAME SOURCE TIMER_START TIMER_END TIMER_WAIT SPINS OBJECT_SCHEMA OBJECT_NAME OBJECT_TYPE OBJECT_INSTANCE_BEGIN NESTING_EVENT_ID OPERATION NUMBER_OF_BYTES FLAGS # # # # # # # # NULL NULL NULL # NULL # NULL 0 -select * from performance_schema.EVENTS_WAITS_CURRENT +select * from performance_schema.events_waits_current where event_name='FOO'; THREAD_ID EVENT_ID EVENT_NAME SOURCE TIMER_START TIMER_END TIMER_WAIT SPINS OBJECT_SCHEMA OBJECT_NAME OBJECT_TYPE OBJECT_INSTANCE_BEGIN NESTING_EVENT_ID OPERATION NUMBER_OF_BYTES FLAGS -insert into performance_schema.EVENTS_WAITS_CURRENT +insert into performance_schema.events_waits_current set thread_id='1', event_id=1, event_name='FOO', timer_start=1, timer_end=2, timer_wait=3; -ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_CURRENT' -update performance_schema.EVENTS_WAITS_CURRENT +ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'events_waits_current' +update performance_schema.events_waits_current set timer_start=12; -ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_CURRENT' -update performance_schema.EVENTS_WAITS_CURRENT +ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'events_waits_current' +update performance_schema.events_waits_current set timer_start=12 where thread_id=0; -ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_CURRENT' -delete from performance_schema.EVENTS_WAITS_CURRENT +ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'events_waits_current' +delete from performance_schema.events_waits_current where thread_id=1; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_CURRENT' -delete from performance_schema.EVENTS_WAITS_CURRENT; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_CURRENT' -LOCK TABLES performance_schema.EVENTS_WAITS_CURRENT READ; -ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_CURRENT' +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'events_waits_current' +delete from performance_schema.events_waits_current; +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'events_waits_current' +LOCK TABLES performance_schema.events_waits_current READ; +ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'events_waits_current' UNLOCK TABLES; -LOCK TABLES performance_schema.EVENTS_WAITS_CURRENT WRITE; -ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_CURRENT' +LOCK TABLES performance_schema.events_waits_current WRITE; +ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'events_waits_current' UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/r/dml_events_waits_history.result b/mysql-test/suite/perfschema/r/dml_events_waits_history.result index 953922868fb..5fc95584c7f 100644 --- a/mysql-test/suite/perfschema/r/dml_events_waits_history.result +++ b/mysql-test/suite/perfschema/r/dml_events_waits_history.result @@ -1,36 +1,36 @@ -select * from performance_schema.EVENTS_WAITS_HISTORY +select * from performance_schema.events_waits_history where event_name like 'Wait/Synch/%' limit 1; THREAD_ID EVENT_ID EVENT_NAME SOURCE TIMER_START TIMER_END TIMER_WAIT SPINS OBJECT_SCHEMA OBJECT_NAME OBJECT_TYPE OBJECT_INSTANCE_BEGIN NESTING_EVENT_ID OPERATION NUMBER_OF_BYTES FLAGS # # # # # # # # NULL NULL NULL # NULL # NULL 0 -select * from performance_schema.EVENTS_WAITS_HISTORY +select * from performance_schema.events_waits_history where event_name='FOO'; THREAD_ID EVENT_ID EVENT_NAME SOURCE TIMER_START TIMER_END TIMER_WAIT SPINS OBJECT_SCHEMA OBJECT_NAME OBJECT_TYPE OBJECT_INSTANCE_BEGIN NESTING_EVENT_ID OPERATION NUMBER_OF_BYTES FLAGS -select * from performance_schema.EVENTS_WAITS_HISTORY +select * from performance_schema.events_waits_history where event_name like 'Wait/Synch/%' order by timer_wait limit 1; THREAD_ID EVENT_ID EVENT_NAME SOURCE TIMER_START TIMER_END TIMER_WAIT SPINS OBJECT_SCHEMA OBJECT_NAME OBJECT_TYPE OBJECT_INSTANCE_BEGIN NESTING_EVENT_ID OPERATION NUMBER_OF_BYTES FLAGS # # # # # # # # NULL NULL NULL # NULL # NULL 0 -select * from performance_schema.EVENTS_WAITS_HISTORY +select * from performance_schema.events_waits_history where event_name like 'Wait/Synch/%' order by timer_wait desc limit 1; THREAD_ID EVENT_ID EVENT_NAME SOURCE TIMER_START TIMER_END TIMER_WAIT SPINS OBJECT_SCHEMA OBJECT_NAME OBJECT_TYPE OBJECT_INSTANCE_BEGIN NESTING_EVENT_ID OPERATION NUMBER_OF_BYTES FLAGS # # # # # # # # NULL NULL NULL # NULL # NULL 0 -insert into performance_schema.EVENTS_WAITS_HISTORY +insert into performance_schema.events_waits_history set thread_id='1', event_id=1, event_name='FOO', timer_start=1, timer_end=2, timer_wait=3; -ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_HISTORY' -update performance_schema.EVENTS_WAITS_HISTORY +ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'events_waits_history' +update performance_schema.events_waits_history set timer_start=12; -ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_HISTORY' -update performance_schema.EVENTS_WAITS_HISTORY +ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'events_waits_history' +update performance_schema.events_waits_history set timer_start=12 where thread_id=0; -ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_HISTORY' -delete from performance_schema.EVENTS_WAITS_HISTORY +ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'events_waits_history' +delete from performance_schema.events_waits_history where thread_id=1; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_HISTORY' -delete from performance_schema.EVENTS_WAITS_HISTORY; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_HISTORY' -LOCK TABLES performance_schema.EVENTS_WAITS_HISTORY READ; -ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_HISTORY' +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'events_waits_history' +delete from performance_schema.events_waits_history; +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'events_waits_history' +LOCK TABLES performance_schema.events_waits_history READ; +ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'events_waits_history' UNLOCK TABLES; -LOCK TABLES performance_schema.EVENTS_WAITS_HISTORY WRITE; -ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_HISTORY' +LOCK TABLES performance_schema.events_waits_history WRITE; +ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'events_waits_history' UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/r/dml_events_waits_history_long.result b/mysql-test/suite/perfschema/r/dml_events_waits_history_long.result index 494469a0db8..2ce949b2228 100644 --- a/mysql-test/suite/perfschema/r/dml_events_waits_history_long.result +++ b/mysql-test/suite/perfschema/r/dml_events_waits_history_long.result @@ -1,36 +1,36 @@ -select * from performance_schema.EVENTS_WAITS_HISTORY_LONG +select * from performance_schema.events_waits_history_long where event_name like 'Wait/Synch/%' limit 1; THREAD_ID EVENT_ID EVENT_NAME SOURCE TIMER_START TIMER_END TIMER_WAIT SPINS OBJECT_SCHEMA OBJECT_NAME OBJECT_TYPE OBJECT_INSTANCE_BEGIN NESTING_EVENT_ID OPERATION NUMBER_OF_BYTES FLAGS # # # # # # # # NULL NULL NULL # NULL # NULL 0 -select * from performance_schema.EVENTS_WAITS_HISTORY_LONG +select * from performance_schema.events_waits_history_long where event_name='FOO'; THREAD_ID EVENT_ID EVENT_NAME SOURCE TIMER_START TIMER_END TIMER_WAIT SPINS OBJECT_SCHEMA OBJECT_NAME OBJECT_TYPE OBJECT_INSTANCE_BEGIN NESTING_EVENT_ID OPERATION NUMBER_OF_BYTES FLAGS -select * from performance_schema.EVENTS_WAITS_HISTORY_LONG +select * from performance_schema.events_waits_history_long where event_name like 'Wait/Synch/%' order by timer_wait limit 1; THREAD_ID EVENT_ID EVENT_NAME SOURCE TIMER_START TIMER_END TIMER_WAIT SPINS OBJECT_SCHEMA OBJECT_NAME OBJECT_TYPE OBJECT_INSTANCE_BEGIN NESTING_EVENT_ID OPERATION NUMBER_OF_BYTES FLAGS # # # # # # # # NULL NULL NULL # NULL # NULL 0 -select * from performance_schema.EVENTS_WAITS_HISTORY_LONG +select * from performance_schema.events_waits_history_long where event_name like 'Wait/Synch/%' order by timer_wait desc limit 1; THREAD_ID EVENT_ID EVENT_NAME SOURCE TIMER_START TIMER_END TIMER_WAIT SPINS OBJECT_SCHEMA OBJECT_NAME OBJECT_TYPE OBJECT_INSTANCE_BEGIN NESTING_EVENT_ID OPERATION NUMBER_OF_BYTES FLAGS # # # # # # # # NULL NULL NULL # NULL # NULL 0 -insert into performance_schema.EVENTS_WAITS_HISTORY_LONG +insert into performance_schema.events_waits_history_long set thread_id='1', event_id=1, event_name='FOO', timer_start=1, timer_end=2, timer_wait=3; -ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_HISTORY_LONG' -update performance_schema.EVENTS_WAITS_HISTORY_LONG +ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'events_waits_history_long' +update performance_schema.events_waits_history_long set timer_start=12; -ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_HISTORY_LONG' -update performance_schema.EVENTS_WAITS_HISTORY_LONG +ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'events_waits_history_long' +update performance_schema.events_waits_history_long set timer_start=12 where thread_id=0; -ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_HISTORY_LONG' -delete from performance_schema.EVENTS_WAITS_HISTORY_LONG +ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'events_waits_history_long' +delete from performance_schema.events_waits_history_long where thread_id=1; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_HISTORY_LONG' -delete from performance_schema.EVENTS_WAITS_HISTORY_LONG; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_HISTORY_LONG' -LOCK TABLES performance_schema.EVENTS_WAITS_HISTORY_LONG READ; -ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_HISTORY_LONG' +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'events_waits_history_long' +delete from performance_schema.events_waits_history_long; +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'events_waits_history_long' +LOCK TABLES performance_schema.events_waits_history_long READ; +ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'events_waits_history_long' UNLOCK TABLES; -LOCK TABLES performance_schema.EVENTS_WAITS_HISTORY_LONG WRITE; -ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_HISTORY_LONG' +LOCK TABLES performance_schema.events_waits_history_long WRITE; +ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'events_waits_history_long' UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/r/dml_ews_by_instance.result b/mysql-test/suite/perfschema/r/dml_ews_by_instance.result index dc262982340..0a745a2c38a 100644 --- a/mysql-test/suite/perfschema/r/dml_ews_by_instance.result +++ b/mysql-test/suite/perfschema/r/dml_ews_by_instance.result @@ -1,45 +1,45 @@ -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE +select * from performance_schema.events_waits_summary_by_instance where event_name like 'Wait/Synch/%' limit 1; EVENT_NAME OBJECT_INSTANCE_BEGIN COUNT_STAR SUM_TIMER_WAIT MIN_TIMER_WAIT AVG_TIMER_WAIT MAX_TIMER_WAIT # # # # # # # -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE +select * from performance_schema.events_waits_summary_by_instance where event_name='FOO'; EVENT_NAME OBJECT_INSTANCE_BEGIN COUNT_STAR SUM_TIMER_WAIT MIN_TIMER_WAIT AVG_TIMER_WAIT MAX_TIMER_WAIT -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE +select * from performance_schema.events_waits_summary_by_instance order by count_star limit 1; EVENT_NAME OBJECT_INSTANCE_BEGIN COUNT_STAR SUM_TIMER_WAIT MIN_TIMER_WAIT AVG_TIMER_WAIT MAX_TIMER_WAIT # # # # # # # -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE +select * from performance_schema.events_waits_summary_by_instance order by count_star desc limit 1; EVENT_NAME OBJECT_INSTANCE_BEGIN COUNT_STAR SUM_TIMER_WAIT MIN_TIMER_WAIT AVG_TIMER_WAIT MAX_TIMER_WAIT # # # # # # # -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE +select * from performance_schema.events_waits_summary_by_instance where min_timer_wait > 0 order by count_star limit 1; EVENT_NAME OBJECT_INSTANCE_BEGIN COUNT_STAR SUM_TIMER_WAIT MIN_TIMER_WAIT AVG_TIMER_WAIT MAX_TIMER_WAIT # # # # # # # -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE +select * from performance_schema.events_waits_summary_by_instance where min_timer_wait > 0 order by count_star desc limit 1; EVENT_NAME OBJECT_INSTANCE_BEGIN COUNT_STAR SUM_TIMER_WAIT MIN_TIMER_WAIT AVG_TIMER_WAIT MAX_TIMER_WAIT # # # # # # # -insert into performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE +insert into performance_schema.events_waits_summary_by_instance set event_name='FOO', object_instance_begin=0, count_star=1, sum_timer_wait=2, min_timer_wait=3, avg_timer_wait=4, max_timer_wait=5; -ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_SUMMARY_BY_INSTANCE' -update performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE +ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'events_waits_summary_by_instance' +update performance_schema.events_waits_summary_by_instance set count_star=12; -ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_SUMMARY_BY_INSTANCE' -update performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE +ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'events_waits_summary_by_instance' +update performance_schema.events_waits_summary_by_instance set count_star=12 where event_name like "FOO"; -ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_SUMMARY_BY_INSTANCE' -delete from performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE +ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'events_waits_summary_by_instance' +delete from performance_schema.events_waits_summary_by_instance where count_star=1; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_SUMMARY_BY_INSTANCE' -delete from performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_SUMMARY_BY_INSTANCE' -LOCK TABLES performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE READ; -ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_SUMMARY_BY_INSTANCE' +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'events_waits_summary_by_instance' +delete from performance_schema.events_waits_summary_by_instance; +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'events_waits_summary_by_instance' +LOCK TABLES performance_schema.events_waits_summary_by_instance READ; +ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'events_waits_summary_by_instance' UNLOCK TABLES; -LOCK TABLES performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE WRITE; -ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_SUMMARY_BY_INSTANCE' +LOCK TABLES performance_schema.events_waits_summary_by_instance WRITE; +ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'events_waits_summary_by_instance' UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/r/dml_ews_by_thread_by_event_name.result b/mysql-test/suite/perfschema/r/dml_ews_by_thread_by_event_name.result index 2a085659431..c64bcdd40f6 100644 --- a/mysql-test/suite/perfschema/r/dml_ews_by_thread_by_event_name.result +++ b/mysql-test/suite/perfschema/r/dml_ews_by_thread_by_event_name.result @@ -1,29 +1,29 @@ -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME +select * from performance_schema.events_waits_summary_by_thread_by_event_name where event_name like 'Wait/Synch/%' limit 1; THREAD_ID EVENT_NAME COUNT_STAR SUM_TIMER_WAIT MIN_TIMER_WAIT AVG_TIMER_WAIT MAX_TIMER_WAIT # # # # # # # -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME +select * from performance_schema.events_waits_summary_by_thread_by_event_name where event_name='FOO'; THREAD_ID EVENT_NAME COUNT_STAR SUM_TIMER_WAIT MIN_TIMER_WAIT AVG_TIMER_WAIT MAX_TIMER_WAIT -insert into performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME +insert into performance_schema.events_waits_summary_by_thread_by_event_name set event_name='FOO', thread_id=1, count_star=1, sum_timer_wait=2, min_timer_wait=3, avg_timer_wait=4, max_timer_wait=5; -ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME' -update performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME +ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'events_waits_summary_by_thread_by_event_name' +update performance_schema.events_waits_summary_by_thread_by_event_name set count_star=12; -ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME' -update performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME +ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'events_waits_summary_by_thread_by_event_name' +update performance_schema.events_waits_summary_by_thread_by_event_name set count_star=12 where event_name like "FOO"; -ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME' -delete from performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME +ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'events_waits_summary_by_thread_by_event_name' +delete from performance_schema.events_waits_summary_by_thread_by_event_name where count_star=1; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME' -delete from performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME' -LOCK TABLES performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME READ; -ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME' +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'events_waits_summary_by_thread_by_event_name' +delete from performance_schema.events_waits_summary_by_thread_by_event_name; +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'events_waits_summary_by_thread_by_event_name' +LOCK TABLES performance_schema.events_waits_summary_by_thread_by_event_name READ; +ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'events_waits_summary_by_thread_by_event_name' UNLOCK TABLES; -LOCK TABLES performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME WRITE; -ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME' +LOCK TABLES performance_schema.events_waits_summary_by_thread_by_event_name WRITE; +ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'events_waits_summary_by_thread_by_event_name' UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/r/dml_ews_global_by_event_name.result b/mysql-test/suite/perfschema/r/dml_ews_global_by_event_name.result index 64ede2fddac..c59451922c5 100644 --- a/mysql-test/suite/perfschema/r/dml_ews_global_by_event_name.result +++ b/mysql-test/suite/perfschema/r/dml_ews_global_by_event_name.result @@ -1,28 +1,28 @@ -select * from performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME +select * from performance_schema.events_waits_summary_global_by_event_name where event_name like 'Wait/Synch/%' limit 1; EVENT_NAME COUNT_STAR SUM_TIMER_WAIT MIN_TIMER_WAIT AVG_TIMER_WAIT MAX_TIMER_WAIT # # # # # # -select * from performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME +select * from performance_schema.events_waits_summary_global_by_event_name where event_name='FOO'; EVENT_NAME COUNT_STAR SUM_TIMER_WAIT MIN_TIMER_WAIT AVG_TIMER_WAIT MAX_TIMER_WAIT -insert into performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME +insert into performance_schema.events_waits_summary_global_by_event_name set event_name='FOO', count_star=1, sum_timer_wait=2, min_timer_wait=3, avg_timer_wait=4, max_timer_wait=5; -ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME' -update performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME +ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'events_waits_summary_global_by_event_name' +update performance_schema.events_waits_summary_global_by_event_name set count_star=12; -ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME' -update performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME +ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'events_waits_summary_global_by_event_name' +update performance_schema.events_waits_summary_global_by_event_name set count_star=12 where event_name like "FOO"; -ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME' -delete from performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME +ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'events_waits_summary_global_by_event_name' +delete from performance_schema.events_waits_summary_global_by_event_name where count_star=1; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME' -delete from performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME' -LOCK TABLES performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME READ; -ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME' +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'events_waits_summary_global_by_event_name' +delete from performance_schema.events_waits_summary_global_by_event_name; +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'events_waits_summary_global_by_event_name' +LOCK TABLES performance_schema.events_waits_summary_global_by_event_name READ; +ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'events_waits_summary_global_by_event_name' UNLOCK TABLES; -LOCK TABLES performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME WRITE; -ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME' +LOCK TABLES performance_schema.events_waits_summary_global_by_event_name WRITE; +ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'events_waits_summary_global_by_event_name' UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/r/dml_file_instances.result b/mysql-test/suite/perfschema/r/dml_file_instances.result index e15d68cbad3..5a51a4ca018 100644 --- a/mysql-test/suite/perfschema/r/dml_file_instances.result +++ b/mysql-test/suite/perfschema/r/dml_file_instances.result @@ -1,23 +1,23 @@ -select * from performance_schema.FILE_INSTANCES limit 1; +select * from performance_schema.file_instances limit 1; FILE_NAME EVENT_NAME OPEN_COUNT # # # -select * from performance_schema.FILE_INSTANCES +select * from performance_schema.file_instances where file_name='FOO'; FILE_NAME EVENT_NAME OPEN_COUNT -insert into performance_schema.FILE_INSTANCES +insert into performance_schema.file_instances set file_name='FOO', event_name='BAR', open_count=12; -ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'FILE_INSTANCES' -update performance_schema.FILE_INSTANCES +ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'file_instances' +update performance_schema.file_instances set file_name='FOO'; -ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'FILE_INSTANCES' -delete from performance_schema.FILE_INSTANCES +ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'file_instances' +delete from performance_schema.file_instances where event_name like "wait/%"; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'FILE_INSTANCES' -delete from performance_schema.FILE_INSTANCES; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'FILE_INSTANCES' -LOCK TABLES performance_schema.FILE_INSTANCES READ; -ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'FILE_INSTANCES' +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'file_instances' +delete from performance_schema.file_instances; +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'file_instances' +LOCK TABLES performance_schema.file_instances READ; +ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'file_instances' UNLOCK TABLES; -LOCK TABLES performance_schema.FILE_INSTANCES WRITE; -ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'FILE_INSTANCES' +LOCK TABLES performance_schema.file_instances WRITE; +ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'file_instances' UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/r/dml_file_summary_by_event_name.result b/mysql-test/suite/perfschema/r/dml_file_summary_by_event_name.result index 1ecc82f40a5..97a196dbf19 100644 --- a/mysql-test/suite/perfschema/r/dml_file_summary_by_event_name.result +++ b/mysql-test/suite/perfschema/r/dml_file_summary_by_event_name.result @@ -1,28 +1,28 @@ -select * from performance_schema.FILE_SUMMARY_BY_EVENT_NAME +select * from performance_schema.file_summary_by_event_name where event_name like 'Wait/io/%' limit 1; EVENT_NAME COUNT_READ COUNT_WRITE SUM_NUMBER_OF_BYTES_READ SUM_NUMBER_OF_BYTES_WRITE # # # # # -select * from performance_schema.FILE_SUMMARY_BY_EVENT_NAME +select * from performance_schema.file_summary_by_event_name where event_name='FOO'; EVENT_NAME COUNT_READ COUNT_WRITE SUM_NUMBER_OF_BYTES_READ SUM_NUMBER_OF_BYTES_WRITE -insert into performance_schema.FILE_SUMMARY_BY_EVENT_NAME +insert into performance_schema.file_summary_by_event_name set event_name='FOO', count_read=1, count_write=2, sum_number_of_bytes_read=4, sum_number_of_bytes_write=5; -ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'FILE_SUMMARY_BY_EVENT_NAME' -update performance_schema.FILE_SUMMARY_BY_EVENT_NAME +ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'file_summary_by_event_name' +update performance_schema.file_summary_by_event_name set count_read=12; -ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'FILE_SUMMARY_BY_EVENT_NAME' -update performance_schema.FILE_SUMMARY_BY_EVENT_NAME +ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'file_summary_by_event_name' +update performance_schema.file_summary_by_event_name set count_write=12 where event_name like "FOO"; -ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'FILE_SUMMARY_BY_EVENT_NAME' -delete from performance_schema.FILE_SUMMARY_BY_EVENT_NAME +ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'file_summary_by_event_name' +delete from performance_schema.file_summary_by_event_name where count_read=1; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'FILE_SUMMARY_BY_EVENT_NAME' -delete from performance_schema.FILE_SUMMARY_BY_EVENT_NAME; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'FILE_SUMMARY_BY_EVENT_NAME' -LOCK TABLES performance_schema.FILE_SUMMARY_BY_EVENT_NAME READ; -ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'FILE_SUMMARY_BY_EVENT_NAME' +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'file_summary_by_event_name' +delete from performance_schema.file_summary_by_event_name; +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'file_summary_by_event_name' +LOCK TABLES performance_schema.file_summary_by_event_name READ; +ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'file_summary_by_event_name' UNLOCK TABLES; -LOCK TABLES performance_schema.FILE_SUMMARY_BY_EVENT_NAME WRITE; -ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'FILE_SUMMARY_BY_EVENT_NAME' +LOCK TABLES performance_schema.file_summary_by_event_name WRITE; +ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'file_summary_by_event_name' UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/r/dml_file_summary_by_instance.result b/mysql-test/suite/perfschema/r/dml_file_summary_by_instance.result index 05b204cc1a9..d85e23cb6f4 100644 --- a/mysql-test/suite/perfschema/r/dml_file_summary_by_instance.result +++ b/mysql-test/suite/perfschema/r/dml_file_summary_by_instance.result @@ -1,28 +1,28 @@ -select * from performance_schema.FILE_SUMMARY_BY_INSTANCE +select * from performance_schema.file_summary_by_instance where event_name like 'Wait/io/%' limit 1; FILE_NAME EVENT_NAME COUNT_READ COUNT_WRITE SUM_NUMBER_OF_BYTES_READ SUM_NUMBER_OF_BYTES_WRITE # # # # # # -select * from performance_schema.FILE_SUMMARY_BY_INSTANCE +select * from performance_schema.file_summary_by_instance where event_name='FOO'; FILE_NAME EVENT_NAME COUNT_READ COUNT_WRITE SUM_NUMBER_OF_BYTES_READ SUM_NUMBER_OF_BYTES_WRITE -insert into performance_schema.FILE_SUMMARY_BY_INSTANCE +insert into performance_schema.file_summary_by_instance set event_name='FOO', count_read=1, count_write=2, sum_number_of_bytes_read=4, sum_number_of_bytes_write=5; -ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'FILE_SUMMARY_BY_INSTANCE' -update performance_schema.FILE_SUMMARY_BY_INSTANCE +ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'file_summary_by_instance' +update performance_schema.file_summary_by_instance set count_read=12; -ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'FILE_SUMMARY_BY_INSTANCE' -update performance_schema.FILE_SUMMARY_BY_INSTANCE +ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'file_summary_by_instance' +update performance_schema.file_summary_by_instance set count_write=12 where event_name like "FOO"; -ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'FILE_SUMMARY_BY_INSTANCE' -delete from performance_schema.FILE_SUMMARY_BY_INSTANCE +ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'file_summary_by_instance' +delete from performance_schema.file_summary_by_instance where count_read=1; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'FILE_SUMMARY_BY_INSTANCE' -delete from performance_schema.FILE_SUMMARY_BY_INSTANCE; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'FILE_SUMMARY_BY_INSTANCE' -LOCK TABLES performance_schema.FILE_SUMMARY_BY_INSTANCE READ; -ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'FILE_SUMMARY_BY_INSTANCE' +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'file_summary_by_instance' +delete from performance_schema.file_summary_by_instance; +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'file_summary_by_instance' +LOCK TABLES performance_schema.file_summary_by_instance READ; +ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'file_summary_by_instance' UNLOCK TABLES; -LOCK TABLES performance_schema.FILE_SUMMARY_BY_INSTANCE WRITE; -ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'FILE_SUMMARY_BY_INSTANCE' +LOCK TABLES performance_schema.file_summary_by_instance WRITE; +ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'file_summary_by_instance' UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/r/dml_mutex_instances.result b/mysql-test/suite/perfschema/r/dml_mutex_instances.result index 862123b3450..1ea7311b149 100644 --- a/mysql-test/suite/perfschema/r/dml_mutex_instances.result +++ b/mysql-test/suite/perfschema/r/dml_mutex_instances.result @@ -1,23 +1,23 @@ -select * from performance_schema.MUTEX_INSTANCES limit 1; +select * from performance_schema.mutex_instances limit 1; NAME OBJECT_INSTANCE_BEGIN LOCKED_BY_THREAD_ID # # # -select * from performance_schema.MUTEX_INSTANCES +select * from performance_schema.mutex_instances where name='FOO'; NAME OBJECT_INSTANCE_BEGIN LOCKED_BY_THREAD_ID -insert into performance_schema.MUTEX_INSTANCES +insert into performance_schema.mutex_instances set name='FOO', object_instance_begin=12; -ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'MUTEX_INSTANCES' -update performance_schema.MUTEX_INSTANCES +ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'mutex_instances' +update performance_schema.mutex_instances set name='FOO'; -ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'MUTEX_INSTANCES' -delete from performance_schema.MUTEX_INSTANCES +ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'mutex_instances' +delete from performance_schema.mutex_instances where name like "wait/%"; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'MUTEX_INSTANCES' -delete from performance_schema.MUTEX_INSTANCES; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'MUTEX_INSTANCES' -LOCK TABLES performance_schema.MUTEX_INSTANCES READ; -ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'MUTEX_INSTANCES' +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'mutex_instances' +delete from performance_schema.mutex_instances; +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'mutex_instances' +LOCK TABLES performance_schema.mutex_instances READ; +ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'mutex_instances' UNLOCK TABLES; -LOCK TABLES performance_schema.MUTEX_INSTANCES WRITE; -ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'MUTEX_INSTANCES' +LOCK TABLES performance_schema.mutex_instances WRITE; +ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'mutex_instances' UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/r/dml_performance_timers.result b/mysql-test/suite/perfschema/r/dml_performance_timers.result index 99c1c74b797..f345cce921e 100644 --- a/mysql-test/suite/perfschema/r/dml_performance_timers.result +++ b/mysql-test/suite/perfschema/r/dml_performance_timers.result @@ -1,29 +1,29 @@ -select * from performance_schema.PERFORMANCE_TIMERS; +select * from performance_schema.performance_timers; TIMER_NAME TIMER_FREQUENCY TIMER_RESOLUTION TIMER_OVERHEAD CYCLE NANOSECOND MICROSECOND MILLISECOND TICK -select * from performance_schema.PERFORMANCE_TIMERS +select * from performance_schema.performance_timers where timer_name='CYCLE'; TIMER_NAME TIMER_FREQUENCY TIMER_RESOLUTION TIMER_OVERHEAD CYCLE -insert into performance_schema.PERFORMANCE_TIMERS +insert into performance_schema.performance_timers set timer_name='FOO', timer_frequency=1, timer_resolution=2, timer_overhead=3; -ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'PERFORMANCE_TIMERS' -update performance_schema.PERFORMANCE_TIMERS +ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'performance_timers' +update performance_schema.performance_timers set timer_frequency=12 where timer_name='CYCLE'; -ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'PERFORMANCE_TIMERS' -delete from performance_schema.PERFORMANCE_TIMERS; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'PERFORMANCE_TIMERS' -delete from performance_schema.PERFORMANCE_TIMERS +ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'performance_timers' +delete from performance_schema.performance_timers; +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'performance_timers' +delete from performance_schema.performance_timers where timer_name='CYCLE'; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'PERFORMANCE_TIMERS' -LOCK TABLES performance_schema.PERFORMANCE_TIMERS READ; -ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'PERFORMANCE_TIMERS' +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'performance_timers' +LOCK TABLES performance_schema.performance_timers READ; +ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'performance_timers' UNLOCK TABLES; -LOCK TABLES performance_schema.PERFORMANCE_TIMERS WRITE; -ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'PERFORMANCE_TIMERS' +LOCK TABLES performance_schema.performance_timers WRITE; +ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'performance_timers' UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/r/dml_rwlock_instances.result b/mysql-test/suite/perfschema/r/dml_rwlock_instances.result index 686007e58e9..964fa0fa46f 100644 --- a/mysql-test/suite/perfschema/r/dml_rwlock_instances.result +++ b/mysql-test/suite/perfschema/r/dml_rwlock_instances.result @@ -1,23 +1,23 @@ -select * from performance_schema.RWLOCK_INSTANCES limit 1; +select * from performance_schema.rwlock_instances limit 1; NAME OBJECT_INSTANCE_BEGIN WRITE_LOCKED_BY_THREAD_ID READ_LOCKED_BY_COUNT # # # # -select * from performance_schema.RWLOCK_INSTANCES +select * from performance_schema.rwlock_instances where name='FOO'; NAME OBJECT_INSTANCE_BEGIN WRITE_LOCKED_BY_THREAD_ID READ_LOCKED_BY_COUNT -insert into performance_schema.RWLOCK_INSTANCES +insert into performance_schema.rwlock_instances set name='FOO', object_instance_begin=12; -ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'RWLOCK_INSTANCES' -update performance_schema.RWLOCK_INSTANCES +ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'rwlock_instances' +update performance_schema.rwlock_instances set name='FOO'; -ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'RWLOCK_INSTANCES' -delete from performance_schema.RWLOCK_INSTANCES +ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'rwlock_instances' +delete from performance_schema.rwlock_instances where name like "wait/%"; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'RWLOCK_INSTANCES' -delete from performance_schema.RWLOCK_INSTANCES; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'RWLOCK_INSTANCES' -LOCK TABLES performance_schema.RWLOCK_INSTANCES READ; -ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'RWLOCK_INSTANCES' +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'rwlock_instances' +delete from performance_schema.rwlock_instances; +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'rwlock_instances' +LOCK TABLES performance_schema.rwlock_instances READ; +ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'rwlock_instances' UNLOCK TABLES; -LOCK TABLES performance_schema.RWLOCK_INSTANCES WRITE; -ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'RWLOCK_INSTANCES' +LOCK TABLES performance_schema.rwlock_instances WRITE; +ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'rwlock_instances' UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/r/dml_setup_consumers.result b/mysql-test/suite/perfschema/r/dml_setup_consumers.result index 44ed751dcd2..db0a6820de9 100644 --- a/mysql-test/suite/perfschema/r/dml_setup_consumers.result +++ b/mysql-test/suite/perfschema/r/dml_setup_consumers.result @@ -1,4 +1,4 @@ -select * from performance_schema.SETUP_CONSUMERS; +select * from performance_schema.setup_consumers; NAME ENABLED events_waits_current YES events_waits_history YES @@ -8,11 +8,11 @@ events_waits_summary_by_event_name YES events_waits_summary_by_instance YES file_summary_by_event_name YES file_summary_by_instance YES -select * from performance_schema.SETUP_CONSUMERS +select * from performance_schema.setup_consumers where name='events_waits_current'; NAME ENABLED events_waits_current YES -select * from performance_schema.SETUP_CONSUMERS +select * from performance_schema.setup_consumers where enabled='YES'; NAME ENABLED events_waits_current YES @@ -23,23 +23,23 @@ events_waits_summary_by_event_name YES events_waits_summary_by_instance YES file_summary_by_event_name YES file_summary_by_instance YES -select * from performance_schema.SETUP_CONSUMERS +select * from performance_schema.setup_consumers where enabled='NO'; NAME ENABLED -insert into performance_schema.SETUP_CONSUMERS +insert into performance_schema.setup_consumers set name='FOO', enabled='YES'; -ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'SETUP_CONSUMERS' -update performance_schema.SETUP_CONSUMERS +ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'setup_consumers' +update performance_schema.setup_consumers set name='FOO'; ERROR HY000: Invalid performance_schema usage. -update performance_schema.SETUP_CONSUMERS +update performance_schema.setup_consumers set enabled='YES'; -delete from performance_schema.SETUP_CONSUMERS; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'SETUP_CONSUMERS' -delete from performance_schema.SETUP_CONSUMERS +delete from performance_schema.setup_consumers; +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'setup_consumers' +delete from performance_schema.setup_consumers where name='events_waits_current'; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'SETUP_CONSUMERS' -LOCK TABLES performance_schema.SETUP_CONSUMERS READ; +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'setup_consumers' +LOCK TABLES performance_schema.setup_consumers READ; UNLOCK TABLES; -LOCK TABLES performance_schema.SETUP_CONSUMERS WRITE; +LOCK TABLES performance_schema.setup_consumers WRITE; UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/r/dml_setup_instruments.result b/mysql-test/suite/perfschema/r/dml_setup_instruments.result index 2338252976c..7dbb7274c1d 100644 --- a/mysql-test/suite/perfschema/r/dml_setup_instruments.result +++ b/mysql-test/suite/perfschema/r/dml_setup_instruments.result @@ -1,5 +1,5 @@ -select * from performance_schema.SETUP_INSTRUMENTS; -select * from performance_schema.SETUP_INSTRUMENTS +select * from performance_schema.setup_instruments; +select * from performance_schema.setup_instruments where name like 'Wait/Synch/Mutex/sql/%' and name not in ('wait/synch/mutex/sql/DEBUG_SYNC::mutex') order by name limit 10; @@ -14,7 +14,7 @@ wait/synch/mutex/sql/LOCK_audit_mask YES YES wait/synch/mutex/sql/LOCK_connection_count YES YES wait/synch/mutex/sql/LOCK_crypt YES YES wait/synch/mutex/sql/LOCK_delayed_create YES YES -select * from performance_schema.SETUP_INSTRUMENTS +select * from performance_schema.setup_instruments where name like 'Wait/Synch/Rwlock/sql/%' and name not in ('wait/synch/rwlock/sql/CRYPTO_dynlock_value::lock') order by name limit 10; @@ -29,7 +29,7 @@ wait/synch/rwlock/sql/MDL_context::LOCK_waiting_for YES YES wait/synch/rwlock/sql/MDL_lock::rwlock YES YES wait/synch/rwlock/sql/Query_cache_query::lock YES YES wait/synch/rwlock/sql/THR_LOCK_servers YES YES -select * from performance_schema.SETUP_INSTRUMENTS +select * from performance_schema.setup_instruments where name like 'Wait/Synch/Cond/sql/%' and name not in ( 'wait/synch/cond/sql/COND_handler_count', @@ -46,29 +46,29 @@ wait/synch/cond/sql/COND_thread_cache YES YES wait/synch/cond/sql/COND_thread_count YES YES wait/synch/cond/sql/Delayed_insert::cond YES YES wait/synch/cond/sql/Delayed_insert::cond_client YES YES -select * from performance_schema.SETUP_INSTRUMENTS +select * from performance_schema.setup_instruments where name='Wait'; -select * from performance_schema.SETUP_INSTRUMENTS +select * from performance_schema.setup_instruments where enabled='YES'; -insert into performance_schema.SETUP_INSTRUMENTS +insert into performance_schema.setup_instruments set name='FOO', enabled='YES', timed='YES'; -ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'SETUP_INSTRUMENTS' -update performance_schema.SETUP_INSTRUMENTS +ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'setup_instruments' +update performance_schema.setup_instruments set name='FOO'; ERROR HY000: Invalid performance_schema usage. -update performance_schema.SETUP_INSTRUMENTS +update performance_schema.setup_instruments set enabled='NO'; -update performance_schema.SETUP_INSTRUMENTS +update performance_schema.setup_instruments set timed='NO'; -select * from performance_schema.SETUP_INSTRUMENTS; -update performance_schema.SETUP_INSTRUMENTS +select * from performance_schema.setup_instruments; +update performance_schema.setup_instruments set enabled='YES', timed='YES'; -delete from performance_schema.SETUP_INSTRUMENTS; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'SETUP_INSTRUMENTS' -delete from performance_schema.SETUP_INSTRUMENTS +delete from performance_schema.setup_instruments; +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'setup_instruments' +delete from performance_schema.setup_instruments where name like 'Wait/Synch/%'; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'SETUP_INSTRUMENTS' -LOCK TABLES performance_schema.SETUP_INSTRUMENTS READ; +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'setup_instruments' +LOCK TABLES performance_schema.setup_instruments READ; UNLOCK TABLES; -LOCK TABLES performance_schema.SETUP_INSTRUMENTS WRITE; +LOCK TABLES performance_schema.setup_instruments WRITE; UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/r/dml_setup_timers.result b/mysql-test/suite/perfschema/r/dml_setup_timers.result index a9bee916cde..ad1f6df3e81 100644 --- a/mysql-test/suite/perfschema/r/dml_setup_timers.result +++ b/mysql-test/suite/perfschema/r/dml_setup_timers.result @@ -1,33 +1,33 @@ -select * from performance_schema.SETUP_TIMERS; +select * from performance_schema.setup_timers; NAME TIMER_NAME wait CYCLE -select * from performance_schema.SETUP_TIMERS +select * from performance_schema.setup_timers where name='Wait'; NAME TIMER_NAME wait CYCLE -select * from performance_schema.SETUP_TIMERS +select * from performance_schema.setup_timers where timer_name='CYCLE'; NAME TIMER_NAME wait CYCLE -insert into performance_schema.SETUP_TIMERS +insert into performance_schema.setup_timers set name='FOO', timer_name='CYCLE'; -ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'SETUP_TIMERS' -update performance_schema.SETUP_TIMERS +ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'setup_timers' +update performance_schema.setup_timers set name='FOO'; ERROR HY000: Invalid performance_schema usage. -update performance_schema.SETUP_TIMERS +update performance_schema.setup_timers set timer_name='MILLISECOND'; -select * from performance_schema.SETUP_TIMERS; +select * from performance_schema.setup_timers; NAME TIMER_NAME wait MILLISECOND -update performance_schema.SETUP_TIMERS +update performance_schema.setup_timers set timer_name='CYCLE'; -delete from performance_schema.SETUP_TIMERS; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'SETUP_TIMERS' -delete from performance_schema.SETUP_TIMERS +delete from performance_schema.setup_timers; +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'setup_timers' +delete from performance_schema.setup_timers where name='Wait'; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'SETUP_TIMERS' -LOCK TABLES performance_schema.SETUP_TIMERS READ; +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'setup_timers' +LOCK TABLES performance_schema.setup_timers READ; UNLOCK TABLES; -LOCK TABLES performance_schema.SETUP_TIMERS WRITE; +LOCK TABLES performance_schema.setup_timers WRITE; UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/r/dml_threads.result b/mysql-test/suite/perfschema/r/dml_threads.result index 261e7977aa5..8c61521d091 100644 --- a/mysql-test/suite/perfschema/r/dml_threads.result +++ b/mysql-test/suite/perfschema/r/dml_threads.result @@ -1,27 +1,27 @@ -select * from performance_schema.THREADS +select * from performance_schema.threads where name like 'Thread/%' limit 1; THREAD_ID PROCESSLIST_ID NAME # # # -select * from performance_schema.THREADS +select * from performance_schema.threads where name='FOO'; THREAD_ID PROCESSLIST_ID NAME -insert into performance_schema.THREADS +insert into performance_schema.threads set name='FOO', thread_id=1, processlist_id=2; -ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'THREADS' -update performance_schema.THREADS +ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'threads' +update performance_schema.threads set thread_id=12; -ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'THREADS' -update performance_schema.THREADS +ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'threads' +update performance_schema.threads set thread_id=12 where name like "FOO"; -ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'THREADS' -delete from performance_schema.THREADS +ERROR 42000: UPDATE command denied to user 'root'@'localhost' for table 'threads' +delete from performance_schema.threads where id=1; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'THREADS' -delete from performance_schema.THREADS; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'THREADS' -LOCK TABLES performance_schema.THREADS READ; -ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'THREADS' +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'threads' +delete from performance_schema.threads; +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'threads' +LOCK TABLES performance_schema.threads READ; +ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'threads' UNLOCK TABLES; -LOCK TABLES performance_schema.THREADS WRITE; -ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'THREADS' +LOCK TABLES performance_schema.threads WRITE; +ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'threads' UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/r/func_file_io.result b/mysql-test/suite/perfschema/r/func_file_io.result index 655ce1394f9..781851bd11c 100644 --- a/mysql-test/suite/perfschema/r/func_file_io.result +++ b/mysql-test/suite/perfschema/r/func_file_io.result @@ -1,18 +1,18 @@ -UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'NO', timed = 'YES'; -UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'YES' +UPDATE performance_schema.setup_instruments SET enabled = 'NO', timed = 'YES'; +UPDATE performance_schema.setup_instruments SET enabled = 'YES' WHERE name LIKE 'wait/io/file/%'; DROP TABLE IF EXISTS t1; CREATE TABLE t1 (id INT PRIMARY KEY, b CHAR(100) DEFAULT 'initial value') ENGINE=MyISAM; INSERT INTO t1 (id) VALUES (1), (2), (3), (4), (5), (6), (7), (8); -TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY_LONG; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_CURRENT; +TRUNCATE TABLE performance_schema.events_waits_history_long; +TRUNCATE TABLE performance_schema.events_waits_history; +TRUNCATE TABLE performance_schema.events_waits_current; SELECT * FROM t1 WHERE id = 1; id b 1 initial value SET @before_count = (SELECT SUM(TIMER_WAIT) -FROM performance_schema.EVENTS_WAITS_HISTORY_LONG +FROM performance_schema.events_waits_history_long WHERE (EVENT_NAME = 'wait/io/file/myisam/dfile') AND (OBJECT_NAME LIKE '%t1.MYD')); SELECT IF(@before_count > 0, 'Success', 'Failure') has_instrumentation; @@ -24,15 +24,15 @@ id b 2 initial value 3 initial value SET @after_count = (SELECT SUM(TIMER_WAIT) -FROM performance_schema.EVENTS_WAITS_HISTORY_LONG +FROM performance_schema.events_waits_history_long WHERE (EVENT_NAME = 'wait/io/file/myisam/dfile') AND (OBJECT_NAME LIKE '%t1.MYD') AND (1 = 1)); SELECT IF((@after_count - @before_count) > 0, 'Success', 'Failure') test_ff1_timed; test_ff1_timed Success -UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled='NO'; +UPDATE performance_schema.setup_instruments SET enabled='NO'; SET @before_count = (SELECT SUM(TIMER_WAIT) -FROM performance_schema.EVENTS_WAITS_HISTORY_LONG +FROM performance_schema.events_waits_history_long WHERE (EVENT_NAME = 'wait/io/file/myisam/dfile') AND (OBJECT_NAME LIKE '%t1.MYD') AND (2 = 2)); SELECT * FROM t1 WHERE id < 6; @@ -43,40 +43,40 @@ id b 4 initial value 5 initial value SET @after_count = (SELECT SUM(TIMER_WAIT) -FROM performance_schema.EVENTS_WAITS_HISTORY_LONG +FROM performance_schema.events_waits_history_long WHERE (EVENT_NAME = 'wait/io/file/myisam/dfile') AND (OBJECT_NAME LIKE '%t1.MYD') AND (3 = 3)); SELECT IF((COALESCE(@after_count, 0) - COALESCE(@before_count, 0)) = 0, 'Success', 'Failure') test_ff2_timed; test_ff2_timed Success -UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'YES' +UPDATE performance_schema.setup_instruments SET enabled = 'YES' WHERE name LIKE 'wait/io/file/%'; -UPDATE performance_schema.SETUP_INSTRUMENTS SET timed = 'NO'; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY_LONG; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_CURRENT; +UPDATE performance_schema.setup_instruments SET timed = 'NO'; +TRUNCATE TABLE performance_schema.events_waits_history_long; +TRUNCATE TABLE performance_schema.events_waits_history; +TRUNCATE TABLE performance_schema.events_waits_current; SELECT * FROM t1 WHERE id > 4; id b 5 initial value 6 initial value 7 initial value 8 initial value -SELECT * FROM performance_schema.EVENTS_WAITS_HISTORY_LONG +SELECT * FROM performance_schema.events_waits_history_long WHERE TIMER_WAIT != NULL OR TIMER_START != NULL OR TIMER_END != NULL; THREAD_ID EVENT_ID EVENT_NAME SOURCE TIMER_START TIMER_END TIMER_WAIT SPINS OBJECT_SCHEMA OBJECT_NAME OBJECT_TYPE OBJECT_INSTANCE_BEGIN NESTING_EVENT_ID OPERATION NUMBER_OF_BYTES FLAGS -SELECT * FROM performance_schema.EVENTS_WAITS_HISTORY +SELECT * FROM performance_schema.events_waits_history WHERE TIMER_WAIT != NULL OR TIMER_START != NULL OR TIMER_END != NULL; THREAD_ID EVENT_ID EVENT_NAME SOURCE TIMER_START TIMER_END TIMER_WAIT SPINS OBJECT_SCHEMA OBJECT_NAME OBJECT_TYPE OBJECT_INSTANCE_BEGIN NESTING_EVENT_ID OPERATION NUMBER_OF_BYTES FLAGS -SELECT * FROM performance_schema.EVENTS_WAITS_CURRENT +SELECT * FROM performance_schema.events_waits_current WHERE TIMER_WAIT != NULL OR TIMER_START != NULL OR TIMER_END != NULL; THREAD_ID EVENT_ID EVENT_NAME SOURCE TIMER_START TIMER_END TIMER_WAIT SPINS OBJECT_SCHEMA OBJECT_NAME OBJECT_TYPE OBJECT_INSTANCE_BEGIN NESTING_EVENT_ID OPERATION NUMBER_OF_BYTES FLAGS -UPDATE performance_schema.SETUP_INSTRUMENTS SET timed = 'YES'; +UPDATE performance_schema.setup_instruments SET timed = 'YES'; SELECT * FROM t1 WHERE id < 4; id b 1 initial value @@ -87,16 +87,16 @@ SELECT SUM(COUNT_READ) AS sum_count_read, SUM(COUNT_WRITE) AS sum_count_write, SUM(SUM_NUMBER_OF_BYTES_READ) AS sum_num_bytes_read, SUM(SUM_NUMBER_OF_BYTES_WRITE) AS sum_num_bytes_write -FROM performance_schema.FILE_SUMMARY_BY_INSTANCE +FROM performance_schema.file_summary_by_instance WHERE FILE_NAME LIKE CONCAT('%', @@tmpdir, '%') ORDER BY NULL; SELECT EVENT_NAME, COUNT_STAR, AVG_TIMER_WAIT, SUM_TIMER_WAIT -FROM performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME +FROM performance_schema.events_waits_summary_global_by_event_name WHERE COUNT_STAR > 0 ORDER BY SUM_TIMER_WAIT DESC LIMIT 10; SELECT h.EVENT_NAME, SUM(h.TIMER_WAIT) TOTAL_WAIT -FROM performance_schema.EVENTS_WAITS_HISTORY_LONG h -INNER JOIN performance_schema.THREADS p USING (THREAD_ID) +FROM performance_schema.events_waits_history_long h +INNER JOIN performance_schema.threads p USING (THREAD_ID) WHERE p.PROCESSLIST_ID = 1 GROUP BY h.EVENT_NAME HAVING TOTAL_WAIT > 0; diff --git a/mysql-test/suite/perfschema/r/func_mutex.result b/mysql-test/suite/perfschema/r/func_mutex.result index e32d7267bb1..d767455609d 100644 --- a/mysql-test/suite/perfschema/r/func_mutex.result +++ b/mysql-test/suite/perfschema/r/func_mutex.result @@ -1,19 +1,19 @@ -UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'NO', timed = 'YES'; -UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'YES' +UPDATE performance_schema.setup_instruments SET enabled = 'NO', timed = 'YES'; +UPDATE performance_schema.setup_instruments SET enabled = 'YES' WHERE name LIKE 'wait/synch/mutex/%' OR name LIKE 'wait/synch/rwlock/%'; DROP TABLE IF EXISTS t1; CREATE TABLE t1 (id INT PRIMARY KEY, b CHAR(100) DEFAULT 'initial value') ENGINE=MyISAM; INSERT INTO t1 (id) VALUES (1), (2), (3), (4), (5), (6), (7), (8); -TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY_LONG; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_CURRENT; +TRUNCATE TABLE performance_schema.events_waits_history_long; +TRUNCATE TABLE performance_schema.events_waits_history; +TRUNCATE TABLE performance_schema.events_waits_current; SELECT * FROM t1 WHERE id = 1; id b 1 initial value SET @before_count = (SELECT SUM(TIMER_WAIT) -FROM performance_schema.EVENTS_WAITS_HISTORY_LONG +FROM performance_schema.events_waits_history_long WHERE (EVENT_NAME = 'wait/synch/mutex/sql/LOCK_open')); SELECT * FROM t1; id b @@ -26,21 +26,21 @@ id b 7 initial value 8 initial value SET @after_count = (SELECT SUM(TIMER_WAIT) -FROM performance_schema.EVENTS_WAITS_HISTORY_LONG +FROM performance_schema.events_waits_history_long WHERE (EVENT_NAME = 'wait/synch/mutex/sql/LOCK_open')); SELECT IF((@after_count - @before_count) > 0, 'Success', 'Failure') test_fm1_timed; test_fm1_timed Success -UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'NO' +UPDATE performance_schema.setup_instruments SET enabled = 'NO' WHERE NAME = 'wait/synch/mutex/sql/LOCK_open'; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY_LONG; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_CURRENT; +TRUNCATE TABLE performance_schema.events_waits_history_long; +TRUNCATE TABLE performance_schema.events_waits_history; +TRUNCATE TABLE performance_schema.events_waits_current; SELECT * FROM t1 WHERE id = 1; id b 1 initial value SET @before_count = (SELECT SUM(TIMER_WAIT) -FROM performance_schema.EVENTS_WAITS_HISTORY_LONG +FROM performance_schema.events_waits_history_long WHERE (EVENT_NAME = 'wait/synch/mutex/sql/LOCK_open')); SELECT * FROM t1; id b @@ -53,19 +53,19 @@ id b 7 initial value 8 initial value SET @after_count = (SELECT SUM(TIMER_WAIT) -FROM performance_schema.EVENTS_WAITS_HISTORY_LONG +FROM performance_schema.events_waits_history_long WHERE (EVENT_NAME = 'wait/synch/mutex/sql/LOCK_open')); SELECT IF((COALESCE(@after_count, 0) - COALESCE(@before_count, 0)) = 0, 'Success', 'Failure') test_fm2_timed; test_fm2_timed Success -TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY_LONG; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_CURRENT; +TRUNCATE TABLE performance_schema.events_waits_history_long; +TRUNCATE TABLE performance_schema.events_waits_history; +TRUNCATE TABLE performance_schema.events_waits_current; SELECT * FROM t1 WHERE id = 1; id b 1 initial value SET @before_count = (SELECT SUM(TIMER_WAIT) -FROM performance_schema.EVENTS_WAITS_HISTORY_LONG +FROM performance_schema.events_waits_history_long WHERE (EVENT_NAME = 'wait/synch/rwlock/sql/LOCK_grant')); SELECT * FROM t1; id b @@ -78,21 +78,21 @@ id b 7 initial value 8 initial value SET @after_count = (SELECT SUM(TIMER_WAIT) -FROM performance_schema.EVENTS_WAITS_HISTORY_LONG +FROM performance_schema.events_waits_history_long WHERE (EVENT_NAME = 'wait/synch/rwlock/sql/LOCK_grant')); SELECT IF((@after_count - @before_count) > 0, 'Success', 'Failure') test_fm1_rw_timed; test_fm1_rw_timed Success -UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'NO' +UPDATE performance_schema.setup_instruments SET enabled = 'NO' WHERE NAME = 'wait/synch/rwlock/sql/LOCK_grant'; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY_LONG; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_CURRENT; +TRUNCATE TABLE performance_schema.events_waits_history_long; +TRUNCATE TABLE performance_schema.events_waits_history; +TRUNCATE TABLE performance_schema.events_waits_current; SELECT * FROM t1 WHERE id = 1; id b 1 initial value SET @before_count = (SELECT SUM(TIMER_WAIT) -FROM performance_schema.EVENTS_WAITS_HISTORY_LONG +FROM performance_schema.events_waits_history_long WHERE (EVENT_NAME = 'wait/synch/rwlock/sql/LOCK_grant')); SELECT * FROM t1; id b @@ -105,7 +105,7 @@ id b 7 initial value 8 initial value SET @after_count = (SELECT SUM(TIMER_WAIT) -FROM performance_schema.EVENTS_WAITS_HISTORY_LONG +FROM performance_schema.events_waits_history_long WHERE (EVENT_NAME = 'wait/synch/rwlock/sql/LOCK_grant')); SELECT IF((COALESCE(@after_count, 0) - COALESCE(@before_count, 0)) = 0, 'Success', 'Failure') test_fm2_rw_timed; test_fm2_rw_timed diff --git a/mysql-test/suite/perfschema/r/global_read_lock.result b/mysql-test/suite/perfschema/r/global_read_lock.result index 93d6adfd049..8a58c072b7a 100644 --- a/mysql-test/suite/perfschema/r/global_read_lock.result +++ b/mysql-test/suite/perfschema/r/global_read_lock.result @@ -2,31 +2,31 @@ use performance_schema; grant SELECT, UPDATE, LOCK TABLES on performance_schema.* to pfsuser@localhost; flush privileges; connect (con1, localhost, pfsuser, , test); -lock tables performance_schema.SETUP_INSTRUMENTS read; -select * from performance_schema.SETUP_INSTRUMENTS; +lock tables performance_schema.setup_instruments read; +select * from performance_schema.setup_instruments; unlock tables; -lock tables performance_schema.SETUP_INSTRUMENTS write; -update performance_schema.SETUP_INSTRUMENTS set enabled='NO'; -update performance_schema.SETUP_INSTRUMENTS set enabled='YES'; +lock tables performance_schema.setup_instruments write; +update performance_schema.setup_instruments set enabled='NO'; +update performance_schema.setup_instruments set enabled='YES'; unlock tables; connection default; flush tables with read lock; connection con1; -lock tables performance_schema.SETUP_INSTRUMENTS read; -select * from performance_schema.SETUP_INSTRUMENTS; +lock tables performance_schema.setup_instruments read; +select * from performance_schema.setup_instruments; unlock tables; -lock tables performance_schema.SETUP_INSTRUMENTS write; +lock tables performance_schema.setup_instruments write; connection default; select event_name, left(source, locate(":", source)) as short_source, timer_end, timer_wait, operation -from performance_schema.EVENTS_WAITS_CURRENT +from performance_schema.events_waits_current where event_name like "wait/synch/cond/sql/COND_global_read_lock"; event_name short_source timer_end timer_wait operation wait/synch/cond/sql/COND_global_read_lock lock.cc: NULL NULL wait unlock tables; -update performance_schema.SETUP_INSTRUMENTS set enabled='NO'; -update performance_schema.SETUP_INSTRUMENTS set enabled='YES'; +update performance_schema.setup_instruments set enabled='NO'; +update performance_schema.setup_instruments set enabled='YES'; unlock tables; connection default; drop user pfsuser@localhost; diff --git a/mysql-test/suite/perfschema/r/information_schema.result b/mysql-test/suite/perfschema/r/information_schema.result index 8e7478564fb..ab464cce687 100644 --- a/mysql-test/suite/perfschema/r/information_schema.result +++ b/mysql-test/suite/perfschema/r/information_schema.result @@ -1,189 +1,189 @@ -select TABLE_SCHEMA, upper(TABLE_NAME), TABLE_CATALOG +select TABLE_SCHEMA, lower(TABLE_NAME), TABLE_CATALOG from information_schema.tables where TABLE_SCHEMA='performance_schema'; -TABLE_SCHEMA upper(TABLE_NAME) TABLE_CATALOG -performance_schema COND_INSTANCES def -performance_schema EVENTS_WAITS_CURRENT def -performance_schema EVENTS_WAITS_HISTORY def -performance_schema EVENTS_WAITS_HISTORY_LONG def -performance_schema EVENTS_WAITS_SUMMARY_BY_INSTANCE def -performance_schema EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME def -performance_schema EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME def -performance_schema FILE_INSTANCES def -performance_schema FILE_SUMMARY_BY_EVENT_NAME def -performance_schema FILE_SUMMARY_BY_INSTANCE def -performance_schema MUTEX_INSTANCES def -performance_schema PERFORMANCE_TIMERS def -performance_schema RWLOCK_INSTANCES def -performance_schema SETUP_CONSUMERS def -performance_schema SETUP_INSTRUMENTS def -performance_schema SETUP_TIMERS def -performance_schema THREADS def -select upper(TABLE_NAME), TABLE_TYPE, ENGINE +TABLE_SCHEMA lower(TABLE_NAME) TABLE_CATALOG +performance_schema cond_instances def +performance_schema events_waits_current def +performance_schema events_waits_history def +performance_schema events_waits_history_long def +performance_schema events_waits_summary_by_instance def +performance_schema events_waits_summary_by_thread_by_event_name def +performance_schema events_waits_summary_global_by_event_name def +performance_schema file_instances def +performance_schema file_summary_by_event_name def +performance_schema file_summary_by_instance def +performance_schema mutex_instances def +performance_schema performance_timers def +performance_schema rwlock_instances def +performance_schema setup_consumers def +performance_schema setup_instruments def +performance_schema setup_timers def +performance_schema threads def +select lower(TABLE_NAME), TABLE_TYPE, ENGINE from information_schema.tables where TABLE_SCHEMA='performance_schema'; -upper(TABLE_NAME) TABLE_TYPE ENGINE -COND_INSTANCES BASE TABLE PERFORMANCE_SCHEMA -EVENTS_WAITS_CURRENT BASE TABLE PERFORMANCE_SCHEMA -EVENTS_WAITS_HISTORY BASE TABLE PERFORMANCE_SCHEMA -EVENTS_WAITS_HISTORY_LONG BASE TABLE PERFORMANCE_SCHEMA -EVENTS_WAITS_SUMMARY_BY_INSTANCE BASE TABLE PERFORMANCE_SCHEMA -EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME BASE TABLE PERFORMANCE_SCHEMA -EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME BASE TABLE PERFORMANCE_SCHEMA -FILE_INSTANCES BASE TABLE PERFORMANCE_SCHEMA -FILE_SUMMARY_BY_EVENT_NAME BASE TABLE PERFORMANCE_SCHEMA -FILE_SUMMARY_BY_INSTANCE BASE TABLE PERFORMANCE_SCHEMA -MUTEX_INSTANCES BASE TABLE PERFORMANCE_SCHEMA -PERFORMANCE_TIMERS BASE TABLE PERFORMANCE_SCHEMA -RWLOCK_INSTANCES BASE TABLE PERFORMANCE_SCHEMA -SETUP_CONSUMERS BASE TABLE PERFORMANCE_SCHEMA -SETUP_INSTRUMENTS BASE TABLE PERFORMANCE_SCHEMA -SETUP_TIMERS BASE TABLE PERFORMANCE_SCHEMA -THREADS BASE TABLE PERFORMANCE_SCHEMA -select upper(TABLE_NAME), VERSION, ROW_FORMAT +lower(TABLE_NAME) TABLE_TYPE ENGINE +cond_instances BASE TABLE PERFORMANCE_SCHEMA +events_waits_current BASE TABLE PERFORMANCE_SCHEMA +events_waits_history BASE TABLE PERFORMANCE_SCHEMA +events_waits_history_long BASE TABLE PERFORMANCE_SCHEMA +events_waits_summary_by_instance BASE TABLE PERFORMANCE_SCHEMA +events_waits_summary_by_thread_by_event_name BASE TABLE PERFORMANCE_SCHEMA +events_waits_summary_global_by_event_name BASE TABLE PERFORMANCE_SCHEMA +file_instances BASE TABLE PERFORMANCE_SCHEMA +file_summary_by_event_name BASE TABLE PERFORMANCE_SCHEMA +file_summary_by_instance BASE TABLE PERFORMANCE_SCHEMA +mutex_instances BASE TABLE PERFORMANCE_SCHEMA +performance_timers BASE TABLE PERFORMANCE_SCHEMA +rwlock_instances BASE TABLE PERFORMANCE_SCHEMA +setup_consumers BASE TABLE PERFORMANCE_SCHEMA +setup_instruments BASE TABLE PERFORMANCE_SCHEMA +setup_timers BASE TABLE PERFORMANCE_SCHEMA +threads BASE TABLE PERFORMANCE_SCHEMA +select lower(TABLE_NAME), VERSION, ROW_FORMAT from information_schema.tables where TABLE_SCHEMA='performance_schema'; -upper(TABLE_NAME) VERSION ROW_FORMAT -COND_INSTANCES 10 Dynamic -EVENTS_WAITS_CURRENT 10 Dynamic -EVENTS_WAITS_HISTORY 10 Dynamic -EVENTS_WAITS_HISTORY_LONG 10 Dynamic -EVENTS_WAITS_SUMMARY_BY_INSTANCE 10 Dynamic -EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME 10 Dynamic -EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME 10 Dynamic -FILE_INSTANCES 10 Dynamic -FILE_SUMMARY_BY_EVENT_NAME 10 Dynamic -FILE_SUMMARY_BY_INSTANCE 10 Dynamic -MUTEX_INSTANCES 10 Dynamic -PERFORMANCE_TIMERS 10 Fixed -RWLOCK_INSTANCES 10 Dynamic -SETUP_CONSUMERS 10 Dynamic -SETUP_INSTRUMENTS 10 Dynamic -SETUP_TIMERS 10 Dynamic -THREADS 10 Dynamic -select upper(TABLE_NAME), TABLE_ROWS, AVG_ROW_LENGTH +lower(TABLE_NAME) VERSION ROW_FORMAT +cond_instances 10 Dynamic +events_waits_current 10 Dynamic +events_waits_history 10 Dynamic +events_waits_history_long 10 Dynamic +events_waits_summary_by_instance 10 Dynamic +events_waits_summary_by_thread_by_event_name 10 Dynamic +events_waits_summary_global_by_event_name 10 Dynamic +file_instances 10 Dynamic +file_summary_by_event_name 10 Dynamic +file_summary_by_instance 10 Dynamic +mutex_instances 10 Dynamic +performance_timers 10 Fixed +rwlock_instances 10 Dynamic +setup_consumers 10 Dynamic +setup_instruments 10 Dynamic +setup_timers 10 Dynamic +threads 10 Dynamic +select lower(TABLE_NAME), TABLE_ROWS, AVG_ROW_LENGTH from information_schema.tables where TABLE_SCHEMA='performance_schema'; -upper(TABLE_NAME) TABLE_ROWS AVG_ROW_LENGTH -COND_INSTANCES 1000 0 -EVENTS_WAITS_CURRENT 1000 0 -EVENTS_WAITS_HISTORY 1000 0 -EVENTS_WAITS_HISTORY_LONG 10000 0 -EVENTS_WAITS_SUMMARY_BY_INSTANCE 1000 0 -EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME 1000 0 -EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME 1000 0 -FILE_INSTANCES 1000 0 -FILE_SUMMARY_BY_EVENT_NAME 1000 0 -FILE_SUMMARY_BY_INSTANCE 1000 0 -MUTEX_INSTANCES 1000 0 -PERFORMANCE_TIMERS 5 0 -RWLOCK_INSTANCES 1000 0 -SETUP_CONSUMERS 8 0 -SETUP_INSTRUMENTS 1000 0 -SETUP_TIMERS 1 0 -THREADS 1000 0 -select upper(TABLE_NAME), DATA_LENGTH, MAX_DATA_LENGTH +lower(TABLE_NAME) TABLE_ROWS AVG_ROW_LENGTH +cond_instances 1000 0 +events_waits_current 1000 0 +events_waits_history 1000 0 +events_waits_history_long 10000 0 +events_waits_summary_by_instance 1000 0 +events_waits_summary_by_thread_by_event_name 1000 0 +events_waits_summary_global_by_event_name 1000 0 +file_instances 1000 0 +file_summary_by_event_name 1000 0 +file_summary_by_instance 1000 0 +mutex_instances 1000 0 +performance_timers 5 0 +rwlock_instances 1000 0 +setup_consumers 8 0 +setup_instruments 1000 0 +setup_timers 1 0 +threads 1000 0 +select lower(TABLE_NAME), DATA_LENGTH, MAX_DATA_LENGTH from information_schema.tables where TABLE_SCHEMA='performance_schema'; -upper(TABLE_NAME) DATA_LENGTH MAX_DATA_LENGTH -COND_INSTANCES 0 0 -EVENTS_WAITS_CURRENT 0 0 -EVENTS_WAITS_HISTORY 0 0 -EVENTS_WAITS_HISTORY_LONG 0 0 -EVENTS_WAITS_SUMMARY_BY_INSTANCE 0 0 -EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME 0 0 -EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME 0 0 -FILE_INSTANCES 0 0 -FILE_SUMMARY_BY_EVENT_NAME 0 0 -FILE_SUMMARY_BY_INSTANCE 0 0 -MUTEX_INSTANCES 0 0 -PERFORMANCE_TIMERS 0 0 -RWLOCK_INSTANCES 0 0 -SETUP_CONSUMERS 0 0 -SETUP_INSTRUMENTS 0 0 -SETUP_TIMERS 0 0 -THREADS 0 0 -select upper(TABLE_NAME), INDEX_LENGTH, DATA_FREE, AUTO_INCREMENT +lower(TABLE_NAME) DATA_LENGTH MAX_DATA_LENGTH +cond_instances 0 0 +events_waits_current 0 0 +events_waits_history 0 0 +events_waits_history_long 0 0 +events_waits_summary_by_instance 0 0 +events_waits_summary_by_thread_by_event_name 0 0 +events_waits_summary_global_by_event_name 0 0 +file_instances 0 0 +file_summary_by_event_name 0 0 +file_summary_by_instance 0 0 +mutex_instances 0 0 +performance_timers 0 0 +rwlock_instances 0 0 +setup_consumers 0 0 +setup_instruments 0 0 +setup_timers 0 0 +threads 0 0 +select lower(TABLE_NAME), INDEX_LENGTH, DATA_FREE, AUTO_INCREMENT from information_schema.tables where TABLE_SCHEMA='performance_schema'; -upper(TABLE_NAME) INDEX_LENGTH DATA_FREE AUTO_INCREMENT -COND_INSTANCES 0 0 NULL -EVENTS_WAITS_CURRENT 0 0 NULL -EVENTS_WAITS_HISTORY 0 0 NULL -EVENTS_WAITS_HISTORY_LONG 0 0 NULL -EVENTS_WAITS_SUMMARY_BY_INSTANCE 0 0 NULL -EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME 0 0 NULL -EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME 0 0 NULL -FILE_INSTANCES 0 0 NULL -FILE_SUMMARY_BY_EVENT_NAME 0 0 NULL -FILE_SUMMARY_BY_INSTANCE 0 0 NULL -MUTEX_INSTANCES 0 0 NULL -PERFORMANCE_TIMERS 0 0 NULL -RWLOCK_INSTANCES 0 0 NULL -SETUP_CONSUMERS 0 0 NULL -SETUP_INSTRUMENTS 0 0 NULL -SETUP_TIMERS 0 0 NULL -THREADS 0 0 NULL -select upper(TABLE_NAME), CREATE_TIME, UPDATE_TIME, CHECK_TIME +lower(TABLE_NAME) INDEX_LENGTH DATA_FREE AUTO_INCREMENT +cond_instances 0 0 NULL +events_waits_current 0 0 NULL +events_waits_history 0 0 NULL +events_waits_history_long 0 0 NULL +events_waits_summary_by_instance 0 0 NULL +events_waits_summary_by_thread_by_event_name 0 0 NULL +events_waits_summary_global_by_event_name 0 0 NULL +file_instances 0 0 NULL +file_summary_by_event_name 0 0 NULL +file_summary_by_instance 0 0 NULL +mutex_instances 0 0 NULL +performance_timers 0 0 NULL +rwlock_instances 0 0 NULL +setup_consumers 0 0 NULL +setup_instruments 0 0 NULL +setup_timers 0 0 NULL +threads 0 0 NULL +select lower(TABLE_NAME), CREATE_TIME, UPDATE_TIME, CHECK_TIME from information_schema.tables where TABLE_SCHEMA='performance_schema'; -upper(TABLE_NAME) CREATE_TIME UPDATE_TIME CHECK_TIME -COND_INSTANCES NULL NULL NULL -EVENTS_WAITS_CURRENT NULL NULL NULL -EVENTS_WAITS_HISTORY NULL NULL NULL -EVENTS_WAITS_HISTORY_LONG NULL NULL NULL -EVENTS_WAITS_SUMMARY_BY_INSTANCE NULL NULL NULL -EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME NULL NULL NULL -EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME NULL NULL NULL -FILE_INSTANCES NULL NULL NULL -FILE_SUMMARY_BY_EVENT_NAME NULL NULL NULL -FILE_SUMMARY_BY_INSTANCE NULL NULL NULL -MUTEX_INSTANCES NULL NULL NULL -PERFORMANCE_TIMERS NULL NULL NULL -RWLOCK_INSTANCES NULL NULL NULL -SETUP_CONSUMERS NULL NULL NULL -SETUP_INSTRUMENTS NULL NULL NULL -SETUP_TIMERS NULL NULL NULL -THREADS NULL NULL NULL -select upper(TABLE_NAME), TABLE_COLLATION, CHECKSUM +lower(TABLE_NAME) CREATE_TIME UPDATE_TIME CHECK_TIME +cond_instances NULL NULL NULL +events_waits_current NULL NULL NULL +events_waits_history NULL NULL NULL +events_waits_history_long NULL NULL NULL +events_waits_summary_by_instance NULL NULL NULL +events_waits_summary_by_thread_by_event_name NULL NULL NULL +events_waits_summary_global_by_event_name NULL NULL NULL +file_instances NULL NULL NULL +file_summary_by_event_name NULL NULL NULL +file_summary_by_instance NULL NULL NULL +mutex_instances NULL NULL NULL +performance_timers NULL NULL NULL +rwlock_instances NULL NULL NULL +setup_consumers NULL NULL NULL +setup_instruments NULL NULL NULL +setup_timers NULL NULL NULL +threads NULL NULL NULL +select lower(TABLE_NAME), TABLE_COLLATION, CHECKSUM from information_schema.tables where TABLE_SCHEMA='performance_schema'; -upper(TABLE_NAME) TABLE_COLLATION CHECKSUM -COND_INSTANCES utf8_general_ci NULL -EVENTS_WAITS_CURRENT utf8_general_ci NULL -EVENTS_WAITS_HISTORY utf8_general_ci NULL -EVENTS_WAITS_HISTORY_LONG utf8_general_ci NULL -EVENTS_WAITS_SUMMARY_BY_INSTANCE utf8_general_ci NULL -EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME utf8_general_ci NULL -EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME utf8_general_ci NULL -FILE_INSTANCES utf8_general_ci NULL -FILE_SUMMARY_BY_EVENT_NAME utf8_general_ci NULL -FILE_SUMMARY_BY_INSTANCE utf8_general_ci NULL -MUTEX_INSTANCES utf8_general_ci NULL -PERFORMANCE_TIMERS utf8_general_ci NULL -RWLOCK_INSTANCES utf8_general_ci NULL -SETUP_CONSUMERS utf8_general_ci NULL -SETUP_INSTRUMENTS utf8_general_ci NULL -SETUP_TIMERS utf8_general_ci NULL -THREADS utf8_general_ci NULL -select upper(TABLE_NAME), TABLE_COMMENT +lower(TABLE_NAME) TABLE_COLLATION CHECKSUM +cond_instances utf8_general_ci NULL +events_waits_current utf8_general_ci NULL +events_waits_history utf8_general_ci NULL +events_waits_history_long utf8_general_ci NULL +events_waits_summary_by_instance utf8_general_ci NULL +events_waits_summary_by_thread_by_event_name utf8_general_ci NULL +events_waits_summary_global_by_event_name utf8_general_ci NULL +file_instances utf8_general_ci NULL +file_summary_by_event_name utf8_general_ci NULL +file_summary_by_instance utf8_general_ci NULL +mutex_instances utf8_general_ci NULL +performance_timers utf8_general_ci NULL +rwlock_instances utf8_general_ci NULL +setup_consumers utf8_general_ci NULL +setup_instruments utf8_general_ci NULL +setup_timers utf8_general_ci NULL +threads utf8_general_ci NULL +select lower(TABLE_NAME), TABLE_COMMENT from information_schema.tables where TABLE_SCHEMA='performance_schema'; -upper(TABLE_NAME) TABLE_COMMENT -COND_INSTANCES -EVENTS_WAITS_CURRENT -EVENTS_WAITS_HISTORY -EVENTS_WAITS_HISTORY_LONG -EVENTS_WAITS_SUMMARY_BY_INSTANCE -EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME -EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME -FILE_INSTANCES -FILE_SUMMARY_BY_EVENT_NAME -FILE_SUMMARY_BY_INSTANCE -MUTEX_INSTANCES -PERFORMANCE_TIMERS -RWLOCK_INSTANCES -SETUP_CONSUMERS -SETUP_INSTRUMENTS -SETUP_TIMERS -THREADS +lower(TABLE_NAME) TABLE_COMMENT +cond_instances +events_waits_current +events_waits_history +events_waits_history_long +events_waits_summary_by_instance +events_waits_summary_by_thread_by_event_name +events_waits_summary_global_by_event_name +file_instances +file_summary_by_event_name +file_summary_by_instance +mutex_instances +performance_timers +rwlock_instances +setup_consumers +setup_instruments +setup_timers +threads diff --git a/mysql-test/suite/perfschema/r/misc.result b/mysql-test/suite/perfschema/r/misc.result index e389a4ce65c..4e9b08e00ef 100644 --- a/mysql-test/suite/perfschema/r/misc.result +++ b/mysql-test/suite/perfschema/r/misc.result @@ -1,13 +1,13 @@ -SELECT EVENT_ID FROM performance_schema.EVENTS_WAITS_CURRENT +SELECT EVENT_ID FROM performance_schema.events_waits_current WHERE THREAD_ID IN -(SELECT THREAD_ID FROM performance_schema.THREADS) +(SELECT THREAD_ID FROM performance_schema.threads) AND EVENT_NAME IN -(SELECT NAME FROM performance_schema.SETUP_INSTRUMENTS +(SELECT NAME FROM performance_schema.setup_instruments WHERE NAME LIKE "wait/synch/%") LIMIT 1; create table test.t1(a int) engine=performance_schema; ERROR HY000: Invalid performance_schema usage. -create table test.t1 like performance_schema.EVENTS_WAITS_CURRENT; +create table test.t1 like performance_schema.events_waits_current; ERROR HY000: Invalid performance_schema usage. create table performance_schema.t1(a int); ERROR 42000: CREATE command denied to user 'root'@'localhost' for table 't1' @@ -22,7 +22,7 @@ a b 1 3 2 4 drop table test.ghost; -select * from performance_schema.FILE_INSTANCES +select * from performance_schema.file_instances where file_name like "%ghost%"; FILE_NAME EVENT_NAME OPEN_COUNT select * from performance_schema.no_such_table; diff --git a/mysql-test/suite/perfschema/r/myisam_file_io.result b/mysql-test/suite/perfschema/r/myisam_file_io.result index 5d710d9183d..287abd43d74 100644 --- a/mysql-test/suite/perfschema/r/myisam_file_io.result +++ b/mysql-test/suite/perfschema/r/myisam_file_io.result @@ -1,9 +1,9 @@ -update performance_schema.SETUP_INSTRUMENTS set enabled='NO'; -update performance_schema.SETUP_INSTRUMENTS set enabled='YES' +update performance_schema.setup_instruments set enabled='NO'; +update performance_schema.setup_instruments set enabled='YES' where name like "wait/io/file/myisam/%"; -update performance_schema.SETUP_CONSUMERS +update performance_schema.setup_consumers set enabled='YES'; -truncate table performance_schema.EVENTS_WAITS_HISTORY_LONG; +truncate table performance_schema.events_waits_history_long; flush status; drop table if exists test.no_index_tab; create table test.no_index_tab ( a varchar(255), b int ) engine=myisam; @@ -14,7 +14,7 @@ select event_name, left(source, locate(":", source)) as short_source, operation, number_of_bytes, substring(object_name, locate("no_index_tab", object_name)) as short_name -from performance_schema.EVENTS_WAITS_HISTORY_LONG +from performance_schema.events_waits_history_long where operation not like "tell" order by thread_id, event_id; event_name short_source operation number_of_bytes short_name @@ -56,5 +56,5 @@ Performance_schema_table_handles_lost 0 Performance_schema_table_instances_lost 0 Performance_schema_thread_classes_lost 0 Performance_schema_thread_instances_lost 0 -update performance_schema.SETUP_INSTRUMENTS set enabled='YES'; +update performance_schema.setup_instruments set enabled='YES'; drop table test.no_index_tab; diff --git a/mysql-test/suite/perfschema/r/no_threads.result b/mysql-test/suite/perfschema/r/no_threads.result index 79d16809eee..89ae72c8df1 100644 --- a/mysql-test/suite/perfschema/r/no_threads.result +++ b/mysql-test/suite/perfschema/r/no_threads.result @@ -1,11 +1,11 @@ -update performance_schema.SETUP_INSTRUMENTS set enabled='NO'; -update performance_schema.SETUP_CONSUMERS set enabled='YES'; -update performance_schema.SETUP_INSTRUMENTS set enabled='YES' +update performance_schema.setup_instruments set enabled='NO'; +update performance_schema.setup_consumers set enabled='YES'; +update performance_schema.setup_instruments set enabled='YES' where name like "wait/synch/mutex/mysys/THR_LOCK_myisam"; drop table if exists test.t1; -truncate table performance_schema.EVENTS_WAITS_CURRENT; -truncate table performance_schema.EVENTS_WAITS_HISTORY; -truncate table performance_schema.EVENTS_WAITS_HISTORY_LONG; +truncate table performance_schema.events_waits_current; +truncate table performance_schema.events_waits_history; +truncate table performance_schema.events_waits_history_long; show variables like "thread_handling"; Variable_name Value thread_handling no-threads @@ -17,27 +17,27 @@ show variables like "performance_schema_max_thread%"; Variable_name Value performance_schema_max_thread_classes 50 performance_schema_max_thread_instances 10 -select count(*) from performance_schema.THREADS +select count(*) from performance_schema.threads where name like "thread/sql/main"; count(*) 1 -select count(*) from performance_schema.THREADS +select count(*) from performance_schema.threads where name like "thread/sql/OneConnection"; count(*) 0 select event_name, operation, left(source, locate(":", source)) as short_source -from performance_schema.EVENTS_WAITS_CURRENT; +from performance_schema.events_waits_current; event_name operation short_source wait/synch/mutex/mysys/THR_LOCK_myisam lock mi_create.c: select event_name, operation, left(source, locate(":", source)) as short_source -from performance_schema.EVENTS_WAITS_HISTORY; +from performance_schema.events_waits_history; event_name operation short_source wait/synch/mutex/mysys/THR_LOCK_myisam lock mi_create.c: select event_name, operation, left(source, locate(":", source)) as short_source -from performance_schema.EVENTS_WAITS_HISTORY_LONG; +from performance_schema.events_waits_history_long; event_name operation short_source wait/synch/mutex/mysys/THR_LOCK_myisam lock mi_create.c: drop table test.t1; diff --git a/mysql-test/suite/perfschema/r/one_thread_per_con.result b/mysql-test/suite/perfschema/r/one_thread_per_con.result index 9677a09933a..998aba6281c 100644 --- a/mysql-test/suite/perfschema/r/one_thread_per_con.result +++ b/mysql-test/suite/perfschema/r/one_thread_per_con.result @@ -1,9 +1,9 @@ -update performance_schema.SETUP_INSTRUMENTS set enabled='YES' +update performance_schema.setup_instruments set enabled='YES' where name like "wait/synch/mutex/mysys/THR_LOCK_myisam"; drop table if exists test.t1; drop table if exists test.t2; drop table if exists test.t3; -truncate table performance_schema.EVENTS_WAITS_HISTORY_LONG; +truncate table performance_schema.events_waits_history_long; show variables like "thread_handling"; Variable_name Value thread_handling one-thread-per-connection @@ -35,4 +35,4 @@ thread/sql/one_connection drop table test.t1; drop table test.t2; drop table test.t3; -update performance_schema.SETUP_INSTRUMENTS set enabled='YES'; +update performance_schema.setup_instruments set enabled='YES'; diff --git a/mysql-test/suite/perfschema/r/privilege.result b/mysql-test/suite/perfschema/r/privilege.result index 4283b250cee..61f5adac354 100644 --- a/mysql-test/suite/perfschema/r/privilege.result +++ b/mysql-test/suite/perfschema/r/privilege.result @@ -35,102 +35,102 @@ grant INSERT on performance_schema.* to 'pfs_user_2'@localhost; grant UPDATE on performance_schema.* to 'pfs_user_2'@localhost; grant DELETE on performance_schema.* to 'pfs_user_2'@localhost; grant LOCK TABLES on performance_schema.* to 'pfs_user_2'@localhost; -grant ALL on performance_schema.SETUP_INSTRUMENTS to 'pfs_user_3'@localhost +grant ALL on performance_schema.setup_instruments to 'pfs_user_3'@localhost with GRANT OPTION; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -grant CREATE on performance_schema.SETUP_INSTRUMENTS to 'pfs_user_3'@localhost; -grant DROP on performance_schema.SETUP_INSTRUMENTS to 'pfs_user_3'@localhost; -grant REFERENCES on performance_schema.SETUP_INSTRUMENTS to 'pfs_user_3'@localhost; +grant CREATE on performance_schema.setup_instruments to 'pfs_user_3'@localhost; +grant DROP on performance_schema.setup_instruments to 'pfs_user_3'@localhost; +grant REFERENCES on performance_schema.setup_instruments to 'pfs_user_3'@localhost; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -grant INDEX on performance_schema.SETUP_INSTRUMENTS to 'pfs_user_3'@localhost; +grant INDEX on performance_schema.setup_instruments to 'pfs_user_3'@localhost; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -grant ALTER on performance_schema.SETUP_INSTRUMENTS to 'pfs_user_3'@localhost; +grant ALTER on performance_schema.setup_instruments to 'pfs_user_3'@localhost; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -grant CREATE VIEW on performance_schema.SETUP_INSTRUMENTS to 'pfs_user_3'@localhost; +grant CREATE VIEW on performance_schema.setup_instruments to 'pfs_user_3'@localhost; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -grant SHOW VIEW on performance_schema.SETUP_INSTRUMENTS to 'pfs_user_3'@localhost; +grant SHOW VIEW on performance_schema.setup_instruments to 'pfs_user_3'@localhost; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -grant TRIGGER on performance_schema.SETUP_INSTRUMENTS to 'pfs_user_3'@localhost; +grant TRIGGER on performance_schema.setup_instruments to 'pfs_user_3'@localhost; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -grant INSERT on performance_schema.SETUP_INSTRUMENTS to 'pfs_user_3'@localhost; -ERROR 42000: INSERT,GRANT command denied to user 'root'@'localhost' for table 'SETUP_INSTRUMENTS' -grant DELETE on performance_schema.SETUP_INSTRUMENTS to 'pfs_user_3'@localhost; -ERROR 42000: DELETE,GRANT command denied to user 'root'@'localhost' for table 'SETUP_INSTRUMENTS' -grant SELECT on performance_schema.SETUP_INSTRUMENTS to 'pfs_user_3'@localhost +grant INSERT on performance_schema.setup_instruments to 'pfs_user_3'@localhost; +ERROR 42000: INSERT,GRANT command denied to user 'root'@'localhost' for table 'setup_instruments' +grant DELETE on performance_schema.setup_instruments to 'pfs_user_3'@localhost; +ERROR 42000: DELETE,GRANT command denied to user 'root'@'localhost' for table 'setup_instruments' +grant SELECT on performance_schema.setup_instruments to 'pfs_user_3'@localhost with GRANT OPTION; -grant UPDATE on performance_schema.SETUP_INSTRUMENTS to 'pfs_user_3'@localhost +grant UPDATE on performance_schema.setup_instruments to 'pfs_user_3'@localhost with GRANT OPTION; -grant ALL on performance_schema.EVENTS_WAITS_CURRENT to 'pfs_user_3'@localhost +grant ALL on performance_schema.events_waits_current to 'pfs_user_3'@localhost with GRANT OPTION; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -grant CREATE on performance_schema.EVENTS_WAITS_CURRENT to 'pfs_user_3'@localhost; -grant DROP on performance_schema.EVENTS_WAITS_CURRENT to 'pfs_user_3'@localhost; -grant REFERENCES on performance_schema.EVENTS_WAITS_CURRENT to 'pfs_user_3'@localhost; +grant CREATE on performance_schema.events_waits_current to 'pfs_user_3'@localhost; +grant DROP on performance_schema.events_waits_current to 'pfs_user_3'@localhost; +grant REFERENCES on performance_schema.events_waits_current to 'pfs_user_3'@localhost; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -grant INDEX on performance_schema.EVENTS_WAITS_CURRENT to 'pfs_user_3'@localhost; +grant INDEX on performance_schema.events_waits_current to 'pfs_user_3'@localhost; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -grant ALTER on performance_schema.EVENTS_WAITS_CURRENT to 'pfs_user_3'@localhost; +grant ALTER on performance_schema.events_waits_current to 'pfs_user_3'@localhost; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -grant CREATE VIEW on performance_schema.EVENTS_WAITS_CURRENT to 'pfs_user_3'@localhost; +grant CREATE VIEW on performance_schema.events_waits_current to 'pfs_user_3'@localhost; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -grant SHOW VIEW on performance_schema.EVENTS_WAITS_CURRENT to 'pfs_user_3'@localhost; +grant SHOW VIEW on performance_schema.events_waits_current to 'pfs_user_3'@localhost; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -grant TRIGGER on performance_schema.EVENTS_WAITS_CURRENT to 'pfs_user_3'@localhost; +grant TRIGGER on performance_schema.events_waits_current to 'pfs_user_3'@localhost; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -grant INSERT on performance_schema.EVENTS_WAITS_CURRENT to 'pfs_user_3'@localhost; -ERROR 42000: INSERT,GRANT command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_CURRENT' -grant UPDATE on performance_schema.EVENTS_WAITS_CURRENT to 'pfs_user_3'@localhost; -ERROR 42000: UPDATE,GRANT command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_CURRENT' -grant DELETE on performance_schema.EVENTS_WAITS_CURRENT to 'pfs_user_3'@localhost; -ERROR 42000: DELETE,GRANT command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_CURRENT' -grant SELECT on performance_schema.EVENTS_WAITS_CURRENT to 'pfs_user_3'@localhost +grant INSERT on performance_schema.events_waits_current to 'pfs_user_3'@localhost; +ERROR 42000: INSERT,GRANT command denied to user 'root'@'localhost' for table 'events_waits_current' +grant UPDATE on performance_schema.events_waits_current to 'pfs_user_3'@localhost; +ERROR 42000: UPDATE,GRANT command denied to user 'root'@'localhost' for table 'events_waits_current' +grant DELETE on performance_schema.events_waits_current to 'pfs_user_3'@localhost; +ERROR 42000: DELETE,GRANT command denied to user 'root'@'localhost' for table 'events_waits_current' +grant SELECT on performance_schema.events_waits_current to 'pfs_user_3'@localhost with GRANT OPTION; -grant ALL on performance_schema.FILE_INSTANCES to 'pfs_user_3'@localhost +grant ALL on performance_schema.file_instances to 'pfs_user_3'@localhost with GRANT OPTION; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -grant CREATE on performance_schema.FILE_INSTANCES to 'pfs_user_3'@localhost; -grant DROP on performance_schema.FILE_INSTANCES to 'pfs_user_3'@localhost; -grant REFERENCES on performance_schema.FILE_INSTANCES to 'pfs_user_3'@localhost; +grant CREATE on performance_schema.file_instances to 'pfs_user_3'@localhost; +grant DROP on performance_schema.file_instances to 'pfs_user_3'@localhost; +grant REFERENCES on performance_schema.file_instances to 'pfs_user_3'@localhost; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -grant INDEX on performance_schema.FILE_INSTANCES to 'pfs_user_3'@localhost; +grant INDEX on performance_schema.file_instances to 'pfs_user_3'@localhost; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -grant ALTER on performance_schema.FILE_INSTANCES to 'pfs_user_3'@localhost; +grant ALTER on performance_schema.file_instances to 'pfs_user_3'@localhost; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -grant CREATE VIEW on performance_schema.FILE_INSTANCES to 'pfs_user_3'@localhost; +grant CREATE VIEW on performance_schema.file_instances to 'pfs_user_3'@localhost; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -grant SHOW VIEW on performance_schema.FILE_INSTANCES to 'pfs_user_3'@localhost; +grant SHOW VIEW on performance_schema.file_instances to 'pfs_user_3'@localhost; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -grant TRIGGER on performance_schema.FILE_INSTANCES to 'pfs_user_3'@localhost; +grant TRIGGER on performance_schema.file_instances to 'pfs_user_3'@localhost; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -grant INSERT on performance_schema.FILE_INSTANCES to 'pfs_user_3'@localhost; -ERROR 42000: INSERT,GRANT command denied to user 'root'@'localhost' for table 'FILE_INSTANCES' -grant UPDATE on performance_schema.FILE_INSTANCES to 'pfs_user_3'@localhost; -ERROR 42000: UPDATE,GRANT command denied to user 'root'@'localhost' for table 'FILE_INSTANCES' -grant DELETE on performance_schema.FILE_INSTANCES to 'pfs_user_3'@localhost; -ERROR 42000: DELETE,GRANT command denied to user 'root'@'localhost' for table 'FILE_INSTANCES' -grant SELECT on performance_schema.FILE_INSTANCES to 'pfs_user_3'@localhost +grant INSERT on performance_schema.file_instances to 'pfs_user_3'@localhost; +ERROR 42000: INSERT,GRANT command denied to user 'root'@'localhost' for table 'file_instances' +grant UPDATE on performance_schema.file_instances to 'pfs_user_3'@localhost; +ERROR 42000: UPDATE,GRANT command denied to user 'root'@'localhost' for table 'file_instances' +grant DELETE on performance_schema.file_instances to 'pfs_user_3'@localhost; +ERROR 42000: DELETE,GRANT command denied to user 'root'@'localhost' for table 'file_instances' +grant SELECT on performance_schema.file_instances to 'pfs_user_3'@localhost with GRANT OPTION; grant LOCK TABLES on performance_schema.* to 'pfs_user_3'@localhost with GRANT OPTION; flush privileges; drop table if exists test.t1; -rename table performance_schema.SETUP_INSTRUMENTS to test.t1; +rename table performance_schema.setup_instruments to test.t1; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -rename table performance_schema.EVENTS_WAITS_CURRENT to test.t1; +rename table performance_schema.events_waits_current to test.t1; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -rename table performance_schema.FILE_INSTANCES to test.t1; +rename table performance_schema.file_instances to test.t1; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -rename table performance_schema.SETUP_INSTRUMENTS to performance_schema.t1; +rename table performance_schema.setup_instruments to performance_schema.t1; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -rename table performance_schema.EVENTS_WAITS_CURRENT to performance_schema.t1; +rename table performance_schema.events_waits_current to performance_schema.t1; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -rename table performance_schema.FILE_INSTANCES to performance_schema.t1; +rename table performance_schema.file_instances to performance_schema.t1; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -rename table performance_schema.SETUP_INSTRUMENTS -to performance_schema.EVENTS_WAITS_CURRENT; +rename table performance_schema.setup_instruments +to performance_schema.events_waits_current; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' -rename table performance_schema.EVENTS_WAITS_CURRENT -to performance_schema.SETUP_INSTRUMENTS; +rename table performance_schema.events_waits_current +to performance_schema.setup_instruments; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' create procedure performance_schema.my_proc() begin end; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' @@ -140,95 +140,95 @@ create event performance_schema.my_event on schedule every 15 minute do begin end; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' create trigger performance_schema.bi_setup_instruments -before insert on performance_schema.SETUP_INSTRUMENTS +before insert on performance_schema.setup_instruments for each row begin end; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' create trigger performance_schema.bi_events_waits_current -before insert on performance_schema.EVENTS_WAITS_CURRENT +before insert on performance_schema.events_waits_current for each row begin end; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' create trigger performance_schema.bi_file_instances -before insert on performance_schema.FILE_INSTANCES +before insert on performance_schema.file_instances for each row begin end; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' create table test.t1(a int) engine=PERFORMANCE_SCHEMA; ERROR HY000: Invalid performance_schema usage. -create table test.t1 like performance_schema.SETUP_INSTRUMENTS; +create table test.t1 like performance_schema.setup_instruments; ERROR HY000: Invalid performance_schema usage. -create table test.t1 like performance_schema.EVENTS_WAITS_CURRENT; +create table test.t1 like performance_schema.events_waits_current; ERROR HY000: Invalid performance_schema usage. -create table test.t1 like performance_schema.FILE_INSTANCES; +create table test.t1 like performance_schema.file_instances; ERROR HY000: Invalid performance_schema usage. -insert into performance_schema.SETUP_INSTRUMENTS +insert into performance_schema.setup_instruments set name="foo"; -ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'SETUP_INSTRUMENTS' -insert into performance_schema.EVENTS_WAITS_CURRENT +ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'setup_instruments' +insert into performance_schema.events_waits_current set name="foo"; -ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_CURRENT' -insert into performance_schema.FILE_INSTANCES +ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'events_waits_current' +insert into performance_schema.file_instances set name="foo"; -ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'FILE_INSTANCES' -delete from performance_schema.SETUP_INSTRUMENTS; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'SETUP_INSTRUMENTS' -delete from performance_schema.EVENTS_WAITS_CURRENT; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_CURRENT' -delete from performance_schema.FILE_INSTANCES; -ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'FILE_INSTANCES' -lock table performance_schema.SETUP_INSTRUMENTS read; +ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'file_instances' +delete from performance_schema.setup_instruments; +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'setup_instruments' +delete from performance_schema.events_waits_current; +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'events_waits_current' +delete from performance_schema.file_instances; +ERROR 42000: DELETE command denied to user 'root'@'localhost' for table 'file_instances' +lock table performance_schema.setup_instruments read; unlock tables; -lock table performance_schema.SETUP_INSTRUMENTS write; +lock table performance_schema.setup_instruments write; unlock tables; -lock table performance_schema.EVENTS_WAITS_CURRENT read; -ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_CURRENT' +lock table performance_schema.events_waits_current read; +ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'events_waits_current' unlock tables; -lock table performance_schema.EVENTS_WAITS_CURRENT write; -ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'EVENTS_WAITS_CURRENT' +lock table performance_schema.events_waits_current write; +ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'events_waits_current' unlock tables; -lock table performance_schema.FILE_INSTANCES read; -ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'FILE_INSTANCES' +lock table performance_schema.file_instances read; +ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'file_instances' unlock tables; -lock table performance_schema.FILE_INSTANCES write; -ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'FILE_INSTANCES' +lock table performance_schema.file_instances write; +ERROR 42000: SELECT,LOCK TABL command denied to user 'root'@'localhost' for table 'file_instances' unlock tables; # # WL#4818, NFS2: Can use grants to give normal user access -# to view data from _CURRENT and _HISTORY tables +# to view data from _current and _history tables # # Should work as pfs_user_1 and pfs_user_2, but not as pfs_user_3. -# (Except for EVENTS_WAITS_CURRENT, which is granted.) -SELECT "can select" FROM performance_schema.EVENTS_WAITS_HISTORY LIMIT 1; +# (Except for events_waits_current, which is granted.) +SELECT "can select" FROM performance_schema.events_waits_history LIMIT 1; can select can select -SELECT "can select" FROM performance_schema.EVENTS_WAITS_HISTORY_LONG LIMIT 1; +SELECT "can select" FROM performance_schema.events_waits_history_long LIMIT 1; can select can select -SELECT "can select" FROM performance_schema.EVENTS_WAITS_CURRENT LIMIT 1; +SELECT "can select" FROM performance_schema.events_waits_current LIMIT 1; can select can select -SELECT "can select" FROM performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE LIMIT 1; +SELECT "can select" FROM performance_schema.events_waits_summary_by_instance LIMIT 1; can select can select -SELECT "can select" FROM performance_schema.FILE_SUMMARY_BY_INSTANCE LIMIT 1; +SELECT "can select" FROM performance_schema.file_summary_by_instance LIMIT 1; can select can select drop table if exists test.t1; -rename table performance_schema.SETUP_INSTRUMENTS to test.t1; +rename table performance_schema.setup_instruments to test.t1; ERROR 42000: Access denied for user 'pfs_user_1'@'localhost' to database 'performance_schema' -rename table performance_schema.EVENTS_WAITS_CURRENT to test.t1; +rename table performance_schema.events_waits_current to test.t1; ERROR 42000: Access denied for user 'pfs_user_1'@'localhost' to database 'performance_schema' -rename table performance_schema.FILE_INSTANCES to test.t1; +rename table performance_schema.file_instances to test.t1; ERROR 42000: Access denied for user 'pfs_user_1'@'localhost' to database 'performance_schema' -rename table performance_schema.SETUP_INSTRUMENTS to performance_schema.t1; +rename table performance_schema.setup_instruments to performance_schema.t1; ERROR 42000: Access denied for user 'pfs_user_1'@'localhost' to database 'performance_schema' -rename table performance_schema.EVENTS_WAITS_CURRENT to performance_schema.t1; +rename table performance_schema.events_waits_current to performance_schema.t1; ERROR 42000: Access denied for user 'pfs_user_1'@'localhost' to database 'performance_schema' -rename table performance_schema.FILE_INSTANCES to performance_schema.t1; +rename table performance_schema.file_instances to performance_schema.t1; ERROR 42000: Access denied for user 'pfs_user_1'@'localhost' to database 'performance_schema' -rename table performance_schema.SETUP_INSTRUMENTS -to performance_schema.EVENTS_WAITS_CURRENT; +rename table performance_schema.setup_instruments +to performance_schema.events_waits_current; ERROR 42000: Access denied for user 'pfs_user_1'@'localhost' to database 'performance_schema' -rename table performance_schema.EVENTS_WAITS_CURRENT -to performance_schema.SETUP_INSTRUMENTS; +rename table performance_schema.events_waits_current +to performance_schema.setup_instruments; ERROR 42000: Access denied for user 'pfs_user_1'@'localhost' to database 'performance_schema' create procedure performance_schema.my_proc() begin end; ERROR 42000: Access denied for user 'pfs_user_1'@'localhost' to database 'performance_schema' @@ -238,95 +238,95 @@ create event performance_schema.my_event on schedule every 15 minute do begin end; ERROR 42000: Access denied for user 'pfs_user_1'@'localhost' to database 'performance_schema' create trigger performance_schema.bi_setup_instruments -before insert on performance_schema.SETUP_INSTRUMENTS +before insert on performance_schema.setup_instruments for each row begin end; ERROR 42000: Access denied for user 'pfs_user_1'@'localhost' to database 'performance_schema' create trigger performance_schema.bi_events_waits_current -before insert on performance_schema.EVENTS_WAITS_CURRENT +before insert on performance_schema.events_waits_current for each row begin end; ERROR 42000: Access denied for user 'pfs_user_1'@'localhost' to database 'performance_schema' create trigger performance_schema.bi_file_instances -before insert on performance_schema.FILE_INSTANCES +before insert on performance_schema.file_instances for each row begin end; ERROR 42000: Access denied for user 'pfs_user_1'@'localhost' to database 'performance_schema' create table test.t1(a int) engine=PERFORMANCE_SCHEMA; ERROR HY000: Invalid performance_schema usage. -create table test.t1 like performance_schema.SETUP_INSTRUMENTS; +create table test.t1 like performance_schema.setup_instruments; ERROR HY000: Invalid performance_schema usage. -create table test.t1 like performance_schema.EVENTS_WAITS_CURRENT; +create table test.t1 like performance_schema.events_waits_current; ERROR HY000: Invalid performance_schema usage. -create table test.t1 like performance_schema.FILE_INSTANCES; +create table test.t1 like performance_schema.file_instances; ERROR HY000: Invalid performance_schema usage. -insert into performance_schema.SETUP_INSTRUMENTS +insert into performance_schema.setup_instruments set name="foo"; -ERROR 42000: INSERT command denied to user 'pfs_user_1'@'localhost' for table 'SETUP_INSTRUMENTS' -insert into performance_schema.EVENTS_WAITS_CURRENT +ERROR 42000: INSERT command denied to user 'pfs_user_1'@'localhost' for table 'setup_instruments' +insert into performance_schema.events_waits_current set name="foo"; -ERROR 42000: INSERT command denied to user 'pfs_user_1'@'localhost' for table 'EVENTS_WAITS_CURRENT' -insert into performance_schema.FILE_INSTANCES +ERROR 42000: INSERT command denied to user 'pfs_user_1'@'localhost' for table 'events_waits_current' +insert into performance_schema.file_instances set name="foo"; -ERROR 42000: INSERT command denied to user 'pfs_user_1'@'localhost' for table 'FILE_INSTANCES' -delete from performance_schema.SETUP_INSTRUMENTS; -ERROR 42000: DELETE command denied to user 'pfs_user_1'@'localhost' for table 'SETUP_INSTRUMENTS' -delete from performance_schema.EVENTS_WAITS_CURRENT; -ERROR 42000: DELETE command denied to user 'pfs_user_1'@'localhost' for table 'EVENTS_WAITS_CURRENT' -delete from performance_schema.FILE_INSTANCES; -ERROR 42000: DELETE command denied to user 'pfs_user_1'@'localhost' for table 'FILE_INSTANCES' -lock table performance_schema.SETUP_INSTRUMENTS read; +ERROR 42000: INSERT command denied to user 'pfs_user_1'@'localhost' for table 'file_instances' +delete from performance_schema.setup_instruments; +ERROR 42000: DELETE command denied to user 'pfs_user_1'@'localhost' for table 'setup_instruments' +delete from performance_schema.events_waits_current; +ERROR 42000: DELETE command denied to user 'pfs_user_1'@'localhost' for table 'events_waits_current' +delete from performance_schema.file_instances; +ERROR 42000: DELETE command denied to user 'pfs_user_1'@'localhost' for table 'file_instances' +lock table performance_schema.setup_instruments read; unlock tables; -lock table performance_schema.SETUP_INSTRUMENTS write; +lock table performance_schema.setup_instruments write; unlock tables; -lock table performance_schema.EVENTS_WAITS_CURRENT read; -ERROR 42000: SELECT,LOCK TABL command denied to user 'pfs_user_1'@'localhost' for table 'EVENTS_WAITS_CURRENT' +lock table performance_schema.events_waits_current read; +ERROR 42000: SELECT,LOCK TABL command denied to user 'pfs_user_1'@'localhost' for table 'events_waits_current' unlock tables; -lock table performance_schema.EVENTS_WAITS_CURRENT write; -ERROR 42000: SELECT,LOCK TABL command denied to user 'pfs_user_1'@'localhost' for table 'EVENTS_WAITS_CURRENT' +lock table performance_schema.events_waits_current write; +ERROR 42000: SELECT,LOCK TABL command denied to user 'pfs_user_1'@'localhost' for table 'events_waits_current' unlock tables; -lock table performance_schema.FILE_INSTANCES read; -ERROR 42000: SELECT,LOCK TABL command denied to user 'pfs_user_1'@'localhost' for table 'FILE_INSTANCES' +lock table performance_schema.file_instances read; +ERROR 42000: SELECT,LOCK TABL command denied to user 'pfs_user_1'@'localhost' for table 'file_instances' unlock tables; -lock table performance_schema.FILE_INSTANCES write; -ERROR 42000: SELECT,LOCK TABL command denied to user 'pfs_user_1'@'localhost' for table 'FILE_INSTANCES' +lock table performance_schema.file_instances write; +ERROR 42000: SELECT,LOCK TABL command denied to user 'pfs_user_1'@'localhost' for table 'file_instances' unlock tables; # # WL#4818, NFS2: Can use grants to give normal user access -# to view data from _CURRENT and _HISTORY tables +# to view data from _current and _history tables # # Should work as pfs_user_1 and pfs_user_2, but not as pfs_user_3. -# (Except for EVENTS_WAITS_CURRENT, which is granted.) -SELECT "can select" FROM performance_schema.EVENTS_WAITS_HISTORY LIMIT 1; +# (Except for events_waits_current, which is granted.) +SELECT "can select" FROM performance_schema.events_waits_history LIMIT 1; can select can select -SELECT "can select" FROM performance_schema.EVENTS_WAITS_HISTORY_LONG LIMIT 1; +SELECT "can select" FROM performance_schema.events_waits_history_long LIMIT 1; can select can select -SELECT "can select" FROM performance_schema.EVENTS_WAITS_CURRENT LIMIT 1; +SELECT "can select" FROM performance_schema.events_waits_current LIMIT 1; can select can select -SELECT "can select" FROM performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE LIMIT 1; +SELECT "can select" FROM performance_schema.events_waits_summary_by_instance LIMIT 1; can select can select -SELECT "can select" FROM performance_schema.FILE_SUMMARY_BY_INSTANCE LIMIT 1; +SELECT "can select" FROM performance_schema.file_summary_by_instance LIMIT 1; can select can select drop table if exists test.t1; -rename table performance_schema.SETUP_INSTRUMENTS to test.t1; +rename table performance_schema.setup_instruments to test.t1; ERROR 42000: Access denied for user 'pfs_user_2'@'localhost' to database 'performance_schema' -rename table performance_schema.EVENTS_WAITS_CURRENT to test.t1; +rename table performance_schema.events_waits_current to test.t1; ERROR 42000: Access denied for user 'pfs_user_2'@'localhost' to database 'performance_schema' -rename table performance_schema.FILE_INSTANCES to test.t1; +rename table performance_schema.file_instances to test.t1; ERROR 42000: Access denied for user 'pfs_user_2'@'localhost' to database 'performance_schema' -rename table performance_schema.SETUP_INSTRUMENTS to performance_schema.t1; +rename table performance_schema.setup_instruments to performance_schema.t1; ERROR 42000: Access denied for user 'pfs_user_2'@'localhost' to database 'performance_schema' -rename table performance_schema.EVENTS_WAITS_CURRENT to performance_schema.t1; +rename table performance_schema.events_waits_current to performance_schema.t1; ERROR 42000: Access denied for user 'pfs_user_2'@'localhost' to database 'performance_schema' -rename table performance_schema.FILE_INSTANCES to performance_schema.t1; +rename table performance_schema.file_instances to performance_schema.t1; ERROR 42000: Access denied for user 'pfs_user_2'@'localhost' to database 'performance_schema' -rename table performance_schema.SETUP_INSTRUMENTS -to performance_schema.EVENTS_WAITS_CURRENT; +rename table performance_schema.setup_instruments +to performance_schema.events_waits_current; ERROR 42000: Access denied for user 'pfs_user_2'@'localhost' to database 'performance_schema' -rename table performance_schema.EVENTS_WAITS_CURRENT -to performance_schema.SETUP_INSTRUMENTS; +rename table performance_schema.events_waits_current +to performance_schema.setup_instruments; ERROR 42000: Access denied for user 'pfs_user_2'@'localhost' to database 'performance_schema' create procedure performance_schema.my_proc() begin end; ERROR 42000: Access denied for user 'pfs_user_2'@'localhost' to database 'performance_schema' @@ -336,95 +336,95 @@ create event performance_schema.my_event on schedule every 15 minute do begin end; ERROR 42000: Access denied for user 'pfs_user_2'@'localhost' to database 'performance_schema' create trigger performance_schema.bi_setup_instruments -before insert on performance_schema.SETUP_INSTRUMENTS +before insert on performance_schema.setup_instruments for each row begin end; ERROR 42000: Access denied for user 'pfs_user_2'@'localhost' to database 'performance_schema' create trigger performance_schema.bi_events_waits_current -before insert on performance_schema.EVENTS_WAITS_CURRENT +before insert on performance_schema.events_waits_current for each row begin end; ERROR 42000: Access denied for user 'pfs_user_2'@'localhost' to database 'performance_schema' create trigger performance_schema.bi_file_instances -before insert on performance_schema.FILE_INSTANCES +before insert on performance_schema.file_instances for each row begin end; ERROR 42000: Access denied for user 'pfs_user_2'@'localhost' to database 'performance_schema' create table test.t1(a int) engine=PERFORMANCE_SCHEMA; ERROR HY000: Invalid performance_schema usage. -create table test.t1 like performance_schema.SETUP_INSTRUMENTS; +create table test.t1 like performance_schema.setup_instruments; ERROR HY000: Invalid performance_schema usage. -create table test.t1 like performance_schema.EVENTS_WAITS_CURRENT; +create table test.t1 like performance_schema.events_waits_current; ERROR HY000: Invalid performance_schema usage. -create table test.t1 like performance_schema.FILE_INSTANCES; +create table test.t1 like performance_schema.file_instances; ERROR HY000: Invalid performance_schema usage. -insert into performance_schema.SETUP_INSTRUMENTS +insert into performance_schema.setup_instruments set name="foo"; -ERROR 42000: INSERT command denied to user 'pfs_user_2'@'localhost' for table 'SETUP_INSTRUMENTS' -insert into performance_schema.EVENTS_WAITS_CURRENT +ERROR 42000: INSERT command denied to user 'pfs_user_2'@'localhost' for table 'setup_instruments' +insert into performance_schema.events_waits_current set name="foo"; -ERROR 42000: INSERT command denied to user 'pfs_user_2'@'localhost' for table 'EVENTS_WAITS_CURRENT' -insert into performance_schema.FILE_INSTANCES +ERROR 42000: INSERT command denied to user 'pfs_user_2'@'localhost' for table 'events_waits_current' +insert into performance_schema.file_instances set name="foo"; -ERROR 42000: INSERT command denied to user 'pfs_user_2'@'localhost' for table 'FILE_INSTANCES' -delete from performance_schema.SETUP_INSTRUMENTS; -ERROR 42000: DELETE command denied to user 'pfs_user_2'@'localhost' for table 'SETUP_INSTRUMENTS' -delete from performance_schema.EVENTS_WAITS_CURRENT; -ERROR 42000: DELETE command denied to user 'pfs_user_2'@'localhost' for table 'EVENTS_WAITS_CURRENT' -delete from performance_schema.FILE_INSTANCES; -ERROR 42000: DELETE command denied to user 'pfs_user_2'@'localhost' for table 'FILE_INSTANCES' -lock table performance_schema.SETUP_INSTRUMENTS read; +ERROR 42000: INSERT command denied to user 'pfs_user_2'@'localhost' for table 'file_instances' +delete from performance_schema.setup_instruments; +ERROR 42000: DELETE command denied to user 'pfs_user_2'@'localhost' for table 'setup_instruments' +delete from performance_schema.events_waits_current; +ERROR 42000: DELETE command denied to user 'pfs_user_2'@'localhost' for table 'events_waits_current' +delete from performance_schema.file_instances; +ERROR 42000: DELETE command denied to user 'pfs_user_2'@'localhost' for table 'file_instances' +lock table performance_schema.setup_instruments read; unlock tables; -lock table performance_schema.SETUP_INSTRUMENTS write; +lock table performance_schema.setup_instruments write; unlock tables; -lock table performance_schema.EVENTS_WAITS_CURRENT read; -ERROR 42000: SELECT,LOCK TABL command denied to user 'pfs_user_2'@'localhost' for table 'EVENTS_WAITS_CURRENT' +lock table performance_schema.events_waits_current read; +ERROR 42000: SELECT,LOCK TABL command denied to user 'pfs_user_2'@'localhost' for table 'events_waits_current' unlock tables; -lock table performance_schema.EVENTS_WAITS_CURRENT write; -ERROR 42000: SELECT,LOCK TABL command denied to user 'pfs_user_2'@'localhost' for table 'EVENTS_WAITS_CURRENT' +lock table performance_schema.events_waits_current write; +ERROR 42000: SELECT,LOCK TABL command denied to user 'pfs_user_2'@'localhost' for table 'events_waits_current' unlock tables; -lock table performance_schema.FILE_INSTANCES read; -ERROR 42000: SELECT,LOCK TABL command denied to user 'pfs_user_2'@'localhost' for table 'FILE_INSTANCES' +lock table performance_schema.file_instances read; +ERROR 42000: SELECT,LOCK TABL command denied to user 'pfs_user_2'@'localhost' for table 'file_instances' unlock tables; -lock table performance_schema.FILE_INSTANCES write; -ERROR 42000: SELECT,LOCK TABL command denied to user 'pfs_user_2'@'localhost' for table 'FILE_INSTANCES' +lock table performance_schema.file_instances write; +ERROR 42000: SELECT,LOCK TABL command denied to user 'pfs_user_2'@'localhost' for table 'file_instances' unlock tables; # # WL#4818, NFS2: Can use grants to give normal user access -# to view data from _CURRENT and _HISTORY tables +# to view data from _current and _history tables # # Should work as pfs_user_1 and pfs_user_2, but not as pfs_user_3. -# (Except for EVENTS_WAITS_CURRENT, which is granted.) -SELECT "can select" FROM performance_schema.EVENTS_WAITS_HISTORY LIMIT 1; +# (Except for events_waits_current, which is granted.) +SELECT "can select" FROM performance_schema.events_waits_history LIMIT 1; can select can select -SELECT "can select" FROM performance_schema.EVENTS_WAITS_HISTORY_LONG LIMIT 1; +SELECT "can select" FROM performance_schema.events_waits_history_long LIMIT 1; can select can select -SELECT "can select" FROM performance_schema.EVENTS_WAITS_CURRENT LIMIT 1; +SELECT "can select" FROM performance_schema.events_waits_current LIMIT 1; can select can select -SELECT "can select" FROM performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE LIMIT 1; +SELECT "can select" FROM performance_schema.events_waits_summary_by_instance LIMIT 1; can select can select -SELECT "can select" FROM performance_schema.FILE_SUMMARY_BY_INSTANCE LIMIT 1; +SELECT "can select" FROM performance_schema.file_summary_by_instance LIMIT 1; can select can select drop table if exists test.t1; -rename table performance_schema.SETUP_INSTRUMENTS to test.t1; +rename table performance_schema.setup_instruments to test.t1; ERROR 42000: Access denied for user 'pfs_user_3'@'localhost' to database 'performance_schema' -rename table performance_schema.EVENTS_WAITS_CURRENT to test.t1; +rename table performance_schema.events_waits_current to test.t1; ERROR 42000: Access denied for user 'pfs_user_3'@'localhost' to database 'performance_schema' -rename table performance_schema.FILE_INSTANCES to test.t1; +rename table performance_schema.file_instances to test.t1; ERROR 42000: Access denied for user 'pfs_user_3'@'localhost' to database 'performance_schema' -rename table performance_schema.SETUP_INSTRUMENTS to performance_schema.t1; +rename table performance_schema.setup_instruments to performance_schema.t1; ERROR 42000: Access denied for user 'pfs_user_3'@'localhost' to database 'performance_schema' -rename table performance_schema.EVENTS_WAITS_CURRENT to performance_schema.t1; +rename table performance_schema.events_waits_current to performance_schema.t1; ERROR 42000: Access denied for user 'pfs_user_3'@'localhost' to database 'performance_schema' -rename table performance_schema.FILE_INSTANCES to performance_schema.t1; +rename table performance_schema.file_instances to performance_schema.t1; ERROR 42000: Access denied for user 'pfs_user_3'@'localhost' to database 'performance_schema' -rename table performance_schema.SETUP_INSTRUMENTS -to performance_schema.EVENTS_WAITS_CURRENT; +rename table performance_schema.setup_instruments +to performance_schema.events_waits_current; ERROR 42000: Access denied for user 'pfs_user_3'@'localhost' to database 'performance_schema' -rename table performance_schema.EVENTS_WAITS_CURRENT -to performance_schema.SETUP_INSTRUMENTS; +rename table performance_schema.events_waits_current +to performance_schema.setup_instruments; ERROR 42000: Access denied for user 'pfs_user_3'@'localhost' to database 'performance_schema' create procedure performance_schema.my_proc() begin end; ERROR 42000: Access denied for user 'pfs_user_3'@'localhost' to database 'performance_schema' @@ -434,73 +434,73 @@ create event performance_schema.my_event on schedule every 15 minute do begin end; ERROR 42000: Access denied for user 'pfs_user_3'@'localhost' to database 'performance_schema' create trigger performance_schema.bi_setup_instruments -before insert on performance_schema.SETUP_INSTRUMENTS +before insert on performance_schema.setup_instruments for each row begin end; ERROR 42000: Access denied for user 'pfs_user_3'@'localhost' to database 'performance_schema' create trigger performance_schema.bi_events_waits_current -before insert on performance_schema.EVENTS_WAITS_CURRENT +before insert on performance_schema.events_waits_current for each row begin end; ERROR 42000: Access denied for user 'pfs_user_3'@'localhost' to database 'performance_schema' create trigger performance_schema.bi_file_instances -before insert on performance_schema.FILE_INSTANCES +before insert on performance_schema.file_instances for each row begin end; ERROR 42000: Access denied for user 'pfs_user_3'@'localhost' to database 'performance_schema' create table test.t1(a int) engine=PERFORMANCE_SCHEMA; ERROR HY000: Invalid performance_schema usage. -create table test.t1 like performance_schema.SETUP_INSTRUMENTS; +create table test.t1 like performance_schema.setup_instruments; ERROR HY000: Invalid performance_schema usage. -create table test.t1 like performance_schema.EVENTS_WAITS_CURRENT; +create table test.t1 like performance_schema.events_waits_current; ERROR HY000: Invalid performance_schema usage. -create table test.t1 like performance_schema.FILE_INSTANCES; +create table test.t1 like performance_schema.file_instances; ERROR HY000: Invalid performance_schema usage. -insert into performance_schema.SETUP_INSTRUMENTS +insert into performance_schema.setup_instruments set name="foo"; -ERROR 42000: INSERT command denied to user 'pfs_user_3'@'localhost' for table 'SETUP_INSTRUMENTS' -insert into performance_schema.EVENTS_WAITS_CURRENT +ERROR 42000: INSERT command denied to user 'pfs_user_3'@'localhost' for table 'setup_instruments' +insert into performance_schema.events_waits_current set name="foo"; -ERROR 42000: INSERT command denied to user 'pfs_user_3'@'localhost' for table 'EVENTS_WAITS_CURRENT' -insert into performance_schema.FILE_INSTANCES +ERROR 42000: INSERT command denied to user 'pfs_user_3'@'localhost' for table 'events_waits_current' +insert into performance_schema.file_instances set name="foo"; -ERROR 42000: INSERT command denied to user 'pfs_user_3'@'localhost' for table 'FILE_INSTANCES' -delete from performance_schema.SETUP_INSTRUMENTS; -ERROR 42000: DELETE command denied to user 'pfs_user_3'@'localhost' for table 'SETUP_INSTRUMENTS' -delete from performance_schema.EVENTS_WAITS_CURRENT; -ERROR 42000: DELETE command denied to user 'pfs_user_3'@'localhost' for table 'EVENTS_WAITS_CURRENT' -delete from performance_schema.FILE_INSTANCES; -ERROR 42000: DELETE command denied to user 'pfs_user_3'@'localhost' for table 'FILE_INSTANCES' -lock table performance_schema.SETUP_INSTRUMENTS read; +ERROR 42000: INSERT command denied to user 'pfs_user_3'@'localhost' for table 'file_instances' +delete from performance_schema.setup_instruments; +ERROR 42000: DELETE command denied to user 'pfs_user_3'@'localhost' for table 'setup_instruments' +delete from performance_schema.events_waits_current; +ERROR 42000: DELETE command denied to user 'pfs_user_3'@'localhost' for table 'events_waits_current' +delete from performance_schema.file_instances; +ERROR 42000: DELETE command denied to user 'pfs_user_3'@'localhost' for table 'file_instances' +lock table performance_schema.setup_instruments read; unlock tables; -lock table performance_schema.SETUP_INSTRUMENTS write; +lock table performance_schema.setup_instruments write; unlock tables; -lock table performance_schema.EVENTS_WAITS_CURRENT read; -ERROR 42000: SELECT,LOCK TABL command denied to user 'pfs_user_3'@'localhost' for table 'EVENTS_WAITS_CURRENT' +lock table performance_schema.events_waits_current read; +ERROR 42000: SELECT,LOCK TABL command denied to user 'pfs_user_3'@'localhost' for table 'events_waits_current' unlock tables; -lock table performance_schema.EVENTS_WAITS_CURRENT write; -ERROR 42000: SELECT,LOCK TABL command denied to user 'pfs_user_3'@'localhost' for table 'EVENTS_WAITS_CURRENT' +lock table performance_schema.events_waits_current write; +ERROR 42000: SELECT,LOCK TABL command denied to user 'pfs_user_3'@'localhost' for table 'events_waits_current' unlock tables; -lock table performance_schema.FILE_INSTANCES read; -ERROR 42000: SELECT,LOCK TABL command denied to user 'pfs_user_3'@'localhost' for table 'FILE_INSTANCES' +lock table performance_schema.file_instances read; +ERROR 42000: SELECT,LOCK TABL command denied to user 'pfs_user_3'@'localhost' for table 'file_instances' unlock tables; -lock table performance_schema.FILE_INSTANCES write; -ERROR 42000: SELECT,LOCK TABL command denied to user 'pfs_user_3'@'localhost' for table 'FILE_INSTANCES' +lock table performance_schema.file_instances write; +ERROR 42000: SELECT,LOCK TABL command denied to user 'pfs_user_3'@'localhost' for table 'file_instances' unlock tables; # # WL#4818, NFS2: Can use grants to give normal user access -# to view data from _CURRENT and _HISTORY tables +# to view data from _current and _history tables # # Should work as pfs_user_1 and pfs_user_2, but not as pfs_user_3. -# (Except for EVENTS_WAITS_CURRENT, which is granted.) -SELECT "can select" FROM performance_schema.EVENTS_WAITS_HISTORY LIMIT 1; -ERROR 42000: SELECT command denied to user 'pfs_user_3'@'localhost' for table 'EVENTS_WAITS_HISTORY' -SELECT "can select" FROM performance_schema.EVENTS_WAITS_HISTORY_LONG LIMIT 1; -ERROR 42000: SELECT command denied to user 'pfs_user_3'@'localhost' for table 'EVENTS_WAITS_HISTORY_LONG' -SELECT "can select" FROM performance_schema.EVENTS_WAITS_CURRENT LIMIT 1; +# (Except for events_waits_current, which is granted.) +SELECT "can select" FROM performance_schema.events_waits_history LIMIT 1; +ERROR 42000: SELECT command denied to user 'pfs_user_3'@'localhost' for table 'events_waits_history' +SELECT "can select" FROM performance_schema.events_waits_history_long LIMIT 1; +ERROR 42000: SELECT command denied to user 'pfs_user_3'@'localhost' for table 'events_waits_history_long' +SELECT "can select" FROM performance_schema.events_waits_current LIMIT 1; can select can select -SELECT "can select" FROM performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE LIMIT 1; -ERROR 42000: SELECT command denied to user 'pfs_user_3'@'localhost' for table 'EVENTS_WAITS_SUMMARY_BY_INSTANCE' -SELECT "can select" FROM performance_schema.FILE_SUMMARY_BY_INSTANCE LIMIT 1; -ERROR 42000: SELECT command denied to user 'pfs_user_3'@'localhost' for table 'FILE_SUMMARY_BY_INSTANCE' +SELECT "can select" FROM performance_schema.events_waits_summary_by_instance LIMIT 1; +ERROR 42000: SELECT command denied to user 'pfs_user_3'@'localhost' for table 'events_waits_summary_by_instance' +SELECT "can select" FROM performance_schema.file_summary_by_instance LIMIT 1; +ERROR 42000: SELECT command denied to user 'pfs_user_3'@'localhost' for table 'file_summary_by_instance' revoke all privileges, grant option from 'pfs_user_1'@localhost; revoke all privileges, grant option from 'pfs_user_2'@localhost; revoke all privileges, grant option from 'pfs_user_3'@localhost; @@ -516,63 +516,63 @@ CREATE user pfs_user_4; # without grants # # Select as pfs_user_4 should fail without grant -SELECT event_id FROM performance_schema.EVENTS_WAITS_HISTORY; -ERROR 42000: SELECT command denied to user 'pfs_user_4'@'localhost' for table 'EVENTS_WAITS_HISTORY' -SELECT event_id FROM performance_schema.EVENTS_WAITS_HISTORY_LONG; -ERROR 42000: SELECT command denied to user 'pfs_user_4'@'localhost' for table 'EVENTS_WAITS_HISTORY_LONG' -SELECT event_id FROM performance_schema.EVENTS_WAITS_CURRENT; -ERROR 42000: SELECT command denied to user 'pfs_user_4'@'localhost' for table 'EVENTS_WAITS_CURRENT' -SELECT event_name FROM performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE; -ERROR 42000: SELECT command denied to user 'pfs_user_4'@'localhost' for table 'EVENTS_WAITS_SUMMARY_BY_INSTANCE' -SELECT event_name FROM performance_schema.FILE_SUMMARY_BY_INSTANCE; -ERROR 42000: SELECT command denied to user 'pfs_user_4'@'localhost' for table 'FILE_SUMMARY_BY_INSTANCE' +SELECT event_id FROM performance_schema.events_waits_history; +ERROR 42000: SELECT command denied to user 'pfs_user_4'@'localhost' for table 'events_waits_history' +SELECT event_id FROM performance_schema.events_waits_history_long; +ERROR 42000: SELECT command denied to user 'pfs_user_4'@'localhost' for table 'events_waits_history_long' +SELECT event_id FROM performance_schema.events_waits_current; +ERROR 42000: SELECT command denied to user 'pfs_user_4'@'localhost' for table 'events_waits_current' +SELECT event_name FROM performance_schema.events_waits_summary_by_instance; +ERROR 42000: SELECT command denied to user 'pfs_user_4'@'localhost' for table 'events_waits_summary_by_instance' +SELECT event_name FROM performance_schema.file_summary_by_instance; +ERROR 42000: SELECT command denied to user 'pfs_user_4'@'localhost' for table 'file_summary_by_instance' # # WL#4818, NFS3: Normal user does not have access to change what is # instrumented without grants # # User pfs_user_4 should not be allowed to tweak instrumentation without # explicit grant -UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'NO', timed = 'YES'; -ERROR 42000: UPDATE command denied to user 'pfs_user_4'@'localhost' for table 'SETUP_INSTRUMENTS' -UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'YES' +UPDATE performance_schema.setup_instruments SET enabled = 'NO', timed = 'YES'; +ERROR 42000: UPDATE command denied to user 'pfs_user_4'@'localhost' for table 'setup_instruments' +UPDATE performance_schema.setup_instruments SET enabled = 'YES' WHERE name LIKE 'wait/synch/mutex/%' OR name LIKE 'wait/synch/rwlock/%'; -ERROR 42000: UPDATE command denied to user 'pfs_user_4'@'localhost' for table 'SETUP_INSTRUMENTS' -UPDATE performance_schema.SETUP_CONSUMERS SET enabled = 'YES'; -ERROR 42000: UPDATE command denied to user 'pfs_user_4'@'localhost' for table 'SETUP_CONSUMERS' -UPDATE performance_schema.SETUP_TIMERS SET timer_name = 'TICK'; -ERROR 42000: UPDATE command denied to user 'pfs_user_4'@'localhost' for table 'SETUP_TIMERS' -TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY_LONG; -ERROR 42000: DROP command denied to user 'pfs_user_4'@'localhost' for table 'EVENTS_WAITS_HISTORY_LONG' -TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY; -ERROR 42000: DROP command denied to user 'pfs_user_4'@'localhost' for table 'EVENTS_WAITS_HISTORY' -TRUNCATE TABLE performance_schema.EVENTS_WAITS_CURRENT; -ERROR 42000: DROP command denied to user 'pfs_user_4'@'localhost' for table 'EVENTS_WAITS_CURRENT' +ERROR 42000: UPDATE command denied to user 'pfs_user_4'@'localhost' for table 'setup_instruments' +UPDATE performance_schema.setup_consumers SET enabled = 'YES'; +ERROR 42000: UPDATE command denied to user 'pfs_user_4'@'localhost' for table 'setup_consumers' +UPDATE performance_schema.setup_timers SET timer_name = 'TICK'; +ERROR 42000: UPDATE command denied to user 'pfs_user_4'@'localhost' for table 'setup_timers' +TRUNCATE TABLE performance_schema.events_waits_history_long; +ERROR 42000: DROP command denied to user 'pfs_user_4'@'localhost' for table 'events_waits_history_long' +TRUNCATE TABLE performance_schema.events_waits_history; +ERROR 42000: DROP command denied to user 'pfs_user_4'@'localhost' for table 'events_waits_history' +TRUNCATE TABLE performance_schema.events_waits_current; +ERROR 42000: DROP command denied to user 'pfs_user_4'@'localhost' for table 'events_waits_current' # # WL#4814, NFS1: Can use grants to give normal user access # to turn on and off instrumentation # # Grant access to change tables with the root account -GRANT UPDATE ON performance_schema.SETUP_CONSUMERS TO pfs_user_4; -GRANT UPDATE ON performance_schema.SETUP_TIMERS TO pfs_user_4; -GRANT UPDATE, SELECT ON performance_schema.SETUP_INSTRUMENTS TO pfs_user_4; -GRANT DROP ON performance_schema.EVENTS_WAITS_CURRENT TO pfs_user_4; -GRANT DROP ON performance_schema.EVENTS_WAITS_HISTORY TO pfs_user_4; -GRANT DROP ON performance_schema.EVENTS_WAITS_HISTORY_LONG TO pfs_user_4; +GRANT UPDATE ON performance_schema.setup_consumers TO pfs_user_4; +GRANT UPDATE ON performance_schema.setup_timers TO pfs_user_4; +GRANT UPDATE, SELECT ON performance_schema.setup_instruments TO pfs_user_4; +GRANT DROP ON performance_schema.events_waits_current TO pfs_user_4; +GRANT DROP ON performance_schema.events_waits_history TO pfs_user_4; +GRANT DROP ON performance_schema.events_waits_history_long TO pfs_user_4; # User pfs_user_4 should now be allowed to tweak instrumentation -UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'NO', timed = 'YES'; -UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'YES' +UPDATE performance_schema.setup_instruments SET enabled = 'NO', timed = 'YES'; +UPDATE performance_schema.setup_instruments SET enabled = 'YES' WHERE name LIKE 'wait/synch/mutex/%' OR name LIKE 'wait/synch/rwlock/%'; -UPDATE performance_schema.SETUP_CONSUMERS SET enabled = 'YES'; -UPDATE performance_schema.SETUP_TIMERS SET timer_name = 'TICK'; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY_LONG; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_CURRENT; +UPDATE performance_schema.setup_consumers SET enabled = 'YES'; +UPDATE performance_schema.setup_timers SET timer_name = 'TICK'; +TRUNCATE TABLE performance_schema.events_waits_history_long; +TRUNCATE TABLE performance_schema.events_waits_history; +TRUNCATE TABLE performance_schema.events_waits_current; # Clean up REVOKE ALL PRIVILEGES, GRANT OPTION FROM pfs_user_4; DROP USER pfs_user_4; flush privileges; -UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'YES', timed = 'YES'; -UPDATE performance_schema.SETUP_CONSUMERS SET enabled = 'YES'; -UPDATE performance_schema.SETUP_TIMERS SET timer_name = 'CYCLE'; +UPDATE performance_schema.setup_instruments SET enabled = 'YES', timed = 'YES'; +UPDATE performance_schema.setup_consumers SET enabled = 'YES'; +UPDATE performance_schema.setup_timers SET timer_name = 'CYCLE'; diff --git a/mysql-test/suite/perfschema/r/query_cache.result b/mysql-test/suite/perfschema/r/query_cache.result index a0aeac5a916..c7ac3d499b4 100644 --- a/mysql-test/suite/perfschema/r/query_cache.result +++ b/mysql-test/suite/perfschema/r/query_cache.result @@ -33,10 +33,10 @@ Qcache_inserts 1 show status like "Qcache_hits"; Variable_name Value Qcache_hits 1 -select spins from performance_schema.EVENTS_WAITS_CURRENT order by event_name limit 1; +select spins from performance_schema.events_waits_current order by event_name limit 1; spins NULL -select name from performance_schema.SETUP_INSTRUMENTS order by name limit 1; +select name from performance_schema.setup_instruments order by name limit 1; name wait/io/file/csv/data show status like "Qcache_queries_in_cache"; @@ -48,10 +48,10 @@ Qcache_inserts 1 show status like "Qcache_hits"; Variable_name Value Qcache_hits 1 -select spins from performance_schema.EVENTS_WAITS_CURRENT order by event_name limit 1; +select spins from performance_schema.events_waits_current order by event_name limit 1; spins NULL -select name from performance_schema.SETUP_INSTRUMENTS order by name limit 1; +select name from performance_schema.setup_instruments order by name limit 1; name wait/io/file/csv/data show status like "Qcache_queries_in_cache"; diff --git a/mysql-test/suite/perfschema/r/read_only.result b/mysql-test/suite/perfschema/r/read_only.result index 6a30eb4ab8b..19108326f1b 100644 --- a/mysql-test/suite/perfschema/r/read_only.result +++ b/mysql-test/suite/perfschema/r/read_only.result @@ -13,9 +13,9 @@ show grants; Grants for pfsuser@localhost GRANT USAGE ON *.* TO 'pfsuser'@'localhost' GRANT SELECT, UPDATE ON `performance_schema`.* TO 'pfsuser'@'localhost' -select * from performance_schema.SETUP_INSTRUMENTS; -update performance_schema.SETUP_INSTRUMENTS set enabled='NO'; -update performance_schema.SETUP_INSTRUMENTS set enabled='YES'; +select * from performance_schema.setup_instruments; +update performance_schema.setup_instruments set enabled='NO'; +update performance_schema.setup_instruments set enabled='YES'; connection default; set global read_only=1; connection con1; @@ -26,9 +26,9 @@ show grants; Grants for pfsuser@localhost GRANT USAGE ON *.* TO 'pfsuser'@'localhost' GRANT SELECT, UPDATE ON `performance_schema`.* TO 'pfsuser'@'localhost' -select * from performance_schema.SETUP_INSTRUMENTS; -update performance_schema.SETUP_INSTRUMENTS set enabled='NO'; -update performance_schema.SETUP_INSTRUMENTS set enabled='YES'; +select * from performance_schema.setup_instruments; +update performance_schema.setup_instruments set enabled='NO'; +update performance_schema.setup_instruments set enabled='YES'; connection default; grant super on *.* to pfsuser@localhost; flush privileges; @@ -40,9 +40,9 @@ show grants; Grants for pfsuser@localhost GRANT SUPER ON *.* TO 'pfsuser'@'localhost' GRANT SELECT, UPDATE ON `performance_schema`.* TO 'pfsuser'@'localhost' -select * from performance_schema.SETUP_INSTRUMENTS; -update performance_schema.SETUP_INSTRUMENTS set enabled='NO'; -update performance_schema.SETUP_INSTRUMENTS set enabled='YES'; +select * from performance_schema.setup_instruments; +update performance_schema.setup_instruments set enabled='NO'; +update performance_schema.setup_instruments set enabled='YES'; connection default; set global read_only= @start_read_only; drop user pfsuser@localhost; diff --git a/mysql-test/suite/perfschema/r/schema.result b/mysql-test/suite/perfschema/r/schema.result index 1599d51a59f..5bafa137af5 100644 --- a/mysql-test/suite/perfschema/r/schema.result +++ b/mysql-test/suite/perfschema/r/schema.result @@ -8,32 +8,32 @@ test use performance_schema; show tables; Tables_in_performance_schema -COND_INSTANCES -EVENTS_WAITS_CURRENT -EVENTS_WAITS_HISTORY -EVENTS_WAITS_HISTORY_LONG -EVENTS_WAITS_SUMMARY_BY_INSTANCE -EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME -EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME -FILE_INSTANCES -FILE_SUMMARY_BY_EVENT_NAME -FILE_SUMMARY_BY_INSTANCE -MUTEX_INSTANCES -PERFORMANCE_TIMERS -RWLOCK_INSTANCES -SETUP_CONSUMERS -SETUP_INSTRUMENTS -SETUP_TIMERS -THREADS -show create table COND_INSTANCES; +cond_instances +events_waits_current +events_waits_history +events_waits_history_long +events_waits_summary_by_instance +events_waits_summary_by_thread_by_event_name +events_waits_summary_global_by_event_name +file_instances +file_summary_by_event_name +file_summary_by_instance +mutex_instances +performance_timers +rwlock_instances +setup_consumers +setup_instruments +setup_timers +threads +show create table cond_instances; Table Create Table -COND_INSTANCES CREATE TABLE `COND_INSTANCES` ( +cond_instances CREATE TABLE `cond_instances` ( `NAME` varchar(128) NOT NULL, `OBJECT_INSTANCE_BEGIN` bigint(20) NOT NULL ) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8 -show create table EVENTS_WAITS_CURRENT; +show create table events_waits_current; Table Create Table -EVENTS_WAITS_CURRENT CREATE TABLE `EVENTS_WAITS_CURRENT` ( +events_waits_current CREATE TABLE `events_waits_current` ( `THREAD_ID` int(11) NOT NULL, `EVENT_ID` bigint(20) unsigned NOT NULL, `EVENT_NAME` varchar(128) NOT NULL, @@ -51,9 +51,9 @@ EVENTS_WAITS_CURRENT CREATE TABLE `EVENTS_WAITS_CURRENT` ( `NUMBER_OF_BYTES` bigint(20) unsigned DEFAULT NULL, `FLAGS` int(10) unsigned DEFAULT NULL ) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8 -show create table EVENTS_WAITS_HISTORY; +show create table events_waits_history; Table Create Table -EVENTS_WAITS_HISTORY CREATE TABLE `EVENTS_WAITS_HISTORY` ( +events_waits_history CREATE TABLE `events_waits_history` ( `THREAD_ID` int(11) NOT NULL, `EVENT_ID` bigint(20) unsigned NOT NULL, `EVENT_NAME` varchar(128) NOT NULL, @@ -71,9 +71,9 @@ EVENTS_WAITS_HISTORY CREATE TABLE `EVENTS_WAITS_HISTORY` ( `NUMBER_OF_BYTES` bigint(20) unsigned DEFAULT NULL, `FLAGS` int(10) unsigned DEFAULT NULL ) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8 -show create table EVENTS_WAITS_HISTORY_LONG; +show create table events_waits_history_long; Table Create Table -EVENTS_WAITS_HISTORY_LONG CREATE TABLE `EVENTS_WAITS_HISTORY_LONG` ( +events_waits_history_long CREATE TABLE `events_waits_history_long` ( `THREAD_ID` int(11) NOT NULL, `EVENT_ID` bigint(20) unsigned NOT NULL, `EVENT_NAME` varchar(128) NOT NULL, @@ -91,9 +91,9 @@ EVENTS_WAITS_HISTORY_LONG CREATE TABLE `EVENTS_WAITS_HISTORY_LONG` ( `NUMBER_OF_BYTES` bigint(20) unsigned DEFAULT NULL, `FLAGS` int(10) unsigned DEFAULT NULL ) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8 -show create table EVENTS_WAITS_SUMMARY_BY_INSTANCE; +show create table events_waits_summary_by_instance; Table Create Table -EVENTS_WAITS_SUMMARY_BY_INSTANCE CREATE TABLE `EVENTS_WAITS_SUMMARY_BY_INSTANCE` ( +events_waits_summary_by_instance CREATE TABLE `events_waits_summary_by_instance` ( `EVENT_NAME` varchar(128) NOT NULL, `OBJECT_INSTANCE_BEGIN` bigint(20) NOT NULL, `COUNT_STAR` bigint(20) unsigned NOT NULL, @@ -102,9 +102,9 @@ EVENTS_WAITS_SUMMARY_BY_INSTANCE CREATE TABLE `EVENTS_WAITS_SUMMARY_BY_INSTANCE` `AVG_TIMER_WAIT` bigint(20) unsigned NOT NULL, `MAX_TIMER_WAIT` bigint(20) unsigned NOT NULL ) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8 -show create table EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME; +show create table events_waits_summary_by_thread_by_event_name; Table Create Table -EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME CREATE TABLE `EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME` ( +events_waits_summary_by_thread_by_event_name CREATE TABLE `events_waits_summary_by_thread_by_event_name` ( `THREAD_ID` int(11) NOT NULL, `EVENT_NAME` varchar(128) NOT NULL, `COUNT_STAR` bigint(20) unsigned NOT NULL, @@ -113,9 +113,9 @@ EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME CREATE TABLE `EVENTS_WAITS_SUMMARY_ `AVG_TIMER_WAIT` bigint(20) unsigned NOT NULL, `MAX_TIMER_WAIT` bigint(20) unsigned NOT NULL ) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8 -show create table EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME; +show create table events_waits_summary_global_by_event_name; Table Create Table -EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME CREATE TABLE `EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME` ( +events_waits_summary_global_by_event_name CREATE TABLE `events_waits_summary_global_by_event_name` ( `EVENT_NAME` varchar(128) NOT NULL, `COUNT_STAR` bigint(20) unsigned NOT NULL, `SUM_TIMER_WAIT` bigint(20) unsigned NOT NULL, @@ -123,25 +123,25 @@ EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME CREATE TABLE `EVENTS_WAITS_SUMMARY_GLO `AVG_TIMER_WAIT` bigint(20) unsigned NOT NULL, `MAX_TIMER_WAIT` bigint(20) unsigned NOT NULL ) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8 -show create table FILE_INSTANCES; +show create table file_instances; Table Create Table -FILE_INSTANCES CREATE TABLE `FILE_INSTANCES` ( +file_instances CREATE TABLE `file_instances` ( `FILE_NAME` varchar(512) NOT NULL, `EVENT_NAME` varchar(128) NOT NULL, `OPEN_COUNT` int(10) unsigned NOT NULL ) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8 -show create table FILE_SUMMARY_BY_EVENT_NAME; +show create table file_summary_by_event_name; Table Create Table -FILE_SUMMARY_BY_EVENT_NAME CREATE TABLE `FILE_SUMMARY_BY_EVENT_NAME` ( +file_summary_by_event_name CREATE TABLE `file_summary_by_event_name` ( `EVENT_NAME` varchar(128) NOT NULL, `COUNT_READ` bigint(20) unsigned NOT NULL, `COUNT_WRITE` bigint(20) unsigned NOT NULL, `SUM_NUMBER_OF_BYTES_READ` bigint(20) unsigned NOT NULL, `SUM_NUMBER_OF_BYTES_WRITE` bigint(20) unsigned NOT NULL ) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8 -show create table FILE_SUMMARY_BY_INSTANCE; +show create table file_summary_by_instance; Table Create Table -FILE_SUMMARY_BY_INSTANCE CREATE TABLE `FILE_SUMMARY_BY_INSTANCE` ( +file_summary_by_instance CREATE TABLE `file_summary_by_instance` ( `FILE_NAME` varchar(512) NOT NULL, `EVENT_NAME` varchar(128) NOT NULL, `COUNT_READ` bigint(20) unsigned NOT NULL, @@ -149,51 +149,51 @@ FILE_SUMMARY_BY_INSTANCE CREATE TABLE `FILE_SUMMARY_BY_INSTANCE` ( `SUM_NUMBER_OF_BYTES_READ` bigint(20) unsigned NOT NULL, `SUM_NUMBER_OF_BYTES_WRITE` bigint(20) unsigned NOT NULL ) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8 -show create table MUTEX_INSTANCES; +show create table mutex_instances; Table Create Table -MUTEX_INSTANCES CREATE TABLE `MUTEX_INSTANCES` ( +mutex_instances CREATE TABLE `mutex_instances` ( `NAME` varchar(128) NOT NULL, `OBJECT_INSTANCE_BEGIN` bigint(20) NOT NULL, `LOCKED_BY_THREAD_ID` int(11) DEFAULT NULL ) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8 -show create table PERFORMANCE_TIMERS; +show create table performance_timers; Table Create Table -PERFORMANCE_TIMERS CREATE TABLE `PERFORMANCE_TIMERS` ( +performance_timers CREATE TABLE `performance_timers` ( `TIMER_NAME` enum('CYCLE','NANOSECOND','MICROSECOND','MILLISECOND','TICK') NOT NULL, `TIMER_FREQUENCY` bigint(20) DEFAULT NULL, `TIMER_RESOLUTION` bigint(20) DEFAULT NULL, `TIMER_OVERHEAD` bigint(20) DEFAULT NULL ) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8 -show create table RWLOCK_INSTANCES; +show create table rwlock_instances; Table Create Table -RWLOCK_INSTANCES CREATE TABLE `RWLOCK_INSTANCES` ( +rwlock_instances CREATE TABLE `rwlock_instances` ( `NAME` varchar(128) NOT NULL, `OBJECT_INSTANCE_BEGIN` bigint(20) NOT NULL, `WRITE_LOCKED_BY_THREAD_ID` int(11) DEFAULT NULL, `READ_LOCKED_BY_COUNT` int(10) unsigned NOT NULL ) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8 -show create table SETUP_CONSUMERS; +show create table setup_consumers; Table Create Table -SETUP_CONSUMERS CREATE TABLE `SETUP_CONSUMERS` ( +setup_consumers CREATE TABLE `setup_consumers` ( `NAME` varchar(64) NOT NULL, `ENABLED` enum('YES','NO') NOT NULL ) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8 -show create table SETUP_INSTRUMENTS; +show create table setup_instruments; Table Create Table -SETUP_INSTRUMENTS CREATE TABLE `SETUP_INSTRUMENTS` ( +setup_instruments CREATE TABLE `setup_instruments` ( `NAME` varchar(128) NOT NULL, `ENABLED` enum('YES','NO') NOT NULL, `TIMED` enum('YES','NO') NOT NULL ) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8 -show create table SETUP_TIMERS; +show create table setup_timers; Table Create Table -SETUP_TIMERS CREATE TABLE `SETUP_TIMERS` ( +setup_timers CREATE TABLE `setup_timers` ( `NAME` varchar(64) NOT NULL, `TIMER_NAME` enum('CYCLE','NANOSECOND','MICROSECOND','MILLISECOND','TICK') NOT NULL ) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8 -show create table THREADS; +show create table threads; Table Create Table -THREADS CREATE TABLE `THREADS` ( +threads CREATE TABLE `threads` ( `THREAD_ID` int(11) NOT NULL, `PROCESSLIST_ID` int(11) DEFAULT NULL, `NAME` varchar(128) NOT NULL diff --git a/mysql-test/suite/perfschema/r/selects.result b/mysql-test/suite/perfschema/r/selects.result index 6d596ba8d9a..a3d0931cf4c 100644 --- a/mysql-test/suite/perfschema/r/selects.result +++ b/mysql-test/suite/perfschema/r/selects.result @@ -1,38 +1,38 @@ -UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'YES', timed = 'YES'; +UPDATE performance_schema.setup_instruments SET enabled = 'YES', timed = 'YES'; DROP TABLE IF EXISTS t1; CREATE TABLE t1 (id INT PRIMARY KEY, b CHAR(100) DEFAULT 'initial value') ENGINE=MyISAM; INSERT INTO t1 (id) VALUES (1), (2), (3), (4), (5), (6), (7), (8); SELECT OPERATION, SUM(NUMBER_OF_BYTES) AS TOTAL -FROM performance_schema.EVENTS_WAITS_HISTORY_LONG +FROM performance_schema.events_waits_history_long GROUP BY OPERATION HAVING TOTAL IS NOT NULL ORDER BY OPERATION LIMIT 1; OPERATION TOTAL chsize [NUM_BYTES] -SELECT EVENT_ID FROM performance_schema.EVENTS_WAITS_CURRENT +SELECT EVENT_ID FROM performance_schema.events_waits_current WHERE THREAD_ID IN -(SELECT THREAD_ID FROM performance_schema.THREADS) +(SELECT THREAD_ID FROM performance_schema.threads) AND EVENT_NAME IN -(SELECT NAME FROM performance_schema.SETUP_INSTRUMENTS +(SELECT NAME FROM performance_schema.setup_instruments WHERE NAME LIKE "wait/synch/%") LIMIT 1; EVENT_ID [EVENT_ID] SELECT DISTINCT EVENT_ID -FROM performance_schema.EVENTS_WAITS_CURRENT -JOIN performance_schema.EVENTS_WAITS_HISTORY USING (EVENT_ID) -JOIN performance_schema.EVENTS_WAITS_HISTORY_LONG USING (EVENT_ID) +FROM performance_schema.events_waits_current +JOIN performance_schema.events_waits_history USING (EVENT_ID) +JOIN performance_schema.events_waits_history_long USING (EVENT_ID) ORDER BY EVENT_ID LIMIT 1; EVENT_ID [EVENT_ID] SELECT t1.THREAD_ID, t2.EVENT_ID, t3.EVENT_NAME, t4.TIMER_WAIT -FROM performance_schema.EVENTS_WAITS_HISTORY t1 -JOIN performance_schema.EVENTS_WAITS_HISTORY t2 USING (EVENT_ID) -JOIN performance_schema.EVENTS_WAITS_HISTORY t3 ON (t2.THREAD_ID = t3.THREAD_ID) -JOIN performance_schema.EVENTS_WAITS_HISTORY t4 ON (t3.EVENT_NAME = t4.EVENT_NAME) +FROM performance_schema.events_waits_history t1 +JOIN performance_schema.events_waits_history t2 USING (EVENT_ID) +JOIN performance_schema.events_waits_history t3 ON (t2.THREAD_ID = t3.THREAD_ID) +JOIN performance_schema.events_waits_history t4 ON (t3.EVENT_NAME = t4.EVENT_NAME) ORDER BY t1.EVENT_ID, t2.EVENT_ID LIMIT 5; THREAD_ID EVENT_ID EVENT_NAME TIMER_WAIT @@ -42,11 +42,11 @@ THREAD_ID EVENT_ID EVENT_NAME TIMER_WAIT [THREAD_ID] [EVENT_ID] [EVENT_NAME] [TIMER_WAIT] [THREAD_ID] [EVENT_ID] [EVENT_NAME] [TIMER_WAIT] SELECT THREAD_ID, EVENT_ID FROM ( -SELECT THREAD_ID, EVENT_ID FROM performance_schema.EVENTS_WAITS_CURRENT +SELECT THREAD_ID, EVENT_ID FROM performance_schema.events_waits_current UNION -SELECT THREAD_ID, EVENT_ID FROM performance_schema.EVENTS_WAITS_HISTORY +SELECT THREAD_ID, EVENT_ID FROM performance_schema.events_waits_history UNION -SELECT THREAD_ID, EVENT_ID FROM performance_schema.EVENTS_WAITS_HISTORY_LONG +SELECT THREAD_ID, EVENT_ID FROM performance_schema.events_waits_history_long ) t1 ORDER BY THREAD_ID, EVENT_ID LIMIT 5; THREAD_ID EVENT_ID @@ -58,14 +58,14 @@ THREAD_ID EVENT_ID DROP TABLE IF EXISTS t_event; DROP EVENT IF EXISTS t_ps_event; CREATE TABLE t_event AS -SELECT EVENT_ID FROM performance_schema.EVENTS_WAITS_CURRENT +SELECT EVENT_ID FROM performance_schema.events_waits_current WHERE 1 = 2; CREATE EVENT t_ps_event ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 SECOND DO INSERT INTO t_event SELECT DISTINCT EVENT_ID -FROM performance_schema.EVENTS_WAITS_CURRENT -JOIN performance_schema.EVENTS_WAITS_HISTORY USING (EVENT_ID) +FROM performance_schema.events_waits_current +JOIN performance_schema.events_waits_history USING (EVENT_ID) ORDER BY EVENT_ID LIMIT 1; ALTER TABLE t1 ADD COLUMN c INT; @@ -73,7 +73,7 @@ DROP TRIGGER IF EXISTS t_ps_trigger; CREATE TRIGGER t_ps_trigger BEFORE INSERT ON t1 FOR EACH ROW BEGIN SET NEW.c = (SELECT MAX(EVENT_ID) -FROM performance_schema.EVENTS_WAITS_CURRENT); +FROM performance_schema.events_waits_current); END; | INSERT INTO t1 (id) VALUES (11), (12), (13); @@ -86,7 +86,7 @@ DROP TRIGGER t_ps_trigger; DROP PROCEDURE IF EXISTS t_ps_proc; CREATE PROCEDURE t_ps_proc(IN conid INT, OUT pid INT) BEGIN -SELECT thread_id FROM performance_schema.THREADS +SELECT thread_id FROM performance_schema.threads WHERE PROCESSLIST_ID = conid INTO pid; END; | @@ -94,7 +94,7 @@ CALL t_ps_proc(connection_id(), @p_id); DROP FUNCTION IF EXISTS t_ps_proc; CREATE FUNCTION t_ps_func(conid INT) RETURNS int BEGIN -return (SELECT thread_id FROM performance_schema.THREADS +return (SELECT thread_id FROM performance_schema.threads WHERE PROCESSLIST_ID = conid); END; | diff --git a/mysql-test/suite/perfschema/r/server_init.result b/mysql-test/suite/perfschema/r/server_init.result index 0c1e06d157c..950b63fd94c 100644 --- a/mysql-test/suite/perfschema/r/server_init.result +++ b/mysql-test/suite/perfschema/r/server_init.result @@ -1,209 +1,209 @@ use performance_schema; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/mysys/THR_LOCK_threads"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/mysys/THR_LOCK_malloc"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/mysys/THR_LOCK_open"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/mysys/THR_LOCK_isam"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/mysys/THR_LOCK_myisam"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/mysys/THR_LOCK_heap"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/mysys/THR_LOCK_net"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/mysys/THR_LOCK_charset"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/mysys/THR_LOCK_time"; count(name) 1 -select count(name) from COND_INSTANCES +select count(name) from cond_instances where name like "wait/synch/cond/mysys/THR_COND_threads"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_open"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_thread_count"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_status"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_error_log"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_delayed_insert"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_uuid_generator"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_delayed_status"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_delayed_create"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_crypt"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_slave_list"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_active_mi"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_manager"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_global_read_lock"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_global_system_variables"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_user_conn"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_prepared_stmt_count"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_connection_count"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_server_started"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_rpl_status"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/Query_cache::structure_guard_mutex"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_event_metadata"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_event_queue"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_user_locks"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/Cversion_lock"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_audit_mask"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_xid_cache"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_plugin"; count(name) 1 -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/tz_LOCK"; count(name) 1 -select count(name) from RWLOCK_INSTANCES +select count(name) from rwlock_instances where name like "wait/synch/rwlock/sql/LOCK_grant"; count(name) 1 -select count(name) from RWLOCK_INSTANCES +select count(name) from rwlock_instances where name like "wait/synch/rwlock/sql/LOCK_sys_init_connect"; count(name) 1 -select count(name) from RWLOCK_INSTANCES +select count(name) from rwlock_instances where name like "wait/synch/rwlock/sql/LOCK_sys_init_slave"; count(name) 1 -select count(name) from RWLOCK_INSTANCES +select count(name) from rwlock_instances where name like "wait/synch/rwlock/sql/LOCK_system_variables_hash"; count(name) 1 -select count(name) from COND_INSTANCES +select count(name) from cond_instances where name like "wait/synch/cond/sql/COND_server_started"; count(name) 1 -select count(name) from COND_INSTANCES +select count(name) from cond_instances where name like "wait/synch/cond/sql/COND_refresh"; count(name) 0 -select count(name) from COND_INSTANCES +select count(name) from cond_instances where name like "wait/synch/cond/sql/COND_thread_count"; count(name) 1 -select count(name) from COND_INSTANCES +select count(name) from cond_instances where name like "wait/synch/cond/sql/COND_manager"; count(name) 1 -select count(name) from COND_INSTANCES +select count(name) from cond_instances where name like "wait/synch/cond/sql/COND_global_read_lock"; count(name) 1 -select count(name) from COND_INSTANCES +select count(name) from cond_instances where name like "wait/synch/cond/sql/COND_thread_cache"; count(name) 1 -select count(name) from COND_INSTANCES +select count(name) from cond_instances where name like "wait/synch/cond/sql/COND_flush_thread_cache"; count(name) 1 -select count(name) from COND_INSTANCES +select count(name) from cond_instances where name like "wait/synch/cond/sql/COND_rpl_status"; count(name) 1 -select count(name) from COND_INSTANCES +select count(name) from cond_instances where name like "wait/synch/cond/sql/Query_cache::COND_cache_status_changed"; count(name) 1 -select count(name) from COND_INSTANCES +select count(name) from cond_instances where name like "wait/synch/cond/sql/COND_queue_state"; count(name) 1 diff --git a/mysql-test/suite/perfschema/r/start_server_no_cond_class.result b/mysql-test/suite/perfschema/r/start_server_no_cond_class.result index d03e227fc83..f32ffe327a2 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_cond_class.result +++ b/mysql-test/suite/perfschema/r/start_server_no_cond_class.result @@ -5,35 +5,35 @@ mtr mysql performance_schema test -select count(*) from performance_schema.PERFORMANCE_TIMERS; +select count(*) from performance_schema.performance_timers; count(*) 5 -select count(*) from performance_schema.SETUP_CONSUMERS; +select count(*) from performance_schema.setup_consumers; count(*) 8 -select count(*) > 0 from performance_schema.SETUP_INSTRUMENTS; +select count(*) > 0 from performance_schema.setup_instruments; count(*) > 0 1 -select count(*) from performance_schema.SETUP_TIMERS; +select count(*) from performance_schema.setup_timers; count(*) 1 -select * from performance_schema.COND_INSTANCES; -select * from performance_schema.EVENTS_WAITS_CURRENT; -select * from performance_schema.EVENTS_WAITS_HISTORY; -select * from performance_schema.EVENTS_WAITS_HISTORY_LONG; -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE; -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME; -select * from performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME; -select * from performance_schema.FILE_INSTANCES; -select * from performance_schema.FILE_SUMMARY_BY_EVENT_NAME; -select * from performance_schema.FILE_SUMMARY_BY_INSTANCE; -select * from performance_schema.MUTEX_INSTANCES; -select * from performance_schema.PERFORMANCE_TIMERS; -select * from performance_schema.RWLOCK_INSTANCES; -select * from performance_schema.SETUP_CONSUMERS; -select * from performance_schema.SETUP_INSTRUMENTS; -select * from performance_schema.SETUP_TIMERS; -select * from performance_schema.THREADS; +select * from performance_schema.cond_instances; +select * from performance_schema.events_waits_current; +select * from performance_schema.events_waits_history; +select * from performance_schema.events_waits_history_long; +select * from performance_schema.events_waits_summary_by_instance; +select * from performance_schema.events_waits_summary_by_thread_by_event_name; +select * from performance_schema.events_waits_summary_global_by_event_name; +select * from performance_schema.file_instances; +select * from performance_schema.file_summary_by_event_name; +select * from performance_schema.file_summary_by_instance; +select * from performance_schema.mutex_instances; +select * from performance_schema.performance_timers; +select * from performance_schema.rwlock_instances; +select * from performance_schema.setup_consumers; +select * from performance_schema.setup_instruments; +select * from performance_schema.setup_timers; +select * from performance_schema.threads; show variables like "performance_schema%"; Variable_name Value performance_schema ON @@ -57,7 +57,7 @@ show status like "performance_schema%"; show variables like "performance_schema_max_cond_classes"; Variable_name Value performance_schema_max_cond_classes 0 -select count(*) from performance_schema.SETUP_INSTRUMENTS +select count(*) from performance_schema.setup_instruments where name like "wait/synch/cond/%"; count(*) 0 @@ -65,7 +65,7 @@ select variable_value > 0 from information_schema.global_status where variable_name like 'PERFORMANCE_SCHEMA_COND_CLASSES_LOST'; variable_value > 0 1 -select count(*) from performance_schema.COND_INSTANCES; +select count(*) from performance_schema.cond_instances; count(*) 0 show status like "performance_schema_cond_instances_lost"; diff --git a/mysql-test/suite/perfschema/r/start_server_no_cond_inst.result b/mysql-test/suite/perfschema/r/start_server_no_cond_inst.result index 812dc329aaf..ef853ccc710 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_cond_inst.result +++ b/mysql-test/suite/perfschema/r/start_server_no_cond_inst.result @@ -5,35 +5,35 @@ mtr mysql performance_schema test -select count(*) from performance_schema.PERFORMANCE_TIMERS; +select count(*) from performance_schema.performance_timers; count(*) 5 -select count(*) from performance_schema.SETUP_CONSUMERS; +select count(*) from performance_schema.setup_consumers; count(*) 8 -select count(*) > 0 from performance_schema.SETUP_INSTRUMENTS; +select count(*) > 0 from performance_schema.setup_instruments; count(*) > 0 1 -select count(*) from performance_schema.SETUP_TIMERS; +select count(*) from performance_schema.setup_timers; count(*) 1 -select * from performance_schema.COND_INSTANCES; -select * from performance_schema.EVENTS_WAITS_CURRENT; -select * from performance_schema.EVENTS_WAITS_HISTORY; -select * from performance_schema.EVENTS_WAITS_HISTORY_LONG; -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE; -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME; -select * from performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME; -select * from performance_schema.FILE_INSTANCES; -select * from performance_schema.FILE_SUMMARY_BY_EVENT_NAME; -select * from performance_schema.FILE_SUMMARY_BY_INSTANCE; -select * from performance_schema.MUTEX_INSTANCES; -select * from performance_schema.PERFORMANCE_TIMERS; -select * from performance_schema.RWLOCK_INSTANCES; -select * from performance_schema.SETUP_CONSUMERS; -select * from performance_schema.SETUP_INSTRUMENTS; -select * from performance_schema.SETUP_TIMERS; -select * from performance_schema.THREADS; +select * from performance_schema.cond_instances; +select * from performance_schema.events_waits_current; +select * from performance_schema.events_waits_history; +select * from performance_schema.events_waits_history_long; +select * from performance_schema.events_waits_summary_by_instance; +select * from performance_schema.events_waits_summary_by_thread_by_event_name; +select * from performance_schema.events_waits_summary_global_by_event_name; +select * from performance_schema.file_instances; +select * from performance_schema.file_summary_by_event_name; +select * from performance_schema.file_summary_by_instance; +select * from performance_schema.mutex_instances; +select * from performance_schema.performance_timers; +select * from performance_schema.rwlock_instances; +select * from performance_schema.setup_consumers; +select * from performance_schema.setup_instruments; +select * from performance_schema.setup_timers; +select * from performance_schema.threads; show variables like "performance_schema%"; Variable_name Value performance_schema ON @@ -57,7 +57,7 @@ show status like "performance_schema%"; show variables like "performance_schema_max_cond_classes"; Variable_name Value performance_schema_max_cond_classes 80 -select count(*) > 0 from performance_schema.SETUP_INSTRUMENTS +select count(*) > 0 from performance_schema.setup_instruments where name like "wait/synch/cond/%"; count(*) > 0 1 @@ -67,7 +67,7 @@ Performance_schema_cond_classes_lost 0 show variables like "performance_schema_max_cond_instances"; Variable_name Value performance_schema_max_cond_instances 0 -select count(*) from performance_schema.COND_INSTANCES; +select count(*) from performance_schema.cond_instances; count(*) 0 select variable_value > 0 from information_schema.global_status diff --git a/mysql-test/suite/perfschema/r/start_server_no_file_class.result b/mysql-test/suite/perfschema/r/start_server_no_file_class.result index 7ef247e0755..bafb4cac270 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_file_class.result +++ b/mysql-test/suite/perfschema/r/start_server_no_file_class.result @@ -5,35 +5,35 @@ mtr mysql performance_schema test -select count(*) from performance_schema.PERFORMANCE_TIMERS; +select count(*) from performance_schema.performance_timers; count(*) 5 -select count(*) from performance_schema.SETUP_CONSUMERS; +select count(*) from performance_schema.setup_consumers; count(*) 8 -select count(*) > 0 from performance_schema.SETUP_INSTRUMENTS; +select count(*) > 0 from performance_schema.setup_instruments; count(*) > 0 1 -select count(*) from performance_schema.SETUP_TIMERS; +select count(*) from performance_schema.setup_timers; count(*) 1 -select * from performance_schema.COND_INSTANCES; -select * from performance_schema.EVENTS_WAITS_CURRENT; -select * from performance_schema.EVENTS_WAITS_HISTORY; -select * from performance_schema.EVENTS_WAITS_HISTORY_LONG; -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE; -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME; -select * from performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME; -select * from performance_schema.FILE_INSTANCES; -select * from performance_schema.FILE_SUMMARY_BY_EVENT_NAME; -select * from performance_schema.FILE_SUMMARY_BY_INSTANCE; -select * from performance_schema.MUTEX_INSTANCES; -select * from performance_schema.PERFORMANCE_TIMERS; -select * from performance_schema.RWLOCK_INSTANCES; -select * from performance_schema.SETUP_CONSUMERS; -select * from performance_schema.SETUP_INSTRUMENTS; -select * from performance_schema.SETUP_TIMERS; -select * from performance_schema.THREADS; +select * from performance_schema.cond_instances; +select * from performance_schema.events_waits_current; +select * from performance_schema.events_waits_history; +select * from performance_schema.events_waits_history_long; +select * from performance_schema.events_waits_summary_by_instance; +select * from performance_schema.events_waits_summary_by_thread_by_event_name; +select * from performance_schema.events_waits_summary_global_by_event_name; +select * from performance_schema.file_instances; +select * from performance_schema.file_summary_by_event_name; +select * from performance_schema.file_summary_by_instance; +select * from performance_schema.mutex_instances; +select * from performance_schema.performance_timers; +select * from performance_schema.rwlock_instances; +select * from performance_schema.setup_consumers; +select * from performance_schema.setup_instruments; +select * from performance_schema.setup_timers; +select * from performance_schema.threads; show variables like "performance_schema%"; Variable_name Value performance_schema ON @@ -57,7 +57,7 @@ show status like "performance_schema%"; show variables like "performance_schema_max_file_classes"; Variable_name Value performance_schema_max_file_classes 0 -select count(*) from performance_schema.SETUP_INSTRUMENTS +select count(*) from performance_schema.setup_instruments where name like "wait/io/file/%"; count(*) 0 @@ -65,7 +65,7 @@ select variable_value > 0 from information_schema.global_status where variable_name like 'PERFORMANCE_SCHEMA_FILE_CLASSES_LOST'; variable_value > 0 1 -select count(*) from performance_schema.FILE_INSTANCES; +select count(*) from performance_schema.file_instances; count(*) 0 show status like "performance_schema_file_instances_lost"; diff --git a/mysql-test/suite/perfschema/r/start_server_no_file_inst.result b/mysql-test/suite/perfschema/r/start_server_no_file_inst.result index 301c4e44f1e..2e557e5510a 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_file_inst.result +++ b/mysql-test/suite/perfschema/r/start_server_no_file_inst.result @@ -5,35 +5,35 @@ mtr mysql performance_schema test -select count(*) from performance_schema.PERFORMANCE_TIMERS; +select count(*) from performance_schema.performance_timers; count(*) 5 -select count(*) from performance_schema.SETUP_CONSUMERS; +select count(*) from performance_schema.setup_consumers; count(*) 8 -select count(*) > 0 from performance_schema.SETUP_INSTRUMENTS; +select count(*) > 0 from performance_schema.setup_instruments; count(*) > 0 1 -select count(*) from performance_schema.SETUP_TIMERS; +select count(*) from performance_schema.setup_timers; count(*) 1 -select * from performance_schema.COND_INSTANCES; -select * from performance_schema.EVENTS_WAITS_CURRENT; -select * from performance_schema.EVENTS_WAITS_HISTORY; -select * from performance_schema.EVENTS_WAITS_HISTORY_LONG; -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE; -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME; -select * from performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME; -select * from performance_schema.FILE_INSTANCES; -select * from performance_schema.FILE_SUMMARY_BY_EVENT_NAME; -select * from performance_schema.FILE_SUMMARY_BY_INSTANCE; -select * from performance_schema.MUTEX_INSTANCES; -select * from performance_schema.PERFORMANCE_TIMERS; -select * from performance_schema.RWLOCK_INSTANCES; -select * from performance_schema.SETUP_CONSUMERS; -select * from performance_schema.SETUP_INSTRUMENTS; -select * from performance_schema.SETUP_TIMERS; -select * from performance_schema.THREADS; +select * from performance_schema.cond_instances; +select * from performance_schema.events_waits_current; +select * from performance_schema.events_waits_history; +select * from performance_schema.events_waits_history_long; +select * from performance_schema.events_waits_summary_by_instance; +select * from performance_schema.events_waits_summary_by_thread_by_event_name; +select * from performance_schema.events_waits_summary_global_by_event_name; +select * from performance_schema.file_instances; +select * from performance_schema.file_summary_by_event_name; +select * from performance_schema.file_summary_by_instance; +select * from performance_schema.mutex_instances; +select * from performance_schema.performance_timers; +select * from performance_schema.rwlock_instances; +select * from performance_schema.setup_consumers; +select * from performance_schema.setup_instruments; +select * from performance_schema.setup_timers; +select * from performance_schema.threads; show variables like "performance_schema%"; Variable_name Value performance_schema ON @@ -57,7 +57,7 @@ show status like "performance_schema%"; show variables like "performance_schema_max_file_classes"; Variable_name Value performance_schema_max_file_classes 50 -select count(*) > 0 from performance_schema.SETUP_INSTRUMENTS +select count(*) > 0 from performance_schema.setup_instruments where name like "wait/io/file/%"; count(*) > 0 1 @@ -67,7 +67,7 @@ Performance_schema_file_classes_lost 0 show variables like "performance_schema_max_file_instances"; Variable_name Value performance_schema_max_file_instances 0 -select count(*) from performance_schema.FILE_INSTANCES; +select count(*) from performance_schema.file_instances; count(*) 0 select variable_value > 0 from information_schema.global_status diff --git a/mysql-test/suite/perfschema/r/start_server_no_mutex_class.result b/mysql-test/suite/perfschema/r/start_server_no_mutex_class.result index a1f880d3b9e..b6d359ae5d2 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_mutex_class.result +++ b/mysql-test/suite/perfschema/r/start_server_no_mutex_class.result @@ -5,35 +5,35 @@ mtr mysql performance_schema test -select count(*) from performance_schema.PERFORMANCE_TIMERS; +select count(*) from performance_schema.performance_timers; count(*) 5 -select count(*) from performance_schema.SETUP_CONSUMERS; +select count(*) from performance_schema.setup_consumers; count(*) 8 -select count(*) > 0 from performance_schema.SETUP_INSTRUMENTS; +select count(*) > 0 from performance_schema.setup_instruments; count(*) > 0 1 -select count(*) from performance_schema.SETUP_TIMERS; +select count(*) from performance_schema.setup_timers; count(*) 1 -select * from performance_schema.COND_INSTANCES; -select * from performance_schema.EVENTS_WAITS_CURRENT; -select * from performance_schema.EVENTS_WAITS_HISTORY; -select * from performance_schema.EVENTS_WAITS_HISTORY_LONG; -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE; -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME; -select * from performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME; -select * from performance_schema.FILE_INSTANCES; -select * from performance_schema.FILE_SUMMARY_BY_EVENT_NAME; -select * from performance_schema.FILE_SUMMARY_BY_INSTANCE; -select * from performance_schema.MUTEX_INSTANCES; -select * from performance_schema.PERFORMANCE_TIMERS; -select * from performance_schema.RWLOCK_INSTANCES; -select * from performance_schema.SETUP_CONSUMERS; -select * from performance_schema.SETUP_INSTRUMENTS; -select * from performance_schema.SETUP_TIMERS; -select * from performance_schema.THREADS; +select * from performance_schema.cond_instances; +select * from performance_schema.events_waits_current; +select * from performance_schema.events_waits_history; +select * from performance_schema.events_waits_history_long; +select * from performance_schema.events_waits_summary_by_instance; +select * from performance_schema.events_waits_summary_by_thread_by_event_name; +select * from performance_schema.events_waits_summary_global_by_event_name; +select * from performance_schema.file_instances; +select * from performance_schema.file_summary_by_event_name; +select * from performance_schema.file_summary_by_instance; +select * from performance_schema.mutex_instances; +select * from performance_schema.performance_timers; +select * from performance_schema.rwlock_instances; +select * from performance_schema.setup_consumers; +select * from performance_schema.setup_instruments; +select * from performance_schema.setup_timers; +select * from performance_schema.threads; show variables like "performance_schema%"; Variable_name Value performance_schema ON @@ -57,7 +57,7 @@ show status like "performance_schema%"; show variables like "performance_schema_max_mutex_classes"; Variable_name Value performance_schema_max_mutex_classes 0 -select count(*) from performance_schema.SETUP_INSTRUMENTS +select count(*) from performance_schema.setup_instruments where name like "wait/synch/mutex/%"; count(*) 0 @@ -65,7 +65,7 @@ select variable_value > 0 from information_schema.global_status where variable_name like 'PERFORMANCE_SCHEMA_MUTEX_CLASSES_LOST'; variable_value > 0 1 -select count(*) from performance_schema.MUTEX_INSTANCES; +select count(*) from performance_schema.mutex_instances; count(*) 0 show status like "performance_schema_mutex_instances_lost"; diff --git a/mysql-test/suite/perfschema/r/start_server_no_mutex_inst.result b/mysql-test/suite/perfschema/r/start_server_no_mutex_inst.result index ab566f0703a..190d58378ac 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_mutex_inst.result +++ b/mysql-test/suite/perfschema/r/start_server_no_mutex_inst.result @@ -5,35 +5,35 @@ mtr mysql performance_schema test -select count(*) from performance_schema.PERFORMANCE_TIMERS; +select count(*) from performance_schema.performance_timers; count(*) 5 -select count(*) from performance_schema.SETUP_CONSUMERS; +select count(*) from performance_schema.setup_consumers; count(*) 8 -select count(*) > 0 from performance_schema.SETUP_INSTRUMENTS; +select count(*) > 0 from performance_schema.setup_instruments; count(*) > 0 1 -select count(*) from performance_schema.SETUP_TIMERS; +select count(*) from performance_schema.setup_timers; count(*) 1 -select * from performance_schema.COND_INSTANCES; -select * from performance_schema.EVENTS_WAITS_CURRENT; -select * from performance_schema.EVENTS_WAITS_HISTORY; -select * from performance_schema.EVENTS_WAITS_HISTORY_LONG; -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE; -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME; -select * from performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME; -select * from performance_schema.FILE_INSTANCES; -select * from performance_schema.FILE_SUMMARY_BY_EVENT_NAME; -select * from performance_schema.FILE_SUMMARY_BY_INSTANCE; -select * from performance_schema.MUTEX_INSTANCES; -select * from performance_schema.PERFORMANCE_TIMERS; -select * from performance_schema.RWLOCK_INSTANCES; -select * from performance_schema.SETUP_CONSUMERS; -select * from performance_schema.SETUP_INSTRUMENTS; -select * from performance_schema.SETUP_TIMERS; -select * from performance_schema.THREADS; +select * from performance_schema.cond_instances; +select * from performance_schema.events_waits_current; +select * from performance_schema.events_waits_history; +select * from performance_schema.events_waits_history_long; +select * from performance_schema.events_waits_summary_by_instance; +select * from performance_schema.events_waits_summary_by_thread_by_event_name; +select * from performance_schema.events_waits_summary_global_by_event_name; +select * from performance_schema.file_instances; +select * from performance_schema.file_summary_by_event_name; +select * from performance_schema.file_summary_by_instance; +select * from performance_schema.mutex_instances; +select * from performance_schema.performance_timers; +select * from performance_schema.rwlock_instances; +select * from performance_schema.setup_consumers; +select * from performance_schema.setup_instruments; +select * from performance_schema.setup_timers; +select * from performance_schema.threads; show variables like "performance_schema%"; Variable_name Value performance_schema ON @@ -57,7 +57,7 @@ show status like "performance_schema%"; show variables like "performance_schema_max_mutex_classes"; Variable_name Value performance_schema_max_mutex_classes 200 -select count(*) > 0 from performance_schema.SETUP_INSTRUMENTS +select count(*) > 0 from performance_schema.setup_instruments where name like "wait/synch/mutex/%"; count(*) > 0 1 @@ -67,7 +67,7 @@ Performance_schema_mutex_classes_lost 0 show variables like "performance_schema_max_mutex_instances"; Variable_name Value performance_schema_max_mutex_instances 0 -select count(*) from performance_schema.MUTEX_INSTANCES; +select count(*) from performance_schema.mutex_instances; count(*) 0 select variable_value > 0 from information_schema.global_status diff --git a/mysql-test/suite/perfschema/r/start_server_no_rwlock_class.result b/mysql-test/suite/perfschema/r/start_server_no_rwlock_class.result index aabc9ec49bb..b27159828f6 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_rwlock_class.result +++ b/mysql-test/suite/perfschema/r/start_server_no_rwlock_class.result @@ -5,35 +5,35 @@ mtr mysql performance_schema test -select count(*) from performance_schema.PERFORMANCE_TIMERS; +select count(*) from performance_schema.performance_timers; count(*) 5 -select count(*) from performance_schema.SETUP_CONSUMERS; +select count(*) from performance_schema.setup_consumers; count(*) 8 -select count(*) > 0 from performance_schema.SETUP_INSTRUMENTS; +select count(*) > 0 from performance_schema.setup_instruments; count(*) > 0 1 -select count(*) from performance_schema.SETUP_TIMERS; +select count(*) from performance_schema.setup_timers; count(*) 1 -select * from performance_schema.COND_INSTANCES; -select * from performance_schema.EVENTS_WAITS_CURRENT; -select * from performance_schema.EVENTS_WAITS_HISTORY; -select * from performance_schema.EVENTS_WAITS_HISTORY_LONG; -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE; -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME; -select * from performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME; -select * from performance_schema.FILE_INSTANCES; -select * from performance_schema.FILE_SUMMARY_BY_EVENT_NAME; -select * from performance_schema.FILE_SUMMARY_BY_INSTANCE; -select * from performance_schema.MUTEX_INSTANCES; -select * from performance_schema.PERFORMANCE_TIMERS; -select * from performance_schema.RWLOCK_INSTANCES; -select * from performance_schema.SETUP_CONSUMERS; -select * from performance_schema.SETUP_INSTRUMENTS; -select * from performance_schema.SETUP_TIMERS; -select * from performance_schema.THREADS; +select * from performance_schema.cond_instances; +select * from performance_schema.events_waits_current; +select * from performance_schema.events_waits_history; +select * from performance_schema.events_waits_history_long; +select * from performance_schema.events_waits_summary_by_instance; +select * from performance_schema.events_waits_summary_by_thread_by_event_name; +select * from performance_schema.events_waits_summary_global_by_event_name; +select * from performance_schema.file_instances; +select * from performance_schema.file_summary_by_event_name; +select * from performance_schema.file_summary_by_instance; +select * from performance_schema.mutex_instances; +select * from performance_schema.performance_timers; +select * from performance_schema.rwlock_instances; +select * from performance_schema.setup_consumers; +select * from performance_schema.setup_instruments; +select * from performance_schema.setup_timers; +select * from performance_schema.threads; show variables like "performance_schema%"; Variable_name Value performance_schema ON @@ -57,7 +57,7 @@ show status like "performance_schema%"; show variables like "performance_schema_max_rwlock_classes"; Variable_name Value performance_schema_max_rwlock_classes 0 -select count(*) from performance_schema.SETUP_INSTRUMENTS +select count(*) from performance_schema.setup_instruments where name like "wait/synch/rwlock/%"; count(*) 0 @@ -65,7 +65,7 @@ select variable_value > 0 from information_schema.global_status where variable_name like 'PERFORMANCE_SCHEMA_RWLOCK_CLASSES_LOST'; variable_value > 0 1 -select count(*) from performance_schema.RWLOCK_INSTANCES; +select count(*) from performance_schema.rwlock_instances; count(*) 0 show status like "performance_schema_rwlock_instances_lost"; diff --git a/mysql-test/suite/perfschema/r/start_server_no_rwlock_inst.result b/mysql-test/suite/perfschema/r/start_server_no_rwlock_inst.result index 5e5998a9959..7466235c42f 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_rwlock_inst.result +++ b/mysql-test/suite/perfschema/r/start_server_no_rwlock_inst.result @@ -5,35 +5,35 @@ mtr mysql performance_schema test -select count(*) from performance_schema.PERFORMANCE_TIMERS; +select count(*) from performance_schema.performance_timers; count(*) 5 -select count(*) from performance_schema.SETUP_CONSUMERS; +select count(*) from performance_schema.setup_consumers; count(*) 8 -select count(*) > 0 from performance_schema.SETUP_INSTRUMENTS; +select count(*) > 0 from performance_schema.setup_instruments; count(*) > 0 1 -select count(*) from performance_schema.SETUP_TIMERS; +select count(*) from performance_schema.setup_timers; count(*) 1 -select * from performance_schema.COND_INSTANCES; -select * from performance_schema.EVENTS_WAITS_CURRENT; -select * from performance_schema.EVENTS_WAITS_HISTORY; -select * from performance_schema.EVENTS_WAITS_HISTORY_LONG; -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE; -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME; -select * from performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME; -select * from performance_schema.FILE_INSTANCES; -select * from performance_schema.FILE_SUMMARY_BY_EVENT_NAME; -select * from performance_schema.FILE_SUMMARY_BY_INSTANCE; -select * from performance_schema.MUTEX_INSTANCES; -select * from performance_schema.PERFORMANCE_TIMERS; -select * from performance_schema.RWLOCK_INSTANCES; -select * from performance_schema.SETUP_CONSUMERS; -select * from performance_schema.SETUP_INSTRUMENTS; -select * from performance_schema.SETUP_TIMERS; -select * from performance_schema.THREADS; +select * from performance_schema.cond_instances; +select * from performance_schema.events_waits_current; +select * from performance_schema.events_waits_history; +select * from performance_schema.events_waits_history_long; +select * from performance_schema.events_waits_summary_by_instance; +select * from performance_schema.events_waits_summary_by_thread_by_event_name; +select * from performance_schema.events_waits_summary_global_by_event_name; +select * from performance_schema.file_instances; +select * from performance_schema.file_summary_by_event_name; +select * from performance_schema.file_summary_by_instance; +select * from performance_schema.mutex_instances; +select * from performance_schema.performance_timers; +select * from performance_schema.rwlock_instances; +select * from performance_schema.setup_consumers; +select * from performance_schema.setup_instruments; +select * from performance_schema.setup_timers; +select * from performance_schema.threads; show variables like "performance_schema%"; Variable_name Value performance_schema ON @@ -57,7 +57,7 @@ show status like "performance_schema%"; show variables like "performance_schema_max_rwlock_classes"; Variable_name Value performance_schema_max_rwlock_classes 30 -select count(*) > 0 from performance_schema.SETUP_INSTRUMENTS +select count(*) > 0 from performance_schema.setup_instruments where name like "wait/synch/rwlock/%"; count(*) > 0 1 @@ -67,7 +67,7 @@ Performance_schema_rwlock_classes_lost 0 show variables like "performance_schema_max_rwlock_instances"; Variable_name Value performance_schema_max_rwlock_instances 0 -select count(*) from performance_schema.RWLOCK_INSTANCES; +select count(*) from performance_schema.rwlock_instances; count(*) 0 select variable_value > 0 from information_schema.global_status diff --git a/mysql-test/suite/perfschema/r/start_server_no_thread_class.result b/mysql-test/suite/perfschema/r/start_server_no_thread_class.result index 96c3cae97ab..075c22bc405 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_thread_class.result +++ b/mysql-test/suite/perfschema/r/start_server_no_thread_class.result @@ -5,35 +5,35 @@ mtr mysql performance_schema test -select count(*) from performance_schema.PERFORMANCE_TIMERS; +select count(*) from performance_schema.performance_timers; count(*) 5 -select count(*) from performance_schema.SETUP_CONSUMERS; +select count(*) from performance_schema.setup_consumers; count(*) 8 -select count(*) > 0 from performance_schema.SETUP_INSTRUMENTS; +select count(*) > 0 from performance_schema.setup_instruments; count(*) > 0 1 -select count(*) from performance_schema.SETUP_TIMERS; +select count(*) from performance_schema.setup_timers; count(*) 1 -select * from performance_schema.COND_INSTANCES; -select * from performance_schema.EVENTS_WAITS_CURRENT; -select * from performance_schema.EVENTS_WAITS_HISTORY; -select * from performance_schema.EVENTS_WAITS_HISTORY_LONG; -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE; -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME; -select * from performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME; -select * from performance_schema.FILE_INSTANCES; -select * from performance_schema.FILE_SUMMARY_BY_EVENT_NAME; -select * from performance_schema.FILE_SUMMARY_BY_INSTANCE; -select * from performance_schema.MUTEX_INSTANCES; -select * from performance_schema.PERFORMANCE_TIMERS; -select * from performance_schema.RWLOCK_INSTANCES; -select * from performance_schema.SETUP_CONSUMERS; -select * from performance_schema.SETUP_INSTRUMENTS; -select * from performance_schema.SETUP_TIMERS; -select * from performance_schema.THREADS; +select * from performance_schema.cond_instances; +select * from performance_schema.events_waits_current; +select * from performance_schema.events_waits_history; +select * from performance_schema.events_waits_history_long; +select * from performance_schema.events_waits_summary_by_instance; +select * from performance_schema.events_waits_summary_by_thread_by_event_name; +select * from performance_schema.events_waits_summary_global_by_event_name; +select * from performance_schema.file_instances; +select * from performance_schema.file_summary_by_event_name; +select * from performance_schema.file_summary_by_instance; +select * from performance_schema.mutex_instances; +select * from performance_schema.performance_timers; +select * from performance_schema.rwlock_instances; +select * from performance_schema.setup_consumers; +select * from performance_schema.setup_instruments; +select * from performance_schema.setup_timers; +select * from performance_schema.threads; show variables like "performance_schema%"; Variable_name Value performance_schema ON @@ -57,7 +57,7 @@ show status like "performance_schema%"; show variables like "performance_schema_max_thread_classes"; Variable_name Value performance_schema_max_thread_classes 0 -select count(*) from performance_schema.SETUP_INSTRUMENTS +select count(*) from performance_schema.setup_instruments where name like "thread/%"; count(*) 0 @@ -65,7 +65,7 @@ select variable_value > 0 from information_schema.global_status where variable_name like 'PERFORMANCE_SCHEMA_THREAD_CLASSES_LOST'; variable_value > 0 1 -select count(*) from performance_schema.THREADS; +select count(*) from performance_schema.threads; count(*) 0 show status like "performance_schema_thread_instances_lost"; diff --git a/mysql-test/suite/perfschema/r/start_server_no_thread_inst.result b/mysql-test/suite/perfschema/r/start_server_no_thread_inst.result index e2cf0917cbf..763b5b69ca1 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_thread_inst.result +++ b/mysql-test/suite/perfschema/r/start_server_no_thread_inst.result @@ -5,35 +5,35 @@ mtr mysql performance_schema test -select count(*) from performance_schema.PERFORMANCE_TIMERS; +select count(*) from performance_schema.performance_timers; count(*) 5 -select count(*) from performance_schema.SETUP_CONSUMERS; +select count(*) from performance_schema.setup_consumers; count(*) 8 -select count(*) > 0 from performance_schema.SETUP_INSTRUMENTS; +select count(*) > 0 from performance_schema.setup_instruments; count(*) > 0 1 -select count(*) from performance_schema.SETUP_TIMERS; +select count(*) from performance_schema.setup_timers; count(*) 1 -select * from performance_schema.COND_INSTANCES; -select * from performance_schema.EVENTS_WAITS_CURRENT; -select * from performance_schema.EVENTS_WAITS_HISTORY; -select * from performance_schema.EVENTS_WAITS_HISTORY_LONG; -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE; -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME; -select * from performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME; -select * from performance_schema.FILE_INSTANCES; -select * from performance_schema.FILE_SUMMARY_BY_EVENT_NAME; -select * from performance_schema.FILE_SUMMARY_BY_INSTANCE; -select * from performance_schema.MUTEX_INSTANCES; -select * from performance_schema.PERFORMANCE_TIMERS; -select * from performance_schema.RWLOCK_INSTANCES; -select * from performance_schema.SETUP_CONSUMERS; -select * from performance_schema.SETUP_INSTRUMENTS; -select * from performance_schema.SETUP_TIMERS; -select * from performance_schema.THREADS; +select * from performance_schema.cond_instances; +select * from performance_schema.events_waits_current; +select * from performance_schema.events_waits_history; +select * from performance_schema.events_waits_history_long; +select * from performance_schema.events_waits_summary_by_instance; +select * from performance_schema.events_waits_summary_by_thread_by_event_name; +select * from performance_schema.events_waits_summary_global_by_event_name; +select * from performance_schema.file_instances; +select * from performance_schema.file_summary_by_event_name; +select * from performance_schema.file_summary_by_instance; +select * from performance_schema.mutex_instances; +select * from performance_schema.performance_timers; +select * from performance_schema.rwlock_instances; +select * from performance_schema.setup_consumers; +select * from performance_schema.setup_instruments; +select * from performance_schema.setup_timers; +select * from performance_schema.threads; show variables like "performance_schema%"; Variable_name Value performance_schema ON @@ -63,7 +63,7 @@ Performance_schema_thread_classes_lost 0 show variables like "performance_schema_max_thread_instances"; Variable_name Value performance_schema_max_thread_instances 0 -select count(*) from performance_schema.THREADS; +select count(*) from performance_schema.threads; count(*) 0 select variable_value > 0 from information_schema.global_status diff --git a/mysql-test/suite/perfschema/r/start_server_off.result b/mysql-test/suite/perfschema/r/start_server_off.result index 8bf52580e77..4cdfad654ae 100644 --- a/mysql-test/suite/perfschema/r/start_server_off.result +++ b/mysql-test/suite/perfschema/r/start_server_off.result @@ -5,35 +5,35 @@ mtr mysql performance_schema test -select count(*) from performance_schema.PERFORMANCE_TIMERS; +select count(*) from performance_schema.performance_timers; count(*) 5 -select count(*) from performance_schema.SETUP_CONSUMERS; +select count(*) from performance_schema.setup_consumers; count(*) 8 -select count(*) > 0 from performance_schema.SETUP_INSTRUMENTS; +select count(*) > 0 from performance_schema.setup_instruments; count(*) > 0 0 -select count(*) from performance_schema.SETUP_TIMERS; +select count(*) from performance_schema.setup_timers; count(*) 1 -select * from performance_schema.COND_INSTANCES; -select * from performance_schema.EVENTS_WAITS_CURRENT; -select * from performance_schema.EVENTS_WAITS_HISTORY; -select * from performance_schema.EVENTS_WAITS_HISTORY_LONG; -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE; -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME; -select * from performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME; -select * from performance_schema.FILE_INSTANCES; -select * from performance_schema.FILE_SUMMARY_BY_EVENT_NAME; -select * from performance_schema.FILE_SUMMARY_BY_INSTANCE; -select * from performance_schema.MUTEX_INSTANCES; -select * from performance_schema.PERFORMANCE_TIMERS; -select * from performance_schema.RWLOCK_INSTANCES; -select * from performance_schema.SETUP_CONSUMERS; -select * from performance_schema.SETUP_INSTRUMENTS; -select * from performance_schema.SETUP_TIMERS; -select * from performance_schema.THREADS; +select * from performance_schema.cond_instances; +select * from performance_schema.events_waits_current; +select * from performance_schema.events_waits_history; +select * from performance_schema.events_waits_history_long; +select * from performance_schema.events_waits_summary_by_instance; +select * from performance_schema.events_waits_summary_by_thread_by_event_name; +select * from performance_schema.events_waits_summary_global_by_event_name; +select * from performance_schema.file_instances; +select * from performance_schema.file_summary_by_event_name; +select * from performance_schema.file_summary_by_instance; +select * from performance_schema.mutex_instances; +select * from performance_schema.performance_timers; +select * from performance_schema.rwlock_instances; +select * from performance_schema.setup_consumers; +select * from performance_schema.setup_instruments; +select * from performance_schema.setup_timers; +select * from performance_schema.threads; show variables like "performance_schema%"; Variable_name Value performance_schema OFF diff --git a/mysql-test/suite/perfschema/r/start_server_on.result b/mysql-test/suite/perfschema/r/start_server_on.result index 15fe4e082ab..a17f78b27db 100644 --- a/mysql-test/suite/perfschema/r/start_server_on.result +++ b/mysql-test/suite/perfschema/r/start_server_on.result @@ -5,35 +5,35 @@ mtr mysql performance_schema test -select count(*) from performance_schema.PERFORMANCE_TIMERS; +select count(*) from performance_schema.performance_timers; count(*) 5 -select count(*) from performance_schema.SETUP_CONSUMERS; +select count(*) from performance_schema.setup_consumers; count(*) 8 -select count(*) > 0 from performance_schema.SETUP_INSTRUMENTS; +select count(*) > 0 from performance_schema.setup_instruments; count(*) > 0 1 -select count(*) from performance_schema.SETUP_TIMERS; +select count(*) from performance_schema.setup_timers; count(*) 1 -select * from performance_schema.COND_INSTANCES; -select * from performance_schema.EVENTS_WAITS_CURRENT; -select * from performance_schema.EVENTS_WAITS_HISTORY; -select * from performance_schema.EVENTS_WAITS_HISTORY_LONG; -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE; -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME; -select * from performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME; -select * from performance_schema.FILE_INSTANCES; -select * from performance_schema.FILE_SUMMARY_BY_EVENT_NAME; -select * from performance_schema.FILE_SUMMARY_BY_INSTANCE; -select * from performance_schema.MUTEX_INSTANCES; -select * from performance_schema.PERFORMANCE_TIMERS; -select * from performance_schema.RWLOCK_INSTANCES; -select * from performance_schema.SETUP_CONSUMERS; -select * from performance_schema.SETUP_INSTRUMENTS; -select * from performance_schema.SETUP_TIMERS; -select * from performance_schema.THREADS; +select * from performance_schema.cond_instances; +select * from performance_schema.events_waits_current; +select * from performance_schema.events_waits_history; +select * from performance_schema.events_waits_history_long; +select * from performance_schema.events_waits_summary_by_instance; +select * from performance_schema.events_waits_summary_by_thread_by_event_name; +select * from performance_schema.events_waits_summary_global_by_event_name; +select * from performance_schema.file_instances; +select * from performance_schema.file_summary_by_event_name; +select * from performance_schema.file_summary_by_instance; +select * from performance_schema.mutex_instances; +select * from performance_schema.performance_timers; +select * from performance_schema.rwlock_instances; +select * from performance_schema.setup_consumers; +select * from performance_schema.setup_instruments; +select * from performance_schema.setup_timers; +select * from performance_schema.threads; show variables like "performance_schema%"; Variable_name Value performance_schema ON diff --git a/mysql-test/suite/perfschema/r/tampered_perfschema_table1.result b/mysql-test/suite/perfschema/r/tampered_perfschema_table1.result index cdf0029eeb9..6e49dc06db5 100644 --- a/mysql-test/suite/perfschema/r/tampered_perfschema_table1.result +++ b/mysql-test/suite/perfschema/r/tampered_perfschema_table1.result @@ -1,6 +1,6 @@ call mtr.add_suppression( -"Column count of mysql.SETUP_INSTRUMENTS is wrong. " +"Column count of mysql.setup_instruments is wrong. " "Expected 4, found 3. The table is probably corrupted"); -select * from performance_schema.SETUP_INSTRUMENTS limit 1; +select * from performance_schema.setup_instruments limit 1; ERROR HY000: Native table 'performance_schema'.'SETUP_INSTRUMENTS' has the wrong structure -select * from performance_schema.SETUP_CONSUMERS limit 1; +select * from performance_schema.setup_consumers limit 1; diff --git a/mysql-test/suite/perfschema/t/aggregate.test b/mysql-test/suite/perfschema/t/aggregate.test index a8ca3dd91e2..13906af3099 100644 --- a/mysql-test/suite/perfschema/t/aggregate.test +++ b/mysql-test/suite/perfschema/t/aggregate.test @@ -25,19 +25,19 @@ drop table if exists t1; --enable_warnings -update performance_schema.SETUP_INSTRUMENTS set enabled = 'NO'; -update performance_schema.SETUP_CONSUMERS set enabled = 'NO'; +update performance_schema.setup_instruments set enabled = 'NO'; +update performance_schema.setup_consumers set enabled = 'NO'; # Cleanup statistics -truncate table performance_schema.FILE_SUMMARY_BY_EVENT_NAME; -truncate table performance_schema.FILE_SUMMARY_BY_INSTANCE; -truncate table performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME; -truncate table performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE; -truncate table performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME; +truncate table performance_schema.file_summary_by_event_name; +truncate table performance_schema.file_summary_by_instance; +truncate table performance_schema.events_waits_summary_global_by_event_name; +truncate table performance_schema.events_waits_summary_by_instance; +truncate table performance_schema.events_waits_summary_by_thread_by_event_name; # Start recording data -update performance_schema.SETUP_CONSUMERS set enabled = 'YES'; -update performance_schema.SETUP_INSTRUMENTS +update performance_schema.setup_consumers set enabled = 'YES'; +update performance_schema.setup_instruments set enabled = 'YES', timed = 'YES'; @@ -49,27 +49,27 @@ create table t1 ( insert into t1 (id) values (1), (2), (3), (4), (5), (6), (7), (8); # Stop recording data, so the select below don't add noise. -update performance_schema.SETUP_INSTRUMENTS SET enabled = 'NO'; +update performance_schema.setup_instruments SET enabled = 'NO'; # Disable all consumers, for long standing waits -update performance_schema.SETUP_CONSUMERS set enabled = 'NO'; +update performance_schema.setup_consumers set enabled = 'NO'; # Helper to debug set @dump_all=FALSE; # Note that in general: -# - COUNT/SUM/MAX(FILE_SUMMARY_BY_EVENT_NAME) >= -# COUNT/SUM/MAX(FILE_SUMMARY_BY_INSTANCE). -# - MIN(FILE_SUMMARY_BY_EVENT_NAME) <= -# MIN(FILE_SUMMARY_BY_INSTANCE). +# - COUNT/SUM/MAX(file_summary_by_event_name) >= +# COUNT/SUM/MAX(file_summary_by_instance). +# - MIN(file_summary_by_event_name) <= +# MIN(file_summary_by_instance). # There will be equality only when file instances are not removed, # aka when a file is not deleted from the file system, -# because doing so removes a row in FILE_SUMMARY_BY_INSTANCE. +# because doing so removes a row in file_summary_by_instance. # Likewise: -# - COUNT/SUM/MAX(EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME) >= -# COUNT/SUM/MAX(EVENTS_WAITS_SUMMARY_BY_INSTANCE) -# - MIN(EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME) <= -# MIN(EVENTS_WAITS_SUMMARY_BY_INSTANCE) +# - COUNT/SUM/MAX(events_waits_summary_global_by_event_name) >= +# COUNT/SUM/MAX(events_waits_summary_by_instance) +# - MIN(events_waits_summary_global_by_event_name) <= +# MIN(events_waits_summary_by_instance) # There will be equality only when an instrument instance # is not removed, which is next to impossible to predictably guarantee # in the server. @@ -77,18 +77,18 @@ set @dump_all=FALSE; # will cause a mysql_mutex_destroy on myisam/MYISAM_SHARE::intern_lock. # Another example, a thread terminating will cause a mysql_mutex_destroy # on sql/LOCK_delete -# Both cause a row to be deleted from EVENTS_WAITS_SUMMARY_BY_INSTANCE. +# Both cause a row to be deleted from events_waits_summary_by_instance. # Likewise: -# - COUNT/SUM/MAX(EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME) >= -# COUNT/SUM/MAX(EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME) -# - MIN(EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME) <= -# MIN(EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME) +# - COUNT/SUM/MAX(events_waits_summary_global_by_event_name) >= +# COUNT/SUM/MAX(events_waits_summary_by_thread_by_event_name) +# - MIN(events_waits_summary_global_by_event_name) <= +# MIN(events_waits_summary_by_thread_by_event_name) # There will be equality only when no thread is removed, # that is if no thread disconnects, or no sub thread (for example insert # delayed) ever completes. # A thread completing will cause rows in -# EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME to be removed. +# events_waits_summary_by_thread_by_event_name to be removed. --echo "Verifying file aggregate consistency" @@ -101,29 +101,29 @@ set @dump_all=FALSE; # If any of these queries returns data, the test failed. SELECT EVENT_NAME, e.COUNT_READ, SUM(i.COUNT_READ) -FROM performance_schema.FILE_SUMMARY_BY_EVENT_NAME AS e -JOIN performance_schema.FILE_SUMMARY_BY_INSTANCE AS i USING (EVENT_NAME) +FROM performance_schema.file_summary_by_event_name AS e +JOIN performance_schema.file_summary_by_instance AS i USING (EVENT_NAME) GROUP BY EVENT_NAME HAVING (e.COUNT_READ <> SUM(i.COUNT_READ)) OR @dump_all; SELECT EVENT_NAME, e.COUNT_WRITE, SUM(i.COUNT_WRITE) -FROM performance_schema.FILE_SUMMARY_BY_EVENT_NAME AS e -JOIN performance_schema.FILE_SUMMARY_BY_INSTANCE AS i USING (EVENT_NAME) +FROM performance_schema.file_summary_by_event_name AS e +JOIN performance_schema.file_summary_by_instance AS i USING (EVENT_NAME) GROUP BY EVENT_NAME HAVING (e.COUNT_WRITE <> SUM(i.COUNT_WRITE)) OR @dump_all; SELECT EVENT_NAME, e.SUM_NUMBER_OF_BYTES_READ, SUM(i.SUM_NUMBER_OF_BYTES_READ) -FROM performance_schema.FILE_SUMMARY_BY_EVENT_NAME AS e -JOIN performance_schema.FILE_SUMMARY_BY_INSTANCE AS i USING (EVENT_NAME) +FROM performance_schema.file_summary_by_event_name AS e +JOIN performance_schema.file_summary_by_instance AS i USING (EVENT_NAME) GROUP BY EVENT_NAME HAVING (e.SUM_NUMBER_OF_BYTES_READ <> SUM(i.SUM_NUMBER_OF_BYTES_READ)) OR @dump_all; SELECT EVENT_NAME, e.SUM_NUMBER_OF_BYTES_WRITE, SUM(i.SUM_NUMBER_OF_BYTES_WRITE) -FROM performance_schema.FILE_SUMMARY_BY_EVENT_NAME AS e -JOIN performance_schema.FILE_SUMMARY_BY_INSTANCE AS i USING (EVENT_NAME) +FROM performance_schema.file_summary_by_event_name AS e +JOIN performance_schema.file_summary_by_instance AS i USING (EVENT_NAME) GROUP BY EVENT_NAME HAVING (e.SUM_NUMBER_OF_BYTES_WRITE <> SUM(i.SUM_NUMBER_OF_BYTES_WRITE)) OR @dump_all; @@ -131,23 +131,23 @@ OR @dump_all; --echo "Verifying waits aggregate consistency (instance)" SELECT EVENT_NAME, e.SUM_TIMER_WAIT, SUM(i.SUM_TIMER_WAIT) -FROM performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME AS e -JOIN performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE AS i USING (EVENT_NAME) +FROM performance_schema.events_waits_summary_global_by_event_name AS e +JOIN performance_schema.events_waits_summary_by_instance AS i USING (EVENT_NAME) GROUP BY EVENT_NAME HAVING (e.SUM_TIMER_WAIT < SUM(i.SUM_TIMER_WAIT)) OR @dump_all; SELECT EVENT_NAME, e.MIN_TIMER_WAIT, MIN(i.MIN_TIMER_WAIT) -FROM performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME AS e -JOIN performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE AS i USING (EVENT_NAME) +FROM performance_schema.events_waits_summary_global_by_event_name AS e +JOIN performance_schema.events_waits_summary_by_instance AS i USING (EVENT_NAME) GROUP BY EVENT_NAME HAVING (e.MIN_TIMER_WAIT > MIN(i.MIN_TIMER_WAIT)) AND (MIN(i.MIN_TIMER_WAIT) != 0) OR @dump_all; SELECT EVENT_NAME, e.MAX_TIMER_WAIT, MAX(i.MAX_TIMER_WAIT) -FROM performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME AS e -JOIN performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE AS i USING (EVENT_NAME) +FROM performance_schema.events_waits_summary_global_by_event_name AS e +JOIN performance_schema.events_waits_summary_by_instance AS i USING (EVENT_NAME) GROUP BY EVENT_NAME HAVING (e.MAX_TIMER_WAIT < MAX(i.MAX_TIMER_WAIT)) OR @dump_all; @@ -155,16 +155,16 @@ OR @dump_all; --echo "Verifying waits aggregate consistency (thread)" SELECT EVENT_NAME, e.SUM_TIMER_WAIT, SUM(t.SUM_TIMER_WAIT) -FROM performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME AS e -JOIN performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME AS t +FROM performance_schema.events_waits_summary_global_by_event_name AS e +JOIN performance_schema.events_waits_summary_by_thread_by_event_name AS t USING (EVENT_NAME) GROUP BY EVENT_NAME HAVING (e.SUM_TIMER_WAIT < SUM(t.SUM_TIMER_WAIT)) OR @dump_all; SELECT EVENT_NAME, e.MIN_TIMER_WAIT, MIN(t.MIN_TIMER_WAIT) -FROM performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME AS e -JOIN performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME AS t +FROM performance_schema.events_waits_summary_global_by_event_name AS e +JOIN performance_schema.events_waits_summary_by_thread_by_event_name AS t USING (EVENT_NAME) GROUP BY EVENT_NAME HAVING (e.MIN_TIMER_WAIT > MIN(t.MIN_TIMER_WAIT)) @@ -172,8 +172,8 @@ AND (MIN(t.MIN_TIMER_WAIT) != 0) OR @dump_all; SELECT EVENT_NAME, e.MAX_TIMER_WAIT, MAX(t.MAX_TIMER_WAIT) -FROM performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME AS e -JOIN performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME AS t +FROM performance_schema.events_waits_summary_global_by_event_name AS e +JOIN performance_schema.events_waits_summary_by_thread_by_event_name AS t USING (EVENT_NAME) GROUP BY EVENT_NAME HAVING (e.MAX_TIMER_WAIT < MAX(t.MAX_TIMER_WAIT)) @@ -182,8 +182,8 @@ OR @dump_all; # Cleanup -update performance_schema.SETUP_CONSUMERS set enabled = 'YES'; -update performance_schema.SETUP_INSTRUMENTS +update performance_schema.setup_consumers set enabled = 'YES'; +update performance_schema.setup_instruments set enabled = 'YES', timed = 'YES'; drop table test.t1; diff --git a/mysql-test/suite/perfschema/t/checksum.test b/mysql-test/suite/perfschema/t/checksum.test index d7fdd7b4c2c..0600edcef26 100644 --- a/mysql-test/suite/perfschema/t/checksum.test +++ b/mysql-test/suite/perfschema/t/checksum.test @@ -24,41 +24,41 @@ # --disable_result_log -checksum table performance_schema.COND_INSTANCES; -checksum table performance_schema.EVENTS_WAITS_CURRENT; -checksum table performance_schema.EVENTS_WAITS_HISTORY; -checksum table performance_schema.EVENTS_WAITS_HISTORY_LONG; -checksum table performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE; -checksum table performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME; -checksum table performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME; -checksum table performance_schema.FILE_INSTANCES; -checksum table performance_schema.FILE_SUMMARY_BY_EVENT_NAME; -checksum table performance_schema.FILE_SUMMARY_BY_INSTANCE; -checksum table performance_schema.MUTEX_INSTANCES; -checksum table performance_schema.PERFORMANCE_TIMERS; -checksum table performance_schema.RWLOCK_INSTANCES; -checksum table performance_schema.SETUP_CONSUMERS; -checksum table performance_schema.SETUP_INSTRUMENTS; -checksum table performance_schema.SETUP_TIMERS; -checksum table performance_schema.THREADS; +checksum table performance_schema.cond_instances; +checksum table performance_schema.events_waits_current; +checksum table performance_schema.events_waits_history; +checksum table performance_schema.events_waits_history_long; +checksum table performance_schema.events_waits_summary_by_instance; +checksum table performance_schema.events_waits_summary_by_thread_by_event_name; +checksum table performance_schema.events_waits_summary_global_by_event_name; +checksum table performance_schema.file_instances; +checksum table performance_schema.file_summary_by_event_name; +checksum table performance_schema.file_summary_by_instance; +checksum table performance_schema.mutex_instances; +checksum table performance_schema.performance_timers; +checksum table performance_schema.rwlock_instances; +checksum table performance_schema.setup_consumers; +checksum table performance_schema.setup_instruments; +checksum table performance_schema.setup_timers; +checksum table performance_schema.threads; -checksum table performance_schema.COND_INSTANCES extended; -checksum table performance_schema.EVENTS_WAITS_CURRENT extended; -checksum table performance_schema.EVENTS_WAITS_HISTORY extended; -checksum table performance_schema.EVENTS_WAITS_HISTORY_LONG extended; -checksum table performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE extended; -checksum table performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME extended; -checksum table performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME extended; -checksum table performance_schema.FILE_INSTANCES extended; -checksum table performance_schema.FILE_SUMMARY_BY_EVENT_NAME extended; -checksum table performance_schema.FILE_SUMMARY_BY_INSTANCE extended; -checksum table performance_schema.MUTEX_INSTANCES extended; -checksum table performance_schema.PERFORMANCE_TIMERS extended; -checksum table performance_schema.RWLOCK_INSTANCES extended; -checksum table performance_schema.SETUP_CONSUMERS extended; -checksum table performance_schema.SETUP_INSTRUMENTS extended; -checksum table performance_schema.SETUP_TIMERS extended; -checksum table performance_schema.THREADS extended; +checksum table performance_schema.cond_instances extended; +checksum table performance_schema.events_waits_current extended; +checksum table performance_schema.events_waits_history extended; +checksum table performance_schema.events_waits_history_long extended; +checksum table performance_schema.events_waits_summary_by_instance extended; +checksum table performance_schema.events_waits_summary_by_thread_by_event_name extended; +checksum table performance_schema.events_waits_summary_global_by_event_name extended; +checksum table performance_schema.file_instances extended; +checksum table performance_schema.file_summary_by_event_name extended; +checksum table performance_schema.file_summary_by_instance extended; +checksum table performance_schema.mutex_instances extended; +checksum table performance_schema.performance_timers extended; +checksum table performance_schema.rwlock_instances extended; +checksum table performance_schema.setup_consumers extended; +checksum table performance_schema.setup_instruments extended; +checksum table performance_schema.setup_timers extended; +checksum table performance_schema.threads extended; --enable_result_log diff --git a/mysql-test/suite/perfschema/t/column_privilege.test b/mysql-test/suite/perfschema/t/column_privilege.test index b6bcbdb3396..a1b0ede6b45 100644 --- a/mysql-test/suite/perfschema/t/column_privilege.test +++ b/mysql-test/suite/perfschema/t/column_privilege.test @@ -26,10 +26,10 @@ grant usage on *.* to 'pfs_user_5'@localhost with GRANT OPTION; # Test per column privileges on performance_schema -grant SELECT(thread_id, event_id) on performance_schema.EVENTS_WAITS_CURRENT +grant SELECT(thread_id, event_id) on performance_schema.events_waits_current to 'pfs_user_5'@localhost; -grant UPDATE(enabled) on performance_schema.SETUP_INSTRUMENTS +grant UPDATE(enabled) on performance_schema.setup_instruments to 'pfs_user_5'@localhost; flush privileges; @@ -42,32 +42,28 @@ connect (con1, localhost, pfs_user_5, , ); # For statements that works, we do not look at the output --disable_result_log -select thread_id from performance_schema.EVENTS_WAITS_CURRENT; +select thread_id from performance_schema.events_waits_current; -select thread_id, event_id from performance_schema.EVENTS_WAITS_CURRENT; +select thread_id, event_id from performance_schema.events_waits_current; -update performance_schema.SETUP_INSTRUMENTS set enabled='YES'; +update performance_schema.setup_instruments set enabled='YES'; --enable_result_log # For statements that are denied, check the error number and error text. ---replace_result '\'events_waits_current' '\'EVENTS_WAITS_CURRENT' --error ER_COLUMNACCESS_DENIED_ERROR -select event_name from performance_schema.EVENTS_WAITS_CURRENT; +select event_name from performance_schema.events_waits_current; ---replace_result '\'events_waits_current' '\'EVENTS_WAITS_CURRENT' --error ER_COLUMNACCESS_DENIED_ERROR select thread_id, event_id, event_name - from performance_schema.EVENTS_WAITS_CURRENT; + from performance_schema.events_waits_current; ---replace_result '\'setup_instruments' '\'SETUP_INSTRUMENTS' --error ER_COLUMNACCESS_DENIED_ERROR -update performance_schema.SETUP_INSTRUMENTS set name='illegal'; +update performance_schema.setup_instruments set name='illegal'; ---replace_result '\'setup_instruments' '\'SETUP_INSTRUMENTS' --error ER_COLUMNACCESS_DENIED_ERROR -update performance_schema.SETUP_INSTRUMENTS set timed='NO'; +update performance_schema.setup_instruments set timed='NO'; # Cleanup @@ -76,7 +72,7 @@ update performance_schema.SETUP_INSTRUMENTS set timed='NO'; REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'pfs_user_5'@localhost; DROP USER 'pfs_user_5'@localhost; flush privileges; -UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'YES', timed = 'YES'; -UPDATE performance_schema.SETUP_CONSUMERS SET enabled = 'YES'; -UPDATE performance_schema.SETUP_TIMERS SET timer_name = 'CYCLE'; +UPDATE performance_schema.setup_instruments SET enabled = 'YES', timed = 'YES'; +UPDATE performance_schema.setup_consumers SET enabled = 'YES'; +UPDATE performance_schema.setup_timers SET timer_name = 'CYCLE'; diff --git a/mysql-test/suite/perfschema/t/ddl_cond_instances.test b/mysql-test/suite/perfschema/t/ddl_cond_instances.test index e78429cb181..2da1100702f 100644 --- a/mysql-test/suite/perfschema/t/ddl_cond_instances.test +++ b/mysql-test/suite/perfschema/t/ddl_cond_instances.test @@ -19,14 +19,14 @@ --source include/have_perfschema.inc -- error ER_DBACCESS_DENIED_ERROR -alter table performance_schema.COND_INSTANCES add column foo integer; +alter table performance_schema.cond_instances add column foo integer; -- error ER_WRONG_PERFSCHEMA_USAGE -truncate table performance_schema.COND_INSTANCES; +truncate table performance_schema.cond_instances; -- error ER_DBACCESS_DENIED_ERROR -ALTER TABLE performance_schema.COND_INSTANCES ADD INDEX test_index(NAME); +ALTER TABLE performance_schema.cond_instances ADD INDEX test_index(NAME); -- error ER_DBACCESS_DENIED_ERROR -CREATE UNIQUE INDEX test_index ON performance_schema.COND_INSTANCES(NAME); +CREATE UNIQUE INDEX test_index ON performance_schema.cond_instances(NAME); diff --git a/mysql-test/suite/perfschema/t/ddl_events_waits_current.test b/mysql-test/suite/perfschema/t/ddl_events_waits_current.test index 34f735c1271..1914d333f00 100644 --- a/mysql-test/suite/perfschema/t/ddl_events_waits_current.test +++ b/mysql-test/suite/perfschema/t/ddl_events_waits_current.test @@ -19,13 +19,13 @@ --source include/have_perfschema.inc -- error ER_DBACCESS_DENIED_ERROR -alter table performance_schema.EVENTS_WAITS_CURRENT add column foo integer; +alter table performance_schema.events_waits_current add column foo integer; -truncate table performance_schema.EVENTS_WAITS_CURRENT; +truncate table performance_schema.events_waits_current; -- error ER_DBACCESS_DENIED_ERROR -ALTER TABLE performance_schema.EVENTS_WAITS_CURRENT ADD INDEX test_index(EVENT_ID); +ALTER TABLE performance_schema.events_waits_current ADD INDEX test_index(EVENT_ID); -- error ER_DBACCESS_DENIED_ERROR -CREATE UNIQUE INDEX test_index ON performance_schema.EVENTS_WAITS_CURRENT(EVENT_ID); +CREATE UNIQUE INDEX test_index ON performance_schema.events_waits_current(EVENT_ID); diff --git a/mysql-test/suite/perfschema/t/ddl_events_waits_history.test b/mysql-test/suite/perfschema/t/ddl_events_waits_history.test index 76ebe3d85c4..97c840a350d 100644 --- a/mysql-test/suite/perfschema/t/ddl_events_waits_history.test +++ b/mysql-test/suite/perfschema/t/ddl_events_waits_history.test @@ -19,13 +19,13 @@ --source include/have_perfschema.inc -- error ER_DBACCESS_DENIED_ERROR -alter table performance_schema.EVENTS_WAITS_HISTORY add column foo integer; +alter table performance_schema.events_waits_history add column foo integer; -truncate table performance_schema.EVENTS_WAITS_HISTORY; +truncate table performance_schema.events_waits_history; -- error ER_DBACCESS_DENIED_ERROR -ALTER TABLE performance_schema.EVENTS_WAITS_HISTORY ADD INDEX test_index(EVENT_ID); +ALTER TABLE performance_schema.events_waits_history ADD INDEX test_index(EVENT_ID); -- error ER_DBACCESS_DENIED_ERROR -CREATE UNIQUE INDEX test_index ON performance_schema.EVENTS_WAITS_HISTORY(EVENT_ID); +CREATE UNIQUE INDEX test_index ON performance_schema.events_waits_history(EVENT_ID); diff --git a/mysql-test/suite/perfschema/t/ddl_events_waits_history_long.test b/mysql-test/suite/perfschema/t/ddl_events_waits_history_long.test index 549c5d6880b..b57a3864e1a 100644 --- a/mysql-test/suite/perfschema/t/ddl_events_waits_history_long.test +++ b/mysql-test/suite/perfschema/t/ddl_events_waits_history_long.test @@ -19,13 +19,13 @@ --source include/have_perfschema.inc -- error ER_DBACCESS_DENIED_ERROR -alter table performance_schema.EVENTS_WAITS_HISTORY_LONG add column foo integer; +alter table performance_schema.events_waits_history_long add column foo integer; -truncate table performance_schema.EVENTS_WAITS_HISTORY_LONG; +truncate table performance_schema.events_waits_history_long; -- error ER_DBACCESS_DENIED_ERROR -ALTER TABLE performance_schema.EVENTS_WAITS_HISTORY_LONG ADD INDEX test_index(EVENT_ID); +ALTER TABLE performance_schema.events_waits_history_long ADD INDEX test_index(EVENT_ID); -- error ER_DBACCESS_DENIED_ERROR -CREATE UNIQUE INDEX test_index ON performance_schema.EVENTS_WAITS_HISTORY_LONG(EVENT_ID); +CREATE UNIQUE INDEX test_index ON performance_schema.events_waits_history_long(EVENT_ID); diff --git a/mysql-test/suite/perfschema/t/ddl_ews_by_instance.test b/mysql-test/suite/perfschema/t/ddl_ews_by_instance.test index e6dad07fd63..a6315edd31d 100644 --- a/mysql-test/suite/perfschema/t/ddl_ews_by_instance.test +++ b/mysql-test/suite/perfschema/t/ddl_ews_by_instance.test @@ -19,13 +19,13 @@ --source include/have_perfschema.inc -- error ER_DBACCESS_DENIED_ERROR -alter table performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE add column foo integer; +alter table performance_schema.events_waits_summary_by_instance add column foo integer; -truncate table performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE; +truncate table performance_schema.events_waits_summary_by_instance; -- error ER_DBACCESS_DENIED_ERROR -ALTER TABLE performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE ADD INDEX test_index(EVENT_NAME); +ALTER TABLE performance_schema.events_waits_summary_by_instance ADD INDEX test_index(EVENT_NAME); -- error ER_DBACCESS_DENIED_ERROR -CREATE UNIQUE INDEX test_index ON performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE(EVENT_NAME); +CREATE UNIQUE INDEX test_index ON performance_schema.events_waits_summary_by_instance(EVENT_NAME); diff --git a/mysql-test/suite/perfschema/t/ddl_ews_by_thread_by_event_name.test b/mysql-test/suite/perfschema/t/ddl_ews_by_thread_by_event_name.test index 5b65ec26064..f59daca4b46 100644 --- a/mysql-test/suite/perfschema/t/ddl_ews_by_thread_by_event_name.test +++ b/mysql-test/suite/perfschema/t/ddl_ews_by_thread_by_event_name.test @@ -19,15 +19,15 @@ --source include/have_perfschema.inc -- error ER_DBACCESS_DENIED_ERROR -alter table performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME +alter table performance_schema.events_waits_summary_by_thread_by_event_name add column foo integer; -truncate table performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME; +truncate table performance_schema.events_waits_summary_by_thread_by_event_name; -- error ER_DBACCESS_DENIED_ERROR -ALTER TABLE performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME ADD INDEX test_index(THREAD_ID); +ALTER TABLE performance_schema.events_waits_summary_by_thread_by_event_name ADD INDEX test_index(THREAD_ID); -- error ER_DBACCESS_DENIED_ERROR CREATE UNIQUE INDEX test_index - ON performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME(THREAD_ID); + ON performance_schema.events_waits_summary_by_thread_by_event_name(THREAD_ID); diff --git a/mysql-test/suite/perfschema/t/ddl_ews_global_by_event_name.test b/mysql-test/suite/perfschema/t/ddl_ews_global_by_event_name.test index c7a767b013b..880b4bf1a59 100644 --- a/mysql-test/suite/perfschema/t/ddl_ews_global_by_event_name.test +++ b/mysql-test/suite/perfschema/t/ddl_ews_global_by_event_name.test @@ -19,16 +19,16 @@ --source include/have_perfschema.inc -- error ER_DBACCESS_DENIED_ERROR -alter table performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME +alter table performance_schema.events_waits_summary_global_by_event_name add column foo integer; -truncate table performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME; +truncate table performance_schema.events_waits_summary_global_by_event_name; -- error ER_DBACCESS_DENIED_ERROR -ALTER TABLE performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME +ALTER TABLE performance_schema.events_waits_summary_global_by_event_name ADD INDEX test_index(EVENT_NAME); -- error ER_DBACCESS_DENIED_ERROR CREATE UNIQUE INDEX test_index - ON performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME(EVENT_NAME); + ON performance_schema.events_waits_summary_global_by_event_name(EVENT_NAME); diff --git a/mysql-test/suite/perfschema/t/ddl_file_instances.test b/mysql-test/suite/perfschema/t/ddl_file_instances.test index a9c9a2a95b6..9d6b8c3cf26 100644 --- a/mysql-test/suite/perfschema/t/ddl_file_instances.test +++ b/mysql-test/suite/perfschema/t/ddl_file_instances.test @@ -19,14 +19,14 @@ --source include/have_perfschema.inc -- error ER_DBACCESS_DENIED_ERROR -alter table performance_schema.FILE_INSTANCES add column foo integer; +alter table performance_schema.file_instances add column foo integer; -- error ER_WRONG_PERFSCHEMA_USAGE -truncate table performance_schema.FILE_INSTANCES; +truncate table performance_schema.file_instances; -- error ER_DBACCESS_DENIED_ERROR -ALTER TABLE performance_schema.FILE_INSTANCES ADD INDEX test_index(FILE_NAME); +ALTER TABLE performance_schema.file_instances ADD INDEX test_index(FILE_NAME); -- error ER_DBACCESS_DENIED_ERROR -CREATE UNIQUE INDEX test_index ON performance_schema.FILE_INSTANCES(FILE_NAME); +CREATE UNIQUE INDEX test_index ON performance_schema.file_instances(FILE_NAME); diff --git a/mysql-test/suite/perfschema/t/ddl_fs_by_event_name.test b/mysql-test/suite/perfschema/t/ddl_fs_by_event_name.test index 2581f07c0d2..f9a9cabb5b2 100644 --- a/mysql-test/suite/perfschema/t/ddl_fs_by_event_name.test +++ b/mysql-test/suite/perfschema/t/ddl_fs_by_event_name.test @@ -19,13 +19,13 @@ --source include/have_perfschema.inc -- error ER_DBACCESS_DENIED_ERROR -alter table performance_schema.FILE_SUMMARY_BY_EVENT_NAME add column foo integer; +alter table performance_schema.file_summary_by_event_name add column foo integer; -truncate table performance_schema.FILE_SUMMARY_BY_EVENT_NAME; +truncate table performance_schema.file_summary_by_event_name; -- error ER_DBACCESS_DENIED_ERROR -ALTER TABLE performance_schema.FILE_SUMMARY_BY_EVENT_NAME ADD INDEX test_index(NAME); +ALTER TABLE performance_schema.file_summary_by_event_name ADD INDEX test_index(NAME); -- error ER_DBACCESS_DENIED_ERROR -CREATE UNIQUE INDEX test_index ON performance_schema.FILE_SUMMARY_BY_EVENT_NAME(NAME); +CREATE UNIQUE INDEX test_index ON performance_schema.file_summary_by_event_name(NAME); diff --git a/mysql-test/suite/perfschema/t/ddl_fs_by_instance.test b/mysql-test/suite/perfschema/t/ddl_fs_by_instance.test index e06ad2eb7cd..defbff34321 100644 --- a/mysql-test/suite/perfschema/t/ddl_fs_by_instance.test +++ b/mysql-test/suite/perfschema/t/ddl_fs_by_instance.test @@ -19,13 +19,13 @@ --source include/have_perfschema.inc -- error ER_DBACCESS_DENIED_ERROR -alter table performance_schema.FILE_SUMMARY_BY_INSTANCE add column foo integer; +alter table performance_schema.file_summary_by_instance add column foo integer; -truncate table performance_schema.FILE_SUMMARY_BY_INSTANCE; +truncate table performance_schema.file_summary_by_instance; -- error ER_DBACCESS_DENIED_ERROR -ALTER TABLE performance_schema.FILE_SUMMARY_BY_INSTANCE ADD INDEX test_index(NAME); +ALTER TABLE performance_schema.file_summary_by_instance ADD INDEX test_index(NAME); -- error ER_DBACCESS_DENIED_ERROR -CREATE UNIQUE INDEX test_index ON performance_schema.FILE_SUMMARY_BY_INSTANCE(NAME); +CREATE UNIQUE INDEX test_index ON performance_schema.file_summary_by_instance(NAME); diff --git a/mysql-test/suite/perfschema/t/ddl_mutex_instances.test b/mysql-test/suite/perfschema/t/ddl_mutex_instances.test index 6489a689620..ccd970655af 100644 --- a/mysql-test/suite/perfschema/t/ddl_mutex_instances.test +++ b/mysql-test/suite/perfschema/t/ddl_mutex_instances.test @@ -19,14 +19,14 @@ --source include/have_perfschema.inc -- error ER_DBACCESS_DENIED_ERROR -alter table performance_schema.MUTEX_INSTANCES add column foo integer; +alter table performance_schema.mutex_instances add column foo integer; -- error ER_WRONG_PERFSCHEMA_USAGE -truncate table performance_schema.MUTEX_INSTANCES; +truncate table performance_schema.mutex_instances; -- error ER_DBACCESS_DENIED_ERROR -ALTER TABLE performance_schema.MUTEX_INSTANCES ADD INDEX test_index(NAME); +ALTER TABLE performance_schema.mutex_instances ADD INDEX test_index(NAME); -- error ER_DBACCESS_DENIED_ERROR -CREATE UNIQUE INDEX test_index ON performance_schema.MUTEX_INSTANCES(NAME); +CREATE UNIQUE INDEX test_index ON performance_schema.mutex_instances(NAME); diff --git a/mysql-test/suite/perfschema/t/ddl_performance_timers.test b/mysql-test/suite/perfschema/t/ddl_performance_timers.test index b692291b8cf..f6fcfd58bab 100644 --- a/mysql-test/suite/perfschema/t/ddl_performance_timers.test +++ b/mysql-test/suite/perfschema/t/ddl_performance_timers.test @@ -19,14 +19,14 @@ --source include/have_perfschema.inc -- error ER_DBACCESS_DENIED_ERROR -alter table performance_schema.PERFORMANCE_TIMERS add column foo integer; +alter table performance_schema.performance_timers add column foo integer; -- error ER_WRONG_PERFSCHEMA_USAGE -truncate table performance_schema.PERFORMANCE_TIMERS; +truncate table performance_schema.performance_timers; -- error ER_DBACCESS_DENIED_ERROR -ALTER TABLE performance_schema.PERFORMANCE_TIMERS ADD INDEX test_index(TIMER_NAME); +ALTER TABLE performance_schema.performance_timers ADD INDEX test_index(TIMER_NAME); -- error ER_DBACCESS_DENIED_ERROR -CREATE UNIQUE INDEX test_index ON performance_schema.PERFORMANCE_TIMERS(TIMER_NAME); +CREATE UNIQUE INDEX test_index ON performance_schema.performance_timers(TIMER_NAME); diff --git a/mysql-test/suite/perfschema/t/ddl_rwlock_instances.test b/mysql-test/suite/perfschema/t/ddl_rwlock_instances.test index c07cd1ede48..e5bd8b890a1 100644 --- a/mysql-test/suite/perfschema/t/ddl_rwlock_instances.test +++ b/mysql-test/suite/perfschema/t/ddl_rwlock_instances.test @@ -19,14 +19,14 @@ --source include/have_perfschema.inc -- error ER_DBACCESS_DENIED_ERROR -alter table performance_schema.RWLOCK_INSTANCES add column foo integer; +alter table performance_schema.rwlock_instances add column foo integer; -- error ER_WRONG_PERFSCHEMA_USAGE -truncate table performance_schema.RWLOCK_INSTANCES; +truncate table performance_schema.rwlock_instances; -- error ER_DBACCESS_DENIED_ERROR -ALTER TABLE performance_schema.RWLOCK_INSTANCES ADD INDEX test_index(NAME); +ALTER TABLE performance_schema.rwlock_instances ADD INDEX test_index(NAME); -- error ER_DBACCESS_DENIED_ERROR -CREATE UNIQUE INDEX test_index ON performance_schema.RWLOCK_INSTANCES(NAME); +CREATE UNIQUE INDEX test_index ON performance_schema.rwlock_instances(NAME); diff --git a/mysql-test/suite/perfschema/t/ddl_setup_consumers.test b/mysql-test/suite/perfschema/t/ddl_setup_consumers.test index c44db822145..3984e0b7fab 100644 --- a/mysql-test/suite/perfschema/t/ddl_setup_consumers.test +++ b/mysql-test/suite/perfschema/t/ddl_setup_consumers.test @@ -18,16 +18,15 @@ --source include/not_embedded.inc --source include/have_perfschema.inc ---replace_result '\'setup_consumers' '\'SETUP_CONSUMERS' -- error ER_DBACCESS_DENIED_ERROR -alter table performance_schema.SETUP_CONSUMERS add column foo integer; +alter table performance_schema.setup_consumers add column foo integer; -- error ER_WRONG_PERFSCHEMA_USAGE -truncate table performance_schema.SETUP_CONSUMERS; +truncate table performance_schema.setup_consumers; -- error ER_DBACCESS_DENIED_ERROR -ALTER TABLE performance_schema.SETUP_CONSUMERS ADD INDEX test_index(NAME); +ALTER TABLE performance_schema.setup_consumers ADD INDEX test_index(NAME); -- error ER_DBACCESS_DENIED_ERROR -CREATE UNIQUE INDEX test_index ON performance_schema.SETUP_CONSUMERS(NAME); +CREATE UNIQUE INDEX test_index ON performance_schema.setup_consumers(NAME); diff --git a/mysql-test/suite/perfschema/t/ddl_setup_instruments.test b/mysql-test/suite/perfschema/t/ddl_setup_instruments.test index c20c386447c..b900f69e801 100644 --- a/mysql-test/suite/perfschema/t/ddl_setup_instruments.test +++ b/mysql-test/suite/perfschema/t/ddl_setup_instruments.test @@ -18,16 +18,15 @@ --source include/not_embedded.inc --source include/have_perfschema.inc ---replace_result '\'setup_instruments' '\'SETUP_INSTRUMENTS' -- error ER_DBACCESS_DENIED_ERROR -alter table performance_schema.SETUP_INSTRUMENTS add column foo integer; +alter table performance_schema.setup_instruments add column foo integer; -- error ER_WRONG_PERFSCHEMA_USAGE -truncate table performance_schema.SETUP_INSTRUMENTS; +truncate table performance_schema.setup_instruments; -- error ER_DBACCESS_DENIED_ERROR -ALTER TABLE performance_schema.SETUP_INSTRUMENTS ADD INDEX test_index(NAME); +ALTER TABLE performance_schema.setup_instruments ADD INDEX test_index(NAME); -- error ER_DBACCESS_DENIED_ERROR -CREATE UNIQUE INDEX test_index ON performance_schema.SETUP_INSTRUMENTS(NAME); +CREATE UNIQUE INDEX test_index ON performance_schema.setup_instruments(NAME); diff --git a/mysql-test/suite/perfschema/t/ddl_setup_timers.test b/mysql-test/suite/perfschema/t/ddl_setup_timers.test index b9a5c32ecbe..bf8878a496d 100644 --- a/mysql-test/suite/perfschema/t/ddl_setup_timers.test +++ b/mysql-test/suite/perfschema/t/ddl_setup_timers.test @@ -18,16 +18,15 @@ --source include/not_embedded.inc --source include/have_perfschema.inc ---replace_result '\'setup_timers' '\'SETUP_TIMERS' -- error ER_DBACCESS_DENIED_ERROR -alter table performance_schema.SETUP_TIMERS add column foo integer; +alter table performance_schema.setup_timers add column foo integer; -- error ER_WRONG_PERFSCHEMA_USAGE -truncate table performance_schema.SETUP_TIMERS; +truncate table performance_schema.setup_timers; -- error ER_DBACCESS_DENIED_ERROR -ALTER TABLE performance_schema.SETUP_TIMERS ADD INDEX test_index(NAME); +ALTER TABLE performance_schema.setup_timers ADD INDEX test_index(NAME); -- error ER_DBACCESS_DENIED_ERROR -CREATE UNIQUE INDEX test_index ON performance_schema.SETUP_TIMERS(NAME); +CREATE UNIQUE INDEX test_index ON performance_schema.setup_timers(NAME); diff --git a/mysql-test/suite/perfschema/t/ddl_threads.test b/mysql-test/suite/perfschema/t/ddl_threads.test index 12613e30c1f..d9ff3356b8d 100644 --- a/mysql-test/suite/perfschema/t/ddl_threads.test +++ b/mysql-test/suite/perfschema/t/ddl_threads.test @@ -19,14 +19,14 @@ --source include/have_perfschema.inc -- error ER_DBACCESS_DENIED_ERROR -alter table performance_schema.THREADS add column foo integer; +alter table performance_schema.threads add column foo integer; -- error ER_WRONG_PERFSCHEMA_USAGE -truncate table performance_schema.THREADS; +truncate table performance_schema.threads; -- error ER_DBACCESS_DENIED_ERROR -ALTER TABLE performance_schema.THREADS ADD INDEX test_index(ID); +ALTER TABLE performance_schema.threads ADD INDEX test_index(ID); -- error ER_DBACCESS_DENIED_ERROR -CREATE UNIQUE INDEX test_index ON performance_schema.THREADS(ID); +CREATE UNIQUE INDEX test_index ON performance_schema.threads(ID); diff --git a/mysql-test/suite/perfschema/t/dml_cond_instances.test b/mysql-test/suite/perfschema/t/dml_cond_instances.test index 1d1614db73f..528dae80dfa 100644 --- a/mysql-test/suite/perfschema/t/dml_cond_instances.test +++ b/mysql-test/suite/perfschema/t/dml_cond_instances.test @@ -19,37 +19,31 @@ --source include/have_perfschema.inc --replace_column 1 # 2 # -select * from performance_schema.COND_INSTANCES limit 1; +select * from performance_schema.cond_instances limit 1; -select * from performance_schema.COND_INSTANCES +select * from performance_schema.cond_instances where name='FOO'; ---replace_result '\'cond_instances' '\'COND_INSTANCES' --error ER_TABLEACCESS_DENIED_ERROR -insert into performance_schema.COND_INSTANCES +insert into performance_schema.cond_instances set name='FOO', object_instance_begin=12; ---replace_result '\'cond_instances' '\'COND_INSTANCES' --error ER_TABLEACCESS_DENIED_ERROR -update performance_schema.COND_INSTANCES +update performance_schema.cond_instances set name='FOO'; ---replace_result '\'cond_instances' '\'COND_INSTANCES' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.COND_INSTANCES +delete from performance_schema.cond_instances where name like "wait/%"; ---replace_result '\'cond_instances' '\'COND_INSTANCES' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.COND_INSTANCES; +delete from performance_schema.cond_instances; ---replace_result '\'cond_instances' '\'COND_INSTANCES' -- error ER_TABLEACCESS_DENIED_ERROR -LOCK TABLES performance_schema.COND_INSTANCES READ; +LOCK TABLES performance_schema.cond_instances READ; UNLOCK TABLES; ---replace_result '\'cond_instances' '\'COND_INSTANCES' -- error ER_TABLEACCESS_DENIED_ERROR -LOCK TABLES performance_schema.COND_INSTANCES WRITE; +LOCK TABLES performance_schema.cond_instances WRITE; UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/t/dml_events_waits_current.test b/mysql-test/suite/perfschema/t/dml_events_waits_current.test index 3a93b98cb57..f82fac63df9 100644 --- a/mysql-test/suite/perfschema/t/dml_events_waits_current.test +++ b/mysql-test/suite/perfschema/t/dml_events_waits_current.test @@ -19,44 +19,37 @@ --source include/have_perfschema.inc --replace_column 1 # 2 # 3 # 4 # 5 # 6 # 7 # 8 # 12 # 14 # -select * from performance_schema.EVENTS_WAITS_CURRENT +select * from performance_schema.events_waits_current where event_name like 'Wait/Synch/%' limit 1; -select * from performance_schema.EVENTS_WAITS_CURRENT +select * from performance_schema.events_waits_current where event_name='FOO'; ---replace_result '\'events_waits_current' '\'EVENTS_WAITS_CURRENT' --error ER_TABLEACCESS_DENIED_ERROR -insert into performance_schema.EVENTS_WAITS_CURRENT +insert into performance_schema.events_waits_current set thread_id='1', event_id=1, event_name='FOO', timer_start=1, timer_end=2, timer_wait=3; ---replace_result '\'events_waits_current' '\'EVENTS_WAITS_CURRENT' --error ER_TABLEACCESS_DENIED_ERROR -update performance_schema.EVENTS_WAITS_CURRENT +update performance_schema.events_waits_current set timer_start=12; ---replace_result '\'events_waits_current' '\'EVENTS_WAITS_CURRENT' --error ER_TABLEACCESS_DENIED_ERROR -update performance_schema.EVENTS_WAITS_CURRENT +update performance_schema.events_waits_current set timer_start=12 where thread_id=0; ---replace_result '\'events_waits_current' '\'EVENTS_WAITS_CURRENT' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.EVENTS_WAITS_CURRENT +delete from performance_schema.events_waits_current where thread_id=1; ---replace_result '\'events_waits_current' '\'EVENTS_WAITS_CURRENT' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.EVENTS_WAITS_CURRENT; +delete from performance_schema.events_waits_current; ---replace_result '\'events_waits_current' '\'EVENTS_WAITS_CURRENT' -- error ER_TABLEACCESS_DENIED_ERROR -LOCK TABLES performance_schema.EVENTS_WAITS_CURRENT READ; +LOCK TABLES performance_schema.events_waits_current READ; UNLOCK TABLES; ---replace_result '\'events_waits_current' '\'EVENTS_WAITS_CURRENT' -- error ER_TABLEACCESS_DENIED_ERROR -LOCK TABLES performance_schema.EVENTS_WAITS_CURRENT WRITE; +LOCK TABLES performance_schema.events_waits_current WRITE; UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/t/dml_events_waits_history.test b/mysql-test/suite/perfschema/t/dml_events_waits_history.test index 174ef2147d1..865d261d7f9 100644 --- a/mysql-test/suite/perfschema/t/dml_events_waits_history.test +++ b/mysql-test/suite/perfschema/t/dml_events_waits_history.test @@ -19,52 +19,45 @@ --source include/have_perfschema.inc --replace_column 1 # 2 # 3 # 4 # 5 # 6 # 7 # 8 # 12 # 14 # -select * from performance_schema.EVENTS_WAITS_HISTORY +select * from performance_schema.events_waits_history where event_name like 'Wait/Synch/%' limit 1; -select * from performance_schema.EVENTS_WAITS_HISTORY +select * from performance_schema.events_waits_history where event_name='FOO'; --replace_column 1 # 2 # 3 # 4 # 5 # 6 # 7 # 8 # 12 # 14 # -select * from performance_schema.EVENTS_WAITS_HISTORY +select * from performance_schema.events_waits_history where event_name like 'Wait/Synch/%' order by timer_wait limit 1; --replace_column 1 # 2 # 3 # 4 # 5 # 6 # 7 # 8 # 12 # 14 # -select * from performance_schema.EVENTS_WAITS_HISTORY +select * from performance_schema.events_waits_history where event_name like 'Wait/Synch/%' order by timer_wait desc limit 1; ---replace_result '\'events_waits_history' '\'EVENTS_WAITS_HISTORY' --error ER_TABLEACCESS_DENIED_ERROR -insert into performance_schema.EVENTS_WAITS_HISTORY +insert into performance_schema.events_waits_history set thread_id='1', event_id=1, event_name='FOO', timer_start=1, timer_end=2, timer_wait=3; ---replace_result '\'events_waits_history' '\'EVENTS_WAITS_HISTORY' --error ER_TABLEACCESS_DENIED_ERROR -update performance_schema.EVENTS_WAITS_HISTORY +update performance_schema.events_waits_history set timer_start=12; ---replace_result '\'events_waits_history' '\'EVENTS_WAITS_HISTORY' --error ER_TABLEACCESS_DENIED_ERROR -update performance_schema.EVENTS_WAITS_HISTORY +update performance_schema.events_waits_history set timer_start=12 where thread_id=0; ---replace_result '\'events_waits_history' '\'EVENTS_WAITS_HISTORY' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.EVENTS_WAITS_HISTORY +delete from performance_schema.events_waits_history where thread_id=1; ---replace_result '\'events_waits_history' '\'EVENTS_WAITS_HISTORY' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.EVENTS_WAITS_HISTORY; +delete from performance_schema.events_waits_history; ---replace_result '\'events_waits_history' '\'EVENTS_WAITS_HISTORY' -- error ER_TABLEACCESS_DENIED_ERROR -LOCK TABLES performance_schema.EVENTS_WAITS_HISTORY READ; +LOCK TABLES performance_schema.events_waits_history READ; UNLOCK TABLES; ---replace_result '\'events_waits_history' '\'EVENTS_WAITS_HISTORY' -- error ER_TABLEACCESS_DENIED_ERROR -LOCK TABLES performance_schema.EVENTS_WAITS_HISTORY WRITE; +LOCK TABLES performance_schema.events_waits_history WRITE; UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/t/dml_events_waits_history_long.test b/mysql-test/suite/perfschema/t/dml_events_waits_history_long.test index 73dc0aefd06..606e33b3e80 100644 --- a/mysql-test/suite/perfschema/t/dml_events_waits_history_long.test +++ b/mysql-test/suite/perfschema/t/dml_events_waits_history_long.test @@ -19,52 +19,45 @@ --source include/have_perfschema.inc --replace_column 1 # 2 # 3 # 4 # 5 # 6 # 7 # 8 # 12 # 14 # -select * from performance_schema.EVENTS_WAITS_HISTORY_LONG +select * from performance_schema.events_waits_history_long where event_name like 'Wait/Synch/%' limit 1; -select * from performance_schema.EVENTS_WAITS_HISTORY_LONG +select * from performance_schema.events_waits_history_long where event_name='FOO'; --replace_column 1 # 2 # 3 # 4 # 5 # 6 # 7 # 8 # 12 # 14 # -select * from performance_schema.EVENTS_WAITS_HISTORY_LONG +select * from performance_schema.events_waits_history_long where event_name like 'Wait/Synch/%' order by timer_wait limit 1; --replace_column 1 # 2 # 3 # 4 # 5 # 6 # 7 # 8 # 12 # 14 # -select * from performance_schema.EVENTS_WAITS_HISTORY_LONG +select * from performance_schema.events_waits_history_long where event_name like 'Wait/Synch/%' order by timer_wait desc limit 1; ---replace_result '\'events_waits_history_long' '\'EVENTS_WAITS_HISTORY_LONG' --error ER_TABLEACCESS_DENIED_ERROR -insert into performance_schema.EVENTS_WAITS_HISTORY_LONG +insert into performance_schema.events_waits_history_long set thread_id='1', event_id=1, event_name='FOO', timer_start=1, timer_end=2, timer_wait=3; ---replace_result '\'events_waits_history_long' '\'EVENTS_WAITS_HISTORY_LONG' --error ER_TABLEACCESS_DENIED_ERROR -update performance_schema.EVENTS_WAITS_HISTORY_LONG +update performance_schema.events_waits_history_long set timer_start=12; ---replace_result '\'events_waits_history_long' '\'EVENTS_WAITS_HISTORY_LONG' --error ER_TABLEACCESS_DENIED_ERROR -update performance_schema.EVENTS_WAITS_HISTORY_LONG +update performance_schema.events_waits_history_long set timer_start=12 where thread_id=0; ---replace_result '\'events_waits_history_long' '\'EVENTS_WAITS_HISTORY_LONG' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.EVENTS_WAITS_HISTORY_LONG +delete from performance_schema.events_waits_history_long where thread_id=1; ---replace_result '\'events_waits_history_long' '\'EVENTS_WAITS_HISTORY_LONG' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.EVENTS_WAITS_HISTORY_LONG; +delete from performance_schema.events_waits_history_long; ---replace_result '\'events_waits_history_long' '\'EVENTS_WAITS_HISTORY_LONG' -- error ER_TABLEACCESS_DENIED_ERROR -LOCK TABLES performance_schema.EVENTS_WAITS_HISTORY_LONG READ; +LOCK TABLES performance_schema.events_waits_history_long READ; UNLOCK TABLES; ---replace_result '\'events_waits_history_long' '\'EVENTS_WAITS_HISTORY_LONG' -- error ER_TABLEACCESS_DENIED_ERROR -LOCK TABLES performance_schema.EVENTS_WAITS_HISTORY_LONG WRITE; +LOCK TABLES performance_schema.events_waits_history_long WRITE; UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/t/dml_ews_by_instance.test b/mysql-test/suite/perfschema/t/dml_ews_by_instance.test index 4c386313bc5..2e4ab9bcc74 100644 --- a/mysql-test/suite/perfschema/t/dml_ews_by_instance.test +++ b/mysql-test/suite/perfschema/t/dml_ews_by_instance.test @@ -19,61 +19,54 @@ --source include/have_perfschema.inc --replace_column 1 # 2 # 3 # 4 # 5 # 6 # 7 # -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE +select * from performance_schema.events_waits_summary_by_instance where event_name like 'Wait/Synch/%' limit 1; -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE +select * from performance_schema.events_waits_summary_by_instance where event_name='FOO'; --replace_column 1 # 2 # 3 # 4 # 5 # 6 # 7 # -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE +select * from performance_schema.events_waits_summary_by_instance order by count_star limit 1; --replace_column 1 # 2 # 3 # 4 # 5 # 6 # 7 # -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE +select * from performance_schema.events_waits_summary_by_instance order by count_star desc limit 1; --replace_column 1 # 2 # 3 # 4 # 5 # 6 # 7 # -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE +select * from performance_schema.events_waits_summary_by_instance where min_timer_wait > 0 order by count_star limit 1; --replace_column 1 # 2 # 3 # 4 # 5 # 6 # 7 # -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE +select * from performance_schema.events_waits_summary_by_instance where min_timer_wait > 0 order by count_star desc limit 1; ---replace_result '\'events_waits_summary_by_instance' '\'EVENTS_WAITS_SUMMARY_BY_INSTANCE' --error ER_TABLEACCESS_DENIED_ERROR -insert into performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE +insert into performance_schema.events_waits_summary_by_instance set event_name='FOO', object_instance_begin=0, count_star=1, sum_timer_wait=2, min_timer_wait=3, avg_timer_wait=4, max_timer_wait=5; ---replace_result '\'events_waits_summary_by_instance' '\'EVENTS_WAITS_SUMMARY_BY_INSTANCE' --error ER_TABLEACCESS_DENIED_ERROR -update performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE +update performance_schema.events_waits_summary_by_instance set count_star=12; ---replace_result '\'events_waits_summary_by_instance' '\'EVENTS_WAITS_SUMMARY_BY_INSTANCE' --error ER_TABLEACCESS_DENIED_ERROR -update performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE +update performance_schema.events_waits_summary_by_instance set count_star=12 where event_name like "FOO"; ---replace_result '\'events_waits_summary_by_instance' '\'EVENTS_WAITS_SUMMARY_BY_INSTANCE' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE +delete from performance_schema.events_waits_summary_by_instance where count_star=1; ---replace_result '\'events_waits_summary_by_instance' '\'EVENTS_WAITS_SUMMARY_BY_INSTANCE' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE; +delete from performance_schema.events_waits_summary_by_instance; ---replace_result '\'events_waits_summary_by_instance' '\'EVENTS_WAITS_SUMMARY_BY_INSTANCE' -- error ER_TABLEACCESS_DENIED_ERROR -LOCK TABLES performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE READ; +LOCK TABLES performance_schema.events_waits_summary_by_instance READ; UNLOCK TABLES; ---replace_result '\'events_waits_summary_by_instance' '\'EVENTS_WAITS_SUMMARY_BY_INSTANCE' -- error ER_TABLEACCESS_DENIED_ERROR -LOCK TABLES performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE WRITE; +LOCK TABLES performance_schema.events_waits_summary_by_instance WRITE; UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/t/dml_ews_by_thread_by_event_name.test b/mysql-test/suite/perfschema/t/dml_ews_by_thread_by_event_name.test index ce29e59d014..bdbee9a90c1 100644 --- a/mysql-test/suite/perfschema/t/dml_ews_by_thread_by_event_name.test +++ b/mysql-test/suite/perfschema/t/dml_ews_by_thread_by_event_name.test @@ -19,45 +19,38 @@ --source include/have_perfschema.inc --replace_column 1 # 2 # 3 # 4 # 5 # 6 # 7 # -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME +select * from performance_schema.events_waits_summary_by_thread_by_event_name where event_name like 'Wait/Synch/%' limit 1; -select * from performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME +select * from performance_schema.events_waits_summary_by_thread_by_event_name where event_name='FOO'; ---replace_result '\'events_waits_summary_by_thread_by_event_name' '\'EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME' --error ER_TABLEACCESS_DENIED_ERROR -insert into performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME +insert into performance_schema.events_waits_summary_by_thread_by_event_name set event_name='FOO', thread_id=1, count_star=1, sum_timer_wait=2, min_timer_wait=3, avg_timer_wait=4, max_timer_wait=5; ---replace_result '\'events_waits_summary_by_thread_by_event_name' '\'EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME' --error ER_TABLEACCESS_DENIED_ERROR -update performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME +update performance_schema.events_waits_summary_by_thread_by_event_name set count_star=12; ---replace_result '\'events_waits_summary_by_thread_by_event_name' '\'EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME' --error ER_TABLEACCESS_DENIED_ERROR -update performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME +update performance_schema.events_waits_summary_by_thread_by_event_name set count_star=12 where event_name like "FOO"; ---replace_result '\'events_waits_summary_by_thread_by_event_name' '\'EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME +delete from performance_schema.events_waits_summary_by_thread_by_event_name where count_star=1; ---replace_result '\'events_waits_summary_by_thread_by_event_name' '\'EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME; +delete from performance_schema.events_waits_summary_by_thread_by_event_name; ---replace_result '\'events_waits_summary_by_thread_by_event_name' '\'EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME' -- error ER_TABLEACCESS_DENIED_ERROR -LOCK TABLES performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME READ; +LOCK TABLES performance_schema.events_waits_summary_by_thread_by_event_name READ; UNLOCK TABLES; ---replace_result '\'events_waits_summary_by_thread_by_event_name' '\'EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME' -- error ER_TABLEACCESS_DENIED_ERROR -LOCK TABLES performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME WRITE; +LOCK TABLES performance_schema.events_waits_summary_by_thread_by_event_name WRITE; UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/t/dml_ews_global_by_event_name.test b/mysql-test/suite/perfschema/t/dml_ews_global_by_event_name.test index cd3918f38be..4f1b50bb7c0 100644 --- a/mysql-test/suite/perfschema/t/dml_ews_global_by_event_name.test +++ b/mysql-test/suite/perfschema/t/dml_ews_global_by_event_name.test @@ -19,44 +19,37 @@ --source include/have_perfschema.inc --replace_column 1 # 2 # 3 # 4 # 5 # 6 # -select * from performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME +select * from performance_schema.events_waits_summary_global_by_event_name where event_name like 'Wait/Synch/%' limit 1; -select * from performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME +select * from performance_schema.events_waits_summary_global_by_event_name where event_name='FOO'; ---replace_result '\'events_waits_summary_global_by_event_name' '\'EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME' --error ER_TABLEACCESS_DENIED_ERROR -insert into performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME +insert into performance_schema.events_waits_summary_global_by_event_name set event_name='FOO', count_star=1, sum_timer_wait=2, min_timer_wait=3, avg_timer_wait=4, max_timer_wait=5; ---replace_result '\'events_waits_summary_global_by_event_name' '\'EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME' --error ER_TABLEACCESS_DENIED_ERROR -update performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME +update performance_schema.events_waits_summary_global_by_event_name set count_star=12; ---replace_result '\'events_waits_summary_global_by_event_name' '\'EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME' --error ER_TABLEACCESS_DENIED_ERROR -update performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME +update performance_schema.events_waits_summary_global_by_event_name set count_star=12 where event_name like "FOO"; ---replace_result '\'events_waits_summary_global_by_event_name' '\'EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME +delete from performance_schema.events_waits_summary_global_by_event_name where count_star=1; ---replace_result '\'events_waits_summary_global_by_event_name' '\'EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME; +delete from performance_schema.events_waits_summary_global_by_event_name; ---replace_result '\'events_waits_summary_global_by_event_name' '\'EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME' -- error ER_TABLEACCESS_DENIED_ERROR -LOCK TABLES performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME READ; +LOCK TABLES performance_schema.events_waits_summary_global_by_event_name READ; UNLOCK TABLES; ---replace_result '\'events_waits_summary_global_by_event_name' '\'EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME' -- error ER_TABLEACCESS_DENIED_ERROR -LOCK TABLES performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME WRITE; +LOCK TABLES performance_schema.events_waits_summary_global_by_event_name WRITE; UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/t/dml_file_instances.test b/mysql-test/suite/perfschema/t/dml_file_instances.test index 71a053c21be..f3a13eaee32 100644 --- a/mysql-test/suite/perfschema/t/dml_file_instances.test +++ b/mysql-test/suite/perfschema/t/dml_file_instances.test @@ -19,37 +19,31 @@ --source include/have_perfschema.inc --replace_column 1 # 2 # 3 # -select * from performance_schema.FILE_INSTANCES limit 1; +select * from performance_schema.file_instances limit 1; -select * from performance_schema.FILE_INSTANCES +select * from performance_schema.file_instances where file_name='FOO'; ---replace_result '\'file_instances' '\'FILE_INSTANCES' --error ER_TABLEACCESS_DENIED_ERROR -insert into performance_schema.FILE_INSTANCES +insert into performance_schema.file_instances set file_name='FOO', event_name='BAR', open_count=12; ---replace_result '\'file_instances' '\'FILE_INSTANCES' --error ER_TABLEACCESS_DENIED_ERROR -update performance_schema.FILE_INSTANCES +update performance_schema.file_instances set file_name='FOO'; ---replace_result '\'file_instances' '\'FILE_INSTANCES' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.FILE_INSTANCES +delete from performance_schema.file_instances where event_name like "wait/%"; ---replace_result '\'file_instances' '\'FILE_INSTANCES' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.FILE_INSTANCES; +delete from performance_schema.file_instances; ---replace_result '\'file_instances' '\'FILE_INSTANCES' -- error ER_TABLEACCESS_DENIED_ERROR -LOCK TABLES performance_schema.FILE_INSTANCES READ; +LOCK TABLES performance_schema.file_instances READ; UNLOCK TABLES; ---replace_result '\'file_instances' '\'FILE_INSTANCES' -- error ER_TABLEACCESS_DENIED_ERROR -LOCK TABLES performance_schema.FILE_INSTANCES WRITE; +LOCK TABLES performance_schema.file_instances WRITE; UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/t/dml_file_summary_by_event_name.test b/mysql-test/suite/perfschema/t/dml_file_summary_by_event_name.test index 3753f581560..f5e1f90e9c9 100644 --- a/mysql-test/suite/perfschema/t/dml_file_summary_by_event_name.test +++ b/mysql-test/suite/perfschema/t/dml_file_summary_by_event_name.test @@ -19,44 +19,37 @@ --source include/have_perfschema.inc --replace_column 1 # 2 # 3 # 4 # 5 # -select * from performance_schema.FILE_SUMMARY_BY_EVENT_NAME +select * from performance_schema.file_summary_by_event_name where event_name like 'Wait/io/%' limit 1; -select * from performance_schema.FILE_SUMMARY_BY_EVENT_NAME +select * from performance_schema.file_summary_by_event_name where event_name='FOO'; ---replace_result '\'file_summary_by_event_name' '\'FILE_SUMMARY_BY_EVENT_NAME' --error ER_TABLEACCESS_DENIED_ERROR -insert into performance_schema.FILE_SUMMARY_BY_EVENT_NAME +insert into performance_schema.file_summary_by_event_name set event_name='FOO', count_read=1, count_write=2, sum_number_of_bytes_read=4, sum_number_of_bytes_write=5; ---replace_result '\'file_summary_by_event_name' '\'FILE_SUMMARY_BY_EVENT_NAME' --error ER_TABLEACCESS_DENIED_ERROR -update performance_schema.FILE_SUMMARY_BY_EVENT_NAME +update performance_schema.file_summary_by_event_name set count_read=12; ---replace_result '\'file_summary_by_event_name' '\'FILE_SUMMARY_BY_EVENT_NAME' --error ER_TABLEACCESS_DENIED_ERROR -update performance_schema.FILE_SUMMARY_BY_EVENT_NAME +update performance_schema.file_summary_by_event_name set count_write=12 where event_name like "FOO"; ---replace_result '\'file_summary_by_event_name' '\'FILE_SUMMARY_BY_EVENT_NAME' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.FILE_SUMMARY_BY_EVENT_NAME +delete from performance_schema.file_summary_by_event_name where count_read=1; ---replace_result '\'file_summary_by_event_name' '\'FILE_SUMMARY_BY_EVENT_NAME' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.FILE_SUMMARY_BY_EVENT_NAME; +delete from performance_schema.file_summary_by_event_name; ---replace_result '\'file_summary_by_event_name' '\'FILE_SUMMARY_BY_EVENT_NAME' -- error ER_TABLEACCESS_DENIED_ERROR -LOCK TABLES performance_schema.FILE_SUMMARY_BY_EVENT_NAME READ; +LOCK TABLES performance_schema.file_summary_by_event_name READ; UNLOCK TABLES; ---replace_result '\'file_summary_by_event_name' '\'FILE_SUMMARY_BY_EVENT_NAME' -- error ER_TABLEACCESS_DENIED_ERROR -LOCK TABLES performance_schema.FILE_SUMMARY_BY_EVENT_NAME WRITE; +LOCK TABLES performance_schema.file_summary_by_event_name WRITE; UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/t/dml_file_summary_by_instance.test b/mysql-test/suite/perfschema/t/dml_file_summary_by_instance.test index 07372af5f36..2ac32b97f56 100644 --- a/mysql-test/suite/perfschema/t/dml_file_summary_by_instance.test +++ b/mysql-test/suite/perfschema/t/dml_file_summary_by_instance.test @@ -19,44 +19,37 @@ --source include/have_perfschema.inc --replace_column 1 # 2 # 3 # 4 # 5 # 6 # -select * from performance_schema.FILE_SUMMARY_BY_INSTANCE +select * from performance_schema.file_summary_by_instance where event_name like 'Wait/io/%' limit 1; -select * from performance_schema.FILE_SUMMARY_BY_INSTANCE +select * from performance_schema.file_summary_by_instance where event_name='FOO'; ---replace_result '\'file_summary_by_instance' '\'FILE_SUMMARY_BY_INSTANCE' --error ER_TABLEACCESS_DENIED_ERROR -insert into performance_schema.FILE_SUMMARY_BY_INSTANCE +insert into performance_schema.file_summary_by_instance set event_name='FOO', count_read=1, count_write=2, sum_number_of_bytes_read=4, sum_number_of_bytes_write=5; ---replace_result '\'file_summary_by_instance' '\'FILE_SUMMARY_BY_INSTANCE' --error ER_TABLEACCESS_DENIED_ERROR -update performance_schema.FILE_SUMMARY_BY_INSTANCE +update performance_schema.file_summary_by_instance set count_read=12; ---replace_result '\'file_summary_by_instance' '\'FILE_SUMMARY_BY_INSTANCE' --error ER_TABLEACCESS_DENIED_ERROR -update performance_schema.FILE_SUMMARY_BY_INSTANCE +update performance_schema.file_summary_by_instance set count_write=12 where event_name like "FOO"; ---replace_result '\'file_summary_by_instance' '\'FILE_SUMMARY_BY_INSTANCE' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.FILE_SUMMARY_BY_INSTANCE +delete from performance_schema.file_summary_by_instance where count_read=1; ---replace_result '\'file_summary_by_instance' '\'FILE_SUMMARY_BY_INSTANCE' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.FILE_SUMMARY_BY_INSTANCE; +delete from performance_schema.file_summary_by_instance; ---replace_result '\'file_summary_by_instance' '\'FILE_SUMMARY_BY_INSTANCE' -- error ER_TABLEACCESS_DENIED_ERROR -LOCK TABLES performance_schema.FILE_SUMMARY_BY_INSTANCE READ; +LOCK TABLES performance_schema.file_summary_by_instance READ; UNLOCK TABLES; ---replace_result '\'file_summary_by_instance' '\'FILE_SUMMARY_BY_INSTANCE' -- error ER_TABLEACCESS_DENIED_ERROR -LOCK TABLES performance_schema.FILE_SUMMARY_BY_INSTANCE WRITE; +LOCK TABLES performance_schema.file_summary_by_instance WRITE; UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/t/dml_mutex_instances.test b/mysql-test/suite/perfschema/t/dml_mutex_instances.test index 0971c664eb8..c0bbd5276a0 100644 --- a/mysql-test/suite/perfschema/t/dml_mutex_instances.test +++ b/mysql-test/suite/perfschema/t/dml_mutex_instances.test @@ -19,37 +19,31 @@ --source include/have_perfschema.inc --replace_column 1 # 2 # 3 # -select * from performance_schema.MUTEX_INSTANCES limit 1; +select * from performance_schema.mutex_instances limit 1; -select * from performance_schema.MUTEX_INSTANCES +select * from performance_schema.mutex_instances where name='FOO'; ---replace_result '\'mutex_instances' '\'MUTEX_INSTANCES' --error ER_TABLEACCESS_DENIED_ERROR -insert into performance_schema.MUTEX_INSTANCES +insert into performance_schema.mutex_instances set name='FOO', object_instance_begin=12; ---replace_result '\'mutex_instances' '\'MUTEX_INSTANCES' --error ER_TABLEACCESS_DENIED_ERROR -update performance_schema.MUTEX_INSTANCES +update performance_schema.mutex_instances set name='FOO'; ---replace_result '\'mutex_instances' '\'MUTEX_INSTANCES' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.MUTEX_INSTANCES +delete from performance_schema.mutex_instances where name like "wait/%"; ---replace_result '\'mutex_instances' '\'MUTEX_INSTANCES' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.MUTEX_INSTANCES; +delete from performance_schema.mutex_instances; ---replace_result '\'mutex_instances' '\'MUTEX_INSTANCES' -- error ER_TABLEACCESS_DENIED_ERROR -LOCK TABLES performance_schema.MUTEX_INSTANCES READ; +LOCK TABLES performance_schema.mutex_instances READ; UNLOCK TABLES; ---replace_result '\'mutex_instances' '\'MUTEX_INSTANCES' -- error ER_TABLEACCESS_DENIED_ERROR -LOCK TABLES performance_schema.MUTEX_INSTANCES WRITE; +LOCK TABLES performance_schema.mutex_instances WRITE; UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/t/dml_performance_timers.test b/mysql-test/suite/perfschema/t/dml_performance_timers.test index 9c2efb6f709..211e6db4fb1 100644 --- a/mysql-test/suite/perfschema/t/dml_performance_timers.test +++ b/mysql-test/suite/perfschema/t/dml_performance_timers.test @@ -19,39 +19,33 @@ --source include/have_perfschema.inc --replace_column 2 3 4 -select * from performance_schema.PERFORMANCE_TIMERS; +select * from performance_schema.performance_timers; --replace_column 2 3 4 -select * from performance_schema.PERFORMANCE_TIMERS +select * from performance_schema.performance_timers where timer_name='CYCLE'; ---replace_result '\'performance_timers' '\'PERFORMANCE_TIMERS' --error ER_TABLEACCESS_DENIED_ERROR -insert into performance_schema.PERFORMANCE_TIMERS +insert into performance_schema.performance_timers set timer_name='FOO', timer_frequency=1, timer_resolution=2, timer_overhead=3; ---replace_result '\'performance_timers' '\'PERFORMANCE_TIMERS' --error ER_TABLEACCESS_DENIED_ERROR -update performance_schema.PERFORMANCE_TIMERS +update performance_schema.performance_timers set timer_frequency=12 where timer_name='CYCLE'; ---replace_result '\'performance_timers' '\'PERFORMANCE_TIMERS' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.PERFORMANCE_TIMERS; +delete from performance_schema.performance_timers; ---replace_result '\'performance_timers' '\'PERFORMANCE_TIMERS' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.PERFORMANCE_TIMERS +delete from performance_schema.performance_timers where timer_name='CYCLE'; ---replace_result '\'performance_timers' '\'PERFORMANCE_TIMERS' -- error ER_TABLEACCESS_DENIED_ERROR -LOCK TABLES performance_schema.PERFORMANCE_TIMERS READ; +LOCK TABLES performance_schema.performance_timers READ; UNLOCK TABLES; ---replace_result '\'performance_timers' '\'PERFORMANCE_TIMERS' -- error ER_TABLEACCESS_DENIED_ERROR -LOCK TABLES performance_schema.PERFORMANCE_TIMERS WRITE; +LOCK TABLES performance_schema.performance_timers WRITE; UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/t/dml_rwlock_instances.test b/mysql-test/suite/perfschema/t/dml_rwlock_instances.test index 33a42450681..c0fd89a8e75 100644 --- a/mysql-test/suite/perfschema/t/dml_rwlock_instances.test +++ b/mysql-test/suite/perfschema/t/dml_rwlock_instances.test @@ -19,37 +19,31 @@ --source include/have_perfschema.inc --replace_column 1 # 2 # 3 # 4 # -select * from performance_schema.RWLOCK_INSTANCES limit 1; +select * from performance_schema.rwlock_instances limit 1; -select * from performance_schema.RWLOCK_INSTANCES +select * from performance_schema.rwlock_instances where name='FOO'; ---replace_result '\'rwlock_instances' '\'RWLOCK_INSTANCES' --error ER_TABLEACCESS_DENIED_ERROR -insert into performance_schema.RWLOCK_INSTANCES +insert into performance_schema.rwlock_instances set name='FOO', object_instance_begin=12; ---replace_result '\'rwlock_instances' '\'RWLOCK_INSTANCES' --error ER_TABLEACCESS_DENIED_ERROR -update performance_schema.RWLOCK_INSTANCES +update performance_schema.rwlock_instances set name='FOO'; ---replace_result '\'rwlock_instances' '\'RWLOCK_INSTANCES' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.RWLOCK_INSTANCES +delete from performance_schema.rwlock_instances where name like "wait/%"; ---replace_result '\'rwlock_instances' '\'RWLOCK_INSTANCES' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.RWLOCK_INSTANCES; +delete from performance_schema.rwlock_instances; ---replace_result '\'rwlock_instances' '\'RWLOCK_INSTANCES' -- error ER_TABLEACCESS_DENIED_ERROR -LOCK TABLES performance_schema.RWLOCK_INSTANCES READ; +LOCK TABLES performance_schema.rwlock_instances READ; UNLOCK TABLES; ---replace_result '\'rwlock_instances' '\'RWLOCK_INSTANCES' -- error ER_TABLEACCESS_DENIED_ERROR -LOCK TABLES performance_schema.RWLOCK_INSTANCES WRITE; +LOCK TABLES performance_schema.rwlock_instances WRITE; UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/t/dml_setup_consumers.test b/mysql-test/suite/perfschema/t/dml_setup_consumers.test index 85b65864f91..2a29f428f3d 100644 --- a/mysql-test/suite/perfschema/t/dml_setup_consumers.test +++ b/mysql-test/suite/perfschema/t/dml_setup_consumers.test @@ -18,42 +18,38 @@ --source include/not_embedded.inc --source include/have_perfschema.inc -select * from performance_schema.SETUP_CONSUMERS; +select * from performance_schema.setup_consumers; -select * from performance_schema.SETUP_CONSUMERS +select * from performance_schema.setup_consumers where name='events_waits_current'; -select * from performance_schema.SETUP_CONSUMERS +select * from performance_schema.setup_consumers where enabled='YES'; -select * from performance_schema.SETUP_CONSUMERS +select * from performance_schema.setup_consumers where enabled='NO'; ---replace_result '\'setup_consumers' '\'SETUP_CONSUMERS' --error ER_TABLEACCESS_DENIED_ERROR -insert into performance_schema.SETUP_CONSUMERS +insert into performance_schema.setup_consumers set name='FOO', enabled='YES'; ---replace_result '\'setup_consumers' '\'SETUP_CONSUMERS' --error ER_WRONG_PERFSCHEMA_USAGE -update performance_schema.SETUP_CONSUMERS +update performance_schema.setup_consumers set name='FOO'; -update performance_schema.SETUP_CONSUMERS +update performance_schema.setup_consumers set enabled='YES'; ---replace_result '\'setup_consumers' '\'SETUP_CONSUMERS' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.SETUP_CONSUMERS; +delete from performance_schema.setup_consumers; ---replace_result '\'setup_consumers' '\'SETUP_CONSUMERS' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.SETUP_CONSUMERS +delete from performance_schema.setup_consumers where name='events_waits_current'; -LOCK TABLES performance_schema.SETUP_CONSUMERS READ; +LOCK TABLES performance_schema.setup_consumers READ; UNLOCK TABLES; -LOCK TABLES performance_schema.SETUP_CONSUMERS WRITE; +LOCK TABLES performance_schema.setup_consumers WRITE; UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/t/dml_setup_instruments.test b/mysql-test/suite/perfschema/t/dml_setup_instruments.test index b82cde15fb5..b6e28440758 100644 --- a/mysql-test/suite/perfschema/t/dml_setup_instruments.test +++ b/mysql-test/suite/perfschema/t/dml_setup_instruments.test @@ -26,19 +26,19 @@ # - valgrind coverage --disable_result_log -select * from performance_schema.SETUP_INSTRUMENTS; +select * from performance_schema.setup_instruments; --enable_result_log # DEBUG_SYNC::mutex is dependent on the build (DEBUG only) -select * from performance_schema.SETUP_INSTRUMENTS +select * from performance_schema.setup_instruments where name like 'Wait/Synch/Mutex/sql/%' and name not in ('wait/synch/mutex/sql/DEBUG_SYNC::mutex') order by name limit 10; # CRYPTO_dynlock_value::lock is dependent on the build (SSL) -select * from performance_schema.SETUP_INSTRUMENTS +select * from performance_schema.setup_instruments where name like 'Wait/Synch/Rwlock/sql/%' and name not in ('wait/synch/rwlock/sql/CRYPTO_dynlock_value::lock') order by name limit 10; @@ -46,7 +46,7 @@ select * from performance_schema.SETUP_INSTRUMENTS # COND_handler_count is dependent on the build (Windows only) # DEBUG_SYNC::cond is dependent on the build (DEBUG only) -select * from performance_schema.SETUP_INSTRUMENTS +select * from performance_schema.setup_instruments where name like 'Wait/Synch/Cond/sql/%' and name not in ( 'wait/synch/cond/sql/COND_handler_count', @@ -54,50 +54,46 @@ select * from performance_schema.SETUP_INSTRUMENTS order by name limit 10; --disable_result_log -select * from performance_schema.SETUP_INSTRUMENTS +select * from performance_schema.setup_instruments where name='Wait'; --enable_result_log --disable_result_log -select * from performance_schema.SETUP_INSTRUMENTS +select * from performance_schema.setup_instruments where enabled='YES'; --enable_result_log ---replace_result '\'setup_instruments' '\'SETUP_INSTRUMENTS' --error ER_TABLEACCESS_DENIED_ERROR -insert into performance_schema.SETUP_INSTRUMENTS +insert into performance_schema.setup_instruments set name='FOO', enabled='YES', timed='YES'; ---replace_result '\'setup_instruments' '\'SETUP_INSTRUMENTS' --error ER_WRONG_PERFSCHEMA_USAGE -update performance_schema.SETUP_INSTRUMENTS +update performance_schema.setup_instruments set name='FOO'; -update performance_schema.SETUP_INSTRUMENTS +update performance_schema.setup_instruments set enabled='NO'; -update performance_schema.SETUP_INSTRUMENTS +update performance_schema.setup_instruments set timed='NO'; --disable_result_log -select * from performance_schema.SETUP_INSTRUMENTS; +select * from performance_schema.setup_instruments; --enable_result_log -update performance_schema.SETUP_INSTRUMENTS +update performance_schema.setup_instruments set enabled='YES', timed='YES'; ---replace_result '\'setup_instruments' '\'SETUP_INSTRUMENTS' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.SETUP_INSTRUMENTS; +delete from performance_schema.setup_instruments; ---replace_result '\'setup_instruments' '\'SETUP_INSTRUMENTS' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.SETUP_INSTRUMENTS +delete from performance_schema.setup_instruments where name like 'Wait/Synch/%'; -LOCK TABLES performance_schema.SETUP_INSTRUMENTS READ; +LOCK TABLES performance_schema.setup_instruments READ; UNLOCK TABLES; -LOCK TABLES performance_schema.SETUP_INSTRUMENTS WRITE; +LOCK TABLES performance_schema.setup_instruments WRITE; UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/t/dml_setup_timers.test b/mysql-test/suite/perfschema/t/dml_setup_timers.test index 5b5850db575..1bfc0ab83a2 100644 --- a/mysql-test/suite/perfschema/t/dml_setup_timers.test +++ b/mysql-test/suite/perfschema/t/dml_setup_timers.test @@ -18,44 +18,40 @@ --source include/not_embedded.inc --source include/have_perfschema.inc -select * from performance_schema.SETUP_TIMERS; +select * from performance_schema.setup_timers; -select * from performance_schema.SETUP_TIMERS +select * from performance_schema.setup_timers where name='Wait'; -select * from performance_schema.SETUP_TIMERS +select * from performance_schema.setup_timers where timer_name='CYCLE'; ---replace_result '\'setup_timers' '\'SETUP_TIMERS' --error ER_TABLEACCESS_DENIED_ERROR -insert into performance_schema.SETUP_TIMERS +insert into performance_schema.setup_timers set name='FOO', timer_name='CYCLE'; ---replace_result '\'setup_timers' '\'SETUP_TIMERS' --error ER_WRONG_PERFSCHEMA_USAGE -update performance_schema.SETUP_TIMERS +update performance_schema.setup_timers set name='FOO'; -update performance_schema.SETUP_TIMERS +update performance_schema.setup_timers set timer_name='MILLISECOND'; -select * from performance_schema.SETUP_TIMERS; +select * from performance_schema.setup_timers; -update performance_schema.SETUP_TIMERS +update performance_schema.setup_timers set timer_name='CYCLE'; ---replace_result '\'setup_timers' '\'SETUP_TIMERS' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.SETUP_TIMERS; +delete from performance_schema.setup_timers; ---replace_result '\'setup_timers' '\'SETUP_TIMERS' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.SETUP_TIMERS +delete from performance_schema.setup_timers where name='Wait'; -LOCK TABLES performance_schema.SETUP_TIMERS READ; +LOCK TABLES performance_schema.setup_timers READ; UNLOCK TABLES; -LOCK TABLES performance_schema.SETUP_TIMERS WRITE; +LOCK TABLES performance_schema.setup_timers WRITE; UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/t/dml_threads.test b/mysql-test/suite/perfschema/t/dml_threads.test index b6a65b57733..e7188497061 100644 --- a/mysql-test/suite/perfschema/t/dml_threads.test +++ b/mysql-test/suite/perfschema/t/dml_threads.test @@ -19,43 +19,36 @@ --source include/have_perfschema.inc --replace_column 1 # 2 # 3 # -select * from performance_schema.THREADS +select * from performance_schema.threads where name like 'Thread/%' limit 1; -select * from performance_schema.THREADS +select * from performance_schema.threads where name='FOO'; ---replace_result '\'threads' '\'THREADS' --error ER_TABLEACCESS_DENIED_ERROR -insert into performance_schema.THREADS +insert into performance_schema.threads set name='FOO', thread_id=1, processlist_id=2; ---replace_result '\'threads' '\'THREADS' --error ER_TABLEACCESS_DENIED_ERROR -update performance_schema.THREADS +update performance_schema.threads set thread_id=12; ---replace_result '\'threads' '\'THREADS' --error ER_TABLEACCESS_DENIED_ERROR -update performance_schema.THREADS +update performance_schema.threads set thread_id=12 where name like "FOO"; ---replace_result '\'threads' '\'THREADS' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.THREADS +delete from performance_schema.threads where id=1; ---replace_result '\'threads' '\'THREADS' --error ER_TABLEACCESS_DENIED_ERROR -delete from performance_schema.THREADS; +delete from performance_schema.threads; ---replace_result '\'threads' '\'THREADS' -- error ER_TABLEACCESS_DENIED_ERROR -LOCK TABLES performance_schema.THREADS READ; +LOCK TABLES performance_schema.threads READ; UNLOCK TABLES; ---replace_result '\'threads' '\'THREADS' -- error ER_TABLEACCESS_DENIED_ERROR -LOCK TABLES performance_schema.THREADS WRITE; +LOCK TABLES performance_schema.threads WRITE; UNLOCK TABLES; diff --git a/mysql-test/suite/perfschema/t/func_file_io.test b/mysql-test/suite/perfschema/t/func_file_io.test index dc9a7a09e40..911f97b5d6c 100644 --- a/mysql-test/suite/perfschema/t/func_file_io.test +++ b/mysql-test/suite/perfschema/t/func_file_io.test @@ -22,9 +22,9 @@ --source include/not_embedded.inc --source include/have_perfschema.inc -UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'NO', timed = 'YES'; +UPDATE performance_schema.setup_instruments SET enabled = 'NO', timed = 'YES'; -UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'YES' +UPDATE performance_schema.setup_instruments SET enabled = 'YES' WHERE name LIKE 'wait/io/file/%'; --disable_warnings @@ -40,9 +40,9 @@ ENGINE=MyISAM; INSERT INTO t1 (id) VALUES (1), (2), (3), (4), (5), (6), (7), (8); -TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY_LONG; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_CURRENT; +TRUNCATE TABLE performance_schema.events_waits_history_long; +TRUNCATE TABLE performance_schema.events_waits_history; +TRUNCATE TABLE performance_schema.events_waits_current; # # FF1: Count for file should increase with instrumentation enabled and @@ -52,7 +52,7 @@ TRUNCATE TABLE performance_schema.EVENTS_WAITS_CURRENT; SELECT * FROM t1 WHERE id = 1; SET @before_count = (SELECT SUM(TIMER_WAIT) - FROM performance_schema.EVENTS_WAITS_HISTORY_LONG + FROM performance_schema.events_waits_history_long WHERE (EVENT_NAME = 'wait/io/file/myisam/dfile') AND (OBJECT_NAME LIKE '%t1.MYD')); @@ -61,23 +61,23 @@ SELECT IF(@before_count > 0, 'Success', 'Failure') has_instrumentation; SELECT * FROM t1 WHERE id < 4; SET @after_count = (SELECT SUM(TIMER_WAIT) - FROM performance_schema.EVENTS_WAITS_HISTORY_LONG + FROM performance_schema.events_waits_history_long WHERE (EVENT_NAME = 'wait/io/file/myisam/dfile') AND (OBJECT_NAME LIKE '%t1.MYD') AND (1 = 1)); SELECT IF((@after_count - @before_count) > 0, 'Success', 'Failure') test_ff1_timed; -UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled='NO'; +UPDATE performance_schema.setup_instruments SET enabled='NO'; SET @before_count = (SELECT SUM(TIMER_WAIT) - FROM performance_schema.EVENTS_WAITS_HISTORY_LONG + FROM performance_schema.events_waits_history_long WHERE (EVENT_NAME = 'wait/io/file/myisam/dfile') AND (OBJECT_NAME LIKE '%t1.MYD') AND (2 = 2)); SELECT * FROM t1 WHERE id < 6; SET @after_count = (SELECT SUM(TIMER_WAIT) - FROM performance_schema.EVENTS_WAITS_HISTORY_LONG + FROM performance_schema.events_waits_history_long WHERE (EVENT_NAME = 'wait/io/file/myisam/dfile') AND (OBJECT_NAME LIKE '%t1.MYD') AND (3 = 3)); @@ -87,33 +87,33 @@ SELECT IF((COALESCE(@after_count, 0) - COALESCE(@before_count, 0)) = 0, 'Success # Check not timed measurements # -UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'YES' +UPDATE performance_schema.setup_instruments SET enabled = 'YES' WHERE name LIKE 'wait/io/file/%'; -UPDATE performance_schema.SETUP_INSTRUMENTS SET timed = 'NO'; +UPDATE performance_schema.setup_instruments SET timed = 'NO'; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY_LONG; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_CURRENT; +TRUNCATE TABLE performance_schema.events_waits_history_long; +TRUNCATE TABLE performance_schema.events_waits_history; +TRUNCATE TABLE performance_schema.events_waits_current; SELECT * FROM t1 WHERE id > 4; -SELECT * FROM performance_schema.EVENTS_WAITS_HISTORY_LONG +SELECT * FROM performance_schema.events_waits_history_long WHERE TIMER_WAIT != NULL OR TIMER_START != NULL OR TIMER_END != NULL; -SELECT * FROM performance_schema.EVENTS_WAITS_HISTORY +SELECT * FROM performance_schema.events_waits_history WHERE TIMER_WAIT != NULL OR TIMER_START != NULL OR TIMER_END != NULL; -SELECT * FROM performance_schema.EVENTS_WAITS_CURRENT +SELECT * FROM performance_schema.events_waits_current WHERE TIMER_WAIT != NULL OR TIMER_START != NULL OR TIMER_END != NULL; -UPDATE performance_schema.SETUP_INSTRUMENTS SET timed = 'YES'; +UPDATE performance_schema.setup_instruments SET timed = 'YES'; SELECT * FROM t1 WHERE id < 4; @@ -128,7 +128,7 @@ SELECT SUM(COUNT_READ) AS sum_count_read, SUM(COUNT_WRITE) AS sum_count_write, SUM(SUM_NUMBER_OF_BYTES_READ) AS sum_num_bytes_read, SUM(SUM_NUMBER_OF_BYTES_WRITE) AS sum_num_bytes_write -FROM performance_schema.FILE_SUMMARY_BY_INSTANCE +FROM performance_schema.file_summary_by_instance WHERE FILE_NAME LIKE CONCAT('%', @@tmpdir, '%') ORDER BY NULL; --enable_result_log @@ -144,7 +144,7 @@ WHERE FILE_NAME LIKE CONCAT('%', @@tmpdir, '%') ORDER BY NULL; # --disable_result_log SELECT EVENT_NAME, COUNT_STAR, AVG_TIMER_WAIT, SUM_TIMER_WAIT -FROM performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME +FROM performance_schema.events_waits_summary_global_by_event_name WHERE COUNT_STAR > 0 ORDER BY SUM_TIMER_WAIT DESC LIMIT 10; @@ -157,8 +157,8 @@ LIMIT 10; ## --disable_result_log ## SELECT i.user, SUM(TIMER_WAIT) SUM_WAIT ## # ((TIME_TO_SEC(TIMEDIFF(NOW(), i.startup_time)) * 1000) / SUM(TIMER_WAIT)) * 100 WAIT_PERCENTAGE -## FROM performance_schema.EVENTS_WAITS_HISTORY_LONG h -## INNER JOIN performance_schema.THREADS p USING (THREAD_ID) +## FROM performance_schema.events_waits_history_long h +## INNER JOIN performance_schema.threads p USING (THREAD_ID) ## LEFT JOIN information_schema.PROCESSLIST i USING (ID) ## GROUP BY i.user ## ORDER BY SUM_WAIT DESC @@ -170,8 +170,8 @@ LIMIT 10; # --disable_result_log SELECT h.EVENT_NAME, SUM(h.TIMER_WAIT) TOTAL_WAIT -FROM performance_schema.EVENTS_WAITS_HISTORY_LONG h -INNER JOIN performance_schema.THREADS p USING (THREAD_ID) +FROM performance_schema.events_waits_history_long h +INNER JOIN performance_schema.threads p USING (THREAD_ID) WHERE p.PROCESSLIST_ID = 1 GROUP BY h.EVENT_NAME HAVING TOTAL_WAIT > 0; @@ -183,8 +183,8 @@ HAVING TOTAL_WAIT > 0; ## --disable_result_log ## SELECT i.user, h.operation, SUM(NUMBER_OF_BYTES) bytes -## FROM performance_schema.EVENTS_WAITS_HISTORY_LONG h -## INNER JOIN performance_schema.THREADS p USING (THREAD_ID) +## FROM performance_schema.events_waits_history_long h +## INNER JOIN performance_schema.threads p USING (THREAD_ID) ## LEFT JOIN information_schema.PROCESSLIST i USING (ID) ## GROUP BY i.user, h.operation ## HAVING BYTES > 0 diff --git a/mysql-test/suite/perfschema/t/func_mutex.test b/mysql-test/suite/perfschema/t/func_mutex.test index 98cb905c67c..31d81e4b004 100644 --- a/mysql-test/suite/perfschema/t/func_mutex.test +++ b/mysql-test/suite/perfschema/t/func_mutex.test @@ -22,9 +22,9 @@ --source include/not_embedded.inc --source include/have_perfschema.inc -UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'NO', timed = 'YES'; +UPDATE performance_schema.setup_instruments SET enabled = 'NO', timed = 'YES'; -UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'YES' +UPDATE performance_schema.setup_instruments SET enabled = 'YES' WHERE name LIKE 'wait/synch/mutex/%' OR name LIKE 'wait/synch/rwlock/%'; @@ -46,41 +46,41 @@ INSERT INTO t1 (id) VALUES (1), (2), (3), (4), (5), (6), (7), (8); # FM2: Count for mutex should not increase with instrumentation disabled # -TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY_LONG; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_CURRENT; +TRUNCATE TABLE performance_schema.events_waits_history_long; +TRUNCATE TABLE performance_schema.events_waits_history; +TRUNCATE TABLE performance_schema.events_waits_current; SELECT * FROM t1 WHERE id = 1; SET @before_count = (SELECT SUM(TIMER_WAIT) - FROM performance_schema.EVENTS_WAITS_HISTORY_LONG + FROM performance_schema.events_waits_history_long WHERE (EVENT_NAME = 'wait/synch/mutex/sql/LOCK_open')); SELECT * FROM t1; SET @after_count = (SELECT SUM(TIMER_WAIT) - FROM performance_schema.EVENTS_WAITS_HISTORY_LONG + FROM performance_schema.events_waits_history_long WHERE (EVENT_NAME = 'wait/synch/mutex/sql/LOCK_open')); SELECT IF((@after_count - @before_count) > 0, 'Success', 'Failure') test_fm1_timed; -UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'NO' +UPDATE performance_schema.setup_instruments SET enabled = 'NO' WHERE NAME = 'wait/synch/mutex/sql/LOCK_open'; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY_LONG; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_CURRENT; +TRUNCATE TABLE performance_schema.events_waits_history_long; +TRUNCATE TABLE performance_schema.events_waits_history; +TRUNCATE TABLE performance_schema.events_waits_current; SELECT * FROM t1 WHERE id = 1; SET @before_count = (SELECT SUM(TIMER_WAIT) - FROM performance_schema.EVENTS_WAITS_HISTORY_LONG + FROM performance_schema.events_waits_history_long WHERE (EVENT_NAME = 'wait/synch/mutex/sql/LOCK_open')); SELECT * FROM t1; SET @after_count = (SELECT SUM(TIMER_WAIT) - FROM performance_schema.EVENTS_WAITS_HISTORY_LONG + FROM performance_schema.events_waits_history_long WHERE (EVENT_NAME = 'wait/synch/mutex/sql/LOCK_open')); SELECT IF((COALESCE(@after_count, 0) - COALESCE(@before_count, 0)) = 0, 'Success', 'Failure') test_fm2_timed; @@ -89,41 +89,41 @@ SELECT IF((COALESCE(@after_count, 0) - COALESCE(@before_count, 0)) = 0, 'Success # Repeat for RW-lock # -TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY_LONG; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_CURRENT; +TRUNCATE TABLE performance_schema.events_waits_history_long; +TRUNCATE TABLE performance_schema.events_waits_history; +TRUNCATE TABLE performance_schema.events_waits_current; SELECT * FROM t1 WHERE id = 1; SET @before_count = (SELECT SUM(TIMER_WAIT) - FROM performance_schema.EVENTS_WAITS_HISTORY_LONG + FROM performance_schema.events_waits_history_long WHERE (EVENT_NAME = 'wait/synch/rwlock/sql/LOCK_grant')); SELECT * FROM t1; SET @after_count = (SELECT SUM(TIMER_WAIT) - FROM performance_schema.EVENTS_WAITS_HISTORY_LONG + FROM performance_schema.events_waits_history_long WHERE (EVENT_NAME = 'wait/synch/rwlock/sql/LOCK_grant')); SELECT IF((@after_count - @before_count) > 0, 'Success', 'Failure') test_fm1_rw_timed; -UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'NO' +UPDATE performance_schema.setup_instruments SET enabled = 'NO' WHERE NAME = 'wait/synch/rwlock/sql/LOCK_grant'; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY_LONG; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_CURRENT; +TRUNCATE TABLE performance_schema.events_waits_history_long; +TRUNCATE TABLE performance_schema.events_waits_history; +TRUNCATE TABLE performance_schema.events_waits_current; SELECT * FROM t1 WHERE id = 1; SET @before_count = (SELECT SUM(TIMER_WAIT) - FROM performance_schema.EVENTS_WAITS_HISTORY_LONG + FROM performance_schema.events_waits_history_long WHERE (EVENT_NAME = 'wait/synch/rwlock/sql/LOCK_grant')); SELECT * FROM t1; SET @after_count = (SELECT SUM(TIMER_WAIT) - FROM performance_schema.EVENTS_WAITS_HISTORY_LONG + FROM performance_schema.events_waits_history_long WHERE (EVENT_NAME = 'wait/synch/rwlock/sql/LOCK_grant')); SELECT IF((COALESCE(@after_count, 0) - COALESCE(@before_count, 0)) = 0, 'Success', 'Failure') test_fm2_rw_timed; diff --git a/mysql-test/suite/perfschema/t/global_read_lock.test b/mysql-test/suite/perfschema/t/global_read_lock.test index b953ea32ce0..711e72ede76 100644 --- a/mysql-test/suite/perfschema/t/global_read_lock.test +++ b/mysql-test/suite/perfschema/t/global_read_lock.test @@ -15,7 +15,7 @@ # Tests for PERFORMANCE_SCHEMA # -# Test the effect of a flush tables with read lock on SETUP_ tables. +# Test the effect of a flush tables with read lock on setup_ tables. --source include/not_embedded.inc --source include/have_perfschema.inc @@ -28,15 +28,15 @@ flush privileges; --echo connect (con1, localhost, pfsuser, , test); connect (con1, localhost, pfsuser, , test); -lock tables performance_schema.SETUP_INSTRUMENTS read; +lock tables performance_schema.setup_instruments read; --disable_result_log -select * from performance_schema.SETUP_INSTRUMENTS; +select * from performance_schema.setup_instruments; --enable_result_log unlock tables; -lock tables performance_schema.SETUP_INSTRUMENTS write; -update performance_schema.SETUP_INSTRUMENTS set enabled='NO'; -update performance_schema.SETUP_INSTRUMENTS set enabled='YES'; +lock tables performance_schema.setup_instruments write; +update performance_schema.setup_instruments set enabled='NO'; +update performance_schema.setup_instruments set enabled='YES'; unlock tables; --echo connection default; @@ -47,20 +47,20 @@ flush tables with read lock; --echo connection con1; connection con1; -lock tables performance_schema.SETUP_INSTRUMENTS read; +lock tables performance_schema.setup_instruments read; --disable_result_log -select * from performance_schema.SETUP_INSTRUMENTS; +select * from performance_schema.setup_instruments; --enable_result_log unlock tables; # This will block --send -lock tables performance_schema.SETUP_INSTRUMENTS write; +lock tables performance_schema.setup_instruments write; --echo connection default; connection default; -let $wait_condition= select 1 from performance_schema.EVENTS_WAITS_CURRENT where event_name like "wait/synch/cond/sql/COND_global_read_lock"; +let $wait_condition= select 1 from performance_schema.events_waits_current where event_name like "wait/synch/cond/sql/COND_global_read_lock"; --source include/wait_condition.inc @@ -68,7 +68,7 @@ let $wait_condition= select 1 from performance_schema.EVENTS_WAITS_CURRENT where select event_name, left(source, locate(":", source)) as short_source, timer_end, timer_wait, operation - from performance_schema.EVENTS_WAITS_CURRENT + from performance_schema.events_waits_current where event_name like "wait/synch/cond/sql/COND_global_read_lock"; unlock tables; @@ -76,8 +76,8 @@ unlock tables; connection con1; --reap -update performance_schema.SETUP_INSTRUMENTS set enabled='NO'; -update performance_schema.SETUP_INSTRUMENTS set enabled='YES'; +update performance_schema.setup_instruments set enabled='NO'; +update performance_schema.setup_instruments set enabled='YES'; unlock tables; disconnect con1; diff --git a/mysql-test/suite/perfschema/t/information_schema.test b/mysql-test/suite/perfschema/t/information_schema.test index 3d2822a1db3..36ba1912df3 100644 --- a/mysql-test/suite/perfschema/t/information_schema.test +++ b/mysql-test/suite/perfschema/t/information_schema.test @@ -22,46 +22,46 @@ # Note that TABLE_NAME is in uppercase is some platforms, # and in lowercase in others. -# Using upper(TABLE_NAME) to have consistent results. +# Using lower(TABLE_NAME) to have consistent results. -select TABLE_SCHEMA, upper(TABLE_NAME), TABLE_CATALOG +select TABLE_SCHEMA, lower(TABLE_NAME), TABLE_CATALOG from information_schema.tables where TABLE_SCHEMA='performance_schema'; -select upper(TABLE_NAME), TABLE_TYPE, ENGINE +select lower(TABLE_NAME), TABLE_TYPE, ENGINE from information_schema.tables where TABLE_SCHEMA='performance_schema'; -select upper(TABLE_NAME), VERSION, ROW_FORMAT +select lower(TABLE_NAME), VERSION, ROW_FORMAT from information_schema.tables where TABLE_SCHEMA='performance_schema'; -select upper(TABLE_NAME), TABLE_ROWS, AVG_ROW_LENGTH +select lower(TABLE_NAME), TABLE_ROWS, AVG_ROW_LENGTH from information_schema.tables where TABLE_SCHEMA='performance_schema'; -select upper(TABLE_NAME), DATA_LENGTH, MAX_DATA_LENGTH +select lower(TABLE_NAME), DATA_LENGTH, MAX_DATA_LENGTH from information_schema.tables where TABLE_SCHEMA='performance_schema'; -select upper(TABLE_NAME), INDEX_LENGTH, DATA_FREE, AUTO_INCREMENT +select lower(TABLE_NAME), INDEX_LENGTH, DATA_FREE, AUTO_INCREMENT from information_schema.tables where TABLE_SCHEMA='performance_schema'; -select upper(TABLE_NAME), CREATE_TIME, UPDATE_TIME, CHECK_TIME +select lower(TABLE_NAME), CREATE_TIME, UPDATE_TIME, CHECK_TIME from information_schema.tables where TABLE_SCHEMA='performance_schema'; -select upper(TABLE_NAME), TABLE_COLLATION, CHECKSUM +select lower(TABLE_NAME), TABLE_COLLATION, CHECKSUM from information_schema.tables where TABLE_SCHEMA='performance_schema'; # TABLESPACE_NAME does not exist in 5.4 -# select upper(TABLE_NAME), CREATE_OPTIONS, TABLESPACE_NAME +# select lower(TABLE_NAME), CREATE_OPTIONS, TABLESPACE_NAME # from information_schema.tables # where TABLE_SCHEMA='performance_schema'; -select upper(TABLE_NAME), TABLE_COMMENT +select lower(TABLE_NAME), TABLE_COMMENT from information_schema.tables where TABLE_SCHEMA='performance_schema'; diff --git a/mysql-test/suite/perfschema/t/misc.test b/mysql-test/suite/perfschema/t/misc.test index d497c205d50..72e891ca805 100644 --- a/mysql-test/suite/perfschema/t/misc.test +++ b/mysql-test/suite/perfschema/t/misc.test @@ -25,11 +25,11 @@ # --disable_result_log -SELECT EVENT_ID FROM performance_schema.EVENTS_WAITS_CURRENT +SELECT EVENT_ID FROM performance_schema.events_waits_current WHERE THREAD_ID IN - (SELECT THREAD_ID FROM performance_schema.THREADS) + (SELECT THREAD_ID FROM performance_schema.threads) AND EVENT_NAME IN - (SELECT NAME FROM performance_schema.SETUP_INSTRUMENTS + (SELECT NAME FROM performance_schema.setup_instruments WHERE NAME LIKE "wait/synch/%") LIMIT 1; --enable_result_log @@ -46,7 +46,7 @@ create table test.t1(a int) engine=performance_schema; # --error ER_WRONG_PERFSCHEMA_USAGE -create table test.t1 like performance_schema.EVENTS_WAITS_CURRENT; +create table test.t1 like performance_schema.events_waits_current; # # Bug#44898 PerformanceSchema: can create a table in db performance_schema, cannot insert @@ -73,7 +73,7 @@ select * from test.ghost; drop table test.ghost; # Shoud return nothing -select * from performance_schema.FILE_INSTANCES +select * from performance_schema.file_instances where file_name like "%ghost%"; # diff --git a/mysql-test/suite/perfschema/t/myisam_file_io.test b/mysql-test/suite/perfschema/t/myisam_file_io.test index 0861e8f4b74..c2502b5895a 100644 --- a/mysql-test/suite/perfschema/t/myisam_file_io.test +++ b/mysql-test/suite/perfschema/t/myisam_file_io.test @@ -20,14 +20,14 @@ # Setup -update performance_schema.SETUP_INSTRUMENTS set enabled='NO'; -update performance_schema.SETUP_INSTRUMENTS set enabled='YES' +update performance_schema.setup_instruments set enabled='NO'; +update performance_schema.setup_instruments set enabled='YES' where name like "wait/io/file/myisam/%"; -update performance_schema.SETUP_CONSUMERS +update performance_schema.setup_consumers set enabled='YES'; -truncate table performance_schema.EVENTS_WAITS_HISTORY_LONG; +truncate table performance_schema.events_waits_history_long; # Reset lost counters to a known state flush status; @@ -51,7 +51,7 @@ select event_name, left(source, locate(":", source)) as short_source, operation, number_of_bytes, substring(object_name, locate("no_index_tab", object_name)) as short_name - from performance_schema.EVENTS_WAITS_HISTORY_LONG + from performance_schema.events_waits_history_long where operation not like "tell" order by thread_id, event_id; @@ -60,7 +60,7 @@ show status like 'performance_schema_%'; # Cleanup -update performance_schema.SETUP_INSTRUMENTS set enabled='YES'; +update performance_schema.setup_instruments set enabled='YES'; drop table test.no_index_tab; diff --git a/mysql-test/suite/perfschema/t/no_threads.test b/mysql-test/suite/perfschema/t/no_threads.test index 9254535bf1f..f98aa8abdb7 100644 --- a/mysql-test/suite/perfschema/t/no_threads.test +++ b/mysql-test/suite/perfschema/t/no_threads.test @@ -21,18 +21,18 @@ # Setup : in this main thread -update performance_schema.SETUP_INSTRUMENTS set enabled='NO'; -update performance_schema.SETUP_CONSUMERS set enabled='YES'; -update performance_schema.SETUP_INSTRUMENTS set enabled='YES' +update performance_schema.setup_instruments set enabled='NO'; +update performance_schema.setup_consumers set enabled='YES'; +update performance_schema.setup_instruments set enabled='YES' where name like "wait/synch/mutex/mysys/THR_LOCK_myisam"; --disable_warnings drop table if exists test.t1; --enable_warnings -truncate table performance_schema.EVENTS_WAITS_CURRENT; -truncate table performance_schema.EVENTS_WAITS_HISTORY; -truncate table performance_schema.EVENTS_WAITS_HISTORY_LONG; +truncate table performance_schema.events_waits_current; +truncate table performance_schema.events_waits_history; +truncate table performance_schema.events_waits_history_long; show variables like "thread_handling"; @@ -45,23 +45,23 @@ show variables like "performance_schema_max_thread%"; # Verification : in this main thread -select count(*) from performance_schema.THREADS +select count(*) from performance_schema.threads where name like "thread/sql/main"; -select count(*) from performance_schema.THREADS +select count(*) from performance_schema.threads where name like "thread/sql/OneConnection"; select event_name, operation, left(source, locate(":", source)) as short_source - from performance_schema.EVENTS_WAITS_CURRENT; + from performance_schema.events_waits_current; select event_name, operation, left(source, locate(":", source)) as short_source - from performance_schema.EVENTS_WAITS_HISTORY; + from performance_schema.events_waits_history; select event_name, operation, left(source, locate(":", source)) as short_source - from performance_schema.EVENTS_WAITS_HISTORY_LONG; + from performance_schema.events_waits_history_long; # Cleanup diff --git a/mysql-test/suite/perfschema/t/one_thread_per_con.test b/mysql-test/suite/perfschema/t/one_thread_per_con.test index 7d0daffe228..5393152f7d2 100644 --- a/mysql-test/suite/perfschema/t/one_thread_per_con.test +++ b/mysql-test/suite/perfschema/t/one_thread_per_con.test @@ -27,7 +27,7 @@ # The point is not to test myisam, but to test that each # connection is properly instrumented, with one-thread-per-connection -update performance_schema.SETUP_INSTRUMENTS set enabled='YES' +update performance_schema.setup_instruments set enabled='YES' where name like "wait/synch/mutex/mysys/THR_LOCK_myisam"; --disable_warnings @@ -36,7 +36,7 @@ drop table if exists test.t2; drop table if exists test.t3; --enable_warnings -truncate table performance_schema.EVENTS_WAITS_HISTORY_LONG; +truncate table performance_schema.events_waits_history_long; show variables like "thread_handling"; diff --git a/mysql-test/suite/perfschema/t/privilege.test b/mysql-test/suite/perfschema/t/privilege.test index 2d682de2870..277ba9bf3b8 100644 --- a/mysql-test/suite/perfschema/t/privilege.test +++ b/mysql-test/suite/perfschema/t/privilege.test @@ -76,136 +76,128 @@ grant DELETE on performance_schema.* to 'pfs_user_2'@localhost; grant LOCK TABLES on performance_schema.* to 'pfs_user_2'@localhost; # Test denied privileges on specific performance_schema tables. -# SETUP_INSTRUMENT : example of PFS_updatable_acl -# EVENTS_WAITS_CURRENT : example of PFS_truncatable_acl -# FILE_INSTANCES : example of PFS_readonly_acl +# setup_instrument : example of PFS_updatable_acl +# events_waits_current : example of PFS_truncatable_acl +# file_instances : example of PFS_readonly_acl --error ER_DBACCESS_DENIED_ERROR -grant ALL on performance_schema.SETUP_INSTRUMENTS to 'pfs_user_3'@localhost +grant ALL on performance_schema.setup_instruments to 'pfs_user_3'@localhost with GRANT OPTION; # will be ER_DBACCESS_DENIED_ERROR once .FRM are removed -grant CREATE on performance_schema.SETUP_INSTRUMENTS to 'pfs_user_3'@localhost; +grant CREATE on performance_schema.setup_instruments to 'pfs_user_3'@localhost; # will be ER_DBACCESS_DENIED_ERROR once .FRM are removed -grant DROP on performance_schema.SETUP_INSTRUMENTS to 'pfs_user_3'@localhost; +grant DROP on performance_schema.setup_instruments to 'pfs_user_3'@localhost; --error ER_DBACCESS_DENIED_ERROR -grant REFERENCES on performance_schema.SETUP_INSTRUMENTS to 'pfs_user_3'@localhost; +grant REFERENCES on performance_schema.setup_instruments to 'pfs_user_3'@localhost; --error ER_DBACCESS_DENIED_ERROR -grant INDEX on performance_schema.SETUP_INSTRUMENTS to 'pfs_user_3'@localhost; +grant INDEX on performance_schema.setup_instruments to 'pfs_user_3'@localhost; --error ER_DBACCESS_DENIED_ERROR -grant ALTER on performance_schema.SETUP_INSTRUMENTS to 'pfs_user_3'@localhost; +grant ALTER on performance_schema.setup_instruments to 'pfs_user_3'@localhost; --error ER_DBACCESS_DENIED_ERROR -grant CREATE VIEW on performance_schema.SETUP_INSTRUMENTS to 'pfs_user_3'@localhost; +grant CREATE VIEW on performance_schema.setup_instruments to 'pfs_user_3'@localhost; --error ER_DBACCESS_DENIED_ERROR -grant SHOW VIEW on performance_schema.SETUP_INSTRUMENTS to 'pfs_user_3'@localhost; +grant SHOW VIEW on performance_schema.setup_instruments to 'pfs_user_3'@localhost; --error ER_DBACCESS_DENIED_ERROR -grant TRIGGER on performance_schema.SETUP_INSTRUMENTS to 'pfs_user_3'@localhost; +grant TRIGGER on performance_schema.setup_instruments to 'pfs_user_3'@localhost; ---replace_result '\'setup_instruments' '\'SETUP_INSTRUMENTS' --error ER_TABLEACCESS_DENIED_ERROR -grant INSERT on performance_schema.SETUP_INSTRUMENTS to 'pfs_user_3'@localhost; +grant INSERT on performance_schema.setup_instruments to 'pfs_user_3'@localhost; ---replace_result '\'setup_instruments' '\'SETUP_INSTRUMENTS' --error ER_TABLEACCESS_DENIED_ERROR -grant DELETE on performance_schema.SETUP_INSTRUMENTS to 'pfs_user_3'@localhost; +grant DELETE on performance_schema.setup_instruments to 'pfs_user_3'@localhost; -grant SELECT on performance_schema.SETUP_INSTRUMENTS to 'pfs_user_3'@localhost +grant SELECT on performance_schema.setup_instruments to 'pfs_user_3'@localhost with GRANT OPTION; -grant UPDATE on performance_schema.SETUP_INSTRUMENTS to 'pfs_user_3'@localhost +grant UPDATE on performance_schema.setup_instruments to 'pfs_user_3'@localhost with GRANT OPTION; --error ER_DBACCESS_DENIED_ERROR -grant ALL on performance_schema.EVENTS_WAITS_CURRENT to 'pfs_user_3'@localhost +grant ALL on performance_schema.events_waits_current to 'pfs_user_3'@localhost with GRANT OPTION; # will be ER_DBACCESS_DENIED_ERROR once .FRM are removed -grant CREATE on performance_schema.EVENTS_WAITS_CURRENT to 'pfs_user_3'@localhost; +grant CREATE on performance_schema.events_waits_current to 'pfs_user_3'@localhost; # will be ER_DBACCESS_DENIED_ERROR once .FRM are removed -grant DROP on performance_schema.EVENTS_WAITS_CURRENT to 'pfs_user_3'@localhost; +grant DROP on performance_schema.events_waits_current to 'pfs_user_3'@localhost; --error ER_DBACCESS_DENIED_ERROR -grant REFERENCES on performance_schema.EVENTS_WAITS_CURRENT to 'pfs_user_3'@localhost; +grant REFERENCES on performance_schema.events_waits_current to 'pfs_user_3'@localhost; --error ER_DBACCESS_DENIED_ERROR -grant INDEX on performance_schema.EVENTS_WAITS_CURRENT to 'pfs_user_3'@localhost; +grant INDEX on performance_schema.events_waits_current to 'pfs_user_3'@localhost; --error ER_DBACCESS_DENIED_ERROR -grant ALTER on performance_schema.EVENTS_WAITS_CURRENT to 'pfs_user_3'@localhost; +grant ALTER on performance_schema.events_waits_current to 'pfs_user_3'@localhost; --error ER_DBACCESS_DENIED_ERROR -grant CREATE VIEW on performance_schema.EVENTS_WAITS_CURRENT to 'pfs_user_3'@localhost; +grant CREATE VIEW on performance_schema.events_waits_current to 'pfs_user_3'@localhost; --error ER_DBACCESS_DENIED_ERROR -grant SHOW VIEW on performance_schema.EVENTS_WAITS_CURRENT to 'pfs_user_3'@localhost; +grant SHOW VIEW on performance_schema.events_waits_current to 'pfs_user_3'@localhost; --error ER_DBACCESS_DENIED_ERROR -grant TRIGGER on performance_schema.EVENTS_WAITS_CURRENT to 'pfs_user_3'@localhost; +grant TRIGGER on performance_schema.events_waits_current to 'pfs_user_3'@localhost; ---replace_result '\'events_waits_current' '\'EVENTS_WAITS_CURRENT' --error ER_TABLEACCESS_DENIED_ERROR -grant INSERT on performance_schema.EVENTS_WAITS_CURRENT to 'pfs_user_3'@localhost; +grant INSERT on performance_schema.events_waits_current to 'pfs_user_3'@localhost; ---replace_result '\'events_waits_current' '\'EVENTS_WAITS_CURRENT' --error ER_TABLEACCESS_DENIED_ERROR -grant UPDATE on performance_schema.EVENTS_WAITS_CURRENT to 'pfs_user_3'@localhost; +grant UPDATE on performance_schema.events_waits_current to 'pfs_user_3'@localhost; ---replace_result '\'events_waits_current' '\'EVENTS_WAITS_CURRENT' --error ER_TABLEACCESS_DENIED_ERROR -grant DELETE on performance_schema.EVENTS_WAITS_CURRENT to 'pfs_user_3'@localhost; +grant DELETE on performance_schema.events_waits_current to 'pfs_user_3'@localhost; -grant SELECT on performance_schema.EVENTS_WAITS_CURRENT to 'pfs_user_3'@localhost +grant SELECT on performance_schema.events_waits_current to 'pfs_user_3'@localhost with GRANT OPTION; --error ER_DBACCESS_DENIED_ERROR -grant ALL on performance_schema.FILE_INSTANCES to 'pfs_user_3'@localhost +grant ALL on performance_schema.file_instances to 'pfs_user_3'@localhost with GRANT OPTION; # will be ER_DBACCESS_DENIED_ERROR once .FRM are removed -grant CREATE on performance_schema.FILE_INSTANCES to 'pfs_user_3'@localhost; +grant CREATE on performance_schema.file_instances to 'pfs_user_3'@localhost; # will be ER_DBACCESS_DENIED_ERROR once .FRM are removed -grant DROP on performance_schema.FILE_INSTANCES to 'pfs_user_3'@localhost; +grant DROP on performance_schema.file_instances to 'pfs_user_3'@localhost; --error ER_DBACCESS_DENIED_ERROR -grant REFERENCES on performance_schema.FILE_INSTANCES to 'pfs_user_3'@localhost; +grant REFERENCES on performance_schema.file_instances to 'pfs_user_3'@localhost; --error ER_DBACCESS_DENIED_ERROR -grant INDEX on performance_schema.FILE_INSTANCES to 'pfs_user_3'@localhost; +grant INDEX on performance_schema.file_instances to 'pfs_user_3'@localhost; --error ER_DBACCESS_DENIED_ERROR -grant ALTER on performance_schema.FILE_INSTANCES to 'pfs_user_3'@localhost; +grant ALTER on performance_schema.file_instances to 'pfs_user_3'@localhost; --error ER_DBACCESS_DENIED_ERROR -grant CREATE VIEW on performance_schema.FILE_INSTANCES to 'pfs_user_3'@localhost; +grant CREATE VIEW on performance_schema.file_instances to 'pfs_user_3'@localhost; --error ER_DBACCESS_DENIED_ERROR -grant SHOW VIEW on performance_schema.FILE_INSTANCES to 'pfs_user_3'@localhost; +grant SHOW VIEW on performance_schema.file_instances to 'pfs_user_3'@localhost; --error ER_DBACCESS_DENIED_ERROR -grant TRIGGER on performance_schema.FILE_INSTANCES to 'pfs_user_3'@localhost; +grant TRIGGER on performance_schema.file_instances to 'pfs_user_3'@localhost; ---replace_result '\'file_instances' '\'FILE_INSTANCES' --error ER_TABLEACCESS_DENIED_ERROR -grant INSERT on performance_schema.FILE_INSTANCES to 'pfs_user_3'@localhost; +grant INSERT on performance_schema.file_instances to 'pfs_user_3'@localhost; ---replace_result '\'file_instances' '\'FILE_INSTANCES' --error ER_TABLEACCESS_DENIED_ERROR -grant UPDATE on performance_schema.FILE_INSTANCES to 'pfs_user_3'@localhost; +grant UPDATE on performance_schema.file_instances to 'pfs_user_3'@localhost; ---replace_result '\'file_instances' '\'FILE_INSTANCES' --error ER_TABLEACCESS_DENIED_ERROR -grant DELETE on performance_schema.FILE_INSTANCES to 'pfs_user_3'@localhost; +grant DELETE on performance_schema.file_instances to 'pfs_user_3'@localhost; -grant SELECT on performance_schema.FILE_INSTANCES to 'pfs_user_3'@localhost +grant SELECT on performance_schema.file_instances to 'pfs_user_3'@localhost with GRANT OPTION; # See bug#45354 LOCK TABLES is not a TABLE privilege @@ -258,25 +250,20 @@ CREATE user pfs_user_4; --connection pfs_user_4 --echo # Select as pfs_user_4 should fail without grant ---replace_result '\'events_waits_history' '\'EVENTS_WAITS_HISTORY' --error ER_TABLEACCESS_DENIED_ERROR -SELECT event_id FROM performance_schema.EVENTS_WAITS_HISTORY; +SELECT event_id FROM performance_schema.events_waits_history; ---replace_result '\'events_waits_history_long' '\'EVENTS_WAITS_HISTORY_LONG' --error ER_TABLEACCESS_DENIED_ERROR -SELECT event_id FROM performance_schema.EVENTS_WAITS_HISTORY_LONG; +SELECT event_id FROM performance_schema.events_waits_history_long; ---replace_result '\'events_waits_current' '\'EVENTS_WAITS_CURRENT' --error ER_TABLEACCESS_DENIED_ERROR -SELECT event_id FROM performance_schema.EVENTS_WAITS_CURRENT; +SELECT event_id FROM performance_schema.events_waits_current; ---replace_result '\'events_waits_summary_by_instance' '\'EVENTS_WAITS_SUMMARY_BY_INSTANCE' --error ER_TABLEACCESS_DENIED_ERROR -SELECT event_name FROM performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE; +SELECT event_name FROM performance_schema.events_waits_summary_by_instance; ---replace_result '\'file_summary_by_instance' '\'FILE_SUMMARY_BY_INSTANCE' --error ER_TABLEACCESS_DENIED_ERROR -SELECT event_name FROM performance_schema.FILE_SUMMARY_BY_INSTANCE; +SELECT event_name FROM performance_schema.file_summary_by_instance; --echo # --echo # WL#4818, NFS3: Normal user does not have access to change what is @@ -287,35 +274,28 @@ SELECT event_name FROM performance_schema.FILE_SUMMARY_BY_INSTANCE; --echo # User pfs_user_4 should not be allowed to tweak instrumentation without --echo # explicit grant ---replace_result '\'setup_instruments' '\'SETUP_INSTRUMENTS' --error ER_TABLEACCESS_DENIED_ERROR -UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'NO', timed = 'YES'; +UPDATE performance_schema.setup_instruments SET enabled = 'NO', timed = 'YES'; ---replace_result '\'setup_instruments' '\'SETUP_INSTRUMENTS' --error ER_TABLEACCESS_DENIED_ERROR -UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'YES' +UPDATE performance_schema.setup_instruments SET enabled = 'YES' WHERE name LIKE 'wait/synch/mutex/%' OR name LIKE 'wait/synch/rwlock/%'; ---replace_result '\'setup_consumers' '\'SETUP_CONSUMERS' --error ER_TABLEACCESS_DENIED_ERROR -UPDATE performance_schema.SETUP_CONSUMERS SET enabled = 'YES'; +UPDATE performance_schema.setup_consumers SET enabled = 'YES'; ---replace_result '\'setup_timers' '\'SETUP_TIMERS' --error ER_TABLEACCESS_DENIED_ERROR -UPDATE performance_schema.SETUP_TIMERS SET timer_name = 'TICK'; +UPDATE performance_schema.setup_timers SET timer_name = 'TICK'; ---replace_result '\'events_waits_history_long' '\'EVENTS_WAITS_HISTORY_LONG' --error ER_TABLEACCESS_DENIED_ERROR -TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY_LONG; +TRUNCATE TABLE performance_schema.events_waits_history_long; ---replace_result '\'events_waits_history' '\'EVENTS_WAITS_HISTORY' --error ER_TABLEACCESS_DENIED_ERROR -TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY; +TRUNCATE TABLE performance_schema.events_waits_history; ---replace_result '\'events_waits_current' '\'EVENTS_WAITS_CURRENT' --error ER_TABLEACCESS_DENIED_ERROR -TRUNCATE TABLE performance_schema.EVENTS_WAITS_CURRENT; +TRUNCATE TABLE performance_schema.events_waits_current; --echo # --echo # WL#4814, NFS1: Can use grants to give normal user access @@ -325,29 +305,29 @@ TRUNCATE TABLE performance_schema.EVENTS_WAITS_CURRENT; --connection default --echo # Grant access to change tables with the root account -GRANT UPDATE ON performance_schema.SETUP_CONSUMERS TO pfs_user_4; -GRANT UPDATE ON performance_schema.SETUP_TIMERS TO pfs_user_4; -GRANT UPDATE, SELECT ON performance_schema.SETUP_INSTRUMENTS TO pfs_user_4; -GRANT DROP ON performance_schema.EVENTS_WAITS_CURRENT TO pfs_user_4; -GRANT DROP ON performance_schema.EVENTS_WAITS_HISTORY TO pfs_user_4; -GRANT DROP ON performance_schema.EVENTS_WAITS_HISTORY_LONG TO pfs_user_4; +GRANT UPDATE ON performance_schema.setup_consumers TO pfs_user_4; +GRANT UPDATE ON performance_schema.setup_timers TO pfs_user_4; +GRANT UPDATE, SELECT ON performance_schema.setup_instruments TO pfs_user_4; +GRANT DROP ON performance_schema.events_waits_current TO pfs_user_4; +GRANT DROP ON performance_schema.events_waits_history TO pfs_user_4; +GRANT DROP ON performance_schema.events_waits_history_long TO pfs_user_4; --connection pfs_user_4 --echo # User pfs_user_4 should now be allowed to tweak instrumentation -UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'NO', timed = 'YES'; +UPDATE performance_schema.setup_instruments SET enabled = 'NO', timed = 'YES'; -UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'YES' +UPDATE performance_schema.setup_instruments SET enabled = 'YES' WHERE name LIKE 'wait/synch/mutex/%' OR name LIKE 'wait/synch/rwlock/%'; -UPDATE performance_schema.SETUP_CONSUMERS SET enabled = 'YES'; +UPDATE performance_schema.setup_consumers SET enabled = 'YES'; -UPDATE performance_schema.SETUP_TIMERS SET timer_name = 'TICK'; +UPDATE performance_schema.setup_timers SET timer_name = 'TICK'; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY_LONG; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY; -TRUNCATE TABLE performance_schema.EVENTS_WAITS_CURRENT; +TRUNCATE TABLE performance_schema.events_waits_history_long; +TRUNCATE TABLE performance_schema.events_waits_history; +TRUNCATE TABLE performance_schema.events_waits_current; --echo # Clean up --disconnect pfs_user_4 @@ -356,7 +336,7 @@ TRUNCATE TABLE performance_schema.EVENTS_WAITS_CURRENT; REVOKE ALL PRIVILEGES, GRANT OPTION FROM pfs_user_4; DROP USER pfs_user_4; flush privileges; -UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'YES', timed = 'YES'; -UPDATE performance_schema.SETUP_CONSUMERS SET enabled = 'YES'; -UPDATE performance_schema.SETUP_TIMERS SET timer_name = 'CYCLE'; +UPDATE performance_schema.setup_instruments SET enabled = 'YES', timed = 'YES'; +UPDATE performance_schema.setup_consumers SET enabled = 'YES'; +UPDATE performance_schema.setup_timers SET timer_name = 'CYCLE'; diff --git a/mysql-test/suite/perfschema/t/query_cache.test b/mysql-test/suite/perfschema/t/query_cache.test index a48704dc9d6..6e322434ae0 100644 --- a/mysql-test/suite/perfschema/t/query_cache.test +++ b/mysql-test/suite/perfschema/t/query_cache.test @@ -47,17 +47,17 @@ show status like "Qcache_queries_in_cache"; show status like "Qcache_inserts"; show status like "Qcache_hits"; -select spins from performance_schema.EVENTS_WAITS_CURRENT order by event_name limit 1; +select spins from performance_schema.events_waits_current order by event_name limit 1; -select name from performance_schema.SETUP_INSTRUMENTS order by name limit 1; +select name from performance_schema.setup_instruments order by name limit 1; show status like "Qcache_queries_in_cache"; show status like "Qcache_inserts"; show status like "Qcache_hits"; -select spins from performance_schema.EVENTS_WAITS_CURRENT order by event_name limit 1; +select spins from performance_schema.events_waits_current order by event_name limit 1; -select name from performance_schema.SETUP_INSTRUMENTS order by name limit 1; +select name from performance_schema.setup_instruments order by name limit 1; show status like "Qcache_queries_in_cache"; show status like "Qcache_inserts"; diff --git a/mysql-test/suite/perfschema/t/read_only.test b/mysql-test/suite/perfschema/t/read_only.test index 73150207f66..98683e36327 100644 --- a/mysql-test/suite/perfschema/t/read_only.test +++ b/mysql-test/suite/perfschema/t/read_only.test @@ -16,8 +16,8 @@ # Tests for PERFORMANCE_SCHEMA # # Check that -# - a regular user can not update SETUP_ tables under --read-only -# - a user with SUPER privileges cam +# - a regular user can not update setup_ tables under --read-only +# - a user with SUPER privileges can --source include/not_embedded.inc --source include/have_perfschema.inc @@ -43,9 +43,9 @@ connection con1; select @@global.read_only; show grants; --disable_result_log -select * from performance_schema.SETUP_INSTRUMENTS; -update performance_schema.SETUP_INSTRUMENTS set enabled='NO'; -update performance_schema.SETUP_INSTRUMENTS set enabled='YES'; +select * from performance_schema.setup_instruments; +update performance_schema.setup_instruments set enabled='NO'; +update performance_schema.setup_instruments set enabled='YES'; --enable_result_log --echo connection default; @@ -59,11 +59,11 @@ connection con1; select @@global.read_only; show grants; --disable_result_log -select * from performance_schema.SETUP_INSTRUMENTS; +select * from performance_schema.setup_instruments; --error ER_OPTION_PREVENTS_STATEMENT -update performance_schema.SETUP_INSTRUMENTS set enabled='NO'; +update performance_schema.setup_instruments set enabled='NO'; --error ER_OPTION_PREVENTS_STATEMENT -update performance_schema.SETUP_INSTRUMENTS set enabled='YES'; +update performance_schema.setup_instruments set enabled='YES'; --enable_result_log --echo connection default; @@ -79,9 +79,9 @@ connect (con1, localhost, pfsuser, , test); select @@global.read_only; show grants; --disable_result_log -select * from performance_schema.SETUP_INSTRUMENTS; -update performance_schema.SETUP_INSTRUMENTS set enabled='NO'; -update performance_schema.SETUP_INSTRUMENTS set enabled='YES'; +select * from performance_schema.setup_instruments; +update performance_schema.setup_instruments set enabled='NO'; +update performance_schema.setup_instruments set enabled='YES'; --enable_result_log disconnect con1; diff --git a/mysql-test/suite/perfschema/t/schema.test b/mysql-test/suite/perfschema/t/schema.test index 727c4f5a755..32ee4a26676 100644 --- a/mysql-test/suite/perfschema/t/schema.test +++ b/mysql-test/suite/perfschema/t/schema.test @@ -25,21 +25,21 @@ use performance_schema; show tables; -show create table COND_INSTANCES; -show create table EVENTS_WAITS_CURRENT; -show create table EVENTS_WAITS_HISTORY; -show create table EVENTS_WAITS_HISTORY_LONG; -show create table EVENTS_WAITS_SUMMARY_BY_INSTANCE; -show create table EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME; -show create table EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME; -show create table FILE_INSTANCES; -show create table FILE_SUMMARY_BY_EVENT_NAME; -show create table FILE_SUMMARY_BY_INSTANCE; -show create table MUTEX_INSTANCES; -show create table PERFORMANCE_TIMERS; -show create table RWLOCK_INSTANCES; -show create table SETUP_CONSUMERS; -show create table SETUP_INSTRUMENTS; -show create table SETUP_TIMERS; -show create table THREADS; +show create table cond_instances; +show create table events_waits_current; +show create table events_waits_history; +show create table events_waits_history_long; +show create table events_waits_summary_by_instance; +show create table events_waits_summary_by_thread_by_event_name; +show create table events_waits_summary_global_by_event_name; +show create table file_instances; +show create table file_summary_by_event_name; +show create table file_summary_by_instance; +show create table mutex_instances; +show create table performance_timers; +show create table rwlock_instances; +show create table setup_consumers; +show create table setup_instruments; +show create table setup_timers; +show create table threads; diff --git a/mysql-test/suite/perfschema/t/selects.test b/mysql-test/suite/perfschema/t/selects.test index d0249fe654c..e8fd0827c53 100644 --- a/mysql-test/suite/perfschema/t/selects.test +++ b/mysql-test/suite/perfschema/t/selects.test @@ -22,7 +22,7 @@ # Make some data that we can work on: -UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'YES', timed = 'YES'; +UPDATE performance_schema.setup_instruments SET enabled = 'YES', timed = 'YES'; --disable_warnings DROP TABLE IF EXISTS t1; @@ -35,7 +35,7 @@ INSERT INTO t1 (id) VALUES (1), (2), (3), (4), (5), (6), (7), (8); --replace_column 2 [NUM_BYTES] SELECT OPERATION, SUM(NUMBER_OF_BYTES) AS TOTAL -FROM performance_schema.EVENTS_WAITS_HISTORY_LONG +FROM performance_schema.events_waits_history_long GROUP BY OPERATION HAVING TOTAL IS NOT NULL ORDER BY OPERATION @@ -43,11 +43,11 @@ LIMIT 1; # Sub SELECT --replace_column 1 [EVENT_ID] -SELECT EVENT_ID FROM performance_schema.EVENTS_WAITS_CURRENT +SELECT EVENT_ID FROM performance_schema.events_waits_current WHERE THREAD_ID IN - (SELECT THREAD_ID FROM performance_schema.THREADS) + (SELECT THREAD_ID FROM performance_schema.threads) AND EVENT_NAME IN - (SELECT NAME FROM performance_schema.SETUP_INSTRUMENTS + (SELECT NAME FROM performance_schema.setup_instruments WHERE NAME LIKE "wait/synch/%") LIMIT 1; @@ -55,9 +55,9 @@ LIMIT 1; --replace_column 1 [EVENT_ID] SELECT DISTINCT EVENT_ID -FROM performance_schema.EVENTS_WAITS_CURRENT -JOIN performance_schema.EVENTS_WAITS_HISTORY USING (EVENT_ID) -JOIN performance_schema.EVENTS_WAITS_HISTORY_LONG USING (EVENT_ID) +FROM performance_schema.events_waits_current +JOIN performance_schema.events_waits_history USING (EVENT_ID) +JOIN performance_schema.events_waits_history_long USING (EVENT_ID) ORDER BY EVENT_ID LIMIT 1; @@ -65,21 +65,21 @@ LIMIT 1; --replace_column 1 [THREAD_ID] 2 [EVENT_ID] 3 [EVENT_NAME] 4 [TIMER_WAIT] SELECT t1.THREAD_ID, t2.EVENT_ID, t3.EVENT_NAME, t4.TIMER_WAIT -FROM performance_schema.EVENTS_WAITS_HISTORY t1 -JOIN performance_schema.EVENTS_WAITS_HISTORY t2 USING (EVENT_ID) -JOIN performance_schema.EVENTS_WAITS_HISTORY t3 ON (t2.THREAD_ID = t3.THREAD_ID) -JOIN performance_schema.EVENTS_WAITS_HISTORY t4 ON (t3.EVENT_NAME = t4.EVENT_NAME) +FROM performance_schema.events_waits_history t1 +JOIN performance_schema.events_waits_history t2 USING (EVENT_ID) +JOIN performance_schema.events_waits_history t3 ON (t2.THREAD_ID = t3.THREAD_ID) +JOIN performance_schema.events_waits_history t4 ON (t3.EVENT_NAME = t4.EVENT_NAME) ORDER BY t1.EVENT_ID, t2.EVENT_ID LIMIT 5; # UNION --replace_column 1 [THREAD_ID] 2 [EVENT_ID] SELECT THREAD_ID, EVENT_ID FROM ( -SELECT THREAD_ID, EVENT_ID FROM performance_schema.EVENTS_WAITS_CURRENT +SELECT THREAD_ID, EVENT_ID FROM performance_schema.events_waits_current UNION -SELECT THREAD_ID, EVENT_ID FROM performance_schema.EVENTS_WAITS_HISTORY +SELECT THREAD_ID, EVENT_ID FROM performance_schema.events_waits_history UNION -SELECT THREAD_ID, EVENT_ID FROM performance_schema.EVENTS_WAITS_HISTORY_LONG +SELECT THREAD_ID, EVENT_ID FROM performance_schema.events_waits_history_long ) t1 ORDER BY THREAD_ID, EVENT_ID LIMIT 5; @@ -93,14 +93,14 @@ DROP TABLE IF EXISTS t_event; DROP EVENT IF EXISTS t_ps_event; --enable_warnings CREATE TABLE t_event AS -SELECT EVENT_ID FROM performance_schema.EVENTS_WAITS_CURRENT +SELECT EVENT_ID FROM performance_schema.events_waits_current WHERE 1 = 2; CREATE EVENT t_ps_event ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 SECOND DO INSERT INTO t_event SELECT DISTINCT EVENT_ID - FROM performance_schema.EVENTS_WAITS_CURRENT - JOIN performance_schema.EVENTS_WAITS_HISTORY USING (EVENT_ID) + FROM performance_schema.events_waits_current + JOIN performance_schema.events_waits_history USING (EVENT_ID) ORDER BY EVENT_ID LIMIT 1; @@ -116,7 +116,7 @@ delimiter |; CREATE TRIGGER t_ps_trigger BEFORE INSERT ON t1 FOR EACH ROW BEGIN SET NEW.c = (SELECT MAX(EVENT_ID) - FROM performance_schema.EVENTS_WAITS_CURRENT); + FROM performance_schema.events_waits_current); END; | @@ -138,7 +138,7 @@ delimiter |; CREATE PROCEDURE t_ps_proc(IN conid INT, OUT pid INT) BEGIN - SELECT thread_id FROM performance_schema.THREADS + SELECT thread_id FROM performance_schema.threads WHERE PROCESSLIST_ID = conid INTO pid; END; @@ -157,7 +157,7 @@ delimiter |; CREATE FUNCTION t_ps_func(conid INT) RETURNS int BEGIN - return (SELECT thread_id FROM performance_schema.THREADS + return (SELECT thread_id FROM performance_schema.threads WHERE PROCESSLIST_ID = conid); END; diff --git a/mysql-test/suite/perfschema/t/server_init.test b/mysql-test/suite/perfschema/t/server_init.test index cc461374a79..93663118772 100644 --- a/mysql-test/suite/perfschema/t/server_init.test +++ b/mysql-test/suite/perfschema/t/server_init.test @@ -28,185 +28,185 @@ use performance_schema; # Verify that these global mutexes have been properly initilized in mysys -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/mysys/THR_LOCK_threads"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/mysys/THR_LOCK_malloc"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/mysys/THR_LOCK_open"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/mysys/THR_LOCK_isam"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/mysys/THR_LOCK_myisam"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/mysys/THR_LOCK_heap"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/mysys/THR_LOCK_net"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/mysys/THR_LOCK_charset"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/mysys/THR_LOCK_time"; # There are no global rwlock in mysys # Verify that these global conditions have been properly initilized in mysys -select count(name) from COND_INSTANCES +select count(name) from cond_instances where name like "wait/synch/cond/mysys/THR_COND_threads"; # Verify that these global mutexes have been properly initilized in sql -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_open"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_thread_count"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_status"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_error_log"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_delayed_insert"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_uuid_generator"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_delayed_status"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_delayed_create"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_crypt"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_slave_list"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_active_mi"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_manager"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_global_read_lock"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_global_system_variables"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_user_conn"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_prepared_stmt_count"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_connection_count"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_server_started"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_rpl_status"; # LOG_INFO object are created on demand, and are not global. -# select count(name) from MUTEX_INSTANCES +# select count(name) from mutex_instances # where name like "wait/synch/mutex/sql/LOG_INFO::lock"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/Query_cache::structure_guard_mutex"; # The event scheduler may be disabled -# select count(name) from MUTEX_INSTANCES +# select count(name) from mutex_instances # where name like "wait/synch/mutex/sql/Event_scheduler::LOCK_scheduler_state"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_event_metadata"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_event_queue"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_user_locks"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/Cversion_lock"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_audit_mask"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_xid_cache"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_plugin"; # Not a global variable, may be destroyed already. -# select count(name) from MUTEX_INSTANCES +# select count(name) from mutex_instances # where name like "wait/synch/mutex/sql/LOCK_gdl"; -select count(name) from MUTEX_INSTANCES +select count(name) from mutex_instances where name like "wait/synch/mutex/sql/tz_LOCK"; # Verify that these global rwlocks have been properly initilized in sql -select count(name) from RWLOCK_INSTANCES +select count(name) from rwlock_instances where name like "wait/synch/rwlock/sql/LOCK_grant"; -select count(name) from RWLOCK_INSTANCES +select count(name) from rwlock_instances where name like "wait/synch/rwlock/sql/LOCK_sys_init_connect"; -select count(name) from RWLOCK_INSTANCES +select count(name) from rwlock_instances where name like "wait/synch/rwlock/sql/LOCK_sys_init_slave"; -select count(name) from RWLOCK_INSTANCES +select count(name) from rwlock_instances where name like "wait/synch/rwlock/sql/LOCK_system_variables_hash"; # Verify that these global conditions have been properly initilized in sql -select count(name) from COND_INSTANCES +select count(name) from cond_instances where name like "wait/synch/cond/sql/COND_server_started"; -select count(name) from COND_INSTANCES +select count(name) from cond_instances where name like "wait/synch/cond/sql/COND_refresh"; -select count(name) from COND_INSTANCES +select count(name) from cond_instances where name like "wait/synch/cond/sql/COND_thread_count"; -select count(name) from COND_INSTANCES +select count(name) from cond_instances where name like "wait/synch/cond/sql/COND_manager"; -select count(name) from COND_INSTANCES +select count(name) from cond_instances where name like "wait/synch/cond/sql/COND_global_read_lock"; -select count(name) from COND_INSTANCES +select count(name) from cond_instances where name like "wait/synch/cond/sql/COND_thread_cache"; -select count(name) from COND_INSTANCES +select count(name) from cond_instances where name like "wait/synch/cond/sql/COND_flush_thread_cache"; -select count(name) from COND_INSTANCES +select count(name) from cond_instances where name like "wait/synch/cond/sql/COND_rpl_status"; -select count(name) from COND_INSTANCES +select count(name) from cond_instances where name like "wait/synch/cond/sql/Query_cache::COND_cache_status_changed"; # The event scheduler may be disabled -# select count(name) from COND_INSTANCES +# select count(name) from cond_instances # where name like "wait/synch/cond/sql/Event_scheduler::COND_state"; -select count(name) from COND_INSTANCES +select count(name) from cond_instances where name like "wait/synch/cond/sql/COND_queue_state"; diff --git a/mysql-test/suite/perfschema/t/start_server_no_cond_class.test b/mysql-test/suite/perfschema/t/start_server_no_cond_class.test index 34ff61c358e..da75306c2ca 100644 --- a/mysql-test/suite/perfschema/t/start_server_no_cond_class.test +++ b/mysql-test/suite/perfschema/t/start_server_no_cond_class.test @@ -23,7 +23,7 @@ # Expect no classes show variables like "performance_schema_max_cond_classes"; -select count(*) from performance_schema.SETUP_INSTRUMENTS +select count(*) from performance_schema.setup_instruments where name like "wait/synch/cond/%"; # We lost all the classes @@ -31,7 +31,7 @@ select variable_value > 0 from information_schema.global_status where variable_name like 'PERFORMANCE_SCHEMA_COND_CLASSES_LOST'; # Expect no instances -select count(*) from performance_schema.COND_INSTANCES; +select count(*) from performance_schema.cond_instances; # Expect no instances lost show status like "performance_schema_cond_instances_lost"; diff --git a/mysql-test/suite/perfschema/t/start_server_no_cond_inst.test b/mysql-test/suite/perfschema/t/start_server_no_cond_inst.test index fe2177adb82..eb77d76b70e 100644 --- a/mysql-test/suite/perfschema/t/start_server_no_cond_inst.test +++ b/mysql-test/suite/perfschema/t/start_server_no_cond_inst.test @@ -23,7 +23,7 @@ # Expect classes show variables like "performance_schema_max_cond_classes"; -select count(*) > 0 from performance_schema.SETUP_INSTRUMENTS +select count(*) > 0 from performance_schema.setup_instruments where name like "wait/synch/cond/%"; # Expect no class lost @@ -32,7 +32,7 @@ show status like "performance_schema_cond_classes_lost"; # Expect no instances show variables like "performance_schema_max_cond_instances"; -select count(*) from performance_schema.COND_INSTANCES; +select count(*) from performance_schema.cond_instances; # Expect instances lost select variable_value > 0 from information_schema.global_status diff --git a/mysql-test/suite/perfschema/t/start_server_no_file_class.test b/mysql-test/suite/perfschema/t/start_server_no_file_class.test index ca84fbbdcf2..03180dae01e 100644 --- a/mysql-test/suite/perfschema/t/start_server_no_file_class.test +++ b/mysql-test/suite/perfschema/t/start_server_no_file_class.test @@ -23,7 +23,7 @@ # Expect no classes show variables like "performance_schema_max_file_classes"; -select count(*) from performance_schema.SETUP_INSTRUMENTS +select count(*) from performance_schema.setup_instruments where name like "wait/io/file/%"; # We lost all the classes @@ -31,7 +31,7 @@ select variable_value > 0 from information_schema.global_status where variable_name like 'PERFORMANCE_SCHEMA_FILE_CLASSES_LOST'; # Expect no instances -select count(*) from performance_schema.FILE_INSTANCES; +select count(*) from performance_schema.file_instances; # Expect no instances lost show status like "performance_schema_file_instances_lost"; diff --git a/mysql-test/suite/perfschema/t/start_server_no_file_inst.test b/mysql-test/suite/perfschema/t/start_server_no_file_inst.test index dbbba7bbe4a..faa5e97a853 100644 --- a/mysql-test/suite/perfschema/t/start_server_no_file_inst.test +++ b/mysql-test/suite/perfschema/t/start_server_no_file_inst.test @@ -23,7 +23,7 @@ # Expect classes show variables like "performance_schema_max_file_classes"; -select count(*) > 0 from performance_schema.SETUP_INSTRUMENTS +select count(*) > 0 from performance_schema.setup_instruments where name like "wait/io/file/%"; # Expect no class lost @@ -32,7 +32,7 @@ show status like "performance_schema_file_classes_lost"; # Expect no instances show variables like "performance_schema_max_file_instances"; -select count(*) from performance_schema.FILE_INSTANCES; +select count(*) from performance_schema.file_instances; # Expect instances lost select variable_value > 0 from information_schema.global_status diff --git a/mysql-test/suite/perfschema/t/start_server_no_mutex_class.test b/mysql-test/suite/perfschema/t/start_server_no_mutex_class.test index 142e150ede6..79bf3d52bc5 100644 --- a/mysql-test/suite/perfschema/t/start_server_no_mutex_class.test +++ b/mysql-test/suite/perfschema/t/start_server_no_mutex_class.test @@ -23,7 +23,7 @@ # Expect no classes show variables like "performance_schema_max_mutex_classes"; -select count(*) from performance_schema.SETUP_INSTRUMENTS +select count(*) from performance_schema.setup_instruments where name like "wait/synch/mutex/%"; # We lost all the classes @@ -31,7 +31,7 @@ select variable_value > 0 from information_schema.global_status where variable_name like 'PERFORMANCE_SCHEMA_MUTEX_CLASSES_LOST'; # Expect no instances -select count(*) from performance_schema.MUTEX_INSTANCES; +select count(*) from performance_schema.mutex_instances; # Expect no instances lost show status like "performance_schema_mutex_instances_lost"; diff --git a/mysql-test/suite/perfschema/t/start_server_no_mutex_inst.test b/mysql-test/suite/perfschema/t/start_server_no_mutex_inst.test index 5a03251d97a..32c0a02b642 100644 --- a/mysql-test/suite/perfschema/t/start_server_no_mutex_inst.test +++ b/mysql-test/suite/perfschema/t/start_server_no_mutex_inst.test @@ -23,7 +23,7 @@ # Expect classes show variables like "performance_schema_max_mutex_classes"; -select count(*) > 0 from performance_schema.SETUP_INSTRUMENTS +select count(*) > 0 from performance_schema.setup_instruments where name like "wait/synch/mutex/%"; # Expect no class lost @@ -32,7 +32,7 @@ show status like "performance_schema_mutex_classes_lost"; # Expect no instances show variables like "performance_schema_max_mutex_instances"; -select count(*) from performance_schema.MUTEX_INSTANCES; +select count(*) from performance_schema.mutex_instances; # Expect instances lost select variable_value > 0 from information_schema.global_status diff --git a/mysql-test/suite/perfschema/t/start_server_no_rwlock_class.test b/mysql-test/suite/perfschema/t/start_server_no_rwlock_class.test index e4dfe121fcf..10780b59fbe 100644 --- a/mysql-test/suite/perfschema/t/start_server_no_rwlock_class.test +++ b/mysql-test/suite/perfschema/t/start_server_no_rwlock_class.test @@ -23,7 +23,7 @@ # Expect no classes show variables like "performance_schema_max_rwlock_classes"; -select count(*) from performance_schema.SETUP_INSTRUMENTS +select count(*) from performance_schema.setup_instruments where name like "wait/synch/rwlock/%"; # We lost all the classes @@ -31,7 +31,7 @@ select variable_value > 0 from information_schema.global_status where variable_name like 'PERFORMANCE_SCHEMA_RWLOCK_CLASSES_LOST'; # Expect no instances -select count(*) from performance_schema.RWLOCK_INSTANCES; +select count(*) from performance_schema.rwlock_instances; # Expect no instances lost show status like "performance_schema_rwlock_instances_lost"; diff --git a/mysql-test/suite/perfschema/t/start_server_no_rwlock_inst.test b/mysql-test/suite/perfschema/t/start_server_no_rwlock_inst.test index 1d79d2d3991..2ba2ebcdd4b 100644 --- a/mysql-test/suite/perfschema/t/start_server_no_rwlock_inst.test +++ b/mysql-test/suite/perfschema/t/start_server_no_rwlock_inst.test @@ -23,7 +23,7 @@ # Expect classes show variables like "performance_schema_max_rwlock_classes"; -select count(*) > 0 from performance_schema.SETUP_INSTRUMENTS +select count(*) > 0 from performance_schema.setup_instruments where name like "wait/synch/rwlock/%"; # Expect no class lost @@ -32,7 +32,7 @@ show status like "performance_schema_rwlock_classes_lost"; # Expect no instances show variables like "performance_schema_max_rwlock_instances"; -select count(*) from performance_schema.RWLOCK_INSTANCES; +select count(*) from performance_schema.rwlock_instances; # Expect instances lost select variable_value > 0 from information_schema.global_status diff --git a/mysql-test/suite/perfschema/t/start_server_no_thread_class.test b/mysql-test/suite/perfschema/t/start_server_no_thread_class.test index 1ed0fecb538..df825ede637 100644 --- a/mysql-test/suite/perfschema/t/start_server_no_thread_class.test +++ b/mysql-test/suite/perfschema/t/start_server_no_thread_class.test @@ -23,7 +23,7 @@ # Expect no classes show variables like "performance_schema_max_thread_classes"; -select count(*) from performance_schema.SETUP_INSTRUMENTS +select count(*) from performance_schema.setup_instruments where name like "thread/%"; # We lost all the classes @@ -31,7 +31,7 @@ select variable_value > 0 from information_schema.global_status where variable_name like 'PERFORMANCE_SCHEMA_THREAD_CLASSES_LOST'; # Expect no instances -select count(*) from performance_schema.THREADS; +select count(*) from performance_schema.threads; # Expect no instances lost show status like "performance_schema_thread_instances_lost"; diff --git a/mysql-test/suite/perfschema/t/start_server_no_thread_inst.test b/mysql-test/suite/perfschema/t/start_server_no_thread_inst.test index 489f814ba10..150886d01f9 100644 --- a/mysql-test/suite/perfschema/t/start_server_no_thread_inst.test +++ b/mysql-test/suite/perfschema/t/start_server_no_thread_inst.test @@ -24,7 +24,7 @@ show variables like "performance_schema_max_thread_classes"; # Not observable yet -# select count(*) > 0 from performance_schema.SETUP_INSTRUMENTS +# select count(*) > 0 from performance_schema.setup_instruments # where name like "thread/%"; # Expect no class lost @@ -33,7 +33,7 @@ show status like "performance_schema_thread_classes_lost"; # Expect no instances show variables like "performance_schema_max_thread_instances"; -select count(*) from performance_schema.THREADS; +select count(*) from performance_schema.threads; # Expect instances lost select variable_value > 0 from information_schema.global_status diff --git a/mysql-test/suite/perfschema/t/tampered_perfschema_table1.test b/mysql-test/suite/perfschema/t/tampered_perfschema_table1.test index be079bacfbf..741b41ec46b 100644 --- a/mysql-test/suite/perfschema/t/tampered_perfschema_table1.test +++ b/mysql-test/suite/perfschema/t/tampered_perfschema_table1.test @@ -27,18 +27,18 @@ --source include/not_embedded.inc --source include/have_perfschema.inc -# The message prints 'mysql.SETUP_INSTRUMENTS' -# instead of 'performance_schema.SETUP_INSTRUMENTS', +# The message prints 'mysql.setup_instruments' +# instead of 'performance_schema.setup_instruments', # due to Bug#46792 call mtr.add_suppression( -"Column count of mysql.SETUP_INSTRUMENTS is wrong. " +"Column count of mysql.setup_instruments is wrong. " "Expected 4, found 3. The table is probably corrupted"); --error ER_WRONG_NATIVE_TABLE_STRUCTURE -select * from performance_schema.SETUP_INSTRUMENTS limit 1; +select * from performance_schema.setup_instruments limit 1; --disable_result_log -select * from performance_schema.SETUP_CONSUMERS limit 1; +select * from performance_schema.setup_consumers limit 1; --enable_result_log diff --git a/mysql-test/suite/perfschema/t/thread_cache.test b/mysql-test/suite/perfschema/t/thread_cache.test index a59f568e8a2..488b359cd34 100644 --- a/mysql-test/suite/perfschema/t/thread_cache.test +++ b/mysql-test/suite/perfschema/t/thread_cache.test @@ -30,14 +30,14 @@ connect (con1, localhost, root, , ); let $con1_ID=`select connection_id()`; -let $con1_THREAD_ID=`select thread_id from performance_schema.THREADS +let $con1_THREAD_ID=`select thread_id from performance_schema.threads where PROCESSLIST_ID = connection_id()`; connect (con2, localhost, root, , ); let $con2_ID=`select connection_id()`; -let $con2_THREAD_ID=`select thread_id from performance_schema.THREADS +let $con2_THREAD_ID=`select thread_id from performance_schema.threads where PROCESSLIST_ID = connection_id()`; connection default; @@ -58,7 +58,7 @@ connect (con3, localhost, root, , ); let $con3_ID=`select connection_id()`; -let $con3_THREAD_ID=`select thread_id from performance_schema.THREADS +let $con3_THREAD_ID=`select thread_id from performance_schema.threads where PROCESSLIST_ID = connection_id()`; disconnect con3; @@ -82,14 +82,14 @@ connect (con1, localhost, root, , ); let $con1_ID=`select connection_id()`; -let $con1_THREAD_ID=`select thread_id from performance_schema.THREADS +let $con1_THREAD_ID=`select thread_id from performance_schema.threads where PROCESSLIST_ID = connection_id()`; connect (con2, localhost, root, , ); let $con2_ID=`select connection_id()`; -let $con2_THREAD_ID=`select thread_id from performance_schema.THREADS +let $con2_THREAD_ID=`select thread_id from performance_schema.threads where PROCESSLIST_ID = connection_id()`; connection default; @@ -108,7 +108,7 @@ connect (con3, localhost, root, , ); let $con3_ID=`select connection_id()`; -let $con3_THREAD_ID=`select thread_id from performance_schema.THREADS +let $con3_THREAD_ID=`select thread_id from performance_schema.threads where PROCESSLIST_ID = connection_id()`; disconnect con3; diff --git a/scripts/mysql_system_tables.sql b/scripts/mysql_system_tables.sql index d5dd20542ff..96f1fd2db88 100644 --- a/scripts/mysql_system_tables.sql +++ b/scripts/mysql_system_tables.sql @@ -171,7 +171,7 @@ set @have_pfs= (select count(engine) from information_schema.engines where engin -- TABLE COND_INSTANCES -- -SET @l1="CREATE TABLE performance_schema.COND_INSTANCES("; +SET @l1="CREATE TABLE performance_schema.cond_instances("; SET @l2="NAME VARCHAR(128) not null,"; SET @l3="OBJECT_INSTANCE_BEGIN BIGINT not null"; SET @l4=")ENGINE=PERFORMANCE_SCHEMA;"; @@ -187,7 +187,7 @@ DROP PREPARE stmt; -- TABLE EVENTS_WAITS_CURRENT -- -SET @l1="CREATE TABLE performance_schema.EVENTS_WAITS_CURRENT("; +SET @l1="CREATE TABLE performance_schema.events_waits_current("; SET @l2="THREAD_ID INTEGER not null,"; SET @l3="EVENT_ID BIGINT unsigned not null,"; SET @l4="EVENT_NAME VARCHAR(128) not null,"; @@ -217,7 +217,7 @@ DROP PREPARE stmt; -- TABLE EVENTS_WAITS_HISTORY -- -SET @l1="CREATE TABLE performance_schema.EVENTS_WAITS_HISTORY("; +SET @l1="CREATE TABLE performance_schema.events_waits_history("; -- lines 2 to 18 are unchanged from EVENTS_WAITS_CURRENT SET @cmd=concat(@l1,@l2,@l3,@l4,@l5,@l6,@l7,@l8,@l9,@l10,@l11,@l12,@l13,@l14,@l15,@l16,@l17,@l18); @@ -231,7 +231,7 @@ DROP PREPARE stmt; -- TABLE EVENTS_WAITS_HISTORY_LONG -- -SET @l1="CREATE TABLE performance_schema.EVENTS_WAITS_HISTORY_LONG("; +SET @l1="CREATE TABLE performance_schema.events_waits_history_long("; -- lines 2 to 18 are unchanged from EVENTS_WAITS_CURRENT SET @cmd=concat(@l1,@l2,@l3,@l4,@l5,@l6,@l7,@l8,@l9,@l10,@l11,@l12,@l13,@l14,@l15,@l16,@l17,@l18); @@ -245,7 +245,7 @@ DROP PREPARE stmt; -- TABLE EVENTS_WAITS_SUMMARY_BY_INSTANCE -- -SET @l1="CREATE TABLE performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE("; +SET @l1="CREATE TABLE performance_schema.events_waits_summary_by_instance("; SET @l2="EVENT_NAME VARCHAR(128) not null,"; SET @l3="OBJECT_INSTANCE_BEGIN BIGINT not null,"; SET @l4="COUNT_STAR BIGINT unsigned not null,"; @@ -266,7 +266,7 @@ DROP PREPARE stmt; -- TABLE EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME -- -SET @l1="CREATE TABLE performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME("; +SET @l1="CREATE TABLE performance_schema.events_waits_summary_by_thread_by_event_name("; SET @l2="THREAD_ID INTEGER not null,"; SET @l3="EVENT_NAME VARCHAR(128) not null,"; SET @l4="COUNT_STAR BIGINT unsigned not null,"; @@ -287,7 +287,7 @@ DROP PREPARE stmt; -- TABLE EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME -- -SET @l1="CREATE TABLE performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME("; +SET @l1="CREATE TABLE performance_schema.events_waits_summary_global_by_event_name("; SET @l2="EVENT_NAME VARCHAR(128) not null,"; SET @l3="COUNT_STAR BIGINT unsigned not null,"; SET @l4="SUM_TIMER_WAIT BIGINT unsigned not null,"; @@ -307,7 +307,7 @@ DROP PREPARE stmt; -- TABLE FILE_INSTANCES -- -SET @l1="CREATE TABLE performance_schema.FILE_INSTANCES("; +SET @l1="CREATE TABLE performance_schema.file_instances("; SET @l2="FILE_NAME VARCHAR(512) not null,"; SET @l3="EVENT_NAME VARCHAR(128) not null,"; SET @l4="OPEN_COUNT INTEGER unsigned not null"; @@ -324,7 +324,7 @@ DROP PREPARE stmt; -- TABLE FILE_SUMMARY_BY_EVENT_NAME -- -SET @l1="CREATE TABLE performance_schema.FILE_SUMMARY_BY_EVENT_NAME("; +SET @l1="CREATE TABLE performance_schema.file_summary_by_event_name("; SET @l2="EVENT_NAME VARCHAR(128) not null,"; SET @l3="COUNT_READ BIGINT unsigned not null,"; SET @l4="COUNT_WRITE BIGINT unsigned not null,"; @@ -343,7 +343,7 @@ DROP PREPARE stmt; -- TABLE FILE_SUMMARY_BY_INSTANCE -- -SET @l1="CREATE TABLE performance_schema.FILE_SUMMARY_BY_INSTANCE("; +SET @l1="CREATE TABLE performance_schema.file_summary_by_instance("; SET @l2="FILE_NAME VARCHAR(512) not null,"; SET @l3="EVENT_NAME VARCHAR(128) not null,"; SET @l4="COUNT_READ BIGINT unsigned not null,"; @@ -363,7 +363,7 @@ DROP PREPARE stmt; -- TABLE MUTEX_INSTANCES -- -SET @l1="CREATE TABLE performance_schema.MUTEX_INSTANCES("; +SET @l1="CREATE TABLE performance_schema.mutex_instances("; SET @l2="NAME VARCHAR(128) not null,"; SET @l3="OBJECT_INSTANCE_BEGIN BIGINT not null,"; SET @l4="LOCKED_BY_THREAD_ID INTEGER"; @@ -380,7 +380,7 @@ DROP PREPARE stmt; -- TABLE PERFORMANCE_TIMERS -- -SET @l1="CREATE TABLE performance_schema.PERFORMANCE_TIMERS("; +SET @l1="CREATE TABLE performance_schema.performance_timers("; SET @l2="TIMER_NAME ENUM ('CYCLE', 'NANOSECOND', 'MICROSECOND', 'MILLISECOND', 'TICK') not null,"; SET @l3="TIMER_FREQUENCY BIGINT,"; SET @l4="TIMER_RESOLUTION BIGINT,"; @@ -398,7 +398,7 @@ DROP PREPARE stmt; -- TABLE RWLOCK_INSTANCES -- -SET @l1="CREATE TABLE performance_schema.RWLOCK_INSTANCES("; +SET @l1="CREATE TABLE performance_schema.rwlock_instances("; SET @l2="NAME VARCHAR(128) not null,"; SET @l3="OBJECT_INSTANCE_BEGIN BIGINT not null,"; SET @l4="WRITE_LOCKED_BY_THREAD_ID INTEGER,"; @@ -416,7 +416,7 @@ DROP PREPARE stmt; -- TABLE SETUP_CONSUMERS -- -SET @l1="CREATE TABLE performance_schema.SETUP_CONSUMERS("; +SET @l1="CREATE TABLE performance_schema.setup_consumers("; SET @l2="NAME VARCHAR(64) not null,"; SET @l3="ENABLED ENUM ('YES', 'NO') not null"; SET @l4=")ENGINE=PERFORMANCE_SCHEMA;"; @@ -432,7 +432,7 @@ DROP PREPARE stmt; -- TABLE SETUP_INSTRUMENTS -- -SET @l1="CREATE TABLE performance_schema.SETUP_INSTRUMENTS("; +SET @l1="CREATE TABLE performance_schema.setup_instruments("; SET @l2="NAME VARCHAR(128) not null,"; SET @l3="ENABLED ENUM ('YES', 'NO') not null,"; SET @l4="TIMED ENUM ('YES', 'NO') not null"; @@ -449,7 +449,7 @@ DROP PREPARE stmt; -- TABLE SETUP_TIMERS -- -SET @l1="CREATE TABLE performance_schema.SETUP_TIMERS("; +SET @l1="CREATE TABLE performance_schema.setup_timers("; SET @l2="NAME VARCHAR(64) not null,"; SET @l3="TIMER_NAME ENUM ('CYCLE', 'NANOSECOND', 'MICROSECOND', 'MILLISECOND', 'TICK') not null"; SET @l4=")ENGINE=PERFORMANCE_SCHEMA;"; @@ -465,7 +465,7 @@ DROP PREPARE stmt; -- TABLE THREADS -- -SET @l1="CREATE TABLE performance_schema.THREADS("; +SET @l1="CREATE TABLE performance_schema.threads("; SET @l2="THREAD_ID INTEGER not null,"; SET @l3="PROCESSLIST_ID INTEGER,"; SET @l4="NAME VARCHAR(128) not null"; diff --git a/storage/perfschema/table_events_waits.cc b/storage/perfschema/table_events_waits.cc index d34f6fbe722..d55f0fc2dc8 100644 --- a/storage/perfschema/table_events_waits.cc +++ b/storage/perfschema/table_events_waits.cc @@ -118,7 +118,7 @@ table_events_waits_current::m_field_def= PFS_engine_table_share table_events_waits_current::m_share= { - { C_STRING_WITH_LEN("EVENTS_WAITS_CURRENT") }, + { C_STRING_WITH_LEN("events_waits_current") }, &pfs_truncatable_acl, &table_events_waits_current::create, NULL, /* write_row */ @@ -135,7 +135,7 @@ THR_LOCK table_events_waits_history::m_table_lock; PFS_engine_table_share table_events_waits_history::m_share= { - { C_STRING_WITH_LEN("EVENTS_WAITS_HISTORY") }, + { C_STRING_WITH_LEN("events_waits_history") }, &pfs_truncatable_acl, &table_events_waits_history::create, NULL, /* write_row */ @@ -152,7 +152,7 @@ THR_LOCK table_events_waits_history_long::m_table_lock; PFS_engine_table_share table_events_waits_history_long::m_share= { - { C_STRING_WITH_LEN("EVENTS_WAITS_HISTORY_LONG") }, + { C_STRING_WITH_LEN("events_waits_history_long") }, &pfs_truncatable_acl, &table_events_waits_history_long::create, NULL, /* write_row */ diff --git a/storage/perfschema/table_events_waits_summary.cc b/storage/perfschema/table_events_waits_summary.cc index 435a3500f06..05f280f8521 100644 --- a/storage/perfschema/table_events_waits_summary.cc +++ b/storage/perfschema/table_events_waits_summary.cc @@ -74,7 +74,7 @@ table_events_waits_summary_by_thread_by_event_name::m_field_def= PFS_engine_table_share table_events_waits_summary_by_thread_by_event_name::m_share= { - { C_STRING_WITH_LEN("EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME") }, + { C_STRING_WITH_LEN("events_waits_summary_by_thread_by_event_name") }, &pfs_truncatable_acl, &table_events_waits_summary_by_thread_by_event_name::create, NULL, /* write_row */ @@ -386,7 +386,7 @@ table_events_waits_summary_by_instance::m_field_def= PFS_engine_table_share table_events_waits_summary_by_instance::m_share= { - { C_STRING_WITH_LEN("EVENTS_WAITS_SUMMARY_BY_INSTANCE") }, + { C_STRING_WITH_LEN("events_waits_summary_by_instance") }, &pfs_truncatable_acl, &table_events_waits_summary_by_instance::create, NULL, /* write_row */ diff --git a/storage/perfschema/table_ews_global_by_event_name.cc b/storage/perfschema/table_ews_global_by_event_name.cc index 35e744ed96b..c983a967c4e 100644 --- a/storage/perfschema/table_ews_global_by_event_name.cc +++ b/storage/perfschema/table_ews_global_by_event_name.cc @@ -69,7 +69,7 @@ table_ews_global_by_event_name::m_field_def= PFS_engine_table_share table_ews_global_by_event_name::m_share= { - { C_STRING_WITH_LEN("EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME") }, + { C_STRING_WITH_LEN("events_waits_summary_global_by_event_name") }, &pfs_truncatable_acl, &table_ews_global_by_event_name::create, NULL, /* write_row */ diff --git a/storage/perfschema/table_file_instances.cc b/storage/perfschema/table_file_instances.cc index f1676421616..9ae732a0e1c 100644 --- a/storage/perfschema/table_file_instances.cc +++ b/storage/perfschema/table_file_instances.cc @@ -54,7 +54,7 @@ table_file_instances::m_field_def= PFS_engine_table_share table_file_instances::m_share= { - { C_STRING_WITH_LEN("FILE_INSTANCES") }, + { C_STRING_WITH_LEN("file_instances") }, &pfs_readonly_acl, &table_file_instances::create, NULL, /* write_row */ diff --git a/storage/perfschema/table_file_summary.cc b/storage/perfschema/table_file_summary.cc index f8b9e66118b..a954db7ef4e 100644 --- a/storage/perfschema/table_file_summary.cc +++ b/storage/perfschema/table_file_summary.cc @@ -64,7 +64,7 @@ table_file_summary_by_event_name::m_field_def= PFS_engine_table_share table_file_summary_by_event_name::m_share= { - { C_STRING_WITH_LEN("FILE_SUMMARY_BY_EVENT_NAME") }, + { C_STRING_WITH_LEN("file_summary_by_event_name") }, &pfs_truncatable_acl, &table_file_summary_by_event_name::create, NULL, /* write_row */ @@ -227,7 +227,7 @@ table_file_summary_by_instance::m_field_def= PFS_engine_table_share table_file_summary_by_instance::m_share= { - { C_STRING_WITH_LEN("FILE_SUMMARY_BY_INSTANCE") }, + { C_STRING_WITH_LEN("file_summary_by_instance") }, &pfs_truncatable_acl, &table_file_summary_by_instance::create, NULL, /* write_row */ diff --git a/storage/perfschema/table_performance_timers.cc b/storage/perfschema/table_performance_timers.cc index f400e37366c..acd379bc57b 100644 --- a/storage/perfschema/table_performance_timers.cc +++ b/storage/perfschema/table_performance_timers.cc @@ -58,7 +58,7 @@ table_performance_timers::m_field_def= PFS_engine_table_share table_performance_timers::m_share= { - { C_STRING_WITH_LEN("PERFORMANCE_TIMERS") }, + { C_STRING_WITH_LEN("performance_timers") }, &pfs_readonly_acl, &table_performance_timers::create, NULL, /* write_row */ diff --git a/storage/perfschema/table_setup_consumers.cc b/storage/perfschema/table_setup_consumers.cc index 3cc6a1441c1..5b39fd89a03 100644 --- a/storage/perfschema/table_setup_consumers.cc +++ b/storage/perfschema/table_setup_consumers.cc @@ -84,7 +84,7 @@ table_setup_consumers::m_field_def= PFS_engine_table_share table_setup_consumers::m_share= { - { C_STRING_WITH_LEN("SETUP_CONSUMERS") }, + { C_STRING_WITH_LEN("setup_consumers") }, &pfs_updatable_acl, &table_setup_consumers::create, NULL, /* write_row */ diff --git a/storage/perfschema/table_setup_instruments.cc b/storage/perfschema/table_setup_instruments.cc index 259ccee3c84..310f859248b 100644 --- a/storage/perfschema/table_setup_instruments.cc +++ b/storage/perfschema/table_setup_instruments.cc @@ -54,7 +54,7 @@ table_setup_instruments::m_field_def= PFS_engine_table_share table_setup_instruments::m_share= { - { C_STRING_WITH_LEN("SETUP_INSTRUMENTS") }, + { C_STRING_WITH_LEN("setup_instruments") }, &pfs_updatable_acl, &table_setup_instruments::create, NULL, /* write_row */ diff --git a/storage/perfschema/table_setup_timers.cc b/storage/perfschema/table_setup_timers.cc index 8ca218913bb..24ec18dafb1 100644 --- a/storage/perfschema/table_setup_timers.cc +++ b/storage/perfschema/table_setup_timers.cc @@ -57,7 +57,7 @@ table_setup_timers::m_field_def= PFS_engine_table_share table_setup_timers::m_share= { - { C_STRING_WITH_LEN("SETUP_TIMERS") }, + { C_STRING_WITH_LEN("setup_timers") }, &pfs_updatable_acl, &table_setup_timers::create, NULL, /* write_row */ diff --git a/storage/perfschema/table_sync_instances.cc b/storage/perfschema/table_sync_instances.cc index 82587ce493d..f2bd9fa1a28 100644 --- a/storage/perfschema/table_sync_instances.cc +++ b/storage/perfschema/table_sync_instances.cc @@ -55,7 +55,7 @@ table_mutex_instances::m_field_def= PFS_engine_table_share table_mutex_instances::m_share= { - { C_STRING_WITH_LEN("MUTEX_INSTANCES") }, + { C_STRING_WITH_LEN("mutex_instances") }, &pfs_readonly_acl, &table_mutex_instances::create, NULL, /* write_row */ @@ -223,7 +223,7 @@ table_rwlock_instances::m_field_def= PFS_engine_table_share table_rwlock_instances::m_share= { - { C_STRING_WITH_LEN("RWLOCK_INSTANCES") }, + { C_STRING_WITH_LEN("rwlock_instances") }, &pfs_readonly_acl, &table_rwlock_instances::create, NULL, /* write_row */ @@ -388,7 +388,7 @@ table_cond_instances::m_field_def= PFS_engine_table_share table_cond_instances::m_share= { - { C_STRING_WITH_LEN("COND_INSTANCES") }, + { C_STRING_WITH_LEN("cond_instances") }, &pfs_readonly_acl, &table_cond_instances::create, NULL, /* write_row */ diff --git a/storage/perfschema/table_threads.cc b/storage/perfschema/table_threads.cc index d9aa600a21e..541ba860386 100644 --- a/storage/perfschema/table_threads.cc +++ b/storage/perfschema/table_threads.cc @@ -52,7 +52,7 @@ table_threads::m_field_def= PFS_engine_table_share table_threads::m_share= { - { C_STRING_WITH_LEN("THREADS") }, + { C_STRING_WITH_LEN("threads") }, &pfs_readonly_acl, &table_threads::create, NULL, /* write_row */ From c1b2d729002fa28bf29957436c0ed1926e9c45a6 Mon Sep 17 00:00:00 2001 From: Jon Olav Hauglid Date: Wed, 3 Nov 2010 16:47:32 +0100 Subject: [PATCH 173/304] Bug #57130 crash in Item_field::print during SHOW CREATE TABLE or VIEW This crash could happen if SHOW CREATE VIEW indirectly failed to open a view due to failures to open underlying tables (or functions). Several such errors were hidden and converted to ER_VIEW_INVALID warnings to prevent exposing details of underlying tables for which the user have no privileges. However, with the changes introduced by the patch for Bug#52044, failing to open a view will cause opened tables, views and functions to be closed. Since the errors causing these failures were converted to warnings, SHOW CREATE VIEW would try to continue. This made it possible to try to access memory that had been freed, causing a crash. This patch fixes the problem by not closing opened tables, views and functions in these cases. This allows SHOW CREATE VIEW to continue and also prevents it from accessing freed memory. Test case added to lock_sync.test. --- mysql-test/r/lock_sync.result | 35 +++++++++++++++++++++ mysql-test/t/lock_sync.test | 59 +++++++++++++++++++++++++++++++++++ sql/sql_show.cc | 13 ++++++-- 3 files changed, 105 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/lock_sync.result b/mysql-test/r/lock_sync.result index 726b754eaa8..8fe94679e70 100644 --- a/mysql-test/r/lock_sync.result +++ b/mysql-test/r/lock_sync.result @@ -738,3 +738,38 @@ SET DEBUG_SYNC= 'now SIGNAL release_thrlock'; # Connection default DROP TABLE t1; SET DEBUG_SYNC= 'RESET'; +# +# Bug#57130 crash in Item_field::print during SHOW CREATE TABLE or VIEW +# +DROP TABLE IF EXISTS t1; +DROP VIEW IF EXISTS v1; +DROP FUNCTION IF EXISTS f1; +CREATE TABLE t1(a INT); +CREATE FUNCTION f1() RETURNS INTEGER RETURN 1; +CREATE VIEW v1 AS SELECT * FROM t1 WHERE f1() = 1; +DROP FUNCTION f1; +# Connection con1 +SET DEBUG_SYNC= 'open_tables_after_open_and_process_table SIGNAL opened WAIT_FOR dropped EXECUTE 2'; +# Sending: +SHOW CREATE VIEW v1; +# Connection con2 +SET DEBUG_SYNC= 'now WAIT_FOR opened'; +SET DEBUG_SYNC= 'now SIGNAL dropped'; +SET DEBUG_SYNC= 'now WAIT_FOR opened'; +# Sending: +FLUSH TABLES; +# Connection default +# Waiting for FLUSH TABLES to be blocked. +SET DEBUG_SYNC= 'now SIGNAL dropped'; +# Connection con1 +# Reaping: SHOW CREATE VIEW v1 +View Create View character_set_client collation_connection +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a` from `t1` where (`f1`() = 1) latin1 latin1_swedish_ci +Warnings: +Warning 1356 View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them +# Connection con2 +# Reaping: FLUSH TABLES +# Connection default +SET DEBUG_SYNC= 'RESET'; +DROP VIEW v1; +DROP TABLE t1; diff --git a/mysql-test/t/lock_sync.test b/mysql-test/t/lock_sync.test index 7131e2cde31..d5ad7becd7d 100644 --- a/mysql-test/t/lock_sync.test +++ b/mysql-test/t/lock_sync.test @@ -1078,6 +1078,65 @@ DROP TABLE t1; SET DEBUG_SYNC= 'RESET'; +--echo # +--echo # Bug#57130 crash in Item_field::print during SHOW CREATE TABLE or VIEW +--echo # + +--disable_warnings +DROP TABLE IF EXISTS t1; +DROP VIEW IF EXISTS v1; +DROP FUNCTION IF EXISTS f1; +--enable_warnings + +CREATE TABLE t1(a INT); +CREATE FUNCTION f1() RETURNS INTEGER RETURN 1; +CREATE VIEW v1 AS SELECT * FROM t1 WHERE f1() = 1; +DROP FUNCTION f1; +connect(con2, localhost, root); + +--echo # Connection con1 +connect (con1, localhost, root); +# Need to trigger this sync point at least twice in order to +# get valgrind test failures without the patch +SET DEBUG_SYNC= 'open_tables_after_open_and_process_table SIGNAL opened WAIT_FOR dropped EXECUTE 2'; +--echo # Sending: +--send SHOW CREATE VIEW v1 + +--echo # Connection con2 +connection con2; +SET DEBUG_SYNC= 'now WAIT_FOR opened'; +SET DEBUG_SYNC= 'now SIGNAL dropped'; +SET DEBUG_SYNC= 'now WAIT_FOR opened'; +--echo # Sending: +--send FLUSH TABLES + +--echo # Connection default +connection default; +--echo # Waiting for FLUSH TABLES to be blocked. +let $wait_condition= SELECT COUNT(*)=1 FROM information_schema.processlist + WHERE state= 'Waiting for table flush' AND info= 'FLUSH TABLES'; +--source include/wait_condition.inc +SET DEBUG_SYNC= 'now SIGNAL dropped'; + +--echo # Connection con1 +connection con1; +--echo # Reaping: SHOW CREATE VIEW v1 +--reap + +--echo # Connection con2 +connection con2; +--echo # Reaping: FLUSH TABLES +--reap + +--echo # Connection default +connection default; +SET DEBUG_SYNC= 'RESET'; +DROP VIEW v1; +DROP TABLE t1; +disconnect con1; +disconnect con2; + + # Check that all connections opened by test cases in this file are really # gone so execution of other tests won't be affected by their presence. --source include/wait_until_count_sessions.inc diff --git a/sql/sql_show.cc b/sql/sql_show.cc index be3dd8a0ca2..fa9c0e85c27 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -29,6 +29,8 @@ #include "repl_failsafe.h" #include "sql_parse.h" // check_access, check_table_access #include "sql_partition.h" // partition_element +#include "sql_derived.h" // mysql_derived_prepare, + // mysql_handle_derived, #include "sql_db.h" // check_db_dir_existence, load_db_opt_by_name #include "sql_time.h" // interval_type_to_name #include "tztime.h" // struct Time_zone @@ -683,11 +685,18 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) thd->lex->view_prepare_mode= TRUE; { + /* + Use open_tables() directly rather than open_normal_and_derived_tables(). + This ensures that close_thread_tables() is not called if open tables fails + and the error is ignored. This allows us to handle broken views nicely. + */ + uint counter; Show_create_error_handler view_error_suppressor(thd, table_list); thd->push_internal_handler(&view_error_suppressor); bool open_error= - open_normal_and_derived_tables(thd, table_list, - MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL); + open_tables(thd, &table_list, &counter, + MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL) || + mysql_handle_derived(thd->lex, &mysql_derived_prepare); thd->pop_internal_handler(); if (open_error && (thd->killed || thd->is_error())) goto exit; From 1f0f542a4264e2896fc8b2be8190d3e8fa813b80 Mon Sep 17 00:00:00 2001 From: Sunny Bains Date: Thu, 4 Nov 2010 09:41:36 +1100 Subject: [PATCH 174/304] Add change log entry for bug#54538 fix. --- storage/innodb_plugin/ChangeLog | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 57a4b588703..62371d05bd0 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -4,6 +4,13 @@ Fix Bug#57947 InnoDB diagnostics shows btr_block_get calls instead of real callers +2010-11-03 The InnoDB Team + + * fil/fil0fil.c, fsp/fsp0fsp.c, handler/ha_innodb.cc, + include/fil0fil.h, include/univ.i: + Fix Bug #54538 - use of exclusive innodb dictionary lock limits + performance. + 2010-11-02 The InnoDB Team * row/row0sel.c: From 6429e7d36b7c608392fb5e94f14b092addde3eda Mon Sep 17 00:00:00 2001 From: He Zhenxing Date: Thu, 4 Nov 2010 13:29:16 +0800 Subject: [PATCH 175/304] BUG#47027 delegates_init() failure is not user friendly (usability issue) Function delegetas_init() did not report proper error messages when there are failures, which made it hard to know where the problem occurred. Fixed the problem by adding specific error message for every possible place that can fail. And since these failures are supposed to never happen, ask the user to report a bug if they happened. --- sql/mysqld.cc | 8 ++++---- sql/rpl_handler.cc | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 99754e8b7f6..df4f0f95b8c 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3778,12 +3778,12 @@ static int init_server_components() unireg_abort(1); } - /* initialize delegates for extension observers */ + /* + initialize delegates for extension observers, errors have already + been reported in the function + */ if (delegates_init()) - { - sql_print_error("Initialize extension delegates failed"); unireg_abort(1); - } /* need to configure logging before initializing storage engines */ if (opt_log_slave_updates && !opt_bin_log) diff --git a/sql/rpl_handler.cc b/sql/rpl_handler.cc index 5f16544d855..4355942e47f 100644 --- a/sql/rpl_handler.cc +++ b/sql/rpl_handler.cc @@ -105,12 +105,20 @@ int delegates_init() transaction_delegate= new (place_trans_mem) Trans_delegate; if (!transaction_delegate->is_inited()) + { + sql_print_error("Initialization of transaction delegates failed. " + "Please report a bug."); return 1; + } binlog_storage_delegate= new (place_storage_mem) Binlog_storage_delegate; if (!binlog_storage_delegate->is_inited()) + { + sql_print_error("Initialization binlog storage delegates failed. " + "Please report a bug."); return 1; + } #ifdef HAVE_REPLICATION void *place_transmit_mem= transmit_mem.data; @@ -119,16 +127,29 @@ int delegates_init() binlog_transmit_delegate= new (place_transmit_mem) Binlog_transmit_delegate; if (!binlog_transmit_delegate->is_inited()) + { + sql_print_error("Initialization of binlog transmit delegates failed. " + "Please report a bug."); return 1; + } binlog_relay_io_delegate= new (place_relay_io_mem) Binlog_relay_IO_delegate; if (!binlog_relay_io_delegate->is_inited()) + { + sql_print_error("Initialization binlog relay IO delegates failed. " + "Please report a bug."); return 1; + } #endif if (pthread_key_create(&RPL_TRANS_BINLOG_INFO, NULL)) + { + sql_print_error("Error while creating pthread specific data key for replication. " + "Please report a bug."); return 1; + } + return 0; } From 64bee6fdc5a16bacc6e290e586038ac338b1ed69 Mon Sep 17 00:00:00 2001 From: Jorgen Loland Date: Thu, 4 Nov 2010 09:36:04 +0100 Subject: [PATCH 176/304] Bug#57882 - Item_func_conv_charset::val_str(String*): Assertion `fixed == 1' failed (also fixes duplicate bug 57515) agg_item_set_converter() (item.cc) handles conversion of character sets by creating a new Item. fix_fields() is then called on this newly created item. Prior to this patch, it was not checked whether fix_fields() was successful or not. Thus, agg_item_set_converter() would return success even when an error occured. This patch makes it return error (TRUE) if fix_fields() fails. mysql-test/r/errors.result: Add test for BUG#57882 mysql-test/t/errors.test: Add test for BUG#57882 sql/item.cc: Make agg_item_set_converter() return with error if fix_fields() on the newly created converted item fails. --- mysql-test/r/errors.result | 12 ++++++++++++ mysql-test/t/errors.test | 16 ++++++++++++++++ sql/item.cc | 11 ++++++----- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/errors.result b/mysql-test/r/errors.result index 3d247a242a3..43cabd28498 100644 --- a/mysql-test/r/errors.result +++ b/mysql-test/r/errors.result @@ -134,3 +134,15 @@ INSERT INTO t1 VALUES ('abc\0\0'); INSERT INTO t1 VALUES ('abc\0\0'); ERROR 23000: Duplicate entry 'abc\x00\x00' for key 'PRIMARY' DROP TABLE t1; +# +# Bug#57882: Item_func_conv_charset::val_str(String*): +# Assertion `fixed == 1' failed +# +SELECT (CONVERT('0' USING latin1) IN (CHAR(COT('v') USING utf8),'')); +ERROR 22003: DOUBLE value is out of range in 'cot('v')' +SET NAMES utf8 COLLATE utf8_latvian_ci ; +SELECT UPDATEXML(-73 * -2465717823867977728,@@global.slave_net_timeout,null); +ERROR 22003: BIGINT value is out of range in '(-(73) * -(2465717823867977728))' +# +# End Bug#57882 +# diff --git a/mysql-test/t/errors.test b/mysql-test/t/errors.test index f308c340645..8de5889f1c6 100644 --- a/mysql-test/t/errors.test +++ b/mysql-test/t/errors.test @@ -155,3 +155,19 @@ INSERT INTO t1 VALUES ('abc\0\0'); --error ER_DUP_ENTRY INSERT INTO t1 VALUES ('abc\0\0'); DROP TABLE t1; + +--echo # +--echo # Bug#57882: Item_func_conv_charset::val_str(String*): +--echo # Assertion `fixed == 1' failed +--echo # + +--error ER_DATA_OUT_OF_RANGE +SELECT (CONVERT('0' USING latin1) IN (CHAR(COT('v') USING utf8),'')); + +SET NAMES utf8 COLLATE utf8_latvian_ci ; +--error ER_DATA_OUT_OF_RANGE +SELECT UPDATEXML(-73 * -2465717823867977728,@@global.slave_net_timeout,null); + +--echo # +--echo # End Bug#57882 +--echo # diff --git a/sql/item.cc b/sql/item.cc index b166f3e645f..3594bf45798 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1853,11 +1853,12 @@ bool agg_item_set_converter(DTCollation &coll, const char *fname, *arg= conv; else thd->change_item_tree(arg, conv); - /* - We do not check conv->fixed, because Item_func_conv_charset which can - be return by safe_charset_converter can't be fixed at creation - */ - conv->fix_fields(thd, arg); + + if (conv->fix_fields(thd, arg)) + { + res= TRUE; + break; // we cannot return here, we need to restore "arena". + } } if (arena) thd->restore_active_arena(arena, &backup); From f8d2154c30b37817299c37fed39ed7c86b92d052 Mon Sep 17 00:00:00 2001 From: Mats Kindahl Date: Thu, 4 Nov 2010 11:00:59 +0100 Subject: [PATCH 177/304] BUG#57108: mysqld crashes when I attempt to install plugin If a relative path is supplied to option --defaults-file or --defaults-extra-file, the server will crash when executing an INSTALL PLUGIN command. The reason is that the defaults file is initially read relative the current working directory when the server is started, but when INSTALL PLUGIN is executed, the server has changed working directory to the data directory. Since there is no check that the call to my_load_defaults() inside mysql_install_plugin(), the subsequence call to free_defaults() will crash the server. This patch fixes the problem by: - Prepending the current working directory to the file name when a relative path is given to the --defaults-file or --defaults- extra-file option the first time my_load_defaults() is called, which is just after the server has started in main(). - Adding a check of the return value of my_load_defaults() inside mysql_install_plugin() and aborting command (with an error) if an error is returned. - It also adds a check of the return value for load_defaults in lib_sql.cc for the embedded server since that was missing. To test that the relative files for the options --defaults-file and --defaults-extra-file is handled properly, mysql-test-run.pl is also changed to not add a --defaults-file option if one is provided in the tests *.opt file. --- include/my_sys.h | 2 +- libmysqld/lib_sql.cc | 3 +- mysql-test/mysql-test-run.pl | 11 ++- mysql-test/std_data/bug57108.cnf | 95 +++++++++++++++++++++ mysql-test/suite/bugs/r/bug57108.result | 5 ++ mysql-test/suite/bugs/t/bug57108-master.opt | 2 + mysql-test/suite/bugs/t/bug57108.test | 12 +++ mysys/default.c | 61 +++++++++++-- sql/sql_plugin.cc | 6 +- 9 files changed, 184 insertions(+), 13 deletions(-) create mode 100644 mysql-test/std_data/bug57108.cnf create mode 100644 mysql-test/suite/bugs/r/bug57108.result create mode 100644 mysql-test/suite/bugs/t/bug57108-master.opt create mode 100644 mysql-test/suite/bugs/t/bug57108.test diff --git a/include/my_sys.h b/include/my_sys.h index 23c9b2da55f..7b437e2a745 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -256,7 +256,7 @@ extern my_bool my_disable_locking, my_disable_async_io, extern char wild_many,wild_one,wild_prefix; extern const char *charsets_dir; /* from default.c */ -extern char *my_defaults_extra_file; +extern const char *my_defaults_extra_file; extern const char *my_defaults_group_suffix; extern const char *my_defaults_file; diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 1c9b773de15..b07ae1de96b 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -506,7 +506,8 @@ int init_embedded_server(int argc, char **argv, char **groups) orig_argc= *argcp; orig_argv= *argvp; - load_defaults("my", (const char **)groups, argcp, argvp); + if (load_defaults("my", (const char **)groups, argcp, argvp)) + return 1; defaults_argc= *argcp; defaults_argv= *argvp; remaining_argc= argc; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 88719ff5bb2..db9e6eda2bc 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -4406,7 +4406,13 @@ sub mysqld_arguments ($$$) { my $mysqld= shift; my $extra_opts= shift; - mtr_add_arg($args, "--defaults-file=%s", $path_config_file); + my @defaults = grep(/^--defaults-file=/, @$extra_opts); + if (@defaults > 0) { + mtr_add_arg($args, pop(@defaults)) + } + else { + mtr_add_arg($args, "--defaults-file=%s", $path_config_file); + } # When mysqld is run by a root user(euid is 0), it will fail # to start unless we specify what user to run as, see BUG#30630 @@ -4442,6 +4448,9 @@ sub mysqld_arguments ($$$) { my $found_skip_core= 0; foreach my $arg ( @$extra_opts ) { + # Skip --defaults-file option since it's handled above. + next if $arg =~ /^--defaults-file/; + # Allow --skip-core-file to be set in -[master|slave].opt file if ($arg eq "--skip-core-file") { diff --git a/mysql-test/std_data/bug57108.cnf b/mysql-test/std_data/bug57108.cnf new file mode 100644 index 00000000000..5fd8c485cf0 --- /dev/null +++ b/mysql-test/std_data/bug57108.cnf @@ -0,0 +1,95 @@ +[mysqld] +open-files-limit=1024 +character-set-server=latin1 +connect-timeout=4711 +log-bin-trust-function-creators=1 +key_buffer_size=1M +sort_buffer=256K +max_heap_table_size=1M +loose-innodb_data_file_path=ibdata1:10M:autoextend +loose-innodb_buffer_pool_size=8M +loose-innodb_write_io_threads=2 +loose-innodb_read_io_threads=2 +loose-innodb_log_buffer_size=1M +loose-innodb_log_file_size=5M +loose-innodb_additional_mem_pool_size=1M +loose-innodb_log_files_in_group=2 +slave-net-timeout=120 +log-bin=mysqld-bin +loose-enable-performance-schema +loose-performance-schema-max-mutex-instances=10000 +loose-performance-schema-max-rwlock-instances=10000 +loose-performance-schema-max-table-instances=500 +loose-performance-schema-max-table-handles=1000 +binlog-direct-non-transactional-updates + +[mysql] +default-character-set=latin1 + +[mysqlshow] +default-character-set=latin1 + +[mysqlimport] +default-character-set=latin1 + +[mysqlcheck] +default-character-set=latin1 + +[mysql_upgrade] +default-character-set=latin1 +tmpdir=/home/bzr/bugs/b57108-5.5-bugteam/mysql-test/var/tmp + +[mysqld.1] +#!run-master-sh +log-bin=master-bin +loose-enable-performance-schema +basedir=/home/bzr/bugs/b57108-5.5-bugteam +tmpdir=/home/bzr/bugs/b57108-5.5-bugteam/mysql-test/var/tmp/mysqld.1 +character-sets-dir=/home/bzr/bugs/b57108-5.5-bugteam/sql/share/charsets +lc-messages-dir=/home/bzr/bugs/b57108-5.5-bugteam/sql/share/ +datadir=/home/bzr/bugs/b57108-5.5-bugteam/mysql-test/var/mysqld.1/data +pid-file=/home/bzr/bugs/b57108-5.5-bugteam/mysql-test/var/run/mysqld.1.pid +#host=localhost +port=13000 +socket=/home/bzr/bugs/b57108-5.5-bugteam/mysql-test/var/tmp/mysqld.1.sock +#log-error=/home/bzr/bugs/b57108-5.5-bugteam/mysql-test/var/log/mysqld.1.err +general_log=1 +general_log_file=/home/bzr/bugs/b57108-5.5-bugteam/mysql-test/var/mysqld.1/mysqld.log +slow_query_log=1 +slow_query_log_file=/home/bzr/bugs/b57108-5.5-bugteam/mysql-test/var/mysqld.1/mysqld-slow.log +#user=root +#password= +server-id=1 +secure-file-priv=/home/bzr/bugs/b57108-5.5-bugteam/mysql-test/var +ssl-ca=/home/bzr/bugs/b57108-5.5-bugteam/mysql-test/std_data/cacert.pem +ssl-cert=/home/bzr/bugs/b57108-5.5-bugteam/mysql-test/std_data/server-cert.pem +ssl-key=/home/bzr/bugs/b57108-5.5-bugteam/mysql-test/std_data/server-key.pem + +[mysqlbinlog] +disable-force-if-open +character-sets-dir=/home/bzr/bugs/b57108-5.5-bugteam/sql/share/charsets + +[ENV] +MASTER_MYPORT=13000 +MASTER_MYSOCK=/home/bzr/bugs/b57108-5.5-bugteam/mysql-test/var/tmp/mysqld.1.sock + +[client] +password= +user=root +port=13000 +host=localhost +socket=/home/bzr/bugs/b57108-5.5-bugteam/mysql-test/var/tmp/mysqld.1.sock + +[mysqltest] +ssl-ca=/home/bzr/bugs/b57108-5.5-bugteam/mysql-test/std_data/cacert.pem +ssl-cert=/home/bzr/bugs/b57108-5.5-bugteam/mysql-test/std_data/client-cert.pem +ssl-key=/home/bzr/bugs/b57108-5.5-bugteam/mysql-test/std_data/client-key.pem +skip-ssl=1 + +[client.1] +password= +user=root +port=13000 +host=localhost +socket=/home/bzr/bugs/b57108-5.5-bugteam/mysql-test/var/tmp/mysqld.1.sock + diff --git a/mysql-test/suite/bugs/r/bug57108.result b/mysql-test/suite/bugs/r/bug57108.result new file mode 100644 index 00000000000..ad60b07a1e3 --- /dev/null +++ b/mysql-test/suite/bugs/r/bug57108.result @@ -0,0 +1,5 @@ +INSTALL PLUGIN example SONAME 'ha_example.so'; +SELECT @@global.connect_timeout AS connect_timeout, @@global.local_infile AS local_infile; +connect_timeout 4711 +local_infile 1 +UNINSTALL PLUGIN example; diff --git a/mysql-test/suite/bugs/t/bug57108-master.opt b/mysql-test/suite/bugs/t/bug57108-master.opt new file mode 100644 index 00000000000..c2ab1c2ead6 --- /dev/null +++ b/mysql-test/suite/bugs/t/bug57108-master.opt @@ -0,0 +1,2 @@ +--defaults-file=std_data/bug57108.cnf +$EXAMPLE_PLUGIN_OPT diff --git a/mysql-test/suite/bugs/t/bug57108.test b/mysql-test/suite/bugs/t/bug57108.test new file mode 100644 index 00000000000..1006a7b30f1 --- /dev/null +++ b/mysql-test/suite/bugs/t/bug57108.test @@ -0,0 +1,12 @@ +--source include/not_windows_embedded.inc +--source include/have_example_plugin.inc + +# Test that we can install a plugin despite the fact that we have +# switched directory after starting the server and am using a relative +# --defaults-file. +--replace_regex /\.dll/.so/ +eval INSTALL PLUGIN example SONAME $HA_EXAMPLE_SO; + +--query_vertical SELECT @@global.connect_timeout AS connect_timeout, @@global.local_infile AS local_infile + +UNINSTALL PLUGIN example; diff --git a/mysys/default.c b/mysys/default.c index 0e0883e1fcf..a57f1150816 100644 --- a/mysys/default.c +++ b/mysys/default.c @@ -66,7 +66,9 @@ const char *args_separator= "----args-separator----"; const char *my_defaults_file=0; const char *my_defaults_group_suffix=0; -char *my_defaults_extra_file=0; +const char *my_defaults_extra_file=0; + +static my_bool defaults_already_read= FALSE; /* Which directories are searched for options (and in which order) */ @@ -139,6 +141,36 @@ static const char **init_default_directories(MEM_ROOT *alloc); static char *remove_end_comment(char *ptr); +/* + Expand a file name so that the current working directory is added if + the name is relative. + + RETURNS + 0 All OK + 2 Out of memory or path to long + 3 Not able to get working directory + */ + +static int +fn_expand(const char *filename, const char **filename_var) +{ + char dir[FN_REFLEN], buf[FN_REFLEN]; + const int flags= MY_UNPACK_FILENAME | MY_SAFE_PATH | MY_RELATIVE_PATH; + const char *result_path= NULL; + DBUG_ENTER("fn_expand"); + DBUG_PRINT("enter", ("filename: %s, buf: 0x%lx", filename, (unsigned long) buf)); + if (my_getwd(dir, sizeof(dir), MYF(0))) + DBUG_RETURN(3); + DBUG_PRINT("debug", ("dir: %s", dir)); + if (fn_format(buf, filename, dir, NULL, flags) == NULL || + (result_path= my_strdup(buf, MYF(0))) == NULL) + DBUG_RETURN(2); + DBUG_PRINT("return", ("result: %s", result_path)); + DBUG_ASSERT(result_path != NULL); + *filename_var= result_path; + DBUG_RETURN(0); +} + /* Process config files in default directories. @@ -167,6 +199,7 @@ static char *remove_end_comment(char *ptr); 0 ok 1 given cinf_file doesn't exist 2 out of memory + 3 Can't get current working directory The global variable 'my_defaults_group_suffix' is updated with value for --defaults_group_suffix @@ -189,11 +222,21 @@ int my_search_option_files(const char *conf_file, int *argc, char ***argv, if (! my_defaults_group_suffix) my_defaults_group_suffix= getenv(STRINGIFY_ARG(DEFAULT_GROUP_SUFFIX_ENV)); - if (forced_extra_defaults) - my_defaults_extra_file= (char *) forced_extra_defaults; - - if (forced_default_file) - my_defaults_file= forced_default_file; + if (forced_extra_defaults && !defaults_already_read) + { + int error= fn_expand(forced_extra_defaults, &my_defaults_extra_file); + if (error) + DBUG_RETURN(error); + } + + if (forced_default_file && !defaults_already_read) + { + int error= fn_expand(forced_default_file, &my_defaults_file); + if (error) + DBUG_RETURN(error); + } + + defaults_already_read= TRUE; /* We can only handle 'defaults-group-suffix' if we are called from @@ -236,15 +279,15 @@ int my_search_option_files(const char *conf_file, int *argc, char ***argv, group->type_names[group->count]= 0; } - if (forced_default_file) + if (my_defaults_file) { if ((error= search_default_file_with_ext(func, func_ctx, "", "", - forced_default_file, 0)) < 0) + my_defaults_file, 0)) < 0) goto err; if (error > 0) { fprintf(stderr, "Could not open required defaults file: %s\n", - forced_default_file); + my_defaults_file); goto err; } } diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 451277712db..0fe89cd3748 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1738,7 +1738,11 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING *dl mysql_mutex_lock(&LOCK_plugin); mysql_rwlock_wrlock(&LOCK_system_variables_hash); - my_load_defaults(MYSQL_CONFIG_NAME, load_default_groups, &argc, &argv, NULL); + if (my_load_defaults(MYSQL_CONFIG_NAME, load_default_groups, &argc, &argv, NULL)) + { + report_error(REPORT_TO_USER, ER_PLUGIN_IS_NOT_LOADED, name->str); + goto err; + } error= plugin_add(thd->mem_root, name, dl, &argc, argv, REPORT_TO_USER); if (argv) free_defaults(argv); From 0752b54a49fbb2c28a1a69e4de11ff68673d570c Mon Sep 17 00:00:00 2001 From: smenon Date: Thu, 4 Nov 2010 11:11:43 +0100 Subject: [PATCH 178/304] Bug #57746: Win directory of source distribution - out-of-date files / support for new files (win/README updated with some more changes) --- win/README | 62 ++++++++++++++++++++++++------------------------------ 1 file changed, 28 insertions(+), 34 deletions(-) diff --git a/win/README b/win/README index 9886fe3a44d..9c8ca9a87bc 100644 --- a/win/README +++ b/win/README @@ -11,6 +11,7 @@ or ealier. The Windows build system uses a tool named CMake to generate build files for a variety of project systems. This tool is combined with a set of jscript files to enable building of MySQL for Windows directly out of a bzr clone. +For relevant information, please refer to http://forge.mysql.com/wiki/CMake The steps required are below. Step 1: @@ -41,53 +42,42 @@ before you start the build) Step 4 ------ -Clone your bzr tree to any location you like. +One of the nice CMake features is "out-of-source" build support, which +means not building in the source directory, but in dedicated build +directory. This keeps the source directory clean and allows for more than +single build tree for the same source tree (e.g debug and release, 32 and +64 bit etc). We'll create subdirectory "bld" in the source directory for +this purpose. Clone your bzr tree to any location you like. Step 5 ------ -From the root of your installation directory, execute the command: +From the root of your installation directory use cmake . -L to see the +various configuration parameters. -win\configure - -The options right now are: - - WITH_INNOBASE_STORAGE_ENGINE Enable particular storage engines - WITH_PARTITION_STORAGE_ENGINE - WITH_ARCHIVE_STORAGE_ENGINE - WITH_BLACKHOLE_STORAGE_ENGINE - WITH_EXAMPLE_STORAGE_ENGINE - WITH_FEDERATED_STORAGE_ENGINE - __NT__ Enable named pipe support - WITHOUT_ATOMICS Do not use atomic instructions - MYSQL_SERVER_SUFFIX= Server suffix, default none - COMPILATION_COMMENT= Server comment, default "Source distribution" - MYSQL_TCP_PORT= Server port, default 3306 - CYBOZU Default character set is UTF8 - EMBED_MANIFESTS Embed custom manifests into final exes, otherwise VS - default will be used. (Note - This option should only be - used by MySQL AB.) - WITH_EMBEDDED_SERVER Configure solution to produce libmysqld.dll - and the static mysqlserver.lib - So the command line could look like: -win\configure WITH_INNOBASE_STORAGE_ENGINE WITH_PARTITION_STORAGE_ENGINE MYSQL_SERVER_SUFFIX=-pro +cmake .. -G "target" -DWITH_INNOBASE_STORAGE_ENGINE=1 + +The recommended way of configuring would be to use -DBUILD_CONFIG=mysql_release +to build binaries exactly the same as the official MySQL releases. Step 6 ------ From the root of your installation directory/bzr clone, you can -use cmake to compile the sources.Use cmake --help when necessary. -Before you run cmake with changed settings (compiler, system -libraries, options, ...), make sure you delete the CMakeCache.txt -generated by your previous run. +use cmake to compile the sources. Use cmake --help when necessary. +Before you start building the sources, please remove the old build area +created from an earlier run and start afresh. + +C:\> del bld +C:\> md bld +C:\> cd bld +C:\> cmake .. -G "target name" -DBUILD_CONFIG=mysql_release -C:\>del CMakeCache.txt -C:\>cmake . -G "target name" For Example: To generate the Win64 project files using Visual Studio 9, you would run -cmake . -G "Visual Studio 9 2008 Win64" +cmake .. -G "Visual Studio 9 2008 Win64" Other target names supported using CMake 2.6 patch 4 are: @@ -99,8 +89,8 @@ Other target names supported using CMake 2.6 patch 4 are: For generating project files using Visual Studio 10, you need CMake 2.8 or higher and corresponding target names are - Visual Studio 10 - Visual Studio 10 Win64 + Visual Studio 10 "Visual Studio 10" + Visual Studio 10 (64 bit) "Visual Studio 10 Win64" Step 7 ------ @@ -109,6 +99,10 @@ From the root of your bzr clone, start your build. For Visual Studio, execute mysql.sln. This will start the IDE and you can click the build solution menu option. +Alternatively, you could start the build from command line as follows + +devenv mysql.sln /build relwithdebinfo + Current issues -------------- 1. After changing configuration (eg. adding or removing a storage engine), it From f0ce67873cd2eb2b6eb30ba1ecb0d3df5206d5a0 Mon Sep 17 00:00:00 2001 From: Jorgen Loland Date: Thu, 4 Nov 2010 13:36:36 +0100 Subject: [PATCH 179/304] Bug#57882 - Item_func_conv_charset::val_str(String*): Assertion `fixed == 1' failed Followup patch. Test case relied on system variable that is only available if replication is compiled in. Replaced with variable available in all builds. mysql-test/r/errors.result: Test case relied on system variable that is only available if replication is compiled in. Replaced with variable available in all builds. mysql-test/t/errors.test: Test case relied on system variable that is only available if replication is compiled in. Replaced with variable available in all builds. --- mysql-test/r/errors.result | 2 +- mysql-test/t/errors.test | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/errors.result b/mysql-test/r/errors.result index 43cabd28498..e6a1b492b39 100644 --- a/mysql-test/r/errors.result +++ b/mysql-test/r/errors.result @@ -141,7 +141,7 @@ DROP TABLE t1; SELECT (CONVERT('0' USING latin1) IN (CHAR(COT('v') USING utf8),'')); ERROR 22003: DOUBLE value is out of range in 'cot('v')' SET NAMES utf8 COLLATE utf8_latvian_ci ; -SELECT UPDATEXML(-73 * -2465717823867977728,@@global.slave_net_timeout,null); +SELECT UPDATEXML(-73 * -2465717823867977728,@@global.auto_increment_increment,null); ERROR 22003: BIGINT value is out of range in '(-(73) * -(2465717823867977728))' # # End Bug#57882 diff --git a/mysql-test/t/errors.test b/mysql-test/t/errors.test index 8de5889f1c6..82822c87e89 100644 --- a/mysql-test/t/errors.test +++ b/mysql-test/t/errors.test @@ -166,7 +166,7 @@ SELECT (CONVERT('0' USING latin1) IN (CHAR(COT('v') USING utf8),'')); SET NAMES utf8 COLLATE utf8_latvian_ci ; --error ER_DATA_OUT_OF_RANGE -SELECT UPDATEXML(-73 * -2465717823867977728,@@global.slave_net_timeout,null); +SELECT UPDATEXML(-73 * -2465717823867977728,@@global.auto_increment_increment,null); --echo # --echo # End Bug#57882 From 57cb45514dd00b2afd48e9a0b8b36730ac350e72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 4 Nov 2010 15:12:15 +0200 Subject: [PATCH 180/304] row_ins_index_entry(): Note that only CREATE INDEX sets foreign=FALSE. --- storage/innodb_plugin/include/row0ins.h | 3 ++- storage/innodb_plugin/row/row0ins.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/storage/innodb_plugin/include/row0ins.h b/storage/innodb_plugin/include/row0ins.h index c780d228a45..810973e61a7 100644 --- a/storage/innodb_plugin/include/row0ins.h +++ b/storage/innodb_plugin/include/row0ins.h @@ -86,7 +86,8 @@ row_ins_index_entry( dict_index_t* index, /*!< in: index */ dtuple_t* entry, /*!< in/out: index entry to insert */ ulint n_ext, /*!< in: number of externally stored columns */ - ibool foreign,/*!< in: TRUE=check foreign key constraints */ + ibool foreign,/*!< in: TRUE=check foreign key constraints + (foreign=FALSE only during CREATE INDEX) */ que_thr_t* thr); /*!< in: query thread */ /***********************************************************//** Inserts a row to a table. This is a high-level function used in diff --git a/storage/innodb_plugin/row/row0ins.c b/storage/innodb_plugin/row/row0ins.c index 81b58465e11..298c601c7e3 100644 --- a/storage/innodb_plugin/row/row0ins.c +++ b/storage/innodb_plugin/row/row0ins.c @@ -2160,7 +2160,8 @@ row_ins_index_entry( dict_index_t* index, /*!< in: index */ dtuple_t* entry, /*!< in/out: index entry to insert */ ulint n_ext, /*!< in: number of externally stored columns */ - ibool foreign,/*!< in: TRUE=check foreign key constraints */ + ibool foreign,/*!< in: TRUE=check foreign key constraints + (foreign=FALSE only during CREATE INDEX) */ que_thr_t* thr) /*!< in: query thread */ { ulint err; From 368ac9f03ef9c1f0c9d02985c13708ac52cfbfaf Mon Sep 17 00:00:00 2001 From: Evgeny Potemkin Date: Thu, 4 Nov 2010 16:18:27 +0300 Subject: [PATCH 181/304] Bug#57278: Crash on min/max + with date out of range. MySQL officially supports DATE values starting from 1000-01-01. This is enforced for int values, but not for string values, thus one could easily insert '0001-01-01' value. Int values are checked by number_to_datetime function and Item_cache_datetime::val_str uses it to fill MYSQL_TIME struct out of cached int value. This leads to the scenario where Item_cache_datetime caches a non-null datetime value and when it tries to convert it from int to string number_to_datetime function treats the value as out-of-range and returns an error and Item_cache_datetime::val_str returns NULL for a non-null value. Due to this inconsistency server crashes. Now number_to_datetime allows DATE values below 1000-01-01 if the TIME_FUZZY_DATE flag is set. Better NULL handling for Item_cache_datetime. Added the Item_cache_datetime::store function to reset str_value_cached flag when an item is stored. mysql-test/r/type_date.result: Added a test case for the bug#57278. mysql-test/t/type_date.test: Added a test case for the bug#57278. sql-common/my_time.c: Bug#57278: Crash on min/max + with date out of range. Now number_to_datetime allows DATE values below 1000-01-01 if the TIME_FUZZY_DATE flag is set. sql/item.cc: Bug#57278: Crash on min/max + with date out of range. Item_cache_datetime::val_str now better handles null_value. --- mysql-test/r/type_date.result | 8 ++++++++ mysql-test/t/type_date.test | 8 ++++++++ sql-common/my_time.c | 7 ++++++- sql/item.cc | 19 ++++++++++++++++--- sql/item.h | 2 +- 5 files changed, 39 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/type_date.result b/mysql-test/r/type_date.result index bb441099b98..41345be5b8d 100644 --- a/mysql-test/r/type_date.result +++ b/mysql-test/r/type_date.result @@ -318,4 +318,12 @@ f1 date YES NULL f2 date YES NULL DROP TABLE t1; # +# +# Bug#57278: Crash on min/max + with date out of range. +# +set @a=(select min(makedate('111','1'))) ; +select @a; +@a +0111-01-01 +# End of 6.0 tests diff --git a/mysql-test/t/type_date.test b/mysql-test/t/type_date.test index 11f2b68804a..6dec86dacab 100644 --- a/mysql-test/t/type_date.test +++ b/mysql-test/t/type_date.test @@ -284,4 +284,12 @@ DROP TABLE t1; --echo # +--echo # +--echo # Bug#57278: Crash on min/max + with date out of range. +--echo # +set @a=(select min(makedate('111','1'))) ; +select @a; +--echo # + + --echo End of 6.0 tests diff --git a/sql-common/my_time.c b/sql-common/my_time.c index ac6c2ace890..38384600fc1 100644 --- a/sql-common/my_time.c +++ b/sql-common/my_time.c @@ -1127,7 +1127,12 @@ longlong number_to_datetime(longlong nr, MYSQL_TIME *time_res, nr= (nr+19000000L)*1000000L; /* YYMMDD, year: 1970-1999 */ goto ok; } - if (nr < 10000101L) + /* + Though officially we support DATE values from 1000-01-01 only, one can + easily insert a value like 1-1-1. So, for consistency reasons such dates + are allowed when TIME_FUZZY_DATE is set. + */ + if (nr < 10000101L && !(flags & TIME_FUZZY_DATE)) goto err; if (nr <= 99991231L) { diff --git a/sql/item.cc b/sql/item.cc index b166f3e645f..7efbdf162a7 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -7493,9 +7493,19 @@ void Item_cache_datetime::store(Item *item, longlong val_arg) } +void Item_cache_datetime::store(Item *item) +{ + Item_cache::store(item); + str_value_cached= FALSE; +} + String *Item_cache_datetime::val_str(String *str) { DBUG_ASSERT(fixed == 1); + + if ((value_cached || str_value_cached) && null_value) + return NULL; + if (!str_value_cached) { /* @@ -7509,6 +7519,8 @@ String *Item_cache_datetime::val_str(String *str) if (value_cached) { MYSQL_TIME ltime; + /* Return NULL in case of OOM/conversion error. */ + null_value= TRUE; if (str_value.alloc(MAX_DATE_STRING_REP_LENGTH)) return NULL; if (cached_field_type == MYSQL_TYPE_TIME) @@ -7531,13 +7543,14 @@ String *Item_cache_datetime::val_str(String *str) { int was_cut; longlong res; - res= number_to_datetime(val_int(), <ime, TIME_FUZZY_DATE, &was_cut); + res= number_to_datetime(int_value, <ime, TIME_FUZZY_DATE, &was_cut); if (res == -1) return NULL; } str_value.length(my_TIME_to_str(<ime, const_cast(str_value.ptr()))); str_value_cached= TRUE; + null_value= FALSE; } else if (!cache_value()) return NULL; @@ -7558,7 +7571,7 @@ my_decimal *Item_cache_datetime::val_decimal(my_decimal *decimal_val) double Item_cache_datetime::val_real() { DBUG_ASSERT(fixed == 1); - if (!value_cached && !cache_value_int()) + if ((!value_cached && !cache_value_int()) || null_value) return 0.0; return (double) int_value; } @@ -7566,7 +7579,7 @@ double Item_cache_datetime::val_real() longlong Item_cache_datetime::val_int() { DBUG_ASSERT(fixed == 1); - if (!value_cached && !cache_value_int()) + if ((!value_cached && !cache_value_int()) || null_value) return 0; return int_value; } diff --git a/sql/item.h b/sql/item.h index 8e8199ecac8..b46f78853b7 100644 --- a/sql/item.h +++ b/sql/item.h @@ -3451,8 +3451,8 @@ public: cmp_context= STRING_RESULT; } - virtual void store(Item *item) { Item_cache::store(item); } void store(Item *item, longlong val_arg); + void store(Item *item); double val_real(); longlong val_int(); String* val_str(String *str); From adc189aecef38fe743f73371da3b9ec229db6521 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 4 Nov 2010 10:18:05 -0500 Subject: [PATCH 182/304] Bug57960 - In ha_innodb.cc, get_foreign_key_info() make sure the referenced_table name uses the actual length of the table name. --- mysql-test/suite/innodb/r/innodb_bug57904.result | 4 ++-- storage/innobase/handler/ha_innodb.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mysql-test/suite/innodb/r/innodb_bug57904.result b/mysql-test/suite/innodb/r/innodb_bug57904.result index c3e980a6cf4..84868dcf46b 100755 --- a/mysql-test/suite/innodb/r/innodb_bug57904.result +++ b/mysql-test/suite/innodb/r/innodb_bug57904.result @@ -24,7 +24,7 @@ MATCH_OPTION NONE UPDATE_RULE CASCADE DELETE_RULE RESTRICT TABLE_NAME product_order -REFERENCED_TABLE_NAME pro +REFERENCED_TABLE_NAME product CONSTRAINT_CATALOG def CONSTRAINT_SCHEMA test CONSTRAINT_NAME product_order_ibfk_2 @@ -35,7 +35,7 @@ MATCH_OPTION NONE UPDATE_RULE RESTRICT DELETE_RULE RESTRICT TABLE_NAME product_order -REFERENCED_TABLE_NAME cus +REFERENCED_TABLE_NAME customer DROP TABLE product_order; DROP TABLE product; DROP TABLE customer; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index ed391972a95..ee42d6c6500 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -8358,7 +8358,7 @@ get_foreign_key_info( /* Referenced (parent) table name */ ptr = dict_remove_db_name(foreign->referenced_table_name); - len = filename_to_tablename(ptr, name_buff, sizeof(name)); + len = filename_to_tablename(ptr, name_buff, sizeof(name_buff)); f_key_info.referenced_table = thd_make_lex_string(thd, 0, name_buff, len, 1); /* Dependent (child) database name */ From aafb35d09975170b6162a9bcd3b2c35cdb78579d Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Fri, 5 Nov 2010 08:23:39 +0000 Subject: [PATCH 183/304] BUG#57899: Certain reserved words should not be reserved Small fix for the test case. The column named "slow" was used twice in the SELECTs. As a consequence, the column named "ignore_server_ids" was not used. To fix this we simply replace the second column selected named "slow" with a column named "ignore_server_ids". --- mysql-test/r/keywords.result | 80 ++++++++++++++++++------------------ mysql-test/t/keywords.test | 8 ++-- 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/mysql-test/r/keywords.result b/mysql-test/r/keywords.result index 977fe7791b9..58cb7430563 100644 --- a/mysql-test/r/keywords.result +++ b/mysql-test/r/keywords.result @@ -50,16 +50,16 @@ INSERT INTO slow(slow, general, master_heartbeat_period, ignore_server_ids) VALU INSERT INTO slow(slow, general, master_heartbeat_period) VALUES (1,2,3), (5,6,7); INSERT INTO slow(slow, general) VALUES (1,2), (5,6); INSERT INTO slow(slow) VALUES (1), (5); -SELECT slow, general, master_heartbeat_period, slow FROM slow ORDER BY slow; -slow general master_heartbeat_period slow -1 2 3 1 -1 2 3 1 -1 2 NULL 1 -1 NULL NULL 1 -5 6 7 5 -5 6 7 5 -5 6 NULL 5 -5 NULL NULL 5 +SELECT slow, general, master_heartbeat_period, ignore_server_ids FROM slow ORDER BY slow; +slow general master_heartbeat_period ignore_server_ids +1 2 3 4 +1 2 3 NULL +1 2 NULL NULL +1 NULL NULL NULL +5 6 7 8 +5 6 7 NULL +5 6 NULL NULL +5 NULL NULL NULL SELECT slow, general, master_heartbeat_period FROM slow ORDER BY slow; slow general master_heartbeat_period 1 2 3 @@ -96,16 +96,16 @@ INSERT INTO general(slow, general, master_heartbeat_period, ignore_server_ids) V INSERT INTO general(slow, general, master_heartbeat_period) VALUES (1,2,3), (5,6,7); INSERT INTO general(slow, general) VALUES (1,2), (5,6); INSERT INTO general(slow) VALUES (1), (5); -SELECT slow, general, master_heartbeat_period, slow FROM general ORDER BY slow; -slow general master_heartbeat_period slow -1 2 3 1 -1 2 3 1 -1 2 NULL 1 -1 NULL NULL 1 -5 6 7 5 -5 6 7 5 -5 6 NULL 5 -5 NULL NULL 5 +SELECT slow, general, master_heartbeat_period, ignore_server_ids FROM general ORDER BY slow; +slow general master_heartbeat_period ignore_server_ids +1 2 3 4 +1 2 3 NULL +1 2 NULL NULL +1 NULL NULL NULL +5 6 7 8 +5 6 7 NULL +5 6 NULL NULL +5 NULL NULL NULL SELECT slow, general, master_heartbeat_period FROM general ORDER BY slow; slow general master_heartbeat_period 1 2 3 @@ -142,16 +142,16 @@ INSERT INTO master_heartbeat_period(slow, general, master_heartbeat_period, igno INSERT INTO master_heartbeat_period(slow, general, master_heartbeat_period) VALUES (1,2,3), (5,6,7); INSERT INTO master_heartbeat_period(slow, general) VALUES (1,2), (5,6); INSERT INTO master_heartbeat_period(slow) VALUES (1), (5); -SELECT slow, general, master_heartbeat_period, slow FROM master_heartbeat_period ORDER BY slow; -slow general master_heartbeat_period slow -1 2 3 1 -1 2 3 1 -1 2 NULL 1 -1 NULL NULL 1 -5 6 7 5 -5 6 7 5 -5 6 NULL 5 -5 NULL NULL 5 +SELECT slow, general, master_heartbeat_period, ignore_server_ids FROM master_heartbeat_period ORDER BY slow; +slow general master_heartbeat_period ignore_server_ids +1 2 3 4 +1 2 3 NULL +1 2 NULL NULL +1 NULL NULL NULL +5 6 7 8 +5 6 7 NULL +5 6 NULL NULL +5 NULL NULL NULL SELECT slow, general, master_heartbeat_period FROM master_heartbeat_period ORDER BY slow; slow general master_heartbeat_period 1 2 3 @@ -188,16 +188,16 @@ INSERT INTO ignore_server_ids(slow, general, master_heartbeat_period, ignore_ser INSERT INTO ignore_server_ids(slow, general, master_heartbeat_period) VALUES (1,2,3), (5,6,7); INSERT INTO ignore_server_ids(slow, general) VALUES (1,2), (5,6); INSERT INTO ignore_server_ids(slow) VALUES (1), (5); -SELECT slow, general, master_heartbeat_period, slow FROM ignore_server_ids ORDER BY slow; -slow general master_heartbeat_period slow -1 2 3 1 -1 2 3 1 -1 2 NULL 1 -1 NULL NULL 1 -5 6 7 5 -5 6 7 5 -5 6 NULL 5 -5 NULL NULL 5 +SELECT slow, general, master_heartbeat_period, ignore_server_ids FROM ignore_server_ids ORDER BY slow; +slow general master_heartbeat_period ignore_server_ids +1 2 3 4 +1 2 3 NULL +1 2 NULL NULL +1 NULL NULL NULL +5 6 7 8 +5 6 7 NULL +5 6 NULL NULL +5 NULL NULL NULL SELECT slow, general, master_heartbeat_period FROM ignore_server_ids ORDER BY slow; slow general master_heartbeat_period 1 2 3 diff --git a/mysql-test/t/keywords.test b/mysql-test/t/keywords.test index 2681f786f40..08016313ca7 100644 --- a/mysql-test/t/keywords.test +++ b/mysql-test/t/keywords.test @@ -78,7 +78,7 @@ INSERT INTO slow(slow, general, master_heartbeat_period, ignore_server_ids) VALU INSERT INTO slow(slow, general, master_heartbeat_period) VALUES (1,2,3), (5,6,7); INSERT INTO slow(slow, general) VALUES (1,2), (5,6); INSERT INTO slow(slow) VALUES (1), (5); -SELECT slow, general, master_heartbeat_period, slow FROM slow ORDER BY slow; +SELECT slow, general, master_heartbeat_period, ignore_server_ids FROM slow ORDER BY slow; SELECT slow, general, master_heartbeat_period FROM slow ORDER BY slow; SELECT slow, master_heartbeat_period FROM slow ORDER BY slow; SELECT slow FROM slow ORDER BY slow; @@ -88,7 +88,7 @@ INSERT INTO general(slow, general, master_heartbeat_period, ignore_server_ids) V INSERT INTO general(slow, general, master_heartbeat_period) VALUES (1,2,3), (5,6,7); INSERT INTO general(slow, general) VALUES (1,2), (5,6); INSERT INTO general(slow) VALUES (1), (5); -SELECT slow, general, master_heartbeat_period, slow FROM general ORDER BY slow; +SELECT slow, general, master_heartbeat_period, ignore_server_ids FROM general ORDER BY slow; SELECT slow, general, master_heartbeat_period FROM general ORDER BY slow; SELECT slow, master_heartbeat_period FROM general ORDER BY slow; SELECT slow FROM general ORDER BY slow; @@ -98,7 +98,7 @@ INSERT INTO master_heartbeat_period(slow, general, master_heartbeat_period, igno INSERT INTO master_heartbeat_period(slow, general, master_heartbeat_period) VALUES (1,2,3), (5,6,7); INSERT INTO master_heartbeat_period(slow, general) VALUES (1,2), (5,6); INSERT INTO master_heartbeat_period(slow) VALUES (1), (5); -SELECT slow, general, master_heartbeat_period, slow FROM master_heartbeat_period ORDER BY slow; +SELECT slow, general, master_heartbeat_period, ignore_server_ids FROM master_heartbeat_period ORDER BY slow; SELECT slow, general, master_heartbeat_period FROM master_heartbeat_period ORDER BY slow; SELECT slow, master_heartbeat_period FROM master_heartbeat_period ORDER BY slow; SELECT slow FROM master_heartbeat_period ORDER BY slow; @@ -108,7 +108,7 @@ INSERT INTO ignore_server_ids(slow, general, master_heartbeat_period, ignore_ser INSERT INTO ignore_server_ids(slow, general, master_heartbeat_period) VALUES (1,2,3), (5,6,7); INSERT INTO ignore_server_ids(slow, general) VALUES (1,2), (5,6); INSERT INTO ignore_server_ids(slow) VALUES (1), (5); -SELECT slow, general, master_heartbeat_period, slow FROM ignore_server_ids ORDER BY slow; +SELECT slow, general, master_heartbeat_period, ignore_server_ids FROM ignore_server_ids ORDER BY slow; SELECT slow, general, master_heartbeat_period FROM ignore_server_ids ORDER BY slow; SELECT slow, master_heartbeat_period FROM ignore_server_ids ORDER BY slow; SELECT slow FROM ignore_server_ids ORDER BY slow; From c04318ed243fd85eeb7256399516a9189e12a0b0 Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Fri, 5 Nov 2010 12:01:10 +0100 Subject: [PATCH 184/304] Bug#57778: failed primary key add to partitioned innodb table inconsistent and crashes It was possible to issue an ALTER TABLE ADD PRIMARY KEY on an partitioned InnoDB table that failed and crashed the server. The problem was that it succeeded to create the PK on at least one partition, and then failed on a subsequent partition, due to duplicate key violation. Since the partitions that already had added the PK was not reverted all partitions was not consistent with the table definition, which caused the crash. The solution was to add a revert step to ha_partition::add_index() that dropped the index for the already succeeded partitions, on failure. mysql-test/r/partition.result: updated result mysql-test/t/partition.test: Added test sql/ha_partition.cc: Only allow ADD/DROP flags in pairs, so that they can be reverted on failures. If add_index() fails for a partition, revert (drop the index) for the previous partitions. sql/handler.h: Added some extra info in a comment. --- mysql-test/r/partition.result | 33 +++++++++++++++++++ mysql-test/t/partition.test | 18 ++++++++++ sql/ha_partition.cc | 62 ++++++++++++++++++++++++++++++++--- sql/handler.h | 2 ++ 4 files changed, 111 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index 80676c0d324..a639f9e6b3b 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -1,5 +1,38 @@ drop table if exists t1, t2; # +# Bug#57778: failed primary key add to partitioned innodb table +# inconsistent and crashes +# +CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL) +PARTITION BY KEY (a) PARTITIONS 2; +INSERT INTO t1 VALUES (0,1), (0,2); +ALTER TABLE t1 ADD PRIMARY KEY (a); +ERROR 23000: Duplicate entry '0' for key 'PRIMARY' +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL, + `b` int(11) NOT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY KEY (a) +PARTITIONS 2 */ +SELECT * FROM t1; +a b +0 1 +0 2 +UPDATE t1 SET a = 1, b = 1 WHERE a = 0 AND b = 2; +ALTER TABLE t1 ADD PRIMARY KEY (a); +SELECT * FROM t1; +a b +1 1 +0 1 +ALTER TABLE t1 DROP PRIMARY KEY; +SELECT * FROM t1; +a b +1 1 +0 1 +DROP TABLE t1; +# # Bug#57113: ha_partition::extra(ha_extra_function): # Assertion `m_extra_cache' failed CREATE TABLE t1 diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index 68239c06660..cf3dcfadb27 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -14,6 +14,24 @@ drop table if exists t1, t2; --enable_warnings +--echo # +--echo # Bug#57778: failed primary key add to partitioned innodb table +--echo # inconsistent and crashes +--echo # +CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL) +PARTITION BY KEY (a) PARTITIONS 2; +INSERT INTO t1 VALUES (0,1), (0,2); +--error ER_DUP_ENTRY +ALTER TABLE t1 ADD PRIMARY KEY (a); +SHOW CREATE TABLE t1; +SELECT * FROM t1; +UPDATE t1 SET a = 1, b = 1 WHERE a = 0 AND b = 2; +ALTER TABLE t1 ADD PRIMARY KEY (a); +SELECT * FROM t1; +ALTER TABLE t1 DROP PRIMARY KEY; +SELECT * FROM t1; +DROP TABLE t1; + --echo # --echo # Bug#57113: ha_partition::extra(ha_extra_function): --echo # Assertion `m_extra_cache' failed diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 3d8d5ae9eb8..70cf8480ba1 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -6375,9 +6375,42 @@ bool ha_partition::get_error_message(int error, String *buf) */ uint ha_partition::alter_table_flags(uint flags) { + uint flags_to_return, flags_to_check; DBUG_ENTER("ha_partition::alter_table_flags"); - DBUG_RETURN(ht->alter_table_flags(flags) | - m_file[0]->alter_table_flags(flags)); + + flags_to_return= ht->alter_table_flags(flags); + flags_to_return|= m_file[0]->alter_table_flags(flags); + + /* + If one partition fails we must be able to revert the change for the other, + already altered, partitions. So both ADD and DROP can only be supported in + pairs. + */ + flags_to_check= HA_ONLINE_ADD_INDEX_NO_WRITES; + flags_to_check|= HA_ONLINE_DROP_INDEX_NO_WRITES; + if ((flags_to_return & flags_to_check) != flags_to_check) + flags_to_return&= ~flags_to_check; + flags_to_check= HA_ONLINE_ADD_UNIQUE_INDEX_NO_WRITES; + flags_to_check|= HA_ONLINE_DROP_UNIQUE_INDEX_NO_WRITES; + if ((flags_to_return & flags_to_check) != flags_to_check) + flags_to_return&= ~flags_to_check; + flags_to_check= HA_ONLINE_ADD_PK_INDEX_NO_WRITES; + flags_to_check|= HA_ONLINE_DROP_PK_INDEX_NO_WRITES; + if ((flags_to_return & flags_to_check) != flags_to_check) + flags_to_return&= ~flags_to_check; + flags_to_check= HA_ONLINE_ADD_INDEX; + flags_to_check|= HA_ONLINE_DROP_INDEX; + if ((flags_to_return & flags_to_check) != flags_to_check) + flags_to_return&= ~flags_to_check; + flags_to_check= HA_ONLINE_ADD_UNIQUE_INDEX; + flags_to_check|= HA_ONLINE_DROP_UNIQUE_INDEX; + if ((flags_to_return & flags_to_check) != flags_to_check) + flags_to_return&= ~flags_to_check; + flags_to_check= HA_ONLINE_ADD_PK_INDEX; + flags_to_check|= HA_ONLINE_DROP_PK_INDEX; + if ((flags_to_return & flags_to_check) != flags_to_check) + flags_to_return&= ~flags_to_check; + DBUG_RETURN(flags_to_return); } @@ -6412,6 +6445,7 @@ int ha_partition::add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys) handler **file; int ret= 0; + DBUG_ENTER("ha_partition::add_index"); /* There has already been a check in fix_partition_func in mysql_alter_table before this call, which checks for unique/primary key violations of the @@ -6419,8 +6453,28 @@ int ha_partition::add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys) */ for (file= m_file; *file; file++) if ((ret= (*file)->add_index(table_arg, key_info, num_of_keys))) - break; - return ret; + goto err; + DBUG_RETURN(ret); +err: + if (file > m_file) + { + uint *key_numbers= (uint*) ha_thd()->alloc(sizeof(uint) * num_of_keys); + uint old_num_of_keys= table_arg->s->keys; + uint i; + /* The newly created keys have the last id's */ + for (i= 0; i < num_of_keys; i++) + key_numbers[i]= i + old_num_of_keys; + if (!table_arg->key_info) + table_arg->key_info= key_info; + while (--file >= m_file) + { + (void) (*file)->prepare_drop_index(table_arg, key_numbers, num_of_keys); + (void) (*file)->final_drop_index(table_arg); + } + if (table_arg->key_info == key_info) + table_arg->key_info= NULL; + } + DBUG_RETURN(ret); } diff --git a/sql/handler.h b/sql/handler.h index 325df003215..0e03ea17dde 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -174,6 +174,8 @@ /* These bits are set if different kinds of indexes can be created off-line without re-create of the table (but with a table lock). + Partitioning needs both ADD and DROP to be supported by its underlying + handlers, due to error handling, see bug#57778. */ #define HA_ONLINE_ADD_INDEX_NO_WRITES (1L << 0) /*add index w/lock*/ #define HA_ONLINE_DROP_INDEX_NO_WRITES (1L << 1) /*drop index w/lock*/ From cf1b01e28f40bb7e93c9b66eca6715a7cb38fb63 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Fri, 5 Nov 2010 12:28:17 +0100 Subject: [PATCH 185/304] Bug #57749 vs-config option of mysql-test-run does not work Option was incorrectly coded without an argument Added the missing =s --- mysql-test/mysql-test-run.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index ed7dedf7adc..fd9c6ce5432 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -887,7 +887,7 @@ sub command_line_setup { 'ssl|with-openssl' => \$opt_ssl, 'skip-ssl' => \$opt_skip_ssl, 'compress' => \$opt_compress, - 'vs-config' => \$opt_vs_config, + 'vs-config=s' => \$opt_vs_config, # Max number of parallel threads to use 'parallel=s' => \$opt_parallel, From 03b9e73878c8953d8228dfefb0a14d4c09756cf3 Mon Sep 17 00:00:00 2001 From: Guilhem Bichot Date: Fri, 5 Nov 2010 14:16:27 +0100 Subject: [PATCH 186/304] Fix for BUG#57316 "It is not clear how to disable autocommit" add boolean command-line option --autocommit. mysql-test/mysql-test-run.pl: do in --gdb like in --ddd: to let the developer debug the startup phase (like command-line options parsing), don't "run". It's the third time I do this change, it was previously lost by merges, port of 6.0 to next-mr... mysql-test/r/mysqld--help-notwin.result: new command-line option mysql-test/r/mysqld--help-win.result: a Linux user's best guess at what the Windows result should be mysql-test/suite/sys_vars/inc/autocommit_func2.inc: new test mysql-test/suite/sys_vars/t/autocommit_func2-master.opt: test new option mysql-test/suite/sys_vars/t/autocommit_func3-master.opt: test new option sql/mysqld.cc: new --autocommit sql/mysqld.h: new --autocommit sql/sql_partition.cc: What matters to this partitioning quote is to have the OPTION_QUOTE_SHOW_CREATE flag down, it's all that append_identifier() uses. So we make it explicit. --- mysql-test/mysql-test-run.pl | 3 +- mysql-test/r/mysqld--help-notwin.result | 1 + mysql-test/r/mysqld--help-win.result | 1 + .../suite/sys_vars/inc/autocommit_func2.inc | 29 ++++++++++++ .../suite/sys_vars/r/autocommit_func2.result | 46 +++++++++++++++++++ .../suite/sys_vars/r/autocommit_func3.result | 42 +++++++++++++++++ .../sys_vars/t/autocommit_func2-master.opt | 1 + .../suite/sys_vars/t/autocommit_func2.test | 1 + .../sys_vars/t/autocommit_func3-master.opt | 1 + .../suite/sys_vars/t/autocommit_func3.test | 1 + sql/mysqld.cc | 13 ++++++ sql/mysqld.h | 3 +- sql/sql_partition.cc | 5 +- 13 files changed, 141 insertions(+), 6 deletions(-) create mode 100644 mysql-test/suite/sys_vars/inc/autocommit_func2.inc create mode 100644 mysql-test/suite/sys_vars/r/autocommit_func2.result create mode 100644 mysql-test/suite/sys_vars/r/autocommit_func3.result create mode 100644 mysql-test/suite/sys_vars/t/autocommit_func2-master.opt create mode 100644 mysql-test/suite/sys_vars/t/autocommit_func2.test create mode 100644 mysql-test/suite/sys_vars/t/autocommit_func3-master.opt create mode 100644 mysql-test/suite/sys_vars/t/autocommit_func3.test diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 05d4dacaf71..6b8d73b3f69 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -5317,8 +5317,7 @@ sub gdb_arguments { "break mysql_parse\n" . "commands 1\n" . "disable 1\n" . - "end\n" . - "run"); + "end\n"); } if ( $opt_manual_gdb ) diff --git a/mysql-test/r/mysqld--help-notwin.result b/mysql-test/r/mysqld--help-notwin.result index 63e17e1c188..fc269e1dd82 100644 --- a/mysql-test/r/mysqld--help-notwin.result +++ b/mysql-test/r/mysqld--help-notwin.result @@ -19,6 +19,7 @@ The following options may be given as the first argument: --auto-increment-offset[=#] Offset added to Auto-increment columns. Used when auto-increment-increment != 1 + --autocommit Set default value for autocommit (0 or 1) --automatic-sp-privileges Creating and dropping stored procedures alters ACLs (Defaults to on; use --skip-automatic-sp-privileges to disable.) diff --git a/mysql-test/r/mysqld--help-win.result b/mysql-test/r/mysqld--help-win.result index c5996981e92..c5d7bb458c3 100644 --- a/mysql-test/r/mysqld--help-win.result +++ b/mysql-test/r/mysqld--help-win.result @@ -19,6 +19,7 @@ The following options may be given as the first argument: --auto-increment-offset[=#] Offset added to Auto-increment columns. Used when auto-increment-increment != 1 + --autocommit Set default value for autocommit (0 or 1) --automatic-sp-privileges Creating and dropping stored procedures alters ACLs (Defaults to on; use --skip-automatic-sp-privileges to disable.) diff --git a/mysql-test/suite/sys_vars/inc/autocommit_func2.inc b/mysql-test/suite/sys_vars/inc/autocommit_func2.inc new file mode 100644 index 00000000000..5fff72157b4 --- /dev/null +++ b/mysql-test/suite/sys_vars/inc/autocommit_func2.inc @@ -0,0 +1,29 @@ +--source include/have_innodb.inc + +CREATE TABLE t1 +( +id INT NOT NULL auto_increment, +PRIMARY KEY (id), +name varchar(30) +) ENGINE = INNODB; + +SELECT @@global.autocommit; +SELECT @@autocommit; +INSERT into t1(name) values('Record_1'); +INSERT into t1(name) values('Record_2'); +SELECT * from t1; +ROLLBACK; +SELECT * from t1; + +set @@global.autocommit = 1-@@global.autocommit; +set @@autocommit = 1-@@autocommit; +SELECT @@global.autocommit; +SELECT @@autocommit; +INSERT into t1(name) values('Record_1'); +INSERT into t1(name) values('Record_2'); +SELECT * from t1; +ROLLBACK; +SELECT * from t1; + +DROP TABLE t1; +set @@global.autocommit = 1-@@global.autocommit; diff --git a/mysql-test/suite/sys_vars/r/autocommit_func2.result b/mysql-test/suite/sys_vars/r/autocommit_func2.result new file mode 100644 index 00000000000..5fcb50526f2 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/autocommit_func2.result @@ -0,0 +1,46 @@ +CREATE TABLE t1 +( +id INT NOT NULL auto_increment, +PRIMARY KEY (id), +name varchar(30) +) ENGINE = INNODB; +SELECT @@global.autocommit; +@@global.autocommit +1 +SELECT @@autocommit; +@@autocommit +1 +INSERT into t1(name) values('Record_1'); +INSERT into t1(name) values('Record_2'); +SELECT * from t1; +id name +1 Record_1 +2 Record_2 +ROLLBACK; +SELECT * from t1; +id name +1 Record_1 +2 Record_2 +set @@global.autocommit = 1-@@global.autocommit; +set @@autocommit = 1-@@autocommit; +SELECT @@global.autocommit; +@@global.autocommit +0 +SELECT @@autocommit; +@@autocommit +0 +INSERT into t1(name) values('Record_1'); +INSERT into t1(name) values('Record_2'); +SELECT * from t1; +id name +1 Record_1 +2 Record_2 +3 Record_1 +4 Record_2 +ROLLBACK; +SELECT * from t1; +id name +1 Record_1 +2 Record_2 +DROP TABLE t1; +set @@global.autocommit = 1-@@global.autocommit; diff --git a/mysql-test/suite/sys_vars/r/autocommit_func3.result b/mysql-test/suite/sys_vars/r/autocommit_func3.result new file mode 100644 index 00000000000..6807c594cb1 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/autocommit_func3.result @@ -0,0 +1,42 @@ +CREATE TABLE t1 +( +id INT NOT NULL auto_increment, +PRIMARY KEY (id), +name varchar(30) +) ENGINE = INNODB; +SELECT @@global.autocommit; +@@global.autocommit +0 +SELECT @@autocommit; +@@autocommit +0 +INSERT into t1(name) values('Record_1'); +INSERT into t1(name) values('Record_2'); +SELECT * from t1; +id name +1 Record_1 +2 Record_2 +ROLLBACK; +SELECT * from t1; +id name +set @@global.autocommit = 1-@@global.autocommit; +set @@autocommit = 1-@@autocommit; +SELECT @@global.autocommit; +@@global.autocommit +1 +SELECT @@autocommit; +@@autocommit +1 +INSERT into t1(name) values('Record_1'); +INSERT into t1(name) values('Record_2'); +SELECT * from t1; +id name +3 Record_1 +4 Record_2 +ROLLBACK; +SELECT * from t1; +id name +3 Record_1 +4 Record_2 +DROP TABLE t1; +set @@global.autocommit = 1-@@global.autocommit; diff --git a/mysql-test/suite/sys_vars/t/autocommit_func2-master.opt b/mysql-test/suite/sys_vars/t/autocommit_func2-master.opt new file mode 100644 index 00000000000..85e5d17d5e8 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/autocommit_func2-master.opt @@ -0,0 +1 @@ +--autocommit=1 diff --git a/mysql-test/suite/sys_vars/t/autocommit_func2.test b/mysql-test/suite/sys_vars/t/autocommit_func2.test new file mode 100644 index 00000000000..9bb4c26d5d5 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/autocommit_func2.test @@ -0,0 +1 @@ +--source suite/sys_vars/inc/autocommit_func2.inc diff --git a/mysql-test/suite/sys_vars/t/autocommit_func3-master.opt b/mysql-test/suite/sys_vars/t/autocommit_func3-master.opt new file mode 100644 index 00000000000..e0fa81e6eeb --- /dev/null +++ b/mysql-test/suite/sys_vars/t/autocommit_func3-master.opt @@ -0,0 +1 @@ +--autocommit=0 diff --git a/mysql-test/suite/sys_vars/t/autocommit_func3.test b/mysql-test/suite/sys_vars/t/autocommit_func3.test new file mode 100644 index 00000000000..9bb4c26d5d5 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/autocommit_func3.test @@ -0,0 +1 @@ +--source suite/sys_vars/inc/autocommit_func2.inc diff --git a/sql/mysqld.cc b/sql/mysqld.cc index df4f0f95b8c..21754b23940 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5662,6 +5662,12 @@ struct my_option my_long_options[]= {"ansi", 'a', "Use ANSI SQL syntax instead of MySQL syntax. This mode " "will also set transaction isolation level 'serializable'.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + /* + Because Sys_var_bit does not support command-line options, we need to + explicitely add one for --autocommit + */ + {"autocommit", OPT_AUTOCOMMIT, "Set default value for autocommit (0 or 1)", + NULL, NULL, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, NULL}, {"bind-address", OPT_BIND_ADDRESS, "IP address to bind to.", &my_bind_addr_str, &my_bind_addr_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -7114,6 +7120,13 @@ mysqld_get_one_option(int optid, if (argument == NULL) /* no argument */ log_error_file_ptr= const_cast(""); break; + case OPT_AUTOCOMMIT: + const ulonglong turn_bit_on= (argument && (atoi(argument) == 0)) ? + OPTION_NOT_AUTOCOMMIT : OPTION_AUTOCOMMIT; + global_system_variables.option_bits= + (global_system_variables.option_bits & + ~(OPTION_NOT_AUTOCOMMIT | OPTION_AUTOCOMMIT)) | turn_bit_on; + break; } return 0; } diff --git a/sql/mysqld.h b/sql/mysqld.h index 6e81c240f7d..dc9f94c0d03 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -391,7 +391,8 @@ enum options_mysqld OPT_UPDATE_LOG, OPT_WANT_CORE, OPT_ENGINE_CONDITION_PUSHDOWN, - OPT_LOG_ERROR + OPT_LOG_ERROR, + OPT_AUTOCOMMIT }; diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 455d95ada85..70b200bf3cd 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -1997,7 +1997,7 @@ static int add_part_field_list(File fptr, List field_list) String field_string("", 0, system_charset_info); THD *thd= current_thd; ulonglong save_options= thd->variables.option_bits; - thd->variables.option_bits= 0; + thd->variables.option_bits&= ~OPTION_QUOTE_SHOW_CREATE; append_identifier(thd, &field_string, field_str, strlen(field_str)); thd->variables.option_bits= save_options; @@ -2016,8 +2016,7 @@ static int add_name_string(File fptr, const char *name) String name_string("", 0, system_charset_info); THD *thd= current_thd; ulonglong save_options= thd->variables.option_bits; - - thd->variables.option_bits= 0; + thd->variables.option_bits&= ~OPTION_QUOTE_SHOW_CREATE; append_identifier(thd, &name_string, name, strlen(name)); thd->variables.option_bits= save_options; From f6ae96d40dc3e24c7ea0d88fa8cbfc3554449d04 Mon Sep 17 00:00:00 2001 From: Guilhem Bichot Date: Fri, 5 Nov 2010 14:17:47 +0100 Subject: [PATCH 187/304] BUG#57933 "add -Wdeclaration-after-statement to gcc builds"; first part, for autotools build. config/ac-macros/maintainer.m4: Add the flag. With it, and as we use -Werror, we nicely get "error: ISO C90 forbids mixed declarations and code" if a declaration follows a statement in C code. Note that g++ refuses this flag. --- config/ac-macros/maintainer.m4 | 1 + 1 file changed, 1 insertion(+) diff --git a/config/ac-macros/maintainer.m4 b/config/ac-macros/maintainer.m4 index 5960853d7f1..b4d2f08e558 100644 --- a/config/ac-macros/maintainer.m4 +++ b/config/ac-macros/maintainer.m4 @@ -19,6 +19,7 @@ AC_DEFUN([MY_MAINTAINER_MODE_WARNINGS], [ AS_IF([test "$GCC" = "yes"], [ C_WARNINGS="-Wall -Wextra -Wunused -Wwrite-strings -Wno-strict-aliasing -Werror" CXX_WARNINGS="${C_WARNINGS} -Wno-unused-parameter" + C_WARNINGS="${C_WARNINGS} -Wdeclaration-after-statement" ]) # Test whether the warning options work. From 866cec611a369be344bafed0d4691ad6b83e4086 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Fri, 5 Nov 2010 15:26:38 +0100 Subject: [PATCH 188/304] Bug #57840 MTR: parallel execution breaks with smart ordering of test cases There were actually more problems in this area: Slaves (if any) were unconditionally restarted, this appears unnecessary. Sort criteria were suboptimal, included the test name. Added logic to "reserve" a sequence of tests with same config for one thread Got rid of sort_criteria hash, put it into the test case itself Adds little sanity check that expected worker picks up test Fixed some tests that may fail if starting on running server Some of these fail only if *same* test is repeated. Finally, special sorting of tests that do --force-restart --- mysql-test/lib/mtr_cases.pm | 21 ++++--- mysql-test/mysql-test-run.pl | 58 ++++++++++++------- .../suite/binlog/t/binlog_index-master.opt | 1 + .../binlog/t/binlog_stm_binlog-master.opt | 1 + .../binlog/t/binlog_stm_do_db-master.opt | 1 + .../suite/rpl/r/rpl_ignore_table.result | 1 + .../suite/rpl/t/rpl_cross_version-master.opt | 1 + .../suite/rpl/t/rpl_current_user-master.opt | 1 + mysql-test/suite/rpl/t/rpl_ignore_table.test | 2 + .../rpl/t/rpl_loaddata_symlink-master.sh | 1 + .../suite/rpl/t/rpl_loaddata_symlink-slave.sh | 1 + ...rpl_slave_load_tmpdir_not_exist-master.opt | 1 + mysql-test/t/key_cache-master.opt | 1 + mysql-test/t/mysqlbinlog-master.opt | 1 + 14 files changed, 62 insertions(+), 30 deletions(-) create mode 100644 mysql-test/suite/binlog/t/binlog_index-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_current_user-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_slave_load_tmpdir_not_exist-master.opt diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm index 7d25a72212a..7961fa6fa7d 100644 --- a/mysql-test/lib/mtr_cases.pm +++ b/mysql-test/lib/mtr_cases.pm @@ -170,8 +170,6 @@ sub collect_test_cases ($$$) { if ( $opt_reorder && !$quick_collect) { # Reorder the test cases in an order that will make them faster to run - my %sort_criteria; - # Make a mapping of test name to a string that represents how that test # should be sorted among the other tests. Put the most important criterion # first, then a sub-criterion, then sub-sub-criterion, etc. @@ -183,24 +181,31 @@ sub collect_test_cases ($$$) { # Append the criteria for sorting, in order of importance. # push(@criteria, "ndb=" . ($tinfo->{'ndb_test'} ? "A" : "B")); + push(@criteria, $tinfo->{template_path}); # Group test with equal options together. # Ending with "~" makes empty sort later than filled my $opts= $tinfo->{'master_opt'} ? $tinfo->{'master_opt'} : []; push(@criteria, join("!", sort @{$opts}) . "~"); + # Add slave opts if any + if ($tinfo->{'slave_opt'}) + { + push(@criteria, join("!", sort @{$tinfo->{'slave_opt'}})); + } + # This sorts tests with force-restart *before* identical tests + push(@criteria, $tinfo->{force_restart} ? "force-restart" : "no-restart"); - $sort_criteria{$tinfo->{name}} = join(" ", @criteria); + $tinfo->{criteria}= join(" ", @criteria); } - @$cases = sort { - $sort_criteria{$a->{'name'}} . $a->{'name'} cmp - $sort_criteria{$b->{'name'}} . $b->{'name'}; } @$cases; + @$cases = sort {$a->{criteria} cmp $b->{criteria}; } @$cases; # For debugging the sort-order # foreach my $tinfo (@$cases) # { - # print("$sort_criteria{$tinfo->{'name'}} -> \t$tinfo->{'name'}\n"); + # my $tname= $tinfo->{name} . ' ' . $tinfo->{combination}; + # my $crit= $tinfo->{criteria}; + # print("$tname\n\t$crit\n"); # } - } if (defined $print_testcases){ diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 651dabcd408..b4cd53cff09 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -662,22 +662,40 @@ sub run_test_server ($$$) { next; } - # Prefer same configuration, or just use next if --noreorder - if (!$opt_reorder or (defined $result and - $result->{template_path} eq $t->{template_path})) - { - #mtr_report("Test uses same config => good match"); - # Test uses same config => good match - $next= splice(@$tests, $i, 1); - last; - } - # Second best choice is the first that does not fulfill # any of the above conditions if (!defined $second_best){ #mtr_report("Setting second_best to $i"); $second_best= $i; } + + # Smart allocation of next test within this thread. + + if ($opt_reorder and $opt_parallel > 1 and defined $result) + { + my $wid= $result->{worker}; + # Reserved for other thread, try next + next if (defined $t->{reserved} and $t->{reserved} != $wid); + if (! defined $t->{reserved}) + { + # Force-restart not relevant when comparing *next* test + $t->{criteria} =~ s/force-restart$/no-restart/; + my $criteria= $t->{criteria}; + # Reserve similar tests for this worker, but not too many + my $maxres= (@$tests - $i) / $opt_parallel + 1; + for (my $j= $i+1; $j <= $i + $maxres; $j++) + { + my $tt= $tests->[$j]; + last unless defined $tt; + last if $tt->{criteria} ne $criteria; + $tt->{reserved}= $wid; + } + } + } + + # At this point we have found next suitable test + $next= splice(@$tests, $i, 1); + last; } # Use second best choice if no other test has been found @@ -686,10 +704,12 @@ sub run_test_server ($$$) { mtr_error("Internal error, second best too large($second_best)") if $second_best > $#$tests; $next= splice(@$tests, $second_best, 1); + delete $next->{reserved}; } if ($next) { - #$next->print_test(); + # We don't need this any more + delete $next->{criteria}; $next->write_test($sock, 'TESTCASE'); $running{$next->key()}= $next; $num_ndb_tests++ if ($next->{ndb_test}); @@ -772,6 +792,11 @@ sub run_worker ($) { delete($test->{'comment'}); delete($test->{'logfile'}); + # A sanity check. Should this happen often we need to look at it. + if (defined $test->{reserved} && $test->{reserved} != $thread_num) { + my $tres= $test->{reserved}; + mtr_warning("Test reserved for w$tres picked up by w$thread_num"); + } $test->{worker} = $thread_num if $opt_parallel > 1; run_testcase($test); @@ -4575,17 +4600,6 @@ sub server_need_restart { } } - # Temporary re-enable the "always restart slave" hack - # this should be removed asap, but will require that each rpl - # testcase cleanup better after itself - ie. stop and reset - # replication - # Use the "#!use-slave-opt" marker to detect that this is a "slave" - # server - if ( $server->option("#!use-slave-opt") ){ - mtr_verbose_restart($server, "Always restart slave(s)"); - return 1; - } - my $is_mysqld= grep ($server eq $_, mysqlds()); if ($is_mysqld) { diff --git a/mysql-test/suite/binlog/t/binlog_index-master.opt b/mysql-test/suite/binlog/t/binlog_index-master.opt new file mode 100644 index 00000000000..cef79bc8585 --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_index-master.opt @@ -0,0 +1 @@ +--force-restart diff --git a/mysql-test/suite/binlog/t/binlog_stm_binlog-master.opt b/mysql-test/suite/binlog/t/binlog_stm_binlog-master.opt index ad2c6a647b5..377e2114039 100644 --- a/mysql-test/suite/binlog/t/binlog_stm_binlog-master.opt +++ b/mysql-test/suite/binlog/t/binlog_stm_binlog-master.opt @@ -1 +1,2 @@ -O max_binlog_size=4096 +--force-restart diff --git a/mysql-test/suite/binlog/t/binlog_stm_do_db-master.opt b/mysql-test/suite/binlog/t/binlog_stm_do_db-master.opt index e2cfcb299cf..2a1187d3fe4 100644 --- a/mysql-test/suite/binlog/t/binlog_stm_do_db-master.opt +++ b/mysql-test/suite/binlog/t/binlog_stm_do_db-master.opt @@ -1 +1,2 @@ --binlog-do-db=b42829 +--force-restart diff --git a/mysql-test/suite/rpl/r/rpl_ignore_table.result b/mysql-test/suite/rpl/r/rpl_ignore_table.result index e77be425270..6b845ddcac9 100644 --- a/mysql-test/suite/rpl/r/rpl_ignore_table.result +++ b/mysql-test/suite/rpl/r/rpl_ignore_table.result @@ -141,3 +141,4 @@ HEX(word) SELECT * FROM tmptbl504451f4258$1; ERROR 42S02: Table 'test.tmptbl504451f4258$1' doesn't exist DROP TABLE t5; +call mtr.force_restart(); diff --git a/mysql-test/suite/rpl/t/rpl_cross_version-master.opt b/mysql-test/suite/rpl/t/rpl_cross_version-master.opt index 0ea05290c11..2b2d357b124 100644 --- a/mysql-test/suite/rpl/t/rpl_cross_version-master.opt +++ b/mysql-test/suite/rpl/t/rpl_cross_version-master.opt @@ -1 +1,2 @@ --replicate-same-server-id --relay-log=slave-relay-bin --secure-file-priv=$MYSQL_TMP_DIR +--force-restart diff --git a/mysql-test/suite/rpl/t/rpl_current_user-master.opt b/mysql-test/suite/rpl/t/rpl_current_user-master.opt new file mode 100644 index 00000000000..cef79bc8585 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_current_user-master.opt @@ -0,0 +1 @@ +--force-restart diff --git a/mysql-test/suite/rpl/t/rpl_ignore_table.test b/mysql-test/suite/rpl/t/rpl_ignore_table.test index 66f96e8f4e8..b5666ad6e91 100644 --- a/mysql-test/suite/rpl/t/rpl_ignore_table.test +++ b/mysql-test/suite/rpl/t/rpl_ignore_table.test @@ -174,3 +174,5 @@ SELECT * FROM tmptbl504451f4258$1; connection master; DROP TABLE t5; sync_slave_with_master; + +call mtr.force_restart(); diff --git a/mysql-test/suite/rpl/t/rpl_loaddata_symlink-master.sh b/mysql-test/suite/rpl/t/rpl_loaddata_symlink-master.sh index 066f72926af..e5bb3e61d11 100644 --- a/mysql-test/suite/rpl/t/rpl_loaddata_symlink-master.sh +++ b/mysql-test/suite/rpl/t/rpl_loaddata_symlink-master.sh @@ -1 +1,2 @@ +rm -f $MYSQLTEST_VARDIR/std_data_master_link ln -s $MYSQLTEST_VARDIR/std_data $MYSQLTEST_VARDIR/std_data_master_link diff --git a/mysql-test/suite/rpl/t/rpl_loaddata_symlink-slave.sh b/mysql-test/suite/rpl/t/rpl_loaddata_symlink-slave.sh index 218209a2542..7a0c0bb382a 100644 --- a/mysql-test/suite/rpl/t/rpl_loaddata_symlink-slave.sh +++ b/mysql-test/suite/rpl/t/rpl_loaddata_symlink-slave.sh @@ -1 +1,2 @@ +rm -f $MYSQLTEST_VARDIR/std_data_slave_link ln -s $MYSQLTEST_VARDIR/std_data $MYSQLTEST_VARDIR/std_data_slave_link diff --git a/mysql-test/suite/rpl/t/rpl_slave_load_tmpdir_not_exist-master.opt b/mysql-test/suite/rpl/t/rpl_slave_load_tmpdir_not_exist-master.opt new file mode 100644 index 00000000000..cef79bc8585 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_slave_load_tmpdir_not_exist-master.opt @@ -0,0 +1 @@ +--force-restart diff --git a/mysql-test/t/key_cache-master.opt b/mysql-test/t/key_cache-master.opt index 66e19c18a8a..6398e3e0a26 100644 --- a/mysql-test/t/key_cache-master.opt +++ b/mysql-test/t/key_cache-master.opt @@ -1 +1,2 @@ --key_buffer_size=2M --small.key_buffer_size=256K --small.key_buffer_size=128K +--force-restart diff --git a/mysql-test/t/mysqlbinlog-master.opt b/mysql-test/t/mysqlbinlog-master.opt index ac1a87c73b3..a9f4a6010d8 100644 --- a/mysql-test/t/mysqlbinlog-master.opt +++ b/mysql-test/t/mysqlbinlog-master.opt @@ -1 +1,2 @@ --max-binlog-size=4096 +--force-restart From e0678e2ca624395a447dd8898583c13e31ec2f6a Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Sat, 6 Nov 2010 19:21:12 +0100 Subject: [PATCH 189/304] some test fixes after merging 57840 --- mysql-test/suite/rpl/r/rpl000017.result | 1 + mysql-test/suite/rpl/r/rpl_slave_status.result | 1 + mysql-test/suite/rpl/t/rpl000017.test | 2 ++ mysql-test/suite/rpl/t/rpl_bug33931-master.opt | 1 + mysql-test/suite/rpl/t/rpl_heartbeat-master.opt | 1 + mysql-test/suite/rpl/t/rpl_ip_mix-master.opt | 1 + mysql-test/suite/rpl/t/rpl_ip_mix2-master.opt | 1 + mysql-test/suite/rpl/t/rpl_semi_sync-master.opt | 1 + mysql-test/suite/rpl/t/rpl_slave_status.test | 1 + mysql-test/suite/rpl/t/rpl_sync.test | 1 + mysql-test/suite/rpl/t/rpl_temporary_errors-slave.opt | 3 +-- mysql-test/t/union.test | 2 +- 12 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 mysql-test/suite/rpl/t/rpl_bug33931-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_heartbeat-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_ip_mix-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_ip_mix2-master.opt diff --git a/mysql-test/suite/rpl/r/rpl000017.result b/mysql-test/suite/rpl/r/rpl000017.result index 403f4d4d4fe..39f46c41217 100644 --- a/mysql-test/suite/rpl/r/rpl000017.result +++ b/mysql-test/suite/rpl/r/rpl000017.result @@ -13,3 +13,4 @@ n 24 drop table t1; delete from mysql.user where user="replicate"; +call mtr.force_restart(); diff --git a/mysql-test/suite/rpl/r/rpl_slave_status.result b/mysql-test/suite/rpl/r/rpl_slave_status.result index a98a81dc74f..315008d559a 100644 --- a/mysql-test/suite/rpl/r/rpl_slave_status.result +++ b/mysql-test/suite/rpl/r/rpl_slave_status.result @@ -33,3 +33,4 @@ Slave_IO_Running = No (should be No) DROP TABLE t1; [on master] DROP TABLE t1; +call mtr.force_restart(); diff --git a/mysql-test/suite/rpl/t/rpl000017.test b/mysql-test/suite/rpl/t/rpl000017.test index a65189657cc..d271ba49c68 100644 --- a/mysql-test/suite/rpl/t/rpl000017.test +++ b/mysql-test/suite/rpl/t/rpl000017.test @@ -31,4 +31,6 @@ drop table t1; delete from mysql.user where user="replicate"; sync_slave_with_master; +call mtr.force_restart(); + # End of 4.1 tests diff --git a/mysql-test/suite/rpl/t/rpl_bug33931-master.opt b/mysql-test/suite/rpl/t/rpl_bug33931-master.opt new file mode 100644 index 00000000000..cef79bc8585 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_bug33931-master.opt @@ -0,0 +1 @@ +--force-restart diff --git a/mysql-test/suite/rpl/t/rpl_heartbeat-master.opt b/mysql-test/suite/rpl/t/rpl_heartbeat-master.opt new file mode 100644 index 00000000000..cef79bc8585 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_heartbeat-master.opt @@ -0,0 +1 @@ +--force-restart diff --git a/mysql-test/suite/rpl/t/rpl_ip_mix-master.opt b/mysql-test/suite/rpl/t/rpl_ip_mix-master.opt new file mode 100644 index 00000000000..cef79bc8585 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_ip_mix-master.opt @@ -0,0 +1 @@ +--force-restart diff --git a/mysql-test/suite/rpl/t/rpl_ip_mix2-master.opt b/mysql-test/suite/rpl/t/rpl_ip_mix2-master.opt new file mode 100644 index 00000000000..cef79bc8585 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_ip_mix2-master.opt @@ -0,0 +1 @@ +--force-restart diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync-master.opt b/mysql-test/suite/rpl/t/rpl_semi_sync-master.opt index 58029d28ace..1e8eb90679e 100644 --- a/mysql-test/suite/rpl/t/rpl_semi_sync-master.opt +++ b/mysql-test/suite/rpl/t/rpl_semi_sync-master.opt @@ -1 +1,2 @@ $SEMISYNC_PLUGIN_OPT +--force-restart diff --git a/mysql-test/suite/rpl/t/rpl_slave_status.test b/mysql-test/suite/rpl/t/rpl_slave_status.test index 02fd555d13c..9601062b65f 100644 --- a/mysql-test/suite/rpl/t/rpl_slave_status.test +++ b/mysql-test/suite/rpl/t/rpl_slave_status.test @@ -68,3 +68,4 @@ DROP TABLE t1; --echo [on master] connection master; DROP TABLE t1; +call mtr.force_restart(); diff --git a/mysql-test/suite/rpl/t/rpl_sync.test b/mysql-test/suite/rpl/t/rpl_sync.test index 48c8dc02efb..4ec02325572 100644 --- a/mysql-test/suite/rpl/t/rpl_sync.test +++ b/mysql-test/suite/rpl/t/rpl_sync.test @@ -150,3 +150,4 @@ source include/diff_tables.inc; --echo =====Clean up=======; connection master; drop table t1; +--remove_file $MYSQLD_SLAVE_DATADIR/master.backup diff --git a/mysql-test/suite/rpl/t/rpl_temporary_errors-slave.opt b/mysql-test/suite/rpl/t/rpl_temporary_errors-slave.opt index 80c171170f6..b37427aa2cd 100644 --- a/mysql-test/suite/rpl/t/rpl_temporary_errors-slave.opt +++ b/mysql-test/suite/rpl/t/rpl_temporary_errors-slave.opt @@ -1,3 +1,2 @@ --loose-debug="+d,all_errors_are_temporary_errors" --slave-transaction-retries=2 - - +--force-restart diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index 93dc4cad50c..596fc5f41ef 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -1062,7 +1062,7 @@ SELECT ( SELECT a UNION SELECT a ) INTO OUTFILE 'union.out.file3' FROM t1; SELECT ( SELECT a UNION SELECT a ) INTO DUMPFILE 'union.out.file4' FROM t1; DROP TABLE t1; - +remove_files_wildcard $MYSQLTEST_VARDIR/mysqld.1/data/test union.out.fil*; --echo # --echo # Bug #49734: Crash on EXPLAIN EXTENDED UNION ... ORDER BY From 5b8dbe96a566f4c304f3ebee7c2c4fcdd5793116 Mon Sep 17 00:00:00 2001 From: He Zhenxing Date: Sun, 7 Nov 2010 12:41:03 +0800 Subject: [PATCH 190/304] Remove rpl_killed_ddl.test from experimental after fixed BUG#47638 --- mysql-test/collections/default.experimental | 1 - 1 file changed, 1 deletion(-) diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index ce3f50f5f94..2ddf87485ad 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -24,7 +24,6 @@ main.wait_timeout @solaris # Bug#51244 2010-04-26 alik wait_timeou rpl.rpl_heartbeat_basic # BUG#54820 2010-06-26 alik rpl.rpl_heartbeat_basic fails sporadically again rpl.rpl_heartbeat_2slaves # BUG#43828 2009-10-22 luis fails sporadically rpl.rpl_innodb_bug28430* # Bug#46029 -rpl.rpl_killed_ddl @windows # Bug#47638 2010-01-20 alik The rpl_killed_ddl test fails on Windows sys_vars.max_sp_recursion_depth_func @solaris # Bug#47791 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun sys_vars.slow_query_log_func @solaris # Bug#54819 2010-06-26 alik sys_vars.slow_query_log_func fails sporadically on Solaris 10 From 8f237f5874a814daaa7431748849997d1a2aa8ea Mon Sep 17 00:00:00 2001 From: Dmitry Shulga Date: Sun, 7 Nov 2010 23:42:54 +0600 Subject: [PATCH 191/304] A fix and a test case for Bug#47924 -main.log_tables times out sporadically. The cause of the sporadic time out was a leaking protection against the global read lock, taken by the RENAME statement, and not released in case of an error occurred during RENAME. The leaking protection counter would lead to the value of protect_against_global_read never dropping to 0. Consequently FLUSH TABLES in all connections, including the one that leaked the protection, could not proceed. The fix is to ensure that all branchesin RENAME code properly release GRL protection. mysql-test/r/log_tables.result: Added results for test for bug#47924. mysql-test/t/log_tables.test: Added test for bug#47924. sql/sql_rename.cc: mysql_rename_tables() modified: replaced return from function to goto to clean up code block in case of error. --- mysql-test/r/log_tables.result | 10 ++++++++++ mysql-test/t/log_tables.test | 19 +++++++++++++++++++ sql/sql_rename.cc | 6 +++--- 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/log_tables.result b/mysql-test/r/log_tables.result index f8321520880..fcde09db7c5 100644 --- a/mysql-test/r/log_tables.result +++ b/mysql-test/r/log_tables.result @@ -899,6 +899,16 @@ TIMESTAMP 1 1 SELECT SQL_NO_CACHE 'Bug#31700 - KEY', f1,f2,f3,SLEEP(1.1) FROM t1 TIMESTAMP 1 1 SELECT SQL_NO_CACHE 'Bug#31700 - PK', f1,f2,f3,SLEEP(1.1) FROM t1 WHERE f1=2 DROP TABLE t1; TRUNCATE TABLE mysql.slow_log; +use mysql; +drop table if exists renamed_general_log; +drop table if exists renamed_slow_log; +RENAME TABLE general_log TO renamed_general_log; +ERROR HY000: Cannot rename 'general_log'. When logging enabled, rename to/from log table must rename two tables: the log table to an archive table and another table back to 'general_log' +RENAME TABLE slow_log TO renamed_slow_log; +ERROR HY000: Cannot rename 'slow_log'. When logging enabled, rename to/from log table must rename two tables: the log table to an archive table and another table back to 'slow_log' +use test; +flush tables with read lock; +unlock tables; SET @@session.long_query_time= @old_long_query_time; SET @@global.log_output= @old_log_output; SET @@global.slow_query_log= @old_slow_query_log; diff --git a/mysql-test/t/log_tables.test b/mysql-test/t/log_tables.test index 076f2e8bc3b..af6c34dec37 100644 --- a/mysql-test/t/log_tables.test +++ b/mysql-test/t/log_tables.test @@ -1027,6 +1027,25 @@ DROP TABLE t1; TRUNCATE TABLE mysql.slow_log; +# +# Bug #47924 main.log_tables times out sporadically +# + +use mysql; +# Should result in error +--disable_warnings +drop table if exists renamed_general_log; +drop table if exists renamed_slow_log; +--enable_warnings +--error ER_CANT_RENAME_LOG_TABLE +RENAME TABLE general_log TO renamed_general_log; +--error ER_CANT_RENAME_LOG_TABLE +RENAME TABLE slow_log TO renamed_slow_log; + +use test; +flush tables with read lock; +unlock tables; + SET @@session.long_query_time= @old_long_query_time; SET @@global.log_output= @old_log_output; diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index e85e730db5b..df7054c94d0 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -99,7 +99,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent) */ my_error(ER_CANT_RENAME_LOG_TABLE, MYF(0), ren_table->table_name, ren_table->table_name); - DBUG_RETURN(1); + goto err; } } else @@ -112,7 +112,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent) */ my_error(ER_CANT_RENAME_LOG_TABLE, MYF(0), ren_table->table_name, ren_table->table_name); - DBUG_RETURN(1); + goto err; } else { @@ -130,7 +130,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent) else my_error(ER_CANT_RENAME_LOG_TABLE, MYF(0), rename_log_table[1], rename_log_table[1]); - DBUG_RETURN(1); + goto err; } } From d7202ef7f8785d47788072d71f59270a862299b6 Mon Sep 17 00:00:00 2001 From: Anitha Gopi Date: Mon, 8 Nov 2010 14:57:05 +0530 Subject: [PATCH 192/304] Bug#58041 : Moved rpl_binlog_row to daily. Run just main suite for ps_row and embedded per push. Other suites run daily --- mysql-test/collections/mysql-5.1-bugteam.daily | 5 +++++ mysql-test/collections/mysql-5.1-bugteam.push | 4 ++++ 2 files changed, 9 insertions(+) create mode 100644 mysql-test/collections/mysql-5.1-bugteam.daily create mode 100644 mysql-test/collections/mysql-5.1-bugteam.push diff --git a/mysql-test/collections/mysql-5.1-bugteam.daily b/mysql-test/collections/mysql-5.1-bugteam.daily new file mode 100644 index 00000000000..0503bd49f73 --- /dev/null +++ b/mysql-test/collections/mysql-5.1-bugteam.daily @@ -0,0 +1,5 @@ +perl mysql-test-run.pl --timer --force --parallel=auto --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --experimental=collections/default.experimental +perl mysql-test-run.pl --timer --force --parallel=auto --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row --experimental=collections/default.experimental +perl mysql-test-run.pl --timer --force --parallel=auto --comment=embedded --vardir=var-emebbed --embedded --experimental=collections/default.experimental +perl mysql-test-run.pl --timer --force --parallel=auto --comment=rpl_binlog_row --vardir=var-rpl_binlog_row --suite=rpl,binlog --mysqld=--binlog-format=row --experimental=collections/default.experimental +perl mysql-test-run.pl --timer --force --parallel=auto --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1 --experimental=collections/default.experimental diff --git a/mysql-test/collections/mysql-5.1-bugteam.push b/mysql-test/collections/mysql-5.1-bugteam.push new file mode 100644 index 00000000000..d01b98eb87f --- /dev/null +++ b/mysql-test/collections/mysql-5.1-bugteam.push @@ -0,0 +1,4 @@ +perl mysql-test-run.pl --timer --force --parallel=auto --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --experimental=collections/default.experimental --skip-ndb +perl mysql-test-run.pl --timer --force --parallel=auto --comment=ps_row --vardir=var-ps_row --suite=main --ps-protocol --mysqld=--binlog-format=row --experimental=collections/default.experimental --skip-ndb +perl mysql-test-run.pl --timer --force --parallel=auto --comment=embedded --vardir=var-emebbed --suite=main --embedded --experimental=collections/default.experimental --skip-ndb +perl mysql-test-run.pl --timer --force --parallel=auto --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1 --experimental=collections/default.experimental --skip-ndb From 55086d79e1864f8a9f66af808d4566665d7bc846 Mon Sep 17 00:00:00 2001 From: Jon Olav Hauglid Date: Mon, 8 Nov 2010 10:48:31 +0100 Subject: [PATCH 193/304] Bug #45288 pb2 returns a lot of compilation warnings GCOV builds were broken after the patch for Bug#57933 which added add -Wdeclaration-after-statement to gcc builds. This patch fixes: stacktrace.c:328: warning: ISO C90 forbids mixed declarations and code No test case added. --- mysys/stacktrace.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mysys/stacktrace.c b/mysys/stacktrace.c index 7bac8017324..ebd84548a9b 100644 --- a/mysys/stacktrace.c +++ b/mysys/stacktrace.c @@ -318,6 +318,9 @@ end: /* Produce a core for the thread */ void my_write_core(int sig) { +#ifdef HAVE_gcov + extern void __gcov_flush(void); +#endif signal(sig, SIG_DFL); #ifdef HAVE_gcov /* @@ -325,7 +328,6 @@ void my_write_core(int sig) information from this process, causing gcov output to be incomplete. So we force the writing of coverage information here before terminating. */ - extern void __gcov_flush(void); __gcov_flush(); #endif pthread_kill(pthread_self(), sig); From 0a29baba4bae36b947aba9001956f3c800f4205f Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Mon, 8 Nov 2010 13:34:27 +0300 Subject: [PATCH 194/304] Fix for bug #54575: crash when joining tables with unique set column(backport from 5.1) Problem: a flaw (derefencing a NULL pointer) in the LIKE optimization code may lead to a server crash in some rare cases. Fix: check the pointer before its dereferencing. mysql-test/r/func_like.result: Fix for bug #54575: crash when joining tables with unique set column - test result. mysql-test/t/func_like.test: Fix for bug #54575: crash when joining tables with unique set column - test case. sql/item_cmpfunc.cc: Fix for bug #54575: crash when joining tables with unique set column - check res2 buffer pointer before its dereferencing as it may be NULL in some cases. --- mysql-test/r/func_like.result | 14 ++++++++++++++ mysql-test/t/func_like.test | 18 ++++++++++++++++-- sql/item_cmpfunc.cc | 7 ++++--- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/func_like.result b/mysql-test/r/func_like.result index 7e6fedb9403..f8743d6305f 100644 --- a/mysql-test/r/func_like.result +++ b/mysql-test/r/func_like.result @@ -165,3 +165,17 @@ select 'andre%' like 'andre select _cp1251'andre%' like convert('andreĘ%' using cp1251) escape 'Ę'; _cp1251'andre%' like convert('andreĘ%' using cp1251) escape 'Ę' 1 +End of 4.1 tests +# +# Bug #54575: crash when joining tables with unique set column +# +CREATE TABLE t1(a SET('a') NOT NULL, UNIQUE KEY(a)); +CREATE TABLE t2(b INT PRIMARY KEY); +INSERT INTO t1 VALUES (); +Warnings: +Warning 1364 Field 'a' doesn't have a default value +INSERT INTO t2 VALUES (1), (2), (3); +SELECT 1 FROM t2 JOIN t1 ON 1 LIKE a GROUP BY a; +1 +DROP TABLE t1, t2; +End of 5.1 tests diff --git a/mysql-test/t/func_like.test b/mysql-test/t/func_like.test index 4e1183afeff..50ebb2b2782 100644 --- a/mysql-test/t/func_like.test +++ b/mysql-test/t/func_like.test @@ -112,5 +112,19 @@ select 'andre%' like 'andre # select _cp1251'andre%' like convert('andreĘ%' using cp1251) escape 'Ę'; -# -# End of 4.1 tests + +--echo End of 4.1 tests + + +--echo # +--echo # Bug #54575: crash when joining tables with unique set column +--echo # +CREATE TABLE t1(a SET('a') NOT NULL, UNIQUE KEY(a)); +CREATE TABLE t2(b INT PRIMARY KEY); +INSERT INTO t1 VALUES (); +INSERT INTO t2 VALUES (1), (2), (3); +SELECT 1 FROM t2 JOIN t1 ON 1 LIKE a GROUP BY a; +DROP TABLE t1, t2; + + +--echo End of 5.1 tests diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 5c2fb9857d5..4ae381af683 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -4220,13 +4220,14 @@ Item_func::optimize_type Item_func_like::select_optimize() const if (args[1]->const_item()) { String* res2= args[1]->val_str((String *)&tmp_value2); + const char *ptr2; - if (!res2) + if (!res2 || !(ptr2= res2->ptr())) return OPTIMIZE_NONE; - if (*res2->ptr() != wild_many) + if (*ptr2 != wild_many) { - if (args[0]->result_type() != STRING_RESULT || *res2->ptr() != wild_one) + if (args[0]->result_type() != STRING_RESULT || *ptr2 != wild_one) return OPTIMIZE_OP; } } From 50a3c55ee7e378b36bca5940e382fb18674dbd9b Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Mon, 8 Nov 2010 13:51:39 +0300 Subject: [PATCH 195/304] Bug#52711 Segfault when doing EXPLAIN SELECT with union...order by (select... where...) backport from 5.1 mysql-test/r/subselect.result: backport from 5.1 mysql-test/t/subselect.test: backport from 5.1 sql/sql_select.cc: backport from 5.1 --- mysql-test/r/subselect.result | 16 ++++++++++++++++ mysql-test/t/subselect.test | 21 +++++++++++++++++++++ sql/sql_select.cc | 5 +++-- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 09a650c722b..7fbe4c08b08 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -4527,4 +4527,20 @@ pk int_key 3 3 7 3 DROP TABLE t1,t2; +# +# Bug #52711: Segfault when doing EXPLAIN SELECT with +# union...order by (select... where...) +# +CREATE TABLE t1 (a VARCHAR(10), FULLTEXT KEY a (a)); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (b INT); +INSERT INTO t2 VALUES (1),(2); +# Should not crash +EXPLAIN +SELECT * FROM t2 UNION SELECT * FROM t2 +ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE)); +# Should not crash +SELECT * FROM t2 UNION SELECT * FROM t2 +ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE)); +DROP TABLE t1,t2; End of 5.0 tests. diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index bd12742f0f1..0956f91619d 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -3506,5 +3506,26 @@ ORDER BY outr.pk; DROP TABLE t1,t2; +--echo # +--echo # Bug #52711: Segfault when doing EXPLAIN SELECT with +--echo # union...order by (select... where...) +--echo # + +CREATE TABLE t1 (a VARCHAR(10), FULLTEXT KEY a (a)); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (b INT); +INSERT INTO t2 VALUES (1),(2); + +--echo # Should not crash +--disable_result_log +EXPLAIN +SELECT * FROM t2 UNION SELECT * FROM t2 + ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE)); + +--echo # Should not crash +SELECT * FROM t2 UNION SELECT * FROM t2 + ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE)); +DROP TABLE t1,t2; +--enable_result_log --echo End of 5.0 tests. diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 53a6b699022..929ef3c8949 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -501,7 +501,7 @@ JOIN::prepare(Item ***rref_pointer_array, thd->lex->allow_sum_func= save_allow_sum_func; } - if (!thd->lex->view_prepare_mode) + if (!thd->lex->view_prepare_mode && !(select_options & SELECT_DESCRIBE)) { Item_subselect *subselect; /* Is it subselect? */ @@ -6861,7 +6861,8 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond, *simple_order=0; // Must do a temp table to sort else if (!(order_tables & not_const_tables)) { - if (order->item[0]->with_subselect) + if (order->item[0]->with_subselect && + !(join->select_lex->options & SELECT_DESCRIBE)) order->item[0]->val_str(&order->item[0]->str_value); DBUG_PRINT("info",("removing: %s", order->item[0]->full_name())); continue; // skip const item From 83e40f9634f860d8fbb1c4877b370003ca693618 Mon Sep 17 00:00:00 2001 From: Jon Olav Hauglid Date: Mon, 8 Nov 2010 12:51:48 +0100 Subject: [PATCH 196/304] Bug #45288 pb2 returns a lot of compilation warnings GCOV builds were broken after the patch for Bug#57933 which added add -Wdeclaration-after-statement to gcc builds. This patch fixes: stacktrace.c:328: warning: ISO C90 forbids mixed declarations and code No test case added. --- mysys/stacktrace.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mysys/stacktrace.c b/mysys/stacktrace.c index 7bac8017324..ebd84548a9b 100644 --- a/mysys/stacktrace.c +++ b/mysys/stacktrace.c @@ -318,6 +318,9 @@ end: /* Produce a core for the thread */ void my_write_core(int sig) { +#ifdef HAVE_gcov + extern void __gcov_flush(void); +#endif signal(sig, SIG_DFL); #ifdef HAVE_gcov /* @@ -325,7 +328,6 @@ void my_write_core(int sig) information from this process, causing gcov output to be incomplete. So we force the writing of coverage information here before terminating. */ - extern void __gcov_flush(void); __gcov_flush(); #endif pthread_kill(pthread_self(), sig); From 42e133e74e6f7e6adcf15afaa7bae1449c42ebbb Mon Sep 17 00:00:00 2001 From: Sven Sandberg Date: Mon, 8 Nov 2010 14:52:10 +0100 Subject: [PATCH 197/304] Fixed compilation error. storage/ndb/src/mgmsrv/InitConfigFileParser.cpp: Added 'const' to fix compilation error. --- storage/ndb/src/mgmsrv/InitConfigFileParser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/ndb/src/mgmsrv/InitConfigFileParser.cpp b/storage/ndb/src/mgmsrv/InitConfigFileParser.cpp index 560a9559999..7493e5e9c89 100644 --- a/storage/ndb/src/mgmsrv/InitConfigFileParser.cpp +++ b/storage/ndb/src/mgmsrv/InitConfigFileParser.cpp @@ -702,7 +702,7 @@ load_defaults(Vector& options, const char* groups[]) BaseString group_suffix; const char *save_file = my_defaults_file; - char *save_extra_file = my_defaults_extra_file; + const char *save_extra_file = my_defaults_extra_file; const char *save_group_suffix = my_defaults_group_suffix; if (my_defaults_file) From bf10c4a583a93997988b0e7fb01d9dda14bbe325 Mon Sep 17 00:00:00 2001 From: "Horst.Hunger" Date: Mon, 8 Nov 2010 16:30:26 +0100 Subject: [PATCH 198/304] Fix for bug#52501 consisting of changes of some sys_vars tests including review results. --- mysql-test/suite/sys_vars/README | 3 -- .../suite/sys_vars/inc/timestamp_basic.inc | 4 -- .../sys_vars/r/general_log_file_basic.result | 5 +- .../suite/sys_vars/r/general_log_func.result | 2 + .../r/innodb_commit_concurrency_basic.result | 46 ++++++------------- .../suite/sys_vars/r/log_output_basic.result | 4 +- .../suite/sys_vars/r/log_output_func.result | 3 +- .../r/slow_query_log_file_basic.result | 4 +- .../sys_vars/r/timestamp_basic_32.result | 12 ++--- .../sys_vars/r/timestamp_basic_64.result | 16 +++---- .../sys_vars/r/tmp_table_size_basic.result | 2 - .../sys_vars/t/completion_type_func.test | 2 +- mysql-test/suite/sys_vars/t/disabled.def | 13 ++++++ .../sys_vars/t/general_log_file_basic.test | 6 ++- .../suite/sys_vars/t/general_log_func.test | 2 + ...innodb_commit_concurrency_basic-master.opt | 1 + .../t/innodb_commit_concurrency_basic.test | 18 +++----- .../suite/sys_vars/t/log_output_func.test | 6 ++- .../myisam_data_pointer_size_func-master.opt | 1 + .../t/myisam_data_pointer_size_func.test | 3 ++ .../suite/sys_vars/t/rpl_init_slave_func.test | 2 +- .../sys_vars/t/slow_query_log_file_basic.test | 8 +++- .../sys_vars/t/sql_log_off_func-master.opt | 1 + .../suite/sys_vars/t/timestamp_basic_32.test | 4 ++ .../suite/sys_vars/t/timestamp_basic_64.test | 5 ++ .../sys_vars/t/tmp_table_size_basic.test | 3 +- 26 files changed, 91 insertions(+), 85 deletions(-) delete mode 100644 mysql-test/suite/sys_vars/README create mode 100644 mysql-test/suite/sys_vars/t/disabled.def create mode 100644 mysql-test/suite/sys_vars/t/innodb_commit_concurrency_basic-master.opt create mode 100644 mysql-test/suite/sys_vars/t/myisam_data_pointer_size_func-master.opt create mode 100644 mysql-test/suite/sys_vars/t/sql_log_off_func-master.opt diff --git a/mysql-test/suite/sys_vars/README b/mysql-test/suite/sys_vars/README deleted file mode 100644 index a84f00f1f62..00000000000 --- a/mysql-test/suite/sys_vars/README +++ /dev/null @@ -1,3 +0,0 @@ -Some of these tests allocate more than 4GB RAM. -So, assure that the machine on which the suite will be executed has more than 4GB RAM. - diff --git a/mysql-test/suite/sys_vars/inc/timestamp_basic.inc b/mysql-test/suite/sys_vars/inc/timestamp_basic.inc index 9ef57c97043..68ded3e5a97 100644 --- a/mysql-test/suite/sys_vars/inc/timestamp_basic.inc +++ b/mysql-test/suite/sys_vars/inc/timestamp_basic.inc @@ -66,10 +66,6 @@ SET @@timestamp = 0; --echo 'Setting 0 resets timestamp to session default timestamp' -SET @@timestamp = 123456789123456; -SELECT @@timestamp; -SET @@timestamp = 60*60*60*60*365; -SELECT @@timestamp; SET @@timestamp = -1000000000; SELECT @@timestamp; diff --git a/mysql-test/suite/sys_vars/r/general_log_file_basic.result b/mysql-test/suite/sys_vars/r/general_log_file_basic.result index 48a8d90b55e..5c0b93cf4ab 100644 --- a/mysql-test/suite/sys_vars/r/general_log_file_basic.result +++ b/mysql-test/suite/sys_vars/r/general_log_file_basic.result @@ -1,7 +1,6 @@ -SET @start_value = @@global.general_log_file; SELECT @start_value; @start_value -test.log +NULL '#---------------------FN_DYNVARS_004_01-------------------------#' SET @@global.general_log_file = DEFAULT; SELECT RIGHT(@@global.general_log_file,10) AS log_file; @@ -17,4 +16,4 @@ FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='general_log_file'; @@global.general_log_file = VARIABLE_VALUE 1 -SET @@global.general_log_file= @start_value; +SET @@global.general_log_file= 'test.log'; diff --git a/mysql-test/suite/sys_vars/r/general_log_func.result b/mysql-test/suite/sys_vars/r/general_log_func.result index 39ba90265d5..119991396e0 100644 --- a/mysql-test/suite/sys_vars/r/general_log_func.result +++ b/mysql-test/suite/sys_vars/r/general_log_func.result @@ -26,6 +26,7 @@ SELECT @@general_log; INSERT into t1(name) values('Record_3'); INSERT into t1(name) values('Record_4'); ## There should be a difference ## +SET @start_value= @@global.max_allowed_packet; SET @@global.max_allowed_packet= 1024*1024*1024; SET @orig_file= load_file('MYSQLD_LOGFILE.orig'); SET @copy_file= load_file('MYSQLD_LOGFILE.copy'); @@ -34,3 +35,4 @@ STRCMP(@orig_file, @copy_file) 1 ## Dropping tables ## DROP TABLE t1; +SET @@global.max_allowed_packet= @start_value; diff --git a/mysql-test/suite/sys_vars/r/innodb_commit_concurrency_basic.result b/mysql-test/suite/sys_vars/r/innodb_commit_concurrency_basic.result index 301016d4362..201f183ad0e 100644 --- a/mysql-test/suite/sys_vars/r/innodb_commit_concurrency_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_commit_concurrency_basic.result @@ -1,30 +1,23 @@ SET @global_start_value = @@global.innodb_commit_concurrency; SELECT @global_start_value; @global_start_value -0 +10 '#--------------------FN_DYNVARS_046_01------------------------#' -SET @@global.innodb_commit_concurrency = 0; SET @@global.innodb_commit_concurrency = DEFAULT; SELECT @@global.innodb_commit_concurrency; @@global.innodb_commit_concurrency -0 +10 '#---------------------FN_DYNVARS_046_02-------------------------#' SET innodb_commit_concurrency = 1; ERROR HY000: Variable 'innodb_commit_concurrency' is a GLOBAL variable and should be set with SET GLOBAL SELECT @@innodb_commit_concurrency; @@innodb_commit_concurrency -0 +10 SELECT local.innodb_commit_concurrency; ERROR 42S02: Unknown table 'local' in field list SET global innodb_commit_concurrency = 0; -SELECT @@global.innodb_commit_concurrency; -@@global.innodb_commit_concurrency -0 +ERROR HY000: Incorrect arguments to SET '#--------------------FN_DYNVARS_046_03------------------------#' -SET @@global.innodb_commit_concurrency = 0; -SELECT @@global.innodb_commit_concurrency; -@@global.innodb_commit_concurrency -0 SET @@global.innodb_commit_concurrency = 1; SELECT @@global.innodb_commit_concurrency; @@global.innodb_commit_concurrency @@ -35,27 +28,17 @@ SELECT @@global.innodb_commit_concurrency; 1000 '#--------------------FN_DYNVARS_046_04-------------------------#' SET @@global.innodb_commit_concurrency = -1; -Warnings: -Warning 1292 Truncated incorrect commit_concurrency value: '18446744073709551615' -SELECT @@global.innodb_commit_concurrency; -@@global.innodb_commit_concurrency -1000 +SELECT @@global.innodb_commit_concurrency IN (4294967295,18446744073709551615); +@@global.innodb_commit_concurrency IN (4294967295,18446744073709551615) +1 SET @@global.innodb_commit_concurrency = "T"; ERROR 42000: Incorrect argument type to variable 'innodb_commit_concurrency' -SELECT @@global.innodb_commit_concurrency; -@@global.innodb_commit_concurrency -1000 SET @@global.innodb_commit_concurrency = "Y"; ERROR 42000: Incorrect argument type to variable 'innodb_commit_concurrency' -SELECT @@global.innodb_commit_concurrency; -@@global.innodb_commit_concurrency -1000 SET @@global.innodb_commit_concurrency = 1001; -Warnings: -Warning 1292 Truncated incorrect commit_concurrency value: '1001' SELECT @@global.innodb_commit_concurrency; @@global.innodb_commit_concurrency -1000 +1001 '#----------------------FN_DYNVARS_046_05------------------------#' SELECT @@global.innodb_commit_concurrency = VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES @@ -65,32 +48,33 @@ VARIABLE_VALUE 1 SELECT @@global.innodb_commit_concurrency; @@global.innodb_commit_concurrency -1000 +1001 SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='innodb_commit_concurrency'; VARIABLE_VALUE -1000 +1001 '#---------------------FN_DYNVARS_046_06-------------------------#' SET @@global.innodb_commit_concurrency = OFF; ERROR 42000: Incorrect argument type to variable 'innodb_commit_concurrency' SELECT @@global.innodb_commit_concurrency; @@global.innodb_commit_concurrency -1000 +1001 SET @@global.innodb_commit_concurrency = ON; ERROR 42000: Incorrect argument type to variable 'innodb_commit_concurrency' SELECT @@global.innodb_commit_concurrency; @@global.innodb_commit_concurrency -1000 +1001 '#---------------------FN_DYNVARS_046_07----------------------#' SET @@global.innodb_commit_concurrency = TRUE; SELECT @@global.innodb_commit_concurrency; @@global.innodb_commit_concurrency 1 SET @@global.innodb_commit_concurrency = FALSE; +ERROR HY000: Incorrect arguments to SET SELECT @@global.innodb_commit_concurrency; @@global.innodb_commit_concurrency -0 +1 SET @@global.innodb_commit_concurrency = @global_start_value; SELECT @@global.innodb_commit_concurrency; @@global.innodb_commit_concurrency -0 +10 diff --git a/mysql-test/suite/sys_vars/r/log_output_basic.result b/mysql-test/suite/sys_vars/r/log_output_basic.result index 481d5862074..6f350556ff9 100644 --- a/mysql-test/suite/sys_vars/r/log_output_basic.result +++ b/mysql-test/suite/sys_vars/r/log_output_basic.result @@ -1,7 +1,7 @@ SET @start_value = @@global.log_output; SELECT @start_value; @start_value -FILE,TABLE +FILE '#--------------------FN_DYNVARS_065_01------------------------#' SET @@global.log_output = FILE; SET @@global.log_output = DEFAULT; @@ -172,4 +172,4 @@ TABLE SET @@global.log_output = @start_value; SELECT @@global.log_output; @@global.log_output -FILE,TABLE +FILE diff --git a/mysql-test/suite/sys_vars/r/log_output_func.result b/mysql-test/suite/sys_vars/r/log_output_func.result index 060f930a161..00a8e824f78 100644 --- a/mysql-test/suite/sys_vars/r/log_output_func.result +++ b/mysql-test/suite/sys_vars/r/log_output_func.result @@ -1,6 +1,5 @@ SET @start_value= @@global.log_output; SET @start_general_log= @@global.general_log; -SET @start_general_log_file= @@global.general_log_file; '#--------------------FN_DYNVARS_065_01-------------------------#' SET @@global.log_output = 'NONE'; 'connect (con1,localhost,root,,,,)' @@ -53,7 +52,7 @@ count(*) DROP TABLE t1; connection default; SET @@global.general_log= 'OFF'; -SET @@global.general_log_file= @start_general_log_file; +SET @@global.general_log_file= '/home/horst/bzr/5.1-52501/mysql-test/var/mysqld.1/mysqld.log'; SET @@global.log_output= @start_value; SET @@global.general_log= @start_general_log; SET @@global.general_log= 'ON'; diff --git a/mysql-test/suite/sys_vars/r/slow_query_log_file_basic.result b/mysql-test/suite/sys_vars/r/slow_query_log_file_basic.result index 925f940a5c4..3cd62187d0b 100644 --- a/mysql-test/suite/sys_vars/r/slow_query_log_file_basic.result +++ b/mysql-test/suite/sys_vars/r/slow_query_log_file_basic.result @@ -1,4 +1,4 @@ -SET @start_value = @@global.slow_query_log_file; +slowtest.log '#---------------------FN_DYNVARS_004_01-------------------------#' SET @@global.slow_query_log_file = DEFAULT; SELECT RIGHT(@@global.slow_query_log_file,15); @@ -14,4 +14,4 @@ FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='slow_query_log_file'; @@global.slow_query_log_file = VARIABLE_VALUE 1 -SET @@global.slow_query_log_file= @start_value; +SET @@global.slow_query_log_file= 'slowtest.log'; diff --git a/mysql-test/suite/sys_vars/r/timestamp_basic_32.result b/mysql-test/suite/sys_vars/r/timestamp_basic_32.result index a8be2201e68..87c9edc668e 100644 --- a/mysql-test/suite/sys_vars/r/timestamp_basic_32.result +++ b/mysql-test/suite/sys_vars/r/timestamp_basic_32.result @@ -8,14 +8,6 @@ ERROR HY000: Variable 'timestamp' is a SESSION variable and can't be used with S '#--------------------FN_DYNVARS_001_03------------------------#' SET @@timestamp = 0; 'Setting 0 resets timestamp to session default timestamp' -SET @@timestamp = 123456789123456; -SELECT @@timestamp; -@@timestamp -2249167232 -SET @@timestamp = 60*60*60*60*365; -SELECT @@timestamp; -@@timestamp -435432704 SET @@timestamp = -1000000000; SELECT @@timestamp; @@timestamp @@ -66,3 +58,7 @@ ERROR 42S02: Unknown table 'session' in field list SELECT timestamp = @@session.timestamp; ERROR 42S22: Unknown column 'timestamp' in 'field list' SET @@timestamp = @session_start_value; +SET @@timestamp = 123456789123456; +ERROR HY000: This version of MySQL doesn't support dates later than 2038 +SET @@timestamp = 60*60*60*60*365; +ERROR HY000: This version of MySQL doesn't support dates later than 2038 diff --git a/mysql-test/suite/sys_vars/r/timestamp_basic_64.result b/mysql-test/suite/sys_vars/r/timestamp_basic_64.result index 824a3ea5529..b5d3979610f 100644 --- a/mysql-test/suite/sys_vars/r/timestamp_basic_64.result +++ b/mysql-test/suite/sys_vars/r/timestamp_basic_64.result @@ -8,14 +8,6 @@ ERROR HY000: Variable 'timestamp' is a SESSION variable and can't be used with S '#--------------------FN_DYNVARS_001_03------------------------#' SET @@timestamp = 0; 'Setting 0 resets timestamp to session default timestamp' -SET @@timestamp = 123456789123456; -SELECT @@timestamp; -@@timestamp -123456789123456 -SET @@timestamp = 60*60*60*60*365; -SELECT @@timestamp; -@@timestamp -4730400000 SET @@timestamp = -1000000000; SELECT @@timestamp; @@timestamp @@ -66,3 +58,11 @@ ERROR 42S02: Unknown table 'session' in field list SELECT timestamp = @@session.timestamp; ERROR 42S22: Unknown column 'timestamp' in 'field list' SET @@timestamp = @session_start_value; +SET @@timestamp = 123456789123456; +SELECT @@timestamp; +@@timestamp +123456789123456 +SET @@timestamp = 60*60*60*60*365; +SELECT @@timestamp; +@@timestamp +4730400000 diff --git a/mysql-test/suite/sys_vars/r/tmp_table_size_basic.result b/mysql-test/suite/sys_vars/r/tmp_table_size_basic.result index 2ebeb8d61d8..06b624ad5c8 100644 --- a/mysql-test/suite/sys_vars/r/tmp_table_size_basic.result +++ b/mysql-test/suite/sys_vars/r/tmp_table_size_basic.result @@ -100,8 +100,6 @@ SELECT @@session.tmp_table_size; SET @@session.tmp_table_size = "Test"; ERROR 42000: Incorrect argument type to variable 'tmp_table_size' SET @@session.tmp_table_size = 12345678901; -Warnings: -Warning 1292 Truncated incorrect tmp_table_size value: '12345678901' SELECT @@session.tmp_table_size IN (12345678901,4294967295); @@session.tmp_table_size IN (12345678901,4294967295) 1 diff --git a/mysql-test/suite/sys_vars/t/completion_type_func.test b/mysql-test/suite/sys_vars/t/completion_type_func.test index 8e363ed2a7d..82e2dc47e54 100644 --- a/mysql-test/suite/sys_vars/t/completion_type_func.test +++ b/mysql-test/suite/sys_vars/t/completion_type_func.test @@ -18,7 +18,7 @@ # server-system-variables.html#option_mysqld_completion_type # # # ################################################################################ - +--source include/not_embedded.inc --source include/have_innodb.inc --disable_warnings diff --git a/mysql-test/suite/sys_vars/t/disabled.def b/mysql-test/suite/sys_vars/t/disabled.def new file mode 100644 index 00000000000..915ea7a6f5c --- /dev/null +++ b/mysql-test/suite/sys_vars/t/disabled.def @@ -0,0 +1,13 @@ +############################################################################## +# +# List the test cases that are to be disabled temporarily. +# +# Separate the test case name and the comment with ':'. +# +# : BUG# +# +# Do not use any TAB characters for whitespace. +# +############################################################################## +sys_vars.max_binlog_cache_size_basic_64 : bug#56408 2010-08-31 Horst +sys_vars.max_binlog_cache_size_basic_32 : bug#56408 2010-08-31 Horst diff --git a/mysql-test/suite/sys_vars/t/general_log_file_basic.test b/mysql-test/suite/sys_vars/t/general_log_file_basic.test index 014108f88d2..35905bad987 100644 --- a/mysql-test/suite/sys_vars/t/general_log_file_basic.test +++ b/mysql-test/suite/sys_vars/t/general_log_file_basic.test @@ -35,7 +35,8 @@ # Saving initial value of general_log_file in a temporary variable # ######################################################################## -SET @start_value = @@global.general_log_file; +#SET @start_value = @@global.general_log_file; +LET $start_value = `SELECT @@global.general_log_file`; SELECT @start_value; @@ -68,7 +69,8 @@ SELECT @@global.general_log_file = VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='general_log_file'; -SET @@global.general_log_file= @start_value; +#SET @@global.general_log_file= @start_value; +eval SET @@global.general_log_file= '$start_value'; ##################################################### # END OF general_log_file TESTS # diff --git a/mysql-test/suite/sys_vars/t/general_log_func.test b/mysql-test/suite/sys_vars/t/general_log_func.test index 24d535e88e5..d355d0d619c 100644 --- a/mysql-test/suite/sys_vars/t/general_log_func.test +++ b/mysql-test/suite/sys_vars/t/general_log_func.test @@ -79,6 +79,7 @@ INSERT into t1(name) values('Record_4'); --chmod 0777 $MYSQLD_LOGFILE.orig --echo ## There should be a difference ## +SET @start_value= @@global.max_allowed_packet; SET @@global.max_allowed_packet= 1024*1024*1024; --replace_result $MYSQLD_LOGFILE MYSQLD_LOGFILE eval SET @orig_file= load_file('$MYSQLD_LOGFILE.orig'); @@ -91,3 +92,4 @@ eval SELECT STRCMP(@orig_file, @copy_file); --echo ## Dropping tables ## DROP TABLE t1; +SET @@global.max_allowed_packet= @start_value; diff --git a/mysql-test/suite/sys_vars/t/innodb_commit_concurrency_basic-master.opt b/mysql-test/suite/sys_vars/t/innodb_commit_concurrency_basic-master.opt new file mode 100644 index 00000000000..727bbc4b11b --- /dev/null +++ b/mysql-test/suite/sys_vars/t/innodb_commit_concurrency_basic-master.opt @@ -0,0 +1 @@ +--innodb-commit-concurrency=10 diff --git a/mysql-test/suite/sys_vars/t/innodb_commit_concurrency_basic.test b/mysql-test/suite/sys_vars/t/innodb_commit_concurrency_basic.test index 1ef69e34999..2c7645f3b25 100644 --- a/mysql-test/suite/sys_vars/t/innodb_commit_concurrency_basic.test +++ b/mysql-test/suite/sys_vars/t/innodb_commit_concurrency_basic.test @@ -11,6 +11,10 @@ # Creation Date: 2008-02-07 # # Author: Rizwan # # # +# Modified 2010-09-01 Horst # +# Added amaster.opt with innodb-commit-concurrency > 0 to be able to assign # +# different values <> 0 # +# # #Description:Test Cases of Dynamic System Variable innodb_commit_concurrency # # that checks the behavior of this variable in the following ways # # * Default Value # @@ -43,7 +47,6 @@ SELECT @global_start_value; # Display the DEFAULT value of innodb_commit_concurrency # ######################################################################## -SET @@global.innodb_commit_concurrency = 0; SET @@global.innodb_commit_concurrency = DEFAULT; SELECT @@global.innodb_commit_concurrency; @@ -60,20 +63,14 @@ SELECT @@innodb_commit_concurrency; --Error ER_UNKNOWN_TABLE SELECT local.innodb_commit_concurrency; +--error ER_WRONG_ARGUMENTS SET global innodb_commit_concurrency = 0; -SELECT @@global.innodb_commit_concurrency; - - --echo '#--------------------FN_DYNVARS_046_03------------------------#' ########################################################################## # change the value of innodb_commit_concurrency to a valid value # ########################################################################## - -SET @@global.innodb_commit_concurrency = 0; -SELECT @@global.innodb_commit_concurrency; - SET @@global.innodb_commit_concurrency = 1; SELECT @@global.innodb_commit_concurrency; SET @@global.innodb_commit_concurrency = 1000; @@ -85,15 +82,13 @@ SELECT @@global.innodb_commit_concurrency; ########################################################################### SET @@global.innodb_commit_concurrency = -1; -SELECT @@global.innodb_commit_concurrency; +SELECT @@global.innodb_commit_concurrency IN (4294967295,18446744073709551615); --Error ER_WRONG_TYPE_FOR_VAR SET @@global.innodb_commit_concurrency = "T"; -SELECT @@global.innodb_commit_concurrency; --Error ER_WRONG_TYPE_FOR_VAR SET @@global.innodb_commit_concurrency = "Y"; -SELECT @@global.innodb_commit_concurrency; SET @@global.innodb_commit_concurrency = 1001; SELECT @@global.innodb_commit_concurrency; @@ -131,6 +126,7 @@ SELECT @@global.innodb_commit_concurrency; SET @@global.innodb_commit_concurrency = TRUE; SELECT @@global.innodb_commit_concurrency; +--error ER_WRONG_ARGUMENTS SET @@global.innodb_commit_concurrency = FALSE; SELECT @@global.innodb_commit_concurrency; diff --git a/mysql-test/suite/sys_vars/t/log_output_func.test b/mysql-test/suite/sys_vars/t/log_output_func.test index 007c4f38659..8a2fbe0728b 100644 --- a/mysql-test/suite/sys_vars/t/log_output_func.test +++ b/mysql-test/suite/sys_vars/t/log_output_func.test @@ -26,7 +26,8 @@ SET @start_value= @@global.log_output; SET @start_general_log= @@global.general_log; -SET @start_general_log_file= @@global.general_log_file; +#SET @start_general_log_file= @@global.general_log_file; +LET $start_general_log_file= `SELECT @@global.general_log_file`; --echo '#--------------------FN_DYNVARS_065_01-------------------------#' ################################################################## @@ -113,7 +114,8 @@ file_exists $MYSQLTEST_VARDIR/run/mytest.log ; --echo connection default; connection default; SET @@global.general_log= 'OFF'; -SET @@global.general_log_file= @start_general_log_file; +#SET @@global.general_log_file= @start_general_log_file; +eval SET @@global.general_log_file= '$start_general_log_file'; SET @@global.log_output= @start_value; SET @@global.general_log= @start_general_log; SET @@global.general_log= 'ON'; diff --git a/mysql-test/suite/sys_vars/t/myisam_data_pointer_size_func-master.opt b/mysql-test/suite/sys_vars/t/myisam_data_pointer_size_func-master.opt new file mode 100644 index 00000000000..d392e2e4262 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/myisam_data_pointer_size_func-master.opt @@ -0,0 +1 @@ +--log-error='dummy.log' diff --git a/mysql-test/suite/sys_vars/t/myisam_data_pointer_size_func.test b/mysql-test/suite/sys_vars/t/myisam_data_pointer_size_func.test index 37dd3a5a297..441e9c72982 100644 --- a/mysql-test/suite/sys_vars/t/myisam_data_pointer_size_func.test +++ b/mysql-test/suite/sys_vars/t/myisam_data_pointer_size_func.test @@ -19,6 +19,9 @@ # # ################################################################################ +# due to bug#56486 +--source include/not_windows.inc + --echo '#--------------------FN_DYNVARS_093_01-------------------------#' ############################################################################### # Check if setting myisam_data_pointer_size is changed in every new connection# diff --git a/mysql-test/suite/sys_vars/t/rpl_init_slave_func.test b/mysql-test/suite/sys_vars/t/rpl_init_slave_func.test index f2c66eb3a0a..2cc31c91388 100644 --- a/mysql-test/suite/sys_vars/t/rpl_init_slave_func.test +++ b/mysql-test/suite/sys_vars/t/rpl_init_slave_func.test @@ -55,7 +55,7 @@ DROP TABLE t1; eval SELECT @@global.init_slave = $my_init_slave; --echo Expect 1 # wait for the slave threads have set the global variable. -let $wait_timeout= 90; +let $wait_timeout= 240; let $wait_condition= SELECT @@global.max_connections = @start_max_connections; --source include/wait_condition_sp.inc # check that the action in init_slave does not happen immediately diff --git a/mysql-test/suite/sys_vars/t/slow_query_log_file_basic.test b/mysql-test/suite/sys_vars/t/slow_query_log_file_basic.test index 9125b686cad..810588b8f4e 100644 --- a/mysql-test/suite/sys_vars/t/slow_query_log_file_basic.test +++ b/mysql-test/suite/sys_vars/t/slow_query_log_file_basic.test @@ -35,7 +35,9 @@ # Saving initial value of slow_query_log_file in a temporary variable # ########################################################################### -SET @start_value = @@global.slow_query_log_file; +#SET @start_value = @@global.slow_query_log_file; +LET $start_value = `SELECT @@global.slow_query_log_file`; +--echo $start_value --echo '#---------------------FN_DYNVARS_004_01-------------------------#' ############################################### @@ -65,7 +67,9 @@ SELECT @@global.slow_query_log_file = VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='slow_query_log_file'; -SET @@global.slow_query_log_file= @start_value; +#SET @@global.slow_query_log_file= @start_value; +eval SET @@global.slow_query_log_file= '$start_value'; +#SELECT @start_value; ##################################################### # END OF slow_query_log_file TESTS # ##################################################### diff --git a/mysql-test/suite/sys_vars/t/sql_log_off_func-master.opt b/mysql-test/suite/sys_vars/t/sql_log_off_func-master.opt new file mode 100644 index 00000000000..875ecc54b55 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/sql_log_off_func-master.opt @@ -0,0 +1 @@ +--general-log --log-output=TABLE,FILE diff --git a/mysql-test/suite/sys_vars/t/timestamp_basic_32.test b/mysql-test/suite/sys_vars/t/timestamp_basic_32.test index a2b6139aef9..11b7535d9ef 100644 --- a/mysql-test/suite/sys_vars/t/timestamp_basic_32.test +++ b/mysql-test/suite/sys_vars/t/timestamp_basic_32.test @@ -7,3 +7,7 @@ --source include/have_32bit.inc --source suite/sys_vars/inc/timestamp_basic.inc +--error ER_UNKNOWN_ERROR +SET @@timestamp = 123456789123456; +--error ER_UNKNOWN_ERROR +SET @@timestamp = 60*60*60*60*365; diff --git a/mysql-test/suite/sys_vars/t/timestamp_basic_64.test b/mysql-test/suite/sys_vars/t/timestamp_basic_64.test index fbc86316ed9..5180c86392a 100644 --- a/mysql-test/suite/sys_vars/t/timestamp_basic_64.test +++ b/mysql-test/suite/sys_vars/t/timestamp_basic_64.test @@ -7,3 +7,8 @@ --source include/have_64bit.inc --source suite/sys_vars/inc/timestamp_basic.inc +SET @@timestamp = 123456789123456; +SELECT @@timestamp; +SET @@timestamp = 60*60*60*60*365; +SELECT @@timestamp; + diff --git a/mysql-test/suite/sys_vars/t/tmp_table_size_basic.test b/mysql-test/suite/sys_vars/t/tmp_table_size_basic.test index c2ff51d50ca..116196ddb07 100644 --- a/mysql-test/suite/sys_vars/t/tmp_table_size_basic.test +++ b/mysql-test/suite/sys_vars/t/tmp_table_size_basic.test @@ -133,8 +133,9 @@ SELECT @@session.tmp_table_size; --Error ER_WRONG_TYPE_FOR_VAR SET @@session.tmp_table_size = "Test"; +--disable_warnings SET @@session.tmp_table_size = 12345678901; - +--enable_warnings # With a 64 bit mysqld:12345678901,with a 32 bit mysqld: 4294967295 SELECT @@session.tmp_table_size IN (12345678901,4294967295); From 62e43d42ca45e22e9270e2784566aafe6cad8d00 Mon Sep 17 00:00:00 2001 From: Marc Alff Date: Mon, 8 Nov 2010 17:55:38 +0100 Subject: [PATCH 199/304] Adjusted test result to lowercase table names --- .../suite/perfschema/r/pfs_upgrade.result | 170 +++++++++--------- 1 file changed, 85 insertions(+), 85 deletions(-) diff --git a/mysql-test/suite/perfschema/r/pfs_upgrade.result b/mysql-test/suite/perfschema/r/pfs_upgrade.result index 7a782687184..2ec6a3bd1dd 100644 --- a/mysql-test/suite/perfschema/r/pfs_upgrade.result +++ b/mysql-test/suite/perfschema/r/pfs_upgrade.result @@ -8,23 +8,23 @@ use performance_schema; show tables like "user_table"; Tables_in_performance_schema (user_table) user_table -ERROR 1050 (42S01) at line 183: Table 'COND_INSTANCES' already exists -ERROR 1050 (42S01) at line 213: Table 'EVENTS_WAITS_CURRENT' already exists -ERROR 1050 (42S01) at line 227: Table 'EVENTS_WAITS_HISTORY' already exists -ERROR 1050 (42S01) at line 241: Table 'EVENTS_WAITS_HISTORY_LONG' already exists -ERROR 1050 (42S01) at line 262: Table 'EVENTS_WAITS_SUMMARY_BY_INSTANCE' already exists -ERROR 1050 (42S01) at line 283: Table 'EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME' already exists -ERROR 1050 (42S01) at line 303: Table 'EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME' already exists -ERROR 1050 (42S01) at line 320: Table 'FILE_INSTANCES' already exists -ERROR 1050 (42S01) at line 339: Table 'FILE_SUMMARY_BY_EVENT_NAME' already exists -ERROR 1050 (42S01) at line 359: Table 'FILE_SUMMARY_BY_INSTANCE' already exists -ERROR 1050 (42S01) at line 376: Table 'MUTEX_INSTANCES' already exists -ERROR 1050 (42S01) at line 394: Table 'PERFORMANCE_TIMERS' already exists -ERROR 1050 (42S01) at line 412: Table 'RWLOCK_INSTANCES' already exists -ERROR 1050 (42S01) at line 428: Table 'SETUP_CONSUMERS' already exists -ERROR 1050 (42S01) at line 445: Table 'SETUP_INSTRUMENTS' already exists -ERROR 1050 (42S01) at line 461: Table 'SETUP_TIMERS' already exists -ERROR 1050 (42S01) at line 478: Table 'THREADS' already exists +ERROR 1050 (42S01) at line 183: Table 'cond_instances' already exists +ERROR 1050 (42S01) at line 213: Table 'events_waits_current' already exists +ERROR 1050 (42S01) at line 227: Table 'events_waits_history' already exists +ERROR 1050 (42S01) at line 241: Table 'events_waits_history_long' already exists +ERROR 1050 (42S01) at line 262: Table 'events_waits_summary_by_instance' already exists +ERROR 1050 (42S01) at line 283: Table 'events_waits_summary_by_thread_by_event_name' already exists +ERROR 1050 (42S01) at line 303: Table 'events_waits_summary_global_by_event_name' already exists +ERROR 1050 (42S01) at line 320: Table 'file_instances' already exists +ERROR 1050 (42S01) at line 339: Table 'file_summary_by_event_name' already exists +ERROR 1050 (42S01) at line 359: Table 'file_summary_by_instance' already exists +ERROR 1050 (42S01) at line 376: Table 'mutex_instances' already exists +ERROR 1050 (42S01) at line 394: Table 'performance_timers' already exists +ERROR 1050 (42S01) at line 412: Table 'rwlock_instances' already exists +ERROR 1050 (42S01) at line 428: Table 'setup_consumers' already exists +ERROR 1050 (42S01) at line 445: Table 'setup_instruments' already exists +ERROR 1050 (42S01) at line 461: Table 'setup_timers' already exists +ERROR 1050 (42S01) at line 478: Table 'threads' already exists ERROR 1644 (HY000) at line 1122: Unexpected content found in the performance_schema database. FATAL ERROR: Upgrade failed show tables like "user_table"; @@ -38,23 +38,23 @@ use performance_schema; show tables like "user_view"; Tables_in_performance_schema (user_view) user_view -ERROR 1050 (42S01) at line 183: Table 'COND_INSTANCES' already exists -ERROR 1050 (42S01) at line 213: Table 'EVENTS_WAITS_CURRENT' already exists -ERROR 1050 (42S01) at line 227: Table 'EVENTS_WAITS_HISTORY' already exists -ERROR 1050 (42S01) at line 241: Table 'EVENTS_WAITS_HISTORY_LONG' already exists -ERROR 1050 (42S01) at line 262: Table 'EVENTS_WAITS_SUMMARY_BY_INSTANCE' already exists -ERROR 1050 (42S01) at line 283: Table 'EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME' already exists -ERROR 1050 (42S01) at line 303: Table 'EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME' already exists -ERROR 1050 (42S01) at line 320: Table 'FILE_INSTANCES' already exists -ERROR 1050 (42S01) at line 339: Table 'FILE_SUMMARY_BY_EVENT_NAME' already exists -ERROR 1050 (42S01) at line 359: Table 'FILE_SUMMARY_BY_INSTANCE' already exists -ERROR 1050 (42S01) at line 376: Table 'MUTEX_INSTANCES' already exists -ERROR 1050 (42S01) at line 394: Table 'PERFORMANCE_TIMERS' already exists -ERROR 1050 (42S01) at line 412: Table 'RWLOCK_INSTANCES' already exists -ERROR 1050 (42S01) at line 428: Table 'SETUP_CONSUMERS' already exists -ERROR 1050 (42S01) at line 445: Table 'SETUP_INSTRUMENTS' already exists -ERROR 1050 (42S01) at line 461: Table 'SETUP_TIMERS' already exists -ERROR 1050 (42S01) at line 478: Table 'THREADS' already exists +ERROR 1050 (42S01) at line 183: Table 'cond_instances' already exists +ERROR 1050 (42S01) at line 213: Table 'events_waits_current' already exists +ERROR 1050 (42S01) at line 227: Table 'events_waits_history' already exists +ERROR 1050 (42S01) at line 241: Table 'events_waits_history_long' already exists +ERROR 1050 (42S01) at line 262: Table 'events_waits_summary_by_instance' already exists +ERROR 1050 (42S01) at line 283: Table 'events_waits_summary_by_thread_by_event_name' already exists +ERROR 1050 (42S01) at line 303: Table 'events_waits_summary_global_by_event_name' already exists +ERROR 1050 (42S01) at line 320: Table 'file_instances' already exists +ERROR 1050 (42S01) at line 339: Table 'file_summary_by_event_name' already exists +ERROR 1050 (42S01) at line 359: Table 'file_summary_by_instance' already exists +ERROR 1050 (42S01) at line 376: Table 'mutex_instances' already exists +ERROR 1050 (42S01) at line 394: Table 'performance_timers' already exists +ERROR 1050 (42S01) at line 412: Table 'rwlock_instances' already exists +ERROR 1050 (42S01) at line 428: Table 'setup_consumers' already exists +ERROR 1050 (42S01) at line 445: Table 'setup_instruments' already exists +ERROR 1050 (42S01) at line 461: Table 'setup_timers' already exists +ERROR 1050 (42S01) at line 478: Table 'threads' already exists ERROR 1644 (HY000) at line 1122: Unexpected content found in the performance_schema database. FATAL ERROR: Upgrade failed show tables like "user_view"; @@ -66,23 +66,23 @@ drop view test.user_view; create procedure test.user_proc() select "Not supposed to be here"; update mysql.proc set db='performance_schema' where name='user_proc'; -ERROR 1050 (42S01) at line 183: Table 'COND_INSTANCES' already exists -ERROR 1050 (42S01) at line 213: Table 'EVENTS_WAITS_CURRENT' already exists -ERROR 1050 (42S01) at line 227: Table 'EVENTS_WAITS_HISTORY' already exists -ERROR 1050 (42S01) at line 241: Table 'EVENTS_WAITS_HISTORY_LONG' already exists -ERROR 1050 (42S01) at line 262: Table 'EVENTS_WAITS_SUMMARY_BY_INSTANCE' already exists -ERROR 1050 (42S01) at line 283: Table 'EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME' already exists -ERROR 1050 (42S01) at line 303: Table 'EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME' already exists -ERROR 1050 (42S01) at line 320: Table 'FILE_INSTANCES' already exists -ERROR 1050 (42S01) at line 339: Table 'FILE_SUMMARY_BY_EVENT_NAME' already exists -ERROR 1050 (42S01) at line 359: Table 'FILE_SUMMARY_BY_INSTANCE' already exists -ERROR 1050 (42S01) at line 376: Table 'MUTEX_INSTANCES' already exists -ERROR 1050 (42S01) at line 394: Table 'PERFORMANCE_TIMERS' already exists -ERROR 1050 (42S01) at line 412: Table 'RWLOCK_INSTANCES' already exists -ERROR 1050 (42S01) at line 428: Table 'SETUP_CONSUMERS' already exists -ERROR 1050 (42S01) at line 445: Table 'SETUP_INSTRUMENTS' already exists -ERROR 1050 (42S01) at line 461: Table 'SETUP_TIMERS' already exists -ERROR 1050 (42S01) at line 478: Table 'THREADS' already exists +ERROR 1050 (42S01) at line 183: Table 'cond_instances' already exists +ERROR 1050 (42S01) at line 213: Table 'events_waits_current' already exists +ERROR 1050 (42S01) at line 227: Table 'events_waits_history' already exists +ERROR 1050 (42S01) at line 241: Table 'events_waits_history_long' already exists +ERROR 1050 (42S01) at line 262: Table 'events_waits_summary_by_instance' already exists +ERROR 1050 (42S01) at line 283: Table 'events_waits_summary_by_thread_by_event_name' already exists +ERROR 1050 (42S01) at line 303: Table 'events_waits_summary_global_by_event_name' already exists +ERROR 1050 (42S01) at line 320: Table 'file_instances' already exists +ERROR 1050 (42S01) at line 339: Table 'file_summary_by_event_name' already exists +ERROR 1050 (42S01) at line 359: Table 'file_summary_by_instance' already exists +ERROR 1050 (42S01) at line 376: Table 'mutex_instances' already exists +ERROR 1050 (42S01) at line 394: Table 'performance_timers' already exists +ERROR 1050 (42S01) at line 412: Table 'rwlock_instances' already exists +ERROR 1050 (42S01) at line 428: Table 'setup_consumers' already exists +ERROR 1050 (42S01) at line 445: Table 'setup_instruments' already exists +ERROR 1050 (42S01) at line 461: Table 'setup_timers' already exists +ERROR 1050 (42S01) at line 478: Table 'threads' already exists ERROR 1644 (HY000) at line 1122: Unexpected content found in the performance_schema database. FATAL ERROR: Upgrade failed select name from mysql.proc where db='performance_schema'; @@ -94,23 +94,23 @@ drop procedure test.user_proc; create function test.user_func() returns integer return 0; update mysql.proc set db='performance_schema' where name='user_func'; -ERROR 1050 (42S01) at line 183: Table 'COND_INSTANCES' already exists -ERROR 1050 (42S01) at line 213: Table 'EVENTS_WAITS_CURRENT' already exists -ERROR 1050 (42S01) at line 227: Table 'EVENTS_WAITS_HISTORY' already exists -ERROR 1050 (42S01) at line 241: Table 'EVENTS_WAITS_HISTORY_LONG' already exists -ERROR 1050 (42S01) at line 262: Table 'EVENTS_WAITS_SUMMARY_BY_INSTANCE' already exists -ERROR 1050 (42S01) at line 283: Table 'EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME' already exists -ERROR 1050 (42S01) at line 303: Table 'EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME' already exists -ERROR 1050 (42S01) at line 320: Table 'FILE_INSTANCES' already exists -ERROR 1050 (42S01) at line 339: Table 'FILE_SUMMARY_BY_EVENT_NAME' already exists -ERROR 1050 (42S01) at line 359: Table 'FILE_SUMMARY_BY_INSTANCE' already exists -ERROR 1050 (42S01) at line 376: Table 'MUTEX_INSTANCES' already exists -ERROR 1050 (42S01) at line 394: Table 'PERFORMANCE_TIMERS' already exists -ERROR 1050 (42S01) at line 412: Table 'RWLOCK_INSTANCES' already exists -ERROR 1050 (42S01) at line 428: Table 'SETUP_CONSUMERS' already exists -ERROR 1050 (42S01) at line 445: Table 'SETUP_INSTRUMENTS' already exists -ERROR 1050 (42S01) at line 461: Table 'SETUP_TIMERS' already exists -ERROR 1050 (42S01) at line 478: Table 'THREADS' already exists +ERROR 1050 (42S01) at line 183: Table 'cond_instances' already exists +ERROR 1050 (42S01) at line 213: Table 'events_waits_current' already exists +ERROR 1050 (42S01) at line 227: Table 'events_waits_history' already exists +ERROR 1050 (42S01) at line 241: Table 'events_waits_history_long' already exists +ERROR 1050 (42S01) at line 262: Table 'events_waits_summary_by_instance' already exists +ERROR 1050 (42S01) at line 283: Table 'events_waits_summary_by_thread_by_event_name' already exists +ERROR 1050 (42S01) at line 303: Table 'events_waits_summary_global_by_event_name' already exists +ERROR 1050 (42S01) at line 320: Table 'file_instances' already exists +ERROR 1050 (42S01) at line 339: Table 'file_summary_by_event_name' already exists +ERROR 1050 (42S01) at line 359: Table 'file_summary_by_instance' already exists +ERROR 1050 (42S01) at line 376: Table 'mutex_instances' already exists +ERROR 1050 (42S01) at line 394: Table 'performance_timers' already exists +ERROR 1050 (42S01) at line 412: Table 'rwlock_instances' already exists +ERROR 1050 (42S01) at line 428: Table 'setup_consumers' already exists +ERROR 1050 (42S01) at line 445: Table 'setup_instruments' already exists +ERROR 1050 (42S01) at line 461: Table 'setup_timers' already exists +ERROR 1050 (42S01) at line 478: Table 'threads' already exists ERROR 1644 (HY000) at line 1122: Unexpected content found in the performance_schema database. FATAL ERROR: Upgrade failed select name from mysql.proc where db='performance_schema'; @@ -122,23 +122,23 @@ drop function test.user_func; create event test.user_event on schedule every 1 day do select "not supposed to be here"; update mysql.event set db='performance_schema' where name='user_event'; -ERROR 1050 (42S01) at line 183: Table 'COND_INSTANCES' already exists -ERROR 1050 (42S01) at line 213: Table 'EVENTS_WAITS_CURRENT' already exists -ERROR 1050 (42S01) at line 227: Table 'EVENTS_WAITS_HISTORY' already exists -ERROR 1050 (42S01) at line 241: Table 'EVENTS_WAITS_HISTORY_LONG' already exists -ERROR 1050 (42S01) at line 262: Table 'EVENTS_WAITS_SUMMARY_BY_INSTANCE' already exists -ERROR 1050 (42S01) at line 283: Table 'EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME' already exists -ERROR 1050 (42S01) at line 303: Table 'EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME' already exists -ERROR 1050 (42S01) at line 320: Table 'FILE_INSTANCES' already exists -ERROR 1050 (42S01) at line 339: Table 'FILE_SUMMARY_BY_EVENT_NAME' already exists -ERROR 1050 (42S01) at line 359: Table 'FILE_SUMMARY_BY_INSTANCE' already exists -ERROR 1050 (42S01) at line 376: Table 'MUTEX_INSTANCES' already exists -ERROR 1050 (42S01) at line 394: Table 'PERFORMANCE_TIMERS' already exists -ERROR 1050 (42S01) at line 412: Table 'RWLOCK_INSTANCES' already exists -ERROR 1050 (42S01) at line 428: Table 'SETUP_CONSUMERS' already exists -ERROR 1050 (42S01) at line 445: Table 'SETUP_INSTRUMENTS' already exists -ERROR 1050 (42S01) at line 461: Table 'SETUP_TIMERS' already exists -ERROR 1050 (42S01) at line 478: Table 'THREADS' already exists +ERROR 1050 (42S01) at line 183: Table 'cond_instances' already exists +ERROR 1050 (42S01) at line 213: Table 'events_waits_current' already exists +ERROR 1050 (42S01) at line 227: Table 'events_waits_history' already exists +ERROR 1050 (42S01) at line 241: Table 'events_waits_history_long' already exists +ERROR 1050 (42S01) at line 262: Table 'events_waits_summary_by_instance' already exists +ERROR 1050 (42S01) at line 283: Table 'events_waits_summary_by_thread_by_event_name' already exists +ERROR 1050 (42S01) at line 303: Table 'events_waits_summary_global_by_event_name' already exists +ERROR 1050 (42S01) at line 320: Table 'file_instances' already exists +ERROR 1050 (42S01) at line 339: Table 'file_summary_by_event_name' already exists +ERROR 1050 (42S01) at line 359: Table 'file_summary_by_instance' already exists +ERROR 1050 (42S01) at line 376: Table 'mutex_instances' already exists +ERROR 1050 (42S01) at line 394: Table 'performance_timers' already exists +ERROR 1050 (42S01) at line 412: Table 'rwlock_instances' already exists +ERROR 1050 (42S01) at line 428: Table 'setup_consumers' already exists +ERROR 1050 (42S01) at line 445: Table 'setup_instruments' already exists +ERROR 1050 (42S01) at line 461: Table 'setup_timers' already exists +ERROR 1050 (42S01) at line 478: Table 'threads' already exists ERROR 1644 (HY000) at line 1122: Unexpected content found in the performance_schema database. FATAL ERROR: Upgrade failed select name from mysql.event where db='performance_schema'; From b28e64ca86c934787b26b5020d8b2470bdd914a4 Mon Sep 17 00:00:00 2001 From: Anitha Gopi Date: Tue, 9 Nov 2010 12:16:43 +0530 Subject: [PATCH 200/304] Bug#58041 : Created separate per push and daily collections for 5.5-bugteam. Moved rpl_binlog_row to daily. Run just main suite for ps_row and embedded per push. Other suites run daily --- mysql-test/collections/mysql-5.5-bugteam.daily | 5 +++++ mysql-test/collections/mysql-5.5-bugteam.push | 4 ++++ 2 files changed, 9 insertions(+) create mode 100644 mysql-test/collections/mysql-5.5-bugteam.daily create mode 100644 mysql-test/collections/mysql-5.5-bugteam.push diff --git a/mysql-test/collections/mysql-5.5-bugteam.daily b/mysql-test/collections/mysql-5.5-bugteam.daily new file mode 100644 index 00000000000..81dffff91ce --- /dev/null +++ b/mysql-test/collections/mysql-5.5-bugteam.daily @@ -0,0 +1,5 @@ +perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed +perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row +perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=embedded --vardir=var-emebbed --embedded +perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1 +perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=rpl_binlog_row --vardir=var-rpl_binlog_row --mysqld=--binlog-format=row --suite=rpl,binlog --skip-ndb diff --git a/mysql-test/collections/mysql-5.5-bugteam.push b/mysql-test/collections/mysql-5.5-bugteam.push new file mode 100644 index 00000000000..06118ed9e1e --- /dev/null +++ b/mysql-test/collections/mysql-5.5-bugteam.push @@ -0,0 +1,4 @@ +perl mysql-test-run.pl --timer --force --parallel=auto --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --experimental=collections/default.experimental --skip-ndb --skip-test-list=collections/disabled-per-push.list +perl mysql-test-run.pl --timer --force --parallel=auto --comment=main_ps_row --vardir=var-main-ps_row --suite=main --ps-protocol --mysqld=--binlog-format=row --experimental=collections/default.experimental --skip-ndb --skip-test-list=collections/disabled-per-push.list +perl mysql-test-run.pl --timer --force --parallel=auto --comment=main_embedded --vardir=var-main_emebbed --suite=main --embedded --experimental=collections/default.experimental --skip-ndb +perl mysql-test-run.pl --timer --force --parallel=auto --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1 --experimental=collections/default.experimental --skip-ndb From f91c6de21188613220cef7cee8935510f6b5cc99 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 9 Nov 2010 11:08:02 +0300 Subject: [PATCH 201/304] Postfix for Bug#26474 Add Sinhala script (Sri Lanka) collation to MySQL --- mysql-test/r/ctype_utf8.result | 14 ++++++++++++++ mysql-test/t/ctype_utf8.test | 9 +++++++++ strings/ctype-uca.c | 2 +- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index 122d722be71..02ff80890e0 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -2040,6 +2040,20 @@ predicted_order hex(utf8_encoding) 100 E0B78AE2808DE0B6BA 101 E0B78AE2808DE0B6BB DROP TABLE t1; +SET NAMES utf8 COLLATE utf8_sinhala_ci; +CREATE TABLE t1 (s1 VARCHAR(10) COLLATE utf8_sinhala_ci); +INSERT INTO t1 VALUES ('a'),('ae'),('af'); +SELECT s1,hex(s1) FROM t1 ORDER BY s1; +s1 hex(s1) +a 61 +ae 6165 +af 6166 +SELECT * FROM t1 ORDER BY s1; +s1 +a +ae +af +DROP TABLE t1; End of 5.4 tests # # Start of 5.5 tests diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index 5b665e24958..c7586c71229 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -1477,6 +1477,15 @@ CREATE TABLE t1 ( INSERT INTO t1 VALUES (19, x'E0B696'), (30, x'E0B69AE0B798'), (61, x'E0B6AF'), (93, x'E0B799'), (52, x'E0B6A6'), (73, x'E0B6BBE0B78AE2808D'), (3, x'E0B686'), (56, x'E0B6AA'), (55, x'E0B6A9'), (70, x'E0B6B9'), (94, x'E0B79A'), (80, x'E0B785'), (25, x'E0B69AE0B791'), (48, x'E0B6A2'), (13, x'E0B690'), (86, x'E0B793'), (91, x'E0B79F'), (81, x'E0B786'), (79, x'E0B784'), (14, x'E0B691'), (99, x'E0B78A'), (8, x'E0B68B'), (68, x'E0B6B7'), (22, x'E0B69A'), (16, x'E0B693'), (33, x'E0B69AE0B7B3'), (38, x'E0B69AE0B79D'), (21, x'E0B683'), (11, x'E0B68E'), (77, x'E0B782'), (40, x'E0B69AE0B78A'), (101, x'E0B78AE2808DE0B6BB'), (35, x'E0B69AE0B79A'), (1, x'E0B7B4'), (9, x'E0B68C'), (96, x'E0B79C'), (6, x'E0B689'), (95, x'E0B79B'), (88, x'E0B796'), (64, x'E0B6B3'), (26, x'E0B69AE0B792'), (82, x'E0B78F'), (28, x'E0B69AE0B794'), (39, x'E0B69AE0B79E'), (97, x'E0B79D'), (2, x'E0B685'), (75, x'E0B780'), (34, x'E0B69AE0B799'), (69, x'E0B6B8'), (83, x'E0B790'), (18, x'E0B695'), (90, x'E0B7B2'), (17, x'E0B694'), (72, x'E0B6BB'), (66, x'E0B6B5'), (59, x'E0B6AD'), (44, x'E0B69E'), (15, x'E0B692'), (23, x'E0B69AE0B78F'), (65, x'E0B6B4'), (42, x'E0B69C'), (63, x'E0B6B1'), (85, x'E0B792'), (47, x'E0B6A1'), (49, x'E0B6A3'), (92, x'E0B7B3'), (78, x'E0B783'), (36, x'E0B69AE0B79B'), (4, x'E0B687'), (24, x'E0B69AE0B790'), (87, x'E0B794'), (37, x'E0B69AE0B79C'), (32, x'E0B69AE0B79F'), (29, x'E0B69AE0B796'), (43, x'E0B69D'), (62, x'E0B6B0'), (100, x'E0B78AE2808DE0B6BA'), (60, x'E0B6AE'), (45, x'E0B69F'), (12, x'E0B68F'), (46, x'E0B6A0'), (50, x'E0B6A5'), (51, x'E0B6A4'), (5, x'E0B688'), (76, x'E0B781'), (89, x'E0B798'), (74, x'E0B6BD'), (10, x'E0B68D'), (57, x'E0B6AB'), (71, x'E0B6BA'), (58, x'E0B6AC'), (27, x'E0B69AE0B793'), (54, x'E0B6A8'), (84, x'E0B791'), (31, x'E0B69AE0B7B2'), (98, x'E0B79E'), (53, x'E0B6A7'), (41, x'E0B69B'), (67, x'E0B6B6'), (7, x'E0B68A'), (20, x'E0B682'); SELECT predicted_order, hex(utf8_encoding) FROM t1 ORDER BY utf8_encoding COLLATE utf8_sinhala_ci; DROP TABLE t1; +# +# Postfix for Bug#26474 +# +SET NAMES utf8 COLLATE utf8_sinhala_ci; +CREATE TABLE t1 (s1 VARCHAR(10) COLLATE utf8_sinhala_ci); +INSERT INTO t1 VALUES ('a'),('ae'),('af'); +SELECT s1,hex(s1) FROM t1 ORDER BY s1; +SELECT * FROM t1 ORDER BY s1; +DROP TABLE t1; --echo End of 5.4 tests diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c index beacf4f02c4..3cf61b213eb 100644 --- a/strings/ctype-uca.c +++ b/strings/ctype-uca.c @@ -9461,7 +9461,7 @@ CHARSET_INFO my_charset_utf8_sinhala_uca_ci= 8, /* strxfrm_multiply */ 1, /* caseup_multiply */ 1, /* casedn_multiply */ - 3, /* mbminlen */ + 1, /* mbminlen */ 3, /* mbmaxlen */ 9, /* min_sort_char */ 0xFFFF, /* max_sort_char */ From 1b88853ab80315746dc38057bbd25ec6da7e9bf6 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 9 Nov 2010 12:45:13 -0200 Subject: [PATCH 202/304] Bug#57210: remove pstack Quoting from the bug report: The pstack library has been included in MySQL since version 4.0.0. It's useless and should be removed. Details: According to its own documentation, pstack only works on Linux on x86 in 32 bit mode and requires LinuxThreads and a statically linked binary. It doesn't really support any Linux from 2003 or later and doesn't work on any other OS. The --enable-pstack option is thus deprecated and has no effect. --- BUILD/compile-pentium-mysqlfs-debug | 2 +- Makefile.am | 2 - README | 94 - configure.in | 45 +- include/mysql_embed.h | 1 - pstack/Makefile.am | 32 - pstack/aout/Makefile.am | 4 - pstack/aout/aout64.h | 475 -- pstack/aout/stab.def | 264 - pstack/aout/stab_gnu.h | 37 - pstack/bucomm.c | 238 - pstack/bucomm.h | 91 - pstack/budbg.h | 64 - pstack/debug.c | 3509 ------------- pstack/debug.h | 798 --- pstack/demangle.h | 90 - pstack/filemode.c | 266 - pstack/ieee.c | 7602 --------------------------- pstack/ieee.h | 138 - pstack/libiberty.h | 180 - pstack/linuxthreads.c | 90 - pstack/linuxthreads.h | 28 - pstack/pstack.c | 2746 ---------- pstack/pstack.h | 22 - pstack/pstacktrace.h | 24 - pstack/rddbg.c | 462 -- pstack/stabs.c | 5082 ------------------ sql/Makefile.am | 1 - sql/mysqld.cc | 26 +- 29 files changed, 14 insertions(+), 22399 deletions(-) delete mode 100644 pstack/Makefile.am delete mode 100644 pstack/aout/Makefile.am delete mode 100644 pstack/aout/aout64.h delete mode 100644 pstack/aout/stab.def delete mode 100644 pstack/aout/stab_gnu.h delete mode 100644 pstack/bucomm.c delete mode 100644 pstack/bucomm.h delete mode 100644 pstack/budbg.h delete mode 100644 pstack/debug.c delete mode 100644 pstack/debug.h delete mode 100644 pstack/demangle.h delete mode 100644 pstack/filemode.c delete mode 100644 pstack/ieee.c delete mode 100644 pstack/ieee.h delete mode 100644 pstack/libiberty.h delete mode 100644 pstack/linuxthreads.c delete mode 100644 pstack/linuxthreads.h delete mode 100644 pstack/pstack.c delete mode 100644 pstack/pstack.h delete mode 100644 pstack/pstacktrace.h delete mode 100644 pstack/rddbg.c delete mode 100644 pstack/stabs.c diff --git a/BUILD/compile-pentium-mysqlfs-debug b/BUILD/compile-pentium-mysqlfs-debug index c871200604e..0f457eec0bb 100755 --- a/BUILD/compile-pentium-mysqlfs-debug +++ b/BUILD/compile-pentium-mysqlfs-debug @@ -6,6 +6,6 @@ path=`dirname $0` extra_flags="$pentium_cflags $debug_cflags" extra_configs="$pentium_configs $debug_configs $static_link" -extra_configs="$extra_configs --with-debug=full --with-mysqlfs --without-server --without-pstack" +extra_configs="$extra_configs --with-debug=full --with-mysqlfs --without-server" . "$path/FINISH.sh" diff --git a/Makefile.am b/Makefile.am index 4ce753ad8aa..9996d187cd4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -23,7 +23,6 @@ EXTRA_DIST = INSTALL-SOURCE INSTALL-WIN-SOURCE \ SUBDIRS = . include @docs_dirs@ @zlib_dir@ \ @readline_topdir@ sql-common scripts \ - @pstack_dir@ \ @sql_union_dirs@ unittest \ @sql_server@ @man_dirs@ tests \ netware @libmysqld_dirs@ \ @@ -32,7 +31,6 @@ SUBDIRS = . include @docs_dirs@ @zlib_dir@ \ DIST_SUBDIRS = . include Docs zlib \ cmd-line-utils sql-common scripts \ - pstack \ strings mysys dbug extra regex libmysql libmysql_r client unittest storage plugin \ vio sql man tests \ netware libmysqld \ diff --git a/README b/README index ac92d77f8bd..71491e31a8c 100644 --- a/README +++ b/README @@ -1192,97 +1192,3 @@ library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. *************************************************************************** - -%%The following software may be included in this product: -pstack (part of GNU Binutils) - -Use of any of this software is governed by the terms of the license below: - -pstack is comprised of various .c and .h files; all begin like this: - -/* bucomm.h -- binutils common include file. - Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc. - -This file is part of GNU Binutils. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ - -*************************************************************************** - -%%The following software may be included in this product: -libiberty.h (part of pstack GNU Binutils) - -Use of any of this software is governed by the terms of the license below: - -See -http://www.koders.com/c/fid99F596804BBE22C076522B848D5575F142079064.aspx - -/* Function declarations for libiberty. - Written by Cygnus Support, 1994. - - The libiberty library provides a number of functions which are - missing on some operating systems. We do not declare those here, - to avoid conflicts with the system header files on operating - systems that do support those functions. In this file we only - declare those functions which are specific to libiberty. */ - -*************************************************************************** - -%%The following software may be included in this product: -ieee.h (part of pstack GNU Binutils) - -Use of any of this software is governed by the terms of the license below: - -See -http://src.opensolaris.org/source/xref//sfw/usr/src/cmd/gdb/gdb-6.3/include/ieee.h - - -/* IEEE Standard 695-1980 "Universal Format for Object Modules" -header file - Contributed by Cygnus Support. */ - -*************************************************************************** - -%%The following software may be included in this product: -pstack.c (part of pstack GNU Binutils) - -Use of any of this software is governed by the terms of the license below: - -/* - pstack.c -- asynchronous stack trace of a running process - Copyright (c) 1999 Ross Thompson - Author: Ross Thompson - Critical bug fix: Tim Waugh -*/ - -/* - This file is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. -*/ - -*************************************************************************** diff --git a/configure.in b/configure.in index 7fd581af009..6c9c64d9c86 100644 --- a/configure.in +++ b/configure.in @@ -910,46 +910,6 @@ struct request_info *req; ]) AC_SUBST(WRAPLIBS) -if test "$TARGET_LINUX" = "true"; then - AC_ARG_WITH(pstack, - [ --with-pstack Use the pstack backtrace library], - [ USE_PSTACK=$withval ], - [ USE_PSTACK=no ]) - pstack_libs= - pstack_dir= - if test "$USE_PSTACK" = yes -a "$TARGET_LINUX" = "true" -a "$BASE_MACHINE_TYPE" = "i386" - then - have_libiberty= have_libbfd= - my_save_LIBS="$LIBS" -dnl I have no idea if this is a good test - can not find docs for libiberty - AC_CHECK_LIB([iberty], [fdmatch], - [have_libiberty=yes - AC_CHECK_LIB([bfd], [bfd_openr], [have_libbfd=yes], , [-liberty])]) - LIBS="$my_save_LIBS" - - if test x"$have_libiberty" = xyes -a x"$have_libbfd" = xyes - then - pstack_dir="pstack" - pstack_libs="../pstack/libpstack.a -lbfd -liberty" - # We must link staticly when using pstack - with_mysqld_ldflags="-all-static" - AC_SUBST([pstack_dir]) - AC_SUBST([pstack_libs]) - AC_DEFINE([USE_PSTACK], [1], [the pstack backtrace library]) -dnl This check isn't needed, but might be nice to give some feedback.... -dnl AC_CHECK_HEADER(libiberty.h, -dnl have_libiberty_h=yes, -dnl have_libiberty_h=no) - else - USE_PSTACK="no" - fi - else - USE_PSTACK="no" - fi -fi -AC_MSG_CHECKING([if we should use pstack]) -AC_MSG_RESULT([$USE_PSTACK]) - # Check for gtty if termio.h doesn't exists if test "$ac_cv_header_termio_h" = "no" -a "$ac_cv_header_termios_h" = "no" then @@ -1178,7 +1138,7 @@ dnl Is this the right match for DEC OSF on alpha? sql/Makefile.in) # Use gen_lex_hash.linux instead of gen_lex_hash # Add library dependencies to mysqld_DEPENDENCIES - lib_DEPENDENCIES="\$(pstack_libs) \$(openssl_libs) \$(yassl_libs)" + lib_DEPENDENCIES="\$(openssl_libs) \$(yassl_libs)" cat > $filesed << EOF s,\(\./gen_lex_hash\)\$(EXEEXT),\1.linux, s%\(mysqld_DEPENDENCIES = \)%\1$lib_DEPENDENCIES % @@ -2880,9 +2840,6 @@ esac AC_SUBST(MAKE_BINARY_DISTRIBUTION_OPTIONS) # Output results -if test -d "$srcdir/pstack" ; then - AC_CONFIG_FILES(pstack/Makefile pstack/aout/Makefile) -fi if test -d "$srcdir/cmd-line-utils/readline" ; then AC_CONFIG_FILES(cmd-line-utils/readline/Makefile) fi diff --git a/include/mysql_embed.h b/include/mysql_embed.h index 4a7fd3ef63c..a7d6e610918 100644 --- a/include/mysql_embed.h +++ b/include/mysql_embed.h @@ -20,7 +20,6 @@ /* Things we don't need in the embedded version of MySQL */ /* TODO HF add #undef HAVE_VIO if we don't want client in embedded library */ -#undef HAVE_PSTACK /* No stacktrace */ #undef HAVE_OPENSSL #undef HAVE_SMEM /* No shared memory */ #undef HAVE_NDBCLUSTER_DB /* No NDB cluster */ diff --git a/pstack/Makefile.am b/pstack/Makefile.am deleted file mode 100644 index 870fed6ceeb..00000000000 --- a/pstack/Makefile.am +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright (C) 2000-2003, 2005 MySQL AB -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -# -# As pstack doesn't work on all configurations, we have to use -# the USE_PSTACK hack to get all files into distribution -# - -SUBDIRS = aout - -INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include - -pkglib_LIBRARIES = libpstack.a -libpstack_a_SOURCES = bucomm.c filemode.c linuxthreads.c rddbg.c \ - debug.c ieee.c pstack.c stabs.c -noinst_HEADERS = bucomm.h debug.h ieee.h budbg.h demangle.h \ - linuxthreads.h pstack.h pstacktrace.h - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/pstack/aout/Makefile.am b/pstack/aout/Makefile.am deleted file mode 100644 index 2e61555db87..00000000000 --- a/pstack/aout/Makefile.am +++ /dev/null @@ -1,4 +0,0 @@ -noinst_HEADERS = aout64.h stab.def stab_gnu.h - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/pstack/aout/aout64.h b/pstack/aout/aout64.h deleted file mode 100644 index 76f1140b682..00000000000 --- a/pstack/aout/aout64.h +++ /dev/null @@ -1,475 +0,0 @@ -/* `a.out' object-file definitions, including extensions to 64-bit fields */ - -#ifndef __A_OUT_64_H__ -#define __A_OUT_64_H__ - -/* This is the layout on disk of the 32-bit or 64-bit exec header. */ - -#ifndef external_exec -struct external_exec -{ - bfd_byte e_info[4]; /* magic number and stuff */ - bfd_byte e_text[BYTES_IN_WORD]; /* length of text section in bytes */ - bfd_byte e_data[BYTES_IN_WORD]; /* length of data section in bytes */ - bfd_byte e_bss[BYTES_IN_WORD]; /* length of bss area in bytes */ - bfd_byte e_syms[BYTES_IN_WORD]; /* length of symbol table in bytes */ - bfd_byte e_entry[BYTES_IN_WORD]; /* start address */ - bfd_byte e_trsize[BYTES_IN_WORD]; /* length of text relocation info */ - bfd_byte e_drsize[BYTES_IN_WORD]; /* length of data relocation info */ -}; - -#define EXEC_BYTES_SIZE (4 + BYTES_IN_WORD * 7) - -/* Magic numbers for a.out files */ - -#if ARCH_SIZE==64 -#define OMAGIC 0x1001 /* Code indicating object file */ -#define ZMAGIC 0x1002 /* Code indicating demand-paged executable. */ -#define NMAGIC 0x1003 /* Code indicating pure executable. */ - -/* There is no 64-bit QMAGIC as far as I know. */ - -#define N_BADMAG(x) (N_MAGIC(x) != OMAGIC \ - && N_MAGIC(x) != NMAGIC \ - && N_MAGIC(x) != ZMAGIC) -#else -#define OMAGIC 0407 /* ...object file or impure executable. */ -#define NMAGIC 0410 /* Code indicating pure executable. */ -#define ZMAGIC 0413 /* Code indicating demand-paged executable. */ -#define BMAGIC 0415 /* Used by a b.out object. */ - -/* This indicates a demand-paged executable with the header in the text. - It is used by 386BSD (and variants) and Linux, at least. */ -#ifndef QMAGIC -#define QMAGIC 0314 -#endif -# ifndef N_BADMAG -# define N_BADMAG(x) (N_MAGIC(x) != OMAGIC \ - && N_MAGIC(x) != NMAGIC \ - && N_MAGIC(x) != ZMAGIC \ - && N_MAGIC(x) != QMAGIC) -# endif /* N_BADMAG */ -#endif - -#endif - -#ifdef QMAGIC -#define N_IS_QMAGIC(x) (N_MAGIC (x) == QMAGIC) -#else -#define N_IS_QMAGIC(x) (0) -#endif - -/* The difference between TARGET_PAGE_SIZE and N_SEGSIZE is that TARGET_PAGE_SIZE is - the finest granularity at which you can page something, thus it - controls the padding (if any) before the text segment of a ZMAGIC - file. N_SEGSIZE is the resolution at which things can be marked as - read-only versus read/write, so it controls the padding between the - text segment and the data segment (in memory; on disk the padding - between them is TARGET_PAGE_SIZE). TARGET_PAGE_SIZE and N_SEGSIZE are the same - for most machines, but different for sun3. */ - -/* By default, segment size is constant. But some machines override this - to be a function of the a.out header (e.g. machine type). */ - -#ifndef N_SEGSIZE -#define N_SEGSIZE(x) SEGMENT_SIZE -#endif - -/* Virtual memory address of the text section. - This is getting very complicated. A good reason to discard a.out format - for something that specifies these fields explicitly. But til then... - - * OMAGIC and NMAGIC files: - (object files: text for "relocatable addr 0" right after the header) - start at 0, offset is EXEC_BYTES_SIZE, size as stated. - * The text address, offset, and size of ZMAGIC files depend - on the entry point of the file: - * entry point below TEXT_START_ADDR: - (hack for SunOS shared libraries) - start at 0, offset is 0, size as stated. - * If N_HEADER_IN_TEXT(x) is true (which defaults to being the - case when the entry point is EXEC_BYTES_SIZE or further into a page): - no padding is needed; text can start after exec header. Sun - considers the text segment of such files to include the exec header; - for BFD's purposes, we don't, which makes more work for us. - start at TEXT_START_ADDR + EXEC_BYTES_SIZE, offset is EXEC_BYTES_SIZE, - size as stated minus EXEC_BYTES_SIZE. - * If N_HEADER_IN_TEXT(x) is false (which defaults to being the case when - the entry point is less than EXEC_BYTES_SIZE into a page (e.g. page - aligned)): (padding is needed so that text can start at a page boundary) - start at TEXT_START_ADDR, offset TARGET_PAGE_SIZE, size as stated. - - Specific configurations may want to hardwire N_HEADER_IN_TEXT, - for efficiency or to allow people to play games with the entry point. - In that case, you would #define N_HEADER_IN_TEXT(x) as 1 for sunos, - and as 0 for most other hosts (Sony News, Vax Ultrix, etc). - (Do this in the appropriate bfd target file.) - (The default is a heuristic that will break if people try changing - the entry point, perhaps with the ld -e flag.) - - * QMAGIC is always like a ZMAGIC for which N_HEADER_IN_TEXT is true, - and for which the starting address is TARGET_PAGE_SIZE (or should this be - SEGMENT_SIZE?) (TEXT_START_ADDR only applies to ZMAGIC, not to QMAGIC). - */ - -/* This macro is only relevant for ZMAGIC files; QMAGIC always has the header - in the text. */ -#ifndef N_HEADER_IN_TEXT -#define N_HEADER_IN_TEXT(x) (((x).a_entry & (TARGET_PAGE_SIZE-1)) >= EXEC_BYTES_SIZE) -#endif - -/* Sun shared libraries, not linux. This macro is only relevant for ZMAGIC - files. */ -#ifndef N_SHARED_LIB -#define N_SHARED_LIB(x) ((x).a_entry < TEXT_START_ADDR) -#endif - -/* Returning 0 not TEXT_START_ADDR for OMAGIC and NMAGIC is based on - the assumption that we are dealing with a .o file, not an - executable. This is necessary for OMAGIC (but means we don't work - right on the output from ld -N); more questionable for NMAGIC. */ - -#ifndef N_TXTADDR -#define N_TXTADDR(x) \ - (/* The address of a QMAGIC file is always one page in, */ \ - /* with the header in the text. */ \ - N_IS_QMAGIC (x) ? TARGET_PAGE_SIZE + EXEC_BYTES_SIZE : \ - N_MAGIC(x) != ZMAGIC ? 0 : /* object file or NMAGIC */\ - N_SHARED_LIB(x) ? 0 : \ - N_HEADER_IN_TEXT(x) ? \ - TEXT_START_ADDR + EXEC_BYTES_SIZE : /* no padding */\ - TEXT_START_ADDR /* a page of padding */\ - ) -#endif - -/* If N_HEADER_IN_TEXT is not true for ZMAGIC, there is some padding - to make the text segment start at a certain boundary. For most - systems, this boundary is TARGET_PAGE_SIZE. But for Linux, in the - time-honored tradition of crazy ZMAGIC hacks, it is 1024 which is - not what TARGET_PAGE_SIZE needs to be for QMAGIC. */ - -#ifndef ZMAGIC_DISK_BLOCK_SIZE -#define ZMAGIC_DISK_BLOCK_SIZE TARGET_PAGE_SIZE -#endif - -#define N_DISK_BLOCK_SIZE(x) \ - (N_MAGIC(x) == ZMAGIC ? ZMAGIC_DISK_BLOCK_SIZE : TARGET_PAGE_SIZE) - -/* Offset in an a.out of the start of the text section. */ -#ifndef N_TXTOFF -#define N_TXTOFF(x) \ - (/* For {O,N,Q}MAGIC, no padding. */ \ - N_MAGIC(x) != ZMAGIC ? EXEC_BYTES_SIZE : \ - N_SHARED_LIB(x) ? 0 : \ - N_HEADER_IN_TEXT(x) ? \ - EXEC_BYTES_SIZE : /* no padding */\ - ZMAGIC_DISK_BLOCK_SIZE /* a page of padding */\ - ) -#endif -/* Size of the text section. It's always as stated, except that we - offset it to `undo' the adjustment to N_TXTADDR and N_TXTOFF - for ZMAGIC files that nominally include the exec header - as part of the first page of text. (BFD doesn't consider the - exec header to be part of the text segment.) */ -#ifndef N_TXTSIZE -#define N_TXTSIZE(x) \ - (/* For QMAGIC, we don't consider the header part of the text section. */\ - N_IS_QMAGIC (x) ? (x).a_text - EXEC_BYTES_SIZE : \ - (N_MAGIC(x) != ZMAGIC || N_SHARED_LIB(x)) ? (x).a_text : \ - N_HEADER_IN_TEXT(x) ? \ - (x).a_text - EXEC_BYTES_SIZE: /* no padding */\ - (x).a_text /* a page of padding */\ - ) -#endif -/* The address of the data segment in virtual memory. - It is the text segment address, plus text segment size, rounded - up to a N_SEGSIZE boundary for pure or pageable files. */ -#ifndef N_DATADDR -#define N_DATADDR(x) \ - (N_MAGIC(x)==OMAGIC? (N_TXTADDR(x)+N_TXTSIZE(x)) \ - : (N_SEGSIZE(x) + ((N_TXTADDR(x)+N_TXTSIZE(x)-1) & ~(N_SEGSIZE(x)-1)))) -#endif -/* The address of the BSS segment -- immediately after the data segment. */ - -#define N_BSSADDR(x) (N_DATADDR(x) + (x).a_data) - -/* Offsets of the various portions of the file after the text segment. */ - -/* For {Q,Z}MAGIC, there is padding to make the data segment start on - a page boundary. Most of the time the a_text field (and thus - N_TXTSIZE) already contains this padding. It is possible that for - BSDI and/or 386BSD it sometimes doesn't contain the padding, and - perhaps we should be adding it here. But this seems kind of - questionable and probably should be BSDI/386BSD-specific if we do - do it. - - For NMAGIC (at least for hp300 BSD, probably others), there is - padding in memory only, not on disk, so we must *not* ever pad here - for NMAGIC. */ - -#ifndef N_DATOFF -#define N_DATOFF(x) \ - (N_TXTOFF(x) + N_TXTSIZE(x)) -#endif - -#ifndef N_TRELOFF -#define N_TRELOFF(x) ( N_DATOFF(x) + (x).a_data ) -#endif -#ifndef N_DRELOFF -#define N_DRELOFF(x) ( N_TRELOFF(x) + (x).a_trsize ) -#endif -#ifndef N_SYMOFF -#define N_SYMOFF(x) ( N_DRELOFF(x) + (x).a_drsize ) -#endif -#ifndef N_STROFF -#define N_STROFF(x) ( N_SYMOFF(x) + (x).a_syms ) -#endif - -/* Symbols */ -#ifndef external_nlist -struct external_nlist { - bfd_byte e_strx[BYTES_IN_WORD]; /* index into string table of name */ - bfd_byte e_type[1]; /* type of symbol */ - bfd_byte e_other[1]; /* misc info (usually empty) */ - bfd_byte e_desc[2]; /* description field */ - bfd_byte e_value[BYTES_IN_WORD]; /* value of symbol */ -}; -#define EXTERNAL_NLIST_SIZE (BYTES_IN_WORD+4+BYTES_IN_WORD) -#endif - -struct internal_nlist { - unsigned long n_strx; /* index into string table of name */ - unsigned char n_type; /* type of symbol */ - unsigned char n_other; /* misc info (usually empty) */ - unsigned short n_desc; /* description field */ - bfd_vma n_value; /* value of symbol */ -}; - -/* The n_type field is the symbol type, containing: */ - -#define N_UNDF 0 /* Undefined symbol */ -#define N_ABS 2 /* Absolute symbol -- defined at particular addr */ -#define N_TEXT 4 /* Text sym -- defined at offset in text seg */ -#define N_DATA 6 /* Data sym -- defined at offset in data seg */ -#define N_BSS 8 /* BSS sym -- defined at offset in zero'd seg */ -#define N_COMM 0x12 /* Common symbol (visible after shared lib dynlink) */ -#define N_FN 0x1f /* File name of .o file */ -#define N_FN_SEQ 0x0C /* N_FN from Sequent compilers (sigh) */ -/* Note: N_EXT can only be usefully OR-ed with N_UNDF, N_ABS, N_TEXT, - N_DATA, or N_BSS. When the low-order bit of other types is set, - (e.g. N_WARNING versus N_FN), they are two different types. */ -#define N_EXT 1 /* External symbol (as opposed to local-to-this-file) */ -#define N_TYPE 0x1e -#define N_STAB 0xe0 /* If any of these bits are on, it's a debug symbol */ - -#define N_INDR 0x0a - -/* The following symbols refer to set elements. - All the N_SET[ATDB] symbols with the same name form one set. - Space is allocated for the set in the text section, and each set - elements value is stored into one word of the space. - The first word of the space is the length of the set (number of elements). - - The address of the set is made into an N_SETV symbol - whose name is the same as the name of the set. - This symbol acts like a N_DATA global symbol - in that it can satisfy undefined external references. */ - -/* These appear as input to LD, in a .o file. */ -#define N_SETA 0x14 /* Absolute set element symbol */ -#define N_SETT 0x16 /* Text set element symbol */ -#define N_SETD 0x18 /* Data set element symbol */ -#define N_SETB 0x1A /* Bss set element symbol */ - -/* This is output from LD. */ -#define N_SETV 0x1C /* Pointer to set vector in data area. */ - -/* Warning symbol. The text gives a warning message, the next symbol - in the table will be undefined. When the symbol is referenced, the - message is printed. */ - -#define N_WARNING 0x1e - -/* Weak symbols. These are a GNU extension to the a.out format. The - semantics are those of ELF weak symbols. Weak symbols are always - externally visible. The N_WEAK? values are squeezed into the - available slots. The value of a N_WEAKU symbol is 0. The values - of the other types are the definitions. */ -#define N_WEAKU 0x0d /* Weak undefined symbol. */ -#define N_WEAKA 0x0e /* Weak absolute symbol. */ -#define N_WEAKT 0x0f /* Weak text symbol. */ -#define N_WEAKD 0x10 /* Weak data symbol. */ -#define N_WEAKB 0x11 /* Weak bss symbol. */ - -/* Relocations - - There are two types of relocation flavours for a.out systems, - standard and extended. The standard form is used on systems where the - instruction has room for all the bits of an offset to the operand, whilst - the extended form is used when an address operand has to be split over n - instructions. Eg, on the 68k, each move instruction can reference - the target with a displacement of 16 or 32 bits. On the sparc, move - instructions use an offset of 14 bits, so the offset is stored in - the reloc field, and the data in the section is ignored. -*/ - -/* This structure describes a single relocation to be performed. - The text-relocation section of the file is a vector of these structures, - all of which apply to the text section. - Likewise, the data-relocation section applies to the data section. */ - -struct reloc_std_external { - bfd_byte r_address[BYTES_IN_WORD]; /* offset of of data to relocate */ - bfd_byte r_index[3]; /* symbol table index of symbol */ - bfd_byte r_type[1]; /* relocation type */ -}; - -#define RELOC_STD_BITS_PCREL_BIG ((unsigned int) 0x80) -#define RELOC_STD_BITS_PCREL_LITTLE ((unsigned int) 0x01) - -#define RELOC_STD_BITS_LENGTH_BIG ((unsigned int) 0x60) -#define RELOC_STD_BITS_LENGTH_SH_BIG 5 -#define RELOC_STD_BITS_LENGTH_LITTLE ((unsigned int) 0x06) -#define RELOC_STD_BITS_LENGTH_SH_LITTLE 1 - -#define RELOC_STD_BITS_EXTERN_BIG ((unsigned int) 0x10) -#define RELOC_STD_BITS_EXTERN_LITTLE ((unsigned int) 0x08) - -#define RELOC_STD_BITS_BASEREL_BIG ((unsigned int) 0x08) -#define RELOC_STD_BITS_BASEREL_LITTLE ((unsigned int) 0x10) - -#define RELOC_STD_BITS_JMPTABLE_BIG ((unsigned int) 0x04) -#define RELOC_STD_BITS_JMPTABLE_LITTLE ((unsigned int) 0x20) - -#define RELOC_STD_BITS_RELATIVE_BIG ((unsigned int) 0x02) -#define RELOC_STD_BITS_RELATIVE_LITTLE ((unsigned int) 0x40) - -#define RELOC_STD_SIZE (BYTES_IN_WORD + 3 + 1) /* Bytes per relocation entry */ - -struct reloc_std_internal -{ - bfd_vma r_address; /* Address (within segment) to be relocated. */ - /* The meaning of r_symbolnum depends on r_extern. */ - unsigned int r_symbolnum:24; - /* Nonzero means value is a pc-relative offset - and it should be relocated for changes in its own address - as well as for changes in the symbol or section specified. */ - unsigned int r_pcrel:1; - /* Length (as exponent of 2) of the field to be relocated. - Thus, a value of 2 indicates 1<<2 bytes. */ - unsigned int r_length:2; - /* 1 => relocate with value of symbol. - r_symbolnum is the index of the symbol - in files the symbol table. - 0 => relocate with the address of a segment. - r_symbolnum is N_TEXT, N_DATA, N_BSS or N_ABS - (the N_EXT bit may be set also, but signifies nothing). */ - unsigned int r_extern:1; - /* The next three bits are for SunOS shared libraries, and seem to - be undocumented. */ - unsigned int r_baserel:1; /* Linkage table relative */ - unsigned int r_jmptable:1; /* pc-relative to jump table */ - unsigned int r_relative:1; /* "relative relocation" */ - /* unused */ - unsigned int r_pad:1; /* Padding -- set to zero */ -}; - - -/* EXTENDED RELOCS */ - -struct reloc_ext_external { - bfd_byte r_address[BYTES_IN_WORD]; /* offset of of data to relocate */ - bfd_byte r_index[3]; /* symbol table index of symbol */ - bfd_byte r_type[1]; /* relocation type */ - bfd_byte r_addend[BYTES_IN_WORD]; /* datum addend */ -}; - -#define RELOC_EXT_BITS_EXTERN_BIG ((unsigned int) 0x80) -#define RELOC_EXT_BITS_EXTERN_LITTLE ((unsigned int) 0x01) - -#define RELOC_EXT_BITS_TYPE_BIG ((unsigned int) 0x1F) -#define RELOC_EXT_BITS_TYPE_SH_BIG 0 -#define RELOC_EXT_BITS_TYPE_LITTLE ((unsigned int) 0xF8) -#define RELOC_EXT_BITS_TYPE_SH_LITTLE 3 - -/* Bytes per relocation entry */ -#define RELOC_EXT_SIZE (BYTES_IN_WORD + 3 + 1 + BYTES_IN_WORD) - -enum reloc_type -{ - /* simple relocations */ - RELOC_8, /* data[0:7] = addend + sv */ - RELOC_16, /* data[0:15] = addend + sv */ - RELOC_32, /* data[0:31] = addend + sv */ - /* pc-rel displacement */ - RELOC_DISP8, /* data[0:7] = addend - pc + sv */ - RELOC_DISP16, /* data[0:15] = addend - pc + sv */ - RELOC_DISP32, /* data[0:31] = addend - pc + sv */ - /* Special */ - RELOC_WDISP30, /* data[0:29] = (addend + sv - pc)>>2 */ - RELOC_WDISP22, /* data[0:21] = (addend + sv - pc)>>2 */ - RELOC_HI22, /* data[0:21] = (addend + sv)>>10 */ - RELOC_22, /* data[0:21] = (addend + sv) */ - RELOC_13, /* data[0:12] = (addend + sv) */ - RELOC_LO10, /* data[0:9] = (addend + sv) */ - RELOC_SFA_BASE, - RELOC_SFA_OFF13, - /* P.I.C. (base-relative) */ - RELOC_BASE10, /* Not sure - maybe we can do this the */ - RELOC_BASE13, /* right way now */ - RELOC_BASE22, - /* for some sort of pc-rel P.I.C. (?) */ - RELOC_PC10, - RELOC_PC22, - /* P.I.C. jump table */ - RELOC_JMP_TBL, - /* reputedly for shared libraries somehow */ - RELOC_SEGOFF16, - RELOC_GLOB_DAT, - RELOC_JMP_SLOT, - RELOC_RELATIVE, - - RELOC_11, - RELOC_WDISP2_14, - RELOC_WDISP19, - RELOC_HHI22, /* data[0:21] = (addend + sv) >> 42 */ - RELOC_HLO10, /* data[0:9] = (addend + sv) >> 32 */ - - /* 29K relocation types */ - RELOC_JUMPTARG, - RELOC_CONST, - RELOC_CONSTH, - - /* All the new ones I can think of, for sparc v9 */ - - RELOC_64, /* data[0:63] = addend + sv */ - RELOC_DISP64, /* data[0:63] = addend - pc + sv */ - RELOC_WDISP21, /* data[0:20] = (addend + sv - pc)>>2 */ - RELOC_DISP21, /* data[0:20] = addend - pc + sv */ - RELOC_DISP14, /* data[0:13] = addend - pc + sv */ - /* Q . - What are the other ones, - Since this is a clean slate, can we throw away the ones we dont - understand ? Should we sort the values ? What about using a - microcode format like the 68k ? - */ - NO_RELOC - }; - - -struct reloc_internal { - bfd_vma r_address; /* offset of of data to relocate */ - long r_index; /* symbol table index of symbol */ - enum reloc_type r_type; /* relocation type */ - bfd_vma r_addend; /* datum addend */ -}; - -/* Q. - Should the length of the string table be 4 bytes or 8 bytes ? - - Q. - What about archive indexes ? - - */ - -#endif /* __A_OUT_64_H__ */ diff --git a/pstack/aout/stab.def b/pstack/aout/stab.def deleted file mode 100644 index 3c6b456d3a9..00000000000 --- a/pstack/aout/stab.def +++ /dev/null @@ -1,264 +0,0 @@ -/* Table of DBX symbol codes for the GNU system. - Copyright (C) 1988, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* New stab from Solaris 2. This uses an n_type of 0, which in a.out files - overlaps the N_UNDF used for ordinary symbols. In ELF files, the - debug information is in a different file section, so there is no conflict. - This symbol's n_value gives the size of the string section associated - with this file. The symbol's n_strx (relative to the just-updated - string section start address) gives the name of the source file, - e.g. "foo.c", without any path information. The symbol's n_desc gives - the count of upcoming symbols associated with this file (not including - this one). */ -/* __define_stab (N_UNDF, 0x00, "UNDF") */ - -/* Global variable. Only the name is significant. - To find the address, look in the corresponding external symbol. */ -__define_stab (N_GSYM, 0x20, "GSYM") - -/* Function name for BSD Fortran. Only the name is significant. - To find the address, look in the corresponding external symbol. */ -__define_stab (N_FNAME, 0x22, "FNAME") - -/* Function name or text-segment variable for C. Value is its address. - Desc is supposedly starting line number, but GCC doesn't set it - and DBX seems not to miss it. */ -__define_stab (N_FUN, 0x24, "FUN") - -/* Data-segment variable with internal linkage. Value is its address. - "Static Sym". */ -__define_stab (N_STSYM, 0x26, "STSYM") - -/* BSS-segment variable with internal linkage. Value is its address. */ -__define_stab (N_LCSYM, 0x28, "LCSYM") - -/* Name of main routine. Only the name is significant. */ -__define_stab (N_MAIN, 0x2a, "MAIN") - -/* Solaris2: Read-only data symbols. */ -__define_stab (N_ROSYM, 0x2c, "ROSYM") - -/* Global symbol in Pascal. - Supposedly the value is its line number; I'm skeptical. */ -__define_stab (N_PC, 0x30, "PC") - -/* Number of symbols: 0, files,,funcs,lines according to Ultrix V4.0. */ -__define_stab (N_NSYMS, 0x32, "NSYMS") - -/* "No DST map for sym: name, ,0,type,ignored" according to Ultrix V4.0. */ -__define_stab (N_NOMAP, 0x34, "NOMAP") - -/* New stab from Solaris 2. Like N_SO, but for the object file. Two in - a row provide the build directory and the relative path of the .o from it. - Solaris2 uses this to avoid putting the stabs info into the linked - executable; this stab goes into the ".stab.index" section, and the debugger - reads the real stabs directly from the .o files instead. */ -__define_stab (N_OBJ, 0x38, "OBJ") - -/* New stab from Solaris 2. Options for the debugger, related to the - source language for this module. E.g. whether to use ANSI - integral promotions or traditional integral promotions. */ -__define_stab (N_OPT, 0x3c, "OPT") - -/* Register variable. Value is number of register. */ -__define_stab (N_RSYM, 0x40, "RSYM") - -/* Modula-2 compilation unit. Can someone say what info it contains? */ -__define_stab (N_M2C, 0x42, "M2C") - -/* Line number in text segment. Desc is the line number; - value is corresponding address. On Solaris2, the line number is - relative to the start of the current function. */ -__define_stab (N_SLINE, 0x44, "SLINE") - -/* Similar, for data segment. */ -__define_stab (N_DSLINE, 0x46, "DSLINE") - -/* Similar, for bss segment. */ -__define_stab (N_BSLINE, 0x48, "BSLINE") - -/* Sun's source-code browser stabs. ?? Don't know what the fields are. - Supposedly the field is "path to associated .cb file". THIS VALUE - OVERLAPS WITH N_BSLINE! */ -__define_stab_duplicate (N_BROWS, 0x48, "BROWS") - -/* GNU Modula-2 definition module dependency. Value is the modification time - of the definition file. Other is non-zero if it is imported with the - GNU M2 keyword %INITIALIZE. Perhaps N_M2C can be used if there - are enough empty fields? */ -__define_stab(N_DEFD, 0x4a, "DEFD") - -/* New in Solaris2. Function start/body/end line numbers. */ -__define_stab(N_FLINE, 0x4C, "FLINE") - -/* THE FOLLOWING TWO STAB VALUES CONFLICT. Happily, one is for Modula-2 - and one is for C++. Still,... */ -/* GNU C++ exception variable. Name is variable name. */ -__define_stab (N_EHDECL, 0x50, "EHDECL") -/* Modula2 info "for imc": name,,0,0,0 according to Ultrix V4.0. */ -__define_stab_duplicate (N_MOD2, 0x50, "MOD2") - -/* GNU C++ `catch' clause. Value is its address. Desc is nonzero if - this entry is immediately followed by a CAUGHT stab saying what exception - was caught. Multiple CAUGHT stabs means that multiple exceptions - can be caught here. If Desc is 0, it means all exceptions are caught - here. */ -__define_stab (N_CATCH, 0x54, "CATCH") - -/* Structure or union element. Value is offset in the structure. */ -__define_stab (N_SSYM, 0x60, "SSYM") - -/* Solaris2: Last stab emitted for module. */ -__define_stab (N_ENDM, 0x62, "ENDM") - -/* Name of main source file. - Value is starting text address of the compilation. - If multiple N_SO's appear, the first to contain a trailing / is the - compilation directory. The first to not contain a trailing / is the - source file name, relative to the compilation directory. Others (perhaps - resulting from cfront) are ignored. - On Solaris2, value is undefined, but desc is a source-language code. */ - -__define_stab (N_SO, 0x64, "SO") - -/* Automatic variable in the stack. Value is offset from frame pointer. - Also used for type descriptions. */ -__define_stab (N_LSYM, 0x80, "LSYM") - -/* Beginning of an include file. Only Sun uses this. - In an object file, only the name is significant. - The Sun linker puts data into some of the other fields. */ -__define_stab (N_BINCL, 0x82, "BINCL") - -/* Name of sub-source file (#include file). - Value is starting text address of the compilation. */ -__define_stab (N_SOL, 0x84, "SOL") - -/* Parameter variable. Value is offset from argument pointer. - (On most machines the argument pointer is the same as the frame pointer. */ -__define_stab (N_PSYM, 0xa0, "PSYM") - -/* End of an include file. No name. - This and N_BINCL act as brackets around the file's output. - In an object file, there is no significant data in this entry. - The Sun linker puts data into some of the fields. */ -__define_stab (N_EINCL, 0xa2, "EINCL") - -/* Alternate entry point. Value is its address. */ -__define_stab (N_ENTRY, 0xa4, "ENTRY") - -/* Beginning of lexical block. - The desc is the nesting level in lexical blocks. - The value is the address of the start of the text for the block. - The variables declared inside the block *precede* the N_LBRAC symbol. - On Solaris2, the value is relative to the start of the current function. */ -__define_stab (N_LBRAC, 0xc0, "LBRAC") - -/* Place holder for deleted include file. Replaces a N_BINCL and everything - up to the corresponding N_EINCL. The Sun linker generates these when - it finds multiple identical copies of the symbols from an include file. - This appears only in output from the Sun linker. */ -__define_stab (N_EXCL, 0xc2, "EXCL") - -/* Modula-2 scope information. Can someone say what info it contains? */ -__define_stab (N_SCOPE, 0xc4, "SCOPE") - -/* End of a lexical block. Desc matches the N_LBRAC's desc. - The value is the address of the end of the text for the block. - On Solaris2, the value is relative to the start of the current function. */ -__define_stab (N_RBRAC, 0xe0, "RBRAC") - -/* Begin named common block. Only the name is significant. */ -__define_stab (N_BCOMM, 0xe2, "BCOMM") - -/* End named common block. Only the name is significant - (and it should match the N_BCOMM). */ -__define_stab (N_ECOMM, 0xe4, "ECOMM") - -/* Member of a common block; value is offset within the common block. - This should occur within a BCOMM/ECOMM pair. */ -__define_stab (N_ECOML, 0xe8, "ECOML") - -/* Solaris2: Pascal "with" statement: type,,0,0,offset */ -__define_stab (N_WITH, 0xea, "WITH") - -/* These STAB's are used on Gould systems for Non-Base register symbols - or something like that. FIXME. I have assigned the values at random - since I don't have a Gould here. Fixups from Gould folk welcome... */ -__define_stab (N_NBTEXT, 0xF0, "NBTEXT") -__define_stab (N_NBDATA, 0xF2, "NBDATA") -__define_stab (N_NBBSS, 0xF4, "NBBSS") -__define_stab (N_NBSTS, 0xF6, "NBSTS") -__define_stab (N_NBLCS, 0xF8, "NBLCS") - -/* Second symbol entry containing a length-value for the preceding entry. - The value is the length. */ -__define_stab (N_LENG, 0xfe, "LENG") - -/* The above information, in matrix format. - - STAB MATRIX - _________________________________________________ - | 00 - 1F are not dbx stab symbols | - | In most cases, the low bit is the EXTernal bit| - - | 00 UNDEF | 02 ABS | 04 TEXT | 06 DATA | - | 01 |EXT | 03 |EXT | 05 |EXT | 07 |EXT | - - | 08 BSS | 0A INDR | 0C FN_SEQ | 0E WEAKA | - | 09 |EXT | 0B | 0D WEAKU | 0F WEAKT | - - | 10 WEAKD | 12 COMM | 14 SETA | 16 SETT | - | 11 WEAKB | 13 | 15 | 17 | - - | 18 SETD | 1A SETB | 1C SETV | 1E WARNING| - | 19 | 1B | 1D | 1F FN | - - |_______________________________________________| - | Debug entries with bit 01 set are unused. | - | 20 GSYM | 22 FNAME | 24 FUN | 26 STSYM | - | 28 LCSYM | 2A MAIN | 2C ROSYM | 2E | - | 30 PC | 32 NSYMS | 34 NOMAP | 36 | - | 38 OBJ | 3A | 3C OPT | 3E | - | 40 RSYM | 42 M2C | 44 SLINE | 46 DSLINE | - | 48 BSLINE*| 4A DEFD | 4C FLINE | 4E | - | 50 EHDECL*| 52 | 54 CATCH | 56 | - | 58 | 5A | 5C | 5E | - | 60 SSYM | 62 ENDM | 64 SO | 66 | - | 68 | 6A | 6C | 6E | - | 70 | 72 | 74 | 76 | - | 78 | 7A | 7C | 7E | - | 80 LSYM | 82 BINCL | 84 SOL | 86 | - | 88 | 8A | 8C | 8E | - | 90 | 92 | 94 | 96 | - | 98 | 9A | 9C | 9E | - | A0 PSYM | A2 EINCL | A4 ENTRY | A6 | - | A8 | AA | AC | AE | - | B0 | B2 | B4 | B6 | - | B8 | BA | BC | BE | - | C0 LBRAC | C2 EXCL | C4 SCOPE | C6 | - | C8 | CA | CC | CE | - | D0 | D2 | D4 | D6 | - | D8 | DA | DC | DE | - | E0 RBRAC | E2 BCOMM | E4 ECOMM | E6 | - | E8 ECOML | EA WITH | EC | EE | - | F0 | F2 | F4 | F6 | - | F8 | FA | FC | FE LENG | - +-----------------------------------------------+ - * 50 EHDECL is also MOD2. - * 48 BSLINE is also BROWS. - */ diff --git a/pstack/aout/stab_gnu.h b/pstack/aout/stab_gnu.h deleted file mode 100644 index 7d18e14a263..00000000000 --- a/pstack/aout/stab_gnu.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef __GNU_STAB__ - -/* Indicate the GNU stab.h is in use. */ - -#define __GNU_STAB__ - -#define __define_stab(NAME, CODE, STRING) NAME=CODE, -#define __define_stab_duplicate(NAME, CODE, STRING) NAME=CODE, - -enum __stab_debug_code -{ -#include "aout/stab.def" -LAST_UNUSED_STAB_CODE -}; - -#undef __define_stab - -/* Definitions of "desc" field for N_SO stabs in Solaris2. */ - -#define N_SO_AS 1 -#define N_SO_C 2 -#define N_SO_ANSI_C 3 -#define N_SO_CC 4 /* C++ */ -#define N_SO_FORTRAN 5 -#define N_SO_PASCAL 6 - -/* Solaris2: Floating point type values in basic types. */ - -#define NF_NONE 0 -#define NF_SINGLE 1 /* IEEE 32-bit */ -#define NF_DOUBLE 2 /* IEEE 64-bit */ -#define NF_COMPLEX 3 /* Fortran complex */ -#define NF_COMPLEX16 4 /* Fortran double complex */ -#define NF_COMPLEX32 5 /* Fortran complex*16 */ -#define NF_LDOUBLE 6 /* Long double (whatever that is) */ - -#endif /* __GNU_STAB_ */ diff --git a/pstack/bucomm.c b/pstack/bucomm.c deleted file mode 100644 index d3231e71747..00000000000 --- a/pstack/bucomm.c +++ /dev/null @@ -1,238 +0,0 @@ -/* bucomm.c -- Bin Utils COMmon code. - Copyright (C) 1991, 92, 93, 94, 95, 1997 Free Software Foundation, Inc. - - This file is part of GNU Binutils. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -/* We might put this in a library someday so it could be dynamically - loaded, but for now it's not necessary. */ - -#include -#include -#include "bucomm.h" - -#include -#include /* ctime, maybe time_t */ - -#ifdef ANSI_PROTOTYPES -#include -#else -#include -#endif - -/* Error reporting */ - -char *program_name; - -void -bfd_nonfatal (string) - CONST char *string; -{ - CONST char *errmsg = bfd_errmsg (bfd_get_error ()); - - if (string) - fprintf (stderr, "%s: %s: %s\n", program_name, string, errmsg); - else - fprintf (stderr, "%s: %s\n", program_name, errmsg); -} - -void -bfd_fatal (string) - CONST char *string; -{ - bfd_nonfatal (string); - xexit (1); -} - -#ifdef ANSI_PROTOTYPES -void -fatal (const char *format, ...) -{ - va_list args; - - fprintf (stderr, "%s: ", program_name); - va_start (args, format); - vfprintf (stderr, format, args); - va_end (args); - putc ('\n', stderr); - xexit (1); -} -#else -void -fatal (va_alist) - va_dcl -{ - char *Format; - va_list args; - - fprintf (stderr, "%s: ", program_name); - va_start (args); - Format = va_arg (args, char *); - vfprintf (stderr, Format, args); - va_end (args); - putc ('\n', stderr); - xexit (1); -} -#endif - -/* Set the default BFD target based on the configured target. Doing - this permits the binutils to be configured for a particular target, - and linked against a shared BFD library which was configured for a - different target. */ - -#define TARGET "elf32-i386" /* FIXME: hard-coded! */ -void -set_default_bfd_target () -{ - /* The macro TARGET is defined by Makefile. */ - const char *target = TARGET; - - if (! bfd_set_default_target (target)) - { - char *errmsg; - - errmsg = (char *) xmalloc (100 + strlen (target)); - sprintf (errmsg, "can't set BFD default target to `%s'", target); - bfd_fatal (errmsg); - } -} - -/* After a false return from bfd_check_format_matches with - bfd_get_error () == bfd_error_file_ambiguously_recognized, print - the possible matching targets. */ - -void -list_matching_formats (p) - char **p; -{ - fprintf(stderr, "%s: Matching formats:", program_name); - while (*p) - fprintf(stderr, " %s", *p++); - fprintf(stderr, "\n"); -} - -/* List the supported targets. */ - -void -list_supported_targets (name, f) - const char *name; - FILE *f; -{ - extern bfd_target *bfd_target_vector[]; - int t; - - if (name == NULL) - fprintf (f, "Supported targets:"); - else - fprintf (f, "%s: supported targets:", name); - for (t = 0; bfd_target_vector[t] != NULL; t++) - fprintf (f, " %s", bfd_target_vector[t]->name); - fprintf (f, "\n"); -} - -/* Display the archive header for an element as if it were an ls -l listing: - - Mode User\tGroup\tSize\tDate Name */ - -void -print_arelt_descr (file, abfd, verbose) - FILE *file; - bfd *abfd; - boolean verbose; -{ - struct stat buf; - - if (verbose) - { - if (bfd_stat_arch_elt (abfd, &buf) == 0) - { - char modebuf[11]; - char timebuf[40]; - time_t when = buf.st_mtime; - CONST char *ctime_result = (CONST char *) ctime (&when); - - /* POSIX format: skip weekday and seconds from ctime output. */ - sprintf (timebuf, "%.12s %.4s", ctime_result + 4, ctime_result + 20); - - mode_string (buf.st_mode, modebuf); - modebuf[10] = '\0'; - /* POSIX 1003.2/D11 says to skip first character (entry type). */ - fprintf (file, "%s %ld/%ld %6ld %s ", modebuf + 1, - (long) buf.st_uid, (long) buf.st_gid, - (long) buf.st_size, timebuf); - } - } - - fprintf (file, "%s\n", bfd_get_filename (abfd)); -} - -/* Return the name of a temporary file in the same directory as FILENAME. */ - -char * -make_tempname (filename) - char *filename; -{ - static char template[] = "stXXXXXX"; - char *tmpname; - char *slash = strrchr (filename, '/'); - -#if defined (__DJGPP__) || defined (__GO32__) || defined (_WIN32) - if (slash == NULL) - slash = strrchr (filename, '\\'); -#endif - - if (slash != (char *) NULL) - { - char c; - - c = *slash; - *slash = 0; - tmpname = xmalloc (strlen (filename) + sizeof (template) + 1); - strcpy (tmpname, filename); - strcat (tmpname, "/"); - strcat (tmpname, template); - mkstemp (tmpname); - *slash = c; - } - else - { - tmpname = xmalloc (sizeof (template)); - strcpy (tmpname, template); - mkstemp (tmpname); - } - return tmpname; -} - -/* Parse a string into a VMA, with a fatal error if it can't be - parsed. */ - -bfd_vma -parse_vma (s, arg) - const char *s; - const char *arg; -{ - bfd_vma ret; - const char *end; - - ret = bfd_scan_vma (s, &end, 0); - if (*end != '\0') - { - fprintf (stderr, "%s: %s: bad number: %s\n", program_name, arg, s); - exit (1); - } - return ret; -} diff --git a/pstack/bucomm.h b/pstack/bucomm.h deleted file mode 100644 index 6b3633d8d63..00000000000 --- a/pstack/bucomm.h +++ /dev/null @@ -1,91 +0,0 @@ -/* bucomm.h -- binutils common include file. - Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc. - -This file is part of GNU Binutils. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifndef _BUCOMM_H -#define _BUCOMM_H - -#include "ansidecl.h" -#include -#include - -#include -#include - -#include - -#include - -#include - -#ifdef __GNUC__ -# undef alloca -# define alloca __builtin_alloca -#else -# if HAVE_ALLOCA_H -# include -# else -# ifndef alloca /* predefined by HP cc +Olibcalls */ -# if !defined (__STDC__) && !defined (__hpux) -char *alloca (); -# else -void *alloca (); -# endif /* __STDC__, __hpux */ -# endif /* alloca */ -# endif /* HAVE_ALLOCA_H */ -#endif - -#ifndef BFD_TRUE_FALSE -#define boolean bfd_boolean -#define true TRUE -#define false FALSE -#endif - -/* bucomm.c */ -void bfd_nonfatal PARAMS ((CONST char *)); - -void bfd_fatal PARAMS ((CONST char *)); - -void fatal PARAMS ((CONST char *, ...)); - -void set_default_bfd_target PARAMS ((void)); - -void list_matching_formats PARAMS ((char **p)); - -void list_supported_targets PARAMS ((const char *, FILE *)); - -void print_arelt_descr PARAMS ((FILE *file, bfd *abfd, boolean verbose)); - -char *make_tempname PARAMS ((char *)); - -bfd_vma parse_vma PARAMS ((const char *, const char *)); - -extern char *program_name; - -/* filemode.c */ -void mode_string PARAMS ((unsigned long mode, char *buf)); - -/* version.c */ -extern void print_version PARAMS ((const char *)); - -/* libiberty */ -PTR xmalloc PARAMS ((size_t)); - -PTR xrealloc PARAMS ((PTR, size_t)); - -#endif /* _BUCOMM_H */ diff --git a/pstack/budbg.h b/pstack/budbg.h deleted file mode 100644 index 9f0203ad5e7..00000000000 --- a/pstack/budbg.h +++ /dev/null @@ -1,64 +0,0 @@ -/* budbg.c -- Interfaces to the generic debugging information routines. - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - Written by Ian Lance Taylor . - - This file is part of GNU Binutils. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -#ifndef BUDBG_H -#define BUDBG_H - -#include - -#ifndef BFD_TRUE_FALSE -#define boolean bfd_boolean -#define true TRUE -#define false FALSE -#endif - -/* Routine used to read generic debugging information. */ - -extern PTR read_debugging_info PARAMS ((bfd *, asymbol **, long)); - -/* Routine used to print generic debugging information. */ - -extern boolean print_debugging_info PARAMS ((FILE *, PTR)); - -/* Routines used to read and write stabs information. */ - -extern PTR start_stab PARAMS ((PTR, bfd *, boolean, asymbol **, long)); - -extern boolean finish_stab PARAMS ((PTR, PTR)); - -extern boolean parse_stab PARAMS ((PTR, PTR, int, int, bfd_vma, const char *)); - -extern boolean write_stabs_in_sections_debugging_info - PARAMS ((bfd *, PTR, bfd_byte **, bfd_size_type *, bfd_byte **, - bfd_size_type *)); - -/* Routines used to read and write IEEE debugging information. */ - -extern boolean parse_ieee - PARAMS ((PTR, bfd *, const bfd_byte *, bfd_size_type)); - -extern boolean write_ieee_debugging_info PARAMS ((bfd *, PTR)); - -/* Routine used to read COFF debugging information. */ - -extern boolean parse_coff PARAMS ((bfd *, asymbol **, long, PTR)); - -#endif diff --git a/pstack/debug.c b/pstack/debug.c deleted file mode 100644 index 73412ae3f03..00000000000 --- a/pstack/debug.c +++ /dev/null @@ -1,3509 +0,0 @@ -/* debug.c -- Handle generic debugging information. - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - Written by Ian Lance Taylor . - - This file is part of GNU Binutils. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -/* This file implements a generic debugging format. We may eventually - have readers which convert different formats into this generic - format, and writers which write it out. The initial impetus for - this was writing a convertor from stabs to HP IEEE-695 debugging - format. */ - -#include -#include - -#include -#include "bucomm.h" -#include -#include "debug.h" - -/* Global information we keep for debugging. A pointer to this - structure is the debugging handle passed to all the routines. */ - -struct debug_handle -{ - /* A linked list of compilation units. */ - struct debug_unit *units; - /* The current compilation unit. */ - struct debug_unit *current_unit; - /* The current source file. */ - struct debug_file *current_file; - /* The current function. */ - struct debug_function *current_function; - /* The current block. */ - struct debug_block *current_block; - /* The current line number information for the current unit. */ - struct debug_lineno *current_lineno; - /* Mark. This is used by debug_write. */ - unsigned int mark; - /* A struct/class ID used by debug_write. */ - unsigned int class_id; - /* The base for class_id for this call to debug_write. */ - unsigned int base_id; - /* The current line number in debug_write. */ - struct debug_lineno *current_write_lineno; - unsigned int current_write_lineno_index; - /* A list of classes which have assigned ID's during debug_write. - This is linked through the next_id field of debug_class_type. */ - struct debug_class_id *id_list; - /* A list used to avoid recursion during debug_type_samep. */ - struct debug_type_compare_list *compare_list; -}; - -/* Information we keep for a single compilation unit. */ - -struct debug_unit -{ - /* The next compilation unit. */ - struct debug_unit *next; - /* A list of files included in this compilation unit. The first - file is always the main one, and that is where the main file name - is stored. */ - struct debug_file *files; - /* Line number information for this compilation unit. This is not - stored by function, because assembler code may have line number - information without function information. */ - struct debug_lineno *linenos; -}; - -/* Information kept for a single source file. */ - -struct debug_file -{ - /* The next source file in this compilation unit. */ - struct debug_file *next; - /* The name of the source file. */ - const char *filename; - /* Global functions, variables, types, etc. */ - struct debug_namespace *globals; -}; - -/* A type. */ - -struct debug_type -{ - /* Kind of type. */ - enum debug_type_kind kind; - /* Size of type (0 if not known). */ - unsigned int size; - /* Type which is a pointer to this type. */ - debug_type pointer; - /* Tagged union with additional information about the type. */ - union - { - /* DEBUG_KIND_INDIRECT. */ - struct debug_indirect_type *kindirect; - /* DEBUG_KIND_INT. */ - /* Whether the integer is unsigned. */ - boolean kint; - /* DEBUG_KIND_STRUCT, DEBUG_KIND_UNION, DEBUG_KIND_CLASS, - DEBUG_KIND_UNION_CLASS. */ - struct debug_class_type *kclass; - /* DEBUG_KIND_ENUM. */ - struct debug_enum_type *kenum; - /* DEBUG_KIND_POINTER. */ - struct debug_type *kpointer; - /* DEBUG_KIND_FUNCTION. */ - struct debug_function_type *kfunction; - /* DEBUG_KIND_REFERENCE. */ - struct debug_type *kreference; - /* DEBUG_KIND_RANGE. */ - struct debug_range_type *krange; - /* DEBUG_KIND_ARRAY. */ - struct debug_array_type *karray; - /* DEBUG_KIND_SET. */ - struct debug_set_type *kset; - /* DEBUG_KIND_OFFSET. */ - struct debug_offset_type *koffset; - /* DEBUG_KIND_METHOD. */ - struct debug_method_type *kmethod; - /* DEBUG_KIND_CONST. */ - struct debug_type *kconst; - /* DEBUG_KIND_VOLATILE. */ - struct debug_type *kvolatile; - /* DEBUG_KIND_NAMED, DEBUG_KIND_TAGGED. */ - struct debug_named_type *knamed; - } u; -}; - -/* Information kept for an indirect type. */ - -struct debug_indirect_type -{ - /* Slot where the final type will appear. */ - debug_type *slot; - /* Tag. */ - const char *tag; -}; - -/* Information kept for a struct, union, or class. */ - -struct debug_class_type -{ - /* NULL terminated array of fields. */ - debug_field *fields; - /* A mark field which indicates whether the struct has already been - printed. */ - unsigned int mark; - /* This is used to uniquely identify unnamed structs when printing. */ - unsigned int id; - /* The remaining fields are only used for DEBUG_KIND_CLASS and - DEBUG_KIND_UNION_CLASS. */ - /* NULL terminated array of base classes. */ - debug_baseclass *baseclasses; - /* NULL terminated array of methods. */ - debug_method *methods; - /* The type of the class providing the virtual function table for - this class. This may point to the type itself. */ - debug_type vptrbase; -}; - -/* Information kept for an enum. */ - -struct debug_enum_type -{ - /* NULL terminated array of names. */ - const char **names; - /* Array of corresponding values. */ - bfd_signed_vma *values; -}; - -/* Information kept for a function. FIXME: We should be able to - record the parameter types. */ - -struct debug_function_type -{ - /* Return type. */ - debug_type return_type; - /* NULL terminated array of argument types. */ - debug_type *arg_types; - /* Whether the function takes a variable number of arguments. */ - boolean varargs; -}; - -/* Information kept for a range. */ - -struct debug_range_type -{ - /* Range base type. */ - debug_type type; - /* Lower bound. */ - bfd_signed_vma lower; - /* Upper bound. */ - bfd_signed_vma upper; -}; - -/* Information kept for an array. */ - -struct debug_array_type -{ - /* Element type. */ - debug_type element_type; - /* Range type. */ - debug_type range_type; - /* Lower bound. */ - bfd_signed_vma lower; - /* Upper bound. */ - bfd_signed_vma upper; - /* Whether this array is really a string. */ - boolean stringp; -}; - -/* Information kept for a set. */ - -struct debug_set_type -{ - /* Base type. */ - debug_type type; - /* Whether this set is really a bitstring. */ - boolean bitstringp; -}; - -/* Information kept for an offset type (a based pointer). */ - -struct debug_offset_type -{ - /* The type the pointer is an offset from. */ - debug_type base_type; - /* The type the pointer points to. */ - debug_type target_type; -}; - -/* Information kept for a method type. */ - -struct debug_method_type -{ - /* The return type. */ - debug_type return_type; - /* The object type which this method is for. */ - debug_type domain_type; - /* A NULL terminated array of argument types. */ - debug_type *arg_types; - /* Whether the method takes a variable number of arguments. */ - boolean varargs; -}; - -/* Information kept for a named type. */ - -struct debug_named_type -{ - /* Name. */ - struct debug_name *name; - /* Real type. */ - debug_type type; -}; - -/* A field in a struct or union. */ - -struct debug_field -{ - /* Name of the field. */ - const char *name; - /* Type of the field. */ - struct debug_type *type; - /* Visibility of the field. */ - enum debug_visibility visibility; - /* Whether this is a static member. */ - boolean static_member; - union - { - /* If static_member is false. */ - struct - { - /* Bit position of the field in the struct. */ - unsigned int bitpos; - /* Size of the field in bits. */ - unsigned int bitsize; - } f; - /* If static_member is true. */ - struct - { - const char *physname; - } s; - } u; -}; - -/* A base class for an object. */ - -struct debug_baseclass -{ - /* Type of the base class. */ - struct debug_type *type; - /* Bit position of the base class in the object. */ - unsigned int bitpos; - /* Whether the base class is virtual. */ - boolean virtual; - /* Visibility of the base class. */ - enum debug_visibility visibility; -}; - -/* A method of an object. */ - -struct debug_method -{ - /* The name of the method. */ - const char *name; - /* A NULL terminated array of different types of variants. */ - struct debug_method_variant **variants; -}; - -/* The variants of a method function of an object. These indicate - which method to run. */ - -struct debug_method_variant -{ - /* The physical name of the function. */ - const char *physname; - /* The type of the function. */ - struct debug_type *type; - /* The visibility of the function. */ - enum debug_visibility visibility; - /* Whether the function is const. */ - boolean constp; - /* Whether the function is volatile. */ - boolean volatilep; - /* The offset to the function in the virtual function table. */ - bfd_vma voffset; - /* If voffset is VOFFSET_STATIC_METHOD, this is a static method. */ -#define VOFFSET_STATIC_METHOD ((bfd_vma) -1) - /* Context of a virtual method function. */ - struct debug_type *context; -}; - -/* A variable. This is the information we keep for a variable object. - This has no name; a name is associated with a variable in a - debug_name structure. */ - -struct debug_variable -{ - /* Kind of variable. */ - enum debug_var_kind kind; - /* Type. */ - debug_type type; - /* Value. The interpretation of the value depends upon kind. */ - bfd_vma val; -}; - -/* A function. This has no name; a name is associated with a function - in a debug_name structure. */ - -struct debug_function -{ - /* Return type. */ - debug_type return_type; - /* Parameter information. */ - struct debug_parameter *parameters; - /* Block information. The first structure on the list is the main - block of the function, and describes function local variables. */ - struct debug_block *blocks; -}; - -/* A function parameter. */ - -struct debug_parameter -{ - /* Next parameter. */ - struct debug_parameter *next; - /* Name. */ - const char *name; - /* Type. */ - debug_type type; - /* Kind. */ - enum debug_parm_kind kind; - /* Value (meaning depends upon kind). */ - bfd_vma val; -}; - -/* A typed constant. */ - -struct debug_typed_constant -{ - /* Type. */ - debug_type type; - /* Value. FIXME: We may eventually need to support non-integral - values. */ - bfd_vma val; -}; - -/* Information about a block within a function. */ - -struct debug_block -{ - /* Next block with the same parent. */ - struct debug_block *next; - /* Parent block. */ - struct debug_block *parent; - /* List of child blocks. */ - struct debug_block *children; - /* Start address of the block. */ - bfd_vma start; - /* End address of the block. */ - bfd_vma end; - /* Local variables. */ - struct debug_namespace *locals; -}; - -/* Line number information we keep for a compilation unit. FIXME: - This structure is easy to create, but can be very space - inefficient. */ - -struct debug_lineno -{ - /* More line number information for this block. */ - struct debug_lineno *next; - /* Source file. */ - struct debug_file *file; - /* Line numbers, terminated by a -1 or the end of the array. */ -#define DEBUG_LINENO_COUNT 10 - unsigned long linenos[DEBUG_LINENO_COUNT]; - /* Addresses for the line numbers. */ - bfd_vma addrs[DEBUG_LINENO_COUNT]; -}; - -/* A namespace. This is a mapping from names to objects. FIXME: This - should be implemented as a hash table. */ - -struct debug_namespace -{ - /* List of items in this namespace. */ - struct debug_name *list; - /* Pointer to where the next item in this namespace should go. */ - struct debug_name **tail; -}; - -/* Kinds of objects that appear in a namespace. */ - -enum debug_object_kind -{ - /* A type. */ - DEBUG_OBJECT_TYPE, - /* A tagged type (really a different sort of namespace). */ - DEBUG_OBJECT_TAG, - /* A variable. */ - DEBUG_OBJECT_VARIABLE, - /* A function. */ - DEBUG_OBJECT_FUNCTION, - /* An integer constant. */ - DEBUG_OBJECT_INT_CONSTANT, - /* A floating point constant. */ - DEBUG_OBJECT_FLOAT_CONSTANT, - /* A typed constant. */ - DEBUG_OBJECT_TYPED_CONSTANT -}; - -/* Linkage of an object that appears in a namespace. */ - -enum debug_object_linkage -{ - /* Local variable. */ - DEBUG_LINKAGE_AUTOMATIC, - /* Static--either file static or function static, depending upon the - namespace is. */ - DEBUG_LINKAGE_STATIC, - /* Global. */ - DEBUG_LINKAGE_GLOBAL, - /* No linkage. */ - DEBUG_LINKAGE_NONE -}; - -/* A name in a namespace. */ - -struct debug_name -{ - /* Next name in this namespace. */ - struct debug_name *next; - /* Name. */ - const char *name; - /* Mark. This is used by debug_write. */ - unsigned int mark; - /* Kind of object. */ - enum debug_object_kind kind; - /* Linkage of object. */ - enum debug_object_linkage linkage; - /* Tagged union with additional information about the object. */ - union - { - /* DEBUG_OBJECT_TYPE. */ - struct debug_type *type; - /* DEBUG_OBJECT_TAG. */ - struct debug_type *tag; - /* DEBUG_OBJECT_VARIABLE. */ - struct debug_variable *variable; - /* DEBUG_OBJECT_FUNCTION. */ - struct debug_function *function; - /* DEBUG_OBJECT_INT_CONSTANT. */ - bfd_vma int_constant; - /* DEBUG_OBJECT_FLOAT_CONSTANT. */ - double float_constant; - /* DEBUG_OBJECT_TYPED_CONSTANT. */ - struct debug_typed_constant *typed_constant; - } u; -}; - -/* During debug_write, a linked list of these structures is used to - keep track of ID numbers that have been assigned to classes. */ - -struct debug_class_id -{ - /* Next ID number. */ - struct debug_class_id *next; - /* The type with the ID. */ - struct debug_type *type; - /* The tag; NULL if no tag. */ - const char *tag; -}; - -/* During debug_type_samep, a linked list of these structures is kept - on the stack to avoid infinite recursion. */ - -struct debug_type_compare_list -{ - /* Next type on list. */ - struct debug_type_compare_list *next; - /* The types we are comparing. */ - struct debug_type *t1; - struct debug_type *t2; -}; - -/* Local functions. */ - -static void debug_error PARAMS ((const char *)); -static struct debug_name *debug_add_to_namespace - PARAMS ((struct debug_handle *, struct debug_namespace **, const char *, - enum debug_object_kind, enum debug_object_linkage)); -static struct debug_name *debug_add_to_current_namespace - PARAMS ((struct debug_handle *, const char *, enum debug_object_kind, - enum debug_object_linkage)); -static struct debug_type *debug_make_type - PARAMS ((struct debug_handle *, enum debug_type_kind, unsigned int)); -static struct debug_type *debug_get_real_type PARAMS ((PTR, debug_type)); -static boolean debug_write_name - PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR, - struct debug_name *)); -static boolean debug_write_type - PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR, - struct debug_type *, struct debug_name *)); -static boolean debug_write_class_type - PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR, - struct debug_type *, const char *)); -static boolean debug_write_function - PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR, - const char *, enum debug_object_linkage, struct debug_function *)); -static boolean debug_write_block - PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR, - struct debug_block *)); -static boolean debug_write_linenos - PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR, - bfd_vma)); -static boolean debug_set_class_id - PARAMS ((struct debug_handle *, const char *, struct debug_type *)); -static boolean debug_type_samep - PARAMS ((struct debug_handle *, struct debug_type *, struct debug_type *)); -static boolean debug_class_type_samep - PARAMS ((struct debug_handle *, struct debug_type *, struct debug_type *)); - -/* Issue an error message. */ - -static void -debug_error (message) - const char *message; -{ - fprintf (stderr, "%s\n", message); -} - -/* Add an object to a namespace. */ - -static struct debug_name * -debug_add_to_namespace (info, nsp, name, kind, linkage) - struct debug_handle *info; - struct debug_namespace **nsp; - const char *name; - enum debug_object_kind kind; - enum debug_object_linkage linkage; -{ - struct debug_name *n; - struct debug_namespace *ns; - - n = (struct debug_name *) xmalloc (sizeof *n); - memset (n, 0, sizeof *n); - - n->name = name; - n->kind = kind; - n->linkage = linkage; - - ns = *nsp; - if (ns == NULL) - { - ns = (struct debug_namespace *) xmalloc (sizeof *ns); - memset (ns, 0, sizeof *ns); - - ns->tail = &ns->list; - - *nsp = ns; - } - - *ns->tail = n; - ns->tail = &n->next; - - return n; -} - -/* Add an object to the current namespace. */ - -static struct debug_name * -debug_add_to_current_namespace (info, name, kind, linkage) - struct debug_handle *info; - const char *name; - enum debug_object_kind kind; - enum debug_object_linkage linkage; -{ - struct debug_namespace **nsp; - - if (info->current_unit == NULL - || info->current_file == NULL) - { - debug_error ("debug_add_to_current_namespace: no current file"); - return NULL; - } - - if (info->current_block != NULL) - nsp = &info->current_block->locals; - else - nsp = &info->current_file->globals; - - return debug_add_to_namespace (info, nsp, name, kind, linkage); -} - -/* Return a handle for debugging information. */ - -PTR -debug_init () -{ - struct debug_handle *ret; - - ret = (struct debug_handle *) xmalloc (sizeof *ret); - memset (ret, 0, sizeof *ret); - return (PTR) ret; -} - -/* Set the source filename. This implicitly starts a new compilation - unit. */ - -boolean -debug_set_filename (handle, name) - PTR handle; - const char *name; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_file *nfile; - struct debug_unit *nunit; - - if (name == NULL) - name = ""; - - nfile = (struct debug_file *) xmalloc (sizeof *nfile); - memset (nfile, 0, sizeof *nfile); - - nfile->filename = name; - - nunit = (struct debug_unit *) xmalloc (sizeof *nunit); - memset (nunit, 0, sizeof *nunit); - - nunit->files = nfile; - info->current_file = nfile; - - if (info->current_unit != NULL) - info->current_unit->next = nunit; - else - { - assert (info->units == NULL); - info->units = nunit; - } - - info->current_unit = nunit; - - info->current_function = NULL; - info->current_block = NULL; - info->current_lineno = NULL; - - return true; -} - -/* Change source files to the given file name. This is used for - include files in a single compilation unit. */ - -boolean -debug_start_source (handle, name) - PTR handle; - const char *name; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_file *f, **pf; - - if (name == NULL) - name = ""; - - if (info->current_unit == NULL) - { - debug_error ("debug_start_source: no debug_set_filename call"); - return false; - } - - for (f = info->current_unit->files; f != NULL; f = f->next) - { - if (f->filename[0] == name[0] - && f->filename[1] == name[1] - && strcmp (f->filename, name) == 0) - { - info->current_file = f; - return true; - } - } - - f = (struct debug_file *) xmalloc (sizeof *f); - memset (f, 0, sizeof *f); - - f->filename = name; - - for (pf = &info->current_file->next; - *pf != NULL; - pf = &(*pf)->next) - ; - *pf = f; - - info->current_file = f; - - return true; -} - -/* Record a function definition. This implicitly starts a function - block. The debug_type argument is the type of the return value. - The boolean indicates whether the function is globally visible. - The bfd_vma is the address of the start of the function. Currently - the parameter types are specified by calls to - debug_record_parameter. FIXME: There is no way to specify nested - functions. */ - -boolean -debug_record_function (handle, name, return_type, global, addr) - PTR handle; - const char *name; - debug_type return_type; - boolean global; - bfd_vma addr; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_function *f; - struct debug_block *b; - struct debug_name *n; - - if (name == NULL) - name = ""; - if (return_type == NULL) - return false; - - if (info->current_unit == NULL) - { - debug_error ("debug_record_function: no debug_set_filename call"); - return false; - } - - f = (struct debug_function *) xmalloc (sizeof *f); - memset (f, 0, sizeof *f); - - f->return_type = return_type; - - b = (struct debug_block *) xmalloc (sizeof *b); - memset (b, 0, sizeof *b); - - b->start = addr; - b->end = (bfd_vma) -1; - - f->blocks = b; - - info->current_function = f; - info->current_block = b; - - /* FIXME: If we could handle nested functions, this would be the - place: we would want to use a different namespace. */ - n = debug_add_to_namespace (info, - &info->current_file->globals, - name, - DEBUG_OBJECT_FUNCTION, - (global - ? DEBUG_LINKAGE_GLOBAL - : DEBUG_LINKAGE_STATIC)); - if (n == NULL) - return false; - - n->u.function = f; - - return true; -} - -/* Record a parameter for the current function. */ - -boolean -debug_record_parameter (handle, name, type, kind, val) - PTR handle; - const char *name; - debug_type type; - enum debug_parm_kind kind; - bfd_vma val; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_parameter *p, **pp; - - if (name == NULL || type == NULL) - return false; - - if (info->current_unit == NULL - || info->current_function == NULL) - { - debug_error ("debug_record_parameter: no current function"); - return false; - } - - p = (struct debug_parameter *) xmalloc (sizeof *p); - memset (p, 0, sizeof *p); - - p->name = name; - p->type = type; - p->kind = kind; - p->val = val; - - for (pp = &info->current_function->parameters; - *pp != NULL; - pp = &(*pp)->next) - ; - *pp = p; - - return true; -} - -/* End a function. FIXME: This should handle function nesting. */ - -boolean -debug_end_function (handle, addr) - PTR handle; - bfd_vma addr; -{ - struct debug_handle *info = (struct debug_handle *) handle; - - if (info->current_unit == NULL - || info->current_block == NULL - || info->current_function == NULL) - { - debug_error ("debug_end_function: no current function"); - return false; - } - - if (info->current_block->parent != NULL) - { - debug_error ("debug_end_function: some blocks were not closed"); - return false; - } - - info->current_block->end = addr; - - info->current_function = NULL; - info->current_block = NULL; - - return true; -} - -/* Start a block in a function. All local information will be - recorded in this block, until the matching call to debug_end_block. - debug_start_block and debug_end_block may be nested. The bfd_vma - argument is the address at which this block starts. */ - -boolean -debug_start_block (handle, addr) - PTR handle; - bfd_vma addr; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_block *b, **pb; - - /* We must always have a current block: debug_record_function sets - one up. */ - if (info->current_unit == NULL - || info->current_block == NULL) - { - debug_error ("debug_start_block: no current block"); - return false; - } - - b = (struct debug_block *) xmalloc (sizeof *b); - memset (b, 0, sizeof *b); - - b->parent = info->current_block; - b->start = addr; - b->end = (bfd_vma) -1; - - /* This new block is a child of the current block. */ - for (pb = &info->current_block->children; - *pb != NULL; - pb = &(*pb)->next) - ; - *pb = b; - - info->current_block = b; - - return true; -} - -/* Finish a block in a function. This matches the call to - debug_start_block. The argument is the address at which this block - ends. */ - -boolean -debug_end_block (handle, addr) - PTR handle; - bfd_vma addr; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_block *parent; - - if (info->current_unit == NULL - || info->current_block == NULL) - { - debug_error ("debug_end_block: no current block"); - return false; - } - - parent = info->current_block->parent; - if (parent == NULL) - { - debug_error ("debug_end_block: attempt to close top level block"); - return false; - } - - info->current_block->end = addr; - - info->current_block = parent; - - return true; -} - -/* Associate a line number in the current source file and function - with a given address. */ - -boolean -debug_record_line (handle, lineno, addr) - PTR handle; - unsigned long lineno; - bfd_vma addr; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_lineno *l; - unsigned int i; - - if (info->current_unit == NULL) - { - debug_error ("debug_record_line: no current unit"); - return false; - } - - l = info->current_lineno; - if (l != NULL && l->file == info->current_file) - { - for (i = 0; i < DEBUG_LINENO_COUNT; i++) - { - if (l->linenos[i] == (unsigned long) -1) - { - l->linenos[i] = lineno; - l->addrs[i] = addr; - return true; - } - } - } - - /* If we get here, then either 1) there is no current_lineno - structure, which means this is the first line number in this - compilation unit, 2) the current_lineno structure is for a - different file, or 3) the current_lineno structure is full. - Regardless, we want to allocate a new debug_lineno structure, put - it in the right place, and make it the new current_lineno - structure. */ - - l = (struct debug_lineno *) xmalloc (sizeof *l); - memset (l, 0, sizeof *l); - - l->file = info->current_file; - l->linenos[0] = lineno; - l->addrs[0] = addr; - for (i = 1; i < DEBUG_LINENO_COUNT; i++) - l->linenos[i] = (unsigned long) -1; - - if (info->current_lineno != NULL) - info->current_lineno->next = l; - else - info->current_unit->linenos = l; - - info->current_lineno = l; - - return true; -} - -/* Start a named common block. This is a block of variables that may - move in memory. */ - -boolean -debug_start_common_block (handle, name) - PTR handle; - const char *name; -{ - /* FIXME */ - debug_error ("debug_start_common_block: not implemented"); - return false; -} - -/* End a named common block. */ - -boolean -debug_end_common_block (handle, name) - PTR handle; - const char *name; -{ - /* FIXME */ - debug_error ("debug_end_common_block: not implemented"); - return false; -} - -/* Record a named integer constant. */ - -boolean -debug_record_int_const (handle, name, val) - PTR handle; - const char *name; - bfd_vma val; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_name *n; - - if (name == NULL) - return false; - - n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_INT_CONSTANT, - DEBUG_LINKAGE_NONE); - if (n == NULL) - return false; - - n->u.int_constant = val; - - return true; -} - -/* Record a named floating point constant. */ - -boolean -debug_record_float_const (handle, name, val) - PTR handle; - const char *name; - double val; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_name *n; - - if (name == NULL) - return false; - - n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_FLOAT_CONSTANT, - DEBUG_LINKAGE_NONE); - if (n == NULL) - return false; - - n->u.float_constant = val; - - return true; -} - -/* Record a typed constant with an integral value. */ - -boolean -debug_record_typed_const (handle, name, type, val) - PTR handle; - const char *name; - debug_type type; - bfd_vma val; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_name *n; - struct debug_typed_constant *tc; - - if (name == NULL || type == NULL) - return false; - - n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_TYPED_CONSTANT, - DEBUG_LINKAGE_NONE); - if (n == NULL) - return false; - - tc = (struct debug_typed_constant *) xmalloc (sizeof *tc); - memset (tc, 0, sizeof *tc); - - tc->type = type; - tc->val = val; - - n->u.typed_constant = tc; - - return true; -} - -/* Record a label. */ - -boolean -debug_record_label (handle, name, type, addr) - PTR handle; - const char *name; - debug_type type; - bfd_vma addr; -{ - /* FIXME. */ - debug_error ("debug_record_label not implemented"); - return false; -} - -/* Record a variable. */ - -boolean -debug_record_variable (handle, name, type, kind, val) - PTR handle; - const char *name; - debug_type type; - enum debug_var_kind kind; - bfd_vma val; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_namespace **nsp; - enum debug_object_linkage linkage; - struct debug_name *n; - struct debug_variable *v; - - if (name == NULL || type == NULL) - return false; - - if (info->current_unit == NULL - || info->current_file == NULL) - { - debug_error ("debug_record_variable: no current file"); - return false; - } - - if (kind == DEBUG_GLOBAL || kind == DEBUG_STATIC) - { - nsp = &info->current_file->globals; - if (kind == DEBUG_GLOBAL) - linkage = DEBUG_LINKAGE_GLOBAL; - else - linkage = DEBUG_LINKAGE_STATIC; - } - else - { - if (info->current_block == NULL) - { - debug_error ("debug_record_variable: no current block"); - return false; - } - nsp = &info->current_block->locals; - linkage = DEBUG_LINKAGE_AUTOMATIC; - } - - n = debug_add_to_namespace (info, nsp, name, DEBUG_OBJECT_VARIABLE, linkage); - if (n == NULL) - return false; - - v = (struct debug_variable *) xmalloc (sizeof *v); - memset (v, 0, sizeof *v); - - v->kind = kind; - v->type = type; - v->val = val; - - n->u.variable = v; - - return true; -} - -/* Make a type with a given kind and size. */ - -/*ARGSUSED*/ -static struct debug_type * -debug_make_type (info, kind, size) - struct debug_handle *info; - enum debug_type_kind kind; - unsigned int size; -{ - struct debug_type *t; - - t = (struct debug_type *) xmalloc (sizeof *t); - memset (t, 0, sizeof *t); - - t->kind = kind; - t->size = size; - - return t; -} - -/* Make an indirect type which may be used as a placeholder for a type - which is referenced before it is defined. */ - -debug_type -debug_make_indirect_type (handle, slot, tag) - PTR handle; - debug_type *slot; - const char *tag; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - struct debug_indirect_type *i; - - t = debug_make_type (info, DEBUG_KIND_INDIRECT, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - i = (struct debug_indirect_type *) xmalloc (sizeof *i); - memset (i, 0, sizeof *i); - - i->slot = slot; - i->tag = tag; - - t->u.kindirect = i; - - return t; -} - -/* Make a void type. There is only one of these. */ - -debug_type -debug_make_void_type (handle) - PTR handle; -{ - struct debug_handle *info = (struct debug_handle *) handle; - - return debug_make_type (info, DEBUG_KIND_VOID, 0); -} - -/* Make an integer type of a given size. The boolean argument is true - if the integer is unsigned. */ - -debug_type -debug_make_int_type (handle, size, unsignedp) - PTR handle; - unsigned int size; - boolean unsignedp; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - - t = debug_make_type (info, DEBUG_KIND_INT, size); - if (t == NULL) - return DEBUG_TYPE_NULL; - - t->u.kint = unsignedp; - - return t; -} - -/* Make a floating point type of a given size. FIXME: On some - platforms, like an Alpha, you probably need to be able to specify - the format. */ - -debug_type -debug_make_float_type (handle, size) - PTR handle; - unsigned int size; -{ - struct debug_handle *info = (struct debug_handle *) handle; - - return debug_make_type (info, DEBUG_KIND_FLOAT, size); -} - -/* Make a boolean type of a given size. */ - -debug_type -debug_make_bool_type (handle, size) - PTR handle; - unsigned int size; -{ - struct debug_handle *info = (struct debug_handle *) handle; - - return debug_make_type (info, DEBUG_KIND_BOOL, size); -} - -/* Make a complex type of a given size. */ - -debug_type -debug_make_complex_type (handle, size) - PTR handle; - unsigned int size; -{ - struct debug_handle *info = (struct debug_handle *) handle; - - return debug_make_type (info, DEBUG_KIND_COMPLEX, size); -} - -/* Make a structure type. The second argument is true for a struct, - false for a union. The third argument is the size of the struct. - The fourth argument is a NULL terminated array of fields. */ - -debug_type -debug_make_struct_type (handle, structp, size, fields) - PTR handle; - boolean structp; - bfd_vma size; - debug_field *fields; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - struct debug_class_type *c; - - t = debug_make_type (info, - structp ? DEBUG_KIND_STRUCT : DEBUG_KIND_UNION, - size); - if (t == NULL) - return DEBUG_TYPE_NULL; - - c = (struct debug_class_type *) xmalloc (sizeof *c); - memset (c, 0, sizeof *c); - - c->fields = fields; - - t->u.kclass = c; - - return t; -} - -/* Make an object type. The first three arguments after the handle - are the same as for debug_make_struct_type. The next arguments are - a NULL terminated array of base classes, a NULL terminated array of - methods, the type of the object holding the virtual function table - if it is not this object, and a boolean which is true if this - object has its own virtual function table. */ - -debug_type -debug_make_object_type (handle, structp, size, fields, baseclasses, - methods, vptrbase, ownvptr) - PTR handle; - boolean structp; - bfd_vma size; - debug_field *fields; - debug_baseclass *baseclasses; - debug_method *methods; - debug_type vptrbase; - boolean ownvptr; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - struct debug_class_type *c; - - t = debug_make_type (info, - structp ? DEBUG_KIND_CLASS : DEBUG_KIND_UNION_CLASS, - size); - if (t == NULL) - return DEBUG_TYPE_NULL; - - c = (struct debug_class_type *) xmalloc (sizeof *c); - memset (c, 0, sizeof *c); - - c->fields = fields; - c->baseclasses = baseclasses; - c->methods = methods; - if (ownvptr) - c->vptrbase = t; - else - c->vptrbase = vptrbase; - - t->u.kclass = c; - - return t; -} - -/* Make an enumeration type. The arguments are a null terminated - array of strings, and an array of corresponding values. */ - -debug_type -debug_make_enum_type (handle, names, values) - PTR handle; - const char **names; - bfd_signed_vma *values; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - struct debug_enum_type *e; - - t = debug_make_type (info, DEBUG_KIND_ENUM, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - e = (struct debug_enum_type *) xmalloc (sizeof *e); - memset (e, 0, sizeof *e); - - e->names = names; - e->values = values; - - t->u.kenum = e; - - return t; -} - -/* Make a pointer to a given type. */ - -debug_type -debug_make_pointer_type (handle, type) - PTR handle; - debug_type type; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - - if (type == NULL) - return DEBUG_TYPE_NULL; - - if (type->pointer != DEBUG_TYPE_NULL) - return type->pointer; - - t = debug_make_type (info, DEBUG_KIND_POINTER, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - t->u.kpointer = type; - - type->pointer = t; - - return t; -} - -/* Make a function returning a given type. FIXME: We should be able - to record the parameter types. */ - -debug_type -debug_make_function_type (handle, type, arg_types, varargs) - PTR handle; - debug_type type; - debug_type *arg_types; - boolean varargs; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - struct debug_function_type *f; - - if (type == NULL) - return DEBUG_TYPE_NULL; - - t = debug_make_type (info, DEBUG_KIND_FUNCTION, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - f = (struct debug_function_type *) xmalloc (sizeof *f); - memset (f, 0, sizeof *f); - - f->return_type = type; - f->arg_types = arg_types; - f->varargs = varargs; - - t->u.kfunction = f; - - return t; -} - -/* Make a reference to a given type. */ - -debug_type -debug_make_reference_type (handle, type) - PTR handle; - debug_type type; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - - if (type == NULL) - return DEBUG_TYPE_NULL; - - t = debug_make_type (info, DEBUG_KIND_REFERENCE, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - t->u.kreference = type; - - return t; -} - -/* Make a range of a given type from a lower to an upper bound. */ - -debug_type -debug_make_range_type (handle, type, lower, upper) - PTR handle; - debug_type type; - bfd_signed_vma lower; - bfd_signed_vma upper; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - struct debug_range_type *r; - - if (type == NULL) - return DEBUG_TYPE_NULL; - - t = debug_make_type (info, DEBUG_KIND_RANGE, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - r = (struct debug_range_type *) xmalloc (sizeof *r); - memset (r, 0, sizeof *r); - - r->type = type; - r->lower = lower; - r->upper = upper; - - t->u.krange = r; - - return t; -} - -/* Make an array type. The second argument is the type of an element - of the array. The third argument is the type of a range of the - array. The fourth and fifth argument are the lower and upper - bounds, respectively. The sixth argument is true if this array is - actually a string, as in C. */ - -debug_type -debug_make_array_type (handle, element_type, range_type, lower, upper, - stringp) - PTR handle; - debug_type element_type; - debug_type range_type; - bfd_signed_vma lower; - bfd_signed_vma upper; - boolean stringp; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - struct debug_array_type *a; - - if (element_type == NULL || range_type == NULL) - return DEBUG_TYPE_NULL; - - t = debug_make_type (info, DEBUG_KIND_ARRAY, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - a = (struct debug_array_type *) xmalloc (sizeof *a); - memset (a, 0, sizeof *a); - - a->element_type = element_type; - a->range_type = range_type; - a->lower = lower; - a->upper = upper; - a->stringp = stringp; - - t->u.karray = a; - - return t; -} - -/* Make a set of a given type. For example, a Pascal set type. The - boolean argument is true if this set is actually a bitstring, as in - CHILL. */ - -debug_type -debug_make_set_type (handle, type, bitstringp) - PTR handle; - debug_type type; - boolean bitstringp; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - struct debug_set_type *s; - - if (type == NULL) - return DEBUG_TYPE_NULL; - - t = debug_make_type (info, DEBUG_KIND_SET, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - s = (struct debug_set_type *) xmalloc (sizeof *s); - memset (s, 0, sizeof *s); - - s->type = type; - s->bitstringp = bitstringp; - - t->u.kset = s; - - return t; -} - -/* Make a type for a pointer which is relative to an object. The - second argument is the type of the object to which the pointer is - relative. The third argument is the type that the pointer points - to. */ - -debug_type -debug_make_offset_type (handle, base_type, target_type) - PTR handle; - debug_type base_type; - debug_type target_type; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - struct debug_offset_type *o; - - if (base_type == NULL || target_type == NULL) - return DEBUG_TYPE_NULL; - - t = debug_make_type (info, DEBUG_KIND_OFFSET, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - o = (struct debug_offset_type *) xmalloc (sizeof *o); - memset (o, 0, sizeof *o); - - o->base_type = base_type; - o->target_type = target_type; - - t->u.koffset = o; - - return t; -} - -/* Make a type for a method function. The second argument is the - return type, the third argument is the domain, and the fourth - argument is a NULL terminated array of argument types. */ - -debug_type -debug_make_method_type (handle, return_type, domain_type, arg_types, varargs) - PTR handle; - debug_type return_type; - debug_type domain_type; - debug_type *arg_types; - boolean varargs; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - struct debug_method_type *m; - - if (return_type == NULL) - return DEBUG_TYPE_NULL; - - t = debug_make_type (info, DEBUG_KIND_METHOD, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - m = (struct debug_method_type *) xmalloc (sizeof *m); - memset (m, 0, sizeof *m); - - m->return_type = return_type; - m->domain_type = domain_type; - m->arg_types = arg_types; - m->varargs = varargs; - - t->u.kmethod = m; - - return t; -} - -/* Make a const qualified version of a given type. */ - -debug_type -debug_make_const_type (handle, type) - PTR handle; - debug_type type; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - - if (type == NULL) - return DEBUG_TYPE_NULL; - - t = debug_make_type (info, DEBUG_KIND_CONST, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - t->u.kconst = type; - - return t; -} - -/* Make a volatile qualified version of a given type. */ - -debug_type -debug_make_volatile_type (handle, type) - PTR handle; - debug_type type; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - - if (type == NULL) - return DEBUG_TYPE_NULL; - - t = debug_make_type (info, DEBUG_KIND_VOLATILE, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - t->u.kvolatile = type; - - return t; -} - -/* Make an undefined tagged type. For example, a struct which has - been mentioned, but not defined. */ - -debug_type -debug_make_undefined_tagged_type (handle, name, kind) - PTR handle; - const char *name; - enum debug_type_kind kind; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - - if (name == NULL) - return DEBUG_TYPE_NULL; - - switch (kind) - { - case DEBUG_KIND_STRUCT: - case DEBUG_KIND_UNION: - case DEBUG_KIND_CLASS: - case DEBUG_KIND_UNION_CLASS: - case DEBUG_KIND_ENUM: - break; - - default: - debug_error ("debug_make_undefined_type: unsupported kind"); - return DEBUG_TYPE_NULL; - } - - t = debug_make_type (info, kind, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - return debug_tag_type (handle, name, t); -} - -/* Make a base class for an object. The second argument is the base - class type. The third argument is the bit position of this base - class in the object (always 0 unless doing multiple inheritance). - The fourth argument is whether this is a virtual class. The fifth - argument is the visibility of the base class. */ - -/*ARGSUSED*/ -debug_baseclass -debug_make_baseclass (handle, type, bitpos, virtual, visibility) - PTR handle; - debug_type type; - bfd_vma bitpos; - boolean virtual; - enum debug_visibility visibility; -{ - struct debug_baseclass *b; - - b = (struct debug_baseclass *) xmalloc (sizeof *b); - memset (b, 0, sizeof *b); - - b->type = type; - b->bitpos = bitpos; - b->virtual = virtual; - b->visibility = visibility; - - return b; -} - -/* Make a field for a struct. The second argument is the name. The - third argument is the type of the field. The fourth argument is - the bit position of the field. The fifth argument is the size of - the field (it may be zero). The sixth argument is the visibility - of the field. */ - -/*ARGSUSED*/ -debug_field -debug_make_field (handle, name, type, bitpos, bitsize, visibility) - PTR handle; - const char *name; - debug_type type; - bfd_vma bitpos; - bfd_vma bitsize; - enum debug_visibility visibility; -{ - struct debug_field *f; - - f = (struct debug_field *) xmalloc (sizeof *f); - memset (f, 0, sizeof *f); - - f->name = name; - f->type = type; - f->static_member = false; - f->u.f.bitpos = bitpos; - f->u.f.bitsize = bitsize; - f->visibility = visibility; - - return f; -} - -/* Make a static member of an object. The second argument is the - name. The third argument is the type of the member. The fourth - argument is the physical name of the member (i.e., the name as a - global variable). The fifth argument is the visibility of the - member. */ - -/*ARGSUSED*/ -debug_field -debug_make_static_member (handle, name, type, physname, visibility) - PTR handle; - const char *name; - debug_type type; - const char *physname; - enum debug_visibility visibility; -{ - struct debug_field *f; - - f = (struct debug_field *) xmalloc (sizeof *f); - memset (f, 0, sizeof *f); - - f->name = name; - f->type = type; - f->static_member = true; - f->u.s.physname = physname; - f->visibility = visibility; - - return f; -} - -/* Make a method. The second argument is the name, and the third - argument is a NULL terminated array of method variants. */ - -/*ARGSUSED*/ -debug_method -debug_make_method (handle, name, variants) - PTR handle; - const char *name; - debug_method_variant *variants; -{ - struct debug_method *m; - - m = (struct debug_method *) xmalloc (sizeof *m); - memset (m, 0, sizeof *m); - - m->name = name; - m->variants = variants; - - return m; -} - -/* Make a method argument. The second argument is the real name of - the function. The third argument is the type of the function. The - fourth argument is the visibility. The fifth argument is whether - this is a const function. The sixth argument is whether this is a - volatile function. The seventh argument is the offset in the - virtual function table, if any. The eighth argument is the virtual - function context. FIXME: Are the const and volatile arguments - necessary? Could we just use debug_make_const_type? */ - -/*ARGSUSED*/ -debug_method_variant -debug_make_method_variant (handle, physname, type, visibility, constp, - volatilep, voffset, context) - PTR handle; - const char *physname; - debug_type type; - enum debug_visibility visibility; - boolean constp; - boolean volatilep; - bfd_vma voffset; - debug_type context; -{ - struct debug_method_variant *m; - - m = (struct debug_method_variant *) xmalloc (sizeof *m); - memset (m, 0, sizeof *m); - - m->physname = physname; - m->type = type; - m->visibility = visibility; - m->constp = constp; - m->volatilep = volatilep; - m->voffset = voffset; - m->context = context; - - return m; -} - -/* Make a static method argument. The arguments are the same as for - debug_make_method_variant, except that the last two are omitted - since a static method can not also be virtual. */ - -debug_method_variant -debug_make_static_method_variant (handle, physname, type, visibility, - constp, volatilep) - PTR handle; - const char *physname; - debug_type type; - enum debug_visibility visibility; - boolean constp; - boolean volatilep; -{ - struct debug_method_variant *m; - - m = (struct debug_method_variant *) xmalloc (sizeof *m); - memset (m, 0, sizeof *m); - - m->physname = physname; - m->type = type; - m->visibility = visibility; - m->constp = constp; - m->volatilep = volatilep; - m->voffset = VOFFSET_STATIC_METHOD; - - return m; -} - -/* Name a type. */ - -debug_type -debug_name_type (handle, name, type) - PTR handle; - const char *name; - debug_type type; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - struct debug_named_type *n; - struct debug_name *nm; - - if (name == NULL || type == NULL) - return DEBUG_TYPE_NULL; - - if (info->current_unit == NULL - || info->current_file == NULL) - { - debug_error ("debug_name_type: no current file"); - return DEBUG_TYPE_NULL; - /* return false; */ - } - - t = debug_make_type (info, DEBUG_KIND_NAMED, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - n = (struct debug_named_type *) xmalloc (sizeof *n); - memset (n, 0, sizeof *n); - - n->type = type; - - t->u.knamed = n; - - /* We always add the name to the global namespace. This is probably - wrong in some cases, but it seems to be right for stabs. FIXME. */ - - nm = debug_add_to_namespace (info, &info->current_file->globals, name, - DEBUG_OBJECT_TYPE, DEBUG_LINKAGE_NONE); - if (nm == NULL) - return DEBUG_TYPE_NULL; - - nm->u.type = t; - - n->name = nm; - - return t; -} - -/* Tag a type. */ - -debug_type -debug_tag_type (handle, name, type) - PTR handle; - const char *name; - debug_type type; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - struct debug_named_type *n; - struct debug_name *nm; - - if (name == NULL || type == NULL) - return DEBUG_TYPE_NULL; - - if (info->current_file == NULL) - { - debug_error ("debug_tag_type: no current file"); - return DEBUG_TYPE_NULL; - } - - if (type->kind == DEBUG_KIND_TAGGED) - { - if (strcmp (type->u.knamed->name->name, name) == 0) - return type; - debug_error ("debug_tag_type: extra tag attempted"); - return DEBUG_TYPE_NULL; - } - - t = debug_make_type (info, DEBUG_KIND_TAGGED, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - n = (struct debug_named_type *) xmalloc (sizeof *n); - memset (n, 0, sizeof *n); - - n->type = type; - - t->u.knamed = n; - - /* We keep a global namespace of tags for each compilation unit. I - don't know if that is the right thing to do. */ - - nm = debug_add_to_namespace (info, &info->current_file->globals, name, - DEBUG_OBJECT_TAG, DEBUG_LINKAGE_NONE); - if (nm == NULL) - return DEBUG_TYPE_NULL; - - nm->u.tag = t; - - n->name = nm; - - return t; -} - -/* Record the size of a given type. */ - -/*ARGSUSED*/ -boolean -debug_record_type_size (handle, type, size) - PTR handle; - debug_type type; - unsigned int size; -{ -#if 0 - if (type->size != 0 && type->size != size) - fprintf (stderr, "Warning: changing type size from %d to %d\n", - type->size, size); -#endif - - type->size = size; - - return true; -} - -/* Find a named type. */ - -debug_type -debug_find_named_type (handle, name) - PTR handle; - const char *name; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_block *b; - struct debug_file *f; - - /* We only search the current compilation unit. I don't know if - this is right or not. */ - - if (info->current_unit == NULL) - { - debug_error ("debug_find_named_type: no current compilation unit"); - return DEBUG_TYPE_NULL; - } - - for (b = info->current_block; b != NULL; b = b->parent) - { - if (b->locals != NULL) - { - struct debug_name *n; - - for (n = b->locals->list; n != NULL; n = n->next) - { - if (n->kind == DEBUG_OBJECT_TYPE - && n->name[0] == name[0] - && strcmp (n->name, name) == 0) - return n->u.type; - } - } - } - - for (f = info->current_unit->files; f != NULL; f = f->next) - { - if (f->globals != NULL) - { - struct debug_name *n; - - for (n = f->globals->list; n != NULL; n = n->next) - { - if (n->kind == DEBUG_OBJECT_TYPE - && n->name[0] == name[0] - && strcmp (n->name, name) == 0) - return n->u.type; - } - } - } - - return DEBUG_TYPE_NULL; -} - -/* Find a tagged type. */ - -debug_type -debug_find_tagged_type (handle, name, kind) - PTR handle; - const char *name; - enum debug_type_kind kind; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_unit *u; - - /* We search the globals of all the compilation units. I don't know - if this is correct or not. It would be easy to change. */ - - for (u = info->units; u != NULL; u = u->next) - { - struct debug_file *f; - - for (f = u->files; f != NULL; f = f->next) - { - struct debug_name *n; - - if (f->globals != NULL) - { - for (n = f->globals->list; n != NULL; n = n->next) - { - if (n->kind == DEBUG_OBJECT_TAG - && (kind == DEBUG_KIND_ILLEGAL - || n->u.tag->kind == kind) - && n->name[0] == name[0] - && strcmp (n->name, name) == 0) - return n->u.tag; - } - } - } - } - - return DEBUG_TYPE_NULL; -} - -/* Get a base type. */ - -static struct debug_type * -debug_get_real_type (handle, type) - PTR handle; - debug_type type; -{ - switch (type->kind) - { - default: - return type; - case DEBUG_KIND_INDIRECT: - if (*type->u.kindirect->slot != NULL) - return debug_get_real_type (handle, *type->u.kindirect->slot); - return type; - case DEBUG_KIND_NAMED: - case DEBUG_KIND_TAGGED: - return debug_get_real_type (handle, type->u.knamed->type); - } - /*NOTREACHED*/ -} - -/* Get the kind of a type. */ - -enum debug_type_kind -debug_get_type_kind (handle, type) - PTR handle; - debug_type type; -{ - if (type == NULL) - return DEBUG_KIND_ILLEGAL; - type = debug_get_real_type (handle, type); - return type->kind; -} - -/* Get the name of a type. */ - -const char * -debug_get_type_name (handle, type) - PTR handle; - debug_type type; -{ - if (type->kind == DEBUG_KIND_INDIRECT) - { - if (*type->u.kindirect->slot != NULL) - return debug_get_type_name (handle, *type->u.kindirect->slot); - return type->u.kindirect->tag; - } - if (type->kind == DEBUG_KIND_NAMED - || type->kind == DEBUG_KIND_TAGGED) - return type->u.knamed->name->name; - return NULL; -} - -/* Get the size of a type. */ - -bfd_vma -debug_get_type_size (handle, type) - PTR handle; - debug_type type; -{ - if (type == NULL) - return 0; - - /* We don't call debug_get_real_type, because somebody might have - called debug_record_type_size on a named or indirect type. */ - - if (type->size != 0) - return type->size; - - switch (type->kind) - { - default: - return 0; - case DEBUG_KIND_INDIRECT: - if (*type->u.kindirect->slot != NULL) - return debug_get_type_size (handle, *type->u.kindirect->slot); - return 0; - case DEBUG_KIND_NAMED: - case DEBUG_KIND_TAGGED: - return debug_get_type_size (handle, type->u.knamed->type); - } - /*NOTREACHED*/ -} - -/* Get the return type of a function or method type. */ - -debug_type -debug_get_return_type (handle, type) - PTR handle; - debug_type type; -{ - if (type == NULL) - return DEBUG_TYPE_NULL; - type = debug_get_real_type (handle, type); - switch (type->kind) - { - default: - return DEBUG_TYPE_NULL; - case DEBUG_KIND_FUNCTION: - return type->u.kfunction->return_type; - case DEBUG_KIND_METHOD: - return type->u.kmethod->return_type; - } - /*NOTREACHED*/ -} - -/* Get the parameter types of a function or method type (except that - we don't currently store the parameter types of a function). */ - -const debug_type * -debug_get_parameter_types (handle, type, pvarargs) - PTR handle; - debug_type type; - boolean *pvarargs; -{ - if (type == NULL) - return NULL; - type = debug_get_real_type (handle, type); - switch (type->kind) - { - default: - return NULL; - case DEBUG_KIND_FUNCTION: - *pvarargs = type->u.kfunction->varargs; - return type->u.kfunction->arg_types; - case DEBUG_KIND_METHOD: - *pvarargs = type->u.kmethod->varargs; - return type->u.kmethod->arg_types; - } - /*NOTREACHED*/ -} - -/* Get the target type of a type. */ - -debug_type -debug_get_target_type (handle, type) - PTR handle; - debug_type type; -{ - if (type == NULL) - return NULL; - type = debug_get_real_type (handle, type); - switch (type->kind) - { - default: - return NULL; - case DEBUG_KIND_POINTER: - return type->u.kpointer; - case DEBUG_KIND_REFERENCE: - return type->u.kreference; - case DEBUG_KIND_CONST: - return type->u.kconst; - case DEBUG_KIND_VOLATILE: - return type->u.kvolatile; - } - /*NOTREACHED*/ -} - -/* Get the NULL terminated array of fields for a struct, union, or - class. */ - -const debug_field * -debug_get_fields (handle, type) - PTR handle; - debug_type type; -{ - if (type == NULL) - return NULL; - type = debug_get_real_type (handle, type); - switch (type->kind) - { - default: - return NULL; - case DEBUG_KIND_STRUCT: - case DEBUG_KIND_UNION: - case DEBUG_KIND_CLASS: - case DEBUG_KIND_UNION_CLASS: - return type->u.kclass->fields; - } - /*NOTREACHED*/ -} - -/* Get the type of a field. */ - -/*ARGSUSED*/ -debug_type -debug_get_field_type (handle, field) - PTR handle; - debug_field field; -{ - if (field == NULL) - return NULL; - return field->type; -} - -/* Get the name of a field. */ - -/*ARGSUSED*/ -const char * -debug_get_field_name (handle, field) - PTR handle; - debug_field field; -{ - if (field == NULL) - return NULL; - return field->name; -} - -/* Get the bit position of a field. */ - -/*ARGSUSED*/ -bfd_vma -debug_get_field_bitpos (handle, field) - PTR handle; - debug_field field; -{ - if (field == NULL || field->static_member) - return (bfd_vma) -1; - return field->u.f.bitpos; -} - -/* Get the bit size of a field. */ - -/*ARGSUSED*/ -bfd_vma -debug_get_field_bitsize (handle, field) - PTR handle; - debug_field field; -{ - if (field == NULL || field->static_member) - return (bfd_vma) -1; - return field->u.f.bitsize; -} - -/* Get the visibility of a field. */ - -/*ARGSUSED*/ -enum debug_visibility -debug_get_field_visibility (handle, field) - PTR handle; - debug_field field; -{ - if (field == NULL) - return DEBUG_VISIBILITY_IGNORE; - return field->visibility; -} - -/* Get the physical name of a field. */ - -const char * -debug_get_field_physname (handle, field) - PTR handle; - debug_field field; -{ - if (field == NULL || ! field->static_member) - return NULL; - return field->u.s.physname; -} - -/* Write out the debugging information. This is given a handle to - debugging information, and a set of function pointers to call. */ - -boolean -debug_write (handle, fns, fhandle) - PTR handle; - const struct debug_write_fns *fns; - PTR fhandle; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_unit *u; - - /* We use a mark to tell whether we have already written out a - particular name. We use an integer, so that we don't have to - clear the mark fields if we happen to write out the same - information more than once. */ - ++info->mark; - - /* The base_id field holds an ID value which will never be used, so - that we can tell whether we have assigned an ID during this call - to debug_write. */ - info->base_id = info->class_id; - - /* We keep a linked list of classes for which was have assigned ID's - during this call to debug_write. */ - info->id_list = NULL; - - for (u = info->units; u != NULL; u = u->next) - { - struct debug_file *f; - boolean first_file; - - info->current_write_lineno = u->linenos; - info->current_write_lineno_index = 0; - - if (! (*fns->start_compilation_unit) (fhandle, u->files->filename)) - return false; - - first_file = true; - for (f = u->files; f != NULL; f = f->next) - { - struct debug_name *n; - - if (first_file) - first_file = false; - else - { - if (! (*fns->start_source) (fhandle, f->filename)) - return false; - } - - if (f->globals != NULL) - { - for (n = f->globals->list; n != NULL; n = n->next) - { - if (! debug_write_name (info, fns, fhandle, n)) - return false; - } - } - } - - /* Output any line number information which hasn't already been - handled. */ - if (! debug_write_linenos (info, fns, fhandle, (bfd_vma) -1)) - return false; - } - - return true; -} - -/* Write out an element in a namespace. */ - -static boolean -debug_write_name (info, fns, fhandle, n) - struct debug_handle *info; - const struct debug_write_fns *fns; - PTR fhandle; - struct debug_name *n; -{ - switch (n->kind) - { - case DEBUG_OBJECT_TYPE: - if (! debug_write_type (info, fns, fhandle, n->u.type, n) - || ! (*fns->typdef) (fhandle, n->name)) - return false; - return true; - case DEBUG_OBJECT_TAG: - if (! debug_write_type (info, fns, fhandle, n->u.tag, n)) - return false; - return (*fns->tag) (fhandle, n->name); - case DEBUG_OBJECT_VARIABLE: - if (! debug_write_type (info, fns, fhandle, n->u.variable->type, - (struct debug_name *) NULL)) - return false; - return (*fns->variable) (fhandle, n->name, n->u.variable->kind, - n->u.variable->val); - case DEBUG_OBJECT_FUNCTION: - return debug_write_function (info, fns, fhandle, n->name, - n->linkage, n->u.function); - case DEBUG_OBJECT_INT_CONSTANT: - return (*fns->int_constant) (fhandle, n->name, n->u.int_constant); - case DEBUG_OBJECT_FLOAT_CONSTANT: - return (*fns->float_constant) (fhandle, n->name, n->u.float_constant); - case DEBUG_OBJECT_TYPED_CONSTANT: - if (! debug_write_type (info, fns, fhandle, n->u.typed_constant->type, - (struct debug_name *) NULL)) - return false; - return (*fns->typed_constant) (fhandle, n->name, - n->u.typed_constant->val); - default: - abort (); - return false; - } - /*NOTREACHED*/ -} - -/* Write out a type. If the type is DEBUG_KIND_NAMED or - DEBUG_KIND_TAGGED, then the name argument is the name for which we - are about to call typedef or tag. If the type is anything else, - then the name argument is a tag from a DEBUG_KIND_TAGGED type which - points to this one. */ - -static boolean -debug_write_type (info, fns, fhandle, type, name) - struct debug_handle *info; - const struct debug_write_fns *fns; - PTR fhandle; - struct debug_type *type; - struct debug_name *name; -{ - unsigned int i; - int is; - const char *tag; - - /* If we have a name for this type, just output it. We only output - typedef names after they have been defined. We output type tags - whenever we are not actually defining them. */ - if ((type->kind == DEBUG_KIND_NAMED - || type->kind == DEBUG_KIND_TAGGED) - && (type->u.knamed->name->mark == info->mark - || (type->kind == DEBUG_KIND_TAGGED - && type->u.knamed->name != name))) - { - if (type->kind == DEBUG_KIND_NAMED) - return (*fns->typedef_type) (fhandle, type->u.knamed->name->name); - else - { - struct debug_type *real; - unsigned int id; - - real = debug_get_real_type ((PTR) info, type); - id = 0; - if ((real->kind == DEBUG_KIND_STRUCT - || real->kind == DEBUG_KIND_UNION - || real->kind == DEBUG_KIND_CLASS - || real->kind == DEBUG_KIND_UNION_CLASS) - && real->u.kclass != NULL) - { - if (real->u.kclass->id <= info->base_id) - { - if (! debug_set_class_id (info, - type->u.knamed->name->name, - real)) - return false; - } - id = real->u.kclass->id; - } - - return (*fns->tag_type) (fhandle, type->u.knamed->name->name, id, - real->kind); - } - } - - /* Mark the name after we have already looked for a known name, so - that we don't just define a type in terms of itself. We need to - mark the name here so that a struct containing a pointer to - itself will work. */ - if (name != NULL) - name->mark = info->mark; - - tag = NULL; - if (name != NULL - && type->kind != DEBUG_KIND_NAMED - && type->kind != DEBUG_KIND_TAGGED) - { - assert (name->kind == DEBUG_OBJECT_TAG); - tag = name->name; - } - - switch (type->kind) - { - case DEBUG_KIND_ILLEGAL: - debug_error ("debug_write_type: illegal type encountered"); - return false; - case DEBUG_KIND_INDIRECT: - if (*type->u.kindirect->slot == DEBUG_TYPE_NULL) - return (*fns->empty_type) (fhandle); - return debug_write_type (info, fns, fhandle, *type->u.kindirect->slot, - name); - case DEBUG_KIND_VOID: - return (*fns->void_type) (fhandle); - case DEBUG_KIND_INT: - return (*fns->int_type) (fhandle, type->size, type->u.kint); - case DEBUG_KIND_FLOAT: - return (*fns->float_type) (fhandle, type->size); - case DEBUG_KIND_COMPLEX: - return (*fns->complex_type) (fhandle, type->size); - case DEBUG_KIND_BOOL: - return (*fns->bool_type) (fhandle, type->size); - case DEBUG_KIND_STRUCT: - case DEBUG_KIND_UNION: - if (type->u.kclass != NULL) - { - if (type->u.kclass->id <= info->base_id) - { - if (! debug_set_class_id (info, tag, type)) - return false; - } - - if (info->mark == type->u.kclass->mark) - { - /* We are currently outputting this struct, or we have - already output it. I don't know if this can happen, - but it can happen for a class. */ - assert (type->u.kclass->id > info->base_id); - return (*fns->tag_type) (fhandle, tag, type->u.kclass->id, - type->kind); - } - type->u.kclass->mark = info->mark; - } - - if (! (*fns->start_struct_type) (fhandle, tag, - (type->u.kclass != NULL - ? type->u.kclass->id - : 0), - type->kind == DEBUG_KIND_STRUCT, - type->size)) - return false; - if (type->u.kclass != NULL - && type->u.kclass->fields != NULL) - { - for (i = 0; type->u.kclass->fields[i] != NULL; i++) - { - struct debug_field *f; - - f = type->u.kclass->fields[i]; - if (! debug_write_type (info, fns, fhandle, f->type, - (struct debug_name *) NULL) - || ! (*fns->struct_field) (fhandle, f->name, f->u.f.bitpos, - f->u.f.bitsize, f->visibility)) - return false; - } - } - return (*fns->end_struct_type) (fhandle); - case DEBUG_KIND_CLASS: - case DEBUG_KIND_UNION_CLASS: - return debug_write_class_type (info, fns, fhandle, type, tag); - case DEBUG_KIND_ENUM: - if (type->u.kenum == NULL) - return (*fns->enum_type) (fhandle, tag, (const char **) NULL, - (bfd_signed_vma *) NULL); - return (*fns->enum_type) (fhandle, tag, type->u.kenum->names, - type->u.kenum->values); - case DEBUG_KIND_POINTER: - if (! debug_write_type (info, fns, fhandle, type->u.kpointer, - (struct debug_name *) NULL)) - return false; - return (*fns->pointer_type) (fhandle); - case DEBUG_KIND_FUNCTION: - if (! debug_write_type (info, fns, fhandle, - type->u.kfunction->return_type, - (struct debug_name *) NULL)) - return false; - if (type->u.kfunction->arg_types == NULL) - is = -1; - else - { - for (is = 0; type->u.kfunction->arg_types[is] != NULL; is++) - if (! debug_write_type (info, fns, fhandle, - type->u.kfunction->arg_types[is], - (struct debug_name *) NULL)) - return false; - } - return (*fns->function_type) (fhandle, is, - type->u.kfunction->varargs); - case DEBUG_KIND_REFERENCE: - if (! debug_write_type (info, fns, fhandle, type->u.kreference, - (struct debug_name *) NULL)) - return false; - return (*fns->reference_type) (fhandle); - case DEBUG_KIND_RANGE: - if (! debug_write_type (info, fns, fhandle, type->u.krange->type, - (struct debug_name *) NULL)) - return false; - return (*fns->range_type) (fhandle, type->u.krange->lower, - type->u.krange->upper); - case DEBUG_KIND_ARRAY: - if (! debug_write_type (info, fns, fhandle, type->u.karray->element_type, - (struct debug_name *) NULL) - || ! debug_write_type (info, fns, fhandle, - type->u.karray->range_type, - (struct debug_name *) NULL)) - return false; - return (*fns->array_type) (fhandle, type->u.karray->lower, - type->u.karray->upper, - type->u.karray->stringp); - case DEBUG_KIND_SET: - if (! debug_write_type (info, fns, fhandle, type->u.kset->type, - (struct debug_name *) NULL)) - return false; - return (*fns->set_type) (fhandle, type->u.kset->bitstringp); - case DEBUG_KIND_OFFSET: - if (! debug_write_type (info, fns, fhandle, type->u.koffset->base_type, - (struct debug_name *) NULL) - || ! debug_write_type (info, fns, fhandle, - type->u.koffset->target_type, - (struct debug_name *) NULL)) - return false; - return (*fns->offset_type) (fhandle); - case DEBUG_KIND_METHOD: - if (! debug_write_type (info, fns, fhandle, - type->u.kmethod->return_type, - (struct debug_name *) NULL)) - return false; - if (type->u.kmethod->arg_types == NULL) - is = -1; - else - { - for (is = 0; type->u.kmethod->arg_types[is] != NULL; is++) - if (! debug_write_type (info, fns, fhandle, - type->u.kmethod->arg_types[is], - (struct debug_name *) NULL)) - return false; - } - if (type->u.kmethod->domain_type != NULL) - { - if (! debug_write_type (info, fns, fhandle, - type->u.kmethod->domain_type, - (struct debug_name *) NULL)) - return false; - } - return (*fns->method_type) (fhandle, - type->u.kmethod->domain_type != NULL, - is, - type->u.kmethod->varargs); - case DEBUG_KIND_CONST: - if (! debug_write_type (info, fns, fhandle, type->u.kconst, - (struct debug_name *) NULL)) - return false; - return (*fns->const_type) (fhandle); - case DEBUG_KIND_VOLATILE: - if (! debug_write_type (info, fns, fhandle, type->u.kvolatile, - (struct debug_name *) NULL)) - return false; - return (*fns->volatile_type) (fhandle); - case DEBUG_KIND_NAMED: - return debug_write_type (info, fns, fhandle, type->u.knamed->type, - (struct debug_name *) NULL); - case DEBUG_KIND_TAGGED: - return debug_write_type (info, fns, fhandle, type->u.knamed->type, - type->u.knamed->name); - default: - abort (); - return false; - } -} - -/* Write out a class type. */ - -static boolean -debug_write_class_type (info, fns, fhandle, type, tag) - struct debug_handle *info; - const struct debug_write_fns *fns; - PTR fhandle; - struct debug_type *type; - const char *tag; -{ - unsigned int i; - unsigned int id; - struct debug_type *vptrbase; - - if (type->u.kclass == NULL) - { - id = 0; - vptrbase = NULL; - } - else - { - if (type->u.kclass->id <= info->base_id) - { - if (! debug_set_class_id (info, tag, type)) - return false; - } - - if (info->mark == type->u.kclass->mark) - { - /* We are currently outputting this class, or we have - already output it. This can happen when there are - methods for an anonymous class. */ - assert (type->u.kclass->id > info->base_id); - return (*fns->tag_type) (fhandle, tag, type->u.kclass->id, - type->kind); - } - type->u.kclass->mark = info->mark; - id = type->u.kclass->id; - - vptrbase = type->u.kclass->vptrbase; - if (vptrbase != NULL && vptrbase != type) - { - if (! debug_write_type (info, fns, fhandle, vptrbase, - (struct debug_name *) NULL)) - return false; - } - } - - if (! (*fns->start_class_type) (fhandle, tag, id, - type->kind == DEBUG_KIND_CLASS, - type->size, - vptrbase != NULL, - vptrbase == type)) - return false; - - if (type->u.kclass != NULL) - { - if (type->u.kclass->fields != NULL) - { - for (i = 0; type->u.kclass->fields[i] != NULL; i++) - { - struct debug_field *f; - - f = type->u.kclass->fields[i]; - if (! debug_write_type (info, fns, fhandle, f->type, - (struct debug_name *) NULL)) - return false; - if (f->static_member) - { - if (! (*fns->class_static_member) (fhandle, f->name, - f->u.s.physname, - f->visibility)) - return false; - } - else - { - if (! (*fns->struct_field) (fhandle, f->name, f->u.f.bitpos, - f->u.f.bitsize, f->visibility)) - return false; - } - } - } - - if (type->u.kclass->baseclasses != NULL) - { - for (i = 0; type->u.kclass->baseclasses[i] != NULL; i++) - { - struct debug_baseclass *b; - - b = type->u.kclass->baseclasses[i]; - if (! debug_write_type (info, fns, fhandle, b->type, - (struct debug_name *) NULL)) - return false; - if (! (*fns->class_baseclass) (fhandle, b->bitpos, b->virtual, - b->visibility)) - return false; - } - } - - if (type->u.kclass->methods != NULL) - { - for (i = 0; type->u.kclass->methods[i] != NULL; i++) - { - struct debug_method *m; - unsigned int j; - - m = type->u.kclass->methods[i]; - if (! (*fns->class_start_method) (fhandle, m->name)) - return false; - for (j = 0; m->variants[j] != NULL; j++) - { - struct debug_method_variant *v; - - v = m->variants[j]; - if (v->context != NULL) - { - if (! debug_write_type (info, fns, fhandle, v->context, - (struct debug_name *) NULL)) - return false; - } - if (! debug_write_type (info, fns, fhandle, v->type, - (struct debug_name *) NULL)) - return false; - if (v->voffset != VOFFSET_STATIC_METHOD) - { - if (! (*fns->class_method_variant) (fhandle, v->physname, - v->visibility, - v->constp, - v->volatilep, - v->voffset, - v->context != NULL)) - return false; - } - else - { - if (! (*fns->class_static_method_variant) (fhandle, - v->physname, - v->visibility, - v->constp, - v->volatilep)) - return false; - } - } - if (! (*fns->class_end_method) (fhandle)) - return false; - } - } - } - - return (*fns->end_class_type) (fhandle); -} - -/* Write out information for a function. */ - -static boolean -debug_write_function (info, fns, fhandle, name, linkage, function) - struct debug_handle *info; - const struct debug_write_fns *fns; - PTR fhandle; - const char *name; - enum debug_object_linkage linkage; - struct debug_function *function; -{ - struct debug_parameter *p; - struct debug_block *b; - - if (! debug_write_linenos (info, fns, fhandle, function->blocks->start)) - return false; - - if (! debug_write_type (info, fns, fhandle, function->return_type, - (struct debug_name *) NULL)) - return false; - - if (! (*fns->start_function) (fhandle, name, - linkage == DEBUG_LINKAGE_GLOBAL)) - return false; - - for (p = function->parameters; p != NULL; p = p->next) - { - if (! debug_write_type (info, fns, fhandle, p->type, - (struct debug_name *) NULL) - || ! (*fns->function_parameter) (fhandle, p->name, p->kind, p->val)) - return false; - } - - for (b = function->blocks; b != NULL; b = b->next) - { - if (! debug_write_block (info, fns, fhandle, b)) - return false; - } - - return (*fns->end_function) (fhandle); -} - -/* Write out information for a block. */ - -static boolean -debug_write_block (info, fns, fhandle, block) - struct debug_handle *info; - const struct debug_write_fns *fns; - PTR fhandle; - struct debug_block *block; -{ - struct debug_name *n; - struct debug_block *b; - - if (! debug_write_linenos (info, fns, fhandle, block->start)) - return false; - - /* I can't see any point to writing out a block with no local - variables, so we don't bother, except for the top level block. */ - if (block->locals != NULL || block->parent == NULL) - { - if (! (*fns->start_block) (fhandle, block->start)) - return false; - } - - if (block->locals != NULL) - { - for (n = block->locals->list; n != NULL; n = n->next) - { - if (! debug_write_name (info, fns, fhandle, n)) - return false; - } - } - - for (b = block->children; b != NULL; b = b->next) - { - if (! debug_write_block (info, fns, fhandle, b)) - return false; - } - - if (! debug_write_linenos (info, fns, fhandle, block->end)) - return false; - - if (block->locals != NULL || block->parent == NULL) - { - if (! (*fns->end_block) (fhandle, block->end)) - return false; - } - - return true; -} - -/* Write out line number information up to ADDRESS. */ - -static boolean -debug_write_linenos (info, fns, fhandle, address) - struct debug_handle *info; - const struct debug_write_fns *fns; - PTR fhandle; - bfd_vma address; -{ - while (info->current_write_lineno != NULL) - { - struct debug_lineno *l; - - l = info->current_write_lineno; - - while (info->current_write_lineno_index < DEBUG_LINENO_COUNT) - { - if (l->linenos[info->current_write_lineno_index] - == (unsigned long) -1) - break; - - if (l->addrs[info->current_write_lineno_index] >= address) - return true; - - if (! (*fns->lineno) (fhandle, l->file->filename, - l->linenos[info->current_write_lineno_index], - l->addrs[info->current_write_lineno_index])) - return false; - - ++info->current_write_lineno_index; - } - - info->current_write_lineno = l->next; - info->current_write_lineno_index = 0; - } - - return true; -} - -/* Get the ID number for a class. If during the same call to - debug_write we find a struct with the same definition with the same - name, we use the same ID. This type of things happens because the - same struct will be defined by multiple compilation units. */ - -static boolean -debug_set_class_id (info, tag, type) - struct debug_handle *info; - const char *tag; - struct debug_type *type; -{ - struct debug_class_type *c; - struct debug_class_id *l; - - assert (type->kind == DEBUG_KIND_STRUCT - || type->kind == DEBUG_KIND_UNION - || type->kind == DEBUG_KIND_CLASS - || type->kind == DEBUG_KIND_UNION_CLASS); - - c = type->u.kclass; - - if (c->id > info->base_id) - return true; - - for (l = info->id_list; l != NULL; l = l->next) - { - if (l->type->kind != type->kind) - continue; - - if (tag == NULL) - { - if (l->tag != NULL) - continue; - } - else - { - if (l->tag == NULL - || l->tag[0] != tag[0] - || strcmp (l->tag, tag) != 0) - continue; - } - - if (debug_type_samep (info, l->type, type)) - { - c->id = l->type->u.kclass->id; - return true; - } - } - - /* There are no identical types. Use a new ID, and add it to the - list. */ - ++info->class_id; - c->id = info->class_id; - - l = (struct debug_class_id *) xmalloc (sizeof *l); - memset (l, 0, sizeof *l); - - l->type = type; - l->tag = tag; - - l->next = info->id_list; - info->id_list = l; - - return true; -} - -/* See if two types are the same. At this point, we don't care about - tags and the like. */ - -static boolean -debug_type_samep (info, t1, t2) - struct debug_handle *info; - struct debug_type *t1; - struct debug_type *t2; -{ - struct debug_type_compare_list *l; - struct debug_type_compare_list top; - boolean ret; - - if (t1 == NULL) - return t2 == NULL; - if (t2 == NULL) - return false; - - while (t1->kind == DEBUG_KIND_INDIRECT) - { - t1 = *t1->u.kindirect->slot; - if (t1 == NULL) - return false; - } - while (t2->kind == DEBUG_KIND_INDIRECT) - { - t2 = *t2->u.kindirect->slot; - if (t2 == NULL) - return false; - } - - if (t1 == t2) - return true; - - /* As a special case, permit a typedef to match a tag, since C++ - debugging output will sometimes add a typedef where C debugging - output will not. */ - if (t1->kind == DEBUG_KIND_NAMED - && t2->kind == DEBUG_KIND_TAGGED) - return debug_type_samep (info, t1->u.knamed->type, t2); - else if (t1->kind == DEBUG_KIND_TAGGED - && t2->kind == DEBUG_KIND_NAMED) - return debug_type_samep (info, t1, t2->u.knamed->type); - - if (t1->kind != t2->kind - || t1->size != t2->size) - return false; - - /* Get rid of the trivial cases first. */ - switch (t1->kind) - { - default: - break; - case DEBUG_KIND_VOID: - case DEBUG_KIND_FLOAT: - case DEBUG_KIND_COMPLEX: - case DEBUG_KIND_BOOL: - return true; - case DEBUG_KIND_INT: - return t1->u.kint == t2->u.kint; - } - - /* We have to avoid an infinite recursion. We do this by keeping a - list of types which we are comparing. We just keep the list on - the stack. If we encounter a pair of types we are currently - comparing, we just assume that they are equal. */ - for (l = info->compare_list; l != NULL; l = l->next) - { - if (l->t1 == t1 && l->t2 == t2) - return true; - } - - top.t1 = t1; - top.t2 = t2; - top.next = info->compare_list; - info->compare_list = ⊤ - - switch (t1->kind) - { - default: - abort (); - ret = false; - break; - - case DEBUG_KIND_STRUCT: - case DEBUG_KIND_UNION: - case DEBUG_KIND_CLASS: - case DEBUG_KIND_UNION_CLASS: - if (t1->u.kclass == NULL) - ret = t2->u.kclass == NULL; - else if (t2->u.kclass == NULL) - ret = false; - else if (t1->u.kclass->id > info->base_id - && t1->u.kclass->id == t2->u.kclass->id) - ret = true; - else - ret = debug_class_type_samep (info, t1, t2); - break; - - case DEBUG_KIND_ENUM: - if (t1->u.kenum == NULL) - ret = t2->u.kenum == NULL; - else if (t2->u.kenum == NULL) - ret = false; - else - { - const char **pn1, **pn2; - bfd_signed_vma *pv1, *pv2; - - pn1 = t1->u.kenum->names; - pn2 = t2->u.kenum->names; - pv1 = t1->u.kenum->values; - pv2 = t2->u.kenum->values; - while (*pn1 != NULL && *pn2 != NULL) - { - if (**pn1 != **pn2 - || *pv1 != *pv2 - || strcmp (*pn1, *pn2) != 0) - break; - ++pn1; - ++pn2; - ++pv1; - ++pv2; - } - ret = *pn1 == NULL && *pn2 == NULL; - } - break; - - case DEBUG_KIND_POINTER: - ret = debug_type_samep (info, t1->u.kpointer, t2->u.kpointer); - break; - - case DEBUG_KIND_FUNCTION: - if (t1->u.kfunction->varargs != t2->u.kfunction->varargs - || ! debug_type_samep (info, t1->u.kfunction->return_type, - t2->u.kfunction->return_type) - || ((t1->u.kfunction->arg_types == NULL) - != (t2->u.kfunction->arg_types == NULL))) - ret = false; - else if (t1->u.kfunction->arg_types == NULL) - ret = true; - else - { - struct debug_type **a1, **a2; - - a1 = t1->u.kfunction->arg_types; - a2 = t2->u.kfunction->arg_types; - while (*a1 != NULL && *a2 != NULL) - if (! debug_type_samep (info, *a1, *a2)) - break; - ret = *a1 == NULL && *a2 == NULL; - } - break; - - case DEBUG_KIND_REFERENCE: - ret = debug_type_samep (info, t1->u.kreference, t2->u.kreference); - break; - - case DEBUG_KIND_RANGE: - ret = (t1->u.krange->lower == t2->u.krange->lower - && t1->u.krange->upper == t2->u.krange->upper - && debug_type_samep (info, t1->u.krange->type, - t2->u.krange->type)); - - case DEBUG_KIND_ARRAY: - ret = (t1->u.karray->lower == t2->u.karray->lower - && t1->u.karray->upper == t2->u.karray->upper - && t1->u.karray->stringp == t2->u.karray->stringp - && debug_type_samep (info, t1->u.karray->element_type, - t2->u.karray->element_type)); - break; - - case DEBUG_KIND_SET: - ret = (t1->u.kset->bitstringp == t2->u.kset->bitstringp - && debug_type_samep (info, t1->u.kset->type, t2->u.kset->type)); - break; - - case DEBUG_KIND_OFFSET: - ret = (debug_type_samep (info, t1->u.koffset->base_type, - t2->u.koffset->base_type) - && debug_type_samep (info, t1->u.koffset->target_type, - t2->u.koffset->target_type)); - break; - - case DEBUG_KIND_METHOD: - if (t1->u.kmethod->varargs != t2->u.kmethod->varargs - || ! debug_type_samep (info, t1->u.kmethod->return_type, - t2->u.kmethod->return_type) - || ! debug_type_samep (info, t1->u.kmethod->domain_type, - t2->u.kmethod->domain_type) - || ((t1->u.kmethod->arg_types == NULL) - != (t2->u.kmethod->arg_types == NULL))) - ret = false; - else if (t1->u.kmethod->arg_types == NULL) - ret = true; - else - { - struct debug_type **a1, **a2; - - a1 = t1->u.kmethod->arg_types; - a2 = t2->u.kmethod->arg_types; - while (*a1 != NULL && *a2 != NULL) - if (! debug_type_samep (info, *a1, *a2)) - break; - ret = *a1 == NULL && *a2 == NULL; - } - break; - - case DEBUG_KIND_CONST: - ret = debug_type_samep (info, t1->u.kconst, t2->u.kconst); - break; - - case DEBUG_KIND_VOLATILE: - ret = debug_type_samep (info, t1->u.kvolatile, t2->u.kvolatile); - break; - - case DEBUG_KIND_NAMED: - case DEBUG_KIND_TAGGED: - ret = (strcmp (t1->u.knamed->name->name, t2->u.knamed->name->name) == 0 - && debug_type_samep (info, t1->u.knamed->type, - t2->u.knamed->type)); - break; - } - - info->compare_list = top.next; - - return ret; -} - -/* See if two classes are the same. This is a subroutine of - debug_type_samep. */ - -static boolean -debug_class_type_samep (info, t1, t2) - struct debug_handle *info; - struct debug_type *t1; - struct debug_type *t2; -{ - struct debug_class_type *c1, *c2; - - c1 = t1->u.kclass; - c2 = t2->u.kclass; - - if ((c1->fields == NULL) != (c2->fields == NULL) - || (c1->baseclasses == NULL) != (c2->baseclasses == NULL) - || (c1->methods == NULL) != (c2->methods == NULL) - || (c1->vptrbase == NULL) != (c2->vptrbase == NULL)) - return false; - - if (c1->fields != NULL) - { - struct debug_field **pf1, **pf2; - - for (pf1 = c1->fields, pf2 = c2->fields; - *pf1 != NULL && *pf2 != NULL; - pf1++, pf2++) - { - struct debug_field *f1, *f2; - - f1 = *pf1; - f2 = *pf2; - if (f1->name[0] != f2->name[0] - || f1->visibility != f2->visibility - || f1->static_member != f2->static_member) - return false; - if (f1->static_member) - { - if (strcmp (f1->u.s.physname, f2->u.s.physname) != 0) - return false; - } - else - { - if (f1->u.f.bitpos != f2->u.f.bitpos - || f1->u.f.bitsize != f2->u.f.bitsize) - return false; - } - /* We do the checks which require function calls last. We - don't require that the types of fields have the same - names, since that sometimes fails in the presence of - typedefs and we really don't care. */ - if (strcmp (f1->name, f2->name) != 0 - || ! debug_type_samep (info, - debug_get_real_type ((PTR) info, - f1->type), - debug_get_real_type ((PTR) info, - f2->type))) - return false; - } - if (*pf1 != NULL || *pf2 != NULL) - return false; - } - - if (c1->vptrbase != NULL) - { - if (! debug_type_samep (info, c1->vptrbase, c2->vptrbase)) - return false; - } - - if (c1->baseclasses != NULL) - { - struct debug_baseclass **pb1, **pb2; - - for (pb1 = c1->baseclasses, pb2 = c2->baseclasses; - *pb1 != NULL && *pb2 != NULL; - ++pb1, ++pb2) - { - struct debug_baseclass *b1, *b2; - - b1 = *pb1; - b2 = *pb2; - if (b1->bitpos != b2->bitpos - || b1->virtual != b2->virtual - || b1->visibility != b2->visibility - || ! debug_type_samep (info, b1->type, b2->type)) - return false; - } - if (*pb1 != NULL || *pb2 != NULL) - return false; - } - - if (c1->methods != NULL) - { - struct debug_method **pm1, **pm2; - - for (pm1 = c1->methods, pm2 = c2->methods; - *pm1 != NULL && *pm2 != NULL; - ++pm1, ++pm2) - { - struct debug_method *m1, *m2; - - m1 = *pm1; - m2 = *pm2; - if (m1->name[0] != m2->name[0] - || strcmp (m1->name, m2->name) != 0 - || (m1->variants == NULL) != (m2->variants == NULL)) - return false; - if (m1->variants == NULL) - { - struct debug_method_variant **pv1, **pv2; - - for (pv1 = m1->variants, pv2 = m2->variants; - *pv1 != NULL && *pv2 != NULL; - ++pv1, ++pv2) - { - struct debug_method_variant *v1, *v2; - - v1 = *pv1; - v2 = *pv2; - if (v1->physname[0] != v2->physname[0] - || v1->visibility != v2->visibility - || v1->constp != v2->constp - || v1->volatilep != v2->volatilep - || v1->voffset != v2->voffset - || (v1->context == NULL) != (v2->context == NULL) - || strcmp (v1->physname, v2->physname) != 0 - || ! debug_type_samep (info, v1->type, v2->type)) - return false; - if (v1->context != NULL) - { - if (! debug_type_samep (info, v1->context, - v2->context)) - return false; - } - } - if (*pv1 != NULL || *pv2 != NULL) - return false; - } - } - if (*pm1 != NULL || *pm2 != NULL) - return false; - } - - return true; -} diff --git a/pstack/debug.h b/pstack/debug.h deleted file mode 100644 index a4d3d8306cd..00000000000 --- a/pstack/debug.h +++ /dev/null @@ -1,798 +0,0 @@ -/* debug.h -- Describe generic debugging information. - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - Written by Ian Lance Taylor . - - This file is part of GNU Binutils. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -#ifndef DEBUG_H -#define DEBUG_H - -/* This header file describes a generic debugging information format. - We may eventually have readers which convert different formats into - this generic format, and writers which write it out. The initial - impetus for this was writing a convertor from stabs to HP IEEE-695 - debugging format. */ - -/* Different kinds of types. */ - -enum debug_type_kind -{ - /* Not used. */ - DEBUG_KIND_ILLEGAL, - /* Indirect via a pointer. */ - DEBUG_KIND_INDIRECT, - /* Void. */ - DEBUG_KIND_VOID, - /* Integer. */ - DEBUG_KIND_INT, - /* Floating point. */ - DEBUG_KIND_FLOAT, - /* Complex. */ - DEBUG_KIND_COMPLEX, - /* Boolean. */ - DEBUG_KIND_BOOL, - /* Struct. */ - DEBUG_KIND_STRUCT, - /* Union. */ - DEBUG_KIND_UNION, - /* Class. */ - DEBUG_KIND_CLASS, - /* Union class (can this really happen?). */ - DEBUG_KIND_UNION_CLASS, - /* Enumeration type. */ - DEBUG_KIND_ENUM, - /* Pointer. */ - DEBUG_KIND_POINTER, - /* Function. */ - DEBUG_KIND_FUNCTION, - /* Reference. */ - DEBUG_KIND_REFERENCE, - /* Range. */ - DEBUG_KIND_RANGE, - /* Array. */ - DEBUG_KIND_ARRAY, - /* Set. */ - DEBUG_KIND_SET, - /* Based pointer. */ - DEBUG_KIND_OFFSET, - /* Method. */ - DEBUG_KIND_METHOD, - /* Const qualified type. */ - DEBUG_KIND_CONST, - /* Volatile qualified type. */ - DEBUG_KIND_VOLATILE, - /* Named type. */ - DEBUG_KIND_NAMED, - /* Tagged type. */ - DEBUG_KIND_TAGGED -}; - -/* Different kinds of variables. */ - -enum debug_var_kind -{ - /* Not used. */ - DEBUG_VAR_ILLEGAL, - /* A global variable. */ - DEBUG_GLOBAL, - /* A static variable. */ - DEBUG_STATIC, - /* A local static variable. */ - DEBUG_LOCAL_STATIC, - /* A local variable. */ - DEBUG_LOCAL, - /* A register variable. */ - DEBUG_REGISTER -}; - -/* Different kinds of function parameters. */ - -enum debug_parm_kind -{ - /* Not used. */ - DEBUG_PARM_ILLEGAL, - /* A stack based parameter. */ - DEBUG_PARM_STACK, - /* A register parameter. */ - DEBUG_PARM_REG, - /* A stack based reference parameter. */ - DEBUG_PARM_REFERENCE, - /* A register reference parameter. */ - DEBUG_PARM_REF_REG -}; - -/* Different kinds of visibility. */ - -enum debug_visibility -{ - /* A public field (e.g., a field in a C struct). */ - DEBUG_VISIBILITY_PUBLIC, - /* A protected field. */ - DEBUG_VISIBILITY_PROTECTED, - /* A private field. */ - DEBUG_VISIBILITY_PRIVATE, - /* A field which should be ignored. */ - DEBUG_VISIBILITY_IGNORE -}; - -/* A type. */ - -typedef struct debug_type *debug_type; - -#define DEBUG_TYPE_NULL ((debug_type) NULL) - -/* A field in a struct or union. */ - -typedef struct debug_field *debug_field; - -#define DEBUG_FIELD_NULL ((debug_field) NULL) - -/* A base class for an object. */ - -typedef struct debug_baseclass *debug_baseclass; - -#define DEBUG_BASECLASS_NULL ((debug_baseclass) NULL) - -/* A method of an object. */ - -typedef struct debug_method *debug_method; - -#define DEBUG_METHOD_NULL ((debug_method) NULL) - -/* The arguments to a method function of an object. These indicate - which method to run. */ - -typedef struct debug_method_variant *debug_method_variant; - -#define DEBUG_METHOD_VARIANT_NULL ((debug_method_variant) NULL) - -/* This structure is passed to debug_write. It holds function - pointers that debug_write will call based on the accumulated - debugging information. */ - -struct debug_write_fns -{ - /* This is called at the start of each new compilation unit with the - name of the main file in the new unit. */ - boolean (*start_compilation_unit) PARAMS ((PTR, const char *)); - - /* This is called at the start of each source file within a - compilation unit, before outputting any global information for - that file. The argument is the name of the file. */ - boolean (*start_source) PARAMS ((PTR, const char *)); - - /* Each writer must keep a stack of types. */ - - /* Push an empty type onto the type stack. This type can appear if - there is a reference to a type which is never defined. */ - boolean (*empty_type) PARAMS ((PTR)); - - /* Push a void type onto the type stack. */ - boolean (*void_type) PARAMS ((PTR)); - - /* Push an integer type onto the type stack, given the size and - whether it is unsigned. */ - boolean (*int_type) PARAMS ((PTR, unsigned int, boolean)); - - /* Push a floating type onto the type stack, given the size. */ - boolean (*float_type) PARAMS ((PTR, unsigned int)); - - /* Push a complex type onto the type stack, given the size. */ - boolean (*complex_type) PARAMS ((PTR, unsigned int)); - - /* Push a boolean type onto the type stack, given the size. */ - boolean (*bool_type) PARAMS ((PTR, unsigned int)); - - /* Push an enum type onto the type stack, given the tag, a NULL - terminated array of names and the associated values. If there is - no tag, the tag argument will be NULL. If this is an undefined - enum, the names and values arguments will be NULL. */ - boolean (*enum_type) PARAMS ((PTR, const char *, const char **, - bfd_signed_vma *)); - - /* Pop the top type on the type stack, and push a pointer to that - type onto the type stack. */ - boolean (*pointer_type) PARAMS ((PTR)); - - /* Push a function type onto the type stack. The second argument - indicates the number of argument types that have been pushed onto - the stack. If the number of argument types is passed as -1, then - the argument types of the function are unknown, and no types have - been pushed onto the stack. The third argument is true if the - function takes a variable number of arguments. The return type - of the function is pushed onto the type stack below the argument - types, if any. */ - boolean (*function_type) PARAMS ((PTR, int, boolean)); - - /* Pop the top type on the type stack, and push a reference to that - type onto the type stack. */ - boolean (*reference_type) PARAMS ((PTR)); - - /* Pop the top type on the type stack, and push a range of that type - with the given lower and upper bounds onto the type stack. */ - boolean (*range_type) PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma)); - - /* Push an array type onto the type stack. The top type on the type - stack is the range, and the next type on the type stack is the - element type. These should be popped before the array type is - pushed. The arguments are the lower bound, the upper bound, and - whether the array is a string. */ - boolean (*array_type) PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma, - boolean)); - - /* Pop the top type on the type stack, and push a set of that type - onto the type stack. The argument indicates whether this set is - a bitstring. */ - boolean (*set_type) PARAMS ((PTR, boolean)); - - /* Push an offset type onto the type stack. The top type on the - type stack is the target type, and the next type on the type - stack is the base type. These should be popped before the offset - type is pushed. */ - boolean (*offset_type) PARAMS ((PTR)); - - /* Push a method type onto the type stack. If the second argument - is true, the top type on the stack is the class to which the - method belongs; otherwise, the class must be determined by the - class to which the method is attached. The third argument is the - number of argument types; these are pushed onto the type stack in - reverse order (the first type popped is the last argument to the - method). A value of -1 for the third argument means that no - argument information is available. The fourth argument is true - if the function takes a variable number of arguments. The next - type on the type stack below the domain and the argument types is - the return type of the method. All these types must be popped, - and then the method type must be pushed. */ - boolean (*method_type) PARAMS ((PTR, boolean, int, boolean)); - - /* Pop the top type off the type stack, and push a const qualified - version of that type onto the type stack. */ - boolean (*const_type) PARAMS ((PTR)); - - /* Pop the top type off the type stack, and push a volatile - qualified version of that type onto the type stack. */ - boolean (*volatile_type) PARAMS ((PTR)); - - /* Start building a struct. This is followed by calls to the - struct_field function, and finished by a call to the - end_struct_type function. The second argument is the tag; this - will be NULL if there isn't one. If the second argument is NULL, - the third argument is a constant identifying this struct for use - with tag_type. The fourth argument is true for a struct, false - for a union. The fifth argument is the size. If this is an - undefined struct or union, the size will be 0 and struct_field - will not be called before end_struct_type is called. */ - boolean (*start_struct_type) PARAMS ((PTR, const char *, unsigned int, - boolean, unsigned int)); - - /* Add a field to the struct type currently being built. The type - of the field should be popped off the type stack. The arguments - are the name, the bit position, the bit size (may be zero if the - field is not packed), and the visibility. */ - boolean (*struct_field) PARAMS ((PTR, const char *, bfd_vma, bfd_vma, - enum debug_visibility)); - - /* Finish building a struct, and push it onto the type stack. */ - boolean (*end_struct_type) PARAMS ((PTR)); - - /* Start building a class. This is followed by calls to several - functions: struct_field, class_static_member, class_baseclass, - class_start_method, class_method_variant, - class_static_method_variant, and class_end_method. The class is - finished by a call to end_class_type. The first five arguments - are the same as for start_struct_type. The sixth argument is - true if there is a virtual function table; if there is, the - seventh argument is true if the virtual function table can be - found in the type itself, and is false if the type of the object - holding the virtual function table should be popped from the type - stack. */ - boolean (*start_class_type) PARAMS ((PTR, const char *, unsigned int, - boolean, unsigned int, boolean, - boolean)); - - /* Add a static member to the class currently being built. The - arguments are the field name, the physical name, and the - visibility. The type must be popped off the type stack. */ - boolean (*class_static_member) PARAMS ((PTR, const char *, const char *, - enum debug_visibility)); - - /* Add a baseclass to the class currently being built. The type of - the baseclass must be popped off the type stack. The arguments - are the bit position, whether the class is virtual, and the - visibility. */ - boolean (*class_baseclass) PARAMS ((PTR, bfd_vma, boolean, - enum debug_visibility)); - - /* Start adding a method to the class currently being built. This - is followed by calls to class_method_variant and - class_static_method_variant to describe different variants of the - method which take different arguments. The method is finished - with a call to class_end_method. The argument is the method - name. */ - boolean (*class_start_method) PARAMS ((PTR, const char *)); - - /* Describe a variant to the class method currently being built. - The type of the variant must be popped off the type stack. The - second argument is the physical name of the function. The - following arguments are the visibility, whether the variant is - const, whether the variant is volatile, the offset in the virtual - function table, and whether the context is on the type stack - (below the variant type). */ - boolean (*class_method_variant) PARAMS ((PTR, const char *, - enum debug_visibility, - boolean, boolean, - bfd_vma, boolean)); - - /* Describe a static variant to the class method currently being - built. The arguments are the same as for class_method_variant, - except that the last two arguments are omitted. The type of the - variant must be popped off the type stack. */ - boolean (*class_static_method_variant) PARAMS ((PTR, const char *, - enum debug_visibility, - boolean, boolean)); - - /* Finish describing a class method. */ - boolean (*class_end_method) PARAMS ((PTR)); - - /* Finish describing a class, and push it onto the type stack. */ - boolean (*end_class_type) PARAMS ((PTR)); - - /* Push a type on the stack which was given a name by an earlier - call to typdef. */ - boolean (*typedef_type) PARAMS ((PTR, const char *)); - - /* Push a tagged type on the stack which was defined earlier. If - the second argument is not NULL, the type was defined by a call - to tag. If the second argument is NULL, the type was defined by - a call to start_struct_type or start_class_type with a tag of - NULL and the number of the third argument. Either way, the - fourth argument is the tag kind. Note that this may be called - for a struct (class) being defined, in between the call to - start_struct_type (start_class_type) and the call to - end_struct_type (end_class_type). */ - boolean (*tag_type) PARAMS ((PTR, const char *, unsigned int, - enum debug_type_kind)); - - /* Pop the type stack, and typedef it to the given name. */ - boolean (*typdef) PARAMS ((PTR, const char *)); - - /* Pop the type stack, and declare it as a tagged struct or union or - enum or whatever. The tag passed down here is redundant, since - was also passed when enum_type, start_struct_type, or - start_class_type was called. */ - boolean (*tag) PARAMS ((PTR, const char *)); - - /* This is called to record a named integer constant. */ - boolean (*int_constant) PARAMS ((PTR, const char *, bfd_vma)); - - /* This is called to record a named floating point constant. */ - boolean (*float_constant) PARAMS ((PTR, const char *, double)); - - /* This is called to record a typed integer constant. The type is - popped off the type stack. */ - boolean (*typed_constant) PARAMS ((PTR, const char *, bfd_vma)); - - /* This is called to record a variable. The type is popped off the - type stack. */ - boolean (*variable) PARAMS ((PTR, const char *, enum debug_var_kind, - bfd_vma)); - - /* Start writing out a function. The return type must be popped off - the stack. The boolean is true if the function is global. This - is followed by calls to function_parameter, followed by block - information. */ - boolean (*start_function) PARAMS ((PTR, const char *, boolean)); - - /* Record a function parameter for the current function. The type - must be popped off the stack. */ - boolean (*function_parameter) PARAMS ((PTR, const char *, - enum debug_parm_kind, bfd_vma)); - - /* Start writing out a block. There is at least one top level block - per function. Blocks may be nested. The argument is the - starting address of the block. */ - boolean (*start_block) PARAMS ((PTR, bfd_vma)); - - /* Finish writing out a block. The argument is the ending address - of the block. */ - boolean (*end_block) PARAMS ((PTR, bfd_vma)); - - /* Finish writing out a function. */ - boolean (*end_function) PARAMS ((PTR)); - - /* Record line number information for the current compilation unit. */ - boolean (*lineno) PARAMS ((PTR, const char *, unsigned long, bfd_vma)); -}; - -/* Exported functions. */ - -/* The first argument to most of these functions is a handle. This - handle is returned by the debug_init function. The purpose of the - handle is to permit the debugging routines to not use static - variables, and hence to be reentrant. This would be useful for a - program which wanted to handle two executables simultaneously. */ - -/* Return a debugging handle. */ - -extern PTR debug_init PARAMS ((void)); - -/* Set the source filename. This implicitly starts a new compilation - unit. */ - -extern boolean debug_set_filename PARAMS ((PTR, const char *)); - -/* Change source files to the given file name. This is used for - include files in a single compilation unit. */ - -extern boolean debug_start_source PARAMS ((PTR, const char *)); - -/* Record a function definition. This implicitly starts a function - block. The debug_type argument is the type of the return value. - The boolean indicates whether the function is globally visible. - The bfd_vma is the address of the start of the function. Currently - the parameter types are specified by calls to - debug_record_parameter. */ - -extern boolean debug_record_function - PARAMS ((PTR, const char *, debug_type, boolean, bfd_vma)); - -/* Record a parameter for the current function. */ - -extern boolean debug_record_parameter - PARAMS ((PTR, const char *, debug_type, enum debug_parm_kind, bfd_vma)); - -/* End a function definition. The argument is the address where the - function ends. */ - -extern boolean debug_end_function PARAMS ((PTR, bfd_vma)); - -/* Start a block in a function. All local information will be - recorded in this block, until the matching call to debug_end_block. - debug_start_block and debug_end_block may be nested. The argument - is the address at which this block starts. */ - -extern boolean debug_start_block PARAMS ((PTR, bfd_vma)); - -/* Finish a block in a function. This matches the call to - debug_start_block. The argument is the address at which this block - ends. */ - -extern boolean debug_end_block PARAMS ((PTR, bfd_vma)); - -/* Associate a line number in the current source file with a given - address. */ - -extern boolean debug_record_line PARAMS ((PTR, unsigned long, bfd_vma)); - -/* Start a named common block. This is a block of variables that may - move in memory. */ - -extern boolean debug_start_common_block PARAMS ((PTR, const char *)); - -/* End a named common block. */ - -extern boolean debug_end_common_block PARAMS ((PTR, const char *)); - -/* Record a named integer constant. */ - -extern boolean debug_record_int_const PARAMS ((PTR, const char *, bfd_vma)); - -/* Record a named floating point constant. */ - -extern boolean debug_record_float_const PARAMS ((PTR, const char *, double)); - -/* Record a typed constant with an integral value. */ - -extern boolean debug_record_typed_const - PARAMS ((PTR, const char *, debug_type, bfd_vma)); - -/* Record a label. */ - -extern boolean debug_record_label - PARAMS ((PTR, const char *, debug_type, bfd_vma)); - -/* Record a variable. */ - -extern boolean debug_record_variable - PARAMS ((PTR, const char *, debug_type, enum debug_var_kind, bfd_vma)); - -/* Make an indirect type. The first argument is a pointer to the - location where the real type will be placed. The second argument - is the type tag, if there is one; this may be NULL; the only - purpose of this argument is so that debug_get_type_name can return - something useful. This function may be used when a type is - referenced before it is defined. */ - -extern debug_type debug_make_indirect_type - PARAMS ((PTR, debug_type *, const char *)); - -/* Make a void type. */ - -extern debug_type debug_make_void_type PARAMS ((PTR)); - -/* Make an integer type of a given size. The boolean argument is true - if the integer is unsigned. */ - -extern debug_type debug_make_int_type PARAMS ((PTR, unsigned int, boolean)); - -/* Make a floating point type of a given size. FIXME: On some - platforms, like an Alpha, you probably need to be able to specify - the format. */ - -extern debug_type debug_make_float_type PARAMS ((PTR, unsigned int)); - -/* Make a boolean type of a given size. */ - -extern debug_type debug_make_bool_type PARAMS ((PTR, unsigned int)); - -/* Make a complex type of a given size. */ - -extern debug_type debug_make_complex_type PARAMS ((PTR, unsigned int)); - -/* Make a structure type. The second argument is true for a struct, - false for a union. The third argument is the size of the struct. - The fourth argument is a NULL terminated array of fields. */ - -extern debug_type debug_make_struct_type - PARAMS ((PTR, boolean, bfd_vma, debug_field *)); - -/* Make an object type. The first three arguments after the handle - are the same as for debug_make_struct_type. The next arguments are - a NULL terminated array of base classes, a NULL terminated array of - methods, the type of the object holding the virtual function table - if it is not this object, and a boolean which is true if this - object has its own virtual function table. */ - -extern debug_type debug_make_object_type - PARAMS ((PTR, boolean, bfd_vma, debug_field *, debug_baseclass *, - debug_method *, debug_type, boolean)); - -/* Make an enumeration type. The arguments are a null terminated - array of strings, and an array of corresponding values. */ - -extern debug_type debug_make_enum_type - PARAMS ((PTR, const char **, bfd_signed_vma *)); - -/* Make a pointer to a given type. */ - -extern debug_type debug_make_pointer_type - PARAMS ((PTR, debug_type)); - -/* Make a function type. The second argument is the return type. The - third argument is a NULL terminated array of argument types. The - fourth argument is true if the function takes a variable number of - arguments. If the third argument is NULL, then the argument types - are unknown. */ - -extern debug_type debug_make_function_type - PARAMS ((PTR, debug_type, debug_type *, boolean)); - -/* Make a reference to a given type. */ - -extern debug_type debug_make_reference_type PARAMS ((PTR, debug_type)); - -/* Make a range of a given type from a lower to an upper bound. */ - -extern debug_type debug_make_range_type - PARAMS ((PTR, debug_type, bfd_signed_vma, bfd_signed_vma)); - -/* Make an array type. The second argument is the type of an element - of the array. The third argument is the type of a range of the - array. The fourth and fifth argument are the lower and upper - bounds, respectively (if the bounds are not known, lower should be - 0 and upper should be -1). The sixth argument is true if this - array is actually a string, as in C. */ - -extern debug_type debug_make_array_type - PARAMS ((PTR, debug_type, debug_type, bfd_signed_vma, bfd_signed_vma, - boolean)); - -/* Make a set of a given type. For example, a Pascal set type. The - boolean argument is true if this set is actually a bitstring, as in - CHILL. */ - -extern debug_type debug_make_set_type PARAMS ((PTR, debug_type, boolean)); - -/* Make a type for a pointer which is relative to an object. The - second argument is the type of the object to which the pointer is - relative. The third argument is the type that the pointer points - to. */ - -extern debug_type debug_make_offset_type - PARAMS ((PTR, debug_type, debug_type)); - -/* Make a type for a method function. The second argument is the - return type. The third argument is the domain. The fourth - argument is a NULL terminated array of argument types. The fifth - argument is true if the function takes a variable number of - arguments, in which case the array of argument types indicates the - types of the first arguments. The domain and the argument array - may be NULL, in which case this is a stub method and that - information is not available. Stabs debugging uses this, and gets - the argument types from the mangled name. */ - -extern debug_type debug_make_method_type - PARAMS ((PTR, debug_type, debug_type, debug_type *, boolean)); - -/* Make a const qualified version of a given type. */ - -extern debug_type debug_make_const_type PARAMS ((PTR, debug_type)); - -/* Make a volatile qualified version of a given type. */ - -extern debug_type debug_make_volatile_type PARAMS ((PTR, debug_type)); - -/* Make an undefined tagged type. For example, a struct which has - been mentioned, but not defined. */ - -extern debug_type debug_make_undefined_tagged_type - PARAMS ((PTR, const char *, enum debug_type_kind)); - -/* Make a base class for an object. The second argument is the base - class type. The third argument is the bit position of this base - class in the object. The fourth argument is whether this is a - virtual class. The fifth argument is the visibility of the base - class. */ - -extern debug_baseclass debug_make_baseclass - PARAMS ((PTR, debug_type, bfd_vma, boolean, enum debug_visibility)); - -/* Make a field for a struct. The second argument is the name. The - third argument is the type of the field. The fourth argument is - the bit position of the field. The fifth argument is the size of - the field (it may be zero). The sixth argument is the visibility - of the field. */ - -extern debug_field debug_make_field - PARAMS ((PTR, const char *, debug_type, bfd_vma, bfd_vma, - enum debug_visibility)); - -/* Make a static member of an object. The second argument is the - name. The third argument is the type of the member. The fourth - argument is the physical name of the member (i.e., the name as a - global variable). The fifth argument is the visibility of the - member. */ - -extern debug_field debug_make_static_member - PARAMS ((PTR, const char *, debug_type, const char *, - enum debug_visibility)); - -/* Make a method. The second argument is the name, and the third - argument is a NULL terminated array of method variants. Each - method variant is a method with this name but with different - argument types. */ - -extern debug_method debug_make_method - PARAMS ((PTR, const char *, debug_method_variant *)); - -/* Make a method variant. The second argument is the physical name of - the function. The third argument is the type of the function, - probably constructed by debug_make_method_type. The fourth - argument is the visibility. The fifth argument is whether this is - a const function. The sixth argument is whether this is a volatile - function. The seventh argument is the index in the virtual - function table, if any. The eighth argument is the virtual - function context. */ - -extern debug_method_variant debug_make_method_variant - PARAMS ((PTR, const char *, debug_type, enum debug_visibility, boolean, - boolean, bfd_vma, debug_type)); - -/* Make a static method argument. The arguments are the same as for - debug_make_method_variant, except that the last two are omitted - since a static method can not also be virtual. */ - -extern debug_method_variant debug_make_static_method_variant - PARAMS ((PTR, const char *, debug_type, enum debug_visibility, boolean, - boolean)); - -/* Name a type. This returns a new type with an attached name. */ - -extern debug_type debug_name_type PARAMS ((PTR, const char *, debug_type)); - -/* Give a tag to a type, such as a struct or union. This returns a - new type with an attached tag. */ - -extern debug_type debug_tag_type PARAMS ((PTR, const char *, debug_type)); - -/* Record the size of a given type. */ - -extern boolean debug_record_type_size PARAMS ((PTR, debug_type, unsigned int)); - -/* Find a named type. */ - -extern debug_type debug_find_named_type PARAMS ((PTR, const char *)); - -/* Find a tagged type. */ - -extern debug_type debug_find_tagged_type - PARAMS ((PTR, const char *, enum debug_type_kind)); - -/* Get the kind of a type. */ - -extern enum debug_type_kind debug_get_type_kind PARAMS ((PTR, debug_type)); - -/* Get the name of a type. */ - -extern const char *debug_get_type_name PARAMS ((PTR, debug_type)); - -/* Get the size of a type. */ - -extern bfd_vma debug_get_type_size PARAMS ((PTR, debug_type)); - -/* Get the return type of a function or method type. */ - -extern debug_type debug_get_return_type PARAMS ((PTR, debug_type)); - -/* Get the NULL terminated array of parameter types for a function or - method type (actually, parameter types are not currently stored for - function types). This may be used to determine whether a method - type is a stub method or not. The last argument points to a - boolean which is set to true if the function takes a variable - number of arguments. */ - -extern const debug_type *debug_get_parameter_types PARAMS ((PTR, - debug_type, - boolean *)); - -/* Get the target type of a pointer or reference or const or volatile - type. */ - -extern debug_type debug_get_target_type PARAMS ((PTR, debug_type)); - -/* Get the NULL terminated array of fields for a struct, union, or - class. */ - -extern const debug_field *debug_get_fields PARAMS ((PTR, debug_type)); - -/* Get the type of a field. */ - -extern debug_type debug_get_field_type PARAMS ((PTR, debug_field)); - -/* Get the name of a field. */ - -extern const char *debug_get_field_name PARAMS ((PTR, debug_field)); - -/* Get the bit position of a field within the containing structure. - If the field is a static member, this will return (bfd_vma) -1. */ - -extern bfd_vma debug_get_field_bitpos PARAMS ((PTR, debug_field)); - -/* Get the bit size of a field. If the field is a static member, this - will return (bfd_vma) -1. */ - -extern bfd_vma debug_get_field_bitsize PARAMS ((PTR, debug_field)); - -/* Get the visibility of a field. */ - -extern enum debug_visibility debug_get_field_visibility - PARAMS ((PTR, debug_field)); - -/* Get the physical name of a field, if it is a static member. If the - field is not a static member, this will return NULL. */ - -extern const char *debug_get_field_physname PARAMS ((PTR, debug_field)); - -/* Write out the recorded debugging information. This takes a set of - function pointers which are called to do the actual writing. The - first PTR is the debugging handle. The second PTR is a handle - which is passed to the functions. */ - -extern boolean debug_write PARAMS ((PTR, const struct debug_write_fns *, PTR)); - -#endif /* DEBUG_H */ diff --git a/pstack/demangle.h b/pstack/demangle.h deleted file mode 100644 index a961436ca77..00000000000 --- a/pstack/demangle.h +++ /dev/null @@ -1,90 +0,0 @@ -/* Defs for interface to demanglers. - Copyright 1992, 1995, 1996 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - - -#if !defined (DEMANGLE_H) -#define DEMANGLE_H - -#ifdef IN_GCC -#include "gansidecl.h" -#define PARAMS(ARGS) PROTO(ARGS) -#else /* ! IN_GCC */ -#include -#endif /* IN_GCC */ - -/* Options passed to cplus_demangle (in 2nd parameter). */ - -#define DMGL_NO_OPTS 0 /* For readability... */ -#define DMGL_PARAMS (1 << 0) /* Include function args */ -#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ -#define DMGL_JAVA (1 << 2) /* Demangle as Java rather than C++. */ - -#define DMGL_AUTO (1 << 8) -#define DMGL_GNU (1 << 9) -#define DMGL_LUCID (1 << 10) -#define DMGL_ARM (1 << 11) -/* If none of these are set, use 'current_demangling_style' as the default. */ -#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM) - -/* Enumeration of possible demangling styles. - - Lucid and ARM styles are still kept logically distinct, even though - they now both behave identically. The resulting style is actual the - union of both. I.E. either style recognizes both "__pt__" and "__rf__" - for operator "->", even though the first is lucid style and the second - is ARM style. (FIXME?) */ - -extern enum demangling_styles -{ - unknown_demangling = 0, - auto_demangling = DMGL_AUTO, - gnu_demangling = DMGL_GNU, - lucid_demangling = DMGL_LUCID, - arm_demangling = DMGL_ARM -} current_demangling_style; - -/* Define string names for the various demangling styles. */ - -#define AUTO_DEMANGLING_STYLE_STRING "auto" -#define GNU_DEMANGLING_STYLE_STRING "gnu" -#define LUCID_DEMANGLING_STYLE_STRING "lucid" -#define ARM_DEMANGLING_STYLE_STRING "arm" - -/* Some macros to test what demangling style is active. */ - -#define CURRENT_DEMANGLING_STYLE current_demangling_style -#define AUTO_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_AUTO) -#define GNU_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNU) -#define LUCID_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_LUCID) -#define ARM_DEMANGLING (CURRENT_DEMANGLING_STYLE & DMGL_ARM) - -extern char * -cplus_demangle PARAMS ((const char *mangled, int options)); - -extern int -cplus_demangle_opname PARAMS ((const char *opname, char *result, int options)); - -extern const char * -cplus_mangle_opname PARAMS ((const char *opname, int options)); - -/* Note: This sets global state. FIXME if you care about multi-threading. */ - -extern void -set_cplus_marker_for_demangling PARAMS ((int ch)); - -#endif /* DEMANGLE_H */ diff --git a/pstack/filemode.c b/pstack/filemode.c deleted file mode 100644 index 58b52ba7489..00000000000 --- a/pstack/filemode.c +++ /dev/null @@ -1,266 +0,0 @@ -/* filemode.c -- make a string describing file modes - Copyright (C) 1985, 90, 91, 94, 95, 1997 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -#include "bfd.h" -#include "bucomm.h" - -static char ftypelet PARAMS ((unsigned long)); -static void setst PARAMS ((unsigned long, char *)); - -/* filemodestring - fill in string STR with an ls-style ASCII - representation of the st_mode field of file stats block STATP. - 10 characters are stored in STR; no terminating null is added. - The characters stored in STR are: - - 0 File type. 'd' for directory, 'c' for character - special, 'b' for block special, 'm' for multiplex, - 'l' for symbolic link, 's' for socket, 'p' for fifo, - '-' for any other file type - - 1 'r' if the owner may read, '-' otherwise. - - 2 'w' if the owner may write, '-' otherwise. - - 3 'x' if the owner may execute, 's' if the file is - set-user-id, '-' otherwise. - 'S' if the file is set-user-id, but the execute - bit isn't set. - - 4 'r' if group members may read, '-' otherwise. - - 5 'w' if group members may write, '-' otherwise. - - 6 'x' if group members may execute, 's' if the file is - set-group-id, '-' otherwise. - 'S' if it is set-group-id but not executable. - - 7 'r' if any user may read, '-' otherwise. - - 8 'w' if any user may write, '-' otherwise. - - 9 'x' if any user may execute, 't' if the file is "sticky" - (will be retained in swap space after execution), '-' - otherwise. - 'T' if the file is sticky but not executable. */ - -#if 0 - -/* This is not used; only mode_string is used. */ - -void -filemodestring (statp, str) - struct stat *statp; - char *str; -{ - mode_string ((unsigned long) statp->st_mode, str); -} - -#endif - -/* Get definitions for the file permission bits. */ - -#ifndef S_IRWXU -#define S_IRWXU 0700 -#endif -#ifndef S_IRUSR -#define S_IRUSR 0400 -#endif -#ifndef S_IWUSR -#define S_IWUSR 0200 -#endif -#ifndef S_IXUSR -#define S_IXUSR 0100 -#endif - -#ifndef S_IRWXG -#define S_IRWXG 0070 -#endif -#ifndef S_IRGRP -#define S_IRGRP 0040 -#endif -#ifndef S_IWGRP -#define S_IWGRP 0020 -#endif -#ifndef S_IXGRP -#define S_IXGRP 0010 -#endif - -#ifndef S_IRWXO -#define S_IRWXO 0007 -#endif -#ifndef S_IROTH -#define S_IROTH 0004 -#endif -#ifndef S_IWOTH -#define S_IWOTH 0002 -#endif -#ifndef S_IXOTH -#define S_IXOTH 0001 -#endif - -/* Like filemodestring, but only the relevant part of the `struct stat' - is given as an argument. */ - -void -mode_string (mode, str) - unsigned long mode; - char *str; -{ - str[0] = ftypelet ((unsigned long) mode); - str[1] = (mode & S_IRUSR) != 0 ? 'r' : '-'; - str[2] = (mode & S_IWUSR) != 0 ? 'w' : '-'; - str[3] = (mode & S_IXUSR) != 0 ? 'x' : '-'; - str[4] = (mode & S_IRGRP) != 0 ? 'r' : '-'; - str[5] = (mode & S_IWGRP) != 0 ? 'w' : '-'; - str[6] = (mode & S_IXGRP) != 0 ? 'x' : '-'; - str[7] = (mode & S_IROTH) != 0 ? 'r' : '-'; - str[8] = (mode & S_IWOTH) != 0 ? 'w' : '-'; - str[9] = (mode & S_IXOTH) != 0 ? 'x' : '-'; - setst ((unsigned long) mode, str); -} - -/* Return a character indicating the type of file described by - file mode BITS: - 'd' for directories - 'b' for block special files - 'c' for character special files - 'm' for multiplexor files - 'l' for symbolic links - 's' for sockets - 'p' for fifos - '-' for any other file type. */ - -#ifndef S_ISDIR -#ifdef S_IFDIR -#define S_ISDIR(i) (((i) & S_IFMT) == S_IFDIR) -#else /* ! defined (S_IFDIR) */ -#define S_ISDIR(i) (((i) & 0170000) == 040000) -#endif /* ! defined (S_IFDIR) */ -#endif /* ! defined (S_ISDIR) */ - -#ifndef S_ISBLK -#ifdef S_IFBLK -#define S_ISBLK(i) (((i) & S_IFMT) == S_IFBLK) -#else /* ! defined (S_IFBLK) */ -#define S_ISBLK(i) 0 -#endif /* ! defined (S_IFBLK) */ -#endif /* ! defined (S_ISBLK) */ - -#ifndef S_ISCHR -#ifdef S_IFCHR -#define S_ISCHR(i) (((i) & S_IFMT) == S_IFCHR) -#else /* ! defined (S_IFCHR) */ -#define S_ISCHR(i) 0 -#endif /* ! defined (S_IFCHR) */ -#endif /* ! defined (S_ISCHR) */ - -#ifndef S_ISFIFO -#ifdef S_IFIFO -#define S_ISFIFO(i) (((i) & S_IFMT) == S_IFIFO) -#else /* ! defined (S_IFIFO) */ -#define S_ISFIFO(i) 0 -#endif /* ! defined (S_IFIFO) */ -#endif /* ! defined (S_ISFIFO) */ - -#ifndef S_ISSOCK -#ifdef S_IFSOCK -#define S_ISSOCK(i) (((i) & S_IFMT) == S_IFSOCK) -#else /* ! defined (S_IFSOCK) */ -#define S_ISSOCK(i) 0 -#endif /* ! defined (S_IFSOCK) */ -#endif /* ! defined (S_ISSOCK) */ - -#ifndef S_ISLNK -#ifdef S_IFLNK -#define S_ISLNK(i) (((i) & S_IFMT) == S_IFLNK) -#else /* ! defined (S_IFLNK) */ -#define S_ISLNK(i) 0 -#endif /* ! defined (S_IFLNK) */ -#endif /* ! defined (S_ISLNK) */ - -static char -ftypelet (bits) - unsigned long bits; -{ - if (S_ISDIR (bits)) - return 'd'; - if (S_ISLNK (bits)) - return 'l'; - if (S_ISBLK (bits)) - return 'b'; - if (S_ISCHR (bits)) - return 'c'; - if (S_ISSOCK (bits)) - return 's'; - if (S_ISFIFO (bits)) - return 'p'; - -#ifdef S_IFMT -#ifdef S_IFMPC - if ((bits & S_IFMT) == S_IFMPC - || (bits & S_IFMT) == S_IFMPB) - return 'm'; -#endif -#ifdef S_IFNWK - if ((bits & S_IFMT) == S_IFNWK) - return 'n'; -#endif -#endif - - return '-'; -} - -/* Set the 's' and 't' flags in file attributes string CHARS, - according to the file mode BITS. */ - -static void -setst (bits, chars) - unsigned long bits; - char *chars; -{ -#ifdef S_ISUID - if (bits & S_ISUID) - { - if (chars[3] != 'x') - /* Set-uid, but not executable by owner. */ - chars[3] = 'S'; - else - chars[3] = 's'; - } -#endif -#ifdef S_ISGID - if (bits & S_ISGID) - { - if (chars[6] != 'x') - /* Set-gid, but not executable by group. */ - chars[6] = 'S'; - else - chars[6] = 's'; - } -#endif -#ifdef S_ISVTX - if (bits & S_ISVTX) - { - if (chars[9] != 'x') - /* Sticky, but not executable by others. */ - chars[9] = 'T'; - else - chars[9] = 't'; - } -#endif -} diff --git a/pstack/ieee.c b/pstack/ieee.c deleted file mode 100644 index 8084656a5ef..00000000000 --- a/pstack/ieee.c +++ /dev/null @@ -1,7602 +0,0 @@ -/* ieee.c -- Read and write IEEE-695 debugging information. - Copyright (C) 1996 Free Software Foundation, Inc. - Written by Ian Lance Taylor . - - This file is part of GNU Binutils. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -/* This file reads and writes IEEE-695 debugging information. */ - -#include -#include - -#include -#include "ieee.h" -#include "bucomm.h" -#include -#include "debug.h" -#include "budbg.h" - -/* This structure holds an entry on the block stack. */ - -struct ieee_block -{ - /* The kind of block. */ - int kind; - /* The source file name, for a BB5 block. */ - const char *filename; - /* The index of the function type, for a BB4 or BB6 block. */ - unsigned int fnindx; - /* True if this function is being skipped. */ - boolean skip; -}; - -/* This structure is the block stack. */ - -#define BLOCKSTACK_SIZE (16) - -struct ieee_blockstack -{ - /* The stack pointer. */ - struct ieee_block *bsp; - /* The stack. */ - struct ieee_block stack[BLOCKSTACK_SIZE]; -}; - -/* This structure holds information for a variable. */ - -struct ieee_var -{ - /* Start of name. */ - const char *name; - /* Length of name. */ - unsigned long namlen; - /* Type. */ - debug_type type; - /* Slot if we make an indirect type. */ - debug_type *pslot; - /* Kind of variable or function. */ - enum - { - IEEE_UNKNOWN, - IEEE_EXTERNAL, - IEEE_GLOBAL, - IEEE_STATIC, - IEEE_LOCAL, - IEEE_FUNCTION - } kind; -}; - -/* This structure holds all the variables. */ - -struct ieee_vars -{ - /* Number of slots allocated. */ - unsigned int alloc; - /* Variables. */ - struct ieee_var *vars; -}; - -/* This structure holds information for a type. We need this because - we don't want to represent bitfields as real types. */ - -struct ieee_type -{ - /* Type. */ - debug_type type; - /* Slot if this is type is referenced before it is defined. */ - debug_type *pslot; - /* Slots for arguments if we make indirect types for them. */ - debug_type *arg_slots; - /* If this is a bitfield, this is the size in bits. If this is not - a bitfield, this is zero. */ - unsigned long bitsize; -}; - -/* This structure holds all the type information. */ - -struct ieee_types -{ - /* Number of slots allocated. */ - unsigned int alloc; - /* Types. */ - struct ieee_type *types; - /* Builtin types. */ -#define BUILTIN_TYPE_COUNT (60) - debug_type builtins[BUILTIN_TYPE_COUNT]; -}; - -/* This structure holds a linked last of structs with their tag names, - so that we can convert them to C++ classes if necessary. */ - -struct ieee_tag -{ - /* Next tag. */ - struct ieee_tag *next; - /* This tag name. */ - const char *name; - /* The type of the tag. */ - debug_type type; - /* The tagged type is an indirect type pointing at this slot. */ - debug_type slot; - /* This is an array of slots used when a field type is converted - into a indirect type, in case it needs to be later converted into - a reference type. */ - debug_type *fslots; -}; - -/* This structure holds the information we pass around to the parsing - functions. */ - -struct ieee_info -{ - /* The debugging handle. */ - PTR dhandle; - /* The BFD. */ - bfd *abfd; - /* The start of the bytes to be parsed. */ - const bfd_byte *bytes; - /* The end of the bytes to be parsed. */ - const bfd_byte *pend; - /* The block stack. */ - struct ieee_blockstack blockstack; - /* Whether we have seen a BB1 or BB2. */ - boolean saw_filename; - /* The variables. */ - struct ieee_vars vars; - /* The global variables, after a global typedef block. */ - struct ieee_vars *global_vars; - /* The types. */ - struct ieee_types types; - /* The global types, after a global typedef block. */ - struct ieee_types *global_types; - /* The list of tagged structs. */ - struct ieee_tag *tags; -}; - -/* Basic builtin types, not including the pointers. */ - -enum builtin_types -{ - builtin_unknown = 0, - builtin_void = 1, - builtin_signed_char = 2, - builtin_unsigned_char = 3, - builtin_signed_short_int = 4, - builtin_unsigned_short_int = 5, - builtin_signed_long = 6, - builtin_unsigned_long = 7, - builtin_signed_long_long = 8, - builtin_unsigned_long_long = 9, - builtin_float = 10, - builtin_double = 11, - builtin_long_double = 12, - builtin_long_long_double = 13, - builtin_quoted_string = 14, - builtin_instruction_address = 15, - builtin_int = 16, - builtin_unsigned = 17, - builtin_unsigned_int = 18, - builtin_char = 19, - builtin_long = 20, - builtin_short = 21, - builtin_unsigned_short = 22, - builtin_short_int = 23, - builtin_signed_short = 24, - builtin_bcd_float = 25 -}; - -/* These are the values found in the derivation flags of a 'b' - component record of a 'T' type extension record in a C++ pmisc - record. These are bitmasks. */ - -/* Set for a private base class, clear for a public base class. - Protected base classes are not supported. */ -#define BASEFLAGS_PRIVATE (0x1) -/* Set for a virtual base class. */ -#define BASEFLAGS_VIRTUAL (0x2) -/* Set for a friend class, clear for a base class. */ -#define BASEFLAGS_FRIEND (0x10) - -/* These are the values found in the specs flags of a 'd', 'm', or 'v' - component record of a 'T' type extension record in a C++ pmisc - record. The same flags are used for a 'M' record in a C++ pmisc - record. */ - -/* The lower two bits hold visibility information. */ -#define CXXFLAGS_VISIBILITY (0x3) -/* This value in the lower two bits indicates a public member. */ -#define CXXFLAGS_VISIBILITY_PUBLIC (0x0) -/* This value in the lower two bits indicates a private member. */ -#define CXXFLAGS_VISIBILITY_PRIVATE (0x1) -/* This value in the lower two bits indicates a protected member. */ -#define CXXFLAGS_VISIBILITY_PROTECTED (0x2) -/* Set for a static member. */ -#define CXXFLAGS_STATIC (0x4) -/* Set for a virtual override. */ -#define CXXFLAGS_OVERRIDE (0x8) -/* Set for a friend function. */ -#define CXXFLAGS_FRIEND (0x10) -/* Set for a const function. */ -#define CXXFLAGS_CONST (0x20) -/* Set for a volatile function. */ -#define CXXFLAGS_VOLATILE (0x40) -/* Set for an overloaded function. */ -#define CXXFLAGS_OVERLOADED (0x80) -/* Set for an operator function. */ -#define CXXFLAGS_OPERATOR (0x100) -/* Set for a constructor or destructor. */ -#define CXXFLAGS_CTORDTOR (0x400) -/* Set for a constructor. */ -#define CXXFLAGS_CTOR (0x200) -/* Set for an inline function. */ -#define CXXFLAGS_INLINE (0x800) - -/* Local functions. */ - -static void ieee_error - PARAMS ((struct ieee_info *, const bfd_byte *, const char *)); -static void ieee_eof PARAMS ((struct ieee_info *)); -static char *savestring PARAMS ((const char *, unsigned long)); -static boolean ieee_read_number - PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *)); -static boolean ieee_read_optional_number - PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *, boolean *)); -static boolean ieee_read_id - PARAMS ((struct ieee_info *, const bfd_byte **, const char **, - unsigned long *)); -static boolean ieee_read_optional_id - PARAMS ((struct ieee_info *, const bfd_byte **, const char **, - unsigned long *, boolean *)); -static boolean ieee_read_expression - PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *)); -static debug_type ieee_builtin_type - PARAMS ((struct ieee_info *, const bfd_byte *, unsigned int)); -static boolean ieee_alloc_type - PARAMS ((struct ieee_info *, unsigned int, boolean)); -static boolean ieee_read_type_index - PARAMS ((struct ieee_info *, const bfd_byte **, debug_type *)); -static int ieee_regno_to_genreg PARAMS ((bfd *, int)); -static int ieee_genreg_to_regno PARAMS ((bfd *, int)); -static boolean parse_ieee_bb PARAMS ((struct ieee_info *, const bfd_byte **)); -static boolean parse_ieee_be PARAMS ((struct ieee_info *, const bfd_byte **)); -static boolean parse_ieee_nn PARAMS ((struct ieee_info *, const bfd_byte **)); -static boolean parse_ieee_ty PARAMS ((struct ieee_info *, const bfd_byte **)); -static boolean parse_ieee_atn PARAMS ((struct ieee_info *, const bfd_byte **)); -static boolean ieee_read_cxx_misc - PARAMS ((struct ieee_info *, const bfd_byte **, unsigned long)); -static boolean ieee_read_cxx_class - PARAMS ((struct ieee_info *, const bfd_byte **, unsigned long)); -static boolean ieee_read_cxx_defaults - PARAMS ((struct ieee_info *, const bfd_byte **, unsigned long)); -static boolean ieee_read_reference - PARAMS ((struct ieee_info *, const bfd_byte **)); -static boolean ieee_require_asn - PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *)); -static boolean ieee_require_atn65 - PARAMS ((struct ieee_info *, const bfd_byte **, const char **, - unsigned long *)); - -/* Report an error in the IEEE debugging information. */ - -static void -ieee_error (info, p, s) - struct ieee_info *info; - const bfd_byte *p; - const char *s; -{ - if (p != NULL) - fprintf (stderr, "%s: 0x%lx: %s (0x%x)\n", bfd_get_filename (info->abfd), - (unsigned long) (p - info->bytes), s, *p); - else - fprintf (stderr, "%s: %s\n", bfd_get_filename (info->abfd), s); -} - -/* Report an unexpected EOF in the IEEE debugging information. */ - -static void -ieee_eof (info) - struct ieee_info *info; -{ - ieee_error (info, (const bfd_byte *) NULL, - "unexpected end of debugging information"); -} - -/* Save a string in memory. */ - -static char * -savestring (start, len) - const char *start; - unsigned long len; -{ - char *ret; - - ret = (char *) xmalloc (len + 1); - memcpy (ret, start, len); - ret[len] = '\0'; - return ret; -} - -/* Read a number which must be present in an IEEE file. */ - -static boolean -ieee_read_number (info, pp, pv) - struct ieee_info *info; - const bfd_byte **pp; - bfd_vma *pv; -{ - return ieee_read_optional_number (info, pp, pv, (boolean *) NULL); -} - -/* Read a number in an IEEE file. If ppresent is not NULL, the number - need not be there. */ - -static boolean -ieee_read_optional_number (info, pp, pv, ppresent) - struct ieee_info *info; - const bfd_byte **pp; - bfd_vma *pv; - boolean *ppresent; -{ - ieee_record_enum_type b; - - if (*pp >= info->pend) - { - if (ppresent != NULL) - { - *ppresent = false; - return true; - } - ieee_eof (info); - return false; - } - - b = (ieee_record_enum_type) **pp; - ++*pp; - - if (b <= ieee_number_end_enum) - { - *pv = (bfd_vma) b; - if (ppresent != NULL) - *ppresent = true; - return true; - } - - if (b >= ieee_number_repeat_start_enum && b <= ieee_number_repeat_end_enum) - { - unsigned int i; - - i = (int) b - (int) ieee_number_repeat_start_enum; - if (*pp + i - 1 >= info->pend) - { - ieee_eof (info); - return false; - } - - *pv = 0; - for (; i > 0; i--) - { - *pv <<= 8; - *pv += **pp; - ++*pp; - } - - if (ppresent != NULL) - *ppresent = true; - - return true; - } - - if (ppresent != NULL) - { - --*pp; - *ppresent = false; - return true; - } - - ieee_error (info, *pp - 1, "invalid number"); - return false; -} - -/* Read a required string from an IEEE file. */ - -static boolean -ieee_read_id (info, pp, pname, pnamlen) - struct ieee_info *info; - const bfd_byte **pp; - const char **pname; - unsigned long *pnamlen; -{ - return ieee_read_optional_id (info, pp, pname, pnamlen, (boolean *) NULL); -} - -/* Read a string from an IEEE file. If ppresent is not NULL, the - string is optional. */ - -static boolean -ieee_read_optional_id (info, pp, pname, pnamlen, ppresent) - struct ieee_info *info; - const bfd_byte **pp; - const char **pname; - unsigned long *pnamlen; - boolean *ppresent; -{ - bfd_byte b; - unsigned long len; - - if (*pp >= info->pend) - { - ieee_eof (info); - return false; - } - - b = **pp; - ++*pp; - - if (b <= 0x7f) - len = b; - else if ((ieee_record_enum_type) b == ieee_extension_length_1_enum) - { - len = **pp; - ++*pp; - } - else if ((ieee_record_enum_type) b == ieee_extension_length_2_enum) - { - len = (**pp << 8) + (*pp)[1]; - *pp += 2; - } - else - { - if (ppresent != NULL) - { - --*pp; - *ppresent = false; - return true; - } - ieee_error (info, *pp - 1, "invalid string length"); - return false; - } - - if ((unsigned long) (info->pend - *pp) < len) - { - ieee_eof (info); - return false; - } - - *pname = (const char *) *pp; - *pnamlen = len; - *pp += len; - - if (ppresent != NULL) - *ppresent = true; - - return true; -} - -/* Read an expression from an IEEE file. Since this code is only used - to parse debugging information, I haven't bothered to write a full - blown IEEE expression parser. I've only thrown in the things I've - seen in debugging information. This can be easily extended if - necessary. */ - -static boolean -ieee_read_expression (info, pp, pv) - struct ieee_info *info; - const bfd_byte **pp; - bfd_vma *pv; -{ - const bfd_byte *expr_start; -#define EXPR_STACK_SIZE (10) - bfd_vma expr_stack[EXPR_STACK_SIZE]; - bfd_vma *esp; - - expr_start = *pp; - - esp = expr_stack; - - while (1) - { - const bfd_byte *start; - bfd_vma val; - boolean present; - ieee_record_enum_type c; - - start = *pp; - - if (! ieee_read_optional_number (info, pp, &val, &present)) - return false; - - if (present) - { - if (esp - expr_stack >= EXPR_STACK_SIZE) - { - ieee_error (info, start, "expression stack overflow"); - return false; - } - *esp++ = val; - continue; - } - - c = (ieee_record_enum_type) **pp; - - if (c >= ieee_module_beginning_enum) - break; - - ++*pp; - - if (c == ieee_comma) - break; - - switch (c) - { - default: - ieee_error (info, start, "unsupported IEEE expression operator"); - break; - - case ieee_variable_R_enum: - { - bfd_vma indx; - asection *s; - - if (! ieee_read_number (info, pp, &indx)) - return false; - for (s = info->abfd->sections; s != NULL; s = s->next) - if ((bfd_vma) s->target_index == indx) - break; - if (s == NULL) - { - ieee_error (info, start, "unknown section"); - return false; - } - - if (esp - expr_stack >= EXPR_STACK_SIZE) - { - ieee_error (info, start, "expression stack overflow"); - return false; - } - - *esp++ = bfd_get_section_vma (info->abfd, s); - } - break; - - case ieee_function_plus_enum: - case ieee_function_minus_enum: - { - bfd_vma v1, v2; - - if (esp - expr_stack < 2) - { - ieee_error (info, start, "expression stack underflow"); - return false; - } - - v1 = *--esp; - v2 = *--esp; - *esp++ = v1 + v2; - } - break; - } - } - - if (esp - 1 != expr_stack) - { - ieee_error (info, expr_start, "expression stack mismatch"); - return false; - } - - *pv = *--esp; - - return true; -} - -/* Return an IEEE builtin type. */ - -static debug_type -ieee_builtin_type (info, p, indx) - struct ieee_info *info; - const bfd_byte *p; - unsigned int indx; -{ - PTR dhandle; - debug_type type; - const char *name; - - if (indx < BUILTIN_TYPE_COUNT - && info->types.builtins[indx] != DEBUG_TYPE_NULL) - return info->types.builtins[indx]; - - dhandle = info->dhandle; - - if (indx >= 32 && indx < 64) - { - type = debug_make_pointer_type (dhandle, - ieee_builtin_type (info, p, indx - 32)); - assert (indx < BUILTIN_TYPE_COUNT); - info->types.builtins[indx] = type; - return type; - } - - switch ((enum builtin_types) indx) - { - default: - ieee_error (info, p, "unknown builtin type"); - return NULL; - - case builtin_unknown: - type = debug_make_void_type (dhandle); - name = NULL; - break; - - case builtin_void: - type = debug_make_void_type (dhandle); - name = "void"; - break; - - case builtin_signed_char: - type = debug_make_int_type (dhandle, 1, false); - name = "signed char"; - break; - - case builtin_unsigned_char: - type = debug_make_int_type (dhandle, 1, true); - name = "unsigned char"; - break; - - case builtin_signed_short_int: - type = debug_make_int_type (dhandle, 2, false); - name = "signed short int"; - break; - - case builtin_unsigned_short_int: - type = debug_make_int_type (dhandle, 2, true); - name = "unsigned short int"; - break; - - case builtin_signed_long: - type = debug_make_int_type (dhandle, 4, false); - name = "signed long"; - break; - - case builtin_unsigned_long: - type = debug_make_int_type (dhandle, 4, true); - name = "unsigned long"; - break; - - case builtin_signed_long_long: - type = debug_make_int_type (dhandle, 8, false); - name = "signed long long"; - break; - - case builtin_unsigned_long_long: - type = debug_make_int_type (dhandle, 8, true); - name = "unsigned long long"; - break; - - case builtin_float: - type = debug_make_float_type (dhandle, 4); - name = "float"; - break; - - case builtin_double: - type = debug_make_float_type (dhandle, 8); - name = "double"; - break; - - case builtin_long_double: - /* FIXME: The size for this type should depend upon the - processor. */ - type = debug_make_float_type (dhandle, 12); - name = "long double"; - break; - - case builtin_long_long_double: - type = debug_make_float_type (dhandle, 16); - name = "long long double"; - break; - - case builtin_quoted_string: - type = debug_make_array_type (dhandle, - ieee_builtin_type (info, p, - ((unsigned int) - builtin_char)), - ieee_builtin_type (info, p, - ((unsigned int) - builtin_int)), - 0, -1, true); - name = "QUOTED STRING"; - break; - - case builtin_instruction_address: - /* FIXME: This should be a code address. */ - type = debug_make_int_type (dhandle, 4, true); - name = "instruction address"; - break; - - case builtin_int: - /* FIXME: The size for this type should depend upon the - processor. */ - type = debug_make_int_type (dhandle, 4, false); - name = "int"; - break; - - case builtin_unsigned: - /* FIXME: The size for this type should depend upon the - processor. */ - type = debug_make_int_type (dhandle, 4, true); - name = "unsigned"; - break; - - case builtin_unsigned_int: - /* FIXME: The size for this type should depend upon the - processor. */ - type = debug_make_int_type (dhandle, 4, true); - name = "unsigned int"; - break; - - case builtin_char: - type = debug_make_int_type (dhandle, 1, false); - name = "char"; - break; - - case builtin_long: - type = debug_make_int_type (dhandle, 4, false); - name = "long"; - break; - - case builtin_short: - type = debug_make_int_type (dhandle, 2, false); - name = "short"; - break; - - case builtin_unsigned_short: - type = debug_make_int_type (dhandle, 2, true); - name = "unsigned short"; - break; - - case builtin_short_int: - type = debug_make_int_type (dhandle, 2, false); - name = "short int"; - break; - - case builtin_signed_short: - type = debug_make_int_type (dhandle, 2, false); - name = "signed short"; - break; - - case builtin_bcd_float: - ieee_error (info, p, "BCD float type not supported"); - return DEBUG_TYPE_NULL; - } - - if (name != NULL) - type = debug_name_type (dhandle, name, type); - - assert (indx < BUILTIN_TYPE_COUNT); - - info->types.builtins[indx] = type; - - return type; -} - -/* Allocate more space in the type table. If ref is true, this is a - reference to the type; if it is not already defined, we should set - up an indirect type. */ - -static boolean -ieee_alloc_type (info, indx, ref) - struct ieee_info *info; - unsigned int indx; - boolean ref; -{ - unsigned int nalloc; - register struct ieee_type *t; - struct ieee_type *tend; - - if (indx >= info->types.alloc) - { - nalloc = info->types.alloc; - if (nalloc == 0) - nalloc = 4; - while (indx >= nalloc) - nalloc *= 2; - - info->types.types = ((struct ieee_type *) - xrealloc (info->types.types, - nalloc * sizeof *info->types.types)); - - memset (info->types.types + info->types.alloc, 0, - (nalloc - info->types.alloc) * sizeof *info->types.types); - - tend = info->types.types + nalloc; - for (t = info->types.types + info->types.alloc; t < tend; t++) - t->type = DEBUG_TYPE_NULL; - - info->types.alloc = nalloc; - } - - if (ref) - { - t = info->types.types + indx; - if (t->type == NULL) - { - t->pslot = (debug_type *) xmalloc (sizeof *t->pslot); - *t->pslot = DEBUG_TYPE_NULL; - t->type = debug_make_indirect_type (info->dhandle, t->pslot, - (const char *) NULL); - if (t->type == NULL) - return false; - } - } - - return true; -} - -/* Read a type index and return the corresponding type. */ - -static boolean -ieee_read_type_index (info, pp, ptype) - struct ieee_info *info; - const bfd_byte **pp; - debug_type *ptype; -{ - const bfd_byte *start; - bfd_vma indx; - - start = *pp; - - if (! ieee_read_number (info, pp, &indx)) - return false; - - if (indx < 256) - { - *ptype = ieee_builtin_type (info, start, indx); - if (*ptype == NULL) - return false; - return true; - } - - indx -= 256; - if (! ieee_alloc_type (info, indx, true)) - return false; - - *ptype = info->types.types[indx].type; - - return true; -} - -/* Parse IEEE debugging information for a file. This is passed the - bytes which compose the Debug Information Part of an IEEE file. */ - -boolean -parse_ieee (dhandle, abfd, bytes, len) - PTR dhandle; - bfd *abfd; - const bfd_byte *bytes; - bfd_size_type len; -{ - struct ieee_info info; - unsigned int i; - const bfd_byte *p, *pend; - - info.dhandle = dhandle; - info.abfd = abfd; - info.bytes = bytes; - info.pend = bytes + len; - info.blockstack.bsp = info.blockstack.stack; - info.saw_filename = false; - info.vars.alloc = 0; - info.vars.vars = NULL; - info.types.alloc = 0; - info.types.types = NULL; - info.tags = NULL; - for (i = 0; i < BUILTIN_TYPE_COUNT; i++) - info.types.builtins[i] = DEBUG_TYPE_NULL; - - p = bytes; - pend = info.pend; - while (p < pend) - { - const bfd_byte *record_start; - ieee_record_enum_type c; - - record_start = p; - - c = (ieee_record_enum_type) *p++; - - if (c == ieee_at_record_enum) - c = (ieee_record_enum_type) (((unsigned int) c << 8) | *p++); - - if (c <= ieee_number_repeat_end_enum) - { - ieee_error (&info, record_start, "unexpected number"); - return false; - } - - switch (c) - { - default: - ieee_error (&info, record_start, "unexpected record type"); - return false; - - case ieee_bb_record_enum: - if (! parse_ieee_bb (&info, &p)) - return false; - break; - - case ieee_be_record_enum: - if (! parse_ieee_be (&info, &p)) - return false; - break; - - case ieee_nn_record: - if (! parse_ieee_nn (&info, &p)) - return false; - break; - - case ieee_ty_record_enum: - if (! parse_ieee_ty (&info, &p)) - return false; - break; - - case ieee_atn_record_enum: - if (! parse_ieee_atn (&info, &p)) - return false; - break; - } - } - - if (info.blockstack.bsp != info.blockstack.stack) - { - ieee_error (&info, (const bfd_byte *) NULL, - "blocks left on stack at end"); - return false; - } - - return true; -} - -/* Handle an IEEE BB record. */ - -static boolean -parse_ieee_bb (info, pp) - struct ieee_info *info; - const bfd_byte **pp; -{ - const bfd_byte *block_start; - bfd_byte b; - bfd_vma size; - const char *name; - unsigned long namlen; - char *namcopy = NULL; - unsigned int fnindx; - boolean skip; - - block_start = *pp; - - b = **pp; - ++*pp; - - if (! ieee_read_number (info, pp, &size) - || ! ieee_read_id (info, pp, &name, &namlen)) - return false; - - fnindx = (unsigned int) -1; - skip = false; - - switch (b) - { - case 1: - /* BB1: Type definitions local to a module. */ - namcopy = savestring (name, namlen); - if (namcopy == NULL) - return false; - if (! debug_set_filename (info->dhandle, namcopy)) - return false; - info->saw_filename = true; - - /* Discard any variables or types we may have seen before. */ - if (info->vars.vars != NULL) - free (info->vars.vars); - info->vars.vars = NULL; - info->vars.alloc = 0; - if (info->types.types != NULL) - free (info->types.types); - info->types.types = NULL; - info->types.alloc = 0; - - /* Initialize the types to the global types. */ - if (info->global_types != NULL) - { - info->types.alloc = info->global_types->alloc; - info->types.types = ((struct ieee_type *) - xmalloc (info->types.alloc - * sizeof (*info->types.types))); - memcpy (info->types.types, info->global_types->types, - info->types.alloc * sizeof (*info->types.types)); - } - - break; - - case 2: - /* BB2: Global type definitions. The name is supposed to be - empty, but we don't check. */ - if (! debug_set_filename (info->dhandle, "*global*")) - return false; - info->saw_filename = true; - break; - - case 3: - /* BB3: High level module block begin. We don't have to do - anything here. The name is supposed to be the same as for - the BB1, but we don't check. */ - break; - - case 4: - /* BB4: Global function. */ - { - bfd_vma stackspace, typindx, offset; - debug_type return_type; - - if (! ieee_read_number (info, pp, &stackspace) - || ! ieee_read_number (info, pp, &typindx) - || ! ieee_read_expression (info, pp, &offset)) - return false; - - /* We have no way to record the stack space. FIXME. */ - - if (typindx < 256) - { - return_type = ieee_builtin_type (info, block_start, typindx); - if (return_type == DEBUG_TYPE_NULL) - return false; - } - else - { - typindx -= 256; - if (! ieee_alloc_type (info, typindx, true)) - return false; - fnindx = typindx; - return_type = info->types.types[typindx].type; - if (debug_get_type_kind (info->dhandle, return_type) - == DEBUG_KIND_FUNCTION) - return_type = debug_get_return_type (info->dhandle, - return_type); - } - - namcopy = savestring (name, namlen); - if (namcopy == NULL) - return false; - if (! debug_record_function (info->dhandle, namcopy, return_type, - true, offset)) - return false; - } - break; - - case 5: - /* BB5: File name for source line numbers. */ - { - unsigned int i; - - /* We ignore the date and time. FIXME. */ - for (i = 0; i < 6; i++) - { - bfd_vma ignore; - boolean present; - - if (! ieee_read_optional_number (info, pp, &ignore, &present)) - return false; - if (! present) - break; - } - - namcopy = savestring (name, namlen); - if (namcopy == NULL) - return false; - if (! debug_start_source (info->dhandle, namcopy)) - return false; - } - break; - - case 6: - /* BB6: Local function or block. */ - { - bfd_vma stackspace, typindx, offset; - - if (! ieee_read_number (info, pp, &stackspace) - || ! ieee_read_number (info, pp, &typindx) - || ! ieee_read_expression (info, pp, &offset)) - return false; - - /* We have no way to record the stack space. FIXME. */ - - if (namlen == 0) - { - if (! debug_start_block (info->dhandle, offset)) - return false; - /* Change b to indicate that this is a block - rather than a function. */ - b = 0x86; - } - else - { - /* The MRI C++ compiler will output a fake function named - __XRYCPP to hold C++ debugging information. We skip - that function. This is not crucial, but it makes - converting from IEEE to other debug formats work - better. */ - if (strncmp (name, "__XRYCPP", namlen) == 0) - skip = true; - else - { - debug_type return_type; - - if (typindx < 256) - { - return_type = ieee_builtin_type (info, block_start, - typindx); - if (return_type == NULL) - return false; - } - else - { - typindx -= 256; - if (! ieee_alloc_type (info, typindx, true)) - return false; - fnindx = typindx; - return_type = info->types.types[typindx].type; - if (debug_get_type_kind (info->dhandle, return_type) - == DEBUG_KIND_FUNCTION) - return_type = debug_get_return_type (info->dhandle, - return_type); - } - - namcopy = savestring (name, namlen); - if (namcopy == NULL) - return false; - if (! debug_record_function (info->dhandle, namcopy, - return_type, false, offset)) - return false; - } - } - } - break; - - case 10: - /* BB10: Assembler module scope. In the normal case, we - completely ignore all this information. FIXME. */ - { - const char *inam, *vstr; - unsigned long inamlen, vstrlen; - bfd_vma tool_type; - boolean present; - unsigned int i; - - if (! info->saw_filename) - { - namcopy = savestring (name, namlen); - if (namcopy == NULL) - return false; - if (! debug_set_filename (info->dhandle, namcopy)) - return false; - info->saw_filename = true; - } - - if (! ieee_read_id (info, pp, &inam, &inamlen) - || ! ieee_read_number (info, pp, &tool_type) - || ! ieee_read_optional_id (info, pp, &vstr, &vstrlen, &present)) - return false; - for (i = 0; i < 6; i++) - { - bfd_vma ignore; - - if (! ieee_read_optional_number (info, pp, &ignore, &present)) - return false; - if (! present) - break; - } - } - break; - - case 11: - /* BB11: Module section. We completely ignore all this - information. FIXME. */ - { - bfd_vma sectype, secindx, offset, map; - boolean present; - - if (! ieee_read_number (info, pp, §ype) - || ! ieee_read_number (info, pp, &secindx) - || ! ieee_read_expression (info, pp, &offset) - || ! ieee_read_optional_number (info, pp, &map, &present)) - return false; - } - break; - - default: - ieee_error (info, block_start, "unknown BB type"); - return false; - } - - - /* Push this block on the block stack. */ - - if (info->blockstack.bsp >= info->blockstack.stack + BLOCKSTACK_SIZE) - { - ieee_error (info, (const bfd_byte *) NULL, "stack overflow"); - return false; - } - - info->blockstack.bsp->kind = b; - if (b == 5) - info->blockstack.bsp->filename = namcopy; - info->blockstack.bsp->fnindx = fnindx; - info->blockstack.bsp->skip = skip; - ++info->blockstack.bsp; - - return true; -} - -/* Handle an IEEE BE record. */ - -static boolean -parse_ieee_be (info, pp) - struct ieee_info *info; - const bfd_byte **pp; -{ - bfd_vma offset; - - if (info->blockstack.bsp <= info->blockstack.stack) - { - ieee_error (info, *pp, "stack underflow"); - return false; - } - --info->blockstack.bsp; - - switch (info->blockstack.bsp->kind) - { - case 2: - /* When we end the global typedefs block, we copy out the the - contents of info->vars. This is because the variable indices - may be reused in the local blocks. However, we need to - preserve them so that we can locate a function returning a - reference variable whose type is named in the global typedef - block. */ - info->global_vars = ((struct ieee_vars *) - xmalloc (sizeof *info->global_vars)); - info->global_vars->alloc = info->vars.alloc; - info->global_vars->vars = ((struct ieee_var *) - xmalloc (info->vars.alloc - * sizeof (*info->vars.vars))); - memcpy (info->global_vars->vars, info->vars.vars, - info->vars.alloc * sizeof (*info->vars.vars)); - - /* We also copy out the non builtin parts of info->types, since - the types are discarded when we start a new block. */ - info->global_types = ((struct ieee_types *) - xmalloc (sizeof *info->global_types)); - info->global_types->alloc = info->types.alloc; - info->global_types->types = ((struct ieee_type *) - xmalloc (info->types.alloc - * sizeof (*info->types.types))); - memcpy (info->global_types->types, info->types.types, - info->types.alloc * sizeof (*info->types.types)); - memset (info->global_types->builtins, 0, - sizeof (info->global_types->builtins)); - - break; - - case 4: - case 6: - if (! ieee_read_expression (info, pp, &offset)) - return false; - if (! info->blockstack.bsp->skip) - { - if (! debug_end_function (info->dhandle, offset + 1)) - return false; - } - break; - - case 0x86: - /* This is BE6 when BB6 started a block rather than a local - function. */ - if (! ieee_read_expression (info, pp, &offset)) - return false; - if (! debug_end_block (info->dhandle, offset + 1)) - return false; - break; - - case 5: - /* When we end a BB5, we look up the stack for the last BB5, if - there is one, so that we can call debug_start_source. */ - if (info->blockstack.bsp > info->blockstack.stack) - { - struct ieee_block *bl; - - bl = info->blockstack.bsp; - do - { - --bl; - if (bl->kind == 5) - { - if (! debug_start_source (info->dhandle, bl->filename)) - return false; - break; - } - } - while (bl != info->blockstack.stack); - } - break; - - case 11: - if (! ieee_read_expression (info, pp, &offset)) - return false; - /* We just ignore the module size. FIXME. */ - break; - - default: - /* Other block types do not have any trailing information. */ - break; - } - - return true; -} - -/* Parse an NN record. */ - -static boolean -parse_ieee_nn (info, pp) - struct ieee_info *info; - const bfd_byte **pp; -{ - const bfd_byte *nn_start; - bfd_vma varindx; - const char *name; - unsigned long namlen; - - nn_start = *pp; - - if (! ieee_read_number (info, pp, &varindx) - || ! ieee_read_id (info, pp, &name, &namlen)) - return false; - - if (varindx < 32) - { - ieee_error (info, nn_start, "illegal variable index"); - return false; - } - varindx -= 32; - - if (varindx >= info->vars.alloc) - { - unsigned int alloc; - - alloc = info->vars.alloc; - if (alloc == 0) - alloc = 4; - while (varindx >= alloc) - alloc *= 2; - info->vars.vars = ((struct ieee_var *) - xrealloc (info->vars.vars, - alloc * sizeof *info->vars.vars)); - memset (info->vars.vars + info->vars.alloc, 0, - (alloc - info->vars.alloc) * sizeof *info->vars.vars); - info->vars.alloc = alloc; - } - - info->vars.vars[varindx].name = name; - info->vars.vars[varindx].namlen = namlen; - - return true; -} - -/* Parse a TY record. */ - -static boolean -parse_ieee_ty (info, pp) - struct ieee_info *info; - const bfd_byte **pp; -{ - const bfd_byte *ty_start, *ty_var_start, *ty_code_start; - bfd_vma typeindx, varindx, tc; - PTR dhandle; - boolean tag, typdef; - debug_type *arg_slots; - unsigned long type_bitsize; - debug_type type; - - ty_start = *pp; - - if (! ieee_read_number (info, pp, &typeindx)) - return false; - - if (typeindx < 256) - { - ieee_error (info, ty_start, "illegal type index"); - return false; - } - - typeindx -= 256; - if (! ieee_alloc_type (info, typeindx, false)) - return false; - - if (**pp != 0xce) - { - ieee_error (info, *pp, "unknown TY code"); - return false; - } - ++*pp; - - ty_var_start = *pp; - - if (! ieee_read_number (info, pp, &varindx)) - return false; - - if (varindx < 32) - { - ieee_error (info, ty_var_start, "illegal variable index"); - return false; - } - varindx -= 32; - - if (varindx >= info->vars.alloc || info->vars.vars[varindx].name == NULL) - { - ieee_error (info, ty_var_start, "undefined variable in TY"); - return false; - } - - ty_code_start = *pp; - - if (! ieee_read_number (info, pp, &tc)) - return false; - - dhandle = info->dhandle; - - tag = false; - typdef = false; - arg_slots = NULL; - type_bitsize = 0; - switch (tc) - { - default: - ieee_error (info, ty_code_start, "unknown TY code"); - return false; - - case '!': - /* Unknown type, with size. We treat it as int. FIXME. */ - { - bfd_vma size; - - if (! ieee_read_number (info, pp, &size)) - return false; - type = debug_make_int_type (dhandle, size, false); - } - break; - - case 'A': /* Array. */ - case 'a': /* FORTRAN array in column/row order. FIXME: Not - distinguished from normal array. */ - { - debug_type ele_type; - bfd_vma lower, upper; - - if (! ieee_read_type_index (info, pp, &ele_type) - || ! ieee_read_number (info, pp, &lower) - || ! ieee_read_number (info, pp, &upper)) - return false; - type = debug_make_array_type (dhandle, ele_type, - ieee_builtin_type (info, ty_code_start, - ((unsigned int) - builtin_int)), - (bfd_signed_vma) lower, - (bfd_signed_vma) upper, - false); - } - break; - - case 'E': - /* Simple enumeration. */ - { - bfd_vma size; - unsigned int alloc; - const char **names; - unsigned int c; - bfd_signed_vma *vals; - unsigned int i; - - if (! ieee_read_number (info, pp, &size)) - return false; - /* FIXME: we ignore the enumeration size. */ - - alloc = 10; - names = (const char **) xmalloc (alloc * sizeof *names); - memset (names, 0, alloc * sizeof *names); - c = 0; - while (1) - { - const char *name; - unsigned long namlen; - boolean present; - - if (! ieee_read_optional_id (info, pp, &name, &namlen, &present)) - return false; - if (! present) - break; - - if (c + 1 >= alloc) - { - alloc += 10; - names = ((const char **) - xrealloc (names, alloc * sizeof *names)); - } - - names[c] = savestring (name, namlen); - if (names[c] == NULL) - return false; - ++c; - } - - names[c] = NULL; - - vals = (bfd_signed_vma *) xmalloc (c * sizeof *vals); - for (i = 0; i < c; i++) - vals[i] = i; - - type = debug_make_enum_type (dhandle, names, vals); - tag = true; - } - break; - - case 'G': - /* Struct with bit fields. */ - { - bfd_vma size; - unsigned int alloc; - debug_field *fields; - unsigned int c; - - if (! ieee_read_number (info, pp, &size)) - return false; - - alloc = 10; - fields = (debug_field *) xmalloc (alloc * sizeof *fields); - c = 0; - while (1) - { - const char *name; - unsigned long namlen; - boolean present; - debug_type ftype; - bfd_vma bitpos, bitsize; - - if (! ieee_read_optional_id (info, pp, &name, &namlen, &present)) - return false; - if (! present) - break; - if (! ieee_read_type_index (info, pp, &ftype) - || ! ieee_read_number (info, pp, &bitpos) - || ! ieee_read_number (info, pp, &bitsize)) - return false; - - if (c + 1 >= alloc) - { - alloc += 10; - fields = ((debug_field *) - xrealloc (fields, alloc * sizeof *fields)); - } - - fields[c] = debug_make_field (dhandle, savestring (name, namlen), - ftype, bitpos, bitsize, - DEBUG_VISIBILITY_PUBLIC); - if (fields[c] == NULL) - return false; - ++c; - } - - fields[c] = NULL; - - type = debug_make_struct_type (dhandle, true, size, fields); - tag = true; - } - break; - - case 'N': - /* Enumeration. */ - { - unsigned int alloc; - const char **names; - bfd_signed_vma *vals; - unsigned int c; - - alloc = 10; - names = (const char **) xmalloc (alloc * sizeof *names); - vals = (bfd_signed_vma *) xmalloc (alloc * sizeof *names); - c = 0; - while (1) - { - const char *name; - unsigned long namlen; - boolean present; - bfd_vma val; - - if (! ieee_read_optional_id (info, pp, &name, &namlen, &present)) - return false; - if (! present) - break; - if (! ieee_read_number (info, pp, &val)) - return false; - - /* If the length of the name is zero, then the value is - actually the size of the enum. We ignore this - information. FIXME. */ - if (namlen == 0) - continue; - - if (c + 1 >= alloc) - { - alloc += 10; - names = ((const char **) - xrealloc (names, alloc * sizeof *names)); - vals = ((bfd_signed_vma *) - xrealloc (vals, alloc * sizeof *vals)); - } - - names[c] = savestring (name, namlen); - if (names[c] == NULL) - return false; - vals[c] = (bfd_signed_vma) val; - ++c; - } - - names[c] = NULL; - - type = debug_make_enum_type (dhandle, names, vals); - tag = true; - } - break; - - case 'O': /* Small pointer. We don't distinguish small and large - pointers. FIXME. */ - case 'P': /* Large pointer. */ - { - debug_type t; - - if (! ieee_read_type_index (info, pp, &t)) - return false; - type = debug_make_pointer_type (dhandle, t); - } - break; - - case 'R': - /* Range. */ - { - bfd_vma low, high, signedp, size; - - if (! ieee_read_number (info, pp, &low) - || ! ieee_read_number (info, pp, &high) - || ! ieee_read_number (info, pp, &signedp) - || ! ieee_read_number (info, pp, &size)) - return false; - - type = debug_make_range_type (dhandle, - debug_make_int_type (dhandle, size, - ! signedp), - (bfd_signed_vma) low, - (bfd_signed_vma) high); - } - break; - - case 'S': /* Struct. */ - case 'U': /* Union. */ - { - bfd_vma size; - unsigned int alloc; - debug_field *fields; - unsigned int c; - - if (! ieee_read_number (info, pp, &size)) - return false; - - alloc = 10; - fields = (debug_field *) xmalloc (alloc * sizeof *fields); - c = 0; - while (1) - { - const char *name; - unsigned long namlen; - boolean present; - bfd_vma tindx; - bfd_vma offset; - debug_type ftype; - bfd_vma bitsize; - - if (! ieee_read_optional_id (info, pp, &name, &namlen, &present)) - return false; - if (! present) - break; - if (! ieee_read_number (info, pp, &tindx) - || ! ieee_read_number (info, pp, &offset)) - return false; - - if (tindx < 256) - { - ftype = ieee_builtin_type (info, ty_code_start, tindx); - bitsize = 0; - offset *= 8; - } - else - { - struct ieee_type *t; - - tindx -= 256; - if (! ieee_alloc_type (info, tindx, true)) - return false; - t = info->types.types + tindx; - ftype = t->type; - bitsize = t->bitsize; - if (bitsize == 0) - offset *= 8; - } - - if (c + 1 >= alloc) - { - alloc += 10; - fields = ((debug_field *) - xrealloc (fields, alloc * sizeof *fields)); - } - - fields[c] = debug_make_field (dhandle, savestring (name, namlen), - ftype, offset, bitsize, - DEBUG_VISIBILITY_PUBLIC); - if (fields[c] == NULL) - return false; - ++c; - } - - fields[c] = NULL; - - type = debug_make_struct_type (dhandle, tc == 'S', size, fields); - tag = true; - } - break; - - case 'T': - /* Typedef. */ - if (! ieee_read_type_index (info, pp, &type)) - return false; - typdef = true; - break; - - case 'X': - /* Procedure. FIXME: This is an extern declaration, which we - have no way of representing. */ - { - bfd_vma attr; - debug_type rtype; - bfd_vma nargs; - boolean present; - struct ieee_var *pv; - - /* FIXME: We ignore the attribute and the argument names. */ - - if (! ieee_read_number (info, pp, &attr) - || ! ieee_read_type_index (info, pp, &rtype) - || ! ieee_read_number (info, pp, &nargs)) - return false; - do - { - const char *name; - unsigned long namlen; - - if (! ieee_read_optional_id (info, pp, &name, &namlen, &present)) - return false; - } - while (present); - - pv = info->vars.vars + varindx; - pv->kind = IEEE_EXTERNAL; - if (pv->namlen > 0 - && debug_get_type_kind (dhandle, rtype) == DEBUG_KIND_POINTER) - { - /* Set up the return type as an indirect type pointing to - the variable slot, so that we can change it to a - reference later if appropriate. */ - pv->pslot = (debug_type *) xmalloc (sizeof *pv->pslot); - *pv->pslot = rtype; - rtype = debug_make_indirect_type (dhandle, pv->pslot, - (const char *) NULL); - } - - type = debug_make_function_type (dhandle, rtype, (debug_type *) NULL, - false); - } - break; - - case 'V': - /* Void. This is not documented, but the MRI compiler emits it. */ - type = debug_make_void_type (dhandle); - break; - - case 'Z': - /* Array with 0 lower bound. */ - { - debug_type etype; - bfd_vma high; - - if (! ieee_read_type_index (info, pp, &etype) - || ! ieee_read_number (info, pp, &high)) - return false; - - type = debug_make_array_type (dhandle, etype, - ieee_builtin_type (info, ty_code_start, - ((unsigned int) - builtin_int)), - 0, (bfd_signed_vma) high, false); - } - break; - - case 'c': /* Complex. */ - case 'd': /* Double complex. */ - { - const char *name; - unsigned long namlen; - - /* FIXME: I don't know what the name means. */ - - if (! ieee_read_id (info, pp, &name, &namlen)) - return false; - - type = debug_make_complex_type (dhandle, tc == 'c' ? 4 : 8); - } - break; - - case 'f': - /* Pascal file name. FIXME. */ - ieee_error (info, ty_code_start, "Pascal file name not supported"); - return false; - - case 'g': - /* Bitfield type. */ - { - bfd_vma signedp, bitsize, dummy; - const bfd_byte *hold; - boolean present; - - if (! ieee_read_number (info, pp, &signedp) - || ! ieee_read_number (info, pp, &bitsize)) - return false; - - /* I think the documentation says that there is a type index, - but some actual files do not have one. */ - hold = *pp; - if (! ieee_read_optional_number (info, pp, &dummy, &present)) - return false; - if (! present) - { - /* FIXME: This is just a guess. */ - type = debug_make_int_type (dhandle, 4, - signedp ? false : true); - } - else - { - *pp = hold; - if (! ieee_read_type_index (info, pp, &type)) - return false; - } - type_bitsize = bitsize; - } - break; - - case 'n': - /* Qualifier. */ - { - bfd_vma kind; - debug_type t; - - if (! ieee_read_number (info, pp, &kind) - || ! ieee_read_type_index (info, pp, &t)) - return false; - - switch (kind) - { - default: - ieee_error (info, ty_start, "unsupported qualifer"); - return false; - - case 1: - type = debug_make_const_type (dhandle, t); - break; - - case 2: - type = debug_make_volatile_type (dhandle, t); - break; - } - } - break; - - case 's': - /* Set. */ - { - bfd_vma size; - debug_type etype; - - if (! ieee_read_number (info, pp, &size) - || ! ieee_read_type_index (info, pp, &etype)) - return false; - - /* FIXME: We ignore the size. */ - - type = debug_make_set_type (dhandle, etype, false); - } - break; - - case 'x': - /* Procedure with compiler dependencies. */ - { - struct ieee_var *pv; - bfd_vma attr, frame_type, push_mask, nargs, level, father; - debug_type rtype; - debug_type *arg_types; - boolean varargs; - boolean present; - - /* FIXME: We ignore some of this information. */ - - pv = info->vars.vars + varindx; - - if (! ieee_read_number (info, pp, &attr) - || ! ieee_read_number (info, pp, &frame_type) - || ! ieee_read_number (info, pp, &push_mask) - || ! ieee_read_type_index (info, pp, &rtype) - || ! ieee_read_number (info, pp, &nargs)) - return false; - if (nargs == (bfd_vma) -1) - { - arg_types = NULL; - varargs = false; - } - else - { - unsigned int i; - - arg_types = ((debug_type *) - xmalloc ((nargs + 1) * sizeof *arg_types)); - for (i = 0; i < nargs; i++) - if (! ieee_read_type_index (info, pp, arg_types + i)) - return false; - - /* If the last type is pointer to void, this is really a - varargs function. */ - varargs = false; - if (nargs > 0) - { - debug_type last; - - last = arg_types[nargs - 1]; - if (debug_get_type_kind (dhandle, last) == DEBUG_KIND_POINTER - && (debug_get_type_kind (dhandle, - debug_get_target_type (dhandle, - last)) - == DEBUG_KIND_VOID)) - { - --nargs; - varargs = true; - } - } - - /* If there are any pointer arguments, turn them into - indirect types in case we later need to convert them to - reference types. */ - for (i = 0; i < nargs; i++) - { - if (debug_get_type_kind (dhandle, arg_types[i]) - == DEBUG_KIND_POINTER) - { - if (arg_slots == NULL) - { - arg_slots = ((debug_type *) - xmalloc (nargs * sizeof *arg_slots)); - memset (arg_slots, 0, nargs * sizeof *arg_slots); - } - arg_slots[i] = arg_types[i]; - arg_types[i] = - debug_make_indirect_type (dhandle, - arg_slots + i, - (const char *) NULL); - } - } - - arg_types[nargs] = DEBUG_TYPE_NULL; - } - if (! ieee_read_number (info, pp, &level) - || ! ieee_read_optional_number (info, pp, &father, &present)) - return false; - - /* We can't distinguish between a global function and a static - function. */ - pv->kind = IEEE_FUNCTION; - - if (pv->namlen > 0 - && debug_get_type_kind (dhandle, rtype) == DEBUG_KIND_POINTER) - { - /* Set up the return type as an indirect type pointing to - the variable slot, so that we can change it to a - reference later if appropriate. */ - pv->pslot = (debug_type *) xmalloc (sizeof *pv->pslot); - *pv->pslot = rtype; - rtype = debug_make_indirect_type (dhandle, pv->pslot, - (const char *) NULL); - } - - type = debug_make_function_type (dhandle, rtype, arg_types, varargs); - } - break; - } - - /* Record the type in the table. */ - - if (type == DEBUG_TYPE_NULL) - return false; - - info->vars.vars[varindx].type = type; - - if ((tag || typdef) - && info->vars.vars[varindx].namlen > 0) - { - const char *name; - - name = savestring (info->vars.vars[varindx].name, - info->vars.vars[varindx].namlen); - if (typdef) - type = debug_name_type (dhandle, name, type); - else if (tc == 'E' || tc == 'N') - type = debug_tag_type (dhandle, name, type); - else - { - struct ieee_tag *it; - - /* We must allocate all struct tags as indirect types, so - that if we later see a definition of the tag as a C++ - record we can update the indirect slot and automatically - change all the existing references. */ - it = (struct ieee_tag *) xmalloc (sizeof *it); - memset (it, 0, sizeof *it); - it->next = info->tags; - info->tags = it; - it->name = name; - it->slot = type; - - type = debug_make_indirect_type (dhandle, &it->slot, name); - type = debug_tag_type (dhandle, name, type); - - it->type = type; - } - if (type == NULL) - return false; - } - - info->types.types[typeindx].type = type; - info->types.types[typeindx].arg_slots = arg_slots; - info->types.types[typeindx].bitsize = type_bitsize; - - /* We may have already allocated type as an indirect type pointing - to slot. It does no harm to replace the indirect type with the - real type. Filling in slot as well handles the indirect types - which are already hanging around. */ - if (info->types.types[typeindx].pslot != NULL) - *info->types.types[typeindx].pslot = type; - - return true; -} - -/* Parse an ATN record. */ - -static boolean -parse_ieee_atn (info, pp) - struct ieee_info *info; - const bfd_byte **pp; -{ - const bfd_byte *atn_start, *atn_code_start; - bfd_vma varindx; - struct ieee_var *pvar; - debug_type type; - bfd_vma atn_code; - PTR dhandle; - bfd_vma v, v2, v3, v4, v5; - const char *name; - unsigned long namlen; - char *namcopy; - boolean present; - int blocktype; - - atn_start = *pp; - - if (! ieee_read_number (info, pp, &varindx) - || ! ieee_read_type_index (info, pp, &type)) - return false; - - atn_code_start = *pp; - - if (! ieee_read_number (info, pp, &atn_code)) - return false; - - if (varindx == 0) - { - pvar = NULL; - name = ""; - namlen = 0; - } - else if (varindx < 32) - { - ieee_error (info, atn_start, "illegal variable index"); - return false; - } - else - { - varindx -= 32; - if (varindx >= info->vars.alloc - || info->vars.vars[varindx].name == NULL) - { - /* The MRI compiler or linker sometimes omits the NN record - for a pmisc record. */ - if (atn_code == 62) - { - if (varindx >= info->vars.alloc) - { - unsigned int alloc; - - alloc = info->vars.alloc; - if (alloc == 0) - alloc = 4; - while (varindx >= alloc) - alloc *= 2; - info->vars.vars = ((struct ieee_var *) - xrealloc (info->vars.vars, - (alloc - * sizeof *info->vars.vars))); - memset (info->vars.vars + info->vars.alloc, 0, - ((alloc - info->vars.alloc) - * sizeof *info->vars.vars)); - info->vars.alloc = alloc; - } - - pvar = info->vars.vars + varindx; - pvar->name = ""; - pvar->namlen = 0; - } - else - { - ieee_error (info, atn_start, "undefined variable in ATN"); - return false; - } - } - - pvar = info->vars.vars + varindx; - - pvar->type = type; - - name = pvar->name; - namlen = pvar->namlen; - } - - dhandle = info->dhandle; - - /* If we are going to call debug_record_variable with a pointer - type, change the type to an indirect type so that we can later - change it to a reference type if we encounter a C++ pmisc 'R' - record. */ - if (pvar != NULL - && type != DEBUG_TYPE_NULL - && debug_get_type_kind (dhandle, type) == DEBUG_KIND_POINTER) - { - switch (atn_code) - { - case 1: - case 2: - case 3: - case 5: - case 8: - case 10: - pvar->pslot = (debug_type *) xmalloc (sizeof *pvar->pslot); - *pvar->pslot = type; - type = debug_make_indirect_type (dhandle, pvar->pslot, - (const char *) NULL); - pvar->type = type; - break; - } - } - - switch (atn_code) - { - default: - ieee_error (info, atn_code_start, "unknown ATN type"); - return false; - - case 1: - /* Automatic variable. */ - if (! ieee_read_number (info, pp, &v)) - return false; - namcopy = savestring (name, namlen); - if (type == NULL) - type = debug_make_void_type (dhandle); - if (pvar != NULL) - pvar->kind = IEEE_LOCAL; - return debug_record_variable (dhandle, namcopy, type, DEBUG_LOCAL, v); - - case 2: - /* Register variable. */ - if (! ieee_read_number (info, pp, &v)) - return false; - namcopy = savestring (name, namlen); - if (type == NULL) - type = debug_make_void_type (dhandle); - if (pvar != NULL) - pvar->kind = IEEE_LOCAL; - return debug_record_variable (dhandle, namcopy, type, DEBUG_REGISTER, - ieee_regno_to_genreg (info->abfd, v)); - - case 3: - /* Static variable. */ - if (! ieee_require_asn (info, pp, &v)) - return false; - namcopy = savestring (name, namlen); - if (type == NULL) - type = debug_make_void_type (dhandle); - if (info->blockstack.bsp <= info->blockstack.stack) - blocktype = 0; - else - blocktype = info->blockstack.bsp[-1].kind; - if (pvar != NULL) - { - if (blocktype == 4 || blocktype == 6) - pvar->kind = IEEE_LOCAL; - else - pvar->kind = IEEE_STATIC; - } - return debug_record_variable (dhandle, namcopy, type, - (blocktype == 4 || blocktype == 6 - ? DEBUG_LOCAL_STATIC - : DEBUG_STATIC), - v); - - case 4: - /* External function. We don't currently record these. FIXME. */ - if (pvar != NULL) - pvar->kind = IEEE_EXTERNAL; - return true; - - case 5: - /* External variable. We don't currently record these. FIXME. */ - if (pvar != NULL) - pvar->kind = IEEE_EXTERNAL; - return true; - - case 7: - if (! ieee_read_number (info, pp, &v) - || ! ieee_read_number (info, pp, &v2) - || ! ieee_read_optional_number (info, pp, &v3, &present)) - return false; - if (present) - { - if (! ieee_read_optional_number (info, pp, &v4, &present)) - return false; - } - - /* We just ignore the two optional fields in v3 and v4, since - they are not defined. */ - - if (! ieee_require_asn (info, pp, &v3)) - return false; - - /* We have no way to record the column number. FIXME. */ - - return debug_record_line (dhandle, v, v3); - - case 8: - /* Global variable. */ - if (! ieee_require_asn (info, pp, &v)) - return false; - namcopy = savestring (name, namlen); - if (type == NULL) - type = debug_make_void_type (dhandle); - if (pvar != NULL) - pvar->kind = IEEE_GLOBAL; - return debug_record_variable (dhandle, namcopy, type, DEBUG_GLOBAL, v); - - case 9: - /* Variable lifetime information. */ - if (! ieee_read_number (info, pp, &v)) - return false; - - /* We have no way to record this information. FIXME. */ - return true; - - case 10: - /* Locked register. The spec says that there are two required - fields, but at least on occasion the MRI compiler only emits - one. */ - if (! ieee_read_number (info, pp, &v) - || ! ieee_read_optional_number (info, pp, &v2, &present)) - return false; - - /* I think this means a variable that is both in a register and - a frame slot. We ignore the frame slot. FIXME. */ - - namcopy = savestring (name, namlen); - if (type == NULL) - type = debug_make_void_type (dhandle); - if (pvar != NULL) - pvar->kind = IEEE_LOCAL; - return debug_record_variable (dhandle, namcopy, type, DEBUG_REGISTER, v); - - case 11: - /* Reserved for FORTRAN common. */ - ieee_error (info, atn_code_start, "unsupported ATN11"); - - /* Return true to keep going. */ - return true; - - case 12: - /* Based variable. */ - v3 = 0; - v4 = 0x80; - v5 = 0; - if (! ieee_read_number (info, pp, &v) - || ! ieee_read_number (info, pp, &v2) - || ! ieee_read_optional_number (info, pp, &v3, &present)) - return false; - if (present) - { - if (! ieee_read_optional_number (info, pp, &v4, &present)) - return false; - if (present) - { - if (! ieee_read_optional_number (info, pp, &v5, &present)) - return false; - } - } - - /* We have no way to record this information. FIXME. */ - - ieee_error (info, atn_code_start, "unsupported ATN12"); - - /* Return true to keep going. */ - return true; - - case 16: - /* Constant. The description of this that I have is ambiguous, - so I'm not going to try to implement it. */ - if (! ieee_read_number (info, pp, &v) - || ! ieee_read_optional_number (info, pp, &v2, &present)) - return false; - if (present) - { - if (! ieee_read_optional_number (info, pp, &v2, &present)) - return false; - if (present) - { - if (! ieee_read_optional_id (info, pp, &name, &namlen, &present)) - return false; - } - } - - if ((ieee_record_enum_type) **pp == ieee_e2_first_byte_enum) - { - if (! ieee_require_asn (info, pp, &v3)) - return false; - } - - return true; - - case 19: - /* Static variable from assembler. */ - v2 = 0; - if (! ieee_read_number (info, pp, &v) - || ! ieee_read_optional_number (info, pp, &v2, &present) - || ! ieee_require_asn (info, pp, &v3)) - return false; - namcopy = savestring (name, namlen); - /* We don't really handle this correctly. FIXME. */ - return debug_record_variable (dhandle, namcopy, - debug_make_void_type (dhandle), - v2 != 0 ? DEBUG_GLOBAL : DEBUG_STATIC, - v3); - - case 62: - /* Procedure miscellaneous information. */ - case 63: - /* Variable miscellaneous information. */ - case 64: - /* Module miscellaneous information. */ - if (! ieee_read_number (info, pp, &v) - || ! ieee_read_number (info, pp, &v2) - || ! ieee_read_optional_id (info, pp, &name, &namlen, &present)) - return false; - - if (atn_code == 62 && v == 80) - { - if (present) - { - ieee_error (info, atn_code_start, - "unexpected string in C++ misc"); - return false; - } - return ieee_read_cxx_misc (info, pp, v2); - } - - /* We just ignore all of this stuff. FIXME. */ - - for (; v2 > 0; --v2) - { - switch ((ieee_record_enum_type) **pp) - { - default: - ieee_error (info, *pp, "bad misc record"); - return false; - - case ieee_at_record_enum: - if (! ieee_require_atn65 (info, pp, &name, &namlen)) - return false; - break; - - case ieee_e2_first_byte_enum: - if (! ieee_require_asn (info, pp, &v3)) - return false; - break; - } - } - - return true; - } - - /*NOTREACHED*/ -} - -/* Handle C++ debugging miscellaneous records. This is called for - procedure miscellaneous records of type 80. */ - -static boolean -ieee_read_cxx_misc (info, pp, count) - struct ieee_info *info; - const bfd_byte **pp; - unsigned long count; -{ - const bfd_byte *start; - bfd_vma category; - - start = *pp; - - /* Get the category of C++ misc record. */ - if (! ieee_require_asn (info, pp, &category)) - return false; - --count; - - switch (category) - { - default: - ieee_error (info, start, "unrecognized C++ misc record"); - return false; - - case 'T': - if (! ieee_read_cxx_class (info, pp, count)) - return false; - break; - - case 'M': - { - bfd_vma flags; - const char *name; - unsigned long namlen; - - /* The IEEE spec indicates that the 'M' record only has a - flags field. The MRI compiler also emits the name of the - function. */ - - if (! ieee_require_asn (info, pp, &flags)) - return false; - if (*pp < info->pend - && (ieee_record_enum_type) **pp == ieee_at_record_enum) - { - if (! ieee_require_atn65 (info, pp, &name, &namlen)) - return false; - } - - /* This is emitted for method functions, but I don't think we - care very much. It might help if it told us useful - information like the class with which this function is - associated, but it doesn't, so it isn't helpful. */ - } - break; - - case 'B': - if (! ieee_read_cxx_defaults (info, pp, count)) - return false; - break; - - case 'z': - { - const char *name, *mangled, *class; - unsigned long namlen, mangledlen, classlen; - bfd_vma control; - - /* Pointer to member. */ - - if (! ieee_require_atn65 (info, pp, &name, &namlen) - || ! ieee_require_atn65 (info, pp, &mangled, &mangledlen) - || ! ieee_require_atn65 (info, pp, &class, &classlen) - || ! ieee_require_asn (info, pp, &control)) - return false; - - /* FIXME: We should now track down name and change its type. */ - } - break; - - case 'R': - if (! ieee_read_reference (info, pp)) - return false; - break; - } - - return true; -} - -/* Read a C++ class definition. This is a pmisc type 80 record of - category 'T'. */ - -static boolean -ieee_read_cxx_class (info, pp, count) - struct ieee_info *info; - const bfd_byte **pp; - unsigned long count; -{ - const bfd_byte *start; - bfd_vma class; - const char *tag; - unsigned long taglen; - struct ieee_tag *it; - PTR dhandle; - debug_field *fields; - unsigned int field_count, field_alloc; - debug_baseclass *baseclasses; - unsigned int baseclasses_count, baseclasses_alloc; - const debug_field *structfields; - struct ieee_method - { - const char *name; - unsigned long namlen; - debug_method_variant *variants; - unsigned count; - unsigned int alloc; - } *methods; - unsigned int methods_count, methods_alloc; - debug_type vptrbase; - boolean ownvptr; - debug_method *dmethods; - - start = *pp; - - if (! ieee_require_asn (info, pp, &class)) - return false; - --count; - - if (! ieee_require_atn65 (info, pp, &tag, &taglen)) - return false; - --count; - - /* Find the C struct with this name. */ - for (it = info->tags; it != NULL; it = it->next) - if (it->name[0] == tag[0] - && strncmp (it->name, tag, taglen) == 0 - && strlen (it->name) == taglen) - break; - if (it == NULL) - { - ieee_error (info, start, "undefined C++ object"); - return false; - } - - dhandle = info->dhandle; - - fields = NULL; - field_count = 0; - field_alloc = 0; - baseclasses = NULL; - baseclasses_count = 0; - baseclasses_alloc = 0; - methods = NULL; - methods_count = 0; - methods_alloc = 0; - vptrbase = DEBUG_TYPE_NULL; - ownvptr = false; - - structfields = debug_get_fields (dhandle, it->type); - - while (count > 0) - { - bfd_vma id; - const bfd_byte *spec_start; - - spec_start = *pp; - - if (! ieee_require_asn (info, pp, &id)) - return false; - --count; - - switch (id) - { - default: - ieee_error (info, spec_start, "unrecognized C++ object spec"); - return false; - - case 'b': - { - bfd_vma flags, cinline; - const char *basename, *fieldname; - unsigned long baselen, fieldlen; - char *basecopy; - debug_type basetype; - bfd_vma bitpos; - boolean virtualp; - enum debug_visibility visibility; - debug_baseclass baseclass; - - /* This represents a base or friend class. */ - - if (! ieee_require_asn (info, pp, &flags) - || ! ieee_require_atn65 (info, pp, &basename, &baselen) - || ! ieee_require_asn (info, pp, &cinline) - || ! ieee_require_atn65 (info, pp, &fieldname, &fieldlen)) - return false; - count -= 4; - - /* We have no way of recording friend information, so we - just ignore it. */ - if ((flags & BASEFLAGS_FRIEND) != 0) - break; - - /* I assume that either all of the members of the - baseclass are included in the object, starting at the - beginning of the object, or that none of them are - included. */ - - if ((fieldlen == 0) == (cinline == 0)) - { - ieee_error (info, start, "unsupported C++ object type"); - return false; - } - - basecopy = savestring (basename, baselen); - basetype = debug_find_tagged_type (dhandle, basecopy, - DEBUG_KIND_ILLEGAL); - free (basecopy); - if (basetype == DEBUG_TYPE_NULL) - { - ieee_error (info, start, "C++ base class not defined"); - return false; - } - - if (fieldlen == 0) - bitpos = 0; - else - { - const debug_field *pf; - - if (structfields == NULL) - { - ieee_error (info, start, "C++ object has no fields"); - return false; - } - - for (pf = structfields; *pf != DEBUG_FIELD_NULL; pf++) - { - const char *fname; - - fname = debug_get_field_name (dhandle, *pf); - if (fname == NULL) - return false; - if (fname[0] == fieldname[0] - && strncmp (fname, fieldname, fieldlen) == 0 - && strlen (fname) == fieldlen) - break; - } - if (*pf == DEBUG_FIELD_NULL) - { - ieee_error (info, start, - "C++ base class not found in container"); - return false; - } - - bitpos = debug_get_field_bitpos (dhandle, *pf); - } - - if ((flags & BASEFLAGS_VIRTUAL) != 0) - virtualp = true; - else - virtualp = false; - if ((flags & BASEFLAGS_PRIVATE) != 0) - visibility = DEBUG_VISIBILITY_PRIVATE; - else - visibility = DEBUG_VISIBILITY_PUBLIC; - - baseclass = debug_make_baseclass (dhandle, basetype, bitpos, - virtualp, visibility); - if (baseclass == DEBUG_BASECLASS_NULL) - return false; - - if (baseclasses_count + 1 >= baseclasses_alloc) - { - baseclasses_alloc += 10; - baseclasses = ((debug_baseclass *) - xrealloc (baseclasses, - (baseclasses_alloc - * sizeof *baseclasses))); - } - - baseclasses[baseclasses_count] = baseclass; - ++baseclasses_count; - baseclasses[baseclasses_count] = DEBUG_BASECLASS_NULL; - } - break; - - case 'd': - { - bfd_vma flags; - const char *fieldname, *mangledname; - unsigned long fieldlen, mangledlen; - char *fieldcopy; - boolean staticp; - debug_type ftype; - const debug_field *pf = NULL; - enum debug_visibility visibility; - debug_field field; - - /* This represents a data member. */ - - if (! ieee_require_asn (info, pp, &flags) - || ! ieee_require_atn65 (info, pp, &fieldname, &fieldlen) - || ! ieee_require_atn65 (info, pp, &mangledname, &mangledlen)) - return false; - count -= 3; - - fieldcopy = savestring (fieldname, fieldlen); - - staticp = (flags & CXXFLAGS_STATIC) != 0 ? true : false; - - if (staticp) - { - struct ieee_var *pv, *pvend; - - /* See if we can find a definition for this variable. */ - pv = info->vars.vars; - pvend = pv + info->vars.alloc; - for (; pv < pvend; pv++) - if (pv->namlen == mangledlen - && strncmp (pv->name, mangledname, mangledlen) == 0) - break; - if (pv < pvend) - ftype = pv->type; - else - { - /* This can happen if the variable is never used. */ - ftype = ieee_builtin_type (info, start, - (unsigned int) builtin_void); - } - } - else - { - unsigned int findx; - - if (structfields == NULL) - { - ieee_error (info, start, "C++ object has no fields"); - return false; - } - - for (pf = structfields, findx = 0; - *pf != DEBUG_FIELD_NULL; - pf++, findx++) - { - const char *fname; - - fname = debug_get_field_name (dhandle, *pf); - if (fname == NULL) - return false; - if (fname[0] == mangledname[0] - && strncmp (fname, mangledname, mangledlen) == 0 - && strlen (fname) == mangledlen) - break; - } - if (*pf == DEBUG_FIELD_NULL) - { - ieee_error (info, start, - "C++ data member not found in container"); - return false; - } - - ftype = debug_get_field_type (dhandle, *pf); - - if (debug_get_type_kind (dhandle, ftype) == DEBUG_KIND_POINTER) - { - /* We might need to convert this field into a - reference type later on, so make it an indirect - type. */ - if (it->fslots == NULL) - { - unsigned int fcnt; - const debug_field *pfcnt; - - fcnt = 0; - for (pfcnt = structfields; - *pfcnt != DEBUG_FIELD_NULL; - pfcnt++) - ++fcnt; - it->fslots = ((debug_type *) - xmalloc (fcnt * sizeof *it->fslots)); - memset (it->fslots, 0, - fcnt * sizeof *it->fslots); - } - - if (ftype == DEBUG_TYPE_NULL) - return false; - it->fslots[findx] = ftype; - ftype = debug_make_indirect_type (dhandle, - it->fslots + findx, - (const char *) NULL); - } - } - if (ftype == DEBUG_TYPE_NULL) - return false; - - switch (flags & CXXFLAGS_VISIBILITY) - { - default: - ieee_error (info, start, "unknown C++ visibility"); - return false; - - case CXXFLAGS_VISIBILITY_PUBLIC: - visibility = DEBUG_VISIBILITY_PUBLIC; - break; - - case CXXFLAGS_VISIBILITY_PRIVATE: - visibility = DEBUG_VISIBILITY_PRIVATE; - break; - - case CXXFLAGS_VISIBILITY_PROTECTED: - visibility = DEBUG_VISIBILITY_PROTECTED; - break; - } - - if (staticp) - { - char *mangledcopy; - - mangledcopy = savestring (mangledname, mangledlen); - - field = debug_make_static_member (dhandle, fieldcopy, - ftype, mangledcopy, - visibility); - } - else - { - bfd_vma bitpos, bitsize; - - bitpos = debug_get_field_bitpos (dhandle, *pf); - bitsize = debug_get_field_bitsize (dhandle, *pf); - if (bitpos == (bfd_vma) -1 || bitsize == (bfd_vma) -1) - { - ieee_error (info, start, "bad C++ field bit pos or size"); - return false; - } - field = debug_make_field (dhandle, fieldcopy, ftype, bitpos, - bitsize, visibility); - } - - if (field == DEBUG_FIELD_NULL) - return false; - - if (field_count + 1 >= field_alloc) - { - field_alloc += 10; - fields = ((debug_field *) - xrealloc (fields, field_alloc * sizeof *fields)); - } - - fields[field_count] = field; - ++field_count; - fields[field_count] = DEBUG_FIELD_NULL; - } - break; - - case 'm': - case 'v': - { - bfd_vma flags, voffset, control; - const char *name, *mangled; - unsigned long namlen, mangledlen; - struct ieee_var *pv, *pvend; - debug_type type; - enum debug_visibility visibility; - boolean constp, volatilep; - char *mangledcopy; - debug_method_variant mv; - struct ieee_method *meth; - unsigned int im; - - if (! ieee_require_asn (info, pp, &flags) - || ! ieee_require_atn65 (info, pp, &name, &namlen) - || ! ieee_require_atn65 (info, pp, &mangled, &mangledlen)) - return false; - count -= 3; - if (id != 'v') - voffset = 0; - else - { - if (! ieee_require_asn (info, pp, &voffset)) - return false; - --count; - } - if (! ieee_require_asn (info, pp, &control)) - return false; - --count; - - /* We just ignore the control information. */ - - /* We have no way to represent friend information, so we - just ignore it. */ - if ((flags & CXXFLAGS_FRIEND) != 0) - break; - - /* We should already have seen a type for the function. */ - pv = info->vars.vars; - pvend = pv + info->vars.alloc; - for (; pv < pvend; pv++) - if (pv->namlen == mangledlen - && strncmp (pv->name, mangled, mangledlen) == 0) - break; - - if (pv >= pvend) - { - /* We won't have type information for this function if - it is not included in this file. We don't try to - handle this case. FIXME. */ - type = (debug_make_function_type - (dhandle, - ieee_builtin_type (info, start, - (unsigned int) builtin_void), - (debug_type *) NULL, - false)); - } - else - { - debug_type return_type; - const debug_type *arg_types; - boolean varargs; - - if (debug_get_type_kind (dhandle, pv->type) - != DEBUG_KIND_FUNCTION) - { - ieee_error (info, start, - "bad type for C++ method function"); - return false; - } - - return_type = debug_get_return_type (dhandle, pv->type); - arg_types = debug_get_parameter_types (dhandle, pv->type, - &varargs); - if (return_type == DEBUG_TYPE_NULL || arg_types == NULL) - { - ieee_error (info, start, - "no type information for C++ method function"); - return false; - } - - type = debug_make_method_type (dhandle, return_type, it->type, - (debug_type *) arg_types, - varargs); - } - if (type == DEBUG_TYPE_NULL) - return false; - - switch (flags & CXXFLAGS_VISIBILITY) - { - default: - ieee_error (info, start, "unknown C++ visibility"); - return false; - - case CXXFLAGS_VISIBILITY_PUBLIC: - visibility = DEBUG_VISIBILITY_PUBLIC; - break; - - case CXXFLAGS_VISIBILITY_PRIVATE: - visibility = DEBUG_VISIBILITY_PRIVATE; - break; - - case CXXFLAGS_VISIBILITY_PROTECTED: - visibility = DEBUG_VISIBILITY_PROTECTED; - break; - } - - constp = (flags & CXXFLAGS_CONST) != 0 ? true : false; - volatilep = (flags & CXXFLAGS_VOLATILE) != 0 ? true : false; - - mangledcopy = savestring (mangled, mangledlen); - - if ((flags & CXXFLAGS_STATIC) != 0) - { - if (id == 'v') - { - ieee_error (info, start, "C++ static virtual method"); - return false; - } - mv = debug_make_static_method_variant (dhandle, mangledcopy, - type, visibility, - constp, volatilep); - } - else - { - debug_type vcontext; - - if (id != 'v') - vcontext = DEBUG_TYPE_NULL; - else - { - /* FIXME: How can we calculate this correctly? */ - vcontext = it->type; - } - mv = debug_make_method_variant (dhandle, mangledcopy, type, - visibility, constp, - volatilep, voffset, - vcontext); - } - if (mv == DEBUG_METHOD_VARIANT_NULL) - return false; - - for (meth = methods, im = 0; im < methods_count; meth++, im++) - if (meth->namlen == namlen - && strncmp (meth->name, name, namlen) == 0) - break; - if (im >= methods_count) - { - if (methods_count >= methods_alloc) - { - methods_alloc += 10; - methods = ((struct ieee_method *) - xrealloc (methods, - methods_alloc * sizeof *methods)); - } - methods[methods_count].name = name; - methods[methods_count].namlen = namlen; - methods[methods_count].variants = NULL; - methods[methods_count].count = 0; - methods[methods_count].alloc = 0; - meth = methods + methods_count; - ++methods_count; - } - - if (meth->count + 1 >= meth->alloc) - { - meth->alloc += 10; - meth->variants = ((debug_method_variant *) - xrealloc (meth->variants, - (meth->alloc - * sizeof *meth->variants))); - } - - meth->variants[meth->count] = mv; - ++meth->count; - meth->variants[meth->count] = DEBUG_METHOD_VARIANT_NULL; - } - break; - - case 'o': - { - bfd_vma spec; - - /* We have no way to store this information, so we just - ignore it. */ - if (! ieee_require_asn (info, pp, &spec)) - return false; - --count; - if ((spec & 4) != 0) - { - const char *filename; - unsigned long filenamlen; - bfd_vma lineno; - - if (! ieee_require_atn65 (info, pp, &filename, &filenamlen) - || ! ieee_require_asn (info, pp, &lineno)) - return false; - count -= 2; - } - else if ((spec & 8) != 0) - { - const char *mangled; - unsigned long mangledlen; - - if (! ieee_require_atn65 (info, pp, &mangled, &mangledlen)) - return false; - --count; - } - else - { - ieee_error (info, start, - "unrecognized C++ object overhead spec"); - return false; - } - } - break; - - case 'z': - { - const char *vname, *basename; - unsigned long vnamelen, baselen; - bfd_vma vsize, control; - - /* A virtual table pointer. */ - - if (! ieee_require_atn65 (info, pp, &vname, &vnamelen) - || ! ieee_require_asn (info, pp, &vsize) - || ! ieee_require_atn65 (info, pp, &basename, &baselen) - || ! ieee_require_asn (info, pp, &control)) - return false; - count -= 4; - - /* We just ignore the control number. We don't care what - the virtual table name is. We have no way to store the - virtual table size, and I don't think we care anyhow. */ - - /* FIXME: We can't handle multiple virtual table pointers. */ - - if (baselen == 0) - ownvptr = true; - else - { - char *basecopy; - - basecopy = savestring (basename, baselen); - vptrbase = debug_find_tagged_type (dhandle, basecopy, - DEBUG_KIND_ILLEGAL); - free (basecopy); - if (vptrbase == DEBUG_TYPE_NULL) - { - ieee_error (info, start, "undefined C++ vtable"); - return false; - } - } - } - break; - } - } - - /* Now that we have seen all the method variants, we can call - debug_make_method for each one. */ - - if (methods_count == 0) - dmethods = NULL; - else - { - unsigned int i; - - dmethods = ((debug_method *) - xmalloc ((methods_count + 1) * sizeof *dmethods)); - for (i = 0; i < methods_count; i++) - { - char *namcopy; - - namcopy = savestring (methods[i].name, methods[i].namlen); - dmethods[i] = debug_make_method (dhandle, namcopy, - methods[i].variants); - if (dmethods[i] == DEBUG_METHOD_NULL) - return false; - } - dmethods[i] = DEBUG_METHOD_NULL; - free (methods); - } - - /* The struct type was created as an indirect type pointing at - it->slot. We update it->slot to automatically update all - references to this struct. */ - it->slot = debug_make_object_type (dhandle, - class != 'u', - debug_get_type_size (dhandle, - it->slot), - fields, baseclasses, dmethods, - vptrbase, ownvptr); - if (it->slot == DEBUG_TYPE_NULL) - return false; - - return true; -} - -/* Read C++ default argument value and reference type information. */ - -static boolean -ieee_read_cxx_defaults (info, pp, count) - struct ieee_info *info; - const bfd_byte **pp; - unsigned long count; -{ - const bfd_byte *start; - const char *fnname; - unsigned long fnlen; - bfd_vma defcount; - - start = *pp; - - /* Giving the function name before the argument count is an addendum - to the spec. The function name is demangled, though, so this - record must always refer to the current function. */ - - if (info->blockstack.bsp <= info->blockstack.stack - || info->blockstack.bsp[-1].fnindx == (unsigned int) -1) - { - ieee_error (info, start, "C++ default values not in a function"); - return false; - } - - if (! ieee_require_atn65 (info, pp, &fnname, &fnlen) - || ! ieee_require_asn (info, pp, &defcount)) - return false; - count -= 2; - - while (defcount-- > 0) - { - bfd_vma type, val; - const char *strval; - unsigned long strvallen; - - if (! ieee_require_asn (info, pp, &type)) - return false; - --count; - - switch (type) - { - case 0: - case 4: - break; - - case 1: - case 2: - if (! ieee_require_asn (info, pp, &val)) - return false; - --count; - break; - - case 3: - case 7: - if (! ieee_require_atn65 (info, pp, &strval, &strvallen)) - return false; - --count; - break; - - default: - ieee_error (info, start, "unrecognized C++ default type"); - return false; - } - - /* We have no way to record the default argument values, so we - just ignore them. FIXME. */ - } - - /* Any remaining arguments are indices of parameters that are really - reference type. */ - if (count > 0) - { - PTR dhandle; - debug_type *arg_slots; - - dhandle = info->dhandle; - arg_slots = info->types.types[info->blockstack.bsp[-1].fnindx].arg_slots; - while (count-- > 0) - { - bfd_vma indx; - debug_type target; - - if (! ieee_require_asn (info, pp, &indx)) - return false; - /* The index is 1 based. */ - --indx; - if (arg_slots == NULL - || arg_slots[indx] == DEBUG_TYPE_NULL - || (debug_get_type_kind (dhandle, arg_slots[indx]) - != DEBUG_KIND_POINTER)) - { - ieee_error (info, start, "reference parameter is not a pointer"); - return false; - } - - target = debug_get_target_type (dhandle, arg_slots[indx]); - arg_slots[indx] = debug_make_reference_type (dhandle, target); - if (arg_slots[indx] == DEBUG_TYPE_NULL) - return false; - } - } - - return true; -} - -/* Read a C++ reference definition. */ - -static boolean -ieee_read_reference (info, pp) - struct ieee_info *info; - const bfd_byte **pp; -{ - const bfd_byte *start; - bfd_vma flags; - const char *class, *name; - unsigned long classlen, namlen; - debug_type *pslot; - debug_type target; - - start = *pp; - - if (! ieee_require_asn (info, pp, &flags)) - return false; - - /* Giving the class name before the member name is in an addendum to - the spec. */ - if (flags == 3) - { - if (! ieee_require_atn65 (info, pp, &class, &classlen)) - return false; - } - - if (! ieee_require_atn65 (info, pp, &name, &namlen)) - return false; - - pslot = NULL; - if (flags != 3) - { - int pass; - - /* We search from the last variable indices to the first in - hopes of finding local variables correctly. We search the - local variables on the first pass, and the global variables - on the second. FIXME: This probably won't work in all cases. - On the other hand, I don't know what will. */ - for (pass = 0; pass < 2; pass++) - { - struct ieee_vars *vars; - int i; - struct ieee_var *pv = NULL; - - if (pass == 0) - vars = &info->vars; - else - { - vars = info->global_vars; - if (vars == NULL) - break; - } - - for (i = (int) vars->alloc - 1; i >= 0; i--) - { - boolean found; - - pv = vars->vars + i; - - if (pv->pslot == NULL - || pv->namlen != namlen - || strncmp (pv->name, name, namlen) != 0) - continue; - - found = false; - switch (flags) - { - default: - ieee_error (info, start, - "unrecognized C++ reference type"); - return false; - - case 0: - /* Global variable or function. */ - if (pv->kind == IEEE_GLOBAL - || pv->kind == IEEE_EXTERNAL - || pv->kind == IEEE_FUNCTION) - found = true; - break; - - case 1: - /* Global static variable or function. */ - if (pv->kind == IEEE_STATIC - || pv->kind == IEEE_FUNCTION) - found = true; - break; - - case 2: - /* Local variable. */ - if (pv->kind == IEEE_LOCAL) - found = true; - break; - } - - if (found) - break; - } - - if (i >= 0) - { - pslot = pv->pslot; - break; - } - } - } - else - { - struct ieee_tag *it; - - for (it = info->tags; it != NULL; it = it->next) - { - if (it->name[0] == class[0] - && strncmp (it->name, class, classlen) == 0 - && strlen (it->name) == classlen) - { - if (it->fslots != NULL) - { - const debug_field *pf; - unsigned int findx; - - pf = debug_get_fields (info->dhandle, it->type); - if (pf == NULL) - { - ieee_error (info, start, - "C++ reference in class with no fields"); - return false; - } - - for (findx = 0; *pf != DEBUG_FIELD_NULL; pf++, findx++) - { - const char *fname; - - fname = debug_get_field_name (info->dhandle, *pf); - if (fname == NULL) - return false; - if (strncmp (fname, name, namlen) == 0 - && strlen (fname) == namlen) - { - pslot = it->fslots + findx; - break; - } - } - } - - break; - } - } - } - - if (pslot == NULL) - { - ieee_error (info, start, "C++ reference not found"); - return false; - } - - /* We allocated the type of the object as an indirect type pointing - to *pslot, which we can now update to be a reference type. */ - if (debug_get_type_kind (info->dhandle, *pslot) != DEBUG_KIND_POINTER) - { - ieee_error (info, start, "C++ reference is not pointer"); - return false; - } - - target = debug_get_target_type (info->dhandle, *pslot); - *pslot = debug_make_reference_type (info->dhandle, target); - if (*pslot == DEBUG_TYPE_NULL) - return false; - - return true; -} - -/* Require an ASN record. */ - -static boolean -ieee_require_asn (info, pp, pv) - struct ieee_info *info; - const bfd_byte **pp; - bfd_vma *pv; -{ - const bfd_byte *start; - ieee_record_enum_type c; - bfd_vma varindx; - - start = *pp; - - c = (ieee_record_enum_type) **pp; - if (c != ieee_e2_first_byte_enum) - { - ieee_error (info, start, "missing required ASN"); - return false; - } - ++*pp; - - c = (ieee_record_enum_type) (((unsigned int) c << 8) | **pp); - if (c != ieee_asn_record_enum) - { - ieee_error (info, start, "missing required ASN"); - return false; - } - ++*pp; - - /* Just ignore the variable index. */ - if (! ieee_read_number (info, pp, &varindx)) - return false; - - return ieee_read_expression (info, pp, pv); -} - -/* Require an ATN65 record. */ - -static boolean -ieee_require_atn65 (info, pp, pname, pnamlen) - struct ieee_info *info; - const bfd_byte **pp; - const char **pname; - unsigned long *pnamlen; -{ - const bfd_byte *start; - ieee_record_enum_type c; - bfd_vma name_indx, type_indx, atn_code; - - start = *pp; - - c = (ieee_record_enum_type) **pp; - if (c != ieee_at_record_enum) - { - ieee_error (info, start, "missing required ATN65"); - return false; - } - ++*pp; - - c = (ieee_record_enum_type) (((unsigned int) c << 8) | **pp); - if (c != ieee_atn_record_enum) - { - ieee_error (info, start, "missing required ATN65"); - return false; - } - ++*pp; - - if (! ieee_read_number (info, pp, &name_indx) - || ! ieee_read_number (info, pp, &type_indx) - || ! ieee_read_number (info, pp, &atn_code)) - return false; - - /* Just ignore name_indx. */ - - if (type_indx != 0 || atn_code != 65) - { - ieee_error (info, start, "bad ATN65 record"); - return false; - } - - return ieee_read_id (info, pp, pname, pnamlen); -} - -/* Convert a register number in IEEE debugging information into a - generic register number. */ - -static int -ieee_regno_to_genreg (abfd, r) - bfd *abfd; - int r; -{ - switch (bfd_get_arch (abfd)) - { - case bfd_arch_m68k: - /* For some reasons stabs adds 2 to the floating point register - numbers. */ - if (r >= 16) - r += 2; - break; - - case bfd_arch_i960: - /* Stabs uses 0 to 15 for r0 to r15, 16 to 31 for g0 to g15, and - 32 to 35 for fp0 to fp3. */ - --r; - break; - - default: - break; - } - - return r; -} - -/* Convert a generic register number to an IEEE specific one. */ - -static int -ieee_genreg_to_regno (abfd, r) - bfd *abfd; - int r; -{ - switch (bfd_get_arch (abfd)) - { - case bfd_arch_m68k: - /* For some reason stabs add 2 to the floating point register - numbers. */ - if (r >= 18) - r -= 2; - break; - - case bfd_arch_i960: - /* Stabs uses 0 to 15 for r0 to r15, 16 to 31 for g0 to g15, and - 32 to 35 for fp0 to fp3. */ - ++r; - break; - - default: - break; - } - - return r; -} - -/* These routines build IEEE debugging information out of the generic - debugging information. */ - -/* We build the IEEE debugging information byte by byte. Rather than - waste time copying data around, we use a linked list of buffers to - hold the data. */ - -#define IEEE_BUFSIZE (490) - -struct ieee_buf -{ - /* Next buffer. */ - struct ieee_buf *next; - /* Number of data bytes in this buffer. */ - unsigned int c; - /* Bytes. */ - bfd_byte buf[IEEE_BUFSIZE]; -}; - -/* A list of buffers. */ - -struct ieee_buflist -{ - /* Head of list. */ - struct ieee_buf *head; - /* Tail--last buffer on list. */ - struct ieee_buf *tail; -}; - -/* In order to generate the BB11 blocks required by the HP emulator, - we keep track of ranges of addresses which correspond to a given - compilation unit. */ - -struct ieee_range -{ - /* Next range. */ - struct ieee_range *next; - /* Low address. */ - bfd_vma low; - /* High address. */ - bfd_vma high; -}; - -/* This structure holds information for a class on the type stack. */ - -struct ieee_type_class -{ - /* The name index in the debugging information. */ - unsigned int indx; - /* The pmisc records for the class. */ - struct ieee_buflist pmiscbuf; - /* The number of pmisc records. */ - unsigned int pmisccount; - /* The name of the class holding the virtual table, if not this - class. */ - const char *vclass; - /* Whether this class holds its own virtual table. */ - boolean ownvptr; - /* The largest virtual table offset seen so far. */ - bfd_vma voffset; - /* The current method. */ - const char *method; - /* Additional pmisc records used to record fields of reference type. */ - struct ieee_buflist refs; -}; - -/* This is how we store types for the writing routines. Most types - are simply represented by a type index. */ - -struct ieee_write_type -{ - /* Type index. */ - unsigned int indx; - /* The size of the type, if known. */ - unsigned int size; - /* The name of the type, if any. */ - const char *name; - /* If this is a function or method type, we build the type here, and - only add it to the output buffers if we need it. */ - struct ieee_buflist fndef; - /* If this is a struct, this is where the struct definition is - built. */ - struct ieee_buflist strdef; - /* If this is a class, this is where the class information is built. */ - struct ieee_type_class *classdef; - /* Whether the type is unsigned. */ - unsigned int unsignedp : 1; - /* Whether this is a reference type. */ - unsigned int referencep : 1; - /* Whether this is in the local type block. */ - unsigned int localp : 1; - /* Whether this is a duplicate struct definition which we are - ignoring. */ - unsigned int ignorep : 1; -}; - -/* This is the type stack used by the debug writing routines. FIXME: - We could generate more efficient output if we remembered when we - have output a particular type before. */ - -struct ieee_type_stack -{ - /* Next entry on stack. */ - struct ieee_type_stack *next; - /* Type information. */ - struct ieee_write_type type; -}; - -/* This is a list of associations between a name and some types. - These are used for typedefs and tags. */ - -struct ieee_name_type -{ - /* Next type for this name. */ - struct ieee_name_type *next; - /* ID number. For a typedef, this is the index of the type to which - this name is typedefed. */ - unsigned int id; - /* Type. */ - struct ieee_write_type type; - /* If this is a tag which has not yet been defined, this is the - kind. If the tag has been defined, this is DEBUG_KIND_ILLEGAL. */ - enum debug_type_kind kind; -}; - -/* We use a hash table to associate names and types. */ - -struct ieee_name_type_hash_table -{ - struct bfd_hash_table root; -}; - -struct ieee_name_type_hash_entry -{ - struct bfd_hash_entry root; - /* Information for this name. */ - struct ieee_name_type *types; -}; - -/* This is a list of enums. */ - -struct ieee_defined_enum -{ - /* Next enum. */ - struct ieee_defined_enum *next; - /* Type index. */ - unsigned int indx; - /* Whether this enum has been defined. */ - boolean defined; - /* Tag. */ - const char *tag; - /* Names. */ - const char **names; - /* Values. */ - bfd_signed_vma *vals; -}; - -/* We keep a list of modified versions of types, so that we don't - output them more than once. */ - -struct ieee_modified_type -{ - /* Pointer to this type. */ - unsigned int pointer; - /* Function with unknown arguments returning this type. */ - unsigned int function; - /* Const version of this type. */ - unsigned int const_qualified; - /* Volatile version of this type. */ - unsigned int volatile_qualified; - /* List of arrays of this type of various bounds. */ - struct ieee_modified_array_type *arrays; -}; - -/* A list of arrays bounds. */ - -struct ieee_modified_array_type -{ - /* Next array bounds. */ - struct ieee_modified_array_type *next; - /* Type index with these bounds. */ - unsigned int indx; - /* Low bound. */ - bfd_signed_vma low; - /* High bound. */ - bfd_signed_vma high; -}; - -/* This is a list of pending function parameter information. We don't - output them until we see the first block. */ - -struct ieee_pending_parm -{ - /* Next pending parameter. */ - struct ieee_pending_parm *next; - /* Name. */ - const char *name; - /* Type index. */ - unsigned int type; - /* Whether the type is a reference. */ - boolean referencep; - /* Kind. */ - enum debug_parm_kind kind; - /* Value. */ - bfd_vma val; -}; - -/* This is the handle passed down by debug_write. */ - -struct ieee_handle -{ - /* BFD we are writing to. */ - bfd *abfd; - /* Whether we got an error in a subroutine called via traverse or - map_over_sections. */ - boolean error; - /* Current data buffer list. */ - struct ieee_buflist *current; - /* Current data buffer. */ - struct ieee_buf *curbuf; - /* Filename of current compilation unit. */ - const char *filename; - /* Module name of current compilation unit. */ - const char *modname; - /* List of buffer for global types. */ - struct ieee_buflist global_types; - /* List of finished data buffers. */ - struct ieee_buflist data; - /* List of buffers for typedefs in the current compilation unit. */ - struct ieee_buflist types; - /* List of buffers for variables and functions in the current - compilation unit. */ - struct ieee_buflist vars; - /* List of buffers for C++ class definitions in the current - compilation unit. */ - struct ieee_buflist cxx; - /* List of buffers for line numbers in the current compilation unit. */ - struct ieee_buflist linenos; - /* Ranges for the current compilation unit. */ - struct ieee_range *ranges; - /* Ranges for all debugging information. */ - struct ieee_range *global_ranges; - /* Nested pending ranges. */ - struct ieee_range *pending_ranges; - /* Type stack. */ - struct ieee_type_stack *type_stack; - /* Next unallocated type index. */ - unsigned int type_indx; - /* Next unallocated name index. */ - unsigned int name_indx; - /* Typedefs. */ - struct ieee_name_type_hash_table typedefs; - /* Tags. */ - struct ieee_name_type_hash_table tags; - /* Enums. */ - struct ieee_defined_enum *enums; - /* Modified versions of types. */ - struct ieee_modified_type *modified; - /* Number of entries allocated in modified. */ - unsigned int modified_alloc; - /* 4 byte complex type. */ - unsigned int complex_float_index; - /* 8 byte complex type. */ - unsigned int complex_double_index; - /* The depth of block nesting. This is 0 outside a function, and 1 - just after start_function is called. */ - unsigned int block_depth; - /* The name of the current function. */ - const char *fnname; - /* List of buffers for the type of the function we are currently - writing out. */ - struct ieee_buflist fntype; - /* List of buffers for the parameters of the function we are - currently writing out. */ - struct ieee_buflist fnargs; - /* Number of arguments written to fnargs. */ - unsigned int fnargcount; - /* Pending function parameters. */ - struct ieee_pending_parm *pending_parms; - /* Current line number filename. */ - const char *lineno_filename; - /* Line number name index. */ - unsigned int lineno_name_indx; - /* Filename of pending line number. */ - const char *pending_lineno_filename; - /* Pending line number. */ - unsigned long pending_lineno; - /* Address of pending line number. */ - bfd_vma pending_lineno_addr; - /* Highest address seen at end of procedure. */ - bfd_vma highaddr; -}; - -static boolean ieee_init_buffer - PARAMS ((struct ieee_handle *, struct ieee_buflist *)); -static boolean ieee_change_buffer - PARAMS ((struct ieee_handle *, struct ieee_buflist *)); -static boolean ieee_append_buffer - PARAMS ((struct ieee_handle *, struct ieee_buflist *, - struct ieee_buflist *)); -static boolean ieee_real_write_byte PARAMS ((struct ieee_handle *, int)); -static boolean ieee_write_2bytes PARAMS ((struct ieee_handle *, int)); -static boolean ieee_write_number PARAMS ((struct ieee_handle *, bfd_vma)); -static boolean ieee_write_id PARAMS ((struct ieee_handle *, const char *)); -static boolean ieee_write_asn - PARAMS ((struct ieee_handle *, unsigned int, bfd_vma)); -static boolean ieee_write_atn65 - PARAMS ((struct ieee_handle *, unsigned int, const char *)); -static boolean ieee_push_type - PARAMS ((struct ieee_handle *, unsigned int, unsigned int, boolean, - boolean)); -static unsigned int ieee_pop_type PARAMS ((struct ieee_handle *)); -static void ieee_pop_unused_type PARAMS ((struct ieee_handle *)); -static unsigned int ieee_pop_type_used - PARAMS ((struct ieee_handle *, boolean)); -static boolean ieee_add_range - PARAMS ((struct ieee_handle *, boolean, bfd_vma, bfd_vma)); -static boolean ieee_start_range PARAMS ((struct ieee_handle *, bfd_vma)); -static boolean ieee_end_range PARAMS ((struct ieee_handle *, bfd_vma)); -static boolean ieee_define_type - PARAMS ((struct ieee_handle *, unsigned int, boolean, boolean)); -static boolean ieee_define_named_type - PARAMS ((struct ieee_handle *, const char *, unsigned int, unsigned int, - boolean, boolean, struct ieee_buflist *)); -static struct ieee_modified_type *ieee_get_modified_info - PARAMS ((struct ieee_handle *, unsigned int)); -static struct bfd_hash_entry *ieee_name_type_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); -static boolean ieee_write_undefined_tag - PARAMS ((struct ieee_name_type_hash_entry *, PTR)); -static boolean ieee_finish_compilation_unit PARAMS ((struct ieee_handle *)); -static void ieee_add_bb11_blocks PARAMS ((bfd *, asection *, PTR)); -static boolean ieee_add_bb11 - PARAMS ((struct ieee_handle *, asection *, bfd_vma, bfd_vma)); -static boolean ieee_output_pending_parms PARAMS ((struct ieee_handle *)); -static unsigned int ieee_vis_to_flags PARAMS ((enum debug_visibility)); -static boolean ieee_class_method_var - PARAMS ((struct ieee_handle *, const char *, enum debug_visibility, boolean, - boolean, boolean, bfd_vma, boolean)); - -static boolean ieee_start_compilation_unit PARAMS ((PTR, const char *)); -static boolean ieee_start_source PARAMS ((PTR, const char *)); -static boolean ieee_empty_type PARAMS ((PTR)); -static boolean ieee_void_type PARAMS ((PTR)); -static boolean ieee_int_type PARAMS ((PTR, unsigned int, boolean)); -static boolean ieee_float_type PARAMS ((PTR, unsigned int)); -static boolean ieee_complex_type PARAMS ((PTR, unsigned int)); -static boolean ieee_bool_type PARAMS ((PTR, unsigned int)); -static boolean ieee_enum_type - PARAMS ((PTR, const char *, const char **, bfd_signed_vma *)); -static boolean ieee_pointer_type PARAMS ((PTR)); -static boolean ieee_function_type PARAMS ((PTR, int, boolean)); -static boolean ieee_reference_type PARAMS ((PTR)); -static boolean ieee_range_type PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma)); -static boolean ieee_array_type - PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma, boolean)); -static boolean ieee_set_type PARAMS ((PTR, boolean)); -static boolean ieee_offset_type PARAMS ((PTR)); -static boolean ieee_method_type PARAMS ((PTR, boolean, int, boolean)); -static boolean ieee_const_type PARAMS ((PTR)); -static boolean ieee_volatile_type PARAMS ((PTR)); -static boolean ieee_start_struct_type - PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int)); -static boolean ieee_struct_field - PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility)); -static boolean ieee_end_struct_type PARAMS ((PTR)); -static boolean ieee_start_class_type - PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int, boolean, - boolean)); -static boolean ieee_class_static_member - PARAMS ((PTR, const char *, const char *, enum debug_visibility)); -static boolean ieee_class_baseclass - PARAMS ((PTR, bfd_vma, boolean, enum debug_visibility)); -static boolean ieee_class_start_method PARAMS ((PTR, const char *)); -static boolean ieee_class_method_variant - PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean, - bfd_vma, boolean)); -static boolean ieee_class_static_method_variant - PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean)); -static boolean ieee_class_end_method PARAMS ((PTR)); -static boolean ieee_end_class_type PARAMS ((PTR)); -static boolean ieee_typedef_type PARAMS ((PTR, const char *)); -static boolean ieee_tag_type - PARAMS ((PTR, const char *, unsigned int, enum debug_type_kind)); -static boolean ieee_typdef PARAMS ((PTR, const char *)); -static boolean ieee_tag PARAMS ((PTR, const char *)); -static boolean ieee_int_constant PARAMS ((PTR, const char *, bfd_vma)); -static boolean ieee_float_constant PARAMS ((PTR, const char *, double)); -static boolean ieee_typed_constant PARAMS ((PTR, const char *, bfd_vma)); -static boolean ieee_variable - PARAMS ((PTR, const char *, enum debug_var_kind, bfd_vma)); -static boolean ieee_start_function PARAMS ((PTR, const char *, boolean)); -static boolean ieee_function_parameter - PARAMS ((PTR, const char *, enum debug_parm_kind, bfd_vma)); -static boolean ieee_start_block PARAMS ((PTR, bfd_vma)); -static boolean ieee_end_block PARAMS ((PTR, bfd_vma)); -static boolean ieee_end_function PARAMS ((PTR)); -static boolean ieee_lineno - PARAMS ((PTR, const char *, unsigned long, bfd_vma)); - -static const struct debug_write_fns ieee_fns = -{ - ieee_start_compilation_unit, - ieee_start_source, - ieee_empty_type, - ieee_void_type, - ieee_int_type, - ieee_float_type, - ieee_complex_type, - ieee_bool_type, - ieee_enum_type, - ieee_pointer_type, - ieee_function_type, - ieee_reference_type, - ieee_range_type, - ieee_array_type, - ieee_set_type, - ieee_offset_type, - ieee_method_type, - ieee_const_type, - ieee_volatile_type, - ieee_start_struct_type, - ieee_struct_field, - ieee_end_struct_type, - ieee_start_class_type, - ieee_class_static_member, - ieee_class_baseclass, - ieee_class_start_method, - ieee_class_method_variant, - ieee_class_static_method_variant, - ieee_class_end_method, - ieee_end_class_type, - ieee_typedef_type, - ieee_tag_type, - ieee_typdef, - ieee_tag, - ieee_int_constant, - ieee_float_constant, - ieee_typed_constant, - ieee_variable, - ieee_start_function, - ieee_function_parameter, - ieee_start_block, - ieee_end_block, - ieee_end_function, - ieee_lineno -}; - -/* Initialize a buffer to be empty. */ - -/*ARGSUSED*/ -static boolean -ieee_init_buffer (info, buflist) - struct ieee_handle *info; - struct ieee_buflist *buflist; -{ - buflist->head = NULL; - buflist->tail = NULL; - return true; -} - -/* See whether a buffer list has any data. */ - -#define ieee_buffer_emptyp(buflist) ((buflist)->head == NULL) - -/* Change the current buffer to a specified buffer chain. */ - -static boolean -ieee_change_buffer (info, buflist) - struct ieee_handle *info; - struct ieee_buflist *buflist; -{ - if (buflist->head == NULL) - { - struct ieee_buf *buf; - - buf = (struct ieee_buf *) xmalloc (sizeof *buf); - buf->next = NULL; - buf->c = 0; - buflist->head = buf; - buflist->tail = buf; - } - - info->current = buflist; - info->curbuf = buflist->tail; - - return true; -} - -/* Append a buffer chain. */ - -/*ARGSUSED*/ -static boolean -ieee_append_buffer (info, mainbuf, newbuf) - struct ieee_handle *info; - struct ieee_buflist *mainbuf; - struct ieee_buflist *newbuf; -{ - if (newbuf->head != NULL) - { - if (mainbuf->head == NULL) - mainbuf->head = newbuf->head; - else - mainbuf->tail->next = newbuf->head; - mainbuf->tail = newbuf->tail; - } - return true; -} - -/* Write a byte into the buffer. We use a macro for speed and a - function for the complex cases. */ - -#define ieee_write_byte(info, b) \ - ((info)->curbuf->c < IEEE_BUFSIZE \ - ? ((info)->curbuf->buf[(info)->curbuf->c++] = (b), true) \ - : ieee_real_write_byte ((info), (b))) - -static boolean -ieee_real_write_byte (info, b) - struct ieee_handle *info; - int b; -{ - if (info->curbuf->c >= IEEE_BUFSIZE) - { - struct ieee_buf *n; - - n = (struct ieee_buf *) xmalloc (sizeof *n); - n->next = NULL; - n->c = 0; - if (info->current->head == NULL) - info->current->head = n; - else - info->current->tail->next = n; - info->current->tail = n; - info->curbuf = n; - } - - info->curbuf->buf[info->curbuf->c] = b; - ++info->curbuf->c; - - return true; -} - -/* Write out two bytes. */ - -static boolean -ieee_write_2bytes (info, i) - struct ieee_handle *info; - int i; -{ - return (ieee_write_byte (info, i >> 8) - && ieee_write_byte (info, i & 0xff)); -} - -/* Write out an integer. */ - -static boolean -ieee_write_number (info, v) - struct ieee_handle *info; - bfd_vma v; -{ - bfd_vma t; - bfd_byte ab[20]; - bfd_byte *p; - unsigned int c; - - if (v <= (bfd_vma) ieee_number_end_enum) - return ieee_write_byte (info, (int) v); - - t = v; - p = ab + sizeof ab; - while (t != 0) - { - *--p = t & 0xff; - t >>= 8; - } - c = (ab + 20) - p; - - if (c > (unsigned int) (ieee_number_repeat_end_enum - - ieee_number_repeat_start_enum)) - { - fprintf (stderr, "IEEE numeric overflow: 0x"); - fprintf_vma (stderr, v); - fprintf (stderr, "\n"); - return false; - } - - if (! ieee_write_byte (info, (int) ieee_number_repeat_start_enum + c)) - return false; - for (; c > 0; --c, ++p) - { - if (! ieee_write_byte (info, *p)) - return false; - } - - return true; -} - -/* Write out a string. */ - -static boolean -ieee_write_id (info, s) - struct ieee_handle *info; - const char *s; -{ - unsigned int len; - - len = strlen (s); - if (len <= 0x7f) - { - if (! ieee_write_byte (info, len)) - return false; - } - else if (len <= 0xff) - { - if (! ieee_write_byte (info, (int) ieee_extension_length_1_enum) - || ! ieee_write_byte (info, len)) - return false; - } - else if (len <= 0xffff) - { - if (! ieee_write_byte (info, (int) ieee_extension_length_2_enum) - || ! ieee_write_2bytes (info, len)) - return false; - } - else - { - fprintf (stderr, "IEEE string length overflow: %u\n", len); - return false; - } - - for (; *s != '\0'; s++) - if (! ieee_write_byte (info, *s)) - return false; - - return true; -} - -/* Write out an ASN record. */ - -static boolean -ieee_write_asn (info, indx, val) - struct ieee_handle *info; - unsigned int indx; - bfd_vma val; -{ - return (ieee_write_2bytes (info, (int) ieee_asn_record_enum) - && ieee_write_number (info, indx) - && ieee_write_number (info, val)); -} - -/* Write out an ATN65 record. */ - -static boolean -ieee_write_atn65 (info, indx, s) - struct ieee_handle *info; - unsigned int indx; - const char *s; -{ - return (ieee_write_2bytes (info, (int) ieee_atn_record_enum) - && ieee_write_number (info, indx) - && ieee_write_number (info, 0) - && ieee_write_number (info, 65) - && ieee_write_id (info, s)); -} - -/* Push a type index onto the type stack. */ - -static boolean -ieee_push_type (info, indx, size, unsignedp, localp) - struct ieee_handle *info; - unsigned int indx; - unsigned int size; - boolean unsignedp; - boolean localp; -{ - struct ieee_type_stack *ts; - - ts = (struct ieee_type_stack *) xmalloc (sizeof *ts); - memset (ts, 0, sizeof *ts); - - ts->type.indx = indx; - ts->type.size = size; - ts->type.unsignedp = unsignedp; - ts->type.localp = localp; - - ts->next = info->type_stack; - info->type_stack = ts; - - return true; -} - -/* Pop a type index off the type stack. */ - -static unsigned int -ieee_pop_type (info) - struct ieee_handle *info; -{ - return ieee_pop_type_used (info, true); -} - -/* Pop an unused type index off the type stack. */ - -static void -ieee_pop_unused_type (info) - struct ieee_handle *info; -{ - (void) ieee_pop_type_used (info, false); -} - -/* Pop a used or unused type index off the type stack. */ - -static unsigned int -ieee_pop_type_used (info, used) - struct ieee_handle *info; - boolean used; -{ - struct ieee_type_stack *ts; - unsigned int ret; - - ts = info->type_stack; - assert (ts != NULL); - - /* If this is a function type, and we need it, we need to append the - actual definition to the typedef block now. */ - if (used && ! ieee_buffer_emptyp (&ts->type.fndef)) - { - struct ieee_buflist *buflist; - - if (ts->type.localp) - { - /* Make sure we have started the types block. */ - if (ieee_buffer_emptyp (&info->types)) - { - if (! ieee_change_buffer (info, &info->types) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 1) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, info->modname)) - return false; - } - buflist = &info->types; - } - else - { - /* Make sure we started the global type block. */ - if (ieee_buffer_emptyp (&info->global_types)) - { - if (! ieee_change_buffer (info, &info->global_types) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 2) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, "")) - return false; - } - buflist = &info->global_types; - } - - if (! ieee_append_buffer (info, buflist, &ts->type.fndef)) - return false; - } - - ret = ts->type.indx; - info->type_stack = ts->next; - free (ts); - return ret; -} - -/* Add a range of bytes included in the current compilation unit. */ - -static boolean -ieee_add_range (info, global, low, high) - struct ieee_handle *info; - boolean global; - bfd_vma low; - bfd_vma high; -{ - struct ieee_range **plist, *r, **pr; - - if (low == (bfd_vma) -1 || high == (bfd_vma) -1 || low == high) - return true; - - if (global) - plist = &info->global_ranges; - else - plist = &info->ranges; - - for (r = *plist; r != NULL; r = r->next) - { - if (high >= r->low && low <= r->high) - { - /* The new range overlaps r. */ - if (low < r->low) - r->low = low; - if (high > r->high) - r->high = high; - pr = &r->next; - while (*pr != NULL && (*pr)->low <= r->high) - { - struct ieee_range *n; - - if ((*pr)->high > r->high) - r->high = (*pr)->high; - n = (*pr)->next; - free (*pr); - *pr = n; - } - return true; - } - } - - r = (struct ieee_range *) xmalloc (sizeof *r); - memset (r, 0, sizeof *r); - - r->low = low; - r->high = high; - - /* Store the ranges sorted by address. */ - for (pr = plist; *pr != NULL; pr = &(*pr)->next) - if ((*pr)->low > high) - break; - r->next = *pr; - *pr = r; - - return true; -} - -/* Start a new range for which we only have the low address. */ - -static boolean -ieee_start_range (info, low) - struct ieee_handle *info; - bfd_vma low; -{ - struct ieee_range *r; - - r = (struct ieee_range *) xmalloc (sizeof *r); - memset (r, 0, sizeof *r); - r->low = low; - r->next = info->pending_ranges; - info->pending_ranges = r; - return true; -} - -/* Finish a range started by ieee_start_range. */ - -static boolean -ieee_end_range (info, high) - struct ieee_handle *info; - bfd_vma high; -{ - struct ieee_range *r; - bfd_vma low; - - assert (info->pending_ranges != NULL); - r = info->pending_ranges; - low = r->low; - info->pending_ranges = r->next; - free (r); - return ieee_add_range (info, false, low, high); -} - -/* Start defining a type. */ - -static boolean -ieee_define_type (info, size, unsignedp, localp) - struct ieee_handle *info; - unsigned int size; - boolean unsignedp; - boolean localp; -{ - return ieee_define_named_type (info, (const char *) NULL, - (unsigned int) -1, size, unsignedp, - localp, (struct ieee_buflist *) NULL); -} - -/* Start defining a named type. */ - -static boolean -ieee_define_named_type (info, name, indx, size, unsignedp, localp, buflist) - struct ieee_handle *info; - const char *name; - unsigned int indx; - unsigned int size; - boolean unsignedp; - boolean localp; - struct ieee_buflist *buflist; -{ - unsigned int type_indx; - unsigned int name_indx; - - if (indx != (unsigned int) -1) - type_indx = indx; - else - { - type_indx = info->type_indx; - ++info->type_indx; - } - - name_indx = info->name_indx; - ++info->name_indx; - - if (name == NULL) - name = ""; - - /* If we were given a buffer, use it; otherwise, use either the - local or the global type information, and make sure that the type - block is started. */ - if (buflist != NULL) - { - if (! ieee_change_buffer (info, buflist)) - return false; - } - else if (localp) - { - if (! ieee_buffer_emptyp (&info->types)) - { - if (! ieee_change_buffer (info, &info->types)) - return false; - } - else - { - if (! ieee_change_buffer (info, &info->types) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 1) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, info->modname)) - return false; - } - } - else - { - if (! ieee_buffer_emptyp (&info->global_types)) - { - if (! ieee_change_buffer (info, &info->global_types)) - return false; - } - else - { - if (! ieee_change_buffer (info, &info->global_types) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 2) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, "")) - return false; - } - } - - /* Push the new type on the type stack, write out an NN record, and - write out the start of a TY record. The caller will then finish - the TY record. */ - if (! ieee_push_type (info, type_indx, size, unsignedp, localp)) - return false; - - return (ieee_write_byte (info, (int) ieee_nn_record) - && ieee_write_number (info, name_indx) - && ieee_write_id (info, name) - && ieee_write_byte (info, (int) ieee_ty_record_enum) - && ieee_write_number (info, type_indx) - && ieee_write_byte (info, 0xce) - && ieee_write_number (info, name_indx)); -} - -/* Get an entry to the list of modified versions of a type. */ - -static struct ieee_modified_type * -ieee_get_modified_info (info, indx) - struct ieee_handle *info; - unsigned int indx; -{ - if (indx >= info->modified_alloc) - { - unsigned int nalloc; - - nalloc = info->modified_alloc; - if (nalloc == 0) - nalloc = 16; - while (indx >= nalloc) - nalloc *= 2; - info->modified = ((struct ieee_modified_type *) - xrealloc (info->modified, - nalloc * sizeof *info->modified)); - memset (info->modified + info->modified_alloc, 0, - (nalloc - info->modified_alloc) * sizeof *info->modified); - info->modified_alloc = nalloc; - } - - return info->modified + indx; -} - -/* Routines for the hash table mapping names to types. */ - -/* Initialize an entry in the hash table. */ - -static struct bfd_hash_entry * -ieee_name_type_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct ieee_name_type_hash_entry *ret = - (struct ieee_name_type_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == NULL) - ret = ((struct ieee_name_type_hash_entry *) - bfd_hash_allocate (table, sizeof *ret)); - if (ret == NULL) - return NULL; - - /* Call the allocation method of the superclass. */ - ret = ((struct ieee_name_type_hash_entry *) - bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); - if (ret) - { - /* Set local fields. */ - ret->types = NULL; - } - - return (struct bfd_hash_entry *) ret; -} - -/* Look up an entry in the hash table. */ - -#define ieee_name_type_hash_lookup(table, string, create, copy) \ - ((struct ieee_name_type_hash_entry *) \ - bfd_hash_lookup (&(table)->root, (string), (create), (copy))) - -/* Traverse the hash table. */ - -#define ieee_name_type_hash_traverse(table, func, info) \ - (bfd_hash_traverse \ - (&(table)->root, \ - (boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) (func), \ - (info))) - -/* The general routine to write out IEEE debugging information. */ - -boolean -write_ieee_debugging_info (abfd, dhandle) - bfd *abfd; - PTR dhandle; -{ - struct ieee_handle info; - asection *s; - const char *err; - struct ieee_buf *b; - - memset (&info, 0, sizeof info); - info.abfd = abfd; - info.type_indx = 256; - info.name_indx = 32; - - if (! bfd_hash_table_init (&info.typedefs.root, ieee_name_type_newfunc) - || ! bfd_hash_table_init (&info.tags.root, ieee_name_type_newfunc)) - return false; - - if (! ieee_init_buffer (&info, &info.global_types) - || ! ieee_init_buffer (&info, &info.data) - || ! ieee_init_buffer (&info, &info.types) - || ! ieee_init_buffer (&info, &info.vars) - || ! ieee_init_buffer (&info, &info.cxx) - || ! ieee_init_buffer (&info, &info.linenos) - || ! ieee_init_buffer (&info, &info.fntype) - || ! ieee_init_buffer (&info, &info.fnargs)) - return false; - - if (! debug_write (dhandle, &ieee_fns, (PTR) &info)) - return false; - - if (info.filename != NULL) - { - if (! ieee_finish_compilation_unit (&info)) - return false; - } - - /* Put any undefined tags in the global typedef information. */ - info.error = false; - ieee_name_type_hash_traverse (&info.tags, - ieee_write_undefined_tag, - (PTR) &info); - if (info.error) - return false; - - /* Prepend the global typedef information to the other data. */ - if (! ieee_buffer_emptyp (&info.global_types)) - { - /* The HP debugger seems to have a bug in which it ignores the - last entry in the global types, so we add a dummy entry. */ - if (! ieee_change_buffer (&info, &info.global_types) - || ! ieee_write_byte (&info, (int) ieee_nn_record) - || ! ieee_write_number (&info, info.name_indx) - || ! ieee_write_id (&info, "") - || ! ieee_write_byte (&info, (int) ieee_ty_record_enum) - || ! ieee_write_number (&info, info.type_indx) - || ! ieee_write_byte (&info, 0xce) - || ! ieee_write_number (&info, info.name_indx) - || ! ieee_write_number (&info, 'P') - || ! ieee_write_number (&info, (int) builtin_void + 32) - || ! ieee_write_byte (&info, (int) ieee_be_record_enum)) - return false; - - if (! ieee_append_buffer (&info, &info.global_types, &info.data)) - return false; - info.data = info.global_types; - } - - /* Make sure that we have declare BB11 blocks for each range in the - file. They are added to info->vars. */ - info.error = false; - if (! ieee_init_buffer (&info, &info.vars)) - return false; - bfd_map_over_sections (abfd, ieee_add_bb11_blocks, (PTR) &info); - if (info.error) - return false; - if (! ieee_buffer_emptyp (&info.vars)) - { - if (! ieee_change_buffer (&info, &info.vars) - || ! ieee_write_byte (&info, (int) ieee_be_record_enum)) - return false; - - if (! ieee_append_buffer (&info, &info.data, &info.vars)) - return false; - } - - /* Now all the data is in info.data. Write it out to the BFD. We - normally would need to worry about whether all the other sections - are set up yet, but the IEEE backend will handle this particular - case correctly regardless. */ - if (ieee_buffer_emptyp (&info.data)) - { - /* There is no debugging information. */ - return true; - } - err = NULL; - s = bfd_make_section (abfd, ".debug"); - if (s == NULL) - err = "bfd_make_section"; - if (err == NULL) - { - if (! bfd_set_section_flags (abfd, s, SEC_DEBUGGING | SEC_HAS_CONTENTS)) - err = "bfd_set_section_flags"; - } - if (err == NULL) - { - bfd_size_type size; - - size = 0; - for (b = info.data.head; b != NULL; b = b->next) - size += b->c; - if (! bfd_set_section_size (abfd, s, size)) - err = "bfd_set_section_size"; - } - if (err == NULL) - { - file_ptr offset; - - offset = 0; - for (b = info.data.head; b != NULL; b = b->next) - { - if (! bfd_set_section_contents (abfd, s, b->buf, offset, b->c)) - { - err = "bfd_set_section_contents"; - break; - } - offset += b->c; - } - } - - if (err != NULL) - { - fprintf (stderr, "%s: %s: %s\n", bfd_get_filename (abfd), err, - bfd_errmsg (bfd_get_error ())); - return false; - } - - bfd_hash_table_free (&info.typedefs.root); - bfd_hash_table_free (&info.tags.root); - - return true; -} - -/* Write out information for an undefined tag. This is called via - ieee_name_type_hash_traverse. */ - -static boolean -ieee_write_undefined_tag (h, p) - struct ieee_name_type_hash_entry *h; - PTR p; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - struct ieee_name_type *nt; - - for (nt = h->types; nt != NULL; nt = nt->next) - { - unsigned int name_indx; - char code; - - if (nt->kind == DEBUG_KIND_ILLEGAL) - continue; - - if (ieee_buffer_emptyp (&info->global_types)) - { - if (! ieee_change_buffer (info, &info->global_types) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 2) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, "")) - { - info->error = true; - return false; - } - } - else - { - if (! ieee_change_buffer (info, &info->global_types)) - { - info->error = true; - return false; - } - } - - name_indx = info->name_indx; - ++info->name_indx; - if (! ieee_write_byte (info, (int) ieee_nn_record) - || ! ieee_write_number (info, name_indx) - || ! ieee_write_id (info, nt->type.name) - || ! ieee_write_byte (info, (int) ieee_ty_record_enum) - || ! ieee_write_number (info, nt->type.indx) - || ! ieee_write_byte (info, 0xce) - || ! ieee_write_number (info, name_indx)) - { - info->error = true; - return false; - } - - switch (nt->kind) - { - default: - abort (); - info->error = true; - return false; - case DEBUG_KIND_STRUCT: - case DEBUG_KIND_CLASS: - code = 'S'; - break; - case DEBUG_KIND_UNION: - case DEBUG_KIND_UNION_CLASS: - code = 'U'; - break; - case DEBUG_KIND_ENUM: - code = 'E'; - break; - } - if (! ieee_write_number (info, code) - || ! ieee_write_number (info, 0)) - { - info->error = true; - return false; - } - } - - return true; -} - -/* Start writing out information for a compilation unit. */ - -static boolean -ieee_start_compilation_unit (p, filename) - PTR p; - const char *filename; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - const char *modname; - char *c, *s; - unsigned int nindx; - - if (info->filename != NULL) - { - if (! ieee_finish_compilation_unit (info)) - return false; - } - - info->filename = filename; - modname = strrchr (filename, '/'); - if (modname != NULL) - ++modname; - else - { - modname = strrchr (filename, '\\'); - if (modname != NULL) - ++modname; - else - modname = filename; - } - c = xstrdup (modname); - s = strrchr (c, '.'); - if (s != NULL) - *s = '\0'; - info->modname = c; - - if (! ieee_init_buffer (info, &info->types) - || ! ieee_init_buffer (info, &info->vars) - || ! ieee_init_buffer (info, &info->cxx) - || ! ieee_init_buffer (info, &info->linenos)) - return false; - info->ranges = NULL; - - /* Always include a BB1 and a BB3 block. That is what the output of - the MRI linker seems to look like. */ - if (! ieee_change_buffer (info, &info->types) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 1) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, info->modname)) - return false; - - nindx = info->name_indx; - ++info->name_indx; - if (! ieee_change_buffer (info, &info->vars) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 3) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, info->modname)) - return false; - - return true; -} - -/* Finish up a compilation unit. */ - -static boolean -ieee_finish_compilation_unit (info) - struct ieee_handle *info; -{ - struct ieee_range *r; - - if (! ieee_buffer_emptyp (&info->types)) - { - if (! ieee_change_buffer (info, &info->types) - || ! ieee_write_byte (info, (int) ieee_be_record_enum)) - return false; - } - - if (! ieee_buffer_emptyp (&info->cxx)) - { - /* Append any C++ information to the global function and - variable information. */ - assert (! ieee_buffer_emptyp (&info->vars)); - if (! ieee_change_buffer (info, &info->vars)) - return false; - - /* We put the pmisc records in a dummy procedure, just as the - MRI compiler does. */ - if (! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 6) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, "__XRYCPP") - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, info->highaddr - 1) - || ! ieee_append_buffer (info, &info->vars, &info->cxx) - || ! ieee_change_buffer (info, &info->vars) - || ! ieee_write_byte (info, (int) ieee_be_record_enum) - || ! ieee_write_number (info, info->highaddr - 1)) - return false; - } - - if (! ieee_buffer_emptyp (&info->vars)) - { - if (! ieee_change_buffer (info, &info->vars) - || ! ieee_write_byte (info, (int) ieee_be_record_enum)) - return false; - } - - if (info->pending_lineno_filename != NULL) - { - /* Force out the pending line number. */ - if (! ieee_lineno ((PTR) info, (const char *) NULL, 0, (bfd_vma) -1)) - return false; - } - if (! ieee_buffer_emptyp (&info->linenos)) - { - if (! ieee_change_buffer (info, &info->linenos) - || ! ieee_write_byte (info, (int) ieee_be_record_enum)) - return false; - if (strcmp (info->filename, info->lineno_filename) != 0) - { - /* We were not in the main file. We just closed the - included line number block, and now we must close the - main line number block. */ - if (! ieee_write_byte (info, (int) ieee_be_record_enum)) - return false; - } - } - - if (! ieee_append_buffer (info, &info->data, &info->types) - || ! ieee_append_buffer (info, &info->data, &info->vars) - || ! ieee_append_buffer (info, &info->data, &info->linenos)) - return false; - - /* Build BB10/BB11 blocks based on the ranges we recorded. */ - if (! ieee_change_buffer (info, &info->data)) - return false; - - if (! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 10) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, info->modname) - || ! ieee_write_id (info, "") - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, "GNU objcopy")) - return false; - - for (r = info->ranges; r != NULL; r = r->next) - { - bfd_vma low, high; - asection *s; - int kind; - - low = r->low; - high = r->high; - - /* Find the section corresponding to this range. */ - for (s = info->abfd->sections; s != NULL; s = s->next) - { - if (bfd_get_section_vma (info->abfd, s) <= low - && high <= (bfd_get_section_vma (info->abfd, s) - + bfd_section_size (info->abfd, s))) - break; - } - - if (s == NULL) - { - /* Just ignore this range. */ - continue; - } - - /* Coalesce ranges if it seems reasonable. */ - while (r->next != NULL - && high + 0x1000 >= r->next->low - && (r->next->high - <= (bfd_get_section_vma (info->abfd, s) - + bfd_section_size (info->abfd, s)))) - { - r = r->next; - high = r->high; - } - - if ((s->flags & SEC_CODE) != 0) - kind = 1; - else if ((s->flags & SEC_READONLY) != 0) - kind = 3; - else - kind = 2; - - if (! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 11) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, "") - || ! ieee_write_number (info, kind) - || ! ieee_write_number (info, s->index + IEEE_SECTION_NUMBER_BASE) - || ! ieee_write_number (info, low) - || ! ieee_write_byte (info, (int) ieee_be_record_enum) - || ! ieee_write_number (info, high - low)) - return false; - - /* Add this range to the list of global ranges. */ - if (! ieee_add_range (info, true, low, high)) - return false; - } - - if (! ieee_write_byte (info, (int) ieee_be_record_enum)) - return false; - - return true; -} - -/* Add BB11 blocks describing each range that we have not already - described. */ - -static void -ieee_add_bb11_blocks (abfd, sec, data) - bfd *abfd; - asection *sec; - PTR data; -{ - struct ieee_handle *info = (struct ieee_handle *) data; - bfd_vma low, high; - struct ieee_range *r; - - low = bfd_get_section_vma (abfd, sec); - high = low + bfd_section_size (abfd, sec); - - /* Find the first range at or after this section. The ranges are - sorted by address. */ - for (r = info->global_ranges; r != NULL; r = r->next) - if (r->high > low) - break; - - while (low < high) - { - if (r == NULL || r->low >= high) - { - if (! ieee_add_bb11 (info, sec, low, high)) - info->error = true; - return; - } - - if (low < r->low - && r->low - low > 0x100) - { - if (! ieee_add_bb11 (info, sec, low, r->low)) - { - info->error = true; - return; - } - } - low = r->high; - - r = r->next; - } -} - -/* Add a single BB11 block for a range. We add it to info->vars. */ - -static boolean -ieee_add_bb11 (info, sec, low, high) - struct ieee_handle *info; - asection *sec; - bfd_vma low; - bfd_vma high; -{ - int kind; - - if (! ieee_buffer_emptyp (&info->vars)) - { - if (! ieee_change_buffer (info, &info->vars)) - return false; - } - else - { - const char *filename, *modname; - char *c, *s; - - /* Start the enclosing BB10 block. */ - filename = bfd_get_filename (info->abfd); - modname = strrchr (filename, '/'); - if (modname != NULL) - ++modname; - else - { - modname = strrchr (filename, '\\'); - if (modname != NULL) - ++modname; - else - modname = filename; - } - c = xstrdup (modname); - s = strrchr (c, '.'); - if (s != NULL) - *s = '\0'; - - if (! ieee_change_buffer (info, &info->vars) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 10) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, c) - || ! ieee_write_id (info, "") - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, "GNU objcopy")) - return false; - - free (c); - } - - if ((sec->flags & SEC_CODE) != 0) - kind = 1; - else if ((sec->flags & SEC_READONLY) != 0) - kind = 3; - else - kind = 2; - - if (! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 11) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, "") - || ! ieee_write_number (info, kind) - || ! ieee_write_number (info, sec->index + IEEE_SECTION_NUMBER_BASE) - || ! ieee_write_number (info, low) - || ! ieee_write_byte (info, (int) ieee_be_record_enum) - || ! ieee_write_number (info, high - low)) - return false; - - return true; -} - -/* Start recording information from a particular source file. This is - used to record which file defined which types, variables, etc. It - is not used for line numbers, since the lineno entry point passes - down the file name anyhow. IEEE debugging information doesn't seem - to store this information anywhere. */ - -/*ARGSUSED*/ -static boolean -ieee_start_source (p, filename) - PTR p; - const char *filename; -{ - return true; -} - -/* Make an empty type. */ - -static boolean -ieee_empty_type (p) - PTR p; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - return ieee_push_type (info, (int) builtin_unknown, 0, false, false); -} - -/* Make a void type. */ - -static boolean -ieee_void_type (p) - PTR p; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - return ieee_push_type (info, (int) builtin_void, 0, false, false); -} - -/* Make an integer type. */ - -static boolean -ieee_int_type (p, size, unsignedp) - PTR p; - unsigned int size; - boolean unsignedp; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - unsigned int indx; - - switch (size) - { - case 1: - indx = (int) builtin_signed_char; - break; - case 2: - indx = (int) builtin_signed_short_int; - break; - case 4: - indx = (int) builtin_signed_long; - break; - case 8: - indx = (int) builtin_signed_long_long; - break; - default: - fprintf (stderr, "IEEE unsupported integer type size %u\n", size); - return false; - } - - if (unsignedp) - ++indx; - - return ieee_push_type (info, indx, size, unsignedp, false); -} - -/* Make a floating point type. */ - -static boolean -ieee_float_type (p, size) - PTR p; - unsigned int size; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - unsigned int indx; - - switch (size) - { - case 4: - indx = (int) builtin_float; - break; - case 8: - indx = (int) builtin_double; - break; - case 12: - /* FIXME: This size really depends upon the processor. */ - indx = (int) builtin_long_double; - break; - case 16: - indx = (int) builtin_long_long_double; - break; - default: - fprintf (stderr, "IEEE unsupported float type size %u\n", size); - return false; - } - - return ieee_push_type (info, indx, size, false, false); -} - -/* Make a complex type. */ - -static boolean -ieee_complex_type (p, size) - PTR p; - unsigned int size; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - char code; - - switch (size) - { - case 4: - if (info->complex_float_index != 0) - return ieee_push_type (info, info->complex_float_index, size * 2, - false, false); - code = 'c'; - break; - case 12: - case 16: - /* These cases can be output by gcc -gstabs. Outputting the - wrong type is better than crashing. */ - case 8: - if (info->complex_double_index != 0) - return ieee_push_type (info, info->complex_double_index, size * 2, - false, false); - code = 'd'; - break; - default: - fprintf (stderr, "IEEE unsupported complex type size %u\n", size); - return false; - } - - /* FIXME: I don't know what the string is for. */ - if (! ieee_define_type (info, size * 2, false, false) - || ! ieee_write_number (info, code) - || ! ieee_write_id (info, "")) - return false; - - if (size == 4) - info->complex_float_index = info->type_stack->type.indx; - else - info->complex_double_index = info->type_stack->type.indx; - - return true; -} - -/* Make a boolean type. IEEE doesn't support these, so we just make - an integer type instead. */ - -static boolean -ieee_bool_type (p, size) - PTR p; - unsigned int size; -{ - return ieee_int_type (p, size, true); -} - -/* Make an enumeration. */ - -static boolean -ieee_enum_type (p, tag, names, vals) - PTR p; - const char *tag; - const char **names; - bfd_signed_vma *vals; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - struct ieee_defined_enum *e; - boolean localp, simple; - unsigned int indx; - int i = 0; - - localp = false; - indx = (unsigned int) -1; - for (e = info->enums; e != NULL; e = e->next) - { - if (tag == NULL) - { - if (e->tag != NULL) - continue; - } - else - { - if (e->tag == NULL - || tag[0] != e->tag[0] - || strcmp (tag, e->tag) != 0) - continue; - } - - if (! e->defined) - { - /* This enum tag has been seen but not defined. */ - indx = e->indx; - break; - } - - if (names != NULL && e->names != NULL) - { - for (i = 0; names[i] != NULL && e->names[i] != NULL; i++) - { - if (names[i][0] != e->names[i][0] - || vals[i] != e->vals[i] - || strcmp (names[i], e->names[i]) != 0) - break; - } - } - - if ((names == NULL && e->names == NULL) - || (names != NULL - && e->names != NULL - && names[i] == NULL - && e->names[i] == NULL)) - { - /* We've seen this enum before. */ - return ieee_push_type (info, e->indx, 0, true, false); - } - - if (tag != NULL) - { - /* We've already seen an enum of the same name, so we must make - sure to output this one locally. */ - localp = true; - break; - } - } - - /* If this is a simple enumeration, in which the values start at 0 - and always increment by 1, we can use type E. Otherwise we must - use type N. */ - - simple = true; - if (names != NULL) - { - for (i = 0; names[i] != NULL; i++) - { - if (vals[i] != i) - { - simple = false; - break; - } - } - } - - if (! ieee_define_named_type (info, tag, indx, 0, true, localp, - (struct ieee_buflist *) NULL) - || ! ieee_write_number (info, simple ? 'E' : 'N')) - return false; - if (simple) - { - /* FIXME: This is supposed to be the enumeration size, but we - don't store that. */ - if (! ieee_write_number (info, 4)) - return false; - } - if (names != NULL) - { - for (i = 0; names[i] != NULL; i++) - { - if (! ieee_write_id (info, names[i])) - return false; - if (! simple) - { - if (! ieee_write_number (info, vals[i])) - return false; - } - } - } - - if (! localp) - { - if (indx == (unsigned int) -1) - { - e = (struct ieee_defined_enum *) xmalloc (sizeof *e); - memset (e, 0, sizeof *e); - e->indx = info->type_stack->type.indx; - e->tag = tag; - - e->next = info->enums; - info->enums = e; - } - - e->names = names; - e->vals = vals; - e->defined = true; - } - - return true; -} - -/* Make a pointer type. */ - -static boolean -ieee_pointer_type (p) - PTR p; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - boolean localp; - unsigned int indx; - struct ieee_modified_type *m = NULL; - - localp = info->type_stack->type.localp; - indx = ieee_pop_type (info); - - /* A pointer to a simple builtin type can be obtained by adding 32. - FIXME: Will this be a short pointer, and will that matter? */ - if (indx < 32) - return ieee_push_type (info, indx + 32, 0, true, false); - - if (! localp) - { - m = ieee_get_modified_info (p, indx); - if (m == NULL) - return false; - - /* FIXME: The size should depend upon the architecture. */ - if (m->pointer > 0) - return ieee_push_type (info, m->pointer, 4, true, false); - } - - if (! ieee_define_type (info, 4, true, localp) - || ! ieee_write_number (info, 'P') - || ! ieee_write_number (info, indx)) - return false; - - if (! localp) - m->pointer = info->type_stack->type.indx; - - return true; -} - -/* Make a function type. This will be called for a method, but we - don't want to actually add it to the type table in that case. We - handle this by defining the type in a private buffer, and only - adding that buffer to the typedef block if we are going to use it. */ - -static boolean -ieee_function_type (p, argcount, varargs) - PTR p; - int argcount; - boolean varargs; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - boolean localp; - unsigned int *args = NULL; - int i; - unsigned int retindx; - struct ieee_buflist fndef; - struct ieee_modified_type *m; - - localp = false; - - if (argcount > 0) - { - args = (unsigned int *) xmalloc (argcount * sizeof *args); - for (i = argcount - 1; i >= 0; i--) - { - if (info->type_stack->type.localp) - localp = true; - args[i] = ieee_pop_type (info); - } - } - else if (argcount < 0) - varargs = false; - - if (info->type_stack->type.localp) - localp = true; - retindx = ieee_pop_type (info); - - m = NULL; - if (argcount < 0 && ! localp) - { - m = ieee_get_modified_info (p, retindx); - if (m == NULL) - return false; - - if (m->function > 0) - return ieee_push_type (info, m->function, 0, true, false); - } - - /* An attribute of 0x41 means that the frame and push mask are - unknown. */ - if (! ieee_init_buffer (info, &fndef) - || ! ieee_define_named_type (info, (const char *) NULL, - (unsigned int) -1, 0, true, localp, - &fndef) - || ! ieee_write_number (info, 'x') - || ! ieee_write_number (info, 0x41) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, retindx) - || ! ieee_write_number (info, (bfd_vma) argcount + (varargs ? 1 : 0))) - return false; - if (argcount > 0) - { - for (i = 0; i < argcount; i++) - if (! ieee_write_number (info, args[i])) - return false; - free (args); - } - if (varargs) - { - /* A varargs function is represented by writing out the last - argument as type void *, although this makes little sense. */ - if (! ieee_write_number (info, (bfd_vma) builtin_void + 32)) - return false; - } - - if (! ieee_write_number (info, 0)) - return false; - - /* We wrote the information into fndef, in case we don't need it. - It will be appended to info->types by ieee_pop_type. */ - info->type_stack->type.fndef = fndef; - - if (m != NULL) - m->function = info->type_stack->type.indx; - - return true; -} - -/* Make a reference type. */ - -static boolean -ieee_reference_type (p) - PTR p; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - /* IEEE appears to record a normal pointer type, and then use a - pmisc record to indicate that it is really a reference. */ - - if (! ieee_pointer_type (p)) - return false; - info->type_stack->type.referencep = true; - return true; -} - -/* Make a range type. */ - -static boolean -ieee_range_type (p, low, high) - PTR p; - bfd_signed_vma low; - bfd_signed_vma high; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - unsigned int size; - boolean unsignedp, localp; - - size = info->type_stack->type.size; - unsignedp = info->type_stack->type.unsignedp; - localp = info->type_stack->type.localp; - ieee_pop_unused_type (info); - return (ieee_define_type (info, size, unsignedp, localp) - && ieee_write_number (info, 'R') - && ieee_write_number (info, (bfd_vma) low) - && ieee_write_number (info, (bfd_vma) high) - && ieee_write_number (info, unsignedp ? 0 : 1) - && ieee_write_number (info, size)); -} - -/* Make an array type. */ - -/*ARGSUSED*/ -static boolean -ieee_array_type (p, low, high, stringp) - PTR p; - bfd_signed_vma low; - bfd_signed_vma high; - boolean stringp; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - unsigned int eleindx; - boolean localp; - unsigned int size; - struct ieee_modified_type *m = NULL; - struct ieee_modified_array_type *a; - - /* IEEE does not store the range, so we just ignore it. */ - ieee_pop_unused_type (info); - localp = info->type_stack->type.localp; - size = info->type_stack->type.size; - eleindx = ieee_pop_type (info); - - /* If we don't know the range, treat the size as exactly one - element. */ - if (low < high) - size *= (high - low) + 1; - - if (! localp) - { - m = ieee_get_modified_info (info, eleindx); - if (m == NULL) - return false; - - for (a = m->arrays; a != NULL; a = a->next) - { - if (a->low == low && a->high == high) - return ieee_push_type (info, a->indx, size, false, false); - } - } - - if (! ieee_define_type (info, size, false, localp) - || ! ieee_write_number (info, low == 0 ? 'Z' : 'C') - || ! ieee_write_number (info, eleindx)) - return false; - if (low != 0) - { - if (! ieee_write_number (info, low)) - return false; - } - - if (! ieee_write_number (info, high + 1)) - return false; - - if (! localp) - { - a = (struct ieee_modified_array_type *) xmalloc (sizeof *a); - memset (a, 0, sizeof *a); - - a->indx = info->type_stack->type.indx; - a->low = low; - a->high = high; - - a->next = m->arrays; - m->arrays = a; - } - - return true; -} - -/* Make a set type. */ - -static boolean -ieee_set_type (p, bitstringp) - PTR p; - boolean bitstringp; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - boolean localp; - unsigned int eleindx; - - localp = info->type_stack->type.localp; - eleindx = ieee_pop_type (info); - - /* FIXME: We don't know the size, so we just use 4. */ - - return (ieee_define_type (info, 0, true, localp) - && ieee_write_number (info, 's') - && ieee_write_number (info, 4) - && ieee_write_number (info, eleindx)); -} - -/* Make an offset type. */ - -static boolean -ieee_offset_type (p) - PTR p; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - unsigned int targetindx, baseindx; - - targetindx = ieee_pop_type (info); - baseindx = ieee_pop_type (info); - - /* FIXME: The MRI C++ compiler does not appear to generate any - useful type information about an offset type. It just records a - pointer to member as an integer. The MRI/HP IEEE spec does - describe a pmisc record which can be used for a pointer to - member. Unfortunately, it does not describe the target type, - which seems pretty important. I'm going to punt this for now. */ - - return ieee_int_type (p, 4, true); -} - -/* Make a method type. */ - -static boolean -ieee_method_type (p, domain, argcount, varargs) - PTR p; - boolean domain; - int argcount; - boolean varargs; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - /* FIXME: The MRI/HP IEEE spec defines a pmisc record to use for a - method, but the definition is incomplete. We just output an 'x' - type. */ - - if (domain) - ieee_pop_unused_type (info); - - return ieee_function_type (p, argcount, varargs); -} - -/* Make a const qualified type. */ - -static boolean -ieee_const_type (p) - PTR p; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - unsigned int size; - boolean unsignedp, localp; - unsigned int indx; - struct ieee_modified_type *m = NULL; - - size = info->type_stack->type.size; - unsignedp = info->type_stack->type.unsignedp; - localp = info->type_stack->type.localp; - indx = ieee_pop_type (info); - - if (! localp) - { - m = ieee_get_modified_info (info, indx); - if (m == NULL) - return false; - - if (m->const_qualified > 0) - return ieee_push_type (info, m->const_qualified, size, unsignedp, - false); - } - - if (! ieee_define_type (info, size, unsignedp, localp) - || ! ieee_write_number (info, 'n') - || ! ieee_write_number (info, 1) - || ! ieee_write_number (info, indx)) - return false; - - if (! localp) - m->const_qualified = info->type_stack->type.indx; - - return true; -} - -/* Make a volatile qualified type. */ - -static boolean -ieee_volatile_type (p) - PTR p; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - unsigned int size; - boolean unsignedp, localp; - unsigned int indx; - struct ieee_modified_type *m = NULL; - - size = info->type_stack->type.size; - unsignedp = info->type_stack->type.unsignedp; - localp = info->type_stack->type.localp; - indx = ieee_pop_type (info); - - if (! localp) - { - m = ieee_get_modified_info (info, indx); - if (m == NULL) - return false; - - if (m->volatile_qualified > 0) - return ieee_push_type (info, m->volatile_qualified, size, unsignedp, - false); - } - - if (! ieee_define_type (info, size, unsignedp, localp) - || ! ieee_write_number (info, 'n') - || ! ieee_write_number (info, 2) - || ! ieee_write_number (info, indx)) - return false; - - if (! localp) - m->volatile_qualified = info->type_stack->type.indx; - - return true; -} - -/* Convert an enum debug_visibility into a CXXFLAGS value. */ - -static unsigned int -ieee_vis_to_flags (visibility) - enum debug_visibility visibility; -{ - switch (visibility) - { - default: - abort (); - case DEBUG_VISIBILITY_PUBLIC: - return CXXFLAGS_VISIBILITY_PUBLIC; - case DEBUG_VISIBILITY_PRIVATE: - return CXXFLAGS_VISIBILITY_PRIVATE; - case DEBUG_VISIBILITY_PROTECTED: - return CXXFLAGS_VISIBILITY_PROTECTED; - } - /*NOTREACHED*/ -} - -/* Start defining a struct type. We build it in the strdef field on - the stack, to avoid confusing type definitions required by the - fields with the struct type itself. */ - -static boolean -ieee_start_struct_type (p, tag, id, structp, size) - PTR p; - const char *tag; - unsigned int id; - boolean structp; - unsigned int size; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - boolean localp, ignorep; - boolean copy; - char ab[20]; - const char *look; - struct ieee_name_type_hash_entry *h; - struct ieee_name_type *nt, *ntlook; - struct ieee_buflist strdef; - - localp = false; - ignorep = false; - - /* We need to create a tag for internal use even if we don't want - one for external use. This will let us refer to an anonymous - struct. */ - if (tag != NULL) - { - look = tag; - copy = false; - } - else - { - sprintf (ab, "__anon%u", id); - look = ab; - copy = true; - } - - /* If we already have references to the tag, we must use the - existing type index. */ - h = ieee_name_type_hash_lookup (&info->tags, look, true, copy); - if (h == NULL) - return false; - - nt = NULL; - for (ntlook = h->types; ntlook != NULL; ntlook = ntlook->next) - { - if (ntlook->id == id) - nt = ntlook; - else if (! ntlook->type.localp) - { - /* We are creating a duplicate definition of a globally - defined tag. Force it to be local to avoid - confusion. */ - localp = true; - } - } - - if (nt != NULL) - { - assert (localp == nt->type.localp); - if (nt->kind == DEBUG_KIND_ILLEGAL && ! localp) - { - /* We've already seen a global definition of the type. - Ignore this new definition. */ - ignorep = true; - } - } - else - { - nt = (struct ieee_name_type *) xmalloc (sizeof *nt); - memset (nt, 0, sizeof *nt); - nt->id = id; - nt->type.name = h->root.string; - nt->next = h->types; - h->types = nt; - nt->type.indx = info->type_indx; - ++info->type_indx; - } - - nt->kind = DEBUG_KIND_ILLEGAL; - - if (! ieee_init_buffer (info, &strdef) - || ! ieee_define_named_type (info, tag, nt->type.indx, size, true, - localp, &strdef) - || ! ieee_write_number (info, structp ? 'S' : 'U') - || ! ieee_write_number (info, size)) - return false; - - if (! ignorep) - { - const char *hold; - - /* We never want nt->type.name to be NULL. We want the rest of - the type to be the object set up on the type stack; it will - have a NULL name if tag is NULL. */ - hold = nt->type.name; - nt->type = info->type_stack->type; - nt->type.name = hold; - } - - info->type_stack->type.name = tag; - info->type_stack->type.strdef = strdef; - info->type_stack->type.ignorep = ignorep; - - return true; -} - -/* Add a field to a struct. */ - -static boolean -ieee_struct_field (p, name, bitpos, bitsize, visibility) - PTR p; - const char *name; - bfd_vma bitpos; - bfd_vma bitsize; - enum debug_visibility visibility; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - unsigned int size; - boolean unsignedp; - boolean referencep; - boolean localp; - unsigned int indx; - bfd_vma offset; - - assert (info->type_stack != NULL - && info->type_stack->next != NULL - && ! ieee_buffer_emptyp (&info->type_stack->next->type.strdef)); - - /* If we are ignoring this struct definition, just pop and ignore - the type. */ - if (info->type_stack->next->type.ignorep) - { - ieee_pop_unused_type (info); - return true; - } - - size = info->type_stack->type.size; - unsignedp = info->type_stack->type.unsignedp; - referencep = info->type_stack->type.referencep; - localp = info->type_stack->type.localp; - indx = ieee_pop_type (info); - - if (localp) - info->type_stack->type.localp = true; - - if (info->type_stack->type.classdef != NULL) - { - unsigned int flags; - unsigned int nindx; - - /* This is a class. We must add a description of this field to - the class records we are building. */ - - flags = ieee_vis_to_flags (visibility); - nindx = info->type_stack->type.classdef->indx; - if (! ieee_change_buffer (info, - &info->type_stack->type.classdef->pmiscbuf) - || ! ieee_write_asn (info, nindx, 'd') - || ! ieee_write_asn (info, nindx, flags) - || ! ieee_write_atn65 (info, nindx, name) - || ! ieee_write_atn65 (info, nindx, name)) - return false; - info->type_stack->type.classdef->pmisccount += 4; - - if (referencep) - { - unsigned int nindx; - - /* We need to output a record recording that this field is - really of reference type. We put this on the refs field - of classdef, so that it can be appended to the C++ - records after the class is defined. */ - - nindx = info->name_indx; - ++info->name_indx; - - if (! ieee_change_buffer (info, - &info->type_stack->type.classdef->refs) - || ! ieee_write_byte (info, (int) ieee_nn_record) - || ! ieee_write_number (info, nindx) - || ! ieee_write_id (info, "") - || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum) - || ! ieee_write_number (info, nindx) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, 62) - || ! ieee_write_number (info, 80) - || ! ieee_write_number (info, 4) - || ! ieee_write_asn (info, nindx, 'R') - || ! ieee_write_asn (info, nindx, 3) - || ! ieee_write_atn65 (info, nindx, info->type_stack->type.name) - || ! ieee_write_atn65 (info, nindx, name)) - return false; - } - } - - /* If the bitsize doesn't match the expected size, we need to output - a bitfield type. */ - if (size == 0 || bitsize == 0 || bitsize == size * 8) - offset = bitpos / 8; - else - { - if (! ieee_define_type (info, 0, unsignedp, - info->type_stack->type.localp) - || ! ieee_write_number (info, 'g') - || ! ieee_write_number (info, unsignedp ? 0 : 1) - || ! ieee_write_number (info, bitsize) - || ! ieee_write_number (info, indx)) - return false; - indx = ieee_pop_type (info); - offset = bitpos; - } - - /* Switch to the struct we are building in order to output this - field definition. */ - return (ieee_change_buffer (info, &info->type_stack->type.strdef) - && ieee_write_id (info, name) - && ieee_write_number (info, indx) - && ieee_write_number (info, offset)); -} - -/* Finish up a struct type. */ - -static boolean -ieee_end_struct_type (p) - PTR p; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - struct ieee_buflist *pb; - - assert (info->type_stack != NULL - && ! ieee_buffer_emptyp (&info->type_stack->type.strdef)); - - /* If we were ignoring this struct definition because it was a - duplicate defintion, just through away whatever bytes we have - accumulated. Leave the type on the stack. */ - if (info->type_stack->type.ignorep) - return true; - - /* If this is not a duplicate definition of this tag, then localp - will be false, and we can put it in the global type block. - FIXME: We should avoid outputting duplicate definitions which are - the same. */ - if (! info->type_stack->type.localp) - { - /* Make sure we have started the global type block. */ - if (ieee_buffer_emptyp (&info->global_types)) - { - if (! ieee_change_buffer (info, &info->global_types) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 2) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, "")) - return false; - } - pb = &info->global_types; - } - else - { - /* Make sure we have started the types block. */ - if (ieee_buffer_emptyp (&info->types)) - { - if (! ieee_change_buffer (info, &info->types) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 1) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, info->modname)) - return false; - } - pb = &info->types; - } - - /* Append the struct definition to the types. */ - if (! ieee_append_buffer (info, pb, &info->type_stack->type.strdef) - || ! ieee_init_buffer (info, &info->type_stack->type.strdef)) - return false; - - /* Leave the struct on the type stack. */ - - return true; -} - -/* Start a class type. */ - -static boolean -ieee_start_class_type (p, tag, id, structp, size, vptr, ownvptr) - PTR p; - const char *tag; - unsigned int id; - boolean structp; - unsigned int size; - boolean vptr; - boolean ownvptr; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - const char *vclass; - struct ieee_buflist pmiscbuf; - unsigned int indx; - struct ieee_type_class *classdef; - - /* A C++ class is output as a C++ struct along with a set of pmisc - records describing the class. */ - - /* We need to have a name so that we can associate the struct and - the class. */ - if (tag == NULL) - { - char *t; - - t = (char *) xmalloc (20); - sprintf (t, "__anon%u", id); - tag = t; - } - - /* We can't write out the virtual table information until we have - finished the class, because we don't know the virtual table size. - We get the size from the largest voffset we see. */ - vclass = NULL; - if (vptr && ! ownvptr) - { - vclass = info->type_stack->type.name; - assert (vclass != NULL); - /* We don't call ieee_pop_unused_type, since the class should - get defined. */ - (void) ieee_pop_type (info); - } - - if (! ieee_start_struct_type (p, tag, id, structp, size)) - return false; - - indx = info->name_indx; - ++info->name_indx; - - /* We write out pmisc records into the classdef field. We will - write out the pmisc start after we know the number of records we - need. */ - if (! ieee_init_buffer (info, &pmiscbuf) - || ! ieee_change_buffer (info, &pmiscbuf) - || ! ieee_write_asn (info, indx, 'T') - || ! ieee_write_asn (info, indx, structp ? 'o' : 'u') - || ! ieee_write_atn65 (info, indx, tag)) - return false; - - classdef = (struct ieee_type_class *) xmalloc (sizeof *classdef); - memset (classdef, 0, sizeof *classdef); - - classdef->indx = indx; - classdef->pmiscbuf = pmiscbuf; - classdef->pmisccount = 3; - classdef->vclass = vclass; - classdef->ownvptr = ownvptr; - - info->type_stack->type.classdef = classdef; - - return true; -} - -/* Add a static member to a class. */ - -static boolean -ieee_class_static_member (p, name, physname, visibility) - PTR p; - const char *name; - const char *physname; - enum debug_visibility visibility; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - unsigned int flags; - unsigned int nindx; - - /* We don't care about the type. Hopefully there will be a call to - ieee_variable declaring the physical name and the type, since - that is where an IEEE consumer must get the type. */ - ieee_pop_unused_type (info); - - assert (info->type_stack != NULL - && info->type_stack->type.classdef != NULL); - - flags = ieee_vis_to_flags (visibility); - flags |= CXXFLAGS_STATIC; - - nindx = info->type_stack->type.classdef->indx; - - if (! ieee_change_buffer (info, &info->type_stack->type.classdef->pmiscbuf) - || ! ieee_write_asn (info, nindx, 'd') - || ! ieee_write_asn (info, nindx, flags) - || ! ieee_write_atn65 (info, nindx, name) - || ! ieee_write_atn65 (info, nindx, physname)) - return false; - info->type_stack->type.classdef->pmisccount += 4; - - return true; -} - -/* Add a base class to a class. */ - -static boolean -ieee_class_baseclass (p, bitpos, virtual, visibility) - PTR p; - bfd_vma bitpos; - boolean virtual; - enum debug_visibility visibility; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - const char *bname; - boolean localp; - unsigned int bindx; - char *fname; - unsigned int flags; - unsigned int nindx; - - assert (info->type_stack != NULL - && info->type_stack->type.name != NULL - && info->type_stack->next != NULL - && info->type_stack->next->type.classdef != NULL - && ! ieee_buffer_emptyp (&info->type_stack->next->type.strdef)); - - bname = info->type_stack->type.name; - localp = info->type_stack->type.localp; - bindx = ieee_pop_type (info); - - /* We are currently defining both a struct and a class. We must - write out a field definition in the struct which holds the base - class. The stabs debugging reader will create a field named - _vb$CLASS for a virtual base class, so we just use that. FIXME: - we should not depend upon a detail of stabs debugging. */ - if (virtual) - { - fname = (char *) xmalloc (strlen (bname) + sizeof "_vb$"); - sprintf (fname, "_vb$%s", bname); - flags = BASEFLAGS_VIRTUAL; - } - else - { - if (localp) - info->type_stack->type.localp = true; - - fname = (char *) xmalloc (strlen (bname) + sizeof "_b$"); - sprintf (fname, "_b$%s", bname); - - if (! ieee_change_buffer (info, &info->type_stack->type.strdef) - || ! ieee_write_id (info, fname) - || ! ieee_write_number (info, bindx) - || ! ieee_write_number (info, bitpos / 8)) - return false; - flags = 0; - } - - if (visibility == DEBUG_VISIBILITY_PRIVATE) - flags |= BASEFLAGS_PRIVATE; - - nindx = info->type_stack->type.classdef->indx; - - if (! ieee_change_buffer (info, &info->type_stack->type.classdef->pmiscbuf) - || ! ieee_write_asn (info, nindx, 'b') - || ! ieee_write_asn (info, nindx, flags) - || ! ieee_write_atn65 (info, nindx, bname) - || ! ieee_write_asn (info, nindx, 0) - || ! ieee_write_atn65 (info, nindx, fname)) - return false; - info->type_stack->type.classdef->pmisccount += 5; - - free (fname); - - return true; -} - -/* Start building a method for a class. */ - -static boolean -ieee_class_start_method (p, name) - PTR p; - const char *name; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - assert (info->type_stack != NULL - && info->type_stack->type.classdef != NULL - && info->type_stack->type.classdef->method == NULL); - - info->type_stack->type.classdef->method = name; - - return true; -} - -/* Define a new method variant, either static or not. */ - -static boolean -ieee_class_method_var (info, physname, visibility, staticp, constp, - volatilep, voffset, context) - struct ieee_handle *info; - const char *physname; - enum debug_visibility visibility; - boolean staticp; - boolean constp; - boolean volatilep; - bfd_vma voffset; - boolean context; -{ - unsigned int flags; - unsigned int nindx; - boolean virtual; - - /* We don't need the type of the method. An IEEE consumer which - wants the type must track down the function by the physical name - and get the type from that. */ - ieee_pop_unused_type (info); - - /* We don't use the context. FIXME: We probably ought to use it to - adjust the voffset somehow, but I don't really know how. */ - if (context) - ieee_pop_unused_type (info); - - assert (info->type_stack != NULL - && info->type_stack->type.classdef != NULL - && info->type_stack->type.classdef->method != NULL); - - flags = ieee_vis_to_flags (visibility); - - /* FIXME: We never set CXXFLAGS_OVERRIDE, CXXFLAGS_OPERATOR, - CXXFLAGS_CTORDTOR, CXXFLAGS_CTOR, or CXXFLAGS_INLINE. */ - - if (staticp) - flags |= CXXFLAGS_STATIC; - if (constp) - flags |= CXXFLAGS_CONST; - if (volatilep) - flags |= CXXFLAGS_VOLATILE; - - nindx = info->type_stack->type.classdef->indx; - - virtual = context || voffset > 0; - - if (! ieee_change_buffer (info, - &info->type_stack->type.classdef->pmiscbuf) - || ! ieee_write_asn (info, nindx, virtual ? 'v' : 'm') - || ! ieee_write_asn (info, nindx, flags) - || ! ieee_write_atn65 (info, nindx, - info->type_stack->type.classdef->method) - || ! ieee_write_atn65 (info, nindx, physname)) - return false; - - if (virtual) - { - if (voffset > info->type_stack->type.classdef->voffset) - info->type_stack->type.classdef->voffset = voffset; - if (! ieee_write_asn (info, nindx, voffset)) - return false; - ++info->type_stack->type.classdef->pmisccount; - } - - if (! ieee_write_asn (info, nindx, 0)) - return false; - - info->type_stack->type.classdef->pmisccount += 5; - - return true; -} - -/* Define a new method variant. */ - -static boolean -ieee_class_method_variant (p, physname, visibility, constp, volatilep, - voffset, context) - PTR p; - const char *physname; - enum debug_visibility visibility; - boolean constp; - boolean volatilep; - bfd_vma voffset; - boolean context; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - return ieee_class_method_var (info, physname, visibility, false, constp, - volatilep, voffset, context); -} - -/* Define a new static method variant. */ - -static boolean -ieee_class_static_method_variant (p, physname, visibility, constp, volatilep) - PTR p; - const char *physname; - enum debug_visibility visibility; - boolean constp; - boolean volatilep; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - return ieee_class_method_var (info, physname, visibility, true, constp, - volatilep, 0, false); -} - -/* Finish up a method. */ - -static boolean -ieee_class_end_method (p) - PTR p; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - assert (info->type_stack != NULL - && info->type_stack->type.classdef != NULL - && info->type_stack->type.classdef->method != NULL); - - info->type_stack->type.classdef->method = NULL; - - return true; -} - -/* Finish up a class. */ - -static boolean -ieee_end_class_type (p) - PTR p; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - unsigned int nindx; - - assert (info->type_stack != NULL - && info->type_stack->type.classdef != NULL); - - /* If we were ignoring this class definition because it was a - duplicate definition, just through away whatever bytes we have - accumulated. Leave the type on the stack. */ - if (info->type_stack->type.ignorep) - return true; - - nindx = info->type_stack->type.classdef->indx; - - /* If we have a virtual table, we can write out the information now. */ - if (info->type_stack->type.classdef->vclass != NULL - || info->type_stack->type.classdef->ownvptr) - { - if (! ieee_change_buffer (info, - &info->type_stack->type.classdef->pmiscbuf) - || ! ieee_write_asn (info, nindx, 'z') - || ! ieee_write_atn65 (info, nindx, "") - || ! ieee_write_asn (info, nindx, - info->type_stack->type.classdef->voffset)) - return false; - if (info->type_stack->type.classdef->ownvptr) - { - if (! ieee_write_atn65 (info, nindx, "")) - return false; - } - else - { - if (! ieee_write_atn65 (info, nindx, - info->type_stack->type.classdef->vclass)) - return false; - } - if (! ieee_write_asn (info, nindx, 0)) - return false; - info->type_stack->type.classdef->pmisccount += 5; - } - - /* Now that we know the number of pmisc records, we can write out - the atn62 which starts the pmisc records, and append them to the - C++ buffers. */ - - if (! ieee_change_buffer (info, &info->cxx) - || ! ieee_write_byte (info, (int) ieee_nn_record) - || ! ieee_write_number (info, nindx) - || ! ieee_write_id (info, "") - || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum) - || ! ieee_write_number (info, nindx) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, 62) - || ! ieee_write_number (info, 80) - || ! ieee_write_number (info, - info->type_stack->type.classdef->pmisccount)) - return false; - - if (! ieee_append_buffer (info, &info->cxx, - &info->type_stack->type.classdef->pmiscbuf)) - return false; - if (! ieee_buffer_emptyp (&info->type_stack->type.classdef->refs)) - { - if (! ieee_append_buffer (info, &info->cxx, - &info->type_stack->type.classdef->refs)) - return false; - } - - return ieee_end_struct_type (p); -} - -/* Push a previously seen typedef onto the type stack. */ - -static boolean -ieee_typedef_type (p, name) - PTR p; - const char *name; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - struct ieee_name_type_hash_entry *h; - struct ieee_name_type *nt; - - h = ieee_name_type_hash_lookup (&info->typedefs, name, false, false); - - /* h should never be NULL, since that would imply that the generic - debugging code has asked for a typedef which it has not yet - defined. */ - assert (h != NULL); - - /* We always use the most recently defined type for this name, which - will be the first one on the list. */ - - nt = h->types; - if (! ieee_push_type (info, nt->type.indx, nt->type.size, - nt->type.unsignedp, nt->type.localp)) - return false; - - /* Copy over any other type information we may have. */ - info->type_stack->type = nt->type; - - return true; -} - -/* Push a tagged type onto the type stack. */ - -static boolean -ieee_tag_type (p, name, id, kind) - PTR p; - const char *name; - unsigned int id; - enum debug_type_kind kind; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - boolean localp; - boolean copy; - char ab[20]; - struct ieee_name_type_hash_entry *h; - struct ieee_name_type *nt; - - if (kind == DEBUG_KIND_ENUM) - { - struct ieee_defined_enum *e; - - if (name == NULL) - abort (); - for (e = info->enums; e != NULL; e = e->next) - if (e->tag != NULL && strcmp (e->tag, name) == 0) - return ieee_push_type (info, e->indx, 0, true, false); - - e = (struct ieee_defined_enum *) xmalloc (sizeof *e); - memset (e, 0, sizeof *e); - - e->indx = info->type_indx; - ++info->type_indx; - e->tag = name; - e->defined = false; - - e->next = info->enums; - info->enums = e; - - return ieee_push_type (info, e->indx, 0, true, false); - } - - localp = false; - - copy = false; - if (name == NULL) - { - sprintf (ab, "__anon%u", id); - name = ab; - copy = true; - } - - h = ieee_name_type_hash_lookup (&info->tags, name, true, copy); - if (h == NULL) - return false; - - for (nt = h->types; nt != NULL; nt = nt->next) - { - if (nt->id == id) - { - if (! ieee_push_type (info, nt->type.indx, nt->type.size, - nt->type.unsignedp, nt->type.localp)) - return false; - /* Copy over any other type information we may have. */ - info->type_stack->type = nt->type; - return true; - } - - if (! nt->type.localp) - { - /* This is a duplicate of a global type, so it must be - local. */ - localp = true; - } - } - - nt = (struct ieee_name_type *) xmalloc (sizeof *nt); - memset (nt, 0, sizeof *nt); - - nt->id = id; - nt->type.name = h->root.string; - nt->type.indx = info->type_indx; - nt->type.localp = localp; - ++info->type_indx; - nt->kind = kind; - - nt->next = h->types; - h->types = nt; - - if (! ieee_push_type (info, nt->type.indx, 0, false, localp)) - return false; - - info->type_stack->type.name = h->root.string; - - return true; -} - -/* Output a typedef. */ - -static boolean -ieee_typdef (p, name) - PTR p; - const char *name; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - struct ieee_write_type type; - unsigned int indx; - boolean found; - boolean localp; - struct ieee_name_type_hash_entry *h; - struct ieee_name_type *nt; - - type = info->type_stack->type; - indx = type.indx; - - /* If this is a simple builtin type using a builtin name, we don't - want to output the typedef itself. We also want to change the - type index to correspond to the name being used. We recognize - names used in stabs debugging output even if they don't exactly - correspond to the names used for the IEEE builtin types. */ - found = false; - if (indx <= (unsigned int) builtin_bcd_float) - { - switch ((enum builtin_types) indx) - { - default: - break; - - case builtin_void: - if (strcmp (name, "void") == 0) - found = true; - break; - - case builtin_signed_char: - case builtin_char: - if (strcmp (name, "signed char") == 0) - { - indx = (unsigned int) builtin_signed_char; - found = true; - } - else if (strcmp (name, "char") == 0) - { - indx = (unsigned int) builtin_char; - found = true; - } - break; - - case builtin_unsigned_char: - if (strcmp (name, "unsigned char") == 0) - found = true; - break; - - case builtin_signed_short_int: - case builtin_short: - case builtin_short_int: - case builtin_signed_short: - if (strcmp (name, "signed short int") == 0) - { - indx = (unsigned int) builtin_signed_short_int; - found = true; - } - else if (strcmp (name, "short") == 0) - { - indx = (unsigned int) builtin_short; - found = true; - } - else if (strcmp (name, "short int") == 0) - { - indx = (unsigned int) builtin_short_int; - found = true; - } - else if (strcmp (name, "signed short") == 0) - { - indx = (unsigned int) builtin_signed_short; - found = true; - } - break; - - case builtin_unsigned_short_int: - case builtin_unsigned_short: - if (strcmp (name, "unsigned short int") == 0 - || strcmp (name, "short unsigned int") == 0) - { - indx = builtin_unsigned_short_int; - found = true; - } - else if (strcmp (name, "unsigned short") == 0) - { - indx = builtin_unsigned_short; - found = true; - } - break; - - case builtin_signed_long: - case builtin_int: /* FIXME: Size depends upon architecture. */ - case builtin_long: - if (strcmp (name, "signed long") == 0) - { - indx = builtin_signed_long; - found = true; - } - else if (strcmp (name, "int") == 0) - { - indx = builtin_int; - found = true; - } - else if (strcmp (name, "long") == 0 - || strcmp (name, "long int") == 0) - { - indx = builtin_long; - found = true; - } - break; - - case builtin_unsigned_long: - case builtin_unsigned: /* FIXME: Size depends upon architecture. */ - case builtin_unsigned_int: /* FIXME: Like builtin_unsigned. */ - if (strcmp (name, "unsigned long") == 0 - || strcmp (name, "long unsigned int") == 0) - { - indx = builtin_unsigned_long; - found = true; - } - else if (strcmp (name, "unsigned") == 0) - { - indx = builtin_unsigned; - found = true; - } - else if (strcmp (name, "unsigned int") == 0) - { - indx = builtin_unsigned_int; - found = true; - } - break; - - case builtin_signed_long_long: - if (strcmp (name, "signed long long") == 0 - || strcmp (name, "long long int") == 0) - found = true; - break; - - case builtin_unsigned_long_long: - if (strcmp (name, "unsigned long long") == 0 - || strcmp (name, "long long unsigned int") == 0) - found = true; - break; - - case builtin_float: - if (strcmp (name, "float") == 0) - found = true; - break; - - case builtin_double: - if (strcmp (name, "double") == 0) - found = true; - break; - - case builtin_long_double: - if (strcmp (name, "long double") == 0) - found = true; - break; - - case builtin_long_long_double: - if (strcmp (name, "long long double") == 0) - found = true; - break; - } - - if (found) - type.indx = indx; - } - - h = ieee_name_type_hash_lookup (&info->typedefs, name, true, false); - if (h == NULL) - return false; - - /* See if we have already defined this type with this name. */ - localp = type.localp; - for (nt = h->types; nt != NULL; nt = nt->next) - { - if (nt->id == indx) - { - /* If this is a global definition, then we don't need to - do anything here. */ - if (! nt->type.localp) - { - ieee_pop_unused_type (info); - return true; - } - } - else - { - /* This is a duplicate definition, so make this one local. */ - localp = true; - } - } - - /* We need to add a new typedef for this type. */ - - nt = (struct ieee_name_type *) xmalloc (sizeof *nt); - memset (nt, 0, sizeof *nt); - nt->id = indx; - nt->type = type; - nt->type.name = name; - nt->type.localp = localp; - nt->kind = DEBUG_KIND_ILLEGAL; - - nt->next = h->types; - h->types = nt; - - if (found) - { - /* This is one of the builtin typedefs, so we don't need to - actually define it. */ - ieee_pop_unused_type (info); - return true; - } - - indx = ieee_pop_type (info); - - if (! ieee_define_named_type (info, name, (unsigned int) -1, type.size, - type.unsignedp, localp, - (struct ieee_buflist *) NULL) - || ! ieee_write_number (info, 'T') - || ! ieee_write_number (info, indx)) - return false; - - /* Remove the type we just added to the type stack. This should not - be ieee_pop_unused_type, since the type is used, we just don't - need it now. */ - (void) ieee_pop_type (info); - - return true; -} - -/* Output a tag for a type. We don't have to do anything here. */ - -static boolean -ieee_tag (p, name) - PTR p; - const char *name; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - /* This should not be ieee_pop_unused_type, since we want the type - to be defined. */ - (void) ieee_pop_type (info); - return true; -} - -/* Output an integer constant. */ - -static boolean -ieee_int_constant (p, name, val) - PTR p; - const char *name; - bfd_vma val; -{ - /* FIXME. */ - return true; -} - -/* Output a floating point constant. */ - -static boolean -ieee_float_constant (p, name, val) - PTR p; - const char *name; - double val; -{ - /* FIXME. */ - return true; -} - -/* Output a typed constant. */ - -static boolean -ieee_typed_constant (p, name, val) - PTR p; - const char *name; - bfd_vma val; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - /* FIXME. */ - ieee_pop_unused_type (info); - return true; -} - -/* Output a variable. */ - -static boolean -ieee_variable (p, name, kind, val) - PTR p; - const char *name; - enum debug_var_kind kind; - bfd_vma val; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - unsigned int name_indx; - unsigned int size; - boolean referencep; - unsigned int type_indx; - boolean asn; - int refflag; - - size = info->type_stack->type.size; - referencep = info->type_stack->type.referencep; - type_indx = ieee_pop_type (info); - - assert (! ieee_buffer_emptyp (&info->vars)); - if (! ieee_change_buffer (info, &info->vars)) - return false; - - name_indx = info->name_indx; - ++info->name_indx; - - /* Write out an NN and an ATN record for this variable. */ - if (! ieee_write_byte (info, (int) ieee_nn_record) - || ! ieee_write_number (info, name_indx) - || ! ieee_write_id (info, name) - || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum) - || ! ieee_write_number (info, name_indx) - || ! ieee_write_number (info, type_indx)) - return false; - switch (kind) - { - default: - abort (); - return false; - case DEBUG_GLOBAL: - if (! ieee_write_number (info, 8) - || ! ieee_add_range (info, false, val, val + size)) - return false; - refflag = 0; - asn = true; - break; - case DEBUG_STATIC: - if (! ieee_write_number (info, 3) - || ! ieee_add_range (info, false, val, val + size)) - return false; - refflag = 1; - asn = true; - break; - case DEBUG_LOCAL_STATIC: - if (! ieee_write_number (info, 3) - || ! ieee_add_range (info, false, val, val + size)) - return false; - refflag = 2; - asn = true; - break; - case DEBUG_LOCAL: - if (! ieee_write_number (info, 1) - || ! ieee_write_number (info, val)) - return false; - refflag = 2; - asn = false; - break; - case DEBUG_REGISTER: - if (! ieee_write_number (info, 2) - || ! ieee_write_number (info, - ieee_genreg_to_regno (info->abfd, val))) - return false; - refflag = 2; - asn = false; - break; - } - - if (asn) - { - if (! ieee_write_asn (info, name_indx, val)) - return false; - } - - /* If this is really a reference type, then we just output it with - pointer type, and must now output a C++ record indicating that it - is really reference type. */ - if (referencep) - { - unsigned int nindx; - - nindx = info->name_indx; - ++info->name_indx; - - /* If this is a global variable, we want to output the misc - record in the C++ misc record block. Otherwise, we want to - output it just after the variable definition, which is where - the current buffer is. */ - if (refflag != 2) - { - if (! ieee_change_buffer (info, &info->cxx)) - return false; - } - - if (! ieee_write_byte (info, (int) ieee_nn_record) - || ! ieee_write_number (info, nindx) - || ! ieee_write_id (info, "") - || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum) - || ! ieee_write_number (info, nindx) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, 62) - || ! ieee_write_number (info, 80) - || ! ieee_write_number (info, 3) - || ! ieee_write_asn (info, nindx, 'R') - || ! ieee_write_asn (info, nindx, refflag) - || ! ieee_write_atn65 (info, nindx, name)) - return false; - } - - return true; -} - -/* Start outputting information for a function. */ - -static boolean -ieee_start_function (p, name, global) - PTR p; - const char *name; - boolean global; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - boolean referencep; - unsigned int retindx, typeindx; - - referencep = info->type_stack->type.referencep; - retindx = ieee_pop_type (info); - - /* Besides recording a BB4 or BB6 block, we record the type of the - function in the BB1 typedef block. We can't write out the full - type until we have seen all the parameters, so we accumulate it - in info->fntype and info->fnargs. */ - if (! ieee_buffer_emptyp (&info->fntype)) - { - /* FIXME: This might happen someday if we support nested - functions. */ - abort (); - } - - info->fnname = name; - - /* An attribute of 0x40 means that the push mask is unknown. */ - if (! ieee_define_named_type (info, name, (unsigned int) -1, 0, false, true, - &info->fntype) - || ! ieee_write_number (info, 'x') - || ! ieee_write_number (info, 0x40) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, retindx)) - return false; - - typeindx = ieee_pop_type (info); - - if (! ieee_init_buffer (info, &info->fnargs)) - return false; - info->fnargcount = 0; - - /* If the function return value is actually a reference type, we - must add a record indicating that. */ - if (referencep) - { - unsigned int nindx; - - nindx = info->name_indx; - ++info->name_indx; - if (! ieee_change_buffer (info, &info->cxx) - || ! ieee_write_byte (info, (int) ieee_nn_record) - || ! ieee_write_number (info, nindx) - || ! ieee_write_id (info, "") - || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum) - || ! ieee_write_number (info, nindx) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, 62) - || ! ieee_write_number (info, 80) - || ! ieee_write_number (info, 3) - || ! ieee_write_asn (info, nindx, 'R') - || ! ieee_write_asn (info, nindx, global ? 0 : 1) - || ! ieee_write_atn65 (info, nindx, name)) - return false; - } - - assert (! ieee_buffer_emptyp (&info->vars)); - if (! ieee_change_buffer (info, &info->vars)) - return false; - - /* The address is written out as the first block. */ - - ++info->block_depth; - - return (ieee_write_byte (info, (int) ieee_bb_record_enum) - && ieee_write_byte (info, global ? 4 : 6) - && ieee_write_number (info, 0) - && ieee_write_id (info, name) - && ieee_write_number (info, 0) - && ieee_write_number (info, typeindx)); -} - -/* Add a function parameter. This will normally be called before the - first block, so we postpone them until we see the block. */ - -static boolean -ieee_function_parameter (p, name, kind, val) - PTR p; - const char *name; - enum debug_parm_kind kind; - bfd_vma val; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - struct ieee_pending_parm *m, **pm; - - assert (info->block_depth == 1); - - m = (struct ieee_pending_parm *) xmalloc (sizeof *m); - memset (m, 0, sizeof *m); - - m->next = NULL; - m->name = name; - m->referencep = info->type_stack->type.referencep; - m->type = ieee_pop_type (info); - m->kind = kind; - m->val = val; - - for (pm = &info->pending_parms; *pm != NULL; pm = &(*pm)->next) - ; - *pm = m; - - /* Add the type to the fnargs list. */ - if (! ieee_change_buffer (info, &info->fnargs) - || ! ieee_write_number (info, m->type)) - return false; - ++info->fnargcount; - - return true; -} - -/* Output pending function parameters. */ - -static boolean -ieee_output_pending_parms (info) - struct ieee_handle *info; -{ - struct ieee_pending_parm *m; - unsigned int refcount; - - refcount = 0; - for (m = info->pending_parms; m != NULL; m = m->next) - { - enum debug_var_kind vkind; - - switch (m->kind) - { - default: - abort (); - return false; - case DEBUG_PARM_STACK: - case DEBUG_PARM_REFERENCE: - vkind = DEBUG_LOCAL; - break; - case DEBUG_PARM_REG: - case DEBUG_PARM_REF_REG: - vkind = DEBUG_REGISTER; - break; - } - - if (! ieee_push_type (info, m->type, 0, false, false)) - return false; - info->type_stack->type.referencep = m->referencep; - if (m->referencep) - ++refcount; - if (! ieee_variable ((PTR) info, m->name, vkind, m->val)) - return false; - } - - /* If there are any reference parameters, we need to output a - miscellaneous record indicating them. */ - if (refcount > 0) - { - unsigned int nindx, varindx; - - /* FIXME: The MRI compiler outputs the demangled function name - here, but we are outputting the mangled name. */ - nindx = info->name_indx; - ++info->name_indx; - if (! ieee_change_buffer (info, &info->vars) - || ! ieee_write_byte (info, (int) ieee_nn_record) - || ! ieee_write_number (info, nindx) - || ! ieee_write_id (info, "") - || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum) - || ! ieee_write_number (info, nindx) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, 62) - || ! ieee_write_number (info, 80) - || ! ieee_write_number (info, refcount + 3) - || ! ieee_write_asn (info, nindx, 'B') - || ! ieee_write_atn65 (info, nindx, info->fnname) - || ! ieee_write_asn (info, nindx, 0)) - return false; - for (m = info->pending_parms, varindx = 1; - m != NULL; - m = m->next, varindx++) - { - if (m->referencep) - { - if (! ieee_write_asn (info, nindx, varindx)) - return false; - } - } - } - - m = info->pending_parms; - while (m != NULL) - { - struct ieee_pending_parm *next; - - next = m->next; - free (m); - m = next; - } - - info->pending_parms = NULL; - - return true; -} - -/* Start a block. If this is the first block, we output the address - to finish the BB4 or BB6, and then output the function parameters. */ - -static boolean -ieee_start_block (p, addr) - PTR p; - bfd_vma addr; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - if (! ieee_change_buffer (info, &info->vars)) - return false; - - if (info->block_depth == 1) - { - if (! ieee_write_number (info, addr) - || ! ieee_output_pending_parms (info)) - return false; - } - else - { - if (! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 6) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, "") - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, addr)) - return false; - } - - if (! ieee_start_range (info, addr)) - return false; - - ++info->block_depth; - - return true; -} - -/* End a block. */ - -static boolean -ieee_end_block (p, addr) - PTR p; - bfd_vma addr; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - /* The address we are given is the end of the block, but IEEE seems - to want to the address of the last byte in the block, so we - subtract one. */ - if (! ieee_change_buffer (info, &info->vars) - || ! ieee_write_byte (info, (int) ieee_be_record_enum) - || ! ieee_write_number (info, addr - 1)) - return false; - - if (! ieee_end_range (info, addr)) - return false; - - --info->block_depth; - - if (addr > info->highaddr) - info->highaddr = addr; - - return true; -} - -/* End a function. */ - -static boolean -ieee_end_function (p) - PTR p; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - assert (info->block_depth == 1); - - --info->block_depth; - - /* Now we can finish up fntype, and add it to the typdef section. - At this point, fntype is the 'x' type up to the argument count, - and fnargs is the argument types. We must add the argument - count, and we must add the level. FIXME: We don't record varargs - functions correctly. In fact, stabs debugging does not give us - enough information to do so. */ - if (! ieee_change_buffer (info, &info->fntype) - || ! ieee_write_number (info, info->fnargcount) - || ! ieee_change_buffer (info, &info->fnargs) - || ! ieee_write_number (info, 0)) - return false; - - /* Make sure the typdef block has been started. */ - if (ieee_buffer_emptyp (&info->types)) - { - if (! ieee_change_buffer (info, &info->types) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 1) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, info->modname)) - return false; - } - - if (! ieee_append_buffer (info, &info->types, &info->fntype) - || ! ieee_append_buffer (info, &info->types, &info->fnargs)) - return false; - - info->fnname = NULL; - if (! ieee_init_buffer (info, &info->fntype) - || ! ieee_init_buffer (info, &info->fnargs)) - return false; - info->fnargcount = 0; - - return true; -} - -/* Record line number information. */ - -static boolean -ieee_lineno (p, filename, lineno, addr) - PTR p; - const char *filename; - unsigned long lineno; - bfd_vma addr; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - assert (info->filename != NULL); - - /* The HP simulator seems to get confused when more than one line is - listed for the same address, at least if they are in different - files. We handle this by always listing the last line for a - given address, since that seems to be the one that gdb uses. */ - if (info->pending_lineno_filename != NULL - && addr != info->pending_lineno_addr) - { - /* Make sure we have a line number block. */ - if (! ieee_buffer_emptyp (&info->linenos)) - { - if (! ieee_change_buffer (info, &info->linenos)) - return false; - } - else - { - info->lineno_name_indx = info->name_indx; - ++info->name_indx; - if (! ieee_change_buffer (info, &info->linenos) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 5) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, info->filename) - || ! ieee_write_byte (info, (int) ieee_nn_record) - || ! ieee_write_number (info, info->lineno_name_indx) - || ! ieee_write_id (info, "")) - return false; - info->lineno_filename = info->filename; - } - - if (strcmp (info->pending_lineno_filename, info->lineno_filename) != 0) - { - if (strcmp (info->filename, info->lineno_filename) != 0) - { - /* We were not in the main file. Close the block for the - included file. */ - if (! ieee_write_byte (info, (int) ieee_be_record_enum)) - return false; - if (strcmp (info->filename, info->pending_lineno_filename) == 0) - { - /* We need a new NN record, and we aren't about to - output one. */ - info->lineno_name_indx = info->name_indx; - ++info->name_indx; - if (! ieee_write_byte (info, (int) ieee_nn_record) - || ! ieee_write_number (info, info->lineno_name_indx) - || ! ieee_write_id (info, "")) - return false; - } - } - if (strcmp (info->filename, info->pending_lineno_filename) != 0) - { - /* We are not changing to the main file. Open a block for - the new included file. */ - info->lineno_name_indx = info->name_indx; - ++info->name_indx; - if (! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 5) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, info->pending_lineno_filename) - || ! ieee_write_byte (info, (int) ieee_nn_record) - || ! ieee_write_number (info, info->lineno_name_indx) - || ! ieee_write_id (info, "")) - return false; - } - info->lineno_filename = info->pending_lineno_filename; - } - - if (! ieee_write_2bytes (info, (int) ieee_atn_record_enum) - || ! ieee_write_number (info, info->lineno_name_indx) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, 7) - || ! ieee_write_number (info, info->pending_lineno) - || ! ieee_write_number (info, 0) - || ! ieee_write_asn (info, info->lineno_name_indx, - info->pending_lineno_addr)) - return false; - } - - info->pending_lineno_filename = filename; - info->pending_lineno = lineno; - info->pending_lineno_addr = addr; - - return true; -} diff --git a/pstack/ieee.h b/pstack/ieee.h deleted file mode 100644 index 56634b2819a..00000000000 --- a/pstack/ieee.h +++ /dev/null @@ -1,138 +0,0 @@ -/* IEEE Standard 695-1980 "Universal Format for Object Modules" header file - Contributed by Cygnus Support. */ - -#define N_W_VARIABLES 8 -#define Module_Beginning 0xe0 - -typedef struct ieee_module { - char *processor; - char *module_name; -} ieee_module_begin_type; - -#define Address_Descriptor 0xec -typedef struct ieee_address { -bfd_vma number_of_bits_mau; - bfd_vma number_of_maus_in_address; - - unsigned char byte_order; -#define IEEE_LITTLE 0xcc -#define IEEE_BIG 0xcd -} ieee_address_descriptor_type; - -typedef union ieee_w_variable { - file_ptr offset[N_W_VARIABLES]; - struct { - file_ptr extension_record; - file_ptr environmental_record; - file_ptr section_part; - file_ptr external_part; - file_ptr debug_information_part; - file_ptr data_part; - file_ptr trailer_part; - file_ptr me_record; - } r; -} ieee_w_variable_type; - - - - - -typedef enum ieee_record -{ - ieee_number_start_enum = 0x00, - ieee_number_end_enum=0x7f, - ieee_number_repeat_start_enum = 0x80, - ieee_number_repeat_end_enum = 0x88, - ieee_number_repeat_4_enum = 0x84, - ieee_number_repeat_3_enum = 0x83, - ieee_number_repeat_2_enum = 0x82, - ieee_number_repeat_1_enum = 0x81, - ieee_module_beginning_enum = 0xe0, - ieee_module_end_enum = 0xe1, - ieee_extension_length_1_enum = 0xde, - ieee_extension_length_2_enum = 0xdf, - ieee_section_type_enum = 0xe6, - ieee_section_alignment_enum = 0xe7, - ieee_external_symbol_enum = 0xe8, - ieee_comma = 0x90, - ieee_external_reference_enum = 0xe9, - ieee_set_current_section_enum = 0xe5, - ieee_address_descriptor_enum = 0xec, - ieee_load_constant_bytes_enum = 0xed, - ieee_load_with_relocation_enum = 0xe4, - - ieee_variable_A_enum = 0xc1, - ieee_variable_B_enum = 0xc2, - ieee_variable_C_enum = 0xc3, - ieee_variable_D_enum = 0xc4, - ieee_variable_E_enum = 0xc5, - ieee_variable_F_enum = 0xc6, - ieee_variable_G_enum = 0xc7, - ieee_variable_H_enum = 0xc8, - ieee_variable_I_enum = 0xc9, - ieee_variable_J_enum = 0xca, - ieee_variable_K_enum = 0xcb, - ieee_variable_L_enum = 0xcc, - ieee_variable_M_enum = 0xcd, - ieee_variable_N_enum = 0xce, - ieee_variable_O_enum = 0xcf, - ieee_variable_P_enum = 0xd0, - ieee_variable_Q_enum = 0xd1, - ieee_variable_R_enum = 0xd2, - ieee_variable_S_enum = 0xd3, - ieee_variable_T_enum = 0xd4, - ieee_variable_U_enum = 0xd5, - ieee_variable_V_enum = 0xd6, - ieee_variable_W_enum = 0xd7, - ieee_variable_X_enum = 0xd8, - ieee_variable_Y_enum = 0xd9, - ieee_variable_Z_enum = 0xda, - ieee_function_plus_enum = 0xa5, - ieee_function_minus_enum = 0xa6, - ieee_function_signed_open_b_enum = 0xba, - ieee_function_signed_close_b_enum = 0xbb, - - ieee_function_unsigned_open_b_enum = 0xbc, - ieee_function_unsigned_close_b_enum = 0xbd, - - ieee_function_either_open_b_enum = 0xbe, - ieee_function_either_close_b_enum = 0xbf, - ieee_record_seperator_enum = 0xdb, - - ieee_e2_first_byte_enum = 0xe2, - ieee_section_size_enum = 0xe2d3, - ieee_physical_region_size_enum = 0xe2c1, - ieee_region_base_address_enum = 0xe2c2, - ieee_mau_size_enum = 0xe2c6, - ieee_m_value_enum = 0xe2cd, - ieee_section_base_address_enum = 0xe2cc, - ieee_asn_record_enum = 0xe2ce, - ieee_section_offset_enum = 0xe2d2, - ieee_value_starting_address_enum = 0xe2c7, - ieee_assign_value_to_variable_enum = 0xe2d7, - ieee_set_current_pc_enum = 0xe2d0, - ieee_value_record_enum = 0xe2c9, - ieee_nn_record = 0xf0, - ieee_at_record_enum = 0xf1, - ieee_ty_record_enum = 0xf2, - ieee_attribute_record_enum = 0xf1c9, - ieee_atn_record_enum = 0xf1ce, - ieee_external_reference_info_record_enum = 0xf1d8, - ieee_weak_external_reference_enum= 0xf4, - ieee_repeat_data_enum = 0xf7, - ieee_bb_record_enum = 0xf8, - ieee_be_record_enum = 0xf9 -} ieee_record_enum_type; - - -typedef struct ieee_section { - unsigned int section_index; - unsigned int section_type; - char *section_name; - unsigned int parent_section_index; - unsigned int sibling_section_index; - unsigned int context_index; -} ieee_section_type; -#define IEEE_REFERENCE_BASE 11 -#define IEEE_PUBLIC_BASE 32 -#define IEEE_SECTION_NUMBER_BASE 1 diff --git a/pstack/libiberty.h b/pstack/libiberty.h deleted file mode 100644 index ca0043d31c6..00000000000 --- a/pstack/libiberty.h +++ /dev/null @@ -1,180 +0,0 @@ -/* Function declarations for libiberty. - Written by Cygnus Support, 1994. - - The libiberty library provides a number of functions which are - missing on some operating systems. We do not declare those here, - to avoid conflicts with the system header files on operating - systems that do support those functions. In this file we only - declare those functions which are specific to libiberty. */ - -#ifndef LIBIBERTY_H -#define LIBIBERTY_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "ansidecl.h" - -/* Build an argument vector from a string. Allocates memory using - malloc. Use freeargv to free the vector. */ - -extern char **buildargv PARAMS ((char *)); - -/* Free a vector returned by buildargv. */ - -extern void freeargv PARAMS ((char **)); - -/* Duplicate an argument vector. Allocates memory using malloc. Use - freeargv to free the vector. */ - -extern char **dupargv PARAMS ((char **)); - - -/* Return the last component of a path name. Note that we can't use a - prototype here because the parameter is declared inconsistently - across different systems, sometimes as "char *" and sometimes as - "const char *" */ - -#if defined (__GNU_LIBRARY__ ) || defined (__linux__) || defined (__FreeBSD__) -extern char *basename PARAMS ((const char *)); -#else -extern char *basename (); -#endif - -/* Concatenate an arbitrary number of strings, up to (char *) NULL. - Allocates memory using xmalloc. */ - -extern char *concat PARAMS ((const char *, ...)); - -/* Check whether two file descriptors refer to the same file. */ - -extern int fdmatch PARAMS ((int fd1, int fd2)); - -/* Get the amount of time the process has run, in microseconds. */ - -extern long get_run_time PARAMS ((void)); - -/* Choose a temporary directory to use for scratch files. */ - -extern char *choose_temp_base PARAMS ((void)); - -/* Allocate memory filled with spaces. Allocates using malloc. */ - -extern const char *spaces PARAMS ((int count)); - -/* Return the maximum error number for which strerror will return a - string. */ - -extern int errno_max PARAMS ((void)); - -/* Return the name of an errno value (e.g., strerrno (EINVAL) returns - "EINVAL"). */ - -extern const char *strerrno PARAMS ((int)); - -/* Given the name of an errno value, return the value. */ - -extern int strtoerrno PARAMS ((const char *)); - -/* ANSI's strerror(), but more robust. */ - -extern char *xstrerror PARAMS ((int)); - -/* Return the maximum signal number for which strsignal will return a - string. */ - -extern int signo_max PARAMS ((void)); - -/* Return a signal message string for a signal number - (e.g., strsignal (SIGHUP) returns something like "Hangup"). */ -/* This is commented out as it can conflict with one in system headers. - We still document its existence though. */ - -/*extern const char *strsignal PARAMS ((int));*/ - -/* Return the name of a signal number (e.g., strsigno (SIGHUP) returns - "SIGHUP"). */ - -extern const char *strsigno PARAMS ((int)); - -/* Given the name of a signal, return its number. */ - -extern int strtosigno PARAMS ((const char *)); - -/* Register a function to be run by xexit. Returns 0 on success. */ - -extern int xatexit PARAMS ((void (*fn) (void))); - -/* Exit, calling all the functions registered with xatexit. */ - -#ifndef __GNUC__ -extern void xexit PARAMS ((int status)); -#else -void xexit PARAMS ((int status)) __attribute__ ((noreturn)); -#endif - -/* Set the program name used by xmalloc. */ - -extern void xmalloc_set_program_name PARAMS ((const char *)); - -/* Allocate memory without fail. If malloc fails, this will print a - message to stderr (using the name set by xmalloc_set_program_name, - if any) and then call xexit. */ - -#ifdef ANSI_PROTOTYPES -/* Get a definition for size_t. */ -#include -#endif -extern PTR xmalloc PARAMS ((size_t)); - -/* Reallocate memory without fail. This works like xmalloc. - - FIXME: We do not declare the parameter types for the same reason as - xmalloc. */ - -extern PTR xrealloc PARAMS ((PTR, size_t)); - -/* Allocate memory without fail and set it to zero. This works like - xmalloc. */ - -extern PTR xcalloc PARAMS ((size_t, size_t)); - -/* Copy a string into a memory buffer without fail. */ - -extern char *xstrdup PARAMS ((const char *)); - -/* hex character manipulation routines */ - -#define _hex_array_size 256 -#define _hex_bad 99 -extern char _hex_value[_hex_array_size]; -extern void hex_init PARAMS ((void)); -#define hex_p(c) (hex_value (c) != _hex_bad) -/* If you change this, note well: Some code relies on side effects in - the argument being performed exactly once. */ -#define hex_value(c) (_hex_value[(unsigned char) (c)]) - -/* Definitions used by the pexecute routine. */ - -#define PEXECUTE_FIRST 1 -#define PEXECUTE_LAST 2 -#define PEXECUTE_ONE (PEXECUTE_FIRST + PEXECUTE_LAST) -#define PEXECUTE_SEARCH 4 -#define PEXECUTE_VERBOSE 8 - -/* Execute a program. */ - -extern int pexecute PARAMS ((const char *, char * const *, const char *, - const char *, char **, char **, int)); - -/* Wait for pexecute to finish. */ - -extern int pwait PARAMS ((int, int *, int)); - -#ifdef __cplusplus -} -#endif - - -#endif /* ! defined (LIBIBERTY_H) */ diff --git a/pstack/linuxthreads.c b/pstack/linuxthreads.c deleted file mode 100644 index 8624bd21782..00000000000 --- a/pstack/linuxthreads.c +++ /dev/null @@ -1,90 +0,0 @@ -/* $Header$ */ - -/* - * LinuxThreads specific stuff. - */ - -#include - -#include -#include /* PTHREAD_THREADS_MAX */ -#include -#include -#include -#include -#include - -#include "linuxthreads.h" - -#define AT_INT(intval) *((int32_t*)(intval)) - -/* - * Internal LinuxThreads variables. - * Official interface exposed to GDB. - */ -#if 1 -extern volatile int __pthread_threads_debug; -extern volatile char __pthread_handles; -extern char __pthread_initial_thread; -/*extern volatile Elf32_Sym* __pthread_manager_thread;*/ -extern const int __pthread_sizeof_handle; -extern const int __pthread_offsetof_descr; -extern const int __pthread_offsetof_pid; -extern volatile int __pthread_handles_num; -#endif /* 0 */ - -/* - * Notify others. - */ -int -linuxthreads_notify_others( const int signotify) -{ - const pid_t mypid = getpid(); - //const pthread_t mytid = pthread_self(); - int i; - int threadcount = 0; - int threads[PTHREAD_THREADS_MAX]; - int pid; - - TRACE_FPRINTF((stderr, "theadcount:%d\n", __pthread_handles_num)); - if (__pthread_handles_num==2) { - /* no threads beside the initial thread */ - return 0; - } - /*assert(maxthreads>=3); - assert(maxthreads>=__pthread_handles_num+2);*/ - - // take the initial thread with us - pid = AT_INT(&__pthread_initial_thread + __pthread_offsetof_pid); - if (pid!=mypid && pid!=0) - threads[threadcount++] = pid; - // don't know why, but always handles[0]==handles[1] - for (i=1; i<__pthread_handles_num; ++i) { - const int descr = AT_INT(&__pthread_handles+i*__pthread_sizeof_handle+__pthread_offsetof_descr); - assert(descr!=0); - pid = AT_INT(descr+__pthread_offsetof_pid); - if (pid!=mypid && pid!=0) - threads[threadcount++] = pid; - } - /* TRACE_FPRINTF((stderr, "Stopping threads...")); */ - //for (i=0; i -#include "pstacktrace.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Tell other threads to dump stacks... - */ -int -linuxthreads_notify_others( const int signotify); - -#ifdef __cplusplus -} -#endif - -#endif /* pstack_linuxthreads_h_ */ - diff --git a/pstack/pstack.c b/pstack/pstack.c deleted file mode 100644 index 4cdd80d68b5..00000000000 --- a/pstack/pstack.c +++ /dev/null @@ -1,2746 +0,0 @@ -/* - pstack.c -- asynchronous stack trace of a running process - Copyright (c) 1999 Ross Thompson - Author: Ross Thompson - Critical bug fix: Tim Waugh -*/ - -/* - This file is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -/* RESTRICTIONS: - - pstack currently works only on Linux, only on an x86 machine running - 32 bit ELF binaries (64 bit not supported). Also, for symbolic - information, you need to use a GNU compiler to generate your - program, and you can't strip symbols from the binaries. For thread - information to be dumped, you have to use the debug-aware version - of libpthread.so. (To check, run 'nm' on your libpthread.so, and - make sure that the symbol "__pthread_threads_debug" is defined.) - - The details of pulling stuff out of ELF files and running through - program images is very platform specific, and I don't want to - try to support modes or machine types I can't test in or on. - If someone wants to generalize this to other architectures, I would - be happy to help and coordinate the activity. Please send me whatever - changes you make to support these machines, so that I can own the - central font of all truth (at least as regards this program). - - Thanks -*/ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* PTHREAD_THREADS_MAX */ - - -#include - -#include "libiberty.h" - -#include "pstack.h" /* just one function */ -#include "budbg.h" /* binutils stuff related to debugging symbols. */ -#include "bucomm.h" /* some common stuff */ -#include "debug.h" /* and more binutils stuff... */ -#include "budbg.h" -#include "linuxthreads.h" /* LinuxThreads specific stuff... */ - - -/* - * fprintf for file descriptors :) NOTE: we have to use fixed-size buffer :)( - * due to malloc's unavalaibility. - */ -int -fdprintf( int fd, - const char* fmt,...) -{ - char xbuf[2048];// FIXME: enough? - va_list ap; - int r; - if (fd<0) - return -1; - va_start(ap, fmt); - r = vsnprintf(xbuf, sizeof(xbuf), fmt, ap); - va_end(ap); - return write(fd, xbuf, r); -} - -int -fdputc( char c, - int fd) -{ - if (fd<0) - return -1; - return write(fd, &c, sizeof(c)); -} - -int -fdputs( const char* s, - int fd) -{ - if (fd<0) - return -1; - return write(fd, s, strlen(s)); -} - -/* - * Use this function to open log file. - * Flags: truncate on opening. - */ -static const char* path_format = "stack-trace-on-segv-%d.txt"; -static int -open_log_file( const pthread_t tid, - const pid_t pid) -{ - char fname[PATH_MAX]; - int r; - snprintf(fname, sizeof(fname), path_format, tid, pid); - r = open(fname, O_WRONLY|O_CREAT|O_TRUNC, - S_IRUSR|S_IWUSR); - if (r<0) - perror("open"); - return r; -} -/* - * Add additional debugging information for functions. - */ - -/* - * Lineno - */ -typedef struct { - int lineno; - bfd_vma addr; -} debug_lineno_t; - -/* - * Block - a {} pair. - */ -typedef struct debug_block_st { - bfd_vma begin_addr; /* where did it start */ - bfd_vma end_addr; /* where did it end */ - struct debug_block_st* parent; - struct debug_block_st* childs; - int childs_count; -} debug_block_t; - -/* - * Function parameter. - */ -typedef struct { - bfd_vma offset; /* Offset in the stack */ - const char* name; /* And name. */ -} debug_parameter_t; - -/* - * Extra information about functions. - */ -typedef struct { - asymbol* symbol; /* mangled function name, addr */ - debug_lineno_t* lines; - int lines_count; - int max_lines_count; - const char* name; - const char* filename;/* a file name it occured in... */ - debug_block_t* block; /* each function has a block, or not, you know */ - debug_parameter_t* argv; /* argument types. */ - int argc; - int max_argc; -} debug_function_t; - -/* This is the structure we use as a handle for these routines. */ -struct pr_handle -{ - /* File to print information to. */ - FILE *f; - /* Current indentation level. */ - unsigned int indent; - /* Type stack. */ - struct pr_stack *stack; - /* Parameter number we are about to output. */ - int parameter; - debug_block_t* block; /* current block */ - debug_function_t* function; /* current function */ - debug_function_t* functions; /* all functions */ - int functions_size; /* current size */ - int functions_maxsize; /* maximum size */ -}; - -/* The type stack. */ - -struct pr_stack -{ - /* Next element on the stack. */ - struct pr_stack *next; - /* This element. */ - char *type; - /* Current visibility of fields if this is a class. */ - enum debug_visibility visibility; - /* Name of the current method we are handling. */ - const char *method; -}; - -static void indent PARAMS ((struct pr_handle *)); -static boolean push_type PARAMS ((struct pr_handle *, const char *)); -static boolean prepend_type PARAMS ((struct pr_handle *, const char *)); -static boolean append_type PARAMS ((struct pr_handle *, const char *)); -static boolean substitute_type PARAMS ((struct pr_handle *, const char *)); -static boolean indent_type PARAMS ((struct pr_handle *)); -static char *pop_type PARAMS ((struct pr_handle *)); -static void print_vma PARAMS ((bfd_vma, char *, boolean, boolean)); -static boolean pr_fix_visibility - PARAMS ((struct pr_handle *, enum debug_visibility)); - -static boolean pr_start_compilation_unit PARAMS ((PTR, const char *)); -static boolean pr_start_source PARAMS ((PTR, const char *)); -static boolean pr_empty_type PARAMS ((PTR)); -static boolean pr_void_type PARAMS ((PTR)); -static boolean pr_int_type PARAMS ((PTR, unsigned int, boolean)); -static boolean pr_float_type PARAMS ((PTR, unsigned int)); -static boolean pr_complex_type PARAMS ((PTR, unsigned int)); -static boolean pr_bool_type PARAMS ((PTR, unsigned int)); -static boolean pr_enum_type - PARAMS ((PTR, const char *, const char **, bfd_signed_vma *)); -static boolean pr_pointer_type PARAMS ((PTR)); -static boolean pr_function_type PARAMS ((PTR, int, boolean)); -static boolean pr_reference_type PARAMS ((PTR)); -static boolean pr_range_type PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma)); -static boolean pr_array_type - PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma, boolean)); -static boolean pr_set_type PARAMS ((PTR, boolean)); -static boolean pr_offset_type PARAMS ((PTR)); -static boolean pr_method_type PARAMS ((PTR, boolean, int, boolean)); -static boolean pr_const_type PARAMS ((PTR)); -static boolean pr_volatile_type PARAMS ((PTR)); -static boolean pr_start_struct_type - PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int)); -static boolean pr_struct_field - PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility)); -static boolean pr_end_struct_type PARAMS ((PTR)); -static boolean pr_start_class_type - PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int, boolean, - boolean)); -static boolean pr_class_static_member - PARAMS ((PTR, const char *, const char *, enum debug_visibility)); -static boolean pr_class_baseclass - PARAMS ((PTR, bfd_vma, boolean, enum debug_visibility)); -static boolean pr_class_start_method PARAMS ((PTR, const char *)); -static boolean pr_class_method_variant - PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean, - bfd_vma, boolean)); -static boolean pr_class_static_method_variant - PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean)); -static boolean pr_class_end_method PARAMS ((PTR)); -static boolean pr_end_class_type PARAMS ((PTR)); -static boolean pr_typedef_type PARAMS ((PTR, const char *)); -static boolean pr_tag_type - PARAMS ((PTR, const char *, unsigned int, enum debug_type_kind)); -static boolean pr_typdef PARAMS ((PTR, const char *)); -static boolean pr_tag PARAMS ((PTR, const char *)); -static boolean pr_int_constant PARAMS ((PTR, const char *, bfd_vma)); -static boolean pr_float_constant PARAMS ((PTR, const char *, double)); -static boolean pr_typed_constant PARAMS ((PTR, const char *, bfd_vma)); -static boolean pr_variable - PARAMS ((PTR, const char *, enum debug_var_kind, bfd_vma)); -static boolean pr_start_function PARAMS ((PTR, const char *, boolean)); -static boolean pr_function_parameter - PARAMS ((PTR, const char *, enum debug_parm_kind, bfd_vma)); -static boolean pr_start_block PARAMS ((PTR, bfd_vma)); -static boolean pr_end_block PARAMS ((PTR, bfd_vma)); -static boolean pr_end_function PARAMS ((PTR)); -static boolean pr_lineno PARAMS ((PTR, const char *, unsigned long, bfd_vma)); - -static const struct debug_write_fns pr_fns = -{ - pr_start_compilation_unit, - pr_start_source, - pr_empty_type, - pr_void_type, - pr_int_type, - pr_float_type, - pr_complex_type, - pr_bool_type, - pr_enum_type, - pr_pointer_type, - pr_function_type, - pr_reference_type, - pr_range_type, - pr_array_type, - pr_set_type, - pr_offset_type, - pr_method_type, - pr_const_type, - pr_volatile_type, - pr_start_struct_type, - pr_struct_field, - pr_end_struct_type, - pr_start_class_type, - pr_class_static_member, - pr_class_baseclass, - pr_class_start_method, - pr_class_method_variant, - pr_class_static_method_variant, - pr_class_end_method, - pr_end_class_type, - pr_typedef_type, - pr_tag_type, - pr_typdef, - pr_tag, - pr_int_constant, - pr_float_constant, - pr_typed_constant, - pr_variable, - pr_start_function, - pr_function_parameter, - pr_start_block, - pr_end_block, - pr_end_function, - pr_lineno -}; - - -/* Indent to the current indentation level. */ - -static void -indent (info) - struct pr_handle *info; -{ - unsigned int i; - - for (i = 0; i < info->indent; i++) - TRACE_PUTC ((' ', info->f)); -} - -/* Push a type on the type stack. */ - -static boolean -push_type (info, type) - struct pr_handle *info; - const char *type; -{ - struct pr_stack *n; - - if (type == NULL) - return false; - - n = (struct pr_stack *) xmalloc (sizeof *n); - memset (n, 0, sizeof *n); - - n->type = xstrdup (type); - n->visibility = DEBUG_VISIBILITY_IGNORE; - n->method = NULL; - n->next = info->stack; - info->stack = n; - - return true; -} - -/* Prepend a string onto the type on the top of the type stack. */ - -static boolean -prepend_type (info, s) - struct pr_handle *info; - const char *s; -{ - char *n; - - assert (info->stack != NULL); - - n = (char *) xmalloc (strlen (s) + strlen (info->stack->type) + 1); - sprintf (n, "%s%s", s, info->stack->type); - free (info->stack->type); - info->stack->type = n; - - return true; -} - -/* Append a string to the type on the top of the type stack. */ - -static boolean -append_type (info, s) - struct pr_handle *info; - const char *s; -{ - unsigned int len; - - if (s == NULL) - return false; - - assert (info->stack != NULL); - - len = strlen (info->stack->type); - info->stack->type = (char *) xrealloc (info->stack->type, - len + strlen (s) + 1); - strcpy (info->stack->type + len, s); - - return true; -} - -/* We use an underscore to indicate where the name should go in a type - string. This function substitutes a string for the underscore. If - there is no underscore, the name follows the type. */ - -static boolean -substitute_type (info, s) - struct pr_handle *info; - const char *s; -{ - char *u; - - assert (info->stack != NULL); - - u = strchr (info->stack->type, '|'); - if (u != NULL) - { - char *n; - - n = (char *) xmalloc (strlen (info->stack->type) + strlen (s)); - - memcpy (n, info->stack->type, u - info->stack->type); - strcpy (n + (u - info->stack->type), s); - strcat (n, u + 1); - - free (info->stack->type); - info->stack->type = n; - - return true; - } - - if (strchr (s, '|') != NULL - && (strchr (info->stack->type, '{') != NULL - || strchr (info->stack->type, '(') != NULL)) - { - if (! prepend_type (info, "(") - || ! append_type (info, ")")) - return false; - } - - if (*s == '\0') - return true; - - return (append_type (info, " ") - && append_type (info, s)); -} - -/* Indent the type at the top of the stack by appending spaces. */ - -static boolean -indent_type (info) - struct pr_handle *info; -{ - unsigned int i; - - for (i = 0; i < info->indent; i++) - { - if (! append_type (info, " ")) - return false; - } - - return true; -} - -/* Pop a type from the type stack. */ - -static char * -pop_type (info) - struct pr_handle *info; -{ - struct pr_stack *o; - char *ret; - - assert (info->stack != NULL); - - o = info->stack; - info->stack = o->next; - ret = o->type; - free (o); - - return ret; -} - -/* Print a VMA value into a string. */ - -static void -print_vma (vma, buf, unsignedp, hexp) - bfd_vma vma; - char *buf; - boolean unsignedp; - boolean hexp; -{ - if (sizeof (vma) <= sizeof (unsigned long)) - { - if (hexp) - sprintf (buf, "0x%lx", (unsigned long) vma); - else if (unsignedp) - sprintf (buf, "%lu", (unsigned long) vma); - else - sprintf (buf, "%ld", (long) vma); - } - else - { - buf[0] = '0'; - buf[1] = 'x'; - sprintf_vma (buf + 2, vma); - } -} - -/* Start a new compilation unit. */ - -static boolean -pr_start_compilation_unit (p, filename) - PTR p; - const char *filename; -{ - struct pr_handle *info = (struct pr_handle *) p; - - assert (info->indent == 0); -/* - TRACE_FPRINTF( (info->f, "%s:\n", filename)); -*/ - return true; -} - -/* Start a source file within a compilation unit. */ - -static boolean -pr_start_source (p, filename) - PTR p; - const char *filename; -{ - struct pr_handle *info = (struct pr_handle *) p; - - assert (info->indent == 0); -/* - TRACE_FPRINTF( (info->f, " %s:\n", filename)); -*/ - return true; -} - -/* Push an empty type onto the type stack. */ - -static boolean -pr_empty_type (p) - PTR p; -{ - struct pr_handle *info = (struct pr_handle *) p; - - return push_type (info, ""); -} - -/* Push a void type onto the type stack. */ - -static boolean -pr_void_type (p) - PTR p; -{ - struct pr_handle *info = (struct pr_handle *) p; - - return push_type (info, "void"); -} - -/* Push an integer type onto the type stack. */ - -static boolean -pr_int_type (p, size, unsignedp) - PTR p; - unsigned int size; - boolean unsignedp; -{ - struct pr_handle *info = (struct pr_handle *) p; - char ab[10]; - - sprintf (ab, "%sint%d", unsignedp ? "u" : "", size * 8); - return push_type (info, ab); -} - -/* Push a floating type onto the type stack. */ - -static boolean -pr_float_type (p, size) - PTR p; - unsigned int size; -{ - struct pr_handle *info = (struct pr_handle *) p; - char ab[10]; - - if (size == 4) - return push_type (info, "float"); - else if (size == 8) - return push_type (info, "double"); - - sprintf (ab, "float%d", size * 8); - return push_type (info, ab); -} - -/* Push a complex type onto the type stack. */ - -static boolean -pr_complex_type (p, size) - PTR p; - unsigned int size; -{ - struct pr_handle *info = (struct pr_handle *) p; - - if (! pr_float_type (p, size)) - return false; - - return prepend_type (info, "complex "); -} - -/* Push a boolean type onto the type stack. */ - -static boolean -pr_bool_type (p, size) - PTR p; - unsigned int size; -{ - struct pr_handle *info = (struct pr_handle *) p; - char ab[10]; - - sprintf (ab, "bool%d", size * 8); - - return push_type (info, ab); -} - -/* Push an enum type onto the type stack. */ - -static boolean -pr_enum_type (p, tag, names, values) - PTR p; - const char *tag; - const char **names; - bfd_signed_vma *values; -{ - struct pr_handle *info = (struct pr_handle *) p; - unsigned int i; - bfd_signed_vma val; - - if (! push_type (info, "enum ")) - return false; - if (tag != NULL) - { - if (! append_type (info, tag) - || ! append_type (info, " ")) - return false; - } - if (! append_type (info, "{ ")) - return false; - - if (names == NULL) - { - if (! append_type (info, "/* undefined */")) - return false; - } - else - { - val = 0; - for (i = 0; names[i] != NULL; i++) - { - if (i > 0) - { - if (! append_type (info, ", ")) - return false; - } - - if (! append_type (info, names[i])) - return false; - - if (values[i] != val) - { - char ab[20]; - - print_vma (values[i], ab, false, false); - if (! append_type (info, " = ") - || ! append_type (info, ab)) - return false; - val = values[i]; - } - - ++val; - } - } - - return append_type (info, " }"); -} - -/* Turn the top type on the stack into a pointer. */ - -static boolean -pr_pointer_type (p) - PTR p; -{ - struct pr_handle *info = (struct pr_handle *) p; - char *s; - - assert (info->stack != NULL); - - s = strchr (info->stack->type, '|'); - if (s != NULL && s[1] == '[') - return substitute_type (info, "(*|)"); - return substitute_type (info, "*|"); -} - -/* Turn the top type on the stack into a function returning that type. */ - -static boolean -pr_function_type (p, argcount, varargs) - PTR p; - int argcount; - boolean varargs; -{ - struct pr_handle *info = (struct pr_handle *) p; - char **arg_types; - unsigned int len; - char *s; - - assert (info->stack != NULL); - - len = 10; - - if (argcount <= 0) - { - arg_types = NULL; - len += 15; - } - else - { - int i; - - arg_types = (char **) xmalloc (argcount * sizeof *arg_types); - for (i = argcount - 1; i >= 0; i--) - { - if (! substitute_type (info, "")) - return false; - arg_types[i] = pop_type (info); - if (arg_types[i] == NULL) - return false; - len += strlen (arg_types[i]) + 2; - } - if (varargs) - len += 5; - } - - /* Now the return type is on the top of the stack. */ - - s = (char *) xmalloc (len); - strcpy (s, "(|) ("); - - if (argcount < 0) - { -#if 0 - /* Turn off unknown arguments. */ - strcat (s, "/* unknown */"); -#endif - } - else - { - int i; - - for (i = 0; i < argcount; i++) - { - if (i > 0) - strcat (s, ", "); - strcat (s, arg_types[i]); - } - if (varargs) - { - if (i > 0) - strcat (s, ", "); - strcat (s, "..."); - } - if (argcount > 0) - free (arg_types); - } - - strcat (s, ")"); - - if (! substitute_type (info, s)) - return false; - - free (s); - - return true; -} - -/* Turn the top type on the stack into a reference to that type. */ - -static boolean -pr_reference_type (p) - PTR p; -{ - struct pr_handle *info = (struct pr_handle *) p; - - assert (info->stack != NULL); - - return substitute_type (info, "&|"); -} - -/* Make a range type. */ - -static boolean -pr_range_type (p, lower, upper) - PTR p; - bfd_signed_vma lower; - bfd_signed_vma upper; -{ - struct pr_handle *info = (struct pr_handle *) p; - char abl[20], abu[20]; - - assert (info->stack != NULL); - - if (! substitute_type (info, "")) - return false; - - print_vma (lower, abl, false, false); - print_vma (upper, abu, false, false); - - return (prepend_type (info, "range (") - && append_type (info, "):") - && append_type (info, abl) - && append_type (info, ":") - && append_type (info, abu)); -} - -/* Make an array type. */ - -/*ARGSUSED*/ -static boolean -pr_array_type (p, lower, upper, stringp) - PTR p; - bfd_signed_vma lower; - bfd_signed_vma upper; - boolean stringp; -{ - struct pr_handle *info = (struct pr_handle *) p; - char *range_type; - char abl[20], abu[20], ab[50]; - - range_type = pop_type (info); - if (range_type == NULL) - return false; - - if (lower == 0) - { - if (upper == -1) - sprintf (ab, "|[]"); - else - { - print_vma (upper + 1, abu, false, false); - sprintf (ab, "|[%s]", abu); - } - } - else - { - print_vma (lower, abl, false, false); - print_vma (upper, abu, false, false); - sprintf (ab, "|[%s:%s]", abl, abu); - } - - if (! substitute_type (info, ab)) - return false; - - if (strcmp (range_type, "int") != 0) - { - if (! append_type (info, ":") - || ! append_type (info, range_type)) - return false; - } - - if (stringp) - { - if (! append_type (info, " /* string */")) - return false; - } - - return true; -} - -/* Make a set type. */ - -/*ARGSUSED*/ -static boolean -pr_set_type (p, bitstringp) - PTR p; - boolean bitstringp; -{ - struct pr_handle *info = (struct pr_handle *) p; - - if (! substitute_type (info, "")) - return false; - - if (! prepend_type (info, "set { ") - || ! append_type (info, " }")) - return false; - - if (bitstringp) - { - if (! append_type (info, "/* bitstring */")) - return false; - } - - return true; -} - -/* Make an offset type. */ - -static boolean -pr_offset_type (p) - PTR p; -{ - struct pr_handle *info = (struct pr_handle *) p; - char *t; - - if (! substitute_type (info, "")) - return false; - - t = pop_type (info); - if (t == NULL) - return false; - - return (substitute_type (info, "") - && prepend_type (info, " ") - && prepend_type (info, t) - && append_type (info, "::|")); -} - -/* Make a method type. */ - -static boolean -pr_method_type (p, domain, argcount, varargs) - PTR p; - boolean domain; - int argcount; - boolean varargs; -{ - struct pr_handle *info = (struct pr_handle *) p; - unsigned int len; - char *domain_type; - char **arg_types; - char *s; - - len = 10; - - if (! domain) - domain_type = NULL; - else - { - if (! substitute_type (info, "")) - return false; - domain_type = pop_type (info); - if (domain_type == NULL) - return false; - if (strncmp (domain_type, "class ", sizeof "class " - 1) == 0 - && strchr (domain_type + sizeof "class " - 1, ' ') == NULL) - domain_type += sizeof "class " - 1; - else if (strncmp (domain_type, "union class ", - sizeof "union class ") == 0 - && (strchr (domain_type + sizeof "union class " - 1, ' ') - == NULL)) - domain_type += sizeof "union class " - 1; - len += strlen (domain_type); - } - - if (argcount <= 0) - { - arg_types = NULL; - len += 15; - } - else - { - int i; - - arg_types = (char **) xmalloc (argcount * sizeof *arg_types); - for (i = argcount - 1; i >= 0; i--) - { - if (! substitute_type (info, "")) - return false; - arg_types[i] = pop_type (info); - if (arg_types[i] == NULL) - return false; - len += strlen (arg_types[i]) + 2; - } - if (varargs) - len += 5; - } - - /* Now the return type is on the top of the stack. */ - - s = (char *) xmalloc (len); - if (! domain) - *s = '\0'; - else - strcpy (s, domain_type); - strcat (s, "::| ("); - - if (argcount < 0) - strcat (s, "/* unknown */"); - else - { - int i; - - for (i = 0; i < argcount; i++) - { - if (i > 0) - strcat (s, ", "); - strcat (s, arg_types[i]); - } - if (varargs) - { - if (i > 0) - strcat (s, ", "); - strcat (s, "..."); - } - if (argcount > 0) - free (arg_types); - } - - strcat (s, ")"); - - if (! substitute_type (info, s)) - return false; - - free (s); - - return true; -} - -/* Make a const qualified type. */ - -static boolean -pr_const_type (p) - PTR p; -{ - struct pr_handle *info = (struct pr_handle *) p; - - return substitute_type (info, "const |"); -} - -/* Make a volatile qualified type. */ - -static boolean -pr_volatile_type (p) - PTR p; -{ - struct pr_handle *info = (struct pr_handle *) p; - - return substitute_type (info, "volatile |"); -} - -/* Start accumulating a struct type. */ - -static boolean -pr_start_struct_type (p, tag, id, structp, size) - PTR p; - const char *tag; - unsigned int id; - boolean structp; - unsigned int size; -{ - struct pr_handle *info = (struct pr_handle *) p; - - info->indent += 2; - - if (! push_type (info, structp ? "struct " : "union ")) - return false; - if (tag != NULL) - { - if (! append_type (info, tag)) - return false; - } - else - { - char idbuf[20]; - - sprintf (idbuf, "%%anon%u", id); - if (! append_type (info, idbuf)) - return false; - } - - if (! append_type (info, " {")) - return false; - if (size != 0 || tag != NULL) - { - char ab[30]; - - if (! append_type (info, " /*")) - return false; - - if (size != 0) - { - sprintf (ab, " size %u", size); - if (! append_type (info, ab)) - return false; - } - if (tag != NULL) - { - sprintf (ab, " id %u", id); - if (! append_type (info, ab)) - return false; - } - if (! append_type (info, " */")) - return false; - } - if (! append_type (info, "\n")) - return false; - - info->stack->visibility = DEBUG_VISIBILITY_PUBLIC; - - return indent_type (info); -} - -/* Output the visibility of a field in a struct. */ - -static boolean -pr_fix_visibility (info, visibility) - struct pr_handle *info; - enum debug_visibility visibility; -{ - const char *s; - char *t; - unsigned int len; - - assert (info->stack != NULL); - - if (info->stack->visibility == visibility) - return true; - - assert (info->stack->visibility != DEBUG_VISIBILITY_IGNORE); - - switch (visibility) - { - case DEBUG_VISIBILITY_PUBLIC: - s = "public"; - break; - case DEBUG_VISIBILITY_PRIVATE: - s = "private"; - break; - case DEBUG_VISIBILITY_PROTECTED: - s = "protected"; - break; - case DEBUG_VISIBILITY_IGNORE: - s = "/* ignore */"; - break; - default: - abort (); - return false; - } - - /* Trim off a trailing space in the struct string, to make the - output look a bit better, then stick on the visibility string. */ - - t = info->stack->type; - len = strlen (t); - assert (t[len - 1] == ' '); - t[len - 1] = '\0'; - - if (! append_type (info, s) - || ! append_type (info, ":\n") - || ! indent_type (info)) - return false; - - info->stack->visibility = visibility; - - return true; -} - -/* Add a field to a struct type. */ - -static boolean -pr_struct_field (p, name, bitpos, bitsize, visibility) - PTR p; - const char *name; - bfd_vma bitpos; - bfd_vma bitsize; - enum debug_visibility visibility; -{ - struct pr_handle *info = (struct pr_handle *) p; - char ab[20]; - char *t; - - if (! substitute_type (info, name)) - return false; - - if (! append_type (info, "; /* ")) - return false; - - if (bitsize != 0) - { - print_vma (bitsize, ab, true, false); - if (! append_type (info, "bitsize ") - || ! append_type (info, ab) - || ! append_type (info, ", ")) - return false; - } - - print_vma (bitpos, ab, true, false); - if (! append_type (info, "bitpos ") - || ! append_type (info, ab) - || ! append_type (info, " */\n") - || ! indent_type (info)) - return false; - - t = pop_type (info); - if (t == NULL) - return false; - - if (! pr_fix_visibility (info, visibility)) - return false; - - return append_type (info, t); -} - -/* Finish a struct type. */ - -static boolean -pr_end_struct_type (p) - PTR p; -{ - struct pr_handle *info = (struct pr_handle *) p; - char *s; - - assert (info->stack != NULL); - assert (info->indent >= 2); - - info->indent -= 2; - - /* Change the trailing indentation to have a close brace. */ - s = info->stack->type + strlen (info->stack->type) - 2; - assert (s[0] == ' ' && s[1] == ' ' && s[2] == '\0'); - - *s++ = '}'; - *s = '\0'; - - return true; -} - -/* Start a class type. */ - -static boolean -pr_start_class_type (p, tag, id, structp, size, vptr, ownvptr) - PTR p; - const char *tag; - unsigned int id; - boolean structp; - unsigned int size; - boolean vptr; - boolean ownvptr; -{ - struct pr_handle *info = (struct pr_handle *) p; - char *tv = NULL; - - info->indent += 2; - - if (vptr && ! ownvptr) - { - tv = pop_type (info); - if (tv == NULL) - return false; - } - - if (! push_type (info, structp ? "class " : "union class ")) - return false; - if (tag != NULL) - { - if (! append_type (info, tag)) - return false; - } - else - { - char idbuf[20]; - - sprintf (idbuf, "%%anon%u", id); - if (! append_type (info, idbuf)) - return false; - } - - if (! append_type (info, " {")) - return false; - if (size != 0 || vptr || ownvptr || tag != NULL) - { - if (! append_type (info, " /*")) - return false; - - if (size != 0) - { - char ab[20]; - - sprintf (ab, "%u", size); - if (! append_type (info, " size ") - || ! append_type (info, ab)) - return false; - } - - if (vptr) - { - if (! append_type (info, " vtable ")) - return false; - if (ownvptr) - { - if (! append_type (info, "self ")) - return false; - } - else - { - if (! append_type (info, tv) - || ! append_type (info, " ")) - return false; - } - } - - if (tag != NULL) - { - char ab[30]; - - sprintf (ab, " id %u", id); - if (! append_type (info, ab)) - return false; - } - - if (! append_type (info, " */")) - return false; - } - - info->stack->visibility = DEBUG_VISIBILITY_PRIVATE; - - return (append_type (info, "\n") - && indent_type (info)); -} - -/* Add a static member to a class. */ - -static boolean -pr_class_static_member (p, name, physname, visibility) - PTR p; - const char *name; - const char *physname; - enum debug_visibility visibility; -{ - struct pr_handle *info = (struct pr_handle *) p; - char *t; - - if (! substitute_type (info, name)) - return false; - - if (! prepend_type (info, "static ") - || ! append_type (info, "; /* ") - || ! append_type (info, physname) - || ! append_type (info, " */\n") - || ! indent_type (info)) - return false; - - t = pop_type (info); - if (t == NULL) - return false; - - if (! pr_fix_visibility (info, visibility)) - return false; - - return append_type (info, t); -} - -/* Add a base class to a class. */ - -static boolean -pr_class_baseclass (p, bitpos, virtual, visibility) - PTR p; - bfd_vma bitpos; - boolean virtual; - enum debug_visibility visibility; -{ - struct pr_handle *info = (struct pr_handle *) p; - char *t; - const char *prefix; - char ab[20]; - char *s, *l, *n; - - assert (info->stack != NULL && info->stack->next != NULL); - - if (! substitute_type (info, "")) - return false; - - t = pop_type (info); - if (t == NULL) - return false; - - if (strncmp (t, "class ", sizeof "class " - 1) == 0) - t += sizeof "class " - 1; - - /* Push it back on to take advantage of the prepend_type and - append_type routines. */ - if (! push_type (info, t)) - return false; - - if (virtual) - { - if (! prepend_type (info, "virtual ")) - return false; - } - - switch (visibility) - { - case DEBUG_VISIBILITY_PUBLIC: - prefix = "public "; - break; - case DEBUG_VISIBILITY_PROTECTED: - prefix = "protected "; - break; - case DEBUG_VISIBILITY_PRIVATE: - prefix = "private "; - break; - default: - prefix = "/* unknown visibility */ "; - break; - } - - if (! prepend_type (info, prefix)) - return false; - - if (bitpos != 0) - { - print_vma (bitpos, ab, true, false); - if (! append_type (info, " /* bitpos ") - || ! append_type (info, ab) - || ! append_type (info, " */")) - return false; - } - - /* Now the top of the stack is something like "public A / * bitpos - 10 * /". The next element on the stack is something like "class - xx { / * size 8 * /\n...". We want to substitute the top of the - stack in before the {. */ - s = strchr (info->stack->next->type, '{'); - assert (s != NULL); - --s; - - /* If there is already a ':', then we already have a baseclass, and - we must append this one after a comma. */ - for (l = info->stack->next->type; l != s; l++) - if (*l == ':') - break; - if (! prepend_type (info, l == s ? " : " : ", ")) - return false; - - t = pop_type (info); - if (t == NULL) - return false; - - n = (char *) xmalloc (strlen (info->stack->type) + strlen (t) + 1); - memcpy (n, info->stack->type, s - info->stack->type); - strcpy (n + (s - info->stack->type), t); - strcat (n, s); - - free (info->stack->type); - info->stack->type = n; - - free (t); - - return true; -} - -/* Start adding a method to a class. */ - -static boolean -pr_class_start_method (p, name) - PTR p; - const char *name; -{ - struct pr_handle *info = (struct pr_handle *) p; - - assert (info->stack != NULL); - info->stack->method = name; - return true; -} - -/* Add a variant to a method. */ - -static boolean -pr_class_method_variant (p, physname, visibility, constp, volatilep, voffset, - context) - PTR p; - const char *physname; - enum debug_visibility visibility; - boolean constp; - boolean volatilep; - bfd_vma voffset; - boolean context; -{ - struct pr_handle *info = (struct pr_handle *) p; - char *method_type; - char *context_type; - - assert (info->stack != NULL); - assert (info->stack->next != NULL); - - /* Put the const and volatile qualifiers on the type. */ - if (volatilep) - { - if (! append_type (info, " volatile")) - return false; - } - if (constp) - { - if (! append_type (info, " const")) - return false; - } - - /* Stick the name of the method into its type. */ - if (! substitute_type (info, - (context - ? info->stack->next->next->method - : info->stack->next->method))) - return false; - - /* Get the type. */ - method_type = pop_type (info); - if (method_type == NULL) - return false; - - /* Pull off the context type if there is one. */ - if (! context) - context_type = NULL; - else - { - context_type = pop_type (info); - if (context_type == NULL) - return false; - } - - /* Now the top of the stack is the class. */ - - if (! pr_fix_visibility (info, visibility)) - return false; - - if (! append_type (info, method_type) - || ! append_type (info, " /* ") - || ! append_type (info, physname) - || ! append_type (info, " ")) - return false; - if (context || voffset != 0) - { - char ab[20]; - - if (context) - { - if (! append_type (info, "context ") - || ! append_type (info, context_type) - || ! append_type (info, " ")) - return false; - } - print_vma (voffset, ab, true, false); - if (! append_type (info, "voffset ") - || ! append_type (info, ab)) - return false; - } - - return (append_type (info, " */;\n") - && indent_type (info)); -} - -/* Add a static variant to a method. */ - -static boolean -pr_class_static_method_variant (p, physname, visibility, constp, volatilep) - PTR p; - const char *physname; - enum debug_visibility visibility; - boolean constp; - boolean volatilep; -{ - struct pr_handle *info = (struct pr_handle *) p; - char *method_type; - - assert (info->stack != NULL); - assert (info->stack->next != NULL); - assert (info->stack->next->method != NULL); - - /* Put the const and volatile qualifiers on the type. */ - if (volatilep) - { - if (! append_type (info, " volatile")) - return false; - } - if (constp) - { - if (! append_type (info, " const")) - return false; - } - - /* Mark it as static. */ - if (! prepend_type (info, "static ")) - return false; - - /* Stick the name of the method into its type. */ - if (! substitute_type (info, info->stack->next->method)) - return false; - - /* Get the type. */ - method_type = pop_type (info); - if (method_type == NULL) - return false; - - /* Now the top of the stack is the class. */ - - if (! pr_fix_visibility (info, visibility)) - return false; - - return (append_type (info, method_type) - && append_type (info, " /* ") - && append_type (info, physname) - && append_type (info, " */;\n") - && indent_type (info)); -} - -/* Finish up a method. */ - -static boolean -pr_class_end_method (p) - PTR p; -{ - struct pr_handle *info = (struct pr_handle *) p; - - info->stack->method = NULL; - return true; -} - -/* Finish up a class. */ - -static boolean -pr_end_class_type (p) - PTR p; -{ - return pr_end_struct_type (p); -} - -/* Push a type on the stack using a typedef name. */ - -static boolean -pr_typedef_type (p, name) - PTR p; - const char *name; -{ - struct pr_handle *info = (struct pr_handle *) p; - - return push_type (info, name); -} - -/* Push a type on the stack using a tag name. */ - -static boolean -pr_tag_type (p, name, id, kind) - PTR p; - const char *name; - unsigned int id; - enum debug_type_kind kind; -{ - struct pr_handle *info = (struct pr_handle *) p; - const char *t, *tag; - char idbuf[30]; - - switch (kind) - { - case DEBUG_KIND_STRUCT: - t = "struct "; - break; - case DEBUG_KIND_UNION: - t = "union "; - break; - case DEBUG_KIND_ENUM: - t = "enum "; - break; - case DEBUG_KIND_CLASS: - t = "class "; - break; - case DEBUG_KIND_UNION_CLASS: - t = "union class "; - break; - default: - abort (); - return false; - } - - if (! push_type (info, t)) - return false; - if (name != NULL) - tag = name; - else - { - sprintf (idbuf, "%%anon%u", id); - tag = idbuf; - } - - if (! append_type (info, tag)) - return false; - if (name != NULL && kind != DEBUG_KIND_ENUM) - { - sprintf (idbuf, " /* id %u */", id); - if (! append_type (info, idbuf)) - return false; - } - - return true; -} - -/* Output a typedef. */ - -static boolean -pr_typdef (p, name) - PTR p; - const char *name; -{ - struct pr_handle *info = (struct pr_handle *) p; - char *s; - - if (! substitute_type (info, name)) - return false; - - s = pop_type (info); - if (s == NULL) - return false; -/* - indent (info); - TRACE_FPRINTF( (info->f, "typedef %s;\n", s)); -*/ - free (s); - - return true; -} - -/* Output a tag. The tag should already be in the string on the - stack, so all we have to do here is print it out. */ - -/*ARGSUSED*/ -static boolean -pr_tag (p, name) - PTR p; - const char *name; -{ - struct pr_handle *info = (struct pr_handle *) p; - char *t; - - t = pop_type (info); - if (t == NULL) - return false; -/* - indent (info); - TRACE_FPRINTF( (info->f, "%s;\n", t)); -*/ - free (t); - - return true; -} - -/* Output an integer constant. */ - -static boolean -pr_int_constant (p, name, val) - PTR p; - const char *name; - bfd_vma val; -{ -/* - struct pr_handle *info = (struct pr_handle *) p; - char ab[20]; - indent (info); - print_vma (val, ab, false, false); - TRACE_FPRINTF( (info->f, "const int %s = %s;\n", name, ab)); - */ - return true; -} - -/* Output a floating point constant. */ - -static boolean -pr_float_constant (p, name, val) - PTR p; - const char *name; - double val; -{ -/* - struct pr_handle *info = (struct pr_handle *) p; - indent (info); - TRACE_FPRINTF( (info->f, "const double %s = %g;\n", name, val)); - */ - return true; -} - -/* Output a typed constant. */ - -static boolean -pr_typed_constant (p, name, val) - PTR p; - const char *name; - bfd_vma val; -{ - struct pr_handle *info = (struct pr_handle *) p; - char *t; - - t = pop_type (info); - if (t == NULL) - return false; -/* - char ab[20]; - indent (info); - print_vma (val, ab, false, false); - TRACE_FPRINTF( (info->f, "const %s %s = %s;\n", t, name, ab)); -*/ - free (t); - - return true; -} - -/* Output a variable. */ - -static boolean -pr_variable (p, name, kind, val) - PTR p; - const char *name; - enum debug_var_kind kind; - bfd_vma val; -{ - struct pr_handle *info = (struct pr_handle *) p; - char *t; - char ab[20]; - (void)ab; - - if (! substitute_type (info, name)) - return false; - - t = pop_type (info); - if (t == NULL) - return false; - -#if 0 - indent (info); - switch (kind) - { - case DEBUG_STATIC: - case DEBUG_LOCAL_STATIC: - TRACE_FPRINTF( (info->f, "static ")); - break; - case DEBUG_REGISTER: - TRACE_FPRINTF( (info->f, "register ")); - break; - default: - break; - } - print_vma (val, ab, true, true); - TRACE_FPRINTF( (info->f, "%s /* %s */;\n", t, ab)); -#else /* 0 */ -#if 0 - if (kind==DEBUG_STATIC || kind==DEBUG_LOCAL_STATIC) { - print_vma (val, ab, true, true); - TRACE_FPRINTF( (info->f, "STATIC_VAR: %s /* %s */;\n", t, ab)); - } -#endif /* 0 */ -#endif /* !0 */ - - free (t); - - return true; -} - -/* Start outputting a function. */ - -static boolean -pr_start_function (p, name, global) - PTR p; - const char *name; - boolean global; -{ - struct pr_handle *info = (struct pr_handle *) p; - char *t; - - if (! substitute_type (info, name)) - return false; - - t = pop_type (info); - if (t == NULL) - return false; - -#if 0 - indent (info); - if (! global) - TRACE_FPRINTF( (info->f, "static ")); - TRACE_FPRINTF( (info->f, "%s (", t)); - info->parameter = 1; -#else /* 0 */ - if (info->functions_size==info->functions_maxsize) { - info->functions_maxsize *= 2; - info->functions = xrealloc(info->functions, - info->functions_maxsize*sizeof(debug_function_t)); - assert(info->functions!=0); - } - /* info->functions[info->functions_size] = xmalloc(sizeof(debug_function_t)); */ - info->function = &info->functions[info->functions_size]; - ++info->functions_size; - info->function->symbol = NULL; - info->function->lines = NULL; - info->function->lines_count = 0; - info->function->max_lines_count = 0; - info->function->name = t; - info->function->filename = NULL; - info->function->block = NULL; - info->function->argv = NULL; - info->function->argc = 0; - info->function->max_argc = 0; -#endif /* !0 */ - return true; -} - -/* Output a function parameter. */ - -static boolean -pr_function_parameter (p, name, kind, val) - PTR p; - const char *name; - enum debug_parm_kind kind; - bfd_vma val; -{ - struct pr_handle *info = (struct pr_handle *) p; - debug_function_t* f = info->function; - char *t; - char ab[20]; - (void)ab; - - if (kind == DEBUG_PARM_REFERENCE - || kind == DEBUG_PARM_REF_REG) - { - if (! pr_reference_type (p)) - return false; - } - - if (! substitute_type (info, name)) - return false; - - t = pop_type (info); - if (t == NULL) - return false; - -#if 0 - if (info->parameter != 1) - TRACE_FPRINTF( (info->f, ", ")); - - if (kind == DEBUG_PARM_REG || kind == DEBUG_PARM_REF_REG) - TRACE_FPRINTF( (info->f, "register ")); - - print_vma (val, ab, true, true); - TRACE_FPRINTF( (info->f, "%s /* %s */", t, ab)); - free (t); - ++info->parameter; -#else /* 0 */ - assert(f!=NULL); - if (f->argv==NULL) { - f->max_argc = 7; /* rarely anyone has more than that many args... */ - f->argv = xmalloc(sizeof(debug_parameter_t)*f->max_argc); - } else if (f->argc==f->max_argc) { - f->max_argc *= 2; - f->argv = realloc(f->argv,sizeof(debug_parameter_t)*f->max_argc); - } - f->argv[f->argc].offset = val; - f->argv[f->argc].name = t; - ++f->argc; -#endif /* !0 */ - return true; -} - -/* Start writing out a block. */ - -static boolean -pr_start_block (p, addr) - PTR p; - bfd_vma addr; -{ - struct pr_handle *info = (struct pr_handle *) p; - char ab[20]; - debug_block_t* block = 0; - (void)ab; -#if 0 - if (info->parameter > 0) - { - TRACE_FPRINTF( (info->f, ")\n")); - info->parameter = 0; - } - indent (info); - print_vma (addr, ab, true, true); - TRACE_FPRINTF( (info->f, "{ /* %s */\n", ab)); - info->indent += 2; -#else - if (info->block) { - if (info->block->childs_count==0) - info->block->childs = xmalloc(sizeof(debug_block_t)); - else - info->block->childs = xrealloc(info->block->childs, - info->block->childs_count*sizeof(debug_block_t)); - block = &info->block->childs[info->block->childs_count]; - } else { - block = xmalloc(sizeof(debug_block_t)); - info->function->block = block; - } - block->begin_addr = addr; - block->end_addr = 0; - block->parent = info->block; - block->childs = NULL; - block->childs_count = 0; - info->block = block; -#endif - return true; -} - -/* Write out line number information. */ - -static boolean -pr_lineno (p, filename, lineno, addr) - PTR p; - const char *filename; - unsigned long lineno; - bfd_vma addr; -{ - struct pr_handle *info = (struct pr_handle *) p; - char ab[20]; - debug_function_t* f = info->function; - (void)ab; - -#if 0 - indent (info); - print_vma (addr, ab, true, true); - TRACE_FPRINTF( (info->f, "/* file %s line %lu addr %s */\n", filename, lineno, ab)); -#else /* 0 */ - if (f==NULL) /* FIXME: skips junk silently. */ - return true; - /* assert(f!=NULL); */ - if (f->filename==NULL) { - f->filename = filename; - assert(f->lines==0); - f->max_lines_count = 4; - f->lines = xmalloc(sizeof(debug_lineno_t)*f->max_lines_count); - } - if (f->lines_count==f->max_lines_count) { - f->max_lines_count *= 2; - f->lines = xrealloc(f->lines, sizeof(debug_lineno_t)*f->max_lines_count); - } - f->lines[f->lines_count].lineno = lineno; - f->lines[f->lines_count].addr = addr; - ++f->lines_count; -#endif /* !0 */ - - return true; -} - -/* Finish writing out a block. */ - -static boolean -pr_end_block (p, addr) - PTR p; - bfd_vma addr; -{ - struct pr_handle *info = (struct pr_handle *) p; - -#if 0 - char ab[20]; - - info->indent -= 2; - indent (info); - print_vma (addr, ab, true, true); - TRACE_FPRINTF( (info->f, "} /* %s */\n", ab)); -#else /* 0 */ - assert(info->block!=0); - info->block->end_addr = addr; - info->block = info->block->parent; -#endif /* !0 */ - - return true; -} - -/* Finish writing out a function. */ - -/*ARGSUSED*/ -static boolean -pr_end_function (p) - PTR p; -{ - struct pr_handle *info = (struct pr_handle *) p; - assert(info->block==0); - info->function = NULL; - return true; -} - -/* third parameter to segv_action. */ -/* Got it after a bit of head scratching and stack dumping. */ -typedef struct { - u_int32_t foo1; /* +0x00 */ - u_int32_t foo2; - u_int32_t foo3; - u_int32_t foo4; /* usually 2 */ - u_int32_t foo5; /* +0x10 */ - u_int32_t xgs; /* always zero */ - u_int32_t xfs; /* always zero */ - u_int32_t xes; /* always es=ds=ss */ - u_int32_t xds; /* +0x20 */ - u_int32_t edi; - u_int32_t esi; - u_int32_t ebp; - u_int32_t esp; /* +0x30 */ - u_int32_t ebx; - u_int32_t edx; - u_int32_t ecx; - u_int32_t eax; /* +0x40 */ - u_int32_t foo11; /* usually 0xe */ - u_int32_t foo12; /* usually 0x6 */ - u_int32_t eip; /* instruction pointer */ - u_int32_t xcs; /* +0x50 */ - u_int32_t foo21; /* usually 0x2 */ - u_int32_t foo22; /* second stack pointer?! Probably. */ - u_int32_t xss; - u_int32_t foo31; /* +0x60 */ /* usually 0x0 */ - u_int32_t foo32; /* usually 0x2 */ - u_int32_t fault_addr; /* Address which caused a fault */ - u_int32_t foo41; /* usually 0x2 */ -} signal_regs_t; - -signal_regs_t* ptrace_regs = 0; /* Tells my_ptrace to "ptrace" current process" */ -/* - * my_ptrace: small wrapper around ptrace. - * Act as normal ptrace if ptrace_regs==0. - * Read data from current process if ptrace_regs!=0. - */ -static int -my_ptrace( int request, - int pid, - int addr, - int data) -{ - if (ptrace_regs==0) - return ptrace(request, pid, addr, data); - /* we are tracing ourselves! */ - switch (request) { - case PTRACE_ATTACH: return 0; - case PTRACE_CONT: return 0; - case PTRACE_DETACH: return 0; - case PTRACE_PEEKUSER: - switch (addr / 4) { - case EIP: return ptrace_regs->eip; - case EBP: return ptrace_regs->ebp; - default: assert(0); - } - case PTRACE_PEEKTEXT: /* FALLTHROUGH */ - case PTRACE_PEEKDATA: return *(int*)(addr); - default: assert(0); - } - errno = 1; /* what to do here? */ - return 1; /* failed?! */ -} - -#define MAXARGS 6 - -/* - * To minimize the number of parameters. - */ -typedef struct { - asymbol** syms; /* Sorted! */ - int symcount; - debug_function_t** functions; - int functions_size; -} symbol_data_t; - -/* - * Perform a search. A binary search for a symbol. - */ -static void -decode_symbol( symbol_data_t* symbol_data, - const unsigned long addr, - char* buf, - const int bufsize) -{ - asymbol** syms = symbol_data->syms; - const int symcount = symbol_data->symcount; - int bottom = 0; - int top = symcount - 1; - int i; - if (symcount==0) { - sprintf(buf, "????"); - return; - } - while (top>bottom+1) { - i = (top+bottom) / 2; - if (bfd_asymbol_value(syms[i])==addr) { - sprintf(buf, "%s", syms[i]->name); - return; - } else if (bfd_asymbol_value(syms[i]) > addr) - top = i; - else - bottom = i; - } - i = bottom; - if (addr(syms[i]->section->vma+syms[i]->section->_cooked_size)) - sprintf(buf, "????"); - else - sprintf(buf, "%s + 0x%lx", syms[i]->name, addr-bfd_asymbol_value(syms[i])); -} - -/* - * 1. Perform a binary search for an debug_function_t. - * 2. Fill buf/bufsize with name, parameters and lineno, if found - * Or with '????' otherwise. - */ -static debug_function_t* -find_debug_function_t( symbol_data_t* symbol_data, - const pid_t pid, - const unsigned long fp, /* frame pointer */ - const unsigned long addr, - char* buf, /* string buffer */ - const int bufsize)/* FIXME: not used! */ -{ - debug_function_t** syms = symbol_data->functions; - debug_function_t* f = NULL; - debug_block_t* block = NULL; - debug_lineno_t* lineno = NULL; - const int symcount = symbol_data->functions_size; - int bottom = 0; - int top = symcount - 1; - int i; - char* bufptr = buf; - - if (symcount==0) { - sprintf(buf, "????"); - return NULL; - } - while (top>bottom+1) { - i = (top+bottom) / 2; - if (syms[i]->block->begin_addr==addr) { - f = syms[i]; - break; - } else if (syms[i]->block->begin_addr > addr) - top = i; - else - if (syms[i]->block->end_addr >= addr) { - f = syms[i]; - break; - } else - bottom = i; - } - i = bottom; - if (f!=0) - block = f->block; - else { - block = syms[i]->block; - if (block->begin_addr>=addr && block->end_addr<=addr) - f = syms[i]; - } - if (f==0) - sprintf(buf, "????"); - else { - /* - * Do the backtrace the GDB way... - */ - unsigned long arg; - /* assert(f->lines_count>0); */ - if (f->lines_count>0) { - lineno = &f->lines[f->lines_count-1]; - for (i=1; ilines_count; ++i) - if (f->lines[i].addr>addr) { - lineno = &f->lines[i-1]; - break; - } - } - bufptr[0] = 0; - bufptr += sprintf(bufptr, "%s+0x%lx (", f->name, addr-block->begin_addr); - for (i=0; iargc; ++i) { - bufptr += sprintf(bufptr, "%s = ", f->argv[i].name); - /* FIXME: better parameter printing */ - errno = 0; - arg = my_ptrace(PTRACE_PEEKDATA, pid, fp+f->argv[i].offset, 0); - assert(errno==0); - bufptr += sprintf(bufptr, "0x%x", arg); - if (i!=f->argc-1) - bufptr += sprintf(bufptr, ", "); - } - if (lineno!=0) - bufptr += sprintf(bufptr, ") at %s:%d", f->filename, lineno->lineno); - } - return f; -} - -/* - * Advance through the stacks and display frames as needed. - */ -static int -my_crawl( int pid, - symbol_data_t* symbol_data, - int fout) -{ - unsigned long pc = 0; - unsigned long fp = 0; - unsigned long nextfp; - unsigned long nargs; - unsigned long i; - unsigned long arg; - char buf[8096]; // FIXME: enough? - debug_function_t* f = 0; - - errno = 0; - - pc = my_ptrace(PTRACE_PEEKUSER, pid, EIP * 4, 0); - if (!errno) - fp = my_ptrace(PTRACE_PEEKUSER, pid, EBP * 4, 0); - - if (!errno) { -#if 1 - f = find_debug_function_t(symbol_data, pid, fp, pc, buf, sizeof(buf)); - fdprintf(fout,"0x%08lx: %s", pc, buf); - for ( ; !errno && fp; ) { - nextfp = my_ptrace(PTRACE_PEEKDATA, pid, fp, 0); - if (errno) - break; - - if (f==0) { - nargs = (nextfp - fp - 8) / 4; - if (nargs > MAXARGS) - nargs = MAXARGS; - if (nargs > 0) { - fdputs(" (", fout); - for (i = 1; i <= nargs; i++) { - arg = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4 * (i + 1), 0); - if (errno) - break; - fdprintf(fout,"%lx", arg); - if (i < nargs) - fdputs(", ", fout); - } - fdputc(')', fout); - nargs = nextfp - fp - 8 - (4 * nargs); - if (!errno && nargs > 0) - fdprintf(fout," + %lx\n", nargs); - else - fdputc('\n', fout); - } else - fdputc('\n', fout); - } else - fdputc('\n', fout); - - if (errno || !nextfp) - break; - pc = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4, 0); - fp = nextfp; - if (errno) - break; - f = find_debug_function_t(symbol_data, pid, fp, pc, buf, sizeof(buf)); - fdprintf(fout,"0x%08lx: %s", pc, buf); - } -#else /* 1 */ - decode_symbol(symbol_data, pc, buf, sizeof(buf)); - fdprintf(fout,"0x%08lx: %s", pc, buf); - for ( ; !errno && fp; ) { - nextfp = my_ptrace(PTRACE_PEEKDATA, pid, fp, 0); - if (errno) - break; - - nargs = (nextfp - fp - 8) / 4; - if (nargs > MAXARGS) - nargs = MAXARGS; - if (nargs > 0) { - fputs(" (", fout); - for (i = 1; i <= nargs; i++) { - arg = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4 * (i + 1), 0); - if (errno) - break; - fdprintf(fout,"%lx", arg); - if (i < nargs) - fputs(", ", fout); - } - fdputc(')', fout); - nargs = nextfp - fp - 8 - (4 * nargs); - if (!errno && nargs > 0) - fdprintf(fout," + %lx\n", nargs); - else - fdputc('\n', fout); - } else - fdputc('\n', fout); - - if (errno || !nextfp) - break; - pc = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4, 0); - fp = nextfp; - if (errno) - break; - decode_symbol(symbol_data, pc, buf, sizeof(buf)); - fdprintf(fout,"0x%08lx: %s", pc, buf); - } -#endif /* !1 */ - } - if (errno) - perror("my_crawl"); - return errno; -} - -/* layout from /usr/src/linux/arch/i386/kernel/process.c */ -static void -show_regs( signal_regs_t* regs, - int fd) -{ - /* long cr0 = 0L, cr2 = 0L, cr3 = 0L; */ - - fdprintf(fd,"\n"); - fdprintf(fd,"FAULT ADDR: %08x\n", regs->fault_addr); - fdprintf(fd,"EIP: %04x:[<%08x>]",0xffff & regs->xcs,regs->eip); - if (regs->xcs & 3) - fdprintf(fd," ESP: %04x:%08x",0xffff & regs->xss,regs->esp); - /*fdprintf(fd," EFLAGS: %08lx\n",regs->eflags); */ - fdprintf(fd, "\n"); - fdprintf(fd,"EAX: %08x EBX: %08x ECX: %08x EDX: %08x\n", - regs->eax,regs->ebx,regs->ecx,regs->edx); - fdprintf(fd,"ESI: %08x EDI: %08x EBP: %08x", - regs->esi, regs->edi, regs->ebp); - fdprintf(fd," DS: %04x ES: %04x\n", - 0xffff & regs->xds,0xffff & regs->xes); - /* - __asm__("movl %%cr0, %0": "=r" (cr0)); - __asm__("movl %%cr2, %0": "=r" (cr2)); - __asm__("movl %%cr3, %0": "=r" (cr3)); - fprintf(stderr,"CR0: %08lx CR2: %08lx CR3: %08lx\n", cr0, cr2, cr3); */ -} - -/* - * Load a BFD for an executable based on PID. Return 0 on failure. - */ -static bfd* -load_bfd( const int pid) -{ - char filename[512]; - bfd* abfd = 0; - - /* Get the contents from procfs. */ -#if 1 - sprintf(filename, "/proc/%d/exe", pid); -#else - sprintf(filename, "crashing"); -#endif - - if ((abfd = bfd_openr (filename, 0))== NULL) - bfd_nonfatal (filename); - else { - char** matching; - assert(bfd_check_format(abfd, bfd_archive)!=true); - - /* - * There is no indication in BFD documentation that it should be done. - * God knows why... - */ - if (!bfd_check_format_matches (abfd, bfd_object, &matching)) { - bfd_nonfatal (bfd_get_filename (abfd)); - if (bfd_get_error () == bfd_error_file_ambiguously_recognized) { - list_matching_formats (matching); - free (matching); - } - } - } - return abfd; -} - -/* - * Those are for qsort. We need only function addresses, so all the others don't count. - */ -/* - * Compare two BFD::asymbol-s. - */ -static int -compare_symbols(const void* ap, - const void* bp) -{ - const asymbol *a = *(const asymbol **)ap; - const asymbol *b = *(const asymbol **)bp; - if (bfd_asymbol_value (a) > bfd_asymbol_value (b)) - return 1; - else if (bfd_asymbol_value (a) < bfd_asymbol_value (b)) - return -1; - return 0; -} - -/* - * Compare two debug_asymbol_t-s. - */ -static int -compare_debug_function_t(const void* ap, - const void* bp) -{ - const debug_function_t *a = *(const debug_function_t **)ap; - const debug_function_t *b = *(const debug_function_t **)bp; - assert(a->block!=0); - assert(b->block!=0); - { - const bfd_vma addr1 = a->block->begin_addr; - const bfd_vma addr2 = b->block->begin_addr; - if (addr1 > addr2) - return 1; - else if (addr2 > addr1) - return -1; - } - return 0; -} - -/* - * Filter out (in place) symbols that are useless for stack tracing. - * COUNT is the number of elements in SYMBOLS. - * Return the number of useful symbols. - */ - -static long -remove_useless_symbols( asymbol** symbols, - long count) -{ - asymbol** in_ptr = symbols; - asymbol** out_ptr = symbols; - - while (--count >= 0) { - asymbol *sym = *in_ptr++; - - if (sym->name == NULL || sym->name[0] == '\0' || sym->value==0) - continue; - if (sym->flags & (BSF_DEBUGGING)) - continue; - if (bfd_is_und_section (sym->section) || bfd_is_com_section (sym->section)) - continue; - *out_ptr++ = sym; - } - return out_ptr - symbols; -} - -/* - * Debugging information. - */ -static bfd* abfd = 0; -static PTR dhandle = 0; -static asymbol** syms = 0; -static long symcount = 0; -static asymbol** sorted_syms = 0; -static long sorted_symcount = 0; -static debug_function_t** functions = 0; -static int functions_size = 0; -static int sigreport = SIGUSR1; -static pthread_t segv_tid; /* What thread did SEGV? */ -static pid_t segv_pid; - -/* - * We'll get here after a SIGSEGV. But you can install it on other signals, too :) - * Because we are in the middle of the SIGSEGV, we are on our own. We can't do - * any malloc(), any fopen(), nothing. The last is actually a sin. We event can't - * fprintf(stderr,...)!!! - */ -static void -segv_action(int signo, siginfo_t* siginfo, void* ptr) -{ - symbol_data_t symbol_data; - int fd = -1; - - segv_pid = getpid(); - segv_tid = pthread_self(); - fd = open_log_file(segv_tid, segv_pid); - /* signal(SIGSEGV, SIG_DFL); */ - ptrace_regs = (signal_regs_t*)ptr; - assert(ptrace_regs!=0); - - /* Show user how guilty we are. */ - fdprintf(fd,"--------- SEGV in PROCESS %d, THREAD %d ---------------\n", segv_pid, pthread_self()); - show_regs(ptrace_regs, fd); - - /* Some form of stack trace, too. */ - fdprintf(fd, "STACK TRACE:\n"); - - symbol_data.syms = sorted_syms; - symbol_data.symcount = sorted_symcount; - symbol_data.functions = functions; - symbol_data.functions_size = functions_size; - my_crawl(segv_pid, &symbol_data, fd); - //fflush(stdout); - close(fd); - linuxthreads_notify_others(sigreport); -} - - -static void -report_action(int signo, siginfo_t* siginfo, void* ptr) -{ - const int pid = getpid(); - pthread_t tid = pthread_self(); - symbol_data_t symbol_data; - int fd; - if (pthread_equal(tid, segv_tid)) { - /* We have already printed our stack trace... */ - return; - } - - fd = open_log_file(tid, pid); - fdprintf(fd, "REPORT: CURRENT PROCESS:%d, THREAD:%d\n", getpid(), pthread_self()); - /* signal(SIGSEGV, SIG_DFL); */ - ptrace_regs = (signal_regs_t*)ptr; - assert(ptrace_regs!=0); - - /* Show user how guilty we are. */ - fdprintf(fd,"--------- STACK TRACE FOR PROCESS %d, THREAD %d ---------------\n", pid, pthread_self()); - show_regs(ptrace_regs, fd); - - /* Some form of stack trace, too. */ - fdprintf(fd, "STACK TRACE:\n"); - - symbol_data.syms = sorted_syms; - symbol_data.symcount = sorted_symcount; - symbol_data.functions = functions; - symbol_data.functions_size = functions_size; - my_crawl(pid, &symbol_data, fd); - //fflush(stdout); - close(fd); - /* Tell segv_thread to proceed after pause(). */ - /*pthread_kill(segv_tid, sigreport); - kill(segv_pid, sigreport); - pthread_cancel(tid); */ -} - -/* - * Main library routine. Just call it on your program. - */ -int -pstack_install_segv_action( const char* path_format_) -{ - const int pid = getpid(); - struct sigaction act; - - /* Store what we have to for later usage. */ - path_format = path_format_; - - /* We need a signal action for SIGSEGV and sigreport ! */ - sigreport = SIGUSR1; - act.sa_handler = 0; - sigemptyset(&act.sa_mask); - act.sa_flags = SA_SIGINFO|SA_ONESHOT; /* Just one SIGSEGV. */ - act.sa_sigaction = segv_action; - act.sa_restorer = NULL; - if (sigaction(SIGSEGV, &act, NULL)!=0) { - perror("sigaction"); - return 1; - } - act.sa_sigaction = report_action; - act.sa_flags = SA_SIGINFO; /* But many sigreports. */ - if (sigaction(sigreport, &act, NULL)!=0) { - perror("sigaction"); - return 1; - } - - /* And a little setup for libiberty. */ - program_name = "crashing"; - xmalloc_set_program_name (program_name); - - /* Umm, and initialize BFD, too */ - bfd_init(); -#if 0 - list_supported_targets(0, stdout); - set_default_bfd_target(); -#endif /* 0 */ - - if ((abfd = load_bfd(pid))==0) - fprintf(stderr, "BFD load failed..\n"); - else { - long storage_needed= (bfd_get_file_flags(abfd) & HAS_SYMS) ? - bfd_get_symtab_upper_bound (abfd) : 0; - long i; - (void)i; - - if (storage_needed < 0) - fprintf(stderr, "Symbol table size estimation failure.\n"); - else if (storage_needed > 0) { - syms = (asymbol **) xmalloc (storage_needed); - symcount = bfd_canonicalize_symtab (abfd, syms); - - TRACE_FPRINTF((stderr, "TOTAL: %ld SYMBOLS.\n", symcount)); - /* We need debugging info, too! */ - if (symcount==0 || (dhandle = read_debugging_info (abfd, syms, symcount))==0) - fprintf(stderr, "NO DEBUGGING INFORMATION FOUND.\n"); - - /* We make a copy of syms to sort. We don't want to sort syms - because that will screw up the relocs. */ - sorted_syms = (asymbol **) xmalloc (symcount * sizeof (asymbol *)); - memcpy (sorted_syms, syms, symcount * sizeof (asymbol *)); - -#if 0 - for (i=0; iname!=0 && strlen(syms[i]->name)>0 && syms[i]->value!=0) - printf("%08lx T %s\n", syms[i]->section->vma + syms[i]->value, syms[i]->name); -#endif - sorted_symcount = remove_useless_symbols (sorted_syms, symcount); - TRACE_FPRINTF((stderr, "SORTED: %ld SYMBOLS.\n", sorted_symcount)); - - /* Sort the symbols into section and symbol order */ - qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols); -#if 0 - for (i=0; iname!=0 && strlen(sorted_syms[i]->name)>0 && sorted_syms[i]->value!=0) - printf("%08lx T %s\n", sorted_syms[i]->section->vma + sorted_syms[i]->value, sorted_syms[i]->name); -#endif - /* We have symbols, we need debugging info somehow sorted out. */ - if (dhandle==0) { - fprintf(stderr, "STACK TRACE WILL BE UNCOMFORTABLE.\n"); - } else { - /* Start collecting the debugging information.... */ - struct pr_handle info; - - info.f = stdout; - info.indent = 0; - info.stack = NULL; - info.parameter = 0; - info.block = NULL; - info.function = NULL; - info.functions_size = 0; - info.functions_maxsize = 1000; - info.functions = (debug_function_t*)xmalloc(sizeof(debug_function_t)*info.functions_maxsize); - debug_write (dhandle, &pr_fns, (PTR) &info); - TRACE_FPRINTF((stdout, "\n%d DEBUG SYMBOLS\n", info.functions_size)); - assert(info.functions_size!=0); - functions = xmalloc(sizeof(debug_function_t*)*info.functions_size); - functions_size = info.functions_size; - for (i=0; ibegin_addr, info.functions[i].name); -#endif - fflush(stdout); - } - } else /* storage_needed == 0 */ - fprintf(stderr, "NO SYMBOLS FOUND.\n"); - } - return 0; -} - -/*********************************************************************/ -/*********************************************************************/ -/*********************************************************************/ diff --git a/pstack/pstack.h b/pstack/pstack.h deleted file mode 100644 index 4c4fad7e754..00000000000 --- a/pstack/pstack.h +++ /dev/null @@ -1,22 +0,0 @@ -/* $Header$ */ - -#ifndef pstack_pstack_h_ -#define pstack_pstack_h_ - -#include "pstacktrace.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Install the stack-trace-on-SEGV handler.... - */ -extern int -pstack_install_segv_action( const char* path_format); -#ifdef __cplusplus -} -#endif - -#endif /* pstack_pstack_h_ */ - diff --git a/pstack/pstacktrace.h b/pstack/pstacktrace.h deleted file mode 100644 index c884bcb9f87..00000000000 --- a/pstack/pstacktrace.h +++ /dev/null @@ -1,24 +0,0 @@ -/* $Header$ */ - -/* - * Debugging macros. - */ - -#ifndef pstacktrace_h_ -#define pstacktrace_h_ - -#define PSTACK_DEBUG 1 -#undef PSTACK_DEBUG - -#ifdef PSTACK_DEBUG -# define TRACE_PUTC(a) putc a -# define TRACE_FPUTS(a) fputs a -# define TRACE_FPRINTF(a) fprintf a -#else /* PSTACK_DEBUG */ -# define TRACE_PUTC(a) (void)0 -# define TRACE_FPUTS(a) (void)0 -# define TRACE_FPRINTF(a) (void)0 -#endif /* !PSTACK_DEBUG */ - -#endif /* pstacktrace_h_ */ - diff --git a/pstack/rddbg.c b/pstack/rddbg.c deleted file mode 100644 index be3dfc21c57..00000000000 --- a/pstack/rddbg.c +++ /dev/null @@ -1,462 +0,0 @@ -/* rddbg.c -- Read debugging information into a generic form. - Copyright (C) 1995, 96, 1997 Free Software Foundation, Inc. - Written by Ian Lance Taylor . - - This file is part of GNU Binutils. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -/* This file reads debugging information into a generic form. This - file knows how to dig the debugging information out of an object - file. */ - -#include -#include "bucomm.h" -#include -#include "debug.h" -#include "budbg.h" - -static boolean read_section_stabs_debugging_info - PARAMS ((bfd *, asymbol **, long, PTR, boolean *)); -static boolean read_symbol_stabs_debugging_info - PARAMS ((bfd *, asymbol **, long, PTR, boolean *)); -static boolean read_ieee_debugging_info PARAMS ((bfd *, PTR, boolean *)); -static void save_stab PARAMS ((int, int, bfd_vma, const char *)); -static void stab_context PARAMS ((void)); -static void free_saved_stabs PARAMS ((void)); - -/* Read debugging information from a BFD. Returns a generic debugging - pointer. */ - -PTR -read_debugging_info (abfd, syms, symcount) - bfd *abfd; - asymbol **syms; - long symcount; -{ - PTR dhandle; - boolean found; - - dhandle = debug_init (); - if (dhandle == NULL) - return NULL; - - if (! read_section_stabs_debugging_info (abfd, syms, symcount, dhandle, - &found)) - return NULL; - - if (bfd_get_flavour (abfd) == bfd_target_aout_flavour) - { - if (! read_symbol_stabs_debugging_info (abfd, syms, symcount, dhandle, - &found)) - return NULL; - } - - if (bfd_get_flavour (abfd) == bfd_target_ieee_flavour) - { - if (! read_ieee_debugging_info (abfd, dhandle, &found)) - return NULL; - } - - /* Try reading the COFF symbols if we didn't find any stabs in COFF - sections. */ - if (! found - && bfd_get_flavour (abfd) == bfd_target_coff_flavour - && symcount > 0) - { -#if 0 -/* - * JZ: Do we need coff? - */ - if (! parse_coff (abfd, syms, symcount, dhandle)) -#else - fprintf (stderr, "%s: COFF support temporarily disabled\n", - bfd_get_filename (abfd)); - return NULL; -#endif - return NULL; - found = true; - } - - if (! found) - { - fprintf (stderr, "%s: no recognized debugging information\n", - bfd_get_filename (abfd)); - return NULL; - } - - return dhandle; -} - -/* Read stabs in sections debugging information from a BFD. */ - -static boolean -read_section_stabs_debugging_info (abfd, syms, symcount, dhandle, pfound) - bfd *abfd; - asymbol **syms; - long symcount; - PTR dhandle; - boolean *pfound; -{ - static struct - { - const char *secname; - const char *strsecname; - } names[] = { { ".stab", ".stabstr" } }; - unsigned int i; - PTR shandle; - - *pfound = false; - shandle = NULL; - - for (i = 0; i < sizeof names / sizeof names[0]; i++) - { - asection *sec, *strsec; - - sec = bfd_get_section_by_name (abfd, names[i].secname); - strsec = bfd_get_section_by_name (abfd, names[i].strsecname); - if (sec != NULL && strsec != NULL) - { - bfd_size_type stabsize, strsize; - bfd_byte *stabs, *strings; - bfd_byte *stab; - bfd_size_type stroff, next_stroff; - - stabsize = bfd_section_size (abfd, sec); - stabs = (bfd_byte *) xmalloc (stabsize); - if (! bfd_get_section_contents (abfd, sec, stabs, 0, stabsize)) - { - fprintf (stderr, "%s: %s: %s\n", - bfd_get_filename (abfd), names[i].secname, - bfd_errmsg (bfd_get_error ())); - return false; - } - - strsize = bfd_section_size (abfd, strsec); - strings = (bfd_byte *) xmalloc (strsize); - if (! bfd_get_section_contents (abfd, strsec, strings, 0, strsize)) - { - fprintf (stderr, "%s: %s: %s\n", - bfd_get_filename (abfd), names[i].strsecname, - bfd_errmsg (bfd_get_error ())); - return false; - } - - if (shandle == NULL) - { - shandle = start_stab (dhandle, abfd, true, syms, symcount); - if (shandle == NULL) - return false; - } - - *pfound = true; - - stroff = 0; - next_stroff = 0; - for (stab = stabs; stab < stabs + stabsize; stab += 12) - { - bfd_size_type strx; - int type; - int other; - int desc; - bfd_vma value; - - /* This code presumes 32 bit values. */ - - strx = bfd_get_32 (abfd, stab); - type = bfd_get_8 (abfd, stab + 4); - other = bfd_get_8 (abfd, stab + 5); - desc = bfd_get_16 (abfd, stab + 6); - value = bfd_get_32 (abfd, stab + 8); - - if (type == 0) - { - /* Special type 0 stabs indicate the offset to the - next string table. */ - stroff = next_stroff; - next_stroff += value; - } - else - { - char *f, *s; - - f = NULL; - s = (char *) strings + stroff + strx; - while (s[strlen (s) - 1] == '\\' - && stab + 12 < stabs + stabsize) - { - char *p; - - stab += 12; - p = s + strlen (s) - 1; - *p = '\0'; - s = concat (s, - ((char *) strings - + stroff - + bfd_get_32 (abfd, stab)), - (const char *) NULL); - - /* We have to restore the backslash, because, if - the linker is hashing stabs strings, we may - see the same string more than once. */ - *p = '\\'; - - if (f != NULL) - free (f); - f = s; - } - - save_stab (type, desc, value, s); - - if (! parse_stab (dhandle, shandle, type, desc, value, s)) - { -#if 0 -/* - * JZ: skip the junk. - */ - stab_context (); - free_saved_stabs (); - return false; -#endif - } - - /* Don't free f, since I think the stabs code - expects strings to hang around. This should be - straightened out. FIXME. */ - } - } - - free_saved_stabs (); - free (stabs); - - /* Don't free strings, since I think the stabs code expects - the strings to hang around. This should be straightened - out. FIXME. */ - } - } - - if (shandle != NULL) - { - if (! finish_stab (dhandle, shandle)) - return false; - } - - return true; -} - -/* Read stabs in the symbol table. */ - -static boolean -read_symbol_stabs_debugging_info (abfd, syms, symcount, dhandle, pfound) - bfd *abfd; - asymbol **syms; - long symcount; - PTR dhandle; - boolean *pfound; -{ - PTR shandle; - asymbol **ps, **symend; - - shandle = NULL; - symend = syms + symcount; - for (ps = syms; ps < symend; ps++) - { - symbol_info i; - - bfd_get_symbol_info (abfd, *ps, &i); - - if (i.type == '-') - { - const char *s; - char *f; - - if (shandle == NULL) - { - shandle = start_stab (dhandle, abfd, false, syms, symcount); - if (shandle == NULL) - return false; - } - - *pfound = true; - - s = i.name; - f = NULL; - while (s[strlen (s) - 1] == '\\' - && ps + 1 < symend) - { - char *sc, *n; - - ++ps; - sc = xstrdup (s); - sc[strlen (sc) - 1] = '\0'; - n = concat (sc, bfd_asymbol_name (*ps), (const char *) NULL); - free (sc); - if (f != NULL) - free (f); - f = n; - s = n; - } - - save_stab (i.stab_type, i.stab_desc, i.value, s); - - if (! parse_stab (dhandle, shandle, i.stab_type, i.stab_desc, - i.value, s)) - { - stab_context (); - free_saved_stabs (); - return false; - } - - /* Don't free f, since I think the stabs code expects - strings to hang around. This should be straightened out. - FIXME. */ - } - } - - free_saved_stabs (); - - if (shandle != NULL) - { - if (! finish_stab (dhandle, shandle)) - return false; - } - - return true; -} - -/* Read IEEE debugging information. */ - -static boolean -read_ieee_debugging_info (abfd, dhandle, pfound) - bfd *abfd; - PTR dhandle; - boolean *pfound; -{ - asection *dsec; - bfd_size_type size; - bfd_byte *contents; - - /* The BFD backend puts the debugging information into a section - named .debug. */ - - dsec = bfd_get_section_by_name (abfd, ".debug"); - if (dsec == NULL) - return true; - - size = bfd_section_size (abfd, dsec); - contents = (bfd_byte *) xmalloc (size); - if (! bfd_get_section_contents (abfd, dsec, contents, 0, size)) - return false; - - if (! parse_ieee (dhandle, abfd, contents, size)) - return false; - - free (contents); - - *pfound = true; - - return true; -} - -/* Record stabs strings, so that we can give some context for errors. */ - -#define SAVE_STABS_COUNT (16) - -struct saved_stab -{ - int type; - int desc; - bfd_vma value; - char *string; -}; - -static struct saved_stab saved_stabs[SAVE_STABS_COUNT]; -static int saved_stabs_index; - -/* Save a stabs string. */ - -static void -save_stab (type, desc, value, string) - int type; - int desc; - bfd_vma value; - const char *string; -{ - if (saved_stabs[saved_stabs_index].string != NULL) - free (saved_stabs[saved_stabs_index].string); - saved_stabs[saved_stabs_index].type = type; - saved_stabs[saved_stabs_index].desc = desc; - saved_stabs[saved_stabs_index].value = value; - saved_stabs[saved_stabs_index].string = xstrdup (string); - saved_stabs_index = (saved_stabs_index + 1) % SAVE_STABS_COUNT; -} - -/* Provide context for an error. */ - -static void -stab_context () -{ - int i; - - fprintf (stderr, "Last stabs entries before error:\n"); - fprintf (stderr, "n_type n_desc n_value string\n"); - - i = saved_stabs_index; - do - { - struct saved_stab *stabp; - - stabp = saved_stabs + i; - if (stabp->string != NULL) - { - const char *s; - - s = bfd_get_stab_name (stabp->type); - if (s != NULL) - fprintf (stderr, "%-6s", s); - else if (stabp->type == 0) - fprintf (stderr, "HdrSym"); - else - fprintf (stderr, "%-6d", stabp->type); - fprintf (stderr, " %-6d ", stabp->desc); - fprintf_vma (stderr, stabp->value); - if (stabp->type != 0) - fprintf (stderr, " %s", stabp->string); - fprintf (stderr, "\n"); - } - i = (i + 1) % SAVE_STABS_COUNT; - } - while (i != saved_stabs_index); -} - -/* Free the saved stab strings. */ - -static void -free_saved_stabs () -{ - int i; - - for (i = 0; i < SAVE_STABS_COUNT; i++) - { - if (saved_stabs[i].string != NULL) - { - free (saved_stabs[i].string); - saved_stabs[i].string = NULL; - } - } - - saved_stabs_index = 0; -} diff --git a/pstack/stabs.c b/pstack/stabs.c deleted file mode 100644 index 076231d19cb..00000000000 --- a/pstack/stabs.c +++ /dev/null @@ -1,5082 +0,0 @@ -/* stabs.c -- Parse stabs debugging information - Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. - Written by Ian Lance Taylor . - - This file is part of GNU Binutils. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -/* This file contains code which parses stabs debugging information. - The organization of this code is based on the gdb stabs reading - code. The job it does is somewhat different, because it is not - trying to identify the correct address for anything. */ - -#include -#include - -#include -#include "bucomm.h" -#include -#include "demangle.h" -#include "debug.h" -#include "budbg.h" - -/* Meaningless definition needs by aout64.h. FIXME. */ -#define BYTES_IN_WORD 4 - -#include "aout/aout64.h" -#include "aout/stab_gnu.h" - -/* The number of predefined XCOFF types. */ - -#define XCOFF_TYPE_COUNT 34 - -/* This structure is used as a handle so that the stab parsing doesn't - need to use any static variables. */ - -struct stab_handle -{ - /* The BFD. */ - bfd *abfd; - /* True if this is stabs in sections. */ - boolean sections; - /* The symbol table. */ - asymbol **syms; - /* The number of symbols. */ - long symcount; - /* The accumulated file name string. */ - char *so_string; - /* The value of the last N_SO symbol. */ - bfd_vma so_value; - /* The value of the start of the file, so that we can handle file - relative N_LBRAC and N_RBRAC symbols. */ - bfd_vma file_start_offset; - /* The offset of the start of the function, so that we can handle - function relative N_LBRAC and N_RBRAC symbols. */ - bfd_vma function_start_offset; - /* The version number of gcc which compiled the current compilation - unit, 0 if not compiled by gcc. */ - int gcc_compiled; - /* Whether an N_OPT symbol was seen that was not generated by gcc, - so that we can detect the SunPRO compiler. */ - boolean n_opt_found; - /* The main file name. */ - char *main_filename; - /* A stack of unfinished N_BINCL files. */ - struct bincl_file *bincl_stack; - /* A list of finished N_BINCL files. */ - struct bincl_file *bincl_list; - /* Whether we are inside a function or not. */ - boolean within_function; - /* The address of the end of the function, used if we have seen an - N_FUN symbol while in a function. This is -1 if we have not seen - an N_FUN (the normal case). */ - bfd_vma function_end; - /* The depth of block nesting. */ - int block_depth; - /* List of pending variable definitions. */ - struct stab_pending_var *pending; - /* Number of files for which we have types. */ - unsigned int files; - /* Lists of types per file. */ - struct stab_types **file_types; - /* Predefined XCOFF types. */ - debug_type xcoff_types[XCOFF_TYPE_COUNT]; - /* Undefined tags. */ - struct stab_tag *tags; -}; - -/* A list of these structures is used to hold pending variable - definitions seen before the N_LBRAC of a block. */ - -struct stab_pending_var -{ - /* Next pending variable definition. */ - struct stab_pending_var *next; - /* Name. */ - const char *name; - /* Type. */ - debug_type type; - /* Kind. */ - enum debug_var_kind kind; - /* Value. */ - bfd_vma val; -}; - -/* A list of these structures is used to hold the types for a single - file. */ - -struct stab_types -{ - /* Next set of slots for this file. */ - struct stab_types *next; - /* Types indexed by type number. */ -#define STAB_TYPES_SLOTS (16) - debug_type types[STAB_TYPES_SLOTS]; -}; - -/* We keep a list of undefined tags that we encounter, so that we can - fill them in if the tag is later defined. */ - -struct stab_tag -{ - /* Next undefined tag. */ - struct stab_tag *next; - /* Tag name. */ - const char *name; - /* Type kind. */ - enum debug_type_kind kind; - /* Slot to hold real type when we discover it. If we don't, we fill - in an undefined tag type. */ - debug_type slot; - /* Indirect type we have created to point at slot. */ - debug_type type; -}; - -static char *savestring PARAMS ((const char *, int)); -static bfd_vma parse_number PARAMS ((const char **, boolean *)); -static void bad_stab PARAMS ((const char *)); -static void warn_stab PARAMS ((const char *, const char *)); -static boolean parse_stab_string - PARAMS ((PTR, struct stab_handle *, int, int, bfd_vma, const char *)); -static debug_type parse_stab_type - PARAMS ((PTR, struct stab_handle *, const char *, const char **, - debug_type **)); -static boolean parse_stab_type_number - PARAMS ((const char **, int *)); -static debug_type parse_stab_range_type - PARAMS ((PTR, struct stab_handle *, const char *, const char **, - const int *)); -static debug_type parse_stab_sun_builtin_type PARAMS ((PTR, const char **)); -static debug_type parse_stab_sun_floating_type - PARAMS ((PTR, const char **)); -static debug_type parse_stab_enum_type PARAMS ((PTR, const char **)); -static debug_type parse_stab_struct_type - PARAMS ((PTR, struct stab_handle *, const char *, const char **, boolean, - const int *)); -static boolean parse_stab_baseclasses - PARAMS ((PTR, struct stab_handle *, const char **, debug_baseclass **)); -static boolean parse_stab_struct_fields - PARAMS ((PTR, struct stab_handle *, const char **, debug_field **, - boolean *)); -static boolean parse_stab_cpp_abbrev - PARAMS ((PTR, struct stab_handle *, const char **, debug_field *)); -static boolean parse_stab_one_struct_field - PARAMS ((PTR, struct stab_handle *, const char **, const char *, - debug_field *, boolean *)); -static boolean parse_stab_members - PARAMS ((PTR, struct stab_handle *, const char *, const char **, - const int *, debug_method **)); -static debug_type parse_stab_argtypes - PARAMS ((PTR, struct stab_handle *, debug_type, const char *, const char *, - debug_type, const char *, boolean, boolean, const char **)); -static boolean parse_stab_tilde_field - PARAMS ((PTR, struct stab_handle *, const char **, const int *, - debug_type *, boolean *)); -static debug_type parse_stab_array_type - PARAMS ((PTR, struct stab_handle *, const char **, boolean)); -static void push_bincl PARAMS ((struct stab_handle *, const char *, bfd_vma)); -static const char *pop_bincl PARAMS ((struct stab_handle *)); -static boolean find_excl - PARAMS ((struct stab_handle *, const char *, bfd_vma)); -static boolean stab_record_variable - PARAMS ((PTR, struct stab_handle *, const char *, debug_type, - enum debug_var_kind, bfd_vma)); -static boolean stab_emit_pending_vars PARAMS ((PTR, struct stab_handle *)); -static debug_type *stab_find_slot - PARAMS ((struct stab_handle *, const int *)); -static debug_type stab_find_type - PARAMS ((PTR, struct stab_handle *, const int *)); -static boolean stab_record_type - PARAMS ((PTR, struct stab_handle *, const int *, debug_type)); -static debug_type stab_xcoff_builtin_type - PARAMS ((PTR, struct stab_handle *, int)); -static debug_type stab_find_tagged_type - PARAMS ((PTR, struct stab_handle *, const char *, int, - enum debug_type_kind)); -static debug_type *stab_demangle_argtypes - PARAMS ((PTR, struct stab_handle *, const char *, boolean *)); - -/* Save a string in memory. */ - -static char * -savestring (start, len) - const char *start; - int len; -{ - char *ret; - - ret = (char *) xmalloc (len + 1); - memcpy (ret, start, len); - ret[len] = '\0'; - return ret; -} - -/* Read a number from a string. */ - -static bfd_vma -parse_number (pp, poverflow) - const char **pp; - boolean *poverflow; -{ - unsigned long ul; - const char *orig; - - if (poverflow != NULL) - *poverflow = false; - - orig = *pp; - - errno = 0; - ul = strtoul (*pp, (char **) pp, 0); - if (ul + 1 != 0 || errno == 0) - return (bfd_vma) ul; - - /* Note that even though strtoul overflowed, it should have set *pp - to the end of the number, which is where we want it. */ - - if (sizeof (bfd_vma) > sizeof (unsigned long)) - { - const char *p; - boolean neg; - int base; - bfd_vma over, lastdig; - boolean overflow; - bfd_vma v; - - /* Our own version of strtoul, for a bfd_vma. */ - - p = orig; - - neg = false; - if (*p == '+') - ++p; - else if (*p == '-') - { - neg = true; - ++p; - } - - base = 10; - if (*p == '0') - { - if (p[1] == 'x' || p[1] == 'X') - { - base = 16; - p += 2; - } - else - { - base = 8; - ++p; - } - } - - over = ((bfd_vma) (bfd_signed_vma) -1) / (bfd_vma) base; - lastdig = ((bfd_vma) (bfd_signed_vma) -1) % (bfd_vma) base; - - overflow = false; - v = 0; - while (1) - { - int d; - - d = *p++; - if (isdigit ((unsigned char) d)) - d -= '0'; - else if (isupper ((unsigned char) d)) - d -= 'A'; - else if (islower ((unsigned char) d)) - d -= 'a'; - else - break; - - if (d >= base) - break; - - if (v > over || (v == over && (bfd_vma) d > lastdig)) - { - overflow = true; - break; - } - } - - if (! overflow) - { - if (neg) - v = - v; - return v; - } - } - - /* If we get here, the number is too large to represent in a - bfd_vma. */ - - if (poverflow != NULL) - *poverflow = true; - else - warn_stab (orig, "numeric overflow"); - - return 0; -} - -/* Give an error for a bad stab string. */ - -static void -bad_stab (p) - const char *p; -{ - fprintf (stderr, "Bad stab: %s\n", p); -} - -/* Warn about something in a stab string. */ - -static void -warn_stab (p, err) - const char *p; - const char *err; -{ - fprintf (stderr, "Warning: %s: %s\n", err, p); -} - -/* Create a handle to parse stabs symbols with. */ - -/*ARGSUSED*/ -PTR -start_stab (dhandle, abfd, sections, syms, symcount) - PTR dhandle; - bfd *abfd; - boolean sections; - asymbol **syms; - long symcount; -{ - struct stab_handle *ret; - - ret = (struct stab_handle *) xmalloc (sizeof *ret); - memset (ret, 0, sizeof *ret); - ret->abfd = abfd; - ret->sections = sections; - ret->syms = syms; - ret->symcount = symcount; - ret->files = 1; - ret->file_types = (struct stab_types **) xmalloc (sizeof *ret->file_types); - ret->file_types[0] = NULL; - ret->function_end = (bfd_vma) -1; - return (PTR) ret; -} - -/* When we have processed all the stabs information, we need to go - through and fill in all the undefined tags. */ - -boolean -finish_stab (dhandle, handle) - PTR dhandle; - PTR handle; -{ - struct stab_handle *info = (struct stab_handle *) handle; - struct stab_tag *st; - - if (info->within_function) - { - if (! stab_emit_pending_vars (dhandle, info) - || ! debug_end_function (dhandle, info->function_end)) - return false; - info->within_function = false; - info->function_end = (bfd_vma) -1; - } - - for (st = info->tags; st != NULL; st = st->next) - { - enum debug_type_kind kind; - - kind = st->kind; - if (kind == DEBUG_KIND_ILLEGAL) - kind = DEBUG_KIND_STRUCT; - st->slot = debug_make_undefined_tagged_type (dhandle, st->name, kind); - if (st->slot == DEBUG_TYPE_NULL) - return false; - } - - return true; -} - -/* Handle a single stabs symbol. */ - -boolean -parse_stab (dhandle, handle, type, desc, value, string) - PTR dhandle; - PTR handle; - int type; - int desc; - bfd_vma value; - const char *string; -{ - struct stab_handle *info = (struct stab_handle *) handle; - - /* gcc will emit two N_SO strings per compilation unit, one for the - directory name and one for the file name. We just collect N_SO - strings as we see them, and start the new compilation unit when - we see a non N_SO symbol. */ - if (info->so_string != NULL - && (type != N_SO || *string == '\0' || value != info->so_value)) - { - if (! debug_set_filename (dhandle, info->so_string)) - return false; - info->main_filename = info->so_string; - - info->gcc_compiled = 0; - info->n_opt_found = false; - - /* Generally, for stabs in the symbol table, the N_LBRAC and - N_RBRAC symbols are relative to the N_SO symbol value. */ - if (! info->sections) - info->file_start_offset = info->so_value; - - /* We need to reset the mapping from type numbers to types. We - can't free the old mapping, because of the use of - debug_make_indirect_type. */ - info->files = 1; - info->file_types = ((struct stab_types **) - xmalloc (sizeof *info->file_types)); - info->file_types[0] = NULL; - - info->so_string = NULL; - - /* Now process whatever type we just got. */ - } - - switch (type) - { - case N_FN: - case N_FN_SEQ: - break; - - case N_LBRAC: - /* Ignore extra outermost context from SunPRO cc and acc. */ - if (info->n_opt_found && desc == 1) - break; - - if (! info->within_function) - { - fprintf (stderr, "N_LBRAC not within function\n"); - return false; - } - - /* Start an inner lexical block. */ - if (! debug_start_block (dhandle, - (value - + info->file_start_offset - + info->function_start_offset))) - return false; - - /* Emit any pending variable definitions. */ - if (! stab_emit_pending_vars (dhandle, info)) - return false; - - ++info->block_depth; - break; - - case N_RBRAC: - /* Ignore extra outermost context from SunPRO cc and acc. */ - if (info->n_opt_found && desc == 1) - break; - - /* We shouldn't have any pending variable definitions here, but, - if we do, we probably need to emit them before closing the - block. */ - if (! stab_emit_pending_vars (dhandle, info)) - return false; - - /* End an inner lexical block. */ - if (! debug_end_block (dhandle, - (value - + info->file_start_offset - + info->function_start_offset))) - return false; - - --info->block_depth; - if (info->block_depth < 0) - { - fprintf (stderr, "Too many N_RBRACs\n"); - return false; - } - break; - - case N_SO: - /* This always ends a function. */ - if (info->within_function) - { - bfd_vma endval; - - endval = value; - if (*string != '\0' - && info->function_end != (bfd_vma) -1 - && info->function_end < endval) - endval = info->function_end; - if (! stab_emit_pending_vars (dhandle, info) - || ! debug_end_function (dhandle, endval)) - return false; - info->within_function = false; - info->function_end = (bfd_vma) -1; - } - - /* An empty string is emitted by gcc at the end of a compilation - unit. */ - if (*string == '\0') - return true; - - /* Just accumulate strings until we see a non N_SO symbol. If - the string starts with '/', we discard the previously - accumulated strings. */ - if (info->so_string == NULL) - info->so_string = xstrdup (string); - else - { - char *f; - - f = info->so_string; - if (*string == '/') - info->so_string = xstrdup (string); - else - info->so_string = concat (info->so_string, string, - (const char *) NULL); - free (f); - } - - info->so_value = value; - - break; - - case N_SOL: - /* Start an include file. */ - if (! debug_start_source (dhandle, string)) - return false; - break; - - case N_BINCL: - /* Start an include file which may be replaced. */ - push_bincl (info, string, value); - if (! debug_start_source (dhandle, string)) - return false; - break; - - case N_EINCL: - /* End an N_BINCL include. */ - if (! debug_start_source (dhandle, pop_bincl (info))) - return false; - break; - - case N_EXCL: - /* This is a duplicate of a header file named by N_BINCL which - was eliminated by the linker. */ - if (! find_excl (info, string, value)) - return false; - break; - - case N_SLINE: - if (! debug_record_line (dhandle, desc, - value + info->function_start_offset)) - return false; - break; - - case N_BCOMM: - if (! debug_start_common_block (dhandle, string)) - return false; - break; - - case N_ECOMM: - if (! debug_end_common_block (dhandle, string)) - return false; - break; - - case N_FUN: - if (*string == '\0') - { - if (info->within_function) - { - /* This always marks the end of a function; we don't - need to worry about info->function_end. */ - if (info->sections) - value += info->function_start_offset; - if (! stab_emit_pending_vars (dhandle, info) - || ! debug_end_function (dhandle, value)) - return false; - info->within_function = false; - info->function_end = (bfd_vma) -1; - } - break; - } - - /* A const static symbol in the .text section will have an N_FUN - entry. We need to use these to mark the end of the function, - in case we are looking at gcc output before it was changed to - always emit an empty N_FUN. We can't call debug_end_function - here, because it might be a local static symbol. */ - if (info->within_function - && (info->function_end == (bfd_vma) -1 - || value < info->function_end)) - info->function_end = value; - - /* Fall through. */ - /* FIXME: gdb checks the string for N_STSYM, N_LCSYM or N_ROSYM - symbols, and if it does not start with :S, gdb relocates the - value to the start of the section. gcc always seems to use - :S, so we don't worry about this. */ - /* Fall through. */ - default: - { - const char *colon; - - colon = strchr (string, ':'); - if (colon != NULL - && (colon[1] == 'f' || colon[1] == 'F')) - { - if (info->within_function) - { - bfd_vma endval; - - endval = value; - if (info->function_end != (bfd_vma) -1 - && info->function_end < endval) - endval = info->function_end; - if (! stab_emit_pending_vars (dhandle, info) - || ! debug_end_function (dhandle, endval)) - return false; - info->function_end = (bfd_vma) -1; - } - /* For stabs in sections, line numbers and block addresses - are offsets from the start of the function. */ - if (info->sections) - info->function_start_offset = value; - info->within_function = true; - } - - if (! parse_stab_string (dhandle, info, type, desc, value, string)) - return false; - } - break; - - case N_OPT: - if (string != NULL && strcmp (string, "gcc2_compiled.") == 0) - info->gcc_compiled = 2; - else if (string != NULL && strcmp (string, "gcc_compiled.") == 0) - info->gcc_compiled = 1; - else - info->n_opt_found = true; - break; - - case N_OBJ: - case N_ENDM: - case N_MAIN: - break; - } - - return true; -} - -/* Parse the stabs string. */ - -static boolean -parse_stab_string (dhandle, info, stabtype, desc, value, string) - PTR dhandle; - struct stab_handle *info; - int stabtype; - int desc; - bfd_vma value; - const char *string; -{ - const char *p; - char *name; - int type; - debug_type dtype; - boolean synonym; - unsigned int lineno; - debug_type *slot; - - p = strchr (string, ':'); - if (p == NULL) - return true; - - while (p[1] == ':') - { - p += 2; - p = strchr (p, ':'); - if (p == NULL) - { - bad_stab (string); - return false; - } - } - - /* GCC 2.x puts the line number in desc. SunOS apparently puts in - the number of bytes occupied by a type or object, which we - ignore. */ - if (info->gcc_compiled >= 2) - lineno = desc; - else - lineno = 0; - - /* FIXME: Sometimes the special C++ names start with '.'. */ - name = NULL; - if (string[0] == '$') - { - switch (string[1]) - { - case 't': - name = "this"; - break; - case 'v': - /* Was: name = "vptr"; */ - break; - case 'e': - name = "eh_throw"; - break; - case '_': - /* This was an anonymous type that was never fixed up. */ - break; - case 'X': - /* SunPRO (3.0 at least) static variable encoding. */ - break; - default: - warn_stab (string, "unknown C++ encoded name"); - break; - } - } - - if (name == NULL) - { - if (p == string || (string[0] == ' ' && p == string + 1)) - name = NULL; - else - name = savestring (string, p - string); - } - - ++p; - if (isdigit ((unsigned char) *p) || *p == '(' || *p == '-') - type = 'l'; - else - type = *p++; - - switch (type) - { - case 'c': - /* c is a special case, not followed by a type-number. - SYMBOL:c=iVALUE for an integer constant symbol. - SYMBOL:c=rVALUE for a floating constant symbol. - SYMBOL:c=eTYPE,INTVALUE for an enum constant symbol. - e.g. "b:c=e6,0" for "const b = blob1" - (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;"). */ - if (*p != '=') - { - bad_stab (string); - return false; - } - ++p; - switch (*p++) - { - case 'r': - /* Floating point constant. */ - if (! debug_record_float_const (dhandle, name, atof (p))) - return false; - break; - case 'i': - /* Integer constant. */ - /* Defining integer constants this way is kind of silly, - since 'e' constants allows the compiler to give not only - the value, but the type as well. C has at least int, - long, unsigned int, and long long as constant types; - other languages probably should have at least unsigned as - well as signed constants. */ - if (! debug_record_int_const (dhandle, name, atoi (p))) - return false; - break; - case 'e': - /* SYMBOL:c=eTYPE,INTVALUE for a constant symbol whose value - can be represented as integral. - e.g. "b:c=e6,0" for "const b = blob1" - (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;"). */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, - &p, (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return false; - if (*p != ',') - { - bad_stab (string); - return false; - } - if (! debug_record_typed_const (dhandle, name, dtype, atoi (p))) - return false; - break; - default: - bad_stab (string); - return false; - } - - break; - - case 'C': - /* The name of a caught exception. */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, - &p, (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return false; - if (! debug_record_label (dhandle, name, dtype, value)) - return false; - break; - - case 'f': - case 'F': - /* A function definition. */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return false; - if (! debug_record_function (dhandle, name, dtype, type == 'F', value)) - return false; - - /* Sun acc puts declared types of arguments here. We don't care - about their actual types (FIXME -- we should remember the whole - function prototype), but the list may define some new types - that we have to remember, so we must scan it now. */ - while (*p == ';') - { - ++p; - if (parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL) - == DEBUG_TYPE_NULL) - return false; - } - - break; - - case 'G': - { - char leading; - long c; - asymbol **ps; - - /* A global symbol. The value must be extracted from the - symbol table. */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return false; - leading = bfd_get_symbol_leading_char (info->abfd); - for (c = info->symcount, ps = info->syms; c > 0; --c, ++ps) - { - const char *n; - - n = bfd_asymbol_name (*ps); - if (leading != '\0' && *n == leading) - ++n; - if (*n == *name && strcmp (n, name) == 0) - break; - } - if (c > 0) - value = bfd_asymbol_value (*ps); - if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_GLOBAL, - value)) - return false; - } - break; - - /* This case is faked by a conditional above, when there is no - code letter in the dbx data. Dbx data never actually - contains 'l'. */ - case 'l': - case 's': - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return false; - if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_LOCAL, - value)) - return false; - break; - - case 'p': - /* A function parameter. */ - if (*p != 'F') - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - else - { - /* pF is a two-letter code that means a function parameter in - Fortran. The type-number specifies the type of the return - value. Translate it into a pointer-to-function type. */ - ++p; - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype != DEBUG_TYPE_NULL) - { - debug_type ftype; - - ftype = debug_make_function_type (dhandle, dtype, - (debug_type *) NULL, false); - dtype = debug_make_pointer_type (dhandle, ftype); - } - } - if (dtype == DEBUG_TYPE_NULL) - return false; - if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_STACK, - value)) - return false; - - /* FIXME: At this point gdb considers rearranging the parameter - address on a big endian machine if it is smaller than an int. - We have no way to do that, since we don't really know much - about the target. */ - - break; - - case 'P': - if (stabtype == N_FUN) - { - /* Prototype of a function referenced by this file. */ - while (*p == ';') - { - ++p; - if (parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL) - == DEBUG_TYPE_NULL) - return false; - } - break; - } - /* Fall through. */ - case 'R': - /* Parameter which is in a register. */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return false; - if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REG, - value)) - return false; - break; - - case 'r': - /* Register variable (either global or local). */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return false; - if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_REGISTER, - value)) - return false; - - /* FIXME: At this point gdb checks to combine pairs of 'p' and - 'r' stabs into a single 'P' stab. */ - - break; - - case 'S': - /* Static symbol at top level of file */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return false; - if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_STATIC, - value)) - return false; - break; - - case 't': - /* A typedef. */ - dtype = parse_stab_type (dhandle, info, name, &p, &slot); - if (dtype == DEBUG_TYPE_NULL) - return false; - if (name == NULL) - { - /* A nameless type. Nothing to do. */ - return true; - } - - dtype = debug_name_type (dhandle, name, dtype); - if (dtype == DEBUG_TYPE_NULL) - return false; - - if (slot != NULL) - *slot = dtype; - - break; - - case 'T': - /* Struct, union, or enum tag. For GNU C++, this can be be followed - by 't' which means we are typedef'ing it as well. */ - if (*p != 't') - { - synonym = false; - /* FIXME: gdb sets synonym to true if the current language - is C++. */ - } - else - { - synonym = true; - ++p; - } - - dtype = parse_stab_type (dhandle, info, name, &p, &slot); - if (dtype == DEBUG_TYPE_NULL) - return false; - if (name == NULL) - return true; - - dtype = debug_tag_type (dhandle, name, dtype); - if (dtype == DEBUG_TYPE_NULL) - return false; - if (slot != NULL) - *slot = dtype; - - /* See if we have a cross reference to this tag which we can now - fill in. */ - { - register struct stab_tag **pst; - - for (pst = &info->tags; *pst != NULL; pst = &(*pst)->next) - { - if ((*pst)->name[0] == name[0] - && strcmp ((*pst)->name, name) == 0) - { - (*pst)->slot = dtype; - *pst = (*pst)->next; - break; - } - } - } - - if (synonym) - { - dtype = debug_name_type (dhandle, name, dtype); - if (dtype == DEBUG_TYPE_NULL) - return false; - - if (slot != NULL) - *slot = dtype; - } - - break; - - case 'V': - /* Static symbol of local scope */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return false; - /* FIXME: gdb checks os9k_stabs here. */ - if (! stab_record_variable (dhandle, info, name, dtype, - DEBUG_LOCAL_STATIC, value)) - return false; - break; - - case 'v': - /* Reference parameter. */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return false; - if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REFERENCE, - value)) - return false; - break; - - case 'a': - /* Reference parameter which is in a register. */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return false; - if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REF_REG, - value)) - return false; - break; - - case 'X': - /* This is used by Sun FORTRAN for "function result value". - Sun claims ("dbx and dbxtool interfaces", 2nd ed) - that Pascal uses it too, but when I tried it Pascal used - "x:3" (local symbol) instead. */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return false; - if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_LOCAL, - value)) - return false; - break; - - default: - bad_stab (string); - return false; - } - - /* FIXME: gdb converts structure values to structure pointers in a - couple of cases, depending upon the target. */ - - return true; -} - -/* Parse a stabs type. The typename argument is non-NULL if this is a - typedef or a tag definition. The pp argument points to the stab - string, and is updated. The slotp argument points to a place to - store the slot used if the type is being defined. */ - -static debug_type -parse_stab_type (dhandle, info, typename, pp, slotp) - PTR dhandle; - struct stab_handle *info; - const char *typename; - const char **pp; - debug_type **slotp; -{ - const char *orig; - int typenums[2]; - int size; - boolean stringp; - int descriptor; - debug_type dtype; - - if (slotp != NULL) - *slotp = NULL; - - orig = *pp; - - size = -1; - stringp = false; - - /* Read type number if present. The type number may be omitted. - for instance in a two-dimensional array declared with type - "ar1;1;10;ar1;1;10;4". */ - if (! isdigit ((unsigned char) **pp) && **pp != '(' && **pp != '-') - { - /* 'typenums=' not present, type is anonymous. Read and return - the definition, but don't put it in the type vector. */ - typenums[0] = typenums[1] = -1; - } - else - { - if (! parse_stab_type_number (pp, typenums)) - return DEBUG_TYPE_NULL; - - if (**pp != '=') - { - /* Type is not being defined here. Either it already - exists, or this is a forward reference to it. */ - return stab_find_type (dhandle, info, typenums); - } - - /* Only set the slot if the type is being defined. This means - that the mapping from type numbers to types will only record - the name of the typedef which defines a type. If we don't do - this, then something like - typedef int foo; - int i; - will record that i is of type foo. Unfortunately, stabs - information is ambiguous about variable types. For this code, - typedef int foo; - int i; - foo j; - the stabs information records both i and j as having the same - type. This could be fixed by patching the compiler. */ - if (slotp != NULL && typenums[0] >= 0 && typenums[1] >= 0) - *slotp = stab_find_slot (info, typenums); - - /* Type is being defined here. */ - /* Skip the '='. */ - ++*pp; - - while (**pp == '@') - { - const char *p = *pp + 1; - const char *attr; - - if (isdigit ((unsigned char) *p) || *p == '(' || *p == '-') - { - /* Member type. */ - break; - } - - /* Type attributes. */ - attr = p; - - for (; *p != ';'; ++p) - { - if (*p == '\0') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - } - *pp = p + 1; - - switch (*attr) - { - case 's': - size = atoi (attr + 1); - if (size <= 0) - size = -1; - break; - - case 'S': - stringp = true; - break; - - default: - /* Ignore unrecognized type attributes, so future - compilers can invent new ones. */ - break; - } - } - } - - descriptor = **pp; - ++*pp; - - switch (descriptor) - { - case 'x': - { - enum debug_type_kind code; - const char *q1, *q2, *p; - - /* A cross reference to another type. */ - - switch (**pp) - { - case 's': - code = DEBUG_KIND_STRUCT; - break; - case 'u': - code = DEBUG_KIND_UNION; - break; - case 'e': - code = DEBUG_KIND_ENUM; - break; - default: - /* Complain and keep going, so compilers can invent new - cross-reference types. */ - warn_stab (orig, "unrecognized cross reference type"); - code = DEBUG_KIND_STRUCT; - break; - } - ++*pp; - - q1 = strchr (*pp, '<'); - p = strchr (*pp, ':'); - if (p == NULL) - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - while (q1 != NULL && p > q1 && p[1] == ':') - { - q2 = strchr (q1, '>'); - if (q2 == NULL || q2 < p) - break; - p += 2; - p = strchr (p, ':'); - if (p == NULL) - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - } - - dtype = stab_find_tagged_type (dhandle, info, *pp, p - *pp, code); - - *pp = p + 1; - } - break; - - case '-': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '(': - { - const char *hold; - int xtypenums[2]; - - /* This type is defined as another type. */ - - (*pp)--; - hold = *pp; - - /* Peek ahead at the number to detect void. */ - if (! parse_stab_type_number (pp, xtypenums)) - return DEBUG_TYPE_NULL; - - if (typenums[0] == xtypenums[0] && typenums[1] == xtypenums[1]) - { - /* This type is being defined as itself, which means that - it is void. */ - dtype = debug_make_void_type (dhandle); - } - else - { - *pp = hold; - - /* Go back to the number and have parse_stab_type get it. - This means that we can deal with something like - t(1,2)=(3,4)=... which the Lucid compiler uses. */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, - pp, (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - } - - if (typenums[0] != -1) - { - if (! stab_record_type (dhandle, info, typenums, dtype)) - return DEBUG_TYPE_NULL; - } - - break; - } - - case '*': - dtype = debug_make_pointer_type (dhandle, - parse_stab_type (dhandle, info, - (const char *) NULL, - pp, - (debug_type **) NULL)); - break; - - case '&': - /* Reference to another type. */ - dtype = (debug_make_reference_type - (dhandle, - parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL))); - break; - - case 'f': - /* Function returning another type. */ - /* FIXME: gdb checks os9k_stabs here. */ - dtype = (debug_make_function_type - (dhandle, - parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL), - (debug_type *) NULL, false)); - break; - - case 'k': - /* Const qualifier on some type (Sun). */ - /* FIXME: gdb accepts 'c' here if os9k_stabs. */ - dtype = debug_make_const_type (dhandle, - parse_stab_type (dhandle, info, - (const char *) NULL, - pp, - (debug_type **) NULL)); - break; - - case 'B': - /* Volatile qual on some type (Sun). */ - /* FIXME: gdb accepts 'i' here if os9k_stabs. */ - dtype = (debug_make_volatile_type - (dhandle, - parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL))); - break; - - case '@': - /* Offset (class & variable) type. This is used for a pointer - relative to an object. */ - { - debug_type domain; - debug_type memtype; - - /* Member type. */ - - domain = parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL); - if (domain == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - - if (**pp != ',') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - memtype = parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL); - if (memtype == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - - dtype = debug_make_offset_type (dhandle, domain, memtype); - } - break; - - case '#': - /* Method (class & fn) type. */ - if (**pp == '#') - { - debug_type return_type; - - ++*pp; - return_type = parse_stab_type (dhandle, info, (const char *) NULL, - pp, (debug_type **) NULL); - if (return_type == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - if (**pp != ';') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - dtype = debug_make_method_type (dhandle, return_type, - DEBUG_TYPE_NULL, - (debug_type *) NULL, false); - } - else - { - debug_type domain; - debug_type return_type; - debug_type *args; - unsigned int n; - unsigned int alloc; - boolean varargs; - - domain = parse_stab_type (dhandle, info, (const char *) NULL, - pp, (debug_type **) NULL); - if (domain == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - - if (**pp != ',') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - return_type = parse_stab_type (dhandle, info, (const char *) NULL, - pp, (debug_type **) NULL); - if (return_type == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - - alloc = 10; - args = (debug_type *) xmalloc (alloc * sizeof *args); - n = 0; - while (**pp != ';') - { - if (**pp != ',') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - if (n + 1 >= alloc) - { - alloc += 10; - args = ((debug_type *) - xrealloc ((PTR) args, alloc * sizeof *args)); - } - - args[n] = parse_stab_type (dhandle, info, (const char *) NULL, - pp, (debug_type **) NULL); - if (args[n] == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - ++n; - } - ++*pp; - - /* If the last type is not void, then this function takes a - variable number of arguments. Otherwise, we must strip - the void type. */ - if (n == 0 - || debug_get_type_kind (dhandle, args[n - 1]) != DEBUG_KIND_VOID) - varargs = true; - else - { - --n; - varargs = false; - } - - args[n] = DEBUG_TYPE_NULL; - - dtype = debug_make_method_type (dhandle, return_type, domain, args, - varargs); - } - break; - - case 'r': - /* Range type. */ - dtype = parse_stab_range_type (dhandle, info, typename, pp, typenums); - break; - - case 'b': - /* FIXME: gdb checks os9k_stabs here. */ - /* Sun ACC builtin int type. */ - dtype = parse_stab_sun_builtin_type (dhandle, pp); - break; - - case 'R': - /* Sun ACC builtin float type. */ - dtype = parse_stab_sun_floating_type (dhandle, pp); - break; - - case 'e': - /* Enumeration type. */ - dtype = parse_stab_enum_type (dhandle, pp); - break; - - case 's': - case 'u': - /* Struct or union type. */ - dtype = parse_stab_struct_type (dhandle, info, typename, pp, - descriptor == 's', typenums); - break; - - case 'a': - /* Array type. */ - if (**pp != 'r') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - dtype = parse_stab_array_type (dhandle, info, pp, stringp); - break; - - case 'S': - dtype = debug_make_set_type (dhandle, - parse_stab_type (dhandle, info, - (const char *) NULL, - pp, - (debug_type **) NULL), - stringp); - break; - - default: - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - - if (dtype == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - - if (typenums[0] != -1) - { - if (! stab_record_type (dhandle, info, typenums, dtype)) - return DEBUG_TYPE_NULL; - } - - if (size != -1) - { - if (! debug_record_type_size (dhandle, dtype, (unsigned int) size)) - return DEBUG_TYPE_NULL; - } - - return dtype; -} - -/* Read a number by which a type is referred to in dbx data, or - perhaps read a pair (FILENUM, TYPENUM) in parentheses. Just a - single number N is equivalent to (0,N). Return the two numbers by - storing them in the vector TYPENUMS. */ - -static boolean -parse_stab_type_number (pp, typenums) - const char **pp; - int *typenums; -{ - const char *orig; - - orig = *pp; - - if (**pp != '(') - { - typenums[0] = 0; - typenums[1] = (int) parse_number (pp, (boolean *) NULL); - } - else - { - ++*pp; - typenums[0] = (int) parse_number (pp, (boolean *) NULL); - if (**pp != ',') - { - bad_stab (orig); - return false; - } - ++*pp; - typenums[1] = (int) parse_number (pp, (boolean *) NULL); - if (**pp != ')') - { - bad_stab (orig); - return false; - } - ++*pp; - } - - return true; -} - -/* Parse a range type. */ - -static debug_type -parse_stab_range_type (dhandle, info, typename, pp, typenums) - PTR dhandle; - struct stab_handle *info; - const char *typename; - const char **pp; - const int *typenums; -{ - const char *orig; - int rangenums[2]; - boolean self_subrange; - debug_type index_type; - const char *s2, *s3; - bfd_signed_vma n2, n3; - boolean ov2, ov3; - - orig = *pp; - - index_type = DEBUG_TYPE_NULL; - - /* First comes a type we are a subrange of. - In C it is usually 0, 1 or the type being defined. */ - if (! parse_stab_type_number (pp, rangenums)) - return DEBUG_TYPE_NULL; - - self_subrange = (rangenums[0] == typenums[0] - && rangenums[1] == typenums[1]); - - if (**pp == '=') - { - *pp = orig; - index_type = parse_stab_type (dhandle, info, (const char *) NULL, - pp, (debug_type **) NULL); - if (index_type == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - } - - if (**pp == ';') - ++*pp; - - /* The remaining two operands are usually lower and upper bounds of - the range. But in some special cases they mean something else. */ - s2 = *pp; - n2 = parse_number (pp, &ov2); - if (**pp != ';') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - s3 = *pp; - n3 = parse_number (pp, &ov3); - if (**pp != ';') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - if (ov2 || ov3) - { - /* gcc will emit range stabs for long long types. Handle this - as a special case. FIXME: This needs to be more general. */ -#define LLLOW "01000000000000000000000;" -#define LLHIGH "0777777777777777777777;" -#define ULLHIGH "01777777777777777777777;" - if (index_type == DEBUG_TYPE_NULL) - { - if (strncmp (s2, LLLOW, sizeof LLLOW - 1) == 0 - && strncmp (s3, LLHIGH, sizeof LLHIGH - 1) == 0) - return debug_make_int_type (dhandle, 8, false); - if (! ov2 - && n2 == 0 - && strncmp (s3, ULLHIGH, sizeof ULLHIGH - 1) == 0) - return debug_make_int_type (dhandle, 8, true); - } - - warn_stab (orig, "numeric overflow"); - } - - if (index_type == DEBUG_TYPE_NULL) - { - /* A type defined as a subrange of itself, with both bounds 0, - is void. */ - if (self_subrange && n2 == 0 && n3 == 0) - return debug_make_void_type (dhandle); - - /* A type defined as a subrange of itself, with n2 positive and - n3 zero, is a complex type, and n2 is the number of bytes. */ - if (self_subrange && n3 == 0 && n2 > 0) - return debug_make_complex_type (dhandle, n2); - - /* If n3 is zero and n2 is positive, this is a floating point - type, and n2 is the number of bytes. */ - if (n3 == 0 && n2 > 0) - return debug_make_float_type (dhandle, n2); - - /* If the upper bound is -1, this is an unsigned int. */ - if (n2 == 0 && n3 == -1) - { - /* When gcc is used with -gstabs, but not -gstabs+, it will emit - long long int:t6=r1;0;-1; - long long unsigned int:t7=r1;0;-1; - We hack here to handle this reasonably. */ - if (typename != NULL) - { - if (strcmp (typename, "long long int") == 0) - return debug_make_int_type (dhandle, 8, false); - else if (strcmp (typename, "long long unsigned int") == 0) - return debug_make_int_type (dhandle, 8, true); - } - /* FIXME: The size here really depends upon the target. */ - return debug_make_int_type (dhandle, 4, true); - } - - /* A range of 0 to 127 is char. */ - if (self_subrange && n2 == 0 && n3 == 127) - return debug_make_int_type (dhandle, 1, false); - - /* FIXME: gdb checks for the language CHILL here. */ - - if (n2 == 0) - { - if (n3 < 0) - return debug_make_int_type (dhandle, - n3, true); - else if (n3 == 0xff) - return debug_make_int_type (dhandle, 1, true); - else if (n3 == 0xffff) - return debug_make_int_type (dhandle, 2, true); - /* -1 is used for the upper bound of (4 byte) "unsigned int" - and "unsigned long", and we already checked for that, so - don't need to test for it here. */ - } - else if (n3 == 0 - && n2 < 0 - && (self_subrange || n2 == -8)) - return debug_make_int_type (dhandle, - n2, true); - else if (n2 == - n3 - 1) - { - if (n3 == 0x7f) - return debug_make_int_type (dhandle, 1, false); - else if (n3 == 0x7fff) - return debug_make_int_type (dhandle, 2, false); - else if (n3 == 0x7fffffff) - return debug_make_int_type (dhandle, 4, false); - } - } - - /* At this point I don't have the faintest idea how to deal with a - self_subrange type; I'm going to assume that this is used as an - idiom, and that all of them are special cases. So . . . */ - if (self_subrange) - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - - index_type = stab_find_type (dhandle, info, rangenums); - if (index_type == DEBUG_TYPE_NULL) - { - /* Does this actually ever happen? Is that why we are worrying - about dealing with it rather than just calling error_type? */ - warn_stab (orig, "missing index type"); - index_type = debug_make_int_type (dhandle, 4, false); - } - - return debug_make_range_type (dhandle, index_type, n2, n3); -} - -/* Sun's ACC uses a somewhat saner method for specifying the builtin - typedefs in every file (for int, long, etc): - - type = b ; ; - signed = u or s. Possible c in addition to u or s (for char?). - offset = offset from high order bit to start bit of type. - width is # bytes in object of this type, nbits is # bits in type. - - The width/offset stuff appears to be for small objects stored in - larger ones (e.g. `shorts' in `int' registers). We ignore it for now, - FIXME. */ - -static debug_type -parse_stab_sun_builtin_type (dhandle, pp) - PTR dhandle; - const char **pp; -{ - const char *orig; - boolean unsignedp; - bfd_vma bits; - - orig = *pp; - - switch (**pp) - { - case 's': - unsignedp = false; - break; - case 'u': - unsignedp = true; - break; - default: - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - /* For some odd reason, all forms of char put a c here. This is strange - because no other type has this honor. We can safely ignore this because - we actually determine 'char'acterness by the number of bits specified in - the descriptor. */ - if (**pp == 'c') - ++*pp; - - /* The first number appears to be the number of bytes occupied - by this type, except that unsigned short is 4 instead of 2. - Since this information is redundant with the third number, - we will ignore it. */ - (void) parse_number (pp, (boolean *) NULL); - if (**pp != ';') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - /* The second number is always 0, so ignore it too. */ - (void) parse_number (pp, (boolean *) NULL); - if (**pp != ';') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - /* The third number is the number of bits for this type. */ - bits = parse_number (pp, (boolean *) NULL); - - /* The type *should* end with a semicolon. If it are embedded - in a larger type the semicolon may be the only way to know where - the type ends. If this type is at the end of the stabstring we - can deal with the omitted semicolon (but we don't have to like - it). Don't bother to complain(), Sun's compiler omits the semicolon - for "void". */ - if (**pp == ';') - ++*pp; - - if (bits == 0) - return debug_make_void_type (dhandle); - - return debug_make_int_type (dhandle, bits / 8, unsignedp); -} - -/* Parse a builtin floating type generated by the Sun compiler. */ - -static debug_type -parse_stab_sun_floating_type (dhandle, pp) - PTR dhandle; - const char **pp; -{ - const char *orig; - bfd_vma details; - bfd_vma bytes; - - orig = *pp; - - /* The first number has more details about the type, for example - FN_COMPLEX. */ - details = parse_number (pp, (boolean *) NULL); - if (**pp != ';') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - - /* The second number is the number of bytes occupied by this type */ - bytes = parse_number (pp, (boolean *) NULL); - if (**pp != ';') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - - if (details == NF_COMPLEX - || details == NF_COMPLEX16 - || details == NF_COMPLEX32) - return debug_make_complex_type (dhandle, bytes); - - return debug_make_float_type (dhandle, bytes); -} - -/* Handle an enum type. */ - -static debug_type -parse_stab_enum_type (dhandle, pp) - PTR dhandle; - const char **pp; -{ - const char *orig; - const char **names; - bfd_signed_vma *values; - unsigned int n; - unsigned int alloc; - - orig = *pp; - - /* FIXME: gdb checks os9k_stabs here. */ - - /* The aix4 compiler emits an extra field before the enum members; - my guess is it's a type of some sort. Just ignore it. */ - if (**pp == '-') - { - while (**pp != ':') - ++*pp; - ++*pp; - } - - /* Read the value-names and their values. - The input syntax is NAME:VALUE,NAME:VALUE, and so on. - A semicolon or comma instead of a NAME means the end. */ - alloc = 10; - names = (const char **) xmalloc (alloc * sizeof *names); - values = (bfd_signed_vma *) xmalloc (alloc * sizeof *values); - n = 0; - while (**pp != '\0' && **pp != ';' && **pp != ',') - { - const char *p; - char *name; - bfd_signed_vma val; - - p = *pp; - while (*p != ':') - ++p; - - name = savestring (*pp, p - *pp); - - *pp = p + 1; - val = (bfd_signed_vma) parse_number (pp, (boolean *) NULL); - if (**pp != ',') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - if (n + 1 >= alloc) - { - alloc += 10; - names = ((const char **) - xrealloc ((PTR) names, alloc * sizeof *names)); - values = ((bfd_signed_vma *) - xrealloc ((PTR) values, alloc * sizeof *values)); - } - - names[n] = name; - values[n] = val; - ++n; - } - - names[n] = NULL; - values[n] = 0; - - if (**pp == ';') - ++*pp; - - return debug_make_enum_type (dhandle, names, values); -} - -/* Read the description of a structure (or union type) and return an object - describing the type. - - PP points to a character pointer that points to the next unconsumed token - in the the stabs string. For example, given stabs "A:T4=s4a:1,0,32;;", - *PP will point to "4a:1,0,32;;". */ - -static debug_type -parse_stab_struct_type (dhandle, info, tagname, pp, structp, typenums) - PTR dhandle; - struct stab_handle *info; - const char *tagname; - const char **pp; - boolean structp; - const int *typenums; -{ - const char *orig; - bfd_vma size; - debug_baseclass *baseclasses; - debug_field *fields; - boolean statics; - debug_method *methods; - debug_type vptrbase; - boolean ownvptr; - - orig = *pp; - - /* Get the size. */ - size = parse_number (pp, (boolean *) NULL); - - /* Get the other information. */ - if (! parse_stab_baseclasses (dhandle, info, pp, &baseclasses) - || ! parse_stab_struct_fields (dhandle, info, pp, &fields, &statics) - || ! parse_stab_members (dhandle, info, tagname, pp, typenums, &methods) - || ! parse_stab_tilde_field (dhandle, info, pp, typenums, &vptrbase, - &ownvptr)) - return DEBUG_TYPE_NULL; - - if (! statics - && baseclasses == NULL - && methods == NULL - && vptrbase == DEBUG_TYPE_NULL - && ! ownvptr) - return debug_make_struct_type (dhandle, structp, size, fields); - - return debug_make_object_type (dhandle, structp, size, fields, baseclasses, - methods, vptrbase, ownvptr); -} - -/* The stabs for C++ derived classes contain baseclass information which - is marked by a '!' character after the total size. This function is - called when we encounter the baseclass marker, and slurps up all the - baseclass information. - - Immediately following the '!' marker is the number of base classes that - the class is derived from, followed by information for each base class. - For each base class, there are two visibility specifiers, a bit offset - to the base class information within the derived class, a reference to - the type for the base class, and a terminating semicolon. - - A typical example, with two base classes, would be "!2,020,19;0264,21;". - ^^ ^ ^ ^ ^ ^ ^ - Baseclass information marker __________________|| | | | | | | - Number of baseclasses __________________________| | | | | | | - Visibility specifiers (2) ________________________| | | | | | - Offset in bits from start of class _________________| | | | | - Type number for base class ___________________________| | | | - Visibility specifiers (2) _______________________________| | | - Offset in bits from start of class ________________________| | - Type number of base class ____________________________________| - - Return true for success, false for failure. */ - -static boolean -parse_stab_baseclasses (dhandle, info, pp, retp) - PTR dhandle; - struct stab_handle *info; - const char **pp; - debug_baseclass **retp; -{ - const char *orig; - unsigned int c, i; - debug_baseclass *classes; - - *retp = NULL; - - orig = *pp; - - if (**pp != '!') - { - /* No base classes. */ - return true; - } - ++*pp; - - c = (unsigned int) parse_number (pp, (boolean *) NULL); - - if (**pp != ',') - { - bad_stab (orig); - return false; - } - ++*pp; - - classes = (debug_baseclass *) xmalloc ((c + 1) * sizeof (**retp)); - - for (i = 0; i < c; i++) - { - boolean virtual; - enum debug_visibility visibility; - bfd_vma bitpos; - debug_type type; - - switch (**pp) - { - case '0': - virtual = false; - break; - case '1': - virtual = true; - break; - default: - warn_stab (orig, "unknown virtual character for baseclass"); - virtual = false; - break; - } - ++*pp; - - switch (**pp) - { - case '0': - visibility = DEBUG_VISIBILITY_PRIVATE; - break; - case '1': - visibility = DEBUG_VISIBILITY_PROTECTED; - break; - case '2': - visibility = DEBUG_VISIBILITY_PUBLIC; - break; - default: - warn_stab (orig, "unknown visibility character for baseclass"); - visibility = DEBUG_VISIBILITY_PUBLIC; - break; - } - ++*pp; - - /* The remaining value is the bit offset of the portion of the - object corresponding to this baseclass. Always zero in the - absence of multiple inheritance. */ - bitpos = parse_number (pp, (boolean *) NULL); - if (**pp != ',') - { - bad_stab (orig); - return false; - } - ++*pp; - - type = parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL); - if (type == DEBUG_TYPE_NULL) - return false; - - classes[i] = debug_make_baseclass (dhandle, type, bitpos, virtual, - visibility); - if (classes[i] == DEBUG_BASECLASS_NULL) - return false; - - if (**pp != ';') - return false; - ++*pp; - } - - classes[i] = DEBUG_BASECLASS_NULL; - - *retp = classes; - - return true; -} - -/* Read struct or class data fields. They have the form: - - NAME : [VISIBILITY] TYPENUM , BITPOS , BITSIZE ; - - At the end, we see a semicolon instead of a field. - - In C++, this may wind up being NAME:?TYPENUM:PHYSNAME; for - a static field. - - The optional VISIBILITY is one of: - - '/0' (VISIBILITY_PRIVATE) - '/1' (VISIBILITY_PROTECTED) - '/2' (VISIBILITY_PUBLIC) - '/9' (VISIBILITY_IGNORE) - - or nothing, for C style fields with public visibility. - - Returns 1 for success, 0 for failure. */ - -static boolean -parse_stab_struct_fields (dhandle, info, pp, retp, staticsp) - PTR dhandle; - struct stab_handle *info; - const char **pp; - debug_field **retp; - boolean *staticsp; -{ - const char *orig; - const char *p; - debug_field *fields; - unsigned int c; - unsigned int alloc; - - *retp = NULL; - *staticsp = false; - - orig = *pp; - - c = 0; - alloc = 10; - fields = (debug_field *) xmalloc (alloc * sizeof *fields); - while (**pp != ';') - { - /* FIXME: gdb checks os9k_stabs here. */ - - p = *pp; - - /* Add 1 to c to leave room for NULL pointer at end. */ - if (c + 1 >= alloc) - { - alloc += 10; - fields = ((debug_field *) - xrealloc ((PTR) fields, alloc * sizeof *fields)); - } - - /* If it starts with CPLUS_MARKER it is a special abbreviation, - unless the CPLUS_MARKER is followed by an underscore, in - which case it is just the name of an anonymous type, which we - should handle like any other type name. We accept either '$' - or '.', because a field name can never contain one of these - characters except as a CPLUS_MARKER. */ - - if ((*p == '$' || *p == '.') && p[1] != '_') - { - ++*pp; - if (! parse_stab_cpp_abbrev (dhandle, info, pp, fields + c)) - return false; - ++c; - continue; - } - - /* Look for the ':' that separates the field name from the field - values. Data members are delimited by a single ':', while member - functions are delimited by a pair of ':'s. When we hit the member - functions (if any), terminate scan loop and return. */ - - p = strchr (p, ':'); - if (p == NULL) - { - bad_stab (orig); - return false; - } - - if (p[1] == ':') - break; - - if (! parse_stab_one_struct_field (dhandle, info, pp, p, fields + c, - staticsp)) - return false; - - ++c; - } - - fields[c] = DEBUG_FIELD_NULL; - - *retp = fields; - - return true; -} - -/* Special GNU C++ name. */ - -static boolean -parse_stab_cpp_abbrev (dhandle, info, pp, retp) - PTR dhandle; - struct stab_handle *info; - const char **pp; - debug_field *retp; -{ - const char *orig; - int cpp_abbrev; - debug_type context; - const char *name; - const char *typename; - debug_type type; - bfd_vma bitpos; - - *retp = DEBUG_FIELD_NULL; - - orig = *pp; - - if (**pp != 'v') - { - bad_stab (*pp); - return false; - } - ++*pp; - - cpp_abbrev = **pp; - ++*pp; - - /* At this point, *pp points to something like "22:23=*22...", where - the type number before the ':' is the "context" and everything - after is a regular type definition. Lookup the type, find it's - name, and construct the field name. */ - - context = parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL); - if (context == DEBUG_TYPE_NULL) - return false; - - switch (cpp_abbrev) - { - case 'f': - /* $vf -- a virtual function table pointer. */ - name = "_vptr$"; - break; - case 'b': - /* $vb -- a virtual bsomethingorother */ - typename = debug_get_type_name (dhandle, context); - if (typename == NULL) - { - warn_stab (orig, "unnamed $vb type"); - typename = "FOO"; - } - name = concat ("_vb$", typename, (const char *) NULL); - break; - default: - warn_stab (orig, "unrecognized C++ abbreviation"); - name = "INVALID_CPLUSPLUS_ABBREV"; - break; - } - - if (**pp != ':') - { - bad_stab (orig); - return false; - } - ++*pp; - - type = parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL); - if (**pp != ',') - { - bad_stab (orig); - return false; - } - ++*pp; - - bitpos = parse_number (pp, (boolean *) NULL); - if (**pp != ';') - { - bad_stab (orig); - return false; - } - ++*pp; - - *retp = debug_make_field (dhandle, name, type, bitpos, 0, - DEBUG_VISIBILITY_PRIVATE); - if (*retp == DEBUG_FIELD_NULL) - return false; - - return true; -} - -/* Parse a single field in a struct or union. */ - -static boolean -parse_stab_one_struct_field (dhandle, info, pp, p, retp, staticsp) - PTR dhandle; - struct stab_handle *info; - const char **pp; - const char *p; - debug_field *retp; - boolean *staticsp; -{ - const char *orig; - char *name; - enum debug_visibility visibility; - debug_type type; - bfd_vma bitpos; - bfd_vma bitsize; - - orig = *pp; - - /* FIXME: gdb checks ARM_DEMANGLING here. */ - - name = savestring (*pp, p - *pp); - - *pp = p + 1; - - if (**pp != '/') - visibility = DEBUG_VISIBILITY_PUBLIC; - else - { - ++*pp; - switch (**pp) - { - case '0': - visibility = DEBUG_VISIBILITY_PRIVATE; - break; - case '1': - visibility = DEBUG_VISIBILITY_PROTECTED; - break; - case '2': - visibility = DEBUG_VISIBILITY_PUBLIC; - break; - default: - warn_stab (orig, "unknown visibility character for field"); - visibility = DEBUG_VISIBILITY_PUBLIC; - break; - } - ++*pp; - } - - type = parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL); - if (type == DEBUG_TYPE_NULL) - return false; - - if (**pp == ':') - { - char *varname; - - /* This is a static class member. */ - ++*pp; - p = strchr (*pp, ';'); - if (p == NULL) - { - bad_stab (orig); - return false; - } - - varname = savestring (*pp, p - *pp); - - *pp = p + 1; - - *retp = debug_make_static_member (dhandle, name, type, varname, - visibility); - *staticsp = true; - - return true; - } - - if (**pp != ',') - { - bad_stab (orig); - return false; - } - ++*pp; - - bitpos = parse_number (pp, (boolean *) NULL); - if (**pp != ',') - { - bad_stab (orig); - return false; - } - ++*pp; - - bitsize = parse_number (pp, (boolean *) NULL); - if (**pp != ';') - { - bad_stab (orig); - return false; - } - ++*pp; - - if (bitpos == 0 && bitsize == 0) - { - /* This can happen in two cases: (1) at least for gcc 2.4.5 or - so, it is a field which has been optimized out. The correct - stab for this case is to use VISIBILITY_IGNORE, but that is a - recent invention. (2) It is a 0-size array. For example - union { int num; char str[0]; } foo. Printing "" - for str in "p foo" is OK, since foo.str (and thus foo.str[3]) - will continue to work, and a 0-size array as a whole doesn't - have any contents to print. - - I suspect this probably could also happen with gcc -gstabs - (not -gstabs+) for static fields, and perhaps other C++ - extensions. Hopefully few people use -gstabs with gdb, since - it is intended for dbx compatibility. */ - visibility = DEBUG_VISIBILITY_IGNORE; - } - - /* FIXME: gdb does some stuff here to mark fields as unpacked. */ - - *retp = debug_make_field (dhandle, name, type, bitpos, bitsize, visibility); - - return true; -} - -/* Read member function stabs info for C++ classes. The form of each member - function data is: - - NAME :: TYPENUM[=type definition] ARGS : PHYSNAME ; - - An example with two member functions is: - - afunc1::20=##15;:i;2A.;afunc2::20:i;2A.; - - For the case of overloaded operators, the format is op$::*.funcs, where - $ is the CPLUS_MARKER (usually '$'), `*' holds the place for an operator - name (such as `+=') and `.' marks the end of the operator name. */ - -static boolean -parse_stab_members (dhandle, info, tagname, pp, typenums, retp) - PTR dhandle; - struct stab_handle *info; - const char *tagname; - const char **pp; - const int *typenums; - debug_method **retp; -{ - const char *orig; - debug_method *methods; - unsigned int c; - unsigned int alloc; - - *retp = NULL; - - orig = *pp; - - alloc = 0; - methods = NULL; - c = 0; - - while (**pp != ';') - { - const char *p; - char *name; - debug_method_variant *variants; - unsigned int cvars; - unsigned int allocvars; - debug_type look_ahead_type; - - p = strchr (*pp, ':'); - if (p == NULL || p[1] != ':') - break; - - /* FIXME: Some systems use something other than '$' here. */ - if ((*pp)[0] != 'o' || (*pp)[1] != 'p' || (*pp)[2] != '$') - { - name = savestring (*pp, p - *pp); - *pp = p + 2; - } - else - { - /* This is a completely wierd case. In order to stuff in the - names that might contain colons (the usual name delimiter), - Mike Tiemann defined a different name format which is - signalled if the identifier is "op$". In that case, the - format is "op$::XXXX." where XXXX is the name. This is - used for names like "+" or "=". YUUUUUUUK! FIXME! */ - *pp = p + 2; - for (p = *pp; *p != '.' && *p != '\0'; p++) - ; - if (*p != '.') - { - bad_stab (orig); - return false; - } - name = savestring (*pp, p - *pp); - *pp = p + 1; - } - - allocvars = 10; - variants = ((debug_method_variant *) - xmalloc (allocvars * sizeof *variants)); - cvars = 0; - - look_ahead_type = DEBUG_TYPE_NULL; - - do - { - debug_type type; - boolean stub; - char *argtypes; - enum debug_visibility visibility; - boolean constp, volatilep, staticp; - bfd_vma voffset; - debug_type context; - const char *physname; - boolean varargs; - - if (look_ahead_type != DEBUG_TYPE_NULL) - { - /* g++ version 1 kludge */ - type = look_ahead_type; - look_ahead_type = DEBUG_TYPE_NULL; - } - else - { - type = parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL); - if (type == DEBUG_TYPE_NULL) - return false; - if (**pp != ':') - { - bad_stab (orig); - return false; - } - } - - ++*pp; - p = strchr (*pp, ';'); - if (p == NULL) - { - bad_stab (orig); - return false; - } - - stub = false; - if (debug_get_type_kind (dhandle, type) == DEBUG_KIND_METHOD - && debug_get_parameter_types (dhandle, type, &varargs) == NULL) - stub = true; - - argtypes = savestring (*pp, p - *pp); - *pp = p + 1; - - switch (**pp) - { - case '0': - visibility = DEBUG_VISIBILITY_PRIVATE; - break; - case '1': - visibility = DEBUG_VISIBILITY_PROTECTED; - break; - default: - visibility = DEBUG_VISIBILITY_PUBLIC; - break; - } - ++*pp; - - constp = false; - volatilep = false; - switch (**pp) - { - case 'A': - /* Normal function. */ - ++*pp; - break; - case 'B': - /* const member function. */ - constp = true; - ++*pp; - break; - case 'C': - /* volatile member function. */ - volatilep = true; - ++*pp; - break; - case 'D': - /* const volatile member function. */ - constp = true; - volatilep = true; - ++*pp; - break; - case '*': - case '?': - case '.': - /* File compiled with g++ version 1; no information. */ - break; - default: - warn_stab (orig, "const/volatile indicator missing"); - break; - } - - staticp = false; - switch (**pp) - { - case '*': - /* virtual member function, followed by index. The sign - bit is supposedly set to distinguish - pointers-to-methods from virtual function indicies. */ - ++*pp; - voffset = parse_number (pp, (boolean *) NULL); - if (**pp != ';') - { - bad_stab (orig); - return false; - } - ++*pp; - voffset &= 0x7fffffff; - - if (**pp == ';' || *pp == '\0') - { - /* Must be g++ version 1. */ - context = DEBUG_TYPE_NULL; - } - else - { - /* Figure out from whence this virtual function - came. It may belong to virtual function table of - one of its baseclasses. */ - look_ahead_type = parse_stab_type (dhandle, info, - (const char *) NULL, - pp, - (debug_type **) NULL); - if (**pp == ':') - { - /* g++ version 1 overloaded methods. */ - context = DEBUG_TYPE_NULL; - } - else - { - context = look_ahead_type; - look_ahead_type = DEBUG_TYPE_NULL; - if (**pp != ';') - { - bad_stab (orig); - return false; - } - ++*pp; - } - } - break; - - case '?': - /* static member function. */ - ++*pp; - staticp = true; - voffset = 0; - context = DEBUG_TYPE_NULL; - if (strncmp (argtypes, name, strlen (name)) != 0) - stub = true; - break; - - default: - warn_stab (orig, "member function type missing"); - voffset = 0; - context = DEBUG_TYPE_NULL; - break; - - case '.': - ++*pp; - voffset = 0; - context = DEBUG_TYPE_NULL; - break; - } - - /* If the type is not a stub, then the argtypes string is - the physical name of the function. Otherwise the - argtypes string is the mangled form of the argument - types, and the full type and the physical name must be - extracted from them. */ - if (! stub) - physname = argtypes; - else - { - debug_type class_type, return_type; - - class_type = stab_find_type (dhandle, info, typenums); - if (class_type == DEBUG_TYPE_NULL) - return false; - return_type = debug_get_return_type (dhandle, type); - if (return_type == DEBUG_TYPE_NULL) - { - bad_stab (orig); - return false; - } - type = parse_stab_argtypes (dhandle, info, class_type, name, - tagname, return_type, argtypes, - constp, volatilep, &physname); - if (type == DEBUG_TYPE_NULL) - return false; - } - - if (cvars + 1 >= allocvars) - { - allocvars += 10; - variants = ((debug_method_variant *) - xrealloc ((PTR) variants, - allocvars * sizeof *variants)); - } - - if (! staticp) - variants[cvars] = debug_make_method_variant (dhandle, physname, - type, visibility, - constp, volatilep, - voffset, context); - else - variants[cvars] = debug_make_static_method_variant (dhandle, - physname, - type, - visibility, - constp, - volatilep); - if (variants[cvars] == DEBUG_METHOD_VARIANT_NULL) - return false; - - ++cvars; - } - while (**pp != ';' && **pp != '\0'); - - variants[cvars] = DEBUG_METHOD_VARIANT_NULL; - - if (**pp != '\0') - ++*pp; - - if (c + 1 >= alloc) - { - alloc += 10; - methods = ((debug_method *) - xrealloc ((PTR) methods, alloc * sizeof *methods)); - } - - methods[c] = debug_make_method (dhandle, name, variants); - - ++c; - } - - if (methods != NULL) - methods[c] = DEBUG_METHOD_NULL; - - *retp = methods; - - return true; -} - -/* Parse a string representing argument types for a method. Stabs - tries to save space by packing argument types into a mangled - string. This string should give us enough information to extract - both argument types and the physical name of the function, given - the tag name. */ - -static debug_type -parse_stab_argtypes (dhandle, info, class_type, fieldname, tagname, - return_type, argtypes, constp, volatilep, pphysname) - PTR dhandle; - struct stab_handle *info; - debug_type class_type; - const char *fieldname; - const char *tagname; - debug_type return_type; - const char *argtypes; - boolean constp; - boolean volatilep; - const char **pphysname; -{ - boolean is_full_physname_constructor; - boolean is_constructor; - boolean is_destructor; - debug_type *args; - boolean varargs; - - /* Constructors are sometimes handled specially. */ - is_full_physname_constructor = ((argtypes[0] == '_' - && argtypes[1] == '_' - && (isdigit ((unsigned char) argtypes[2]) - || argtypes[2] == 'Q' - || argtypes[2] == 't')) - || strncmp (argtypes, "__ct", 4) == 0); - - is_constructor = (is_full_physname_constructor - || (tagname != NULL - && strcmp (fieldname, tagname) == 0)); - is_destructor = ((argtypes[0] == '_' - && (argtypes[1] == '$' || argtypes[1] == '.') - && argtypes[2] == '_') - || strncmp (argtypes, "__dt", 4) == 0); - - if (is_destructor || is_full_physname_constructor) - *pphysname = argtypes; - else - { - unsigned int len; - const char *const_prefix; - const char *volatile_prefix; - char buf[20]; - unsigned int mangled_name_len; - char *physname; - - len = tagname == NULL ? 0 : strlen (tagname); - const_prefix = constp ? "C" : ""; - volatile_prefix = volatilep ? "V" : ""; - - if (len == 0) - sprintf (buf, "__%s%s", const_prefix, volatile_prefix); - else if (tagname != NULL && strchr (tagname, '<') != NULL) - { - /* Template methods are fully mangled. */ - sprintf (buf, "__%s%s", const_prefix, volatile_prefix); - tagname = NULL; - len = 0; - } - else - sprintf (buf, "__%s%s%d", const_prefix, volatile_prefix, len); - - mangled_name_len = ((is_constructor ? 0 : strlen (fieldname)) - + strlen (buf) - + len - + strlen (argtypes) - + 1); - - if (fieldname[0] == 'o' - && fieldname[1] == 'p' - && (fieldname[2] == '$' || fieldname[2] == '.')) - { - const char *opname; - - opname = cplus_mangle_opname (fieldname + 3, 0); - if (opname == NULL) - { - fprintf (stderr, "No mangling for \"%s\"\n", fieldname); - return DEBUG_TYPE_NULL; - } - mangled_name_len += strlen (opname); - physname = (char *) xmalloc (mangled_name_len); - strncpy (physname, fieldname, 3); - strcpy (physname + 3, opname); - } - else - { - physname = (char *) xmalloc (mangled_name_len); - if (is_constructor) - physname[0] = '\0'; - else - strcpy (physname, fieldname); - } - - strcat (physname, buf); - if (tagname != NULL) - strcat (physname, tagname); - strcat (physname, argtypes); - - *pphysname = physname; - } - - if (*argtypes == '\0' || is_destructor) - { - args = (debug_type *) xmalloc (sizeof *args); - *args = NULL; - return debug_make_method_type (dhandle, return_type, class_type, args, - false); - } - - args = stab_demangle_argtypes (dhandle, info, *pphysname, &varargs); - if (args == NULL) - return DEBUG_TYPE_NULL; - - return debug_make_method_type (dhandle, return_type, class_type, args, - varargs); -} - -/* The tail end of stabs for C++ classes that contain a virtual function - pointer contains a tilde, a %, and a type number. - The type number refers to the base class (possibly this class itself) which - contains the vtable pointer for the current class. - - This function is called when we have parsed all the method declarations, - so we can look for the vptr base class info. */ - -static boolean -parse_stab_tilde_field (dhandle, info, pp, typenums, retvptrbase, retownvptr) - PTR dhandle; - struct stab_handle *info; - const char **pp; - const int *typenums; - debug_type *retvptrbase; - boolean *retownvptr; -{ - const char *orig; - const char *hold; - int vtypenums[2]; - - *retvptrbase = DEBUG_TYPE_NULL; - *retownvptr = false; - - orig = *pp; - - /* If we are positioned at a ';', then skip it. */ - if (**pp == ';') - ++*pp; - - if (**pp != '~') - return true; - - ++*pp; - - if (**pp == '=' || **pp == '+' || **pp == '-') - { - /* Obsolete flags that used to indicate the presence of - constructors and/or destructors. */ - ++*pp; - } - - if (**pp != '%') - return true; - - ++*pp; - - hold = *pp; - - /* The next number is the type number of the base class (possibly - our own class) which supplies the vtable for this class. */ - if (! parse_stab_type_number (pp, vtypenums)) - return false; - - if (vtypenums[0] == typenums[0] - && vtypenums[1] == typenums[1]) - *retownvptr = true; - else - { - debug_type vtype; - const char *p; - - *pp = hold; - - vtype = parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL); - for (p = *pp; *p != ';' && *p != '\0'; p++) - ; - if (*p != ';') - { - bad_stab (orig); - return false; - } - - *retvptrbase = vtype; - - *pp = p + 1; - } - - return true; -} - -/* Read a definition of an array type. */ - -static debug_type -parse_stab_array_type (dhandle, info, pp, stringp) - PTR dhandle; - struct stab_handle *info; - const char **pp; - boolean stringp; -{ - const char *orig; - const char *p; - int typenums[2]; - debug_type index_type; - boolean adjustable; - bfd_signed_vma lower, upper; - debug_type element_type; - - /* Format of an array type: - "ar;lower;upper;". - OS9000: "arlower,upper;". - - Fortran adjustable arrays use Adigits or Tdigits for lower or upper; - for these, produce a type like float[][]. */ - - orig = *pp; - - /* FIXME: gdb checks os9k_stabs here. */ - - /* If the index type is type 0, we take it as int. */ - p = *pp; - if (! parse_stab_type_number (&p, typenums)) - return DEBUG_TYPE_NULL; - if (typenums[0] == 0 && typenums[1] == 0 && **pp != '=') - { - index_type = debug_find_named_type (dhandle, "int"); - if (index_type == DEBUG_TYPE_NULL) - { - index_type = debug_make_int_type (dhandle, 4, false); - if (index_type == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - } - *pp = p; - } - else - { - index_type = parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL); - } - - if (**pp != ';') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - adjustable = false; - - if (! isdigit ((unsigned char) **pp) && **pp != '-') - { - ++*pp; - adjustable = true; - } - - lower = (bfd_signed_vma) parse_number (pp, (boolean *) NULL); - if (**pp != ';') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - if (! isdigit ((unsigned char) **pp) && **pp != '-') - { - ++*pp; - adjustable = true; - } - - upper = (bfd_signed_vma) parse_number (pp, (boolean *) NULL); - if (**pp != ';') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - element_type = parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL); - if (element_type == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - - if (adjustable) - { - lower = 0; - upper = -1; - } - - return debug_make_array_type (dhandle, element_type, index_type, lower, - upper, stringp); -} - -/* This struct holds information about files we have seen using - N_BINCL. */ - -struct bincl_file -{ - /* The next N_BINCL file. */ - struct bincl_file *next; - /* The next N_BINCL on the stack. */ - struct bincl_file *next_stack; - /* The file name. */ - const char *name; - /* The hash value. */ - bfd_vma hash; - /* The file index. */ - unsigned int file; - /* The list of types defined in this file. */ - struct stab_types *file_types; -}; - -/* Start a new N_BINCL file, pushing it onto the stack. */ - -static void -push_bincl (info, name, hash) - struct stab_handle *info; - const char *name; - bfd_vma hash; -{ - struct bincl_file *n; - - n = (struct bincl_file *) xmalloc (sizeof *n); - n->next = info->bincl_list; - n->next_stack = info->bincl_stack; - n->name = name; - n->hash = hash; - n->file = info->files; - n->file_types = NULL; - info->bincl_list = n; - info->bincl_stack = n; - - ++info->files; - info->file_types = ((struct stab_types **) - xrealloc ((PTR) info->file_types, - (info->files - * sizeof *info->file_types))); - info->file_types[n->file] = NULL; -} - -/* Finish an N_BINCL file, at an N_EINCL, popping the name off the - stack. */ - -static const char * -pop_bincl (info) - struct stab_handle *info; -{ - struct bincl_file *o; - - o = info->bincl_stack; - if (o == NULL) - return info->main_filename; - info->bincl_stack = o->next_stack; - - o->file_types = info->file_types[o->file]; - - if (info->bincl_stack == NULL) - return info->main_filename; - return info->bincl_stack->name; -} - -/* Handle an N_EXCL: get the types from the corresponding N_BINCL. */ - -static boolean -find_excl (info, name, hash) - struct stab_handle *info; - const char *name; - bfd_vma hash; -{ - struct bincl_file *l; - - ++info->files; - info->file_types = ((struct stab_types **) - xrealloc ((PTR) info->file_types, - (info->files - * sizeof *info->file_types))); - - for (l = info->bincl_list; l != NULL; l = l->next) - if (l->hash == hash && strcmp (l->name, name) == 0) - break; - if (l == NULL) - { - warn_stab (name, "Undefined N_EXCL"); - info->file_types[info->files - 1] = NULL; - return true; - } - - info->file_types[info->files - 1] = l->file_types; - - return true; -} - -/* Handle a variable definition. gcc emits variable definitions for a - block before the N_LBRAC, so we must hold onto them until we see - it. The SunPRO compiler emits variable definitions after the - N_LBRAC, so we can call debug_record_variable immediately. */ - -static boolean -stab_record_variable (dhandle, info, name, type, kind, val) - PTR dhandle; - struct stab_handle *info; - const char *name; - debug_type type; - enum debug_var_kind kind; - bfd_vma val; -{ - struct stab_pending_var *v; - - if ((kind == DEBUG_GLOBAL || kind == DEBUG_STATIC) - || ! info->within_function - || (info->gcc_compiled == 0 && info->n_opt_found)) - return debug_record_variable (dhandle, name, type, kind, val); - - v = (struct stab_pending_var *) xmalloc (sizeof *v); - memset (v, 0, sizeof *v); - - v->next = info->pending; - v->name = name; - v->type = type; - v->kind = kind; - v->val = val; - info->pending = v; - - return true; -} - -/* Emit pending variable definitions. This is called after we see the - N_LBRAC that starts the block. */ - -static boolean -stab_emit_pending_vars (dhandle, info) - PTR dhandle; - struct stab_handle *info; -{ - struct stab_pending_var *v; - - v = info->pending; - while (v != NULL) - { - struct stab_pending_var *next; - - if (! debug_record_variable (dhandle, v->name, v->type, v->kind, v->val)) - return false; - - next = v->next; - free (v); - v = next; - } - - info->pending = NULL; - - return true; -} - -/* Find the slot for a type in the database. */ - -static debug_type * -stab_find_slot (info, typenums) - struct stab_handle *info; - const int *typenums; -{ - int filenum; - int index; - struct stab_types **ps; - - filenum = typenums[0]; - index = typenums[1]; - - if (filenum < 0 || (unsigned int) filenum >= info->files) - { - fprintf (stderr, "Type file number %d out of range\n", filenum); - return NULL; - } - if (index < 0) - { - fprintf (stderr, "Type index number %d out of range\n", index); - return NULL; - } - - ps = info->file_types + filenum; - - while (index >= STAB_TYPES_SLOTS) - { - if (*ps == NULL) - { - *ps = (struct stab_types *) xmalloc (sizeof **ps); - memset (*ps, 0, sizeof **ps); - } - ps = &(*ps)->next; - index -= STAB_TYPES_SLOTS; - } - if (*ps == NULL) - { - *ps = (struct stab_types *) xmalloc (sizeof **ps); - memset (*ps, 0, sizeof **ps); - } - - return (*ps)->types + index; -} - -/* Find a type given a type number. If the type has not been - allocated yet, create an indirect type. */ - -static debug_type -stab_find_type (dhandle, info, typenums) - PTR dhandle; - struct stab_handle *info; - const int *typenums; -{ - debug_type *slot; - - if (typenums[0] == 0 && typenums[1] < 0) - { - /* A negative type number indicates an XCOFF builtin type. */ - return stab_xcoff_builtin_type (dhandle, info, typenums[1]); - } - - slot = stab_find_slot (info, typenums); - if (slot == NULL) - return DEBUG_TYPE_NULL; - - if (*slot == DEBUG_TYPE_NULL) - return debug_make_indirect_type (dhandle, slot, (const char *) NULL); - - return *slot; -} - -/* Record that a given type number refers to a given type. */ - -static boolean -stab_record_type (dhandle, info, typenums, type) - PTR dhandle; - struct stab_handle *info; - const int *typenums; - debug_type type; -{ - debug_type *slot; - - slot = stab_find_slot (info, typenums); - if (slot == NULL) - return false; - - /* gdb appears to ignore type redefinitions, so we do as well. */ - - *slot = type; - - return true; -} - -/* Return an XCOFF builtin type. */ - -static debug_type -stab_xcoff_builtin_type (dhandle, info, typenum) - PTR dhandle; - struct stab_handle *info; - int typenum; -{ - debug_type rettype; - const char *name; - - if (typenum >= 0 || typenum < -XCOFF_TYPE_COUNT) - { - fprintf (stderr, "Unrecognized XCOFF type %d\n", typenum); - return DEBUG_TYPE_NULL; - } - if (info->xcoff_types[-typenum] != NULL) - return info->xcoff_types[-typenum]; - - switch (-typenum) - { - case 1: - /* The size of this and all the other types are fixed, defined - by the debugging format. */ - name = "int"; - rettype = debug_make_int_type (dhandle, 4, false); - break; - case 2: - name = "char"; - rettype = debug_make_int_type (dhandle, 1, false); - break; - case 3: - name = "short"; - rettype = debug_make_int_type (dhandle, 2, false); - break; - case 4: - name = "long"; - rettype = debug_make_int_type (dhandle, 4, false); - break; - case 5: - name = "unsigned char"; - rettype = debug_make_int_type (dhandle, 1, true); - break; - case 6: - name = "signed char"; - rettype = debug_make_int_type (dhandle, 1, false); - break; - case 7: - name = "unsigned short"; - rettype = debug_make_int_type (dhandle, 2, true); - break; - case 8: - name = "unsigned int"; - rettype = debug_make_int_type (dhandle, 4, true); - break; - case 9: - name = "unsigned"; - rettype = debug_make_int_type (dhandle, 4, true); - case 10: - name = "unsigned long"; - rettype = debug_make_int_type (dhandle, 4, true); - break; - case 11: - name = "void"; - rettype = debug_make_void_type (dhandle); - break; - case 12: - /* IEEE single precision (32 bit). */ - name = "float"; - rettype = debug_make_float_type (dhandle, 4); - break; - case 13: - /* IEEE double precision (64 bit). */ - name = "double"; - rettype = debug_make_float_type (dhandle, 8); - break; - case 14: - /* This is an IEEE double on the RS/6000, and different machines - with different sizes for "long double" should use different - negative type numbers. See stabs.texinfo. */ - name = "long double"; - rettype = debug_make_float_type (dhandle, 8); - break; - case 15: - name = "integer"; - rettype = debug_make_int_type (dhandle, 4, false); - break; - case 16: - name = "boolean"; - rettype = debug_make_bool_type (dhandle, 4); - break; - case 17: - name = "short real"; - rettype = debug_make_float_type (dhandle, 4); - break; - case 18: - name = "real"; - rettype = debug_make_float_type (dhandle, 8); - break; - case 19: - /* FIXME */ - name = "stringptr"; - rettype = NULL; - break; - case 20: - /* FIXME */ - name = "character"; - rettype = debug_make_int_type (dhandle, 1, true); - break; - case 21: - name = "logical*1"; - rettype = debug_make_bool_type (dhandle, 1); - break; - case 22: - name = "logical*2"; - rettype = debug_make_bool_type (dhandle, 2); - break; - case 23: - name = "logical*4"; - rettype = debug_make_bool_type (dhandle, 4); - break; - case 24: - name = "logical"; - rettype = debug_make_bool_type (dhandle, 4); - break; - case 25: - /* Complex type consisting of two IEEE single precision values. */ - name = "complex"; - rettype = debug_make_complex_type (dhandle, 8); - break; - case 26: - /* Complex type consisting of two IEEE double precision values. */ - name = "double complex"; - rettype = debug_make_complex_type (dhandle, 16); - break; - case 27: - name = "integer*1"; - rettype = debug_make_int_type (dhandle, 1, false); - break; - case 28: - name = "integer*2"; - rettype = debug_make_int_type (dhandle, 2, false); - break; - case 29: - name = "integer*4"; - rettype = debug_make_int_type (dhandle, 4, false); - break; - case 30: - /* FIXME */ - name = "wchar"; - rettype = debug_make_int_type (dhandle, 2, false); - break; - case 31: - name = "long long"; - rettype = debug_make_int_type (dhandle, 8, false); - break; - case 32: - name = "unsigned long long"; - rettype = debug_make_int_type (dhandle, 8, true); - break; - case 33: - name = "logical*8"; - rettype = debug_make_bool_type (dhandle, 8); - break; - case 34: - name = "integer*8"; - rettype = debug_make_int_type (dhandle, 8, false); - break; - default: - abort (); - } - - rettype = debug_name_type (dhandle, name, rettype); - - info->xcoff_types[-typenum] = rettype; - - return rettype; -} - -/* Find or create a tagged type. */ - -static debug_type -stab_find_tagged_type (dhandle, info, p, len, kind) - PTR dhandle; - struct stab_handle *info; - const char *p; - int len; - enum debug_type_kind kind; -{ - char *name; - debug_type dtype; - struct stab_tag *st; - - name = savestring (p, len); - - /* We pass DEBUG_KIND_ILLEGAL because we want all tags in the same - namespace. This is right for C, and I don't know how to handle - other languages. FIXME. */ - dtype = debug_find_tagged_type (dhandle, name, DEBUG_KIND_ILLEGAL); - if (dtype != DEBUG_TYPE_NULL) - { - free (name); - return dtype; - } - - /* We need to allocate an entry on the undefined tag list. */ - for (st = info->tags; st != NULL; st = st->next) - { - if (st->name[0] == name[0] - && strcmp (st->name, name) == 0) - { - if (st->kind == DEBUG_KIND_ILLEGAL) - st->kind = kind; - free (name); - break; - } - } - if (st == NULL) - { - st = (struct stab_tag *) xmalloc (sizeof *st); - memset (st, 0, sizeof *st); - - st->next = info->tags; - st->name = name; - st->kind = kind; - st->slot = DEBUG_TYPE_NULL; - st->type = debug_make_indirect_type (dhandle, &st->slot, name); - info->tags = st; - } - - return st->type; -} - -/* In order to get the correct argument types for a stubbed method, we - need to extract the argument types from a C++ mangled string. - Since the argument types can refer back to the return type, this - means that we must demangle the entire physical name. In gdb this - is done by calling cplus_demangle and running the results back - through the C++ expression parser. Since we have no expression - parser, we must duplicate much of the work of cplus_demangle here. - - We assume that GNU style demangling is used, since this is only - done for method stubs, and only g++ should output that form of - debugging information. */ - -/* This structure is used to hold a pointer to type information which - demangling a string. */ - -struct stab_demangle_typestring -{ - /* The start of the type. This is not null terminated. */ - const char *typestring; - /* The length of the type. */ - unsigned int len; -}; - -/* This structure is used to hold information while demangling a - string. */ - -struct stab_demangle_info -{ - /* The debugging information handle. */ - PTR dhandle; - /* The stab information handle. */ - struct stab_handle *info; - /* The array of arguments we are building. */ - debug_type *args; - /* Whether the method takes a variable number of arguments. */ - boolean varargs; - /* The array of types we have remembered. */ - struct stab_demangle_typestring *typestrings; - /* The number of typestrings. */ - unsigned int typestring_count; - /* The number of typestring slots we have allocated. */ - unsigned int typestring_alloc; -}; - -static void stab_bad_demangle PARAMS ((const char *)); -static unsigned int stab_demangle_count PARAMS ((const char **)); -static boolean stab_demangle_get_count - PARAMS ((const char **, unsigned int *)); -static boolean stab_demangle_prefix - PARAMS ((struct stab_demangle_info *, const char **)); -static boolean stab_demangle_function_name - PARAMS ((struct stab_demangle_info *, const char **, const char *)); -static boolean stab_demangle_signature - PARAMS ((struct stab_demangle_info *, const char **)); -static boolean stab_demangle_qualified - PARAMS ((struct stab_demangle_info *, const char **, debug_type *)); -static boolean stab_demangle_template - PARAMS ((struct stab_demangle_info *, const char **)); -static boolean stab_demangle_class - PARAMS ((struct stab_demangle_info *, const char **, const char **)); -static boolean stab_demangle_args - PARAMS ((struct stab_demangle_info *, const char **, debug_type **, - boolean *)); -static boolean stab_demangle_arg - PARAMS ((struct stab_demangle_info *, const char **, debug_type **, - unsigned int *, unsigned int *)); -static boolean stab_demangle_type - PARAMS ((struct stab_demangle_info *, const char **, debug_type *)); -static boolean stab_demangle_fund_type - PARAMS ((struct stab_demangle_info *, const char **, debug_type *)); -static boolean stab_demangle_remember_type - PARAMS ((struct stab_demangle_info *, const char *, int)); - -/* Warn about a bad demangling. */ - -static void -stab_bad_demangle (s) - const char *s; -{ - fprintf (stderr, "bad mangled name `%s'\n", s); -} - -/* Get a count from a stab string. */ - -static unsigned int -stab_demangle_count (pp) - const char **pp; -{ - unsigned int count; - - count = 0; - while (isdigit ((unsigned char) **pp)) - { - count *= 10; - count += **pp - '0'; - ++*pp; - } - return count; -} - -/* Require a count in a string. The count may be multiple digits, in - which case it must end in an underscore. */ - -static boolean -stab_demangle_get_count (pp, pi) - const char **pp; - unsigned int *pi; -{ - if (! isdigit ((unsigned char) **pp)) - return false; - - *pi = **pp - '0'; - ++*pp; - if (isdigit ((unsigned char) **pp)) - { - unsigned int count; - const char *p; - - count = *pi; - p = *pp; - do - { - count *= 10; - count += *p - '0'; - ++p; - } - while (isdigit ((unsigned char) *p)); - if (*p == '_') - { - *pp = p + 1; - *pi = count; - } - } - - return true; -} - -/* This function demangles a physical name, returning a NULL - terminated array of argument types. */ - -static debug_type * -stab_demangle_argtypes (dhandle, info, physname, pvarargs) - PTR dhandle; - struct stab_handle *info; - const char *physname; - boolean *pvarargs; -{ - struct stab_demangle_info minfo; - - minfo.dhandle = dhandle; - minfo.info = info; - minfo.args = NULL; - minfo.varargs = false; - minfo.typestring_alloc = 10; - minfo.typestrings = ((struct stab_demangle_typestring *) - xmalloc (minfo.typestring_alloc - * sizeof *minfo.typestrings)); - minfo.typestring_count = 0; - - /* cplus_demangle checks for special GNU mangled forms, but we can't - see any of them in mangled method argument types. */ - - if (! stab_demangle_prefix (&minfo, &physname)) - goto error_return; - - if (*physname != '\0') - { - if (! stab_demangle_signature (&minfo, &physname)) - goto error_return; - } - - free (minfo.typestrings); - minfo.typestrings = NULL; - - if (minfo.args == NULL) - fprintf (stderr, "no argument types in mangled string\n"); - - *pvarargs = minfo.varargs; - return minfo.args; - - error_return: - if (minfo.typestrings != NULL) - free (minfo.typestrings); - return NULL; -} - -/* Demangle the prefix of the mangled name. */ - -static boolean -stab_demangle_prefix (minfo, pp) - struct stab_demangle_info *minfo; - const char **pp; -{ - const char *scan; - unsigned int i; - - /* cplus_demangle checks for global constructors and destructors, - but we can't see them in mangled argument types. */ - - /* Look for `__'. */ - scan = *pp; - do - { - scan = strchr (scan, '_'); - } - while (scan != NULL && *++scan != '_'); - - if (scan == NULL) - { - stab_bad_demangle (*pp); - return false; - } - - --scan; - - /* We found `__'; move ahead to the last contiguous `__' pair. */ - i = strspn (scan, "_"); - if (i > 2) - scan += i - 2; - - if (scan == *pp - && (isdigit ((unsigned char) scan[2]) - || scan[2] == 'Q' - || scan[2] == 't')) - { - /* This is a GNU style constructor name. */ - *pp = scan + 2; - return true; - } - else if (scan == *pp - && ! isdigit ((unsigned char) scan[2]) - && scan[2] != 't') - { - /* Look for the `__' that separates the prefix from the - signature. */ - while (*scan == '_') - ++scan; - scan = strstr (scan, "__"); - if (scan == NULL || scan[2] == '\0') - { - stab_bad_demangle (*pp); - return false; - } - - return stab_demangle_function_name (minfo, pp, scan); - } - else if (scan[2] != '\0') - { - /* The name doesn't start with `__', but it does contain `__'. */ - return stab_demangle_function_name (minfo, pp, scan); - } - else - { - stab_bad_demangle (*pp); - return false; - } - /*NOTREACHED*/ -} - -/* Demangle a function name prefix. The scan argument points to the - double underscore which separates the function name from the - signature. */ - -static boolean -stab_demangle_function_name (minfo, pp, scan) - struct stab_demangle_info *minfo; - const char **pp; - const char *scan; -{ - const char *name; - - /* The string from *pp to scan is the name of the function. We - don't care about the name, since we just looking for argument - types. However, for conversion operators, the name may include a - type which we must remember in order to handle backreferences. */ - - name = *pp; - *pp = scan + 2; - - if (*pp - name >= 5 - && strncmp (name, "type", 4) == 0 - && (name[4] == '$' || name[4] == '.')) - { - const char *tem; - - /* This is a type conversion operator. */ - tem = name + 5; - if (! stab_demangle_type (minfo, &tem, (debug_type *) NULL)) - return false; - } - else if (name[0] == '_' - && name[1] == '_' - && name[2] == 'o' - && name[3] == 'p') - { - const char *tem; - - /* This is a type conversion operator. */ - tem = name + 4; - if (! stab_demangle_type (minfo, &tem, (debug_type *) NULL)) - return false; - } - - return true; -} - -/* Demangle the signature. This is where the argument types are - found. */ - -static boolean -stab_demangle_signature (minfo, pp) - struct stab_demangle_info *minfo; - const char **pp; -{ - const char *orig; - boolean expect_func, func_done; - const char *hold; - - orig = *pp; - - expect_func = false; - func_done = false; - hold = NULL; - - while (**pp != '\0') - { - switch (**pp) - { - case 'Q': - hold = *pp; - if (! stab_demangle_qualified (minfo, pp, (debug_type *) NULL) - || ! stab_demangle_remember_type (minfo, hold, *pp - hold)) - return false; - expect_func = true; - hold = NULL; - break; - - case 'S': - /* Static member function. FIXME: Can this happen? */ - if (hold == NULL) - hold = *pp; - ++*pp; - break; - - case 'C': - /* Const member function. */ - if (hold == NULL) - hold = *pp; - ++*pp; - break; - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - if (hold == NULL) - hold = *pp; - if (! stab_demangle_class (minfo, pp, (const char **) NULL) - || ! stab_demangle_remember_type (minfo, hold, *pp - hold)) - return false; - expect_func = true; - hold = NULL; - break; - - case 'F': - /* Function. I don't know if this actually happens with g++ - output. */ - hold = NULL; - func_done = true; - ++*pp; - if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs)) - return false; - break; - - case 't': - /* Template. */ - if (hold == NULL) - hold = *pp; - if (! stab_demangle_template (minfo, pp) - || ! stab_demangle_remember_type (minfo, hold, *pp - hold)) - return false; - hold = NULL; - expect_func = true; - break; - - case '_': - /* At the outermost level, we cannot have a return type - specified, so if we run into another '_' at this point we - are dealing with a mangled name that is either bogus, or - has been mangled by some algorithm we don't know how to - deal with. So just reject the entire demangling. */ - stab_bad_demangle (orig); - return false; - - default: - /* Assume we have stumbled onto the first outermost function - argument token, and start processing args. */ - func_done = true; - if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs)) - return false; - break; - } - - if (expect_func) - { - func_done = true; - if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs)) - return false; - } - } - - if (! func_done) - { - /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and - bar__3fooi is 'foo::bar(int)'. We get here when we find the - first case, and need to ensure that the '(void)' gets added - to the current declp. */ - if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs)) - return false; - } - - return true; -} - -/* Demangle a qualified name, such as "Q25Outer5Inner" which is the - mangled form of "Outer::Inner". */ - -static boolean -stab_demangle_qualified (minfo, pp, ptype) - struct stab_demangle_info *minfo; - const char **pp; - debug_type *ptype; -{ - const char *orig; - const char *p; - unsigned int qualifiers; - debug_type context; - - orig = *pp; - - switch ((*pp)[1]) - { - case '_': - /* GNU mangled name with more than 9 classes. The count is - preceded by an underscore (to distinguish it from the <= 9 - case) and followed by an underscore. */ - p = *pp + 2; - if (! isdigit ((unsigned char) *p) || *p == '0') - { - stab_bad_demangle (orig); - return false; - } - qualifiers = atoi (p); - while (isdigit ((unsigned char) *p)) - ++p; - if (*p != '_') - { - stab_bad_demangle (orig); - return false; - } - *pp = p + 1; - break; - - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - qualifiers = (*pp)[1] - '0'; - /* Skip an optional underscore after the count. */ - if ((*pp)[2] == '_') - ++*pp; - *pp += 2; - break; - - case '0': - default: - stab_bad_demangle (orig); - return false; - } - - context = DEBUG_TYPE_NULL; - - /* Pick off the names. */ - while (qualifiers-- > 0) - { - if (**pp == '_') - ++*pp; - if (**pp == 't') - { - /* FIXME: I don't know how to handle the ptype != NULL case - here. */ - if (! stab_demangle_template (minfo, pp)) - return false; - } - else - { - unsigned int len; - - len = stab_demangle_count (pp); - if (strlen (*pp) < len) - { - stab_bad_demangle (orig); - return false; - } - - if (ptype != NULL) - { - const debug_field *fields; - - fields = NULL; - if (context != DEBUG_TYPE_NULL) - fields = debug_get_fields (minfo->dhandle, context); - - context = DEBUG_TYPE_NULL; - - if (fields != NULL) - { - char *name; - - /* Try to find the type by looking through the - fields of context until we find a field with the - same type. This ought to work for a class - defined within a class, but it won't work for, - e.g., an enum defined within a class. stabs does - not give us enough information to figure out the - latter case. */ - - name = savestring (*pp, len); - - for (; *fields != DEBUG_FIELD_NULL; fields++) - { - debug_type ft; - const char *dn; - - ft = debug_get_field_type (minfo->dhandle, *fields); - if (ft == NULL) - return false; - dn = debug_get_type_name (minfo->dhandle, ft); - if (dn != NULL && strcmp (dn, name) == 0) - { - context = ft; - break; - } - } - - free (name); - } - - if (context == DEBUG_TYPE_NULL) - { - /* We have to fall back on finding the type by name. - If there are more types to come, then this must - be a class. Otherwise, it could be anything. */ - - if (qualifiers == 0) - { - char *name; - - name = savestring (*pp, len); - context = debug_find_named_type (minfo->dhandle, - name); - free (name); - } - - if (context == DEBUG_TYPE_NULL) - { - context = stab_find_tagged_type (minfo->dhandle, - minfo->info, - *pp, len, - (qualifiers == 0 - ? DEBUG_KIND_ILLEGAL - : DEBUG_KIND_CLASS)); - if (context == DEBUG_TYPE_NULL) - return false; - } - } - } - - *pp += len; - } - } - - if (ptype != NULL) - *ptype = context; - - return true; -} - -/* Demangle a template. */ - -static boolean -stab_demangle_template (minfo, pp) - struct stab_demangle_info *minfo; - const char **pp; -{ - const char *orig; - unsigned int r, i; - - orig = *pp; - - ++*pp; - - /* Skip the template name. */ - r = stab_demangle_count (pp); - if (r == 0 || strlen (*pp) < r) - { - stab_bad_demangle (orig); - return false; - } - *pp += r; - - /* Get the size of the parameter list. */ - if (stab_demangle_get_count (pp, &r) == 0) - { - stab_bad_demangle (orig); - return false; - } - - for (i = 0; i < r; i++) - { - if (**pp == 'Z') - { - /* This is a type parameter. */ - ++*pp; - if (! stab_demangle_type (minfo, pp, (debug_type *) NULL)) - return false; - } - else - { - const char *old_p; - boolean pointerp, realp, integralp, charp, boolp; - boolean done; - - old_p = *pp; - pointerp = false; - realp = false; - integralp = false; - charp = false; - boolp = false; - done = false; - - /* This is a value parameter. */ - - if (! stab_demangle_type (minfo, pp, (debug_type *) NULL)) - return false; - - while (*old_p != '\0' && ! done) - { - switch (*old_p) - { - case 'P': - case 'p': - case 'R': - pointerp = true; - done = true; - break; - case 'C': /* Const. */ - case 'S': /* Signed. */ - case 'U': /* Unsigned. */ - case 'V': /* Volatile. */ - case 'F': /* Function. */ - case 'M': /* Member function. */ - case 'O': /* ??? */ - ++old_p; - break; - case 'Q': /* Qualified name. */ - integralp = true; - done = true; - break; - case 'T': /* Remembered type. */ - abort (); - case 'v': /* Void. */ - abort (); - case 'x': /* Long long. */ - case 'l': /* Long. */ - case 'i': /* Int. */ - case 's': /* Short. */ - case 'w': /* Wchar_t. */ - integralp = true; - done = true; - break; - case 'b': /* Bool. */ - boolp = true; - done = true; - break; - case 'c': /* Char. */ - charp = true; - done = true; - break; - case 'r': /* Long double. */ - case 'd': /* Double. */ - case 'f': /* Float. */ - realp = true; - done = true; - break; - default: - /* Assume it's a user defined integral type. */ - integralp = true; - done = true; - break; - } - } - - if (integralp) - { - if (**pp == 'm') - ++*pp; - while (isdigit ((unsigned char) **pp)) - ++*pp; - } - else if (charp) - { - unsigned int val; - - if (**pp == 'm') - ++*pp; - val = stab_demangle_count (pp); - if (val == 0) - { - stab_bad_demangle (orig); - return false; - } - } - else if (boolp) - { - unsigned int val; - - val = stab_demangle_count (pp); - if (val != 0 && val != 1) - { - stab_bad_demangle (orig); - return false; - } - } - else if (realp) - { - if (**pp == 'm') - ++*pp; - while (isdigit ((unsigned char) **pp)) - ++*pp; - if (**pp == '.') - { - ++*pp; - while (isdigit ((unsigned char) **pp)) - ++*pp; - } - if (**pp == 'e') - { - ++*pp; - while (isdigit ((unsigned char) **pp)) - ++*pp; - } - } - else if (pointerp) - { - unsigned int len; - - if (! stab_demangle_get_count (pp, &len)) - { - stab_bad_demangle (orig); - return false; - } - *pp += len; - } - } - } - - return true; -} - -/* Demangle a class name. */ - -static boolean -stab_demangle_class (minfo, pp, pstart) - struct stab_demangle_info *minfo; - const char **pp; - const char **pstart; -{ - const char *orig; - unsigned int n; - - orig = *pp; - - n = stab_demangle_count (pp); - if (strlen (*pp) < n) - { - stab_bad_demangle (orig); - return false; - } - - if (pstart != NULL) - *pstart = *pp; - - *pp += n; - - return true; -} - -/* Demangle function arguments. If the pargs argument is not NULL, it - is set to a NULL terminated array holding the arguments. */ - -static boolean -stab_demangle_args (minfo, pp, pargs, pvarargs) - struct stab_demangle_info *minfo; - const char **pp; - debug_type **pargs; - boolean *pvarargs; -{ - const char *orig; - unsigned int alloc, count; - - orig = *pp; - - alloc = 10; - if (pargs != NULL) - { - *pargs = (debug_type *) xmalloc (alloc * sizeof **pargs); - *pvarargs = false; - } - count = 0; - - while (**pp != '_' && **pp != '\0' && **pp != 'e') - { - if (**pp == 'N' || **pp == 'T') - { - char temptype; - unsigned int r, t; - - temptype = **pp; - ++*pp; - - if (temptype == 'T') - r = 1; - else - { - if (! stab_demangle_get_count (pp, &r)) - { - stab_bad_demangle (orig); - return false; - } - } - - if (! stab_demangle_get_count (pp, &t)) - { - stab_bad_demangle (orig); - return false; - } - - if (t >= minfo->typestring_count) - { - stab_bad_demangle (orig); - return false; - } - while (r-- > 0) - { - const char *tem; - - tem = minfo->typestrings[t].typestring; - if (! stab_demangle_arg (minfo, &tem, pargs, &count, &alloc)) - return false; - } - } - else - { - if (! stab_demangle_arg (minfo, pp, pargs, &count, &alloc)) - return false; - } - } - - if (pargs != NULL) - (*pargs)[count] = DEBUG_TYPE_NULL; - - if (**pp == 'e') - { - if (pargs != NULL) - *pvarargs = true; - ++*pp; - } - - return true; -} - -/* Demangle a single argument. */ - -static boolean -stab_demangle_arg (minfo, pp, pargs, pcount, palloc) - struct stab_demangle_info *minfo; - const char **pp; - debug_type **pargs; - unsigned int *pcount; - unsigned int *palloc; -{ - const char *start; - debug_type type; - - start = *pp; - if (! stab_demangle_type (minfo, pp, - pargs == NULL ? (debug_type *) NULL : &type) - || ! stab_demangle_remember_type (minfo, start, *pp - start)) - return false; - - if (pargs != NULL) - { - if (type == DEBUG_TYPE_NULL) - return false; - - if (*pcount + 1 >= *palloc) - { - *palloc += 10; - *pargs = ((debug_type *) - xrealloc (*pargs, *palloc * sizeof **pargs)); - } - (*pargs)[*pcount] = type; - ++*pcount; - } - - return true; -} - -/* Demangle a type. If the ptype argument is not NULL, *ptype is set - to the newly allocated type. */ - -static boolean -stab_demangle_type (minfo, pp, ptype) - struct stab_demangle_info *minfo; - const char **pp; - debug_type *ptype; -{ - const char *orig; - - orig = *pp; - - switch (**pp) - { - case 'P': - case 'p': - /* A pointer type. */ - ++*pp; - if (! stab_demangle_type (minfo, pp, ptype)) - return false; - if (ptype != NULL) - *ptype = debug_make_pointer_type (minfo->dhandle, *ptype); - break; - - case 'R': - /* A reference type. */ - ++*pp; - if (! stab_demangle_type (minfo, pp, ptype)) - return false; - if (ptype != NULL) - *ptype = debug_make_reference_type (minfo->dhandle, *ptype); - break; - - case 'A': - /* An array. */ - { - unsigned long high; - - ++*pp; - high = 0; - while (**pp != '\0' && **pp != '_') - { - if (! isdigit ((unsigned char) **pp)) - { - stab_bad_demangle (orig); - return false; - } - high *= 10; - high += **pp - '0'; - ++*pp; - } - if (**pp != '_') - { - stab_bad_demangle (orig); - return false; - } - ++*pp; - - if (! stab_demangle_type (minfo, pp, ptype)) - return false; - if (ptype != NULL) - { - debug_type int_type; - - int_type = debug_find_named_type (minfo->dhandle, "int"); - if (int_type == NULL) - int_type = debug_make_int_type (minfo->dhandle, 4, false); - *ptype = debug_make_array_type (minfo->dhandle, *ptype, int_type, - 0, high, false); - } - } - break; - - case 'T': - /* A back reference to a remembered type. */ - { - unsigned int i; - const char *p; - - ++*pp; - if (! stab_demangle_get_count (pp, &i)) - { - stab_bad_demangle (orig); - return false; - } - if (i >= minfo->typestring_count) - { - stab_bad_demangle (orig); - return false; - } - p = minfo->typestrings[i].typestring; - if (! stab_demangle_type (minfo, &p, ptype)) - return false; - } - break; - - case 'F': - /* A function. */ - { - debug_type *args; - boolean varargs; - - ++*pp; - if (! stab_demangle_args (minfo, pp, - (ptype == NULL - ? (debug_type **) NULL - : &args), - (ptype == NULL - ? (boolean *) NULL - : &varargs))) - return false; - if (**pp != '_') - { - /* cplus_demangle will accept a function without a return - type, but I don't know when that will happen, or what - to do if it does. */ - stab_bad_demangle (orig); - return false; - } - ++*pp; - if (! stab_demangle_type (minfo, pp, ptype)) - return false; - if (ptype != NULL) - *ptype = debug_make_function_type (minfo->dhandle, *ptype, args, - varargs); - - } - break; - - case 'M': - case 'O': - { - boolean memberp, constp, volatilep; - debug_type *args; - boolean varargs; - unsigned int n; - const char *name; - - memberp = **pp == 'M'; - constp = false; - volatilep = false; - args = NULL; - varargs = false; - - ++*pp; - if (! isdigit ((unsigned char) **pp)) - { - stab_bad_demangle (orig); - return false; - } - n = stab_demangle_count (pp); - if (strlen (*pp) < n) - { - stab_bad_demangle (orig); - return false; - } - name = *pp; - *pp += n; - - if (memberp) - { - if (**pp == 'C') - { - constp = true; - ++*pp; - } - else if (**pp == 'V') - { - volatilep = true; - ++*pp; - } - if (**pp != 'F') - { - stab_bad_demangle (orig); - return false; - } - ++*pp; - if (! stab_demangle_args (minfo, pp, - (ptype == NULL - ? (debug_type **) NULL - : &args), - (ptype == NULL - ? (boolean *) NULL - : &varargs))) - return false; - } - - if (**pp != '_') - { - stab_bad_demangle (orig); - return false; - } - ++*pp; - - if (! stab_demangle_type (minfo, pp, ptype)) - return false; - - if (ptype != NULL) - { - debug_type class_type; - - class_type = stab_find_tagged_type (minfo->dhandle, minfo->info, - name, (int) n, - DEBUG_KIND_CLASS); - if (class_type == DEBUG_TYPE_NULL) - return false; - - if (! memberp) - *ptype = debug_make_offset_type (minfo->dhandle, class_type, - *ptype); - else - { - /* FIXME: We have no way to record constp or - volatilep. */ - *ptype = debug_make_method_type (minfo->dhandle, *ptype, - class_type, args, varargs); - } - } - } - break; - - case 'G': - ++*pp; - if (! stab_demangle_type (minfo, pp, ptype)) - return false; - break; - - case 'C': - ++*pp; - if (! stab_demangle_type (minfo, pp, ptype)) - return false; - if (ptype != NULL) - *ptype = debug_make_const_type (minfo->dhandle, *ptype); - break; - - case 'Q': - { - const char *hold; - - hold = *pp; - if (! stab_demangle_qualified (minfo, pp, ptype)) - return false; - } - break; - - default: - if (! stab_demangle_fund_type (minfo, pp, ptype)) - return false; - break; - } - - return true; -} - -/* Demangle a fundamental type. If the ptype argument is not NULL, - *ptype is set to the newly allocated type. */ - -static boolean -stab_demangle_fund_type (minfo, pp, ptype) - struct stab_demangle_info *minfo; - const char **pp; - debug_type *ptype; -{ - const char *orig; - boolean constp, volatilep, unsignedp, signedp; - boolean done; - - orig = *pp; - - constp = false; - volatilep = false; - unsignedp = false; - signedp = false; - - done = false; - while (! done) - { - switch (**pp) - { - case 'C': - constp = true; - ++*pp; - break; - - case 'U': - unsignedp = true; - ++*pp; - break; - - case 'S': - signedp = true; - ++*pp; - break; - - case 'V': - volatilep = true; - ++*pp; - break; - - default: - done = true; - break; - } - } - - switch (**pp) - { - case '\0': - case '_': - /* cplus_demangle permits this, but I don't know what it means. */ - stab_bad_demangle (orig); - break; - - case 'v': /* void */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, "void"); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_void_type (minfo->dhandle); - } - ++*pp; - break; - - case 'x': /* long long */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, - (unsignedp - ? "long long unsigned int" - : "long long int")); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_int_type (minfo->dhandle, 8, unsignedp); - } - ++*pp; - break; - - case 'l': /* long */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, - (unsignedp - ? "long unsigned int" - : "long int")); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_int_type (minfo->dhandle, 4, unsignedp); - } - ++*pp; - break; - - case 'i': /* int */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, - (unsignedp - ? "unsigned int" - : "int")); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_int_type (minfo->dhandle, 4, unsignedp); - } - ++*pp; - break; - - case 's': /* short */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, - (unsignedp - ? "short unsigned int" - : "short int")); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_int_type (minfo->dhandle, 2, unsignedp); - } - ++*pp; - break; - - case 'b': /* bool */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, "bool"); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_bool_type (minfo->dhandle, 4); - } - ++*pp; - break; - - case 'c': /* char */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, - (unsignedp - ? "unsigned char" - : (signedp - ? "signed char" - : "char"))); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_int_type (minfo->dhandle, 1, unsignedp); - } - ++*pp; - break; - - case 'w': /* wchar_t */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, "__wchar_t"); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_int_type (minfo->dhandle, 2, true); - } - ++*pp; - break; - - case 'r': /* long double */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, "long double"); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_float_type (minfo->dhandle, 8); - } - ++*pp; - break; - - case 'd': /* double */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, "double"); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_float_type (minfo->dhandle, 8); - } - ++*pp; - break; - - case 'f': /* float */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, "float"); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_float_type (minfo->dhandle, 4); - } - ++*pp; - break; - - case 'G': - ++*pp; - if (! isdigit ((unsigned char) **pp)) - { - stab_bad_demangle (orig); - return false; - } - /* Fall through. */ - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - { - const char *hold; - - if (! stab_demangle_class (minfo, pp, &hold)) - return false; - if (ptype != NULL) - { - char *name; - - name = savestring (hold, *pp - hold); - *ptype = debug_find_named_type (minfo->dhandle, name); - if (*ptype == DEBUG_TYPE_NULL) - { - /* FIXME: It is probably incorrect to assume that - undefined types are tagged types. */ - *ptype = stab_find_tagged_type (minfo->dhandle, minfo->info, - hold, *pp - hold, - DEBUG_KIND_ILLEGAL); - } - free (name); - } - } - break; - - case 't': - if (! stab_demangle_template (minfo, pp)) - return false; - if (ptype != NULL) - { - debug_type t; - - /* FIXME: I really don't know how a template should be - represented in the current type system. Perhaps the - template should be demangled into a string, and the type - should be represented as a named type. However, I don't - know what the base type of the named type should be. */ - t = debug_make_void_type (minfo->dhandle); - t = debug_make_pointer_type (minfo->dhandle, t); - t = debug_name_type (minfo->dhandle, "TEMPLATE", t); - *ptype = t; - } - break; - - default: - stab_bad_demangle (orig); - return false; - } - - if (ptype != NULL) - { - if (constp) - *ptype = debug_make_const_type (minfo->dhandle, *ptype); - if (volatilep) - *ptype = debug_make_volatile_type (minfo->dhandle, *ptype); - } - - return true; -} - -/* Remember a type string in a demangled string. */ - -static boolean -stab_demangle_remember_type (minfo, p, len) - struct stab_demangle_info *minfo; - const char *p; - int len; -{ - if (minfo->typestring_count >= minfo->typestring_alloc) - { - minfo->typestring_alloc += 10; - minfo->typestrings = ((struct stab_demangle_typestring *) - xrealloc (minfo->typestrings, - (minfo->typestring_alloc - * sizeof *minfo->typestrings))); - } - - minfo->typestrings[minfo->typestring_count].typestring = p; - minfo->typestrings[minfo->typestring_count].len = (unsigned int) len; - ++minfo->typestring_count; - - return true; -} diff --git a/sql/Makefile.am b/sql/Makefile.am index 0b22481f850..40a3565cb91 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -41,7 +41,6 @@ mysqld_DEPENDENCIES= @mysql_plugin_libs@ $(SUPPORTING_LIBS) libndb.la LDADD = $(SUPPORTING_LIBS) @ZLIB_LIBS@ @NDB_SCI_LIBS@ mysqld_LDADD = libndb.la \ @MYSQLD_EXTRA_LDFLAGS@ \ - @pstack_libs@ \ @mysql_plugin_libs@ \ $(LDADD) $(CXXLDFLAGS) $(WRAPLIBS) @LIBDL@ \ $(yassl_libs) $(openssl_libs) @MYSQLD_EXTRA_LIBS@ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index d9c4c7fc3f5..d17ccc47abb 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -70,10 +70,8 @@ #endif /* stack traces are only supported on linux intel */ -#if defined(__linux__) && defined(__i386__) && defined(USE_PSTACK) +#if defined(__linux__) && defined(__i386__) #define HAVE_STACK_TRACE_ON_SEGV -#include "../pstack/pstack.h" -char pstack_file_name[80]; #endif /* __linux__ */ /* We have HAVE_purify below as this speeds up the shutdown of MySQL */ @@ -2779,14 +2777,6 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused))) if (!opt_bootstrap) create_pid_file(); -#ifdef HAVE_STACK_TRACE_ON_SEGV - if (opt_do_pstack) - { - sprintf(pstack_file_name,"mysqld-%lu-%%d-%%d.backtrace", (ulong)getpid()); - pstack_install_segv_action(pstack_file_name); - } -#endif /* HAVE_STACK_TRACE_ON_SEGV */ - /* signal to start_signal_handler that we are ready This works by waiting for start_signal_handler to free mutex, @@ -5963,9 +5953,10 @@ struct my_option my_long_options[] = NO_ARG, 0, 0, 0, 0, 0, 0}, #endif #ifdef HAVE_STACK_TRACE_ON_SEGV - {"enable-pstack", OPT_DO_PSTACK, "Print a symbolic stack trace on failure.", - &opt_do_pstack, &opt_do_pstack, 0, GET_BOOL, NO_ARG, 0, 0, - 0, 0, 0, 0}, + {"enable-pstack", OPT_DO_PSTACK, "Print a symbolic stack trace on failure. " + "This option is deprecated and has no effect; a symbolic stack trace will " + "be printed after a crash whenever possible.", &opt_do_pstack, &opt_do_pstack, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif /* HAVE_STACK_TRACE_ON_SEGV */ {"engine-condition-pushdown", OPT_ENGINE_CONDITION_PUSHDOWN, @@ -8654,6 +8645,13 @@ mysqld_get_one_option(int optid, lower_case_table_names= argument ? atoi(argument) : 1; lower_case_table_names_used= 1; break; +#ifdef HAVE_STACK_TRACE_ON_SEGV + case OPT_DO_PSTACK: + sql_print_warning("'--enable-pstack' is deprecated and will be removed " + "in a future release. A symbolic stack trace will be " + "printed after a crash whenever possible."); + break; +#endif #if defined(ENABLED_DEBUG_SYNC) case OPT_DEBUG_SYNC_TIMEOUT: /* From 51ffca50b6f281cc6d4166b3cc3dfbc47a53ef3c Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 9 Nov 2010 13:59:33 -0200 Subject: [PATCH 203/304] Bug#58080: Crash on failure to create a thread to handle a user connection The problem was that the scheduler function used to handle a new user connection could use the ER() macro without having a THD object bound to the current thread. The crash would happen whenever the function failed to create a new thread to handle a user connection. Thread creation can fail due to lack or limit of available resources. The solution is to simply use the ER_THD() macro instead and pass to it the THD object which would be bound to the connection. Fix was tested manually. In a test case, it is too cumbersome to inject a error in this context. sql/mysqld.cc: Use ER_THD and pass the object. --- sql/mysqld.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 21754b23940..9f5f3d46e67 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4949,7 +4949,7 @@ void create_thread_to_handle_connection(THD *thd) statistic_increment(aborted_connects,&LOCK_status); /* Can't use my_error() since store_globals has not been called. */ my_snprintf(error_message_buff, sizeof(error_message_buff), - ER(ER_CANT_CREATE_THREAD), error); + ER_THD(thd, ER_CANT_CREATE_THREAD), error); net_send_error(thd, ER_CANT_CREATE_THREAD, error_message_buff, NULL); mysql_mutex_lock(&LOCK_thread_count); close_connection(thd,0,0); From 2c16c7e985f772154eb179ac56eabeef405b9443 Mon Sep 17 00:00:00 2001 From: Dmitry Shulga Date: Wed, 10 Nov 2010 11:49:37 +0600 Subject: [PATCH 204/304] Fixed Bug#57386 - main.execution_constants segfault on MIPS64EL. sql/item_func.cc: Item_func::fix_fields modified: increased minimal required stack size in call to check_stack_overrun(). --- sql/item_func.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/sql/item_func.cc b/sql/item_func.cc index eaf6a1b6d14..d8b5d46938e 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -157,7 +157,14 @@ Item_func::fix_fields(THD *thd, Item **ref) used_tables_cache= not_null_tables_cache= 0; const_item_cache=1; - if (check_stack_overrun(thd, STACK_MIN_SIZE, buff)) + /* + Use stack limit of STACK_MIN_SIZE * 2 since + on some platforms a recursive call to fix_fields + requires more than STACK_MIN_SIZE bytes (e.g. for + MIPS, it takes about 22kB to make one recursive + call to Item_func::fix_fields()) + */ + if (check_stack_overrun(thd, STACK_MIN_SIZE * 2, buff)) return TRUE; // Fatal error if flag is set! if (arg_count) { // Print purify happy From 4b0fe8870871c6af340ad0198dfec1c61700853d Mon Sep 17 00:00:00 2001 From: Dmitry Shulga Date: Wed, 10 Nov 2010 14:32:42 +0600 Subject: [PATCH 205/304] Fixed bug#56619 - Assertion failed during ALTER TABLE RENAME, DISABLE KEYS. The code of ALTER TABLE RENAME, DISABLE KEYS could issue a commit while holding LOCK_open mutex. This is a regression introduced by the fix for Bug 54453. This failed an assert guarding us against a potential deadlock with connections trying to execute FLUSH TABLES WITH READ LOCK. The fix is to move acquisition of LOCK_open outside the section that issues ha_autocommit_or_rollback(). LOCK_open is taken to protect against concurrent operations with .frms and the table definition cache, and doesn't need to cover the call to commit. A test case added to innodb_mysql.test. The patch is to be null-merged to 5.5, which already has 54453 null-merged to it. mysql-test/suite/innodb/r/innodb_mysql.result: Added test results for test for bug#56619. mysql-test/suite/innodb/t/innodb_mysql.test: Added test for bug#56619. sql/sql_table.cc: mysql_alter_table() modified: moved acquisition of LOCK_open after call to ha_autocommit_or_rollback. --- mysql-test/suite/innodb/r/innodb_mysql.result | 8 ++++++++ mysql-test/suite/innodb/t/innodb_mysql.test | 13 +++++++++++++ sql/sql_table.cc | 4 +++- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result index 65b7da143a4..6ac3e8e6302 100644 --- a/mysql-test/suite/innodb/r/innodb_mysql.result +++ b/mysql-test/suite/innodb/r/innodb_mysql.result @@ -2620,3 +2620,11 @@ t2 CREATE TABLE `t2` ( CONSTRAINT `x` FOREIGN KEY (`fk`) REFERENCES `t1` (`pk`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 drop table t2, t1; +# +# Test for bug #56619 - Assertion failed during +# ALTER TABLE RENAME, DISABLE KEYS +# +DROP TABLE IF EXISTS t1, t2; +CREATE TABLE t1 (a INT, INDEX(a)) engine=innodb; +ALTER TABLE t1 RENAME TO t2, DISABLE KEYS; +DROP TABLE IF EXISTS t1, t2; diff --git a/mysql-test/suite/innodb/t/innodb_mysql.test b/mysql-test/suite/innodb/t/innodb_mysql.test index 09dc4c9f187..e99c3c27673 100644 --- a/mysql-test/suite/innodb/t/innodb_mysql.test +++ b/mysql-test/suite/innodb/t/innodb_mysql.test @@ -845,3 +845,16 @@ create table t2 (fk int, key x (fk), constraint x foreign key (FK) references t1 (PK)) engine=InnoDB; show create table t2; drop table t2, t1; + +--echo # +--echo # Test for bug #56619 - Assertion failed during +--echo # ALTER TABLE RENAME, DISABLE KEYS +--echo # +--disable_warnings +DROP TABLE IF EXISTS t1, t2; +--enable_warnings +CREATE TABLE t1 (a INT, INDEX(a)) engine=innodb; +--disable_warnings +ALTER TABLE t1 RENAME TO t2, DISABLE KEYS; +DROP TABLE IF EXISTS t1, t2; +--enable_warnings diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 971e1022d63..b919ea9eae7 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -6832,7 +6832,6 @@ view_err: table->alias); } - VOID(pthread_mutex_lock(&LOCK_open)); /* Unlike to the above case close_cached_table() below will remove ALL instances of TABLE from table cache (it will also remove table lock @@ -6853,6 +6852,7 @@ view_err: */ ha_autocommit_or_rollback(thd, 0); + VOID(pthread_mutex_lock(&LOCK_open)); /* Then do a 'simple' rename of the table. First we need to close all instances of 'source' table. @@ -6885,6 +6885,8 @@ view_err: } } } + else + VOID(pthread_mutex_lock(&LOCK_open)); if (error == HA_ERR_WRONG_COMMAND) { From 3fab29461661f677fd5ca0be75fab8bcf84eadff Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Wed, 10 Nov 2010 09:42:14 +0100 Subject: [PATCH 206/304] Bug #57276 mysqltest: add support for simple compares in if/while conditions Added more parsing in do_block() Limitation: left operand must be variable Also changed var_set_int from 57036 to var_check_int Added tests to mysqltest.test Some tests can now be simplified but will take this later Updated after comments, now white space around operator not needed --- client/mysqltest.cc | 145 ++++++++++++++++++++++-- mysql-test/r/mysqltest.result | 32 +++++- mysql-test/t/mysqltest.test | 202 ++++++++++++++++++++++++++++++---- 3 files changed, 343 insertions(+), 36 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 1afed9fa310..1cc275a37be 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -482,7 +482,8 @@ VAR* var_init(VAR* v, const char *name, int name_len, const char *val, int val_len); VAR* var_get(const char *var_name, const char** var_name_end, my_bool raw, my_bool ignore_not_existing); -void eval_expr(VAR* v, const char *p, const char** p_end); +void eval_expr(VAR* v, const char *p, const char** p_end, + bool open_end=false); my_bool match_delimiter(int c, const char *delim, uint length); void dump_result_to_reject_file(char *buf, int size); void dump_warning_messages(); @@ -2040,9 +2041,11 @@ static void var_free(void *v) C_MODE_END -void var_set_int(VAR *v, const char *str) +void var_check_int(VAR *v) { char *endptr; + char *str= v->str_val; + /* Initially assume not a number */ v->int_val= 0; v->is_int= false; @@ -2089,7 +2092,7 @@ VAR *var_init(VAR *v, const char *name, int name_len, const char *val, memcpy(tmp_var->str_val, val, val_len); tmp_var->str_val[val_len]= 0; } - var_set_int(tmp_var, val); + var_check_int(tmp_var); tmp_var->name_len = name_len; tmp_var->str_val_len = val_len; tmp_var->alloced_len = val_alloc_len; @@ -2540,7 +2543,7 @@ void var_copy(VAR *dest, VAR *src) } -void eval_expr(VAR *v, const char *p, const char **p_end) +void eval_expr(VAR *v, const char *p, const char **p_end, bool open_end) { DBUG_ENTER("eval_expr"); @@ -2558,7 +2561,7 @@ void eval_expr(VAR *v, const char *p, const char **p_end) /* Make sure there was just a $variable and nothing else */ const char* end= *p_end + 1; - if (end < expected_end) + if (end < expected_end && !open_end) die("Found junk '%.*s' after $variable in expression", (int)(expected_end - end - 1), end); @@ -2605,7 +2608,7 @@ void eval_expr(VAR *v, const char *p, const char **p_end) v->str_val_len = new_val_len; memcpy(v->str_val, p, new_val_len); v->str_val[new_val_len] = 0; - var_set_int(v, p); + var_check_int(v); } DBUG_VOID_RETURN; } @@ -5498,6 +5501,40 @@ int do_done(struct st_command *command) return 0; } +/* Operands available in if or while conditions */ + +enum block_op { + EQ_OP, + NE_OP, + GT_OP, + GE_OP, + LT_OP, + LE_OP, + ILLEG_OP +}; + + +enum block_op find_operand(const char *start) +{ + char first= *start; + char next= *(start+1); + + if (first == '=' && next == '=') + return EQ_OP; + if (first == '!' && next == '=') + return NE_OP; + if (first == '>' && next == '=') + return GE_OP; + if (first == '>') + return GT_OP; + if (first == '<' && next == '=') + return LE_OP; + if (first == '<') + return LT_OP; + + return ILLEG_OP; +} + /* Process start of a "if" or "while" statement @@ -5523,6 +5560,13 @@ int do_done(struct st_command *command) A '!' can be used before the to indicate it should be executed if it evaluates to zero. + can also be a simple comparison condition: + + + + The left hand side must be a variable, the right hand side can be a + variable, number, string or `query`. Operands are ==, !=, <, <=, >, >=. + == and != can be used for strings, all can be used for numerical values. */ void do_block(enum block_cmd cmd, struct st_command* command) @@ -5558,6 +5602,9 @@ void do_block(enum block_cmd cmd, struct st_command* command) if (!expr_start++) die("missing '(' in %s", cmd_name); + while (my_isspace(charset_info, *expr_start)) + expr_start++; + /* Check for ! */ if (*expr_start == '!') { @@ -5576,14 +5623,94 @@ void do_block(enum block_cmd cmd, struct st_command* command) die("Missing '{' after %s. Found \"%s\"", cmd_name, p); var_init(&v,0,0,0,0); - eval_expr(&v, expr_start, &expr_end); + /* If expression starts with a variable, it may be a compare condition */ + + if (*expr_start == '$') + { + const char *curr_ptr= expr_end; + eval_expr(&v, expr_start, &curr_ptr, true); + while (my_isspace(charset_info, *++curr_ptr)) + {} + /* If there was nothing past the variable, skip condition part */ + if (curr_ptr == expr_end) + goto NO_COMPARE; + + enum block_op operand= find_operand(curr_ptr); + if (operand == ILLEG_OP) + die("Found junk '%.*s' after $variable in condition", + (int)(expr_end - curr_ptr), curr_ptr); + + /* We could silently allow this, but may be confusing */ + if (not_expr) + die("Negation and comparison should not be combined, please rewrite"); + + /* Skip the 1 or 2 chars of the operand, then white space */ + if (operand == LT_OP || operand == GT_OP) + { + curr_ptr++; + } + else + { + curr_ptr+= 2; + } + while (my_isspace(charset_info, *curr_ptr)) + curr_ptr++; + + VAR v2; + var_init(&v2,0,0,0,0); + eval_expr(&v2, curr_ptr, &expr_end); + + if ((operand!=EQ_OP && operand!=NE_OP) && ! (v.is_int && v2.is_int)) + die ("Only == and != are supported for string values"); + + /* Now we overwrite the first variable with 0 or 1 (for false or true) */ + + switch (operand) + { + case EQ_OP: + if (v.is_int) + v.int_val= (v2.is_int && v2.int_val == v.int_val); + else + v.int_val= !strcmp (v.str_val, v2.str_val); + break; + + case NE_OP: + if (v.is_int) + v.int_val= ! (v2.is_int && v2.int_val == v.int_val); + else + v.int_val= (strcmp (v.str_val, v2.str_val) != 0); + break; + + case LT_OP: + v.int_val= (v.int_val < v2.int_val); + break; + case LE_OP: + v.int_val= (v.int_val <= v2.int_val); + break; + case GT_OP: + v.int_val= (v.int_val > v2.int_val); + break; + case GE_OP: + v.int_val= (v.int_val >= v2.int_val); + break; + } + + v.is_int= TRUE; + } else + { + if (*expr_start != '`' && ! my_isdigit(charset_info, *expr_start)) + die("Expression in if/while must beging with $, ` or a number"); + eval_expr(&v, expr_start, &expr_end); + } + + NO_COMPARE: /* Define inner block */ cur_block++; cur_block->cmd= cmd; - if (v.int_val) + if (v.is_int) { - cur_block->ok= TRUE; + cur_block->ok= (v.int_val != 0); } else /* Any non-empty string which does not begin with 0 is also TRUE */ { diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index cff845a2819..c4bf83db31a 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -401,8 +401,36 @@ true-outer Counter is greater than 0, (counter=10) Counter is not 0, (counter=0) Counter is true, (counter=alpha) -Beta is true while with string, only once +5<7 +5<7 again +5<7 still +5<6 +5>=5 +5>=5 again +5>3 +5==5 +5!=8 +5!=five +5==3+2 +5 == 5 +hello == hello +hello == hello +hello != goodbye +two words +two words are two words +right answer +anything goes +0 != string +mysqltest: At line 2: Only == and != are supported for string values +mysqltest: At line 2: Found junk '~= 6' after $variable in condition +mysqltest: At line 2: Expression in if/while must beging with $, ` or a number +counter is 2 +counter is 3 +counter is 4 +counter is 5 +counter is 6 +counter is 7 1 Testing while with not mysqltest: In included file "MYSQLTEST_VARDIR/tmp/mysqltest_while.inc": At line 64: Nesting too deeply @@ -807,8 +835,6 @@ dir-list.txt SELECT 'c:\\a.txt' AS col; col z -hej -mysqltest: At line 1: Found junk ' != 143' after $variable in expression select 1; 1 1 diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index 8fb05e52cdc..9b8a45d6a87 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -1163,10 +1163,11 @@ if ($counter) { echo oops, -0 is true; } -if (beta) -{ - echo Beta is true; -} +# This is no longer allowed, as a precaution against mistyped conditionals +# if (beta) +# { +# echo Beta is true; +# } let $counter=gamma; while ($counter) { @@ -1174,6 +1175,179 @@ while ($counter) let $counter=000; } +# ---------------------------------------------------------------------------- +# Test if with compare conditions +# ---------------------------------------------------------------------------- + +let $ifvar= 5; +let $ifvar2= 6; + +if ($ifvar < 7) +{ + echo 5<7; +} +if ($ifvar< 7) +{ + echo 5<7 again; +} +if ($ifvar<7) +{ + echo 5<7 still; +} +if ($ifvar < $ifvar2) +{ + echo 5<6; +} +if ($ifvar <= 4) +{ + echo 5<=4; +} +if ($ifvar >= 5) +{ + echo 5>=5; +} +if ($ifvar>=5) +{ + echo 5>=5 again; +} +if ($ifvar > 3) +{ + echo 5>3; +} +if ($ifvar == 4) +{ + echo 5==4; +} +if ($ifvar == 5) +{ + echo 5==5; +} +if ($ifvar != 8) +{ + echo 5!=8; +} +# Any number should compare unequal to any string +if ($ifvar != five) +{ + echo 5!=five; +} +if ($ifvar == `SELECT 3+2`) +{ + echo 5==3+2; +} +if ($ifvar == 5) +{ + echo 5 == 5; +} +let $ifvar= hello; +if ($ifvar == hello there) +{ + echo hello == hello there; +} +if ($ifvar == hello) +{ + echo hello == hello; +} +if ($ifvar == hell) +{ + echo hello == hell; +} +if ($ifvar == hello) +{ + echo hello == hello; +} +if ($ifvar != goodbye) +{ + echo hello != goodbye; +} + +let $ifvar= two words; +if ($ifvar == two words) +{ + echo two words; +} +if ($ifvar == `SELECT 'two words'`) +{ + echo two words are two words; +} +if (42) +{ + echo right answer; +} +if (0) +{ + echo wrong answer; +} +# Non-empty string treated as 'true' +if (`SELECT 'something'`) +{ + echo anything goes; +} +# Make sure 0 and string compare right +let $ifvar= 0; +if ($ifvar == string) +{ + echo 0 == string; +} +if ($ifvar != string) +{ + echo 0 != string; +} +--write_file $MYSQL_TMP_DIR/mysqltest.sql +let $var= 5; +if ($var >= four) +{ + echo 5>=four; +} +EOF +--error 1 +--exec $MYSQL_TEST < $MYSQL_TMP_DIR/mysqltest.sql 2>&1 +remove_file $MYSQL_TMP_DIR/mysqltest.sql; + +--write_file $MYSQL_TMP_DIR/mysqltest.sql +let $var= 5; +if ($var ~= 6) +{ + echo 5~=6; +} +EOF +--error 1 +--exec $MYSQL_TEST < $MYSQL_TMP_DIR/mysqltest.sql 2>&1 +remove_file $MYSQL_TMP_DIR/mysqltest.sql; + +--write_file $MYSQL_TMP_DIR/mysqltest.sql +let $var= text; +if (var == text) +{ + echo Oops I forgot the $; +} +EOF +--error 1 +--exec $MYSQL_TEST < $MYSQL_TMP_DIR/mysqltest.sql 2>&1 +remove_file $MYSQL_TMP_DIR/mysqltest.sql; + +# ---------------------------------------------------------------------------- +# Test while with compare conditions +# ---------------------------------------------------------------------------- + +let $counter= 2; + +while ($counter < 5) +{ + echo counter is $counter; + inc $counter; +} +let $ifvar=; +while ($ifvar != stop) +{ + if ($counter >= 7) + { + let $ifvar= stop; + } + echo counter is $counter; + inc $counter; +} + # ---------------------------------------------------------------------------- # Test while, { and } # ---------------------------------------------------------------------------- @@ -2529,26 +2703,6 @@ rmdir $MYSQLTEST_VARDIR/tmp/testdir; --replace_result c:\\a.txt z SELECT 'c:\\a.txt' AS col; -# -# Bug#32307 mysqltest - does not detect illegal if syntax -# - -let $test= 1; -if ($test){ - echo hej; -} - ---write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql -if ($mysql_errno != 1436) -{ - echo ^ Should not be allowed! -} -EOF ---error 1 ---exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1 -remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql; - - # ---------------------------------------------------------------------------- # Test that -- is not allowed as comment, only as mysqltest builtin command # ---------------------------------------------------------------------------- From bb356127a3f2095cebec63f50205682bdf765e64 Mon Sep 17 00:00:00 2001 From: Oystein Grovlen Date: Wed, 10 Nov 2010 15:48:29 +0100 Subject: [PATCH 207/304] Bug#57704 Cleanup code dies with void TABLE::set_keyread(bool): Assertion `file' failed. This bug was introduced in this revision: kostja@sun.com-20100727102553-b4n2ojcyfj79l2x7 ("A pre-requisite patch for the fix for Bug#52044.") It happens because close_thread_tables() is now called in open_and_lock_tables upon failure. Hence, table is no longer open when optimizer tries to do cleanup. Fix: Make sure to do cleanup in st_select_lex_unit::prepare() upon failure. This way, cleanup() is called before tables are released. mysql-test/r/subselect.result: Added test case for Bug#57704. mysql-test/t/subselect.test: Added test case for Bug#57704. sql/sql_union.cc: st_select_lex_unit::prepare(): On failure, make sure cleanup() is called. --- mysql-test/r/subselect.result | 12 ++++++++++++ mysql-test/t/subselect.test | 18 ++++++++++++++++++ sql/sql_union.cc | 1 + 3 files changed, 31 insertions(+) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 13941b56040..3136b5dfcc0 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -5005,3 +5005,15 @@ SELECT * FROM t2 UNION SELECT * FROM t2 ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE)); DROP TABLE t1,t2; End of 5.1 tests +# +# Bug #57704: Cleanup code dies with void TABLE::set_keyread(bool): +# Assertion `file' failed. +# +CREATE TABLE t1 (a INT); +SELECT 1 FROM +(SELECT ROW( +(SELECT 1 FROM t1 RIGHT JOIN +(SELECT 1 FROM t1, t1 t2) AS d ON 1), +1) FROM t1) AS e; +ERROR 21000: Operand should contain 1 column(s) +DROP TABLE t1; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 2e442e7f897..d4a995ee181 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -3946,3 +3946,21 @@ DROP TABLE t1,t2; --enable_result_log --echo End of 5.1 tests + +--echo # +--echo # Bug #57704: Cleanup code dies with void TABLE::set_keyread(bool): +--echo # Assertion `file' failed. +--echo # + +CREATE TABLE t1 (a INT); + +--error ER_OPERAND_COLUMNS +SELECT 1 FROM + (SELECT ROW( + (SELECT 1 FROM t1 RIGHT JOIN + (SELECT 1 FROM t1, t1 t2) AS d ON 1), + 1) FROM t1) AS e; + +DROP TABLE t1; + + diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 98f20e09949..1c0c48c0fec 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -434,6 +434,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, err: thd_arg->lex->current_select= lex_select_save; + (void) cleanup(); DBUG_RETURN(TRUE); } From 236affe7f96baa02dfaffa2579c95562bd1cf8a5 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 10 Nov 2010 17:21:51 +0200 Subject: [PATCH 208/304] Bug #57744: sql-common/client.c: Missing DBUG_RETURN macro - added missing DBUG_RETURN - fixed whitespace according to coding style. --- sql-common/client.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/sql-common/client.c b/sql-common/client.c index e8ca74eba37..3bb626e824a 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -4197,7 +4197,7 @@ static int native_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) int pkt_len; uchar *pkt; - DBUG_ENTER ("native_password_auth_client"); + DBUG_ENTER("native_password_auth_client"); if (((MCPVIO_EXT *)vio)->mysql_change_user) @@ -4213,10 +4213,10 @@ static int native_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) { /* read the scramble */ if ((pkt_len= vio->read_packet(vio, &pkt)) < 0) - return CR_ERROR; + DBUG_RETURN(CR_ERROR); if (pkt_len != SCRAMBLE_LENGTH + 1) - DBUG_RETURN (CR_SERVER_HANDSHAKE_ERR); + DBUG_RETURN(CR_SERVER_HANDSHAKE_ERR); /* save it in MYSQL */ memcpy(mysql->scramble, pkt, SCRAMBLE_LENGTH); @@ -4226,19 +4226,19 @@ static int native_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) if (mysql->passwd[0]) { char scrambled[SCRAMBLE_LENGTH + 1]; - DBUG_PRINT ("info", ("sending scramble")); + DBUG_PRINT("info", ("sending scramble")); scramble(scrambled, (char*)pkt, mysql->passwd); if (vio->write_packet(vio, (uchar*)scrambled, SCRAMBLE_LENGTH)) - DBUG_RETURN (CR_ERROR); + DBUG_RETURN(CR_ERROR); } else { - DBUG_PRINT ("info", ("no password")); + DBUG_PRINT("info", ("no password")); if (vio->write_packet(vio, 0, 0)) /* no password */ - DBUG_RETURN (CR_ERROR); + DBUG_RETURN(CR_ERROR); } - DBUG_RETURN (CR_OK); + DBUG_RETURN(CR_OK); } /** @@ -4250,7 +4250,7 @@ static int old_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) uchar *pkt; int pkt_len; - DBUG_ENTER ("old_password_auth_client"); + DBUG_ENTER("old_password_auth_client"); if (((MCPVIO_EXT *)vio)->mysql_change_user) { @@ -4265,11 +4265,11 @@ static int old_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) { /* read the scramble */ if ((pkt_len= vio->read_packet(vio, &pkt)) < 0) - return CR_ERROR; + DBUG_RETURN(CR_ERROR); if (pkt_len != SCRAMBLE_LENGTH_323 + 1 && pkt_len != SCRAMBLE_LENGTH + 1) - DBUG_RETURN (CR_SERVER_HANDSHAKE_ERR); + DBUG_RETURN(CR_SERVER_HANDSHAKE_ERR); /* save it in MYSQL */ memcpy(mysql->scramble, pkt, pkt_len); @@ -4281,11 +4281,11 @@ static int old_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) char scrambled[SCRAMBLE_LENGTH_323 + 1]; scramble_323(scrambled, (char*)pkt, mysql->passwd); if (vio->write_packet(vio, (uchar*)scrambled, SCRAMBLE_LENGTH_323 + 1)) - DBUG_RETURN (CR_ERROR); + DBUG_RETURN(CR_ERROR); } else if (vio->write_packet(vio, 0, 0)) /* no password */ - DBUG_RETURN (CR_ERROR); + DBUG_RETURN(CR_ERROR); - DBUG_RETURN (CR_OK); + DBUG_RETURN(CR_OK); } From 7fa9b1e6c05174e16c121550b8ccfce17a2fba02 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 10 Nov 2010 17:55:57 +0200 Subject: [PATCH 209/304] removed misleading and over-promissing comments. --- include/mysql/client_plugin.h | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/include/mysql/client_plugin.h b/include/mysql/client_plugin.h index d9c0dd02008..cc3f468040f 100644 --- a/include/mysql/client_plugin.h +++ b/include/mysql/client_plugin.h @@ -79,8 +79,7 @@ struct st_mysql_client_plugin_AUTHENTICATION /** loads a plugin and initializes it - @param mysql MYSQL structure. only MYSQL_PLUGIN_DIR option value is used, - and last_errno/last_error, for error reporting + @param mysql MYSQL structure. @param name a name of the plugin to load @param type type of plugin that should be loaded, -1 to disable type check @param argc number of arguments to pass to the plugin initialization @@ -100,8 +99,7 @@ mysql_load_plugin(struct st_mysql *mysql, const char *name, int type, This is the same as mysql_load_plugin, but take va_list instead of a list of arguments. - @param mysql MYSQL structure. only MYSQL_PLUGIN_DIR option value is used, - and last_errno/last_error, for error reporting + @param mysql MYSQL structure. @param name a name of the plugin to load @param type type of plugin that should be loaded, -1 to disable type check @param argc number of arguments to pass to the plugin initialization @@ -118,8 +116,7 @@ mysql_load_plugin_v(struct st_mysql *mysql, const char *name, int type, /** finds an already loaded plugin by name, or loads it, if necessary - @param mysql MYSQL structure. only MYSQL_PLUGIN_DIR option value is used, - and last_errno/last_error, for error reporting + @param mysql MYSQL structure. @param name a name of the plugin to load @param type type of plugin that should be loaded From 2e2f3b1fc1eaa18cae707086ad3b8848021b6b25 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Wed, 10 Nov 2010 20:10:04 +0100 Subject: [PATCH 210/304] Fix typo : SVR5=>SVR4 --- cmake/install_layout.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/install_layout.cmake b/cmake/install_layout.cmake index fcc1a2054b1..19a8a61df2d 100644 --- a/cmake/install_layout.cmake +++ b/cmake/install_layout.cmake @@ -86,7 +86,7 @@ IF(UNIX) SET(CMAKE_INSTALL_PREFIX ${default_prefix} CACHE PATH "install prefix" FORCE) ENDIF() - SET(VALID_INSTALL_LAYOUTS "RPM" "STANDALONE" "DEB" "SVR5") + SET(VALID_INSTALL_LAYOUTS "RPM" "STANDALONE" "DEB" "SVR4") LIST(FIND VALID_INSTALL_LAYOUTS "${INSTALL_LAYOUT}" ind) IF(ind EQUAL -1) MESSAGE(FATAL_ERROR "Invalid INSTALL_LAYOUT parameter:${INSTALL_LAYOUT}." From cd1c6e220de1730615c145b5337f7cce554dfdae Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Wed, 10 Nov 2010 19:14:47 -0200 Subject: [PATCH 211/304] Bug#58057: 5.1 libmysql/libmysql.c unused variable/compile failure Bug#57995: Compiler flag change build error on OSX 10.4: my_getncpus.c Bug#57996: Compiler flag change build error on OSX 10.5 : bind.c Bug#57994: Compiler flag change build error : my_redel.c Bug#57993: Compiler flag change build error on FreeBsd 7.0 : regexec.c Bug#57992: Compiler flag change build error on FreeBsd : mf_keycache.c Bug#57997: Compiler flag change build error on OSX 10.6: debug_sync.cc Fix assorted compiler generated warnings. cmd-line-utils/readline/bind.c: Bug#57996: Compiler flag change build error on OSX 10.5 : bind.c Initialize variable to work around a false positive warning. include/m_string.h: Bug#57994: Compiler flag change build error : my_redel.c The expansion of stpcpy (in glibc) causes warnings if the return value of strmov is not being used. Since stpcpy is a GNU extension and the expansion ends up using a built-in provided by GCC, use the compiler provided built-in directly when possible. include/my_compiler.h: Define a dummy MY_GNUC_PREREQ when not compiling with GCC. libmysql/libmysql.c: Bug#58057: 5.1 libmysql/libmysql.c unused variable/compile failure Variable might not be used in some cases. So, tag it as unused. mysys/mf_keycache.c: Bug#57992: Compiler flag change build error on FreeBsd : mf_keycache.c Use UNINIT_VAR to work around a false positive warning. mysys/my_getncpus.c: Bug#57995: Compiler flag change build error on OSX 10.4: my_getncpus.c Declare variable in the same block where it is used. regex/regexec.c: Bug#57993: Compiler flag change build error on FreeBsd 7.0 : regexec.c Work around a compiler bug which causes the cast to not be enforced. sql/debug_sync.cc: Bug#57997: Compiler flag change build error on OSX 10.6: debug_sync.cc Use UNINIT_VAR to work around a false positive warning. sql/handler.cc: Use UNINIT_VAR to work around a false positive warning. sql/slave.cc: Use UNINIT_VAR to work around a false positive warning. sql/sql_partition.cc: Use UNINIT_VAR to work around a false positive warning. storage/myisam/ft_nlq_search.c: Use UNINIT_VAR to work around a false positive warning. storage/myisam/mi_create.c: Use UNINIT_VAR to work around a false positive warning. storage/myisammrg/myrg_open.c: Use UNINIT_VAR to work around a false positive warning. tests/mysql_client_test.c: Change function to take a pointer to const, no need for a cast. --- cmd-line-utils/readline/bind.c | 2 +- include/m_string.h | 4 +++- include/my_compiler.h | 5 +++++ libmysql/libmysql.c | 4 ++-- mysys/mf_keycache.c | 10 +++++----- mysys/my_getncpus.c | 3 ++- regex/regexec.c | 5 +++-- sql/debug_sync.cc | 2 +- sql/handler.cc | 2 +- sql/slave.cc | 2 +- sql/sql_partition.cc | 4 ++-- storage/myisam/ft_nlq_search.c | 2 +- storage/myisam/mi_create.c | 4 +--- storage/myisammrg/myrg_open.c | 2 +- tests/mysql_client_test.c | 6 +++--- 15 files changed, 32 insertions(+), 25 deletions(-) diff --git a/cmd-line-utils/readline/bind.c b/cmd-line-utils/readline/bind.c index c669322f436..0ea8b1ca126 100644 --- a/cmd-line-utils/readline/bind.c +++ b/cmd-line-utils/readline/bind.c @@ -855,7 +855,7 @@ _rl_read_init_file (filename, include_level) { register int i; char *buffer, *openname, *line, *end; - size_t file_size; + size_t file_size = 0; current_readline_init_file = filename; current_readline_init_include_level = include_level; diff --git a/include/m_string.h b/include/m_string.h index 3e5cd063b7b..933da84c336 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -73,7 +73,9 @@ extern "C" { extern void *(*my_str_malloc)(size_t); extern void (*my_str_free)(void *); -#if defined(HAVE_STPCPY) +#if MY_GNUC_PREREQ(3, 4) +#define strmov(dest, src) __builtin_stpcpy(dest, src) +#elif defined(HAVE_STPCPY) #define strmov(A,B) stpcpy((A),(B)) #ifndef stpcpy extern char *stpcpy(char *, const char *); /* For AIX with gcc 2.95.3 */ diff --git a/include/my_compiler.h b/include/my_compiler.h index c7d334999d0..5f898621159 100644 --- a/include/my_compiler.h +++ b/include/my_compiler.h @@ -76,6 +76,11 @@ /** Generic (compiler-independent) features. */ + +#ifndef MY_GNUC_PREREQ +# define MY_GNUC_PREREQ(maj, min) (0) +#endif + #ifndef MY_ALIGNOF # ifdef __cplusplus template struct my_alignof_helper { char m1; type m2; }; diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 8c612b6894e..deb7cd10d2a 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -131,8 +131,8 @@ int STDCALL mysql_server_init(int argc __attribute__((unused)), mysql_port = MYSQL_PORT; #ifndef MSDOS { - struct servent *serv_ptr; - char *env; + char *env; + struct servent *serv_ptr __attribute__((unused)); /* if builder specifically requested a default port, use that diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c index 8042dc2828b..b7faf7c1b95 100644 --- a/mysys/mf_keycache.c +++ b/mysys/mf_keycache.c @@ -3917,11 +3917,11 @@ restart: if (!(block->status & (BLOCK_IN_EVICTION | BLOCK_IN_SWITCH | BLOCK_REASSIGNED))) { - struct st_hash_link *next_hash_link; - my_off_t next_diskpos; - File next_file; - uint next_status; - uint hash_requests; + struct st_hash_link *UNINIT_VAR(next_hash_link); + my_off_t UNINIT_VAR(next_diskpos); + File UNINIT_VAR(next_file); + uint UNINIT_VAR(next_status); + uint UNINIT_VAR(hash_requests); total_found++; found++; diff --git a/mysys/my_getncpus.c b/mysys/my_getncpus.c index 82e87dee2e4..f9db6603924 100644 --- a/mysys/my_getncpus.c +++ b/mysys/my_getncpus.c @@ -18,9 +18,10 @@ #include "mysys_priv.h" #include +#ifdef _SC_NPROCESSORS_ONLN + static int ncpus=0; -#ifdef _SC_NPROCESSORS_ONLN int my_getncpus() { if (!ncpus) diff --git a/regex/regexec.c b/regex/regexec.c index 338c1bfa7fe..c0d03335b41 100644 --- a/regex/regexec.c +++ b/regex/regexec.c @@ -117,6 +117,7 @@ size_t nmatch; my_regmatch_t pmatch[]; int eflags; { + char *pstr = (char *) str; register struct re_guts *g = preg->re_g; #ifdef REDEBUG # define GOODFLAGS(f) (f) @@ -133,7 +134,7 @@ int eflags; if ((size_t) g->nstates <= CHAR_BIT*sizeof(states1) && !(eflags®_LARGE)) - return(smatcher(preg->charset, g, (char *)str, nmatch, pmatch, eflags)); + return(smatcher(preg->charset, g, pstr, nmatch, pmatch, eflags)); else - return(lmatcher(preg->charset, g, (char *)str, nmatch, pmatch, eflags)); + return(lmatcher(preg->charset, g, pstr, nmatch, pmatch, eflags)); } diff --git a/sql/debug_sync.cc b/sql/debug_sync.cc index 23a649a89fa..91c850c6009 100644 --- a/sql/debug_sync.cc +++ b/sql/debug_sync.cc @@ -1718,7 +1718,7 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action) if (action->execute) { - const char *old_proc_info; + const char *UNINIT_VAR(old_proc_info); action->execute--; diff --git a/sql/handler.cc b/sql/handler.cc index a47a5fd8a3c..1525ca53bca 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -4141,7 +4141,7 @@ int handler::read_multi_range_first(KEY_MULTI_RANGE **found_range_p, */ int handler::read_multi_range_next(KEY_MULTI_RANGE **found_range_p) { - int result; + int UNINIT_VAR(result); DBUG_ENTER("handler::read_multi_range_next"); /* We should not be called after the last call returned EOF. */ diff --git a/sql/slave.cc b/sql/slave.cc index 57d673ea1f4..644aade517c 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2321,7 +2321,7 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli) if (slave_trans_retries) { - int temp_err; + int UNINIT_VAR(temp_err); if (exec_res && (temp_err= has_temporary_error(thd))) { const char *errmsg; diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 702c3d99fda..44ed9e759c6 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -6747,8 +6747,8 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info, { DBUG_ASSERT(!is_subpart); Field *field= part_info->part_field_array[0]; - uint32 max_endpoint_val; - get_endpoint_func get_endpoint; + uint32 UNINIT_VAR(max_endpoint_val); + get_endpoint_func UNINIT_VAR(get_endpoint); bool can_match_multiple_values; /* is not '=' */ uint field_len= field->pack_length_in_rec(); part_iter->ret_null_part= part_iter->ret_null_part_orig= FALSE; diff --git a/storage/myisam/ft_nlq_search.c b/storage/myisam/ft_nlq_search.c index 5317da78ee4..e185514b9c1 100644 --- a/storage/myisam/ft_nlq_search.c +++ b/storage/myisam/ft_nlq_search.c @@ -63,7 +63,7 @@ static int FT_SUPERDOC_cmp(void* cmp_arg __attribute__((unused)), static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio) { - int subkeys, r; + int UNINIT_VAR(subkeys), r; uint keylen, doc_cnt; FT_SUPERDOC sdoc, *sptr; TREE_ELEMENT *selem; diff --git a/storage/myisam/mi_create.c b/storage/myisam/mi_create.c index 0b4d781379c..42bd8e26a94 100644 --- a/storage/myisam/mi_create.c +++ b/storage/myisam/mi_create.c @@ -38,7 +38,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, MI_CREATE_INFO *ci,uint flags) { register uint i,j; - File UNINIT_VAR(dfile),file; + File UNINIT_VAR(dfile), UNINIT_VAR(file); int errpos,save_errno, create_mode= O_RDWR | O_TRUNC; myf create_flag; uint fields,length,max_key_length,packed,pointer,real_length_diff, @@ -73,8 +73,6 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, { DBUG_RETURN(my_errno=HA_WRONG_CREATE_OPTION); } - LINT_INIT(dfile); - LINT_INIT(file); errpos=0; options=0; bzero((uchar*) &share,sizeof(share)); diff --git a/storage/myisammrg/myrg_open.c b/storage/myisammrg/myrg_open.c index 18f8aa8d2c0..4bc3f7a4018 100644 --- a/storage/myisammrg/myrg_open.c +++ b/storage/myisammrg/myrg_open.c @@ -221,7 +221,7 @@ MYRG_INFO *myrg_parent_open(const char *parent_name, int (*callback)(void*, const char*), void *callback_param) { - MYRG_INFO *m_info; + MYRG_INFO *UNINIT_VAR(m_info); int rc; int errpos; int save_errno; diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 3bfcf3ee233..ed8031b3fc3 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -1175,7 +1175,7 @@ my_bool fetch_n(const char **query_list, unsigned query_count, /* Separate thread query to test some cases */ -static my_bool thread_query(char *query) +static my_bool thread_query(const char *query) { MYSQL *l_mysql; my_bool error; @@ -1197,7 +1197,7 @@ static my_bool thread_query(char *query) goto end; } l_mysql->reconnect= 1; - if (mysql_query(l_mysql, (char *)query)) + if (mysql_query(l_mysql, query)) { fprintf(stderr, "Query failed (%s)\n", mysql_error(l_mysql)); error= 1; @@ -5821,7 +5821,7 @@ static void test_prepare_alter() rc= mysql_stmt_execute(stmt); check_execute(stmt, rc); - if (thread_query((char *)"ALTER TABLE test_prep_alter change id id_new varchar(20)")) + if (thread_query("ALTER TABLE test_prep_alter change id id_new varchar(20)")) exit(1); is_null= 1; From 871f36357e696d12cc4a360a8c36d7be61516ac6 Mon Sep 17 00:00:00 2001 From: Dmitry Shulga Date: Thu, 11 Nov 2010 10:52:51 +0600 Subject: [PATCH 212/304] Fixed bug#54375 - Error in stored procedure leaves connection in different default schema. In strict mode, when data truncation or conversion happens, THD::killed is set to THD::KILL_BAD_DATA. This is abuse of KILL mechanism to guarantee that execution of statement is aborted. The stored procedures execution, on the other hand, upon detection that a connection was killed, would terminate immediately, without trying to restore the caller's context, in particular, restore the caller's current schema. The fix is, when terminating a stored procedure execution, to only bypass cleanup if the entire connection was killed, not in case of other forms of KILL. mysql-test/r/sp-bugs.result: Added result for a test case for bug#54375. mysql-test/t/sp-bugs.test: Added test case for bug#54375. sql/sp_head.cc: sp_head::execute modified: restore saved current db if connection is not killed. --- mysql-test/r/sp-bugs.result | 36 ++++++++++++++++++++++++++++++++++++ mysql-test/t/sp-bugs.test | 37 +++++++++++++++++++++++++++++++++++++ sql/sp_head.cc | 2 +- 3 files changed, 74 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/sp-bugs.result b/mysql-test/r/sp-bugs.result index 2374b433fba..507c73c2683 100644 --- a/mysql-test/r/sp-bugs.result +++ b/mysql-test/r/sp-bugs.result @@ -73,4 +73,40 @@ CALL p1 (); ERROR HY000: Trigger does not exist DROP TABLE t1; DROP PROCEDURE p1; +# +# Bug#54375: Error in stored procedure leaves connection +# in different default schema +# +SET @@SQL_MODE = 'STRICT_ALL_TABLES'; +DROP DATABASE IF EXISTS db1; +CREATE DATABASE db1; +USE db1; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (c1 int NOT NULL PRIMARY KEY); +INSERT INTO t1 VALUES (1); +CREATE FUNCTION f1 ( +some_value int +) +RETURNS smallint +DETERMINISTIC +BEGIN +INSERT INTO t1 SET c1 = some_value; +RETURN(LAST_INSERT_ID()); +END$$ +DROP DATABASE IF EXISTS db2; +CREATE DATABASE db2; +USE db2; +SELECT DATABASE(); +DATABASE() +db2 +SELECT db1.f1(1); +ERROR 23000: Duplicate entry '1' for key 'PRIMARY' +SELECT DATABASE(); +DATABASE() +db2 +USE test; +DROP FUNCTION db1.f1; +DROP TABLE db1.t1; +DROP DATABASE db1; +DROP DATABASE db2; End of 5.1 tests diff --git a/mysql-test/t/sp-bugs.test b/mysql-test/t/sp-bugs.test index 8aa0791e265..fe52632c784 100644 --- a/mysql-test/t/sp-bugs.test +++ b/mysql-test/t/sp-bugs.test @@ -101,4 +101,41 @@ CALL p1 (); DROP TABLE t1; DROP PROCEDURE p1; +--echo # +--echo # Bug#54375: Error in stored procedure leaves connection +--echo # in different default schema +--echo # + +--disable_warnings +SET @@SQL_MODE = 'STRICT_ALL_TABLES'; +DROP DATABASE IF EXISTS db1; +CREATE DATABASE db1; +USE db1; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (c1 int NOT NULL PRIMARY KEY); +INSERT INTO t1 VALUES (1); +DELIMITER $$; +CREATE FUNCTION f1 ( + some_value int +) +RETURNS smallint +DETERMINISTIC +BEGIN + INSERT INTO t1 SET c1 = some_value; + RETURN(LAST_INSERT_ID()); +END$$ +DELIMITER ;$$ +DROP DATABASE IF EXISTS db2; +CREATE DATABASE db2; +--enable_warnings +USE db2; +SELECT DATABASE(); +--error ER_DUP_ENTRY +SELECT db1.f1(1); +SELECT DATABASE(); +USE test; +DROP FUNCTION db1.f1; +DROP TABLE db1.t1; +DROP DATABASE db1; +DROP DATABASE db2; --echo End of 5.1 tests diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 66d5eff5112..2473abea3c7 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1372,7 +1372,7 @@ sp_head::execute(THD *thd) If the DB has changed, the pointer has changed too, but the original thd->db will then have been freed */ - if (cur_db_changed && !thd->killed) + if (cur_db_changed && thd->killed != THD::KILL_CONNECTION) { /* Force switching back to the saved current database, because it may be From 7ade161589cd1f7c6c245a3e6b2b297fcd828f04 Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Wed, 10 Nov 2010 21:27:10 -0800 Subject: [PATCH 213/304] Port fix for Bug #48026 to 5.1 built-in and plugin: Log start and end of InnoDB buffer pool initialization to the error log --- storage/innobase/srv/srv0start.c | 22 ++++++++++++++++++++++ storage/innodb_plugin/ChangeLog | 6 ++++++ storage/innodb_plugin/srv/srv0start.c | 20 ++++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c index 9d057110d11..4c4360f819e 100644 --- a/storage/innobase/srv/srv0start.c +++ b/storage/innobase/srv/srv0start.c @@ -1247,6 +1247,23 @@ innobase_start_or_create_for_mysql(void) fil_init(srv_max_n_open_files); + /* Print time to initialize the buffer pool */ + ut_print_timestamp(stderr); + fprintf(stderr, + " InnoDB: Initializing buffer pool, size ="); + + if (srv_pool_size * UNIV_PAGE_SIZE >= 1024 * 1024 * 1024) { + fprintf(stderr, + " %.1fG\n", + ((double) (srv_pool_size * UNIV_PAGE_SIZE)) + / (1024 * 1024 * 1024)); + } else { + fprintf(stderr, + " %.1fM\n", + ((double) (srv_pool_size * UNIV_PAGE_SIZE)) + / (1024 * 1024)); + } + if (srv_use_awe) { fprintf(stderr, "InnoDB: Using AWE: Memory window is %lu MB" @@ -1267,6 +1284,8 @@ innobase_start_or_create_for_mysql(void) srv_pool_size); } + ut_print_timestamp(stderr); + if (ret == NULL) { fprintf(stderr, "InnoDB: Fatal error: cannot allocate the memory" @@ -1275,6 +1294,9 @@ innobase_start_or_create_for_mysql(void) return(DB_ERROR); } + fprintf(stderr, + " InnoDB: Completed initialization of buffer pool\n"); + fsp_init(); log_init(); diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index f99c49d63f6..eaf16a923da 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,9 @@ +2010-11-10 The InnoDB Team + + * srv/srv0start.c: + Fix Bug #48026 Log start and end of InnoDB buffer pool + initialization to the error log + 2010-11-03 The InnoDB Team * include/btr0btr.h, include/btr0btr.ic, dict/dict0crea.c: diff --git a/storage/innodb_plugin/srv/srv0start.c b/storage/innodb_plugin/srv/srv0start.c index f823b72fbc1..73f8f319704 100644 --- a/storage/innodb_plugin/srv/srv0start.c +++ b/storage/innodb_plugin/srv/srv0start.c @@ -1286,8 +1286,25 @@ innobase_start_or_create_for_mysql(void) fil_init(srv_file_per_table ? 50000 : 5000, srv_max_n_open_files); + /* Print time to initialize the buffer pool */ + ut_print_timestamp(stderr); + fprintf(stderr, + " InnoDB: Initializing buffer pool, size ="); + + if (srv_buf_pool_size >= 1024 * 1024 * 1024) { + fprintf(stderr, + " %.1fG\n", + ((double) srv_buf_pool_size) / (1024 * 1024 * 1024)); + } else { + fprintf(stderr, + " %.1fM\n", + ((double) srv_buf_pool_size) / (1024 * 1024)); + } + ret = buf_pool_init(); + ut_print_timestamp(stderr); + if (ret == NULL) { fprintf(stderr, "InnoDB: Fatal error: cannot allocate the memory" @@ -1296,6 +1313,9 @@ innobase_start_or_create_for_mysql(void) return(DB_ERROR); } + fprintf(stderr, + " InnoDB: Completed initialization of buffer pool\n"); + #ifdef UNIV_DEBUG /* We have observed deadlocks with a 5MB buffer pool but the actual lower limit could very well be a little higher. */ From f2215a11aca37a583d87ea4809bd62d9d2a5b8e5 Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Wed, 10 Nov 2010 21:32:12 -0800 Subject: [PATCH 214/304] Fix Bug #48026 Log start and end of InnoDB buffer pool initialization to the error log rb://513 approved by Sunny Bains --- storage/innodb_plugin/ChangeLog | 6 ++++++ storage/innodb_plugin/dict/dict0dict.c | 11 +++++++++-- storage/innodb_plugin/handler/handler0alter.cc | 11 ++++++----- storage/innodb_plugin/include/dict0dict.h | 3 ++- storage/innodb_plugin/row/row0merge.c | 2 +- 5 files changed, 24 insertions(+), 9 deletions(-) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index eaf16a923da..86b0c153704 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,9 @@ +2010-11-10 The InnoDB Team + + * dict/dict0dict.c, handler/handler0alter.cc, include/dict0dict.h + row/row0merge.c: + Fix Bug #55084 Innodb crash and corruption after alter table + 2010-11-10 The InnoDB Team * srv/srv0start.c: diff --git a/storage/innodb_plugin/dict/dict0dict.c b/storage/innodb_plugin/dict/dict0dict.c index 2adae4afffb..774e7f213e8 100644 --- a/storage/innodb_plugin/dict/dict0dict.c +++ b/storage/innodb_plugin/dict/dict0dict.c @@ -4842,7 +4842,8 @@ void dict_table_replace_index_in_foreign_list( /*=====================================*/ dict_table_t* table, /*!< in/out: table */ - dict_index_t* index) /*!< in: index to be replaced */ + dict_index_t* index, /*!< in: index to be replaced */ + const trx_t* trx) /*!< in: transaction handle */ { dict_foreign_t* foreign; @@ -4853,7 +4854,13 @@ dict_table_replace_index_in_foreign_list( if (foreign->foreign_index == index) { dict_index_t* new_index = dict_foreign_find_equiv_index(foreign); - ut_a(new_index); + + /* There must exist an alternative index if + check_foreigns (FOREIGN_KEY_CHECKS) is on, + since ha_innobase::prepare_drop_index had done + the check before we reach here. */ + + ut_a(new_index || !trx->check_foreigns); foreign->foreign_index = new_index; } diff --git a/storage/innodb_plugin/handler/handler0alter.cc b/storage/innodb_plugin/handler/handler0alter.cc index e936bfafa0e..517445f7e69 100644 --- a/storage/innodb_plugin/handler/handler0alter.cc +++ b/storage/innodb_plugin/handler/handler0alter.cc @@ -1012,12 +1012,13 @@ ha_innobase::prepare_drop_index( index->to_be_dropped = TRUE; } - /* If FOREIGN_KEY_CHECK = 1 you may not drop an index defined + /* If FOREIGN_KEY_CHECKS = 1 you may not drop an index defined for a foreign key constraint because InnoDB requires that both - tables contain indexes for the constraint. Note that CREATE - INDEX id ON table does a CREATE INDEX and DROP INDEX, and we - can ignore here foreign keys because a new index for the - foreign key has already been created. + tables contain indexes for the constraint. Such index can + be dropped only if FOREIGN_KEY_CHECKS is set to 0. + Note that CREATE INDEX id ON table does a CREATE INDEX and + DROP INDEX, and we can ignore here foreign keys because a + new index for the foreign key has already been created. We check for the foreign key constraints after marking the candidate indexes for deletion, because when we check for an diff --git a/storage/innodb_plugin/include/dict0dict.h b/storage/innodb_plugin/include/dict0dict.h index 44db7b3df1d..7b02111fb87 100644 --- a/storage/innodb_plugin/include/dict0dict.h +++ b/storage/innodb_plugin/include/dict0dict.h @@ -318,7 +318,8 @@ void dict_table_replace_index_in_foreign_list( /*=====================================*/ dict_table_t* table, /*!< in/out: table */ - dict_index_t* index); /*!< in: index to be replaced */ + dict_index_t* index, /*!< in: index to be replaced */ + const trx_t* trx); /*!< in: transaction handle */ /*********************************************************************//** Checks if a index is defined for a foreign key constraint. Index is a part of a foreign key constraint if the index is referenced by foreign key diff --git a/storage/innodb_plugin/row/row0merge.c b/storage/innodb_plugin/row/row0merge.c index 05d77ad7f19..160edd32fbf 100644 --- a/storage/innodb_plugin/row/row0merge.c +++ b/storage/innodb_plugin/row/row0merge.c @@ -2043,7 +2043,7 @@ row_merge_drop_index( /* Replace this index with another equivalent index for all foreign key constraints on this table where this index is used */ - dict_table_replace_index_in_foreign_list(table, index); + dict_table_replace_index_in_foreign_list(table, index, trx); dict_index_remove_from_cache(table, index); trx->op_info = ""; From b49e1573b8cff1daae7311ad25ada297b0e44cb0 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Thu, 11 Nov 2010 08:50:41 +0200 Subject: [PATCH 215/304] Increment InnoDB version from 1.1.3 to 1.1.4 InnoDB 1.1.3 was released with MySQL 5.5.7-rc --- storage/innobase/include/univ.i | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i index 8bcb05c7e56..9cf823c2ff3 100644 --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i @@ -46,7 +46,7 @@ Created 1/20/1994 Heikki Tuuri #define INNODB_VERSION_MAJOR 1 #define INNODB_VERSION_MINOR 1 -#define INNODB_VERSION_BUGFIX 3 +#define INNODB_VERSION_BUGFIX 4 /* The following is the InnoDB version as shown in SELECT plugin_version FROM information_schema.plugins; From ddd6fbe553709c91d7d6b08620f45d789a046897 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Thu, 11 Nov 2010 11:08:53 +0300 Subject: [PATCH 216/304] Bug#57687 crash when reporting duplicate group_key error and utf8 Fixing DoS regression problem. Using "key_part->fieldnr - 1" to access the desired field is only correct in real INSERT queries. In case of inserting records into a temporary table when performing GROUP BY queries this expression does not work. Fix: Instead of accessing field_length and comparing it to key_part->length, there is an easier way to check if we're dealing with a prefix key: check key_part_flag against HA_PART_KEY_SEG flag. --- mysql-test/r/ctype_utf8.result | 11 +++++++++++ mysql-test/t/ctype_utf8.test | 12 ++++++++++++ sql/key.cc | 4 +--- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index 13e1092cb98..3982d09e64b 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -4885,5 +4885,16 @@ maketime(`a`,`a`,`a`) DROP TABLE t1; SET sql_mode=default; # +# Bug#57687 crash when reporting duplicate group_key error and utf8 +# Make sure to modify this when Bug#58081 is fixed. +# +SET NAMES utf8; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (0), (0), (1), (0), (0); +SELECT COUNT(*) FROM t1, t1 t2 +GROUP BY INSERT('', t2.a, t1.a, (@@global.max_binlog_size)); +ERROR 23000: Duplicate entry '107374182410737418241' for key 'group_key' +DROP TABLE t1; +# # End of 5.5 tests # diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index 318bbdca0c7..5ce83a05f61 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -1529,6 +1529,18 @@ DROP TABLE t1, t2; SET NAMES utf8; --source include/ctype_numconv.inc +--echo # +--echo # Bug#57687 crash when reporting duplicate group_key error and utf8 +--echo # Make sure to modify this when Bug#58081 is fixed. +--echo # +SET NAMES utf8; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (0), (0), (1), (0), (0); +--error ER_DUP_ENTRY +SELECT COUNT(*) FROM t1, t1 t2 +GROUP BY INSERT('', t2.a, t1.a, (@@global.max_binlog_size)); +DROP TABLE t1; + --echo # --echo # End of 5.5 tests diff --git a/sql/key.cc b/sql/key.cc index e28e0803986..288afd034a9 100644 --- a/sql/key.cc +++ b/sql/key.cc @@ -364,9 +364,7 @@ void key_unpack(String *to,TABLE *table,uint idx) while (tmp_end > tmp.ptr() && !*--tmp_end) ; tmp.length(tmp_end - tmp.ptr() + 1); } - if (cs->mbmaxlen > 1 && - table->field[key_part->fieldnr - 1]->field_length != - key_part->length) + if (cs->mbmaxlen > 1 && (key_part->key_part_flag & HA_PART_KEY_SEG)) { /* Prefix key, multi-byte charset. From 298717f419292baed99e4d981c8f6c449233ed97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 11 Nov 2010 11:39:09 +0200 Subject: [PATCH 217/304] Declarations and code do not mix in C90, not even within UNIV_DEBUG. --- storage/innodb_plugin/buf/buf0flu.c | 4 ++-- storage/innodb_plugin/sync/sync0rw.c | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/storage/innodb_plugin/buf/buf0flu.c b/storage/innodb_plugin/buf/buf0flu.c index 2123f8a060d..3a9975ce4b7 100644 --- a/storage/innodb_plugin/buf/buf0flu.c +++ b/storage/innodb_plugin/buf/buf0flu.c @@ -1710,9 +1710,9 @@ buf_flush_validate_low(void) ut_a(om > 0); if (UNIV_LIKELY_NULL(buf_pool->flush_rbt)) { + buf_page_t* rpage; ut_a(rnode); - buf_page_t* rpage = *rbt_value(buf_page_t*, - rnode); + rpage = *rbt_value(buf_page_t*, rnode); ut_a(rpage); ut_a(rpage == bpage); rnode = rbt_next(buf_pool->flush_rbt, rnode); diff --git a/storage/innodb_plugin/sync/sync0rw.c b/storage/innodb_plugin/sync/sync0rw.c index 365a53dcac1..572c3690a7f 100644 --- a/storage/innodb_plugin/sync/sync0rw.c +++ b/storage/innodb_plugin/sync/sync0rw.c @@ -335,10 +335,13 @@ rw_lock_validate( /*=============*/ rw_lock_t* lock) /*!< in: rw-lock */ { + ulint waiters; + lint lock_word; + ut_a(lock); - ulint waiters = rw_lock_get_waiters(lock); - lint lock_word = lock->lock_word; + waiters = rw_lock_get_waiters(lock); + lock_word = lock->lock_word; ut_ad(lock->magic_n == RW_LOCK_MAGIC_N); ut_a(waiters == 0 || waiters == 1); From db054043ac616eb17451374ada21e190048e0dc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 11 Nov 2010 11:55:35 +0200 Subject: [PATCH 218/304] Bug#57802 Empty ASSERTION parameter passed to the HASH_SEARCH macro thr_local_validate(), i_s_locks_row_validate(): New validate functions, used in UNIV_DEBUG code for checking the state of internal memory structures. --- storage/innodb_plugin/ChangeLog | 8 +++-- storage/innodb_plugin/thr/thr0loc.c | 27 +++++++++++++-- storage/innodb_plugin/trx/trx0i_s.c | 54 +++++++++++++++++++++++++---- 3 files changed, 77 insertions(+), 12 deletions(-) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 86b0c153704..9990939c0af 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,13 +1,17 @@ +2010-11-11 The InnoDB Team + * thr/thr0loc.c, trx/trx0i_s.c: + Fix Bug#57802 Empty ASSERTION parameter passed to the HASH_SEARCH macro + 2010-11-10 The InnoDB Team * dict/dict0dict.c, handler/handler0alter.cc, include/dict0dict.h row/row0merge.c: - Fix Bug #55084 Innodb crash and corruption after alter table + Fix Bug#55084 InnoDB crash and corruption after ALTER TABLE 2010-11-10 The InnoDB Team * srv/srv0start.c: - Fix Bug #48026 Log start and end of InnoDB buffer pool + Fix Bug#48026 Log start and end of InnoDB buffer pool initialization to the error log 2010-11-03 The InnoDB Team diff --git a/storage/innodb_plugin/thr/thr0loc.c b/storage/innodb_plugin/thr/thr0loc.c index 59a234a6b72..2bc6295dd70 100644 --- a/storage/innodb_plugin/thr/thr0loc.c +++ b/storage/innodb_plugin/thr/thr0loc.c @@ -71,6 +71,23 @@ struct thr_local_struct{ /** The value of thr_local_struct::magic_n */ #define THR_LOCAL_MAGIC_N 1231234 +#ifdef UNIV_DEBUG +/*******************************************************************//** +Validates thread local data. +@return TRUE if valid */ +static +ibool +thr_local_validate( +/*===============*/ + const thr_local_t* local) /*!< in: data to validate */ +{ + ut_ad(local->magic_n == THR_LOCAL_MAGIC_N); + ut_ad(local->slot_no < OS_THREAD_MAX_N); + ut_ad(local->in_ibuf == FALSE || local->in_ibuf == TRUE); + return(TRUE); +} +#endif /* UNIV_DEBUG */ + /*******************************************************************//** Returns the local storage struct for a thread. @return local storage */ @@ -91,7 +108,8 @@ try_again: local = NULL; HASH_SEARCH(hash, thr_local_hash, os_thread_pf(id), - thr_local_t*, local,, os_thread_eq(local->id, id)); + thr_local_t*, local, ut_ad(thr_local_validate(local)), + os_thread_eq(local->id, id)); if (local == NULL) { mutex_exit(&thr_local_mutex); @@ -102,7 +120,7 @@ try_again: goto try_again; } - ut_ad(local->magic_n == THR_LOCAL_MAGIC_N); + ut_ad(thr_local_validate(local)); return(local); } @@ -215,7 +233,8 @@ thr_local_free( /* Look for the local struct in the hash table */ HASH_SEARCH(hash, thr_local_hash, os_thread_pf(id), - thr_local_t*, local,, os_thread_eq(local->id, id)); + thr_local_t*, local, ut_ad(thr_local_validate(local)), + os_thread_eq(local->id, id)); if (local == NULL) { mutex_exit(&thr_local_mutex); @@ -228,6 +247,7 @@ thr_local_free( mutex_exit(&thr_local_mutex); ut_a(local->magic_n == THR_LOCAL_MAGIC_N); + ut_ad(thr_local_validate(local)); mem_free(local); } @@ -270,6 +290,7 @@ thr_local_close(void) local = HASH_GET_NEXT(hash, prev_local); ut_a(prev_local->magic_n == THR_LOCAL_MAGIC_N); + ut_ad(thr_local_validate(prev_local)); mem_free(prev_local); } } diff --git a/storage/innodb_plugin/trx/trx0i_s.c b/storage/innodb_plugin/trx/trx0i_s.c index 5bc8302d0c0..a3ffc4ec015 100644 --- a/storage/innodb_plugin/trx/trx0i_s.c +++ b/storage/innodb_plugin/trx/trx0i_s.c @@ -408,6 +408,42 @@ table_cache_create_empty_row( return(row); } +#ifdef UNIV_DEBUG +/*******************************************************************//** +Validates a row in the locks cache. +@return TRUE if valid */ +static +ibool +i_s_locks_row_validate( +/*===================*/ + const i_s_locks_row_t* row) /*!< in: row to validate */ +{ + ut_ad(row->lock_trx_id != 0); + ut_ad(row->lock_mode != NULL); + ut_ad(row->lock_type != NULL); + ut_ad(row->lock_table != NULL); + ut_ad(row->lock_table_id != 0); + + if (row->lock_space == ULINT_UNDEFINED) { + /* table lock */ + ut_ad(!strcmp("TABLE", row->lock_type)); + ut_ad(row->lock_index == NULL); + ut_ad(row->lock_data == NULL); + ut_ad(row->lock_page == ULINT_UNDEFINED); + ut_ad(row->lock_rec == ULINT_UNDEFINED); + } else { + /* record lock */ + ut_ad(!strcmp("RECORD", row->lock_type)); + ut_ad(row->lock_index != NULL); + ut_ad(row->lock_data != NULL); + ut_ad(row->lock_page != ULINT_UNDEFINED); + ut_ad(row->lock_rec != ULINT_UNDEFINED); + } + + return(TRUE); +} +#endif /* UNIV_DEBUG */ + /*******************************************************************//** Fills i_s_trx_row_t object. If memory can not be allocated then FALSE is returned. @@ -435,18 +471,15 @@ fill_trx_row( row->trx_id = trx_get_id(trx); row->trx_started = (ib_time_t) trx->start_time; row->trx_state = trx_get_que_state_str(trx); + row->requested_lock_row = requested_lock_row; + ut_ad(requested_lock_row == NULL + || i_s_locks_row_validate(requested_lock_row)); if (trx->wait_lock != NULL) { - ut_a(requested_lock_row != NULL); - - row->requested_lock_row = requested_lock_row; row->trx_wait_started = (ib_time_t) trx->wait_started; } else { - ut_a(requested_lock_row == NULL); - - row->requested_lock_row = NULL; row->trx_wait_started = 0; } @@ -729,6 +762,7 @@ fill_locks_row( row->lock_table_id = lock_get_table_id(lock); row->hash_chain.value = row; + ut_ad(i_s_locks_row_validate(row)); return(TRUE); } @@ -749,6 +783,9 @@ fill_lock_waits_row( relevant blocking lock row in innodb_locks */ { + ut_ad(i_s_locks_row_validate(requested_lock_row)); + ut_ad(i_s_locks_row_validate(blocking_lock_row)); + row->requested_lock_row = requested_lock_row; row->blocking_lock_row = blocking_lock_row; @@ -820,6 +857,7 @@ locks_row_eq_lock( or ULINT_UNDEFINED if the lock is a table lock */ { + ut_ad(i_s_locks_row_validate(row)); #ifdef TEST_NO_LOCKS_ROW_IS_EVER_EQUAL_TO_LOCK_T return(0); #else @@ -877,7 +915,7 @@ search_innodb_locks( /* auxiliary variable */ hash_chain, /* assertion on every traversed item */ - , + ut_ad(i_s_locks_row_validate(hash_chain->value)), /* this determines if we have found the lock */ locks_row_eq_lock(hash_chain->value, lock, heap_no)); @@ -917,6 +955,7 @@ add_lock_to_cache( dst_row = search_innodb_locks(cache, lock, heap_no); if (dst_row != NULL) { + ut_ad(i_s_locks_row_validate(dst_row)); return(dst_row); } #endif @@ -954,6 +993,7 @@ add_lock_to_cache( } /* for()-loop */ #endif + ut_ad(i_s_locks_row_validate(dst_row)); return(dst_row); } From 13bc5b3f3d6babe5b2b60256167b2cae1ef7d4c2 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Thu, 11 Nov 2010 13:03:17 +0300 Subject: [PATCH 219/304] BUG#58079 - Remove the IBM DB2 storage engine --- mysql-test/suite/ibmdb2i/include/have_i54.inc | 20 - mysql-test/suite/ibmdb2i/include/have_i61.inc | 20 - .../suite/ibmdb2i/include/have_ibmdb2i.inc | 6 - .../suite/ibmdb2i/r/ibmdb2i_bug_44020.result | 11 - .../suite/ibmdb2i/r/ibmdb2i_bug_44025.result | 4 - .../suite/ibmdb2i/r/ibmdb2i_bug_44232.result | 4 - .../suite/ibmdb2i/r/ibmdb2i_bug_44610.result | 18 - .../suite/ibmdb2i/r/ibmdb2i_bug_45196.result | 33 - .../suite/ibmdb2i/r/ibmdb2i_bug_45793.result | 7 - .../suite/ibmdb2i/r/ibmdb2i_bug_45983.result | 20 - .../suite/ibmdb2i/r/ibmdb2i_bug_49329.result | 9 - .../suite/ibmdb2i/r/ibmdb2i_collations.result | 1204 ------ .../suite/ibmdb2i/t/ibmdb2i_bug_44020.test | 9 - .../suite/ibmdb2i/t/ibmdb2i_bug_44025.test | 9 - .../suite/ibmdb2i/t/ibmdb2i_bug_44232.test | 8 - .../suite/ibmdb2i/t/ibmdb2i_bug_44610.test | 28 - .../suite/ibmdb2i/t/ibmdb2i_bug_45196.test | 26 - .../suite/ibmdb2i/t/ibmdb2i_bug_45793.test | 11 - .../suite/ibmdb2i/t/ibmdb2i_bug_45983.test | 47 - .../suite/ibmdb2i/t/ibmdb2i_bug_49329.test | 10 - .../suite/ibmdb2i/t/ibmdb2i_collations.test | 44 - storage/ibmdb2i/CMakeLists.txt | 25 - storage/ibmdb2i/Makefile.am | 54 - storage/ibmdb2i/db2i_blobCollection.cc | 107 - storage/ibmdb2i/db2i_blobCollection.h | 151 - storage/ibmdb2i/db2i_charsetSupport.cc | 826 ---- storage/ibmdb2i/db2i_charsetSupport.h | 65 - storage/ibmdb2i/db2i_collationSupport.cc | 355 -- storage/ibmdb2i/db2i_collationSupport.h | 48 - storage/ibmdb2i/db2i_constraints.cc | 672 ---- storage/ibmdb2i/db2i_conversion.cc | 1459 ------- storage/ibmdb2i/db2i_errors.cc | 297 -- storage/ibmdb2i/db2i_errors.h | 93 - storage/ibmdb2i/db2i_file.cc | 556 --- storage/ibmdb2i/db2i_file.h | 445 --- storage/ibmdb2i/db2i_global.h | 138 - storage/ibmdb2i/db2i_iconv.h | 51 - storage/ibmdb2i/db2i_ileBridge.cc | 1342 ------- storage/ibmdb2i/db2i_ileBridge.h | 499 --- storage/ibmdb2i/db2i_ioBuffers.cc | 332 -- storage/ibmdb2i/db2i_ioBuffers.h | 416 -- storage/ibmdb2i/db2i_misc.h | 129 - storage/ibmdb2i/db2i_myconv.cc | 1498 -------- storage/ibmdb2i/db2i_myconv.h | 3201 ---------------- storage/ibmdb2i/db2i_rir.cc | 686 ---- storage/ibmdb2i/db2i_safeString.h | 98 - storage/ibmdb2i/db2i_sqlStatementStream.cc | 86 - storage/ibmdb2i/db2i_sqlStatementStream.h | 151 - storage/ibmdb2i/db2i_validatedPointer.h | 162 - storage/ibmdb2i/ha_ibmdb2i.cc | 3359 ----------------- storage/ibmdb2i/ha_ibmdb2i.h | 822 ---- storage/ibmdb2i/plug.in | 12 - 52 files changed, 19683 deletions(-) delete mode 100755 mysql-test/suite/ibmdb2i/include/have_i54.inc delete mode 100644 mysql-test/suite/ibmdb2i/include/have_i61.inc delete mode 100644 mysql-test/suite/ibmdb2i/include/have_ibmdb2i.inc delete mode 100644 mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44020.result delete mode 100644 mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44025.result delete mode 100755 mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44232.result delete mode 100755 mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44610.result delete mode 100644 mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45196.result delete mode 100644 mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45793.result delete mode 100644 mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45983.result delete mode 100644 mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_49329.result delete mode 100644 mysql-test/suite/ibmdb2i/r/ibmdb2i_collations.result delete mode 100644 mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44020.test delete mode 100644 mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44025.test delete mode 100755 mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44232.test delete mode 100755 mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44610.test delete mode 100644 mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45196.test delete mode 100644 mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45793.test delete mode 100644 mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45983.test delete mode 100644 mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_49329.test delete mode 100644 mysql-test/suite/ibmdb2i/t/ibmdb2i_collations.test delete mode 100644 storage/ibmdb2i/CMakeLists.txt delete mode 100644 storage/ibmdb2i/Makefile.am delete mode 100644 storage/ibmdb2i/db2i_blobCollection.cc delete mode 100644 storage/ibmdb2i/db2i_blobCollection.h delete mode 100644 storage/ibmdb2i/db2i_charsetSupport.cc delete mode 100644 storage/ibmdb2i/db2i_charsetSupport.h delete mode 100644 storage/ibmdb2i/db2i_collationSupport.cc delete mode 100644 storage/ibmdb2i/db2i_collationSupport.h delete mode 100644 storage/ibmdb2i/db2i_constraints.cc delete mode 100644 storage/ibmdb2i/db2i_conversion.cc delete mode 100644 storage/ibmdb2i/db2i_errors.cc delete mode 100644 storage/ibmdb2i/db2i_errors.h delete mode 100644 storage/ibmdb2i/db2i_file.cc delete mode 100644 storage/ibmdb2i/db2i_file.h delete mode 100644 storage/ibmdb2i/db2i_global.h delete mode 100644 storage/ibmdb2i/db2i_iconv.h delete mode 100644 storage/ibmdb2i/db2i_ileBridge.cc delete mode 100644 storage/ibmdb2i/db2i_ileBridge.h delete mode 100644 storage/ibmdb2i/db2i_ioBuffers.cc delete mode 100644 storage/ibmdb2i/db2i_ioBuffers.h delete mode 100644 storage/ibmdb2i/db2i_misc.h delete mode 100644 storage/ibmdb2i/db2i_myconv.cc delete mode 100644 storage/ibmdb2i/db2i_myconv.h delete mode 100644 storage/ibmdb2i/db2i_rir.cc delete mode 100644 storage/ibmdb2i/db2i_safeString.h delete mode 100644 storage/ibmdb2i/db2i_sqlStatementStream.cc delete mode 100644 storage/ibmdb2i/db2i_sqlStatementStream.h delete mode 100644 storage/ibmdb2i/db2i_validatedPointer.h delete mode 100644 storage/ibmdb2i/ha_ibmdb2i.cc delete mode 100644 storage/ibmdb2i/ha_ibmdb2i.h delete mode 100644 storage/ibmdb2i/plug.in diff --git a/mysql-test/suite/ibmdb2i/include/have_i54.inc b/mysql-test/suite/ibmdb2i/include/have_i54.inc deleted file mode 100755 index 7054e196153..00000000000 --- a/mysql-test/suite/ibmdb2i/include/have_i54.inc +++ /dev/null @@ -1,20 +0,0 @@ -# Check for IBM i 6.1 or later ---disable_query_log -system uname -rv > $MYSQLTEST_VARDIR/tmp/version; ---disable_warnings -drop table if exists uname_vr; ---enable_warnings -create temporary table uname_vr (r int, v int); ---disable_warnings -eval LOAD DATA INFILE "$MYSQLTEST_VARDIR/tmp/version" into table uname_vr fields terminated by ' '; ---enable_warnings -let $ok = `select count(*) from uname_vr where v = 5 and r = 4`; -drop table uname_vr; -remove_file $MYSQLTEST_VARDIR/tmp/version; ---enable_query_log -if (!$ok) -{ - skip "Need IBM i 5.4 or later"; -} - - diff --git a/mysql-test/suite/ibmdb2i/include/have_i61.inc b/mysql-test/suite/ibmdb2i/include/have_i61.inc deleted file mode 100644 index 84b9a17c1d8..00000000000 --- a/mysql-test/suite/ibmdb2i/include/have_i61.inc +++ /dev/null @@ -1,20 +0,0 @@ -# Check for IBM i 6.1 or later ---disable_query_log -system uname -rv > $MYSQLTEST_VARDIR/tmp/version; ---disable_warnings -drop table if exists uname_vr; ---enable_warnings -create temporary table uname_vr (r int, v int); ---disable_warnings -eval LOAD DATA INFILE "$MYSQLTEST_VARDIR/tmp/version" into table uname_vr fields terminated by ' '; ---enable_warnings -let $ok = `select count(*) from uname_vr where v > 5`; -drop table uname_vr; -remove_file $MYSQLTEST_VARDIR/tmp/version; ---enable_query_log -if (!$ok) -{ - skip "Need IBM i 6.1 or later"; -} - - diff --git a/mysql-test/suite/ibmdb2i/include/have_ibmdb2i.inc b/mysql-test/suite/ibmdb2i/include/have_ibmdb2i.inc deleted file mode 100644 index f3ef0b4f1ac..00000000000 --- a/mysql-test/suite/ibmdb2i/include/have_ibmdb2i.inc +++ /dev/null @@ -1,6 +0,0 @@ -if (!`SELECT count(*) FROM information_schema.engines WHERE - (support = 'YES' OR support = 'DEFAULT') AND - engine = 'ibmdb2i'`) -{ - skip Need ibmdb2i engine; -} diff --git a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44020.result b/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44020.result deleted file mode 100644 index ddf92db6bca..00000000000 --- a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44020.result +++ /dev/null @@ -1,11 +0,0 @@ -create schema `A12345_@$#`; -create table `A12345_@$#`.t1 (i int) engine=ibmdb2i; -show create table `A12345_@$#`.t1; -Table Create Table -t1 CREATE TABLE `t1` ( - `i` int(11) DEFAULT NULL -) ENGINE=IBMDB2I DEFAULT CHARSET=latin1 -select * from `A12345_@$#`.t1; -i -drop table `A12345_@$#`.t1; -drop schema `A12345_@$#`; diff --git a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44025.result b/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44025.result deleted file mode 100644 index 10a3070fcc4..00000000000 --- a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44025.result +++ /dev/null @@ -1,4 +0,0 @@ -create table t1 (c char(10) collate utf8_swedish_ci, index(c)) engine=ibmdb2i; -drop table t1; -create table t1 (c char(10) collate ucs2_swedish_ci, index(c)) engine=ibmdb2i; -drop table t1; diff --git a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44232.result b/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44232.result deleted file mode 100755 index 8276b401073..00000000000 --- a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44232.result +++ /dev/null @@ -1,4 +0,0 @@ -create table t1 (c char(1) character set armscii8) engine=ibmdb2i; -ERROR HY000: Can't create table 'test.t1' (errno: 2504) -create table t1 (c char(1) character set eucjpms ) engine=ibmdb2i; -ERROR HY000: Can't create table 'test.t1' (errno: 2504) diff --git a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44610.result b/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44610.result deleted file mode 100755 index 311e800e1b0..00000000000 --- a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44610.result +++ /dev/null @@ -1,18 +0,0 @@ -create table ABC (i int) engine=ibmdb2i; -drop table ABC; -create table `1234567890ABC` (i int) engine=ibmdb2i; -drop table `1234567890ABC`; -create table `!@#$%` (i int) engine=ibmdb2i; -drop table `!@#$%`; -create table `ABCD#########` (i int) engine=ibmdb2i; -drop table `ABCD#########`; -create table `_` (i int) engine=ibmdb2i; -drop table `_`; -create table `abc##def` (i int) engine=ibmdb2i; -drop table `abc##def`; -set names utf8; -create table İ (s1 int) engine=ibmdb2i; -drop table İ; -create table İİ (s1 int) engine=ibmdb2i; -drop table İİ; -set names latin1; diff --git a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45196.result b/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45196.result deleted file mode 100644 index 916e1d93ee5..00000000000 --- a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45196.result +++ /dev/null @@ -1,33 +0,0 @@ -drop table if exists t1; -create table t1 (c char(10), index(c)) collate ucs2_czech_ci engine=ibmdb2i; -insert into t1 values ("ch"),("h"),("i"); -select * from t1 order by c; -c -h -ch -i -drop table t1; -create table t1 (c char(10), index(c)) collate utf8_czech_ci engine=ibmdb2i; -insert into t1 values ("ch"),("h"),("i"); -select * from t1 order by c; -c -h -ch -i -drop table t1; -create table t1 (c char(10), index(c)) collate ucs2_danish_ci engine=ibmdb2i; -insert into t1 values("abc"),("abcd"),("aaaa"); -select c from t1 order by c; -c -abc -abcd -aaaa -drop table t1; -create table t1 (c char(10), index(c)) collate utf8_danish_ci engine=ibmdb2i; -insert into t1 values("abc"),("abcd"),("aaaa"); -select c from t1 order by c; -c -abc -abcd -aaaa -drop table t1; diff --git a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45793.result b/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45793.result deleted file mode 100644 index 2392b746877..00000000000 --- a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45793.result +++ /dev/null @@ -1,7 +0,0 @@ -drop table if exists t1; -create table t1 (c char(10), index(c)) charset macce engine=ibmdb2i; -insert into t1 values ("test"); -select * from t1 order by c; -c -test -drop table t1; diff --git a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45983.result b/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45983.result deleted file mode 100644 index b9f4dcfc656..00000000000 --- a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45983.result +++ /dev/null @@ -1,20 +0,0 @@ -set ibmdb2i_create_index_option=1; -drop schema if exists test1; -create schema test1; -use test1; -CREATE TABLE t1 (f int primary key, index(f)) engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (f char(10) collate utf8_bin primary key, index(f)) engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (f char(10) collate latin1_swedish_ci primary key, index(f)) engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (f char(10) collate latin1_swedish_ci primary key, i int, index i(i,f)) engine=ibmdb2i; -drop table t1; -create table fd (SQSSEQ CHAR(10)) engine=ibmdb2i; -select * from fd; -SQSSEQ -*HEX -*HEX -*HEX -*HEX -drop table fd; diff --git a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_49329.result b/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_49329.result deleted file mode 100644 index d5bfc2579fd..00000000000 --- a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_49329.result +++ /dev/null @@ -1,9 +0,0 @@ -create table ABC (i int) engine=ibmdb2i; -insert into ABC values(1); -create table abc (i int) engine=ibmdb2i; -insert into abc values (2); -select * from ABC; -i -1 -drop table ABC; -drop table abc; diff --git a/mysql-test/suite/ibmdb2i/r/ibmdb2i_collations.result b/mysql-test/suite/ibmdb2i/r/ibmdb2i_collations.result deleted file mode 100644 index 4f7d71cab2d..00000000000 --- a/mysql-test/suite/ibmdb2i/r/ibmdb2i_collations.result +++ /dev/null @@ -1,1204 +0,0 @@ -drop table if exists t1, ffd, fd; -CREATE TABLE t1 (armscii8_bin integer, c char(10), v varchar(20), index(c), index(v)) collate armscii8_bin engine=ibmdb2i; -CREATE TABLE t1 (armscii8_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate armscii8_general_ci engine=ibmdb2i; -CREATE TABLE t1 (ascii_bin integer, c char(10), v varchar(20), index(c), index(v)) collate ascii_bin engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (ascii_bin char(10) primary key) collate ascii_bin engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (ascii_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ascii_general_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (ascii_general_ci char(10) primary key) collate ascii_general_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (big5_bin integer, c char(10), v varchar(20), index(c), index(v)) collate big5_bin engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 21 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 43 NULL 6 Using where -drop table t1; -create table t1 (big5_bin char(10) primary key) collate big5_bin engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (big5_chinese_ci integer, c char(10), v varchar(20), index(c), index(v)) collate big5_chinese_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 21 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 43 NULL 6 Using where -drop table t1; -create table t1 (big5_chinese_ci char(10) primary key) collate big5_chinese_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (cp1250_bin integer, c char(10), v varchar(20), index(c), index(v)) collate cp1250_bin engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (cp1250_bin char(10) primary key) collate cp1250_bin engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (cp1250_croatian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp1250_croatian_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (cp1250_croatian_ci char(10) primary key) collate cp1250_croatian_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (cp1250_czech_cs integer, c char(10), v varchar(20), index(c), index(v)) collate cp1250_czech_cs engine=ibmdb2i; -CREATE TABLE t1 (cp1250_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp1250_general_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (cp1250_general_ci char(10) primary key) collate cp1250_general_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (cp1250_polish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp1250_polish_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (cp1250_polish_ci char(10) primary key) collate cp1250_polish_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (cp1251_bin integer, c char(10), v varchar(20), index(c), index(v)) collate cp1251_bin engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (cp1251_bin char(10) primary key) collate cp1251_bin engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (cp1251_bulgarian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp1251_bulgarian_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (cp1251_bulgarian_ci char(10) primary key) collate cp1251_bulgarian_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (cp1251_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp1251_general_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (cp1251_general_ci char(10) primary key) collate cp1251_general_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (cp1251_general_cs integer, c char(10), v varchar(20), index(c), index(v)) collate cp1251_general_cs engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (cp1251_general_cs char(10) primary key) collate cp1251_general_cs engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (cp1251_ukrainian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp1251_ukrainian_ci engine=ibmdb2i; -CREATE TABLE t1 (cp1256_bin integer, c char(10), v varchar(20), index(c), index(v)) collate cp1256_bin engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (cp1256_bin char(10) primary key) collate cp1256_bin engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (cp1256_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp1256_general_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (cp1256_general_ci char(10) primary key) collate cp1256_general_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (cp1257_bin integer, c char(10), v varchar(20), index(c), index(v)) collate cp1257_bin engine=ibmdb2i; -CREATE TABLE t1 (cp1257_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp1257_general_ci engine=ibmdb2i; -CREATE TABLE t1 (cp1257_lithuanian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp1257_lithuanian_ci engine=ibmdb2i; -CREATE TABLE t1 (cp850_bin integer, c char(10), v varchar(20), index(c), index(v)) collate cp850_bin engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (cp850_bin char(10) primary key) collate cp850_bin engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (cp850_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp850_general_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (cp850_general_ci char(10) primary key) collate cp850_general_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (cp852_bin integer, c char(10), v varchar(20), index(c), index(v)) collate cp852_bin engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (cp852_bin char(10) primary key) collate cp852_bin engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (cp852_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp852_general_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (cp852_general_ci char(10) primary key) collate cp852_general_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (cp866_bin integer, c char(10), v varchar(20), index(c), index(v)) collate cp866_bin engine=ibmdb2i; -CREATE TABLE t1 (cp866_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp866_general_ci engine=ibmdb2i; -CREATE TABLE t1 (cp932_bin integer, c char(10), v varchar(20), index(c), index(v)) collate cp932_bin engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 21 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 43 NULL 6 Using where -drop table t1; -create table t1 (cp932_bin char(10) primary key) collate cp932_bin engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (cp932_japanese_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp932_japanese_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 21 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 43 NULL 6 Using where -drop table t1; -create table t1 (cp932_japanese_ci char(10) primary key) collate cp932_japanese_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (dec8_bin integer, c char(10), v varchar(20), index(c), index(v)) collate dec8_bin engine=ibmdb2i; -CREATE TABLE t1 (dec8_swedish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate dec8_swedish_ci engine=ibmdb2i; -CREATE TABLE t1 (eucjpms_bin integer, c char(10), v varchar(20), index(c), index(v)) collate eucjpms_bin engine=ibmdb2i; -CREATE TABLE t1 (eucjpms_japanese_ci integer, c char(10), v varchar(20), index(c), index(v)) collate eucjpms_japanese_ci engine=ibmdb2i; -CREATE TABLE t1 (euckr_bin integer, c char(10), v varchar(20), index(c), index(v)) collate euckr_bin engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 21 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 43 NULL 6 Using where -drop table t1; -create table t1 (euckr_bin char(10) primary key) collate euckr_bin engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (euckr_korean_ci integer, c char(10), v varchar(20), index(c), index(v)) collate euckr_korean_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 21 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 43 NULL 6 Using where -drop table t1; -create table t1 (euckr_korean_ci char(10) primary key) collate euckr_korean_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (gb2312_bin integer, c char(10), v varchar(20), index(c), index(v)) collate gb2312_bin engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 21 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 43 NULL 6 Using where -drop table t1; -create table t1 (gb2312_bin char(10) primary key) collate gb2312_bin engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (gb2312_chinese_ci integer, c char(10), v varchar(20), index(c), index(v)) collate gb2312_chinese_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 21 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 43 NULL 6 Using where -drop table t1; -create table t1 (gb2312_chinese_ci char(10) primary key) collate gb2312_chinese_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (gbk_bin integer, c char(10), v varchar(20), index(c), index(v)) collate gbk_bin engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 21 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 43 NULL 6 Using where -drop table t1; -create table t1 (gbk_bin char(10) primary key) collate gbk_bin engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (gbk_chinese_ci integer, c char(10), v varchar(20), index(c), index(v)) collate gbk_chinese_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 21 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 43 NULL 6 Using where -drop table t1; -create table t1 (gbk_chinese_ci char(10) primary key) collate gbk_chinese_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (geostd8_bin integer, c char(10), v varchar(20), index(c), index(v)) collate geostd8_bin engine=ibmdb2i; -CREATE TABLE t1 (geostd8_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate geostd8_general_ci engine=ibmdb2i; -CREATE TABLE t1 (greek_bin integer, c char(10), v varchar(20), index(c), index(v)) collate greek_bin engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (greek_bin char(10) primary key) collate greek_bin engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (greek_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate greek_general_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (greek_general_ci char(10) primary key) collate greek_general_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (hebrew_bin integer, c char(10), v varchar(20), index(c), index(v)) collate hebrew_bin engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (hebrew_bin char(10) primary key) collate hebrew_bin engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (hebrew_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate hebrew_general_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (hebrew_general_ci char(10) primary key) collate hebrew_general_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (hp8_bin integer, c char(10), v varchar(20), index(c), index(v)) collate hp8_bin engine=ibmdb2i; -CREATE TABLE t1 (hp8_english_ci integer, c char(10), v varchar(20), index(c), index(v)) collate hp8_english_ci engine=ibmdb2i; -CREATE TABLE t1 (keybcs2_bin integer, c char(10), v varchar(20), index(c), index(v)) collate keybcs2_bin engine=ibmdb2i; -CREATE TABLE t1 (keybcs2_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate keybcs2_general_ci engine=ibmdb2i; -CREATE TABLE t1 (koi8r_bin integer, c char(10), v varchar(20), index(c), index(v)) collate koi8r_bin engine=ibmdb2i; -CREATE TABLE t1 (koi8r_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate koi8r_general_ci engine=ibmdb2i; -CREATE TABLE t1 (koi8u_bin integer, c char(10), v varchar(20), index(c), index(v)) collate koi8u_bin engine=ibmdb2i; -CREATE TABLE t1 (koi8u_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate koi8u_general_ci engine=ibmdb2i; -CREATE TABLE t1 (latin1_bin integer, c char(10), v varchar(20), index(c), index(v)) collate latin1_bin engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (latin1_bin char(10) primary key) collate latin1_bin engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (latin1_danish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin1_danish_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (latin1_danish_ci char(10) primary key) collate latin1_danish_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (latin1_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin1_general_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (latin1_general_ci char(10) primary key) collate latin1_general_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (latin1_general_cs integer, c char(10), v varchar(20), index(c), index(v)) collate latin1_general_cs engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (latin1_general_cs char(10) primary key) collate latin1_general_cs engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (latin1_german1_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin1_german1_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (latin1_german1_ci char(10) primary key) collate latin1_german1_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (latin1_german2_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin1_german2_ci engine=ibmdb2i; -CREATE TABLE t1 (latin1_spanish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin1_spanish_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (latin1_spanish_ci char(10) primary key) collate latin1_spanish_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (latin1_swedish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin1_swedish_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (latin1_swedish_ci char(10) primary key) collate latin1_swedish_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (latin2_bin integer, c char(10), v varchar(20), index(c), index(v)) collate latin2_bin engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (latin2_bin char(10) primary key) collate latin2_bin engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (latin2_croatian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin2_croatian_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (latin2_croatian_ci char(10) primary key) collate latin2_croatian_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (latin2_czech_cs integer, c char(10), v varchar(20), index(c), index(v)) collate latin2_czech_cs engine=ibmdb2i; -CREATE TABLE t1 (latin2_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin2_general_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (latin2_general_ci char(10) primary key) collate latin2_general_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (latin2_hungarian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin2_hungarian_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (latin2_hungarian_ci char(10) primary key) collate latin2_hungarian_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (latin5_bin integer, c char(10), v varchar(20), index(c), index(v)) collate latin5_bin engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (latin5_bin char(10) primary key) collate latin5_bin engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (latin5_turkish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin5_turkish_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (latin5_turkish_ci char(10) primary key) collate latin5_turkish_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (latin7_bin integer, c char(10), v varchar(20), index(c), index(v)) collate latin7_bin engine=ibmdb2i; -CREATE TABLE t1 (latin7_estonian_cs integer, c char(10), v varchar(20), index(c), index(v)) collate latin7_estonian_cs engine=ibmdb2i; -CREATE TABLE t1 (latin7_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin7_general_ci engine=ibmdb2i; -CREATE TABLE t1 (latin7_general_cs integer, c char(10), v varchar(20), index(c), index(v)) collate latin7_general_cs engine=ibmdb2i; -CREATE TABLE t1 (macce_bin integer, c char(10), v varchar(20), index(c), index(v)) collate macce_bin engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (macce_bin char(10) primary key) collate macce_bin engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (macce_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate macce_general_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (macce_general_ci char(10) primary key) collate macce_general_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (macroman_bin integer, c char(10), v varchar(20), index(c), index(v)) collate macroman_bin engine=ibmdb2i; -CREATE TABLE t1 (macroman_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate macroman_general_ci engine=ibmdb2i; -CREATE TABLE t1 (sjis_bin integer, c char(10), v varchar(20), index(c), index(v)) collate sjis_bin engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 21 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 43 NULL 6 Using where -drop table t1; -create table t1 (sjis_bin char(10) primary key) collate sjis_bin engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (sjis_japanese_ci integer, c char(10), v varchar(20), index(c), index(v)) collate sjis_japanese_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 21 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 43 NULL 6 Using where -drop table t1; -create table t1 (sjis_japanese_ci char(10) primary key) collate sjis_japanese_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (swe7_bin integer, c char(10), v varchar(20), index(c), index(v)) collate swe7_bin engine=ibmdb2i; -CREATE TABLE t1 (swe7_swedish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate swe7_swedish_ci engine=ibmdb2i; -CREATE TABLE t1 (tis620_bin integer, c char(10), v varchar(20), index(c), index(v)) collate tis620_bin engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (tis620_bin char(10) primary key) collate tis620_bin engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (tis620_thai_ci integer, c char(10), v varchar(20), index(c), index(v)) collate tis620_thai_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 11 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 23 NULL 6 Using where -drop table t1; -create table t1 (tis620_thai_ci char(10) primary key) collate tis620_thai_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (ucs2_bin integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_bin engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 21 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 43 NULL 6 Using where -drop table t1; -create table t1 (ucs2_bin char(10) primary key) collate ucs2_bin engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (ucs2_czech_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_czech_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 21 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 43 NULL 6 Using where -drop table t1; -create table t1 (ucs2_czech_ci char(10) primary key) collate ucs2_czech_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (ucs2_danish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_danish_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 21 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 43 NULL 6 Using where -drop table t1; -create table t1 (ucs2_danish_ci char(10) primary key) collate ucs2_danish_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (ucs2_esperanto_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_esperanto_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 21 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 43 NULL 6 Using where -drop table t1; -create table t1 (ucs2_esperanto_ci char(10) primary key) collate ucs2_esperanto_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (ucs2_estonian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_estonian_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 21 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 43 NULL 6 Using where -drop table t1; -create table t1 (ucs2_estonian_ci char(10) primary key) collate ucs2_estonian_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (ucs2_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_general_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 21 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 43 NULL 6 Using where -drop table t1; -create table t1 (ucs2_general_ci char(10) primary key) collate ucs2_general_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (ucs2_hungarian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_hungarian_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 21 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 43 NULL 6 Using where -drop table t1; -create table t1 (ucs2_hungarian_ci char(10) primary key) collate ucs2_hungarian_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (ucs2_icelandic_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_icelandic_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 21 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 43 NULL 6 Using where -drop table t1; -create table t1 (ucs2_icelandic_ci char(10) primary key) collate ucs2_icelandic_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (ucs2_latvian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_latvian_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 21 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 43 NULL 6 Using where -drop table t1; -create table t1 (ucs2_latvian_ci char(10) primary key) collate ucs2_latvian_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (ucs2_lithuanian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_lithuanian_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 21 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 43 NULL 6 Using where -drop table t1; -create table t1 (ucs2_lithuanian_ci char(10) primary key) collate ucs2_lithuanian_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (ucs2_persian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_persian_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 21 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 43 NULL 6 Using where -drop table t1; -create table t1 (ucs2_persian_ci char(10) primary key) collate ucs2_persian_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (ucs2_polish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_polish_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 21 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 43 NULL 6 Using where -drop table t1; -create table t1 (ucs2_polish_ci char(10) primary key) collate ucs2_polish_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (ucs2_romanian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_romanian_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 21 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 43 NULL 6 Using where -drop table t1; -create table t1 (ucs2_romanian_ci char(10) primary key) collate ucs2_romanian_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (ucs2_roman_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_roman_ci engine=ibmdb2i; -CREATE TABLE t1 (ucs2_slovak_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_slovak_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 21 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 43 NULL 6 Using where -drop table t1; -create table t1 (ucs2_slovak_ci char(10) primary key) collate ucs2_slovak_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (ucs2_slovenian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_slovenian_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 21 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 43 NULL 6 Using where -drop table t1; -create table t1 (ucs2_slovenian_ci char(10) primary key) collate ucs2_slovenian_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (ucs2_spanish2_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_spanish2_ci engine=ibmdb2i; -CREATE TABLE t1 (ucs2_spanish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_spanish_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 21 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 43 NULL 6 Using where -drop table t1; -create table t1 (ucs2_spanish_ci char(10) primary key) collate ucs2_spanish_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (ucs2_swedish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_swedish_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 21 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 43 NULL 6 Using where -drop table t1; -create table t1 (ucs2_swedish_ci char(10) primary key) collate ucs2_swedish_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (ucs2_turkish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_turkish_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 21 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 43 NULL 6 Using where -drop table t1; -create table t1 (ucs2_turkish_ci char(10) primary key) collate ucs2_turkish_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (ucs2_unicode_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_unicode_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 21 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 43 NULL 6 Using where -drop table t1; -create table t1 (ucs2_unicode_ci char(10) primary key) collate ucs2_unicode_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (ujis_bin integer, c char(10), v varchar(20), index(c), index(v)) collate ujis_bin engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 31 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 63 NULL 6 Using where -drop table t1; -create table t1 (ujis_bin char(10) primary key) collate ujis_bin engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (ujis_japanese_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ujis_japanese_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 31 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 63 NULL 6 Using where -drop table t1; -create table t1 (ujis_japanese_ci char(10) primary key) collate ujis_japanese_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (utf8_bin integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_bin engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 31 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 63 NULL 6 Using where -drop table t1; -create table t1 (utf8_bin char(10) primary key) collate utf8_bin engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (utf8_czech_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_czech_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 31 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 63 NULL 6 Using where -drop table t1; -create table t1 (utf8_czech_ci char(10) primary key) collate utf8_czech_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (utf8_danish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_danish_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 31 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 63 NULL 6 Using where -drop table t1; -create table t1 (utf8_danish_ci char(10) primary key) collate utf8_danish_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (utf8_esperanto_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_esperanto_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 31 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 63 NULL 6 Using where -drop table t1; -create table t1 (utf8_esperanto_ci char(10) primary key) collate utf8_esperanto_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (utf8_estonian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_estonian_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 31 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 63 NULL 6 Using where -drop table t1; -create table t1 (utf8_estonian_ci char(10) primary key) collate utf8_estonian_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (utf8_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_general_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 31 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 63 NULL 6 Using where -drop table t1; -create table t1 (utf8_general_ci char(10) primary key) collate utf8_general_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (utf8_hungarian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_hungarian_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 31 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 63 NULL 6 Using where -drop table t1; -create table t1 (utf8_hungarian_ci char(10) primary key) collate utf8_hungarian_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (utf8_icelandic_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_icelandic_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 31 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 63 NULL 6 Using where -drop table t1; -create table t1 (utf8_icelandic_ci char(10) primary key) collate utf8_icelandic_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (utf8_latvian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_latvian_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 31 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 63 NULL 6 Using where -drop table t1; -create table t1 (utf8_latvian_ci char(10) primary key) collate utf8_latvian_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (utf8_lithuanian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_lithuanian_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 31 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 63 NULL 6 Using where -drop table t1; -create table t1 (utf8_lithuanian_ci char(10) primary key) collate utf8_lithuanian_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (utf8_persian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_persian_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 31 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 63 NULL 6 Using where -drop table t1; -create table t1 (utf8_persian_ci char(10) primary key) collate utf8_persian_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (utf8_polish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_polish_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 31 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 63 NULL 6 Using where -drop table t1; -create table t1 (utf8_polish_ci char(10) primary key) collate utf8_polish_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (utf8_romanian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_romanian_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 31 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 63 NULL 6 Using where -drop table t1; -create table t1 (utf8_romanian_ci char(10) primary key) collate utf8_romanian_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (utf8_roman_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_roman_ci engine=ibmdb2i; -CREATE TABLE t1 (utf8_slovak_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_slovak_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 31 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 63 NULL 6 Using where -drop table t1; -create table t1 (utf8_slovak_ci char(10) primary key) collate utf8_slovak_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (utf8_slovenian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_slovenian_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 31 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 63 NULL 6 Using where -drop table t1; -create table t1 (utf8_slovenian_ci char(10) primary key) collate utf8_slovenian_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (utf8_spanish2_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_spanish2_ci engine=ibmdb2i; -CREATE TABLE t1 (utf8_spanish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_spanish_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 31 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 63 NULL 6 Using where -drop table t1; -create table t1 (utf8_spanish_ci char(10) primary key) collate utf8_spanish_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (utf8_swedish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_swedish_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 31 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 63 NULL 6 Using where -drop table t1; -create table t1 (utf8_swedish_ci char(10) primary key) collate utf8_swedish_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (utf8_turkish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_turkish_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 31 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 63 NULL 6 Using where -drop table t1; -create table t1 (utf8_turkish_ci char(10) primary key) collate utf8_turkish_ci engine=ibmdb2i; -drop table t1; -CREATE TABLE t1 (utf8_unicode_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_unicode_ci engine=ibmdb2i; -insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); -insert into t1 select * from t1; -explain select c,v from t1 force index(c) where c like "ab%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 31 NULL 6 Using where -explain select c,v from t1 force index(v) where v like "de%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 63 NULL 6 Using where -drop table t1; -create table t1 (utf8_unicode_ci char(10) primary key) collate utf8_unicode_ci engine=ibmdb2i; -drop table t1; -create table ffd (WHCHD1 CHAR(20), WHCSID decimal(5,0)) engine=ibmdb2i; -create table fd (SQSSEQ CHAR(10)) engine=ibmdb2i; -create temporary table intermed (row integer key auto_increment, cs char(30), ccsid integer); -insert into intermed (cs, ccsid) select * from ffd; -create temporary table intermed2 (row integer key auto_increment, srtseq char(10)); -insert into intermed2 (srtseq) select * from fd; -select ccsid, cs, srtseq from intermed inner join intermed2 on intermed.row = intermed2.row; -ccsid cs srtseq -500 "ascii_bin" QBLA101F4U -500 "ascii_general_ci" QALA101F4S -1200 "big5_bin" QBCHT04B0U -1200 "big5_chinese_ci" QACHT04B0S -1153 "cp1250_bin" QELA20481U -1153 "cp1250_croatian_ci" QALA20481S -1153 "cp1250_general_ci" QCLA20481S -1153 "cp1250_polish_ci" QDLA20481S -1025 "cp1251_bin" QCCYR0401U -1025 "cp1251_bulgarian_ci QACYR0401S -1025 "cp1251_general_ci" QBCYR0401S -1025 "cp1251_general_cs" QBCYR0401U -420 "cp1256_bin" QBARA01A4U -420 "cp1256_general_ci" QAARA01A4S -500 "cp850_bin" QDLA101F4U -500 "cp850_general_ci" QCLA101F4S -870 "cp852_bin" QBLA20366U -870 "cp852_general_ci" QALA20366S -1200 "cp932_bin" QBJPN04B0U -1200 "cp932_japanese_ci" QAJPN04B0S -1200 "euckr_bin" QBKOR04B0U -1200 "euckr_korean_ci" QAKOR04B0S -1200 "gb2312_bin" QBCHS04B0U -1200 "gb2312_chinese_ci" QACHS04B0S -1200 "gbk_bin" QDCHS04B0U -1200 "gbk_chinese_ci" QCCHS04B0S -875 "greek_bin" QBELL036BU -875 "greek_general_ci" QAELL036BS -424 "hebrew_bin" QBHEB01A8U -424 "hebrew_general_ci" QAHEB01A8S -1148 "latin1_bin" QFLA1047CU -1148 "latin1_danish_ci" QALA1047CS -1148 "latin1_general_ci" QBLA1047CS -1148 "latin1_general_cs" QBLA1047CU -1148 "latin1_german1_ci" QCLA1047CS -1148 "latin1_spanish_ci" QDLA1047CS -1148 "latin1_swedish_ci" QELA1047CS -870 "latin2_bin" QGLA20366U -870 "latin2_croatian_ci" QCLA20366S -870 "latin2_general_ci" QELA20366S -870 "latin2_hungarian_ci QFLA20366S -1026 "latin5_bin" QBTRK0402U -1026 "latin5_turkish_ci" QATRK0402S -870 "macce_bin" QILA20366U -870 "macce_general_ci" QHLA20366S -1200 "sjis_bin" QDJPN04B0U -1200 "sjis_japanese_ci" QCJPN04B0S -838 "tis620_bin" QBTHA0346U -838 "tis620_thai_ci" QATHA0346S -13488 "ucs2_bin" *HEX -13488 "ucs2_czech_ci" I34ACS_CZ -13488 "ucs2_danish_ci" I34ADA_DK -13488 "ucs2_esperanto_ci" I34AEO -13488 "ucs2_estonian_ci" I34AET -13488 "ucs2_general_ci" QAUCS04B0S -13488 "ucs2_hungarian_ci" I34AHU -13488 "ucs2_icelandic_ci" I34AIS -13488 "ucs2_latvian_ci" I34ALV -13488 "ucs2_lithuanian_ci" I34ALT -13488 "ucs2_persian_ci" I34AFA -13488 "ucs2_polish_ci" I34APL -13488 "ucs2_romanian_ci" I34ARO -13488 "ucs2_slovak_ci" I34ASK -13488 "ucs2_slovenian_ci" I34ASL -13488 "ucs2_spanish_ci" I34AES -13488 "ucs2_swedish_ci" I34ASW -13488 "ucs2_turkish_ci" I34ATR -13488 "ucs2_unicode_ci" I34AEN -1200 "ujis_bin" QFJPN04B0U -1200 "ujis_japanese_ci" QEJPN04B0S -1208 "utf8_bin" *HEX -1208 "utf8_czech_ci" I34ACS_CZ -1208 "utf8_danish_ci" I34ADA_DK -1208 "utf8_esperanto_ci" I34AEO -1208 "utf8_estonian_ci" I34AET -1200 "utf8_general_ci" QAUCS04B0S -1208 "utf8_hungarian_ci" I34AHU -1208 "utf8_icelandic_ci" I34AIS -1208 "utf8_latvian_ci" I34ALV -1208 "utf8_lithuanian_ci" I34ALT -1208 "utf8_persian_ci" I34AFA -1208 "utf8_polish_ci" I34APL -1208 "utf8_romanian_ci" I34ARO -1208 "utf8_slovak_ci" I34ASK -1208 "utf8_slovenian_ci" I34ASL -1208 "utf8_spanish_ci" I34AES -1208 "utf8_swedish_ci" I34ASW -1208 "utf8_turkish_ci" I34ATR -1208 "utf8_unicode_ci" I34AEN -drop table ffd, fd; diff --git a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44020.test b/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44020.test deleted file mode 100644 index 09a7c75cfc0..00000000000 --- a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44020.test +++ /dev/null @@ -1,9 +0,0 @@ -source suite/ibmdb2i/include/have_ibmdb2i.inc; -source include/have_case_sensitive_file_system.inc; - -create schema `A12345_@$#`; -create table `A12345_@$#`.t1 (i int) engine=ibmdb2i; -show create table `A12345_@$#`.t1; -select * from `A12345_@$#`.t1; -drop table `A12345_@$#`.t1; -drop schema `A12345_@$#`; diff --git a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44025.test b/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44025.test deleted file mode 100644 index 9b033a2298f..00000000000 --- a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44025.test +++ /dev/null @@ -1,9 +0,0 @@ -source suite/ibmdb2i/include/have_ibmdb2i.inc; -source suite/ibmdb2i/include/have_i61.inc; - - -create table t1 (c char(10) collate utf8_swedish_ci, index(c)) engine=ibmdb2i; -drop table t1; - -create table t1 (c char(10) collate ucs2_swedish_ci, index(c)) engine=ibmdb2i; -drop table t1; diff --git a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44232.test b/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44232.test deleted file mode 100755 index ea29b5abcd4..00000000000 --- a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44232.test +++ /dev/null @@ -1,8 +0,0 @@ ---source suite/ibmdb2i/include/have_ibmdb2i.inc ---source suite/ibmdb2i/include/have_i54.inc - ---error 1005 -create table t1 (c char(1) character set armscii8) engine=ibmdb2i; - ---error 1005 -create table t1 (c char(1) character set eucjpms ) engine=ibmdb2i; diff --git a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44610.test b/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44610.test deleted file mode 100755 index da69b5d9148..00000000000 --- a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44610.test +++ /dev/null @@ -1,28 +0,0 @@ -source suite/ibmdb2i/include/have_ibmdb2i.inc; - -# Test RCDFMT generation for a variety of kinds of table names -create table ABC (i int) engine=ibmdb2i; -drop table ABC; - -create table `1234567890ABC` (i int) engine=ibmdb2i; -drop table `1234567890ABC`; - -create table `!@#$%` (i int) engine=ibmdb2i; -drop table `!@#$%`; - -create table `ABCD#########` (i int) engine=ibmdb2i; -drop table `ABCD#########`; - -create table `_` (i int) engine=ibmdb2i; -drop table `_`; - -create table `abc##def` (i int) engine=ibmdb2i; -drop table `abc##def`; - -set names utf8; -create table İ (s1 int) engine=ibmdb2i; -drop table İ; - -create table İİ (s1 int) engine=ibmdb2i; -drop table İİ; -set names latin1; diff --git a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45196.test b/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45196.test deleted file mode 100644 index 17b1d658975..00000000000 --- a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45196.test +++ /dev/null @@ -1,26 +0,0 @@ -source suite/ibmdb2i/include/have_ibmdb2i.inc; -source suite/ibmdb2i/include/have_i61.inc; - ---disable_warnings -drop table if exists t1; ---enable_warnings - -create table t1 (c char(10), index(c)) collate ucs2_czech_ci engine=ibmdb2i; -insert into t1 values ("ch"),("h"),("i"); -select * from t1 order by c; -drop table t1; - -create table t1 (c char(10), index(c)) collate utf8_czech_ci engine=ibmdb2i; -insert into t1 values ("ch"),("h"),("i"); -select * from t1 order by c; -drop table t1; - -create table t1 (c char(10), index(c)) collate ucs2_danish_ci engine=ibmdb2i; -insert into t1 values("abc"),("abcd"),("aaaa"); -select c from t1 order by c; -drop table t1; - -create table t1 (c char(10), index(c)) collate utf8_danish_ci engine=ibmdb2i; -insert into t1 values("abc"),("abcd"),("aaaa"); -select c from t1 order by c; -drop table t1; diff --git a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45793.test b/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45793.test deleted file mode 100644 index 93fb78ff421..00000000000 --- a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45793.test +++ /dev/null @@ -1,11 +0,0 @@ -source suite/ibmdb2i/include/have_ibmdb2i.inc; -source suite/ibmdb2i/include/have_i61.inc; - ---disable_warnings -drop table if exists t1; ---enable_warnings - -create table t1 (c char(10), index(c)) charset macce engine=ibmdb2i; -insert into t1 values ("test"); -select * from t1 order by c; -drop table t1; diff --git a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45983.test b/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45983.test deleted file mode 100644 index 695d8e90ada..00000000000 --- a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45983.test +++ /dev/null @@ -1,47 +0,0 @@ -source suite/ibmdb2i/include/have_ibmdb2i.inc; - -# Confirm that ibmdb2i_create_index_option causes additional *HEX sorted indexes to be created for all non-binary keys. - -set ibmdb2i_create_index_option=1; ---disable_warnings -drop schema if exists test1; -create schema test1; -use test1; ---enable_warnings - ---disable_abort_on_error ---error 0,255 -exec system "DLTF QGPL/FDOUT" > /dev/null; ---enable_abort_on_error - -#No additional index because no string fields in key -CREATE TABLE t1 (f int primary key, index(f)) engine=ibmdb2i; ---error 255 -exec system "DSPFD FILE(\"test1\"/PRIM0001) TYPE(*SEQ) OUTPUT(*OUTFILE) OUTFILE(QGPL/FDOUT) OUTMBR(*FIRST *ADD)" > /dev/null; ---error 255 -exec system "DSPFD FILE(\"test1\"/\"f___H_t1\") TYPE(*SEQ) OUTPUT(*OUTFILE) OUTFILE(QGPL/FDOUT) OUTMBR(*FIRST *ADD)" > /dev/null; -drop table t1; - -#No additional index because binary sorting -CREATE TABLE t1 (f char(10) collate utf8_bin primary key, index(f)) engine=ibmdb2i; ---error 255 -exec system "DSPFD FILE(\"test1\"/PRIM0001) TYPE(*SEQ) OUTPUT(*OUTFILE) OUTFILE(QGPL/FDOUT) OUTMBR(*FIRST *ADD)" > /dev/null; ---error 255 -exec system "DSPFD FILE(\"test1\"/\"f___H_t1\") TYPE(*SEQ) OUTPUT(*OUTFILE) OUTFILE(QGPL/FDOUT) OUTMBR(*FIRST *ADD)" > /dev/null; -drop table t1; - -CREATE TABLE t1 (f char(10) collate latin1_swedish_ci primary key, index(f)) engine=ibmdb2i; -exec system "DSPFD FILE(\"test1\"/PRIM0001) TYPE(*SEQ) OUTPUT(*OUTFILE) OUTFILE(QGPL/FDOUT) OUTMBR(*FIRST *ADD)" > /dev/null; -exec system "DSPFD FILE(\"test1\"/\"f___H_t1\") TYPE(*SEQ) OUTPUT(*OUTFILE) OUTFILE(QGPL/FDOUT) OUTMBR(*FIRST *ADD)" > /dev/null; -drop table t1; - -CREATE TABLE t1 (f char(10) collate latin1_swedish_ci primary key, i int, index i(i,f)) engine=ibmdb2i; -exec system "DSPFD FILE(\"test1\"/PRIM0001) TYPE(*SEQ) OUTPUT(*OUTFILE) OUTFILE(QGPL/FDOUT) OUTMBR(*FIRST *ADD)" > /dev/null; -exec system "DSPFD FILE(\"test1\"/\"i___H_t1\") TYPE(*SEQ) OUTPUT(*OUTFILE) OUTFILE(QGPL/FDOUT) OUTMBR(*FIRST *ADD)" > /dev/null; -drop table t1; - - -create table fd (SQSSEQ CHAR(10)) engine=ibmdb2i; -system system "CPYF FROMFILE(QGPL/FDOUT) TOFILE(\"test1\"/\"fd\") mbropt(*replace) fmtopt(*drop *map)" > /dev/null; -select * from fd; -drop table fd; diff --git a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_49329.test b/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_49329.test deleted file mode 100644 index 615df284d8f..00000000000 --- a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_49329.test +++ /dev/null @@ -1,10 +0,0 @@ -source suite/ibmdb2i/include/have_ibmdb2i.inc; -source include/have_case_sensitive_file_system.inc; - -create table ABC (i int) engine=ibmdb2i; -insert into ABC values(1); -create table abc (i int) engine=ibmdb2i; -insert into abc values (2); -select * from ABC; -drop table ABC; -drop table abc; diff --git a/mysql-test/suite/ibmdb2i/t/ibmdb2i_collations.test b/mysql-test/suite/ibmdb2i/t/ibmdb2i_collations.test deleted file mode 100644 index 899f330d360..00000000000 --- a/mysql-test/suite/ibmdb2i/t/ibmdb2i_collations.test +++ /dev/null @@ -1,44 +0,0 @@ -source suite/ibmdb2i/include/have_ibmdb2i.inc; -source suite/ibmdb2i/include/have_i61.inc; ---disable_warnings -drop table if exists t1, ffd, fd; ---enable_warnings - ---disable_abort_on_error ---error 0,255 -exec system "DLTF QGPL/FFDOUT" > /dev/null; ---error 0,255 -exec system "DLTF QGPL/FDOUT" > /dev/null; ---enable_abort_on_error -let $count= query_get_value(select count(*) from information_schema.COLLATIONS where COLLATION_NAME <> "binary", count(*),1); - -while ($count) -{ - let $collation = query_get_value(select COLLATION_NAME from information_schema.COLLATIONS where COLLATION_NAME <> "binary" order by COLLATION_NAME desc, COLLATION_NAME, $count); - error 0,1005,2504,2028; - eval CREATE TABLE t1 ($collation integer, c char(10), v varchar(20), index(c), index(v)) collate $collation engine=ibmdb2i; - if (!$mysql_errno) - { - insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); - insert into t1 select * from t1; - explain select c,v from t1 force index(c) where c like "ab%"; - explain select c,v from t1 force index(v) where v like "de%"; - drop table t1; - eval create table t1 ($collation char(10) primary key) collate $collation engine=ibmdb2i; - system system "DSPFFD FILE(\"test\"/\"t1\") OUTPUT(*OUTFILE) OUTFILE(QGPL/FFDOUT) OUTMBR(*FIRST *ADD)" > /dev/null; - system system "DSPFD FILE(\"test\"/\"t1\") TYPE(*SEQ) OUTPUT(*OUTFILE) OUTFILE(QGPL/FDOUT) OUTMBR(*FIRST *ADD)" > /dev/null; - drop table t1; - } - dec $count; -} - -create table ffd (WHCHD1 CHAR(20), WHCSID decimal(5,0)) engine=ibmdb2i; -system system "CPYF FROMFILE(QGPL/FFDOUT) TOFILE(\"test\"/\"ffd\") mbropt(*replace) fmtopt(*drop *map)" > /dev/null; -create table fd (SQSSEQ CHAR(10)) engine=ibmdb2i; -system system "CPYF FROMFILE(QGPL/FDOUT) TOFILE(\"test\"/\"fd\") mbropt(*replace) fmtopt(*drop *map)" > /dev/null; -create temporary table intermed (row integer key auto_increment, cs char(30), ccsid integer); -insert into intermed (cs, ccsid) select * from ffd; -create temporary table intermed2 (row integer key auto_increment, srtseq char(10)); -insert into intermed2 (srtseq) select * from fd; -select ccsid, cs, srtseq from intermed inner join intermed2 on intermed.row = intermed2.row; -drop table ffd, fd; diff --git a/storage/ibmdb2i/CMakeLists.txt b/storage/ibmdb2i/CMakeLists.txt deleted file mode 100644 index 11cc4300569..00000000000 --- a/storage/ibmdb2i/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2006 MySQL AB -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") -SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") - -INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/sql - ${CMAKE_SOURCE_DIR}/regex - ${CMAKE_SOURCE_DIR}/extra/yassl/include) -ADD_LIBRARY(ibmdb2i ha_ibmdb2i.cc db2i_ileBridge.cc db2i_conversion.cc - db2i_blobCollection.cc db2i_file.cc db2i_charsetSupport.cc - db2i_collationSupport.cc db2i_errors.cc db2i_constraints.cc - db2i_rir.cc db2i_sqlStatementStream.cc db2i_ioBuffers.cc db2i_myconv.cc) diff --git a/storage/ibmdb2i/Makefile.am b/storage/ibmdb2i/Makefile.am deleted file mode 100644 index b9602e392e0..00000000000 --- a/storage/ibmdb2i/Makefile.am +++ /dev/null @@ -1,54 +0,0 @@ -# -# Copyright (c) 2007, 2008, IBM Corporation. -# All rights reserved. -# -# - -#called from the top level Makefile - -MYSQLDATAdir = $(localstatedir) -MYSQLSHAREdir = $(pkgdatadir) -MYSQLBASEdir= $(prefix) -MYSQLLIBdir= $(pkglibdir) -pkgplugindir = $(pkglibdir)/plugin -INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include \ - -I$(top_srcdir)/regex \ - -I$(top_srcdir)/sql \ - -I$(srcdir) \ - -I$ /afs/rchland.ibm.com/lande/shadow/dev2000/osxpf/v5r4m0f.xpf/cur/cmvc/base.pgm/my.xpf/apis \ - -I$ /afs/rchland.ibm.com/lande/shadow/dev2000/osxpf/v5r4m0.xpf/bld/cmvc/base.pgm/lg.xpf \ - -I$ /afs/rchland.ibm.com/lande/shadow/dev2000/osxpf/v5r4m0.xpf/bld/cmvc/base.pgm/tq.xpf -WRAPLIBS= - -LDADD = - -DEFS = @DEFS@ - -noinst_HEADERS = ha_ibmdb2i.h db2i_collationSupport.h db2i_file.h \ - db2i_ioBuffers.h db2i_blobCollection.h \ - db2i_global.h db2i_misc.h db2i_charsetSupport.h db2i_errors.h \ - db2i_iconv.h db2i_myconv.h db2i_safeString.h db2i_sqlStatementStream.h \ - db2i_ileBridge.h db2i_validatedPointer.h - -EXTRA_LTLIBRARIES = ha_ibmdb2i.la -pkgplugin_LTLIBRARIES = @plugin_ibmdb2i_shared_target@ -ha_ibmdb2i_la_LIBADD = -liconv -ha_ibmdb2i_la_LDFLAGS = -module -rpath $(MYSQLLIBdir) -ha_ibmdb2i_la_CXXFLAGS= $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN -ha_ibmdb2i_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN -ha_ibmdb2i_la_SOURCES = ha_ibmdb2i.cc db2i_ileBridge.cc db2i_conversion.cc \ - db2i_blobCollection.cc db2i_file.cc db2i_charsetSupport.cc \ - db2i_collationSupport.cc db2i_errors.cc db2i_constraints.cc \ - db2i_rir.cc db2i_sqlStatementStream.cc db2i_ioBuffers.cc \ - db2i_myconv.cc - -EXTRA_LIBRARIES = libibmdb2i.a -noinst_LIBRARIES = @plugin_ibmdb2i_static_target@ -libibmdb2i_a_CXXFLAGS = $(AM_CXXFLAGS) -libibmdb2i_a_CFLAGS = $(AM_CFLAGS) -libibmdb2i_a_SOURCES= $(ha_ibmdb2i_la_SOURCES) - - -EXTRA_DIST = CMakeLists.txt plug.in -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/ibmdb2i/db2i_blobCollection.cc b/storage/ibmdb2i/db2i_blobCollection.cc deleted file mode 100644 index 17101c9c0a4..00000000000 --- a/storage/ibmdb2i/db2i_blobCollection.cc +++ /dev/null @@ -1,107 +0,0 @@ -/* -Licensed Materials - Property of IBM -DB2 Storage Engine Enablement -Copyright IBM Corporation 2007,2008 -All rights reserved - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - (a) Redistributions of source code must retain this list of conditions, the - copyright notice in section {d} below, and the disclaimer following this - list of conditions. - (b) Redistributions in binary form must reproduce this list of conditions, the - copyright notice in section (d) below, and the disclaimer following this - list of conditions, in the documentation and/or other materials provided - with the distribution. - (c) The name of IBM may not be used to endorse or promote products derived from - this software without specific prior written permission. - (d) The text of the required copyright notice is: - Licensed Materials - Property of IBM - DB2 Storage Engine Enablement - Copyright IBM Corporation 2007,2008 - All rights reserved - -THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - - -#include "db2i_blobCollection.h" - -/** - Return the size to use when allocating space for blob reads. - - @param fieldIndex The field to allocate for - @param[out] shouldProtect Indicates whether storage protection should be - applied to the space, because the size returned is - smaller than the maximum possible size. -*/ - -uint32 -BlobCollection::getSizeToAllocate(int fieldIndex, bool& shouldProtect) -{ - Field* field = table->getMySQLTable()->field[fieldIndex]; - uint fieldLength = field->max_display_length(); - - if (fieldLength <= MAX_FULL_ALLOCATE_BLOB_LENGTH) - { - shouldProtect = false; - return fieldLength; - } - - shouldProtect = true; - - uint curMaxSize = table->getBlobFieldActualSize(fieldIndex); - - uint defaultAllocSize = min(defaultAllocation, fieldLength); - - return max(defaultAllocSize, curMaxSize); - -} - -void -BlobCollection::generateBuffer(int fieldIndex) -{ - DBUG_ASSERT(table->db2Field(fieldIndex).isBlob()); - - bool protect; - buffers[table->getBlobIdFromField(fieldIndex)].Malloc(getSizeToAllocate(fieldIndex, protect), protect); - - return; -} - -/** - Realloc the read buffer associated with a blob field. - - This is used when the previous allocation for a blob field is found to be - too small (this is discovered when QMY_READ trips over the protected boundary - page). - - @param fieldIndex The field to be reallocated - @param size The size of buffer to allocate for this field. -*/ - -ValidatedPointer& -BlobCollection::reallocBuffer(int fieldIndex, size_t size) -{ - ProtectedBuffer& buf = buffers[table->getBlobIdFromField(fieldIndex)]; - if (size <= buf.allocLen()) - return buf.ptr(); - - table->updateBlobFieldActualSize(fieldIndex, size); - - DBUG_PRINT("BlobCollection::reallocBuffer",("PERF: reallocing %d to %d: ", fieldIndex, size)); - - bool protect; - buf.Free(); - buf.Malloc(getSizeToAllocate(fieldIndex, protect), protect); - return buf.ptr(); -} diff --git a/storage/ibmdb2i/db2i_blobCollection.h b/storage/ibmdb2i/db2i_blobCollection.h deleted file mode 100644 index 6a60394555f..00000000000 --- a/storage/ibmdb2i/db2i_blobCollection.h +++ /dev/null @@ -1,151 +0,0 @@ -/* -Licensed Materials - Property of IBM -DB2 Storage Engine Enablement -Copyright IBM Corporation 2007,2008 -All rights reserved - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - (a) Redistributions of source code must retain this list of conditions, the - copyright notice in section {d} below, and the disclaimer following this - list of conditions. - (b) Redistributions in binary form must reproduce this list of conditions, the - copyright notice in section (d) below, and the disclaimer following this - list of conditions, in the documentation and/or other materials provided - with the distribution. - (c) The name of IBM may not be used to endorse or promote products derived from - this software without specific prior written permission. - (d) The text of the required copyright notice is: - Licensed Materials - Property of IBM - DB2 Storage Engine Enablement - Copyright IBM Corporation 2007,2008 - All rights reserved - -THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - - -#ifndef DB2I_BLOBCOLLECTION_H -#define DB2I_BLOBCOLLECTION_H - -#include "db2i_global.h" -#include "db2i_file.h" - -/** - @class ProtectedBuffer - @brief Implements memory management for (optionally) protected buffers. - - Buffers created with the protection option will have a guard page set on the - page following requested allocation size. The side effect is that the actual - allocation is up to 2*4096-1 bytes larger than the size requested by the - using code. -*/ - -class ProtectedBuffer -{ -public: - ProtectedBuffer() : protectBuf(false) - {;} - - void Malloc(size_t size, bool protect = false) - { - protectBuf = protect; - bufptr.alloc(size + (protectBuf ? 0x1fff : 0x0)); - if ((void*)bufptr != NULL) - { - len = size; - if (protectBuf) - mprotect(protectedPage(), 0x1000, PROT_NONE); -#ifndef DBUG_OFF - // Prevents a problem with DBUG_PRINT over-reading in recent versions of - // MySQL - *((char*)protectedPage()-1) = 0; -#endif - } - } - - void Free() - { - if ((void*)bufptr != NULL) - { - if (protectBuf) - mprotect(protectedPage(), 0x1000, PROT_READ | PROT_WRITE); - bufptr.dealloc(); - } - } - - ~ProtectedBuffer() - { - Free(); - } - - ValidatedPointer& ptr() {return bufptr;} - bool isProtected() const {return protectBuf;} - size_t allocLen() const {return len;} -private: - void* protectedPage() - { - return (void*)(((address64_t)(void*)bufptr + len + 0x1000) & ~0xfff); - } - - ValidatedPointer bufptr; - size_t len; - bool protectBuf; - -}; - - -/** - @class BlobCollection - @brief Manages memory allocation for reading blobs associated with a table. - - Allocations are done on-demand and are protected with a guard page if less - than the max possible size is allocated. -*/ -class BlobCollection -{ - public: - BlobCollection(db2i_table* db2Table, uint32 defaultAllocSize) : - defaultAllocation(defaultAllocSize), table(db2Table) - { - buffers = new ProtectedBuffer[table->getBlobCount()]; - } - - ~BlobCollection() - { - delete[] buffers; - } - - ValidatedPointer& getBufferPtr(int fieldIndex) - { - int blobIndex = table->getBlobIdFromField(fieldIndex); - if ((char*)buffers[blobIndex].ptr() == NULL) - generateBuffer(fieldIndex); - - return buffers[blobIndex].ptr(); - } - - ValidatedPointer& reallocBuffer(int fieldIndex, size_t size); - - - private: - - uint32 getSizeToAllocate(int fieldIndex, bool& shouldProtect); - void generateBuffer(int fieldIndex); - - db2i_table* table; // The table being read - ProtectedBuffer* buffers; // The buffers - uint32 defaultAllocation; - /* The default size to use when first allocating a buffer */ -}; - -#endif diff --git a/storage/ibmdb2i/db2i_charsetSupport.cc b/storage/ibmdb2i/db2i_charsetSupport.cc deleted file mode 100644 index 83bf1b9448b..00000000000 --- a/storage/ibmdb2i/db2i_charsetSupport.cc +++ /dev/null @@ -1,826 +0,0 @@ -/* -Licensed Materials - Property of IBM -DB2 Storage Engine Enablement -Copyright IBM Corporation 2007,2008 -All rights reserved - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - (a) Redistributions of source code must retain this list of conditions, the - copyright notice in section {d} below, and the disclaimer following this - list of conditions. - (b) Redistributions in binary form must reproduce this list of conditions, the - copyright notice in section (d) below, and the disclaimer following this - list of conditions, in the documentation and/or other materials provided - with the distribution. - (c) The name of IBM may not be used to endorse or promote products derived from - this software without specific prior written permission. - (d) The text of the required copyright notice is: - Licensed Materials - Property of IBM - DB2 Storage Engine Enablement - Copyright IBM Corporation 2007,2008 - All rights reserved - -THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - - - -#include "db2i_charsetSupport.h" -#include "as400_types.h" -#include "as400_protos.h" -#include "db2i_ileBridge.h" -#include "qlgusr.h" -#include "db2i_errors.h" - - -/* - The following arrays define a mapping between IANA-style text descriptors and - IBM i CCSID text descriptors. The mapping is a 1-to-1 correlation between - corresponding array slots. -*/ -#define MAX_IANASTRING 23 -static const char ianaStringType[MAX_IANASTRING][10] = -{ - {"ascii"}, - {"Big5"}, //big5 - {"cp1250"}, - {"cp1251"}, - {"cp1256"}, - {"cp850"}, - {"cp852"}, - {"cp866"}, - {"IBM943"}, //cp932 - {"EUC-KR"}, //euckr - {"IBM1381"}, //gb2312 - {"IBM1386"}, //gbk - {"greek"}, - {"hebrew"}, - {"latin1"}, - {"latin2"}, - {"latin5"}, - {"macce"}, - {"tis620"}, - {"Shift_JIS"}, //sjis - {"ucs2"}, - {"EUC-JP"}, //ujis - {"utf8"} -}; -static const char ccsidType[MAX_IANASTRING][6] = -{ - {"367"}, //ascii - {"950"}, //big5 - {"1250"}, //cp1250 - {"1251"}, //cp1251 - {"1256"}, //cp1256 - {"850"}, //cp850 - {"852"}, //cp852 - {"866"}, //cp866 - {"943"}, //cp932 - {"970"}, //euckr - {"1381"}, //gb2312 - {"1386"}, //gbk - {"813"}, //greek - {"916"}, //hebrew - {"923"}, //latin1 - {"912"}, //latin2 - {"920"}, //latin5 - {"1282"}, //macce - {"874"}, //tis620 - {"943"}, //sjis - {"13488"},//ucs2 - {"5050"}, //ujis - {"1208"} //utf8 -}; - -static _ILEpointer *QlgCvtTextDescToDesc_sym; - -/* We keep a cache of the mapping for text descriptions obtained via - QlgTextDescToDesc. The following structures implement this cache. */ -static HASH textDescMapHash; -static MEM_ROOT textDescMapMemroot; -static pthread_mutex_t textDescMapHashMutex; -struct TextDescMap -{ - struct HashKey - { - int32 inType; - int32 outType; - char inDesc[Qlg_MaxDescSize]; - } hashKey; - char outDesc[Qlg_MaxDescSize]; -}; - -/* We keep a cache of the mapping for open iconv descriptors. The following - structures implement this cache. */ -static HASH iconvMapHash; -static MEM_ROOT iconvMapMemroot; -static pthread_mutex_t iconvMapHashMutex; -struct IconvMap -{ - struct HashKey - { - uint32 direction; // These are uint32s to avoid garbage data in the key from compiler padding - uint32 db2CCSID; - const CHARSET_INFO* myCharset; - } hashKey; - iconv_t iconvDesc; -}; - - -/** - Initialize the static structures used by this module. - - This must only be called once per plugin instantiation. - - @return 0 if successful. Failure otherwise -*/ -int32 initCharsetSupport() -{ - DBUG_ENTER("initCharsetSupport"); - - int actmark = _ILELOAD("QSYS/QLGUSR", ILELOAD_LIBOBJ); - if ( actmark == -1 ) - { - DBUG_PRINT("initCharsetSupport", ("conversion srvpgm activation failed")); - DBUG_RETURN(1); - } - - QlgCvtTextDescToDesc_sym = (ILEpointer*)malloc_aligned(sizeof(ILEpointer)); - if (_ILESYM(QlgCvtTextDescToDesc_sym, actmark, "QlgCvtTextDescToDesc") == -1) - { - DBUG_PRINT("initCharsetSupport", - ("resolve of QlgCvtTextDescToDesc failed")); - DBUG_RETURN(errno); - } - - VOID(pthread_mutex_init(&textDescMapHashMutex,MY_MUTEX_INIT_FAST)); - hash_init(&textDescMapHash, &my_charset_bin, 10, offsetof(TextDescMap, hashKey), sizeof(TextDescMap::hashKey), 0, 0, HASH_UNIQUE); - - VOID(pthread_mutex_init(&iconvMapHashMutex,MY_MUTEX_INIT_FAST)); - hash_init(&iconvMapHash, &my_charset_bin, 10, offsetof(IconvMap, hashKey), sizeof(IconvMap::hashKey), 0, 0, HASH_UNIQUE); - - init_alloc_root(&textDescMapMemroot, 2048, 0); - init_alloc_root(&iconvMapMemroot, 256, 0); - - initMyconv(); - - DBUG_RETURN(0); -} - -/** - Cleanup the static structures used by this module. - - This must only be called once per plugin instantiation and only if - initCharsetSupport() was successful. -*/ -void doneCharsetSupport() -{ - cleanupMyconv(); - - free_root(&textDescMapMemroot, 0); - free_root(&iconvMapMemroot, 0); - - pthread_mutex_destroy(&textDescMapHashMutex); - hash_free(&textDescMapHash); - pthread_mutex_destroy(&iconvMapHashMutex); - hash_free(&iconvMapHash); - free_aligned(QlgCvtTextDescToDesc_sym); -} - - -/** - Convert a text description from one type to another. - - This function is just a wrapper for the IBM i QlgTextDescToDesc function plus - some overrides for conversions that the API does not handle correctly and - support for caching the computed conversion. - - @param inType The type of descriptor pointed to by "in". - @param outType The type of descriptor requested for "out". - @param in The descriptor to be convereted. - @param[out] out The equivalent descriptor - @param hashKey The hash key to be used for caching the conversion result. - - @return 0 if successful. Failure otherwise -*/ -static int32 getNewTextDesc(const int32 inType, - const int32 outType, - const char* in, - char* out, - const TextDescMap::HashKey* hashKey) -{ - DBUG_ENTER("db2i_charsetSupport::getNewTextDesc"); - const arg_type_t signature[] = { ARG_INT32, ARG_INT32, ARG_MEMPTR, ARG_INT32, ARG_MEMPTR, ARG_INT32, ARG_INT32, ARG_END }; - struct ArgList - { - ILEarglist_base base; - int32 CRDIInType; - int32 CRDIOutType; - ILEpointer CRDIDesc; - int32 CRDIDescSize; - ILEpointer CRDODesc; - int32 CRDODescSize; - int32 CTDCCSID; - } *arguments; - - if ((inType == Qlg_TypeIANA) && (outType == Qlg_TypeAix41)) - { - // Override non-standard charsets - if (unlikely(strcmp("IBM1381", in) == 0)) - { - strcpy(out, "IBM-1381"); - DBUG_RETURN(0); - } - } - else if ((inType == Qlg_TypeAS400CCSID) && (outType == Qlg_TypeAix41)) - { - // Override non-standard charsets - if (strcmp("1148", in) == 0) - { - strcpy(out, "IBM-1148"); - DBUG_RETURN(0); - } - else if (unlikely(strcmp("1153", in) == 0)) - { - strcpy(out, "IBM-1153"); - DBUG_RETURN(0); - } - } - - char argBuf[sizeof(ArgList)+15]; - arguments = (ArgList*)roundToQuadWordBdy(argBuf); - - arguments->CRDIInType = inType; - arguments->CRDIOutType = outType; - arguments->CRDIDesc.s.addr = (address64_t) in; - arguments->CRDIDescSize = Qlg_MaxDescSize; - arguments->CRDODesc.s.addr = (address64_t) out; - arguments->CRDODescSize = Qlg_MaxDescSize; - arguments->CTDCCSID = 819; - _ILECALL(QlgCvtTextDescToDesc_sym, - &arguments->base, - signature, - RESULT_INT32); - if (unlikely(arguments->base.result.s_int32.r_int32 < 0)) - { - if (arguments->base.result.s_int32.r_int32 == Qlg_InDescriptorNotFound) - { - DBUG_RETURN(DB2I_ERR_UNSUPP_CHARSET); - } - else - { - getErrTxt(DB2I_ERR_ILECALL,"QlgCvtTextDescToDesc",arguments->base.result.s_int32.r_int32); - DBUG_RETURN(DB2I_ERR_ILECALL); - } - } - - // Store the conversion information into a cache entry - TextDescMap* mapping = (TextDescMap*)alloc_root(&textDescMapMemroot, sizeof(TextDescMap)); - if (unlikely(!mapping)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - memcpy(&(mapping->hashKey), hashKey, sizeof(hashKey)); - strcpy(mapping->outDesc, out); - pthread_mutex_lock(&textDescMapHashMutex); - my_hash_insert(&textDescMapHash, (const uchar*)mapping); - pthread_mutex_unlock(&textDescMapHashMutex); - - DBUG_RETURN(0); -} - - -/** - Convert a text description from one type to another. - - This function takes a text description in one representation and converts - it into another representation. Although the OS provides some facilities for - doing this, the support is not complete, nor does MySQL always use standard - identifiers. Therefore, there are a lot of hardcoded overrides required. - There is probably some room for optimization here, but this should not be - called frequently under most circumstances. - - @param inType The type of descriptor pointed to by "in". - @param outType The type of descriptor requested for "out". - @param in The descriptor to be convereted. - @param[out] out The equivalent descriptor - - @return 0 if successful. Failure otherwise -*/ -static int32 convertTextDesc(const int32 inType, const int32 outType, const char* inDesc, char* outDesc) -{ - DBUG_ENTER("db2i_charsetSupport::convertTextDesc"); - const char* inDescOverride; - - if (inType == Qlg_TypeIANA) - { - // Override non-standard charsets - if (strcmp("big5", inDesc) == 0) - inDescOverride = "Big5"; - else if (strcmp("cp932", inDesc) == 0) - inDescOverride = "IBM943"; - else if (strcmp("euckr", inDesc) == 0) - inDescOverride = "EUC-KR"; - else if (strcmp("gb2312", inDesc) == 0) - inDescOverride = "IBM1381"; - else if (strcmp("gbk", inDesc) == 0) - inDescOverride = "IBM1386"; - else if (strcmp("sjis", inDesc) == 0) - inDescOverride = "Shift_JIS"; - else if (strcmp("ujis", inDesc) == 0) - inDescOverride = "EUC-JP"; - else - inDescOverride = inDesc; - - // Hardcode non-standard charsets - if (outType == Qlg_TypeAix41) - { - if (strcmp("Big5", inDescOverride) == 0) - { - strcpy(outDesc,"big5"); - DBUG_RETURN(0); - } - else if (strcmp("IBM1386", inDescOverride) == 0) - { - strcpy(outDesc,"GBK"); - DBUG_RETURN(0); - } - else if (strcmp("Shift_JIS", inDescOverride) == 0 || - strcmp("IBM943", inDescOverride) == 0) - { - strcpy(outDesc,"IBM-943"); - DBUG_RETURN(0); - } - else if (strcmp("tis620", inDescOverride) == 0) - { - strcpy(outDesc,"TIS-620"); - DBUG_RETURN(0); - } - else if (strcmp("ucs2", inDescOverride) == 0) - { - strcpy(outDesc,"UCS-2"); - DBUG_RETURN(0); - } - else if (strcmp("cp1250", inDescOverride) == 0) - { - strcpy(outDesc,"IBM-1250"); - DBUG_RETURN(0); - } - else if (strcmp("cp1251", inDescOverride) == 0) - { - strcpy(outDesc,"IBM-1251"); - DBUG_RETURN(0); - } - else if (strcmp("cp1256", inDescOverride) == 0) - { - strcpy(outDesc,"IBM-1256"); - DBUG_RETURN(0); - } - else if (strcmp("macce", inDescOverride) == 0) - { - strcpy(outDesc,"IBM-1282"); - DBUG_RETURN(0); - } - } - else if (outType == Qlg_TypeAS400CCSID) - { - // See if we can fast path the convert - for (int loopCnt = 0; loopCnt < MAX_IANASTRING; ++loopCnt) - { - if (strcmp((char*)ianaStringType[loopCnt],inDescOverride) == 0) - { - strcpy(outDesc,ccsidType[loopCnt]); - DBUG_RETURN(0); - } - } - } - } - else - inDescOverride = inDesc; - - // We call getNewTextDesc for all other conversions and cache the result. - TextDescMap *mapping; - TextDescMap::HashKey hashKey; - hashKey.inType= inType; - hashKey.outType= outType; - uint32 len = strlen(inDescOverride); - memcpy(hashKey.inDesc, inDescOverride, len); - memset(hashKey.inDesc+len, 0, sizeof(hashKey.inDesc) - len); - - if (!(mapping=(TextDescMap *) hash_search(&textDescMapHash, - (const uchar*)&hashKey, - sizeof(hashKey)))) - { - DBUG_RETURN(getNewTextDesc(inType, outType, inDescOverride, outDesc, &hashKey)); - } - else - { - strcpy(outDesc, mapping->outDesc); - } - DBUG_RETURN(0); -} - - -/** - Convert an IANA character set name into a DB2 for i CCSID value. - - @param parmIANADesc An IANA character set name - @param[out] db2Ccsid The equivalent CCSID value - - @return 0 if successful. Failure otherwise -*/ -int32 convertIANAToDb2Ccsid(const char* parmIANADesc, uint16* db2Ccsid) -{ - int32 rc; - uint16 aixCcsid; - char aixCcsidString[Qlg_MaxDescSize]; - int aixEncodingScheme; - int db2EncodingScheme; - rc = convertTextDesc(Qlg_TypeIANA, Qlg_TypeAS400CCSID, parmIANADesc, aixCcsidString); - if (unlikely(rc)) - { - if (rc == DB2I_ERR_UNSUPP_CHARSET) - getErrTxt(DB2I_ERR_UNSUPP_CHARSET, parmIANADesc); - - return rc; - } - aixCcsid = atoi(aixCcsidString); - rc = getEncodingScheme(aixCcsid, aixEncodingScheme); - if (rc != 0) - return rc; - switch(aixEncodingScheme) { // Select on encoding scheme - case 0x1100: // EDCDIC SBCS - case 0x2100: // ASCII SBCS - case 0x4100: // AIX SBCS - case 0x4105: // MS Windows - case 0x5100: // ISO 7 bit ASCII - db2EncodingScheme = 0x1100; - break; - case 0x1200: // EDCDIC DBCS - case 0x2200: // ASCII DBCS - db2EncodingScheme = 0x1200; - break; - case 0x1301: // EDCDIC Mixed - case 0x2300: // ASCII Mixed - case 0x4403: // EUC (ISO 2022) - db2EncodingScheme = 0x1301; - break; - case 0x7200: // UCS2 - db2EncodingScheme = 0x7200; - break; - case 0x7807: // UTF-8 - db2EncodingScheme = 0x7807; - break; - case 0x7500: // UTF-32 - db2EncodingScheme = 0x7500; - break; - default: // Unknown - { - getErrTxt(DB2I_ERR_UNKNOWN_ENCODING,aixEncodingScheme); - return DB2I_ERR_UNKNOWN_ENCODING; - } - break; - } - if (aixEncodingScheme == db2EncodingScheme) - { - *db2Ccsid = aixCcsid; - } - else - { - rc = getAssociatedCCSID(aixCcsid, db2EncodingScheme, db2Ccsid); // EDCDIC SBCS - if (rc != 0) - return rc; - } - - return 0; -} - - -/** - Obtain the encoding scheme of a CCSID. - - @param inCcsid An IBM i CCSID - @param[out] outEncodingScheme The associated encoding scheme - - @return 0 if successful. Failure otherwise -*/ -int32 getEncodingScheme(const uint16 inCcsid, int32& outEncodingScheme) -{ - DBUG_ENTER("db2i_charsetSupport::getEncodingScheme"); - - static bool ptrInited = FALSE; - static char ptrSpace[sizeof(ILEpointer) + 15]; - static ILEpointer* ptrToPtr = (ILEpointer*)roundToQuadWordBdy(ptrSpace); - int rc; - - if (!ptrInited) - { - rc = _RSLOBJ2(ptrToPtr, RSLOBJ_TS_PGM, "QTQGESP", "QSYS"); - - if (rc) - { - getErrTxt(DB2I_ERR_RESOLVE_OBJ,"QTQGESP","QSYS","*PGM",errno); - DBUG_RETURN(DB2I_ERR_RESOLVE_OBJ); - } - ptrInited = TRUE; - } - - DBUG_ASSERT(inCcsid != 0); - - int GESPCCSID = inCcsid; - int GESPLen = 32; - int GESPNbrVal = 0; - int32 GESPES; - int GESPCSCPL[32]; - int GESPFB[3]; - void* ILEArgv[7]; - ILEArgv[0] = &GESPCCSID; - ILEArgv[1] = &GESPLen; - ILEArgv[2] = &GESPNbrVal; - ILEArgv[3] = &GESPES; - ILEArgv[4] = &GESPCSCPL; - ILEArgv[5] = &GESPFB; - ILEArgv[6] = NULL; - - rc = _PGMCALL(ptrToPtr, (void**)&ILEArgv, 0); - - if (rc) - { - getErrTxt(DB2I_ERR_PGMCALL,"QTQGESP","QSYS",rc); - DBUG_RETURN(DB2I_ERR_PGMCALL); - } - if (GESPFB[0] != 0 || - GESPFB[1] != 0 || - GESPFB[2] != 0) - { - getErrTxt(DB2I_ERR_QTQGESP,GESPFB[0],GESPFB[1],GESPFB[2]); - DBUG_RETURN(DB2I_ERR_QTQGESP); - } - outEncodingScheme = GESPES; - - DBUG_RETURN(0); -} - - -/** - Get the best fit equivalent CCSID. (Wrapper for QTQGRDC API) - - @param inCcsid An IBM i CCSID - @param inEncodingScheme The encoding scheme - @param[out] outCcsid The equivalent CCSID - - @return 0 if successful. Failure otherwise -*/ -int32 getAssociatedCCSID(const uint16 inCcsid, const int inEncodingScheme, uint16* outCcsid) -{ - DBUG_ENTER("db2i_charsetSupport::getAssociatedCCSID"); - static bool ptrInited = FALSE; - static char ptrSpace[sizeof(ILEpointer) + 15]; - static ILEpointer* ptrToPtr = (ILEpointer*)roundToQuadWordBdy(ptrSpace); - int rc; - - // Override non-standard charsets - if ((inCcsid == 923) && (inEncodingScheme == 0x1100)) - { - *outCcsid = 1148; - DBUG_RETURN(0); - } - else if ((inCcsid == 1250) && (inEncodingScheme == 0x1100)) - { - *outCcsid = 1153; - DBUG_RETURN(0); - } - - if (!ptrInited) - { - rc = _RSLOBJ2(ptrToPtr, RSLOBJ_TS_PGM, "QTQGRDC", "QSYS"); - - if (rc) - { - getErrTxt(DB2I_ERR_RESOLVE_OBJ,"QTQGRDC","QSYS","*PGM",errno); - DBUG_RETURN(DB2I_ERR_RESOLVE_OBJ); - } - ptrInited = TRUE; - } - - int GRDCCCSID = inCcsid; - int GRDCES = inEncodingScheme; - int GRDCSel = 0; - int GRDCAssCCSID; - int GRDCFB[3]; - void* ILEArgv[7]; - ILEArgv[0] = &GRDCCCSID; - ILEArgv[1] = &GRDCES; - ILEArgv[2] = &GRDCSel; - ILEArgv[3] = &GRDCAssCCSID; - ILEArgv[4] = &GRDCFB; - ILEArgv[5] = NULL; - - rc = _PGMCALL(ptrToPtr, (void**)&ILEArgv, 0); - - if (rc) - { - getErrTxt(DB2I_ERR_PGMCALL,"QTQGRDC","QSYS",rc); - DBUG_RETURN(DB2I_ERR_PGMCALL); - } - if (GRDCFB[0] != 0 || - GRDCFB[1] != 0 || - GRDCFB[2] != 0) - { - getErrTxt(DB2I_ERR_QTQGRDC,GRDCFB[0],GRDCFB[1],GRDCFB[2]); - DBUG_RETURN(DB2I_ERR_QTQGRDC); - } - - *outCcsid = GRDCAssCCSID; - - DBUG_RETURN(0); -} - -/** - Open an iconv conversion between a MySQL charset and the respective IBM i CCSID - - @param direction The direction of the conversion - @param mysqlCSName Name of the MySQL character set - @param db2CCSID The IBM i CCSID - @param hashKey The key to use for inserting the opened conversion into the cache - @param[out] newConversion The iconv descriptor - - @return 0 if successful. Failure otherwise -*/ -static int32 openNewConversion(enum_conversionDirection direction, - const char* mysqlCSName, - uint16 db2CCSID, - IconvMap::HashKey* hashKey, - iconv_t& newConversion) -{ - DBUG_ENTER("db2i_charsetSupport::openNewConversion"); - - char mysqlAix41Desc[Qlg_MaxDescSize]; - char db2Aix41Desc[Qlg_MaxDescSize]; - char db2CcsidString[6] = ""; - int32 rc; - - /* - First we have to convert the MySQL IANA-like name and the DB2 CCSID into - there equivalent iconv descriptions. - */ - rc = convertTextDesc(Qlg_TypeIANA, Qlg_TypeAix41, mysqlCSName, mysqlAix41Desc); - if (unlikely(rc)) - { - if (rc == DB2I_ERR_UNSUPP_CHARSET) - getErrTxt(DB2I_ERR_UNSUPP_CHARSET, mysqlCSName); - - DBUG_RETURN(rc); - } - CHARSET_INFO *cs= &my_charset_bin; - (uint)(cs->cset->long10_to_str)(cs,db2CcsidString,sizeof(db2CcsidString), 10, db2CCSID); - rc = convertTextDesc(Qlg_TypeAS400CCSID, Qlg_TypeAix41, db2CcsidString, db2Aix41Desc); - if (unlikely(rc)) - { - if (rc == DB2I_ERR_UNSUPP_CHARSET) - getErrTxt(DB2I_ERR_UNSUPP_CHARSET, mysqlCSName); - - DBUG_RETURN(rc); - } - - /* Call iconv to open the conversion. */ - if (direction == toDB2) - { - newConversion = iconv_open(db2Aix41Desc, mysqlAix41Desc); - } - else - { - newConversion = iconv_open(mysqlAix41Desc, db2Aix41Desc); - } - - if (unlikely(newConversion == (iconv_t) -1)) - { - getErrTxt(DB2I_ERR_UNSUPP_CHARSET, mysqlCSName); - DBUG_RETURN(DB2I_ERR_UNSUPP_CHARSET); - } - - /* Insert the new conversion into the cache. */ - IconvMap* mapping = (IconvMap*)alloc_root(&iconvMapMemroot, sizeof(IconvMap)); - if (!mapping) - { - my_error(ER_OUTOFMEMORY, MYF(0), sizeof(IconvMap)); - DBUG_RETURN( HA_ERR_OUT_OF_MEM); - } - memcpy(&(mapping->hashKey), hashKey, sizeof(mapping->hashKey)); - mapping->iconvDesc = newConversion; - pthread_mutex_lock(&iconvMapHashMutex); - my_hash_insert(&iconvMapHash, (const uchar*)mapping); - pthread_mutex_unlock(&iconvMapHashMutex); - - DBUG_RETURN(0); -} - - -/** - Open an iconv conversion between a MySQL charset and the respective IBM i CCSID - - @param direction The direction of the conversion - @param cs The MySQL character set - @param db2CCSID The IBM i CCSID - @param[out] newConversion The iconv descriptor - - @return 0 if successful. Failure otherwise -*/ -int32 getConversion(enum_conversionDirection direction, const CHARSET_INFO* cs, uint16 db2CCSID, iconv_t& conversion) -{ - DBUG_ENTER("db2i_charsetSupport::getConversion"); - - int32 rc; - - /* Build the hash key */ - IconvMap::HashKey hashKey; - hashKey.direction= direction; - hashKey.myCharset= cs; - hashKey.db2CCSID= db2CCSID; - - /* Look for the conversion in the cache and add it if it is not there. */ - IconvMap *mapping; - if (!(mapping= (IconvMap *) hash_search(&iconvMapHash, - (const uchar*)&hashKey, - sizeof(hashKey)))) - { - DBUG_PRINT("getConversion", ("Hash miss for direction=%d, cs=%s, ccsid=%d", direction, cs->name, db2CCSID)); - rc= openNewConversion(direction, cs->csname, db2CCSID, &hashKey, conversion); - if (rc) - DBUG_RETURN(rc); - } - else - { - conversion= mapping->iconvDesc; - } - - DBUG_RETURN(0); -} - -/** - Fast-path conversion from ASCII to EBCDIC for use in converting - identifiers to be sent to the QMY APIs. - - @param input ASCII data - @param[out] ouput EBCDIC data - @param ilen Size of input buffer and output buffer -*/ -int convToEbcdic(const char* input, char* output, size_t ilen) -{ - static bool inited = FALSE; - static iconv_t ic; - - if (ilen == 0) - return 0; - - if (!inited) - { - ic = iconv_open( "IBM-037", "ISO8859-1" ); - inited = TRUE; - } - size_t substitutedChars; - size_t olen = ilen; - if (iconv( ic, (char**)&input, &ilen, &output, &olen, &substitutedChars ) == -1) - return errno; - - return 0; -} - - -/** - Fast-path conversion from EBCDIC to ASCII for use in converting - data received from the QMY APIs. - - @param input EBCDIC data - @param[out] ouput ASCII data - @param ilen Size of input buffer and output buffer -*/ -int convFromEbcdic(const char* input, char* output, size_t ilen) -{ - static bool inited = FALSE; - static iconv_t ic; - - if (ilen == 0) - return 0; - - if (!inited) - { - ic = iconv_open("ISO8859-1", "IBM-037"); - inited = TRUE; - } - - size_t substitutedChars; - size_t olen = ilen; - if (iconv( ic, (char**)&input, &ilen, &output, &olen, &substitutedChars) == -1) - return errno; - - return 0; -} diff --git a/storage/ibmdb2i/db2i_charsetSupport.h b/storage/ibmdb2i/db2i_charsetSupport.h deleted file mode 100644 index 77051e1e0db..00000000000 --- a/storage/ibmdb2i/db2i_charsetSupport.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -Licensed Materials - Property of IBM -DB2 Storage Engine Enablement -Copyright IBM Corporation 2007,2008 -All rights reserved - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - (a) Redistributions of source code must retain this list of conditions, the - copyright notice in section {d} below, and the disclaimer following this - list of conditions. - (b) Redistributions in binary form must reproduce this list of conditions, the - copyright notice in section (d) below, and the disclaimer following this - list of conditions, in the documentation and/or other materials provided - with the distribution. - (c) The name of IBM may not be used to endorse or promote products derived from - this software without specific prior written permission. - (d) The text of the required copyright notice is: - Licensed Materials - Property of IBM - DB2 Storage Engine Enablement - Copyright IBM Corporation 2007,2008 - All rights reserved - -THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - - -#ifndef DB2I_CHARSETSUPPORT_H -#define DB2I_CHARSETSUPPORT_H - -#include "db2i_global.h" -#include "mysql_priv.h" -#include -#include "db2i_iconv.h" - -/** - @enum enum_conversionDirection - - Conversion directions for getConversion() -*/ -enum enum_conversionDirection -{ - toMySQL, - toDB2 -}; - -int initCharsetSupport(); -void doneCharsetSupport(); -int32 convertIANAToDb2Ccsid(const char* parmIANADesc, uint16* db2Ccsid); -int32 getEncodingScheme(const uint16 inCcsid, int32& outEncodingScheme); -int32 getAssociatedCCSID(const uint16 inCcsid, const int inEncodingScheme, uint16* outCcsid); -int convToEbcdic(const char* input, char* output, size_t ilen); -int convFromEbcdic(const char* input, char* output, size_t ilen); -int32 getConversion(enum_conversionDirection direction, const CHARSET_INFO* cs, uint16 db2CCSID, iconv_t& conversion); - -#endif diff --git a/storage/ibmdb2i/db2i_collationSupport.cc b/storage/ibmdb2i/db2i_collationSupport.cc deleted file mode 100644 index 65a17fd2452..00000000000 --- a/storage/ibmdb2i/db2i_collationSupport.cc +++ /dev/null @@ -1,355 +0,0 @@ -/* -Licensed Materials - Property of IBM -DB2 Storage Engine Enablement -Copyright IBM Corporation 2007,2008 -All rights reserved - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - (a) Redistributions of source code must retain this list of conditions, the - copyright notice in section {d} below, and the disclaimer following this - list of conditions. - (b) Redistributions in binary form must reproduce this list of conditions, the - copyright notice in section (d) below, and the disclaimer following this - list of conditions, in the documentation and/or other materials provided - with the distribution. - (c) The name of IBM may not be used to endorse or promote products derived from - this software without specific prior written permission. - (d) The text of the required copyright notice is: - Licensed Materials - Property of IBM - DB2 Storage Engine Enablement - Copyright IBM Corporation 2007,2008 - All rights reserved - -THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - - -#include "db2i_collationSupport.h" -#include "db2i_errors.h" - - -/* - The following arrays define a mapping between MySQL collation names and - corresponding IBM i sort sequences. The mapping is a 1-to-1 correlation - between corresponding array slots but is incomplete without case-sensitivity - markers dynamically added to the mySqlSortSequence names. -*/ -#define MAX_COLLATION 87 -static const char* mySQLCollation[MAX_COLLATION] = -{ - {"ascii_general"}, - {"ascii"}, - {"big5_chinese"}, - {"big5"}, - {"cp1250_croatian"}, - {"cp1250_general"}, - {"cp1250_polish"}, - {"cp1250"}, - {"cp1251_bulgarian"}, - {"cp1251_general"}, - {"cp1251"}, - {"cp1256_general"}, - {"cp1256"}, - {"cp850_general"}, - {"cp850"}, - {"cp852_general"}, - {"cp852"}, - {"cp932_japanese"}, - {"cp932"}, - {"euckr_korean"}, - {"euckr"}, - {"gb2312_chinese"}, - {"gb2312"}, - {"gbk_chinese"}, - {"gbk"}, - {"greek_general"}, - {"greek"}, - {"hebrew_general"}, - {"hebrew"}, - {"latin1_danish"}, - {"latin1_general"}, - {"latin1_german1"}, - {"latin1_spanish"}, - {"latin1_swedish"}, - {"latin1"}, - {"latin2_croatian"}, - {"latin2_general"}, - {"latin2_hungarian"}, - {"latin2"}, - {"latin5_turkish"}, - {"latin5"}, - {"macce_general"}, - {"macce"}, - {"sjis_japanese"}, - {"sjis"}, - {"tis620_thai"}, - {"tis620"}, - {"ucs2_czech"}, - {"ucs2_danish"}, - {"ucs2_esperanto"}, - {"ucs2_estonian"}, - {"ucs2_general"}, - {"ucs2_hungarian"}, - {"ucs2_icelandic"}, - {"ucs2_latvian"}, - {"ucs2_lithuanian"}, - {"ucs2_persian"}, - {"ucs2_polish"}, - {"ucs2_romanian"}, - {"ucs2_slovak"}, - {"ucs2_slovenian"}, - {"ucs2_spanish"}, - {"ucs2_swedish"}, - {"ucs2_turkish"}, - {"ucs2_unicode"}, - {"ucs2"}, - {"ujis_japanese"}, - {"ujis"}, - {"utf8_czech"}, - {"utf8_danish"}, - {"utf8_esperanto"}, - {"utf8_estonian"}, - {"utf8_general"}, - {"utf8_hungarian"}, - {"utf8_icelandic"}, - {"utf8_latvian"}, - {"utf8_lithuanian"}, - {"utf8_persian"}, - {"utf8_polish"}, - {"utf8_romanian"}, - {"utf8_slovak"}, - {"utf8_slovenian"}, - {"utf8_spanish"}, - {"utf8_swedish"}, - {"utf8_turkish"}, - {"utf8_unicode"}, - {"utf8"} -}; - - -static const char* mySqlSortSequence[MAX_COLLATION] = -{ - {"QALA101F4"}, - {"QBLA101F4"}, - {"QACHT04B0"}, - {"QBCHT04B0"}, - {"QALA20481"}, - {"QCLA20481"}, - {"QDLA20481"}, - {"QELA20481"}, - {"QACYR0401"}, - {"QBCYR0401"}, - {"QCCYR0401"}, - {"QAARA01A4"}, - {"QBARA01A4"}, - {"QCLA101F4"}, - {"QDLA101F4"}, - {"QALA20366"}, - {"QBLA20366"}, - {"QAJPN04B0"}, - {"QBJPN04B0"}, - {"QAKOR04B0"}, - {"QBKOR04B0"}, - {"QACHS04B0"}, - {"QBCHS04B0"}, - {"QCCHS04B0"}, - {"QDCHS04B0"}, - {"QAELL036B"}, - {"QBELL036B"}, - {"QAHEB01A8"}, - {"QBHEB01A8"}, - {"QALA1047C"}, - {"QBLA1047C"}, - {"QCLA1047C"}, - {"QDLA1047C"}, - {"QELA1047C"}, - {"QFLA1047C"}, - {"QCLA20366"}, - {"QELA20366"}, - {"QFLA20366"}, - {"QGLA20366"}, - {"QATRK0402"}, - {"QBTRK0402"}, - {"QHLA20366"}, - {"QILA20366"}, - {"QCJPN04B0"}, - {"QDJPN04B0"}, - {"QATHA0346"}, - {"QBTHA0346"}, - {"ACS_CZ"}, - {"ADA_DK"}, - {"AEO"}, - {"AET"}, - {"QAUCS04B0"}, - {"AHU"}, - {"AIS"}, - {"ALV"}, - {"ALT"}, - {"AFA"}, - {"APL"}, - {"ARO"}, - {"ASK"}, - {"ASL"}, - {"AES"}, - {"ASW"}, - {"ATR"}, - {"AEN"}, - {"*HEX"}, - {"QEJPN04B0"}, - {"QFJPN04B0"}, - {"ACS_CZ"}, - {"ADA_DK"}, - {"AEO"}, - {"AET"}, - {"QAUCS04B0"}, - {"AHU"}, - {"AIS"}, - {"ALV"}, - {"ALT"}, - {"AFA"}, - {"APL"}, - {"ARO"}, - {"ASK"}, - {"ASL"}, - {"AES"}, - {"ASW"}, - {"ATR"}, - {"AEN"}, - {"*HEX"} -}; - - -/** - Get the IBM i sort sequence that corresponds to the given MySQL collation. - - @param fieldCharSet The collated character set - @param[out] rtnSortSequence The corresponding sort sequence - - @return 0 if successful. Failure otherwise -*/ -static int32 getAssociatedSortSequence(const CHARSET_INFO *fieldCharSet, const char** rtnSortSequence) -{ - DBUG_ENTER("ha_ibmdb2i::getAssociatedSortSequence"); - - if (strcmp(fieldCharSet->csname,"binary") != 0) - { - int collationSearchLen = strlen(fieldCharSet->name); - if (fieldCharSet->state & MY_CS_BINSORT) - collationSearchLen -= 4; - else - collationSearchLen -= 3; - - uint16 loopCnt = 0; - for (loopCnt; loopCnt < MAX_COLLATION; ++loopCnt) - { - if ((strlen(mySQLCollation[loopCnt]) == collationSearchLen) && - (strncmp((char*)mySQLCollation[loopCnt], fieldCharSet->name, collationSearchLen) == 0)) - break; - } - if (loopCnt == MAX_COLLATION) // Did not find associated sort sequence - { - getErrTxt(DB2I_ERR_SRTSEQ); - DBUG_RETURN(DB2I_ERR_SRTSEQ); - } - *rtnSortSequence = mySqlSortSequence[loopCnt]; - } - - DBUG_RETURN(0); -} - - -/** - Update sort sequence information for a key. - - This function accumulates information about a key as it is called for each - field composing the key. The caller should invoke the function for each field - and (with the exception of the charset parm) preserve the values for the - parms across invocations, until a particular key has been evaluated. Once - the last field in the key has been evaluated, the fileSortSequence and - fileSortSequenceLibrary parms will contain the correct information for - creating the corresponding DB2 key. - - @param charset The character set under consideration - @param[in, out] fileSortSequenceType The type of the current key's sort seq - @param[in, out] fileSortSequence The IBM i identifier for the DB2 sort sequence - that corresponds - - @return 0 if successful. Failure otherwise -*/ -int32 updateAssociatedSortSequence(const CHARSET_INFO* charset, - char* fileSortSequenceType, - char* fileSortSequence, - char* fileSortSequenceLibrary) -{ - DBUG_ENTER("ha_ibmdb2i::updateAssociatedSortSequence"); - DBUG_ASSERT(charset); - if (strcmp(charset->csname,"binary") != 0) - { - char newSortSequence[11] = ""; - char newSortSequenceType = ' '; - const char* foundSortSequence; - int rc = getAssociatedSortSequence(charset, &foundSortSequence); - if (rc) DBUG_RETURN (rc); - switch(foundSortSequence[0]) - { - case '*': // Binary - strcat(newSortSequence,foundSortSequence); - newSortSequenceType = 'B'; - break; - case 'Q': // Non-ICU sort sequence - strcat(newSortSequence,foundSortSequence); - if ((charset->state & MY_CS_BINSORT) != 0) - { - strcat(newSortSequence,"U"); - } - else if ((charset->state & MY_CS_CSSORT) != 0) - { - strcat(newSortSequence,"U"); - } - else - { - strcat(newSortSequence,"S"); - } - newSortSequenceType = 'N'; - break; - default: // ICU sort sequence - { - if ((charset->state & MY_CS_CSSORT) == 0) - { - if (osVersion.v >= 6) - strcat(newSortSequence,"I34"); // ICU 3.4 - else - strcat(newSortSequence,"I26"); // ICU 2.6.1 - } - strcat(newSortSequence,foundSortSequence); - newSortSequenceType = 'I'; - } - break; - } - if (*fileSortSequenceType == ' ') // If no sort sequence has been set yet - { - // Set associated sort sequence - strcpy(fileSortSequence,newSortSequence); - strcpy(fileSortSequenceLibrary,"QSYS"); - *fileSortSequenceType = newSortSequenceType; - } - else if (strcmp(fileSortSequence,newSortSequence) != 0) - { - // Only one sort sequence/collation is supported for each DB2 index. - getErrTxt(DB2I_ERR_MIXED_COLLATIONS); - DBUG_RETURN(DB2I_ERR_MIXED_COLLATIONS); - } - } - - DBUG_RETURN(0); -} diff --git a/storage/ibmdb2i/db2i_collationSupport.h b/storage/ibmdb2i/db2i_collationSupport.h deleted file mode 100644 index b2ce09de1ea..00000000000 --- a/storage/ibmdb2i/db2i_collationSupport.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -Licensed Materials - Property of IBM -DB2 Storage Engine Enablement -Copyright IBM Corporation 2007,2008 -All rights reserved - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - (a) Redistributions of source code must retain this list of conditions, the - copyright notice in section {d} below, and the disclaimer following this - list of conditions. - (b) Redistributions in binary form must reproduce this list of conditions, the - copyright notice in section (d) below, and the disclaimer following this - list of conditions, in the documentation and/or other materials provided - with the distribution. - (c) The name of IBM may not be used to endorse or promote products derived from - this software without specific prior written permission. - (d) The text of the required copyright notice is: - Licensed Materials - Property of IBM - DB2 Storage Engine Enablement - Copyright IBM Corporation 2007,2008 - All rights reserved - -THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - - -#ifndef DB2I_COLLATIONSUPPORT_H -#define DB2I_COLLATIONSUPPORT_H - -#include "db2i_global.h" -#include "mysql_priv.h" - -int32 updateAssociatedSortSequence(const CHARSET_INFO* charset, - char* fileSortSequenceType, - char* fileSortSequence, - char* fileSortSequenceLibrary); - -#endif diff --git a/storage/ibmdb2i/db2i_constraints.cc b/storage/ibmdb2i/db2i_constraints.cc deleted file mode 100644 index 1fde0dd3d14..00000000000 --- a/storage/ibmdb2i/db2i_constraints.cc +++ /dev/null @@ -1,672 +0,0 @@ -/* -Licensed Materials - Property of IBM -DB2 Storage Engine Enablement -Copyright IBM Corporation 2007,2008 -All rights reserved - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - (a) Redistributions of source code must retain this list of conditions, the - copyright notice in section {d} below, and the disclaimer following this - list of conditions. - (b) Redistributions in binary form must reproduce this list of conditions, the - copyright notice in section (d) below, and the disclaimer following this - list of conditions, in the documentation and/or other materials provided - with the distribution. - (c) The name of IBM may not be used to endorse or promote products derived from - this software without specific prior written permission. - (d) The text of the required copyright notice is: - Licensed Materials - Property of IBM - DB2 Storage Engine Enablement - Copyright IBM Corporation 2007,2008 - All rights reserved - -THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - - - -#include "ha_ibmdb2i.h" -#include "db2i_safeString.h" - -// This function is called when building the CREATE TABLE information for -// foreign key constraints. It converts a constraint, table, schema, or -// field name from EBCDIC to ASCII. If the DB2 name is quoted, it removes -// those quotes. It then adds the appropriate quotes for a MySQL identifier. - -static void convNameForCreateInfo(THD *thd, SafeString& info, char* fromName, int len) -{ - int quote; - char cquote; // Quote character - char convName[MAX_DB2_FILENAME_LENGTH]; // Converted name - - memset(convName, 0, sizeof(convName)); - convFromEbcdic(fromName, convName, len); - quote = get_quote_char_for_identifier(thd, convName, len); - cquote = (char) quote; - if (quote != EOF) - info.strcat(cquote); - if (convName[0] == '"') // If DB2 name was quoted, remove quotes - { - if (strstr(convName, "\"\"")) - stripExtraQuotes(convName+1, len-1); - info.strncat((char*)(convName+1), len-2); - } - else // DB2 name was not quoted - info.strncat(convName, len); - if (quote != EOF) - info.strcat(cquote); -} - -/** - Evaluate the parse tree to build foreign key constraint clauses - - @parm lex The parse tree - @parm appendHere The DB2 string to receive the constraint clauses - @parm path The path to the table under consideration - @parm fields Pointer to the table's list of field pointers - @parm[in, out] fileSortSequenceType The sort sequence type associated with the table - @parm[in, out] fileSortSequence The sort sequence associated with the table - @parm[in, out] fileSortSequenceLibrary The sort sequence library associated with the table - - @return 0 if successful; HA_ERR_CANNOT_ADD_FOREIGN otherwise -*/ -int ha_ibmdb2i::buildDB2ConstraintString(LEX* lex, - String& appendHere, - const char* path, - Field** fields, - char* fileSortSequenceType, - char* fileSortSequence, - char* fileSortSequenceLibrary) -{ - List_iterator keyIter(lex->alter_info.key_list); - char colName[MAX_DB2_COLNAME_LENGTH+1]; - - Key* curKey; - - while (curKey = keyIter++) - { - if (curKey->type == Key::FOREIGN_KEY) - { - appendHere.append(STRING_WITH_LEN(", ")); - - Foreign_key* fk = (Foreign_key*)curKey; - - char db2LibName[MAX_DB2_SCHEMANAME_LENGTH+1]; - if (fk->name) - { - char db2FKName[MAX_DB2_FILENAME_LENGTH+1]; - appendHere.append(STRING_WITH_LEN("CONSTRAINT ")); - if (fk->ref_table->db.str) - { - convertMySQLNameToDB2Name(fk->ref_table->db.str, db2LibName, sizeof(db2LibName)); - } - else - { - db2i_table::getDB2LibNameFromPath(path, db2LibName); - } - if (lower_case_table_names == 1) - my_casedn_str(files_charset_info, db2LibName); - appendHere.append(db2LibName); - - appendHere.append('.'); - - convertMySQLNameToDB2Name(fk->name, db2FKName, sizeof(db2FKName)); - appendHere.append(db2FKName); - } - - appendHere.append(STRING_WITH_LEN(" FOREIGN KEY (")); - - bool firstTime = true; - - List_iterator column(fk->columns); - Key_part_spec* curColumn; - - while (curColumn = column++) - { - if (!firstTime) - { - appendHere.append(','); - } - firstTime = false; - - convertMySQLNameToDB2Name(curColumn->field_name, colName, sizeof(colName)); - appendHere.append(colName); - - // DB2 requires that the sort sequence on the child table match the parent table's - // sort sequence. We ensure that happens by updating the sort sequence according - // to the constrained fields. - Field** field = fields; - do - { - if (strcmp((*field)->field_name, curColumn->field_name) == 0) - { - int rc = updateAssociatedSortSequence((*field)->charset(), - fileSortSequenceType, - fileSortSequence, - fileSortSequenceLibrary); - - if (unlikely(rc)) return rc; - } - } while (*(++field)); - } - - firstTime = true; - - appendHere.append(STRING_WITH_LEN(") REFERENCES ")); - - if (fk->ref_table->db.str) - { - convertMySQLNameToDB2Name(fk->ref_table->db.str, db2LibName, sizeof(db2LibName)); - } - else - { - db2i_table::getDB2LibNameFromPath(path, db2LibName); - } - if (lower_case_table_names == 1) - my_casedn_str(files_charset_info, db2LibName); - appendHere.append(db2LibName); - appendHere.append('.'); - - char db2FileName[MAX_DB2_FILENAME_LENGTH+1]; - convertMySQLNameToDB2Name(fk->ref_table->table.str, db2FileName, sizeof(db2FileName)); - if (lower_case_table_names) - my_casedn_str(files_charset_info, db2FileName); - appendHere.append(db2FileName); - - - if (!fk->ref_columns.is_empty()) - { - List_iterator ref(fk->ref_columns); - Key_part_spec* curRef; - appendHere.append(STRING_WITH_LEN(" (")); - - - while (curRef = ref++) - { - if (!firstTime) - { - appendHere.append(','); - } - firstTime = false; - - convertMySQLNameToDB2Name(curRef->field_name, colName, sizeof(colName)); - appendHere.append(colName); - } - - appendHere.append(STRING_WITH_LEN(") ")); - } - - if (fk->delete_opt != Foreign_key::FK_OPTION_UNDEF) - { - appendHere.append(STRING_WITH_LEN("ON DELETE ")); - switch (fk->delete_opt) - { - case Foreign_key::FK_OPTION_RESTRICT: - appendHere.append(STRING_WITH_LEN("RESTRICT ")); break; - case Foreign_key::FK_OPTION_CASCADE: - appendHere.append(STRING_WITH_LEN("CASCADE ")); break; - case Foreign_key::FK_OPTION_SET_NULL: - appendHere.append(STRING_WITH_LEN("SET NULL ")); break; - case Foreign_key::FK_OPTION_NO_ACTION: - appendHere.append(STRING_WITH_LEN("NO ACTION ")); break; - case Foreign_key::FK_OPTION_DEFAULT: - appendHere.append(STRING_WITH_LEN("SET DEFAULT ")); break; - default: - return HA_ERR_CANNOT_ADD_FOREIGN; break; - } - } - - if (fk->update_opt != Foreign_key::FK_OPTION_UNDEF) - { - appendHere.append(STRING_WITH_LEN("ON UPDATE ")); - switch (fk->update_opt) - { - case Foreign_key::FK_OPTION_RESTRICT: - appendHere.append(STRING_WITH_LEN("RESTRICT ")); break; - case Foreign_key::FK_OPTION_NO_ACTION: - appendHere.append(STRING_WITH_LEN("NO ACTION ")); break; - default: - return HA_ERR_CANNOT_ADD_FOREIGN; break; - } - } - - } - - } - - return 0; -} - - -/*********************************************************************** -Get the foreign key information in the form of a character string so -that it can be inserted into a CREATE TABLE statement. This is used by -the SHOW CREATE TABLE statement. The string will later be freed by the -free_foreign_key_create_info() method. -************************************************************************/ - -char* ha_ibmdb2i::get_foreign_key_create_info(void) -{ - DBUG_ENTER("ha_ibmdb2i::get_foreign_key_create_info"); - int rc = 0; - char* infoBuffer = NULL; // Pointer to string returned to MySQL - uint32 constraintSpaceLength;// Length of space passed to DB2 - ValidatedPointer constraintSpace; // Space pointer passed to DB2 - uint32 neededLen; // Length returned from DB2 - uint32 cstCnt; // Number of foreign key constraints from DB2 - uint32 fld; // - constraint_hdr* cstHdr; // Pointer to constraint header structure - FK_constraint* FKCstDef; // Pointer to constraint definition structure - cst_name* fieldName; // Pointer to field name structure - char* tempPtr; // Temp pointer for traversing constraint space - char convName[128]; - - /* Allocate space to retrieve the DB2 constraint information. */ - - if (!(share = get_share(table_share->path.str, table))) - DBUG_RETURN(NULL); - - constraintSpaceLength = 5000; // Try allocating 5000 bytes and see if enough. - - initBridge(); - - constraintSpace.alloc(constraintSpaceLength); - rc = bridge()->expectErrors(QMY_ERR_NEED_MORE_SPACE) - ->constraints(db2Table->dataFile()->getMasterDefnHandle(), - constraintSpace, - constraintSpaceLength, - &neededLen, - &cstCnt); - - if (unlikely(rc == QMY_ERR_NEED_MORE_SPACE)) - { - constraintSpaceLength = neededLen; // Get length of space that's needed - constraintSpace.realloc(constraintSpaceLength); - rc = bridge()->expectErrors(QMY_ERR_NEED_MORE_SPACE) - ->constraints(db2Table->dataFile()->getMasterDefnHandle(), - constraintSpace, - constraintSpaceLength, - &neededLen, - &cstCnt); - } - - /* If constraint information was returned by DB2, build a text string */ - /* to return to MySQL. */ - - if ((rc == 0) && (cstCnt > 0)) - { - THD* thd = ha_thd(); - infoBuffer = (char*) my_malloc(MAX_FOREIGN_LEN + 1, MYF(MY_WME)); - if (infoBuffer == NULL) - { - free_share(share); - DBUG_RETURN(NULL); - } - - SafeString info(infoBuffer, MAX_FOREIGN_LEN + 1); - - /* Loop through the DB2 constraints and build a text string for each foreign */ - /* key constraint that is found. */ - - tempPtr = constraintSpace; - cstHdr = (constraint_hdr_t*)(void*)constraintSpace; // Address first constraint definition - for (int i = 0; i < cstCnt && !info.overflowed(); ++i) - { - if (cstHdr->CstType[0] == QMY_CST_FK) // If this is a foreign key constraint - { - tempPtr = (char*)(tempPtr + cstHdr->CstDefOff); - FKCstDef = (FK_constraint_t*)tempPtr; - - /* Process the constraint name. */ - - info.strncat(STRING_WITH_LEN(",\n CONSTRAINT ")); - convNameForCreateInfo(thd, info, - FKCstDef->CstName.Name, FKCstDef->CstName.Len); - - /* Process the names of the foreign keys. */ - - info.strncat(STRING_WITH_LEN(" FOREIGN KEY (")); - tempPtr = (char*)(tempPtr + FKCstDef->KeyColOff); - fieldName= (cst_name_t*)tempPtr; - for (fld = 0; fld < FKCstDef->KeyCnt; ++fld) - { - convNameForCreateInfo(thd, info, fieldName->Name, fieldName->Len); - if ((fld + 1) < FKCstDef->KeyCnt) - { - info.strncat(STRING_WITH_LEN(", ")); - fieldName = fieldName + 1; - } - } - - /* Process the schema-name and name of the referenced table. */ - - info.strncat(STRING_WITH_LEN(") REFERENCES ")); - convNameForCreateInfo(thd, info, - FKCstDef->RefSchema.Name, FKCstDef->RefSchema.Len); - info.strcat('.'); - convNameForCreateInfo(thd, info, - FKCstDef->RefTable.Name, FKCstDef->RefTable.Len); - info.strncat(STRING_WITH_LEN(" (")); - - /* Process the names of the referenced keys. */ - - tempPtr = (char*)FKCstDef; - tempPtr = (char*)(tempPtr + FKCstDef->RefColOff); - fieldName= (cst_name_t*)tempPtr; - for (fld = 0; fld < FKCstDef->RefCnt; ++fld) - { - convNameForCreateInfo(thd, info, fieldName->Name, fieldName->Len); - if ((fld + 1) < FKCstDef->RefCnt) - { - info.strncat(STRING_WITH_LEN(", ")); - fieldName = fieldName + 1; - } - } - - /* Process the ON UPDATE and ON DELETE rules. */ - - info.strncat(STRING_WITH_LEN(") ON UPDATE ")); - switch(FKCstDef->UpdMethod) - { - case QMY_NOACTION: info.strncat(STRING_WITH_LEN("NO ACTION")); break; - case QMY_RESTRICT: info.strncat(STRING_WITH_LEN("RESTRICT")); break; - default: break; - } - info.strncat(STRING_WITH_LEN(" ON DELETE ")); - switch(FKCstDef->DltMethod) - { - case QMY_CASCADE: info.strncat(STRING_WITH_LEN("CASCADE")); break; - case QMY_SETDFT: info.strncat(STRING_WITH_LEN("SET DEFAULT")); break; - case QMY_SETNULL: info.strncat(STRING_WITH_LEN("SET NULL")); break; - case QMY_NOACTION: info.strncat(STRING_WITH_LEN("NO ACTION")); break; - case QMY_RESTRICT: info.strncat(STRING_WITH_LEN("RESTRICT")); break; - default: break; - } - } - - /* Address the next constraint, if any. */ - - if ((i+1) < cstCnt) - { - tempPtr = (char*)cstHdr + cstHdr->CstLen; - cstHdr = (constraint_hdr_t*)(tempPtr); - } - } - } - - /* Cleanup and return */ - free_share(share); - - DBUG_RETURN(infoBuffer); -} - -/*********************************************************************** -Free the foreign key create info (for a table) that was acquired by the -get_foreign_key_create_info() method. -***********************************************************************/ - -void ha_ibmdb2i::free_foreign_key_create_info(char* info) -{ - DBUG_ENTER("ha_ibmdb2i::free_foreign_key_create_info"); - - if (info) - { - my_free(info, MYF(0)); - } - DBUG_VOID_RETURN; -} - -/*********************************************************************** -This method returns to MySQL a list, with one entry in the list describing -each foreign key constraint. -***********************************************************************/ - -int ha_ibmdb2i::get_foreign_key_list(THD *thd, List *f_key_list) -{ - DBUG_ENTER("ha_ibmdb2i::get_foreign_key_list"); - int rc = 0; - uint32 constraintSpaceLength; // Length of space passed to DB2 - ValidatedPointer constraintSpace; // Space pointer passed to DB2 - uint16 rtnCode; // Return code from DB2 - uint32 neededLen; // Bytes needed to contain DB2 constraint info - uint32 cstCnt; // Number of constraints returned by DB2 - uint32 fld; - constraint_hdr* cstHdr; // Pointer to a cst header structure - FK_constraint* FKCstDef; // Pointer to definition of foreign key constraint - cst_name* fieldName; // Pointer to field name structure - const char *method; - ulong methodLen; - char* tempPtr; // Temp pointer for traversing constraint space - char convName[128]; - - if (!(share = get_share(table_share->path.str, table))) - DBUG_RETURN(0); - - // Allocate space to retrieve the DB2 constraint information. - constraintSpaceLength = 5000; // Try allocating 5000 bytes and see if enough. - - constraintSpace.alloc(constraintSpaceLength); - rc = bridge()->expectErrors(QMY_ERR_NEED_MORE_SPACE) - ->constraints(db2Table->dataFile()->getMasterDefnHandle(), - constraintSpace, - constraintSpaceLength, - &neededLen, - &cstCnt); - - if (unlikely(rc == QMY_ERR_NEED_MORE_SPACE)) - { - constraintSpaceLength = neededLen; // Get length of space that's needed - constraintSpace.realloc(constraintSpaceLength); - rc = bridge()->expectErrors(QMY_ERR_NEED_MORE_SPACE) - ->constraints(db2Table->dataFile()->getMasterDefnHandle(), - constraintSpace, - constraintSpaceLength, - &neededLen, - &cstCnt); - } - - /* If constraint information was returned by DB2, build a text string */ - /* to return to MySQL. */ - if ((rc == 0) && (cstCnt > 0)) - { - tempPtr = constraintSpace; - cstHdr = (constraint_hdr_t*)(void*)constraintSpace; // Address first constraint definition - for (int i = 0; i < cstCnt; ++i) - { - if (cstHdr->CstType[0] == QMY_CST_FK) // If this is a foreign key constraint - { - FOREIGN_KEY_INFO f_key_info; - LEX_STRING *name= 0; - tempPtr = (char*)(tempPtr + cstHdr->CstDefOff); - FKCstDef = (FK_constraint_t*)tempPtr; - - /* Process the constraint name. */ - - convFromEbcdic(FKCstDef->CstName.Name, convName,FKCstDef->CstName.Len); - if (convName[0] == '"') // If quoted, exclude quotes. - f_key_info.forein_id = thd_make_lex_string(thd, 0, - convName + 1, (uint) (FKCstDef->CstName.Len - 2), 1); - else // Not quoted - f_key_info.forein_id = thd_make_lex_string(thd, 0, - convName, (uint) FKCstDef->CstName.Len, 1); - - /* Process the names of the foreign keys. */ - - - tempPtr = (char*)(tempPtr + FKCstDef->KeyColOff); - fieldName = (cst_name_t*)tempPtr; - for (fld = 0; fld < FKCstDef->KeyCnt; ++fld) - { - convFromEbcdic(fieldName->Name, convName, fieldName->Len); - if (convName[0] == '"') // If quoted, exclude quotes. - name = thd_make_lex_string(thd, name, - convName + 1, (uint) (fieldName->Len - 2), 1); - else - name = thd_make_lex_string(thd, name, convName, (uint) fieldName->Len, 1); - f_key_info.foreign_fields.push_back(name); - if ((fld + 1) < FKCstDef->KeyCnt) - fieldName = fieldName + 1; - } - - /* Process the schema and name of the referenced table. */ - - convFromEbcdic(FKCstDef->RefSchema.Name, convName, FKCstDef->RefSchema.Len); - if (convName[0] == '"') // If quoted, exclude quotes. - f_key_info.referenced_db = thd_make_lex_string(thd, 0, - convName + 1, (uint) (FKCstDef->RefSchema.Len -2), 1); - else - f_key_info.referenced_db = thd_make_lex_string(thd, 0, - convName, (uint) FKCstDef->RefSchema.Len, 1); - convFromEbcdic(FKCstDef->RefTable.Name, convName, FKCstDef->RefTable.Len); - if (convName[0] == '"') // If quoted, exclude quotes. - f_key_info.referenced_table = thd_make_lex_string(thd, 0, - convName +1, (uint) (FKCstDef->RefTable.Len -2), 1); - else - f_key_info.referenced_table = thd_make_lex_string(thd, 0, - convName, (uint) FKCstDef->RefTable.Len, 1); - - /* Process the names of the referenced keys. */ - - tempPtr = (char*)FKCstDef; - tempPtr = (char*)(tempPtr + FKCstDef->RefColOff); - fieldName= (cst_name_t*)tempPtr; - for (fld = 0; fld < FKCstDef->RefCnt; ++fld) - { - convFromEbcdic(fieldName->Name, convName, fieldName->Len); - if (convName[0] == '"') // If quoted, exclude quotes. - name = thd_make_lex_string(thd, name, - convName + 1, (uint) (fieldName->Len -2), 1); - else - name = thd_make_lex_string(thd, name, convName, (uint) fieldName->Len, 1); - f_key_info.referenced_fields.push_back(name); - if ((fld + 1) < FKCstDef->RefCnt) - fieldName = fieldName + 1; - } - - /* Process the ON UPDATE and ON DELETE rules. */ - - switch(FKCstDef->UpdMethod) - { - case QMY_NOACTION: - { - method = "NO ACTION"; - methodLen=9; - } - break; - case QMY_RESTRICT: - { - method = "RESTRICT"; - methodLen = 8; - } - break; - default: break; - } - f_key_info.update_method = thd_make_lex_string( - thd, f_key_info.update_method, method, methodLen, 1); - switch(FKCstDef->DltMethod) - { - case QMY_CASCADE: - { - method = "CASCADE"; - methodLen = 7; - } - break; - case QMY_SETDFT: - { - method = "SET DEFAULT"; - methodLen = 11; - } - break; - case QMY_SETNULL: - { - method = "SET NULL"; - methodLen = 8; - } - break; - case QMY_NOACTION: - { - method = "NO ACTION"; - methodLen = 9; - } - break; - case QMY_RESTRICT: - { - method = "RESTRICT"; - methodLen = 8; - } - break; - default: break; - } - f_key_info.delete_method = thd_make_lex_string( - thd, f_key_info.delete_method, method, methodLen, 1); - f_key_info.referenced_key_name= thd_make_lex_string(thd, 0, (char *)"", 1, 1); - FOREIGN_KEY_INFO *pf_key_info = (FOREIGN_KEY_INFO *) - thd_memdup(thd, &f_key_info, sizeof(FOREIGN_KEY_INFO)); - f_key_list->push_back(pf_key_info); - } - - /* Address the next constraint, if any. */ - - if ((i+1) < cstCnt) - { - tempPtr = (char*)cstHdr + cstHdr->CstLen; - cstHdr = (constraint_hdr_t*)(tempPtr); - } - } - } - - /* Cleanup and return. */ - - free_share(share); - DBUG_RETURN(0); -} - -/*********************************************************************** -Checks if the table is referenced by a foreign key. -Returns: 0 if not referenced (or error occurs), - > 0 if is referenced -***********************************************************************/ - -uint ha_ibmdb2i::referenced_by_foreign_key(void) -{ - DBUG_ENTER("ha_ibmdb2i::referenced_by_foreign_key"); - - int rc = 0; - FILE_HANDLE queryFile = 0; - uint32 resultRowLen; - uint32 count = 0; - - const char* libName = db2Table->getDB2LibName(db2i_table::ASCII_SQL); - const char* fileName = db2Table->getDB2TableName(db2i_table::ASCII_SQL); - - String query(128); - query.append(STRING_WITH_LEN(" SELECT COUNT(*) FROM SYSIBM.SQLFOREIGNKEYS WHERE PKTABLE_SCHEM = '")); - query.append(libName+1, strlen(libName)-2); // parent library name - query.append(STRING_WITH_LEN("' AND PKTABLE_NAME = '")); - query.append(fileName+1, strlen(fileName)-2); // parent file name - query.append(STRING_WITH_LEN("'")); - - SqlStatementStream sqlStream(query); - - rc = bridge()->prepOpen(sqlStream.getPtrToData(), - &queryFile, - &resultRowLen); - if (rc == 0) - { - IOReadBuffer rowBuffer(1, resultRowLen); - rc = bridge()->read(queryFile, rowBuffer.ptr(), QMY_READ_ONLY, QMY_NONE, QMY_FIRST); - if (!rc) count = *((uint32*)rowBuffer.getRowN(0)); - bridge()->deallocateFile(queryFile); - } - DBUG_RETURN(count); -} diff --git a/storage/ibmdb2i/db2i_conversion.cc b/storage/ibmdb2i/db2i_conversion.cc deleted file mode 100644 index 9a85eb01c9b..00000000000 --- a/storage/ibmdb2i/db2i_conversion.cc +++ /dev/null @@ -1,1459 +0,0 @@ -/* -Licensed Materials - Property of IBM -DB2 Storage Engine Enablement -Copyright IBM Corporation 2007,2008 -All rights reserved - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - (a) Redistributions of source code must retain this list of conditions, the - copyright notice in section {d} below, and the disclaimer following this - list of conditions. - (b) Redistributions in binary form must reproduce this list of conditions, the - copyright notice in section (d) below, and the disclaimer following this - list of conditions, in the documentation and/or other materials provided - with the distribution. - (c) The name of IBM may not be used to endorse or promote products derived from - this software without specific prior written permission. - (d) The text of the required copyright notice is: - Licensed Materials - Property of IBM - DB2 Storage Engine Enablement - Copyright IBM Corporation 2007,2008 - All rights reserved - -THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - - - -#include "db2i_ileBridge.h" -#include "mysql_priv.h" -#include "db2i_charsetSupport.h" -#include "ctype.h" -#include "ha_ibmdb2i.h" -#include "db2i_errors.h" -#include "wchar.h" - -const char ZERO_DATETIME_VALUE[] = "0000-00-00 00:00:00"; -const char ZERO_DATETIME_VALUE_SUBST[] = "0001-01-01 00:00:00"; -const char ZERO_DATE_VALUE[] = "0000-00-00"; -const char ZERO_DATE_VALUE_SUBST[] = "0001-01-01"; - - -/** - Put a BCD digit into a BCD string. - - @param[out] bcdString The BCD string to be modified - @param pos The position within the string to be updated. - @param val The value to be assigned into the string at pos. -*/ -static inline void bcdAssign(char* bcdString, uint pos, uint val) -{ - bcdString[pos/2] |= val << ((pos % 2) ? 0 : 4); -} - -/** - Read a BCD digit from a BCD string. - - @param[out] bcdString The BCD string to be read - @param pos The position within the string to be read. - - @return bcdGet The value of the BCD digit at pos. -*/ -static inline uint bcdGet(const char* bcdString, uint pos) -{ - return (bcdString[pos/2] >> ((pos % 2) ? 0 : 4)) & 0xf; -} - -/** - In-place convert a number in ASCII represenation to EBCDIC representation. - - @param string The string of ASCII characters - @param len The length of string -*/ -static inline void convertNumericToEbcdicFast(char* string, int len) -{ - for (int i = 0; i < len; ++i, ++string) - { - switch(*string) - { - case '-': - *string = 0x60; break; - case ':': - *string = 0x7A; break; - case '.': - *string = 0x4B; break; - default: - DBUG_ASSERT(isdigit(*string)); - *string += 0xF0 - '0'; - break; - } - } -} - - -/** - atoi()-like function for a 4-character EBCDIC string. - - @param string The EBCDIC string - @return a4toi_ebcdic The decimal value of the EBCDIC string -*/ -static inline uint16 a4toi_ebcdic(const uchar* string) -{ - return ((string[0]-0xF0) * 1000 + - (string[1]-0xF0) * 100 + - (string[2]-0xF0) * 10 + - (string[3]-0xF0)); -}; - - -/** - atoi()-like function for a 4-character EBCDIC string. - - @param string The EBCDIC string - @return a4toi_ebcdic The decimal value of the EBCDIC string -*/ -static inline uint8 a2toi_ebcdic(const uchar* string) -{ - return ((string[0]-0xF0) * 10 + - (string[1]-0xF0)); -}; - -/** - Perform character conversion for textual field data. -*/ -int ha_ibmdb2i::convertFieldChars(enum_conversionDirection direction, - uint16 fieldID, - const char* input, - char* output, - size_t ilen, - size_t olen, - size_t* outDataLen, - bool tacitErrors, - size_t* substChars) -{ - DBUG_PRINT("ha_ibmdb2i::convertFieldChars",("Direction: %d; length = %d", direction, ilen)); - - if (unlikely(ilen == 0)) - { - if (outDataLen) *outDataLen = 0; - return (0); - } - - iconv_t& conversion = db2Table->getConversionDefinition(direction, fieldID); - - if (unlikely(conversion == (iconv_t)(-1))) - { - return (DB2I_ERR_UNSUPP_CHARSET); - } - - size_t initOLen= olen; - size_t substitutedChars = 0; - int rc = iconv(conversion, (char**)&input, &ilen, &output, &olen, &substitutedChars ); - if (outDataLen) *outDataLen = initOLen - olen; - if (substChars) *substChars = substitutedChars; - if (unlikely(rc < 0)) - { - int er = errno; - if (er == EILSEQ) - { - if (!tacitErrors) getErrTxt(DB2I_ERR_ILL_CHAR, table->field[fieldID]->field_name); - return (DB2I_ERR_ILL_CHAR); - } - else - { - if (!tacitErrors) getErrTxt(DB2I_ERR_ICONV,er); - return (DB2I_ERR_ICONV); - } - } - if (unlikely(substitutedChars) && (!tacitErrors)) - { - warning(ha_thd(), DB2I_ERR_SUB_CHARS, table->field[fieldID]->field_name); - } - - return (0); -} - -/** - Append the appropriate default value clause onto a CREATE TABLE definition - - This was inspired by get_field_default_value in sql/sql_show.cc. - - @param field The field whose value is to be obtained - @param statement The string to receive the DEFAULT clause - @param quoteIt Does the data type require single quotes around the value? - @param ccsid The ccsid of the field value (if a string type); 0 if no conversion needed -*/ -static void get_field_default_value(Field *field, - String &statement, - bool quoteIt, - uint32 ccsid, - bool substituteZeroDates) -{ - if ((field->type() != FIELD_TYPE_BLOB && - !(field->flags & NO_DEFAULT_VALUE_FLAG) && - field->unireg_check != Field::NEXT_NUMBER)) - { - my_ptrdiff_t old_ptr= (my_ptrdiff_t) (field->table->s->default_values - field->table->record[0]); - field->move_field_offset(old_ptr); - - String defaultClause(64); - defaultClause.length(0); - defaultClause.append(" DEFAULT "); - if (!field->is_null()) - { - my_bitmap_map *old_map = tmp_use_all_columns(field->table, field->table->read_set); - char tmp[MAX_FIELD_WIDTH]; - - if (field->real_type() == MYSQL_TYPE_ENUM || - field->real_type() == MYSQL_TYPE_SET) - { - CHARSET_INFO *cs= &my_charset_bin; - uint len = (uint)(cs->cset->longlong10_to_str)(cs,tmp,sizeof(tmp), 10, field->val_int()); - tmp[len]=0; - defaultClause.append(tmp); - } - else - { - String type(tmp, sizeof(tmp), field->charset()); - field->val_str(&type); - if (type.length()) - { - if (field->type() == MYSQL_TYPE_DATE && - memcmp(type.ptr(), STRING_WITH_LEN(ZERO_DATE_VALUE)) == 0) - { - if (substituteZeroDates) - type.set(STRING_WITH_LEN(ZERO_DATE_VALUE_SUBST), field->charset()); - else - { - warning(current_thd, DB2I_ERR_WARN_COL_ATTRS, field->field_name); - return; - } - } - else if ((field->type() == MYSQL_TYPE_DATETIME || - field->type() == MYSQL_TYPE_TIMESTAMP) && - memcmp(type.ptr(), STRING_WITH_LEN(ZERO_DATETIME_VALUE)) == 0) - { - if (substituteZeroDates) - type.set(STRING_WITH_LEN(ZERO_DATETIME_VALUE_SUBST), field->charset()); - else - { - warning(current_thd, DB2I_ERR_WARN_COL_ATTRS, field->field_name); - return; - } - } - - - if (field->type() != MYSQL_TYPE_STRING && - field->type() != MYSQL_TYPE_VARCHAR && - field->type() != MYSQL_TYPE_BLOB && - field->type() != MYSQL_TYPE_BIT) - { - if (quoteIt) - defaultClause.append('\''); - defaultClause.append(type); - if (quoteIt) - defaultClause.append('\''); - } - else - { - int length; - char* out; - - // If a ccsid is specified, we need to make sure that the DEFAULT - // string is converted to that encoding. - if (ccsid != 0) - { - iconv_t iconvD; - if (getConversion(toDB2, field->charset(), ccsid, iconvD)) - { - warning(current_thd, DB2I_ERR_WARN_COL_ATTRS, field->field_name); - return; - } - - size_t ilen = type.length(); - size_t olen = 6 * ilen; - size_t origOlen = olen; - const char* in = type.ptr(); - const char* tempIn = in; - out = (char*)my_malloc(olen, MYF(MY_WME)); - char* tempOut = out; - size_t substitutedChars; - - if (iconv(iconvD, (char**)&tempIn, &ilen, &tempOut, &olen, &substitutedChars) < 0) - { - warning(current_thd, DB2I_ERR_WARN_COL_ATTRS, field->field_name); - my_free(out, MYF(0)); - return; - } - // Now we process the converted string to represent it as - // hexadecimal values. - - length = origOlen - olen; - } - else - { - length = type.length(); - out = (char*)my_malloc(length*2, MYF(MY_WME)); - memcpy(out, (char*)type.ptr(), length); - } - - if (length > 16370) - { - warning(current_thd, DB2I_ERR_WARN_COL_ATTRS, field->field_name); - my_free(out, MYF(0)); - return; - } - - if (ccsid == 1200) - defaultClause.append("ux'"); - else if (ccsid == 13488) - defaultClause.append("gx'"); - else if (field->charset() == &my_charset_bin) - defaultClause.append("binary(x'"); - else - defaultClause.append("x'"); - - const char hexMap[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; - for (int c = length-1; c >= 0; --c) - { - out[c*2+1] = hexMap[out[c] & 0xF]; - out[c*2] = hexMap[out[c] >> 4]; - } - - defaultClause.append(out, length*2); - defaultClause.append('\''); - if (field->charset() == &my_charset_bin) - defaultClause.append(")"); - - my_free(out, MYF(0)); - } - } - else - defaultClause.length(0); - } - tmp_restore_column_map(field->table->read_set, old_map); - } - else if (field->maybe_null()) - defaultClause.append(STRING_WITH_LEN("NULL")); - - if (old_ptr) - field->move_field_offset(-old_ptr); - - statement.append(defaultClause); - } -} - - - - -/** - Convert a MySQL field definition into its corresponding DB2 type. - - The result will be appended to mapping as a DB2 SQL phrase. - - @param field The MySQL field to be evaluated - @param[out] mapping The receiver for the DB2 SQL syntax - @param timeFormat The format to be used for mapping the TIME type -*/ -int ha_ibmdb2i::getFieldTypeMapping(Field* field, - String& mapping, - enum_TimeFormat timeFormat, - enum_BlobMapping blobMapping, - enum_ZeroDate zeroDateHandling, - bool propagateDefaults, - enum_YearFormat yearFormat) -{ - char stringBuildBuffer[257]; - uint32 fieldLength; - bool defaultNeedsQuotes = false; - uint16 db2Ccsid = 0; - - CHARSET_INFO* fieldCharSet = field->charset(); - switch (field->type()) - { - case MYSQL_TYPE_NEWDECIMAL: - { - uint precision= ((Field_new_decimal*)field)->precision; - uint scale= field->decimals(); - - if (precision <= MAX_DEC_PRECISION) - { - sprintf(stringBuildBuffer,"DECIMAL(%d, %d)",precision,scale); - } - else - { - if (scale > precision - MAX_DEC_PRECISION) - { - scale = scale - (precision - MAX_DEC_PRECISION); - precision = MAX_DEC_PRECISION; - sprintf(stringBuildBuffer,"DECIMAL(%d, %d)",precision,scale); - } - else - { - return HA_ERR_UNSUPPORTED; - } - warning(ha_thd(), DB2I_ERR_PRECISION); - } - - mapping.append(stringBuildBuffer); - } - break; - case MYSQL_TYPE_TINY: - mapping.append(STRING_WITH_LEN("SMALLINT")); - break; - case MYSQL_TYPE_SHORT: - if (((Field_num*)field)->unsigned_flag) - mapping.append(STRING_WITH_LEN("INT")); - else - mapping.append(STRING_WITH_LEN("SMALLINT")); - break; - case MYSQL_TYPE_LONG: - if (((Field_num*)field)->unsigned_flag) - mapping.append(STRING_WITH_LEN("BIGINT")); - else - mapping.append(STRING_WITH_LEN("INT")); - break; - case MYSQL_TYPE_FLOAT: - mapping.append(STRING_WITH_LEN("REAL")); - break; - case MYSQL_TYPE_DOUBLE: - mapping.append(STRING_WITH_LEN("DOUBLE")); - break; - case MYSQL_TYPE_LONGLONG: - if (((Field_num*)field)->unsigned_flag) - mapping.append(STRING_WITH_LEN("DECIMAL(20,0)")); - else - mapping.append(STRING_WITH_LEN("BIGINT")); - break; - case MYSQL_TYPE_INT24: - mapping.append(STRING_WITH_LEN("INTEGER")); - break; - case MYSQL_TYPE_DATE: - case MYSQL_TYPE_NEWDATE: - mapping.append(STRING_WITH_LEN("DATE")); - defaultNeedsQuotes = true; - break; - case MYSQL_TYPE_TIME: - if (timeFormat == TIME_OF_DAY) - { - mapping.append(STRING_WITH_LEN("TIME")); - defaultNeedsQuotes = true; - } - else - mapping.append(STRING_WITH_LEN("INTEGER")); - break; - case MYSQL_TYPE_DATETIME: - mapping.append(STRING_WITH_LEN("TIMESTAMP")); - defaultNeedsQuotes = true; - break; - case MYSQL_TYPE_TIMESTAMP: - mapping.append(STRING_WITH_LEN("TIMESTAMP")); - - if (table_share->timestamp_field == field && propagateDefaults) - { - switch (((Field_timestamp*)field)->get_auto_set_type()) - { - case TIMESTAMP_NO_AUTO_SET: - break; - case TIMESTAMP_AUTO_SET_ON_INSERT: - mapping.append(STRING_WITH_LEN(" DEFAULT CURRENT_TIMESTAMP")); - break; - case TIMESTAMP_AUTO_SET_ON_UPDATE: - if (osVersion.v >= 6 && - !field->is_null()) - { - mapping.append(STRING_WITH_LEN(" GENERATED BY DEFAULT FOR EACH ROW ON UPDATE AS ROW CHANGE TIMESTAMP")); - warning(ha_thd(), DB2I_ERR_WARN_COL_ATTRS, field->field_name); - } - else - warning(ha_thd(), DB2I_ERR_WARN_COL_ATTRS, field->field_name); - break; - case TIMESTAMP_AUTO_SET_ON_BOTH: - if (osVersion.v >= 6 && - !field->is_null()) - mapping.append(STRING_WITH_LEN(" GENERATED BY DEFAULT FOR EACH ROW ON UPDATE AS ROW CHANGE TIMESTAMP")); - else - { - mapping.append(STRING_WITH_LEN(" DEFAULT CURRENT_TIMESTAMP")); - warning(ha_thd(), DB2I_ERR_WARN_COL_ATTRS, field->field_name); - } - break; - } - } - else - defaultNeedsQuotes = true; - break; - case MYSQL_TYPE_YEAR: - if (yearFormat == CHAR4) - { - mapping.append(STRING_WITH_LEN("CHAR(4) CCSID 1208")); - defaultNeedsQuotes = true; - } - else - { - mapping.append(STRING_WITH_LEN("SMALLINT")); - defaultNeedsQuotes = false; - } - break; - case MYSQL_TYPE_BIT: - sprintf(stringBuildBuffer, "BINARY(%d)", (field->max_display_length() / 8) + 1); - mapping.append(stringBuildBuffer); - break; - case MYSQL_TYPE_BLOB: - case MYSQL_TYPE_VARCHAR: - case MYSQL_TYPE_STRING: - { - if (field->real_type() == MYSQL_TYPE_ENUM || - field->real_type() == MYSQL_TYPE_SET) - { - mapping.append(STRING_WITH_LEN("BIGINT")); - } - else - { - defaultNeedsQuotes = true; - - fieldLength = field->max_display_length(); // Get field byte length - - if (fieldCharSet == &my_charset_bin) - { - if (field->type() == MYSQL_TYPE_STRING) - { - sprintf(stringBuildBuffer, "BINARY(%d)", max(fieldLength, 1)); - } - else - { - if (fieldLength <= MAX_VARCHAR_LENGTH) - { - sprintf(stringBuildBuffer, "VARBINARY(%d)", max(fieldLength, 1)); - } - else if (blobMapping == AS_VARCHAR && - (field->flags & PART_KEY_FLAG)) - { - sprintf(stringBuildBuffer, "LONG VARBINARY "); - } - else - { - fieldLength = min(MAX_BLOB_LENGTH, fieldLength); - sprintf(stringBuildBuffer, "BLOB(%d)", max(fieldLength, 1)); - } - } - mapping.append(stringBuildBuffer); - } - else - { - if (field->type() == MYSQL_TYPE_STRING) - { - if (fieldLength > MAX_CHAR_LENGTH) - return 1; - if (fieldCharSet->mbmaxlen > 1) - { - if (memcmp(fieldCharSet->name, "ucs2_", sizeof("ucs2_")-1) == 0 ) // UCS2 - { - sprintf(stringBuildBuffer, "GRAPHIC(%d)", max(fieldLength / fieldCharSet->mbmaxlen, 1)); // Number of characters - db2Ccsid = 13488; - } - else if (memcmp(fieldCharSet->name, "utf8_", sizeof("utf8_")-1) == 0 && - strcmp(fieldCharSet->name, "utf8_general_ci") != 0) - { - sprintf(stringBuildBuffer, "CHAR(%d)", max(fieldLength, 1)); // Number of bytes - db2Ccsid = 1208; - } - else - { - sprintf(stringBuildBuffer, "GRAPHIC(%d)", max(fieldLength / fieldCharSet->mbmaxlen, 1)); // Number of characters - db2Ccsid = 1200; - } - } - else - { - sprintf(stringBuildBuffer, "CHAR(%d)", max(fieldLength, 1)); - } - mapping.append(stringBuildBuffer); - } - else - { - if (fieldLength <= MAX_VARCHAR_LENGTH) - { - if (fieldCharSet->mbmaxlen > 1) - { - if (memcmp(fieldCharSet->name, "ucs2_", sizeof("ucs2_")-1) == 0 ) // UCS2 - { - sprintf(stringBuildBuffer, "VARGRAPHIC(%d)", max(fieldLength / fieldCharSet->mbmaxlen, 1)); // Number of characters - db2Ccsid = 13488; - } - else if (memcmp(fieldCharSet->name, "utf8_", sizeof("utf8_")-1) == 0 && - strcmp(fieldCharSet->name, "utf8_general_ci") != 0) - { - sprintf(stringBuildBuffer, "VARCHAR(%d)", max(fieldLength, 1)); // Number of bytes - db2Ccsid = 1208; - } - else - { - sprintf(stringBuildBuffer, "VARGRAPHIC(%d)", max(fieldLength / fieldCharSet->mbmaxlen, 1)); // Number of characters - db2Ccsid = 1200; - } - } - else - { - sprintf(stringBuildBuffer, "VARCHAR(%d)", max(fieldLength, 1)); - } - } - else if (blobMapping == AS_VARCHAR && - (field->flags & PART_KEY_FLAG)) - { - if (fieldCharSet->mbmaxlen > 1) - { - if (memcmp(fieldCharSet->name, "ucs2_", sizeof("ucs2_")-1) == 0 ) // UCS2 - { - sprintf(stringBuildBuffer, "LONG VARGRAPHIC "); - db2Ccsid = 13488; - } - else if (memcmp(fieldCharSet->name, "utf8_", sizeof("utf8_")-1) == 0 && - strcmp(fieldCharSet->name, "utf8_general_ci") != 0) - { - sprintf(stringBuildBuffer, "LONG VARCHAR "); - db2Ccsid = 1208; - } - else - { - sprintf(stringBuildBuffer, "LONG VARGRAPHIC "); - db2Ccsid = 1200; - } - } - else - { - sprintf(stringBuildBuffer, "LONG VARCHAR "); - } - } - else - { - fieldLength = min(MAX_BLOB_LENGTH, fieldLength); - - if (fieldCharSet->mbmaxlen > 1) - { - if (memcmp(fieldCharSet->name, "ucs2_", sizeof("ucs2_")-1) == 0 ) // UCS2 - { - sprintf(stringBuildBuffer, "DBCLOB(%d)", max(fieldLength / fieldCharSet->mbmaxlen, 1)); // Number of characters - db2Ccsid = 13488; - } - else if (memcmp(fieldCharSet->name, "utf8_", sizeof("utf8_")-1) == 0 && - strcmp(fieldCharSet->name, "utf8_general_ci") != 0) - { - sprintf(stringBuildBuffer, "CLOB(%d)", max(fieldLength, 1)); // Number of bytes - db2Ccsid = 1208; - } - else - { - sprintf(stringBuildBuffer, "DBCLOB(%d)", max(fieldLength / fieldCharSet->mbmaxlen, 1)); // Number of characters - db2Ccsid = 1200; - } - } - else - { - sprintf(stringBuildBuffer, "CLOB(%d)", max(fieldLength, 1)); // Number of characters - } - } - - mapping.append(stringBuildBuffer); - } - if (db2Ccsid == 0) // If not overriding CCSID - { - int32 rtnCode = convertIANAToDb2Ccsid(fieldCharSet->csname, &db2Ccsid); - if (rtnCode) - return rtnCode; - } - - if (db2Ccsid != 1208 && - db2Ccsid != 13488) - { - // Check whether there is a character conversion available. - iconv_t temp; - int32 rc = getConversion(toDB2, fieldCharSet, db2Ccsid, temp); - if (unlikely(rc)) - return rc; - } - - sprintf(stringBuildBuffer, " CCSID %d ", db2Ccsid); - mapping.append(stringBuildBuffer); - } - } - } - break; - - } - - if (propagateDefaults) - get_field_default_value(field, - mapping, - defaultNeedsQuotes, - db2Ccsid, - (zeroDateHandling==SUBSTITUTE_0001_01_01)); - - return 0; -} - - -/** - Convert MySQL field data into the equivalent DB2 format - - @param field The MySQL field to be converted - @param db2Field The corresponding DB2 field definition - @param db2Buf The buffer to receive the converted data - @param data NULL if field points to the correct data; otherwise, - the data to be converted (for use with keys) -*/ -int32 ha_ibmdb2i::convertMySQLtoDB2(Field* field, const DB2Field& db2Field, char* db2Buf, const uchar* data) -{ - enum_field_types fieldType = field->type(); - switch (fieldType) - { - case MYSQL_TYPE_NEWDECIMAL: - { - uint precision= ((Field_new_decimal*)field)->precision; - uint scale= field->decimals(); - uint db2Precision = min(precision, MAX_DEC_PRECISION); - uint truncationAmount = precision - db2Precision; - - if (scale >= truncationAmount) - { - String tempString(precision+2); - - if (data == NULL) - { - field->val_str((String*)&tempString, (String*)(NULL)); - } - else - { - field->val_str(&tempString, data); - } - const char* temp = tempString.ptr(); - char packed[32]; - memset(&packed, 0, sizeof(packed)); - - int bcdPos = db2Precision - (db2Precision % 2 ? 1 : 0); - bcdAssign(packed, bcdPos+1, (temp[0] == '-' ? 0xD : 0xF)); - - int strPos=tempString.length() - 1 - truncationAmount; - - for (;strPos >= 0 && bcdPos >= 0; strPos--) - { - if (my_isdigit(&my_charset_latin1, temp[strPos])) - { - bcdAssign(packed, bcdPos, temp[strPos]-'0'); - --bcdPos; - } - } - memcpy(db2Buf, &packed, (db2Precision/2)+1); - } - - } - break; - case MYSQL_TYPE_TINY: - { - int16 temp = (data == NULL ? field->val_int() : field->val_int(data)); - memcpy(db2Buf , &temp, sizeof(temp)); - } - break; - case MYSQL_TYPE_SHORT: - { - if (((Field_num*)field)->unsigned_flag) - { - memset(db2Buf, 0, 2); - memcpy(db2Buf+2, (data == NULL ? field->ptr : data), 2); - } - else - { - memcpy(db2Buf, (data == NULL ? field->ptr : data), 2); - } - } - break; - case MYSQL_TYPE_LONG: - { - if (((Field_num*)field)->unsigned_flag) - { - memset(db2Buf, 0, 4); - memcpy(db2Buf+4, (data == NULL ? field->ptr : data), 4); - } - else - { - memcpy(db2Buf, (data == NULL ? field->ptr : data), 4); - } - } - break; - case MYSQL_TYPE_FLOAT: - { - memcpy(db2Buf, (data == NULL ? field->ptr : data), 4); - } - break; - case MYSQL_TYPE_DOUBLE: - { - memcpy(db2Buf, (data == NULL ? field->ptr : data), 8); - } - break; - case MYSQL_TYPE_TIMESTAMP: - case MYSQL_TYPE_DATETIME: - { - String tempString(27); - if (data == NULL) - { - field->val_str(&tempString, &tempString); - } - else - { - field->val_str(&tempString, data); - } - memset(db2Buf, '0', 26); - memcpy(db2Buf, tempString.ptr(), tempString.length()); - if (strncmp(db2Buf,ZERO_DATETIME_VALUE,strlen(ZERO_DATETIME_VALUE)) == 0) - { - if (cachedZeroDateOption == SUBSTITUTE_0001_01_01) - memcpy(db2Buf, ZERO_DATETIME_VALUE_SUBST, sizeof(ZERO_DATETIME_VALUE_SUBST)); - else - { - getErrTxt(DB2I_ERR_INVALID_COL_VALUE, field->field_name); - return(DB2I_ERR_INVALID_COL_VALUE); - } - } - (db2Buf)[10] = '-'; - (db2Buf)[13] = (db2Buf)[16] = (db2Buf)[19] = '.'; - - convertNumericToEbcdicFast(db2Buf, 26); - } - break; - case MYSQL_TYPE_LONGLONG: - { - if (((Field_num*)field)->unsigned_flag) - { - char temp[23]; - String tempString(temp, sizeof(temp), &my_charset_latin1); - - if (data == NULL) - { - field->val_str((String*)&tempString, (String*)(NULL)); - } - else - { - field->val_str(&tempString, data); - } - char packed[11]; - memset(packed, 0, sizeof(packed)); - bcdAssign(packed, 21, (temp[0] == '-' ? 0xD : 0xF)); - int strPos=tempString.length()-1; - int bcdPos=20; - - for (;strPos >= 0; strPos--) - { - if (my_isdigit(&my_charset_latin1, temp[strPos])) - { - bcdAssign(packed, bcdPos, temp[strPos]-'0'); - --bcdPos; - } - } - memcpy(db2Buf, &packed, 11); - } - else - { - *(uint64*)db2Buf = *(uint64*)(data == NULL ? field->ptr : data); - } - } - break; - case MYSQL_TYPE_INT24: - { - int32 temp= (data == NULL ? field->val_int() : field->val_int(data)); - memcpy(db2Buf , &temp, sizeof(temp)); - } - break; - case MYSQL_TYPE_DATE: - case MYSQL_TYPE_NEWDATE: - { - String tempString(11); - if (data == NULL) - { - field->val_str(&tempString, (String*)NULL); - } - else - { - field->val_str(&tempString, data); - } - memcpy(db2Buf, tempString.ptr(), 10); - if (strncmp(db2Buf,ZERO_DATE_VALUE,strlen(ZERO_DATE_VALUE)) == 0) - { - if (cachedZeroDateOption == SUBSTITUTE_0001_01_01) - memcpy(db2Buf, ZERO_DATE_VALUE_SUBST, sizeof(ZERO_DATE_VALUE_SUBST)); - else - { - getErrTxt(DB2I_ERR_INVALID_COL_VALUE,field->field_name); - return(DB2I_ERR_INVALID_COL_VALUE); - } - } - - convertNumericToEbcdicFast(db2Buf,10); - } - break; - case MYSQL_TYPE_TIME: - { - if (db2Field.getType() == QMY_TIME) - { - String tempString(10); - if (data == NULL) - { - field->val_str(&tempString, (String*)NULL); - } - else - { - field->val_str(&tempString, data); - } - memcpy(db2Buf, tempString.ptr(), 8); - (db2Buf)[2]=(db2Buf)[5] = '.'; - - convertNumericToEbcdicFast(db2Buf, 8); - } - else - { - int32 temp = sint3korr(data == NULL ? field->ptr : data); - memcpy(db2Buf, &temp, sizeof(temp)); - } - } - break; - case MYSQL_TYPE_YEAR: - { - String tempString(5); - if (db2Field.getType() == QMY_CHAR) - { - if (data == NULL) - { - field->val_str(&tempString, (String*)NULL); - } - else - { - field->val_str(&tempString, data); - } - memcpy(db2Buf, tempString.ptr(), 4); - } - else - { - uint8 temp = *(uint8*)(data == NULL ? field->ptr : data); - *(uint16*)(db2Buf) = (temp ? temp + 1900 : 0); - } - } - break; - case MYSQL_TYPE_BIT: - { - int bytesToCopy = db2Field.getByteLengthInRecord(); - - if (data == NULL) - { - uint64 temp = field->val_int(); - memcpy(db2Buf, - ((char*)&temp) + (sizeof(temp) - bytesToCopy), - bytesToCopy); - } - else - { - memcpy(db2Buf, - data, - bytesToCopy); - } - } - break; - case MYSQL_TYPE_VARCHAR: - case MYSQL_TYPE_STRING: - case MYSQL_TYPE_BLOB: - { - if (field->real_type() == MYSQL_TYPE_ENUM || - field->real_type() == MYSQL_TYPE_SET) - { - int64 temp= (data == NULL ? field->val_int() : field->val_int(data)); - *(int64*)db2Buf = temp; - } - else - { - const uchar* dataToStore; - uint32 bytesToStore; - uint32 bytesToPad = 0; - CHARSET_INFO* fieldCharSet = field->charset(); - uint32 maxDisplayLength = field->max_display_length(); - switch (fieldType) - { - case MYSQL_TYPE_STRING: - { - bytesToStore = maxDisplayLength; - if (data == NULL) - dataToStore = field->ptr; - else - dataToStore = data; - } - break; - case MYSQL_TYPE_VARCHAR: - { - - if (data == NULL) - { - bytesToStore = field->data_length(); - dataToStore = field->ptr + ((Field_varstring*)field)->length_bytes; - } - else - { - // Key lens are stored little-endian - bytesToStore = *(uint8*)data + ((*(uint8*)(data+1)) << 8); - dataToStore = data + 2; - } - bytesToPad = maxDisplayLength - bytesToStore; - } - break; - case MYSQL_TYPE_BLOB: - { - if (data == NULL) - { - bytesToStore = ((Field_blob*)field)->get_length(); - bytesToPad = maxDisplayLength - bytesToStore; - ((Field_blob*)field)->get_ptr((uchar**)&dataToStore); - } - else - { - // Key lens are stored little-endian - bytesToStore = *(uint8*)data + ((*(uint8*)(data+1)) << 8); - dataToStore = data + 2; - } - } - break; - } - - int32 rc; - uint16 db2FieldType = db2Field.getType(); - switch(db2FieldType) - { - case QMY_CHAR: - if (maxDisplayLength == 0) - bytesToPad = 1; - case QMY_VARCHAR: - if (db2FieldType == QMY_VARCHAR) - { - db2Buf += sizeof(uint16); - bytesToPad = 0; - } - - if (bytesToStore > db2Field.getDataLengthInRecord()) - { - bytesToStore = db2Field.getDataLengthInRecord(); - field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1); - } - - if (fieldCharSet == &my_charset_bin) // If binary - { - if (bytesToStore) - memcpy(db2Buf, dataToStore, bytesToStore); - if (bytesToPad) - memset(db2Buf + bytesToStore, 0x00, bytesToPad); - } - else if (db2Field.getCCSID() == 1208) // utf8 - { - if (bytesToStore) - memcpy(db2Buf, dataToStore, bytesToStore); - if (bytesToPad) - memset(db2Buf + bytesToStore, ' ', bytesToPad); - } - else // single-byte ASCII to EBCDIC - { - DBUG_ASSERT(fieldCharSet->mbmaxlen == 1); - if (bytesToStore) - { - rc = convertFieldChars(toDB2, field->field_index, (char*)dataToStore, db2Buf, bytesToStore, bytesToStore, NULL); - if (rc) - return rc; - } - if (bytesToPad) - memset(db2Buf + bytesToStore, 0x40, bytesToPad); - } - - if (db2FieldType == QMY_VARCHAR) - *(uint16*)(db2Buf - sizeof(uint16)) = bytesToStore; - break; - case QMY_VARGRAPHIC: - db2Buf += sizeof(uint16); - bytesToPad = 0; - case QMY_GRAPHIC: - if (maxDisplayLength == 0 && db2FieldType == QMY_GRAPHIC) - bytesToPad = 2; - - if (db2Field.getCCSID() == 13488) - { - if (bytesToStore) - memcpy(db2Buf, dataToStore, bytesToStore); - if (bytesToPad) - memset16((db2Buf + bytesToStore), 0x0020, bytesToPad/2); - } - else - { - size_t db2BytesToStore; - size_t maxDb2BytesToStore; - - if (maxDisplayLength == 0 && db2FieldType == QMY_GRAPHIC) - maxDb2BytesToStore = 2; - else - maxDb2BytesToStore = min(((bytesToStore * 2) / fieldCharSet->mbminlen), - ((maxDisplayLength * 2) / fieldCharSet->mbmaxlen)); - - if (bytesToStore == 0) - db2BytesToStore = 0; - else - { - rc = convertFieldChars(toDB2, field->field_index, (char*)dataToStore, db2Buf, bytesToStore, maxDb2BytesToStore, &db2BytesToStore); - if (rc) - return rc; - bytesToStore = db2BytesToStore; - } - if (db2BytesToStore < maxDb2BytesToStore) // If need to pad - memset16((db2Buf + db2BytesToStore), 0x0020, (maxDb2BytesToStore - db2BytesToStore)/2); - } - - if (db2FieldType == QMY_VARGRAPHIC) - *(uint16*)(db2Buf-sizeof(uint16)) = bytesToStore/2; - break; - case QMY_BLOBCLOB: - case QMY_DBCLOB: - { - DBUG_ASSERT(data == NULL); - DB2LobField* lobField = (DB2LobField*)(db2Buf + db2Field.calcBlobPad()); - - if ((fieldCharSet == &my_charset_bin) || // binary or - (db2Field.getCCSID()==13488) || - (db2Field.getCCSID()==1208)) // binary UTF8 - { - } - else - { - char* temp; - int32 rc; - size_t db2BytesToStore; - if (fieldCharSet->mbmaxlen == 1) // single-byte ASCII to EBCDIC - { - temp = getCharacterConversionBuffer(field->field_index, bytesToStore); - rc = convertFieldChars(toDB2, field->field_index, (char*)dataToStore,temp,bytesToStore, bytesToStore, NULL); - if (rc) - return (rc); - } - else // Else Far East, special UTF8 or non-special UTF8/UCS2 - { - size_t maxDb2BytesToStore; - maxDb2BytesToStore = min(((bytesToStore * 2) / fieldCharSet->mbminlen), - ((maxDisplayLength * 2) / fieldCharSet->mbmaxlen)); - temp = getCharacterConversionBuffer(field->field_index, maxDb2BytesToStore); - rc = convertFieldChars(toDB2, field->field_index, (char*)dataToStore,temp,bytesToStore, maxDb2BytesToStore, &db2BytesToStore); - if (rc) - return (rc); - bytesToStore = db2BytesToStore; - } - dataToStore = (uchar*)temp; - } - - uint16 blobID = db2Table->getBlobIdFromField(field->field_index); - if (blobWriteBuffers[blobID] != (char*)dataToStore) - blobWriteBuffers[blobID].reassign((char*)dataToStore); - if ((void*)blobWriteBuffers[blobID]) - lobField->dataHandle = (ILEMemHandle)blobWriteBuffers[blobID]; - else - lobField->dataHandle = 0; - lobField->length = bytesToStore / (db2FieldType == QMY_DBCLOB ? 2 : 1); - } - break; - } - } - } - break; - default: - DBUG_ASSERT(0); - break; - } - - return (ha_thd()->is_error()); -} - - -/** - Convert DB2 field data into the equivalent MySQL format - - @param db2Field The DB2 field definition - @param field The MySQL field to receive the converted data - @param buf The DB2 data to be converted -*/ -int32 ha_ibmdb2i::convertDB2toMySQL(const DB2Field& db2Field, Field* field, const char* buf) -{ - int32 storeRC = 0; // Result of the field->store() operation - - const char* bufPtr = buf + db2Field.getBufferOffset(); - - switch (field->type()) - { - case MYSQL_TYPE_NEWDECIMAL: - { - uint precision= ((Field_new_decimal*)field)->precision; - uint scale= field->decimals(); - uint db2Precision = min(precision, MAX_DEC_PRECISION); - uint decimalPlace = precision-scale+1; - char temp[80]; - - if (precision <= MAX_DEC_PRECISION || - scale > precision - MAX_DEC_PRECISION) - { - uint numNibbles = db2Precision + (db2Precision % 2 ? 0 : 1); - - temp[0] = (bcdGet(bufPtr, numNibbles) == 0xD ? '-' : ' '); - int strPos=1; - int bcdPos=(db2Precision % 2 ? 0 : 1); - - for (;bcdPos < numNibbles; bcdPos++, strPos++) - { - if (strPos == decimalPlace) - { - temp[strPos] = '.'; - strPos++; - } - - temp[strPos] = bcdGet(bufPtr, bcdPos) + '0'; - } - - temp[strPos] = 0; - - storeRC = field->store(temp, strPos, &my_charset_latin1); - } - } - break; - case MYSQL_TYPE_TINY: - { - storeRC = field->store(*(int16*)bufPtr, ((Field_num*)field)->unsigned_flag); - } - break; - case MYSQL_TYPE_SHORT: - { - if (((Field_num*)field)->unsigned_flag) - { - storeRC = field->store(*(int32*)bufPtr, TRUE); - } - else - { - storeRC = field->store(*(int16*)bufPtr, FALSE); - } - } - break; - case MYSQL_TYPE_LONG: - { - if (((Field_num*)field)->unsigned_flag) - { - storeRC = field->store(*(int64*)bufPtr, TRUE); - } - else - { - storeRC = field->store(*(int32*)bufPtr, FALSE); - } - } - break; - case MYSQL_TYPE_FLOAT: - { - storeRC = field->store(*(float*)bufPtr); - } - break; - case MYSQL_TYPE_DOUBLE: - { - storeRC = field->store(*(double*)bufPtr); - } - break; - case MYSQL_TYPE_LONGLONG: - { - char temp[23]; - if (((Field_num*)field)->unsigned_flag) - { - temp[0] = (bcdGet(bufPtr, 21) == 0xD ? '-' : ' '); - int strPos=1; - int bcdPos=0; - - for (;bcdPos <= 20; bcdPos++, strPos++) - { - temp[strPos] = bcdGet(bufPtr, bcdPos) + '0'; - } - - temp[strPos] = 0; - - storeRC = field->store(temp, strPos, &my_charset_latin1); - } - else - { - storeRC = field->store(*(int64*)bufPtr, FALSE); - } - } - break; - case MYSQL_TYPE_INT24: - { - storeRC = field->store(*(int32*)bufPtr, ((Field_num*)field)->unsigned_flag); - } - break; - case MYSQL_TYPE_DATE: - case MYSQL_TYPE_NEWDATE: - { - longlong value= a4toi_ebcdic((uchar*)bufPtr) * 10000 + - a2toi_ebcdic((uchar*)bufPtr+5) * 100 + - a2toi_ebcdic((uchar*)bufPtr+8); - - if (cachedZeroDateOption == SUBSTITUTE_0001_01_01 && - value == (10000 + 100 + 1)) - value = 0; - - storeRC = field->store(value); - } - break; - case MYSQL_TYPE_TIME: - { - if (db2Field.getType() == QMY_TIME) - { - longlong value= a2toi_ebcdic((uchar*)bufPtr) * 10000 + - a2toi_ebcdic((uchar*)bufPtr+3) * 100 + - a2toi_ebcdic((uchar*)bufPtr+6); - - storeRC = field->store(value); - } - else - storeRC = field->store(*((int32*)bufPtr)); - } - break; - case MYSQL_TYPE_TIMESTAMP: - case MYSQL_TYPE_DATETIME: - { - longlong value= (a4toi_ebcdic((uchar*)bufPtr) * 10000 + - a2toi_ebcdic((uchar*)bufPtr+5) * 100 + - a2toi_ebcdic((uchar*)bufPtr+8)) * 1000000LL + - (a2toi_ebcdic((uchar*)bufPtr+11) * 10000 + - a2toi_ebcdic((uchar*)bufPtr+14) * 100 + - a2toi_ebcdic((uchar*)bufPtr+17)); - - if (cachedZeroDateOption == SUBSTITUTE_0001_01_01 && - value == (10000 + 100 + 1) * 1000000LL) - value = 0; - - storeRC = field->store(value); - } - break; - case MYSQL_TYPE_YEAR: - { - if (db2Field.getType() == QMY_CHAR) - { - storeRC = field->store(bufPtr, 4, &my_charset_bin); - } - else - { - storeRC = field->store(*((uint16*)bufPtr)); - } - } - break; - case MYSQL_TYPE_BIT: - { - uint64 temp= 0; - int bytesToCopy= db2Field.getByteLengthInRecord(); - memcpy(((char*)&temp) + (sizeof(temp) - bytesToCopy), bufPtr, bytesToCopy); - storeRC = field->store(temp, TRUE); - } - break; - case MYSQL_TYPE_VARCHAR: - case MYSQL_TYPE_STRING: - case MYSQL_TYPE_BLOB: - { - if (field->real_type() == MYSQL_TYPE_ENUM || - field->real_type() == MYSQL_TYPE_SET) - { - storeRC = field->store(*(int64*)bufPtr); - } - else - { - - const char* dataToStore = NULL; - uint32 bytesToStore = 0; - CHARSET_INFO* fieldCharSet = field->charset(); - switch(db2Field.getType()) - { - case QMY_CHAR: - case QMY_GRAPHIC: - { - bytesToStore = db2Field.getByteLengthInRecord(); - if (bytesToStore == 0) - bytesToStore = 1; - dataToStore = bufPtr; - } - break; - case QMY_VARCHAR: - { - bytesToStore = *(uint16*)bufPtr; - dataToStore = bufPtr+sizeof(uint16); - } - break; - case QMY_VARGRAPHIC: - { - /* For VARGRAPHIC, convert the number of double-byte characters - to the number of bytes. */ - bytesToStore = (*(uint16*)bufPtr)*2; - dataToStore = bufPtr+sizeof(uint16); - } - break; - case QMY_DBCLOB: - case QMY_BLOBCLOB: - { - DB2LobField* lobField = (DB2LobField* )(bufPtr + db2Field.calcBlobPad()); - bytesToStore = lobField->length * (db2Field.getType() == QMY_DBCLOB ? 2 : 1); - dataToStore = (char*)blobReadBuffers->getBufferPtr(field->field_index); - } - break; - - } - - if ((fieldCharSet != &my_charset_bin) && // not binary & - (db2Field.getCCSID() != 13488) && // not UCS2 & - (db2Field.getCCSID() != 1208)) - { - char* temp; - size_t db2BytesToStore; - int rc; - if (fieldCharSet->mbmaxlen > 1) - { - size_t maxDb2BytesToStore = ((bytesToStore / 2) * fieldCharSet->mbmaxlen); // Worst case for number of bytes - temp = getCharacterConversionBuffer(field->field_index, maxDb2BytesToStore); - rc = convertFieldChars(toMySQL, field->field_index, dataToStore, temp, bytesToStore, maxDb2BytesToStore, &db2BytesToStore); - bytesToStore = db2BytesToStore; - } - else // single-byte ASCII to EBCDIC - { - temp = getCharacterConversionBuffer(field->field_index, bytesToStore); - rc = convertFieldChars(toMySQL, field->field_index, dataToStore, temp, bytesToStore, bytesToStore, NULL); - } - if (rc) - return (rc); - dataToStore = temp; - } - - if ((field)->flags & BLOB_FLAG) - ((Field_blob*)(field))->set_ptr(bytesToStore, (uchar*)dataToStore); - else - storeRC = field->store(dataToStore, bytesToStore, &my_charset_bin); - } - } - break; - default: - DBUG_ASSERT(0); - break; - - } - - if (storeRC) - { - invalidDataFound = true; - } - - return 0; -} diff --git a/storage/ibmdb2i/db2i_errors.cc b/storage/ibmdb2i/db2i_errors.cc deleted file mode 100644 index dd50e40e61b..00000000000 --- a/storage/ibmdb2i/db2i_errors.cc +++ /dev/null @@ -1,297 +0,0 @@ -/* -Licensed Materials - Property of IBM -DB2 Storage Engine Enablement -Copyright IBM Corporation 2007,2008 -All rights reserved - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - (a) Redistributions of source code must retain this list of conditions, the - copyright notice in section {d} below, and the disclaimer following this - list of conditions. - (b) Redistributions in binary form must reproduce this list of conditions, the - copyright notice in section (d) below, and the disclaimer following this - list of conditions, in the documentation and/or other materials provided - with the distribution. - (c) The name of IBM may not be used to endorse or promote products derived from - this software without specific prior written permission. - (d) The text of the required copyright notice is: - Licensed Materials - Property of IBM - DB2 Storage Engine Enablement - Copyright IBM Corporation 2007,2008 - All rights reserved - -THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - - -#include "db2i_errors.h" -#include "db2i_ileBridge.h" -#include "db2i_charsetSupport.h" -#include "mysql_priv.h" -#include "stdarg.h" - -#define MAX_MSGSTRING 109 - -/* - The following strings are associated with errors that can be produced - within the storage engine proper. -*/ -static const char* engineErrors[MAX_MSGSTRING] = -{ - {""}, - {"Error opening codeset conversion from %.64s to %.64s (errno = %d)"}, - {"Invalid %-.10s name '%-.128s'"}, - {"Unsupported move from '%-.128s' to '%-.128s' on RENAME TABLE statement"}, - {"The %-.64s character set is not supported."}, - {"Auto_increment is not allowed for a partitioned table"}, - {"Character set conversion error due to unknown encoding scheme %d"}, - {""}, - {"Table '%-.128s' was not found by the storage engine"}, - {"Could not resolve to %-.128s in library %-.10s type %-.10s (errno = %d)"}, - {"Error on _PGMCALL for program %-.10s in library %-.10s (error = %d)"}, - {"Error on _ILECALL for API '%.128s' (error = %d)"}, - {"Error in iconv() function during character set conversion (errno = %d)"}, - {"Error from Get Encoding Scheme (QTQGESP) API: %d, %d, %d"}, - {"Error from Get Related Default CCSID (QTQGRDC) API: %d, %d, %d"}, - {"Data out of range for column '%.192s'"}, - {"Schema name '%.128s' exceeds maximum length of %d characters"}, - {"Multiple collations not supported in a single index or constraint"}, - {"Sort sequence was not found"}, - {"One or more characters in column %.128s were substituted during conversion"}, - {"A decimal column exceeded the maximum precision. Data may be truncated."}, - {"Some data returned by DB2 for table %s could not be converted for MySQL"}, - {""}, - {"Column %.128s contains characters that cannot be converted"}, - {"An invalid name was specified for ibmdb2i_rdb_name."}, - {"A duplicate key was encountered for index '%.128s'"}, - {"A table with the same name exists but has incompatible column definitions."}, - {"The created table was discovered as an existing DB2 object."}, - {"Some attribute(s) defined for column '%.128s' may not be honored by accesses from DB2."}, -}; - -/* - The following strings are associated with errors that can be returned - by the operating system via the QMY_* APIs. Most are very uncommon and - indicate a bug somewhere. -*/ -static const char* systemErrors[MAX_MSGSTRING] = -{ - {"Thread ID is too long"}, - {"Error creating a SPACE memory object"}, - {"Error creating a FILE memory object"}, - {"Error creating a SPACE synchronization token"}, - {"Error creating a FILE synchronization token"}, - {"See message %-.7s in joblog for job %-.6s/%-.10s/%-.10s."}, - {"Error unlocking a synchronization token when closing a connection"}, - {"Invalid action specified for an 'object lock' request"}, - {"Invalid action specified for a savepoint request"}, - {"Partial keys are not supported with an ICU sort sequence"}, - {"Error retrieving an ICU sort key"}, - {"Error converting single-byte sort sequence to UCS-2"}, - {"An unsupported collation was specified"}, - {"Validation failed for referenced table of foreign key constraint"}, - {"Error extracting table for constraint information"}, - {"Error extracting referenced table for constraint information"}, - {"Invalid action specified for a 'commitment control' request"}, - {"Invalid commitment control isolation level specified on 'open' request"}, - {"Invalid file handle"}, - {" "}, - {"Invalid option specified for returning data on 'read' request"}, - {"Invalid orientation specified for 'read' request"}, - {"Invalid option type specified for 'read' request"}, - {"Invalid isolation level for starting commitment control"}, - {"Error unlocking a synchronization token in module QMYALC"}, - {"Length of space for returned format is not long enough"}, - {"SQL XA transactions are currently unsupported by this interface"}, - {"The associated QSQSRVR job was killed or ended unexpectedly."}, - {"Error unlocking a synchronization token in module QMYSEI"}, - {"Error unlocking a synchronization token in module QMYSPO"}, - {"Error converting input CCSID from short form to long form"}, - {" "}, - {"Error getting associated CCSID for CCSID conversion"}, - {"Error converting a string from one CCSID to another"}, - {"Error unlocking a synchronization token"}, - {"Error destroying a synchronization token"}, - {"Error locking a synchronization token"}, - {"Error recreating a synchronization token"}, - {"A space handle was not specified for a constraint request"}, - {"An SQL cursor was specified for a delete request"}, - {" "}, - {"Error on delete request because current UFCB for connection is not open"}, - {"An SQL cursor was specified for an object initialization request"}, - {"An SQL cursor was specified for an object override request"}, - {"A space handle was not specified for an object override request"}, - {"An SQL cursor was specified for an information request"}, - {"An SQL cursor was specified for an object lock request"}, - {"An SQL cursor was specified for an optimize request"}, - {"A data handle was not specified for a read request"}, - {"A row number handle was not specified for a read request"}, - {"A key handle was not specified for a read request"}, - {"An SQL cursor was specified for an row estimation request"}, - {"A space handle was not specified for a row estimation request"}, - {"An SQL cursor was specified for a release record request"}, - {"A statement handle was not specified for an 'execute immediate' request"}, - {"A statement handle was not specified for a 'prepare open' request"}, - {"An SQL cursor was specified for an update request"}, - {"The UFCB was not open for read"}, - {"Error on update request because current UFCB for connection is not open"}, - {"A data handle was not specified for an update request"}, - {"An SQL cursor was specified for a write request"}, - {"A data handle was not specified for a write request"}, - {"An unknown function was specified on a process request"}, - {"A share definition was not specified for an 'allocate share' request"}, - {"A share handle was not specified for an 'allocate share' request"}, - {"A use count handle was not specified for an 'allocate share' request"}, - {"A 'records per key' handle was not specified for an information request"}, - {"Error resolving LOB addresss"}, - {"Length of a LOB space is too small"}, - {"An unknown function was specified for a server request"}, - {"Object authorization failed. See message %-.7s in joblog for job %-.6s/%-.10s/%-.10s. for more information."}, - {" "}, - {"Error locking mutex on server"}, - {"Error unlocking mutex on server"}, - {"Error checking for RDB name in RDB Directory"}, - {"Error creating mutex on server"}, - {"A table with that name already exists"}, - {" "}, - {"Error unlocking mutex"}, - {"Error connecting to server job"}, - {"Error connecting to server job"}, - {" "}, - {"Function check occurred while registering parameter spaces. See joblog."}, - {" "}, - {" "}, - {"End of block"}, - {"The file has changed and might not be compatible with the MySQL table definition"}, - {"Error giving pipe to server job"}, - {"There are open object locks when attempting to deallocate"}, - {"There is no open lock"}, - {" "}, - {" "}, - {"The maximum value for the auto_increment data type was exceeded"}, - {"Error occurred closing the pipe "}, - {"Error occurred taking a descriptor for the pipe"}, - {"Error writing to pipe "}, - {"Server was interrupted "}, - {"No pipe descriptor exists for reuse "}, - {"Error occurred during an SQL prepare statement "}, - {"Error occurred during an SQL open "}, - {" "}, - {" "}, - {" "}, - {" "}, - {" "}, - {" "}, - {"An unspecified error was returned from the system."}, - {" "} -}; - -/** - This function builds the text string for an error code, and substitutes - a variable number of replacement variables into the string. -*/ -void getErrTxt(int errCode, ...) -{ - va_list args; - va_start(args,errCode); - char* buffer = db2i_ileBridge::getBridgeForThread()->getErrorStorage(); - const char* msg; - - if (errCode >= QMY_ERR_MIN && errCode <= QMY_ERR_SQ_OPEN) - msg = systemErrors[errCode - QMY_ERR_MIN]; - else - { - DBUG_ASSERT(errCode >= DB2I_FIRST_ERR && errCode <= DB2I_LAST_ERR); - msg = engineErrors[errCode - DB2I_FIRST_ERR]; - } - - (void) my_vsnprintf (buffer, MYSQL_ERRMSG_SIZE, msg, args); - va_end(args); - fprintf(stderr,"ibmdb2i error %d: %s\n",errCode,buffer); - DBUG_PRINT("error", ("ibmdb2i error %d: %s",errCode,buffer)); -} - -static inline void trimSpace(char* str) -{ - char* end = strchr(str, ' '); - if (end) *end = 0; -} - - -/** - Generate the error text specific to an API error returned by a QMY_* API. - - @parm errCode The error value - @parm errInfo The structure containing the message and job identifiers. -*/ -void reportSystemAPIError(int errCode, const Qmy_Error_output *errInfo) -{ - if (errCode >= QMY_ERR_MIN && errCode <= QMY_ERR_SQ_OPEN) - { - switch(errCode) - { - case QMY_ERR_MSGID: - case QMY_ERR_NOT_AUTH: - { - DBUG_ASSERT(errInfo); - char jMsg[8]; // Error message ID - char jName[11]; // Job name - char jUser[11]; // Job user - char jNbr[7]; // Job number - memset(jMsg, 0, sizeof(jMsg)); - memset(jName, 0, sizeof(jMsg)); - memset(jUser, 0, sizeof(jMsg)); - memset(jMsg, 0, sizeof(jMsg)); - - convFromEbcdic(errInfo->MsgId,jMsg,sizeof(jMsg)-1); - convFromEbcdic(errInfo->JobName,jName,sizeof(jName)-1); - trimSpace(jName); - convFromEbcdic(errInfo->JobUser,jUser,sizeof(jUser)-1); - trimSpace(jUser); - convFromEbcdic(errInfo->JobNbr,jNbr,sizeof(jNbr)-1); - getErrTxt(errCode,jMsg,jNbr,jUser,jName); - } - break; - case QMY_ERR_RTNFMT: - { - getErrTxt(QMY_ERR_LVLID_MISMATCH); - } - break; - default: - getErrTxt(errCode); - break; - } - } -} - - -/** - Generate a warning for the specified error. -*/ -void warning(THD *thd, int errCode, ...) -{ - va_list args; - va_start(args,errCode); - char buffer[MYSQL_ERRMSG_SIZE]; - const char* msg; - - DBUG_ASSERT(errCode >= DB2I_FIRST_ERR && errCode <= DB2I_LAST_ERR); - msg = engineErrors[errCode - DB2I_FIRST_ERR]; - - (void) my_vsnprintf (buffer, MYSQL_ERRMSG_SIZE, msg, args); - va_end(args); - DBUG_PRINT("warning", ("ibmdb2i warning %d: %s",errCode,buffer)); - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, errCode, buffer); -} - - diff --git a/storage/ibmdb2i/db2i_errors.h b/storage/ibmdb2i/db2i_errors.h deleted file mode 100644 index b6dd314ef50..00000000000 --- a/storage/ibmdb2i/db2i_errors.h +++ /dev/null @@ -1,93 +0,0 @@ -/* -Licensed Materials - Property of IBM -DB2 Storage Engine Enablement -Copyright IBM Corporation 2007,2008 -All rights reserved - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - (a) Redistributions of source code must retain this list of conditions, the - copyright notice in section {d} below, and the disclaimer following this - list of conditions. - (b) Redistributions in binary form must reproduce this list of conditions, the - copyright notice in section (d) below, and the disclaimer following this - list of conditions, in the documentation and/or other materials provided - with the distribution. - (c) The name of IBM may not be used to endorse or promote products derived from - this software without specific prior written permission. - (d) The text of the required copyright notice is: - Licensed Materials - Property of IBM - DB2 Storage Engine Enablement - Copyright IBM Corporation 2007,2008 - All rights reserved - -THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - - -#ifndef DB2I_ERRORS_H -#define DB2I_ERRORS_H - -#include "qmyse.h" -class THD; - -/** - @enum DB2I_errors - - @brief These are the errors that can be returned by the storage engine proper - and that are specific to the engine. Refer to db2i_errors.cc for text - descriptions of the errors. -*/ - -enum DB2I_errors -{ - DB2I_FIRST_ERR = 2500, - DB2I_ERR_ICONV_OPEN, - DB2I_ERR_INVALID_NAME, - DB2I_ERR_RENAME_MOVE, - DB2I_ERR_UNSUPP_CHARSET, - DB2I_ERR_PART_AUTOINC, - DB2I_ERR_UNKNOWN_ENCODING, - DB2I_ERR_RESERVED, - DB2I_ERR_TABLE_NOT_FOUND, - DB2I_ERR_RESOLVE_OBJ, - DB2I_ERR_PGMCALL, - DB2I_ERR_ILECALL, - DB2I_ERR_ICONV, - DB2I_ERR_QTQGESP, - DB2I_ERR_QTQGRDC, - DB2I_ERR_INVALID_COL_VALUE, - DB2I_ERR_TOO_LONG_SCHEMA, - DB2I_ERR_MIXED_COLLATIONS, - DB2I_ERR_SRTSEQ, - DB2I_ERR_SUB_CHARS, - DB2I_ERR_PRECISION, - DB2I_ERR_INVALID_DATA, - DB2I_ERR_RESERVED2, - DB2I_ERR_ILL_CHAR, - DB2I_ERR_BAD_RDB_NAME, - DB2I_ERR_UNKNOWN_IDX, - DB2I_ERR_DISCOVERY_MISMATCH, - DB2I_ERR_WARN_CREATE_DISCOVER, - DB2I_ERR_WARN_COL_ATTRS, - DB2I_LAST_ERR = DB2I_ERR_WARN_COL_ATTRS -}; - -void getErrTxt(int errcode, ...); -void reportSystemAPIError(int errCode, const Qmy_Error_output *errInfo); -void warning(THD *thd, int errCode, ...); - -const char* DB2I_SQL0350 = "\xE2\xD8\xD3\xF0\xF3\xF5\xF0"; // SQL0350 in EBCDIC -const char* DB2I_CPF503A = "\xC3\xD7\xC6\xF5\xF0\xF3\xC1"; // CPF503A in EBCDIC -const char* DB2I_SQL0538 = "\xE2\xD8\xD3\xF0\xF5\xF3\xF8"; // SQL0538 in EBCDIC - -#endif diff --git a/storage/ibmdb2i/db2i_file.cc b/storage/ibmdb2i/db2i_file.cc deleted file mode 100644 index a16aa927527..00000000000 --- a/storage/ibmdb2i/db2i_file.cc +++ /dev/null @@ -1,556 +0,0 @@ -/* -Licensed Materials - Property of IBM -DB2 Storage Engine Enablement -Copyright IBM Corporation 2007,2008 -All rights reserved - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - (a) Redistributions of source code must retain this list of conditions, the - copyright notice in section {d} below, and the disclaimer following this - list of conditions. - (b) Redistributions in binary form must reproduce this list of conditions, the - copyright notice in section (d) below, and the disclaimer following this - list of conditions, in the documentation and/or other materials provided - with the distribution. - (c) The name of IBM may not be used to endorse or promote products derived from - this software without specific prior written permission. - (d) The text of the required copyright notice is: - Licensed Materials - Property of IBM - DB2 Storage Engine Enablement - Copyright IBM Corporation 2007,2008 - All rights reserved - -THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - - - -#include "db2i_file.h" -#include "db2i_charsetSupport.h" -#include "db2i_collationSupport.h" -#include "db2i_misc.h" -#include "db2i_errors.h" -#include "my_dir.h" - -db2i_table::db2i_table(const TABLE_SHARE* myTable, const char* path) : - mysqlTable(myTable), - db2StartId(0), - blobFieldCount(0), - blobFields(NULL), - blobFieldActualSizes(NULL), - logicalFiles(NULL), - physicalFile(NULL), - db2TableNameSQLAscii(NULL), - db2LibNameSQLAscii(NULL) -{ - char asciiLibName[MAX_DB2_SCHEMANAME_LENGTH + 1]; - getDB2LibNameFromPath(path, asciiLibName, ASCII_NATIVE); - - char asciiFileName[MAX_DB2_FILENAME_LENGTH + 1]; - getDB2FileNameFromPath(path, asciiFileName, ASCII_NATIVE); - - size_t libNameLen = strlen(asciiLibName); - size_t fileNameLen = strlen(asciiFileName); - - db2LibNameEbcdic=(char *) - my_multi_malloc(MYF(MY_WME | MY_ZEROFILL), - &db2LibNameEbcdic, libNameLen+1, - &db2LibNameAscii, libNameLen+1, - &db2LibNameSQLAscii, libNameLen*2 + 1, - &db2TableNameEbcdic, fileNameLen+1, - &db2TableNameAscii, fileNameLen+1, - &db2TableNameSQLAscii, fileNameLen*2 + 1, - NullS); - - if (likely(db2LibNameEbcdic)) - { - memcpy(db2LibNameAscii, asciiLibName, libNameLen); - convertNativeToSQLName(db2LibNameAscii, db2LibNameSQLAscii); - convToEbcdic(db2LibNameAscii, db2LibNameEbcdic, libNameLen); - memcpy(db2TableNameAscii, asciiFileName, fileNameLen); - convertNativeToSQLName(db2TableNameAscii, db2TableNameSQLAscii); - convToEbcdic(db2TableNameAscii, db2TableNameEbcdic, fileNameLen); - } - - conversionDefinitions[toMySQL] = NULL; - conversionDefinitions[toDB2] = NULL; - - isTemporaryTable = (strstr(mysqlTable->path.str, mysql_tmpdir) == mysqlTable->path.str); -} - - -int32 db2i_table::initDB2Objects(const char* path) -{ - uint fileObjects = 1 + mysqlTable->keys; - ValidatedPointer fileDefnSpace(sizeof(ShrDef) * fileObjects); - - physicalFile = new db2i_file(this); - physicalFile->fillILEDefn(&fileDefnSpace[0], true); - - logicalFileCount = mysqlTable->keys; - if (logicalFileCount > 0) - { - logicalFiles = new db2i_file*[logicalFileCount]; - for (int k = 0; k < logicalFileCount; k++) - { - logicalFiles[k] = new db2i_file(this, k); - logicalFiles[k]->fillILEDefn(&fileDefnSpace[k+1], false); - } - } - - ValidatedPointer fileDefnHandles(sizeof(FILE_HANDLE) * fileObjects); - size_t formatSpaceLen = sizeof(format_hdr_t) + mysqlTable->fields * sizeof(DB2Field); - formatSpace.alloc(formatSpaceLen); - - int rc = db2i_ileBridge::getBridgeForThread()-> - expectErrors(QMY_ERR_RTNFMT)-> - allocateFileDefn(fileDefnSpace, - fileDefnHandles, - fileObjects, - db2LibNameEbcdic, - strlen(db2LibNameEbcdic), - formatSpace, - formatSpaceLen); - - if (rc) - { - // We have to handle a format space error as a special case of a FID - // mismatch. We should only get the space error if columns have been added - // to the DB2 table without MySQL's knowledge, which is effectively a - // FID problem. - if (rc == QMY_ERR_RTNFMT) - { - rc = QMY_ERR_LVLID_MISMATCH; - getErrTxt(rc); - } - return rc; - } - - convFromEbcdic(((format_hdr_t*)formatSpace)->FilLvlId, fileLevelID, sizeof(fileLevelID)); - - if (!doFileIDsMatch(path)) - { - getErrTxt(QMY_ERR_LVLID_MISMATCH); - return QMY_ERR_LVLID_MISMATCH; - } - - physicalFile->setMasterDefnHandle(fileDefnHandles[0]); - for (int k = 0; k < mysqlTable->keys; k++) - { - logicalFiles[k]->setMasterDefnHandle(fileDefnHandles[k+1]); - } - - db2StartId = (uint64)(((format_hdr_t*)formatSpace)->StartIdVal); - db2Fields = (DB2Field*)((char*)(void*)formatSpace + ((format_hdr_t*)formatSpace)->ColDefOff); - - uint fields = mysqlTable->fields; - for (int i = 0; i < fields; ++i) - { - if (db2Field(i).isBlob()) - { - blobFieldCount++; - } - } - - if (blobFieldCount) - { - blobFieldActualSizes = (uint*)my_multi_malloc(MYF(MY_WME | MY_ZEROFILL), - &blobFieldActualSizes, blobFieldCount * sizeof(uint), - &blobFields, blobFieldCount * sizeof(uint16), - NullS); - - int b = 0; - for (int i = 0; i < fields; ++i) - { - if (db2Field(i).isBlob()) - { - blobFields[b++] = i; - } - } - } - - my_multi_malloc(MYF(MY_WME), - &conversionDefinitions[toMySQL], fields * sizeof(iconv_t), - &conversionDefinitions[toDB2], fields * sizeof(iconv_t), - NullS); - for (int i = 0; i < fields; ++i) - { - conversionDefinitions[toMySQL][i] = (iconv_t)(-1); - conversionDefinitions[toDB2][i] = (iconv_t)(-1); - } - - return 0; -} - -int db2i_table::fastInitForCreate(const char* path) -{ - ValidatedPointer fileDefnSpace(sizeof(ShrDef)); - - physicalFile = new db2i_file(this); - physicalFile->fillILEDefn(fileDefnSpace, true); - - ValidatedPointer fileDefnHandles(sizeof(FILE_HANDLE)); - - size_t formatSpaceLen = sizeof(format_hdr_t) + - mysqlTable->fields * sizeof(DB2Field); - formatSpace.alloc(formatSpaceLen); - - int rc = db2i_ileBridge::getBridgeForThread()->allocateFileDefn(fileDefnSpace, - fileDefnHandles, - 1, - db2LibNameEbcdic, - strlen(db2LibNameEbcdic), - formatSpace, - formatSpaceLen); - - if (rc) - return rc; - - convFromEbcdic(((format_hdr_t*)formatSpace)->FilLvlId, fileLevelID, sizeof(fileLevelID)); - doFileIDsMatch(path); - - return 0; -} - -bool db2i_table::doFileIDsMatch(const char* path) -{ - char name_buff[FN_REFLEN]; - - fn_format(name_buff, path, "", FID_EXT, (MY_REPLACE_EXT | MY_UNPACK_FILENAME)); - - File fd = my_open(name_buff, O_RDONLY, MYF(0)); - - if (fd == -1) - { - if (errno == ENOENT) - { - fd = my_create(name_buff, 0, O_WRONLY, MYF(MY_WME)); - - if (fd == -1) - { - // TODO: Report errno here - return false; - } - my_write(fd, (uchar*)fileLevelID, sizeof(fileLevelID), MYF(MY_WME)); - my_close(fd, MYF(0)); - return true; - } - else - { - // TODO: Report errno here - return false; - } - } - - char diskFID[sizeof(fileLevelID)]; - - bool match = false; - - if (my_read(fd, (uchar*)diskFID, sizeof(diskFID), MYF(MY_WME)) == sizeof(diskFID) && - (memcmp(diskFID, fileLevelID, sizeof(diskFID)) == 0)) - match = true; - - my_close(fd, MYF(0)); - - return match; -} - -void db2i_table::deleteAssocFiles(const char* name) -{ - char name_buff[FN_REFLEN]; - fn_format(name_buff, name, "", FID_EXT, (MY_REPLACE_EXT | MY_UNPACK_FILENAME)); - my_delete(name_buff, MYF(0)); -} - -void db2i_table::renameAssocFiles(const char* from, const char* to) -{ - rename_file_ext(from, to, FID_EXT); -} - - -db2i_table::~db2i_table() -{ - if (blobFieldActualSizes) - my_free(blobFieldActualSizes, MYF(0)); - - if (conversionDefinitions[toMySQL]) - my_free(conversionDefinitions[toMySQL], MYF(0)); - - if (logicalFiles) - { - for (int k = 0; k < logicalFileCount; ++k) - { - delete logicalFiles[k]; - } - - delete[] logicalFiles; - } - delete physicalFile; - - my_free(db2LibNameEbcdic, 0); -} - -void db2i_table::getDB2QualifiedName(char* to) -{ - strcat(to, getDB2LibName(ASCII_SQL)); - strcat(to, "."); - strcat(to, getDB2TableName(ASCII_SQL)); -} - - -void db2i_table::getDB2QualifiedNameFromPath(const char* path, char* to) -{ - getDB2LibNameFromPath(path, to); - strcat(to, "."); - getDB2FileNameFromPath(path, strend(to)); -} - - -size_t db2i_table::smartFilenameToTableName(const char *in, char* out, size_t outlen) -{ - if (strchr(in, '@') == NULL) - { - return filename_to_tablename(in, out, outlen); - } - - char* test = (char*) my_malloc(outlen, MYF(MY_WME)); - - filename_to_tablename(in, test, outlen); - - char* cur = test; - - while (*cur) - { - if ((*cur <= 0x20) || (*cur >= 0x80)) - { - strncpy(out, in, outlen); - my_free(test, MYF(0)); - return min(outlen, strlen(out)); - } - ++cur; - } - - strncpy(out, test, outlen); - my_free(test, MYF(0)); - return min(outlen, strlen(out)); -} - -void db2i_table::filenameToTablename(const char* in, char* out, size_t outlen) -{ - if (strchr(in, '#') == NULL) - { - smartFilenameToTableName(in, out, outlen); - return; - } - - char* temp = (char*)sql_alloc(outlen); - - const char* part1, *part2, *part3, *part4; - part1 = in; - part2 = strstr(part1, "#P#"); - if (part2); - { - part3 = part2 + 3; - part4 = strchr(part3, '#'); - if (!part4) - part4 = strend(in); - } - - memcpy(temp, part1, min(outlen, part2 - part1)); - temp[min(outlen-1, part2-part1)] = 0; - - int32 accumLen = smartFilenameToTableName(temp, out, outlen); - - if (part2 && (accumLen + 4 < outlen)) - { - strcat(out, "#P#"); - accumLen += 4; - - memset(temp, 0, min(outlen, part2-part1)); - memcpy(temp, part3, min(outlen, part4-part3)); - temp[min(outlen-1, part4-part3)] = 0; - - accumLen += smartFilenameToTableName(temp, strend(out), outlen-accumLen); - - if (part4 && (accumLen + (strend(in) - part4 + 1) < outlen)) - { - strcat(out, part4); - } - } -} - -void db2i_table::getDB2LibNameFromPath(const char* path, char* lib, NameFormatFlags format) -{ - if (strstr(path, mysql_tmpdir) == path) - { - strcpy(lib, DB2I_TEMP_TABLE_SCHEMA); - } - else - { - const char* c = strend(path) - 1; - while (c > path && *c != '\\' && *c != '/') - --c; - - if (c != path) - { - const char* dbEnd = c; - do { - --c; - } while (c >= path && *c != '\\' && *c != '/'); - - if (c >= path) - { - const char* dbStart = c+1; - char fileName[FN_REFLEN]; - memcpy(fileName, dbStart, dbEnd - dbStart); - fileName[dbEnd-dbStart] = 0; - - char dbName[MAX_DB2_SCHEMANAME_LENGTH+1]; - filenameToTablename(fileName, dbName , sizeof(dbName)); - - convertMySQLNameToDB2Name(dbName, lib, sizeof(dbName), true, (format==ASCII_SQL) ); - } - else - DBUG_ASSERT(0); // This should never happen! - } - } -} - -void db2i_table::getDB2FileNameFromPath(const char* path, char* file, NameFormatFlags format) -{ - const char* fileEnd = strend(path); - const char* c = fileEnd; - while (c > path && *c != '\\' && *c != '/') - --c; - - if (c != path) - { - const char* fileStart = c+1; - char fileName[FN_REFLEN]; - memcpy(fileName, fileStart, fileEnd - fileStart); - fileName[fileEnd - fileStart] = 0; - char db2Name[MAX_DB2_FILENAME_LENGTH+1]; - filenameToTablename(fileName, db2Name, sizeof(db2Name)); - convertMySQLNameToDB2Name(db2Name, file, sizeof(db2Name), true, (format==ASCII_SQL) ); - } -} - -// Generates the DB2 index name when given the MySQL index and table names. -int32 db2i_table::appendQualifiedIndexFileName(const char* indexName, - const char* tableName, - String& to, - NameFormatFlags format, - enum_DB2I_INDEX_TYPE type) -{ - char generatedName[MAX_DB2_FILENAME_LENGTH+1]; - strncpy(generatedName, indexName, DB2I_INDEX_NAME_LENGTH_TO_PRESERVE); - generatedName[DB2I_INDEX_NAME_LENGTH_TO_PRESERVE] = 0; - char* endOfGeneratedName; - - if (type == typeDefault) - { - strcat(generatedName, DB2I_DEFAULT_INDEX_NAME_DELIMITER); - endOfGeneratedName = strend(generatedName); - } - else if (type != typeNone) - { - strcat(generatedName, DB2I_ADDL_INDEX_NAME_DELIMITER); - endOfGeneratedName = strend(generatedName); - *(endOfGeneratedName-2) = char(type); - } - - uint lenWithoutFile = endOfGeneratedName - generatedName; - - char strippedTableName[MAX_DB2_FILENAME_LENGTH+1]; - if (format == ASCII_SQL) - { - strcpy(strippedTableName, tableName); - stripExtraQuotes(strippedTableName+1, sizeof(strippedTableName)); - tableName = strippedTableName; - } - - if (strlen(tableName) > (MAX_DB2_FILENAME_LENGTH-lenWithoutFile)) - return -1; - - strncat(generatedName, - tableName+1, - min(strlen(tableName), (MAX_DB2_FILENAME_LENGTH-lenWithoutFile))-2 ); - - char finalName[MAX_DB2_FILENAME_LENGTH+1]; - convertMySQLNameToDB2Name(generatedName, finalName, sizeof(finalName), true, (format==ASCII_SQL)); - to.append(finalName); - - return 0; -} - - -void db2i_table::findConversionDefinition(enum_conversionDirection direction, uint16 fieldID) -{ - getConversion(direction, - mysqlTable->field[fieldID]->charset(), - db2Field(fieldID).getCCSID(), - conversionDefinitions[direction][fieldID]); -} - - -db2i_file::db2i_file(db2i_table* table) : db2Table(table) -{ - commonCtorInit(); - - DBUG_ASSERT(table->getMySQLTable()->table_name.length <= MAX_DB2_FILENAME_LENGTH-2); - - db2FileName = (char*)table->getDB2TableName(db2i_table::EBCDIC_NATIVE); -} - -db2i_file::db2i_file(db2i_table* table, int index) : db2Table(table) -{ - commonCtorInit(); - - if ((index == table->getMySQLTable()->primary_key) && !table->isTemporary()) - { - db2FileName = (char*)table->getDB2TableName(db2i_table::EBCDIC_NATIVE); - } - else - { - // Generate the index name (in index___table form); quote and EBCDICize it. - String qualifiedPath; - qualifiedPath.length(0); - - const char* asciiFileName = table->getDB2TableName(db2i_table::ASCII_NATIVE); - - db2i_table::appendQualifiedIndexFileName(table->getMySQLTable()->key_info[index].name, - asciiFileName, - qualifiedPath, - db2i_table::ASCII_NATIVE, - typeDefault); - - db2FileName = (char*)my_malloc(qualifiedPath.length()+1, MYF(MY_WME | MY_ZEROFILL)); - convToEbcdic(qualifiedPath.ptr(), db2FileName, qualifiedPath.length()); - } -} - -void db2i_file::commonCtorInit() -{ - masterDefn = 0; - memset(&formats, 0, maxRowFormats*sizeof(RowFormat)); -} - - -void db2i_file::fillILEDefn(ShrDef* defn, bool readInArrivalSeq) -{ - defn->ObjNamLen = strlen(db2FileName); - DBUG_ASSERT(defn->ObjNamLen <= sizeof(defn->ObjNam)); - memcpy(defn->ObjNam, db2FileName, defn->ObjNamLen); - defn->ArrSeq[0] = (readInArrivalSeq ? QMY_YES : QMY_NO); -} - diff --git a/storage/ibmdb2i/db2i_file.h b/storage/ibmdb2i/db2i_file.h deleted file mode 100644 index 7b63b18c315..00000000000 --- a/storage/ibmdb2i/db2i_file.h +++ /dev/null @@ -1,445 +0,0 @@ -/* -Licensed Materials - Property of IBM -DB2 Storage Engine Enablement -Copyright IBM Corporation 2007,2008 -All rights reserved - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - (a) Redistributions of source code must retain this list of conditions, the - copyright notice in section {d} below, and the disclaimer following this - list of conditions. - (b) Redistributions in binary form must reproduce this list of conditions, the - copyright notice in section (d) below, and the disclaimer following this - list of conditions, in the documentation and/or other materials provided - with the distribution. - (c) The name of IBM may not be used to endorse or promote products derived from - this software without specific prior written permission. - (d) The text of the required copyright notice is: - Licensed Materials - Property of IBM - DB2 Storage Engine Enablement - Copyright IBM Corporation 2007,2008 - All rights reserved - -THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - - -#ifndef DB2I_FILE_H -#define DB2I_FILE_H - -#include "db2i_global.h" -#include "db2i_ileBridge.h" -#include "db2i_validatedPointer.h" -#include "db2i_iconv.h" -#include "db2i_charsetSupport.h" - -const char FID_EXT[] = ".FID"; - -class db2i_file; - -#pragma pack(1) -struct DB2LobField -{ - char reserved1; - uint32 length; - char reserved2[4]; - uint32 ordinal; - ILEMemHandle dataHandle; - char reserved3[8]; -}; -#pragma pack(pop) - -class DB2Field -{ - public: - uint16 getType() const { return *(uint16*)(&definition.ColType); } - uint16 getByteLengthInRecord() const { return definition.ColLen; } - uint16 getDataLengthInRecord() const - { - return (getType() == QMY_VARCHAR || getType() == QMY_VARGRAPHIC ? definition.ColLen - 2 : definition.ColLen); - } - uint16 getCCSID() const { return *(uint16*)(&definition.ColCCSID); } - bool isBlob() const - { - uint16 type = getType(); - return (type == QMY_BLOBCLOB || type == QMY_DBCLOB); - } - uint16 getBufferOffset() const { return definition.ColBufOff; } - uint16 calcBlobPad() const - { - DBUG_ASSERT(isBlob()); - return getByteLengthInRecord() - sizeof (DB2LobField); - } - DB2LobField* asBlobField(char* buf) const - { - DBUG_ASSERT(isBlob()); - return (DB2LobField*)(buf + getBufferOffset() + calcBlobPad()); - } - private: - col_def_t definition; -}; - - -/** - @class db2i_table - - @details - This class describes the logical SQL table provided by DB2. - It stores "table-scoped" information such as the name of the - DB2 schema, BLOB descriptions, and the corresponding MySQL table definition. - Only one instance exists per SQL table. -*/ -class db2i_table -{ - public: - enum NameFormatFlags - { - ASCII_SQL, - ASCII_NATIVE, - EBCDIC_NATIVE - }; - - db2i_table(const TABLE_SHARE* myTable, const char* path = NULL); - - ~db2i_table(); - - int32 initDB2Objects(const char* path); - - const TABLE_SHARE* getMySQLTable() const - { - return mysqlTable; - } - - uint64 getStartId() const - { - return db2StartId; - } - - void updateStartId(uint64 newStartId) - { - db2StartId = newStartId; - } - - bool hasBlobs() const - { - return (blobFieldCount > 0); - } - - uint16 getBlobCount() const - { - return blobFieldCount; - } - - uint getBlobFieldActualSize(uint fieldIndex) const - { - return blobFieldActualSizes[getBlobIdFromField(fieldIndex)]; - } - - void updateBlobFieldActualSize(uint fieldIndex, uint32 newSize) - { - // It's OK that this isn't threadsafe, since this is just an advisory - // value. If a race condition causes the lesser of two values to be stored, - // that's OK. - uint16 blobID = getBlobIdFromField(fieldIndex); - DBUG_ASSERT(blobID < blobFieldCount); - - if (blobFieldActualSizes[blobID] < newSize) - { - blobFieldActualSizes[blobID] = newSize; - } - } - - - - const char* getDB2LibName(NameFormatFlags format = EBCDIC_NATIVE) - { - switch (format) - { - case EBCDIC_NATIVE: - return db2LibNameEbcdic; break; - case ASCII_NATIVE: - return db2LibNameAscii; break; - case ASCII_SQL: - return db2LibNameSQLAscii; break; - default: - DBUG_ASSERT(0); - } - return NULL; - } - - const char* getDB2TableName(NameFormatFlags format = EBCDIC_NATIVE) const - { - switch (format) - { - case EBCDIC_NATIVE: - return db2TableNameEbcdic; break; - case ASCII_NATIVE: - return db2TableNameAscii; break; - case ASCII_SQL: - return db2TableNameAscii; break; - break; - default: - DBUG_ASSERT(0); - } - return NULL; - } - - DB2Field& db2Field(int fieldID) const { return db2Fields[fieldID]; } - DB2Field& db2Field(const Field* field) const { return db2Field(field->field_index); } - - void processFormatSpace(); - - void* getFormatSpace(size_t& spaceNeeded) - { - DBUG_ASSERT(formatSpace == NULL); - spaceNeeded = sizeof(format_hdr_t) + mysqlTable->fields * sizeof(DB2Field); - formatSpace.alloc(spaceNeeded); - return (void*)formatSpace; - } - - bool isTemporary() const - { - return isTemporaryTable; - } - - void getDB2QualifiedName(char* to); - static void getDB2LibNameFromPath(const char* path, char* lib, NameFormatFlags format=ASCII_SQL); - static void getDB2FileNameFromPath(const char* path, char* file, NameFormatFlags format=ASCII_SQL); - static void getDB2QualifiedNameFromPath(const char* path, char* to); - static int32 appendQualifiedIndexFileName(const char* indexName, - const char* tableName, - String& to, - NameFormatFlags format=ASCII_SQL, - enum_DB2I_INDEX_TYPE type=typeDefault); - - uint16 getBlobIdFromField(uint16 fieldID) const - { - for (int i = 0; i < blobFieldCount; ++i) - { - if (blobFields[i] == fieldID) - return i; - } - DBUG_ASSERT(0); - return 0; - } - - iconv_t& getConversionDefinition(enum_conversionDirection direction, - uint16 fieldID) - { - if (conversionDefinitions[direction][fieldID] == (iconv_t)(-1)) - findConversionDefinition(direction, fieldID); - - return conversionDefinitions[direction][fieldID]; - } - - const db2i_file* dataFile() const - { - return physicalFile; - } - - const db2i_file* indexFile(uint idx) const - { - return logicalFiles[idx]; - } - - const char* getFileLevelID() const - { - return fileLevelID; - } - - static void deleteAssocFiles(const char* name); - static void renameAssocFiles(const char* from, const char* to); - - int fastInitForCreate(const char* path); - int initDiscoveredTable(const char* path); - - uint16* blobFields; - -private: - - void findConversionDefinition(enum_conversionDirection direction, uint16 fieldID); - static void filenameToTablename(const char* in, char* out, size_t outlen); - static size_t smartFilenameToTableName(const char *in, char* out, size_t outlen); - void convertNativeToSQLName(const char* input, - char* output) - { - - output[0] = input[0]; - - uint o = 1; - uint i = 1; - do - { - output[o++] = input[i]; - if (input[i] == '"' && input[i+1]) - output[o++] = '"'; - } while (input[++i]); - - output[o] = 0; // This isn't the most user-friendly way to handle overflows, - // but at least its safe. - } - - bool doFileIDsMatch(const char* path); - - ValidatedPointer formatSpace; - DB2Field* db2Fields; - uint64 db2StartId; // Starting value for identity column - uint16 blobFieldCount; // Count of LOB fields in the DB2 table - uint* blobFieldActualSizes; // Array of LOB field lengths (actual vs. allocated). - // This is updated as LOBs are read and will contain - // the length of the longest known LOB in that field. - iconv_t* conversionDefinitions[2]; - - const TABLE_SHARE* mysqlTable; - uint16 logicalFileCount; - char* db2LibNameEbcdic; // Quoted and in EBCDIC - char* db2LibNameAscii; - char* db2TableNameEbcdic; - char* db2TableNameAscii; - char* db2TableNameSQLAscii; - char* db2LibNameSQLAscii; - - db2i_file* physicalFile; - db2i_file** logicalFiles; - - bool isTemporaryTable; - char fileLevelID[13]; -}; - -/** - @class db2i_file - - @details This class describes a file object underlaying a particular SQL - table. Both "physical files" (data) and "logical files" (indices) are - described by this class. Only one instance of the class exists per DB2 file - object. The single instance is responsible for de/allocating the multiple - handles used by the handlers. -*/ -class db2i_file -{ - -public: - struct RowFormat - { - uint16 readRowLen; - uint16 readRowNullOffset; - uint16 writeRowLen; - uint16 writeRowNullOffset; - char inited; - }; - -public: - - // Construct an instance for a physical file. - db2i_file(db2i_table* table); - - // Construct an instance for a logical file. - db2i_file(db2i_table* table, int index); - - ~db2i_file() - { - if (masterDefn) - db2i_ileBridge::getBridgeForThread()->deallocateFile(masterDefn); - - if (db2FileName != (char*)db2Table->getDB2TableName(db2i_table::EBCDIC_NATIVE)) - my_free(db2FileName, MYF(0)); - } - - // This is roughly equivalent to an "open". It tells ILE to allocate a descriptor - // for the file. The associated handle is returned to the caller. - int allocateNewInstance(FILE_HANDLE* newHandle, ILEMemHandle inuseSpace) const - { - int rc; - - rc = db2i_ileBridge::getBridgeForThread()->allocateFileInstance(masterDefn, - inuseSpace, - newHandle); - - if (rc) *newHandle = 0; - - return rc; - } - - // This obtains the row layout associated with a particular access intent for - // an open instance of the file. - int obtainRowFormat(FILE_HANDLE instanceHandle, - char intent, - char commitLevel, - const RowFormat** activeFormat) const - { - DBUG_ENTER("db2i_file::obtainRowFormat"); - RowFormat* rowFormat; - - if (intent == QMY_UPDATABLE) - rowFormat = &(formats[readWrite]); - else if (intent == QMY_READ_ONLY) - rowFormat = &(formats[readOnly]); - - if (unlikely(!rowFormat->inited)) - { - int rc = db2i_ileBridge::getBridgeForThread()-> - initFileForIO(instanceHandle, - intent, - commitLevel, - &(rowFormat->writeRowLen), - &(rowFormat->writeRowNullOffset), - &(rowFormat->readRowLen), - &(rowFormat->readRowNullOffset)); - if (rc) DBUG_RETURN(rc); - rowFormat->inited = 1; - } - - *activeFormat = rowFormat; - DBUG_RETURN(0); - } - - const char* getDB2FileName() const - { - return db2FileName; - } - - void fillILEDefn(ShrDef* defn, bool readInArrivalSeq); - - void setMasterDefnHandle(FILE_HANDLE handle) - { - masterDefn = handle; - } - - FILE_HANDLE getMasterDefnHandle() const - { - return masterDefn; - } - -private: - enum RowFormats - { - readOnly = 0, - readWrite, - maxRowFormats - }; - - mutable RowFormat formats[maxRowFormats]; - - void commonCtorInit(); - - char* db2FileName; // Quoted and in EBCDIC - - db2i_table* db2Table; // The logical SQL table contained by this file. - - bool db2CanSort; - - FILE_HANDLE masterDefn; -}; - - -#endif diff --git a/storage/ibmdb2i/db2i_global.h b/storage/ibmdb2i/db2i_global.h deleted file mode 100644 index d201fbd8124..00000000000 --- a/storage/ibmdb2i/db2i_global.h +++ /dev/null @@ -1,138 +0,0 @@ -/* -Licensed Materials - Property of IBM -DB2 Storage Engine Enablement -Copyright IBM Corporation 2007,2008 -All rights reserved - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - (a) Redistributions of source code must retain this list of conditions, the - copyright notice in section {d} below, and the disclaimer following this - list of conditions. - (b) Redistributions in binary form must reproduce this list of conditions, the - copyright notice in section (d) below, and the disclaimer following this - list of conditions, in the documentation and/or other materials provided - with the distribution. - (c) The name of IBM may not be used to endorse or promote products derived from - this software without specific prior written permission. - (d) The text of the required copyright notice is: - Licensed Materials - Property of IBM - DB2 Storage Engine Enablement - Copyright IBM Corporation 2007,2008 - All rights reserved - -THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - - -#ifndef DB2I_GLOBAL_H -#define DB2I_GLOBAL_H - -#define MYSQL_SERVER 1 - -#include "my_global.h" -#include "my_sys.h" - -const uint MAX_DB2_KEY_PARTS=120; -const int MAX_DB2_V5R4_LIBNAME_LENGTH = 10; -const int MAX_DB2_V6R1_LIBNAME_LENGTH = 30; -const int MAX_DB2_SCHEMANAME_LENGTH=258; -const int MAX_DB2_FILENAME_LENGTH=258; -const int MAX_DB2_COLNAME_LENGTH=128; -const int MAX_DB2_SAVEPOINTNAME_LENGTH=128; -const int MAX_DB2_QUALIFIEDNAME_LENGTH=MAX_DB2_V6R1_LIBNAME_LENGTH + 1 + MAX_DB2_FILENAME_LENGTH; -const uint32 MAX_CHAR_LENGTH = 32765; -const uint32 MAX_VARCHAR_LENGTH = 32739; -const uint32 MAX_DEC_PRECISION = 63; -const uint32 MAX_BLOB_LENGTH = 2147483646; -const uint32 MAX_BINARY_LENGTH = MAX_CHAR_LENGTH; -const uint32 MAX_VARBINARY_LENGTH = MAX_VARCHAR_LENGTH; -const uint32 MAX_FULL_ALLOCATE_BLOB_LENGTH = 65536; -const uint32 MAX_FOREIGN_LEN = 64000; -const char* DB2I_TEMP_TABLE_SCHEMA = "QTEMP"; -const char DB2I_ADDL_INDEX_NAME_DELIMITER[5] = {'_','_','_','_','_'}; -const char DB2I_DEFAULT_INDEX_NAME_DELIMITER[3] = {'_','_','_'}; -const int DB2I_INDEX_NAME_LENGTH_TO_PRESERVE = 110; - -enum enum_DB2I_INDEX_TYPE -{ - typeNone = 0, - typeDefault = 'D', - typeHex = 'H', - typeAscii = 'A' -}; - -void* roundToQuadWordBdy(void* ptr) -{ - return (void*)(((uint64)(ptr)+0xf) & ~0xf); -} - -typedef uint64_t ILEMemHandle; - -struct OSVersion -{ - uint8 v; - uint8 r; -}; -extern OSVersion osVersion; - - -/** - Allocate 16-byte aligned space using the MySQL heap allocator - - @details Many of the spaces used by the QMY_* APIS are required to be - aligned on 16 byte boundaries. The standard system malloc will do this - alignment by default. However, in order to use the heap debug and tracking - features of the mysql allocator, we chose to implement an aligning wrapper - around my_malloc. Essentially, we overallocate the storage space, find the - first aligned address in the space, store a pointer to the true malloc - allocation in the bytes immediately preceding the aligned address, and return - the aligned address to the caller. - - @parm size The size of heap storage needed - - @return A 16-byte aligned pointer to the storage requested. -*/ -void* malloc_aligned(size_t size) -{ - char* p; - char* base; - base = (char*)my_malloc(size + sizeof(void*) + 15, MYF(MY_WME)); - if (likely(base)) - { - p = (char*)roundToQuadWordBdy(base + sizeof(void*)); - char** p2 = (char**)(p - sizeof(void*)); - *p2 = base; - } - else - p = NULL; - - return p; -} - -/** - Free a 16-byte aligned space alloced by malloc_aligned - - @details We know that a pointer to the true malloced storage immediately - precedes the aligned address, so we pull that out and call my_free(). - - @parm p A 16-byte aligned pointer generated by malloc_aligned -*/ -void free_aligned(void* p) -{ - if (likely(p)) - { - my_free(*(char**)((char*)p-sizeof(void*)), MYF(0)); - } -} - -#endif diff --git a/storage/ibmdb2i/db2i_iconv.h b/storage/ibmdb2i/db2i_iconv.h deleted file mode 100644 index 9fc6e4ed636..00000000000 --- a/storage/ibmdb2i/db2i_iconv.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -Licensed Materials - Property of IBM -DB2 Storage Engine Enablement -Copyright IBM Corporation 2007,2008 -All rights reserved - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - (a) Redistributions of source code must retain this list of conditions, the - copyright notice in section {d} below, and the disclaimer following this - list of conditions. - (b) Redistributions in binary form must reproduce this list of conditions, the - copyright notice in section (d) below, and the disclaimer following this - list of conditions, in the documentation and/or other materials provided - with the distribution. - (c) The name of IBM may not be used to endorse or promote products derived from - this software without specific prior written permission. - (d) The text of the required copyright notice is: - Licensed Materials - Property of IBM - DB2 Storage Engine Enablement - Copyright IBM Corporation 2007,2008 - All rights reserved - -THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - -/** - @file - - @brief Used to redefine iconv symbols to the optimized "myconv" ones -*/ - -#ifndef DB2I_ICONV_H -#define DB2I_ICONV_H - -#include "db2i_myconv.h" -#define iconv_open(A, B) myconv_open(A, B, CONVERTER_DMAP) -#define iconv_close myconv_close -#define iconv myconv_dmap -#define iconv_t myconv_t - -#endif diff --git a/storage/ibmdb2i/db2i_ileBridge.cc b/storage/ibmdb2i/db2i_ileBridge.cc deleted file mode 100644 index 68ae2c2bb72..00000000000 --- a/storage/ibmdb2i/db2i_ileBridge.cc +++ /dev/null @@ -1,1342 +0,0 @@ -/* -Licensed Materials - Property of IBM -DB2 Storage Engine Enablement -Copyright IBM Corporation 2007,2008 -All rights reserved - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - (a) Redistributions of source code must retain this list of conditions, the - copyright notice in section {d} below, and the disclaimer following this - list of conditions. - (b) Redistributions in binary form must reproduce this list of conditions, the - copyright notice in section (d) below, and the disclaimer following this - list of conditions, in the documentation and/or other materials provided - with the distribution. - (c) The name of IBM may not be used to endorse or promote products derived from - this software without specific prior written permission. - (d) The text of the required copyright notice is: - Licensed Materials - Property of IBM - DB2 Storage Engine Enablement - Copyright IBM Corporation 2007,2008 - All rights reserved - -THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - - - -#include "db2i_ileBridge.h" -#include "my_dbug.h" -#include "db2i_global.h" -#include "db2i_charsetSupport.h" -#include "db2i_errors.h" - - -// static class member data -ILEpointer* db2i_ileBridge::functionSymbols; -db2i_ileBridge* db2i_ileBridge::globalBridge; -#ifndef DBUG_OFF -uint32 db2i_ileBridge::registeredPtrs; -#endif - -pthread_key(IleParms*, THR_ILEPARMS); - -static void ileParmsDtor(void* parmsToFree) -{ - if (parmsToFree) - { - free_aligned(parmsToFree); - DBUG_PRINT("db2i_ileBridge", ("Freeing space for parms")); - } -} - - -/** - Convert a timestamp in ILE time format into a unix time_t -*/ -static inline time_t convertILEtime(const ILE_time_t& input) -{ - tm temp; - - temp.tm_sec = input.Second; - temp.tm_min = input.Minute; - temp.tm_hour = input.Hour; - temp.tm_mday = input.Day; - temp.tm_mon = input.Month-1; - temp.tm_year = input.Year - 1900; - temp.tm_isdst = -1; - - return mktime(&temp); -} - -/** - Allocate and intialize a new bridge structure -*/ -db2i_ileBridge* db2i_ileBridge::createNewBridge(CONNECTION_HANDLE connID) -{ - DBUG_PRINT("db2i_ileBridge::createNewBridge",("Building new bridge...")); - db2i_ileBridge* newBridge = (db2i_ileBridge*)my_malloc(sizeof(db2i_ileBridge), MYF(MY_WME)); - - if (unlikely(newBridge == NULL)) - return NULL; - - newBridge->stmtTxActive = false; - newBridge->connErrText = NULL; - newBridge->pendingLockedHandles.head = NULL; - newBridge->cachedConnectionID = connID; - - return newBridge; -} - - -void db2i_ileBridge::destroyBridge(db2i_ileBridge* bridge) -{ - bridge->freeErrorStorage(); - my_free(bridge, MYF(0)); -} - - -void db2i_ileBridge::destroyBridgeForThread(const THD* thd) -{ - void* thdData = *thd_ha_data(thd, ibmdb2i_hton); - if (thdData != NULL) - { - destroyBridge((db2i_ileBridge*)thdData); - } -} - - -void db2i_ileBridge::registerPtr(const void* ptr, ILEMemHandle* receiver) -{ - static const arg_type_t ileSignature[] = { ARG_MEMPTR, ARG_END }; - - if (unlikely(ptr == NULL)) - { - *receiver = 0; - return; - } - - struct ArgList - { - ILEarglist_base base; - ILEpointer ptr; - } *arguments; - - char argBuf[sizeof(ArgList)+15]; - arguments = (ArgList*)roundToQuadWordBdy(argBuf); - - arguments->ptr.s.addr = (address64_t)(ptr); - - _ILECALL(&functionSymbols[funcRegisterSpace], - &arguments->base, - ileSignature, - RESULT_INT64); - -#ifndef DBUG_OFF - uint32 truncHandle = arguments->base.result.r_uint64; - DBUG_PRINT("db2i_ileBridge::registerPtr",("Register 0x%p with handle %d", ptr, truncHandle)); - getBridgeForThread()->registeredPtrs++; -#endif - - *receiver = arguments->base.result.r_uint64; - return; -} - -void db2i_ileBridge::unregisterPtr(ILEMemHandle handle) -{ - static const arg_type_t ileSignature[] = { ARG_UINT64, ARG_END }; - - if (unlikely(handle == NULL)) - return; - - struct ArgList - { - ILEarglist_base base; - uint64 handle; - } *arguments; - - char argBuf[sizeof(ArgList)+15]; - arguments = (ArgList*)roundToQuadWordBdy(argBuf); - - arguments->handle = (uint64)(handle); - - _ILECALL(&functionSymbols[funcUnregisterSpace], - &arguments->base, - ileSignature, - RESULT_VOID); - -#ifndef DBUG_OFF - DBUG_PRINT("db2i_ileBridge::unregisterPtr",("Unregister handle %d", (uint32)handle)); - getBridgeForThread()->registeredPtrs--; -#endif -} - - - -/** - Initialize the bridge component - - @details Resolves srvpgm and function names of the APIs. If this fails, - the approrpiate operating system support (PTFs) is probably not installed. - - WARNING: - Must be called before any other functions in this class are used!!!! - Can only be called by a single thread! -*/ -int db2i_ileBridge::setup() -{ - static const char funcNames[db2i_ileBridge::funcListEnd][32] = - { - {"QmyRegisterParameterSpaces"}, - {"QmyRegisterSpace"}, - {"QmyUnregisterSpace"}, - {"QmyProcessRequest"} - }; - - DBUG_ENTER("db2i_ileBridge::setup"); - - int actmark = _ILELOAD("QSYS/QMYSE", ILELOAD_LIBOBJ); - if ( actmark == -1 ) - { - DBUG_PRINT("db2i_ileBridge::setup", ("srvpgm activation failed")); - DBUG_RETURN(1); - } - - functionSymbols = (ILEpointer*)malloc_aligned(sizeof(ILEpointer) * db2i_ileBridge::funcListEnd); - - for (int i = 0; i < db2i_ileBridge::funcListEnd; i++) - { - if (_ILESYM(&functionSymbols[i], actmark, funcNames[i]) == -1) - { - DBUG_PRINT("db2i_ileBridge::setup", - ("resolve of %s failed", funcNames[i])); - DBUG_RETURN(errno); - } - } - - pthread_key_create(&THR_ILEPARMS, &ileParmsDtor); - -#ifndef DBUG_OFF - registeredPtrs = 0; -#endif - - globalBridge = createNewBridge(0); - - DBUG_RETURN(0); -} - -/** - Cleanup any resources before shutting down plug-in -*/ -void db2i_ileBridge::takedown() -{ - if (globalBridge) - destroyBridge(globalBridge); - free_aligned(functionSymbols); -} - -/** - Call off to QmyProcessRequest to perform the API that the caller prepared -*/ -inline int32 db2i_ileBridge::doIt() -{ - static const arg_type_t ileSignature[] = {ARG_END}; - - struct ArgList - { - ILEarglist_base base; - } *arguments; - - char argBuf[sizeof(ArgList)+15]; - arguments = (ArgList*)roundToQuadWordBdy(argBuf); - - _ILECALL(&functionSymbols[funcProcessRequest], - &arguments->base, - ileSignature, - RESULT_INT32); - - return translateErrorCode(arguments->base.result.s_int32.r_int32); -} - -/** - Call off to QmyProcessRequest to perform the API that the caller prepared and - log any errors that may occur. -*/ -inline int32 db2i_ileBridge::doItWithLog() -{ - int32 rc = doIt(); - - if (unlikely(rc)) - { - // Only report errors that we weren't expecting - if (rc != tacitErrors[0] && - rc != tacitErrors[1] && - rc != QMY_ERR_END_OF_BLOCK) - reportSystemAPIError(rc, (Qmy_Error_output_t*)parms()->outParms); - } - memset(tacitErrors, 0, sizeof(tacitErrors)); - - return rc; -} - - -/** - Interface to QMY_ALLOCATE_SHARE API - - See QMY_ALLOCATE_SHARE documentation for more information about - parameters and return codes. -*/ -int32 db2i_ileBridge::allocateFileDefn(ILEMemHandle definitionSpace, - ILEMemHandle handleSpace, - uint16 fileCount, - const char* schemaName, - uint16 schemaNameLength, - ILEMemHandle formatSpace, - uint32 formatSpaceLen) -{ - DBUG_ASSERT(cachedStateIsCoherent()); - - IleParms* parmBlock = parms(); - Qmy_MAOS0100 *input = (Qmy_MAOS0100*)&(parmBlock->inParms); - memset(input, 0, sizeof(*input)); - - input->Format = QMY_ALLOCATE_SHARE; - input->ShrDefSpcHnd = definitionSpace; - input->ShrHndSpcHnd = handleSpace; - input->ShrDefCnt = fileCount; - input->FmtSpcHnd = formatSpace; - input->FmtSpcLen = formatSpaceLen; - - if (schemaNameLength > sizeof(input->SchNam)) - { - // This should never happen! - DBUG_ASSERT(0); - return HA_ERR_GENERIC; - } - - memcpy(input->SchNam, schemaName, schemaNameLength); - input->SchNamLen = schemaNameLength; - - input->CnnHnd = cachedConnectionID; - - int32 rc = doItWithLog(); - - return rc; -} - - -/** - Interface to QMY_ALLOCATE_INSTANCE API - - See QMY_ALLOCATE_INSTANCE documentation for more information about - parameters and return codes. -*/ -int32 db2i_ileBridge::allocateFileInstance(FILE_HANDLE defnHandle, - ILEMemHandle inuseSpace, - FILE_HANDLE* instance) -{ - DBUG_ASSERT(cachedStateIsCoherent()); - - IleParms* parmBlock = parms(); - Qmy_MAOI0100 *input = (Qmy_MAOI0100*)&(parmBlock->inParms); - memset(input, 0, sizeof(*input)); - - input->Format = QMY_ALLOCATE_INSTANCE; - input->ShrHnd = defnHandle; - input->CnnHnd = cachedConnectionID; - input->UseSpcHnd = inuseSpace; - - int32 rc = doItWithLog(); - - if (likely(rc == 0)) - { - Qmy_MAOI0100_output* output = (Qmy_MAOI0100_output*)parmBlock->outParms; - DBUG_ASSERT(instance); - *instance = output->ObjHnd; - } - - return rc; -} - - -/** - Interface to QMY_DEALLOCATE_OBJECT API - - See QMY_DEALLOCATE_OBJECT documentation for more information about - parameters and return codes. -*/ -int32 db2i_ileBridge::deallocateFile(FILE_HANDLE rfileHandle, - bool postDropTable) -{ - IleParms* parmBlock = parms(); - Qmy_MDLC0100 *input = (Qmy_MDLC0100*)&(parmBlock->inParms); - memset(input, 0, sizeof(*input)); - - input->Format = QMY_DEALLOCATE_OBJECT; - input->ObjHnd = rfileHandle; - input->ObjDrp[0] = (postDropTable ? QMY_YES : QMY_NO); - - DBUG_PRINT("db2i_ileBridge::deallocateFile", ("Deallocating %d", (uint32)rfileHandle)); - - int32 rc = doItWithLog(); - - return rc; -} - - -/** - Interface to QMY_OBJECT_INITIALIZATION API - - See QMY_OBJECT_INITIALIZATION documentation for more information about - parameters and return codes. -*/ -int32 db2i_ileBridge::initFileForIO(FILE_HANDLE rfileHandle, - char accessIntent, - char commitLevel, - uint16* inRecSize, - uint16* inRecNullOffset, - uint16* outRecSize, - uint16* outRecNullOffset) -{ - DBUG_ASSERT(cachedStateIsCoherent()); - IleParms* parmBlock = parms(); - Qmy_MOIX0100 *input = (Qmy_MOIX0100*)&(parmBlock->inParms); - memset(input, 0, sizeof(*input)); - - input->Format = QMY_OBJECT_INITIALIZATION; - input->CmtLvl[0] = commitLevel; - input->Intent[0] = accessIntent; - input->ObjHnd = rfileHandle; - input->CnnHnd = cachedConnectionID; - - int32 rc = doItWithLog(); - - if (likely(rc == 0)) - { - Qmy_MOIX0100_output* output = (Qmy_MOIX0100_output*)parmBlock->outParms; - *inRecSize = output->InNxtRowOff; - *inRecNullOffset = output->InNullMapOff; - *outRecSize = output->OutNxtRowOff; - *outRecNullOffset = output->OutNullMapOff; - } - - return rc; -} - - -/** - Interface to QMY_READ_ROWS API for reading a row with a specific RRN. - - See QMY_READ_ROWS documentation for more information about - parameters and return codes. -*/ -int32 db2i_ileBridge::readByRRN(FILE_HANDLE rfileHandle, - ILEMemHandle buf, - uint32 inRRN, - char accessIntent, - char commitLevel) -{ - DBUG_ASSERT(cachedStateIsCoherent()); - IleParms* parmBlock = parms(); - Qmy_MRDX0100 *input = (Qmy_MRDX0100*)&(parmBlock->inParms); - memset(input, 0, sizeof(*input)); - - input->Format = QMY_READ_ROWS; - input->CmtLvl[0] = commitLevel; - input->ObjHnd = rfileHandle; - input->Intent[0] = accessIntent; - input->OutSpcHnd = (uint64)buf; - input->RelRowNbr = inRRN; - input->CnnHnd = cachedConnectionID; - - int32 rc = doItWithLog(); - - if (rc == QMY_ERR_END_OF_BLOCK) - { - rc = 0; - DBUG_PRINT("db2i_ileBridge::readByRRN", ("End of block signalled")); - } - - return rc; -} - - -/** - Interface to QMY_WRITE_ROWS API. - - See QMY_WRITE_ROWS documentation for more information about - parameters and return codes. -*/ -int32 db2i_ileBridge::writeRows(FILE_HANDLE rfileHandle, - ILEMemHandle buf, - char commitLevel, - int64* outIdVal, - bool* outIdGen, - uint32* dupKeyRRN, - char** dupKeyName, - uint32* dupKeyNameLen, - uint32* outIdIncrement) -{ - DBUG_ASSERT(cachedStateIsCoherent()); - IleParms* parmBlock = parms(); - Qmy_MWRT0100 *input = (Qmy_MWRT0100*)&(parmBlock->inParms); - memset(input, 0, sizeof(*input)); - - input->Format = QMY_WRITE_ROWS; - input->CmtLvl[0] = commitLevel; - - input->ObjHnd = rfileHandle; - input->InSpcHnd = (uint64_t) buf; - input->CnnHnd = cachedConnectionID; - - int32 rc = doItWithLog(); - - Qmy_MWRT0100_output_t* output = (Qmy_MWRT0100_output_t*)parmBlock->outParms; - if (likely(rc == 0 || rc == HA_ERR_FOUND_DUPP_KEY)) - { - DBUG_ASSERT(dupKeyRRN && dupKeyName && dupKeyNameLen && outIdGen && outIdIncrement && outIdVal); - *dupKeyRRN = output->DupRRN; - *dupKeyName = (char*)parmBlock->outParms + output->DupObjNamOff; - *dupKeyNameLen = output->DupObjNamLen; - *outIdGen = (output->NewIdGen[0] == QMY_YES ? TRUE : FALSE); - if (*outIdGen == TRUE) - { - *outIdIncrement = output->IdIncrement; - *outIdVal = output->NewIdVal; - } - } - - return rc; - -} - -/** - Interface to QMY_EXECUTE_IMMEDIATE API. - - See QMY_EXECUTE_IMMEDIATE documentation for more information about - parameters and return codes. -*/ -uint32 db2i_ileBridge::execSQL(const char* statement, - uint32 statementCount, - uint8 commitLevel, - bool autoCreateSchema, - bool dropSchema, - bool noCommit, - FILE_HANDLE fileHandle) - -{ - IleParms* parmBlock = parms(); - Qmy_MSEI0100 *input = (Qmy_MSEI0100*)&(parmBlock->inParms); - memset(input, 0, sizeof(*input)); - - input->Format = QMY_EXECUTE_IMMEDIATE; - - registerPtr(statement, &input->StmtsSpcHnd); - - input->NbrStmts = statementCount; - *(uint16*)(&input->StmtCCSID) = 850; - input->AutoCrtSchema[0] = (autoCreateSchema == TRUE ? QMY_YES : QMY_NO); - input->DropSchema[0] = (dropSchema == TRUE ? QMY_YES : QMY_NO); - input->CmtLvl[0] = commitLevel; - if ((commitLevel == QMY_NONE && statementCount == 1) || noCommit) - { - input->CmtBefore[0] = QMY_NO; - input->CmtAfter[0] = QMY_NO; - } - else - { - input->CmtBefore[0] = QMY_YES; - input->CmtAfter[0] = QMY_YES; - } - input->CnnHnd = current_thd->thread_id; - input->ObjHnd = fileHandle; - - int32 rc = doItWithLog(); - - unregisterPtr(input->StmtsSpcHnd); - - return rc; -} - -/** - Interface to QMY_PREPARE_OPEN_CURSOR API. - - See QMY_PREPARE_OPEN_CURSOR documentation for more information about - parameters and return codes. -*/ -int32 db2i_ileBridge::prepOpen(const char* statement, - FILE_HANDLE* rfileHandle, - uint32* recLength) -{ - IleParms* parmBlock = parms(); - Qmy_MSPO0100 *input = (Qmy_MSPO0100*)&(parmBlock->inParms); - memset(input, 0, sizeof(*input)); - - input->Format = QMY_PREPARE_OPEN_CURSOR; - - registerPtr(statement, &input->StmtsSpcHnd ); - *(uint16*)(&input->StmtCCSID) = 850; - input->CnnHnd = current_thd->thread_id; - - int32 rc = doItWithLog(); - - if (likely(rc == 0)) - { - Qmy_MSPO0100_output* output = (Qmy_MSPO0100_output*)parmBlock->outParms; - *rfileHandle = output->ObjHnd; - *recLength = max(output->InNxtRowOff, output->OutNxtRowOff); - } - - - unregisterPtr(input->StmtsSpcHnd); - - return rc; -} - - -/** - Interface to QMY_DELETE_ROW API. - - See QMY_DELETE_ROW documentation for more information about - parameters and return codes. -*/ -int32 db2i_ileBridge::deleteRow(FILE_HANDLE rfileHandle, - uint32 rrn) -{ - DBUG_ASSERT(cachedStateIsCoherent()); - IleParms* parmBlock = parms(); - Qmy_MDLT0100 *input = (Qmy_MDLT0100*)&(parmBlock->inParms); - memset(input, 0, sizeof(*input)); - - input->Format = QMY_DELETE_ROW; - input->ObjHnd = rfileHandle; - input->RelRowNbr = rrn; - input->CnnHnd = cachedConnectionID; - - int32 rc = doItWithLog(); - - return rc; -} - - -/** - Interface to QMY_UPDATE_ROW API. - - See QMY_UPDATE_ROW documentation for more information about - parameters and return codes. -*/ -int32 db2i_ileBridge::updateRow(FILE_HANDLE rfileHandle, - uint32 rrn, - ILEMemHandle buf, - uint32* dupKeyRRN, - char** dupKeyName, - uint32* dupKeyNameLen) -{ - DBUG_ASSERT(cachedStateIsCoherent()); - IleParms* parmBlock = parms(); - Qmy_MUPD0100 *input = (Qmy_MUPD0100*)&(parmBlock->inParms); - memset(input, 0, sizeof(*input)); - - input->Format = QMY_UPDATE_ROW; - input->ObjHnd = rfileHandle; - input->InSpcHnd = (uint64)buf; - input->RelRowNbr = rrn; - input->CnnHnd = cachedConnectionID; - - int32 rc = doItWithLog(); - - if (rc == HA_ERR_FOUND_DUPP_KEY) - { - Qmy_MUPD0100_output* output = (Qmy_MUPD0100_output*)parmBlock->outParms; - DBUG_ASSERT(dupKeyRRN && dupKeyName && dupKeyNameLen); - *dupKeyRRN = output->DupRRN; - *dupKeyName = (char*)parmBlock->outParms + output->DupObjNamOff; - *dupKeyNameLen = output->DupObjNamLen; - } - - return rc; -} - -/** - Interface to QMY_DESCRIBE_RANGE API. - - See QMY_DESCRIBE_RANGE documentation for more information about - parameters and return codes. -*/ -int32 db2i_ileBridge::recordsInRange(FILE_HANDLE defnHandle, - ILEMemHandle inSpc, - uint32 inKeyCnt, - uint32 inLiteralCnt, - uint32 inBoundsOff, - uint32 inLitDefOff, - uint32 inLiteralsOff, - uint32 inCutoff, - uint32 inSpcLen, - uint16 inEndByte, - uint64* outRecCnt, - uint16* outRtnCode) -{ - DBUG_ASSERT(cachedStateIsCoherent()); - - IleParms* parmBlock = parms(); - Qmy_MDRG0100 *input = (Qmy_MDRG0100*)&(parmBlock->inParms); - memset(input, 0, sizeof(*input)); - - input->Format = QMY_DESCRIBE_RANGE; - input->ShrHnd = defnHandle; - input->SpcHnd = (uint64)inSpc; - input->KeyCnt = inKeyCnt; - input->LiteralCnt = inLiteralCnt; - input->BoundsOff = inBoundsOff; - input->LitDefOff = inLitDefOff; - input->LiteralsOff = inLiteralsOff; - input->Cutoff = inCutoff; - input->SpcLen = inSpcLen; - input->EndByte = inEndByte; - input->CnnHnd = cachedConnectionID; - - int rc = doItWithLog(); - - if (likely(rc == 0)) - { - Qmy_MDRG0100_output* output = (Qmy_MDRG0100_output*)parmBlock->outParms; - DBUG_ASSERT(outRecCnt && outRtnCode); - *outRecCnt = output->RecCnt; - *outRtnCode = output->RtnCode; - } - - return rc; -} - - -/** - Interface to QMY_RELEASE_ROW API. - - See QMY_RELEASE_ROW documentation for more information about - parameters and return codes. -*/ -int32 db2i_ileBridge::rrlslck(FILE_HANDLE rfileHandle, char accessIntent) -{ - DBUG_ASSERT(cachedStateIsCoherent()); - - IleParms* parmBlock = parms(); - Qmy_MRRX0100 *input = (Qmy_MRRX0100*)&(parmBlock->inParms); - memset(input, 0, sizeof(*input)); - - input->Format = QMY_RELEASE_ROW; - - input->ObjHnd = rfileHandle; - input->CnnHnd = cachedConnectionID; - input->Intent[0] = accessIntent; - - int32 rc = doItWithLog(); - - return rc; -} - -/** - Interface to QMY_LOCK_OBJECT API. - - See QMY_LOCK_OBJECT documentation for more information about - parameters and return codes. -*/ -int32 db2i_ileBridge::lockObj(FILE_HANDLE defnHandle, - uint64 lockVal, - char lockAction, - char lockType, - char lockTimeout) -{ - DBUG_ASSERT(cachedStateIsCoherent()); - IleParms* parmBlock = parms(); - Qmy_MOLX0100 *input = (Qmy_MOLX0100*)&(parmBlock->inParms); - memset(input, 0, sizeof(*input)); - - input->Format = QMY_LOCK_OBJECT; - input->ShrHnd = defnHandle; - input->LckTimeoutVal = lockVal; - input->Action[0] = lockAction; - input->LckTyp[0] = lockType; - input->LckTimeout[0] = lockTimeout; - input->CnnHnd = cachedConnectionID; - - int32 rc = doItWithLog(); - - return rc; -} - -/** - Interface to QMY_DESCRIBE_CONSTRAINTS API. - - See QMY_DESCRIBE_CONSTRAINTS documentation for more information about - parameters and return codes. -*/ -int32 db2i_ileBridge::constraints(FILE_HANDLE defnHandle, - ILEMemHandle inSpc, - uint32 inSpcLen, - uint32* outLen, - uint32* outCnt) -{ - DBUG_ASSERT(cachedStateIsCoherent()); - IleParms* parmBlock = parms(); - Qmy_MDCT0100 *input = (Qmy_MDCT0100*)&(parmBlock->inParms); - memset(input, 0, sizeof(*input)); - - input->Format = QMY_DESCRIBE_CONSTRAINTS; - input->ShrHnd = defnHandle; - input->CstSpcHnd = (uint64)inSpc; - input->CstSpcLen = inSpcLen; - input->CnnHnd = cachedConnectionID; - - int32 rc = doItWithLog(); - - if (likely(rc == 0)) - { - Qmy_MDCT0100_output* output = (Qmy_MDCT0100_output*)parmBlock->outParms; - DBUG_ASSERT(outLen && outCnt); - *outLen = output->NeededLen; - *outCnt = output->CstCnt; - } - - return rc; -} - - -/** - Interface to QMY_REORGANIZE_TABLE API. - - See QMY_REORGANIZE_TABLE documentation for more information about - parameters and return codes. -*/ -int32 db2i_ileBridge::optimizeTable(FILE_HANDLE defnHandle) -{ - DBUG_ASSERT(cachedStateIsCoherent()); - IleParms* parmBlock = parms(); - Qmy_MRGX0100 *input = (Qmy_MRGX0100*)&(parmBlock->inParms); - memset(input, 0, sizeof(*input)); - - input->Format = QMY_REORGANIZE_TABLE; - input->ShrHnd = defnHandle; - input->CnnHnd = cachedConnectionID; - - int32 rc = doItWithLog(); - - return rc; -} - - -/** - Interface to QMY_PROCESS_COMMITMENT_CONTROL API. - - See QMY_PROCESS_COMMITMENT_CONTROL documentation for more information about - parameters and return codes. -*/ -int32 db2i_ileBridge::commitmentControl(uint8 function) -{ - DBUG_ASSERT(cachedStateIsCoherent()); - IleParms* parmBlock = parms(); - Qmy_MCCX0100 *input = (Qmy_MCCX0100*)&(parmBlock->inParms); - memset(input, 0, sizeof(*input)); - - input->Format = QMY_PROCESS_COMMITMENT_CONTROL; - input->Function[0] = function; - input->CnnHnd = cachedConnectionID; - - int32 rc = doItWithLog(); - - return rc; -} - - -/** - Interface to QMY_PROCESS_SAVEPOINT API. - - See QMY_PROCESS_SAVEPOINT documentation for more information about parameters and - return codes. -*/ -int32 db2i_ileBridge::savepoint(uint8 function, - const char* savepointName) -{ - DBUG_ASSERT(cachedStateIsCoherent()); - DBUG_PRINT("db2i_ileBridge::savepoint",("%d %s", (uint32)function, savepointName)); - - IleParms* parmBlock = parms(); - Qmy_MSPX0100 *input = (Qmy_MSPX0100*)&(parmBlock->inParms); - memset(input, 0, sizeof(*input)); - - char* savPtNam = (char*)(input+1); - - input->Format = QMY_PROCESS_SAVEPOINT; - - if (strlen(savepointName) > MAX_DB2_SAVEPOINTNAME_LENGTH) - { - DBUG_ASSERT(0); - return HA_ERR_GENERIC; - } - strcpy(savPtNam, savepointName); - - input->Function[0] = function; - input->SavPtNamOff = savPtNam - (char*)(input); - input->SavPtNamLen = strlen(savepointName); - input->CnnHnd = cachedConnectionID; - - int32 rc = doItWithLog(); - - return rc; -} - -static ILEMemHandle traceSpcHandle; -/** - Do initialization for the QMY_* APIs. - - @parm aspName The name of the relational database to use for all - connections. - - @return 0 if successful; error otherwise -*/ -int32 db2i_ileBridge::initILE(const char* aspName, - uint16* traceCtlPtr) -{ - // We forego the typical thread-based parms space because MySQL doesn't - // allow us to clean it up before checking for memory leaks. As a result - // we get a complaint about leaked memory on server shutdown. - int32 rc; - char inParms[db2i_ileBridge_MAX_INPARM_SIZE]; - char outParms[db2i_ileBridge_MAX_OUTPARM_SIZE]; - if (rc = registerParmSpace(inParms, outParms)) - { - reportSystemAPIError(rc, NULL); - return rc; - } - - registerPtr(traceCtlPtr, &traceSpcHandle); - - struct ParmBlock - { - Qmy_MINI0100 parms; - } *parmBlock = (ParmBlock*)inParms; - - memset(inParms, 0, sizeof(ParmBlock)); - - parmBlock->parms.Format = QMY_INITIALIZATION; - - char paddedName[18]; - if (strlen(aspName) > sizeof(paddedName)) - { - getErrTxt(DB2I_ERR_BAD_RDB_NAME); - return DB2I_ERR_BAD_RDB_NAME; - } - - memset(paddedName, ' ', sizeof(paddedName)); - memcpy(paddedName, aspName, strlen(aspName)); - convToEbcdic(paddedName, parmBlock->parms.RDBName, strlen(paddedName)); - - parmBlock->parms.RDBNamLen = strlen(paddedName); - parmBlock->parms.TrcSpcHnd = traceSpcHandle; - - rc = doIt(); - - if (rc) - { - reportSystemAPIError(rc, (Qmy_Error_output_t*)outParms); - } - - return rc; -} - -/** - Signal to the QMY_ APIs to perform any cleanup they need to do. -*/ -int32 db2i_ileBridge::exitILE() -{ - IleParms* parmBlock = parms(); - Qmy_MCLN0100 *input = (Qmy_MCLN0100*)&(parmBlock->inParms); - memset(input, 0, sizeof(*input)); - - input->Format = QMY_CLEANUP; - - int32 rc = doIt(); - - if (rc) - { - reportSystemAPIError(rc, (Qmy_Error_output_t*)parmBlock->outParms); - } - - unregisterPtr(traceSpcHandle); - - DBUG_PRINT("db2i_ileBridge::exitILE", ("Registered ptrs remaining: %d", registeredPtrs)); -#ifndef DBUG_OFF - if (registeredPtrs != 0) - printf("Oh no! IBMDB2I left some pointers registered. Count was %d.\n", registeredPtrs); -#endif - - // This is needed to prevent SAFE_MALLOC from complaining at process termination. - my_pthread_setspecific_ptr(THR_ILEPARMS, NULL); - free_aligned(parmBlock); - - return rc; - -} - - -/** - Designate the specified addresses as parameter passing buffers. - - @parm in Input to the API will go here; format is defined by the individual API - @parm out Output from the API will be; format is defined by the individual API - - @return 0 if success; error otherwise -*/ -int db2i_ileBridge::registerParmSpace(char* in, char* out) -{ - static const arg_type_t ileSignature[] = { ARG_MEMPTR, ARG_MEMPTR, ARG_END }; - - struct ArgList - { - ILEarglist_base base; - ILEpointer input; - ILEpointer output; - } *arguments; - - char argBuf[sizeof(ArgList)+15]; - arguments = (ArgList*)roundToQuadWordBdy(argBuf); - - arguments->input.s.addr = (address64_t)(in); - arguments->output.s.addr = (address64_t)(out); - - _ILECALL(&functionSymbols[funcRegisterParameterSpaces], - &arguments->base, - ileSignature, - RESULT_INT32); - - return arguments->base.result.s_int32.r_int32; -} - - -/** - Interface to QMY_OBJECT_OVERRIDE API. - - See QMY_OBJECT_OVERRIDE documentation for more information about parameters and - return codes. -*/ -int32 db2i_ileBridge::objectOverride(FILE_HANDLE rfileHandle, - ILEMemHandle buf, - uint32 recordWidth) -{ - DBUG_ASSERT(cachedStateIsCoherent()); - IleParms* parmBlock = parms(); - Qmy_MOOX0100 *input = (Qmy_MOOX0100*)&(parmBlock->inParms); - memset(input, 0, sizeof(*input)); - - input->Format = QMY_OBJECT_OVERRIDE; - input->ObjHnd = rfileHandle; - input->OutSpcHnd = (uint64)buf; - input->NxtRowOff = recordWidth; - input->CnnHnd = cachedConnectionID; - - int32 rc = doItWithLog(); - - return rc; -} - -/** - Interface to QMY_DESCRIBE_OBJECT API for obtaining table stats. - - See QMY_DESCRIBE_OBJECT documentation for more information about parameters and - return codes. -*/ -int32 db2i_ileBridge::retrieveTableInfo(FILE_HANDLE defnHandle, - uint16 dataRequested, - ha_statistics& stats, - ILEMemHandle inSpc) -{ - DBUG_ASSERT(cachedStateIsCoherent()); - IleParms* parmBlock = parms(); - Qmy_MDSO0100 *input = (Qmy_MDSO0100*)&(parmBlock->inParms); - memset(input, 0, sizeof(*input)); - - input->Format = QMY_DESCRIBE_OBJECT; - input->ShrHnd = defnHandle; - input->CnnHnd = cachedConnectionID; - - if (dataRequested & objLength) - input->RtnObjLen[0] = QMY_YES; - if (dataRequested & rowCount) - input->RtnRowCnt[0] = QMY_YES; - if (dataRequested & deletedRowCount) - input->RtnDltRowCnt[0] = QMY_YES; - if (dataRequested & rowsPerKey) - { - input->RowKeyHnd = (uint64)inSpc; - input->RtnRowKey[0] = QMY_YES; - } - if (dataRequested & meanRowLen) - input->RtnMeanRowLen[0] = QMY_YES; - if (dataRequested & lastModTime) - input->RtnModTim[0] = QMY_YES; - if (dataRequested & createTime) - input->RtnCrtTim[0] = QMY_YES; - if (dataRequested & ioCount) - input->RtnEstIoCnt[0] = QMY_YES; - - int32 rc = doItWithLog(); - - if (likely(rc == 0)) - { - Qmy_MDSO0100_output* output = (Qmy_MDSO0100_output*)parmBlock->outParms; - if (dataRequested & objLength) - stats.data_file_length = output->ObjLen; - if (dataRequested & rowCount) - stats.records= output->RowCnt; - if (dataRequested & deletedRowCount) - stats.deleted = output->DltRowCnt; - if (dataRequested & meanRowLen) - stats.mean_rec_length = output->MeanRowLen; - if (dataRequested & lastModTime) - stats.update_time = convertILEtime(output->ModTim); - if (dataRequested & createTime) - stats.create_time = convertILEtime(output->CrtTim); - if (dataRequested & ioCount) - stats.data_file_length = output->EstIoCnt; - } - - return rc; -} - -/** - Interface to QMY_DESCRIBE_OBJECT API for finding index size. - - See QMY_DESCRIBE_OBJECT documentation for more information about parameters and - return codes. -*/ -int32 db2i_ileBridge::retrieveIndexInfo(FILE_HANDLE defnHandle, - uint64* outPageCnt) -{ - DBUG_ASSERT(cachedStateIsCoherent()); - IleParms* parmBlock = parms(); - Qmy_MDSO0100 *input = (Qmy_MDSO0100*)&(parmBlock->inParms); - memset(input, 0, sizeof(*input)); - - input->Format = QMY_DESCRIBE_OBJECT; - input->ShrHnd = defnHandle; - input->CnnHnd = cachedConnectionID; - input->RtnPageCnt[0] = QMY_YES; - - int32 rc = doItWithLog(); - - if (likely(rc == 0)) - { - Qmy_MDSO0100_output* output = (Qmy_MDSO0100_output*)parmBlock->outParms; - *outPageCnt = output->PageCnt; - } - - return rc; -} - - -/** - Interface to QMY_CLOSE_CONNECTION API - - See QMY_CLOSE_CONNECTION documentation for more information about parameters and - return codes. -*/ -int32 db2i_ileBridge::closeConnection(CONNECTION_HANDLE conn) -{ - IleParms* parmBlock = parms(); - Qmy_MCCN0100 *input = (Qmy_MCCN0100*)&(parmBlock->inParms); - memset(input, 0, sizeof(*input)); - - input->Format = QMY_CLOSE_CONNECTION; - input->CnnHnd = conn; - - int32 rc = doItWithLog(); - - return rc; -} - - -/** - Interface to QMY_INTERRUPT API - - See QMY_INTERRUPT documentation for more information about parameters and - return codes. -*/ -int32 db2i_ileBridge::readInterrupt(FILE_HANDLE fileHandle) -{ - DBUG_ASSERT(cachedStateIsCoherent()); - IleParms* parmBlock = parms(); - Qmy_MINT0100 *input = (Qmy_MINT0100*)&(parmBlock->inParms); - memset(input, 0, sizeof(*input)); - - input->Format = QMY_INTERRUPT; - input->CnnHnd = cachedConnectionID; - input->ObjHnd = fileHandle; - - int32 rc = doItWithLog(); - - if (rc == QMY_ERR_END_OF_BLOCK) - { - rc = 0; - DBUG_PRINT("db2i_ileBridge::readInterrupt", ("End of block signalled")); - } - - return rc; -} - -/** - Interface to QMY_READ_ROWS API - - See QMY_READ_ROWS documentation for more information about parameters and - return codes. -*/ -int32 db2i_ileBridge::read(FILE_HANDLE rfileHandle, - ILEMemHandle buf, - char accessIntent, - char commitLevel, - char orientation, - bool asyncRead, - ILEMemHandle rrn, - ILEMemHandle key, - uint32 keylen, - uint16 keyParts, - int pipeFD) -{ - DBUG_ASSERT(cachedStateIsCoherent()); - IleParms* parmBlock = parms(); - Qmy_MRDX0100 *input = (Qmy_MRDX0100*)&(parmBlock->inParms); - memset(input, 0, sizeof(*input)); - - input->Format = QMY_READ_ROWS; - input->CmtLvl[0] = commitLevel; - - input->ObjHnd = rfileHandle; - input->Intent[0] = accessIntent; - input->OutSpcHnd = (uint64)buf; - input->OutRRNSpcHnd = (uint64)rrn; - input->RtnData[0] = QMY_RETURN_DATA; - - if (key) - { - input->KeySpcHnd = (uint64)key; - input->KeyColsLen = keylen; - input->KeyColsNbr = keyParts; - } - - input->Async[0] = (asyncRead ? QMY_YES : QMY_NO); - input->PipeDesc = pipeFD; - input->Orientation[0] = orientation; - input->CnnHnd = cachedConnectionID; - - int32 rc = doItWithLog(); - - // QMY_ERR_END_OF_BLOCK is informational only, so we ignore it. - if (rc == QMY_ERR_END_OF_BLOCK) - { - rc = 0; - DBUG_PRINT("db2i_ileBridge::read", ("End of block signalled")); - } - - return rc; -} - - -/** - Interface to QMY_QUIESCE_OBJECT API - - See QMY_QUIESCE_OBJECT documentation for more information about parameters and - return codes. -*/ -int32 db2i_ileBridge::quiesceFileInstance(FILE_HANDLE rfileHandle) -{ - IleParms* parmBlock = parms(); - Qmy_MQSC0100 *input = (Qmy_MQSC0100*)&(parmBlock->inParms); - memset(input, 0, sizeof(*input)); - - input->Format = QMY_QUIESCE_OBJECT; - input->ObjHnd = rfileHandle; - - int32 rc = doItWithLog(); - -#ifndef DBUG_OFF - if (unlikely(rc)) - { - DBUG_ASSERT(0); - } -#endif - - return rc; -} - -void db2i_ileBridge::PreservedHandleList::add(const char* newname, FILE_HANDLE newhandle, IBMDB2I_SHARE* share) -{ - NameHandlePair *newPair = (NameHandlePair*)my_malloc(sizeof(NameHandlePair), MYF(MY_WME)); - - newPair->next = head; - head = newPair; - - strcpy(newPair->name, newname); - newPair->handle = newhandle; - newPair->share = share; - DBUG_PRINT("db2i_ileBridge", ("Added handle %d for %s", uint32(newhandle), newname)); -} - - -FILE_HANDLE db2i_ileBridge::PreservedHandleList::findAndRemove(const char* fileName, IBMDB2I_SHARE** share) -{ - NameHandlePair* current = head; - NameHandlePair* prev = NULL; - - while (current) - { - NameHandlePair* next = current->next; - if (strcmp(fileName, current->name) == 0) - { - FILE_HANDLE tmp = current->handle; - *share = current->share; - if (prev) - prev->next = next; - if (current == head) - head = next; - my_free(current, MYF(0)); - DBUG_PRINT("db2i_ileBridge", ("Found handle %d for %s", uint32(tmp), fileName)); - return tmp; - } - prev = current; - current = next; - } - - return 0; -} - - -IleParms* db2i_ileBridge::initParmsForThread() -{ - - IleParms* p = (IleParms*)malloc_aligned(sizeof(IleParms)); - DBUG_ASSERT((uint64)(&(p->outParms))% 16 == 0); // Guarantee that outParms are aligned correctly - - if (likely(p)) - { - int32 rc = registerParmSpace((p->inParms), (p->outParms)); - if (likely(rc == 0)) - { - my_pthread_setspecific_ptr(THR_ILEPARMS, p); - DBUG_PRINT("db2i_ileBridge", ("Inited space for parms")); - return p; - } - else - reportSystemAPIError(rc, NULL); - } - - return NULL; -} - diff --git a/storage/ibmdb2i/db2i_ileBridge.h b/storage/ibmdb2i/db2i_ileBridge.h deleted file mode 100644 index 10b9820d983..00000000000 --- a/storage/ibmdb2i/db2i_ileBridge.h +++ /dev/null @@ -1,499 +0,0 @@ -/* -Licensed Materials - Property of IBM -DB2 Storage Engine Enablement -Copyright IBM Corporation 2007,2008 -All rights reserved - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - (a) Redistributions of source code must retain this list of conditions, the - copyright notice in section {d} below, and the disclaimer following this - list of conditions. - (b) Redistributions in binary form must reproduce this list of conditions, the - copyright notice in section (d) below, and the disclaimer following this - list of conditions, in the documentation and/or other materials provided - with the distribution. - (c) The name of IBM may not be used to endorse or promote products derived from - this software without specific prior written permission. - (d) The text of the required copyright notice is: - Licensed Materials - Property of IBM - DB2 Storage Engine Enablement - Copyright IBM Corporation 2007,2008 - All rights reserved - -THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - - -#ifndef DB2I_ILEBRIDGE_H -#define DB2I_ILEBRIDGE_H - -#include "db2i_global.h" -#include "mysql_priv.h" -#include "as400_types.h" -#include "as400_protos.h" -#include "qmyse.h" -#include "db2i_errors.h" - -typedef uint64_t FILE_HANDLE; -typedef my_thread_id CONNECTION_HANDLE; -const char SAVEPOINT_NAME[] = {0xD4,0xE2,0xD7,0xC9,0xD5,0xE3,0xC5,0xD9,0xD5,0x0}; -const uint32 TACIT_ERRORS_SIZE=2; - -enum db2i_InfoRequestSpec -{ - objLength = 1, - rowCount = 2, - deletedRowCount = 4, - rowsPerKey = 8, - meanRowLen = 16, - lastModTime = 32, - createTime = 64, - ioCount = 128 -}; - -extern handlerton *ibmdb2i_hton; -struct IBMDB2I_SHARE; - -const uint32 db2i_ileBridge_MAX_INPARM_SIZE = 512; -const uint32 db2i_ileBridge_MAX_OUTPARM_SIZE = 512; - -extern pthread_key(IleParms*, THR_ILEPARMS); -struct IleParms -{ - char inParms[db2i_ileBridge_MAX_INPARM_SIZE]; - char outParms[db2i_ileBridge_MAX_OUTPARM_SIZE]; -}; - -/** - @class db2i_ileBridge - - Implements a connection-based interface to the QMY_* APIs - - @details Each client connection that touches an IBMDB2I table has a "bridge" - associated with it. This bridge is constructed on first use and provides a - more C-like interface to the APIs. As well, it is reponsible for tracking - connection scoped information such as statement transaction state and error - message text. The bridge is destroyed when the connection ends. -*/ -class db2i_ileBridge -{ - enum ileFuncs - { - funcRegisterParameterSpaces, - funcRegisterSpace, - funcUnregisterSpace, - funcProcessRequest, - funcListEnd - }; - - static db2i_ileBridge* globalBridge; -public: - - - static int setup(); - static void takedown(); - - /** - Obtain a pointer to the bridge for the current connection. - - If a MySQL client connection is on the stack, we get the associated brideg. - Otherwise, we use the globalBridge. - */ - static db2i_ileBridge* getBridgeForThread() - { - THD* thd = current_thd; - if (likely(thd)) - return getBridgeForThread(thd); - - return globalBridge; - } - - /** - Obtain a pointer to the bridge for the specified connection. - - If a bridge exists already, we return it immediately. Otherwise, prepare - a new bridge for the connection. - */ - static db2i_ileBridge* getBridgeForThread(const THD* thd) - { - void* thdData = *thd_ha_data(thd, ibmdb2i_hton); - if (likely(thdData != NULL)) - return (db2i_ileBridge*)(thdData); - - db2i_ileBridge* newBridge = createNewBridge(thd->thread_id); - *thd_ha_data(thd, ibmdb2i_hton) = (void*)newBridge; - return newBridge; - } - - static void destroyBridgeForThread(const THD* thd); - static void registerPtr(const void* ptr, ILEMemHandle* receiver); - static void unregisterPtr(ILEMemHandle handle); - int32 allocateFileDefn(ILEMemHandle definitionSpace, - ILEMemHandle handleSpace, - uint16 fileCount, - const char* schemaName, - uint16 schemaNameLength, - ILEMemHandle formatSpace, - uint32 formatSpaceLen); - int32 allocateFileInstance(FILE_HANDLE defnHandle, - ILEMemHandle inuseSpace, - FILE_HANDLE* instance); - int32 deallocateFile(FILE_HANDLE fileHandle, - bool postDropTable=FALSE); - int32 read(FILE_HANDLE rfileHandle, - ILEMemHandle buf, - char accessIntent, - char commitLevel, - char orientation, - bool asyncRead = FALSE, - ILEMemHandle rrn = 0, - ILEMemHandle key = 0, - uint32 keylen = 0, - uint16 keyParts = 0, - int pipeFD = -1); - int32 readByRRN(FILE_HANDLE rfileHandle, - ILEMemHandle buf, - uint32 inRRN, - char accessIntent, - char commitLevel); - int32 writeRows(FILE_HANDLE rfileHandle, - ILEMemHandle buf, - char commitLevel, - int64* outIdVal, - bool* outIdGen, - uint32* dupKeyRRN, - char** dupKeyName, - uint32* dupKeyNameLen, - uint32* outIdIncrement); - uint32 execSQL(const char* statement, - uint32 statementCount, - uint8 commitLevel, - bool autoCreateSchema = FALSE, - bool dropSchema = FALSE, - bool noCommit = FALSE, - FILE_HANDLE fileHandle = 0); - int32 prepOpen(const char* statement, - FILE_HANDLE* rfileHandle, - uint32* recLength); - int32 deleteRow(FILE_HANDLE rfileHandle, - uint32 rrn); - int32 updateRow(FILE_HANDLE rfileHandle, - uint32 rrn, - ILEMemHandle buf, - uint32* dupKeyRRN, - char** dupKeyName, - uint32* dupKeyNameLen); - int32 commitmentControl(uint8 function); - int32 savepoint(uint8 function, - const char* savepointName); - int32 recordsInRange(FILE_HANDLE rfileHandle, - ILEMemHandle inSpc, - uint32 inKeyCnt, - uint32 inLiteralCnt, - uint32 inBoundsOff, - uint32 inLitDefOff, - uint32 inLiteralsOff, - uint32 inCutoff, - uint32 inSpcLen, - uint16 inEndByte, - uint64* outRecCnt, - uint16* outRtnCode); - int32 rrlslck(FILE_HANDLE rfileHandle, - char accessIntent); - int32 lockObj(FILE_HANDLE rfileHandle, - uint64 inTimeoutVal, - char inAction, - char inLockType, - char inTimeout); - int32 constraints(FILE_HANDLE rfileHandle, - ILEMemHandle inSpc, - uint32 inSpcLen, - uint32* outLen, - uint32* outCnt); - int32 optimizeTable(FILE_HANDLE rfileHandle); - static int32 initILE(const char* aspName, - uint16* traceCtlPtr); - int32 initFileForIO(FILE_HANDLE rfileHandle, - char accessIntent, - char commitLevel, - uint16* inRecSize, - uint16* inRecNullOffset, - uint16* outRecSize, - uint16* outRecNullOffset); - int32 readInterrupt(FILE_HANDLE fileHandle); - static int32 exitILE(); - - int32 objectOverride(FILE_HANDLE rfileHandle, - ILEMemHandle buf, - uint32 recordWidth = 0); - - int32 retrieveTableInfo(FILE_HANDLE rfileHandle, - uint16 dataRequested, - ha_statistics& stats, - ILEMemHandle inSpc = NULL); - - int32 retrieveIndexInfo(FILE_HANDLE rfileHandle, - uint64* outPageCnt); - - int32 closeConnection(CONNECTION_HANDLE conn); - int32 quiesceFileInstance(FILE_HANDLE rfileHandle); - - /** - Mark the beginning of a "statement transaction" - - @detail MySQL "statement transactions" (see sql/handler.cc) are implemented - as DB2 savepoints having a predefined name. - - @return 0 if successful; error otherwise - */ - uint32 beginStmtTx() - { - DBUG_ENTER("db2i_ileBridge::beginStmtTx"); - if (stmtTxActive) - DBUG_RETURN(0); - - stmtTxActive = true; - - DBUG_RETURN(savepoint(QMY_SET_SAVEPOINT, SAVEPOINT_NAME)); - } - - /** - Commit a "statement transaction" - - @return 0 if successful; error otherwise - */ - uint32 commitStmtTx() - { - DBUG_ENTER("db2i_ileBridge::commitStmtTx"); - DBUG_ASSERT(stmtTxActive); - stmtTxActive = false; - DBUG_RETURN(savepoint(QMY_RELEASE_SAVEPOINT, SAVEPOINT_NAME)); - } - - /** - Roll back a "statement transaction" - - @return 0 if successful; error otherwise - */ - uint32 rollbackStmtTx() - { - DBUG_ENTER("db2i_ileBridge::rollbackStmtTx"); - DBUG_ASSERT(stmtTxActive); - stmtTxActive = false; - DBUG_RETURN(savepoint(QMY_ROLLBACK_SAVEPOINT, SAVEPOINT_NAME)); - } - - - /** - Provide storage for generating error messages. - - This storage must persist until the error message is retrieved from the - handler instance. It is for this reason that we associate it with the bridge. - - @return Pointer to heap storage of MYSQL_ERRMSG_SIZE bytes - */ - char* getErrorStorage() - { - if (!connErrText) - { - connErrText = (char*)my_malloc(MYSQL_ERRMSG_SIZE, MYF(MY_WME)); - if (connErrText) connErrText[0] = 0; - } - - return connErrText; - } - - /** - Free storage for generating error messages. - */ - void freeErrorStorage() - { - if (likely(connErrText)) - { - my_free(connErrText, MYF(0)); - connErrText = NULL; - } - } - - - /** - Store a file handle for later retrieval. - - If deallocateFile encounters a lock when trying to perform its operation, - the file remains allocated but must be deallocated later. This function - provides a way for the connection to "remember" that this deallocation is - still needed. - - @param newname The name of the file to be added - @param newhandle The handle associated with newname - - */ - void preserveHandle(const char* newname, FILE_HANDLE newhandle, IBMDB2I_SHARE* share) - { - pendingLockedHandles.add(newname, newhandle, share); - } - - /** - Retrieve a file handle stored by preserveHandle(). - - @param name The name of the file to be retrieved. - - @return The handle associated with name - */ - FILE_HANDLE findAndRemovePreservedHandle(const char* name, IBMDB2I_SHARE** share) - { - FILE_HANDLE hdl = pendingLockedHandles.findAndRemove(name, share); - return hdl; - } - - /** - Indicate which error messages should be suppressed on the next API call - - These functions are useful for ensuring that the provided error numbers - are returned if a failure occurs but do not cause a spurious error message - to be returned. - - @return A pointer to this instance - */ - db2i_ileBridge* expectErrors(int32 er1) - { - tacitErrors[0]=er1; - return this; - } - - db2i_ileBridge* expectErrors(int32 er1, int32 er2) - { - tacitErrors[0]=er1; - tacitErrors[1]=er2; - return this; - } - - /** - Obtain the IBM i system message that accompanied the last API failure. - - @return A pointer to the 7 character message ID. - */ - static const char* getErrorMsgID() - { - return ((Qmy_Error_output_t*)parms()->outParms)->MsgId; - } - - /** - Convert an API error code into the equivalent MySQL error code (if any) - - @param rc The QMYSE API error code - - @return If an equivalent exists, the MySQL error code; else rc - */ - static int32 translateErrorCode(int32 rc) - { - if (likely(rc == 0)) - return 0; - - switch (rc) - { - case QMY_ERR_KEY_NOT_FOUND: - return HA_ERR_KEY_NOT_FOUND; - case QMY_ERR_DUP_KEY: - return HA_ERR_FOUND_DUPP_KEY; - case QMY_ERR_END_OF_FILE: - return HA_ERR_END_OF_FILE; - case QMY_ERR_LOCK_TIMEOUT: - return HA_ERR_LOCK_WAIT_TIMEOUT; - case QMY_ERR_CST_VIOLATION: - return HA_ERR_NO_REFERENCED_ROW; - case QMY_ERR_TABLE_NOT_FOUND: - return HA_ERR_NO_SUCH_TABLE; - case QMY_ERR_NON_UNIQUE_KEY: - return ER_DUP_ENTRY; - case QMY_ERR_MSGID: - { - if (memcmp(getErrorMsgID(), DB2I_CPF503A, 7) == 0) - return HA_ERR_ROW_IS_REFERENCED; - if (memcmp(getErrorMsgID(), DB2I_SQL0538, 7) == 0) - return HA_ERR_CANNOT_ADD_FOREIGN; - } - } - return rc; - } - -private: - - static db2i_ileBridge* createNewBridge(CONNECTION_HANDLE connID); - static void destroyBridge(db2i_ileBridge* bridge); - static int registerParmSpace(char* in, char* out); - static int32 doIt(); - int32 doItWithLog(); - - static _ILEpointer *functionSymbols; ///< Array of ILE function pointers - CONNECTION_HANDLE cachedConnectionID; ///< The associated connection - bool stmtTxActive; ///< Inside statement transaction - char *connErrText; ///< Storage for error message - int32 tacitErrors[TACIT_ERRORS_SIZE]; ///< List of errors to be suppressed - - static IleParms* initParmsForThread(); - - /** - Get space for passing parameters to the QMY_* APIs - - @details A fixed-length parameter passing space is associated with each - pthread. This space is allocated and registered by initParmsForThread() - the first time a pthread works with a bridge. The space is cached away - and remains available until the pthread ends. It became necessary to - disassociate the parameter space from the bridge in order to support - future enhancements to MySQL that sever the one-to-one relationship between - pthreads and user connections. The QMY_* APIs scope a registered parameter - space to the thread that executes the register operation. - */ - static IleParms* parms() - { - IleParms* p = my_pthread_getspecific_ptr(IleParms*, THR_ILEPARMS); - if (likely(p)) - return p; - - return initParmsForThread(); - } - - class PreservedHandleList - { - friend db2i_ileBridge* db2i_ileBridge::createNewBridge(CONNECTION_HANDLE); - public: - void add(const char* newname, FILE_HANDLE newhandle, IBMDB2I_SHARE* share); - FILE_HANDLE findAndRemove(const char* fileName, IBMDB2I_SHARE** share); - - private: - struct NameHandlePair - { - char name[FN_REFLEN]; - FILE_HANDLE handle; - IBMDB2I_SHARE* share; - NameHandlePair* next; - }* head; - } pendingLockedHandles; - - -#ifndef DBUG_OFF - bool cachedStateIsCoherent() - { - return (current_thd->thread_id == cachedConnectionID); - } - - friend void db2i_ileBridge::unregisterPtr(ILEMemHandle); - friend void db2i_ileBridge::registerPtr(const void*, ILEMemHandle*); - static uint32 registeredPtrs; -#endif -}; - - - -#endif diff --git a/storage/ibmdb2i/db2i_ioBuffers.cc b/storage/ibmdb2i/db2i_ioBuffers.cc deleted file mode 100644 index 9525a6e34b5..00000000000 --- a/storage/ibmdb2i/db2i_ioBuffers.cc +++ /dev/null @@ -1,332 +0,0 @@ -/* -Licensed Materials - Property of IBM -DB2 Storage Engine Enablement -Copyright IBM Corporation 2007,2008 -All rights reserved - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - (a) Redistributions of source code must retain this list of conditions, the - copyright notice in section {d} below, and the disclaimer following this - list of conditions. - (b) Redistributions in binary form must reproduce this list of conditions, the - copyright notice in section (d) below, and the disclaimer following this - list of conditions, in the documentation and/or other materials provided - with the distribution. - (c) The name of IBM may not be used to endorse or promote products derived from - this software without specific prior written permission. - (d) The text of the required copyright notice is: - Licensed Materials - Property of IBM - DB2 Storage Engine Enablement - Copyright IBM Corporation 2007,2008 - All rights reserved - -THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - - -#include "db2i_ioBuffers.h" - -/** - Request another block of rows - - Request the next set of rows from DB2. This must only be called after - newReadRequest(). - - @param orientation The direction to use when reading through the table. -*/ -void IOAsyncReadBuffer::loadNewRows(char orientation) -{ - rewind(); - maxRows() = rowsToBlock; - - DBUG_PRINT("db2i_ioBuffers::loadNewRows", ("Requesting %d rows, async = %d", rowsToBlock, readIsAsync)); - - rc = getBridge()->expectErrors(QMY_ERR_END_OF_BLOCK, QMY_ERR_LOB_SPACE_TOO_SMALL) - ->read(file, - ptr(), - accessIntent, - commitLevel, - orientation, - readIsAsync, - rrnList, - 0, - 0, - 0); - - DBUG_PRINT("db2i_ioBuffers::loadNewRows", ("recordsRead: %d, rc: %d", (uint32)rowCount(), rc)); - - - *releaseRowNeeded = true; - - if (rc == QMY_ERR_END_OF_BLOCK) - { - // This is really just an informational error, so we ignore it. - rc = 0; - DBUG_PRINT("db2i_ioBuffers::loadNewRows", ("End of block signalled")); - } - else if (rc == QMY_ERR_END_OF_FILE) - { - // If we reach EOF or end-of-key, DB2 guarantees that no rows will be locked. - rc = HA_ERR_END_OF_FILE; - *releaseRowNeeded = false; - } - else if (rc == QMY_ERR_KEY_NOT_FOUND) - { - rc = HA_ERR_KEY_NOT_FOUND; - *releaseRowNeeded = false; - } - - if (rc) closePipe(); -} - - -/** - Empty the message pipe to prepare for another read. -*/ -void IOAsyncReadBuffer::drainPipe() -{ - DBUG_ASSERT(pipeState == PendingFullBufferMsg); - PipeRpy_t msg[32]; - int bytes; - PipeRpy_t* lastMsg; - while ((bytes = read(msgPipe, msg, sizeof(msg))) > 0) - { - DBUG_PRINT("db2i_ioBuffers::drainPipe",("Pipe returned %d bytes", bytes)); - lastMsg = &msg[bytes / (sizeof(msg[0]))-1]; - if (lastMsg->CumRowCnt == maxRows() || - lastMsg->RtnCod != 0) - { - pipeState = ConsumedFullBufferMsg; - break; - } - - } - DBUG_PRINT("db2i_ioBuffers::drainPipe",("rc = %d, rows = %d, max = %d", lastMsg->RtnCod, lastMsg->CumRowCnt, (uint32)maxRows())); -} - - -/** - Poll the message pipe for async read messages - - Only valid in async - - @param orientation The direction to use when reading through the table. -*/ -void IOAsyncReadBuffer::pollNextRow(char orientation) -{ - DBUG_ASSERT(readIsAsync); - - // Handle the case in which the buffer is full. - if (rowCount() == maxRows()) - { - // If we haven't read to the end, exit here. - if (readCursor < rowCount()) - return; - - if (pipeState == PendingFullBufferMsg) - drainPipe(); - if (pipeState == ConsumedFullBufferMsg) - loadNewRows(orientation); - } - - if (!rc) - { - PipeRpy_t* lastMsg = NULL; - while (true) - { - PipeRpy_t msg[32]; - int bytes = read(msgPipe, msg, sizeof(msg)); - DBUG_PRINT("db2i_ioBuffers::pollNextRow",("Pipe returned %d bytes", bytes)); - - if (unlikely(bytes < 0)) - { - DBUG_PRINT("db2i_ioBuffers::pollNextRow", ("Error")); - rc = errno; - break; - } - else if (bytes == 0) - break; - - DBUG_ASSERT(bytes % sizeof(msg[0]) == 0); - lastMsg = &msg[bytes / (sizeof(msg[0]))-1]; - - if (lastMsg->RtnCod || (lastMsg->CumRowCnt == usedRows())) - { - rc = lastMsg->RtnCod; - break; - } - } - - *releaseRowNeeded = true; - - if (rc == QMY_ERR_END_OF_BLOCK) - rc = 0; - else if (rc == QMY_ERR_END_OF_FILE) - { - // If we reach EOF or end-of-key, DB2 guarantees that no rows will be locked. - rc = HA_ERR_END_OF_FILE; - *releaseRowNeeded = false; - } - else if (rc == QMY_ERR_KEY_NOT_FOUND) - { - rc = HA_ERR_KEY_NOT_FOUND; - *releaseRowNeeded = false; - } - - if (lastMsg) - DBUG_PRINT("db2i_ioBuffers::pollNextRow", ("Good data: rc=%d; rows=%d; usedRows=%d", lastMsg->RtnCod, lastMsg->CumRowCnt, (uint32)usedRows())); - if (lastMsg && likely(!rc)) - { - if (lastMsg->CumRowCnt < maxRows()) - pipeState = PendingFullBufferMsg; - else - pipeState = ConsumedFullBufferMsg; - - DBUG_ASSERT(lastMsg->CumRowCnt <= usedRows()); - - } - DBUG_ASSERT(rowCount() <= getRowCapacity()); - } - DBUG_PRINT("db2i_ioBuffers::pollNextRow", ("filledRows: %d, rc: %d", rowCount(), rc)); - if (rc) closePipe(); -} - - -/** - Prepare for the destruction of the row buffer storage. -*/ -void IOAsyncReadBuffer::prepForFree() -{ - interruptRead(); - rewind(); - IORowBuffer::prepForFree(); -} - - -/** - Initialize the newly allocated storage. - - @param sizeChanged Indicates whether the storage capacity is being changed. -*/ -void IOAsyncReadBuffer::initAfterAllocate(bool sizeChanged) -{ - rewind(); - - if (sizeChanged || ((void*)rrnList == NULL)) - rrnList.realloc(getRowCapacity() * sizeof(uint32)); -} - - -/** - Send an initial read request - - @param infile The file (table/index) being read from - @param orientation The orientation to use for this read request - @param rowsToBuffer The number of rows to request each time - @param useAsync Whether reads should be performed asynchronously. - @param key The key to use (if any) - @param keyLength The length of key (if any) - @param keyParts The number of columns in the key (if any) - -*/ -void IOAsyncReadBuffer::newReadRequest(FILE_HANDLE infile, - char orientation, - uint32 rowsToBuffer, - bool useAsync, - ILEMemHandle key, - int keyLength, - int keyParts) -{ - DBUG_ENTER("db2i_ioBuffers::newReadRequest"); - DBUG_ASSERT(rowsToBuffer <= getRowCapacity()); -#ifndef DBUG_OFF - if (readCursor < rowCount()) - DBUG_PRINT("PERF:",("Wasting %d buffered rows!\n", rowCount() - readCursor)); -#endif - - int fildes[2]; - int ileDescriptor = QMY_REUSE; - - interruptRead(); - - if (likely(useAsync)) - { - if (rowsToBuffer == 1) - { - // Async provides little or no benefit for single row reads, so we turn it off - DBUG_PRINT("db2i_ioBuffers::newReadRequest", ("Disabling async")); - useAsync = false; - } - else - { - rc = pipe(fildes); - if (rc) DBUG_VOID_RETURN; - - // Translate the pipe write descriptor into the equivalent ILE descriptor - rc = fstatx(fildes[1], (struct stat*)&ileDescriptor, sizeof(ileDescriptor), STX_XPFFD_PASE); - if (rc) - { - close(fildes[0]); - close(fildes[1]); - DBUG_VOID_RETURN; - } - pipeState = Untouched; - msgPipe = fildes[0]; - - DBUG_PRINT("db2i_ioBuffers::newReadRequest", ("Opened pipe %d", fildes[0])); - } - } - - file = infile; - readIsAsync = useAsync; - rowsToBlock = rowsToBuffer; - - rewind(); - maxRows() = 1; - rc = getBridge()->expectErrors(QMY_ERR_END_OF_BLOCK, QMY_ERR_LOB_SPACE_TOO_SMALL) - ->read(file, - ptr(), - accessIntent, - commitLevel, - orientation, - useAsync, - rrnList, - key, - keyLength, - keyParts, - ileDescriptor); - - // Having shared the pipe with ILE, we relinquish our claim on the write end - // of the pipe. - if (useAsync) - close(fildes[1]); - - // If we reach EOF or end-of-key, DB2 guarantees that no rows will be locked. - if (rc == QMY_ERR_END_OF_FILE) - { - rc = HA_ERR_END_OF_FILE; - *releaseRowNeeded = false; - } - else if (rc == QMY_ERR_KEY_NOT_FOUND) - { - if (rowCount()) - rc = HA_ERR_END_OF_FILE; - else - rc = HA_ERR_KEY_NOT_FOUND; - *releaseRowNeeded = false; - } - else - *releaseRowNeeded = true; - - DBUG_VOID_RETURN; -} diff --git a/storage/ibmdb2i/db2i_ioBuffers.h b/storage/ibmdb2i/db2i_ioBuffers.h deleted file mode 100644 index 350d854f055..00000000000 --- a/storage/ibmdb2i/db2i_ioBuffers.h +++ /dev/null @@ -1,416 +0,0 @@ -/* -Licensed Materials - Property of IBM -DB2 Storage Engine Enablement -Copyright IBM Corporation 2007,2008 -All rights reserved - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - (a) Redistributions of source code must retain this list of conditions, the - copyright notice in section {d} below, and the disclaimer following this - list of conditions. - (b) Redistributions in binary form must reproduce this list of conditions, the - copyright notice in section (d) below, and the disclaimer following this - list of conditions, in the documentation and/or other materials provided - with the distribution. - (c) The name of IBM may not be used to endorse or promote products derived from - this software without specific prior written permission. - (d) The text of the required copyright notice is: - Licensed Materials - Property of IBM - DB2 Storage Engine Enablement - Copyright IBM Corporation 2007,2008 - All rights reserved - -THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - - -/** - @file db2i_ioBuffers.h - - @brief Buffer classes used for interacting with QMYSE read/write buffers. - -*/ - - -#include "db2i_validatedPointer.h" -#include "mysql_priv.h" -#include -#include -#include - -// Needed for compilers which do not include fstatx in standard headers. -extern "C" int fstatx(int, struct stat *, int, int); - -/** - Basic row buffer - - Provides the basic structure and methods needed for communicating - with QMYSE I/O APIs. - - @details All QMYSE I/O apis use a buffer that is structured as two integer - row counts (max and used) and storage for some number of rows. The row counts - are both input and output for the API, and their usage depends on the - particular API invoked. This class encapsulates that buffer definition. -*/ -class IORowBuffer -{ - public: - IORowBuffer() : allocSize(0), rowLength(0) {;} - ~IORowBuffer() { freeBuf(); } - ValidatedPointer& ptr() { return data; } - - /** - Sets up the buffer to hold the size indicated. - - @param rowLen length of the rows that will be stored in this buffer - @param nullMapOffset position of null map within each row - @param size buffer size requested - */ - void allocBuf(uint32 rowLen, uint16 nullMapOffset, uint32 size) - { - nullOffset = nullMapOffset; - uint32 newSize = size + sizeof(BufferHdr_t); - // If the internal structure of the row is changing, we need to - // remember this and notify the subclasses via initAfterAllocate(); - bool formatChanged = ((size/rowLen) != rowCapacity); - - if (newSize > allocSize) - { - this->freeBuf(); - data.alloc(newSize); - if (likely((void*)data)) - allocSize = newSize; - } - - if (likely((void*)data)) - { - DBUG_ASSERT((uint64)(void*)data % 16 == 0); - rowLength = rowLen; - rowCapacity = size / rowLength; - initAfterAllocate(formatChanged); - } - else - { - allocSize = 0; - rowCapacity = 0; - } - - DBUG_PRINT("db2i_ioBuffers::allocBuf",("rowCapacity = %d", rowCapacity)); - } - - void zeroBuf() - { - memset(data, 0, allocSize); - } - - void freeBuf() - { - if (likely(allocSize)) - { - prepForFree(); - DBUG_PRINT("IORowBuffer::freeBuf",("Freeing 0x%p", (char*)data)); - data.dealloc(); - } - } - - char* getRowN(uint32 n) - { - if (unlikely(n >= getRowCapacity())) - return NULL; - return (char*)data + sizeof(BufferHdr_t) + (rowLength * n); - }; - - uint32 getRowCapacity() const {return rowCapacity;} - uint32 getRowNullOffset() const {return nullOffset;} - uint32 getRowLength() const {return rowLength;} - - protected: - /** - Called prior to freeing buffer storage so that subclasses can do - any required cleanup - */ - virtual void prepForFree() - { - allocSize = 0; - rowCapacity = 0; - } - - /** - Called after buffer storage so that subclasses can do any required setup. - */ - virtual void initAfterAllocate(bool sizeChanged) { return;} - - ValidatedPointer data; - uint32 allocSize; - uint32 rowCapacity; - uint32 rowLength; - uint16 nullOffset; - uint32& usedRows() const { return ((BufferHdr_t*)(char*)data)->UsedRowCnt; } - uint32& maxRows() const {return ((BufferHdr_t*)(char*)data)->MaxRowCnt; } -}; - - -/** - Write buffer - - Implements methods for inserting data into a row buffer for use with the - QMY_WRITE and QMY_UPDATE APIs. - - @details The max row count defines how many rows are in the buffer. The used - row count is updated by QMYSE to indicate how many rows have been - successfully written. -*/ -class IOWriteBuffer : public IORowBuffer -{ - public: - bool endOfBuffer() const {return (maxRows() == getRowCapacity());} - - char* addRow() - { - return getRowN(maxRows()++); - } - - void resetAfterWrite() - { - maxRows() = 0; - } - - void deleteRow() - { - --maxRows(); - } - - uint32 rowCount() const {return maxRows();} - - uint32 rowsWritten() const {return usedRows()-1;} - - private: - void initAfterAllocate(bool sizeChanged) {maxRows() = 0; usedRows() = 0;} -}; - - -/** - Read buffer - - Implements methods for reading data from and managing a row buffer for use - with the QMY_READ APIs. This is primarily for use with metainformation queries. -*/ -class IOReadBuffer : public IORowBuffer -{ - public: - - IOReadBuffer() {;} - IOReadBuffer(uint32 rows, uint32 rowLength) - { - allocBuf(rows, 0, rows * rowLength); - maxRows() = rows; - } - - uint32 rowCount() {return usedRows();} - void setRowsToProcess(uint32 rows) { maxRows() = rows; } -}; - - -/** - Read buffer - - Implements methods for reading data from and managing a row buffer for use - with the QMY_READ APIs. - - @details This class supports both sync and async read modes. The max row - count defines the number of rows that are requested to be read. The used row - count defines how many rows have been read. Sync mode is reasonably - straightforward, but async mode has a complex system of communicating with - QMYSE that is optimized for low latency. In async mode, the used row count is - updated continuously by QMYSE as rows are read. At the same time, messages are - sent to the associated pipe indicating that a row has been read. As long as - the internal read cursor lags behind the used row count, the pipe is never - consulted. But if the internal read cursor "catches up to" the used row count, - then we block on the pipe until we find a message indicating that a new row - has been read or that an error has occurred. -*/ -class IOAsyncReadBuffer : public IOReadBuffer -{ - public: - IOAsyncReadBuffer() : - file(0), readIsAsync(false), msgPipe(QMY_REUSE), bridge(NULL) - { - } - - ~IOAsyncReadBuffer() - { - interruptRead(); - rrnList.dealloc(); - } - - - /** - Signal read operation complete - - Indicates that the storage engine requires no more data from the table. - Must be called between calls to newReadRequest(). - */ - void endRead() - { -#ifndef DBUG_OFF - if (readCursor < rowCount()) - DBUG_PRINT("PERF:",("Wasting %d buffered rows!\n", rowCount() - readCursor)); -#endif - interruptRead(); - - file = 0; - bridge = NULL; - } - - /** - Update data that may change on each read operation - */ - void update(char newAccessIntent, - bool* newReleaseRowNeeded, - char commitLvl) - { - accessIntent = newAccessIntent; - releaseRowNeeded = newReleaseRowNeeded; - commitLevel = commitLvl; - } - - /** - Read the next row in the table. - - Return a pointer to the next row in the table, where "next" is defined - by the orientation. - - @param orientaton - @param[out] rrn The relative record number of the row returned. Not reliable - if NULL is returned by this function. - - @return Pointer to the row. Null if no more rows are available or an error - occurred. - */ - char* readNextRow(char orientation, uint32& rrn) - { - DBUG_PRINT("db2i_ioBuffers::readNextRow", ("readCursor: %d, filledRows: %d, rc: %d", readCursor, rowCount(), rc)); - - while (readCursor >= rowCount() && !rc) - { - if (!readIsAsync) - loadNewRows(orientation); - else - pollNextRow(orientation); - } - - if (readCursor >= rowCount()) - return NULL; - - rrn = rrnList[readCursor]; - return getRowN(readCursor++); - } - - /** - Retrieve the return code generated by the last operation. - - @return The return code, translated to the appropriate HA_ERR_* - value if possible. - */ - int32 lastrc() - { - return db2i_ileBridge::translateErrorCode(rc); - } - - void rewind() - { - readCursor = 0; - rc = 0; - usedRows() = 0; - } - - bool reachedEOD() { return EOD; } - - void newReadRequest(FILE_HANDLE infile, - char orientation, - uint32 rowsToBuffer, - bool useAsync, - ILEMemHandle key, - int keyLength, - int keyParts); - - private: - - /** - End any running async read operation. - */ - void interruptRead() - { - closePipe(); - if (file && readIsAsync && (rc == 0) && (rowCount() < getRowCapacity())) - { - DBUG_PRINT("IOReadBuffer::interruptRead", ("PERF: Interrupting %d", (uint32)file)); - getBridge()->readInterrupt(file); - } - } - - void closePipe() - { - if (msgPipe != QMY_REUSE) - { - DBUG_PRINT("db2i_ioBuffers::closePipe", ("Closing pipe %d", msgPipe)); - close(msgPipe); - msgPipe = QMY_REUSE; - } - } - - /** - Get a pointer to the active ILE bridge. - - Getting the bridge pointer is (relatively) expensive, so we cache - it off for each operation. - */ - db2i_ileBridge* getBridge() - { - if (unlikely(bridge == NULL)) - { - bridge = db2i_ileBridge::getBridgeForThread(); - } - return bridge; - } - - void drainPipe(); - void pollNextRow(char orientation); - void prepForFree(); - void initAfterAllocate(bool sizeChanged); - void loadNewRows(char orientation); - - - uint32 readCursor; // Read position within buffer - int32 rc; // Last return code received - ValidatedPointer rrnList; // Receiver for list of rrns - char accessIntent; // The access intent for this read - char commitLevel; // What isolation level should be used - char EOD; // Whether end-of-data was hit - char readIsAsync; // Are reads to be done asynchronously? - bool* releaseRowNeeded; - /* Does the caller need to release the current row when finished reading */ - FILE_HANDLE file; // The file to be read - int msgPipe; - /* The read descriptor of the pipe used to pass messages during async reads */ - db2i_ileBridge* bridge; // Cached pointer to bridge - uint32 rowsToBlock; // Number of rows to request - enum - { - ConsumedFullBufferMsg, - PendingFullBufferMsg, - Untouched - } pipeState; - /* The state of the async read message pipe */ -}; - diff --git a/storage/ibmdb2i/db2i_misc.h b/storage/ibmdb2i/db2i_misc.h deleted file mode 100644 index f0b527aaad0..00000000000 --- a/storage/ibmdb2i/db2i_misc.h +++ /dev/null @@ -1,129 +0,0 @@ -/* -Licensed Materials - Property of IBM -DB2 Storage Engine Enablement -Copyright IBM Corporation 2007,2008 -All rights reserved - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - (a) Redistributions of source code must retain this list of conditions, the - copyright notice in section {d} below, and the disclaimer following this - list of conditions. - (b) Redistributions in binary form must reproduce this list of conditions, the - copyright notice in section (d) below, and the disclaimer following this - list of conditions, in the documentation and/or other materials provided - with the distribution. - (c) The name of IBM may not be used to endorse or promote products derived from - this software without specific prior written permission. - (d) The text of the required copyright notice is: - Licensed Materials - Property of IBM - DB2 Storage Engine Enablement - Copyright IBM Corporation 2007,2008 - All rights reserved - -THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - -#ifndef DB2I_MISC_H -#define DB2I_MISC_H - -/** - Undelimit quote-delimited DB2 names in-place -*/ -void stripExtraQuotes(char* name, uint maxLen) -{ - char* oldName = (char*)sql_strdup(name); - uint i = 0; - uint j = 0; - do - { - name[j] = oldName[i]; - if (oldName[i] == '"' && oldName[i+1] == '"') - ++i; - } while (++j < maxLen && oldName[++i]); - - if (j == maxLen) - --j; - name[j] = 0; -} - -/** - Convert a MySQL identifier name into a DB2 compatible format - - @parm input The MySQL name - @parm output The DB2 name - @parm outlen The amount of space allocated for output - @parm delimit Should delimiting quotes be placed around the converted name? - @parm delimitQuotes Should quotes in the MySQL be delimited with additional quotes? - - @return FALSE if output was too small and name was truncated; TRUE otherwise -*/ -bool convertMySQLNameToDB2Name(const char* input, - char* output, - size_t outlen, - bool delimit = true, - bool delimitQuotes = true) -{ - uint o = 0; - if (delimit) - output[o++] = '"'; - - uint i = 0; - do - { - output[o] = input[i]; - if (delimitQuotes && input[i] == '"') - output[++o] = '"'; - } while (++o < outlen-2 && input[++i]); - - if (delimit) - output[o++] = '"'; - output[min(o, outlen-1)] = 0; // This isn't the most user-friendly way to handle overflows, - // but at least its safe. - return (o <= outlen-1); -} - -bool isOrdinaryIdentifier(const char* s) -{ - while (*s) - { - if (my_isupper(system_charset_info, *s) || - my_isdigit(system_charset_info, *s) || - (*s == '_') || - (*s == '@') || - (*s == '$') || - (*s == '#') || - (*s == '"')) - ++s; - else - return false; - } - return true; -} - -/** - Fill memory with a 16-bit word. - - @param p Pointer to space to fill. - @param v Value to fill - @param l Length of space (in 16-bit words) -*/ -void memset16(void* p, uint16 v, size_t l) -{ - uint16* p2=(uint16*)p; - while (l--) - { - *(p2++) = v; - } -} - -#endif diff --git a/storage/ibmdb2i/db2i_myconv.cc b/storage/ibmdb2i/db2i_myconv.cc deleted file mode 100644 index 7be6e1236cd..00000000000 --- a/storage/ibmdb2i/db2i_myconv.cc +++ /dev/null @@ -1,1498 +0,0 @@ -/* -Licensed Materials - Property of IBM -DB2 Storage Engine Enablement -Copyright IBM Corporation 2007,2008 -All rights reserved - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - (a) Redistributions of source code must retain this list of conditions, the - copyright notice in section {d} below, and the disclaimer following this - list of conditions. - (b) Redistributions in binary form must reproduce this list of conditions, the - copyright notice in section (d) below, and the disclaimer following this - list of conditions, in the documentation and/or other materials provided - with the distribution. - (c) The name of IBM may not be used to endorse or promote products derived from - this software without specific prior written permission. - (d) The text of the required copyright notice is: - Licensed Materials - Property of IBM - DB2 Storage Engine Enablement - Copyright IBM Corporation 2007,2008 - All rights reserved - -THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - -/** - @file - - @brief A direct map optimization of iconv and related functions - This was show to significantly reduce character conversion cost - for short strings when compared to calling iconv system code. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "db2i_myconv.h" -#include "db2i_global.h" - -int32_t myconvDebug=0; - -static char szGetTimeString[20]; -static char * GetTimeString(time_t now) -{ - struct tm * tm; - - now = time(&now); - tm = (struct tm *) localtime(&now); - sprintf(szGetTimeString, "%04d/%02d/%02d %02d:%02d:%02d", - tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec); - - return szGetTimeString; -} - -static MEM_ROOT dmapMemRoot; - -void initMyconv() -{ - init_alloc_root(&dmapMemRoot, 0x200, 0); -} - -void cleanupMyconv() -{ - free_root(&dmapMemRoot,0); -} - - -#ifdef DEBUG -/* type: */ -#define STDOUT_WITH_TIME -1 /* to stdout with time */ -#define STDERR_WITH_TIME -2 /* to stderr with time */ -#define STDOUT_WO_TIME 1 /* : to stdout */ -#define STDERR_WO_TIME 2 /* : to stderr */ - - -static void MyPrintf(long type, - char * fmt, ...) -{ - char StdoutFN[256]; - va_list ap; - char * p; - time_t now; - FILE * fd=stderr; - - if (type < 0) - { - now = time(&now); - fprintf(fd, "%s ", GetTimeString(now)); - } - va_start(ap, fmt); - vfprintf(fd, fmt, ap); - va_end(ap); -} -#endif - - - - -#define MAX_CONVERTER 128 - -mycstoccsid(const char* pname) -{ - if (strcmp(pname, "UTF-16")==0) - return 1200; - else if (strcmp(pname, "big5")==0) - return 950; - else - return cstoccsid(pname); -} -#define cstoccsid mycstoccsid - -static struct __myconv_rec myconv_rec [MAX_CONVERTER]; -static struct __dmap_rec dmap_rec [MAX_CONVERTER]; - -static int dmap_open(const char * to, - const char * from, - const int32_t idx) -{ - if (myconvIsSBCS(from) && myconvIsSBCS(to)) { - dmap_rec[idx].codingSchema = DMAP_S2S; - if ((dmap_rec[idx].dmapS2S = (uchar *) alloc_root(&dmapMemRoot, 0x100)) == NULL) { -#ifdef DEBUG - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n", - to, from, idx, DMAP_S2S, errno, __FILE__,__LINE__); -#endif - return -1; - } - memset(dmap_rec[idx].dmapS2S, 0x00, 0x100); - myconv_rec[idx].allocatedSize=0x100; - - { - char dmapSrc[0x100]; - iconv_t cd; - int32_t i; - size_t inBytesLeft=0x100; - size_t outBytesLeft=0x100; - size_t len; - char * inBuf=dmapSrc; - char * outBuf=(char *) dmap_rec[idx].dmapS2S; - - if ((cd = iconv_open(to, from)) == (iconv_t) -1) { -#ifdef DEBUG - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d) failed with iconv_open(), errno = %d in %s at %d\n", - to, from, idx, errno, __FILE__,__LINE__); -#endif - return -1; - } - - inBytesLeft = 0x100; - for (i = 0; i < inBytesLeft; ++i) - dmapSrc[i]=i; - - do { - if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) { -#ifdef DEBUG - if (myconvDebug) { - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d), CS=%d: iconv() returns %d, errno = %d in %s at %d\n", - to, from, idx, DMAP_S2S, len, errno, __FILE__,__LINE__); - MyPrintf(STDERR_WITH_TIME, - "inBytesLeft = %d, inBuf - dmapSrc = %d\n", inBytesLeft, inBuf-dmapSrc); - MyPrintf(STDERR_WITH_TIME, - "outBytesLeft = %d, outBuf - dmapS2S = %d\n", outBytesLeft, outBuf-(char *) dmap_rec[idx].dmapS2S); - } - if ((inBytesLeft == 86 || inBytesLeft == 64 || inBytesLeft == 1) && - memcmp(from, "IBM-1256", 9) == 0 && - memcmp(to, "IBM-420", 8) == 0) { - /* Known problem for IBM-1256_IBM-420 */ - --inBytesLeft; - ++inBuf; - *outBuf=0x00; - ++outBuf; - --outBytesLeft; - continue; - } else if ((inBytesLeft == 173 || inBytesLeft == 172 || - inBytesLeft == 74 || inBytesLeft == 73 || - inBytesLeft == 52 || inBytesLeft == 50 || - inBytesLeft == 31 || inBytesLeft == 20 || - inBytesLeft == 6) && - memcmp(to, "IBM-1256", 9) == 0 && - memcmp(from, "IBM-420", 8) == 0) { - /* Known problem for IBM-420_IBM-1256 */ - --inBytesLeft; - ++inBuf; - *outBuf=0x00; - ++outBuf; - --outBytesLeft; - continue; - } else if ((128 >= inBytesLeft) && - memcmp(to, "IBM-037", 8) == 0 && - memcmp(from, "IBM-367", 8) == 0) { - /* Known problem for IBM-367_IBM-037 */ - --inBytesLeft; - ++inBuf; - *outBuf=0x00; - ++outBuf; - --outBytesLeft; - continue; - } else if (((1 <= inBytesLeft && inBytesLeft <= 4) || (97 <= inBytesLeft && inBytesLeft <= 128)) && - memcmp(to, "IBM-838", 8) == 0 && - memcmp(from, "TIS-620", 8) == 0) { - /* Known problem for TIS-620_IBM-838 */ - --inBytesLeft; - ++inBuf; - *outBuf=0x00; - ++outBuf; - --outBytesLeft; - continue; - } - iconv_close(cd); - return -1; -#else - /* Tolerant to undefined conversions for any converter */ - --inBytesLeft; - ++inBuf; - *outBuf=0x00; - ++outBuf; - --outBytesLeft; - continue; -#endif - } - } while (inBytesLeft > 0); - - if (myconvIsISO(to)) - myconv_rec[idx].subS=0x1A; - else if (myconvIsASCII(to)) - myconv_rec[idx].subS=0x7F; - else if (myconvIsEBCDIC(to)) - myconv_rec[idx].subS=0x3F; - - if (myconvIsISO(from)) - myconv_rec[idx].srcSubS=0x1A; - else if (myconvIsASCII(from)) - myconv_rec[idx].srcSubS=0x7F; - else if (myconvIsEBCDIC(from)) - myconv_rec[idx].srcSubS=0x3F; - - iconv_close(cd); - } - } else if (((myconvIsSBCS(from) && myconvIsUnicode2(to)) && (dmap_rec[idx].codingSchema = DMAP_S2U)) || - ((myconvIsSBCS(from) && myconvIsUTF8(to)) && (dmap_rec[idx].codingSchema = DMAP_S28))) { - int i; - - /* single byte mapping */ - if ((dmap_rec[idx].dmapD12U = (UniChar *) alloc_root(&dmapMemRoot, 0x100 * 2)) == NULL) { -#ifdef DEBUG - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n", - to, from, idx, DMAP_S2U, errno, __FILE__,__LINE__); -#endif - return -1; - } - memset(dmap_rec[idx].dmapD12U, 0x00, 0x100 * 2); - myconv_rec[idx].allocatedSize=0x100 * 2; - - - { - char dmapSrc[2]; - iconv_t cd; - int32_t i; - size_t inBytesLeft; - size_t outBytesLeft; - size_t len; - char * inBuf; - char * outBuf; - char SS=0x1A; -#ifdef support_surrogate - if ((cd = iconv_open("UTF-16", from)) == (iconv_t) -1) { -#else - if ((cd = iconv_open("UCS-2", from)) == (iconv_t) -1) { -#endif -#ifdef DEBUG - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d) failed with iconv_open(), errno = %d in %s at %d\n", - to, from, idx, errno, __FILE__,__LINE__); -#endif - return -1; - } - - for (i = 0; i < 0x100; ++i) { - dmapSrc[0]=i; - inBuf=dmapSrc; - inBytesLeft=1; - outBuf=(char *) &(dmap_rec[idx].dmapD12U[i]); - outBytesLeft=2; - if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) { - if ((errno == EILSEQ || errno == EINVAL) && - inBytesLeft == 1 && - outBytesLeft == 2) { - continue; - } else { -#ifdef DEBUG - if (myconvDebug) { - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d) failed to initialize with iconv(cd,%02x,%d,%02x%02x,%d), errno = %d in %s at %d\n", - to, from, idx, dmapSrc[0], 1, - (&dmap_rec[idx].dmapD12U[i])[0],(&dmap_rec[idx].dmapD12U[i])[1], 2, - errno, __FILE__,__LINE__); - MyPrintf(STDERR_WITH_TIME, - "inBytesLeft=%d, outBytesLeft=%d, %02x%02x\n", - inBytesLeft, outBytesLeft, - (&dmap_rec[idx].dmapD12U[i])[0],(&dmap_rec[idx].dmapD12U[i])[1]); - } -#endif - iconv_close(cd); - return -1; - } - dmap_rec[idx].dmapD12U[i]=0x0000; - } - if (dmap_rec[idx].dmapE02U[i] == 0x001A && /* pick the first one */ - myconv_rec[idx].srcSubS == 0x00) { - myconv_rec[idx].srcSubS=i; - } - } - iconv_close(cd); - } - myconv_rec[idx].subS=0x1A; - myconv_rec[idx].subD=0xFFFD; - - - } else if (((myconvIsUCS2(from) && myconvIsSBCS(to)) && (dmap_rec[idx].codingSchema = DMAP_U2S)) || - ((myconvIsUTF16(from) && myconvIsSBCS(to)) && (dmap_rec[idx].codingSchema = DMAP_T2S)) || - ((myconvIsUTF8(from) && myconvIsSBCS(to)) && (dmap_rec[idx].codingSchema = DMAP_82S))) { - /* UTF-16 -> SBCS, the direct map a bit of waste of space, - * binary search may be reasonable alternative - */ - if ((dmap_rec[idx].dmapU2S = (uchar *) alloc_root(&dmapMemRoot, 0x10000 * 2)) == NULL) { -#ifdef DEBUG - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n", - to, from, idx, DMAP_U2S, errno, __FILE__,__LINE__); -#endif - return -1; - } - memset(dmap_rec[idx].dmapU2S, 0x00, 0x10000); - myconv_rec[idx].allocatedSize=(0x10000 * 2); - - { - iconv_t cd; - int32_t i; - -#ifdef support_surrogate - if ((cd = iconv_open(to, "UTF-16")) == (iconv_t) -1) { -#else - if ((cd = iconv_open(to, "UCS-2")) == (iconv_t) -1) { -#endif -#ifdef DEBUG - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d) failed with iconv_open(), errno = %d in %s at %d\n", - to, from, idx, errno, __FILE__,__LINE__); -#endif - return -1; - } - - for (i = 0; i < 0x100; ++i) { - UniChar dmapSrc[0x100]; - int32_t j; - for (j = 0; j < 0x100; ++j) { - dmapSrc[j]=i * 0x100 + j; - } - char * inBuf=(char *) dmapSrc; - char * outBuf=(char *) &(dmap_rec[idx].dmapU2S[i*0x100]); - size_t inBytesLeft=sizeof(dmapSrc); - size_t outBytesLeft=0x100; - size_t len; - - if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) { - if (inBytesLeft == 0 && outBytesLeft == 0) { /* a number of substitution returns */ - continue; - } -#ifdef DEBUG - if (myconvDebug) { - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d) failed to initialize with iconv(), errno = %d in %s at %d\n", - from, to, idx, errno, __FILE__,__LINE__); - MyPrintf(STDERR_WITH_TIME, - "iconv() retuns %d, errno=%d, InBytesLeft=%d, OutBytesLeft=%d\n", - len, errno, inBytesLeft, outBytesLeft, __FILE__,__LINE__); - } -#endif - iconv_close(cd); - return -1; - } - } - iconv_close(cd); - - myconv_rec[idx].subS = dmap_rec[idx].dmapU2S[0x1A]; - myconv_rec[idx].subD = dmap_rec[idx].dmapU2S[0xFFFD]; - myconv_rec[idx].srcSubS = 0x1A; - myconv_rec[idx].srcSubD = 0xFFFD; - } - - - - } else if (((myconvIsDBCS(from) && myconvIsUnicode2(to)) && (dmap_rec[idx].codingSchema = DMAP_D2U)) || - ((myconvIsDBCS(from) && myconvIsUTF8(to)) && (dmap_rec[idx].codingSchema = DMAP_D28))) { - int i; - /* single byte mapping */ - if ((dmap_rec[idx].dmapD12U = (UniChar *) alloc_root(&dmapMemRoot, 0x100 * 2)) == NULL) { -#ifdef DEBUG - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n", - to, from, idx, DMAP_D2U, errno, __FILE__,__LINE__); -#endif - return -1; - } - memset(dmap_rec[idx].dmapD12U, 0x00, 0x100 * 2); - - /* double byte mapping, assume 7 bit ASCII is not use as the first byte of DBCS. */ - if ((dmap_rec[idx].dmapD22U = (UniChar *) alloc_root(&dmapMemRoot, 0x8000 * 2)) == NULL) { -#ifdef DEBUG - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n", - to, from, idx, DMAP_D2U, errno, __FILE__,__LINE__); -#endif - return -1; - } - memset(dmap_rec[idx].dmapD22U, 0x00, 0x8000 * 2); - - myconv_rec[idx].allocatedSize=(0x100 + 0x8000) * 2; - - - { - char dmapSrc[2]; - iconv_t cd; - int32_t i; - size_t inBytesLeft; - size_t outBytesLeft; - size_t len; - char * inBuf; - char * outBuf; - char SS=0x1A; - -#ifdef support_surrogate - if ((cd = iconv_open("UTF-16", from)) == (iconv_t) -1) { -#else - if ((cd = iconv_open("UCS-2", from)) == (iconv_t) -1) { -#endif -#ifdef DEBUG - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d) failed with iconv_open(), errno = %d in %s at %d\n", - to, from, idx, errno, __FILE__,__LINE__); -#endif - return -1; - } - - for (i = 0; i < 0x100; ++i) { - dmapSrc[0]=i; - inBuf=dmapSrc; - inBytesLeft=1; - outBuf=(char *) (&dmap_rec[idx].dmapD12U[i]); - outBytesLeft=2; - if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) { - if ((errno == EILSEQ || errno == EINVAL) && - inBytesLeft == 1 && - outBytesLeft == 2) { - continue; - } else { -#ifdef DEBUG - if (myconvDebug) { - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d) failed to initialize with iconv(cd,%02x,%d,%02x%02x,%d), errno = %d in %s at %d\n", - to, from, idx, dmapSrc[0], 1, - (&dmap_rec[idx].dmapD12U[i])[0],(&dmap_rec[idx].dmapD12U[i])[1], 2, - errno, __FILE__,__LINE__); - MyPrintf(STDERR_WITH_TIME, - "inBytesLeft=%d, outBytesLeft=%d, %02x%02x\n", - inBytesLeft, outBytesLeft, - (&dmap_rec[idx].dmapD12U[i])[0],(&dmap_rec[idx].dmapD12U[i])[1]); - } -#endif - iconv_close(cd); - return -1; - } - dmap_rec[idx].dmapD12U[i]=0x0000; - } - if (dmap_rec[idx].dmapD12U[i] == 0x001A && /* pick the first one */ - myconv_rec[idx].srcSubS == 0x00) { - myconv_rec[idx].srcSubS=i; - } - } - - - for (i = 0x80; i < 0x100; ++i) { - int j; - if (dmap_rec[idx].dmapD12U[i] != 0x0000) - continue; - for (j = 0x01; j < 0x100; ++j) { - dmapSrc[0]=i; - dmapSrc[1]=j; - int offset = i-0x80; - offset<<=8; - offset+=j; - - inBuf=dmapSrc; - inBytesLeft=2; - outBuf=(char *) &(dmap_rec[idx].dmapD22U[offset]); - outBytesLeft=2; - if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) { - if (inBytesLeft == 2 && outBytesLeft == 2 && (errno == EILSEQ || errno == EINVAL)) { - ; /* invalid DBCS character, dmapDD2U[offset] remains 0x0000 */ - } else { -#ifdef DEBUG - if (myconvDebug) { - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d) failed to initialize with iconv(cd,%p,2,%p,2), errno = %d in %s at %d\n", - to, from, idx, - dmapSrc, &(dmap_rec[idx].dmapD22U[offset]), - errno, __FILE__,__LINE__); - MyPrintf(STDERR_WO_TIME, - "iconv(cd,0x%02x%02x,2,0x%04x,2) returns %d, inBytesLeft=%d, outBytesLeft=%d\n", - dmapSrc[0], dmapSrc[1], - dmap_rec[idx].dmapD22U[offset], - len, inBytesLeft, outBytesLeft); - } -#endif - iconv_close(cd); - return -1; - } - } else { -#ifdef TRACE_DMAP - if (myconvDebug) { - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d) failed to initialize with iconv(), rc=%d, errno=%d in %s at %d\n", - to, from, idx, len, errno, __FILE__,__LINE__); - MyPrintf(STDERR_WITH_TIME, - "%04X: src=%04X%04X, inBuf=0x%02X%02X, inBytesLeft=%d, outBuf=%02X%02X%02X, outBytesLeft=%d\n", - i, dmapSrc[0], dmapSrc[1], inBuf[0], inBuf[1], - inBytesLeft, outBuf[-2], outBuf[-1], outBuf[0], outBytesLeft); - MyPrintf(STDERR_WITH_TIME, - "&dmapSrc=%p, inBuf=%p, %p, outBuf=%p\n", - dmapSrc, inBuf, dmap_rec[idx].dmapU2M3 + (i - 0x80) * 2, outBuf); - } -#endif - } - } - if (dmap_rec[idx].dmapD12U[i] == 0xFFFD) { /* pick the last one */ - myconv_rec[idx].srcSubD=i* 0x100 + j; - } - } - iconv_close(cd); - } - - myconv_rec[idx].subS=0x1A; - myconv_rec[idx].subD=0xFFFD; - myconv_rec[idx].srcSubD=0xFCFC; - - - } else if (((myconvIsUCS2(from) && myconvIsDBCS(to)) && (dmap_rec[idx].codingSchema = DMAP_U2D)) || - ((myconvIsUTF16(from) && myconvIsDBCS(to)) && (dmap_rec[idx].codingSchema = DMAP_T2D)) || - ((myconvIsUTF8(from) && myconvIsDBCS(to)) && (dmap_rec[idx].codingSchema = DMAP_82D))) { - /* UTF-16 -> DBCS single/double byte */ - /* A single table will cover all characters, assuming no second byte is 0x00. */ - if ((dmap_rec[idx].dmapU2D = (uchar *) alloc_root(&dmapMemRoot, 0x10000 * 2)) == NULL) { -#ifdef DEBUG - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n", - to, from, idx, DMAP_U2D, errno, __FILE__,__LINE__); -#endif - return -1; - } - - memset(dmap_rec[idx].dmapU2D, 0x00, 0x10000 * 2); - myconv_rec[idx].allocatedSize=(0x10000 * 2); - - { - UniChar dmapSrc[1]; - iconv_t cd; - int32_t i; - size_t inBytesLeft; - size_t outBytesLeft; - size_t len; - char * inBuf; - char * outBuf; - -#ifdef support_surrogate - if ((cd = iconv_open(to, "UTF-16")) == (iconv_t) -1) { -#else - if ((cd = iconv_open(to, "UCS-2")) == (iconv_t) -1) { -#endif -#ifdef DEBUG - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d) failed with iconv_open(), errno = %d in %s at %d\n", - to, from, idx, errno, __FILE__,__LINE__); -#endif - return -1; - } - - /* easy implementation, convert 1 Unicode character at one time. */ - /* If the open performance is an issue, convert a chunk such as 128 chracters. */ - /* if the converted length is not the same as the original, convert one by one. */ - (dmap_rec[idx].dmapU2D)[0x0000]=0x00; - for (i = 1; i < 0x10000; ++i) { - dmapSrc[0]=i; - inBuf=(char *) dmapSrc; - inBytesLeft=2; - outBuf=(char *) &((dmap_rec[idx].dmapU2D)[2*i]); - outBytesLeft=2; - do { - if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) { - if (len == 1 && inBytesLeft == 0 && outBytesLeft == 1 && (dmap_rec[idx].dmapU2D)[2*i] == 0x1A) { - /* UCS-2_TIS-620:0x0080 => 0x1A, converted to SBCS replacement character */ - (dmap_rec[idx].dmapU2D)[2*i+1]=0x00; - break; - } else if (len == 1 && inBytesLeft == 0 && outBytesLeft == 0) { - break; - } - if (errno == EILSEQ || errno == EINVAL) { -#ifdef DEBUG - if (myconvDebug) { - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d) failed to initialize with iconv(), errno = %d in %s at %d\n", - to, from, idx, errno, __FILE__,__LINE__); - MyPrintf(STDERR_WO_TIME, - "iconv(cd,%04x,2,%02x%02x,2) returns inBytesLeft=%d, outBytesLeft=%d\n", - dmapSrc[0], - (dmap_rec[idx].dmapU2D)[2*i], (dmap_rec[idx].dmapU2D)[2*i+1], - inBytesLeft, outBytesLeft); - if (outBuf - (char *) dmap_rec[idx].dmapU2M2 > 1) - MyPrintf(STDERR_WO_TIME, "outBuf[-2..2]=%02X%02X%02X%02X%02X\n", outBuf[-2],outBuf[-1],outBuf[0],outBuf[1],outBuf[2]); - else - MyPrintf(STDERR_WO_TIME, "outBuf[0..2]=%02X%02X%02X\n", outBuf[0],outBuf[1],outBuf[2]); - } -#endif - inBuf+=2; - inBytesLeft-=2; - memcpy(outBuf, (char *) &(myconv_rec[idx].subD), 2); - outBuf+=2; - outBytesLeft-=2; - } else { -#ifdef DEBUG - MyPrintf(STDERR_WITH_TIME, - "[%d] dmap_open(%s,%s,%d) failed to initialize with iconv(), errno = %d in %s at %d\n", - i, to, from, idx, errno, __FILE__,__LINE__); - MyPrintf(STDERR_WO_TIME, - "iconv(cd,%04x,2,%02x%02x,2) returns %d inBytesLeft=%d, outBytesLeft=%d\n", - dmapSrc[0], - (dmap_rec[idx].dmapU2D)[2*i], - (dmap_rec[idx].dmapU2D)[2*i+1], - len, inBytesLeft,outBytesLeft); - if (i == 1) { - MyPrintf(STDERR_WO_TIME, - " inBuf [-1..2]=%02x%02x%02x%02x\n", - inBuf[-1],inBuf[0],inBuf[1],inBuf[2]); - MyPrintf(STDERR_WO_TIME, - " outBuf [-1..2]=%02x%02x%02x%02x\n", - outBuf[-1],outBuf[0],outBuf[1],outBuf[2]); - } else { - MyPrintf(STDERR_WO_TIME, - " inBuf [-2..2]=%02x%02x%02x%02x%02x\n", - inBuf[-2],inBuf[-1],inBuf[0],inBuf[1],inBuf[2]); - MyPrintf(STDERR_WO_TIME, - " outBuf [-2..2]=%02x%02x%02x%02x%02x\n", - outBuf[-2],outBuf[-1],outBuf[0],outBuf[1],outBuf[2]); - } -#endif - iconv_close(cd); - return -1; - } - if (len == 0 && inBytesLeft == 0 && outBytesLeft == 1) { /* converted to SBCS */ - (dmap_rec[idx].dmapU2D)[2*i+1]=0x00; - break; - } - } - } while (inBytesLeft > 0); - } - iconv_close(cd); - myconv_rec[idx].subS = dmap_rec[idx].dmapU2D[2*0x1A]; - myconv_rec[idx].subD = dmap_rec[idx].dmapU2D[2*0xFFFD] * 0x100 - + dmap_rec[idx].dmapU2D[2*0xFFFD+1]; - myconv_rec[idx].srcSubS = 0x1A; - myconv_rec[idx].srcSubD = 0xFFFD; - } - - - } else if (((myconvIsEUC(from) && myconvIsUnicode2(to)) && (dmap_rec[idx].codingSchema = DMAP_E2U)) || - ((myconvIsEUC(from) && myconvIsUTF8(to)) && (dmap_rec[idx].codingSchema = DMAP_E28))) { - int i; - /* S0: 0x00 - 0x7F */ - if ((dmap_rec[idx].dmapE02U = (UniChar *) alloc_root(&dmapMemRoot, 0x100 * 2)) == NULL) { -#ifdef DEBUG - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n", - to, from, idx, DMAP_E2U, errno, __FILE__,__LINE__); -#endif - return -1; - } - memset(dmap_rec[idx].dmapE02U, 0x00, 0x100 * 2); - - /* S1: 0xA0 - 0xFF, 0xA0 - 0xFF */ - if ((dmap_rec[idx].dmapE12U = (UniChar *) alloc_root(&dmapMemRoot, 0x60 * 0x60 * 2)) == NULL) { -#ifdef DEBUG - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n", - to, from, idx, DMAP_E2U, errno, __FILE__,__LINE__); -#endif - return -1; - } - memset(dmap_rec[idx].dmapE12U, 0x00, 0x60 * 0x60 * 2); - - /* SS2: 0x8E + 0xA0 - 0xFF, 0xA0 - 0xFF */ - if ((dmap_rec[idx].dmapE22U = (UniChar *) alloc_root(&dmapMemRoot, 0x60 * 0x61 * 2)) == NULL) { -#ifdef DEBUG - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n", - to, from, idx, DMAP_E2U, errno, __FILE__,__LINE__); -#endif - return -1; - } - memset(dmap_rec[idx].dmapE22U, 0x00, 0x60 * 0x61 * 2); - - /* SS3: 0x8F + 0xA0 - 0xFF, 0xA0 - 0xFF */ - if ((dmap_rec[idx].dmapE32U = (UniChar *) alloc_root(&dmapMemRoot, 0x60 * 0x61 * 2)) == NULL) { -#ifdef DEBUG - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n", - to, from, idx, DMAP_E2U, errno, __FILE__,__LINE__); -#endif - return -1; - } - memset(dmap_rec[idx].dmapE32U, 0x00, 0x60 * 0x61 * 2); - - myconv_rec[idx].allocatedSize=(0x100 + 0x60 * 0x60 + 0x60 * 0x61* 2) * 2; - - - { - char dmapSrc[0x60 * 0x60 * 3]; - iconv_t cd; - int32_t i; - size_t inBytesLeft; - size_t outBytesLeft; - size_t len; - char * inBuf; - char * outBuf; - char SS=0x8E; - -#ifdef support_surrogate - if ((cd = iconv_open("UTF-16", from)) == (iconv_t) -1) { -#else - if ((cd = iconv_open("UCS-2", from)) == (iconv_t) -1) { -#endif -#ifdef DEBUG - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d) failed with iconv_open(), errno = %d in %s at %d\n", - to, from, idx, errno, __FILE__,__LINE__); -#endif - return -1; - } - - for (i = 0; i < 0x100; ++i) { - dmapSrc[0]=i; - inBuf=dmapSrc; - inBytesLeft=1; - outBuf=(char *) (&dmap_rec[idx].dmapE02U[i]); - outBytesLeft=2; - if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) { -#ifdef DEBUG - if (myconvDebug) { - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d) failed to initialize with iconv(), errno = %d in %s at %d\n", - to, from, idx, errno, __FILE__,__LINE__); - } -#endif - dmap_rec[idx].dmapE02U[i]=0x0000; - } - if (dmap_rec[idx].dmapE02U[i] == 0x001A && /* pick the first one */ - myconv_rec[idx].srcSubS == 0x00) { - myconv_rec[idx].srcSubS=i; - } - } - - - inBuf=dmapSrc; - for (i = 0; i < 0x60; ++i) { - int j; - for (j = 0; j < 0x60; ++j) { - *inBuf=i+0xA0; - ++inBuf; - *inBuf=j+0xA0; - ++inBuf; - } - } - inBuf=dmapSrc; - inBytesLeft=0x60 * 0x60 * 2; - outBuf=(char *) dmap_rec[idx].dmapE12U; - outBytesLeft=0x60 * 0x60 * 2; - do { - if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) { - if (errno == EILSEQ) { -#ifdef DEBUG - if (myconvDebug) { - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d) failed to initialize with iconv(), errno = %d in %s at %d\n", - to, from, idx, errno, __FILE__,__LINE__); - MyPrintf(STDERR_WO_TIME, "inBytesLeft=%d, outBytesLeft=%d\n", inBytesLeft, outBytesLeft); - if (inBuf - dmapSrc > 1 && inBuf - dmapSrc <= sizeof(dmapSrc) - 2) - MyPrintf(STDERR_WO_TIME, "inBuf[-2..2]=%02X%02X%02X%02X%02X\n", inBuf[-2],inBuf[-1],inBuf[0],inBuf[1],inBuf[2]); - else - MyPrintf(STDERR_WO_TIME, "inBuf[0..2]=%02X%02X%02X\n", inBuf[0],inBuf[1],inBuf[2]); - if (outBuf - (char *) dmap_rec[idx].dmapE12U > 1) - MyPrintf(STDERR_WO_TIME, "outBuf[-2..2]=%02X%02X%02X%02X%02X\n", outBuf[-2],outBuf[-1],outBuf[0],outBuf[1],outBuf[2]); - else - MyPrintf(STDERR_WO_TIME, "outBuf[0..2]=%02X%02X%02X\n", outBuf[0],outBuf[1],outBuf[2]); - } -#endif - inBuf+=2; - inBytesLeft-=2; - outBuf[0]=0x00; - outBuf[1]=0x00; - outBuf+=2; - outBytesLeft-=2; - } else { -#ifdef DEBUG - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d) failed to initialize with iconv(), errno = %d in %s at %d\n", - to, from, idx, errno, __FILE__,__LINE__); -#endif - iconv_close(cd); - return -1; - } - } - } while (inBytesLeft > 0); - - /* SS2: 0x8E + 1 or 2 bytes */ - /* SS3: 0x8E + 1 or 2 bytes */ - while (SS != 0x00) { - int32_t numSuccess=0; - for (i = 0; i < 0x60; ++i) { - inBuf=dmapSrc; - inBuf[0]=SS; - inBuf[1]=i+0xA0; - inBytesLeft=2; - if (SS == 0x8E) - outBuf=(char *) &(dmap_rec[idx].dmapE22U[i]); - else - outBuf=(char *) &(dmap_rec[idx].dmapE32U[i]); - outBytesLeft=2; - if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) { - if (SS == 0x8E) - dmap_rec[idx].dmapE22U[i]=0x0000; - else - dmap_rec[idx].dmapE32U[i]=0x0000; - } else { - ++numSuccess; - } - } - if (numSuccess == 0) { /* SS2 is 2 bytes */ - inBuf=dmapSrc; - for (i = 0; i < 0x60; ++i) { - int j; - for (j = 0; j < 0x60; ++j) { - *inBuf=SS; - ++inBuf; - *inBuf=i+0xA0; - ++inBuf; - *inBuf=j+0xA0; - ++inBuf; - } - } - inBuf=dmapSrc; - inBytesLeft=0x60 * 0x60 * 3; - if (SS == 0x8E) - outBuf=(char *) &(dmap_rec[idx].dmapE22U[0x60]); - else - outBuf=(char *) &(dmap_rec[idx].dmapE32U[0x60]); - outBytesLeft=0x60 * 0x60 * 2; - do { - if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) { -#ifdef DEBUG - if (myconvDebug) { - MyPrintf(STDERR_WITH_TIME, - "%02X:dmap_open(%s,%s,%d) failed to initialize with iconv(), errno = %d in %s at %d\n", - SS, to, from, idx, errno, __FILE__,__LINE__); - MyPrintf(STDERR_WO_TIME, "inBytesLeft=%d, outBytesLeft=%d\n", inBytesLeft, outBytesLeft); - if (inBuf - dmapSrc > 1 && inBuf - dmapSrc <= sizeof(dmapSrc) - 2) - MyPrintf(STDERR_WO_TIME, "inBuf[-2..2]=%02X%02X%02X%02X%02X\n", inBuf[-2],inBuf[-1],inBuf[0],inBuf[1],inBuf[2]); - else - MyPrintf(STDERR_WO_TIME, "inBuf[0..2]=%02X%02X%02X\n", inBuf[0],inBuf[1],inBuf[2]); - } -#endif - if (errno == EILSEQ || errno == EINVAL) { - inBuf+=3; - inBytesLeft-=3; - outBuf[0]=0x00; - outBuf[1]=0x00; - outBuf+=2; - outBytesLeft-=2; - } else { -#ifdef DEBUG - MyPrintf(STDERR_WITH_TIME, - "%02X:dmap_open(%s,%s,%d) failed to initialize with iconv(), errno = %d in %s at %d\n", - SS, to, from, idx, errno, __FILE__,__LINE__); -#endif - iconv_close(cd); - return -1; - } - } - } while (inBytesLeft > 0); - } - if (SS == 0x8E) - SS=0x8F; - else - SS = 0x00; - } - iconv_close(cd); - - myconv_rec[idx].subS=0x1A; - myconv_rec[idx].subD=0xFFFD; - for (i = 0; i < 0x80; ++i) { - if (dmap_rec[idx].dmapE02U[i] == 0x001A) { - myconv_rec[idx].srcSubS=i; /* pick the first one */ - break; - } - } - - for (i = 0; i < 0x60 * 0x60; ++i) { - if (dmap_rec[idx].dmapE12U[i] == 0xFFFD) { - uchar byte1=i / 0x60; - uchar byte2=i % 0x60; - myconv_rec[idx].srcSubD=(byte1 + 0xA0) * 0x100 + (byte2 + 0xA0); /* pick the last one */ - } - } - - } - - } else if (((myconvIsUCS2(from) && myconvIsEUC(to)) && (dmap_rec[idx].codingSchema = DMAP_U2E)) || - ((myconvIsUTF16(from) && myconvIsEUC(to)) && (dmap_rec[idx].codingSchema = DMAP_T2E)) || - ((myconvIsUTF8(from) && myconvIsEUC(to)) && (dmap_rec[idx].codingSchema = DMAP_82E))) { - /* S0: 0x00 - 0xFF */ - if ((dmap_rec[idx].dmapU2S = (uchar *) alloc_root(&dmapMemRoot, 0x100)) == NULL) { -#ifdef DEBUG - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n", - to, from, idx, DMAP_U2E, errno, __FILE__,__LINE__); -#endif - return -1; - } - memset(dmap_rec[idx].dmapU2S, 0x00, 0x100); - - /* U0080 - UFFFF -> S1: 0xA0 - 0xFF, 0xA0 - 0xFF */ - if ((dmap_rec[idx].dmapU2M2 = (uchar *) alloc_root(&dmapMemRoot, 0xFF80 * 2)) == NULL) { -#ifdef DEBUG - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n", - to, from, idx, DMAP_U2E, errno, __FILE__,__LINE__); -#endif - return -1; - } - memset(dmap_rec[idx].dmapU2M2, 0x00, 0xFF80 * 2); - - /* U0080 - UFFFF -> SS2: 0x8E + 0xA0 - 0xFF, 0xA0 - 0xFF - * SS3: 0x8F + 0xA0 - 0xFF, 0xA0 - 0xFF */ - if ((dmap_rec[idx].dmapU2M3 = (uchar *) alloc_root(&dmapMemRoot, 0xFF80 * 3)) == NULL) { -#ifdef DEBUG - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n", - to, from, idx, DMAP_U2E, errno, __FILE__,__LINE__); -#endif - return -1; - } - memset(dmap_rec[idx].dmapU2M3, 0x00, 0xFF80 * 3); - myconv_rec[idx].allocatedSize=(0x100 + 0xFF80 * 2 + 0xFF80 * 3); - - { - UniChar dmapSrc[0x80]; - iconv_t cd; - int32_t i; - size_t inBytesLeft; - size_t outBytesLeft; - size_t len; - char * inBuf; - char * outBuf; - -#ifdef support_surrogate - if ((cd = iconv_open(to, "UTF-16")) == (iconv_t) -1) { -#else - if ((cd = iconv_open(to, "UCS-2")) == (iconv_t) -1) { -#endif -#ifdef DEBUG - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d) failed with iconv_open(), errno = %d in %s at %d\n", - to, from, idx, errno, __FILE__,__LINE__); -#endif - return -1; - } - - for (i = 0; i < 0x80; ++i) - dmapSrc[i]=i; - inBuf=(char *) dmapSrc; - inBytesLeft=0x80 * 2; - outBuf=(char *) dmap_rec[idx].dmapU2S; - outBytesLeft=0x80; - do { - if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) { -#ifdef DEBUG - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d) failed to initialize with iconv(), errno = %d in %s at %d\n", - to, from, idx, errno, __FILE__,__LINE__); -#endif - iconv_close(cd); - return -1; - } - } while (inBytesLeft > 0); - - myconv_rec[idx].srcSubS = 0x1A; - myconv_rec[idx].srcSubD = 0xFFFD; - myconv_rec[idx].subS = dmap_rec[idx].dmapU2S[0x1A]; - - outBuf=(char *) &(myconv_rec[idx].subD); - dmapSrc[0]=0xFFFD; - inBuf=(char *) dmapSrc; - inBytesLeft=2; - outBytesLeft=2; - if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) { -#ifdef DEBUG - if (myconvDebug) { - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d) failed to initialize with iconv(), rc=%d, errno=%d in %s at %d\n", - to, from, idx, len, errno, __FILE__,__LINE__); - MyPrintf(STDERR_WO_TIME, "iconv(0x1A,1,%p,1) returns outBuf=%p, outBytesLeft=%d\n", - dmapSrc, outBuf, outBytesLeft); - } -#endif - if (outBytesLeft == 0) { - /* UCS-2_IBM-eucKR returns error. - myconv(iconv) rc=1, error=0, InBytesLeft=0, OutBytesLeft=18 - myconv(iconvRev) rc=-1, error=116, InBytesLeft=2, OutBytesLeft=20 - iconv: 0xFFFD => 0xAFFE => 0x rc=1,-1 sub=0,0 - */ - ; - } else { - iconv_close(cd); - return -1; - } - } - - for (i = 0x80; i < 0xFFFF; ++i) { - uchar eucBuf[3]; - dmapSrc[0]=i; - inBuf=(char *) dmapSrc; - inBytesLeft=2; - outBuf=(char *) eucBuf; - outBytesLeft=sizeof(eucBuf); - errno=0; - if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) { - if (len == 1 && errno == 0 && inBytesLeft == 0 && outBytesLeft == 1) { /* substitution occurred. */ continue; - } - - if (errno == EILSEQ) { -#ifdef DEBUG - if (myconvDebug) { - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d) failed to initialize with iconv(), errno = %d in %s at %d\n", - to, from, idx, errno, __FILE__,__LINE__); - MyPrintf(STDERR_WO_TIME, "inBytesLeft=%d, outBytesLeft=%d\n", inBytesLeft, outBytesLeft); - if (inBuf - (char *) dmapSrc > 1 && inBuf - (char *) dmapSrc <= sizeof(dmapSrc) - 2) - MyPrintf(STDERR_WO_TIME, "inBuf[-2..2]=%02X%02X%02X%02X%02X\n", inBuf[-2],inBuf[-1],inBuf[0],inBuf[1],inBuf[2]); - else - MyPrintf(STDERR_WO_TIME, "inBuf[0..2]=%02X%02X%02X\n", inBuf[0],inBuf[1],inBuf[2]); - if (outBuf - (char *) dmap_rec[idx].dmapU2M2 > 1) - MyPrintf(STDERR_WO_TIME, "outBuf[-2..2]=%02X%02X%02X%02X%02X\n", outBuf[-2],outBuf[-1],outBuf[0],outBuf[1],outBuf[2]); - else - MyPrintf(STDERR_WO_TIME, "outBuf[0..2]=%02X%02X%02X\n", outBuf[0],outBuf[1],outBuf[2]); - } -#endif - inBuf+=2; - inBytesLeft-=2; - memcpy(outBuf, (char *) &(myconv_rec[idx].subD), 2); - outBuf+=2; - outBytesLeft-=2; - } else { -#ifdef DEBUG - if (myconvDebug) { - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d) failed to initialize with iconv(), rc = %d, errno = %d in %s at %d\n", - to, from, idx, len, errno, __FILE__,__LINE__); - MyPrintf(STDERR_WITH_TIME, - "%04X: src=%04X%04X, inBuf=0x%02X%02X, inBytesLeft=%d, outBuf[-2..0]=%02X%02X%02X, outBytesLeft=%d\n", - i, dmapSrc[0], dmapSrc[1], inBuf[0], inBuf[1], - inBytesLeft, outBuf[-2], outBuf[-1], outBuf[0], outBytesLeft); - MyPrintf(STDERR_WITH_TIME, - "&dmapSrc=%p, inBuf=%p, dmapU2M2 + %d = %p, outBuf=%p\n", - dmapSrc, inBuf, (i - 0x80) * 2, dmap_rec[idx].dmapU2M2 + (i - 0x80) * 2, outBuf); - } -#endif - iconv_close(cd); - return -1; - } - } - if (sizeof(eucBuf) - outBytesLeft == 1) { - if (i < 0x100) { - (dmap_rec[idx].dmapU2S)[i]=eucBuf[0]; - } else { - dmap_rec[idx].dmapU2M2[(i - 0x80) * 2] = eucBuf[0]; - dmap_rec[idx].dmapU2M2[(i - 0x80) * 2 + 1] = 0x00; - } - } else if (sizeof(eucBuf) - outBytesLeft == 2) { /* 2 bytes */ - dmap_rec[idx].dmapU2M2[(i - 0x80) * 2] = eucBuf[0]; - dmap_rec[idx].dmapU2M2[(i - 0x80) * 2 + 1] = eucBuf[1]; - } else if (sizeof(eucBuf) - outBytesLeft == 3) { /* 3 byte SS2/SS3 */ - dmap_rec[idx].dmapU2M3[(i - 0x80) * 3] = eucBuf[0]; - dmap_rec[idx].dmapU2M3[(i - 0x80) * 3 + 1] = eucBuf[1]; - dmap_rec[idx].dmapU2M3[(i - 0x80) * 3 + 2] = eucBuf[2]; - } else { -#ifdef DEBUG - if (myconvDebug) { - MyPrintf(STDERR_WITH_TIME, - "dmap_open(%s,%s,%d) failed to initialize with iconv(), rc=%d, errno=%d in %s at %d\n", - to, from, idx, len, errno, __FILE__,__LINE__); - MyPrintf(STDERR_WITH_TIME, - "%04X: src=%04X%04X, inBuf=0x%02X%02X, inBytesLeft=%d, outBuf=%02X%02X%02X, outBytesLeft=%d\n", - i, dmapSrc[0], dmapSrc[1], inBuf[0], inBuf[1], - inBytesLeft, outBuf[-2], outBuf[-1], outBuf[0], outBytesLeft); - MyPrintf(STDERR_WITH_TIME, - "&dmapSrc=%p, inBuf=%p, %p, outBuf=%p\n", - dmapSrc, inBuf, dmap_rec[idx].dmapU2M3 + (i - 0x80) * 2, outBuf); - } -#endif - return -1; - } - - } - iconv_close(cd); - } - - } else if (myconvIsUTF16(from) && myconvIsUTF8(to)) { - dmap_rec[idx].codingSchema = DMAP_T28; - - } else if (myconvIsUCS2(from) && myconvIsUTF8(to)) { - dmap_rec[idx].codingSchema = DMAP_U28; - - } else if (myconvIsUTF8(from) && myconvIsUnicode2(to)) { - dmap_rec[idx].codingSchema = DMAP_82U; - - } else if (myconvIsUnicode2(from) && myconvIsUnicode2(to)) { - dmap_rec[idx].codingSchema = DMAP_U2U; - - } else { - - return -1; - } - myconv_rec[idx].cnv_dmap=&(dmap_rec[idx]); - return 0; -} - - - -static int bins_open(const char * to, - const char * from, - const int32_t idx) -{ - return -1; -} - - - -static int32_t dmap_close(const int32_t idx) -{ - if (dmap_rec[idx].codingSchema == DMAP_S2S) { - if (dmap_rec[idx].dmapS2S != NULL) { - dmap_rec[idx].dmapS2S=NULL; - } - } else if (dmap_rec[idx].codingSchema = DMAP_E2U) { - if (dmap_rec[idx].dmapE02U != NULL) { - dmap_rec[idx].dmapE02U=NULL; - } - if (dmap_rec[idx].dmapE12U != NULL) { - dmap_rec[idx].dmapE12U=NULL; - } - if (dmap_rec[idx].dmapE22U != NULL) { - dmap_rec[idx].dmapE22U=NULL; - } - if (dmap_rec[idx].dmapE32U != NULL) { - dmap_rec[idx].dmapE32U=NULL; - } - } - - return 0; -} - - -static int32_t bins_close(const int32_t idx) -{ - return 0; -} - - -myconv_t myconv_open(const char * toCode, - const char * fromCode, - int32_t converter) -{ - int32 i; - for (i = 0; i < MAX_CONVERTER; ++i) { - if (myconv_rec[i].converterType == 0) - break; - } - if (i >= MAX_CONVERTER) - return ((myconv_t) -1); - - myconv_rec[i].converterType = converter; - myconv_rec[i].index=i; - myconv_rec[i].fromCcsid=cstoccsid(fromCode); - if (myconv_rec[i].fromCcsid == 0 && memcmp(fromCode, "big5",5) == 0) - myconv_rec[i].fromCcsid=950; - myconv_rec[i].toCcsid=cstoccsid(toCode); - if (myconv_rec[i].toCcsid == 0 && memcmp(toCode, "big5",5) == 0) - myconv_rec[i].toCcsid=950; - strncpy(myconv_rec[i].from, fromCode, sizeof(myconv_rec[i].from)-1); - strncpy(myconv_rec[i].to, toCode, sizeof(myconv_rec[i].to)-1); - - if (converter == CONVERTER_ICONV) { - if ((myconv_rec[i].cnv_iconv=iconv_open(toCode, fromCode)) == (iconv_t) -1) { - return ((myconv_t) -1); - } - myconv_rec[i].allocatedSize = -1; - myconv_rec[i].srcSubS=myconvGetSubS(fromCode); - myconv_rec[i].srcSubD=myconvGetSubD(fromCode); - myconv_rec[i].subS=myconvGetSubS(toCode); - myconv_rec[i].subD=myconvGetSubD(toCode); - return &(myconv_rec[i]); - } else if (converter == CONVERTER_DMAP && - dmap_open(toCode, fromCode, i) != -1) { - return &(myconv_rec[i]); - } - return ((myconv_t) -1); -} - - - -int32_t myconv_close(myconv_t cd) -{ - int32_t ret=0; - - if (cd->converterType == CONVERTER_ICONV) { - ret=iconv_close(cd->cnv_iconv); - } else if (cd->converterType == CONVERTER_DMAP) { - ret=dmap_close(cd->index); - } - memset(&(myconv_rec[cd->index]), 0x00, sizeof(myconv_rec[cd->index])); - return ret; -} - - - - -/* reference: http://www-306.ibm.com/software/globalization/other/es.jsp */ -/* systemCL would be expensive, and myconvIsXXXXX is called frequently. - need to cache entries */ -#define MAX_CCSID 256 -static int ccsidList [MAX_CCSID]; -static int esList [MAX_CCSID]; -int32 getEncodingScheme(const uint16 inCcsid, int32& outEncodingScheme); -EXTERN int myconvGetES(CCSID ccsid) -{ - /* call QtqValidateCCSID in ILE to get encoding schema */ - /* return QtqValidateCCSID(ccsid); */ - int i; - for (i = 0; i < MAX_CCSID; ++i) { - if (ccsidList[i] == ccsid) - return esList[i]; - if (ccsidList[i] == 0x00) - break; - } - - if (i >= MAX_CCSID) { - i=MAX_CCSID-1; - } - - { - ccsidList[i]=ccsid; - getEncodingScheme(ccsid, esList[i]); -#ifdef DEBUG_PASE - if (myconvDebug) { - fprintf(stderr, "CCSID=%d, ES=0x%04X\n", ccsid, esList[i]); - } -#endif - return esList[i]; - } - return 0; -} - - -EXTERN int myconvIsEBCDIC(const char * pName) -{ - int es = myconvGetES(cstoccsid(pName)); - if (es == 0x1100 || - es == 0x1200 || - es == 0x6100 || - es == 0x6200 || - es == 0x1301 ) { - return TRUE; - } - return FALSE; -} - - -EXTERN int myconvIsISO(const char * pName) -{ - int es = myconvGetES(cstoccsid(pName)); - if (es == 0x4100 || - es == 0x4105 || - es == 0x4155 || - es == 0x5100 || - es == 0x5150 || - es == 0x5200 || - es == 0x5404 || - es == 0x5409 || - es == 0x540A || - es == 0x5700) { - return TRUE; - } - return FALSE; -} - - -EXTERN int myconvIsASCII(const char * pName) -{ - int es = myconvGetES(cstoccsid(pName)); - if (es == 0x2100 || - es == 0x3100 || - es == 0x8100 || - es == 0x2200 || - es == 0x3200 || - es == 0x9200 || - es == 0x2300 || - es == 0x2305 || - es == 0x3300 || - es == 0x2900 || - es == 0x2A00) { - return TRUE; - } else if (memcmp(pName, "big5", 5) == 0) { - return TRUE; - } - return FALSE; -} - - - -EXTERN int myconvIsUCS2(const char * pName) -{ - if (cstoccsid(pName) == 13488) { - return TRUE; - } - return FALSE; -} - - -EXTERN int myconvIsUTF16(const char * pName) -{ - if (cstoccsid(pName) == 1200) { - return TRUE; - } - return FALSE; -} - - -EXTERN int myconvIsUnicode2(const char * pName) -{ - int es = myconvGetES(cstoccsid(pName)); - if (es == 0x7200 || - es == 0x720B || - es == 0x720F) { - return TRUE; - } - return FALSE; -} - - -EXTERN int myconvIsUTF8(const char * pName) -{ - int es = myconvGetES(cstoccsid(pName)); - if (es == 0x7807) { - return TRUE; - } - return FALSE; -} - - -EXTERN int myconvIsUnicode(const char * pName) -{ - int es = myconvGetES(cstoccsid(pName)); - if (es == 0x7200 || - es == 0x720B || - es == 0x720F || - es == 0x7807) { - return TRUE; - } - return FALSE; -} - - -EXTERN int myconvIsEUC(const char * pName) -{ - int es = myconvGetES(cstoccsid(pName)); - if (es == 0x4403) { - return TRUE; - } - return FALSE; -} - - -EXTERN int myconvIsDBCS(const char * pName) -{ - int es = myconvGetES(cstoccsid(pName)); - if (es == 0x1200 || - es == 0x2200 || - es == 0x2300 || - es == 0x2305 || - es == 0x2A00 || - es == 0x3200 || - es == 0x3300 || - es == 0x5200 || - es == 0x6200 || - es == 0x9200) { - return TRUE; - } else if (memcmp(pName, "big5", 5) == 0) { - return TRUE; - } - return FALSE; -} - - -EXTERN int myconvIsSBCS(const char * pName) -{ - int es = myconvGetES(cstoccsid(pName)); - if (es == 0x1100 || - es == 0x2100 || - es == 0x3100 || - es == 0x4100 || - es == 0x4105 || - es == 0x5100 || - es == 0x5150 || - es == 0x6100 || - es == 0x8100) { - return TRUE; - } - return FALSE; -} - - - -EXTERN char myconvGetSubS(const char * code) -{ - if (myconvIsEBCDIC(code)) { - return 0x3F; - } else if (myconvIsASCII(code)) { - return 0x1A; - } else if (myconvIsISO(code)) { - return 0x1A; - } else if (myconvIsEUC(code)) { - return 0x1A; - } else if (myconvIsUCS2(code)) { - return 0x00; - } else if (myconvIsUTF8(code)) { - return 0x1A; - } - return 0x00; -} - - -EXTERN UniChar myconvGetSubD(const char * code) -{ - if (myconvIsEBCDIC(code)) { - return 0xFDFD; - } else if (myconvIsASCII(code)) { - return 0xFCFC; - } else if (myconvIsISO(code)) { - return 0x00; - } else if (myconvIsEUC(code)) { - return 0x00; - } else if (myconvIsUCS2(code)) { - return 0xFFFD; - } else if (myconvIsUTF8(code)) { - return 0x00; - } - return 0x00; -} - diff --git a/storage/ibmdb2i/db2i_myconv.h b/storage/ibmdb2i/db2i_myconv.h deleted file mode 100644 index 98032748148..00000000000 --- a/storage/ibmdb2i/db2i_myconv.h +++ /dev/null @@ -1,3201 +0,0 @@ -/* -Licensed Materials - Property of IBM -DB2 Storage Engine Enablement -Copyright IBM Corporation 2007,2008 -All rights reserved - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - (a) Redistributions of source code must retain this list of conditions, the - copyright notice in section {d} below, and the disclaimer following this - list of conditions. - (b) Redistributions in binary form must reproduce this list of conditions, the - copyright notice in section (d) below, and the disclaimer following this - list of conditions, in the documentation and/or other materials provided - with the distribution. - (c) The name of IBM may not be used to endorse or promote products derived from - this software without specific prior written permission. - (d) The text of the required copyright notice is: - Licensed Materials - Property of IBM - DB2 Storage Engine Enablement - Copyright IBM Corporation 2007,2008 - All rights reserved - -THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - -/** - @file - - @brief A direct map optimization of iconv and related functions - This was show to significantly reduce character conversion cost - for short strings when compared to calling iconv system code. -*/ - -#ifndef DB2I_MYCONV_H -#define DB2I_MYCONV_H - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifdef __cplusplus -#define INTERN inline -#define EXTERN extern "C" -#else -#define INTERN static -#define EXTERN extern -#endif - - -/* ANSI integer data types */ -#if defined(__OS400_TGTVRM__) -/* for DTAMDL(*P128), datamodel(P128): int/long/pointer=4/4/16 */ -/* LLP64:4/4/8 is used for teraspace ?? */ -typedef short int16_t; -typedef unsigned short uint16_t; -typedef int int32_t; -typedef unsigned int uint32_t; -typedef long long int64_t; -typedef unsigned long long uint64_t; -#elif defined(PASE) -/* PASE uses IPL32: int/long/pointer=4/4/4 + long long */ -#elif defined(__64BIT__) -/* AIX 64 bit uses LP64: int/long/pointer=4/8/8 */ -#endif - -#define CONVERTER_ICONV 1 -#define CONVERTER_DMAP 2 - -#define DMAP_S2S 10 -#define DMAP_S2U 20 -#define DMAP_D2U 30 -#define DMAP_E2U 40 -#define DMAP_U2S 120 -#define DMAP_T2S 125 -#define DMAP_U2D 130 -#define DMAP_T2D 135 -#define DMAP_U2E 140 -#define DMAP_T2E 145 -#define DMAP_S28 220 -#define DMAP_D28 230 -#define DMAP_E28 240 -#define DMAP_82S 310 -#define DMAP_82D 320 -#define DMAP_82E 330 -#define DMAP_U28 410 -#define DMAP_82U 420 -#define DMAP_T28 425 -#define DMAP_U2U 510 - - -typedef struct __dmap_rec *dmap_t; - -struct __dmap_rec -{ - uint32_t codingSchema; - unsigned char * dmapS2S; /* SBCS -> SBCS */ - /* The following conversion needs be followed by conversion from UCS-2/UTF-16 to UTF-8 */ - UniChar * dmapD12U; /* DBCS(non-EUC) -> UCS-2/UTF-16 */ - UniChar * dmapD22U; /* DBCS(non-EUC) -> UCS-2/UTF-16 */ - UniChar * dmapE02U; /* EUC/SS0 -> UCS-2/UTF-16 */ - UniChar * dmapE12U; /* EUC/SS1 -> UCS-2/UTF-16 */ - UniChar * dmapE22U; /* EUC/0x8E + SS2 -> UCS-2/UTF-16 */ - UniChar * dmapE32U; /* EUC/0x8F + SS3 -> UCS-2/UTF-16 */ - uchar * dmapU2D; /* UCS-2 -> DBCS */ - uchar * dmapU2S; /* UCS-2 -> EUC SS0 */ - uchar * dmapU2M2; /* UCS-2 -> EUC SS1 */ - uchar * dmapU2M3; /* UCS-2 -> EUC SS2/SS3 */ - /* All of these pointers/tables are not used at the same time. - * You may be able save some space if you consolidate them. - */ - uchar * dmapS28; /* SBCS -> UTF-8 */ - uchar * dmapD28; /* DBCS -> UTF-8 */ -}; - -typedef struct __myconv_rec *myconv_t; -struct __myconv_rec -{ - uint32_t converterType; - uint32_t index; /* for close */ - union { - iconv_t cnv_iconv; - dmap_t cnv_dmap; - }; - int32_t allocatedSize; - int32_t fromCcsid; - int32_t toCcsid; - UniChar subD; /* DBCS substitution char */ - char subS; /* SBCS substitution char */ - UniChar srcSubD; /* DBCS substitution char of src codepage */ - char srcSubS; /* SBCS substitution char of src codepage */ - char from [41+1]; /* codepage name is up to 41 bytes */ - char to [41+1]; /* codepage name is up to 41 bytes */ -#ifdef __64BIT__ - char reserved[10]; /* align 128 */ -#else - char reserved[14]; /* align 128 */ -#endif -}; - - -EXTERN int32_t myconvDebug; - - - -EXTERN int myconvGetES(CCSID); -EXTERN int myconvIsEBCDIC(const char *); -EXTERN int myconvIsASCII(const char *); -EXTERN int myconvIsUnicode(const char *); /* UTF-8, UTF-16, or UCS-2 */ -EXTERN int myconvIsUnicode2(const char *); /* 2 byte Unicode */ -EXTERN int myconvIsUCS2(const char *); -EXTERN int myconvIsUTF16(const char *); -EXTERN int myconvIsUTF8(const char *); -EXTERN int myconvIsEUC(const char *); -EXTERN int myconvIsISO(const char *); -EXTERN int myconvIsSBCS(const char *); -EXTERN int myconvIsDBCS(const char *); -EXTERN char myconvGetSubS(const char *); -EXTERN UniChar myconvGetSubD(const char *); - - -EXTERN myconv_t myconv_open(const char*, const char*, int32_t); -EXTERN int myconv_close(myconv_t); - -INTERN size_t myconv_iconv(myconv_t cd , - char** inBuf, - size_t* inBytesLeft, - char** outBuf, - size_t* outBytesLeft, - size_t* numSub) -{ - return iconv(cd->cnv_iconv, inBuf, inBytesLeft, outBuf, outBytesLeft); -} - -INTERN size_t myconv_dmap(myconv_t cd, - char** inBuf, - size_t* inBytesLeft, - char** outBuf, - size_t* outBytesLeft, - size_t* numSub) -{ - if (cd->cnv_dmap->codingSchema == DMAP_S2S) { - register unsigned char * dmapS2S=cd->cnv_dmap->dmapS2S; - register int inLen=*inBytesLeft; - register char * pOut=*outBuf; - register char * pIn=*inBuf; - register char * pLastOutBuf = *outBuf + *outBytesLeft - 1; - register char subS=cd->subS; - register size_t numS=0; - while (0 < inLen) { - if (pLastOutBuf < pOut) - break; - if (*pIn == 0x00) { - *pOut=0x00; - } else { - *pOut=dmapS2S[*pIn]; - if (*pOut == 0x00) { - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(*inBytesLeft-inLen); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return -1; - } - if (*pOut == subS) { - if ((*pOut=dmapS2S[*pIn]) == subS) { - if (*pIn != cd->srcSubS) - ++numS; - } - } - } - ++pIn; - --inLen; - ++pOut; - } - *outBytesLeft-=(*inBytesLeft-inLen); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return 0; - - } else if (cd->cnv_dmap->codingSchema == DMAP_E2U) { - /* use uchar * instead of UniChar to avoid memcpy */ - register uchar * dmapE02U=(uchar *) (cd->cnv_dmap->dmapE02U); - register uchar * dmapE12U=(uchar *) (cd->cnv_dmap->dmapE12U); - register uchar * dmapE22U=(uchar *) (cd->cnv_dmap->dmapE22U); - register uchar * dmapE32U=(uchar *) (cd->cnv_dmap->dmapE32U); - register int inLen=*inBytesLeft; - register char * pOut=*outBuf; - register char * pIn=*inBuf; - register int offset; - register char * pLastOutBuf = *outBuf + *outBytesLeft - 1; - register size_t numS=0; - while (0 < inLen) { - if (pLastOutBuf < pOut) - break; - if (*pIn == 0x00) { - *pOut=0x00; - ++pOut; - *pOut=0x00; - ++pOut; - ++pIn; - --inLen; - } else { - if (*pIn == 0x8E) { /* SS2 */ - if (inLen < 2) { - if (cd->fromCcsid == 33722 || /* IBM-eucJP */ - cd->fromCcsid == 964) /* IBM-eucTW */ - errno=EINVAL; /* 22 */ - else - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - return -1; - } - ++pIn; - if (*pIn < 0xA0) { - if (cd->fromCcsid == 964) /* IBM-eucTW */ - errno=EINVAL; /* 22 */ - else - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-1; - return -1; - } - offset=(*pIn - 0xA0); - offset<<=1; - if (dmapE22U[offset] == 0x00 && - dmapE22U[offset+1] == 0x00) { /* 2 bytes */ - if (inLen < 3) { - if (cd->fromCcsid == 964) /* IBM-eucTW */ - errno=EINVAL; /* 22 */ - else - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-1; - return -1; - } - offset=(*pIn - 0xA0) * 0x60 + 0x60; - ++pIn; - if (*pIn < 0xA0) { - if (cd->fromCcsid == 964) /* IBM-eucTW */ - errno=EINVAL; /* 22 */ - else - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-2; - return -1; - } - offset+=(*pIn - 0xA0); - offset<<=1; - if (dmapE22U[offset] == 0x00 && - dmapE22U[offset+1] == 0x00) { - if (cd->fromCcsid == 964) /* IBM-eucTW */ - errno=EINVAL; /* 22 */ - else - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-2; - return -1; - } - *pOut=dmapE22U[offset]; - ++pOut; - *pOut=dmapE22U[offset+1]; - ++pOut; - if (dmapE22U[offset] == 0xFF && - dmapE22U[offset+1] == 0xFD) { - if (pIn[-2] * 0x100 + pIn[-1] != cd->srcSubD) - ++numS; - } - ++pIn; - inLen-=3; - } else { /* 1 bytes */ - *pOut=dmapE22U[offset]; - ++pOut; - *pOut=dmapE22U[offset+1]; - ++pOut; - ++pIn; - inLen-=2; - } - } else if (*pIn == 0x8F) { /* SS3 */ - if (inLen < 2) { - if (cd->fromCcsid == 33722) /* IBM-eucJP */ - errno=EINVAL; /* 22 */ - else - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - return -1; - } - ++pIn; - if (*pIn < 0xA0) { - if (cd->fromCcsid == 970 || /* IBM-eucKR */ - cd->fromCcsid == 964 || /* IBM-eucTW */ - cd->fromCcsid == 1383 || /* IBM-eucCN */ - (cd->fromCcsid == 33722 && 3 <= inLen)) /* IBM-eucJP */ - errno=EILSEQ; /* 116 */ - else - errno=EINVAL; /* 22 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-1; - return -1; - } - offset=(*pIn - 0xA0); - offset<<=1; - if (dmapE32U[offset] == 0x00 && - dmapE32U[offset+1] == 0x00) { /* 0x8F + 2 bytes */ - if (inLen < 3) { - if (cd->fromCcsid == 33722) - errno=EINVAL; /* 22 */ - else - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-1; - return -1; - } - offset=(*pIn - 0xA0) * 0x60 + 0x60; - ++pIn; - if (*pIn < 0xA0) { - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-2; - return -1; - } - offset+=(*pIn - 0xA0); - offset<<=1; - if (dmapE32U[offset] == 0x00 && - dmapE32U[offset+1] == 0x00) { - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-2; - return -1; - } - *pOut=dmapE32U[offset]; - ++pOut; - *pOut=dmapE32U[offset+1]; - ++pOut; - if (dmapE32U[offset] == 0xFF && - dmapE32U[offset+1] == 0xFD) { - if (pIn[-2] * 0x100 + pIn[-1] != cd->srcSubD) - ++numS; - } - ++pIn; - inLen-=3; - } else { /* 0x8F + 1 bytes */ - *pOut=dmapE32U[offset]; - ++pOut; - *pOut=dmapE32U[offset+1]; - ++pOut; - ++pIn; - inLen-=2; - } - - } else { - offset=*pIn; - offset<<=1; - if (dmapE02U[offset] == 0x00 && - dmapE02U[offset+1] == 0x00) { /* SS1 */ - if (inLen < 2) { - if ((cd->fromCcsid == 33722 && (*pIn == 0xA0 || (0xA9 <= *pIn && *pIn <= 0xAF) || *pIn == 0xFF)) || - (cd->fromCcsid == 970 && (*pIn == 0xA0 || *pIn == 0xAD || *pIn == 0xAE || *pIn == 0xAF || *pIn == 0xFF)) || - (cd->fromCcsid == 964 && (*pIn == 0xA0 || (0xAA <= *pIn && *pIn <= 0xC1) || *pIn == 0xC3 || *pIn == 0xFE || *pIn == 0xFF)) || - (cd->fromCcsid == 1383 && (*pIn == 0xA0 || *pIn == 0xFF))) - errno=EILSEQ; /* 116 */ - else - errno=EINVAL; /* 22 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - return -1; - } - if (*pIn < 0xA0) { - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - return -1; - } - offset=(*pIn - 0xA0) * 0x60; - ++pIn; - if (*pIn < 0xA0) { - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-1; - return -1; - } - offset+=(*pIn - 0xA0); - offset<<=1; - if (dmapE12U[offset] == 0x00 && - dmapE12U[offset+1] == 0x00) { /* undefined mapping */ - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-1; - return -1; - } - *pOut=dmapE12U[offset]; - ++pOut; - *pOut=dmapE12U[offset+1]; - ++pOut; - if (dmapE12U[offset] == 0xFF && - dmapE12U[offset+1] == 0xFD) { - if (pIn[-1] * 0x100 + pIn[0] != cd->srcSubD) - ++numS; - } - ++pIn; - inLen-=2; - } else { - *pOut=dmapE02U[offset]; - ++pOut; - *pOut=dmapE02U[offset+1]; - ++pOut; - if (dmapE02U[offset] == 0x00 && - dmapE02U[offset+1] == 0x1A) { - if (*pIn != cd->srcSubS) - ++numS; - } - ++pIn; - --inLen; - } - } - } - } - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return 0; - - - } else if (cd->cnv_dmap->codingSchema == DMAP_E28) { - /* use uchar * instead of UniChar to avoid memcpy */ - register uchar * dmapE02U=(uchar *) (cd->cnv_dmap->dmapE02U); - register uchar * dmapE12U=(uchar *) (cd->cnv_dmap->dmapE12U); - register uchar * dmapE22U=(uchar *) (cd->cnv_dmap->dmapE22U); - register uchar * dmapE32U=(uchar *) (cd->cnv_dmap->dmapE32U); - register int inLen=*inBytesLeft; - register char * pOut=*outBuf; - register char * pIn=*inBuf; - register int offset; - register char * pLastOutBuf = *outBuf + *outBytesLeft - 1; - register size_t numS=0; - register UniChar in; /* copy part of U28 */ - register UniChar ucs2; - while (0 < inLen) { - if (pLastOutBuf < pOut) - break; - if (*pIn == 0x00) { - *pOut=0x00; - ++pOut; - ++pIn; - --inLen; - } else { - if (*pIn == 0x8E) { /* SS2 */ - if (inLen < 2) { - if (cd->fromCcsid == 33722 || /* IBM-eucJP */ - cd->fromCcsid == 964) /* IBM-eucTW */ - errno=EINVAL; /* 22 */ - else - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - return -1; - } - ++pIn; - if (*pIn < 0xA0) { - if (cd->fromCcsid == 964) /* IBM-eucTW */ - errno=EINVAL; /* 22 */ - else - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-1; - return -1; - } - offset=(*pIn - 0xA0); - offset<<=1; - if (dmapE22U[offset] == 0x00 && - dmapE22U[offset+1] == 0x00) { /* 2 bytes */ - if (inLen < 3) { - if (cd->fromCcsid == 964) /* IBM-eucTW */ - errno=EINVAL; /* 22 */ - else - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-1; - return -1; - } - offset=(*pIn - 0xA0) * 0x60 + 0x60; - ++pIn; - if (*pIn < 0xA0) { - if (cd->fromCcsid == 964) /* IBM-eucTW */ - errno=EINVAL; /* 22 */ - else - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-2; - return -1; - } - offset+=(*pIn - 0xA0); - offset<<=1; - if (dmapE22U[offset] == 0x00 && - dmapE22U[offset+1] == 0x00) { - if (cd->fromCcsid == 964) /* IBM-eucTW */ - errno=EINVAL; /* 22 */ - else - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-2; - return -1; - } - in=dmapE22U[offset]; - in<<=8; - in+=dmapE22U[offset+1]; - if (dmapE22U[offset] == 0xFF && - dmapE22U[offset+1] == 0xFD) { - if (pIn[-2] * 0x100 + pIn[-1] != cd->srcSubD) - ++numS; - } - ++pIn; - inLen-=3; - } else { /* 1 bytes */ - in=dmapE22U[offset]; - in<<=8; - in+=dmapE22U[offset+1]; - ++pIn; - inLen-=2; - } - } else if (*pIn == 0x8F) { /* SS3 */ - if (inLen < 2) { - if (cd->fromCcsid == 33722) /* IBM-eucJP */ - errno=EINVAL; /* 22 */ - else - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - return -1; - } - ++pIn; - if (*pIn < 0xA0) { - if (cd->fromCcsid == 970 || /* IBM-eucKR */ - cd->fromCcsid == 964 || /* IBM-eucTW */ - cd->fromCcsid == 1383 || /* IBM-eucCN */ - (cd->fromCcsid == 33722 && 3 <= inLen)) /* IBM-eucJP */ - errno=EILSEQ; /* 116 */ - else - errno=EINVAL; /* 22 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-1; - return -1; - } - offset=(*pIn - 0xA0); - offset<<=1; - if (dmapE32U[offset] == 0x00 && - dmapE32U[offset+1] == 0x00) { /* 0x8F + 2 bytes */ - if (inLen < 3) { - if (cd->fromCcsid == 33722) - errno=EINVAL; /* 22 */ - else - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-1; - return -1; - } - offset=(*pIn - 0xA0) * 0x60 + 0x60; - ++pIn; - if (*pIn < 0xA0) { - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-2; - return -1; - } - offset+=(*pIn - 0xA0); - offset<<=1; - if (dmapE32U[offset] == 0x00 && - dmapE32U[offset+1] == 0x00) { - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-2; - return -1; - } - in=dmapE32U[offset]; - in<<=8; - in+=dmapE32U[offset+1]; - if (dmapE32U[offset] == 0xFF && - dmapE32U[offset+1] == 0xFD) { - if (pIn[-2] * 0x100 + pIn[-1] != cd->srcSubD) - ++numS; - } - ++pIn; - inLen-=3; - } else { /* 0x8F + 1 bytes */ - in=dmapE32U[offset]; - in<<=8; - in+=dmapE32U[offset+1]; - ++pIn; - inLen-=2; - } - - } else { - offset=*pIn; - offset<<=1; - if (dmapE02U[offset] == 0x00 && - dmapE02U[offset+1] == 0x00) { /* SS1 */ - if (inLen < 2) { - if ((cd->fromCcsid == 33722 && (*pIn == 0xA0 || (0xA9 <= *pIn && *pIn <= 0xAF) || *pIn == 0xFF)) || - (cd->fromCcsid == 970 && (*pIn == 0xA0 || *pIn == 0xAD || *pIn == 0xAE || *pIn == 0xAF || *pIn == 0xFF)) || - (cd->fromCcsid == 964 && (*pIn == 0xA0 || (0xAA <= *pIn && *pIn <= 0xC1) || *pIn == 0xC3 || *pIn == 0xFE || *pIn == 0xFF)) || - (cd->fromCcsid == 1383 && (*pIn == 0xA0 || *pIn == 0xFF))) - errno=EILSEQ; /* 116 */ - else - errno=EINVAL; /* 22 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - return -1; - } - if (*pIn < 0xA0) { - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - return -1; - } - offset=(*pIn - 0xA0) * 0x60; - ++pIn; - if (*pIn < 0xA0) { - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-1; - return -1; - } - offset+=(*pIn - 0xA0); - offset<<=1; - if (dmapE12U[offset] == 0x00 && - dmapE12U[offset+1] == 0x00) { /* undefined mapping */ - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-1; - return -1; - } - in=dmapE12U[offset]; - in<<=8; - in+=dmapE12U[offset+1]; - if (dmapE12U[offset] == 0xFF && - dmapE12U[offset+1] == 0xFD) { - if (pIn[-1] * 0x100 + pIn[0] != cd->srcSubD) - ++numS; - } - ++pIn; - inLen-=2; - } else { - in=dmapE02U[offset]; - in<<=8; - in+=dmapE02U[offset+1]; - if (dmapE02U[offset] == 0x00 && - dmapE02U[offset+1] == 0x1A) { - if (*pIn != cd->srcSubS) - ++numS; - } - ++pIn; - --inLen; - } - } - ucs2=in; - if ((in & 0xFF80) == 0x0000) { /* U28: in & 0b1111111110000000 == 0x0000 */ - *pOut=in; - ++pOut; - } else if ((in & 0xF800) == 0x0000) { /* in & 0b1111100000000000 == 0x0000 */ - register uchar byte; - in>>=6; - in&=0x001F; /* 0b0000000000011111 */ - in|=0x00C0; /* 0b0000000011000000 */ - *pOut=in; - ++pOut; - byte=ucs2; /* dmapD12U[offset+1]; */ - byte&=0x3F; /* 0b00111111; */ - byte|=0x80; /* 0b10000000; */ - *pOut=byte; - ++pOut; - } else if ((in & 0xFC00) == 0xD800) { - *pOut=0xEF; - ++pOut; - *pOut=0xBF; - ++pOut; - *pOut=0xBD; - ++pOut; - } else { - register uchar byte; - register uchar work; - byte=(ucs2>>8); /* dmapD12U[offset]; */ - byte>>=4; - byte|=0xE0; /* 0b11100000; */ - *pOut=byte; - ++pOut; - - byte=(ucs2>>8); /* dmapD12U[offset]; */ - byte<<=2; - work=ucs2; /* dmapD12U[offset+1]; */ - work>>=6; - byte|=work; - byte&=0x3F; /* 0b00111111; */ - byte|=0x80; /* 0b10000000; */ - *pOut=byte; - ++pOut; - - byte=ucs2; /* dmapD12U[offset+1]; */ - byte&=0x3F; /* 0b00111111; */ - byte|=0x80; /* 0b10000000; */ - *pOut=byte; - ++pOut; - } - /* end of U28 */ - } - } - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return 0; - - } else if (cd->cnv_dmap->codingSchema == DMAP_U2E) { - register uchar * dmapU2S=cd->cnv_dmap->dmapU2S; - register uchar * dmapU2M2=cd->cnv_dmap->dmapU2M2 - 0x80 * 2; - register uchar * dmapU2M3=cd->cnv_dmap->dmapU2M3 - 0x80 * 3; - register int inLen=*inBytesLeft; - register char * pOut=*outBuf; - register char * pIn=*inBuf; - register char * pLastOutBuf = *outBuf + *outBytesLeft - 1; - register char subS=cd->subS; - register char * pSubD=(char *) &(cd->subD); - register size_t numS=0; - register size_t rc=0; - while (0 < inLen) { - register uint32_t in; - if (inLen == 1) { - errno=EINVAL; /* 22 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - return -1; - } - if (pLastOutBuf < pOut) - break; - in=pIn[0]; - in<<=8; - in+=pIn[1]; - if (in == 0x0000) { - *pOut=0x00; - ++pOut; - } else if (in < 0x100 && dmapU2S[in] != 0x0000) { - if ((*pOut=dmapU2S[in]) == subS) { - if (in != cd->srcSubS) - ++numS; - } - ++pOut; - } else { - in<<=1; - if (dmapU2M2[in] == 0x00) { /* not found in dmapU2M2 */ - in*=1.5; - if (dmapU2M3[in] == 0x00) { /* not found in dmapU2M3*/ - *pOut=pSubD[0]; - ++pOut; - *pOut=pSubD[1]; - ++pOut; - ++numS; - ++rc; - } else { - *pOut=dmapU2M3[in]; - ++pOut; - *pOut=dmapU2M3[1+in]; - ++pOut; - *pOut=dmapU2M3[2+in]; - ++pOut; - } - } else { - *pOut=dmapU2M2[in]; - ++pOut; - if (dmapU2M2[1+in] == 0x00) { - if (*pOut == subS) { - in>>=1; - if (in != cd->srcSubS) - ++numS; - } - } else { - *pOut=dmapU2M2[1+in]; - ++pOut; - if (memcmp(pOut-2, pSubD, 2) == 0) { - in>>=1; - if (in != cd->srcSubD) { - ++numS; - ++rc; - } - } - } - } - } - pIn+=2; - inLen-=2; - } - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return rc; /* compatibility to iconv() */ - - } else if (cd->cnv_dmap->codingSchema == DMAP_T2E) { - register uchar * dmapU2S=cd->cnv_dmap->dmapU2S; - register uchar * dmapU2M2=cd->cnv_dmap->dmapU2M2 - 0x80 * 2; - register uchar * dmapU2M3=cd->cnv_dmap->dmapU2M3 - 0x80 * 3; - register int inLen=*inBytesLeft; - register char * pOut=*outBuf; - register char * pIn=*inBuf; - register char * pLastOutBuf = *outBuf + *outBytesLeft - 1; - register char subS=cd->subS; - register char * pSubD=(char *) &(cd->subD); - register size_t numS=0; - register size_t rc=0; - while (0 < inLen) { - register uint32_t in; - if (inLen == 1) { - errno=EINVAL; /* 22 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen-1; - *outBuf=pOut; - *inBuf=pIn; - ++numS; - *numSub+=numS; - return 0; - } - if (pLastOutBuf < pOut) - break; - in=pIn[0]; - in<<=8; - in+=pIn[1]; - if (in == 0x0000) { - *pOut=0x00; - ++pOut; - } else if (0xD800 <= in && in <= 0xDBFF) { /* first byte of surrogate */ - errno=EINVAL; /* 22 */ - *inBytesLeft=inLen-2; - *outBytesLeft-=(pOut-*outBuf); - *outBuf=pOut; - *inBuf=pIn+2; - ++numS; - *numSub+=numS; - return -1; - - } else if (0xDC00 <= in && in <= 0xDFFF) { /* second byte of surrogate */ - errno=EINVAL; /* 22 */ - *inBytesLeft=inLen-1; - *outBytesLeft-=(pOut-*outBuf); - *outBuf=pOut; - *inBuf=pIn; - ++numS; - *numSub+=numS; - return -1; - - } else if (in < 0x100 && dmapU2S[in] != 0x0000) { - if ((*pOut=dmapU2S[in]) == subS) { - if (in != cd->srcSubS) - ++numS; - } - ++pOut; - } else { - in<<=1; - if (dmapU2M2[in] == 0x00) { /* not found in dmapU2M2 */ - in*=1.5; - if (dmapU2M3[in] == 0x00) { /* not found in dmapU2M3*/ - *pOut=pSubD[0]; - ++pOut; - *pOut=pSubD[1]; - ++pOut; - ++numS; - ++rc; - } else { - *pOut=dmapU2M3[in]; - ++pOut; - *pOut=dmapU2M3[1+in]; - ++pOut; - *pOut=dmapU2M3[2+in]; - ++pOut; - } - } else { - *pOut=dmapU2M2[in]; - ++pOut; - if (dmapU2M2[1+in] == 0x00) { - if (*pOut == subS) { - in>>=1; - if (in != cd->srcSubS) - ++numS; - } - } else { - *pOut=dmapU2M2[1+in]; - ++pOut; - if (memcmp(pOut-2, pSubD, 2) == 0) { - in>>=1; - if (in != cd->srcSubD) { - ++numS; - ++rc; - } - } - } - } - } - pIn+=2; - inLen-=2; - } - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return 0; - - } else if (cd->cnv_dmap->codingSchema == DMAP_82E) { - register uchar * dmapU2S=cd->cnv_dmap->dmapU2S; - register uchar * dmapU2M2=cd->cnv_dmap->dmapU2M2 - 0x80 * 2; - register uchar * dmapU2M3=cd->cnv_dmap->dmapU2M3 - 0x80 * 3; - register int inLen=*inBytesLeft; - register char * pOut=*outBuf; - register char * pIn=*inBuf; - register char * pLastOutBuf = *outBuf + *outBytesLeft - 1; - register char subS=cd->subS; - register char * pSubD=(char *) &(cd->subD); - register size_t numS=0; - register size_t rc=0; - while (0 < inLen) { - register uint32_t in; - uint32_t in2; - if (pLastOutBuf < pOut) - break; - /* convert from UTF-8 to UCS-2 */ - if (*pIn == 0x00) { - in=0x0000; - ++pIn; - --inLen; - } else { /* 82U: */ - register uchar byte1=*pIn; - if ((byte1 & 0x80) == 0x00) { /* if (byte1 & 0b10000000 == 0b00000000) { */ - /* 1 bytes sequence: 0xxxxxxx => 00000000 0xxxxxxx*/ - in=byte1; - ++pIn; - --inLen; - } else if ((byte1 & 0xE0) == 0xC0) { /* (byte1 & 0b11100000 == 0b11000000) { */ - if (inLen < 2) { - errno=EINVAL; /* 22 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return -1; - } - if (byte1 == 0xC0 || byte1 == 0xC1) { /* invalid sequence */ - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return -1; - } - /* 2 bytes sequence: - 110yyyyy 10xxxxxx => 00000yyy yyxxxxxx */ - register uchar byte2; - ++pIn; - byte2=*pIn; - if ((byte2 & 0xC0) == 0x80) { /* byte2 & 0b11000000 == 0b10000000) { */ - register uchar work=byte1; - work<<=6; - byte2&=0x3F; /* 0b00111111; */ - byte2|=work; - - byte1&=0x1F; /* 0b00011111; */ - byte1>>=2; - in=byte1; - in<<=8; - in+=byte2; - inLen-=2; - ++pIn; - } else { /* invalid sequence */ - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-1; - *numSub+=numS; - return -1; - } - } else if ((byte1 & 0xF0) == 0xE0) { /* byte1 & 0b11110000 == 0b11100000 */ - /* 3 bytes sequence: - 1110zzzz 10yyyyyy 10xxxxxx => zzzzyyyy yyxxxxxx */ - register uchar byte2; - register uchar byte3; - if (inLen < 3) { - if (inLen == 2 && (pIn[1] & 0xC0) != 0x80) - errno=EILSEQ; /* 116 */ - else - errno=EINVAL; /* 22 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return -1; - } - ++pIn; - byte2=*pIn; - ++pIn; - byte3=*pIn; - if ((byte2 & 0xC0) != 0x80 || - (byte3 & 0xC0) != 0x80 || - (byte1 == 0xE0 && byte2 < 0xA0)) { /* invalid sequence, only 0xA0-0xBF allowed after 0xE0 */ - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-2; - *numSub+=numS; - return -1; - } - { - register uchar work=byte2; - work<<=6; - byte3&=0x3F; /* 0b00111111; */ - byte3|=work; - - byte2&=0x3F; /* 0b00111111; */ - byte2>>=2; - - byte1<<=4; - in=byte1 | byte2;; - in<<=8; - in+=byte3; - inLen-=3; - ++pIn; - } - } else if ((0xF0 <= byte1 && byte1 <= 0xF4)) { /* (bytes1 & 11111000) == 0x1110000 */ - /* 4 bytes sequence - 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx => 110110ww wwzzzzyy 110111yy yyxxxxxx - where uuuuu = wwww + 1 */ - register uchar byte2; - register uchar byte3; - register uchar byte4; - if (inLen < 4) { - if ((inLen >= 2 && (pIn[1] & 0xC0) != 0x80) || - (inLen >= 3 && (pIn[2] & 0xC0) != 0x80) || - (cd->toCcsid == 13488) ) - errno=EILSEQ; /* 116 */ - else - errno=EINVAL; /* 22 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return -1; - } - ++pIn; - byte2=*pIn; - ++pIn; - byte3=*pIn; - ++pIn; - byte4=*pIn; - if ((byte2 & 0xC0) == 0x80 && /* byte2 & 0b11000000 == 0b10000000 */ - (byte3 & 0xC0) == 0x80 && /* byte3 & 0b11000000 == 0b10000000 */ - (byte4 & 0xC0) == 0x80) { /* byte4 & 0b11000000 == 0b10000000 */ - register uchar work=byte2; - if (byte1 == 0xF0 && byte2 < 0x90) { - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-3; - *numSub+=numS; - return -1; - /* iconv() returns 0 for 0xF4908080 and convert to 0x00 - } else if (byte1 == 0xF4 && byte2 > 0x8F) { - errno=EINVAL; - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-3; - *numSub+=numS; - return -1; - */ - } - - work&=0x30; /* 0b00110000; */ - work>>=4; - byte1&=0x07; /* 0b00000111; */ - byte1<<=2; - byte1+=work; /* uuuuu */ - --byte1; /* wwww */ - - work=byte1 & 0x0F; - work>>=2; - work+=0xD8; /* 0b11011011; */ - in=work; - in<<=8; - - byte1<<=6; - byte2<<=2; - byte2&=0x3C; /* 0b00111100; */ - work=byte3; - work>>=4; - work&=0x03; /* 0b00000011; */ - work|=byte1; - work|=byte2; - in+=work; - - work=byte3; - work>>=2; - work&=0x03; /* 0b00000011; */ - work|=0xDC; /* 0b110111xx; */ - in2=work; - in2<<=8; - - byte3<<=6; - byte4&=0x3F; /* 0b00111111; */ - byte4|=byte3; - in2+=byte4; - inLen-=4; - ++pIn; -#ifdef match_with_GBK - if ((0xD800 == in && in2 < 0xDC80) || - (0xD840 == in && in2 < 0xDC80) || - (0xD880 == in && in2 < 0xDC80) || - (0xD8C0 == in && in2 < 0xDC80) || - (0xD900 == in && in2 < 0xDC80) || - (0xD940 == in && in2 < 0xDC80) || - (0xD980 == in && in2 < 0xDC80) || - (0xD9C0 == in && in2 < 0xDC80) || - (0xDA00 == in && in2 < 0xDC80) || - (0xDA40 == in && in2 < 0xDC80) || - (0xDA80 == in && in2 < 0xDC80) || - (0xDAC0 == in && in2 < 0xDC80) || - (0xDB00 == in && in2 < 0xDC80) || - (0xDB40 == in && in2 < 0xDC80) || - (0xDB80 == in && in2 < 0xDC80) || - (0xDBC0 == in && in2 < 0xDC80)) { -#else - if ((0xD800 <= in && in <= 0xDBFF) && - (0xDC00 <= in2 && in2 <= 0xDFFF)) { -#endif - *pOut=subS; - ++pOut; - ++numS; - continue; - } - } else { /* invalid sequence */ - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-3; - *numSub+=numS; - return -1; - } - } else if (0xF5 <= byte1 && byte1 <= 0xFF) { /* minic iconv() behavior */ - if (inLen < 4 || - (inLen >= 4 && byte1 == 0xF8 && pIn[1] < 0x90) || - pIn[1] < 0x80 || 0xBF < pIn[1] || - pIn[2] < 0x80 || 0xBF < pIn[2] || - pIn[3] < 0x80 || 0xBF < pIn[3] ) { - if (inLen == 1) - errno=EINVAL; /* 22 */ - else if (inLen == 2 && (pIn[1] & 0xC0) != 0x80) - errno=EILSEQ; /* 116 */ - else if (inLen == 3 && ((pIn[1] & 0xC0) != 0x80 || (pIn[2] & 0xC0) != 0x80)) - errno=EILSEQ; /* 116 */ - else if (inLen >= 4 && (byte1 == 0xF8 || (pIn[1] & 0xC0) != 0x80 || (pIn[2] & 0xC0) != 0x80 || (pIn[3] & 0xC0) != 0x80)) - errno=EILSEQ; /* 116 */ - else - errno=EINVAL; /* 22 */ - - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return -1; - } else if ((pIn[1] == 0x80 || pIn[1] == 0x90 || pIn[1] == 0xA0 || pIn[1] == 0xB0) && - pIn[2] < 0x82) { - *pOut=subS; /* Though returns replacement character, which iconv() does not return. */ - ++pOut; - ++numS; - pIn+=4; - inLen-=4; - continue; - } else { - *pOut=pSubD[0]; /* Though returns replacement character, which iconv() does not return. */ - ++pOut; - *pOut=pSubD[1]; - ++pOut; - ++numS; - pIn+=4; - inLen-=4; - continue; - /* iconv() returns 0 with strange 1 byte converted values */ - } - - } else { /* invalid sequence */ - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return -1; - } - } - /* end of UTF-8 to UCS-2 */ - if (in == 0x0000) { - *pOut=0x00; - ++pOut; - } else if (in < 0x100 && dmapU2S[in] != 0x0000) { - if ((*pOut=dmapU2S[in]) == subS) { - if (in != cd->srcSubS) - ++numS; - } - ++pOut; - } else { - in<<=1; - if (dmapU2M2[in] == 0x00) { /* not found in dmapU2M2 */ - in*=1.5; - if (dmapU2M3[in] == 0x00) { /* not found in dmapU2M3*/ - *pOut=pSubD[0]; - ++pOut; - *pOut=pSubD[1]; - ++pOut; - ++numS; - ++rc; - } else { - *pOut=dmapU2M3[in]; - ++pOut; - *pOut=dmapU2M3[1+in]; - ++pOut; - *pOut=dmapU2M3[2+in]; - ++pOut; - } - } else { - *pOut=dmapU2M2[in]; - ++pOut; - if (dmapU2M2[1+in] == 0x00) { - if (*pOut == subS) { - in>>=1; - if (in != cd->srcSubS) - ++numS; - } - } else { - *pOut=dmapU2M2[1+in]; - ++pOut; - if (memcmp(pOut-2, pSubD, 2) == 0) { - in>>=1; - if (in != cd->srcSubD) { - ++numS; - ++rc; - } - } - } - } - } - } - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return 0; - - } else if (cd->cnv_dmap->codingSchema == DMAP_S2U) { - /* use uchar * instead of UniChar to avoid memcpy */ - register uchar * dmapD12U=(uchar *) (cd->cnv_dmap->dmapD12U); - register int inLen=*inBytesLeft; - register char * pOut=*outBuf; - register char * pIn=*inBuf; - register int offset; - register char * pLastOutBuf = *outBuf + *outBytesLeft - 1; - register size_t numS=0; - while (0 < inLen) { - if (pLastOutBuf < pOut) - break; - if (*pIn == 0x00) { - *pOut=0x00; - ++pOut; - *pOut=0x00; - ++pOut; - ++pIn; - --inLen; - } else { - offset=*pIn; - offset<<=1; - *pOut=dmapD12U[offset]; - ++pOut; - *pOut=dmapD12U[offset+1]; - ++pOut; - if (dmapD12U[offset] == 0x00) { - if (dmapD12U[offset+1] == 0x1A) { - if (*pIn != cd->srcSubS) - ++numS; - } else if (dmapD12U[offset+1] == 0x00) { - pOut-=2; - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return -1; - } - } - ++pIn; - --inLen; - } - } - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return 0; - - } else if (cd->cnv_dmap->codingSchema == DMAP_S28) { - /* use uchar * instead of UniChar to avoid memcpy */ - register uchar * dmapD12U=(uchar *) (cd->cnv_dmap->dmapD12U); - register int inLen=*inBytesLeft; - register char * pOut=*outBuf; - register char * pIn=*inBuf; - register int offset; - register char * pLastOutBuf = *outBuf + *outBytesLeft - 1; - register size_t numS=0; - register UniChar in; /* copy part of U28 */ - while (0 < inLen) { - if (pLastOutBuf < pOut) - break; - if (*pIn == 0x00) { - *pOut=0x00; - ++pOut; - ++pIn; - --inLen; - } else { - offset=*pIn; - offset<<=1; - in=dmapD12U[offset]; - in<<=8; - in+=dmapD12U[offset+1]; - if ((in & 0xFF80) == 0x0000) { /* U28: in & 0b1111111110000000 == 0x0000 */ - if (in == 0x000) { - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return -1; - } - *pOut=in; - ++pOut; - } else if ((in & 0xF800) == 0x0000) { /* in & 0b1111100000000000 == 0x0000 */ - register uchar byte; - in>>=6; - in&=0x001F; /* 0b0000000000011111 */ - in|=0x00C0; /* 0b0000000011000000 */ - *pOut=in; - ++pOut; - byte=dmapD12U[offset+1]; - byte&=0x3F; /* 0b00111111; */ - byte|=0x80; /* 0b10000000; */ - *pOut=byte; - ++pOut; - } else if ((in & 0xFC00) == 0xD800) { /* There should not be no surrogate character in SBCS. */ - *pOut=0xEF; - ++pOut; - *pOut=0xBF; - ++pOut; - *pOut=0xBD; - ++pOut; - } else { - register uchar byte; - register uchar work; - byte=dmapD12U[offset]; - byte>>=4; - byte|=0xE0; /* 0b11100000; */ - *pOut=byte; - ++pOut; - - byte=dmapD12U[offset]; - byte<<=2; - work=dmapD12U[offset+1]; - work>>=6; - byte|=work; - byte&=0x3F; /* 0b00111111; */ - byte|=0x80; /* 0b10000000; */ - *pOut=byte; - ++pOut; - - byte=dmapD12U[offset+1]; - byte&=0x3F; /* 0b00111111; */ - byte|=0x80; /* 0b10000000; */ - *pOut=byte; - ++pOut; - } - /* end of U28 */ - if (dmapD12U[offset] == 0x00) { - if (dmapD12U[offset+1] == 0x1A) { - if (*pIn != cd->srcSubS) - ++numS; - } - } - ++pIn; - --inLen; - } - } - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return 0; - - } else if (cd->cnv_dmap->codingSchema == DMAP_U2S) { - register uchar * dmapU2S=cd->cnv_dmap->dmapU2S; - register int inLen=*inBytesLeft; - register char * pOut=*outBuf; - register char * pIn=*inBuf; - register char * pLastOutBuf = *outBuf + *outBytesLeft - 1; - register char subS=cd->subS; - register size_t numS=0; - while (0 < inLen) { - register uint32_t in; - if (inLen == 1) { - errno=EINVAL; /* 22 */ - - *inBytesLeft=inLen; - *outBytesLeft-=(pOut-*outBuf); - *outBuf=pOut; - *inBuf=pIn; - return -1; - } - if (pLastOutBuf < pOut) - break; - in=pIn[0]; - in<<=8; - in+=pIn[1]; - if (in == 0x0000) { - *pOut=0x00; - } else { - if ((*pOut=dmapU2S[in]) == 0x00) { - *pOut=subS; - ++numS; - errno=EINVAL; /* 22 */ - } else if (*pOut == subS) { - if (in != cd->srcSubS) - ++numS; - } - } - ++pOut; - pIn+=2; - inLen-=2; - } - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return numS; - - } else if (cd->cnv_dmap->codingSchema == DMAP_T2S) { - register uchar * dmapU2S=cd->cnv_dmap->dmapU2S; - register int inLen=*inBytesLeft; - register char * pOut=*outBuf; - register char * pIn=*inBuf; - register char * pLastOutBuf = *outBuf + *outBytesLeft - 1; - register char subS=cd->subS; - register size_t numS=0; - while (0 < inLen) { - register uint32_t in; - if (inLen == 1) { - errno=EINVAL; /* 22 */ - - *inBytesLeft=inLen-1; - *outBytesLeft-=(pOut-*outBuf); - *outBuf=pOut; - *inBuf=pIn; - ++numS; - *numSub+=numS; - return 0; - } - if (pLastOutBuf < pOut) - break; - in=pIn[0]; - in<<=8; - in+=pIn[1]; - if (in == 0x0000) { - *pOut=0x00; - - } else if (0xD800 <= in && in <= 0xDFFF) { /* 0xD800-0xDFFF, surrogate first and second values */ - if (0xDC00 <= in ) { - errno=EINVAL; /* 22 */ - *inBytesLeft=inLen-1; - *outBytesLeft-=(pOut-*outBuf); - *outBuf=pOut; - *inBuf=pIn; - return -1; - - } else if (inLen < 4) { - errno=EINVAL; /* 22 */ - *inBytesLeft=inLen-2; - *outBytesLeft-=(pOut-*outBuf); - *outBuf=pOut; - *inBuf=pIn+2; - return -1; - - } else { - register uint32_t in2; - in2=pIn[2]; - in2<<=8; - in2+=pIn[3]; - if (0xDC00 <= in2 && in2 <= 0xDFFF) { /* second surrogate character =0xDC00 - 0xDFFF*/ - *pOut=subS; - ++numS; - pIn+=4; - } else { - errno=EINVAL; /* 22 */ - *inBytesLeft=inLen-1; - *outBytesLeft-=(pOut-*outBuf); - *outBuf=pOut; - *inBuf=pIn; - return -1; - } - } - } else { - if ((*pOut=dmapU2S[in]) == 0x00) { - *pOut=subS; - ++numS; - errno=EINVAL; /* 22 */ - } else if (*pOut == subS) { - if (in != cd->srcSubS) - ++numS; - } - } - ++pOut; - pIn+=2; - inLen-=2; - } - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return 0; - - } else if (cd->cnv_dmap->codingSchema == DMAP_82S) { - register uchar * dmapU2S=cd->cnv_dmap->dmapU2S; - register int inLen=*inBytesLeft; - register char * pOut=*outBuf; - register char * pIn=*inBuf; - register char * pLastOutBuf = *outBuf + *outBytesLeft - 1; - register char subS=cd->subS; - register size_t numS=0; - while (0 < inLen) { - register uint32_t in; - uint32_t in2; /* The second surrogate value */ - if (pLastOutBuf < pOut) - break; - /* convert from UTF-8 to UCS-2 */ - if (*pIn == 0x00) { - in=0x0000; - ++pIn; - --inLen; - } else { /* 82U: */ - register uchar byte1=*pIn; - if ((byte1 & 0x80) == 0x00) { /* if (byte1 & 0b10000000 == 0b00000000) { */ - /* 1 bytes sequence: 0xxxxxxx => 00000000 0xxxxxxx*/ - in=byte1; - ++pIn; - --inLen; - } else if ((byte1 & 0xE0) == 0xC0) { /* (byte1 & 0b11100000 == 0b11000000) { */ - if (inLen < 2) { - errno=EINVAL; /* 22 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return -1; - } - if (byte1 == 0xC0 || byte1 == 0xC1) { /* invalid sequence */ - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return -1; - } - /* 2 bytes sequence: - 110yyyyy 10xxxxxx => 00000yyy yyxxxxxx */ - register uchar byte2; - ++pIn; - byte2=*pIn; - if ((byte2 & 0xC0) == 0x80) { /* byte2 & 0b11000000 == 0b10000000) { */ - register uchar work=byte1; - work<<=6; - byte2&=0x3F; /* 0b00111111; */ - byte2|=work; - - byte1&=0x1F; /* 0b00011111; */ - byte1>>=2; - in=byte1; - in<<=8; - in+=byte2; - inLen-=2; - ++pIn; - } else { /* invalid sequence */ - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-1; - *numSub+=numS; - return -1; - } - } else if ((byte1 & 0xF0) == 0xE0) { /* byte1 & 0b11110000 == 0b11100000 */ - /* 3 bytes sequence: - 1110zzzz 10yyyyyy 10xxxxxx => zzzzyyyy yyxxxxxx */ - register uchar byte2; - register uchar byte3; - if (inLen < 3) { - if (inLen == 2 && (pIn[1] & 0xC0) != 0x80) - errno=EILSEQ; /* 116 */ - else - errno=EINVAL; /* 22 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return -1; - } - ++pIn; - byte2=*pIn; - ++pIn; - byte3=*pIn; - if ((byte2 & 0xC0) != 0x80 || - (byte3 & 0xC0) != 0x80 || - (byte1 == 0xE0 && byte2 < 0xA0)) { /* invalid sequence, only 0xA0-0xBF allowed after 0xE0 */ - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-2; - *numSub+=numS; - return -1; - } - { - register uchar work=byte2; - work<<=6; - byte3&=0x3F; /* 0b00111111; */ - byte3|=work; - - byte2&=0x3F; /* 0b00111111; */ - byte2>>=2; - - byte1<<=4; - in=byte1 | byte2;; - in<<=8; - in+=byte3; - inLen-=3; - ++pIn; - } - } else if ((0xF0 <= byte1 && byte1 <= 0xF4) || /* (bytes1 & 11111000) == 0x1110000 */ - ((byte1&=0xF7) && 0xF0 <= byte1 && byte1 <= 0xF4)) { /* minic iconv() behavior */ - /* 4 bytes sequence - 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx => 110110ww wwzzzzyy 110111yy yyxxxxxx - where uuuuu = wwww + 1 */ - register uchar byte2; - register uchar byte3; - register uchar byte4; - if (inLen < 4) { - if ((inLen >= 2 && (pIn[1] & 0xC0) != 0x80) || - (inLen >= 3 && (pIn[2] & 0xC0) != 0x80) || - (cd->toCcsid == 13488) ) - errno=EILSEQ; /* 116 */ - else - errno=EINVAL; /* 22 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return -1; - } - ++pIn; - byte2=*pIn; - ++pIn; - byte3=*pIn; - ++pIn; - byte4=*pIn; - if ((byte2 & 0xC0) == 0x80 && /* byte2 & 0b11000000 == 0b10000000 */ - (byte3 & 0xC0) == 0x80 && /* byte3 & 0b11000000 == 0b10000000 */ - (byte4 & 0xC0) == 0x80) { /* byte4 & 0b11000000 == 0b10000000 */ - register uchar work=byte2; - if (byte1 == 0xF0 && byte2 < 0x90) { - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-3; - *numSub+=numS; - return -1; - /* iconv() returns 0 for 0xF4908080 and convert to 0x00 - } else if (byte1 == 0xF4 && byte2 > 0x8F) { - errno=EINVAL; - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-3; - *numSub+=numS; - return -1; - */ - } - - work&=0x30; /* 0b00110000; */ - work>>=4; - byte1&=0x07; /* 0b00000111; */ - byte1<<=2; - byte1+=work; /* uuuuu */ - --byte1; /* wwww */ - - work=byte1 & 0x0F; - work>>=2; - work+=0xD8; /* 0b11011011; */ - in=work; - in<<=8; - - byte1<<=6; - byte2<<=2; - byte2&=0x3C; /* 0b00111100; */ - work=byte3; - work>>=4; - work&=0x03; /* 0b00000011; */ - work|=byte1; - work|=byte2; - in+=work; - - work=byte3; - work>>=2; - work&=0x03; /* 0b00000011; */ - work|=0xDC; /* 0b110111xx; */ - in2=work; - in2<<=8; - - byte3<<=6; - byte4&=0x3F; /* 0b00111111; */ - byte4|=byte3; - in2+=byte4; - inLen-=4; - ++pIn; - } else { /* invalid sequence */ - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-3; - *numSub+=numS; - return -1; - } - } else if ((byte1 & 0xF0) == 0xF0) { /* minic iconv() behavior */ - if (inLen < 4 || - pIn[1] < 0x80 || 0xBF < pIn[1] || - pIn[2] < 0x80 || 0xBF < pIn[2] || - pIn[3] < 0x80 || 0xBF < pIn[3] ) { - if (inLen == 1) - errno=EINVAL; /* 22 */ - else if (inLen == 2 && (pIn[1] & 0xC0) != 0x80) - errno=EILSEQ; /* 116 */ - else if (inLen == 3 && ((pIn[1] & 0xC0) != 0x80 || (pIn[2] & 0xC0) != 0x80)) - errno=EILSEQ; /* 116 */ - else if (inLen >= 4 && ((pIn[1] & 0xC0) != 0x80 || (pIn[2] & 0xC0) != 0x80 || (pIn[3] & 0xC0) != 0x80)) - errno=EILSEQ; /* 116 */ - else - errno=EINVAL; /* 22 */ - - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return -1; - } else { - *pOut=subS; /* Though returns replacement character, which iconv() does not return. */ - ++pOut; - ++numS; - pIn+=4; - inLen-=4; - /* UTF-8_IBM-850 0xF0908080 : converted value does not match, iconv=0x00, dmap=0x7F - UTF-8_IBM-850 0xF0908081 : converted value does not match, iconv=0x01, dmap=0x7F - UTF-8_IBM-850 0xF0908082 : converted value does not match, iconv=0x02, dmap=0x7F - UTF-8_IBM-850 0xF0908083 : converted value does not match, iconv=0x03, dmap=0x7F - .... - UTF-8_IBM-850 0xF09081BE : converted value does not match, iconv=0x7E, dmap=0x7F - UTF-8_IBM-850 0xF09081BF : converted value does not match, iconv=0x1C, dmap=0x7F - UTF-8_IBM-850 0xF09082A0 : converted value does not match, iconv=0xFF, dmap=0x7F - UTF-8_IBM-850 0xF09082A1 : converted value does not match, iconv=0xAD, dmap=0x7F - .... - */ - continue; - /* iconv() returns 0 with strange 1 byte converted values */ - } - - } else { /* invalid sequence */ - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return -1; - } - } - /* end of UTF-8 to UCS-2 */ - if (in == 0x0000) { - *pOut=0x00; - } else { - if ((*pOut=dmapU2S[in]) == 0x00) { - *pOut=subS; - ++numS; - errno=EINVAL; /* 22 */ - } else if (*pOut == subS) { - if (in != cd->srcSubS) { - ++numS; - } - } - } - ++pOut; - } - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return 0; - - } else if (cd->cnv_dmap->codingSchema == DMAP_D2U) { - /* use uchar * instead of UniChar to avoid memcpy */ - register uchar * dmapD12U=(uchar *) (cd->cnv_dmap->dmapD12U); - register uchar * dmapD22U=(uchar *) (cd->cnv_dmap->dmapD22U); - register int inLen=*inBytesLeft; - register char * pOut=*outBuf; - register char * pIn=*inBuf; - register int offset; - register char * pLastOutBuf = *outBuf + *outBytesLeft - 1; - register size_t numS=0; - while (0 < inLen) { - if (pLastOutBuf < pOut) - break; - if (*pIn == 0x00) { - *pOut=0x00; - ++pOut; - *pOut=0x00; - ++pOut; - ++pIn; - --inLen; - } else { - offset=*pIn; - offset<<=1; - if (dmapD12U[offset] == 0x00 && - dmapD12U[offset+1] == 0x00) { /* DBCS */ - if (inLen < 2) { - if (*pIn == 0x80 || *pIn == 0xFF || - (cd->fromCcsid == 943 && (*pIn == 0x85 || *pIn == 0x86 || *pIn == 0xA0 || *pIn == 0xEB || *pIn == 0xEC || *pIn == 0xEF || *pIn == 0xFD || *pIn == 0xFE)) || - (cd->fromCcsid == 932 && (*pIn == 0x85 || *pIn == 0x86 || *pIn == 0x87 || *pIn == 0xEB || *pIn == 0xEC || *pIn == 0xED || *pIn == 0xEE || *pIn == 0xEF)) || - (cd->fromCcsid == 1381 && ((0x85 <= *pIn && *pIn <= 0x8B) || (0xAA <= *pIn && *pIn <= 0xAF) || (0xF8 <= *pIn && *pIn <= 0xFE)))) - errno=EILSEQ; /* 116 */ - else - errno=EINVAL; /* 22 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - return -1; - } - offset-=0x100; - ++pIn; - offset<<=8; - offset+=(*pIn * 2); - if (dmapD22U[offset] == 0x00 && - dmapD22U[offset+1] == 0x00) { - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-1; - return -1; - } - *pOut=dmapD22U[offset]; - ++pOut; - *pOut=dmapD22U[offset+1]; - ++pOut; - if (dmapD22U[offset] == 0xFF && - dmapD22U[offset+1] == 0xFD) { - if (pIn[-1] * 0x100 + pIn[0] != cd->srcSubD) - ++numS; - } - ++pIn; - inLen-=2; - } else { /* SBCS */ - *pOut=dmapD12U[offset]; - ++pOut; - *pOut=dmapD12U[offset+1]; - ++pOut; - if (dmapD12U[offset] == 0x00 && - dmapD12U[offset+1] == 0x1A) { - if (*pIn != cd->srcSubS) - ++numS; - } - ++pIn; - --inLen; - } - } - } - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return 0; - - } else if (cd->cnv_dmap->codingSchema == DMAP_D28) { - /* use uchar * instead of UniChar to avoid memcpy */ - register uchar * dmapD12U=(uchar *) (cd->cnv_dmap->dmapD12U); - register uchar * dmapD22U=(uchar *) (cd->cnv_dmap->dmapD22U); - register int inLen=*inBytesLeft; - register char * pOut=*outBuf; - register char * pIn=*inBuf; - register int offset; - register char * pLastOutBuf = *outBuf + *outBytesLeft - 1; - register size_t numS=0; - register UniChar in; /* copy part of U28 */ - register UniChar ucs2; - while (0 < inLen) { - if (pLastOutBuf < pOut) - break; - if (*pIn == 0x00) { - *pOut=0x00; - ++pOut; - ++pIn; - --inLen; - } else { - offset=*pIn; - offset<<=1; - if (dmapD12U[offset] == 0x00 && - dmapD12U[offset+1] == 0x00) { /* DBCS */ - if (inLen < 2) { - if (*pIn == 0x80 || *pIn == 0xFF || - (cd->fromCcsid == 943 && (*pIn == 0x85 || *pIn == 0x86 || *pIn == 0xA0 || *pIn == 0xEB || *pIn == 0xEC || *pIn == 0xEF || *pIn == 0xFD || *pIn == 0xFE)) || - (cd->fromCcsid == 932 && (*pIn == 0x85 || *pIn == 0x86 || *pIn == 0x87 || *pIn == 0xEB || *pIn == 0xEC || *pIn == 0xED || *pIn == 0xEE || *pIn == 0xEF)) || - (cd->fromCcsid == 1381 && ((0x85 <= *pIn && *pIn <= 0x8B) || (0xAA <= *pIn && *pIn <= 0xAF) || (0xF8 <= *pIn && *pIn <= 0xFE)))) - errno=EILSEQ; /* 116 */ - else - errno=EINVAL; /* 22 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - return -1; - } - offset-=0x100; - ++pIn; - offset<<=8; - offset+=(*pIn * 2); - if (dmapD22U[offset] == 0x00 && - dmapD22U[offset+1] == 0x00) { - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-1; - return -1; - } - in=dmapD22U[offset]; - in<<=8; - in+=dmapD22U[offset+1]; - ucs2=in; - if (dmapD22U[offset] == 0xFF && - dmapD22U[offset+1] == 0xFD) { - if (in != cd->srcSubD) - ++numS; - } - ++pIn; - inLen-=2; - } else { /* SBCS */ - in=dmapD12U[offset]; - in<<=8; - in+=dmapD12U[offset+1]; - ucs2=in; - if (dmapD12U[offset] == 0x00 && - dmapD12U[offset+1] == 0x1A) { - if (in != cd->srcSubS) - ++numS; - } - ++pIn; - --inLen; - } - if ((in & 0xFF80) == 0x0000) { /* U28: in & 0b1111111110000000 == 0x0000 */ - *pOut=in; - ++pOut; - } else if ((in & 0xF800) == 0x0000) { /* in & 0b1111100000000000 == 0x0000 */ - register uchar byte; - in>>=6; - in&=0x001F; /* 0b0000000000011111 */ - in|=0x00C0; /* 0b0000000011000000 */ - *pOut=in; - ++pOut; - byte=ucs2; /* dmapD12U[offset+1]; */ - byte&=0x3F; /* 0b00111111; */ - byte|=0x80; /* 0b10000000; */ - *pOut=byte; - ++pOut; - } else if ((in & 0xFC00) == 0xD800) { /* There should not be no surrogate character in SBCS. */ - *pOut=0xEF; - ++pOut; - *pOut=0xBF; - ++pOut; - *pOut=0xBD; - ++pOut; - } else { - register uchar byte; - register uchar work; - byte=(ucs2>>8); /* dmapD12U[offset]; */ - byte>>=4; - byte|=0xE0; /* 0b11100000; */ - *pOut=byte; - ++pOut; - - byte=(ucs2>>8); /* dmapD12U[offset]; */ - byte<<=2; - work=ucs2; /* dmapD12U[offset+1]; */ - work>>=6; - byte|=work; - byte&=0x3F; /* 0b00111111; */ - byte|=0x80; /* 0b10000000; */ - *pOut=byte; - ++pOut; - - byte=ucs2; /* dmapD12U[offset+1]; */ - byte&=0x3F; /* 0b00111111; */ - byte|=0x80; /* 0b10000000; */ - *pOut=byte; - ++pOut; - } - /* end of U28 */ - } - } - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return 0; - - } else if (cd->cnv_dmap->codingSchema == DMAP_U2D) { - register uchar * dmapU2D=cd->cnv_dmap->dmapU2D; - register int inLen=*inBytesLeft; - register char * pOut=*outBuf; - register char * pIn=*inBuf; - register char * pLastOutBuf = *outBuf + *outBytesLeft - 1; - register char subS=cd->subS; - register char * pSubD=(char *) &(cd->subD); - register size_t numS=0; - while (0 < inLen) { - register uint32_t in; - if (inLen == 1) { - errno=EINVAL; /* 22 */ - - *inBytesLeft=inLen; - *outBytesLeft-=(pOut-*outBuf); - *outBuf=pOut; - *inBuf=pIn; - return -1; - } - if (pLastOutBuf < pOut) - break; - in=pIn[0]; - in<<=8; - in+=pIn[1]; - if (in == 0x0000) { - *pOut=0x00; - ++pOut; - } else { - in<<=1; - *pOut=dmapU2D[in]; - ++pOut; - if (dmapU2D[in+1] == 0x00) { /* SBCS */ - if (*pOut == subS) { - if (in != cd->srcSubS) - ++numS; - } - } else { - *pOut=dmapU2D[in+1]; - ++pOut; - if (dmapU2D[in] == pSubD[0] && - dmapU2D[in+1] == pSubD[1]) { - in>>=1; - if (in != cd->srcSubD) - ++numS; - } - } - } - pIn+=2; - inLen-=2; - } - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return numS; /* to minic iconv() behavior */ - - } else if (cd->cnv_dmap->codingSchema == DMAP_T2D) { - register uchar * dmapU2D=cd->cnv_dmap->dmapU2D; - register int inLen=*inBytesLeft; - register char * pOut=*outBuf; - register char * pIn=*inBuf; - register char * pLastOutBuf = *outBuf + *outBytesLeft - 1; - register char subS=cd->subS; - register char * pSubD=(char *) &(cd->subD); - register size_t numS=0; - while (0 < inLen) { - register uint32_t in; - if (inLen == 1) { - errno=EINVAL; /* 22 */ - *inBytesLeft=inLen-1; - *outBytesLeft-=(pOut-*outBuf); - *outBuf=pOut; - *inBuf=pIn; - ++numS; - *numSub+=numS; - return 0; - } - if (pLastOutBuf < pOut) - break; - in=pIn[0]; - in<<=8; - in+=pIn[1]; - if (in == 0x0000) { - *pOut=0x00; - ++pOut; - } else if (0xD800 <= in && in <= 0xDBFF) { /* first byte of surrogate */ - errno=EINVAL; /* 22 */ - *inBytesLeft=inLen-2; - *outBytesLeft-=(pOut-*outBuf); - *outBuf=pOut; - *inBuf=pIn+2; - ++numS; - *numSub+=numS; - return -1; - - } else if (0xDC00 <= in && in <= 0xDFFF) { /* second byte of surrogate */ - errno=EINVAL; /* 22 */ - *inBytesLeft=inLen-1; - *outBytesLeft-=(pOut-*outBuf); - *outBuf=pOut; - *inBuf=pIn; - ++numS; - *numSub+=numS; - return -1; - - } else { - in<<=1; - *pOut=dmapU2D[in]; - ++pOut; - if (dmapU2D[in+1] == 0x00) { /* SBCS */ - if (*pOut == subS) { - if (in != cd->srcSubS) - ++numS; - } - } else { - *pOut=dmapU2D[in+1]; - ++pOut; - if (dmapU2D[in] == pSubD[0] && - dmapU2D[in+1] == pSubD[1]) { - in>>=1; - if (in != cd->srcSubD) - ++numS; - } - } - } - pIn+=2; - inLen-=2; - } - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return 0; /* to minic iconv() behavior */ - - } else if (cd->cnv_dmap->codingSchema == DMAP_82D) { - register uchar * dmapU2D=cd->cnv_dmap->dmapU2D; - register int inLen=*inBytesLeft; - register char * pOut=*outBuf; - register char * pIn=*inBuf; - register char * pLastOutBuf = *outBuf + *outBytesLeft - 1; - register char subS=cd->subS; - register char * pSubD=(char *) &(cd->subD); - register size_t numS=0; - while (0 < inLen) { - register uint32_t in; - uint32_t in2; - if (pLastOutBuf < pOut) - break; - /* convert from UTF-8 to UCS-2 */ - if (*pIn == 0x00) { - in=0x0000; - ++pIn; - --inLen; - } else { /* 82U: */ - register uchar byte1=*pIn; - if ((byte1 & 0x80) == 0x00) { /* if (byte1 & 0b10000000 == 0b00000000) { */ - /* 1 bytes sequence: 0xxxxxxx => 00000000 0xxxxxxx*/ - in=byte1; - ++pIn; - --inLen; - } else if ((byte1 & 0xE0) == 0xC0) { /* (byte1 & 0b11100000 == 0b11000000) { */ - if (inLen < 2) { - errno=EINVAL; /* 22 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return -1; - } - if (byte1 == 0xC0 || byte1 == 0xC1) { /* invalid sequence */ - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return -1; - } - /* 2 bytes sequence: - 110yyyyy 10xxxxxx => 00000yyy yyxxxxxx */ - register uchar byte2; - ++pIn; - byte2=*pIn; - if ((byte2 & 0xC0) == 0x80) { /* byte2 & 0b11000000 == 0b10000000) { */ - register uchar work=byte1; - work<<=6; - byte2&=0x3F; /* 0b00111111; */ - byte2|=work; - - byte1&=0x1F; /* 0b00011111; */ - byte1>>=2; - in=byte1; - in<<=8; - in+=byte2; - inLen-=2; - ++pIn; - } else { /* invalid sequence */ - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-1; - *numSub+=numS; - return -1; - } - } else if ((byte1 & 0xF0) == 0xE0) { /* byte1 & 0b11110000 == 0b11100000 */ - /* 3 bytes sequence: - 1110zzzz 10yyyyyy 10xxxxxx => zzzzyyyy yyxxxxxx */ - register uchar byte2; - register uchar byte3; - if (inLen < 3) { - if (inLen == 2 && (pIn[1] & 0xC0) != 0x80) - errno=EILSEQ; /* 116 */ - else - errno=EINVAL; /* 22 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return -1; - } - ++pIn; - byte2=*pIn; - ++pIn; - byte3=*pIn; - if ((byte2 & 0xC0) != 0x80 || - (byte3 & 0xC0) != 0x80 || - (byte1 == 0xE0 && byte2 < 0xA0)) { /* invalid sequence, only 0xA0-0xBF allowed after 0xE0 */ - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-2; - *numSub+=numS; - return -1; - } - { - register uchar work=byte2; - work<<=6; - byte3&=0x3F; /* 0b00111111; */ - byte3|=work; - - byte2&=0x3F; /* 0b00111111; */ - byte2>>=2; - - byte1<<=4; - in=byte1 | byte2;; - in<<=8; - in+=byte3; - inLen-=3; - ++pIn; - } - } else if ((0xF0 <= byte1 && byte1 <= 0xF4)) { /* (bytes1 & 11111000) == 0x1110000 */ - /* 4 bytes sequence - 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx => 110110ww wwzzzzyy 110111yy yyxxxxxx - where uuuuu = wwww + 1 */ - register uchar byte2; - register uchar byte3; - register uchar byte4; - if (inLen < 4) { - if ((inLen >= 2 && (pIn[1] & 0xC0) != 0x80) || - (inLen >= 3 && (pIn[2] & 0xC0) != 0x80) || - (cd->toCcsid == 13488) ) - errno=EILSEQ; /* 116 */ - else - errno=EINVAL; /* 22 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return -1; - } - ++pIn; - byte2=*pIn; - ++pIn; - byte3=*pIn; - ++pIn; - byte4=*pIn; - if ((byte2 & 0xC0) == 0x80 && /* byte2 & 0b11000000 == 0b10000000 */ - (byte3 & 0xC0) == 0x80 && /* byte3 & 0b11000000 == 0b10000000 */ - (byte4 & 0xC0) == 0x80) { /* byte4 & 0b11000000 == 0b10000000 */ - register uchar work=byte2; - if (byte1 == 0xF0 && byte2 < 0x90) { - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-3; - *numSub+=numS; - return -1; - /* iconv() returns 0 for 0xF4908080 and convert to 0x00 - } else if (byte1 == 0xF4 && byte2 > 0x8F) { - errno=EINVAL; - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-3; - *numSub+=numS; - return -1; - */ - } - - work&=0x30; /* 0b00110000; */ - work>>=4; - byte1&=0x07; /* 0b00000111; */ - byte1<<=2; - byte1+=work; /* uuuuu */ - --byte1; /* wwww */ - - work=byte1 & 0x0F; - work>>=2; - work+=0xD8; /* 0b11011011; */ - in=work; - in<<=8; - - byte1<<=6; - byte2<<=2; - byte2&=0x3C; /* 0b00111100; */ - work=byte3; - work>>=4; - work&=0x03; /* 0b00000011; */ - work|=byte1; - work|=byte2; - in+=work; - - work=byte3; - work>>=2; - work&=0x03; /* 0b00000011; */ - work|=0xDC; /* 0b110111xx; */ - in2=work; - in2<<=8; - - byte3<<=6; - byte4&=0x3F; /* 0b00111111; */ - byte4|=byte3; - in2+=byte4; - inLen-=4; - ++pIn; -#ifdef match_with_GBK - if ((0xD800 == in && in2 < 0xDC80) || - (0xD840 == in && in2 < 0xDC80) || - (0xD880 == in && in2 < 0xDC80) || - (0xD8C0 == in && in2 < 0xDC80) || - (0xD900 == in && in2 < 0xDC80) || - (0xD940 == in && in2 < 0xDC80) || - (0xD980 == in && in2 < 0xDC80) || - (0xD9C0 == in && in2 < 0xDC80) || - (0xDA00 == in && in2 < 0xDC80) || - (0xDA40 == in && in2 < 0xDC80) || - (0xDA80 == in && in2 < 0xDC80) || - (0xDAC0 == in && in2 < 0xDC80) || - (0xDB00 == in && in2 < 0xDC80) || - (0xDB40 == in && in2 < 0xDC80) || - (0xDB80 == in && in2 < 0xDC80) || - (0xDBC0 == in && in2 < 0xDC80)) { -#else - if ((0xD800 <= in && in <= 0xDBFF) && - (0xDC00 <= in2 && in2 <= 0xDFFF)) { -#endif - *pOut=subS; - ++pOut; - ++numS; - continue; - } - } else { /* invalid sequence */ - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-3; - *numSub+=numS; - return -1; - } - } else if (0xF5 <= byte1 && byte1 <= 0xFF) { /* minic iconv() behavior */ - if (inLen < 4 || - (inLen >= 4 && byte1 == 0xF8 && pIn[1] < 0x90) || - pIn[1] < 0x80 || 0xBF < pIn[1] || - pIn[2] < 0x80 || 0xBF < pIn[2] || - pIn[3] < 0x80 || 0xBF < pIn[3] ) { - if (inLen == 1) - errno=EINVAL; /* 22 */ - else if (inLen == 2 && (pIn[1] & 0xC0) != 0x80) - errno=EILSEQ; /* 116 */ - else if (inLen == 3 && ((pIn[1] & 0xC0) != 0x80 || (pIn[2] & 0xC0) != 0x80)) - errno=EILSEQ; /* 116 */ - else if (inLen >= 4 && (byte1 == 0xF8 || (pIn[1] & 0xC0) != 0x80 || (pIn[2] & 0xC0) != 0x80 || (pIn[3] & 0xC0) != 0x80)) - errno=EILSEQ; /* 116 */ - else - errno=EINVAL; /* 22 */ - - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return -1; - } else if ((pIn[1] == 0x80 || pIn[1] == 0x90 || pIn[1] == 0xA0 || pIn[1] == 0xB0) && - pIn[2] < 0x82) { - *pOut=subS; /* Though returns replacement character, which iconv() does not return. */ - ++pOut; - ++numS; - pIn+=4; - inLen-=4; - continue; - } else { - *pOut=pSubD[0]; /* Though returns replacement character, which iconv() does not return. */ - ++pOut; - *pOut=pSubD[1]; - ++pOut; - ++numS; - pIn+=4; - inLen-=4; - continue; - /* iconv() returns 0 with strange 1 byte converted values */ - } - - } else { /* invalid sequence */ - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return -1; - } - } - /* end of UTF-8 to UCS-2 */ - if (in == 0x0000) { - *pOut=0x00; - ++pOut; - } else { - in<<=1; - *pOut=dmapU2D[in]; - ++pOut; - if (dmapU2D[in+1] == 0x00) { /* SBCS */ - if (dmapU2D[in] == subS) { - in>>=1; - if (in != cd->srcSubS) - ++numS; - } - } else { - *pOut=dmapU2D[in+1]; - ++pOut; - if (dmapU2D[in] == pSubD[0] && - dmapU2D[in+1] == pSubD[1]) { - in>>=1; - if (in != cd->srcSubD) - ++numS; - } - } - } - } - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return 0; - - } else if (cd->cnv_dmap->codingSchema == DMAP_82U) { - /* See http://unicode.org/versions/corrigendum1.html */ - /* convert from UTF-8 to UTF-16 can cover all conversion from UTF-8 to UCS-2 */ - register int inLen=*inBytesLeft; - register char * pOut=*outBuf; - register char * pIn=*inBuf; - register char * pLastOutBuf = *outBuf + *outBytesLeft - 1; - register size_t numS=0; - while (0 < inLen) { - if (pLastOutBuf < pOut) - break; - if (*pIn == 0x00) { - *pOut=0x00; - ++pOut; - *pOut=0x00; - ++pOut; - ++pIn; - --inLen; - } else { /* 82U: */ - register uchar byte1=*pIn; - if ((byte1 & 0x80) == 0x00) { /* if (byte1 & 0b10000000 == 0b00000000) { */ - /* 1 bytes sequence: 0xxxxxxx => 00000000 0xxxxxxx*/ - *pOut=0x00; - ++pOut; - *pOut=byte1; - ++pOut; - ++pIn; - --inLen; - } else if ((byte1 & 0xE0) == 0xC0) { /* (byte1 & 0b11100000 == 0b11000000) { */ - if (inLen < 2) { - errno=EINVAL; /* 22 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return -1; - } - if (byte1 == 0xC0 || byte1 == 0xC1) { /* invalid sequence */ - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return -1; - } - /* 2 bytes sequence: - 110yyyyy 10xxxxxx => 00000yyy yyxxxxxx */ - register uchar byte2; - ++pIn; - byte2=*pIn; - if ((byte2 & 0xC0) == 0x80) { /* byte2 & 0b11000000 == 0b10000000) { */ - register uchar work=byte1; - work<<=6; - byte2&=0x3F; /* 0b00111111; */ - byte2|=work; - - byte1&=0x1F; /* 0b00011111; */ - byte1>>=2; - *pOut=byte1; - ++pOut; - *pOut=byte2; - ++pOut; - inLen-=2; - ++pIn; - } else { /* invalid sequence */ - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-1; - *numSub+=numS; - return -1; - } - } else if ((byte1 & 0xF0) == 0xE0) { /* byte1 & 0b11110000 == 0b11100000 */ - /* 3 bytes sequence: - 1110zzzz 10yyyyyy 10xxxxxx => zzzzyyyy yyxxxxxx */ - register uchar byte2; - register uchar byte3; - if (inLen < 3) { - if (inLen == 2 && (pIn[1] & 0xC0) != 0x80) - errno=EILSEQ; /* 116 */ - else - errno=EINVAL; /* 22 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return -1; - } - ++pIn; - byte2=*pIn; - ++pIn; - byte3=*pIn; - if ((byte2 & 0xC0) != 0x80 || - (byte3 & 0xC0) != 0x80 || - (byte1 == 0xE0 && byte2 < 0xA0)) { /* invalid sequence, only 0xA0-0xBF allowed after 0xE0 */ - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-2; - *numSub+=numS; - return -1; - } - { - register uchar work=byte2; - work<<=6; - byte3&=0x3F; /* 0b00111111; */ - byte3|=work; - - byte2&=0x3F; /* 0b00111111; */ - byte2>>=2; - - byte1<<=4; - *pOut=byte1 | byte2;; - ++pOut; - *pOut=byte3; - ++pOut; - inLen-=3; - ++pIn; - } - } else if ((0xF0 <= byte1 && byte1 <= 0xF4) || /* (bytes1 & 11111000) == 0x1110000 */ - ((byte1&=0xF7) && 0xF0 <= byte1 && byte1 <= 0xF4)) { /* minic iconv() behavior */ - /* 4 bytes sequence - 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx => 110110ww wwzzzzyy 110111yy yyxxxxxx - where uuuuu = wwww + 1 */ - register uchar byte2; - register uchar byte3; - register uchar byte4; - if (inLen < 4 || cd->toCcsid == 13488) { - if ((inLen >= 2 && (pIn[1] & 0xC0) != 0x80) || - (inLen >= 3 && (pIn[2] & 0xC0) != 0x80) || - (cd->toCcsid == 13488) ) - errno=EILSEQ; /* 116 */ - else - errno=EINVAL; /* 22 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return -1; - } - ++pIn; - byte2=*pIn; - ++pIn; - byte3=*pIn; - ++pIn; - byte4=*pIn; - if ((byte2 & 0xC0) == 0x80 && /* byte2 & 0b11000000 == 0b10000000 */ - (byte3 & 0xC0) == 0x80 && /* byte3 & 0b11000000 == 0b10000000 */ - (byte4 & 0xC0) == 0x80) { /* byte4 & 0b11000000 == 0b10000000 */ - register uchar work=byte2; - if (byte1 == 0xF0 && byte2 < 0x90) { - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-3; - *numSub+=numS; - return -1; - } else if (byte1 == 0xF4 && byte2 > 0x8F) { - errno=EINVAL; /* 22 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-3; - *numSub+=numS; - return -1; - } - - work&=0x30; /* 0b00110000; */ - work>>=4; - byte1&=0x07; /* 0b00000111; */ - byte1<<=2; - byte1+=work; /* uuuuu */ - --byte1; /* wwww */ - - work=byte1 & 0x0F; - work>>=2; - work+=0xD8; /* 0b11011011; */ - *pOut=work; - ++pOut; - - byte1<<=6; - byte2<<=2; - byte2&=0x3C; /* 0b00111100; */ - work=byte3; - work>>=4; - work&=0x03; /* 0b00000011; */ - work|=byte1; - work|=byte2; - *pOut=work; - ++pOut; - - work=byte3; - work>>=2; - work&=0x03; /* 0b00000011; */ - work|=0xDC; /* 0b110111xx; */ - *pOut=work; - ++pOut; - - byte3<<=6; - byte4&=0x3F; /* 0b00111111; */ - byte4|=byte3; - *pOut=byte4; - ++pOut; - inLen-=4; - ++pIn; - } else { /* invalid sequence */ - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn-3; - *numSub+=numS; - return -1; - } - } else if ((byte1 & 0xF0) == 0xF0) { - if (cd->toCcsid == 13488) { - errno=EILSEQ; /* 116 */ - } else { - if (inLen == 1) - errno=EINVAL; /* 22 */ - else if (inLen == 2 && (pIn[1] & 0xC0) != 0x80) - errno=EILSEQ; /* 116 */ - else if (inLen == 3 && ((pIn[1] & 0xC0) != 0x80 || (pIn[2] & 0xC0) != 0x80)) - errno=EILSEQ; /* 116 */ - else if (inLen >= 4 && ((pIn[1] & 0xC0) != 0x80 || (pIn[2] & 0xC0) != 0x80 || (pIn[3] & 0xC0) != 0x80)) - errno=EILSEQ; /* 116 */ - else - errno=EINVAL; /* 22 */ - } - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return -1; - - } else { /* invalid sequence */ - errno=EILSEQ; /* 116 */ - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return -1; - } - } - } - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - *numSub+=numS; - return 0; - } else if (cd->cnv_dmap->codingSchema == DMAP_U28) { - /* See http://unicode.org/versions/corrigendum1.html */ - register int inLen=*inBytesLeft; - register char * pOut=*outBuf; - register char * pIn=*inBuf; - register char * pLastOutBuf = *outBuf + *outBytesLeft - 1; - // register size_t numS=0; - while (0 < inLen) { - register uint32_t in; - if (inLen == 1) { - errno=EINVAL; /* 22 */ - *inBytesLeft=inLen; - *outBytesLeft-=(pOut-*outBuf); - *outBuf=pOut; - *inBuf=pIn; - return -1; - } - if (pLastOutBuf < pOut) - break; - in=pIn[0]; - in<<=8; - in+=pIn[1]; - if (in == 0x0000) { - *pOut=0x00; - ++pOut; - } else if ((in & 0xFF80) == 0x0000) { /* U28: in & 0b1111111110000000 == 0x0000 */ - *pOut=in; - ++pOut; - } else if ((in & 0xF800) == 0x0000) { /* in & 0b1111100000000000 == 0x0000 */ - register uchar byte; - in>>=6; - in&=0x001F; /* 0b0000000000011111 */ - in|=0x00C0; /* 0b0000000011000000 */ - *pOut=in; - ++pOut; - byte=pIn[1]; - byte&=0x3F; /* 0b00111111; */ - byte|=0x80; /* 0b10000000; */ - *pOut=byte; - ++pOut; - } else { - register uchar byte; - register uchar work; - byte=pIn[0]; - byte>>=4; - byte|=0xE0; /* 0b11100000; */ - *pOut=byte; - ++pOut; - - byte=pIn[0]; - byte<<=2; - work=pIn[1]; - work>>=6; - byte|=work; - byte&=0x3F; /* 0b00111111; */ - byte|=0x80; /* 0b10000000; */ - *pOut=byte; - ++pOut; - - byte=pIn[1]; - byte&=0x3F; /* 0b00111111; */ - byte|=0x80; /* 0b10000000; */ - *pOut=byte; - ++pOut; - } - pIn+=2; - inLen-=2; - } - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - // *numSub+=numS; - return 0; - - } else if (cd->cnv_dmap->codingSchema == DMAP_T28) { /* UTF-16_UTF-8 */ - /* See http://unicode.org/versions/corrigendum1.html */ - register int inLen=*inBytesLeft; - register char * pOut=*outBuf; - register char * pIn=*inBuf; - register char * pLastOutBuf = *outBuf + *outBytesLeft - 1; - // register size_t numS=0; - while (0 < inLen) { - register uint32_t in; - if (inLen == 1) { - errno=EINVAL; /* 22 */ - *inBytesLeft=0; - *outBytesLeft-=(pOut-*outBuf); - *outBuf=pOut; - *inBuf=pIn; - return 0; - } - if (pLastOutBuf < pOut) - break; - in=pIn[0]; - in<<=8; - in+=pIn[1]; - if (in == 0x0000) { - *pOut=0x00; - ++pOut; - } else if ((in & 0xFF80) == 0x0000) { /* U28: in & 0b1111111110000000 == 0x0000 */ - *pOut=in; - ++pOut; - } else if ((in & 0xF800) == 0x0000) { /* in & 0b1111100000000000 == 0x0000 */ - register uchar byte; - in>>=6; - in&=0x001F; /* 0b0000000000011111 */ - in|=0x00C0; /* 0b0000000011000000 */ - *pOut=in; - ++pOut; - byte=pIn[1]; - byte&=0x3F; /* 0b00111111; */ - byte|=0x80; /* 0b10000000; */ - *pOut=byte; - ++pOut; - } else if ((in & 0xFC00) == 0xD800) { /* in & 0b1111110000000000 == 0b1101100000000000, first surrogate character */ - if (0xDC00 <= in ) { - errno=EINVAL; /* 22 */ - *inBytesLeft=inLen-1; - *outBytesLeft-=(pOut-*outBuf); - *outBuf=pOut; - *inBuf=pIn; - return -1; - - } else if (inLen < 4) { - errno=EINVAL; /* 22 */ - *inBytesLeft=inLen-2; - *outBytesLeft-=(pOut-*outBuf); - *outBuf=pOut; - *inBuf=pIn+2; - return -1; - - } else if ((pIn[2] & 0xFC) != 0xDC) { /* pIn[2] & 0b11111100 == 0b11011100, second surrogate character */ - errno=EINVAL; /* 22 */ - *inBytesLeft=inLen-2; - *outBytesLeft-=(pOut-*outBuf); - *outBuf=pOut; - *inBuf=pIn+2; - return -1; - - } else { - register uchar byte; - register uchar work; - in>>=6; - in&=0x000F; /* 0b0000000000001111 */ - byte=in; /* wwww */ - ++byte; /* uuuuu */ - work=byte; /* save uuuuu */ - byte>>=2; - byte|=0xF0; /* 0b11110000; */ - *pOut=byte; - ++pOut; - - byte=work; - byte&=0x03; /* 0b00000011; */ - byte<<=4; - byte|=0x80; /* 0b10000000; */ - work=pIn[1]; - work&=0x3C; /* 0b00111100; */ - work>>=2; - byte|=work; - *pOut=byte; - ++pOut; - - byte=pIn[1]; - byte&=0x03; /* 0b00000011; */ - byte<<=4; - byte|=0x80; /* 0b10000000; */ - work=pIn[2]; - work&=0x03; /* 0b00000011; */ - work<<=2; - byte|=work; - work=pIn[3]; - work>>=6; - byte|=work; - *pOut=byte; - ++pOut; - - byte=pIn[3]; - byte&=0x3F; /* 0b00111111; */ - byte|=0x80; /* 0b10000000; */ - *pOut=byte; - ++pOut; - pIn+=2; - inLen-=2; - } - } else if ((in & 0xFC00) == 0xDC00) { /* in & 0b11111100 == 0b11011100, second surrogate character */ - errno=EINVAL; /* 22 */ - *inBytesLeft=inLen-1; - *outBytesLeft-=(pOut-*outBuf); - *outBuf=pOut; - *inBuf=pIn; - return -1; - - } else { - register uchar byte; - register uchar work; - byte=pIn[0]; - byte>>=4; - byte|=0xE0; /* 0b11100000; */ - *pOut=byte; - ++pOut; - - byte=pIn[0]; - byte<<=2; - work=pIn[1]; - work>>=6; - byte|=work; - byte&=0x3F; /* 0b00111111; */ - byte|=0x80; /* 0b10000000; */ - *pOut=byte; - ++pOut; - - byte=pIn[1]; - byte&=0x3F; /* 0b00111111; */ - byte|=0x80; /* 0b10000000; */ - *pOut=byte; - ++pOut; - } - pIn+=2; - inLen-=2; - } - *outBytesLeft-=(pOut-*outBuf); - *inBytesLeft=inLen; - *outBuf=pOut; - *inBuf=pIn; - // *numSub+=numS; - return 0; - - } else if (cd->cnv_dmap->codingSchema == DMAP_U2U) { /* UTF-16_UCS-2 */ - register int inLen=*inBytesLeft; - register int outLen=*outBytesLeft; - if (inLen <= outLen) { - memcpy(*outBuf, *inBuf, inLen); - (*outBytesLeft)-=inLen; - (*inBuf)+=inLen; - (*outBuf)+=inLen; - *inBytesLeft=0; - return 0; - } - memcpy(*outBuf, *inBuf, outLen); - (*outBytesLeft)=0; - (*inBuf)+=outLen; - (*outBuf)+=outLen; - *inBytesLeft-=outLen; - return (*inBytesLeft); - - } else { - return -1; - } - return 0; -} - - -#ifdef DEBUG -inline size_t myconv(myconv_t cd , - char** inBuf, - size_t* inBytesLeft, - char** outBuf, - size_t* outBytesLeft, - size_t* numSub) -{ - if (cd->converterType == CONVERTER_ICONV) { - return myconv_iconv(cd,inBuf,inBytesLeft,outBuf,outBytesLeft,numSub); - } else if (cd->converterType == CONVERTER_DMAP) { - return myconv_dmap(cd,inBuf,inBytesLeft,outBuf,outBytesLeft,numSub); - } - return -1; -} - -inline char * converterName(int32_t type) -{ - if (type == CONVERTER_ICONV) - return "iconv"; - else if (type == CONVERTER_DMAP) - return "dmap"; - - return "?????"; -} -#else -#define myconv(a,b,c,d,e,f) \ -(((a)->converterType == CONVERTER_ICONV)? myconv_iconv((a),(b),(c),(d),(e),(f)): (((a)->converterType == CONVERTER_DMAP)? myconv_dmap((a),(b),(c),(d),(e),(f)): -1)) - - -#define converterName(a) \ -(((a) == CONVERTER_ICONV)? "iconv": ((a) == CONVERTER_DMAP)? "dmap": "?????") -#endif - -void initMyconv(); -void cleanupMyconv(); - -#endif diff --git a/storage/ibmdb2i/db2i_rir.cc b/storage/ibmdb2i/db2i_rir.cc deleted file mode 100644 index 091c4d98383..00000000000 --- a/storage/ibmdb2i/db2i_rir.cc +++ /dev/null @@ -1,686 +0,0 @@ -/* -Licensed Materials - Property of IBM -DB2 Storage Engine Enablement -Copyright IBM Corporation 2007,2008 -All rights reserved - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - (a) Redistributions of source code must retain this list of conditions, the - copyright notice in section {d} below, and the disclaimer following this - list of conditions. - (b) Redistributions in binary form must reproduce this list of conditions, the - copyright notice in section (d) below, and the disclaimer following this - list of conditions, in the documentation and/or other materials provided - with the distribution. - (c) The name of IBM may not be used to endorse or promote products derived from - this software without specific prior written permission. - (d) The text of the required copyright notice is: - Licensed Materials - Property of IBM - DB2 Storage Engine Enablement - Copyright IBM Corporation 2007,2008 - All rights reserved - -THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - - -#include "ha_ibmdb2i.h" - -/* Helper function for records_in_range. - Input: Bitmap of used key parts. - Output: Number of used key parts. */ - -static inline int getKeyCntFromMap(key_part_map keypart_map) -{ - int cnt = 0; - while (keypart_map) - { - keypart_map = keypart_map >> 1; - cnt++; - } - return (cnt); -} - -/** - @brief - Given a starting key and an ending key, estimate the number of rows that - will exist between the two keys. - - INPUT - inx Index to use - min_key Min key. Is NULL if no min range - max_key Max key. Is NULL if no max range - - NOTES - min_key.flag can have one of the following values: - HA_READ_KEY_EXACT Include the key in the range - HA_READ_AFTER_KEY Don't include key in range - - max_key.flag can have one of the following values: - HA_READ_BEFORE_KEY Don't include key in range - HA_READ_AFTER_KEY Include all 'end_key' values in the range - - RETURN - HA_POS_ERROR Error or the storage engine cannot estimate the number of rows - 1 There are no matching keys in the given range - n > 0 There are approximately n rows in the range -*/ -ha_rows ha_ibmdb2i::records_in_range(uint inx, - key_range *min_key, - key_range *max_key) -{ - DBUG_ENTER("ha_ibmdb2i::records_in_range"); - int rc = 0; // Return code - ha_rows rows = 0; // Row count returned to caller of this method - uint32 spcLen; // Length of space passed to DB2 - uint32 keyCnt; // Number of fields in the key composite - uint32 literalCnt = 0; // Number of literals - uint32 boundsOff; // Offset from beginning of space to range bounds - uint32 litDefOff; // Offset from beginning of space to literal definitions - uint32 literalsOff; // Offset from beginning of space to literal values - uint32 cutoff = 0; // Early exit cutoff (currently not used) - uint64 recCnt; // Row count from DB2 - uint16 rtnCode; // Return code from DB2 - Bounds* boundsPtr; // Pointer to a pair of range bounds - Bound* boundPtr; // Pointer to a single (high or low) range bound - LitDef* litDefPtr; // Pointer to a literal definition - char* literalsPtr; // Pointer to the start of all literal values - char* literalPtr; // Pointer to the start of this literal value - char* tempPtr; // Temporary pointer - char* tempMinPtr; // Temporary pointer into min_key - int minKeyCnt = 0; // Number of fields in the min_key composite - int maxKeyCnt = 0; // Number of fields in the max_key composite - size_t tempLen = 0; // Temporary length - uint16 DB2FieldWidth = 0; // DB2 field width - uint32 workFieldLen = 0; // Length of workarea needed for CCSID conversions - bool overrideInclusion; // Indicator for inclusion/exclusion - char* endOfLiteralPtr; // Pointer to the end of this literal - char* endOfMinPtr; // Pointer to end of min_key - uint16 endByte = 0; // End byte of char or graphic literal (padding not included) - bool reuseLiteral; // Indicator that hi and lo bounds use same literal - char* minPtr = NULL; // Work pointer for traversing min_key - char* maxPtr = NULL; // Work pointer for traversing max_key - /* - Handle the special case of 'x < null' anywhere in the key range. There are - no values less than null, but return 1 so that MySQL does not assume - the empty set for the query. - */ - if (min_key != NULL && max_key != NULL && - min_key->flag == HA_READ_AFTER_KEY && max_key->flag == HA_READ_BEFORE_KEY && - min_key->length == max_key->length && - (memcmp((uchar*)min_key->key,(uchar*)max_key->key,min_key->length)==0)) - { - DBUG_PRINT("ha_ibmdb2i::records_in_range",("Estimate 1 row for key %d; special case: < null", inx)); - DBUG_RETURN((ha_rows) 1 ); - } - /* - Determine the number of fields in the key composite. - */ - - if (min_key) - { - minKeyCnt = getKeyCntFromMap(min_key->keypart_map); - minPtr = (char*)min_key->key; - } - if (max_key) - { - maxKeyCnt = getKeyCntFromMap(max_key->keypart_map); - maxPtr = (char*)max_key->key; - } - keyCnt = maxKeyCnt >= minKeyCnt ? maxKeyCnt : minKeyCnt; - - /* - Handle the special case where MySQL does not pass either a min or max - key range. In this case, set the key count to 1 (knowing that there - is at least one key field) to flow through and create one bounds structure. - When both the min and max key ranges are nil, the bounds structure will - specify positive and negative infinity and DB2 will estimate the total - number of rows. */ - - if (keyCnt == 0) - keyCnt = 1; - - /* - Allocate the space needed to pass range information to DB2. The - space must be large enough to store the following: - - one pair of bounds (high and low) per field in the key composite - - one literal definition per literal value - - the literal values - - work area for literal CCSID conversions - Since we don't know yet how many of these structures are needed, - allocate enough space for the maximum that we will possibly need. - The workarea for the literal conversion must be big enough to hold the - largest of the DB2 key fields. - */ - KEY& curKey = table->key_info[inx]; - - for (int i = 0; i < keyCnt; i++) - { - DB2FieldWidth = - db2Table->db2Field(curKey.key_part[i].field->field_index).getByteLengthInRecord(); - if (DB2FieldWidth > workFieldLen) - workFieldLen = DB2FieldWidth; // Get length of largest DB2 field - tempLen = tempLen + DB2FieldWidth; // Tally the DB2 field lengths - } - spcLen = (sizeof(Bounds)*keyCnt) + (sizeof(LitDef)*keyCnt*2) + (tempLen*2) + workFieldLen; - - ValidatedPointer spcPtr(spcLen); // Pointer to space passed to DB2 - memset(spcPtr, 0, spcLen); // Clear the allocated space - /* - Set addressability to the various sections of the DB2 interface space. - */ - boundsOff = 0; // Range bounds are at the start of the space - litDefOff = sizeof(Bounds) * keyCnt; // Literal defs follow all the range bounds - literalsOff = litDefOff + (sizeof(LitDef) * keyCnt * 2); // Literal values are last - boundsPtr = (Bounds_t*)(void*)spcPtr; // Address first bounds structure - tempPtr = (char*)((char*)spcPtr + litDefOff); - litDefPtr = (LitDef_t*)tempPtr; // Address first literal definition - tempPtr = (char*)((char*)spcPtr + literalsOff); - literalsPtr = (char*)tempPtr; // Address start of literal values - literalPtr = literalsPtr; // Address first literal value - /* - For each key part, build the low (min) and high (max) DB2 range bounds. - If literals are specified in the MySQL range, build DB2 literal - definitions and store the literal values for access by DB2. - - If no value is specified for a key part, assume infinity. Negative - infinity will cause processing to start at the first index entry. - Positive infinity will cause processing to end at the last index entry. - When infinity is specified in a bound, inclusion/exclusion and position - are ignored, and there is no literal definition or literal value for - the bound. - - If the keypart value is null, the null indicator is set in the range - bound and the other fields in the bound are ignored. When the bound is - null, only index entries with the null value will be included in the - estimate. If one bound is null, both bounds must be null. When the bound - is not null, the data offset and length must be set, and the literal - value stored for access by DB2. - */ - for (int partsInUse = 0; partsInUse < keyCnt; ++partsInUse) - { - Field *field= curKey.key_part[partsInUse].field; - overrideInclusion = false; - reuseLiteral = false; - endOfLiteralPtr = NULL; - /* - Build the low bound for the key range. - */ - if ((partsInUse + 1) > minKeyCnt) // if no min_key info for this part - boundsPtr->LoBound.Infinity[0] = QMY_NEG_INFINITY; // select...where 3 between x and y - else - { - if ((curKey.key_part[partsInUse].null_bit) && (char*)minPtr[0]) - { // min_key is null - if (max_key == NULL || - ((partsInUse + 1) > maxKeyCnt)) // select...where x='ab' and y=null and z != 'c' - boundsPtr->LoBound.Infinity[0] = QMY_NEG_INFINITY; // select...where x not null or - // select...where x > null - else // max_key is not null - { - if (min_key->flag == HA_READ_KEY_EXACT) - boundsPtr->LoBound.IsNull[0] = QMY_YES; // select...where x is null - else - { - if ((char*)maxPtr[0]) - boundsPtr->LoBound.IsNull[0] = QMY_YES; // select...where a = null and b < 5 (max-before) - // select...where a='a' and b is null and c !='a' (max-after) - else - boundsPtr->LoBound.Infinity[0] = QMY_NEG_INFINITY; // select...where x < y - } - } // end min_key is null - } - else // min_key is not null - { - if (literalCnt) litDefPtr = litDefPtr + 1; - literalCnt = literalCnt + 1; - boundsPtr->LoBound.Position = literalCnt; - /* - Determine inclusion or exclusion. - */ - if (min_key->flag == HA_READ_KEY_EXACT || //select...where a like 'this%' - - /* An example for the following conditions is 'select...where a = 5 and b > null'. */ - - (max_key && - (memcmp((uchar*)minPtr,(uchar*)maxPtr, - curKey.key_part[partsInUse].store_length)==0))) - - { - if ((min_key->flag != HA_READ_KEY_EXACT) || - (max_key && - (memcmp((uchar*)minPtr,(uchar*)maxPtr, - curKey.key_part[partsInUse].store_length)==0))) - overrideInclusion = true; // Need inclusion for both min and max - } - else - boundsPtr->LoBound.Embodiment[0] = QMY_EXCLUSION; - litDefPtr->FieldNbr = field->field_index + 1; - DB2Field& db2Field = db2Table->db2Field(field->field_index); - litDefPtr->DataType = db2Field.getType(); - /* - Convert the literal to DB2 format - */ - if ((field->type() != MYSQL_TYPE_BIT) && // Don't do conversion on BIT data - (field->charset() != &my_charset_bin) && // Don't do conversion on BINARY data - (litDefPtr->DataType == QMY_CHAR || - litDefPtr->DataType == QMY_VARCHAR || - litDefPtr->DataType == QMY_GRAPHIC || - litDefPtr->DataType == QMY_VARGRAPHIC)) - { - // Most of the code is required by the considerable wrangling needed - // to prepare partial keys for use by DB2 - // 1. UTF8 (CCSID 1208) data can be copied across unmodified if it is - // utf8_bin. Otherwise, we need to convert the min and max - // characters into the min and max characters employed - // by the DB2 sort sequence. This is complicated by the fact that - // the character widths are not always equal. - // 2. Likewise, UCS2 (CCSID 13488) data can be copied across unmodified - // if it is ucs2_bin or ucs2_general_ci. Otherwise, we need to - // convert the min and max characters into the min and max characters - // employed by the DB2 sort sequence. - // 3. All other data will use standard iconv conversions. If an - // unconvertible character is encountered, we assume it is the min - // char and fill the remainder of the DB2 key with 0s. This may not - // always be accurate, but it is probably sufficient for range - // estimations. - const char* keyData = minPtr+((curKey.key_part[partsInUse].null_bit)? 1 : 0); - char* db2Data = literalPtr; - uint16 outLen = db2Field.getByteLengthInRecord(); - uint16 inLen; - if (litDefPtr->DataType == QMY_VARCHAR || - litDefPtr->DataType == QMY_VARGRAPHIC) - { - inLen = *(uint8*)keyData + ((*(uint8*)(keyData+1)) << 8); - keyData += 2; - outLen -= sizeof(uint16); - db2Data += sizeof(uint16); - } - else - { - inLen = field->max_display_length(); - } - - size_t convertedBytes = 0; - if (db2Field.getCCSID() == 1208) - { - DBUG_ASSERT(inLen <= outLen); - if (strcmp(field->charset()->name, "utf8_bin")) - { - const char* end = keyData+inLen; - const char* curKey = keyData; - char* curDB2 = db2Data; - uint32 min = field->charset()->min_sort_char; - while ((curKey < end) && (curDB2 < db2Data+outLen-3)) - { - my_wc_t temp; - int len = field->charset()->cset->mb_wc(field->charset(), - &temp, - (const uchar*)curKey, - (const uchar*)end); - if (temp != min) - { - DBUG_ASSERT(len <= 3); - switch (len) - { - case 3: *(curDB2+2) = *(curKey+2); - case 2: *(curDB2+1) = *(curKey+1); - case 1: *(curDB2) = *(curKey); - } - curDB2 += len; - } - else - { - *(curDB2++) = 0xEF; - *(curDB2++) = 0xBF; - *(curDB2++) = 0xBF; - } - curKey += len; - } - convertedBytes = curDB2 - db2Data; - } - else - { - memcpy(db2Data, keyData, inLen); - convertedBytes = inLen; - } - rc = 0; - } - else if (db2Field.getCCSID() == 13488) - { - DBUG_ASSERT(inLen <= outLen); - if (strcmp(field->charset()->name, "ucs2_bin") && - strcmp(field->charset()->name, "ucs2_general_ci")) - { - const char* end = keyData+inLen; - const uint16* curKey = (uint16*)keyData; - uint16* curDB2 = (uint16*)db2Data; - uint16 min = field->charset()->min_sort_char; - while (curKey < (uint16*)end) - { - if (*curKey != min) - *curDB2 = *curKey; - else - *curDB2 = 0xFFFF; - ++curKey; - ++curDB2; - } - } - else - { - memcpy(db2Data, keyData, inLen); - } - convertedBytes = inLen; - rc = 0; - } - else - { - rc = convertFieldChars(toDB2, - field->field_index, - keyData, - db2Data, - inLen, - outLen, - &convertedBytes, - true); - - if (rc == DB2I_ERR_ILL_CHAR) - { - // If an illegal character is encountered, we fill the remainder - // of the key with 0x00. This was implemented as a corollary to - // Bug#45012, though it should probably remain even after that - // bug is fixed. - memset(db2Data+convertedBytes, 0x00, outLen-convertedBytes); - convertedBytes = outLen; - rc = 0; - } - } - - if (!rc && - (litDefPtr->DataType == QMY_VARGRAPHIC || - litDefPtr->DataType == QMY_VARCHAR)) - { - *(uint16*)(db2Data-sizeof(uint16)) = - convertedBytes / (litDefPtr->DataType == QMY_VARGRAPHIC ? 2 : 1); - } - - } - else // Non-character fields - { - rc = convertMySQLtoDB2(field, - db2Field, - literalPtr, - (uchar*)minPtr+((curKey.key_part[partsInUse].null_bit)? 1 : 0)); - } - - if (rc != 0) break; - litDefPtr->Offset = (uint32_t)(literalPtr - literalsPtr); - litDefPtr->Length = db2Field.getByteLengthInRecord(); - literalPtr = literalPtr + litDefPtr->Length; // Bump pointer for next literal - } - /* If there is a max_key value for this field, and if the max_key value is - the same as the min_key value, then the low bound literal can be reused - for the high bound literal. This eliminates the overhead of copying and - converting the same value twice. */ - if (max_key && ((partsInUse + 1) <= maxKeyCnt) && - (memcmp((uchar*)minPtr,(uchar*)maxPtr, - curKey.key_part[partsInUse].store_length)==0 || endOfLiteralPtr)) - reuseLiteral = true; - minPtr += curKey.key_part[partsInUse].store_length; - } - /* - Build the high bound for the key range. - */ - if (max_key == NULL || ((partsInUse + 1) > maxKeyCnt)) - boundsPtr->HiBound.Infinity[0] = QMY_POS_INFINITY; - else - { - if ((curKey.key_part[partsInUse].null_bit) && (char*)maxPtr[0]) - { - if (min_key == NULL) - boundsPtr->HiBound.Infinity[0] = QMY_POS_INFINITY; - else - boundsPtr->HiBound.IsNull[0] = QMY_YES; // select...where x is null - } - else // max_key field is not null - { - if (boundsPtr->LoBound.IsNull[0] == QMY_YES) // select where x < 10 or x is null - { - rc = HA_POS_ERROR; - break; - } - if (!reuseLiteral) - { - if (literalCnt) - litDefPtr = litDefPtr + 1; - literalCnt = literalCnt + 1; - litDefPtr->FieldNbr = field->field_index + 1; - DB2Field& db2Field = db2Table->db2Field(field->field_index); - litDefPtr->DataType = db2Field.getType(); - /* - Convert the literal to DB2 format - */ - if ((field->type() != MYSQL_TYPE_BIT) && // Don't do conversion on BIT data - (field->charset() != &my_charset_bin) && // Don't do conversion on BINARY data - (litDefPtr->DataType == QMY_CHAR || - litDefPtr->DataType == QMY_VARCHAR || - litDefPtr->DataType == QMY_GRAPHIC || - litDefPtr->DataType == QMY_VARGRAPHIC)) - { - // We need to handle char fields in a special way in order to account - // for partial keys. Refer to the note above for a description of the - // basic design. - char* keyData = maxPtr+((curKey.key_part[partsInUse].null_bit)? 1 : 0); - char* db2Data = literalPtr; - uint16 outLen = db2Field.getByteLengthInRecord(); - uint16 inLen; - if (litDefPtr->DataType == QMY_VARCHAR || - litDefPtr->DataType == QMY_VARGRAPHIC) - { - inLen = *(uint8*)keyData + ((*(uint8*)(keyData+1)) << 8); - keyData += 2; - outLen -= sizeof(uint16); - db2Data += sizeof(uint16); - } - else - { - inLen = field->max_display_length(); - } - - size_t convertedBytes; - if (db2Field.getCCSID() == 1208) - { - if (strcmp(field->charset()->name, "utf8_bin")) - { - const char* end = keyData+inLen; - const char* curKey = keyData; - char* curDB2 = db2Data; - uint32 max = field->charset()->max_sort_char; - while (curKey < end && (curDB2 < db2Data+outLen-3)) - { - my_wc_t temp; - int len = field->charset()->cset->mb_wc(field->charset(), &temp, (const uchar*)curKey, (const uchar*)end); - if (temp != max) - { - DBUG_ASSERT(len <= 3); - switch (len) - { - case 3: *(curDB2+2) = *(curKey+2); - case 2: *(curDB2+1) = *(curKey+1); - case 1: *(curDB2) = *(curKey); - } - curDB2 += len; - } - else - { - *(curDB2++) = 0xE4; - *(curDB2++) = 0xB6; - *(curDB2++) = 0xBF; - } - curKey += len; - } - convertedBytes = curDB2 - db2Data; - } - else - { - DBUG_ASSERT(inLen <= outLen); - memcpy(db2Data, keyData, inLen); - convertedBytes = inLen; - } - rc = 0; - } - else if (db2Field.getCCSID() == 13488) - { - if (strcmp(field->charset()->name, "ucs2_bin") && - strcmp(field->charset()->name, "ucs2_general_ci")) - { - char* end = keyData+inLen; - uint16* curKey = (uint16*)keyData; - uint16* curDB2 = (uint16*)db2Data; - uint16 max = field->charset()->max_sort_char; - while (curKey < (uint16*)end) - { - if (*curKey != max) - *curDB2 = *curKey; - else - *curDB2 = 0x4DBF; - ++curKey; - ++curDB2; - } - } - else - { - memcpy(db2Data, keyData, outLen); - } - rc = 0; - } - else - { - size_t substituteChars = 0; - rc = convertFieldChars(toDB2, - field->field_index, - keyData, - db2Data, - inLen, - outLen, - &convertedBytes, - true, - &substituteChars); - - if (rc == DB2I_ERR_ILL_CHAR) - { - // If an illegal character is encountered, we fill the remainder - // of the key with 0xFF. This was implemented to work around - // Bug#45012, though it should probably remain even after that - // bug is fixed. - memset(db2Data+convertedBytes, 0xFF, outLen-convertedBytes); - rc = 0; - } - else if ((substituteChars && - (litDefPtr->DataType == QMY_VARCHAR || - litDefPtr->DataType == QMY_CHAR)) || - strcmp(field->charset()->name, "cp1251_bulgarian_ci") == 0) - { - // When iconv translates the max_sort_char with a substitute - // character, we have no way to know whether this affects - // the sort order of the key. Therefore, to be safe, when - // we know that substitute characters have been used in a - // single-byte string, we traverse the translated key - // in reverse, replacing substitue characters with 0xFF, which - // always sorts with the greatest weight in DB2 sort sequences. - // cp1251_bulgarian_ci is also handled this way because the - // max_sort_char is a control character which does not sort - // equivalently in DB2. - DBUG_ASSERT(inLen == outLen); - char* tmpKey = keyData + inLen - 1; - char* tmpDB2 = db2Data + outLen - 1; - while (*tmpKey == field->charset()->max_sort_char && - *tmpDB2 != 0xFF) - { - *tmpDB2 = 0xFF; - --tmpKey; - --tmpDB2; - } - } - } - - if (!rc && - (litDefPtr->DataType == QMY_VARGRAPHIC || - litDefPtr->DataType == QMY_VARCHAR)) - { - *(uint16*)(db2Data-sizeof(uint16)) = - outLen / (litDefPtr->DataType == QMY_VARGRAPHIC ? 2 : 1); - } - } - else - { - rc = convertMySQLtoDB2(field, - db2Field, - literalPtr, - (uchar*)maxPtr+((curKey.key_part[partsInUse].null_bit)? 1 : 0)); - } - if (rc != 0) break; - litDefPtr->Offset = (uint32_t)(literalPtr - literalsPtr); - litDefPtr->Length = db2Field.getByteLengthInRecord(); - literalPtr = literalPtr + litDefPtr->Length; // Bump pointer for next literal - } - boundsPtr->HiBound.Position = literalCnt; - if (max_key->flag == HA_READ_BEFORE_KEY && !overrideInclusion) - boundsPtr->HiBound.Embodiment[0] = QMY_EXCLUSION; - } - maxPtr += curKey.key_part[partsInUse].store_length; - } - /* - Bump to the next field in the key composite. - */ - - if ((partsInUse+1) < keyCnt) - boundsPtr = boundsPtr + 1; - } - - /* - Call DB2 to estimate the number of rows in the key range. - */ - if (rc == 0) - { - rc = db2i_ileBridge::getBridgeForThread()->recordsInRange((indexHandles[inx] ? indexHandles[inx] : db2Table->indexFile(inx)->getMasterDefnHandle()), - spcPtr, - keyCnt, - literalCnt, - boundsOff, - litDefOff, - literalsOff, - cutoff, - (uint32_t)(literalPtr - (char*)spcPtr), - endByte, - &recCnt, - &rtnCode); - } - /* - Set the row count and return. - Beware that if this method returns a zero row count, MySQL assumes the - result set for the query is zero; never return a zero row count. - */ - if ((rc == 0) && (rtnCode == QMY_SUCCESS || rtnCode == QMY_EARLY_EXIT)) - { - rows = recCnt ? (ha_rows)recCnt : 1; - } - - rows = (rows > 0 ? rows : HA_POS_ERROR); - - setIndexReadEstimate(inx, rows); - - DBUG_PRINT("ha_ibmdb2i::recordsInRange",("Estimate %d rows for key %d", uint32(rows), inx)); - - DBUG_RETURN(rows); -} diff --git a/storage/ibmdb2i/db2i_safeString.h b/storage/ibmdb2i/db2i_safeString.h deleted file mode 100644 index e353316c8fc..00000000000 --- a/storage/ibmdb2i/db2i_safeString.h +++ /dev/null @@ -1,98 +0,0 @@ -/* -Licensed Materials - Property of IBM -DB2 Storage Engine Enablement -Copyright IBM Corporation 2007,2008 -All rights reserved - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - (a) Redistributions of source code must retain this list of conditions, the - copyright notice in section {d} below, and the disclaimer following this - list of conditions. - (b) Redistributions in binary form must reproduce this list of conditions, the - copyright notice in section (d) below, and the disclaimer following this - list of conditions, in the documentation and/or other materials provided - with the distribution. - (c) The name of IBM may not be used to endorse or promote products derived from - this software without specific prior written permission. - (d) The text of the required copyright notice is: - Licensed Materials - Property of IBM - DB2 Storage Engine Enablement - Copyright IBM Corporation 2007,2008 - All rights reserved - -THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - - - -#ifndef DB2I_SAFESTRING_H -#define DB2I_SAFESTRING_H - - -#include -#include - -/** - @class SafeString - - This class was designed to provide safe, but lightweight, concatenation - operations C strings inside pre-allocated buffers. -*/ -class SafeString -{ -public: - SafeString(char* buffer, size_t size) : - allocSize(size), curPos(0), buf(buffer) - { - DBUG_ASSERT(size > 0); - buf[allocSize - 1] = 0xFF; // Set an overflow indicator - } - - char* ptr() { return buf; } - operator char*() { return buf; } - - SafeString& strcat(const char* str) - { - return this->strncat(str, strlen(str)); - } - - SafeString& strcat(char one) - { - if (curPos < allocSize - 2) - { - buf[curPos++] = one; - } - buf[curPos] = 0; - - return *this; - } - - SafeString& strncat(const char* str, size_t len) - { - uint64 amountToCopy = min((allocSize-1) - curPos, len); - memcpy(buf + curPos, str, amountToCopy); - curPos += amountToCopy; - buf[curPos] = 0; - return *this; - } - - bool overflowed() const { return (buf[allocSize - 1] == 0);} - -private: - char* buf; - uint64 curPos; - size_t allocSize; -}; - - -#endif diff --git a/storage/ibmdb2i/db2i_sqlStatementStream.cc b/storage/ibmdb2i/db2i_sqlStatementStream.cc deleted file mode 100644 index 92a8b03fd00..00000000000 --- a/storage/ibmdb2i/db2i_sqlStatementStream.cc +++ /dev/null @@ -1,86 +0,0 @@ -/* -Licensed Materials - Property of IBM -DB2 Storage Engine Enablement -Copyright IBM Corporation 2007,2008 -All rights reserved - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - (a) Redistributions of source code must retain this list of conditions, the - copyright notice in section {d} below, and the disclaimer following this - list of conditions. - (b) Redistributions in binary form must reproduce this list of conditions, the - copyright notice in section (d) below, and the disclaimer following this - list of conditions, in the documentation and/or other materials provided - with the distribution. - (c) The name of IBM may not be used to endorse or promote products derived from - this software without specific prior written permission. - (d) The text of the required copyright notice is: - Licensed Materials - Property of IBM - DB2 Storage Engine Enablement - Copyright IBM Corporation 2007,2008 - All rights reserved - -THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - - -#include "db2i_sqlStatementStream.h" -#include "as400_types.h" - -/** - Add a statement to the statement stream, allocating additional memory as needed. - - @parm stmt The statement text - @parm length The length of the statement text - @parm fileSortSequence The DB2 sort sequence identifier, in EBCDIC - @parm fileSortSequenceLibrary The DB2 sort sequence library, in EBCDIC - - @return Reference to this object -*/ -SqlStatementStream& SqlStatementStream::addStatementInternal(const char* stmt, - uint32 length, - const char* fileSortSequence, - const char* fileSortSequenceLibrary) -{ - uint32 storageNeeded = length + sizeof(StmtHdr_t); - storageNeeded = (storageNeeded + 3) & ~3; // We have to be 4-byte aligned. - if (storageNeeded > storageRemaining()) - { - // We overallocate new storage to reduce number of times reallocation is - // needed. - int newSize = curSize + 2 * storageNeeded; - DBUG_PRINT("SqlStatementStream::addStatementInternal", - ("PERF: Had to realloc! Old size=%d. New size=%d", curSize, newSize)); - char* old_space = block; - char* new_space = (char*)getNewSpace(newSize); - memcpy(new_space, old_space, curSize); - ptr = new_space + (ptr - old_space); - curSize = newSize; - } - - DBUG_ASSERT((address64_t)ptr % 4 == 0); - - memcpy(((StmtHdr_t*)ptr)->SrtSeqNam, - fileSortSequence, - sizeof(((StmtHdr_t*)ptr)->SrtSeqNam)); - memcpy(((StmtHdr_t*)ptr)->SrtSeqSch, - fileSortSequenceLibrary, - sizeof(((StmtHdr_t*)ptr)->SrtSeqSch)); - ((StmtHdr_t*)ptr)->Length = length; - memcpy(ptr + sizeof(StmtHdr_t), stmt, length); - - ptr += storageNeeded; - ++statements; - - return *this; -} diff --git a/storage/ibmdb2i/db2i_sqlStatementStream.h b/storage/ibmdb2i/db2i_sqlStatementStream.h deleted file mode 100644 index 11db41a6c5d..00000000000 --- a/storage/ibmdb2i/db2i_sqlStatementStream.h +++ /dev/null @@ -1,151 +0,0 @@ -/* -Licensed Materials - Property of IBM -DB2 Storage Engine Enablement -Copyright IBM Corporation 2007,2008 -All rights reserved - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - (a) Redistributions of source code must retain this list of conditions, the - copyright notice in section {d} below, and the disclaimer following this - list of conditions. - (b) Redistributions in binary form must reproduce this list of conditions, the - copyright notice in section (d) below, and the disclaimer following this - list of conditions, in the documentation and/or other materials provided - with the distribution. - (c) The name of IBM may not be used to endorse or promote products derived from - this software without specific prior written permission. - (d) The text of the required copyright notice is: - Licensed Materials - Property of IBM - DB2 Storage Engine Enablement - Copyright IBM Corporation 2007,2008 - All rights reserved - -THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - - -#ifndef DB2I_SQLSTATEMENTSTREAM_H -#define DB2I_SQLSTATEMENTSTREAM_H - -#include "db2i_charsetSupport.h" -#include "qmyse.h" - -/** - @class SqlStatementStream - - This class handles building the stream of SQL statements expected by the - QMY_EXECUTE_IMMEDIATE and QMY_PREPARE_OPEN_CURSOR APIs. - Memory allocation is handled internally. -*/ -class SqlStatementStream -{ - public: - /** - ctor to be used when multiple strings may be appended. - */ - SqlStatementStream(uint32 firstStringSize) : statements(0) - { - curSize = firstStringSize + sizeof(StmtHdr_t); - curSize = (curSize + 3) & ~3; - ptr = (char*) getNewSpace(curSize); - if (ptr == NULL) - curSize = 0; - } - - /** - ctor to be used when only a single statement will be executed. - */ - SqlStatementStream(const String& statement) : statements(0), block(NULL), curSize(0), ptr(0) - { - addStatement(statement); - } - - /** - ctor to be used when only a single statement will be executed. - */ - SqlStatementStream(const char* statement) : statements(0), block(NULL), curSize(0), ptr(0) - { - addStatement(statement); - } - - /** - Append an SQL statement, specifiying the DB2 sort sequence under which - the statement should be executed. This is important for CREATE TABLE - and CREATE INDEX statements. - */ - SqlStatementStream& addStatement(const String& append, const char* fileSortSequence, const char* fileSortSequenceLibrary) - { - char sortSeqEbcdic[10]; - char sortSeqLibEbcdic[10]; - - DBUG_ASSERT(strlen(fileSortSequence) <= 10 && - strlen(fileSortSequenceLibrary) <= 10); - memset(sortSeqEbcdic, 0x40, 10); - memset(sortSeqLibEbcdic, 0x40, 10); - convToEbcdic(fileSortSequence, sortSeqEbcdic, strlen(fileSortSequence)); - convToEbcdic(fileSortSequenceLibrary, sortSeqLibEbcdic, strlen(fileSortSequenceLibrary)); - - return addStatementInternal(append.ptr(), append.length(), sortSeqEbcdic, sortSeqLibEbcdic); - } - - /** - Append an SQL statement using default (*HEX) sort sequence. - */ - SqlStatementStream& addStatement(const String& append) - { - const char splatHEX[] = {0x5C, 0xC8, 0xC5, 0xE7, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40}; // *HEX - const char blanks[] = {0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40}; // - - return addStatementInternal(append.ptr(), append.length(), splatHEX, blanks); - } - - /** - Append an SQL statement using default (*HEX) sort sequence. - */ - SqlStatementStream& addStatement(const char* stmt) - { - const char splatHEX[] = {0x5C, 0xC8, 0xC5, 0xE7, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40}; // *HEX - const char blanks[] = {0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40}; // - - return addStatementInternal(stmt, strlen(stmt), splatHEX, blanks); - } - - char* getPtrToData() const { return block; } - uint32 getStatementCount() const { return statements; } - private: - SqlStatementStream& addStatementInternal(const char* stmt, - uint32 length, - const char* fileSortSequence, - const char* fileSortSequenceLibrary); - - uint32 storageRemaining() const - { - return (block == NULL ? 0 : curSize - (ptr - block)); - } - - char* getNewSpace(size_t size) - { - allocBase = (char*)sql_alloc(size + 15); - block = (char*)roundToQuadWordBdy(allocBase); - return block; - } - - uint32 curSize; // The size of the usable memory. - char* allocBase; // The allocated memory (with padding for aligment) - char* block; // The usable memory chunck (aligned for ILE) - char* ptr; // The current position within block. - uint32 statements; // The number of statements that have been appended. -}; - -#endif - diff --git a/storage/ibmdb2i/db2i_validatedPointer.h b/storage/ibmdb2i/db2i_validatedPointer.h deleted file mode 100644 index c4e31d1f11b..00000000000 --- a/storage/ibmdb2i/db2i_validatedPointer.h +++ /dev/null @@ -1,162 +0,0 @@ -/* -Licensed Materials - Property of IBM -DB2 Storage Engine Enablement -Copyright IBM Corporation 2007,2008 -All rights reserved - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - (a) Redistributions of source code must retain this list of conditions, the - copyright notice in section {d} below, and the disclaimer following this - list of conditions. - (b) Redistributions in binary form must reproduce this list of conditions, the - copyright notice in section (d) below, and the disclaimer following this - list of conditions, in the documentation and/or other materials provided - with the distribution. - (c) The name of IBM may not be used to endorse or promote products derived from - this software without specific prior written permission. - (d) The text of the required copyright notice is: - Licensed Materials - Property of IBM - DB2 Storage Engine Enablement - Copyright IBM Corporation 2007,2008 - All rights reserved - -THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - -#ifndef DB2I_VALIDATEDPOINTER_H -#define DB2I_VALIDATEDPOINTER_H - -#include "db2i_ileBridge.h" - -/** - @class ValidatedPointer - @brief Encapsulates a pointer registered for usage by the QMYSE APIs - - @details As a performance optimization, to prevent pointer validation each - time a particular pointer is thunked across to ILE, QMYSE allows us to - "register" a pointer such that it is validated once and then subsequently - referenced on QMYSE APIs by means of a handle value. This class should be - used to manage memory allocation/registration/unregistration of these - pointers. Using the alloc function guarantees that the resulting storage is - 16-byte aligned, a requirement for many pointers passed to QMYSE. -*/ -template -class ValidatedPointer -{ -public: - ValidatedPointer() : address(NULL), handle(NULL) {;} - - ValidatedPointer(size_t size) - { - alloc(size); - } - - ValidatedPointer(T* ptr) - { - assign(ptr); - } - - operator T*() - { - return address; - }; - - operator T*() const - { - return address; - }; - - operator void*() - { - return address; - }; - - operator ILEMemHandle() - { - return handle; - } - - void alloc(size_t size) - { - address = (T*)malloc_aligned(size); - if (address) - db2i_ileBridge::registerPtr(address, &handle); - mallocedHere = 1; - } - - void assign(T* ptr) - { - address = ptr; - db2i_ileBridge::registerPtr((void*)ptr, &handle); - mallocedHere = 0; - } - - void realloc(size_t size) - { - dealloc(); - alloc(size); - } - - void reassign(T* ptr) - { - dealloc(); - assign(ptr); - } - - void dealloc() - { - if (address) - { - db2i_ileBridge::unregisterPtr(handle); - - if (mallocedHere) - free_aligned((void*)address); - } - address = NULL; - handle = 0; - } - - ~ValidatedPointer() - { - dealloc(); - } - -private: - // Disable copy ctor and assignment operator, as these would break - // the registration guarantees provided by the class. - ValidatedPointer& operator= (const ValidatedPointer newVal); - ValidatedPointer(ValidatedPointer& newCopy); - - ILEMemHandle handle; - T* address; - char mallocedHere; -}; - - -/** - @class ValidatedObject - @brief This class allows users to instantiate and register a particular - object in a single step. -*/ -template -class ValidatedObject : public ValidatedPointer -{ - public: - ValidatedObject() : ValidatedPointer(&value) {;} - - T& operator= (const T newVal) { value = newVal; return value; } - - private: - T value; -}; -#endif diff --git a/storage/ibmdb2i/ha_ibmdb2i.cc b/storage/ibmdb2i/ha_ibmdb2i.cc deleted file mode 100644 index 39096be7848..00000000000 --- a/storage/ibmdb2i/ha_ibmdb2i.cc +++ /dev/null @@ -1,3359 +0,0 @@ -/* -Licensed Materials - Property of IBM -DB2 Storage Engine Enablement -Copyright IBM Corporation 2007,2008 -All rights reserved - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - (a) Redistributions of source code must retain this list of conditions, the - copyright notice in section {d} below, and the disclaimer following this - list of conditions. - (b) Redistributions in binary form must reproduce this list of conditions, the - copyright notice in section (d) below, and the disclaimer following this - list of conditions, in the documentation and/or other materials provided - with the distribution. - (c) The name of IBM may not be used to endorse or promote products derived from - this software without specific prior written permission. - (d) The text of the required copyright notice is: - Licensed Materials - Property of IBM - DB2 Storage Engine Enablement - Copyright IBM Corporation 2007,2008 - All rights reserved - -THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - - -/** - @file ha_ibmdb2i.cc - - @brief - The ha_ibmdb2i storage engine provides an interface from MySQL to IBM DB2 for i. - -*/ - -#ifdef USE_PRAGMA_IMPLEMENTATION -#pragma implementation // gcc: Class implementation -#endif - -#include "ha_ibmdb2i.h" -#include "mysql_priv.h" -#include -#include "db2i_ileBridge.h" -#include "db2i_charsetSupport.h" -#include -#include "db2i_safeString.h" - -static const char __NOT_NULL_VALUE_EBCDIC = 0xF0; // '0' -static const char __NULL_VALUE_EBCDIC = 0xF1; // '1' -static const char __DEFAULT_VALUE_EBCDIC = 0xC4; // 'D' -static const char BlankASPName[19] = " "; -static const int DEFAULT_MAX_ROWS_TO_BUFFER = 4096; - -static const char SAVEPOINT_PREFIX[] = {0xD4, 0xE8, 0xE2, 0xD7}; // MYSP (in EBCDIC) - -OSVersion osVersion; - - -// ================================================================ -// ================================================================ -// System variables -static char* ibmdb2i_rdb_name; -static MYSQL_SYSVAR_STR(rdb_name, ibmdb2i_rdb_name, - PLUGIN_VAR_MEMALLOC | PLUGIN_VAR_READONLY, - "The name of the RDB to use", - NULL, - NULL, - BlankASPName); - -static MYSQL_THDVAR_BOOL(transaction_unsafe, - 0, - "Disable support for commitment control", - NULL, - NULL, - FALSE); - -static MYSQL_THDVAR_UINT(lob_alloc_size, - 0, - "Baseline allocation for lob read buffer", - NULL, - NULL, - 2*1024*1024, - 64*1024, - 128*1024*1024, - 1); - -static MYSQL_THDVAR_UINT(max_read_buffer_size, - 0, - "Maximum size of buffers used for read-ahead.", - NULL, - NULL, - 1*1024*1024, - 32*1024, - 16*1024*1024, - 1); - -static MYSQL_THDVAR_UINT(max_write_buffer_size, - 0, - "Maximum size of buffers used for bulk writes.", - NULL, - NULL, - 8*1024*1024, - 32*1024, - 64*1024*1024, - 1); - -static MYSQL_THDVAR_BOOL(compat_opt_time_as_duration, - 0, - "Control how new TIME columns should be defined in DB2. 0=time-of-day (default), 1=duration.", - NULL, - NULL, - FALSE); - -static MYSQL_THDVAR_UINT(compat_opt_year_as_int, - 0, - "Control how new YEAR columns should be defined in DB2. 0=CHAR(4) (default), 1=SMALLINT.", - NULL, - NULL, - 0, - 0, - 1, - 1); - -static MYSQL_THDVAR_UINT(compat_opt_blob_cols, - 0, - "Control how new TEXT and BLOB columns should be defined in DB2. 0=CLOB/BLOB (default), 1=VARCHAR/VARBINARY", - NULL, - NULL, - 0, - 0, - 1, - 1); - -static MYSQL_THDVAR_UINT(compat_opt_allow_zero_date_vals, - 0, - "Allow substitute values to be used when storing a column with a 0000-00-00 date component. 0=No substitution (default), 1=Substitute '0001-01-01'", - NULL, - NULL, - 0, - 0, - 1, - 1); - -static MYSQL_THDVAR_BOOL(propagate_default_col_vals, - 0, - "Should DEFAULT column values be propagated to the DB2 table definition.", - NULL, - NULL, - TRUE); - -static my_bool ibmdb2i_assume_exclusive_use; -static MYSQL_SYSVAR_BOOL(assume_exclusive_use, ibmdb2i_assume_exclusive_use, - 0, - "Can MySQL assume that this process is the only one modifying the DB2 tables. ", - NULL, - NULL, - FALSE); - -static MYSQL_THDVAR_BOOL(async_enabled, - 0, - "Should reads be done asynchronously when possible", - NULL, - NULL, - TRUE); - -static MYSQL_THDVAR_UINT(create_index_option, - 0, - "Control whether additional indexes are created. 0=No (default), 1=Create additional *HEX-based index", - NULL, - NULL, - 0, - 0, - 1, - 1); - -/* static MYSQL_THDVAR_UINT(discovery_mode, - 0, - "Unsupported", - NULL, - NULL, - 0, - 0, - 1, - 1); */ - -static uint32 ibmdb2i_system_trace; -static MYSQL_SYSVAR_UINT(system_trace_level, ibmdb2i_system_trace, - 0, - "Set system tracing level", - NULL, - NULL, - 0, - 0, - 63, - 1); - - -inline uint8 ha_ibmdb2i::getCommitLevel(THD* thd) -{ - if (!THDVAR(thd, transaction_unsafe)) - { - switch (thd_tx_isolation(thd)) - { - case ISO_READ_UNCOMMITTED: - return (accessIntent == QMY_READ_ONLY ? QMY_READ_UNCOMMITTED : QMY_REPEATABLE_READ); - case ISO_READ_COMMITTED: - return (accessIntent == QMY_READ_ONLY ? QMY_READ_COMMITTED : QMY_REPEATABLE_READ); - case ISO_REPEATABLE_READ: - return QMY_REPEATABLE_READ; - case ISO_SERIALIZABLE: - return QMY_SERIALIZABLE; - } - } - - return QMY_NONE; -} - -inline uint8 ha_ibmdb2i::getCommitLevel() -{ - return getCommitLevel(ha_thd()); -} - -//===================================================================== - -static handler *ibmdb2i_create_handler(handlerton *hton, - TABLE_SHARE *table, - MEM_ROOT *mem_root); -static void ibmdb2i_drop_database(handlerton *hton, char* path); -static int ibmdb2i_savepoint_set(handlerton *hton, THD* thd, void *sv); -static int ibmdb2i_savepoint_rollback(handlerton *hton, THD* thd, void *sv); -static int ibmdb2i_savepoint_release(handlerton *hton, THD* thd, void *sv); -static uint ibmdb2i_alter_table_flags(uint flags); - -handlerton *ibmdb2i_hton; -static bool was_ILE_inited; - -/* Tracks the number of open tables */ -static HASH ibmdb2i_open_tables; - -/* Mutex used to synchronize initialization of the hash */ -static pthread_mutex_t ibmdb2i_mutex; - - -/** - Create hash key for tracking open tables. -*/ - -static uchar* ibmdb2i_get_key(IBMDB2I_SHARE *share,size_t *length, - bool not_used __attribute__((unused))) -{ - *length=share->table_name_length; - return (uchar*) share->table_name; -} - - -int ibmdb2i_close_connection(handlerton* hton, THD *thd) -{ - DBUG_PRINT("ha_ibmdb2i::close_connection", ("Closing %d", thd->thread_id)); - db2i_ileBridge::getBridgeForThread(thd)->closeConnection(thd->thread_id); - db2i_ileBridge::destroyBridgeForThread(thd); - - return 0; -} - - -static int ibmdb2i_init_func(void *p) -{ - DBUG_ENTER("ibmdb2i_init_func"); - - utsname tempName; - uname(&tempName); - osVersion.v = atoi(tempName.version); - osVersion.r = atoi(tempName.release); - - was_ILE_inited = false; - ibmdb2i_hton= (handlerton *)p; - VOID(pthread_mutex_init(&ibmdb2i_mutex,MY_MUTEX_INIT_FAST)); - (void) hash_init(&ibmdb2i_open_tables,table_alias_charset,32,0,0, - (hash_get_key) ibmdb2i_get_key,0,0); - - ibmdb2i_hton->state= SHOW_OPTION_YES; - ibmdb2i_hton->create= ibmdb2i_create_handler; - ibmdb2i_hton->drop_database= ibmdb2i_drop_database; - ibmdb2i_hton->commit= ha_ibmdb2i::doCommit; - ibmdb2i_hton->rollback= ha_ibmdb2i::doRollback; - ibmdb2i_hton->savepoint_offset= 0; - ibmdb2i_hton->savepoint_set= ibmdb2i_savepoint_set; - ibmdb2i_hton->savepoint_rollback= ibmdb2i_savepoint_rollback; - ibmdb2i_hton->savepoint_release= ibmdb2i_savepoint_release; - ibmdb2i_hton->alter_table_flags=ibmdb2i_alter_table_flags; - ibmdb2i_hton->close_connection=ibmdb2i_close_connection; - - int rc; - - rc = initCharsetSupport(); - - if (!rc) - rc = db2i_ileBridge::setup(); - - if (!rc) - { - int nameLen = strlen(ibmdb2i_rdb_name); - for (int i = 0; i < nameLen; ++i) - { - ibmdb2i_rdb_name[i] = my_toupper(system_charset_info, (uchar)ibmdb2i_rdb_name[i]); - } - - rc = db2i_ileBridge::initILE(ibmdb2i_rdb_name, (uint16*)(((char*)&ibmdb2i_system_trace)+2)); - if (rc == 0) - { - was_ILE_inited = true; - } - } - - DBUG_RETURN(rc); -} - - -static int ibmdb2i_done_func(void *p) -{ - int error= 0; - DBUG_ENTER("ibmdb2i_done_func"); - - if (ibmdb2i_open_tables.records) - error= 1; - - if (was_ILE_inited) - db2i_ileBridge::exitILE(); - - db2i_ileBridge::takedown(); - - doneCharsetSupport(); - - hash_free(&ibmdb2i_open_tables); - pthread_mutex_destroy(&ibmdb2i_mutex); - - DBUG_RETURN(0); -} - - -IBMDB2I_SHARE *ha_ibmdb2i::get_share(const char *table_name, TABLE *table) -{ - IBMDB2I_SHARE *share; - uint length; - char *tmp_name; - - pthread_mutex_lock(&ibmdb2i_mutex); - length=(uint) strlen(table_name); - - if (!(share=(IBMDB2I_SHARE*) hash_search(&ibmdb2i_open_tables, - (uchar*)table_name, - length))) - { - if (!(share=(IBMDB2I_SHARE *) - my_multi_malloc(MYF(MY_WME | MY_ZEROFILL), - &share, sizeof(*share), - &tmp_name, length+1, - NullS))) - { - pthread_mutex_unlock(&ibmdb2i_mutex); - return NULL; - } - - share->use_count=0; - share->table_name_length=length; - share->table_name=tmp_name; - strmov(share->table_name,table_name); - if (my_hash_insert(&ibmdb2i_open_tables, (uchar*) share)) - goto error; - thr_lock_init(&share->lock); - pthread_mutexattr_t mutexattr = MY_MUTEX_INIT_FAST; - pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&share->mutex, &mutexattr); - - share->db2Table = new db2i_table(table->s, table_name); - int32 rc = share->db2Table->initDB2Objects(table_name); - - if (rc) - { - delete share->db2Table; - hash_delete(&ibmdb2i_open_tables, (uchar*) share); - thr_lock_delete(&share->lock); - my_errno = rc; - goto error; - } - - memset(&share->cachedStats, 0, sizeof(share->cachedStats)); - } - share->use_count++; - pthread_mutex_unlock(&ibmdb2i_mutex); - - db2Table = share->db2Table; - - return share; - -error: - pthread_mutex_destroy(&share->mutex); - my_free((uchar*) share, MYF(0)); - pthread_mutex_unlock(&ibmdb2i_mutex); - - return NULL; -} - - - -int ha_ibmdb2i::free_share(IBMDB2I_SHARE *share) -{ - pthread_mutex_lock(&ibmdb2i_mutex); - if (!--share->use_count) - { - delete share->db2Table; - db2Table = NULL; - - hash_delete(&ibmdb2i_open_tables, (uchar*) share); - thr_lock_delete(&share->lock); - pthread_mutex_destroy(&share->mutex); - my_free(share, MYF(0)); - pthread_mutex_unlock(&ibmdb2i_mutex); - return 1; - } - pthread_mutex_unlock(&ibmdb2i_mutex); - - return 0; -} - -static handler* ibmdb2i_create_handler(handlerton *hton, - TABLE_SHARE *table, - MEM_ROOT *mem_root) -{ - return new (mem_root) ha_ibmdb2i(hton, table); -} - -static void ibmdb2i_drop_database(handlerton *hton, char* path) -{ - DBUG_ENTER("ha_ibmdb2i::ibmdb2i_drop_database"); - int rc = 0; - char queryBuffer[200]; - String query(queryBuffer, sizeof(queryBuffer), system_charset_info); - query.length(0); - query.append(STRING_WITH_LEN(" DROP SCHEMA \"")); - query.append(path+2, strchr(path+2, '/')-(path+2)); - query.append('"'); - - SqlStatementStream sqlStream(query); - - rc = db2i_ileBridge::getBridgeForThread()->execSQL(sqlStream.getPtrToData(), - sqlStream.getStatementCount(), - QMY_NONE, - FALSE, - TRUE); - DBUG_VOID_RETURN; -} - -inline static void genSavepointName(const void* sv, char* out) -{ - *(uint32*)out = *(uint32*)SAVEPOINT_PREFIX; - DBUG_ASSERT(sizeof(SAVEPOINT_PREFIX) == 4); - out += sizeof(SAVEPOINT_PREFIX); - - longlong2str((longlong)sv, out, 10); - while (*out) - { - out += 0xF0; - ++out; - } -} - - -/********************************************************************* -Sets a transaction savepoint. */ -static int ibmdb2i_savepoint_set(handlerton* hton, THD* thd, void* sv) -{ - DBUG_ENTER("ibmdb2i_savepoint_set"); - int rc = 0; - if (!THDVAR(thd ,transaction_unsafe)) - { - char name[64]; - genSavepointName(sv, name); - DBUG_PRINT("ibmdb2i_savepoint_set",("Setting %s", name)); - rc = ha_ibmdb2i::doSavepointSet(thd, name); - } - DBUG_RETURN(rc); -} - - -/********************************************************************* -Rollback a savepoint. */ -static int ibmdb2i_savepoint_rollback(handlerton* hton, THD* thd, void* sv) -{ - DBUG_ENTER("ibmdb2i_savepoint_rollback"); - int rc = 0; - if (!THDVAR(thd,transaction_unsafe)) - { - char name[64]; - genSavepointName(sv, name); - DBUG_PRINT("ibmdb2i_savepoint_rollback",("Rolling back %s", name)); - rc = ha_ibmdb2i::doSavepointRollback(thd, name); - } - DBUG_RETURN(rc); -} - - -/********************************************************************* -Release a savepoint. */ -static int ibmdb2i_savepoint_release(handlerton* hton, THD* thd, void* sv) -{ - DBUG_ENTER("ibmdb2i_savepoint_release"); - int rc = 0; - if (!THDVAR(thd,transaction_unsafe)) - { - char name[64]; - genSavepointName(sv, name); - DBUG_PRINT("ibmdb2i_savepoint_release",("Releasing %s", name)); - rc = ha_ibmdb2i::doSavepointRelease(thd, name); - } - DBUG_RETURN(rc); -} - -/* Thse flags allow for the online add and drop of an index via the CREATE INDEX, - DROP INDEX, and ALTER TABLE statements. These flags indicate that MySQL is not - required to lock the table before calling the storage engine to add or drop the - index(s). */ -static uint ibmdb2i_alter_table_flags(uint flags) -{ - return (HA_ONLINE_ADD_INDEX | HA_ONLINE_DROP_INDEX | - HA_ONLINE_ADD_UNIQUE_INDEX | HA_ONLINE_DROP_UNIQUE_INDEX | - HA_ONLINE_ADD_PK_INDEX | HA_ONLINE_DROP_PK_INDEX); -} - -ha_ibmdb2i::ha_ibmdb2i(handlerton *hton, TABLE_SHARE *table_arg) - :share(NULL), handler(hton, table_arg), - activeHandle(0), dataHandle(0), - activeReadBuf(NULL), activeWriteBuf(NULL), - blobReadBuffers(NULL), accessIntent(QMY_UPDATABLE), currentRRN(0), - releaseRowNeeded(FALSE), - indexReadSizeEstimates(NULL), - outstanding_start_bulk_insert(false), - last_rnd_init_rc(0), - last_index_init_rc(0), - last_start_bulk_insert_rc(0), - autoIncLockAcquired(false), - got_auto_inc_values(false), - next_identity_value(0), - indexHandles(0), - returnDupKeysImmediately(false), - onDupUpdate(false), - blobWriteBuffers(NULL), - forceSingleRowRead(false) - { - activeReferences = 0; - ref_length = sizeof(currentRRN); - if (table_share && table_share->keys > 0) - { - indexHandles = (FILE_HANDLE*)my_malloc(table_share->keys * sizeof(FILE_HANDLE), MYF(MY_WME | MY_ZEROFILL)); - } - clear_alloc_root(&conversionBufferMemroot); - } - - -ha_ibmdb2i::~ha_ibmdb2i() -{ - DBUG_ASSERT(activeReferences == 0 || outstanding_start_bulk_insert); - - if (indexHandles) - my_free(indexHandles, MYF(0)); - if (indexReadSizeEstimates) - my_free(indexReadSizeEstimates, MYF(0)); - - cleanupBuffers(); -} - - -static const char *ha_ibmdb2i_exts[] = { - FID_EXT, - NullS -}; - -const char **ha_ibmdb2i::bas_ext() const -{ - return ha_ibmdb2i_exts; -} - - -int ha_ibmdb2i::open(const char *name, int mode, uint test_if_locked) -{ - DBUG_ENTER("ha_ibmdb2i::open"); - - initBridge(); - - dataHandle = bridge()->findAndRemovePreservedHandle(name, &share); - - if (share) - db2Table = share->db2Table; - - if (!share && (!(share = get_share(name, table)))) - DBUG_RETURN(my_errno); - thr_lock_data_init(&share->lock,&lock,NULL); - - info(HA_STATUS_NO_LOCK | HA_STATUS_CONST | HA_STATUS_VARIABLE); - - - DBUG_RETURN(0); -} - - - - -int ha_ibmdb2i::close(void) -{ - DBUG_ENTER("ha_ibmdb2i::close"); - int32 rc = 0; - bool preserveShare = false; - - db2i_ileBridge* bridge = db2i_ileBridge::getBridgeForThread(); - - if (dataHandle) - { - if (bridge->expectErrors(QMY_ERR_PEND_LOCKS)->deallocateFile(dataHandle, FALSE) == QMY_ERR_PEND_LOCKS) - { - bridge->preserveHandle(share->table_name, dataHandle, share); - preserveShare = true; - } - dataHandle = 0; - } - - for (int idx = 0; idx < table_share->keys; ++idx) - { - if (indexHandles[idx] != 0) - { - bridge->deallocateFile(indexHandles[idx], FALSE); - } - } - - cleanupBuffers(); - - if (!preserveShare) - { - if (free_share(share)) - share = NULL; - } - - DBUG_RETURN(rc); -} - - - -int ha_ibmdb2i::write_row(uchar * buf) -{ - - DBUG_ENTER("ha_ibmdb2i::write_row"); - - if (last_start_bulk_insert_rc) - DBUG_RETURN( last_start_bulk_insert_rc ); - - ha_statistic_increment(&SSV::ha_write_count); - int rc = 0; - - bool fileHandleNeedsRelease = false; - - if (!activeHandle) - { - rc = useDataFile(); - if (rc) DBUG_RETURN(rc); - fileHandleNeedsRelease = true; - } - - if (!outstanding_start_bulk_insert) - rc = prepWriteBuffer(1, getFileForActiveHandle()); - - if (!rc) - { - if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT) - table->timestamp_field->set_time(); - - char* writeBuffer = activeWriteBuf->addRow(); - rc = prepareRowForWrite(writeBuffer, - writeBuffer+activeWriteBuf->getRowNullOffset(), - true); - if (rc == 0) - { - // If we are doing block inserts, if the MI is supposed to generate an auto_increment - // (i.e. identity column) value for this record, and if this is not the first record in - // the block, then store the value (that the MI will generate for the identity column) - // into the MySQL write buffer. We can predetermine the value because the file is locked. - - if ((autoIncLockAcquired) && (default_identity_value) && (got_auto_inc_values)) - { - if (unlikely((next_identity_value - 1) == - maxValueForField(table->next_number_field))) - { - rc = QMY_ERR_MAXVALUE; - } - else - { - rc = table->next_number_field->store((longlong) next_identity_value, TRUE); - next_identity_value = next_identity_value + incrementByValue; - } - } - // If the buffer is full, or if we locked the file and this is the first or last row - // of a blocked insert, then flush the buffer. - if (!rc && (activeWriteBuf->endOfBuffer()) || - ((autoIncLockAcquired) && - ((!got_auto_inc_values))) || - (returnDupKeysImmediately)) - rc = flushWrite(activeHandle, buf); - } - else - activeWriteBuf->deleteRow(); - } - - if (fileHandleNeedsRelease) - releaseActiveHandle(); - - DBUG_RETURN(rc); -} - -/** - @brief - Helper function used by write_row and update_row to prepare the MySQL - row for insertion into DB2. -*/ -int ha_ibmdb2i::prepareRowForWrite(char* data, char* nulls, bool honorIdentCols) -{ - int rc = 0; - - // set null map all to non nulls - memset(nulls,__NOT_NULL_VALUE_EBCDIC, table->s->fields); - default_identity_value = FALSE; - - ulong sql_mode = ha_thd()->variables.sql_mode; - - my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set); - for (Field **field = table->field; *field && !rc; ++field) - { - int fieldIndex = (*field)->field_index; - if ((*field)->Field::is_null()) - { - nulls[fieldIndex] = __NULL_VALUE_EBCDIC; - } - if (honorIdentCols && ((*field)->flags & AUTO_INCREMENT_FLAG) && - *field == table->next_number_field) -// && ((!autoIncLockAcquired) || (!got_auto_inc_values))) - { - if (sql_mode & MODE_NO_AUTO_VALUE_ON_ZERO) - { - if (!table->auto_increment_field_not_null) - { - nulls[fieldIndex] = __DEFAULT_VALUE_EBCDIC; - default_identity_value = TRUE; - } - } - else if ((*field)->val_int() == 0) - { - nulls[fieldIndex] = __DEFAULT_VALUE_EBCDIC; - default_identity_value = TRUE; - } - } - - DB2Field& db2Field = db2Table->db2Field(fieldIndex); - if (nulls[fieldIndex] == __NOT_NULL_VALUE_EBCDIC || - db2Field.isBlob()) - { - rc = convertMySQLtoDB2(*field, db2Field, data + db2Field.getBufferOffset()); - } - } - - if (!rc && db2Table->hasBlobs()) - rc = db2i_ileBridge::getBridgeForThread()->objectOverride(activeHandle, - activeWriteBuf->ptr()); - - dbug_tmp_restore_column_map(table->read_set, old_map); - - return rc; -} - - - -int ha_ibmdb2i::update_row(const uchar * old_data, uchar * new_data) -{ - DBUG_ENTER("ha_ibmdb2i::update_row"); - ha_statistic_increment(&SSV::ha_update_count); - int rc; - - bool fileHandleNeedsRelease = false; - - if (!activeHandle) - { - rc = useFileByHandle(QMY_UPDATABLE, rrnAssocHandle); - if (rc) DBUG_RETURN(rc); - fileHandleNeedsRelease = true; - } - - if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) - table->timestamp_field->set_time(); - - char* writeBuf = activeWriteBuf->addRow(); - rc = prepareRowForWrite(writeBuf, - writeBuf+activeWriteBuf->getRowNullOffset(), - onDupUpdate); - - char* lastDupKeyNamePtr = NULL; - uint32 lastDupKeyNameLen = 0; - - if (!rc) - { - rc = db2i_ileBridge::getBridgeForThread()->updateRow(activeHandle, - currentRRN, - activeWriteBuf->ptr(), - &lastDupKeyRRN, - &lastDupKeyNamePtr, - &lastDupKeyNameLen); - } - - if (lastDupKeyNameLen) - { - lastDupKeyID = getKeyFromName(lastDupKeyNamePtr, lastDupKeyNameLen); - rrnAssocHandle = activeHandle; - } - - if (fileHandleNeedsRelease) - releaseActiveHandle(); - - activeWriteBuf->resetAfterWrite(); - - DBUG_RETURN(rc); -} - - -int ha_ibmdb2i::delete_row(const uchar * buf) -{ - DBUG_ENTER("ha_ibmdb2i::delete_row"); - ha_statistic_increment(&SSV::ha_delete_count); - - bool needReleaseFile = false; - int rc = 0; - - if (!activeHandle) // In some circumstances, MySQL comes here after - { // closing the active handle. We need to re-open. - rc = useFileByHandle(QMY_UPDATABLE, rrnAssocHandle); - needReleaseFile = true; - } - - if (likely(!rc)) - { - rc = db2i_ileBridge::getBridgeForThread()->deleteRow(activeHandle, - currentRRN); - invalidateCachedStats(); - if (needReleaseFile) - releaseActiveHandle(); - } - - DBUG_RETURN(rc); -} - - - -int ha_ibmdb2i::index_init(uint idx, bool sorted) -{ - DBUG_ENTER("ha_ibmdb2i::index_init"); - - int& rc = last_index_init_rc; - rc = 0; - - invalidDataFound=false; - tweakReadSet(); - - active_index=idx; - - rc = useIndexFile(idx); - - if (!rc) - { -// THD* thd = ha_thd(); -// if (accessIntent == QMY_UPDATABLE && -// thd_tx_isolation(thd) == ISO_REPEATABLE_READ && -// !THDVAR(thd, transaction_unsafe)) -// { -// readAccessIntent = QMY_READ_ONLY; -// } -// else -// { - readAccessIntent = accessIntent; -// } - - if (!rc && accessIntent != QMY_READ_ONLY) - rc = prepWriteBuffer(1, db2Table->indexFile(idx)); - - if (rc) - releaseIndexFile(idx); - } - - rrnAssocHandle= 0; - - DBUG_RETURN(rc); -} - - - -int ha_ibmdb2i::index_read(uchar * buf, const uchar * key, - uint key_len, - enum ha_rkey_function find_flag) -{ - DBUG_ENTER("ha_ibmdb2i::index_read"); - - if (unlikely(last_index_init_rc)) DBUG_RETURN(last_index_init_rc); - - int rc; - - ha_rows estimatedRows = getIndexReadEstimate(active_index); - rc = prepReadBuffer(estimatedRows, db2Table->indexFile(active_index), readAccessIntent); - if (unlikely(rc)) DBUG_RETURN(rc); - - DBUG_ASSERT(activeReadBuf); - - keyBuf.allocBuf(activeReadBuf->getRowLength(), - activeReadBuf->getRowNullOffset(), - activeReadBuf->getRowLength()); - keyBuf.zeroBuf(); - - char* db2KeyBufPtr = keyBuf.ptr(); - char* nullKeyMap = db2KeyBufPtr + activeReadBuf->getRowNullOffset(); - - const uchar* keyBegin = key; - int partsInUse; - - KEY& curKey = table->key_info[active_index]; - - for (partsInUse = 0; partsInUse < curKey.key_parts, key - keyBegin < key_len; ++partsInUse) - { - Field* field = curKey.key_part[partsInUse].field; - if ((curKey.key_part[partsInUse].null_bit) && - (char*)key[0]) - { - if (field->flags & AUTO_INCREMENT_FLAG) - { - table->status = STATUS_NOT_FOUND; - DBUG_RETURN(HA_ERR_END_OF_FILE); - } - else - { - nullKeyMap[partsInUse] = __NULL_VALUE_EBCDIC; - } - } - else - { - nullKeyMap[partsInUse] = __NOT_NULL_VALUE_EBCDIC; - convertMySQLtoDB2(field, - db2Table->db2Field(field->field_index), - db2KeyBufPtr, - (uchar*)key+((curKey.key_part[partsInUse].null_bit)? 1 : 0) ); // + (curKey.key_parts+7) / 8); - } - - db2KeyBufPtr += db2Table->db2Field(field->field_index).getByteLengthInRecord(); - key += curKey.key_part[partsInUse].store_length; - } - - keyLen = db2KeyBufPtr - (char*)keyBuf.ptr(); - - DBUG_PRINT("ha_ibmdb2i::index_read", ("find_flag: %d", find_flag)); - - char readDirection = QMY_NEXT; - - switch (find_flag) - { - case HA_READ_AFTER_KEY: - doInitialRead(QMY_AFTER_EQUAL, estimatedRows, - keyBuf.ptr(), keyLen, partsInUse); - break; - case HA_READ_BEFORE_KEY: - doInitialRead(QMY_BEFORE_EQUAL, estimatedRows, - keyBuf.ptr(), keyLen, partsInUse); - break; - case HA_READ_KEY_OR_NEXT: - doInitialRead(QMY_AFTER_OR_EQUAL, estimatedRows, - keyBuf.ptr(), keyLen, partsInUse); - break; - case HA_READ_KEY_OR_PREV: - DBUG_ASSERT(0); // This function is unused - doInitialRead(QMY_BEFORE_OR_EQUAL, estimatedRows, - keyBuf.ptr(), keyLen, partsInUse); - break; - case HA_READ_PREFIX_LAST_OR_PREV: - doInitialRead(QMY_LAST_PREVIOUS, estimatedRows, - keyBuf.ptr(), keyLen, partsInUse); - readDirection = QMY_PREVIOUS; - break; - case HA_READ_PREFIX_LAST: - doInitialRead(QMY_PREFIX_LAST, estimatedRows, - keyBuf.ptr(), keyLen, partsInUse); - readDirection = QMY_PREVIOUS; - break; - case HA_READ_KEY_EXACT: - doInitialRead(QMY_EQUAL, estimatedRows, keyBuf.ptr(), keyLen, partsInUse); - break; - default: - DBUG_ASSERT(0); - return HA_ERR_GENERIC; - break; - } - - ha_statistic_increment(&SSV::ha_read_key_count); - rc = readFromBuffer(buf, readDirection); - - table->status= (rc ? STATUS_NOT_FOUND: 0); - DBUG_RETURN(rc); -} - - -int ha_ibmdb2i::index_next(uchar * buf) -{ - DBUG_ENTER("ha_ibmdb2i::index_next"); - ha_statistic_increment(&SSV::ha_read_next_count); - - int rc = readFromBuffer(buf, QMY_NEXT); - - table->status= (rc ? STATUS_NOT_FOUND: 0); - DBUG_RETURN(rc); -} - - -int ha_ibmdb2i::index_next_same(uchar *buf, const uchar *key, uint keylen) -{ - DBUG_ENTER("ha_ibmdb2i::index_next_same"); - ha_statistic_increment(&SSV::ha_read_next_count); - - int rc = readFromBuffer(buf, QMY_NEXT_EQUAL); - - if (rc == HA_ERR_KEY_NOT_FOUND) - { - rc = HA_ERR_END_OF_FILE; - } - - table->status= (rc ? STATUS_NOT_FOUND: 0); - DBUG_RETURN(rc); -} - -int ha_ibmdb2i::index_read_last(uchar * buf, const uchar * key, uint key_len) -{ - DBUG_ENTER("ha_ibmdb2i::index_read_last"); - DBUG_RETURN(index_read(buf, key, key_len, HA_READ_PREFIX_LAST)); -} - - - -int ha_ibmdb2i::index_prev(uchar * buf) -{ - DBUG_ENTER("ha_ibmdb2i::index_prev"); - ha_statistic_increment(&SSV::ha_read_prev_count); - - int rc = readFromBuffer(buf, QMY_PREVIOUS); - - table->status= (rc ? STATUS_NOT_FOUND: 0); - DBUG_RETURN(rc); -} - - -int ha_ibmdb2i::index_first(uchar * buf) -{ - DBUG_ENTER("ha_ibmdb2i::index_first"); - - if (unlikely(last_index_init_rc)) DBUG_RETURN(last_index_init_rc); - - int rc = prepReadBuffer(DEFAULT_MAX_ROWS_TO_BUFFER, - db2Table->indexFile(active_index), - readAccessIntent); - - if (rc == 0) - { - doInitialRead(QMY_FIRST, DEFAULT_MAX_ROWS_TO_BUFFER); - ha_statistic_increment(&SSV::ha_read_first_count); - rc = readFromBuffer(buf, QMY_NEXT); - } - - table->status= (rc ? STATUS_NOT_FOUND: 0); - DBUG_RETURN(rc); -} - - -int ha_ibmdb2i::index_last(uchar * buf) -{ - DBUG_ENTER("ha_ibmdb2i::index_last"); - - if (unlikely(last_index_init_rc)) DBUG_RETURN(last_index_init_rc); - - int rc = prepReadBuffer(DEFAULT_MAX_ROWS_TO_BUFFER, - db2Table->indexFile(active_index), - readAccessIntent); - - if (rc == 0) - { - doInitialRead(QMY_LAST, DEFAULT_MAX_ROWS_TO_BUFFER); - ha_statistic_increment(&SSV::ha_read_last_count); - rc = readFromBuffer(buf, QMY_PREVIOUS); - } - - table->status= (rc ? STATUS_NOT_FOUND: 0); - DBUG_RETURN(rc); -} - - -int ha_ibmdb2i::rnd_init(bool scan) -{ - DBUG_ENTER("ha_ibmdb2i::rnd_init"); - - int& rc = last_rnd_init_rc; - rc = 0; - - tweakReadSet(); - invalidDataFound=false; - - uint32 rowsToBlockOnRead; - - if (!scan) - { - rowsToBlockOnRead = 1; - } - else - { - rowsToBlockOnRead = DEFAULT_MAX_ROWS_TO_BUFFER; - } - - rc = useDataFile(); - - if (!rc) - { -// THD* thd = ha_thd(); -// if (accessIntent == QMY_UPDATABLE && -// thd_tx_isolation(thd) == ISO_REPEATABLE_READ && -// !THDVAR(thd, transaction_unsafe)) -// { -// readAccessIntent = QMY_READ_ONLY; -// } -// else -// { - readAccessIntent = accessIntent; -// } - - rc = prepReadBuffer(rowsToBlockOnRead, db2Table->dataFile(), readAccessIntent); - - if (!rc && accessIntent != QMY_READ_ONLY) - rc = prepWriteBuffer(1, db2Table->dataFile()); - - if (!rc && scan) - doInitialRead(QMY_FIRST, rowsToBlockOnRead); - - if (rc) - releaseDataFile(); - } - - rrnAssocHandle= 0; - - DBUG_RETURN(0); // MySQL sometimes does not check the return code, causing - // an assert in ha_rnd_end later on if we return a non-zero - // value here. -} - -int ha_ibmdb2i::rnd_end() -{ - DBUG_ENTER("ha_ibmdb2i::rnd_end"); - - warnIfInvalidData(); - if (likely(activeReadBuf)) - activeReadBuf->endRead(); - if (last_rnd_init_rc == 0) - releaseActiveHandle(); - last_rnd_init_rc = 0; - DBUG_RETURN(0); -} - - -int32 ha_ibmdb2i::mungeDB2row(uchar* record, const char* dataPtr, const char* nullMapPtr, bool skipLOBs) -{ - DBUG_ASSERT(dataPtr); - - my_bitmap_map *old_write_map= dbug_tmp_use_all_columns(table, table->write_set); - my_bitmap_map *old_read_map; - - if (unlikely(readAllColumns)) - old_read_map = tmp_use_all_columns(table, table->read_set); - - resetCharacterConversionBuffers(); - - my_ptrdiff_t old_ptr= (my_ptrdiff_t) (record - table->record[0]); - int fieldIndex = 0; - for (Field **field = table->field; *field; ++field, ++fieldIndex) - { - if (unlikely(old_ptr)) - (*field)->move_field_offset(old_ptr); - if (nullMapPtr[fieldIndex] == __NULL_VALUE_EBCDIC || - (!bitmap_is_set(table->read_set, fieldIndex)) || - (skipLOBs && db2Table->db2Field(fieldIndex).isBlob())) - { - (*field)->set_null(); - } - else - { - (*field)->set_notnull(); - convertDB2toMySQL(db2Table->db2Field(fieldIndex), *field, dataPtr); - } - if (unlikely(old_ptr)) - (*field)->move_field_offset(-old_ptr); - - } - - if (unlikely(readAllColumns)) - tmp_restore_column_map(table->read_set, old_read_map); - dbug_tmp_restore_column_map(table->write_set, old_write_map); - - return 0; -} - - -int ha_ibmdb2i::rnd_next(uchar *buf) -{ - DBUG_ENTER("ha_ibmdb2i::rnd_next"); - - if (unlikely(last_rnd_init_rc)) DBUG_RETURN(last_rnd_init_rc); - ha_statistic_increment(&SSV::ha_read_rnd_next_count); - - int rc; - - rc = readFromBuffer(buf, QMY_NEXT); - - table->status= (rc ? STATUS_NOT_FOUND: 0); - DBUG_RETURN(rc); -} - - -void ha_ibmdb2i::position(const uchar *record) -{ - DBUG_ENTER("ha_ibmdb2i::position"); - my_store_ptr(ref, ref_length, currentRRN); - DBUG_VOID_RETURN; -} - - -int ha_ibmdb2i::rnd_pos(uchar * buf, uchar *pos) -{ - DBUG_ENTER("ha_ibmdb2i::rnd_pos"); - if (unlikely(last_rnd_init_rc)) DBUG_RETURN( last_rnd_init_rc); - ha_statistic_increment(&SSV::ha_read_rnd_count); - - currentRRN = my_get_ptr(pos, ref_length); - - tweakReadSet(); - - int rc = 0; - - if (rrnAssocHandle && - (activeHandle != rrnAssocHandle)) - { - if (activeHandle) releaseActiveHandle(); - rc = useFileByHandle(QMY_UPDATABLE, rrnAssocHandle); - } - - if (likely(rc == 0)) - { - rc = prepReadBuffer(1, getFileForActiveHandle(), accessIntent); - - if (likely(rc == 0) && accessIntent == QMY_UPDATABLE) - rc = prepWriteBuffer(1, getFileForActiveHandle()); - - if (likely(rc == 0)) - { - rc = db2i_ileBridge::getBridgeForThread()->readByRRN(activeHandle, - activeReadBuf->ptr(), - currentRRN, - accessIntent, - getCommitLevel()); - - if (likely(rc == 0)) - { - rrnAssocHandle = activeHandle; - const char* readBuf = activeReadBuf->getRowN(0); - rc = mungeDB2row(buf, readBuf, readBuf + activeReadBuf->getRowNullOffset(), false); - releaseRowNeeded = TRUE; - } - } - } - - DBUG_RETURN(rc); -} - - -int ha_ibmdb2i::info(uint flag) -{ - DBUG_ENTER("ha_ibmdb2i::info"); - - uint16 infoRequested = 0; - ValidatedPointer rowKeySpcPtr; // Space pointer passed to DB2 - uint32 rowKeySpcLen; // Length of space passed to DB2 - THD* thd = ha_thd(); - int command = thd_sql_command(thd); - - if (flag & HA_STATUS_AUTO) - stats.auto_increment_value = (ulonglong) 0; - - if (flag & HA_STATUS_ERRKEY) - { - errkey = lastDupKeyID; - my_store_ptr(dup_ref, ref_length, lastDupKeyRRN); - } - - if (flag & HA_STATUS_TIME) - { - if ((flag & HA_STATUS_NO_LOCK) && - ibmdb2i_assume_exclusive_use && - share && - (share->cachedStats.isInited(lastModTime))) - stats.update_time = share->cachedStats.getUpdateTime(); - else - infoRequested |= lastModTime; - } - - if (flag & HA_STATUS_CONST) - { - stats.block_size=4096; - infoRequested |= createTime; - - if (table->s->keys) - { - infoRequested |= rowsPerKey; - rowKeySpcLen = (table->s->keys) * MAX_DB2_KEY_PARTS * sizeof(uint64); - rowKeySpcPtr.alloc(rowKeySpcLen); - memset(rowKeySpcPtr, 0, rowKeySpcLen); // Clear the allocated space - } - } - - if (flag & HA_STATUS_VARIABLE) - { - if ((flag & HA_STATUS_NO_LOCK) && - (command != SQLCOM_SHOW_TABLE_STATUS) && - ibmdb2i_assume_exclusive_use && - share && - (share->cachedStats.isInited(rowCount | deletedRowCount | meanRowLen | ioCount)) && - (share->cachedStats.getRowCount() >= 2)) - { - stats.records = share->cachedStats.getRowCount(); - stats.deleted = share->cachedStats.getDelRowCount(); - stats.mean_rec_length = share->cachedStats.getMeanLength(); - stats.data_file_length = share->cachedStats.getAugmentedDataLength(); - } - else - { - infoRequested |= rowCount | deletedRowCount | meanRowLen; - if (command == SQLCOM_SHOW_TABLE_STATUS) - infoRequested |= objLength; - else - infoRequested |= ioCount; - } - } - - int rc = 0; - - if (infoRequested) - { - DBUG_PRINT("ha_ibmdb2i::info",("Retrieving fresh stats %d", flag)); - - initBridge(thd); - rc = bridge()->retrieveTableInfo((dataHandle ? dataHandle : db2Table->dataFile()->getMasterDefnHandle()), - infoRequested, - stats, - rowKeySpcPtr); - - if (!rc) - { - if ((flag & HA_STATUS_VARIABLE) && - (command != SQLCOM_SHOW_TABLE_STATUS)) - stats.data_file_length = stats.data_file_length * IO_SIZE; - - if ((ibmdb2i_assume_exclusive_use) && - (share) && - (command != SQLCOM_SHOW_TABLE_STATUS)) - { - if (flag & HA_STATUS_VARIABLE) - { - share->cachedStats.cacheRowCount(stats.records); - share->cachedStats.cacheDelRowCount(stats.deleted); - share->cachedStats.cacheMeanLength(stats.mean_rec_length); - share->cachedStats.cacheAugmentedDataLength(stats.data_file_length); - } - - if (flag & HA_STATUS_TIME) - { - share->cachedStats.cacheUpdateTime(stats.update_time); - } - } - - if (flag & HA_STATUS_CONST) - { - ulong i; // Loop counter for indexes - ulong j; // Loop counter for key parts - RowKey* rowKeyPtr; // Pointer to 'number of unique rows' array for this index - - rowKeyPtr = (RowKey_t*)(void*)rowKeySpcPtr; // Address first array of DB2 row counts - for (i = 0; i < table->s->keys; i++) // Do for each index, including primary - { - for (j = 0; j < table->key_info[i].key_parts; j++) - { - table->key_info[i].rec_per_key[j]= rowKeyPtr->RowKeyArray[j]; - } - rowKeyPtr = rowKeyPtr + 1; // Address next array of DB2 row counts - } - } - } - else if (rc == HA_ERR_LOCK_WAIT_TIMEOUT && share) - { - // If we couldn't retrieve the info because the object was locked, - // we'll do our best by returning the most recently cached data. - if ((infoRequested & rowCount) && - share->cachedStats.isInited(rowCount)) - stats.records = share->cachedStats.getRowCount(); - if ((infoRequested & deletedRowCount) && - share->cachedStats.isInited(deletedRowCount)) - stats.deleted = share->cachedStats.getDelRowCount(); - if ((infoRequested & meanRowLen) && - share->cachedStats.isInited(meanRowLen)) - stats.mean_rec_length = share->cachedStats.getMeanLength(); - if ((infoRequested & lastModTime) && - share->cachedStats.isInited(lastModTime)) - stats.update_time = share->cachedStats.getUpdateTime(); - - rc = 0; - } - } - - DBUG_RETURN(rc); -} - - -ha_rows ha_ibmdb2i::records() -{ - DBUG_ENTER("ha_ibmdb2i::records"); - int rc; - rc = bridge()->retrieveTableInfo((dataHandle ? dataHandle : db2Table->dataFile()->getMasterDefnHandle()), - rowCount, - stats); - - if (unlikely(rc)) - { - if (rc == HA_ERR_LOCK_WAIT_TIMEOUT && - share && - (share->cachedStats.isInited(rowCount))) - DBUG_RETURN(share->cachedStats.getRowCount()); - else - DBUG_RETURN(HA_POS_ERROR); - } - else if (share) - { - share->cachedStats.cacheRowCount(stats.records); - } - - DBUG_RETURN(stats.records); -} - - -int ha_ibmdb2i::extra(enum ha_extra_function operation) -{ - DBUG_ENTER("ha_ibmdb2i::extra"); - - switch(operation) - { - // Can these first five flags be replaced by attending to HA_EXTRA_WRITE_CACHE? - case HA_EXTRA_NO_IGNORE_DUP_KEY: - case HA_EXTRA_WRITE_CANNOT_REPLACE: - { - returnDupKeysImmediately = false; - onDupUpdate = false; - } - break; - case HA_EXTRA_INSERT_WITH_UPDATE: - { - returnDupKeysImmediately = true; - onDupUpdate = true; - } - break; - case HA_EXTRA_IGNORE_DUP_KEY: - case HA_EXTRA_WRITE_CAN_REPLACE: - returnDupKeysImmediately = true; - break; - case HA_EXTRA_FLUSH_CACHE: - if (outstanding_start_bulk_insert) - finishBulkInsert(); - break; - } - - - DBUG_RETURN(0); -} - -/** - @brief - The DB2 storage engine will ignore a MySQL generated value and will generate - a new value in SLIC. We arbitrarily set first_value to 1, and set the - interval to infinity for better performance on multi-row inserts. -*/ -void ha_ibmdb2i::get_auto_increment(ulonglong offset, ulonglong increment, - ulonglong nb_desired_values, - ulonglong *first_value, - ulonglong *nb_reserved_values) -{ - DBUG_ENTER("ha_ibmdb2i::get_auto_increment"); - *first_value= 1; - *nb_reserved_values= ULONGLONG_MAX; -} - - - -void ha_ibmdb2i::update_create_info(HA_CREATE_INFO *create_info) -{ - DBUG_ENTER("ha_ibmdb2i::update_create_info"); - - if ((!(create_info->used_fields & HA_CREATE_USED_AUTO)) && - (table->found_next_number_field != NULL)) - { - initBridge(); - - create_info->auto_increment_value= 1; - - ha_rows rowCount = records(); - - if (rowCount == 0) - { - create_info->auto_increment_value = db2Table->getStartId(); - DBUG_VOID_RETURN; - } - else if (rowCount == HA_POS_ERROR) - { - DBUG_VOID_RETURN; - } - - getNextIdVal(&create_info->auto_increment_value); - } - DBUG_VOID_RETURN; -} - - -int ha_ibmdb2i::getNextIdVal(ulonglong *value) -{ - DBUG_ENTER("ha_ibmdb2i::getNextIdVal"); - - char queryBuffer[MAX_DB2_COLNAME_LENGTH + MAX_DB2_QUALIFIEDNAME_LENGTH + 64]; - strcpy(queryBuffer, " SELECT CAST(MAX( "); - convertMySQLNameToDB2Name(table->found_next_number_field->field_name, - strend(queryBuffer), - MAX_DB2_COLNAME_LENGTH+1); - strcat(queryBuffer, ") AS BIGINT) FROM "); - db2Table->getDB2QualifiedName(strend(queryBuffer)); - DBUG_ASSERT(strlen(queryBuffer) < sizeof(queryBuffer)); - - SqlStatementStream sqlStream(queryBuffer); - DBUG_PRINT("ha_ibmdb2i::getNextIdVal", ("Sent to DB2: %s",queryBuffer)); - - int rc = 0; - FILE_HANDLE fileHandle2; - uint32 db2RowDataLen2; - rc = bridge()->prepOpen(sqlStream.getPtrToData(), - &fileHandle2, - &db2RowDataLen2); - if (likely(rc == 0)) - { - IOReadBuffer rowBuffer(1, db2RowDataLen2); - rc = bridge()->read(fileHandle2, - rowBuffer.ptr(), - QMY_READ_ONLY, - QMY_NONE, - QMY_FIRST); - - if (likely(rc == 0)) - { - /* This check is here for the case where the table is not empty, - but the auto_increment starting value has been changed since - the last record was written. */ - - longlong maxIdVal = *(longlong*)(rowBuffer.getRowN(0)); - if ((maxIdVal + 1) > db2Table->getStartId()) - *value = maxIdVal + 1; - else - *value = db2Table->getStartId(); - } - - bridge()->deallocateFile(fileHandle2); - } - DBUG_RETURN(rc); -} - - -/* - Updates index cardinalities. -*/ -int ha_ibmdb2i::analyze(THD* thd, HA_CHECK_OPT *check_opt) -{ - DBUG_ENTER("ha_ibmdb2i::analyze"); - info(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE); - DBUG_RETURN(0); -} - -int ha_ibmdb2i::optimize(THD* thd, HA_CHECK_OPT *check_opt) -{ - DBUG_ENTER("ha_ibmdb2i::optimize"); - - initBridge(thd); - - if (unlikely(records() == 0)) - DBUG_RETURN(0); // DB2 doesn't like to reorganize a table with no data. - - quiesceAllFileHandles(); - - int32 rc = bridge()->optimizeTable(db2Table->dataFile()->getMasterDefnHandle()); - info(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE); - - DBUG_RETURN(rc); -} - - -/** - @brief - Determines if an ALTER TABLE is allowed to switch the storage engine - for this table. If the table has a foreign key or is referenced by a - foreign key, then it cannot be switched. -*/ -bool ha_ibmdb2i::can_switch_engines(void) -/*=================================*/ -{ - DBUG_ENTER("ha_ibmdb2i::can_switch_engines"); - - int rc = 0; - FILE_HANDLE queryFile = 0; - uint32 resultRowLen; - uint count = 0; - bool can_switch = FALSE; // 1 if changing storage engine is allowed - - const char* libName = db2Table->getDB2LibName(db2i_table::ASCII_SQL); - const char* fileName = db2Table->getDB2TableName(db2i_table::ASCII_SQL); - - String query(256); - query.append(STRING_WITH_LEN(" SELECT COUNT(*) FROM SYSIBM.SQLFOREIGNKEYS WHERE ((PKTABLE_SCHEM = '")); - query.append(libName+1, strlen(libName)-2); // Remove quotes from parent schema name - query.append(STRING_WITH_LEN("' AND PKTABLE_NAME = '")); - query.append(fileName+1,strlen(fileName)-2); // Remove quotes from file name - query.append(STRING_WITH_LEN("') OR (FKTABLE_SCHEM = '")); - query.append(libName+1,strlen(libName)-2); // Remove quotes from child schema - query.append(STRING_WITH_LEN("' AND FKTABLE_NAME = '")); - query.append(fileName+1,strlen(fileName)-2); // Remove quotes from child name - query.append(STRING_WITH_LEN("'))")); - - SqlStatementStream sqlStream(query); - - rc = bridge()->prepOpen(sqlStream.getPtrToData(), - &queryFile, - &resultRowLen); - if (rc == 0) - { - IOReadBuffer rowBuffer(1, resultRowLen); - - rc = bridge()->read(queryFile, - rowBuffer.ptr(), - QMY_READ_ONLY, - QMY_NONE, - QMY_FIRST); - if (!rc) - { - count = *(uint*)(rowBuffer.getRowN(0)); - if (count == 0) - can_switch = TRUE; - } - - bridge()->deallocateFile(queryFile); - } - DBUG_RETURN(can_switch); -} - - - -bool ha_ibmdb2i::check_if_incompatible_data(HA_CREATE_INFO *info, - uint table_changes) -{ - DBUG_ENTER("ha_ibmdb2i::check_if_incompatible_data"); - uint i; - /* Check that auto_increment value and field definitions were - not changed. */ - if ((info->used_fields & HA_CREATE_USED_AUTO && - info->auto_increment_value != 0) || - table_changes != IS_EQUAL_YES) - DBUG_RETURN(COMPATIBLE_DATA_NO); - /* Check if any fields were renamed. */ - for (i= 0; i < table->s->fields; i++) - { - Field *field= table->field[i]; - if (field->flags & FIELD_IS_RENAMED) - { - DBUG_PRINT("info", ("Field has been renamed, copy table")); - DBUG_RETURN(COMPATIBLE_DATA_NO); - } - } - DBUG_RETURN(COMPATIBLE_DATA_YES); -} - -int ha_ibmdb2i::reset_auto_increment(ulonglong value) - { - DBUG_ENTER("ha_ibmdb2i::reset_auto_increment"); - - int rc = 0; - - quiesceAllFileHandles(); - - const char* libName = db2Table->getDB2LibName(db2i_table::ASCII_SQL); - const char* fileName = db2Table->getDB2TableName(db2i_table::ASCII_SQL); - - String query(512); - query.append(STRING_WITH_LEN(" ALTER TABLE ")); - query.append(libName); - query.append('.'); - query.append(fileName); - query.append(STRING_WITH_LEN(" ALTER COLUMN ")); - char colName[MAX_DB2_COLNAME_LENGTH+1]; - convertMySQLNameToDB2Name(table->found_next_number_field->field_name, - colName, - sizeof(colName)); - query.append(colName); - - char restart_value[22]; - CHARSET_INFO *cs= &my_charset_bin; - uint len = (uint)(cs->cset->longlong10_to_str)(cs,restart_value,sizeof(restart_value), 10, value); - restart_value[len] = 0; - - query.append(STRING_WITH_LEN(" RESTART WITH ")); - query.append(restart_value); - - SqlStatementStream sqlStream(query); - DBUG_PRINT("ha_ibmdb2i::reset_auto_increment", ("Sent to DB2: %s",query.c_ptr())); - - rc = db2i_ileBridge::getBridgeForThread()->execSQL(sqlStream.getPtrToData(), - sqlStream.getStatementCount(), - QMY_NONE, //getCommitLevel(), - FALSE, - FALSE, - TRUE, //FALSE, - dataHandle); - if (rc == 0) - db2Table->updateStartId(value); - - DBUG_RETURN(rc); -} - - -/** - @brief - This function receives an error code that was previously set by the handler. - It returns to MySQL the error string associated with that error. -*/ -bool ha_ibmdb2i::get_error_message(int error, String *buf) -{ - DBUG_ENTER("ha_ibmdb2i::get_error_message"); - if ((error >= DB2I_FIRST_ERR && error <= DB2I_LAST_ERR) || - (error >= QMY_ERR_MIN && error <= QMY_ERR_MAX)) - { - db2i_ileBridge* bridge = db2i_ileBridge::getBridgeForThread(ha_thd()); - char* errMsg = bridge->getErrorStorage(); - buf->copy(errMsg, strlen(errMsg),system_charset_info); - bridge->freeErrorStorage(); - } - DBUG_RETURN(FALSE); -} - - -int ha_ibmdb2i::delete_all_rows() -{ - DBUG_ENTER("ha_ibmdb2i::delete_all_rows"); - int rc = 0; - char queryBuffer[MAX_DB2_QUALIFIEDNAME_LENGTH + 64]; - strcpy(queryBuffer, " DELETE FROM "); - db2Table->getDB2QualifiedName(strend(queryBuffer)); - DBUG_ASSERT(strlen(queryBuffer) < sizeof(queryBuffer)); - - SqlStatementStream sqlStream(queryBuffer); - DBUG_PRINT("ha_ibmdb2i::delete_all_rows", ("Sent to DB2: %s",queryBuffer)); - rc = bridge()->execSQL(sqlStream.getPtrToData(), - sqlStream.getStatementCount(), - getCommitLevel(), - false, - false, - true, - dataHandle); - - /* If this method was called on behalf of a TRUNCATE TABLE statement, and if */ - /* the table has an auto_increment field, then reset the starting value for */ - /* the auto_increment field to 1. - */ - if (rc == 0 && thd_sql_command(ha_thd()) == SQLCOM_TRUNCATE && - table->found_next_number_field ) - rc = reset_auto_increment(1); - - invalidateCachedStats(); - - DBUG_RETURN(rc); -} - - -int ha_ibmdb2i::external_lock(THD *thd, int lock_type) -{ - int rc = 0; - - DBUG_ENTER("ha_ibmdb2i::external_lock"); - DBUG_PRINT("ha_ibmdb2i::external_lock",("Lock type: %d", lock_type)); - - if (lock_type == F_RDLCK) - accessIntent = QMY_READ_ONLY; - else if (lock_type == F_WRLCK) - accessIntent = QMY_UPDATABLE; - - initBridge(thd); - int command = thd_sql_command(thd); - - if (!THDVAR(thd,transaction_unsafe)) - { - if (lock_type != F_UNLCK) - { - if (autoCommitIsOn(thd) == QMY_YES) - { - trans_register_ha(thd, FALSE, ibmdb2i_hton); - } - else - { - trans_register_ha(thd, TRUE, ibmdb2i_hton); - if (likely(command != SQLCOM_CREATE_TABLE)) - { - trans_register_ha(thd, FALSE, ibmdb2i_hton); - bridge()->beginStmtTx(); - } - } - } - } - - if (command == SQLCOM_LOCK_TABLES || - command == SQLCOM_ALTER_TABLE || - command == SQLCOM_UNLOCK_TABLES || - (accessIntent == QMY_UPDATABLE && - (command == SQLCOM_UPDATE || - command == SQLCOM_UPDATE_MULTI || - command == SQLCOM_DELETE || - command == SQLCOM_DELETE_MULTI || - command == SQLCOM_REPLACE || - command == SQLCOM_REPLACE_SELECT) && - getCommitLevel(thd) == QMY_NONE)) - { - char action; - char type; - if (lock_type == F_UNLCK) - { - action = QMY_UNLOCK; - type = accessIntent == QMY_READ_ONLY ? QMY_LSRD : QMY_LENR; - } - else - { - action = QMY_LOCK; - type = lock_type == F_RDLCK ? QMY_LSRD : QMY_LENR; - } - - DBUG_PRINT("ha_ibmdb2i::external_lock",("%socking table", action==QMY_LOCK ? "L" : "Unl")); - - if (!dataHandle) - rc = db2Table->dataFile()->allocateNewInstance(&dataHandle, curConnection); - - rc = bridge()->lockObj(dataHandle, - 0, - action, - type, - (command == SQLCOM_LOCK_TABLES ? QMY_NO : QMY_YES)); - - } - - // Cache this away so we don't have to access it on each row operation - cachedZeroDateOption = (enum_ZeroDate)THDVAR(thd, compat_opt_allow_zero_date_vals); - - DBUG_RETURN(rc); -} - - -THR_LOCK_DATA **ha_ibmdb2i::store_lock(THD *thd, - THR_LOCK_DATA **to, - enum thr_lock_type lock_type) -{ - if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) - { - if ((lock_type >= TL_WRITE_CONCURRENT_INSERT && - lock_type <= TL_WRITE) && !(thd->in_lock_tables && thd_sql_command(thd) == SQLCOM_LOCK_TABLES)) - lock_type= TL_WRITE_ALLOW_WRITE; - lock.type=lock_type; - } - *to++= &lock; - return to; -} - - -int ha_ibmdb2i::delete_table(const char *name) -{ - DBUG_ENTER("ha_ibmdb2i::delete_table"); - THD* thd = ha_thd(); - db2i_ileBridge* bridge = db2i_ileBridge::getBridgeForThread(thd); - - char db2Name[MAX_DB2_QUALIFIEDNAME_LENGTH]; - db2i_table::getDB2QualifiedNameFromPath(name, db2Name); - - String query(128); - query.append(STRING_WITH_LEN(" DROP TABLE ")); - query.append(db2Name); - - if (thd_sql_command(thd) == SQLCOM_DROP_TABLE && - thd->lex->drop_mode == DROP_RESTRICT) - query.append(STRING_WITH_LEN(" RESTRICT ")); - DBUG_PRINT("ha_ibmdb2i::delete_table", ("Sent to DB2: %s",query.c_ptr())); - - SqlStatementStream sqlStream(query); - - db2i_table::getDB2LibNameFromPath(name, db2Name); - bool isTemporary = (strcmp(db2Name, DB2I_TEMP_TABLE_SCHEMA) == 0 ? TRUE : FALSE); - - int rc = bridge->execSQL(sqlStream.getPtrToData(), - sqlStream.getStatementCount(), - (isTemporary ? QMY_NONE : getCommitLevel(thd)), - FALSE, - FALSE, - isTemporary); - - if (rc == HA_ERR_NO_SUCH_TABLE) - { - warning(thd, DB2I_ERR_TABLE_NOT_FOUND, name); - rc = 0; - } - - if (rc == 0) - { - db2i_table::deleteAssocFiles(name); - } - - FILE_HANDLE savedHandle = bridge->findAndRemovePreservedHandle(name, &share); - while (savedHandle) - { - bridge->deallocateFile(savedHandle, TRUE); - DBUG_ASSERT(share); - if (free_share(share)) - share = NULL; - savedHandle = bridge->findAndRemovePreservedHandle(name, &share); - } - - my_errno = rc; - DBUG_RETURN(rc); -} - - -int ha_ibmdb2i::rename_table(const char * from, const char * to) -{ - DBUG_ENTER("ha_ibmdb2i::rename_table "); - - char db2FromFileName[MAX_DB2_FILENAME_LENGTH + 1]; - char db2ToFileName[MAX_DB2_FILENAME_LENGTH+1]; - char db2FromLibName[MAX_DB2_SCHEMANAME_LENGTH+1]; - char db2ToLibName[MAX_DB2_SCHEMANAME_LENGTH+1]; - - db2i_table::getDB2LibNameFromPath(from, db2FromLibName); - db2i_table::getDB2LibNameFromPath(to, db2ToLibName); - - if (strcmp(db2FromLibName, db2ToLibName) != 0 ) - { - getErrTxt(DB2I_ERR_RENAME_MOVE,from,to); - DBUG_RETURN(DB2I_ERR_RENAME_MOVE); - } - - db2i_table::getDB2FileNameFromPath(from, db2FromFileName, db2i_table::ASCII_NATIVE); - db2i_table::getDB2FileNameFromPath(to, db2ToFileName); - - char escapedFromFileName[2 * MAX_DB2_FILENAME_LENGTH + 1]; - - uint o = 0; - uint i = 1; - do - { - escapedFromFileName[o++] = db2FromFileName[i]; - if (db2FromFileName[i] == '+') - escapedFromFileName[o++] = '+'; - } while (db2FromFileName[++i]); - escapedFromFileName[o-1] = 0; - - - int rc = 0; - - char queryBuffer[sizeof(db2FromLibName) + 2 * sizeof(db2FromFileName) + 256]; - SafeString selectQuery(queryBuffer, sizeof(queryBuffer)); - selectQuery.strncat(STRING_WITH_LEN("SELECT CAST(INDEX_NAME AS VARCHAR(128) CCSID 1208) FROM QSYS2.SYSINDEXES WHERE INDEX_NAME LIKE '%+_+_+_%")); - selectQuery.strcat(escapedFromFileName); - selectQuery.strncat(STRING_WITH_LEN("' ESCAPE '+' AND TABLE_NAME='")); - selectQuery.strncat(db2FromFileName+1, strlen(db2FromFileName)-2); - selectQuery.strncat(STRING_WITH_LEN("' AND TABLE_SCHEMA='")); - selectQuery.strncat(db2FromLibName+1, strlen(db2FromLibName)-2); - selectQuery.strcat('\''); - DBUG_ASSERT(!selectQuery.overflowed()); - - SqlStatementStream indexQuery(selectQuery.ptr()); - - FILE_HANDLE queryFile = 0; - uint32 resultRowLen; - - initBridge(); - rc = bridge()->prepOpen(indexQuery.getPtrToData(), - &queryFile, - &resultRowLen); - - if (unlikely(rc)) - DBUG_RETURN(rc); - - IOReadBuffer rowBuffer(1, resultRowLen); - - int tableNameLen = strlen(db2FromFileName) - 2; - - SqlStatementStream renameQuery(64); - String query; - while (rc == 0) - { - query.length(0); - - rc = bridge()->read(queryFile, - rowBuffer.ptr(), - QMY_READ_ONLY, - QMY_NONE, - QMY_NEXT); - - if (!rc) - { - const char* rowData = rowBuffer.getRowN(0); - char indexFileName[MAX_DB2_FILENAME_LENGTH]; - memset(indexFileName, 0, sizeof(indexFileName)); - - uint16 fileNameLen = *(uint16*)(rowData); - strncpy(indexFileName, rowData + sizeof(uint16), fileNameLen); - - int bytesToRetain = fileNameLen - tableNameLen; - if (bytesToRetain <= 0) - /* We can't handle index names in which the MySQL index name and - the table name together are longer than the max index name. */ - { - getErrTxt(DB2I_ERR_INVALID_NAME,"index","*generated*"); - DBUG_RETURN(DB2I_ERR_INVALID_NAME); - } - char indexName[MAX_DB2_FILENAME_LENGTH]; - memset(indexName, 0, sizeof(indexName)); - - strncpy(indexName, - indexFileName, - bytesToRetain); - - char db2IndexName[MAX_DB2_FILENAME_LENGTH+1]; - - convertMySQLNameToDB2Name(indexFileName, db2IndexName, sizeof(db2IndexName)); - - query.append(STRING_WITH_LEN("RENAME INDEX ")); - query.append(db2FromLibName); - query.append('.'); - query.append(db2IndexName); - query.append(STRING_WITH_LEN(" TO ")); - if (db2i_table::appendQualifiedIndexFileName(indexName, db2ToFileName, query, db2i_table::ASCII_SQL, typeNone) == -1) - { - getErrTxt(DB2I_ERR_INVALID_NAME,"index","*generated*"); - DBUG_RETURN(DB2I_ERR_INVALID_NAME ); - } - renameQuery.addStatement(query); - DBUG_PRINT("ha_ibmdb2i::rename_table", ("Sent to DB2: %s",query.c_ptr_safe())); - } - } - - - if (queryFile) - bridge()->deallocateFile(queryFile); - - if (rc != HA_ERR_END_OF_FILE) - DBUG_RETURN(rc); - - char db2Name[MAX_DB2_QUALIFIEDNAME_LENGTH]; - - /* Rename the table */ - query.length(0); - query.append(STRING_WITH_LEN(" RENAME TABLE ")); - db2i_table::getDB2QualifiedNameFromPath(from, db2Name); - query.append(db2Name); - query.append(STRING_WITH_LEN(" TO ")); - query.append(db2ToFileName); - DBUG_PRINT("ha_ibmdb2i::rename_table", ("Sent to DB2: %s",query.c_ptr_safe())); - renameQuery.addStatement(query); - rc = bridge()->execSQL(renameQuery.getPtrToData(), - renameQuery.getStatementCount(), - getCommitLevel()); - - if (!rc) - db2i_table::renameAssocFiles(from, to); - - DBUG_RETURN(rc); -} - - -int ha_ibmdb2i::create(const char *name, TABLE *table_arg, - HA_CREATE_INFO *create_info) -{ - DBUG_ENTER("ha_ibmdb2i::create"); - - int rc; - char fileSortSequence[11] = "*HEX"; - char fileSortSequenceLibrary[11] = ""; - char fileSortSequenceType = ' '; - char libName[MAX_DB2_SCHEMANAME_LENGTH+1]; - char fileName[MAX_DB2_FILENAME_LENGTH+1]; - char colName[MAX_DB2_COLNAME_LENGTH+1]; - bool isTemporary; - ulong auto_inc_value; - - db2i_table::getDB2LibNameFromPath(name, libName); - db2i_table::getDB2FileNameFromPath(name, fileName); - - if (osVersion.v < 6) - { - if (strlen(libName) > - MAX_DB2_V5R4_LIBNAME_LENGTH + (isOrdinaryIdentifier(libName) ? 2 : 0)) - { - getErrTxt(DB2I_ERR_TOO_LONG_SCHEMA,libName, MAX_DB2_V5R4_LIBNAME_LENGTH); - DBUG_RETURN(DB2I_ERR_TOO_LONG_SCHEMA); - } - } - else if (strlen(libName) > MAX_DB2_V6R1_LIBNAME_LENGTH) - { - getErrTxt(DB2I_ERR_TOO_LONG_SCHEMA,libName, MAX_DB2_V6R1_LIBNAME_LENGTH); - DBUG_RETURN(DB2I_ERR_TOO_LONG_SCHEMA); - } - - String query(256); - - if (strcmp(libName, DB2I_TEMP_TABLE_SCHEMA)) - { - query.append(STRING_WITH_LEN("CREATE TABLE ")); - query.append(libName); - query.append('.'); - query.append(fileName); - isTemporary = FALSE; - } - else - { - query.append(STRING_WITH_LEN("DECLARE GLOBAL TEMPORARY TABLE ")); - query.append(fileName); - isTemporary = TRUE; - } - query.append(STRING_WITH_LEN(" (")); - - THD* thd = ha_thd(); - enum_TimeFormat timeFormat = (enum_TimeFormat)(THDVAR(thd, compat_opt_time_as_duration)); - enum_YearFormat yearFormat = (enum_YearFormat)(THDVAR(thd, compat_opt_year_as_int)); - enum_BlobMapping blobMapping = (enum_BlobMapping)(THDVAR(thd, compat_opt_blob_cols)); - enum_ZeroDate zeroDate = (enum_ZeroDate)(THDVAR(thd, compat_opt_allow_zero_date_vals)); - bool propagateDefaults = THDVAR(thd, propagate_default_col_vals); - - Field **field; - for (field= table_arg->field; *field; field++) - { - if ( field != table_arg->field ) // Not the first one - query.append(STRING_WITH_LEN(" , ")); - - if (!convertMySQLNameToDB2Name((*field)->field_name, colName, sizeof(colName))) - { - getErrTxt(DB2I_ERR_INVALID_NAME,"field",(*field)->field_name); - DBUG_RETURN(DB2I_ERR_INVALID_NAME ); - } - - query.append(colName); - query.append(' '); - - if (rc = getFieldTypeMapping(*field, - query, - timeFormat, - blobMapping, - zeroDate, - propagateDefaults, - yearFormat)) - DBUG_RETURN(rc); - - if ( (*field)->flags & NOT_NULL_FLAG ) - { - query.append(STRING_WITH_LEN(" NOT NULL ")); - } - if ( (*field)->flags & AUTO_INCREMENT_FLAG ) - { -#ifdef WITH_PARTITION_STORAGE_ENGINE - if (table_arg->part_info) - { - getErrTxt(DB2I_ERR_PART_AUTOINC); - DBUG_RETURN(DB2I_ERR_PART_AUTOINC); - } -#endif - query.append(STRING_WITH_LEN(" GENERATED BY DEFAULT AS IDENTITY ") ); - if (create_info->auto_increment_value != 0) - { - /* Query was ALTER TABLE...AUTO_INCREMENT = x; or - CREATE TABLE ...AUTO_INCREMENT = x; Set the starting - value for the auto_increment column. */ - char stringValue[22]; - CHARSET_INFO *cs= &my_charset_bin; - uint len = (uint)(cs->cset->longlong10_to_str)(cs,stringValue,sizeof(stringValue), 10, create_info->auto_increment_value); - stringValue[len] = 0; - query.append(STRING_WITH_LEN(" (START WITH ")); - query.append(stringValue); - - uint64 maxValue=maxValueForField(*field); - - if (maxValue) - { - len = (uint)(cs->cset->longlong10_to_str)(cs,stringValue,sizeof(stringValue), 10, maxValue); - stringValue[len] = 0; - query.append(STRING_WITH_LEN(" MAXVALUE ")); - query.append(stringValue); - } - - query.append(STRING_WITH_LEN(") ")); - } - - } - } - - String fieldDefinition(128); - - if (table_arg->s->primary_key != MAX_KEY && !isTemporary) - { - query.append(STRING_WITH_LEN(", PRIMARY KEY ")); - rc = buildIndexFieldList(fieldDefinition, - table_arg->key_info[table_arg->s->primary_key], - true, - &fileSortSequenceType, - fileSortSequence, - fileSortSequenceLibrary); - if (rc) DBUG_RETURN(rc); - query.append(fieldDefinition); - } - - rc = buildDB2ConstraintString(thd->lex, - query, - name, - table_arg->field, - &fileSortSequenceType, - fileSortSequence, - fileSortSequenceLibrary); - if (rc) DBUG_RETURN (rc); - - query.append(STRING_WITH_LEN(" ) ")); - - if (isTemporary) - query.append(STRING_WITH_LEN(" ON COMMIT PRESERVE ROWS ")); - - if (create_info->alias) - generateAndAppendRCDFMT(create_info->alias, query); - else if (((TABLE_LIST*)(thd->lex->select_lex.table_list.first))->table_name) - generateAndAppendRCDFMT((char*)((TABLE_LIST*)(thd->lex->select_lex.table_list.first))->table_name, query); - - DBUG_PRINT("ha_ibmdb2i::create", ("Sent to DB2: %s",query.c_ptr())); - SqlStatementStream sqlStream(query.length()); - sqlStream.addStatement(query,fileSortSequence,fileSortSequenceLibrary); - - if (table_arg->s->primary_key != MAX_KEY && - !isTemporary && - (THDVAR(thd, create_index_option)==1) && - (fileSortSequenceType != 'B') && - (fileSortSequenceType != ' ')) - { - rc = generateShadowIndex(sqlStream, - table_arg->key_info[table_arg->s->primary_key], - libName, - fileName, - fieldDefinition); - if (rc) DBUG_RETURN(rc); - } - for (uint i = 0; i < table_arg->s->keys; ++i) - { - if (i != table_arg->s->primary_key || isTemporary) - { - rc = buildCreateIndexStatement(sqlStream, - table_arg->key_info[i], - false, - libName, - fileName); - if (rc) DBUG_RETURN (rc); - } - } - - bool noCommit = isTemporary || ((!autoCommitIsOn(thd)) && (thd_sql_command(thd) == SQLCOM_ALTER_TABLE)); - - initBridge(); - -// if (THDVAR(thd, discovery_mode) == 1) -// bridge()->expectErrors(QMY_ERR_TABLE_EXISTS); - - rc = bridge()->execSQL(sqlStream.getPtrToData(), - sqlStream.getStatementCount(), - (isTemporary ? QMY_NONE : getCommitLevel(thd)), - TRUE, - FALSE, - noCommit ); - - if (unlikely(rc == QMY_ERR_MSGID) && - memcmp(bridge()->getErrorMsgID(), DB2I_SQL0350, 7) == 0) - { - my_error(ER_BLOB_USED_AS_KEY, MYF(0), "*unknown*"); - rc = ER_BLOB_USED_AS_KEY; - } -/* else if (unlikely(rc == QMY_ERR_TABLE_EXISTS) && - THDVAR(thd, discovery_mode) == 1) - { - db2i_table* temp = new db2i_table(table_arg->s, name); - int32 rc = temp->fastInitForCreate(name); - delete temp; - - if (!rc) - warning(thd, DB2I_ERR_WARN_CREATE_DISCOVER); - - DBUG_RETURN(rc); - } -*/ - - if (!rc && !isTemporary) - { - db2i_table* temp = new db2i_table(table_arg->s, name); - rc = temp->fastInitForCreate(name); - delete temp; - if (rc) - delete_table(name); - } - - DBUG_RETURN(rc); -} - - -/** - @brief - Add an index on-line to a table. This method is called on behalf of - a CREATE INDEX or ALTER TABLE statement. - It is implemented via a composed DDL statement passed to DB2. -*/ -int ha_ibmdb2i::add_index(TABLE *table_arg, - KEY *key_info, - uint num_of_keys) -{ - DBUG_ENTER("ha_ibmdb2i::add_index"); - - int rc; - SqlStatementStream sqlStream(256); - const char* libName = db2Table->getDB2LibName(db2i_table::ASCII_SQL); - const char* fileName = db2Table->getDB2TableName(db2i_table::ASCII_SQL); - - quiesceAllFileHandles(); - - uint primaryKey = MAX_KEY; - if (table_arg->s->primary_key >= MAX_KEY && !db2Table->isTemporary()) - { - for (int i = 0; i < num_of_keys; ++i) - { - if (strcmp(key_info[i].name, "PRIMARY") == 0) - { - primaryKey = i; - break; - } - else if (primaryKey == MAX_KEY && - key_info[i].flags & HA_NOSAME) - { - primaryKey = i; - for (int j=0 ; j < key_info[i].key_parts ;j++) - { - uint fieldnr= key_info[i].key_part[j].fieldnr; - if (table_arg->s->field[fieldnr]->null_ptr || - table_arg->s->field[fieldnr]->key_length() != - key_info[i].key_part[j].length) - { - primaryKey = MAX_KEY; - break; - } - } - } - } - } - - - for (int i = 0; i < num_of_keys; ++i) - { - KEY& curKey= key_info[i]; - rc = buildCreateIndexStatement(sqlStream, - curKey, - (i == primaryKey), - libName, - fileName); - if (rc) DBUG_RETURN (rc); - } - - rc = bridge()->execSQL(sqlStream.getPtrToData(), - sqlStream.getStatementCount(), - getCommitLevel(), - FALSE, - FALSE, - FALSE, - dataHandle); - - /* Handle the case where a unique index is being created but an error occurs - because the file contains duplicate key values. */ - if (rc == ER_DUP_ENTRY) - print_keydup_error(MAX_KEY,ER(ER_DUP_ENTRY_WITH_KEY_NAME)); - - DBUG_RETURN(rc); -} - -/** - @brief - Drop an index on-line from a table. This method is called on behalf of - a DROP INDEX or ALTER TABLE statement. - It is implemented via a composed DDL statement passed to DB2. -*/ -int ha_ibmdb2i::prepare_drop_index(TABLE *table_arg, - uint *key_num, uint num_of_keys) -{ - DBUG_ENTER("ha_ibmdb2i::prepare_drop_index"); - int rc; - int i = 0; - String query(64); - SqlStatementStream sqlStream(64 * num_of_keys); - SqlStatementStream shadowStream(64 * num_of_keys); - - quiesceAllFileHandles(); - - const char* libName = db2Table->getDB2LibName(db2i_table::ASCII_SQL); - const char* fileName = db2Table->getDB2TableName(db2i_table::ASCII_SQL); - - while (i < num_of_keys) - { - query.length(0); - DBUG_PRINT("info", ("ha_ibmdb2i::prepare_drop_index %u", key_num[i])); - KEY& curKey= table_arg->key_info[key_num[i]]; - if (key_num[i] == table->s->primary_key && !db2Table->isTemporary()) - { - query.append(STRING_WITH_LEN("ALTER TABLE ")); - query.append(libName); - query.append(STRING_WITH_LEN(".")); - query.append(fileName); - query.append(STRING_WITH_LEN(" DROP PRIMARY KEY")); - } - else - { - query.append(STRING_WITH_LEN("DROP INDEX ")); - query.append(libName); - query.append(STRING_WITH_LEN(".")); - db2i_table::appendQualifiedIndexFileName(curKey.name, fileName, query); - } - DBUG_PRINT("ha_ibmdb2i::prepare_drop_index", ("Sent to DB2: %s",query.c_ptr_safe())); - sqlStream.addStatement(query); - - query.length(0); - query.append(STRING_WITH_LEN("DROP INDEX ")); - query.append(libName); - query.append(STRING_WITH_LEN(".")); - db2i_table::appendQualifiedIndexFileName(curKey.name, fileName, query, db2i_table::ASCII_SQL, typeHex); - - DBUG_PRINT("ha_ibmdb2i::prepare_drop_index", ("Sent to DB2: %s",query.c_ptr_safe())); - shadowStream.addStatement(query); - - ++i; - } - - rc = bridge()->execSQL(sqlStream.getPtrToData(), - sqlStream.getStatementCount(), - getCommitLevel(), - FALSE, - FALSE, - FALSE, - dataHandle); - - if (rc == 0) - bridge()->execSQL(shadowStream.getPtrToData(), - shadowStream.getStatementCount(), - getCommitLevel()); - - DBUG_RETURN(rc); -} - - -void -ha_ibmdb2i::unlock_row() -{ - DBUG_ENTER("ha_ibmdb2i::unlock_row"); - DBUG_VOID_RETURN; -} - -int -ha_ibmdb2i::index_end() -{ - DBUG_ENTER("ha_ibmdb2i::index_end"); - warnIfInvalidData(); - last_index_init_rc = 0; - if (likely(activeReadBuf)) - activeReadBuf->endRead(); - if (likely(!last_index_init_rc)) - releaseIndexFile(active_index); - active_index= MAX_KEY; - DBUG_RETURN (0); -} - -int ha_ibmdb2i::doCommit(handlerton *hton, THD *thd, bool all) -{ - if (!THDVAR(thd, transaction_unsafe)) - { - if (all || autoCommitIsOn(thd)) - { - DBUG_PRINT("ha_ibmdb2i::doCommit",("Committing all")); - return (db2i_ileBridge::getBridgeForThread(thd)->commitmentControl(QMY_COMMIT)); - } - else - { - DBUG_PRINT("ha_ibmdb2i::doCommit",("Committing stmt")); - return (db2i_ileBridge::getBridgeForThread(thd)->commitStmtTx()); - } - } - - return (0); -} - - -int ha_ibmdb2i::doRollback(handlerton *hton, THD *thd, bool all) -{ - if (!THDVAR(thd,transaction_unsafe)) - { - if (all || autoCommitIsOn(thd)) - { - DBUG_PRINT("ha_ibmdb2i::doRollback",("Rolling back all")); - return ( db2i_ileBridge::getBridgeForThread(thd)->commitmentControl(QMY_ROLLBACK)); - } - else - { - DBUG_PRINT("ha_ibmdb2i::doRollback",("Rolling back stmt")); - return (db2i_ileBridge::getBridgeForThread(thd)->rollbackStmtTx()); - } - } - return (0); -} - - -void ha_ibmdb2i::start_bulk_insert(ha_rows rows) -{ - DBUG_ENTER("ha_ibmdb2i::start_bulk_insert"); - DBUG_PRINT("ha_ibmdb2i::start_bulk_insert",("Rows hinted %d", rows)); - int rc; - THD* thd = ha_thd(); - int command = thd_sql_command(thd); - - if (db2Table->hasBlobs() || - (command == SQLCOM_REPLACE || command == SQLCOM_REPLACE_SELECT)) - rows = 1; - else if (rows == 0) - rows = DEFAULT_MAX_ROWS_TO_BUFFER; // Shoot the moon - - // If we're doing a multi-row insert, binlogging is active, and the table has an - // auto_increment column, then we'll attempt to lock the file while we perform a 'fast path' blocked - // insert. If we can't get the lock, then we'll do a row-by-row 'slow path' insert instead. The reason is - // because the MI generates the auto_increment (identity value), and if we can't lock the file, - // then we can't predetermine what that value will be for insertion into the MySQL write buffer. - - if ((rows > 1) && // Multi-row insert - (thd->options & OPTION_BIN_LOG) && // Binlogging is on - (table->found_next_number_field)) // Table has an auto_increment column - { - if (!dataHandle) - rc = db2Table->dataFile()->allocateNewInstance(&dataHandle, curConnection); - - rc = bridge()->lockObj(dataHandle, 1, QMY_LOCK, QMY_LEAR, QMY_YES); - if (rc==0) // Got the lock - { - autoIncLockAcquired = TRUE; - got_auto_inc_values = FALSE; - } - else // Didn't get the lock - rows = 1; // No problem, but don't block inserts - } - - if (activeHandle == 0) - { - last_start_bulk_insert_rc = useDataFile(); - if (last_start_bulk_insert_rc == 0) - last_start_bulk_insert_rc = prepWriteBuffer(rows, db2Table->dataFile()); - } - - if (last_start_bulk_insert_rc == 0) - outstanding_start_bulk_insert = true; - else - { - if (autoIncLockAcquired == TRUE) - { - bridge()->lockObj(dataHandle, 0, QMY_UNLOCK, QMY_LEAR, QMY_YES); - autoIncLockAcquired = FALSE; - } - } - - DBUG_VOID_RETURN; -} - - -int ha_ibmdb2i::end_bulk_insert() -{ - DBUG_ENTER("ha_ibmdb2i::end_bulk_insert"); - int rc = 0; - - if (outstanding_start_bulk_insert) - { - rc = finishBulkInsert(); - } - - my_errno = rc; - - DBUG_RETURN(rc); -} - - -int ha_ibmdb2i::prepReadBuffer(ha_rows rowsToRead, const db2i_file* file, char intent) -{ - DBUG_ENTER("ha_ibmdb2i::prepReadBuffer"); - DBUG_ASSERT(rowsToRead > 0); - - THD* thd = ha_thd(); - char cmtLvl = getCommitLevel(thd); - - const db2i_file::RowFormat* format; - int rc = file->obtainRowFormat(activeHandle, intent, cmtLvl, &format); - - if (unlikely(rc)) DBUG_RETURN(rc); - - if (lobFieldsRequested()) - { - forceSingleRowRead = true; - rowsToRead = 1; - } - - rowsToRead = min(stats.records+1,min(rowsToRead, DEFAULT_MAX_ROWS_TO_BUFFER)); - - uint bufSize = min((format->readRowLen * rowsToRead), THDVAR(thd, max_read_buffer_size)); - multiRowReadBuf.allocBuf(format->readRowLen, format->readRowNullOffset, bufSize); - activeReadBuf = &multiRowReadBuf; - - if (db2Table->hasBlobs()) - { - if (!blobReadBuffers) - blobReadBuffers = new BlobCollection(db2Table, THDVAR(thd, lob_alloc_size)); - rc = prepareReadBufferForLobs(); - if (rc) DBUG_RETURN(rc); - } - -// if (accessIntent == QMY_UPDATABLE && -// thd_tx_isolation(thd) == ISO_REPEATABLE_READ && -// !THDVAR(thd, transaction_unsafe)) -// activeReadBuf->update(QMY_READ_ONLY, &releaseRowNeeded, QMY_REPEATABLE_READ); -// else - activeReadBuf->update(intent, &releaseRowNeeded, cmtLvl); - - DBUG_RETURN(rc); -} - - -int ha_ibmdb2i::prepWriteBuffer(ha_rows rowsToWrite, const db2i_file* file) -{ - DBUG_ENTER("ha_ibmdb2i::prepWriteBuffer"); - DBUG_ASSERT(accessIntent == QMY_UPDATABLE && rowsToWrite > 0); - - const db2i_file::RowFormat* format; - int rc = file->obtainRowFormat(activeHandle, - QMY_UPDATABLE, - getCommitLevel(ha_thd()), - &format); - - if (unlikely(rc)) DBUG_RETURN(rc); - - rowsToWrite = min(rowsToWrite, DEFAULT_MAX_ROWS_TO_BUFFER); - - uint bufSize = min((format->writeRowLen * rowsToWrite), THDVAR(ha_thd(), max_write_buffer_size)); - multiRowWriteBuf.allocBuf(format->writeRowLen, format->writeRowNullOffset, bufSize); - activeWriteBuf = &multiRowWriteBuf; - - if (!blobWriteBuffers && db2Table->hasBlobs()) - { - blobWriteBuffers = new ValidatedPointer[db2Table->getBlobCount()]; - } - DBUG_RETURN(rc); -} - - -int ha_ibmdb2i::flushWrite(FILE_HANDLE fileHandle, uchar* buf ) -{ - DBUG_ENTER("ha_ibmdb2i::flushWrite"); - int rc; - int64 generatedIdValue = 0; - bool IdValueWasGenerated = FALSE; - char* lastDupKeyNamePtr = NULL; - uint32 lastDupKeyNameLen = 0; - int loopCnt = 0; - bool retry_dup = FALSE; - - while (loopCnt == 0 || retry_dup == TRUE) - { - rc = bridge()->writeRows(fileHandle, - activeWriteBuf->ptr(), - getCommitLevel(), - &generatedIdValue, - &IdValueWasGenerated, - &lastDupKeyRRN, - &lastDupKeyNamePtr, - &lastDupKeyNameLen, - &incrementByValue); - loopCnt++; - retry_dup = FALSE; - invalidateCachedStats(); - if (lastDupKeyNameLen) - { - rrnAssocHandle = fileHandle; - - int command = thd_sql_command(ha_thd()); - - if (command == SQLCOM_REPLACE || - command == SQLCOM_REPLACE_SELECT) - lastDupKeyID = 0; - else - { - lastDupKeyID = getKeyFromName(lastDupKeyNamePtr, lastDupKeyNameLen); - - if (likely(lastDupKeyID != MAX_KEY)) - { - uint16 failedRow = activeWriteBuf->rowsWritten()+1; - - if (buf && (failedRow != activeWriteBuf->rowCount())) - { - const char* badRow = activeWriteBuf->getRowN(failedRow-1); - bool savedReadAllColumns = readAllColumns; - readAllColumns = true; - mungeDB2row(buf, - badRow, - badRow + activeWriteBuf->getRowNullOffset(), - true); - readAllColumns = savedReadAllColumns; - - if (table->found_next_number_field) - { - table->next_number_field->store(next_identity_value - (incrementByValue * (activeWriteBuf->rowCount() - (failedRow - 1)))); - } - } - - if (default_identity_value && // Table has ID colm and generating a value - (!autoIncLockAcquired || !got_auto_inc_values) && - // Writing first or only row in block - loopCnt == 1 && // Didn't already retry - lastDupKeyID == table->s->next_number_index) // Autoinc column is in failed index - { - if (alterStartWith() == 0) // Reset next Identity value to max+1 - retry_dup = TRUE; // Rtry the write operation - } - } - else - { - char unknownIndex[MAX_DB2_FILENAME_LENGTH+1]; - convFromEbcdic(lastDupKeyNamePtr, unknownIndex, min(lastDupKeyNameLen, MAX_DB2_FILENAME_LENGTH)); - unknownIndex[min(lastDupKeyNameLen, MAX_DB2_FILENAME_LENGTH)] = 0; - getErrTxt(DB2I_ERR_UNKNOWN_IDX, unknownIndex); - } - } - } - } - - if ((rc == 0 || rc == HA_ERR_FOUND_DUPP_KEY) - && default_identity_value && IdValueWasGenerated && - (!autoIncLockAcquired || !got_auto_inc_values)) - { - /* Save the generated identity value for the MySQL last_insert_id() function. */ - insert_id_for_cur_row = generatedIdValue; - - /* Store the value into MySQL's buf for row-based replication - or for an 'on duplicate key update' clause. */ - table->next_number_field->store((longlong) generatedIdValue, TRUE); - if (autoIncLockAcquired) - { - got_auto_inc_values = TRUE; - next_identity_value = generatedIdValue + incrementByValue; - } - } - else - { - if (!autoIncLockAcquired) // Don't overlay value for first row of a block - insert_id_for_cur_row = 0; - } - - - activeWriteBuf->resetAfterWrite(); - DBUG_RETURN(rc); -} - -int ha_ibmdb2i::alterStartWith() -{ - DBUG_ENTER("ha_ibmdb2i::alterStartWith"); - int rc = 0; - ulonglong nextIdVal; - if (!dataHandle) - rc = db2Table->dataFile()->allocateNewInstance(&dataHandle, curConnection); - if (!rc) {rc = bridge()->lockObj(dataHandle, 1, QMY_LOCK, QMY_LENR, QMY_YES);} - if (!rc) - { - rc = getNextIdVal(&nextIdVal); - if (!rc) {rc = reset_auto_increment(nextIdVal);} - bridge()->lockObj(dataHandle, 0, QMY_UNLOCK, QMY_LENR, QMY_YES); - } - DBUG_RETURN(rc); -} - -bool ha_ibmdb2i::lobFieldsRequested() -{ - if (!db2Table->hasBlobs()) - { - DBUG_PRINT("ha_ibmdb2i::lobFieldsRequested",("No LOBs")); - return (false); - } - - if (readAllColumns) - { - DBUG_PRINT("ha_ibmdb2i::lobFieldsRequested",("All cols requested")); - return (true); - } - - for (int i = 0; i < db2Table->getBlobCount(); ++i) - { - if (bitmap_is_set(table->read_set, db2Table->blobFields[i])) - { - DBUG_PRINT("ha_ibmdb2i::lobFieldsRequested",("LOB requested")); - return (true); - } - } - - DBUG_PRINT("ha_ibmdb2i::lobFieldsRequested",("No LOBs requested")); - return (false); -} - - -int ha_ibmdb2i::prepareReadBufferForLobs() -{ - DBUG_ENTER("ha_ibmdb2i::prepareReadBufferForLobs"); - DBUG_ASSERT(db2Table->hasBlobs()); - - uint32 activeLobFields = 0; - DB2LobField* lobField; - uint16 blobCount = db2Table->getBlobCount(); - - char* readBuf = activeReadBuf->getRowN(0); - - for (int i = 0; i < blobCount; ++i) - { - int fieldID = db2Table->blobFields[i]; - DB2Field& db2Field = db2Table->db2Field(fieldID); - lobField = db2Field.asBlobField(readBuf); - if (readAllColumns || - bitmap_is_set(table->read_set, fieldID)) - { - lobField->dataHandle = (ILEMemHandle)blobReadBuffers->getBufferPtr(fieldID); - activeLobFields++; - } - else - { - lobField->dataHandle = NULL; - } - } - - if (activeLobFields == 0) - { - for (int i = 0; i < blobCount; ++i) - { - DB2Field& db2Field = db2Table->db2Field(db2Table->blobFields[i]); - uint16 offset = db2Field.getBufferOffset() + db2Field.calcBlobPad(); - - for (int r = 1; r < activeReadBuf->getRowCapacity(); ++r) - { - lobField = (DB2LobField*)(activeReadBuf->getRowN(r) + offset); - lobField->dataHandle = NULL; - } - } - } - - activeReadBuf->setRowsToProcess((activeLobFields ? 1 : activeReadBuf->getRowCapacity())); - int rc = bridge()->objectOverride(activeHandle, - activeReadBuf->ptr(), - activeReadBuf->getRowLength()); - DBUG_RETURN(rc); -} - - -uint32 ha_ibmdb2i::adjustLobBuffersForRead() -{ - DBUG_ENTER("ha_ibmdb2i::adjustLobBuffersForRead"); - - char* readBuf = activeReadBuf->getRowN(0); - - for (int i = 0; i < db2Table->getBlobCount(); ++i) - { - DB2Field& db2Field = db2Table->db2Field(db2Table->blobFields[i]); - DB2LobField* lobField = db2Field.asBlobField(readBuf); - if (readAllColumns || - bitmap_is_set(table->read_set, db2Table->blobFields[i])) - { - lobField->dataHandle = (ILEMemHandle)blobReadBuffers->reallocBuffer(db2Table->blobFields[i], lobField->length); - - if (lobField->dataHandle == NULL) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - else - { - lobField->dataHandle = 0; - } - } - - int32 rc = bridge()->objectOverride(activeHandle, - activeReadBuf->ptr()); - DBUG_RETURN(rc); -} - - - -int ha_ibmdb2i::reset() -{ - DBUG_ENTER("ha_ibmdb2i::reset"); - - if (outstanding_start_bulk_insert) - { - finishBulkInsert(); - } - - if (activeHandle != 0) - { - releaseActiveHandle(); - } - - cleanupBuffers(); - - db2i_ileBridge::getBridgeForThread(ha_thd())->freeErrorStorage(); - - last_rnd_init_rc = last_index_init_rc = last_start_bulk_insert_rc = 0; - - returnDupKeysImmediately = false; - onDupUpdate = false; - forceSingleRowRead = false; - -#ifndef DBUG_OFF - cachedBridge=NULL; -#endif - - DBUG_RETURN(0); -} - - -int32 ha_ibmdb2i::buildCreateIndexStatement(SqlStatementStream& sqlStream, - KEY& key, - bool isPrimary, - const char* db2LibName, - const char* db2FileName) -{ - DBUG_ENTER("ha_ibmdb2i::buildCreateIndexStatement"); - - char fileSortSequence[11] = "*HEX"; - char fileSortSequenceLibrary[11] = ""; - char fileSortSequenceType = ' '; - String query(256); - query.length(0); - int rc = 0; - - if (isPrimary) - { - query.append(STRING_WITH_LEN("ALTER TABLE ")); - query.append(db2LibName); - query.append('.'); - query.append(db2FileName); - query.append(STRING_WITH_LEN(" ADD PRIMARY KEY ")); - } - else - { - query.append(STRING_WITH_LEN("CREATE")); - - if (key.flags & HA_NOSAME) - query.append(STRING_WITH_LEN(" UNIQUE WHERE NOT NULL")); - - query.append(STRING_WITH_LEN(" INDEX ")); - - query.append(db2LibName); - query.append('.'); - if (db2i_table::appendQualifiedIndexFileName(key.name, db2FileName, query)) - { - getErrTxt(DB2I_ERR_INVALID_NAME,"index","*generated*"); - DBUG_RETURN(DB2I_ERR_INVALID_NAME ); - } - - query.append(STRING_WITH_LEN(" ON ")); - - query.append(db2LibName); - query.append('.'); - query.append(db2FileName); - } - - String fieldDefinition(128); - rc = buildIndexFieldList(fieldDefinition, - key, - isPrimary, - &fileSortSequenceType, - fileSortSequence, - fileSortSequenceLibrary); - - if (rc) DBUG_RETURN(rc); - - query.append(fieldDefinition); - - if ((THDVAR(ha_thd(), create_index_option)==1) && - (fileSortSequenceType != 'B') && - (fileSortSequenceType != ' ')) - { - rc = generateShadowIndex(sqlStream, - key, - db2LibName, - db2FileName, - fieldDefinition); - if (rc) DBUG_RETURN(rc); - } - - DBUG_PRINT("ha_ibmdb2i::buildCreateIndexStatement", ("Sent to DB2: %s",query.c_ptr_safe())); - sqlStream.addStatement(query,fileSortSequence,fileSortSequenceLibrary); - - DBUG_RETURN(0); -} - -/** - Generate the SQL syntax for the list of fields to be assigned to the - specified key. The corresponding sort sequence is also calculated. - - @param[out] appendHere The string to receive the generated SQL - @param key The key to evaluate - @param isPrimary True if this is being generated on behalf of the primary key - @param[out] fileSortSequenceType The type of the associated sort sequence - @param[out] fileSortSequence The name of the associated sort sequence - @param[out] fileSortSequenceLibrary The library of the associated sort sequence - - @return 0 if successful; error value otherwise -*/ -int32 ha_ibmdb2i::buildIndexFieldList(String& appendHere, - const KEY& key, - bool isPrimary, - char* fileSortSequenceType, - char* fileSortSequence, - char* fileSortSequenceLibrary) -{ - DBUG_ENTER("ha_ibmdb2i::buildIndexFieldList"); - appendHere.append(STRING_WITH_LEN(" ( ")); - for (int j = 0; j < key.key_parts; ++j) - { - char colName[MAX_DB2_COLNAME_LENGTH+1]; - if (j != 0) - { - appendHere.append(STRING_WITH_LEN(" , ")); - } - - KEY_PART_INFO& kpi = key.key_part[j]; - Field* field = kpi.field; - - convertMySQLNameToDB2Name(field->field_name, - colName, - sizeof(colName)); - appendHere.append(colName); - - int32 rc; - rc = updateAssociatedSortSequence(field->charset(), - fileSortSequenceType, - fileSortSequence, - fileSortSequenceLibrary); - if (rc) DBUG_RETURN (rc); - } - - appendHere.append(STRING_WITH_LEN(" ) ")); - - DBUG_RETURN(0); -} - - -/** - Generate an SQL statement that defines a *HEX sorted index to implement - the ibmdb2i_create_index. - - @param[out] stream The stream to append the generated statement to - @param key The key to evaluate - @param[out] libName The library containg the table - @param[out] fileName The DB2-compatible name of the table - @param[out] fieldDefinition The list of the fields in the index, in SQL syntax - - @return 0 if successful; error value otherwise -*/ -int32 ha_ibmdb2i::generateShadowIndex(SqlStatementStream& stream, - const KEY& key, - const char* libName, - const char* fileName, - const String& fieldDefinition) -{ - String shadowQuery(256); - shadowQuery.length(0); - shadowQuery.append(STRING_WITH_LEN("CREATE INDEX ")); - shadowQuery.append(libName); - shadowQuery.append('.'); - if (db2i_table::appendQualifiedIndexFileName(key.name, fileName, shadowQuery, db2i_table::ASCII_SQL, typeHex)) - { - getErrTxt(DB2I_ERR_INVALID_NAME,"index","*generated*"); - return DB2I_ERR_INVALID_NAME; - } - shadowQuery.append(STRING_WITH_LEN(" ON ")); - shadowQuery.append(libName); - shadowQuery.append('.'); - shadowQuery.append(fileName); - shadowQuery.append(fieldDefinition); - DBUG_PRINT("ha_ibmdb2i::generateShadowIndex", ("Sent to DB2: %s",shadowQuery.c_ptr_safe())); - stream.addStatement(shadowQuery,"*HEX","QSYS"); - return 0; -} - - -void ha_ibmdb2i::doInitialRead(char orientation, - uint32 rowsToBuffer, - ILEMemHandle key, - int keyLength, - int keyParts) -{ - DBUG_ENTER("ha_ibmdb2i::doInitialRead"); - - if (forceSingleRowRead) - rowsToBuffer = 1; - else - rowsToBuffer = min(rowsToBuffer, activeReadBuf->getRowCapacity()); - - activeReadBuf->newReadRequest(activeHandle, - orientation, - rowsToBuffer, - THDVAR(ha_thd(), async_enabled), - key, - keyLength, - keyParts); - DBUG_VOID_RETURN; -} - - -int ha_ibmdb2i::start_stmt(THD *thd, thr_lock_type lock_type) -{ - DBUG_ENTER("ha_ibmdb2i::start_stmt"); - initBridge(thd); - if (!THDVAR(thd, transaction_unsafe)) - { - trans_register_ha(thd, FALSE, ibmdb2i_hton); - - if (!autoCommitIsOn(thd)) - { - bridge()->beginStmtTx(); - } - } - - DBUG_RETURN(0); -} - -int32 ha_ibmdb2i::handleLOBReadOverflow() -{ - DBUG_ENTER("ha_ibmdb2i::handleLOBReadOverflow"); - DBUG_ASSERT(db2Table->hasBlobs() && (activeReadBuf->getRowCapacity() == 1)); - - int32 rc = adjustLobBuffersForRead(); - - if (!rc) - { - activeReadBuf->rewind(); - rc = bridge()->expectErrors(QMY_ERR_END_OF_BLOCK) - ->read(activeHandle, - activeReadBuf->ptr(), - accessIntent, - getCommitLevel(), - QMY_SAME); - releaseRowNeeded = TRUE; - - } - DBUG_RETURN(rc); -} - - -int32 ha_ibmdb2i::finishBulkInsert() -{ - int32 rc = 0; - - if (activeWriteBuf->rowCount() && activeHandle) - rc = flushWrite(activeHandle, table->record[0]); - - if (activeHandle) - releaseActiveHandle(); - - if (autoIncLockAcquired == TRUE) - { - // We could check the return code on the unlock, but beware not - // to overlay the return code from the flushwrite or we will mask - // duplicate key errors.. - bridge()->lockObj(dataHandle, 0, QMY_UNLOCK, QMY_LEAR, QMY_YES); - autoIncLockAcquired = FALSE; - } - outstanding_start_bulk_insert = false; - multiRowWriteBuf.freeBuf(); - last_start_bulk_insert_rc = 0; - - resetCharacterConversionBuffers(); - - return rc; -} - -int ha_ibmdb2i::getKeyFromName(const char* name, size_t len) -{ - for (int i = 0; i < table_share->keys; ++i) - { - const char* indexName = db2Table->indexFile(i)->getDB2FileName(); - if ((strncmp(name, indexName, len) == 0) && - (strlen(indexName) == len)) - { - return i; - } - } - return MAX_KEY; -} - -/* -Determine the number of I/O's it takes to read through the table. - */ -double ha_ibmdb2i::scan_time() - { - DBUG_ENTER("ha_ibmdb2i::scan_time"); - DBUG_RETURN(ulonglong2double((stats.data_file_length)/IO_SIZE)); - } - - -/** - Estimate the number of I/O's it takes to read a set of ranges through - an index. - - @param index - @param ranges - @param rows - - @return The estimate number of I/Os -*/ - -double ha_ibmdb2i::read_time(uint index, uint ranges, ha_rows rows) -{ - DBUG_ENTER("ha_ibmdb2i::read_time"); - int rc; - uint64 idxPageCnt = 0; - double cost; - - if (unlikely(rows == HA_POS_ERROR)) - DBUG_RETURN(double(rows) + ranges); - - rc = bridge()->retrieveIndexInfo(db2Table->indexFile(index)->getMasterDefnHandle(), - &idxPageCnt); - if (!rc) - { - if ((idxPageCnt == 1) || // Retrieving rows in requested order or - (ranges == rows)) // 'Sweep' full records retrieval - cost = idxPageCnt/4; - else - { - uint64 totalRecords = stats.records + 1; - double dataPageCount = stats.data_file_length/IO_SIZE; - - cost = (rows * dataPageCount / totalRecords) + - min(idxPageCnt, (log_2(idxPageCnt) * ranges + - rows * (log_2(idxPageCnt) + log_2(rows) - log_2(totalRecords)))); - } - } - else - { - cost = rows2double(ranges+rows); // Use default costing - } - DBUG_RETURN(cost); -} - -int ha_ibmdb2i::useIndexFile(int idx) -{ - DBUG_ENTER("ha_ibmdb2i::useIndexFile"); - - if (activeHandle) - releaseActiveHandle(); - - int rc = 0; - - if (!indexHandles[idx]) - rc = db2Table->indexFile(idx)->allocateNewInstance(&indexHandles[idx], curConnection); - - if (rc == 0) - { - activeHandle = indexHandles[idx]; - bumpInUseCounter(1); - } - - DBUG_RETURN(rc); -} - - -ulong ha_ibmdb2i::index_flags(uint inx, uint part, bool all_parts) const -{ - return HA_READ_NEXT | HA_READ_PREV | HA_KEYREAD_ONLY | HA_READ_ORDER | HA_READ_RANGE; -} - - -static struct st_mysql_sys_var* ibmdb2i_system_variables[] = { - MYSQL_SYSVAR(rdb_name), - MYSQL_SYSVAR(transaction_unsafe), - MYSQL_SYSVAR(lob_alloc_size), - MYSQL_SYSVAR(max_read_buffer_size), - MYSQL_SYSVAR(max_write_buffer_size), - MYSQL_SYSVAR(async_enabled), - MYSQL_SYSVAR(assume_exclusive_use), - MYSQL_SYSVAR(compat_opt_blob_cols), - MYSQL_SYSVAR(compat_opt_time_as_duration), - MYSQL_SYSVAR(compat_opt_allow_zero_date_vals), - MYSQL_SYSVAR(compat_opt_year_as_int), - MYSQL_SYSVAR(propagate_default_col_vals), - MYSQL_SYSVAR(create_index_option), -// MYSQL_SYSVAR(discovery_mode), - MYSQL_SYSVAR(system_trace_level), - NULL -}; - - -struct st_mysql_storage_engine ibmdb2i_storage_engine= -{ MYSQL_HANDLERTON_INTERFACE_VERSION }; - -mysql_declare_plugin(ibmdb2i) -{ - MYSQL_STORAGE_ENGINE_PLUGIN, - &ibmdb2i_storage_engine, - "IBMDB2I", - "The IBM development team in Rochester, Minnesota", - "IBM DB2 for i Storage Engine", - PLUGIN_LICENSE_GPL, - ibmdb2i_init_func, /* Plugin Init */ - ibmdb2i_done_func, /* Plugin Deinit */ - 0x0100 /* 1.0 */, - NULL, /* status variables */ - ibmdb2i_system_variables, /* system variables */ - NULL /* config options */ -} -mysql_declare_plugin_end; diff --git a/storage/ibmdb2i/ha_ibmdb2i.h b/storage/ibmdb2i/ha_ibmdb2i.h deleted file mode 100644 index b2a43232f2d..00000000000 --- a/storage/ibmdb2i/ha_ibmdb2i.h +++ /dev/null @@ -1,822 +0,0 @@ -/* -Licensed Materials - Property of IBM -DB2 Storage Engine Enablement -Copyright IBM Corporation 2007,2008 -All rights reserved - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - (a) Redistributions of source code must retain this list of conditions, the - copyright notice in section {d} below, and the disclaimer following this - list of conditions. - (b) Redistributions in binary form must reproduce this list of conditions, the - copyright notice in section (d) below, and the disclaimer following this - list of conditions, in the documentation and/or other materials provided - with the distribution. - (c) The name of IBM may not be used to endorse or promote products derived from - this software without specific prior written permission. - (d) The text of the required copyright notice is: - Licensed Materials - Property of IBM - DB2 Storage Engine Enablement - Copyright IBM Corporation 2007,2008 - All rights reserved - -THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - -/** @file ha_ibmdb2i.h - - @brief - - @note - - @see -*/ - -#ifdef USE_PRAGMA_INTERFACE -#pragma interface /* gcc class implementation */ -#endif - -#include "as400_types.h" -#include "as400_protos.h" -#include "db2i_global.h" -#include "db2i_ileBridge.h" -#include "builtins.h" -#include "db2i_misc.h" -#include "db2i_file.h" -#include "db2i_blobCollection.h" -#include "db2i_collationSupport.h" -#include "db2i_validatedPointer.h" -#include "db2i_ioBuffers.h" -#include "db2i_errors.h" -#include "db2i_sqlStatementStream.h" - -/** @brief - IBMDB2I_SHARE is a structure that will be shared among all open handlers. - It is used to describe the underlying table definition, and it caches - table statistics. -*/ -struct IBMDB2I_SHARE { - char *table_name; - uint table_name_length,use_count; - pthread_mutex_t mutex; - THR_LOCK lock; - - db2i_table* db2Table; - - class CStats - { - public: - void cacheUpdateTime(time_t time) - {update_time = time; initFlag |= lastModTime;} - time_t getUpdateTime() const - {return update_time;} - void cacheRowCount(ha_rows rows) - {records = rows; initFlag |= rowCount;} - ha_rows getRowCount() const - {return records;} - void cacheDelRowCount(ha_rows rows) - {deleted = rows; initFlag |= deletedRowCount;} - ha_rows getDelRowCount() const - {return deleted;} - void cacheMeanLength(ulong len) - {mean_rec_length = len; initFlag |= meanRowLen;} - ulong getMeanLength() - {return mean_rec_length;} - void cacheAugmentedDataLength(ulong len) - {data_file_length = len; initFlag |= ioCount;} - ulong getAugmentedDataLength() - {return data_file_length;} - bool isInited(uint flags) - {return initFlag & flags;} - void invalidate(uint flags) - {initFlag &= ~flags;} - - private: - uint initFlag; - time_t update_time; - ha_rows records; - ha_rows deleted; - ulong mean_rec_length; - ulong data_file_length; - } cachedStats; - -}; - -class ha_ibmdb2i: public handler -{ - THR_LOCK_DATA lock; ///< MySQL lock - IBMDB2I_SHARE *share; ///< Shared lock info - - // The record we are positioned on, together with the handle used to get - // i. - uint32 currentRRN; - uint32 rrnAssocHandle; - - // Dup key values needed by info() - uint32 lastDupKeyRRN; - uint32 lastDupKeyID; - - bool returnDupKeysImmediately; - - // Dup key value need by update() - bool onDupUpdate; - - - db2i_table* db2Table; - - // The file handle of the PF or LF being accessed by the current operation. - FILE_HANDLE activeHandle; - - // The file handle of the underlying PF - FILE_HANDLE dataHandle; - - // Array of file handles belonging to the underlying LFs - FILE_HANDLE* indexHandles; - - // Flag to indicate whether a call needs to be made to unlock a row when - // a read operation has ended. DB2 will handle row unlocking as we move - // through rows, but if an operation ends before we reach the end of a file, - // DB2 needs to know to unlock the last row read. - bool releaseRowNeeded; - - // Pointer to a definition of the layout of the row buffer for the file - // described by activeHandle - const db2i_file::RowFormat* activeFormat; - - IORowBuffer keyBuf; - uint32 keyLen; - - IOWriteBuffer multiRowWriteBuf; - IOAsyncReadBuffer multiRowReadBuf; - - IOAsyncReadBuffer* activeReadBuf; - IOWriteBuffer* activeWriteBuf; - - BlobCollection* blobReadBuffers; // Dynamically allocated per query and used - // to manage the buffers used for reading LOBs - ValidatedPointer* blobWriteBuffers; - - // Return codes are not used/honored by rnd_init and start_bulk_insert - // so we need a way to signal the failure "downstream" to subsequent - // functions. - int last_rnd_init_rc; - int last_index_init_rc; - int last_start_bulk_insert_rc; - - // end_bulk_insert may get called twice for a single start_bulk_insert - // This is our way to do cleanup only once. - bool outstanding_start_bulk_insert; - - // Auto_increment 'increment by' value needed by write_row() - uint32 incrementByValue; - bool default_identity_value; - - // Flags and values used during write operations for auto_increment processing - bool autoIncLockAcquired; - bool got_auto_inc_values; - uint64 next_identity_value; - - // The access intent indicated by the last external_locks() call. - // May be either QMY_READ or QMY_UPDATABLE - char accessIntent; - char readAccessIntent; - - ha_rows* indexReadSizeEstimates; - - MEM_ROOT conversionBufferMemroot; - - bool forceSingleRowRead; - - bool readAllColumns; - - bool invalidDataFound; - - db2i_ileBridge* cachedBridge; - - ValidatedObject curConnection; - uint16 activeReferences; - -public: - - ha_ibmdb2i(handlerton *hton, TABLE_SHARE *table_arg); - ~ha_ibmdb2i(); - - const char *table_type() const { return "IBMDB2I"; } - const char *index_type(uint inx) { return "RADIX"; } - const key_map *keys_to_use_for_scanning() { return &key_map_full; } - const char **bas_ext() const; - - ulonglong table_flags() const - { - return HA_NULL_IN_KEY | HA_REC_NOT_IN_SEQ | HA_AUTO_PART_KEY | - HA_PARTIAL_COLUMN_READ | - HA_DUPLICATE_POS | HA_NO_PREFIX_CHAR_KEYS | - HA_HAS_RECORDS | HA_BINLOG_ROW_CAPABLE | HA_REQUIRES_KEY_COLUMNS_FOR_DELETE | - HA_CAN_INDEX_BLOBS; - } - - ulong index_flags(uint inx, uint part, bool all_parts) const; - -// Note that we do not implement max_supported_record_length. -// We'll let create fail accordingly if the row is -// too long. This allows us to hide the fact that varchars > 32K are being -// implemented as DB2 LOBs. - - uint max_supported_keys() const { return 4000; } - uint max_supported_key_parts() const { return MAX_DB2_KEY_PARTS; } - uint max_supported_key_length() const { return 32767; } - uint max_supported_key_part_length() const { return 32767; } - double read_time(uint index, uint ranges, ha_rows rows); - double scan_time(); - int open(const char *name, int mode, uint test_if_locked); - int close(void); - int write_row(uchar * buf); - int update_row(const uchar * old_data, uchar * new_data); - int delete_row(const uchar * buf); - int index_init(uint idx, bool sorted); - int index_read(uchar * buf, const uchar * key, - uint key_len, enum ha_rkey_function find_flag); - int index_next(uchar * buf); - int index_read_last(uchar * buf, const uchar * key, uint key_len); - int index_next_same(uchar *buf, const uchar *key, uint keylen); - int index_prev(uchar * buf); - int index_first(uchar * buf); - int index_last(uchar * buf); - int rnd_init(bool scan); - int rnd_end(); - int rnd_next(uchar *buf); - int rnd_pos(uchar * buf, uchar *pos); - void position(const uchar *record); - int info(uint); - ha_rows records(); - int extra(enum ha_extra_function operation); - int external_lock(THD *thd, int lock_type); - int delete_all_rows(void); - ha_rows records_in_range(uint inx, key_range *min_key, - key_range *max_key); - int delete_table(const char *from); - int rename_table(const char * from, const char * to); - int create(const char *name, TABLE *form, - HA_CREATE_INFO *create_info); - int updateFrm(TABLE *table_def, File file); - int openTableDef(TABLE *table_def); - int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys); - int prepare_drop_index(TABLE *table_arg, uint *key_num, uint num_of_keys); - int final_drop_index(TABLE *table_arg) {return 0;} - void get_auto_increment(ulonglong offset, ulonglong increment, - ulonglong nb_desired_values, - ulonglong *first_value, - ulonglong *nb_reserved_values); - int reset_auto_increment(ulonglong value); - void restore_auto_increment(ulonglong prev_insert_id) {return;} - void update_create_info(HA_CREATE_INFO *create_info); - int getNextIdVal(ulonglong *value); - int analyze(THD* thd,HA_CHECK_OPT* check_opt); - int optimize(THD* thd, HA_CHECK_OPT* check_opt); - bool can_switch_engines(); - void free_foreign_key_create_info(char* str); - char* get_foreign_key_create_info(); - int get_foreign_key_list(THD *thd, List *f_key_list); - uint referenced_by_foreign_key(); - bool check_if_incompatible_data(HA_CREATE_INFO *info, uint table_changes); - virtual bool get_error_message(int error, String *buf); - - THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, - enum thr_lock_type lock_type); - - bool low_byte_first() const { return 0; } - void unlock_row(); - int index_end(); - int reset(); - static int doCommit(handlerton *hton, THD *thd, bool all); - static int doRollback(handlerton *hton, THD *thd, bool all); - void start_bulk_insert(ha_rows rows); - int end_bulk_insert(); - int start_stmt(THD *thd, thr_lock_type lock_type); - - void initBridge(THD* thd = NULL) - { - if (thd == NULL) thd = ha_thd(); - DBUG_PRINT("ha_ibmdb2i::initBridge",("Initing bridge. Conn ID=%d", thd->thread_id)); - cachedBridge = db2i_ileBridge::getBridgeForThread(thd); - } - - db2i_ileBridge* bridge() {DBUG_ASSERT(cachedBridge); return cachedBridge;} - - static uint8 autoCommitIsOn(THD* thd) - { return (thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN) ? QMY_NO : QMY_YES); } - - uint8 getCommitLevel(); - uint8 getCommitLevel(THD* thd); - - static int doSavepointSet(THD* thd, char* name) - { - return db2i_ileBridge::getBridgeForThread(thd)->savepoint(QMY_SET_SAVEPOINT, - name); - } - - static int doSavepointRollback(THD* thd, char* name) - { - return db2i_ileBridge::getBridgeForThread(thd)->savepoint(QMY_ROLLBACK_SAVEPOINT, - name); - } - - static int doSavepointRelease(THD* thd, char* name) - { - return db2i_ileBridge::getBridgeForThread(thd)->savepoint(QMY_RELEASE_SAVEPOINT, - name); - } - - // We can't guarantee that the rows we know about when this is called - // will be the same number of rows that read returns (since DB2 activity - // may insert additional rows). Therefore, we do as the Federated SE and - // return the max possible. - ha_rows estimate_rows_upper_bound() - { - return HA_POS_ERROR; - } - - -private: - - enum enum_TimeFormat - { - TIME_OF_DAY, - DURATION - }; - - enum enum_BlobMapping - { - AS_BLOB, - AS_VARCHAR - }; - - enum enum_ZeroDate - { - NO_SUBSTITUTE, - SUBSTITUTE_0001_01_01 - }; - - enum enum_YearFormat - { - CHAR4, - SMALLINT - }; - - enum_ZeroDate cachedZeroDateOption; - - IBMDB2I_SHARE *get_share(const char *table_name, TABLE *table); - int free_share(IBMDB2I_SHARE *share); - int32 mungeDB2row(uchar* record, const char* dataPtr, const char* nullMapPtr, bool skipLOBs); - int prepareRowForWrite(char* data, char* nulls, bool honorIdentCols); - int prepareReadBufferForLobs(); - int32 prepareWriteBufferForLobs(); - uint32 adjustLobBuffersForRead(); - bool lobFieldsRequested(); - int convertFieldChars(enum_conversionDirection direction, - uint16 fieldID, - const char* input, - char* output, - size_t ilen, - size_t olen, - size_t* outDataLen, - bool tacitErrors=FALSE, - size_t* substChars=NULL); - - /** - Fast integer log2 function - */ - uint64 log_2(uint64 val) - { - uint64 exp = 0; - while( (val >> exp) != 0) - { - exp++; - } - DBUG_ASSERT(exp-1 == (uint64)log2(val)); - return exp-1; - } - - void bumpInUseCounter(uint16 amount) - { - activeReferences += amount; - DBUG_PRINT("ha_ibmdb2i::bumpInUseCounter", ("activeReferences = %d", activeReferences)); - if (activeReferences) - curConnection = (uint32)(ha_thd()->thread_id); - else - curConnection = 0; - } - - - int useDataFile() - { - DBUG_ENTER("ha_ibmdb2i::useDataFile"); - - int rc = 0; - if (!dataHandle) - rc = db2Table->dataFile()->allocateNewInstance(&dataHandle, curConnection); - else if (activeHandle == dataHandle) - DBUG_RETURN(0); - - DBUG_ASSERT(activeHandle == 0); - - if (likely(rc == 0)) - { - activeHandle = dataHandle; - bumpInUseCounter(1); - } - - DBUG_RETURN(rc); - } - - void releaseAnyLockedRows() - { - if (releaseRowNeeded) - { - DBUG_PRINT("ha_ibmdb2i::releaseAnyLockedRows", ("Releasing rows")); - db2i_ileBridge::getBridgeForThread()->rrlslck(activeHandle, accessIntent); - releaseRowNeeded = FALSE; - } - } - - - void releaseDataFile() - { - DBUG_ENTER("ha_ibmdb2i::releaseDataFile"); - releaseAnyLockedRows(); - bumpInUseCounter(-1); - DBUG_ASSERT((volatile int)activeReferences >= 0); - activeHandle = 0; - DBUG_VOID_RETURN; - } - - int useIndexFile(int idx); - - void releaseIndexFile(int idx) - { - DBUG_ENTER("ha_ibmdb2i::releaseIndexFile"); - releaseAnyLockedRows(); - bumpInUseCounter(-1); - DBUG_ASSERT((volatile int)activeReferences >= 0); - activeHandle = 0; - DBUG_VOID_RETURN; - } - - FILE_HANDLE allocateFileHandle(char* database, char* table, int* activityReference, bool hasBlobs); - - int updateBuffers(const db2i_file::RowFormat* format, uint rowsToRead, uint rowsToWrite); - - int flushWrite(FILE_HANDLE fileHandle, uchar* buf = NULL); - - int alterStartWith(); - - int buildDB2ConstraintString(LEX* lex, - String& appendHere, - const char* database, - Field** fields, - char* fileSortSequenceType, - char* fileSortSequence, - char* fileSortSequenceLibrary); - - void releaseWriteBuffer(); - - void setIndexReadEstimate(uint index, ha_rows rows) - { - if (!indexReadSizeEstimates) - { - indexReadSizeEstimates = (ha_rows*)my_malloc(sizeof(ha_rows) * table->s->keys, MYF(MY_WME | MY_ZEROFILL)); - } - indexReadSizeEstimates[index] = rows; - } - - ha_rows getIndexReadEstimate(uint index) - { - if (indexReadSizeEstimates) - return max(indexReadSizeEstimates[index], 1); - - return 10000; // Assume index scan if no estimate exists. - } - - - void quiesceAllFileHandles() - { - db2i_ileBridge* bridge = db2i_ileBridge::getBridgeForThread(); - if (dataHandle) - { - bridge->quiesceFileInstance(dataHandle); - } - - for (int idx = 0; idx < table_share->keys; ++idx) - { - if (indexHandles[idx] != 0) - { - bridge->quiesceFileInstance(indexHandles[idx]); - } - } - } - - int32 buildCreateIndexStatement(SqlStatementStream& sqlStream, - KEY& key, - bool isPrimary, - const char* db2LibName, - const char* db2FileName); - - int32 buildIndexFieldList(String& appendHere, - const KEY& key, - bool isPrimary, - char* fileSortSequenceType, - char* fileSortSequence, - char* fileSortSequenceLibrary); - - // Specify NULL for data when using the data pointed to by field - int32 convertMySQLtoDB2(Field* field, const DB2Field& db2Field, char* db2Buf, const uchar* data = NULL); - - int32 convertDB2toMySQL(const DB2Field& db2Field, Field* field, const char* buf); - int getFieldTypeMapping(Field* field, - String& mapping, - enum_TimeFormat timeFormate, - enum_BlobMapping blobMapping, - enum_ZeroDate zeroDateHandling, - bool propagateDefaults, - enum_YearFormat yearFormat); - - int getKeyFromName(const char* name, size_t len); - - void releaseActiveHandle() - { - if (activeHandle == dataHandle) - releaseDataFile(); - else - releaseIndexFile(active_index); - } - - - int32 finishBulkInsert(); - - void doInitialRead(char orientation, - uint32 rowsToBuffer, - ILEMemHandle key = 0, - int keyLength = 0, - int keyParts = 0); - - - int32 readFromBuffer(uchar* destination, char orientation) - { - char* row; - int32 rc = 0; - row = activeReadBuf->readNextRow(orientation, currentRRN); - - if (unlikely(!row)) - { - rc = activeReadBuf->lastrc(); - if (rc == QMY_ERR_LOB_SPACE_TOO_SMALL) - { - rc = handleLOBReadOverflow(); - if (rc == 0) - { - DBUG_ASSERT(activeReadBuf->rowCount() == 1); - row = activeReadBuf->readNextRow(orientation, currentRRN); - - if (unlikely(!row)) - rc = activeReadBuf->lastrc(); - } - } - } - - if (likely(rc == 0)) - { - rrnAssocHandle = activeHandle; - rc = mungeDB2row(destination, row, row+activeReadBuf->getRowNullOffset(), false); - } - return rc; - } - - int32 handleLOBReadOverflow(); - - char* getCharacterConversionBuffer(int fieldId, int length) - { - if (unlikely(!alloc_root_inited(&conversionBufferMemroot))) - init_alloc_root(&conversionBufferMemroot, 8192, 0); - - return (char*)alloc_root(&conversionBufferMemroot, length);; - } - - void resetCharacterConversionBuffers() - { - if (alloc_root_inited(&conversionBufferMemroot)) - { - free_root(&conversionBufferMemroot, MYF(MY_MARK_BLOCKS_FREE)); - } - } - - void tweakReadSet() - { - THD* thd = ha_thd(); - int command = thd_sql_command(thd); - if ((command == SQLCOM_UPDATE || - command == SQLCOM_UPDATE_MULTI) || - ((command == SQLCOM_DELETE || - command == SQLCOM_DELETE_MULTI) && - thd->options & OPTION_BIN_LOG)) - readAllColumns = TRUE; - else - readAllColumns = FALSE; - } - - /** - - */ - int useFileByHandle(char intent, - FILE_HANDLE handle) - { - DBUG_ENTER("ha_ibmdb2i::useFileByHandle"); - - const db2i_file* file; - if (handle == dataHandle) - file = db2Table->dataFile(); - else - { - for (uint i = 0; i < table_share->keys; ++i) - { - if (indexHandles[i] == handle) - { - file = db2Table->indexFile(i); - active_index = i; - } - } - } - - int rc = file->obtainRowFormat(handle, intent, getCommitLevel(), &activeFormat); - if (likely(rc == 0)) - { - activeHandle = handle; - bumpInUseCounter(1); - } - - DBUG_RETURN(rc); - } - - const db2i_file* getFileForActiveHandle() const - { - if (activeHandle == dataHandle) - return db2Table->dataFile(); - else - for (uint i = 0; i < table_share->keys; ++i) - if (indexHandles[i] == activeHandle) - return db2Table->indexFile(i); - DBUG_ASSERT(0); - return NULL; - } - - int prepReadBuffer(ha_rows rowsToRead, const db2i_file* file, char intent); - int prepWriteBuffer(ha_rows rowsToWrite, const db2i_file* file); - - void invalidateCachedStats() - { - share->cachedStats.invalidate(rowCount | deletedRowCount | objLength | - meanRowLen | ioCount); - } - - void warnIfInvalidData() - { - if (unlikely(invalidDataFound)) - { - warning(ha_thd(), DB2I_ERR_INVALID_DATA, table->alias); - } - } - - /** - Calculate the maximum value that a particular field can hold. - - This is used to anticipate overflows in the auto_increment processing. - - @param field The Field to be analyzed - - @return The maximum value - */ - static uint64 maxValueForField(const Field* field) - { - uint64 maxValue=0; - switch (field->type()) - { - case MYSQL_TYPE_TINY: - if (((const Field_num*)field)->unsigned_flag) - maxValue = (1 << 8) - 1; - else - maxValue = (1 << 7) - 1; - break; - case MYSQL_TYPE_SHORT: - if (((const Field_num*)field)->unsigned_flag) - maxValue = (1 << 16) - 1; - else - maxValue = (1 << 15) - 1; - break; - case MYSQL_TYPE_INT24: - if (((const Field_num*)field)->unsigned_flag) - maxValue = (1 << 24) - 1; - else - maxValue = (1 << 23) - 1; - break; - case MYSQL_TYPE_LONG: - if (((const Field_num*)field)->unsigned_flag) - maxValue = (1LL << 32) - 1; - else - maxValue = (1 << 31) - 1; - break; - case MYSQL_TYPE_LONGLONG: - if (((const Field_num*)field)->unsigned_flag) - maxValue = ~(0LL); - else - maxValue = 1 << 63 - 1; - break; - } - - return maxValue; - } - - void cleanupBuffers() - { - if (blobReadBuffers) - { - delete blobReadBuffers; - blobReadBuffers = NULL; - } - if (blobWriteBuffers) - { - delete[] blobWriteBuffers; - blobWriteBuffers = NULL; - } - if (alloc_root_inited(&conversionBufferMemroot)) - { - free_root(&conversionBufferMemroot, MYF(0)); - } - } - - -/** - Generate a valid RCDFMT name based on the name of the table. - - The RCDFMT name is devised by munging the name of the table, - uppercasing all ascii alpha-numeric characters and replacing all other - characters with underscores until up to ten characters have been generated. - - @param tableName The name of the table, as given on the MySQL - CREATE TABLE statement - @param[out] query The string to receive the generated RCDFMT name -*/ - static void generateAndAppendRCDFMT(const char* tableName, String& query) - { - char rcdfmt[11]; - - // The RCDFMT name must begin with an alpha character. - // We enforce this by skipping to the first alpha character in the table - // name. If no alpha character exists, we use 'X' for the RCDFMT name; - - while (*tableName && - (!my_isascii(*tableName) || - !my_isalpha(system_charset_info, *tableName))) - { - tableName += my_mbcharlen(system_charset_info, *tableName); - } - - if (unlikely(!(*tableName))) - { - rcdfmt[0]= 'X'; - rcdfmt[1]= 0; - } - else - { - int r= 0; - while ((r < sizeof(rcdfmt)-1) && *tableName) - { - if (my_isascii(*tableName) && - my_isalnum(system_charset_info, *tableName)) - rcdfmt[r] = my_toupper(system_charset_info, *tableName); - else - rcdfmt[r] = '_'; - - ++r; - tableName += my_mbcharlen(system_charset_info, *tableName); - } - rcdfmt[r]= 0; - } - query.append(STRING_WITH_LEN(" RCDFMT ")); - query.append(rcdfmt); - } - - int32 generateShadowIndex(SqlStatementStream& stream, - const KEY& key, - const char* libName, - const char* fileName, - const String& fieldDefinition); -}; diff --git a/storage/ibmdb2i/plug.in b/storage/ibmdb2i/plug.in deleted file mode 100644 index 0913d72aabf..00000000000 --- a/storage/ibmdb2i/plug.in +++ /dev/null @@ -1,12 +0,0 @@ -MYSQL_STORAGE_ENGINE([ibmdb2i], [], [IBM DB2 for i Storage Engine], - [IBM DB2 for i Storage Engine], [max,max-no-ndb]) -MYSQL_PLUGIN_DYNAMIC([ibmdb2i], [ha_ibmdb2i.la]) - -AC_CHECK_HEADER([qlgusr.h], - # qlgusr.h is just one of the headers from the i5/OS PASE environment; the - # EBCDIC headers are in /QIBM/include, and have to be converted to ASCII - # before cpp gets to them - [:], - # Missing PASE environment, can't build this engine - [mysql_plugin_ibmdb2i=no - with_plugin_ibmdb2i=no]) From aa668865e271694e9b3ebbfe518cb4d0c2ad0c38 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Thu, 11 Nov 2010 13:25:23 +0300 Subject: [PATCH 220/304] Bug#57257 Replace(ExtractValue(...)) causes MySQL crash Bug#57820 extractvalue crashes Problem: ExtractValue and Replace crashed in some cases due to invalid handling of empty and NULL arguments. Per file comments: @mysql-test/r/ctype_ujis.result @mysql-test/r/xml.result @mysql-test/t/ctype_ujis.test @mysql-test/t/xml.test Adding tests @sql/item_strfunc.cc Make sure Item_func_replace::val_str safely handles empty strings. @sql/item_xmlfunc.cc set null_value if nodeset_func returned NULL, which is possible when the second argument is an unset user variable. --- mysql-test/r/ctype_ujis.result | 10 ++++++++++ mysql-test/r/xml.result | 13 +++++++++++++ mysql-test/t/ctype_ujis.test | 7 +++++++ mysql-test/t/xml.test | 11 +++++++++++ sql/item_strfunc.cc | 8 +++++++- sql/item_xmlfunc.cc | 4 ++-- 6 files changed, 50 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/ctype_ujis.result b/mysql-test/r/ctype_ujis.result index 540ba178756..765ad5a96ca 100644 --- a/mysql-test/r/ctype_ujis.result +++ b/mysql-test/r/ctype_ujis.result @@ -2374,6 +2374,16 @@ hex(convert(_latin1 0xA4A2 using ujis)) hex(c2) DROP PROCEDURE sp1; DROP TABLE t1; DROP TABLE t2; +# +# Bug#57257 Replace(ExtractValue(...)) causes MySQL crash +# +SET NAMES utf8; +SELECT CONVERT(REPLACE(EXPORT_SET('a','a','a','','a'),'00','') USING ujis); +CONVERT(REPLACE(EXPORT_SET('a','a','a','','a'),'00','') USING ujis) + +Warnings: +Warning 1292 Truncated incorrect INTEGER value: 'a' +Warning 1292 Truncated incorrect INTEGER value: 'a' set names default; set character_set_database=default; set character_set_server=default; diff --git a/mysql-test/r/xml.result b/mysql-test/r/xml.result index fad2cab0e57..e6811789679 100644 --- a/mysql-test/r/xml.result +++ b/mysql-test/r/xml.result @@ -1093,4 +1093,17 @@ Warnings: Warning 1525 Incorrect XML value: 'parse error at line 1 pos 23: unexpected END-OF-INPUT' Warning 1525 Incorrect XML value: 'parse error at line 1 pos 23: unexpected END-OF-INPUT' DROP TABLE t1; +# +# Bug#57257 Replace(ExtractValue(...)) causes MySQL crash +# +SET NAMES utf8; +SELECT REPLACE(EXTRACTVALUE('1', '/a'),'ds',''); +REPLACE(EXTRACTVALUE('1', '/a'),'ds','') + +# +# Bug #57820 extractvalue crashes +# +SELECT AVG(DISTINCT EXTRACTVALUE((''),('$@k'))); +AVG(DISTINCT EXTRACTVALUE((''),('$@k'))) +NULL End of 5.1 tests diff --git a/mysql-test/t/ctype_ujis.test b/mysql-test/t/ctype_ujis.test index 400f1301dd3..4c29a2e11a0 100644 --- a/mysql-test/t/ctype_ujis.test +++ b/mysql-test/t/ctype_ujis.test @@ -1209,6 +1209,13 @@ DROP PROCEDURE sp1; DROP TABLE t1; DROP TABLE t2; +--echo # +--echo # Bug#57257 Replace(ExtractValue(...)) causes MySQL crash +--echo # +SET NAMES utf8; +SELECT CONVERT(REPLACE(EXPORT_SET('a','a','a','','a'),'00','') USING ujis); + + set names default; set character_set_database=default; set character_set_server=default; diff --git a/mysql-test/t/xml.test b/mysql-test/t/xml.test index 6e7d38cdfca..a8917fc9fe7 100644 --- a/mysql-test/t/xml.test +++ b/mysql-test/t/xml.test @@ -617,4 +617,15 @@ FROM t1 ORDER BY t1.id; DROP TABLE t1; +--echo # +--echo # Bug#57257 Replace(ExtractValue(...)) causes MySQL crash +--echo # +SET NAMES utf8; +SELECT REPLACE(EXTRACTVALUE('1', '/a'),'ds',''); + +--echo # +--echo # Bug #57820 extractvalue crashes +--echo # +SELECT AVG(DISTINCT EXTRACTVALUE((''),('$@k'))); + --echo End of 5.1 tests diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 8fda281bd9e..fd5c47d25cb 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -904,9 +904,15 @@ String *Item_func_replace::val_str(String *str) search=res2->ptr(); search_end=search+from_length; redo: + DBUG_ASSERT(res->ptr() || !offset); ptr=res->ptr()+offset; strend=res->ptr()+res->length(); - end=strend-from_length+1; + /* + In some cases val_str() can return empty string + with ptr() == NULL and length() == 0. + Let's check strend to avoid overflow. + */ + end= strend ? strend - from_length + 1 : NULL; while (ptr < end) { if (*ptr == *search) diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc index 3e20b90e68e..364311877e0 100644 --- a/sql/item_xmlfunc.cc +++ b/sql/item_xmlfunc.cc @@ -2790,12 +2790,12 @@ String *Item_func_xml_extractvalue::val_str(String *str) null_value= 0; if (!nodeset_func || !(res= args[0]->val_str(str)) || - !parse_xml(res, &pxml)) + !parse_xml(res, &pxml) || + !(res= nodeset_func->val_str(&tmp_value))) { null_value= 1; return 0; } - res= nodeset_func->val_str(&tmp_value); return res; } From e0a8c25438dac90ec697f5edaa712d9681acf96b Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Thu, 11 Nov 2010 11:34:55 +0100 Subject: [PATCH 221/304] Bug#57890: Assertion failed: next_insert_id == 0 with on duplicate key update There was a missed corner case in the partitioning handler, which caused the next_insert_id to be changed in the second level handlers (i.e the hander of a partition), which caused this debug assertion. The solution was to always ensure that only the partitioning level generates auto_increment values, since if it was done within a partition, it may fail to match the partition function. mysql-test/suite/parts/inc/partition_auto_increment.inc: Added tests mysql-test/suite/parts/r/partition_auto_increment_blackhole.result: updated results mysql-test/suite/parts/r/partition_auto_increment_innodb.result: updated results mysql-test/suite/parts/r/partition_auto_increment_memory.result: updated results mysql-test/suite/parts/r/partition_auto_increment_myisam.result: updated results sql/ha_partition.cc: In ::write_row the auto_inc value is generated through handler::update_auto_increment (which calls ::get_auto_increment() if needed). If: * INSERT_ID was set to 0 * it was updated to 0 by 'INSERT ... ON DUPLICATE KEY UPDATE' and changed partitions for the row Then it would try to generate a auto_increment value in the ::write_row, which will trigger the assert. So the solution is to prevent this by, in ha_partition::write_row set auto_inc_field_not_null and add MODE_NO_AUTO_VALUE_ON_ZERO in ha_partition::update_row (when changing partition) temporary set table->next_number_field to NULL which calling the partitions ::write_row(). --- .../parts/inc/partition_auto_increment.inc | 49 +++++++++++++ .../partition_auto_increment_blackhole.result | 32 +++++++++ .../r/partition_auto_increment_innodb.result | 72 +++++++++++++++++++ .../r/partition_auto_increment_memory.result | 72 +++++++++++++++++++ .../r/partition_auto_increment_myisam.result | 72 +++++++++++++++++++ sql/ha_partition.cc | 37 +++++++++- 6 files changed, 332 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/parts/inc/partition_auto_increment.inc b/mysql-test/suite/parts/inc/partition_auto_increment.inc index 102e57d3d04..034460d49ac 100644 --- a/mysql-test/suite/parts/inc/partition_auto_increment.inc +++ b/mysql-test/suite/parts/inc/partition_auto_increment.inc @@ -105,6 +105,30 @@ OPTIMIZE TABLE t1; SHOW CREATE TABLE t1; DROP TABLE t1; +if (!$skip_update) +{ +eval CREATE TABLE t1 +(a INT NULL AUTO_INCREMENT, + UNIQUE KEY (a)) +ENGINE=$engine; +SET LAST_INSERT_ID = 999; +SET INSERT_ID = 0; +INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL; +SELECT LAST_INSERT_ID(); +SELECT * FROM t1; +INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL; +SELECT LAST_INSERT_ID(); +SELECT * FROM t1; +UPDATE t1 SET a = 1 WHERE a IS NULL; +SELECT LAST_INSERT_ID(); +SELECT * FROM t1; +UPDATE t1 SET a = NULL WHERE a = 1; +SELECT LAST_INSERT_ID(); +SELECT * FROM t1; +DROP TABLE t1; +SET INSERT_ID = 1; +} + -- echo # Simple test with NULL eval CREATE TABLE t1 ( c1 INT NOT NULL AUTO_INCREMENT, @@ -831,5 +855,30 @@ SELECT * FROM t ORDER BY c1 ASC; DROP TABLE t; +if (!$skip_update) +{ +eval CREATE TABLE t1 +(a INT NULL AUTO_INCREMENT, + UNIQUE KEY (a)) +ENGINE=$engine +PARTITION BY KEY(a) PARTITIONS 2; +SET LAST_INSERT_ID = 999; +SET INSERT_ID = 0; +INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL; +SELECT LAST_INSERT_ID(); +SELECT * FROM t1; +INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL; +SELECT LAST_INSERT_ID(); +SELECT * FROM t1; +UPDATE t1 SET a = 1 WHERE a IS NULL; +SELECT LAST_INSERT_ID(); +SELECT * FROM t1; +UPDATE t1 SET a = NULL WHERE a = 1; +SELECT LAST_INSERT_ID(); +SELECT * FROM t1; +DROP TABLE t1; +} + + --echo ############################################################################## } diff --git a/mysql-test/suite/parts/r/partition_auto_increment_blackhole.result b/mysql-test/suite/parts/r/partition_auto_increment_blackhole.result index d6ea8ba0fe4..2344f03ce3f 100644 --- a/mysql-test/suite/parts/r/partition_auto_increment_blackhole.result +++ b/mysql-test/suite/parts/r/partition_auto_increment_blackhole.result @@ -120,6 +120,38 @@ t1 CREATE TABLE `t1` ( PRIMARY KEY (`c1`) ) ENGINE=BLACKHOLE DEFAULT CHARSET=latin1 DROP TABLE t1; +CREATE TABLE t1 +(a INT NULL AUTO_INCREMENT, +UNIQUE KEY (a)) +ENGINE='Blackhole'; +SET LAST_INSERT_ID = 999; +SET INSERT_ID = 0; +INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL; +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +999 +SELECT * FROM t1; +a +INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL; +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +999 +SELECT * FROM t1; +a +UPDATE t1 SET a = 1 WHERE a IS NULL; +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +999 +SELECT * FROM t1; +a +UPDATE t1 SET a = NULL WHERE a = 1; +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +999 +SELECT * FROM t1; +a +DROP TABLE t1; +SET INSERT_ID = 1; # Simple test with NULL CREATE TABLE t1 ( c1 INT NOT NULL AUTO_INCREMENT, diff --git a/mysql-test/suite/parts/r/partition_auto_increment_innodb.result b/mysql-test/suite/parts/r/partition_auto_increment_innodb.result index 4cd7aa57417..5fd576322d5 100644 --- a/mysql-test/suite/parts/r/partition_auto_increment_innodb.result +++ b/mysql-test/suite/parts/r/partition_auto_increment_innodb.result @@ -136,6 +136,42 @@ t1 CREATE TABLE `t1` ( PRIMARY KEY (`c1`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 DROP TABLE t1; +CREATE TABLE t1 +(a INT NULL AUTO_INCREMENT, +UNIQUE KEY (a)) +ENGINE='InnoDB'; +SET LAST_INSERT_ID = 999; +SET INSERT_ID = 0; +INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL; +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +999 +SELECT * FROM t1; +a +1 +INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL; +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +999 +SELECT * FROM t1; +a +0 +UPDATE t1 SET a = 1 WHERE a IS NULL; +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +999 +SELECT * FROM t1; +a +0 +UPDATE t1 SET a = NULL WHERE a = 1; +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +999 +SELECT * FROM t1; +a +0 +DROP TABLE t1; +SET INSERT_ID = 1; # Simple test with NULL CREATE TABLE t1 ( c1 INT NOT NULL AUTO_INCREMENT, @@ -1023,4 +1059,40 @@ c1 c2 2 20 127 40 DROP TABLE t; +CREATE TABLE t1 +(a INT NULL AUTO_INCREMENT, +UNIQUE KEY (a)) +ENGINE='InnoDB' +PARTITION BY KEY(a) PARTITIONS 2; +SET LAST_INSERT_ID = 999; +SET INSERT_ID = 0; +INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL; +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +999 +SELECT * FROM t1; +a +1 +INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL; +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +999 +SELECT * FROM t1; +a +0 +UPDATE t1 SET a = 1 WHERE a IS NULL; +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +999 +SELECT * FROM t1; +a +0 +UPDATE t1 SET a = NULL WHERE a = 1; +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +999 +SELECT * FROM t1; +a +0 +DROP TABLE t1; ############################################################################## diff --git a/mysql-test/suite/parts/r/partition_auto_increment_memory.result b/mysql-test/suite/parts/r/partition_auto_increment_memory.result index 1a27d1c2e52..c3a5073b029 100644 --- a/mysql-test/suite/parts/r/partition_auto_increment_memory.result +++ b/mysql-test/suite/parts/r/partition_auto_increment_memory.result @@ -136,6 +136,42 @@ t1 CREATE TABLE `t1` ( PRIMARY KEY (`c1`) ) ENGINE=MEMORY AUTO_INCREMENT=102 DEFAULT CHARSET=latin1 DROP TABLE t1; +CREATE TABLE t1 +(a INT NULL AUTO_INCREMENT, +UNIQUE KEY (a)) +ENGINE='Memory'; +SET LAST_INSERT_ID = 999; +SET INSERT_ID = 0; +INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL; +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +999 +SELECT * FROM t1; +a +1 +INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL; +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +999 +SELECT * FROM t1; +a +0 +UPDATE t1 SET a = 1 WHERE a IS NULL; +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +999 +SELECT * FROM t1; +a +0 +UPDATE t1 SET a = NULL WHERE a = 1; +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +999 +SELECT * FROM t1; +a +0 +DROP TABLE t1; +SET INSERT_ID = 1; # Simple test with NULL CREATE TABLE t1 ( c1 INT NOT NULL AUTO_INCREMENT, @@ -1051,4 +1087,40 @@ c1 c2 2 20 127 40 DROP TABLE t; +CREATE TABLE t1 +(a INT NULL AUTO_INCREMENT, +UNIQUE KEY (a)) +ENGINE='Memory' +PARTITION BY KEY(a) PARTITIONS 2; +SET LAST_INSERT_ID = 999; +SET INSERT_ID = 0; +INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL; +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +999 +SELECT * FROM t1; +a +1 +INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL; +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +999 +SELECT * FROM t1; +a +0 +UPDATE t1 SET a = 1 WHERE a IS NULL; +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +999 +SELECT * FROM t1; +a +0 +UPDATE t1 SET a = NULL WHERE a = 1; +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +999 +SELECT * FROM t1; +a +0 +DROP TABLE t1; ############################################################################## diff --git a/mysql-test/suite/parts/r/partition_auto_increment_myisam.result b/mysql-test/suite/parts/r/partition_auto_increment_myisam.result index 9885c78a921..ad440155d33 100644 --- a/mysql-test/suite/parts/r/partition_auto_increment_myisam.result +++ b/mysql-test/suite/parts/r/partition_auto_increment_myisam.result @@ -136,6 +136,42 @@ t1 CREATE TABLE `t1` ( PRIMARY KEY (`c1`) ) ENGINE=MyISAM AUTO_INCREMENT=102 DEFAULT CHARSET=latin1 DROP TABLE t1; +CREATE TABLE t1 +(a INT NULL AUTO_INCREMENT, +UNIQUE KEY (a)) +ENGINE='MyISAM'; +SET LAST_INSERT_ID = 999; +SET INSERT_ID = 0; +INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL; +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +999 +SELECT * FROM t1; +a +1 +INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL; +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +999 +SELECT * FROM t1; +a +0 +UPDATE t1 SET a = 1 WHERE a IS NULL; +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +999 +SELECT * FROM t1; +a +0 +UPDATE t1 SET a = NULL WHERE a = 1; +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +999 +SELECT * FROM t1; +a +0 +DROP TABLE t1; +SET INSERT_ID = 1; # Simple test with NULL CREATE TABLE t1 ( c1 INT NOT NULL AUTO_INCREMENT, @@ -1070,4 +1106,40 @@ c1 c2 2 20 127 40 DROP TABLE t; +CREATE TABLE t1 +(a INT NULL AUTO_INCREMENT, +UNIQUE KEY (a)) +ENGINE='MyISAM' +PARTITION BY KEY(a) PARTITIONS 2; +SET LAST_INSERT_ID = 999; +SET INSERT_ID = 0; +INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL; +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +999 +SELECT * FROM t1; +a +1 +INSERT INTO t1 SET a = 1 ON DUPLICATE KEY UPDATE a = NULL; +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +999 +SELECT * FROM t1; +a +0 +UPDATE t1 SET a = 1 WHERE a IS NULL; +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +999 +SELECT * FROM t1; +a +0 +UPDATE t1 SET a = NULL WHERE a = 1; +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +999 +SELECT * FROM t1; +a +0 +DROP TABLE t1; ############################################################################## diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 24c0f3e71f2..607f4ce2143 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -3050,7 +3050,9 @@ int ha_partition::write_row(uchar * buf) my_bitmap_map *old_map; HA_DATA_PARTITION *ha_data= (HA_DATA_PARTITION*) table_share->ha_data; THD *thd= ha_thd(); - timestamp_auto_set_type orig_timestamp_type= table->timestamp_field_type; + timestamp_auto_set_type saved_timestamp_type= table->timestamp_field_type; + ulong saved_sql_mode= thd->variables.sql_mode; + bool saved_auto_inc_field_not_null= table->auto_increment_field_not_null; #ifdef NOT_NEEDED uchar *rec0= m_rec0; #endif @@ -3086,6 +3088,22 @@ int ha_partition::write_row(uchar * buf) */ if (error) goto exit; + + /* + Don't allow generation of auto_increment value the partitions handler. + If a partitions handler would change the value, then it might not + match the partition any longer. + This can occur if 'SET INSERT_ID = 0; INSERT (NULL)', + So allow this by adding 'MODE_NO_AUTO_VALUE_ON_ZERO' to sql_mode. + The partitions handler::next_insert_id must always be 0. Otherwise + we need to forward release_auto_increment, or reset it for all + partitions. + */ + if (table->next_number_field->val_int() == 0) + { + table->auto_increment_field_not_null= TRUE; + thd->variables.sql_mode|= MODE_NO_AUTO_VALUE_ON_ZERO; + } } old_map= dbug_tmp_use_all_columns(table, table->read_set); @@ -3119,7 +3137,9 @@ int ha_partition::write_row(uchar * buf) set_auto_increment_if_higher(table->next_number_field); reenable_binlog(thd); exit: - table->timestamp_field_type= orig_timestamp_type; + thd->variables.sql_mode= saved_sql_mode; + table->auto_increment_field_not_null= saved_auto_inc_field_not_null; + table->timestamp_field_type= saved_timestamp_type; DBUG_RETURN(error); } @@ -3186,11 +3206,24 @@ int ha_partition::update_row(const uchar *old_data, uchar *new_data) } else { + Field *saved_next_number_field= table->next_number_field; + /* + Don't allow generation of auto_increment value for update. + table->next_number_field is never set on UPDATE. + But is set for INSERT ... ON DUPLICATE KEY UPDATE, + and since update_row() does not generate or update an auto_inc value, + we cannot have next_number_field set when moving a row + to another partition with write_row(), since that could + generate/update the auto_inc value. + This gives the same behavior for partitioned vs non partitioned tables. + */ + table->next_number_field= NULL; DBUG_PRINT("info", ("Update from partition %d to partition %d", old_part_id, new_part_id)); tmp_disable_binlog(thd); /* Do not replicate the low-level changes. */ error= m_file[new_part_id]->ha_write_row(new_data); reenable_binlog(thd); + table->next_number_field= saved_next_number_field; if (error) goto exit; From f9c2f7cd016f45f8aef64af46c7e2ae270979548 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Thu, 11 Nov 2010 13:11:52 +0200 Subject: [PATCH 222/304] Remove unused parameter has_dict_mutex of dict_update_statistics_low() Also delete dict_update_statistics() and rename dict_update_statistics_low() to dict_update_statistics() because the only thing that distinguished those two functions was the removed parameter. --- storage/innodb_plugin/dict/dict0dict.c | 29 ++++------------------- storage/innodb_plugin/dict/dict0load.c | 6 ++--- storage/innodb_plugin/include/dict0dict.h | 16 +------------ 3 files changed, 7 insertions(+), 44 deletions(-) diff --git a/storage/innodb_plugin/dict/dict0dict.c b/storage/innodb_plugin/dict/dict0dict.c index 774e7f213e8..eb3169bd176 100644 --- a/storage/innodb_plugin/dict/dict0dict.c +++ b/storage/innodb_plugin/dict/dict0dict.c @@ -4213,16 +4213,13 @@ Calculates new estimates for table and index statistics. The statistics are used in query optimization. */ UNIV_INTERN void -dict_update_statistics_low( -/*=======================*/ +dict_update_statistics( +/*===================*/ dict_table_t* table, /*!< in/out: table */ - ibool only_calc_if_missing_stats,/*!< in: only + ibool only_calc_if_missing_stats)/*!< in: only update/recalc the stats if they have not been initialized yet, otherwise do nothing */ - ibool has_dict_mutex __attribute__((unused))) - /*!< in: TRUE if the caller has the - dictionary mutex */ { dict_index_t* index; ulint sum_of_index_sizes = 0; @@ -4316,22 +4313,6 @@ dict_update_statistics_low( dict_table_stats_unlock(table, RW_X_LATCH); } -/*********************************************************************//** -Calculates new estimates for table and index statistics. The statistics -are used in query optimization. */ -UNIV_INTERN -void -dict_update_statistics( -/*===================*/ - dict_table_t* table, /*!< in/out: table */ - ibool only_calc_if_missing_stats)/*!< in: only - update/recalc the stats if they have - not been initialized yet, otherwise - do nothing */ -{ - dict_update_statistics_low(table, only_calc_if_missing_stats, FALSE); -} - /**********************************************************************//** Prints info of a foreign key constraint. */ static @@ -4409,9 +4390,7 @@ dict_table_print_low( ut_ad(mutex_own(&(dict_sys->mutex))); - dict_update_statistics_low(table, - FALSE /* update even if initialized */, - TRUE /* we have the dict mutex */); + dict_update_statistics(table, FALSE /* update even if initialized */); dict_table_stats_lock(table, RW_S_LATCH); diff --git a/storage/innodb_plugin/dict/dict0load.c b/storage/innodb_plugin/dict/dict0load.c index 3baa12b4235..c3825902536 100644 --- a/storage/innodb_plugin/dict/dict0load.c +++ b/storage/innodb_plugin/dict/dict0load.c @@ -222,10 +222,8 @@ loop: is no index */ if (dict_table_get_first_index(table)) { - dict_update_statistics_low( - table, - FALSE /* update even if initialized */, - TRUE /* we have the dict mutex */); + dict_update_statistics(table, FALSE /* update + even if initialized */); } dict_table_print_low(table); diff --git a/storage/innodb_plugin/include/dict0dict.h b/storage/innodb_plugin/include/dict0dict.h index 7b02111fb87..fdb3bd5d50c 100644 --- a/storage/innodb_plugin/include/dict0dict.h +++ b/storage/innodb_plugin/include/dict0dict.h @@ -1054,23 +1054,9 @@ Calculates new estimates for table and index statistics. The statistics are used in query optimization. */ UNIV_INTERN void -dict_update_statistics_low( -/*=======================*/ - dict_table_t* table, /*!< in/out: table */ - ibool only_calc_if_missing_stats,/*!< in: only - update/recalc the stats if they have - not been initialized yet, otherwise - do nothing */ - ibool has_dict_mutex);/*!< in: TRUE if the caller has the - dictionary mutex */ -/*********************************************************************//** -Calculates new estimates for table and index statistics. The statistics -are used in query optimization. */ -UNIV_INTERN -void dict_update_statistics( /*===================*/ - dict_table_t* table, /*!< in/out: table */ + dict_table_t* table, /*!< in/out: table */ ibool only_calc_if_missing_stats);/*!< in: only update/recalc the stats if they have not been initialized yet, otherwise From 6272025ad408a81f31d3adbb28c8a12bd00d2890 Mon Sep 17 00:00:00 2001 From: Marc Alff Date: Thu, 11 Nov 2010 12:34:46 +0100 Subject: [PATCH 223/304] Bug#58003 Segfault on CHECKSUM TABLE performance_schema.EVENTS_WAITS_HISTORY_LONG EXTENDED This fix is a follow up on the fix for similar issue 56761. When sanitizing data read from the events_waits_history_long table, the code needs also to sanitize the schema_name / object_name / file_name pointers, because such pointers could also hold invalid values. Checking the string length alone was required but not sufficient. This fix verifies that: - the table schema and table name used in table io events - the file name used in file io events are valid pointers before dereferencing these pointers. --- storage/perfschema/pfs_global.h | 16 ++++++ storage/perfschema/pfs_instr.cc | 23 +++++++- storage/perfschema/pfs_instr.h | 1 + storage/perfschema/pfs_instr_class.cc | 70 ++++++++++++++++++++---- storage/perfschema/pfs_instr_class.h | 2 + storage/perfschema/table_events_waits.cc | 21 +++++-- 6 files changed, 112 insertions(+), 21 deletions(-) diff --git a/storage/perfschema/pfs_global.h b/storage/perfschema/pfs_global.h index 6050612e24c..c0c0490a380 100644 --- a/storage/perfschema/pfs_global.h +++ b/storage/perfschema/pfs_global.h @@ -79,5 +79,21 @@ inline uint randomized_index(const void *ptr, uint max_size) void pfs_print_error(const char *format, ...); +/** + Given an array defined as T ARRAY[MAX], + check that an UNSAFE pointer actually points to an element + within the array. +*/ +#define SANITIZE_ARRAY_BODY(T, ARRAY, MAX, UNSAFE) \ + intptr offset; \ + if ((&ARRAY[0] <= UNSAFE) && \ + (UNSAFE < &ARRAY[MAX])) \ + { \ + offset= ((intptr) UNSAFE - (intptr) ARRAY) % sizeof(T); \ + if (offset == 0) \ + return UNSAFE; \ + } \ + return NULL + #endif diff --git a/storage/perfschema/pfs_instr.cc b/storage/perfschema/pfs_instr.cc index 0c7b25a03de..904efc2aff4 100644 --- a/storage/perfschema/pfs_instr.cc +++ b/storage/perfschema/pfs_instr.cc @@ -758,9 +758,26 @@ PFS_thread* create_thread(PFS_thread_class *klass, const void *identity, */ PFS_thread *sanitize_thread(PFS_thread *unsafe) { - if ((&thread_array[0] <= unsafe) && - (unsafe < &thread_array[thread_max])) - return unsafe; + SANITIZE_ARRAY_BODY(PFS_thread, thread_array, thread_max, unsafe); +} + +const char *sanitize_file_name(const char *unsafe) +{ + intptr ptr= (intptr) unsafe; + intptr first= (intptr) &file_array[0]; + intptr last= (intptr) &file_array[file_max]; + + /* Check if unsafe points inside file_array[] */ + if (likely((first <= ptr) && (ptr < last))) + { + /* Check if unsafe points to PFS_file::m_filename */ + intptr offset= (ptr - first) % sizeof(PFS_file); + intptr valid_offset= my_offsetof(PFS_file, m_filename[0]); + if (likely(offset == valid_offset)) + { + return unsafe; + } + } return NULL; } diff --git a/storage/perfschema/pfs_instr.h b/storage/perfschema/pfs_instr.h index 791e2cd1f8d..2f6b729628e 100644 --- a/storage/perfschema/pfs_instr.h +++ b/storage/perfschema/pfs_instr.h @@ -227,6 +227,7 @@ struct PFS_thread }; PFS_thread *sanitize_thread(PFS_thread *unsafe); +const char *sanitize_file_name(const char *unsafe); PFS_single_stat_chain* find_per_thread_mutex_class_wait_stat(PFS_thread *thread, diff --git a/storage/perfschema/pfs_instr_class.cc b/storage/perfschema/pfs_instr_class.cc index 48547f73628..d99ca4d513c 100644 --- a/storage/perfschema/pfs_instr_class.cc +++ b/storage/perfschema/pfs_instr_class.cc @@ -543,15 +543,9 @@ PFS_mutex_class *find_mutex_class(PFS_sync_key key) FIND_CLASS_BODY(key, mutex_class_allocated_count, mutex_class_array); } -#define SANITIZE_ARRAY_BODY(ARRAY, MAX, UNSAFE) \ - if ((&ARRAY[0] <= UNSAFE) && \ - (UNSAFE < &ARRAY[MAX])) \ - return UNSAFE; \ - return NULL - PFS_mutex_class *sanitize_mutex_class(PFS_mutex_class *unsafe) { - SANITIZE_ARRAY_BODY(mutex_class_array, mutex_class_max, unsafe); + SANITIZE_ARRAY_BODY(PFS_mutex_class, mutex_class_array, mutex_class_max, unsafe); } /** @@ -566,7 +560,7 @@ PFS_rwlock_class *find_rwlock_class(PFS_sync_key key) PFS_rwlock_class *sanitize_rwlock_class(PFS_rwlock_class *unsafe) { - SANITIZE_ARRAY_BODY(rwlock_class_array, rwlock_class_max, unsafe); + SANITIZE_ARRAY_BODY(PFS_rwlock_class, rwlock_class_array, rwlock_class_max, unsafe); } /** @@ -581,7 +575,7 @@ PFS_cond_class *find_cond_class(PFS_sync_key key) PFS_cond_class *sanitize_cond_class(PFS_cond_class *unsafe) { - SANITIZE_ARRAY_BODY(cond_class_array, cond_class_max, unsafe); + SANITIZE_ARRAY_BODY(PFS_cond_class, cond_class_array, cond_class_max, unsafe); } /** @@ -636,7 +630,7 @@ PFS_thread_class *find_thread_class(PFS_sync_key key) PFS_thread_class *sanitize_thread_class(PFS_thread_class *unsafe) { - SANITIZE_ARRAY_BODY(thread_class_array, thread_class_max, unsafe); + SANITIZE_ARRAY_BODY(PFS_thread_class, thread_class_array, thread_class_max, unsafe); } /** @@ -687,7 +681,7 @@ PFS_file_class *find_file_class(PFS_file_key key) PFS_file_class *sanitize_file_class(PFS_file_class *unsafe) { - SANITIZE_ARRAY_BODY(file_class_array, file_class_max, unsafe); + SANITIZE_ARRAY_BODY(PFS_file_class, file_class_array, file_class_max, unsafe); } /** @@ -820,7 +814,59 @@ search: PFS_table_share *sanitize_table_share(PFS_table_share *unsafe) { - SANITIZE_ARRAY_BODY(table_share_array, table_share_max, unsafe); + SANITIZE_ARRAY_BODY(PFS_table_share, table_share_array, table_share_max, unsafe); +} + +const char *sanitize_table_schema_name(const char *unsafe) +{ + intptr ptr= (intptr) unsafe; + intptr first= (intptr) &table_share_array[0]; + intptr last= (intptr) &table_share_array[table_share_max]; + + PFS_table_share dummy; + + /* Check if unsafe points inside table_share_array[] */ + if (likely((first <= ptr) && (ptr < last))) + { + intptr offset= (ptr - first) % sizeof(PFS_table_share); + intptr from= my_offsetof(PFS_table_share, m_key.m_hash_key); + intptr len= sizeof(dummy.m_key.m_hash_key); + /* Check if unsafe points inside PFS_table_share::m_key::m_hash_key */ + if (likely((from <= offset) && (offset < from + len))) + { + PFS_table_share *base= (PFS_table_share*) (ptr - offset); + /* Check if unsafe really is the schema name */ + if (likely(base->m_schema_name == unsafe)) + return unsafe; + } + } + return NULL; +} + +const char *sanitize_table_object_name(const char *unsafe) +{ + intptr ptr= (intptr) unsafe; + intptr first= (intptr) &table_share_array[0]; + intptr last= (intptr) &table_share_array[table_share_max]; + + PFS_table_share dummy; + + /* Check if unsafe points inside table_share_array[] */ + if (likely((first <= ptr) && (ptr < last))) + { + intptr offset= (ptr - first) % sizeof(PFS_table_share); + intptr from= my_offsetof(PFS_table_share, m_key.m_hash_key); + intptr len= sizeof(dummy.m_key.m_hash_key); + /* Check if unsafe points inside PFS_table_share::m_key::m_hash_key */ + if (likely((from <= offset) && (offset < from + len))) + { + PFS_table_share *base= (PFS_table_share*) (ptr - offset); + /* Check if unsafe really is the table name */ + if (likely(base->m_table_name == unsafe)) + return unsafe; + } + } + return NULL; } static void reset_mutex_class_waits(void) diff --git a/storage/perfschema/pfs_instr_class.h b/storage/perfschema/pfs_instr_class.h index bd6560dbb55..107db628226 100644 --- a/storage/perfschema/pfs_instr_class.h +++ b/storage/perfschema/pfs_instr_class.h @@ -222,6 +222,8 @@ PFS_thread_class *find_thread_class(PSI_thread_key key); PFS_thread_class *sanitize_thread_class(PFS_thread_class *unsafe); PFS_file_class *find_file_class(PSI_file_key key); PFS_file_class *sanitize_file_class(PFS_file_class *unsafe); +const char *sanitize_table_schema_name(const char *unsafe); +const char *sanitize_table_object_name(const char *unsafe); PFS_table_share *find_or_create_table_share(PFS_thread *thread, const char *schema_name, diff --git a/storage/perfschema/table_events_waits.cc b/storage/perfschema/table_events_waits.cc index d55f0fc2dc8..8408cc55975 100644 --- a/storage/perfschema/table_events_waits.cc +++ b/storage/perfschema/table_events_waits.cc @@ -194,6 +194,9 @@ void table_events_waits_common::make_row(bool thread_own_wait, PFS_instr_class *safe_class; const char *base; const char *safe_source_file; + const char *safe_table_schema_name; + const char *safe_table_object_name; + const char *safe_file_name; m_row_exists= false; safe_thread= sanitize_thread(pfs_thread); @@ -252,15 +255,19 @@ void table_events_waits_common::make_row(bool thread_own_wait, m_row.m_object_type= "TABLE"; m_row.m_object_type_length= 5; m_row.m_object_schema_length= wait->m_schema_name_length; + safe_table_schema_name= sanitize_table_schema_name(wait->m_schema_name); if (unlikely((m_row.m_object_schema_length == 0) || - (m_row.m_object_schema_length > sizeof(m_row.m_object_schema)))) + (m_row.m_object_schema_length > sizeof(m_row.m_object_schema)) || + (safe_table_schema_name == NULL))) return; - memcpy(m_row.m_object_schema, wait->m_schema_name, m_row.m_object_schema_length); + memcpy(m_row.m_object_schema, safe_table_schema_name, m_row.m_object_schema_length); m_row.m_object_name_length= wait->m_object_name_length; + safe_table_object_name= sanitize_table_object_name(wait->m_object_name); if (unlikely((m_row.m_object_name_length == 0) || - (m_row.m_object_name_length > sizeof(m_row.m_object_name)))) + (m_row.m_object_name_length > sizeof(m_row.m_object_name)) || + (safe_table_object_name == NULL))) return; - memcpy(m_row.m_object_name, wait->m_object_name, m_row.m_object_name_length); + memcpy(m_row.m_object_name, safe_table_object_name, m_row.m_object_name_length); safe_class= &global_table_class; break; case WAIT_CLASS_FILE: @@ -268,10 +275,12 @@ void table_events_waits_common::make_row(bool thread_own_wait, m_row.m_object_type_length= 4; m_row.m_object_schema_length= 0; m_row.m_object_name_length= wait->m_object_name_length; + safe_file_name= sanitize_file_name(wait->m_object_name); if (unlikely((m_row.m_object_name_length == 0) || - (m_row.m_object_name_length > sizeof(m_row.m_object_name)))) + (m_row.m_object_name_length > sizeof(m_row.m_object_name)) || + (safe_file_name == NULL))) return; - memcpy(m_row.m_object_name, wait->m_object_name, m_row.m_object_name_length); + memcpy(m_row.m_object_name, safe_file_name, m_row.m_object_name_length); safe_class= sanitize_file_class((PFS_file_class*) wait->m_class); break; case NO_WAIT_CLASS: From 53f6e8bc9a270f4e4eaf8ef0695a36e72eec951a Mon Sep 17 00:00:00 2001 From: Sunanda Menon Date: Thu, 11 Nov 2010 13:32:12 +0100 Subject: [PATCH 224/304] #57746: Win directory of source distribution - out-of-date files / support for new files ( Based on review comments) --- win/README | 110 +---------------------------------------------------- 1 file changed, 2 insertions(+), 108 deletions(-) diff --git a/win/README b/win/README index 9c8ca9a87bc..e5363cf8c8d 100644 --- a/win/README +++ b/win/README @@ -1,114 +1,8 @@ Windows building readme ====================================== -----------------IMPORTANT---------------------------- -This readme outlines the instructions for building -MySQL for Windows staring from version 5.1. -This readme does not apply to MySQL versions 5.0 -or ealier. ------------------------------------------------------ - The Windows build system uses a tool named CMake to generate build files for a variety of project systems. This tool is combined with a set of jscript files to enable building of MySQL for Windows directly out of a bzr clone. -For relevant information, please refer to http://forge.mysql.com/wiki/CMake -The steps required are below. - -Step 1: -------- - -Install a Windows C++ compiler. If you don't have one, you can use -the free compiler "Visual C++ 2005 express edition", which from Cmake -point of view is same as Visual studio 8: -http://msdn.microsoft.com/vstudio/express/ - -Step 2 ------- -Download and install CMake. It can be downloaded from http://www.cmake.org. -Once it is installed, modify your path to make sure you can execute -the cmake binary. - -Step 3 ------- -Download and install bison for Windows. It can be downloaded from -http://gnuwin32.sourceforge.net/packages/bison.htm. Please download using -the link named "Complete package, excluding sources". This includes an -installer that will install bison. After the installer finishes, modify -your path so that you can execute bison. - -(As an alternative you can take the sql_yacc.yy and sql_yacc.h files from a -matching mysql tar distribution and drop them into the sql directory just -before you start the build) - -Step 4 ------- -One of the nice CMake features is "out-of-source" build support, which -means not building in the source directory, but in dedicated build -directory. This keeps the source directory clean and allows for more than -single build tree for the same source tree (e.g debug and release, 32 and -64 bit etc). We'll create subdirectory "bld" in the source directory for -this purpose. Clone your bzr tree to any location you like. - -Step 5 ------- -From the root of your installation directory use cmake . -L to see the -various configuration parameters. - -So the command line could look like: - -cmake .. -G "target" -DWITH_INNOBASE_STORAGE_ENGINE=1 - -The recommended way of configuring would be to use -DBUILD_CONFIG=mysql_release -to build binaries exactly the same as the official MySQL releases. - -Step 6 ------- - -From the root of your installation directory/bzr clone, you can -use cmake to compile the sources. Use cmake --help when necessary. -Before you start building the sources, please remove the old build area -created from an earlier run and start afresh. - -C:\> del bld -C:\> md bld -C:\> cd bld -C:\> cmake .. -G "target name" -DBUILD_CONFIG=mysql_release - - -For Example: -To generate the Win64 project files using Visual Studio 9, you would run -cmake .. -G "Visual Studio 9 2008 Win64" - -Other target names supported using CMake 2.6 patch 4 are: - - Visual Studio 7 "Visual Studio 7 .NET 2003" - Visual Studio 8 "Visual Studio 8 2005" - Visual Studio 8 (64 bit) "Visual Studio 8 2005 Win64" - Visual Studio 9 "Visual Studio 9 2008" - Visual Studio 9 (64 bit) "Visual Studio 9 2008 Win64" - -For generating project files using Visual Studio 10, you need CMake 2.8 -or higher and corresponding target names are - Visual Studio 10 "Visual Studio 10" - Visual Studio 10 (64 bit) "Visual Studio 10 Win64" - -Step 7 ------- -From the root of your bzr clone, start your build. - -For Visual Studio, execute mysql.sln. This will start the IDE -and you can click the build solution menu option. - -Alternatively, you could start the build from command line as follows - -devenv mysql.sln /build relwithdebinfo - -Current issues --------------- -1. After changing configuration (eg. adding or removing a storage engine), it -may be necessary to clean the build tree to remove any stale objects. - -2. To use Visual C++ Express Edition you also need to install the Platform SDK. -Please see this link: http://msdn.microsoft.com/vstudio/express/visualc/usingpsdk/ -At step 5 you only need to add the libraries advapi32.lib and user32.lib to -the file "corewin_express.vsprops" in order to avoid link errors. +For relevant information and/or for building binaries from source distribution, +please refer to http://forge.mysql.com/wiki/CMake From 4bb4eb800e11aa1cf27ce9b5773aefc923f7c67e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 11 Nov 2010 15:12:39 +0200 Subject: [PATCH 225/304] Fix a debug assertion failure in the Bug#57802 fix. thr_local_create(): Initialize local->slot_no to ULINT_UNDEFINED. thr_local_validate(): Allow local->slot_no to be ULINT_UNDEFINED. --- storage/innodb_plugin/thr/thr0loc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/storage/innodb_plugin/thr/thr0loc.c b/storage/innodb_plugin/thr/thr0loc.c index 2bc6295dd70..94b84b11fbe 100644 --- a/storage/innodb_plugin/thr/thr0loc.c +++ b/storage/innodb_plugin/thr/thr0loc.c @@ -82,7 +82,8 @@ thr_local_validate( const thr_local_t* local) /*!< in: data to validate */ { ut_ad(local->magic_n == THR_LOCAL_MAGIC_N); - ut_ad(local->slot_no < OS_THREAD_MAX_N); + ut_ad(local->slot_no == ULINT_UNDEFINED + || local->slot_no < OS_THREAD_MAX_N); ut_ad(local->in_ibuf == FALSE || local->in_ibuf == TRUE); return(TRUE); } @@ -206,7 +207,7 @@ thr_local_create(void) local->id = os_thread_get_curr_id(); local->handle = os_thread_get_curr(); local->magic_n = THR_LOCAL_MAGIC_N; - + local->slot_no = ULINT_UNDEFINED; local->in_ibuf = FALSE; mutex_enter(&thr_local_mutex); From 6bf6272fdabf78e62f04fbcafb1d1e7dee2b27c2 Mon Sep 17 00:00:00 2001 From: Dmitry Lenev Date: Thu, 11 Nov 2010 20:11:05 +0300 Subject: [PATCH 226/304] Patch that refactors global read lock implementation and fixes bug #57006 "Deadlock between HANDLER and FLUSH TABLES WITH READ LOCK" and bug #54673 "It takes too long to get readlock for 'FLUSH TABLES WITH READ LOCK'". The first bug manifested itself as a deadlock which occurred when a connection, which had some table open through HANDLER statement, tried to update some data through DML statement while another connection tried to execute FLUSH TABLES WITH READ LOCK concurrently. What happened was that FTWRL in the second connection managed to perform first step of GRL acquisition and thus blocked all upcoming DML. After that it started to wait for table open through HANDLER statement to be flushed. When the first connection tried to execute DML it has started to wait for GRL/the second connection creating deadlock. The second bug manifested itself as starvation of FLUSH TABLES WITH READ LOCK statements in cases when there was a constant stream of concurrent DML statements (in two or more connections). This has happened because requests for protection against GRL which were acquired by DML statements were ignoring presence of pending GRL and thus the latter was starved. This patch solves both these problems by re-implementing GRL using metadata locks. Similar to the old implementation acquisition of GRL in new implementation is two-step. During the first step we block all concurrent DML and DDL statements by acquiring global S metadata lock (each DML and DDL statement acquires global IX lock for its duration). During the second step we block commits by acquiring global S lock in COMMIT namespace (commit code acquires global IX lock in this namespace). Note that unlike in old implementation acquisition of protection against GRL in DML and DDL is semi-automatic. We assume that any statement which should be blocked by GRL will either open and acquires write-lock on tables or acquires metadata locks on objects it is going to modify. For any such statement global IX metadata lock is automatically acquired for its duration. The first problem is solved because waits for GRL become visible to deadlock detector in metadata locking subsystem and thus deadlocks like one in the first bug become impossible. The second problem is solved because global S locks which are used for GRL implementation are given preference over IX locks which are acquired by concurrent DML (and we can switch to fair scheduling in future if needed). Important change: FTWRL/GRL no longer blocks DML and DDL on temporary tables. Before this patch behavior was not consistent in this respect: in some cases DML/DDL statements on temporary tables were blocked while in others they were not. Since the main use cases for FTWRL are various forms of backups and temporary tables are not preserved during backups we have opted for consistently allowing DML/DDL on temporary tables during FTWRL/GRL. Important change: This patch changes thread state names which are used when DML/DDL of FTWRL is waiting for global read lock. It is now either "Waiting for global read lock" or "Waiting for commit lock" depending on the stage on which FTWRL is. Incompatible change: To solve deadlock in events code which was exposed by this patch we have to replace LOCK_event_metadata mutex with metadata locks on events. As result we have to prohibit DDL on events under LOCK TABLES. This patch also adds extensive test coverage for interaction of DML/DDL and FTWRL. Performance of new and old global read lock implementations in sysbench tests were compared. There were no significant difference between new and old implementations. mysql-test/include/check_ftwrl_compatible.inc: Added helper script which allows to check that a statement is compatible with FLUSH TABLES WITH READ LOCK. mysql-test/include/check_ftwrl_incompatible.inc: Added helper script which allows to check that a statement is incompatible with FLUSH TABLES WITH READ LOCK. mysql-test/include/handler.inc: Adjusted test case to the fact that now DROP TABLE closes open HANDLERs for the table to be dropped before checking if there active FTWRL in this connection. mysql-test/include/wait_show_condition.inc: Fixed small error in the timeout message. The correct name of variable used as parameter for this script is "$condition" and not "$wait_condition". mysql-test/r/delayed.result: Added test coverage for scenario which triggered assert in metadata locking subsystem. mysql-test/r/events_2.result: Updated test results after prohibiting event DDL operations under LOCK TABLES. mysql-test/r/flush.result: Added test coverage for bug #57006 "Deadlock between HANDLER and FLUSH TABLES WITH READ LOCK". mysql-test/r/flush_read_lock.result: Added test coverage for various aspects of FLUSH TABLES WITH READ LOCK functionality. mysql-test/r/flush_read_lock_kill.result: Adjusted test case after replacing custom global read lock implementation with one based on metadata locks. Use new debug_sync point. Do not disable concurrent inserts as now InnoDB we always use InnoDB table. mysql-test/r/handler_innodb.result: Adjusted test case to the fact that now DROP TABLE closes open HANDLERs for the table to be dropped before checking if there active FTWRL in this connection. mysql-test/r/handler_myisam.result: Adjusted test case to the fact that now DROP TABLE closes open HANDLERs for the table to be dropped before checking if there active FTWRL in this connection. mysql-test/r/mdl_sync.result: Adjusted test case after replacing custom global read lock implementation with one based on metadata locks. Replaced usage of GRL-specific debug_sync's with appropriate sync points in MDL subsystem. mysql-test/suite/perfschema/r/dml_setup_instruments.result: Updated test results after removing global COND_global_read_lock condition variable. mysql-test/suite/perfschema/r/func_file_io.result: Ensure that this test doesn't affect subsequent tests. At the end of its execution enable back P_S instrumentation which this test disables at some point. mysql-test/suite/perfschema/r/func_mutex.result: Ensure that this test doesn't affect subsequent tests. At the end of its execution enable back P_S instrumentation which this test disables at some point. mysql-test/suite/perfschema/r/global_read_lock.result: Adjusted test case to take into account that new GRL implementation is based on MDL. mysql-test/suite/perfschema/r/server_init.result: Adjusted test case after replacing custom global read lock implementation with one based on MDL and replacing LOCK_event_metadata mutex with metadata lock. mysql-test/suite/perfschema/t/func_file_io.test: Ensure that this test doesn't affect subsequent tests. At the end of its execution enable back P_S instrumentation which this test disables at some point. mysql-test/suite/perfschema/t/func_mutex.test: Ensure that this test doesn't affect subsequent tests. At the end of its execution enable back P_S instrumentation which this test disables at some point. mysql-test/suite/perfschema/t/global_read_lock.test: Adjusted test case to take into account that new GRL implementation is based on MDL. mysql-test/suite/perfschema/t/server_init.test: Adjusted test case after replacing custom global read lock implementation with one based on MDL and replacing LOCK_event_metadata mutex with metadata lock. mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result: Updated test results after prohibiting event DDL under LOCK TABLES. mysql-test/t/delayed.test: Added test coverage for scenario which triggered assert in metadata locking subsystem. mysql-test/t/events_2.test: Updated test case after prohibiting event DDL operations under LOCK TABLES. mysql-test/t/flush.test: Added test coverage for bug #57006 "Deadlock between HANDLER and FLUSH TABLES WITH READ LOCK". mysql-test/t/flush_block_commit.test: Adjusted test case after changing thread state name which is used when COMMIT waits for FLUSH TABLES WITH READ LOCK from "Waiting for release of readlock" to "Waiting for commit lock". mysql-test/t/flush_block_commit_notembedded.test: Adjusted test case after changing thread state name which is used when DML waits for FLUSH TABLES WITH READ LOCK. Now we use "Waiting for global read lock" in this case. mysql-test/t/flush_read_lock.test: Added test coverage for various aspects of FLUSH TABLES WITH READ LOCK functionality. mysql-test/t/flush_read_lock_kill-master.opt: We no longer need to use make_global_read_lock_block_commit_loop debug tag in this test. Instead we rely on an appropriate debug_sync point in MDL code. mysql-test/t/flush_read_lock_kill.test: Adjusted test case after replacing custom global read lock implementation with one based on metadata locks. Use new debug_sync point. Do not disable concurrent inserts as now InnoDB we always use InnoDB table. mysql-test/t/lock_multi.test: Adjusted test case after changing thread state names which are used when DML or DDL waits for FLUSH TABLES WITH READ LOCK to "Waiting for global read lock". mysql-test/t/mdl_sync.test: Adjusted test case after replacing custom global read lock implementation with one based on metadata locks. Replaced usage of GRL-specific debug_sync's with appropriate sync points in MDL subsystem. Updated thread state names which are used when DDL waits for FTWRL. mysql-test/t/trigger_notembedded.test: Adjusted test case after changing thread state names which are used when DML or DDL waits for FLUSH TABLES WITH READ LOCK to "Waiting for global read lock". sql/event_data_objects.cc: Removed Event_queue_element::status/last_executed_changed members and Event_queue_element::update_timing_fields() method. We no longer use this class for updating mysql.events once event is chosen for execution. Accesses to instances of this class in scheduler thread require protection by Event_queue::LOCK_event_queue mutex and we try to avoid updating table while holding this lock. sql/event_data_objects.h: Removed Event_queue_element::status/last_executed_changed members and Event_queue_element::update_timing_fields() method. We no longer use this class for updating mysql.events once event is chosen for execution. Accesses to instances of this class in scheduler thread require protection by Event_queue::LOCK_event_queue mutex and we try to avoid updating table while holding this lock. sql/event_db_repository.cc: - Changed Event_db_repository methods to not release all metadata locks once they are done updating mysql.events table. This allows to keep metadata lock protecting against GRL and lock protecting particular event around until corresponding DDL statement is written to the binary log. - Removed logic for conditional update of "status" and "last_executed" fields from update_timing_fields_for_event() method. In the only case when this method is called now "last_executed" is always modified and tracking change of "status" is too much hassle. sql/event_db_repository.h: Removed logic for conditional update of "status" and "last_executed" fields from Event_db_repository:: update_timing_fields_for_event() method. In the only case when this method is called now "last_executed" is always modified and tracking change of "status" field is too much hassle. sql/event_queue.cc: Changed event scheduler code not to update mysql.events table while holding Event_queue::LOCK_event_queue mutex. Doing so led to a deadlock with a new GRL implementation. This deadlock didn't occur with old implementation due to fact that code acquiring protection against GRL ignored pending GRL requests (which lead to GRL starvation). One of goals of new implementation is to disallow GRL starvation and so we have to solve problem with this deadlock in a different way. sql/events.cc: Changed methods of Events class to acquire protection against GRL while perfoming DDL statement and keep it until statement is written to the binary log. Unfortunately this step together with new GRL implementation exposed deadlock involving Events::LOCK_event_metadata and GRL. To solve it Events::LOCK_event_metadata mutex was replaced with a metadata lock on event. As a side-effect events DDL has to be prohibited under LOCK TABLES even in cases when mysql.events table was explicitly locked for write. sql/events.h: Replaced Events::LOCK_event_metadata mutex with a metadata lock on event. sql/ha_ndbcluster.cc: Updated code after replacing custom global read lock implementation with one based on MDL. Since MDL subsystem should now be able to detect deadlocks involving metadata locks and GRL there is no need for special handling of active GRL. sql/handler.cc: Replaced custom implementation of global read lock with one based on metadata locks. Consequently when doing commit instead of calling method of Global_read_lock class to acquire protection against GRL we simply acquire IX in COMMIT namespace. sql/lock.cc: Replaced custom implementation of global read lock with one based on metadata locks. This step allows to expose wait for GRL to deadlock detector of MDL subsystem and thus succesfully resolve deadlocks similar to one behind bug #57006 "Deadlock between HANDLER and FLUSH TABLES WITH READ LOCK". It also solves problem with GRL starvation described in bug #54673 "It takes too long to get readlock for 'FLUSH TABLES WITH READ LOCK'" since metadata locks used by GRL give preference to FTWRL statement instead of DML statements (if needed in future this can be changed to fair scheduling). Similar to old implementation of acquisition of GRL is two-step. During the first step we block all concurrent DML and DDL statements by acquiring global S metadata lock (each DML and DDL statement acquires global IX lock for its duration). During the second step we block commits by acquiring global S lock in COMMIT namespace (commit code acquires global IX lock in this namespace). Note that unlike in old implementation acquisition of protection against GRL in DML and DDL is semi-automatic. We assume that any statement which should be blocked by GRL will either open and acquires write-lock on tables or acquires metadata locks on objects it is going to modify. For any such statement global IX metadata lock is automatically acquired for its duration. To support this change: - Global_read_lock::lock/unlock_global_read_lock and make_global_read_lock_block_commit methods were changed accordingly. - Global_read_lock::wait_if_global_read_lock() and start_waiting_global_read_lock() methods were dropped. It is now responsibility of code acquiring metadata locks opening tables to acquire protection against GRL by explicitly taking global IX lock with statement duration. - Global variables, mutex and condition variable used by old implementation was removed. - lock_routine_name() was changed to use statement duration for its global IX lock. It was also renamed to lock_object_name() as it now also used to take metadata locks on events. - Global_read_lock::set_explicit_lock_duration() was added which allows not to release locks used for GRL when leaving prelocked mode. sql/lock.h: - Renamed lock_routine_name() to lock_object_name() and changed its signature to allow its usage for events. - Removed broadcast_refresh() function. It is no longer needed with new GRL implementation. sql/log_event.cc: Release metadata locks with statement duration at the end of processing legacy event for LOAD DATA. This ensures that replication thread processing such event properly releases its protection against global read lock. sql/mdl.cc: Changed MDL subsystem to support new MDL-based implementation of global read lock. Added COMMIT and EVENTS namespaces for metadata locks. Changed thread state name for GLOBAL namespace to "Waiting for global read lock". Optimized MDL_map::find_or_insert() method to avoid taking m_mutex mutex when looking up MDL_lock objects for GLOBAL or COMMIT namespaces. We keep pre-created MDL_lock objects for these namespaces around and simply return pointers to these global objects when needed. Changed MDL_lock/MDL_scoped_lock to properly handle notification of insert delayed handler threads when FTWRL takes global S lock. Introduced concept of lock duration. In addition to locks with transaction duration which work in the way which is similar to how locks worked before (i.e. they are released at the end of transaction), locks with statement and explicit duration were introduced. Locks with statement duration are automatically released at the end of statement. Locks with explicit duration require explicit release and obsolete concept of transactional sentinel. * Changed MDL_request and MDL_ticket classes to support notion of duration. * Changed MDL_context to keep locks with different duration in different lists. Changed code handling ticket list to take this into account. * Changed methods responsible for releasing locks to take into account duration of tickets. Particularly public MDL_context::release_lock() method now only can release tickets with explicit duration (there is still internal method which allows to specify duration). To release locks with statement or transaction duration one have to use release_statement/transactional_locks() methods. * Concept of savepoint for MDL subsystem now has to take into account locks with statement duration. Consequently MDL_savepoint class was introduced and methods working with savepoints were updated accordingly. * Added methods which allow to set duration for one or all locks in the context. sql/mdl.h: Changed MDL subsystem to support new MDL-based implementation of global read lock. Added COMMIT and EVENTS namespaces for metadata locks. Introduced concept of lock duration. In addition to locks with transaction duration which work in the way which is similar to how locks worked before (i.e. they are released at the end of transaction), locks with statement and explicit duration were introduced. Locks with statement duration are automatically released at the end of statement. Locks with explicit duration require explicit release and obsolete concept of transactional sentinel. * Changed MDL_request and MDL_ticket classes to support notion of duration. * Changed MDL_context to keep locks with different duration in different lists. Changed code handling ticket list to take this into account. * Changed methods responsible for releasing locks to take into account duration of tickets. Particularly public MDL_context::release_lock() method now only can release tickets with explicit duration (there is still internal method which allows to specify duration). To release locks with statement or transaction duration one have to use release_statement/transactional_locks() methods. * Concept of savepoint for MDL subsystem now has to take into account locks with statement duration. Consequently MDL_savepoint class was introduced and methods working with savepoints were updated accordingly. * Added methods which allow to set duration for one or all locks in the context. sql/mysqld.cc: Removed global mutex and condition variables which were used by old implementation of GRL. Also we no longer need to initialize Events::LOCK_event_metadata mutex as it was replaced with metadata locks on events. sql/mysqld.h: Removed global variable, mutex and condition variables which were used by old implementation of GRL. sql/rpl_rli.cc: When slave thread closes tables which were open for handling of RBR events ensure that it releases global IX lock which was acquired as protection against GRL. sql/sp.cc: Adjusted code to the new signature of lock_object/routine_name(), to the fact that one now needs specify duration of lock when initializing MDL_request and to the fact that savepoints for MDL subsystem are now represented by MDL_savepoint class. sql/sp_head.cc: Ensure that statements in stored procedures release statement metadata locks and thus release their protectiong against GRL in proper moment in time. Adjusted code to the fact that one now needs specify duration of lock when initializing MDL_request. sql/sql_admin.cc: Adjusted code to the fact that one now needs specify duration of lock when initializing MDL_request. sql/sql_base.cc: - Implemented support for new approach to acquiring protection against global read lock. We no longer acquire such protection explicitly on the basis of statement flags. Instead we always rely on code which is responsible for acquiring metadata locks on object to be changed acquiring this protection. This is achieved by acquiring global IX metadata lock with statement duration. Code doing this also responsible for checking that current connection has no active GRL by calling an Global_read_lock::can_acquire_protection() method. Changed code in open_table() and lock_table_names() accordingly. Note that as result of this change DDL and DML on temporary tables is always compatible with GRL (before it was incompatible in some cases and compatible in other cases). - To speed-up code acquiring protection against GRL introduced m_has_protection_against_grl member in Open_table_context class. It indicates that protection was already acquired sometime during open_tables() execution and new attempts can be skipped. - Thanks to new GRL implementation calls to broadcast_refresh() became unnecessary and were removed. - Adjusted code to the fact that one now needs specify duration of lock when initializing MDL_request and to the fact that savepoints for MDL subsystem are now represented by MDL_savepoint class. sql/sql_base.h: Adjusted code to the fact that savepoints for MDL subsystem are now represented by MDL_savepoint class. Also introduced Open_table_context::m_has_protection_against_grl member which allows to avoid acquiring protection against GRL while opening tables if such protection was already acquired. sql/sql_class.cc: Changed THD::leave_locked_tables_mode() after transactional sentinel for metadata locks was obsoleted by introduction of locks with explicit duration. sql/sql_class.h: - Adjusted code to the fact that savepoints for MDL subsystem are now represented by MDL_savepoint class. - Changed Global_read_lock class according to changes in global read lock implementation: * wait_if_global_read_lock and start_waiting_global_read_lock are now gone. Instead code needing protection against GRL has to acquire global IX metadata lock with statement duration itself. To help it new can_acquire_protection() was introduced. Also as result of the above change m_protection_count member is gone too. * Added m_mdl_blocks_commits_lock member to store metadata lock blocking commits. * Adjusted code to the fact that concept of transactional sentinel was obsoleted by concept of lock duration. - Removed CF_PROTECT_AGAINST_GRL flag as it is no longer necessary. New GRL implementation acquires protection against global read lock automagically when statement acquires metadata locks on tables or other objects it is going to change. sql/sql_db.cc: Adjusted code to the fact that one now needs specify duration of lock when initializing MDL_request. sql/sql_handler.cc: Removed call to broadcast_refresh() function. It is no longer needed with new GRL implementation. Adjusted code after introducing duration concept for metadata locks. Particularly to the fact transactional sentinel was replaced with explicit duration. sql/sql_handler.h: Renamed mysql_ha_move_tickets_after_trans_sentinel() to mysql_ha_set_explicit_lock_duration() after transactional sentinel was obsoleted by locks with explicit duration. sql/sql_insert.cc: Adjusted code handling delaying inserts after switching to new GRL implementation. Now connection thread initiating delayed insert has to acquire global IX lock in addition to metadata lock on table being inserted into. This IX lock protects against GRL and similarly to SW lock on table being inserted into has to be passed to handler thread in order to avoid deadlocks. sql/sql_lex.cc: LEX::protect_against_global_read_lock member is no longer necessary since protection against GRL is automatically taken by code acquiring metadata locks/opening tables. sql/sql_lex.h: LEX::protect_against_global_read_lock member is no longer necessary since protection against GRL is automatically taken by code acquiring metadata locks/opening tables. sql/sql_parse.cc: - Implemented support for new approach to acquiring protection against global read lock. We no longer acquire such protection explicitly on the basis of statement flags. Instead we always rely on code which is responsible for acquiring metadata locks on object to be changed acquiring this protection. This is achieved by acquiring global IX metadata lock with statement duration. This lock is automatically released at the end of statement execution. - Changed implementation of CREATE/DROP PROCEDURE/FUNCTION not to release metadata locks and thus protection against of GRL in the middle of statement execution. - Adjusted code to the fact that one now needs specify duration of lock when initializing MDL_request and to the fact that savepoints for MDL subsystem are now represented by MDL_savepoint class. sql/sql_prepare.cc: Adjusted code to the to the fact that savepoints for MDL subsystem are now represented by MDL_savepoint class. sql/sql_rename.cc: With new GRL implementation there is no need to explicitly acquire protection against GRL before renaming tables. This happens automatically in code which acquires metadata locks on tables being renamed. sql/sql_show.cc: Adjusted code to the fact that one now needs specify duration of lock when initializing MDL_request and to the fact that savepoints for MDL subsystem are now represented by MDL_savepoint class. sql/sql_table.cc: - With new GRL implementation there is no need to explicitly acquire protection against GRL before dropping tables. This happens automatically in code which acquires metadata locks on tables being dropped. - Changed mysql_alter_table() not to release lock on new table name explicitly and to rely on automatic release of locks at the end of statement instead. This was necessary since now MDL_context::release_lock() is supported only for locks for explicit duration. sql/sql_trigger.cc: With new GRL implementation there is no need to explicitly acquire protection against GRL before changing table triggers. This happens automatically in code which acquires metadata locks on tables which triggers are to be changed. sql/sql_update.cc: Fix bug exposed by GRL testing. During prepare phase acquire only S metadata locks instead of SW locks to keep prepare of multi-UPDATE compatible with concurrent LOCK TABLES WRITE and global read lock. sql/sql_view.cc: With new GRL implementation there is no need to explicitly acquire protection against GRL before creating view. This happens automatically in code which acquires metadata lock on view to be created. sql/sql_yacc.yy: LEX::protect_against_global_read_lock member is no longer necessary since protection against GRL is automatically taken by code acquiring metadata locks/opening tables. sql/table.cc: Adjusted code to the fact that one now needs specify duration of lock when initializing MDL_request. sql/table.h: Adjusted code to the fact that one now needs specify duration of lock when initializing MDL_request. sql/transaction.cc: Replaced custom implementation of global read lock with one based on metadata locks. Consequently when doing commit instead of calling method of Global_read_lock class to acquire protection against GRL we simply acquire IX in COMMIT namespace. Also adjusted code to the fact that MDL savepoint is now represented by MDL_savepoint class. --- mysql-test/include/check_ftwrl_compatible.inc | 158 ++ .../include/check_ftwrl_incompatible.inc | 155 ++ mysql-test/include/handler.inc | 2 - mysql-test/include/wait_show_condition.inc | 2 +- mysql-test/r/delayed.result | 12 + mysql-test/r/events_2.result | 46 +- mysql-test/r/flush.result | 28 + mysql-test/r/flush_read_lock.result | 1683 +++++++++++++ mysql-test/r/flush_read_lock_kill.result | 36 +- mysql-test/r/handler_innodb.result | 4 - mysql-test/r/handler_myisam.result | 4 - mysql-test/r/mdl_sync.result | 11 +- .../perfschema/r/dml_setup_instruments.result | 2 +- .../suite/perfschema/r/func_file_io.result | 1 + .../suite/perfschema/r/func_mutex.result | 1 + .../perfschema/r/global_read_lock.result | 5 +- .../suite/perfschema/r/server_init.result | 12 - .../suite/perfschema/t/func_file_io.test | 3 + mysql-test/suite/perfschema/t/func_mutex.test | 2 + .../suite/perfschema/t/global_read_lock.test | 8 +- .../suite/perfschema/t/server_init.test | 9 - .../suite/rpl/r/rpl_tmp_table_and_DDL.result | 6 +- mysql-test/t/delayed.test | 15 + mysql-test/t/events_2.test | 46 +- mysql-test/t/flush.test | 67 + mysql-test/t/flush_block_commit.test | 2 +- .../t/flush_block_commit_notembedded.test | 2 +- mysql-test/t/flush_read_lock.test | 2187 +++++++++++++++++ mysql-test/t/flush_read_lock_kill-master.opt | 1 - mysql-test/t/flush_read_lock_kill.test | 68 +- mysql-test/t/lock_multi.test | 58 +- mysql-test/t/mdl_sync.test | 15 +- mysql-test/t/trigger_notembedded.test | 2 +- sql/event_data_objects.cc | 45 - sql/event_data_objects.h | 7 - sql/event_db_repository.cc | 53 +- sql/event_db_repository.h | 2 - sql/event_queue.cc | 20 +- sql/events.cc | 42 +- sql/events.h | 4 +- sql/ha_ndbcluster.cc | 49 +- sql/handler.cc | 40 +- sql/lock.cc | 360 +-- sql/lock.h | 6 +- sql/log_event.cc | 2 + sql/mdl.cc | 569 +++-- sql/mdl.h | 181 +- sql/mysqld.cc | 16 +- sql/mysqld.h | 9 +- sql/rpl_rli.cc | 3 + sql/sp.cc | 23 +- sql/sp_head.cc | 9 +- sql/sql_admin.cc | 2 +- sql/sql_base.cc | 130 +- sql/sql_base.h | 26 +- sql/sql_class.cc | 10 +- sql/sql_class.h | 61 +- sql/sql_db.cc | 3 +- sql/sql_handler.cc | 35 +- sql/sql_handler.h | 2 +- sql/sql_insert.cc | 85 +- sql/sql_lex.cc | 1 - sql/sql_lex.h | 16 - sql/sql_parse.cc | 154 +- sql/sql_prepare.cc | 3 +- sql/sql_rename.cc | 7 +- sql/sql_show.cc | 6 +- sql/sql_table.cc | 30 +- sql/sql_trigger.cc | 14 - sql/sql_update.cc | 12 +- sql/sql_view.cc | 10 +- sql/sql_yacc.yy | 4 - sql/table.cc | 3 +- sql/table.h | 3 +- sql/transaction.cc | 25 +- 75 files changed, 5492 insertions(+), 1243 deletions(-) create mode 100644 mysql-test/include/check_ftwrl_compatible.inc create mode 100644 mysql-test/include/check_ftwrl_incompatible.inc create mode 100644 mysql-test/r/flush_read_lock.result create mode 100644 mysql-test/t/flush_read_lock.test delete mode 100644 mysql-test/t/flush_read_lock_kill-master.opt diff --git a/mysql-test/include/check_ftwrl_compatible.inc b/mysql-test/include/check_ftwrl_compatible.inc new file mode 100644 index 00000000000..76c1915957c --- /dev/null +++ b/mysql-test/include/check_ftwrl_compatible.inc @@ -0,0 +1,158 @@ +# +# SUMMARY +# Check that a statement is compatible with FLUSH TABLES WITH READ LOCK. +# +# PARAMETERS +# $con_aux1 Name of the 1st aux connection to be used by this script. +# $con_aux2 Name of the 2nd aux connection to be used by this script. +# $statement The statement to be checked. +# $cleanup_stmt The statement to be run in order to revert effects of +# the statement to be checked. +# $skip_3rd_chk Skip the 3rd stage of checking. The purpose of the third +# stage is to check that metadata locks taken by this +# statement are compatible with metadata locks taken +# by FTWRL. +# +# EXAMPLE +# flush_read_lock.test +# +--disable_result_log +--disable_query_log + +# Reset DEBUG_SYNC facility for safety. +set debug_sync= "RESET"; + +# +# First, check that the statement can be run under FTWRL. +# +flush tables with read lock; +--disable_abort_on_error +--eval $statement +--enable_abort_on_error +let $err= $mysql_errno; +if (!$err) +{ +--echo Success: Was able to run '$statement' under FTWRL. +unlock tables; +if (`SELECT "$cleanup_stmt" <> ""`) +{ +--eval $cleanup_stmt; +} +} +if ($err) +{ +--echo Error: Wasn't able to run '$statement' under FTWRL! +unlock tables; +} + +# +# Then check that this statement won't be blocked by FTWRL +# that is active in another connection. +# +connection $con_aux1; +flush tables with read lock; + +connection default; +--send_eval $statement; + +connection $con_aux1; + +--enable_result_log +--enable_query_log +let $wait_condition= + select count(*) = 0 from information_schema.processlist + where info = "$statement"; +--source include/wait_condition.inc +--disable_result_log +--disable_query_log + +if ($success) +{ +--echo Success: Was able to run '$statement' with FTWRL active in another connection. + +connection default; +# Apparently statement was successfully executed and so +# was not blocked by FTWRL. +# To be safe against wait_condition.inc succeeding due to +# races let us first reap the statement being checked to +# ensure that it has been successfully executed. +--reap + +connection $con_aux1; +unlock tables; + +connection default; +} +if (!$success) +{ +--echo Error: Wasn't able to run '$statement' with FTWRL active in another connection! +unlock tables; +connection default; +--reap +} + +if (`SELECT "$cleanup_stmt" <> ""`) +{ +--eval $cleanup_stmt; +} + +if (`SELECT "$skip_3rd_check" = ""`) +{ +# +# Finally, let us check that FTWRL will succeed if this statement +# is active but has already closed its tables. +# +connection default; +set debug_sync='execute_command_after_close_tables SIGNAL parked WAIT_FOR go'; +--send_eval $statement; + +connection $con_aux1; +set debug_sync="now WAIT_FOR parked"; +--send flush tables with read lock + +connection $con_aux2; +--enable_result_log +--enable_query_log +let $wait_condition= + select count(*) = 0 from information_schema.processlist + where info = "flush tables with read lock"; +--source include/wait_condition.inc +--disable_result_log +--disable_query_log + +if ($success) +{ +--echo Success: Was able to run FTWRL while '$statement' was active in another connection. +connection $con_aux1; +# Apparently FTWRL was successfully executed and so was not blocked by +# the statement being checked. To be safe against wait_condition.inc +# succeeding due to races let us first reap the FTWRL to ensure that it +# has been successfully executed. +--reap +unlock tables; +set debug_sync="now SIGNAL go"; +connection default; +--reap +} +if (!$success) +{ +--echo Error: Wasn't able to run FTWRL while '$statement' was active in another connection! +set debug_sync="now SIGNAL go"; +connection default; +--reap +connection $con_aux1; +--reap +unlock tables; +connection default; +} + +set debug_sync= "RESET"; +if (`SELECT "$cleanup_stmt" <> ""`) +{ +--eval $cleanup_stmt; +} + +} + +--enable_result_log +--enable_query_log diff --git a/mysql-test/include/check_ftwrl_incompatible.inc b/mysql-test/include/check_ftwrl_incompatible.inc new file mode 100644 index 00000000000..56deef8e92f --- /dev/null +++ b/mysql-test/include/check_ftwrl_incompatible.inc @@ -0,0 +1,155 @@ +# +# SUMMARY +# Check that a statement is incompatible with FLUSH TABLES WITH READ LOCK. +# +# PARAMETERS +# $con_aux1 Name of the 1st aux connection to be used by this script. +# $con_aux2 Name of the 2nd aux connection to be used by this script. +# $statement The statement to be checked. +# $cleanup_stmt1 The 1st statement to be run in order to revert effects +# of statement to be checked. +# $cleanup_stmt2 The 2nd statement to be run in order to revert effects +# of statement to be checked. +# $skip_3rd_chk Skip the 3rd stage of checking. The purpose of the third +# stage is to check that metadata locks taken by this +# statement are incompatible with metadata locks taken +# by FTWRL. +# +# EXAMPLE +# flush_read_lock.test +# +--disable_result_log +--disable_query_log + +# Reset DEBUG_SYNC facility for safety. +set debug_sync= "RESET"; + +# +# First, check that the statement cannot be run under FTWRL. +# +flush tables with read lock; +--disable_abort_on_error +--eval $statement +--enable_abort_on_error +let $err= $mysql_errno; +if ($err) +{ +--echo Success: Was not able to run '$statement' under FTWRL. +unlock tables; +} +if (!$err) +{ +--echo Error: Was able to run '$statement' under FTWRL! +unlock tables; +if (`SELECT "$cleanup_stmt1" <> ""`) +{ +--eval $cleanup_stmt1; +} +if (`SELECT "$cleanup_stmt2" <> ""`) +{ +--eval $cleanup_stmt2; +} +} + + +# +# Then check that this statement is blocked by FTWRL +# that is active in another connection. +# +connection $con_aux1; +flush tables with read lock; + +connection default; +--send_eval $statement; + +connection $con_aux1; + +--enable_result_log +--enable_query_log +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where (state = "Waiting for global read lock" or + state = "Waiting for commit lock") and + info = "$statement"; +--source include/wait_condition.inc +--disable_result_log +--disable_query_log + +if ($success) +{ +--echo Success: '$statement' is blocked by FTWRL active in another connection. +} +if (!$success) +{ +--echo Error: '$statement' wasn't blocked by FTWRL active in another connection! +} +unlock tables; + +connection default; +--reap + +if (`SELECT "$cleanup_stmt1" <> ""`) +{ +--eval $cleanup_stmt1; +} +if (`SELECT "$cleanup_stmt2" <> ""`) +{ +--eval $cleanup_stmt2; +} + +if (`SELECT "$skip_3rd_check" = ""`) +{ +# +# Finally, let us check that FTWRL will not succeed if this +# statement is active but has already closed its tables. +# +connection default; +--eval set debug_sync='execute_command_after_close_tables SIGNAL parked WAIT_FOR go'; +--send_eval $statement; + +connection $con_aux1; +set debug_sync="now WAIT_FOR parked"; +--send flush tables with read lock + +connection $con_aux2; +--enable_result_log +--enable_query_log +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where (state = "Waiting for global read lock" or + state = "Waiting for commit lock") and + info = "flush tables with read lock"; +--source include/wait_condition.inc +--disable_result_log +--disable_query_log + +if ($success) +{ +--echo Success: FTWRL is blocked when '$statement' is active in another connection. +} +if (!$success) +{ +--echo Error: FTWRL isn't blocked when '$statement' is active in another connection! +} +set debug_sync="now SIGNAL go"; +connection default; +--reap +connection $con_aux1; +--reap +unlock tables; +connection default; + +set debug_sync= "RESET"; + +if (`SELECT "$cleanup_stmt1" <> ""`) +{ +--eval $cleanup_stmt1; +} +if (`SELECT "$cleanup_stmt2" <> ""`) +{ +--eval $cleanup_stmt2; +} +} + +--enable_result_log +--enable_query_log diff --git a/mysql-test/include/handler.inc b/mysql-test/include/handler.inc index b86d5d9287f..57d368960bf 100644 --- a/mysql-test/include/handler.inc +++ b/mysql-test/include/handler.inc @@ -1545,8 +1545,6 @@ lock table not_exists_write read; --echo # We still have the read lock. --error ER_CANT_UPDATE_WITH_READLOCK drop table t1; -handler t1 read next; -handler t1 close; handler t1 open; select a from t2; handler t1 read next; diff --git a/mysql-test/include/wait_show_condition.inc b/mysql-test/include/wait_show_condition.inc index f683ca7b47b..07bde560f20 100644 --- a/mysql-test/include/wait_show_condition.inc +++ b/mysql-test/include/wait_show_condition.inc @@ -101,7 +101,7 @@ if (`SELECT '$wait_for_all' = '1'`) if (!$found) { - echo # Timeout in include/wait_show_condition.inc for $wait_condition; + echo # Timeout in include/wait_show_condition.inc for $condition; echo # show_statement : $show_statement; echo # field : $field; echo # condition : $condition; diff --git a/mysql-test/r/delayed.result b/mysql-test/r/delayed.result index 77aa0d49407..d9082914d05 100644 --- a/mysql-test/r/delayed.result +++ b/mysql-test/r/delayed.result @@ -418,6 +418,18 @@ COMMIT; UNLOCK TABLES; # Connection con1 # Reaping: INSERT DELAYED INTO t1 VALUES (5) +# Connection default +# Test 5: LOCK TABLES + INSERT DELAYED in one connection. +# This test has triggered some asserts in metadata locking +# subsystem at some point in time.. +LOCK TABLE t1 WRITE; +INSERT DELAYED INTO t2 VALUES (7); +UNLOCK TABLES; +SET AUTOCOMMIT= 0; +LOCK TABLE t1 WRITE; +INSERT DELAYED INTO t2 VALUES (8); +UNLOCK TABLES; +SET AUTOCOMMIT= 1; # Connection con2 # Connection con1 # Connection default diff --git a/mysql-test/r/events_2.result b/mysql-test/r/events_2.result index 530d8559f11..66ec00d7357 100644 --- a/mysql-test/r/events_2.result +++ b/mysql-test/r/events_2.result @@ -133,15 +133,15 @@ select event_name from information_schema.events; event_name e1 create event e2 on schedule every 10 hour do select 1; -ERROR HY000: Table 'event' was not locked with LOCK TABLES +ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction alter event e2 disable; -ERROR HY000: Table 'event' was not locked with LOCK TABLES +ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction alter event e2 rename to e3; -ERROR HY000: Table 'event' was not locked with LOCK TABLES +ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction drop event e2; -ERROR HY000: Table 'event' was not locked with LOCK TABLES +ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction drop event e1; -ERROR HY000: Table 'event' was not locked with LOCK TABLES +ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction unlock tables; lock table t1 write; show create event e1; @@ -151,15 +151,15 @@ select event_name from information_schema.events; event_name e1 create event e2 on schedule every 10 hour do select 1; -ERROR HY000: Table 'event' was not locked with LOCK TABLES +ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction alter event e2 disable; -ERROR HY000: Table 'event' was not locked with LOCK TABLES +ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction alter event e2 rename to e3; -ERROR HY000: Table 'event' was not locked with LOCK TABLES +ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction drop event e2; -ERROR HY000: Table 'event' was not locked with LOCK TABLES +ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction drop event e1; -ERROR HY000: Table 'event' was not locked with LOCK TABLES +ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction unlock tables; lock table t1 read, mysql.event read; show create event e1; @@ -169,15 +169,15 @@ select event_name from information_schema.events; event_name e1 create event e2 on schedule every 10 hour do select 1; -ERROR HY000: Table 'event' was locked with a READ lock and can't be updated +ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction alter event e2 disable; -ERROR HY000: Table 'event' was locked with a READ lock and can't be updated +ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction alter event e2 rename to e3; -ERROR HY000: Table 'event' was locked with a READ lock and can't be updated +ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction drop event e2; -ERROR HY000: Table 'event' was locked with a READ lock and can't be updated +ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction drop event e1; -ERROR HY000: Table 'event' was locked with a READ lock and can't be updated +ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction unlock tables; lock table t1 write, mysql.event read; show create event e1; @@ -187,15 +187,15 @@ select event_name from information_schema.events; event_name e1 create event e2 on schedule every 10 hour do select 1; -ERROR HY000: Table 'event' was locked with a READ lock and can't be updated +ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction alter event e2 disable; -ERROR HY000: Table 'event' was locked with a READ lock and can't be updated +ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction alter event e2 rename to e3; -ERROR HY000: Table 'event' was locked with a READ lock and can't be updated +ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction drop event e2; -ERROR HY000: Table 'event' was locked with a READ lock and can't be updated +ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction drop event e1; -ERROR HY000: Table 'event' was locked with a READ lock and can't be updated +ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction unlock tables; lock table t1 read, mysql.event write; ERROR HY000: You can't combine write-locking of system tables with other tables or lock types @@ -209,11 +209,17 @@ select event_name from information_schema.events; event_name e1 create event e2 on schedule every 10 hour do select 1; +ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction alter event e2 disable; +ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction alter event e2 rename to e3; +ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction drop event e3; +ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction drop event e1; +ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction unlock tables; +drop event e1; Make sure we have left no events select event_name from information_schema.events; event_name diff --git a/mysql-test/r/flush.result b/mysql-test/r/flush.result index ced8306c3ab..b1e2e48eca8 100644 --- a/mysql-test/r/flush.result +++ b/mysql-test/r/flush.result @@ -423,3 +423,31 @@ i 4 unlock tables; drop tables tm, t1, t2; +# +# Test for bug #57006 "Deadlock between HANDLER and +# FLUSH TABLES WITH READ LOCK". +# +drop table if exists t1, t2; +create table t1 (i int); +create table t2 (i int); +handler t1 open; +# Switching to connection 'con1'. +# Sending: +flush tables with read lock; +# Switching to connection 'con2'. +# Wait until FTWRL starts waiting for 't1' to be closed. +# Switching to connection 'default'. +# The below statement should not cause deadlock. +# Sending: +insert into t2 values (1); +# Switching to connection 'con2'. +# Wait until INSERT starts to wait for FTWRL to go away. +# Switching to connection 'con1'. +# FTWRL should be able to continue now. +# Reap FTWRL. +unlock tables; +# Switching to connection 'default'. +# Reap INSERT. +handler t1 close; +# Cleanup. +drop tables t1, t2; diff --git a/mysql-test/r/flush_read_lock.result b/mysql-test/r/flush_read_lock.result new file mode 100644 index 00000000000..2b1071a92b2 --- /dev/null +++ b/mysql-test/r/flush_read_lock.result @@ -0,0 +1,1683 @@ +# FTWRL takes two global metadata locks -- a global shared +# metadata lock and the commit blocker lock. +# The first lock prevents DDL from taking place. +# Let's say that all DDL statements that take metadata +# locks form class #1 -- incompatible with FTWRL because +# take incompatible MDL table locks. +# The first global lock doesn't, however, prevent standalone +# COMMITs (or implicit COMMITs) from taking place, since a +# COMMIT doesn't take table locks. It doesn't prevent +# DDL on temporary tables either, since they don't +# take any table locks either. +# Most DDL statements do not perform an implicit commit +# if operate on a temporary table. Examples are CREATE +# TEMPORARY TABLE and DROP TEMPORARY TABLE. +# Thus, these DDL statements can go through in presence +# of FTWRL. This is class #2 -- compatible because +# do not take incompatible MDL locks and do not issue +# implicit commit.. +# (Although these operations do not commit, their effects +# cannot be rolled back either.) +# ALTER TABLE, ANALYZE, OPTIMIZE and some others always +# issue an implicit commit, even if its argument is a +# temporary table. +# *Howewer* an implicit commit is a no-op if all engines +# used since the start of transactiona are non- +# transactional. Thus, for non-transactional engines, +# these operations are not blocked by FTWRL. +# This is class #3 -- compatible because do not take +# MDL table locks and are non-transactional. +# On the contrary, for transactional engines, there +# is always a commit, regardless of whether a table +# is temporary or not. Thus, for example, ALTER TABLE +# for a transactional engine will wait for FTWRL, +# even if the subject table is temporary. +# Thus ALTER TABLE is incompatible +# with FTWRL. This is class #4 -- incompatible +# becuase issue implicit COMMIT which is not a no-op. +# Finally, there are administrative statements (such as +# RESET SLAVE) that do not take any locks and do not +# issue COMMIT. +# This is class #5. +# The goal of this coverage is to test statements +# of all classes. +# @todo: documents the effects of @@autocommit, +# DML and temporary transactional tables. +# Use MyISAM engine for the most of the tables +# used in this test in order to be able to +# check that DDL statements on temporary tables +# are compatible with FTRWL. +drop tables if exists t1_base, t2_base, t3_trans; +drop tables if exists tm_base, tm_base_temp; +drop database if exists mysqltest1; +# We're going to test ALTER DATABASE UPGRADE +drop database if exists `#mysql50#mysqltest-2`; +drop procedure if exists p1; +drop function if exists f1; +drop view if exists v1; +drop procedure if exists p2; +drop function if exists f2_base; +drop function if exists f2_temp; +drop event if exists e1; +drop event if exists e2; +create table t1_base(i int) engine=myisam; +create table t2_base(j int) engine=myisam; +create table t3_trans(i int) engine=innodb; +create temporary table t1_temp(i int) engine=myisam; +create temporary table t2_temp(j int) engine=myisam; +create temporary table t3_temp_trans(i int) engine=innodb; +create database mysqltest1; +create database `#mysql50#mysqltest-2`; +create procedure p1() begin end; +create function f1() returns int return 0; +create view v1 as select 1 as i; +create procedure p2(i int) begin end; +create function f2_base() returns int +begin +insert into t1_base values (1); +return 0; +end| +create function f2_temp() returns int +begin +insert into t1_temp values (1); +return 0; +end| +create event e1 on schedule every 1 minute do begin end; +# +# Test compatibility of FLUSH TABLES WITH READ LOCK +# with various statements. +# +# These tests don't cover some classes of statements: +# - Replication-related - CHANGE MASTER TO, START/STOP SLAVE and etc +# (all compatible with FTWRL). +# - Plugin-related - INSTALL/UNINSTALL (incompatible with FTWRL, +# require plugin support). +# +# 1) ALTER variants. +# +# 1.1) ALTER TABLE +# +# 1.1.a) For base table should be incompatible with FTWRL. +# +Success: Was not able to run 'alter table t1_base add column c1 int' under FTWRL. +Success: 'alter table t1_base add column c1 int' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'alter table t1_base add column c1 int' is active in another connection. +# +# 1.1.b) For a temporary table should be compatible with FTWRL. +# +Success: Was able to run 'alter table t1_temp add column c1 int' under FTWRL. +Success: Was able to run 'alter table t1_temp add column c1 int' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'alter table t1_temp add column c1 int' was active in another connection. +# +# 1.2) ALTER DATABASE should be incompatible with FTWRL. +# +Success: Was not able to run 'alter database mysqltest1 default character set utf8' under FTWRL. +Success: 'alter database mysqltest1 default character set utf8' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'alter database mysqltest1 default character set utf8' is active in another connection. +# +# 1.3) ALTER DATABASE UPGRADE DATA DIRECTORY NAME should be +# incompatible with FTWRL. +# +Success: Was not able to run 'alter database `#mysql50#mysqltest-2` upgrade data directory name' under FTWRL. +Success: 'alter database `#mysql50#mysqltest-2` upgrade data directory name' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'alter database `#mysql50#mysqltest-2` upgrade data directory name' is active in another connection. +# +# 1.4) ALTER PROCEDURE should be incompatible with FTWRL. +# +Success: Was not able to run 'alter procedure p1 comment 'a'' under FTWRL. +Success: 'alter procedure p1 comment 'a'' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'alter procedure p1 comment 'a'' is active in another connection. +# +# 1.5) ALTER FUNCTION should be incompatible with FTWRL. +# +Success: Was not able to run 'alter function f1 comment 'a'' under FTWRL. +Success: 'alter function f1 comment 'a'' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'alter function f1 comment 'a'' is active in another connection. +# +# 1.6) ALTER VIEW should be incompatible with FTWRL. +# +Success: Was not able to run 'alter view v1 as select 2 as j' under FTWRL. +Success: 'alter view v1 as select 2 as j' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'alter view v1 as select 2 as j' is active in another connection. +# +# 1.7) ALTER EVENT should be incompatible with FTWRL. +# +Success: Was not able to run 'alter event e1 comment 'test'' under FTWRL. +Success: 'alter event e1 comment 'test'' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'alter event e1 comment 'test'' is active in another connection. +# +# 1.x) The rest of ALTER statements (ALTER TABLESPACE, +# ALTER LOGFILE GROUP and ALTER SERVER) are too +# special to be tested here. +# +# +# 2) ANALYZE TABLE statement is compatible with FTWRL. +# See Bug#43336 ANALYZE and OPTIMIZE do not honour +# --read-only for a discussion why. +# +Success: Was able to run 'analyze table t1_base' under FTWRL. +Success: Was able to run 'analyze table t1_base' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'analyze table t1_base' was active in another connection. +# +# 3) BEGIN, ROLLBACK and COMMIT statements. +# BEGIN and ROLLBACK are compatible with FTWRL. +# COMMIT is not. +# +# We need a special test for these statements as +# FTWRL commits a transaction and because COMMIT +# is handled in a special way. +flush tables with read lock; +begin; +# ROLLBACK is allowed under FTWRL although there +# no much sense in it. FTWRL commits any previous +# changes and doesn't allows any DML after it. +# So such a ROLLBACK is always a no-op. +rollback; +# Although COMMIT is incompatible with FTWRL in +# other senses it is still allowed under FTWRL. +# This fact relied upon by some versions of +# innobackup tool. +# Similarly to ROLLBACK it is a no-op in this situation. +commit; +unlock tables; +# Check that BEGIN/ROLLBACK are not blocked and +# COMMIT is blocked by active FTWRL in another +# connection. +# +# Switching to connection 'con1'. +flush tables with read lock; +# Switching to connection 'default'. +begin; +# Switching to connection 'con1'. +unlock tables; +# Switching to connection 'default'. +# Do some work so ROLLBACK is not a no-op. +insert into t3_trans values (1); +# Switching to connection 'con1'. +flush tables with read lock; +# Switching to connection 'default'. +rollback; +# Switching to connection 'con1'. +unlock tables; +# Switching to connection 'default'. +begin; +# Do some work so COMMIT is not a no-op. +insert into t3_trans values (1); +# Switching to connection 'con1'. +flush tables with read lock; +# Switching to connection 'default'. +# Send: +commit; +# Switching to connection 'con1'. +# Wait until COMMIT is blocked. +unlock tables; +# Switching to connection 'default'. +# Reap COMMIT. +delete from t3_trans; +# +# Check that COMMIT blocks FTWRL in another connection. +begin; +insert into t3_trans values (1); +set debug_sync='RESET'; +set debug_sync='ha_commit_trans_after_acquire_commit_lock SIGNAL parked WAIT_FOR go'; +commit; +# Switching to connection 'con1'. +set debug_sync='now WAIT_FOR parked'; +flush tables with read lock; +# Switching to connection 'con2'. +# Wait until FTWRL is blocked. +set debug_sync='now SIGNAL go'; +# Switching to connection 'default'. +# Reap COMMIT. +# Switching to connection 'con1'. +# Reap FTWRL. +unlock tables; +# Switching to connection 'default'. +delete from t3_trans; +set debug_sync= "RESET"; +# We don't run similar test for BEGIN and ROLLBACK as +# they release metadata locks in non-standard place. +# +# 4) BINLOG statement should be incompatible with FTWRL. +# +# +# Provide format description BINLOG statement first. +BINLOG ' +MfmqTA8BAAAAZwAAAGsAAAABAAQANS41LjctbTMtZGVidWctbG9nAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAx+apMEzgNAAgAEgAEBAQEEgAAVAAEGggAAAAICAgCAA== +'; +# Now test compatibility for BINLOG statement which is +# equivalent to INSERT INTO t1_base VALUES (1). +# Skip last part of compatibility testing as this statement +# releases metadata locks in non-standard place. +Success: Was not able to run 'BINLOG ' +MfmqTBMBAAAALgAAAN0AAAAAACgAAAAAAAEABHRlc3QAB3QxX2Jhc2UAAQMAAQ== +MfmqTBcBAAAAIgAAAP8AAAAAACgAAAAAAAEAAf/+AQAAAA== +'' under FTWRL. +Success: 'BINLOG ' +MfmqTBMBAAAALgAAAN0AAAAAACgAAAAAAAEABHRlc3QAB3QxX2Jhc2UAAQMAAQ== +MfmqTBcBAAAAIgAAAP8AAAAAACgAAAAAAAEAAf/+AQAAAA== +'' is blocked by FTWRL active in another connection. +# +# 5) CALL statement. This statement uses resources in two +# ways: through expressions used as parameters and through +# sub-statements. This test covers only usage through +# parameters as sub-statements do locking individually. +# +# 5.a) In simple cases a parameter expression should be +# compatible with FTWRL. +# Skip last part of compatibility testing as this statement +# releases metadata locks in non-standard place. +Success: Was able to run 'call p2((select count(*) from t1_base))' under FTWRL. +Success: Was able to run 'call p2((select count(*) from t1_base))' with FTWRL active in another connection. +# +# 5.b) In case when an expression uses function which updates +# base tables CALL should be incompatible with FTWRL. +# +# Skip last part of compatibility testing as this statement +# releases metadata locks in non-standard place. +Success: Was not able to run 'call p2(f2_base())' under FTWRL. +Success: 'call p2(f2_base())' is blocked by FTWRL active in another connection. +# +# 5.c) If function used as argument updates temporary tables +# CALL statement should be compatible with FTWRL. +# +# Skip last part of compatibility testing as this statement +# releases metadata locks in non-standard place. +Success: Was able to run 'call p2(f2_temp())' under FTWRL. +Success: Was able to run 'call p2(f2_temp())' with FTWRL active in another connection. +# +# 6) CHECK TABLE statement is compatible with FTWRL. +# +Success: Was able to run 'check table t1_base' under FTWRL. +Success: Was able to run 'check table t1_base' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'check table t1_base' was active in another connection. +# +# 7) CHECKSUM TABLE statement is compatible with FTWRL. +# +Success: Was able to run 'checksum table t1_base' under FTWRL. +Success: Was able to run 'checksum table t1_base' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'checksum table t1_base' was active in another connection. +# +# 8) CREATE variants. +# +# 8.1) CREATE TABLE statement. +# +# 8.1.a) CREATE TABLE is incompatible with FTWRL when +# base table is created. +Success: Was not able to run 'create table t3_base(i int)' under FTWRL. +Success: 'create table t3_base(i int)' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'create table t3_base(i int)' is active in another connection. +# 8.1.b) CREATE TABLE is compatible with FTWRL when +# temporary table is created. +Success: Was able to run 'create temporary table t3_temp(i int)' under FTWRL. +Success: Was able to run 'create temporary table t3_temp(i int)' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'create temporary table t3_temp(i int)' was active in another connection. +# 8.1.c) CREATE TABLE LIKE is incompatible with FTWRL when +# base table is created. +Success: Was not able to run 'create table t3_base like t1_temp' under FTWRL. +Success: 'create table t3_base like t1_temp' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'create table t3_base like t1_temp' is active in another connection. +# 8.1.d) CREATE TABLE LIKE is compatible with FTWRL when +# temporary table is created. +Success: Was able to run 'create temporary table t3_temp like t1_base' under FTWRL. +Success: Was able to run 'create temporary table t3_temp like t1_base' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'create temporary table t3_temp like t1_base' was active in another connection. +# 8.1.e) CREATE TABLE SELECT is incompatible with FTWRL when +# base table is created. +Success: Was not able to run 'create table t3_base select 1 as i' under FTWRL. +Success: 'create table t3_base select 1 as i' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'create table t3_base select 1 as i' is active in another connection. +# 8.1.f) CREATE TABLE SELECT is compatible with FTWRL when +# temporary table is created. +Success: Was able to run 'create temporary table t3_temp select 1 as i' under FTWRL. +Success: Was able to run 'create temporary table t3_temp select 1 as i' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'create temporary table t3_temp select 1 as i' was active in another connection. +# 8.2) CREATE INDEX statement. +# +# 8.2.a) CREATE INDEX is incompatible with FTWRL when +# applied to base table. +Success: Was not able to run 'create index i on t1_base (i)' under FTWRL. +Success: 'create index i on t1_base (i)' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'create index i on t1_base (i)' is active in another connection. +# 8.2.b) CREATE INDEX is compatible with FTWRL when +# applied to temporary table. +Success: Was able to run 'create index i on t1_temp (i)' under FTWRL. +Success: Was able to run 'create index i on t1_temp (i)' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'create index i on t1_temp (i)' was active in another connection. +# +# 8.3) CREATE DATABASE is incompatible with FTWRL. +# +Success: Was not able to run 'create database mysqltest2' under FTWRL. +Success: 'create database mysqltest2' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'create database mysqltest2' is active in another connection. +# +# 8.4) CREATE VIEW is incompatible with FTWRL. +# +Success: Was not able to run 'create view v2 as select 1 as j' under FTWRL. +Success: 'create view v2 as select 1 as j' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'create view v2 as select 1 as j' is active in another connection. +# +# 8.5) CREATE TRIGGER is incompatible with FTWRL. +# +Success: Was not able to run 'create trigger t1_bi before insert on t1_base for each row begin end' under FTWRL. +Success: 'create trigger t1_bi before insert on t1_base for each row begin end' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'create trigger t1_bi before insert on t1_base for each row begin end' is active in another connection. +# +# 8.6) CREATE FUNCTION is incompatible with FTWRL. +# +Success: Was not able to run 'create function f2() returns int return 0' under FTWRL. +Success: 'create function f2() returns int return 0' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'create function f2() returns int return 0' is active in another connection. +# +# 8.7) CREATE PROCEDURE is incompatible with FTWRL. +# +Success: Was not able to run 'create procedure p3() begin end' under FTWRL. +Success: 'create procedure p3() begin end' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'create procedure p3() begin end' is active in another connection. +# +# 8.8) CREATE EVENT should be incompatible with FTWRL. +# +Success: Was not able to run 'create event e2 on schedule every 1 minute do begin end' under FTWRL. +Success: 'create event e2 on schedule every 1 minute do begin end' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'create event e2 on schedule every 1 minute do begin end' is active in another connection. +# +# 8.9) CREATE USER should be incompatible with FTWRL. +# +Success: Was not able to run 'create user mysqltest_u1' under FTWRL. +Success: 'create user mysqltest_u1' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'create user mysqltest_u1' is active in another connection. +# +# 8.x) The rest of CREATE variants (CREATE LOGFILE GROUP, +# CREATE TABLESPACE and CREATE SERVER) are too special +# to test here. +# +# +# 9) PREPARE, EXECUTE and DEALLOCATE PREPARE statements. +# +# 9.1) PREPARE statement is compatible with FTWRL as it +# doesn't change any data. +# +# 9.1.a) Prepare of simple INSERT statement. +# +# Skip last part of compatibility testing as this statement +# releases metadata locks in non-standard place. +Success: Was able to run 'prepare stmt1 from 'insert into t1_base values (1)'' under FTWRL. +Success: Was able to run 'prepare stmt1 from 'insert into t1_base values (1)'' with FTWRL active in another connection. +# +# 9.1.b) Prepare of multi-UPDATE. At some point such statements +# tried to acquire thr_lock.c locks during prepare phase. +# This no longer happens and thus it is compatible with +# FTWRL. +# Skip last part of compatibility testing as this statement +# releases metadata locks in non-standard place. +Success: Was able to run 'prepare stmt1 from 'update t1_base, t2_base set t1_base.i= 1 where t1_base.i = t2_base.j'' under FTWRL. +Success: Was able to run 'prepare stmt1 from 'update t1_base, t2_base set t1_base.i= 1 where t1_base.i = t2_base.j'' with FTWRL active in another connection. +# +# 9.1.c) Prepare of multi-DELETE. Again PREPARE of such +# statement should be compatible with FTWRL. +# Skip last part of compatibility testing as this statement +# releases metadata locks in non-standard place. +Success: Was able to run 'prepare stmt1 from 'delete t1_base from t1_base, t2_base where t1_base.i = t2_base.j'' under FTWRL. +Success: Was able to run 'prepare stmt1 from 'delete t1_base from t1_base, t2_base where t1_base.i = t2_base.j'' with FTWRL active in another connection. +# +# 9.2) Compatibility of EXECUTE statement depends on statement +# to be executed. +# +# 9.2.a) EXECUTE for statement which is itself compatible with +# FTWRL should be compatible. +prepare stmt1 from 'select * from t1_base'; +Success: Was able to run 'execute stmt1' under FTWRL. +Success: Was able to run 'execute stmt1' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'execute stmt1' was active in another connection. +deallocate prepare stmt1; +# +# 9.2.b) EXECUTE for statement which is incompatible with FTWRL +# should be also incompatible. +# +# Check that EXECUTE is not allowed under FTWRL. +prepare stmt1 from 'insert into t1_base values (1)'; +flush tables with read lock; +execute stmt1; +ERROR HY000: Can't execute the query because you have a conflicting read lock +unlock tables; +# Check that active FTWRL in another connection +# blocks EXECUTE which changes data. +# +# Switching to connection 'con1'. +flush tables with read lock; +# Switching to connection 'default'. +execute stmt1 ; +# Switching to connection 'con1'. +# Check that EXECUTE is blocked. +unlock tables; +# Switching to connection 'default'. +# Reap EXECUTE. +set debug_sync='RESET'; +set debug_sync='execute_command_after_close_tables SIGNAL parked WAIT_FOR go'; +execute stmt1; ; +# Switching to connection 'con1'. +set debug_sync='now WAIT_FOR parked'; +flush tables with read lock; +# Switching to connection 'con2'. +# Wait until FTWRL is blocked. +set debug_sync='now SIGNAL go'; +# Switching to connection 'default'. +# Reap EXECUTE. +# Switching to connection 'con1'. +# Reap FTWRL. +unlock tables; +# Switching to connection 'default'. +set debug_sync= "RESET"; +delete from t1_base; +deallocate prepare stmt1; +# +# 9.3) DEALLOCATE PREPARE is compatible with FTWRL. +# +prepare stmt1 from 'insert into t1_base values (1)'; +Success: Was able to run 'deallocate prepare stmt1' under FTWRL. +Success: Was able to run 'deallocate prepare stmt1' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'deallocate prepare stmt1' was active in another connection. +deallocate prepare stmt1; +# +# 10) DELETE variations. +# +# 10.1) Simple DELETE. +# +# 10.1.a) Simple DELETE on base table is incompatible with FTWRL. +Success: Was not able to run 'delete from t1_base' under FTWRL. +Success: 'delete from t1_base' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'delete from t1_base' is active in another connection. +# +# 10.1.b) Simple DELETE on temporary table is compatible with FTWRL. +Success: Was able to run 'delete from t1_temp' under FTWRL. +Success: Was able to run 'delete from t1_temp' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'delete from t1_temp' was active in another connection. +# +# 10.2) Multi DELETE. +# +# 10.2.a) Multi DELETE on base tables is incompatible with FTWRL. +Success: Was not able to run 'delete t1_base from t1_base, t2_base where t1_base.i = t2_base.j' under FTWRL. +Success: 'delete t1_base from t1_base, t2_base where t1_base.i = t2_base.j' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'delete t1_base from t1_base, t2_base where t1_base.i = t2_base.j' is active in another connection. +# +# 10.2.b) Multi DELETE on temporary tables is compatible with FTWRL. +Success: Was able to run 'delete t1_temp from t1_temp, t2_temp where t1_temp.i = t2_temp.j' under FTWRL. +Success: Was able to run 'delete t1_temp from t1_temp, t2_temp where t1_temp.i = t2_temp.j' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'delete t1_temp from t1_temp, t2_temp where t1_temp.i = t2_temp.j' was active in another connection. +# +# 11) DESCRIBE should be compatible with FTWRL. +# +Success: Was able to run 'describe t1_base' under FTWRL. +Success: Was able to run 'describe t1_base' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'describe t1_base' was active in another connection. +# +# 12) Compatibility of DO statement with FTWRL depends on its +# expression. +# +# 12.a) DO with expression which does not change base table +# should be compatible with FTWRL. +Success: Was able to run 'do (select count(*) from t1_base)' under FTWRL. +Success: Was able to run 'do (select count(*) from t1_base)' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'do (select count(*) from t1_base)' was active in another connection. +# +# 12.b) DO which calls SF updating base table should be +# incompatible with FTWRL. +Success: Was not able to run 'do f2_base()' under FTWRL. +Success: 'do f2_base()' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'do f2_base()' is active in another connection. +# +# 12.c) DO which calls SF updating temporary table should be +# compatible with FTWRL. +Success: Was able to run 'do f2_temp()' under FTWRL. +Success: Was able to run 'do f2_temp()' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'do f2_temp()' was active in another connection. +# +# 13) DROP variants. +# +# 13.1) DROP TABLES. +# +# 13.1.a) DROP TABLES which affects base tables is incompatible +# with FTWRL. +Success: Was not able to run 'drop table t2_base' under FTWRL. +Success: 'drop table t2_base' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'drop table t2_base' is active in another connection. +# 13.1.b) DROP TABLES which affects only temporary tables +# in theory can be compatible with FTWRL. +# In practice it is not yet. +Success: Was not able to run 'drop table t2_temp' under FTWRL. +Success: 'drop table t2_temp' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'drop table t2_temp' is active in another connection. +# +# 13.1.c) DROP TEMPORARY TABLES should be compatible with FTWRL. +Success: Was able to run 'drop temporary table t2_temp' under FTWRL. +Success: Was able to run 'drop temporary table t2_temp' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'drop temporary table t2_temp' was active in another connection. +# +# 13.2) DROP INDEX. +# +# 13.2.a) DROP INDEX on a base table is incompatible with FTWRL. +create index i on t1_base (i); +Success: Was not able to run 'drop index i on t1_base' under FTWRL. +Success: 'drop index i on t1_base' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'drop index i on t1_base' is active in another connection. +drop index i on t1_base; +# +# 13.2.b) DROP INDEX on a temporary table is compatible with FTWRL. +create index i on t1_temp (i); +Success: Was able to run 'drop index i on t1_temp' under FTWRL. +Success: Was able to run 'drop index i on t1_temp' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'drop index i on t1_temp' was active in another connection. +drop index i on t1_temp; +# +# 13.3) DROP DATABASE is incompatible with FTWRL +# +Success: Was not able to run 'drop database mysqltest1' under FTWRL. +Success: 'drop database mysqltest1' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'drop database mysqltest1' is active in another connection. +# +# 13.4) DROP FUNCTION is incompatible with FTWRL. +# +Success: Was not able to run 'drop function f1' under FTWRL. +Success: 'drop function f1' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'drop function f1' is active in another connection. +# +# 13.5) DROP PROCEDURE is incompatible with FTWRL. +# +Success: Was not able to run 'drop procedure p1' under FTWRL. +Success: 'drop procedure p1' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'drop procedure p1' is active in another connection. +# +# 13.6) DROP USER should be incompatible with FTWRL. +# +create user mysqltest_u1; +Success: Was not able to run 'drop user mysqltest_u1' under FTWRL. +Success: 'drop user mysqltest_u1' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'drop user mysqltest_u1' is active in another connection. +drop user mysqltest_u1; +# +# 13.7) DROP VIEW should be incompatible with FTWRL. +# +Success: Was not able to run 'drop view v1' under FTWRL. +Success: 'drop view v1' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'drop view v1' is active in another connection. +# +# 13.8) DROP EVENT should be incompatible with FTWRL. +# +Success: Was not able to run 'drop event e1' under FTWRL. +Success: 'drop event e1' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'drop event e1' is active in another connection. +# +# 13.9) DROP TRIGGER is incompatible with FTWRL. +# +create trigger t1_bi before insert on t1_base for each row begin end; +Success: Was not able to run 'drop trigger t1_bi' under FTWRL. +Success: 'drop trigger t1_bi' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'drop trigger t1_bi' is active in another connection. +drop trigger t1_bi; +# +# 13.x) The rest of DROP variants (DROP TABLESPACE, DROP LOGFILE +# GROUP and DROP SERVER) are too special to test here. +# +# +# 14) FLUSH variants. +# +# Test compatibility of _some_ important FLUSH variants with FTWRL. +# +# 14.1) FLUSH TABLES WITH READ LOCK is compatible with itself. +# +# Check that FTWRL statements can be run while FTWRL +# is active in another connection. +# +# Switching to connection 'con1'. +flush tables with read lock; +# The second FTWRL in a row is allowed at the moment. +# It does not make much sense as it does only flush. +flush tables with read lock; +unlock tables; +# Switching to connection 'con1'. +flush tables with read lock; +# Switching to connection 'default'. +flush tables with read lock; +unlock tables; +# Switching to connection 'con1'. +unlock tables; +# Switching to connection 'default'. +# +# 14.2) FLUSH TABLES WITH READ LOCK is not blocked by +# active FTWRL. But since the latter keeps tables open +# FTWRL is blocked by FLUSH TABLES WITH READ LOCK. +flush tables with read lock; +# FT WRL is allowed under FTWRL at the moment. +# It does not make much sense though. +flush tables t1_base, t2_base with read lock; +unlock tables; +# Switching to connection 'con1'. +flush tables with read lock; +# Switching to connection 'default'. +flush tables t1_base, t2_base with read lock; +unlock tables; +# Switching to connection 'con1'. +unlock tables; +# Switching to connection 'default'. +flush tables t1_base, t2_base with read lock; +# Switching to connection 'con1'. +flush tables with read lock; +# Switching to connection 'con2'. +# Wait until FTWRL is blocked. +# Switching to connection 'default'. +unlock tables; +# Switching to connection 'con1'. +# Reap FTWRL. +unlock tables; +# Switching to connection 'default'. +# +# 14.3) FLUSH TABLES is compatible with FTWRL. +Success: Was able to run 'flush tables' under FTWRL. +Success: Was able to run 'flush tables' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'flush tables' was active in another connection. +# +# 14.4) FLUSH TABLES is compatible with FTWRL. +Success: Was able to run 'flush table t1_base, t2_base' under FTWRL. +Success: Was able to run 'flush table t1_base, t2_base' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'flush table t1_base, t2_base' was active in another connection. +# +# 14.5) FLUSH PRIVILEGES is compatible with FTWRL. +Success: Was able to run 'flush privileges' under FTWRL. +Success: Was able to run 'flush privileges' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'flush privileges' was active in another connection. +# +# 15) GRANT statement should be incompatible with FTWRL. +# +Success: Was not able to run 'grant all privileges on t1_base to mysqltest_u1' under FTWRL. +Success: 'grant all privileges on t1_base to mysqltest_u1' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'grant all privileges on t1_base to mysqltest_u1' is active in another connection. +drop user mysqltest_u1; +# +# 16) All HANDLER variants are half-compatible with FTWRL. +# I.e. they are not blocked by active FTWRL. But since open +# HANDLER means open table instance FTWRL is blocked while +# HANDLER is not closed. +# +# Check that HANDLER statements succeed under FTWRL. +flush tables with read lock; +handler t1_base open; +handler t1_base read first; +i +handler t1_base close; +unlock tables; +# Check that HANDLER statements can be run while FTWRL +# is active in another connection. +# +# Switching to connection 'con1'. +flush tables with read lock; +# Switching to connection 'default'. +handler t1_base open; +handler t1_base read first; +i +handler t1_base close; +# Switching to connection 'con1'. +unlock tables; +# Switching to connection 'default'. +# +# 17) HELP statement is compatible with FTWRL. +# +Success: Was able to run 'help no_such_topic' under FTWRL. +Success: Was able to run 'help no_such_topic' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'help no_such_topic' was active in another connection. +# +# 18) INSERT statement. +# +# 18.a) Ordinary INSERT into base table is incompatible with FTWRL. +Success: Was not able to run 'insert into t1_base values (1)' under FTWRL. +Success: 'insert into t1_base values (1)' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'insert into t1_base values (1)' is active in another connection. +# +# 18.b) Ordinary INSERT into temp table is compatible with FTWRL. +Success: Was able to run 'insert into t1_temp values (1)' under FTWRL. +Success: Was able to run 'insert into t1_temp values (1)' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'insert into t1_temp values (1)' was active in another connection. +# +# 18.c) INSERT DELAYED is incompatible with FTWRL. +Success: Was not able to run 'insert delayed into t1_base values (1)' under FTWRL. +Success: 'insert delayed into t1_base values (1)' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'insert delayed into t1_base values (1)' is active in another connection. +delete from t1_base; +# +# 18.d) INSERT SELECT into base table is incompatible with FTWRL. +Success: Was not able to run 'insert into t1_base select * from t1_temp' under FTWRL. +Success: 'insert into t1_base select * from t1_temp' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'insert into t1_base select * from t1_temp' is active in another connection. +# +# 18.e) INSERT SELECT into temp table is compatible with FTWRL. +Success: Was able to run 'insert into t1_temp select * from t1_base' under FTWRL. +Success: Was able to run 'insert into t1_temp select * from t1_base' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'insert into t1_temp select * from t1_base' was active in another connection. +# +# 19) KILL statement is compatible with FTWRL. +# +# Check that KILL can be run under FTWRL. +flush tables with read lock; +set @id:= connection_id(); +kill query @id; +ERROR 70100: Query execution was interrupted +unlock tables; +# Check that KILL statements can be run while FTWRL +# is active in another connection. +# +# Switching to connection 'con1'. +flush tables with read lock; +# Switching to connection 'default'. +kill query @id; +ERROR 70100: Query execution was interrupted +# Switching to connection 'con1'. +unlock tables; +# Switching to connection 'default'. +# Finally check that KILL doesn't block FTWRL +set debug_sync='RESET'; +set debug_sync='execute_command_after_close_tables SIGNAL parked WAIT_FOR go'; +kill query @id; +# Switching to connection 'con1'. +set debug_sync='now WAIT_FOR parked'; +flush tables with read lock; +unlock tables; +set debug_sync='now SIGNAL go'; +# Switching to connection 'default'. +# Reap KILL. +ERROR 70100: Query execution was interrupted +set debug_sync='RESET'; +# +# 20) LOAD DATA statement. +# +# 20.a) LOAD DATA into base table is incompatible with FTWRL. +Success: Was not able to run 'load data infile '../../std_data/rpl_loaddata.dat' into table t1_base (@dummy, i)' under FTWRL. +Success: 'load data infile '../../std_data/rpl_loaddata.dat' into table t1_base (@dummy, i)' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'load data infile '../../std_data/rpl_loaddata.dat' into table t1_base (@dummy, i)' is active in another connection. +# +# 20.b) LOAD DATA into temporary table is compatible with FTWRL. +Success: Was able to run 'load data infile '../../std_data/rpl_loaddata.dat' into table t1_temp (@dummy, i)' under FTWRL. +Success: Was able to run 'load data infile '../../std_data/rpl_loaddata.dat' into table t1_temp (@dummy, i)' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'load data infile '../../std_data/rpl_loaddata.dat' into table t1_temp (@dummy, i)' was active in another connection. +# +# 21) LOCK/UNLOCK TABLES statements. +# +# LOCK TABLES statement always (almost) blocks FTWRL as it +# keeps tables open until UNLOCK TABLES. +# Active FTWRL on the other hand blocks only those +# LOCK TABLES which allow updating of base tables. +# +# 21.a) LOCK TABLES READ is allowed under FTWRL and +# is not blocked by active FTWRL. +flush tables with read lock; +lock tables t1_base read; +unlock tables; +# +# Switching to connection 'con1'. +flush tables with read lock; +# Switching to connection 'default'. +lock tables t1_base read; +unlock tables; +# Switching to connection 'con1'. +unlock tables; +# Switching to connection 'default'. +# +# 21.b) LOCK TABLES WRITE on a base table is disallowed +# under FTWRL and should be blocked by active FTWRL. +flush tables with read lock; +lock tables t1_base write; +ERROR HY000: Can't execute the query because you have a conflicting read lock +unlock tables; +# +# Switching to connection 'con1'. +flush tables with read lock; +# Switching to connection 'default'. +lock tables t1_base write ; +# Switching to connection 'con1'. +# Check that LOCK TABLES WRITE is blocked. +unlock tables; +# Switching to connection 'default'. +# Reap LOCK TABLES WRITE +unlock tables; +# +# 21.c) LOCK TABLES WRITE on temporary table doesn't +# make much sense but is allowed under FTWRL +# and should not be blocked by active FTWRL. +flush tables with read lock; +lock tables t1_temp write; +unlock tables; +# +# Switching to connection 'con1'. +flush tables with read lock; +# Switching to connection 'default'. +lock tables t1_temp write; +unlock tables; +# Switching to connection 'con1'. +unlock tables; +# Switching to connection 'default'. +# +# 22) OPTIMIZE TABLE statement. +# +# 22.a) OPTIMIZE TABLE of base table is incompatible with FTWRL. +flush tables with read lock; +# OPTIMIZE statement returns errors as part of result-set. +optimize table t1_base; +Table Op Msg_type Msg_text +test.t1_base optimize Error Can't execute the query because you have a conflicting read lock +test.t1_base optimize error Corrupt +unlock tables; +# +# Switching to connection 'con1'. +flush tables with read lock; +# Switching to connection 'default'. +optimize table t1_base; +# Switching to connection 'con1'. +# Check that OPTIMIZE TABLE is blocked. +unlock tables; +# Switching to connection 'default'. +# Reap OPTIMIZE TABLE +Table Op Msg_type Msg_text +test.t1_base optimize status OK +# We don't check that active OPTIMIZE TABLE blocks +# FTWRL as this one of statements releasing metadata +# locks in non-standard place. +# +# 22.b) OPTIMIZE TABLE of temporary table is compatible with FTWRL. +# Skip last part of compatibility testing as this statement +# releases metadata locks in non-standard place. +Success: Was able to run 'optimize table t1_temp' under FTWRL. +Success: Was able to run 'optimize table t1_temp' with FTWRL active in another connection. +# +# 23) CACHE statement is compatible with FTWRL. +# +# Skip last part of compatibility testing as this statement +# releases metadata locks in non-standard place. +Success: Was able to run 'cache index t1_base in default' under FTWRL. +Success: Was able to run 'cache index t1_base in default' with FTWRL active in another connection. +# +# 24) LOAD INDEX statement is compatible with FTWRL. +# +# Skip last part of compatibility testing as this statement +# releases metadata locks in non-standard place. +Success: Was able to run 'load index into cache t1_base' under FTWRL. +Success: Was able to run 'load index into cache t1_base' with FTWRL active in another connection. +# +# 25) SAVEPOINT/RELEASE SAVEPOINT/ROLLBACK TO SAVEPOINT are +# compatible with FTWRL. +# +# Since manipulations on savepoint have to be done +# inside transaction and FTWRL commits transaction we +# need a special test for these statements. +flush tables with read lock; +begin; +savepoint sv1; +rollback to savepoint sv1; +release savepoint sv1; +unlock tables; +commit; +# Check that these statements are not blocked by +# active FTWRL in another connection. +# +# Switching to connection 'con1'. +flush tables with read lock; +# Switching to connection 'default'. +begin; +# Switching to connection 'con1'. +unlock tables; +# Switching to connection 'default'. +# Do some changes to avoid SAVEPOINT and friends +# being almost no-ops. +insert into t3_trans values (1); +# Switching to connection 'con1'. +flush tables with read lock; +# Switching to connection 'default'. +savepoint sv1; +# Switching to connection 'con1'. +unlock tables; +# Switching to connection 'default'. +insert into t3_trans values (2); +# Switching to connection 'con1'. +flush tables with read lock; +# Switching to connection 'default'. +rollback to savepoint sv1; +release savepoint sv1; +# Switching to connection 'con1'. +unlock tables; +# Switching to connection 'default'. +rollback; +# Check that these statements don't block FTWRL in +# another connection. +begin; +# Do some changes to avoid SAVEPOINT and friends +# being almost no-ops. +insert into t3_trans values (1); +set debug_sync='RESET'; +set debug_sync='execute_command_after_close_tables SIGNAL parked WAIT_FOR go'; +savepoint sv1; +# Switching to connection 'con1'. +set debug_sync='now WAIT_FOR parked'; +flush tables with read lock; +unlock tables; +set debug_sync='now SIGNAL go'; +# Switching to connection 'default'. +# Reap SAVEPOINT +insert into t3_trans values (2); +set debug_sync='execute_command_after_close_tables SIGNAL parked WAIT_FOR go'; +rollback to savepoint sv1; +# Switching to connection 'con1'. +set debug_sync='now WAIT_FOR parked'; +flush tables with read lock; +unlock tables; +set debug_sync='now SIGNAL go'; +# Switching to connection 'default'. +# Reap ROLLBACK TO SAVEPOINT +set debug_sync='execute_command_after_close_tables SIGNAL parked WAIT_FOR go'; +release savepoint sv1; +# Switching to connection 'con1'. +set debug_sync='now WAIT_FOR parked'; +flush tables with read lock; +unlock tables; +set debug_sync='now SIGNAL go'; +# Switching to connection 'default'. +# Reap RELEASE SAVEPOINT +rollback; +set debug_sync= "RESET"; +# +# 26) RENAME variants. +# +# 26.1) RENAME TABLES is incompatible with FTWRL. +Success: Was not able to run 'rename table t1_base to t3_base' under FTWRL. +Success: 'rename table t1_base to t3_base' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'rename table t1_base to t3_base' is active in another connection. +# +# 26.2) RENAME USER is incompatible with FTWRL. +create user mysqltest_u1; +Success: Was not able to run 'rename user mysqltest_u1 to mysqltest_u2' under FTWRL. +Success: 'rename user mysqltest_u1 to mysqltest_u2' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'rename user mysqltest_u1 to mysqltest_u2' is active in another connection. +drop user mysqltest_u1; +# +# 27) REPAIR TABLE statement. +# +# 27.a) REPAIR TABLE of base table is incompatible with FTWRL. +flush tables with read lock; +# REPAIR statement returns errors as part of result-set. +repair table t1_base; +Table Op Msg_type Msg_text +test.t1_base repair Error Can't execute the query because you have a conflicting read lock +test.t1_base repair error Corrupt +unlock tables; +# +# Switching to connection 'con1'. +flush tables with read lock; +# Switching to connection 'default'. +repair table t1_base; +# Switching to connection 'con1'. +# Check that REPAIR TABLE is blocked. +unlock tables; +# Switching to connection 'default'. +# Reap REPAIR TABLE +Table Op Msg_type Msg_text +test.t1_base repair status OK +# We don't check that active REPAIR TABLE blocks +# FTWRL as this one of statements releasing metadata +# locks in non-standard place. +# +# 27.b) REPAIR TABLE of temporary table is compatible with FTWRL. +# Skip last part of compatibility testing as this statement +# releases metadata locks in non-standard place. +Success: Was able to run 'repair table t1_temp' under FTWRL. +Success: Was able to run 'repair table t1_temp' with FTWRL active in another connection. +# +# 28) REPLACE statement. +# +# 28.a) Ordinary REPLACE into base table is incompatible with FTWRL. +Success: Was not able to run 'replace into t1_base values (1)' under FTWRL. +Success: 'replace into t1_base values (1)' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'replace into t1_base values (1)' is active in another connection. +# +# 28.b) Ordinary REPLACE into temp table is compatible with FTWRL. +Success: Was able to run 'replace into t1_temp values (1)' under FTWRL. +Success: Was able to run 'replace into t1_temp values (1)' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'replace into t1_temp values (1)' was active in another connection. +# +# 28.c) REPLACE SELECT into base table is incompatible with FTWRL. +Success: Was not able to run 'replace into t1_base select * from t1_temp' under FTWRL. +Success: 'replace into t1_base select * from t1_temp' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'replace into t1_base select * from t1_temp' is active in another connection. +# +# 28.d) REPLACE SELECT into temp table is compatible with FTWRL. +Success: Was able to run 'replace into t1_temp select * from t1_base' under FTWRL. +Success: Was able to run 'replace into t1_temp select * from t1_base' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'replace into t1_temp select * from t1_base' was active in another connection. +# +# 29) REVOKE variants. +# +# 29.1) REVOKE privileges is incompatible with FTWRL. +grant all privileges on t1_base to mysqltest_u1; +Success: Was not able to run 'revoke all privileges on t1_base from mysqltest_u1' under FTWRL. +Success: 'revoke all privileges on t1_base from mysqltest_u1' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'revoke all privileges on t1_base from mysqltest_u1' is active in another connection. +# +# 29.2) REVOKE ALL PRIVILEGES, GRANT OPTION is incompatible with FTWRL. +Success: Was not able to run 'revoke all privileges, grant option from mysqltest_u1' under FTWRL. +Success: 'revoke all privileges, grant option from mysqltest_u1' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'revoke all privileges, grant option from mysqltest_u1' is active in another connection. +drop user mysqltest_u1; +# +# 30) Compatibility of SELECT statement with FTWRL depends on +# locking mode used and on functions being invoked by it. +# +# 30.a) Simple SELECT which does not change tables should be +# compatible with FTWRL. +Success: Was able to run 'select count(*) from t1_base' under FTWRL. +Success: Was able to run 'select count(*) from t1_base' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'select count(*) from t1_base' was active in another connection. +# 30.b) SELECT ... FOR UPDATE is incompatible with FTWRL. +Success: Was not able to run 'select count(*) from t1_base for update' under FTWRL. +Success: 'select count(*) from t1_base for update' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'select count(*) from t1_base for update' is active in another connection. +# 30.c) SELECT ... LOCK IN SHARE MODE is compatible with FTWRL. +Success: Was able to run 'select count(*) from t1_base lock in share mode' under FTWRL. +Success: Was able to run 'select count(*) from t1_base lock in share mode' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'select count(*) from t1_base lock in share mode' was active in another connection. +# +# 30.d) SELECT which calls SF updating base table should be +# incompatible with FTWRL. +Success: Was not able to run 'select f2_base()' under FTWRL. +Success: 'select f2_base()' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'select f2_base()' is active in another connection. +# +# 30.e) SELECT which calls SF updating temporary table should be +# compatible with FTWRL. +Success: Was able to run 'select f2_temp()' under FTWRL. +Success: Was able to run 'select f2_temp()' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'select f2_temp()' was active in another connection. +# +# 31) Compatibility of SET statement with FTWRL depends on its +# expression and on whether it is a special SET statement. +# +# 31.a) Ordinary SET with expression which does not +# changes base table should be compatible with FTWRL. +# Skip last part of compatibility testing as our helper debug +# sync-point doesn't work for SET statements. +Success: Was able to run 'set @a:= (select count(*) from t1_base)' under FTWRL. +Success: Was able to run 'set @a:= (select count(*) from t1_base)' with FTWRL active in another connection. +# +# 31.b) Ordinary SET which calls SF updating base table should +# be incompatible with FTWRL. +# Skip last part of compatibility testing as our helper debug +# sync-point doesn't work for SET statements. +Success: Was not able to run 'set @a:= f2_base()' under FTWRL. +Success: 'set @a:= f2_base()' is blocked by FTWRL active in another connection. +# +# 31.c) Ordinary SET which calls SF updating temporary table +# should be compatible with FTWRL. +# Skip last part of compatibility testing as our helper debug +# sync-point doesn't work for SET statements. +Success: Was able to run 'set @a:= f2_temp()' under FTWRL. +Success: Was able to run 'set @a:= f2_temp()' with FTWRL active in another connection. +# +# 31.d) Special SET variants have different compatibility with FTWRL. +# +# 31.d.I) SET PASSWORD is incompatible with FTWRL as it changes data. +create user mysqltest_u1; +# Skip last part of compatibility testing as our helper debug +# sync-point doesn't work for SET statements. +Success: Was not able to run 'set password for 'mysqltest_u1' = password('')' under FTWRL. +Success: 'set password for 'mysqltest_u1' = password('')' is blocked by FTWRL active in another connection. +drop user mysqltest_u1; +# +# 31.d.II) SET READ_ONLY is compatible with FTWRL (but has no +# effect when executed under it). +# Skip last part of compatibility testing as our helper debug +# sync-point doesn't work for SET statements. +Success: Was able to run 'set global read_only= 1' under FTWRL. +Success: Was able to run 'set global read_only= 1' with FTWRL active in another connection. +# +# 31.d.III) Situation with SET AUTOCOMMIT is complex. +# Turning auto-commit off is always compatible with FTWRL. +# Turning auto-commit on causes implicit commit and so +# is incompatible with FTWRL if there are changes to be +# committed. +flush tables with read lock; +set autocommit= 0; +# Turning auto-commit on causes implicit commit so can +# be incompatible with FTWRL if there is something to +# commit. But since even in this case we allow commits +# under active FTWRL such statement should always succeed. +insert into t3_temp_trans values (1); +set autocommit= 1; +unlock tables; +delete from t3_temp_trans; +# Check that SET AUTOCOMMIT=0 is not blocked and +# SET AUTOCOMMIT=1 is blocked by active FTWRL in +# another connection. +# +# Switching to connection 'con1'. +flush tables with read lock; +# Switching to connection 'default'. +set autocommit= 0; +# Switching to connection 'con1'. +unlock tables; +# Switching to connection 'default'. +# Do some work so implicit commit in SET AUTOCOMMIT=1 +# is not a no-op. +insert into t3_trans values (1); +# Switching to connection 'con1'. +flush tables with read lock; +# Switching to connection 'default'. +# Send: +set autocommit= 1; +# Switching to connection 'con1'. +# Wait until SET AUTOCOMMIT=1 is blocked. +unlock tables; +# Switching to connection 'default'. +# Reap SET AUTOCOMMIT=1. +delete from t3_trans; +# +# Check that SET AUTOCOMMIT=1 blocks FTWRL in another connection. +set autocommit= 0; +insert into t3_trans values (1); +set debug_sync='RESET'; +set debug_sync='ha_commit_trans_after_acquire_commit_lock SIGNAL parked WAIT_FOR go'; +set autocommit= 1; +# Switching to connection 'con1'. +set debug_sync='now WAIT_FOR parked'; +flush tables with read lock; +# Switching to connection 'con2'. +# Wait until FTWRL is blocked. +set debug_sync='now SIGNAL go'; +# Switching to connection 'default'. +# Reap SET AUTOCOMMIT=1. +# Switching to connection 'con1'. +# Reap FTWRL. +unlock tables; +# Switching to connection 'default'. +delete from t3_trans; +set debug_sync= "RESET"; +# +# 32) SHOW statements are compatible with FTWRL. +# Let us test _some_ of them. +# +# 32.1) SHOW TABLES. +Success: Was able to run 'show tables from test' under FTWRL. +Success: Was able to run 'show tables from test' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'show tables from test' was active in another connection. +# +# 32.1) SHOW TABLES. +Success: Was able to run 'show tables from test' under FTWRL. +Success: Was able to run 'show tables from test' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'show tables from test' was active in another connection. +# +# 32.2) SHOW EVENTS. +Success: Was able to run 'show events from test' under FTWRL. +Success: Was able to run 'show events from test' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'show events from test' was active in another connection. +# +# 32.3) SHOW GRANTS. +create user mysqltest_u1; +Success: Was able to run 'show grants for mysqltest_u1' under FTWRL. +Success: Was able to run 'show grants for mysqltest_u1' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'show grants for mysqltest_u1' was active in another connection. +drop user mysqltest_u1; +# +# 32.4) SHOW CREATE TABLE. +Success: Was able to run 'show create table t1_base' under FTWRL. +Success: Was able to run 'show create table t1_base' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'show create table t1_base' was active in another connection. +# +# 32.5) SHOW CREATE FUNCTION. +Success: Was able to run 'show create function f1' under FTWRL. +Success: Was able to run 'show create function f1' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'show create function f1' was active in another connection. +# +# 33) SIGNAL statement is compatible with FTWRL. +# +# Note that we don't cover RESIGNAL as it requires +# active handler context. +Success: Was able to run 'signal sqlstate '01000'' under FTWRL. +Success: Was able to run 'signal sqlstate '01000'' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'signal sqlstate '01000'' was active in another connection. +# +# 34) TRUNCATE TABLE statement. +# +# 34.a) TRUNCATE of base table is incompatible with FTWRL. +Success: Was not able to run 'truncate table t1_base' under FTWRL. +Success: 'truncate table t1_base' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'truncate table t1_base' is active in another connection. +# +# 34.b) TRUNCATE of temporary table is compatible with FTWRL. +Success: Was able to run 'truncate table t1_temp' under FTWRL. +Success: Was able to run 'truncate table t1_temp' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'truncate table t1_temp' was active in another connection. +# +# 35) UPDATE variants. +# +# 35.1) Simple UPDATE. +# +# 35.1.a) Simple UPDATE on base table is incompatible with FTWRL. +Success: Was not able to run 'update t1_base set i= 1 where i = 0' under FTWRL. +Success: 'update t1_base set i= 1 where i = 0' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'update t1_base set i= 1 where i = 0' is active in another connection. +# +# 35.1.b) Simple UPDATE on temporary table is compatible with FTWRL. +Success: Was able to run 'update t1_temp set i= 1 where i = 0' under FTWRL. +Success: Was able to run 'update t1_temp set i= 1 where i = 0' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'update t1_temp set i= 1 where i = 0' was active in another connection. +# +# 35.2) Multi UPDATE. +# +# 35.2.a) Multi UPDATE on base tables is incompatible with FTWRL. +Success: Was not able to run 'update t1_base, t2_base set t1_base.i= 1 where t1_base.i = t2_base.j' under FTWRL. +Success: 'update t1_base, t2_base set t1_base.i= 1 where t1_base.i = t2_base.j' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'update t1_base, t2_base set t1_base.i= 1 where t1_base.i = t2_base.j' is active in another connection. +# +# 35.2.b) Multi UPDATE on temporary tables is compatible with FTWRL. +Success: Was able to run 'update t1_temp, t2_temp set t1_temp.i= 1 where t1_temp.i = t2_temp.j' under FTWRL. +Success: Was able to run 'update t1_temp, t2_temp set t1_temp.i= 1 where t1_temp.i = t2_temp.j' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'update t1_temp, t2_temp set t1_temp.i= 1 where t1_temp.i = t2_temp.j' was active in another connection. +# +# 36) USE statement is compatible with FTWRL. +# +Success: Was able to run 'use mysqltest1' under FTWRL. +Success: Was able to run 'use mysqltest1' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'use mysqltest1' was active in another connection. +# +# 37) XA statements. +# +# XA statements are similar to BEGIN/COMMIT/ROLLBACK. +# +# XA BEGIN, END, PREPARE, ROLLBACK and RECOVER are compatible +# with FTWRL. XA COMMIT is not. +flush tables with read lock; +# Although all below statements are allowed under FTWRL they +# are almost no-ops as FTWRL does commit and does not allows +# any non-temporary DML under it. +xa start 'test1'; +xa end 'test1'; +xa prepare 'test1'; +xa rollback 'test1'; +xa start 'test1'; +xa end 'test1'; +xa prepare 'test1'; +xa commit 'test1'; +xa recover; +unlock tables; +# Check that XA non-COMMIT statements are not and COMMIT is +# blocked by active FTWRL in another connection +# +# Switching to connection 'con1'. +flush tables with read lock; +# Switching to connection 'default'. +xa start 'test1'; +# Switching to connection 'con1'. +unlock tables; +# Switching to connection 'default'. +insert into t3_trans values (1); +# Switching to connection 'con1'. +flush tables with read lock; +# Switching to connection 'default'. +xa end 'test1'; +xa prepare 'test1'; +xa rollback 'test1'; +# Switching to connection 'con1'. +unlock tables; +# Switching to connection 'default'. +xa start 'test1'; +insert into t3_trans values (1); +# Switching to connection 'con1'. +flush tables with read lock; +# Switching to connection 'default'. +xa end 'test1'; +xa prepare 'test1'; +# Send: +xa commit 'test1';; +# Switching to connection 'con1'. +# Wait until XA COMMIT is blocked. +unlock tables; +# Switching to connection 'default'. +# Reap XA COMMIT. +delete from t3_trans; +# +# Check that XA COMMIT blocks FTWRL in another connection. +xa start 'test1'; +insert into t3_trans values (1); +xa end 'test1'; +xa prepare 'test1'; +set debug_sync='RESET'; +set debug_sync='trans_xa_commit_after_acquire_commit_lock SIGNAL parked WAIT_FOR go'; +xa commit 'test1'; +# Switching to connection 'con1'. +set debug_sync='now WAIT_FOR parked'; +flush tables with read lock; +# Switching to connection 'con2'. +# Wait until FTWRL is blocked. +set debug_sync='now SIGNAL go'; +# Switching to connection 'default'. +# Reap XA COMMIT. +# Switching to connection 'con1'. +# Reap FTWRL. +unlock tables; +# Switching to connection 'default'. +delete from t3_trans; +set debug_sync= "RESET"; +# +# 38) Test effect of auto-commit mode for DML on transactional +# temporary tables. +# +# 38.1) When auto-commit is on each such a statement ends with commit +# of changes to temporary tables. But since transactions doing +# such changes are considered read only [sic!/QQ] this commit +# is compatible with FTWRL. +# +# Let us demostrate this fact for some common DML statements. +Success: Was able to run 'delete from t3_temp_trans' under FTWRL. +Success: Was able to run 'delete from t3_temp_trans' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'delete from t3_temp_trans' was active in another connection. +Success: Was able to run 'insert into t3_temp_trans values (1)' under FTWRL. +Success: Was able to run 'insert into t3_temp_trans values (1)' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'insert into t3_temp_trans values (1)' was active in another connection. +Success: Was able to run 'update t3_temp_trans, t2_temp set t3_temp_trans.i= 1 where t3_temp_trans.i = t2_temp.j' under FTWRL. +Success: Was able to run 'update t3_temp_trans, t2_temp set t3_temp_trans.i= 1 where t3_temp_trans.i = t2_temp.j' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'update t3_temp_trans, t2_temp set t3_temp_trans.i= 1 where t3_temp_trans.i = t2_temp.j' was active in another connection. +# +# 38.2) When auto-commit is off DML on transaction temporary tables +# is compatible with FTWRL. +# +set autocommit= 0; +Success: Was able to run 'delete from t3_temp_trans' under FTWRL. +Success: Was able to run 'delete from t3_temp_trans' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'delete from t3_temp_trans' was active in another connection. +Success: Was able to run 'insert into t3_temp_trans values (1)' under FTWRL. +Success: Was able to run 'insert into t3_temp_trans values (1)' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'insert into t3_temp_trans values (1)' was active in another connection. +Success: Was able to run 'update t3_temp_trans, t2_temp set t3_temp_trans.i= 1 where t3_temp_trans.i = t2_temp.j' under FTWRL. +Success: Was able to run 'update t3_temp_trans, t2_temp set t3_temp_trans.i= 1 where t3_temp_trans.i = t2_temp.j' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'update t3_temp_trans, t2_temp set t3_temp_trans.i= 1 where t3_temp_trans.i = t2_temp.j' was active in another connection. +set autocommit= 1; +# +# 39) Test effect of DDL on transactional tables. +# +# 39.1) Due to implicit commit at the end of statement some of DDL +# statements which are compatible with FTWRL in non-transactional +# case are not compatible in case of transactional tables. +# +# 39.1.a) ANALYZE TABLE for transactional table is incompatible with +# FTWRL. +flush tables with read lock; +# Implicit commits are allowed under FTWRL. +analyze table t3_trans; +Table Op Msg_type Msg_text +test.t3_trans analyze status OK +unlock tables; +# +# Switching to connection 'con1'. +flush tables with read lock; +# Switching to connection 'default'. +analyze table t3_trans; +# Switching to connection 'con1'. +# Check that ANALYZE TABLE is blocked. +unlock tables; +# Switching to connection 'default'. +# Reap ANALYZE TABLE +Table Op Msg_type Msg_text +test.t3_trans analyze status OK +# +# 39.1.b) CHECK TABLE for transactional table is compatible with FTWRL. +# Although it does implicit commit at the end of statement it +# is considered to be read-only operation. +# Skip last part of compatibility testing as this statement +# releases metadata locks in non-standard place. +Success: Was able to run 'check table t3_trans' under FTWRL. +Success: Was able to run 'check table t3_trans' with FTWRL active in another connection. +# +# 39.2) Situation with DDL on temporary transactional tables is +# complex. +# +# 39.2.a) Some statements compatible with FTWRL since they don't +# do implicit commit. +# +# For example, CREATE TEMPORARY TABLE: +Success: Was able to run 'create temporary table t4_temp_trans(i int) engine=innodb' under FTWRL. +Success: Was able to run 'create temporary table t4_temp_trans(i int) engine=innodb' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'create temporary table t4_temp_trans(i int) engine=innodb' was active in another connection. +# +# Or DROP TEMPORARY TABLE: +Success: Was able to run 'drop temporary tables t3_temp_trans' under FTWRL. +Success: Was able to run 'drop temporary tables t3_temp_trans' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'drop temporary tables t3_temp_trans' was active in another connection. +# +# 39.2.b) Some statements do implicit commit but are considered +# read-only and so are compatible with FTWRL. +# +# For example, REPAIR TABLE: +Success: Was able to run 'repair table t3_temp_trans' under FTWRL. +Success: Was able to run 'repair table t3_temp_trans' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'repair table t3_temp_trans' was active in another connection. +# +# And ANALYZE TABLE: +Success: Was able to run 'analyze table t3_temp_trans' under FTWRL. +Success: Was able to run 'analyze table t3_temp_trans' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'analyze table t3_temp_trans' was active in another connection. +# +# 39.2.c) Some statements do implicit commit and not +# considered read-only. As result they are +# not compatible with FTWRL. +# +flush tables with read lock; +# Implicit commits are allowed under FTWRL. +alter table t3_temp_trans add column c1 int; +unlock tables; +# +# Switching to connection 'con1'. +flush tables with read lock; +# Switching to connection 'default'. +alter table t3_temp_trans drop column c1; +# Switching to connection 'con1'. +# Check that ALTER TABLE is blocked. +unlock tables; +# Switching to connection 'default'. +# Reap ALTER TABLE +# +# 40) Test effect of implicit commit for DDL which is otherwise +# compatible with FTWRL. Implicit commit at the start of DDL +# statement can make it incompatible with FTWRL if there are +# some changes to be commited even in case when DDL statement +# itself is compatible with FTWRL. +# +# For example CHECK TABLE for base non-transactional tables and +# ALTER TABLE for temporary non-transactional tables are affected. +begin; +insert into t3_trans values (1); +# +# Switching to connection 'con1'. +flush tables with read lock; +# Switching to connection 'default'. +check table t1_base; +# Switching to connection 'con1'. +# Check that CHECK TABLE is blocked. +unlock tables; +# Switching to connection 'default'. +# Reap CHECK TABLE +Table Op Msg_type Msg_text +test.t1_base check status OK +begin; +delete from t3_trans; +# +# Switching to connection 'con1'. +flush tables with read lock; +# Switching to connection 'default'. +alter table t1_temp add column c1 int; +# Switching to connection 'con1'. +# Check that ALTER TABLE is blocked. +unlock tables; +# Switching to connection 'default'. +# Reap ALTER TABLE +alter table t1_temp drop column c1; +# +# Check that FLUSH TABLES WITH READ LOCK is blocked by individual +# statements and is not blocked in the presence of transaction which +# has done some changes earlier but is idle now (or does only reads). +# This allows to use this statement even on systems which has long +# running transactions. +# +begin; +insert into t1_base values (1); +insert into t3_trans values (1); +# Switching to connection 'con1'. +# The below FTWRL should not be blocked by transaction in 'default'. +flush tables with read lock; +# Switching to connection 'default'. +# Transaction still is able to read even with FTWRL active in another +# connection. +select * from t1_base; +i +1 +select * from t2_base; +j +select * from t3_trans; +i +1 +# Switching to connection 'con1'. +unlock tables; +# Switching to connection 'default'. +commit; +delete from t1_base; +delete from t3_trans; +# +# Check that impending FTWRL blocks new DML statements and +# so can't be starved by a constant flow of DML. +# (a.k.a. test for bug #54673 "It takes too long to get +# readlock for 'FLUSH TABLES WITH READ LOCK'"). +# +set debug_sync='RESET'; +set debug_sync='execute_command_after_close_tables SIGNAL parked WAIT_FOR go'; +insert into t1_base values (1); +# Switching to connection 'con1'. +set debug_sync='now WAIT_FOR parked'; +flush tables with read lock; +# Switching to connection 'con2'. +# Wait until FTWRL is blocked. +# Try to run another INSERT and see that it is blocked. +insert into t2_base values (1);; +# Switching to connection 'con3'. +# Wait until new INSERT is blocked. +# Unblock INSERT in the first connection. +set debug_sync='now SIGNAL go'; +# Switching to connection 'default'. +# Reap first INSERT. +# Switching to connection 'con1'. +# Reap FTWRL. +unlock tables; +# Switching to connection 'con2'. +# Reap second INSERT. +# Switching to connection 'default'. +set debug_sync= "RESET"; +delete from t1_base; +delete from t2_base; + +# Check that COMMIT thas is issued after +# FLUSH TABLES WITH READ LOCK is not blocked by +# FLUSH TABLES WITH READ LOCK from another connection. +# This scenario is used in innobackup.pl. The COMMIT goes +# through because the transaction started by FTWRL does +# not modify any tables, and the commit blocker lock is +# only taken when there were such modifications. + +flush tables with read lock; +# Switching to connection 'con1'. +# The below FTWRL should not be blocked by transaction in 'default'. +flush tables with read lock; +# Switching to connection 'default'. +select * from t1_base; +i +select * from t3_trans; +i +commit; +# Switching to connection 'con1'. +select * from t1_base; +i +select * from t3_trans; +i +commit; +unlock tables; +# Switching to connection 'default'. +unlock tables; +# +# Check how FLUSH TABLE WITH READ LOCK is handled for MERGE tables. +# As usual there are tricky cases related to this type of tables. +# +# +# 1) Most typical case - base MERGE table with base underlying tables. +# +# 1.a) DML statements which change data should be incompatible with FTWRL. +create table tm_base (i int) engine=merge union=(t1_base) insert_method=last; +Success: Was not able to run 'insert into tm_base values (1)' under FTWRL. +Success: 'insert into tm_base values (1)' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'insert into tm_base values (1)' is active in another connection. +# +# 1.b) DDL statement on such table should be incompatible with FTWRL as well. +Success: Was not able to run 'alter table tm_base insert_method=first' under FTWRL. +Success: 'alter table tm_base insert_method=first' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'alter table tm_base insert_method=first' is active in another connection. +drop table tm_base; +# +# 2) Temporary MERGE table with base underlying tables. +# +# 2.a) DML statements which change data should be incompatible with FTWRL +# as they affect base tables. +create temporary table tm_temp_base (i int) engine=merge union=(t1_base) insert_method=last; +Success: Was not able to run 'insert into tm_temp_base values (1)' under FTWRL. +Success: 'insert into tm_temp_base values (1)' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'insert into tm_temp_base values (1)' is active in another connection. +# +# 2.b) Some of DDL statements on such table can be compatible with FTWRL +# as they don't affect base tables. +Success: Was able to run 'drop temporary tables tm_temp_base' under FTWRL. +Success: Was able to run 'drop temporary tables tm_temp_base' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'drop temporary tables tm_temp_base' was active in another connection. +# +# 2.c) ALTER statement is incompatible with FTWRL. Even though it does +# not change data in base table it still acquires strong metadata +# locks on them. +Success: Was not able to run 'alter table tm_temp_base insert_method=first' under FTWRL. +Success: 'alter table tm_temp_base insert_method=first' is blocked by FTWRL active in another connection. +Success: FTWRL is blocked when 'alter table tm_temp_base insert_method=first' is active in another connection. +drop table tm_temp_base; +# +# 3) Temporary MERGE table with temporary underlying tables. +# +# 3.a) DML statements should be compatible with FTWRL as +# no base table is going to be affected. +create temporary table tm_temp_temp (i int) engine=merge union=(t1_temp) insert_method=last; +Success: Was able to run 'insert into tm_temp_temp values (1)' under FTWRL. +Success: Was able to run 'insert into tm_temp_temp values (1)' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'insert into tm_temp_temp values (1)' was active in another connection. +# +# 3.b) DDL statements should be compatible with FTWRL as well +# as no base table is going to be affected too. +Success: Was able to run 'alter table tm_temp_temp union=(t1_temp) insert_method=first' under FTWRL. +Success: Was able to run 'alter table tm_temp_temp union=(t1_temp) insert_method=first' with FTWRL active in another connection. +Success: Was able to run FTWRL while 'alter table tm_temp_temp union=(t1_temp) insert_method=first' was active in another connection. +drop table tm_temp_temp; +# +# 4) For the sake of completeness let us check that base MERGE tables +# with temporary underlying tables are not functional. +create table tm_base_temp (i int) engine=merge union=(t1_temp) insert_method=last; +select * from tm_base_temp; +ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist +drop table tm_base_temp; +# +# Clean-up. +# +drop event e1; +drop function f2_temp; +drop function f2_base; +drop procedure p2; +drop view v1; +drop function f1; +drop procedure p1; +drop database `#mysql50#mysqltest-2`; +drop database mysqltest1; +drop temporary tables t1_temp, t2_temp; +drop tables t1_base, t2_base, t3_trans; diff --git a/mysql-test/r/flush_read_lock_kill.result b/mysql-test/r/flush_read_lock_kill.result index b16a8b114b3..8453d26cbea 100644 --- a/mysql-test/r/flush_read_lock_kill.result +++ b/mysql-test/r/flush_read_lock_kill.result @@ -1,12 +1,38 @@ -SET @old_concurrent_insert= @@global.concurrent_insert; -SET @@global.concurrent_insert= 0; DROP TABLE IF EXISTS t1; -CREATE TABLE t1 (kill_id INT); +SET DEBUG_SYNC= 'RESET'; +CREATE TABLE t1 (kill_id INT) engine = InnoDB; INSERT INTO t1 VALUES(connection_id()); +# Switching to connection 'default'. +# Start transaction. +BEGIN; +INSERT INTO t1 VALUES(connection_id()); +# Ensure that COMMIT will pause once it acquires protection +# against its global read lock. +SET DEBUG_SYNC='ha_commit_trans_after_acquire_commit_lock SIGNAL acquired WAIT_FOR go'; +# Sending: +COMMIT; +# Switching to 'con1'. +# Wait till COMMIT acquires protection against global read +# lock and pauses. +SET DEBUG_SYNC='now WAIT_FOR acquired'; +# Sending: FLUSH TABLES WITH READ LOCK; -SELECT ((@id := kill_id) - kill_id) FROM t1; +# Switching to 'con2'. +SELECT ((@id := kill_id) - kill_id) FROM t1 LIMIT 1; ((@id := kill_id) - kill_id) 0 +# Wait till FLUSH TABLES WITH READ LOCK blocks due +# to active COMMIT +# Kill connection 'con1'. KILL CONNECTION @id; +# Switching to 'con1'. +# Try to reap FLUSH TABLES WITH READ LOCK, +# it fail due to killed statement and connection. +Got one of the listed errors +# Switching to 'con2'. +# Resume COMMIT. +SET DEBUG_SYNC='now SIGNAL go'; +# Switching to 'default'. +# Reaping COMMIT. DROP TABLE t1; -SET @@global.concurrent_insert= @old_concurrent_insert; +SET DEBUG_SYNC= 'RESET'; diff --git a/mysql-test/r/handler_innodb.result b/mysql-test/r/handler_innodb.result index 66914285733..dd4cac669c8 100644 --- a/mysql-test/r/handler_innodb.result +++ b/mysql-test/r/handler_innodb.result @@ -1485,10 +1485,6 @@ ERROR 42S02: Table 'test.not_exists_write' doesn't exist # We still have the read lock. drop table t1; ERROR HY000: Can't execute the query because you have a conflicting read lock -handler t1 read next; -a b -1 1 -handler t1 close; handler t1 open; select a from t2; a diff --git a/mysql-test/r/handler_myisam.result b/mysql-test/r/handler_myisam.result index d5d43ca0717..69d791b8263 100644 --- a/mysql-test/r/handler_myisam.result +++ b/mysql-test/r/handler_myisam.result @@ -1481,10 +1481,6 @@ ERROR 42S02: Table 'test.not_exists_write' doesn't exist # We still have the read lock. drop table t1; ERROR HY000: Can't execute the query because you have a conflicting read lock -handler t1 read next; -a b -1 1 -handler t1 close; handler t1 open; select a from t2; a diff --git a/mysql-test/r/mdl_sync.result b/mysql-test/r/mdl_sync.result index d2a32c25201..594cf433692 100644 --- a/mysql-test/r/mdl_sync.result +++ b/mysql-test/r/mdl_sync.result @@ -2471,7 +2471,7 @@ CREATE PROCEDURE p1() SELECT 1; SET DEBUG_SYNC= 'now WAIT_FOR table_opened'; # Check that FLUSH must wait to get the GRL # and let CREATE PROCEDURE continue -SET DEBUG_SYNC= 'wait_lock_global_read_lock SIGNAL grlwait'; +SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL grlwait'; FLUSH TABLES WITH READ LOCK; # Connection 1 # Connection 2 @@ -2486,10 +2486,17 @@ DROP PROCEDURE p1; SET DEBUG_SYNC= 'now WAIT_FOR table_opened'; # Check that FLUSH must wait to get the GRL # and let DROP PROCEDURE continue -SET DEBUG_SYNC= 'wait_lock_global_read_lock SIGNAL grlwait'; +SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL grlwait'; FLUSH TABLES WITH READ LOCK; # Connection 1 +# Once FLUSH TABLES WITH READ LOCK starts waiting +# DROP PROCEDURE will be waked up and will drop +# procedure. Global read lock will be granted after +# this statement ends. +# +# Reaping DROP PROCEDURE. # Connection 2 +# Reaping FTWRL. UNLOCK TABLES; # Connection 1 SET DEBUG_SYNC= 'RESET'; diff --git a/mysql-test/suite/perfschema/r/dml_setup_instruments.result b/mysql-test/suite/perfschema/r/dml_setup_instruments.result index 2338252976c..15174ee40bf 100644 --- a/mysql-test/suite/perfschema/r/dml_setup_instruments.result +++ b/mysql-test/suite/perfschema/r/dml_setup_instruments.result @@ -37,7 +37,6 @@ where name like 'Wait/Synch/Cond/sql/%' order by name limit 10; NAME ENABLED TIMED wait/synch/cond/sql/COND_flush_thread_cache YES YES -wait/synch/cond/sql/COND_global_read_lock YES YES wait/synch/cond/sql/COND_manager YES YES wait/synch/cond/sql/COND_queue_state YES YES wait/synch/cond/sql/COND_rpl_status YES YES @@ -46,6 +45,7 @@ wait/synch/cond/sql/COND_thread_cache YES YES wait/synch/cond/sql/COND_thread_count YES YES wait/synch/cond/sql/Delayed_insert::cond YES YES wait/synch/cond/sql/Delayed_insert::cond_client YES YES +wait/synch/cond/sql/Event_scheduler::COND_state YES YES select * from performance_schema.SETUP_INSTRUMENTS where name='Wait'; select * from performance_schema.SETUP_INSTRUMENTS diff --git a/mysql-test/suite/perfschema/r/func_file_io.result b/mysql-test/suite/perfschema/r/func_file_io.result index 655ce1394f9..8314bed94bf 100644 --- a/mysql-test/suite/perfschema/r/func_file_io.result +++ b/mysql-test/suite/perfschema/r/func_file_io.result @@ -100,3 +100,4 @@ INNER JOIN performance_schema.THREADS p USING (THREAD_ID) WHERE p.PROCESSLIST_ID = 1 GROUP BY h.EVENT_NAME HAVING TOTAL_WAIT > 0; +UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'YES'; diff --git a/mysql-test/suite/perfschema/r/func_mutex.result b/mysql-test/suite/perfschema/r/func_mutex.result index e32d7267bb1..93ba4064a90 100644 --- a/mysql-test/suite/perfschema/r/func_mutex.result +++ b/mysql-test/suite/perfschema/r/func_mutex.result @@ -110,4 +110,5 @@ WHERE (EVENT_NAME = 'wait/synch/rwlock/sql/LOCK_grant')); SELECT IF((COALESCE(@after_count, 0) - COALESCE(@before_count, 0)) = 0, 'Success', 'Failure') test_fm2_rw_timed; test_fm2_rw_timed Success +UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'YES'; DROP TABLE t1; diff --git a/mysql-test/suite/perfschema/r/global_read_lock.result b/mysql-test/suite/perfschema/r/global_read_lock.result index 93d6adfd049..365ac095e84 100644 --- a/mysql-test/suite/perfschema/r/global_read_lock.result +++ b/mysql-test/suite/perfschema/r/global_read_lock.result @@ -1,4 +1,5 @@ use performance_schema; +update performance_schema.SETUP_INSTRUMENTS set enabled='YES'; grant SELECT, UPDATE, LOCK TABLES on performance_schema.* to pfsuser@localhost; flush privileges; connect (con1, localhost, pfsuser, , test); @@ -21,9 +22,9 @@ select event_name, left(source, locate(":", source)) as short_source, timer_end, timer_wait, operation from performance_schema.EVENTS_WAITS_CURRENT -where event_name like "wait/synch/cond/sql/COND_global_read_lock"; +where event_name like "wait/synch/cond/sql/MDL_context::COND_wait_status"; event_name short_source timer_end timer_wait operation -wait/synch/cond/sql/COND_global_read_lock lock.cc: NULL NULL wait +wait/synch/cond/sql/MDL_context::COND_wait_status mdl.cc: NULL NULL timed_wait unlock tables; update performance_schema.SETUP_INSTRUMENTS set enabled='NO'; update performance_schema.SETUP_INSTRUMENTS set enabled='YES'; diff --git a/mysql-test/suite/perfschema/r/server_init.result b/mysql-test/suite/perfschema/r/server_init.result index 0c1e06d157c..474a481929a 100644 --- a/mysql-test/suite/perfschema/r/server_init.result +++ b/mysql-test/suite/perfschema/r/server_init.result @@ -88,10 +88,6 @@ where name like "wait/synch/mutex/sql/LOCK_manager"; count(name) 1 select count(name) from MUTEX_INSTANCES -where name like "wait/synch/mutex/sql/LOCK_global_read_lock"; -count(name) -1 -select count(name) from MUTEX_INSTANCES where name like "wait/synch/mutex/sql/LOCK_global_system_variables"; count(name) 1 @@ -120,10 +116,6 @@ where name like "wait/synch/mutex/sql/Query_cache::structure_guard_mutex"; count(name) 1 select count(name) from MUTEX_INSTANCES -where name like "wait/synch/mutex/sql/LOCK_event_metadata"; -count(name) -1 -select count(name) from MUTEX_INSTANCES where name like "wait/synch/mutex/sql/LOCK_event_queue"; count(name) 1 @@ -184,10 +176,6 @@ where name like "wait/synch/cond/sql/COND_manager"; count(name) 1 select count(name) from COND_INSTANCES -where name like "wait/synch/cond/sql/COND_global_read_lock"; -count(name) -1 -select count(name) from COND_INSTANCES where name like "wait/synch/cond/sql/COND_thread_cache"; count(name) 1 diff --git a/mysql-test/suite/perfschema/t/func_file_io.test b/mysql-test/suite/perfschema/t/func_file_io.test index dc9a7a09e40..9ba8d061b12 100644 --- a/mysql-test/suite/perfschema/t/func_file_io.test +++ b/mysql-test/suite/perfschema/t/func_file_io.test @@ -190,3 +190,6 @@ HAVING TOTAL_WAIT > 0; ## HAVING BYTES > 0 ## ORDER BY i.user, h.operation; ## --enable_result_log + +# Clean-up. +UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'YES'; diff --git a/mysql-test/suite/perfschema/t/func_mutex.test b/mysql-test/suite/perfschema/t/func_mutex.test index 98cb905c67c..624f5734c40 100644 --- a/mysql-test/suite/perfschema/t/func_mutex.test +++ b/mysql-test/suite/perfschema/t/func_mutex.test @@ -128,4 +128,6 @@ SET @after_count = (SELECT SUM(TIMER_WAIT) SELECT IF((COALESCE(@after_count, 0) - COALESCE(@before_count, 0)) = 0, 'Success', 'Failure') test_fm2_rw_timed; +# Clean-up. +UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'YES'; DROP TABLE t1; diff --git a/mysql-test/suite/perfschema/t/global_read_lock.test b/mysql-test/suite/perfschema/t/global_read_lock.test index b953ea32ce0..9b7c54b1411 100644 --- a/mysql-test/suite/perfschema/t/global_read_lock.test +++ b/mysql-test/suite/perfschema/t/global_read_lock.test @@ -22,6 +22,10 @@ use performance_schema; +# Make test robust against errors in other tests. +# Ensure that instrumentation is turned on when we create new connection. +update performance_schema.SETUP_INSTRUMENTS set enabled='YES'; + grant SELECT, UPDATE, LOCK TABLES on performance_schema.* to pfsuser@localhost; flush privileges; @@ -60,7 +64,7 @@ lock tables performance_schema.SETUP_INSTRUMENTS write; --echo connection default; connection default; -let $wait_condition= select 1 from performance_schema.EVENTS_WAITS_CURRENT where event_name like "wait/synch/cond/sql/COND_global_read_lock"; +let $wait_condition= select 1 from performance_schema.EVENTS_WAITS_CURRENT where event_name like "wait/synch/cond/sql/MDL_context::COND_wait_status"; --source include/wait_condition.inc @@ -69,7 +73,7 @@ select event_name, left(source, locate(":", source)) as short_source, timer_end, timer_wait, operation from performance_schema.EVENTS_WAITS_CURRENT - where event_name like "wait/synch/cond/sql/COND_global_read_lock"; + where event_name like "wait/synch/cond/sql/MDL_context::COND_wait_status"; unlock tables; diff --git a/mysql-test/suite/perfschema/t/server_init.test b/mysql-test/suite/perfschema/t/server_init.test index cc461374a79..7036464ddb9 100644 --- a/mysql-test/suite/perfschema/t/server_init.test +++ b/mysql-test/suite/perfschema/t/server_init.test @@ -100,9 +100,6 @@ select count(name) from MUTEX_INSTANCES select count(name) from MUTEX_INSTANCES where name like "wait/synch/mutex/sql/LOCK_manager"; -select count(name) from MUTEX_INSTANCES - where name like "wait/synch/mutex/sql/LOCK_global_read_lock"; - select count(name) from MUTEX_INSTANCES where name like "wait/synch/mutex/sql/LOCK_global_system_variables"; @@ -132,9 +129,6 @@ select count(name) from MUTEX_INSTANCES # select count(name) from MUTEX_INSTANCES # where name like "wait/synch/mutex/sql/Event_scheduler::LOCK_scheduler_state"; -select count(name) from MUTEX_INSTANCES - where name like "wait/synch/mutex/sql/LOCK_event_metadata"; - select count(name) from MUTEX_INSTANCES where name like "wait/synch/mutex/sql/LOCK_event_queue"; @@ -188,9 +182,6 @@ select count(name) from COND_INSTANCES select count(name) from COND_INSTANCES where name like "wait/synch/cond/sql/COND_manager"; -select count(name) from COND_INSTANCES - where name like "wait/synch/cond/sql/COND_global_read_lock"; - select count(name) from COND_INSTANCES where name like "wait/synch/cond/sql/COND_thread_cache"; diff --git a/mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result b/mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result index 3136599e5aa..14af782a4d5 100644 --- a/mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result +++ b/mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result @@ -123,16 +123,16 @@ DROP PROCEDURE p2; ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction INSERT INTO t2 VALUES ("DROP PROCEDURE p2 with table locked"); CREATE EVENT e1 ON SCHEDULE EVERY 10 HOUR DO SELECT 1; -ERROR HY000: Table 'event' was not locked with LOCK TABLES +ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction INSERT INTO t2 VALUES ("CREATE EVENT e1 with table locked"); UNLOCK TABLE; CREATE EVENT e2 ON SCHEDULE EVERY 10 HOUR DO SELECT 1; LOCK TABLE t1 WRITE; ALTER EVENT e2 ON SCHEDULE EVERY 20 HOUR DO SELECT 1; -ERROR HY000: Table 'event' was not locked with LOCK TABLES +ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction INSERT INTO t2 VALUES ("ALTER EVENT e2 with table locked"); DROP EVENT e2; -ERROR HY000: Table 'event' was not locked with LOCK TABLES +ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction INSERT INTO t2 VALUES ("DROP EVENT e2 with table locked"); CREATE DATABASE mysqltest1; ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction diff --git a/mysql-test/t/delayed.test b/mysql-test/t/delayed.test index 3a2bc982ad3..c47db78a11b 100644 --- a/mysql-test/t/delayed.test +++ b/mysql-test/t/delayed.test @@ -539,6 +539,21 @@ connection con1; --echo # Reaping: INSERT DELAYED INTO t1 VALUES (5) --reap +--echo # Connection default +connection default; + +--echo # Test 5: LOCK TABLES + INSERT DELAYED in one connection. +--echo # This test has triggered some asserts in metadata locking +--echo # subsystem at some point in time.. +LOCK TABLE t1 WRITE; +INSERT DELAYED INTO t2 VALUES (7); +UNLOCK TABLES; +SET AUTOCOMMIT= 0; +LOCK TABLE t1 WRITE; +INSERT DELAYED INTO t2 VALUES (8); +UNLOCK TABLES; +SET AUTOCOMMIT= 1; + --echo # Connection con2 connection con2; disconnect con2; diff --git a/mysql-test/t/events_2.test b/mysql-test/t/events_2.test index 08412d2f5b0..3d609654b21 100644 --- a/mysql-test/t/events_2.test +++ b/mysql-test/t/events_2.test @@ -212,15 +212,15 @@ lock table t1 read; --replace_regex /STARTS '[^']+'/STARTS '#'/ show create event e1; select event_name from information_schema.events; ---error ER_TABLE_NOT_LOCKED +--error ER_LOCK_OR_ACTIVE_TRANSACTION create event e2 on schedule every 10 hour do select 1; ---error ER_TABLE_NOT_LOCKED +--error ER_LOCK_OR_ACTIVE_TRANSACTION alter event e2 disable; ---error ER_TABLE_NOT_LOCKED +--error ER_LOCK_OR_ACTIVE_TRANSACTION alter event e2 rename to e3; ---error ER_TABLE_NOT_LOCKED +--error ER_LOCK_OR_ACTIVE_TRANSACTION drop event e2; ---error ER_TABLE_NOT_LOCKED +--error ER_LOCK_OR_ACTIVE_TRANSACTION drop event e1; unlock tables; # @@ -229,15 +229,15 @@ lock table t1 write; --replace_regex /STARTS '[^']+'/STARTS '#'/ show create event e1; select event_name from information_schema.events; ---error ER_TABLE_NOT_LOCKED +--error ER_LOCK_OR_ACTIVE_TRANSACTION create event e2 on schedule every 10 hour do select 1; ---error ER_TABLE_NOT_LOCKED +--error ER_LOCK_OR_ACTIVE_TRANSACTION alter event e2 disable; ---error ER_TABLE_NOT_LOCKED +--error ER_LOCK_OR_ACTIVE_TRANSACTION alter event e2 rename to e3; ---error ER_TABLE_NOT_LOCKED +--error ER_LOCK_OR_ACTIVE_TRANSACTION drop event e2; ---error ER_TABLE_NOT_LOCKED +--error ER_LOCK_OR_ACTIVE_TRANSACTION drop event e1; unlock tables; # @@ -246,15 +246,15 @@ lock table t1 read, mysql.event read; --replace_regex /STARTS '[^']+'/STARTS '#'/ show create event e1; select event_name from information_schema.events; ---error ER_TABLE_NOT_LOCKED_FOR_WRITE +--error ER_LOCK_OR_ACTIVE_TRANSACTION create event e2 on schedule every 10 hour do select 1; ---error ER_TABLE_NOT_LOCKED_FOR_WRITE +--error ER_LOCK_OR_ACTIVE_TRANSACTION alter event e2 disable; ---error ER_TABLE_NOT_LOCKED_FOR_WRITE +--error ER_LOCK_OR_ACTIVE_TRANSACTION alter event e2 rename to e3; ---error ER_TABLE_NOT_LOCKED_FOR_WRITE +--error ER_LOCK_OR_ACTIVE_TRANSACTION drop event e2; ---error ER_TABLE_NOT_LOCKED_FOR_WRITE +--error ER_LOCK_OR_ACTIVE_TRANSACTION drop event e1; unlock tables; # @@ -263,15 +263,15 @@ lock table t1 write, mysql.event read; --replace_regex /STARTS '[^']+'/STARTS '#'/ show create event e1; select event_name from information_schema.events; ---error ER_TABLE_NOT_LOCKED_FOR_WRITE +--error ER_LOCK_OR_ACTIVE_TRANSACTION create event e2 on schedule every 10 hour do select 1; ---error ER_TABLE_NOT_LOCKED_FOR_WRITE +--error ER_LOCK_OR_ACTIVE_TRANSACTION alter event e2 disable; ---error ER_TABLE_NOT_LOCKED_FOR_WRITE +--error ER_LOCK_OR_ACTIVE_TRANSACTION alter event e2 rename to e3; ---error ER_TABLE_NOT_LOCKED_FOR_WRITE +--error ER_LOCK_OR_ACTIVE_TRANSACTION drop event e2; ---error ER_TABLE_NOT_LOCKED_FOR_WRITE +--error ER_LOCK_OR_ACTIVE_TRANSACTION drop event e1; unlock tables; # @@ -285,12 +285,18 @@ lock table mysql.event write; --replace_regex /STARTS '[^']+'/STARTS '#'/ show create event e1; select event_name from information_schema.events; +--error ER_LOCK_OR_ACTIVE_TRANSACTION create event e2 on schedule every 10 hour do select 1; +--error ER_LOCK_OR_ACTIVE_TRANSACTION alter event e2 disable; +--error ER_LOCK_OR_ACTIVE_TRANSACTION alter event e2 rename to e3; +--error ER_LOCK_OR_ACTIVE_TRANSACTION drop event e3; +--error ER_LOCK_OR_ACTIVE_TRANSACTION drop event e1; unlock tables; +drop event e1; --echo Make sure we have left no events select event_name from information_schema.events; --echo diff --git a/mysql-test/t/flush.test b/mysql-test/t/flush.test index 1cafbe3e6bd..944c9c43019 100644 --- a/mysql-test/t/flush.test +++ b/mysql-test/t/flush.test @@ -577,3 +577,70 @@ select * from t1; select * from t2; unlock tables; drop tables tm, t1, t2; + + +--echo # +--echo # Test for bug #57006 "Deadlock between HANDLER and +--echo # FLUSH TABLES WITH READ LOCK". +--echo # +--disable_warnings +drop table if exists t1, t2; +--enable_warnings +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); +connection default; +create table t1 (i int); +create table t2 (i int); +handler t1 open; + +--echo # Switching to connection 'con1'. +connection con1; +--echo # Sending: +--send flush tables with read lock + +--echo # Switching to connection 'con2'. +connection con2; +--echo # Wait until FTWRL starts waiting for 't1' to be closed. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for table flush" + and info = "flush tables with read lock"; +--source include/wait_condition.inc + +--echo # Switching to connection 'default'. +connection default; +--echo # The below statement should not cause deadlock. +--echo # Sending: +--send insert into t2 values (1) + +--echo # Switching to connection 'con2'. +connection con2; +--echo # Wait until INSERT starts to wait for FTWRL to go away. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for global read lock" + and info = "insert into t2 values (1)"; +--source include/wait_condition.inc + +--echo # Switching to connection 'con1'. +connection con1; +--echo # FTWRL should be able to continue now. +--echo # Reap FTWRL. +--reap +unlock tables; + +--echo # Switching to connection 'default'. +connection default; +--echo # Reap INSERT. +--reap +handler t1 close; + +--echo # Cleanup. +connection con1; +disconnect con1; +--source include/wait_until_disconnected.inc +connection con2; +disconnect con2; +--source include/wait_until_disconnected.inc +connection default; +drop tables t1, t2; diff --git a/mysql-test/t/flush_block_commit.test b/mysql-test/t/flush_block_commit.test index 0b3bede1684..90443dc9242 100644 --- a/mysql-test/t/flush_block_commit.test +++ b/mysql-test/t/flush_block_commit.test @@ -39,7 +39,7 @@ connection con2; --echo # Wait until COMMIT gets blocked. let $wait_condition= select count(*) = 1 from information_schema.processlist - where state = "Waiting for release of readlock" and info = "COMMIT"; + where state = "Waiting for commit lock" and info = "COMMIT"; --source include/wait_condition.inc --echo # Verify that 'con1' was blocked and data did not move. SELECT * FROM t1; diff --git a/mysql-test/t/flush_block_commit_notembedded.test b/mysql-test/t/flush_block_commit_notembedded.test index 7e3f4838ffb..fe9dbf7c19e 100644 --- a/mysql-test/t/flush_block_commit_notembedded.test +++ b/mysql-test/t/flush_block_commit_notembedded.test @@ -53,7 +53,7 @@ begin; connection con1; let $wait_condition= select count(*) = 1 from information_schema.processlist - where state = "Waiting for release of readlock" and + where state = "Waiting for global read lock" and info = "insert into t1 values (1)"; --source include/wait_condition.inc unlock tables; diff --git a/mysql-test/t/flush_read_lock.test b/mysql-test/t/flush_read_lock.test new file mode 100644 index 00000000000..b234d941e6e --- /dev/null +++ b/mysql-test/t/flush_read_lock.test @@ -0,0 +1,2187 @@ +# +# Test coverage for various aspects of FLUSH TABLES WITH READ LOCK +# functionality. +# + +# We need InnoDB for COMMIT/ROLLBACK related tests. +--source include/have_innodb.inc +# We need the Debug Sync Facility. +--source include/have_debug_sync.inc +# Save the initial number of concurrent sessions. +--source include/count_sessions.inc + +--echo # FTWRL takes two global metadata locks -- a global shared +--echo # metadata lock and the commit blocker lock. +--echo # The first lock prevents DDL from taking place. +--echo # Let's say that all DDL statements that take metadata +--echo # locks form class #1 -- incompatible with FTWRL because +--echo # take incompatible MDL table locks. +--echo # The first global lock doesn't, however, prevent standalone +--echo # COMMITs (or implicit COMMITs) from taking place, since a +--echo # COMMIT doesn't take table locks. It doesn't prevent +--echo # DDL on temporary tables either, since they don't +--echo # take any table locks either. +--echo # Most DDL statements do not perform an implicit commit +--echo # if operate on a temporary table. Examples are CREATE +--echo # TEMPORARY TABLE and DROP TEMPORARY TABLE. +--echo # Thus, these DDL statements can go through in presence +--echo # of FTWRL. This is class #2 -- compatible because +--echo # do not take incompatible MDL locks and do not issue +--echo # implicit commit.. +--echo # (Although these operations do not commit, their effects +--echo # cannot be rolled back either.) +--echo # ALTER TABLE, ANALYZE, OPTIMIZE and some others always +--echo # issue an implicit commit, even if its argument is a +--echo # temporary table. +--echo # *Howewer* an implicit commit is a no-op if all engines +--echo # used since the start of transactiona are non- +--echo # transactional. Thus, for non-transactional engines, +--echo # these operations are not blocked by FTWRL. +--echo # This is class #3 -- compatible because do not take +--echo # MDL table locks and are non-transactional. +--echo # On the contrary, for transactional engines, there +--echo # is always a commit, regardless of whether a table +--echo # is temporary or not. Thus, for example, ALTER TABLE +--echo # for a transactional engine will wait for FTWRL, +--echo # even if the subject table is temporary. +--echo # Thus ALTER TABLE is incompatible +--echo # with FTWRL. This is class #4 -- incompatible +--echo # becuase issue implicit COMMIT which is not a no-op. +--echo # Finally, there are administrative statements (such as +--echo # RESET SLAVE) that do not take any locks and do not +--echo # issue COMMIT. +--echo # This is class #5. +--echo # The goal of this coverage is to test statements +--echo # of all classes. +--echo # @todo: documents the effects of @@autocommit, +--echo # DML and temporary transactional tables. + +--echo # Use MyISAM engine for the most of the tables +--echo # used in this test in order to be able to +--echo # check that DDL statements on temporary tables +--echo # are compatible with FTRWL. +--disable_warnings +drop tables if exists t1_base, t2_base, t3_trans; +drop tables if exists tm_base, tm_base_temp; +drop database if exists mysqltest1; +--echo # We're going to test ALTER DATABASE UPGRADE +drop database if exists `#mysql50#mysqltest-2`; +drop procedure if exists p1; +drop function if exists f1; +drop view if exists v1; +drop procedure if exists p2; +drop function if exists f2_base; +drop function if exists f2_temp; +drop event if exists e1; +drop event if exists e2; +--enable_warnings +create table t1_base(i int) engine=myisam; +create table t2_base(j int) engine=myisam; +create table t3_trans(i int) engine=innodb; +create temporary table t1_temp(i int) engine=myisam; +create temporary table t2_temp(j int) engine=myisam; +create temporary table t3_temp_trans(i int) engine=innodb; +create database mysqltest1; +create database `#mysql50#mysqltest-2`; +create procedure p1() begin end; +create function f1() returns int return 0; +create view v1 as select 1 as i; +create procedure p2(i int) begin end; +delimiter |; +create function f2_base() returns int +begin + insert into t1_base values (1); + return 0; +end| +create function f2_temp() returns int +begin + insert into t1_temp values (1); + return 0; +end| +delimiter ;| +create event e1 on schedule every 1 minute do begin end; + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); +connect (con3,localhost,root,,); +connection default; + +--echo # +--echo # Test compatibility of FLUSH TABLES WITH READ LOCK +--echo # with various statements. +--echo # +--echo # These tests don't cover some classes of statements: +--echo # - Replication-related - CHANGE MASTER TO, START/STOP SLAVE and etc +--echo # (all compatible with FTWRL). +--echo # - Plugin-related - INSTALL/UNINSTALL (incompatible with FTWRL, +--echo # require plugin support). + +let $con_aux1=con1; +let $con_aux2=con2; +let $cleanup_stmt2= ; +let $skip_3rd_check= ; + +--echo # +--echo # 1) ALTER variants. +--echo # +--echo # 1.1) ALTER TABLE +--echo # +--echo # 1.1.a) For base table should be incompatible with FTWRL. +--echo # +let $statement= alter table t1_base add column c1 int; +let $cleanup_stmt1= alter table t1_base drop column c1; +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 1.1.b) For a temporary table should be compatible with FTWRL. +--echo # +let $statement= alter table t1_temp add column c1 int; +let $cleanup_stmt= alter table t1_temp drop column c1; +--source include/check_ftwrl_compatible.inc + +--echo # +--echo # 1.2) ALTER DATABASE should be incompatible with FTWRL. +--echo # +let $statement= alter database mysqltest1 default character set utf8; +let $cleanup_stmt1= alter database mysqltest1 default character set latin1; +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 1.3) ALTER DATABASE UPGRADE DATA DIRECTORY NAME should be +--echo # incompatible with FTWRL. +--echo # +let $statement= alter database `#mysql50#mysqltest-2` upgrade data directory name; +let $cleanup_stmt1= drop database `mysqltest-2`; +let $cleanup_stmt2= create database `#mysql50#mysqltest-2`; +--source include/check_ftwrl_incompatible.inc +let $cleanup_stmt2= ; + +--echo # +--echo # 1.4) ALTER PROCEDURE should be incompatible with FTWRL. +--echo # +let $statement= alter procedure p1 comment 'a'; +let $cleanup_stmt1= alter procedure p1 comment ''; +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 1.5) ALTER FUNCTION should be incompatible with FTWRL. +--echo # +let $statement= alter function f1 comment 'a'; +let $cleanup_stmt1= alter function f1 comment ''; +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 1.6) ALTER VIEW should be incompatible with FTWRL. +--echo # +let $statement= alter view v1 as select 2 as j; +let $cleanup_stmt1= alter view v1 as select 1 as i; +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 1.7) ALTER EVENT should be incompatible with FTWRL. +--echo # +let $statement= alter event e1 comment 'test'; +let $cleanup_stmt1= alter event e1 comment ''; +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 1.x) The rest of ALTER statements (ALTER TABLESPACE, +--echo # ALTER LOGFILE GROUP and ALTER SERVER) are too +--echo # special to be tested here. +--echo # + + +--echo # +--echo # 2) ANALYZE TABLE statement is compatible with FTWRL. +--echo # See Bug#43336 ANALYZE and OPTIMIZE do not honour +--echo # --read-only for a discussion why. +--echo # +let $statement= analyze table t1_base; +let $cleanup_stmt= ; +--source include/check_ftwrl_compatible.inc + +--echo # +--echo # 3) BEGIN, ROLLBACK and COMMIT statements. +--echo # BEGIN and ROLLBACK are compatible with FTWRL. +--echo # COMMIT is not. +--echo # +--echo # We need a special test for these statements as +--echo # FTWRL commits a transaction and because COMMIT +--echo # is handled in a special way. +flush tables with read lock; +begin; +--echo # ROLLBACK is allowed under FTWRL although there +--echo # no much sense in it. FTWRL commits any previous +--echo # changes and doesn't allows any DML after it. +--echo # So such a ROLLBACK is always a no-op. +rollback; +--echo # Although COMMIT is incompatible with FTWRL in +--echo # other senses it is still allowed under FTWRL. +--echo # This fact relied upon by some versions of +--echo # innobackup tool. +--echo # Similarly to ROLLBACK it is a no-op in this situation. +commit; +unlock tables; +--echo # Check that BEGIN/ROLLBACK are not blocked and +--echo # COMMIT is blocked by active FTWRL in another +--echo # connection. +--echo # +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +flush tables with read lock; +--echo # Switching to connection 'default'. +connection default; +begin; +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +unlock tables; +--echo # Switching to connection 'default'. +connection default; +--echo # Do some work so ROLLBACK is not a no-op. +insert into t3_trans values (1); +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +flush tables with read lock; +--echo # Switching to connection 'default'. +connection default; +rollback; +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +unlock tables; +--echo # Switching to connection 'default'. +connection default; +begin; +--echo # Do some work so COMMIT is not a no-op. +insert into t3_trans values (1); +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +flush tables with read lock; +--echo # Switching to connection 'default'. +connection default; +--echo # Send: +--send commit +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +--echo # Wait until COMMIT is blocked. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for commit lock" and + info = "commit"; +--source include/wait_condition.inc +unlock tables; +--echo # Switching to connection 'default'. +connection default; +--echo # Reap COMMIT. +--reap +delete from t3_trans; +--echo # +--echo # Check that COMMIT blocks FTWRL in another connection. +begin; +insert into t3_trans values (1); +set debug_sync='RESET'; +set debug_sync='ha_commit_trans_after_acquire_commit_lock SIGNAL parked WAIT_FOR go'; +--send commit +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +set debug_sync='now WAIT_FOR parked'; +--send flush tables with read lock +--echo # Switching to connection '$con_aux2'. +connection $con_aux2; +--echo # Wait until FTWRL is blocked. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for commit lock" and + info = "flush tables with read lock"; +--source include/wait_condition.inc +set debug_sync='now SIGNAL go'; +--echo # Switching to connection 'default'. +connection default; +--echo # Reap COMMIT. +--reap +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +--echo # Reap FTWRL. +--reap +unlock tables; +--echo # Switching to connection 'default'. +connection default; +delete from t3_trans; +set debug_sync= "RESET"; +--echo # We don't run similar test for BEGIN and ROLLBACK as +--echo # they release metadata locks in non-standard place. + + +--echo # +--echo # 4) BINLOG statement should be incompatible with FTWRL. +--echo # +--echo # +--echo # Provide format description BINLOG statement first. +BINLOG ' +MfmqTA8BAAAAZwAAAGsAAAABAAQANS41LjctbTMtZGVidWctbG9nAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAx+apMEzgNAAgAEgAEBAQEEgAAVAAEGggAAAAICAgCAA== +'; +--echo # Now test compatibility for BINLOG statement which is +--echo # equivalent to INSERT INTO t1_base VALUES (1). +let $statement= BINLOG ' +MfmqTBMBAAAALgAAAN0AAAAAACgAAAAAAAEABHRlc3QAB3QxX2Jhc2UAAQMAAQ== +MfmqTBcBAAAAIgAAAP8AAAAAACgAAAAAAAEAAf/+AQAAAA== +'; +let $cleanup_stmt1= delete from t1_base where i = 1 limit 1; +--echo # Skip last part of compatibility testing as this statement +--echo # releases metadata locks in non-standard place. +let $skip_3rd_check= 1; +--source include/check_ftwrl_incompatible.inc +let $skip_3rd_check= ; + + +--echo # +--echo # 5) CALL statement. This statement uses resources in two +--echo # ways: through expressions used as parameters and through +--echo # sub-statements. This test covers only usage through +--echo # parameters as sub-statements do locking individually. +--echo # +--echo # 5.a) In simple cases a parameter expression should be +--echo # compatible with FTWRL. +let $statement= call p2((select count(*) from t1_base)); +let $cleanup_stmt1= ; +--echo # Skip last part of compatibility testing as this statement +--echo # releases metadata locks in non-standard place. +let $skip_3rd_check= 1; +--source include/check_ftwrl_compatible.inc +let $skip_3rd_check= ; + +--echo # +--echo # 5.b) In case when an expression uses function which updates +--echo # base tables CALL should be incompatible with FTWRL. +--echo # +let $statement= call p2(f2_base()); +let $cleanup_stmt1= ; +--echo # Skip last part of compatibility testing as this statement +--echo # releases metadata locks in non-standard place. +let $skip_3rd_check= 1; +--source include/check_ftwrl_incompatible.inc +let $skip_3rd_check= ; + +--echo # +--echo # 5.c) If function used as argument updates temporary tables +--echo # CALL statement should be compatible with FTWRL. +--echo # +let $statement= call p2(f2_temp()); +let $cleanup_stmt1= ; +--echo # Skip last part of compatibility testing as this statement +--echo # releases metadata locks in non-standard place. +let $skip_3rd_check= 1; +--source include/check_ftwrl_compatible.inc +let $skip_3rd_check= ; + + +--echo # +--echo # 6) CHECK TABLE statement is compatible with FTWRL. +--echo # +let $statement= check table t1_base; +let $cleanup_stmt= ; +--source include/check_ftwrl_compatible.inc + + +--echo # +--echo # 7) CHECKSUM TABLE statement is compatible with FTWRL. +--echo # +let $statement= checksum table t1_base; +let $cleanup_stmt= ; +--source include/check_ftwrl_compatible.inc + + +--echo # +--echo # 8) CREATE variants. +--echo # +--echo # 8.1) CREATE TABLE statement. +--echo # +--echo # 8.1.a) CREATE TABLE is incompatible with FTWRL when +--echo # base table is created. +let $statement= create table t3_base(i int); +let $cleanup_stmt1= drop table t3_base; +--source include/check_ftwrl_incompatible.inc + +--echo # 8.1.b) CREATE TABLE is compatible with FTWRL when +--echo # temporary table is created. +let $statement= create temporary table t3_temp(i int); +let $cleanup_stmt= drop temporary tables t3_temp; +--source include/check_ftwrl_compatible.inc + +--echo # 8.1.c) CREATE TABLE LIKE is incompatible with FTWRL when +--echo # base table is created. +let $statement= create table t3_base like t1_temp; +let $cleanup_stmt1= drop table t3_base; +--source include/check_ftwrl_incompatible.inc + +--echo # 8.1.d) CREATE TABLE LIKE is compatible with FTWRL when +--echo # temporary table is created. +let $statement= create temporary table t3_temp like t1_base; +let $cleanup_stmt= drop temporary table t3_temp; +--source include/check_ftwrl_compatible.inc + +--echo # 8.1.e) CREATE TABLE SELECT is incompatible with FTWRL when +--echo # base table is created. +let $statement= create table t3_base select 1 as i; +let $cleanup_stmt1= drop table t3_base; +--source include/check_ftwrl_incompatible.inc + +--echo # 8.1.f) CREATE TABLE SELECT is compatible with FTWRL when +--echo # temporary table is created. +let $statement= create temporary table t3_temp select 1 as i; +let $cleanup_stmt= drop temporary table t3_temp; +--source include/check_ftwrl_compatible.inc + +--echo # 8.2) CREATE INDEX statement. +--echo # +--echo # 8.2.a) CREATE INDEX is incompatible with FTWRL when +--echo # applied to base table. +let $statement= create index i on t1_base (i); +let $cleanup_stmt1= drop index i on t1_base; +--source include/check_ftwrl_incompatible.inc + +--echo # 8.2.b) CREATE INDEX is compatible with FTWRL when +--echo # applied to temporary table. +let $statement= create index i on t1_temp (i); +let $cleanup_stmt= drop index i on t1_temp; +--source include/check_ftwrl_compatible.inc + +--echo # +--echo # 8.3) CREATE DATABASE is incompatible with FTWRL. +--echo # +let $statement= create database mysqltest2; +let $cleanup_stmt1= drop database mysqltest2; +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 8.4) CREATE VIEW is incompatible with FTWRL. +--echo # +let $statement= create view v2 as select 1 as j; +let $cleanup_stmt1= drop view v2; +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 8.5) CREATE TRIGGER is incompatible with FTWRL. +--echo # +let $statement= create trigger t1_bi before insert on t1_base for each row begin end; +let $cleanup_stmt1= drop trigger t1_bi; +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 8.6) CREATE FUNCTION is incompatible with FTWRL. +--echo # +let $statement= create function f2() returns int return 0; +let $cleanup_stmt1= drop function f2; +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 8.7) CREATE PROCEDURE is incompatible with FTWRL. +--echo # +let $statement= create procedure p3() begin end; +let $cleanup_stmt1= drop procedure p3; +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 8.8) CREATE EVENT should be incompatible with FTWRL. +--echo # +let $statement= create event e2 on schedule every 1 minute do begin end; +let $cleanup_stmt1= drop event e2; +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 8.9) CREATE USER should be incompatible with FTWRL. +--echo # +let $statement= create user mysqltest_u1; +let $cleanup_stmt1= drop user mysqltest_u1; +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 8.x) The rest of CREATE variants (CREATE LOGFILE GROUP, +--echo # CREATE TABLESPACE and CREATE SERVER) are too special +--echo # to test here. +--echo # + + +--echo # +--echo # 9) PREPARE, EXECUTE and DEALLOCATE PREPARE statements. +--echo # +--echo # 9.1) PREPARE statement is compatible with FTWRL as it +--echo # doesn't change any data. +--echo # +--echo # 9.1.a) Prepare of simple INSERT statement. +--echo # +let $statement= prepare stmt1 from 'insert into t1_base values (1)'; +let $cleanup_stmt= deallocate prepare stmt1; +--echo # Skip last part of compatibility testing as this statement +--echo # releases metadata locks in non-standard place. +let $skip_3rd_check= 1; +--source include/check_ftwrl_compatible.inc +let $skip_3rd_check= ; + +--echo # +--echo # 9.1.b) Prepare of multi-UPDATE. At some point such statements +--echo # tried to acquire thr_lock.c locks during prepare phase. +--echo # This no longer happens and thus it is compatible with +--echo # FTWRL. +let $statement= prepare stmt1 from 'update t1_base, t2_base set t1_base.i= 1 where t1_base.i = t2_base.j'; +let $cleanup_stmt= deallocate prepare stmt1; +--echo # Skip last part of compatibility testing as this statement +--echo # releases metadata locks in non-standard place. +let $skip_3rd_check= 1; +--source include/check_ftwrl_compatible.inc +let $skip_3rd_check= ; + +--echo # +--echo # 9.1.c) Prepare of multi-DELETE. Again PREPARE of such +--echo # statement should be compatible with FTWRL. +let $statement= prepare stmt1 from 'delete t1_base from t1_base, t2_base where t1_base.i = t2_base.j'; +let $cleanup_stmt= deallocate prepare stmt1; +--echo # Skip last part of compatibility testing as this statement +--echo # releases metadata locks in non-standard place. +let $skip_3rd_check= 1; +--source include/check_ftwrl_compatible.inc +let $skip_3rd_check= ; + +--echo # +--echo # 9.2) Compatibility of EXECUTE statement depends on statement +--echo # to be executed. +--echo # +--echo # 9.2.a) EXECUTE for statement which is itself compatible with +--echo # FTWRL should be compatible. +prepare stmt1 from 'select * from t1_base'; +let $statement= execute stmt1; +let $cleanup_stmt= ; +--source include/check_ftwrl_compatible.inc +deallocate prepare stmt1; + +--echo # +--echo # 9.2.b) EXECUTE for statement which is incompatible with FTWRL +--echo # should be also incompatible. +--echo # +--echo # Check that EXECUTE is not allowed under FTWRL. +prepare stmt1 from 'insert into t1_base values (1)'; +flush tables with read lock; +--error ER_CANT_UPDATE_WITH_READLOCK +execute stmt1; +unlock tables; +--echo # Check that active FTWRL in another connection +--echo # blocks EXECUTE which changes data. +--echo # +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +flush tables with read lock; +--echo # Switching to connection 'default'. +connection default; +--send execute stmt1 +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +--echo # Check that EXECUTE is blocked. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for global read lock" and + info = "insert into t1_base values (1)"; +--source include/wait_condition.inc +unlock tables; +--echo # Switching to connection 'default'. +connection default; +--echo # Reap EXECUTE. +--reap +set debug_sync='RESET'; +set debug_sync='execute_command_after_close_tables SIGNAL parked WAIT_FOR go'; +--send execute stmt1; +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +set debug_sync='now WAIT_FOR parked'; +--send flush tables with read lock +--echo # Switching to connection '$con_aux2'. +connection $con_aux2; +--echo # Wait until FTWRL is blocked. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for global read lock" and + info = "flush tables with read lock"; +--source include/wait_condition.inc +set debug_sync='now SIGNAL go'; +--echo # Switching to connection 'default'. +connection default; +--echo # Reap EXECUTE. +--reap +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +--echo # Reap FTWRL. +--reap +unlock tables; +--echo # Switching to connection 'default'. +connection default; +set debug_sync= "RESET"; +delete from t1_base; +deallocate prepare stmt1; + +--echo # +--echo # 9.3) DEALLOCATE PREPARE is compatible with FTWRL. +--echo # +prepare stmt1 from 'insert into t1_base values (1)'; +let $statement= deallocate prepare stmt1; +let $cleanup_stmt= prepare stmt1 from 'insert into t1_base values (1)'; +--source include/check_ftwrl_compatible.inc +deallocate prepare stmt1; + + +--echo # +--echo # 10) DELETE variations. +--echo # +--echo # 10.1) Simple DELETE. +--echo # +--echo # 10.1.a) Simple DELETE on base table is incompatible with FTWRL. +let $statement= delete from t1_base; +let $cleanup_stmt1= ; +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 10.1.b) Simple DELETE on temporary table is compatible with FTWRL. +let $statement= delete from t1_temp; +let $cleanup_stmt= ; +--source include/check_ftwrl_compatible.inc + +--echo # +--echo # 10.2) Multi DELETE. +--echo # +--echo # 10.2.a) Multi DELETE on base tables is incompatible with FTWRL. +let $statement= delete t1_base from t1_base, t2_base where t1_base.i = t2_base.j; +let $cleanup_stmt1= ; +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 10.2.b) Multi DELETE on temporary tables is compatible with FTWRL. +let $statement= delete t1_temp from t1_temp, t2_temp where t1_temp.i = t2_temp.j; +let $cleanup_stmt= ; +--source include/check_ftwrl_compatible.inc + + +--echo # +--echo # 11) DESCRIBE should be compatible with FTWRL. +--echo # +let $statement= describe t1_base; +let $cleanup_stmt= ; +--source include/check_ftwrl_compatible.inc + + +--echo # +--echo # 12) Compatibility of DO statement with FTWRL depends on its +--echo # expression. +--echo # +--echo # 12.a) DO with expression which does not change base table +--echo # should be compatible with FTWRL. +let $statement= do (select count(*) from t1_base); +let $cleanup_stmt= ; +--source include/check_ftwrl_compatible.inc + +--echo # +--echo # 12.b) DO which calls SF updating base table should be +--echo # incompatible with FTWRL. +let $statement= do f2_base(); +let $cleanup_stmt1= delete from t1_base limit 1; +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 12.c) DO which calls SF updating temporary table should be +--echo # compatible with FTWRL. +let $statement= do f2_temp(); +let $cleanup_stmt= delete from t1_temp limit 1; +--source include/check_ftwrl_compatible.inc + + +--echo # +--echo # 13) DROP variants. +--echo # +--echo # 13.1) DROP TABLES. +--echo # +--echo # 13.1.a) DROP TABLES which affects base tables is incompatible +--echo # with FTWRL. +let $statement= drop table t2_base; +let $cleanup_stmt1= create table t2_base(j int); +--source include/check_ftwrl_incompatible.inc + +--echo # 13.1.b) DROP TABLES which affects only temporary tables +--echo # in theory can be compatible with FTWRL. +--echo # In practice it is not yet. +let $statement= drop table t2_temp; +let $cleanup_stmt1= create temporary table t2_temp(j int); +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 13.1.c) DROP TEMPORARY TABLES should be compatible with FTWRL. +let $statement= drop temporary table t2_temp; +let $cleanup_stmt= create temporary table t2_temp(j int); +--source include/check_ftwrl_compatible.inc + +--echo # +--echo # 13.2) DROP INDEX. +--echo # +--echo # 13.2.a) DROP INDEX on a base table is incompatible with FTWRL. +create index i on t1_base (i); +let $statement= drop index i on t1_base; +let $cleanup_stmt1= create index i on t1_base (i); +--source include/check_ftwrl_incompatible.inc +drop index i on t1_base; + +--echo # +--echo # 13.2.b) DROP INDEX on a temporary table is compatible with FTWRL. +create index i on t1_temp (i); +let $statement= drop index i on t1_temp; +let $cleanup_stmt= create index i on t1_temp (i); +--source include/check_ftwrl_compatible.inc +drop index i on t1_temp; + +--echo # +--echo # 13.3) DROP DATABASE is incompatible with FTWRL +--echo # +let $statement= drop database mysqltest1; +let $cleanup_stmt1= create database mysqltest1; +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 13.4) DROP FUNCTION is incompatible with FTWRL. +--echo # +let $statement= drop function f1; +let $cleanup_stmt1= create function f1() returns int return 0; +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 13.5) DROP PROCEDURE is incompatible with FTWRL. +--echo # +let $statement= drop procedure p1; +let $cleanup_stmt1= create procedure p1() begin end; +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 13.6) DROP USER should be incompatible with FTWRL. +--echo # +create user mysqltest_u1; +let $statement= drop user mysqltest_u1; +let $cleanup_stmt1= create user mysqltest_u1; +--source include/check_ftwrl_incompatible.inc +drop user mysqltest_u1; + +--echo # +--echo # 13.7) DROP VIEW should be incompatible with FTWRL. +--echo # +let $statement= drop view v1; +let $cleanup_stmt1= create view v1 as select 1 as i; +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 13.8) DROP EVENT should be incompatible with FTWRL. +--echo # +let $statement= drop event e1; +let $cleanup_stmt1= create event e1 on schedule every 1 minute do begin end; +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 13.9) DROP TRIGGER is incompatible with FTWRL. +--echo # +create trigger t1_bi before insert on t1_base for each row begin end; +let $statement= drop trigger t1_bi; +let $cleanup_stmt1= create trigger t1_bi before insert on t1_base for each row begin end; +--source include/check_ftwrl_incompatible.inc +drop trigger t1_bi; + +--echo # +--echo # 13.x) The rest of DROP variants (DROP TABLESPACE, DROP LOGFILE +--echo # GROUP and DROP SERVER) are too special to test here. +--echo # + + +--echo # +--echo # 14) FLUSH variants. +--echo # +--echo # Test compatibility of _some_ important FLUSH variants with FTWRL. +--echo # +--echo # 14.1) FLUSH TABLES WITH READ LOCK is compatible with itself. +--echo # +--echo # Check that FTWRL statements can be run while FTWRL +--echo # is active in another connection. +--echo # +--echo # Switching to connection '$con_aux1'. +flush tables with read lock; +--echo # The second FTWRL in a row is allowed at the moment. +--echo # It does not make much sense as it does only flush. +flush tables with read lock; +unlock tables; +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +flush tables with read lock; +--echo # Switching to connection 'default'. +connection default; +flush tables with read lock; +unlock tables; +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +unlock tables; +--echo # Switching to connection 'default'. +connection default; + +--echo # +--echo # 14.2) FLUSH TABLES WITH READ LOCK is not blocked by +--echo # active FTWRL. But since the latter keeps tables open +--echo # FTWRL is blocked by FLUSH TABLES WITH READ LOCK. +flush tables with read lock; +--echo # FT WRL is allowed under FTWRL at the moment. +--echo # It does not make much sense though. +flush tables t1_base, t2_base with read lock; +unlock tables; +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +flush tables with read lock; +--echo # Switching to connection 'default'. +connection default; +flush tables t1_base, t2_base with read lock; +unlock tables; +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +unlock tables; +--echo # Switching to connection 'default'. +connection default; +flush tables t1_base, t2_base with read lock; +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +--send flush tables with read lock +--echo # Switching to connection '$con_aux2'. +connection $con_aux2; +--echo # Wait until FTWRL is blocked. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for table flush" and + info = "flush tables with read lock"; +--source include/wait_condition.inc +--echo # Switching to connection 'default'. +connection default; +unlock tables; +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +--echo # Reap FTWRL. +--reap +unlock tables; +--echo # Switching to connection 'default'. +connection default; + + +--echo # +--echo # 14.3) FLUSH TABLES is compatible with FTWRL. +let $statement= flush tables; +let $cleanup_stmt= ; +--source include/check_ftwrl_compatible.inc + +--echo # +--echo # 14.4) FLUSH TABLES is compatible with FTWRL. +let $statement= flush table t1_base, t2_base; +let $cleanup_stmt= ; +--source include/check_ftwrl_compatible.inc + +--echo # +--echo # 14.5) FLUSH PRIVILEGES is compatible with FTWRL. +let $statement= flush privileges; +let $cleanup_stmt= ; +--source include/check_ftwrl_compatible.inc + + +--echo # +--echo # 15) GRANT statement should be incompatible with FTWRL. +--echo # +let $statement= grant all privileges on t1_base to mysqltest_u1; +let $cleanup_stmt1= revoke all privileges on t1_base from mysqltest_u1; +--source include/check_ftwrl_incompatible.inc +drop user mysqltest_u1; + + +--echo # +--echo # 16) All HANDLER variants are half-compatible with FTWRL. +--echo # I.e. they are not blocked by active FTWRL. But since open +--echo # HANDLER means open table instance FTWRL is blocked while +--echo # HANDLER is not closed. +--echo # +--echo # Check that HANDLER statements succeed under FTWRL. +flush tables with read lock; +handler t1_base open; +handler t1_base read first; +handler t1_base close; +unlock tables; +--echo # Check that HANDLER statements can be run while FTWRL +--echo # is active in another connection. +--echo # +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +flush tables with read lock; +--echo # Switching to connection 'default'. +connection default; +handler t1_base open; +handler t1_base read first; +handler t1_base close; +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +unlock tables; +--echo # Switching to connection 'default'. +connection default; + + +--echo # +--echo # 17) HELP statement is compatible with FTWRL. +--echo # +let $statement= help no_such_topic; +let $cleanup_stmt= ; +--source include/check_ftwrl_compatible.inc + + +--echo # +--echo # 18) INSERT statement. +--echo # +--echo # 18.a) Ordinary INSERT into base table is incompatible with FTWRL. +let $statement= insert into t1_base values (1); +let $cleanup_stmt1= delete from t1_base limit 1; +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 18.b) Ordinary INSERT into temp table is compatible with FTWRL. +let $statement= insert into t1_temp values (1); +let $cleanup_stmt= delete from t1_temp limit 1; +--source include/check_ftwrl_compatible.inc + +--echo # +--echo # 18.c) INSERT DELAYED is incompatible with FTWRL. +let $statement= insert delayed into t1_base values (1); +let $cleanup_stmt1= ; +--source include/check_ftwrl_incompatible.inc +delete from t1_base; + +--echo # +--echo # 18.d) INSERT SELECT into base table is incompatible with FTWRL. +let $statement= insert into t1_base select * from t1_temp; +let $cleanup_stmt1= ; +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 18.e) INSERT SELECT into temp table is compatible with FTWRL. +let $statement= insert into t1_temp select * from t1_base; +let $cleanup_stmt= ; +--source include/check_ftwrl_compatible.inc + + +--echo # +--echo # 19) KILL statement is compatible with FTWRL. +--echo # +--echo # Check that KILL can be run under FTWRL. +flush tables with read lock; +set @id:= connection_id(); +--error ER_QUERY_INTERRUPTED +kill query @id; +unlock tables; +--echo # Check that KILL statements can be run while FTWRL +--echo # is active in another connection. +--echo # +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +flush tables with read lock; +--echo # Switching to connection 'default'. +connection default; +--error ER_QUERY_INTERRUPTED +kill query @id; +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +unlock tables; +--echo # Switching to connection 'default'. +connection default; +--echo # Finally check that KILL doesn't block FTWRL +set debug_sync='RESET'; +set debug_sync='execute_command_after_close_tables SIGNAL parked WAIT_FOR go'; +--send kill query @id +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +set debug_sync='now WAIT_FOR parked'; +flush tables with read lock; +unlock tables; +set debug_sync='now SIGNAL go'; +--echo # Switching to connection 'default'. +connection default; +--echo # Reap KILL. +--error ER_QUERY_INTERRUPTED +--reap +set debug_sync='RESET'; + + +--echo # +--echo # 20) LOAD DATA statement. +--echo # +--echo # 20.a) LOAD DATA into base table is incompatible with FTWRL. +let $statement= load data infile '../../std_data/rpl_loaddata.dat' into table t1_base (@dummy, i); +let $cleanup_stmt1= delete from t1_base; +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 20.b) LOAD DATA into temporary table is compatible with FTWRL. +let $statement= load data infile '../../std_data/rpl_loaddata.dat' into table t1_temp (@dummy, i); +let $cleanup_stmt= delete from t1_temp; +--source include/check_ftwrl_compatible.inc + + +--echo # +--echo # 21) LOCK/UNLOCK TABLES statements. +--echo # +--echo # LOCK TABLES statement always (almost) blocks FTWRL as it +--echo # keeps tables open until UNLOCK TABLES. +--echo # Active FTWRL on the other hand blocks only those +--echo # LOCK TABLES which allow updating of base tables. +--echo # +--echo # 21.a) LOCK TABLES READ is allowed under FTWRL and +--echo # is not blocked by active FTWRL. +flush tables with read lock; +lock tables t1_base read; +unlock tables; +--echo # +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +flush tables with read lock; +--echo # Switching to connection 'default'. +connection default; +lock tables t1_base read; +unlock tables; +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +unlock tables; +--echo # Switching to connection 'default'. +connection default; + +--echo # +--echo # 21.b) LOCK TABLES WRITE on a base table is disallowed +--echo # under FTWRL and should be blocked by active FTWRL. +flush tables with read lock; +--error ER_CANT_UPDATE_WITH_READLOCK +lock tables t1_base write; +unlock tables; +--echo # +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +flush tables with read lock; +--echo # Switching to connection 'default'. +connection default; +--send lock tables t1_base write +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +--echo # Check that LOCK TABLES WRITE is blocked. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for global read lock" and + info = "lock tables t1_base write"; +--source include/wait_condition.inc +unlock tables; +--echo # Switching to connection 'default'. +connection default; +--echo # Reap LOCK TABLES WRITE +--reap +unlock tables; + +--echo # +--echo # 21.c) LOCK TABLES WRITE on temporary table doesn't +--echo # make much sense but is allowed under FTWRL +--echo # and should not be blocked by active FTWRL. +flush tables with read lock; +lock tables t1_temp write; +unlock tables; +--echo # +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +flush tables with read lock; +--echo # Switching to connection 'default'. +connection default; +lock tables t1_temp write; +unlock tables; +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +unlock tables; +--echo # Switching to connection 'default'. +connection default; + + +--echo # +--echo # 22) OPTIMIZE TABLE statement. +--echo # +--echo # 22.a) OPTIMIZE TABLE of base table is incompatible with FTWRL. +flush tables with read lock; +--echo # OPTIMIZE statement returns errors as part of result-set. +optimize table t1_base; +unlock tables; +--echo # +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +flush tables with read lock; +--echo # Switching to connection 'default'. +connection default; +--send optimize table t1_base +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +--echo # Check that OPTIMIZE TABLE is blocked. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for global read lock" and + info = "optimize table t1_base"; +--source include/wait_condition.inc +unlock tables; +--echo # Switching to connection 'default'. +connection default; +--echo # Reap OPTIMIZE TABLE +--reap +--echo # We don't check that active OPTIMIZE TABLE blocks +--echo # FTWRL as this one of statements releasing metadata +--echo # locks in non-standard place. + +--echo # +--echo # 22.b) OPTIMIZE TABLE of temporary table is compatible with FTWRL. +let $statement= optimize table t1_temp; +let $cleanup_stmt= ; +--echo # Skip last part of compatibility testing as this statement +--echo # releases metadata locks in non-standard place. +let $skip_3rd_check= 1; +--source include/check_ftwrl_compatible.inc +let $skip_3rd_check= ; + + +--echo # +--echo # 23) CACHE statement is compatible with FTWRL. +--echo # +let $statement= cache index t1_base in default; +let $cleanup_stmt= ; +--echo # Skip last part of compatibility testing as this statement +--echo # releases metadata locks in non-standard place. +let $skip_3rd_check= 1; +--source include/check_ftwrl_compatible.inc +let $skip_3rd_check= ; + + +--echo # +--echo # 24) LOAD INDEX statement is compatible with FTWRL. +--echo # +let $statement= load index into cache t1_base; +let $cleanup_stmt= ; +--echo # Skip last part of compatibility testing as this statement +--echo # releases metadata locks in non-standard place. +let $skip_3rd_check= 1; +--source include/check_ftwrl_compatible.inc +let $skip_3rd_check= ; + + +--echo # +--echo # 25) SAVEPOINT/RELEASE SAVEPOINT/ROLLBACK TO SAVEPOINT are +--echo # compatible with FTWRL. +--echo # +--echo # Since manipulations on savepoint have to be done +--echo # inside transaction and FTWRL commits transaction we +--echo # need a special test for these statements. +flush tables with read lock; +begin; +savepoint sv1; +rollback to savepoint sv1; +release savepoint sv1; +unlock tables; +commit; +--echo # Check that these statements are not blocked by +--echo # active FTWRL in another connection. +--echo # +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +flush tables with read lock; +--echo # Switching to connection 'default'. +connection default; +begin; +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +unlock tables; +--echo # Switching to connection 'default'. +connection default; +--echo # Do some changes to avoid SAVEPOINT and friends +--echo # being almost no-ops. +insert into t3_trans values (1); +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +flush tables with read lock; +--echo # Switching to connection 'default'. +connection default; +savepoint sv1; +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +unlock tables; +--echo # Switching to connection 'default'. +connection default; +insert into t3_trans values (2); +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +flush tables with read lock; +--echo # Switching to connection 'default'. +connection default; +rollback to savepoint sv1; +release savepoint sv1; +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +unlock tables; +--echo # Switching to connection 'default'. +connection default; +rollback; +--echo # Check that these statements don't block FTWRL in +--echo # another connection. +begin; +--echo # Do some changes to avoid SAVEPOINT and friends +--echo # being almost no-ops. +insert into t3_trans values (1); +set debug_sync='RESET'; +set debug_sync='execute_command_after_close_tables SIGNAL parked WAIT_FOR go'; +--send savepoint sv1 +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +set debug_sync='now WAIT_FOR parked'; +flush tables with read lock; +unlock tables; +set debug_sync='now SIGNAL go'; +--echo # Switching to connection 'default'. +connection default; +--echo # Reap SAVEPOINT +--reap +insert into t3_trans values (2); +set debug_sync='execute_command_after_close_tables SIGNAL parked WAIT_FOR go'; +--send rollback to savepoint sv1 +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +set debug_sync='now WAIT_FOR parked'; +flush tables with read lock; +unlock tables; +set debug_sync='now SIGNAL go'; +--echo # Switching to connection 'default'. +connection default; +--echo # Reap ROLLBACK TO SAVEPOINT +--reap +set debug_sync='execute_command_after_close_tables SIGNAL parked WAIT_FOR go'; +--send release savepoint sv1 +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +set debug_sync='now WAIT_FOR parked'; +flush tables with read lock; +unlock tables; +set debug_sync='now SIGNAL go'; +--echo # Switching to connection 'default'. +connection default; +--echo # Reap RELEASE SAVEPOINT +--reap +rollback; +set debug_sync= "RESET"; + + +--echo # +--echo # 26) RENAME variants. +--echo # +--echo # 26.1) RENAME TABLES is incompatible with FTWRL. +let $statement= rename table t1_base to t3_base; +let $cleanup_stmt1= rename table t3_base to t1_base; +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 26.2) RENAME USER is incompatible with FTWRL. +create user mysqltest_u1; +let $statement= rename user mysqltest_u1 to mysqltest_u2; +let $cleanup_stmt1= rename user mysqltest_u2 to mysqltest_u1; +--source include/check_ftwrl_incompatible.inc +drop user mysqltest_u1; + + +--echo # +--echo # 27) REPAIR TABLE statement. +--echo # +--echo # 27.a) REPAIR TABLE of base table is incompatible with FTWRL. +flush tables with read lock; +--echo # REPAIR statement returns errors as part of result-set. +repair table t1_base; +unlock tables; +--echo # +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +flush tables with read lock; +--echo # Switching to connection 'default'. +connection default; +--send repair table t1_base +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +--echo # Check that REPAIR TABLE is blocked. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for global read lock" and + info = "repair table t1_base"; +--source include/wait_condition.inc +unlock tables; +--echo # Switching to connection 'default'. +connection default; +--echo # Reap REPAIR TABLE +--reap +--echo # We don't check that active REPAIR TABLE blocks +--echo # FTWRL as this one of statements releasing metadata +--echo # locks in non-standard place. + +--echo # +--echo # 27.b) REPAIR TABLE of temporary table is compatible with FTWRL. +let $statement= repair table t1_temp; +let $cleanup_stmt= ; +--echo # Skip last part of compatibility testing as this statement +--echo # releases metadata locks in non-standard place. +let $skip_3rd_check= 1; +--source include/check_ftwrl_compatible.inc +let $skip_3rd_check= ; + + +--echo # +--echo # 28) REPLACE statement. +--echo # +--echo # 28.a) Ordinary REPLACE into base table is incompatible with FTWRL. +let $statement= replace into t1_base values (1); +let $cleanup_stmt1= delete from t1_base limit 1; +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 28.b) Ordinary REPLACE into temp table is compatible with FTWRL. +let $statement= replace into t1_temp values (1); +let $cleanup_stmt= delete from t1_temp limit 1; +--source include/check_ftwrl_compatible.inc + +--echo # +--echo # 28.c) REPLACE SELECT into base table is incompatible with FTWRL. +let $statement= replace into t1_base select * from t1_temp; +let $cleanup_stmt1= ; +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 28.d) REPLACE SELECT into temp table is compatible with FTWRL. +let $statement= replace into t1_temp select * from t1_base; +let $cleanup_stmt= ; +--source include/check_ftwrl_compatible.inc + + +--echo # +--echo # 29) REVOKE variants. +--echo # +--echo # 29.1) REVOKE privileges is incompatible with FTWRL. +grant all privileges on t1_base to mysqltest_u1; +let $statement= revoke all privileges on t1_base from mysqltest_u1; +let $cleanup_stmt1= grant all privileges on t1_base to mysqltest_u1; +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 29.2) REVOKE ALL PRIVILEGES, GRANT OPTION is incompatible with FTWRL. +let $statement= revoke all privileges, grant option from mysqltest_u1; +let $cleanup_stmt1= grant all privileges on t1_base to mysqltest_u1; +--source include/check_ftwrl_incompatible.inc +drop user mysqltest_u1; + + +--echo # +--echo # 30) Compatibility of SELECT statement with FTWRL depends on +--echo # locking mode used and on functions being invoked by it. +--echo # +--echo # 30.a) Simple SELECT which does not change tables should be +--echo # compatible with FTWRL. +let $statement= select count(*) from t1_base; +let $cleanup_stmt= ; +--source include/check_ftwrl_compatible.inc + +--echo # 30.b) SELECT ... FOR UPDATE is incompatible with FTWRL. +let $statement= select count(*) from t1_base for update; +let $cleanup_stmt1= ; +--source include/check_ftwrl_incompatible.inc + +--echo # 30.c) SELECT ... LOCK IN SHARE MODE is compatible with FTWRL. +let $statement= select count(*) from t1_base lock in share mode; +let $cleanup_stmt= ; +--source include/check_ftwrl_compatible.inc + +--echo # +--echo # 30.d) SELECT which calls SF updating base table should be +--echo # incompatible with FTWRL. +let $statement= select f2_base(); +let $cleanup_stmt1= delete from t1_base limit 1; +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 30.e) SELECT which calls SF updating temporary table should be +--echo # compatible with FTWRL. +let $statement= select f2_temp(); +let $cleanup_stmt= delete from t1_temp limit 1; +--source include/check_ftwrl_compatible.inc + + +--echo # +--echo # 31) Compatibility of SET statement with FTWRL depends on its +--echo # expression and on whether it is a special SET statement. +--echo # +--echo # 31.a) Ordinary SET with expression which does not +--echo # changes base table should be compatible with FTWRL. +let $statement= set @a:= (select count(*) from t1_base); +let $cleanup_stmt= ; +--echo # Skip last part of compatibility testing as our helper debug +--echo # sync-point doesn't work for SET statements. +let $skip_3rd_check= 1; +--source include/check_ftwrl_compatible.inc +let $skip_3rd_check= ; + +--echo # +--echo # 31.b) Ordinary SET which calls SF updating base table should +--echo # be incompatible with FTWRL. +let $statement= set @a:= f2_base(); +let $cleanup_stmt1= delete from t1_base limit 1; +--echo # Skip last part of compatibility testing as our helper debug +--echo # sync-point doesn't work for SET statements. +let $skip_3rd_check= 1; +--source include/check_ftwrl_incompatible.inc +let $skip_3rd_check= ; + +--echo # +--echo # 31.c) Ordinary SET which calls SF updating temporary table +--echo # should be compatible with FTWRL. +let $statement= set @a:= f2_temp(); +let $cleanup_stmt= delete from t1_temp limit 1; +--echo # Skip last part of compatibility testing as our helper debug +--echo # sync-point doesn't work for SET statements. +let $skip_3rd_check= 1; +--source include/check_ftwrl_compatible.inc +let $skip_3rd_check= ; + +--echo # +--echo # 31.d) Special SET variants have different compatibility with FTWRL. +--echo # +--echo # 31.d.I) SET PASSWORD is incompatible with FTWRL as it changes data. +create user mysqltest_u1; +let $statement= set password for 'mysqltest_u1' = password(''); +let $cleanup_stmt1= ; +--echo # Skip last part of compatibility testing as our helper debug +--echo # sync-point doesn't work for SET statements. +let $skip_3rd_check= 1; +--source include/check_ftwrl_incompatible.inc +let $skip_3rd_check= ; +drop user mysqltest_u1; +--echo # +--echo # 31.d.II) SET READ_ONLY is compatible with FTWRL (but has no +--echo # effect when executed under it). +let $statement= set global read_only= 1; +let $cleanup_stmt= set global read_only= 0; +--echo # Skip last part of compatibility testing as our helper debug +--echo # sync-point doesn't work for SET statements. +let $skip_3rd_check= 1; +--source include/check_ftwrl_compatible.inc +let $skip_3rd_check= ; +--echo # +--echo # 31.d.III) Situation with SET AUTOCOMMIT is complex. +--echo # Turning auto-commit off is always compatible with FTWRL. +--echo # Turning auto-commit on causes implicit commit and so +--echo # is incompatible with FTWRL if there are changes to be +--echo # committed. +flush tables with read lock; +set autocommit= 0; +--echo # Turning auto-commit on causes implicit commit so can +--echo # be incompatible with FTWRL if there is something to +--echo # commit. But since even in this case we allow commits +--echo # under active FTWRL such statement should always succeed. +insert into t3_temp_trans values (1); +set autocommit= 1; +unlock tables; +delete from t3_temp_trans; +--echo # Check that SET AUTOCOMMIT=0 is not blocked and +--echo # SET AUTOCOMMIT=1 is blocked by active FTWRL in +--echo # another connection. +--echo # +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +flush tables with read lock; +--echo # Switching to connection 'default'. +connection default; +set autocommit= 0; +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +unlock tables; +--echo # Switching to connection 'default'. +connection default; +--echo # Do some work so implicit commit in SET AUTOCOMMIT=1 +--echo # is not a no-op. +insert into t3_trans values (1); +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +flush tables with read lock; +--echo # Switching to connection 'default'. +connection default; +--echo # Send: +--send set autocommit= 1 +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +--echo # Wait until SET AUTOCOMMIT=1 is blocked. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for commit lock" and + info = "set autocommit= 1"; +--source include/wait_condition.inc +unlock tables; +--echo # Switching to connection 'default'. +connection default; +--echo # Reap SET AUTOCOMMIT=1. +--reap +delete from t3_trans; +--echo # +--echo # Check that SET AUTOCOMMIT=1 blocks FTWRL in another connection. +set autocommit= 0; +insert into t3_trans values (1); +set debug_sync='RESET'; +set debug_sync='ha_commit_trans_after_acquire_commit_lock SIGNAL parked WAIT_FOR go'; +--send set autocommit= 1 +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +set debug_sync='now WAIT_FOR parked'; +--send flush tables with read lock +--echo # Switching to connection '$con_aux2'. +connection $con_aux2; +--echo # Wait until FTWRL is blocked. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for commit lock" and + info = "flush tables with read lock"; +--source include/wait_condition.inc +set debug_sync='now SIGNAL go'; +--echo # Switching to connection 'default'. +connection default; +--echo # Reap SET AUTOCOMMIT=1. +--reap +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +--echo # Reap FTWRL. +--reap +unlock tables; +--echo # Switching to connection 'default'. +connection default; +delete from t3_trans; +set debug_sync= "RESET"; + + +--echo # +--echo # 32) SHOW statements are compatible with FTWRL. +--echo # Let us test _some_ of them. +--echo # +--echo # 32.1) SHOW TABLES. +let $statement= show tables from test; +let $cleanup_stmt= ; +--source include/check_ftwrl_compatible.inc + +--echo # +--echo # 32.1) SHOW TABLES. +let $statement= show tables from test; +let $cleanup_stmt= ; +--source include/check_ftwrl_compatible.inc + +--echo # +--echo # 32.2) SHOW EVENTS. +let $statement= show events from test; +let $cleanup_stmt= ; +--source include/check_ftwrl_compatible.inc + +--echo # +--echo # 32.3) SHOW GRANTS. +create user mysqltest_u1; +let $statement= show grants for mysqltest_u1; +let $cleanup_stmt= ; +--source include/check_ftwrl_compatible.inc +drop user mysqltest_u1; + +--echo # +--echo # 32.4) SHOW CREATE TABLE. +let $statement= show create table t1_base; +let $cleanup_stmt= ; +--source include/check_ftwrl_compatible.inc + +--echo # +--echo # 32.5) SHOW CREATE FUNCTION. +let $statement= show create function f1; +let $cleanup_stmt= ; +--source include/check_ftwrl_compatible.inc + + +--echo # +--echo # 33) SIGNAL statement is compatible with FTWRL. +--echo # +--echo # Note that we don't cover RESIGNAL as it requires +--echo # active handler context. +let $statement= signal sqlstate '01000'; +let $cleanup_stmt= ; +--source include/check_ftwrl_compatible.inc + + +--echo # +--echo # 34) TRUNCATE TABLE statement. +--echo # +--echo # 34.a) TRUNCATE of base table is incompatible with FTWRL. +let $statement= truncate table t1_base; +let $cleanup_stmt1= ; +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 34.b) TRUNCATE of temporary table is compatible with FTWRL. +let $statement= truncate table t1_temp; +let $cleanup_stmt= ; +--source include/check_ftwrl_compatible.inc + + +--echo # +--echo # 35) UPDATE variants. +--echo # +--echo # 35.1) Simple UPDATE. +--echo # +--echo # 35.1.a) Simple UPDATE on base table is incompatible with FTWRL. +let $statement= update t1_base set i= 1 where i = 0; +let $cleanup_stmt1= ; +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 35.1.b) Simple UPDATE on temporary table is compatible with FTWRL. +let $statement= update t1_temp set i= 1 where i = 0; +let $cleanup_stmt= ; +--source include/check_ftwrl_compatible.inc + +--echo # +--echo # 35.2) Multi UPDATE. +--echo # +--echo # 35.2.a) Multi UPDATE on base tables is incompatible with FTWRL. +let $statement= update t1_base, t2_base set t1_base.i= 1 where t1_base.i = t2_base.j; +let $cleanup_stmt1= ; +--source include/check_ftwrl_incompatible.inc + +--echo # +--echo # 35.2.b) Multi UPDATE on temporary tables is compatible with FTWRL. +let $statement= update t1_temp, t2_temp set t1_temp.i= 1 where t1_temp.i = t2_temp.j; +let $cleanup_stmt= ; +--source include/check_ftwrl_compatible.inc + + +--echo # +--echo # 36) USE statement is compatible with FTWRL. +--echo # +let $statement= use mysqltest1; +let $cleanup_stmt= use test; +--source include/check_ftwrl_compatible.inc + + +--echo # +--echo # 37) XA statements. +--echo # +--echo # XA statements are similar to BEGIN/COMMIT/ROLLBACK. +--echo # +--echo # XA BEGIN, END, PREPARE, ROLLBACK and RECOVER are compatible +--echo # with FTWRL. XA COMMIT is not. +flush tables with read lock; +--echo # Although all below statements are allowed under FTWRL they +--echo # are almost no-ops as FTWRL does commit and does not allows +--echo # any non-temporary DML under it. +xa start 'test1'; +xa end 'test1'; +xa prepare 'test1'; +xa rollback 'test1'; +xa start 'test1'; +xa end 'test1'; +xa prepare 'test1'; +xa commit 'test1'; +--disable_result_log +xa recover; +--enable_result_log +unlock tables; +--echo # Check that XA non-COMMIT statements are not and COMMIT is +--echo # blocked by active FTWRL in another connection +--echo # +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +flush tables with read lock; +--echo # Switching to connection 'default'. +connection default; +xa start 'test1'; +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +unlock tables; +--echo # Switching to connection 'default'. +connection default; +insert into t3_trans values (1); +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +flush tables with read lock; +--echo # Switching to connection 'default'. +connection default; +xa end 'test1'; +xa prepare 'test1'; +xa rollback 'test1'; +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +unlock tables; +--echo # Switching to connection 'default'. +connection default; +xa start 'test1'; +insert into t3_trans values (1); +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +flush tables with read lock; +--echo # Switching to connection 'default'. +connection default; +connection default; +xa end 'test1'; +xa prepare 'test1'; +--echo # Send: +--send xa commit 'test1'; +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +--echo # Wait until XA COMMIT is blocked. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for commit lock" and + info = "xa commit 'test1'"; +--source include/wait_condition.inc +unlock tables; +--echo # Switching to connection 'default'. +connection default; +--echo # Reap XA COMMIT. +--reap +delete from t3_trans; +--echo # +--echo # Check that XA COMMIT blocks FTWRL in another connection. +xa start 'test1'; +insert into t3_trans values (1); +xa end 'test1'; +xa prepare 'test1'; +set debug_sync='RESET'; +set debug_sync='trans_xa_commit_after_acquire_commit_lock SIGNAL parked WAIT_FOR go'; +--send xa commit 'test1' +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +set debug_sync='now WAIT_FOR parked'; +--send flush tables with read lock +--echo # Switching to connection '$con_aux2'. +connection $con_aux2; +--echo # Wait until FTWRL is blocked. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for commit lock" and + info = "flush tables with read lock"; +--source include/wait_condition.inc +set debug_sync='now SIGNAL go'; +--echo # Switching to connection 'default'. +connection default; +--echo # Reap XA COMMIT. +--reap +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +--echo # Reap FTWRL. +--reap +unlock tables; +--echo # Switching to connection 'default'. +connection default; +delete from t3_trans; +set debug_sync= "RESET"; + + +--echo # +--echo # 38) Test effect of auto-commit mode for DML on transactional +--echo # temporary tables. +--echo # +--echo # 38.1) When auto-commit is on each such a statement ends with commit +--echo # of changes to temporary tables. But since transactions doing +--echo # such changes are considered read only [sic!/QQ] this commit +--echo # is compatible with FTWRL. +--echo # +--echo # Let us demostrate this fact for some common DML statements. +let $statement= delete from t3_temp_trans; +let $cleanup_stmt= ; +--source include/check_ftwrl_compatible.inc + +let $statement= insert into t3_temp_trans values (1); +let $cleanup_stmt= delete from t3_temp_trans limit 1; +--source include/check_ftwrl_compatible.inc + +let $statement= update t3_temp_trans, t2_temp set t3_temp_trans.i= 1 where t3_temp_trans.i = t2_temp.j; +let $cleanup_stmt= ; +--source include/check_ftwrl_compatible.inc + +--echo # +--echo # 38.2) When auto-commit is off DML on transaction temporary tables +--echo # is compatible with FTWRL. +--echo # +set autocommit= 0; +let $statement= delete from t3_temp_trans; +let $cleanup_stmt= ; +--source include/check_ftwrl_compatible.inc + +let $statement= insert into t3_temp_trans values (1); +let $cleanup_stmt= delete from t3_temp_trans limit 1; +--source include/check_ftwrl_compatible.inc + +let $statement= update t3_temp_trans, t2_temp set t3_temp_trans.i= 1 where t3_temp_trans.i = t2_temp.j; +let $cleanup_stmt= ; +--source include/check_ftwrl_compatible.inc +set autocommit= 1; + + +--echo # +--echo # 39) Test effect of DDL on transactional tables. +--echo # +--echo # 39.1) Due to implicit commit at the end of statement some of DDL +--echo # statements which are compatible with FTWRL in non-transactional +--echo # case are not compatible in case of transactional tables. +--echo # +--echo # 39.1.a) ANALYZE TABLE for transactional table is incompatible with +--echo # FTWRL. +flush tables with read lock; +--echo # Implicit commits are allowed under FTWRL. +analyze table t3_trans; +unlock tables; +--echo # +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +flush tables with read lock; +--echo # Switching to connection 'default'. +connection default; +--send analyze table t3_trans +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +--echo # Check that ANALYZE TABLE is blocked. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for commit lock" and + info = "analyze table t3_trans"; +--source include/wait_condition.inc +unlock tables; +--echo # Switching to connection 'default'. +connection default; +--echo # Reap ANALYZE TABLE +--reap + +--echo # +--echo # 39.1.b) CHECK TABLE for transactional table is compatible with FTWRL. +--echo # Although it does implicit commit at the end of statement it +--echo # is considered to be read-only operation. +let $statement= check table t3_trans; +let $cleanup_stmt= ; +--echo # Skip last part of compatibility testing as this statement +--echo # releases metadata locks in non-standard place. +let $skip_3rd_check= 1; +--source include/check_ftwrl_compatible.inc +let $skip_3rd_check= ; + +--echo # +--echo # 39.2) Situation with DDL on temporary transactional tables is +--echo # complex. +--echo # +--echo # 39.2.a) Some statements compatible with FTWRL since they don't +--echo # do implicit commit. +--echo # +--echo # For example, CREATE TEMPORARY TABLE: +let $statement= create temporary table t4_temp_trans(i int) engine=innodb; +let $cleanup_stmt= drop temporary tables t4_temp_trans; +--source include/check_ftwrl_compatible.inc +--echo # +--echo # Or DROP TEMPORARY TABLE: +let $statement= drop temporary tables t3_temp_trans; +let $cleanup_stmt= create temporary table t3_temp_trans(i int) engine=innodb; +--source include/check_ftwrl_compatible.inc +--echo # +--echo # 39.2.b) Some statements do implicit commit but are considered +--echo # read-only and so are compatible with FTWRL. +--echo # +--echo # For example, REPAIR TABLE: +let $statement= repair table t3_temp_trans; +let $cleanup_stmt= ; +--source include/check_ftwrl_compatible.inc +--echo # +--echo # And ANALYZE TABLE: +let $statement= analyze table t3_temp_trans; +let $cleanup_stmt= ; +--source include/check_ftwrl_compatible.inc +--echo # +--echo # 39.2.c) Some statements do implicit commit and not +--echo # considered read-only. As result they are +--echo # not compatible with FTWRL. +--echo # +flush tables with read lock; +--echo # Implicit commits are allowed under FTWRL. +alter table t3_temp_trans add column c1 int; +unlock tables; +--echo # +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +flush tables with read lock; +--echo # Switching to connection 'default'. +connection default; +--send alter table t3_temp_trans drop column c1 +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +--echo # Check that ALTER TABLE is blocked. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for commit lock" and + info = "alter table t3_temp_trans drop column c1"; +--source include/wait_condition.inc +unlock tables; +--echo # Switching to connection 'default'. +connection default; +--echo # Reap ALTER TABLE +--reap + + +--echo # +--echo # 40) Test effect of implicit commit for DDL which is otherwise +--echo # compatible with FTWRL. Implicit commit at the start of DDL +--echo # statement can make it incompatible with FTWRL if there are +--echo # some changes to be commited even in case when DDL statement +--echo # itself is compatible with FTWRL. +--echo # +--echo # For example CHECK TABLE for base non-transactional tables and +--echo # ALTER TABLE for temporary non-transactional tables are affected. +begin; +insert into t3_trans values (1); +--echo # +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +flush tables with read lock; +--echo # Switching to connection 'default'. +connection default; +--send check table t1_base +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +--echo # Check that CHECK TABLE is blocked. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for commit lock" and + info = "check table t1_base"; +--source include/wait_condition.inc +unlock tables; +--echo # Switching to connection 'default'. +connection default; +--echo # Reap CHECK TABLE +--reap +begin; +delete from t3_trans; +--echo # +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +flush tables with read lock; +--echo # Switching to connection 'default'. +connection default; +--send alter table t1_temp add column c1 int +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +--echo # Check that ALTER TABLE is blocked. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for commit lock" and + info = "alter table t1_temp add column c1 int"; +--source include/wait_condition.inc +unlock tables; +--echo # Switching to connection 'default'. +connection default; +--echo # Reap ALTER TABLE +--reap +alter table t1_temp drop column c1; + + +--echo # +--echo # Check that FLUSH TABLES WITH READ LOCK is blocked by individual +--echo # statements and is not blocked in the presence of transaction which +--echo # has done some changes earlier but is idle now (or does only reads). +--echo # This allows to use this statement even on systems which has long +--echo # running transactions. +--echo # +begin; +insert into t1_base values (1); +insert into t3_trans values (1); +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +--echo # The below FTWRL should not be blocked by transaction in 'default'. +flush tables with read lock; +--echo # Switching to connection 'default'. +connection default; +--echo # Transaction still is able to read even with FTWRL active in another +--echo # connection. +select * from t1_base; +select * from t2_base; +select * from t3_trans; +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +unlock tables; +--echo # Switching to connection 'default'. +connection default; +commit; +delete from t1_base; +delete from t3_trans; + + +--echo # +--echo # Check that impending FTWRL blocks new DML statements and +--echo # so can't be starved by a constant flow of DML. +--echo # (a.k.a. test for bug #54673 "It takes too long to get +--echo # readlock for 'FLUSH TABLES WITH READ LOCK'"). +--echo # +set debug_sync='RESET'; +set debug_sync='execute_command_after_close_tables SIGNAL parked WAIT_FOR go'; +--send insert into t1_base values (1) +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +set debug_sync='now WAIT_FOR parked'; +--send flush tables with read lock +--echo # Switching to connection '$con_aux2'. +connection $con_aux2; +--echo # Wait until FTWRL is blocked. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for global read lock" and + info = "flush tables with read lock"; +--source include/wait_condition.inc +--echo # Try to run another INSERT and see that it is blocked. +--send insert into t2_base values (1); +--echo # Switching to connection 'con3'. +connection con3; +--echo # Wait until new INSERT is blocked. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for global read lock" and + info = "insert into t2_base values (1)"; +--echo # Unblock INSERT in the first connection. +set debug_sync='now SIGNAL go'; +--echo # Switching to connection 'default'. +connection default; +--echo # Reap first INSERT. +--reap +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +--echo # Reap FTWRL. +--reap +unlock tables; +--echo # Switching to connection '$con_aux2'. +connection $con_aux2; +--echo # Reap second INSERT. +--reap +--echo # Switching to connection 'default'. +connection default; +set debug_sync= "RESET"; +delete from t1_base; +delete from t2_base; + +--echo +--echo # Check that COMMIT thas is issued after +--echo # FLUSH TABLES WITH READ LOCK is not blocked by +--echo # FLUSH TABLES WITH READ LOCK from another connection. +--echo # This scenario is used in innobackup.pl. The COMMIT goes +--echo # through because the transaction started by FTWRL does +--echo # not modify any tables, and the commit blocker lock is +--echo # only taken when there were such modifications. +--echo +flush tables with read lock; +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +--echo # The below FTWRL should not be blocked by transaction in 'default'. +flush tables with read lock; +--echo # Switching to connection 'default'. +connection default; +select * from t1_base; +select * from t3_trans; +commit; +--echo # Switching to connection '$con_aux1'. +connection $con_aux1; +select * from t1_base; +select * from t3_trans; +commit; +unlock tables; +--echo # Switching to connection 'default'. +connection default; +unlock tables; + + +--echo # +--echo # Check how FLUSH TABLE WITH READ LOCK is handled for MERGE tables. +--echo # As usual there are tricky cases related to this type of tables. +--echo # +--echo # +--echo # 1) Most typical case - base MERGE table with base underlying tables. +--echo # +--echo # 1.a) DML statements which change data should be incompatible with FTWRL. +create table tm_base (i int) engine=merge union=(t1_base) insert_method=last; +let $statement= insert into tm_base values (1); +let $cleanup_stmt1= delete from tm_base; +--source include/check_ftwrl_incompatible.inc +--echo # +--echo # 1.b) DDL statement on such table should be incompatible with FTWRL as well. +let $statement= alter table tm_base insert_method=first; +let $cleanup_stmt1= alter table tm_base insert_method=last; +--source include/check_ftwrl_incompatible.inc +drop table tm_base; + +--echo # +--echo # 2) Temporary MERGE table with base underlying tables. +--echo # +--echo # 2.a) DML statements which change data should be incompatible with FTWRL +--echo # as they affect base tables. +create temporary table tm_temp_base (i int) engine=merge union=(t1_base) insert_method=last; +let $statement= insert into tm_temp_base values (1); +let $cleanup_stmt1= delete from tm_temp_base; +--source include/check_ftwrl_incompatible.inc +--echo # +--echo # 2.b) Some of DDL statements on such table can be compatible with FTWRL +--echo # as they don't affect base tables. +let $statement= drop temporary tables tm_temp_base; +let $cleanup_stmt= create temporary table tm_temp_base (i int) engine=merge union=(t1_base) insert_method=last; +--source include/check_ftwrl_compatible.inc +--echo # +--echo # 2.c) ALTER statement is incompatible with FTWRL. Even though it does +--echo # not change data in base table it still acquires strong metadata +--echo # locks on them. +let $statement= alter table tm_temp_base insert_method=first; +let $cleanup_stmt1= alter table tm_temp_base insert_method=last; +--source include/check_ftwrl_incompatible.inc +drop table tm_temp_base; + +--echo # +--echo # 3) Temporary MERGE table with temporary underlying tables. +--echo # +--echo # 3.a) DML statements should be compatible with FTWRL as +--echo # no base table is going to be affected. +create temporary table tm_temp_temp (i int) engine=merge union=(t1_temp) insert_method=last; +let $statement= insert into tm_temp_temp values (1); +let $cleanup_stmt= delete from tm_temp_temp; +--source include/check_ftwrl_compatible.inc +--echo # +--echo # 3.b) DDL statements should be compatible with FTWRL as well +--echo # as no base table is going to be affected too. +let $statement= alter table tm_temp_temp union=(t1_temp) insert_method=first; +let $cleanup_stmt= alter table tm_temp_temp union=(t1_temp) insert_method=last; +--source include/check_ftwrl_compatible.inc +drop table tm_temp_temp; + +--echo # +--echo # 4) For the sake of completeness let us check that base MERGE tables +--echo # with temporary underlying tables are not functional. +create table tm_base_temp (i int) engine=merge union=(t1_temp) insert_method=last; +--error ER_WRONG_MRG_TABLE +select * from tm_base_temp; +drop table tm_base_temp; + + +--echo # +--echo # Clean-up. +--echo # +drop event e1; +drop function f2_temp; +drop function f2_base; +drop procedure p2; +drop view v1; +drop function f1; +drop procedure p1; +drop database `#mysql50#mysqltest-2`; +drop database mysqltest1; +drop temporary tables t1_temp, t2_temp; +drop tables t1_base, t2_base, t3_trans; +disconnect con1; +disconnect con2; +disconnect con3; + +# Check that all connections opened by test cases in this file are really +# gone so execution of other tests won't be affected by their presence. +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/t/flush_read_lock_kill-master.opt b/mysql-test/t/flush_read_lock_kill-master.opt deleted file mode 100644 index 61e2b242351..00000000000 --- a/mysql-test/t/flush_read_lock_kill-master.opt +++ /dev/null @@ -1 +0,0 @@ ---loose-debug=+d,make_global_read_lock_block_commit_loop diff --git a/mysql-test/t/flush_read_lock_kill.test b/mysql-test/t/flush_read_lock_kill.test index 2d359383949..a672fa5dfc5 100644 --- a/mysql-test/t/flush_read_lock_kill.test +++ b/mysql-test/t/flush_read_lock_kill.test @@ -2,24 +2,19 @@ # for running commits to finish (in the past it could not) # This will not be a meaningful test on non-debug servers so will be # skipped. -# If running mysql-test-run --debug, the --debug added by -# mysql-test-run to the mysqld command line will override the one of -# -master.opt. But this test is designed to still pass then (though it -# won't test anything interesting). # This also won't work with the embedded server test --source include/not_embedded.inc --source include/have_debug.inc +# This test needs transactional engine as otherwise COMMIT +# won't block FLUSH TABLES WITH GLOBAL READ LOCK. +--source include/have_innodb.inc + # Save the initial number of concurrent sessions --source include/count_sessions.inc -# Disable concurrent inserts to avoid test failures when reading the -# connection id which was inserted into a table by another thread. -SET @old_concurrent_insert= @@global.concurrent_insert; -SET @@global.concurrent_insert= 0; - connect (con1,localhost,root,,); connect (con2,localhost,root,,); connection con1; @@ -27,47 +22,64 @@ connection con1; --disable_warnings DROP TABLE IF EXISTS t1; --enable_warnings -CREATE TABLE t1 (kill_id INT); +SET DEBUG_SYNC= 'RESET'; +CREATE TABLE t1 (kill_id INT) engine = InnoDB; INSERT INTO t1 VALUES(connection_id()); -# Thanks to the parameter we passed to --debug, this FLUSH will -# block on a debug build running with our --debug=make_global... It -# will block until killed. In other cases (non-debug build or other -# --debug) it will succeed immediately +--echo # Switching to connection 'default'. +connection default; +--echo # Start transaction. +BEGIN; +INSERT INTO t1 VALUES(connection_id()); +--echo # Ensure that COMMIT will pause once it acquires protection +--echo # against its global read lock. +SET DEBUG_SYNC='ha_commit_trans_after_acquire_commit_lock SIGNAL acquired WAIT_FOR go'; +--echo # Sending: +--send COMMIT + +--echo # Switching to 'con1'. connection con1; +--echo # Wait till COMMIT acquires protection against global read +--echo # lock and pauses. +SET DEBUG_SYNC='now WAIT_FOR acquired'; +--echo # Sending: send FLUSH TABLES WITH READ LOCK; -# kill con1 +--echo # Switching to 'con2'. connection con2; -SELECT ((@id := kill_id) - kill_id) FROM t1; +SELECT ((@id := kill_id) - kill_id) FROM t1 LIMIT 1; -# Wait for the debug sync point, test won't run on non-debug -# builds anyway. +--echo # Wait till FLUSH TABLES WITH READ LOCK blocks due +--echo # to active COMMIT let $wait_condition= select count(*) = 1 from information_schema.processlist - where state = "Waiting for all running commits to finish" + where state = "Waiting for commit lock" and info = "flush tables with read lock"; --source include/wait_condition.inc +--echo # Kill connection 'con1'. KILL CONNECTION @id; +--echo # Switching to 'con1'. connection con1; -# On debug builds it will be error 1053 (killed); on non-debug, or -# debug build running without our --debug=make_global..., will be -# error 0 (no error). The only important thing to test is that on -# debug builds with our --debug=make_global... we don't hang forever. ---error 0,1317,2013 +--echo # Try to reap FLUSH TABLES WITH READ LOCK, +--echo # it fail due to killed statement and connection. +--error 1317,2013 reap; +--echo # Switching to 'con2'. connection con2; -DROP TABLE t1; +--echo # Resume COMMIT. +SET DEBUG_SYNC='now SIGNAL go'; +--echo # Switching to 'default'. connection default; +--echo # Reaping COMMIT. +--reap disconnect con2; - -# Restore global concurrent_insert value -SET @@global.concurrent_insert= @old_concurrent_insert; +DROP TABLE t1; +SET DEBUG_SYNC= 'RESET'; # Wait till all disconnects are completed --source include/wait_until_count_sessions.inc diff --git a/mysql-test/t/lock_multi.test b/mysql-test/t/lock_multi.test index 6bdb235903d..5bab5e647ab 100644 --- a/mysql-test/t/lock_multi.test +++ b/mysql-test/t/lock_multi.test @@ -228,7 +228,7 @@ connection writer; # Sleep a bit till the flush of connection locker is in work and hangs let $wait_condition= select count(*) = 1 from information_schema.processlist - where state = "Waiting for global metadata lock" and + where state = "Waiting for global read lock" and info = "FLUSH TABLES WITH READ LOCK"; --source include/wait_condition.inc # This must not block. @@ -260,7 +260,7 @@ connection writer; # Sleep a bit till the flush of connection locker is in work and hangs let $wait_condition= select count(*) = 1 from information_schema.processlist - where state = "Waiting for global metadata lock" and + where state = "Waiting for global read lock" and info = "FLUSH TABLES WITH READ LOCK"; --source include/wait_condition.inc --error ER_TABLE_NOT_LOCKED @@ -296,10 +296,11 @@ DROP DATABASE mysqltest_1; # With bug in place: try to acquire LOCK_mysql_create_table... # When fixed: Reject dropping db because of the read lock. connection con1; -# Wait a bit so that the session con2 is in state "Waiting for release of readlock" +# Wait a bit so that the session con2 is in state +# "Waiting for global read lock" let $wait_condition= select count(*) = 1 from information_schema.processlist - where state = "Waiting for release of readlock" + where state = "Waiting for global read lock" and info = "DROP DATABASE mysqltest_1"; --source include/wait_condition.inc --error ER_CANT_UPDATE_WITH_READLOCK @@ -376,7 +377,7 @@ connection con5; --echo # con5 let $wait_condition= select count(*) = 1 from information_schema.processlist - where state = "Waiting for global metadata lock" and + where state = "Waiting for global read lock" and info = "flush tables with read lock"; --source include/wait_condition.inc --echo # global read lock is taken @@ -384,10 +385,11 @@ connection con3; --echo # con3 send select * from t2 for update; connection con5; -let $show_statement= SHOW PROCESSLIST; -let $field= State; -let $condition= = 'Waiting for release of readlock'; ---source include/wait_show_condition.inc +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for global read lock" and + info = "select * from t2 for update"; +--source include/wait_condition.inc --echo # waiting for release of read lock connection con4; --echo # con4 @@ -433,10 +435,11 @@ connection con1; send update t2 set a = 1; connection default; --echo # default -let $show_statement= SHOW PROCESSLIST; -let $field= State; -let $condition= = 'Waiting for release of readlock'; ---source include/wait_show_condition.inc +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for global read lock" and + info = "update t2 set a = 1"; +--source include/wait_condition.inc --echo # statement is waiting for release of read lock connection con2; --echo # con2 @@ -460,10 +463,11 @@ connection con1; send lock tables t2 write; connection default; --echo # default -let $show_statement= SHOW PROCESSLIST; -let $field= State; -let $condition= = 'Waiting for release of readlock'; ---source include/wait_show_condition.inc +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for global read lock" and + info = "lock tables t2 write"; +--source include/wait_condition.inc --echo # statement is waiting for release of read lock connection con2; --echo # con2 @@ -571,7 +575,8 @@ connection default; --echo connection: default let $wait_condition= select count(*) = 1 from information_schema.processlist - where state = "Waiting for global metadata lock"; + where state = "Waiting for global read lock" and + info = "flush tables with read lock"; --source include/wait_condition.inc alter table t1 add column j int; connect (insert,localhost,root,,test,,); @@ -579,14 +584,16 @@ connection insert; --echo connection: insert let $wait_condition= select count(*) = 1 from information_schema.processlist - where state = "Waiting for global metadata lock"; + where state = "Waiting for global read lock" and + info = "flush tables with read lock"; --source include/wait_condition.inc --send insert into t1 values (1,2); --echo connection: default connection default; let $wait_condition= select count(*) = 1 from information_schema.processlist - where state = "Waiting for release of readlock"; + where state = "Waiting for global read lock" and + info = "insert into t1 values (1,2)"; --source include/wait_condition.inc unlock tables; connection flush; @@ -594,7 +601,8 @@ connection flush; --reap let $wait_condition= select count(*) = 1 from information_schema.processlist - where state = "Waiting for release of readlock"; + where state = "Waiting for global read lock" and + info = "insert into t1 values (1,2)"; --source include/wait_condition.inc select * from t1; unlock tables; @@ -629,12 +637,12 @@ connection default; --echo connection: default let $wait_condition= select count(*) = 1 from information_schema.processlist - where state = "Waiting for global metadata lock"; + where state = "Waiting for global read lock"; --source include/wait_condition.inc flush tables; let $wait_condition= select count(*) = 1 from information_schema.processlist - where state = "Waiting for global metadata lock"; + where state = "Waiting for global read lock"; --source include/wait_condition.inc unlock tables; connection flush; @@ -698,12 +706,12 @@ connection default; --echo connection: default let $wait_condition= select count(*) = 1 from information_schema.processlist - where state = "Waiting for global metadata lock"; + where state = "Waiting for global read lock"; --source include/wait_condition.inc flush tables; let $wait_condition= select count(*) = 1 from information_schema.processlist - where state = "Waiting for global metadata lock"; + where state = "Waiting for global read lock"; --source include/wait_condition.inc drop table t1; connection flush; diff --git a/mysql-test/t/mdl_sync.test b/mysql-test/t/mdl_sync.test index 5c4fc20b428..197cad536e4 100644 --- a/mysql-test/t/mdl_sync.test +++ b/mysql-test/t/mdl_sync.test @@ -3661,7 +3661,7 @@ connection con2; SET DEBUG_SYNC= 'now WAIT_FOR table_opened'; --echo # Check that FLUSH must wait to get the GRL --echo # and let CREATE PROCEDURE continue -SET DEBUG_SYNC= 'wait_lock_global_read_lock SIGNAL grlwait'; +SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL grlwait'; --send FLUSH TABLES WITH READ LOCK --echo # Connection 1 @@ -3689,15 +3689,22 @@ connection con2; SET DEBUG_SYNC= 'now WAIT_FOR table_opened'; --echo # Check that FLUSH must wait to get the GRL --echo # and let DROP PROCEDURE continue -SET DEBUG_SYNC= 'wait_lock_global_read_lock SIGNAL grlwait'; +SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL grlwait'; --send FLUSH TABLES WITH READ LOCK --echo # Connection 1 connection default; +--echo # Once FLUSH TABLES WITH READ LOCK starts waiting +--echo # DROP PROCEDURE will be waked up and will drop +--echo # procedure. Global read lock will be granted after +--echo # this statement ends. +--echo # +--echo # Reaping DROP PROCEDURE. --reap --echo # Connection 2 connection con2; +--echo # Reaping FTWRL. --reap UNLOCK TABLES; @@ -4485,7 +4492,7 @@ connection con2; --echo # Connection default connection default; let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist - WHERE state='Waiting for release of readlock' + WHERE state='Waiting for global read lock' AND info='CREATE TABLE db1.t2(a INT)'; --source include/wait_condition.inc UNLOCK TABLES; @@ -4507,7 +4514,7 @@ connection con2; --echo # Connection default connection default; let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist - WHERE state='Waiting for release of readlock' + WHERE state='Waiting for global read lock' AND info='ALTER DATABASE db1 DEFAULT CHARACTER SET utf8'; --source include/wait_condition.inc UNLOCK TABLES; diff --git a/mysql-test/t/trigger_notembedded.test b/mysql-test/t/trigger_notembedded.test index 89857063ebd..536b00308ab 100644 --- a/mysql-test/t/trigger_notembedded.test +++ b/mysql-test/t/trigger_notembedded.test @@ -896,7 +896,7 @@ connection default; --echo connection: default let $wait_condition= select count(*) = 1 from information_schema.processlist - where state = "Waiting for global metadata lock"; + where state = "Waiting for global read lock"; --source include/wait_condition.inc create trigger t1_bi before insert on t1 for each row begin end; unlock tables; diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc index 52c509621ac..bdc79dcbcfd 100644 --- a/sql/event_data_objects.cc +++ b/sql/event_data_objects.cc @@ -290,7 +290,6 @@ Event_basic::load_time_zone(THD *thd, const LEX_STRING tz_name) */ Event_queue_element::Event_queue_element(): - status_changed(FALSE), last_executed_changed(FALSE), on_completion(Event_parse_data::ON_COMPLETION_DROP), status(Event_parse_data::ENABLED), expression(0), dropped(FALSE), execution_count(0) @@ -539,7 +538,6 @@ Event_queue_element::load_from_row(THD *thd, TABLE *table) TIME_NO_ZERO_DATE); last_executed= my_tz_OFFSET0->TIME_to_gmt_sec(&time,¬_used); } - last_executed_changed= FALSE; if ((ptr= get_field(&mem_root, table->field[ET_FIELD_STATUS])) == NullS) DBUG_RETURN(TRUE); @@ -935,7 +933,6 @@ Event_queue_element::compute_next_execution_time() DBUG_PRINT("info",("One-time event will be dropped: %d.", dropped)); status= Event_parse_data::DISABLED; - status_changed= TRUE; } goto ret; } @@ -955,7 +952,6 @@ Event_queue_element::compute_next_execution_time() dropped= TRUE; DBUG_PRINT("info", ("Dropped: %d", dropped)); status= Event_parse_data::DISABLED; - status_changed= TRUE; goto ret; } @@ -1018,7 +1014,6 @@ Event_queue_element::compute_next_execution_time() if (on_completion == Event_parse_data::ON_COMPLETION_DROP) dropped= TRUE; status= Event_parse_data::DISABLED; - status_changed= TRUE; } else { @@ -1108,7 +1103,6 @@ Event_queue_element::compute_next_execution_time() execute_at= 0; execute_at_null= TRUE; status= Event_parse_data::DISABLED; - status_changed= TRUE; if (on_completion == Event_parse_data::ON_COMPLETION_DROP) dropped= TRUE; } @@ -1144,50 +1138,11 @@ void Event_queue_element::mark_last_executed(THD *thd) { last_executed= (my_time_t) thd->query_start(); - last_executed_changed= TRUE; execution_count++; } -/* - Saves status and last_executed_at to the disk if changed. - - SYNOPSIS - Event_queue_element::update_timing_fields() - thd - thread context - - RETURN VALUE - FALSE OK - TRUE Error while opening mysql.event for writing or during - write on disk -*/ - -bool -Event_queue_element::update_timing_fields(THD *thd) -{ - Event_db_repository *db_repository= Events::get_db_repository(); - int ret; - - DBUG_ENTER("Event_queue_element::update_timing_fields"); - - DBUG_PRINT("enter", ("name: %*s", (int) name.length, name.str)); - - /* No need to update if nothing has changed */ - if (!(status_changed || last_executed_changed)) - DBUG_RETURN(0); - - ret= db_repository->update_timing_fields_for_event(thd, - dbname, name, - last_executed_changed, - last_executed, - status_changed, - (ulonglong) status); - last_executed_changed= status_changed= FALSE; - DBUG_RETURN(ret); -} - - static void append_datetime(String *buf, Time_zone *time_zone, my_time_t secs, diff --git a/sql/event_data_objects.h b/sql/event_data_objects.h index 9d17213bcb8..46740812d31 100644 --- a/sql/event_data_objects.h +++ b/sql/event_data_objects.h @@ -82,10 +82,6 @@ protected: class Event_queue_element : public Event_basic { -protected: - bool status_changed; - bool last_executed_changed; - public: int on_completion; int status; @@ -117,9 +113,6 @@ public: void mark_last_executed(THD *thd); - - bool - update_timing_fields(THD *thd); }; diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc index db508e4ea41..053558aa0c3 100644 --- a/sql/event_db_repository.cc +++ b/sql/event_db_repository.cc @@ -622,6 +622,12 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data, TABLE *table= NULL; sp_head *sp= thd->lex->sphead; ulong saved_mode= thd->variables.sql_mode; + /* + Take a savepoint to release only the lock on mysql.event + table at the end but keep the global read lock and + possible other locks taken by the caller. + */ + MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint(); DBUG_ENTER("Event_db_repository::create_event"); @@ -699,8 +705,8 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data, ret= 0; end: - if (table) - close_mysql_tables(thd); + close_thread_tables(thd); + thd->mdl_context.rollback_to_savepoint(mdl_savepoint); thd->variables.sql_mode= saved_mode; DBUG_RETURN(test(ret)); @@ -734,6 +740,12 @@ Event_db_repository::update_event(THD *thd, Event_parse_data *parse_data, TABLE *table= NULL; sp_head *sp= thd->lex->sphead; ulong saved_mode= thd->variables.sql_mode; + /* + Take a savepoint to release only the lock on mysql.event + table at the end but keep the global read lock and + possible other locks taken by the caller. + */ + MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint(); int ret= 1; DBUG_ENTER("Event_db_repository::update_event"); @@ -811,8 +823,8 @@ Event_db_repository::update_event(THD *thd, Event_parse_data *parse_data, ret= 0; end: - if (table) - close_mysql_tables(thd); + close_thread_tables(thd); + thd->mdl_context.rollback_to_savepoint(mdl_savepoint); thd->variables.sql_mode= saved_mode; DBUG_RETURN(test(ret)); @@ -838,6 +850,12 @@ Event_db_repository::drop_event(THD *thd, LEX_STRING db, LEX_STRING name, bool drop_if_exists) { TABLE *table= NULL; + /* + Take a savepoint to release only the lock on mysql.event + table at the end but keep the global read lock and + possible other locks taken by the caller. + */ + MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint(); int ret= 1; DBUG_ENTER("Event_db_repository::drop_event"); @@ -866,8 +884,8 @@ Event_db_repository::drop_event(THD *thd, LEX_STRING db, LEX_STRING name, ret= 0; end: - if (table) - close_mysql_tables(thd); + close_thread_tables(thd); + thd->mdl_context.rollback_to_savepoint(mdl_savepoint); DBUG_RETURN(test(ret)); } @@ -940,7 +958,7 @@ Event_db_repository::drop_schema_events(THD *thd, LEX_STRING schema) TABLE *table= NULL; READ_RECORD read_record_info; enum enum_events_table_field field= ET_FIELD_DB; - MDL_ticket *mdl_savepoint= thd->mdl_context.mdl_savepoint(); + MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint(); DBUG_ENTER("Event_db_repository::drop_schema_events"); DBUG_PRINT("enter", ("field=%d schema=%s", field, schema.str)); @@ -1042,15 +1060,14 @@ Event_db_repository:: update_timing_fields_for_event(THD *thd, LEX_STRING event_db_name, LEX_STRING event_name, - bool update_last_executed, my_time_t last_executed, - bool update_status, ulonglong status) { TABLE *table= NULL; Field **fields; int ret= 1; bool save_binlog_row_based; + MYSQL_TIME time; DBUG_ENTER("Event_db_repository::update_timing_fields_for_event"); @@ -1075,20 +1092,12 @@ update_timing_fields_for_event(THD *thd, /* Don't update create on row update. */ table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET; - if (update_last_executed) - { - MYSQL_TIME time; - my_tz_OFFSET0->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, MYSQL_TIMESTAMP_DATETIME); - fields[ET_FIELD_LAST_EXECUTED]->set_notnull(); - fields[ET_FIELD_LAST_EXECUTED]->store_time(&time, - MYSQL_TIMESTAMP_DATETIME); - } - if (update_status) - { - fields[ET_FIELD_STATUS]->set_notnull(); - fields[ET_FIELD_STATUS]->store(status, TRUE); - } + fields[ET_FIELD_STATUS]->set_notnull(); + fields[ET_FIELD_STATUS]->store(status, TRUE); if ((ret= table->file->ha_update_row(table->record[1], table->record[0]))) { diff --git a/sql/event_db_repository.h b/sql/event_db_repository.h index ea7f3bbac0e..58484d17f06 100644 --- a/sql/event_db_repository.h +++ b/sql/event_db_repository.h @@ -101,9 +101,7 @@ public: update_timing_fields_for_event(THD *thd, LEX_STRING event_db_name, LEX_STRING event_name, - bool update_last_executed, my_time_t last_executed, - bool update_status, ulonglong status); public: static bool diff --git a/sql/event_queue.cc b/sql/event_queue.cc index 458a7c1defd..92b8a2c9071 100644 --- a/sql/event_queue.cc +++ b/sql/event_queue.cc @@ -17,6 +17,8 @@ #include "unireg.h" #include "event_queue.h" #include "event_data_objects.h" +#include "event_db_repository.h" +#include "events.h" #include "sql_audit.h" #include "tztime.h" // my_tz_find, my_tz_OFFSET0, struct Time_zone #include "log.h" // sql_print_error @@ -444,7 +446,6 @@ Event_queue::recalculate_activation_times(THD *thd) for (i= 0; i < queue.elements; i++) { ((Event_queue_element*)queue_element(&queue, i))->compute_next_execution_time(); - ((Event_queue_element*)queue_element(&queue, i))->update_timing_fields(thd); } queue_fix(&queue); /* @@ -567,6 +568,8 @@ Event_queue::get_top_for_execution_if_time(THD *thd, { bool ret= FALSE; *event_name= NULL; + my_time_t last_executed; + int status; DBUG_ENTER("Event_queue::get_top_for_execution_if_time"); LOCK_QUEUE_DATA(); @@ -632,8 +635,14 @@ Event_queue::get_top_for_execution_if_time(THD *thd, top->execution_count++; (*event_name)->dropped= top->dropped; + /* + Save new values of last_executed timestamp and event status on stack + in order to be able to update event description in system table once + QUEUE_DATA lock is released. + */ + last_executed= top->last_executed; + status= top->status; - top->update_timing_fields(thd); if (top->status == Event_parse_data::DISABLED) { DBUG_PRINT("info", ("removing from the queue")); @@ -656,9 +665,16 @@ end: ret, (long) *event_name)); if (*event_name) + { DBUG_PRINT("info", ("db: %s name: %s", (*event_name)->dbname.str, (*event_name)->name.str)); + Event_db_repository *db_repository= Events::get_db_repository(); + (void) db_repository->update_timing_fields_for_event(thd, + (*event_name)->dbname, (*event_name)->name, + last_executed, (ulonglong) status); + } + DBUG_RETURN(ret); } diff --git a/sql/events.cc b/sql/events.cc index e7e47801586..23a0dc9eb52 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -30,6 +30,7 @@ #include "event_scheduler.h" #include "sp_head.h" // for Stored_program_creation_ctx #include "set_var.h" +#include "lock.h" // lock_object_name /** @addtogroup Event_Scheduler @@ -77,7 +78,6 @@ Event_queue *Events::event_queue; Event_scheduler *Events::scheduler; Event_db_repository *Events::db_repository; ulong Events::opt_event_scheduler= Events::EVENTS_OFF; -mysql_mutex_t Events::LOCK_event_metadata; bool Events::check_system_tables_error= FALSE; @@ -340,7 +340,9 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row())) thd->clear_current_stmt_binlog_format_row(); - mysql_mutex_lock(&LOCK_event_metadata); + if (lock_object_name(thd, MDL_key::EVENT, + parse_data->dbname.str, parse_data->name.str)) + DBUG_RETURN(TRUE); /* On error conditions my_error() is called so no need to handle here */ if (!(ret= db_repository->create_event(thd, parse_data, if_not_exists))) @@ -388,7 +390,6 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, } } } - mysql_mutex_unlock(&LOCK_event_metadata); /* Restore the state of binlog format */ DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); if (save_binlog_row_based) @@ -472,7 +473,9 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row())) thd->clear_current_stmt_binlog_format_row(); - mysql_mutex_lock(&LOCK_event_metadata); + if (lock_object_name(thd, MDL_key::EVENT, + parse_data->dbname.str, parse_data->name.str)) + DBUG_RETURN(TRUE); /* On error conditions my_error() is called so no need to handle here */ if (!(ret= db_repository->update_event(thd, parse_data, @@ -502,7 +505,6 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, ret= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); } } - mysql_mutex_unlock(&LOCK_event_metadata); /* Restore the state of binlog format */ DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); if (save_binlog_row_based) @@ -556,7 +558,9 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists) if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row())) thd->clear_current_stmt_binlog_format_row(); - mysql_mutex_lock(&LOCK_event_metadata); + if (lock_object_name(thd, MDL_key::EVENT, + dbname.str, name.str)) + DBUG_RETURN(TRUE); /* On error conditions my_error() is called so no need to handle here */ if (!(ret= db_repository->drop_event(thd, dbname, name, if_exists))) { @@ -566,7 +570,6 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists) DBUG_ASSERT(thd->query() && thd->query_length()); ret= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); } - mysql_mutex_unlock(&LOCK_event_metadata); /* Restore the state of binlog format */ DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); if (save_binlog_row_based) @@ -595,15 +598,12 @@ Events::drop_schema_events(THD *thd, char *db) DBUG_PRINT("enter", ("dropping events from %s", db)); /* - sic: no check if the scheduler is disabled or system tables + Sic: no check if the scheduler is disabled or system tables are damaged, as intended. */ - - mysql_mutex_lock(&LOCK_event_metadata); if (event_queue) event_queue->drop_schema_events(thd, db_lex); db_repository->drop_schema_events(thd, db_lex); - mysql_mutex_unlock(&LOCK_event_metadata); DBUG_VOID_RETURN; } @@ -915,12 +915,11 @@ Events::deinit() } #ifdef HAVE_PSI_INTERFACE -PSI_mutex_key key_LOCK_event_metadata, key_LOCK_event_queue, +PSI_mutex_key key_LOCK_event_queue, key_event_scheduler_LOCK_scheduler_state; static PSI_mutex_info all_events_mutexes[]= { - { &key_LOCK_event_metadata, "LOCK_event_metadata", PSI_FLAG_GLOBAL}, { &key_LOCK_event_queue, "LOCK_event_queue", PSI_FLAG_GLOBAL}, { &key_event_scheduler_LOCK_scheduler_state, "Event_scheduler::LOCK_scheduler_state", PSI_FLAG_GLOBAL} }; @@ -974,23 +973,6 @@ Events::init_mutexes() #ifdef HAVE_PSI_INTERFACE init_events_psi_keys(); #endif - - mysql_mutex_init(key_LOCK_event_metadata, - &LOCK_event_metadata, MY_MUTEX_INIT_FAST); -} - - -/* - Destroys Events mutexes - - SYNOPSIS - Events::destroy_mutexes() -*/ - -void -Events::destroy_mutexes() -{ - mysql_mutex_destroy(&LOCK_event_metadata); } diff --git a/sql/events.h b/sql/events.h index f3ebc6da4ad..a337b29049a 100644 --- a/sql/events.h +++ b/sql/events.h @@ -26,8 +26,7 @@ */ #ifdef HAVE_PSI_INTERFACE -extern PSI_mutex_key key_LOCK_event_metadata, - key_event_scheduler_LOCK_scheduler_state; +extern PSI_mutex_key key_event_scheduler_LOCK_scheduler_state; extern PSI_cond_key key_event_scheduler_COND_state; extern PSI_thread_key key_thread_event_scheduler, key_thread_event_worker; #endif /* HAVE_PSI_INTERFACE */ @@ -79,7 +78,6 @@ public: enum enum_opt_event_scheduler { EVENTS_OFF, EVENTS_ON, EVENTS_DISABLED }; /* Protected using LOCK_global_system_variables only. */ static ulong opt_event_scheduler; - static mysql_mutex_t LOCK_event_metadata; static bool check_if_system_tables_error(); static bool start(); static bool stop(); diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 6b07cf76d79..20745db9ce9 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -7382,38 +7382,35 @@ int ndbcluster_find_files(handlerton *hton, THD *thd, } /* + Delete old files. + ndbcluster_find_files() may be called from I_S code and ndbcluster_binlog thread in situations when some tables are already open. This means that code below will try to obtain exclusive metadata lock on some table - while holding shared meta-data lock on other tables. This might lead to - a deadlock, and therefore is disallowed by assertions of the metadata - locking subsystem. This is violation of metadata - locking protocol which has to be closed ASAP. + while holding shared meta-data lock on other tables. This might lead to a + deadlock but such a deadlock should be detected by MDL deadlock detector. + XXX: the scenario described above is not covered with any test. */ - if (!global_read_lock) + List_iterator_fast it3(delete_list); + while ((file_name_str= it3++)) { - // Delete old files - List_iterator_fast it3(delete_list); - while ((file_name_str= it3++)) - { - DBUG_PRINT("info", ("Remove table %s/%s", db, file_name_str)); - // Delete the table and all related files - TABLE_LIST table_list; - table_list.init_one_table(db, strlen(db), file_name_str, - strlen(file_name_str), file_name_str, - TL_WRITE); - table_list.mdl_request.set_type(MDL_EXCLUSIVE); - (void)mysql_rm_table_part2(thd, &table_list, - FALSE, /* if_exists */ - FALSE, /* drop_temporary */ - FALSE, /* drop_view */ - TRUE /* dont_log_query*/); - trans_commit_implicit(thd); /* Safety, should be unnecessary. */ - thd->mdl_context.release_transactional_locks(); - /* Clear error message that is returned when table is deleted */ - thd->clear_error(); - } + DBUG_PRINT("info", ("Remove table %s/%s", db, file_name_str)); + /* Delete the table and all related files. */ + TABLE_LIST table_list; + table_list.init_one_table(db, strlen(db), file_name_str, + strlen(file_name_str), file_name_str, + TL_WRITE); + table_list.mdl_request.set_type(MDL_EXCLUSIVE); + (void)mysql_rm_table_part2(thd, &table_list, + FALSE, /* if_exists */ + FALSE, /* drop_temporary */ + FALSE, /* drop_view */ + TRUE /* dont_log_query*/); + trans_commit_implicit(thd); /* Safety, should be unnecessary. */ + thd->mdl_context.release_transactional_locks(); + /* Clear error message that is returned when table is deleted */ + thd->clear_error(); } /* Lock mutex before creating .FRM files. */ diff --git a/sql/handler.cc b/sql/handler.cc index eb060002f48..22bb3069a9f 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -29,8 +29,6 @@ #include "sql_cache.h" // query_cache, query_cache_* #include "key.h" // key_copy, key_unpack, key_cmp_if_same, key_cmp #include "sql_table.h" // build_table_filename -#include "lock.h" // wait_if_global_read_lock, - // start_waiting_global_read_lock #include "sql_parse.h" // check_stack_overrun #include "sql_acl.h" // SUPER_ACL #include "sql_base.h" // free_io_cache @@ -41,6 +39,7 @@ #include "transaction.h" #include #include "probes_mysql.h" +#include "debug_sync.h" // DEBUG_SYNC #ifdef WITH_PARTITION_STORAGE_ENGINE #include "ha_partition.h" @@ -1155,6 +1154,7 @@ int ha_commit_trans(THD *thd, bool all) { uint rw_ha_count; bool rw_trans; + MDL_request mdl_request; DBUG_EXECUTE_IF("crash_commit_before", DBUG_SUICIDE();); @@ -1166,11 +1166,27 @@ int ha_commit_trans(THD *thd, bool all) /* rw_trans is TRUE when we in a transaction changing data */ rw_trans= is_real_trans && (rw_ha_count > 0); - if (rw_trans && - thd->global_read_lock.wait_if_global_read_lock(thd, FALSE, FALSE)) + if (rw_trans) { - ha_rollback_trans(thd, all); - DBUG_RETURN(1); + /* + Acquire a metadata lock which will ensure that COMMIT is blocked + by an active FLUSH TABLES WITH READ LOCK (and vice versa: + COMMIT in progress blocks FTWRL). + + We allow the owner of FTWRL to COMMIT; we assume that it knows + what it does. + */ + mdl_request.init(MDL_key::COMMIT, "", "", MDL_INTENTION_EXCLUSIVE, + MDL_EXPLICIT); + + if (thd->mdl_context.acquire_lock(&mdl_request, + thd->variables.lock_wait_timeout)) + { + ha_rollback_trans(thd, all); + DBUG_RETURN(1); + } + + DEBUG_SYNC(thd, "ha_commit_trans_after_acquire_commit_lock"); } if (rw_trans && @@ -1225,8 +1241,16 @@ int ha_commit_trans(THD *thd, bool all) DBUG_EXECUTE_IF("crash_commit_after", DBUG_SUICIDE();); RUN_HOOK(transaction, after_commit, (thd, FALSE)); end: - if (rw_trans) - thd->global_read_lock.start_waiting_global_read_lock(thd); + if (rw_trans && mdl_request.ticket) + { + /* + We do not always immediately release transactional locks + after ha_commit_trans() (see uses of ha_enable_transaction()), + thus we release the commit blocker lock as soon as it's + not needed. + */ + thd->mdl_context.release_lock(mdl_request.ticket); + } } /* Free resources and perform other cleanup even for 'empty' transactions. */ else if (is_real_trans) diff --git a/sql/lock.cc b/sql/lock.cc index 84cc24b3f61..2e141e1c9fb 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -777,8 +777,11 @@ bool lock_schema_name(THD *thd, const char *db) return TRUE; } - global_request.init(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE); - mdl_request.init(MDL_key::SCHEMA, db, "", MDL_EXCLUSIVE); + if (thd->global_read_lock.can_acquire_protection()) + return TRUE; + global_request.init(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE, + MDL_STATEMENT); + mdl_request.init(MDL_key::SCHEMA, db, "", MDL_EXCLUSIVE, MDL_TRANSACTION); mdl_requests.push_front(&mdl_request); mdl_requests.push_front(&global_request); @@ -793,13 +796,13 @@ bool lock_schema_name(THD *thd, const char *db) /** - Obtain an exclusive metadata lock on the stored routine name. + Obtain an exclusive metadata lock on an object name. @param thd Thread handle. - @param is_function Stored routine type (only functions or procedures - are name-locked. - @param db The schema the routine belongs to. - @param name Routine name. + @param mdl_type Object type (currently functions, procedures + and events can be name-locked). + @param db The schema the object belongs to. + @param name Object name in the schema. This function assumes that no metadata locks were acquired before calling it. Additionally, it cannot be called while @@ -815,12 +818,9 @@ bool lock_schema_name(THD *thd, const char *db) or this connection was killed. */ -bool lock_routine_name(THD *thd, bool is_function, +bool lock_object_name(THD *thd, MDL_key::enum_mdl_namespace mdl_type, const char *db, const char *name) { - MDL_key::enum_mdl_namespace mdl_type= (is_function ? - MDL_key::FUNCTION : - MDL_key::PROCEDURE); MDL_request_list mdl_requests; MDL_request global_request; MDL_request schema_request; @@ -836,9 +836,13 @@ bool lock_routine_name(THD *thd, bool is_function, DBUG_ASSERT(name); DEBUG_SYNC(thd, "before_wait_locked_pname"); - global_request.init(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE); - schema_request.init(MDL_key::SCHEMA, db, "", MDL_INTENTION_EXCLUSIVE); - mdl_request.init(mdl_type, db, name, MDL_EXCLUSIVE); + if (thd->global_read_lock.can_acquire_protection()) + return TRUE; + global_request.init(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE, + MDL_STATEMENT); + schema_request.init(MDL_key::SCHEMA, db, "", MDL_INTENTION_EXCLUSIVE, + MDL_TRANSACTION); + mdl_request.init(mdl_type, db, name, MDL_EXCLUSIVE, MDL_TRANSACTION); mdl_requests.push_front(&mdl_request); mdl_requests.push_front(&schema_request); @@ -888,45 +892,24 @@ static void print_lock_error(int error, const char *table) /**************************************************************************** Handling of global read locks + Global read lock is implemented using metadata lock infrastructure. + Taking the global read lock is TWO steps (2nd step is optional; without it, COMMIT of existing transactions will be allowed): lock_global_read_lock() THEN make_global_read_lock_block_commit(). - The global locks are handled through the global variables: - global_read_lock - count of threads which have the global read lock (i.e. have completed at - least the first step above) - global_read_lock_blocks_commit - count of threads which have the global read lock and block - commits (i.e. are in or have completed the second step above) - waiting_for_read_lock - count of threads which want to take a global read lock but cannot - protect_against_global_read_lock - count of threads which have set protection against global read lock. - - access to them is protected with a mutex LOCK_global_read_lock - - (XXX: one should never take LOCK_open if LOCK_global_read_lock is - taken, otherwise a deadlock may occur. Other mutexes could be a - problem too - grep the code for global_read_lock if you want to use - any other mutex here) Also one must not hold LOCK_open when calling - wait_if_global_read_lock(). When the thread with the global read lock - tries to close its tables, it needs to take LOCK_open in - close_thread_table(). - How blocking of threads by global read lock is achieved: that's - advisory. Any piece of code which should be blocked by global read lock must - be designed like this: - - call to wait_if_global_read_lock(). When this returns 0, no global read - lock is owned; if argument abort_on_refresh was 0, none can be obtained. - - job - - if abort_on_refresh was 0, call to start_waiting_global_read_lock() to - allow other threads to get the global read lock. I.e. removal of the - protection. - (Note: it's a bit like an implementation of rwlock). - - [ I am sorry to mention some SQL syntaxes below I know I shouldn't but found - no better descriptive way ] + semi-automatic. We assume that any statement which should be blocked + by global read lock will either open and acquires write-lock on tables + or acquires metadata locks on objects it is going to modify. For any + such statement global IX metadata lock is automatically acquired for + its duration (in case of LOCK TABLES until end of LOCK TABLES mode). + And lock_global_read_lock() simply acquires global S metadata lock + and thus prohibits execution of statements which modify data (unless + they modify only temporary tables). If deadlock happens it is detected + by MDL subsystem and resolved in the standard fashion (by backing-off + metadata locks acquired so far and restarting open tables process + if possible). Why does FLUSH TABLES WITH READ LOCK need to block COMMIT: because it's used to read a non-moving SHOW MASTER STATUS, and a COMMIT writes to the binary @@ -960,11 +943,6 @@ static void print_lock_error(int error, const char *table) ****************************************************************************/ -volatile uint global_read_lock=0; -volatile uint global_read_lock_blocks_commit=0; -static volatile uint protect_against_global_read_lock=0; -static volatile uint waiting_for_read_lock=0; - /** Take global read lock, wait if there is protection against lock. @@ -985,84 +963,17 @@ bool Global_read_lock::lock_global_read_lock(THD *thd) if (!m_state) { MDL_request mdl_request; - const char *old_message; - const char *new_message= "Waiting to get readlock"; - (void) mysql_mutex_lock(&LOCK_global_read_lock); - - old_message= thd->enter_cond(&COND_global_read_lock, - &LOCK_global_read_lock, new_message); - DBUG_PRINT("info", - ("waiting_for: %d protect_against: %d", - waiting_for_read_lock, protect_against_global_read_lock)); - - waiting_for_read_lock++; - -#if defined(ENABLED_DEBUG_SYNC) - /* - The below sync point fires if we have to wait for - protect_against_global_read_lock. - - WARNING: Beware to use WAIT_FOR with this sync point. We hold - LOCK_global_read_lock here. - - The sync point is after enter_cond() so that proc_info is - available immediately after the sync point sends a SIGNAL. This - can make tests more reliable. - - The sync point is before the loop so that it is executed only once. - */ - if (protect_against_global_read_lock && !thd->killed) - { - DEBUG_SYNC(thd, "wait_lock_global_read_lock"); - } -#endif /* defined(ENABLED_DEBUG_SYNC) */ - - while (protect_against_global_read_lock && !thd->killed) - mysql_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock); - waiting_for_read_lock--; - if (thd->killed) - { - thd->exit_cond(old_message); - DBUG_RETURN(1); - } - m_state= GRL_ACQUIRED; - global_read_lock++; - thd->exit_cond(old_message); // this unlocks LOCK_global_read_lock - /* - When we perform FLUSH TABLES or ALTER TABLE under LOCK TABLES, - tables being reopened are protected only by meta-data locks at - some point. To avoid sneaking in with our global read lock at - this moment we have to take global shared meta data lock. - - TODO: We should change this code to acquire global shared metadata - lock before acquiring global read lock. But in order to do - this we have to get rid of all those places in which - wait_if_global_read_lock() is called before acquiring - metadata locks first. Also long-term we should get rid of - redundancy between metadata locks, global read lock and DDL - blocker (see WL#4399 and WL#4400). - */ DBUG_ASSERT(! thd->mdl_context.is_lock_owner(MDL_key::GLOBAL, "", "", MDL_SHARED)); - mdl_request.init(MDL_key::GLOBAL, "", "", MDL_SHARED); + mdl_request.init(MDL_key::GLOBAL, "", "", MDL_SHARED, MDL_EXPLICIT); if (thd->mdl_context.acquire_lock(&mdl_request, thd->variables.lock_wait_timeout)) - { - /* Our thread was killed -- return back to initial state. */ - mysql_mutex_lock(&LOCK_global_read_lock); - if (!(--global_read_lock)) - { - DBUG_PRINT("signal", ("Broadcasting COND_global_read_lock")); - mysql_cond_broadcast(&COND_global_read_lock); - } - mysql_mutex_unlock(&LOCK_global_read_lock); - m_state= GRL_NONE; DBUG_RETURN(1); - } - thd->mdl_context.move_ticket_after_trans_sentinel(mdl_request.ticket); + m_mdl_global_shared_lock= mdl_request.ticket; + m_state= GRL_ACQUIRED; } /* We DON'T set global_read_lock_blocks_commit now, it will be set after @@ -1088,166 +999,22 @@ bool Global_read_lock::lock_global_read_lock(THD *thd) void Global_read_lock::unlock_global_read_lock(THD *thd) { - uint tmp; DBUG_ENTER("unlock_global_read_lock"); - DBUG_PRINT("info", - ("global_read_lock: %u global_read_lock_blocks_commit: %u", - global_read_lock, global_read_lock_blocks_commit)); DBUG_ASSERT(m_mdl_global_shared_lock && m_state); + if (m_mdl_blocks_commits_lock) + { + thd->mdl_context.release_lock(m_mdl_blocks_commits_lock); + m_mdl_blocks_commits_lock= NULL; + } thd->mdl_context.release_lock(m_mdl_global_shared_lock); m_mdl_global_shared_lock= NULL; - - mysql_mutex_lock(&LOCK_global_read_lock); - tmp= --global_read_lock; - if (m_state == GRL_ACQUIRED_AND_BLOCKS_COMMIT) - --global_read_lock_blocks_commit; - mysql_mutex_unlock(&LOCK_global_read_lock); - /* Send the signal outside the mutex to avoid a context switch */ - if (!tmp) - { - DBUG_PRINT("signal", ("Broadcasting COND_global_read_lock")); - mysql_cond_broadcast(&COND_global_read_lock); - } m_state= GRL_NONE; DBUG_VOID_RETURN; } -/** - Wait if the global read lock is set, and optionally seek protection against - global read lock. - - See also "Handling of global read locks" above. - - @param thd Reference to thread. - @param abort_on_refresh If True, abort waiting if a refresh occurs, - do NOT seek protection against GRL. - If False, wait until the GRL is released and seek - protection against GRL. - @param is_not_commit If False, called from a commit operation, - wait only if commit blocking is also enabled. - - @retval False Success, protection against global read lock is set - (if !abort_on_refresh) - @retval True Failure, wait was aborted or thread was killed. -*/ - -#define must_wait (global_read_lock && \ - (is_not_commit || \ - global_read_lock_blocks_commit)) - -bool Global_read_lock:: -wait_if_global_read_lock(THD *thd, bool abort_on_refresh, - bool is_not_commit) -{ - const char *UNINIT_VAR(old_message); - bool result= 0, need_exit_cond; - DBUG_ENTER("wait_if_global_read_lock"); - - /* - If we already have protection against global read lock, - just increment the counter. - */ - if (unlikely(m_protection_count > 0)) - { - if (!abort_on_refresh) - m_protection_count++; - DBUG_RETURN(FALSE); - } - /* - Assert that we do not own LOCK_open. If we would own it, other - threads could not close their tables. This would make a pretty - deadlock. - */ - mysql_mutex_assert_not_owner(&LOCK_open); - - mysql_mutex_lock(&LOCK_global_read_lock); - if ((need_exit_cond= must_wait)) - { - if (m_state) // This thread had the read locks - { - if (is_not_commit) - my_message(ER_CANT_UPDATE_WITH_READLOCK, - ER(ER_CANT_UPDATE_WITH_READLOCK), MYF(0)); - mysql_mutex_unlock(&LOCK_global_read_lock); - /* - We allow FLUSHer to COMMIT; we assume FLUSHer knows what it does. - This allowance is needed to not break existing versions of innobackup - which do a BEGIN; INSERT; FLUSH TABLES WITH READ LOCK; COMMIT. - */ - DBUG_RETURN(is_not_commit); - } - old_message=thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock, - "Waiting for release of readlock"); - while (must_wait && ! thd->killed && - (!abort_on_refresh || !thd->open_tables || - thd->open_tables->s->version == refresh_version)) - { - DBUG_PRINT("signal", ("Waiting for COND_global_read_lock")); - mysql_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock); - DBUG_PRINT("signal", ("Got COND_global_read_lock")); - } - if (thd->killed) - result=1; - } - if (!abort_on_refresh && !result) - { - m_protection_count++; - protect_against_global_read_lock++; - DBUG_PRINT("sql_lock", ("protect_against_global_read_lock incr: %u", - protect_against_global_read_lock)); - } - /* - The following is only true in case of a global read locks (which is rare) - and if old_message is set - */ - if (unlikely(need_exit_cond)) - thd->exit_cond(old_message); // this unlocks LOCK_global_read_lock - else - mysql_mutex_unlock(&LOCK_global_read_lock); - DBUG_RETURN(result); -} - - -/** - Release protection against global read lock and restart - global read lock waiters. - - Should only be called if we have protection against global read lock. - - See also "Handling of global read locks" above. - - @param thd Reference to thread. -*/ - -void Global_read_lock::start_waiting_global_read_lock(THD *thd) -{ - bool tmp; - DBUG_ENTER("start_waiting_global_read_lock"); - /* - Ignore request if we do not have protection against global read lock. - (Note that this is a violation of the interface contract, hence the assert). - */ - DBUG_ASSERT(m_protection_count > 0); - if (unlikely(m_protection_count == 0)) - DBUG_VOID_RETURN; - /* Decrement local read lock protection counter, return if we still have it */ - if (unlikely(--m_protection_count > 0)) - DBUG_VOID_RETURN; - if (unlikely(m_state)) - DBUG_VOID_RETURN; - mysql_mutex_lock(&LOCK_global_read_lock); - DBUG_ASSERT(protect_against_global_read_lock); - tmp= (!--protect_against_global_read_lock && - (waiting_for_read_lock || global_read_lock_blocks_commit)); - mysql_mutex_unlock(&LOCK_global_read_lock); - if (tmp) - mysql_cond_broadcast(&COND_global_read_lock); - DBUG_VOID_RETURN; -} - /** Make global read lock also block commits. @@ -1266,8 +1033,7 @@ void Global_read_lock::start_waiting_global_read_lock(THD *thd) bool Global_read_lock::make_global_read_lock_block_commit(THD *thd) { - bool error; - const char *old_message; + MDL_request mdl_request; DBUG_ENTER("make_global_read_lock_block_commit"); /* If we didn't succeed lock_global_read_lock(), or if we already suceeded @@ -1275,42 +1041,32 @@ bool Global_read_lock::make_global_read_lock_block_commit(THD *thd) */ if (m_state != GRL_ACQUIRED) DBUG_RETURN(0); - mysql_mutex_lock(&LOCK_global_read_lock); - /* increment this BEFORE waiting on cond (otherwise race cond) */ - global_read_lock_blocks_commit++; - /* For testing we set up some blocking, to see if we can be killed */ - DBUG_EXECUTE_IF("make_global_read_lock_block_commit_loop", - protect_against_global_read_lock++;); - old_message= thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock, - "Waiting for all running commits to finish"); - while (protect_against_global_read_lock && !thd->killed) - mysql_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock); - DBUG_EXECUTE_IF("make_global_read_lock_block_commit_loop", - protect_against_global_read_lock--;); - if ((error= test(thd->killed))) - global_read_lock_blocks_commit--; // undo what we did - else - m_state= GRL_ACQUIRED_AND_BLOCKS_COMMIT; - thd->exit_cond(old_message); // this unlocks LOCK_global_read_lock - DBUG_RETURN(error); + + mdl_request.init(MDL_key::COMMIT, "", "", MDL_SHARED, MDL_EXPLICIT); + + if (thd->mdl_context.acquire_lock(&mdl_request, + thd->variables.lock_wait_timeout)) + DBUG_RETURN(TRUE); + + m_mdl_blocks_commits_lock= mdl_request.ticket; + m_state= GRL_ACQUIRED_AND_BLOCKS_COMMIT; + + DBUG_RETURN(FALSE); } /** - Broadcast COND_global_read_lock. + Set explicit duration for metadata locks which are used to implement GRL. - TODO/FIXME: Dmitry thinks that we broadcast on COND_global_read_lock - when old instance of table is closed to avoid races - between incrementing refresh_version and - wait_if_global_read_lock(thd, TRUE, FALSE) call. - Once global read lock implementation starts using MDL - infrastructure this will became unnecessary and should - be removed. + @param thd Reference to thread. */ -void broadcast_refresh(void) +void Global_read_lock::set_explicit_lock_duration(THD *thd) { - mysql_cond_broadcast(&COND_global_read_lock); + if (m_mdl_global_shared_lock) + thd->mdl_context.set_lock_duration(m_mdl_global_shared_lock, MDL_EXPLICIT); + if (m_mdl_blocks_commits_lock) + thd->mdl_context.set_lock_duration(m_mdl_blocks_commits_lock, MDL_EXPLICIT); } /** diff --git a/sql/lock.h b/sql/lock.h index c097c8d269e..6f779595af8 100644 --- a/sql/lock.h +++ b/sql/lock.h @@ -2,6 +2,7 @@ #define LOCK_INCLUDED #include "thr_lock.h" /* thr_lock_type */ +#include "mdl.h" // Forward declarations struct TABLE; @@ -18,11 +19,10 @@ void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table); void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock); bool mysql_lock_abort_for_thread(THD *thd, TABLE *table); MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b); -void broadcast_refresh(void); /* Lock based on name */ bool lock_schema_name(THD *thd, const char *db); /* Lock based on stored routine name */ -bool lock_routine_name(THD *thd, bool is_function, const char *db, - const char *name); +bool lock_object_name(THD *thd, MDL_key::enum_mdl_namespace mdl_type, + const char *db, const char *name); #endif /* LOCK_INCLUDED */ diff --git a/sql/log_event.cc b/sql/log_event.cc index b4641af07c5..2feb69493a8 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -4961,6 +4961,8 @@ error: */ if (! thd->in_multi_stmt_transaction_mode()) thd->mdl_context.release_transactional_locks(); + else + thd->mdl_context.release_statement_locks(); DBUG_EXECUTE_IF("LOAD_DATA_INFILE_has_fatal_error", thd->is_slave_error= 0; thd->is_fatal_error= 1;); diff --git a/sql/mdl.cc b/sql/mdl.cc index d53ddcee0c8..3aed54ce12d 100644 --- a/sql/mdl.cc +++ b/sql/mdl.cc @@ -68,8 +68,6 @@ static void init_mdl_psi_keys(void) } #endif /* HAVE_PSI_INTERFACE */ -void notify_shared_lock(THD *thd, MDL_ticket *conflicting_ticket); - /** Thread state names to be used in case when we have to wait on resource @@ -78,12 +76,14 @@ void notify_shared_lock(THD *thd, MDL_ticket *conflicting_ticket); const char *MDL_key::m_namespace_to_wait_state_name[NAMESPACE_END]= { - "Waiting for global metadata lock", + "Waiting for global read lock", "Waiting for schema metadata lock", "Waiting for table metadata lock", "Waiting for stored function metadata lock", "Waiting for stored procedure metadata lock", - NULL + "Waiting for trigger metadata lock", + "Waiting for event metadata lock", + "Waiting for commit lock" }; static bool mdl_initialized= 0; @@ -100,7 +100,6 @@ class MDL_map public: void init(); void destroy(); - MDL_lock *find(const MDL_key *key); MDL_lock *find_or_insert(const MDL_key *key); void remove(MDL_lock *lock); private: @@ -110,6 +109,10 @@ private: HASH m_locks; /* Protects access to m_locks hash. */ mysql_mutex_t m_mutex; + /** Pre-allocated MDL_lock object for GLOBAL namespace. */ + MDL_lock *m_global_lock; + /** Pre-allocated MDL_lock object for COMMIT namespace. */ + MDL_lock *m_commit_lock; }; @@ -354,18 +357,6 @@ public: inline static MDL_lock *create(const MDL_key *key); - void notify_shared_locks(MDL_context *ctx) - { - Ticket_iterator it(m_granted); - MDL_ticket *conflicting_ticket; - - while ((conflicting_ticket= it++)) - { - if (conflicting_ticket->get_ctx() != ctx) - notify_shared_lock(ctx->get_thd(), conflicting_ticket); - } - } - void reschedule_waiters(); void remove_ticket(Ticket_list MDL_lock::*queue, MDL_ticket *ticket); @@ -373,6 +364,9 @@ public: bool visit_subgraph(MDL_ticket *waiting_ticket, MDL_wait_for_graph_visitor *gvisitor); + virtual bool needs_notification(const MDL_ticket *ticket) const = 0; + virtual void notify_conflicting_locks(MDL_context *ctx) = 0; + /** List of granted tickets for this lock. */ Ticket_list m_granted; /** Tickets for contexts waiting to acquire a lock. */ @@ -442,6 +436,11 @@ public: { return m_waiting_incompatible; } + virtual bool needs_notification(const MDL_ticket *ticket) const + { + return (ticket->get_type() == MDL_SHARED); + } + virtual void notify_conflicting_locks(MDL_context *ctx); private: static const bitmap_t m_granted_incompatible[MDL_TYPE_END]; @@ -469,6 +468,11 @@ public: { return m_waiting_incompatible; } + virtual bool needs_notification(const MDL_ticket *ticket) const + { + return ticket->is_upgradable_or_exclusive(); + } + virtual void notify_conflicting_locks(MDL_context *ctx); private: static const bitmap_t m_granted_incompatible[MDL_TYPE_END]; @@ -536,9 +540,14 @@ void mdl_destroy() void MDL_map::init() { + MDL_key global_lock_key(MDL_key::GLOBAL, "", ""); + MDL_key commit_lock_key(MDL_key::COMMIT, "", ""); + mysql_mutex_init(key_MDL_map_mutex, &m_mutex, NULL); my_hash_init(&m_locks, &my_charset_bin, 16 /* FIXME */, 0, 0, mdl_locks_key, 0, 0); + m_global_lock= MDL_lock::create(&global_lock_key); + m_commit_lock= MDL_lock::create(&commit_lock_key); } @@ -552,6 +561,8 @@ void MDL_map::destroy() DBUG_ASSERT(!m_locks.records); mysql_mutex_destroy(&m_mutex); my_hash_free(&m_locks); + MDL_lock::destroy(m_global_lock); + MDL_lock::destroy(m_commit_lock); } @@ -569,6 +580,29 @@ MDL_lock* MDL_map::find_or_insert(const MDL_key *mdl_key) MDL_lock *lock; my_hash_value_type hash_value; + if (mdl_key->mdl_namespace() == MDL_key::GLOBAL || + mdl_key->mdl_namespace() == MDL_key::COMMIT) + { + /* + Avoid locking m_mutex when lock for GLOBAL or COMMIT namespace is + requested. Return pointer to pre-allocated MDL_lock instance instead. + Such an optimization allows to save one mutex lock/unlock for any + statement changing data. + + It works since these namespaces contain only one element so keys + for them look like '\0\0'. + */ + DBUG_ASSERT(mdl_key->length() == 3); + + lock= (mdl_key->mdl_namespace() == MDL_key::GLOBAL) ? m_global_lock : + m_commit_lock; + + mysql_prlock_wrlock(&lock->m_rwlock); + + return lock; + } + + hash_value= my_calc_hash(&m_locks, mdl_key->ptr(), mdl_key->length()); retry: @@ -594,39 +628,6 @@ retry: } -/** - Find MDL_lock object corresponding to the key. - - @retval non-NULL - MDL_lock instance for the key with locked - MDL_lock::m_rwlock. - @retval NULL - There was no MDL_lock for the key. -*/ - -MDL_lock* MDL_map::find(const MDL_key *mdl_key) -{ - MDL_lock *lock; - my_hash_value_type hash_value; - - hash_value= my_calc_hash(&m_locks, mdl_key->ptr(), mdl_key->length()); - -retry: - mysql_mutex_lock(&m_mutex); - if (!(lock= (MDL_lock*) my_hash_search_using_hash_value(&m_locks, - hash_value, - mdl_key->ptr(), - mdl_key->length()))) - { - mysql_mutex_unlock(&m_mutex); - return NULL; - } - - if (move_from_hash_to_lock_mutex(lock)) - goto retry; - - return lock; -} - - /** Release mdl_locks.m_mutex mutex and lock MDL_lock::m_rwlock for lock object from the hash. Handle situation when object was released @@ -684,6 +685,17 @@ void MDL_map::remove(MDL_lock *lock) { uint ref_usage, ref_release; + if (lock->key.mdl_namespace() == MDL_key::GLOBAL || + lock->key.mdl_namespace() == MDL_key::COMMIT) + { + /* + Never destroy pre-allocated MDL_lock objects for GLOBAL and + COMMIT namespaces. + */ + mysql_prlock_unlock(&lock->m_rwlock); + return; + } + /* Destroy the MDL_lock object, but ensure that anyone that is holding a reference to the object is not remaining, if so he @@ -719,8 +731,7 @@ void MDL_map::remove(MDL_lock *lock) */ MDL_context::MDL_context() - :m_trans_sentinel(NULL), - m_thd(NULL), + : m_thd(NULL), m_needs_thr_lock_abort(FALSE), m_waiting_for(NULL) { @@ -742,7 +753,9 @@ MDL_context::MDL_context() void MDL_context::destroy() { - DBUG_ASSERT(m_tickets.is_empty()); + DBUG_ASSERT(m_tickets[MDL_STATEMENT].is_empty() && + m_tickets[MDL_TRANSACTION].is_empty() && + m_tickets[MDL_EXPLICIT].is_empty()); mysql_prlock_destroy(&m_LOCK_waiting_for); } @@ -771,10 +784,12 @@ void MDL_context::destroy() void MDL_request::init(MDL_key::enum_mdl_namespace mdl_namespace, const char *db_arg, const char *name_arg, - enum enum_mdl_type mdl_type_arg) + enum_mdl_type mdl_type_arg, + enum_mdl_duration mdl_duration_arg) { key.mdl_key_init(mdl_namespace, db_arg, name_arg); type= mdl_type_arg; + duration= mdl_duration_arg; ticket= NULL; } @@ -789,48 +804,16 @@ void MDL_request::init(MDL_key::enum_mdl_namespace mdl_namespace, */ void MDL_request::init(const MDL_key *key_arg, - enum enum_mdl_type mdl_type_arg) + enum_mdl_type mdl_type_arg, + enum_mdl_duration mdl_duration_arg) { key.mdl_key_init(key_arg); type= mdl_type_arg; + duration= mdl_duration_arg; ticket= NULL; } -/** - Allocate and initialize one lock request. - - Same as mdl_init_lock(), but allocates the lock and the key buffer - on a memory root. Necessary to lock ad-hoc tables, e.g. - mysql.* tables of grant and data dictionary subsystems. - - @param mdl_namespace Id of namespace of object to be locked - @param db Name of database to which object belongs - @param name Name of of object - @param root MEM_ROOT on which object should be allocated - - @note The allocated lock request will have MDL_SHARED type. - - @retval 0 Error if out of memory - @retval non-0 Pointer to an object representing a lock request -*/ - -MDL_request * -MDL_request::create(MDL_key::enum_mdl_namespace mdl_namespace, const char *db, - const char *name, enum_mdl_type mdl_type, - MEM_ROOT *root) -{ - MDL_request *mdl_request; - - if (!(mdl_request= (MDL_request*) alloc_root(root, sizeof(MDL_request)))) - return NULL; - - mdl_request->init(mdl_namespace, db, name, mdl_type); - - return mdl_request; -} - - /** Auxiliary functions needed for creation/destruction of MDL_lock objects. @@ -846,6 +829,7 @@ inline MDL_lock *MDL_lock::create(const MDL_key *mdl_key) { case MDL_key::GLOBAL: case MDL_key::SCHEMA: + case MDL_key::COMMIT: return new MDL_scoped_lock(mdl_key); default: return new MDL_object_lock(mdl_key); @@ -867,9 +851,17 @@ void MDL_lock::destroy(MDL_lock *lock) on memory allocation by reusing released objects. */ -MDL_ticket *MDL_ticket::create(MDL_context *ctx_arg, enum_mdl_type type_arg) +MDL_ticket *MDL_ticket::create(MDL_context *ctx_arg, enum_mdl_type type_arg +#ifndef DBUG_OFF + , enum_mdl_duration duration_arg +#endif + ) { - return new MDL_ticket(ctx_arg, type_arg); + return new MDL_ticket(ctx_arg, type_arg +#ifndef DBUG_OFF + , duration_arg +#endif + ); } @@ -1438,13 +1430,11 @@ bool MDL_ticket::is_incompatible_when_waiting(enum_mdl_type type) const /** Check whether the context already holds a compatible lock ticket on an object. - Start searching the transactional locks. If not - found in the list of transactional locks, look at LOCK TABLES - and HANDLER locks. + Start searching from list of locks for the same duration as lock + being requested. If not look at lists for other durations. @param mdl_request Lock request object for lock to be acquired - @param[out] is_transactional FALSE if we pass beyond m_trans_sentinel - while searching for ticket, otherwise TRUE. + @param[out] result_duration Duration of lock which was found. @note Tickets which correspond to lock types "stronger" than one being requested are also considered compatible. @@ -1454,24 +1444,28 @@ bool MDL_ticket::is_incompatible_when_waiting(enum_mdl_type type) const MDL_ticket * MDL_context::find_ticket(MDL_request *mdl_request, - bool *is_transactional) + enum_mdl_duration *result_duration) { MDL_ticket *ticket; - Ticket_iterator it(m_tickets); + int i; - *is_transactional= TRUE; - - while ((ticket= it++)) + for (i= 0; i < MDL_DURATION_END; i++) { - if (ticket == m_trans_sentinel) - *is_transactional= FALSE; + enum_mdl_duration duration= (enum_mdl_duration)((mdl_request->duration+i) % + MDL_DURATION_END); + Ticket_iterator it(m_tickets[duration]); - if (mdl_request->key.is_equal(&ticket->m_lock->key) && - ticket->has_stronger_or_equal_type(mdl_request->type)) - break; + while ((ticket= it++)) + { + if (mdl_request->key.is_equal(&ticket->m_lock->key) && + ticket->has_stronger_or_equal_type(mdl_request->type)) + { + *result_duration= duration; + return ticket; + } + } } - - return ticket; + return NULL; } @@ -1549,7 +1543,7 @@ MDL_context::try_acquire_lock_impl(MDL_request *mdl_request, MDL_lock *lock; MDL_key *key= &mdl_request->key; MDL_ticket *ticket; - bool is_transactional; + enum_mdl_duration found_duration; DBUG_ASSERT(mdl_request->type != MDL_EXCLUSIVE || is_lock_owner(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE)); @@ -1563,7 +1557,7 @@ MDL_context::try_acquire_lock_impl(MDL_request *mdl_request, Check whether the context already holds a shared lock on the object, and if so, grant the request. */ - if ((ticket= find_ticket(mdl_request, &is_transactional))) + if ((ticket= find_ticket(mdl_request, &found_duration))) { DBUG_ASSERT(ticket->m_lock); DBUG_ASSERT(ticket->has_stronger_or_equal_type(mdl_request->type)); @@ -1585,7 +1579,9 @@ MDL_context::try_acquire_lock_impl(MDL_request *mdl_request, a different alias. */ mdl_request->ticket= ticket; - if (!is_transactional && clone_ticket(mdl_request)) + if ((found_duration != mdl_request->duration || + mdl_request->duration == MDL_EXPLICIT) && + clone_ticket(mdl_request)) { /* Clone failed. */ mdl_request->ticket= NULL; @@ -1594,7 +1590,11 @@ MDL_context::try_acquire_lock_impl(MDL_request *mdl_request, return FALSE; } - if (!(ticket= MDL_ticket::create(this, mdl_request->type))) + if (!(ticket= MDL_ticket::create(this, mdl_request->type +#ifndef DBUG_OFF + , mdl_request->duration +#endif + ))) return TRUE; /* The below call implicitly locks MDL_lock::m_rwlock on success. */ @@ -1612,7 +1612,7 @@ MDL_context::try_acquire_lock_impl(MDL_request *mdl_request, mysql_prlock_unlock(&lock->m_rwlock); - m_tickets.push_front(ticket); + m_tickets[mdl_request->duration].push_front(ticket); mdl_request->ticket= ticket; } @@ -1647,7 +1647,11 @@ MDL_context::clone_ticket(MDL_request *mdl_request) we effectively downgrade the cloned lock to the level of the request. */ - if (!(ticket= MDL_ticket::create(this, mdl_request->type))) + if (!(ticket= MDL_ticket::create(this, mdl_request->type +#ifndef DBUG_OFF + , mdl_request->duration +#endif + ))) return TRUE; /* clone() is not supposed to be used to get a stronger lock. */ @@ -1660,36 +1664,74 @@ MDL_context::clone_ticket(MDL_request *mdl_request) ticket->m_lock->m_granted.add_ticket(ticket); mysql_prlock_unlock(&ticket->m_lock->m_rwlock); - m_tickets.push_front(ticket); + m_tickets[mdl_request->duration].push_front(ticket); return FALSE; } /** - Notify a thread holding a shared metadata lock which - conflicts with a pending exclusive lock. + Notify threads holding a shared metadata locks on object which + conflict with a pending X, SNW or SNRW lock. - @param thd Current thread context - @param conflicting_ticket Conflicting metadata lock + @param ctx MDL_context for current thread. */ -void notify_shared_lock(THD *thd, MDL_ticket *conflicting_ticket) +void MDL_object_lock::notify_conflicting_locks(MDL_context *ctx) { - /* Only try to abort locks on which we back off. */ - if (conflicting_ticket->get_type() < MDL_SHARED_NO_WRITE) - { - MDL_context *conflicting_ctx= conflicting_ticket->get_ctx(); - THD *conflicting_thd= conflicting_ctx->get_thd(); - DBUG_ASSERT(thd != conflicting_thd); /* Self-deadlock */ + Ticket_iterator it(m_granted); + MDL_ticket *conflicting_ticket; - /* - If thread which holds conflicting lock is waiting on table-level - lock or some other non-MDL resource we might need to wake it up - by calling code outside of MDL. - */ - mysql_notify_thread_having_shared_lock(thd, conflicting_thd, - conflicting_ctx->get_needs_thr_lock_abort()); + while ((conflicting_ticket= it++)) + { + /* Only try to abort locks on which we back off. */ + if (conflicting_ticket->get_ctx() != ctx && + conflicting_ticket->get_type() < MDL_SHARED_NO_WRITE) + + { + MDL_context *conflicting_ctx= conflicting_ticket->get_ctx(); + + /* + If thread which holds conflicting lock is waiting on table-level + lock or some other non-MDL resource we might need to wake it up + by calling code outside of MDL. + */ + mysql_notify_thread_having_shared_lock(ctx->get_thd(), + conflicting_ctx->get_thd(), + conflicting_ctx->get_needs_thr_lock_abort()); + } + } +} + + +/** + Notify threads holding scoped IX locks which conflict with a pending S lock. + + @param ctx MDL_context for current thread. +*/ + +void MDL_scoped_lock::notify_conflicting_locks(MDL_context *ctx) +{ + Ticket_iterator it(m_granted); + MDL_ticket *conflicting_ticket; + + while ((conflicting_ticket= it++)) + { + if (conflicting_ticket->get_ctx() != ctx && + conflicting_ticket->get_type() == MDL_INTENTION_EXCLUSIVE) + + { + MDL_context *conflicting_ctx= conflicting_ticket->get_ctx(); + + /* + Thread which holds global IX lock can be a handler thread for + insert delayed. We need to kill such threads in order to get + global shared lock. We do this my calling code outside of MDL. + */ + mysql_notify_thread_having_shared_lock(ctx->get_thd(), + conflicting_ctx->get_thd(), + conflicting_ctx->get_needs_thr_lock_abort()); + } } } @@ -1747,8 +1789,8 @@ MDL_context::acquire_lock(MDL_request *mdl_request, ulong lock_wait_timeout) */ m_wait.reset_status(); - if (ticket->is_upgradable_or_exclusive()) - lock->notify_shared_locks(this); + if (lock->needs_notification(ticket)) + lock->notify_conflicting_locks(this); mysql_prlock_unlock(&lock->m_rwlock); @@ -1759,7 +1801,7 @@ MDL_context::acquire_lock(MDL_request *mdl_request, ulong lock_wait_timeout) find_deadlock(); - if (ticket->is_upgradable_or_exclusive()) + if (lock->needs_notification(ticket)) { struct timespec abs_shortwait; set_timespec(abs_shortwait, 1); @@ -1775,7 +1817,7 @@ MDL_context::acquire_lock(MDL_request *mdl_request, ulong lock_wait_timeout) break; mysql_prlock_wrlock(&lock->m_rwlock); - lock->notify_shared_locks(this); + lock->notify_conflicting_locks(this); mysql_prlock_unlock(&lock->m_rwlock); set_timespec(abs_shortwait, 1); } @@ -1818,7 +1860,7 @@ MDL_context::acquire_lock(MDL_request *mdl_request, ulong lock_wait_timeout) */ DBUG_ASSERT(wait_status == MDL_wait::GRANTED); - m_tickets.push_front(ticket); + m_tickets[mdl_request->duration].push_front(ticket); mdl_request->ticket= ticket; @@ -1859,7 +1901,7 @@ bool MDL_context::acquire_locks(MDL_request_list *mdl_requests, { MDL_request_list::Iterator it(*mdl_requests); MDL_request **sort_buf, **p_req; - MDL_ticket *mdl_svp= mdl_savepoint(); + MDL_savepoint mdl_svp= mdl_savepoint(); ssize_t req_count= static_cast(mdl_requests->elements()); if (req_count == 0) @@ -1928,7 +1970,7 @@ MDL_context::upgrade_shared_lock_to_exclusive(MDL_ticket *mdl_ticket, ulong lock_wait_timeout) { MDL_request mdl_xlock_request; - MDL_ticket *mdl_svp= mdl_savepoint(); + MDL_savepoint mdl_svp= mdl_savepoint(); bool is_new_ticket; DBUG_ENTER("MDL_ticket::upgrade_shared_lock_to_exclusive"); @@ -1945,7 +1987,8 @@ MDL_context::upgrade_shared_lock_to_exclusive(MDL_ticket *mdl_ticket, DBUG_ASSERT(mdl_ticket->m_type == MDL_SHARED_NO_WRITE || mdl_ticket->m_type == MDL_SHARED_NO_READ_WRITE); - mdl_xlock_request.init(&mdl_ticket->m_lock->key, MDL_EXCLUSIVE); + mdl_xlock_request.init(&mdl_ticket->m_lock->key, MDL_EXCLUSIVE, + MDL_TRANSACTION); if (acquire_lock(&mdl_xlock_request, lock_wait_timeout)) DBUG_RETURN(TRUE); @@ -1969,7 +2012,7 @@ MDL_context::upgrade_shared_lock_to_exclusive(MDL_ticket *mdl_ticket, if (is_new_ticket) { - m_tickets.remove(mdl_xlock_request.ticket); + m_tickets[MDL_TRANSACTION].remove(mdl_xlock_request.ticket); MDL_ticket::destroy(mdl_xlock_request.ticket); } @@ -2230,10 +2273,12 @@ void MDL_context::find_deadlock() /** Release lock. - @param ticket Ticket for lock to be released. + @param duration Lock duration. + @param ticket Ticket for lock to be released. + */ -void MDL_context::release_lock(MDL_ticket *ticket) +void MDL_context::release_lock(enum_mdl_duration duration, MDL_ticket *ticket) { MDL_lock *lock= ticket->m_lock; DBUG_ENTER("MDL_context::release_lock"); @@ -2243,63 +2288,66 @@ void MDL_context::release_lock(MDL_ticket *ticket) DBUG_ASSERT(this == ticket->get_ctx()); mysql_mutex_assert_not_owner(&LOCK_open); - if (ticket == m_trans_sentinel) - m_trans_sentinel= ++Ticket_list::Iterator(m_tickets, ticket); - lock->remove_ticket(&MDL_lock::m_granted, ticket); - m_tickets.remove(ticket); + m_tickets[duration].remove(ticket); MDL_ticket::destroy(ticket); DBUG_VOID_RETURN; } +/** + Release lock with explicit duration. + + @param ticket Ticket for lock to be released. + +*/ + +void MDL_context::release_lock(MDL_ticket *ticket) +{ + DBUG_ASSERT(ticket->m_duration == MDL_EXPLICIT); + + release_lock(MDL_EXPLICIT, ticket); +} + + /** Release all locks associated with the context. If the sentinel is not NULL, do not release locks stored in the list after and including the sentinel. - Transactional locks are added to the beginning of the list, i.e. - stored in reverse temporal order. This allows to employ this - function to: + Statement and transactional locks are added to the beginning of + the corresponding lists, i.e. stored in reverse temporal order. + This allows to employ this function to: - back off in case of a lock conflict. - - release all locks in the end of a transaction + - release all locks in the end of a statment or transaction - rollback to a savepoint. - - The sentinel semantics is used to support LOCK TABLES - mode and HANDLER statements: locks taken by these statements - survive COMMIT, ROLLBACK, ROLLBACK TO SAVEPOINT. */ -void MDL_context::release_locks_stored_before(MDL_ticket *sentinel) +void MDL_context::release_locks_stored_before(enum_mdl_duration duration, + MDL_ticket *sentinel) { MDL_ticket *ticket; - Ticket_iterator it(m_tickets); + Ticket_iterator it(m_tickets[duration]); DBUG_ENTER("MDL_context::release_locks_stored_before"); - if (m_tickets.is_empty()) + if (m_tickets[duration].is_empty()) DBUG_VOID_RETURN; while ((ticket= it++) && ticket != sentinel) { DBUG_PRINT("info", ("found lock to release ticket=%p", ticket)); - release_lock(ticket); + release_lock(duration, ticket); } - /* - If all locks were released, then the sentinel was not present - in the list. It must never happen because the sentinel was - bogus, i.e. pointed to a ticket that no longer exists. - */ - DBUG_ASSERT(! m_tickets.is_empty() || sentinel == NULL); DBUG_VOID_RETURN; } /** - Release all locks in the context which correspond to the same name/ - object as this lock request. + Release all explicit locks in the context which correspond to the + same name/object as this lock request. @param ticket One of the locks for the name/object for which all locks should be released. @@ -2312,17 +2360,13 @@ void MDL_context::release_all_locks_for_name(MDL_ticket *name) /* Remove matching lock tickets from the context. */ MDL_ticket *ticket; - Ticket_iterator it_ticket(m_tickets); + Ticket_iterator it_ticket(m_tickets[MDL_EXPLICIT]); while ((ticket= it_ticket++)) { DBUG_ASSERT(ticket->m_lock); - /* - We rarely have more than one ticket in this loop, - let's not bother saving on pthread_cond_broadcast(). - */ if (ticket->m_lock == lock) - release_lock(ticket); + release_lock(MDL_EXPLICIT, ticket); } } @@ -2377,9 +2421,10 @@ MDL_context::is_lock_owner(MDL_key::enum_mdl_namespace mdl_namespace, enum_mdl_type mdl_type) { MDL_request mdl_request; - bool is_transactional_unused; - mdl_request.init(mdl_namespace, db, name, mdl_type); - MDL_ticket *ticket= find_ticket(&mdl_request, &is_transactional_unused); + enum_mdl_duration not_unused; + /* We don't care about exact duration of lock here. */ + mdl_request.init(mdl_namespace, db, name, mdl_type, MDL_TRANSACTION); + MDL_ticket *ticket= find_ticket(&mdl_request, ¬_unused); DBUG_ASSERT(ticket == NULL || ticket->m_lock); @@ -2408,18 +2453,15 @@ bool MDL_ticket::has_pending_conflicting_lock() const @note It's safe to iterate and unlock any locks after taken after this savepoint because other statements that take other special locks cause a implicit commit (ie LOCK TABLES). - - @param mdl_savepont The last acquired MDL lock when the - savepoint was set. */ -void MDL_context::rollback_to_savepoint(MDL_ticket *mdl_savepoint) +void MDL_context::rollback_to_savepoint(const MDL_savepoint &mdl_savepoint) { DBUG_ENTER("MDL_context::rollback_to_savepoint"); /* If savepoint is NULL, it is from the start of the transaction. */ - release_locks_stored_before(mdl_savepoint ? - mdl_savepoint : m_trans_sentinel); + release_locks_stored_before(MDL_STATEMENT, mdl_savepoint.m_stmt_ticket); + release_locks_stored_before(MDL_TRANSACTION, mdl_savepoint.m_trans_ticket); DBUG_VOID_RETURN; } @@ -2437,65 +2479,150 @@ void MDL_context::rollback_to_savepoint(MDL_ticket *mdl_savepoint) void MDL_context::release_transactional_locks() { DBUG_ENTER("MDL_context::release_transactional_locks"); - release_locks_stored_before(m_trans_sentinel); + release_locks_stored_before(MDL_STATEMENT, NULL); + release_locks_stored_before(MDL_TRANSACTION, NULL); + DBUG_VOID_RETURN; +} + + +void MDL_context::release_statement_locks() +{ + DBUG_ENTER("MDL_context::release_transactional_locks"); + release_locks_stored_before(MDL_STATEMENT, NULL); DBUG_VOID_RETURN; } /** Does this savepoint have this lock? - - @retval TRUE The ticket is older than the savepoint and - is not LT, HA or GLR ticket. Thus it belongs - to the savepoint. - @retval FALSE The ticket is newer than the savepoint - or is an LT, HA or GLR ticket. + + @retval TRUE The ticket is older than the savepoint or + is an LT, HA or GLR ticket. Thus it belongs + to the savepoint or has explicit duration. + @retval FALSE The ticket is newer than the savepoint. + and is not an LT, HA or GLR ticket. */ -bool MDL_context::has_lock(MDL_ticket *mdl_savepoint, +bool MDL_context::has_lock(const MDL_savepoint &mdl_savepoint, MDL_ticket *mdl_ticket) { MDL_ticket *ticket; /* Start from the beginning, most likely mdl_ticket's been just acquired. */ - MDL_context::Ticket_iterator it(m_tickets); - bool found_savepoint= FALSE; + MDL_context::Ticket_iterator s_it(m_tickets[MDL_STATEMENT]); + MDL_context::Ticket_iterator t_it(m_tickets[MDL_TRANSACTION]); - while ((ticket= it++) && ticket != m_trans_sentinel) + while ((ticket= s_it++) && ticket != mdl_savepoint.m_stmt_ticket) { - /* - First met the savepoint. The ticket must be - somewhere after it. - */ - if (ticket == mdl_savepoint) - found_savepoint= TRUE; - /* - Met the ticket. If we haven't yet met the savepoint, - the ticket is newer than the savepoint. - */ if (ticket == mdl_ticket) - return found_savepoint; + return FALSE; } - /* Reached m_trans_sentinel. The ticket must be LT, HA or GRL ticket. */ - return FALSE; + + while ((ticket= t_it++) && ticket != mdl_savepoint.m_trans_ticket) + { + if (ticket == mdl_ticket) + return FALSE; + } + return TRUE; } /** - Rearrange the ticket to reside in the part of the list that's - beyond m_trans_sentinel. This effectively changes the ticket - life cycle, from automatic to manual: i.e. the ticket is no - longer released by MDL_context::release_transactional_locks() or - MDL_context::rollback_to_savepoint(), it must be released manually. + Change lock duration for transactional lock. + + @param ticket Ticket representing lock. + @param duration Lock duration to be set. + + @note This method only supports changing duration of + transactional lock to some other duration. */ -void MDL_context::move_ticket_after_trans_sentinel(MDL_ticket *mdl_ticket) +void MDL_context::set_lock_duration(MDL_ticket *mdl_ticket, + enum_mdl_duration duration) { - m_tickets.remove(mdl_ticket); - if (m_trans_sentinel == NULL) - { - m_trans_sentinel= mdl_ticket; - m_tickets.push_back(mdl_ticket); - } - else - m_tickets.insert_after(m_trans_sentinel, mdl_ticket); + DBUG_ASSERT(mdl_ticket->m_duration == MDL_TRANSACTION && + duration != MDL_TRANSACTION); + + m_tickets[MDL_TRANSACTION].remove(mdl_ticket); + m_tickets[duration].push_front(mdl_ticket); +#ifndef DBUG_OFF + mdl_ticket->m_duration= duration; +#endif +} + + +/** + Set explicit duration for all locks in the context. +*/ + +void MDL_context::set_explicit_duration_for_all_locks() +{ + int i; + MDL_ticket *ticket; + + /* + In the most common case when this function is called list + of transactional locks is bigger than list of locks with + explicit duration. So we start by swapping these two lists + and then move elements from new list of transactional + locks and list of statement locks to list of locks with + explicit duration. + */ + + m_tickets[MDL_EXPLICIT].swap(m_tickets[MDL_TRANSACTION]); + + for (i= 0; i < MDL_EXPLICIT; i++) + { + Ticket_iterator it_ticket(m_tickets[i]); + + while ((ticket= it_ticket++)) + { + m_tickets[i].remove(ticket); + m_tickets[MDL_EXPLICIT].push_front(ticket); + } + } + +#ifndef DBUG_OFF + Ticket_iterator exp_it(m_tickets[MDL_EXPLICIT]); + + while ((ticket= exp_it++)) + ticket->m_duration= MDL_EXPLICIT; +#endif +} + + +/** + Set transactional duration for all locks in the context. +*/ + +void MDL_context::set_transaction_duration_for_all_locks() +{ + MDL_ticket *ticket; + + /* + In the most common case when this function is called list + of explicit locks is bigger than two other lists (in fact, + list of statement locks is always empty). So we start by + swapping list of explicit and transactional locks and then + move contents of new list of explicit locks to list of + locks with transactional duration. + */ + + DBUG_ASSERT(m_tickets[MDL_STATEMENT].is_empty()); + + m_tickets[MDL_TRANSACTION].swap(m_tickets[MDL_EXPLICIT]); + + Ticket_iterator it_ticket(m_tickets[MDL_EXPLICIT]); + + while ((ticket= it_ticket++)) + { + m_tickets[MDL_EXPLICIT].remove(ticket); + m_tickets[MDL_TRANSACTION].push_front(ticket); + } + +#ifndef DBUG_OFF + Ticket_iterator trans_it(m_tickets[MDL_TRANSACTION]); + + while ((ticket= trans_it++)) + ticket->m_duration= MDL_TRANSACTION; +#endif } diff --git a/sql/mdl.h b/sql/mdl.h index 7938d833eac..ff30746e739 100644 --- a/sql/mdl.h +++ b/sql/mdl.h @@ -150,6 +150,15 @@ enum enum_mdl_type { MDL_TYPE_END}; +/** Duration of metadata lock. */ + +enum enum_mdl_duration { MDL_STATEMENT= 0, + MDL_TRANSACTION, + MDL_EXPLICIT, + /* This should be the last ! */ + MDL_DURATION_END }; + + /** Maximal length of key for metadata locking subsystem. */ #define MAX_MDLKEY_LENGTH (1 + NAME_LEN + 1 + NAME_LEN + 1) @@ -167,13 +176,16 @@ class MDL_key { public: /** - Object namespaces + Object namespaces. + Sic: when adding a new member to this enum make sure to + update m_namespace_to_wait_state_name array in mdl.cc! Different types of objects exist in different namespaces - TABLE is for tables and views. - FUNCTION is for stored functions. - PROCEDURE is for stored procedures. - TRIGGER is for triggers. + - EVENT is for event scheduler events Note that although there isn't metadata locking on triggers, it's necessary to have a separate namespace for them since MDL_key is also used outside of the MDL subsystem. @@ -184,6 +196,8 @@ public: FUNCTION, PROCEDURE, TRIGGER, + EVENT, + COMMIT, /* This should be the last ! */ NAMESPACE_END }; @@ -305,6 +319,8 @@ class MDL_request public: /** Type of metadata lock. */ enum enum_mdl_type type; + /** Duration for requested lock. */ + enum enum_mdl_duration duration; /** Pointers for participating in the list of lock requests for this context. @@ -327,17 +343,16 @@ public: void init(MDL_key::enum_mdl_namespace namespace_arg, const char *db_arg, const char *name_arg, - enum_mdl_type mdl_type_arg); - void init(const MDL_key *key_arg, enum_mdl_type mdl_type_arg); + enum_mdl_type mdl_type_arg, + enum_mdl_duration mdl_duration_arg); + void init(const MDL_key *key_arg, enum_mdl_type mdl_type_arg, + enum_mdl_duration mdl_duration_arg); /** Set type of lock request. Can be only applied to pending locks. */ inline void set_type(enum_mdl_type type_arg) { DBUG_ASSERT(ticket == NULL); type= type_arg; } - static MDL_request *create(MDL_key::enum_mdl_namespace mdl_namespace, - const char *db, const char *name, - enum_mdl_type mdl_type, MEM_ROOT *root); /* This is to work around the ugliness of TABLE_LIST @@ -363,6 +378,7 @@ public: MDL_request(const MDL_request *rhs) :type(rhs->type), + duration(rhs->duration), ticket(NULL), key(&rhs->key) {} @@ -484,17 +500,35 @@ public: private: friend class MDL_context; - MDL_ticket(MDL_context *ctx_arg, enum_mdl_type type_arg) + MDL_ticket(MDL_context *ctx_arg, enum_mdl_type type_arg +#ifndef DBUG_OFF + , enum_mdl_duration duration_arg +#endif + ) : m_type(type_arg), +#ifndef DBUG_OFF + m_duration(duration_arg), +#endif m_ctx(ctx_arg), m_lock(NULL) {} - static MDL_ticket *create(MDL_context *ctx_arg, enum_mdl_type type_arg); + static MDL_ticket *create(MDL_context *ctx_arg, enum_mdl_type type_arg +#ifndef DBUG_OFF + , enum_mdl_duration duration_arg +#endif + ); static void destroy(MDL_ticket *ticket); private: /** Type of metadata lock. Externally accessible. */ enum enum_mdl_type m_type; +#ifndef DBUG_OFF + /** + Duration of lock represented by this ticket. + Context private. Debug-only. + */ + enum_mdl_duration m_duration; +#endif /** Context of the owner of the metadata lock ticket. Externally accessible. */ @@ -511,6 +545,39 @@ private: }; +/** + Savepoint for MDL context. + + Doesn't include metadata locks with explicit duration as + they are not released during rollback to savepoint. +*/ + +class MDL_savepoint +{ +public: + MDL_savepoint() {}; + +private: + MDL_savepoint(MDL_ticket *stmt_ticket, MDL_ticket *trans_ticket) + : m_stmt_ticket(stmt_ticket), m_trans_ticket(trans_ticket) + {} + + friend class MDL_context; + +private: + /** + Pointer to last lock with statement duration which was taken + before creation of savepoint. + */ + MDL_ticket *m_stmt_ticket; + /** + Pointer to last lock with transaction duration which was taken + before creation of savepoint. + */ + MDL_ticket *m_trans_ticket; +}; + + /** A reliable way to wait on an MDL lock. */ @@ -559,9 +626,7 @@ public: typedef I_P_List, - I_P_List_null_counter, - I_P_List_fast_push_back > + &MDL_ticket::prev_in_context> > Ticket_list; typedef Ticket_list::Iterator Ticket_iterator; @@ -584,37 +649,28 @@ public: const char *db, const char *name, enum_mdl_type mdl_type); - bool has_lock(MDL_ticket *mdl_savepoint, MDL_ticket *mdl_ticket); + bool has_lock(const MDL_savepoint &mdl_savepoint, MDL_ticket *mdl_ticket); inline bool has_locks() const { - return !m_tickets.is_empty(); + return !(m_tickets[MDL_STATEMENT].is_empty() && + m_tickets[MDL_TRANSACTION].is_empty() && + m_tickets[MDL_EXPLICIT].is_empty()); } - MDL_ticket *mdl_savepoint() + MDL_savepoint mdl_savepoint() { - /* - NULL savepoint represents the start of the transaction. - Checking for m_trans_sentinel also makes sure we never - return a pointer to HANDLER ticket as a savepoint. - */ - return m_tickets.front() == m_trans_sentinel ? NULL : m_tickets.front(); + return MDL_savepoint(m_tickets[MDL_STATEMENT].front(), + m_tickets[MDL_TRANSACTION].front()); } - void set_trans_sentinel() - { - m_trans_sentinel= m_tickets.front(); - } - MDL_ticket *trans_sentinel() const { return m_trans_sentinel; } - - void reset_trans_sentinel(MDL_ticket *sentinel_arg) - { - m_trans_sentinel= sentinel_arg; - } - void move_ticket_after_trans_sentinel(MDL_ticket *mdl_ticket); + void set_explicit_duration_for_all_locks(); + void set_transaction_duration_for_all_locks(); + void set_lock_duration(MDL_ticket *mdl_ticket, enum_mdl_duration duration); + void release_statement_locks(); void release_transactional_locks(); - void rollback_to_savepoint(MDL_ticket *mdl_savepoint); + void rollback_to_savepoint(const MDL_savepoint &mdl_savepoint); inline THD *get_thd() const { return m_thd; } @@ -655,46 +711,43 @@ public: MDL_wait m_wait; private: /** - All MDL tickets acquired by this connection. + Lists of all MDL tickets acquired by this connection. - The order of tickets in m_tickets list. - --------------------------------------- - The entire set of locks acquired by a connection - can be separated in two subsets: transactional and - non-transactional locks. + Lists of MDL tickets: + --------------------- + The entire set of locks acquired by a connection can be separated + in three subsets according to their: locks released at the end of + statement, at the end of transaction and locks are released + explicitly. - Transactional locks are locks with automatic scope. They - are accumulated in the course of a transaction, and - released only on COMMIT, ROLLBACK or ROLLBACK TO SAVEPOINT. - They must not be (and never are) released manually, + Statement and transactional locks are locks with automatic scope. + They are accumulated in the course of a transaction, and released + either at the end of uppermost statement (for statement locks) or + on COMMIT, ROLLBACK or ROLLBACK TO SAVEPOINT (for transactional + locks). They must not be (and never are) released manually, i.e. with release_lock() call. - Non-transactional locks are taken for locks that span + Locks with explicit duration are taken for locks that span multiple transactions or savepoints. These are: HANDLER SQL locks (HANDLER SQL is transaction-agnostic), LOCK TABLES locks (you can COMMIT/etc under LOCK TABLES, and the locked tables stay locked), and - SET GLOBAL READ_ONLY=1 global shared lock. + locks implementing "global read lock". - Transactional locks are always prepended to the beginning - of the list. In other words, they are stored in reverse - temporal order. Thus, when we rollback to a savepoint, - we start popping and releasing tickets from the front - until we reach the last ticket acquired after the - savepoint. + Statement/transactional locks are always prepended to the + beginning of the appropriate list. In other words, they are + stored in reverse temporal order. Thus, when we rollback to + a savepoint, we start popping and releasing tickets from the + front until we reach the last ticket acquired after the savepoint. - Non-transactional locks are always stored after - transactional ones, and among each other can be - split into three sets: + Locks with explicit duration stored are not stored in any + particular order, and among each other can be split into + three sets: [LOCK TABLES locks] [HANDLER locks] [GLOBAL READ LOCK locks] The following is known about these sets: - * we can never have both HANDLER and LOCK TABLES locks - together -- HANDLER statements are prohibited under LOCK - TABLES, entering LOCK TABLES implicitly closes all open - HANDLERs. * GLOBAL READ LOCK locks are always stored after LOCK TABLES locks and after HANDLER locks. This is because one can't say SET GLOBAL read_only=1 or FLUSH TABLES WITH READ LOCK @@ -709,14 +762,9 @@ private: However, one can open a few HANDLERs after entering the read only mode. * LOCK TABLES locks include intention exclusive locks on - involved schemas. + involved schemas and global intention exclusive lock. */ - Ticket_list m_tickets; - /** - Separates transactional and non-transactional locks - in m_tickets list, @sa m_tickets. - */ - MDL_ticket *m_trans_sentinel; + Ticket_list m_tickets[MDL_DURATION_END]; THD *m_thd; /** TRUE - if for this context we will break protocol and try to @@ -747,8 +795,9 @@ private: MDL_wait_for_subgraph *m_waiting_for; private: MDL_ticket *find_ticket(MDL_request *mdl_req, - bool *is_transactional); - void release_locks_stored_before(MDL_ticket *sentinel); + enum_mdl_duration *duration); + void release_locks_stored_before(enum_mdl_duration duration, MDL_ticket *sentinel); + void release_lock(enum_mdl_duration duration, MDL_ticket *ticket); bool try_acquire_lock_impl(MDL_request *mdl_request, MDL_ticket **out_ticket); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 21754b23940..9e4026f3a1c 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -604,8 +604,7 @@ pthread_key(MEM_ROOT**,THR_MALLOC); pthread_key(THD*, THR_THD); mysql_mutex_t LOCK_thread_count; mysql_mutex_t - LOCK_status, LOCK_global_read_lock, - LOCK_error_log, LOCK_uuid_generator, + LOCK_status, LOCK_error_log, LOCK_uuid_generator, LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_global_system_variables, @@ -625,7 +624,6 @@ mysql_mutex_t LOCK_des_key_file; mysql_rwlock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave; mysql_rwlock_t LOCK_system_variables_hash; mysql_cond_t COND_thread_count; -mysql_cond_t COND_global_read_lock; pthread_t signal_thread; pthread_attr_t connection_attrib; mysql_mutex_t LOCK_server_started; @@ -1542,7 +1540,6 @@ static void clean_up_mutexes() mysql_mutex_destroy(&LOCK_crypt); mysql_mutex_destroy(&LOCK_user_conn); mysql_mutex_destroy(&LOCK_connection_count); - Events::destroy_mutexes(); #ifdef HAVE_OPENSSL mysql_mutex_destroy(&LOCK_des_key_file); #ifndef HAVE_YASSL @@ -1560,12 +1557,10 @@ static void clean_up_mutexes() mysql_rwlock_destroy(&LOCK_sys_init_slave); mysql_mutex_destroy(&LOCK_global_system_variables); mysql_rwlock_destroy(&LOCK_system_variables_hash); - mysql_mutex_destroy(&LOCK_global_read_lock); mysql_mutex_destroy(&LOCK_uuid_generator); mysql_mutex_destroy(&LOCK_prepared_stmt_count); mysql_mutex_destroy(&LOCK_error_messages); mysql_cond_destroy(&COND_thread_count); - mysql_cond_destroy(&COND_global_read_lock); mysql_cond_destroy(&COND_thread_cache); mysql_cond_destroy(&COND_flush_thread_cache); mysql_cond_destroy(&COND_manager); @@ -3524,8 +3519,6 @@ static int init_thread_environment() &LOCK_global_system_variables, MY_MUTEX_INIT_FAST); mysql_rwlock_init(key_rwlock_LOCK_system_variables_hash, &LOCK_system_variables_hash); - mysql_mutex_init(key_LOCK_global_read_lock, - &LOCK_global_read_lock, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_LOCK_prepared_stmt_count, &LOCK_prepared_stmt_count, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_LOCK_error_messages, @@ -3553,7 +3546,6 @@ static int init_thread_environment() mysql_rwlock_init(key_rwlock_LOCK_sys_init_slave, &LOCK_sys_init_slave); mysql_rwlock_init(key_rwlock_LOCK_grant, &LOCK_grant); mysql_cond_init(key_COND_thread_count, &COND_thread_count, NULL); - mysql_cond_init(key_COND_global_read_lock, &COND_global_read_lock, NULL); mysql_cond_init(key_COND_thread_cache, &COND_thread_cache, NULL); mysql_cond_init(key_COND_flush_thread_cache, &COND_flush_thread_cache, NULL); mysql_cond_init(key_COND_manager, &COND_manager, NULL); @@ -7669,7 +7661,7 @@ PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_prep_xids, key_delayed_insert_mutex, key_hash_filo_lock, key_LOCK_active_mi, key_LOCK_connection_count, key_LOCK_crypt, key_LOCK_delayed_create, key_LOCK_delayed_insert, key_LOCK_delayed_status, key_LOCK_error_log, - key_LOCK_gdl, key_LOCK_global_read_lock, key_LOCK_global_system_variables, + key_LOCK_gdl, key_LOCK_global_system_variables, key_LOCK_manager, key_LOCK_prepared_stmt_count, key_LOCK_rpl_status, key_LOCK_server_started, key_LOCK_status, @@ -7707,7 +7699,6 @@ static PSI_mutex_info all_server_mutexes[]= { &key_LOCK_delayed_status, "LOCK_delayed_status", PSI_FLAG_GLOBAL}, { &key_LOCK_error_log, "LOCK_error_log", PSI_FLAG_GLOBAL}, { &key_LOCK_gdl, "LOCK_gdl", PSI_FLAG_GLOBAL}, - { &key_LOCK_global_read_lock, "LOCK_global_read_lock", PSI_FLAG_GLOBAL}, { &key_LOCK_global_system_variables, "LOCK_global_system_variables", PSI_FLAG_GLOBAL}, { &key_LOCK_manager, "LOCK_manager", PSI_FLAG_GLOBAL}, { &key_LOCK_prepared_stmt_count, "LOCK_prepared_stmt_count", PSI_FLAG_GLOBAL}, @@ -7756,7 +7747,7 @@ PSI_cond_key key_PAGE_cond, key_COND_active, key_COND_pool; #endif /* HAVE_MMAP */ PSI_cond_key key_BINLOG_COND_prep_xids, key_BINLOG_update_cond, - key_COND_cache_status_changed, key_COND_global_read_lock, key_COND_manager, + key_COND_cache_status_changed, key_COND_manager, key_COND_rpl_status, key_COND_server_started, key_delayed_insert_cond, key_delayed_insert_cond_client, key_item_func_sleep_cond, key_master_info_data_cond, @@ -7779,7 +7770,6 @@ static PSI_cond_info all_server_conds[]= { &key_BINLOG_COND_prep_xids, "MYSQL_BIN_LOG::COND_prep_xids", 0}, { &key_BINLOG_update_cond, "MYSQL_BIN_LOG::update_cond", 0}, { &key_COND_cache_status_changed, "Query_cache::COND_cache_status_changed", 0}, - { &key_COND_global_read_lock, "COND_global_read_lock", PSI_FLAG_GLOBAL}, { &key_COND_manager, "COND_manager", PSI_FLAG_GLOBAL}, { &key_COND_rpl_status, "COND_rpl_status", PSI_FLAG_GLOBAL}, { &key_COND_server_started, "COND_server_started", PSI_FLAG_GLOBAL}, diff --git a/sql/mysqld.h b/sql/mysqld.h index dc9f94c0d03..5e65d0d2a8d 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -100,7 +100,7 @@ extern bool opt_ignore_builtin_innodb; extern my_bool opt_character_set_client_handshake; extern bool volatile abort_loop; extern bool in_bootstrap; -extern uint volatile thread_count, global_read_lock; +extern uint volatile thread_count; extern uint connection_count; extern my_bool opt_safe_user_create; extern my_bool opt_safe_show_db, opt_local_infile, opt_myisam_use_mmap; @@ -227,7 +227,7 @@ extern PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_prep_xids, key_delayed_insert_mutex, key_hash_filo_lock, key_LOCK_active_mi, key_LOCK_connection_count, key_LOCK_crypt, key_LOCK_delayed_create, key_LOCK_delayed_insert, key_LOCK_delayed_status, key_LOCK_error_log, - key_LOCK_gdl, key_LOCK_global_read_lock, key_LOCK_global_system_variables, + key_LOCK_gdl, key_LOCK_global_system_variables, key_LOCK_logger, key_LOCK_manager, key_LOCK_prepared_stmt_count, key_LOCK_rpl_status, key_LOCK_server_started, key_LOCK_status, @@ -248,7 +248,7 @@ extern PSI_cond_key key_PAGE_cond, key_COND_active, key_COND_pool; #endif /* HAVE_MMAP */ extern PSI_cond_key key_BINLOG_COND_prep_xids, key_BINLOG_update_cond, - key_COND_cache_status_changed, key_COND_global_read_lock, key_COND_manager, + key_COND_cache_status_changed, key_COND_manager, key_COND_rpl_status, key_COND_server_started, key_delayed_insert_cond, key_delayed_insert_cond_client, key_item_func_sleep_cond, key_master_info_data_cond, @@ -320,7 +320,7 @@ extern mysql_mutex_t LOCK_user_locks, LOCK_status, LOCK_error_log, LOCK_delayed_insert, LOCK_uuid_generator, LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone, - LOCK_slave_list, LOCK_active_mi, LOCK_manager, LOCK_global_read_lock, + LOCK_slave_list, LOCK_active_mi, LOCK_manager, LOCK_global_system_variables, LOCK_user_conn, LOCK_prepared_stmt_count, LOCK_error_messages, LOCK_connection_count; extern MYSQL_PLUGIN_IMPORT mysql_mutex_t LOCK_thread_count; @@ -333,7 +333,6 @@ extern mysql_rwlock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave; extern mysql_rwlock_t LOCK_system_variables_hash; extern mysql_cond_t COND_thread_count; extern mysql_cond_t COND_manager; -extern mysql_cond_t COND_global_read_lock; extern int32 thread_running; extern my_atomic_rwlock_t thread_running_lock; diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index af9b452acd8..a35e7bb1612 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -1274,6 +1274,9 @@ void Relay_log_info::slave_close_thread_tables(THD *thd) */ if (! thd->in_multi_stmt_transaction_mode()) thd->mdl_context.release_transactional_locks(); + else + thd->mdl_context.release_statement_locks(); + clear_tables_to_lock(); } #endif diff --git a/sql/sp.cc b/sql/sp.cc index 7385a6ffcae..4dea6843ef1 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -27,7 +27,7 @@ #include "sql_acl.h" // SUPER_ACL #include "sp_head.h" #include "sp_cache.h" -#include "lock.h" // lock_routine_name +#include "lock.h" // lock_object_name #include @@ -440,7 +440,7 @@ static TABLE *open_proc_table_for_update(THD *thd) { TABLE_LIST table_list; TABLE *table; - MDL_ticket *mdl_savepoint= thd->mdl_context.mdl_savepoint(); + MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint(); DBUG_ENTER("open_proc_table_for_update"); table_list.init_one_table("mysql", 5, "proc", 4, "proc", TL_WRITE); @@ -925,6 +925,8 @@ sp_create_routine(THD *thd, int type, sp_head *sp) TABLE *table; char definer[USER_HOST_BUFF_SIZE]; ulong saved_mode= thd->variables.sql_mode; + MDL_key::enum_mdl_namespace mdl_type= type == TYPE_ENUM_FUNCTION ? + MDL_key::FUNCTION : MDL_key::PROCEDURE; CHARSET_INFO *db_cs= get_default_db_collation(thd, sp->m_db.str); @@ -944,8 +946,7 @@ sp_create_routine(THD *thd, int type, sp_head *sp) type == TYPE_ENUM_FUNCTION); /* Grab an exclusive MDL lock. */ - if (lock_routine_name(thd, type == TYPE_ENUM_FUNCTION, - sp->m_db.str, sp->m_name.str)) + if (lock_object_name(thd, mdl_type, sp->m_db.str, sp->m_name.str)) DBUG_RETURN(SP_OPEN_TABLE_FAILED); /* Reset sql_mode during data dictionary operations. */ @@ -1193,6 +1194,8 @@ sp_drop_routine(THD *thd, int type, sp_name *name) TABLE *table; int ret; bool save_binlog_row_based; + MDL_key::enum_mdl_namespace mdl_type= type == TYPE_ENUM_FUNCTION ? + MDL_key::FUNCTION : MDL_key::PROCEDURE; DBUG_ENTER("sp_drop_routine"); DBUG_PRINT("enter", ("type: %d name: %.*s", type, (int) name->m_name.length, name->m_name.str)); @@ -1201,8 +1204,7 @@ sp_drop_routine(THD *thd, int type, sp_name *name) type == TYPE_ENUM_FUNCTION); /* Grab an exclusive MDL lock. */ - if (lock_routine_name(thd, type == TYPE_ENUM_FUNCTION, - name->m_db.str, name->m_name.str)) + if (lock_object_name(thd, mdl_type, name->m_db.str, name->m_name.str)) DBUG_RETURN(SP_DELETE_ROW_FAILED); if (!(table= open_proc_table_for_update(thd))) @@ -1273,6 +1275,8 @@ sp_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics) TABLE *table; int ret; bool save_binlog_row_based; + MDL_key::enum_mdl_namespace mdl_type= type == TYPE_ENUM_FUNCTION ? + MDL_key::FUNCTION : MDL_key::PROCEDURE; DBUG_ENTER("sp_update_routine"); DBUG_PRINT("enter", ("type: %d name: %.*s", type, (int) name->m_name.length, name->m_name.str)); @@ -1281,8 +1285,7 @@ sp_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics) type == TYPE_ENUM_FUNCTION); /* Grab an exclusive MDL lock. */ - if (lock_routine_name(thd, type == TYPE_ENUM_FUNCTION, - name->m_db.str, name->m_name.str)) + if (lock_object_name(thd, mdl_type, name->m_db.str, name->m_name.str)) DBUG_RETURN(SP_OPEN_TABLE_FAILED); if (!(table= open_proc_table_for_update(thd))) @@ -1370,7 +1373,7 @@ sp_drop_db_routines(THD *thd, char *db) TABLE *table; int ret; uint key_len; - MDL_ticket *mdl_savepoint= thd->mdl_context.mdl_savepoint(); + MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint(); DBUG_ENTER("sp_drop_db_routines"); DBUG_PRINT("enter", ("db: %s", db)); @@ -1697,7 +1700,7 @@ bool sp_add_used_routine(Query_tables_list *prelocking_ctx, Query_arena *arena, (Sroutine_hash_entry *)arena->alloc(sizeof(Sroutine_hash_entry)); if (!rn) // OOM. Error will be reported using fatal_error(). return FALSE; - rn->mdl_request.init(key, MDL_SHARED); + rn->mdl_request.init(key, MDL_SHARED, MDL_TRANSACTION); if (my_hash_insert(&prelocking_ctx->sroutines, (uchar *)rn)) return FALSE; prelocking_ctx->sroutines_list.link_in_list(rn, &rn->next); diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 0d33bd5c599..5089e7e0340 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -2140,6 +2140,8 @@ sp_head::execute_procedure(THD *thd, List *args) if (! thd->in_sub_stmt && ! thd->in_multi_stmt_transaction_mode()) thd->mdl_context.release_transactional_locks(); + else if (! thd->in_sub_stmt) + thd->mdl_context.release_statement_locks(); thd->rollback_item_tree_changes(); @@ -2978,6 +2980,8 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp, if (! thd->in_sub_stmt && ! thd->in_multi_stmt_transaction_mode()) thd->mdl_context.release_transactional_locks(); + else if (! thd->in_sub_stmt) + thd->mdl_context.release_statement_locks(); } if (m_lex->query_tables_own_last) @@ -4176,7 +4180,8 @@ sp_head::add_used_tables_to_table_list(THD *thd, */ table->mdl_request.init(MDL_key::TABLE, table->db, table->table_name, table->lock_type >= TL_WRITE_ALLOW_WRITE ? - MDL_SHARED_WRITE : MDL_SHARED_READ); + MDL_SHARED_WRITE : MDL_SHARED_READ, + MDL_TRANSACTION); /* Everyting else should be zeroed */ @@ -4220,7 +4225,7 @@ sp_add_to_query_tables(THD *thd, LEX *lex, table->select_lex= lex->current_select; table->cacheable_table= 1; table->mdl_request.init(MDL_key::TABLE, table->db, table->table_name, - mdl_type); + mdl_type, MDL_TRANSACTION); lex->add_to_query_tables(table); return table; diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index 21a05a5baca..f648d219fac 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -85,7 +85,7 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, key_length= create_table_def_key(thd, key, table_list, 0); table_list->mdl_request.init(MDL_key::TABLE, table_list->db, table_list->table_name, - MDL_EXCLUSIVE); + MDL_EXCLUSIVE, MDL_TRANSACTION); if (lock_table_names(thd, table_list, table_list->next_global, thd->variables.lock_wait_timeout, diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 8caae3ee406..60c32a1a376 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -21,7 +21,7 @@ #include "sql_priv.h" #include "unireg.h" #include "debug_sync.h" -#include "lock.h" // broadcast_refresh, mysql_lock_remove, +#include "lock.h" // mysql_lock_remove, // mysql_unlock_tables, // mysql_lock_have_duplicate #include "sql_show.h" // append_identifier @@ -1285,20 +1285,12 @@ static void mark_used_tables_as_free_for_reuse(THD *thd, TABLE *table) static void close_open_tables(THD *thd) { - bool found_old_table= 0; - mysql_mutex_assert_not_owner(&LOCK_open); DBUG_PRINT("info", ("thd->open_tables: 0x%lx", (long) thd->open_tables)); while (thd->open_tables) - found_old_table|= close_thread_table(thd, &thd->open_tables); - - if (found_old_table) - { - /* Tell threads waiting for refresh that something has happened */ - broadcast_refresh(); - } + (void) close_thread_table(thd, &thd->open_tables); } @@ -1364,11 +1356,6 @@ close_all_tables_for_name(THD *thd, TABLE_SHARE *share, /* Remove the table share from the cache. */ tdc_remove_table(thd, TDC_RT_REMOVE_ALL, db, table_name, FALSE); - /* - There could be a FLUSH thread waiting - on the table to go away. Wake it up. - */ - broadcast_refresh(); } @@ -2463,7 +2450,8 @@ open_table_get_mdl_lock(THD *thd, Open_table_context *ot_ctx, mdl_request_shared.init(&mdl_request->key, (flags & MYSQL_OPEN_FORCE_SHARED_MDL) ? - MDL_SHARED : MDL_SHARED_HIGH_PRIO); + MDL_SHARED : MDL_SHARED_HIGH_PRIO, + MDL_TRANSACTION); mdl_request= &mdl_request_shared; } @@ -2627,32 +2615,6 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, key_length= (create_table_def_key(thd, key, table_list, 1) - TMP_TABLE_KEY_EXTRA); - /* - We need this to work for all tables, including temporary - tables, for backwards compatibility. But not under LOCK - TABLES, since under LOCK TABLES one can't use a non-prelocked - table. This code only works for updates done inside DO/SELECT - f1() statements, normal DML is handled by means of - sql_command_flags. - */ - if (global_read_lock && table_list->lock_type >= TL_WRITE_ALLOW_WRITE && - ! (flags & MYSQL_OPEN_IGNORE_GLOBAL_READ_LOCK) && - ! thd->locked_tables_mode) - { - /* - Someone has issued FLUSH TABLES WITH READ LOCK and we want - a write lock. Wait until the lock is gone. - */ - if (thd->global_read_lock.wait_if_global_read_lock(thd, 1, 1)) - DBUG_RETURN(TRUE); - - if (thd->open_tables && thd->open_tables->s->version != refresh_version) - { - (void)ot_ctx->request_backoff_action(Open_table_context::OT_REOPEN_TABLES, - NULL); - DBUG_RETURN(TRUE); - } - } /* Unless requested otherwise, try to resolve this table in the list of temporary tables of this thread. In MySQL temporary tables @@ -2824,6 +2786,59 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, if (! (flags & MYSQL_OPEN_HAS_MDL_LOCK)) { + /* + We are not under LOCK TABLES and going to acquire write-lock/ + modify the base table. We need to acquire protection against + global read lock until end of this statement in order to have + this statement blocked by active FLUSH TABLES WITH READ LOCK. + + We don't block acquire this protection under LOCK TABLES as + such protection already acquired at LOCK TABLES time and + not released until UNLOCK TABLES. + + We don't block statements which modify only temporary tables + as these tables are not preserved by backup by any form of + backup which uses FLUSH TABLES WITH READ LOCK. + + TODO: The fact that we sometimes acquire protection against + GRL only when we encounter table to be write-locked + slightly increases probability of deadlock. + This problem will be solved once Alik pushes his + temporary table refactoring patch and we can start + pre-acquiring metadata locks at the beggining of + open_tables() call. + */ + if (table_list->mdl_request.type >= MDL_SHARED_WRITE && + ! (flags & (MYSQL_OPEN_IGNORE_GLOBAL_READ_LOCK | + MYSQL_OPEN_FORCE_SHARED_MDL | + MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL | + MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK)) && + ! ot_ctx->has_protection_against_grl()) + { + MDL_request protection_request; + MDL_deadlock_handler mdl_deadlock_handler(ot_ctx); + + if (thd->global_read_lock.can_acquire_protection()) + DBUG_RETURN(TRUE); + + protection_request.init(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE, + MDL_STATEMENT); + + /* + Install error handler which if possible will convert deadlock error + into request to back-off and restart process of opening tables. + */ + thd->push_internal_handler(&mdl_deadlock_handler); + bool result= thd->mdl_context.acquire_lock(&protection_request, + ot_ctx->get_timeout()); + thd->pop_internal_handler(); + + if (result) + DBUG_RETURN(TRUE); + + ot_ctx->set_has_protection_against_grl(); + } + if (open_table_get_mdl_lock(thd, ot_ctx, &table_list->mdl_request, flags, &mdl_ticket) || mdl_ticket == NULL) @@ -3379,7 +3394,6 @@ unlink_all_closed_tables(THD *thd, MYSQL_LOCK *lock, size_t reopen_count) close_thread_table(thd, &thd->open_tables); } - broadcast_refresh(); } /* Exclude all closed tables from the LOCK TABLES list. */ for (TABLE_LIST *table_list= m_locked_tables; table_list; table_list= @@ -3856,7 +3870,8 @@ Open_table_context::Open_table_context(THD *thd, uint flags) LONG_TIMEOUT : thd->variables.lock_wait_timeout), m_flags(flags), m_action(OT_NO_ACTION), - m_has_locks(thd->mdl_context.has_locks()) + m_has_locks(thd->mdl_context.has_locks()), + m_has_protection_against_grl(FALSE) {} @@ -4013,6 +4028,12 @@ recover_from_failed_open(THD *thd) for safety. */ m_failed_table= NULL; + /* + Reset flag indicating that we have already acquired protection + against GRL. It is no longer valid as the corresponding lock was + released by close_tables_for_reopen(). + */ + m_has_protection_against_grl= FALSE; /* Prepare for possible another back-off. */ m_action= OT_NO_ACTION; return result; @@ -4551,11 +4572,20 @@ lock_table_names(THD *thd, if (schema_request == NULL) return TRUE; schema_request->init(MDL_key::SCHEMA, table->db, "", - MDL_INTENTION_EXCLUSIVE); + MDL_INTENTION_EXCLUSIVE, + MDL_TRANSACTION); mdl_requests.push_front(schema_request); } - /* Take the global intention exclusive lock. */ - global_request.init(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE); + + /* + Protect this statement against concurrent global read lock + by acquiring global intention exclusive lock with statement + duration. + */ + if (thd->global_read_lock.can_acquire_protection()) + return TRUE; + global_request.init(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE, + MDL_STATEMENT); mdl_requests.push_front(&global_request); } @@ -5362,7 +5392,7 @@ bool open_and_lock_tables(THD *thd, TABLE_LIST *tables, Prelocking_strategy *prelocking_strategy) { uint counter; - MDL_ticket *mdl_savepoint= thd->mdl_context.mdl_savepoint(); + MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint(); DBUG_ENTER("open_and_lock_tables"); DBUG_PRINT("enter", ("derived handling: %d", derived)); @@ -5419,7 +5449,7 @@ bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags) { DML_prelocking_strategy prelocking_strategy; uint counter; - MDL_ticket *mdl_savepoint= thd->mdl_context.mdl_savepoint(); + MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint(); DBUG_ENTER("open_normal_and_derived_tables"); DBUG_ASSERT(!thd->fill_derived_tables()); if (open_tables(thd, &tables, &counter, flags, &prelocking_strategy) || @@ -5676,7 +5706,7 @@ bool lock_tables(THD *thd, TABLE_LIST *tables, uint count, */ void close_tables_for_reopen(THD *thd, TABLE_LIST **tables, - MDL_ticket *start_of_statement_svp) + const MDL_savepoint &start_of_statement_svp) { TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table(); TABLE_LIST *tmp; diff --git a/sql/sql_base.h b/sql/sql_base.h index 00f335ab209..35fa04b3674 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -159,7 +159,7 @@ thr_lock_type read_lock_type_for_table(THD *thd, my_bool mysql_rm_tmp_tables(void); bool rm_temporary_table(handlerton *base, char *path); void close_tables_for_reopen(THD *thd, TABLE_LIST **tables, - MDL_ticket *start_of_statement_svp); + const MDL_savepoint &start_of_statement_svp); TABLE_LIST *find_table_in_list(TABLE_LIST *table, TABLE_LIST *TABLE_LIST::*link, const char *db_name, @@ -507,7 +507,7 @@ public: the statement, so that we can rollback to it before waiting on locks. */ - MDL_ticket *start_of_statement_svp() const + const MDL_savepoint &start_of_statement_svp() const { return m_start_of_statement_svp; } @@ -518,6 +518,21 @@ public: } uint get_flags() const { return m_flags; } + + /** + Set flag indicating that we have already acquired metadata lock + protecting this statement against GRL while opening tables. + */ + void set_has_protection_against_grl() + { + m_has_protection_against_grl= TRUE; + } + + bool has_protection_against_grl() const + { + return m_has_protection_against_grl; + } + private: /** For OT_DISCOVER and OT_REPAIR actions, the table list element for @@ -525,7 +540,7 @@ private: should be repaired. */ TABLE_LIST *m_failed_table; - MDL_ticket *m_start_of_statement_svp; + MDL_savepoint m_start_of_statement_svp; /** Lock timeout in seconds. Initialized to LONG_TIMEOUT when opening system tables or to the "lock_wait_timeout" system variable for regular tables. @@ -541,6 +556,11 @@ private: and we can't safely do back-off (and release them). */ bool m_has_locks; + /** + Indicates that in the process of opening tables we have acquired + protection against global read lock. + */ + bool m_has_protection_against_grl; }; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index c848d686299..1823a0416ff 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -3497,11 +3497,15 @@ void THD::set_mysys_var(struct st_my_thread_var *new_mysys_var) void THD::leave_locked_tables_mode() { locked_tables_mode= LTM_NONE; - /* Make sure we don't release the global read lock when leaving LTM. */ - mdl_context.reset_trans_sentinel(global_read_lock.global_shared_lock()); + mdl_context.set_transaction_duration_for_all_locks(); + /* + Make sure we don't release the global read lock and commit blocker + when leaving LTM. + */ + global_read_lock.set_explicit_lock_duration(this); /* Also ensure that we don't release metadata locks for open HANDLERs. */ if (handler_tables_hash.records) - mysql_ha_move_tickets_after_trans_sentinel(this); + mysql_ha_set_explicit_lock_duration(this); } void THD::get_definer(LEX_USER *definer) diff --git a/sql/sql_class.h b/sql/sql_class.h index 8c444f34364..8bf72f1cdb2 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -822,8 +822,8 @@ struct st_savepoint { char *name; uint length; Ha_trx_info *ha_list; - /** Last acquired lock before this savepoint was set. */ - MDL_ticket *mdl_savepoint; + /** State of metadata locks before this savepoint was set. */ + MDL_savepoint mdl_savepoint; }; enum xa_states {XA_NOTR=0, XA_ACTIVE, XA_IDLE, XA_PREPARED, XA_ROLLBACK_ONLY}; @@ -1058,12 +1058,12 @@ class Open_tables_backup: public Open_tables_state public: /** When we backup the open tables state to open a system - table or tables, points at the last metadata lock - acquired before the backup. Is used to release - metadata locks on system tables after they are + table or tables, we want to save state of metadata + locks which were acquired before the backup. It is used + to release metadata locks on system tables after they are no longer used. */ - MDL_ticket *mdl_system_tables_svp; + MDL_savepoint mdl_system_tables_svp; }; /** @@ -1336,26 +1336,43 @@ public: }; Global_read_lock() - :m_protection_count(0), m_state(GRL_NONE), m_mdl_global_shared_lock(NULL) + : m_state(GRL_NONE), + m_mdl_global_shared_lock(NULL), + m_mdl_blocks_commits_lock(NULL) {} bool lock_global_read_lock(THD *thd); void unlock_global_read_lock(THD *thd); - bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh, - bool is_not_commit); - void start_waiting_global_read_lock(THD *thd); + /** + Check if this connection can acquire protection against GRL and + emit error if otherwise. + */ + bool can_acquire_protection() const + { + if (m_state) + { + my_error(ER_CANT_UPDATE_WITH_READLOCK, MYF(0)); + return TRUE; + } + return FALSE; + } bool make_global_read_lock_block_commit(THD *thd); bool is_acquired() const { return m_state != GRL_NONE; } - bool has_protection() const { return m_protection_count > 0; } - MDL_ticket *global_shared_lock() const { return m_mdl_global_shared_lock; } + void set_explicit_lock_duration(THD *thd); private: - uint m_protection_count; // GRL protection count + enum_grl_state m_state; /** In order to acquire the global read lock, the connection must - acquire a global shared metadata lock, to prohibit all DDL. + acquire shared metadata lock in GLOBAL namespace, to prohibit + all DDL. */ - enum_grl_state m_state; MDL_ticket *m_mdl_global_shared_lock; + /** + Also in order to acquire the global read lock, the connection + must acquire a shared metadata lock in COMMIT namespace, to + prohibit commits. + */ + MDL_ticket *m_mdl_blocks_commits_lock; }; @@ -2697,7 +2714,7 @@ public: { DBUG_ASSERT(locked_tables_mode == LTM_NONE); - mdl_context.set_trans_sentinel(); + mdl_context.set_explicit_duration_for_all_locks(); locked_tables_mode= mode_arg; } void leave_locked_tables_mode(); @@ -3502,21 +3519,11 @@ public: */ #define CF_DIAGNOSTIC_STMT (1U << 8) -/** - SQL statements that must be protected against impending global read lock - to prevent deadlock. This deadlock could otherwise happen if the statement - starts waiting for the GRL to go away inside mysql_lock_tables while at the - same time having "old" opened tables. The thread holding the GRL can be - waiting for these "old" opened tables to be closed, causing a deadlock - (FLUSH TABLES WITH READ LOCK). - */ -#define CF_PROTECT_AGAINST_GRL (1U << 10) - /** Identifies statements that may generate row events and that may end up in the binary log. */ -#define CF_CAN_GENERATE_ROW_EVENTS (1U << 11) +#define CF_CAN_GENERATE_ROW_EVENTS (1U << 9) /* Bits in server_command_flags */ diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 517cb9139e9..4df8748429c 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -1054,7 +1054,8 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, table_list->alias= table_list->table_name; // If lower_case_table_names=2 table_list->internal_tmp_table= is_prefix(file->name, tmp_file_prefix); table_list->mdl_request.init(MDL_key::TABLE, table_list->db, - table_list->table_name, MDL_EXCLUSIVE); + table_list->table_name, MDL_EXCLUSIVE, + MDL_TRANSACTION); /* Link into list */ (*tot_list_next_local)= table_list; (*tot_list_next_global)= table_list; diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index a5c126a8521..b5cd3ac9e9a 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -55,7 +55,7 @@ #include "sql_handler.h" #include "unireg.h" // REQUIRED: for other includes #include "sql_base.h" // close_thread_tables -#include "lock.h" // broadcast_refresh, mysql_unlock_tables +#include "lock.h" // mysql_unlock_tables #include "key.h" // key_copy #include "sql_base.h" // insert_fields #include "sql_select.h" @@ -131,11 +131,7 @@ static void mysql_ha_close_table(THD *thd, TABLE_LIST *tables) /* Non temporary table. */ tables->table->file->ha_index_or_rnd_end(); tables->table->open_by_handler= 0; - if (close_thread_table(thd, &tables->table)) - { - /* Tell threads waiting for refresh that something has happened */ - broadcast_refresh(); - } + (void) close_thread_table(thd, &tables->table); thd->mdl_context.release_lock(tables->mdl_request.ticket); } else if (tables->table) @@ -183,7 +179,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen) uint dblen, namelen, aliaslen, counter; bool error; TABLE *backup_open_tables; - MDL_ticket *mdl_savepoint; + MDL_savepoint mdl_savepoint; DBUG_ENTER("mysql_ha_open"); DBUG_PRINT("enter",("'%s'.'%s' as '%s' reopen: %d", tables->db, tables->table_name, tables->alias, @@ -252,7 +248,13 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen) memcpy(hash_tables->db, tables->db, dblen); memcpy(hash_tables->table_name, tables->table_name, namelen); memcpy(hash_tables->alias, tables->alias, aliaslen); - hash_tables->mdl_request.init(MDL_key::TABLE, db, name, MDL_SHARED); + /* + We can't request lock with explicit duration for this table + right from the start as open_tables() can't handle properly + back-off for such locks. + */ + hash_tables->mdl_request.init(MDL_key::TABLE, db, name, MDL_SHARED, + MDL_TRANSACTION); /* for now HANDLER can be used only for real TABLES */ hash_tables->required_type= FRMTYPE_TABLE; @@ -332,8 +334,8 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen) thd->set_open_tables(backup_open_tables); if (hash_tables->mdl_request.ticket) { - thd->mdl_context. - move_ticket_after_trans_sentinel(hash_tables->mdl_request.ticket); + thd->mdl_context.set_lock_duration(hash_tables->mdl_request.ticket, + MDL_EXPLICIT); thd->mdl_context.set_needs_thr_lock_abort(TRUE); } @@ -969,24 +971,23 @@ void mysql_ha_cleanup(THD *thd) /** - Move tickets for metadata locks corresponding to open HANDLERs - after transaction sentinel in order to protect them from being - released at the end of transaction. + Set explicit duration for metadata locks corresponding to open HANDLERs + to protect them from being released at the end of transaction. @param thd Thread identifier. */ -void mysql_ha_move_tickets_after_trans_sentinel(THD *thd) +void mysql_ha_set_explicit_lock_duration(THD *thd) { TABLE_LIST *hash_tables; - DBUG_ENTER("mysql_ha_move_tickets_after_trans_sentinel"); + DBUG_ENTER("mysql_ha_set_explicit_lock_duration"); for (uint i= 0; i < thd->handler_tables_hash.records; i++) { hash_tables= (TABLE_LIST*) my_hash_element(&thd->handler_tables_hash, i); if (hash_tables->table && hash_tables->table->mdl_ticket) - thd->mdl_context. - move_ticket_after_trans_sentinel(hash_tables->table->mdl_ticket); + thd->mdl_context.set_lock_duration(hash_tables->table->mdl_ticket, + MDL_EXPLICIT); } DBUG_VOID_RETURN; } diff --git a/sql/sql_handler.h b/sql/sql_handler.h index c5da3c4d468..2eea552d7c9 100644 --- a/sql/sql_handler.h +++ b/sql/sql_handler.h @@ -31,6 +31,6 @@ void mysql_ha_flush(THD *thd); void mysql_ha_flush_tables(THD *thd, TABLE_LIST *all_tables); void mysql_ha_rm_tables(THD *thd, TABLE_LIST *tables); void mysql_ha_cleanup(THD *thd); -void mysql_ha_move_tickets_after_trans_sentinel(THD *thd); +void mysql_ha_set_explicit_lock_duration(THD *thd); #endif /* SQL_HANDLER_INCLUDED */ diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 1f8da3fab5c..860a5b8941a 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -77,7 +77,8 @@ #include "sql_audit.h" #ifndef EMBEDDED_LIBRARY -static bool delayed_get_table(THD *thd, TABLE_LIST *table_list); +static bool delayed_get_table(THD *thd, MDL_request *grl_protection_request, + TABLE_LIST *table_list); static int write_delayed(THD *thd, TABLE *table, enum_duplicates duplic, LEX_STRING query, bool ignore, bool log_on); static void end_delayed_insert(THD *thd); @@ -529,32 +530,28 @@ void upgrade_lock_type(THD *thd, thr_lock_type *lock_type, static bool open_and_lock_for_insert_delayed(THD *thd, TABLE_LIST *table_list) { + MDL_request protection_request; DBUG_ENTER("open_and_lock_for_insert_delayed"); #ifndef EMBEDDED_LIBRARY - if (thd->locked_tables_mode && thd->global_read_lock.is_acquired()) - { - /* - If this connection has the global read lock, the handler thread - will not be able to lock the table. It will wait for the global - read lock to go away, but this will never happen since the - connection thread will be stuck waiting for the handler thread - to open and lock the table. - If we are not in locked tables mode, INSERT will seek protection - against the global read lock (and fail), thus we will only get - to this point in locked tables mode. - */ - my_error(ER_CANT_UPDATE_WITH_READLOCK, MYF(0)); - DBUG_RETURN(TRUE); - } - /* In order for the deadlock detector to be able to find any deadlocks - caused by the handler thread locking this table, we take the metadata - lock inside the connection thread. If this goes ok, the ticket is cloned - and added to the list of granted locks held by the handler thread. + caused by the handler thread waiting for GRL or this table, we acquire + protection against GRL (global IX metadata lock) and metadata lock on + table to being inserted into inside the connection thread. + If this goes ok, the tickets are cloned and added to the list of granted + locks held by the handler thread. */ - MDL_ticket *mdl_savepoint= thd->mdl_context.mdl_savepoint(); + if (thd->global_read_lock.can_acquire_protection()) + DBUG_RETURN(TRUE); + + protection_request.init(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE, + MDL_STATEMENT); + + if (thd->mdl_context.acquire_lock(&protection_request, + thd->variables.lock_wait_timeout)) + DBUG_RETURN(TRUE); + if (thd->mdl_context.acquire_lock(&table_list->mdl_request, thd->variables.lock_wait_timeout)) /* @@ -564,7 +561,7 @@ bool open_and_lock_for_insert_delayed(THD *thd, TABLE_LIST *table_list) DBUG_RETURN(TRUE); bool error= FALSE; - if (delayed_get_table(thd, table_list)) + if (delayed_get_table(thd, &protection_request, table_list)) error= TRUE; else if (table_list->table) { @@ -589,13 +586,13 @@ bool open_and_lock_for_insert_delayed(THD *thd, TABLE_LIST *table_list) } /* - If a lock was acquired above, we should release it after - handle_delayed_insert() has cloned the ticket. Note that acquire_lock() can - succeed because the connection already has the lock. In this case the ticket - will be before the mdl_savepoint and we should not release it here. + We can't release protection against GRL and metadata lock on the table + being inserted into here. These locks might be required, for example, + because this INSERT DELAYED calls functions which may try to update + this or another tables (updating the same table is of course illegal, + but such an attempt can be discovered only later during statement + execution). */ - if (!thd->mdl_context.has_lock(mdl_savepoint, table_list->mdl_request.ticket)) - thd->mdl_context.release_lock(table_list->mdl_request.ticket); /* Reset the ticket in case we end up having to use normal insert and @@ -1873,10 +1870,11 @@ public: mysql_cond_t cond, cond_client; volatile uint tables_in_use,stacked_inserts; volatile bool status; - /* + /** When the handler thread starts, it clones a metadata lock ticket - for the table to be inserted. This is done to allow the deadlock - detector to detect deadlocks resulting from this lock. + which protects against GRL and ticket for the table to be inserted. + This is done to allow the deadlock detector to detect deadlocks + resulting from these locks. Before this is done, the connection thread cannot safely exit without causing problems for clone_ticket(). Once handler_thread_initialized has been set, it is safe for the @@ -1888,6 +1886,11 @@ public: I_List rows; ulong group_count; TABLE_LIST table_list; // Argument + /** + Request for IX metadata lock protecting against GRL which is + passed from connection thread to the handler thread. + */ + MDL_request grl_protection; Delayed_insert() :locks_in_memory(0), table(0),tables_in_use(0),stacked_inserts(0), @@ -2066,7 +2069,8 @@ Delayed_insert *find_handler(THD *thd, TABLE_LIST *table_list) */ static -bool delayed_get_table(THD *thd, TABLE_LIST *table_list) +bool delayed_get_table(THD *thd, MDL_request *grl_protection_request, + TABLE_LIST *table_list) { int error; Delayed_insert *di; @@ -2110,7 +2114,10 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list) /* Replace volatile strings with local copies */ di->table_list.alias= di->table_list.table_name= di->thd.query(); di->table_list.db= di->thd.db; - /* We need the ticket so that it can be cloned in handle_delayed_insert */ + /* We need the tickets so that they can be cloned in handle_delayed_insert */ + di->grl_protection.init(MDL_key::GLOBAL, "", "", + MDL_INTENTION_EXCLUSIVE, MDL_STATEMENT); + di->grl_protection.ticket= grl_protection_request->ticket; init_mdl_requests(&di->table_list); di->table_list.mdl_request.ticket= table_list->mdl_request.ticket; @@ -2650,13 +2657,15 @@ pthread_handler_t handle_delayed_insert(void *arg) thd->set_current_stmt_binlog_format_row_if_mixed(); /* - Clone the ticket representing the lock on the target table for - the insert and add it to the list of granted metadata locks held by - the handler thread. This is safe since the handler thread is - not holding nor waiting on any metadata locks. + Clone tickets representing protection against GRL and the lock on + the target table for the insert and add them to the list of granted + metadata locks held by the handler thread. This is safe since the + handler thread is not holding nor waiting on any metadata locks. */ - if (thd->mdl_context.clone_ticket(&di->table_list.mdl_request)) + if (thd->mdl_context.clone_ticket(&di->grl_protection) || + thd->mdl_context.clone_ticket(&di->table_list.mdl_request)) { + thd->mdl_context.release_transactional_locks(); di->handler_thread_initialized= TRUE; goto err; } diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index d91489b4a7a..7a8a86d3ca4 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -417,7 +417,6 @@ void lex_start(THD *thd) lex->nest_level=0 ; lex->allow_sum_func= 0; lex->in_sum_func= NULL; - lex->protect_against_global_read_lock= FALSE; /* ok, there must be a better solution for this, long-term I tried "bzero" in the sql_yacc.yy code, but that for diff --git a/sql/sql_lex.h b/sql/sql_lex.h index c20c2f0bca2..191562bd3e8 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -2394,22 +2394,6 @@ struct LEX: public Query_tables_list bool escape_used; bool is_lex_started; /* If lex_start() did run. For debugging. */ - /* - Special case for SELECT .. FOR UPDATE and LOCK TABLES .. WRITE. - - Protect from a impending GRL as otherwise the thread might deadlock - if it starts waiting for the GRL in mysql_lock_tables. - - The protection is needed because there is a race between setting - the global read lock and waiting for all open tables to be closed. - The problem is a circular wait where a thread holding "old" open - tables will wait for the global read lock to be released while the - thread holding the global read lock will wait for all "old" open - tables to be closed -- the flush part of flush tables with read - lock. - */ - bool protect_against_global_read_lock; - LEX(); virtual ~LEX() diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index c09a4abb2c8..e95745634e8 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -18,12 +18,9 @@ #include "sql_priv.h" #include "unireg.h" // REQUIRED: for other includes #include "sql_parse.h" // sql_kill, *_precheck, *_prepare -#include "lock.h" // wait_if_global_read_lock, - // unlock_global_read_lock, - // try_transactional_lock, +#include "lock.h" // try_transactional_lock, // check_transactional_lock, // set_handler_table_locks, - // start_waiting_global_read_lock, // lock_global_read_lock, // make_global_read_lock_block_commit #include "sql_base.h" // find_temporary_tablesx @@ -260,21 +257,20 @@ void init_update_queries(void) the code, in particular in the Query_log_event's constructor. */ sql_command_flags[SQLCOM_CREATE_TABLE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | - CF_AUTO_COMMIT_TRANS | CF_PROTECT_AGAINST_GRL | + CF_AUTO_COMMIT_TRANS | CF_CAN_GENERATE_ROW_EVENTS; sql_command_flags[SQLCOM_CREATE_INDEX]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; sql_command_flags[SQLCOM_ALTER_TABLE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND | - CF_AUTO_COMMIT_TRANS | CF_PROTECT_AGAINST_GRL; + CF_AUTO_COMMIT_TRANS; sql_command_flags[SQLCOM_TRUNCATE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND | - CF_AUTO_COMMIT_TRANS | CF_PROTECT_AGAINST_GRL; + CF_AUTO_COMMIT_TRANS; sql_command_flags[SQLCOM_DROP_TABLE]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; sql_command_flags[SQLCOM_LOAD]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | - CF_PROTECT_AGAINST_GRL | CF_CAN_GENERATE_ROW_EVENTS; - sql_command_flags[SQLCOM_CREATE_DB]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | CF_PROTECT_AGAINST_GRL; - sql_command_flags[SQLCOM_DROP_DB]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | CF_PROTECT_AGAINST_GRL; - sql_command_flags[SQLCOM_ALTER_DB_UPGRADE]= CF_AUTO_COMMIT_TRANS | CF_PROTECT_AGAINST_GRL; - sql_command_flags[SQLCOM_ALTER_DB]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | CF_PROTECT_AGAINST_GRL; + sql_command_flags[SQLCOM_CREATE_DB]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; + sql_command_flags[SQLCOM_DROP_DB]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; + sql_command_flags[SQLCOM_ALTER_DB_UPGRADE]= CF_AUTO_COMMIT_TRANS; + sql_command_flags[SQLCOM_ALTER_DB]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; sql_command_flags[SQLCOM_RENAME_TABLE]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; sql_command_flags[SQLCOM_DROP_INDEX]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; sql_command_flags[SQLCOM_CREATE_VIEW]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | @@ -285,26 +281,18 @@ void init_update_queries(void) sql_command_flags[SQLCOM_CREATE_EVENT]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; sql_command_flags[SQLCOM_ALTER_EVENT]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; sql_command_flags[SQLCOM_DROP_EVENT]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; - sql_command_flags[SQLCOM_CREATE_TRIGGER]= CF_AUTO_COMMIT_TRANS; - sql_command_flags[SQLCOM_DROP_TRIGGER]= CF_AUTO_COMMIT_TRANS; sql_command_flags[SQLCOM_UPDATE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | - CF_PROTECT_AGAINST_GRL | CF_CAN_GENERATE_ROW_EVENTS; sql_command_flags[SQLCOM_UPDATE_MULTI]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | - CF_PROTECT_AGAINST_GRL | CF_CAN_GENERATE_ROW_EVENTS; sql_command_flags[SQLCOM_INSERT]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | - CF_PROTECT_AGAINST_GRL | CF_CAN_GENERATE_ROW_EVENTS; sql_command_flags[SQLCOM_INSERT_SELECT]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | - CF_PROTECT_AGAINST_GRL | CF_CAN_GENERATE_ROW_EVENTS; sql_command_flags[SQLCOM_DELETE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | - CF_PROTECT_AGAINST_GRL | CF_CAN_GENERATE_ROW_EVENTS; sql_command_flags[SQLCOM_DELETE_MULTI]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | - CF_PROTECT_AGAINST_GRL | CF_CAN_GENERATE_ROW_EVENTS; sql_command_flags[SQLCOM_REPLACE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | CF_CAN_GENERATE_ROW_EVENTS; @@ -366,20 +354,19 @@ void init_update_queries(void) CF_REEXECUTION_FRAGILE); - sql_command_flags[SQLCOM_CREATE_USER]= CF_CHANGES_DATA | CF_PROTECT_AGAINST_GRL; - sql_command_flags[SQLCOM_RENAME_USER]= CF_CHANGES_DATA | CF_PROTECT_AGAINST_GRL; - sql_command_flags[SQLCOM_DROP_USER]= CF_CHANGES_DATA | CF_PROTECT_AGAINST_GRL; + sql_command_flags[SQLCOM_CREATE_USER]= CF_CHANGES_DATA; + sql_command_flags[SQLCOM_RENAME_USER]= CF_CHANGES_DATA; + sql_command_flags[SQLCOM_DROP_USER]= CF_CHANGES_DATA; sql_command_flags[SQLCOM_GRANT]= CF_CHANGES_DATA; sql_command_flags[SQLCOM_REVOKE]= CF_CHANGES_DATA; - sql_command_flags[SQLCOM_REVOKE_ALL]= CF_PROTECT_AGAINST_GRL; sql_command_flags[SQLCOM_OPTIMIZE]= CF_CHANGES_DATA; sql_command_flags[SQLCOM_CREATE_FUNCTION]= CF_CHANGES_DATA; - sql_command_flags[SQLCOM_CREATE_PROCEDURE]= CF_CHANGES_DATA | CF_PROTECT_AGAINST_GRL | CF_AUTO_COMMIT_TRANS; - sql_command_flags[SQLCOM_CREATE_SPFUNCTION]= CF_CHANGES_DATA | CF_PROTECT_AGAINST_GRL | CF_AUTO_COMMIT_TRANS; - sql_command_flags[SQLCOM_DROP_PROCEDURE]= CF_CHANGES_DATA | CF_PROTECT_AGAINST_GRL | CF_AUTO_COMMIT_TRANS; - sql_command_flags[SQLCOM_DROP_FUNCTION]= CF_CHANGES_DATA | CF_PROTECT_AGAINST_GRL | CF_AUTO_COMMIT_TRANS; - sql_command_flags[SQLCOM_ALTER_PROCEDURE]= CF_CHANGES_DATA | CF_PROTECT_AGAINST_GRL | CF_AUTO_COMMIT_TRANS; - sql_command_flags[SQLCOM_ALTER_FUNCTION]= CF_CHANGES_DATA | CF_PROTECT_AGAINST_GRL | CF_AUTO_COMMIT_TRANS; + sql_command_flags[SQLCOM_CREATE_PROCEDURE]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; + sql_command_flags[SQLCOM_CREATE_SPFUNCTION]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; + sql_command_flags[SQLCOM_DROP_PROCEDURE]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; + sql_command_flags[SQLCOM_DROP_FUNCTION]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; + sql_command_flags[SQLCOM_ALTER_PROCEDURE]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; + sql_command_flags[SQLCOM_ALTER_FUNCTION]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; sql_command_flags[SQLCOM_INSTALL_PLUGIN]= CF_CHANGES_DATA; sql_command_flags[SQLCOM_UNINSTALL_PLUGIN]= CF_CHANGES_DATA; @@ -1111,7 +1098,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, SHOW statements should not add the used tables to the list of tables used in a transaction. */ - MDL_ticket *mdl_savepoint= thd->mdl_context.mdl_savepoint(); + MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint(); status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_FIELDS]); if (thd->copy_db_to(&db.str, &db.length)) @@ -1754,16 +1741,6 @@ bool sp_process_definer(THD *thd) /** Execute command saved in thd and lex->sql_command. - Before every operation that can request a write lock for a table - wait if a global read lock exists. However do not wait if this - thread has locked tables already. No new locks can be requested - until the other locks are released. The thread that requests the - global read lock waits for write locked tables to become unlocked. - - Note that wait_if_global_read_lock() sets a protection against a new - global read lock when it succeeds. This needs to be released by - start_waiting_global_read_lock() after the operation. - @param thd Thread handle @todo @@ -1797,7 +1774,6 @@ mysql_execute_command(THD *thd) /* have table map for update for multi-update statement (BUG#37051) */ bool have_table_map_for_update= FALSE; #endif - /* Saved variable value */ DBUG_ENTER("mysql_execute_command"); #ifdef WITH_PARTITION_STORAGE_ENGINE thd->work_part_info= 0; @@ -1989,17 +1965,6 @@ mysql_execute_command(THD *thd) thd->mdl_context.release_transactional_locks(); } - /* - Check if this command needs protection against the global read lock - to avoid deadlock. See CF_PROTECT_AGAINST_GRL. - start_waiting_global_read_lock() is called at the end of - mysql_execute_command(). - */ - if (((sql_command_flags[lex->sql_command] & CF_PROTECT_AGAINST_GRL) != 0) && - !thd->locked_tables_mode) - if (thd->global_read_lock.wait_if_global_read_lock(thd, FALSE, TRUE)) - goto error; - #ifndef DBUG_OFF if (lex->sql_command != SQLCOM_SET_OPTION) DEBUG_SYNC(thd,"before_execute_sql_command"); @@ -2074,10 +2039,6 @@ mysql_execute_command(THD *thd) if (res) break; - if (!thd->locked_tables_mode && lex->protect_against_global_read_lock && - thd->global_read_lock.wait_if_global_read_lock(thd, FALSE, TRUE)) - break; - res= execute_sqlcom_select(thd, all_tables); break; } @@ -2336,20 +2297,6 @@ case SQLCOM_PREPARE: create_info.default_table_charset= create_info.table_charset; create_info.table_charset= 0; } - /* - The create-select command will open and read-lock the select table - and then create, open and write-lock the new table. If a global - read lock steps in, we get a deadlock. The write lock waits for - the global read lock, while the global read lock waits for the - select table to be closed. So we wait until the global readlock is - gone before starting both steps. Note that - wait_if_global_read_lock() sets a protection against a new global - read lock when it succeeds. This needs to be released by - start_waiting_global_read_lock(). We protect the normal CREATE - TABLE in the same way. That way we avoid that a new table is - created during a global read lock. - Protection against grl is covered by the CF_PROTECT_AGAINST_GRL flag. - */ #ifdef WITH_PARTITION_STORAGE_ENGINE { @@ -3143,9 +3090,6 @@ end_with_restore_list: if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, all_tables, FALSE, UINT_MAX, FALSE)) goto error; - if (lex->protect_against_global_read_lock && - thd->global_read_lock.wait_if_global_read_lock(thd, FALSE, TRUE)) - goto error; thd->variables.option_bits|= OPTION_TABLE_LOCK; thd->in_lock_tables=1; @@ -3801,13 +3745,22 @@ end_with_restore_list: Security_context *backup= NULL; LEX_USER *definer= thd->lex->definer; /* - We're going to issue an implicit GRANT statement. - It takes metadata locks and updates system tables. - Make sure that sp_create_routine() did not leave any - locks in the MDL context, so there is no risk to - deadlock. + We're going to issue an implicit GRANT statement so we close all + open tables. We have to keep metadata locks as this ensures that + this statement is atomic against concurent FLUSH TABLES WITH READ + LOCK. Deadlocks which can arise due to fact that this implicit + statement takes metadata locks should be detected by a deadlock + detector in MDL subsystem and reported as errors. + + No need to commit/rollback statement transaction, it's not started. + + TODO: Long-term we should either ensure that implicit GRANT statement + is written into binary log as a separate statement or make both + creation of routine and implicit GRANT parts of one fully atomic + statement. */ - close_mysql_tables(thd); + DBUG_ASSERT(thd->transaction.stmt.is_empty()); + close_thread_tables(thd); /* Check if the definer exists on slave, then use definer privilege to insert routine privileges to mysql.procs_priv. @@ -4067,13 +4020,22 @@ create_sp_error: #ifndef NO_EMBEDDED_ACCESS_CHECKS /* - We're going to issue an implicit REVOKE statement. - It takes metadata locks and updates system tables. - Make sure that sp_create_routine() did not leave any - locks in the MDL context, so there is no risk to - deadlock. + We're going to issue an implicit REVOKE statement so we close all + open tables. We have to keep metadata locks as this ensures that + this statement is atomic against concurent FLUSH TABLES WITH READ + LOCK. Deadlocks which can arise due to fact that this implicit + statement takes metadata locks should be detected by a deadlock + detector in MDL subsystem and reported as errors. + + No need to commit/rollback statement transaction, it's not started. + + TODO: Long-term we should either ensure that implicit REVOKE statement + is written into binary log as a separate statement or make both + dropping of routine and implicit REVOKE parts of one fully atomic + statement. */ - close_mysql_tables(thd); + DBUG_ASSERT(thd->transaction.stmt.is_empty()); + close_thread_tables(thd); if (sp_result != SP_KEY_NOT_FOUND && sp_automatic_privileges && !opt_noacl && @@ -4362,14 +4324,6 @@ error: res= TRUE; finish: - if (thd->global_read_lock.has_protection()) - { - /* - Release the protection against the global read lock and wake - everyone, who might want to set a global read lock. - */ - thd->global_read_lock.start_waiting_global_read_lock(thd); - } DBUG_ASSERT(!thd->in_active_multi_stmt_transaction() || thd->in_multi_stmt_transaction_mode()); @@ -4405,6 +4359,11 @@ finish: close_thread_tables(thd); thd_proc_info(thd, 0); +#ifndef DBUG_OFF + if (lex->sql_command != SQLCOM_SET_OPTION && ! thd->in_sub_stmt) + DEBUG_SYNC(thd, "execute_command_after_close_tables"); +#endif + if (stmt_causes_implicit_commit(thd, CF_IMPLICIT_COMMIT_END)) { /* No transaction control allowed in sub-statements. */ @@ -4430,6 +4389,10 @@ finish: */ thd->mdl_context.release_transactional_locks(); } + else if (! thd->in_sub_stmt) + { + thd->mdl_context.release_statement_locks(); + } DBUG_RETURN(res || thd->is_error()); } @@ -5899,7 +5862,8 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, ptr->next_name_resolution_table= NULL; /* Link table in global list (all used tables) */ lex->add_to_query_tables(ptr); - ptr->mdl_request.init(MDL_key::TABLE, ptr->db, ptr->table_name, mdl_type); + ptr->mdl_request.init(MDL_key::TABLE, ptr->db, ptr->table_name, mdl_type, + MDL_TRANSACTION); DBUG_RETURN(ptr); } diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index fcbf2c48896..2b51305d099 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -3172,7 +3172,6 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) bool error; Statement stmt_backup; Query_arena *old_stmt_arena; - MDL_ticket *mdl_savepoint= NULL; DBUG_ENTER("Prepared_statement::prepare"); /* If this is an SQLCOM_PREPARE, we also increase Com_prepare_sql. @@ -3244,7 +3243,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) Marker used to release metadata locks acquired while the prepared statement is being checked. */ - mdl_savepoint= thd->mdl_context.mdl_savepoint(); + MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint(); /* The only case where we should have items in the thd->free_list is diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index 8f990eae001..6a7b0b0b3ad 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -24,8 +24,7 @@ #include "sql_table.h" // build_table_filename #include "sql_view.h" // mysql_frm_type, mysql_rename_view #include "sql_trigger.h" -#include "lock.h" // wait_if_global_read_lock - // start_waiting_global_read_lock +#include "lock.h" // MYSQL_OPEN_SKIP_TEMPORARY #include "sql_base.h" // tdc_remove_table, lock_table_names, #include "sql_handler.h" // mysql_ha_rm_tables #include "datadict.h" @@ -63,9 +62,6 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent) mysql_ha_rm_tables(thd, table_list); - if (thd->global_read_lock.wait_if_global_read_lock(thd, FALSE, TRUE)) - DBUG_RETURN(1); - if (logger.is_log_table_enabled(QUERY_LOG_GENERAL) || logger.is_log_table_enabled(QUERY_LOG_SLOW)) { @@ -189,7 +185,6 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent) query_cache_invalidate3(thd, table_list, 0); err: - thd->global_read_lock.start_waiting_global_read_lock(thd); DBUG_RETURN(error || binlog_error); } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 19a73c85a9b..b8c66562b1a 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -671,7 +671,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) Metadata locks taken during SHOW CREATE should be released when the statmement completes as it is an information statement. */ - MDL_ticket *mdl_savepoint= thd->mdl_context.mdl_savepoint(); + MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint(); /* We want to preserve the tree for views. */ thd->lex->view_prepare_mode= TRUE; @@ -3186,7 +3186,7 @@ try_acquire_high_prio_shared_mdl_lock(THD *thd, TABLE_LIST *table, { bool error; table->mdl_request.init(MDL_key::TABLE, table->db, table->table_name, - MDL_SHARED_HIGH_PRIO); + MDL_SHARED_HIGH_PRIO, MDL_TRANSACTION); if (can_deadlock) { @@ -7745,7 +7745,7 @@ bool show_create_trigger(THD *thd, const sp_name *trg_name) Metadata locks taken during SHOW CREATE TRIGGER should be released when the statement completes as it is an information statement. */ - MDL_ticket *mdl_savepoint= thd->mdl_context.mdl_savepoint(); + MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint(); /* Open the table by name in order to load Table_triggers_list object. diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 1c6ca4a48d9..ed0acc66e49 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -23,9 +23,7 @@ #include "sql_parse.h" // test_if_data_home_dir #include "sql_cache.h" // query_cache_* #include "sql_base.h" // open_table_uncached, lock_table_names -#include "lock.h" // wait_if_global_read_lock - // start_waiting_global_read_lock, - // mysql_unlock_tables +#include "lock.h" // mysql_unlock_tables #include "strfunc.h" // find_type2, find_set #include "sql_view.h" // view_checksum #include "sql_truncate.h" // regenerate_locked_table @@ -1855,21 +1853,10 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, DBUG_ENTER("mysql_rm_table"); /* mark for close and remove all cached entries */ - - if (!drop_temporary) - { - if (!thd->locked_tables_mode && - thd->global_read_lock.wait_if_global_read_lock(thd, FALSE, TRUE)) - DBUG_RETURN(TRUE); - } - thd->push_internal_handler(&err_handler); error= mysql_rm_table_part2(thd, tables, if_exists, drop_temporary, 0, 0); thd->pop_internal_handler(); - if (thd->global_read_lock.has_protection()) - thd->global_read_lock.start_waiting_global_read_lock(thd); - if (error) DBUG_RETURN(TRUE); my_ok(thd); @@ -5592,7 +5579,6 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, TABLE *table, *new_table= 0; MDL_ticket *mdl_ticket; MDL_request target_mdl_request; - bool has_target_mdl_lock= FALSE; int error= 0; char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN + 1]; char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias; @@ -5754,7 +5740,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, else { target_mdl_request.init(MDL_key::TABLE, new_db, new_name, - MDL_EXCLUSIVE); + MDL_EXCLUSIVE, MDL_TRANSACTION); /* Global intention exclusive lock must have been already acquired when table to be altered was open, so there is no need to do it here. @@ -5772,7 +5758,6 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, DBUG_RETURN(TRUE); } DEBUG_SYNC(thd, "locked_table_name"); - has_target_mdl_lock= TRUE; /* Table maybe does not exist, but we got an exclusive lock on the name, now we can safely try to find out for sure. @@ -5959,10 +5944,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, along with the implicit commit. */ if (new_name != table_name || new_db != db) - { - thd->mdl_context.release_lock(target_mdl_request.ticket); thd->mdl_context.release_all_locks_for_name(mdl_ticket); - } else mdl_ticket->downgrade_exclusive_lock(MDL_SHARED_NO_READ_WRITE); } @@ -6667,10 +6649,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, thd->locked_tables_mode == LTM_PRELOCKED_UNDER_LOCK_TABLES) { if ((new_name != table_name || new_db != db)) - { - thd->mdl_context.release_lock(target_mdl_request.ticket); thd->mdl_context.release_all_locks_for_name(mdl_ticket); - } else mdl_ticket->downgrade_exclusive_lock(MDL_SHARED_NO_READ_WRITE); } @@ -6731,8 +6710,6 @@ err: alter_info->datetime_field->field_name); thd->abort_on_warning= save_abort_on_warning; } - if (has_target_mdl_lock) - thd->mdl_context.release_lock(target_mdl_request.ticket); DBUG_RETURN(TRUE); @@ -6744,9 +6721,6 @@ err_with_mdl: tables and release the exclusive metadata lock. */ thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0); - if (has_target_mdl_lock) - thd->mdl_context.release_lock(target_mdl_request.ticket); - thd->mdl_context.release_all_locks_for_name(mdl_ticket); DBUG_RETURN(TRUE); } diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index a9b52eee9fc..c2e3cd9944a 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -24,8 +24,6 @@ #include "parse_file.h" #include "sp.h" #include "sql_base.h" // find_temporary_table -#include "lock.h" // wait_if_global_read_lock, - // start_waiting_global_read_lock #include "sql_show.h" // append_definer, append_identifier #include "sql_table.h" // build_table_filename, // check_n_cut_mysql50_prefix @@ -391,15 +389,6 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) DBUG_RETURN(TRUE); } - /* - We don't want perform our operations while global read lock is held - so we have to wait until its end and then prevent it from occurring - again until we are done, unless we are under lock tables. - */ - if (!thd->locked_tables_mode && - thd->global_read_lock.wait_if_global_read_lock(thd, FALSE, TRUE)) - DBUG_RETURN(TRUE); - if (!create) { bool if_exists= thd->lex->drop_if_exists; @@ -547,9 +536,6 @@ end: if (!create) thd->lex->restore_backup_query_tables_list(&backup); - if (thd->global_read_lock.has_protection()) - thd->global_read_lock.start_waiting_global_read_lock(thd); - if (!result) my_ok(thd); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 96b1ac67b49..8a9feb1b3f8 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1026,9 +1026,17 @@ int mysql_multi_update_prepare(THD *thd) /* following need for prepared statements, to run next time multi-update */ thd->lex->sql_command= SQLCOM_UPDATE_MULTI; - /* open tables and create derived ones, but do not lock and fill them */ + /* + Open tables and create derived ones, but do not lock and fill them yet. + + During prepare phase acquire only S metadata locks instead of SW locks to + keep prepare of multi-UPDATE compatible with concurrent LOCK TABLES WRITE + and global read lock. + */ if ((original_multiupdate && - open_tables(thd, &table_list, &table_count, 0)) || + open_tables(thd, &table_list, &table_count, + (thd->stmt_arena->is_stmt_prepare() ? + MYSQL_OPEN_FORCE_SHARED_MDL : 0))) || mysql_handle_derived(lex, &mysql_derived_prepare)) DBUG_RETURN(TRUE); /* diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 5fdf7b8d850..54b5eb43ab1 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -22,7 +22,7 @@ #include "sql_base.h" // find_table_in_global_list, lock_table_names #include "sql_parse.h" // sql_parse #include "sql_cache.h" // query_cache_* -#include "lock.h" // wait_if_global_read_lock +#include "lock.h" // MYSQL_OPEN_SKIP_TEMPORARY #include "sql_show.h" // append_identifier #include "sql_table.h" // build_table_filename #include "sql_db.h" // mysql_opt_change_db, mysql_change_db @@ -649,13 +649,6 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, } #endif - - if (thd->global_read_lock.wait_if_global_read_lock(thd, FALSE, TRUE)) - { - res= TRUE; - goto err; - } - res= mysql_register_view(thd, view, mode); if (mysql_bin_log.is_open()) @@ -704,7 +697,6 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, if (mode != VIEW_CREATE_NEW) query_cache_invalidate3(thd, view, 0); - thd->global_read_lock.start_waiting_global_read_lock(thd); if (res) goto err; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 66d74a398fb..9aa938437b1 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -7385,7 +7385,6 @@ select_lock_type: LEX *lex=Lex; lex->current_select->set_lock_for_tables(TL_WRITE); lex->safe_to_cache_query=0; - lex->protect_against_global_read_lock= TRUE; } | LOCK_SYM IN_SYM SHARE_SYM MODE_SYM { @@ -13182,9 +13181,6 @@ table_lock: MDL_SHARED_NO_READ_WRITE : MDL_SHARED_READ))) MYSQL_YYABORT; - /* If table is to be write locked, protect from a impending GRL. */ - if (lock_for_write) - Lex->protect_against_global_read_lock= TRUE; } ; diff --git a/sql/table.cc b/sql/table.cc index f55095d6e82..8cd2e9e9bab 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -5219,7 +5219,8 @@ void init_mdl_requests(TABLE_LIST *table_list) table_list->mdl_request.init(MDL_key::TABLE, table_list->db, table_list->table_name, table_list->lock_type >= TL_WRITE_ALLOW_WRITE ? - MDL_SHARED_WRITE : MDL_SHARED_READ); + MDL_SHARED_WRITE : MDL_SHARED_READ, + MDL_TRANSACTION); } diff --git a/sql/table.h b/sql/table.h index c8e1ad8e658..6aba4f21db2 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1384,7 +1384,8 @@ struct TABLE_LIST lock_type= lock_type_arg; mdl_request.init(MDL_key::TABLE, db, table_name, (lock_type >= TL_WRITE_ALLOW_WRITE) ? - MDL_SHARED_WRITE : MDL_SHARED_READ); + MDL_SHARED_WRITE : MDL_SHARED_READ, + MDL_TRANSACTION); } /* diff --git a/sql/transaction.cc b/sql/transaction.cc index d3e3ba142b9..b331fea89fe 100644 --- a/sql/transaction.cc +++ b/sql/transaction.cc @@ -21,6 +21,7 @@ #include "sql_priv.h" #include "transaction.h" #include "rpl_handler.h" +#include "debug_sync.h" // DEBUG_SYNC /* Conditions under which the transaction state must not change. */ static bool trans_check(THD *thd) @@ -391,15 +392,15 @@ bool trans_savepoint(THD *thd, LEX_STRING name) thd->transaction.savepoints= newsv; /* - Remember the last acquired lock before the savepoint was set. - This is used as a marker to only release locks acquired after + Remember locks acquired before the savepoint was set. + They are used as a marker to only release locks acquired after the setting of this savepoint. Note: this works just fine if we're under LOCK TABLES, since mdl_savepoint() is guaranteed to be beyond the last locked table. This allows to release some locks acquired during LOCK TABLES. */ - newsv->mdl_savepoint = thd->mdl_context.mdl_savepoint(); + newsv->mdl_savepoint= thd->mdl_context.mdl_savepoint(); DBUG_RETURN(FALSE); } @@ -645,17 +646,31 @@ bool trans_xa_commit(THD *thd) } else if (xa_state == XA_PREPARED && thd->lex->xa_opt == XA_NONE) { - if (thd->global_read_lock.wait_if_global_read_lock(thd, FALSE, FALSE)) + MDL_request mdl_request; + + /* + Acquire metadata lock which will ensure that COMMIT is blocked + by active FLUSH TABLES WITH READ LOCK (and vice versa COMMIT in + progress blocks FTWRL). + + We allow FLUSHer to COMMIT; we assume FLUSHer knows what it does. + */ + mdl_request.init(MDL_key::COMMIT, "", "", MDL_INTENTION_EXCLUSIVE, + MDL_TRANSACTION); + + if (thd->mdl_context.acquire_lock(&mdl_request, + thd->variables.lock_wait_timeout)) { ha_rollback_trans(thd, TRUE); my_error(ER_XAER_RMERR, MYF(0)); } else { + DEBUG_SYNC(thd, "trans_xa_commit_after_acquire_commit_lock"); + res= test(ha_commit_one_phase(thd, 1)); if (res) my_error(ER_XAER_RMERR, MYF(0)); - thd->global_read_lock.start_waiting_global_read_lock(thd); } } else From e1837cc0d822fd866a5e0ea7e472234f6aa7abdf Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 12 Nov 2010 02:33:19 +0100 Subject: [PATCH 227/304] Bug #52275 CMake configure wrapper does not handle --with-comment correctly Properly convert --with-comment do not uppercase it, quote as it might contain spaces. --- cmake/configure.pl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cmake/configure.pl b/cmake/configure.pl index 1dc8080810c..b24afa034c7 100644 --- a/cmake/configure.pl +++ b/cmake/configure.pl @@ -185,6 +185,11 @@ foreach my $option (@ARGV) ($option =~ /enable/ ? "1" : "0"); next; } + if ($option =~ /with-comment=/) + { + $cmakeargs = $cmakeargs." \"-DWITH_COMMENT=".substr($option,13)."\""; + next; + } $option = uc($option); $option =~ s/-/_/g; From 41dc34d60b7e924ace2c6a044189aaa345cf2820 Mon Sep 17 00:00:00 2001 From: Marc Alff Date: Fri, 12 Nov 2010 07:23:26 +0100 Subject: [PATCH 228/304] Bug#58052 Binary log IO not being accounted for properly Before this fix, file io for the binary log file was not accounted properly, and showed no io at all. This bug was due to the following issues: 1) file io for the binlog was instrumented: - sometime as "wait/io/file/sql/binlog" - sometime as "wait/io/file/sql/MYSQL_LOG" leading to inconsistent event_names. 2) the binlog file itself was using an IO_CACHE, but the IO_CACHE implementation in mysys/mf_iocache.c was not instrumented to make performance schema calls to record file io. 3) The "wait/io/file/sql/MYSQL_LOG" instrumentation was used for several log files, such as: - the binary log - the slow log - the query log which caused file io in these different log files to be accounted against the same instrument. The instrumentation needs to have a finer grain and report io in different event_names, because each file really serves a different purpose. With this fix: - the IO_CACHE implementation is now instrumented - the "wait/io/file/sql/MYSQL_LOG" instrument has been removed - binlog io is now always instrumented with "wait/io/file/sql/binlog" - the slow log is instrumented with a new name, "wait/io/file/sql/slow_log" - the query log is instrumented with a new name, "wait/io/file/sql/query_log" --- mysys/mf_iocache.c | 48 +++++++++++++++++++++++----------------------- sql/log.cc | 23 +++++++++++++++++----- sql/log.h | 26 ++++++++++++++++++++----- sql/mysqld.cc | 6 ++++-- sql/mysqld.h | 3 ++- 5 files changed, 69 insertions(+), 37 deletions(-) diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c index 173b678cdd1..575581712d4 100644 --- a/mysys/mf_iocache.c +++ b/mysys/mf_iocache.c @@ -173,7 +173,7 @@ int init_io_cache(IO_CACHE *info, File file, size_t cachesize, if (file >= 0) { - pos= my_tell(file, MYF(0)); + pos= mysql_file_tell(file, MYF(0)); if ((pos == (my_off_t) -1) && (my_errno == ESPIPE)) { /* @@ -205,7 +205,7 @@ int init_io_cache(IO_CACHE *info, File file, size_t cachesize, if (!(cache_myflags & MY_DONT_CHECK_FILESIZE)) { /* Calculate end of file to avoid allocating oversized buffers */ - end_of_file=my_seek(file,0L,MY_SEEK_END,MYF(0)); + end_of_file= mysql_file_seek(file, 0L, MY_SEEK_END, MYF(0)); /* Need to reset seek_not_done now that we just did a seek. */ info->seek_not_done= end_of_file == seek_offset ? 0 : 1; if (end_of_file < seek_offset) @@ -485,7 +485,7 @@ int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count) */ if (info->seek_not_done) { - if ((my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)) + if ((mysql_file_seek(info->file, pos_in_file, MY_SEEK_SET, MYF(0)) != MY_FILEPOS_ERROR)) { /* No error, reset seek_not_done flag. */ @@ -529,7 +529,7 @@ int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count) end aligned with a block. */ length=(Count & (size_t) ~(IO_SIZE-1))-diff_length; - if ((read_length= my_read(info->file,Buffer, length, info->myflags)) + if ((read_length= mysql_file_read(info->file,Buffer, length, info->myflags)) != length) { /* @@ -572,7 +572,7 @@ int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count) } length=0; /* Didn't read any chars */ } - else if ((length= my_read(info->file,info->buffer, max_length, + else if ((length= mysql_file_read(info->file,info->buffer, max_length, info->myflags)) < Count || length == (size_t) -1) { @@ -1056,7 +1056,7 @@ int _my_b_read_r(register IO_CACHE *cache, uchar *Buffer, size_t Count) */ if (cache->seek_not_done) { - if (my_seek(cache->file, pos_in_file, MY_SEEK_SET, MYF(0)) + if (mysql_file_seek(cache->file, pos_in_file, MY_SEEK_SET, MYF(0)) == MY_FILEPOS_ERROR) { cache->error= -1; @@ -1064,7 +1064,7 @@ int _my_b_read_r(register IO_CACHE *cache, uchar *Buffer, size_t Count) DBUG_RETURN(1); } } - len= my_read(cache->file, cache->buffer, length, cache->myflags); + len= mysql_file_read(cache->file, cache->buffer, length, cache->myflags); } DBUG_PRINT("io_cache_share", ("read %lu bytes", (ulong) len)); @@ -1203,7 +1203,7 @@ int _my_b_seq_read(register IO_CACHE *info, uchar *Buffer, size_t Count) With read-append cache we must always do a seek before we read, because the write could have moved the file pointer astray */ - if (my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)) == MY_FILEPOS_ERROR) + if (mysql_file_seek(info->file, pos_in_file, MY_SEEK_SET, MYF(0)) == MY_FILEPOS_ERROR) { info->error= -1; unlock_append_buffer(info); @@ -1220,8 +1220,8 @@ int _my_b_seq_read(register IO_CACHE *info, uchar *Buffer, size_t Count) size_t read_length; length=(Count & (size_t) ~(IO_SIZE-1))-diff_length; - if ((read_length= my_read(info->file,Buffer, length, - info->myflags)) == (size_t) -1) + if ((read_length= mysql_file_read(info->file,Buffer, length, + info->myflags)) == (size_t) -1) { info->error= -1; unlock_append_buffer(info); @@ -1254,7 +1254,7 @@ int _my_b_seq_read(register IO_CACHE *info, uchar *Buffer, size_t Count) } else { - length= my_read(info->file,info->buffer, max_length, info->myflags); + length= mysql_file_read(info->file,info->buffer, max_length, info->myflags); if (length == (size_t) -1) { info->error= -1; @@ -1431,7 +1431,7 @@ int _my_b_async_read(register IO_CACHE *info, uchar *Buffer, size_t Count) return 1; } - if (my_seek(info->file,next_pos_in_file,MY_SEEK_SET,MYF(0)) + if (mysql_file_seek(info->file, next_pos_in_file, MY_SEEK_SET, MYF(0)) == MY_FILEPOS_ERROR) { info->error= -1; @@ -1441,8 +1441,8 @@ int _my_b_async_read(register IO_CACHE *info, uchar *Buffer, size_t Count) read_length=IO_SIZE*2- (size_t) (next_pos_in_file & (IO_SIZE-1)); if (Count < read_length) { /* Small block, read to cache */ - if ((read_length=my_read(info->file,info->request_pos, - read_length, info->myflags)) == (size_t) -1) + if ((read_length=mysql_file_read(info->file,info->request_pos, + read_length, info->myflags)) == (size_t) -1) return info->error= -1; use_length=min(Count,read_length); memcpy(Buffer,info->request_pos,(size_t) use_length); @@ -1462,7 +1462,7 @@ int _my_b_async_read(register IO_CACHE *info, uchar *Buffer, size_t Count) } else { /* Big block, don't cache it */ - if ((read_length= my_read(info->file,Buffer, Count,info->myflags)) + if ((read_length= mysql_file_read(info->file, Buffer, Count,info->myflags)) != Count) { info->error= read_length == (size_t) -1 ? -1 : read_length+left_length; @@ -1569,14 +1569,14 @@ int _my_b_write(register IO_CACHE *info, const uchar *Buffer, size_t Count) "seek_not_done" to indicate this to other functions operating on the IO_CACHE. */ - if (my_seek(info->file,info->pos_in_file,MY_SEEK_SET,MYF(0))) + if (mysql_file_seek(info->file, info->pos_in_file, MY_SEEK_SET, MYF(0))) { info->error= -1; return (1); } info->seek_not_done=0; } - if (my_write(info->file, Buffer, length, info->myflags | MY_NABP)) + if (mysql_file_write(info->file, Buffer, length, info->myflags | MY_NABP)) return info->error= -1; #ifdef THREAD @@ -1639,7 +1639,7 @@ int my_b_append(register IO_CACHE *info, const uchar *Buffer, size_t Count) if (Count >= IO_SIZE) { /* Fill first intern buffer */ length=Count & (size_t) ~(IO_SIZE-1); - if (my_write(info->file,Buffer, length, info->myflags | MY_NABP)) + if (mysql_file_write(info->file,Buffer, length, info->myflags | MY_NABP)) { unlock_append_buffer(info); return info->error= -1; @@ -1695,11 +1695,11 @@ int my_block_write(register IO_CACHE *info, const uchar *Buffer, size_t Count, { /* Of no overlap, write everything without buffering */ if (pos + Count <= info->pos_in_file) - return my_pwrite(info->file, Buffer, Count, pos, - info->myflags | MY_NABP); + return mysql_file_pwrite(info->file, Buffer, Count, pos, + info->myflags | MY_NABP); /* Write the part of the block that is before buffer */ length= (uint) (info->pos_in_file - pos); - if (my_pwrite(info->file, Buffer, length, pos, info->myflags | MY_NABP)) + if (mysql_file_pwrite(info->file, Buffer, length, pos, info->myflags | MY_NABP)) info->error= error= -1; Buffer+=length; pos+= length; @@ -1789,7 +1789,7 @@ int my_b_flush_io_cache(IO_CACHE *info, */ if (!append_cache && info->seek_not_done) { /* File touched, do seek */ - if (my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)) == + if (mysql_file_seek(info->file, pos_in_file, MY_SEEK_SET, MYF(0)) == MY_FILEPOS_ERROR) { UNLOCK_APPEND_BUFFER; @@ -1803,7 +1803,7 @@ int my_b_flush_io_cache(IO_CACHE *info, info->write_end= (info->write_buffer+info->buffer_length- ((pos_in_file+length) & (IO_SIZE-1))); - if (my_write(info->file,info->write_buffer,length, + if (mysql_file_write(info->file,info->write_buffer,length, info->myflags | MY_NABP)) info->error= -1; else @@ -1815,7 +1815,7 @@ int my_b_flush_io_cache(IO_CACHE *info, else { info->end_of_file+=(info->write_pos-info->append_read_pos); - DBUG_ASSERT(info->end_of_file == my_tell(info->file,MYF(0))); + DBUG_ASSERT(info->end_of_file == mysql_file_tell(info->file, MYF(0))); } info->append_read_pos=info->write_pos=info->write_buffer; diff --git a/sql/log.cc b/sql/log.cc index ae0cb813742..bfc5018b556 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -2177,7 +2177,11 @@ bool MYSQL_LOG::init_and_set_log_file_name(const char *log_name, 1 error */ -bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, +bool MYSQL_LOG::open( +#ifdef HAVE_PSI_INTERFACE + PSI_file_key log_file_key, +#endif + const char *log_name, enum_log_type log_type_arg, const char *new_name, enum cache_type io_cache_type_arg) { char buff[FN_REFLEN]; @@ -2205,7 +2209,12 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, db[0]= 0; - if ((file= mysql_file_open(key_file_MYSQL_LOG, +#ifdef HAVE_PSI_INTERFACE + /* Keep the key for reopen */ + m_log_file_key= log_file_key; +#endif + + if ((file= mysql_file_open(log_file_key, log_file_name, open_flags, MYF(MY_WME | ME_WAITTANG))) < 0 || init_io_cache(&log_file, file, IO_SIZE, io_cache_type, @@ -2389,7 +2398,11 @@ void MYSQL_QUERY_LOG::reopen_file() Note that at this point, log_state != LOG_CLOSED (important for is_open()). */ - open(save_name, log_type, 0, io_cache_type); + open( +#ifdef HAVE_PSI_INTERFACE + m_log_file_key, +#endif + save_name, log_type, 0, io_cache_type); my_free(save_name); mysql_mutex_unlock(&LOCK_log); @@ -2855,8 +2868,8 @@ bool MYSQL_BIN_LOG::open(const char *log_name, write_error= 0; /* open the main log file */ - if (MYSQL_LOG::open(log_name, log_type_arg, new_name, - io_cache_type_arg)) + if (MYSQL_LOG::open(key_file_binlog, + log_name, log_type_arg, new_name, io_cache_type_arg)) { #ifdef HAVE_REPLICATION close_purge_index_file(); diff --git a/sql/log.h b/sql/log.h index 89b3594cd1e..d824d3afa26 100644 --- a/sql/log.h +++ b/sql/log.h @@ -196,7 +196,11 @@ public: MYSQL_LOG(); void init_pthread_objects(); void cleanup(); - bool open(const char *log_name, + bool open( +#ifdef HAVE_PSI_INTERFACE + PSI_file_key log_file_key, +#endif + const char *log_name, enum_log_type log_type, const char *new_name, enum cache_type io_cache_type_arg); @@ -223,6 +227,10 @@ public: volatile enum_log_state log_state; enum cache_type io_cache_type; friend class Log_event; +#ifdef HAVE_PSI_INTERFACE + /** Instrumentation key to use for file io in @c log_file */ + PSI_file_key m_log_file_key; +#endif }; class MYSQL_QUERY_LOG: public MYSQL_LOG @@ -241,14 +249,22 @@ public: bool open_slow_log(const char *log_name) { char buf[FN_REFLEN]; - return open(generate_name(log_name, "-slow.log", 0, buf), LOG_NORMAL, 0, - WRITE_CACHE); + return open( +#ifdef HAVE_PSI_INTERFACE + key_file_slow_log, +#endif + generate_name(log_name, "-slow.log", 0, buf), + LOG_NORMAL, 0, WRITE_CACHE); } bool open_query_log(const char *log_name) { char buf[FN_REFLEN]; - return open(generate_name(log_name, ".log", 0, buf), LOG_NORMAL, 0, - WRITE_CACHE); + return open( +#ifdef HAVE_PSI_INTERFACE + key_file_query_log, +#endif + generate_name(log_name, ".log", 0, buf), + LOG_NORMAL, 0, WRITE_CACHE); } private: diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 9f5f3d46e67..04e61635f22 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -7838,9 +7838,10 @@ PSI_file_key key_file_binlog, key_file_binlog_index, key_file_casetest, key_file_dbopt, key_file_des_key_file, key_file_ERRMSG, key_select_to_file, key_file_fileparser, key_file_frm, key_file_global_ddl_log, key_file_load, key_file_loadfile, key_file_log_event_data, key_file_log_event_info, - key_file_master_info, key_file_misc, key_file_MYSQL_LOG, key_file_partition, + key_file_master_info, key_file_misc, key_file_partition, key_file_pid, key_file_relay_log_info, key_file_send_file, key_file_tclog, key_file_trg, key_file_trn, key_file_init; +PSI_file_key key_file_query_log, key_file_slow_log; static PSI_file_info all_server_files[]= { @@ -7863,11 +7864,12 @@ static PSI_file_info all_server_files[]= { &key_file_log_event_info, "log_event_info", 0}, { &key_file_master_info, "master_info", 0}, { &key_file_misc, "misc", 0}, - { &key_file_MYSQL_LOG, "MYSQL_LOG", 0}, { &key_file_partition, "partition", 0}, { &key_file_pid, "pid", 0}, + { &key_file_query_log, "query_log", 0}, { &key_file_relay_log_info, "relay_log_info", 0}, { &key_file_send_file, "send_file", 0}, + { &key_file_slow_log, "slow_log", 0}, { &key_file_tclog, "tclog", 0}, { &key_file_trg, "trigger_name", 0}, { &key_file_trn, "trigger", 0}, diff --git a/sql/mysqld.h b/sql/mysqld.h index dc9f94c0d03..113bc3aa983 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -270,9 +270,10 @@ extern PSI_file_key key_file_binlog, key_file_binlog_index, key_file_casetest, key_file_dbopt, key_file_des_key_file, key_file_ERRMSG, key_select_to_file, key_file_fileparser, key_file_frm, key_file_global_ddl_log, key_file_load, key_file_loadfile, key_file_log_event_data, key_file_log_event_info, - key_file_master_info, key_file_misc, key_file_MYSQL_LOG, key_file_partition, + key_file_master_info, key_file_misc, key_file_partition, key_file_pid, key_file_relay_log_info, key_file_send_file, key_file_tclog, key_file_trg, key_file_trn, key_file_init; +extern PSI_file_key key_file_query_log, key_file_slow_log; void init_server_psi_keys(); #endif /* HAVE_PSI_INTERFACE */ From 1b583fa5da71a764dd66ad8b3668d7c75b122444 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Fri, 12 Nov 2010 13:12:15 +0300 Subject: [PATCH 229/304] Bug#58005 utf8 + get_format causes failed assertion: !str || str != Ptr' Problem: When GET_FORMAT() is called two times from the upper level function (e.g. LEAST in the bug report), on the second call "res= args[0]->val_str(...)" and str point to the same String object. 1. Fix: changing the order from - get val_str into tmp_value then convert to str to - get val_str into str then convert to tmp_value The new order is more correct: the purpose of "str" parameter is exactly to call val_str() for arguments. The purpose of String class members (like tmp_value) is to do further actions on the result. Doing it in the other way around give unexpected surprises. 2. Using str_value instead of str to do padding, for the same reason. --- mysql-test/r/date_formats.result | 14 ++++++++++++++ mysql-test/t/date_formats.test | 16 ++++++++++++++++ sql/item_timefunc.cc | 14 +++++++------- 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/date_formats.result b/mysql-test/r/date_formats.result index 7e185daa668..a919a6f8c5e 100644 --- a/mysql-test/r/date_formats.result +++ b/mysql-test/r/date_formats.result @@ -609,3 +609,17 @@ SELECT DATE_FORMAT("2009-01-01",'%W %d %M %Y') as valid_date; valid_date Thursday 01 January 2009 "End of 5.0 tests" +# +# Start of 5.1 tests +# +# +# Bug#58005 utf8 + get_format causes failed assertion: !str || str != Ptr' +# +SET NAMES utf8; +SELECT LEAST('%', GET_FORMAT(datetime, 'eur'), CAST(GET_FORMAT(datetime, 'eur') AS CHAR(65535))); +LEAST('%', GET_FORMAT(datetime, 'eur'), CAST(GET_FORMAT(datetime, 'eur') AS CHAR(65535))) +% +SET NAMES latin1; +# +# End of 5.1 tests +# diff --git a/mysql-test/t/date_formats.test b/mysql-test/t/date_formats.test index e5dc7ffa53e..2a5de8ca9ba 100644 --- a/mysql-test/t/date_formats.test +++ b/mysql-test/t/date_formats.test @@ -359,3 +359,19 @@ SELECT DATE_FORMAT("0000-02-28",'%W %d %M %Y') as valid_date; SELECT DATE_FORMAT("2009-01-01",'%W %d %M %Y') as valid_date; --echo "End of 5.0 tests" + + +--echo # +--echo # Start of 5.1 tests +--echo # + +--echo # +--echo # Bug#58005 utf8 + get_format causes failed assertion: !str || str != Ptr' +--echo # +SET NAMES utf8; +SELECT LEAST('%', GET_FORMAT(datetime, 'eur'), CAST(GET_FORMAT(datetime, 'eur') AS CHAR(65535))); +SET NAMES latin1; + +--echo # +--echo # End of 5.1 tests +--echo # diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 103bd96efd4..6335199b8de 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2456,14 +2456,14 @@ String *Item_char_typecast::val_str(String *str) { // Convert character set if differ uint dummy_errors; - if (!(res= args[0]->val_str(&tmp_value)) || - str->copy(res->ptr(), res->length(), from_cs, - cast_cs, &dummy_errors)) + if (!(res= args[0]->val_str(str)) || + tmp_value.copy(res->ptr(), res->length(), from_cs, + cast_cs, &dummy_errors)) { null_value= 1; return 0; } - res= str; + res= &tmp_value; } res->set_charset(cast_cs); @@ -2497,9 +2497,9 @@ String *Item_char_typecast::val_str(String *str) { if (res->alloced_length() < (uint) cast_length) { - str->alloc(cast_length); - str->copy(*res); - res= str; + str_value.alloc(cast_length); + str_value.copy(*res); + res= &str_value; } bzero((char*) res->ptr() + res->length(), (uint) cast_length - res->length()); From 2184a619c9953dd5914b5b6447e1c16755790428 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20Bl=C3=A5udd?= Date: Fri, 12 Nov 2010 11:50:37 +0100 Subject: [PATCH 230/304] Bug#58159 mtr.pl can't run out of source build with NDB - use $bindir instead of $basedir when looking for binaries - NOTE! the $ENV{NDB_EXAMPLES_*} will be reworked so that mtr.pl does not need to set them up. --- mysql-test/mysql-test-run.pl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 88719ff5bb2..bc609a0c960 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1752,17 +1752,17 @@ sub executable_setup () { if ( ! $opt_skip_ndbcluster ) { $exe_ndbd= - my_find_bin($basedir, + my_find_bin($bindir, ["storage/ndb/src/kernel", "libexec", "sbin", "bin"], "ndbd"); $exe_ndb_mgmd= - my_find_bin($basedir, + my_find_bin($bindir, ["storage/ndb/src/mgmsrv", "libexec", "sbin", "bin"], "ndb_mgmd"); $exe_ndb_waiter= - my_find_bin($basedir, + my_find_bin($bindir, ["storage/ndb/tools/", "bin"], "ndb_waiter"); @@ -2128,12 +2128,12 @@ sub environment_setup { if ( ! $opt_skip_ndbcluster ) { $ENV{'NDB_MGM'}= - my_find_bin($basedir, + my_find_bin($bindir, ["storage/ndb/src/mgmclient", "bin"], "ndb_mgm"); $ENV{'NDB_TOOLS_DIR'}= - my_find_dir($basedir, + my_find_dir($bindir, ["storage/ndb/tools", "bin"]); $ENV{'NDB_EXAMPLES_DIR'}= @@ -2141,7 +2141,7 @@ sub environment_setup { ["storage/ndb/ndbapi-examples", "bin"]); $ENV{'NDB_EXAMPLES_BINARY'}= - my_find_bin($basedir, + my_find_bin($bindir, ["storage/ndb/ndbapi-examples/ndbapi_simple", "bin"], "ndbapi_simple", NOT_REQUIRED); From 36fffdeaa22c7208d3744613a7bd7bbe6e49b394 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 12 Nov 2010 13:42:50 +0100 Subject: [PATCH 231/304] Bug#58074: ADD_VERSION_INFO cmake/mysql_version.cmake fails if LINK_FLAGS are modified Backport version info handling (Windows-specific) from next-mr. Instead of adding ".res" object as linker flag, add resource file (.rc) file to the source list. This is more obvious and less error prone method. --- cmake/install_macros.cmake | 2 -- cmake/libutils.cmake | 3 +++ cmake/mysql_add_executable.cmake | 2 +- cmake/mysql_version.cmake | 34 ++++++++------------------------ cmake/plugin.cmake | 1 + 5 files changed, 13 insertions(+), 29 deletions(-) diff --git a/cmake/install_macros.cmake b/cmake/install_macros.cmake index bc8d9945690..ddfbcd09ce4 100644 --- a/cmake/install_macros.cmake +++ b/cmake/install_macros.cmake @@ -224,8 +224,6 @@ FUNCTION(MYSQL_INSTALL_TARGETS) IF(SIGNCODE AND SIGNCODE_ENABLED) SIGN_TARGET(${target}) ENDIF() - # For Windows, add version info to executables - ADD_VERSION_INFO(${target}) # Install man pages on Unix IF(UNIX) GET_TARGET_PROPERTY(target_location ${target} LOCATION) diff --git a/cmake/libutils.cmake b/cmake/libutils.cmake index 0cc8895f43e..89eb5a74d80 100644 --- a/cmake/libutils.cmake +++ b/cmake/libutils.cmake @@ -250,6 +250,9 @@ MACRO(MERGE_LIBRARIES) ENDFOREACH() ENDIF() CREATE_EXPORT_FILE(SRC ${TARGET} "${ARG_EXPORTS}") + IF(NOT ARG_NOINSTALL) + ADD_VERSION_INFO(${TARGET} SHARED SRC) + ENDIF() ADD_LIBRARY(${TARGET} ${LIBTYPE} ${SRC}) TARGET_LINK_LIBRARIES(${TARGET} ${LIBS}) IF(ARG_OUTPUT_NAME) diff --git a/cmake/mysql_add_executable.cmake b/cmake/mysql_add_executable.cmake index b49a737716c..ac812fbcdfd 100644 --- a/cmake/mysql_add_executable.cmake +++ b/cmake/mysql_add_executable.cmake @@ -37,7 +37,7 @@ FUNCTION (MYSQL_ADD_EXECUTABLE) LIST(REMOVE_AT ARG_DEFAULT_ARGS 0) SET(sources ${ARG_DEFAULT_ARGS}) - + ADD_VERSION_INFO(${target} EXECUTABLE sources) ADD_EXECUTABLE(${target} ${ARG_WIN32} ${ARG_MACOSX_BUNDLE} ${ARG_EXCLUDE_FROM_ALL} ${sources}) # tell CPack where to install IF(NOT ARG_EXCLUDE_FROM_ALL) diff --git a/cmake/mysql_version.cmake b/cmake/mysql_version.cmake index 886d7b9e8a9..9f0f7729c22 100644 --- a/cmake/mysql_version.cmake +++ b/cmake/mysql_version.cmake @@ -133,9 +133,8 @@ ENDIF() # Refer to http://msdn.microsoft.com/en-us/library/aa381058(VS.85).aspx # for more info. IF(MSVC) - GET_TARGET_PROPERTY(location gen_versioninfo LOCATION) - IF(NOT location) GET_FILENAME_COMPONENT(MYSQL_CMAKE_SCRIPT_DIR ${CMAKE_CURRENT_LIST_FILE} PATH) + SET(FILETYPE VFT_APP) CONFIGURE_FILE(${MYSQL_CMAKE_SCRIPT_DIR}/versioninfo.rc.in ${CMAKE_BINARY_DIR}/versioninfo_exe.rc) @@ -143,31 +142,14 @@ IF(MSVC) SET(FILETYPE VFT_DLL) CONFIGURE_FILE(${MYSQL_CMAKE_SCRIPT_DIR}/versioninfo.rc.in ${CMAKE_BINARY_DIR}/versioninfo_dll.rc) - - ADD_CUSTOM_COMMAND( - OUTPUT ${CMAKE_BINARY_DIR}/versioninfo_exe.res - ${CMAKE_BINARY_DIR}/versioninfo_dll.res - COMMAND ${CMAKE_RC_COMPILER} versioninfo_exe.rc - COMMAND ${CMAKE_RC_COMPILER} versioninfo_dll.rc - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - ) - ADD_CUSTOM_TARGET(gen_versioninfo - DEPENDS - ${CMAKE_BINARY_DIR}/versioninfo_exe.res - ${CMAKE_BINARY_DIR}/versioninfo_dll.res - ) - ENDIF() - - FUNCTION(ADD_VERSION_INFO target) - GET_TARGET_PROPERTY(target_type ${target} TYPE) - ADD_DEPENDENCIES(${target} gen_versioninfo) - IF(target_type MATCHES "SHARED" OR target_type MATCHES "MODULE") - SET_PROPERTY(TARGET ${target} APPEND PROPERTY LINK_FLAGS - "\"${CMAKE_BINARY_DIR}/versioninfo_dll.res\"") - ELSEIF(target_type MATCHES "EXE") - SET_PROPERTY(TARGET ${target} APPEND PROPERTY LINK_FLAGS - "${target_link_flags} \"${CMAKE_BINARY_DIR}/versioninfo_exe.res\"") + + FUNCTION(ADD_VERSION_INFO target target_type sources_var) + IF("${target_type}" MATCHES "SHARED" OR "${target_type}" MATCHES "MODULE") + SET(rcfile ${CMAKE_BINARY_DIR}/versioninfo_dll.rc) + ELSEIF("${target_type}" MATCHES "EXE") + SET(rcfile ${CMAKE_BINARY_DIR}/versioninfo_exe.rc) ENDIF() + SET(${sources_var} ${${sources_var}} ${rcfile} PARENT_SCOPE) ENDFUNCTION() ELSE() FUNCTION(ADD_VERSION_INFO) diff --git a/cmake/plugin.cmake b/cmake/plugin.cmake index 94fdc8bf1e9..bf34407db25 100644 --- a/cmake/plugin.cmake +++ b/cmake/plugin.cmake @@ -151,6 +151,7 @@ MACRO(MYSQL_ADD_PLUGIN) ENDIF() ENDIF() + ADD_VERSION_INFO(${target} MODULE SOURCES) ADD_LIBRARY(${target} MODULE ${SOURCES}) DTRACE_INSTRUMENT(${target}) SET_TARGET_PROPERTIES (${target} PROPERTIES PREFIX "" From 78fa2e4d6d89b8d0bb4b26fe648668b97c9400b9 Mon Sep 17 00:00:00 2001 From: Konstantin Osipov Date: Fri, 12 Nov 2010 15:56:21 +0300 Subject: [PATCH 232/304] Implement a fix for Bug#57058 -- send SERVER_QUERY_WAS_SLOW over network when a query was slow. When a query is slow, sent a special flag to the client indicating this fact. Add a test case. Implement review comments. include/mysql_com.h: Clear SERVER_QUERY_WAS_SLOW at end of each statement. Since this patch removes the technique when thd->server_status is modified briefly only to execute my_eof(), reset more server status bit that may remain in the status from execution of the previous statement. sql/protocol.cc: Always use thd->server_status to in net_* functions to send the latest status to the client. sql/sp_head.cc: Calculate if a query was slow before sending EOF packet. sql/sql_cursor.cc: Remove juggling with thd->server_status. The extra status bits are reset at start of the next statement. sql/sql_db.cc: Remove juggling with thd->server_status. The extra status bits are reset at start of the next statement. sql/sql_error.cc: Remove m_server_status member, it's not really part of the Diagnostics_area. sql/sql_error.h: Remove server_status member, it's not part of the Diagnostics_area. The associated hack is removed as well. sql/sql_parse.cc: Do not calculate if a query was slow twice. Use a status flag in thd->server_status. tests/mysql_client_test.c: Add a test case for Bug#57058. Check that the status is present at the client, when sent. --- include/mysql_com.h | 6 +++++- sql/protocol.cc | 4 ++-- sql/sp_head.cc | 5 +++++ sql/sql_class.h | 14 +++++++++++++ sql/sql_cursor.cc | 3 --- sql/sql_db.cc | 1 - sql/sql_error.cc | 2 -- sql/sql_error.h | 15 -------------- sql/sql_parse.cc | 5 +++-- tests/mysql_client_test.c | 42 ++++++++++++++++++++++++++++++++++++++- 10 files changed, 70 insertions(+), 27 deletions(-) diff --git a/include/mysql_com.h b/include/mysql_com.h index d4223211710..bc9296a6d02 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -255,7 +255,11 @@ enum enum_server_command #define SERVER_STATUS_CLEAR_SET (SERVER_QUERY_NO_GOOD_INDEX_USED| \ SERVER_QUERY_NO_INDEX_USED|\ SERVER_MORE_RESULTS_EXISTS|\ - SERVER_STATUS_METADATA_CHANGED) + SERVER_STATUS_METADATA_CHANGED |\ + SERVER_QUERY_WAS_SLOW |\ + SERVER_STATUS_DB_DROPPED |\ + SERVER_STATUS_CURSOR_EXISTS|\ + SERVER_STATUS_LAST_ROW_SENT) #define MYSQL_ERRMSG_SIZE 512 #define NET_READ_TIMEOUT 30 /* Timeout on read */ diff --git a/sql/protocol.cc b/sql/protocol.cc index dd3a5d92a87..03b151e4346 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -505,11 +505,11 @@ void Protocol::end_statement() thd->stmt_da->get_sqlstate()); break; case Diagnostics_area::DA_EOF: - error= send_eof(thd->stmt_da->server_status(), + error= send_eof(thd->server_status, thd->stmt_da->statement_warn_count()); break; case Diagnostics_area::DA_OK: - error= send_ok(thd->stmt_da->server_status(), + error= send_ok(thd->server_status, thd->stmt_da->statement_warn_count(), thd->stmt_da->affected_rows(), thd->stmt_da->last_insert_id(), diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 47b698c3a2f..27238fa05d2 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -3100,7 +3100,12 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) res= m_lex_keeper.reset_lex_and_exec_core(thd, nextp, FALSE, this); if (thd->stmt_da->is_eof()) + { + /* Finalize server status flags after executing a statement. */ + thd->update_server_status(); + thd->protocol->end_statement(); + } query_cache_end_of_result(thd); diff --git a/sql/sql_class.h b/sql/sql_class.h index 8bf72f1cdb2..cc41595e56c 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2234,6 +2234,20 @@ public: } void set_time_after_lock() { utime_after_lock= my_micro_time(); } ulonglong current_utime() { return my_micro_time(); } + /** + Update server status after execution of a top level statement. + + Currently only checks if a query was slow, and assigns + the status accordingly. + Evaluate the current time, and if it exceeds the long-query-time + setting, mark the query as slow. + */ + void update_server_status() + { + ulonglong end_utime_of_query= current_utime(); + if (end_utime_of_query > utime_after_lock + variables.long_query_time) + server_status|= SERVER_QUERY_WAS_SLOW; + } inline ulonglong found_rows(void) { return limit_found_rows; diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc index 7a9834b4cde..acc591f1ea2 100644 --- a/sql/sql_cursor.cc +++ b/sql/sql_cursor.cc @@ -277,7 +277,6 @@ int Materialized_cursor::open(JOIN *join __attribute__((unused))) rc= result->send_result_set_metadata(item_list, Protocol::SEND_NUM_ROWS); thd->server_status|= SERVER_STATUS_CURSOR_EXISTS; result->send_eof(); - thd->server_status&= ~SERVER_STATUS_CURSOR_EXISTS; } return rc; } @@ -318,12 +317,10 @@ void Materialized_cursor::fetch(ulong num_rows) case 0: thd->server_status|= SERVER_STATUS_CURSOR_EXISTS; result->send_eof(); - thd->server_status&= ~SERVER_STATUS_CURSOR_EXISTS; break; case HA_ERR_END_OF_FILE: thd->server_status|= SERVER_STATUS_LAST_ROW_SENT; result->send_eof(); - thd->server_status&= ~SERVER_STATUS_LAST_ROW_SENT; close(); break; default: diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 4df8748429c..1dea2f279e9 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -866,7 +866,6 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) thd->clear_error(); thd->server_status|= SERVER_STATUS_DB_DROPPED; my_ok(thd, (ulong) deleted); - thd->server_status&= ~SERVER_STATUS_DB_DROPPED; } else if (mysql_bin_log.is_open()) { diff --git a/sql/sql_error.cc b/sql/sql_error.cc index 8c038e10a1f..f042a7cd164 100644 --- a/sql/sql_error.cc +++ b/sql/sql_error.cc @@ -365,7 +365,6 @@ Diagnostics_area::set_ok_status(THD *thd, ulonglong affected_rows_arg, if (is_error() || is_disabled()) return; - m_server_status= thd->server_status; m_statement_warn_count= thd->warning_info->statement_warn_count(); m_affected_rows= affected_rows_arg; m_last_insert_id= last_insert_id_arg; @@ -395,7 +394,6 @@ Diagnostics_area::set_eof_status(THD *thd) if (is_error() || is_disabled()) return; - m_server_status= thd->server_status; /* If inside a stored procedure, do not return the total number of warnings, since they are not available to the client diff --git a/sql/sql_error.h b/sql/sql_error.h index 87e98e27673..14dc5e6d12c 100644 --- a/sql/sql_error.h +++ b/sql/sql_error.h @@ -79,12 +79,6 @@ public: const char* get_sqlstate() const { DBUG_ASSERT(m_status == DA_ERROR); return m_sqlstate; } - uint server_status() const - { - DBUG_ASSERT(m_status == DA_OK || m_status == DA_EOF); - return m_server_status; - } - ulonglong affected_rows() const { DBUG_ASSERT(m_status == DA_OK); return m_affected_rows; } @@ -110,15 +104,6 @@ private: char m_sqlstate[SQLSTATE_LENGTH+1]; - /** - Copied from thd->server_status when the diagnostics area is assigned. - We need this member as some places in the code use the following pattern: - thd->server_status|= ... - my_eof(thd); - thd->server_status&= ~... - Assigned by OK, EOF or ERROR. - */ - uint m_server_status; /** The number of rows affected by the last statement. This is semantically close to thd->row_count_func, but has a different diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e95745634e8..4f4e26d1df0 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1438,8 +1438,7 @@ void log_slow_statement(THD *thd) ulonglong end_utime_of_query= thd->current_utime(); thd_proc_info(thd, "logging slow query"); - if (((end_utime_of_query - thd->utime_after_lock) > - thd->variables.long_query_time || + if (((thd->server_status & SERVER_QUERY_WAS_SLOW) || ((thd->server_status & (SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) && opt_log_queries_not_using_indexes && @@ -5505,6 +5504,8 @@ void mysql_parse(THD *thd, char *rawbuf, uint length, thd->end_statement(); thd->cleanup_after_query(); DBUG_ASSERT(thd->change_list.is_empty()); + /* Finalize server status flags after executing a statement. */ + thd->update_server_status(); } DBUG_VOID_RETURN; diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index b85a6c587e4..3d709720727 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -19061,7 +19061,7 @@ static void test_bug49972() my_bool is_null; DBUG_ENTER("test_bug49972"); - myheader("test_49972"); + myheader("test_bug49972"); rc= mysql_query(mysql, "DROP FUNCTION IF EXISTS f1"); myquery(rc); @@ -19148,6 +19148,45 @@ static void test_bug49972() DBUG_VOID_RETURN; } + +/** + Bug#57058 SERVER_QUERY_WAS_SLOW not wired up. +*/ + +static void test_bug57058() +{ + MYSQL_RES *res; + int rc; + + DBUG_ENTER("test_bug57058"); + myheader("test_bug57058"); + + rc= mysql_query(mysql, "set @@session.long_query_time=0.1"); + myquery(rc); + + DIE_UNLESS(!(mysql->server_status & SERVER_QUERY_WAS_SLOW)); + + rc= mysql_query(mysql, "select sleep(1)"); + myquery(rc); + + /* + Important: the flag is sent in the last EOF packet of + the query, the one which ends the result. Read the + result to see the "slow" status. + */ + res= mysql_store_result(mysql); + + DIE_UNLESS(mysql->server_status & SERVER_QUERY_WAS_SLOW); + + mysql_free_result(res); + + rc= mysql_query(mysql, "set @@session.long_query_time=default"); + myquery(rc); + + DBUG_VOID_RETURN; +} + + /* Read and parse arguments and MySQL options from my.cnf */ @@ -19481,6 +19520,7 @@ static struct my_tests_st my_tests[]= { { "test_bug42373", test_bug42373 }, { "test_bug54041", test_bug54041 }, { "test_bug47485", test_bug47485 }, + { "test_bug57058", test_bug57058 }, { 0, 0 } }; From 2f5b308f3b073444f45a3739f0fada20d71cc2d8 Mon Sep 17 00:00:00 2001 From: Dmitry Lenev Date: Fri, 12 Nov 2010 16:57:08 +0300 Subject: [PATCH 233/304] Follow-up for patch fixing bug #57006 "Deadlock between HANDLER and FLUSH TABLES WITH READ LOCK" and bug #54673 "It takes too long to get readlock for 'FLUSH TABLES WITH READ LOCK'". Disable execution of flush_read_lock.test on embedded server. This test uses too many statements which are not supported by embedded server. --- mysql-test/t/flush_read_lock.test | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mysql-test/t/flush_read_lock.test b/mysql-test/t/flush_read_lock.test index b234d941e6e..dbb1dd7cb49 100644 --- a/mysql-test/t/flush_read_lock.test +++ b/mysql-test/t/flush_read_lock.test @@ -7,6 +7,9 @@ --source include/have_innodb.inc # We need the Debug Sync Facility. --source include/have_debug_sync.inc +# Parts of this test use DDL on events, BINLOG statement and +# other statements which are not supported in embedded server. +-- source include/not_embedded.inc # Save the initial number of concurrent sessions. --source include/count_sessions.inc From 86bc11a54f99b14bfca6e300f75118660d0db6bc Mon Sep 17 00:00:00 2001 From: Konstantin Osipov Date: Fri, 12 Nov 2010 17:20:12 +0300 Subject: [PATCH 234/304] Fix a compilation failure of non-debug build introduced by the patch for Bug#57058. sql/sql_error.cc: Delete assignment of a removed class member. --- sql/sql_error.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/sql/sql_error.cc b/sql/sql_error.cc index f042a7cd164..d0982b879e7 100644 --- a/sql/sql_error.cc +++ b/sql/sql_error.cc @@ -334,7 +334,6 @@ Diagnostics_area::reset_diagnostics_area() /** Don't take chances in production */ m_message[0]= '\0'; m_sql_errno= 0; - m_server_status= 0; m_affected_rows= 0; m_last_insert_id= 0; m_statement_warn_count= 0; From b4d5039e717bc02a94a42f5511e7077404a31d72 Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Fri, 12 Nov 2010 22:22:55 +0100 Subject: [PATCH 235/304] Patch for bug#57596 MySQL-shared RPM no longer provides mysql-shared The spec file is changed to explicitly "provide" "mysql-shared" by the "shared" sub-RPM. --- support-files/mysql.spec.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 53178bb4d96..595586962ba 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -335,6 +335,7 @@ For a description of MySQL see the base MySQL RPM or http://www.mysql.com/ %package -n MySQL-shared%{product_suffix} Summary: MySQL - Shared libraries Group: Applications/Databases +Provides: mysql-shared Obsoletes: MySQL-shared-community %description -n MySQL-shared%{product_suffix} From 3fa437cf4061c20f2995e859b89a6898d3b646b4 Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Sat, 13 Nov 2010 18:05:02 +0300 Subject: [PATCH 236/304] Fix for Bug#56934 (mysql_stmt_fetch() incorrectly fills MYSQL_TIME structure buffer). This is a follow-up for WL#4435. The bug actually existed not only MYSQL_TYPE_DATETIME type. The problem was that Item_param::set_value() was written in an assumption that it's working with expressions, i.e. with basic data types. There are two different quick fixes here: a) Change Item_param::make_field() -- remove setting of Send_field::length, Send_field::charsetnr, Send_field::flags and Send_field::type. That would lead to marshalling all data using basic types to the client (MYSQL_TYPE_LONGLONG, MYSQL_TYPE_DOUBLE, MYSQL_TYPE_STRING and MYSQL_TYPE_NEWDECIMAL). In particular, that means, DATETIME would be sent as MYSQL_TYPE_STRING, TINYINT -- as MYSQL_TYPE_LONGLONG, etc. That could be Ok for the client, because the client library does reverse conversion automatically (the client program would see DATETIME as MYSQL_TIME object). However, there is a problem with metadata -- the metadata would be wrong (misleading): it would say that DATETIME is marshaled as MYSQL_TYPE_DATETIME, not as MYSQL_TYPE_STRING. b) Set Item_param::param_type properly to actual underlying field type. That would lead to double conversion inside the server: for example, MYSQL_TIME-object would be converted into STRING-object (in Item_param::set_value()), and then converted back to MYSQL_TIME-object (in Item_param::send()). The data however would be marshalled more properly, and also metadata would be correct. This patch implements b). There is also a possibility to avoid double conversion either by clonning the data field, or by storing a reference to it and using it on Item::send() time. That requires more work and might be done later. --- mysql-test/r/ps.result | 504 +++++++++++++++++++++++++ mysql-test/t/ps.test | 6 + mysql-test/t/wl4435_generated.inc | 588 ++++++++++++++++++++++++++++++ sql/item.cc | 9 +- sql/sp_rcontext.h | 1 + sql/sql_prepare.cc | 2 +- tests/mysql_client_test.c | 250 +++++++++++++ 7 files changed, 1352 insertions(+), 8 deletions(-) create mode 100644 mysql-test/t/wl4435_generated.inc diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 33282823931..17f639cdca3 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -3202,6 +3202,510 @@ test1 DROP PROCEDURE p1; DROP PROCEDURE p2; +TINYINT + +CREATE PROCEDURE p1(OUT v TINYINT) +SET v = 127; +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; +SHOW CREATE TABLE tmp1; +Table Create Table +tmp1 CREATE TEMPORARY TABLE `tmp1` ( + `c1` bigint(20) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT @a, @a = 127; +@a @a = 127 +127 1 +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +SMALLINT + +CREATE PROCEDURE p1(OUT v SMALLINT) +SET v = 32767; +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; +SHOW CREATE TABLE tmp1; +Table Create Table +tmp1 CREATE TEMPORARY TABLE `tmp1` ( + `c1` bigint(20) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT @a, @a = 32767; +@a @a = 32767 +32767 1 +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +MEDIUMINT + +CREATE PROCEDURE p1(OUT v MEDIUMINT) +SET v = 8388607; +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; +SHOW CREATE TABLE tmp1; +Table Create Table +tmp1 CREATE TEMPORARY TABLE `tmp1` ( + `c1` bigint(20) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT @a, @a = 8388607; +@a @a = 8388607 +8388607 1 +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +INT + +CREATE PROCEDURE p1(OUT v INT) +SET v = 2147483647; +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; +SHOW CREATE TABLE tmp1; +Table Create Table +tmp1 CREATE TEMPORARY TABLE `tmp1` ( + `c1` bigint(20) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT @a, @a = 2147483647; +@a @a = 2147483647 +2147483647 1 +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +BIGINT + +CREATE PROCEDURE p1(OUT v BIGINT) +SET v = 9223372036854775807; +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; +SHOW CREATE TABLE tmp1; +Table Create Table +tmp1 CREATE TEMPORARY TABLE `tmp1` ( + `c1` bigint(20) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT @a, @a = 9223372036854775807; +@a @a = 9223372036854775807 +9223372036854775807 1 +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +BIT(11) + +CREATE PROCEDURE p1(OUT v BIT(11)) +SET v = b'10100100101'; +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; +SHOW CREATE TABLE tmp1; +Table Create Table +tmp1 CREATE TEMPORARY TABLE `tmp1` ( + `c1` bigint(20) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT @a, @a = b'10100100101'; +@a @a = b'10100100101' +1317 1 +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +TIMESTAMP + +CREATE PROCEDURE p1(OUT v TIMESTAMP) +SET v = '2007-11-18 15:01:02'; +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; +SHOW CREATE TABLE tmp1; +Table Create Table +tmp1 CREATE TEMPORARY TABLE `tmp1` ( + `c1` longblob +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT @a, @a = '2007-11-18 15:01:02'; +@a @a = '2007-11-18 15:01:02' +2007-11-18 15:01:02 1 +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +DATETIME + +CREATE PROCEDURE p1(OUT v DATETIME) +SET v = '1234-11-12 12:34:59'; +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; +SHOW CREATE TABLE tmp1; +Table Create Table +tmp1 CREATE TEMPORARY TABLE `tmp1` ( + `c1` longblob +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT @a, @a = '1234-11-12 12:34:59'; +@a @a = '1234-11-12 12:34:59' +1234-11-12 12:34:59 1 +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +TIME + +CREATE PROCEDURE p1(OUT v TIME) +SET v = '123:45:01'; +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; +SHOW CREATE TABLE tmp1; +Table Create Table +tmp1 CREATE TEMPORARY TABLE `tmp1` ( + `c1` longblob +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT @a, @a = '123:45:01'; +@a @a = '123:45:01' +123:45:01 1 +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +DATE + +CREATE PROCEDURE p1(OUT v DATE) +SET v = '1234-11-12'; +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; +SHOW CREATE TABLE tmp1; +Table Create Table +tmp1 CREATE TEMPORARY TABLE `tmp1` ( + `c1` longblob +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT @a, @a = '1234-11-12'; +@a @a = '1234-11-12' +1234-11-12 1 +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +YEAR + +CREATE PROCEDURE p1(OUT v YEAR) +SET v = 2010; +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; +SHOW CREATE TABLE tmp1; +Table Create Table +tmp1 CREATE TEMPORARY TABLE `tmp1` ( + `c1` bigint(20) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT @a, @a = 2010; +@a @a = 2010 +2010 1 +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +FLOAT(7, 4) + +CREATE PROCEDURE p1(OUT v FLOAT(7, 4)) +SET v = 123.4567; +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; +SHOW CREATE TABLE tmp1; +Table Create Table +tmp1 CREATE TEMPORARY TABLE `tmp1` ( + `c1` double DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT @a, @a - 123.4567 < 0.00001; +@a @a - 123.4567 < 0.00001 +123.45670318603516 1 +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +DOUBLE(8, 5) + +CREATE PROCEDURE p1(OUT v DOUBLE(8, 5)) +SET v = 123.45678; +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; +SHOW CREATE TABLE tmp1; +Table Create Table +tmp1 CREATE TEMPORARY TABLE `tmp1` ( + `c1` double DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT @a, @a - 123.45678 < 0.000001; +@a @a - 123.45678 < 0.000001 +123.45678 1 +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +DECIMAL(9, 6) + +CREATE PROCEDURE p1(OUT v DECIMAL(9, 6)) +SET v = 123.456789; +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; +SHOW CREATE TABLE tmp1; +Table Create Table +tmp1 CREATE TEMPORARY TABLE `tmp1` ( + `c1` decimal(65,30) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT @a, @a = 123.456789; +@a @a = 123.456789 +123.456789 1 +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +CHAR(32) + +CREATE PROCEDURE p1(OUT v CHAR(32)) +SET v = REPEAT('a', 16); +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; +SHOW CREATE TABLE tmp1; +Table Create Table +tmp1 CREATE TEMPORARY TABLE `tmp1` ( + `c1` longblob +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT @a, @a = REPEAT('a', 16); +@a @a = REPEAT('a', 16) +aaaaaaaaaaaaaaaa 1 +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +VARCHAR(32) + +CREATE PROCEDURE p1(OUT v VARCHAR(32)) +SET v = REPEAT('b', 16); +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; +SHOW CREATE TABLE tmp1; +Table Create Table +tmp1 CREATE TEMPORARY TABLE `tmp1` ( + `c1` longblob +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT @a, @a = REPEAT('b', 16); +@a @a = REPEAT('b', 16) +bbbbbbbbbbbbbbbb 1 +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +TINYTEXT + +CREATE PROCEDURE p1(OUT v TINYTEXT) +SET v = REPEAT('c', 16); +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; +SHOW CREATE TABLE tmp1; +Table Create Table +tmp1 CREATE TEMPORARY TABLE `tmp1` ( + `c1` longblob +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT @a, @a = REPEAT('c', 16); +@a @a = REPEAT('c', 16) +cccccccccccccccc 1 +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +TEXT + +CREATE PROCEDURE p1(OUT v TEXT) +SET v = REPEAT('d', 16); +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; +SHOW CREATE TABLE tmp1; +Table Create Table +tmp1 CREATE TEMPORARY TABLE `tmp1` ( + `c1` longblob +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT @a, @a = REPEAT('d', 16); +@a @a = REPEAT('d', 16) +dddddddddddddddd 1 +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +MEDIUMTEXT + +CREATE PROCEDURE p1(OUT v MEDIUMTEXT) +SET v = REPEAT('e', 16); +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; +SHOW CREATE TABLE tmp1; +Table Create Table +tmp1 CREATE TEMPORARY TABLE `tmp1` ( + `c1` longblob +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT @a, @a = REPEAT('e', 16); +@a @a = REPEAT('e', 16) +eeeeeeeeeeeeeeee 1 +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +LONGTEXT + +CREATE PROCEDURE p1(OUT v LONGTEXT) +SET v = REPEAT('f', 16); +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; +SHOW CREATE TABLE tmp1; +Table Create Table +tmp1 CREATE TEMPORARY TABLE `tmp1` ( + `c1` longblob +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT @a, @a = REPEAT('f', 16); +@a @a = REPEAT('f', 16) +ffffffffffffffff 1 +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +BINARY(32) + +CREATE PROCEDURE p1(OUT v BINARY(32)) +SET v = REPEAT('g', 32); +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; +SHOW CREATE TABLE tmp1; +Table Create Table +tmp1 CREATE TEMPORARY TABLE `tmp1` ( + `c1` longblob +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT @a, @a = REPEAT('g', 32); +@a @a = REPEAT('g', 32) +gggggggggggggggggggggggggggggggg 1 +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +VARBINARY(32) + +CREATE PROCEDURE p1(OUT v VARBINARY(32)) +SET v = REPEAT('h', 16); +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; +SHOW CREATE TABLE tmp1; +Table Create Table +tmp1 CREATE TEMPORARY TABLE `tmp1` ( + `c1` longblob +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT @a, @a = REPEAT('h', 16); +@a @a = REPEAT('h', 16) +hhhhhhhhhhhhhhhh 1 +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +TINYBLOB + +CREATE PROCEDURE p1(OUT v TINYBLOB) +SET v = REPEAT('i', 16); +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; +SHOW CREATE TABLE tmp1; +Table Create Table +tmp1 CREATE TEMPORARY TABLE `tmp1` ( + `c1` longblob +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT @a, @a = REPEAT('i', 16); +@a @a = REPEAT('i', 16) +iiiiiiiiiiiiiiii 1 +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +BLOB + +CREATE PROCEDURE p1(OUT v BLOB) +SET v = REPEAT('j', 16); +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; +SHOW CREATE TABLE tmp1; +Table Create Table +tmp1 CREATE TEMPORARY TABLE `tmp1` ( + `c1` longblob +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT @a, @a = REPEAT('j', 16); +@a @a = REPEAT('j', 16) +jjjjjjjjjjjjjjjj 1 +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +MEDIUMBLOB + +CREATE PROCEDURE p1(OUT v MEDIUMBLOB) +SET v = REPEAT('k', 16); +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; +SHOW CREATE TABLE tmp1; +Table Create Table +tmp1 CREATE TEMPORARY TABLE `tmp1` ( + `c1` longblob +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT @a, @a = REPEAT('k', 16); +@a @a = REPEAT('k', 16) +kkkkkkkkkkkkkkkk 1 +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +LONGBLOB + +CREATE PROCEDURE p1(OUT v LONGBLOB) +SET v = REPEAT('l', 16); +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; +SHOW CREATE TABLE tmp1; +Table Create Table +tmp1 CREATE TEMPORARY TABLE `tmp1` ( + `c1` longblob +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT @a, @a = REPEAT('l', 16); +@a @a = REPEAT('l', 16) +llllllllllllllll 1 +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +SET('aaa', 'bbb') + +CREATE PROCEDURE p1(OUT v SET('aaa', 'bbb')) +SET v = 'aaa'; +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; +SHOW CREATE TABLE tmp1; +Table Create Table +tmp1 CREATE TEMPORARY TABLE `tmp1` ( + `c1` longblob +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT @a, @a = 'aaa'; +@a @a = 'aaa' +aaa 1 +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +ENUM('aaa', 'bbb') + +CREATE PROCEDURE p1(OUT v ENUM('aaa', 'bbb')) +SET v = 'aaa'; +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; +SHOW CREATE TABLE tmp1; +Table Create Table +tmp1 CREATE TEMPORARY TABLE `tmp1` ( + `c1` longblob +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT @a, @a = 'aaa'; +@a @a = 'aaa' +aaa 1 +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + # End of WL#4435. # # WL#4284: Transactional DDL locking diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index bf15648951b..eaef1cf3000 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -3296,6 +3296,12 @@ SELECT @a; DROP PROCEDURE p1; DROP PROCEDURE p2; +########################################################################### + +--source t/wl4435_generated.inc + +########################################################################### + --echo --echo # End of WL#4435. diff --git a/mysql-test/t/wl4435_generated.inc b/mysql-test/t/wl4435_generated.inc new file mode 100644 index 00000000000..5ea05a89402 --- /dev/null +++ b/mysql-test/t/wl4435_generated.inc @@ -0,0 +1,588 @@ + +########################################################################### + +--echo +--echo TINYINT +--echo + +CREATE PROCEDURE p1(OUT v TINYINT) + SET v = 127; + +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; + +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; + +SHOW CREATE TABLE tmp1; + +SELECT @a, @a = 127; + +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +########################################################################### + +--echo +--echo SMALLINT +--echo + +CREATE PROCEDURE p1(OUT v SMALLINT) + SET v = 32767; + +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; + +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; + +SHOW CREATE TABLE tmp1; + +SELECT @a, @a = 32767; + +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +########################################################################### + +--echo +--echo MEDIUMINT +--echo + +CREATE PROCEDURE p1(OUT v MEDIUMINT) + SET v = 8388607; + +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; + +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; + +SHOW CREATE TABLE tmp1; + +SELECT @a, @a = 8388607; + +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +########################################################################### + +--echo +--echo INT +--echo + +CREATE PROCEDURE p1(OUT v INT) + SET v = 2147483647; + +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; + +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; + +SHOW CREATE TABLE tmp1; + +SELECT @a, @a = 2147483647; + +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +########################################################################### + +--echo +--echo BIGINT +--echo + +CREATE PROCEDURE p1(OUT v BIGINT) + SET v = 9223372036854775807; + +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; + +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; + +SHOW CREATE TABLE tmp1; + +SELECT @a, @a = 9223372036854775807; + +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +########################################################################### + +--echo +--echo BIT(11) +--echo + +CREATE PROCEDURE p1(OUT v BIT(11)) + SET v = b'10100100101'; + +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; + +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; + +SHOW CREATE TABLE tmp1; + +SELECT @a, @a = b'10100100101'; + +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +########################################################################### + +--echo +--echo TIMESTAMP +--echo + +CREATE PROCEDURE p1(OUT v TIMESTAMP) + SET v = '2007-11-18 15:01:02'; + +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; + +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; + +SHOW CREATE TABLE tmp1; + +SELECT @a, @a = '2007-11-18 15:01:02'; + +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +########################################################################### + +--echo +--echo DATETIME +--echo + +CREATE PROCEDURE p1(OUT v DATETIME) + SET v = '1234-11-12 12:34:59'; + +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; + +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; + +SHOW CREATE TABLE tmp1; + +SELECT @a, @a = '1234-11-12 12:34:59'; + +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +########################################################################### + +--echo +--echo TIME +--echo + +CREATE PROCEDURE p1(OUT v TIME) + SET v = '123:45:01'; + +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; + +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; + +SHOW CREATE TABLE tmp1; + +SELECT @a, @a = '123:45:01'; + +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +########################################################################### + +--echo +--echo DATE +--echo + +CREATE PROCEDURE p1(OUT v DATE) + SET v = '1234-11-12'; + +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; + +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; + +SHOW CREATE TABLE tmp1; + +SELECT @a, @a = '1234-11-12'; + +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +########################################################################### + +--echo +--echo YEAR +--echo + +CREATE PROCEDURE p1(OUT v YEAR) + SET v = 2010; + +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; + +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; + +SHOW CREATE TABLE tmp1; + +SELECT @a, @a = 2010; + +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +########################################################################### + +--echo +--echo FLOAT(7, 4) +--echo + +CREATE PROCEDURE p1(OUT v FLOAT(7, 4)) + SET v = 123.4567; + +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; + +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; + +SHOW CREATE TABLE tmp1; + +SELECT @a, @a - 123.4567 < 0.00001; + +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +########################################################################### + +--echo +--echo DOUBLE(8, 5) +--echo + +CREATE PROCEDURE p1(OUT v DOUBLE(8, 5)) + SET v = 123.45678; + +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; + +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; + +SHOW CREATE TABLE tmp1; + +SELECT @a, @a - 123.45678 < 0.000001; + +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +########################################################################### + +--echo +--echo DECIMAL(9, 6) +--echo + +CREATE PROCEDURE p1(OUT v DECIMAL(9, 6)) + SET v = 123.456789; + +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; + +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; + +SHOW CREATE TABLE tmp1; + +SELECT @a, @a = 123.456789; + +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +########################################################################### + +--echo +--echo CHAR(32) +--echo + +CREATE PROCEDURE p1(OUT v CHAR(32)) + SET v = REPEAT('a', 16); + +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; + +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; + +SHOW CREATE TABLE tmp1; + +SELECT @a, @a = REPEAT('a', 16); + +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +########################################################################### + +--echo +--echo VARCHAR(32) +--echo + +CREATE PROCEDURE p1(OUT v VARCHAR(32)) + SET v = REPEAT('b', 16); + +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; + +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; + +SHOW CREATE TABLE tmp1; + +SELECT @a, @a = REPEAT('b', 16); + +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +########################################################################### + +--echo +--echo TINYTEXT +--echo + +CREATE PROCEDURE p1(OUT v TINYTEXT) + SET v = REPEAT('c', 16); + +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; + +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; + +SHOW CREATE TABLE tmp1; + +SELECT @a, @a = REPEAT('c', 16); + +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +########################################################################### + +--echo +--echo TEXT +--echo + +CREATE PROCEDURE p1(OUT v TEXT) + SET v = REPEAT('d', 16); + +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; + +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; + +SHOW CREATE TABLE tmp1; + +SELECT @a, @a = REPEAT('d', 16); + +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +########################################################################### + +--echo +--echo MEDIUMTEXT +--echo + +CREATE PROCEDURE p1(OUT v MEDIUMTEXT) + SET v = REPEAT('e', 16); + +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; + +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; + +SHOW CREATE TABLE tmp1; + +SELECT @a, @a = REPEAT('e', 16); + +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +########################################################################### + +--echo +--echo LONGTEXT +--echo + +CREATE PROCEDURE p1(OUT v LONGTEXT) + SET v = REPEAT('f', 16); + +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; + +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; + +SHOW CREATE TABLE tmp1; + +SELECT @a, @a = REPEAT('f', 16); + +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +########################################################################### + +--echo +--echo BINARY(32) +--echo + +CREATE PROCEDURE p1(OUT v BINARY(32)) + SET v = REPEAT('g', 32); + +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; + +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; + +SHOW CREATE TABLE tmp1; + +SELECT @a, @a = REPEAT('g', 32); + +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +########################################################################### + +--echo +--echo VARBINARY(32) +--echo + +CREATE PROCEDURE p1(OUT v VARBINARY(32)) + SET v = REPEAT('h', 16); + +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; + +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; + +SHOW CREATE TABLE tmp1; + +SELECT @a, @a = REPEAT('h', 16); + +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +########################################################################### + +--echo +--echo TINYBLOB +--echo + +CREATE PROCEDURE p1(OUT v TINYBLOB) + SET v = REPEAT('i', 16); + +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; + +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; + +SHOW CREATE TABLE tmp1; + +SELECT @a, @a = REPEAT('i', 16); + +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +########################################################################### + +--echo +--echo BLOB +--echo + +CREATE PROCEDURE p1(OUT v BLOB) + SET v = REPEAT('j', 16); + +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; + +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; + +SHOW CREATE TABLE tmp1; + +SELECT @a, @a = REPEAT('j', 16); + +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +########################################################################### + +--echo +--echo MEDIUMBLOB +--echo + +CREATE PROCEDURE p1(OUT v MEDIUMBLOB) + SET v = REPEAT('k', 16); + +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; + +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; + +SHOW CREATE TABLE tmp1; + +SELECT @a, @a = REPEAT('k', 16); + +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +########################################################################### + +--echo +--echo LONGBLOB +--echo + +CREATE PROCEDURE p1(OUT v LONGBLOB) + SET v = REPEAT('l', 16); + +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; + +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; + +SHOW CREATE TABLE tmp1; + +SELECT @a, @a = REPEAT('l', 16); + +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +########################################################################### + +--echo +--echo SET('aaa', 'bbb') +--echo + +CREATE PROCEDURE p1(OUT v SET('aaa', 'bbb')) + SET v = 'aaa'; + +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; + +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; + +SHOW CREATE TABLE tmp1; + +SELECT @a, @a = 'aaa'; + +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; + +########################################################################### + +--echo +--echo ENUM('aaa', 'bbb') +--echo + +CREATE PROCEDURE p1(OUT v ENUM('aaa', 'bbb')) + SET v = 'aaa'; + +PREPARE stmt1 FROM 'CALL p1(?)'; +EXECUTE stmt1 USING @a; + +CREATE TEMPORARY TABLE tmp1 AS SELECT @a AS c1; + +SHOW CREATE TABLE tmp1; + +SELECT @a, @a = 'aaa'; + +DROP TEMPORARY TABLE tmp1; +DROP PROCEDURE p1; diff --git a/sql/item.cc b/sql/item.cc index 3594bf45798..71e495fd259 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -226,8 +226,6 @@ bool Item::val_bool() */ String *Item::val_str_ascii(String *str) { - DBUG_ASSERT(fixed == 1); - if (!(collation.collation->state & MY_CS_NONASCII)) return val_str(str); @@ -3459,19 +3457,16 @@ Item_param::set_value(THD *thd, sp_rcontext *ctx, Item **it) str_value.charset()); collation.set(str_value.charset(), DERIVATION_COERCIBLE); decimals= 0; - param_type= MYSQL_TYPE_STRING; break; } case REAL_RESULT: set_double(arg->val_real()); - param_type= MYSQL_TYPE_DOUBLE; break; case INT_RESULT: set_int(arg->val_int(), arg->max_length); - param_type= MYSQL_TYPE_LONG; break; case DECIMAL_RESULT: @@ -3483,8 +3478,6 @@ Item_param::set_value(THD *thd, sp_rcontext *ctx, Item **it) return TRUE; set_decimal(dv); - param_type= MYSQL_TYPE_NEWDECIMAL; - break; } @@ -3516,6 +3509,7 @@ void Item_param::set_out_param_info(Send_field *info) { m_out_param_info= info; + param_type= m_out_param_info->type; } @@ -3561,6 +3555,7 @@ void Item_param::make_field(Send_field *field) field->org_table_name= m_out_param_info->org_table_name; field->col_name= m_out_param_info->col_name; field->org_col_name= m_out_param_info->org_col_name; + field->length= m_out_param_info->length; field->charsetnr= m_out_param_info->charsetnr; field->flags= m_out_param_info->flags; diff --git a/sql/sp_rcontext.h b/sql/sp_rcontext.h index 1af758ed0af..ec8d82063e4 100644 --- a/sql/sp_rcontext.h +++ b/sql/sp_rcontext.h @@ -220,6 +220,7 @@ private: during execution. */ bool m_return_value_set; + /** TRUE if the context is created for a sub-statement. */ diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index fcbf2c48896..6a84d050d7f 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1185,7 +1185,7 @@ static bool insert_params_from_vars_with_log(Prepared_statement *stmt, uint32 length= 0; THD *thd= stmt->thd; - DBUG_ENTER("insert_params_from_vars"); + DBUG_ENTER("insert_params_from_vars_with_log"); if (query->copy(stmt->query(), stmt->query_length(), default_charset_info)) DBUG_RETURN(1); diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index b85a6c587e4..5ddf428602b 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -2103,6 +2103,255 @@ static void test_wl4435_2() } +#define WL4435_TEST(sql_type, sql_value, \ + c_api_in_type, c_api_out_type, \ + c_type, c_type_ext, \ + printf_args, assert_condition) \ +\ + do { \ + int rc; \ + MYSQL_STMT *ps; \ + MYSQL_BIND psp; \ + MYSQL_RES *rs_metadata; \ + MYSQL_FIELD *fields; \ + c_type pspv c_type_ext; \ + my_bool psp_null; \ + \ + bzero(&pspv, sizeof (pspv)); \ + \ + rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1"); \ + myquery(rc); \ + \ + rc= mysql_query(mysql, \ + "CREATE PROCEDURE p1(OUT v " sql_type ") SET v = " sql_value ";"); \ + myquery(rc); \ + \ + ps = mysql_simple_prepare(mysql, "CALL p1(?)"); \ + check_stmt(ps); \ + \ + bzero(&psp, sizeof (psp)); \ + psp.buffer_type= c_api_in_type; \ + psp.is_null= &psp_null; \ + psp.buffer= (char *) &pspv; \ + psp.buffer_length= sizeof (psp); \ + \ + rc= mysql_stmt_bind_param(ps, &psp); \ + check_execute(ps, rc); \ + \ + rc= mysql_stmt_execute(ps); \ + check_execute(ps, rc); \ + \ + DIE_UNLESS(mysql->server_status & SERVER_PS_OUT_PARAMS); \ + DIE_UNLESS(mysql_stmt_field_count(ps) == 1); \ + \ + rs_metadata= mysql_stmt_result_metadata(ps); \ + fields= mysql_fetch_fields(rs_metadata); \ + \ + rc= mysql_stmt_bind_result(ps, &psp); \ + check_execute(ps, rc); \ + \ + rc= mysql_stmt_fetch(ps); \ + DIE_UNLESS(rc == 0); \ + \ + DIE_UNLESS(fields[0].type == c_api_out_type); \ + printf printf_args; \ + printf("; in type: %d; out type: %d\n", \ + (int) c_api_in_type, (int) c_api_out_type); \ + \ + rc= mysql_stmt_fetch(ps); \ + DIE_UNLESS(rc == MYSQL_NO_DATA); \ + \ + rc= mysql_stmt_next_result(ps); \ + DIE_UNLESS(rc == 0); \ + \ + mysql_stmt_free_result(ps); \ + mysql_stmt_close(ps); \ + \ + DIE_UNLESS(assert_condition); \ + \ + } while (0) + +static void test_wl4435_3() +{ + char tmp[255]; + + puts(""); + + // The following types are not supported: + // - ENUM + // - SET + // + // The following types are supported but can not be used for + // OUT-parameters: + // - MEDIUMINT; + // - BIT(..); + // + // The problem is that those types are not supported for IN-parameters, + // and OUT-parameters should be bound as IN-parameters before execution. + // + // The following types should not be used: + // - MYSQL_TYPE_YEAR (use MYSQL_TYPE_SHORT instead); + // - MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB + // (use MYSQL_TYPE_BLOB instead); + + WL4435_TEST("TINYINT", "127", + MYSQL_TYPE_TINY, MYSQL_TYPE_TINY, + char, , + (" - TINYINT / char / MYSQL_TYPE_TINY:\t\t\t %d", (int) pspv), + pspv == 127); + + WL4435_TEST("SMALLINT", "32767", + MYSQL_TYPE_SHORT, MYSQL_TYPE_SHORT, + short, , + (" - SMALLINT / short / MYSQL_TYPE_SHORT:\t\t %d", (int) pspv), + pspv == 32767); + + WL4435_TEST("INT", "2147483647", + MYSQL_TYPE_LONG, MYSQL_TYPE_LONG, + int, , + (" - INT / int / MYSQL_TYPE_LONG:\t\t\t %d", pspv), + pspv == 2147483647l); + + WL4435_TEST("BIGINT", "9223372036854775807", + MYSQL_TYPE_LONGLONG, MYSQL_TYPE_LONGLONG, + long long, , + (" - BIGINT / long long / MYSQL_TYPE_LONGLONG:\t\t %lld", pspv), + pspv == 9223372036854775807ll); + + WL4435_TEST("TIMESTAMP", "'2007-11-18 15:01:02'", + MYSQL_TYPE_TIMESTAMP, MYSQL_TYPE_TIMESTAMP, + MYSQL_TIME, , + (" - TIMESTAMP / MYSQL_TIME / MYSQL_TYPE_TIMESTAMP:\t " + "%.4d-%.2d-%.2d %.2d:%.2d:%.2d", + (int) pspv.year, (int) pspv.month, (int) pspv.day, + (int) pspv.hour, (int) pspv.minute, (int) pspv.second), + pspv.year == 2007 && pspv.month == 11 && pspv.day == 18 && + pspv.hour == 15 && pspv.minute == 1 && pspv.second == 2); + + WL4435_TEST("DATETIME", "'1234-11-12 12:34:59'", + MYSQL_TYPE_DATETIME, MYSQL_TYPE_DATETIME, + MYSQL_TIME, , + (" - DATETIME / MYSQL_TIME / MYSQL_TYPE_DATETIME:\t " + "%.4d-%.2d-%.2d %.2d:%.2d:%.2d", + (int) pspv.year, (int) pspv.month, (int) pspv.day, + (int) pspv.hour, (int) pspv.minute, (int) pspv.second), + pspv.year == 1234 && pspv.month == 11 && pspv.day == 12 && + pspv.hour == 12 && pspv.minute == 34 && pspv.second == 59); + + WL4435_TEST("TIME", "'123:45:01'", + MYSQL_TYPE_TIME, MYSQL_TYPE_TIME, + MYSQL_TIME, , + (" - TIME / MYSQL_TIME / MYSQL_TYPE_TIME:\t\t " + "%.3d:%.2d:%.2d", + (int) pspv.hour, (int) pspv.minute, (int) pspv.second), + pspv.hour == 123 && pspv.minute == 45 && pspv.second == 1); + + WL4435_TEST("DATE", "'1234-11-12'", + MYSQL_TYPE_DATE, MYSQL_TYPE_DATE, + MYSQL_TIME, , + (" - DATE / MYSQL_TIME / MYSQL_TYPE_DATE:\t\t " + "%.4d-%.2d-%.2d", + (int) pspv.year, (int) pspv.month, (int) pspv.day), + pspv.year == 1234 && pspv.month == 11 && pspv.day == 12); + + WL4435_TEST("YEAR", "'2010'", + MYSQL_TYPE_SHORT, MYSQL_TYPE_YEAR, + short, , + (" - YEAR / short / MYSQL_TYPE_SHORT:\t\t\t %.4d", (int) pspv), + pspv == 2010); + + WL4435_TEST("FLOAT(7, 4)", "123.4567", + MYSQL_TYPE_FLOAT, MYSQL_TYPE_FLOAT, + float, , + (" - FLOAT / float / MYSQL_TYPE_FLOAT:\t\t\t %g", (double) pspv), + pspv - 123.4567 < 0.0001); + + WL4435_TEST("DOUBLE(8, 5)", "123.45678", + MYSQL_TYPE_DOUBLE, MYSQL_TYPE_DOUBLE, + double, , + (" - DOUBLE / double / MYSQL_TYPE_DOUBLE:\t\t %g", (double) pspv), + pspv - 123.45678 < 0.00001); + + WL4435_TEST("DECIMAL(9, 6)", "123.456789", + MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_NEWDECIMAL, + char, [255], + (" - DECIMAL / char[] / MYSQL_TYPE_NEWDECIMAL:\t\t '%s'", (char *) pspv), + !strcmp(pspv, "123.456789")); + + WL4435_TEST("CHAR(32)", "REPEAT('C', 16)", + MYSQL_TYPE_STRING, MYSQL_TYPE_STRING, + char, [255], + (" - CHAR(32) / char[] / MYSQL_TYPE_STRING:\t\t '%s'", (char *) pspv), + !strcmp(pspv, "CCCCCCCCCCCCCCCC")); + + WL4435_TEST("VARCHAR(32)", "REPEAT('V', 16)", + MYSQL_TYPE_VAR_STRING, MYSQL_TYPE_VAR_STRING, + char, [255], + (" - VARCHAR(32) / char[] / MYSQL_TYPE_VAR_STRING:\t '%s'", (char *) pspv), + !strcmp(pspv, "VVVVVVVVVVVVVVVV")); + + WL4435_TEST("TINYTEXT", "REPEAT('t', 16)", + MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_BLOB, + char, [255], + (" - TINYTEXT / char[] / MYSQL_TYPE_TINY_BLOB:\t\t '%s'", (char *) pspv), + !strcmp(pspv, "tttttttttttttttt")); + + WL4435_TEST("TEXT", "REPEAT('t', 16)", + MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB, + char, [255], + (" - TEXT / char[] / MYSQL_TYPE_BLOB:\t\t\t '%s'", (char *) pspv), + !strcmp(pspv, "tttttttttttttttt")); + + WL4435_TEST("MEDIUMTEXT", "REPEAT('t', 16)", + MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_BLOB, + char, [255], + (" - MEDIUMTEXT / char[] / MYSQL_TYPE_MEDIUM_BLOB:\t '%s'", (char *) pspv), + !strcmp(pspv, "tttttttttttttttt")); + + WL4435_TEST("LONGTEXT", "REPEAT('t', 16)", + MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_BLOB, + char, [255], + (" - LONGTEXT / char[] / MYSQL_TYPE_LONG_BLOB:\t\t '%s'", (char *) pspv), + !strcmp(pspv, "tttttttttttttttt")); + + WL4435_TEST("BINARY(32)", "REPEAT('\1', 16)", + MYSQL_TYPE_STRING, MYSQL_TYPE_STRING, + char, [255], + (" - BINARY(32) / char[] / MYSQL_TYPE_STRING:\t\t '%s'", (char *) pspv), + memset(tmp, 1, 16) && !memcmp(tmp, pspv, 16)); + + WL4435_TEST("VARBINARY(32)", "REPEAT('\1', 16)", + MYSQL_TYPE_VAR_STRING, MYSQL_TYPE_VAR_STRING, + char, [255], + (" - VARBINARY(32) / char[] / MYSQL_TYPE_VAR_STRING:\t '%s'", (char *) pspv), + memset(tmp, 1, 16) && !memcmp(tmp, pspv, 16)); + + WL4435_TEST("TINYBLOB", "REPEAT('\2', 16)", + MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_BLOB, + char, [255], + (" - TINYBLOB / char[] / MYSQL_TYPE_TINY_BLOB:\t\t '%s'", (char *) pspv), + memset(tmp, 2, 16) && !memcmp(tmp, pspv, 16)); + + WL4435_TEST("BLOB", "REPEAT('\2', 16)", + MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB, + char, [255], + (" - BLOB / char[] / MYSQL_TYPE_BLOB:\t\t\t '%s'", (char *) pspv), + memset(tmp, 2, 16) && !memcmp(tmp, pspv, 16)); + + WL4435_TEST("MEDIUMBLOB", "REPEAT('\2', 16)", + MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_BLOB, + char, [255], + (" - MEDIUMBLOB / char[] / MYSQL_TYPE_MEDIUM_BLOB:\t '%s'", (char *) pspv), + memset(tmp, 2, 16) && !memcmp(tmp, pspv, 16)); + + WL4435_TEST("LONGBLOB", "REPEAT('\2', 16)", + MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_BLOB, + char, [255], + (" - LONGBLOB / char[] / MYSQL_TYPE_LONG_BLOB:\t\t '%s'", (char *) pspv), + memset(tmp, 2, 16) && !memcmp(tmp, pspv, 16)); +} + + /* Test simple prepare field results */ static void test_prepare_field_result() @@ -19468,6 +19717,7 @@ static struct my_tests_st my_tests[]= { { "test_wl4284_1", test_wl4284_1 }, { "test_wl4435", test_wl4435 }, { "test_wl4435_2", test_wl4435_2 }, + { "test_wl4435_3", test_wl4435_3 }, { "test_bug38486", test_bug38486 }, { "test_bug33831", test_bug33831 }, { "test_bug40365", test_bug40365 }, From 1b6bf12b1113cafa183b441a9fb52c7d5617f702 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Sat, 13 Nov 2010 19:38:39 +0100 Subject: [PATCH 237/304] Bug#58178: "make package" is broken with cmake 2.8.3 Problem: with "make package" , many small packages are generated, one per CMake COMPONENT, instead of expected single package. This is due to the new (in cmake 2.8.3) component-based install for archive( e.g ZIP,TGZ ) CPack generators. See http://public.kitware.com/Bug/view.php?id=11452 for discussion. Fix: use CPACK_MONOLITHIC_INSTALL=1 to enforce single package. Reset this variable temporarily to 0 for MSI creation (MSI needs COMPONENTs) --- CMakeLists.txt | 5 +++++ packaging/WiX/create_msi.cmake.in | 12 ++++++++++++ 2 files changed, 17 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 544c48f79f6..4078e520a08 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -331,6 +331,11 @@ ELSE() SET(CPACK_GENERATOR "TGZ") ENDIF() ADD_SUBDIRECTORY(packaging/WiX) + +# Create a single package with "make package" +# (see http://public.kitware.com/Bug/view.php?id=11452) +SET(CPACK_MONOLITHIC_INSTALL 1 CACHE INTERNAL "") + INCLUDE(CPack) IF(UNIX) INSTALL(FILES Docs/mysql.info DESTINATION ${INSTALL_INFODIR} OPTIONAL) diff --git a/packaging/WiX/create_msi.cmake.in b/packaging/WiX/create_msi.cmake.in index adc3cf4c4dd..404095fb567 100644 --- a/packaging/WiX/create_msi.cmake.in +++ b/packaging/WiX/create_msi.cmake.in @@ -27,6 +27,12 @@ ENDIF() SET(ENV{VS_UNICODE_OUTPUT}) +# Switch off the monolithic install +EXECUTE_PROCESS( + COMMAND ${CMAKE_COMMAND} -DCPACK_MONOLITHIC_INSTALL=0 ${CMAKE_BINARY_DIR} + OUTPUT_QUIET +) + INCLUDE(${CMAKE_BINARY_DIR}/CPackConfig.cmake) IF(CPACK_WIX_CONFIG) @@ -318,3 +324,9 @@ EXECUTE_PROCESS( ${EXTRA_LIGHT_ARGS} ) +# Switch monolithic install on again +EXECUTE_PROCESS( + COMMAND ${CMAKE_COMMAND} -DCPACK_MONOLITHIC_INSTALL=1 ${CMAKE_BINARY_DIR} + OUTPUT_QUIET +) + From f0c2b9c5c60973ba89eff82a6c7fb9f54e1beee2 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Sat, 13 Nov 2010 23:16:52 +0100 Subject: [PATCH 238/304] add missing COMPONENT to all CMake INSTALL commands --- CMakeLists.txt | 13 +++++++++---- cmake/install_macros.cmake | 11 ++++------- libmysql/CMakeLists.txt | 6 +++--- libservices/CMakeLists.txt | 2 +- man/CMakeLists.txt | 6 ++++-- mysql-test/CMakeLists.txt | 3 ++- scripts/CMakeLists.txt | 2 +- sql-bench/CMakeLists.txt | 10 +++++----- sql/CMakeLists.txt | 2 +- support-files/CMakeLists.txt | 11 ++++++++--- 10 files changed, 38 insertions(+), 28 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4078e520a08..6c7e89974c1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -338,21 +338,26 @@ SET(CPACK_MONOLITHIC_INSTALL 1 CACHE INTERNAL "") INCLUDE(CPack) IF(UNIX) - INSTALL(FILES Docs/mysql.info DESTINATION ${INSTALL_INFODIR} OPTIONAL) + INSTALL(FILES Docs/mysql.info DESTINATION ${INSTALL_INFODIR} OPTIONAL COMPONENT Info) ENDIF() # # RPM installs documentation directly from the source tree # IF(NOT INSTALL_LAYOUT MATCHES "RPM") - INSTALL(FILES COPYING EXCEPTIONS-CLIENT LICENSE.mysql DESTINATION ${INSTALL_DOCREADMEDIR} OPTIONAL) - INSTALL(FILES README DESTINATION ${INSTALL_DOCREADMEDIR}) + INSTALL(FILES COPYING EXCEPTIONS-CLIENT LICENSE.mysql + DESTINATION ${INSTALL_DOCREADMEDIR} + COMPONENT Readme + OPTIONAL + ) + INSTALL(FILES README DESTINATION ${INSTALL_DOCREADMEDIR} COMPONENT Readme) IF(UNIX) - INSTALL(FILES Docs/INSTALL-BINARY DESTINATION ${INSTALL_DOCREADMEDIR}) + INSTALL(FILES Docs/INSTALL-BINARY DESTINATION ${INSTALL_DOCREADMEDIR} COMPONENT Readme) ENDIF() # MYSQL_DOCS_LOCATON is used in "make dist", points to the documentation directory SET(MYSQL_DOCS_LOCATION "" CACHE PATH "Location from where documentation is copied") MARK_AS_ADVANCED(MYSQL_DOCS_LOCATION) INSTALL(DIRECTORY Docs/ DESTINATION ${INSTALL_DOCDIR} + COMPONENT Documentation PATTERN "INSTALL-BINARY" EXCLUDE PATTERN "Makefile.*" EXCLUDE PATTERN "glibc*" EXCLUDE diff --git a/cmake/install_macros.cmake b/cmake/install_macros.cmake index ddfbcd09ce4..e244e4262e0 100644 --- a/cmake/install_macros.cmake +++ b/cmake/install_macros.cmake @@ -78,7 +78,9 @@ FUNCTION(INSTALL_MANPAGE file) ELSE() SET(SECTION man8) ENDIF() - INSTALL(FILES "${MANPAGE}" DESTINATION "${INSTALL_MANDIR}/${SECTION}") + MESSAGE("huj!") + INSTALL(FILES "${MANPAGE}" DESTINATION "${INSTALL_MANDIR}/${SECTION}" + COMPONENT ManPages) ENDIF() ENDFUNCTION() @@ -137,12 +139,7 @@ IF(UNIX) STRING(REPLACE "${CMAKE_CFG_INTDIR}" "\${CMAKE_INSTALL_CONFIG_NAME}" output ${output}) ENDIF() - IF(component) - SET(COMP COMPONENT ${component}) - ELSE() - SET(COMP) - ENDIF() - INSTALL(FILES ${output} DESTINATION ${destination} ${COMP}) + INSTALL(FILES ${output} DESTINATION ${destination} COMPONENT ${component}) ENDIF() ENDMACRO() diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt index 7441423743e..d7426c465d8 100644 --- a/libmysql/CMakeLists.txt +++ b/libmysql/CMakeLists.txt @@ -172,7 +172,7 @@ IF(UNIX) SET(${OUTNAME} ${LIBNAME}${EXTENSION}${DOT_VERSION}) ENDIF() ENDMACRO() - INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} COMPONENT SharedLibraries) + INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development) ENDIF() IF(NOT DISABLE_SHARED) @@ -210,7 +210,7 @@ IF(NOT DISABLE_SHARED) "${CMAKE_SHARED_LIBRARY_SUFFIX}" "" linkname) - INSTALL_SYMLINK(${linkname} libmysql ${INSTALL_LIBDIR} COMPONENT SharedLibraries) + INSTALL_SYMLINK(${linkname} libmysql ${INSTALL_LIBDIR} SharedLibraries) SET(OS_SHARED_LIB_SYMLINKS "${SHARED_LIB_MAJOR_VERSION}" "${OS_SHARED_LIB_VERSION}") LIST(REMOVE_DUPLICATES OS_SHARED_LIB_SYMLINKS) FOREACH(ver ${OS_SHARED_LIB_SYMLINKS}) @@ -219,7 +219,7 @@ IF(NOT DISABLE_SHARED) "${CMAKE_SHARED_LIBRARY_SUFFIX}" "${ver}" linkname) - INSTALL_SYMLINK(${linkname} libmysql ${INSTALL_LIBDIR} COMPONENT SharedLibraries) + INSTALL_SYMLINK(${linkname} libmysql ${INSTALL_LIBDIR} SharedLibraries) ENDFOREACH() ENDIF() ENDIF() diff --git a/libservices/CMakeLists.txt b/libservices/CMakeLists.txt index 396430fba12..300e0ce32a3 100644 --- a/libservices/CMakeLists.txt +++ b/libservices/CMakeLists.txt @@ -22,4 +22,4 @@ SET(MYSQLSERVICES_SOURCES my_thread_scheduler_service.c) ADD_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES}) -INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR}) +INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development) diff --git a/man/CMakeLists.txt b/man/CMakeLists.txt index 7c96deada08..135d66634e4 100644 --- a/man/CMakeLists.txt +++ b/man/CMakeLists.txt @@ -21,8 +21,10 @@ IF(MAN1_FILES) IF(MAN1_EXCLUDE) LIST(REMOVE_ITEM MAN1_FILES ${MAN1_EXCLUDE}) ENDIF() - INSTALL(FILES ${MAN1_FILES} DESTINATION ${INSTALL_MANDIR}/man1) + INSTALL(FILES ${MAN1_FILES} DESTINATION ${INSTALL_MANDIR}/man1 + COMPONENT ManPages) ENDIF() IF(MAN8_FILES) - INSTALL(FILES ${MAN8_FILES} DESTINATION ${INSTALL_MANDIR}/man8) + INSTALL(FILES ${MAN8_FILES} DESTINATION ${INSTALL_MANDIR}/man8 + COMPONENT ManPages) ENDIF() diff --git a/mysql-test/CMakeLists.txt b/mysql-test/CMakeLists.txt index 3c38e5772d0..f18b2ae341c 100644 --- a/mysql-test/CMakeLists.txt +++ b/mysql-test/CMakeLists.txt @@ -53,7 +53,8 @@ IF(UNIX) IF(INSTALL_MYSQLTESTDIR) INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/mtr ${CMAKE_CURRENT_BINARY_DIR}/mysql-test-run - DESTINATION ${INSTALL_MYSQLTESTDIR}) + DESTINATION ${INSTALL_MYSQLTESTDIR} + COMPONENT Test) ENDIF() ENDIF() diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index 0a8d4f9658d..56b7f779bb0 100644 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -310,7 +310,7 @@ IF(WIN32) FOREACH(file ${SH_FILES}) CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh ${CMAKE_CURRENT_BINARY_DIR}/${file}.pl ESCAPE_QUOTES @ONLY) - INSTALL_SCRIPT(${CMAKE_CURRENT_BINARY_DIR}/${file}.pl COMPONENT ${${file}_COMPONENT}) + INSTALL_SCRIPT(${CMAKE_CURRENT_BINARY_DIR}/${file}.pl COMPONENT Server_Scripts) ENDFOREACH() ELSE() # On Unix, most of the files end up in the bin directory diff --git a/sql-bench/CMakeLists.txt b/sql-bench/CMakeLists.txt index f8be18c6653..ae05d30530d 100644 --- a/sql-bench/CMakeLists.txt +++ b/sql-bench/CMakeLists.txt @@ -26,13 +26,13 @@ ELSE() ENDIF() INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/Data/ATIS - DESTINATION ${prefix}sql-bench/Data) + DESTINATION ${prefix}sql-bench/Data COMPONENT SqlBench) INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/Data/Wisconsin - DESTINATION ${prefix}sql-bench/Data) + DESTINATION ${prefix}sql-bench/Data COMPONENT SqlBench) INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/limits - DESTINATION ${prefix}sql-bench) + DESTINATION ${prefix}sql-bench COMPONENT SqlBench) FILE(GLOB all_files ${CMAKE_CURRENT_SOURCE_DIR}/*) @@ -54,10 +54,10 @@ FOREACH(file ${all_files}) CONFIGURE_FILE(${file} ${target} COPYONLY) IF (ext MATCHES ".bat") IF(WIN32) - INSTALL(FILES ${target} DESTINATION ${prefix}sql-bench) + INSTALL(FILES ${target} DESTINATION ${prefix}sql-bench COMPONENT SqlBench) ENDIF() ELSE() - INSTALL(FILES ${target} DESTINATION ${prefix}sql-bench) + INSTALL(FILES ${target} DESTINATION ${prefix}sql-bench COMPONENT SqlBench) ENDIF() ENDIF() ENDFOREACH() diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 0860adde652..2c782380baf 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -283,7 +283,7 @@ IF(WIN32 AND MYSQLD_EXECUTABLE) COMPONENT DataFiles PATTERN "initdb.dep" EXCLUDE PATTERN "bootstrap.sql" EXCLUDE) ELSE() # Not windows or cross compiling, just install an empty directory - INSTALL(FILES ${DUMMY_FILE} DESTINATION data/mysql) + INSTALL(FILES ${DUMMY_FILE} DESTINATION data/mysql COMPONENT DataFiles) ENDIF() ENDIF() diff --git a/support-files/CMakeLists.txt b/support-files/CMakeLists.txt index ef676c8ee2a..26aa7ad81ad 100644 --- a/support-files/CMakeLists.txt +++ b/support-files/CMakeLists.txt @@ -61,12 +61,17 @@ IF(UNIX) CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${script}.sh ${CMAKE_CURRENT_BINARY_DIR}/${script} @ONLY ) + IF(script MATCHES ".ini") + SET(comp IniFiles) + ELSE() + SET(comp Server_Scripts) + ENDIF() INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${script} - DESTINATION ${inst_location} + DESTINATION ${inst_location} COMPONENT ${comp} PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) ENDFOREACH() IF(INSTALL_SUPPORTFILESDIR) - INSTALL(FILES magic DESTINATION ${inst_location}) + INSTALL(FILES magic DESTINATION ${inst_location} COMPONENT SupportFiles) ENDIF() INSTALL(FILES mysql.m4 DESTINATION ${INSTALL_SHAREDIR}/aclocal COMPONENT Development) @@ -83,7 +88,7 @@ IF(UNIX) CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/mysql.server.sh ${CMAKE_CURRENT_BINARY_DIR}/mysql.server @ONLY) INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/mysql.server - DESTINATION ${inst_location} + DESTINATION ${inst_location} COMPONENT SupportFiles PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) ENDIF() From f64026427e7906f2ec5a70bd3c4517f1abdd7cfb Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Sun, 14 Nov 2010 23:08:04 -0800 Subject: [PATCH 239/304] Fix Bug #16290 Unclear error message when adding foreign key constraint rb://502 approved by Sunny Bains --- storage/innobase/dict/dict0dict.c | 4 ++-- storage/innobase/handler/ha_innodb.cc | 25 +++++++++++++++++++++++++ storage/innobase/include/db0err.h | 6 ++++++ storage/innobase/ut/ut0ut.c | 4 ++++ 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c index b4191ad2d6d..0d15ad8b716 100644 --- a/storage/innobase/dict/dict0dict.c +++ b/storage/innobase/dict/dict0dict.c @@ -3483,7 +3483,7 @@ col_loop1: start_of_latest_foreign); mutex_exit(&dict_foreign_err_mutex); - return(DB_CANNOT_ADD_CONSTRAINT); + return(DB_CHILD_NO_INDEX); } ptr = dict_accept(cs, ptr, "REFERENCES", &success); @@ -3764,7 +3764,7 @@ try_find_index: start_of_latest_foreign); mutex_exit(&dict_foreign_err_mutex); - return(DB_CANNOT_ADD_CONSTRAINT); + return(DB_PARENT_NO_INDEX); } } else { ut_a(trx->check_foreigns == FALSE); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 295dee7b007..b0d620c060d 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -960,6 +960,8 @@ convert_error_code_to_mysql( return(HA_ERR_ROW_IS_REFERENCED); case DB_CANNOT_ADD_CONSTRAINT: + case DB_CHILD_NO_INDEX: + case DB_PARENT_NO_INDEX: return(HA_ERR_CANNOT_ADD_FOREIGN); case DB_CANNOT_DROP_CONSTRAINT: @@ -6977,6 +6979,29 @@ ha_innobase::create( trx, stmt, stmt_len, norm_name, create_info->options & HA_LEX_CREATE_TMP_TABLE); + switch (error) { + + case DB_PARENT_NO_INDEX: + push_warning_printf( + thd, MYSQL_ERROR::WARN_LEVEL_WARN, + HA_ERR_CANNOT_ADD_FOREIGN, + "Create table '%s' with foreign key constraint" + " failed. There is no index in the referenced" + " table where the referenced columns appear" + " as the first columns.\n", norm_name); + break; + + case DB_CHILD_NO_INDEX: + push_warning_printf( + thd, MYSQL_ERROR::WARN_LEVEL_WARN, + HA_ERR_CANNOT_ADD_FOREIGN, + "Create table '%s' with foreign key constraint" + " failed. There is no index in the referencing" + " table where referencing columns appear" + " as the first columns.\n", norm_name); + break; + } + error = convert_error_code_to_mysql(error, flags, NULL); if (error) { diff --git a/storage/innobase/include/db0err.h b/storage/innobase/include/db0err.h index 01bb1b80754..8a71fa6511a 100644 --- a/storage/innobase/include/db0err.h +++ b/storage/innobase/include/db0err.h @@ -104,6 +104,12 @@ enum db_err { DB_FOREIGN_EXCEED_MAX_CASCADE, /* Foreign key constraint related cascading delete/update exceeds maximum allowed depth */ + DB_CHILD_NO_INDEX, /* the child (foreign) table does not + have an index that contains the + foreign keys as its prefix columns */ + DB_PARENT_NO_INDEX, /* the parent table does not + have an index that contains the + foreign keys as its prefix columns */ /* The following are partial failure codes */ DB_FAIL = 1000, diff --git a/storage/innobase/ut/ut0ut.c b/storage/innobase/ut/ut0ut.c index 39c60d2bc2f..4f4dfc5eed8 100644 --- a/storage/innobase/ut/ut0ut.c +++ b/storage/innobase/ut/ut0ut.c @@ -715,6 +715,10 @@ ut_strerr( return("Zip overflow"); case DB_RECORD_NOT_FOUND: return("Record not found"); + case DB_CHILD_NO_INDEX: + return("No index on referencing keys in referencing table"); + case DB_PARENT_NO_INDEX: + return("No index on referenced keys in referenced table"); case DB_END_OF_INDEX: return("End of index"); /* do not add default: in order to produce a warning if new code From a557a66145255da841ce3f4796ac52b9101aff0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20Bl=C3=A5udd?= Date: Mon, 15 Nov 2010 10:51:59 +0100 Subject: [PATCH 240/304] Bug#58195 Make mysqltest poll for next epoch more often - Speed up replicated NDB test by havin mysqltest poll every 100ms (instead of every second) in sync_master_with_slave. Default epoch timeout is 100ms, so that make sense. --- client/mysqltest.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 5dc3576e759..219fd518555 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -4243,7 +4243,7 @@ int do_save_master_pos() const char latest_applied_binlog_epoch_str[]= "latest_applied_binlog_epoch="; if (count) - sleep(1); + my_sleep(100*1000); /* 100ms */ if (mysql_query(mysql, query= "show engine ndb status")) die("failed in '%s': %d %s", query, mysql_errno(mysql), mysql_error(mysql)); @@ -4332,7 +4332,7 @@ int do_save_master_pos() count++; if (latest_handled_binlog_epoch >= start_epoch) do_continue= 0; - else if (count > 30) + else if (count > 300) /* 30s */ { break; } From a3d9a26d3b9ada36d7c57815614027c9fa798002 Mon Sep 17 00:00:00 2001 From: Jon Olav Hauglid Date: Mon, 15 Nov 2010 12:32:49 +0100 Subject: [PATCH 241/304] Bug #57663 Concurrent statement using stored function and DROP DATABASE breaks SBR This pre-requisite patch removes obsolete and dead code used to remove raid subdirectories and files during DROP DATABASE. Other parts of the raid code have already been removed in WL#5498 and the support for MyISAM raid tables was removed in 5.0. --- sql/sql_db.cc | 52 ++++++--------------------------------------------- 1 file changed, 6 insertions(+), 46 deletions(-) diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 1dea2f279e9..2abe4d8d072 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -45,7 +45,7 @@ static TYPELIB deletable_extentions= {array_elements(del_exts)-1,"del_exts", del_exts, NULL}; static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, - const char *db, const char *path, uint level, + const char *db, const char *path, TABLE_LIST **dropped_tables); long mysql_rm_arc_files(THD *thd, MY_DIR *dirp, const char *org_path); @@ -809,7 +809,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) as disabled and will not log the drop database statement on any other connected server. */ - if ((deleted= mysql_rm_known_files(thd, dirp, db, path, 0, + if ((deleted= mysql_rm_known_files(thd, dirp, db, path, &dropped_tables)) >= 0) { ha_drop_database(path); @@ -932,20 +932,18 @@ exit: } /* - Removes files with known extensions plus all found subdirectories that - are 2 hex digits (raid directories). + Removes files with known extensions. thd MUST be set when calling this function! */ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, - const char *org_path, uint level, + const char *org_path, TABLE_LIST **dropped_tables) { long deleted=0; ulong found_other_files=0; char filePath[FN_REFLEN]; TABLE_LIST *tot_list=0, **tot_list_next_local, **tot_list_next_global; - List raid_dirs; DBUG_ENTER("mysql_rm_known_files"); DBUG_PRINT("enter",("path: %s", org_path)); @@ -964,36 +962,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, (file->name[1] == '.' && !file->name[2]))) continue; - /* Check if file is a raid directory */ - if ((my_isdigit(system_charset_info, file->name[0]) || - (file->name[0] >= 'a' && file->name[0] <= 'f')) && - (my_isdigit(system_charset_info, file->name[1]) || - (file->name[1] >= 'a' && file->name[1] <= 'f')) && - !file->name[2] && !level) - { - char newpath[FN_REFLEN], *copy_of_path; - MY_DIR *new_dirp; - String *dir; - uint length; - - strxmov(newpath,org_path,"/",file->name,NullS); - length= unpack_filename(newpath,newpath); - if ((new_dirp = my_dir(newpath,MYF(MY_DONT_SORT)))) - { - DBUG_PRINT("my",("New subdir found: %s", newpath)); - if ((mysql_rm_known_files(thd, new_dirp, NullS, newpath,1,0)) < 0) - goto err; - if (!(copy_of_path= (char*) thd->memdup(newpath, length+1)) || - !(dir= new (thd->mem_root) String(copy_of_path, length, - &my_charset_bin)) || - raid_dirs.push_back(dir)) - goto err; - continue; - } - found_other_files++; - continue; - } - else if (file->name[0] == 'a' && file->name[1] == 'r' && + if (file->name[0] == 'a' && file->name[1] == 'r' && file->name[2] == 'c' && file->name[3] == '\0') { /* .frm archive: @@ -1075,14 +1044,6 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, (tot_list && mysql_rm_table_part2(thd, tot_list, 1, 0, 1, 1))) goto err; - /* Remove RAID directories */ - { - List_iterator it(raid_dirs); - String *dir; - while ((dir= it++)) - if (rmdir(dir->c_ptr()) < 0) - found_other_files++; - } my_dirend(dirp); if (dropped_tables) @@ -1099,8 +1060,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, } else { - /* Don't give errors if we can't delete 'RAID' directory */ - if (rm_dir_w_symlink(org_path, level == 0)) + if (rm_dir_w_symlink(org_path, true)) DBUG_RETURN(-1); } From 92a1a112030452b375684e2b8633de0a32dc0912 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Mon, 15 Nov 2010 14:23:02 +0100 Subject: [PATCH 242/304] Bug #58087 mysqltest re-evaluates 'let' expressions infinitely Results from query is sent for evaluation Break recursion by asking for ` to be ignored --- client/mysqltest.cc | 9 +++++---- mysql-test/r/mysqltest.result | 4 ++++ mysql-test/t/mysqltest.test | 7 +++++++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index abedd874948..9fc692d0d04 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -471,7 +471,7 @@ VAR* var_init(VAR* v, const char *name, int name_len, const char *val, void var_free(void* v); VAR* var_get(const char *var_name, const char** var_name_end, my_bool raw, my_bool ignore_not_existing); -void eval_expr(VAR* v, const char *p, const char** p_end); +void eval_expr(VAR* v, const char *p, const char** p_end, bool backtick= true); my_bool match_delimiter(int c, const char *delim, uint length); void dump_result_to_reject_file(char *buf, int size); void dump_warning_messages(); @@ -2233,7 +2233,8 @@ void var_query_set(VAR *var, const char *query, const char** query_end) dynstr_append_mem(&result, "\t", 1); } end= result.str + result.length-1; - eval_expr(var, result.str, (const char**) &end); + /* Evaluation should not recurse via backtick */ + eval_expr(var, result.str, (const char**) &end, false); dynstr_free(&result); } else @@ -2389,7 +2390,7 @@ void var_copy(VAR *dest, VAR *src) } -void eval_expr(VAR *v, const char *p, const char **p_end) +void eval_expr(VAR *v, const char *p, const char **p_end, bool backtick) { DBUG_ENTER("eval_expr"); @@ -2414,7 +2415,7 @@ void eval_expr(VAR *v, const char *p, const char **p_end) DBUG_VOID_RETURN; } - if (*p == '`') + if (*p == '`' && backtick) { var_query_set(v, p, p_end); DBUG_VOID_RETURN; diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index 8afef65b66f..f22a18057c3 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -308,6 +308,10 @@ var3 two columns with same name var4 from query that returns NULL var5 from query that returns no row failing query in let +create table t1 (a varchar(100)); +insert into t1 values ('`select 42`'); +`select 42` +drop table t1; mysqltest: At line 1: Error running query 'failing query': 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'failing query' at line 1 mysqltest: At line 1: Missing required argument 'filename' to command 'source' mysqltest: At line 1: Could not open './non_existingFile' for reading, errno: 2 diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index d6bdbc2b3c1..59ff70e1591 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -854,6 +854,13 @@ let $var2= `failing query`; echo $var2; EOF +create table t1 (a varchar(100)); +insert into t1 values ('`select 42`'); +let $a= `select * from t1`; +# This should output `select 42`, not evaluate it again to 42 +echo $a; +drop table t1; + --error 1 --exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/let.sql 2>&1 From 47b514ffce0c5b1bdda27f745d1129496dff037f Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Mon, 15 Nov 2010 16:17:38 +0100 Subject: [PATCH 243/304] Bug#58197: main.variables-big fails on windows The test result differs on windows, since it writes out 'localhost:' instead of only 'localhost', since it uses tcp/ip instead of unix sockets on windows. Fixed by replacing that column. Also requires --big-test from some long running tests and added a weekly run of all test requiring --big-test. mysql-test/collections/default.weekly: Added a run of big-test (already exists in 5.5). mysql-test/r/variables-big.result: Updated results mysql-test/suite/parts/t/part_supported_sql_func_innodb.test: requiring --big-test since the test takes long time mysql-test/suite/parts/t/partition_alter1_1_2_innodb.test: requiring --big-test since the test takes long time mysql-test/suite/parts/t/partition_alter1_2_innodb.test: requiring --big-test since the test takes long time mysql-test/suite/parts/t/partition_alter4_innodb.test: requiring --big-test since the test takes long time mysql-test/t/disabled.def: Disabled two tests since they fail and was already reported as bugs (but was never run since they requires --big-test flag). mysql-test/t/variables-big.test: Replacing column 3 in process list since it is not the same on windows as in unix. --- mysql-test/collections/default.weekly | 2 ++ mysql-test/r/variables-big.result | 10 +++++----- .../suite/parts/t/part_supported_sql_func_innodb.test | 3 +++ .../suite/parts/t/partition_alter1_1_2_innodb.test | 3 +++ .../suite/parts/t/partition_alter1_2_innodb.test | 3 +++ mysql-test/suite/parts/t/partition_alter4_innodb.test | 3 +++ mysql-test/t/disabled.def | 2 ++ mysql-test/t/variables-big.test | 10 +++++----- 8 files changed, 26 insertions(+), 10 deletions(-) diff --git a/mysql-test/collections/default.weekly b/mysql-test/collections/default.weekly index e69de29bb2d..5865864f4cd 100644 --- a/mysql-test/collections/default.weekly +++ b/mysql-test/collections/default.weekly @@ -0,0 +1,2 @@ +perl mysql-test-run.pl --timer --force --comment=1st --experimental=collections/default.experimental 1st +perl mysql-test-run.pl --timer --force --comment=big-tests --experimental=collections/default.experimental --vardir=var-big-tests --big-test --testcase-timeout=60 --suite-timeout=600 parts.partition_alter1_2_ndb parts.part_supported_sql_func_innodb parts.partition_alter1_2_innodb parts.partition_alter4_innodb parts.partition_alter1_1_2_ndb parts.partition_alter1_1_2_innodb parts.partition_alter1_1_ndb large_tests.alter_table rpl_ndb.rpl_truncate_7ndb_2 main.archive-big main.sum_distinct-big main.mysqlbinlog_row_big main.alter_table-big main.variables-big main.type_newdecimal-big main.read_many_rows_innodb main.log_tables-big main.count_distinct3 main.events_time_zone main.merge-big main.create-big main.events_stress main.ssl-big diff --git a/mysql-test/r/variables-big.result b/mysql-test/r/variables-big.result index 960fc6d22f4..71b32393d82 100644 --- a/mysql-test/r/variables-big.result +++ b/mysql-test/r/variables-big.result @@ -1,20 +1,20 @@ SET SESSION transaction_prealloc_size=1024*1024*1024*1; SHOW PROCESSLIST; Id User Host db Command Time State Info - root localhost test Query